(function(window){
'use strict';
var isNumber=function(str){
return String(str).isNumeric()&&! String(str).startsWith('0');
};
var empty=function(mixedVar){
var undef;
var key;
var i;
var len;
var emptyValues=[ undef, null, false, 0, '', '0' ];
for(i=0, len=emptyValues.length; i < len; i++){
if(mixedVar===emptyValues[ i ]){
return true;
}}
if(typeof mixedVar==='object'){
for(key in mixedVar){
if(mixedVar.hasOwnProperty(key)){
return false;
}}
return true;
}
return false;
};
var array_key_exists=function(key, search){
if(! search||(search.constructor!==Array&&search.constructor!==Object)){
return false;
}
return key in search;
};
var getNumberOfParameters=function(func){
const ARROW=true;
const FUNC_ARGS=ARROW ? /^(function)?\s*[^\(]*\(\s*([^\)]*)\)/m:/^(function)\s*[^\(]*\(\s*([^\)]*)\)/m;
const FUNC_ARG_SPLIT=/,/;
const FUNC_ARG=/^\s*(_?)(.+?)\1\s*$/;
const STRIP_COMMENTS=/((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg;
return(( func||'')
.toString()
.replace(STRIP_COMMENTS, '')
.match(FUNC_ARGS)||[ '', '', '' ])[ 2 ]
.split(FUNC_ARG_SPLIT)
.map(function(arg){
return arg.replace(FUNC_ARG, function(all, underscore, name){
return name.split('=')[ 0 ].trim();
});
})
.filter(String)
.length;
};
var getNumberOfRequiredParameters=function(func){
return func.length;
};
var is_scalar=function(mixedVar){
return(/boolean|number|string/).test(typeof mixedVar);
};
var gettype=function(obj){
return window.jQuery.epoAPI.util.getType(obj);
};
var floatval=function(s, d){
var n;
if(!(typeof s==='string'||typeof s==='number')||isNaN(s)){
if(d!==undefined){
return d;
}
return 0;
}
n=parseFloat(s);
if(isNaN(n)){
if(d!==undefined){
return d;
}
return s;
}
return n;
};
var strcmp=function(str1, str2){
return(( str1===str2) ? 0:(( str1 > str2) ? 1:-1));
};
var bindec=function(binaryString){
binaryString=(binaryString + '').replace(/[^01]/gi, '');
return parseInt(binaryString, 2);
};
var decbin=function(number){
if(number < 0){
number=0xFFFFFFFF + number + 1;
}
return parseInt(number, 10).toString(2);
};
var dechex=function(number){
if(number < 0){
number=0xFFFFFFFF + number + 1;
}
return parseInt(number, 10).toString(16);
};
var decoct=function(number){
if(number < 0){
number=0xFFFFFFFF + number + 1;
}
return parseInt(number, 10).toString(8);
};
var deg2rad=function(angle){
return angle * 0.017453292519943295;
};
var roundWithPrecision=function(num, dec=0){
var num_sign=num >=0 ? 1:-1;
return dec===0 ? Math.round(num):parseFloat(( Math.round(( num * Math.pow(10, dec)) +(num_sign * 0.0001)) / Math.pow(10, dec)).toFixed(dec));
};
var hexdec=function(hexString){
hexString=(hexString + '').replace(/[^a-f0-9]/gi, '');
return parseInt(hexString, 16);
};
var octdec=function(octString){
octString=(octString + '').replace(/[^0-7]/gi, '');
return parseInt(octString, 8);
};
var hypot=function(x, y){
var t;
x=Math.abs(x);
y=Math.abs(y);
t=Math.min(x, y);
x=Math.max(x, y);
t=t / x;
return x * Math.sqrt(1 +(t * t))||null;
};
var THEMECOMPLETE_EPO_MATH={
variables: {},
on_var_not_found: undefined,
on_var_validation: undefined,
operators: {},
functions: {},
cache: {},
construct: function(){
this.add_defaults();
this.set_division_by_zero_to_zero();
return this;
},
add_operator: function($operator){
this.operators[ $operator.operator ]=$operator;
return this;
},
evaluate: function($expression, $cache=true){
return this.execute($expression, $cache);
},
parse: function($expression){
var $tokens;
var result;
var $calculator;
var count=0;
var char;
for(char of $expression){
if(char==='('){
count++;
}else if(char===')'){
count--;
}
if(count < 0){
return false;
}}
if(count!==0){
return false;
}
$tokens=new THEMECOMPLETE_EPO_MATH_Tokenizer($expression, this.operators);
$tokens=$tokens.tokenize().build_reverse_polish_notation();
$calculator=new THEMECOMPLETE_EPO_MATH_Calculator(this.functions, this.operators);
result=$calculator.calculate($tokens, this.variables, this.on_var_not_found, this);
if('number'!==gettype(result)||isNaN(result)){
return false;
}
return result;
},
execute: function($expression, $cache=true, $canreturnstring=false){
var $cache_key=$expression;
var $calculator;
var $tokens;
var result;
if(! array_key_exists($cache_key, this.cache)){
$tokens=new THEMECOMPLETE_EPO_MATH_Tokenizer($expression, this.operators);
$tokens=$tokens.tokenize().build_reverse_polish_notation();
if($cache){
this.cache[ $cache_key ]=$tokens;
}}else{
$tokens=this.cache[ $cache_key ];
}
$calculator=new THEMECOMPLETE_EPO_MATH_Calculator(this.functions, this.operators);
result=$calculator.calculate($tokens, this.variables, this.on_var_not_found, this);
if(false===$canreturnstring&&('number'!==gettype(result)||isNaN(result))){
result=0;
}
return result;
},
add_function: function($name, $function){
this.functions[ $name ]=new THEMECOMPLETE_EPO_MATH_CustomFunction($name, $function);
return this;
},
get_vars: function(){
return this.variables;
},
get_var: function($variable){
if(! array_key_exists($variable, this.variables)){
if(this.on_var_not_found&&'function'===typeof this.on_var_not_found){
this.on_var_not_found($variable);
}
return THEMECOMPLETE_EPO_MATH_Error.trigger('Variable (' + $variable + ') not set', 'UnknownVariableError', 0);
}
return this.variables[ $variable ];
},
set_var: function($variable, $value){
if(this.on_var_validation&&'function'===typeof this.on_var_validation){
$value=this.on_var_validation($variable, $value);
}
this.variables[ $variable ]=$value;
return this;
},
var_exists: function($variable){
return array_key_exists($variable, this.variables);
},
set_vars: function($variables, $clear=true){
var $this=this;
if($clear){
this.remove_vars();
}
$variables.forFach(function($value, $name){
$this.set_var($name, $value);
});
return this;
},
set_var_not_found_handler: function($handler){
this.on_var_not_found=$handler;
return this;
},
set_var_validation_handler: function($handler){
this.on_var_validation=$handler;
return this;
},
remove_var: function($variable){
delete this.variables[ $variable ];
return this;
},
remove_vars: function(){
this.variables={};
this.on_var_not_found=null;
return this;
},
get_operators: function(){
return this.operators;
},
get_functions: function(){
return this.functions;
},
remove_operator: function($operator){
delete this.operators[ $operator ];
},
set_division_by_zero_to_zero: function(){
this.add_operator(new THEMECOMPLETE_EPO_MATH_Operator(
'/',
false,
180,
function($a, $b){
$a=Number($a);
$b=Number($b);
return 0==$b ? 0:$a / $b;
}
)
);
return this;
},
get_cache: function(){
return this.cache;
},
clear_cache: function(){
this.cache=[];
},
add_defaults: function(){
var $this=this;
var default_operators=this.default_operators();
var default_functions=this.default_functions();
Object.keys(default_operators).forEach(function($name){
var $operator=default_operators[ $name ];
$this.add_operator(new THEMECOMPLETE_EPO_MATH_Operator($name, $operator[ 2 ], $operator[ 1 ], $operator[ 0 ]));
});
Object.keys(default_functions).forEach(function($name){
var $callable=default_functions[ $name ];
$this.add_function($name, $callable);
});
this.on_var_validation=this.default_var_validation;
this.variables=this.default_vars();
return this;
},
default_operators: function(){
return {
'+': [
function($a, $b){
$a=floatval($a, 0);
$b=floatval($b, 0);
return $a + $b;
},
170,
false
],
'-': [
function($a, $b){
$a=floatval($a, 0);
$b=floatval($b, 0);
return $a - $b;
},
170,
false
],
uPos: [
function($a){
$a=floatval($a, 0);
return $a;
},
200,
false
],
uNeg: [
function($a){
$a=floatval($a, 0);
return 0 - $a;
},
200,
false
],
'*': [
function($a, $b){
$a=floatval($a, 0);
$b=floatval($b, 0);
return $a * $b;
},
180,
false
],
'/': [
function($a, $b){
$a=floatval($a, 0);
$b=floatval($b, 0);
if(empty($b)){
return THEMECOMPLETE_EPO_MATH_Error.trigger('Division By Zero', 'DivisionByZeroError', 0);
}
return $a / $b;
},
180,
false
],
'^': [
function($a, $b){
$a=floatval($a, 0);
$b=floatval($b, 0);
return Math.pow($a, $b);
},
220,
true
],
'%': [
function($a, $b){
$a=floatval($a, 0);
$b=floatval($b, 0);
return $a % $b;
},
180,
false
],
'&&': [
function($a, $b){
$a=String($a);
$b=String($b);
if($a.isNumeric()){
$a=floatval($a, 0);
}
if($b.isNumeric()){
$b=floatval($b, 0);
}
return $a&&$b ? 1:0;
},
100,
false
],
'||': [
function($a, $b){
$a=String($a);
$b=String($b);
if($a.isNumeric()){
$a=floatval($a, 0);
}
if($b.isNumeric()){
$b=floatval($b, 0);
}
return $a||$b ? 1:0;
},
90,
false
],
'==': [
function($a, $b){
$a=String($a);
$b=String($b);
if($a.isNumeric()&&$b.isNumeric()){
return floatval($a)===floatval($b) ? 1:0;
}
return 0===strcmp($a, $b) ? 1:0;
},
140,
false
],
'!=': [
function($a, $b){
$a=String($a);
$b=String($b);
if($a.isNumeric()&&$b.isNumeric()){
return floatval($a)!==floatval($b) ? 1:0;
}
return 0!==strcmp($a, $b) ? 1:0;
},
140,
false
],
'>=': [
function($a, $b){
$a=String($a);
$b=String($b);
if($a.isNumeric()){
$a=floatval($a, 0);
}
if($b.isNumeric()){
$b=floatval($b, 0);
}
return $a >=$b ? 1:0;
},
150,
false
],
'>': [
function($a, $b){
$a=String($a);
$b=String($b);
if($a.isNumeric()){
$a=floatval($a, 0);
}
if($b.isNumeric()){
$b=floatval($b, 0);
}
return $a > $b ? 1:0;
},
150,
false
],
'<=': [
function($a, $b){
$a=String($a);
$b=String($b);
if($a.isNumeric()){
$a=floatval($a, 0);
}
if($b.isNumeric()){
$b=floatval($b, 0);
}
return $a <=$b ? 1:0;
},
150,
false
],
'<': [
function($a, $b){
$a=String($a);
$b=String($b);
if($a.isNumeric()){
$a=floatval($a, 0);
}
if($b.isNumeric()){
$b=floatval($b, 0);
}
return $a < $b ? 1:0;
},
150,
false
]
};},
default_functions: function(){
var $this=this;
return {
abs: Math.abs,
acos: Math.acos,
acosh: Math.acosh,
arcsin: Math.asin,
arcctg: function($arg){
return(Math.PI / 2) - Math.atan($arg);
},
arccot: function($arg){
return(Math.PI / 2) - Math.atan($arg);
},
arccotan: function($arg){
return(Math.PI / 2) - Math.atan($arg);
},
arcsec: function($arg){
return Math.acos(1 / $arg);
},
arccosec: function($arg){
return Math.asin(1 / $arg);
},
arccsc: function($arg){
return Math.asin(1 / $arg);
},
arccos: Math.acos,
arctan: Math.atan,
arctg: Math.atan,
array: function(...$args){
return $args;
},
asin: Math.asin,
atan: Math.atan,
atan2: Math.atan2,
atanh: Math.atanh,
atn: Math.atan,
avg: function($arg1, ...$args){
var sum;
if(Array.isArray($arg1)){
if(0===$arg1.length){
return THEMECOMPLETE_EPO_MATH_Error.trigger('Array must contain at least one element!', 'InvalidArgumentError', 0);
}}
$args=[].concat.apply([], [ $arg1, ...$args ]);
sum=$args.reduce(function(previousValue, currentValue){
return floatval(currentValue, 0) + floatval(previousValue, 0);
});
return sum / $args.length;
},
average: function($arg1, ...$args){
var sum;
if(Array.isArray($arg1)){
if(0===$arg1.length){
return THEMECOMPLETE_EPO_MATH_Error.trigger('Array must contain at least one element!', 'InvalidArgumentError', 0);
}}
$args=[].concat.apply([], [ $arg1, ...$args ]);
sum=$args.reduce(function(previousValue, currentValue){
return floatval(currentValue, 0) + floatval(previousValue, 0);
});
return sum / $args.length;
},
bindec: bindec,
ceil: Math.ceil,
cos: Math.cos,
cosec: function($arg){
return Math.sin(1 / $arg);
},
csc: function($arg){
return Math.sin(1 / $arg);
},
cosh: Math.cosh,
ctg: function($arg){
return Math.cos($arg) / Math.sin($arg);
},
cot: function($arg){
return Math.cos($arg) / Math.sin($arg);
},
cotan: function($arg){
return Math.cos($arg) / Math.sin($arg);
},
cotg: function($arg){
return Math.cos($arg) / Math.sin($arg);
},
ctn: function($arg){
return Math.cos($arg) / Math.sin($arg);
},
decbin: decbin,
dechex: dechex,
decoct: decoct,
deg2rad: deg2rad,
exp: Math.exp,
expm1: Math.expm1,
floor: Math.floor,
int: Math.floor,
fmod: function($arg1, $arg2){
return $arg1 % $arg2;
},
hexdec: hexdec,
hypot: hypot,
if: function(...$args){
var $exres;
var $expr;
var $trueval;
var $falseval;
var $canreturnstring;
$expr=$args[ 0 ];
$trueval=$args[ 1 ];
$falseval=$args[ 2 ];
if('string'===gettype($trueval)){
$trueval="'" + $trueval.replace(/'/g, "\\'") + "'";
}
if('string'===gettype($falseval)){
$falseval="'" + $falseval.replace(/'/g, "\\'") + "'";
}
$canreturnstring=$args[ 3 ]!==undefined ? $args[ 3 ]:false;
if(0===$expr||1===$expr||true===$expr||false===$expr){
$exres=$expr;
}else{
$exres=$this.execute($expr, true, $canreturnstring);
}
if($exres){
return $this.execute($trueval, true, $canreturnstring);
}
return $this.execute($falseval, true, $canreturnstring);
},
intdiv: function($arg1, $arg2){
return Math.trunc(Math.trunc($arg1) / Math.trunc($arg2));
},
ln: Math.log,
lg: Math.log10,
log: Math.log,
log1p: Math.log1p,
max: function($arg1, ...$args){
var $array;
if(Array.isArray($arg1)&&0===$arg1.length){
return THEMECOMPLETE_EPO_MATH_Error.trigger('Array must contain at least one element!', 'InvalidArgumentError', 0);
}
$array=Array.isArray($arg1) ? $arg1:[ $arg1, ...$args ];
$array=$array.map(floatval);
return Math.max(...$array);
},
min: function($arg1, ...$args){
var $array;
if(Array.isArray($arg1)&&0===$arg1.length){
return THEMECOMPLETE_EPO_MATH_Error.trigger('Array must contain at least one element!', 'InvalidArgumentError', 0);
}
$array=Array.isArray($arg1) ? $arg1:[ $arg1, ...$args ];
$array=$array.map(floatval);
return Math.min(...$array);
},
octdec: octdec,
pi: function(){
return Math.PI;
},
pow: Math.pow,
rad2deg: function(angle){
return angle * 57.29577951308232;
},
round: roundWithPrecision,
sin: Math.sin,
sinh: Math.sinh,
sec: function($arg){
return 1 / Math.cos($arg);
},
sqrt: Math.sqrt,
tan: Math.tan,
tanh: Math.tanh,
tn: Math.tan,
tg: Math.tan,
lookuptable: function(field, lookupTableId){
var lookupTables;
var x;
var y;
var table;
var xColumn;
var price=0;
var tableNum=0;
var TMEPOJS=window.TMEPOJS;
if(TMEPOJS){
lookupTables=window.jQuery.epoAPI.util.parseJSON(TMEPOJS.lookupTables);
if(lookupTables){
if(Array.isArray(lookupTableId)){
tableNum=lookupTableId[ 1 ];
lookupTableId=lookupTableId[ 0 ];
}
if(empty(lookupTableId)){
return 0;
}
if(empty(tableNum)){
tableNum=0;
}
if(Array.isArray(field)){
x=String(field[ 0 ]);
y=String(field[ 1 ]);
}else{
x=String(field);
y='';
}
table=lookupTables[ lookupTableId ];
if(table){
table=table[ tableNum ];
if(table){
table=table.data;
xColumn=table[ x ];
if(xColumn===undefined&&x && x!==undefined){
if(x.isNumeric()&&floatval(x)===0){
xColumn=table[ Object.keys(table)[ 0 ] ];
}else if(x){
x=$this.find_lookup_table_index(x, table);
xColumn=table[ x ];
}}
if(xColumn!==undefined){
if(y&&y!==undefined){
y=$this.find_lookup_table_index(y, xColumn);
}else{
y=Object.keys(xColumn)[ 0 ];
}
if(y==='max'){
price=floatval(xColumn[ Object.keys(xColumn)[ Object.keys(xColumn).length - 1 ] ]);
}else{
price=floatval(xColumn[ y ]);
}}
}}
}}
return price;
},
concat: function($arg1, ...$args){
var $array;
if(Array.isArray($arg1)&&0===$arg1.length){
return THEMECOMPLETE_EPO_MATH_Error.trigger('Array must contain at least one element!', 'InvalidArgumentError', 0);
}
$array=Array.isArray($arg1) ? $arg1:[ $arg1, ...$args ];
return $array.join('');
}};},
find_lookup_table_index: function(value, table){
var r;
var keys=Object.keys(table);
var hasNumericValuesOrMaxLast=function(arr){
var lastElement=arr[ arr.length - 1 ];
var areAllNumericValues=arr.every(function(val){
return String(val).isNumeric();
});
return areAllNumericValues||lastElement==='max';
};
if(hasNumericValuesOrMaxLast(keys)){
value=isNumber(value) ? floatval(value):value;
r=keys.map(function(n){
return isNumber(n) ? floatval(n):n;
}).reduce(function(a, b){
if(b==='max'&&value > a){
return b;
}
if(a==='max'&&value > b){
return a;
}
if(a < b){
if(value > a&&value <=b){
return b;
}}else{
if(( value > b&&value <=a)||(value > a||b==='max')){
return a;
}
return b;
}
if(value > b){
return b;
}
return a;
});
keys=keys.map(function(n){
return isNumber(n) ? floatval(n):n;
});
if(value > Math.max(...keys)||value < Math.min(...keys)){
return false;
}}else{
r=value;
}
return r;
},
default_vars: function(){
return {
pi: 3.141592653589793,
e: 2.718281828459045
};},
default_var_validation: function($variable, $value){
if(! is_scalar($value)&&! Array.isArray($value)&&undefined!==$value){
return THEMECOMPLETE_EPO_MATH_Error.trigger('Variable (' + $variable + ') type (' + gettype($value) + ') is not scalar or array!', 0);
}
return $value;
}};
var THEMECOMPLETE_EPO_MATH_Tokenizer=function($input, $operators){
var node={
tokens: [],
input: '',
operators: {},
number_buffer: '',
string_buffer: '',
allow_negative: true,
in_single_quoted_string: false,
in_double_quoted_string: false,
is_number: function(ch){
return ch >='0'&&ch <='9';
},
is_alpha: function(ch){
return(ch >='a'&&ch <='z')||(ch >='A'&&ch <='Z')||'_'===ch;
},
is_dot: function(ch){
return '.'===ch;
},
is_lp: function(ch){
return '('===ch;
},
is_rp: function(ch){
return ')'===ch;
},
is_comma: function(ch){
return ','===ch;
},
empty_number_buffer_as_literal: function(){
if(this.number_buffer.length){
this.tokens.push(THEMECOMPLETE_EPO_MATH_Token(THEMECOMPLETE_EPO_MATH_Constants.LITERAL, this.number_buffer));
this.number_buffer='';
}},
empty_str_buffer_as_variable: function(){
if(''!==this.string_buffer){
this.tokens.push(THEMECOMPLETE_EPO_MATH_Token(THEMECOMPLETE_EPO_MATH_Constants.VARIABLE, this.string_buffer));
this.string_buffer='';
}},
tokenize: function(){
var is_last_char_escape=false;
var $this=this;
var $token_test=[];
this.tokens=[];
this.input.toString().split('').forEach(function(ch){
switch(true){
case $this.in_single_quoted_string:
if('\\'===ch){
if(is_last_char_escape){
$this.string_buffer +='\\';
is_last_char_escape=false;
}else{
is_last_char_escape=true;
}
break;
}else if("'"===ch){
if(is_last_char_escape){
$this.string_buffer +="'";
is_last_char_escape=false;
}else{
$this.tokens.push(THEMECOMPLETE_EPO_MATH_Token(THEMECOMPLETE_EPO_MATH_Constants.STRING, $this.string_buffer));
$this.in_single_quoted_string=false;
$this.string_buffer='';
}
break;
}
if(is_last_char_escape){
$this.string_buffer +='\\';
is_last_char_escape=false;
}
$this.string_buffer +=ch;
break;
case $this.in_double_quoted_string:
if('\\'===ch){
if(is_last_char_escape){
$this.string_buffer +='\\';
is_last_char_escape=false;
}else{
is_last_char_escape=true;
}
break;
}else if('"'===ch){
if(is_last_char_escape){
$this.string_buffer +='"';
is_last_char_escape=false;
}else{
$this.tokens.push(THEMECOMPLETE_EPO_MATH_Token(THEMECOMPLETE_EPO_MATH_Constants.STRING, $this.string_buffer));
$this.in_double_quoted_string=false;
$this.string_buffer='';
}
break;
}
if(is_last_char_escape){
$this.string_buffer +='\\';
is_last_char_escape=false;
}
$this.string_buffer +=ch;
break;
case '['===ch:
$this.tokens.push(THEMECOMPLETE_EPO_MATH_Token(THEMECOMPLETE_EPO_MATH_Constants.FUNCTION, 'array'));
$this.allow_negative=true;
$this.tokens.push(THEMECOMPLETE_EPO_MATH_Token(THEMECOMPLETE_EPO_MATH_Constants.LEFTPARENTHESIS, ''));
break;
case ' '===ch||'\n'===ch||'\r'===ch||'\t'===ch:
break;
case $this.is_number(ch):
if(''!==$this.string_buffer){
$this.string_buffer +=ch;
break;
}
$this.number_buffer +=ch;
$this.allow_negative=false;
break;
case 'e'===ch.toLowerCase():
if($this.number_buffer.length&&-1!==$this.number_buffer.indexOf('.')){
$this.number_buffer +='e';
$this.allow_negative=false;
break;
}
case $this.is_alpha(ch):
if($this.number_buffer.length){
$this.empty_number_buffer_as_literal();
$this.tokens.push(THEMECOMPLETE_EPO_MATH_Token(THEMECOMPLETE_EPO_MATH_Constants.OPERATOR, '*'));
}
$this.allow_negative=false;
$this.string_buffer +=ch;
break;
case '"'===ch:
$this.in_double_quoted_string=true;
break;
case "'"===ch:
$this.in_single_quoted_string=true;
break;
case $this.is_dot(ch):
$this.number_buffer +=ch;
$this.allow_negative=false;
break;
case $this.is_lp(ch):
if(''!==$this.string_buffer){
$this.tokens.push(THEMECOMPLETE_EPO_MATH_Token(THEMECOMPLETE_EPO_MATH_Constants.FUNCTION, $this.string_buffer));
$this.string_buffer='';
}else if($this.number_buffer.length){
$this.empty_number_buffer_as_literal();
$this.tokens.push(THEMECOMPLETE_EPO_MATH_Token(THEMECOMPLETE_EPO_MATH_Constants.OPERATOR, '*'));
}
$this.allow_negative=true;
$this.tokens.push(THEMECOMPLETE_EPO_MATH_Token(THEMECOMPLETE_EPO_MATH_Constants.LEFTPARENTHESIS, ch));
break;
case $this.is_rp(ch)||']'===ch :
$this.empty_number_buffer_as_literal();
$this.empty_str_buffer_as_variable();
$this.allow_negative=false;
$this.tokens.push(THEMECOMPLETE_EPO_MATH_Token(THEMECOMPLETE_EPO_MATH_Constants.RIGHTPARENTHESIS, ch));
break;
case $this.is_comma(ch):
$this.empty_number_buffer_as_literal();
$this.empty_str_buffer_as_variable();
$this.allow_negative=true;
$this.tokens.push(THEMECOMPLETE_EPO_MATH_Token(THEMECOMPLETE_EPO_MATH_Constants.PARAMSEPARATOR, ch));
break;
default:
if('-'===ch||'+'===ch){
if($this.allow_negative){
$this.allow_negative=false;
$this.tokens.push(THEMECOMPLETE_EPO_MATH_Token(THEMECOMPLETE_EPO_MATH_Constants.OPERATOR, '-'===ch ? 'uNeg':'uPos'));
break;
}
if($this.number_buffer&&'e'===$this.number_buffer[ $this.number_buffer.length - 1 ]){
$this.number_buffer +=ch;
break;
}}
$this.empty_number_buffer_as_literal();
$this.empty_str_buffer_as_variable();
if('$'!==ch){
if($this.tokens.length > 0){
if(THEMECOMPLETE_EPO_MATH_Constants.OPERATOR===$this.tokens[ $this.tokens.length - 1 ].type){
$this.tokens[ $this.tokens.length - 1 ].value +=ch;
}else{
$this.tokens.push(THEMECOMPLETE_EPO_MATH_Token(THEMECOMPLETE_EPO_MATH_Constants.OPERATOR, ch));
}}else{
$this.tokens.push(THEMECOMPLETE_EPO_MATH_Token(THEMECOMPLETE_EPO_MATH_Constants.OPERATOR, ch));
}}
$this.allow_negative=true;
}});
this.empty_number_buffer_as_literal();
this.empty_str_buffer_as_variable();
this.tokens.forEach(function($token, $key){
$token_test[ $key ]=$token.type;
});
$token_test.forEach(function($type, $key){
if($key > 0&&'space'===$type&&'variable'===$token_test[ $key + 1 ]&&'variable'===$token_test[ $key - 1 ]){
$this.tokens[ $key ]=new THEMECOMPLETE_EPO_MATH_Token(THEMECOMPLETE_EPO_MATH_Constants.LITERAL, 0);
$this.tokens.splice($key + 1, 1);
$this.tokens.splice($key - 1, 1);
}});
return this;
},
build_reverse_polish_notation: function(){
var $tokens=[];
var $stack=[];
var $param_counter=[];
var $ctoken;
var $f;
var $op1;
var $op2;
var $this=this;
try {
this.tokens.forEach(function($token){
switch($token.type){
case THEMECOMPLETE_EPO_MATH_Constants.LITERAL:
case THEMECOMPLETE_EPO_MATH_Constants.VARIABLE:
case THEMECOMPLETE_EPO_MATH_Constants.STRING:
$tokens.push($token);
if($param_counter.length > 0&&0===$param_counter[ $param_counter.length - 1 ]){
$param_counter.push($param_counter.pop() + 1);
}
break;
case THEMECOMPLETE_EPO_MATH_Constants.FUNCTION:
if($param_counter.length > 0&&0===$param_counter[ $param_counter.length - 1 ]){
$param_counter.push($param_counter.pop() + 1);
}
$stack.push($token);
$param_counter.push(0);
break;
case THEMECOMPLETE_EPO_MATH_Constants.LEFTPARENTHESIS:
$stack.push($token);
break;
case THEMECOMPLETE_EPO_MATH_Constants.PARAMSEPARATOR:
while(THEMECOMPLETE_EPO_MATH_Constants.LEFTPARENTHESIS!==$stack[ $stack.length - 1 ].type){
if(0===$stack.length){
return THEMECOMPLETE_EPO_MATH_Error.trigger('Incorrect Brackets', 'IncorrectBracketsError', $tokens);
}
$tokens.push($stack.pop());
}
$param_counter.push($param_counter.pop() + 1);
break;
case THEMECOMPLETE_EPO_MATH_Constants.OPERATOR:
if(! array_key_exists($token.value, $this.operators)){
return THEMECOMPLETE_EPO_MATH_Error.trigger($token.value, 'UnknownOperatorError', $tokens);
}
$op1=$this.operators[ $token.value ];
while($stack.length > 0&&THEMECOMPLETE_EPO_MATH_Constants.OPERATOR===$stack[ $stack.length - 1 ].type){
if(! array_key_exists($stack[ $stack.length - 1 ].value, $this.operators)){
return THEMECOMPLETE_EPO_MATH_Error.trigger($stack[ $stack.length - 1 ].value, 'UnknownOperatorError', $tokens);
}
$op2=$this.operators[ $stack[ $stack.length - 1 ].value ];
if($op2.priority >=$op1.priority){
$tokens.push($stack.pop());
continue;
}
break;
}
$stack.push($token);
break;
case THEMECOMPLETE_EPO_MATH_Constants.RIGHTPARENTHESIS:
while(true){
try {
$ctoken=$stack.pop();
if(THEMECOMPLETE_EPO_MATH_Constants.LEFTPARENTHESIS===$ctoken.type){
break;
}
$tokens.push($ctoken);
} catch($e){
return THEMECOMPLETE_EPO_MATH_Error.trigger('Incorrect Brackets', 'IncorrectBracketsError', $tokens);
}}
if($stack.length > 0&&THEMECOMPLETE_EPO_MATH_Constants.FUNCTION===$stack[ $stack.length - 1 ].type){
$f=$stack.pop();
$f.param_count=$param_counter.pop();
$tokens.push($f);
}
break;
case THEMECOMPLETE_EPO_MATH_Constants.SPACE:
}});
} catch($e){
$tokens=[];
return THEMECOMPLETE_EPO_MATH_Error.trigger($e, 'Error', $tokens);
}
while(0!==$stack.length){
if(THEMECOMPLETE_EPO_MATH_Constants.LEFTPARENTHESIS===$stack[ $stack.length - 1 ].type||THEMECOMPLETE_EPO_MATH_Constants.RIGHTPARENTHESIS===$stack[ $stack.length - 1 ].type){
return THEMECOMPLETE_EPO_MATH_Error.trigger('Incorrect Brackets', 'IncorrectBracketsError', $tokens);
}
if(THEMECOMPLETE_EPO_MATH_Constants.SPACE===$stack[ $stack.length - 1 ].type){
$stack.pop();
continue;
}
$tokens.push($stack.pop());
}
return $tokens;
}};
node.input=$input;
node.operators=$operators;
return node;
};
var THEMECOMPLETE_EPO_MATH_Constants={
LITERAL: 'literal',
VARIABLE: 'variable',
OPERATOR: 'operator',
LEFTPARENTHESIS: 'LP',
RIGHTPARENTHESIS: 'RP',
FUNCTION: 'function',
PARAMSEPARATOR: 'separator',
STRING: 'string',
SPACE: 'space'
};
var THEMECOMPLETE_EPO_MATH_Token=function($type, $value, $name){
var node={
type: THEMECOMPLETE_EPO_MATH_Constants.LITERAL,
value: undefined,
name: undefined,
param_count: null
};
node.type=$type;
node.value=$value;
node.name=$name;
return node;
};
var THEMECOMPLETE_EPO_MATH_Operator=function($operator, $is_right_assoc, $priority, $function){
var node={
operator: '',
is_right_assoc: false,
priority: 0,
function: null,
places: 0
};
node.operator=$operator;
node.is_right_assoc=$is_right_assoc;
node.priority=$priority;
node.function=$function;
node.places=getNumberOfParameters($function);
node.execute=function($stack){
var $args=[];
var $i;
var $result;
if($stack.length < this.places){
$stack.splice(0, $stack.length);
return THEMECOMPLETE_EPO_MATH_Error.trigger('Incorrect Expression', 'IncorrectExpressionError', new THEMECOMPLETE_EPO_MATH_Token(THEMECOMPLETE_EPO_MATH_Constants.LITERAL, 0));
}
for($i=0; $i < this.places; $i++){
$args.unshift($stack.pop().value);
}
$result=this.function.apply(null, $args);
if('number'!==gettype($result)&&'string'!==gettype($result)){
$result=0;
}
return new THEMECOMPLETE_EPO_MATH_Token(THEMECOMPLETE_EPO_MATH_Constants.LITERAL, $result);
};
return node;
};
var THEMECOMPLETE_EPO_MATH_CustomFunction=function($name, $function){
var node={
name: '',
function: undefined,
required_param_count: undefined
};
node.name=$name;
node.function=$function;
node.required_param_count=getNumberOfRequiredParameters($function);
node.execute=function($stack, $param_count_in_stack){
var $args=[];
var $i;
var $argument;
var $result;
if($param_count_in_stack < this.required_param_count){
$param_count_in_stack=this.required_param_count;
}
if($param_count_in_stack < this.required_param_count){
$stack.splice(0, $stack.length);
return THEMECOMPLETE_EPO_MATH_Error.trigger(this.name, 'IncorrectNumberOfFunctionParametersError', new THEMECOMPLETE_EPO_MATH_Token(THEMECOMPLETE_EPO_MATH_Constants.LITERAL, 0));
}
if($param_count_in_stack > 0){
for($i=0; $i < $param_count_in_stack; $i++){
$argument=$stack.length ? $stack.pop().value:0;
if(null===$argument){
$argument='0';
$args.push($argument);
}else{
$args.unshift($argument);
}}
}
$result=this.function.apply(null, $args);
if($result===Infinity||$result===-Infinity){
$result=0;
}
return THEMECOMPLETE_EPO_MATH_Token(THEMECOMPLETE_EPO_MATH_Constants.LITERAL, $result);
};
return node;
};
var THEMECOMPLETE_EPO_MATH_Calculator=function($functions, $operators){
var node={
functions: {},
operators: {}};
node.functions=$functions;
node.operators=$operators;
node.calculate=function($tokens, $variables, $on_var_not_found=null, $math_object=false){
var $this=this;
var $stack=[];
var $result;
if(empty($tokens)){
return 0;
}
try {
$tokens.forEach(function($token){
var $variable;
var $value;
if(THEMECOMPLETE_EPO_MATH_Constants.LITERAL===$token.type||THEMECOMPLETE_EPO_MATH_Constants.STRING===$token.type){
$stack.push($token);
}else if(THEMECOMPLETE_EPO_MATH_Constants.VARIABLE===$token.type){
$variable=$token.value;
$value=null;
if(array_key_exists($variable, $variables)){
$value=$variables[ $variable ];
}else if($on_var_not_found&&'function'===typeof $on_var_not_found){
$value=$on_var_not_found($variable);
}else{
$value=$variable;
$math_object.variables[ $variable ]=$value;
$variables[ $variable ]=$value;
}
$stack.push(THEMECOMPLETE_EPO_MATH_Token(THEMECOMPLETE_EPO_MATH_Constants.LITERAL, $value, $variable));
}else if(THEMECOMPLETE_EPO_MATH_Constants.FUNCTION===$token.type){
if(! array_key_exists($token.value, $this.functions)){
$math_object.add_function($token.value,
function(){
return 0;
}
);
$this.functions=$math_object.functions;
if(! array_key_exists($token.value, $this.functions)){
return THEMECOMPLETE_EPO_MATH_Error.trigger($token.value, 'UnknownFunctionError', 0);
}
THEMECOMPLETE_EPO_MATH_Error.trigger($token.value, 'UnknownFunctionError', 0);
}
$stack.push($this.functions[ $token.value ].execute($stack, $token.param_count));
}else if(THEMECOMPLETE_EPO_MATH_Constants.OPERATOR===$token.type){
if(! array_key_exists($token.value, $this.operators)){
return THEMECOMPLETE_EPO_MATH_Error.trigger($token.value, 'UnknownOperatorError', 0);
}
$stack.push($this.operators[ $token.value ].execute($stack));
}});
} catch($e){
if(window.TMEPOJS&&window.TMEPOJS.WP_DEBUG){
window.console.log($e);
}}
$result=$stack.pop();
if(undefined===$result||null===$result||! empty($stack)){
return THEMECOMPLETE_EPO_MATH_Error.trigger('Stack must be empty', 'IncorrectExpressionError', 0);
}
if(false===$result.value){
$result.value=0;
}
if(true===$result.value){
$result.value=1;
}
if('string'===gettype($result.value)&&$result.value.isNumeric()){
$result.value=floatval($result.value);
}
return $result.value;
};
return node;
};
var THEMECOMPLETE_EPO_MATH_Error={
trigger: function($msg, $code='', $return=false){
if(window.TMEPOJS&&window.TMEPOJS.WP_DEBUG){
window.console.log($code + '\n' + $msg);
window.console.trace();
}
if(window.TMEPOGLOBALADMINJS&&window.TMEPOGLOBALADMINJS.WP_DEBUG){
return $msg;
}
return $return;
}};
window.tcmexp=THEMECOMPLETE_EPO_MATH.construct();
}(window));