2016-03-07 13:47:23 +01:00
( function ( exports , global ) { "use strict" ; function array _to _hash ( a ) { var ret = Object . create ( null ) ; for ( var i = 0 ; i < a . length ; ++ i ) ret [ a [ i ] ] = true ; return ret } function slice ( a , start ) { return Array . prototype . slice . call ( a , start || 0 ) } function characters ( str ) { return str . split ( "" ) } function member ( name , array ) { for ( var i = array . length ; -- i >= 0 ; ) if ( array [ i ] == name ) return true ; return false } function find _if ( func , array ) { for ( var i = 0 , n = array . length ; i < n ; ++ i ) { if ( func ( array [ i ] ) ) return array [ i ] } } function repeat _string ( str , i ) { if ( i <= 0 ) return "" ; if ( i == 1 ) return str ; var d = repeat _string ( str , i >> 1 ) ; d += d ; if ( i & 1 ) d += str ; return d } function DefaultsError ( msg , defs ) { Error . call ( this , msg ) ; this . msg = msg ; this . defs = defs } DefaultsError . prototype = Object . create ( Error . prototype ) ; DefaultsError . prototype . constructor = DefaultsError ; DefaultsError . croak = function ( msg , defs ) { throw new DefaultsError ( msg , defs ) } ; function defaults ( args , defs , croak ) { if ( args === true ) args = { } ; var ret = args || { } ; if ( croak ) for ( var i in ret ) if ( ret . hasOwnProperty ( i ) && ! defs . hasOwnProperty ( i ) ) DefaultsError . croak ( "`" + i + "` is not a supported option" , defs ) ; for ( var i in defs ) if ( defs . hasOwnProperty ( i ) ) { ret [ i ] = args && args . hasOwnProperty ( i ) ? args [ i ] : defs [ i ] } return ret } function merge ( obj , ext ) { var count = 0 ; for ( var i in ext ) if ( ext . hasOwnProperty ( i ) ) { obj [ i ] = ext [ i ] ; count ++ } return count } function noop ( ) { } var MAP = function ( ) { function MAP ( a , f , backwards ) { var ret = [ ] , top = [ ] , i ; function doit ( ) { var val = f ( a [ i ] , i ) ; var is _last = val instanceof Last ; if ( is _last ) val = val . v ; if ( val instanceof AtTop ) { val = val . v ; if ( val instanceof Splice ) { top . push . apply ( top , backwards ? val . v . slice ( ) . reverse ( ) : val . v ) } else { top . push ( val ) } } else if ( val !== skip ) { if ( val instanceof Splice ) { ret . push . apply ( ret , backwards ? val . v . slice ( ) . reverse ( ) : val . v ) } else { ret . push ( val ) } } return is _last } if ( a instanceof Array ) { if ( backwards ) { for ( i = a . length ; -- i >= 0 ; ) if ( doit ( ) ) break ; ret . reverse ( ) ; top . reverse ( ) } else { for ( i = 0 ; i < a . length ; ++ i ) if ( doit ( ) ) break } } else { for ( i in a ) if ( a . hasOwnProperty ( i ) ) if ( doit ( ) ) break } return top . concat ( ret ) } MAP . at _top = function ( val ) { return new AtTop ( val ) } ; MAP . splice = function ( val ) { return new Splice ( val ) } ; MAP . last = function ( val ) { return new Last ( val ) } ; var skip = MAP . skip = { } ; function AtTop ( val ) { this . v = val } function Splice ( val ) { this . v = val } function Last ( val ) { this . v = val } return MAP } ( ) ; function push _uniq ( array , el ) { if ( array . indexOf ( el ) < 0 ) array . push ( el ) } function string _template ( text , props ) { return text . replace ( /\{(.+?)\}/g , function ( str , p ) { return props [ p ] } ) } function remove ( array , el ) { for ( var i = array . length ; -- i >= 0 ; ) { if ( array [ i ] === el ) array . splice ( i , 1 ) } } function mergeSort ( array , cmp ) { if ( array . length < 2 ) return array . slice ( ) ; function merge ( a , b ) { var r = [ ] , ai = 0 , bi = 0 , i = 0 ; while ( ai < a . length && bi < b . length ) { cmp ( a [ ai ] , b [ bi ] ) <= 0 ? r [ i ++ ] = a [ ai ++ ] : r [ i ++ ] = b [ bi ++ ] } if ( ai < a . length ) r . push . apply ( r , a . slice ( ai ) ) ; if ( bi < b . length ) r . push . apply ( r , b . slice ( bi ) ) ; return r } function _ms ( a ) { if ( a . length <= 1 ) return a ; var m = Math . floor ( a . length / 2 ) , left = a . slice ( 0 , m ) , right = a . slice ( m ) ; left = _ms ( left ) ; right = _ms ( right ) ; return merge ( left , right ) } return _ms ( array ) } function set _difference ( a , b ) { return a . filter ( function ( el ) { return b . indexOf ( el ) < 0 } ) } function set _intersection ( a , b ) { return a . filter ( function ( el ) { return b . indexOf ( el ) >= 0 } ) } function makePredicate ( words ) { if ( ! ( words instanceof Array ) ) words = words . split ( " " ) ; var f = "" , cats = [ ] ; out : for ( var i = 0 ; i < words . length ; ++ i ) { for ( var j = 0 ; j < cats . length ; ++ j ) if ( cats [ j ] [ 0 ] . length == words [ i ] . length ) { cats [ j ] . push ( words [ i ] ) ; continue out } cats . push ( [ words [ i ] ] ) } function compareTo ( arr ) { if ( arr . length == 1 ) return f += "return str === " + JSON . stringify ( arr [ 0 ] ) + ";" ; f += "switch(str){" ; for ( var i = 0 ; i < arr . length ; ++ i ) f += "case " + JSON . stringify ( arr [ i ] ) + ":" ; f += "return true}return false;" } if ( cats . length > 3 ) { cats . sort ( function ( a , b ) { return b . length - a . length } ) ; f += "switch(str.length){" ; for ( var i = 0 ; i < cats . length ; ++ i ) { var cat = cats [ i ] ; f += "case " + cat [ 0 ] . length + ":" ; compareTo ( cat ) } f += "}" } else { compareTo ( words ) } return new Function ( "str" , f ) } function all ( array , predicate ) { for ( var i = array . length ; -- i >= 0 ; ) if ( ! predicate ( array [ i ] ) ) return false ; return true } function Dictionary ( ) { this . _values = Object . create ( null ) ; this . _size = 0 } Dictionary . prototype = { set : function ( key , val ) { if ( ! this . has ( key ) ) ++
digit : new RegExp ( "[\\u0030-\\u0039\\u0660-\\u0669\\u06F0-\\u06F9\\u07C0-\\u07C9\\u0966-\\u096F\\u09E6-\\u09EF\\u0A66-\\u0A6F\\u0AE6-\\u0AEF\\u0B66-\\u0B6F\\u0BE6-\\u0BEF\\u0C66-\\u0C6F\\u0CE6-\\u0CEF\\u0D66-\\u0D6F\\u0DE6-\\u0DEF\\u0E50-\\u0E59\\u0ED0-\\u0ED9\\u0F20-\\u0F29\\u1040-\\u1049\\u1090-\\u1099\\u17E0-\\u17E9\\u1810-\\u1819\\u1946-\\u194F\\u19D0-\\u19D9\\u1A80-\\u1A89\\u1A90-\\u1A99\\u1B50-\\u1B59\\u1BB0-\\u1BB9\\u1C40-\\u1C49\\u1C50-\\u1C59\\uA620-\\uA629\\uA8D0-\\uA8D9\\uA900-\\uA909\\uA9D0-\\uA9D9\\uA9F0-\\uA9F9\\uAA50-\\uAA59\\uABF0-\\uABF9\\uFF10-\\uFF19]" ) , non _spacing _mark : new RegExp ( "[\\u0300-\\u036F\\u0483-\\u0487\\u0591-\\u05BD\\u05BF\\u05C1\\u05C2\\u05C4\\u05C5\\u05C7\\u0610-\\u061A\\u064B-\\u065E\\u0670\\u06D6-\\u06DC\\u06DF-\\u06E4\\u06E7\\u06E8\\u06EA-\\u06ED\\u0711\\u0730-\\u074A\\u07A6-\\u07B0\\u07EB-\\u07F3\\u0816-\\u0819\\u081B-\\u0823\\u0825-\\u0827\\u0829-\\u082D\\u0900-\\u0902\\u093C\\u0941-\\u0948\\u094D\\u0951-\\u0955\\u0962\\u0963\\u0981\\u09BC\\u09C1-\\u09C4\\u09CD\\u09E2\\u09E3\\u0A01\\u0A02\\u0A3C\\u0A41\\u0A42\\u0A47\\u0A48\\u0A4B-\\u0A4D\\u0A51\\u0A70\\u0A71\\u0A75\\u0A81\\u0A82\\u0ABC\\u0AC1-\\u0AC5\\u0AC7\\u0AC8\\u0ACD\\u0AE2\\u0AE3\\u0B01\\u0B3C\\u0B3F\\u0B41-\\u0B44\\u0B4D\\u0B56\\u0B62\\u0B63\\u0B82\\u0BC0\\u0BCD\\u0C3E-\\u0C40\\u0C46-\\u0C48\\u0C4A-\\u0C4D\\u0C55\\u0C56\\u0C62\\u0C63\\u0CBC\\u0CBF\\u0CC6\\u0CCC\\u0CCD\\u0CE2\\u0CE3\\u0D41-\\u0D44\\u0D4D\\u0D62\\u0D63\\u0DCA\\u0DD2-\\u0DD4\\u0DD6\\u0E31\\u0E34-\\u0E3A\\u0E47-\\u0E4E\\u0EB1\\u0EB4-\\u0EB9\\u0EBB\\u0EBC\\u0EC8-\\u0ECD\\u0F18\\u0F19\\u0F35\\u0F37\\u0F39\\u0F71-\\u0F7E\\u0F80-\\u0F84\\u0F86\\u0F87\\u0F90-\\u0F97\\u0F99-\\u0FBC\\u0FC6\\u102D-\\u1030\\u1032-\\u1037\\u1039\\u103A\\u103D\\u103E\\u1058\\u1059\\u105E-\\u1060\\u1071-\\u1074\\u1082\\u1085\\u1086\\u108D\\u109D\\u135F\\u1712-\\u1714\\u1732-\\u1734\\u1752\\u1753\\u1772\\u1773\\u17B7-\\u17BD\\u17C6\\u17C9-\\u17D3\\u17DD\\u180B-\\u180D\\u18A9\\u1920-\\u1922\\u1927\\u1928\\u1932\\u1939-\\u193B\\u1A17\\u1A18\\u1A56\\u1A58-\\u1A5E\\u1A60\\u1A62\\u1A65-\\u1A6C\\u1A73-\\u1A7C\\u1A7F\\u1B00-\\u1B03\\u1B34\\u1B36-\\u1B3A\\u1B3C\\u1B42\\u1B6B-\\u1B73\\u1B80\\u1B81\\u1BA2-\\u1BA5\\u1BA8\\u1BA9\\u1C2C-\\u1C33\\u1C36\\u1C37\\u1CD0-\\u1CD2\\u1CD4-\\u1CE0\\u1CE2-\\u1CE8\\u1CED\\u1DC0-\\u1DE6\\u1DFD-\\u1DFF\\u20D0-\\u20DC\\u20E1\\u20E5-\\u20F0\\u2CEF-\\u2CF1\\u2DE0-\\u2DFF\\u302A-\\u302F\\u3099\\u309A\\uA66F\\uA67C\\uA67D\\uA6F0\\uA6F1\\uA802\\uA806\\uA80B\\uA825\\uA826\\uA8C4\\uA8E0-\\uA8F1\\uA926-\\uA92D\\uA947-\\uA951\\uA980-\\uA982\\uA9B3\\uA9B6-\\uA9B9\\uA9BC\\uAA29-\\uAA2E\\uAA31\\uAA32\\uAA35\\uAA36\\uAA43\\uAA4C\\uAAB0\\uAAB2-\\uAAB4\\uAAB7\\uAAB8\\uAABE\\uAABF\\uAAC1\\uABE5\\uABE8\\uABED\\uFB1E\\uFE00-\\uFE0F\\uFE20-\\uFE26]" ) , space _combining _mark : new RegExp ( "[\\u0903\\u093E-\\u0940\\u0949-\\u094C\\u094E\\u0982\\u0983\\u09BE-\\u09C0\\u09C7\\u09C8\\u09CB\\u09CC\\u09D7\\u0A03\\u0A3E-\\u0A40\\u0A83\\u0ABE-\\u0AC0\\u0AC9\\u0ACB\\u0ACC\\u0B02\\u0B03\\u0B3E\\u0B40\\u0B47\\u0B48\\u0B4B\\u0B4C\\u0B57\\u0BBE\\u0BBF\\u0BC1\\u0BC2\\u0BC6-\\u0BC8\\u0BCA-\\u0BCC\\u0BD7\\u0C01-\\u0C03\\u0C41-\\u0C44\\u0C82\\u0C83\\u0CBE\\u0CC0-\\u0CC4\\u0CC7\\u0CC8\\u0CCA\\u0CCB\\u0CD5\\u0CD6\\u0D02\\u0D03\\u0D3E-\\u0D40\\u0D46-\\u0D48\\u0D4A-\\u0D4C\\u0D57\\u0D82\\u0D83\\u0DCF-\\u0DD1\\u0DD8-\\u0DDF\\u0DF2\\u0DF3\\u0F3E\\u0F3F\\u0F7F\\u102B\\u102C\\u1031\\u1038\\u103B\\u103C\\u1056\\u1057\\u1062-\\u1064\\u1067-\\u106D\\u1083\\u1084\\u1087-\\u108C\\u108F\\u109A-\\u109C\\u17B6\\u17BE-\\u17C5\\u17C7\\u17C8\\u1923-\\u1926\\u1929-\\u192B\\u1930\\u1931\\u1933-\\u1938\\u19B0-\\u19C0\\u19C8\\u19C9\\u1A19-\\u1A1B\\u1A55\\u1A57\\u1A61\\u1A63\\u1A64\\u1A6D-\\u1A72\\u1B04\\u1B35\\u1B3B\\u1B3D-\\u1B41\\u1B43\\u1B44\\u1B82\\u1BA1\\u1BA6\\u1BA7\\u1BAA\\u1C24-\\u1C2B\\u1C34\\u1C35\\u1CE1\\u1CF2\\uA823\\uA824\\uA827\\uA880\\uA881\\uA8B4-\\uA8C3\\uA952\\uA953\\uA983\\uA9B4\\uA9B5\\uA9BA\\uA9BB\\uA9BD-\\uA9C0\\uAA2F\\uAA30\\uAA33\\uAA34\\uAA4D\\uAA7B\\uABE3\\uABE4\\uABE6\\uABE7\\uABE9\\uABEA\\uABEC]" ) , connector _punctuation : new RegExp ( "[\\u005F\\u203F\\u2040\\u2054\\uFE33\\uFE34\\uFE4D-\\uFE4F\\uFF3F]" ) } ; function is
} , mangle : function ( options ) { var cache = options . cache && options . cache . props ; if ( this . global && cache && cache . has ( this . name ) ) { this . mangled _name = cache . get ( this . name ) } else if ( ! this . mangled _name && ! this . unmangleable ( options ) ) { var s = this . scope ; if ( ! options . screw _ie8 && this . orig [ 0 ] instanceof AST _SymbolLambda ) s = s . parent _scope ; this . mangled _name = s . next _mangled ( options , this ) ; if ( this . global && cache ) { cache . set ( this . name , this . mangled _name ) } } } } ; AST _Toplevel . DEFMETHOD ( "figure_out_scope" , function ( options ) { options = defaults ( options , { screw _ie8 : false , cache : null } ) ; var self = this ; var scope = self . parent _scope = null ; var labels = new Dictionary ; var defun = null ; var last _var _had _const _pragma = false ; var nesting = 0 ; var tw = new TreeWalker ( function ( node , descend ) { if ( options . screw _ie8 && node instanceof AST _Catch ) { var save _scope = scope ; scope = new AST _Scope ( node ) ; scope . init _scope _vars ( nesting ) ; scope . parent _scope = save _scope ; descend ( ) ; scope = save _scope ; return true } if ( node instanceof AST _Scope ) { node . init _scope _vars ( nesting ) ; var save _scope = node . parent _scope = scope ; var save _defun = defun ; var save _labels = labels ; defun = scope = node ; labels = new Dictionary ; ++ nesting ; descend ( ) ; -- nesting ; scope = save _scope ; defun = save _defun ; labels = save _labels ; return true } if ( node instanceof AST _LabeledStatement ) { var l = node . label ; if ( labels . has ( l . name ) ) { throw new Error ( string _template ( "Label {name} defined twice" , l ) ) } labels . set ( l . name , l ) ; descend ( ) ; labels . del ( l . name ) ; return true } if ( node instanceof AST _With ) { for ( var s = scope ; s ; s = s . parent _scope ) s . uses _with = true ; return } if ( node instanceof AST _Symbol ) { node . scope = scope } if ( node instanceof AST _Label ) { node . thedef = node ; node . references = [ ] } if ( node instanceof AST _SymbolLambda ) { defun . def _function ( node ) } else if ( node instanceof AST _SymbolDefun ) { ( node . scope = defun . parent _scope ) . def _function ( node ) } else if ( node instanceof AST _Var ) { last _var _had _const _pragma = node . has _const _pragma ( ) } else if ( node instanceof AST _SymbolVar || node instanceof AST _SymbolConst ) { var def = defun . def _variable ( node ) ; def . constant = node instanceof AST _SymbolConst || last _var _had _const _pragma ; def . init = tw . parent ( ) . value } else if ( node instanceof AST _SymbolCatch ) { ( options . screw _ie8 ? scope : defun ) . def _variable ( node ) } else if ( node instanceof AST _LabelRef ) { var sym = labels . get ( node . name ) ; if ( ! sym ) throw new Error ( string _template ( "Undefined label {name} [{line},{col}]" , { name : node . name , line : node . start . line , col : node . start . col } ) ) ; node . thedef = sym } } ) ; self . walk ( tw ) ; var func = null ; var globals = self . globals = new Dictionary ; var tw = new TreeWalker ( function ( node , descend ) { if ( node instanceof AST _Lambda ) { var prev _func = func ; func = node ; descend ( ) ; func = prev _func ; return true } if ( node instanceof AST _LoopControl && node . label ) { node . label . thedef . references . push ( node ) ; return true } if ( node instanceof AST _SymbolRef ) { var name = node . name ; if ( name == "eval" && tw . parent ( ) instanceof AST _Call ) { for ( var s = node . scope ; s && ! s . uses _eval ; s = s . parent _scope ) { s . uses _eval = true } } var sym = node . scope . find _variable ( name ) ; if ( ! sym ) { var g ; if ( globals . has ( name ) ) { g = globals . get ( name ) } else { g = new SymbolDef ( self , globals . size ( ) , node ) ; g . undeclared = true ; g . global = true ; globals . set ( name , g ) } node . thedef = g ; if ( func && name == "arguments" ) { func . uses _arguments = true } } else { node . thedef = sym } node . reference ( ) ; return true } } ) ; self . walk ( tw ) ; if ( options . cache ) { this . cname = options . cache . cname } } ) ; AST _Scope . DEFMETHOD ( "init_scope_vars" , function ( nesting ) { this . variables = new Dictionary ; this . functions = new Dictionary ; this . uses _with = false ; this . uses _eval = false ; this . parent _scope = null ; this . enclosed = [ ] ; this . cname = - 1 ; this . nesting = nesting } ) ; AST _Lambda . DEFMETHOD ( "init_scope_vars" , function ( ) { AST _Scope . prototype . init _scope _vars . apply ( this , arguments ) ; this . uses _arguments = false ; var symbol = new AST _VarDef ( { name : "arguments" , start : this . start , end : this . end } ) ; var def = new SymbolDef ( this , this . variables . size ( ) , symbol ) ; this . variables . set ( symbol . name , def ) } ) ; AST _SymbolRef . DEFMETHOD ( "reference" , function ( ) { var def = this . definition ( ) ; def . references . push ( this ) ; var s = this . scope ; while ( s ) { push _uniq ( s . enclosed , def ) ; if ( s === def . scope ) break ; s = s . parent _scope } this . frame = this . scope . nesting - def . scope . nesting } ) ; AST _Scope . DEFMETHOD ( "find_variable" , function ( name ) { if ( name instanceof AST _Symbol ) nam
if ( i ) { output . print ( "," ) ; output . newline ( ) } output . indent ( ) ; prop . print ( output ) } ) ; output . newline ( ) } ) ; else output . print ( "{}" ) } ) ; DEFPRINT ( AST _ObjectKeyVal , function ( self , output ) { var key = self . key ; var quote = self . quote ; if ( output . option ( "quote_keys" ) ) { output . print _string ( key + "" ) } else if ( ( typeof key == "number" || ! output . option ( "beautify" ) && + key + "" == key ) && parseFloat ( key ) >= 0 ) { output . print ( make _num ( key ) ) } else if ( RESERVED _WORDS ( key ) ? output . option ( "screw_ie8" ) : is _identifier _string ( key ) ) { output . print _name ( key ) } else { output . print _string ( key , quote ) } output . colon ( ) ; self . value . print ( output ) } ) ; DEFPRINT ( AST _ObjectSetter , function ( self , output ) { output . print ( "set" ) ; output . space ( ) ; self . key . print ( output ) ; self . value . _do _print ( output , true ) } ) ; DEFPRINT ( AST _ObjectGetter , function ( self , output ) { output . print ( "get" ) ; output . space ( ) ; self . key . print ( output ) ; self . value . _do _print ( output , true ) } ) ; DEFPRINT ( AST _Symbol , function ( self , output ) { var def = self . definition ( ) ; output . print _name ( def ? def . mangled _name || def . name : self . name ) } ) ; DEFPRINT ( AST _Undefined , function ( self , output ) { output . print ( "void 0" ) } ) ; DEFPRINT ( AST _Hole , noop ) ; DEFPRINT ( AST _Infinity , function ( self , output ) { output . print ( "Infinity" ) } ) ; DEFPRINT ( AST _NaN , function ( self , output ) { output . print ( "NaN" ) } ) ; DEFPRINT ( AST _This , function ( self , output ) { output . print ( "this" ) } ) ; DEFPRINT ( AST _Constant , function ( self , output ) { output . print ( self . getValue ( ) ) } ) ; DEFPRINT ( AST _String , function ( self , output ) { output . print _string ( self . getValue ( ) , self . quote ) } ) ; DEFPRINT ( AST _Number , function ( self , output ) { if ( use _asm && self . start . raw != null ) { output . print ( self . start . raw ) } else { output . print ( make _num ( self . getValue ( ) ) ) } } ) ; function regexp _safe _literal ( code ) { return [ 92 , 47 , 46 , 43 , 42 , 63 , 40 , 41 , 91 , 93 , 123 , 125 , 36 , 94 , 58 , 124 , 33 , 10 , 13 , 0 , 65279 , 8232 , 8233 ] . indexOf ( code ) < 0 } DEFPRINT ( AST _RegExp , function ( self , output ) { var str = self . getValue ( ) . toString ( ) ; if ( output . option ( "ascii_only" ) ) { str = output . to _ascii ( str ) } else if ( output . option ( "unescape_regexps" ) ) { str = str . split ( "\\\\" ) . map ( function ( str ) { return str . replace ( /\\u[0-9a-fA-F]{4}|\\x[0-9a-fA-F]{2}/g , function ( s ) { var code = parseInt ( s . substr ( 2 ) , 16 ) ; return regexp _safe _literal ( code ) ? String . fromCharCode ( code ) : s } ) } ) . join ( "\\\\" ) } output . print ( str ) ; var p = output . parent ( ) ; if ( p instanceof AST _Binary && /^in/ . test ( p . operator ) && p . left === self ) output . print ( " " ) } ) ; function force _statement ( stat , output ) { if ( output . option ( "bracketize" ) ) { if ( ! stat || stat instanceof AST _EmptyStatement ) output . print ( "{}" ) ; else if ( stat instanceof AST _BlockStatement ) stat . print ( output ) ; else output . with _block ( function ( ) { output . indent ( ) ; stat . print ( output ) ; output . newline ( ) } ) } else { if ( ! stat || stat instanceof AST _EmptyStatement ) output . force _semicolon ( ) ; else stat . print ( output ) } } function first _in _statement ( output ) { var a = output . stack ( ) , i = a . length , node = a [ -- i ] , p = a [ -- i ] ; while ( i > 0 ) { if ( p instanceof AST _Statement && p . body === node ) return true ; if ( p instanceof AST _Seq && p . car === node || p instanceof AST _Call && p . expression === node && ! ( p instanceof AST _New ) || p instanceof AST _Dot && p . expression === node || p instanceof AST _Sub && p . expression === node || p instanceof AST _Conditional && p . condition === node || p instanceof AST _Binary && p . left === node || p instanceof AST _UnaryPostfix && p . expression === node ) { node = p ; p = a [ -- i ] } else { return false } } } function no _constructor _parens ( self , output ) { return self . args . length == 0 && ! output . option ( "beautify" ) } function best _of ( a ) { var best = a [ 0 ] , len = best . length ; for ( var i = 1 ; i < a . length ; ++ i ) { if ( a [ i ] . length < len ) { best = a [ i ] ; len = best . length } } return best } function make _num ( num ) { var str = num . toString ( 10 ) , a = [ str . replace ( /^0\./ , "." ) . replace ( "e+" , "e" ) ] , m ; if ( Math . floor ( num ) === num ) { if ( num >= 0 ) { a . push ( "0x" + num . toString ( 16 ) . toLowerCase ( ) , "0" + num . toString ( 8 ) ) } else { a . push ( "-0x" + ( - num ) . toString ( 16 ) . toLowerCase ( ) , "-0" + ( - num ) . toString ( 8 ) ) } if ( m = /^(.*?)(0+)$/ . exec ( num ) ) { a . push ( m [ 1 ] + "e" + m [ 2 ] . length ) } } else if ( m = /^0?\.(0+)(.*)$/ . exec ( num ) ) { a . push ( m [ 2 ] + "e-" + ( m [ 1 ] . length + m [ 2 ] . length ) , str . substr ( str . indexOf ( "." ) ) ) } return best _of ( a ) } function make _block ( stmt , output ) { if ( stmt instanceof AST _BlockStatement ) { stmt . print ( output ) ; return } output . with _block ( function ( ) { output . indent ( ) ; stmt . print ( output ) ; output . newline ( ) } ) } function DEFMAP ( nodetype , generator ) { nodety
return make _node ( AST _EmptyStatement , self ) } return self . label . references . length == 0 ? self . body : self } ) ; OPT ( AST _Block , function ( self , compressor ) { self . body = tighten _body ( self . body , compressor ) ; return self } ) ; OPT ( AST _BlockStatement , function ( self , compressor ) { self . body = tighten _body ( self . body , compressor ) ; switch ( self . body . length ) { case 1 : return self . body [ 0 ] ; case 0 : return make _node ( AST _EmptyStatement , self ) } return self } ) ; AST _Scope . DEFMETHOD ( "drop_unused" , function ( compressor ) { var self = this ; if ( compressor . has _directive ( "use asm" ) ) return self ; if ( compressor . option ( "unused" ) && ! ( self instanceof AST _Toplevel ) && ! self . uses _eval ) { var in _use = [ ] ; var initializations = new Dictionary ; var scope = this ; var tw = new TreeWalker ( function ( node , descend ) { if ( node !== self ) { if ( node instanceof AST _Defun ) { initializations . add ( node . name . name , node ) ; return true } if ( node instanceof AST _Definitions && scope === self ) { node . definitions . forEach ( function ( def ) { if ( def . value ) { initializations . add ( def . name . name , def . value ) ; if ( def . value . has _side _effects ( compressor ) ) { def . value . walk ( tw ) } } } ) ; return true } if ( node instanceof AST _SymbolRef ) { push _uniq ( in _use , node . definition ( ) ) ; return true } if ( node instanceof AST _Scope ) { var save _scope = scope ; scope = node ; descend ( ) ; scope = save _scope ; return true } } } ) ; self . walk ( tw ) ; for ( var i = 0 ; i < in _use . length ; ++ i ) { in _use [ i ] . orig . forEach ( function ( decl ) { var init = initializations . get ( decl . name ) ; if ( init ) init . forEach ( function ( init ) { var tw = new TreeWalker ( function ( node ) { if ( node instanceof AST _SymbolRef ) { push _uniq ( in _use , node . definition ( ) ) } } ) ; init . walk ( tw ) } ) } ) } var tt = new TreeTransformer ( function before ( node , descend , in _list ) { if ( node instanceof AST _Lambda && ! ( node instanceof AST _Accessor ) ) { if ( ! compressor . option ( "keep_fargs" ) ) { for ( var a = node . argnames , i = a . length ; -- i >= 0 ; ) { var sym = a [ i ] ; if ( sym . unreferenced ( ) ) { a . pop ( ) ; compressor . warn ( "Dropping unused function argument {name} [{file}:{line},{col}]" , { name : sym . name , file : sym . start . file , line : sym . start . line , col : sym . start . col } ) } else break } } } if ( node instanceof AST _Defun && node !== self ) { if ( ! member ( node . name . definition ( ) , in _use ) ) { compressor . warn ( "Dropping unused function {name} [{file}:{line},{col}]" , { name : node . name . name , file : node . name . start . file , line : node . name . start . line , col : node . name . start . col } ) ; return make _node ( AST _EmptyStatement , node ) } return node } if ( node instanceof AST _Definitions && ! ( tt . parent ( ) instanceof AST _ForIn ) ) { var def = node . definitions . filter ( function ( def ) { if ( member ( def . name . definition ( ) , in _use ) ) return true ; var w = { name : def . name . name , file : def . name . start . file , line : def . name . start . line , col : def . name . start . col } ; if ( def . value && def . value . has _side _effects ( compressor ) ) { def . _unused _side _effects = true ; compressor . warn ( "Side effects in initialization of unused variable {name} [{file}:{line},{col}]" , w ) ; return true } compressor . warn ( "Dropping unused variable {name} [{file}:{line},{col}]" , w ) ; return false } ) ; def = mergeSort ( def , function ( a , b ) { if ( ! a . value && b . value ) return - 1 ; if ( ! b . value && a . value ) return 1 ; return 0 } ) ; var side _effects = [ ] ; for ( var i = 0 ; i < def . length ; ) { var x = def [ i ] ; if ( x . _unused _side _effects ) { side _effects . push ( x . value ) ; def . splice ( i , 1 ) } else { if ( side _effects . length > 0 ) { side _effects . push ( x . value ) ; x . value = AST _Seq . from _array ( side _effects ) ; side _effects = [ ] } ++ i } } if ( side _effects . length > 0 ) { side _effects = make _node ( AST _BlockStatement , node , { body : [ make _node ( AST _SimpleStatement , node , { body : AST _Seq . from _array ( side _effects ) } ) ] } ) } else { side _effects = null } if ( def . length == 0 && ! side _effects ) { return make _node ( AST _EmptyStatement , node ) } if ( def . length == 0 ) { return in _list ? MAP . splice ( side _effects . body ) : side _effects } node . definitions = def ; if ( side _effects ) { side _effects . body . unshift ( node ) ; return in _list ? MAP . splice ( side _effects . body ) : side _effects } return node } if ( node instanceof AST _For ) { descend ( node , this ) ; if ( node . init instanceof AST _BlockStatement ) { var body = node . init . body . slice ( 0 , - 1 ) ; node . init = node . init . body . slice ( - 1 ) [ 0 ] . body ; body . push ( node ) ; return in _list ? MAP . splice ( body ) : make _node ( AST _BlockStatement , node , { body : body } ) } } if ( node instanceof AST _Scope && node !== self ) return node } ) ; self . transform ( tt ) } } ) ; AST _Scope . DEFMETHOD ( "hoist_declarations" , function ( compressor ) { var self = this ; if ( compressor . has _directive ( "use asm" ) ) re
} } var negated = cond [ 0 ] . negate ( compressor ) ; if ( best _of ( cond [ 0 ] , negated ) === negated ) { self = make _node ( AST _Conditional , self , { condition : negated , consequent : self . alternative , alternative : self . consequent } ) } var consequent = self . consequent ; var alternative = self . alternative ; if ( consequent instanceof AST _Assign && alternative instanceof AST _Assign && consequent . operator == alternative . operator && consequent . left . equivalent _to ( alternative . left ) && ! consequent . left . has _side _effects ( compressor ) ) { return make _node ( AST _Assign , self , { operator : consequent . operator , left : consequent . left , right : make _node ( AST _Conditional , self , { condition : self . condition , consequent : consequent . right , alternative : alternative . right } ) } ) } if ( consequent instanceof AST _Call && alternative . TYPE === consequent . TYPE && consequent . args . length == alternative . args . length && ! consequent . expression . has _side _effects ( compressor ) && consequent . expression . equivalent _to ( alternative . expression ) ) { if ( consequent . args . length == 0 ) { return make _node ( AST _Seq , self , { car : self . condition , cdr : consequent } ) } if ( consequent . args . length == 1 ) { consequent . args [ 0 ] = make _node ( AST _Conditional , self , { condition : self . condition , consequent : consequent . args [ 0 ] , alternative : alternative . args [ 0 ] } ) ; return consequent } } if ( consequent instanceof AST _Conditional && consequent . alternative . equivalent _to ( alternative ) ) { return make _node ( AST _Conditional , self , { condition : make _node ( AST _Binary , self , { left : self . condition , operator : "&&" , right : consequent . condition } ) , consequent : consequent . consequent , alternative : alternative } ) } if ( consequent . is _constant ( compressor ) && alternative . is _constant ( compressor ) && consequent . equivalent _to ( alternative ) ) { var consequent _value = consequent . constant _value ( ) ; if ( self . condition . has _side _effects ( compressor ) ) { return AST _Seq . from _array ( [ self . condition , make _node _from _constant ( compressor , consequent _value , self ) ] ) } else { return make _node _from _constant ( compressor , consequent _value , self ) } } if ( is _true ( consequent ) && is _false ( alternative ) ) { if ( self . condition . is _boolean ( ) ) { return self . condition } self . condition = self . condition . negate ( compressor ) ; return make _node ( AST _UnaryPrefix , self . condition , { operator : "!" , expression : self . condition } ) } if ( is _false ( consequent ) && is _true ( alternative ) ) { return self . condition . negate ( compressor ) } return self ; function is _true ( node ) { return node instanceof AST _True || node instanceof AST _UnaryPrefix && node . operator == "!" && node . expression instanceof AST _Constant && ! node . expression . value } function is _false ( node ) { return node instanceof AST _False || node instanceof AST _UnaryPrefix && node . operator == "!" && node . expression instanceof AST _Constant && ! ! node . expression . value } } ) ; OPT ( AST _Boolean , function ( self , compressor ) { if ( compressor . option ( "booleans" ) ) { var p = compressor . parent ( ) ; if ( p instanceof AST _Binary && ( p . operator == "==" || p . operator == "!=" ) ) { compressor . warn ( "Non-strict equality against boolean: {operator} {value} [{file}:{line},{col}]" , { operator : p . operator , value : self . value , file : p . start . file , line : p . start . line , col : p . start . col } ) ; return make _node ( AST _Number , self , { value : + self . value } ) } return make _node ( AST _UnaryPrefix , self , { operator : "!" , expression : make _node ( AST _Number , self , { value : 1 - self . value } ) } ) } return self } ) ; OPT ( AST _Sub , function ( self , compressor ) { var prop = self . property ; if ( prop instanceof AST _String && compressor . option ( "properties" ) ) { prop = prop . getValue ( ) ; if ( RESERVED _WORDS ( prop ) ? compressor . option ( "screw_ie8" ) : is _identifier _string ( prop ) ) { return make _node ( AST _Dot , self , { expression : self . expression , property : prop } ) . optimize ( compressor ) } var v = parseFloat ( prop ) ; if ( ! isNaN ( v ) && v . toString ( ) == prop ) { self . property = make _node ( AST _Number , self . property , { value : v } ) } } return self } ) ; OPT ( AST _Dot , function ( self , compressor ) { var prop = self . property ; if ( RESERVED _WORDS ( prop ) && ! compressor . option ( "screw_ie8" ) ) { return make _node ( AST _Sub , self , { expression : self . expression , property : make _node ( AST _String , self , { value : prop } ) } ) . optimize ( compressor ) } return self . evaluate ( compressor ) [ 0 ] } ) ; function literals _in _boolean _context ( self , compressor ) { if ( compressor . option ( "booleans" ) && compressor . in _boolean _context ( ) && ! self . has _side _effects ( compressor ) ) { return make _node ( AST _True , self ) } return self } OPT ( AST _Array , literals _in _boolean _context ) ; OPT ( AS