/** ** ============================== ** O O O OOOO ** O O O O O O ** O O O O O O ** OOOO OOOO O OOO OOOO ** O O O O O O O ** O O O O O O O ** OOOO OOOO O O OOOO ** ============================== ** Dr. Stefan Bosse http://www.bsslab.de ** ** COPYRIGHT: THIS SOFTWARE, EXECUTABLE AND SOURCE CODE IS OWNED ** BY THE AUTHOR(S). ** THIS SOURCE CODE MAY NOT BE COPIED, EXTRACTED, ** MODIFIED, OR OTHERWISE USED IN A CONTEXT ** OUTSIDE OF THE SOFTWARE SYSTEM. ** ** $AUTHORS: Stefan Bosse, Douglas Crockford (jsmin, C, 2002) ** $INITIAL: (C) 2006-2020 bLAB ** $CREATED: 09-06-20 by sbosse. ** $RCS: $Id: minify.js,v 1.4 2020/02/03 09:45:01 sbosse Exp sbosse $ ** $VERSION: 1.1.1 ** ** $INFO: ** ** Fast JavaScript Code Minifier (C-to-JS port) ** ** $ENDOFINFO */ var EOF = null; var theA; var theB; var theLookahead = EOF; var theX = EOF; var theY = EOF; var theInbuf = null; var theOutbuf = null; var theInbufIndex = 0; var theOutbufIndex = 0; /* isAlphanum -- return true if the character is a letter, digit, underscore, dollar sign, or non-ASCII character. */ function isAlphanum(c) { return ((c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z') || c == '_' || c == '$' || c == '\\' || c > String.fromCharCode(126)); } function get() { var c = theLookahead; theLookahead = EOF; if (c == EOF) { c = theInbuf[theInbufIndex++]; } if (c >= ' ' || c == '\n' || c == EOF) { return c; } if (c == '\r') { return '\n'; } return ' '; } function put(c) { theOutbuf += c; } function peek() { theLookahead = get(); return theLookahead; } function error(msg) { throw msg } function next() { var c = get(); if (c == '/') { switch (peek()) { case '/': for (;;) { c = get(); if (c <= '\n') { break; } } break; case '*': get(); while (c != ' ') { switch (get()) { case '*': if (peek() == '/') { get(); c = ' '; } break; case EOF: error("Unterminated comment."); } } break; } } theY = theX; theX = c; return c; } /* action -- do something! What you do is determined by the argument: 1 Output A. Copy B to A. Get the next B. 2 Copy B to A. Get the next B. (Delete A). 3 Get the next B. (Delete B). action treats a string as a single character. Wow! action recognizes a regular expression if it is preceded by ( or , or =. */ function action(d) { switch (d) { case 1: put(theA); if ( (theY == '\n' || theY == ' ') && (theA == '+' || theA == '-' || theA == '*' || theA == '/') && (theB == '+' || theB == '-' || theB == '*' || theB == '/') ) { put(theY); } case 2: theA = theB; if (theA == '\'' || theA == '"' || theA == '`') { for (;;) { put(theA); theA = get(); if (theA == theB) { break; } if (theA == '\\') { put(theA); theA = get(); } if (theA == EOF) { error("Unterminated string literal."); } } } case 3: theB = next(); if (theB == '/' && ( theA == '(' || theA == ',' || theA == '=' || theA == ':' || theA == '[' || theA == '!' || theA == '&' || theA == '|' || theA == '?' || theA == '+' || theA == '-' || theA == '~' || theA == '*' || theA == '/' || theA == '{' || theA == '\n' )) { put(theA); if (theA == '/' || theA == '*') { put(' '); } put(theB); for (;;) { theA = get(); if (theA == '[') { for (;;) { put(theA); theA = get(); if (theA == ']') { break; } if (theA == '\\') { put(theA); theA = get(); } if (theA == EOF) { error("Unterminated set in Regular Expression literal."); } } } else if (theA == '/') { switch (peek()) { case '/': case '*': error("Unterminated set in Regular Expression literal."); break; case '\n': put(theA); theA='\n'; /* Newline required after end of regex */ } break; } else if (theA =='\\') { put(theA); theA = get(); } if (theA == EOF) { error("Unterminated Regular Expression literal."); } put(theA); } theB = next(); } } } function minify(text) { theA=0; theB=0; theLookahead = EOF; theX = EOF; theY = EOF; theInbuf=text; theInbufIndex=0; theOutbuf=''; if (peek() == 0xEF) { get(); get(); get(); } theA = get(); action(3); while (theA != EOF) { switch (theA) { case ' ': action(isAlphanum(theB) ? 1 : 2); break; case '\n': switch (theB) { case '{': case '[': case '(': case '+': case '-': case '!': case '~': action(1); break; case ' ': action(3); break; default: action(isAlphanum(theB) ? 1 : 2); } break; default: switch (theB) { case ' ': action(isAlphanum(theA) ? 1 : 3); break; case '\n': switch (theA) { case '}': case ']': case ')': case '+': case '-': case '"': case '\'': case '`': action(1); break; default: action(isAlphanum(theA) ? 1 : 3); } break; default: action(1); break; } } } return theOutbuf; } // old faulty regex minimizer from Code module!! function minimize0 (code) { // Inline and multi-line comments var regex4= /\/\*([\S\s]*?)\*\//g; var regex5= /([^\\}])\\n/g; var regex6= /\/\/[^\n]+/g; // Newline after {},; var regex7= /[ ]*([{},; ]|else)[ ]*\n[\n]*/g; // Filter for string quotes var regex8= /([^\'"]+)|([\'"](?:[^\'"\\]|\\.)+[\'"])/g; // Multi-spaces reduction var regex9= / [ ]+/g; // relax } syntax errors after newline removal; exclude keywords! var regex10= /}\s+(?!else|finally|catch)([a-zA-Z_]+)/g; // relax ) syntax errors after newline removal var regex11= /\)\s+([a-zA-Z_]+)/g; code=code.replace(regex4,"") .replace(regex5,'$1\n') .replace(regex5,'$1\n') .replace(regex6,"") .replace(regex7,"$1") .replace(regex8, function($0, $1, $2) { if ($1) { return $1.replace(regex9,' ').replace(regex10,'};$1').replace(regex11,')\n$1'); } else { return $2; } }); return code; } // compare regex minimizer versa character state machine function test() { var n=1E4; var text=minify.toString(); var t0=Date.now() for(var i=0;i