| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320 | 
							- "use strict";
 
- Object.defineProperty(exports, "__esModule", {
 
-   value: true
 
- });
 
- exports.default = void 0;
 
- var _convertUnit = _interopRequireDefault(require("./convertUnit"));
 
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
 
- function isValueType(type) {
 
-   switch (type) {
 
-     case 'LengthValue':
 
-     case 'AngleValue':
 
-     case 'TimeValue':
 
-     case 'FrequencyValue':
 
-     case 'ResolutionValue':
 
-     case 'EmValue':
 
-     case 'ExValue':
 
-     case 'ChValue':
 
-     case 'RemValue':
 
-     case 'VhValue':
 
-     case 'VwValue':
 
-     case 'VminValue':
 
-     case 'VmaxValue':
 
-     case 'PercentageValue':
 
-     case 'Number':
 
-       return true;
 
-   }
 
-   return false;
 
- }
 
- function flip(operator) {
 
-   return operator === '+' ? '-' : '+';
 
- }
 
- function isAddSubOperator(operator) {
 
-   return operator === '+' || operator === '-';
 
- }
 
- function collectAddSubItems(preOperator, node, collected, precision) {
 
-   if (!isAddSubOperator(preOperator)) {
 
-     throw new Error(`invalid operator ${preOperator}`);
 
-   }
 
-   var type = node.type;
 
-   if (isValueType(type)) {
 
-     var itemIndex = collected.findIndex(function (x) {
 
-       return x.node.type === type;
 
-     });
 
-     if (itemIndex >= 0) {
 
-       if (node.value === 0) {
 
-         return;
 
-       }
 
-       var _covertNodesUnits = covertNodesUnits(collected[itemIndex].node, node, precision),
 
-           reducedNode = _covertNodesUnits.left,
 
-           current = _covertNodesUnits.right;
 
-       if (collected[itemIndex].preOperator === '-') {
 
-         collected[itemIndex].preOperator = '+';
 
-         reducedNode.value *= -1;
 
-       }
 
-       if (preOperator === "+") {
 
-         reducedNode.value += current.value;
 
-       } else {
 
-         reducedNode.value -= current.value;
 
-       } // make sure reducedNode.value >= 0
 
-       if (reducedNode.value >= 0) {
 
-         collected[itemIndex] = {
 
-           node: reducedNode,
 
-           preOperator: '+'
 
-         };
 
-       } else {
 
-         reducedNode.value *= -1;
 
-         collected[itemIndex] = {
 
-           node: reducedNode,
 
-           preOperator: '-'
 
-         };
 
-       }
 
-     } else {
 
-       // make sure node.value >= 0
 
-       if (node.value >= 0) {
 
-         collected.push({
 
-           node,
 
-           preOperator
 
-         });
 
-       } else {
 
-         node.value *= -1;
 
-         collected.push({
 
-           node,
 
-           preOperator: flip(preOperator)
 
-         });
 
-       }
 
-     }
 
-   } else if (type === "MathExpression") {
 
-     if (isAddSubOperator(node.operator)) {
 
-       collectAddSubItems(preOperator, node.left, collected, precision);
 
-       var collectRightOperator = preOperator === '-' ? flip(node.operator) : node.operator;
 
-       collectAddSubItems(collectRightOperator, node.right, collected, precision);
 
-     } else {
 
-       // * or /
 
-       var _reducedNode = reduce(node, precision); // prevent infinite recursive call
 
-       if (_reducedNode.type !== "MathExpression" || isAddSubOperator(_reducedNode.operator)) {
 
-         collectAddSubItems(preOperator, _reducedNode, collected, precision);
 
-       } else {
 
-         collected.push({
 
-           node: _reducedNode,
 
-           preOperator
 
-         });
 
-       }
 
-     }
 
-   } else {
 
-     collected.push({
 
-       node,
 
-       preOperator
 
-     });
 
-   }
 
- }
 
- function reduceAddSubExpression(node, precision) {
 
-   var collected = [];
 
-   collectAddSubItems('+', node, collected, precision);
 
-   var withoutZeroItem = collected.filter(function (item) {
 
-     return !(isValueType(item.node.type) && item.node.value === 0);
 
-   });
 
-   var firstNonZeroItem = withoutZeroItem[0]; // could be undefined
 
-   // prevent producing "calc(-var(--a))" or "calc()"
 
-   // which is invalid css
 
-   if (!firstNonZeroItem || firstNonZeroItem.preOperator === '-' && !isValueType(firstNonZeroItem.node.type)) {
 
-     var firstZeroItem = collected.find(function (item) {
 
-       return isValueType(item.node.type) && item.node.value === 0;
 
-     });
 
-     withoutZeroItem.unshift(firstZeroItem);
 
-   } // make sure the preOperator of the first item is +
 
-   if (withoutZeroItem[0].preOperator === '-' && isValueType(withoutZeroItem[0].node.type)) {
 
-     withoutZeroItem[0].node.value *= -1;
 
-     withoutZeroItem[0].preOperator = '+';
 
-   }
 
-   var root = withoutZeroItem[0].node;
 
-   for (var i = 1; i < withoutZeroItem.length; i++) {
 
-     root = {
 
-       type: 'MathExpression',
 
-       operator: withoutZeroItem[i].preOperator,
 
-       left: root,
 
-       right: withoutZeroItem[i].node
 
-     };
 
-   }
 
-   return root;
 
- }
 
