uglifier 0.4.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of uglifier might be problematic. Click here for more details.

data/Gemfile CHANGED
@@ -3,7 +3,8 @@ source "http://rubygems.org"
3
3
  # Example:
4
4
  # gem "activesupport", ">= 2.3.5"
5
5
 
6
- gem "therubyracer", "~> 0.8.0"
6
+ gem "execjs", "~> 0.1.0"
7
+ gem "json"
7
8
 
8
9
  # Add dependencies to develop your gem here.
9
10
  # Include everything needed to run rake, tests, features, etc.
data/README.rdoc CHANGED
@@ -1,6 +1,14 @@
1
1
  = Uglifier
2
2
 
3
- Ruby wrapper for UglifyJS[http://github.com/mishoo/UglifyJS] JavaScript compressor.
3
+ Ruby wrapper for UglifyJS[https://github.com/mishoo/UglifyJS] JavaScript compressor.
4
+
5
+ == Installation
6
+
7
+ Uglifier is available as ruby gem.
8
+
9
+ $ gem install uglifier
10
+
11
+ Ensure that your environment has a JavaScript interpreter supported by ExecJS[https://github.com/sstephenson/execjs]. Usually, installing therubyracer gem is the best alternative.
4
12
 
5
13
  == Usage
6
14
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.4.0
1
+ 0.5.0
data/build.js ADDED
@@ -0,0 +1,28 @@
1
+ #!/usr/bin/env node
2
+
3
+ var fs = require("fs");
4
+ var stitch = require("stitch");
5
+ var UglifyJS = require("./vendor/uglifyjs");
6
+ var uglify = UglifyJS.uglify;
7
+
8
+ var package = stitch.createPackage({
9
+ paths: [__dirname + "/vendor/uglifyjs/lib"]
10
+ });
11
+
12
+ package.compile(function(err, source) {
13
+ if (err) throw err;
14
+
15
+ source = "(function(global) {" +
16
+ source + ";" +
17
+ "global.UglifyJS = {};" +
18
+ "global.UglifyJS.parser = this.require('parse-js');" +
19
+ "global.UglifyJS.uglify = this.require('process');" +
20
+ "}).call({}, this)";
21
+
22
+ var ast = UglifyJS.parser.parse(source);
23
+ source = uglify.gen_code(uglify.ast_squeeze(uglify.ast_mangle(ast)));
24
+
25
+ fs.writeFile(__dirname + "/lib/uglify.js", source, function(err) {
26
+ if (err) throw err;
27
+ });
28
+ });
data/lib/uglifier.rb CHANGED
@@ -1,8 +1,7 @@
1
- require "uglifier/node"
1
+ require "execjs"
2
2
 
3
3
  class Uglifier
4
- # Raised when compilation fails
5
- class Error < StandardError; end
4
+ Error = ExecJS::Error
6
5
 
7
6
  DEFAULTS = {
8
7
  :mangle => true, # Mangle variables names
@@ -21,78 +20,70 @@ class Uglifier
21
20
  }
22
21
  }
23
22
 
23
+ SourcePath = File.expand_path("../uglify.js", __FILE__)
24
+
25
+ def self.compile(source, options = {})
26
+ self.new(options).compile(source)
27
+ end
28
+
24
29
  # Create new instance of Uglifier with given options
25
30
  def initialize(options = {})
26
31
  @options = DEFAULTS.merge(options)
27
- @node = Node.new do |cxt|
28
- @tokenizer = cxt.require("parse-js")["tokenizer"]
29
- process = cxt.require("process")
30
- process["set_logger"].call(lambda {|m| $stderr.puts m })
31
- end
32
+ @context = ExecJS.compile(File.read(SourcePath))
32
33
  end
33
34
 
34
35
  def compile(source)
35
- str = stringify(source)
36
+ source = source.respond_to?(:read) ? source.read : source.to_s
36
37
 
37
- if @options[:copyright]
38
- copyright(str)
39
- else
40
- ""
41
- end << generate_code(ast(str))
42
- rescue V8::JSError => e
43
- raise Error.new(e.message)
44
- end
38
+ js = []
39
+ js << "var result = '';"
40
+ js << "var source = #{source.to_json};"
41
+ js << "var ast = UglifyJS.parser.parse(source);"
45
42
 
46
- def self.compile(source, options = {})
47
- self.new(options).compile(source)
48
- end
43
+ if @options[:copyright]
44
+ js << <<-JS
45
+ var comments = UglifyJS.parser.tokenizer(source)().comments_before;
46
+ for (var i = 0; i < comments.length; i++) {
47
+ var c = comments[i];
48
+ result += (c.type == "comment1") ? "//"+c.value+"\\n" : "/*"+c.value+"*/\\n";
49
+ }
50
+ JS
51
+ end
49
52
 
50
- private
53
+ if @options[:mangle]
54
+ js << "ast = UglifyJS.uglify.ast_mangle(ast, #{mangle_options.to_json});"
55
+ end
51
56
 
52
- def stringify(source)
53
- if source.respond_to? :read
54
- source.read
55
- else
56
- source.to_s
57
+ if @options[:squeeze]
58
+ js << "ast = UglifyJS.uglify.ast_squeeze(ast, #{squeeze_options.to_json});"
57
59
  end
58
- end
59
60
 
60
- def copyright(source)
61
- tokens = @tokenizer.call(source, false)
62
- tokens.call.comments_before.inject("") do |copyright, comment|
63
- copyright + if comment["type"] == "comment1"
64
- "//" + comment["value"] + "\n"
65
- else
66
- "/*" + comment["value"] + "*/\n"
67
- end
61
+ if @options[:unsafe]
62
+ js << "ast = UglifyJS.uglify.ast_squeeze_more(ast);"
68
63
  end
69
- end
70
64
 
71
- def generate_code(ast)
72
- @node["gen_code"].call(ast, @options[:beautify] && @options[:beautify_options])
73
- end
65
+ js << "result += UglifyJS.uglify.gen_code(ast, #{gen_code_options.to_json});"
66
+ js << "return result;"
74
67
 
75
- def ast(source)
76
- squeeze_unsafe(squeeze(mangle(@node["parse"].call(source))))
68
+ @context.exec js.join("\n")
77
69
  end
70
+ alias_method :compress, :compile
78
71
 
79
- def mangle(ast)
80
- return ast unless @options[:mangle]
81
- @node["ast_mangle"].call(ast, @options[:toplevel])
82
- end
72
+ private
83
73
 
84
- def squeeze(ast)
85
- return ast unless @options[:squeeze]
74
+ def mangle_options
75
+ @options[:toplevel]
76
+ end
86
77
 
87
- @node["ast_squeeze"].call(ast, {
78
+ def squeeze_options
79
+ {
88
80
  "make_seqs" => @options[:seqs],
89
81
  "dead_code" => @options[:dead_code],
90
82
  "keep_comps" => !@options[:unsafe]
91
- })
83
+ }
92
84
  end
93
85
 
94
- def squeeze_unsafe(ast)
95
- return ast unless @options[:unsafe]
96
- @node["ast_squeeze_more"].call(ast)
86
+ def gen_code_options
87
+ @options[:beautify] ? @options[:beautify_options] : {}
97
88
  end
98
89
  end
data/lib/uglify.js ADDED
@@ -0,0 +1 @@
1
+ (function(a){(function(){if(!this.require){var a={},b={},c=function(f,g){var h=b[f],i=d(g,f),j;if(h)return h;if(!(j=a[i]||a[i=d(i,"./index")]))throw"module '"+f+"' not found";h={id:f,exports:{}};try{b[f]=h.exports,j(h.exports,function(a){return c(a,e(i))},h);return b[f]=h.exports}catch(k){delete b[f];throw k}},d=function(a,b){var c=[],d,e;/^\.\.?(\/|$)/.test(b)?d=[a,b].join("/").split("/"):d=b.split("/");for(var f=0,g=d.length;f<g;f++)e=d[f],e==".."?c.pop():e!="."&&e!=""&&c.push(e);return c.join("/")},e=function(a){return a.split("/").slice(0,-1).join("/")};this.require=function(a){return c(a,"")},this.require.define=function(b){for(var c in b)a[c]=b[c]}}return this.require.define}).call(this)({"parse-js":function(a,b,c){function S(a,b){return Object.prototype.hasOwnProperty.call(a,b)}function R(a,b){for(var c=b.length;--c>=0;)if(b[c]===a)return!0;return!1}function Q(a){return a.split("")}function P(a,b){return Array.prototype.slice.call(a,b==null?0:b)}function O(a){var b={};for(var c=0;c<a.length;++c)b[a[c]]=!0;return b}function N(a){a instanceof Function&&(a=a());for(var b=1,c=arguments.length;--c>0;++b)arguments[b]();return a}function M(a){var b=P(arguments,1);return function(){return a.apply(this,b.concat(P(arguments)))}}function L(a,b,c){function bl(a){try{++d.in_loop;return a()}finally{--d.in_loop}}function bk(a,b){arguments.length==0&&(a=!0);var c=bj(b);if(a&&e("punc",",")){g();return p("seq",c,bk(!0,b))}return c}function bj(a){var b=bh(a),c=d.token.value;if(e("operator")&&S(G,c)){if(bi(b)){g();return p("assign",G[c],b,bj(a))}i("Invalid assignment")}return b}function bi(a){if(!b)return!0;switch(a[0]){case"dot":case"sub":case"new":case"call":return!0;case"name":return a[1]!="this"}}function bh(a){var b=bg(a);if(e("operator","?")){g();var c=bk(!1);m(":");return p("conditional",b,c,bk(!1,a))}return b}function bg(a){return bf(Z(!0),0,a)}function bf(a,b,c){var f=e("operator")?d.token.value:null;f&&f=="in"&&c&&(f=null);var h=f!=null?H[f]:null;if(h!=null&&h>b){g();var i=bf(Z(!0),h,c);return bf(p("binary",f,a,i),b,c)}return a}function be(a,b,c){(b=="++"||b=="--")&&!bi(c)&&i("Invalid use of "+b+" operator");return p(a,b,c)}function bd(a,b){if(e("punc",".")){g();return bd(p("dot",a,bc()),b)}if(e("punc","[")){g();return bd(p("sub",a,N(bk,M(m,"]"))),b)}if(b&&e("punc","(")){g();return bd(p("call",a,$(")")),!0)}if(b&&e("operator")&&S(F,d.token.value))return N(M(be,"unary-postfix",d.token.value,a),g);return a}function bc(){switch(d.token.type){case"name":case"operator":case"keyword":case"atom":return N(d.token.value,g);default:k()}}function bb(){switch(d.token.type){case"num":case"string":return N(d.token.value,g)}return bc()}function ba(){var a=!0,c=[];while(!e("punc","}")){a?a=!1:m(",");if(!b&&e("punc","}"))break;var f=d.token.type,h=bb();f!="name"||h!="get"&&h!="set"||!!e("punc",":")?(m(":"),c.push([h,bk(!1)])):c.push([bc(),C(!1),h])}g();return p("object",c)}function _(){return p("array",$("]",!b,!0))}function $(a,b,c){var d=!0,f=[];while(!e("punc",a)){d?d=!1:m(",");if(b&&e("punc",a))break;e("punc",",")&&c?f.push(["atom","undefined"]):f.push(bk(!1))}g();return f}function Z(a){if(e("operator","new")){g();return Y()}if(e("operator")&&S(E,d.token.value))return be("unary-prefix",N(d.token.value,g),Z(a));if(e("punc")){switch(d.token.value){case"(":g();return bd(N(bk,M(m,")")),a);case"[":g();return bd(_(),a);case"{":g();return bd(ba(),a)}k()}if(e("keyword","function")){g();return bd(C(!1),a)}if(S(J,d.token.type)){var b=d.token.type=="regexp"?p("regexp",d.token.value[0],d.token.value[1]):p(d.token.type,d.token.value);return bd(N(b,g),a)}k()}function Y(){var a=Z(!1),b;e("punc","(")?(g(),b=$(")")):b=[];return bd(p("new",a,b),!0)}function X(){return p("const",V())}function W(a){return p("var",V(a))}function V(a){var b=[];for(;;){e("name")||k();var c=d.token.value;g(),e("operator","=")?(g(),b.push([c,bk(!1,a)])):b.push([c]);if(!e("punc",","))break;g()}return b}function U(){var a=Q(),b,c;if(e("keyword","catch")){g(),m("("),e("name")||i("Name expected");var f=d.token.value;g(),m(")"),b=[f,Q()]}e("keyword","finally")&&(g(),c=Q()),!b&&!c&&i("Missing catch/finally blocks");return p("try",a,b,c)}function Q(){m("{");var a=[];while(!e("punc","}"))e("eof")&&k(),a.push(s());g();return a}function O(){var a=q(),b=s(),c;e("keyword","else")&&(g(),c=s());return p("if",a,b,c)}function L(a){var b=e("name")?N(d.token.value,g):null;a&&!b&&k(),m("(");return p(a?"defun":"function",b,function(a,b){while(!e("punc",")"))a?a=!1:m(","),e("name")||k(),b.push(d.token.value),g();g();return b}(!0,[]),function(){++d.in_function;var a=d.in_loop;d.in_loop=0;var b=Q();--d.in_function,d.in_loop=a;return b}())}function z(a){var b=a[0]=="var"?p("name",a[1][0]):a;g();var c=bk();m(")");return p("for-in",a,b,c,bl(s))}function y(a){m(";");var b=e("punc",";")?null:bk();m(";");var c=e("punc",")")?null:bk();m(")");return p("for",a,b,c,bl(s))}function x(){m("(");var a=null;if(!e("punc",";")){a=e("keyword","var")?(g(),W(!0)):bk(!0,!0);if(e("operator","in"))return z(a)}return y(a)}function w(a){var b=e("name")?d.token.value:null;b!=null?(g(),R(b,d.labels)||i("Label "+b+" without matching loop or statement")):d.in_loop==0&&i(a+" not inside a loop or switch"),o();return p(a,b)}function v(){return p("stat",N(bk,o))}function u(a){d.labels.push(a);var c=d.token,e=s();b&&!S(I,e[0])&&k(c),d.labels.pop();return p("label",a,e)}function t(){e("operator","/")&&(d.peeked=null,d.token=d.input(!0));switch(d.token.type){case"num":case"string":case"regexp":case"operator":case"atom":return v();case"name":return B(f(),"punc",":")?u(N(d.token.value,g,g)):v();case"punc":switch(d.token.value){case"{":return p("block",Q());case"[":case"(":return v();case";":g();return p("block");default:k()};case"keyword":switch(N(d.token.value,g)){case"break":return w("break");case"continue":return w("continue");case"debugger":o();return p("debugger");case"do":return function(a){l("keyword","while");return p("do",N(q,o),a)}(bl(s));case"for":return x();case"function":return C(!0);case"if":return O();case"return":d.in_function==0&&i("'return' outside of function");return p("return",e("punc",";")?(g(),null):n()?null:N(bk,o));case"switch":return p("switch",q(),T());case"throw":return p("throw",N(bk,o));case"try":return U();case"var":return N(W,o);case"const":return N(X,o);case"while":return p("while",q(),bl(s));case"with":return p("with",q(),s());default:k()}}}function r(a,b,c){return a instanceof K?a:new K(a,b,c)}function q(){m("(");var a=bk();m(")");return a}function p(){return P(arguments)}function o(){e("punc",";")?g():n()||k()}function n(){return!b&&(d.token.nlb||e("eof")||e("punc","}"))}function m(a){return l("punc",a)}function l(a,b){if(e(a,b))return g();j(d.token,"Unexpected token "+d.token.type+", expected "+a)}function k(a){a==null&&(a=d.token),j(a,"Unexpected token: "+a.type+" ("+a.value+")")}function j(a,b){i(b,a.line,a.col)}function i(a,b,c,e){var f=d.input.context();A(a,b!=null?b:f.tokline,c!=null?c:f.tokcol,e!=null?e:f.tokpos)}function h(){return d.prev}function g(){d.prev=d.token,d.peeked?(d.token=d.peeked,d.peeked=null):d.token=d.input();return d.token}function f(){return d.peeked||(d.peeked=d.input())}function e(a,b){return B(d.token,a,b)}var d={input:typeof a=="string"?D(a,!0):a,token:null,prev:null,peeked:null,in_function:0,in_loop:0,labels:[]};d.token=g();var s=c?function(){var a=d.token,b=t.apply(this,arguments);b[0]=r(b[0],a,h());return b}:t,C=c?function(){var a=h(),b=L.apply(this,arguments);b[0]=r(b[0],a,h());return b}:L,T=M(bl,function(){m("{");var a=[],b=null;while(!e("punc","}"))e("eof")&&k(),e("keyword","case")?(g(),b=[],a.push([bk(),b]),m(":")):e("keyword","default")?(g(),m(":"),b=[],a.push([null,b])):(b||k(),b.push(s()));g();return a});return p("toplevel",function(a){while(!e("eof"))a.push(s());return a}([]))}function K(a,b,c){this.name=a,this.start=b,this.end=c}function D(a){function O(a){if(a)return I();q(),k();var b=c();if(!b)return p("eof");if(s(b))return v();if(b=='"'||b=="'")return D();if(S(o,b))return p("punc",e());if(b==".")return L();if(b=="/")return K();if(S(h,b))return J();if(b=="\\"||w(b))return M();u("Unexpected character '"+b+"'")}function N(a,b){try{return b()}catch(c){if(c===C)u(a);else throw c}}function M(){var a=H();return S(d,a)?S(l,a)?p("operator",a):S(g,a)?p("atom",a):p("keyword",a):p("name",a)}function L(){e();return s(c())?v("."):p("punc",".")}function K(){e();var a=b.regex_allowed;switch(c()){case"/":b.comments_before.push(E()),b.regex_allowed=a;return O();case"*":b.comments_before.push(G()),b.regex_allowed=a;return O()}return b.regex_allowed?I():J("/")}function J(a){function b(a){if(!c())return a;var d=a+c();if(S(l,d)){e();return b(d)}return a}return p("operator",b(a||e()))}function I(){return N("Unterminated regular expression",function(){var a=!1,b="",c,d=!1;while(c=e(!0))if(a)b+="\\"+c,a=!1;else if(c=="[")d=!0,b+=c;else if(c=="]"&&d)d=!1,b+=c;else{if(c=="/"&&!d)break;c=="\\"?a=!0:b+=c}var f=H();return p("regexp",[b,f])})}function H(){var a=!1,b="",d;while((d=c())!=null)if(!a)if(d=="\\")a=!0,e();else if(x(d))b+=e();else break;else d!="u"&&u("Expecting UnicodeEscapeSequence -- uXXXX"),d=z(),x(d)||u("Unicode char: "+d.charCodeAt(0)+" is not valid in identifier"),b+=d,a=!1;return b}function G(){e();return N("Unterminated multiline comment",function(){var a=j("*/",!0),c=b.text.substring(b.pos,a),d=p("comment2",c,!0);b.pos=a+2,b.line+=c.split("\n").length-1,b.newline_before=c.indexOf("\n")>=0,/^@cc_on/i.test(c)&&(T("WARNING: at line "+b.line),T('*** Found "conditional comment": '+c),T("*** UglifyJS DISCARDS ALL COMMENTS. This means your code might no longer work properly in Internet Explorer."));return d})}function E(){e();var a=j("\n"),c;a==-1?(c=b.text.substr(b.pos),b.pos=b.text.length):(c=b.text.substring(b.pos,a),b.pos=a);return p("comment1",c,!0)}function D(){return N("Unterminated string constant",function(){var a=e(),b="";for(;;){var c=e(!0);if(c=="\\")c=z();else if(c==a)break;b+=c}return p("string",b)})}function B(a){var b=0;for(;a>0;--a){var c=parseInt(e(!0),16);isNaN(c)&&u("Invalid hex-character pattern in string"),b=b<<4|c}return b}function z(){var a=e(!0);switch(a){case"n":return"\n";case"r":return"\r";case"t":return"\t";case"b":return"\b";case"v":return" ";case"f":return"\f";case"0":return"";case"x":return String.fromCharCode(B(2));case"u":return String.fromCharCode(B(4));default:return a}}function v(a){var b=!1,c=!1,d=!1,e=a==".",f=r(function(f,g){if(f=="x"||f=="X"){if(d)return!1;return d=!0}if(!d&&(f=="E"||f=="e")){if(b)return!1;return b=c=!0}if(f=="-"){if(c||g==0&&!a)return!0;return!1}if(f=="+")return c;c=!1;if(f=="."){if(!e&&!d)return e=!0;return!1}return t(f)});a&&(f=a+f);var g=y(f);if(!isNaN(g))return p("num",g);u("Invalid syntax: "+f)}function u(a){A(a,b.tokline,b.tokcol,b.tokpos)}function r(a){var b="",d=c(),f=0;while(d&&a(d,f++))b+=e(),d=c();return b}function q(){while(S(m,c()))e()}function p(a,c,d){b.regex_allowed=a=="operator"&&!S(F,c)||a=="keyword"&&S(f,c)||a=="punc"&&S(n,c);var e={type:a,value:c,line:b.tokline,col:b.tokcol,pos:b.tokpos,nlb:b.newline_before};d||(e.comments_before=b.comments_before,b.comments_before=[]),b.newline_before=!1;return e}function k(){b.tokline=b.line,b.tokcol=b.col,b.tokpos=b.pos}function j(a,c){var d=b.text.indexOf(a,b.pos);if(c&&d==-1)throw C;return d}function i(){return!b.peek()}function e(a){var c=b.text.charAt(b.pos++);if(a&&!c)throw C;c=="\n"?(b.newline_before=!0,++b.line,b.col=0):++b.col;return c}function c(){return b.text.charAt(b.pos)}var b={text:a.replace(/\r\n?|[\n\u2028\u2029]/g,"\n").replace(/^\uFEFF/,""),pos:0,tokpos:0,line:0,tokline:0,col:0,tokcol:0,newline_before:!1,regex_allowed:!1,comments_before:[]};O.context=function(a){a&&(b=a);return b};return O}function B(a,b,c){return a.type==b&&(c==null||a.value==c)}function A(a,b,c,d){throw new z(a,b,c,d)}function z(a,b,c,d){this.message=a,this.line=b,this.col=c,this.pos=d;try{({})()}catch(e){this.stack=e.stack}}function y(a){if(i.test(a))return parseInt(a.substr(2),16);if(j.test(a))return parseInt(a.substr(1),8);if(k.test(a))return parseFloat(a)}function x(a){return w(a)||u(a)||s(a)||v(a)||a=="‌"||a=="‍"}function w(a){return a=="$"||a=="_"||r(a)}function v(a){return q.connector_punctuation.test(a)}function u(a){return q.non_spacing_mark.test(a)||q.space_combining_mark.test(a)}function t(a){return s(a)||r(a)}function s(a){a=a.charCodeAt(0);return a>=48&&a<=57}function r(a){return q.letter.test(a)}var d=O(["break","case","catch","const","continue","default","delete","do","else","finally","for","function","if","in","instanceof","new","return","switch","throw","try","typeof","var","void","while","with"]),e=O(["abstract","boolean","byte","char","class","debugger","double","enum","export","extends","final","float","goto","implements","import","int","interface","long","native","package","private","protected","public","short","static","super","synchronized","throws","transient","volatile"]),f=O(["return","new","delete","throw","else","case"]),g=O(["false","null","true","undefined"]),h=O(Q("+-*&%=<>!?|~^")),i=/^0x[0-9a-f]+$/i,j=/^0[0-7]+$/,k=/^\d*\.?\d*(?:e[+-]?\d*(?:\d\.?|\.?\d)\d*)?$/i,l=O(["in","instanceof","typeof","new","void","delete","++","--","+","-","!","~","&","|","^","*","/","%",">>","<<",">>>","<",">","<=",">=","==","===","!=","!==","?","=","+=","-=","/=","*=","%=",">>=","<<=",">>>=","|=","^=","&=","&&","||"]),m=O(Q(" \n\r\t​")),n=O(Q("[{}(,.;:")),o=O(Q("[]{}(),;:")),p=O(Q("gmsiy")),q={letter:new RegExp("[\\u0041-\\u005A\\u0061-\\u007A\\u00AA\\u00B5\\u00BA\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02C1\\u02C6-\\u02D1\\u02E0-\\u02E4\\u02EC\\u02EE\\u0370-\\u0374\\u0376\\u0377\\u037A-\\u037D\\u0386\\u0388-\\u038A\\u038C\\u038E-\\u03A1\\u03A3-\\u03F5\\u03F7-\\u0481\\u048A-\\u0523\\u0531-\\u0556\\u0559\\u0561-\\u0587\\u05D0-\\u05EA\\u05F0-\\u05F2\\u0621-\\u064A\\u066E\\u066F\\u0671-\\u06D3\\u06D5\\u06E5\\u06E6\\u06EE\\u06EF\\u06FA-\\u06FC\\u06FF\\u0710\\u0712-\\u072F\\u074D-\\u07A5\\u07B1\\u07CA-\\u07EA\\u07F4\\u07F5\\u07FA\\u0904-\\u0939\\u093D\\u0950\\u0958-\\u0961\\u0971\\u0972\\u097B-\\u097F\\u0985-\\u098C\\u098F\\u0990\\u0993-\\u09A8\\u09AA-\\u09B0\\u09B2\\u09B6-\\u09B9\\u09BD\\u09CE\\u09DC\\u09DD\\u09DF-\\u09E1\\u09F0\\u09F1\\u0A05-\\u0A0A\\u0A0F\\u0A10\\u0A13-\\u0A28\\u0A2A-\\u0A30\\u0A32\\u0A33\\u0A35\\u0A36\\u0A38\\u0A39\\u0A59-\\u0A5C\\u0A5E\\u0A72-\\u0A74\\u0A85-\\u0A8D\\u0A8F-\\u0A91\\u0A93-\\u0AA8\\u0AAA-\\u0AB0\\u0AB2\\u0AB3\\u0AB5-\\u0AB9\\u0ABD\\u0AD0\\u0AE0\\u0AE1\\u0B05-\\u0B0C\\u0B0F\\u0B10\\u0B13-\\u0B28\\u0B2A-\\u0B30\\u0B32\\u0B33\\u0B35-\\u0B39\\u0B3D\\u0B5C\\u0B5D\\u0B5F-\\u0B61\\u0B71\\u0B83\\u0B85-\\u0B8A\\u0B8E-\\u0B90\\u0B92-\\u0B95\\u0B99\\u0B9A\\u0B9C\\u0B9E\\u0B9F\\u0BA3\\u0BA4\\u0BA8-\\u0BAA\\u0BAE-\\u0BB9\\u0BD0\\u0C05-\\u0C0C\\u0C0E-\\u0C10\\u0C12-\\u0C28\\u0C2A-\\u0C33\\u0C35-\\u0C39\\u0C3D\\u0C58\\u0C59\\u0C60\\u0C61\\u0C85-\\u0C8C\\u0C8E-\\u0C90\\u0C92-\\u0CA8\\u0CAA-\\u0CB3\\u0CB5-\\u0CB9\\u0CBD\\u0CDE\\u0CE0\\u0CE1\\u0D05-\\u0D0C\\u0D0E-\\u0D10\\u0D12-\\u0D28\\u0D2A-\\u0D39\\u0D3D\\u0D60\\u0D61\\u0D7A-\\u0D7F\\u0D85-\\u0D96\\u0D9A-\\u0DB1\\u0DB3-\\u0DBB\\u0DBD\\u0DC0-\\u0DC6\\u0E01-\\u0E30\\u0E32\\u0E33\\u0E40-\\u0E46\\u0E81\\u0E82\\u0E84\\u0E87\\u0E88\\u0E8A\\u0E8D\\u0E94-\\u0E97\\u0E99-\\u0E9F\\u0EA1-\\u0EA3\\u0EA5\\u0EA7\\u0EAA\\u0EAB\\u0EAD-\\u0EB0\\u0EB2\\u0EB3\\u0EBD\\u0EC0-\\u0EC4\\u0EC6\\u0EDC\\u0EDD\\u0F00\\u0F40-\\u0F47\\u0F49-\\u0F6C\\u0F88-\\u0F8B\\u1000-\\u102A\\u103F\\u1050-\\u1055\\u105A-\\u105D\\u1061\\u1065\\u1066\\u106E-\\u1070\\u1075-\\u1081\\u108E\\u10A0-\\u10C5\\u10D0-\\u10FA\\u10FC\\u1100-\\u1159\\u115F-\\u11A2\\u11A8-\\u11F9\\u1200-\\u1248\\u124A-\\u124D\\u1250-\\u1256\\u1258\\u125A-\\u125D\\u1260-\\u1288\\u128A-\\u128D\\u1290-\\u12B0\\u12B2-\\u12B5\\u12B8-\\u12BE\\u12C0\\u12C2-\\u12C5\\u12C8-\\u12D6\\u12D8-\\u1310\\u1312-\\u1315\\u1318-\\u135A\\u1380-\\u138F\\u13A0-\\u13F4\\u1401-\\u166C\\u166F-\\u1676\\u1681-\\u169A\\u16A0-\\u16EA\\u1700-\\u170C\\u170E-\\u1711\\u1720-\\u1731\\u1740-\\u1751\\u1760-\\u176C\\u176E-\\u1770\\u1780-\\u17B3\\u17D7\\u17DC\\u1820-\\u1877\\u1880-\\u18A8\\u18AA\\u1900-\\u191C\\u1950-\\u196D\\u1970-\\u1974\\u1980-\\u19A9\\u19C1-\\u19C7\\u1A00-\\u1A16\\u1B05-\\u1B33\\u1B45-\\u1B4B\\u1B83-\\u1BA0\\u1BAE\\u1BAF\\u1C00-\\u1C23\\u1C4D-\\u1C4F\\u1C5A-\\u1C7D\\u1D00-\\u1DBF\\u1E00-\\u1F15\\u1F18-\\u1F1D\\u1F20-\\u1F45\\u1F48-\\u1F4D\\u1F50-\\u1F57\\u1F59\\u1F5B\\u1F5D\\u1F5F-\\u1F7D\\u1F80-\\u1FB4\\u1FB6-\\u1FBC\\u1FBE\\u1FC2-\\u1FC4\\u1FC6-\\u1FCC\\u1FD0-\\u1FD3\\u1FD6-\\u1FDB\\u1FE0-\\u1FEC\\u1FF2-\\u1FF4\\u1FF6-\\u1FFC\\u2071\\u207F\\u2090-\\u2094\\u2102\\u2107\\u210A-\\u2113\\u2115\\u2119-\\u211D\\u2124\\u2126\\u2128\\u212A-\\u212D\\u212F-\\u2139\\u213C-\\u213F\\u2145-\\u2149\\u214E\\u2183\\u2184\\u2C00-\\u2C2E\\u2C30-\\u2C5E\\u2C60-\\u2C6F\\u2C71-\\u2C7D\\u2C80-\\u2CE4\\u2D00-\\u2D25\\u2D30-\\u2D65\\u2D6F\\u2D80-\\u2D96\\u2DA0-\\u2DA6\\u2DA8-\\u2DAE\\u2DB0-\\u2DB6\\u2DB8-\\u2DBE\\u2DC0-\\u2DC6\\u2DC8-\\u2DCE\\u2DD0-\\u2DD6\\u2DD8-\\u2DDE\\u2E2F\\u3005\\u3006\\u3031-\\u3035\\u303B\\u303C\\u3041-\\u3096\\u309D-\\u309F\\u30A1-\\u30FA\\u30FC-\\u30FF\\u3105-\\u312D\\u3131-\\u318E\\u31A0-\\u31B7\\u31F0-\\u31FF\\u3400\\u4DB5\\u4E00\\u9FC3\\uA000-\\uA48C\\uA500-\\uA60C\\uA610-\\uA61F\\uA62A\\uA62B\\uA640-\\uA65F\\uA662-\\uA66E\\uA67F-\\uA697\\uA717-\\uA71F\\uA722-\\uA788\\uA78B\\uA78C\\uA7FB-\\uA801\\uA803-\\uA805\\uA807-\\uA80A\\uA80C-\\uA822\\uA840-\\uA873\\uA882-\\uA8B3\\uA90A-\\uA925\\uA930-\\uA946\\uAA00-\\uAA28\\uAA40-\\uAA42\\uAA44-\\uAA4B\\uAC00\\uD7A3\\uF900-\\uFA2D\\uFA30-\\uFA6A\\uFA70-\\uFAD9\\uFB00-\\uFB06\\uFB13-\\uFB17\\uFB1D\\uFB1F-\\uFB28\\uFB2A-\\uFB36\\uFB38-\\uFB3C\\uFB3E\\uFB40\\uFB41\\uFB43\\uFB44\\uFB46-\\uFBB1\\uFBD3-\\uFD3D\\uFD50-\\uFD8F\\uFD92-\\uFDC7\\uFDF0-\\uFDFB\\uFE70-\\uFE74\\uFE76-\\uFEFC\\uFF21-\\uFF3A\\uFF41-\\uFF5A\\uFF66-\\uFFBE\\uFFC2-\\uFFC7\\uFFCA-\\uFFCF\\uFFD2-\\uFFD7\\uFFDA-\\uFFDC]"),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]")};z.prototype.toString=function(){return this.message+" (line: "+this.line+", col: "+this.col+", pos: "+this.pos+")"+"\n\n"+this.stack};var C={},E=O(["typeof","void","delete","--","++","!","~","-","+"]),F=O(["--","++"]),G=function(a,b,c){while(c<a.length)b[a[c]]=a[c].substr(0,a[c].length-1),c++;return b}(["+=","-=","/=","*=","%=",">>=","<<=",">>>=","|=","^=","&="],{"=":!0},0),H=function(a,b){for(var c=0,d=1;c<a.length;++c,++d){var e=a[c];for(var f=0;f<e.length;++f)b[e[f]]=d}return b}([["||"],["&&"],["|"],["^"],["&"],["==","===","!=","!=="],["<",">","<=",">=","in","instanceof"],[">>","<<",">>>"],["+","-"],["*","/","%"]],{}),I=O(["for","do","while","switch"]),J=O(["atom","num","string","regexp","name"]);K.prototype.toString=function(){return this.name};var T=function(){};a.tokenizer=D,a.parse=L,a.slice=P,a.curry=M,a.member=R,a.array_to_hash=O,a.PRECEDENCE=H,a.KEYWORDS_ATOM=g,a.RESERVED_WORDS=e,a.KEYWORDS=d,a.ATOMIC_START_TOKEN=J,a.OPERATORS=l,a.is_alphanumeric_char=t,a.set_logger=function(a){T=a}},process:function(a,b,c){function G(a,b){return Object.prototype.hasOwnProperty.call(a,b)}function F(a){return/^[a-z_$][a-z0-9_$]*$/i.test(a)&&a!="this"&&!G(d.KEYWORDS_ATOM,a)&&!G(d.RESERVED_WORDS,a)&&!G(d.KEYWORDS,a)}function E(a,b){var c={};a===!0&&(a={});for(var d in b)G(b,d)&&(c[d]=a&&G(a,d)?a[d]:b[d]);return c}function D(a,b){if(b<=0)return"";if(b==1)return a;var c=D(a,b>>1);c+=c,b&1&&(c+=a);return c}function C(a,b){var c=[0];d.parse(function(){function j(){var a=e.apply(this,arguments);out:{if(g&&g.type=="keyword")break out;if(h(a)>b)switch(a.type){case"keyword":case"atom":case"name":case"punc":i(a);break out}}g=a;return a}function i(a){f=a.pos,c.push(f)}function h(a){return a.pos-f}var e=d.tokenizer(a),f=0,g;j.context=function(){return e.context.apply(this,arguments)};return j}());return c.map(function(b,d){return a.substring(b,c[d+1]||a.length)}).join("\n")}function B(a,b){function N(a){var b=a[0],c=x[b];if(!c)throw new Error("Can't find generator for \""+b+'"');M.push(a);var d=c.apply(b,a.slice(1));M.pop();return d}function L(a){var b=a[0],c=a[1];c!=null&&(b=q([n(b),"=",N(c)]));return b}function K(a){if(!a)return";";if(a.length==0)return"{}";return"{"+k+p(function(){return I(a).join(k)})+k+o("}")}function J(a){var b=a.length;if(b==0)return"{}";return"{"+k+H(a,function(a,d){var e=a[1].length>0,f=p(function(){return o(a[0]?q(["case",N(a[0])+":"]):"default:")},.5)+(e?k+p(function(){return I(a[1]).join(k)}):"");!c&&e&&d<b-1&&(f+=";");return f}).join(k)+k+o("}")}function I(a){for(var b=[],d=a.length-1,e=0;e<=d;++e){var g=a[e],h=N(g);h!=";"&&(!c&&e==d&&(g[0]=="while"&&t(g[2])||f(g[0],["for","for-in"])&&t(g[4])||g[0]=="if"&&t(g[2])&&!g[3]||g[0]=="if"&&g[3]&&t(g[3])?h=h.replace(/;*\s*$/,";"):h=h.replace(/;+\s*$/,"")),b.push(h))}return H(b,o)}function C(a,b,c,d){var e=d||"function";a&&(e+=" "+n(a)),e+="("+r(H(b,n))+")";return q([e,K(c)])}function B(a){if(a[0]=="do")return N(["block",[a]]);var b=a;for(;;){var c=b[0];if(c=="if"){if(!b[3])return N(["block",[a]]);b=b[3]}else if(c=="while"||c=="do")b=b[2];else if(c=="for"||c=="for-in")b=b[4];else break}return N(a)}function w(a){var b=a.toString(10),c=[b.replace(/^0\./,".")],d;Math.floor(a)===a?(c.push("0x"+a.toString(16).toLowerCase(),"0"+a.toString(8)),(d=/^(.*?)(0+)$/.exec(a))&&c.push(d[1]+"e"+d[2].length)):(d=/^0?\.(0+)(.*)$/.exec(a))&&c.push(d[2]+"e-"+(d[1].length+d[2].length),b.substr(b.indexOf(".")));return u(c)}function v(a){if(a[0]=="function"||a[0]=="object"){var b=e(M),c=b.pop(),d=b.pop();while(d){if(d[0]=="stat")return!0;if((d[0]=="seq"||d[0]=="call"||d[0]=="dot"||d[0]=="sub"||d[0]=="conditional")&&d[1]===c||(d[0]=="binary"||d[0]=="assign"||d[0]=="unary-postfix")&&d[2]===c)c=d,d=b.pop();else return!1}}return!G(y,a[0])}function u(a){if(a.length==1)return a[0];if(a.length==2){var b=a[1];a=a[0];return a.length<=b.length?a:b}return u([a[0],u(a.slice(1))])}function s(a){var b=N(a);for(var c=1;c<arguments.length;++c){var d=arguments[c];if(d instanceof Function&&d(a)||a[0]==d)return"("+b+")"}return b}function r(a){return a.join(","+l)}function q(a){if(c)return a.join(" ");var b=[];for(var d=0;d<a.length;++d){var e=a[d+1];b.push(a[d]),e&&(/[a-z0-9_\x24]$/i.test(a[d].toString())&&/^[a-z0-9_\x24]/i.test(e.toString())||/[\+\-]$/.test(a[d].toString())&&/^[\+\-]/.test(e.toString()))&&b.push(" ")}return b.join("")}function p(a,b){b==null&&(b=1),j+=b;try{return a.apply(null,e(arguments,1))}finally{j-=b}}function o(a){a==null&&(a=""),c&&(a=D(" ",b.indent_start+j*b.indent_level)+a);return a}function n(a){a=a.toString(),b.ascii_only&&(a=A(a));return a}function m(a){return z(a,b.ascii_only)}b=E(b,{indent_start:0,indent_level:4,quote_keys:!1,space_colon:!1,beautify:!1,ascii_only:!1});var c=!!b.beautify,j=0,k=c?"\n":"",l=c?" ":"",x={string:m,num:w,name:n,toplevel:function(a){return I(a).join(k+k)},block:K,"var":function(a){return"var "+r(H(a,L))+";"},"const":function(a){return"const "+r(H(a,L))+";"},"try":function(a,b,c){var d=["try",K(a)];b&&d.push("catch","("+b[0]+")",K(b[1])),c&&d.push("finally",K(c));return q(d)},"throw":function(a){return q(["throw",N(a)])+";"},"new":function(a,b){b=b.length>0?"("+r(H(b,N))+")":"";return q(["new",s(a,"seq","binary","conditional","assign",function(a){var b=i(),c={};try{b.with_walkers({call:function(){throw c},"function":function(){return this}},function(){b.walk(a)})}catch(d){if(d===c)return!0;throw d}})+b])},"switch":function(a,b){return q(["switch","("+N(a)+")",J(b)])},"break":function(a){var b="break";a!=null&&(b+=" "+n(a));return b+";"},"continue":function(a){var b="continue";a!=null&&(b+=" "+n(a));return b+";"},conditional:function(a,b,c){return q([s(a,"assign","seq","conditional"),"?",s(b,"seq"),":",s(c,"seq")])},assign:function(a,b,c){a&&a!==!0?a+="=":a="=";return q([N(b),a,s(c,"seq")])},dot:function(a){var b=N(a),c=1;a[0]=="num"?/\./.test(a[1])||(b+="."):v(a)&&(b="("+b+")");while(c<arguments.length)b+="."+n(arguments[c++]);return b},call:function(a,b){var c=N(a);v(a)&&(c="("+c+")");return c+"("+r(H(b,function(a){return s(a,"seq")}))+")"},"function":C,defun:C,"if":function(a,b,c){var d=["if","("+N(a)+")",c?B(b):N(b)];c&&d.push("else",N(c));return q(d)},"for":function(a,b,c,d){var e=["for"];a=(a!=null?N(a):"").replace(/;*\s*$/,";"+l),b=(b!=null?N(b):"").replace(/;*\s*$/,";"+l),c=(c!=null?N(c):"").replace(/;*\s*$/,"");var f=a+b+c;f=="; ; "&&(f=";;"),e.push("("+f+")",N(d));return q(e)},"for-in":function(a,b,c,d){return q(["for","("+(a?N(a).replace(/;+$/,""):N(b)),"in",N(c)+")",N(d)])},"while":function(a,b){return q(["while","("+N(a)+")",N(b)])},"do":function(a,b){return q(["do",N(b),"while","("+N(a)+")"])+";"},"return":function(a){var b=["return"];a!=null&&b.push(N(a));return q(b)+";"},binary:function(a,b,c){var d=N(b),e=N(c);if(f(b[0],["assign","conditional","seq"])||b[0]=="binary"&&g[a]>g[b[1]])d="("+d+")";if(f(c[0],["assign","conditional","seq"])||c[0]=="binary"&&g[a]>=g[c[1]]&&(c[1]!=a||!f(a,["&&","||","*"])))e="("+e+")";return q([d,a,e])},"unary-prefix":function(a,b){var c=N(b);b[0]=="num"||b[0]=="unary-prefix"&&!G(h,a+b[1])||!v(b)||(c="("+c+")");return a+(d.is_alphanumeric_char(a.charAt(0))?" ":"")+c},"unary-postfix":function(a,b){var c=N(b);b[0]=="num"||b[0]=="unary-postfix"&&!G(h,a+b[1])||!v(b)||(c="("+c+")");return c+a},sub:function(a,b){var c=N(a);v(a)&&(c="("+c+")");return c+"["+N(b)+"]"},object:function(a){if(a.length==0)return"{}";return"{"+k+p(function(){return H(a,function(a){if(a.length==3)return o(C(a[0],a[1][2],a[1][3],a[2]));var d=a[0],e=N(a[1]);b.quote_keys?d=m(d):(typeof d=="number"||!c&&+d+""==d)&&parseFloat(d)>=0?d=w(+d):F(d)||(d=m(d));return o(q(c&&b.space_colon?[d,":",e]:[d+":",e]))}).join(","+k)})+k+o("}")},regexp:function(a,b){return"/"+a+"/"+b},array:function(a){if(a.length==0)return"[]";return q(["[",r(H(a,function(a){if(!c&&a[0]=="atom"&&a[1]=="undefined")return"";return s(a,"seq")})),"]"])},stat:function(a){return N(a).replace(/;*\s*$/,";")},seq:function(){return r(H(e(arguments),N))},label:function(a,b){return q([n(a),":",N(b)])},"with":function(a,b){return q(["with","("+N(a)+")",N(b)])},atom:function(a){return n(a)}},M=[];return N(a)}function A(a){return a.replace(/[\u0080-\uffff]/g,function(a){var b=a.charCodeAt(0).toString(16);while(b.length<4)b="0"+b;return"\\u"+b})}function z(a,b){var c=0,d=0;a=a.replace(/[\\\b\f\n\r\t\x22\x27\u2028\u2029]/g,function(a){switch(a){case"\\":return"\\\\";case"\b":return"\\b";case"\f":return"\\f";case"\n":return"\\n";case"\r":return"\\r";case"\t":return"\\t";case"\u2028":return"\\u2028";case"\u2029":return"\\u2029";case'"':++c;return'"';case"'":++d;return"'"}return a}),b&&(a=A(a));return c>d?"'"+a.replace(/\x27/g,"\\'")+"'":'"'+a.replace(/\x22/g,'\\"')+'"'}function x(a,b){function y(a,b){return v(a,function(a,c){if(!c){w(b);return["block"]}return["for",null,null,null,d(b)]})}function x(a,b,c){a=d(a),b=d(b),c=d(c),t(b)?(a=h(a),b=c,c=null):t(c)?c=null:function(){var d=B(a),e=h(a),f=B(e);if(f.length<d.length){var g=b;b=c,c=g,a=e}}();if(t(c)&&t(b))return["stat",a];var e=["if",a,b,c];b[0]=="if"&&t(b[3])&&t(c)?e=o(e,d(["if",["binary","&&",a,b[1]],b[2]])):b[0]=="stat"?c?c[0]=="stat"&&(e=o(e,["stat",s(a,b[1],c[1])])):e=o(e,["stat",s(a,b[1])]):c&&b[0]==c[0]&&(b[0]=="return"||b[0]=="throw")&&b[1]&&c[1]?e=o(e,[b[0],s(a,b[1],c[1])]):c&&q(b)?(e=[["if",a,b]],c[0]=="block"?c[1]&&(e=e.concat(c[1])):e.push(c),e=d(["block",e])):b&&q(c)&&(e=[["if",h(a),c]],b[0]=="block"?b[1]&&(e=e.concat(b[1])):e.push(b),e=d(["block",e]));return e}function u(a,b,c){return v(a,function(a,d){if(d){w(c);return b}w(b);return c},function(){return x(a,b,c)})}function n(a,c){a=a.reduce(function(a,b){b[0]=="block"?b[1]&&a.push.apply(a,b[1]):a.push(b);return a},[]),a=function(b,c){a.forEach(function(a){c&&(a[0]=="var"&&c[0]=="var"||a[0]=="const"&&c[0]=="const")?c[1]=c[1].concat(a[1]):(b.push(a),c=a)});return b}([]),b.dead_code&&(a=function(c,d){a.forEach(function(a){d?f(a[0],["function","defun","var","const"])?c.push(a):b.no_warnings||w(a):(c.push(a),f(a[0],["return","throw","break","continue"])&&(d=!0))});return c}([])),b.make_seqs&&(a=function(b,c){a.forEach(function(a){c&&c[0]=="stat"&&a[0]=="stat"?c[1]=["seq",c[1],a[1]]:(b.push(a),c=a)});return b}([])),c=="lambda"&&(a=function(b,c,d){while(b<a.length){d=a[b++];if(d[0]=="if"&&!d[3]){if(d[2][0]=="return"&&d[2][1]==null){c.push(u(h(d[1]),["block",a.slice(b)]));break}var e=p(d[2]);if(e[0]=="return"&&e[1]==null){c.push(u(d[1],["block",d[2][1].slice(0,-1)],["block",a.slice(b)]));break}}c.push(d)}return c}(0,[]));return a}function m(a,b,c){return[this[0],a,b,j(c.scope,function(){return n(H(c,d),"lambda")})]}function k(a){a!=null&&a[0]=="block"&&a[1]&&(a[1].length==1?a=a[1][0]:a[1].length==0&&(a=["block"]));return a}function j(a,b){var c=g;g=a;var d=b();d.scope=a,g=c;return d}function h(a){var c=["unary-prefix","!",a];switch(a[0]){case"unary-prefix":return a[1]=="!"&&r(a[2])?a[2]:c;case"seq":a=e(a),a[a.length-1]=h(a[a.length-1]);return a;case"conditional":return o(c,["conditional",a[1],h(a[2]),h(a[3])]);case"binary":var d=a[1],f=a[2],g=a[3];if(!b.keep_comps)switch(d){case"<=":return["binary",">",f,g];case"<":return["binary",">=",f,g];case">=":return["binary","<",f,g];case">":return["binary","<=",f,g]}switch(d){case"==":return["binary","!=",f,g];case"!=":return["binary","==",f,g];case"===":return["binary","!==",f,g];case"!==":return["binary","===",f,g];case"&&":return o(c,["binary","||",h(f),h(g)]);case"||":return o(c,["binary","&&",h(f),h(g)])}}return c}b=E(b,{make_seqs:!0,dead_code:!0,keep_comps:!0,no_warnings:!1});var c=i(),d=c.walk,g;return c.with_walkers({sub:function(a,b){if(b[0]=="string"){var c=b[1];if(F(c))return["dot",d(a),c];if(/^[1-9][0-9]*$/.test(c)||c==="0")return["sub",d(a),["num",parseInt(c,10)]]}},"if":u,toplevel:function(a){return["toplevel",j(this.scope,function(){return n(H(a,d))})]},"switch":function(a,b){var c=b.length-1;return["switch",d(a),H(b,function(a,b){var e=n(H(a[1],d));if(b==c&&e.length>0){var f=e[e.length-1];f[0]=="break"&&!f[1]&&e.pop()}return[a[0]?d(a[0]):null,e]})]},"function":function(){var a=m.apply(this,arguments);a[1]&&!G(g.refs,a[1])&&(a[1]=null);return a},defun:m,block:function(a){if(a)return k(["block",n(H(a,d))])},binary:function(a,b,c){return v(["binary",a,d(b),d(c)],function(a){return o(d(a),this)},function(){return this})},conditional:function(a,b,c){return s(d(a),d(b),d(c))},"try":function(a,b,c){return["try",n(H(a,d)),b!=null?[b[0],n(H(b[1],d))]:null,c!=null?n(H(c,d)):null]},"unary-prefix":function(a,b){b=d(b);var c=["unary-prefix",a,b];a=="!"&&(c=o(c,h(b)));return v(c,function(a,b){return d(a)},function(){return c})},name:function(a){switch(a){case"true":return["unary-prefix","!",["num",0]];case"false":return["unary-prefix","!",["num",1]]}},"new":function(a,b){if(a[0]=="name"&&a[1]=="Array"&&!g.has("Array"))return b.length!=1?["array",b]:["call",["name","Array"],b]},call:function(a,b){if(a[0]=="name"&&a[1]=="Array"&&b.length!=1&&!g.has("Array"))return["array",b]},"while":y,"do":y},function(){return d(l(a))})}function w(a){t(a)||n("Dropping unreachable code: "+B(a,!0))}function u(a){return a[0]=="string"||a[0]=="unary-prefix"&&a[1]=="typeof"||a[0]=="binary"&&a[1]=="+"&&(u(a[2])||u(a[3]))}function t(a){return!a||a[0]=="block"&&(!a[1]||a[1].length==0)}function s(a,b,c){return a[0]=="unary-prefix"&&a[1]=="!"?c?["conditional",a[2],c,b]:["binary","||",a[2],b]:c?["conditional",a,b,c]:["binary","&&",a,b]}function r(a){return a[0]=="unary-prefix"&&f(a[1],["!","delete"])||a[0]=="binary"&&f(a[1],["in","instanceof","==","!=","===","!==","<","<=",">=",">"])||a[0]=="binary"&&f(a[1],["&&","||"])&&r(a[2])&&r(a[3])||a[0]=="conditional"&&r(a[2])&&r(a[3])||a[0]=="assign"&&a[1]===!0&&r(a[3])||a[0]=="seq"&&r(a[a.length-1])}function q(a){if(a){a=p(a);if(a[0]=="return"||a[0]=="break"||a[0]=="continue"||a[0]=="throw")return!0}}function p(a){if(a[0]=="block"&&a[1]&&a[1].length>0)return a[1][a[1].length-1];return a}function o(a,b){return B(a).length>B(b[0]=="stat"?b[1]:b).length?b:a}function m(a,b){function k(a){return[this[0],H(a,function(a){return[g(a[0]),d(a[1])]})]}function j(a,b){var c=e;e=a;for(var d in a.names)G(a.names,d)&&g(d,!0);var f=b();f.scope=a,e=c;return f}function h(a,b,c){a&&(a=g(a)),c=j(c.scope,function(){b=H(b,function(a){return g(a)});return H(c,d)});return[this[0],a,b,c]}function g(a,c){if(!b.toplevel&&!e.parent)return a;if(b.except&&f(a,b.except))return a;return e.get_mangled(a,c)}var c=i(),d=c.walk,e;b=b||{};return c.with_walkers({"function":h,defun:function(){var a=h.apply(this,arguments);switch(c.parent()[0]){case"toplevel":case"function":case"defun":return H.at_top(a)}return a},"var":k,"const":k,name:function(a){return[this[0],g(a)]},"try":function(a,b,c){return[this[0],H(a,d),b!=null?[g(b[0]),H(b[1],d)]:null,c!=null?H(c,d):null]},toplevel:function(a){var b=this;return j(b.scope,function(){return[b[0],H(a,d)]})}},function(){return d(l(a))})}function l(a){function k(a,b,c){return[this[0],g(a),b,f(function(){H(b,g);return H(c,d)})]}function h(a){b.refs[a]=!0}function g(a){return b.define(a)}function f(a){b=new j(b);var c=b.body=a();c.scope=b,b=b.parent;return c}var b=null,c=i(),d=c.walk,e=[];return f(function(){function i(a,b){for(b=a.children.length;--b>=0;)i(a.children[b]);for(b in a.refs)if(G(a.refs,b))for(var c=a.has(b),d=a;d;d=d.parent){d.refs[b]=c;if(d===c)break}}var f=c.with_walkers({"function":k,defun:k,"with":function(a,c){for(var d=b;d;d=d.parent)d.uses_with=!0},"var":function(a){H(a,function(a){g(a[0])})},"const":function(a){H(a,function(a){g(a[0])})},"try":function(a,b,c){if(b!=null)return[this[0],H(a,d),[g(b[0]),H(b[1],d)],c!=null?H(c,d):null]},name:function(a){a=="eval"&&e.push(b),h(a)}},function(){return d(a)});H(e,function(a){if(!a.has("eval"))while(a)a.uses_eval=!0,a=a.parent}),i(b);return f})}function j(a){this.names={},this.mangled={},this.rev_mangled={},this.cname=-1,this.refs={},this.uses_with=!1,this.uses_eval=!1,this.parent=a,this.children=[],a?(this.level=a.level+1,a.children.push(this)):this.level=0}function i(a){function h(a,b){var c={},e;for(e in a)G(a,e)&&(c[e]=d[e],d[e]=a[e]);var f=b();for(e in c)G(c,e)&&(c[e]?d[e]=c[e]:delete d[e]);return f}function g(a){if(a==null)return null;try{f.push(a);var b=a[0],e=d[b];if(e){var g=e.apply(a,a.slice(1));if(g!=null)return g}e=c[b];return e.apply(a,a.slice(1))}finally{f.pop()}}function b(a){return[this[0],H(a,function(a){var b=[a[0]];a.length>1&&(b[1]=g(a[1]));return b})]}var c={string:function(a){return[this[0],a]},num:function(a){return[this[0],a]},name:function(a){return[this[0],a]},toplevel:function(a){return[this[0],H(a,g)]},block:function(a){var b=[this[0]];a!=null&&b.push(H(a,g));return b},"var":b,"const":b,"try":function(a,b,c){return[this[0],H(a,g),b!=null?[b[0],H(b[1],g)]:null,c!=null?H(c,g):null]},"throw":function(a){return[this[0],g(a)]},"new":function(a,b){return[this[0],g(a),H(b,g)]},"switch":function(a,b){return[this[0],g(a),H(b,function(a){return[a[0]?g(a[0]):null,H(a[1],g)]})]},"break":function(a){return[this[0],a]},"continue":function(a){return[this[0],a]},conditional:function(a,b,c){return[this[0],g(a),g(b),g(c)]},assign:function(a,b,c){return[this[0],a,g(b),g(c)]},dot:function(a){return[this[0],g(a)].concat(e(arguments,1))},call:function(a,b){return[this[0],g(a),H(b,g)]},"function":function(a,b,c){return[this[0],a,b.slice(),H(c,g)]},defun:function(a,b,c){return[this[0],a,b.slice(),H(c,g)]},"if":function(a,b,c){return[this[0],g(a),g(b),g(c)]},"for":function(a,b,c,d){return[this[0],g(a),g(b),g(c),g(d)]},"for-in":function(a,b,c,d){return[this[0],g(a),g(b),g(c),g(d)]},"while":function(a,b){return[this[0],g(a),g(b)]},"do":function(a,b){return[this[0],g(a),g(b)]},"return":function(a){return[this[0],g(a)]},binary:function(a,b,c){return[this[0],a,g(b),g(c)]},"unary-prefix":function(a,b){return[this[0],a,g(b)]},"unary-postfix":function(a,b){return[this[0],a,g(b)]},sub:function(a,b){return[this[0],g(a),g(b)]},object:function(a){return[this[0],H(a,function(a){return a.length==2?[a[0],g(a[1])]:[a[0],g(a[1]),a[2]]})]},regexp:function(a,b){return[this[0],a,b]},array:function(a){return[this[0],H(a,g)]},stat:function(a){return[this[0],g(a)]},seq:function(){return[this[0]].concat(H(e(arguments),g))},label:function(a,b){return[this[0],a,g(b)]},"with":function(a,b){return[this[0],g(a),g(b)]},atom:function(a){return[this[0],a]}},d={},f=[];return{walk:g,with_walkers:h,parent:function(){return f[f.length-2]},stack:function(){return f}}}var d=b("./parse-js"),e=d.slice,f=d.member,g=d.PRECEDENCE,h=d.OPERATORS,k=function(){var a="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$_";return function(b){var c="";do c=a.charAt(b%54)+c,b=Math.floor(b/54);while(b>0);return c}}();j.prototype={has:function(a){for(var b=this;b;b=b.parent)if(G(b.names,a))return b},has_mangled:function(a){for(var b=this;b;b=b.parent)if(G(b.rev_mangled,a))return b},toJSON:function(){return{names:this.names,uses_eval:this.uses_eval,uses_with:this.uses_with}},next_mangled:function(){for(;;){var a=k(++this.cname),b;b=this.has_mangled(a);if(b&&this.refs[b.rev_mangled[a]]===b)continue;b=this.has(a);if(b&&b!==this&&this.refs[a]===b&&!b.has_mangled(a))continue;if(G(this.refs,a)&&this.refs[a]==null)continue;if(!F(a))continue;return a}},get_mangled:function(a,b){if(this.uses_eval||this.uses_with)return a;var c=this.has(a);if(!c)return a;if(G(c.mangled,a))return c.mangled[a];if(!b)return a;var d=c.next_mangled();c.rev_mangled[d]=a;return c.mangled[a]=d},define:function(a){if(a!=null)return this.names[a]=a}};var n=function(){},v=function(){function b(c){switch(c[0]){case"string":case"num":return c[1];case"name":case"atom":switch(c[1]){case"true":return!0;case"false":return!1}break;case"unary-prefix":switch(c[1]){case"!":return!b(c[2]);case"typeof":return typeof b(c[2]);case"~":return~b(c[2]);case"-":return-b(c[2]);case"+":return+b(c[2])}break;case"binary":var d=c[2],e=c[3];switch(c[1]){case"&&":return b(d)&&b(e);case"||":return b(d)||b(e);case"|":return b(d)|b(e);case"&":return b(d)&b(e);case"^":return b(d)^b(e);case"+":return b(d)+b(e);case"*":return b(d)*b(e);case"/":return b(d)/b(e);case"-":return b(d)-b(e);case"<<":return b(d)<<b(e);case">>":return b(d)>>b(e);case">>>":return b(d)>>>b(e);case"==":return b(d)==b(e);case"===":return b(d)===b(e);case"!=":return b(d)!=b(e);case"!==":return b(d)!==b(e);case"<":return b(d)<b(e);case"<=":return b(d)<=b(e);case">":return b(d)>b(e);case">=":return b(d)>=b(e);case"in":return b(d)in b(e);case"instanceof":return b(d)instanceof b(e)}}throw a}var a={};return function(c,d,e){try{var f=b(c),g;switch(typeof f){case"string":g=["string",f];break;case"number":g=["num",f];break;case"boolean":g=["name",String(f)];break;default:throw new Error("Can't handle constant of type: "+typeof f)}return d.call(c,g,f)}catch(h){if(h===a){c[0]=="binary"&&(c[1]=="==="||c[1]=="!==")&&(u(c[2])&&u(c[3])||r(c[2])&&r(c[3]))&&(c[1]=c[1].substr(0,2));return e?e.call(c,c):null}throw h}}}(),y=d.array_to_hash(["name","array","object","string","dot","sub","call","regexp"]),H;(function(){function a(a){this.v=a}H=function(b,c,d){var e=[];for(var f=0;f<b.length;++f){var g=c.call(d,b[f],f);g instanceof a?e.unshift(g.v):e.push(g)}return e},H.at_top=function(b){return new a(b)}})(),a.ast_walker=i,a.ast_mangle=m,a.ast_squeeze=x,a.gen_code=B,a.ast_add_scope=l,a.set_logger=function(a){n=a},a.make_string=z,a.split_lines=C,a.MAP=H,a.ast_squeeze_more=b("./squeeze-more").ast_squeeze_more},"squeeze-more":function(a,b,c){function j(a){var b=e.ast_walker(),c=b.walk;return b.with_walkers({call:function(a,b){if(a[0]=="dot"&&a[2]=="toString"&&b.length==0)return["binary","+",a[1],["string",""]]}},function(){return c(a)})}var d=b("./parse-js"),e=b("./process"),f=d.slice,g=d.member,h=d.PRECEDENCE,i=d.OPERATORS;a.ast_squeeze_more=j}}),a.UglifyJS={},a.UglifyJS.parser=this.require("parse-js"),a.UglifyJS.uglify=this.require("process")}).call({},this)
@@ -16,16 +16,6 @@ describe "Uglifier" do
16
16
  }.should raise_error(Uglifier::Error)
17
17
  end
18
18
 
19
- it "logs to stderr" do
20
- $stderr.should_receive(:write).at_least(:once)
21
- lambda {
22
- Uglifier.new.compile("function uglifyThis() {
23
- return;
24
- return 1; // This is an error
25
- }")
26
- }.should_not raise_error(Uglifier::Error)
27
- end
28
-
29
19
  describe "Copyright Preservation" do
30
20
  before :all do
31
21
  @source = <<-EOS
data/uglifier.gemspec CHANGED
@@ -5,14 +5,12 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{uglifier}
8
- s.version = "0.4.0"
8
+ s.version = "0.5.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Ville Lautanala"]
12
- s.date = %q{2011-02-26}
13
- s.default_executable = %q{uglify}
12
+ s.date = %q{2011-04-07}
14
13
  s.email = %q{lautis@gmail.com}
15
- s.executables = ["uglify"]
16
14
  s.extra_rdoc_files = [
17
15
  "LICENSE.txt",
18
16
  "README.rdoc"
@@ -26,10 +24,9 @@ Gem::Specification.new do |s|
26
24
  "README.rdoc",
27
25
  "Rakefile",
28
26
  "VERSION",
29
- "bin/uglify",
27
+ "build.js",
30
28
  "lib/uglifier.rb",
31
- "lib/uglifier/cli.rb",
32
- "lib/uglifier/node.rb",
29
+ "lib/uglify.js",
33
30
  "spec/spec_helper.rb",
34
31
  "spec/uglifier_spec.rb",
35
32
  "uglifier.gemspec",
@@ -50,20 +47,23 @@ Gem::Specification.new do |s|
50
47
  s.specification_version = 3
51
48
 
52
49
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
53
- s.add_runtime_dependency(%q<therubyracer>, ["~> 0.8.0"])
50
+ s.add_runtime_dependency(%q<execjs>, ["~> 0.1.0"])
51
+ s.add_runtime_dependency(%q<json>, [">= 0"])
54
52
  s.add_development_dependency(%q<rspec>, ["~> 2.5.0"])
55
53
  s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
56
54
  s.add_development_dependency(%q<jeweler>, ["~> 1.5.0"])
57
55
  s.add_development_dependency(%q<rcov>, [">= 0"])
58
56
  else
59
- s.add_dependency(%q<therubyracer>, ["~> 0.8.0"])
57
+ s.add_dependency(%q<execjs>, ["~> 0.1.0"])
58
+ s.add_dependency(%q<json>, [">= 0"])
60
59
  s.add_dependency(%q<rspec>, ["~> 2.5.0"])
61
60
  s.add_dependency(%q<bundler>, ["~> 1.0.0"])
62
61
  s.add_dependency(%q<jeweler>, ["~> 1.5.0"])
63
62
  s.add_dependency(%q<rcov>, [">= 0"])
64
63
  end
65
64
  else
66
- s.add_dependency(%q<therubyracer>, ["~> 0.8.0"])
65
+ s.add_dependency(%q<execjs>, ["~> 0.1.0"])
66
+ s.add_dependency(%q<json>, [">= 0"])
67
67
  s.add_dependency(%q<rspec>, ["~> 2.5.0"])
68
68
  s.add_dependency(%q<bundler>, ["~> 1.0.0"])
69
69
  s.add_dependency(%q<jeweler>, ["~> 1.5.0"])
@@ -182,7 +182,6 @@ var OPERATORS = array_to_hash([
182
182
  ">>=",
183
183
  "<<=",
184
184
  ">>>=",
185
- "%=",
186
185
  "|=",
187
186
  "^=",
188
187
  "&=",
@@ -382,7 +381,7 @@ function tokenizer($TEXT) {
382
381
  if (ch == "+") return after_e;
383
382
  after_e = false;
384
383
  if (ch == ".") {
385
- if (!has_dot)
384
+ if (!has_dot && !has_x)
386
385
  return has_dot = true;
387
386
  return false;
388
387
  }
@@ -10,14 +10,13 @@
10
10
 
11
11
  Exported functions:
12
12
 
13
- - ast_mangle(ast, include_toplevel) -- mangles the
14
- variable/function names in the AST. Returns an AST. Pass true
15
- as second argument to mangle toplevel names too.
13
+ - ast_mangle(ast, options) -- mangles the variable/function names
14
+ in the AST. Returns an AST.
16
15
 
17
16
  - ast_squeeze(ast) -- employs various optimizations to make the
18
17
  final generated code even smaller. Returns an AST.
19
18
 
20
- - gen_code(ast, beautify) -- generates JS code from the AST. Pass
19
+ - gen_code(ast, options) -- generates JS code from the AST. Pass
21
20
  true (or an object, see the code for some options) as second
22
21
  argument to get "pretty" (indented) code.
23
22
 
@@ -256,8 +255,8 @@ function Scope(parent) {
256
255
  this.rev_mangled = {}; // reverse lookup (mangled => orig.name)
257
256
  this.cname = -1; // current mangled name
258
257
  this.refs = {}; // names referenced from this scope
259
- this.uses_with = false; // will become TRUE if eval() is detected in this or any subscopes
260
- this.uses_eval = false; // will become TRUE if with() is detected in this or any subscopes
258
+ this.uses_with = false; // will become TRUE if with() is detected in this or any subscopes
259
+ this.uses_eval = false; // will become TRUE if eval() is detected in this or any subscopes
261
260
  this.parent = parent; // parent scope
262
261
  this.children = []; // sub-scopes
263
262
  if (parent) {
@@ -936,9 +935,10 @@ function ast_squeeze(ast, options) {
936
935
  "sub": function(expr, subscript) {
937
936
  if (subscript[0] == "string") {
938
937
  var name = subscript[1];
939
- if (is_identifier(name)) {
938
+ if (is_identifier(name))
940
939
  return [ "dot", walk(expr), name ];
941
- }
940
+ else if (/^[1-9][0-9]*$/.test(name) || name === "0")
941
+ return [ "sub", walk(expr), [ "num", parseInt(name, 10) ] ];
942
942
  }
943
943
  },
944
944
  "if": make_if,
@@ -1029,6 +1029,7 @@ function ast_squeeze(ast, options) {
1029
1029
  var DOT_CALL_NO_PARENS = jsp.array_to_hash([
1030
1030
  "name",
1031
1031
  "array",
1032
+ "object",
1032
1033
  "string",
1033
1034
  "dot",
1034
1035
  "sub",
@@ -1036,9 +1037,9 @@ var DOT_CALL_NO_PARENS = jsp.array_to_hash([
1036
1037
  "regexp"
1037
1038
  ]);
1038
1039
 
1039
- function make_string(str) {
1040
+ function make_string(str, ascii_only) {
1040
1041
  var dq = 0, sq = 0;
1041
- str = str.replace(/[\\\b\f\n\r\t\x22\x27]/g, function(s){
1042
+ str = str.replace(/[\\\b\f\n\r\t\x22\x27\u2028\u2029]/g, function(s){
1042
1043
  switch (s) {
1043
1044
  case "\\": return "\\\\";
1044
1045
  case "\b": return "\\b";
@@ -1046,34 +1047,56 @@ function make_string(str) {
1046
1047
  case "\n": return "\\n";
1047
1048
  case "\r": return "\\r";
1048
1049
  case "\t": return "\\t";
1050
+ case "\u2028": return "\\u2028";
1051
+ case "\u2029": return "\\u2029";
1049
1052
  case '"': ++dq; return '"';
1050
1053
  case "'": ++sq; return "'";
1051
1054
  }
1052
1055
  return s;
1053
1056
  });
1054
- if (dq > sq) {
1055
- return "'" + str.replace(/\x27/g, "\\'") + "'";
1056
- } else {
1057
- return '"' + str.replace(/\x22/g, '\\"') + '"';
1058
- }
1057
+ if (ascii_only) str = to_ascii(str);
1058
+ if (dq > sq) return "'" + str.replace(/\x27/g, "\\'") + "'";
1059
+ else return '"' + str.replace(/\x22/g, '\\"') + '"';
1060
+ };
1061
+
1062
+ function to_ascii(str) {
1063
+ return str.replace(/[\u0080-\uffff]/g, function(ch) {
1064
+ var code = ch.charCodeAt(0).toString(16);
1065
+ while (code.length < 4) code = "0" + code;
1066
+ return "\\u" + code;
1067
+ });
1059
1068
  };
1060
1069
 
1061
- function gen_code(ast, beautify) {
1062
- if (beautify) beautify = defaults(beautify, {
1070
+ function gen_code(ast, options) {
1071
+ options = defaults(options, {
1063
1072
  indent_start : 0,
1064
1073
  indent_level : 4,
1065
1074
  quote_keys : false,
1066
- space_colon : false
1075
+ space_colon : false,
1076
+ beautify : false,
1077
+ ascii_only : false
1067
1078
  });
1079
+ var beautify = !!options.beautify;
1068
1080
  var indentation = 0,
1069
1081
  newline = beautify ? "\n" : "",
1070
1082
  space = beautify ? " " : "";
1071
1083
 
1084
+ function encode_string(str) {
1085
+ return make_string(str, options.ascii_only);
1086
+ };
1087
+
1088
+ function make_name(name) {
1089
+ name = name.toString();
1090
+ if (options.ascii_only)
1091
+ name = to_ascii(name);
1092
+ return name;
1093
+ };
1094
+
1072
1095
  function indent(line) {
1073
1096
  if (line == null)
1074
1097
  line = "";
1075
1098
  if (beautify)
1076
- line = repeat_string(" ", beautify.indent_start + indentation * beautify.indent_level) + line;
1099
+ line = repeat_string(" ", options.indent_start + indentation * options.indent_level) + line;
1077
1100
  return line;
1078
1101
  };
1079
1102
 
@@ -1127,7 +1150,7 @@ function gen_code(ast, beautify) {
1127
1150
  };
1128
1151
 
1129
1152
  function needs_parens(expr) {
1130
- if (expr[0] == "function") {
1153
+ if (expr[0] == "function" || expr[0] == "object") {
1131
1154
  // dot/call on a literal function requires the
1132
1155
  // function literal itself to be parenthesized
1133
1156
  // only if it's the first "thing" in a
@@ -1139,9 +1162,8 @@ function gen_code(ast, beautify) {
1139
1162
  var a = slice($stack), self = a.pop(), p = a.pop();
1140
1163
  while (p) {
1141
1164
  if (p[0] == "stat") return true;
1142
- if ((p[0] == "seq" && p[1] === self) ||
1143
- (p[0] == "call" && p[1] === self) ||
1144
- (p[0] == "binary" && p[2] === self)) {
1165
+ if (((p[0] == "seq" || p[0] == "call" || p[0] == "dot" || p[0] == "sub" || p[0] == "conditional") && p[1] === self) ||
1166
+ ((p[0] == "binary" || p[0] == "assign" || p[0] == "unary-postfix") && p[2] === self)) {
1145
1167
  self = p;
1146
1168
  p = a.pop();
1147
1169
  } else {
@@ -1168,7 +1190,7 @@ function gen_code(ast, beautify) {
1168
1190
  };
1169
1191
 
1170
1192
  var generators = {
1171
- "string": make_string,
1193
+ "string": encode_string,
1172
1194
  "num": make_num,
1173
1195
  "name": make_name,
1174
1196
  "toplevel": function(statements) {
@@ -1236,9 +1258,10 @@ function gen_code(ast, beautify) {
1236
1258
  },
1237
1259
  "dot": function(expr) {
1238
1260
  var out = make(expr), i = 1;
1239
- if (expr[0] == "num")
1240
- out += ".";
1241
- else if (needs_parens(expr))
1261
+ if (expr[0] == "num") {
1262
+ if (!/\./.test(expr[1]))
1263
+ out += ".";
1264
+ } else if (needs_parens(expr))
1242
1265
  out = "(" + out + ")";
1243
1266
  while (i < arguments.length)
1244
1267
  out += "." + make_name(arguments[i++]);
@@ -1333,15 +1356,15 @@ function gen_code(ast, beautify) {
1333
1356
  return indent(make_function(p[0], p[1][2], p[1][3], p[2]));
1334
1357
  }
1335
1358
  var key = p[0], val = make(p[1]);
1336
- if (beautify && beautify.quote_keys) {
1337
- key = make_string(key);
1359
+ if (options.quote_keys) {
1360
+ key = encode_string(key);
1338
1361
  } else if ((typeof key == "number" || !beautify && +key + "" == key)
1339
1362
  && parseFloat(key) >= 0) {
1340
1363
  key = make_num(+key);
1341
1364
  } else if (!is_identifier(key)) {
1342
- key = make_string(key);
1365
+ key = encode_string(key);
1343
1366
  }
1344
- return indent(add_spaces(beautify && beautify.space_colon
1367
+ return indent(add_spaces(beautify && options.space_colon
1345
1368
  ? [ key, ":", val ]
1346
1369
  : [ key + ":", val ]));
1347
1370
  }).join("," + newline);
@@ -1414,10 +1437,6 @@ function gen_code(ast, beautify) {
1414
1437
  return add_spaces([ out, make_block(body) ]);
1415
1438
  };
1416
1439
 
1417
- function make_name(name) {
1418
- return name.toString();
1419
- };
1420
-
1421
1440
  function make_block_statements(statements) {
1422
1441
  for (var a = [], last = statements.length - 1, i = 0; i <= last; ++i) {
1423
1442
  var stat = statements[i];
@@ -1467,7 +1486,7 @@ function gen_code(ast, beautify) {
1467
1486
  function make_1vardef(def) {
1468
1487
  var name = def[0], val = def[1];
1469
1488
  if (val != null)
1470
- name = add_spaces([ name, "=", make(val) ]);
1489
+ name = add_spaces([ make_name(name), "=", make(val) ]);
1471
1490
  return name;
1472
1491
  };
1473
1492
 
@@ -1588,7 +1607,10 @@ exports.ast_mangle = ast_mangle;
1588
1607
  exports.ast_squeeze = ast_squeeze;
1589
1608
  exports.gen_code = gen_code;
1590
1609
  exports.ast_add_scope = ast_add_scope;
1591
- exports.ast_squeeze_more = require("./squeeze-more").ast_squeeze_more;
1592
1610
  exports.set_logger = function(logger) { warn = logger };
1593
1611
  exports.make_string = make_string;
1594
1612
  exports.split_lines = split_lines;
1613
+ exports.MAP = MAP;
1614
+
1615
+ // keep this last!
1616
+ exports.ast_squeeze_more = require("./squeeze-more").ast_squeeze_more;
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: uglifier
3
3
  version: !ruby/object:Gem::Version
4
- hash: 15
4
+ hash: 11
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
- - 4
8
+ - 5
9
9
  - 0
10
- version: 0.4.0
10
+ version: 0.5.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Ville Lautanala
@@ -15,8 +15,8 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-02-26 00:00:00 +02:00
19
- default_executable: uglify
18
+ date: 2011-04-07 00:00:00 +03:00
19
+ default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
22
22
  prerelease: false
@@ -26,18 +26,32 @@ dependencies:
26
26
  requirements:
27
27
  - - ~>
28
28
  - !ruby/object:Gem::Version
29
- hash: 63
29
+ hash: 27
30
30
  segments:
31
31
  - 0
32
- - 8
32
+ - 1
33
33
  - 0
34
- version: 0.8.0
35
- name: therubyracer
34
+ version: 0.1.0
35
+ name: execjs
36
36
  version_requirements: *id001
37
37
  - !ruby/object:Gem::Dependency
38
38
  prerelease: false
39
- type: :development
39
+ type: :runtime
40
40
  requirement: &id002 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ hash: 3
46
+ segments:
47
+ - 0
48
+ version: "0"
49
+ name: json
50
+ version_requirements: *id002
51
+ - !ruby/object:Gem::Dependency
52
+ prerelease: false
53
+ type: :development
54
+ requirement: &id003 !ruby/object:Gem::Requirement
41
55
  none: false
42
56
  requirements:
43
57
  - - ~>
@@ -49,11 +63,11 @@ dependencies:
49
63
  - 0
50
64
  version: 2.5.0
51
65
  name: rspec
52
- version_requirements: *id002
66
+ version_requirements: *id003
53
67
  - !ruby/object:Gem::Dependency
54
68
  prerelease: false
55
69
  type: :development
56
- requirement: &id003 !ruby/object:Gem::Requirement
70
+ requirement: &id004 !ruby/object:Gem::Requirement
57
71
  none: false
58
72
  requirements:
59
73
  - - ~>
@@ -65,11 +79,11 @@ dependencies:
65
79
  - 0
66
80
  version: 1.0.0
67
81
  name: bundler
68
- version_requirements: *id003
82
+ version_requirements: *id004
69
83
  - !ruby/object:Gem::Dependency
70
84
  prerelease: false
71
85
  type: :development
72
- requirement: &id004 !ruby/object:Gem::Requirement
86
+ requirement: &id005 !ruby/object:Gem::Requirement
73
87
  none: false
74
88
  requirements:
75
89
  - - ~>
@@ -81,11 +95,11 @@ dependencies:
81
95
  - 0
82
96
  version: 1.5.0
83
97
  name: jeweler
84
- version_requirements: *id004
98
+ version_requirements: *id005
85
99
  - !ruby/object:Gem::Dependency
86
100
  prerelease: false
87
101
  type: :development
88
- requirement: &id005 !ruby/object:Gem::Requirement
102
+ requirement: &id006 !ruby/object:Gem::Requirement
89
103
  none: false
90
104
  requirements:
91
105
  - - ">="
@@ -95,11 +109,11 @@ dependencies:
95
109
  - 0
96
110
  version: "0"
97
111
  name: rcov
98
- version_requirements: *id005
112
+ version_requirements: *id006
99
113
  description:
100
114
  email: lautis@gmail.com
101
- executables:
102
- - uglify
115
+ executables: []
116
+
103
117
  extensions: []
104
118
 
105
119
  extra_rdoc_files:
@@ -114,10 +128,9 @@ files:
114
128
  - README.rdoc
115
129
  - Rakefile
116
130
  - VERSION
117
- - bin/uglify
131
+ - build.js
118
132
  - lib/uglifier.rb
119
- - lib/uglifier/cli.rb
120
- - lib/uglifier/node.rb
133
+ - lib/uglify.js
121
134
  - spec/spec_helper.rb
122
135
  - spec/uglifier_spec.rb
123
136
  - uglifier.gemspec
data/bin/uglify DELETED
@@ -1,6 +0,0 @@
1
- #!/usr/bin/env ruby
2
- $LOAD_PATH.unshift File.join(File.dirname(__FILE__), '..', 'lib')
3
- require 'uglifier'
4
- require 'uglifier/cli'
5
-
6
- exit Uglifier::Cli.run!
data/lib/uglifier/cli.rb DELETED
@@ -1,58 +0,0 @@
1
- require 'optparse'
2
-
3
- class Uglifier
4
- module Cli
5
- def self.run!
6
- options = {}
7
- OptionParser.new do |opts|
8
- opts.banner = "Usage: uglifier [options] file1 file2 ..."
9
-
10
- opts.on("-M", "--no-mangle", "Don't mangle variable names") do |m|
11
- options[:mangle] = m
12
- end
13
-
14
- opts.on("-t", "--toplevel", "Mangle top-level variable names") do |m|
15
- options[:toplevel] = m
16
- end
17
-
18
- opts.on("-S", "--no-squeeze", "Squeeze code resulting in smaller, but less-readable code") do |s|
19
- options[:squeeze] = s
20
- end
21
-
22
- opts.on("-Q", "--no-seqs", "Reduce consecutive statements in blocks into single statement") do |q|
23
- options[:seqs] = q
24
- end
25
-
26
- opts.on("-d", "--[no-]dead-code", "Remove dead code (e.g. after return)") do |d|
27
- options[:dead_code] = d
28
- end
29
-
30
- opts.on("-u", "--unsafe-optimizations", "Optimizations known to be unsafe in some situations") do |d|
31
- options[:unsafe] = d
32
- end
33
-
34
- opts.on("-C", "--no-copyright", "Omit copyright information") do |d|
35
- options[:copyright] = d
36
- end
37
-
38
- opts.on("-b", "--beautify", "Output indented code") do |d|
39
- options[:beautify] = d
40
- end
41
-
42
- opts.on("-v", "--verbose", "Run verbosely") do |v|
43
- options[:verbose] = v
44
- end
45
- end.parse!
46
-
47
- uglifier = Uglifier.new(options)
48
- if ARGV[0]
49
- ARGV.each do |f|
50
- puts uglifier.compile(File.open(f, 'r'))
51
- end
52
- else
53
- puts uglifier.compile($stdin)
54
- end
55
- true
56
- end
57
- end
58
- end
data/lib/uglifier/node.rb DELETED
@@ -1,24 +0,0 @@
1
- require "v8"
2
-
3
- class Uglifier
4
- class Node < V8::Context
5
- def initialize(*args, &blk)
6
- @exports = {}
7
- super(*args, &blk)
8
- end
9
- def require(file)
10
- old = self["exports"]
11
- self["exports"] = {}
12
- self["require"] = lambda {|r|
13
- @exports[File.basename(r, ".js")] || begin
14
- @exports[file] = self["exports"] # Prevent circular dependencies
15
- self.require(File.basename(r, ".js"))
16
- end
17
- }
18
- load(File.join(File.dirname(__FILE__), "..", "..", "vendor", "uglifyjs", "lib", File.basename(file, ".js") + ".js"))
19
- @exports[file] = self["exports"]
20
- self["exports"] = old
21
- @exports[file]
22
- end
23
- end
24
- end