PageSourceSearch

https://oblure.com/wp-content/plugins/woocommerce-tm-extra-product-options/assets/js/tm-math.js?ver=6.4.2

js oblure.com collected 2026-10-04 19:02:47 UTC 39,335 bytes, 1,379 lines download raw bytes

1
2/*jshint esversion: 6 */
3( function( window ) {
4	'use strict';
5
6	var empty = function( mixedVar ) {
7		var undef;
8		var key;
9		var i;
10		var len;
11		var emptyValues = [ undef, null, false, 0, '', '0' ];
12		for ( i = 0, len = emptyValues.length; i < len; i++ ) {
13			if ( mixedVar === emptyValues[ i ] ) {
14				return true;
15			}
16		}
17		if ( typeof mixedVar === 'object' ) {
18			for ( key in mixedVar ) {
19				if ( mixedVar.hasOwnProperty( key ) ) {
20					return false;
21				}
22			}
23			return true;
24		}
25		return false;
26	};
27
28	var array_key_exists = function( key, search ) {
29		if ( ! search || ( search.constructor !== Array && search.constructor !== Object ) ) {
30			return false;
31		}
32		return key in search;
33	};
34
35	var getNumberOfParameters = function( func ) {
36		const ARROW = true;
37		const FUNC_ARGS = ARROW ? /^(function)?\s*[^\(]*\(\s*([^\)]*)\)/m : /^(function)\s*[^\(]*\(\s*([^\)]*)\)/m;
38		const FUNC_ARG_SPLIT = /,/;
39		const FUNC_ARG = /^\s*(_?)(.+?)\1\s*$/;
40		const STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg;
41
42		return ( ( func || '' )
43			.toString()
44			.replace( STRIP_COMMENTS, '' )
45			.match( FUNC_ARGS ) || [ '', '', '' ] )[ 2 ]
46			.split( FUNC_ARG_SPLIT )
47			.map( function( arg ) {
48				return arg.replace( FUNC_ARG, function( all, underscore, name ) {
49					return name.split( '=' )[ 0 ].trim();
50				} );
51			} )
52			.filter( String )
53			.length;
54	};
55
56	var getNumberOfRequiredParameters = function( func ) {
57		return func.length;
58	};
59
60	var is_scalar = function( mixedVar ) {
61		return ( /boolean|number|string/ ).test( typeof mixedVar );
62	};
63
64	var gettype = function( obj ) {
65		return {}.toString.call( obj ).split( ' ' )[ 1 ].slice( 0, -1 ).toLowerCase();
66	};
67
68	var floatval = function( s, d ) {
69		var n;
70
71		if ( ! ( typeof s === 'string' || typeof s === 'number' ) || isNaN( s ) ) {
72			if ( d !== undefined ) {
73				return d;
74			}
75			return 0;
76		}
77		n = parseFloat( s );
78		if ( isNaN( n ) ) {
79			if ( d !== undefined ) {
80				return d;
81			}
82			return s;
83		}
84
85		return n;
86	};
87
88	var strcmp = function( str1, str2 ) {
89		return ( ( str1 === str2 ) ? 0 : ( ( str1 > str2 ) ? 1 : -1 ) );
90	};
91
92	var bindec = function( binaryString ) {
93		binaryString = ( binaryString + '' ).replace( /[^01]/gi, '' );
94		return parseInt( binaryString, 2 );
95	};
96
97	var decbin = function( number ) {
98		if ( number < 0 ) {
99			number = 0xFFFFFFFF + number + 1;
100		}
101		return parseInt( number, 10 ).toString( 2 );
102	};
103
104	var dechex = function( number ) {
105		if ( number < 0 ) {
106			number = 0xFFFFFFFF + number + 1;
107		}
108		return parseInt( number, 10 ).toString( 16 );
109	};
110
111	var decoct = function( number ) {
112		if ( number < 0 ) {
113			number = 0xFFFFFFFF + number + 1;
114		}
115		return parseInt( number, 10 ).toString( 8 );
116	};
117
118	var deg2rad = function( angle ) {
119		return angle * 0.017453292519943295; // (angle / 180) * Math.PI;
120	};
121
122	var roundWithPrecision = function( num, dec = 0 ) {
123		var num_sign = num >= 0 ? 1 : -1;
124		return dec === 0 ? Math.round( num ) : parseFloat( ( Math.round( ( num * Math.pow( 10, dec ) ) + ( num_sign * 0.0001 ) ) / Math.pow( 10, dec ) ).toFixed( dec ) );
125	};
126
127	var hexdec = function( hexString ) {
128		hexString = ( hexString + '' ).replace( /[^a-f0-9]/gi, '' );
129		return parseInt( hexString, 16 );
130	};
131
132	var octdec = function( octString ) {
133		octString = ( octString + '' ).replace( /[^0-7]/gi, '' );
134		return parseInt( octString, 8 );
135	};
136
137	var hypot = function( x, y ) {
138		var t;
139		x = Math.abs( x );
140		y = Math.abs( y );
141		t = Math.min( x, y );
142		x = Math.max( x, y );
143		t = t / x;
144		return x * Math.sqrt( 1 + ( t * t ) ) || null;
145	};
146
147	var THEMECOMPLETE_EPO_MATH = {
148		variables: {},
149		on_var_not_found: undefined,
150		on_var_validation: undefined,
151		operators: {},
152		functions: {},
153		cache: {},
154		construct: function() {
155			this.add_defaults();
156			this.set_division_by_zero_to_zero();
157			return this;
158		},
159		add_operator: function( $operator ) {
160			this.operators[ $operator.operator ] = $operator;
161			return this;
162		},
163		evaluate: function( $expression, $cache = true ) {
164			return this.execute( $expression, $cache );
165		},
166		parse: function( $expression ) {
167			var $tokens;
168			var result;
169			var $calculator;
170			var count = 0;
171			var char;
172
173			for ( char of $expression ) {
174				if ( char === '(' ) {
175					count++;
176				} else if ( char === ')' ) {
177					count--;
178				}
179
180				// If count becomes negative at any point, return false
181				if ( count < 0 ) {
182					return false;
183				}
184			}
185
186			// If count is not zero at the end, parentheses are not balanced
187			if ( count !== 0 ) {
188				return false;
189			}
190
191			$tokens = new THEMECOMPLETE_EPO_MATH_Tokenizer( $expression, this.operators );
192			$tokens = $tokens.tokenize().build_reverse_polish_notation();
193			$calculator = new THEMECOMPLETE_EPO_MATH_Calculator( this.functions, this.operators );
194
195			result = $calculator.calculate( $tokens, this.variables, this.on_var_not_found, this );
196			if ( 'number' !== gettype( result ) || isNaN( result ) ) {
197				return false;
198			}
199			return result;
200		},
201		execute: function( $expression, $cache = true ) {
202			var $cache_key = $expression;
203			var $calculator;
204			var $tokens;
205			var result;
206
207			if ( ! array_key_exists( $cache_key, this.cache ) ) {
208				$tokens = new THEMECOMPLETE_EPO_MATH_Tokenizer( $expression, this.operators );
209				$tokens = $tokens.tokenize().build_reverse_polish_notation();
210				if ( $cache ) {
211					this.cache[ $cache_key ] = $tokens;
212				}
213			} else {
214				$tokens = this.cache[ $cache_key ];
215			}
216
217			$calculator = new THEMECOMPLETE_EPO_MATH_Calculator( this.functions, this.operators );
218
219			result = $calculator.calculate( $tokens, this.variables, this.on_var_not_found, this );
220
221			if ( 'number' !== gettype( result ) || isNaN( result ) ) {
222				result = 0;
223			}
224
225			return result;
226		},
227		add_function: function( $name, $function ) {
228			this.functions[ $name ] = new THEMECOMPLETE_EPO_MATH_CustomFunction( $name, $function );
229			return this;
230		},
231		get_vars: function() {
232			return this.variables;
233		},
234		get_var: function( $variable ) {
235			if ( ! array_key_exists( $variable, this.variables ) ) {
236				if ( this.on_var_not_found && 'function' === typeof this.on_var_not_found ) {
237					this.on_var_not_found( $variable );
238				}
239				return THEMECOMPLETE_EPO_MATH_Error.trigger( 'Variable (' + $variable + ') not set', 'UnknownVariableError', 0 );
240			}
241			return this.variables[ $variable ];
242		},
243		set_var: function( $variable, $value ) {
244			if ( this.on_var_validation && 'function' === typeof this.on_var_validation ) {
245				$value = this.on_var_validation( $variable, $value );
246			}
247			this.variables[ $variable ] = $value;
248			return this;
249		},
250		var_exists: function( $variable ) {
251			return array_key_exists( $variable, this.variables );
252		},
253		set_vars: function( $variables, $clear = true ) {
254			var $this = this;
255			if ( $clear ) {
256				this.remove_vars();
257			}
258			$variables.forFach( function( $value, $name ) {
259				$this.set_var( $name, $value );
260			} );
261			return this;
262		},
263		set_var_not_found_handler: function( $handler ) {
264			this.on_var_not_found = $handler;
265			return this;
266		},
267		set_var_validation_handler: function( $handler ) {
268			this.on_var_validation = $handler;
269			return this;
270		},
271		remove_var: function( $variable ) {
272			delete this.variables[ $variable ];
273			return this;
274		},
275		remove_vars: function() {
276			this.variables = {};
277			this.on_var_not_found = null;
278			return this;
279		},
280		get_operators: function() {
281			return this.operators;
282		},
283		get_functions: function() {
284			return this.functions;
285		},
286		remove_operator: function( $operator ) {
287			delete this.operators[ $operator ];
288		},
289		set_division_by_zero_to_zero: function() {
290			this.add_operator(
291				new THEMECOMPLETE_EPO_MATH_Operator(
292					'/',
293					false,
294					180,
295					function( $a, $b ) {
296						$a = Number( $a );
297						$b = Number( $b );
298						return 0 == $b ? 0 : $a / $b; // eslint-disable-line eqeqeq
299					}
300				)
301			);
302			return this;
303		},
304		get_cache: function() {
305			return this.cache;
306		},
307		clear_cache: function() {
308			this.cache = [];
309		},
310		add_defaults: function() {
311			var $this = this;
312			var default_operators = this.default_operators();
313			var default_functions = this.default_functions();
314			Object.keys( default_operators ).forEach( function( $name ) {
315				var $operator = default_operators[ $name ];
316				$this.add_operator( new THEMECOMPLETE_EPO_MATH_Operator( $name, $operator[ 2 ], $operator[ 1 ], $operator[ 0 ] ) );
317			} );
318			Object.keys( default_functions ).forEach( function( $name ) {
319				var $callable = default_functions[ $name ];
320				$this.add_function( $name, $callable );
321			} );
322			this.on_var_validation = this.default_var_validation;
323			this.variables = this.default_vars();
324			return this;
325		},
326		default_operators: function() {
327			return {
328				'+': [
329					function( $a, $b ) {
330						$a = floatval( $a, 0 );
331						$b = floatval( $b, 0 );
332						return $a + $b;
333					},
334					170,
335					false
336				],
337				'-': [
338					function( $a, $b ) {
339						$a = floatval( $a, 0 );
340						$b = floatval( $b, 0 );
341						return $a - $b;
342					},
343					170,
344					false
345				],
346				// unary positive token.
347				uPos: [
348					function( $a ) {
349						$a = floatval( $a, 0 );
350						return $a;
351					},
352					200,
353					false
354				],
355				// unary minus token.
356				uNeg: [
357					function( $a ) {
358						$a = floatval( $a, 0 );
359						return 0 - $a;
360					},
361					200,
362					false
363				],
364				'*': [
365					function( $a, $b ) {
366						$a = floatval( $a, 0 );
367						$b = floatval( $b, 0 );
368						return $a * $b;
369					},
370					180,
371					false
372				],
373				'/': [
374					function( $a, $b ) {
375						$a = floatval( $a, 0 );
376						$b = floatval( $b, 0 );
377						if ( empty( $b ) ) {
378							return THEMECOMPLETE_EPO_MATH_Error.trigger( 'Division By Zero', 'DivisionByZeroError', 0 );
379						}
380						return $a / $b;
381					},
382					180,
383					false
384				],
385				'^': [
386					function( $a, $b ) {
387						$a = floatval( $a, 0 );
388						$b = floatval( $b, 0 );
389						return Math.pow( $a, $b );
390					},
391					220,
392					true
393				],
394				'%': [
395					function( $a, $b ) {
396						$a = floatval( $a, 0 );
397						$b = floatval( $b, 0 );
398						return $a % $b;
399					},
400					180,
401					false
402				],
403				'&&': [
404					function( $a, $b ) {
405						$a = String( $a );
406						$b = String( $b );
407						if ( $a.isNumeric() ) {
408							$a = floatval( $a, 0 );
409						}
410						if ( $b.isNumeric() ) {
411							$b = floatval( $b, 0 );
412						}
413						return $a && $b ? 1 : 0;
414					},
415					100,
416					false
417				],
418				'||': [
419					function( $a, $b ) {
420						$a = String( $a );
421						$b = String( $b );
422						if ( $a.isNumeric() ) {
423							$a = floatval( $a, 0 );
424						}
425						if ( $b.isNumeric() ) {
426							$b = floatval( $b, 0 );
427						}
428						return $a || $b ? 1 : 0;
429					},
430					90,
431					false
432				],
433				'==': [
434					function( $a, $b ) {
435						$a = String( $a );
436						$b = String( $b );
437						if ( $a.isNumeric() && $b.isNumeric() ) {
438							return floatval( $a ) === floatval( $b ) ? 1 : 0;
439						}
440						return 0 === strcmp( $a, $b ) ? 1 : 0;
441					},
442					140,
443					false
444				],
445				'!=': [
446					function( $a, $b ) {
447						$a = String( $a );
448						$b = String( $b );
449						if ( $a.isNumeric() && $b.isNumeric() ) {
450							return floatval( $a ) !== floatval( $b ) ? 1 : 0;
451						}
452						return 0 !== strcmp( $a, $b ) ? 1 : 0;
453					},
454					140,
455					false
456				],
457				'>=': [
458					function( $a, $b ) {
459						$a = String( $a );
460						$b = String( $b );
461						if ( $a.isNumeric() ) {
462							$a = floatval( $a, 0 );
463						}
464						if ( $b.isNumeric() ) {
465							$b = floatval( $b, 0 );
466						}
467						return $a >= $b ? 1 : 0;
468					},
469					150,
470					false
471				],
472				'>': [
473					function( $a, $b ) {
474						$a = String( $a );
475						$b = String( $b );
476						if ( $a.isNumeric() ) {
477							$a = floatval( $a, 0 );
478						}
479						if ( $b.isNumeric() ) {
480							$b = floatval( $b, 0 );
481						}
482						return $a > $b ? 1 : 0;
483					},
484					150,
485					false
486				],
487				'<=': [
488					function( $a, $b ) {
489						$a = String( $a );
490						$b = String( $b );
491						if ( $a.isNumeric() ) {
492							$a = floatval( $a, 0 );
493						}
494						if ( $b.isNumeric() ) {
495							$b = floatval( $b, 0 );
496						}
497						return $a <= $b ? 1 : 0;
498					},
499					150,
500					false
501				],
502				'<': [
503					function( $a, $b ) {
504						$a = String( $a );
505						$b = String( $b );
506						if ( $a.isNumeric() ) {
507							$a = floatval( $a, 0 );
508						}
509						if ( $b.isNumeric() ) {
510							$b = floatval( $b, 0 );
511						}
512						return $a < $b ? 1 : 0;
513					},
514					150,
515					false
516				]
517			};
518		},
519		default_functions: function() {
520			var $this = this;
521			return {
522				abs: Math.abs,
523				acos: Math.acos,
524				acosh: Math.acosh,
525				arcsin: Math.asin,
526				arcctg: function( $arg ) {
527					return ( Math.PI / 2 ) - Math.atan( $arg );
528				},
529				arccot: function( $arg ) {
530					return ( Math.PI / 2 ) - Math.atan( $arg );
531				},
532				arccotan: function( $arg ) {
533					return ( Math.PI / 2 ) - Math.atan( $arg );
534				},
535				arcsec: function( $arg ) {
536					return Math.acos( 1 / $arg );
537				},
538				arccosec: function( $arg ) {
539					return Math.asin( 1 / $arg );
540				},
541				arccsc: function( $arg ) {
542					return Math.asin( 1 / $arg );
543				},
544				arccos: Math.acos,
545				arctan: Math.atan,
546				arctg: Math.atan,
547				array: function( ...$args ) {
548					return $args;
549				},
550				asin: Math.asin,
551				atan: Math.atan,
552				atan2: Math.atan2,
553				atanh: Math.atanh,
554				atn: Math.atan,
555
556				avg: function( $arg1, ...$args ) {
557					var sum;
558					if ( Array.isArray( $arg1 ) ) {
559						if ( 0 === $arg1.length ) {
560							return THEMECOMPLETE_EPO_MATH_Error.trigger( 'Array must contain at least one element!', 'InvalidArgumentError', 0 );
561						}
562					}
563					$args = [].concat.apply( [], [ $arg1, ...$args ] );
564
565					sum = $args.reduce( function( previousValue, currentValue ) {
566						return floatval( currentValue, 0 ) + floatval( previousValue, 0 );
567					} );
568					return sum / $args.length;
569				},
570				average: function( $arg1, ...$args ) {
571					var sum;
572					if ( Array.isArray( $arg1 ) ) {
573						if ( 0 === $arg1.length ) {
574							return THEMECOMPLETE_EPO_MATH_Error.trigger( 'Array must contain at least one element!', 'InvalidArgumentError', 0 );
575						}
576					}
577					$args = [].concat.apply( [], [ $arg1, ...$args ] );
578
579					sum = $args.reduce( function( previousValue, currentValue ) {
580						return floatval( currentValue, 0 ) + floatval( previousValue, 0 );
581					} );
582					return sum / $args.length;
583				},
584				bindec: bindec,
585				ceil: Math.ceil,
586				cos: Math.cos,
587				cosec: function( $arg ) {
588					return Math.sin( 1 / $arg );
589				},
590				csc: function( $arg ) {
591					return Math.sin( 1 / $arg );
592				},
593				cosh: Math.cosh,
594				ctg: function( $arg ) {
595					return Math.cos( $arg ) / Math.sin( $arg );
596				},
597				cot: function( $arg ) {
598					return Math.cos( $arg ) / Math.sin( $arg );
599				},
600				cotan: function( $arg ) {
601					return Math.cos( $arg ) / Math.sin( $arg );
602				},
603				cotg: function( $arg ) {
604					return Math.cos( $arg ) / Math.sin( $arg );
605				},
606				ctn: function( $arg ) {
607					return Math.cos( $arg ) / Math.sin( $arg );
608				},
609				decbin: decbin,
610				dechex: dechex,
611				decoct: decoct,
612				deg2rad: deg2rad,
613				exp: Math.exp,
614				expm1: Math.expm1,
615				floor: Math.floor,
616				int: Math.floor,
617				fmod: function( $arg1, $arg2 ) {
618					return $arg1 % $arg2;
619				},
620				hexdec: hexdec,
621				hypot: hypot,
622				if: function( $expr, $trueval, $falseval ) {
623					var $exres;
624					if ( 0 === $expr || 1 === $expr || true === $expr || false === $expr ) {
625						$exres = $expr;
626					} else {
627						$exres = $this.execute( $expr );
628					}
629					if ( $exres ) {
630						return $this.execute( $trueval );
631					}
632					return $this.execute( $falseval );
633				},
634				intdiv: function( $arg1, $arg2 ) {
635					return Math.trunc( Math.trunc( $arg1 ) / Math.trunc( $arg2 ) );
636				},
637				ln: Math.log,
638				lg: Math.log10,
639				log: Math.log,
640				log1p: Math.log1p,
641				max: function( $arg1, ...$args ) {
642					var $array;
643					if ( Array.isArray( $arg1 ) && 0 === $arg1.length ) {
644						return THEMECOMPLETE_EPO_MATH_Error.trigger( 'Array must contain at least one element!', 'InvalidArgumentError', 0 );
645					}
646					$array = Array.isArray( $arg1 ) ? $arg1 : [ $arg1, ...$args ];
647					$array = $array.map( floatval );
648
649					return Math.max( ...$array );
650				},
651				min: function( $arg1, ...$args ) {
652					var $array;
653					if ( Array.isArray( $arg1 ) && 0 === $arg1.length ) {
654						return THEMECOMPLETE_EPO_MATH_Error.trigger( 'Array must contain at least one element!', 'InvalidArgumentError', 0 );
655					}
656					$array = Array.isArray( $arg1 ) ? $arg1 : [ $arg1, ...$args ];
657					$array = $array.map( floatval );
658
659					return Math.min( ...$array );
660				},
661				octdec: octdec,
662				pi: function() {
663					return Math.PI;
664				},
665				pow: Math.pow,
666				rad2deg: function( angle ) {
667					return angle * 57.29577951308232; // angle / Math.PI * 180
668				},
669				round: roundWithPrecision,
670				sin: Math.sin,
671				sinh: Math.sinh,
672				sec: function( $arg ) {
673					return 1 / Math.cos( $arg );
674				},
675				sqrt: Math.sqrt,
676				tan: Math.tan,
677				tanh: Math.tanh,
678				tn: Math.tan,
679				tg: Math.tan,
680				lookuptable: function( field, lookupTableId ) {
681					var lookupTables;
682					var x;
683					var y;
684					var table;
685					var xColumn;
686					var price = 0;
687					var tableNum = 0;
688					var TMEPOJS = window.TMEPOJS;
689
690					if ( TMEPOJS ) {
691						lookupTables = window && window.jQuery && window.jQuery.epoAPI && window.jQuery.epoAPI.util.parseJSON( TMEPOJS.lookupTables );
692						if ( lookupTables ) {
693							if ( Array.isArray( lookupTableId ) ) {
694								tableNum = lookupTableId[ 1 ];
695								lookupTableId = lookupTableId[ 0 ];
696							}
697							if ( empty( lookupTableId ) ) {
698								return 0;
699							}
700							if ( empty( tableNum ) ) {
701								tableNum = 0;
702							}
703							if ( Array.isArray( field ) ) {
704								x = String( field[ 0 ] );
705								y = String( field[ 1 ] );
706							} else {
707								x = String( field );
708								y = '';
709							}
710
711							table = lookupTables[ lookupTableId ];
712							if ( table ) {
713								table = table[ tableNum ];
714								if ( table ) {
715									table = table.data;
716									xColumn = table[ x ];
717									if ( xColumn === undefined && x && x !== undefined ) {
718										if ( x.isNumeric() && floatval( x ) === 0 ) {
719											xColumn = table[ Object.keys( table )[ 0 ] ];
720										} else if ( x ) {
721											x = $this.find_lookup_table_index( x, table );
722											xColumn = table[ x ];
723										}
724									}
725									if ( xColumn !== undefined ) {
726										if ( y && y !== undefined ) {
727											y = $this.find_lookup_table_index( y, xColumn );
728										} else {
729											// fetch the first row since this means we want
730											// a single row result
731											y = Object.keys( xColumn )[ 0 ];
732										}
733										if ( y === 'max' ) {
734											price = floatval( xColumn[ Object.keys( xColumn )[ Object.keys( xColumn ).length - 1 ] ] );
735										} else {
736											price = floatval( xColumn[ y ] );
737										}
738									}
739								}
740							}
741						}
742					}
743					return price;
744				},
745				concat: function( $arg1, ...$args ) {
746					var $array;
747					if ( Array.isArray( $arg1 ) && 0 === $arg1.length ) {
748						return THEMECOMPLETE_EPO_MATH_Error.trigger( 'Array must contain at least one element!', 'InvalidArgumentError', 0 );
749					}
750					$array = Array.isArray( $arg1 ) ? $arg1 : [ $arg1, ...$args ];
751
752					return $array.join( '' );
753				}
754			};
755		},
756		find_lookup_table_index: function( value, table ) {
757			var r;
758			var keys = Object.keys( table );
759			var hasNumericValuesOrMaxLast = function( arr ) {
760				var lastElement = arr[ arr.length - 1 ];
761				var areAllNumericValues = arr.every( function( val ) {
762					return String( val ).isNumeric();
763				} );
764				return areAllNumericValues || lastElement === 'max';
765			};
766
767			if ( hasNumericValuesOrMaxLast( keys ) ) {
768				value = String( value ).isNumeric() ? floatval( value ) : value;
769				r = keys.map( function( n ) {
770					return String( n ).isNumeric() ? floatval( n ) : n;
771				} ).reduce( function( a, b ) {
772					if ( b === 'max' && value > a ) {
773						return b;
774					}
775					if ( a === 'max' && value > b ) {
776						return a;
777					}
778					if ( a < b ) {
779						if ( value > a && value <= b ) {
780							return b;
781						}
782					} else {
783						if ( ( value > b && value <= a ) || ( value > a || b === 'max' ) ) {
784							return a;
785						}
786						return b;
787					}
788					if ( value > b ) {
789						return b;
790					}
791					return a;
792				} );
793				keys = keys.map( function( n ) {
794					return String( n ).isNumeric() ? floatval( n ) : n;
795				} );
796
797				if ( value > Math.max( ...keys ) || value < Math.min( ...keys ) ) {
798					return false;
799				}
800			} else {
801				r = value;
802			}
803
804			return r;
805		},
806		default_vars: function() {
807			return {
808				pi: 3.141592653589793,
809				e: 2.718281828459045
810			};
811		},
812		default_var_validation: function( $variable, $value ) {
813			if ( ! is_scalar( $value ) && ! Array.isArray( $value ) && undefined !== $value ) {
814				return THEMECOMPLETE_EPO_MATH_Error.trigger( 'Variable (' + $variable + ') type (' + gettype( $value ) + ') is not scalar or array!', 0 );
815			}
816			return $value;
817		}
818	};
819
820	var THEMECOMPLETE_EPO_MATH_Tokenizer = function( $input, $operators ) {
821		var node = {
822			tokens: [],
823			input: '',
824			operators: {},
825			number_buffer: '',
826			string_buffer: '',
827			allow_negative: true,
828			in_single_quoted_string: false,
829			in_double_quoted_string: false,
830			is_number: function( ch ) {
831				return ch >= '0' && ch <= '9';
832			},
833			is_alpha: function( ch ) {
834				return ( ch >= 'a' && ch <= 'z' ) || ( ch >= 'A' && ch <= 'Z' ) || '_' === ch;
835			},
836			is_dot: function( ch ) {
837				return '.' === ch;
838			},
839			is_lp: function( ch ) {
840				return '(' === ch;
841			},
842			is_rp: function( ch ) {
843				return ')' === ch;
844			},
845			is_comma: function( ch ) {
846				return ',' === ch;
847			},
848			empty_number_buffer_as_literal: function() {
849				if ( this.number_buffer.length ) {
850					this.tokens.push( THEMECOMPLETE_EPO_MATH_Token( THEMECOMPLETE_EPO_MATH_Constants.LITERAL, this.number_buffer ) );
851					this.number_buffer = '';
852				}
853			},
854			empty_str_buffer_as_variable: function() {
855				if ( '' !== this.string_buffer ) {
856					this.tokens.push( THEMECOMPLETE_EPO_MATH_Token( THEMECOMPLETE_EPO_MATH_Constants.VARIABLE, this.string_buffer ) );
857					this.string_buffer = '';
858				}
859			},
860			tokenize: function() {
861				var is_last_char_escape = false;
862				var $this = this;
863				var $token_test = [];
864
865				this.tokens = [];
866
867				this.input.toString().split( '' ).forEach( function( ch ) {
868					switch ( true ) {
869						case $this.in_single_quoted_string:
870							if ( '\\' === ch ) {
871								if ( is_last_char_escape ) {
872									$this.string_buffer += '\\';
873									is_last_char_escape = false;
874								} else {
875									is_last_char_escape = true;
876								}
877								break;
878							} else if ( "'" === ch ) {
879								if ( is_last_char_escape ) {
880									$this.string_buffer += "'";
881									is_last_char_escape = false;
882								} else {
883									$this.tokens.push( THEMECOMPLETE_EPO_MATH_Token( THEMECOMPLETE_EPO_MATH_Constants.STRING, $this.string_buffer ) );
884									$this.in_single_quoted_string = false;
885									$this.string_buffer = '';
886								}
887								break;
888							}
889							if ( is_last_char_escape ) {
890								$this.string_buffer += '\\';
891								is_last_char_escape = false;
892							}
893							$this.string_buffer += ch;
894							break;
895						case $this.in_double_quoted_string:
896							if ( '\\' === ch ) {
897								if ( is_last_char_escape ) {
898									$this.string_buffer += '\\';
899									is_last_char_escape = false;
900								} else {
901									is_last_char_escape = true;
902								}
903								break;
904							} else if ( '"' === ch ) {
905								if ( is_last_char_escape ) {
906									$this.string_buffer += '"';
907									is_last_char_escape = false;
908								} else {
909									$this.tokens.push( THEMECOMPLETE_EPO_MATH_Token( THEMECOMPLETE_EPO_MATH_Constants.STRING, $this.string_buffer ) );
910									$this.in_double_quoted_string = false;
911									$this.string_buffer = '';
912								}
913								break;
914							}
915							if ( is_last_char_escape ) {
916								$this.string_buffer += '\\';
917								is_last_char_escape = false;
918							}
919							$this.string_buffer += ch;
920							break;
921						case '[' === ch:
922							$this.tokens.push( THEMECOMPLETE_EPO_MATH_Token( THEMECOMPLETE_EPO_MATH_Constants.FUNCTION, 'array' ) );
923							$this.allow_negative = true;
924							$this.tokens.push( THEMECOMPLETE_EPO_MATH_Token( THEMECOMPLETE_EPO_MATH_Constants.LEFTPARENTHESIS, '' ) );
925							break;
926						case ' ' === ch || '\n' === ch || '\r' === ch || '\t' === ch:
927							/**
928							 * In case those tokens must not be ingored use the following
929							 *
930							 * $this.empty_number_buffer_as_literal();
931							 * $this.empty_str_buffer_as_variable();
932							 * $this.tokens.push( THEMECOMPLETE_EPO_MATH_Token( THEMECOMPLETE_EPO_MATH_Constants.SPACE, '' ) );
933							 */
934							break;
935						case $this.is_number( ch ):
936							if ( '' !== $this.string_buffer ) {
937								$this.string_buffer += ch;
938								break;
939							}
940							$this.number_buffer += ch;
941							$this.allow_negative = false;
942							break;
943						case 'e' === ch.toLowerCase():
944							if ( $this.number_buffer.length && -1 !== $this.number_buffer.indexOf( '.' ) ) {
945								$this.number_buffer += 'e';
946								$this.allow_negative = false;
947								break;
948							}
949							/* falls through */
950						case $this.is_alpha( ch ):
951							if ( $this.number_buffer.length ) {
952								$this.empty_number_buffer_as_literal();
953								$this.tokens.push( THEMECOMPLETE_EPO_MATH_Token( THEMECOMPLETE_EPO_MATH_Constants.OPERATOR, '*' ) );
954							}
955							$this.allow_negative = false;
956							$this.string_buffer += ch;
957							break;
958						case '"' === ch:
959							$this.in_double_quoted_string = true;
960							break;
961						case "'" === ch:
962							$this.in_single_quoted_string = true;
963							break;
964						case $this.is_dot( ch ):
965							$this.number_buffer += ch;
966							$this.allow_negative = false;
967							break;
968						case $this.is_lp( ch ):
969							if ( '' !== $this.string_buffer ) {
970								$this.tokens.push( THEMECOMPLETE_EPO_MATH_Token( THEMECOMPLETE_EPO_MATH_Constants.FUNCTION, $this.string_buffer ) );
971								$this.string_buffer = '';
972							} else if ( $this.number_buffer.length ) {
973								$this.empty_number_buffer_as_literal();
974								$this.tokens.push( THEMECOMPLETE_EPO_MATH_Token( THEMECOMPLETE_EPO_MATH_Constants.OPERATOR, '*' ) );
975							}
976							$this.allow_negative = true;
977							$this.tokens.push( THEMECOMPLETE_EPO_MATH_Token( THEMECOMPLETE_EPO_MATH_Constants.LEFTPARENTHESIS, ch ) );
978							break;
979						case $this.is_rp( ch ) || ']' === ch :
980							$this.empty_number_buffer_as_literal();
981							$this.empty_str_buffer_as_variable();
982							$this.allow_negative = false;
983							$this.tokens.push( THEMECOMPLETE_EPO_MATH_Token( THEMECOMPLETE_EPO_MATH_Constants.RIGHTPARENTHESIS, ch ) );
984							break;
985						case $this.is_comma( ch ):
986							$this.empty_number_buffer_as_literal();
987							$this.empty_str_buffer_as_variable();
988							$this.allow_negative = true;
989							$this.tokens.push( THEMECOMPLETE_EPO_MATH_Token( THEMECOMPLETE_EPO_MATH_Constants.PARAMSEPARATOR, ch ) );
990							break;
991						default:
992							// special case for unary operations.
993							if ( '-' === ch || '+' === ch ) {
994								if ( $this.allow_negative ) {
995									$this.allow_negative = false;
996									$this.tokens.push( THEMECOMPLETE_EPO_MATH_Token( THEMECOMPLETE_EPO_MATH_Constants.OPERATOR, '-' === ch ? 'uNeg' : 'uPos' ) );
997									break;
998								}
999								// could be in exponent, in which case negative should be added to the number_buffer.
1000								if ( $this.number_buffer && 'e' === $this.number_buffer[ $this.number_buffer.length - 1 ] ) {
1001									$this.number_buffer += ch;
1002									break;
1003								}
1004							}
1005							$this.empty_number_buffer_as_literal();
1006							$this.empty_str_buffer_as_variable();
1007
1008							if ( '$' !== ch ) {
1009								if ( $this.tokens.length > 0 ) {
1010									if ( THEMECOMPLETE_EPO_MATH_Constants.OPERATOR === $this.tokens[ $this.tokens.length - 1 ].type ) {
1011										$this.tokens[ $this.tokens.length - 1 ].value += ch;
1012									} else {
1013										$this.tokens.push( THEMECOMPLETE_EPO_MATH_Token( THEMECOMPLETE_EPO_MATH_Constants.OPERATOR, ch ) );
1014									}
1015								} else {
1016									$this.tokens.push( THEMECOMPLETE_EPO_MATH_Token( THEMECOMPLETE_EPO_MATH_Constants.OPERATOR, ch ) );
1017								}
1018							}
1019							$this.allow_negative = true;
1020					}
1021				} );
1022				this.empty_number_buffer_as_literal();
1023				this.empty_str_buffer_as_variable();
1024
1025				this.tokens.forEach( function( $token, $key ) {
1026					$token_test[ $key ] = $token.type;
1027				} );
1028				$token_test.forEach( function( $type, $key ) {
1029					if ( $key > 0 && 'space' === $type && 'variable' === $token_test[ $key + 1 ] && 'variable' === $token_test[ $key - 1 ] ) {
1030						$this.tokens[ $key ] = new THEMECOMPLETE_EPO_MATH_Token( THEMECOMPLETE_EPO_MATH_Constants.LITERAL, 0 );
1031						$this.tokens.splice( $key + 1, 1 );
1032						$this.tokens.splice( $key - 1, 1 );
1033					}
1034				} );
1035				return this;
1036			},
1037			build_reverse_polish_notation: function() {
1038				var $tokens = [];
1039				var $stack = [];
1040				var $param_counter = [];
1041				var $ctoken;
1042				var $f;
1043				var $op1;
1044				var $op2;
1045				var $this = this;
1046
1047				try {
1048					this.tokens.forEach( function( $token ) {
1049						switch ( $token.type ) {
1050							case THEMECOMPLETE_EPO_MATH_Constants.LITERAL:
1051							case THEMECOMPLETE_EPO_MATH_Constants.VARIABLE:
1052							case THEMECOMPLETE_EPO_MATH_Constants.STRING:
1053								$tokens.push( $token );
1054
1055								if ( $param_counter.length > 0 && 0 === $param_counter[ $param_counter.length - 1 ] ) {
1056									$param_counter.push( $param_counter.pop() + 1 );
1057								}
1058
1059								break;
1060
1061							case THEMECOMPLETE_EPO_MATH_Constants.FUNCTION:
1062								if ( $param_counter.length > 0 && 0 === $param_counter[ $param_counter.length - 1 ] ) {
1063									$param_counter.push( $param_counter.pop() + 1 );
1064								}
1065								$stack.push( $token );
1066								$param_counter.push( 0 );
1067
1068								break;
1069
1070							case THEMECOMPLETE_EPO_MATH_Constants.LEFTPARENTHESIS:
1071								$stack.push( $token );
1072
1073								break;
1074
1075							case THEMECOMPLETE_EPO_MATH_Constants.PARAMSEPARATOR:
1076								while ( THEMECOMPLETE_EPO_MATH_Constants.LEFTPARENTHESIS !== $stack[ $stack.length - 1 ].type ) {
1077									if ( 0 === $stack.length ) {
1078										return THEMECOMPLETE_EPO_MATH_Error.trigger( 'Incorrect Brackets', 'IncorrectBracketsError', $tokens );
1079									}
1080									$tokens.push( $stack.pop() );
1081								}
1082								$param_counter.push( $param_counter.pop() + 1 );
1083
1084								break;
1085
1086							case THEMECOMPLETE_EPO_MATH_Constants.OPERATOR:
1087								if ( ! array_key_exists( $token.value, $this.operators ) ) {
1088									return THEMECOMPLETE_EPO_MATH_Error.trigger( $token.value, 'UnknownOperatorError', $tokens );
1089								}
1090								$op1 = $this.operators[ $token.value ];
1091
1092								while ( $stack.length > 0 && THEMECOMPLETE_EPO_MATH_Constants.OPERATOR === $stack[ $stack.length - 1 ].type ) {
1093									if ( ! array_key_exists( $stack[ $stack.length - 1 ].value, $this.operators ) ) {
1094										return THEMECOMPLETE_EPO_MATH_Error.trigger( $stack[ $stack.length - 1 ].value, 'UnknownOperatorError', $tokens );
1095									}
1096									$op2 = $this.operators[ $stack[ $stack.length - 1 ].value ];
1097
1098									if ( $op2.priority >= $op1.priority ) {
1099										$tokens.push( $stack.pop() );
1100
1101										continue;
1102									}
1103
1104									break;
1105								}
1106								$stack.push( $token );
1107
1108								break;
1109
1110							case THEMECOMPLETE_EPO_MATH_Constants.RIGHTPARENTHESIS:
1111								while ( true ) {
1112									try {
1113										$ctoken = $stack.pop();
1114
1115										if ( THEMECOMPLETE_EPO_MATH_Constants.LEFTPARENTHESIS === $ctoken.type ) {
1116											break;
1117										}
1118										$tokens.push( $ctoken );
1119									} catch ( $e ) {
1120										return THEMECOMPLETE_EPO_MATH_Error.trigger( 'Incorrect Brackets', 'IncorrectBracketsError', $tokens );
1121									}
1122								}
1123
1124								if ( $stack.length > 0 && THEMECOMPLETE_EPO_MATH_Constants.FUNCTION === $stack[ $stack.length - 1 ].type ) {
1125									$f = $stack.pop();
1126									$f.param_count = $param_counter.pop();
1127									$tokens.push( $f );
1128								}
1129
1130								break;
1131
1132							case THEMECOMPLETE_EPO_MATH_Constants.SPACE:
1133								// do nothing.
1134						}
1135					} );
1136				} catch ( $e ) {
1137					$tokens = [];
1138					return THEMECOMPLETE_EPO_MATH_Error.trigger( $e, 'Error', $tokens );
1139				}
1140
1141				while ( 0 !== $stack.length ) {
1142					if ( THEMECOMPLETE_EPO_MATH_Constants.LEFTPARENTHESIS === $stack[ $stack.length - 1 ].type || THEMECOMPLETE_EPO_MATH_Constants.RIGHTPARENTHESIS === $stack[ $stack.length - 1 ].type ) {
1143						return THEMECOMPLETE_EPO_MATH_Error.trigger( 'Incorrect Brackets', 'IncorrectBracketsError', $tokens );
1144					}
1145
1146					if ( THEMECOMPLETE_EPO_MATH_Constants.SPACE === $stack[ $stack.length - 1 ].type ) {
1147						$stack.pop();
1148						continue;
1149					}
1150					$tokens.push( $stack.pop() );
1151				}
1152
1153				return $tokens;
1154			}
1155		};
1156		node.input = $input;
1157		node.operators = $operators;
1158		return node;
1159	};
1160
1161	var THEMECOMPLETE_EPO_MATH_Constants = {
1162		LITERAL: 'literal',
1163		VARIABLE: 'variable',
1164		OPERATOR: 'operator',
1165		LEFTPARENTHESIS: 'LP',
1166		RIGHTPARENTHESIS: 'RP',
1167		FUNCTION: 'function',
1168		PARAMSEPARATOR: 'separator',
1169		STRING: 'string',
1170		SPACE: 'space'
1171
1172	};
1173
1174	var THEMECOMPLETE_EPO_MATH_Token = function( $type, $value, $name ) {
1175		var node = {
1176			type: THEMECOMPLETE_EPO_MATH_Constants.LITERAL,
1177			value: undefined,
1178			name: undefined,
1179			param_count: null
1180		};
1181		node.type = $type;
1182		node.value = $value;
1183		node.name = $name;
1184		return node;
1185	};
1186
1187	var THEMECOMPLETE_EPO_MATH_Operator = function( $operator, $is_right_assoc, $priority, $function ) {
1188		var node = {
1189			operator: '',
1190			is_right_assoc: false,
1191			priority: 0,
1192			function: null,
1193			places: 0
1194		};
1195		node.operator = $operator;
1196		node.is_right_assoc = $is_right_assoc;
1197		node.priority = $priority;
1198		node.function = $function;
1199		node.places = getNumberOfParameters( $function );
1200
1201		node.execute = function( $stack ) {
1202			var $args = [];
1203			var $i;
1204			var $result;
1205
1206			if ( $stack.length < this.places ) {
1207				// Empty the $stack
1208				$stack.splice( 0, $stack.length );
1209				return THEMECOMPLETE_EPO_MATH_Error.trigger( 'Incorrect Expression', 'IncorrectExpressionError', new THEMECOMPLETE_EPO_MATH_Token( THEMECOMPLETE_EPO_MATH_Constants.LITERAL, 0 ) );
1210			}
1211
1212			for ( $i = 0; $i < this.places; $i++ ) {
1213				$args.unshift( $stack.pop().value );
1214			}
1215
1216			$result = this.function.apply( null, $args );
1217			if ( 'number' !== gettype( $result ) && 'string' !== gettype( $result ) ) {
1218				$result = 0;
1219			}
1220
1221			return new THEMECOMPLETE_EPO_MATH_Token( THEMECOMPLETE_EPO_MATH_Constants.LITERAL, $result );
1222		};
1223
1224		return node;
1225	};
1226
1227	var THEMECOMPLETE_EPO_MATH_CustomFunction = function( $name, $function ) {
1228		var node = {
1229			name: '',
1230			function: undefined,
1231			required_param_count: undefined
1232		};
1233
1234		node.name = $name;
1235		node.function = $function;
1236		node.required_param_count = getNumberOfRequiredParameters( $function );
1237
1238		node.execute = function( $stack, $param_count_in_stack ) {
1239			var $args = [];
1240			var $i;
1241			var $argument;
1242			var $result;
1243			if ( $param_count_in_stack < this.required_param_count ) {
1244				$param_count_in_stack = this.required_param_count;
1245			}
1246			// We skip this section.
1247			if ( $param_count_in_stack < this.required_param_count ) {
1248				// Empty the $stack
1249				$stack.splice( 0, $stack.length );
1250				return THEMECOMPLETE_EPO_MATH_Error.trigger( this.name, 'IncorrectNumberOfFunctionParametersError', new THEMECOMPLETE_EPO_MATH_Token( THEMECOMPLETE_EPO_MATH_Constants.LITERAL, 0 ) );
1251			}
1252
1253			if ( $param_count_in_stack > 0 ) {
1254				for ( $i = 0; $i < $param_count_in_stack; $i++ ) {
1255					$argument = $stack.length ? $stack.pop().value : 0;
1256					if ( null === $argument ) {
1257						$argument = '0';
1258						$args.push( $argument );
1259					} else {
1260						$args.unshift( $argument );
1261					}
1262				}
1263			}
1264
1265			$result = this.function.apply( null, $args );
1266
1267			if ( $result === Infinity || $result === -Infinity ) {
1268				$result = 0;
1269			}
1270
1271			return THEMECOMPLETE_EPO_MATH_Token( THEMECOMPLETE_EPO_MATH_Constants.LITERAL, $result );
1272		};
1273
1274		return node;
1275	};
1276
1277	var THEMECOMPLETE_EPO_MATH_Calculator = function( $functions, $operators ) {
1278		var node = {
1279			functions: {},
1280			operators: {}
1281		};
1282		node.functions = $functions;
1283		node.operators = $operators;
1284
1285		node.calculate = function( $tokens, $variables, $on_var_not_found = null, $math_object = false ) {
1286			var $this = this;
1287			/** Array of THEMECOMPLETE_EPO_MATH_Token */
1288			var $stack = [];
1289			var $result;
1290
1291			if ( empty( $tokens ) ) {
1292				return 0;
1293			}
1294			try {
1295				$tokens.forEach( function( $token ) {
1296					var $variable;
1297					var $value;
1298					if ( THEMECOMPLETE_EPO_MATH_Constants.LITERAL === $token.type || THEMECOMPLETE_EPO_MATH_Constants.STRING === $token.type ) {
1299						$stack.push( $token );
1300					} else if ( THEMECOMPLETE_EPO_MATH_Constants.VARIABLE === $token.type ) {
1301						$variable = $token.value;
1302
1303						$value = null;
1304
1305						if ( array_key_exists( $variable, $variables ) ) {
1306							$value = $variables[ $variable ];
1307						} else if ( $on_var_not_found && 'function' === typeof $on_var_not_found ) {
1308							$value = $on_var_not_found( $variable );
1309						} else {
1310							$value = $variable;
1311							$math_object.variables[ $variable ] = $value;
1312							$variables[ $variable ] = $value;
1313						}
1314						$stack.push( THEMECOMPLETE_EPO_MATH_Token( THEMECOMPLETE_EPO_MATH_Constants.LITERAL, $value, $variable ) );
1315					} else if ( THEMECOMPLETE_EPO_MATH_Constants.FUNCTION === $token.type ) {
1316						if ( ! array_key_exists( $token.value, $this.functions ) ) {
1317							$math_object.add_function(
1318								$token.value,
1319								function() {
1320									return 0;
1321								}
1322							);
1323							$this.functions = $math_object.functions;
1324							if ( ! array_key_exists( $token.value, $this.functions ) ) {
1325								return THEMECOMPLETE_EPO_MATH_Error.trigger( $token.value, 'UnknownFunctionError', 0 );
1326							}
1327							THEMECOMPLETE_EPO_MATH_Error.trigger( $token.value, 'UnknownFunctionError', 0 );
1328						}
1329						$stack.push( $this.functions[ $token.value ].execute( $stack, $token.param_count ) );
1330					} else if ( THEMECOMPLETE_EPO_MATH_Constants.OPERATOR === $token.type ) {
1331						if ( ! array_key_exists( $token.value, $this.operators ) ) {
1332							return THEMECOMPLETE_EPO_MATH_Error.trigger( $token.value, 'UnknownOperatorError', 0 );
1333						}
1334						$stack.push( $this.operators[ $token.value ].execute( $stack ) );
1335					}
1336				} );
1337			} catch ( $e ) {
1338				if ( window.TMEPOJS && window.TMEPOJS.WP_DEBUG ) {
1339					window.console.log( $e );
1340				}
1341			}
1342			$result = $stack.pop();
1343
1344			if ( null === $result || ! empty( $stack ) ) {
1345				return THEMECOMPLETE_EPO_MATH_Error.trigger( 'Stack must be empty', 'IncorrectExpressionError', 0 );
1346			}
1347
1348			if ( false === $result.value ) {
1349				$result.value = 0;
1350			}
1351
1352			if ( true === $result.value ) {
1353				$result.value = 1;
1354			}
1355
1356			if ( 'string' === gettype( $result.value ) && $result.value.isNumeric() ) {
1357				$result.value = floatval( $result.value );
1358			}
1359
1360			return $result.value;
1361		};
1362		return node;
1363	};
1364
1365	var THEMECOMPLETE_EPO_MATH_Error = {
1366		trigger: function( $msg, $code = '', $return = false ) {
1367			if ( window.TMEPOJS && window.TMEPOJS.WP_DEBUG ) {
1368				window.console.log( $code + '\n' + $msg );
1369				window.console.trace();
1370			}
1371			if ( window.TMEPOGLOBALADMINJS && window.TMEPOGLOBALADMINJS.WP_DEBUG ) {
1372				return $msg;
1373			}
1374			return $return;
1375		}
1376	};
1377
1378	window.tcmexp = THEMECOMPLETE_EPO_MATH.construct();
1379}( window ) );

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.