- function reduceDivisionExpression(node) {
 
-   if (!isValueType(node.right.type)) {
 
-     return node;
 
-   }
 
-   if (node.right.type !== 'Number') {
 
-     throw new Error(`Cannot divide by "${node.right.unit}", number expected`);
 
-   }
 
-   return applyNumberDivision(node.left, node.right.value);
 
- } // apply (expr) / number
 
- function applyNumberDivision(node, divisor) {
 
-   if (divisor === 0) {
 
-     throw new Error('Cannot divide by zero');
 
-   }
 
-   if (isValueType(node.type)) {
 
-     node.value /= divisor;
 
-     return node;
 
-   }
 
-   if (node.type === "MathExpression" && isAddSubOperator(node.operator)) {
 
-     // turn (a + b) / num into a/num + b/num
 
-     // is good for further reduction
 
-     // checkout the test case
 
-     // "should reduce division before reducing additions"
 
-     return {
 
-       type: "MathExpression",
 
-       operator: node.operator,
 
-       left: applyNumberDivision(node.left, divisor),
 
-       right: applyNumberDivision(node.right, divisor)
 
-     };
 
-   } // it is impossible to reduce it into a single value
 
-   // .e.g the node contains css variable
 
-   // so we just preserve the division and let browser do it
 
-   return {
 
-     type: "MathExpression",
 
-     operator: '/',
 
-     left: node,
 
-     right: {
 
-       type: "Number",
 
-       value: divisor
 
-     }
 
-   };
 
- }
 
- function reduceMultiplicationExpression(node) {
 
-   // (expr) * number
 
-   if (node.right.type === 'Number') {
 
-     return applyNumberMultiplication(node.left, node.right.value);
 
-   } // number * (expr)
 
-   if (node.left.type === 'Number') {
 
-     return applyNumberMultiplication(node.right, node.left.value);
 
-   }
 
-   return node;
 
- } // apply (expr) / number
 
- function applyNumberMultiplication(node, multiplier) {
 
-   if (isValueType(node.type)) {
 
-     node.value *= multiplier;
 
-     return node;
 
-   }
 
-   if (node.type === "MathExpression" && isAddSubOperator(node.operator)) {
 
-     // turn (a + b) * num into a*num + b*num
 
-     // is good for further reduction
 
-     // checkout the test case
 
-     // "should reduce multiplication before reducing additions"
 
-     return {
 
-       type: "MathExpression",
 
-       operator: node.operator,
 
-       left: applyNumberMultiplication(node.left, multiplier),
 
-       right: applyNumberMultiplication(node.right, multiplier)
 
-     };
 
-   } // it is impossible to reduce it into a single value
 
-   // .e.g the node contains css variable
 
-   // so we just preserve the division and let browser do it
 
-   return {
 
-     type: "MathExpression",
 
-     operator: '*',
 
-     left: node,
 
-     right: {
 
-       type: "Number",
 
-       value: multiplier
 
-     }
 
-   };
 
- }
 
- function covertNodesUnits(left, right, precision) {
 
-   switch (left.type) {
 
-     case 'LengthValue':
 
-     case 'AngleValue':
 
-     case 'TimeValue':
 
-     case 'FrequencyValue':
 
-     case 'ResolutionValue':
 
-       if (right.type === left.type && right.unit && left.unit) {
 
-         var converted = (0, _convertUnit.default)(right.value, right.unit, left.unit, precision);
 
-         right = {
 
-           type: left.type,
 
-           value: converted,
 
-           unit: left.unit
 
-         };
 
-       }
 
-       return {
 
-         left,
 
-         right
 
-       };
 
-     default:
 
-       return {
 
-         left,
 
-         right
 
-       };
 
-   }
 
- }
 
- function reduce(node, precision) {
 
-   if (node.type === "MathExpression") {
 
-     if (isAddSubOperator(node.operator)) {
 
-       // reduceAddSubExpression will call reduce recursively
 
-       return reduceAddSubExpression(node, precision);
 
-     }
 
-     node.left = reduce(node.left, precision);
 
-     node.right = reduce(node.right, precision);
 
-     switch (node.operator) {
 
-       case "/":
 
-         return reduceDivisionExpression(node, precision);
 
-       case "*":
 
-         return reduceMultiplicationExpression(node, precision);
 
-     }
 
-     return node;
 
-   }
 
-   return node;
 
- }
 
- var _default = reduce;
 
- exports.default = _default;
 
- module.exports = exports.default;
 
 
  |