feat:node-modules
This commit is contained in:
196
node_modules/mathjs/lib/cjs/expression/node/AccessorNode.js
generated
vendored
Normal file
196
node_modules/mathjs/lib/cjs/expression/node/AccessorNode.js
generated
vendored
Normal file
@@ -0,0 +1,196 @@
|
||||
"use strict";
|
||||
|
||||
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.createAccessorNode = void 0;
|
||||
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
||||
var _is = require("../../utils/is.js");
|
||||
var _customs = require("../../utils/customs.js");
|
||||
var _factory = require("../../utils/factory.js");
|
||||
var _access = require("./utils/access.js");
|
||||
const name = 'AccessorNode';
|
||||
const dependencies = ['subset', 'Node'];
|
||||
const createAccessorNode = exports.createAccessorNode = /* #__PURE__ */(0, _factory.factory)(name, dependencies, _ref => {
|
||||
let {
|
||||
subset,
|
||||
Node
|
||||
} = _ref;
|
||||
const access = (0, _access.accessFactory)({
|
||||
subset
|
||||
});
|
||||
|
||||
/**
|
||||
* Are parenthesis needed?
|
||||
* @private
|
||||
*/
|
||||
function needParenthesis(node) {
|
||||
// TODO: maybe make a method on the nodes which tells whether they need parenthesis?
|
||||
return !((0, _is.isAccessorNode)(node) || (0, _is.isArrayNode)(node) || (0, _is.isConstantNode)(node) || (0, _is.isFunctionNode)(node) || (0, _is.isObjectNode)(node) || (0, _is.isParenthesisNode)(node) || (0, _is.isSymbolNode)(node));
|
||||
}
|
||||
class AccessorNode extends Node {
|
||||
/**
|
||||
* @constructor AccessorNode
|
||||
* @extends {Node}
|
||||
* Access an object property or get a matrix subset
|
||||
*
|
||||
* @param {Node} object The object from which to retrieve
|
||||
* a property or subset.
|
||||
* @param {IndexNode} index IndexNode containing ranges
|
||||
*/
|
||||
constructor(object, index) {
|
||||
super();
|
||||
if (!(0, _is.isNode)(object)) {
|
||||
throw new TypeError('Node expected for parameter "object"');
|
||||
}
|
||||
if (!(0, _is.isIndexNode)(index)) {
|
||||
throw new TypeError('IndexNode expected for parameter "index"');
|
||||
}
|
||||
this.object = object;
|
||||
this.index = index;
|
||||
}
|
||||
|
||||
// readonly property name
|
||||
get name() {
|
||||
if (this.index) {
|
||||
return this.index.isObjectProperty() ? this.index.getObjectProperty() : '';
|
||||
} else {
|
||||
return this.object.name || '';
|
||||
}
|
||||
}
|
||||
get type() {
|
||||
return name;
|
||||
}
|
||||
get isAccessorNode() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile a node into a JavaScript function.
|
||||
* This basically pre-calculates as much as possible and only leaves open
|
||||
* calculations which depend on a dynamic scope with variables.
|
||||
* @param {Object} math Math.js namespace with functions and constants.
|
||||
* @param {Object} argNames An object with argument names as key and `true`
|
||||
* as value. Used in the SymbolNode to optimize
|
||||
* for arguments from user assigned functions
|
||||
* (see FunctionAssignmentNode) or special symbols
|
||||
* like `end` (see IndexNode).
|
||||
* @return {function} Returns a function which can be called like:
|
||||
* evalNode(scope: Object, args: Object, context: *)
|
||||
*/
|
||||
_compile(math, argNames) {
|
||||
const evalObject = this.object._compile(math, argNames);
|
||||
const evalIndex = this.index._compile(math, argNames);
|
||||
if (this.index.isObjectProperty()) {
|
||||
const prop = this.index.getObjectProperty();
|
||||
return function evalAccessorNode(scope, args, context) {
|
||||
// get a property from an object evaluated using the scope.
|
||||
return (0, _customs.getSafeProperty)(evalObject(scope, args, context), prop);
|
||||
};
|
||||
} else {
|
||||
return function evalAccessorNode(scope, args, context) {
|
||||
const object = evalObject(scope, args, context);
|
||||
// we pass just object here instead of context:
|
||||
const index = evalIndex(scope, args, object);
|
||||
return access(object, index);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a callback for each of the child nodes of this node
|
||||
* @param {function(child: Node, path: string, parent: Node)} callback
|
||||
*/
|
||||
forEach(callback) {
|
||||
callback(this.object, 'object', this);
|
||||
callback(this.index, 'index', this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new AccessorNode whose children are the results of calling
|
||||
* the provided callback function for each child of the original node.
|
||||
* @param {function(child: Node, path: string, parent: Node): Node} callback
|
||||
* @returns {AccessorNode} Returns a transformed copy of the node
|
||||
*/
|
||||
map(callback) {
|
||||
return new AccessorNode(this._ifNode(callback(this.object, 'object', this)), this._ifNode(callback(this.index, 'index', this)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a clone of this node, a shallow copy
|
||||
* @return {AccessorNode}
|
||||
*/
|
||||
clone() {
|
||||
return new AccessorNode(this.object, this.index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get string representation
|
||||
* @param {Object} options
|
||||
* @return {string}
|
||||
*/
|
||||
_toString(options) {
|
||||
let object = this.object.toString(options);
|
||||
if (needParenthesis(this.object)) {
|
||||
object = '(' + object + ')';
|
||||
}
|
||||
return object + this.index.toString(options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get HTML representation
|
||||
* @param {Object} options
|
||||
* @return {string}
|
||||
*/
|
||||
_toHTML(options) {
|
||||
let object = this.object.toHTML(options);
|
||||
if (needParenthesis(this.object)) {
|
||||
object = '<span class="math-parenthesis math-round-parenthesis">(</span>' + object + '<span class="math-parenthesis math-round-parenthesis">)</span>';
|
||||
}
|
||||
return object + this.index.toHTML(options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get LaTeX representation
|
||||
* @param {Object} options
|
||||
* @return {string}
|
||||
*/
|
||||
_toTex(options) {
|
||||
let object = this.object.toTex(options);
|
||||
if (needParenthesis(this.object)) {
|
||||
object = '\\left(\' + object + \'\\right)';
|
||||
}
|
||||
return object + this.index.toTex(options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a JSON representation of the node
|
||||
* @returns {Object}
|
||||
*/
|
||||
toJSON() {
|
||||
return {
|
||||
mathjs: name,
|
||||
object: this.object,
|
||||
index: this.index
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiate an AccessorNode from its JSON representation
|
||||
* @param {Object} json
|
||||
* An object structured like
|
||||
* `{"mathjs": "AccessorNode", object: ..., index: ...}`,
|
||||
* where mathjs is optional
|
||||
* @returns {AccessorNode}
|
||||
*/
|
||||
static fromJSON(json) {
|
||||
return new AccessorNode(json.object, json.index);
|
||||
}
|
||||
}
|
||||
(0, _defineProperty2.default)(AccessorNode, "name", name);
|
||||
return AccessorNode;
|
||||
}, {
|
||||
isClass: true,
|
||||
isNode: true
|
||||
});
|
||||
183
node_modules/mathjs/lib/cjs/expression/node/ArrayNode.js
generated
vendored
Normal file
183
node_modules/mathjs/lib/cjs/expression/node/ArrayNode.js
generated
vendored
Normal file
@@ -0,0 +1,183 @@
|
||||
"use strict";
|
||||
|
||||
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.createArrayNode = void 0;
|
||||
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
||||
var _is = require("../../utils/is.js");
|
||||
var _array = require("../../utils/array.js");
|
||||
var _factory = require("../../utils/factory.js");
|
||||
const name = 'ArrayNode';
|
||||
const dependencies = ['Node'];
|
||||
const createArrayNode = exports.createArrayNode = /* #__PURE__ */(0, _factory.factory)(name, dependencies, _ref => {
|
||||
let {
|
||||
Node
|
||||
} = _ref;
|
||||
class ArrayNode extends Node {
|
||||
/**
|
||||
* @constructor ArrayNode
|
||||
* @extends {Node}
|
||||
* Holds an 1-dimensional array with items
|
||||
* @param {Node[]} [items] 1 dimensional array with items
|
||||
*/
|
||||
constructor(items) {
|
||||
super();
|
||||
this.items = items || [];
|
||||
|
||||
// validate input
|
||||
if (!Array.isArray(this.items) || !this.items.every(_is.isNode)) {
|
||||
throw new TypeError('Array containing Nodes expected');
|
||||
}
|
||||
}
|
||||
get type() {
|
||||
return name;
|
||||
}
|
||||
get isArrayNode() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile a node into a JavaScript function.
|
||||
* This basically pre-calculates as much as possible and only leaves open
|
||||
* calculations which depend on a dynamic scope with variables.
|
||||
* @param {Object} math Math.js namespace with functions and constants.
|
||||
* @param {Object} argNames An object with argument names as key and `true`
|
||||
* as value. Used in the SymbolNode to optimize
|
||||
* for arguments from user assigned functions
|
||||
* (see FunctionAssignmentNode) or special symbols
|
||||
* like `end` (see IndexNode).
|
||||
* @return {function} Returns a function which can be called like:
|
||||
* evalNode(scope: Object, args: Object, context: *)
|
||||
*/
|
||||
_compile(math, argNames) {
|
||||
const evalItems = (0, _array.map)(this.items, function (item) {
|
||||
return item._compile(math, argNames);
|
||||
});
|
||||
const asMatrix = math.config.matrix !== 'Array';
|
||||
if (asMatrix) {
|
||||
const matrix = math.matrix;
|
||||
return function evalArrayNode(scope, args, context) {
|
||||
return matrix((0, _array.map)(evalItems, function (evalItem) {
|
||||
return evalItem(scope, args, context);
|
||||
}));
|
||||
};
|
||||
} else {
|
||||
return function evalArrayNode(scope, args, context) {
|
||||
return (0, _array.map)(evalItems, function (evalItem) {
|
||||
return evalItem(scope, args, context);
|
||||
});
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a callback for each of the child nodes of this node
|
||||
* @param {function(child: Node, path: string, parent: Node)} callback
|
||||
*/
|
||||
forEach(callback) {
|
||||
for (let i = 0; i < this.items.length; i++) {
|
||||
const node = this.items[i];
|
||||
callback(node, 'items[' + i + ']', this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new ArrayNode whose children are the results of calling
|
||||
* the provided callback function for each child of the original node.
|
||||
* @param {function(child: Node, path: string, parent: Node): Node} callback
|
||||
* @returns {ArrayNode} Returns a transformed copy of the node
|
||||
*/
|
||||
map(callback) {
|
||||
const items = [];
|
||||
for (let i = 0; i < this.items.length; i++) {
|
||||
items[i] = this._ifNode(callback(this.items[i], 'items[' + i + ']', this));
|
||||
}
|
||||
return new ArrayNode(items);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a clone of this node, a shallow copy
|
||||
* @return {ArrayNode}
|
||||
*/
|
||||
clone() {
|
||||
return new ArrayNode(this.items.slice(0));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get string representation
|
||||
* @param {Object} options
|
||||
* @return {string} str
|
||||
* @override
|
||||
*/
|
||||
_toString(options) {
|
||||
const items = this.items.map(function (node) {
|
||||
return node.toString(options);
|
||||
});
|
||||
return '[' + items.join(', ') + ']';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a JSON representation of the node
|
||||
* @returns {Object}
|
||||
*/
|
||||
toJSON() {
|
||||
return {
|
||||
mathjs: name,
|
||||
items: this.items
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiate an ArrayNode from its JSON representation
|
||||
* @param {Object} json An object structured like
|
||||
* `{"mathjs": "ArrayNode", items: [...]}`,
|
||||
* where mathjs is optional
|
||||
* @returns {ArrayNode}
|
||||
*/
|
||||
static fromJSON(json) {
|
||||
return new ArrayNode(json.items);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get HTML representation
|
||||
* @param {Object} options
|
||||
* @return {string} str
|
||||
* @override
|
||||
*/
|
||||
_toHTML(options) {
|
||||
const items = this.items.map(function (node) {
|
||||
return node.toHTML(options);
|
||||
});
|
||||
return '<span class="math-parenthesis math-square-parenthesis">[</span>' + items.join('<span class="math-separator">,</span>') + '<span class="math-parenthesis math-square-parenthesis">]</span>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get LaTeX representation
|
||||
* @param {Object} options
|
||||
* @return {string} str
|
||||
*/
|
||||
_toTex(options) {
|
||||
function itemsToTex(items, nested) {
|
||||
const mixedItems = items.some(_is.isArrayNode) && !items.every(_is.isArrayNode);
|
||||
const itemsFormRow = nested || mixedItems;
|
||||
const itemSep = itemsFormRow ? '&' : '\\\\';
|
||||
const itemsTex = items.map(function (node) {
|
||||
if (node.items) {
|
||||
return itemsToTex(node.items, !nested);
|
||||
} else {
|
||||
return node.toTex(options);
|
||||
}
|
||||
}).join(itemSep);
|
||||
return mixedItems || !itemsFormRow || itemsFormRow && !nested ? '\\begin{bmatrix}' + itemsTex + '\\end{bmatrix}' : itemsTex;
|
||||
}
|
||||
return itemsToTex(this.items, false);
|
||||
}
|
||||
}
|
||||
(0, _defineProperty2.default)(ArrayNode, "name", name);
|
||||
return ArrayNode;
|
||||
}, {
|
||||
isClass: true,
|
||||
isNode: true
|
||||
});
|
||||
313
node_modules/mathjs/lib/cjs/expression/node/AssignmentNode.js
generated
vendored
Normal file
313
node_modules/mathjs/lib/cjs/expression/node/AssignmentNode.js
generated
vendored
Normal file
@@ -0,0 +1,313 @@
|
||||
"use strict";
|
||||
|
||||
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.createAssignmentNode = void 0;
|
||||
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
||||
var _is = require("../../utils/is.js");
|
||||
var _customs = require("../../utils/customs.js");
|
||||
var _factory = require("../../utils/factory.js");
|
||||
var _access = require("./utils/access.js");
|
||||
var _assign = require("./utils/assign.js");
|
||||
var _operators = require("../operators.js");
|
||||
const name = 'AssignmentNode';
|
||||
const dependencies = ['subset', '?matrix',
|
||||
// FIXME: should not be needed at all, should be handled by subset
|
||||
'Node'];
|
||||
const createAssignmentNode = exports.createAssignmentNode = /* #__PURE__ */(0, _factory.factory)(name, dependencies, _ref => {
|
||||
let {
|
||||
subset,
|
||||
matrix,
|
||||
Node
|
||||
} = _ref;
|
||||
const access = (0, _access.accessFactory)({
|
||||
subset
|
||||
});
|
||||
const assign = (0, _assign.assignFactory)({
|
||||
subset,
|
||||
matrix
|
||||
});
|
||||
|
||||
/*
|
||||
* Is parenthesis needed?
|
||||
* @param {node} node
|
||||
* @param {string} [parenthesis='keep']
|
||||
* @param {string} implicit
|
||||
* @private
|
||||
*/
|
||||
function needParenthesis(node, parenthesis, implicit) {
|
||||
if (!parenthesis) {
|
||||
parenthesis = 'keep';
|
||||
}
|
||||
const precedence = (0, _operators.getPrecedence)(node, parenthesis, implicit);
|
||||
const exprPrecedence = (0, _operators.getPrecedence)(node.value, parenthesis, implicit);
|
||||
return parenthesis === 'all' || exprPrecedence !== null && exprPrecedence <= precedence;
|
||||
}
|
||||
class AssignmentNode extends Node {
|
||||
/**
|
||||
* @constructor AssignmentNode
|
||||
* @extends {Node}
|
||||
*
|
||||
* Define a symbol, like `a=3.2`, update a property like `a.b=3.2`, or
|
||||
* replace a subset of a matrix like `A[2,2]=42`.
|
||||
*
|
||||
* Syntax:
|
||||
*
|
||||
* new AssignmentNode(symbol, value)
|
||||
* new AssignmentNode(object, index, value)
|
||||
*
|
||||
* Usage:
|
||||
*
|
||||
* new AssignmentNode(new SymbolNode('a'), new ConstantNode(2)) // a=2
|
||||
* new AssignmentNode(new SymbolNode('a'),
|
||||
* new IndexNode('b'),
|
||||
* new ConstantNode(2)) // a.b=2
|
||||
* new AssignmentNode(new SymbolNode('a'),
|
||||
* new IndexNode(1, 2),
|
||||
* new ConstantNode(3)) // a[1,2]=3
|
||||
*
|
||||
* @param {SymbolNode | AccessorNode} object
|
||||
* Object on which to assign a value
|
||||
* @param {IndexNode} [index=null]
|
||||
* Index, property name or matrix index. Optional. If not provided
|
||||
* and `object` is a SymbolNode, the property is assigned to the
|
||||
* global scope.
|
||||
* @param {Node} value
|
||||
* The value to be assigned
|
||||
*/
|
||||
constructor(object, index, value) {
|
||||
super();
|
||||
this.object = object;
|
||||
this.index = value ? index : null;
|
||||
this.value = value || index;
|
||||
|
||||
// validate input
|
||||
if (!(0, _is.isSymbolNode)(object) && !(0, _is.isAccessorNode)(object)) {
|
||||
throw new TypeError('SymbolNode or AccessorNode expected as "object"');
|
||||
}
|
||||
if ((0, _is.isSymbolNode)(object) && object.name === 'end') {
|
||||
throw new Error('Cannot assign to symbol "end"');
|
||||
}
|
||||
if (this.index && !(0, _is.isIndexNode)(this.index)) {
|
||||
// index is optional
|
||||
throw new TypeError('IndexNode expected as "index"');
|
||||
}
|
||||
if (!(0, _is.isNode)(this.value)) {
|
||||
throw new TypeError('Node expected as "value"');
|
||||
}
|
||||
}
|
||||
|
||||
// class name for typing purposes:
|
||||
|
||||
// readonly property name
|
||||
get name() {
|
||||
if (this.index) {
|
||||
return this.index.isObjectProperty() ? this.index.getObjectProperty() : '';
|
||||
} else {
|
||||
return this.object.name || '';
|
||||
}
|
||||
}
|
||||
get type() {
|
||||
return name;
|
||||
}
|
||||
get isAssignmentNode() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile a node into a JavaScript function.
|
||||
* This basically pre-calculates as much as possible and only leaves open
|
||||
* calculations which depend on a dynamic scope with variables.
|
||||
* @param {Object} math Math.js namespace with functions and constants.
|
||||
* @param {Object} argNames An object with argument names as key and `true`
|
||||
* as value. Used in the SymbolNode to optimize
|
||||
* for arguments from user assigned functions
|
||||
* (see FunctionAssignmentNode) or special symbols
|
||||
* like `end` (see IndexNode).
|
||||
* @return {function} Returns a function which can be called like:
|
||||
* evalNode(scope: Object, args: Object, context: *)
|
||||
*/
|
||||
_compile(math, argNames) {
|
||||
const evalObject = this.object._compile(math, argNames);
|
||||
const evalIndex = this.index ? this.index._compile(math, argNames) : null;
|
||||
const evalValue = this.value._compile(math, argNames);
|
||||
const name = this.object.name;
|
||||
if (!this.index) {
|
||||
// apply a variable to the scope, for example `a=2`
|
||||
if (!(0, _is.isSymbolNode)(this.object)) {
|
||||
throw new TypeError('SymbolNode expected as object');
|
||||
}
|
||||
return function evalAssignmentNode(scope, args, context) {
|
||||
const value = evalValue(scope, args, context);
|
||||
scope.set(name, value);
|
||||
return value;
|
||||
};
|
||||
} else if (this.index.isObjectProperty()) {
|
||||
// apply an object property for example `a.b=2`
|
||||
const prop = this.index.getObjectProperty();
|
||||
return function evalAssignmentNode(scope, args, context) {
|
||||
const object = evalObject(scope, args, context);
|
||||
const value = evalValue(scope, args, context);
|
||||
(0, _customs.setSafeProperty)(object, prop, value);
|
||||
return value;
|
||||
};
|
||||
} else if ((0, _is.isSymbolNode)(this.object)) {
|
||||
// update a matrix subset, for example `a[2]=3`
|
||||
return function evalAssignmentNode(scope, args, context) {
|
||||
const childObject = evalObject(scope, args, context);
|
||||
const value = evalValue(scope, args, context);
|
||||
// Important: we pass childObject instead of context:
|
||||
const index = evalIndex(scope, args, childObject);
|
||||
scope.set(name, assign(childObject, index, value));
|
||||
return value;
|
||||
};
|
||||
} else {
|
||||
// isAccessorNode(node.object) === true
|
||||
// update a matrix subset, for example `a.b[2]=3`
|
||||
|
||||
// we will not use the compile function of the AccessorNode, but
|
||||
// compile it ourselves here as we need the parent object of the
|
||||
// AccessorNode:
|
||||
// wee need to apply the updated object to parent object
|
||||
const evalParentObject = this.object.object._compile(math, argNames);
|
||||
if (this.object.index.isObjectProperty()) {
|
||||
const parentProp = this.object.index.getObjectProperty();
|
||||
return function evalAssignmentNode(scope, args, context) {
|
||||
const parent = evalParentObject(scope, args, context);
|
||||
const childObject = (0, _customs.getSafeProperty)(parent, parentProp);
|
||||
// Important: we pass childObject instead of context:
|
||||
const index = evalIndex(scope, args, childObject);
|
||||
const value = evalValue(scope, args, context);
|
||||
(0, _customs.setSafeProperty)(parent, parentProp, assign(childObject, index, value));
|
||||
return value;
|
||||
};
|
||||
} else {
|
||||
// if some parameters use the 'end' parameter, we need to calculate
|
||||
// the size
|
||||
const evalParentIndex = this.object.index._compile(math, argNames);
|
||||
return function evalAssignmentNode(scope, args, context) {
|
||||
const parent = evalParentObject(scope, args, context);
|
||||
// Important: we pass parent instead of context:
|
||||
const parentIndex = evalParentIndex(scope, args, parent);
|
||||
const childObject = access(parent, parentIndex);
|
||||
// Important: we pass childObject instead of context
|
||||
const index = evalIndex(scope, args, childObject);
|
||||
const value = evalValue(scope, args, context);
|
||||
assign(parent, parentIndex, assign(childObject, index, value));
|
||||
return value;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a callback for each of the child nodes of this node
|
||||
* @param {function(child: Node, path: string, parent: Node)} callback
|
||||
*/
|
||||
forEach(callback) {
|
||||
callback(this.object, 'object', this);
|
||||
if (this.index) {
|
||||
callback(this.index, 'index', this);
|
||||
}
|
||||
callback(this.value, 'value', this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new AssignmentNode whose children are the results of calling
|
||||
* the provided callback function for each child of the original node.
|
||||
* @param {function(child: Node, path: string, parent: Node): Node} callback
|
||||
* @returns {AssignmentNode} Returns a transformed copy of the node
|
||||
*/
|
||||
map(callback) {
|
||||
const object = this._ifNode(callback(this.object, 'object', this));
|
||||
const index = this.index ? this._ifNode(callback(this.index, 'index', this)) : null;
|
||||
const value = this._ifNode(callback(this.value, 'value', this));
|
||||
return new AssignmentNode(object, index, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a clone of this node, a shallow copy
|
||||
* @return {AssignmentNode}
|
||||
*/
|
||||
clone() {
|
||||
return new AssignmentNode(this.object, this.index, this.value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get string representation
|
||||
* @param {Object} options
|
||||
* @return {string}
|
||||
*/
|
||||
_toString(options) {
|
||||
const object = this.object.toString(options);
|
||||
const index = this.index ? this.index.toString(options) : '';
|
||||
let value = this.value.toString(options);
|
||||
if (needParenthesis(this, options && options.parenthesis, options && options.implicit)) {
|
||||
value = '(' + value + ')';
|
||||
}
|
||||
return object + index + ' = ' + value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a JSON representation of the node
|
||||
* @returns {Object}
|
||||
*/
|
||||
toJSON() {
|
||||
return {
|
||||
mathjs: name,
|
||||
object: this.object,
|
||||
index: this.index,
|
||||
value: this.value
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiate an AssignmentNode from its JSON representation
|
||||
* @param {Object} json
|
||||
* An object structured like
|
||||
* `{"mathjs": "AssignmentNode", object: ..., index: ..., value: ...}`,
|
||||
* where mathjs is optional
|
||||
* @returns {AssignmentNode}
|
||||
*/
|
||||
static fromJSON(json) {
|
||||
return new AssignmentNode(json.object, json.index, json.value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get HTML representation
|
||||
* @param {Object} options
|
||||
* @return {string}
|
||||
*/
|
||||
_toHTML(options) {
|
||||
const object = this.object.toHTML(options);
|
||||
const index = this.index ? this.index.toHTML(options) : '';
|
||||
let value = this.value.toHTML(options);
|
||||
if (needParenthesis(this, options && options.parenthesis, options && options.implicit)) {
|
||||
value = '<span class="math-paranthesis math-round-parenthesis">(</span>' + value + '<span class="math-paranthesis math-round-parenthesis">)</span>';
|
||||
}
|
||||
return object + index + '<span class="math-operator math-assignment-operator ' + 'math-variable-assignment-operator math-binary-operator">=</span>' + value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get LaTeX representation
|
||||
* @param {Object} options
|
||||
* @return {string}
|
||||
*/
|
||||
_toTex(options) {
|
||||
const object = this.object.toTex(options);
|
||||
const index = this.index ? this.index.toTex(options) : '';
|
||||
let value = this.value.toTex(options);
|
||||
if (needParenthesis(this, options && options.parenthesis, options && options.implicit)) {
|
||||
value = `\\left(${value}\\right)`;
|
||||
}
|
||||
return object + index + '=' + value;
|
||||
}
|
||||
}
|
||||
(0, _defineProperty2.default)(AssignmentNode, "name", name);
|
||||
return AssignmentNode;
|
||||
}, {
|
||||
isClass: true,
|
||||
isNode: true
|
||||
});
|
||||
192
node_modules/mathjs/lib/cjs/expression/node/BlockNode.js
generated
vendored
Normal file
192
node_modules/mathjs/lib/cjs/expression/node/BlockNode.js
generated
vendored
Normal file
@@ -0,0 +1,192 @@
|
||||
"use strict";
|
||||
|
||||
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.createBlockNode = void 0;
|
||||
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
||||
var _is = require("../../utils/is.js");
|
||||
var _array = require("../../utils/array.js");
|
||||
var _factory = require("../../utils/factory.js");
|
||||
const name = 'BlockNode';
|
||||
const dependencies = ['ResultSet', 'Node'];
|
||||
const createBlockNode = exports.createBlockNode = /* #__PURE__ */(0, _factory.factory)(name, dependencies, _ref => {
|
||||
let {
|
||||
ResultSet,
|
||||
Node
|
||||
} = _ref;
|
||||
class BlockNode extends Node {
|
||||
/**
|
||||
* @constructor BlockNode
|
||||
* @extends {Node}
|
||||
* Holds a set with blocks
|
||||
* @param {Array.<{node: Node} | {node: Node, visible: boolean}>} blocks
|
||||
* An array with blocks, where a block is constructed as an
|
||||
* Object with properties block, which is a Node, and visible,
|
||||
* which is a boolean. The property visible is optional and
|
||||
* is true by default
|
||||
*/
|
||||
constructor(blocks) {
|
||||
super();
|
||||
// validate input, copy blocks
|
||||
if (!Array.isArray(blocks)) throw new Error('Array expected');
|
||||
this.blocks = blocks.map(function (block) {
|
||||
const node = block && block.node;
|
||||
const visible = block && block.visible !== undefined ? block.visible : true;
|
||||
if (!(0, _is.isNode)(node)) throw new TypeError('Property "node" must be a Node');
|
||||
if (typeof visible !== 'boolean') {
|
||||
throw new TypeError('Property "visible" must be a boolean');
|
||||
}
|
||||
return {
|
||||
node,
|
||||
visible
|
||||
};
|
||||
});
|
||||
}
|
||||
get type() {
|
||||
return name;
|
||||
}
|
||||
get isBlockNode() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile a node into a JavaScript function.
|
||||
* This basically pre-calculates as much as possible and only leaves open
|
||||
* calculations which depend on a dynamic scope with variables.
|
||||
* @param {Object} math Math.js namespace with functions and constants.
|
||||
* @param {Object} argNames An object with argument names as key and `true`
|
||||
* as value. Used in the SymbolNode to optimize
|
||||
* for arguments from user assigned functions
|
||||
* (see FunctionAssignmentNode) or special symbols
|
||||
* like `end` (see IndexNode).
|
||||
* @return {function} Returns a function which can be called like:
|
||||
* evalNode(scope: Object, args: Object, context: *)
|
||||
*/
|
||||
_compile(math, argNames) {
|
||||
const evalBlocks = (0, _array.map)(this.blocks, function (block) {
|
||||
return {
|
||||
evaluate: block.node._compile(math, argNames),
|
||||
visible: block.visible
|
||||
};
|
||||
});
|
||||
return function evalBlockNodes(scope, args, context) {
|
||||
const results = [];
|
||||
(0, _array.forEach)(evalBlocks, function evalBlockNode(block) {
|
||||
const result = block.evaluate(scope, args, context);
|
||||
if (block.visible) {
|
||||
results.push(result);
|
||||
}
|
||||
});
|
||||
return new ResultSet(results);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a callback for each of the child blocks of this node
|
||||
* @param {function(child: Node, path: string, parent: Node)} callback
|
||||
*/
|
||||
forEach(callback) {
|
||||
for (let i = 0; i < this.blocks.length; i++) {
|
||||
callback(this.blocks[i].node, 'blocks[' + i + '].node', this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new BlockNode whose children are the results of calling
|
||||
* the provided callback function for each child of the original node.
|
||||
* @param {function(child: Node, path: string, parent: Node): Node} callback
|
||||
* @returns {BlockNode} Returns a transformed copy of the node
|
||||
*/
|
||||
map(callback) {
|
||||
const blocks = [];
|
||||
for (let i = 0; i < this.blocks.length; i++) {
|
||||
const block = this.blocks[i];
|
||||
const node = this._ifNode(callback(block.node, 'blocks[' + i + '].node', this));
|
||||
blocks[i] = {
|
||||
node,
|
||||
visible: block.visible
|
||||
};
|
||||
}
|
||||
return new BlockNode(blocks);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a clone of this node, a shallow copy
|
||||
* @return {BlockNode}
|
||||
*/
|
||||
clone() {
|
||||
const blocks = this.blocks.map(function (block) {
|
||||
return {
|
||||
node: block.node,
|
||||
visible: block.visible
|
||||
};
|
||||
});
|
||||
return new BlockNode(blocks);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get string representation
|
||||
* @param {Object} options
|
||||
* @return {string} str
|
||||
* @override
|
||||
*/
|
||||
_toString(options) {
|
||||
return this.blocks.map(function (param) {
|
||||
return param.node.toString(options) + (param.visible ? '' : ';');
|
||||
}).join('\n');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a JSON representation of the node
|
||||
* @returns {Object}
|
||||
*/
|
||||
toJSON() {
|
||||
return {
|
||||
mathjs: name,
|
||||
blocks: this.blocks
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiate an BlockNode from its JSON representation
|
||||
* @param {Object} json
|
||||
* An object structured like
|
||||
* `{"mathjs": "BlockNode", blocks: [{node: ..., visible: false}, ...]}`,
|
||||
* where mathjs is optional
|
||||
* @returns {BlockNode}
|
||||
*/
|
||||
static fromJSON(json) {
|
||||
return new BlockNode(json.blocks);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get HTML representation
|
||||
* @param {Object} options
|
||||
* @return {string} str
|
||||
* @override
|
||||
*/
|
||||
_toHTML(options) {
|
||||
return this.blocks.map(function (param) {
|
||||
return param.node.toHTML(options) + (param.visible ? '' : '<span class="math-separator">;</span>');
|
||||
}).join('<span class="math-separator"><br /></span>');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get LaTeX representation
|
||||
* @param {Object} options
|
||||
* @return {string} str
|
||||
*/
|
||||
_toTex(options) {
|
||||
return this.blocks.map(function (param) {
|
||||
return param.node.toTex(options) + (param.visible ? '' : ';');
|
||||
}).join('\\;\\;\n');
|
||||
}
|
||||
}
|
||||
(0, _defineProperty2.default)(BlockNode, "name", name);
|
||||
return BlockNode;
|
||||
}, {
|
||||
isClass: true,
|
||||
isNode: true
|
||||
});
|
||||
232
node_modules/mathjs/lib/cjs/expression/node/ConditionalNode.js
generated
vendored
Normal file
232
node_modules/mathjs/lib/cjs/expression/node/ConditionalNode.js
generated
vendored
Normal file
@@ -0,0 +1,232 @@
|
||||
"use strict";
|
||||
|
||||
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.createConditionalNode = void 0;
|
||||
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
||||
var _is = require("../../utils/is.js");
|
||||
var _factory = require("../../utils/factory.js");
|
||||
var _operators = require("../operators.js");
|
||||
const name = 'ConditionalNode';
|
||||
const dependencies = ['Node'];
|
||||
const createConditionalNode = exports.createConditionalNode = /* #__PURE__ */(0, _factory.factory)(name, dependencies, _ref => {
|
||||
let {
|
||||
Node
|
||||
} = _ref;
|
||||
/**
|
||||
* Test whether a condition is met
|
||||
* @param {*} condition
|
||||
* @returns {boolean} true if condition is true or non-zero, else false
|
||||
*/
|
||||
function testCondition(condition) {
|
||||
if (typeof condition === 'number' || typeof condition === 'boolean' || typeof condition === 'string') {
|
||||
return !!condition;
|
||||
}
|
||||
if (condition) {
|
||||
if ((0, _is.isBigNumber)(condition)) {
|
||||
return !condition.isZero();
|
||||
}
|
||||
if ((0, _is.isComplex)(condition)) {
|
||||
return !!(condition.re || condition.im);
|
||||
}
|
||||
if ((0, _is.isUnit)(condition)) {
|
||||
return !!condition.value;
|
||||
}
|
||||
}
|
||||
if (condition === null || condition === undefined) {
|
||||
return false;
|
||||
}
|
||||
throw new TypeError('Unsupported type of condition "' + (0, _is.typeOf)(condition) + '"');
|
||||
}
|
||||
class ConditionalNode extends Node {
|
||||
/**
|
||||
* A lazy evaluating conditional operator: 'condition ? trueExpr : falseExpr'
|
||||
*
|
||||
* @param {Node} condition Condition, must result in a boolean
|
||||
* @param {Node} trueExpr Expression evaluated when condition is true
|
||||
* @param {Node} falseExpr Expression evaluated when condition is true
|
||||
*
|
||||
* @constructor ConditionalNode
|
||||
* @extends {Node}
|
||||
*/
|
||||
constructor(condition, trueExpr, falseExpr) {
|
||||
super();
|
||||
if (!(0, _is.isNode)(condition)) {
|
||||
throw new TypeError('Parameter condition must be a Node');
|
||||
}
|
||||
if (!(0, _is.isNode)(trueExpr)) {
|
||||
throw new TypeError('Parameter trueExpr must be a Node');
|
||||
}
|
||||
if (!(0, _is.isNode)(falseExpr)) {
|
||||
throw new TypeError('Parameter falseExpr must be a Node');
|
||||
}
|
||||
this.condition = condition;
|
||||
this.trueExpr = trueExpr;
|
||||
this.falseExpr = falseExpr;
|
||||
}
|
||||
get type() {
|
||||
return name;
|
||||
}
|
||||
get isConditionalNode() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile a node into a JavaScript function.
|
||||
* This basically pre-calculates as much as possible and only leaves open
|
||||
* calculations which depend on a dynamic scope with variables.
|
||||
* @param {Object} math Math.js namespace with functions and constants.
|
||||
* @param {Object} argNames An object with argument names as key and `true`
|
||||
* as value. Used in the SymbolNode to optimize
|
||||
* for arguments from user assigned functions
|
||||
* (see FunctionAssignmentNode) or special symbols
|
||||
* like `end` (see IndexNode).
|
||||
* @return {function} Returns a function which can be called like:
|
||||
* evalNode(scope: Object, args: Object, context: *)
|
||||
*/
|
||||
_compile(math, argNames) {
|
||||
const evalCondition = this.condition._compile(math, argNames);
|
||||
const evalTrueExpr = this.trueExpr._compile(math, argNames);
|
||||
const evalFalseExpr = this.falseExpr._compile(math, argNames);
|
||||
return function evalConditionalNode(scope, args, context) {
|
||||
return testCondition(evalCondition(scope, args, context)) ? evalTrueExpr(scope, args, context) : evalFalseExpr(scope, args, context);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a callback for each of the child nodes of this node
|
||||
* @param {function(child: Node, path: string, parent: Node)} callback
|
||||
*/
|
||||
forEach(callback) {
|
||||
callback(this.condition, 'condition', this);
|
||||
callback(this.trueExpr, 'trueExpr', this);
|
||||
callback(this.falseExpr, 'falseExpr', this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new ConditionalNode whose children are the results of calling
|
||||
* the provided callback function for each child of the original node.
|
||||
* @param {function(child: Node, path: string, parent: Node): Node} callback
|
||||
* @returns {ConditionalNode} Returns a transformed copy of the node
|
||||
*/
|
||||
map(callback) {
|
||||
return new ConditionalNode(this._ifNode(callback(this.condition, 'condition', this)), this._ifNode(callback(this.trueExpr, 'trueExpr', this)), this._ifNode(callback(this.falseExpr, 'falseExpr', this)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a clone of this node, a shallow copy
|
||||
* @return {ConditionalNode}
|
||||
*/
|
||||
clone() {
|
||||
return new ConditionalNode(this.condition, this.trueExpr, this.falseExpr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get string representation
|
||||
* @param {Object} options
|
||||
* @return {string} str
|
||||
*/
|
||||
_toString(options) {
|
||||
const parenthesis = options && options.parenthesis ? options.parenthesis : 'keep';
|
||||
const precedence = (0, _operators.getPrecedence)(this, parenthesis, options && options.implicit);
|
||||
|
||||
// Enclose Arguments in parentheses if they are an OperatorNode
|
||||
// or have lower or equal precedence
|
||||
// NOTE: enclosing all OperatorNodes in parentheses is a decision
|
||||
// purely based on aesthetics and readability
|
||||
let condition = this.condition.toString(options);
|
||||
const conditionPrecedence = (0, _operators.getPrecedence)(this.condition, parenthesis, options && options.implicit);
|
||||
if (parenthesis === 'all' || this.condition.type === 'OperatorNode' || conditionPrecedence !== null && conditionPrecedence <= precedence) {
|
||||
condition = '(' + condition + ')';
|
||||
}
|
||||
let trueExpr = this.trueExpr.toString(options);
|
||||
const truePrecedence = (0, _operators.getPrecedence)(this.trueExpr, parenthesis, options && options.implicit);
|
||||
if (parenthesis === 'all' || this.trueExpr.type === 'OperatorNode' || truePrecedence !== null && truePrecedence <= precedence) {
|
||||
trueExpr = '(' + trueExpr + ')';
|
||||
}
|
||||
let falseExpr = this.falseExpr.toString(options);
|
||||
const falsePrecedence = (0, _operators.getPrecedence)(this.falseExpr, parenthesis, options && options.implicit);
|
||||
if (parenthesis === 'all' || this.falseExpr.type === 'OperatorNode' || falsePrecedence !== null && falsePrecedence <= precedence) {
|
||||
falseExpr = '(' + falseExpr + ')';
|
||||
}
|
||||
return condition + ' ? ' + trueExpr + ' : ' + falseExpr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a JSON representation of the node
|
||||
* @returns {Object}
|
||||
*/
|
||||
toJSON() {
|
||||
return {
|
||||
mathjs: name,
|
||||
condition: this.condition,
|
||||
trueExpr: this.trueExpr,
|
||||
falseExpr: this.falseExpr
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiate an ConditionalNode from its JSON representation
|
||||
* @param {Object} json
|
||||
* An object structured like
|
||||
* ```
|
||||
* {"mathjs": "ConditionalNode",
|
||||
* "condition": ...,
|
||||
* "trueExpr": ...,
|
||||
* "falseExpr": ...}
|
||||
* ```
|
||||
* where mathjs is optional
|
||||
* @returns {ConditionalNode}
|
||||
*/
|
||||
static fromJSON(json) {
|
||||
return new ConditionalNode(json.condition, json.trueExpr, json.falseExpr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get HTML representation
|
||||
* @param {Object} options
|
||||
* @return {string} str
|
||||
*/
|
||||
_toHTML(options) {
|
||||
const parenthesis = options && options.parenthesis ? options.parenthesis : 'keep';
|
||||
const precedence = (0, _operators.getPrecedence)(this, parenthesis, options && options.implicit);
|
||||
|
||||
// Enclose Arguments in parentheses if they are an OperatorNode
|
||||
// or have lower or equal precedence
|
||||
// NOTE: enclosing all OperatorNodes in parentheses is a decision
|
||||
// purely based on aesthetics and readability
|
||||
let condition = this.condition.toHTML(options);
|
||||
const conditionPrecedence = (0, _operators.getPrecedence)(this.condition, parenthesis, options && options.implicit);
|
||||
if (parenthesis === 'all' || this.condition.type === 'OperatorNode' || conditionPrecedence !== null && conditionPrecedence <= precedence) {
|
||||
condition = '<span class="math-parenthesis math-round-parenthesis">(</span>' + condition + '<span class="math-parenthesis math-round-parenthesis">)</span>';
|
||||
}
|
||||
let trueExpr = this.trueExpr.toHTML(options);
|
||||
const truePrecedence = (0, _operators.getPrecedence)(this.trueExpr, parenthesis, options && options.implicit);
|
||||
if (parenthesis === 'all' || this.trueExpr.type === 'OperatorNode' || truePrecedence !== null && truePrecedence <= precedence) {
|
||||
trueExpr = '<span class="math-parenthesis math-round-parenthesis">(</span>' + trueExpr + '<span class="math-parenthesis math-round-parenthesis">)</span>';
|
||||
}
|
||||
let falseExpr = this.falseExpr.toHTML(options);
|
||||
const falsePrecedence = (0, _operators.getPrecedence)(this.falseExpr, parenthesis, options && options.implicit);
|
||||
if (parenthesis === 'all' || this.falseExpr.type === 'OperatorNode' || falsePrecedence !== null && falsePrecedence <= precedence) {
|
||||
falseExpr = '<span class="math-parenthesis math-round-parenthesis">(</span>' + falseExpr + '<span class="math-parenthesis math-round-parenthesis">)</span>';
|
||||
}
|
||||
return condition + '<span class="math-operator math-conditional-operator">?</span>' + trueExpr + '<span class="math-operator math-conditional-operator">:</span>' + falseExpr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get LaTeX representation
|
||||
* @param {Object} options
|
||||
* @return {string} str
|
||||
*/
|
||||
_toTex(options) {
|
||||
return '\\begin{cases} {' + this.trueExpr.toTex(options) + '}, &\\quad{\\text{if }\\;' + this.condition.toTex(options) + '}\\\\{' + this.falseExpr.toTex(options) + '}, &\\quad{\\text{otherwise}}\\end{cases}';
|
||||
}
|
||||
}
|
||||
(0, _defineProperty2.default)(ConditionalNode, "name", name);
|
||||
return ConditionalNode;
|
||||
}, {
|
||||
isClass: true,
|
||||
isNode: true
|
||||
});
|
||||
186
node_modules/mathjs/lib/cjs/expression/node/ConstantNode.js
generated
vendored
Normal file
186
node_modules/mathjs/lib/cjs/expression/node/ConstantNode.js
generated
vendored
Normal file
@@ -0,0 +1,186 @@
|
||||
"use strict";
|
||||
|
||||
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.createConstantNode = void 0;
|
||||
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
||||
var _string = require("../../utils/string.js");
|
||||
var _is = require("../../utils/is.js");
|
||||
var _latex = require("../../utils/latex.js");
|
||||
var _factory = require("../../utils/factory.js");
|
||||
const name = 'ConstantNode';
|
||||
const dependencies = ['Node'];
|
||||
const createConstantNode = exports.createConstantNode = /* #__PURE__ */(0, _factory.factory)(name, dependencies, _ref => {
|
||||
let {
|
||||
Node
|
||||
} = _ref;
|
||||
class ConstantNode extends Node {
|
||||
/**
|
||||
* A ConstantNode holds a constant value like a number or string.
|
||||
*
|
||||
* Usage:
|
||||
*
|
||||
* new ConstantNode(2.3)
|
||||
* new ConstantNode('hello')
|
||||
*
|
||||
* @param {*} value Value can be any type (number, BigNumber, bigint, string, ...)
|
||||
* @constructor ConstantNode
|
||||
* @extends {Node}
|
||||
*/
|
||||
constructor(value) {
|
||||
super();
|
||||
this.value = value;
|
||||
}
|
||||
get type() {
|
||||
return name;
|
||||
}
|
||||
get isConstantNode() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile a node into a JavaScript function.
|
||||
* This basically pre-calculates as much as possible and only leaves open
|
||||
* calculations which depend on a dynamic scope with variables.
|
||||
* @param {Object} math Math.js namespace with functions and constants.
|
||||
* @param {Object} argNames An object with argument names as key and `true`
|
||||
* as value. Used in the SymbolNode to optimize
|
||||
* for arguments from user assigned functions
|
||||
* (see FunctionAssignmentNode) or special symbols
|
||||
* like `end` (see IndexNode).
|
||||
* @return {function} Returns a function which can be called like:
|
||||
* evalNode(scope: Object, args: Object, context: *)
|
||||
*/
|
||||
_compile(math, argNames) {
|
||||
const value = this.value;
|
||||
return function evalConstantNode() {
|
||||
return value;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a callback for each of the child nodes of this node
|
||||
* @param {function(child: Node, path: string, parent: Node)} callback
|
||||
*/
|
||||
forEach(callback) {
|
||||
// nothing to do, we don't have any children
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new ConstantNode with children produced by the given callback.
|
||||
* Trivial because there are no children.
|
||||
* @param {function(child: Node, path: string, parent: Node) : Node} callback
|
||||
* @returns {ConstantNode} Returns a clone of the node
|
||||
*/
|
||||
map(callback) {
|
||||
return this.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a clone of this node, a shallow copy
|
||||
* @return {ConstantNode}
|
||||
*/
|
||||
clone() {
|
||||
return new ConstantNode(this.value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get string representation
|
||||
* @param {Object} options
|
||||
* @return {string} str
|
||||
*/
|
||||
_toString(options) {
|
||||
return (0, _string.format)(this.value, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get HTML representation
|
||||
* @param {Object} options
|
||||
* @return {string} str
|
||||
*/
|
||||
_toHTML(options) {
|
||||
const value = this._toString(options);
|
||||
switch ((0, _is.typeOf)(this.value)) {
|
||||
case 'number':
|
||||
case 'bigint':
|
||||
case 'BigNumber':
|
||||
case 'Fraction':
|
||||
return '<span class="math-number">' + value + '</span>';
|
||||
case 'string':
|
||||
return '<span class="math-string">' + value + '</span>';
|
||||
case 'boolean':
|
||||
return '<span class="math-boolean">' + value + '</span>';
|
||||
case 'null':
|
||||
return '<span class="math-null-symbol">' + value + '</span>';
|
||||
case 'undefined':
|
||||
return '<span class="math-undefined">' + value + '</span>';
|
||||
default:
|
||||
return '<span class="math-symbol">' + value + '</span>';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a JSON representation of the node
|
||||
* @returns {Object}
|
||||
*/
|
||||
toJSON() {
|
||||
return {
|
||||
mathjs: name,
|
||||
value: this.value
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiate a ConstantNode from its JSON representation
|
||||
* @param {Object} json An object structured like
|
||||
* `{"mathjs": "SymbolNode", value: 2.3}`,
|
||||
* where mathjs is optional
|
||||
* @returns {ConstantNode}
|
||||
*/
|
||||
static fromJSON(json) {
|
||||
return new ConstantNode(json.value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get LaTeX representation
|
||||
* @param {Object} options
|
||||
* @return {string} str
|
||||
*/
|
||||
_toTex(options) {
|
||||
const value = this._toString(options);
|
||||
const type = (0, _is.typeOf)(this.value);
|
||||
switch (type) {
|
||||
case 'string':
|
||||
return '\\mathtt{' + (0, _latex.escapeLatex)(value) + '}';
|
||||
case 'number':
|
||||
case 'BigNumber':
|
||||
{
|
||||
const finite = type === 'BigNumber' ? this.value.isFinite() : isFinite(this.value);
|
||||
if (!finite) {
|
||||
return this.value.valueOf() < 0 ? '-\\infty' : '\\infty';
|
||||
}
|
||||
const index = value.toLowerCase().indexOf('e');
|
||||
if (index !== -1) {
|
||||
return value.substring(0, index) + '\\cdot10^{' + value.substring(index + 1) + '}';
|
||||
}
|
||||
return value;
|
||||
}
|
||||
case 'bigint':
|
||||
{
|
||||
return value.toString();
|
||||
}
|
||||
case 'Fraction':
|
||||
return this.value.toLatex();
|
||||
default:
|
||||
return value;
|
||||
}
|
||||
}
|
||||
}
|
||||
(0, _defineProperty2.default)(ConstantNode, "name", name);
|
||||
return ConstantNode;
|
||||
}, {
|
||||
isClass: true,
|
||||
isNode: true
|
||||
});
|
||||
242
node_modules/mathjs/lib/cjs/expression/node/FunctionAssignmentNode.js
generated
vendored
Normal file
242
node_modules/mathjs/lib/cjs/expression/node/FunctionAssignmentNode.js
generated
vendored
Normal file
@@ -0,0 +1,242 @@
|
||||
"use strict";
|
||||
|
||||
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.createFunctionAssignmentNode = void 0;
|
||||
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
||||
var _is = require("../../utils/is.js");
|
||||
var _keywords = require("../keywords.js");
|
||||
var _string = require("../../utils/string.js");
|
||||
var _array = require("../../utils/array.js");
|
||||
var _latex = require("../../utils/latex.js");
|
||||
var _operators = require("../operators.js");
|
||||
var _factory = require("../../utils/factory.js");
|
||||
const name = 'FunctionAssignmentNode';
|
||||
const dependencies = ['typed', 'Node'];
|
||||
const createFunctionAssignmentNode = exports.createFunctionAssignmentNode = /* #__PURE__ */(0, _factory.factory)(name, dependencies, _ref => {
|
||||
let {
|
||||
typed,
|
||||
Node
|
||||
} = _ref;
|
||||
/**
|
||||
* Is parenthesis needed?
|
||||
* @param {Node} node
|
||||
* @param {Object} parenthesis
|
||||
* @param {string} implicit
|
||||
* @private
|
||||
*/
|
||||
function needParenthesis(node, parenthesis, implicit) {
|
||||
const precedence = (0, _operators.getPrecedence)(node, parenthesis, implicit);
|
||||
const exprPrecedence = (0, _operators.getPrecedence)(node.expr, parenthesis, implicit);
|
||||
return parenthesis === 'all' || exprPrecedence !== null && exprPrecedence <= precedence;
|
||||
}
|
||||
class FunctionAssignmentNode extends Node {
|
||||
/**
|
||||
* @constructor FunctionAssignmentNode
|
||||
* @extends {Node}
|
||||
* Function assignment
|
||||
*
|
||||
* @param {string} name Function name
|
||||
* @param {string[] | Array.<{name: string, type: string}>} params
|
||||
* Array with function parameter names, or an
|
||||
* array with objects containing the name
|
||||
* and type of the parameter
|
||||
* @param {Node} expr The function expression
|
||||
*/
|
||||
constructor(name, params, expr) {
|
||||
super();
|
||||
// validate input
|
||||
if (typeof name !== 'string') {
|
||||
throw new TypeError('String expected for parameter "name"');
|
||||
}
|
||||
if (!Array.isArray(params)) {
|
||||
throw new TypeError('Array containing strings or objects expected for parameter "params"');
|
||||
}
|
||||
if (!(0, _is.isNode)(expr)) {
|
||||
throw new TypeError('Node expected for parameter "expr"');
|
||||
}
|
||||
if (_keywords.keywords.has(name)) {
|
||||
throw new Error('Illegal function name, "' + name + '" is a reserved keyword');
|
||||
}
|
||||
const paramNames = new Set();
|
||||
for (const param of params) {
|
||||
const name = typeof param === 'string' ? param : param.name;
|
||||
if (paramNames.has(name)) {
|
||||
throw new Error(`Duplicate parameter name "${name}"`);
|
||||
} else {
|
||||
paramNames.add(name);
|
||||
}
|
||||
}
|
||||
this.name = name;
|
||||
this.params = params.map(function (param) {
|
||||
return param && param.name || param;
|
||||
});
|
||||
this.types = params.map(function (param) {
|
||||
return param && param.type || 'any';
|
||||
});
|
||||
this.expr = expr;
|
||||
}
|
||||
get type() {
|
||||
return name;
|
||||
}
|
||||
get isFunctionAssignmentNode() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile a node into a JavaScript function.
|
||||
* This basically pre-calculates as much as possible and only leaves open
|
||||
* calculations which depend on a dynamic scope with variables.
|
||||
* @param {Object} math Math.js namespace with functions and constants.
|
||||
* @param {Object} argNames An object with argument names as key and `true`
|
||||
* as value. Used in the SymbolNode to optimize
|
||||
* for arguments from user assigned functions
|
||||
* (see FunctionAssignmentNode) or special symbols
|
||||
* like `end` (see IndexNode).
|
||||
* @return {function} Returns a function which can be called like:
|
||||
* evalNode(scope: Object, args: Object, context: *)
|
||||
*/
|
||||
_compile(math, argNames) {
|
||||
const childArgNames = Object.create(argNames);
|
||||
(0, _array.forEach)(this.params, function (param) {
|
||||
childArgNames[param] = true;
|
||||
});
|
||||
|
||||
// compile the function expression with the child args
|
||||
const evalExpr = this.expr._compile(math, childArgNames);
|
||||
const name = this.name;
|
||||
const params = this.params;
|
||||
const signature = (0, _array.join)(this.types, ',');
|
||||
const syntax = name + '(' + (0, _array.join)(this.params, ', ') + ')';
|
||||
return function evalFunctionAssignmentNode(scope, args, context) {
|
||||
const signatures = {};
|
||||
signatures[signature] = function () {
|
||||
const childArgs = Object.create(args);
|
||||
for (let i = 0; i < params.length; i++) {
|
||||
childArgs[params[i]] = arguments[i];
|
||||
}
|
||||
return evalExpr(scope, childArgs, context);
|
||||
};
|
||||
const fn = typed(name, signatures);
|
||||
fn.syntax = syntax;
|
||||
scope.set(name, fn);
|
||||
return fn;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a callback for each of the child nodes of this node
|
||||
* @param {function(child: Node, path: string, parent: Node)} callback
|
||||
*/
|
||||
forEach(callback) {
|
||||
callback(this.expr, 'expr', this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new FunctionAssignmentNode whose children are the results of
|
||||
* calling the provided callback function for each child of the original
|
||||
* node.
|
||||
* @param {function(child: Node, path: string, parent: Node): Node} callback
|
||||
* @returns {FunctionAssignmentNode} Returns a transformed copy of the node
|
||||
*/
|
||||
map(callback) {
|
||||
const expr = this._ifNode(callback(this.expr, 'expr', this));
|
||||
return new FunctionAssignmentNode(this.name, this.params.slice(0), expr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a clone of this node, a shallow copy
|
||||
* @return {FunctionAssignmentNode}
|
||||
*/
|
||||
clone() {
|
||||
return new FunctionAssignmentNode(this.name, this.params.slice(0), this.expr);
|
||||
}
|
||||
|
||||
/**
|
||||
* get string representation
|
||||
* @param {Object} options
|
||||
* @return {string} str
|
||||
*/
|
||||
_toString(options) {
|
||||
const parenthesis = options && options.parenthesis ? options.parenthesis : 'keep';
|
||||
let expr = this.expr.toString(options);
|
||||
if (needParenthesis(this, parenthesis, options && options.implicit)) {
|
||||
expr = '(' + expr + ')';
|
||||
}
|
||||
return this.name + '(' + this.params.join(', ') + ') = ' + expr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a JSON representation of the node
|
||||
* @returns {Object}
|
||||
*/
|
||||
toJSON() {
|
||||
const types = this.types;
|
||||
return {
|
||||
mathjs: name,
|
||||
name: this.name,
|
||||
params: this.params.map(function (param, index) {
|
||||
return {
|
||||
name: param,
|
||||
type: types[index]
|
||||
};
|
||||
}),
|
||||
expr: this.expr
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiate an FunctionAssignmentNode from its JSON representation
|
||||
* @param {Object} json
|
||||
* An object structured like
|
||||
* ```
|
||||
* {"mathjs": "FunctionAssignmentNode",
|
||||
* name: ..., params: ..., expr: ...}
|
||||
* ```
|
||||
* where mathjs is optional
|
||||
* @returns {FunctionAssignmentNode}
|
||||
*/
|
||||
static fromJSON(json) {
|
||||
return new FunctionAssignmentNode(json.name, json.params, json.expr);
|
||||
}
|
||||
|
||||
/**
|
||||
* get HTML representation
|
||||
* @param {Object} options
|
||||
* @return {string} str
|
||||
*/
|
||||
_toHTML(options) {
|
||||
const parenthesis = options && options.parenthesis ? options.parenthesis : 'keep';
|
||||
const params = [];
|
||||
for (let i = 0; i < this.params.length; i++) {
|
||||
params.push('<span class="math-symbol math-parameter">' + (0, _string.escape)(this.params[i]) + '</span>');
|
||||
}
|
||||
let expr = this.expr.toHTML(options);
|
||||
if (needParenthesis(this, parenthesis, options && options.implicit)) {
|
||||
expr = '<span class="math-parenthesis math-round-parenthesis">(</span>' + expr + '<span class="math-parenthesis math-round-parenthesis">)</span>';
|
||||
}
|
||||
return '<span class="math-function">' + (0, _string.escape)(this.name) + '</span>' + '<span class="math-parenthesis math-round-parenthesis">(</span>' + params.join('<span class="math-separator">,</span>') + '<span class="math-parenthesis math-round-parenthesis">)</span>' + '<span class="math-operator math-assignment-operator ' + 'math-variable-assignment-operator math-binary-operator">=</span>' + expr;
|
||||
}
|
||||
|
||||
/**
|
||||
* get LaTeX representation
|
||||
* @param {Object} options
|
||||
* @return {string} str
|
||||
*/
|
||||
_toTex(options) {
|
||||
const parenthesis = options && options.parenthesis ? options.parenthesis : 'keep';
|
||||
let expr = this.expr.toTex(options);
|
||||
if (needParenthesis(this, parenthesis, options && options.implicit)) {
|
||||
expr = `\\left(${expr}\\right)`;
|
||||
}
|
||||
return '\\mathrm{' + this.name + '}\\left(' + this.params.map(_latex.toSymbol).join(',') + '\\right)=' + expr;
|
||||
}
|
||||
}
|
||||
(0, _defineProperty2.default)(FunctionAssignmentNode, "name", name);
|
||||
return FunctionAssignmentNode;
|
||||
}, {
|
||||
isClass: true,
|
||||
isNode: true
|
||||
});
|
||||
486
node_modules/mathjs/lib/cjs/expression/node/FunctionNode.js
generated
vendored
Normal file
486
node_modules/mathjs/lib/cjs/expression/node/FunctionNode.js
generated
vendored
Normal file
@@ -0,0 +1,486 @@
|
||||
"use strict";
|
||||
|
||||
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.createFunctionNode = void 0;
|
||||
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
||||
var _is = require("../../utils/is.js");
|
||||
var _string = require("../../utils/string.js");
|
||||
var _object = require("../../utils/object.js");
|
||||
var _customs = require("../../utils/customs.js");
|
||||
var _scope = require("../../utils/scope.js");
|
||||
var _factory = require("../../utils/factory.js");
|
||||
var _latex = require("../../utils/latex.js");
|
||||
const name = 'FunctionNode';
|
||||
const dependencies = ['math', 'Node', 'SymbolNode'];
|
||||
const createFunctionNode = exports.createFunctionNode = /* #__PURE__ */(0, _factory.factory)(name, dependencies, _ref => {
|
||||
var _FunctionNode;
|
||||
let {
|
||||
math,
|
||||
Node,
|
||||
SymbolNode
|
||||
} = _ref;
|
||||
/* format to fixed length */
|
||||
const strin = entity => (0, _string.format)(entity, {
|
||||
truncate: 78
|
||||
});
|
||||
|
||||
/*
|
||||
* Expand a LaTeX template
|
||||
*
|
||||
* @param {string} template
|
||||
* @param {Node} node
|
||||
* @param {Object} options
|
||||
* @private
|
||||
**/
|
||||
function expandTemplate(template, node, options) {
|
||||
let latex = '';
|
||||
|
||||
// Match everything of the form ${identifier} or ${identifier[2]} or $$
|
||||
// while submatching identifier and 2 (in the second case)
|
||||
const regex = /\$(?:\{([a-z_][a-z_0-9]*)(?:\[([0-9]+)\])?\}|\$)/gi;
|
||||
let inputPos = 0; // position in the input string
|
||||
let match;
|
||||
while ((match = regex.exec(template)) !== null) {
|
||||
// go through all matches
|
||||
// add everything in front of the match to the LaTeX string
|
||||
latex += template.substring(inputPos, match.index);
|
||||
inputPos = match.index;
|
||||
if (match[0] === '$$') {
|
||||
// escaped dollar sign
|
||||
latex += '$';
|
||||
inputPos++;
|
||||
} else {
|
||||
// template parameter
|
||||
inputPos += match[0].length;
|
||||
const property = node[match[1]];
|
||||
if (!property) {
|
||||
throw new ReferenceError('Template: Property ' + match[1] + ' does not exist.');
|
||||
}
|
||||
if (match[2] === undefined) {
|
||||
// no square brackets
|
||||
switch (typeof property) {
|
||||
case 'string':
|
||||
latex += property;
|
||||
break;
|
||||
case 'object':
|
||||
if ((0, _is.isNode)(property)) {
|
||||
latex += property.toTex(options);
|
||||
} else if (Array.isArray(property)) {
|
||||
// make array of Nodes into comma separated list
|
||||
latex += property.map(function (arg, index) {
|
||||
if ((0, _is.isNode)(arg)) {
|
||||
return arg.toTex(options);
|
||||
}
|
||||
throw new TypeError('Template: ' + match[1] + '[' + index + '] is not a Node.');
|
||||
}).join(',');
|
||||
} else {
|
||||
throw new TypeError('Template: ' + match[1] + ' has to be a Node, String or array of Nodes');
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new TypeError('Template: ' + match[1] + ' has to be a Node, String or array of Nodes');
|
||||
}
|
||||
} else {
|
||||
// with square brackets
|
||||
if ((0, _is.isNode)(property[match[2]] && property[match[2]])) {
|
||||
latex += property[match[2]].toTex(options);
|
||||
} else {
|
||||
throw new TypeError('Template: ' + match[1] + '[' + match[2] + '] is not a Node.');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
latex += template.slice(inputPos); // append rest of the template
|
||||
|
||||
return latex;
|
||||
}
|
||||
class FunctionNode extends Node {
|
||||
/**
|
||||
* @constructor FunctionNode
|
||||
* @extends {./Node}
|
||||
* invoke a list with arguments on a node
|
||||
* @param {./Node | string} fn
|
||||
* Item resolving to a function on which to invoke
|
||||
* the arguments, typically a SymbolNode or AccessorNode
|
||||
* @param {./Node[]} args
|
||||
*/
|
||||
constructor(fn, args) {
|
||||
super();
|
||||
if (typeof fn === 'string') {
|
||||
fn = new SymbolNode(fn);
|
||||
}
|
||||
|
||||
// validate input
|
||||
if (!(0, _is.isNode)(fn)) throw new TypeError('Node expected as parameter "fn"');
|
||||
if (!Array.isArray(args) || !args.every(_is.isNode)) {
|
||||
throw new TypeError('Array containing Nodes expected for parameter "args"');
|
||||
}
|
||||
this.fn = fn;
|
||||
this.args = args || [];
|
||||
}
|
||||
|
||||
// readonly property name
|
||||
get name() {
|
||||
return this.fn.name || '';
|
||||
}
|
||||
get type() {
|
||||
return name;
|
||||
}
|
||||
get isFunctionNode() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile a node into a JavaScript function.
|
||||
* This basically pre-calculates as much as possible and only leaves open
|
||||
* calculations which depend on a dynamic scope with variables.
|
||||
* @param {Object} math Math.js namespace with functions and constants.
|
||||
* @param {Object} argNames An object with argument names as key and `true`
|
||||
* as value. Used in the SymbolNode to optimize
|
||||
* for arguments from user assigned functions
|
||||
* (see FunctionAssignmentNode) or special symbols
|
||||
* like `end` (see IndexNode).
|
||||
* @return {function} Returns a function which can be called like:
|
||||
* evalNode(scope: Object, args: Object, context: *)
|
||||
*/
|
||||
_compile(math, argNames) {
|
||||
// compile arguments
|
||||
const evalArgs = this.args.map(arg => arg._compile(math, argNames));
|
||||
if ((0, _is.isSymbolNode)(this.fn)) {
|
||||
const name = this.fn.name;
|
||||
if (!argNames[name]) {
|
||||
// we can statically determine whether the function
|
||||
// has the rawArgs property
|
||||
const fn = name in math ? (0, _customs.getSafeProperty)(math, name) : undefined;
|
||||
const isRaw = typeof fn === 'function' && fn.rawArgs === true;
|
||||
const resolveFn = scope => {
|
||||
let value;
|
||||
if (scope.has(name)) {
|
||||
value = scope.get(name);
|
||||
} else if (name in math) {
|
||||
value = (0, _customs.getSafeProperty)(math, name);
|
||||
} else {
|
||||
return FunctionNode.onUndefinedFunction(name);
|
||||
}
|
||||
if (typeof value === 'function') {
|
||||
return value;
|
||||
}
|
||||
throw new TypeError(`'${name}' is not a function; its value is:\n ${strin(value)}`);
|
||||
};
|
||||
if (isRaw) {
|
||||
// pass unevaluated parameters (nodes) to the function
|
||||
// "raw" evaluation
|
||||
const rawArgs = this.args;
|
||||
return function evalFunctionNode(scope, args, context) {
|
||||
const fn = resolveFn(scope);
|
||||
|
||||
// the original function can be overwritten in the scope with a non-rawArgs function
|
||||
if (fn.rawArgs === true) {
|
||||
return fn(rawArgs, math, (0, _scope.createSubScope)(scope, args));
|
||||
} else {
|
||||
// "regular" evaluation
|
||||
const values = evalArgs.map(evalArg => evalArg(scope, args, context));
|
||||
return fn(...values);
|
||||
}
|
||||
};
|
||||
} else {
|
||||
// "regular" evaluation
|
||||
switch (evalArgs.length) {
|
||||
case 0:
|
||||
return function evalFunctionNode(scope, args, context) {
|
||||
const fn = resolveFn(scope);
|
||||
return fn();
|
||||
};
|
||||
case 1:
|
||||
return function evalFunctionNode(scope, args, context) {
|
||||
const fn = resolveFn(scope);
|
||||
const evalArg0 = evalArgs[0];
|
||||
return fn(evalArg0(scope, args, context));
|
||||
};
|
||||
case 2:
|
||||
return function evalFunctionNode(scope, args, context) {
|
||||
const fn = resolveFn(scope);
|
||||
const evalArg0 = evalArgs[0];
|
||||
const evalArg1 = evalArgs[1];
|
||||
return fn(evalArg0(scope, args, context), evalArg1(scope, args, context));
|
||||
};
|
||||
default:
|
||||
return function evalFunctionNode(scope, args, context) {
|
||||
const fn = resolveFn(scope);
|
||||
const values = evalArgs.map(evalArg => evalArg(scope, args, context));
|
||||
return fn(...values);
|
||||
};
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// the function symbol is an argName
|
||||
const rawArgs = this.args;
|
||||
return function evalFunctionNode(scope, args, context) {
|
||||
const fn = (0, _customs.getSafeProperty)(args, name);
|
||||
if (typeof fn !== 'function') {
|
||||
throw new TypeError(`Argument '${name}' was not a function; received: ${strin(fn)}`);
|
||||
}
|
||||
if (fn.rawArgs) {
|
||||
// "Raw" evaluation
|
||||
return fn(rawArgs, math, (0, _scope.createSubScope)(scope, args));
|
||||
} else {
|
||||
const values = evalArgs.map(evalArg => evalArg(scope, args, context));
|
||||
return fn.apply(fn, values);
|
||||
}
|
||||
};
|
||||
}
|
||||
} else if ((0, _is.isAccessorNode)(this.fn) && (0, _is.isIndexNode)(this.fn.index) && this.fn.index.isObjectProperty()) {
|
||||
// execute the function with the right context:
|
||||
// the object of the AccessorNode
|
||||
|
||||
const evalObject = this.fn.object._compile(math, argNames);
|
||||
const prop = this.fn.index.getObjectProperty();
|
||||
const rawArgs = this.args;
|
||||
return function evalFunctionNode(scope, args, context) {
|
||||
const object = evalObject(scope, args, context);
|
||||
const fn = (0, _customs.getSafeMethod)(object, prop);
|
||||
if (fn !== null && fn !== void 0 && fn.rawArgs) {
|
||||
// "Raw" evaluation
|
||||
return fn(rawArgs, math, (0, _scope.createSubScope)(scope, args));
|
||||
} else {
|
||||
// "regular" evaluation
|
||||
const values = evalArgs.map(evalArg => evalArg(scope, args, context));
|
||||
return fn.apply(object, values);
|
||||
}
|
||||
};
|
||||
} else {
|
||||
// node.fn.isAccessorNode && !node.fn.index.isObjectProperty()
|
||||
// we have to dynamically determine whether the function has the
|
||||
// rawArgs property
|
||||
const fnExpr = this.fn.toString();
|
||||
const evalFn = this.fn._compile(math, argNames);
|
||||
const rawArgs = this.args;
|
||||
return function evalFunctionNode(scope, args, context) {
|
||||
const fn = evalFn(scope, args, context);
|
||||
if (typeof fn !== 'function') {
|
||||
throw new TypeError(`Expression '${fnExpr}' did not evaluate to a function; value is:` + `\n ${strin(fn)}`);
|
||||
}
|
||||
if (fn.rawArgs) {
|
||||
// "Raw" evaluation
|
||||
return fn(rawArgs, math, (0, _scope.createSubScope)(scope, args));
|
||||
} else {
|
||||
// "regular" evaluation
|
||||
const values = evalArgs.map(evalArg => evalArg(scope, args, context));
|
||||
return fn.apply(fn, values);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a callback for each of the child nodes of this node
|
||||
* @param {function(child: Node, path: string, parent: Node)} callback
|
||||
*/
|
||||
forEach(callback) {
|
||||
callback(this.fn, 'fn', this);
|
||||
for (let i = 0; i < this.args.length; i++) {
|
||||
callback(this.args[i], 'args[' + i + ']', this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new FunctionNode whose children are the results of calling
|
||||
* the provided callback function for each child of the original node.
|
||||
* @param {function(child: Node, path: string, parent: Node): Node} callback
|
||||
* @returns {FunctionNode} Returns a transformed copy of the node
|
||||
*/
|
||||
map(callback) {
|
||||
const fn = this._ifNode(callback(this.fn, 'fn', this));
|
||||
const args = [];
|
||||
for (let i = 0; i < this.args.length; i++) {
|
||||
args[i] = this._ifNode(callback(this.args[i], 'args[' + i + ']', this));
|
||||
}
|
||||
return new FunctionNode(fn, args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a clone of this node, a shallow copy
|
||||
* @return {FunctionNode}
|
||||
*/
|
||||
clone() {
|
||||
return new FunctionNode(this.fn, this.args.slice(0));
|
||||
}
|
||||
|
||||
/**
|
||||
* Throws an error 'Undefined function {name}'
|
||||
* @param {string} name
|
||||
*/
|
||||
|
||||
/**
|
||||
* Get string representation. (wrapper function)
|
||||
* This overrides parts of Node's toString function.
|
||||
* If callback is an object containing callbacks, it
|
||||
* calls the correct callback for the current node,
|
||||
* otherwise it falls back to calling Node's toString
|
||||
* function.
|
||||
*
|
||||
* @param {Object} options
|
||||
* @return {string} str
|
||||
* @override
|
||||
*/
|
||||
toString(options) {
|
||||
let customString;
|
||||
const name = this.fn.toString(options);
|
||||
if (options && typeof options.handler === 'object' && (0, _object.hasOwnProperty)(options.handler, name)) {
|
||||
// callback is a map of callback functions
|
||||
customString = options.handler[name](this, options);
|
||||
}
|
||||
if (typeof customString !== 'undefined') {
|
||||
return customString;
|
||||
}
|
||||
|
||||
// fall back to Node's toString
|
||||
return super.toString(options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get string representation
|
||||
* @param {Object} options
|
||||
* @return {string} str
|
||||
*/
|
||||
_toString(options) {
|
||||
const args = this.args.map(function (arg) {
|
||||
return arg.toString(options);
|
||||
});
|
||||
const fn = (0, _is.isFunctionAssignmentNode)(this.fn) ? '(' + this.fn.toString(options) + ')' : this.fn.toString(options);
|
||||
|
||||
// format the arguments like "add(2, 4.2)"
|
||||
return fn + '(' + args.join(', ') + ')';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a JSON representation of the node
|
||||
* @returns {Object}
|
||||
*/
|
||||
toJSON() {
|
||||
return {
|
||||
mathjs: name,
|
||||
fn: this.fn,
|
||||
args: this.args
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiate an AssignmentNode from its JSON representation
|
||||
* @param {Object} json An object structured like
|
||||
* `{"mathjs": "FunctionNode", fn: ..., args: ...}`,
|
||||
* where mathjs is optional
|
||||
* @returns {FunctionNode}
|
||||
*/
|
||||
|
||||
/**
|
||||
* Get HTML representation
|
||||
* @param {Object} options
|
||||
* @return {string} str
|
||||
*/
|
||||
_toHTML(options) {
|
||||
const args = this.args.map(function (arg) {
|
||||
return arg.toHTML(options);
|
||||
});
|
||||
|
||||
// format the arguments like "add(2, 4.2)"
|
||||
return '<span class="math-function">' + (0, _string.escape)(this.fn) + '</span><span class="math-paranthesis math-round-parenthesis">(</span>' + args.join('<span class="math-separator">,</span>') + '<span class="math-paranthesis math-round-parenthesis">)</span>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get LaTeX representation. (wrapper function)
|
||||
* This overrides parts of Node's toTex function.
|
||||
* If callback is an object containing callbacks, it
|
||||
* calls the correct callback for the current node,
|
||||
* otherwise it falls back to calling Node's toTex
|
||||
* function.
|
||||
*
|
||||
* @param {Object} options
|
||||
* @return {string}
|
||||
*/
|
||||
toTex(options) {
|
||||
let customTex;
|
||||
if (options && typeof options.handler === 'object' && (0, _object.hasOwnProperty)(options.handler, this.name)) {
|
||||
// callback is a map of callback functions
|
||||
customTex = options.handler[this.name](this, options);
|
||||
}
|
||||
if (typeof customTex !== 'undefined') {
|
||||
return customTex;
|
||||
}
|
||||
|
||||
// fall back to Node's toTex
|
||||
return super.toTex(options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get LaTeX representation
|
||||
* @param {Object} options
|
||||
* @return {string} str
|
||||
*/
|
||||
_toTex(options) {
|
||||
const args = this.args.map(function (arg) {
|
||||
// get LaTeX of the arguments
|
||||
return arg.toTex(options);
|
||||
});
|
||||
let latexConverter;
|
||||
if (_latex.latexFunctions[this.name]) {
|
||||
latexConverter = _latex.latexFunctions[this.name];
|
||||
}
|
||||
|
||||
// toTex property on the function itself
|
||||
if (math[this.name] && (typeof math[this.name].toTex === 'function' || typeof math[this.name].toTex === 'object' || typeof math[this.name].toTex === 'string')) {
|
||||
// .toTex is a callback function
|
||||
latexConverter = math[this.name].toTex;
|
||||
}
|
||||
let customToTex;
|
||||
switch (typeof latexConverter) {
|
||||
case 'function':
|
||||
// a callback function
|
||||
customToTex = latexConverter(this, options);
|
||||
break;
|
||||
case 'string':
|
||||
// a template string
|
||||
customToTex = expandTemplate(latexConverter, this, options);
|
||||
break;
|
||||
case 'object':
|
||||
// an object with different "converters" for different
|
||||
// numbers of arguments
|
||||
switch (typeof latexConverter[args.length]) {
|
||||
case 'function':
|
||||
customToTex = latexConverter[args.length](this, options);
|
||||
break;
|
||||
case 'string':
|
||||
customToTex = expandTemplate(latexConverter[args.length], this, options);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (typeof customToTex !== 'undefined') {
|
||||
return customToTex;
|
||||
}
|
||||
return expandTemplate(_latex.defaultTemplate, this, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get identifier.
|
||||
* @return {string}
|
||||
*/
|
||||
getIdentifier() {
|
||||
return this.type + ':' + this.name;
|
||||
}
|
||||
}
|
||||
_FunctionNode = FunctionNode;
|
||||
(0, _defineProperty2.default)(FunctionNode, "name", name);
|
||||
(0, _defineProperty2.default)(FunctionNode, "onUndefinedFunction", function (name) {
|
||||
throw new Error('Undefined function ' + name);
|
||||
});
|
||||
(0, _defineProperty2.default)(FunctionNode, "fromJSON", function (json) {
|
||||
return new _FunctionNode(json.fn, json.args);
|
||||
});
|
||||
return FunctionNode;
|
||||
}, {
|
||||
isClass: true,
|
||||
isNode: true
|
||||
});
|
||||
226
node_modules/mathjs/lib/cjs/expression/node/IndexNode.js
generated
vendored
Normal file
226
node_modules/mathjs/lib/cjs/expression/node/IndexNode.js
generated
vendored
Normal file
@@ -0,0 +1,226 @@
|
||||
"use strict";
|
||||
|
||||
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.createIndexNode = void 0;
|
||||
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
||||
var _array = require("../../utils/array.js");
|
||||
var _customs = require("../../utils/customs.js");
|
||||
var _factory = require("../../utils/factory.js");
|
||||
var _is = require("../../utils/is.js");
|
||||
var _string = require("../../utils/string.js");
|
||||
const name = 'IndexNode';
|
||||
const dependencies = ['Node', 'size'];
|
||||
const createIndexNode = exports.createIndexNode = /* #__PURE__ */(0, _factory.factory)(name, dependencies, _ref => {
|
||||
let {
|
||||
Node,
|
||||
size
|
||||
} = _ref;
|
||||
class IndexNode extends Node {
|
||||
/**
|
||||
* @constructor IndexNode
|
||||
* @extends Node
|
||||
*
|
||||
* Describes a subset of a matrix or an object property.
|
||||
* Cannot be used on its own, needs to be used within an AccessorNode or
|
||||
* AssignmentNode.
|
||||
*
|
||||
* @param {Node[]} dimensions
|
||||
* @param {boolean} [dotNotation=false]
|
||||
* Optional property describing whether this index was written using dot
|
||||
* notation like `a.b`, or using bracket notation like `a["b"]`
|
||||
* (which is the default). This property is used for string conversion.
|
||||
*/
|
||||
constructor(dimensions, dotNotation) {
|
||||
super();
|
||||
this.dimensions = dimensions;
|
||||
this.dotNotation = dotNotation || false;
|
||||
|
||||
// validate input
|
||||
if (!Array.isArray(dimensions) || !dimensions.every(_is.isNode)) {
|
||||
throw new TypeError('Array containing Nodes expected for parameter "dimensions"');
|
||||
}
|
||||
if (this.dotNotation && !this.isObjectProperty()) {
|
||||
throw new Error('dotNotation only applicable for object properties');
|
||||
}
|
||||
}
|
||||
get type() {
|
||||
return name;
|
||||
}
|
||||
get isIndexNode() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile a node into a JavaScript function.
|
||||
* This basically pre-calculates as much as possible and only leaves open
|
||||
* calculations which depend on a dynamic scope with variables.
|
||||
* @param {Object} math Math.js namespace with functions and constants.
|
||||
* @param {Object} argNames An object with argument names as key and `true`
|
||||
* as value. Used in the SymbolNode to optimize
|
||||
* for arguments from user assigned functions
|
||||
* (see FunctionAssignmentNode) or special symbols
|
||||
* like `end` (see IndexNode).
|
||||
* @return {function} Returns a function which can be called like:
|
||||
* evalNode(scope: Object, args: Object, context: *)
|
||||
*/
|
||||
_compile(math, argNames) {
|
||||
// TODO: implement support for bignumber (currently bignumbers are silently
|
||||
// reduced to numbers when changing the value to zero-based)
|
||||
|
||||
// TODO: Optimization: when the range values are ConstantNodes,
|
||||
// we can beforehand resolve the zero-based value
|
||||
|
||||
// optimization for a simple object property
|
||||
const evalDimensions = (0, _array.map)(this.dimensions, function (dimension, i) {
|
||||
const needsEnd = dimension.filter(node => node.isSymbolNode && node.name === 'end').length > 0;
|
||||
if (needsEnd) {
|
||||
// SymbolNode 'end' is used inside the index,
|
||||
// like in `A[end]` or `A[end - 2]`
|
||||
const childArgNames = Object.create(argNames);
|
||||
childArgNames.end = true;
|
||||
const _evalDimension = dimension._compile(math, childArgNames);
|
||||
return function evalDimension(scope, args, context) {
|
||||
if (!(0, _is.isMatrix)(context) && !(0, _is.isArray)(context) && !(0, _is.isString)(context)) {
|
||||
throw new TypeError('Cannot resolve "end": ' + 'context must be a Matrix, Array, or string but is ' + (0, _is.typeOf)(context));
|
||||
}
|
||||
const s = size(context).valueOf();
|
||||
const childArgs = Object.create(args);
|
||||
childArgs.end = s[i];
|
||||
return _evalDimension(scope, childArgs, context);
|
||||
};
|
||||
} else {
|
||||
// SymbolNode `end` not used
|
||||
return dimension._compile(math, argNames);
|
||||
}
|
||||
});
|
||||
const index = (0, _customs.getSafeProperty)(math, 'index');
|
||||
return function evalIndexNode(scope, args, context) {
|
||||
const dimensions = (0, _array.map)(evalDimensions, function (evalDimension) {
|
||||
return evalDimension(scope, args, context);
|
||||
});
|
||||
return index(...dimensions);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a callback for each of the child nodes of this node
|
||||
* @param {function(child: Node, path: string, parent: Node)} callback
|
||||
*/
|
||||
forEach(callback) {
|
||||
for (let i = 0; i < this.dimensions.length; i++) {
|
||||
callback(this.dimensions[i], 'dimensions[' + i + ']', this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new IndexNode whose children are the results of calling
|
||||
* the provided callback function for each child of the original node.
|
||||
* @param {function(child: Node, path: string, parent: Node): Node} callback
|
||||
* @returns {IndexNode} Returns a transformed copy of the node
|
||||
*/
|
||||
map(callback) {
|
||||
const dimensions = [];
|
||||
for (let i = 0; i < this.dimensions.length; i++) {
|
||||
dimensions[i] = this._ifNode(callback(this.dimensions[i], 'dimensions[' + i + ']', this));
|
||||
}
|
||||
return new IndexNode(dimensions, this.dotNotation);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a clone of this node, a shallow copy
|
||||
* @return {IndexNode}
|
||||
*/
|
||||
clone() {
|
||||
return new IndexNode(this.dimensions.slice(0), this.dotNotation);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test whether this IndexNode contains a single property name
|
||||
* @return {boolean}
|
||||
*/
|
||||
isObjectProperty() {
|
||||
return this.dimensions.length === 1 && (0, _is.isConstantNode)(this.dimensions[0]) && typeof this.dimensions[0].value === 'string';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the property name if IndexNode contains a property.
|
||||
* If not, returns null.
|
||||
* @return {string | null}
|
||||
*/
|
||||
getObjectProperty() {
|
||||
return this.isObjectProperty() ? this.dimensions[0].value : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get string representation
|
||||
* @param {Object} options
|
||||
* @return {string} str
|
||||
*/
|
||||
_toString(options) {
|
||||
// format the parameters like "[1, 0:5]"
|
||||
return this.dotNotation ? '.' + this.getObjectProperty() : '[' + this.dimensions.join(', ') + ']';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a JSON representation of the node
|
||||
* @returns {Object}
|
||||
*/
|
||||
toJSON() {
|
||||
return {
|
||||
mathjs: name,
|
||||
dimensions: this.dimensions,
|
||||
dotNotation: this.dotNotation
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiate an IndexNode from its JSON representation
|
||||
* @param {Object} json
|
||||
* An object structured like
|
||||
* `{"mathjs": "IndexNode", dimensions: [...], dotNotation: false}`,
|
||||
* where mathjs is optional
|
||||
* @returns {IndexNode}
|
||||
*/
|
||||
static fromJSON(json) {
|
||||
return new IndexNode(json.dimensions, json.dotNotation);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get HTML representation
|
||||
* @param {Object} options
|
||||
* @return {string} str
|
||||
*/
|
||||
_toHTML(options) {
|
||||
// format the parameters like "[1, 0:5]"
|
||||
const dimensions = [];
|
||||
for (let i = 0; i < this.dimensions.length; i++) {
|
||||
dimensions[i] = this.dimensions[i].toHTML();
|
||||
}
|
||||
if (this.dotNotation) {
|
||||
return '<span class="math-operator math-accessor-operator">.</span>' + '<span class="math-symbol math-property">' + (0, _string.escape)(this.getObjectProperty()) + '</span>';
|
||||
} else {
|
||||
return '<span class="math-parenthesis math-square-parenthesis">[</span>' + dimensions.join('<span class="math-separator">,</span>') + '<span class="math-parenthesis math-square-parenthesis">]</span>';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get LaTeX representation
|
||||
* @param {Object} options
|
||||
* @return {string} str
|
||||
*/
|
||||
_toTex(options) {
|
||||
const dimensions = this.dimensions.map(function (range) {
|
||||
return range.toTex(options);
|
||||
});
|
||||
return this.dotNotation ? '.' + this.getObjectProperty() + '' : '_{' + dimensions.join(',') + '}';
|
||||
}
|
||||
}
|
||||
(0, _defineProperty2.default)(IndexNode, "name", name);
|
||||
return IndexNode;
|
||||
}, {
|
||||
isClass: true,
|
||||
isNode: true
|
||||
});
|
||||
378
node_modules/mathjs/lib/cjs/expression/node/Node.js
generated
vendored
Normal file
378
node_modules/mathjs/lib/cjs/expression/node/Node.js
generated
vendored
Normal file
@@ -0,0 +1,378 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.createNode = void 0;
|
||||
var _is = require("../../utils/is.js");
|
||||
var _keywords = require("../keywords.js");
|
||||
var _object = require("../../utils/object.js");
|
||||
var _factory = require("../../utils/factory.js");
|
||||
var _map = require("../../utils/map.js");
|
||||
const name = 'Node';
|
||||
const dependencies = ['mathWithTransform'];
|
||||
const createNode = exports.createNode = /* #__PURE__ */(0, _factory.factory)(name, dependencies, _ref => {
|
||||
let {
|
||||
mathWithTransform
|
||||
} = _ref;
|
||||
/**
|
||||
* Validate the symbol names of a scope.
|
||||
* Throws an error when the scope contains an illegal symbol.
|
||||
* @param {Object} scope
|
||||
*/
|
||||
function _validateScope(scope) {
|
||||
for (const symbol of [..._keywords.keywords]) {
|
||||
if (scope.has(symbol)) {
|
||||
throw new Error('Scope contains an illegal symbol, "' + symbol + '" is a reserved keyword');
|
||||
}
|
||||
}
|
||||
}
|
||||
class Node {
|
||||
get type() {
|
||||
return 'Node';
|
||||
}
|
||||
get isNode() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluate the node
|
||||
* @param {Object} [scope] Scope to read/write variables
|
||||
* @return {*} Returns the result
|
||||
*/
|
||||
evaluate(scope) {
|
||||
return this.compile().evaluate(scope);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the node into an optimized, evauatable JavaScript function
|
||||
* @return {{evaluate: function([Object])}} object
|
||||
* Returns an object with a function 'evaluate',
|
||||
* which can be invoked as expr.evaluate([scope: Object]),
|
||||
* where scope is an optional object with
|
||||
* variables.
|
||||
*/
|
||||
compile() {
|
||||
const expr = this._compile(mathWithTransform, {});
|
||||
const args = {};
|
||||
const context = null;
|
||||
function evaluate(scope) {
|
||||
const s = (0, _map.createMap)(scope);
|
||||
_validateScope(s);
|
||||
return expr(s, args, context);
|
||||
}
|
||||
return {
|
||||
evaluate
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile a node into a JavaScript function.
|
||||
* This basically pre-calculates as much as possible and only leaves open
|
||||
* calculations which depend on a dynamic scope with variables.
|
||||
* @param {Object} math Math.js namespace with functions and constants.
|
||||
* @param {Object} argNames An object with argument names as key and `true`
|
||||
* as value. Used in the SymbolNode to optimize
|
||||
* for arguments from user assigned functions
|
||||
* (see FunctionAssignmentNode) or special symbols
|
||||
* like `end` (see IndexNode).
|
||||
* @return {function} Returns a function which can be called like:
|
||||
* evalNode(scope: Object, args: Object, context: *)
|
||||
*/
|
||||
_compile(math, argNames) {
|
||||
throw new Error('Method _compile must be implemented by type ' + this.type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a callback for each of the child nodes of this node
|
||||
* @param {function(child: Node, path: string, parent: Node)} callback
|
||||
*/
|
||||
forEach(callback) {
|
||||
// must be implemented by each of the Node implementations
|
||||
throw new Error('Cannot run forEach on a Node interface');
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new Node whose children are the results of calling the
|
||||
* provided callback function for each child of the original node.
|
||||
* @param {function(child: Node, path: string, parent: Node): Node} callback
|
||||
* @returns {OperatorNode} Returns a transformed copy of the node
|
||||
*/
|
||||
map(callback) {
|
||||
// must be implemented by each of the Node implementations
|
||||
throw new Error('Cannot run map on a Node interface');
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate whether an object is a Node, for use with map
|
||||
* @param {Node} node
|
||||
* @returns {Node} Returns the input if it's a node, else throws an Error
|
||||
* @protected
|
||||
*/
|
||||
_ifNode(node) {
|
||||
if (!(0, _is.isNode)(node)) {
|
||||
throw new TypeError('Callback function must return a Node');
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively traverse all nodes in a node tree. Executes given callback for
|
||||
* this node and each of its child nodes.
|
||||
* @param {function(node: Node, path: string, parent: Node)} callback
|
||||
* A callback called for every node in the node tree.
|
||||
*/
|
||||
traverse(callback) {
|
||||
// execute callback for itself
|
||||
// eslint-disable-next-line
|
||||
callback(this, null, null);
|
||||
|
||||
// recursively traverse over all children of a node
|
||||
function _traverse(node, callback) {
|
||||
node.forEach(function (child, path, parent) {
|
||||
callback(child, path, parent);
|
||||
_traverse(child, callback);
|
||||
});
|
||||
}
|
||||
_traverse(this, callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively transform a node tree via a transform function.
|
||||
*
|
||||
* For example, to replace all nodes of type SymbolNode having name 'x' with
|
||||
* a ConstantNode with value 2:
|
||||
*
|
||||
* const res = Node.transform(function (node, path, parent) {
|
||||
* if (node && node.isSymbolNode) && (node.name === 'x')) {
|
||||
* return new ConstantNode(2)
|
||||
* }
|
||||
* else {
|
||||
* return node
|
||||
* }
|
||||
* })
|
||||
*
|
||||
* @param {function(node: Node, path: string, parent: Node) : Node} callback
|
||||
* A mapping function accepting a node, and returning
|
||||
* a replacement for the node or the original node. The "signature"
|
||||
* of the callback must be:
|
||||
* callback(node: Node, index: string, parent: Node) : Node
|
||||
* @return {Node} Returns the original node or its replacement
|
||||
*/
|
||||
transform(callback) {
|
||||
function _transform(child, path, parent) {
|
||||
const replacement = callback(child, path, parent);
|
||||
if (replacement !== child) {
|
||||
// stop iterating when the node is replaced
|
||||
return replacement;
|
||||
}
|
||||
return child.map(_transform);
|
||||
}
|
||||
return _transform(this, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find any node in the node tree matching given filter function. For
|
||||
* example, to find all nodes of type SymbolNode having name 'x':
|
||||
*
|
||||
* const results = Node.filter(function (node) {
|
||||
* return (node && node.isSymbolNode) && (node.name === 'x')
|
||||
* })
|
||||
*
|
||||
* @param {function(node: Node, path: string, parent: Node) : Node} callback
|
||||
* A test function returning true when a node matches, and false
|
||||
* otherwise. Function signature:
|
||||
* callback(node: Node, index: string, parent: Node) : boolean
|
||||
* @return {Node[]} nodes
|
||||
* An array with nodes matching given filter criteria
|
||||
*/
|
||||
filter(callback) {
|
||||
const nodes = [];
|
||||
this.traverse(function (node, path, parent) {
|
||||
if (callback(node, path, parent)) {
|
||||
nodes.push(node);
|
||||
}
|
||||
});
|
||||
return nodes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a shallow clone of this node
|
||||
* @return {Node}
|
||||
*/
|
||||
clone() {
|
||||
// must be implemented by each of the Node implementations
|
||||
throw new Error('Cannot clone a Node interface');
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a deep clone of this node
|
||||
* @return {Node}
|
||||
*/
|
||||
cloneDeep() {
|
||||
return this.map(function (node) {
|
||||
return node.cloneDeep();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Deep compare this node with another node.
|
||||
* @param {Node} other
|
||||
* @return {boolean} Returns true when both nodes are of the same type and
|
||||
* contain the same values (as do their childs)
|
||||
*/
|
||||
equals(other) {
|
||||
return other ? this.type === other.type && (0, _object.deepStrictEqual)(this, other) : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get string representation. (wrapper function)
|
||||
*
|
||||
* This function can get an object of the following form:
|
||||
* {
|
||||
* handler: //This can be a callback function of the form
|
||||
* // "function callback(node, options)"or
|
||||
* // a map that maps function names (used in FunctionNodes)
|
||||
* // to callbacks
|
||||
* parenthesis: "keep" //the parenthesis option (This is optional)
|
||||
* }
|
||||
*
|
||||
* @param {Object} [options]
|
||||
* @return {string}
|
||||
*/
|
||||
toString(options) {
|
||||
const customString = this._getCustomString(options);
|
||||
if (typeof customString !== 'undefined') {
|
||||
return customString;
|
||||
}
|
||||
return this._toString(options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal function to generate the string output.
|
||||
* This has to be implemented by every Node
|
||||
*
|
||||
* @throws {Error}
|
||||
*/
|
||||
_toString() {
|
||||
// must be implemented by each of the Node implementations
|
||||
throw new Error('_toString not implemented for ' + this.type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a JSON representation of the node
|
||||
* Both .toJSON() and the static .fromJSON(json) should be implemented by all
|
||||
* implementations of Node
|
||||
* @returns {Object}
|
||||
*/
|
||||
toJSON() {
|
||||
throw new Error('Cannot serialize object: toJSON not implemented by ' + this.type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get HTML representation. (wrapper function)
|
||||
*
|
||||
* This function can get an object of the following form:
|
||||
* {
|
||||
* handler: //This can be a callback function of the form
|
||||
* // "function callback(node, options)" or
|
||||
* // a map that maps function names (used in FunctionNodes)
|
||||
* // to callbacks
|
||||
* parenthesis: "keep" //the parenthesis option (This is optional)
|
||||
* }
|
||||
*
|
||||
* @param {Object} [options]
|
||||
* @return {string}
|
||||
*/
|
||||
toHTML(options) {
|
||||
const customString = this._getCustomString(options);
|
||||
if (typeof customString !== 'undefined') {
|
||||
return customString;
|
||||
}
|
||||
return this._toHTML(options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal function to generate the HTML output.
|
||||
* This has to be implemented by every Node
|
||||
*
|
||||
* @throws {Error}
|
||||
*/
|
||||
_toHTML() {
|
||||
// must be implemented by each of the Node implementations
|
||||
throw new Error('_toHTML not implemented for ' + this.type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get LaTeX representation. (wrapper function)
|
||||
*
|
||||
* This function can get an object of the following form:
|
||||
* {
|
||||
* handler: //This can be a callback function of the form
|
||||
* // "function callback(node, options)"or
|
||||
* // a map that maps function names (used in FunctionNodes)
|
||||
* // to callbacks
|
||||
* parenthesis: "keep" //the parenthesis option (This is optional)
|
||||
* }
|
||||
*
|
||||
* @param {Object} [options]
|
||||
* @return {string}
|
||||
*/
|
||||
toTex(options) {
|
||||
const customString = this._getCustomString(options);
|
||||
if (typeof customString !== 'undefined') {
|
||||
return customString;
|
||||
}
|
||||
return this._toTex(options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal function to generate the LaTeX output.
|
||||
* This has to be implemented by every Node
|
||||
*
|
||||
* @param {Object} [options]
|
||||
* @throws {Error}
|
||||
*/
|
||||
_toTex(options) {
|
||||
// must be implemented by each of the Node implementations
|
||||
throw new Error('_toTex not implemented for ' + this.type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper used by `to...` functions.
|
||||
*/
|
||||
_getCustomString(options) {
|
||||
if (options && typeof options === 'object') {
|
||||
switch (typeof options.handler) {
|
||||
case 'object':
|
||||
case 'undefined':
|
||||
return;
|
||||
case 'function':
|
||||
return options.handler(this, options);
|
||||
default:
|
||||
throw new TypeError('Object or function expected as callback');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get identifier.
|
||||
* @return {string}
|
||||
*/
|
||||
getIdentifier() {
|
||||
return this.type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the content of the current Node.
|
||||
* @return {Node} node
|
||||
**/
|
||||
getContent() {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
return Node;
|
||||
}, {
|
||||
isClass: true,
|
||||
isNode: true
|
||||
});
|
||||
200
node_modules/mathjs/lib/cjs/expression/node/ObjectNode.js
generated
vendored
Normal file
200
node_modules/mathjs/lib/cjs/expression/node/ObjectNode.js
generated
vendored
Normal file
@@ -0,0 +1,200 @@
|
||||
"use strict";
|
||||
|
||||
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.createObjectNode = void 0;
|
||||
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
||||
var _customs = require("../../utils/customs.js");
|
||||
var _factory = require("../../utils/factory.js");
|
||||
var _is = require("../../utils/is.js");
|
||||
var _object = require("../../utils/object.js");
|
||||
var _string = require("../../utils/string.js");
|
||||
const name = 'ObjectNode';
|
||||
const dependencies = ['Node'];
|
||||
const createObjectNode = exports.createObjectNode = /* #__PURE__ */(0, _factory.factory)(name, dependencies, _ref => {
|
||||
let {
|
||||
Node
|
||||
} = _ref;
|
||||
class ObjectNode extends Node {
|
||||
/**
|
||||
* @constructor ObjectNode
|
||||
* @extends {Node}
|
||||
* Holds an object with keys/values
|
||||
* @param {Object.<string, Node>} [properties] object with key/value pairs
|
||||
*/
|
||||
constructor(properties) {
|
||||
super();
|
||||
this.properties = properties || {};
|
||||
|
||||
// validate input
|
||||
if (properties) {
|
||||
if (!(typeof properties === 'object') || !Object.keys(properties).every(function (key) {
|
||||
return (0, _is.isNode)(properties[key]);
|
||||
})) {
|
||||
throw new TypeError('Object containing Nodes expected');
|
||||
}
|
||||
}
|
||||
}
|
||||
get type() {
|
||||
return name;
|
||||
}
|
||||
get isObjectNode() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile a node into a JavaScript function.
|
||||
* This basically pre-calculates as much as possible and only leaves open
|
||||
* calculations which depend on a dynamic scope with variables.
|
||||
* @param {Object} math Math.js namespace with functions and constants.
|
||||
* @param {Object} argNames An object with argument names as key and `true`
|
||||
* as value. Used in the SymbolNode to optimize
|
||||
* for arguments from user assigned functions
|
||||
* (see FunctionAssignmentNode) or special symbols
|
||||
* like `end` (see IndexNode).
|
||||
* @return {function} Returns a function which can be called like:
|
||||
* evalNode(scope: Object, args: Object, context: *)
|
||||
*/
|
||||
_compile(math, argNames) {
|
||||
const evalEntries = {};
|
||||
for (const key in this.properties) {
|
||||
if ((0, _object.hasOwnProperty)(this.properties, key)) {
|
||||
// we stringify/parse the key here to resolve unicode characters,
|
||||
// so you cannot create a key like {"co\\u006Estructor": null}
|
||||
const stringifiedKey = (0, _string.stringify)(key);
|
||||
const parsedKey = JSON.parse(stringifiedKey);
|
||||
const prop = (0, _customs.getSafeProperty)(this.properties, key);
|
||||
evalEntries[parsedKey] = prop._compile(math, argNames);
|
||||
}
|
||||
}
|
||||
return function evalObjectNode(scope, args, context) {
|
||||
const obj = {};
|
||||
for (const key in evalEntries) {
|
||||
if ((0, _object.hasOwnProperty)(evalEntries, key)) {
|
||||
obj[key] = evalEntries[key](scope, args, context);
|
||||
}
|
||||
}
|
||||
return obj;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a callback for each of the child nodes of this node
|
||||
* @param {function(child: Node, path: string, parent: Node)} callback
|
||||
*/
|
||||
forEach(callback) {
|
||||
for (const key in this.properties) {
|
||||
if ((0, _object.hasOwnProperty)(this.properties, key)) {
|
||||
callback(this.properties[key], 'properties[' + (0, _string.stringify)(key) + ']', this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new ObjectNode whose children are the results of calling
|
||||
* the provided callback function for each child of the original node.
|
||||
* @param {function(child: Node, path: string, parent: Node): Node} callback
|
||||
* @returns {ObjectNode} Returns a transformed copy of the node
|
||||
*/
|
||||
map(callback) {
|
||||
const properties = {};
|
||||
for (const key in this.properties) {
|
||||
if ((0, _object.hasOwnProperty)(this.properties, key)) {
|
||||
properties[key] = this._ifNode(callback(this.properties[key], 'properties[' + (0, _string.stringify)(key) + ']', this));
|
||||
}
|
||||
}
|
||||
return new ObjectNode(properties);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a clone of this node, a shallow copy
|
||||
* @return {ObjectNode}
|
||||
*/
|
||||
clone() {
|
||||
const properties = {};
|
||||
for (const key in this.properties) {
|
||||
if ((0, _object.hasOwnProperty)(this.properties, key)) {
|
||||
properties[key] = this.properties[key];
|
||||
}
|
||||
}
|
||||
return new ObjectNode(properties);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get string representation
|
||||
* @param {Object} options
|
||||
* @return {string} str
|
||||
* @override
|
||||
*/
|
||||
_toString(options) {
|
||||
const entries = [];
|
||||
for (const key in this.properties) {
|
||||
if ((0, _object.hasOwnProperty)(this.properties, key)) {
|
||||
entries.push((0, _string.stringify)(key) + ': ' + this.properties[key].toString(options));
|
||||
}
|
||||
}
|
||||
return '{' + entries.join(', ') + '}';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a JSON representation of the node
|
||||
* @returns {Object}
|
||||
*/
|
||||
toJSON() {
|
||||
return {
|
||||
mathjs: name,
|
||||
properties: this.properties
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiate an OperatorNode from its JSON representation
|
||||
* @param {Object} json An object structured like
|
||||
* `{"mathjs": "ObjectNode", "properties": {...}}`,
|
||||
* where mathjs is optional
|
||||
* @returns {ObjectNode}
|
||||
*/
|
||||
static fromJSON(json) {
|
||||
return new ObjectNode(json.properties);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get HTML representation
|
||||
* @param {Object} options
|
||||
* @return {string} str
|
||||
* @override
|
||||
*/
|
||||
_toHTML(options) {
|
||||
const entries = [];
|
||||
for (const key in this.properties) {
|
||||
if ((0, _object.hasOwnProperty)(this.properties, key)) {
|
||||
entries.push('<span class="math-symbol math-property">' + (0, _string.escape)(key) + '</span>' + '<span class="math-operator math-assignment-operator ' + 'math-property-assignment-operator math-binary-operator">' + ':</span>' + this.properties[key].toHTML(options));
|
||||
}
|
||||
}
|
||||
return '<span class="math-parenthesis math-curly-parenthesis">{</span>' + entries.join('<span class="math-separator">,</span>') + '<span class="math-parenthesis math-curly-parenthesis">}</span>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get LaTeX representation
|
||||
* @param {Object} options
|
||||
* @return {string} str
|
||||
*/
|
||||
_toTex(options) {
|
||||
const entries = [];
|
||||
for (const key in this.properties) {
|
||||
if ((0, _object.hasOwnProperty)(this.properties, key)) {
|
||||
entries.push('\\mathbf{' + key + ':} & ' + this.properties[key].toTex(options) + '\\\\');
|
||||
}
|
||||
}
|
||||
const tex = '\\left\\{\\begin{array}{ll}' + entries.join('\n') + '\\end{array}\\right\\}';
|
||||
return tex;
|
||||
}
|
||||
}
|
||||
(0, _defineProperty2.default)(ObjectNode, "name", name);
|
||||
return ObjectNode;
|
||||
}, {
|
||||
isClass: true,
|
||||
isNode: true
|
||||
});
|
||||
636
node_modules/mathjs/lib/cjs/expression/node/OperatorNode.js
generated
vendored
Normal file
636
node_modules/mathjs/lib/cjs/expression/node/OperatorNode.js
generated
vendored
Normal file
@@ -0,0 +1,636 @@
|
||||
"use strict";
|
||||
|
||||
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.createOperatorNode = void 0;
|
||||
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
||||
var _is = require("../../utils/is.js");
|
||||
var _array = require("../../utils/array.js");
|
||||
var _scope = require("../../utils/scope.js");
|
||||
var _string = require("../../utils/string.js");
|
||||
var _customs = require("../../utils/customs.js");
|
||||
var _operators = require("../operators.js");
|
||||
var _latex = require("../../utils/latex.js");
|
||||
var _factory = require("../../utils/factory.js");
|
||||
const name = 'OperatorNode';
|
||||
const dependencies = ['Node'];
|
||||
const createOperatorNode = exports.createOperatorNode = /* #__PURE__ */(0, _factory.factory)(name, dependencies, _ref => {
|
||||
let {
|
||||
Node
|
||||
} = _ref;
|
||||
/**
|
||||
* Returns true if the expression starts with a constant, under
|
||||
* the current parenthesization:
|
||||
* @param {Node} expression
|
||||
* @param {string} parenthesis
|
||||
* @return {boolean}
|
||||
*/
|
||||
function startsWithConstant(expr, parenthesis) {
|
||||
let curNode = expr;
|
||||
if (parenthesis === 'auto') {
|
||||
while ((0, _is.isParenthesisNode)(curNode)) curNode = curNode.content;
|
||||
}
|
||||
if ((0, _is.isConstantNode)(curNode)) return true;
|
||||
if ((0, _is.isOperatorNode)(curNode)) {
|
||||
return startsWithConstant(curNode.args[0], parenthesis);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate which parentheses are necessary. Gets an OperatorNode
|
||||
* (which is the root of the tree) and an Array of Nodes
|
||||
* (this.args) and returns an array where 'true' means that an argument
|
||||
* has to be enclosed in parentheses whereas 'false' means the opposite.
|
||||
*
|
||||
* @param {OperatorNode} root
|
||||
* @param {string} parenthesis
|
||||
* @param {Node[]} args
|
||||
* @param {boolean} latex
|
||||
* @return {boolean[]}
|
||||
* @private
|
||||
*/
|
||||
function calculateNecessaryParentheses(root, parenthesis, implicit, args, latex) {
|
||||
// precedence of the root OperatorNode
|
||||
const precedence = (0, _operators.getPrecedence)(root, parenthesis, implicit);
|
||||
const associativity = (0, _operators.getAssociativity)(root, parenthesis);
|
||||
if (parenthesis === 'all' || args.length > 2 && root.getIdentifier() !== 'OperatorNode:add' && root.getIdentifier() !== 'OperatorNode:multiply') {
|
||||
return args.map(function (arg) {
|
||||
switch (arg.getContent().type) {
|
||||
// Nodes that don't need extra parentheses
|
||||
case 'ArrayNode':
|
||||
case 'ConstantNode':
|
||||
case 'SymbolNode':
|
||||
case 'ParenthesisNode':
|
||||
return false;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
let result;
|
||||
switch (args.length) {
|
||||
case 0:
|
||||
result = [];
|
||||
break;
|
||||
case 1:
|
||||
// unary operators
|
||||
{
|
||||
// precedence of the operand
|
||||
const operandPrecedence = (0, _operators.getPrecedence)(args[0], parenthesis, implicit, root);
|
||||
|
||||
// handle special cases for LaTeX, where some of the parentheses aren't needed
|
||||
if (latex && operandPrecedence !== null) {
|
||||
let operandIdentifier;
|
||||
let rootIdentifier;
|
||||
if (parenthesis === 'keep') {
|
||||
operandIdentifier = args[0].getIdentifier();
|
||||
rootIdentifier = root.getIdentifier();
|
||||
} else {
|
||||
// Ignore Parenthesis Nodes when not in 'keep' mode
|
||||
operandIdentifier = args[0].getContent().getIdentifier();
|
||||
rootIdentifier = root.getContent().getIdentifier();
|
||||
}
|
||||
if (_operators.properties[precedence][rootIdentifier].latexLeftParens === false) {
|
||||
result = [false];
|
||||
break;
|
||||
}
|
||||
if (_operators.properties[operandPrecedence][operandIdentifier].latexParens === false) {
|
||||
result = [false];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (operandPrecedence === null) {
|
||||
// if the operand has no defined precedence, no parens are needed
|
||||
result = [false];
|
||||
break;
|
||||
}
|
||||
if (operandPrecedence <= precedence) {
|
||||
// if the operands precedence is lower, parens are needed
|
||||
result = [true];
|
||||
break;
|
||||
}
|
||||
|
||||
// otherwise, no parens needed
|
||||
result = [false];
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
// binary operators
|
||||
{
|
||||
let lhsParens; // left hand side needs parenthesis?
|
||||
// precedence of the left hand side
|
||||
const lhsPrecedence = (0, _operators.getPrecedence)(args[0], parenthesis, implicit, root);
|
||||
// is the root node associative with the left hand side
|
||||
const assocWithLhs = (0, _operators.isAssociativeWith)(root, args[0], parenthesis);
|
||||
if (lhsPrecedence === null) {
|
||||
// if the left hand side has no defined precedence, no parens are needed
|
||||
// FunctionNode for example
|
||||
lhsParens = false;
|
||||
} else if (lhsPrecedence === precedence && associativity === 'right' && !assocWithLhs) {
|
||||
// In case of equal precedence, if the root node is left associative
|
||||
// parens are **never** necessary for the left hand side.
|
||||
// If it is right associative however, parens are necessary
|
||||
// if the root node isn't associative with the left hand side
|
||||
lhsParens = true;
|
||||
} else if (lhsPrecedence < precedence) {
|
||||
lhsParens = true;
|
||||
} else {
|
||||
lhsParens = false;
|
||||
}
|
||||
let rhsParens; // right hand side needs parenthesis?
|
||||
// precedence of the right hand side
|
||||
const rhsPrecedence = (0, _operators.getPrecedence)(args[1], parenthesis, implicit, root);
|
||||
// is the root node associative with the right hand side?
|
||||
const assocWithRhs = (0, _operators.isAssociativeWith)(root, args[1], parenthesis);
|
||||
if (rhsPrecedence === null) {
|
||||
// if the right hand side has no defined precedence, no parens are needed
|
||||
// FunctionNode for example
|
||||
rhsParens = false;
|
||||
} else if (rhsPrecedence === precedence && associativity === 'left' && !assocWithRhs) {
|
||||
// In case of equal precedence, if the root node is right associative
|
||||
// parens are **never** necessary for the right hand side.
|
||||
// If it is left associative however, parens are necessary
|
||||
// if the root node isn't associative with the right hand side
|
||||
rhsParens = true;
|
||||
} else if (rhsPrecedence < precedence) {
|
||||
rhsParens = true;
|
||||
} else {
|
||||
rhsParens = false;
|
||||
}
|
||||
|
||||
// handle special cases for LaTeX, where some of the parentheses aren't needed
|
||||
if (latex) {
|
||||
let rootIdentifier;
|
||||
let lhsIdentifier;
|
||||
let rhsIdentifier;
|
||||
if (parenthesis === 'keep') {
|
||||
rootIdentifier = root.getIdentifier();
|
||||
lhsIdentifier = root.args[0].getIdentifier();
|
||||
rhsIdentifier = root.args[1].getIdentifier();
|
||||
} else {
|
||||
// Ignore ParenthesisNodes when not in 'keep' mode
|
||||
rootIdentifier = root.getContent().getIdentifier();
|
||||
lhsIdentifier = root.args[0].getContent().getIdentifier();
|
||||
rhsIdentifier = root.args[1].getContent().getIdentifier();
|
||||
}
|
||||
if (lhsPrecedence !== null) {
|
||||
if (_operators.properties[precedence][rootIdentifier].latexLeftParens === false) {
|
||||
lhsParens = false;
|
||||
}
|
||||
if (_operators.properties[lhsPrecedence][lhsIdentifier].latexParens === false) {
|
||||
lhsParens = false;
|
||||
}
|
||||
}
|
||||
if (rhsPrecedence !== null) {
|
||||
if (_operators.properties[precedence][rootIdentifier].latexRightParens === false) {
|
||||
rhsParens = false;
|
||||
}
|
||||
if (_operators.properties[rhsPrecedence][rhsIdentifier].latexParens === false) {
|
||||
rhsParens = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
result = [lhsParens, rhsParens];
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (root.getIdentifier() === 'OperatorNode:add' || root.getIdentifier() === 'OperatorNode:multiply') {
|
||||
result = args.map(function (arg) {
|
||||
const argPrecedence = (0, _operators.getPrecedence)(arg, parenthesis, implicit, root);
|
||||
const assocWithArg = (0, _operators.isAssociativeWith)(root, arg, parenthesis);
|
||||
const argAssociativity = (0, _operators.getAssociativity)(arg, parenthesis);
|
||||
if (argPrecedence === null) {
|
||||
// if the argument has no defined precedence, no parens are needed
|
||||
return false;
|
||||
} else if (precedence === argPrecedence && associativity === argAssociativity && !assocWithArg) {
|
||||
return true;
|
||||
} else if (argPrecedence < precedence) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// Handles an edge case of parentheses with implicit multiplication
|
||||
// of ConstantNode.
|
||||
// In that case, parenthesize ConstantNodes that follow an unparenthesized
|
||||
// expression, even though they normally wouldn't be printed.
|
||||
if (args.length >= 2 && root.getIdentifier() === 'OperatorNode:multiply' && root.implicit && parenthesis !== 'all' && implicit === 'hide') {
|
||||
for (let i = 1; i < result.length; ++i) {
|
||||
if (startsWithConstant(args[i], parenthesis) && !result[i - 1] && (parenthesis !== 'keep' || !(0, _is.isParenthesisNode)(args[i - 1]))) {
|
||||
result[i] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
class OperatorNode extends Node {
|
||||
/**
|
||||
* @constructor OperatorNode
|
||||
* @extends {Node}
|
||||
* An operator with two arguments, like 2+3
|
||||
*
|
||||
* @param {string} op Operator name, for example '+'
|
||||
* @param {string} fn Function name, for example 'add'
|
||||
* @param {Node[]} args Operator arguments
|
||||
* @param {boolean} [implicit] Is this an implicit multiplication?
|
||||
* @param {boolean} [isPercentage] Is this an percentage Operation?
|
||||
*/
|
||||
constructor(op, fn, args, implicit, isPercentage) {
|
||||
super();
|
||||
// validate input
|
||||
if (typeof op !== 'string') {
|
||||
throw new TypeError('string expected for parameter "op"');
|
||||
}
|
||||
if (typeof fn !== 'string') {
|
||||
throw new TypeError('string expected for parameter "fn"');
|
||||
}
|
||||
if (!Array.isArray(args) || !args.every(_is.isNode)) {
|
||||
throw new TypeError('Array containing Nodes expected for parameter "args"');
|
||||
}
|
||||
this.implicit = implicit === true;
|
||||
this.isPercentage = isPercentage === true;
|
||||
this.op = op;
|
||||
this.fn = fn;
|
||||
this.args = args || [];
|
||||
}
|
||||
get type() {
|
||||
return name;
|
||||
}
|
||||
get isOperatorNode() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile a node into a JavaScript function.
|
||||
* This basically pre-calculates as much as possible and only leaves open
|
||||
* calculations which depend on a dynamic scope with variables.
|
||||
* @param {Object} math Math.js namespace with functions and constants.
|
||||
* @param {Object} argNames An object with argument names as key and `true`
|
||||
* as value. Used in the SymbolNode to optimize
|
||||
* for arguments from user assigned functions
|
||||
* (see FunctionAssignmentNode) or special symbols
|
||||
* like `end` (see IndexNode).
|
||||
* @return {function} Returns a function which can be called like:
|
||||
* evalNode(scope: Object, args: Object, context: *)
|
||||
*/
|
||||
_compile(math, argNames) {
|
||||
// validate fn
|
||||
if (typeof this.fn !== 'string' || !(0, _customs.isSafeMethod)(math, this.fn)) {
|
||||
if (!math[this.fn]) {
|
||||
throw new Error('Function ' + this.fn + ' missing in provided namespace "math"');
|
||||
} else {
|
||||
throw new Error('No access to function "' + this.fn + '"');
|
||||
}
|
||||
}
|
||||
const fn = (0, _customs.getSafeProperty)(math, this.fn);
|
||||
const evalArgs = (0, _array.map)(this.args, function (arg) {
|
||||
return arg._compile(math, argNames);
|
||||
});
|
||||
if (typeof fn === 'function' && fn.rawArgs === true) {
|
||||
// pass unevaluated parameters (nodes) to the function
|
||||
// "raw" evaluation
|
||||
const rawArgs = this.args;
|
||||
return function evalOperatorNode(scope, args, context) {
|
||||
return fn(rawArgs, math, (0, _scope.createSubScope)(scope, args));
|
||||
};
|
||||
} else if (evalArgs.length === 1) {
|
||||
const evalArg0 = evalArgs[0];
|
||||
return function evalOperatorNode(scope, args, context) {
|
||||
return fn(evalArg0(scope, args, context));
|
||||
};
|
||||
} else if (evalArgs.length === 2) {
|
||||
const evalArg0 = evalArgs[0];
|
||||
const evalArg1 = evalArgs[1];
|
||||
return function evalOperatorNode(scope, args, context) {
|
||||
return fn(evalArg0(scope, args, context), evalArg1(scope, args, context));
|
||||
};
|
||||
} else {
|
||||
return function evalOperatorNode(scope, args, context) {
|
||||
return fn.apply(null, (0, _array.map)(evalArgs, function (evalArg) {
|
||||
return evalArg(scope, args, context);
|
||||
}));
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a callback for each of the child nodes of this node
|
||||
* @param {function(child: Node, path: string, parent: Node)} callback
|
||||
*/
|
||||
forEach(callback) {
|
||||
for (let i = 0; i < this.args.length; i++) {
|
||||
callback(this.args[i], 'args[' + i + ']', this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new OperatorNode whose children are the results of calling
|
||||
* the provided callback function for each child of the original node.
|
||||
* @param {function(child: Node, path: string, parent: Node): Node} callback
|
||||
* @returns {OperatorNode} Returns a transformed copy of the node
|
||||
*/
|
||||
map(callback) {
|
||||
const args = [];
|
||||
for (let i = 0; i < this.args.length; i++) {
|
||||
args[i] = this._ifNode(callback(this.args[i], 'args[' + i + ']', this));
|
||||
}
|
||||
return new OperatorNode(this.op, this.fn, args, this.implicit, this.isPercentage);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a clone of this node, a shallow copy
|
||||
* @return {OperatorNode}
|
||||
*/
|
||||
clone() {
|
||||
return new OperatorNode(this.op, this.fn, this.args.slice(0), this.implicit, this.isPercentage);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether this is an unary OperatorNode:
|
||||
* has exactly one argument, like `-a`.
|
||||
* @return {boolean}
|
||||
* Returns true when an unary operator node, false otherwise.
|
||||
*/
|
||||
isUnary() {
|
||||
return this.args.length === 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether this is a binary OperatorNode:
|
||||
* has exactly two arguments, like `a + b`.
|
||||
* @return {boolean}
|
||||
* Returns true when a binary operator node, false otherwise.
|
||||
*/
|
||||
isBinary() {
|
||||
return this.args.length === 2;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get string representation.
|
||||
* @param {Object} options
|
||||
* @return {string} str
|
||||
*/
|
||||
_toString(options) {
|
||||
const parenthesis = options && options.parenthesis ? options.parenthesis : 'keep';
|
||||
const implicit = options && options.implicit ? options.implicit : 'hide';
|
||||
const args = this.args;
|
||||
const parens = calculateNecessaryParentheses(this, parenthesis, implicit, args, false);
|
||||
if (args.length === 1) {
|
||||
// unary operators
|
||||
const assoc = (0, _operators.getAssociativity)(this, parenthesis);
|
||||
let operand = args[0].toString(options);
|
||||
if (parens[0]) {
|
||||
operand = '(' + operand + ')';
|
||||
}
|
||||
|
||||
// for example for "not", we want a space between operand and argument
|
||||
const opIsNamed = /[a-zA-Z]+/.test(this.op);
|
||||
if (assoc === 'right') {
|
||||
// prefix operator
|
||||
return this.op + (opIsNamed ? ' ' : '') + operand;
|
||||
} else if (assoc === 'left') {
|
||||
// postfix
|
||||
return operand + (opIsNamed ? ' ' : '') + this.op;
|
||||
}
|
||||
|
||||
// fall back to postfix
|
||||
return operand + this.op;
|
||||
} else if (args.length === 2) {
|
||||
let lhs = args[0].toString(options); // left hand side
|
||||
let rhs = args[1].toString(options); // right hand side
|
||||
if (parens[0]) {
|
||||
// left hand side in parenthesis?
|
||||
lhs = '(' + lhs + ')';
|
||||
}
|
||||
if (parens[1]) {
|
||||
// right hand side in parenthesis?
|
||||
rhs = '(' + rhs + ')';
|
||||
}
|
||||
if (this.implicit && this.getIdentifier() === 'OperatorNode:multiply' && implicit === 'hide') {
|
||||
return lhs + ' ' + rhs;
|
||||
}
|
||||
return lhs + ' ' + this.op + ' ' + rhs;
|
||||
} else if (args.length > 2 && (this.getIdentifier() === 'OperatorNode:add' || this.getIdentifier() === 'OperatorNode:multiply')) {
|
||||
const stringifiedArgs = args.map(function (arg, index) {
|
||||
arg = arg.toString(options);
|
||||
if (parens[index]) {
|
||||
// put in parenthesis?
|
||||
arg = '(' + arg + ')';
|
||||
}
|
||||
return arg;
|
||||
});
|
||||
if (this.implicit && this.getIdentifier() === 'OperatorNode:multiply' && implicit === 'hide') {
|
||||
return stringifiedArgs.join(' ');
|
||||
}
|
||||
return stringifiedArgs.join(' ' + this.op + ' ');
|
||||
} else {
|
||||
// fallback to formatting as a function call
|
||||
return this.fn + '(' + this.args.join(', ') + ')';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a JSON representation of the node
|
||||
* @returns {Object}
|
||||
*/
|
||||
toJSON() {
|
||||
return {
|
||||
mathjs: name,
|
||||
op: this.op,
|
||||
fn: this.fn,
|
||||
args: this.args,
|
||||
implicit: this.implicit,
|
||||
isPercentage: this.isPercentage
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiate an OperatorNode from its JSON representation
|
||||
* @param {Object} json
|
||||
* An object structured like
|
||||
* ```
|
||||
* {"mathjs": "OperatorNode",
|
||||
* "op": "+", "fn": "add", "args": [...],
|
||||
* "implicit": false,
|
||||
* "isPercentage":false}
|
||||
* ```
|
||||
* where mathjs is optional
|
||||
* @returns {OperatorNode}
|
||||
*/
|
||||
static fromJSON(json) {
|
||||
return new OperatorNode(json.op, json.fn, json.args, json.implicit, json.isPercentage);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get HTML representation.
|
||||
* @param {Object} options
|
||||
* @return {string} str
|
||||
*/
|
||||
_toHTML(options) {
|
||||
const parenthesis = options && options.parenthesis ? options.parenthesis : 'keep';
|
||||
const implicit = options && options.implicit ? options.implicit : 'hide';
|
||||
const args = this.args;
|
||||
const parens = calculateNecessaryParentheses(this, parenthesis, implicit, args, false);
|
||||
if (args.length === 1) {
|
||||
// unary operators
|
||||
const assoc = (0, _operators.getAssociativity)(this, parenthesis);
|
||||
let operand = args[0].toHTML(options);
|
||||
if (parens[0]) {
|
||||
operand = '<span class="math-parenthesis math-round-parenthesis">(</span>' + operand + '<span class="math-parenthesis math-round-parenthesis">)</span>';
|
||||
}
|
||||
if (assoc === 'right') {
|
||||
// prefix operator
|
||||
return '<span class="math-operator math-unary-operator ' + 'math-lefthand-unary-operator">' + (0, _string.escape)(this.op) + '</span>' + operand;
|
||||
} else {
|
||||
// postfix when assoc === 'left' or undefined
|
||||
return operand + '<span class="math-operator math-unary-operator ' + 'math-righthand-unary-operator">' + (0, _string.escape)(this.op) + '</span>';
|
||||
}
|
||||
} else if (args.length === 2) {
|
||||
// binary operatoes
|
||||
let lhs = args[0].toHTML(options); // left hand side
|
||||
let rhs = args[1].toHTML(options); // right hand side
|
||||
if (parens[0]) {
|
||||
// left hand side in parenthesis?
|
||||
lhs = '<span class="math-parenthesis math-round-parenthesis">(</span>' + lhs + '<span class="math-parenthesis math-round-parenthesis">)</span>';
|
||||
}
|
||||
if (parens[1]) {
|
||||
// right hand side in parenthesis?
|
||||
rhs = '<span class="math-parenthesis math-round-parenthesis">(</span>' + rhs + '<span class="math-parenthesis math-round-parenthesis">)</span>';
|
||||
}
|
||||
if (this.implicit && this.getIdentifier() === 'OperatorNode:multiply' && implicit === 'hide') {
|
||||
return lhs + '<span class="math-operator math-binary-operator ' + 'math-implicit-binary-operator"></span>' + rhs;
|
||||
}
|
||||
return lhs + '<span class="math-operator math-binary-operator ' + 'math-explicit-binary-operator">' + (0, _string.escape)(this.op) + '</span>' + rhs;
|
||||
} else {
|
||||
const stringifiedArgs = args.map(function (arg, index) {
|
||||
arg = arg.toHTML(options);
|
||||
if (parens[index]) {
|
||||
// put in parenthesis?
|
||||
arg = '<span class="math-parenthesis math-round-parenthesis">(</span>' + arg + '<span class="math-parenthesis math-round-parenthesis">)</span>';
|
||||
}
|
||||
return arg;
|
||||
});
|
||||
if (args.length > 2 && (this.getIdentifier() === 'OperatorNode:add' || this.getIdentifier() === 'OperatorNode:multiply')) {
|
||||
if (this.implicit && this.getIdentifier() === 'OperatorNode:multiply' && implicit === 'hide') {
|
||||
return stringifiedArgs.join('<span class="math-operator math-binary-operator ' + 'math-implicit-binary-operator"></span>');
|
||||
}
|
||||
return stringifiedArgs.join('<span class="math-operator math-binary-operator ' + 'math-explicit-binary-operator">' + (0, _string.escape)(this.op) + '</span>');
|
||||
} else {
|
||||
// fallback to formatting as a function call
|
||||
return '<span class="math-function">' + (0, _string.escape)(this.fn) + '</span><span class="math-paranthesis math-round-parenthesis">' + '(</span>' + stringifiedArgs.join('<span class="math-separator">,</span>') + '<span class="math-paranthesis math-round-parenthesis">)</span>';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get LaTeX representation
|
||||
* @param {Object} options
|
||||
* @return {string} str
|
||||
*/
|
||||
_toTex(options) {
|
||||
const parenthesis = options && options.parenthesis ? options.parenthesis : 'keep';
|
||||
const implicit = options && options.implicit ? options.implicit : 'hide';
|
||||
const args = this.args;
|
||||
const parens = calculateNecessaryParentheses(this, parenthesis, implicit, args, true);
|
||||
let op = _latex.latexOperators[this.fn];
|
||||
op = typeof op === 'undefined' ? this.op : op; // fall back to using this.op
|
||||
|
||||
if (args.length === 1) {
|
||||
// unary operators
|
||||
const assoc = (0, _operators.getAssociativity)(this, parenthesis);
|
||||
let operand = args[0].toTex(options);
|
||||
if (parens[0]) {
|
||||
operand = `\\left(${operand}\\right)`;
|
||||
}
|
||||
if (assoc === 'right') {
|
||||
// prefix operator
|
||||
return op + operand;
|
||||
} else if (assoc === 'left') {
|
||||
// postfix operator
|
||||
return operand + op;
|
||||
}
|
||||
|
||||
// fall back to postfix
|
||||
return operand + op;
|
||||
} else if (args.length === 2) {
|
||||
// binary operators
|
||||
const lhs = args[0]; // left hand side
|
||||
let lhsTex = lhs.toTex(options);
|
||||
if (parens[0]) {
|
||||
lhsTex = `\\left(${lhsTex}\\right)`;
|
||||
}
|
||||
const rhs = args[1]; // right hand side
|
||||
let rhsTex = rhs.toTex(options);
|
||||
if (parens[1]) {
|
||||
rhsTex = `\\left(${rhsTex}\\right)`;
|
||||
}
|
||||
|
||||
// handle some exceptions (due to the way LaTeX works)
|
||||
let lhsIdentifier;
|
||||
if (parenthesis === 'keep') {
|
||||
lhsIdentifier = lhs.getIdentifier();
|
||||
} else {
|
||||
// Ignore ParenthesisNodes if in 'keep' mode
|
||||
lhsIdentifier = lhs.getContent().getIdentifier();
|
||||
}
|
||||
switch (this.getIdentifier()) {
|
||||
case 'OperatorNode:divide':
|
||||
// op contains '\\frac' at this point
|
||||
return op + '{' + lhsTex + '}' + '{' + rhsTex + '}';
|
||||
case 'OperatorNode:pow':
|
||||
lhsTex = '{' + lhsTex + '}';
|
||||
rhsTex = '{' + rhsTex + '}';
|
||||
switch (lhsIdentifier) {
|
||||
case 'ConditionalNode': //
|
||||
case 'OperatorNode:divide':
|
||||
lhsTex = `\\left(${lhsTex}\\right)`;
|
||||
}
|
||||
break;
|
||||
case 'OperatorNode:multiply':
|
||||
if (this.implicit && implicit === 'hide') {
|
||||
return lhsTex + '~' + rhsTex;
|
||||
}
|
||||
}
|
||||
return lhsTex + op + rhsTex;
|
||||
} else if (args.length > 2 && (this.getIdentifier() === 'OperatorNode:add' || this.getIdentifier() === 'OperatorNode:multiply')) {
|
||||
const texifiedArgs = args.map(function (arg, index) {
|
||||
arg = arg.toTex(options);
|
||||
if (parens[index]) {
|
||||
arg = `\\left(${arg}\\right)`;
|
||||
}
|
||||
return arg;
|
||||
});
|
||||
if (this.getIdentifier() === 'OperatorNode:multiply' && this.implicit && implicit === 'hide') {
|
||||
return texifiedArgs.join('~');
|
||||
}
|
||||
return texifiedArgs.join(op);
|
||||
} else {
|
||||
// fall back to formatting as a function call
|
||||
// as this is a fallback, it doesn't use
|
||||
// fancy function names
|
||||
return '\\mathrm{' + this.fn + '}\\left(' + args.map(function (arg) {
|
||||
return arg.toTex(options);
|
||||
}).join(',') + '\\right)';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get identifier.
|
||||
* @return {string}
|
||||
*/
|
||||
getIdentifier() {
|
||||
return this.type + ':' + this.fn;
|
||||
}
|
||||
}
|
||||
(0, _defineProperty2.default)(OperatorNode, "name", name);
|
||||
return OperatorNode;
|
||||
}, {
|
||||
isClass: true,
|
||||
isNode: true
|
||||
});
|
||||
159
node_modules/mathjs/lib/cjs/expression/node/ParenthesisNode.js
generated
vendored
Normal file
159
node_modules/mathjs/lib/cjs/expression/node/ParenthesisNode.js
generated
vendored
Normal file
@@ -0,0 +1,159 @@
|
||||
"use strict";
|
||||
|
||||
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.createParenthesisNode = void 0;
|
||||
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
||||
var _is = require("../../utils/is.js");
|
||||
var _factory = require("../../utils/factory.js");
|
||||
const name = 'ParenthesisNode';
|
||||
const dependencies = ['Node'];
|
||||
const createParenthesisNode = exports.createParenthesisNode = /* #__PURE__ */(0, _factory.factory)(name, dependencies, _ref => {
|
||||
let {
|
||||
Node
|
||||
} = _ref;
|
||||
class ParenthesisNode extends Node {
|
||||
/**
|
||||
* @constructor ParenthesisNode
|
||||
* @extends {Node}
|
||||
* A parenthesis node describes manual parenthesis from the user input
|
||||
* @param {Node} content
|
||||
* @extends {Node}
|
||||
*/
|
||||
constructor(content) {
|
||||
super();
|
||||
// validate input
|
||||
if (!(0, _is.isNode)(content)) {
|
||||
throw new TypeError('Node expected for parameter "content"');
|
||||
}
|
||||
this.content = content;
|
||||
}
|
||||
get type() {
|
||||
return name;
|
||||
}
|
||||
get isParenthesisNode() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile a node into a JavaScript function.
|
||||
* This basically pre-calculates as much as possible and only leaves open
|
||||
* calculations which depend on a dynamic scope with variables.
|
||||
* @param {Object} math Math.js namespace with functions and constants.
|
||||
* @param {Object} argNames An object with argument names as key and `true`
|
||||
* as value. Used in the SymbolNode to optimize
|
||||
* for arguments from user assigned functions
|
||||
* (see FunctionAssignmentNode) or special symbols
|
||||
* like `end` (see IndexNode).
|
||||
* @return {function} Returns a function which can be called like:
|
||||
* evalNode(scope: Object, args: Object, context: *)
|
||||
*/
|
||||
_compile(math, argNames) {
|
||||
return this.content._compile(math, argNames);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the content of the current Node.
|
||||
* @return {Node} content
|
||||
* @override
|
||||
**/
|
||||
getContent() {
|
||||
return this.content.getContent();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a callback for each of the child nodes of this node
|
||||
* @param {function(child: Node, path: string, parent: Node)} callback
|
||||
*/
|
||||
forEach(callback) {
|
||||
callback(this.content, 'content', this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new ParenthesisNode whose child is the result of calling
|
||||
* the provided callback function on the child of this node.
|
||||
* @param {function(child: Node, path: string, parent: Node) : Node} callback
|
||||
* @returns {ParenthesisNode} Returns a clone of the node
|
||||
*/
|
||||
map(callback) {
|
||||
const content = callback(this.content, 'content', this);
|
||||
return new ParenthesisNode(content);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a clone of this node, a shallow copy
|
||||
* @return {ParenthesisNode}
|
||||
*/
|
||||
clone() {
|
||||
return new ParenthesisNode(this.content);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get string representation
|
||||
* @param {Object} options
|
||||
* @return {string} str
|
||||
* @override
|
||||
*/
|
||||
_toString(options) {
|
||||
if (!options || options && !options.parenthesis || options && options.parenthesis === 'keep') {
|
||||
return '(' + this.content.toString(options) + ')';
|
||||
}
|
||||
return this.content.toString(options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a JSON representation of the node
|
||||
* @returns {Object}
|
||||
*/
|
||||
toJSON() {
|
||||
return {
|
||||
mathjs: name,
|
||||
content: this.content
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiate an ParenthesisNode from its JSON representation
|
||||
* @param {Object} json An object structured like
|
||||
* `{"mathjs": "ParenthesisNode", "content": ...}`,
|
||||
* where mathjs is optional
|
||||
* @returns {ParenthesisNode}
|
||||
*/
|
||||
static fromJSON(json) {
|
||||
return new ParenthesisNode(json.content);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get HTML representation
|
||||
* @param {Object} options
|
||||
* @return {string} str
|
||||
* @override
|
||||
*/
|
||||
_toHTML(options) {
|
||||
if (!options || options && !options.parenthesis || options && options.parenthesis === 'keep') {
|
||||
return '<span class="math-parenthesis math-round-parenthesis">(</span>' + this.content.toHTML(options) + '<span class="math-parenthesis math-round-parenthesis">)</span>';
|
||||
}
|
||||
return this.content.toHTML(options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get LaTeX representation
|
||||
* @param {Object} options
|
||||
* @return {string} str
|
||||
* @override
|
||||
*/
|
||||
_toTex(options) {
|
||||
if (!options || options && !options.parenthesis || options && options.parenthesis === 'keep') {
|
||||
return `\\left(${this.content.toTex(options)}\\right)`;
|
||||
}
|
||||
return this.content.toTex(options);
|
||||
}
|
||||
}
|
||||
(0, _defineProperty2.default)(ParenthesisNode, "name", name);
|
||||
return ParenthesisNode;
|
||||
}, {
|
||||
isClass: true,
|
||||
isNode: true
|
||||
});
|
||||
257
node_modules/mathjs/lib/cjs/expression/node/RangeNode.js
generated
vendored
Normal file
257
node_modules/mathjs/lib/cjs/expression/node/RangeNode.js
generated
vendored
Normal file
@@ -0,0 +1,257 @@
|
||||
"use strict";
|
||||
|
||||
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.createRangeNode = void 0;
|
||||
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
||||
var _is = require("../../utils/is.js");
|
||||
var _factory = require("../../utils/factory.js");
|
||||
var _operators = require("../operators.js");
|
||||
const name = 'RangeNode';
|
||||
const dependencies = ['Node'];
|
||||
const createRangeNode = exports.createRangeNode = /* #__PURE__ */(0, _factory.factory)(name, dependencies, _ref => {
|
||||
let {
|
||||
Node
|
||||
} = _ref;
|
||||
/**
|
||||
* Calculate the necessary parentheses
|
||||
* @param {Node} node
|
||||
* @param {string} parenthesis
|
||||
* @param {string} implicit
|
||||
* @return {Object} parentheses
|
||||
* @private
|
||||
*/
|
||||
function calculateNecessaryParentheses(node, parenthesis, implicit) {
|
||||
const precedence = (0, _operators.getPrecedence)(node, parenthesis, implicit);
|
||||
const parens = {};
|
||||
const startPrecedence = (0, _operators.getPrecedence)(node.start, parenthesis, implicit);
|
||||
parens.start = startPrecedence !== null && startPrecedence <= precedence || parenthesis === 'all';
|
||||
if (node.step) {
|
||||
const stepPrecedence = (0, _operators.getPrecedence)(node.step, parenthesis, implicit);
|
||||
parens.step = stepPrecedence !== null && stepPrecedence <= precedence || parenthesis === 'all';
|
||||
}
|
||||
const endPrecedence = (0, _operators.getPrecedence)(node.end, parenthesis, implicit);
|
||||
parens.end = endPrecedence !== null && endPrecedence <= precedence || parenthesis === 'all';
|
||||
return parens;
|
||||
}
|
||||
class RangeNode extends Node {
|
||||
/**
|
||||
* @constructor RangeNode
|
||||
* @extends {Node}
|
||||
* create a range
|
||||
* @param {Node} start included lower-bound
|
||||
* @param {Node} end included upper-bound
|
||||
* @param {Node} [step] optional step
|
||||
*/
|
||||
constructor(start, end, step) {
|
||||
super();
|
||||
// validate inputs
|
||||
if (!(0, _is.isNode)(start)) throw new TypeError('Node expected');
|
||||
if (!(0, _is.isNode)(end)) throw new TypeError('Node expected');
|
||||
if (step && !(0, _is.isNode)(step)) throw new TypeError('Node expected');
|
||||
if (arguments.length > 3) throw new Error('Too many arguments');
|
||||
this.start = start; // included lower-bound
|
||||
this.end = end; // included upper-bound
|
||||
this.step = step || null; // optional step
|
||||
}
|
||||
get type() {
|
||||
return name;
|
||||
}
|
||||
get isRangeNode() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the RangeNode needs the `end` symbol to be defined.
|
||||
* This end is the size of the Matrix in current dimension.
|
||||
* @return {boolean}
|
||||
*/
|
||||
needsEnd() {
|
||||
// find all `end` symbols in this RangeNode
|
||||
const endSymbols = this.filter(function (node) {
|
||||
return (0, _is.isSymbolNode)(node) && node.name === 'end';
|
||||
});
|
||||
return endSymbols.length > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile a node into a JavaScript function.
|
||||
* This basically pre-calculates as much as possible and only leaves open
|
||||
* calculations which depend on a dynamic scope with variables.
|
||||
* @param {Object} math Math.js namespace with functions and constants.
|
||||
* @param {Object} argNames An object with argument names as key and `true`
|
||||
* as value. Used in the SymbolNode to optimize
|
||||
* for arguments from user assigned functions
|
||||
* (see FunctionAssignmentNode) or special symbols
|
||||
* like `end` (see IndexNode).
|
||||
* @return {function} Returns a function which can be called like:
|
||||
* evalNode(scope: Object, args: Object, context: *)
|
||||
*/
|
||||
_compile(math, argNames) {
|
||||
const range = math.range;
|
||||
const evalStart = this.start._compile(math, argNames);
|
||||
const evalEnd = this.end._compile(math, argNames);
|
||||
if (this.step) {
|
||||
const evalStep = this.step._compile(math, argNames);
|
||||
return function evalRangeNode(scope, args, context) {
|
||||
return range(evalStart(scope, args, context), evalEnd(scope, args, context), evalStep(scope, args, context));
|
||||
};
|
||||
} else {
|
||||
return function evalRangeNode(scope, args, context) {
|
||||
return range(evalStart(scope, args, context), evalEnd(scope, args, context));
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a callback for each of the child nodes of this node
|
||||
* @param {function(child: Node, path: string, parent: Node)} callback
|
||||
*/
|
||||
forEach(callback) {
|
||||
callback(this.start, 'start', this);
|
||||
callback(this.end, 'end', this);
|
||||
if (this.step) {
|
||||
callback(this.step, 'step', this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new RangeNode whose children are the results of calling
|
||||
* the provided callback function for each child of the original node.
|
||||
* @param {function(child: Node, path: string, parent: Node): Node} callback
|
||||
* @returns {RangeNode} Returns a transformed copy of the node
|
||||
*/
|
||||
map(callback) {
|
||||
return new RangeNode(this._ifNode(callback(this.start, 'start', this)), this._ifNode(callback(this.end, 'end', this)), this.step && this._ifNode(callback(this.step, 'step', this)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a clone of this node, a shallow copy
|
||||
* @return {RangeNode}
|
||||
*/
|
||||
clone() {
|
||||
return new RangeNode(this.start, this.end, this.step && this.step);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get string representation
|
||||
* @param {Object} options
|
||||
* @return {string} str
|
||||
*/
|
||||
_toString(options) {
|
||||
const parenthesis = options && options.parenthesis ? options.parenthesis : 'keep';
|
||||
const parens = calculateNecessaryParentheses(this, parenthesis, options && options.implicit);
|
||||
|
||||
// format string as start:step:stop
|
||||
let str;
|
||||
let start = this.start.toString(options);
|
||||
if (parens.start) {
|
||||
start = '(' + start + ')';
|
||||
}
|
||||
str = start;
|
||||
if (this.step) {
|
||||
let step = this.step.toString(options);
|
||||
if (parens.step) {
|
||||
step = '(' + step + ')';
|
||||
}
|
||||
str += ':' + step;
|
||||
}
|
||||
let end = this.end.toString(options);
|
||||
if (parens.end) {
|
||||
end = '(' + end + ')';
|
||||
}
|
||||
str += ':' + end;
|
||||
return str;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a JSON representation of the node
|
||||
* @returns {Object}
|
||||
*/
|
||||
toJSON() {
|
||||
return {
|
||||
mathjs: name,
|
||||
start: this.start,
|
||||
end: this.end,
|
||||
step: this.step
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiate an RangeNode from its JSON representation
|
||||
* @param {Object} json
|
||||
* An object structured like
|
||||
* `{"mathjs": "RangeNode", "start": ..., "end": ..., "step": ...}`,
|
||||
* where mathjs is optional
|
||||
* @returns {RangeNode}
|
||||
*/
|
||||
static fromJSON(json) {
|
||||
return new RangeNode(json.start, json.end, json.step);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get HTML representation
|
||||
* @param {Object} options
|
||||
* @return {string} str
|
||||
*/
|
||||
_toHTML(options) {
|
||||
const parenthesis = options && options.parenthesis ? options.parenthesis : 'keep';
|
||||
const parens = calculateNecessaryParentheses(this, parenthesis, options && options.implicit);
|
||||
|
||||
// format string as start:step:stop
|
||||
let str;
|
||||
let start = this.start.toHTML(options);
|
||||
if (parens.start) {
|
||||
start = '<span class="math-parenthesis math-round-parenthesis">(</span>' + start + '<span class="math-parenthesis math-round-parenthesis">)</span>';
|
||||
}
|
||||
str = start;
|
||||
if (this.step) {
|
||||
let step = this.step.toHTML(options);
|
||||
if (parens.step) {
|
||||
step = '<span class="math-parenthesis math-round-parenthesis">(</span>' + step + '<span class="math-parenthesis math-round-parenthesis">)</span>';
|
||||
}
|
||||
str += '<span class="math-operator math-range-operator">:</span>' + step;
|
||||
}
|
||||
let end = this.end.toHTML(options);
|
||||
if (parens.end) {
|
||||
end = '<span class="math-parenthesis math-round-parenthesis">(</span>' + end + '<span class="math-parenthesis math-round-parenthesis">)</span>';
|
||||
}
|
||||
str += '<span class="math-operator math-range-operator">:</span>' + end;
|
||||
return str;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get LaTeX representation
|
||||
* @params {Object} options
|
||||
* @return {string} str
|
||||
*/
|
||||
_toTex(options) {
|
||||
const parenthesis = options && options.parenthesis ? options.parenthesis : 'keep';
|
||||
const parens = calculateNecessaryParentheses(this, parenthesis, options && options.implicit);
|
||||
let str = this.start.toTex(options);
|
||||
if (parens.start) {
|
||||
str = `\\left(${str}\\right)`;
|
||||
}
|
||||
if (this.step) {
|
||||
let step = this.step.toTex(options);
|
||||
if (parens.step) {
|
||||
step = `\\left(${step}\\right)`;
|
||||
}
|
||||
str += ':' + step;
|
||||
}
|
||||
let end = this.end.toTex(options);
|
||||
if (parens.end) {
|
||||
end = `\\left(${end}\\right)`;
|
||||
}
|
||||
str += ':' + end;
|
||||
return str;
|
||||
}
|
||||
}
|
||||
(0, _defineProperty2.default)(RangeNode, "name", name);
|
||||
return RangeNode;
|
||||
}, {
|
||||
isClass: true,
|
||||
isNode: true
|
||||
});
|
||||
205
node_modules/mathjs/lib/cjs/expression/node/RelationalNode.js
generated
vendored
Normal file
205
node_modules/mathjs/lib/cjs/expression/node/RelationalNode.js
generated
vendored
Normal file
@@ -0,0 +1,205 @@
|
||||
"use strict";
|
||||
|
||||
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.createRelationalNode = void 0;
|
||||
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
||||
var _operators = require("../operators.js");
|
||||
var _string = require("../../utils/string.js");
|
||||
var _customs = require("../../utils/customs.js");
|
||||
var _latex = require("../../utils/latex.js");
|
||||
var _factory = require("../../utils/factory.js");
|
||||
const name = 'RelationalNode';
|
||||
const dependencies = ['Node'];
|
||||
const createRelationalNode = exports.createRelationalNode = /* #__PURE__ */(0, _factory.factory)(name, dependencies, _ref => {
|
||||
let {
|
||||
Node
|
||||
} = _ref;
|
||||
const operatorMap = {
|
||||
equal: '==',
|
||||
unequal: '!=',
|
||||
smaller: '<',
|
||||
larger: '>',
|
||||
smallerEq: '<=',
|
||||
largerEq: '>='
|
||||
};
|
||||
class RelationalNode extends Node {
|
||||
/**
|
||||
* A node representing a chained conditional expression, such as 'x > y > z'
|
||||
*
|
||||
* @param {String[]} conditionals
|
||||
* An array of conditional operators used to compare the parameters
|
||||
* @param {Node[]} params
|
||||
* The parameters that will be compared
|
||||
*
|
||||
* @constructor RelationalNode
|
||||
* @extends {Node}
|
||||
*/
|
||||
constructor(conditionals, params) {
|
||||
super();
|
||||
if (!Array.isArray(conditionals)) {
|
||||
throw new TypeError('Parameter conditionals must be an array');
|
||||
}
|
||||
if (!Array.isArray(params)) {
|
||||
throw new TypeError('Parameter params must be an array');
|
||||
}
|
||||
if (conditionals.length !== params.length - 1) {
|
||||
throw new TypeError('Parameter params must contain exactly one more element ' + 'than parameter conditionals');
|
||||
}
|
||||
this.conditionals = conditionals;
|
||||
this.params = params;
|
||||
}
|
||||
get type() {
|
||||
return name;
|
||||
}
|
||||
get isRelationalNode() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile a node into a JavaScript function.
|
||||
* This basically pre-calculates as much as possible and only leaves open
|
||||
* calculations which depend on a dynamic scope with variables.
|
||||
* @param {Object} math Math.js namespace with functions and constants.
|
||||
* @param {Object} argNames An object with argument names as key and `true`
|
||||
* as value. Used in the SymbolNode to optimize
|
||||
* for arguments from user assigned functions
|
||||
* (see FunctionAssignmentNode) or special symbols
|
||||
* like `end` (see IndexNode).
|
||||
* @return {function} Returns a function which can be called like:
|
||||
* evalNode(scope: Object, args: Object, context: *)
|
||||
*/
|
||||
_compile(math, argNames) {
|
||||
const self = this;
|
||||
const compiled = this.params.map(p => p._compile(math, argNames));
|
||||
return function evalRelationalNode(scope, args, context) {
|
||||
let evalLhs;
|
||||
let evalRhs = compiled[0](scope, args, context);
|
||||
for (let i = 0; i < self.conditionals.length; i++) {
|
||||
evalLhs = evalRhs;
|
||||
evalRhs = compiled[i + 1](scope, args, context);
|
||||
const condFn = (0, _customs.getSafeProperty)(math, self.conditionals[i]);
|
||||
if (!condFn(evalLhs, evalRhs)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a callback for each of the child nodes of this node
|
||||
* @param {function(child: Node, path: string, parent: Node)} callback
|
||||
*/
|
||||
forEach(callback) {
|
||||
this.params.forEach((n, i) => callback(n, 'params[' + i + ']', this), this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new RelationalNode whose children are the results of calling
|
||||
* the provided callback function for each child of the original node.
|
||||
* @param {function(child: Node, path: string, parent: Node): Node} callback
|
||||
* @returns {RelationalNode} Returns a transformed copy of the node
|
||||
*/
|
||||
map(callback) {
|
||||
return new RelationalNode(this.conditionals.slice(), this.params.map((n, i) => this._ifNode(callback(n, 'params[' + i + ']', this)), this));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a clone of this node, a shallow copy
|
||||
* @return {RelationalNode}
|
||||
*/
|
||||
clone() {
|
||||
return new RelationalNode(this.conditionals, this.params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get string representation.
|
||||
* @param {Object} options
|
||||
* @return {string} str
|
||||
*/
|
||||
_toString(options) {
|
||||
const parenthesis = options && options.parenthesis ? options.parenthesis : 'keep';
|
||||
const precedence = (0, _operators.getPrecedence)(this, parenthesis, options && options.implicit);
|
||||
const paramStrings = this.params.map(function (p, index) {
|
||||
const paramPrecedence = (0, _operators.getPrecedence)(p, parenthesis, options && options.implicit);
|
||||
return parenthesis === 'all' || paramPrecedence !== null && paramPrecedence <= precedence ? '(' + p.toString(options) + ')' : p.toString(options);
|
||||
});
|
||||
let ret = paramStrings[0];
|
||||
for (let i = 0; i < this.conditionals.length; i++) {
|
||||
ret += ' ' + operatorMap[this.conditionals[i]];
|
||||
ret += ' ' + paramStrings[i + 1];
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a JSON representation of the node
|
||||
* @returns {Object}
|
||||
*/
|
||||
toJSON() {
|
||||
return {
|
||||
mathjs: name,
|
||||
conditionals: this.conditionals,
|
||||
params: this.params
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiate a RelationalNode from its JSON representation
|
||||
* @param {Object} json
|
||||
* An object structured like
|
||||
* `{"mathjs": "RelationalNode", "conditionals": ..., "params": ...}`,
|
||||
* where mathjs is optional
|
||||
* @returns {RelationalNode}
|
||||
*/
|
||||
static fromJSON(json) {
|
||||
return new RelationalNode(json.conditionals, json.params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get HTML representation
|
||||
* @param {Object} options
|
||||
* @return {string} str
|
||||
*/
|
||||
_toHTML(options) {
|
||||
const parenthesis = options && options.parenthesis ? options.parenthesis : 'keep';
|
||||
const precedence = (0, _operators.getPrecedence)(this, parenthesis, options && options.implicit);
|
||||
const paramStrings = this.params.map(function (p, index) {
|
||||
const paramPrecedence = (0, _operators.getPrecedence)(p, parenthesis, options && options.implicit);
|
||||
return parenthesis === 'all' || paramPrecedence !== null && paramPrecedence <= precedence ? '<span class="math-parenthesis math-round-parenthesis">(</span>' + p.toHTML(options) + '<span class="math-parenthesis math-round-parenthesis">)</span>' : p.toHTML(options);
|
||||
});
|
||||
let ret = paramStrings[0];
|
||||
for (let i = 0; i < this.conditionals.length; i++) {
|
||||
ret += '<span class="math-operator math-binary-operator ' + 'math-explicit-binary-operator">' + (0, _string.escape)(operatorMap[this.conditionals[i]]) + '</span>' + paramStrings[i + 1];
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get LaTeX representation
|
||||
* @param {Object} options
|
||||
* @return {string} str
|
||||
*/
|
||||
_toTex(options) {
|
||||
const parenthesis = options && options.parenthesis ? options.parenthesis : 'keep';
|
||||
const precedence = (0, _operators.getPrecedence)(this, parenthesis, options && options.implicit);
|
||||
const paramStrings = this.params.map(function (p, index) {
|
||||
const paramPrecedence = (0, _operators.getPrecedence)(p, parenthesis, options && options.implicit);
|
||||
return parenthesis === 'all' || paramPrecedence !== null && paramPrecedence <= precedence ? '\\left(' + p.toTex(options) + '\right)' : p.toTex(options);
|
||||
});
|
||||
let ret = paramStrings[0];
|
||||
for (let i = 0; i < this.conditionals.length; i++) {
|
||||
ret += _latex.latexOperators[this.conditionals[i]] + paramStrings[i + 1];
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
(0, _defineProperty2.default)(RelationalNode, "name", name);
|
||||
return RelationalNode;
|
||||
}, {
|
||||
isClass: true,
|
||||
isNode: true
|
||||
});
|
||||
199
node_modules/mathjs/lib/cjs/expression/node/SymbolNode.js
generated
vendored
Normal file
199
node_modules/mathjs/lib/cjs/expression/node/SymbolNode.js
generated
vendored
Normal file
@@ -0,0 +1,199 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.createSymbolNode = void 0;
|
||||
var _string = require("../../utils/string.js");
|
||||
var _customs = require("../../utils/customs.js");
|
||||
var _factory = require("../../utils/factory.js");
|
||||
var _latex = require("../../utils/latex.js");
|
||||
const name = 'SymbolNode';
|
||||
const dependencies = ['math', '?Unit', 'Node'];
|
||||
const createSymbolNode = exports.createSymbolNode = /* #__PURE__ */(0, _factory.factory)(name, dependencies, _ref => {
|
||||
let {
|
||||
math,
|
||||
Unit,
|
||||
Node
|
||||
} = _ref;
|
||||
/**
|
||||
* Check whether some name is a valueless unit like "inch".
|
||||
* @param {string} name
|
||||
* @return {boolean}
|
||||
*/
|
||||
function isValuelessUnit(name) {
|
||||
return Unit ? Unit.isValuelessUnit(name) : false;
|
||||
}
|
||||
class SymbolNode extends Node {
|
||||
/**
|
||||
* @constructor SymbolNode
|
||||
* @extends {Node}
|
||||
* A symbol node can hold and resolve a symbol
|
||||
* @param {string} name
|
||||
* @extends {Node}
|
||||
*/
|
||||
constructor(name) {
|
||||
super();
|
||||
// validate input
|
||||
if (typeof name !== 'string') {
|
||||
throw new TypeError('String expected for parameter "name"');
|
||||
}
|
||||
this.name = name;
|
||||
}
|
||||
get type() {
|
||||
return 'SymbolNode';
|
||||
}
|
||||
get isSymbolNode() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile a node into a JavaScript function.
|
||||
* This basically pre-calculates as much as possible and only leaves open
|
||||
* calculations which depend on a dynamic scope with variables.
|
||||
* @param {Object} math Math.js namespace with functions and constants.
|
||||
* @param {Object} argNames An object with argument names as key and `true`
|
||||
* as value. Used in the SymbolNode to optimize
|
||||
* for arguments from user assigned functions
|
||||
* (see FunctionAssignmentNode) or special symbols
|
||||
* like `end` (see IndexNode).
|
||||
* @return {function} Returns a function which can be called like:
|
||||
* evalNode(scope: Object, args: Object, context: *)
|
||||
*/
|
||||
_compile(math, argNames) {
|
||||
const name = this.name;
|
||||
if (argNames[name] === true) {
|
||||
// this is a FunctionAssignment argument
|
||||
// (like an x when inside the expression of a function
|
||||
// assignment `f(x) = ...`)
|
||||
return function (scope, args, context) {
|
||||
return (0, _customs.getSafeProperty)(args, name);
|
||||
};
|
||||
} else if (name in math) {
|
||||
return function (scope, args, context) {
|
||||
return scope.has(name) ? scope.get(name) : (0, _customs.getSafeProperty)(math, name);
|
||||
};
|
||||
} else {
|
||||
const isUnit = isValuelessUnit(name);
|
||||
return function (scope, args, context) {
|
||||
return scope.has(name) ? scope.get(name) : isUnit ? new Unit(null, name) : SymbolNode.onUndefinedSymbol(name);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a callback for each of the child nodes of this node
|
||||
* @param {function(child: Node, path: string, parent: Node)} callback
|
||||
*/
|
||||
forEach(callback) {
|
||||
// nothing to do, we don't have any children
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new SymbolNode with children produced by the given callback.
|
||||
* Trivial since a SymbolNode has no children
|
||||
* @param {function(child: Node, path: string, parent: Node) : Node} callback
|
||||
* @returns {SymbolNode} Returns a clone of the node
|
||||
*/
|
||||
map(callback) {
|
||||
return this.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Throws an error 'Undefined symbol {name}'
|
||||
* @param {string} name
|
||||
*/
|
||||
static onUndefinedSymbol(name) {
|
||||
throw new Error('Undefined symbol ' + name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a clone of this node, a shallow copy
|
||||
* @return {SymbolNode}
|
||||
*/
|
||||
clone() {
|
||||
return new SymbolNode(this.name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get string representation
|
||||
* @param {Object} options
|
||||
* @return {string} str
|
||||
* @override
|
||||
*/
|
||||
_toString(options) {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get HTML representation
|
||||
* @param {Object} options
|
||||
* @return {string} str
|
||||
* @override
|
||||
*/
|
||||
_toHTML(options) {
|
||||
const name = (0, _string.escape)(this.name);
|
||||
if (name === 'true' || name === 'false') {
|
||||
return '<span class="math-symbol math-boolean">' + name + '</span>';
|
||||
} else if (name === 'i') {
|
||||
return '<span class="math-symbol math-imaginary-symbol">' + name + '</span>';
|
||||
} else if (name === 'Infinity') {
|
||||
return '<span class="math-symbol math-infinity-symbol">' + name + '</span>';
|
||||
} else if (name === 'NaN') {
|
||||
return '<span class="math-symbol math-nan-symbol">' + name + '</span>';
|
||||
} else if (name === 'null') {
|
||||
return '<span class="math-symbol math-null-symbol">' + name + '</span>';
|
||||
} else if (name === 'undefined') {
|
||||
return '<span class="math-symbol math-undefined-symbol">' + name + '</span>';
|
||||
}
|
||||
return '<span class="math-symbol">' + name + '</span>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a JSON representation of the node
|
||||
* @returns {Object}
|
||||
*/
|
||||
toJSON() {
|
||||
return {
|
||||
mathjs: 'SymbolNode',
|
||||
name: this.name
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiate a SymbolNode from its JSON representation
|
||||
* @param {Object} json An object structured like
|
||||
* `{"mathjs": "SymbolNode", name: "x"}`,
|
||||
* where mathjs is optional
|
||||
* @returns {SymbolNode}
|
||||
*/
|
||||
static fromJSON(json) {
|
||||
return new SymbolNode(json.name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get LaTeX representation
|
||||
* @param {Object} options
|
||||
* @return {string} str
|
||||
* @override
|
||||
*/
|
||||
_toTex(options) {
|
||||
let isUnit = false;
|
||||
if (typeof math[this.name] === 'undefined' && isValuelessUnit(this.name)) {
|
||||
isUnit = true;
|
||||
}
|
||||
const symbol = (0, _latex.toSymbol)(this.name, isUnit);
|
||||
if (symbol[0] === '\\') {
|
||||
// no space needed if the symbol starts with '\'
|
||||
return symbol;
|
||||
}
|
||||
// the space prevents symbols from breaking stuff like '\cdot'
|
||||
// if it's written right before the symbol
|
||||
return ' ' + symbol;
|
||||
}
|
||||
}
|
||||
return SymbolNode;
|
||||
}, {
|
||||
isClass: true,
|
||||
isNode: true
|
||||
});
|
||||
46
node_modules/mathjs/lib/cjs/expression/node/utils/access.js
generated
vendored
Normal file
46
node_modules/mathjs/lib/cjs/expression/node/utils/access.js
generated
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.accessFactory = accessFactory;
|
||||
var _errorTransform = require("../../transform/utils/errorTransform.js");
|
||||
var _customs = require("../../../utils/customs.js");
|
||||
function accessFactory(_ref) {
|
||||
let {
|
||||
subset
|
||||
} = _ref;
|
||||
/**
|
||||
* Retrieve part of an object:
|
||||
*
|
||||
* - Retrieve a property from an object
|
||||
* - Retrieve a part of a string
|
||||
* - Retrieve a matrix subset
|
||||
*
|
||||
* @param {Object | Array | Matrix | string} object
|
||||
* @param {Index} index
|
||||
* @return {Object | Array | Matrix | string} Returns the subset
|
||||
*/
|
||||
return function access(object, index) {
|
||||
try {
|
||||
if (Array.isArray(object)) {
|
||||
return subset(object, index);
|
||||
} else if (object && typeof object.subset === 'function') {
|
||||
// Matrix
|
||||
return object.subset(index);
|
||||
} else if (typeof object === 'string') {
|
||||
// TODO: move getStringSubset into a separate util file, use that
|
||||
return subset(object, index);
|
||||
} else if (typeof object === 'object') {
|
||||
if (!index.isObjectProperty()) {
|
||||
throw new TypeError('Cannot apply a numeric index as object property');
|
||||
}
|
||||
return (0, _customs.getSafeProperty)(object, index.getObjectProperty());
|
||||
} else {
|
||||
throw new TypeError('Cannot apply index: unsupported type of object');
|
||||
}
|
||||
} catch (err) {
|
||||
throw (0, _errorTransform.errorTransform)(err);
|
||||
}
|
||||
};
|
||||
}
|
||||
57
node_modules/mathjs/lib/cjs/expression/node/utils/assign.js
generated
vendored
Normal file
57
node_modules/mathjs/lib/cjs/expression/node/utils/assign.js
generated
vendored
Normal file
@@ -0,0 +1,57 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.assignFactory = assignFactory;
|
||||
var _errorTransform = require("../../transform/utils/errorTransform.js");
|
||||
var _customs = require("../../../utils/customs.js");
|
||||
function assignFactory(_ref) {
|
||||
let {
|
||||
subset,
|
||||
matrix
|
||||
} = _ref;
|
||||
/**
|
||||
* Replace part of an object:
|
||||
*
|
||||
* - Assign a property to an object
|
||||
* - Replace a part of a string
|
||||
* - Replace a matrix subset
|
||||
*
|
||||
* @param {Object | Array | Matrix | string} object
|
||||
* @param {Index} index
|
||||
* @param {*} value
|
||||
* @return {Object | Array | Matrix | string} Returns the original object
|
||||
* except in case of a string
|
||||
*/
|
||||
// TODO: change assign to return the value instead of the object
|
||||
return function assign(object, index, value) {
|
||||
try {
|
||||
if (Array.isArray(object)) {
|
||||
const result = matrix(object).subset(index, value).valueOf();
|
||||
|
||||
// shallow copy all (updated) items into the original array
|
||||
result.forEach((item, index) => {
|
||||
object[index] = item;
|
||||
});
|
||||
return object;
|
||||
} else if (object && typeof object.subset === 'function') {
|
||||
// Matrix
|
||||
return object.subset(index, value);
|
||||
} else if (typeof object === 'string') {
|
||||
// TODO: move setStringSubset into a separate util file, use that
|
||||
return subset(object, index, value);
|
||||
} else if (typeof object === 'object') {
|
||||
if (!index.isObjectProperty()) {
|
||||
throw TypeError('Cannot apply a numeric index as object property');
|
||||
}
|
||||
(0, _customs.setSafeProperty)(object, index.getObjectProperty(), value);
|
||||
return object;
|
||||
} else {
|
||||
throw new TypeError('Cannot apply index: unsupported type of object');
|
||||
}
|
||||
} catch (err) {
|
||||
throw (0, _errorTransform.errorTransform)(err);
|
||||
}
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user