1 var require = function (file, cwd) {
2 var resolved = require.resolve(file, cwd || '/');
3 var mod = require.modules[resolved];
4 if (!mod) throw new Error(
5 'Failed to resolve module ' + file + ', tried ' + resolved
7 var res = mod._cached ? mod._cached : mod();
10 var __require = require;
14 require.extensions = [".js",".coffee"];
16 require.resolve = (function () {
25 return function (x, cwd) {
28 if (core[x]) return x;
29 var path = require.modules.path();
32 if (x.match(/^(?:\.\.?\/|\/)/)) {
33 var m = loadAsFileSync(path.resolve(y, x))
34 || loadAsDirectorySync(path.resolve(y, x));
38 var n = loadNodeModulesSync(x, y);
41 throw new Error("Cannot find module '" + x + "'");
43 function loadAsFileSync (x) {
44 if (require.modules[x]) {
48 for (var i = 0; i < require.extensions.length; i++) {
49 var ext = require.extensions[i];
50 if (require.modules[x + ext]) return x + ext;
54 function loadAsDirectorySync (x) {
55 x = x.replace(/\/+$/, '');
56 var pkgfile = x + '/package.json';
57 if (require.modules[pkgfile]) {
58 var pkg = require.modules[pkgfile]();
59 var b = pkg.browserify;
60 if (typeof b === 'object' && b.main) {
61 var m = loadAsFileSync(path.resolve(x, b.main));
64 else if (typeof b === 'string') {
65 var m = loadAsFileSync(path.resolve(x, b));
69 var m = loadAsFileSync(path.resolve(x, pkg.main));
74 return loadAsFileSync(x + '/index');
77 function loadNodeModulesSync (x, start) {
78 var dirs = nodeModulesPathsSync(start);
79 for (var i = 0; i < dirs.length; i++) {
81 var m = loadAsFileSync(dir + '/' + x);
83 var n = loadAsDirectorySync(dir + '/' + x);
87 var m = loadAsFileSync(x);
91 function nodeModulesPathsSync (start) {
93 if (start === '/') parts = [ '' ];
94 else parts = path.normalize(start).split('/');
97 for (var i = parts.length - 1; i >= 0; i--) {
98 if (parts[i] === 'node_modules') continue;
99 var dir = parts.slice(0, i + 1).join('/') + '/node_modules';
108 require.alias = function (from, to) {
109 var path = require.modules.path();
112 res = require.resolve(from + '/package.json', '/');
115 res = require.resolve(from, '/');
117 var basedir = path.dirname(res);
119 var keys = Object_keys(require.modules);
121 for (var i = 0; i < keys.length; i++) {
123 if (key.slice(0, basedir.length + 1) === basedir + '/') {
124 var f = key.slice(basedir.length);
125 require.modules[to + f] = require.modules[basedir + f];
127 else if (key === basedir) {
128 require.modules[to] = require.modules[basedir];
133 var Object_keys = Object.keys || function (obj) {
135 for (var key in obj) res.push(key)
139 if (typeof process === 'undefined') process = {};
141 if (!process.nextTick) process.nextTick = function (fn) {
145 if (!process.title) process.title = 'browser';
147 if (!process.binding) process.binding = function (name) {
148 if (name === 'evals') return require('vm')
149 else throw new Error('No such module')
152 if (!process.cwd) process.cwd = function () { return '.' };
154 require.modules["path"] = function () {
155 var module = { exports : {} };
156 var exports = module.exports;
158 var __filename = "path";
160 var require = function (file) {
161 return __require(file, ".");
164 require.resolve = function (file) {
165 return __require.resolve(name, ".");
168 require.modules = __require.modules;
169 __require.modules["path"]._cached = module.exports;
172 function filter (xs, fn) {
174 for (var i = 0; i < xs.length; i++) {
175 if (fn(xs[i], i, xs)) res.push(xs[i]);
180 // resolves . and .. elements in a path array with directory names there
181 // must be no slashes, empty elements, or device names (c:\) in the array
182 // (so also no leading and trailing slashes - it does not distinguish
183 // relative and absolute paths)
184 function normalizeArray(parts, allowAboveRoot) {
185 // if the path tries to go above the root, `up` ends up > 0
187 for (var i = parts.length; i >= 0; i--) {
191 } else if (last === '..') {
200 // if the path is allowed to go above the root, restore leading ..s
201 if (allowAboveRoot) {
210 // Regex to split a filename into [*, dir, basename, ext]
212 var splitPathRe = /^(.+\/(?!$)|\/)?((?:.+?)?(\.[^.]*)?)$/;
214 // path.resolve([from ...], to)
216 exports.resolve = function() {
217 var resolvedPath = '',
218 resolvedAbsolute = false;
220 for (var i = arguments.length; i >= -1 && !resolvedAbsolute; i--) {
225 // Skip empty and invalid entries
226 if (typeof path !== 'string' || !path) {
230 resolvedPath = path + '/' + resolvedPath;
231 resolvedAbsolute = path.charAt(0) === '/';
234 // At this point the path should be resolved to a full absolute path, but
235 // handle relative paths to be safe (might happen when process.cwd() fails)
237 // Normalize the path
238 resolvedPath = normalizeArray(filter(resolvedPath.split('/'), function(p) {
240 }), !resolvedAbsolute).join('/');
242 return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.';
245 // path.normalize(path)
247 exports.normalize = function(path) {
248 var isAbsolute = path.charAt(0) === '/',
249 trailingSlash = path.slice(-1) === '/';
251 // Normalize the path
252 path = normalizeArray(filter(path.split('/'), function(p) {
254 }), !isAbsolute).join('/');
256 if (!path && !isAbsolute) {
259 if (path && trailingSlash) {
263 return (isAbsolute ? '/' : '') + path;
268 exports.join = function() {
269 var paths = Array.prototype.slice.call(arguments, 0);
270 return exports.normalize(filter(paths, function(p, index) {
271 return p && typeof p === 'string';
276 exports.dirname = function(path) {
277 var dir = splitPathRe.exec(path)[1] || '';
278 var isWindows = false;
282 } else if (dir.length === 1 ||
283 (isWindows && dir.length <= 3 && dir.charAt(1) === ':')) {
284 // It is just a slash or a drive letter with a slash
287 // It is a full dirname, strip trailing slash
288 return dir.substring(0, dir.length - 1);
293 exports.basename = function(path, ext) {
294 var f = splitPathRe.exec(path)[2] || '';
295 // TODO: make this comparison case-insensitive on windows?
296 if (ext && f.substr(-1 * ext.length) === ext) {
297 f = f.substr(0, f.length - ext.length);
303 exports.extname = function(path) {
304 return splitPathRe.exec(path)[3] || '';
307 }).call(module.exports);
309 __require.modules["path"]._cached = module.exports;
310 return module.exports;
313 require.modules["/node_modules/burrito/package.json"] = function () {
314 var module = { exports : {} };
315 var exports = module.exports;
316 var __dirname = "/node_modules/burrito";
317 var __filename = "/node_modules/burrito/package.json";
319 var require = function (file) {
320 return __require(file, "/node_modules/burrito");
323 require.resolve = function (file) {
324 return __require.resolve(name, "/node_modules/burrito");
327 require.modules = __require.modules;
328 __require.modules["/node_modules/burrito/package.json"]._cached = module.exports;
331 module.exports = {"name":"burrito","description":"Wrap up expressions with a trace function while walking the AST with rice and beans on the side","version":"0.2.8","repository":{"type":"git","url":"git://github.com/substack/node-burrito.git"},"main":"./index.js","keywords":["trace","ast","walk","syntax","source","tree","uglify"],"directories":{"lib":".","example":"example","test":"test"},"scripts":{"test":"expresso"},"dependencies":{"traverse":">=0.5.1 <0.6","uglify-js":"1.0.4"},"devDependencies":{"expresso":"=0.7.x"},"engines":{"node":">=0.4.0"},"license":"BSD","author":{"name":"James Halliday","email":"mail@substack.net","url":"http://substack.net"}};
332 }).call(module.exports);
334 __require.modules["/node_modules/burrito/package.json"]._cached = module.exports;
335 return module.exports;
338 require.modules["/node_modules/burrito/node_modules/uglify-js/package.json"] = function () {
339 var module = { exports : {} };
340 var exports = module.exports;
341 var __dirname = "/node_modules/burrito/node_modules/uglify-js";
342 var __filename = "/node_modules/burrito/node_modules/uglify-js/package.json";
344 var require = function (file) {
345 return __require(file, "/node_modules/burrito/node_modules/uglify-js");
348 require.resolve = function (file) {
349 return __require.resolve(name, "/node_modules/burrito/node_modules/uglify-js");
352 require.modules = __require.modules;
353 __require.modules["/node_modules/burrito/node_modules/uglify-js/package.json"]._cached = module.exports;
356 module.exports = {"name":"uglify-js","author":{"name":"Mihai Bazon","email":"mihai.bazon@gmail.com","url":"http://mihai.bazon.net/blog"},"version":"1.0.4","main":"./uglify-js.js","bin":{"uglifyjs":"./bin/uglifyjs"},"repository":{"type":"git","url":"git@github.com:mishoo/UglifyJS.git"}};
357 }).call(module.exports);
359 __require.modules["/node_modules/burrito/node_modules/uglify-js/package.json"]._cached = module.exports;
360 return module.exports;
363 require.modules["/node_modules/burrito/node_modules/uglify-js/uglify-js.js"] = function () {
364 var module = { exports : {} };
365 var exports = module.exports;
366 var __dirname = "/node_modules/burrito/node_modules/uglify-js";
367 var __filename = "/node_modules/burrito/node_modules/uglify-js/uglify-js.js";
369 var require = function (file) {
370 return __require(file, "/node_modules/burrito/node_modules/uglify-js");
373 require.resolve = function (file) {
374 return __require.resolve(name, "/node_modules/burrito/node_modules/uglify-js");
377 require.modules = __require.modules;
378 __require.modules["/node_modules/burrito/node_modules/uglify-js/uglify-js.js"]._cached = module.exports;
381 //convienence function(src, [options]);
382 function uglify(orig_code, options){
383 options || (options = {});
384 var jsp = uglify.parser;
385 var pro = uglify.uglify;
387 var ast = jsp.parse(orig_code, options.strict_semicolons); // parse code and get the initial AST
388 ast = pro.ast_mangle(ast, options.mangle_options); // get a new AST with mangled names
389 ast = pro.ast_squeeze(ast, options.squeeze_options); // get an AST with compression optimizations
390 var final_code = pro.gen_code(ast, options.gen_options); // compressed code here
394 uglify.parser = require("./lib/parse-js");
395 uglify.uglify = require("./lib/process");
397 module.exports = uglify;
398 }).call(module.exports);
400 __require.modules["/node_modules/burrito/node_modules/uglify-js/uglify-js.js"]._cached = module.exports;
401 return module.exports;
404 require.modules["/node_modules/burrito/node_modules/uglify-js/lib/parse-js.js"] = function () {
405 var module = { exports : {} };
406 var exports = module.exports;
407 var __dirname = "/node_modules/burrito/node_modules/uglify-js/lib";
408 var __filename = "/node_modules/burrito/node_modules/uglify-js/lib/parse-js.js";
410 var require = function (file) {
411 return __require(file, "/node_modules/burrito/node_modules/uglify-js/lib");
414 require.resolve = function (file) {
415 return __require.resolve(name, "/node_modules/burrito/node_modules/uglify-js/lib");
418 require.modules = __require.modules;
419 __require.modules["/node_modules/burrito/node_modules/uglify-js/lib/parse-js.js"]._cached = module.exports;
422 /***********************************************************************
424 A JavaScript tokenizer / parser / beautifier / compressor.
426 This version is suitable for Node.js. With minimal changes (the
427 exports stuff) it should work on any JS platform.
429 This file contains the tokenizer/parser. It is a port to JavaScript
430 of parse-js [1], a JavaScript parser library written in Common Lisp
431 by Marijn Haverbeke. Thank you Marijn!
433 [1] http://marijn.haverbeke.nl/parse-js/
437 - tokenizer(code) -- returns a function. Call the returned
438 function to fetch the next token.
440 - parse(code) -- returns an AST of the given JavaScript code.
442 -------------------------------- (C) ---------------------------------
445 <mihai.bazon@gmail.com>
446 http://mihai.bazon.net/blog
448 Distributed under the BSD license:
450 Copyright 2010 (c) Mihai Bazon <mihai.bazon@gmail.com>
451 Based on parse-js (http://marijn.haverbeke.nl/parse-js/).
453 Redistribution and use in source and binary forms, with or without
454 modification, are permitted provided that the following conditions
457 * Redistributions of source code must retain the above
458 copyright notice, this list of conditions and the following
461 * Redistributions in binary form must reproduce the above
462 copyright notice, this list of conditions and the following
463 disclaimer in the documentation and/or other materials
464 provided with the distribution.
466 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
467 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
468 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
469 PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
470 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
471 OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
472 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
473 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
474 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
475 TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
476 THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
479 ***********************************************************************/
481 /* -----[ Tokenizer (constants) ]----- */
483 var KEYWORDS = array_to_hash([
511 var RESERVED_WORDS = array_to_hash([
544 var KEYWORDS_BEFORE_EXPRESSION = array_to_hash([
553 var KEYWORDS_ATOM = array_to_hash([
560 var OPERATOR_CHARS = array_to_hash(characters("+-*&%=<>!?|~^"));
562 var RE_HEX_NUMBER = /^0x[0-9a-f]+$/i;
563 var RE_OCT_NUMBER = /^0[0-7]+$/;
564 var RE_DEC_NUMBER = /^\d*\.?\d*(?:e[+-]?\d*(?:\d\.?|\.?\d)\d*)?$/i;
566 var OPERATORS = array_to_hash([
613 var WHITESPACE_CHARS = array_to_hash(characters(" \u00a0\n\r\t\f\v\u200b"));
615 var PUNC_BEFORE_EXPRESSION = array_to_hash(characters("[{}(,.;:"));
617 var PUNC_CHARS = array_to_hash(characters("[]{}(),;:"));
619 var REGEXP_MODIFIERS = array_to_hash(characters("gmsiy"));
621 /* -----[ Tokenizer ]----- */
623 // regexps adapted from http://xregexp.com/plugins/#unicode
625 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]"),
626 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]"),
627 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]"),
628 connector_punctuation: new RegExp("[\\u005F\\u203F\\u2040\\u2054\\uFE33\\uFE34\\uFE4D-\\uFE4F\\uFF3F]")
631 function is_letter(ch) {
632 return UNICODE.letter.test(ch);
635 function is_digit(ch) {
636 ch = ch.charCodeAt(0);
637 return ch >= 48 && ch <= 57; //XXX: find out if "UnicodeDigit" means something else than 0..9
640 function is_alphanumeric_char(ch) {
641 return is_digit(ch) || is_letter(ch);
644 function is_unicode_combining_mark(ch) {
645 return UNICODE.non_spacing_mark.test(ch) || UNICODE.space_combining_mark.test(ch);
648 function is_unicode_connector_punctuation(ch) {
649 return UNICODE.connector_punctuation.test(ch);
652 function is_identifier_start(ch) {
653 return ch == "$" || ch == "_" || is_letter(ch);
656 function is_identifier_char(ch) {
657 return is_identifier_start(ch)
658 || is_unicode_combining_mark(ch)
660 || is_unicode_connector_punctuation(ch)
661 || ch == "\u200c" // zero-width non-joiner <ZWNJ>
662 || ch == "\u200d" // zero-width joiner <ZWJ> (in my ECMA-262 PDF, this is also 200c)
666 function parse_js_number(num) {
667 if (RE_HEX_NUMBER.test(num)) {
668 return parseInt(num.substr(2), 16);
669 } else if (RE_OCT_NUMBER.test(num)) {
670 return parseInt(num.substr(1), 8);
671 } else if (RE_DEC_NUMBER.test(num)) {
672 return parseFloat(num);
676 function JS_Parse_Error(message, line, col, pos) {
677 this.message = message;
684 this.stack = ex.stack;
688 JS_Parse_Error.prototype.toString = function() {
689 return this.message + " (line: " + this.line + ", col: " + this.col + ", pos: " + this.pos + ")" + "\n\n" + this.stack;
692 function js_error(message, line, col, pos) {
693 throw new JS_Parse_Error(message, line, col, pos);
696 function is_token(token, type, val) {
697 return token.type == type && (val == null || token.value == val);
702 function tokenizer($TEXT) {
705 text : $TEXT.replace(/\r\n?|[\n\u2028\u2029]/g, "\n").replace(/^\uFEFF/, ''),
712 newline_before : false,
713 regex_allowed : false,
717 function peek() { return S.text.charAt(S.pos); };
719 function next(signal_eof) {
720 var ch = S.text.charAt(S.pos++);
721 if (signal_eof && !ch)
724 S.newline_before = true;
737 function find(what, signal_eof) {
738 var pos = S.text.indexOf(what, S.pos);
739 if (signal_eof && pos == -1) throw EX_EOF;
743 function start_token() {
749 function token(type, value, is_comment) {
750 S.regex_allowed = ((type == "operator" && !HOP(UNARY_POSTFIX, value)) ||
751 (type == "keyword" && HOP(KEYWORDS_BEFORE_EXPRESSION, value)) ||
752 (type == "punc" && HOP(PUNC_BEFORE_EXPRESSION, value)));
759 nlb : S.newline_before
762 ret.comments_before = S.comments_before;
763 S.comments_before = [];
765 S.newline_before = false;
769 function skip_whitespace() {
770 while (HOP(WHITESPACE_CHARS, peek()))
774 function read_while(pred) {
775 var ret = "", ch = peek(), i = 0;
776 while (ch && pred(ch, i++)) {
783 function parse_error(err) {
784 js_error(err, S.tokline, S.tokcol, S.tokpos);
787 function read_num(prefix) {
788 var has_e = false, after_e = false, has_x = false, has_dot = prefix == ".";
789 var num = read_while(function(ch, i){
790 if (ch == "x" || ch == "X") {
791 if (has_x) return false;
794 if (!has_x && (ch == "E" || ch == "e")) {
795 if (has_e) return false;
796 return has_e = after_e = true;
799 if (after_e || (i == 0 && !prefix)) return true;
802 if (ch == "+") return after_e;
805 if (!has_dot && !has_x)
806 return has_dot = true;
809 return is_alphanumeric_char(ch);
813 var valid = parse_js_number(num);
815 return token("num", valid);
817 parse_error("Invalid syntax: " + num);
821 function read_escaped_char() {
824 case "n" : return "\n";
825 case "r" : return "\r";
826 case "t" : return "\t";
827 case "b" : return "\b";
828 case "v" : return "\v";
829 case "f" : return "\f";
830 case "0" : return "\0";
831 case "x" : return String.fromCharCode(hex_bytes(2));
832 case "u" : return String.fromCharCode(hex_bytes(4));
837 function hex_bytes(n) {
840 var digit = parseInt(next(true), 16);
842 parse_error("Invalid hex-character pattern in string");
843 num = (num << 4) | digit;
848 function read_string() {
849 return with_eof_error("Unterminated string constant", function(){
850 var quote = next(), ret = "";
853 if (ch == "\\") ch = read_escaped_char();
854 else if (ch == quote) break;
857 return token("string", ret);
861 function read_line_comment() {
863 var i = find("\n"), ret;
865 ret = S.text.substr(S.pos);
866 S.pos = S.text.length;
868 ret = S.text.substring(S.pos, i);
871 return token("comment1", ret, true);
874 function read_multiline_comment() {
876 return with_eof_error("Unterminated multiline comment", function(){
877 var i = find("*/", true),
878 text = S.text.substring(S.pos, i),
879 tok = token("comment2", text, true);
881 S.line += text.split("\n").length - 1;
882 S.newline_before = text.indexOf("\n") >= 0;
884 // https://github.com/mishoo/UglifyJS/issues/#issue/100
885 if (/^@cc_on/i.test(text)) {
886 warn("WARNING: at line " + S.line);
887 warn("*** Found \"conditional comment\": " + text);
888 warn("*** UglifyJS DISCARDS ALL COMMENTS. This means your code might no longer work properly in Internet Explorer.");
895 function read_name() {
896 var backslash = false, name = "", ch;
897 while ((ch = peek()) != null) {
899 if (ch == "\\") backslash = true, next();
900 else if (is_identifier_char(ch)) name += next();
904 if (ch != "u") parse_error("Expecting UnicodeEscapeSequence -- uXXXX");
905 ch = read_escaped_char();
906 if (!is_identifier_char(ch)) parse_error("Unicode char: " + ch.charCodeAt(0) + " is not valid in identifier");
914 function read_regexp() {
915 return with_eof_error("Unterminated regular expression", function(){
916 var prev_backslash = false, regexp = "", ch, in_class = false;
917 while ((ch = next(true))) if (prev_backslash) {
919 prev_backslash = false;
920 } else if (ch == "[") {
923 } else if (ch == "]" && in_class) {
926 } else if (ch == "/" && !in_class) {
928 } else if (ch == "\\") {
929 prev_backslash = true;
933 var mods = read_name();
934 return token("regexp", [ regexp, mods ]);
938 function read_operator(prefix) {
940 if (!peek()) return op;
941 var bigger = op + peek();
942 if (HOP(OPERATORS, bigger)) {
949 return token("operator", grow(prefix || next()));
952 function handle_slash() {
954 var regex_allowed = S.regex_allowed;
957 S.comments_before.push(read_line_comment());
958 S.regex_allowed = regex_allowed;
961 S.comments_before.push(read_multiline_comment());
962 S.regex_allowed = regex_allowed;
965 return S.regex_allowed ? read_regexp() : read_operator("/");
968 function handle_dot() {
970 return is_digit(peek())
972 : token("punc", ".");
975 function read_word() {
976 var word = read_name();
977 return !HOP(KEYWORDS, word)
978 ? token("name", word)
979 : HOP(OPERATORS, word)
980 ? token("operator", word)
981 : HOP(KEYWORDS_ATOM, word)
982 ? token("atom", word)
983 : token("keyword", word);
986 function with_eof_error(eof_error, cont) {
990 if (ex === EX_EOF) parse_error(eof_error);
995 function next_token(force_regexp) {
997 return read_regexp();
1001 if (!ch) return token("eof");
1002 if (is_digit(ch)) return read_num();
1003 if (ch == '"' || ch == "'") return read_string();
1004 if (HOP(PUNC_CHARS, ch)) return token("punc", next());
1005 if (ch == ".") return handle_dot();
1006 if (ch == "/") return handle_slash();
1007 if (HOP(OPERATOR_CHARS, ch)) return read_operator();
1008 if (ch == "\\" || is_identifier_start(ch)) return read_word();
1009 parse_error("Unexpected character '" + ch + "'");
1012 next_token.context = function(nc) {
1021 /* -----[ Parser (constants) ]----- */
1023 var UNARY_PREFIX = array_to_hash([
1035 var UNARY_POSTFIX = array_to_hash([ "--", "++" ]);
1037 var ASSIGNMENT = (function(a, ret, i){
1038 while (i < a.length) {
1039 ret[a[i]] = a[i].substr(0, a[i].length - 1);
1044 ["+=", "-=", "/=", "*=", "%=", ">>=", "<<=", ">>>=", "|=", "^=", "&="],
1049 var PRECEDENCE = (function(a, ret){
1050 for (var i = 0, n = 1; i < a.length; ++i, ++n) {
1052 for (var j = 0; j < b.length; ++j) {
1064 ["==", "===", "!=", "!=="],
1065 ["<", ">", "<=", ">=", "in", "instanceof"],
1066 [">>", "<<", ">>>"],
1073 var STATEMENTS_WITH_LABELS = array_to_hash([ "for", "do", "while", "switch" ]);
1075 var ATOMIC_START_TOKEN = array_to_hash([ "atom", "num", "string", "regexp", "name" ]);
1077 /* -----[ Parser ]----- */
1079 function NodeWithToken(str, start, end) {
1085 NodeWithToken.prototype.toString = function() { return this.name; };
1087 function parse($TEXT, exigent_mode, embed_tokens) {
1090 input : typeof $TEXT == "string" ? tokenizer($TEXT, true) : $TEXT,
1101 function is(type, value) {
1102 return is_token(S.token, type, value);
1105 function peek() { return S.peeked || (S.peeked = S.input()); };
1113 S.token = S.input();
1122 function croak(msg, line, col, pos) {
1123 var ctx = S.input.context();
1125 line != null ? line : ctx.tokline,
1126 col != null ? col : ctx.tokcol,
1127 pos != null ? pos : ctx.tokpos);
1130 function token_error(token, msg) {
1131 croak(msg, token.line, token.col);
1134 function unexpected(token) {
1137 token_error(token, "Unexpected token: " + token.type + " (" + token.value + ")");
1140 function expect_token(type, val) {
1141 if (is(type, val)) {
1144 token_error(S.token, "Unexpected token " + S.token.type + ", expected " + type);
1147 function expect(punc) { return expect_token("punc", punc); };
1149 function can_insert_semicolon() {
1150 return !exigent_mode && (
1151 S.token.nlb || is("eof") || is("punc", "}")
1155 function semicolon() {
1156 if (is("punc", ";")) next();
1157 else if (!can_insert_semicolon()) unexpected();
1161 return slice(arguments);
1164 function parenthesised() {
1166 var ex = expression();
1171 function add_tokens(str, start, end) {
1172 return str instanceof NodeWithToken ? str : new NodeWithToken(str, start, end);
1175 function maybe_embed_tokens(parser) {
1176 if (embed_tokens) return function() {
1177 var start = S.token;
1178 var ast = parser.apply(this, arguments);
1179 ast[0] = add_tokens(ast[0], start, prev());
1185 var statement = maybe_embed_tokens(function() {
1186 if (is("operator", "/")) {
1188 S.token = S.input(true); // force regexp
1190 switch (S.token.type) {
1196 return simple_statement();
1199 return is_token(peek(), "punc", ":")
1200 ? labeled_statement(prog1(S.token.value, next, next))
1201 : simple_statement();
1204 switch (S.token.value) {
1206 return as("block", block_());
1209 return simple_statement();
1218 switch (prog1(S.token.value, next)) {
1220 return break_cont("break");
1223 return break_cont("continue");
1227 return as("debugger");
1230 return (function(body){
1231 expect_token("keyword", "while");
1232 return as("do", prog1(parenthesised, semicolon), body);
1233 })(in_loop(statement));
1239 return function_(true);
1245 if (S.in_function == 0)
1246 croak("'return' outside of function");
1250 : can_insert_semicolon()
1252 : prog1(expression, semicolon));
1255 return as("switch", parenthesised(), switch_block_());
1258 return as("throw", prog1(expression, semicolon));
1264 return prog1(var_, semicolon);
1267 return prog1(const_, semicolon);
1270 return as("while", parenthesised(), in_loop(statement));
1273 return as("with", parenthesised(), statement());
1281 function labeled_statement(label) {
1282 S.labels.push(label);
1283 var start = S.token, stat = statement();
1284 if (exigent_mode && !HOP(STATEMENTS_WITH_LABELS, stat[0]))
1287 return as("label", label, stat);
1290 function simple_statement() {
1291 return as("stat", prog1(expression, semicolon));
1294 function break_cont(type) {
1296 if (!can_insert_semicolon()) {
1297 name = is("name") ? S.token.value : null;
1301 if (!member(name, S.labels))
1302 croak("Label " + name + " without matching loop or statement");
1304 else if (S.in_loop == 0)
1305 croak(type + " not inside a loop or switch");
1307 return as(type, name);
1313 if (!is("punc", ";")) {
1314 init = is("keyword", "var")
1315 ? (next(), var_(true))
1316 : expression(true, true);
1317 if (is("operator", "in"))
1318 return for_in(init);
1320 return regular_for(init);
1323 function regular_for(init) {
1325 var test = is("punc", ";") ? null : expression();
1327 var step = is("punc", ")") ? null : expression();
1329 return as("for", init, test, step, in_loop(statement));
1332 function for_in(init) {
1333 var lhs = init[0] == "var" ? as("name", init[1][0]) : init;
1335 var obj = expression();
1337 return as("for-in", init, lhs, obj, in_loop(statement));
1340 var function_ = maybe_embed_tokens(function(in_statement) {
1341 var name = is("name") ? prog1(S.token.value, next) : null;
1342 if (in_statement && !name)
1345 return as(in_statement ? "defun" : "function",
1348 (function(first, a){
1349 while (!is("punc", ")")) {
1350 if (first) first = false; else expect(",");
1351 if (!is("name")) unexpected();
1352 a.push(S.token.value);
1361 var loop = S.in_loop;
1371 var cond = parenthesised(), body = statement(), belse;
1372 if (is("keyword", "else")) {
1374 belse = statement();
1376 return as("if", cond, body, belse);
1382 while (!is("punc", "}")) {
1383 if (is("eof")) unexpected();
1384 a.push(statement());
1390 var switch_block_ = curry(in_loop, function(){
1392 var a = [], cur = null;
1393 while (!is("punc", "}")) {
1394 if (is("eof")) unexpected();
1395 if (is("keyword", "case")) {
1398 a.push([ expression(), cur ]);
1401 else if (is("keyword", "default")) {
1405 a.push([ null, cur ]);
1408 if (!cur) unexpected();
1409 cur.push(statement());
1417 var body = block_(), bcatch, bfinally;
1418 if (is("keyword", "catch")) {
1422 croak("Name expected");
1423 var name = S.token.value;
1426 bcatch = [ name, block_() ];
1428 if (is("keyword", "finally")) {
1430 bfinally = block_();
1432 if (!bcatch && !bfinally)
1433 croak("Missing catch/finally blocks");
1434 return as("try", body, bcatch, bfinally);
1437 function vardefs(no_in) {
1442 var name = S.token.value;
1444 if (is("operator", "=")) {
1446 a.push([ name, expression(false, no_in) ]);
1450 if (!is("punc", ","))
1457 function var_(no_in) {
1458 return as("var", vardefs(no_in));
1462 return as("const", vardefs());
1466 var newexp = expr_atom(false), args;
1467 if (is("punc", "(")) {
1469 args = expr_list(")");
1473 return subscripts(as("new", newexp, args), true);
1476 var expr_atom = maybe_embed_tokens(function(allow_calls) {
1477 if (is("operator", "new")) {
1481 if (is("operator") && HOP(UNARY_PREFIX, S.token.value)) {
1482 return make_unary("unary-prefix",
1483 prog1(S.token.value, next),
1484 expr_atom(allow_calls));
1487 switch (S.token.value) {
1490 return subscripts(prog1(expression, curry(expect, ")")), allow_calls);
1493 return subscripts(array_(), allow_calls);
1496 return subscripts(object_(), allow_calls);
1500 if (is("keyword", "function")) {
1502 return subscripts(function_(false), allow_calls);
1504 if (HOP(ATOMIC_START_TOKEN, S.token.type)) {
1505 var atom = S.token.type == "regexp"
1506 ? as("regexp", S.token.value[0], S.token.value[1])
1507 : as(S.token.type, S.token.value);
1508 return subscripts(prog1(atom, next), allow_calls);
1513 function expr_list(closing, allow_trailing_comma, allow_empty) {
1514 var first = true, a = [];
1515 while (!is("punc", closing)) {
1516 if (first) first = false; else expect(",");
1517 if (allow_trailing_comma && is("punc", closing)) break;
1518 if (is("punc", ",") && allow_empty) {
1519 a.push([ "atom", "undefined" ]);
1521 a.push(expression(false));
1529 return as("array", expr_list("]", !exigent_mode, true));
1532 function object_() {
1533 var first = true, a = [];
1534 while (!is("punc", "}")) {
1535 if (first) first = false; else expect(",");
1536 if (!exigent_mode && is("punc", "}"))
1537 // allow trailing comma
1539 var type = S.token.type;
1540 var name = as_property_name();
1541 if (type == "name" && (name == "get" || name == "set") && !is("punc", ":")) {
1542 a.push([ as_name(), function_(false), name ]);
1545 a.push([ name, expression(false) ]);
1549 return as("object", a);
1552 function as_property_name() {
1553 switch (S.token.type) {
1556 return prog1(S.token.value, next);
1561 function as_name() {
1562 switch (S.token.type) {
1567 return prog1(S.token.value, next);
1573 function subscripts(expr, allow_calls) {
1574 if (is("punc", ".")) {
1576 return subscripts(as("dot", expr, as_name()), allow_calls);
1578 if (is("punc", "[")) {
1580 return subscripts(as("sub", expr, prog1(expression, curry(expect, "]"))), allow_calls);
1582 if (allow_calls && is("punc", "(")) {
1584 return subscripts(as("call", expr, expr_list(")")), true);
1586 if (allow_calls && is("operator") && HOP(UNARY_POSTFIX, S.token.value)) {
1587 return prog1(curry(make_unary, "unary-postfix", S.token.value, expr),
1593 function make_unary(tag, op, expr) {
1594 if ((op == "++" || op == "--") && !is_assignable(expr))
1595 croak("Invalid use of " + op + " operator");
1596 return as(tag, op, expr);
1599 function expr_op(left, min_prec, no_in) {
1600 var op = is("operator") ? S.token.value : null;
1601 if (op && op == "in" && no_in) op = null;
1602 var prec = op != null ? PRECEDENCE[op] : null;
1603 if (prec != null && prec > min_prec) {
1605 var right = expr_op(expr_atom(true), prec, no_in);
1606 return expr_op(as("binary", op, left, right), min_prec, no_in);
1611 function expr_ops(no_in) {
1612 return expr_op(expr_atom(true), 0, no_in);
1615 function maybe_conditional(no_in) {
1616 var expr = expr_ops(no_in);
1617 if (is("operator", "?")) {
1619 var yes = expression(false);
1621 return as("conditional", expr, yes, expression(false, no_in));
1626 function is_assignable(expr) {
1627 if (!exigent_mode) return true;
1635 return expr[1] != "this";
1639 function maybe_assign(no_in) {
1640 var left = maybe_conditional(no_in), val = S.token.value;
1641 if (is("operator") && HOP(ASSIGNMENT, val)) {
1642 if (is_assignable(left)) {
1644 return as("assign", ASSIGNMENT[val], left, maybe_assign(no_in));
1646 croak("Invalid assignment");
1651 var expression = maybe_embed_tokens(function(commas, no_in) {
1652 if (arguments.length == 0)
1654 var expr = maybe_assign(no_in);
1655 if (commas && is("punc", ",")) {
1657 return as("seq", expr, expression(true, no_in));
1662 function in_loop(cont) {
1671 return as("toplevel", (function(a){
1673 a.push(statement());
1679 /* -----[ Utilities ]----- */
1682 var args = slice(arguments, 1);
1683 return function() { return f.apply(this, args.concat(slice(arguments))); };
1686 function prog1(ret) {
1687 if (ret instanceof Function)
1689 for (var i = 1, n = arguments.length; --n > 0; ++i)
1694 function array_to_hash(a) {
1696 for (var i = 0; i < a.length; ++i)
1701 function slice(a, start) {
1702 return Array.prototype.slice.call(a, start == null ? 0 : start);
1705 function characters(str) {
1706 return str.split("");
1709 function member(name, array) {
1710 for (var i = array.length; --i >= 0;)
1711 if (array[i] === name)
1716 function HOP(obj, prop) {
1717 return Object.prototype.hasOwnProperty.call(obj, prop);
1720 var warn = function() {};
1722 /* -----[ Exports ]----- */
1724 exports.tokenizer = tokenizer;
1725 exports.parse = parse;
1726 exports.slice = slice;
1727 exports.curry = curry;
1728 exports.member = member;
1729 exports.array_to_hash = array_to_hash;
1730 exports.PRECEDENCE = PRECEDENCE;
1731 exports.KEYWORDS_ATOM = KEYWORDS_ATOM;
1732 exports.RESERVED_WORDS = RESERVED_WORDS;
1733 exports.KEYWORDS = KEYWORDS;
1734 exports.ATOMIC_START_TOKEN = ATOMIC_START_TOKEN;
1735 exports.OPERATORS = OPERATORS;
1736 exports.is_alphanumeric_char = is_alphanumeric_char;
1737 exports.set_logger = function(logger) {
1741 }).call(module.exports);
1743 __require.modules["/node_modules/burrito/node_modules/uglify-js/lib/parse-js.js"]._cached = module.exports;
1744 return module.exports;
1747 require.modules["/node_modules/burrito/node_modules/uglify-js/lib/process.js"] = function () {
1748 var module = { exports : {} };
1749 var exports = module.exports;
1750 var __dirname = "/node_modules/burrito/node_modules/uglify-js/lib";
1751 var __filename = "/node_modules/burrito/node_modules/uglify-js/lib/process.js";
1753 var require = function (file) {
1754 return __require(file, "/node_modules/burrito/node_modules/uglify-js/lib");
1757 require.resolve = function (file) {
1758 return __require.resolve(name, "/node_modules/burrito/node_modules/uglify-js/lib");
1761 require.modules = __require.modules;
1762 __require.modules["/node_modules/burrito/node_modules/uglify-js/lib/process.js"]._cached = module.exports;
1765 /***********************************************************************
1767 A JavaScript tokenizer / parser / beautifier / compressor.
1769 This version is suitable for Node.js. With minimal changes (the
1770 exports stuff) it should work on any JS platform.
1772 This file implements some AST processors. They work on data built
1777 - ast_mangle(ast, options) -- mangles the variable/function names
1778 in the AST. Returns an AST.
1780 - ast_squeeze(ast) -- employs various optimizations to make the
1781 final generated code even smaller. Returns an AST.
1783 - gen_code(ast, options) -- generates JS code from the AST. Pass
1784 true (or an object, see the code for some options) as second
1785 argument to get "pretty" (indented) code.
1787 -------------------------------- (C) ---------------------------------
1790 <mihai.bazon@gmail.com>
1791 http://mihai.bazon.net/blog
1793 Distributed under the BSD license:
1795 Copyright 2010 (c) Mihai Bazon <mihai.bazon@gmail.com>
1797 Redistribution and use in source and binary forms, with or without
1798 modification, are permitted provided that the following conditions
1801 * Redistributions of source code must retain the above
1802 copyright notice, this list of conditions and the following
1805 * Redistributions in binary form must reproduce the above
1806 copyright notice, this list of conditions and the following
1807 disclaimer in the documentation and/or other materials
1808 provided with the distribution.
1810 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
1811 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1812 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
1813 PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
1814 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
1815 OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
1816 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
1817 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
1818 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
1819 TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
1820 THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1823 ***********************************************************************/
1825 var jsp = require("./parse-js"),
1827 member = jsp.member,
1828 PRECEDENCE = jsp.PRECEDENCE,
1829 OPERATORS = jsp.OPERATORS;
1831 /* -----[ helper for AST traversal ]----- */
1833 function ast_walker(ast) {
1834 function _vardefs(defs) {
1835 return [ this[0], MAP(defs, function(def){
1838 a[1] = walk(def[1]);
1842 function _block(statements) {
1843 var out = [ this[0] ];
1844 if (statements != null)
1845 out.push(MAP(statements, walk));
1849 "string": function(str) {
1850 return [ this[0], str ];
1852 "num": function(num) {
1853 return [ this[0], num ];
1855 "name": function(name) {
1856 return [ this[0], name ];
1858 "toplevel": function(statements) {
1859 return [ this[0], MAP(statements, walk) ];
1865 "try": function(t, c, f) {
1869 c != null ? [ c[0], MAP(c[1], walk) ] : null,
1870 f != null ? MAP(f, walk) : null
1873 "throw": function(expr) {
1874 return [ this[0], walk(expr) ];
1876 "new": function(ctor, args) {
1877 return [ this[0], walk(ctor), MAP(args, walk) ];
1879 "switch": function(expr, body) {
1880 return [ this[0], walk(expr), MAP(body, function(branch){
1881 return [ branch[0] ? walk(branch[0]) : null,
1882 MAP(branch[1], walk) ];
1885 "break": function(label) {
1886 return [ this[0], label ];
1888 "continue": function(label) {
1889 return [ this[0], label ];
1891 "conditional": function(cond, t, e) {
1892 return [ this[0], walk(cond), walk(t), walk(e) ];
1894 "assign": function(op, lvalue, rvalue) {
1895 return [ this[0], op, walk(lvalue), walk(rvalue) ];
1897 "dot": function(expr) {
1898 return [ this[0], walk(expr) ].concat(slice(arguments, 1));
1900 "call": function(expr, args) {
1901 return [ this[0], walk(expr), MAP(args, walk) ];
1903 "function": function(name, args, body) {
1904 return [ this[0], name, args.slice(), MAP(body, walk) ];
1906 "defun": function(name, args, body) {
1907 return [ this[0], name, args.slice(), MAP(body, walk) ];
1909 "if": function(conditional, t, e) {
1910 return [ this[0], walk(conditional), walk(t), walk(e) ];
1912 "for": function(init, cond, step, block) {
1913 return [ this[0], walk(init), walk(cond), walk(step), walk(block) ];
1915 "for-in": function(vvar, key, hash, block) {
1916 return [ this[0], walk(vvar), walk(key), walk(hash), walk(block) ];
1918 "while": function(cond, block) {
1919 return [ this[0], walk(cond), walk(block) ];
1921 "do": function(cond, block) {
1922 return [ this[0], walk(cond), walk(block) ];
1924 "return": function(expr) {
1925 return [ this[0], walk(expr) ];
1927 "binary": function(op, left, right) {
1928 return [ this[0], op, walk(left), walk(right) ];
1930 "unary-prefix": function(op, expr) {
1931 return [ this[0], op, walk(expr) ];
1933 "unary-postfix": function(op, expr) {
1934 return [ this[0], op, walk(expr) ];
1936 "sub": function(expr, subscript) {
1937 return [ this[0], walk(expr), walk(subscript) ];
1939 "object": function(props) {
1940 return [ this[0], MAP(props, function(p){
1941 return p.length == 2
1942 ? [ p[0], walk(p[1]) ]
1943 : [ p[0], walk(p[1]), p[2] ]; // get/set-ter
1946 "regexp": function(rx, mods) {
1947 return [ this[0], rx, mods ];
1949 "array": function(elements) {
1950 return [ this[0], MAP(elements, walk) ];
1952 "stat": function(stat) {
1953 return [ this[0], walk(stat) ];
1956 return [ this[0] ].concat(MAP(slice(arguments), walk));
1958 "label": function(name, block) {
1959 return [ this[0], name, walk(block) ];
1961 "with": function(expr, block) {
1962 return [ this[0], walk(expr), walk(block) ];
1964 "atom": function(name) {
1965 return [ this[0], name ];
1971 function walk(ast) {
1977 var gen = user[type];
1979 var ret = gen.apply(ast, ast.slice(1));
1983 gen = walkers[type];
1984 return gen.apply(ast, ast.slice(1));
1990 function with_walkers(walkers, cont){
1992 for (i in walkers) if (HOP(walkers, i)) {
1994 user[i] = walkers[i];
1997 for (i in save) if (HOP(save, i)) {
1998 if (!save[i]) delete user[i];
1999 else user[i] = save[i];
2006 with_walkers: with_walkers,
2007 parent: function() {
2008 return stack[stack.length - 2]; // last one is current node
2016 /* -----[ Scope and mangling ]----- */
2018 function Scope(parent) {
2019 this.names = {}; // names defined in this scope
2020 this.mangled = {}; // mangled names (orig.name => mangled)
2021 this.rev_mangled = {}; // reverse lookup (mangled => orig.name)
2022 this.cname = -1; // current mangled name
2023 this.refs = {}; // names referenced from this scope
2024 this.uses_with = false; // will become TRUE if with() is detected in this or any subscopes
2025 this.uses_eval = false; // will become TRUE if eval() is detected in this or any subscopes
2026 this.parent = parent; // parent scope
2027 this.children = []; // sub-scopes
2029 this.level = parent.level + 1;
2030 parent.children.push(this);
2036 var base54 = (function(){
2037 var DIGITS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$_";
2038 return function(num) {
2041 ret = DIGITS.charAt(num % 54) + ret;
2042 num = Math.floor(num / 54);
2049 has: function(name) {
2050 for (var s = this; s; s = s.parent)
2051 if (HOP(s.names, name))
2054 has_mangled: function(mname) {
2055 for (var s = this; s; s = s.parent)
2056 if (HOP(s.rev_mangled, mname))
2059 toJSON: function() {
2062 uses_eval: this.uses_eval,
2063 uses_with: this.uses_with
2067 next_mangled: function() {
2068 // we must be careful that the new mangled name:
2070 // 1. doesn't shadow a mangled name from a parent
2071 // scope, unless we don't reference the original
2072 // name from this scope OR from any sub-scopes!
2073 // This will get slow.
2075 // 2. doesn't shadow an original name from a parent
2076 // scope, in the event that the name is not mangled
2077 // in the parent scope and we reference that name
2078 // here OR IN ANY SUBSCOPES!
2080 // 3. doesn't shadow a name that is referenced but not
2081 // defined (possibly global defined elsewhere).
2083 var m = base54(++this.cname), prior;
2086 prior = this.has_mangled(m);
2087 if (prior && this.refs[prior.rev_mangled[m]] === prior)
2091 prior = this.has(m);
2092 if (prior && prior !== this && this.refs[m] === prior && !prior.has_mangled(m))
2096 if (HOP(this.refs, m) && this.refs[m] == null)
2099 // I got "do" once. :-/
2100 if (!is_identifier(m))
2106 set_mangle: function(name, m) {
2107 this.rev_mangled[m] = name;
2108 return this.mangled[name] = m;
2110 get_mangled: function(name, newMangle) {
2111 if (this.uses_eval || this.uses_with) return name; // no mangle if eval or with is in use
2112 var s = this.has(name);
2113 if (!s) return name; // not in visible scope, no mangle
2114 if (HOP(s.mangled, name)) return s.mangled[name]; // already mangled in this scope
2115 if (!newMangle) return name; // not found and no mangling requested
2116 return s.set_mangle(name, s.next_mangled());
2118 define: function(name) {
2120 return this.names[name] = name;
2124 function ast_add_scope(ast) {
2126 var current_scope = null;
2127 var w = ast_walker(), walk = w.walk;
2128 var having_eval = [];
2130 function with_new_scope(cont) {
2131 current_scope = new Scope(current_scope);
2132 var ret = current_scope.body = cont();
2133 ret.scope = current_scope;
2134 current_scope = current_scope.parent;
2138 function define(name) {
2139 return current_scope.define(name);
2142 function reference(name) {
2143 current_scope.refs[name] = true;
2146 function _lambda(name, args, body) {
2147 var is_defun = this[0] == "defun";
2148 return [ this[0], is_defun ? define(name) : name, args, with_new_scope(function(){
2149 if (!is_defun) define(name);
2151 return MAP(body, walk);
2155 return with_new_scope(function(){
2157 var ret = w.with_walkers({
2158 "function": _lambda,
2160 "with": function(expr, block) {
2161 for (var s = current_scope; s; s = s.parent)
2164 "var": function(defs) {
2165 MAP(defs, function(d){ define(d[0]) });
2167 "const": function(defs) {
2168 MAP(defs, function(d){ define(d[0]) });
2170 "try": function(t, c, f) {
2171 if (c != null) return [
2174 [ define(c[0]), MAP(c[1], walk) ],
2175 f != null ? MAP(f, walk) : null
2178 "name": function(name) {
2180 having_eval.push(current_scope);
2187 // the reason why we need an additional pass here is
2188 // that names can be used prior to their definition.
2190 // scopes where eval was detected and their parents
2191 // are marked with uses_eval, unless they define the
2193 MAP(having_eval, function(scope){
2194 if (!scope.has("eval")) while (scope) {
2195 scope.uses_eval = true;
2196 scope = scope.parent;
2200 // for referenced names it might be useful to know
2201 // their origin scope. current_scope here is the
2203 function fixrefs(scope, i) {
2204 // do children first; order shouldn't matter
2205 for (i = scope.children.length; --i >= 0;)
2206 fixrefs(scope.children[i]);
2207 for (i in scope.refs) if (HOP(scope.refs, i)) {
2208 // find origin scope and propagate the reference to origin
2209 for (var origin = scope.has(i), s = scope; s; s = s.parent) {
2211 if (s === origin) break;
2215 fixrefs(current_scope);
2222 /* -----[ mangle names ]----- */
2224 function ast_mangle(ast, options) {
2225 var w = ast_walker(), walk = w.walk, scope;
2226 options = options || {};
2228 function get_mangled(name, newMangle) {
2229 if (!options.toplevel && !scope.parent) return name; // don't mangle toplevel
2230 if (options.except && member(name, options.except))
2232 return scope.get_mangled(name, newMangle);
2235 function get_define(name) {
2236 if (options.defines) {
2237 // we always lookup a defined symbol for the current scope FIRST, so declared
2238 // vars trump a DEFINE symbol, but if no such var is found, then match a DEFINE value
2239 if (!scope.has(name)) {
2240 if (HOP(options.defines, name)) {
2241 return options.defines[name];
2248 function _lambda(name, args, body) {
2249 var is_defun = this[0] == "defun", extra;
2251 if (is_defun) name = get_mangled(name);
2254 name = extra[name] = scope.next_mangled();
2257 body = with_scope(body.scope, function(){
2258 args = MAP(args, function(name){ return get_mangled(name) });
2259 return MAP(body, walk);
2261 return [ this[0], name, args, body ];
2264 function with_scope(s, cont, extra) {
2267 if (extra) for (var i in extra) if (HOP(extra, i)) {
2268 s.set_mangle(i, extra[i]);
2270 for (var i in s.names) if (HOP(s.names, i)) {
2271 get_mangled(i, true);
2279 function _vardefs(defs) {
2280 return [ this[0], MAP(defs, function(d){
2281 return [ get_mangled(d[0]), walk(d[1]) ];
2285 return w.with_walkers({
2286 "function": _lambda,
2287 "defun": function() {
2288 // move function declarations to the top when
2289 // they are not in some block.
2290 var ast = _lambda.apply(this, arguments);
2291 switch (w.parent()[0]) {
2295 return MAP.at_top(ast);
2301 "name": function(name) {
2302 return get_define(name) || [ this[0], get_mangled(name) ];
2304 "try": function(t, c, f) {
2307 c != null ? [ get_mangled(c[0]), MAP(c[1], walk) ] : null,
2308 f != null ? MAP(f, walk) : null ];
2310 "toplevel": function(body) {
2312 return with_scope(self.scope, function(){
2313 return [ self[0], MAP(body, walk) ];
2317 return walk(ast_add_scope(ast));
2322 - compress foo["bar"] into foo.bar,
2323 - remove block brackets {} where possible
2324 - join consecutive var declarations
2325 - various optimizations for IFs:
2326 - if (cond) foo(); else bar(); ==> cond?foo():bar();
2327 - if (cond) foo(); ==> cond&&foo();
2328 - if (foo) return bar(); else return baz(); ==> return foo?bar():baz(); // also for throw
2329 - if (foo) return bar(); else something(); ==> {if(foo)return bar();something()}
2332 var warn = function(){};
2334 function best_of(ast1, ast2) {
2335 return gen_code(ast1).length > gen_code(ast2[0] == "stat" ? ast2[1] : ast2).length ? ast2 : ast1;
2338 function last_stat(b) {
2339 if (b[0] == "block" && b[1] && b[1].length > 0)
2340 return b[1][b[1].length - 1];
2344 function aborts(t) {
2347 if (t[0] == "return" || t[0] == "break" || t[0] == "continue" || t[0] == "throw")
2352 function boolean_expr(expr) {
2353 return ( (expr[0] == "unary-prefix"
2354 && member(expr[1], [ "!", "delete" ])) ||
2356 (expr[0] == "binary"
2357 && member(expr[1], [ "in", "instanceof", "==", "!=", "===", "!==", "<", "<=", ">=", ">" ])) ||
2359 (expr[0] == "binary"
2360 && member(expr[1], [ "&&", "||" ])
2361 && boolean_expr(expr[2])
2362 && boolean_expr(expr[3])) ||
2364 (expr[0] == "conditional"
2365 && boolean_expr(expr[2])
2366 && boolean_expr(expr[3])) ||
2368 (expr[0] == "assign"
2370 && boolean_expr(expr[3])) ||
2373 && boolean_expr(expr[expr.length - 1]))
2377 function make_conditional(c, t, e) {
2378 var make_real_conditional = function() {
2379 if (c[0] == "unary-prefix" && c[1] == "!") {
2380 return e ? [ "conditional", c[2], e, t ] : [ "binary", "||", c[2], t ];
2382 return e ? [ "conditional", c, t, e ] : [ "binary", "&&", c, t ];
2385 // shortcut the conditional if the expression has a constant value
2386 return when_constant(c, function(ast, val){
2387 warn_unreachable(val ? e : t);
2388 return (val ? t : e);
2389 }, make_real_conditional);
2393 return !b || (b[0] == "block" && (!b[1] || b[1].length == 0));
2396 function is_string(node) {
2397 return (node[0] == "string" ||
2398 node[0] == "unary-prefix" && node[1] == "typeof" ||
2399 node[0] == "binary" && node[1] == "+" &&
2400 (is_string(node[2]) || is_string(node[3])));
2403 var when_constant = (function(){
2405 var $NOT_CONSTANT = {};
2407 // this can only evaluate constant expressions. If it finds anything
2408 // not constant, it throws $NOT_CONSTANT.
2409 function evaluate(expr) {
2417 case "true": return true;
2418 case "false": return false;
2421 case "unary-prefix":
2423 case "!": return !evaluate(expr[2]);
2424 case "typeof": return typeof evaluate(expr[2]);
2425 case "~": return ~evaluate(expr[2]);
2426 case "-": return -evaluate(expr[2]);
2427 case "+": return +evaluate(expr[2]);
2431 var left = expr[2], right = expr[3];
2433 case "&&" : return evaluate(left) && evaluate(right);
2434 case "||" : return evaluate(left) || evaluate(right);
2435 case "|" : return evaluate(left) | evaluate(right);
2436 case "&" : return evaluate(left) & evaluate(right);
2437 case "^" : return evaluate(left) ^ evaluate(right);
2438 case "+" : return evaluate(left) + evaluate(right);
2439 case "*" : return evaluate(left) * evaluate(right);
2440 case "/" : return evaluate(left) / evaluate(right);
2441 case "-" : return evaluate(left) - evaluate(right);
2442 case "<<" : return evaluate(left) << evaluate(right);
2443 case ">>" : return evaluate(left) >> evaluate(right);
2444 case ">>>" : return evaluate(left) >>> evaluate(right);
2445 case "==" : return evaluate(left) == evaluate(right);
2446 case "===" : return evaluate(left) === evaluate(right);
2447 case "!=" : return evaluate(left) != evaluate(right);
2448 case "!==" : return evaluate(left) !== evaluate(right);
2449 case "<" : return evaluate(left) < evaluate(right);
2450 case "<=" : return evaluate(left) <= evaluate(right);
2451 case ">" : return evaluate(left) > evaluate(right);
2452 case ">=" : return evaluate(left) >= evaluate(right);
2453 case "in" : return evaluate(left) in evaluate(right);
2454 case "instanceof" : return evaluate(left) instanceof evaluate(right);
2457 throw $NOT_CONSTANT;
2460 return function(expr, yes, no) {
2462 var val = evaluate(expr), ast;
2463 switch (typeof val) {
2464 case "string": ast = [ "string", val ]; break;
2465 case "number": ast = [ "num", val ]; break;
2466 case "boolean": ast = [ "name", String(val) ]; break;
2467 default: throw new Error("Can't handle constant of type: " + (typeof val));
2469 return yes.call(expr, ast, val);
2471 if (ex === $NOT_CONSTANT) {
2472 if (expr[0] == "binary"
2473 && (expr[1] == "===" || expr[1] == "!==")
2474 && ((is_string(expr[2]) && is_string(expr[3]))
2475 || (boolean_expr(expr[2]) && boolean_expr(expr[3])))) {
2476 expr[1] = expr[1].substr(0, 2);
2478 else if (no && expr[0] == "binary"
2479 && (expr[1] == "||" || expr[1] == "&&")) {
2480 // the whole expression is not constant but the lval may be...
2482 var lval = evaluate(expr[2]);
2483 expr = ((expr[1] == "&&" && (lval ? expr[3] : lval)) ||
2484 (expr[1] == "||" && (lval ? lval : expr[3])) ||
2487 // IGNORE... lval is not constant
2490 return no ? no.call(expr, expr) : null;
2498 function warn_unreachable(ast) {
2500 warn("Dropping unreachable code: " + gen_code(ast, true));
2503 function prepare_ifs(ast) {
2504 var w = ast_walker(), walk = w.walk;
2505 // In this first pass, we rewrite ifs which abort with no else with an
2506 // if-else. For example:
2514 // is rewritten into:
2522 function redo_if(statements) {
2523 statements = MAP(statements, walk);
2525 for (var i = 0; i < statements.length; ++i) {
2526 var fi = statements[i];
2527 if (fi[0] != "if") continue;
2529 if (fi[3] && walk(fi[3])) continue;
2531 var t = walk(fi[2]);
2532 if (!aborts(t)) continue;
2534 var conditional = walk(fi[1]);
2536 var e_body = statements.slice(i + 1);
2538 if (e_body.length == 1) e = e_body[0];
2539 else e = [ "block", e_body ];
2541 var ret = statements.slice(0, i).concat([ [
2543 conditional, // conditional
2548 return redo_if(ret);
2554 function redo_if_lambda(name, args, body) {
2555 body = redo_if(body);
2556 return [ this[0], name, args.slice(), body ];
2559 function redo_if_block(statements) {
2560 var out = [ this[0] ];
2561 if (statements != null)
2562 out.push(redo_if(statements));
2566 return w.with_walkers({
2567 "defun": redo_if_lambda,
2568 "function": redo_if_lambda,
2569 "block": redo_if_block,
2570 "splice": redo_if_block,
2571 "toplevel": function(statements) {
2572 return [ this[0], redo_if(statements) ];
2574 "try": function(t, c, f) {
2578 c != null ? [ c[0], redo_if(c[1]) ] : null,
2579 f != null ? redo_if(f) : null
2582 "with": function(expr, block) {
2583 return [ this[0], walk(expr), redo_if(block) ];
2590 function ast_squeeze(ast, options) {
2591 options = defaults(options, {
2598 var w = ast_walker(), walk = w.walk, scope;
2600 function negate(c) {
2601 var not_c = [ "unary-prefix", "!", c ];
2603 case "unary-prefix":
2604 return c[1] == "!" && boolean_expr(c[2]) ? c[2] : not_c;
2607 c[c.length - 1] = negate(c[c.length - 1]);
2610 return best_of(not_c, [ "conditional", c[1], negate(c[2]), negate(c[3]) ]);
2612 var op = c[1], left = c[2], right = c[3];
2613 if (!options.keep_comps) switch (op) {
2614 case "<=" : return [ "binary", ">", left, right ];
2615 case "<" : return [ "binary", ">=", left, right ];
2616 case ">=" : return [ "binary", "<", left, right ];
2617 case ">" : return [ "binary", "<=", left, right ];
2620 case "==" : return [ "binary", "!=", left, right ];
2621 case "!=" : return [ "binary", "==", left, right ];
2622 case "===" : return [ "binary", "!==", left, right ];
2623 case "!==" : return [ "binary", "===", left, right ];
2624 case "&&" : return best_of(not_c, [ "binary", "||", negate(left), negate(right) ]);
2625 case "||" : return best_of(not_c, [ "binary", "&&", negate(left), negate(right) ]);
2632 function with_scope(s, cont) {
2641 function rmblock(block) {
2642 if (block != null && block[0] == "block" && block[1]) {
2643 if (block[1].length == 1)
2644 block = block[1][0];
2645 else if (block[1].length == 0)
2646 block = [ "block" ];
2651 function _lambda(name, args, body) {
2652 var is_defun = this[0] == "defun";
2653 body = with_scope(body.scope, function(){
2654 var ret = tighten(MAP(body, walk), "lambda");
2655 if (!is_defun && name && !HOP(scope.refs, name))
2659 return [ this[0], name, args, body ];
2662 // we get here for blocks that have been already transformed.
2663 // this function does a few things:
2664 // 1. discard useless blocks
2665 // 2. join consecutive var declarations
2666 // 3. remove obviously dead code
2667 // 4. transform consecutive statements using the comma operator
2668 // 5. if block_type == "lambda" and it detects constructs like if(foo) return ... - rewrite like if (!foo) { ... }
2669 function tighten(statements, block_type) {
2670 statements = statements.reduce(function(a, stat){
2671 if (stat[0] == "block") {
2673 a.push.apply(a, stat[1]);
2681 statements = (function(a, prev){
2682 statements.forEach(function(cur){
2683 if (prev && ((cur[0] == "var" && prev[0] == "var") ||
2684 (cur[0] == "const" && prev[0] == "const"))) {
2685 prev[1] = prev[1].concat(cur[1]);
2694 if (options.dead_code) statements = (function(a, has_quit){
2695 statements.forEach(function(st){
2697 if (member(st[0], [ "function", "defun" , "var", "const" ])) {
2700 else if (!options.no_warnings)
2701 warn_unreachable(st);
2705 if (member(st[0], [ "return", "throw", "break", "continue" ]))
2712 if (options.make_seqs) statements = (function(a, prev) {
2713 statements.forEach(function(cur){
2714 if (prev && prev[0] == "stat" && cur[0] == "stat") {
2715 prev[1] = [ "seq", prev[1], cur[1] ];
2724 if (block_type == "lambda") statements = (function(i, a, stat){
2725 while (i < statements.length) {
2726 stat = statements[i++];
2727 if (stat[0] == "if" && !stat[3]) {
2728 if (stat[2][0] == "return" && stat[2][1] == null) {
2729 a.push(make_if(negate(stat[1]), [ "block", statements.slice(i) ]));
2732 var last = last_stat(stat[2]);
2733 if (last[0] == "return" && last[1] == null) {
2734 a.push(make_if(stat[1], [ "block", stat[2][1].slice(0, -1) ], [ "block", statements.slice(i) ]));
2746 function make_if(c, t, e) {
2747 return when_constant(c, function(ast, val){
2749 warn_unreachable(e);
2752 warn_unreachable(t);
2756 return make_real_if(c, t, e);
2760 function make_real_if(c, t, e) {
2769 } else if (empty(e)) {
2772 // if we have both else and then, maybe it makes sense to switch them?
2774 var a = gen_code(c);
2776 var b = gen_code(n);
2777 if (b.length < a.length) {
2785 if (empty(e) && empty(t))
2786 return [ "stat", c ];
2787 var ret = [ "if", c, t, e ];
2788 if (t[0] == "if" && empty(t[3]) && empty(e)) {
2789 ret = best_of(ret, walk([ "if", [ "binary", "&&", c, t[1] ], t[2] ]));
2791 else if (t[0] == "stat") {
2793 if (e[0] == "stat") {
2794 ret = best_of(ret, [ "stat", make_conditional(c, t[1], e[1]) ]);
2798 ret = best_of(ret, [ "stat", make_conditional(c, t[1]) ]);
2801 else if (e && t[0] == e[0] && (t[0] == "return" || t[0] == "throw") && t[1] && e[1]) {
2802 ret = best_of(ret, [ t[0], make_conditional(c, t[1], e[1] ) ]);
2804 else if (e && aborts(t)) {
2805 ret = [ [ "if", c, t ] ];
2806 if (e[0] == "block") {
2807 if (e[1]) ret = ret.concat(e[1]);
2812 ret = walk([ "block", ret ]);
2814 else if (t && aborts(e)) {
2815 ret = [ [ "if", negate(c), e ] ];
2816 if (t[0] == "block") {
2817 if (t[1]) ret = ret.concat(t[1]);
2821 ret = walk([ "block", ret ]);
2826 function _do_while(cond, body) {
2827 return when_constant(cond, function(cond, val){
2829 warn_unreachable(body);
2832 return [ "for", null, null, null, walk(body) ];
2837 ast = prepare_ifs(ast);
2838 ast = ast_add_scope(ast);
2840 return w.with_walkers({
2841 "sub": function(expr, subscript) {
2842 if (subscript[0] == "string") {
2843 var name = subscript[1];
2844 if (is_identifier(name))
2845 return [ "dot", walk(expr), name ];
2846 else if (/^[1-9][0-9]*$/.test(name) || name === "0")
2847 return [ "sub", walk(expr), [ "num", parseInt(name, 10) ] ];
2851 "toplevel": function(body) {
2852 return [ "toplevel", with_scope(this.scope, function(){
2853 return tighten(MAP(body, walk));
2856 "switch": function(expr, body) {
2857 var last = body.length - 1;
2858 return [ "switch", walk(expr), MAP(body, function(branch, i){
2859 var block = tighten(MAP(branch[1], walk));
2860 if (i == last && block.length > 0) {
2861 var node = block[block.length - 1];
2862 if (node[0] == "break" && !node[1])
2865 return [ branch[0] ? walk(branch[0]) : null, block ];
2868 "function": _lambda,
2870 "block": function(body) {
2871 if (body) return rmblock([ "block", tighten(MAP(body, walk)) ]);
2873 "binary": function(op, left, right) {
2874 return when_constant([ "binary", op, walk(left), walk(right) ], function yes(c){
2875 return best_of(walk(c), this);
2880 "conditional": function(c, t, e) {
2881 return make_conditional(walk(c), walk(t), walk(e));
2883 "try": function(t, c, f) {
2886 tighten(MAP(t, walk)),
2887 c != null ? [ c[0], tighten(MAP(c[1], walk)) ] : null,
2888 f != null ? tighten(MAP(f, walk)) : null
2891 "unary-prefix": function(op, expr) {
2893 var ret = [ "unary-prefix", op, expr ];
2895 ret = best_of(ret, negate(expr));
2896 return when_constant(ret, function(ast, val){
2897 return walk(ast); // it's either true or false, so minifies to !0 or !1
2898 }, function() { return ret });
2900 "name": function(name) {
2902 case "true": return [ "unary-prefix", "!", [ "num", 0 ]];
2903 case "false": return [ "unary-prefix", "!", [ "num", 1 ]];
2906 "new": function(ctor, args) {
2907 if (ctor[0] == "name" && ctor[1] == "Array" && !scope.has("Array")) {
2908 if (args.length != 1) {
2909 return [ "array", args ];
2911 return [ "call", [ "name", "Array" ], args ];
2915 "call": function(expr, args) {
2916 if (expr[0] == "name" && expr[1] == "Array" && args.length != 1 && !scope.has("Array")) {
2917 return [ "array", args ];
2926 /* -----[ re-generate code from the AST ]----- */
2928 var DOT_CALL_NO_PARENS = jsp.array_to_hash([
2939 function make_string(str, ascii_only) {
2941 str = str.replace(/[\\\b\f\n\r\t\x22\x27\u2028\u2029]/g, function(s){
2943 case "\\": return "\\\\";
2944 case "\b": return "\\b";
2945 case "\f": return "\\f";
2946 case "\n": return "\\n";
2947 case "\r": return "\\r";
2948 case "\t": return "\\t";
2949 case "\u2028": return "\\u2028";
2950 case "\u2029": return "\\u2029";
2951 case '"': ++dq; return '"';
2952 case "'": ++sq; return "'";
2956 if (ascii_only) str = to_ascii(str);
2957 if (dq > sq) return "'" + str.replace(/\x27/g, "\\'") + "'";
2958 else return '"' + str.replace(/\x22/g, '\\"') + '"';
2961 function to_ascii(str) {
2962 return str.replace(/[\u0080-\uffff]/g, function(ch) {
2963 var code = ch.charCodeAt(0).toString(16);
2964 while (code.length < 4) code = "0" + code;
2965 return "\\u" + code;
2969 var SPLICE_NEEDS_BRACKETS = jsp.array_to_hash([ "if", "while", "do", "for", "for-in", "with" ]);
2971 function gen_code(ast, options) {
2972 options = defaults(options, {
2976 space_colon : false,
2980 var beautify = !!options.beautify;
2981 var indentation = 0,
2982 newline = beautify ? "\n" : "",
2983 space = beautify ? " " : "";
2985 function encode_string(str) {
2986 return make_string(str, options.ascii_only);
2989 function make_name(name) {
2990 name = name.toString();
2991 if (options.ascii_only)
2992 name = to_ascii(name);
2996 function indent(line) {
3000 line = repeat_string(" ", options.indent_start + indentation * options.indent_level) + line;
3004 function with_indent(cont, incr) {
3005 if (incr == null) incr = 1;
3006 indentation += incr;
3007 try { return cont.apply(null, slice(arguments, 1)); }
3008 finally { indentation -= incr; }
3011 function add_spaces(a) {
3015 for (var i = 0; i < a.length; ++i) {
3016 var next = a[i + 1];
3019 ((/[a-z0-9_\x24]$/i.test(a[i].toString()) && /^[a-z0-9_\x24]/i.test(next.toString())) ||
3020 (/[\+\-]$/.test(a[i].toString()) && /^[\+\-]/.test(next.toString())))) {
3027 function add_commas(a) {
3028 return a.join("," + space);
3031 function parenthesize(expr) {
3032 var gen = make(expr);
3033 for (var i = 1; i < arguments.length; ++i) {
3034 var el = arguments[i];
3035 if ((el instanceof Function && el(expr)) || expr[0] == el)
3036 return "(" + gen + ")";
3041 function best_of(a) {
3042 if (a.length == 1) {
3045 if (a.length == 2) {
3048 return a.length <= b.length ? a : b;
3050 return best_of([ a[0], best_of(a.slice(1)) ]);
3053 function needs_parens(expr) {
3054 if (expr[0] == "function" || expr[0] == "object") {
3055 // dot/call on a literal function requires the
3056 // function literal itself to be parenthesized
3057 // only if it's the first "thing" in a
3058 // statement. This means that the parent is
3059 // "stat", but it could also be a "seq" and
3060 // we're the first in this "seq" and the
3061 // parent is "stat", and so on. Messy stuff,
3062 // but it worths the trouble.
3063 var a = slice($stack), self = a.pop(), p = a.pop();
3065 if (p[0] == "stat") return true;
3066 if (((p[0] == "seq" || p[0] == "call" || p[0] == "dot" || p[0] == "sub" || p[0] == "conditional") && p[1] === self) ||
3067 ((p[0] == "binary" || p[0] == "assign" || p[0] == "unary-postfix") && p[2] === self)) {
3075 return !HOP(DOT_CALL_NO_PARENS, expr[0]);
3078 function make_num(num) {
3079 var str = num.toString(10), a = [ str.replace(/^0\./, ".") ], m;
3080 if (Math.floor(num) === num) {
3081 a.push("0x" + num.toString(16).toLowerCase(), // probably pointless
3082 "0" + num.toString(8)); // same.
3083 if ((m = /^(.*?)(0+)$/.exec(num))) {
3084 a.push(m[1] + "e" + m[2].length);
3086 } else if ((m = /^0?\.(0+)(.*)$/.exec(num))) {
3087 a.push(m[2] + "e-" + (m[1].length + m[2].length),
3088 str.substr(str.indexOf(".")));
3094 "string": encode_string,
3097 "toplevel": function(statements) {
3098 return make_block_statements(statements)
3099 .join(newline + newline);
3101 "splice": function(statements) {
3102 var parent = $stack[$stack.length - 2][0];
3103 if (HOP(SPLICE_NEEDS_BRACKETS, parent)) {
3104 // we need block brackets in this case
3105 return make_block.apply(this, arguments);
3107 return MAP(make_block_statements(statements, true),
3109 // the first line is already indented
3110 return i > 0 ? indent(line) : line;
3114 "block": make_block,
3115 "var": function(defs) {
3116 return "var " + add_commas(MAP(defs, make_1vardef)) + ";";
3118 "const": function(defs) {
3119 return "const " + add_commas(MAP(defs, make_1vardef)) + ";";
3121 "try": function(tr, ca, fi) {
3122 var out = [ "try", make_block(tr) ];
3123 if (ca) out.push("catch", "(" + ca[0] + ")", make_block(ca[1]));
3124 if (fi) out.push("finally", make_block(fi));
3125 return add_spaces(out);
3127 "throw": function(expr) {
3128 return add_spaces([ "throw", make(expr) ]) + ";";
3130 "new": function(ctor, args) {
3131 args = args.length > 0 ? "(" + add_commas(MAP(args, make)) + ")" : "";
3132 return add_spaces([ "new", parenthesize(ctor, "seq", "binary", "conditional", "assign", function(expr){
3133 var w = ast_walker(), has_call = {};
3136 "call": function() { throw has_call },
3137 "function": function() { return this }
3142 if (ex === has_call)
3148 "switch": function(expr, body) {
3149 return add_spaces([ "switch", "(" + make(expr) + ")", make_switch_block(body) ]);
3151 "break": function(label) {
3154 out += " " + make_name(label);
3157 "continue": function(label) {
3158 var out = "continue";
3160 out += " " + make_name(label);
3163 "conditional": function(co, th, el) {
3164 return add_spaces([ parenthesize(co, "assign", "seq", "conditional"), "?",
3165 parenthesize(th, "seq"), ":",
3166 parenthesize(el, "seq") ]);
3168 "assign": function(op, lvalue, rvalue) {
3169 if (op && op !== true) op += "=";
3171 return add_spaces([ make(lvalue), op, parenthesize(rvalue, "seq") ]);
3173 "dot": function(expr) {
3174 var out = make(expr), i = 1;
3175 if (expr[0] == "num") {
3176 if (!/\./.test(expr[1]))
3178 } else if (needs_parens(expr))
3179 out = "(" + out + ")";
3180 while (i < arguments.length)
3181 out += "." + make_name(arguments[i++]);
3184 "call": function(func, args) {
3186 if (needs_parens(func))
3188 return f + "(" + add_commas(MAP(args, function(expr){
3189 return parenthesize(expr, "seq");
3192 "function": make_function,
3193 "defun": make_function,
3194 "if": function(co, th, el) {
3195 var out = [ "if", "(" + make(co) + ")", el ? make_then(th) : make(th) ];
3197 out.push("else", make(el));
3199 return add_spaces(out);
3201 "for": function(init, cond, step, block) {
3202 var out = [ "for" ];
3203 init = (init != null ? make(init) : "").replace(/;*\s*$/, ";" + space);
3204 cond = (cond != null ? make(cond) : "").replace(/;*\s*$/, ";" + space);
3205 step = (step != null ? make(step) : "").replace(/;*\s*$/, "");
3206 var args = init + cond + step;
3207 if (args == "; ; ") args = ";;";
3208 out.push("(" + args + ")", make(block));
3209 return add_spaces(out);
3211 "for-in": function(vvar, key, hash, block) {
3212 return add_spaces([ "for", "(" +
3213 (vvar ? make(vvar).replace(/;+$/, "") : make(key)),
3215 make(hash) + ")", make(block) ]);
3217 "while": function(condition, block) {
3218 return add_spaces([ "while", "(" + make(condition) + ")", make(block) ]);
3220 "do": function(condition, block) {
3221 return add_spaces([ "do", make(block), "while", "(" + make(condition) + ")" ]) + ";";
3223 "return": function(expr) {
3224 var out = [ "return" ];
3225 if (expr != null) out.push(make(expr));
3226 return add_spaces(out) + ";";
3228 "binary": function(operator, lvalue, rvalue) {
3229 var left = make(lvalue), right = make(rvalue);
3230 // XXX: I'm pretty sure other cases will bite here.
3231 // we need to be smarter.
3232 // adding parens all the time is the safest bet.
3233 if (member(lvalue[0], [ "assign", "conditional", "seq" ]) ||
3234 lvalue[0] == "binary" && PRECEDENCE[operator] > PRECEDENCE[lvalue[1]]) {
3235 left = "(" + left + ")";
3237 if (member(rvalue[0], [ "assign", "conditional", "seq" ]) ||
3238 rvalue[0] == "binary" && PRECEDENCE[operator] >= PRECEDENCE[rvalue[1]] &&
3239 !(rvalue[1] == operator && member(operator, [ "&&", "||", "*" ]))) {
3240 right = "(" + right + ")";
3242 return add_spaces([ left, operator, right ]);
3244 "unary-prefix": function(operator, expr) {
3245 var val = make(expr);
3246 if (!(expr[0] == "num" || (expr[0] == "unary-prefix" && !HOP(OPERATORS, operator + expr[1])) || !needs_parens(expr)))
3247 val = "(" + val + ")";
3248 return operator + (jsp.is_alphanumeric_char(operator.charAt(0)) ? " " : "") + val;
3250 "unary-postfix": function(operator, expr) {
3251 var val = make(expr);
3252 if (!(expr[0] == "num" || (expr[0] == "unary-postfix" && !HOP(OPERATORS, operator + expr[1])) || !needs_parens(expr)))
3253 val = "(" + val + ")";
3254 return val + operator;
3256 "sub": function(expr, subscript) {
3257 var hash = make(expr);
3258 if (needs_parens(expr))
3259 hash = "(" + hash + ")";
3260 return hash + "[" + make(subscript) + "]";
3262 "object": function(props) {
3263 if (props.length == 0)
3265 return "{" + newline + with_indent(function(){
3266 return MAP(props, function(p){
3267 if (p.length == 3) {
3268 // getter/setter. The name is in p[0], the arg.list in p[1][2], the
3269 // body in p[1][3] and type ("get" / "set") in p[2].
3270 return indent(make_function(p[0], p[1][2], p[1][3], p[2]));
3272 var key = p[0], val = make(p[1]);
3273 if (options.quote_keys) {
3274 key = encode_string(key);
3275 } else if ((typeof key == "number" || !beautify && +key + "" == key)
3276 && parseFloat(key) >= 0) {
3277 key = make_num(+key);
3278 } else if (!is_identifier(key)) {
3279 key = encode_string(key);
3281 return indent(add_spaces(beautify && options.space_colon
3283 : [ key + ":", val ]));
3284 }).join("," + newline);
3285 }) + newline + indent("}");
3287 "regexp": function(rx, mods) {
3288 return "/" + rx + "/" + mods;
3290 "array": function(elements) {
3291 if (elements.length == 0) return "[]";
3292 return add_spaces([ "[", add_commas(MAP(elements, function(el){
3293 if (!beautify && el[0] == "atom" && el[1] == "undefined") return "";
3294 return parenthesize(el, "seq");
3297 "stat": function(stmt) {
3298 return make(stmt).replace(/;*\s*$/, ";");
3301 return add_commas(MAP(slice(arguments), make));
3303 "label": function(name, block) {
3304 return add_spaces([ make_name(name), ":", make(block) ]);
3306 "with": function(expr, block) {
3307 return add_spaces([ "with", "(" + make(expr) + ")", make(block) ]);
3309 "atom": function(name) {
3310 return make_name(name);
3314 // The squeezer replaces "block"-s that contain only a single
3315 // statement with the statement itself; technically, the AST
3316 // is correct, but this can create problems when we output an
3317 // IF having an ELSE clause where the THEN clause ends in an
3318 // IF *without* an ELSE block (then the outer ELSE would refer
3319 // to the inner IF). This function checks for this case and
3320 // adds the block brackets if needed.
3321 function make_then(th) {
3322 if (th[0] == "do") {
3323 // https://github.com/mishoo/UglifyJS/issues/#issue/57
3324 // IE croaks with "syntax error" on code like this:
3325 // if (foo) do ... while(cond); else ...
3326 // we need block brackets around do/while
3327 return make([ "block", [ th ]]);
3334 // no else, we must add the block
3335 return make([ "block", [ th ]]);
3338 else if (type == "while" || type == "do") b = b[2];
3339 else if (type == "for" || type == "for-in") b = b[4];
3345 function make_function(name, args, body, keyword) {
3346 var out = keyword || "function";
3348 out += " " + make_name(name);
3350 out += "(" + add_commas(MAP(args, make_name)) + ")";
3351 return add_spaces([ out, make_block(body) ]);
3354 function make_block_statements(statements, noindent) {
3355 for (var a = [], last = statements.length - 1, i = 0; i <= last; ++i) {
3356 var stat = statements[i];
3357 var code = make(stat);
3359 if (!beautify && i == last) {
3360 if ((stat[0] == "while" && empty(stat[2])) ||
3361 (member(stat[0], [ "for", "for-in"] ) && empty(stat[4])) ||
3362 (stat[0] == "if" && empty(stat[2]) && !stat[3]) ||
3363 (stat[0] == "if" && stat[3] && empty(stat[3]))) {
3364 code = code.replace(/;*\s*$/, ";");
3366 code = code.replace(/;+\s*$/, "");
3372 return noindent ? a : MAP(a, indent);
3375 function make_switch_block(body) {
3376 var n = body.length;
3377 if (n == 0) return "{}";
3378 return "{" + newline + MAP(body, function(branch, i){
3379 var has_body = branch[1].length > 0, code = with_indent(function(){
3380 return indent(branch[0]
3381 ? add_spaces([ "case", make(branch[0]) + ":" ])
3383 }, 0.5) + (has_body ? newline + with_indent(function(){
3384 return make_block_statements(branch[1]).join(newline);
3386 if (!beautify && has_body && i < n - 1)
3389 }).join(newline) + newline + indent("}");
3392 function make_block(statements) {
3393 if (!statements) return ";";
3394 if (statements.length == 0) return "{}";
3395 return "{" + newline + with_indent(function(){
3396 return make_block_statements(statements).join(newline);
3397 }) + newline + indent("}");
3400 function make_1vardef(def) {
3401 var name = def[0], val = def[1];
3403 name = add_spaces([ make_name(name), "=", parenthesize(val, "seq") ]);
3409 function make(node) {
3411 var gen = generators[type];
3413 throw new Error("Can't find generator for \"" + type + "\"");
3415 var ret = gen.apply(type, node.slice(1));
3423 function split_lines(code, max_line_length) {
3425 jsp.parse(function(){
3426 var next_token = jsp.tokenizer(code);
3429 function current_length(tok) {
3430 return tok.pos - last_split;
3432 function split_here(tok) {
3433 last_split = tok.pos;
3434 splits.push(last_split);
3437 var tok = next_token.apply(this, arguments);
3440 if (prev_token.type == "keyword") break out;
3442 if (current_length(tok) > max_line_length) {
3456 custom.context = function() {
3457 return next_token.context.apply(this, arguments);
3461 return splits.map(function(pos, i){
3462 return code.substring(pos, splits[i + 1] || code.length);
3466 /* -----[ Utilities ]----- */
3468 function repeat_string(str, i) {
3469 if (i <= 0) return "";
3470 if (i == 1) return str;
3471 var d = repeat_string(str, i >> 1);
3473 if (i & 1) d += str;
3477 function defaults(args, defs) {
3481 for (var i in defs) if (HOP(defs, i)) {
3482 ret[i] = (args && HOP(args, i)) ? args[i] : defs[i];
3487 function is_identifier(name) {
3488 return /^[a-z_$][a-z0-9_$]*$/i.test(name)
3490 && !HOP(jsp.KEYWORDS_ATOM, name)
3491 && !HOP(jsp.RESERVED_WORDS, name)
3492 && !HOP(jsp.KEYWORDS, name);
3495 function HOP(obj, prop) {
3496 return Object.prototype.hasOwnProperty.call(obj, prop);
3504 MAP = function(a, f, o) {
3506 for (var i = 0; i < a.length; ++i) {
3507 var val = f.call(o, a[i], i);
3508 if (val instanceof AtTop) ret.unshift(val.v);
3513 MAP.at_top = function(val) { return new AtTop(val) };
3514 function AtTop(val) { this.v = val };
3517 /* -----[ Exports ]----- */
3519 exports.ast_walker = ast_walker;
3520 exports.ast_mangle = ast_mangle;
3521 exports.ast_squeeze = ast_squeeze;
3522 exports.gen_code = gen_code;
3523 exports.ast_add_scope = ast_add_scope;
3524 exports.set_logger = function(logger) { warn = logger };
3525 exports.make_string = make_string;
3526 exports.split_lines = split_lines;
3530 exports.ast_squeeze_more = require("./squeeze-more").ast_squeeze_more;
3532 }).call(module.exports);
3534 __require.modules["/node_modules/burrito/node_modules/uglify-js/lib/process.js"]._cached = module.exports;
3535 return module.exports;
3538 require.modules["/node_modules/burrito/node_modules/uglify-js/lib/squeeze-more.js"] = function () {
3539 var module = { exports : {} };
3540 var exports = module.exports;
3541 var __dirname = "/node_modules/burrito/node_modules/uglify-js/lib";
3542 var __filename = "/node_modules/burrito/node_modules/uglify-js/lib/squeeze-more.js";
3544 var require = function (file) {
3545 return __require(file, "/node_modules/burrito/node_modules/uglify-js/lib");
3548 require.resolve = function (file) {
3549 return __require.resolve(name, "/node_modules/burrito/node_modules/uglify-js/lib");
3552 require.modules = __require.modules;
3553 __require.modules["/node_modules/burrito/node_modules/uglify-js/lib/squeeze-more.js"]._cached = module.exports;
3556 var jsp = require("./parse-js"),
3557 pro = require("./process"),
3559 member = jsp.member,
3560 PRECEDENCE = jsp.PRECEDENCE,
3561 OPERATORS = jsp.OPERATORS;
3563 function ast_squeeze_more(ast) {
3564 var w = pro.ast_walker(), walk = w.walk;
3565 return w.with_walkers({
3566 "call": function(expr, args) {
3567 if (expr[0] == "dot" && expr[2] == "toString" && args.length == 0) {
3568 // foo.toString() ==> foo+""
3569 return [ "binary", "+", expr[1], [ "string", "" ]];
3577 exports.ast_squeeze_more = ast_squeeze_more;
3579 }).call(module.exports);
3581 __require.modules["/node_modules/burrito/node_modules/uglify-js/lib/squeeze-more.js"]._cached = module.exports;
3582 return module.exports;
3585 require.modules["/node_modules/burrito/node_modules/traverse/package.json"] = function () {
3586 var module = { exports : {} };
3587 var exports = module.exports;
3588 var __dirname = "/node_modules/burrito/node_modules/traverse";
3589 var __filename = "/node_modules/burrito/node_modules/traverse/package.json";
3591 var require = function (file) {
3592 return __require(file, "/node_modules/burrito/node_modules/traverse");
3595 require.resolve = function (file) {
3596 return __require.resolve(name, "/node_modules/burrito/node_modules/traverse");
3599 require.modules = __require.modules;
3600 __require.modules["/node_modules/burrito/node_modules/traverse/package.json"]._cached = module.exports;
3603 module.exports = {"name":"traverse","version":"0.5.0","description":"Traverse and transform objects by visiting every node on a recursive walk","author":"James Halliday","license":"MIT/X11","main":"./index","repository":{"type":"git","url":"http://github.com/substack/js-traverse.git"},"devDependencies":{"expresso":"0.7.x"},"scripts":{"test":"expresso"}};
3604 }).call(module.exports);
3606 __require.modules["/node_modules/burrito/node_modules/traverse/package.json"]._cached = module.exports;
3607 return module.exports;
3610 require.modules["/node_modules/burrito/node_modules/traverse/index.js"] = function () {
3611 var module = { exports : {} };
3612 var exports = module.exports;
3613 var __dirname = "/node_modules/burrito/node_modules/traverse";
3614 var __filename = "/node_modules/burrito/node_modules/traverse/index.js";
3616 var require = function (file) {
3617 return __require(file, "/node_modules/burrito/node_modules/traverse");
3620 require.resolve = function (file) {
3621 return __require.resolve(name, "/node_modules/burrito/node_modules/traverse");
3624 require.modules = __require.modules;
3625 __require.modules["/node_modules/burrito/node_modules/traverse/index.js"]._cached = module.exports;
3628 module.exports = Traverse;
3629 function Traverse (obj) {
3630 if (!(this instanceof Traverse)) return new Traverse(obj);
3634 Traverse.prototype.get = function (ps) {
3635 var node = this.value;
3636 for (var i = 0; i < ps.length; i ++) {
3638 if (!Object.hasOwnProperty.call(node, key)) {
3647 Traverse.prototype.set = function (ps, value) {
3648 var node = this.value;
3649 for (var i = 0; i < ps.length - 1; i ++) {
3651 if (!Object.hasOwnProperty.call(node, key)) node[key] = {};
3654 node[ps[i]] = value;
3658 Traverse.prototype.map = function (cb) {
3659 return walk(this.value, cb, true);
3662 Traverse.prototype.forEach = function (cb) {
3663 this.value = walk(this.value, cb, false);
3667 Traverse.prototype.reduce = function (cb, init) {
3668 var skip = arguments.length === 1;
3669 var acc = skip ? this.value : init;
3670 this.forEach(function (x) {
3671 if (!this.isRoot || !skip) {
3672 acc = cb.call(this, acc, x);
3678 Traverse.prototype.paths = function () {
3680 this.forEach(function (x) {
3681 acc.push(this.path);
3686 Traverse.prototype.nodes = function () {
3688 this.forEach(function (x) {
3689 acc.push(this.node);
3694 Traverse.prototype.clone = function () {
3695 var parents = [], nodes = [];
3697 return (function clone (src) {
3698 for (var i = 0; i < parents.length; i++) {
3699 if (parents[i] === src) {
3704 if (typeof src === 'object' && src !== null) {
3705 var dst = copy(src);
3710 forEach(Object_keys(src), function (key) {
3711 dst[key] = clone(src[key]);
3724 function walk (root, cb, immutable) {
3729 return (function walker (node_) {
3730 var node = immutable ? copy(node_) : node_;
3733 var keepGoing = true;
3738 path : [].concat(path),
3739 parent : parents[parents.length - 1],
3741 key : path.slice(-1)[0],
3742 isRoot : path.length === 0,
3743 level : path.length,
3745 update : function (x, stopHere) {
3746 if (!state.isRoot) {
3747 state.parent.node[state.key] = x;
3750 if (stopHere) keepGoing = false;
3752 'delete' : function () {
3753 delete state.parent.node[state.key];
3755 remove : function () {
3756 if (Array_isArray(state.parent.node)) {
3757 state.parent.node.splice(state.key, 1);
3760 delete state.parent.node[state.key];
3764 before : function (f) { modifiers.before = f },
3765 after : function (f) { modifiers.after = f },
3766 pre : function (f) { modifiers.pre = f },
3767 post : function (f) { modifiers.post = f },
3768 stop : function () { alive = false },
3769 block : function () { keepGoing = false }
3772 if (!alive) return state;
3774 if (typeof node === 'object' && node !== null) {
3775 state.keys = Object_keys(node);
3777 state.isLeaf = state.keys.length == 0;
3779 for (var i = 0; i < parents.length; i++) {
3780 if (parents[i].node_ === node_) {
3781 state.circular = parents[i];
3787 state.isLeaf = true;
3790 state.notLeaf = !state.isLeaf;
3791 state.notRoot = !state.isRoot;
3793 // use return values to update if defined
3794 var ret = cb.call(state, state.node);
3795 if (ret !== undefined && state.update) state.update(ret);
3797 if (modifiers.before) modifiers.before.call(state, state.node);
3799 if (!keepGoing) return state;
3801 if (typeof state.node == 'object'
3802 && state.node !== null && !state.circular) {
3803 parents.push(state);
3805 forEach(state.keys, function (key, i) {
3808 if (modifiers.pre) modifiers.pre.call(state, state.node[key], key);
3810 var child = walker(state.node[key]);
3811 if (immutable && Object.hasOwnProperty.call(state.node, key)) {
3812 state.node[key] = child.node;
3815 child.isLast = i == state.keys.length - 1;
3816 child.isFirst = i == 0;
3818 if (modifiers.post) modifiers.post.call(state, child);
3825 if (modifiers.after) modifiers.after.call(state, state.node);
3831 function copy (src) {
3832 if (typeof src === 'object' && src !== null) {
3835 if (Array_isArray(src)) {
3838 else if (src instanceof Date) {
3839 dst = new Date(src);
3841 else if (src instanceof Boolean) {
3842 dst = new Boolean(src);
3844 else if (src instanceof Number) {
3845 dst = new Number(src);
3847 else if (src instanceof String) {
3848 dst = new String(src);
3850 else if (Object.create && Object.getPrototypeOf) {
3851 dst = Object.create(Object.getPrototypeOf(src));
3853 else if (src.__proto__ || src.constructor.prototype) {
3854 var proto = src.__proto__ || src.constructor.prototype || {};
3855 var T = function () {};
3856 T.prototype = proto;
3858 if (!dst.__proto__) dst.__proto__ = proto;
3861 forEach(Object_keys(src), function (key) {
3862 dst[key] = src[key];
3869 var Object_keys = Object.keys || function keys (obj) {
3871 for (var key in obj) res.push(key)
3875 var Array_isArray = Array.isArray || function isArray (xs) {
3876 return Object.prototype.toString.call(xs) === '[object Array]';
3879 var forEach = function (xs, fn) {
3880 if (xs.forEach) return xs.forEach(fn)
3881 else for (var i = 0; i < xs.length; i++) {
3886 forEach(Object_keys(Traverse.prototype), function (key) {
3887 Traverse[key] = function (obj) {
3888 var args = [].slice.call(arguments, 1);
3889 var t = Traverse(obj);
3890 return t[key].apply(t, args);
3894 }).call(module.exports);
3896 __require.modules["/node_modules/burrito/node_modules/traverse/index.js"]._cached = module.exports;
3897 return module.exports;
3900 require.modules["vm"] = function () {
3901 var module = { exports : {} };
3902 var exports = module.exports;
3903 var __dirname = ".";
3904 var __filename = "vm";
3906 var require = function (file) {
3907 return __require(file, ".");
3910 require.resolve = function (file) {
3911 return __require.resolve(name, ".");
3914 require.modules = __require.modules;
3915 __require.modules["vm"]._cached = module.exports;
3918 var Object_keys = function (obj) {
3919 if (Object.keys) return Object.keys(obj)
3922 for (var key in obj) res.push(key)
3927 var forEach = function (xs, fn) {
3928 if (xs.forEach) return xs.forEach(fn)
3929 else for (var i = 0; i < xs.length; i++) {
3934 var Script = exports.Script = function NodeScript (code) {
3935 if (!(this instanceof Script)) return new Script(code);
3939 var iframe = document.createElement('iframe');
3940 if (!iframe.style) iframe.style = {};
3941 iframe.style.display = 'none';
3943 var iframeCapable = true; // until proven otherwise
3944 if (navigator.appName === 'Microsoft Internet Explorer') {
3945 var m = navigator.appVersion.match(/\bMSIE (\d+\.\d+);/);
3946 if (m && parseFloat(m[1]) <= 9.0) {
3947 iframeCapable = false;
3951 Script.prototype.runInNewContext = function (context) {
3952 if (!context) context = {};
3954 if (!iframeCapable) {
3955 var keys = Object_keys(context);
3957 for (var i = 0; i < keys.length; i++) {
3958 args.push(context[keys[i]]);
3961 var fn = Function(keys, this.code);
3962 return fn.apply(null, args);
3965 document.body.appendChild(iframe);
3967 var win = iframe.contentWindow
3968 || (window.frames && window.frames[window.frames.length - 1])
3969 || window[window.length - 1]
3972 forEach(Object_keys(context), function (key) {
3973 win[key] = context[key];
3974 iframe[key] = context[key];
3978 // chrome and ff can just .eval()
3979 var res = win.eval(this.code);
3982 // this works in IE9 but not anything newer
3983 iframe.setAttribute('src',
3984 'javascript:__browserifyVmResult=(' + this.code + ')'
3986 if ('__browserifyVmResult' in win) {
3987 var res = win.__browserifyVmResult;
3990 iframeCapable = false;
3991 res = this.runInThisContext(context);
3995 forEach(Object_keys(win), function (key) {
3996 context[key] = win[key];
3999 document.body.removeChild(iframe);
4004 Script.prototype.runInThisContext = function () {
4005 return eval(this.code); // maybe...
4008 Script.prototype.runInContext = function (context) {
4009 // seems to be just runInNewContext on magical context objects which are
4010 // otherwise indistinguishable from objects except plain old objects
4011 // for the parameter segfaults node
4012 return this.runInNewContext(context);
4015 forEach(Object_keys(Script.prototype), function (name) {
4016 exports[name] = Script[name] = function (code) {
4017 var s = Script(code);
4018 return s[name].apply(s, [].slice.call(arguments, 1));
4022 exports.createScript = function (code) {
4023 return exports.Script(code);
4026 exports.createContext = Script.createContext = function (context) {
4027 // not really sure what this one does
4028 // seems to just make a shallow copy
4030 forEach(Object_keys(context), function (key) {
4031 copy[key] = context[key];
4036 }).call(module.exports);
4038 __require.modules["vm"]._cached = module.exports;
4039 return module.exports;
4042 require.modules["/node_modules/jsonify/package.json"] = function () {
4043 var module = { exports : {} };
4044 var exports = module.exports;
4045 var __dirname = "/node_modules/jsonify";
4046 var __filename = "/node_modules/jsonify/package.json";
4048 var require = function (file) {
4049 return __require(file, "/node_modules/jsonify");
4052 require.resolve = function (file) {
4053 return __require.resolve(name, "/node_modules/jsonify");
4056 require.modules = __require.modules;
4057 __require.modules["/node_modules/jsonify/package.json"]._cached = module.exports;
4060 module.exports = {"name":"jsonify","version":"0.0.0","description":"JSON without touching any globals","main":"index.js","directories":{"lib":".","test":"test"},"devDependencies":{"tap":"0.0.x","garbage":"0.0.x"},"scripts":{"test":"tap test"},"repository":{"type":"git","url":"http://github.com/substack/jsonify.git"},"keywords":["json","browser"],"author":{"name":"Douglas Crockford","url":"http://crockford.com/"},"license":"Public Domain"};
4061 }).call(module.exports);
4063 __require.modules["/node_modules/jsonify/package.json"]._cached = module.exports;
4064 return module.exports;
4067 require.modules["/node_modules/jsonify/index.js"] = function () {
4068 var module = { exports : {} };
4069 var exports = module.exports;
4070 var __dirname = "/node_modules/jsonify";
4071 var __filename = "/node_modules/jsonify/index.js";
4073 var require = function (file) {
4074 return __require(file, "/node_modules/jsonify");
4077 require.resolve = function (file) {
4078 return __require.resolve(name, "/node_modules/jsonify");
4081 require.modules = __require.modules;
4082 __require.modules["/node_modules/jsonify/index.js"]._cached = module.exports;
4085 exports.parse = require('./lib/parse');
4086 exports.stringify = require('./lib/stringify');
4088 }).call(module.exports);
4090 __require.modules["/node_modules/jsonify/index.js"]._cached = module.exports;
4091 return module.exports;
4094 require.modules["/node_modules/jsonify/lib/parse.js"] = function () {
4095 var module = { exports : {} };
4096 var exports = module.exports;
4097 var __dirname = "/node_modules/jsonify/lib";
4098 var __filename = "/node_modules/jsonify/lib/parse.js";
4100 var require = function (file) {
4101 return __require(file, "/node_modules/jsonify/lib");
4104 require.resolve = function (file) {
4105 return __require.resolve(name, "/node_modules/jsonify/lib");
4108 require.modules = __require.modules;
4109 __require.modules["/node_modules/jsonify/lib/parse.js"]._cached = module.exports;
4112 var at, // The index of the current character
4113 ch, // The current character
4126 error = function (m) {
4127 // Call error when something is wrong.
4129 name: 'SyntaxError',
4136 next = function (c) {
4137 // If a c parameter is provided, verify that it matches the current character.
4138 if (c && c !== ch) {
4139 error("Expected '" + c + "' instead of '" + ch + "'");
4142 // Get the next character. When there are no more characters,
4143 // return the empty string.
4145 ch = text.charAt(at);
4150 number = function () {
4151 // Parse a number value.
4159 while (ch >= '0' && ch <= '9') {
4165 while (next() && ch >= '0' && ch <= '9') {
4169 if (ch === 'e' || ch === 'E') {
4172 if (ch === '-' || ch === '+') {
4176 while (ch >= '0' && ch <= '9') {
4182 if (!isFinite(number)) {
4183 error("Bad number");
4189 string = function () {
4190 // Parse a string value.
4196 // When parsing for string values, we must look for " and \ characters.
4202 } else if (ch === '\\') {
4206 for (i = 0; i < 4; i += 1) {
4207 hex = parseInt(next(), 16);
4208 if (!isFinite(hex)) {
4211 uffff = uffff * 16 + hex;
4213 string += String.fromCharCode(uffff);
4214 } else if (typeof escapee[ch] === 'string') {
4215 string += escapee[ch];
4224 error("Bad string");
4227 white = function () {
4231 while (ch && ch <= ' ') {
4236 word = function () {
4238 // true, false, or null.
4261 error("Unexpected '" + ch + "'");
4264 value, // Place holder for the value function.
4266 array = function () {
4268 // Parse an array value.
4277 return array; // empty array
4280 array.push(value());
4293 object = function () {
4295 // Parse an object value.
4305 return object; // empty object
4311 if (Object.hasOwnProperty.call(object, key)) {
4312 error('Duplicate key "' + key + '"');
4314 object[key] = value();
4324 error("Bad object");
4327 value = function () {
4329 // Parse a JSON value. It could be an object, an array, a string, a number,
4343 return ch >= '0' && ch <= '9' ? number() : word();
4347 // Return the json_parse function. It will have access to all of the above
4348 // functions and variables.
4350 module.exports = function (source, reviver) {
4359 error("Syntax error");
4362 // If there is a reviver function, we recursively walk the new structure,
4363 // passing each name/value pair to the reviver function for possible
4364 // transformation, starting with a temporary root object that holds the result
4365 // in an empty key. If there is not a reviver function, we simply return the
4368 return typeof reviver === 'function' ? (function walk(holder, key) {
4369 var k, v, value = holder[key];
4370 if (value && typeof value === 'object') {
4372 if (Object.prototype.hasOwnProperty.call(value, k)) {
4374 if (v !== undefined) {
4382 return reviver.call(holder, key, value);
4383 }({'': result}, '')) : result;
4386 }).call(module.exports);
4388 __require.modules["/node_modules/jsonify/lib/parse.js"]._cached = module.exports;
4389 return module.exports;
4392 require.modules["/node_modules/jsonify/lib/stringify.js"] = function () {
4393 var module = { exports : {} };
4394 var exports = module.exports;
4395 var __dirname = "/node_modules/jsonify/lib";
4396 var __filename = "/node_modules/jsonify/lib/stringify.js";
4398 var require = function (file) {
4399 return __require(file, "/node_modules/jsonify/lib");
4402 require.resolve = function (file) {
4403 return __require.resolve(name, "/node_modules/jsonify/lib");
4406 require.modules = __require.modules;
4407 __require.modules["/node_modules/jsonify/lib/stringify.js"]._cached = module.exports;
4410 var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
4411 escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
4414 meta = { // table of character substitutions
4425 function quote(string) {
4426 // If the string contains no control characters, no quote characters, and no
4427 // backslash characters, then we can safely slap some quotes around it.
4428 // Otherwise we must also replace the offending characters with safe escape
4431 escapable.lastIndex = 0;
4432 return escapable.test(string) ? '"' + string.replace(escapable, function (a) {
4434 return typeof c === 'string' ? c :
4435 '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
4436 }) + '"' : '"' + string + '"';
4439 function str(key, holder) {
4440 // Produce a string from holder[key].
4441 var i, // The loop counter.
4442 k, // The member key.
4443 v, // The member value.
4447 value = holder[key];
4449 // If the value has a toJSON method, call it to obtain a replacement value.
4450 if (value && typeof value === 'object' &&
4451 typeof value.toJSON === 'function') {
4452 value = value.toJSON(key);
4455 // If we were called with a replacer function, then call the replacer to
4456 // obtain a replacement value.
4457 if (typeof rep === 'function') {
4458 value = rep.call(holder, key, value);
4461 // What happens next depends on the value's type.
4462 switch (typeof value) {
4464 return quote(value);
4467 // JSON numbers must be finite. Encode non-finite numbers as null.
4468 return isFinite(value) ? String(value) : 'null';
4472 // If the value is a boolean or null, convert it to a string. Note:
4473 // typeof null does not produce 'null'. The case is included here in
4474 // the remote chance that this gets fixed someday.
4475 return String(value);
4478 if (!value) return 'null';
4483 if (Object.prototype.toString.apply(value) === '[object Array]') {
4484 length = value.length;
4485 for (i = 0; i < length; i += 1) {
4486 partial[i] = str(i, value) || 'null';
4489 // Join all of the elements together, separated with commas, and
4490 // wrap them in brackets.
4491 v = partial.length === 0 ? '[]' : gap ?
4492 '[\n' + gap + partial.join(',\n' + gap) + '\n' + mind + ']' :
4493 '[' + partial.join(',') + ']';
4498 // If the replacer is an array, use it to select the members to be
4500 if (rep && typeof rep === 'object') {
4501 length = rep.length;
4502 for (i = 0; i < length; i += 1) {
4504 if (typeof k === 'string') {
4507 partial.push(quote(k) + (gap ? ': ' : ':') + v);
4513 // Otherwise, iterate through all of the keys in the object.
4515 if (Object.prototype.hasOwnProperty.call(value, k)) {
4518 partial.push(quote(k) + (gap ? ': ' : ':') + v);
4524 // Join all of the member texts together, separated with commas,
4525 // and wrap them in braces.
4527 v = partial.length === 0 ? '{}' : gap ?
4528 '{\n' + gap + partial.join(',\n' + gap) + '\n' + mind + '}' :
4529 '{' + partial.join(',') + '}';
4535 module.exports = function (value, replacer, space) {
4540 // If the space parameter is a number, make an indent string containing that
4542 if (typeof space === 'number') {
4543 for (i = 0; i < space; i += 1) {
4547 // If the space parameter is a string, it will be used as the indent string.
4548 else if (typeof space === 'string') {
4552 // If there is a replacer, it must be a function or an array.
4553 // Otherwise, throw an error.
4555 if (replacer && typeof replacer !== 'function'
4556 && (typeof replacer !== 'object' || typeof replacer.length !== 'number')) {
4557 throw new Error('JSON.stringify');
4560 // Make a fake root object containing our value under the key of ''.
4561 // Return the result of stringifying the value.
4562 return str('', {'': value});
4565 }).call(module.exports);
4567 __require.modules["/node_modules/jsonify/lib/stringify.js"]._cached = module.exports;
4568 return module.exports;
4571 require.modules["/node_modules/burrito/index.js"] = function () {
4572 var module = { exports : {} };
4573 var exports = module.exports;
4574 var __dirname = "/node_modules/burrito";
4575 var __filename = "/node_modules/burrito/index.js";
4577 var require = function (file) {
4578 return __require(file, "/node_modules/burrito");
4581 require.resolve = function (file) {
4582 return __require.resolve(name, "/node_modules/burrito");
4585 require.modules = __require.modules;
4586 __require.modules["/node_modules/burrito/index.js"]._cached = module.exports;
4589 var uglify = require('uglify-js');
4590 var parser = uglify.parser;
4591 var parse = function (expr) {
4592 if (typeof expr !== 'string') throw 'expression should be a string';
4595 var args = [].slice.call(arguments);
4596 var ast = parser.parse.apply(null, args);
4599 if (err.message === undefined
4600 || err.line === undefined
4601 || err.col === undefined
4602 || err.pos === undefined
4605 var e = new SyntaxError(
4607 + '\n at line ' + err.line + ':' + err.col + ' in expression:\n\n'
4608 + ' ' + expr.split(/\r?\n/)[err.line]
4621 var deparse = function (ast, b) {
4622 return uglify.uglify.gen_code(ast, { beautify : b });
4625 var traverse = require('traverse');
4626 var vm = require('vm');
4628 var burrito = module.exports = function (code, cb) {
4629 var ast = Array_isArray(code)
4630 ? code // already an ast
4631 : parse(code.toString(), false, true)
4634 var ast_ = traverse(ast).map(function mapper () {
4638 return deparse(parse(deparse(ast_)), true);
4641 var wrapNode = burrito.wrapNode = function (state, cb) {
4642 var node = state.node;
4644 var ann = Array_isArray(node) && node[0]
4645 && typeof node[0] === 'object' && node[0].name
4650 if (!ann) return undefined;
4655 start : node[0].start,
4657 value : node.slice(1),
4661 self.wrap = function (s) {
4662 var subsrc = deparse(
4663 traverse(node).map(function (x) {
4664 if (!this.isRoot) wrapNode(this, cb)
4668 if (self.name === 'binary') {
4669 var a = deparse(traverse(node[2]).map(function (x) {
4670 if (!this.isRoot) wrapNode(this, cb)
4672 var b = deparse(traverse(node[3]).map(function (x) {
4673 if (!this.isRoot) wrapNode(this, cb)
4679 if (typeof s === 'function') {
4680 if (self.name === 'binary') {
4681 src = s(subsrc, a, b);
4689 .replace(/%s/g, function () {
4694 if (self.name === 'binary') {
4696 .replace(/%a/g, function () { return a })
4697 .replace(/%b/g, function () { return b })
4702 var expr = parse(src);
4703 state.update(expr, true);
4708 self.parent = state.isRoot ? null : function () {
4709 if (!cache.parent) {
4714 if (s) x = wrapNode(s);
4720 return cache.parent;
4723 self.source = function () {
4724 if (!cache.source) cache.source = deparse(node);
4725 return cache.source;
4728 self.label = function () {
4729 return burrito.label(self);
4732 if (cb) cb.call(state, self);
4734 if (self.node[0].name === 'conditional') {
4735 self.wrap('[%s][0]');
4741 burrito.microwave = function (code, context, cb) {
4742 if (!cb) { cb = context; context = {} };
4743 if (!context) context = {};
4745 var src = burrito(code, cb);
4746 return vm.runInNewContext(src, context);
4749 burrito.generateName = function (len) {
4751 var lower = '$'.charCodeAt(0);
4752 var upper = 'z'.charCodeAt(0);
4754 while (name.length < len) {
4755 var c = String.fromCharCode(Math.floor(
4756 Math.random() * (upper - lower + 1) + lower
4758 if ((name + c).match(/^[A-Za-z_$][A-Za-z0-9_$]*$/)) name += c;
4764 burrito.parse = parse;
4765 burrito.deparse = deparse;
4767 burrito.label = function (node) {
4768 if (node.name === 'call') {
4769 if (typeof node.value[0] === 'string') {
4770 return node.value[0];
4772 else if (node.value[0] && typeof node.value[0][1] === 'string') {
4773 return node.value[0][1];
4779 else if (node.name === 'var') {
4780 return node.value[0].map(function (x) { return x[0] });
4782 else if (node.name === 'defun') {
4783 return node.value[0];
4785 else if (node.name === 'function') {
4786 return node.value[0];
4793 var Array_isArray = Array.isArray || function isArray (xs) {
4794 return Object.prototype.toString.call(xs) === '[object Array]';
4797 }).call(module.exports);
4799 __require.modules["/node_modules/burrito/index.js"]._cached = module.exports;
4800 return module.exports;
4803 process.nextTick(function () {
4804 var module = { exports : {} };
4805 var exports = module.exports;
4806 var __dirname = "/";
4807 var __filename = "//home/substack/projects/node-burrito/example/web";
4809 var require = function (file) {
4810 return __require(file, "/");
4812 require.modules = __require.modules;
4814 var burrito = require('burrito');
4815 var json = require('jsonify');
4818 'function f () { g() }',
4819 'function g () { h() }',
4820 'function h () { throw "moo" + Array(x).join("!") }',
4825 window.onload = function () {
4826 burrito(src, function (node) {
4827 document.body.innerHTML += node.name + '<br>\n';
4830 if (document.readyState === 'complete') window.onload();