[Pkg-javascript-commits] [node-grunt-contrib-uglify] 01/09: Import Upstream version 2.0.0

Paolo Greppi paolog-guest at moszumanska.debian.org
Wed Dec 21 07:06:28 UTC 2016


This is an automated email from the git hooks/post-receive script.

paolog-guest pushed a commit to branch master
in repository node-grunt-contrib-uglify.

commit cadeed76f89a32934f3e74f846f5c99e7cf144f0
Author: Paolo Greppi <paolo.greppi at libpf.com>
Date:   Tue Dec 20 07:23:01 2016 +0000

    Import Upstream version 2.0.0
---
 .editorconfig                                      |  11 +
 .gitattributes                                     |   3 +
 .gitignore                                         |   5 +
 .jshintrc                                          |  14 +
 .travis.yml                                        |  18 +
 AUTHORS                                            |   3 +
 CHANGELOG                                          | 159 ++++++
 CONTRIBUTING.md                                    |   1 +
 Gruntfile.js                                       | 437 ++++++++++++++++
 LICENSE-MIT                                        |  22 +
 README.md                                          | 559 +++++++++++++++++++++
 appveyor.yml                                       |  39 ++
 docs/uglify-examples.md                            | 286 +++++++++++
 docs/uglify-options.md                             | 179 +++++++
 docs/uglify-overview.md                            |  22 +
 package.json                                       |  39 ++
 tasks/lib/uglify.js                                | 294 +++++++++++
 tasks/uglify.js                                    | 190 +++++++
 test/fixtures/expected/asciionly.js                |   1 +
 test/fixtures/expected/beautify.js                 |   2 +
 test/fixtures/expected/comments.js                 |  13 +
 test/fixtures/expected/compress.js                 |   1 +
 test/fixtures/expected/compress_explicit.js        |   1 +
 test/fixtures/expected/compress_mangle.js          |   1 +
 test/fixtures/expected/compress_mangle_banner.js   |   2 +
 test/fixtures/expected/compress_mangle_beautify.js |   6 +
 test/fixtures/expected/compress_mangle_except.js   |   1 +
 .../deep/directory/location/source_map.js.map      |   1 +
 test/fixtures/expected/enclose.js                  |   8 +
 test/fixtures/expected/exportAll.js                |   1 +
 test/fixtures/expected/expression.js               |   1 +
 test/fixtures/expected/expression.json             |   1 +
 test/fixtures/expected/mangle.js                   |   1 +
 test/fixtures/expected/mangleprops.js              |   1 +
 test/fixtures/expected/mangleprops_withExcept.js   |   1 +
 .../mangleprops_withExceptAndExceptionsFiles.js    |   1 +
 .../expected/mangleprops_withExceptionsFiles.js    |   1 +
 .../expected/mangleprops_withNameCacheFile1.js     |   1 +
 .../expected/mangleprops_withNameCacheFile2.js     |   1 +
 test/fixtures/expected/mangleprops_withRegex.js    |   1 +
 test/fixtures/expected/maxLineLen.js               |   5 +
 test/fixtures/expected/multifile.js                |   1 +
 test/fixtures/expected/quotes_double.js            |   1 +
 test/fixtures/expected/quotes_original.js          |   1 +
 test/fixtures/expected/quotes_single.js            |   1 +
 test/fixtures/expected/screwIE8.js                 |   1 +
 test/fixtures/expected/source_map_custom_name      |   1 +
 test/fixtures/expected/sourcemap_basic.js          |   2 +
 test/fixtures/expected/sourcemap_basic.js.map      |   1 +
 test/fixtures/expected/sourcemap_customDir.js      |   2 +
 test/fixtures/expected/sourcemap_customName.js     |   2 +
 test/fixtures/expected/sourcemap_customRoot.js     |   2 +
 test/fixtures/expected/sourcemap_customRoot.js.map |   1 +
 test/fixtures/expected/sourcemap_customUrl.js      |   2 +
 test/fixtures/expected/sourcemap_functionName.js   |   2 +
 .../expected/sourcemap_functionName.js.fn.map      |   1 +
 test/fixtures/expected/sourcemap_sources.js.map    |   1 +
 test/fixtures/expected/sourcemapin.js              |   4 +
 test/fixtures/expected/sourcemapin.js.map          |   1 +
 test/fixtures/expected/sourcemapin_sources.js      |   2 +
 test/fixtures/expected/sourcemapin_sources.js.map  |   1 +
 test/fixtures/expected/sourcemaps_multiple1.js     |   2 +
 test/fixtures/expected/sourcemaps_multiple1.js.map |   1 +
 .../expected/sourcemaps_multiple1_fnName.js        |   2 +
 .../expected/sourcemaps_multiple1_fnName.js.fn.map |   1 +
 test/fixtures/expected/sourcemaps_multiple2.js     |   2 +
 test/fixtures/expected/sourcemaps_multiple2.js.map |   1 +
 .../expected/sourcemaps_multiple2_fnName.js        |   2 +
 .../expected/sourcemaps_multiple2_fnName.js.fn.map |   1 +
 test/fixtures/expected/uglify_name_cache.json      |  19 +
 test/fixtures/expected/wrap.js                     |   1 +
 test/fixtures/src/comments.js                      |  21 +
 test/fixtures/src/exceptionsfile1.json             |   4 +
 test/fixtures/src/exceptionsfile2.json             |   5 +
 test/fixtures/src/expression.js                    |   3 +
 test/fixtures/src/localization.js                  |   6 +
 test/fixtures/src/mangleprops.js                   |   8 +
 test/fixtures/src/mangleprops_withNameCache.js     |   2 +
 test/fixtures/src/mangleprops_withRegex.js         |   4 +
 test/fixtures/src/quotes.js                        |  11 +
 test/fixtures/src/screwIE8.js                      |   5 +
 test/fixtures/src/simple.js                        |  15 +
 test/fixtures/src/simple.json                      |   8 +
 test/fixtures/src/simple2.coffee                   |  28 ++
 test/fixtures/src/simple2.js                       |  39 ++
 test/fixtures/src/simple2.map                      |   1 +
 test/uglify_test.js                                |  78 +++
 87 files changed, 2634 insertions(+)

diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000..59290ba
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,11 @@
+root = true
+
+[*]
+indent_style = space
+indent_size = 2
+end_of_line = lf
+insert_final_newline = true
+trim_trailing_whitespace = true
+
+[*.md]
+trim_trailing_whitespace = false
diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..431be3b
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,3 @@
+* text=auto
+*.js text eol=lf
+*.js.map text eol=lf
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..dc3f724
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,5 @@
+node_modules
+npm-debug.log
+tmp
+.idea
+.DS_Store
diff --git a/.jshintrc b/.jshintrc
new file mode 100644
index 0000000..507f912
--- /dev/null
+++ b/.jshintrc
@@ -0,0 +1,14 @@
+{
+  "boss": true,
+  "curly": true,
+  "eqeqeq": true,
+  "eqnull": true,
+  "immed": true,
+  "latedef": true,
+  "newcap": true,
+  "noarg": true,
+  "node": true,
+  "sub": true,
+  "undef": true,
+  "unused": true
+}
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..2eac80c
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,18 @@
+sudo: false
+
+language: node_js
+
+node_js:
+  - "0.10"
+  - "0.12"
+  - "4"
+  - "5"
+  - "6"
+  - "iojs"
+
+matrix:
+  fast_finish: true
+
+cache:
+  directories:
+    - node_modules
diff --git a/AUTHORS b/AUTHORS
new file mode 100644
index 0000000..ae935c1
--- /dev/null
+++ b/AUTHORS
@@ -0,0 +1,3 @@
+"Cowboy" Ben Alman (http://benalman.com)
+Tyler Kellen (http://goingslowly.com)
+Jarrod Overson (http://jarrodoverson.com)
\ No newline at end of file
diff --git a/CHANGELOG b/CHANGELOG
new file mode 100644
index 0000000..b7bb15e
--- /dev/null
+++ b/CHANGELOG
@@ -0,0 +1,159 @@
+v2.0.0:
+  date: 2016-07-19
+  changes:
+    - Update uglify-js to v2.7.0. `screwIE8` is enabled by default.
+v1.0.2:
+  date: 2016-07-19
+  changes:
+    - Update grunt to ^1.0.0.
+    - Fix `beautify` when passed as an object.
+    - Fix docs about `report` values.
+v1.0.1:
+  date: 2016-03-16
+  changes:
+    - Downgrade maxmin for Node.js 0.10.
+v1.0.0:
+  date: 2016-03-04
+  changes:
+    - Use uglify-js ~2.6.2 to fix sourcemap issue.
+    - Improve docs for `global-defs` and `--define` options.
+    - Add `sourceMapUrl` option.
+    - Add `bare_returns` option.
+    - Optionally set report verbosity level using report option.
+v0.11.1:
+  date: 2016-01-29
+  changes:
+    - Update lodash to ^4.0.1.
+    - Update grunt-contrib-clean to ^0.7.0.
+    - Update grunt-contrib-jshint to ^0.12.0.
+v0.11.0:
+  date: 2015-11-20
+  changes:
+    - Update uglify-js to ~2.6.0.
+v0.10.1:
+  date: 2015-11-12
+  changes:
+    - Update uglify-js to ~2.5.
+v0.10.0:
+  date: 2015-10-27
+  changes:
+    - Update uglify-js to ^2.5.
+v0.9.2:
+  date: 2015-08-24
+  changes:
+    - Update uglify-js to ^2.4.24
+v0.9.1:
+  date: 2015-04-07
+  changes:
+    - More fixes for `mangle` options.
+v0.9.0:
+  date: 2015-04-07
+  changes:
+    - Add hook into uglify-js's mangling functionality.
+v0.8.1:
+  date: 2015-03-30
+  changes:
+    - Lock uglify-js to 2.4.17 due to breaking changes.
+v0.8.0:
+  date: 2015-02-19
+  changes:
+    - Add `screwIE8` option.
+    - Fix issue with explicit `compress` in Node.js 0.12.0.
+v0.7.0:
+  date: 2014-12-23
+  changes:
+    - Add `sourceMapRoot` options.
+    - Update readme descriptions.
+    - Remove reference to clean-css.
+v0.6.0:
+  date: 2014-09-17
+  changes:
+    - Output fixes.
+    - 'Add `ASCIIOnly` option.'
+    - Other fixes.
+v0.5.1:
+  date: 2014-07-25
+  changes:
+    - Update chalk to ^0.5.1.
+    - Output updates.
+v0.4.0:
+  date: 2014-03-01
+  changes:
+    - Remove grunt-lib-contrib dependency and add more colors.
+v0.3.3:
+  date: 2014-02-27
+  changes:
+    - Remove unnecessary calls to `grunt.template.process`.
+v0.3.2:
+  date: 2014-01-22
+  changes:
+    - Fix handling of `sourceMapIncludeSources` option.
+v0.3.1:
+  date: 2014-01-20
+  changes:
+    - Fix relative path issue in sourcemaps.
+v0.3.0:
+  date: 2014-01-16
+  changes:
+    - Refactor sourcemap support.
+v0.2.7:
+  date: 2013-11-09
+  changes:
+    - 'Prepend banner if `sourceMap` option not set, addresses #109.'
+v0.2.6:
+  date: 2013-11-08
+  changes:
+    - 'Merge #45, #53, #85 (#105 by way of duping #53).'
+    - Add support for banners in uglified files with sourcemaps.
+    - Update docs.
+v0.2.5:
+  date: 2013-10-28
+  changes:
+    - Add warning for banners when using sourcemaps.
+v0.2.4:
+  date: 2013-09-02
+  changes:
+    - 'Update sourcemap format via #83.'
+v0.2.3:
+  date: 2013-06-10
+  changes:
+    - Add `footer` option.
+v0.2.2:
+  date: 2013-05-31
+  changes:
+    - 'Revert #56 due to #58 until [chrome/239660](https://code.google.com/p/chromium/issues/detail?id=239660&q=sourcemappingurl&colspec=ID%20Pri%20M%20Iteration%20ReleaseBlock%20Cr%20Status%20Owner%20Summary%20OS%20Modified) [firefox/870361](https://bugzilla.mozilla.org/show_bug.cgi?id=870361) drop.'
+v0.2.1:
+  date: 2013-05-22
+  changes:
+    - 'Update uglify-js to ~2.3.5 #55 #40.'
+    - 'Change `sourcemappingUrl` syntax #56.'
+    - 'Disable sorting of names for consistent mangling #44.'
+    - 'Update docs for `sourceMapRoot` #47 #25.'
+v0.2.0:
+  date: 2013-03-14
+  changes:
+    - No longer report gzip results by default.
+    - Support `report` option.
+v0.1.2:
+  date: 2013-01-30
+  changes:
+    - Add better error reporting.
+    - Support for dynamic names of multiple sourcemaps.
+v0.1.1:
+  date: 2013-02-15
+  changes:
+    - First official release for Grunt 0.4.0.
+v0.1.1rc6:
+  date: 2013-01-18
+  changes:
+    - Update grunt/gruntplugin dependencies to rc6.
+    - Change in-development grunt/gruntplugin dependency versions from tilde version ranges to specific versions.
+v0.1.1rc5:
+  date: 2013-01-09
+  changes:
+    - Update to work with grunt v0.4.0rc5.
+    - Switch back to `this.files` API.
+v0.1.0:
+  date: 2012-11-28
+  changes:
+    - Work in progress, not officially released yet.
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 0000000..5d08cc3
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1 @@
+Please see the [Contributing to grunt](http://gruntjs.com/contributing) guide for information on contributing to this project.
diff --git a/Gruntfile.js b/Gruntfile.js
new file mode 100644
index 0000000..5003c2a
--- /dev/null
+++ b/Gruntfile.js
@@ -0,0 +1,437 @@
+/*
+ * grunt-contrib-uglify
+ * http://gruntjs.com/
+ *
+ * Copyright (c) 2016 "Cowboy" Ben Alman, contributors
+ * Licensed under the MIT license.
+ */
+
+'use strict';
+
+module.exports = function(grunt) {
+
+  // Project configuration.
+  grunt.initConfig({
+    jshint: {
+      all: [
+        'Gruntfile.js',
+        'tasks/**/*.js',
+        '<%= nodeunit.tests %>'
+      ],
+      options: {
+        jshintrc: '.jshintrc'
+      }
+    },
+
+    // Before generating any new files, remove any previously-created files.
+    clean: {
+      tests: ['tmp']
+    },
+
+    // Configuration to be run (and then tested).
+    uglify: {
+      compress: {
+        files: {
+          'tmp/compress.js': ['test/fixtures/src/simple.js']
+        },
+        options: {
+          mangle: false
+        }
+      },
+      compress_explicit: {
+        files: {
+          'tmp/compress_explicit.js': ['test/fixtures/src/simple.js']
+        },
+        options: {
+          compress: true
+        }
+      },
+      compress_mangle: {
+        files: {
+          'tmp/compress_mangle.js': ['test/fixtures/src/simple.js']
+        }
+      },
+      compress_mangle_banner: {
+        files: {
+          'tmp/compress_mangle_banner.js': ['test/fixtures/src/simple.js']
+        },
+        options: {
+          banner: '// banner without sourcemap\n'
+        }
+      },
+      no_src: {
+        files: {
+          'tmp/compress_mangle.js': []
+        }
+      },
+      compress_mangle_except: {
+        files: {
+          'tmp/compress_mangle_except.js': ['test/fixtures/src/simple.js']
+        },
+        options: {
+          mangle: {
+            except: ['argumentC']
+          }
+        }
+      },
+      compress_mangle_beautify: {
+        files: {
+          'tmp/compress_mangle_beautify.js': ['test/fixtures/src/simple.js']
+        },
+        options: {
+          beautify: true,
+          footer: '\n// This is a footer.'
+        }
+      },
+      enclose: {
+        files: {
+          'tmp/enclose.js': ['test/fixtures/src/simple.js']
+        },
+        options: {
+          beautify: true,
+          compress: false,
+          enclose: {
+            'window.argA': 'paramA',
+            'window.argB': 'paramB'
+          },
+          mangle: false
+        }
+      },
+      multifile: {
+        files: {
+          'tmp/multifile.js': ['test/fixtures/src/simple.js', 'test/fixtures/src/comments.js']
+        },
+        options: {
+          mangle: false
+        }
+      },
+      comments: {
+        src: 'test/fixtures/src/comments.js',
+        dest: 'tmp/comments.js',
+        options: {
+          mangle: false,
+          preserveComments: 'some'
+        }
+      },
+      wrap: {
+        src: 'test/fixtures/src/simple.js',
+        dest: 'tmp/wrap.js',
+        options: {
+          mangle: false,
+          wrap: 'testExport'
+        }
+      },
+      maxLineLen: {
+        src: 'test/fixtures/src/simple2.js',
+        dest: 'tmp/maxLineLen.js',
+        options: {
+          mangle: false,
+          maxLineLen: 100
+        }
+      },
+      ASCIIOnly: {
+        src: 'test/fixtures/src/localization.js',
+        dest: 'tmp/asciionly.js',
+        options: {
+          mangle: false,
+          ASCIIOnly: true
+        }
+      },
+      screwIE8: {
+        src: 'test/fixtures/src/screwIE8.js',
+        dest: 'tmp/screwIE8.js',
+        options: {
+          screwIE8: false
+        }
+      },
+      exportAll: {
+        src: 'test/fixtures/src/simple.js',
+        dest: 'tmp/exportAll.js',
+        options: {
+          mangle: false,
+          wrap: 'testExport',
+          exportAll: true
+        }
+      },
+      sourcemap_basic: {
+        src: 'test/fixtures/src/simple.js',
+        dest: 'tmp/sourcemap_basic.js',
+        options: {
+          sourceMap: true
+        }
+      },
+      sourcemap_customName: {
+        src: 'test/fixtures/src/simple.js',
+        dest: 'tmp/sourcemap_customName.js',
+        options: {
+          sourceMap: true,
+          sourceMapName: 'tmp/source_map_custom_name'
+        }
+      },
+      sourcemap_customDir: {
+        src: 'test/fixtures/src/simple.js',
+        dest: 'tmp/sourcemap_customDir.js',
+        options: {
+          sourceMap: true,
+          sourceMapName: 'tmp/deep/directory/location/source_map.js.map'
+        }
+      },
+      sourcemap_customRoot: {
+        src: 'test/fixtures/src/simple.js',
+        dest: 'tmp/sourcemap_customRoot.js',
+        options: {
+          sourceMap: true,
+          sourceMapRoot: 'https://github.com/RReverser/grunt-contrib-uglify/tree/master/tmp'
+        }
+      },
+      sourcemap_customUrl: {
+        src: 'test/fixtures/src/simple.js',
+        dest: 'tmp/sourcemap_customUrl.js',
+        options: {
+          sourceMap: true,
+          sourceMapUrl: 'http://www.test.com/test/sourcemap_customUrl.js.map'
+        }
+      },
+      sourcemap_functionName: {
+        src: 'test/fixtures/src/simple.js',
+        dest: 'tmp/sourcemap_functionName.js',
+        options: {
+          sourceMap: true,
+          sourceMapName: function(dest) {
+            return dest + '.fn.map';
+          }
+        }
+      },
+      sourcemap_multiple: {
+        files: {
+          'tmp/sourcemaps_multiple1.js': ['test/fixtures/src/simple.js'],
+          'tmp/sourcemaps_multiple2.js': ['test/fixtures/src/comments.js']
+        },
+        options: {
+          sourceMap: true
+        }
+      },
+      sourcemap_multipleFunctionNames: {
+        files: {
+          'tmp/sourcemaps_multiple1_fnName.js': ['test/fixtures/src/simple.js'],
+          'tmp/sourcemaps_multiple2_fnName.js': ['test/fixtures/src/comments.js']
+        },
+        options: {
+          sourceMap: true,
+          sourceMapName: function(dest) {
+            return dest+'.fn.map';
+          }
+        }
+      },
+      sourcemapin: {
+        files: {
+          'tmp/sourcemapin.js': ['test/fixtures/src/simple2.js']
+        },
+        options: {
+          mangle: false,
+          banner: '// Hello World\n',
+          sourceMap: true,
+          sourceMapIn: function() {
+            return 'test/fixtures/src/simple2.map';
+          },
+          sourceMapIncludeSources: false
+        }
+      },
+      sourcemap_sources: {
+        files: {
+          'tmp/sourcemap_sources.js': ['test/fixtures/src/simple.js']
+        },
+        options: {
+          sourceMap: true,
+          sourceMapIncludeSources: true
+        }
+      },
+      sourcemapin_sources: {
+        files: {
+          'tmp/sourcemapin_sources.js': ['test/fixtures/src/simple2.js']
+        },
+        options: {
+          sourceMap: true,
+          sourceMapIn: function() {
+            return 'test/fixtures/src/simple2.map';
+          },
+          sourceMapIncludeSources: true
+        }
+      },
+      expression_json: {
+        files: {
+          'tmp/expression.json': ['test/fixtures/src/simple.json']
+        },
+        options: {
+          expression: true,
+          mangle: false,
+          compress: false
+        }
+      },
+      expression_js: {
+        files: {
+          'tmp/expression.js': ['test/fixtures/src/expression.js']
+        },
+        options: {
+          expression: true,
+          mangle: false,
+          compress: false
+        }
+      },
+      mangleprops: {
+        files: {
+          'tmp/mangleprops.js': ['test/fixtures/src/mangleprops.js']
+        },
+        options: {
+          mangleProperties: true
+        }
+      },
+      mangleprops_withExcept: {
+        files: {
+          'tmp/mangleprops_withExcept.js': ['test/fixtures/src/mangleprops.js']
+        },
+        options: {
+          mangle: {
+            except: ['dontMangleMeVariable']
+          },
+          mangleProperties: true
+        }
+      },
+      mangleprops_withExceptionsFiles: {
+        files: {
+          'tmp/mangleprops_withExceptionsFiles.js': ['test/fixtures/src/mangleprops.js']
+        },
+        options: {
+          mangle: {
+            toplevel: true
+          },
+          mangleProperties: true,
+          exceptionsFiles: ['test/fixtures/src/exceptionsfile1.json', 'test/fixtures/src/exceptionsfile2.json']
+        }
+      },
+      mangleprops_withExceptAndExceptionsFiles: {
+        files: {
+          'tmp/mangleprops_withExceptAndExceptionsFiles.js': ['test/fixtures/src/mangleprops.js']
+        },
+        options: {
+          mangle: {
+            toplevel: true,
+            except: ['dontMangleMeVariable']
+          },
+          mangleProperties: true,
+          exceptionsFiles: ['test/fixtures/src/exceptionsfile1.json', 'test/fixtures/src/exceptionsfile2.json']
+        }
+      },
+      mangleprops_withNameCacheFile: {
+        files: {
+          'tmp/mangleprops_withNameCacheFile1.js': ['test/fixtures/src/mangleprops.js'],
+          'tmp/mangleprops_withNameCacheFile2.js': ['test/fixtures/src/mangleprops_withNameCache.js']
+        },
+        options: {
+          mangle: {
+            toplevel: true
+          },
+          mangleProperties: true,
+          nameCache: 'tmp/uglify_name_cache.json'
+        }
+      },
+      mangleprops_withRegex: {
+        files: {
+          'tmp/mangleprops_withRegex.js': ['test/fixtures/src/mangleprops_withRegex.js']
+        },
+        options: {
+          mangleProperties: {
+            regex: /^[^#].*/
+          }
+        }
+      },
+      quotes_single: {
+        files: {
+          'tmp/quotes_single.js': ['test/fixtures/src/quotes.js']
+        },
+        options: {
+          quoteStyle: 1
+        }
+      },
+      quotes_double: {
+        files: {
+          'tmp/quotes_double.js': ['test/fixtures/src/quotes.js']
+        },
+        options: {
+          quoteStyle: 2
+        }
+      },
+      quotes_original: {
+        files: {
+          'tmp/quotes_original.js': ['test/fixtures/src/quotes.js']
+        },
+        options: {
+          quoteStyle: 3
+        }
+      },
+      mangle_isNotObject: {
+        files: {
+          'tmp/mangle.js': ['test/fixtures/src/simple.js']
+        },
+        mangle: true
+      },
+      beautify_Object: {
+        files: {
+          'tmp/beautify.js': ['test/fixtures/src/localization.js', 'test/fixtures/src/simple.js']
+        },
+        options: {
+          beautify: {
+            'ascii_only': true,
+            'indent_start': 2,
+            'max_line_len': 40
+          }
+        }
+      }
+    },
+
+    // Unit tests.
+    nodeunit: {
+      tests: ['test/*_test.js']
+    }
+  });
+
+  // task that expects its argument (another task) to fail
+  grunt.registerTask('expectFail', function() {
+    var task = this.args.join(':');
+
+    var done = this.async();
+
+    function onComplete(error, result) {
+      grunt.log.write('\n > ' + result.stdout.split('\n').join('\n > ') + '\n');
+      var rv = error ? true : new Error('Task ' + task + ' unexpectedly passed.');
+      done(rv);
+    }
+
+    grunt.util.spawn({
+      grunt: true,
+      args: task
+    }, onComplete);
+  });
+
+  // Actually load this plugin's task(s).
+  grunt.loadTasks('tasks');
+
+  // These plugins provide necessary tasks.
+  grunt.loadNpmTasks('grunt-contrib-jshint');
+  grunt.loadNpmTasks('grunt-contrib-clean');
+  grunt.loadNpmTasks('grunt-contrib-nodeunit');
+  grunt.loadNpmTasks('grunt-contrib-internal');
+
+  // Whenever the "test" task is run, first clean the "tmp" dir, then run this
+  // plugin's task(s), then test the result.
+  grunt.registerTask('test', [
+    'jshint',
+    'clean',
+    'uglify',
+    'nodeunit'
+  ]);
+
+  // By default, lint and run all tests.
+  grunt.registerTask('default', ['test', 'build-contrib']);
+
+};
diff --git a/LICENSE-MIT b/LICENSE-MIT
new file mode 100644
index 0000000..8fbdfc1
--- /dev/null
+++ b/LICENSE-MIT
@@ -0,0 +1,22 @@
+Copyright (c) 2016 "Cowboy" Ben Alman, contributors
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..20aeea4
--- /dev/null
+++ b/README.md
@@ -0,0 +1,559 @@
+# grunt-contrib-uglify v2.0.0 [![Build Status: Linux](https://travis-ci.org/gruntjs/grunt-contrib-uglify.svg?branch=master)](https://travis-ci.org/gruntjs/grunt-contrib-uglify) [![Build Status: Windows](https://ci.appveyor.com/api/projects/status/ybtf5vbvtenii561/branch/master?svg=true)](https://ci.appveyor.com/project/gruntjs/grunt-contrib-uglify/branch/master)
+
+> Minify JavaScript files with UglifyJS
+
+
+
+## Getting Started
+
+If you haven't used [Grunt](http://gruntjs.com/) before, be sure to check out the [Getting Started](http://gruntjs.com/getting-started) guide, as it explains how to create a [Gruntfile](http://gruntjs.com/sample-gruntfile) as well as install and use Grunt plugins. Once you're familiar with that process, you may install this plugin with this command:
+
+```shell
+npm install grunt-contrib-uglify --save-dev
+```
+
+Once the plugin has been installed, it may be enabled inside your Gruntfile with this line of JavaScript:
+
+```js
+grunt.loadNpmTasks('grunt-contrib-uglify');
+```
+
+
+
+
+## Uglify task
+_Run this task with the `grunt uglify` command._
+
+Task targets, files and options may be specified according to the grunt [Configuring tasks](http://gruntjs.com/configuring-tasks) guide.
+
+### Migrating from 2.x to 3.x
+
+Version `3.x` introduced changes to configuring source maps. Accordingly, if you don't use the source map options you should be able to upgrade seamlessly. If you do use source maps, see below.
+
+#### Removed options
+
+`sourceMappingURL` - This is calculated automatically now
+`sourceMapPrefix` - No longer necessary for the above reason
+
+#### Changed options
+
+`sourceMap` - Only accepts a `Boolean` value. Generates a map with a default name for you
+`sourceMapRoot` - The location of your sources is now calculated for you when `sourceMap` is set to `true` but you can set manual source root if needed
+
+#### New options
+
+`sourceMapName` - Accepts a string or function to change the location or name of your map
+`sourceMapIncludeSources` - Embed the content of your source files directly into the map
+`expression` - Accepts a `Boolean` value. Parse a single expression (JSON or single functions)
+`quoteStyle` - Accepts integers `0` (default), `1`, `2`, `3`. Enforce or preserve quotation mark style.
+
+### Options
+
+This task primarily delegates to [UglifyJS2][], so please consider the [UglifyJS documentation][] as required reading for advanced configuration.
+
+[UglifyJS2]: https://github.com/mishoo/UglifyJS2
+[UglifyJS documentation]: http://lisperator.net/uglifyjs/
+
+
+#### mangle
+Type: `Boolean` `Object`  
+Default: `{}`
+
+Turn on or off mangling with default options. If an `Object` is specified, it is passed directly to `ast.mangle_names()` *and* `ast.compute_char_frequency()` (mimicking command line behavior). [View all options here](https://github.com/mishoo/UglifyJS2#mangler-options).
+
+#### compress
+Type: `Boolean` `Object`  
+Default: `{}`
+
+Turn on or off source compression with default options. If an `Object` is specified, it is passed as options to `UglifyJS.Compressor()`. [View all options here](https://github.com/mishoo/UglifyJS2#compressor-options).
+
+#### beautify
+Type: `Boolean` `Object`  
+Default: `false`
+
+Turns on beautification of the generated source code. An `Object` will be merged and passed with the options sent to `UglifyJS.OutputStream()`. [View all options here](https://github.com/mishoo/UglifyJS2#beautifier-options)
+
+###### expression
+Type: `Boolean`  
+Default: `false`
+
+Parse a single expression, rather than a program (for parsing JSON)
+
+#### report
+Choices: `'none'`, `'min'`, `'gzip'`
+Default: `'min'`
+
+Either report only minification result or report minification and gzip results.
+This is useful to see exactly how well UglifyJS is performing but using `'gzip'` will make the task take 5-10x longer to complete. [Example output](https://github.com/sindresorhus/maxmin#readme).
+If `'none'` is used the report will be generated on the verbose output.
+
+#### sourceMap
+Type: `Boolean`  
+Default: `false`
+
+If `true`, a source map file will be generated in the same directory as the `dest` file. By default it will have the same basename as the `dest` file, but with a `.map` extension.
+
+#### sourceMapName
+Type: `String`  `Function`  
+Default: `undefined`
+
+To customize the name or location of the generated source map, pass a string to indicate where to write the source map to. If a function is provided, the uglify destination is passed as the argument and the return value will be used as the file name.
+
+#### sourceMapIn
+Type: `String`  `Function`  
+Default: `undefined`
+
+The location of an input source map from an earlier compilation, e.g. from CoffeeScript. If a function is provided, the
+uglify source is passed as the argument and the return value will be used as the sourceMap name. This only makes sense
+when there's one source file.
+
+#### sourceMapIncludeSources
+Type: `Boolean`  
+Default: `false`
+
+Pass this flag if you want to include the content of source files in the source map as sourcesContent property.
+
+###### sourceMapRoot
+Type: `String`  
+Default: `undefined`
+
+With this option you can customize root URL that browser will use when looking for sources.
+
+If the sources are not absolute URLs after prepending of the `sourceMapRoot`, the sources are resolved relative to the source map.
+
+#### sourceMapUrl
+Type: `String`  
+Default: `undefined`
+
+Override the calculated value for `sourceMappingURL` in the source map. This is useful if the source map location is not relative to the base path of the minified file, i.e. when using a CDN
+
+###### enclose
+Type: `Object`  
+Default: `undefined`
+
+Wrap all of the code in a closure with a configurable arguments/parameters list.
+Each key-value pair in the `enclose` object is effectively an argument-parameter pair.
+
+#### wrap
+Type: `String`  
+Default: `undefined`
+
+Wrap all of the code in a closure, an easy way to make sure nothing is leaking.
+For variables that need to be public `exports` and `global` variables are made available.
+The value of wrap is the global variable exports will be available as.
+
+#### maxLineLen
+Type: `Number`  
+Default: `32000`
+
+Limit the line length in symbols. Pass maxLineLen = 0 to disable this safety feature.
+
+#### ASCIIOnly
+Type: `Boolean`  
+Default: `false`
+
+Enables to encode non-ASCII characters as \uXXXX.
+
+#### exportAll
+Type: `Boolean`  
+Default: `false`
+
+When using `wrap` this will make all global functions and variables available via the export variable.
+
+#### preserveComments
+Type: `Boolean` `String` `Function`  
+Default: `undefined`  
+Options: `false` `'all'` `'some'`
+
+Turn on preservation of comments.
+
+- `false` will strip all comments
+- `'all'` will preserve all comments in code blocks that have not been squashed or dropped
+- `'some'` will preserve all comments that start with a bang (`!`) or include a closure compiler style directive (`@preserve` `@license` `@cc_on`)
+- `Function` specify your own comment preservation function. You will be passed the current node and the current comment and are expected to return either `true` or `false`
+
+#### banner
+Type: `String`  
+Default: `''`
+
+This string will be prepended to the minified output. Template strings (e.g. `<%= config.value %>` will be expanded automatically.
+
+#### footer
+Type: `String`  
+Default: `''`
+
+This string will be appended to the minified output. Template strings (e.g. `<%= config.value %>` will be expanded automatically.
+
+#### screwIE8
+Type: `Boolean`  
+Default: `true`
+
+Set this to `false` if you still care about full compliance with Internet Explorer 6-8 quirks.
+
+#### mangleProperties
+Type: `Boolean` `Object`
+Default: `false`
+
+Turn on or off property mangling with default options. If an `Object` is specified, it is passed directly to `ast.mangle_properties()` (mimicking command line behavior). [View all options here](https://github.com/mishoo/UglifyJS2#mangler-options).
+
+#### reserveDOMProperties
+Type: `Boolean`  
+Default: `false`
+
+Use this flag in conjunction with `mangleProperties` to prevent built-in browser object properties from being mangled.
+
+#### exceptionsFiles
+Type: `Array`  
+Default: `[]`
+
+Use this with `mangleProperties` to pass one or more JSON files containing a list of variables and object properties
+that should not be mangled. See the [UglifyJS docs](https://www.npmjs.com/package/uglify-js) for more info on the file syntax.
+
+#### nameCache
+Type: `String`  
+Default: `''`
+
+A string that is a path to a JSON cache file that uglify will create and use to coordinate symbol mangling between
+multiple runs of uglify. Note: this generated file uses the same JSON format as the `exceptionsFiles` files.
+
+#### quoteStyle
+Type: `Integer`  
+Default: `0`
+
+Preserve or enforce quotation mark style.
+
+* `0` will use single or double quotes such as to minimize the number of bytes (prefers double quotes when both will do)
+* `1` will always use single quotes
+* `2` will always use double quotes
+* `3` will preserve original quotation marks
+
+### Usage examples
+
+#### Basic compression
+
+This configuration will compress and mangle the input files using the default options.
+
+```js
+// Project configuration.
+grunt.initConfig({
+  uglify: {
+    my_target: {
+      files: {
+        'dest/output.min.js': ['src/input1.js', 'src/input2.js']
+      }
+    }
+  }
+});
+```
+
+#### No mangling
+
+Specify `mangle: false` to prevent changes to your variable and function names.
+
+```js
+// Project configuration.
+grunt.initConfig({
+  uglify: {
+    options: {
+      mangle: false
+    },
+    my_target: {
+      files: {
+        'dest/output.min.js': ['src/input.js']
+      }
+    }
+  }
+});
+```
+
+#### Reserved identifiers
+
+You can specify identifiers to leave untouched with an `except` array in the `mangle` options.
+
+```js
+// Project configuration.
+grunt.initConfig({
+  uglify: {
+    options: {
+      mangle: {
+        except: ['jQuery', 'Backbone']
+      }
+    },
+    my_target: {
+      files: {
+        'dest/output.min.js': ['src/input.js']
+      }
+    }
+  }
+});
+```
+
+#### Source maps
+
+Generate a source map by setting the `sourceMap` option to `true`. The generated
+source map will be in the same directory as the destination file. Its name will be the
+basename of the destination file with a `.map` extension. Override these
+defaults with the `sourceMapName` attribute.
+
+```js
+// Project configuration.
+grunt.initConfig({
+  uglify: {
+    my_target: {
+      options: {
+        sourceMap: true,
+        sourceMapName: 'path/to/sourcemap.map'
+      },
+      files: {
+        'dest/output.min.js': ['src/input.js']
+      }
+    }
+  }
+});
+```
+
+#### Advanced source maps
+
+Set the `sourceMapIncludeSources` option to `true` to embed your sources directly into the map. To include
+a source map from a previous compilation pass it as the value of the `sourceMapIn` option.
+
+```js
+// Project configuration.
+grunt.initConfig({
+  uglify: {
+    my_target: {
+      options: {
+        sourceMap: true,
+        sourceMapIncludeSources: true,
+        sourceMapIn: 'example/coffeescript-sourcemap.js', // input sourcemap from a previous compilation
+      },
+      files: {
+        'dest/output.min.js': ['src/input.js'],
+      },
+    },
+  },
+});
+```
+
+Refer to the [UglifyJS SourceMap Documentation](http://lisperator.net/uglifyjs/codegen#source-map) for more information.
+
+#### Turn off console warnings
+
+Specify `drop_console: true` as part of the `compress` options to discard calls to `console.*` functions.
+This will suppress warning messages in the console.
+
+```js
+// Project configuration.
+grunt.initConfig({
+  uglify: {
+    options: {
+      compress: {
+        drop_console: true
+      }
+    },
+    my_target: {
+      files: {
+        'dest/output.min.js': ['src/input.js']
+      }
+    }
+  }
+});
+```
+
+#### Beautify
+
+Specify `beautify: true` to beautify your code for debugging/troubleshooting purposes.
+Pass an object to manually configure any other output options passed directly to `UglifyJS.OutputStream()`.
+
+See [UglifyJS Codegen documentation](http://lisperator.net/uglifyjs/codegen) for more information.
+
+_Note that manual configuration will require you to explicitly set `beautify: true` if you want traditional, beautified output._
+
+```js
+// Project configuration.
+grunt.initConfig({
+  uglify: {
+    my_target: {
+      options: {
+        beautify: true
+      },
+      files: {
+        'dest/output.min.js': ['src/input.js']
+      }
+    },
+    my_advanced_target: {
+      options: {
+        beautify: {
+          width: 80,
+          beautify: true
+        }
+      },
+      files: {
+        'dest/output.min.js': ['src/input.js']
+      }
+    }
+  }
+});
+```
+
+#### Banner comments
+
+In this example, running `grunt uglify:my_target` will prepend a banner created by interpolating the `banner` template string with the config object. Here, those properties are the values imported from the `package.json` file (which are available via the `pkg` config property) plus today's date.
+
+_Note: you don't have to use an external JSON file. It's also valid to create the `pkg` object inline in the config. That being said, if you already have a JSON file, you might as well reference it._
+
+```js
+// Project configuration.
+grunt.initConfig({
+  pkg: grunt.file.readJSON('package.json'),
+  uglify: {
+    options: {
+      banner: '/*! <%= pkg.name %> - v<%= pkg.version %> - ' +
+        '<%= grunt.template.today("yyyy-mm-dd") %> */'
+    },
+    my_target: {
+      files: {
+        'dest/output.min.js': ['src/input.js']
+      }
+    }
+  }
+});
+```
+
+#### Conditional compilation
+
+You can also enable UglifyJS conditional compilation. This is commonly used to remove debug code blocks for production builds. This is equivalent to the command line [`--define` option](https://github.com/mishoo/UglifyJS#use-as-a-code-pre-processor).
+
+See [UglifyJS global definitions documentation](http://lisperator.net/uglifyjs/compress#global-defs) for more information.
+
+```js
+// Project configuration.
+grunt.initConfig({
+  uglify: {
+    options: {
+      compress: {
+        global_defs: {
+          'DEBUG': false
+        },
+        dead_code: true
+      }
+    },
+    my_target: {
+      files: {
+        'dest/output.min.js': ['src/input.js']
+      }
+    }
+  }
+});
+```
+
+#### Compiling all files in a folder dynamically
+
+This configuration will compress and mangle the files dynamically.
+
+```js
+// Project configuration.
+grunt.initConfig({
+  uglify: {
+    my_target: {
+      files: [{
+          expand: true,
+          cwd: 'src/js',
+          src: '**/*.js',
+          dest: 'dest/js'
+      }]
+    }
+  }
+});
+```
+
+#### Turn on object property name mangling
+
+This configuration will turn on object property name mangling, but not mangle built-in browser object properties.
+Additionally, variables and object properties listed in the `myExceptionsFile.json` will be mangled. For more info,
+on the format of the exception file format please see the [UglifyJS docs](https://www.npmjs.com/package/uglify-js).
+
+```js
+// Project configuration.
+grunt.initConfig({
+  uglify: {
+    options: {
+      mangleProperties: true,
+      reserveDOMCache: true,
+      exceptionsFiles: [ 'myExceptionsFile.json' ]
+    },
+    my_target: {
+      files: {
+        'dest/output.min.js': ['src/input.js']
+      }
+    }
+  }
+});
+```
+
+#### Turn on use of name mangling cache
+
+Turn on use of name mangling cache to coordinate mangled symbols between outputted uglify files. uglify will the
+generate a JSON cache file with the name provided in the options. Note: this generated file uses the same JSON format
+as the `exceptionsFiles` files.
+
+```js
+// Project configuration.
+grunt.initConfig({
+  uglify: {
+    options: {
+      nameCache: '.tmp/grunt-uglify-cache.json',
+    },
+    my_target: {
+      files: {
+        'dest/output1.min.js': ['src/input1.js'],
+        'dest/output2.min.js': ['src/input2.js']
+      }
+    }
+  }
+});
+```
+
+
+## Release History
+
+ * 2016-07-19   v2.0.0   Update uglify-js to v2.7.0. `screwIE8` is enabled by default.
+ * 2016-07-19   v1.0.2   Update grunt to ^1.0.0. Fix `beautify` when passed as an object. Fix docs about `report` values.
+ * 2016-03-16   v1.0.1   Downgrade maxmin for Node.js 0.10.
+ * 2016-03-04   v1.0.0   Use uglify-js ~2.6.2 to fix sourcemap issue. Improve docs for `global-defs` and `--define` options. Add `sourceMapUrl` option. Add `bare_returns` option. Optionally set report verbosity level using report option.
+ * 2016-01-29   v0.11.1   Update lodash to ^4.0.1. Update grunt-contrib-clean to ^0.7.0. Update grunt-contrib-jshint to ^0.12.0.
+ * 2015-11-20   v0.11.0   Update uglify-js to ~2.6.0.
+ * 2015-11-12   v0.10.1   Update uglify-js to ~2.5.
+ * 2015-10-27   v0.10.0   Update uglify-js to ^2.5.
+ * 2015-08-24   v0.9.2   Update uglify-js to ^2.4.24
+ * 2015-04-07   v0.9.1   More fixes for `mangle` options.
+ * 2015-04-07   v0.9.0   Add hook into uglify-js's mangling functionality.
+ * 2015-03-30   v0.8.1   Lock uglify-js to 2.4.17 due to breaking changes.
+ * 2015-02-19   v0.8.0   Add `screwIE8` option. Fix issue with explicit `compress` in Node.js 0.12.0.
+ * 2014-12-23   v0.7.0   Add `sourceMapRoot` options. Update readme descriptions. Remove reference to clean-css.
+ * 2014-09-17   v0.6.0   Output fixes. Add `ASCIIOnly` option. Other fixes.
+ * 2014-07-25   v0.5.1   Update chalk to ^0.5.1. Output updates.
+ * 2014-03-01   v0.4.0   Remove grunt-lib-contrib dependency and add more colors.
+ * 2014-02-27   v0.3.3   Remove unnecessary calls to `grunt.template.process`.
+ * 2014-01-22   v0.3.2   Fix handling of `sourceMapIncludeSources` option.
+ * 2014-01-20   v0.3.1   Fix relative path issue in sourcemaps.
+ * 2014-01-16   v0.3.0   Refactor sourcemap support.
+ * 2013-11-09   v0.2.7   Prepend banner if `sourceMap` option not set, addresses #109.
+ * 2013-11-08   v0.2.6   Merge #45, #53, #85 (#105 by way of duping #53). Add support for banners in uglified files with sourcemaps. Update docs.
+ * 2013-10-28   v0.2.5   Add warning for banners when using sourcemaps.
+ * 2013-09-02   v0.2.4   Update sourcemap format via #83.
+ * 2013-06-10   v0.2.3   Add `footer` option.
+ * 2013-05-31   v0.2.2   Revert #56 due to #58 until [chrome/239660](https://code.google.com/p/chromium/issues/detail?id=239660&q=sourcemappingurl&colspec=ID%20Pri%20M%20Iteration%20ReleaseBlock%20Cr%20Status%20Owner%20Summary%20OS%20Modified) [firefox/870361](https://bugzilla.mozilla.org/show_bug.cgi?id=870361) drop.
+ * 2013-05-22   v0.2.1   Update uglify-js to ~2.3.5 #55 #40. Change `sourcemappingUrl` syntax #56. Disable sorting of names for consistent mangling #44. Update docs for `sourceMapRoot` #47 #25.
+ * 2013-03-14   v0.2.0   No longer report gzip results by default. Support `report` option.
+ * 2013-01-30   v0.1.2   Add better error reporting. Support for dynamic names of multiple sourcemaps.
+ * 2013-02-15   v0.1.1   First official release for Grunt 0.4.0.
+ * 2013-01-18   v0.1.1rc6   Update grunt/gruntplugin dependencies to rc6. Change in-development grunt/gruntplugin dependency versions from tilde version ranges to specific versions.
+ * 2013-01-09   v0.1.1rc5   Update to work with grunt v0.4.0rc5. Switch back to `this.files` API.
+ * 2012-11-28   v0.1.0   Work in progress, not officially released yet.
+
+---
+
+Task submitted by ["Cowboy" Ben Alman](http://benalman.com)
+
+*This file was generated on Tue Jul 19 2016 16:46:21.*
diff --git a/appveyor.yml b/appveyor.yml
new file mode 100644
index 0000000..62725fb
--- /dev/null
+++ b/appveyor.yml
@@ -0,0 +1,39 @@
+clone_depth: 10
+
+version: "{build}"
+
+# What combinations to test
+environment:
+  matrix:
+    - nodejs_version: "0.10"
+      platform: x86
+    - nodejs_version: "0.12"
+      platform: x86
+    - nodejs_version: "4"
+      platform: x64
+    - nodejs_version: "4"
+      platform: x86
+    - nodejs_version: "5"
+      platform: x86
+    - nodejs_version: "6"
+      platform: x86
+
+install:
+  - ps: Install-Product node $env:nodejs_version $env:platform
+  - npm install
+
+test_script:
+  # Output useful info for debugging
+  - node --version && npm --version
+  # We test multiple Windows shells because of prior stdout buffering issues
+  # filed against Grunt. https://github.com/joyent/node/issues/3584
+  - ps: "npm test # PowerShell" # Pass comment to PS for easier debugging
+  - cmd: npm test
+
+build: off
+
+matrix:
+  fast_finish: true
+
+cache:
+  - node_modules -> package.json
diff --git a/docs/uglify-examples.md b/docs/uglify-examples.md
new file mode 100644
index 0000000..acbc958
--- /dev/null
+++ b/docs/uglify-examples.md
@@ -0,0 +1,286 @@
+# Usage examples
+
+## Basic compression
+
+This configuration will compress and mangle the input files using the default options.
+
+```js
+// Project configuration.
+grunt.initConfig({
+  uglify: {
+    my_target: {
+      files: {
+        'dest/output.min.js': ['src/input1.js', 'src/input2.js']
+      }
+    }
+  }
+});
+```
+
+## No mangling
+
+Specify `mangle: false` to prevent changes to your variable and function names.
+
+```js
+// Project configuration.
+grunt.initConfig({
+  uglify: {
+    options: {
+      mangle: false
+    },
+    my_target: {
+      files: {
+        'dest/output.min.js': ['src/input.js']
+      }
+    }
+  }
+});
+```
+
+## Reserved identifiers
+
+You can specify identifiers to leave untouched with an `except` array in the `mangle` options.
+
+```js
+// Project configuration.
+grunt.initConfig({
+  uglify: {
+    options: {
+      mangle: {
+        except: ['jQuery', 'Backbone']
+      }
+    },
+    my_target: {
+      files: {
+        'dest/output.min.js': ['src/input.js']
+      }
+    }
+  }
+});
+```
+
+## Source maps
+
+Generate a source map by setting the `sourceMap` option to `true`. The generated
+source map will be in the same directory as the destination file. Its name will be the
+basename of the destination file with a `.map` extension. Override these
+defaults with the `sourceMapName` attribute.
+
+```js
+// Project configuration.
+grunt.initConfig({
+  uglify: {
+    my_target: {
+      options: {
+        sourceMap: true,
+        sourceMapName: 'path/to/sourcemap.map'
+      },
+      files: {
+        'dest/output.min.js': ['src/input.js']
+      }
+    }
+  }
+});
+```
+
+## Advanced source maps
+
+Set the `sourceMapIncludeSources` option to `true` to embed your sources directly into the map. To include
+a source map from a previous compilation pass it as the value of the `sourceMapIn` option.
+
+```js
+// Project configuration.
+grunt.initConfig({
+  uglify: {
+    my_target: {
+      options: {
+        sourceMap: true,
+        sourceMapIncludeSources: true,
+        sourceMapIn: 'example/coffeescript-sourcemap.js', // input sourcemap from a previous compilation
+      },
+      files: {
+        'dest/output.min.js': ['src/input.js'],
+      },
+    },
+  },
+});
+```
+
+Refer to the [UglifyJS SourceMap Documentation](http://lisperator.net/uglifyjs/codegen#source-map) for more information.
+
+## Turn off console warnings
+
+Specify `drop_console: true` as part of the `compress` options to discard calls to `console.*` functions.
+This will suppress warning messages in the console.
+
+```js
+// Project configuration.
+grunt.initConfig({
+  uglify: {
+    options: {
+      compress: {
+        drop_console: true
+      }
+    },
+    my_target: {
+      files: {
+        'dest/output.min.js': ['src/input.js']
+      }
+    }
+  }
+});
+```
+
+## Beautify
+
+Specify `beautify: true` to beautify your code for debugging/troubleshooting purposes.
+Pass an object to manually configure any other output options passed directly to `UglifyJS.OutputStream()`.
+
+See [UglifyJS Codegen documentation](http://lisperator.net/uglifyjs/codegen) for more information.
+
+_Note that manual configuration will require you to explicitly set `beautify: true` if you want traditional, beautified output._
+
+```js
+// Project configuration.
+grunt.initConfig({
+  uglify: {
+    my_target: {
+      options: {
+        beautify: true
+      },
+      files: {
+        'dest/output.min.js': ['src/input.js']
+      }
+    },
+    my_advanced_target: {
+      options: {
+        beautify: {
+          width: 80,
+          beautify: true
+        }
+      },
+      files: {
+        'dest/output.min.js': ['src/input.js']
+      }
+    }
+  }
+});
+```
+
+## Banner comments
+
+In this example, running `grunt uglify:my_target` will prepend a banner created by interpolating the `banner` template string with the config object. Here, those properties are the values imported from the `package.json` file (which are available via the `pkg` config property) plus today's date.
+
+_Note: you don't have to use an external JSON file. It's also valid to create the `pkg` object inline in the config. That being said, if you already have a JSON file, you might as well reference it._
+
+```js
+// Project configuration.
+grunt.initConfig({
+  pkg: grunt.file.readJSON('package.json'),
+  uglify: {
+    options: {
+      banner: '/*! <%= pkg.name %> - v<%= pkg.version %> - ' +
+        '<%= grunt.template.today("yyyy-mm-dd") %> */'
+    },
+    my_target: {
+      files: {
+        'dest/output.min.js': ['src/input.js']
+      }
+    }
+  }
+});
+```
+
+## Conditional compilation
+
+You can also enable UglifyJS conditional compilation. This is commonly used to remove debug code blocks for production builds. This is equivalent to the command line [`--define` option](https://github.com/mishoo/UglifyJS#use-as-a-code-pre-processor).
+
+See [UglifyJS global definitions documentation](http://lisperator.net/uglifyjs/compress#global-defs) for more information.
+
+```js
+// Project configuration.
+grunt.initConfig({
+  uglify: {
+    options: {
+      compress: {
+        global_defs: {
+          'DEBUG': false
+        },
+        dead_code: true
+      }
+    },
+    my_target: {
+      files: {
+        'dest/output.min.js': ['src/input.js']
+      }
+    }
+  }
+});
+```
+
+## Compiling all files in a folder dynamically
+
+This configuration will compress and mangle the files dynamically.
+
+```js
+// Project configuration.
+grunt.initConfig({
+  uglify: {
+    my_target: {
+      files: [{
+          expand: true,
+          cwd: 'src/js',
+          src: '**/*.js',
+          dest: 'dest/js'
+      }]
+    }
+  }
+});
+```
+
+## Turn on object property name mangling
+
+This configuration will turn on object property name mangling, but not mangle built-in browser object properties.
+Additionally, variables and object properties listed in the `myExceptionsFile.json` will be mangled. For more info,
+on the format of the exception file format please see the [UglifyJS docs](https://www.npmjs.com/package/uglify-js).
+
+```js
+// Project configuration.
+grunt.initConfig({
+  uglify: {
+    options: {
+      mangleProperties: true,
+      reserveDOMCache: true,
+      exceptionsFiles: [ 'myExceptionsFile.json' ]
+    },
+    my_target: {
+      files: {
+        'dest/output.min.js': ['src/input.js']
+      }
+    }
+  }
+});
+```
+
+## Turn on use of name mangling cache
+
+Turn on use of name mangling cache to coordinate mangled symbols between outputted uglify files. uglify will the
+generate a JSON cache file with the name provided in the options. Note: this generated file uses the same JSON format
+as the `exceptionsFiles` files.
+
+```js
+// Project configuration.
+grunt.initConfig({
+  uglify: {
+    options: {
+      nameCache: '.tmp/grunt-uglify-cache.json',
+    },
+    my_target: {
+      files: {
+        'dest/output1.min.js': ['src/input1.js'],
+        'dest/output2.min.js': ['src/input2.js']
+      }
+    }
+  }
+});
+```
diff --git a/docs/uglify-options.md b/docs/uglify-options.md
new file mode 100644
index 0000000..6ef4f0e
--- /dev/null
+++ b/docs/uglify-options.md
@@ -0,0 +1,179 @@
+# Options
+
+This task primarily delegates to [UglifyJS2][], so please consider the [UglifyJS documentation][] as required reading for advanced configuration.
+
+[UglifyJS2]: https://github.com/mishoo/UglifyJS2
+[UglifyJS documentation]: http://lisperator.net/uglifyjs/
+
+
+## mangle
+Type: `Boolean` `Object`  
+Default: `{}`
+
+Turn on or off mangling with default options. If an `Object` is specified, it is passed directly to `ast.mangle_names()` *and* `ast.compute_char_frequency()` (mimicking command line behavior). [View all options here](https://github.com/mishoo/UglifyJS2#mangler-options).
+
+## compress
+Type: `Boolean` `Object`  
+Default: `{}`
+
+Turn on or off source compression with default options. If an `Object` is specified, it is passed as options to `UglifyJS.Compressor()`. [View all options here](https://github.com/mishoo/UglifyJS2#compressor-options).
+
+## beautify
+Type: `Boolean` `Object`  
+Default: `false`
+
+Turns on beautification of the generated source code. An `Object` will be merged and passed with the options sent to `UglifyJS.OutputStream()`. [View all options here](https://github.com/mishoo/UglifyJS2#beautifier-options)
+
+#### expression
+Type: `Boolean`  
+Default: `false`
+
+Parse a single expression, rather than a program (for parsing JSON)
+
+## report
+Choices: `'none'`, `'min'`, `'gzip'`
+Default: `'min'`
+
+Either report only minification result or report minification and gzip results.
+This is useful to see exactly how well UglifyJS is performing but using `'gzip'` will make the task take 5-10x longer to complete. [Example output](https://github.com/sindresorhus/maxmin#readme).
+If `'none'` is used the report will be generated on the verbose output.
+
+## sourceMap
+Type: `Boolean`  
+Default: `false`
+
+If `true`, a source map file will be generated in the same directory as the `dest` file. By default it will have the same basename as the `dest` file, but with a `.map` extension.
+
+## sourceMapName
+Type: `String`  `Function`  
+Default: `undefined`
+
+To customize the name or location of the generated source map, pass a string to indicate where to write the source map to. If a function is provided, the uglify destination is passed as the argument and the return value will be used as the file name.
+
+## sourceMapIn
+Type: `String`  `Function`  
+Default: `undefined`
+
+The location of an input source map from an earlier compilation, e.g. from CoffeeScript. If a function is provided, the
+uglify source is passed as the argument and the return value will be used as the sourceMap name. This only makes sense
+when there's one source file.
+
+## sourceMapIncludeSources
+Type: `Boolean`  
+Default: `false`
+
+Pass this flag if you want to include the content of source files in the source map as sourcesContent property.
+
+#### sourceMapRoot
+Type: `String`  
+Default: `undefined`
+
+With this option you can customize root URL that browser will use when looking for sources.
+
+If the sources are not absolute URLs after prepending of the `sourceMapRoot`, the sources are resolved relative to the source map.
+
+## sourceMapUrl
+Type: `String`  
+Default: `undefined`
+
+Override the calculated value for `sourceMappingURL` in the source map. This is useful if the source map location is not relative to the base path of the minified file, i.e. when using a CDN
+
+#### enclose
+Type: `Object`  
+Default: `undefined`
+
+Wrap all of the code in a closure with a configurable arguments/parameters list.
+Each key-value pair in the `enclose` object is effectively an argument-parameter pair.
+
+## wrap
+Type: `String`  
+Default: `undefined`
+
+Wrap all of the code in a closure, an easy way to make sure nothing is leaking.
+For variables that need to be public `exports` and `global` variables are made available.
+The value of wrap is the global variable exports will be available as.
+
+## maxLineLen
+Type: `Number`  
+Default: `32000`
+
+Limit the line length in symbols. Pass maxLineLen = 0 to disable this safety feature.
+
+## ASCIIOnly
+Type: `Boolean`  
+Default: `false`
+
+Enables to encode non-ASCII characters as \uXXXX.
+
+## exportAll
+Type: `Boolean`  
+Default: `false`
+
+When using `wrap` this will make all global functions and variables available via the export variable.
+
+## preserveComments
+Type: `Boolean` `String` `Function`  
+Default: `undefined`  
+Options: `false` `'all'` `'some'`
+
+Turn on preservation of comments.
+
+- `false` will strip all comments
+- `'all'` will preserve all comments in code blocks that have not been squashed or dropped
+- `'some'` will preserve all comments that start with a bang (`!`) or include a closure compiler style directive (`@preserve` `@license` `@cc_on`)
+- `Function` specify your own comment preservation function. You will be passed the current node and the current comment and are expected to return either `true` or `false`
+
+## banner
+Type: `String`  
+Default: `''`
+
+This string will be prepended to the minified output. Template strings (e.g. `<%= config.value %>` will be expanded automatically.
+
+## footer
+Type: `String`  
+Default: `''`
+
+This string will be appended to the minified output. Template strings (e.g. `<%= config.value %>` will be expanded automatically.
+
+## screwIE8
+Type: `Boolean`  
+Default: `true`
+
+Set this to `false` if you still care about full compliance with Internet Explorer 6-8 quirks.
+
+## mangleProperties
+Type: `Boolean` `Object`
+Default: `false`
+
+Turn on or off property mangling with default options. If an `Object` is specified, it is passed directly to `ast.mangle_properties()` (mimicking command line behavior). [View all options here](https://github.com/mishoo/UglifyJS2#mangler-options).
+
+## reserveDOMProperties
+Type: `Boolean`  
+Default: `false`
+
+Use this flag in conjunction with `mangleProperties` to prevent built-in browser object properties from being mangled.
+
+## exceptionsFiles
+Type: `Array`  
+Default: `[]`
+
+Use this with `mangleProperties` to pass one or more JSON files containing a list of variables and object properties
+that should not be mangled. See the [UglifyJS docs](https://www.npmjs.com/package/uglify-js) for more info on the file syntax.
+
+## nameCache
+Type: `String`  
+Default: `''`
+
+A string that is a path to a JSON cache file that uglify will create and use to coordinate symbol mangling between
+multiple runs of uglify. Note: this generated file uses the same JSON format as the `exceptionsFiles` files.
+
+## quoteStyle
+Type: `Integer`  
+Default: `0`
+
+Preserve or enforce quotation mark style.
+
+* `0` will use single or double quotes such as to minimize the number of bytes (prefers double quotes when both will do)
+* `1` will always use single quotes
+* `2` will always use double quotes
+* `3` will preserve original quotation marks
diff --git a/docs/uglify-overview.md b/docs/uglify-overview.md
new file mode 100644
index 0000000..563c01e
--- /dev/null
+++ b/docs/uglify-overview.md
@@ -0,0 +1,22 @@
+Task targets, files and options may be specified according to the grunt [Configuring tasks](http://gruntjs.com/configuring-tasks) guide.
+
+# Migrating from 2.x to 3.x
+
+Version `3.x` introduced changes to configuring source maps. Accordingly, if you don't use the source map options you should be able to upgrade seamlessly. If you do use source maps, see below.
+
+## Removed options
+
+`sourceMappingURL` - This is calculated automatically now
+`sourceMapPrefix` - No longer necessary for the above reason
+
+## Changed options
+
+`sourceMap` - Only accepts a `Boolean` value. Generates a map with a default name for you
+`sourceMapRoot` - The location of your sources is now calculated for you when `sourceMap` is set to `true` but you can set manual source root if needed
+
+## New options
+
+`sourceMapName` - Accepts a string or function to change the location or name of your map
+`sourceMapIncludeSources` - Embed the content of your source files directly into the map
+`expression` - Accepts a `Boolean` value. Parse a single expression (JSON or single functions)
+`quoteStyle` - Accepts integers `0` (default), `1`, `2`, `3`. Enforce or preserve quotation mark style.
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..aff25b4
--- /dev/null
+++ b/package.json
@@ -0,0 +1,39 @@
+{
+  "name": "grunt-contrib-uglify",
+  "description": "Minify JavaScript files with UglifyJS",
+  "version": "2.0.0",
+  "author": {
+    "name": "Grunt Team",
+    "url": "http://gruntjs.com/"
+  },
+  "repository": "gruntjs/grunt-contrib-uglify",
+  "license": "MIT",
+  "engines": {
+    "node": ">=0.10.0"
+  },
+  "main": "tasks/uglify.js",
+  "scripts": {
+    "test": "grunt test"
+  },
+  "dependencies": {
+    "chalk": "^1.0.0",
+    "lodash.assign": "^4.0.9",
+    "maxmin": "^1.1.0",
+    "uglify-js": "~2.7.0",
+    "uri-path": "^1.0.0"
+  },
+  "devDependencies": {
+    "grunt": "^1.0.0",
+    "grunt-contrib-clean": "^1.0.0",
+    "grunt-contrib-internal": "^1.1.0",
+    "grunt-contrib-jshint": "^1.0.0",
+    "grunt-contrib-nodeunit": "^1.0.0"
+  },
+  "keywords": [
+    "gruntplugin"
+  ],
+  "files": [
+    "tasks"
+  ],
+  "appveyor_id": "ybtf5vbvtenii561"
+}
diff --git a/tasks/lib/uglify.js b/tasks/lib/uglify.js
new file mode 100644
index 0000000..4b67bca
--- /dev/null
+++ b/tasks/lib/uglify.js
@@ -0,0 +1,294 @@
+/*
+ * grunt-contrib-uglify
+ * https://gruntjs.com/
+ *
+ * Copyright (c) 2016 "Cowboy" Ben Alman, contributors
+ * Licensed under the MIT license.
+ */
+
+'use strict';
+
+// External libs.
+var path = require('path');
+var UglifyJS = require('uglify-js');
+var assign = require('lodash.assign');
+var uriPath = require('uri-path');
+var getOutputOptions;
+
+exports.init = function(grunt) {
+  var exports = {};
+
+  // Minify with UglifyJS.
+  // From https://github.com/mishoo/UglifyJS2
+  // API docs at http://lisperator.net/uglifyjs/
+  exports.minify = function(files, dest, options) {
+    options = options || {};
+
+    grunt.verbose.write('Minifying with UglifyJS...');
+
+    var topLevel = null;
+    var totalCode = '';
+    var sourcesContent = {};
+
+    var outputOptions = getOutputOptions(options, dest);
+    var output = UglifyJS.OutputStream(outputOptions);
+
+    // Grab and parse all source files
+    files.forEach(function(file) {
+
+      var code = grunt.file.read(file);
+      totalCode += code;
+
+      // The src file name must be relative to the source map for things to work
+      var basename = path.basename(file);
+      var fileDir = path.dirname(file);
+      var sourceMapDir = path.dirname(options.generatedSourceMapName);
+      var relativePath = path.relative(sourceMapDir, fileDir);
+      var pathPrefix = relativePath ? relativePath + path.sep : '';
+      var bare_returns = options.bare_returns || undefined;
+
+      // Convert paths to use forward slashes for sourcemap use in the browser
+      file = uriPath(pathPrefix + basename);
+
+      sourcesContent[file] = code;
+      topLevel = UglifyJS.parse(code, {
+        filename: file,
+        toplevel: topLevel,
+        expression: options.expression,
+        bare_returns: bare_returns
+      });
+    });
+
+    // Wrap code in a common js wrapper.
+    if (options.wrap) {
+      topLevel = topLevel.wrap_commonjs(options.wrap, options.exportAll);
+    }
+
+    // Wrap code in closure with configurable arguments/parameters list.
+    if (options.enclose) {
+      var argParamList = Object.keys(options.enclose).map(function(key) {
+        return key + ':' + options.enclose[key];
+      });
+
+      topLevel = topLevel.wrap_enclose(argParamList);
+    }
+
+    var topLevelCache = null;
+    if (options.nameCache) {
+      topLevelCache = UglifyJS.readNameCache(options.nameCache, 'vars');
+    }
+
+    // Need to call this before we mangle or compress,
+    // and call after any compression or ast altering
+    if (options.expression === false) {
+      topLevel.figure_out_scope({
+        screw_ie8: options.screwIE8,
+        cache: topLevelCache
+      });
+    }
+
+    if (options.compress !== false) {
+      if (options.compress === true) {
+        options.compress = {};
+      }
+      if (options.compress.warnings !== true) {
+        options.compress.warnings = false;
+      }
+      if (options.screwIE8 === false) {
+        options.compress.screw_ie8 = false;
+      }
+      var compressor = UglifyJS.Compressor(options.compress);
+      topLevel = topLevel.transform(compressor);
+
+      // Need to figure out scope again after source being altered
+      if (options.expression === false) {
+        topLevel.figure_out_scope({
+          screw_ie8: options.screwIE8,
+          cache: topLevelCache
+        });
+      }
+    }
+
+    var mangleExclusions = {
+      vars: [],
+      props: []
+    };
+    if (options.reserveDOMProperties) {
+      mangleExclusions = UglifyJS.readDefaultReservedFile();
+    }
+
+    if (options.exceptionsFiles) {
+      try {
+        options.exceptionsFiles.forEach(function(filename) {
+          mangleExclusions = UglifyJS.readReservedFile(filename, mangleExclusions);
+        });
+      } catch (ex) {
+        grunt.warn(ex);
+      }
+    }
+
+    var cache = null;
+    if (options.nameCache) {
+      cache = UglifyJS.readNameCache(options.nameCache, 'props');
+    }
+
+    if (typeof options.mangleProperties !== 'undefined' && options.mangleProperties !== false) {
+      // if options.mangleProperties is a boolean (true) convert it into an object
+      if (typeof options.mangleProperties !== 'object') {
+        options.mangleProperties = {};
+      }
+
+      options.mangleProperties.reserved = mangleExclusions ? mangleExclusions.props : null;
+      options.mangleProperties.cache = cache;
+
+      topLevel = UglifyJS.mangle_properties(topLevel, options.mangleProperties);
+
+      if (options.nameCache) {
+        UglifyJS.writeNameCache(options.nameCache, 'props', cache);
+      }
+
+      // Need to figure out scope again since topLevel has been altered
+      if (options.expression === false) {
+        topLevel.figure_out_scope({
+          screw_ie8: options.screwIE8,
+          cache: topLevelCache
+        });
+      }
+    }
+
+    if (options.mangle !== false) {
+      if (options.mangle === true) {
+        options.mangle = {};
+      }
+      if (options.screwIE8 === false) {
+        options.mangle.screw_ie8 = false;
+      }
+      // disabled due to:
+      //   1) preserve stable name mangling
+      //   2) it increases gzipped file size, see https://github.com/mishoo/UglifyJS2#mangler-options
+      // // compute_char_frequency optimizes names for compression
+      // topLevel.compute_char_frequency(options.mangle);
+
+      // if options.mangle is a boolean (true) convert it into an object
+      if (typeof options.mangle !== 'object') {
+        options.mangle = {};
+      }
+
+      options.mangle.cache = topLevelCache;
+
+      options.mangle.except = options.mangle.except ? options.mangle.except : [];
+      if (mangleExclusions.vars) {
+        mangleExclusions.vars.forEach(function(name) {
+          UglifyJS.push_uniq(options.mangle.except, name);
+        });
+      }
+
+      // Requires previous call to figure_out_scope
+      // and should always be called after compressor transform
+      topLevel.mangle_names(options.mangle);
+
+      UglifyJS.writeNameCache(options.nameCache, 'vars', options.mangle.cache);
+    }
+
+    if (options.sourceMap && options.sourceMapIncludeSources) {
+      for (var file in sourcesContent) {
+        if (sourcesContent.hasOwnProperty(file)) {
+          outputOptions.source_map.get().setSourceContent(file, sourcesContent[file]);
+        }
+      }
+    }
+
+    // Print the ast to OutputStream
+    topLevel.print(output);
+
+    var min = output.get();
+
+    // Add the source map reference to the end of the file
+    if (options.sourceMap) {
+      // Set all paths to forward slashes for use in the browser
+      var sourceMappingURL;
+      sourceMappingURL = options.destToSourceMap.match(/^http[s]?:\/\//) === null ? uriPath(options.destToSourceMap) : options.destToSourceMap;
+      min += '\n//# sourceMappingURL=' + sourceMappingURL;
+    }
+
+    var result = {
+      max: totalCode,
+      min: min,
+      sourceMap: outputOptions.source_map
+    };
+
+    grunt.verbose.ok();
+
+    return result;
+  };
+
+  getOutputOptions = function(options, dest) {
+    var outputOptions = {
+      beautify: false,
+      source_map: null
+    };
+
+    if (options.banner && options.sourceMap) {
+      outputOptions.preamble = options.banner;
+    }
+
+    if (options.screwIE8 === false) {
+      outputOptions.screw_ie8 = false;
+    }
+
+    if (options.sourceMap) {
+
+      var destBasename = path.basename(dest);
+      var sourceMapIn;
+      if (options.sourceMapIn) {
+        sourceMapIn = grunt.file.readJSON(options.sourceMapIn);
+      }
+      outputOptions.source_map = UglifyJS.SourceMap({
+        file: destBasename,
+        root: options.sourceMapRoot,
+        orig: sourceMapIn
+      });
+      if (options.sourceMapIncludeSources && sourceMapIn && sourceMapIn.sourcesContent) {
+        sourceMapIn.sourcesContent.forEach(function(content, idx) {
+          outputOptions.source_map.get().setSourceContent(sourceMapIn.sources[idx], content);
+        });
+      }
+
+      if (options.sourceMapIn) {
+        outputOptions.source_map.get()._file = destBasename;
+      }
+    }
+
+    if (typeof options.indentLevel !== 'undefined') {
+      outputOptions.indent_level = options.indentLevel;
+    }
+
+    if (typeof options.maxLineLen !== 'undefined') {
+      outputOptions.max_line_len = options.maxLineLen;
+    }
+
+    if (typeof options.ASCIIOnly !== 'undefined') {
+      outputOptions.ascii_only = options.ASCIIOnly;
+    }
+
+    if (typeof options.quoteStyle !== 'undefined') {
+      outputOptions.quote_style = options.quoteStyle;
+    }
+
+    if (typeof options.preserveComments !== 'undefined') {
+      outputOptions.comments = options.preserveComments;
+    }
+
+    if (options.beautify) {
+      if (typeof options.beautify === 'object') {
+        assign(outputOptions, options.beautify);
+      } else {
+        outputOptions.beautify = true;
+      }
+    }
+
+    return outputOptions;
+  };
+
+  return exports;
+};
diff --git a/tasks/uglify.js b/tasks/uglify.js
new file mode 100644
index 0000000..d1e1fbe
--- /dev/null
+++ b/tasks/uglify.js
@@ -0,0 +1,190 @@
+/*
+ * grunt-contrib-uglify
+ * http://gruntjs.com/
+ *
+ * Copyright (c) 2016 "Cowboy" Ben Alman, contributors
+ * Licensed under the MIT license.
+ */
+
+'use strict';
+
+var path = require('path');
+var chalk = require('chalk');
+var maxmin = require('maxmin');
+var err;
+
+// Return the relative path from file1 => file2
+function relativePath(file1, file2) {
+  var file1Dirname = path.dirname(file1);
+  var file2Dirname = path.dirname(file2);
+
+  if (file1Dirname !== file2Dirname) {
+    return path.relative(file1Dirname, file2Dirname) + path.sep;
+  }
+  return '';
+}
+
+// Converts \r\n to \n
+function normalizeLf(string) {
+  return string.replace(/\r\n/g, '\n');
+}
+
+module.exports = function(grunt) {
+  // Internal lib.
+  var uglify = require('./lib/uglify').init(grunt);
+
+  grunt.registerMultiTask('uglify', 'Minify files with UglifyJS.', function() {
+    // Merge task-specific and/or target-specific options with these defaults.
+    var options = this.options({
+      banner: '',
+      footer: '',
+      compress: {
+        warnings: false
+      },
+      mangle: {},
+      beautify: false,
+      report: 'min',
+      expression: false,
+      maxLineLen: 32000,
+      ASCIIOnly: false,
+      screwIE8: true,
+      quoteStyle: 0
+    });
+
+    // Process banner.
+    var banner = normalizeLf(options.banner);
+    var footer = normalizeLf(options.footer);
+    var mapNameGenerator, mapInNameGenerator;
+    var createdFiles = 0;
+    var createdMaps = 0;
+
+    // Iterate over all src-dest file pairs.
+    this.files.forEach(function (f) {
+      var src = f.src.filter(function (filepath) {
+        // Warn on and remove invalid source files (if nonull was set).
+        if (!grunt.file.exists(filepath)) {
+          grunt.log.warn('Source file ' + chalk.cyan(filepath) + ' not found.');
+          return false;
+        }
+        return true;
+      });
+
+      if (src.length === 0) {
+        grunt.log.warn('Destination ' + chalk.cyan(f.dest) + ' not written because src files were empty.');
+        return;
+      }
+
+      // Warn on incompatible options
+      if (options.expression && (options.compress || options.mangle)) {
+        grunt.log.warn('Option ' + chalk.cyan('expression') + ' not compatible with ' + chalk.cyan('compress and mangle'));
+        options.compress = false;
+        options.mangle = false;
+      }
+
+      // function to get the name of the sourceMap
+      if (typeof options.sourceMapName === 'function') {
+        mapNameGenerator = options.sourceMapName;
+      }
+
+      // function to get the name of the sourceMapIn file
+      if (typeof options.sourceMapIn === 'function') {
+        if (src.length !== 1) {
+          grunt.fail.warn('Cannot generate `sourceMapIn` for multiple source files.');
+        }
+        mapInNameGenerator = options.sourceMapIn;
+      }
+
+      // dynamically create destination sourcemap name
+      if (mapNameGenerator) {
+        try {
+          options.generatedSourceMapName = mapNameGenerator(f.dest);
+        } catch (e) {
+          err = new Error('SourceMap failed.');
+          err.origError = e;
+          grunt.fail.warn(err);
+        }
+      // If no name is passed append .map to the filename
+      } else if (!options.sourceMapName) {
+        options.generatedSourceMapName = f.dest + '.map';
+      } else {
+        options.generatedSourceMapName = options.sourceMapName;
+      }
+
+      // Dynamically create incoming sourcemap names
+      if (mapInNameGenerator) {
+        try {
+          options.sourceMapIn = mapInNameGenerator(src[0]);
+        } catch (e) {
+          err = new Error('SourceMapInName failed.');
+          err.origError = e;
+          grunt.fail.warn(err);
+        }
+      }
+
+      // Calculate the path from the dest file to the sourcemap for the
+      // sourceMappingURL reference
+      // If sourceMapUrl is defined, use this instead
+      if (options.sourceMap) {
+        var destToSourceMapPath, sourceMapBasename;
+        if (!options.sourceMapUrl) {
+          destToSourceMapPath = relativePath(f.dest, options.generatedSourceMapName);
+          sourceMapBasename = path.basename(options.generatedSourceMapName);
+          options.destToSourceMap = destToSourceMapPath + sourceMapBasename;
+        } else {
+          options.destToSourceMap = options.sourceMapUrl;
+        }
+      }
+
+      // Minify files, warn and fail on error.
+      var result;
+      try {
+        result = uglify.minify(src, f.dest, options);
+      } catch (e) {
+        console.log(e);
+        err = new Error('Uglification failed.');
+        if (e.message) {
+          err.message += '\n' + e.message + '. \n';
+          if (e.line) {
+            err.message += 'Line ' + e.line + ' in ' + src + '\n';
+          }
+        }
+        err.origError = e;
+        grunt.log.warn('Uglifying source ' + chalk.cyan(src) + ' failed.');
+        grunt.fail.warn(err);
+      }
+
+      // Concat minified source + footer
+      var output = result.min + footer;
+
+      // Only prepend banner if uglify hasn't taken care of it as part of the preamble
+      if (!options.sourceMap) {
+        output = banner + output;
+      }
+
+      // Write the destination file.
+      grunt.file.write(f.dest, output);
+
+      // Write source map
+      if (options.sourceMap) {
+        grunt.file.write(options.generatedSourceMapName, result.sourceMap);
+        grunt.verbose.writeln('File ' + chalk.cyan(options.generatedSourceMapName) + ' created (source map).');
+        createdMaps++;
+      }
+
+      var outputSize = maxmin(result.max, output, options.report === 'gzip');
+      grunt.verbose.writeln('File ' + chalk.cyan(f.dest) + ' created: ' + outputSize);
+
+      createdFiles++;
+    });
+
+    if (createdMaps > 0) {
+      grunt.log.ok(createdMaps + ' source' + grunt.util.pluralize(createdMaps, 'map/maps') + ' created.');
+    }
+
+    if (createdFiles > 0) {
+      grunt.log.ok(createdFiles + ' ' + grunt.util.pluralize(this.files.length, 'file/files') + ' created.');
+    } else {
+      grunt.log.warn('No files created.');
+    }
+  });
+};
diff --git a/test/fixtures/expected/asciionly.js b/test/fixtures/expected/asciionly.js
new file mode 100644
index 0000000..df6b5ff
--- /dev/null
+++ b/test/fixtures/expected/asciionly.js
@@ -0,0 +1 @@
+var set=["This is a random set of ch\u03b1racters and strings.","\u8fd9\u662f\u4e00\u7ec4\u968f\u673a\u5b57\u7b26\u548c\u5b57\u7b26\u4e32\u3002","\u042d\u0442\u043e \u0441\u043b\u0443\u0447\u0430\u0439\u043d\u044b\u0439 \u043d\u0430\u0431\u043e\u0440 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432 \u0438 \u0441\u0442\u0440\u043e\u043a","\u0426\xe9 \u0432\u0438\u043f\u0430\u0434\u043a\u043e\u0432\u0438\u0439 \u043d\u0430\u0431\u0456\u0440 \u0441\u0438\u043c\u0432\u043e\u043b\u0456\u0432  [...]
\ No newline at end of file
diff --git a/test/fixtures/expected/beautify.js b/test/fixtures/expected/beautify.js
new file mode 100644
index 0000000..665339d
--- /dev/null
+++ b/test/fixtures/expected/beautify.js
@@ -0,0 +1,2 @@
+function longFunctionC(a,b){return longNameA+longNameB+a+b;
+}var set=["This is a random set of ch\u03b1racters and strings.","\u8fd9\u662f\u4e00\u7ec4\u968f\u673a\u5b57\u7b26\u548c\u5b57\u7b26\u4e32\u3002","\u042d\u0442\u043e \u0441\u043b\u0443\u0447\u0430\u0439\u043d\u044b\u0439 \u043d\u0430\u0431\u043e\u0440 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432 \u0438 \u0441\u0442\u0440\u043e\u043a","\u0426\xe9 \u0432\u0438\u043f\u0430\u0434\u043a\u043e\u0432\u0438\u0439 \u043d\u0430\u0431\u0456\u0440 \u0441\u0438\u043c\u0432\u043e\u043b\u0456\u0432 [...]
\ No newline at end of file
diff --git a/test/fixtures/expected/comments.js b/test/fixtures/expected/comments.js
new file mode 100644
index 0000000..684215f
--- /dev/null
+++ b/test/fixtures/expected/comments.js
@@ -0,0 +1,13 @@
+/*!
+ * I am a comment
+ */
+function foo(){return 42}
+// @preserve preserve
+// @license license
+function bar(){return 2*foo()}/* @preserve
+ * multiline preserve
+ */
+/* @license
+ * multiline license
+ */
+function baz(){return bar()*bar()}
\ No newline at end of file
diff --git a/test/fixtures/expected/compress.js b/test/fixtures/expected/compress.js
new file mode 100644
index 0000000..a9c123e
--- /dev/null
+++ b/test/fixtures/expected/compress.js
@@ -0,0 +1 @@
+function longFunctionC(argumentC,argumentD){return longNameA+longNameB+argumentC+argumentD}var longNameA=1,longNameB=2,result=longFunctionC(3,4);
\ No newline at end of file
diff --git a/test/fixtures/expected/compress_explicit.js b/test/fixtures/expected/compress_explicit.js
new file mode 100644
index 0000000..c66c512
--- /dev/null
+++ b/test/fixtures/expected/compress_explicit.js
@@ -0,0 +1 @@
+function longFunctionC(a,b){return longNameA+longNameB+a+b}var longNameA=1,longNameB=2,result=longFunctionC(3,4);
\ No newline at end of file
diff --git a/test/fixtures/expected/compress_mangle.js b/test/fixtures/expected/compress_mangle.js
new file mode 100644
index 0000000..c66c512
--- /dev/null
+++ b/test/fixtures/expected/compress_mangle.js
@@ -0,0 +1 @@
+function longFunctionC(a,b){return longNameA+longNameB+a+b}var longNameA=1,longNameB=2,result=longFunctionC(3,4);
\ No newline at end of file
diff --git a/test/fixtures/expected/compress_mangle_banner.js b/test/fixtures/expected/compress_mangle_banner.js
new file mode 100644
index 0000000..1de7a82
--- /dev/null
+++ b/test/fixtures/expected/compress_mangle_banner.js
@@ -0,0 +1,2 @@
+// banner without sourcemap
+function longFunctionC(a,b){return longNameA+longNameB+a+b}var longNameA=1,longNameB=2,result=longFunctionC(3,4);
\ No newline at end of file
diff --git a/test/fixtures/expected/compress_mangle_beautify.js b/test/fixtures/expected/compress_mangle_beautify.js
new file mode 100644
index 0000000..15b03f0
--- /dev/null
+++ b/test/fixtures/expected/compress_mangle_beautify.js
@@ -0,0 +1,6 @@
+function longFunctionC(a, b) {
+    return longNameA + longNameB + a + b;
+}
+
+var longNameA = 1, longNameB = 2, result = longFunctionC(3, 4);
+// This is a footer.
\ No newline at end of file
diff --git a/test/fixtures/expected/compress_mangle_except.js b/test/fixtures/expected/compress_mangle_except.js
new file mode 100644
index 0000000..6830da9
--- /dev/null
+++ b/test/fixtures/expected/compress_mangle_except.js
@@ -0,0 +1 @@
+function longFunctionC(argumentC,a){return longNameA+longNameB+argumentC+a}var longNameA=1,longNameB=2,result=longFunctionC(3,4);
\ No newline at end of file
diff --git a/test/fixtures/expected/deep/directory/location/source_map.js.map b/test/fixtures/expected/deep/directory/location/source_map.js.map
new file mode 100644
index 0000000..39dde8e
--- /dev/null
+++ b/test/fixtures/expected/deep/directory/location/source_map.js.map
@@ -0,0 +1 @@
+{"version":3,"sources":["../../../../test/fixtures/src/simple.js"],"names":["longFunctionC","argumentC","argumentD","longNameA","longNameB","result"],"mappings":"AAOA,QAASA,eAAcC,EAAUC,GAC/B,MAAOC,WAAYC,UAAYH,EAAYC,EAL7C,GAAIC,WAAY,EAEZC,UAAY,EAMZC,OAASL,cAAc,EAAE","file":"sourcemap_customDir.js"}
\ No newline at end of file
diff --git a/test/fixtures/expected/enclose.js b/test/fixtures/expected/enclose.js
new file mode 100644
index 0000000..85dbcf8
--- /dev/null
+++ b/test/fixtures/expected/enclose.js
@@ -0,0 +1,8 @@
+(function(paramA, paramB) {
+    var longNameA = 1;
+    var longNameB = 2;
+    function longFunctionC(argumentC, argumentD) {
+        return longNameA + longNameB + argumentC + argumentD;
+    }
+    var result = longFunctionC(3, 4);
+})(window.argA, window.argB);
\ No newline at end of file
diff --git a/test/fixtures/expected/exportAll.js b/test/fixtures/expected/exportAll.js
new file mode 100644
index 0000000..604faa1
--- /dev/null
+++ b/test/fixtures/expected/exportAll.js
@@ -0,0 +1 @@
+!function(exports,global){function longFunctionC(argumentC,argumentD){return longNameA+longNameB+argumentC+argumentD}var longNameA=1,longNameB=2,result=longFunctionC(3,4);exports.longNameA=longNameA,exports.longNameB=longNameB,exports.longFunctionC=longFunctionC,exports.result=result,global.testExport=exports}({},function(){return this}());
\ No newline at end of file
diff --git a/test/fixtures/expected/expression.js b/test/fixtures/expected/expression.js
new file mode 100644
index 0000000..ce5c947
--- /dev/null
+++ b/test/fixtures/expected/expression.js
@@ -0,0 +1 @@
+function(doc){emit(doc._id,doc)}
\ No newline at end of file
diff --git a/test/fixtures/expected/expression.json b/test/fixtures/expected/expression.json
new file mode 100644
index 0000000..d2ef132
--- /dev/null
+++ b/test/fixtures/expected/expression.json
@@ -0,0 +1 @@
+{employees:[{firstName:"John",lastName:"Doe"}]}
\ No newline at end of file
diff --git a/test/fixtures/expected/mangle.js b/test/fixtures/expected/mangle.js
new file mode 100644
index 0000000..c66c512
--- /dev/null
+++ b/test/fixtures/expected/mangle.js
@@ -0,0 +1 @@
+function longFunctionC(a,b){return longNameA+longNameB+a+b}var longNameA=1,longNameB=2,result=longFunctionC(3,4);
\ No newline at end of file
diff --git a/test/fixtures/expected/mangleprops.js b/test/fixtures/expected/mangleprops.js
new file mode 100644
index 0000000..19e7eb9
--- /dev/null
+++ b/test/fixtures/expected/mangleprops.js
@@ -0,0 +1 @@
+var myObj={a:function(a){a++},b:function(){},c:function(){}},dontMangleMeVariable2=function(){},dontMangleMeVariable3=function(){};
\ No newline at end of file
diff --git a/test/fixtures/expected/mangleprops_withExcept.js b/test/fixtures/expected/mangleprops_withExcept.js
new file mode 100644
index 0000000..1118726
--- /dev/null
+++ b/test/fixtures/expected/mangleprops_withExcept.js
@@ -0,0 +1 @@
+var myObj={a:function(dontMangleMeVariable){dontMangleMeVariable++},b:function(){},c:function(){}},dontMangleMeVariable2=function(){},dontMangleMeVariable3=function(){};
\ No newline at end of file
diff --git a/test/fixtures/expected/mangleprops_withExceptAndExceptionsFiles.js b/test/fixtures/expected/mangleprops_withExceptAndExceptionsFiles.js
new file mode 100644
index 0000000..334f4a5
--- /dev/null
+++ b/test/fixtures/expected/mangleprops_withExceptAndExceptionsFiles.js
@@ -0,0 +1 @@
+var a={a:function(dontMangleMeVariable){dontMangleMeVariable++},dontMangleMeProperty:function(){},b:function(){}},dontMangleMeVariable2=function(){},dontMangleMeVariable3=function(){};
\ No newline at end of file
diff --git a/test/fixtures/expected/mangleprops_withExceptionsFiles.js b/test/fixtures/expected/mangleprops_withExceptionsFiles.js
new file mode 100644
index 0000000..c7ec6d0
--- /dev/null
+++ b/test/fixtures/expected/mangleprops_withExceptionsFiles.js
@@ -0,0 +1 @@
+var a={a:function(a){a++},dontMangleMeProperty:function(){},b:function(){}},dontMangleMeVariable2=function(){},dontMangleMeVariable3=function(){};
\ No newline at end of file
diff --git a/test/fixtures/expected/mangleprops_withNameCacheFile1.js b/test/fixtures/expected/mangleprops_withNameCacheFile1.js
new file mode 100644
index 0000000..4205c8e
--- /dev/null
+++ b/test/fixtures/expected/mangleprops_withNameCacheFile1.js
@@ -0,0 +1 @@
+var a={a:function(a){a++},b:function(){},c:function(){}},b=function(){},c=function(){};
\ No newline at end of file
diff --git a/test/fixtures/expected/mangleprops_withNameCacheFile2.js b/test/fixtures/expected/mangleprops_withNameCacheFile2.js
new file mode 100644
index 0000000..92a68ba
--- /dev/null
+++ b/test/fixtures/expected/mangleprops_withNameCacheFile2.js
@@ -0,0 +1 @@
+var d=10;a.a(d);
\ No newline at end of file
diff --git a/test/fixtures/expected/mangleprops_withRegex.js b/test/fixtures/expected/mangleprops_withRegex.js
new file mode 100644
index 0000000..9e42982
--- /dev/null
+++ b/test/fixtures/expected/mangleprops_withRegex.js
@@ -0,0 +1 @@
+var anObject={a:"val","#key2":"val2"};
\ No newline at end of file
diff --git a/test/fixtures/expected/maxLineLen.js b/test/fixtures/expected/maxLineLen.js
new file mode 100644
index 0000000..fd54657
--- /dev/null
+++ b/test/fixtures/expected/maxLineLen.js
@@ -0,0 +1,5 @@
+void function(){var cubes,list,math,number,opposite,race,square;number=42,opposite=!0,opposite&&(number=-42),
+square=function(x){return x*x},list=[1,2,3,4,5],math={root:Math.sqrt,square:square,cube:function(x){return x*square(x);
+}},race=function(winner,runners){return runners=2<=arguments.length?[].slice.call(arguments,1):[],print(winner,runners);
+},"undefined"!=typeof elvis&&null!=elvis&&alert("I knew it!"),cubes=function(accum$){for(var num,i$=0,length$=list.length;i$<length$;++i$)num=list[i$],
+accum$.push(math.cube(num));return accum$}.call(this,[])}.call(this);
\ No newline at end of file
diff --git a/test/fixtures/expected/multifile.js b/test/fixtures/expected/multifile.js
new file mode 100644
index 0000000..beb6c51
--- /dev/null
+++ b/test/fixtures/expected/multifile.js
@@ -0,0 +1 @@
+function longFunctionC(argumentC,argumentD){return longNameA+longNameB+argumentC+argumentD}function foo(){return 42}function bar(){return 2*foo()}function baz(){return bar()*bar()}var longNameA=1,longNameB=2,result=longFunctionC(3,4);
\ No newline at end of file
diff --git a/test/fixtures/expected/quotes_double.js b/test/fixtures/expected/quotes_double.js
new file mode 100644
index 0000000..29a920c
--- /dev/null
+++ b/test/fixtures/expected/quotes_double.js
@@ -0,0 +1 @@
+function llama(){var a="This is a single quote string",b="This is a double quote string",c={this:"is part of an Object",and:"so is this",but:"this one has \"mixed\" quotes: '"};return[a,b,c]}
\ No newline at end of file
diff --git a/test/fixtures/expected/quotes_original.js b/test/fixtures/expected/quotes_original.js
new file mode 100644
index 0000000..296ab5c
--- /dev/null
+++ b/test/fixtures/expected/quotes_original.js
@@ -0,0 +1 @@
+function llama(){var a='This is a single quote string',b="This is a double quote string",c={this:"is part of an Object",and:'so is this',but:'this one has "mixed" quotes: \''};return[a,b,c]}
\ No newline at end of file
diff --git a/test/fixtures/expected/quotes_single.js b/test/fixtures/expected/quotes_single.js
new file mode 100644
index 0000000..b7628d3
--- /dev/null
+++ b/test/fixtures/expected/quotes_single.js
@@ -0,0 +1 @@
+function llama(){var a='This is a single quote string',b='This is a double quote string',c={this:'is part of an Object',and:'so is this',but:'this one has "mixed" quotes: \''};return[a,b,c]}
\ No newline at end of file
diff --git a/test/fixtures/expected/screwIE8.js b/test/fixtures/expected/screwIE8.js
new file mode 100644
index 0000000..a8ae2a3
--- /dev/null
+++ b/test/fixtures/expected/screwIE8.js
@@ -0,0 +1 @@
+var reserved_words={"class":!0};
\ No newline at end of file
diff --git a/test/fixtures/expected/source_map_custom_name b/test/fixtures/expected/source_map_custom_name
new file mode 100644
index 0000000..174aefc
--- /dev/null
+++ b/test/fixtures/expected/source_map_custom_name
@@ -0,0 +1 @@
+{"version":3,"sources":["../test/fixtures/src/simple.js"],"names":["longFunctionC","argumentC","argumentD","longNameA","longNameB","result"],"mappings":"AAOA,QAASA,eAAcC,EAAUC,GAC/B,MAAOC,WAAYC,UAAYH,EAAYC,EAL7C,GAAIC,WAAY,EAEZC,UAAY,EAMZC,OAASL,cAAc,EAAE","file":"sourcemap_customName.js"}
\ No newline at end of file
diff --git a/test/fixtures/expected/sourcemap_basic.js b/test/fixtures/expected/sourcemap_basic.js
new file mode 100644
index 0000000..26073b7
--- /dev/null
+++ b/test/fixtures/expected/sourcemap_basic.js
@@ -0,0 +1,2 @@
+function longFunctionC(a,b){return longNameA+longNameB+a+b}var longNameA=1,longNameB=2,result=longFunctionC(3,4);
+//# sourceMappingURL=sourcemap_basic.js.map
\ No newline at end of file
diff --git a/test/fixtures/expected/sourcemap_basic.js.map b/test/fixtures/expected/sourcemap_basic.js.map
new file mode 100644
index 0000000..87ade48
--- /dev/null
+++ b/test/fixtures/expected/sourcemap_basic.js.map
@@ -0,0 +1 @@
+{"version":3,"sources":["../test/fixtures/src/simple.js"],"names":["longFunctionC","argumentC","argumentD","longNameA","longNameB","result"],"mappings":"AAOA,QAASA,eAAcC,EAAUC,GAC/B,MAAOC,WAAYC,UAAYH,EAAYC,EAL7C,GAAIC,WAAY,EAEZC,UAAY,EAMZC,OAASL,cAAc,EAAE","file":"sourcemap_basic.js"}
\ No newline at end of file
diff --git a/test/fixtures/expected/sourcemap_customDir.js b/test/fixtures/expected/sourcemap_customDir.js
new file mode 100644
index 0000000..3ee9114
--- /dev/null
+++ b/test/fixtures/expected/sourcemap_customDir.js
@@ -0,0 +1,2 @@
+function longFunctionC(a,b){return longNameA+longNameB+a+b}var longNameA=1,longNameB=2,result=longFunctionC(3,4);
+//# sourceMappingURL=deep/directory/location/source_map.js.map
\ No newline at end of file
diff --git a/test/fixtures/expected/sourcemap_customName.js b/test/fixtures/expected/sourcemap_customName.js
new file mode 100644
index 0000000..133ca52
--- /dev/null
+++ b/test/fixtures/expected/sourcemap_customName.js
@@ -0,0 +1,2 @@
+function longFunctionC(a,b){return longNameA+longNameB+a+b}var longNameA=1,longNameB=2,result=longFunctionC(3,4);
+//# sourceMappingURL=source_map_custom_name
\ No newline at end of file
diff --git a/test/fixtures/expected/sourcemap_customRoot.js b/test/fixtures/expected/sourcemap_customRoot.js
new file mode 100644
index 0000000..98fe505
--- /dev/null
+++ b/test/fixtures/expected/sourcemap_customRoot.js
@@ -0,0 +1,2 @@
+function longFunctionC(a,b){return longNameA+longNameB+a+b}var longNameA=1,longNameB=2,result=longFunctionC(3,4);
+//# sourceMappingURL=sourcemap_customRoot.js.map
\ No newline at end of file
diff --git a/test/fixtures/expected/sourcemap_customRoot.js.map b/test/fixtures/expected/sourcemap_customRoot.js.map
new file mode 100644
index 0000000..b90cfe9
--- /dev/null
+++ b/test/fixtures/expected/sourcemap_customRoot.js.map
@@ -0,0 +1 @@
+{"version":3,"sources":["../test/fixtures/src/simple.js"],"names":["longFunctionC","argumentC","argumentD","longNameA","longNameB","result"],"mappings":"AAOA,QAASA,eAAcC,EAAUC,GAC/B,MAAOC,WAAYC,UAAYH,EAAYC,EAL7C,GAAIC,WAAY,EAEZC,UAAY,EAMZC,OAASL,cAAc,EAAE","file":"sourcemap_customRoot.js","sourceRoot":"https://github.com/RReverser/grunt-contrib-uglify/tree/master/tmp"}
\ No newline at end of file
diff --git a/test/fixtures/expected/sourcemap_customUrl.js b/test/fixtures/expected/sourcemap_customUrl.js
new file mode 100644
index 0000000..c063d4b
--- /dev/null
+++ b/test/fixtures/expected/sourcemap_customUrl.js
@@ -0,0 +1,2 @@
+function longFunctionC(a,b){return longNameA+longNameB+a+b}var longNameA=1,longNameB=2,result=longFunctionC(3,4);
+//# sourceMappingURL=http://www.test.com/test/sourcemap_customUrl.js.map
\ No newline at end of file
diff --git a/test/fixtures/expected/sourcemap_functionName.js b/test/fixtures/expected/sourcemap_functionName.js
new file mode 100644
index 0000000..448cc3a
--- /dev/null
+++ b/test/fixtures/expected/sourcemap_functionName.js
@@ -0,0 +1,2 @@
+function longFunctionC(a,b){return longNameA+longNameB+a+b}var longNameA=1,longNameB=2,result=longFunctionC(3,4);
+//# sourceMappingURL=sourcemap_functionName.js.fn.map
\ No newline at end of file
diff --git a/test/fixtures/expected/sourcemap_functionName.js.fn.map b/test/fixtures/expected/sourcemap_functionName.js.fn.map
new file mode 100644
index 0000000..226ffab
--- /dev/null
+++ b/test/fixtures/expected/sourcemap_functionName.js.fn.map
@@ -0,0 +1 @@
+{"version":3,"sources":["../test/fixtures/src/simple.js"],"names":["longFunctionC","argumentC","argumentD","longNameA","longNameB","result"],"mappings":"AAOA,QAASA,eAAcC,EAAUC,GAC/B,MAAOC,WAAYC,UAAYH,EAAYC,EAL7C,GAAIC,WAAY,EAEZC,UAAY,EAMZC,OAASL,cAAc,EAAE","file":"sourcemap_functionName.js"}
\ No newline at end of file
diff --git a/test/fixtures/expected/sourcemap_sources.js.map b/test/fixtures/expected/sourcemap_sources.js.map
new file mode 100644
index 0000000..dd2b1f6
--- /dev/null
+++ b/test/fixtures/expected/sourcemap_sources.js.map
@@ -0,0 +1 @@
+{"version":3,"sources":["../test/fixtures/src/simple.js"],"names":["longFunctionC","argumentC","argumentD","longNameA","longNameB","result"],"mappings":"AAOA,QAASA,eAAcC,EAAUC,GAC/B,MAAOC,WAAYC,UAAYH,EAAYC,EAL7C,GAAIC,WAAY,EAEZC,UAAY,EAMZC,OAASL,cAAc,EAAE","file":"sourcemap_sources.js","sourcesContent":["\n// Hello world, I'm a comment!\n\nvar longNameA = 1;\n\nvar longNameB = 2;\n\nfunction longFunctionC(argumentC,argumentD) {\n  return longNameA + longNameB + argumentC + argumentD;\n}\ [...]
\ No newline at end of file
diff --git a/test/fixtures/expected/sourcemapin.js b/test/fixtures/expected/sourcemapin.js
new file mode 100644
index 0000000..558eaeb
--- /dev/null
+++ b/test/fixtures/expected/sourcemapin.js
@@ -0,0 +1,4 @@
+// Hello World
+
+void function(){var cubes,list,math,number,opposite,race,square;number=42,opposite=!0,opposite&&(number=-42),square=function(x){return x*x},list=[1,2,3,4,5],math={root:Math.sqrt,square:square,cube:function(x){return x*square(x)}},race=function(winner,runners){return runners=2<=arguments.length?[].slice.call(arguments,1):[],print(winner,runners)},"undefined"!=typeof elvis&&null!=elvis&&alert("I knew it!"),cubes=function(accum$){for(var num,i$=0,length$=list.length;i$<length$;++i$)num=list [...]
+//# sourceMappingURL=sourcemapin.js.map
\ No newline at end of file
diff --git a/test/fixtures/expected/sourcemapin.js.map b/test/fixtures/expected/sourcemapin.js.map
new file mode 100644
index 0000000..918379d
--- /dev/null
+++ b/test/fixtures/expected/sourcemapin.js.map
@@ -0,0 +1 @@
+{"version":3,"sources":["../test/fixtures/src/simple2.coffee"],"names":["number","opposite","square","x","list","math","root","Math","sqrt","cube","race","winner","runners","arguments","length","slice","call","print","elvis","alert","cubes","accum$","i$","length$","num"],"mappings":";;+DACCA,QAAW,GACXC,UAAW,EAGKA,WAAhBD,QAAS,IAGTE,OAAS,SAAAC,SAAOA,GAAIA,GAGpBC,MAAQ,EAAG,EAAG,EAAG,EAAG,GAGpBC,MACGC,KAAQC,KAAIC,KACbN,OAAQA,OACRO,KAAQ,SAAAN,SAAOA,GAAID,OAAOC,KAG1BO,KAAO,SAAAC,OAAAC,eAASA,SA [...]
\ No newline at end of file
diff --git a/test/fixtures/expected/sourcemapin_sources.js b/test/fixtures/expected/sourcemapin_sources.js
new file mode 100644
index 0000000..e73be28
--- /dev/null
+++ b/test/fixtures/expected/sourcemapin_sources.js
@@ -0,0 +1,2 @@
+void function(){var a,b,c,d,e,f,g;d=42,e=!0,e&&(d=-42),g=function(a){return a*a},b=[1,2,3,4,5],c={root:Math.sqrt,square:g,cube:function(a){return a*g(a)}},f=function(a,b){return b=2<=arguments.length?[].slice.call(arguments,1):[],print(a,b)},"undefined"!=typeof elvis&&null!=elvis&&alert("I knew it!"),a=function(a){for(var d,e=0,f=b.length;e<f;++e)d=b[e],a.push(c.cube(d));return a}.call(this,[])}.call(this);
+//# sourceMappingURL=sourcemapin_sources.js.map
\ No newline at end of file
diff --git a/test/fixtures/expected/sourcemapin_sources.js.map b/test/fixtures/expected/sourcemapin_sources.js.map
new file mode 100644
index 0000000..113a596
--- /dev/null
+++ b/test/fixtures/expected/sourcemapin_sources.js.map
@@ -0,0 +1 @@
+{"version":3,"sources":["../test/fixtures/src/simple2.coffee"],"names":["number","opposite","square","x","list","math","root","Math","sqrt","cube","race","winner","runners","arguments","length","slice","call","print","elvis","alert","cubes","accum$","i$","length$","num"],"mappings":"iCACCA,GAAW,GACXC,GAAW,EAGKA,IAAhBD,GAAS,IAGTE,EAAS,SAAAC,SAAOA,GAAIA,GAGpBC,GAAQ,EAAG,EAAG,EAAG,EAAG,GAGpBC,GACGC,KAAQC,KAAIC,KACbN,OAAQA,EACRO,KAAQ,SAAAN,SAAOA,GAAID,EAAOC,KAG1BO,EAAO,SAAAC,EAAAC,SAASA,GAAA [...]
\ No newline at end of file
diff --git a/test/fixtures/expected/sourcemaps_multiple1.js b/test/fixtures/expected/sourcemaps_multiple1.js
new file mode 100644
index 0000000..69953e7
--- /dev/null
+++ b/test/fixtures/expected/sourcemaps_multiple1.js
@@ -0,0 +1,2 @@
+function longFunctionC(a,b){return longNameA+longNameB+a+b}var longNameA=1,longNameB=2,result=longFunctionC(3,4);
+//# sourceMappingURL=sourcemaps_multiple1.js.map
\ No newline at end of file
diff --git a/test/fixtures/expected/sourcemaps_multiple1.js.map b/test/fixtures/expected/sourcemaps_multiple1.js.map
new file mode 100644
index 0000000..fe9ca2f
--- /dev/null
+++ b/test/fixtures/expected/sourcemaps_multiple1.js.map
@@ -0,0 +1 @@
+{"version":3,"sources":["../test/fixtures/src/simple.js"],"names":["longFunctionC","argumentC","argumentD","longNameA","longNameB","result"],"mappings":"AAOA,QAASA,eAAcC,EAAUC,GAC/B,MAAOC,WAAYC,UAAYH,EAAYC,EAL7C,GAAIC,WAAY,EAEZC,UAAY,EAMZC,OAASL,cAAc,EAAE","file":"sourcemaps_multiple1.js"}
\ No newline at end of file
diff --git a/test/fixtures/expected/sourcemaps_multiple1_fnName.js b/test/fixtures/expected/sourcemaps_multiple1_fnName.js
new file mode 100644
index 0000000..4e0e3f9
--- /dev/null
+++ b/test/fixtures/expected/sourcemaps_multiple1_fnName.js
@@ -0,0 +1,2 @@
+function longFunctionC(a,b){return longNameA+longNameB+a+b}var longNameA=1,longNameB=2,result=longFunctionC(3,4);
+//# sourceMappingURL=sourcemaps_multiple1_fnName.js.fn.map
\ No newline at end of file
diff --git a/test/fixtures/expected/sourcemaps_multiple1_fnName.js.fn.map b/test/fixtures/expected/sourcemaps_multiple1_fnName.js.fn.map
new file mode 100644
index 0000000..8a99578
--- /dev/null
+++ b/test/fixtures/expected/sourcemaps_multiple1_fnName.js.fn.map
@@ -0,0 +1 @@
+{"version":3,"sources":["../test/fixtures/src/simple.js"],"names":["longFunctionC","argumentC","argumentD","longNameA","longNameB","result"],"mappings":"AAOA,QAASA,eAAcC,EAAUC,GAC/B,MAAOC,WAAYC,UAAYH,EAAYC,EAL7C,GAAIC,WAAY,EAEZC,UAAY,EAMZC,OAASL,cAAc,EAAE","file":"sourcemaps_multiple1_fnName.js"}
\ No newline at end of file
diff --git a/test/fixtures/expected/sourcemaps_multiple2.js b/test/fixtures/expected/sourcemaps_multiple2.js
new file mode 100644
index 0000000..817a4bf
--- /dev/null
+++ b/test/fixtures/expected/sourcemaps_multiple2.js
@@ -0,0 +1,2 @@
+function foo(){return 42}function bar(){return 2*foo()}function baz(){return bar()*bar()}
+//# sourceMappingURL=sourcemaps_multiple2.js.map
\ No newline at end of file
diff --git a/test/fixtures/expected/sourcemaps_multiple2.js.map b/test/fixtures/expected/sourcemaps_multiple2.js.map
new file mode 100644
index 0000000..f1160d9
--- /dev/null
+++ b/test/fixtures/expected/sourcemaps_multiple2.js.map
@@ -0,0 +1 @@
+{"version":3,"sources":["../test/fixtures/src/comments.js"],"names":["foo","bar","baz"],"mappings":"AAGA,QAASA,OACP,MAAO,IAIT,QAASC,OACP,MAAa,GAAND,MAQT,QAASE,OACP,MAAOD,OAAMA","file":"sourcemaps_multiple2.js"}
\ No newline at end of file
diff --git a/test/fixtures/expected/sourcemaps_multiple2_fnName.js b/test/fixtures/expected/sourcemaps_multiple2_fnName.js
new file mode 100644
index 0000000..ed8bfff
--- /dev/null
+++ b/test/fixtures/expected/sourcemaps_multiple2_fnName.js
@@ -0,0 +1,2 @@
+function foo(){return 42}function bar(){return 2*foo()}function baz(){return bar()*bar()}
+//# sourceMappingURL=sourcemaps_multiple2_fnName.js.fn.map
\ No newline at end of file
diff --git a/test/fixtures/expected/sourcemaps_multiple2_fnName.js.fn.map b/test/fixtures/expected/sourcemaps_multiple2_fnName.js.fn.map
new file mode 100644
index 0000000..129d091
--- /dev/null
+++ b/test/fixtures/expected/sourcemaps_multiple2_fnName.js.fn.map
@@ -0,0 +1 @@
+{"version":3,"sources":["../test/fixtures/src/comments.js"],"names":["foo","bar","baz"],"mappings":"AAGA,QAASA,OACP,MAAO,IAIT,QAASC,OACP,MAAa,GAAND,MAQT,QAASE,OACP,MAAOD,OAAMA","file":"sourcemaps_multiple2_fnName.js"}
\ No newline at end of file
diff --git a/test/fixtures/expected/uglify_name_cache.json b/test/fixtures/expected/uglify_name_cache.json
new file mode 100644
index 0000000..3c40b56
--- /dev/null
+++ b/test/fixtures/expected/uglify_name_cache.json
@@ -0,0 +1,19 @@
+{
+  "props": {
+    "cname": 2,
+    "props": {
+      "$myFunction": "a",
+      "$dontMangleMeProperty": "b",
+      "$dontMangleMeProperty2": "c"
+    }
+  },
+  "vars": {
+    "cname": 3,
+    "props": {
+      "$myObj": "a",
+      "$dontMangleMeVariable2": "b",
+      "$dontMangleMeVariable3": "c",
+      "$myNumber": "d"
+    }
+  }
+}
\ No newline at end of file
diff --git a/test/fixtures/expected/wrap.js b/test/fixtures/expected/wrap.js
new file mode 100644
index 0000000..4723543
--- /dev/null
+++ b/test/fixtures/expected/wrap.js
@@ -0,0 +1 @@
+!function(exports,global){function longFunctionC(argumentC,argumentD){return longNameA+longNameB+argumentC+argumentD}var longNameA=1,longNameB=2;longFunctionC(3,4);global.testExport=exports}({},function(){return this}());
\ No newline at end of file
diff --git a/test/fixtures/src/comments.js b/test/fixtures/src/comments.js
new file mode 100644
index 0000000..32e5578
--- /dev/null
+++ b/test/fixtures/src/comments.js
@@ -0,0 +1,21 @@
+/*!
+ * I am a comment
+ */
+function foo() {
+  return 42;
+}
+// @preserve preserve
+// @license license
+function bar() {
+  return foo()*2;
+}
+/* @preserve
+ * multiline preserve
+ */
+/* @license
+ * multiline license
+ */
+function baz() {
+  return bar()*bar();
+}
+// end - not preserved
\ No newline at end of file
diff --git a/test/fixtures/src/exceptionsfile1.json b/test/fixtures/src/exceptionsfile1.json
new file mode 100644
index 0000000..e76446e
--- /dev/null
+++ b/test/fixtures/src/exceptionsfile1.json
@@ -0,0 +1,4 @@
+{
+  "vars": ["dontMangleMeVariable2"],
+  "props": ["dontMangleMeProperty"]
+}
diff --git a/test/fixtures/src/exceptionsfile2.json b/test/fixtures/src/exceptionsfile2.json
new file mode 100644
index 0000000..f2cb796
--- /dev/null
+++ b/test/fixtures/src/exceptionsfile2.json
@@ -0,0 +1,5 @@
+{
+  "vars": ["dontMangleMeVariable3"],
+  "props": []
+}
+
diff --git a/test/fixtures/src/expression.js b/test/fixtures/src/expression.js
new file mode 100644
index 0000000..5cf0e64
--- /dev/null
+++ b/test/fixtures/src/expression.js
@@ -0,0 +1,3 @@
+function(doc) {
+    emit(doc._id,doc);
+}
diff --git a/test/fixtures/src/localization.js b/test/fixtures/src/localization.js
new file mode 100644
index 0000000..da8c0b4
--- /dev/null
+++ b/test/fixtures/src/localization.js
@@ -0,0 +1,6 @@
+var set = [
+    "This is a random set of chαracters and strings.",
+    "这是一组随机字符和字符串。",
+    "Это случайный набор символов и строк",
+    "Цé випадковий набір символів та рядків"
+], answer = set[Math.floor(Math.random()*set.length)];
\ No newline at end of file
diff --git a/test/fixtures/src/mangleprops.js b/test/fixtures/src/mangleprops.js
new file mode 100644
index 0000000..985a89c
--- /dev/null
+++ b/test/fixtures/src/mangleprops.js
@@ -0,0 +1,8 @@
+var myObj = {
+  myFunction: function(dontMangleMeVariable) { dontMangleMeVariable++; },
+  dontMangleMeProperty: function() {},
+  dontMangleMeProperty2: function() {}
+};
+
+var dontMangleMeVariable2 = function() {};
+var dontMangleMeVariable3 = function() {};
diff --git a/test/fixtures/src/mangleprops_withNameCache.js b/test/fixtures/src/mangleprops_withNameCache.js
new file mode 100644
index 0000000..5902dda
--- /dev/null
+++ b/test/fixtures/src/mangleprops_withNameCache.js
@@ -0,0 +1,2 @@
+var myNumber = 10;
+myObj.myFunction(myNumber);
diff --git a/test/fixtures/src/mangleprops_withRegex.js b/test/fixtures/src/mangleprops_withRegex.js
new file mode 100644
index 0000000..bd37657
--- /dev/null
+++ b/test/fixtures/src/mangleprops_withRegex.js
@@ -0,0 +1,4 @@
+var anObject = {
+  key1: 'val',
+  '#key2': 'val2'
+};
diff --git a/test/fixtures/src/quotes.js b/test/fixtures/src/quotes.js
new file mode 100644
index 0000000..649c89d
--- /dev/null
+++ b/test/fixtures/src/quotes.js
@@ -0,0 +1,11 @@
+function llama() {
+  var a = 'This is a single quote string';
+  var b = "This is a double quote string";
+  var c = {
+    "this": "is part of an Object",
+    'and': 'so is this',
+    'but': 'this one has "mixed" quotes: \''
+  };
+
+  return [a, b, c];
+}
diff --git a/test/fixtures/src/screwIE8.js b/test/fixtures/src/screwIE8.js
new file mode 100644
index 0000000..70ce11e
--- /dev/null
+++ b/test/fixtures/src/screwIE8.js
@@ -0,0 +1,5 @@
+
+// screw-ie8 false will not remove quotes
+var reserved_words = {
+  'class': true
+};
diff --git a/test/fixtures/src/simple.js b/test/fixtures/src/simple.js
new file mode 100644
index 0000000..00bc938
--- /dev/null
+++ b/test/fixtures/src/simple.js
@@ -0,0 +1,15 @@
+
+// Hello world, I'm a comment!
+
+var longNameA = 1;
+
+var longNameB = 2;
+
+function longFunctionC(argumentC,argumentD) {
+  return longNameA + longNameB + argumentC + argumentD;
+}
+
+var result = longFunctionC(3,4);
+
+/*! I might be preserved, yay! */
+
diff --git a/test/fixtures/src/simple.json b/test/fixtures/src/simple.json
new file mode 100644
index 0000000..597bd5d
--- /dev/null
+++ b/test/fixtures/src/simple.json
@@ -0,0 +1,8 @@
+{
+    "employees": [
+        {
+            "firstName": "John",
+            "lastName": "Doe"
+        }
+    ]
+}
diff --git a/test/fixtures/src/simple2.coffee b/test/fixtures/src/simple2.coffee
new file mode 100644
index 0000000..113aa34
--- /dev/null
+++ b/test/fixtures/src/simple2.coffee
@@ -0,0 +1,28 @@
+# Assignment:
+number   = 42
+opposite = true
+
+# Conditions:
+number = -42 if opposite
+
+# Functions:
+square = (x) -> x * x
+
+# Arrays:
+list = [1, 2, 3, 4, 5]
+
+# Objects:
+math =
+  root:   Math.sqrt
+  square: square
+  cube:   (x) -> x * square x
+
+# Splats:
+race = (winner, runners...) ->
+  print winner, runners
+
+# Existence:
+alert "I knew it!" if elvis?
+
+# Array comprehensions:
+cubes = (math.cube num for num in list)
\ No newline at end of file
diff --git a/test/fixtures/src/simple2.js b/test/fixtures/src/simple2.js
new file mode 100644
index 0000000..31fd083
--- /dev/null
+++ b/test/fixtures/src/simple2.js
@@ -0,0 +1,39 @@
+// Generated by CoffeeScript 2.0.0-dev
+void function () {
+  var cubes, list, math, number, opposite, race, square;
+  number = 42;
+  opposite = true;
+  if (opposite)
+    number = -42;
+  square = function (x) {
+    return x * x;
+  };
+  list = [
+    1,
+    2,
+    3,
+    4,
+    5
+  ];
+  math = {
+    root: Math.sqrt,
+    square: square,
+    cube: function (x) {
+      return x * square(x);
+    }
+  };
+  race = function (winner, runners) {
+    runners = 2 <= arguments.length ? [].slice.call(arguments, 1) : [];
+    return print(winner, runners);
+  };
+  if ('undefined' !== typeof elvis && null != elvis)
+    alert('I knew it!');
+  cubes = function (accum$) {
+    var num;
+    for (var i$ = 0, length$ = list.length; i$ < length$; ++i$) {
+      num = list[i$];
+      accum$.push(math.cube(num));
+    }
+    return accum$;
+  }.call(this, []);
+}.call(this);
diff --git a/test/fixtures/src/simple2.map b/test/fixtures/src/simple2.map
new file mode 100644
index 0000000..fa590f6
--- /dev/null
+++ b/test/fixtures/src/simple2.map
@@ -0,0 +1 @@
+{"version":3,"file":"test/fixtures/src/simple2.coffee","sources":["../test/fixtures/src/simple2.coffee"],"names":[],"mappings":"AAAC;;;EACA,MAAA,GAAW;EACX,QAAA,GAAW;EAGX,IAAgB,QAAhB,CAAA;AAAA,IAAA,MAAA,GAAS,CAAC;EAGV,MAAA,GAAS,SAAA,CAAA,CAAA,CAAA;WAAO,CAAA,CAAA,CAAA,CAAI;;EAGpB,IAAA,GAAO,CAAA;AAAA,IAAC,CAAD;AAAA,IAAI,CAAJ;AAAA,IAAO,CAAP;AAAA,IAAU,CAAV;AAAA,IAAa,CAAb;AAAA,EAAA;EAGP,IAAA,GACG,CAAA;AAAA,IAAA,IAAA,EAAQ,IAAI,KAAZ;AAAA,IACD,MAAA,EAAQ,MADP;AAAA,IAED,IAAA,EAAQ,SAAA,CAAA,CAAA,CAA [...]
\ No newline at end of file
diff --git a/test/uglify_test.js b/test/uglify_test.js
new file mode 100644
index 0000000..05ad08b
--- /dev/null
+++ b/test/uglify_test.js
@@ -0,0 +1,78 @@
+'use strict';
+
+var grunt = require('grunt');
+var path = require('path');
+
+var read = function() {
+  var filepath = path.join.apply(this, Array.prototype.slice.call(arguments));
+  return grunt.util.normalizelf(grunt.file.read(filepath));
+};
+
+exports.contrib_uglify = {
+  preuglified_files: function(test) {
+
+    var files = [
+      'beautify.js',
+      'comments.js',
+      'compress.js',
+      'compress_explicit.js',
+      'compress_mangle.js',
+      'compress_mangle_banner.js',
+      'compress_mangle_beautify.js',
+      'compress_mangle_except.js',
+      'enclose.js',
+      'multifile.js',
+      'wrap.js',
+      'maxLineLen.js',
+      'asciionly.js',
+      'exportAll.js',
+      'screwIE8.js',
+      'sourcemap_basic.js',
+      'sourcemap_basic.js.map',
+      'sourcemap_customDir.js',
+      'sourcemap_customName.js',
+      'sourcemap_customRoot.js',
+      'sourcemap_customRoot.js.map',
+      'sourcemap_customUrl.js',
+      'sourcemap_functionName.js',
+      'sourcemap_functionName.js.fn.map',
+      path.join('deep', 'directory', 'location', 'source_map.js.map'),
+      'sourcemapin.js',
+      'sourcemapin.js.map',
+      'sourcemap_sources.js.map',
+      'sourcemapin_sources.js',
+      'sourcemapin_sources.js.map',
+      'sourcemaps_multiple1.js',
+      'sourcemaps_multiple1.js.map',
+      'sourcemaps_multiple2.js',
+      'sourcemaps_multiple2.js.map',
+      'sourcemaps_multiple1_fnName.js',
+      'sourcemaps_multiple1_fnName.js.fn.map',
+      'sourcemaps_multiple2_fnName.js',
+      'sourcemaps_multiple2_fnName.js.fn.map',
+      'expression.json',
+      'expression.js',
+      'mangleprops.js',
+      'mangleprops_withExcept.js',
+      'mangleprops_withExceptionsFiles.js',
+      'mangleprops_withExceptAndExceptionsFiles.js',
+      'mangleprops_withNameCacheFile1.js',
+      'mangleprops_withNameCacheFile2.js',
+      'mangleprops_withRegex.js',
+      'uglify_name_cache.json',
+      'quotes_single.js',
+      'quotes_double.js',
+      'quotes_original.js'
+    ];
+
+    test.expect(files.length);
+
+    files.forEach(function(file) {
+      var actual = read('tmp', file);
+      var expected = read('test', 'fixtures', 'expected', file);
+      test.equal(actual, expected, 'task output should equal ' + file);
+    });
+
+    test.done();
+  }
+};

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-javascript/node-grunt-contrib-uglify.git



More information about the Pkg-javascript-commits mailing list