From 23d58e79bbe82244ed58c8816d16838a97ea3077 Mon Sep 17 00:00:00 2001
From: ole-martin <47389666+ole-martin@users.noreply.github.com>
Date: Mon, 18 Nov 2019 21:21:03 +0100
Subject: [PATCH 01/24] fix(runtime.js): partials compile not caching (#1600)

Reintroduce "merge" function, no called "mergeIfNeeded", that only creates a new partials
object if both "env.partials" and "options.partials" are set.

closes #1598
---
 lib/handlebars/runtime.js | 12 +++++++++++-
 spec/regressions.js       | 27 +++++++++++++++++++++++++++
 2 files changed, 38 insertions(+), 1 deletion(-)

diff --git a/lib/handlebars/runtime.js b/lib/handlebars/runtime.js
index 958afc3ef..59b1cc106 100644
--- a/lib/handlebars/runtime.js
+++ b/lib/handlebars/runtime.js
@@ -124,6 +124,15 @@ export function template(templateSpec, env) {
       }
       return value;
     },
+    mergeIfNeeded: function(param, common) {
+      let obj = param || common;
+
+      if (param && common && (param !== common)) {
+        obj = Utils.extend({}, common, param);
+      }
+
+      return obj;
+    },
     // An empty object to use as replacement for null-contexts
     nullContext: Object.seal({}),
 
@@ -161,7 +170,8 @@ export function template(templateSpec, env) {
       container.helpers = Utils.extend({}, env.helpers, options.helpers);
 
       if (templateSpec.usePartial) {
-        container.partials = Utils.extend({}, env.partials, options.partials);
+        // Use mergeIfNeeded here to prevent compiling global partials multiple times
+        container.partials = container.mergeIfNeeded(options.partials, env.partials);
       }
       if (templateSpec.usePartial || templateSpec.useDecorators) {
         container.decorators = Utils.extend({}, env.decorators, options.decorators);
diff --git a/spec/regressions.js b/spec/regressions.js
index 74594de6b..3eccb2817 100644
--- a/spec/regressions.js
+++ b/spec/regressions.js
@@ -334,4 +334,31 @@ describe('Regressions', function() {
 
     shouldCompileTo('{{helpa length="foo"}}', [obj, helpers], 'foo');
   });
+
+  describe('GH-1598: Performance degradation for partials since v4.3.0', function() {
+    // Do not run test for runs without compiler
+    if (!Handlebars.compile) {
+      return;
+    }
+
+    var newHandlebarsInstance;
+    beforeEach(function() {
+      newHandlebarsInstance = Handlebars.create();
+    });
+    afterEach(function() {
+      sinon.restore();
+    });
+
+    it('should only compile global partials once', function() {
+      var templateSpy = sinon.spy(newHandlebarsInstance, 'template');
+      newHandlebarsInstance.registerPartial({
+        'dude': 'I am a partial'
+      });
+      var string = 'Dudes: {{> dude}} {{> dude}}';
+      newHandlebarsInstance.compile(string)(); // This should compile template + partial once
+      newHandlebarsInstance.compile(string)(); // This should only compile template
+      equal(templateSpy.callCount, 3);
+      sinon.restore();
+    });
+  });
 });

From edcc84f29224fec79bba0f989d19a0eabde749e2 Mon Sep 17 00:00:00 2001
From: ole-martin <47389666+ole-martin@users.noreply.github.com>
Date: Mon, 2 Dec 2019 22:03:52 +0100
Subject: [PATCH 02/24] Update readme.md with updated links (#1620)

* Update readme.md with updated links

Fix http->https where possible and update links doc links

* Update README.markdown

* Fix precompilation link
---
 README.markdown | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/README.markdown b/README.markdown
index 434a0e3a6..5450f9cd2 100644
--- a/README.markdown
+++ b/README.markdown
@@ -11,12 +11,12 @@ Handlebars.js and Mustache are both logicless templating languages that
 keep the view and the code separated like we all know they should be.
 
 Checkout the official Handlebars docs site at
-[http://www.handlebarsjs.com](http://www.handlebarsjs.com) and the live demo at [http://tryhandlebarsjs.com/](http://tryhandlebarsjs.com/).
+[https://handlebarsjs.com/](https://handlebarsjs.com) and the live demo at [http://tryhandlebarsjs.com/](http://tryhandlebarsjs.com/).
 
 Installing
 ----------
 
-See our [installation documentation](http://handlebarsjs.com/installation.html).
+See our [installation documentation](https://handlebarsjs.com/installation/).
 
 Usage
 -----
@@ -46,23 +46,23 @@ var result = template(data);
 // </ul>
 ```
 
-Full documentation and more examples are at [handlebarsjs.com](http://handlebarsjs.com/).
+Full documentation and more examples are at [handlebarsjs.com](https://handlebarsjs.com/).
 
 Precompiling Templates
 ----------------------
 
-Handlebars allows templates to be precompiled and included as javascript code rather than the handlebars template allowing for faster startup time. Full details are located [here](http://handlebarsjs.com/precompilation.html).
+Handlebars allows templates to be precompiled and included as javascript code rather than the handlebars template allowing for faster startup time. Full details are located [here](https://handlebarsjs.com/installation/precompilation.html).
 
 Differences Between Handlebars.js and Mustache
 ----------------------------------------------
 Handlebars.js adds a couple of additional features to make writing
 templates easier and also changes a tiny detail of how partials work.
 
-- [Nested Paths](http://handlebarsjs.com/#paths)
-- [Helpers](http://handlebarsjs.com/#helpers)
-- [Block Expressions](http://handlebarsjs.com/#block-expressions)
-- [Literal Values](http://handlebarsjs.com/#literals)
-- [Delimited Comments](http://handlebarsjs.com/#comments)
+- [Nested Paths](https://handlebarsjs.com/guide/expressions.html#path-expressions)
+- [Helpers](https://handlebarsjs.com/guide/expressions.html#helpers)
+- [Block Expressions](https://handlebarsjs.com/guide/block-helpers.html#basic-blocks)
+- [Literal Values](https://handlebarsjs.com/guide/expressions.html#literal-segments)
+- [Delimited Comments](https://handlebarsjs.com/guide/#template-comments)
 
 Block expressions have the same syntax as mustache sections but should not be confused with one another. Sections are akin to an implicit `each` or `with` statement depending on the input data and helpers are explicit pieces of code that are free to implement whatever behavior they like. The [mustache spec](http://mustache.github.io/mustache.5.html) defines the exact behavior of sections. In the case of name conflicts, helpers are given priority.
 

From 587e7a3e63bf815857fd479c9100c7f07912e215 Mon Sep 17 00:00:00 2001
From: Nils Knappmeier <github@knappi.org>
Date: Sat, 30 Nov 2019 23:37:44 +0100
Subject: [PATCH 03/24] remove yarn.lock

---
 yarn.lock | 5839 -----------------------------------------------------
 1 file changed, 5839 deletions(-)
 delete mode 100644 yarn.lock

diff --git a/yarn.lock b/yarn.lock
deleted file mode 100644
index bf9a353ba..000000000
--- a/yarn.lock
+++ /dev/null
@@ -1,5839 +0,0 @@
-# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
-# yarn lockfile v1
-
-
-"@babel/code-frame@^7.0.0":
-  version "7.5.5"
-  resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.5.5.tgz#bc0782f6d69f7b7d49531219699b988f669a8f9d"
-  integrity sha512-27d4lZoomVyo51VegxI20xZPuSHusqbQag/ztrBC7wegWoQ1nLREPVSKSW8byhTlzTKyNE4ifaTA6lCp7JjpFw==
-  dependencies:
-    "@babel/highlight" "^7.0.0"
-
-"@babel/highlight@^7.0.0":
-  version "7.5.0"
-  resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.5.0.tgz#56d11312bd9248fa619591d02472be6e8cb32540"
-  integrity sha512-7dV4eu9gBxoM0dAnj/BCFDW9LFU0zvTrkq0ugM7pnHEgguOEeOz1so2ZghEdzviYzQEED0r4EAgpsBChKy1TRQ==
-  dependencies:
-    chalk "^2.0.0"
-    esutils "^2.0.2"
-    js-tokens "^4.0.0"
-
-"@knappi/grunt-saucelabs@^9.0.2":
-  version "9.0.2"
-  resolved "https://registry.yarnpkg.com/@knappi/grunt-saucelabs/-/grunt-saucelabs-9.0.2.tgz#ac3cf06bb2006e52174a9da43a73c32123fb5b95"
-  integrity sha512-PHnusXA+begWFgZS084ZAC8kT7FNRvvJIWg5FOqusRjr4LSe++RIk2HRULAQ8Dx+6HiKJiQXzrAsDagKh3k1pw==
-  dependencies:
-    "@knappi/sauce-tunnel" "^2.5.0"
-    colors "~1.1.2"
-    lodash "^4.17.11"
-    q "~1.4.1"
-    requestretry "~1.9.0"
-    saucelabs "^1.5.0"
-
-"@knappi/sauce-tunnel@^2.5.0":
-  version "2.5.0"
-  resolved "https://registry.yarnpkg.com/@knappi/sauce-tunnel/-/sauce-tunnel-2.5.0.tgz#b0161a95c211e438b39a80a5ddf0d5a57a0c6ca4"
-  integrity sha512-8f60HrHH4SRHOspcVLbN0gpDiBYLQjmZCXwmqibhzJDHGaD/fflPpdUD2kJJyeioydcf1T0xfpbMcJW0dLjpnw==
-  dependencies:
-    chalk "^2.4.2"
-    request "^2.88.0"
-    split "^1.0.1"
-
-"@types/parsimmon@^1.3.0":
-  version "1.10.0"
-  resolved "https://registry.yarnpkg.com/@types/parsimmon/-/parsimmon-1.10.0.tgz#ffb81cb023ff435a41d4710a29ab23c561dc9fdf"
-  integrity sha512-bsTIJFVQv7jnvNiC42ld2pQW2KRI+pAG243L+iATvqzy3X6+NH1obz2itRKDZZ8VVhN3wjwYax/VBGCcXzgTqQ==
-
-JSONSelect@0.4.0:
-  version "0.4.0"
-  resolved "https://registry.yarnpkg.com/JSONSelect/-/JSONSelect-0.4.0.tgz#a08edcc67eb3fcbe99ed630855344a0cf282bb8d"
-  integrity sha1-oI7cxn6z/L6Z7WMIVTRKDPKCu40=
-
-"JSV@>= 4.0.x":
-  version "4.0.2"
-  resolved "https://registry.yarnpkg.com/JSV/-/JSV-4.0.2.tgz#d077f6825571f82132f9dffaed587b4029feff57"
-  integrity sha1-0Hf2glVx+CEy+d/67Vh7QCn+/1c=
-
-abbrev@1:
-  version "1.1.1"
-  resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8"
-  integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==
-
-abbrev@1.0.x:
-  version "1.0.9"
-  resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.0.9.tgz#91b4792588a7738c25f35dd6f63752a2f8776135"
-  integrity sha1-kbR5JYinc4wl813W9jdSovh3YTU=
-
-accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.7:
-  version "1.3.7"
-  resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.7.tgz#531bc726517a3b2b41f850021c6cc15eaab507cd"
-  integrity sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==
-  dependencies:
-    mime-types "~2.1.24"
-    negotiator "0.6.2"
-
-acorn-jsx@^3.0.0:
-  version "3.0.1"
-  resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-3.0.1.tgz#afdf9488fb1ecefc8348f6fb22f464e32a58b36b"
-  integrity sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=
-  dependencies:
-    acorn "^3.0.4"
-
-acorn@^3.0.0, acorn@^3.0.4:
-  version "3.3.0"
-  resolved "https://registry.yarnpkg.com/acorn/-/acorn-3.3.0.tgz#45e37fb39e8da3f25baee3ff5369e2bb5f22017a"
-  integrity sha1-ReN/s56No/JbruP/U2niu18iAXo=
-
-acorn@^5.2.1, acorn@^5.5.0:
-  version "5.7.3"
-  resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.3.tgz#67aa231bf8812974b85235a96771eb6bd07ea279"
-  integrity sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw==
-
-agent-base@^4.3.0:
-  version "4.3.0"
-  resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.3.0.tgz#8165f01c436009bccad0b1d122f05ed770efc6ee"
-  integrity sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==
-  dependencies:
-    es6-promisify "^5.0.0"
-
-ajv-keywords@^2.1.0:
-  version "2.1.1"
-  resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-2.1.1.tgz#617997fc5f60576894c435f940d819e135b80762"
-  integrity sha1-YXmX/F9gV2iUxDX5QNgZ4TW4B2I=
-
-ajv@^5.2.3, ajv@^5.3.0:
-  version "5.5.2"
-  resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.5.2.tgz#73b5eeca3fab653e3d3f9422b341ad42205dc965"
-  integrity sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=
-  dependencies:
-    co "^4.6.0"
-    fast-deep-equal "^1.0.0"
-    fast-json-stable-stringify "^2.0.0"
-    json-schema-traverse "^0.3.0"
-
-ajv@^6.5.5:
-  version "6.10.2"
-  resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.10.2.tgz#d3cea04d6b017b2894ad69040fec8b623eb4bd52"
-  integrity sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==
-  dependencies:
-    fast-deep-equal "^2.0.1"
-    fast-json-stable-stringify "^2.0.0"
-    json-schema-traverse "^0.4.1"
-    uri-js "^4.2.2"
-
-align-text@^0.1.1, align-text@^0.1.3:
-  version "0.1.4"
-  resolved "https://registry.yarnpkg.com/align-text/-/align-text-0.1.4.tgz#0cd90a561093f35d0a99256c22b7069433fad117"
-  integrity sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=
-  dependencies:
-    kind-of "^3.0.2"
-    longest "^1.0.1"
-    repeat-string "^1.5.2"
-
-alter@~0.2.0:
-  version "0.2.0"
-  resolved "https://registry.yarnpkg.com/alter/-/alter-0.2.0.tgz#c7588808617572034aae62480af26b1d4d1cb3cd"
-  integrity sha1-x1iICGF1cgNKrmJICvJrHU0cs80=
-  dependencies:
-    stable "~0.1.3"
-
-amdefine@>=0.0.4:
-  version "1.0.1"
-  resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5"
-  integrity sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=
-
-ansi-escapes@^3.0.0:
-  version "3.2.0"
-  resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.2.0.tgz#8780b98ff9dbf5638152d1f1fe5c1d7b4442976b"
-  integrity sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==
-
-ansi-regex@^2.0.0:
-  version "2.1.1"
-  resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df"
-  integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8=
-
-ansi-regex@^3.0.0:
-  version "3.0.0"
-  resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998"
-  integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=
-
-ansi-styles@^2.2.1:
-  version "2.2.1"
-  resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe"
-  integrity sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=
-
-ansi-styles@^3.2.1:
-  version "3.2.1"
-  resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d"
-  integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==
-  dependencies:
-    color-convert "^1.9.0"
-
-ansi-styles@~1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-1.0.0.tgz#cb102df1c56f5123eab8b67cd7b98027a0279178"
-  integrity sha1-yxAt8cVvUSPquLZ817mAJ6AnkXg=
-
-anymatch@^1.3.0:
-  version "1.3.2"
-  resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-1.3.2.tgz#553dcb8f91e3c889845dfdba34c77721b90b9d7a"
-  integrity sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==
-  dependencies:
-    micromatch "^2.1.5"
-    normalize-path "^2.0.0"
-
-aproba@^1.0.3:
-  version "1.2.0"
-  resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a"
-  integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==
-
-are-we-there-yet@~1.1.2:
-  version "1.1.5"
-  resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz#4b35c2944f062a8bfcda66410760350fe9ddfc21"
-  integrity sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==
-  dependencies:
-    delegates "^1.0.0"
-    readable-stream "^2.0.6"
-
-argparse@^1.0.7:
-  version "1.0.10"
-  resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911"
-  integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==
-  dependencies:
-    sprintf-js "~1.0.2"
-
-arr-diff@^2.0.0:
-  version "2.0.0"
-  resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-2.0.0.tgz#8f3b827f955a8bd669697e4a4256ac3ceae356cf"
-  integrity sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=
-  dependencies:
-    arr-flatten "^1.0.1"
-
-arr-diff@^4.0.0:
-  version "4.0.0"
-  resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520"
-  integrity sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=
-
-arr-flatten@^1.0.1, arr-flatten@^1.1.0:
-  version "1.1.0"
-  resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1"
-  integrity sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==
-
-arr-union@^3.1.0:
-  version "3.1.0"
-  resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4"
-  integrity sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=
-
-array-each@^1.0.1:
-  version "1.0.1"
-  resolved "https://registry.yarnpkg.com/array-each/-/array-each-1.0.1.tgz#a794af0c05ab1752846ee753a1f211a05ba0c44f"
-  integrity sha1-p5SvDAWrF1KEbudTofIRoFugxE8=
-
-array-find-index@^1.0.1:
-  version "1.0.2"
-  resolved "https://registry.yarnpkg.com/array-find-index/-/array-find-index-1.0.2.tgz#df010aa1287e164bbda6f9723b0a96a1ec4187a1"
-  integrity sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=
-
-array-flatten@1.1.1:
-  version "1.1.1"
-  resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2"
-  integrity sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=
-
-array-slice@^1.0.0:
-  version "1.1.0"
-  resolved "https://registry.yarnpkg.com/array-slice/-/array-slice-1.1.0.tgz#e368ea15f89bc7069f7ffb89aec3a6c7d4ac22d4"
-  integrity sha512-B1qMD3RBP7O8o0H2KbrXDyB0IccejMF15+87Lvlor12ONPRHP6gTjXMNkt/d3ZuOGbAe66hFmaCfECI24Ufp6w==
-
-array-unique@^0.2.1:
-  version "0.2.1"
-  resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.2.1.tgz#a1d97ccafcbc2625cc70fadceb36a50c58b01a53"
-  integrity sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=
-
-array-unique@^0.3.2:
-  version "0.3.2"
-  resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428"
-  integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=
-
-asn1@~0.2.3:
-  version "0.2.4"
-  resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136"
-  integrity sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==
-  dependencies:
-    safer-buffer "~2.1.0"
-
-assert-plus@1.0.0, assert-plus@^1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525"
-  integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=
-
-assert@^1.1.1:
-  version "1.5.0"
-  resolved "https://registry.yarnpkg.com/assert/-/assert-1.5.0.tgz#55c109aaf6e0aefdb3dc4b71240c70bf574b18eb"
-  integrity sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA==
-  dependencies:
-    object-assign "^4.1.1"
-    util "0.10.3"
-
-assign-symbols@^1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367"
-  integrity sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=
-
-ast-traverse@~0.1.1:
-  version "0.1.1"
-  resolved "https://registry.yarnpkg.com/ast-traverse/-/ast-traverse-0.1.1.tgz#69cf2b8386f19dcda1bb1e05d68fe359d8897de6"
-  integrity sha1-ac8rg4bxnc2hux4F1o/jWdiJfeY=
-
-ast-types@0.8.12:
-  version "0.8.12"
-  resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.8.12.tgz#a0d90e4351bb887716c83fd637ebf818af4adfcc"
-  integrity sha1-oNkOQ1G7iHcWyD/WN+v4GK9K38w=
-
-ast-types@0.8.15:
-  version "0.8.15"
-  resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.8.15.tgz#8eef0827f04dff0ec8857ba925abe3fea6194e52"
-  integrity sha1-ju8IJ/BN/w7IhXupJavj/qYZTlI=
-
-ast-types@0.9.6:
-  version "0.9.6"
-  resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.9.6.tgz#102c9e9e9005d3e7e3829bf0c4fa24ee862ee9b9"
-  integrity sha1-ECyenpAF0+fjgpvwxPok7oYu6bk=
-
-async-each@^1.0.0:
-  version "1.0.3"
-  resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.3.tgz#b727dbf87d7651602f06f4d4ac387f47d91b0cbf"
-  integrity sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==
-
-async@1.5.2, async@1.x, async@^1.3.0, async@^1.5.2, async@~1.5.2:
-  version "1.5.2"
-  resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a"
-  integrity sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=
-
-async@^0.9.0:
-  version "0.9.2"
-  resolved "https://registry.yarnpkg.com/async/-/async-0.9.2.tgz#aea74d5e61c1f899613bf64bda66d4c78f2fd17d"
-  integrity sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0=
-
-async@^2.6.0:
-  version "2.6.3"
-  resolved "https://registry.yarnpkg.com/async/-/async-2.6.3.tgz#d72625e2344a3656e3a3ad4fa749fa83299d82ff"
-  integrity sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==
-  dependencies:
-    lodash "^4.17.14"
-
-async@~0.2.6:
-  version "0.2.10"
-  resolved "https://registry.yarnpkg.com/async/-/async-0.2.10.tgz#b6bbe0b0674b9d719708ca38de8c237cb526c3d1"
-  integrity sha1-trvgsGdLnXGXCMo43owjfLUmw9E=
-
-asynckit@^0.4.0:
-  version "0.4.0"
-  resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
-  integrity sha1-x57Zf380y48robyXkLzDZkdLS3k=
-
-atob@^2.1.1:
-  version "2.1.2"
-  resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9"
-  integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==
-
-aws-sdk@^2.1.49:
-  version "2.556.0"
-  resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.556.0.tgz#5c96bacf7942b530b20c94f3307e6650a97fd7be"
-  integrity sha512-qILMUNl/a7FYWU67Y24OGsXFhyDHM4qYdplMR2tps/g17pN9bEQ5ijxvGzW2T8VVyAsTanmn+dFyl/CH38pC5Q==
-  dependencies:
-    buffer "4.9.1"
-    events "1.1.1"
-    ieee754 "1.1.13"
-    jmespath "0.15.0"
-    querystring "0.2.0"
-    sax "1.2.1"
-    url "0.10.3"
-    uuid "3.3.2"
-    xml2js "0.4.19"
-
-aws-sign2@~0.7.0:
-  version "0.7.0"
-  resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8"
-  integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=
-
-aws4@^1.8.0:
-  version "1.8.0"
-  resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.8.0.tgz#f0e003d9ca9e7f59c7a508945d7b2ef9a04a542f"
-  integrity sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==
-
-babel-code-frame@^6.22.0:
-  version "6.26.0"
-  resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b"
-  integrity sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=
-  dependencies:
-    chalk "^1.1.3"
-    esutils "^2.0.2"
-    js-tokens "^3.0.2"
-
-babel-core@^5.0.0, babel-core@^5.4.0:
-  version "5.8.38"
-  resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-5.8.38.tgz#1fcaee79d7e61b750b00b8e54f6dfc9d0af86558"
-  integrity sha1-H8ruedfmG3ULALjlT238nQr4ZVg=
-  dependencies:
-    babel-plugin-constant-folding "^1.0.1"
-    babel-plugin-dead-code-elimination "^1.0.2"
-    babel-plugin-eval "^1.0.1"
-    babel-plugin-inline-environment-variables "^1.0.1"
-    babel-plugin-jscript "^1.0.4"
-    babel-plugin-member-expression-literals "^1.0.1"
-    babel-plugin-property-literals "^1.0.1"
-    babel-plugin-proto-to-assign "^1.0.3"
-    babel-plugin-react-constant-elements "^1.0.3"
-    babel-plugin-react-display-name "^1.0.3"
-    babel-plugin-remove-console "^1.0.1"
-    babel-plugin-remove-debugger "^1.0.1"
-    babel-plugin-runtime "^1.0.7"
-    babel-plugin-undeclared-variables-check "^1.0.2"
-    babel-plugin-undefined-to-void "^1.1.6"
-    babylon "^5.8.38"
-    bluebird "^2.9.33"
-    chalk "^1.0.0"
-    convert-source-map "^1.1.0"
-    core-js "^1.0.0"
-    debug "^2.1.1"
-    detect-indent "^3.0.0"
-    esutils "^2.0.0"
-    fs-readdir-recursive "^0.1.0"
-    globals "^6.4.0"
-    home-or-tmp "^1.0.0"
-    is-integer "^1.0.4"
-    js-tokens "1.0.1"
-    json5 "^0.4.0"
-    lodash "^3.10.0"
-    minimatch "^2.0.3"
-    output-file-sync "^1.1.0"
-    path-exists "^1.0.0"
-    path-is-absolute "^1.0.0"
-    private "^0.1.6"
-    regenerator "0.8.40"
-    regexpu "^1.3.0"
-    repeating "^1.1.2"
-    resolve "^1.1.6"
-    shebang-regex "^1.0.0"
-    slash "^1.0.0"
-    source-map "^0.5.0"
-    source-map-support "^0.2.10"
-    to-fast-properties "^1.0.0"
-    trim-right "^1.0.0"
-    try-resolve "^1.0.0"
-
-babel-loader@^5.0.0:
-  version "5.4.2"
-  resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-5.4.2.tgz#77fe28d8e60d0f056b1c1bca25b8494cdaab9c76"
-  integrity sha1-d/4o2OYNDwVrHBvKJbhJTNqrnHY=
-  dependencies:
-    babel-core "^5.4.0"
-    loader-utils "^0.2.9"
-    object-assign "^3.0.0"
-
-babel-plugin-constant-folding@^1.0.1:
-  version "1.0.1"
-  resolved "https://registry.yarnpkg.com/babel-plugin-constant-folding/-/babel-plugin-constant-folding-1.0.1.tgz#8361d364c98e449c3692bdba51eff0844290aa8e"
-  integrity sha1-g2HTZMmORJw2kr26Ue/whEKQqo4=
-
-babel-plugin-dead-code-elimination@^1.0.2:
-  version "1.0.2"
-  resolved "https://registry.yarnpkg.com/babel-plugin-dead-code-elimination/-/babel-plugin-dead-code-elimination-1.0.2.tgz#5f7c451274dcd7cccdbfbb3e0b85dd28121f0f65"
-  integrity sha1-X3xFEnTc18zNv7s+C4XdKBIfD2U=
-
-babel-plugin-eval@^1.0.1:
-  version "1.0.1"
-  resolved "https://registry.yarnpkg.com/babel-plugin-eval/-/babel-plugin-eval-1.0.1.tgz#a2faed25ce6be69ade4bfec263f70169195950da"
-  integrity sha1-ovrtJc5r5preS/7CY/cBaRlZUNo=
-
-babel-plugin-inline-environment-variables@^1.0.1:
-  version "1.0.1"
-  resolved "https://registry.yarnpkg.com/babel-plugin-inline-environment-variables/-/babel-plugin-inline-environment-variables-1.0.1.tgz#1f58ce91207ad6a826a8bf645fafe68ff5fe3ffe"
-  integrity sha1-H1jOkSB61qgmqL9kX6/mj/X+P/4=
-
-babel-plugin-jscript@^1.0.4:
-  version "1.0.4"
-  resolved "https://registry.yarnpkg.com/babel-plugin-jscript/-/babel-plugin-jscript-1.0.4.tgz#8f342c38276e87a47d5fa0a8bd3d5eb6ccad8fcc"
-  integrity sha1-jzQsOCduh6R9X6CovT1etsytj8w=
-
-babel-plugin-member-expression-literals@^1.0.1:
-  version "1.0.1"
-  resolved "https://registry.yarnpkg.com/babel-plugin-member-expression-literals/-/babel-plugin-member-expression-literals-1.0.1.tgz#cc5edb0faa8dc927170e74d6d1c02440021624d3"
-  integrity sha1-zF7bD6qNyScXDnTW0cAkQAIWJNM=
-
-babel-plugin-property-literals@^1.0.1:
-  version "1.0.1"
-  resolved "https://registry.yarnpkg.com/babel-plugin-property-literals/-/babel-plugin-property-literals-1.0.1.tgz#0252301900192980b1c118efea48ce93aab83336"
-  integrity sha1-AlIwGQAZKYCxwRjv6kjOk6q4MzY=
-
-babel-plugin-proto-to-assign@^1.0.3:
-  version "1.0.4"
-  resolved "https://registry.yarnpkg.com/babel-plugin-proto-to-assign/-/babel-plugin-proto-to-assign-1.0.4.tgz#c49e7afd02f577bc4da05ea2df002250cf7cd123"
-  integrity sha1-xJ56/QL1d7xNoF6i3wAiUM980SM=
-  dependencies:
-    lodash "^3.9.3"
-
-babel-plugin-react-constant-elements@^1.0.3:
-  version "1.0.3"
-  resolved "https://registry.yarnpkg.com/babel-plugin-react-constant-elements/-/babel-plugin-react-constant-elements-1.0.3.tgz#946736e8378429cbc349dcff62f51c143b34e35a"
-  integrity sha1-lGc26DeEKcvDSdz/YvUcFDs041o=
-
-babel-plugin-react-display-name@^1.0.3:
-  version "1.0.3"
-  resolved "https://registry.yarnpkg.com/babel-plugin-react-display-name/-/babel-plugin-react-display-name-1.0.3.tgz#754fe38926e8424a4e7b15ab6ea6139dee0514fc"
-  integrity sha1-dU/jiSboQkpOexWrbqYTne4FFPw=
-
-babel-plugin-remove-console@^1.0.1:
-  version "1.0.1"
-  resolved "https://registry.yarnpkg.com/babel-plugin-remove-console/-/babel-plugin-remove-console-1.0.1.tgz#d8f24556c3a05005d42aaaafd27787f53ff013a7"
-  integrity sha1-2PJFVsOgUAXUKqqv0neH9T/wE6c=
-
-babel-plugin-remove-debugger@^1.0.1:
-  version "1.0.1"
-  resolved "https://registry.yarnpkg.com/babel-plugin-remove-debugger/-/babel-plugin-remove-debugger-1.0.1.tgz#fd2ea3cd61a428ad1f3b9c89882ff4293e8c14c7"
-  integrity sha1-/S6jzWGkKK0fO5yJiC/0KT6MFMc=
-
-babel-plugin-runtime@^1.0.7:
-  version "1.0.7"
-  resolved "https://registry.yarnpkg.com/babel-plugin-runtime/-/babel-plugin-runtime-1.0.7.tgz#bf7c7d966dd56ecd5c17fa1cb253c9acb7e54aaf"
-  integrity sha1-v3x9lm3Vbs1cF/ocslPJrLflSq8=
-
-babel-plugin-undeclared-variables-check@^1.0.2:
-  version "1.0.2"
-  resolved "https://registry.yarnpkg.com/babel-plugin-undeclared-variables-check/-/babel-plugin-undeclared-variables-check-1.0.2.tgz#5cf1aa539d813ff64e99641290af620965f65dee"
-  integrity sha1-XPGqU52BP/ZOmWQSkK9iCWX2Xe4=
-  dependencies:
-    leven "^1.0.2"
-
-babel-plugin-undefined-to-void@^1.1.6:
-  version "1.1.6"
-  resolved "https://registry.yarnpkg.com/babel-plugin-undefined-to-void/-/babel-plugin-undefined-to-void-1.1.6.tgz#7f578ef8b78dfae6003385d8417a61eda06e2f81"
-  integrity sha1-f1eO+LeN+uYAM4XYQXph7aBuL4E=
-
-babel-runtime@^5.1.10:
-  version "5.8.38"
-  resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-5.8.38.tgz#1c0b02eb63312f5f087ff20450827b425c9d4c19"
-  integrity sha1-HAsC62MxL18If/IEUIJ7QlydTBk=
-  dependencies:
-    core-js "^1.0.0"
-
-babylon@^5.8.38:
-  version "5.8.38"
-  resolved "https://registry.yarnpkg.com/babylon/-/babylon-5.8.38.tgz#ec9b120b11bf6ccd4173a18bf217e60b79859ffd"
-  integrity sha1-7JsSCxG/bM1Bc6GL8hfmC3mFn/0=
-
-balanced-match@^1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767"
-  integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c=
-
-base64-js@^1.0.2:
-  version "1.3.1"
-  resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.1.tgz#58ece8cb75dd07e71ed08c736abc5fac4dbf8df1"
-  integrity sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==
-
-base@^0.11.1:
-  version "0.11.2"
-  resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f"
-  integrity sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==
-  dependencies:
-    cache-base "^1.0.1"
-    class-utils "^0.3.5"
-    component-emitter "^1.2.1"
-    define-property "^1.0.0"
-    isobject "^3.0.1"
-    mixin-deep "^1.2.0"
-    pascalcase "^0.1.1"
-
-basic-auth@~2.0.0:
-  version "2.0.1"
-  resolved "https://registry.yarnpkg.com/basic-auth/-/basic-auth-2.0.1.tgz#b998279bf47ce38344b4f3cf916d4679bbf51e3a"
-  integrity sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==
-  dependencies:
-    safe-buffer "5.1.2"
-
-batch@0.6.1:
-  version "0.6.1"
-  resolved "https://registry.yarnpkg.com/batch/-/batch-0.6.1.tgz#dc34314f4e679318093fc760272525f94bf25c16"
-  integrity sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=
-
-bcrypt-pbkdf@^1.0.0:
-  version "1.0.2"
-  resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e"
-  integrity sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=
-  dependencies:
-    tweetnacl "^0.14.3"
-
-benchmark@~1.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/benchmark/-/benchmark-1.0.0.tgz#2f1e2fa4c359f11122aa183082218e957e390c73"
-  integrity sha1-Lx4vpMNZ8REiqhgwgiGOlX45DHM=
-
-big.js@^3.1.3:
-  version "3.2.0"
-  resolved "https://registry.yarnpkg.com/big.js/-/big.js-3.2.0.tgz#a5fc298b81b9e0dca2e458824784b65c52ba588e"
-  integrity sha512-+hN/Zh2D08Mx65pZ/4g5bsmNiZUuChDiQfTUQ7qJr4/kuopCr88xZsAXv6mBoZEsUI4OuGHlX59qE94K2mMW8Q==
-
-binary-extensions@^1.0.0:
-  version "1.13.1"
-  resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.13.1.tgz#598afe54755b2868a5330d2aff9d4ebb53209b65"
-  integrity sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==
-
-bluebird@^2.9.33:
-  version "2.11.0"
-  resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-2.11.0.tgz#534b9033c022c9579c56ba3b3e5a5caafbb650e1"
-  integrity sha1-U0uQM8AiyVecVro7Plpcqvu2UOE=
-
-body-parser@1.19.0:
-  version "1.19.0"
-  resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.19.0.tgz#96b2709e57c9c4e09a6fd66a8fd979844f69f08a"
-  integrity sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==
-  dependencies:
-    bytes "3.1.0"
-    content-type "~1.0.4"
-    debug "2.6.9"
-    depd "~1.1.2"
-    http-errors "1.7.2"
-    iconv-lite "0.4.24"
-    on-finished "~2.3.0"
-    qs "6.7.0"
-    raw-body "2.4.0"
-    type-is "~1.6.17"
-
-body@^5.1.0:
-  version "5.1.0"
-  resolved "https://registry.yarnpkg.com/body/-/body-5.1.0.tgz#e4ba0ce410a46936323367609ecb4e6553125069"
-  integrity sha1-5LoM5BCkaTYyM2dgnstOZVMSUGk=
-  dependencies:
-    continuable-cache "^0.3.1"
-    error "^7.0.0"
-    raw-body "~1.1.0"
-    safe-json-parse "~1.0.1"
-
-brace-expansion@^1.0.0, brace-expansion@^1.1.7:
-  version "1.1.11"
-  resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"
-  integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==
-  dependencies:
-    balanced-match "^1.0.0"
-    concat-map "0.0.1"
-
-braces@^1.8.2:
-  version "1.8.5"
-  resolved "https://registry.yarnpkg.com/braces/-/braces-1.8.5.tgz#ba77962e12dff969d6b76711e914b737857bf6a7"
-  integrity sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=
-  dependencies:
-    expand-range "^1.8.1"
-    preserve "^0.2.0"
-    repeat-element "^1.1.2"
-
-braces@^2.3.1:
-  version "2.3.2"
-  resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729"
-  integrity sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==
-  dependencies:
-    arr-flatten "^1.1.0"
-    array-unique "^0.3.2"
-    extend-shallow "^2.0.1"
-    fill-range "^4.0.0"
-    isobject "^3.0.1"
-    repeat-element "^1.1.2"
-    snapdragon "^0.8.1"
-    snapdragon-node "^2.0.1"
-    split-string "^3.0.2"
-    to-regex "^3.0.1"
-
-breakable@~1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/breakable/-/breakable-1.0.0.tgz#784a797915a38ead27bad456b5572cb4bbaa78c1"
-  integrity sha1-eEp5eRWjjq0nutRWtVcstLuqeME=
-
-browser-stdout@1.3.1:
-  version "1.3.1"
-  resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60"
-  integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==
-
-browserify-aes@0.4.0:
-  version "0.4.0"
-  resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-0.4.0.tgz#067149b668df31c4b58533e02d01e806d8608e2c"
-  integrity sha1-BnFJtmjfMcS1hTPgLQHoBthgjiw=
-  dependencies:
-    inherits "^2.0.1"
-
-browserify-zlib@^0.1.4:
-  version "0.1.4"
-  resolved "https://registry.yarnpkg.com/browserify-zlib/-/browserify-zlib-0.1.4.tgz#bb35f8a519f600e0fa6b8485241c979d0141fb2d"
-  integrity sha1-uzX4pRn2AOD6a4SFJByXnQFB+y0=
-  dependencies:
-    pako "~0.2.0"
-
-buffer-from@^1.0.0:
-  version "1.1.1"
-  resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef"
-  integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==
-
-buffer@4.9.1, buffer@^4.9.0:
-  version "4.9.1"
-  resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.1.tgz#6d1bb601b07a4efced97094132093027c95bc298"
-  integrity sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg=
-  dependencies:
-    base64-js "^1.0.2"
-    ieee754 "^1.1.4"
-    isarray "^1.0.0"
-
-builtin-modules@^1.1.1:
-  version "1.1.1"
-  resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f"
-  integrity sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=
-
-builtin-status-codes@^3.0.0:
-  version "3.0.0"
-  resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8"
-  integrity sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=
-
-bytes@1:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/bytes/-/bytes-1.0.0.tgz#3569ede8ba34315fab99c3e92cb04c7220de1fa8"
-  integrity sha1-NWnt6Lo0MV+rmcPpLLBMciDeH6g=
-
-bytes@3.0.0:
-  version "3.0.0"
-  resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048"
-  integrity sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=
-
-bytes@3.1.0:
-  version "3.1.0"
-  resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.0.tgz#f6cf7933a360e0588fa9fde85651cdc7f805d1f6"
-  integrity sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==
-
-cache-base@^1.0.1:
-  version "1.0.1"
-  resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2"
-  integrity sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==
-  dependencies:
-    collection-visit "^1.0.0"
-    component-emitter "^1.2.1"
-    get-value "^2.0.6"
-    has-value "^1.0.0"
-    isobject "^3.0.1"
-    set-value "^2.0.0"
-    to-object-path "^0.3.0"
-    union-value "^1.0.0"
-    unset-value "^1.0.0"
-
-caller-path@^0.1.0:
-  version "0.1.0"
-  resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-0.1.0.tgz#94085ef63581ecd3daa92444a8fe94e82577751f"
-  integrity sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=
-  dependencies:
-    callsites "^0.2.0"
-
-callsites@^0.2.0:
-  version "0.2.0"
-  resolved "https://registry.yarnpkg.com/callsites/-/callsites-0.2.0.tgz#afab96262910a7f33c19a5775825c69f34e350ca"
-  integrity sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=
-
-camelcase-keys@^2.0.0:
-  version "2.1.0"
-  resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-2.1.0.tgz#308beeaffdf28119051efa1d932213c91b8f92e7"
-  integrity sha1-MIvur/3ygRkFHvodkyITyRuPkuc=
-  dependencies:
-    camelcase "^2.0.0"
-    map-obj "^1.0.0"
-
-camelcase@^1.0.2, camelcase@^1.2.1:
-  version "1.2.1"
-  resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-1.2.1.tgz#9bb5304d2e0b56698b2c758b08a3eaa9daa58a39"
-  integrity sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=
-
-camelcase@^2.0.0, camelcase@^2.0.1:
-  version "2.1.1"
-  resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-2.1.1.tgz#7c1d16d679a1bbe59ca02cacecfb011e201f5a1f"
-  integrity sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=
-
-camelcase@^5.0.0:
-  version "5.3.1"
-  resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320"
-  integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==
-
-caseless@~0.12.0:
-  version "0.12.0"
-  resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc"
-  integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=
-
-center-align@^0.1.1:
-  version "0.1.3"
-  resolved "https://registry.yarnpkg.com/center-align/-/center-align-0.1.3.tgz#aa0d32629b6ee972200411cbd4461c907bc2b7ad"
-  integrity sha1-qg0yYptu6XIgBBHL1EYckHvCt60=
-  dependencies:
-    align-text "^0.1.3"
-    lazy-cache "^1.0.3"
-
-chalk@^1.0.0, chalk@^1.1.1, chalk@^1.1.3:
-  version "1.1.3"
-  resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98"
-  integrity sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=
-  dependencies:
-    ansi-styles "^2.2.1"
-    escape-string-regexp "^1.0.2"
-    has-ansi "^2.0.0"
-    strip-ansi "^3.0.0"
-    supports-color "^2.0.0"
-
-chalk@^2.0.0, chalk@^2.1.0, chalk@^2.3.0, chalk@^2.4.2, chalk@~2.4.1:
-  version "2.4.2"
-  resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424"
-  integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==
-  dependencies:
-    ansi-styles "^3.2.1"
-    escape-string-regexp "^1.0.5"
-    supports-color "^5.3.0"
-
-chalk@~0.4.0:
-  version "0.4.0"
-  resolved "https://registry.yarnpkg.com/chalk/-/chalk-0.4.0.tgz#5199a3ddcd0c1efe23bc08c1b027b06176e0c64f"
-  integrity sha1-UZmj3c0MHv4jvAjBsCewYXbgxk8=
-  dependencies:
-    ansi-styles "~1.0.0"
-    has-color "~0.1.0"
-    strip-ansi "~0.1.0"
-
-chardet@^0.4.0:
-  version "0.4.2"
-  resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.4.2.tgz#b5473b33dc97c424e5d98dc87d55d4d8a29c8bf2"
-  integrity sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I=
-
-chokidar@^1.0.0:
-  version "1.7.0"
-  resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-1.7.0.tgz#798e689778151c8076b4b360e5edd28cda2bb468"
-  integrity sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=
-  dependencies:
-    anymatch "^1.3.0"
-    async-each "^1.0.0"
-    glob-parent "^2.0.0"
-    inherits "^2.0.1"
-    is-binary-path "^1.0.0"
-    is-glob "^2.0.0"
-    path-is-absolute "^1.0.0"
-    readdirp "^2.0.0"
-  optionalDependencies:
-    fsevents "^1.0.0"
-
-chokidar@~1.5.1:
-  version "1.5.2"
-  resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-1.5.2.tgz#293e728640cc93dd8277424334b3c6d4ad3a348a"
-  integrity sha1-KT5yhkDMk92Cd0JDNLPG1K06NIo=
-  dependencies:
-    anymatch "^1.3.0"
-    async-each "^1.0.0"
-    glob-parent "^2.0.0"
-    inherits "^2.0.1"
-    is-binary-path "^1.0.0"
-    is-glob "^2.0.0"
-    path-is-absolute "^1.0.0"
-    readdirp "^2.0.0"
-  optionalDependencies:
-    fsevents "^1.0.0"
-
-chownr@^1.1.1:
-  version "1.1.3"
-  resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.3.tgz#42d837d5239688d55f303003a508230fa6727142"
-  integrity sha512-i70fVHhmV3DtTl6nqvZOnIjbY0Pe4kAUjwHj8z0zAdgBtYrJyYwLKCCuRBQ5ppkyL0AkN7HKRnETdmdp1zqNXw==
-
-circular-json@^0.3.1:
-  version "0.3.3"
-  resolved "https://registry.yarnpkg.com/circular-json/-/circular-json-0.3.3.tgz#815c99ea84f6809529d2f45791bdf82711352d66"
-  integrity sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==
-
-cjson@0.3.0:
-  version "0.3.0"
-  resolved "https://registry.yarnpkg.com/cjson/-/cjson-0.3.0.tgz#e6439b90703d312ff6e2224097bea92ce3d02a14"
-  integrity sha1-5kObkHA9MS/24iJAl76pLOPQKhQ=
-  dependencies:
-    jsonlint "1.6.0"
-
-class-utils@^0.3.5:
-  version "0.3.6"
-  resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463"
-  integrity sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==
-  dependencies:
-    arr-union "^3.1.0"
-    define-property "^0.2.5"
-    isobject "^3.0.0"
-    static-extend "^0.1.1"
-
-cli-cursor@^2.1.0:
-  version "2.1.0"
-  resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5"
-  integrity sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=
-  dependencies:
-    restore-cursor "^2.0.0"
-
-cli-width@^2.0.0:
-  version "2.2.0"
-  resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.0.tgz#ff19ede8a9a5e579324147b0c11f0fbcbabed639"
-  integrity sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=
-
-cli@^1.0.1:
-  version "1.0.1"
-  resolved "https://registry.yarnpkg.com/cli/-/cli-1.0.1.tgz#22817534f24bfa4950c34d532d48ecbc621b8c14"
-  integrity sha1-IoF1NPJL+klQw01TLUjsvGIbjBQ=
-  dependencies:
-    exit "0.1.2"
-    glob "^7.1.1"
-
-cliui@^2.1.0:
-  version "2.1.0"
-  resolved "https://registry.yarnpkg.com/cliui/-/cliui-2.1.0.tgz#4b475760ff80264c762c3a1719032e91c7fea0d1"
-  integrity sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=
-  dependencies:
-    center-align "^0.1.1"
-    right-align "^0.1.1"
-    wordwrap "0.0.2"
-
-cliui@^3.0.3:
-  version "3.2.0"
-  resolved "https://registry.yarnpkg.com/cliui/-/cliui-3.2.0.tgz#120601537a916d29940f934da3b48d585a39213d"
-  integrity sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=
-  dependencies:
-    string-width "^1.0.1"
-    strip-ansi "^3.0.1"
-    wrap-ansi "^2.0.0"
-
-cliui@^4.0.0:
-  version "4.1.0"
-  resolved "https://registry.yarnpkg.com/cliui/-/cliui-4.1.0.tgz#348422dbe82d800b3022eef4f6ac10bf2e4d1b49"
-  integrity sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==
-  dependencies:
-    string-width "^2.1.1"
-    strip-ansi "^4.0.0"
-    wrap-ansi "^2.0.0"
-
-clone@^1.0.2:
-  version "1.0.4"
-  resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e"
-  integrity sha1-2jCcwmPfFZlMaIypAheco8fNfH4=
-
-co@^4.6.0:
-  version "4.6.0"
-  resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184"
-  integrity sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=
-
-code-point-at@^1.0.0:
-  version "1.1.0"
-  resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77"
-  integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=
-
-coffee-script@>=1.2.0:
-  version "1.12.7"
-  resolved "https://registry.yarnpkg.com/coffee-script/-/coffee-script-1.12.7.tgz#c05dae0cb79591d05b3070a8433a98c9a89ccc53"
-  integrity sha512-fLeEhqwymYat/MpTPUjSKHVYYl0ec2mOyALEMLmzr5i1isuG+6jfI2j2d5oBO3VIzgUXgBVIcOT9uH1TFxBckw==
-
-coffeescript@~1.10.0:
-  version "1.10.0"
-  resolved "https://registry.yarnpkg.com/coffeescript/-/coffeescript-1.10.0.tgz#e7aa8301917ef621b35d8a39f348dcdd1db7e33e"
-  integrity sha1-56qDAZF+9iGzXYo580jc3R234z4=
-
-collection-visit@^1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0"
-  integrity sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=
-  dependencies:
-    map-visit "^1.0.0"
-    object-visit "^1.0.0"
-
-color-convert@^1.9.0:
-  version "1.9.3"
-  resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8"
-  integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==
-  dependencies:
-    color-name "1.1.3"
-
-color-name@1.1.3:
-  version "1.1.3"
-  resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25"
-  integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=
-
-colors@0.5.x:
-  version "0.5.1"
-  resolved "https://registry.yarnpkg.com/colors/-/colors-0.5.1.tgz#7d0023eaeb154e8ee9fce75dcb923d0ed1667774"
-  integrity sha1-fQAj6usVTo7p/Oddy5I9DtFmd3Q=
-
-colors@~1.1.2:
-  version "1.1.2"
-  resolved "https://registry.yarnpkg.com/colors/-/colors-1.1.2.tgz#168a4701756b6a7f51a12ce0c97bfa28c084ed63"
-  integrity sha1-FopHAXVran9RoSzgyXv6KMCE7WM=
-
-combined-stream@^1.0.6, combined-stream@~1.0.6:
-  version "1.0.8"
-  resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f"
-  integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==
-  dependencies:
-    delayed-stream "~1.0.0"
-
-commander@2.15.1:
-  version "2.15.1"
-  resolved "https://registry.yarnpkg.com/commander/-/commander-2.15.1.tgz#df46e867d0fc2aec66a34662b406a9ccafff5b0f"
-  integrity sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==
-
-commander@^2.12.1, commander@^2.5.0, commander@~2.20.3:
-  version "2.20.3"
-  resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33"
-  integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==
-
-commoner@~0.10.3:
-  version "0.10.8"
-  resolved "https://registry.yarnpkg.com/commoner/-/commoner-0.10.8.tgz#34fc3672cd24393e8bb47e70caa0293811f4f2c5"
-  integrity sha1-NPw2cs0kOT6LtH5wyqApOBH08sU=
-  dependencies:
-    commander "^2.5.0"
-    detective "^4.3.1"
-    glob "^5.0.15"
-    graceful-fs "^4.1.2"
-    iconv-lite "^0.4.5"
-    mkdirp "^0.5.0"
-    private "^0.1.6"
-    q "^1.1.2"
-    recast "^0.11.17"
-
-component-emitter@^1.2.1:
-  version "1.3.0"
-  resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0"
-  integrity sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==
-
-compressible@~2.0.16:
-  version "2.0.17"
-  resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.17.tgz#6e8c108a16ad58384a977f3a482ca20bff2f38c1"
-  integrity sha512-BGHeLCK1GV7j1bSmQQAi26X+GgWcTjLr/0tzSvMCl3LH1w1IJ4PFSPoV5316b30cneTziC+B1a+3OjoSUcQYmw==
-  dependencies:
-    mime-db ">= 1.40.0 < 2"
-
-compression@^1.5.2:
-  version "1.7.4"
-  resolved "https://registry.yarnpkg.com/compression/-/compression-1.7.4.tgz#95523eff170ca57c29a0ca41e6fe131f41e5bb8f"
-  integrity sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==
-  dependencies:
-    accepts "~1.3.5"
-    bytes "3.0.0"
-    compressible "~2.0.16"
-    debug "2.6.9"
-    on-headers "~1.0.2"
-    safe-buffer "5.1.2"
-    vary "~1.1.2"
-
-concat-map@0.0.1:
-  version "0.0.1"
-  resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
-  integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=
-
-concat-stream@^1.4.1, concat-stream@^1.6.0:
-  version "1.6.2"
-  resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34"
-  integrity sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==
-  dependencies:
-    buffer-from "^1.0.0"
-    inherits "^2.0.3"
-    readable-stream "^2.2.2"
-    typedarray "^0.0.6"
-
-connect-history-api-fallback@^1.3.0:
-  version "1.6.0"
-  resolved "https://registry.yarnpkg.com/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz#8b32089359308d111115d81cad3fceab888f97bc"
-  integrity sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg==
-
-connect-livereload@^0.5.0:
-  version "0.5.4"
-  resolved "https://registry.yarnpkg.com/connect-livereload/-/connect-livereload-0.5.4.tgz#80157d1371c9f37cc14039ab1895970d119dc3bc"
-  integrity sha1-gBV9E3HJ83zBQDmrGJWXDRGdw7w=
-
-connect@^3.4.0:
-  version "3.7.0"
-  resolved "https://registry.yarnpkg.com/connect/-/connect-3.7.0.tgz#5d49348910caa5e07a01800b030d0c35f20484f8"
-  integrity sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ==
-  dependencies:
-    debug "2.6.9"
-    finalhandler "1.1.2"
-    parseurl "~1.3.3"
-    utils-merge "1.0.1"
-
-console-browserify@^1.1.0:
-  version "1.1.0"
-  resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.1.0.tgz#f0241c45730a9fc6323b206dbf38edc741d0bb10"
-  integrity sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA=
-  dependencies:
-    date-now "^0.1.4"
-
-console-control-strings@^1.0.0, console-control-strings@~1.1.0:
-  version "1.1.0"
-  resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e"
-  integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=
-
-constants-browserify@^1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75"
-  integrity sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=
-
-content-disposition@0.5.3:
-  version "0.5.3"
-  resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.3.tgz#e130caf7e7279087c5616c2007d0485698984fbd"
-  integrity sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==
-  dependencies:
-    safe-buffer "5.1.2"
-
-content-type@~1.0.4:
-  version "1.0.4"
-  resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b"
-  integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==
-
-continuable-cache@^0.3.1:
-  version "0.3.1"
-  resolved "https://registry.yarnpkg.com/continuable-cache/-/continuable-cache-0.3.1.tgz#bd727a7faed77e71ff3985ac93351a912733ad0f"
-  integrity sha1-vXJ6f67XfnH/OYWskzUakSczrQ8=
-
-convert-source-map@^1.1.0, convert-source-map@^1.1.1:
-  version "1.6.0"
-  resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.6.0.tgz#51b537a8c43e0f04dec1993bffcdd504e758ac20"
-  integrity sha512-eFu7XigvxdZ1ETfbgPBohgyQ/Z++C0eEhTor0qRwBw9unw+L0/6V8wkSuGgzdThkiS5lSpdptOQPD8Ak40a+7A==
-  dependencies:
-    safe-buffer "~5.1.1"
-
-cookie-signature@1.0.6:
-  version "1.0.6"
-  resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c"
-  integrity sha1-4wOogrNCzD7oylE6eZmXNNqzriw=
-
-cookie@0.4.0:
-  version "0.4.0"
-  resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.0.tgz#beb437e7022b3b6d49019d088665303ebe9c14ba"
-  integrity sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==
-
-copy-descriptor@^0.1.0:
-  version "0.1.1"
-  resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d"
-  integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=
-
-core-js@^1.0.0:
-  version "1.2.7"
-  resolved "https://registry.yarnpkg.com/core-js/-/core-js-1.2.7.tgz#652294c14651db28fa93bd2d5ff2983a4f08c636"
-  integrity sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY=
-
-core-util-is@1.0.2, core-util-is@~1.0.0:
-  version "1.0.2"
-  resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
-  integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=
-
-cross-spawn@^5.1.0:
-  version "5.1.0"
-  resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449"
-  integrity sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=
-  dependencies:
-    lru-cache "^4.0.1"
-    shebang-command "^1.2.0"
-    which "^1.2.9"
-
-cross-spawn@^6.0.0:
-  version "6.0.5"
-  resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4"
-  integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==
-  dependencies:
-    nice-try "^1.0.4"
-    path-key "^2.0.1"
-    semver "^5.5.0"
-    shebang-command "^1.2.0"
-    which "^1.2.9"
-
-crypto-browserify@3.3.0:
-  version "3.3.0"
-  resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.3.0.tgz#b9fc75bb4a0ed61dcf1cd5dae96eb30c9c3e506c"
-  integrity sha1-ufx1u0oO1h3PHNXa6W6zDJw+UGw=
-  dependencies:
-    browserify-aes "0.4.0"
-    pbkdf2-compat "2.0.1"
-    ripemd160 "0.2.0"
-    sha.js "2.2.6"
-
-currently-unhandled@^0.4.1:
-  version "0.4.1"
-  resolved "https://registry.yarnpkg.com/currently-unhandled/-/currently-unhandled-0.4.1.tgz#988df33feab191ef799a61369dd76c17adf957ea"
-  integrity sha1-mI3zP+qxke95mmE2nddsF635V+o=
-  dependencies:
-    array-find-index "^1.0.1"
-
-dashdash@^1.12.0:
-  version "1.14.1"
-  resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0"
-  integrity sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=
-  dependencies:
-    assert-plus "^1.0.0"
-
-date-now@^0.1.4:
-  version "0.1.4"
-  resolved "https://registry.yarnpkg.com/date-now/-/date-now-0.1.4.tgz#eaf439fd4d4848ad74e5cc7dbef200672b9e345b"
-  integrity sha1-6vQ5/U1ISK105cx9vvIAZyueNFs=
-
-dateformat@~1.0.12:
-  version "1.0.12"
-  resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-1.0.12.tgz#9f124b67594c937ff706932e4a642cca8dbbfee9"
-  integrity sha1-nxJLZ1lMk3/3BpMuSmQsyo27/uk=
-  dependencies:
-    get-stdin "^4.0.1"
-    meow "^3.3.0"
-
-debug@2.6.9, debug@^2.1.1, debug@^2.2.0, debug@^2.3.3:
-  version "2.6.9"
-  resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
-  integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==
-  dependencies:
-    ms "2.0.0"
-
-debug@3.1.0:
-  version "3.1.0"
-  resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261"
-  integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==
-  dependencies:
-    ms "2.0.0"
-
-debug@^3.0.0, debug@^3.1.0, debug@^3.2.5, debug@^3.2.6:
-  version "3.2.6"
-  resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b"
-  integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==
-  dependencies:
-    ms "^2.1.1"
-
-decamelize@^1.0.0, decamelize@^1.1.1, decamelize@^1.1.2, decamelize@^1.2.0:
-  version "1.2.0"
-  resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290"
-  integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=
-
-decode-uri-component@^0.2.0:
-  version "0.2.0"
-  resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545"
-  integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=
-
-deep-extend@^0.6.0:
-  version "0.6.0"
-  resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac"
-  integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==
-
-deep-is@~0.1.2, deep-is@~0.1.3:
-  version "0.1.3"
-  resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34"
-  integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=
-
-define-property@^0.2.5:
-  version "0.2.5"
-  resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116"
-  integrity sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=
-  dependencies:
-    is-descriptor "^0.1.0"
-
-define-property@^1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/define-property/-/define-property-1.0.0.tgz#769ebaaf3f4a63aad3af9e8d304c9bbe79bfb0e6"
-  integrity sha1-dp66rz9KY6rTr56NMEybvnm/sOY=
-  dependencies:
-    is-descriptor "^1.0.0"
-
-define-property@^2.0.2:
-  version "2.0.2"
-  resolved "https://registry.yarnpkg.com/define-property/-/define-property-2.0.2.tgz#d459689e8d654ba77e02a817f8710d702cb16e9d"
-  integrity sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==
-  dependencies:
-    is-descriptor "^1.0.2"
-    isobject "^3.0.1"
-
-defined@^1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/defined/-/defined-1.0.0.tgz#c98d9bcef75674188e110969151199e39b1fa693"
-  integrity sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=
-
-definitelytyped-header-parser@^1.0.1, definitelytyped-header-parser@^1.2.0:
-  version "1.2.0"
-  resolved "https://registry.yarnpkg.com/definitelytyped-header-parser/-/definitelytyped-header-parser-1.2.0.tgz#f21374b8a18fabcd3ba4b008a0bcbc9db2b7b4c4"
-  integrity sha512-xpg8uu/2YD/reaVsZV4oJ4g7UDYFqQGWvT1W9Tsj6q4VtWBSaig38Qgah0ZMnQGF9kAsAim08EXDO1nSi0+Nog==
-  dependencies:
-    "@types/parsimmon" "^1.3.0"
-    parsimmon "^1.2.0"
-
-defs@~1.1.0:
-  version "1.1.1"
-  resolved "https://registry.yarnpkg.com/defs/-/defs-1.1.1.tgz#b22609f2c7a11ba7a3db116805c139b1caffa9d2"
-  integrity sha1-siYJ8sehG6ej2xFoBcE5scr/qdI=
-  dependencies:
-    alter "~0.2.0"
-    ast-traverse "~0.1.1"
-    breakable "~1.0.0"
-    esprima-fb "~15001.1001.0-dev-harmony-fb"
-    simple-fmt "~0.1.0"
-    simple-is "~0.2.0"
-    stringmap "~0.2.2"
-    stringset "~0.2.1"
-    tryor "~0.1.2"
-    yargs "~3.27.0"
-
-delayed-stream@~1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
-  integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk=
-
-delegates@^1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a"
-  integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=
-
-depd@~1.1.2:
-  version "1.1.2"
-  resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9"
-  integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=
-
-destroy@~1.0.4:
-  version "1.0.4"
-  resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80"
-  integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=
-
-detect-file@^1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/detect-file/-/detect-file-1.0.0.tgz#f0d66d03672a825cb1b73bdb3fe62310c8e552b7"
-  integrity sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=
-
-detect-indent@^3.0.0:
-  version "3.0.1"
-  resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-3.0.1.tgz#9dc5e5ddbceef8325764b9451b02bc6d54084f75"
-  integrity sha1-ncXl3bzu+DJXZLlFGwK8bVQIT3U=
-  dependencies:
-    get-stdin "^4.0.1"
-    minimist "^1.1.0"
-    repeating "^1.1.0"
-
-detect-libc@^1.0.2:
-  version "1.0.3"
-  resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b"
-  integrity sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=
-
-detective@^4.3.1:
-  version "4.7.1"
-  resolved "https://registry.yarnpkg.com/detective/-/detective-4.7.1.tgz#0eca7314338442febb6d65da54c10bb1c82b246e"
-  integrity sha512-H6PmeeUcZloWtdt4DAkFyzFL94arpHr3NOwwmVILFiy+9Qd4JTxxXrzfyGk/lmct2qVGBwTSwSXagqu2BxmWig==
-  dependencies:
-    acorn "^5.2.1"
-    defined "^1.0.0"
-
-diff@3.5.0:
-  version "3.5.0"
-  resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12"
-  integrity sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==
-
-diff@^4.0.1:
-  version "4.0.1"
-  resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.1.tgz#0c667cb467ebbb5cea7f14f135cc2dba7780a8ff"
-  integrity sha512-s2+XdvhPCOF01LRQBC8hf4vhbVmI2CGS5aZnxLJlT5FtdhPCDFq80q++zK2KlrVorVDdL5BOGZ/VfLrVtYNF+Q==
-
-doctrine@^2.1.0:
-  version "2.1.0"
-  resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d"
-  integrity sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==
-  dependencies:
-    esutils "^2.0.2"
-
-domain-browser@^1.1.1:
-  version "1.2.0"
-  resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda"
-  integrity sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==
-
-download-file-sync@^1.0.4:
-  version "1.0.4"
-  resolved "https://registry.yarnpkg.com/download-file-sync/-/download-file-sync-1.0.4.tgz#d3e3c543f836f41039455b9034c72e355b036019"
-  integrity sha1-0+PFQ/g29BA5RVuQNMcuNVsDYBk=
-
-dts-critic@^1.0.4:
-  version "1.2.0"
-  resolved "https://registry.yarnpkg.com/dts-critic/-/dts-critic-1.2.0.tgz#fc358cad7461180ad426438ab88b249fedebd5c0"
-  integrity sha512-z6VI1Sz7xxy0BgN6YsWuG9hbRIfph3U9hwrfNHLnLzsq865VYyjo5xKKUgXPuqMgJ04BUF1LGYQJ+kWyWwvUvQ==
-  dependencies:
-    definitelytyped-header-parser "^1.2.0"
-    download-file-sync "^1.0.4"
-    yargs "^12.0.5"
-
-dtslint@^0.5.5:
-  version "0.5.9"
-  resolved "https://registry.yarnpkg.com/dtslint/-/dtslint-0.5.9.tgz#462299c97f675a224758a3aafa2a519737584f9c"
-  integrity sha512-/RU8h05QMS1DLZsMsDpJ6rvtEXrXQ0KRGT0q7IkqvDbCDa3fJRGLqGrVFLLaUTCl/4p2+sgsOEBCPsFqV5BRXA==
-  dependencies:
-    definitelytyped-header-parser "^1.0.1"
-    dts-critic "^1.0.4"
-    fs-extra "^6.0.1"
-    request "^2.88.0"
-    strip-json-comments "^2.0.1"
-    tslint "^5.14.0"
-    typescript next
-
-dustjs-linkedin@^2.0.2:
-  version "2.7.5"
-  resolved "https://registry.yarnpkg.com/dustjs-linkedin/-/dustjs-linkedin-2.7.5.tgz#618f063f72c19b78c8055ac2301c75b7b6bbdccc"
-  integrity sha1-YY8GP3LBm3jIBVrCMBx1t7a73Mw=
-  dependencies:
-    chokidar "~1.5.1"
-    cli "^1.0.1"
-
-ebnf-parser@0.1.10:
-  version "0.1.10"
-  resolved "https://registry.yarnpkg.com/ebnf-parser/-/ebnf-parser-0.1.10.tgz#cd1f6ba477c5638c40c97ed9b572db5bab5d8331"
-  integrity sha1-zR9rpHfFY4xAyX7ZtXLbW6tdgzE=
-
-ecc-jsbn@~0.1.1:
-  version "0.1.2"
-  resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9"
-  integrity sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=
-  dependencies:
-    jsbn "~0.1.0"
-    safer-buffer "^2.1.0"
-
-eco@~1.1.0-rc-3:
-  version "1.1.0-rc-3"
-  resolved "https://registry.yarnpkg.com/eco/-/eco-1.1.0-rc-3.tgz#742a32c4615af705ab3e9a46b6ce5c16dbc57262"
-  integrity sha1-dCoyxGFa9wWrPppGts5cFtvFcmI=
-  dependencies:
-    coffee-script ">=1.2.0"
-    strscan ">=1.0.1"
-
-ee-first@1.1.1:
-  version "1.1.1"
-  resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d"
-  integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=
-
-emojis-list@^2.0.0:
-  version "2.1.0"
-  resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-2.1.0.tgz#4daa4d9db00f9819880c79fa457ae5b09a1fd389"
-  integrity sha1-TapNnbAPmBmIDHn6RXrlsJof04k=
-
-encodeurl@~1.0.2:
-  version "1.0.2"
-  resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59"
-  integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=
-
-end-of-stream@^1.1.0:
-  version "1.4.4"
-  resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0"
-  integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==
-  dependencies:
-    once "^1.4.0"
-
-enhanced-resolve@~0.9.0:
-  version "0.9.1"
-  resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-0.9.1.tgz#4d6e689b3725f86090927ccc86cd9f1635b89e2e"
-  integrity sha1-TW5omzcl+GCQknzMhs2fFjW4ni4=
-  dependencies:
-    graceful-fs "^4.1.2"
-    memory-fs "^0.2.0"
-    tapable "^0.1.8"
-
-errno@^0.1.3:
-  version "0.1.7"
-  resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.7.tgz#4684d71779ad39af177e3f007996f7c67c852618"
-  integrity sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==
-  dependencies:
-    prr "~1.0.1"
-
-error-ex@^1.2.0:
-  version "1.3.2"
-  resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf"
-  integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==
-  dependencies:
-    is-arrayish "^0.2.1"
-
-error@^7.0.0:
-  version "7.2.0"
-  resolved "https://registry.yarnpkg.com/error/-/error-7.2.0.tgz#80c989885635b41df9309d145834a4f125ae2245"
-  integrity sha512-M6t3j3Vt3uDicrViMP5fLq2AeADNrCVFD8Oj4Qt2MHsX0mPYG7D5XdnEfSdRpaHQzjAJ19wu+I1mw9rQYMTAPg==
-  dependencies:
-    string-template "~0.2.1"
-
-es6-promise@^4.0.3:
-  version "4.2.8"
-  resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.8.tgz#4eb21594c972bc40553d276e510539143db53e0a"
-  integrity sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==
-
-es6-promisify@^5.0.0:
-  version "5.0.0"
-  resolved "https://registry.yarnpkg.com/es6-promisify/-/es6-promisify-5.0.0.tgz#5109d62f3e56ea967c4b63505aef08291c8a5203"
-  integrity sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=
-  dependencies:
-    es6-promise "^4.0.3"
-
-escape-html@~1.0.3:
-  version "1.0.3"
-  resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988"
-  integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=
-
-escape-string-regexp@1.0.5, escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5:
-  version "1.0.5"
-  resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
-  integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=
-
-escodegen@1.3.x:
-  version "1.3.3"
-  resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.3.3.tgz#f024016f5a88e046fd12005055e939802e6c5f23"
-  integrity sha1-8CQBb1qI4Eb9EgBQVek5gC5sXyM=
-  dependencies:
-    esprima "~1.1.1"
-    estraverse "~1.5.0"
-    esutils "~1.0.0"
-  optionalDependencies:
-    source-map "~0.1.33"
-
-escodegen@1.7.x:
-  version "1.7.1"
-  resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.7.1.tgz#30ecfcf66ca98dc67cd2fd162abeb6eafa8ce6fc"
-  integrity sha1-MOz89mypjcZ80v0WKr626vqM5vw=
-  dependencies:
-    esprima "^1.2.2"
-    estraverse "^1.9.1"
-    esutils "^2.0.2"
-    optionator "^0.5.0"
-  optionalDependencies:
-    source-map "~0.2.0"
-
-eslint-scope@^3.7.1:
-  version "3.7.3"
-  resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-3.7.3.tgz#bb507200d3d17f60247636160b4826284b108535"
-  integrity sha512-W+B0SvF4gamyCTmUc+uITPY0989iXVfKvhwtmJocTaYoc/3khEHmEmvfY/Gn9HA9VV75jrQECsHizkNw1b68FA==
-  dependencies:
-    esrecurse "^4.1.0"
-    estraverse "^4.1.1"
-
-eslint-visitor-keys@^1.0.0:
-  version "1.1.0"
-  resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz#e2a82cea84ff246ad6fb57f9bde5b46621459ec2"
-  integrity sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A==
-
-eslint@^4.0.0:
-  version "4.19.1"
-  resolved "https://registry.yarnpkg.com/eslint/-/eslint-4.19.1.tgz#32d1d653e1d90408854bfb296f076ec7e186a300"
-  integrity sha512-bT3/1x1EbZB7phzYu7vCr1v3ONuzDtX8WjuM9c0iYxe+cq+pwcKEoQjl7zd3RpC6YOLgnSy3cTN58M2jcoPDIQ==
-  dependencies:
-    ajv "^5.3.0"
-    babel-code-frame "^6.22.0"
-    chalk "^2.1.0"
-    concat-stream "^1.6.0"
-    cross-spawn "^5.1.0"
-    debug "^3.1.0"
-    doctrine "^2.1.0"
-    eslint-scope "^3.7.1"
-    eslint-visitor-keys "^1.0.0"
-    espree "^3.5.4"
-    esquery "^1.0.0"
-    esutils "^2.0.2"
-    file-entry-cache "^2.0.0"
-    functional-red-black-tree "^1.0.1"
-    glob "^7.1.2"
-    globals "^11.0.1"
-    ignore "^3.3.3"
-    imurmurhash "^0.1.4"
-    inquirer "^3.0.6"
-    is-resolvable "^1.0.0"
-    js-yaml "^3.9.1"
-    json-stable-stringify-without-jsonify "^1.0.1"
-    levn "^0.3.0"
-    lodash "^4.17.4"
-    minimatch "^3.0.2"
-    mkdirp "^0.5.1"
-    natural-compare "^1.4.0"
-    optionator "^0.8.2"
-    path-is-inside "^1.0.2"
-    pluralize "^7.0.0"
-    progress "^2.0.0"
-    regexpp "^1.0.1"
-    require-uncached "^1.0.3"
-    semver "^5.3.0"
-    strip-ansi "^4.0.0"
-    strip-json-comments "~2.0.1"
-    table "4.0.2"
-    text-table "~0.2.0"
-
-espree@^3.5.4:
-  version "3.5.4"
-  resolved "https://registry.yarnpkg.com/espree/-/espree-3.5.4.tgz#b0f447187c8a8bed944b815a660bddf5deb5d1a7"
-  integrity sha512-yAcIQxtmMiB/jL32dzEp2enBeidsB7xWPLNiw3IIkpVds1P+h7qF9YwJq1yUNzp2OKXgAprs4F61ih66UsoD1A==
-  dependencies:
-    acorn "^5.5.0"
-    acorn-jsx "^3.0.0"
-
-esprima-fb@~15001.1001.0-dev-harmony-fb:
-  version "15001.1001.0-dev-harmony-fb"
-  resolved "https://registry.yarnpkg.com/esprima-fb/-/esprima-fb-15001.1001.0-dev-harmony-fb.tgz#43beb57ec26e8cf237d3dd8b33e42533577f2659"
-  integrity sha1-Q761fsJujPI3092LM+QlM1d/Jlk=
-
-esprima@1.1.x, esprima@~1.1.1:
-  version "1.1.1"
-  resolved "https://registry.yarnpkg.com/esprima/-/esprima-1.1.1.tgz#5b6f1547f4d102e670e140c509be6771d6aeb549"
-  integrity sha1-W28VR/TRAuZw4UDFCb5ncdautUk=
-
-esprima@2.5.x:
-  version "2.5.0"
-  resolved "https://registry.yarnpkg.com/esprima/-/esprima-2.5.0.tgz#f387a46fd344c1b1a39baf8c20bfb43b6d0058cc"
-  integrity sha1-84ekb9NEwbGjm6+MIL+0O20AWMw=
-
-esprima@^1.2.2:
-  version "1.2.5"
-  resolved "https://registry.yarnpkg.com/esprima/-/esprima-1.2.5.tgz#0993502feaf668138325756f30f9a51feeec11e9"
-  integrity sha1-CZNQL+r2aBODJXVvMPmlH+7sEek=
-
-esprima@^2.6.0:
-  version "2.7.3"
-  resolved "https://registry.yarnpkg.com/esprima/-/esprima-2.7.3.tgz#96e3b70d5779f6ad49cd032673d1c312767ba581"
-  integrity sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=
-
-esprima@^4.0.0:
-  version "4.0.1"
-  resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71"
-  integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==
-
-esprima@~3.1.0:
-  version "3.1.3"
-  resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.1.3.tgz#fdca51cee6133895e3c88d535ce49dbff62a4633"
-  integrity sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=
-
-esquery@^1.0.0:
-  version "1.0.1"
-  resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.0.1.tgz#406c51658b1f5991a5f9b62b1dc25b00e3e5c708"
-  integrity sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==
-  dependencies:
-    estraverse "^4.0.0"
-
-esrecurse@^4.1.0:
-  version "4.2.1"
-  resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.2.1.tgz#007a3b9fdbc2b3bb87e4879ea19c92fdbd3942cf"
-  integrity sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==
-  dependencies:
-    estraverse "^4.1.0"
-
-estraverse@^1.9.1:
-  version "1.9.3"
-  resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-1.9.3.tgz#af67f2dc922582415950926091a4005d29c9bb44"
-  integrity sha1-r2fy3JIlgkFZUJJgkaQAXSnJu0Q=
-
-estraverse@^4.0.0, estraverse@^4.1.0, estraverse@^4.1.1:
-  version "4.3.0"
-  resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d"
-  integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==
-
-estraverse@~1.5.0:
-  version "1.5.1"
-  resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-1.5.1.tgz#867a3e8e58a9f84618afb6c2ddbcd916b7cbaf71"
-  integrity sha1-hno+jlip+EYYr7bC3bzZFrfLr3E=
-
-esutils@^2.0.0, esutils@^2.0.2:
-  version "2.0.3"
-  resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64"
-  integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==
-
-esutils@~1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/esutils/-/esutils-1.0.0.tgz#8151d358e20c8acc7fb745e7472c0025fe496570"
-  integrity sha1-gVHTWOIMisx/t0XnRywAJf5JZXA=
-
-etag@~1.8.1:
-  version "1.8.1"
-  resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887"
-  integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=
-
-eventemitter2@~0.4.13:
-  version "0.4.14"
-  resolved "https://registry.yarnpkg.com/eventemitter2/-/eventemitter2-0.4.14.tgz#8f61b75cde012b2e9eb284d4545583b5643b61ab"
-  integrity sha1-j2G3XN4BKy6esoTUVFWDtWQ7Yas=
-
-eventemitter3@^4.0.0:
-  version "4.0.0"
-  resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.0.tgz#d65176163887ee59f386d64c82610b696a4a74eb"
-  integrity sha512-qerSRB0p+UDEssxTtm6EDKcE7W4OaoisfIMl4CngyEhjpYglocpNg6UEqCvemdGhosAsg4sO2dXJOdyBifPGCg==
-
-events@1.1.1, events@^1.0.0:
-  version "1.1.1"
-  resolved "https://registry.yarnpkg.com/events/-/events-1.1.1.tgz#9ebdb7635ad099c70dcc4c2a1f5004288e8bd924"
-  integrity sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ=
-
-eventsource@^1.0.7:
-  version "1.0.7"
-  resolved "https://registry.yarnpkg.com/eventsource/-/eventsource-1.0.7.tgz#8fbc72c93fcd34088090bc0a4e64f4b5cee6d8d0"
-  integrity sha512-4Ln17+vVT0k8aWq+t/bF5arcS3EpT9gYtW66EPacdj/mAFevznsnyoHLPy2BA8gbIQeIHoPsvwmfBftfcG//BQ==
-  dependencies:
-    original "^1.0.0"
-
-execa@^1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/execa/-/execa-1.0.0.tgz#c6236a5bb4df6d6f15e88e7f017798216749ddd8"
-  integrity sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==
-  dependencies:
-    cross-spawn "^6.0.0"
-    get-stream "^4.0.0"
-    is-stream "^1.1.0"
-    npm-run-path "^2.0.0"
-    p-finally "^1.0.0"
-    signal-exit "^3.0.0"
-    strip-eof "^1.0.0"
-
-exit@0.1.2, exit@~0.1.1:
-  version "0.1.2"
-  resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c"
-  integrity sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=
-
-expand-brackets@^0.1.4:
-  version "0.1.5"
-  resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-0.1.5.tgz#df07284e342a807cd733ac5af72411e581d1177b"
-  integrity sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=
-  dependencies:
-    is-posix-bracket "^0.1.0"
-
-expand-brackets@^2.1.4:
-  version "2.1.4"
-  resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622"
-  integrity sha1-t3c14xXOMPa27/D4OwQVGiJEliI=
-  dependencies:
-    debug "^2.3.3"
-    define-property "^0.2.5"
-    extend-shallow "^2.0.1"
-    posix-character-classes "^0.1.0"
-    regex-not "^1.0.0"
-    snapdragon "^0.8.1"
-    to-regex "^3.0.1"
-
-expand-range@^1.8.1:
-  version "1.8.2"
-  resolved "https://registry.yarnpkg.com/expand-range/-/expand-range-1.8.2.tgz#a299effd335fe2721ebae8e257ec79644fc85337"
-  integrity sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=
-  dependencies:
-    fill-range "^2.1.0"
-
-expand-tilde@^2.0.0, expand-tilde@^2.0.2:
-  version "2.0.2"
-  resolved "https://registry.yarnpkg.com/expand-tilde/-/expand-tilde-2.0.2.tgz#97e801aa052df02454de46b02bf621642cdc8502"
-  integrity sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=
-  dependencies:
-    homedir-polyfill "^1.0.1"
-
-express@^4.13.3:
-  version "4.17.1"
-  resolved "https://registry.yarnpkg.com/express/-/express-4.17.1.tgz#4491fc38605cf51f8629d39c2b5d026f98a4c134"
-  integrity sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==
-  dependencies:
-    accepts "~1.3.7"
-    array-flatten "1.1.1"
-    body-parser "1.19.0"
-    content-disposition "0.5.3"
-    content-type "~1.0.4"
-    cookie "0.4.0"
-    cookie-signature "1.0.6"
-    debug "2.6.9"
-    depd "~1.1.2"
-    encodeurl "~1.0.2"
-    escape-html "~1.0.3"
-    etag "~1.8.1"
-    finalhandler "~1.1.2"
-    fresh "0.5.2"
-    merge-descriptors "1.0.1"
-    methods "~1.1.2"
-    on-finished "~2.3.0"
-    parseurl "~1.3.3"
-    path-to-regexp "0.1.7"
-    proxy-addr "~2.0.5"
-    qs "6.7.0"
-    range-parser "~1.2.1"
-    safe-buffer "5.1.2"
-    send "0.17.1"
-    serve-static "1.14.1"
-    setprototypeof "1.1.1"
-    statuses "~1.5.0"
-    type-is "~1.6.18"
-    utils-merge "1.0.1"
-    vary "~1.1.2"
-
-extend-shallow@^2.0.1:
-  version "2.0.1"
-  resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f"
-  integrity sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=
-  dependencies:
-    is-extendable "^0.1.0"
-
-extend-shallow@^3.0.0, extend-shallow@^3.0.2:
-  version "3.0.2"
-  resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-3.0.2.tgz#26a71aaf073b39fb2127172746131c2704028db8"
-  integrity sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=
-  dependencies:
-    assign-symbols "^1.0.0"
-    is-extendable "^1.0.1"
-
-extend@^3.0.0, extend@~3.0.2:
-  version "3.0.2"
-  resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa"
-  integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==
-
-external-editor@^2.0.4:
-  version "2.2.0"
-  resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-2.2.0.tgz#045511cfd8d133f3846673d1047c154e214ad3d5"
-  integrity sha512-bSn6gvGxKt+b7+6TKEv1ZycHleA7aHhRHyAqJyp5pbUFuYYNIzpZnQDk7AsYckyWdEnTeAnay0aCy2aV6iTk9A==
-  dependencies:
-    chardet "^0.4.0"
-    iconv-lite "^0.4.17"
-    tmp "^0.0.33"
-
-extglob@^0.3.1:
-  version "0.3.2"
-  resolved "https://registry.yarnpkg.com/extglob/-/extglob-0.3.2.tgz#2e18ff3d2f49ab2765cec9023f011daa8d8349a1"
-  integrity sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=
-  dependencies:
-    is-extglob "^1.0.0"
-
-extglob@^2.0.4:
-  version "2.0.4"
-  resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543"
-  integrity sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==
-  dependencies:
-    array-unique "^0.3.2"
-    define-property "^1.0.0"
-    expand-brackets "^2.1.4"
-    extend-shallow "^2.0.1"
-    fragment-cache "^0.2.1"
-    regex-not "^1.0.0"
-    snapdragon "^0.8.1"
-    to-regex "^3.0.1"
-
-extsprintf@1.3.0:
-  version "1.3.0"
-  resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05"
-  integrity sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=
-
-extsprintf@^1.2.0:
-  version "1.4.0"
-  resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f"
-  integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8=
-
-fast-deep-equal@^1.0.0:
-  version "1.1.0"
-  resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz#c053477817c86b51daa853c81e059b733d023614"
-  integrity sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=
-
-fast-deep-equal@^2.0.1:
-  version "2.0.1"
-  resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz#7b05218ddf9667bf7f370bf7fdb2cb15fdd0aa49"
-  integrity sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=
-
-fast-json-stable-stringify@^2.0.0:
-  version "2.0.0"
-  resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2"
-  integrity sha1-1RQsDK7msRifh9OnYREGT4bIu/I=
-
-fast-levenshtein@~1.0.0:
-  version "1.0.7"
-  resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-1.0.7.tgz#0178dcdee023b92905193af0959e8a7639cfdcb9"
-  integrity sha1-AXjc3uAjuSkFGTrwlZ6KdjnP3Lk=
-
-fast-levenshtein@~2.0.4:
-  version "2.0.6"
-  resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917"
-  integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=
-
-faye-websocket@^0.10.0, faye-websocket@~0.10.0:
-  version "0.10.0"
-  resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.10.0.tgz#4e492f8d04dfb6f89003507f6edbf2d501e7c6f4"
-  integrity sha1-TkkvjQTftviQA1B/btvy1QHnxvQ=
-  dependencies:
-    websocket-driver ">=0.5.1"
-
-faye-websocket@~0.11.1:
-  version "0.11.3"
-  resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.11.3.tgz#5c0e9a8968e8912c286639fde977a8b209f2508e"
-  integrity sha512-D2y4bovYpzziGgbHYtGCMjlJM36vAl/y+xUyn1C+FVx8szd1E+86KwVw6XvYSzOP8iMpm1X0I4xJD+QtUb36OA==
-  dependencies:
-    websocket-driver ">=0.5.1"
-
-fg-lodash@0.0.2:
-  version "0.0.2"
-  resolved "https://registry.yarnpkg.com/fg-lodash/-/fg-lodash-0.0.2.tgz#988352537f427da6af222129bb63acca49e62fa3"
-  integrity sha1-mINSU39CfaavIiEpu2OsyknmL6M=
-  dependencies:
-    lodash "^2.4.1"
-    underscore.string "~2.3.3"
-
-figures@^1.0.1:
-  version "1.7.0"
-  resolved "https://registry.yarnpkg.com/figures/-/figures-1.7.0.tgz#cbe1e3affcf1cd44b80cadfed28dc793a9701d2e"
-  integrity sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=
-  dependencies:
-    escape-string-regexp "^1.0.5"
-    object-assign "^4.1.0"
-
-figures@^2.0.0:
-  version "2.0.0"
-  resolved "https://registry.yarnpkg.com/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962"
-  integrity sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=
-  dependencies:
-    escape-string-regexp "^1.0.5"
-
-file-entry-cache@^2.0.0:
-  version "2.0.0"
-  resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-2.0.0.tgz#c392990c3e684783d838b8c84a45d8a048458361"
-  integrity sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=
-  dependencies:
-    flat-cache "^1.2.1"
-    object-assign "^4.0.1"
-
-file-sync-cmp@^0.1.0:
-  version "0.1.1"
-  resolved "https://registry.yarnpkg.com/file-sync-cmp/-/file-sync-cmp-0.1.1.tgz#a5e7a8ffbfa493b43b923bbd4ca89a53b63b612b"
-  integrity sha1-peeo/7+kk7Q7kju9TKiaU7Y7YSs=
-
-filename-regex@^2.0.0:
-  version "2.0.1"
-  resolved "https://registry.yarnpkg.com/filename-regex/-/filename-regex-2.0.1.tgz#c1c4b9bee3e09725ddb106b75c1e301fe2f18b26"
-  integrity sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=
-
-fileset@0.2.x:
-  version "0.2.1"
-  resolved "https://registry.yarnpkg.com/fileset/-/fileset-0.2.1.tgz#588ef8973c6623b2a76df465105696b96aac8067"
-  integrity sha1-WI74lzxmI7KnbfRlEFaWuWqsgGc=
-  dependencies:
-    glob "5.x"
-    minimatch "2.x"
-
-fill-range@^2.1.0:
-  version "2.2.4"
-  resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-2.2.4.tgz#eb1e773abb056dcd8df2bfdf6af59b8b3a936565"
-  integrity sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q==
-  dependencies:
-    is-number "^2.1.0"
-    isobject "^2.0.0"
-    randomatic "^3.0.0"
-    repeat-element "^1.1.2"
-    repeat-string "^1.5.2"
-
-fill-range@^4.0.0:
-  version "4.0.0"
-  resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7"
-  integrity sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=
-  dependencies:
-    extend-shallow "^2.0.1"
-    is-number "^3.0.0"
-    repeat-string "^1.6.1"
-    to-regex-range "^2.1.0"
-
-finalhandler@1.1.2, finalhandler@~1.1.2:
-  version "1.1.2"
-  resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.2.tgz#b7e7d000ffd11938d0fdb053506f6ebabe9f587d"
-  integrity sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==
-  dependencies:
-    debug "2.6.9"
-    encodeurl "~1.0.2"
-    escape-html "~1.0.3"
-    on-finished "~2.3.0"
-    parseurl "~1.3.3"
-    statuses "~1.5.0"
-    unpipe "~1.0.0"
-
-find-up@^1.0.0:
-  version "1.1.2"
-  resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f"
-  integrity sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=
-  dependencies:
-    path-exists "^2.0.0"
-    pinkie-promise "^2.0.0"
-
-find-up@^3.0.0:
-  version "3.0.0"
-  resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73"
-  integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==
-  dependencies:
-    locate-path "^3.0.0"
-
-findup-sync@^2.0.0:
-  version "2.0.0"
-  resolved "https://registry.yarnpkg.com/findup-sync/-/findup-sync-2.0.0.tgz#9326b1488c22d1a6088650a86901b2d9a90a2cbc"
-  integrity sha1-kyaxSIwi0aYIhlCoaQGy2akKLLw=
-  dependencies:
-    detect-file "^1.0.0"
-    is-glob "^3.1.0"
-    micromatch "^3.0.4"
-    resolve-dir "^1.0.1"
-
-findup-sync@~0.3.0:
-  version "0.3.0"
-  resolved "https://registry.yarnpkg.com/findup-sync/-/findup-sync-0.3.0.tgz#37930aa5d816b777c03445e1966cc6790a4c0b16"
-  integrity sha1-N5MKpdgWt3fANEXhlmzGeQpMCxY=
-  dependencies:
-    glob "~5.0.0"
-
-fined@^1.0.1:
-  version "1.2.0"
-  resolved "https://registry.yarnpkg.com/fined/-/fined-1.2.0.tgz#d00beccf1aa2b475d16d423b0238b713a2c4a37b"
-  integrity sha512-ZYDqPLGxDkDhDZBjZBb+oD1+j0rA4E0pXY50eplAAOPg2N/gUBSSk5IM1/QhPfyVo19lJ+CvXpqfvk+b2p/8Ng==
-  dependencies:
-    expand-tilde "^2.0.2"
-    is-plain-object "^2.0.3"
-    object.defaults "^1.1.0"
-    object.pick "^1.2.0"
-    parse-filepath "^1.0.1"
-
-flagged-respawn@^1.0.0:
-  version "1.0.1"
-  resolved "https://registry.yarnpkg.com/flagged-respawn/-/flagged-respawn-1.0.1.tgz#e7de6f1279ddd9ca9aac8a5971d618606b3aab41"
-  integrity sha512-lNaHNVymajmk0OJMBn8fVUAU1BtDeKIqKoVhk4xAALB57aALg6b4W0MfJ/cUE0g9YBXy5XhSlPIpYIJ7HaY/3Q==
-
-flat-cache@^1.2.1:
-  version "1.3.4"
-  resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-1.3.4.tgz#2c2ef77525cc2929007dfffa1dd314aa9c9dee6f"
-  integrity sha512-VwyB3Lkgacfik2vhqR4uv2rvebqmDvFu4jlN/C1RzWoJEo8I7z4Q404oiqYCkq41mni8EzQnm95emU9seckwtg==
-  dependencies:
-    circular-json "^0.3.1"
-    graceful-fs "^4.1.2"
-    rimraf "~2.6.2"
-    write "^0.2.1"
-
-follow-redirects@^1.0.0:
-  version "1.9.0"
-  resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.9.0.tgz#8d5bcdc65b7108fe1508649c79c12d732dcedb4f"
-  integrity sha512-CRcPzsSIbXyVDl0QI01muNDu69S8trU4jArW9LpOt2WtC6LyUJetcIrmfHsRBx7/Jb6GHJUiuqyYxPooFfNt6A==
-  dependencies:
-    debug "^3.0.0"
-
-for-in@^1.0.1, for-in@^1.0.2:
-  version "1.0.2"
-  resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80"
-  integrity sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=
-
-for-own@^0.1.4:
-  version "0.1.5"
-  resolved "https://registry.yarnpkg.com/for-own/-/for-own-0.1.5.tgz#5265c681a4f294dabbf17c9509b6763aa84510ce"
-  integrity sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=
-  dependencies:
-    for-in "^1.0.1"
-
-for-own@^1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/for-own/-/for-own-1.0.0.tgz#c63332f415cedc4b04dbfe70cf836494c53cb44b"
-  integrity sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=
-  dependencies:
-    for-in "^1.0.1"
-
-forever-agent@~0.6.1:
-  version "0.6.1"
-  resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91"
-  integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=
-
-form-data@~2.3.2:
-  version "2.3.3"
-  resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6"
-  integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==
-  dependencies:
-    asynckit "^0.4.0"
-    combined-stream "^1.0.6"
-    mime-types "^2.1.12"
-
-forwarded@~0.1.2:
-  version "0.1.2"
-  resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84"
-  integrity sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=
-
-fragment-cache@^0.2.1:
-  version "0.2.1"
-  resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19"
-  integrity sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=
-  dependencies:
-    map-cache "^0.2.2"
-
-fresh@0.5.2:
-  version "0.5.2"
-  resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7"
-  integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=
-
-fs-extra@^6.0.1:
-  version "6.0.1"
-  resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-6.0.1.tgz#8abc128f7946e310135ddc93b98bddb410e7a34b"
-  integrity sha512-GnyIkKhhzXZUWFCaJzvyDLEEgDkPfb4/TPvJCJVuS8MWZgoSsErf++QpiAlDnKFcqhRlm+tIOcencCjyJE6ZCA==
-  dependencies:
-    graceful-fs "^4.1.2"
-    jsonfile "^4.0.0"
-    universalify "^0.1.0"
-
-fs-minipass@^1.2.5:
-  version "1.2.7"
-  resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.7.tgz#ccff8570841e7fe4265693da88936c55aed7f7c7"
-  integrity sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==
-  dependencies:
-    minipass "^2.6.0"
-
-fs-readdir-recursive@^0.1.0:
-  version "0.1.2"
-  resolved "https://registry.yarnpkg.com/fs-readdir-recursive/-/fs-readdir-recursive-0.1.2.tgz#315b4fb8c1ca5b8c47defef319d073dad3568059"
-  integrity sha1-MVtPuMHKW4xH3v7zGdBz2tNWgFk=
-
-fs.realpath@^1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
-  integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8=
-
-fsevents@^1.0.0:
-  version "1.2.9"
-  resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.9.tgz#3f5ed66583ccd6f400b5a00db6f7e861363e388f"
-  integrity sha512-oeyj2H3EjjonWcFjD5NvZNE9Rqe4UW+nQBU2HNeKw0koVLEFIhtyETyAakeAM3de7Z/SW5kcA+fZUait9EApnw==
-  dependencies:
-    nan "^2.12.1"
-    node-pre-gyp "^0.12.0"
-
-functional-red-black-tree@^1.0.1:
-  version "1.0.1"
-  resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327"
-  integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=
-
-gauge@~2.7.3:
-  version "2.7.4"
-  resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7"
-  integrity sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=
-  dependencies:
-    aproba "^1.0.3"
-    console-control-strings "^1.0.0"
-    has-unicode "^2.0.0"
-    object-assign "^4.1.0"
-    signal-exit "^3.0.0"
-    string-width "^1.0.1"
-    strip-ansi "^3.0.1"
-    wide-align "^1.1.0"
-
-gaze@^1.1.0:
-  version "1.1.3"
-  resolved "https://registry.yarnpkg.com/gaze/-/gaze-1.1.3.tgz#c441733e13b927ac8c0ff0b4c3b033f28812924a"
-  integrity sha512-BRdNm8hbWzFzWHERTrejLqwHDfS4GibPoq5wjTPIoJHoBtKGPg3xAFfxmM+9ztbXelxcf2hwQcaz1PtmFeue8g==
-  dependencies:
-    globule "^1.0.0"
-
-get-caller-file@^1.0.1:
-  version "1.0.3"
-  resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.3.tgz#f978fa4c90d1dfe7ff2d6beda2a515e713bdcf4a"
-  integrity sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==
-
-get-stdin@^4.0.1:
-  version "4.0.1"
-  resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-4.0.1.tgz#b968c6b0a04384324902e8bf1a5df32579a450fe"
-  integrity sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=
-
-get-stream@^4.0.0:
-  version "4.1.0"
-  resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5"
-  integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==
-  dependencies:
-    pump "^3.0.0"
-
-get-value@^2.0.3, get-value@^2.0.6:
-  version "2.0.6"
-  resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28"
-  integrity sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=
-
-getobject@~0.1.0:
-  version "0.1.0"
-  resolved "https://registry.yarnpkg.com/getobject/-/getobject-0.1.0.tgz#047a449789fa160d018f5486ed91320b6ec7885c"
-  integrity sha1-BHpEl4n6Fg0Bj1SG7ZEyC27HiFw=
-
-getpass@^0.1.1:
-  version "0.1.7"
-  resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa"
-  integrity sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=
-  dependencies:
-    assert-plus "^1.0.0"
-
-glob-base@^0.3.0:
-  version "0.3.0"
-  resolved "https://registry.yarnpkg.com/glob-base/-/glob-base-0.3.0.tgz#dbb164f6221b1c0b1ccf82aea328b497df0ea3c4"
-  integrity sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=
-  dependencies:
-    glob-parent "^2.0.0"
-    is-glob "^2.0.0"
-
-glob-parent@^2.0.0:
-  version "2.0.0"
-  resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-2.0.0.tgz#81383d72db054fcccf5336daa902f182f6edbb28"
-  integrity sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=
-  dependencies:
-    is-glob "^2.0.0"
-
-glob@5.x, glob@^5.0.15, glob@~5.0.0:
-  version "5.0.15"
-  resolved "https://registry.yarnpkg.com/glob/-/glob-5.0.15.tgz#1bc936b9e02f4a603fcc222ecf7633d30b8b93b1"
-  integrity sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=
-  dependencies:
-    inflight "^1.0.4"
-    inherits "2"
-    minimatch "2 || 3"
-    once "^1.3.0"
-    path-is-absolute "^1.0.0"
-
-glob@7.1.2:
-  version "7.1.2"
-  resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15"
-  integrity sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==
-  dependencies:
-    fs.realpath "^1.0.0"
-    inflight "^1.0.4"
-    inherits "2"
-    minimatch "^3.0.4"
-    once "^1.3.0"
-    path-is-absolute "^1.0.0"
-
-glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@~7.1.1:
-  version "7.1.5"
-  resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.5.tgz#6714c69bee20f3c3e64c4dd905553e532b40cdc0"
-  integrity sha512-J9dlskqUXK1OeTOYBEn5s8aMukWMwWfs+rPTn/jn50Ux4MNXVhubL1wu/j2t+H4NVI+cXEcCaYellqaPVGXNqQ==
-  dependencies:
-    fs.realpath "^1.0.0"
-    inflight "^1.0.4"
-    inherits "2"
-    minimatch "^3.0.4"
-    once "^1.3.0"
-    path-is-absolute "^1.0.0"
-
-glob@~7.0.0:
-  version "7.0.6"
-  resolved "https://registry.yarnpkg.com/glob/-/glob-7.0.6.tgz#211bafaf49e525b8cd93260d14ab136152b3f57a"
-  integrity sha1-IRuvr0nlJbjNkyYNFKsTYVKz9Xo=
-  dependencies:
-    fs.realpath "^1.0.0"
-    inflight "^1.0.4"
-    inherits "2"
-    minimatch "^3.0.2"
-    once "^1.3.0"
-    path-is-absolute "^1.0.0"
-
-global-modules@^1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-1.0.0.tgz#6d770f0eb523ac78164d72b5e71a8877265cc3ea"
-  integrity sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==
-  dependencies:
-    global-prefix "^1.0.1"
-    is-windows "^1.0.1"
-    resolve-dir "^1.0.0"
-
-global-prefix@^1.0.1:
-  version "1.0.2"
-  resolved "https://registry.yarnpkg.com/global-prefix/-/global-prefix-1.0.2.tgz#dbf743c6c14992593c655568cb66ed32c0122ebe"
-  integrity sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=
-  dependencies:
-    expand-tilde "^2.0.2"
-    homedir-polyfill "^1.0.1"
-    ini "^1.3.4"
-    is-windows "^1.0.1"
-    which "^1.2.14"
-
-globals@^11.0.1:
-  version "11.12.0"
-  resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e"
-  integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==
-
-globals@^6.4.0:
-  version "6.4.1"
-  resolved "https://registry.yarnpkg.com/globals/-/globals-6.4.1.tgz#8498032b3b6d1cc81eebc5f79690d8fe29fabf4f"
-  integrity sha1-hJgDKzttHMge68X3lpDY/in6v08=
-
-globule@^1.0.0:
-  version "1.2.1"
-  resolved "https://registry.yarnpkg.com/globule/-/globule-1.2.1.tgz#5dffb1b191f22d20797a9369b49eab4e9839696d"
-  integrity sha512-g7QtgWF4uYSL5/dn71WxubOrS7JVGCnFPEnoeChJmBnyR9Mw8nGoEwOgJL/RC2Te0WhbsEUCejfH8SZNJ+adYQ==
-  dependencies:
-    glob "~7.1.1"
-    lodash "~4.17.10"
-    minimatch "~3.0.2"
-
-graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.4, graceful-fs@^4.1.6:
-  version "4.2.3"
-  resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.3.tgz#4a12ff1b60376ef09862c2093edd908328be8423"
-  integrity sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==
-
-growl@1.10.5:
-  version "1.10.5"
-  resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e"
-  integrity sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==
-
-grunt-babel@^5.0.0:
-  version "5.0.3"
-  resolved "https://registry.yarnpkg.com/grunt-babel/-/grunt-babel-5.0.3.tgz#86220eb3202efae233a8418a1d7f87b60adee323"
-  integrity sha1-hiIOsyAu+uIzqEGKHX+Htgre4yM=
-  dependencies:
-    babel-core "^5.0.0"
-
-grunt-bg-shell@^2.3.3:
-  version "2.3.3"
-  resolved "https://registry.yarnpkg.com/grunt-bg-shell/-/grunt-bg-shell-2.3.3.tgz#139ae8f9c76f68a0db4ee9dbbd4ec825b9227fff"
-  integrity sha1-E5ro+cdvaKDbTunbvU7IJbkif/8=
-
-grunt-cli@^1:
-  version "1.3.2"
-  resolved "https://registry.yarnpkg.com/grunt-cli/-/grunt-cli-1.3.2.tgz#60f12d12c1b5aae94ae3469c6b5fe24e960014e8"
-  integrity sha512-8OHDiZZkcptxVXtMfDxJvmN7MVJNE8L/yIcPb4HB7TlyFD1kDvjHrb62uhySsU14wJx9ORMnTuhRMQ40lH/orQ==
-  dependencies:
-    grunt-known-options "~1.1.0"
-    interpret "~1.1.0"
-    liftoff "~2.5.0"
-    nopt "~4.0.1"
-    v8flags "~3.1.1"
-
-grunt-cli@~1.2.0:
-  version "1.2.0"
-  resolved "https://registry.yarnpkg.com/grunt-cli/-/grunt-cli-1.2.0.tgz#562b119ebb069ddb464ace2845501be97b35b6a8"
-  integrity sha1-VisRnrsGndtGSs4oRVAb6Xs1tqg=
-  dependencies:
-    findup-sync "~0.3.0"
-    grunt-known-options "~1.1.0"
-    nopt "~3.0.6"
-    resolve "~1.1.0"
-
-grunt-contrib-clean@^1:
-  version "1.1.0"
-  resolved "https://registry.yarnpkg.com/grunt-contrib-clean/-/grunt-contrib-clean-1.1.0.tgz#564abf2d0378a983a15b9e3f30ee75b738c40638"
-  integrity sha1-Vkq/LQN4qYOhW54/MO51tzjEBjg=
-  dependencies:
-    async "^1.5.2"
-    rimraf "^2.5.1"
-
-grunt-contrib-concat@^1:
-  version "1.0.1"
-  resolved "https://registry.yarnpkg.com/grunt-contrib-concat/-/grunt-contrib-concat-1.0.1.tgz#61509863084e871d7e86de48c015259ed97745bd"
-  integrity sha1-YVCYYwhOhx1+ht5IwBUlntl3Rb0=
-  dependencies:
-    chalk "^1.0.0"
-    source-map "^0.5.3"
-
-grunt-contrib-connect@^1:
-  version "1.0.2"
-  resolved "https://registry.yarnpkg.com/grunt-contrib-connect/-/grunt-contrib-connect-1.0.2.tgz#5cf933b91a67386044273c0b2444603cd98879ba"
-  integrity sha1-XPkzuRpnOGBEJzwLJERgPNmIebo=
-  dependencies:
-    async "^1.5.2"
-    connect "^3.4.0"
-    connect-livereload "^0.5.0"
-    http2 "^3.3.4"
-    morgan "^1.6.1"
-    opn "^4.0.0"
-    portscanner "^1.0.0"
-    serve-index "^1.7.1"
-    serve-static "^1.10.0"
-
-grunt-contrib-copy@^1:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/grunt-contrib-copy/-/grunt-contrib-copy-1.0.0.tgz#7060c6581e904b8ab0d00f076e0a8f6e3e7c3573"
-  integrity sha1-cGDGWB6QS4qw0A8HbgqPbj58NXM=
-  dependencies:
-    chalk "^1.1.1"
-    file-sync-cmp "^0.1.0"
-
-grunt-contrib-requirejs@^1:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/grunt-contrib-requirejs/-/grunt-contrib-requirejs-1.0.0.tgz#ec1670cafc32713902ee53569454715b2e3cbad5"
-  integrity sha1-7BZwyvwycTkC7lNWlFRxWy48utU=
-  dependencies:
-    requirejs "^2.1.0"
-
-grunt-contrib-uglify@^1:
-  version "1.0.2"
-  resolved "https://registry.yarnpkg.com/grunt-contrib-uglify/-/grunt-contrib-uglify-1.0.2.tgz#ae67a46f9153edd4cb11813a55eb69c70d7db2fb"
-  integrity sha1-rmekb5FT7dTLEYE6Vetpxw19svs=
-  dependencies:
-    chalk "^1.0.0"
-    lodash "^4.0.1"
-    maxmin "^1.1.0"
-    uglify-js "~2.6.2"
-    uri-path "^1.0.0"
-
-grunt-contrib-watch@^1.1.0:
-  version "1.1.0"
-  resolved "https://registry.yarnpkg.com/grunt-contrib-watch/-/grunt-contrib-watch-1.1.0.tgz#c143ca5b824b288a024b856639a5345aedb78ed4"
-  integrity sha512-yGweN+0DW5yM+oo58fRu/XIRrPcn3r4tQx+nL7eMRwjpvk+rQY6R8o94BPK0i2UhTg9FN21hS+m8vR8v9vXfeg==
-  dependencies:
-    async "^2.6.0"
-    gaze "^1.1.0"
-    lodash "^4.17.10"
-    tiny-lr "^1.1.1"
-
-grunt-eslint@^20.1.0:
-  version "20.2.0"
-  resolved "https://registry.yarnpkg.com/grunt-eslint/-/grunt-eslint-20.2.0.tgz#beeda46fa9b84e00863742aa4bcc84846cd27bca"
-  integrity sha512-XPrN3lyFwiTdQWpblZqvKvKtk74aZNs/6tUdKZqSCl/YNq+iaoE477w7I/082OwTSjyXi4ylE1P5fhHWuzxu1w==
-  dependencies:
-    chalk "^2.1.0"
-    eslint "^4.0.0"
-
-grunt-known-options@~1.1.0:
-  version "1.1.1"
-  resolved "https://registry.yarnpkg.com/grunt-known-options/-/grunt-known-options-1.1.1.tgz#6cc088107bd0219dc5d3e57d91923f469059804d"
-  integrity sha512-cHwsLqoighpu7TuYj5RonnEuxGVFnztcUqTqp5rXFGYL4OuPFofwC4Ycg7n9fYwvK6F5WbYgeVOwph9Crs2fsQ==
-
-grunt-legacy-log-utils@~2.0.0:
-  version "2.0.1"
-  resolved "https://registry.yarnpkg.com/grunt-legacy-log-utils/-/grunt-legacy-log-utils-2.0.1.tgz#d2f442c7c0150065d9004b08fd7410d37519194e"
-  integrity sha512-o7uHyO/J+i2tXG8r2bZNlVk20vlIFJ9IEYyHMCQGfWYru8Jv3wTqKZzvV30YW9rWEjq0eP3cflQ1qWojIe9VFA==
-  dependencies:
-    chalk "~2.4.1"
-    lodash "~4.17.10"
-
-grunt-legacy-log@~2.0.0:
-  version "2.0.0"
-  resolved "https://registry.yarnpkg.com/grunt-legacy-log/-/grunt-legacy-log-2.0.0.tgz#c8cd2c6c81a4465b9bbf2d874d963fef7a59ffb9"
-  integrity sha512-1m3+5QvDYfR1ltr8hjiaiNjddxGdQWcH0rw1iKKiQnF0+xtgTazirSTGu68RchPyh1OBng1bBUjLmX8q9NpoCw==
-  dependencies:
-    colors "~1.1.2"
-    grunt-legacy-log-utils "~2.0.0"
-    hooker "~0.2.3"
-    lodash "~4.17.5"
-
-grunt-legacy-util@~1.1.1:
-  version "1.1.1"
-  resolved "https://registry.yarnpkg.com/grunt-legacy-util/-/grunt-legacy-util-1.1.1.tgz#e10624e7c86034e5b870c8a8616743f0a0845e42"
-  integrity sha512-9zyA29w/fBe6BIfjGENndwoe1Uy31BIXxTH3s8mga0Z5Bz2Sp4UCjkeyv2tI449ymkx3x26B+46FV4fXEddl5A==
-  dependencies:
-    async "~1.5.2"
-    exit "~0.1.1"
-    getobject "~0.1.0"
-    hooker "~0.2.3"
-    lodash "~4.17.10"
-    underscore.string "~3.3.4"
-    which "~1.3.0"
-
-grunt-webpack@^1.0.8:
-  version "1.0.18"
-  resolved "https://registry.yarnpkg.com/grunt-webpack/-/grunt-webpack-1.0.18.tgz#ff26c43ff35bae6cca707a93c4bcdd950a3ecbb7"
-  integrity sha1-/ybEP/NbrmzKcHqTxLzdlQo+y7c=
-  dependencies:
-    lodash "^4.7.0"
-
-grunt@^1.0.3:
-  version "1.0.4"
-  resolved "https://registry.yarnpkg.com/grunt/-/grunt-1.0.4.tgz#c799883945a53a3d07622e0737c8f70bfe19eb38"
-  integrity sha512-PYsMOrOC+MsdGEkFVwMaMyc6Ob7pKmq+deg1Sjr+vvMWp35sztfwKE7qoN51V+UEtHsyNuMcGdgMLFkBHvMxHQ==
-  dependencies:
-    coffeescript "~1.10.0"
-    dateformat "~1.0.12"
-    eventemitter2 "~0.4.13"
-    exit "~0.1.1"
-    findup-sync "~0.3.0"
-    glob "~7.0.0"
-    grunt-cli "~1.2.0"
-    grunt-known-options "~1.1.0"
-    grunt-legacy-log "~2.0.0"
-    grunt-legacy-util "~1.1.1"
-    iconv-lite "~0.4.13"
-    js-yaml "~3.13.0"
-    minimatch "~3.0.2"
-    mkdirp "~0.5.1"
-    nopt "~3.0.6"
-    path-is-absolute "~1.0.0"
-    rimraf "~2.6.2"
-
-gzip-size@^1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/gzip-size/-/gzip-size-1.0.0.tgz#66cf8b101047227b95bace6ea1da0c177ed5c22f"
-  integrity sha1-Zs+LEBBHInuVus5uodoMF37Vwi8=
-  dependencies:
-    browserify-zlib "^0.1.4"
-    concat-stream "^1.4.1"
-
-handlebars@^4.0.1:
-  version "4.4.5"
-  resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.4.5.tgz#1b1f94f9bfe7379adda86a8b73fb570265a0dddd"
-  integrity sha512-0Ce31oWVB7YidkaTq33ZxEbN+UDxMMgThvCe8ptgQViymL5DPis9uLdTA13MiRPhgvqyxIegugrP97iK3JeBHg==
-  dependencies:
-    neo-async "^2.6.0"
-    optimist "^0.6.1"
-    source-map "^0.6.1"
-  optionalDependencies:
-    uglify-js "^3.1.4"
-
-har-schema@^2.0.0:
-  version "2.0.0"
-  resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92"
-  integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=
-
-har-validator@~5.1.0:
-  version "5.1.3"
-  resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.3.tgz#1ef89ebd3e4996557675eed9893110dc350fa080"
-  integrity sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==
-  dependencies:
-    ajv "^6.5.5"
-    har-schema "^2.0.0"
-
-has-ansi@^2.0.0:
-  version "2.0.0"
-  resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91"
-  integrity sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=
-  dependencies:
-    ansi-regex "^2.0.0"
-
-has-color@~0.1.0:
-  version "0.1.7"
-  resolved "https://registry.yarnpkg.com/has-color/-/has-color-0.1.7.tgz#67144a5260c34fc3cca677d041daf52fe7b78b2f"
-  integrity sha1-ZxRKUmDDT8PMpnfQQdr1L+e3iy8=
-
-has-flag@^1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-1.0.0.tgz#9d9e793165ce017a00f00418c43f942a7b1d11fa"
-  integrity sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=
-
-has-flag@^3.0.0:
-  version "3.0.0"
-  resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd"
-  integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0=
-
-has-unicode@^2.0.0:
-  version "2.0.1"
-  resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9"
-  integrity sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=
-
-has-value@^0.3.1:
-  version "0.3.1"
-  resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f"
-  integrity sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=
-  dependencies:
-    get-value "^2.0.3"
-    has-values "^0.1.4"
-    isobject "^2.0.0"
-
-has-value@^1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/has-value/-/has-value-1.0.0.tgz#18b281da585b1c5c51def24c930ed29a0be6b177"
-  integrity sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=
-  dependencies:
-    get-value "^2.0.6"
-    has-values "^1.0.0"
-    isobject "^3.0.0"
-
-has-values@^0.1.4:
-  version "0.1.4"
-  resolved "https://registry.yarnpkg.com/has-values/-/has-values-0.1.4.tgz#6d61de95d91dfca9b9a02089ad384bff8f62b771"
-  integrity sha1-bWHeldkd/Km5oCCJrThL/49it3E=
-
-has-values@^1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/has-values/-/has-values-1.0.0.tgz#95b0b63fec2146619a6fe57fe75628d5a39efe4f"
-  integrity sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=
-  dependencies:
-    is-number "^3.0.0"
-    kind-of "^4.0.0"
-
-he@1.1.1:
-  version "1.1.1"
-  resolved "https://registry.yarnpkg.com/he/-/he-1.1.1.tgz#93410fd21b009735151f8868c2f271f3427e23fd"
-  integrity sha1-k0EP0hsAlzUVH4howvJx80J+I/0=
-
-home-or-tmp@^1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/home-or-tmp/-/home-or-tmp-1.0.0.tgz#4b9f1e40800c3e50c6c27f781676afcce71f3985"
-  integrity sha1-S58eQIAMPlDGwn94FnavzOcfOYU=
-  dependencies:
-    os-tmpdir "^1.0.1"
-    user-home "^1.1.1"
-
-homedir-polyfill@^1.0.1:
-  version "1.0.3"
-  resolved "https://registry.yarnpkg.com/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz#743298cef4e5af3e194161fbadcc2151d3a058e8"
-  integrity sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==
-  dependencies:
-    parse-passwd "^1.0.0"
-
-hooker@~0.2.3:
-  version "0.2.3"
-  resolved "https://registry.yarnpkg.com/hooker/-/hooker-0.2.3.tgz#b834f723cc4a242aa65963459df6d984c5d3d959"
-  integrity sha1-uDT3I8xKJCqmWWNFnfbZhMXT2Vk=
-
-hosted-git-info@^2.1.4:
-  version "2.8.5"
-  resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.5.tgz#759cfcf2c4d156ade59b0b2dfabddc42a6b9c70c"
-  integrity sha512-kssjab8CvdXfcXMXVcvsXum4Hwdq9XGtRD3TteMEvEbq0LXyiNQr6AprqKqfeaDXze7SxWvRxdpwE6ku7ikLkg==
-
-http-errors@1.7.2:
-  version "1.7.2"
-  resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.2.tgz#4f5029cf13239f31036e5b2e55292bcfbcc85c8f"
-  integrity sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==
-  dependencies:
-    depd "~1.1.2"
-    inherits "2.0.3"
-    setprototypeof "1.1.1"
-    statuses ">= 1.5.0 < 2"
-    toidentifier "1.0.0"
-
-http-errors@~1.6.2:
-  version "1.6.3"
-  resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d"
-  integrity sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=
-  dependencies:
-    depd "~1.1.2"
-    inherits "2.0.3"
-    setprototypeof "1.1.0"
-    statuses ">= 1.4.0 < 2"
-
-http-errors@~1.7.2:
-  version "1.7.3"
-  resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.3.tgz#6c619e4f9c60308c38519498c14fbb10aacebb06"
-  integrity sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw==
-  dependencies:
-    depd "~1.1.2"
-    inherits "2.0.4"
-    setprototypeof "1.1.1"
-    statuses ">= 1.5.0 < 2"
-    toidentifier "1.0.0"
-
-"http-parser-js@>=0.4.0 <0.4.11":
-  version "0.4.10"
-  resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.4.10.tgz#92c9c1374c35085f75db359ec56cc257cbb93fa4"
-  integrity sha1-ksnBN0w1CF912zWexWzCV8u5P6Q=
-
-http-proxy-middleware@~0.17.1:
-  version "0.17.4"
-  resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-0.17.4.tgz#642e8848851d66f09d4f124912846dbaeb41b833"
-  integrity sha1-ZC6ISIUdZvCdTxJJEoRtuutBuDM=
-  dependencies:
-    http-proxy "^1.16.2"
-    is-glob "^3.1.0"
-    lodash "^4.17.2"
-    micromatch "^2.3.11"
-
-http-proxy@^1.16.2:
-  version "1.18.0"
-  resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.18.0.tgz#dbe55f63e75a347db7f3d99974f2692a314a6a3a"
-  integrity sha512-84I2iJM/n1d4Hdgc6y2+qY5mDaz2PUVjlg9znE9byl+q0uC3DeByqBGReQu5tpLK0TAqTIXScRUV+dg7+bUPpQ==
-  dependencies:
-    eventemitter3 "^4.0.0"
-    follow-redirects "^1.0.0"
-    requires-port "^1.0.0"
-
-http-signature@~1.2.0:
-  version "1.2.0"
-  resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1"
-  integrity sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=
-  dependencies:
-    assert-plus "^1.0.0"
-    jsprim "^1.2.2"
-    sshpk "^1.7.0"
-
-http2@^3.3.4:
-  version "3.3.7"
-  resolved "https://registry.yarnpkg.com/http2/-/http2-3.3.7.tgz#78396eb1e0bcd1db1f4b138d997c682e23414fbc"
-  integrity sha512-puSi8M8WNlFJm9Pk4c/Mbz9Gwparuj3gO9/RRO5zv6piQ0FY+9Qywp0PdWshYgsMJSalixFY7eC6oPu0zRxLAQ==
-
-https-browserify@0.0.1:
-  version "0.0.1"
-  resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-0.0.1.tgz#3f91365cabe60b77ed0ebba24b454e3e09d95a82"
-  integrity sha1-P5E2XKvmC3ftDruiS0VOPgnZWoI=
-
-https-proxy-agent@^2.2.1:
-  version "2.2.3"
-  resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-2.2.3.tgz#fb6cd98ed5b9c35056b5a73cd01a8a721d7193d1"
-  integrity sha512-Ytgnz23gm2DVftnzqRRz2dOXZbGd2uiajSw/95bPp6v53zPRspQjLm/AfBgqbJ2qfeRXWIOMVLpp86+/5yX39Q==
-  dependencies:
-    agent-base "^4.3.0"
-    debug "^3.1.0"
-
-iconv-lite@0.4.24, iconv-lite@^0.4.17, iconv-lite@^0.4.4, iconv-lite@^0.4.5, iconv-lite@~0.4.13:
-  version "0.4.24"
-  resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b"
-  integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==
-  dependencies:
-    safer-buffer ">= 2.1.2 < 3"
-
-ieee754@1.1.13, ieee754@^1.1.4:
-  version "1.1.13"
-  resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.13.tgz#ec168558e95aa181fd87d37f55c32bbcb6708b84"
-  integrity sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==
-
-ignore-walk@^3.0.1:
-  version "3.0.3"
-  resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-3.0.3.tgz#017e2447184bfeade7c238e4aefdd1e8f95b1e37"
-  integrity sha512-m7o6xuOaT1aqheYHKf8W6J5pYH85ZI9w077erOzLje3JsB1gkafkAhHHY19dqjulgIZHFm32Cp5uNZgcQqdJKw==
-  dependencies:
-    minimatch "^3.0.4"
-
-ignore@^3.3.3:
-  version "3.3.10"
-  resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.10.tgz#0a97fb876986e8081c631160f8f9f389157f0043"
-  integrity sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==
-
-imurmurhash@^0.1.4:
-  version "0.1.4"
-  resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea"
-  integrity sha1-khi5srkoojixPcT7a21XbyMUU+o=
-
-indent-string@^2.1.0:
-  version "2.1.0"
-  resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-2.1.0.tgz#8e2d48348742121b4a8218b7a137e9a52049dc80"
-  integrity sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=
-  dependencies:
-    repeating "^2.0.0"
-
-indexof@0.0.1:
-  version "0.0.1"
-  resolved "https://registry.yarnpkg.com/indexof/-/indexof-0.0.1.tgz#82dc336d232b9062179d05ab3293a66059fd435d"
-  integrity sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10=
-
-inflight@^1.0.4:
-  version "1.0.6"
-  resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9"
-  integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=
-  dependencies:
-    once "^1.3.0"
-    wrappy "1"
-
-inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.1, inherits@~2.0.3:
-  version "2.0.4"
-  resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
-  integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
-
-inherits@2.0.1:
-  version "2.0.1"
-  resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1"
-  integrity sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=
-
-inherits@2.0.3:
-  version "2.0.3"
-  resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de"
-  integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=
-
-ini@^1.3.4, ini@~1.3.0:
-  version "1.3.5"
-  resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927"
-  integrity sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==
-
-inquirer@^3.0.6:
-  version "3.3.0"
-  resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-3.3.0.tgz#9dd2f2ad765dcab1ff0443b491442a20ba227dc9"
-  integrity sha512-h+xtnyk4EwKvFWHrUYsWErEVR+igKtLdchu+o0Z1RL7VU/jVMFbYir2bp6bAj8efFNxWqHX0dIss6fJQ+/+qeQ==
-  dependencies:
-    ansi-escapes "^3.0.0"
-    chalk "^2.0.0"
-    cli-cursor "^2.1.0"
-    cli-width "^2.0.0"
-    external-editor "^2.0.4"
-    figures "^2.0.0"
-    lodash "^4.3.0"
-    mute-stream "0.0.7"
-    run-async "^2.2.0"
-    rx-lite "^4.0.8"
-    rx-lite-aggregates "^4.0.8"
-    string-width "^2.1.0"
-    strip-ansi "^4.0.0"
-    through "^2.3.6"
-
-interpret@^0.6.4:
-  version "0.6.6"
-  resolved "https://registry.yarnpkg.com/interpret/-/interpret-0.6.6.tgz#fecd7a18e7ce5ca6abfb953e1f86213a49f1625b"
-  integrity sha1-/s16GOfOXKar+5U+H4YhOknxYls=
-
-interpret@~1.1.0:
-  version "1.1.0"
-  resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.1.0.tgz#7ed1b1410c6a0e0f78cf95d3b8440c63f78b8614"
-  integrity sha1-ftGxQQxqDg94z5XTuEQMY/eLhhQ=
-
-invert-kv@^1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6"
-  integrity sha1-EEqOSqym09jNFXqO+L+rLXo//bY=
-
-invert-kv@^2.0.0:
-  version "2.0.0"
-  resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-2.0.0.tgz#7393f5afa59ec9ff5f67a27620d11c226e3eec02"
-  integrity sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==
-
-ipaddr.js@1.9.0:
-  version "1.9.0"
-  resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.0.tgz#37df74e430a0e47550fe54a2defe30d8acd95f65"
-  integrity sha512-M4Sjn6N/+O6/IXSJseKqHoFc+5FdGJ22sXqnjTpdZweHK64MzEPAyQZyEU3R/KRv2GLoa7nNtg/C2Ev6m7z+eA==
-
-is-absolute@^1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/is-absolute/-/is-absolute-1.0.0.tgz#395e1ae84b11f26ad1795e73c17378e48a301576"
-  integrity sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==
-  dependencies:
-    is-relative "^1.0.0"
-    is-windows "^1.0.1"
-
-is-accessor-descriptor@^0.1.6:
-  version "0.1.6"
-  resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6"
-  integrity sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=
-  dependencies:
-    kind-of "^3.0.2"
-
-is-accessor-descriptor@^1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz#169c2f6d3df1f992618072365c9b0ea1f6878656"
-  integrity sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==
-  dependencies:
-    kind-of "^6.0.0"
-
-is-arrayish@^0.2.1:
-  version "0.2.1"
-  resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d"
-  integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=
-
-is-binary-path@^1.0.0:
-  version "1.0.1"
-  resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898"
-  integrity sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=
-  dependencies:
-    binary-extensions "^1.0.0"
-
-is-buffer@^1.1.5:
-  version "1.1.6"
-  resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be"
-  integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==
-
-is-data-descriptor@^0.1.4:
-  version "0.1.4"
-  resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56"
-  integrity sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=
-  dependencies:
-    kind-of "^3.0.2"
-
-is-data-descriptor@^1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz#d84876321d0e7add03990406abbbbd36ba9268c7"
-  integrity sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==
-  dependencies:
-    kind-of "^6.0.0"
-
-is-descriptor@^0.1.0:
-  version "0.1.6"
-  resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca"
-  integrity sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==
-  dependencies:
-    is-accessor-descriptor "^0.1.6"
-    is-data-descriptor "^0.1.4"
-    kind-of "^5.0.0"
-
-is-descriptor@^1.0.0, is-descriptor@^1.0.2:
-  version "1.0.2"
-  resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-1.0.2.tgz#3b159746a66604b04f8c81524ba365c5f14d86ec"
-  integrity sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==
-  dependencies:
-    is-accessor-descriptor "^1.0.0"
-    is-data-descriptor "^1.0.0"
-    kind-of "^6.0.2"
-
-is-dotfile@^1.0.0:
-  version "1.0.3"
-  resolved "https://registry.yarnpkg.com/is-dotfile/-/is-dotfile-1.0.3.tgz#a6a2f32ffd2dfb04f5ca25ecd0f6b83cf798a1e1"
-  integrity sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=
-
-is-equal-shallow@^0.1.3:
-  version "0.1.3"
-  resolved "https://registry.yarnpkg.com/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz#2238098fc221de0bcfa5d9eac4c45d638aa1c534"
-  integrity sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=
-  dependencies:
-    is-primitive "^2.0.0"
-
-is-extendable@^0.1.0, is-extendable@^0.1.1:
-  version "0.1.1"
-  resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89"
-  integrity sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=
-
-is-extendable@^1.0.1:
-  version "1.0.1"
-  resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-1.0.1.tgz#a7470f9e426733d81bd81e1155264e3a3507cab4"
-  integrity sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==
-  dependencies:
-    is-plain-object "^2.0.4"
-
-is-extglob@^1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-1.0.0.tgz#ac468177c4943405a092fc8f29760c6ffc6206c0"
-  integrity sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=
-
-is-extglob@^2.1.0:
-  version "2.1.1"
-  resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2"
-  integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=
-
-is-finite@^1.0.0:
-  version "1.0.2"
-  resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.0.2.tgz#cc6677695602be550ef11e8b4aa6305342b6d0aa"
-  integrity sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=
-  dependencies:
-    number-is-nan "^1.0.0"
-
-is-fullwidth-code-point@^1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb"
-  integrity sha1-754xOG8DGn8NZDr4L95QxFfvAMs=
-  dependencies:
-    number-is-nan "^1.0.0"
-
-is-fullwidth-code-point@^2.0.0:
-  version "2.0.0"
-  resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f"
-  integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=
-
-is-glob@^2.0.0, is-glob@^2.0.1:
-  version "2.0.1"
-  resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-2.0.1.tgz#d096f926a3ded5600f3fdfd91198cb0888c2d863"
-  integrity sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=
-  dependencies:
-    is-extglob "^1.0.0"
-
-is-glob@^3.1.0:
-  version "3.1.0"
-  resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a"
-  integrity sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=
-  dependencies:
-    is-extglob "^2.1.0"
-
-is-integer@^1.0.4:
-  version "1.0.7"
-  resolved "https://registry.yarnpkg.com/is-integer/-/is-integer-1.0.7.tgz#6bde81aacddf78b659b6629d629cadc51a886d5c"
-  integrity sha1-a96Bqs3feLZZtmKdYpytxRqIbVw=
-  dependencies:
-    is-finite "^1.0.0"
-
-is-number@^2.1.0:
-  version "2.1.0"
-  resolved "https://registry.yarnpkg.com/is-number/-/is-number-2.1.0.tgz#01fcbbb393463a548f2f466cce16dece49db908f"
-  integrity sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=
-  dependencies:
-    kind-of "^3.0.2"
-
-is-number@^3.0.0:
-  version "3.0.0"
-  resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195"
-  integrity sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=
-  dependencies:
-    kind-of "^3.0.2"
-
-is-number@^4.0.0:
-  version "4.0.0"
-  resolved "https://registry.yarnpkg.com/is-number/-/is-number-4.0.0.tgz#0026e37f5454d73e356dfe6564699867c6a7f0ff"
-  integrity sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==
-
-is-plain-object@^2.0.3, is-plain-object@^2.0.4:
-  version "2.0.4"
-  resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677"
-  integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==
-  dependencies:
-    isobject "^3.0.1"
-
-is-posix-bracket@^0.1.0:
-  version "0.1.1"
-  resolved "https://registry.yarnpkg.com/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz#3334dc79774368e92f016e6fbc0a88f5cd6e6bc4"
-  integrity sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=
-
-is-primitive@^2.0.0:
-  version "2.0.0"
-  resolved "https://registry.yarnpkg.com/is-primitive/-/is-primitive-2.0.0.tgz#207bab91638499c07b2adf240a41a87210034575"
-  integrity sha1-IHurkWOEmcB7Kt8kCkGochADRXU=
-
-is-promise@^2.1.0:
-  version "2.1.0"
-  resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa"
-  integrity sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=
-
-is-relative@^1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/is-relative/-/is-relative-1.0.0.tgz#a1bb6935ce8c5dba1e8b9754b9b2dcc020e2260d"
-  integrity sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==
-  dependencies:
-    is-unc-path "^1.0.0"
-
-is-resolvable@^1.0.0:
-  version "1.1.0"
-  resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.1.0.tgz#fb18f87ce1feb925169c9a407c19318a3206ed88"
-  integrity sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==
-
-is-stream@^1.1.0:
-  version "1.1.0"
-  resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44"
-  integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ=
-
-is-typedarray@~1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a"
-  integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=
-
-is-unc-path@^1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/is-unc-path/-/is-unc-path-1.0.0.tgz#d731e8898ed090a12c352ad2eaed5095ad322c9d"
-  integrity sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==
-  dependencies:
-    unc-path-regex "^0.1.2"
-
-is-utf8@^0.2.0:
-  version "0.2.1"
-  resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72"
-  integrity sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=
-
-is-windows@^1.0.1, is-windows@^1.0.2:
-  version "1.0.2"
-  resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d"
-  integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==
-
-isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11"
-  integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=
-
-isexe@^2.0.0:
-  version "2.0.0"
-  resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"
-  integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=
-
-isobject@^2.0.0:
-  version "2.1.0"
-  resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89"
-  integrity sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=
-  dependencies:
-    isarray "1.0.0"
-
-isobject@^3.0.0, isobject@^3.0.1:
-  version "3.0.1"
-  resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df"
-  integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8=
-
-isstream@~0.1.2:
-  version "0.1.2"
-  resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a"
-  integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=
-
-istanbul@kpdecker/istanbul:
-  version "0.4.0"
-  resolved "https://codeload.github.com/kpdecker/istanbul/tar.gz/dd1228d2f0a6e8506cbb5dba398a8297b1dbaf22"
-  dependencies:
-    abbrev "1.0.x"
-    async "1.x"
-    convert-source-map "^1.1.1"
-    escodegen "1.7.x"
-    esprima "2.5.x"
-    fileset "0.2.x"
-    handlebars "^4.0.1"
-    js-yaml "3.x"
-    mkdirp "0.5.x"
-    nopt "3.x"
-    once "1.x"
-    resolve "1.1.x"
-    source-map "^0.4.4"
-    source-map-support "^0.3.2"
-    supports-color "^3.1.0"
-    which "^1.1.1"
-    wordwrap "^1.0.0"
-
-jison-lex@0.3.x:
-  version "0.3.4"
-  resolved "https://registry.yarnpkg.com/jison-lex/-/jison-lex-0.3.4.tgz#81ca28d84f84499dfa8c594dcde3d8a3f26ec7a5"
-  integrity sha1-gcoo2E+ESZ36jFlNzePYo/Jux6U=
-  dependencies:
-    lex-parser "0.1.x"
-    nomnom "1.5.2"
-
-jison@0.4.16:
-  version "0.4.16"
-  resolved "https://registry.yarnpkg.com/jison/-/jison-0.4.16.tgz#1337103f5949f0ed7159399426885ce10cc160b5"
-  integrity sha1-EzcQP1lJ8O1xWTmUJohc4QzBYLU=
-  dependencies:
-    JSONSelect "0.4.0"
-    cjson "0.3.0"
-    ebnf-parser "0.1.10"
-    escodegen "1.3.x"
-    esprima "1.1.x"
-    jison-lex "0.3.x"
-    lex-parser "~0.1.3"
-    nomnom "1.5.2"
-
-jmespath@0.15.0:
-  version "0.15.0"
-  resolved "https://registry.yarnpkg.com/jmespath/-/jmespath-0.15.0.tgz#a3f222a9aae9f966f5d27c796510e28091764217"
-  integrity sha1-o/Iiqarp+Wb10nx5ZRDigJF2Qhc=
-
-js-tokens@1.0.1:
-  version "1.0.1"
-  resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-1.0.1.tgz#cc435a5c8b94ad15acb7983140fc80182c89aeae"
-  integrity sha1-zENaXIuUrRWst5gxQPyAGCyJrq4=
-
-js-tokens@^3.0.2:
-  version "3.0.2"
-  resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b"
-  integrity sha1-mGbfOVECEw449/mWvOtlRDIJwls=
-
-js-tokens@^4.0.0:
-  version "4.0.0"
-  resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
-  integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==
-
-js-yaml@3.x, js-yaml@^3.13.1, js-yaml@^3.9.1, js-yaml@~3.13.0:
-  version "3.13.1"
-  resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847"
-  integrity sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==
-  dependencies:
-    argparse "^1.0.7"
-    esprima "^4.0.0"
-
-jsbn@~0.1.0:
-  version "0.1.1"
-  resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513"
-  integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM=
-
-jsesc@~0.5.0:
-  version "0.5.0"
-  resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d"
-  integrity sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=
-
-json-schema-traverse@^0.3.0:
-  version "0.3.1"
-  resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz#349a6d44c53a51de89b40805c5d5e59b417d3340"
-  integrity sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=
-
-json-schema-traverse@^0.4.1:
-  version "0.4.1"
-  resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660"
-  integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==
-
-json-schema@0.2.3:
-  version "0.2.3"
-  resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13"
-  integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=
-
-json-stable-stringify-without-jsonify@^1.0.1:
-  version "1.0.1"
-  resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651"
-  integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=
-
-json-stringify-safe@~5.0.1:
-  version "5.0.1"
-  resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb"
-  integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=
-
-json3@^3.3.2:
-  version "3.3.3"
-  resolved "https://registry.yarnpkg.com/json3/-/json3-3.3.3.tgz#7fc10e375fc5ae42c4705a5cc0aa6f62be305b81"
-  integrity sha512-c7/8mbUsKigAbLkD5B010BK4D9LZm7A1pNItkEwiUZRpIN66exu/e7YQWysGun+TRKaJp8MhemM+VkfWv42aCA==
-
-json5@^0.4.0:
-  version "0.4.0"
-  resolved "https://registry.yarnpkg.com/json5/-/json5-0.4.0.tgz#054352e4c4c80c86c0923877d449de176a732c8d"
-  integrity sha1-BUNS5MTIDIbAkjh31EneF2pzLI0=
-
-json5@^0.5.0:
-  version "0.5.1"
-  resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821"
-  integrity sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=
-
-jsonfile@^4.0.0:
-  version "4.0.0"
-  resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb"
-  integrity sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=
-  optionalDependencies:
-    graceful-fs "^4.1.6"
-
-jsonlint@1.6.0:
-  version "1.6.0"
-  resolved "https://registry.yarnpkg.com/jsonlint/-/jsonlint-1.6.0.tgz#88aa46bc289a7ac93bb46cae2d58a187a9bb494a"
-  integrity sha1-iKpGvCiaesk7tGyuLVihh6m7SUo=
-  dependencies:
-    JSV ">= 4.0.x"
-    nomnom ">= 1.5.x"
-
-jsprim@^1.2.2:
-  version "1.4.1"
-  resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2"
-  integrity sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=
-  dependencies:
-    assert-plus "1.0.0"
-    extsprintf "1.3.0"
-    json-schema "0.2.3"
-    verror "1.10.0"
-
-kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0:
-  version "3.2.2"
-  resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64"
-  integrity sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=
-  dependencies:
-    is-buffer "^1.1.5"
-
-kind-of@^4.0.0:
-  version "4.0.0"
-  resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57"
-  integrity sha1-IIE989cSkosgc3hpGkUGb65y3Vc=
-  dependencies:
-    is-buffer "^1.1.5"
-
-kind-of@^5.0.0:
-  version "5.1.0"
-  resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-5.1.0.tgz#729c91e2d857b7a419a1f9aa65685c4c33f5845d"
-  integrity sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==
-
-kind-of@^6.0.0, kind-of@^6.0.2:
-  version "6.0.2"
-  resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.2.tgz#01146b36a6218e64e58f3a8d66de5d7fc6f6d051"
-  integrity sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==
-
-lazy-cache@^1.0.3:
-  version "1.0.4"
-  resolved "https://registry.yarnpkg.com/lazy-cache/-/lazy-cache-1.0.4.tgz#a1d78fc3a50474cb80845d3b3b6e1da49a446e8e"
-  integrity sha1-odePw6UEdMuAhF07O24dpJpEbo4=
-
-lcid@^1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/lcid/-/lcid-1.0.0.tgz#308accafa0bc483a3867b4b6f2b9506251d1b835"
-  integrity sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=
-  dependencies:
-    invert-kv "^1.0.0"
-
-lcid@^2.0.0:
-  version "2.0.0"
-  resolved "https://registry.yarnpkg.com/lcid/-/lcid-2.0.0.tgz#6ef5d2df60e52f82eb228a4c373e8d1f397253cf"
-  integrity sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==
-  dependencies:
-    invert-kv "^2.0.0"
-
-leven@^1.0.2:
-  version "1.0.2"
-  resolved "https://registry.yarnpkg.com/leven/-/leven-1.0.2.tgz#9144b6eebca5f1d0680169f1a6770dcea60b75c3"
-  integrity sha1-kUS27ryl8dBoAWnxpncNzqYLdcM=
-
-levn@^0.3.0, levn@~0.3.0:
-  version "0.3.0"
-  resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee"
-  integrity sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=
-  dependencies:
-    prelude-ls "~1.1.2"
-    type-check "~0.3.2"
-
-levn@~0.2.5:
-  version "0.2.5"
-  resolved "https://registry.yarnpkg.com/levn/-/levn-0.2.5.tgz#ba8d339d0ca4a610e3a3f145b9caf48807155054"
-  integrity sha1-uo0znQykphDjo/FFucr0iAcVUFQ=
-  dependencies:
-    prelude-ls "~1.1.0"
-    type-check "~0.3.1"
-
-lex-parser@0.1.x, lex-parser@~0.1.3:
-  version "0.1.4"
-  resolved "https://registry.yarnpkg.com/lex-parser/-/lex-parser-0.1.4.tgz#64c4f025f17fd53bfb45763faeb16f015a747550"
-  integrity sha1-ZMTwJfF/1Tv7RXY/rrFvAVp0dVA=
-
-liftoff@~2.5.0:
-  version "2.5.0"
-  resolved "https://registry.yarnpkg.com/liftoff/-/liftoff-2.5.0.tgz#2009291bb31cea861bbf10a7c15a28caf75c31ec"
-  integrity sha1-IAkpG7Mc6oYbvxCnwVooyvdcMew=
-  dependencies:
-    extend "^3.0.0"
-    findup-sync "^2.0.0"
-    fined "^1.0.1"
-    flagged-respawn "^1.0.0"
-    is-plain-object "^2.0.4"
-    object.map "^1.0.0"
-    rechoir "^0.6.2"
-    resolve "^1.1.7"
-
-livereload-js@^2.3.0:
-  version "2.4.0"
-  resolved "https://registry.yarnpkg.com/livereload-js/-/livereload-js-2.4.0.tgz#447c31cf1ea9ab52fc20db615c5ddf678f78009c"
-  integrity sha512-XPQH8Z2GDP/Hwz2PCDrh2mth4yFejwA1OZ/81Ti3LgKyhDcEjsSsqFWZojHG0va/duGd+WyosY7eXLDoOyqcPw==
-
-load-json-file@^1.0.0:
-  version "1.1.0"
-  resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0"
-  integrity sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=
-  dependencies:
-    graceful-fs "^4.1.2"
-    parse-json "^2.2.0"
-    pify "^2.0.0"
-    pinkie-promise "^2.0.0"
-    strip-bom "^2.0.0"
-
-loader-utils@^0.2.11, loader-utils@^0.2.9:
-  version "0.2.17"
-  resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-0.2.17.tgz#f86e6374d43205a6e6c60e9196f17c0299bfb348"
-  integrity sha1-+G5jdNQyBabmxg6RlvF8Apm/s0g=
-  dependencies:
-    big.js "^3.1.3"
-    emojis-list "^2.0.0"
-    json5 "^0.5.0"
-    object-assign "^4.0.1"
-
-locate-path@^3.0.0:
-  version "3.0.0"
-  resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e"
-  integrity sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==
-  dependencies:
-    p-locate "^3.0.0"
-    path-exists "^3.0.0"
-
-lodash@^2.4.1:
-  version "2.4.2"
-  resolved "https://registry.yarnpkg.com/lodash/-/lodash-2.4.2.tgz#fadd834b9683073da179b3eae6d9c0d15053f73e"
-  integrity sha1-+t2DS5aDBz2hebPq5tnA0VBT9z4=
-
-lodash@^3.10.0, lodash@^3.9.3:
-  version "3.10.1"
-  resolved "https://registry.yarnpkg.com/lodash/-/lodash-3.10.1.tgz#5bf45e8e49ba4189e17d482789dfd15bd140b7b6"
-  integrity sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=
-
-lodash@^4.0.1, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.2, lodash@^4.17.4, lodash@^4.3.0, lodash@^4.7.0, lodash@~4.17.10, lodash@~4.17.5:
-  version "4.17.15"
-  resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548"
-  integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==
-
-longest@^1.0.1:
-  version "1.0.1"
-  resolved "https://registry.yarnpkg.com/longest/-/longest-1.0.1.tgz#30a0b2da38f73770e8294a0d22e6625ed77d0097"
-  integrity sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=
-
-loud-rejection@^1.0.0:
-  version "1.6.0"
-  resolved "https://registry.yarnpkg.com/loud-rejection/-/loud-rejection-1.6.0.tgz#5b46f80147edee578870f086d04821cf998e551f"
-  integrity sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=
-  dependencies:
-    currently-unhandled "^0.4.1"
-    signal-exit "^3.0.0"
-
-lru-cache@^4.0.1:
-  version "4.1.5"
-  resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.5.tgz#8bbe50ea85bed59bc9e33dcab8235ee9bcf443cd"
-  integrity sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==
-  dependencies:
-    pseudomap "^1.0.2"
-    yallist "^2.1.2"
-
-make-iterator@^1.0.0:
-  version "1.0.1"
-  resolved "https://registry.yarnpkg.com/make-iterator/-/make-iterator-1.0.1.tgz#29b33f312aa8f547c4a5e490f56afcec99133ad6"
-  integrity sha512-pxiuXh0iVEq7VM7KMIhs5gxsfxCux2URptUQaXo4iZZJxBAzTPOLE2BumO5dbfVYq/hBJFBR/a1mFDmOx5AGmw==
-  dependencies:
-    kind-of "^6.0.2"
-
-map-age-cleaner@^0.1.1:
-  version "0.1.3"
-  resolved "https://registry.yarnpkg.com/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz#7d583a7306434c055fe474b0f45078e6e1b4b92a"
-  integrity sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==
-  dependencies:
-    p-defer "^1.0.0"
-
-map-cache@^0.2.0, map-cache@^0.2.2:
-  version "0.2.2"
-  resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf"
-  integrity sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=
-
-map-obj@^1.0.0, map-obj@^1.0.1:
-  version "1.0.1"
-  resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d"
-  integrity sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=
-
-map-visit@^1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f"
-  integrity sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=
-  dependencies:
-    object-visit "^1.0.0"
-
-math-random@^1.0.1:
-  version "1.0.4"
-  resolved "https://registry.yarnpkg.com/math-random/-/math-random-1.0.4.tgz#5dd6943c938548267016d4e34f057583080c514c"
-  integrity sha512-rUxjysqif/BZQH2yhd5Aaq7vXMSx9NdEsQcyA07uEzIvxgI7zIr33gGsh+RU0/XjmQpCW7RsVof1vlkvQVCK5A==
-
-maxmin@^1.1.0:
-  version "1.1.0"
-  resolved "https://registry.yarnpkg.com/maxmin/-/maxmin-1.1.0.tgz#71365e84a99dd8f8b3f7d5fde2f00d1e7f73be61"
-  integrity sha1-cTZehKmd2Piz99X94vANHn9zvmE=
-  dependencies:
-    chalk "^1.0.0"
-    figures "^1.0.1"
-    gzip-size "^1.0.0"
-    pretty-bytes "^1.0.0"
-
-media-typer@0.3.0:
-  version "0.3.0"
-  resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748"
-  integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=
-
-mem@^4.0.0:
-  version "4.3.0"
-  resolved "https://registry.yarnpkg.com/mem/-/mem-4.3.0.tgz#461af497bc4ae09608cdb2e60eefb69bff744178"
-  integrity sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w==
-  dependencies:
-    map-age-cleaner "^0.1.1"
-    mimic-fn "^2.0.0"
-    p-is-promise "^2.0.0"
-
-memory-fs@^0.2.0:
-  version "0.2.0"
-  resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.2.0.tgz#f2bb25368bc121e391c2520de92969caee0a0290"
-  integrity sha1-8rslNovBIeORwlIN6Slpyu4KApA=
-
-memory-fs@~0.3.0:
-  version "0.3.0"
-  resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.3.0.tgz#7bcc6b629e3a43e871d7e29aca6ae8a7f15cbb20"
-  integrity sha1-e8xrYp46Q+hx1+Kaymrop/FcuyA=
-  dependencies:
-    errno "^0.1.3"
-    readable-stream "^2.0.1"
-
-memory-fs@~0.4.1:
-  version "0.4.1"
-  resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.4.1.tgz#3a9a20b8462523e447cfbc7e8bb80ed667bfc552"
-  integrity sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=
-  dependencies:
-    errno "^0.1.3"
-    readable-stream "^2.0.1"
-
-meow@^3.1.0, meow@^3.3.0:
-  version "3.7.0"
-  resolved "https://registry.yarnpkg.com/meow/-/meow-3.7.0.tgz#72cb668b425228290abbfa856892587308a801fb"
-  integrity sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=
-  dependencies:
-    camelcase-keys "^2.0.0"
-    decamelize "^1.1.2"
-    loud-rejection "^1.0.0"
-    map-obj "^1.0.1"
-    minimist "^1.1.3"
-    normalize-package-data "^2.3.4"
-    object-assign "^4.0.1"
-    read-pkg-up "^1.0.1"
-    redent "^1.0.0"
-    trim-newlines "^1.0.0"
-
-merge-descriptors@1.0.1:
-  version "1.0.1"
-  resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61"
-  integrity sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=
-
-methods@~1.1.2:
-  version "1.1.2"
-  resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee"
-  integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=
-
-micromatch@^2.1.5, micromatch@^2.3.11:
-  version "2.3.11"
-  resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-2.3.11.tgz#86677c97d1720b363431d04d0d15293bd38c1565"
-  integrity sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=
-  dependencies:
-    arr-diff "^2.0.0"
-    array-unique "^0.2.1"
-    braces "^1.8.2"
-    expand-brackets "^0.1.4"
-    extglob "^0.3.1"
-    filename-regex "^2.0.0"
-    is-extglob "^1.0.0"
-    is-glob "^2.0.1"
-    kind-of "^3.0.2"
-    normalize-path "^2.0.1"
-    object.omit "^2.0.0"
-    parse-glob "^3.0.4"
-    regex-cache "^0.4.2"
-
-micromatch@^3.0.4, micromatch@^3.1.10:
-  version "3.1.10"
-  resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23"
-  integrity sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==
-  dependencies:
-    arr-diff "^4.0.0"
-    array-unique "^0.3.2"
-    braces "^2.3.1"
-    define-property "^2.0.2"
-    extend-shallow "^3.0.2"
-    extglob "^2.0.4"
-    fragment-cache "^0.2.1"
-    kind-of "^6.0.2"
-    nanomatch "^1.2.9"
-    object.pick "^1.3.0"
-    regex-not "^1.0.0"
-    snapdragon "^0.8.1"
-    to-regex "^3.0.2"
-
-mime-db@1.40.0:
-  version "1.40.0"
-  resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.40.0.tgz#a65057e998db090f732a68f6c276d387d4126c32"
-  integrity sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==
-
-"mime-db@>= 1.40.0 < 2":
-  version "1.42.0"
-  resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.42.0.tgz#3e252907b4c7adb906597b4b65636272cf9e7bac"
-  integrity sha512-UbfJCR4UAVRNgMpfImz05smAXK7+c+ZntjaA26ANtkXLlOe947Aag5zdIcKQULAiF9Cq4WxBi9jUs5zkA84bYQ==
-
-mime-types@^2.1.12, mime-types@~2.1.17, mime-types@~2.1.19, mime-types@~2.1.24:
-  version "2.1.24"
-  resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.24.tgz#b6f8d0b3e951efb77dedeca194cff6d16f676f81"
-  integrity sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==
-  dependencies:
-    mime-db "1.40.0"
-
-mime@1.6.0, mime@^1.5.0:
-  version "1.6.0"
-  resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1"
-  integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==
-
-mimic-fn@^1.0.0:
-  version "1.2.0"
-  resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022"
-  integrity sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==
-
-mimic-fn@^2.0.0:
-  version "2.1.0"
-  resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b"
-  integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==
-
-"minimatch@2 || 3", minimatch@3.0.4, minimatch@^3.0.2, minimatch@^3.0.4, minimatch@~3.0.2:
-  version "3.0.4"
-  resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
-  integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==
-  dependencies:
-    brace-expansion "^1.1.7"
-
-minimatch@2.x, minimatch@^2.0.3:
-  version "2.0.10"
-  resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-2.0.10.tgz#8d087c39c6b38c001b97fca7ce6d0e1e80afbac7"
-  integrity sha1-jQh8OcazjAAbl/ynzm0OHoCvusc=
-  dependencies:
-    brace-expansion "^1.0.0"
-
-minimist@0.0.8:
-  version "0.0.8"
-  resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d"
-  integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=
-
-minimist@^1.1.0, minimist@^1.1.3, minimist@^1.2.0:
-  version "1.2.0"
-  resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284"
-  integrity sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=
-
-minimist@~0.0.1:
-  version "0.0.10"
-  resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.10.tgz#de3f98543dbf96082be48ad1a0c7cda836301dcf"
-  integrity sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=
-
-minipass@^2.6.0, minipass@^2.8.6, minipass@^2.9.0:
-  version "2.9.0"
-  resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.9.0.tgz#e713762e7d3e32fed803115cf93e04bca9fcc9a6"
-  integrity sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==
-  dependencies:
-    safe-buffer "^5.1.2"
-    yallist "^3.0.0"
-
-minizlib@^1.2.1:
-  version "1.3.3"
-  resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.3.3.tgz#2290de96818a34c29551c8a8d301216bd65a861d"
-  integrity sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==
-  dependencies:
-    minipass "^2.9.0"
-
-mixin-deep@^1.2.0:
-  version "1.3.2"
-  resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.2.tgz#1120b43dc359a785dce65b55b82e257ccf479566"
-  integrity sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==
-  dependencies:
-    for-in "^1.0.2"
-    is-extendable "^1.0.1"
-
-mkdirp@0.5.1, mkdirp@0.5.x, mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.0, mkdirp@~0.5.1:
-  version "0.5.1"
-  resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903"
-  integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=
-  dependencies:
-    minimist "0.0.8"
-
-mocha@^5:
-  version "5.2.0"
-  resolved "https://registry.yarnpkg.com/mocha/-/mocha-5.2.0.tgz#6d8ae508f59167f940f2b5b3c4a612ae50c90ae6"
-  integrity sha512-2IUgKDhc3J7Uug+FxMXuqIyYzH7gJjXECKe/w43IGgQHTSj3InJi+yAA7T24L9bQMRKiUEHxEX37G5JpVUGLcQ==
-  dependencies:
-    browser-stdout "1.3.1"
-    commander "2.15.1"
-    debug "3.1.0"
-    diff "3.5.0"
-    escape-string-regexp "1.0.5"
-    glob "7.1.2"
-    growl "1.10.5"
-    he "1.1.1"
-    minimatch "3.0.4"
-    mkdirp "0.5.1"
-    supports-color "5.4.0"
-
-mock-stdin@^0.3.0:
-  version "0.3.1"
-  resolved "https://registry.yarnpkg.com/mock-stdin/-/mock-stdin-0.3.1.tgz#c657d9642d90786435c64ca5e99bbd4d09bd7dd3"
-  integrity sha1-xlfZZC2QeGQ1xkyl6Zu9TQm9fdM=
-
-morgan@^1.6.1:
-  version "1.9.1"
-  resolved "https://registry.yarnpkg.com/morgan/-/morgan-1.9.1.tgz#0a8d16734a1d9afbc824b99df87e738e58e2da59"
-  integrity sha512-HQStPIV4y3afTiCYVxirakhlCfGkI161c76kKFca7Fk1JusM//Qeo1ej2XaMniiNeaZklMVrh3vTtIzpzwbpmA==
-  dependencies:
-    basic-auth "~2.0.0"
-    debug "2.6.9"
-    depd "~1.1.2"
-    on-finished "~2.3.0"
-    on-headers "~1.0.1"
-
-ms@2.0.0:
-  version "2.0.0"
-  resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
-  integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=
-
-ms@2.1.1:
-  version "2.1.1"
-  resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a"
-  integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==
-
-ms@^2.1.1:
-  version "2.1.2"
-  resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009"
-  integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
-
-mustache@^2.1.3:
-  version "2.3.2"
-  resolved "https://registry.yarnpkg.com/mustache/-/mustache-2.3.2.tgz#a6d4d9c3f91d13359ab889a812954f9230a3d0c5"
-  integrity sha512-KpMNwdQsYz3O/SBS1qJ/o3sqUJ5wSb8gb0pul8CO0S56b9Y2ALm8zCfsjPXsqGFfoNBkDwZuZIAjhsZI03gYVQ==
-
-mute-stream@0.0.7:
-  version "0.0.7"
-  resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab"
-  integrity sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=
-
-nan@^2.12.1:
-  version "2.14.0"
-  resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.0.tgz#7818f722027b2459a86f0295d434d1fc2336c52c"
-  integrity sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==
-
-nanomatch@^1.2.9:
-  version "1.2.13"
-  resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119"
-  integrity sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==
-  dependencies:
-    arr-diff "^4.0.0"
-    array-unique "^0.3.2"
-    define-property "^2.0.2"
-    extend-shallow "^3.0.2"
-    fragment-cache "^0.2.1"
-    is-windows "^1.0.2"
-    kind-of "^6.0.2"
-    object.pick "^1.3.0"
-    regex-not "^1.0.0"
-    snapdragon "^0.8.1"
-    to-regex "^3.0.1"
-
-natural-compare@^1.4.0:
-  version "1.4.0"
-  resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7"
-  integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=
-
-needle@^2.2.1:
-  version "2.4.0"
-  resolved "https://registry.yarnpkg.com/needle/-/needle-2.4.0.tgz#6833e74975c444642590e15a750288c5f939b57c"
-  integrity sha512-4Hnwzr3mi5L97hMYeNl8wRW/Onhy4nUKR/lVemJ8gJedxxUyBLm9kkrDColJvoSfwi0jCNhD+xCdOtiGDQiRZg==
-  dependencies:
-    debug "^3.2.6"
-    iconv-lite "^0.4.4"
-    sax "^1.2.4"
-
-negotiator@0.6.2:
-  version "0.6.2"
-  resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb"
-  integrity sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==
-
-neo-async@^2.6.0:
-  version "2.6.1"
-  resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.1.tgz#ac27ada66167fa8849a6addd837f6b189ad2081c"
-  integrity sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==
-
-nice-try@^1.0.4:
-  version "1.0.5"
-  resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366"
-  integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==
-
-node-libs-browser@^0.7.0:
-  version "0.7.0"
-  resolved "https://registry.yarnpkg.com/node-libs-browser/-/node-libs-browser-0.7.0.tgz#3e272c0819e308935e26674408d7af0e1491b83b"
-  integrity sha1-PicsCBnjCJNeJmdECNevDhSRuDs=
-  dependencies:
-    assert "^1.1.1"
-    browserify-zlib "^0.1.4"
-    buffer "^4.9.0"
-    console-browserify "^1.1.0"
-    constants-browserify "^1.0.0"
-    crypto-browserify "3.3.0"
-    domain-browser "^1.1.1"
-    events "^1.0.0"
-    https-browserify "0.0.1"
-    os-browserify "^0.2.0"
-    path-browserify "0.0.0"
-    process "^0.11.0"
-    punycode "^1.2.4"
-    querystring-es3 "^0.2.0"
-    readable-stream "^2.0.5"
-    stream-browserify "^2.0.1"
-    stream-http "^2.3.1"
-    string_decoder "^0.10.25"
-    timers-browserify "^2.0.2"
-    tty-browserify "0.0.0"
-    url "^0.11.0"
-    util "^0.10.3"
-    vm-browserify "0.0.4"
-
-node-pre-gyp@^0.12.0:
-  version "0.12.0"
-  resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.12.0.tgz#39ba4bb1439da030295f899e3b520b7785766149"
-  integrity sha512-4KghwV8vH5k+g2ylT+sLTjy5wmUOb9vPhnM8NHvRf9dHmnW/CndrFXy2aRPaPST6dugXSdHXfeaHQm77PIz/1A==
-  dependencies:
-    detect-libc "^1.0.2"
-    mkdirp "^0.5.1"
-    needle "^2.2.1"
-    nopt "^4.0.1"
-    npm-packlist "^1.1.6"
-    npmlog "^4.0.2"
-    rc "^1.2.7"
-    rimraf "^2.6.1"
-    semver "^5.3.0"
-    tar "^4"
-
-nomnom@1.5.2:
-  version "1.5.2"
-  resolved "https://registry.yarnpkg.com/nomnom/-/nomnom-1.5.2.tgz#f4345448a853cfbd5c0d26320f2477ab0526fe2f"
-  integrity sha1-9DRUSKhTz71cDSYyDyR3qwUm/i8=
-  dependencies:
-    colors "0.5.x"
-    underscore "1.1.x"
-
-"nomnom@>= 1.5.x":
-  version "1.8.1"
-  resolved "https://registry.yarnpkg.com/nomnom/-/nomnom-1.8.1.tgz#2151f722472ba79e50a76fc125bb8c8f2e4dc2a7"
-  integrity sha1-IVH3Ikcrp55Qp2/BJbuMjy5Nwqc=
-  dependencies:
-    chalk "~0.4.0"
-    underscore "~1.6.0"
-
-nopt@3.x, nopt@~3.0.6:
-  version "3.0.6"
-  resolved "https://registry.yarnpkg.com/nopt/-/nopt-3.0.6.tgz#c6465dbf08abcd4db359317f79ac68a646b28ff9"
-  integrity sha1-xkZdvwirzU2zWTF/eaxopkayj/k=
-  dependencies:
-    abbrev "1"
-
-nopt@^4.0.1, nopt@~4.0.1:
-  version "4.0.1"
-  resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.1.tgz#d0d4685afd5415193c8c7505602d0d17cd64474d"
-  integrity sha1-0NRoWv1UFRk8jHUFYC0NF81kR00=
-  dependencies:
-    abbrev "1"
-    osenv "^0.1.4"
-
-normalize-package-data@^2.3.2, normalize-package-data@^2.3.4:
-  version "2.5.0"
-  resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8"
-  integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==
-  dependencies:
-    hosted-git-info "^2.1.4"
-    resolve "^1.10.0"
-    semver "2 || 3 || 4 || 5"
-    validate-npm-package-license "^3.0.1"
-
-normalize-path@^2.0.0, normalize-path@^2.0.1:
-  version "2.1.1"
-  resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9"
-  integrity sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=
-  dependencies:
-    remove-trailing-separator "^1.0.1"
-
-npm-bundled@^1.0.1:
-  version "1.0.6"
-  resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.0.6.tgz#e7ba9aadcef962bb61248f91721cd932b3fe6bdd"
-  integrity sha512-8/JCaftHwbd//k6y2rEWp6k1wxVfpFzB6t1p825+cUb7Ym2XQfhwIC5KwhrvzZRJu+LtDE585zVaS32+CGtf0g==
-
-npm-packlist@^1.1.6:
-  version "1.4.6"
-  resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-1.4.6.tgz#53ba3ed11f8523079f1457376dd379ee4ea42ff4"
-  integrity sha512-u65uQdb+qwtGvEJh/DgQgW1Xg7sqeNbmxYyrvlNznaVTjV3E5P6F/EFjM+BVHXl7JJlsdG8A64M0XI8FI/IOlg==
-  dependencies:
-    ignore-walk "^3.0.1"
-    npm-bundled "^1.0.1"
-
-npm-run-path@^2.0.0:
-  version "2.0.2"
-  resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f"
-  integrity sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=
-  dependencies:
-    path-key "^2.0.0"
-
-npmlog@^4.0.2:
-  version "4.1.2"
-  resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b"
-  integrity sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==
-  dependencies:
-    are-we-there-yet "~1.1.2"
-    console-control-strings "~1.1.0"
-    gauge "~2.7.3"
-    set-blocking "~2.0.0"
-
-number-is-nan@^1.0.0:
-  version "1.0.1"
-  resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d"
-  integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=
-
-oauth-sign@~0.9.0:
-  version "0.9.0"
-  resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455"
-  integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==
-
-object-assign@^3.0.0:
-  version "3.0.0"
-  resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-3.0.0.tgz#9bedd5ca0897949bca47e7ff408062d549f587f2"
-  integrity sha1-m+3VygiXlJvKR+f/QIBi1Un1h/I=
-
-object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1:
-  version "4.1.1"
-  resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
-  integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=
-
-object-copy@^0.1.0:
-  version "0.1.0"
-  resolved "https://registry.yarnpkg.com/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c"
-  integrity sha1-fn2Fi3gb18mRpBupde04EnVOmYw=
-  dependencies:
-    copy-descriptor "^0.1.0"
-    define-property "^0.2.5"
-    kind-of "^3.0.3"
-
-object-visit@^1.0.0:
-  version "1.0.1"
-  resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb"
-  integrity sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=
-  dependencies:
-    isobject "^3.0.0"
-
-object.defaults@^1.1.0:
-  version "1.1.0"
-  resolved "https://registry.yarnpkg.com/object.defaults/-/object.defaults-1.1.0.tgz#3a7f868334b407dea06da16d88d5cd29e435fecf"
-  integrity sha1-On+GgzS0B96gbaFtiNXNKeQ1/s8=
-  dependencies:
-    array-each "^1.0.1"
-    array-slice "^1.0.0"
-    for-own "^1.0.0"
-    isobject "^3.0.0"
-
-object.map@^1.0.0:
-  version "1.0.1"
-  resolved "https://registry.yarnpkg.com/object.map/-/object.map-1.0.1.tgz#cf83e59dc8fcc0ad5f4250e1f78b3b81bd801d37"
-  integrity sha1-z4Plncj8wK1fQlDh94s7gb2AHTc=
-  dependencies:
-    for-own "^1.0.0"
-    make-iterator "^1.0.0"
-
-object.omit@^2.0.0:
-  version "2.0.1"
-  resolved "https://registry.yarnpkg.com/object.omit/-/object.omit-2.0.1.tgz#1a9c744829f39dbb858c76ca3579ae2a54ebd1fa"
-  integrity sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=
-  dependencies:
-    for-own "^0.1.4"
-    is-extendable "^0.1.1"
-
-object.pick@^1.2.0, object.pick@^1.3.0:
-  version "1.3.0"
-  resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747"
-  integrity sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=
-  dependencies:
-    isobject "^3.0.1"
-
-on-finished@~2.3.0:
-  version "2.3.0"
-  resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947"
-  integrity sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=
-  dependencies:
-    ee-first "1.1.1"
-
-on-headers@~1.0.1, on-headers@~1.0.2:
-  version "1.0.2"
-  resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.2.tgz#772b0ae6aaa525c399e489adfad90c403eb3c28f"
-  integrity sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==
-
-once@1.x, once@^1.3.0, once@^1.3.1, once@^1.4.0:
-  version "1.4.0"
-  resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
-  integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E=
-  dependencies:
-    wrappy "1"
-
-onetime@^2.0.0:
-  version "2.0.1"
-  resolved "https://registry.yarnpkg.com/onetime/-/onetime-2.0.1.tgz#067428230fd67443b2794b22bba528b6867962d4"
-  integrity sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=
-  dependencies:
-    mimic-fn "^1.0.0"
-
-open@0.0.5:
-  version "0.0.5"
-  resolved "https://registry.yarnpkg.com/open/-/open-0.0.5.tgz#42c3e18ec95466b6bf0dc42f3a2945c3f0cad8fc"
-  integrity sha1-QsPhjslUZra/DcQvOilFw/DK2Pw=
-
-opn@^4.0.0:
-  version "4.0.2"
-  resolved "https://registry.yarnpkg.com/opn/-/opn-4.0.2.tgz#7abc22e644dff63b0a96d5ab7f2790c0f01abc95"
-  integrity sha1-erwi5kTf9jsKltWrfyeQwPAavJU=
-  dependencies:
-    object-assign "^4.0.1"
-    pinkie-promise "^2.0.0"
-
-optimist@^0.6.1, optimist@~0.6.0, optimist@~0.6.1:
-  version "0.6.1"
-  resolved "https://registry.yarnpkg.com/optimist/-/optimist-0.6.1.tgz#da3ea74686fa21a19a111c326e90eb15a0196686"
-  integrity sha1-2j6nRob6IaGaERwybpDrFaAZZoY=
-  dependencies:
-    minimist "~0.0.1"
-    wordwrap "~0.0.2"
-
-optionator@^0.5.0:
-  version "0.5.0"
-  resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.5.0.tgz#b75a8995a2d417df25b6e4e3862f50aa88651368"
-  integrity sha1-t1qJlaLUF98ltuTjhi9QqohlE2g=
-  dependencies:
-    deep-is "~0.1.2"
-    fast-levenshtein "~1.0.0"
-    levn "~0.2.5"
-    prelude-ls "~1.1.1"
-    type-check "~0.3.1"
-    wordwrap "~0.0.2"
-
-optionator@^0.8.2:
-  version "0.8.2"
-  resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.2.tgz#364c5e409d3f4d6301d6c0b4c05bba50180aeb64"
-  integrity sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=
-  dependencies:
-    deep-is "~0.1.3"
-    fast-levenshtein "~2.0.4"
-    levn "~0.3.0"
-    prelude-ls "~1.1.2"
-    type-check "~0.3.2"
-    wordwrap "~1.0.0"
-
-original@^1.0.0:
-  version "1.0.2"
-  resolved "https://registry.yarnpkg.com/original/-/original-1.0.2.tgz#e442a61cffe1c5fd20a65f3261c26663b303f25f"
-  integrity sha512-hyBVl6iqqUOJ8FqRe+l/gS8H+kKYjrEndd5Pm1MfBtsEKA038HkkdbAl/72EAXGyonD/PFsvmVG+EvcIpliMBg==
-  dependencies:
-    url-parse "^1.4.3"
-
-os-browserify@^0.2.0:
-  version "0.2.1"
-  resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.2.1.tgz#63fc4ccee5d2d7763d26bbf8601078e6c2e0044f"
-  integrity sha1-Y/xMzuXS13Y9Jrv4YBB45sLgBE8=
-
-os-homedir@^1.0.0:
-  version "1.0.2"
-  resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3"
-  integrity sha1-/7xJiDNuDoM94MFox+8VISGqf7M=
-
-os-locale@^1.4.0:
-  version "1.4.0"
-  resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-1.4.0.tgz#20f9f17ae29ed345e8bde583b13d2009803c14d9"
-  integrity sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=
-  dependencies:
-    lcid "^1.0.0"
-
-os-locale@^3.0.0:
-  version "3.1.0"
-  resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-3.1.0.tgz#a802a6ee17f24c10483ab9935719cef4ed16bf1a"
-  integrity sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==
-  dependencies:
-    execa "^1.0.0"
-    lcid "^2.0.0"
-    mem "^4.0.0"
-
-os-tmpdir@^1.0.0, os-tmpdir@^1.0.1, os-tmpdir@~1.0.2:
-  version "1.0.2"
-  resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274"
-  integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=
-
-osenv@^0.1.4:
-  version "0.1.5"
-  resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.5.tgz#85cdfafaeb28e8677f416e287592b5f3f49ea410"
-  integrity sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==
-  dependencies:
-    os-homedir "^1.0.0"
-    os-tmpdir "^1.0.0"
-
-output-file-sync@^1.1.0:
-  version "1.1.2"
-  resolved "https://registry.yarnpkg.com/output-file-sync/-/output-file-sync-1.1.2.tgz#d0a33eefe61a205facb90092e826598d5245ce76"
-  integrity sha1-0KM+7+YaIF+suQCS6CZZjVJFznY=
-  dependencies:
-    graceful-fs "^4.1.4"
-    mkdirp "^0.5.1"
-    object-assign "^4.1.0"
-
-p-defer@^1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/p-defer/-/p-defer-1.0.0.tgz#9f6eb182f6c9aa8cd743004a7d4f96b196b0fb0c"
-  integrity sha1-n26xgvbJqozXQwBKfU+WsZaw+ww=
-
-p-finally@^1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae"
-  integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=
-
-p-is-promise@^2.0.0:
-  version "2.1.0"
-  resolved "https://registry.yarnpkg.com/p-is-promise/-/p-is-promise-2.1.0.tgz#918cebaea248a62cf7ffab8e3bca8c5f882fc42e"
-  integrity sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg==
-
-p-limit@^2.0.0:
-  version "2.2.1"
-  resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.2.1.tgz#aa07a788cc3151c939b5131f63570f0dd2009537"
-  integrity sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg==
-  dependencies:
-    p-try "^2.0.0"
-
-p-locate@^3.0.0:
-  version "3.0.0"
-  resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4"
-  integrity sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==
-  dependencies:
-    p-limit "^2.0.0"
-
-p-try@^2.0.0:
-  version "2.2.0"
-  resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6"
-  integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==
-
-pako@~0.2.0:
-  version "0.2.9"
-  resolved "https://registry.yarnpkg.com/pako/-/pako-0.2.9.tgz#f3f7522f4ef782348da8161bad9ecfd51bf83a75"
-  integrity sha1-8/dSL073gjSNqBYbrZ7P1Rv4OnU=
-
-parse-filepath@^1.0.1:
-  version "1.0.2"
-  resolved "https://registry.yarnpkg.com/parse-filepath/-/parse-filepath-1.0.2.tgz#a632127f53aaf3d15876f5872f3ffac763d6c891"
-  integrity sha1-pjISf1Oq89FYdvWHLz/6x2PWyJE=
-  dependencies:
-    is-absolute "^1.0.0"
-    map-cache "^0.2.0"
-    path-root "^0.1.1"
-
-parse-glob@^3.0.4:
-  version "3.0.4"
-  resolved "https://registry.yarnpkg.com/parse-glob/-/parse-glob-3.0.4.tgz#b2c376cfb11f35513badd173ef0bb6e3a388391c"
-  integrity sha1-ssN2z7EfNVE7rdFz7wu246OIORw=
-  dependencies:
-    glob-base "^0.3.0"
-    is-dotfile "^1.0.0"
-    is-extglob "^1.0.0"
-    is-glob "^2.0.0"
-
-parse-json@^2.2.0:
-  version "2.2.0"
-  resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9"
-  integrity sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=
-  dependencies:
-    error-ex "^1.2.0"
-
-parse-passwd@^1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/parse-passwd/-/parse-passwd-1.0.0.tgz#6d5b934a456993b23d37f40a382d6f1666a8e5c6"
-  integrity sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=
-
-parseurl@~1.3.2, parseurl@~1.3.3:
-  version "1.3.3"
-  resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4"
-  integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==
-
-parsimmon@^1.2.0:
-  version "1.13.0"
-  resolved "https://registry.yarnpkg.com/parsimmon/-/parsimmon-1.13.0.tgz#6e4ef3dbd45ed6ea6808be600ac4b9c8a44228cf"
-  integrity sha512-5UIrOCW+gjbILkjKPgTgmq8LKf8TT3Iy7kN2VD7OtQ81facKn8B4gG1X94jWqXYZsxG2KbJhrv/Yq/5H6BQn7A==
-
-pascalcase@^0.1.1:
-  version "0.1.1"
-  resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14"
-  integrity sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=
-
-path-browserify@0.0.0:
-  version "0.0.0"
-  resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-0.0.0.tgz#a0b870729aae214005b7d5032ec2cbbb0fb4451a"
-  integrity sha1-oLhwcpquIUAFt9UDLsLLuw+0RRo=
-
-path-exists@^1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-1.0.0.tgz#d5a8998eb71ef37a74c34eb0d9eba6e878eea081"
-  integrity sha1-1aiZjrce83p0w06w2eum6HjuoIE=
-
-path-exists@^2.0.0:
-  version "2.1.0"
-  resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b"
-  integrity sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=
-  dependencies:
-    pinkie-promise "^2.0.0"
-
-path-exists@^3.0.0:
-  version "3.0.0"
-  resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515"
-  integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=
-
-path-is-absolute@^1.0.0, path-is-absolute@~1.0.0:
-  version "1.0.1"
-  resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
-  integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18=
-
-path-is-inside@^1.0.2:
-  version "1.0.2"
-  resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53"
-  integrity sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=
-
-path-key@^2.0.0, path-key@^2.0.1:
-  version "2.0.1"
-  resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40"
-  integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=
-
-path-parse@^1.0.6:
-  version "1.0.6"
-  resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c"
-  integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==
-
-path-root-regex@^0.1.0:
-  version "0.1.2"
-  resolved "https://registry.yarnpkg.com/path-root-regex/-/path-root-regex-0.1.2.tgz#bfccdc8df5b12dc52c8b43ec38d18d72c04ba96d"
-  integrity sha1-v8zcjfWxLcUsi0PsONGNcsBLqW0=
-
-path-root@^0.1.1:
-  version "0.1.1"
-  resolved "https://registry.yarnpkg.com/path-root/-/path-root-0.1.1.tgz#9a4a6814cac1c0cd73360a95f32083c8ea4745b7"
-  integrity sha1-mkpoFMrBwM1zNgqV8yCDyOpHRbc=
-  dependencies:
-    path-root-regex "^0.1.0"
-
-path-to-regexp@0.1.7:
-  version "0.1.7"
-  resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c"
-  integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=
-
-path-type@^1.0.0:
-  version "1.1.0"
-  resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441"
-  integrity sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=
-  dependencies:
-    graceful-fs "^4.1.2"
-    pify "^2.0.0"
-    pinkie-promise "^2.0.0"
-
-pbkdf2-compat@2.0.1:
-  version "2.0.1"
-  resolved "https://registry.yarnpkg.com/pbkdf2-compat/-/pbkdf2-compat-2.0.1.tgz#b6e0c8fa99494d94e0511575802a59a5c142f288"
-  integrity sha1-tuDI+plJTZTgURV1gCpZpcFC8og=
-
-performance-now@^2.1.0:
-  version "2.1.0"
-  resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b"
-  integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=
-
-pify@^2.0.0:
-  version "2.3.0"
-  resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c"
-  integrity sha1-7RQaasBDqEnqWISY59yosVMw6Qw=
-
-pinkie-promise@^2.0.0:
-  version "2.0.1"
-  resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa"
-  integrity sha1-ITXW36ejWMBprJsXh3YogihFD/o=
-  dependencies:
-    pinkie "^2.0.0"
-
-pinkie@^2.0.0:
-  version "2.0.4"
-  resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870"
-  integrity sha1-clVrgM+g1IqXToDnckjoDtT3+HA=
-
-pluralize@^7.0.0:
-  version "7.0.0"
-  resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-7.0.0.tgz#298b89df8b93b0221dbf421ad2b1b1ea23fc6777"
-  integrity sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow==
-
-portscanner@^1.0.0:
-  version "1.2.0"
-  resolved "https://registry.yarnpkg.com/portscanner/-/portscanner-1.2.0.tgz#b14bbda257d14c310fa9cc09682af02d40961802"
-  integrity sha1-sUu9olfRTDEPqcwJaCrwLUCWGAI=
-  dependencies:
-    async "1.5.2"
-
-posix-character-classes@^0.1.0:
-  version "0.1.1"
-  resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab"
-  integrity sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=
-
-prelude-ls@~1.1.0, prelude-ls@~1.1.1, prelude-ls@~1.1.2:
-  version "1.1.2"
-  resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54"
-  integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=
-
-preserve@^0.2.0:
-  version "0.2.0"
-  resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b"
-  integrity sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=
-
-pretty-bytes@^1.0.0:
-  version "1.0.4"
-  resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-1.0.4.tgz#0a22e8210609ad35542f8c8d5d2159aff0751c84"
-  integrity sha1-CiLoIQYJrTVUL4yNXSFZr/B1HIQ=
-  dependencies:
-    get-stdin "^4.0.1"
-    meow "^3.1.0"
-
-private@^0.1.6, private@~0.1.5:
-  version "0.1.8"
-  resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff"
-  integrity sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==
-
-process-nextick-args@~2.0.0:
-  version "2.0.1"
-  resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2"
-  integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==
-
-process@^0.11.0:
-  version "0.11.10"
-  resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182"
-  integrity sha1-czIwDoQBYb2j5podHZGn1LwW8YI=
-
-progress@^2.0.0:
-  version "2.0.3"
-  resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8"
-  integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==
-
-proxy-addr@~2.0.5:
-  version "2.0.5"
-  resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.5.tgz#34cbd64a2d81f4b1fd21e76f9f06c8a45299ee34"
-  integrity sha512-t/7RxHXPH6cJtP0pRG6smSr9QJidhB+3kXu0KgXnbGYMgzEnUxRQ4/LDdfOwZEMyIh3/xHb8PX3t+lfL9z+YVQ==
-  dependencies:
-    forwarded "~0.1.2"
-    ipaddr.js "1.9.0"
-
-prr@~1.0.1:
-  version "1.0.1"
-  resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476"
-  integrity sha1-0/wRS6BplaRexok/SEzrHXj19HY=
-
-pseudomap@^1.0.2:
-  version "1.0.2"
-  resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3"
-  integrity sha1-8FKijacOYYkX7wqKw0wa5aaChrM=
-
-psl@^1.1.24:
-  version "1.4.0"
-  resolved "https://registry.yarnpkg.com/psl/-/psl-1.4.0.tgz#5dd26156cdb69fa1fdb8ab1991667d3f80ced7c2"
-  integrity sha512-HZzqCGPecFLyoRj5HLfuDSKYTJkAfB5thKBIkRHtGjWwY7p1dAyveIbXIq4tO0KYfDF2tHqPUgY9SDnGm00uFw==
-
-pump@^3.0.0:
-  version "3.0.0"
-  resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64"
-  integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==
-  dependencies:
-    end-of-stream "^1.1.0"
-    once "^1.3.1"
-
-punycode@1.3.2:
-  version "1.3.2"
-  resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d"
-  integrity sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=
-
-punycode@^1.2.4, punycode@^1.4.1:
-  version "1.4.1"
-  resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e"
-  integrity sha1-wNWmOycYgArY4esPpSachN1BhF4=
-
-punycode@^2.1.0:
-  version "2.1.1"
-  resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec"
-  integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==
-
-q@^1.1.2:
-  version "1.5.1"
-  resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7"
-  integrity sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=
-
-q@~1.4.1:
-  version "1.4.1"
-  resolved "https://registry.yarnpkg.com/q/-/q-1.4.1.tgz#55705bcd93c5f3673530c2c2cbc0c2b3addc286e"
-  integrity sha1-VXBbzZPF82c1MMLCy8DCs63cKG4=
-
-qs@6.7.0:
-  version "6.7.0"
-  resolved "https://registry.yarnpkg.com/qs/-/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc"
-  integrity sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==
-
-qs@^6.4.0:
-  version "6.9.0"
-  resolved "https://registry.yarnpkg.com/qs/-/qs-6.9.0.tgz#d1297e2a049c53119cb49cca366adbbacc80b409"
-  integrity sha512-27RP4UotQORTpmNQDX8BHPukOnBP3p1uUJY5UnDhaJB+rMt9iMsok724XL+UHU23bEFOHRMQ2ZhI99qOWUMGFA==
-
-qs@~6.5.2:
-  version "6.5.2"
-  resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36"
-  integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==
-
-querystring-es3@^0.2.0:
-  version "0.2.1"
-  resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73"
-  integrity sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=
-
-querystring@0.2.0:
-  version "0.2.0"
-  resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620"
-  integrity sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=
-
-querystringify@^2.1.1:
-  version "2.1.1"
-  resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.1.1.tgz#60e5a5fd64a7f8bfa4d2ab2ed6fdf4c85bad154e"
-  integrity sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA==
-
-randomatic@^3.0.0:
-  version "3.1.1"
-  resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-3.1.1.tgz#b776efc59375984e36c537b2f51a1f0aff0da1ed"
-  integrity sha512-TuDE5KxZ0J461RVjrJZCJc+J+zCkTb1MbH9AQUq68sMhOMcy9jLcb3BrZKgp9q9Ncltdg4QVqWrH02W2EFFVYw==
-  dependencies:
-    is-number "^4.0.0"
-    kind-of "^6.0.0"
-    math-random "^1.0.1"
-
-range-parser@^1.0.3, range-parser@~1.2.1:
-  version "1.2.1"
-  resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031"
-  integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==
-
-raw-body@2.4.0:
-  version "2.4.0"
-  resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.0.tgz#a1ce6fb9c9bc356ca52e89256ab59059e13d0332"
-  integrity sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==
-  dependencies:
-    bytes "3.1.0"
-    http-errors "1.7.2"
-    iconv-lite "0.4.24"
-    unpipe "1.0.0"
-
-raw-body@~1.1.0:
-  version "1.1.7"
-  resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-1.1.7.tgz#1d027c2bfa116acc6623bca8f00016572a87d425"
-  integrity sha1-HQJ8K/oRasxmI7yo8AAWVyqH1CU=
-  dependencies:
-    bytes "1"
-    string_decoder "0.10"
-
-rc@^1.2.7:
-  version "1.2.8"
-  resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed"
-  integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==
-  dependencies:
-    deep-extend "^0.6.0"
-    ini "~1.3.0"
-    minimist "^1.2.0"
-    strip-json-comments "~2.0.1"
-
-read-pkg-up@^1.0.1:
-  version "1.0.1"
-  resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02"
-  integrity sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=
-  dependencies:
-    find-up "^1.0.0"
-    read-pkg "^1.0.0"
-
-read-pkg@^1.0.0:
-  version "1.1.0"
-  resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28"
-  integrity sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=
-  dependencies:
-    load-json-file "^1.0.0"
-    normalize-package-data "^2.3.2"
-    path-type "^1.0.0"
-
-readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.5, readable-stream@^2.0.6, readable-stream@^2.2.2, readable-stream@^2.3.6:
-  version "2.3.6"
-  resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf"
-  integrity sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==
-  dependencies:
-    core-util-is "~1.0.0"
-    inherits "~2.0.3"
-    isarray "~1.0.0"
-    process-nextick-args "~2.0.0"
-    safe-buffer "~5.1.1"
-    string_decoder "~1.1.1"
-    util-deprecate "~1.0.1"
-
-readdirp@^2.0.0:
-  version "2.2.1"
-  resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.2.1.tgz#0e87622a3325aa33e892285caf8b4e846529a525"
-  integrity sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==
-  dependencies:
-    graceful-fs "^4.1.11"
-    micromatch "^3.1.10"
-    readable-stream "^2.0.2"
-
-recast@0.10.33:
-  version "0.10.33"
-  resolved "https://registry.yarnpkg.com/recast/-/recast-0.10.33.tgz#942808f7aa016f1fa7142c461d7e5704aaa8d697"
-  integrity sha1-lCgI96oBbx+nFCxGHX5XBKqo1pc=
-  dependencies:
-    ast-types "0.8.12"
-    esprima-fb "~15001.1001.0-dev-harmony-fb"
-    private "~0.1.5"
-    source-map "~0.5.0"
-
-recast@^0.10.10:
-  version "0.10.43"
-  resolved "https://registry.yarnpkg.com/recast/-/recast-0.10.43.tgz#b95d50f6d60761a5f6252e15d80678168491ce7f"
-  integrity sha1-uV1Q9tYHYaX2JS4V2AZ4FoSRzn8=
-  dependencies:
-    ast-types "0.8.15"
-    esprima-fb "~15001.1001.0-dev-harmony-fb"
-    private "~0.1.5"
-    source-map "~0.5.0"
-
-recast@^0.11.17:
-  version "0.11.23"
-  resolved "https://registry.yarnpkg.com/recast/-/recast-0.11.23.tgz#451fd3004ab1e4df9b4e4b66376b2a21912462d3"
-  integrity sha1-RR/TAEqx5N+bTktmN2sqIZEkYtM=
-  dependencies:
-    ast-types "0.9.6"
-    esprima "~3.1.0"
-    private "~0.1.5"
-    source-map "~0.5.0"
-
-rechoir@^0.6.2:
-  version "0.6.2"
-  resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384"
-  integrity sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=
-  dependencies:
-    resolve "^1.1.6"
-
-redent@^1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/redent/-/redent-1.0.0.tgz#cf916ab1fd5f1f16dfb20822dd6ec7f730c2afde"
-  integrity sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=
-  dependencies:
-    indent-string "^2.1.0"
-    strip-indent "^1.0.1"
-
-regenerate@^1.2.1:
-  version "1.4.0"
-  resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.0.tgz#4a856ec4b56e4077c557589cae85e7a4c8869a11"
-  integrity sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg==
-
-regenerator@0.8.40:
-  version "0.8.40"
-  resolved "https://registry.yarnpkg.com/regenerator/-/regenerator-0.8.40.tgz#a0e457c58ebdbae575c9f8cd75127e93756435d8"
-  integrity sha1-oORXxY69uuV1yfjNdRJ+k3VkNdg=
-  dependencies:
-    commoner "~0.10.3"
-    defs "~1.1.0"
-    esprima-fb "~15001.1001.0-dev-harmony-fb"
-    private "~0.1.5"
-    recast "0.10.33"
-    through "~2.3.8"
-
-regex-cache@^0.4.2:
-  version "0.4.4"
-  resolved "https://registry.yarnpkg.com/regex-cache/-/regex-cache-0.4.4.tgz#75bdc58a2a1496cec48a12835bc54c8d562336dd"
-  integrity sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==
-  dependencies:
-    is-equal-shallow "^0.1.3"
-
-regex-not@^1.0.0, regex-not@^1.0.2:
-  version "1.0.2"
-  resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c"
-  integrity sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==
-  dependencies:
-    extend-shallow "^3.0.2"
-    safe-regex "^1.1.0"
-
-regexpp@^1.0.1:
-  version "1.1.0"
-  resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-1.1.0.tgz#0e3516dd0b7904f413d2d4193dce4618c3a689ab"
-  integrity sha512-LOPw8FpgdQF9etWMaAfG/WRthIdXJGYp4mJ2Jgn/2lpkbod9jPn0t9UqN7AxBOKNfzRbYyVfgc7Vk4t/MpnXgw==
-
-regexpu@^1.3.0:
-  version "1.3.0"
-  resolved "https://registry.yarnpkg.com/regexpu/-/regexpu-1.3.0.tgz#e534dc991a9e5846050c98de6d7dd4a55c9ea16d"
-  integrity sha1-5TTcmRqeWEYFDJjebX3UpVyeoW0=
-  dependencies:
-    esprima "^2.6.0"
-    recast "^0.10.10"
-    regenerate "^1.2.1"
-    regjsgen "^0.2.0"
-    regjsparser "^0.1.4"
-
-regjsgen@^0.2.0:
-  version "0.2.0"
-  resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.2.0.tgz#6c016adeac554f75823fe37ac05b92d5a4edb1f7"
-  integrity sha1-bAFq3qxVT3WCP+N6wFuS1aTtsfc=
-
-regjsparser@^0.1.4:
-  version "0.1.5"
-  resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.1.5.tgz#7ee8f84dc6fa792d3fd0ae228d24bd949ead205c"
-  integrity sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw=
-  dependencies:
-    jsesc "~0.5.0"
-
-remove-trailing-separator@^1.0.1:
-  version "1.1.0"
-  resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef"
-  integrity sha1-wkvOKig62tW8P1jg1IJJuSN52O8=
-
-repeat-element@^1.1.2:
-  version "1.1.3"
-  resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.3.tgz#782e0d825c0c5a3bb39731f84efee6b742e6b1ce"
-  integrity sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==
-
-repeat-string@^1.5.2, repeat-string@^1.6.1:
-  version "1.6.1"
-  resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637"
-  integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc=
-
-repeating@^1.1.0, repeating@^1.1.2:
-  version "1.1.3"
-  resolved "https://registry.yarnpkg.com/repeating/-/repeating-1.1.3.tgz#3d4114218877537494f97f77f9785fab810fa4ac"
-  integrity sha1-PUEUIYh3U3SU+X93+Xhfq4EPpKw=
-  dependencies:
-    is-finite "^1.0.0"
-
-repeating@^2.0.0:
-  version "2.0.1"
-  resolved "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda"
-  integrity sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=
-  dependencies:
-    is-finite "^1.0.0"
-
-request@^2.74.x, request@^2.88.0:
-  version "2.88.0"
-  resolved "https://registry.yarnpkg.com/request/-/request-2.88.0.tgz#9c2fca4f7d35b592efe57c7f0a55e81052124fef"
-  integrity sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==
-  dependencies:
-    aws-sign2 "~0.7.0"
-    aws4 "^1.8.0"
-    caseless "~0.12.0"
-    combined-stream "~1.0.6"
-    extend "~3.0.2"
-    forever-agent "~0.6.1"
-    form-data "~2.3.2"
-    har-validator "~5.1.0"
-    http-signature "~1.2.0"
-    is-typedarray "~1.0.0"
-    isstream "~0.1.2"
-    json-stringify-safe "~5.0.1"
-    mime-types "~2.1.19"
-    oauth-sign "~0.9.0"
-    performance-now "^2.1.0"
-    qs "~6.5.2"
-    safe-buffer "^5.1.2"
-    tough-cookie "~2.4.3"
-    tunnel-agent "^0.6.0"
-    uuid "^3.3.2"
-
-requestretry@~1.9.0:
-  version "1.9.1"
-  resolved "https://registry.yarnpkg.com/requestretry/-/requestretry-1.9.1.tgz#0a2a004eaf211969c4cc2cfebf3fe9e57b92c74e"
-  integrity sha1-CioATq8hGWnEzCz+vz/p5XuSx04=
-  dependencies:
-    extend "^3.0.0"
-    fg-lodash "0.0.2"
-    request "^2.74.x"
-    when "~3.7.5"
-
-require-directory@^2.1.1:
-  version "2.1.1"
-  resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42"
-  integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I=
-
-require-main-filename@^1.0.1:
-  version "1.0.1"
-  resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1"
-  integrity sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=
-
-require-uncached@^1.0.3:
-  version "1.0.3"
-  resolved "https://registry.yarnpkg.com/require-uncached/-/require-uncached-1.0.3.tgz#4e0d56d6c9662fd31e43011c4b95aa49955421d3"
-  integrity sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=
-  dependencies:
-    caller-path "^0.1.0"
-    resolve-from "^1.0.0"
-
-requirejs@^2.1.0:
-  version "2.3.6"
-  resolved "https://registry.yarnpkg.com/requirejs/-/requirejs-2.3.6.tgz#e5093d9601c2829251258c0b9445d4d19fa9e7c9"
-  integrity sha512-ipEzlWQe6RK3jkzikgCupiTbTvm4S0/CAU5GlgptkN5SO6F3u0UD0K18wy6ErDqiCyP4J4YYe1HuAShvsxePLg==
-
-requires-port@^1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff"
-  integrity sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=
-
-resolve-dir@^1.0.0, resolve-dir@^1.0.1:
-  version "1.0.1"
-  resolved "https://registry.yarnpkg.com/resolve-dir/-/resolve-dir-1.0.1.tgz#79a40644c362be82f26effe739c9bb5382046f43"
-  integrity sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=
-  dependencies:
-    expand-tilde "^2.0.0"
-    global-modules "^1.0.0"
-
-resolve-from@^1.0.0:
-  version "1.0.1"
-  resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-1.0.1.tgz#26cbfe935d1aeeeabb29bc3fe5aeb01e93d44226"
-  integrity sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=
-
-resolve-url@^0.2.1:
-  version "0.2.1"
-  resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a"
-  integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=
-
-resolve@1.1.x, resolve@~1.1.0:
-  version "1.1.7"
-  resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b"
-  integrity sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=
-
-resolve@^1.1.6, resolve@^1.1.7, resolve@^1.10.0, resolve@^1.3.2:
-  version "1.12.0"
-  resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.12.0.tgz#3fc644a35c84a48554609ff26ec52b66fa577df6"
-  integrity sha512-B/dOmuoAik5bKcD6s6nXDCjzUKnaDvdkRyAk6rsmsKLipWj4797iothd7jmmUhWTfinVMU+wc56rYKsit2Qy4w==
-  dependencies:
-    path-parse "^1.0.6"
-
-restore-cursor@^2.0.0:
-  version "2.0.0"
-  resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf"
-  integrity sha1-n37ih/gv0ybU/RYpI9YhKe7g368=
-  dependencies:
-    onetime "^2.0.0"
-    signal-exit "^3.0.2"
-
-ret@~0.1.10:
-  version "0.1.15"
-  resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc"
-  integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==
-
-right-align@^0.1.1:
-  version "0.1.3"
-  resolved "https://registry.yarnpkg.com/right-align/-/right-align-0.1.3.tgz#61339b722fe6a3515689210d24e14c96148613ef"
-  integrity sha1-YTObci/mo1FWiSENJOFMlhSGE+8=
-  dependencies:
-    align-text "^0.1.1"
-
-rimraf@^2.5.1, rimraf@^2.6.1:
-  version "2.7.1"
-  resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec"
-  integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==
-  dependencies:
-    glob "^7.1.3"
-
-rimraf@~2.6.2:
-  version "2.6.3"
-  resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab"
-  integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==
-  dependencies:
-    glob "^7.1.3"
-
-ripemd160@0.2.0:
-  version "0.2.0"
-  resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-0.2.0.tgz#2bf198bde167cacfa51c0a928e84b68bbe171fce"
-  integrity sha1-K/GYveFnys+lHAqSjoS2i74XH84=
-
-run-async@^2.2.0:
-  version "2.3.0"
-  resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.3.0.tgz#0371ab4ae0bdd720d4166d7dfda64ff7a445a6c0"
-  integrity sha1-A3GrSuC91yDUFm19/aZP96RFpsA=
-  dependencies:
-    is-promise "^2.1.0"
-
-rx-lite-aggregates@^4.0.8:
-  version "4.0.8"
-  resolved "https://registry.yarnpkg.com/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz#753b87a89a11c95467c4ac1626c4efc4e05c67be"
-  integrity sha1-dTuHqJoRyVRnxKwWJsTvxOBcZ74=
-  dependencies:
-    rx-lite "*"
-
-rx-lite@*, rx-lite@^4.0.8:
-  version "4.0.8"
-  resolved "https://registry.yarnpkg.com/rx-lite/-/rx-lite-4.0.8.tgz#0b1e11af8bc44836f04a6407e92da42467b79444"
-  integrity sha1-Cx4Rr4vESDbwSmQH6S2kJGe3lEQ=
-
-safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1:
-  version "5.1.2"
-  resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d"
-  integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==
-
-safe-buffer@>=5.1.0, safe-buffer@^5.0.1, safe-buffer@^5.1.2:
-  version "5.2.0"
-  resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.0.tgz#b74daec49b1148f88c64b68d49b1e815c1f2f519"
-  integrity sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==
-
-safe-json-parse@~1.0.1:
-  version "1.0.1"
-  resolved "https://registry.yarnpkg.com/safe-json-parse/-/safe-json-parse-1.0.1.tgz#3e76723e38dfdda13c9b1d29a1e07ffee4b30b57"
-  integrity sha1-PnZyPjjf3aE8mx0poeB//uSzC1c=
-
-safe-regex@^1.1.0:
-  version "1.1.0"
-  resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e"
-  integrity sha1-QKNmnzsHfR6UPURinhV91IAjvy4=
-  dependencies:
-    ret "~0.1.10"
-
-"safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0:
-  version "2.1.2"
-  resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
-  integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==
-
-saucelabs@^1.5.0:
-  version "1.5.0"
-  resolved "https://registry.yarnpkg.com/saucelabs/-/saucelabs-1.5.0.tgz#9405a73c360d449b232839919a86c396d379fd9d"
-  integrity sha512-jlX3FGdWvYf4Q3LFfFWS1QvPg3IGCGWxIc8QBFdPTbpTJnt/v17FHXYVAn7C8sHf1yUXo2c7yIM0isDryfYtHQ==
-  dependencies:
-    https-proxy-agent "^2.2.1"
-
-sax@1.2.1:
-  version "1.2.1"
-  resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.1.tgz#7b8e656190b228e81a66aea748480d828cd2d37a"
-  integrity sha1-e45lYZCyKOgaZq6nSEgNgozS03o=
-
-sax@>=0.6.0, sax@^1.2.4:
-  version "1.2.4"
-  resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9"
-  integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==
-
-"semver@2 || 3 || 4 || 5", semver@^5.0.1, semver@^5.3.0, semver@^5.5.0:
-  version "5.7.1"
-  resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7"
-  integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==
-
-send@0.17.1:
-  version "0.17.1"
-  resolved "https://registry.yarnpkg.com/send/-/send-0.17.1.tgz#c1d8b059f7900f7466dd4938bdc44e11ddb376c8"
-  integrity sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==
-  dependencies:
-    debug "2.6.9"
-    depd "~1.1.2"
-    destroy "~1.0.4"
-    encodeurl "~1.0.2"
-    escape-html "~1.0.3"
-    etag "~1.8.1"
-    fresh "0.5.2"
-    http-errors "~1.7.2"
-    mime "1.6.0"
-    ms "2.1.1"
-    on-finished "~2.3.0"
-    range-parser "~1.2.1"
-    statuses "~1.5.0"
-
-serve-index@^1.7.1, serve-index@^1.7.2:
-  version "1.9.1"
-  resolved "https://registry.yarnpkg.com/serve-index/-/serve-index-1.9.1.tgz#d3768d69b1e7d82e5ce050fff5b453bea12a9239"
-  integrity sha1-03aNabHn2C5c4FD/9bRTvqEqkjk=
-  dependencies:
-    accepts "~1.3.4"
-    batch "0.6.1"
-    debug "2.6.9"
-    escape-html "~1.0.3"
-    http-errors "~1.6.2"
-    mime-types "~2.1.17"
-    parseurl "~1.3.2"
-
-serve-static@1.14.1, serve-static@^1.10.0:
-  version "1.14.1"
-  resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.14.1.tgz#666e636dc4f010f7ef29970a88a674320898b2f9"
-  integrity sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==
-  dependencies:
-    encodeurl "~1.0.2"
-    escape-html "~1.0.3"
-    parseurl "~1.3.3"
-    send "0.17.1"
-
-set-blocking@^2.0.0, set-blocking@~2.0.0:
-  version "2.0.0"
-  resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7"
-  integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc=
-
-set-value@^2.0.0, set-value@^2.0.1:
-  version "2.0.1"
-  resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.1.tgz#a18d40530e6f07de4228c7defe4227af8cad005b"
-  integrity sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==
-  dependencies:
-    extend-shallow "^2.0.1"
-    is-extendable "^0.1.1"
-    is-plain-object "^2.0.3"
-    split-string "^3.0.1"
-
-setimmediate@^1.0.4:
-  version "1.0.5"
-  resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285"
-  integrity sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=
-
-setprototypeof@1.1.0:
-  version "1.1.0"
-  resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656"
-  integrity sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==
-
-setprototypeof@1.1.1:
-  version "1.1.1"
-  resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.1.tgz#7e95acb24aa92f5885e0abef5ba131330d4ae683"
-  integrity sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==
-
-sha.js@2.2.6:
-  version "2.2.6"
-  resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.2.6.tgz#17ddeddc5f722fb66501658895461977867315ba"
-  integrity sha1-F93t3F9yL7ZlAWWIlUYZd4ZzFbo=
-
-shebang-command@^1.2.0:
-  version "1.2.0"
-  resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea"
-  integrity sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=
-  dependencies:
-    shebang-regex "^1.0.0"
-
-shebang-regex@^1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3"
-  integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=
-
-signal-exit@^3.0.0, signal-exit@^3.0.2:
-  version "3.0.2"
-  resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d"
-  integrity sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=
-
-simple-fmt@~0.1.0:
-  version "0.1.0"
-  resolved "https://registry.yarnpkg.com/simple-fmt/-/simple-fmt-0.1.0.tgz#191bf566a59e6530482cb25ab53b4a8dc85c3a6b"
-  integrity sha1-GRv1ZqWeZTBILLJatTtKjchcOms=
-
-simple-is@~0.2.0:
-  version "0.2.0"
-  resolved "https://registry.yarnpkg.com/simple-is/-/simple-is-0.2.0.tgz#2abb75aade39deb5cc815ce10e6191164850baf0"
-  integrity sha1-Krt1qt453rXMgVzhDmGRFkhQuvA=
-
-slash@^1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55"
-  integrity sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=
-
-slice-ansi@1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-1.0.0.tgz#044f1a49d8842ff307aad6b505ed178bd950134d"
-  integrity sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg==
-  dependencies:
-    is-fullwidth-code-point "^2.0.0"
-
-snapdragon-node@^2.0.1:
-  version "2.1.1"
-  resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b"
-  integrity sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==
-  dependencies:
-    define-property "^1.0.0"
-    isobject "^3.0.0"
-    snapdragon-util "^3.0.1"
-
-snapdragon-util@^3.0.1:
-  version "3.0.1"
-  resolved "https://registry.yarnpkg.com/snapdragon-util/-/snapdragon-util-3.0.1.tgz#f956479486f2acd79700693f6f7b805e45ab56e2"
-  integrity sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==
-  dependencies:
-    kind-of "^3.2.0"
-
-snapdragon@^0.8.1:
-  version "0.8.2"
-  resolved "https://registry.yarnpkg.com/snapdragon/-/snapdragon-0.8.2.tgz#64922e7c565b0e14204ba1aa7d6964278d25182d"
-  integrity sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==
-  dependencies:
-    base "^0.11.1"
-    debug "^2.2.0"
-    define-property "^0.2.5"
-    extend-shallow "^2.0.1"
-    map-cache "^0.2.2"
-    source-map "^0.5.6"
-    source-map-resolve "^0.5.0"
-    use "^3.1.0"
-
-sockjs-client@^1.0.3:
-  version "1.4.0"
-  resolved "https://registry.yarnpkg.com/sockjs-client/-/sockjs-client-1.4.0.tgz#c9f2568e19c8fd8173b4997ea3420e0bb306c7d5"
-  integrity sha512-5zaLyO8/nri5cua0VtOrFXBPK1jbL4+1cebT/mmKA1E1ZXOvJrII75bPu0l0k843G/+iAbhEqzyKr0w/eCCj7g==
-  dependencies:
-    debug "^3.2.5"
-    eventsource "^1.0.7"
-    faye-websocket "~0.11.1"
-    inherits "^2.0.3"
-    json3 "^3.3.2"
-    url-parse "^1.4.3"
-
-sockjs@^0.3.15:
-  version "0.3.19"
-  resolved "https://registry.yarnpkg.com/sockjs/-/sockjs-0.3.19.tgz#d976bbe800af7bd20ae08598d582393508993c0d"
-  integrity sha512-V48klKZl8T6MzatbLlzzRNhMepEys9Y4oGFpypBFFn1gLI/QQ9HtLLyWJNbPlwGLelOVOEijUbTTJeLLI59jLw==
-  dependencies:
-    faye-websocket "^0.10.0"
-    uuid "^3.0.1"
-
-source-list-map@~0.1.7:
-  version "0.1.8"
-  resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-0.1.8.tgz#c550b2ab5427f6b3f21f5afead88c4f5587b2106"
-  integrity sha1-xVCyq1Qn9rPyH1r+rYjE9Vh7IQY=
-
-source-map-resolve@^0.5.0:
-  version "0.5.2"
-  resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.2.tgz#72e2cc34095543e43b2c62b2c4c10d4a9054f259"
-  integrity sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==
-  dependencies:
-    atob "^2.1.1"
-    decode-uri-component "^0.2.0"
-    resolve-url "^0.2.1"
-    source-map-url "^0.4.0"
-    urix "^0.1.0"
-
-source-map-support@^0.2.10:
-  version "0.2.10"
-  resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.2.10.tgz#ea5a3900a1c1cb25096a0ae8cc5c2b4b10ded3dc"
-  integrity sha1-6lo5AKHByyUJagrozFwrSxDe09w=
-  dependencies:
-    source-map "0.1.32"
-
-source-map-support@^0.3.2:
-  version "0.3.3"
-  resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.3.3.tgz#34900977d5ba3f07c7757ee72e73bb1a9b53754f"
-  integrity sha1-NJAJd9W6PwfHdX7nLnO7GptTdU8=
-  dependencies:
-    source-map "0.1.32"
-
-source-map-url@^0.4.0:
-  version "0.4.0"
-  resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3"
-  integrity sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=
-
-source-map@0.1.32:
-  version "0.1.32"
-  resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.1.32.tgz#c8b6c167797ba4740a8ea33252162ff08591b266"
-  integrity sha1-yLbBZ3l7pHQKjqMyUhYv8IWRsmY=
-  dependencies:
-    amdefine ">=0.0.4"
-
-source-map@^0.4.4, source-map@~0.4.1:
-  version "0.4.4"
-  resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.4.4.tgz#eba4f5da9c0dc999de68032d8b4f76173652036b"
-  integrity sha1-66T12pwNyZneaAMti092FzZSA2s=
-  dependencies:
-    amdefine ">=0.0.4"
-
-source-map@^0.5.0, source-map@^0.5.3, source-map@^0.5.6, source-map@~0.5.0, source-map@~0.5.1:
-  version "0.5.7"
-  resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc"
-  integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=
-
-source-map@^0.6.1, source-map@~0.6.1:
-  version "0.6.1"
-  resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
-  integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==
-
-source-map@~0.1.33:
-  version "0.1.43"
-  resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.1.43.tgz#c24bc146ca517c1471f5dacbe2571b2b7f9e3346"
-  integrity sha1-wkvBRspRfBRx9drL4lcbK3+eM0Y=
-  dependencies:
-    amdefine ">=0.0.4"
-
-source-map@~0.2.0:
-  version "0.2.0"
-  resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.2.0.tgz#dab73fbcfc2ba819b4de03bd6f6eaa48164b3f9d"
-  integrity sha1-2rc/vPwrqBm03gO9b26qSBZLP50=
-  dependencies:
-    amdefine ">=0.0.4"
-
-spdx-correct@^3.0.0:
-  version "3.1.0"
-  resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.0.tgz#fb83e504445268f154b074e218c87c003cd31df4"
-  integrity sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==
-  dependencies:
-    spdx-expression-parse "^3.0.0"
-    spdx-license-ids "^3.0.0"
-
-spdx-exceptions@^2.1.0:
-  version "2.2.0"
-  resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz#2ea450aee74f2a89bfb94519c07fcd6f41322977"
-  integrity sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA==
-
-spdx-expression-parse@^3.0.0:
-  version "3.0.0"
-  resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz#99e119b7a5da00e05491c9fa338b7904823b41d0"
-  integrity sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==
-  dependencies:
-    spdx-exceptions "^2.1.0"
-    spdx-license-ids "^3.0.0"
-
-spdx-license-ids@^3.0.0:
-  version "3.0.5"
-  resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz#3694b5804567a458d3c8045842a6358632f62654"
-  integrity sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==
-
-split-string@^3.0.1, split-string@^3.0.2:
-  version "3.1.0"
-  resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2"
-  integrity sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==
-  dependencies:
-    extend-shallow "^3.0.0"
-
-split@^1.0.1:
-  version "1.0.1"
-  resolved "https://registry.yarnpkg.com/split/-/split-1.0.1.tgz#605bd9be303aa59fb35f9229fbea0ddec9ea07d9"
-  integrity sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==
-  dependencies:
-    through "2"
-
-sprintf-js@^1.0.3:
-  version "1.1.2"
-  resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.1.2.tgz#da1765262bf8c0f571749f2ad6c26300207ae673"
-  integrity sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==
-
-sprintf-js@~1.0.2:
-  version "1.0.3"
-  resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c"
-  integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=
-
-sshpk@^1.7.0:
-  version "1.16.1"
-  resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.16.1.tgz#fb661c0bef29b39db40769ee39fa70093d6f6877"
-  integrity sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==
-  dependencies:
-    asn1 "~0.2.3"
-    assert-plus "^1.0.0"
-    bcrypt-pbkdf "^1.0.0"
-    dashdash "^1.12.0"
-    ecc-jsbn "~0.1.1"
-    getpass "^0.1.1"
-    jsbn "~0.1.0"
-    safer-buffer "^2.0.2"
-    tweetnacl "~0.14.0"
-
-stable@~0.1.3:
-  version "0.1.8"
-  resolved "https://registry.yarnpkg.com/stable/-/stable-0.1.8.tgz#836eb3c8382fe2936feaf544631017ce7d47a3cf"
-  integrity sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==
-
-static-extend@^0.1.1:
-  version "0.1.2"
-  resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6"
-  integrity sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=
-  dependencies:
-    define-property "^0.2.5"
-    object-copy "^0.1.0"
-
-"statuses@>= 1.4.0 < 2", "statuses@>= 1.5.0 < 2", statuses@~1.5.0:
-  version "1.5.0"
-  resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c"
-  integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=
-
-stream-browserify@^2.0.1:
-  version "2.0.2"
-  resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-2.0.2.tgz#87521d38a44aa7ee91ce1cd2a47df0cb49dd660b"
-  integrity sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==
-  dependencies:
-    inherits "~2.0.1"
-    readable-stream "^2.0.2"
-
-stream-cache@~0.0.1:
-  version "0.0.2"
-  resolved "https://registry.yarnpkg.com/stream-cache/-/stream-cache-0.0.2.tgz#1ac5ad6832428ca55667dbdee395dad4e6db118f"
-  integrity sha1-GsWtaDJCjKVWZ9ve45Xa1ObbEY8=
-
-stream-http@^2.3.1:
-  version "2.8.3"
-  resolved "https://registry.yarnpkg.com/stream-http/-/stream-http-2.8.3.tgz#b2d242469288a5a27ec4fe8933acf623de6514fc"
-  integrity sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==
-  dependencies:
-    builtin-status-codes "^3.0.0"
-    inherits "^2.0.1"
-    readable-stream "^2.3.6"
-    to-arraybuffer "^1.0.0"
-    xtend "^4.0.0"
-
-string-template@~0.2.1:
-  version "0.2.1"
-  resolved "https://registry.yarnpkg.com/string-template/-/string-template-0.2.1.tgz#42932e598a352d01fc22ec3367d9d84eec6c9add"
-  integrity sha1-QpMuWYo1LQH8IuwzZ9nYTuxsmt0=
-
-string-width@^1.0.1:
-  version "1.0.2"
-  resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3"
-  integrity sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=
-  dependencies:
-    code-point-at "^1.0.0"
-    is-fullwidth-code-point "^1.0.0"
-    strip-ansi "^3.0.0"
-
-"string-width@^1.0.2 || 2", string-width@^2.0.0, string-width@^2.1.0, string-width@^2.1.1:
-  version "2.1.1"
-  resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e"
-  integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==
-  dependencies:
-    is-fullwidth-code-point "^2.0.0"
-    strip-ansi "^4.0.0"
-
-string_decoder@0.10, string_decoder@^0.10.25:
-  version "0.10.31"
-  resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94"
-  integrity sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=
-
-string_decoder@~1.1.1:
-  version "1.1.1"
-  resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8"
-  integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==
-  dependencies:
-    safe-buffer "~5.1.0"
-
-stringmap@~0.2.2:
-  version "0.2.2"
-  resolved "https://registry.yarnpkg.com/stringmap/-/stringmap-0.2.2.tgz#556c137b258f942b8776f5b2ef582aa069d7d1b1"
-  integrity sha1-VWwTeyWPlCuHdvWy71gqoGnX0bE=
-
-stringset@~0.2.1:
-  version "0.2.1"
-  resolved "https://registry.yarnpkg.com/stringset/-/stringset-0.2.1.tgz#ef259c4e349344377fcd1c913dd2e848c9c042b5"
-  integrity sha1-7yWcTjSTRDd/zRyRPdLoSMnAQrU=
-
-strip-ansi@^3.0.0, strip-ansi@^3.0.1:
-  version "3.0.1"
-  resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf"
-  integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=
-  dependencies:
-    ansi-regex "^2.0.0"
-
-strip-ansi@^4.0.0:
-  version "4.0.0"
-  resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f"
-  integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8=
-  dependencies:
-    ansi-regex "^3.0.0"
-
-strip-ansi@~0.1.0:
-  version "0.1.1"
-  resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-0.1.1.tgz#39e8a98d044d150660abe4a6808acf70bb7bc991"
-  integrity sha1-OeipjQRNFQZgq+SmgIrPcLt7yZE=
-
-strip-bom@^2.0.0:
-  version "2.0.0"
-  resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e"
-  integrity sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=
-  dependencies:
-    is-utf8 "^0.2.0"
-
-strip-eof@^1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf"
-  integrity sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=
-
-strip-indent@^1.0.1:
-  version "1.0.1"
-  resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-1.0.1.tgz#0c7962a6adefa7bbd4ac366460a638552ae1a0a2"
-  integrity sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=
-  dependencies:
-    get-stdin "^4.0.1"
-
-strip-json-comments@^2.0.1, strip-json-comments@~2.0.1:
-  version "2.0.1"
-  resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a"
-  integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo=
-
-strscan@>=1.0.1:
-  version "1.0.1"
-  resolved "https://registry.yarnpkg.com/strscan/-/strscan-1.0.1.tgz#472d9bc00c68e906ef2fc22cdf762be7c61acc4d"
-  integrity sha1-Ry2bwAxo6QbvL8Is33Yr58YazE0=
-
-supports-color@5.4.0:
-  version "5.4.0"
-  resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.4.0.tgz#1c6b337402c2137605efe19f10fec390f6faab54"
-  integrity sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==
-  dependencies:
-    has-flag "^3.0.0"
-
-supports-color@^2.0.0:
-  version "2.0.0"
-  resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7"
-  integrity sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=
-
-supports-color@^3.1.0, supports-color@^3.1.1:
-  version "3.2.3"
-  resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.2.3.tgz#65ac0504b3954171d8a64946b2ae3cbb8a5f54f6"
-  integrity sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=
-  dependencies:
-    has-flag "^1.0.0"
-
-supports-color@^5.3.0:
-  version "5.5.0"
-  resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f"
-  integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==
-  dependencies:
-    has-flag "^3.0.0"
-
-table@4.0.2:
-  version "4.0.2"
-  resolved "https://registry.yarnpkg.com/table/-/table-4.0.2.tgz#a33447375391e766ad34d3486e6e2aedc84d2e36"
-  integrity sha512-UUkEAPdSGxtRpiV9ozJ5cMTtYiqz7Ni1OGqLXRCynrvzdtR1p+cfOWe2RJLwvUG8hNanaSRjecIqwOjqeatDsA==
-  dependencies:
-    ajv "^5.2.3"
-    ajv-keywords "^2.1.0"
-    chalk "^2.1.0"
-    lodash "^4.17.4"
-    slice-ansi "1.0.0"
-    string-width "^2.1.1"
-
-tapable@^0.1.8, tapable@~0.1.8:
-  version "0.1.10"
-  resolved "https://registry.yarnpkg.com/tapable/-/tapable-0.1.10.tgz#29c35707c2b70e50d07482b5d202e8ed446dafd4"
-  integrity sha1-KcNXB8K3DlDQdIK10gLo7URtr9Q=
-
-tar@^4:
-  version "4.4.13"
-  resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.13.tgz#43b364bc52888d555298637b10d60790254ab525"
-  integrity sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA==
-  dependencies:
-    chownr "^1.1.1"
-    fs-minipass "^1.2.5"
-    minipass "^2.8.6"
-    minizlib "^1.2.1"
-    mkdirp "^0.5.0"
-    safe-buffer "^5.1.2"
-    yallist "^3.0.3"
-
-text-table@~0.2.0:
-  version "0.2.0"
-  resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4"
-  integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=
-
-through@2, through@^2.3.6, through@~2.3.8:
-  version "2.3.8"
-  resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5"
-  integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=
-
-time-stamp@^2.0.0:
-  version "2.2.0"
-  resolved "https://registry.yarnpkg.com/time-stamp/-/time-stamp-2.2.0.tgz#917e0a66905688790ec7bbbde04046259af83f57"
-  integrity sha512-zxke8goJQpBeEgD82CXABeMh0LSJcj7CXEd0OHOg45HgcofF7pxNwZm9+RknpxpDhwN4gFpySkApKfFYfRQnUA==
-
-timers-browserify@^2.0.2:
-  version "2.0.11"
-  resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-2.0.11.tgz#800b1f3eee272e5bc53ee465a04d0e804c31211f"
-  integrity sha512-60aV6sgJ5YEbzUdn9c8kYGIqOubPoUdqQCul3SBAsRCZ40s6Y5cMcrW4dt3/k/EsbLVJNl9n6Vz3fTc+k2GeKQ==
-  dependencies:
-    setimmediate "^1.0.4"
-
-tiny-lr@^1.1.1:
-  version "1.1.1"
-  resolved "https://registry.yarnpkg.com/tiny-lr/-/tiny-lr-1.1.1.tgz#9fa547412f238fedb068ee295af8b682c98b2aab"
-  integrity sha512-44yhA3tsaRoMOjQQ+5v5mVdqef+kH6Qze9jTpqtVufgYjYt08zyZAwNwwVBj3i1rJMnR52IxOW0LK0vBzgAkuA==
-  dependencies:
-    body "^5.1.0"
-    debug "^3.1.0"
-    faye-websocket "~0.10.0"
-    livereload-js "^2.3.0"
-    object-assign "^4.1.0"
-    qs "^6.4.0"
-
-tmp@^0.0.33:
-  version "0.0.33"
-  resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9"
-  integrity sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==
-  dependencies:
-    os-tmpdir "~1.0.2"
-
-to-arraybuffer@^1.0.0:
-  version "1.0.1"
-  resolved "https://registry.yarnpkg.com/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz#7d229b1fcc637e466ca081180836a7aabff83f43"
-  integrity sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=
-
-to-fast-properties@^1.0.0:
-  version "1.0.3"
-  resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.3.tgz#b83571fa4d8c25b82e231b06e3a3055de4ca1a47"
-  integrity sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=
-
-to-object-path@^0.3.0:
-  version "0.3.0"
-  resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af"
-  integrity sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=
-  dependencies:
-    kind-of "^3.0.2"
-
-to-regex-range@^2.1.0:
-  version "2.1.1"
-  resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-2.1.1.tgz#7c80c17b9dfebe599e27367e0d4dd5590141db38"
-  integrity sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=
-  dependencies:
-    is-number "^3.0.0"
-    repeat-string "^1.6.1"
-
-to-regex@^3.0.1, to-regex@^3.0.2:
-  version "3.0.2"
-  resolved "https://registry.yarnpkg.com/to-regex/-/to-regex-3.0.2.tgz#13cfdd9b336552f30b51f33a8ae1b42a7a7599ce"
-  integrity sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==
-  dependencies:
-    define-property "^2.0.2"
-    extend-shallow "^3.0.2"
-    regex-not "^1.0.2"
-    safe-regex "^1.1.0"
-
-toidentifier@1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553"
-  integrity sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==
-
-tough-cookie@~2.4.3:
-  version "2.4.3"
-  resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.4.3.tgz#53f36da3f47783b0925afa06ff9f3b165280f781"
-  integrity sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==
-  dependencies:
-    psl "^1.1.24"
-    punycode "^1.4.1"
-
-trim-newlines@^1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-1.0.0.tgz#5887966bb582a4503a41eb524f7d35011815a613"
-  integrity sha1-WIeWa7WCpFA6QetST301ARgVphM=
-
-trim-right@^1.0.0:
-  version "1.0.1"
-  resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003"
-  integrity sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=
-
-try-resolve@^1.0.0:
-  version "1.0.1"
-  resolved "https://registry.yarnpkg.com/try-resolve/-/try-resolve-1.0.1.tgz#cfde6fabd72d63e5797cfaab873abbe8e700e912"
-  integrity sha1-z95vq9ctY+V5fPqrhzq76OcA6RI=
-
-tryor@~0.1.2:
-  version "0.1.2"
-  resolved "https://registry.yarnpkg.com/tryor/-/tryor-0.1.2.tgz#8145e4ca7caff40acde3ccf946e8b8bb75b4172b"
-  integrity sha1-gUXkynyv9ArN48z5Rui4u3W0Fys=
-
-tslib@^1.8.0, tslib@^1.8.1:
-  version "1.10.0"
-  resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.10.0.tgz#c3c19f95973fb0a62973fb09d90d961ee43e5c8a"
-  integrity sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==
-
-tslint@^5.14.0:
-  version "5.20.0"
-  resolved "https://registry.yarnpkg.com/tslint/-/tslint-5.20.0.tgz#fac93bfa79568a5a24e7be9cdde5e02b02d00ec1"
-  integrity sha512-2vqIvkMHbnx8acMogAERQ/IuINOq6DFqgF8/VDvhEkBqQh/x6SP0Y+OHnKth9/ZcHQSroOZwUQSN18v8KKF0/g==
-  dependencies:
-    "@babel/code-frame" "^7.0.0"
-    builtin-modules "^1.1.1"
-    chalk "^2.3.0"
-    commander "^2.12.1"
-    diff "^4.0.1"
-    glob "^7.1.1"
-    js-yaml "^3.13.1"
-    minimatch "^3.0.4"
-    mkdirp "^0.5.1"
-    resolve "^1.3.2"
-    semver "^5.3.0"
-    tslib "^1.8.0"
-    tsutils "^2.29.0"
-
-tsutils@^2.29.0:
-  version "2.29.0"
-  resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-2.29.0.tgz#32b488501467acbedd4b85498673a0812aca0b99"
-  integrity sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==
-  dependencies:
-    tslib "^1.8.1"
-
-tty-browserify@0.0.0:
-  version "0.0.0"
-  resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6"
-  integrity sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=
-
-tunnel-agent@^0.6.0:
-  version "0.6.0"
-  resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd"
-  integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=
-  dependencies:
-    safe-buffer "^5.0.1"
-
-tweetnacl@^0.14.3, tweetnacl@~0.14.0:
-  version "0.14.5"
-  resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64"
-  integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=
-
-type-check@~0.3.1, type-check@~0.3.2:
-  version "0.3.2"
-  resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72"
-  integrity sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=
-  dependencies:
-    prelude-ls "~1.1.2"
-
-type-is@~1.6.17, type-is@~1.6.18:
-  version "1.6.18"
-  resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131"
-  integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==
-  dependencies:
-    media-typer "0.3.0"
-    mime-types "~2.1.24"
-
-typedarray@^0.0.6:
-  version "0.0.6"
-  resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
-  integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=
-
-typescript@^3.4.3:
-  version "3.6.4"
-  resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.6.4.tgz#b18752bb3792bc1a0281335f7f6ebf1bbfc5b91d"
-  integrity sha512-unoCll1+l+YK4i4F8f22TaNVPRHcD9PA3yCuZ8g5e0qGqlVlJ/8FSateOLLSagn+Yg5+ZwuPkL8LFUc0Jcvksg==
-
-typescript@next:
-  version "3.8.0-dev.20191025"
-  resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.8.0-dev.20191025.tgz#680191c15791aee9eda7ce7ca131772d7ff3105a"
-  integrity sha512-5cjThi6BKQy3C40gW9HeBLiMH+vrASAtT8RwrYzn5IMaAepiF8mv3gKqji4pkjCTBlf0iNDu6fuujKm7yO1HEw==
-
-uglify-js@^3.1.4:
-  version "3.6.4"
-  resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.6.4.tgz#88cc880c6ed5cf9868fdfa0760654e7bed463f1d"
-  integrity sha512-9Yc2i881pF4BPGhjteCXQNaXx1DCwm3dtOyBaG2hitHjLWOczw/ki8vD1bqyT3u6K0Ms/FpCShkmfg+FtlOfYA==
-  dependencies:
-    commander "~2.20.3"
-    source-map "~0.6.1"
-
-uglify-js@~2.6.2:
-  version "2.6.4"
-  resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-2.6.4.tgz#65ea2fb3059c9394692f15fed87c2b36c16b9adf"
-  integrity sha1-ZeovswWck5RpLxX+2HwrNsFrmt8=
-  dependencies:
-    async "~0.2.6"
-    source-map "~0.5.1"
-    uglify-to-browserify "~1.0.0"
-    yargs "~3.10.0"
-
-uglify-js@~2.7.3:
-  version "2.7.5"
-  resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-2.7.5.tgz#4612c0c7baaee2ba7c487de4904ae122079f2ca8"
-  integrity sha1-RhLAx7qu4rp8SH3kkErhIgefLKg=
-  dependencies:
-    async "~0.2.6"
-    source-map "~0.5.1"
-    uglify-to-browserify "~1.0.0"
-    yargs "~3.10.0"
-
-uglify-to-browserify@~1.0.0:
-  version "1.0.2"
-  resolved "https://registry.yarnpkg.com/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz#6e0924d6bda6b5afe349e39a6d632850a0f882b7"
-  integrity sha1-bgkk1r2mta/jSeOabWMoUKD4grc=
-
-unc-path-regex@^0.1.2:
-  version "0.1.2"
-  resolved "https://registry.yarnpkg.com/unc-path-regex/-/unc-path-regex-0.1.2.tgz#e73dd3d7b0d7c5ed86fbac6b0ae7d8c6a69d50fa"
-  integrity sha1-5z3T17DXxe2G+6xrCufYxqadUPo=
-
-underscore.string@~2.3.3:
-  version "2.3.3"
-  resolved "https://registry.yarnpkg.com/underscore.string/-/underscore.string-2.3.3.tgz#71c08bf6b428b1133f37e78fa3a21c82f7329b0d"
-  integrity sha1-ccCL9rQosRM/N+ePo6Icgvcymw0=
-
-underscore.string@~3.3.4:
-  version "3.3.5"
-  resolved "https://registry.yarnpkg.com/underscore.string/-/underscore.string-3.3.5.tgz#fc2ad255b8bd309e239cbc5816fd23a9b7ea4023"
-  integrity sha512-g+dpmgn+XBneLmXXo+sGlW5xQEt4ErkS3mgeN2GFbremYeMBSJKr9Wf2KJplQVaiPY/f7FN6atosWYNm9ovrYg==
-  dependencies:
-    sprintf-js "^1.0.3"
-    util-deprecate "^1.0.2"
-
-underscore@1.1.x:
-  version "1.1.7"
-  resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.1.7.tgz#40bab84bad19d230096e8d6ef628bff055d83db0"
-  integrity sha1-QLq4S60Z0jAJbo1u9ii/8FXYPbA=
-
-underscore@^1.5.1:
-  version "1.9.1"
-  resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.9.1.tgz#06dce34a0e68a7babc29b365b8e74b8925203961"
-  integrity sha512-5/4etnCkd9c8gwgowi5/om/mYO5ajCaOgdzj/oW+0eQV9WxKBDZw5+ycmKmeaTXjInS/W0BzpGLo2xR2aBwZdg==
-
-underscore@~1.6.0:
-  version "1.6.0"
-  resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.6.0.tgz#8b38b10cacdef63337b8b24e4ff86d45aea529a8"
-  integrity sha1-izixDKze9jM3uLJOT/htRa6lKag=
-
-union-value@^1.0.0:
-  version "1.0.1"
-  resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.1.tgz#0b6fe7b835aecda61c6ea4d4f02c14221e109847"
-  integrity sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==
-  dependencies:
-    arr-union "^3.1.0"
-    get-value "^2.0.6"
-    is-extendable "^0.1.1"
-    set-value "^2.0.1"
-
-universalify@^0.1.0:
-  version "0.1.2"
-  resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66"
-  integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==
-
-unpipe@1.0.0, unpipe@~1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec"
-  integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=
-
-unset-value@^1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559"
-  integrity sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=
-  dependencies:
-    has-value "^0.3.1"
-    isobject "^3.0.0"
-
-uri-js@^4.2.2:
-  version "4.2.2"
-  resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0"
-  integrity sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==
-  dependencies:
-    punycode "^2.1.0"
-
-uri-path@^1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/uri-path/-/uri-path-1.0.0.tgz#9747f018358933c31de0fccfd82d138e67262e32"
-  integrity sha1-l0fwGDWJM8Md4PzP2C0TjmcmLjI=
-
-urix@^0.1.0:
-  version "0.1.0"
-  resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72"
-  integrity sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=
-
-url-parse@^1.4.3:
-  version "1.4.7"
-  resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.4.7.tgz#a8a83535e8c00a316e403a5db4ac1b9b853ae278"
-  integrity sha512-d3uaVyzDB9tQoSXFvuSUNFibTd9zxd2bkVrDRvF5TmvWWQwqE4lgYJ5m+x1DbecWkw+LK4RNl2CU1hHuOKPVlg==
-  dependencies:
-    querystringify "^2.1.1"
-    requires-port "^1.0.0"
-
-url@0.10.3:
-  version "0.10.3"
-  resolved "https://registry.yarnpkg.com/url/-/url-0.10.3.tgz#021e4d9c7705f21bbf37d03ceb58767402774c64"
-  integrity sha1-Ah5NnHcF8hu/N9A861h2dAJ3TGQ=
-  dependencies:
-    punycode "1.3.2"
-    querystring "0.2.0"
-
-url@^0.11.0:
-  version "0.11.0"
-  resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1"
-  integrity sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=
-  dependencies:
-    punycode "1.3.2"
-    querystring "0.2.0"
-
-use@^3.1.0:
-  version "3.1.1"
-  resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f"
-  integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==
-
-user-home@^1.1.1:
-  version "1.1.1"
-  resolved "https://registry.yarnpkg.com/user-home/-/user-home-1.1.1.tgz#2b5be23a32b63a7c9deb8d0f28d485724a3df190"
-  integrity sha1-K1viOjK2Onyd640PKNSFcko98ZA=
-
-util-deprecate@^1.0.2, util-deprecate@~1.0.1:
-  version "1.0.2"
-  resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
-  integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=
-
-util@0.10.3:
-  version "0.10.3"
-  resolved "https://registry.yarnpkg.com/util/-/util-0.10.3.tgz#7afb1afe50805246489e3db7fe0ed379336ac0f9"
-  integrity sha1-evsa/lCAUkZInj23/g7TeTNqwPk=
-  dependencies:
-    inherits "2.0.1"
-
-util@^0.10.3:
-  version "0.10.4"
-  resolved "https://registry.yarnpkg.com/util/-/util-0.10.4.tgz#3aa0125bfe668a4672de58857d3ace27ecb76901"
-  integrity sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A==
-  dependencies:
-    inherits "2.0.3"
-
-utils-merge@1.0.1:
-  version "1.0.1"
-  resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713"
-  integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=
-
-uuid@3.3.2:
-  version "3.3.2"
-  resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.2.tgz#1b4af4955eb3077c501c23872fc6513811587131"
-  integrity sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==
-
-uuid@^3.0.1, uuid@^3.3.2:
-  version "3.3.3"
-  resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.3.tgz#4568f0216e78760ee1dbf3a4d2cf53e224112866"
-  integrity sha512-pW0No1RGHgzlpHJO1nsVrHKpOEIxkGg1xB+v0ZmdNH5OAeAwzAVrCnI2/6Mtx+Uys6iaylxa+D3g4j63IKKjSQ==
-
-v8flags@~3.1.1:
-  version "3.1.3"
-  resolved "https://registry.yarnpkg.com/v8flags/-/v8flags-3.1.3.tgz#fc9dc23521ca20c5433f81cc4eb9b3033bb105d8"
-  integrity sha512-amh9CCg3ZxkzQ48Mhcb8iX7xpAfYJgePHxWMQCBWECpOSqJUXgY26ncA61UTV0BkPqfhcy6mzwCIoP4ygxpW8w==
-  dependencies:
-    homedir-polyfill "^1.0.1"
-
-validate-npm-package-license@^3.0.1:
-  version "3.0.4"
-  resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a"
-  integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==
-  dependencies:
-    spdx-correct "^3.0.0"
-    spdx-expression-parse "^3.0.0"
-
-vary@~1.1.2:
-  version "1.1.2"
-  resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc"
-  integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=
-
-verror@1.10.0:
-  version "1.10.0"
-  resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400"
-  integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=
-  dependencies:
-    assert-plus "^1.0.0"
-    core-util-is "1.0.2"
-    extsprintf "^1.2.0"
-
-vm-browserify@0.0.4:
-  version "0.0.4"
-  resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-0.0.4.tgz#5d7ea45bbef9e4a6ff65f95438e0a87c357d5a73"
-  integrity sha1-XX6kW7755Kb/ZflUOOCofDV9WnM=
-  dependencies:
-    indexof "0.0.1"
-
-watchpack@^0.2.1:
-  version "0.2.9"
-  resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-0.2.9.tgz#62eaa4ab5e5ba35fdfc018275626e3c0f5e3fb0b"
-  integrity sha1-Yuqkq15bo1/fwBgnVibjwPXj+ws=
-  dependencies:
-    async "^0.9.0"
-    chokidar "^1.0.0"
-    graceful-fs "^4.1.2"
-
-webpack-core@~0.6.9:
-  version "0.6.9"
-  resolved "https://registry.yarnpkg.com/webpack-core/-/webpack-core-0.6.9.tgz#fc571588c8558da77be9efb6debdc5a3b172bdc2"
-  integrity sha1-/FcViMhVjad76e+23r3Fo7FyvcI=
-  dependencies:
-    source-list-map "~0.1.7"
-    source-map "~0.4.1"
-
-webpack-dev-middleware@^1.10.2:
-  version "1.12.2"
-  resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-1.12.2.tgz#f8fc1120ce3b4fc5680ceecb43d777966b21105e"
-  integrity sha512-FCrqPy1yy/sN6U/SaEZcHKRXGlqU0DUaEBL45jkUYoB8foVb6wCnbIJ1HKIx+qUFTW+3JpVcCJCxZ8VATL4e+A==
-  dependencies:
-    memory-fs "~0.4.1"
-    mime "^1.5.0"
-    path-is-absolute "^1.0.0"
-    range-parser "^1.0.3"
-    time-stamp "^2.0.0"
-
-webpack-dev-server@^1.12.1:
-  version "1.16.5"
-  resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-1.16.5.tgz#0cbd5f2d2ac8d4e593aacd5c9702e7bbd5e59892"
-  integrity sha1-DL1fLSrI1OWTqs1clwLnu9XlmJI=
-  dependencies:
-    compression "^1.5.2"
-    connect-history-api-fallback "^1.3.0"
-    express "^4.13.3"
-    http-proxy-middleware "~0.17.1"
-    open "0.0.5"
-    optimist "~0.6.1"
-    serve-index "^1.7.2"
-    sockjs "^0.3.15"
-    sockjs-client "^1.0.3"
-    stream-cache "~0.0.1"
-    strip-ansi "^3.0.0"
-    supports-color "^3.1.1"
-    webpack-dev-middleware "^1.10.2"
-
-webpack@^1.12.6:
-  version "1.15.0"
-  resolved "https://registry.yarnpkg.com/webpack/-/webpack-1.15.0.tgz#4ff31f53db03339e55164a9d468ee0324968fe98"
-  integrity sha1-T/MfU9sDM55VFkqdRo7gMklo/pg=
-  dependencies:
-    acorn "^3.0.0"
-    async "^1.3.0"
-    clone "^1.0.2"
-    enhanced-resolve "~0.9.0"
-    interpret "^0.6.4"
-    loader-utils "^0.2.11"
-    memory-fs "~0.3.0"
-    mkdirp "~0.5.0"
-    node-libs-browser "^0.7.0"
-    optimist "~0.6.0"
-    supports-color "^3.1.0"
-    tapable "~0.1.8"
-    uglify-js "~2.7.3"
-    watchpack "^0.2.1"
-    webpack-core "~0.6.9"
-
-websocket-driver@>=0.5.1:
-  version "0.7.3"
-  resolved "https://registry.yarnpkg.com/websocket-driver/-/websocket-driver-0.7.3.tgz#a2d4e0d4f4f116f1e6297eba58b05d430100e9f9"
-  integrity sha512-bpxWlvbbB459Mlipc5GBzzZwhoZgGEZLuqPaR0INBGnPAY1vdBX6hPnoFXiw+3yWxDuHyQjO2oXTMyS8A5haFg==
-  dependencies:
-    http-parser-js ">=0.4.0 <0.4.11"
-    safe-buffer ">=5.1.0"
-    websocket-extensions ">=0.1.1"
-
-websocket-extensions@>=0.1.1:
-  version "0.1.3"
-  resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.3.tgz#5d2ff22977003ec687a4b87073dfbbac146ccf29"
-  integrity sha512-nqHUnMXmBzT0w570r2JpJxfiSD1IzoI+HGVdd3aZ0yNi3ngvQ4jv1dtHt5VGxfI2yj5yqImPhOK4vmIh2xMbGg==
-
-when@~3.7.5:
-  version "3.7.8"
-  resolved "https://registry.yarnpkg.com/when/-/when-3.7.8.tgz#c7130b6a7ea04693e842cdc9e7a1f2aa39a39f82"
-  integrity sha1-xxMLan6gRpPoQs3J56Hyqjmjn4I=
-
-which-module@^2.0.0:
-  version "2.0.0"
-  resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a"
-  integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=
-
-which@^1.1.1, which@^1.2.14, which@^1.2.9, which@~1.3.0:
-  version "1.3.1"
-  resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a"
-  integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==
-  dependencies:
-    isexe "^2.0.0"
-
-wide-align@^1.1.0:
-  version "1.1.3"
-  resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457"
-  integrity sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==
-  dependencies:
-    string-width "^1.0.2 || 2"
-
-window-size@0.1.0:
-  version "0.1.0"
-  resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.1.0.tgz#5438cd2ea93b202efa3a19fe8887aee7c94f9c9d"
-  integrity sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0=
-
-window-size@^0.1.2, window-size@^0.1.4:
-  version "0.1.4"
-  resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.1.4.tgz#f8e1aa1ee5a53ec5bf151ffa09742a6ad7697876"
-  integrity sha1-+OGqHuWlPsW/FR/6CXQqatdpeHY=
-
-wordwrap@0.0.2:
-  version "0.0.2"
-  resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.2.tgz#b79669bb42ecb409f83d583cad52ca17eaa1643f"
-  integrity sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=
-
-wordwrap@^1.0.0, wordwrap@~1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb"
-  integrity sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=
-
-wordwrap@~0.0.2:
-  version "0.0.3"
-  resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.3.tgz#a3d5da6cd5c0bc0008d37234bbaf1bed63059107"
-  integrity sha1-o9XabNXAvAAI03I0u68b7WMFkQc=
-
-wrap-ansi@^2.0.0:
-  version "2.1.0"
-  resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85"
-  integrity sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=
-  dependencies:
-    string-width "^1.0.1"
-    strip-ansi "^3.0.1"
-
-wrappy@1:
-  version "1.0.2"
-  resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
-  integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=
-
-write@^0.2.1:
-  version "0.2.1"
-  resolved "https://registry.yarnpkg.com/write/-/write-0.2.1.tgz#5fc03828e264cea3fe91455476f7a3c566cb0757"
-  integrity sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=
-  dependencies:
-    mkdirp "^0.5.1"
-
-xml2js@0.4.19:
-  version "0.4.19"
-  resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.19.tgz#686c20f213209e94abf0d1bcf1efaa291c7827a7"
-  integrity sha512-esZnJZJOiJR9wWKMyuvSE1y6Dq5LCuJanqhxslH2bxM6duahNZ+HMpCLhBQGZkbX6xRf8x1Y2eJlgt2q3qo49Q==
-  dependencies:
-    sax ">=0.6.0"
-    xmlbuilder "~9.0.1"
-
-xmlbuilder@~9.0.1:
-  version "9.0.7"
-  resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-9.0.7.tgz#132ee63d2ec5565c557e20f4c22df9aca686b10d"
-  integrity sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0=
-
-xtend@^4.0.0:
-  version "4.0.2"
-  resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54"
-  integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==
-
-y18n@^3.2.0:
-  version "3.2.1"
-  resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.1.tgz#6d15fba884c08679c0d77e88e7759e811e07fa41"
-  integrity sha1-bRX7qITAhnnA136I53WegR4H+kE=
-
-"y18n@^3.2.1 || ^4.0.0":
-  version "4.0.0"
-  resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b"
-  integrity sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==
-
-yallist@^2.1.2:
-  version "2.1.2"
-  resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52"
-  integrity sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=
-
-yallist@^3.0.0, yallist@^3.0.3:
-  version "3.1.1"
-  resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd"
-  integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==
-
-yargs-parser@^11.1.1:
-  version "11.1.1"
-  resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-11.1.1.tgz#879a0865973bca9f6bab5cbdf3b1c67ec7d3bcf4"
-  integrity sha512-C6kB/WJDiaxONLJQnF8ccx9SEeoTTLek8RVbaOIsrAUS8VrBEXfmeSnCZxygc+XC2sNMBIwOOnfcxiynjHsVSQ==
-  dependencies:
-    camelcase "^5.0.0"
-    decamelize "^1.2.0"
-
-yargs@^12.0.5:
-  version "12.0.5"
-  resolved "https://registry.yarnpkg.com/yargs/-/yargs-12.0.5.tgz#05f5997b609647b64f66b81e3b4b10a368e7ad13"
-  integrity sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw==
-  dependencies:
-    cliui "^4.0.0"
-    decamelize "^1.2.0"
-    find-up "^3.0.0"
-    get-caller-file "^1.0.1"
-    os-locale "^3.0.0"
-    require-directory "^2.1.1"
-    require-main-filename "^1.0.1"
-    set-blocking "^2.0.0"
-    string-width "^2.0.0"
-    which-module "^2.0.0"
-    y18n "^3.2.1 || ^4.0.0"
-    yargs-parser "^11.1.1"
-
-yargs@^3.32.0:
-  version "3.32.0"
-  resolved "https://registry.yarnpkg.com/yargs/-/yargs-3.32.0.tgz#03088e9ebf9e756b69751611d2a5ef591482c995"
-  integrity sha1-AwiOnr+edWtpdRYR0qXvWRSCyZU=
-  dependencies:
-    camelcase "^2.0.1"
-    cliui "^3.0.3"
-    decamelize "^1.1.1"
-    os-locale "^1.4.0"
-    string-width "^1.0.1"
-    window-size "^0.1.4"
-    y18n "^3.2.0"
-
-yargs@~3.10.0:
-  version "3.10.0"
-  resolved "https://registry.yarnpkg.com/yargs/-/yargs-3.10.0.tgz#f7ee7bd857dd7c1d2d38c0e74efbd681d1431fd1"
-  integrity sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=
-  dependencies:
-    camelcase "^1.0.2"
-    cliui "^2.1.0"
-    decamelize "^1.0.0"
-    window-size "0.1.0"
-
-yargs@~3.27.0:
-  version "3.27.0"
-  resolved "https://registry.yarnpkg.com/yargs/-/yargs-3.27.0.tgz#21205469316e939131d59f2da0c6d7f98221ea40"
-  integrity sha1-ISBUaTFuk5Ex1Z8toMbX+YIh6kA=
-  dependencies:
-    camelcase "^1.2.1"
-    cliui "^2.1.0"
-    decamelize "^1.0.0"
-    os-locale "^1.4.0"
-    window-size "^0.1.2"
-    y18n "^3.2.0"

From 1f61f2125015d1efee6437d8aa97e86030246a93 Mon Sep 17 00:00:00 2001
From: Nils Knappmeier <github@knappi.org>
Date: Sat, 30 Nov 2019 22:38:06 +0100
Subject: [PATCH 04/24] chore: configure prettier and eslint

- add prettier to do formatting
- add eslint-config-prettier to
  disable rules conflicting with prettier
- remove eslint from grunt workflow
- use lint-stage to lint and format
  on precommit
- use eslint and prettier in travis directly
- remove rules that are already part of
  the "recommended" ruleset

That rational is that eslint and prettier should be run in
Travis-CI, on commit and as IDE integration (highlighting
errors directlry). They don't need to be run along with
test-cases. Getting linting errors when running the tests
because of missing semicolons is just annoying, but doesn't
help the overall code-quality.
---
 .eslintignore                                 |   24 +
 .eslintrc.js                                  |  153 +-
 .gitignore                                    |   15 +-
 .prettierignore                               |   21 +
 .travis.yml                                   |    2 +
 Gruntfile.js                                  |   17 +-
 bench/.eslintrc                               |    3 +-
 .../multi-nodejs-test/.eslintrc.js            |   17 +-
 package-lock.json                             | 2137 +++++++++++++----
 package.json                                  |   26 +-
 prettier.config.js                            |    5 +
 spec/.eslintrc                                |    5 +-
 spec/amd-runtime.html                         |    4 +-
 spec/amd.html                                 |    4 +-
 spec/index.html                               |    2 +-
 spec/umd-runtime.html                         |    4 +-
 spec/umd.html                                 |    4 +-
 spec/{env => vendor}/json2.js                 |    0
 spec/{env => vendor}/require.js               |    0
 19 files changed, 1890 insertions(+), 553 deletions(-)
 create mode 100644 .eslintignore
 create mode 100644 .prettierignore
 create mode 100644 prettier.config.js
 rename spec/{env => vendor}/json2.js (100%)
 rename spec/{env => vendor}/require.js (100%)

diff --git a/.eslintignore b/.eslintignore
new file mode 100644
index 000000000..a64673018
--- /dev/null
+++ b/.eslintignore
@@ -0,0 +1,24 @@
+.rvmrc
+.DS_Store
+/tmp/
+*.sublime-project
+*.sublime-workspace
+npm-debug.log
+sauce_connect.log*
+.idea
+yarn-error.log
+node_modules
+/handlebars-release.tgz
+
+# Generated files
+lib/handlebars/compiler/parser.js
+/coverage/
+/dist/
+/integration-testing/*/dist/
+
+# Third-party or files that must remain unchanged
+/spec/expected/
+/spec/vendor
+
+# JS-Snippets
+src/*.js
diff --git a/.eslintrc.js b/.eslintrc.js
index 5c55b10f9..0abcd5806 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -1,118 +1,67 @@
 module.exports = {
-  "extends": ["eslint:recommended","plugin:compat/recommended"],
-  "globals": {
-    "self": false
+  extends: ['eslint:recommended', 'plugin:compat/recommended', 'prettier'],
+  globals: {
+    self: false
   },
-  "env": {
-    "node": true,
-    "es6": true
+  env: {
+    node: true,
+    es6: true
   },
-  "rules": {
-    // overrides eslint:recommended defaults
-    "no-sparse-arrays": "off",
-    "no-func-assign": "off",
-    "no-console": "warn",
-    "no-debugger": "warn",
-    "no-unreachable": "warn",
-
-    // Possible Errors //
-    //-----------------//
-    "no-unsafe-negation": "error",
+  rules: {
+    'no-console': 'warn',
 
+    // temporarily disabled until the violating places are fixed.
+    'no-func-assign': 'off',
+    'no-sparse-arrays': 'off',
 
     // Best Practices //
     //----------------//
-    "curly": "error",
-    "default-case": "warn",
-    "dot-notation": ["error", { "allowKeywords": false }],
-    "guard-for-in": "warn",
-    "no-alert": "error",
-    "no-caller": "error",
-    "no-div-regex": "warn",
-    "no-eval": "error",
-    "no-extend-native": "error",
-    "no-extra-bind": "error",
-    "no-floating-decimal": "error",
-    "no-implied-eval": "error",
-    "no-iterator": "error",
-    "no-labels": "error",
-    "no-lone-blocks": "error",
-    "no-loop-func": "error",
-    "no-multi-spaces": "error",
-    "no-multi-str": "warn",
-    "no-global-assign": "error",
-    "no-new": "error",
-    "no-new-func": "error",
-    "no-new-wrappers": "error",
-    "no-octal-escape": "error",
-    "no-process-env": "error",
-    "no-proto": "error",
-    "no-return-assign": "error",
-    "no-script-url": "error",
-    "no-self-compare": "error",
-    "no-sequences": "error",
-    "no-throw-literal": "error",
-    "no-unused-expressions": "error",
-    "no-warning-comments": "warn",
-    "no-with": "error",
-    "radix": "error",
-    "wrap-iife": "error",
-    "no-prototype-builtins": "error",
-
+    'default-case': 'warn',
+    'dot-notation': ['error', { allowKeywords: false }],
+    'guard-for-in': 'warn',
+    'no-alert': 'error',
+    'no-caller': 'error',
+    'no-div-regex': 'warn',
+    'no-eval': 'error',
+    'no-extend-native': 'error',
+    'no-extra-bind': 'error',
+    'no-floating-decimal': 'error',
+    'no-implied-eval': 'error',
+    'no-iterator': 'error',
+    'no-labels': 'error',
+    'no-lone-blocks': 'error',
+    'no-loop-func': 'error',
+    'no-multi-str': 'warn',
+    'no-global-assign': 'error',
+    'no-new': 'error',
+    'no-new-func': 'error',
+    'no-new-wrappers': 'error',
+    'no-octal-escape': 'error',
+    'no-process-env': 'error',
+    'no-proto': 'error',
+    'no-return-assign': 'error',
+    'no-script-url': 'error',
+    'no-self-compare': 'error',
+    'no-sequences': 'error',
+    'no-throw-literal': 'error',
+    'no-unused-expressions': 'error',
+    'no-warning-comments': 'warn',
+    'no-with': 'error',
+    radix: 'error',
 
     // Variables //
     //-----------//
-    "no-catch-shadow": "error",
-    "no-label-var": "error",
-    "no-shadow-restricted-names": "error",
-    "no-undef-init": "error",
-    "no-use-before-define": ["error", "nofunc"],
-
-
-    // Stylistic Issues //
-    //------------------//
-    "comma-dangle": ["error", "never"],
-    "quote-props": ["error", "as-needed", { "keywords": true, "unnecessary": false }],
-    "brace-style": ["error", "1tbs", { "allowSingleLine": true }],
-    "camelcase": "error",
-    "comma-spacing": ["error", { "before": false, "after": true }],
-    "comma-style": ["error", "last"],
-    "consistent-this": ["warn", "self"],
-    "eol-last": "error",
-    "func-style": ["error", "declaration"],
-    "key-spacing": ["error", {
-      "beforeColon": false,
-      "afterColon": true
-    }],
-    "new-cap": "error",
-    "new-parens": "error",
-    "no-array-constructor": "error",
-    "no-lonely-if": "error",
-    "no-mixed-spaces-and-tabs": "error",
-    "no-nested-ternary": "warn",
-    "no-new-object": "error",
-    "no-spaced-func": "error",
-    "no-trailing-spaces": "error",
-    "no-extra-parens": ["error", "functions"],
-    "quotes": ["error", "single", "avoid-escape"],
-    "semi": "error",
-    "semi-spacing": ["error", { "before": false, "after": true }],
-    "keyword-spacing": "error",
-    "space-before-blocks": ["error", "always"],
-    "space-before-function-paren": ["error", { "anonymous": "never", "named": "never" }],
-    "space-in-parens": ["error", "never"],
-    "space-infix-ops": "error",
-    "space-unary-ops": "error",
-    "spaced-comment": ["error", "always", { "markers": [","] }],
-    "wrap-regex": "warn",
+    'no-label-var': 'error',
+    'no-undef-init': 'error',
+    'no-use-before-define': ['error', 'nofunc'],
 
     // ECMAScript 6 //
     //--------------//
-    "no-var": "warn"
+    'no-var': 'error'
   },
-  "parserOptions": {
-    "sourceType": "module",
-    "ecmaVersion": 6,
-    "ecmaFeatures": {}
+  parserOptions: {
+    sourceType: 'module',
+    ecmaVersion: 6,
+    ecmaFeatures: {}
   }
 };
diff --git a/.gitignore b/.gitignore
index 4c97eecd6..8922abaf6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,15 +1,18 @@
-vendor
 .rvmrc
 .DS_Store
-lib/handlebars/compiler/parser.js
-/dist/
 /tmp/
-/coverage/
-node_modules
 *.sublime-project
 *.sublime-workspace
 npm-debug.log
 sauce_connect.log*
 .idea
-yarn-error.log
+/yarn-error.log
+/yarn.lock
+node_modules
 /handlebars-release.tgz
+
+# Generated files
+lib/handlebars/compiler/parser.js
+/coverage/
+/dist/
+/integration-testing/*/dist/
diff --git a/.prettierignore b/.prettierignore
new file mode 100644
index 000000000..b6bc46217
--- /dev/null
+++ b/.prettierignore
@@ -0,0 +1,21 @@
+.rvmrc
+.DS_Store
+/tmp/
+*.sublime-project
+*.sublime-workspace
+npm-debug.log
+sauce_connect.log*
+.idea
+yarn-error.log
+node_modules
+/handlebars-release.tgz
+
+# Generated files
+lib/handlebars/compiler/parser.js
+/coverage/
+/dist/
+/integration-testing/*/dist/
+
+# Third-party or files that must remain unchanged
+/spec/expected/
+/spec/vendor
diff --git a/.travis.yml b/.travis.yml
index ce9690a9c..a6b141a22 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -2,6 +2,8 @@ language: node_js
 before_install:
 - npm install -g grunt-cli
 script:
+- npm run lint
+- npm run check-format
 - grunt --stack travis
 email:
   on_failure: change
diff --git a/Gruntfile.js b/Gruntfile.js
index 430a0c60a..a471f67e7 100644
--- a/Gruntfile.js
+++ b/Gruntfile.js
@@ -4,19 +4,6 @@ module.exports = function(grunt) {
   grunt.initConfig({
     pkg: grunt.file.readJSON('package.json'),
 
-    eslint: {
-      files: [
-        '*.js',
-        'bench/**/*.js',
-        'tasks/**/*.js',
-        'lib/**/!(*.min|parser).js',
-        'spec/**/!(*.amd|json2|require).js',
-        'integration-testing/multi-nodejs-test/*.js',
-        'integration-testing/webpack-test/*.js',
-        'integration-testing/webpack-test/src/*.js'
-      ]
-    },
-
     clean: ['tmp', 'dist', 'lib/handlebars/compiler/parser.js', 'integration-testing/**/node_modules'],
 
     copy: {
@@ -215,7 +202,6 @@ module.exports = function(grunt) {
 
   // Build a new version of the library
   this.registerTask('build', 'Builds a distributable version of the current project', [
-                    'eslint',
                     'bgShell:checkTypes',
                     'parser',
                     'node',
@@ -226,7 +212,7 @@ module.exports = function(grunt) {
   this.registerTask('globals', ['webpack']);
   this.registerTask('tests', ['concat:tests']);
 
-  this.registerTask('release', 'Build final packages', ['eslint', 'amd', 'uglify', 'test:min', 'copy:dist', 'copy:components', 'copy:cdnjs']);
+  this.registerTask('release', 'Build final packages', ['amd', 'uglify', 'test:min', 'copy:dist', 'copy:components', 'copy:cdnjs']);
 
   // Load tasks from npm
   grunt.loadNpmTasks('grunt-contrib-clean');
@@ -238,7 +224,6 @@ module.exports = function(grunt) {
   grunt.loadNpmTasks('grunt-contrib-watch');
   grunt.loadNpmTasks('grunt-babel');
   grunt.loadNpmTasks('grunt-bg-shell');
-  grunt.loadNpmTasks('grunt-eslint');
   grunt.loadNpmTasks('@knappi/grunt-saucelabs');
   grunt.loadNpmTasks('grunt-webpack');
 
diff --git a/bench/.eslintrc b/bench/.eslintrc
index e03f181ed..823629cd7 100644
--- a/bench/.eslintrc
+++ b/bench/.eslintrc
@@ -1,4 +1,5 @@
 {
+  "extends": "prettier",
   "globals": {
     "require": true
   },
@@ -11,4 +12,4 @@
     "handle-callback-err": 0,
     "no-console": 0
   }
-}
\ No newline at end of file
+}
diff --git a/integration-testing/multi-nodejs-test/.eslintrc.js b/integration-testing/multi-nodejs-test/.eslintrc.js
index 7f583d1c5..fcc705596 100644
--- a/integration-testing/multi-nodejs-test/.eslintrc.js
+++ b/integration-testing/multi-nodejs-test/.eslintrc.js
@@ -1,12 +1,13 @@
 module.exports = {
-  "extends": "eslint:recommended",
-  "globals": {
-    "self": false
+  extends: ['eslint:recommended', 'plugin:es5/no-es2015', 'prettier'],
+  globals: {
+    self: false
   },
-  "env": {
-    "node": true
+  env: {
+    node: true
   },
-  "rules": {
-    'no-console': 'off'
+  rules: {
+    'no-console': 'off',
+    'no-var': 'off'
   }
-}
\ No newline at end of file
+};
diff --git a/package-lock.json b/package-lock.json
index 6ed12f6bb..3a36a15af 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,9 +1,66 @@
 {
   "name": "handlebars",
-  "version": "4.5.2",
+  "version": "4.5.3",
   "lockfileVersion": 1,
   "requires": true,
   "dependencies": {
+    "@babel/code-frame": {
+      "version": "7.5.5",
+      "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.5.5.tgz",
+      "integrity": "sha512-27d4lZoomVyo51VegxI20xZPuSHusqbQag/ztrBC7wegWoQ1nLREPVSKSW8byhTlzTKyNE4ifaTA6lCp7JjpFw==",
+      "dev": true,
+      "requires": {
+        "@babel/highlight": "^7.0.0"
+      }
+    },
+    "@babel/highlight": {
+      "version": "7.5.0",
+      "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.5.0.tgz",
+      "integrity": "sha512-7dV4eu9gBxoM0dAnj/BCFDW9LFU0zvTrkq0ugM7pnHEgguOEeOz1so2ZghEdzviYzQEED0r4EAgpsBChKy1TRQ==",
+      "dev": true,
+      "requires": {
+        "chalk": "^2.0.0",
+        "esutils": "^2.0.2",
+        "js-tokens": "^4.0.0"
+      },
+      "dependencies": {
+        "ansi-styles": {
+          "version": "3.2.1",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+          "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+          "dev": true,
+          "requires": {
+            "color-convert": "^1.9.0"
+          }
+        },
+        "chalk": {
+          "version": "2.4.2",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+          "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "^3.2.1",
+            "escape-string-regexp": "^1.0.5",
+            "supports-color": "^5.3.0"
+          }
+        },
+        "js-tokens": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
+          "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
+          "dev": true
+        },
+        "supports-color": {
+          "version": "5.5.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+          "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+          "dev": true,
+          "requires": {
+            "has-flag": "^3.0.0"
+          }
+        }
+      }
+    },
     "@babel/runtime": {
       "version": "7.6.3",
       "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.6.3.tgz",
@@ -83,6 +140,41 @@
         }
       }
     },
+    "@nodelib/fs.scandir": {
+      "version": "2.1.3",
+      "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz",
+      "integrity": "sha512-eGmwYQn3gxo4r7jdQnkrrN6bY478C3P+a/y72IJukF8LjB6ZHeB3c+Ehacj3sYeSmUXGlnA67/PmbM9CVwL7Dw==",
+      "dev": true,
+      "requires": {
+        "@nodelib/fs.stat": "2.0.3",
+        "run-parallel": "^1.1.9"
+      }
+    },
+    "@nodelib/fs.stat": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.3.tgz",
+      "integrity": "sha512-bQBFruR2TAwoevBEd/NWMoAAtNGzTRgdrqnYCc7dhzfoNvqPzLyqlEQnzZ3kVnNrSp25iyxE00/3h2fqGAGArA==",
+      "dev": true
+    },
+    "@nodelib/fs.walk": {
+      "version": "1.2.4",
+      "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.4.tgz",
+      "integrity": "sha512-1V9XOY4rDW0rehzbrcqAmHnz8e7SKvX27gh8Gt2WgB0+pdzdiLV83p72kZPU+jvMbS1qU5mauP2iOvO8rhmurQ==",
+      "dev": true,
+      "requires": {
+        "@nodelib/fs.scandir": "2.1.3",
+        "fastq": "^1.6.0"
+      }
+    },
+    "@samverschueren/stream-to-observable": {
+      "version": "0.3.0",
+      "resolved": "https://registry.npmjs.org/@samverschueren/stream-to-observable/-/stream-to-observable-0.3.0.tgz",
+      "integrity": "sha512-MI4Xx6LHs4Webyvi6EbspgyAb4D2Q2VtnCQ1blOJcoLS6mVa8lNN2rkIy1CVxfTUpoyIbCTkXES1rLXztFD1lg==",
+      "dev": true,
+      "requires": {
+        "any-observable": "^0.3.0"
+      }
+    },
     "@sinonjs/commons": {
       "version": "1.6.0",
       "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.6.0.tgz",
@@ -127,6 +219,41 @@
       "integrity": "sha512-+iTbntw2IZPb/anVDbypzfQa+ay64MW0Zo8aJ8gZPWMMK6/OubMVb6lUPMagqjOPnmtauXnFCACVl3O7ogjeqQ==",
       "dev": true
     },
+    "@types/events": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz",
+      "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==",
+      "dev": true
+    },
+    "@types/glob": {
+      "version": "7.1.1",
+      "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz",
+      "integrity": "sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==",
+      "dev": true,
+      "requires": {
+        "@types/events": "*",
+        "@types/minimatch": "*",
+        "@types/node": "*"
+      }
+    },
+    "@types/minimatch": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz",
+      "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==",
+      "dev": true
+    },
+    "@types/node": {
+      "version": "12.12.14",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.14.tgz",
+      "integrity": "sha512-u/SJDyXwuihpwjXy7hOOghagLEV1KdAST6syfnOk6QZAMzZuWZqXy5aYYZbh8Jdpd4escVFP0MvftHNDb9pruA==",
+      "dev": true
+    },
+    "@types/normalize-package-data": {
+      "version": "2.4.0",
+      "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz",
+      "integrity": "sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==",
+      "dev": true
+    },
     "@types/parsimmon": {
       "version": "1.10.0",
       "resolved": "https://registry.npmjs.org/@types/parsimmon/-/parsimmon-1.10.0.tgz",
@@ -162,21 +289,10 @@
       "dev": true
     },
     "acorn-jsx": {
-      "version": "3.0.1",
-      "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz",
-      "integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=",
-      "dev": true,
-      "requires": {
-        "acorn": "^3.0.4"
-      },
-      "dependencies": {
-        "acorn": {
-          "version": "3.3.0",
-          "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz",
-          "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=",
-          "dev": true
-        }
-      }
+      "version": "5.1.0",
+      "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.1.0.tgz",
+      "integrity": "sha512-tMUqwBWfLFbJbizRmEcWSLw6HnFzfdJs2sOJEOwwtVPMoH/0Ay+E703oZz78VSXZiiDcZrQ5XKjPIUQixhmgVw==",
+      "dev": true
     },
     "agent-base": {
       "version": "4.3.0",
@@ -187,24 +303,36 @@
         "es6-promisify": "^5.0.0"
       }
     },
+    "aggregate-error": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.0.1.tgz",
+      "integrity": "sha512-quoaXsZ9/BLNae5yiNoUz+Nhkwz83GhWwtYFglcjEQB2NDHCIpApbqXxIFnm4Pq/Nvhrsq5sYJFyohrrxnTGAA==",
+      "dev": true,
+      "requires": {
+        "clean-stack": "^2.0.0",
+        "indent-string": "^4.0.0"
+      },
+      "dependencies": {
+        "indent-string": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz",
+          "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==",
+          "dev": true
+        }
+      }
+    },
     "ajv": {
-      "version": "5.5.2",
-      "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz",
-      "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=",
+      "version": "6.10.2",
+      "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz",
+      "integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==",
       "dev": true,
       "requires": {
-        "co": "^4.6.0",
-        "fast-deep-equal": "^1.0.0",
+        "fast-deep-equal": "^2.0.1",
         "fast-json-stable-stringify": "^2.0.0",
-        "json-schema-traverse": "^0.3.0"
+        "json-schema-traverse": "^0.4.1",
+        "uri-js": "^4.2.2"
       }
     },
-    "ajv-keywords": {
-      "version": "2.1.1",
-      "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-2.1.1.tgz",
-      "integrity": "sha1-YXmX/F9gV2iUxDX5QNgZ4TW4B2I=",
-      "dev": true
-    },
     "align-text": {
       "version": "0.1.4",
       "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz",
@@ -249,6 +377,12 @@
       "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
       "dev": true
     },
+    "any-observable": {
+      "version": "0.3.0",
+      "resolved": "https://registry.npmjs.org/any-observable/-/any-observable-0.3.0.tgz",
+      "integrity": "sha512-/FQM1EDkTsf63Ub2C6O7GuYFDsSXUwsaZDurV0np41ocwq0jthUAYCmhBX9f+KwlaCgIuWyr/4WlUQUBfKfZog==",
+      "dev": true
+    },
     "anymatch": {
       "version": "1.3.2",
       "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz",
@@ -327,6 +461,12 @@
       "integrity": "sha1-42jqFfibxwaff/uJrsOmx9SsItQ=",
       "dev": true
     },
+    "array-union": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz",
+      "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==",
+      "dev": true
+    },
     "array-unique": {
       "version": "0.2.1",
       "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz",
@@ -404,6 +544,12 @@
       "integrity": "sha1-ECyenpAF0+fjgpvwxPok7oYu6bk=",
       "dev": true
     },
+    "astral-regex": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz",
+      "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==",
+      "dev": true
+    },
     "async": {
       "version": "1.5.2",
       "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz",
@@ -974,19 +1120,27 @@
         }
       }
     },
-    "caller-path": {
-      "version": "0.1.0",
-      "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz",
-      "integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=",
+    "caller-callsite": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz",
+      "integrity": "sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ=",
       "dev": true,
       "requires": {
-        "callsites": "^0.2.0"
+        "callsites": "^2.0.0"
+      },
+      "dependencies": {
+        "callsites": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz",
+          "integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=",
+          "dev": true
+        }
       }
     },
     "callsites": {
-      "version": "0.2.0",
-      "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz",
-      "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=",
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
+      "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
       "dev": true
     },
     "camelcase": {
@@ -1069,9 +1223,9 @@
       }
     },
     "chardet": {
-      "version": "0.4.2",
-      "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.4.2.tgz",
-      "integrity": "sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I=",
+      "version": "0.7.0",
+      "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz",
+      "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==",
       "dev": true
     },
     "check-error": {
@@ -1097,10 +1251,10 @@
         "readdirp": "^2.0.0"
       }
     },
-    "circular-json": {
-      "version": "0.3.3",
-      "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz",
-      "integrity": "sha1-gVyZ6oT2gJUp0vRXkb34JxE1LWY=",
+    "ci-info": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz",
+      "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==",
       "dev": true
     },
     "class-utils": {
@@ -1132,6 +1286,12 @@
         }
       }
     },
+    "clean-stack": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz",
+      "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==",
+      "dev": true
+    },
     "cli": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/cli/-/cli-1.0.1.tgz",
@@ -1176,6 +1336,44 @@
         "restore-cursor": "^2.0.0"
       }
     },
+    "cli-truncate": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-0.2.1.tgz",
+      "integrity": "sha1-nxXPuwcFAFNpIWxiasfQWrkN1XQ=",
+      "dev": true,
+      "requires": {
+        "slice-ansi": "0.0.4",
+        "string-width": "^1.0.1"
+      },
+      "dependencies": {
+        "is-fullwidth-code-point": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
+          "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
+          "dev": true,
+          "requires": {
+            "number-is-nan": "^1.0.0"
+          }
+        },
+        "slice-ansi": {
+          "version": "0.0.4",
+          "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz",
+          "integrity": "sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU=",
+          "dev": true
+        },
+        "string-width": {
+          "version": "1.0.2",
+          "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
+          "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
+          "dev": true,
+          "requires": {
+            "code-point-at": "^1.0.0",
+            "is-fullwidth-code-point": "^1.0.0",
+            "strip-ansi": "^3.0.0"
+          }
+        }
+      }
+    },
     "cli-width": {
       "version": "2.2.0",
       "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz",
@@ -1207,12 +1405,6 @@
       "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=",
       "dev": true
     },
-    "co": {
-      "version": "4.6.0",
-      "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
-      "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=",
-      "dev": true
-    },
     "code-point-at": {
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
@@ -1384,7 +1576,7 @@
     "connect-history-api-fallback": {
       "version": "1.6.0",
       "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz",
-      "integrity": "sha1-izIIk1kwjRERFdgcrT/Oq4iPl7w=",
+      "integrity": "sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg==",
       "dev": true
     },
     "connect-livereload": {
@@ -1417,7 +1609,7 @@
     "content-type": {
       "version": "1.0.4",
       "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
-      "integrity": "sha1-4TjMdeBAxyexlm/l5fjJruJW/js=",
+      "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==",
       "dev": true
     },
     "continuable-cache": {
@@ -1465,13 +1657,55 @@
       "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=",
       "dev": true
     },
+    "cosmiconfig": {
+      "version": "5.2.1",
+      "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz",
+      "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==",
+      "dev": true,
+      "requires": {
+        "import-fresh": "^2.0.0",
+        "is-directory": "^0.3.1",
+        "js-yaml": "^3.13.1",
+        "parse-json": "^4.0.0"
+      },
+      "dependencies": {
+        "esprima": {
+          "version": "4.0.1",
+          "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
+          "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
+          "dev": true
+        },
+        "js-yaml": {
+          "version": "3.13.1",
+          "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz",
+          "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==",
+          "dev": true,
+          "requires": {
+            "argparse": "^1.0.7",
+            "esprima": "^4.0.0"
+          }
+        },
+        "parse-json": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz",
+          "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=",
+          "dev": true,
+          "requires": {
+            "error-ex": "^1.3.1",
+            "json-parse-better-errors": "^1.0.1"
+          }
+        }
+      }
+    },
     "cross-spawn": {
-      "version": "5.1.0",
-      "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz",
-      "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=",
+      "version": "6.0.5",
+      "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz",
+      "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==",
       "dev": true,
       "requires": {
-        "lru-cache": "^4.0.1",
+        "nice-try": "^1.0.4",
+        "path-key": "^2.0.1",
+        "semver": "^5.5.0",
         "shebang-command": "^1.2.0",
         "which": "^1.2.9"
       }
@@ -1506,6 +1740,12 @@
         "assert-plus": "^1.0.0"
       }
     },
+    "date-fns": {
+      "version": "1.30.1",
+      "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-1.30.1.tgz",
+      "integrity": "sha512-hBSVCvSmWC+QypYObzwGOd9wqdDpOt+0wl0KbU+R+uuZBS1jN8VsD1ss3irQDknRj5NvxiTF6oj/nDRnN/UQNw==",
+      "dev": true
+    },
     "date-now": {
       "version": "0.1.4",
       "resolved": "https://registry.npmjs.org/date-now/-/date-now-0.1.4.tgz",
@@ -1543,6 +1783,12 @@
       "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=",
       "dev": true
     },
+    "dedent": {
+      "version": "0.7.0",
+      "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz",
+      "integrity": "sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=",
+      "dev": true
+    },
     "deep-eql": {
       "version": "3.0.1",
       "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz",
@@ -1645,6 +1891,83 @@
         "yargs": "~3.27.0"
       }
     },
+    "del": {
+      "version": "5.1.0",
+      "resolved": "https://registry.npmjs.org/del/-/del-5.1.0.tgz",
+      "integrity": "sha512-wH9xOVHnczo9jN2IW68BabcecVPxacIA3g/7z6vhSU/4stOKQzeCRK0yD0A24WiAAUJmmVpWqrERcTxnLo3AnA==",
+      "dev": true,
+      "requires": {
+        "globby": "^10.0.1",
+        "graceful-fs": "^4.2.2",
+        "is-glob": "^4.0.1",
+        "is-path-cwd": "^2.2.0",
+        "is-path-inside": "^3.0.1",
+        "p-map": "^3.0.0",
+        "rimraf": "^3.0.0",
+        "slash": "^3.0.0"
+      },
+      "dependencies": {
+        "glob": {
+          "version": "7.1.6",
+          "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
+          "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
+          "dev": true,
+          "requires": {
+            "fs.realpath": "^1.0.0",
+            "inflight": "^1.0.4",
+            "inherits": "2",
+            "minimatch": "^3.0.4",
+            "once": "^1.3.0",
+            "path-is-absolute": "^1.0.0"
+          }
+        },
+        "graceful-fs": {
+          "version": "4.2.3",
+          "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz",
+          "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==",
+          "dev": true
+        },
+        "is-extglob": {
+          "version": "2.1.1",
+          "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+          "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
+          "dev": true
+        },
+        "is-glob": {
+          "version": "4.0.1",
+          "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz",
+          "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==",
+          "dev": true,
+          "requires": {
+            "is-extglob": "^2.1.1"
+          }
+        },
+        "minimatch": {
+          "version": "3.0.4",
+          "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
+          "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
+          "dev": true,
+          "requires": {
+            "brace-expansion": "^1.1.7"
+          }
+        },
+        "rimraf": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.0.tgz",
+          "integrity": "sha512-NDGVxTsjqfunkds7CqsOiEnxln4Bo7Nddl3XhS4pXg5OzwkLqJ971ZVAAnB+DDLnF76N+VnDEiBHaVV8I06SUg==",
+          "dev": true,
+          "requires": {
+            "glob": "^7.1.3"
+          }
+        },
+        "slash": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
+          "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
+          "dev": true
+        }
+      }
+    },
     "delayed-stream": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
@@ -1704,6 +2027,23 @@
       "integrity": "sha1-gAwN0eCov7yVg1wgKtIg/jF+WhI=",
       "dev": true
     },
+    "dir-glob": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
+      "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==",
+      "dev": true,
+      "requires": {
+        "path-type": "^4.0.0"
+      },
+      "dependencies": {
+        "path-type": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
+          "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
+          "dev": true
+        }
+      }
+    },
     "dirty-chai": {
       "version": "2.0.1",
       "resolved": "https://registry.npmjs.org/dirty-chai/-/dirty-chai-2.0.1.tgz",
@@ -1711,9 +2051,9 @@
       "dev": true
     },
     "doctrine": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz",
-      "integrity": "sha1-XNAfwQFiG0LEzX9dGmYkNxbT850=",
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz",
+      "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==",
       "dev": true,
       "requires": {
         "esutils": "^2.0.2"
@@ -1722,7 +2062,7 @@
     "domain-browser": {
       "version": "1.2.0",
       "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz",
-      "integrity": "sha1-PTH1AZGmdJ3RN1p/Ui6CPULlTto=",
+      "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==",
       "dev": true
     },
     "download-file-sync": {
@@ -1882,10 +2222,22 @@
       "integrity": "sha512-s5hv+TSJSVRsxH190De66YHb50pBGTweT9XGWYu/LMR20KX6TsjFzObo36CjVAzM+PUeeKSBRtm/mISlCzeojQ==",
       "dev": true
     },
-    "emojis-list": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz",
-      "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=",
+    "elegant-spinner": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/elegant-spinner/-/elegant-spinner-1.0.1.tgz",
+      "integrity": "sha1-2wQ1IcldfjA/2PNFvtwzSc+wcp4=",
+      "dev": true
+    },
+    "emoji-regex": {
+      "version": "8.0.0",
+      "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+      "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+      "dev": true
+    },
+    "emojis-list": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz",
+      "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=",
       "dev": true
     },
     "encodeurl": {
@@ -1944,7 +2296,7 @@
     "error-ex": {
       "version": "1.3.2",
       "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
-      "integrity": "sha1-tKxAZIEH/c3PriQvQovqihTU8b8=",
+      "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
       "dev": true,
       "requires": {
         "is-arrayish": "^0.2.1"
@@ -2045,61 +2397,60 @@
       }
     },
     "eslint": {
-      "version": "4.19.1",
-      "resolved": "https://registry.npmjs.org/eslint/-/eslint-4.19.1.tgz",
-      "integrity": "sha1-MtHWU+HZBAiFS/spbwdux+GGowA=",
+      "version": "6.7.2",
+      "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.7.2.tgz",
+      "integrity": "sha512-qMlSWJaCSxDFr8fBPvJM9kJwbazrhNcBU3+DszDW1OlEwKBBRWsJc7NJFelvwQpanHCR14cOLD41x8Eqvo3Nng==",
       "dev": true,
       "requires": {
-        "ajv": "^5.3.0",
-        "babel-code-frame": "^6.22.0",
+        "@babel/code-frame": "^7.0.0",
+        "ajv": "^6.10.0",
         "chalk": "^2.1.0",
-        "concat-stream": "^1.6.0",
-        "cross-spawn": "^5.1.0",
-        "debug": "^3.1.0",
-        "doctrine": "^2.1.0",
-        "eslint-scope": "^3.7.1",
-        "eslint-visitor-keys": "^1.0.0",
-        "espree": "^3.5.4",
-        "esquery": "^1.0.0",
+        "cross-spawn": "^6.0.5",
+        "debug": "^4.0.1",
+        "doctrine": "^3.0.0",
+        "eslint-scope": "^5.0.0",
+        "eslint-utils": "^1.4.3",
+        "eslint-visitor-keys": "^1.1.0",
+        "espree": "^6.1.2",
+        "esquery": "^1.0.1",
         "esutils": "^2.0.2",
-        "file-entry-cache": "^2.0.0",
+        "file-entry-cache": "^5.0.1",
         "functional-red-black-tree": "^1.0.1",
-        "glob": "^7.1.2",
-        "globals": "^11.0.1",
-        "ignore": "^3.3.3",
+        "glob-parent": "^5.0.0",
+        "globals": "^12.1.0",
+        "ignore": "^4.0.6",
+        "import-fresh": "^3.0.0",
         "imurmurhash": "^0.1.4",
-        "inquirer": "^3.0.6",
-        "is-resolvable": "^1.0.0",
-        "js-yaml": "^3.9.1",
+        "inquirer": "^7.0.0",
+        "is-glob": "^4.0.0",
+        "js-yaml": "^3.13.1",
         "json-stable-stringify-without-jsonify": "^1.0.1",
         "levn": "^0.3.0",
-        "lodash": "^4.17.4",
-        "minimatch": "^3.0.2",
+        "lodash": "^4.17.14",
+        "minimatch": "^3.0.4",
         "mkdirp": "^0.5.1",
         "natural-compare": "^1.4.0",
-        "optionator": "^0.8.2",
-        "path-is-inside": "^1.0.2",
-        "pluralize": "^7.0.0",
+        "optionator": "^0.8.3",
         "progress": "^2.0.0",
-        "regexpp": "^1.0.1",
-        "require-uncached": "^1.0.3",
-        "semver": "^5.3.0",
-        "strip-ansi": "^4.0.0",
-        "strip-json-comments": "~2.0.1",
-        "table": "4.0.2",
-        "text-table": "~0.2.0"
+        "regexpp": "^2.0.1",
+        "semver": "^6.1.2",
+        "strip-ansi": "^5.2.0",
+        "strip-json-comments": "^3.0.1",
+        "table": "^5.2.3",
+        "text-table": "^0.2.0",
+        "v8-compile-cache": "^2.0.3"
       },
       "dependencies": {
         "ansi-regex": {
-          "version": "3.0.0",
-          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
-          "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
+          "version": "4.1.0",
+          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
+          "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
           "dev": true
         },
         "ansi-styles": {
           "version": "3.2.1",
           "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
-          "integrity": "sha1-QfuyAkPlCxK+DwS43tvwdSDOhB0=",
+          "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
           "dev": true,
           "requires": {
             "color-convert": "^1.9.0"
@@ -2108,7 +2459,7 @@
         "chalk": {
           "version": "2.4.2",
           "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
-          "integrity": "sha1-zUJUFnelQzPPVBpJEIwUMrRMlCQ=",
+          "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
           "dev": true,
           "requires": {
             "ansi-styles": "^3.2.1",
@@ -2117,9 +2468,9 @@
           }
         },
         "debug": {
-          "version": "3.2.6",
-          "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
-          "integrity": "sha1-6D0X3hbYp++3cX7b5fsQE17uYps=",
+          "version": "4.1.1",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
+          "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
           "dev": true,
           "requires": {
             "ms": "^2.1.1"
@@ -2131,30 +2482,53 @@
           "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
           "dev": true
         },
-        "glob": {
-          "version": "7.1.3",
-          "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz",
-          "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==",
+        "glob-parent": {
+          "version": "5.1.0",
+          "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.0.tgz",
+          "integrity": "sha512-qjtRgnIVmOfnKUE3NJAQEdk+lKrxfw8t5ke7SXtfMTHcjsBfOfWXCQfdb30zfDoZQ2IRSIiidmjtbHZPZ++Ihw==",
           "dev": true,
           "requires": {
-            "fs.realpath": "^1.0.0",
-            "inflight": "^1.0.4",
-            "inherits": "2",
-            "minimatch": "^3.0.4",
-            "once": "^1.3.0",
-            "path-is-absolute": "^1.0.0"
+            "is-glob": "^4.0.1"
           }
         },
         "globals": {
-          "version": "11.11.0",
-          "resolved": "https://registry.npmjs.org/globals/-/globals-11.11.0.tgz",
-          "integrity": "sha512-WHq43gS+6ufNOEqlrDBxVEbb8ntfXrfAUU2ZOpCxrBdGKW3gyv8mCxAfIBD0DroPKGrJ2eSsXsLtY9MPntsyTw==",
+          "version": "12.3.0",
+          "resolved": "https://registry.npmjs.org/globals/-/globals-12.3.0.tgz",
+          "integrity": "sha512-wAfjdLgFsPZsklLJvOBUBmzYE8/CwhEqSBEMRXA3qxIiNtyqvjYurAtIfDh6chlEPUfmTY3MnZh5Hfh4q0UlIw==",
+          "dev": true,
+          "requires": {
+            "type-fest": "^0.8.1"
+          }
+        },
+        "import-fresh": {
+          "version": "3.2.1",
+          "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.1.tgz",
+          "integrity": "sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ==",
+          "dev": true,
+          "requires": {
+            "parent-module": "^1.0.0",
+            "resolve-from": "^4.0.0"
+          }
+        },
+        "is-extglob": {
+          "version": "2.1.1",
+          "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+          "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
           "dev": true
         },
+        "is-glob": {
+          "version": "4.0.1",
+          "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz",
+          "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==",
+          "dev": true,
+          "requires": {
+            "is-extglob": "^2.1.1"
+          }
+        },
         "js-yaml": {
-          "version": "3.12.2",
-          "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.2.tgz",
-          "integrity": "sha512-QHn/Lh/7HhZ/Twc7vJYQTkjuCa0kaCcDcjK5Zlk2rvnUpy7DxMJ23+Jc2dcyvltwQVg1nygAVlB2oRDFHoRS5Q==",
+          "version": "3.13.1",
+          "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz",
+          "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==",
           "dev": true,
           "requires": {
             "argparse": "^1.0.7",
@@ -2162,43 +2536,78 @@
           }
         },
         "lodash": {
-          "version": "4.17.11",
-          "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz",
-          "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==",
+          "version": "4.17.15",
+          "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
+          "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==",
           "dev": true
         },
         "minimatch": {
           "version": "3.0.4",
           "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
-          "integrity": "sha1-UWbihkV/AzBgZL5Ul+jbsMPTIIM=",
+          "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
           "dev": true,
           "requires": {
             "brace-expansion": "^1.1.7"
           }
         },
         "ms": {
-          "version": "2.1.1",
-          "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
-          "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==",
+          "version": "2.1.2",
+          "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+          "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+          "dev": true
+        },
+        "semver": {
+          "version": "6.3.0",
+          "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+          "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
           "dev": true
         },
         "strip-ansi": {
-          "version": "4.0.0",
-          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
-          "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
+          "version": "5.2.0",
+          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
+          "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
           "dev": true,
           "requires": {
-            "ansi-regex": "^3.0.0"
+            "ansi-regex": "^4.1.0"
           }
         },
+        "strip-json-comments": {
+          "version": "3.0.1",
+          "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.0.1.tgz",
+          "integrity": "sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw==",
+          "dev": true
+        },
         "supports-color": {
           "version": "5.5.0",
           "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
-          "integrity": "sha1-4uaaRKyHcveKHsCzW2id9lMO/I8=",
+          "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
           "dev": true,
           "requires": {
             "has-flag": "^3.0.0"
           }
+        },
+        "type-fest": {
+          "version": "0.8.1",
+          "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz",
+          "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==",
+          "dev": true
+        }
+      }
+    },
+    "eslint-config-prettier": {
+      "version": "6.7.0",
+      "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-6.7.0.tgz",
+      "integrity": "sha512-FamQVKM3jjUVwhG4hEMnbtsq7xOIDm+SY5iBPfR8gKsJoAB2IQnNF+bk1+8Fy44Nq7PPJaLvkRxILYdJWoguKQ==",
+      "dev": true,
+      "requires": {
+        "get-stdin": "^6.0.0"
+      },
+      "dependencies": {
+        "get-stdin": {
+          "version": "6.0.0",
+          "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-6.0.0.tgz",
+          "integrity": "sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g==",
+          "dev": true
         }
       }
     },
@@ -2232,29 +2641,47 @@
       "dev": true
     },
     "eslint-scope": {
-      "version": "3.7.3",
-      "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-3.7.3.tgz",
-      "integrity": "sha1-u1ByANPRf2AkdjYWC0gmKEsQhTU=",
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.0.0.tgz",
+      "integrity": "sha512-oYrhJW7S0bxAFDvWqzvMPRm6pcgcnWc4QnofCAqRTRfQC0JcwenzGglTtsLyIuuWFfkqDG9vz67cnttSd53djw==",
       "dev": true,
       "requires": {
         "esrecurse": "^4.1.0",
         "estraverse": "^4.1.1"
       }
     },
+    "eslint-utils": {
+      "version": "1.4.3",
+      "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.3.tgz",
+      "integrity": "sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==",
+      "dev": true,
+      "requires": {
+        "eslint-visitor-keys": "^1.1.0"
+      }
+    },
     "eslint-visitor-keys": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz",
-      "integrity": "sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ==",
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz",
+      "integrity": "sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A==",
       "dev": true
     },
     "espree": {
-      "version": "3.5.4",
-      "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.4.tgz",
-      "integrity": "sha1-sPRHGHyKi+2US4FaZgvd9d610ac=",
+      "version": "6.1.2",
+      "resolved": "https://registry.npmjs.org/espree/-/espree-6.1.2.tgz",
+      "integrity": "sha512-2iUPuuPP+yW1PZaMSDM9eyVf8D5P0Hi8h83YtZ5bPc/zHYjII5khoixIUTMO794NOY8F/ThF1Bo8ncZILarUTA==",
       "dev": true,
       "requires": {
-        "acorn": "^5.5.0",
-        "acorn-jsx": "^3.0.0"
+        "acorn": "^7.1.0",
+        "acorn-jsx": "^5.1.0",
+        "eslint-visitor-keys": "^1.1.0"
+      },
+      "dependencies": {
+        "acorn": {
+          "version": "7.1.0",
+          "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.0.tgz",
+          "integrity": "sha512-kL5CuoXA/dgxlBbVrflsflzQ3PAas7RYZB52NOm/6839iVYJgKMJ3cQJD+t2i5+qFa8h3MDpEOJiS64E8JLnSQ==",
+          "dev": true
+        }
       }
     },
     "esprima-fb": {
@@ -2266,7 +2693,7 @@
     "esquery": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz",
-      "integrity": "sha1-QGxRZYsfWZGl+bYrHcJbAOPlxwg=",
+      "integrity": "sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==",
       "dev": true,
       "requires": {
         "estraverse": "^4.0.0"
@@ -2275,16 +2702,16 @@
     "esrecurse": {
       "version": "4.2.1",
       "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz",
-      "integrity": "sha1-AHo7n9vCs7uH5IeeoZyS/b05Qs8=",
+      "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==",
       "dev": true,
       "requires": {
         "estraverse": "^4.1.0"
       }
     },
     "estraverse": {
-      "version": "4.2.0",
-      "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz",
-      "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=",
+      "version": "4.3.0",
+      "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
+      "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
       "dev": true
     },
     "esutils": {
@@ -2320,7 +2747,7 @@
     "eventsource": {
       "version": "1.0.7",
       "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-1.0.7.tgz",
-      "integrity": "sha1-j7xyyT/NNAiAkLwKTmT0tc7m2NA=",
+      "integrity": "sha512-4Ln17+vVT0k8aWq+t/bF5arcS3EpT9gYtW66EPacdj/mAFevznsnyoHLPy2BA8gbIQeIHoPsvwmfBftfcG//BQ==",
       "dev": true,
       "requires": {
         "original": "^1.0.0"
@@ -2484,13 +2911,13 @@
       }
     },
     "external-editor": {
-      "version": "2.2.0",
-      "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.2.0.tgz",
-      "integrity": "sha1-BFURz9jRM/OEZnPRBHwVTiFK09U=",
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz",
+      "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==",
       "dev": true,
       "requires": {
-        "chardet": "^0.4.0",
-        "iconv-lite": "^0.4.17",
+        "chardet": "^0.7.0",
+        "iconv-lite": "^0.4.24",
         "tmp": "^0.0.33"
       }
     },
@@ -2510,11 +2937,93 @@
       "dev": true
     },
     "fast-deep-equal": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz",
-      "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=",
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz",
+      "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=",
       "dev": true
     },
+    "fast-glob": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.1.0.tgz",
+      "integrity": "sha512-TrUz3THiq2Vy3bjfQUB2wNyPdGBeGmdjbzzBLhfHN4YFurYptCKwGq/TfiRavbGywFRzY6U2CdmQ1zmsY5yYaw==",
+      "dev": true,
+      "requires": {
+        "@nodelib/fs.stat": "^2.0.2",
+        "@nodelib/fs.walk": "^1.2.3",
+        "glob-parent": "^5.1.0",
+        "merge2": "^1.3.0",
+        "micromatch": "^4.0.2"
+      },
+      "dependencies": {
+        "braces": {
+          "version": "3.0.2",
+          "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
+          "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
+          "dev": true,
+          "requires": {
+            "fill-range": "^7.0.1"
+          }
+        },
+        "fill-range": {
+          "version": "7.0.1",
+          "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
+          "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
+          "dev": true,
+          "requires": {
+            "to-regex-range": "^5.0.1"
+          }
+        },
+        "glob-parent": {
+          "version": "5.1.0",
+          "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.0.tgz",
+          "integrity": "sha512-qjtRgnIVmOfnKUE3NJAQEdk+lKrxfw8t5ke7SXtfMTHcjsBfOfWXCQfdb30zfDoZQ2IRSIiidmjtbHZPZ++Ihw==",
+          "dev": true,
+          "requires": {
+            "is-glob": "^4.0.1"
+          }
+        },
+        "is-extglob": {
+          "version": "2.1.1",
+          "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+          "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
+          "dev": true
+        },
+        "is-glob": {
+          "version": "4.0.1",
+          "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz",
+          "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==",
+          "dev": true,
+          "requires": {
+            "is-extglob": "^2.1.1"
+          }
+        },
+        "is-number": {
+          "version": "7.0.0",
+          "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+          "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+          "dev": true
+        },
+        "micromatch": {
+          "version": "4.0.2",
+          "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz",
+          "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==",
+          "dev": true,
+          "requires": {
+            "braces": "^3.0.1",
+            "picomatch": "^2.0.5"
+          }
+        },
+        "to-regex-range": {
+          "version": "5.0.1",
+          "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+          "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+          "dev": true,
+          "requires": {
+            "is-number": "^7.0.0"
+          }
+        }
+      }
+    },
     "fast-json-stable-stringify": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz",
@@ -2527,6 +3036,15 @@
       "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=",
       "dev": true
     },
+    "fastq": {
+      "version": "1.6.0",
+      "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.6.0.tgz",
+      "integrity": "sha512-jmxqQ3Z/nXoeyDmWAzF9kH1aGZSis6e/SbfPmJpUnyZ0ogr6iscHQaml4wsEepEWSdtmpy+eVXmCRIMpxaXqOA==",
+      "dev": true,
+      "requires": {
+        "reusify": "^1.0.0"
+      }
+    },
     "faye-websocket": {
       "version": "0.10.0",
       "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.10.0.tgz",
@@ -2579,21 +3097,12 @@
       }
     },
     "file-entry-cache": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz",
-      "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=",
+      "version": "5.0.1",
+      "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz",
+      "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==",
       "dev": true,
       "requires": {
-        "flat-cache": "^1.2.1",
-        "object-assign": "^4.0.1"
-      },
-      "dependencies": {
-        "object-assign": {
-          "version": "4.1.1",
-          "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
-          "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
-          "dev": true
-        }
+        "flat-cache": "^2.0.1"
       }
     },
     "file-sync-cmp": {
@@ -2696,17 +3205,22 @@
       "dev": true
     },
     "flat-cache": {
-      "version": "1.3.4",
-      "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.4.tgz",
-      "integrity": "sha1-LC73dSXMKSkAff/6HdMUqpyd7m8=",
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz",
+      "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==",
       "dev": true,
       "requires": {
-        "circular-json": "^0.3.1",
-        "graceful-fs": "^4.1.2",
-        "rimraf": "~2.6.2",
-        "write": "^0.2.1"
+        "flatted": "^2.0.0",
+        "rimraf": "2.6.3",
+        "write": "1.0.3"
       }
     },
+    "flatted": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.1.tgz",
+      "integrity": "sha512-a1hQMktqW9Nmqr5aktAux3JMNqaucxGcjtjWnZLHX7yyPCmlSV3M54nGYbqT8K+0GhF3NBgmJCc3ma+WOgX8Jg==",
+      "dev": true
+    },
     "follow-redirects": {
       "version": "1.7.0",
       "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.7.0.tgz",
@@ -3384,6 +3898,12 @@
       "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=",
       "dev": true
     },
+    "get-own-enumerable-property-symbols": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.1.tgz",
+      "integrity": "sha512-09/VS4iek66Dh2bctjRkowueRJbY1JDGR1L/zRxO1Qk8Uxs6PnqaNSqalpizPT+CDjre3hnEsuzvhgomz9qYrA==",
+      "dev": true
+    },
     "get-stdin": {
       "version": "4.0.1",
       "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz",
@@ -3482,6 +4002,59 @@
       "integrity": "sha1-hJgDKzttHMge68X3lpDY/in6v08=",
       "dev": true
     },
+    "globby": {
+      "version": "10.0.1",
+      "resolved": "https://registry.npmjs.org/globby/-/globby-10.0.1.tgz",
+      "integrity": "sha512-sSs4inE1FB2YQiymcmTv6NWENryABjUNPeWhOvmn4SjtKybglsyPZxFB3U1/+L1bYi0rNZDqCLlHyLYDl1Pq5A==",
+      "dev": true,
+      "requires": {
+        "@types/glob": "^7.1.1",
+        "array-union": "^2.1.0",
+        "dir-glob": "^3.0.1",
+        "fast-glob": "^3.0.3",
+        "glob": "^7.1.3",
+        "ignore": "^5.1.1",
+        "merge2": "^1.2.3",
+        "slash": "^3.0.0"
+      },
+      "dependencies": {
+        "glob": {
+          "version": "7.1.6",
+          "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
+          "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
+          "dev": true,
+          "requires": {
+            "fs.realpath": "^1.0.0",
+            "inflight": "^1.0.4",
+            "inherits": "2",
+            "minimatch": "^3.0.4",
+            "once": "^1.3.0",
+            "path-is-absolute": "^1.0.0"
+          }
+        },
+        "ignore": {
+          "version": "5.1.4",
+          "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.4.tgz",
+          "integrity": "sha512-MzbUSahkTW1u7JpKKjY7LCARd1fU5W2rLdxlM4kdkayuCwZImjkpluF9CM1aLewYJguPDqewLam18Y6AU69A8A==",
+          "dev": true
+        },
+        "minimatch": {
+          "version": "3.0.4",
+          "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
+          "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
+          "dev": true,
+          "requires": {
+            "brace-expansion": "^1.1.7"
+          }
+        },
+        "slash": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
+          "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
+          "dev": true
+        }
+      }
+    },
     "globule": {
       "version": "1.2.1",
       "resolved": "https://registry.npmjs.org/globule/-/globule-1.2.1.tgz",
@@ -3806,47 +4379,6 @@
         }
       }
     },
-    "grunt-eslint": {
-      "version": "20.2.0",
-      "resolved": "https://registry.npmjs.org/grunt-eslint/-/grunt-eslint-20.2.0.tgz",
-      "integrity": "sha1-vu2kb6m4TgCGN0KqS8yEhGzSe8o=",
-      "dev": true,
-      "requires": {
-        "chalk": "^2.1.0",
-        "eslint": "^4.0.0"
-      },
-      "dependencies": {
-        "ansi-styles": {
-          "version": "3.2.1",
-          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
-          "integrity": "sha1-QfuyAkPlCxK+DwS43tvwdSDOhB0=",
-          "dev": true,
-          "requires": {
-            "color-convert": "^1.9.0"
-          }
-        },
-        "chalk": {
-          "version": "2.4.2",
-          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
-          "integrity": "sha1-zUJUFnelQzPPVBpJEIwUMrRMlCQ=",
-          "dev": true,
-          "requires": {
-            "ansi-styles": "^3.2.1",
-            "escape-string-regexp": "^1.0.5",
-            "supports-color": "^5.3.0"
-          }
-        },
-        "supports-color": {
-          "version": "5.5.0",
-          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
-          "integrity": "sha1-4uaaRKyHcveKHsCzW2id9lMO/I8=",
-          "dev": true,
-          "requires": {
-            "has-flag": "^3.0.0"
-          }
-        }
-      }
-    },
     "grunt-known-options": {
       "version": "1.1.1",
       "resolved": "https://registry.npmjs.org/grunt-known-options/-/grunt-known-options-1.1.1.tgz",
@@ -4275,15 +4807,101 @@
         }
       }
     },
-    "iconv-lite": {
-      "version": "0.4.24",
-      "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
-      "integrity": "sha1-ICK0sl+93CHS9SSXSkdKr+czkIs=",
+    "husky": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/husky/-/husky-3.1.0.tgz",
+      "integrity": "sha512-FJkPoHHB+6s4a+jwPqBudBDvYZsoQW5/HBuMSehC8qDiCe50kpcxeqFoDSlow+9I6wg47YxBoT3WxaURlrDIIQ==",
       "dev": true,
       "requires": {
-        "safer-buffer": ">= 2.1.2 < 3"
-      }
-    },
+        "chalk": "^2.4.2",
+        "ci-info": "^2.0.0",
+        "cosmiconfig": "^5.2.1",
+        "execa": "^1.0.0",
+        "get-stdin": "^7.0.0",
+        "opencollective-postinstall": "^2.0.2",
+        "pkg-dir": "^4.2.0",
+        "please-upgrade-node": "^3.2.0",
+        "read-pkg": "^5.2.0",
+        "run-node": "^1.0.0",
+        "slash": "^3.0.0"
+      },
+      "dependencies": {
+        "ansi-styles": {
+          "version": "3.2.1",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+          "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+          "dev": true,
+          "requires": {
+            "color-convert": "^1.9.0"
+          }
+        },
+        "chalk": {
+          "version": "2.4.2",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+          "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "^3.2.1",
+            "escape-string-regexp": "^1.0.5",
+            "supports-color": "^5.3.0"
+          }
+        },
+        "get-stdin": {
+          "version": "7.0.0",
+          "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-7.0.0.tgz",
+          "integrity": "sha512-zRKcywvrXlXsA0v0i9Io4KDRaAw7+a1ZpjRwl9Wox8PFlVCCHra7E9c4kqXCoCM9nR5tBkaTTZRBoCm60bFqTQ==",
+          "dev": true
+        },
+        "parse-json": {
+          "version": "5.0.0",
+          "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz",
+          "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==",
+          "dev": true,
+          "requires": {
+            "@babel/code-frame": "^7.0.0",
+            "error-ex": "^1.3.1",
+            "json-parse-better-errors": "^1.0.1",
+            "lines-and-columns": "^1.1.6"
+          }
+        },
+        "read-pkg": {
+          "version": "5.2.0",
+          "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz",
+          "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==",
+          "dev": true,
+          "requires": {
+            "@types/normalize-package-data": "^2.4.0",
+            "normalize-package-data": "^2.5.0",
+            "parse-json": "^5.0.0",
+            "type-fest": "^0.6.0"
+          }
+        },
+        "slash": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
+          "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
+          "dev": true
+        },
+        "supports-color": {
+          "version": "5.5.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+          "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+          "dev": true,
+          "requires": {
+            "has-flag": "^3.0.0"
+          }
+        }
+      }
+    },
+    "iconv-lite": {
+      "version": "0.4.24",
+      "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
+      "integrity": "sha1-ICK0sl+93CHS9SSXSkdKr+czkIs=",
+      "dev": true,
+      "requires": {
+        "safer-buffer": ">= 2.1.2 < 3"
+      }
+    },
     "ieee754": {
       "version": "1.1.8",
       "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.8.tgz",
@@ -4291,11 +4909,38 @@
       "dev": true
     },
     "ignore": {
-      "version": "3.3.10",
-      "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.10.tgz",
-      "integrity": "sha1-Cpf7h2mG6AgcYxFg+PnziRV/AEM=",
+      "version": "4.0.6",
+      "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz",
+      "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==",
       "dev": true
     },
+    "import-fresh": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz",
+      "integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=",
+      "dev": true,
+      "requires": {
+        "caller-path": "^2.0.0",
+        "resolve-from": "^3.0.0"
+      },
+      "dependencies": {
+        "caller-path": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-2.0.0.tgz",
+          "integrity": "sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ=",
+          "dev": true,
+          "requires": {
+            "caller-callsite": "^2.0.0"
+          }
+        },
+        "resolve-from": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz",
+          "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=",
+          "dev": true
+        }
+      }
+    },
     "imurmurhash": {
       "version": "0.1.4",
       "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
@@ -4351,37 +4996,45 @@
       "dev": true
     },
     "inquirer": {
-      "version": "3.3.0",
-      "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-3.3.0.tgz",
-      "integrity": "sha1-ndLyrXZdyrH/BEO0kUQqILoifck=",
+      "version": "7.0.0",
+      "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.0.0.tgz",
+      "integrity": "sha512-rSdC7zelHdRQFkWnhsMu2+2SO41mpv2oF2zy4tMhmiLWkcKbOAs87fWAJhVXttKVwhdZvymvnuM95EyEXg2/tQ==",
       "dev": true,
       "requires": {
-        "ansi-escapes": "^3.0.0",
-        "chalk": "^2.0.0",
-        "cli-cursor": "^2.1.0",
+        "ansi-escapes": "^4.2.1",
+        "chalk": "^2.4.2",
+        "cli-cursor": "^3.1.0",
         "cli-width": "^2.0.0",
-        "external-editor": "^2.0.4",
-        "figures": "^2.0.0",
-        "lodash": "^4.3.0",
-        "mute-stream": "0.0.7",
+        "external-editor": "^3.0.3",
+        "figures": "^3.0.0",
+        "lodash": "^4.17.15",
+        "mute-stream": "0.0.8",
         "run-async": "^2.2.0",
-        "rx-lite": "^4.0.8",
-        "rx-lite-aggregates": "^4.0.8",
-        "string-width": "^2.1.0",
-        "strip-ansi": "^4.0.0",
+        "rxjs": "^6.4.0",
+        "string-width": "^4.1.0",
+        "strip-ansi": "^5.1.0",
         "through": "^2.3.6"
       },
       "dependencies": {
+        "ansi-escapes": {
+          "version": "4.3.0",
+          "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.0.tgz",
+          "integrity": "sha512-EiYhwo0v255HUL6eDyuLrXEkTi7WwVCLAw+SeOQ7M7qdun1z1pum4DEm/nuqIVbPvi9RPPc9k9LbyBv6H0DwVg==",
+          "dev": true,
+          "requires": {
+            "type-fest": "^0.8.1"
+          }
+        },
         "ansi-regex": {
-          "version": "3.0.0",
-          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
-          "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
+          "version": "5.0.0",
+          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz",
+          "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==",
           "dev": true
         },
         "ansi-styles": {
           "version": "3.2.1",
           "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
-          "integrity": "sha1-QfuyAkPlCxK+DwS43tvwdSDOhB0=",
+          "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
           "dev": true,
           "requires": {
             "color-convert": "^1.9.0"
@@ -4390,7 +5043,7 @@
         "chalk": {
           "version": "2.4.2",
           "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
-          "integrity": "sha1-zUJUFnelQzPPVBpJEIwUMrRMlCQ=",
+          "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
           "dev": true,
           "requires": {
             "ansi-styles": "^3.2.1",
@@ -4398,38 +5051,114 @@
             "supports-color": "^5.3.0"
           }
         },
+        "cli-cursor": {
+          "version": "3.1.0",
+          "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz",
+          "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==",
+          "dev": true,
+          "requires": {
+            "restore-cursor": "^3.1.0"
+          }
+        },
         "figures": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz",
-          "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=",
+          "version": "3.1.0",
+          "resolved": "https://registry.npmjs.org/figures/-/figures-3.1.0.tgz",
+          "integrity": "sha512-ravh8VRXqHuMvZt/d8GblBeqDMkdJMBdv/2KntFH+ra5MXkO7nxNKpzQ3n6QD/2da1kH0aWmNISdvhM7gl2gVg==",
           "dev": true,
           "requires": {
             "escape-string-regexp": "^1.0.5"
           }
         },
+        "is-fullwidth-code-point": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+          "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+          "dev": true
+        },
         "lodash": {
-          "version": "4.17.11",
-          "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz",
-          "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==",
+          "version": "4.17.15",
+          "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
+          "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==",
           "dev": true
         },
+        "mimic-fn": {
+          "version": "2.1.0",
+          "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
+          "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
+          "dev": true
+        },
+        "onetime": {
+          "version": "5.1.0",
+          "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz",
+          "integrity": "sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==",
+          "dev": true,
+          "requires": {
+            "mimic-fn": "^2.1.0"
+          }
+        },
+        "restore-cursor": {
+          "version": "3.1.0",
+          "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz",
+          "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==",
+          "dev": true,
+          "requires": {
+            "onetime": "^5.1.0",
+            "signal-exit": "^3.0.2"
+          }
+        },
+        "string-width": {
+          "version": "4.2.0",
+          "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz",
+          "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==",
+          "dev": true,
+          "requires": {
+            "emoji-regex": "^8.0.0",
+            "is-fullwidth-code-point": "^3.0.0",
+            "strip-ansi": "^6.0.0"
+          },
+          "dependencies": {
+            "strip-ansi": {
+              "version": "6.0.0",
+              "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz",
+              "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==",
+              "dev": true,
+              "requires": {
+                "ansi-regex": "^5.0.0"
+              }
+            }
+          }
+        },
         "strip-ansi": {
-          "version": "4.0.0",
-          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
-          "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
+          "version": "5.2.0",
+          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
+          "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
           "dev": true,
           "requires": {
-            "ansi-regex": "^3.0.0"
+            "ansi-regex": "^4.1.0"
+          },
+          "dependencies": {
+            "ansi-regex": {
+              "version": "4.1.0",
+              "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
+              "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
+              "dev": true
+            }
           }
         },
         "supports-color": {
           "version": "5.5.0",
           "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
-          "integrity": "sha1-4uaaRKyHcveKHsCzW2id9lMO/I8=",
+          "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
           "dev": true,
           "requires": {
             "has-flag": "^3.0.0"
           }
+        },
+        "type-fest": {
+          "version": "0.8.1",
+          "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz",
+          "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==",
+          "dev": true
         }
       }
     },
@@ -4519,6 +5248,12 @@
         }
       }
     },
+    "is-directory": {
+      "version": "0.3.1",
+      "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz",
+      "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=",
+      "dev": true
+    },
     "is-dotfile": {
       "version": "1.0.3",
       "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz",
@@ -4588,6 +5323,33 @@
         "kind-of": "^3.0.2"
       }
     },
+    "is-obj": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz",
+      "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=",
+      "dev": true
+    },
+    "is-observable": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/is-observable/-/is-observable-1.1.0.tgz",
+      "integrity": "sha512-NqCa4Sa2d+u7BWc6CukaObG3Fh+CU9bvixbpcXYhy2VvYS7vVGIdAgnIS5Ks3A/cqk4rebLJ9s8zBstT2aKnIA==",
+      "dev": true,
+      "requires": {
+        "symbol-observable": "^1.1.0"
+      }
+    },
+    "is-path-cwd": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz",
+      "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==",
+      "dev": true
+    },
+    "is-path-inside": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.2.tgz",
+      "integrity": "sha512-/2UGPSgmtqwo1ktx8NDHjuPwZWmHhO+gj0f93EkhLB5RgW9RZevWYYlIkS6zePc6U2WpOdQYIwHe9YC4DWEBVg==",
+      "dev": true
+    },
     "is-plain-object": {
       "version": "2.0.4",
       "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
@@ -4623,6 +5385,12 @@
       "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=",
       "dev": true
     },
+    "is-regexp": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz",
+      "integrity": "sha1-/S2INUXEa6xaYz57mgnof6LLUGk=",
+      "dev": true
+    },
     "is-relative": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz",
@@ -4632,12 +5400,6 @@
         "is-unc-path": "^1.0.0"
       }
     },
-    "is-resolvable": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz",
-      "integrity": "sha1-+xj4fOH+uSUWnJpAfBkxijIG7Yg=",
-      "dev": true
-    },
     "is-stream": {
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
@@ -4814,6 +5576,12 @@
       "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=",
       "dev": true
     },
+    "json-parse-better-errors": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz",
+      "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==",
+      "dev": true
+    },
     "json-schema": {
       "version": "0.2.3",
       "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
@@ -4821,9 +5589,9 @@
       "dev": true
     },
     "json-schema-traverse": {
-      "version": "0.3.1",
-      "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz",
-      "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=",
+      "version": "0.4.1",
+      "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+      "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
       "dev": true
     },
     "json-stable-stringify-without-jsonify": {
@@ -5219,19 +5987,367 @@
           "integrity": "sha1-cIWbyVyYQJUvNZoGij/En57PrCM=",
           "dev": true,
           "requires": {
-            "arr-diff": "^4.0.0",
-            "array-unique": "^0.3.2",
-            "braces": "^2.3.1",
-            "define-property": "^2.0.2",
-            "extend-shallow": "^3.0.2",
-            "extglob": "^2.0.4",
-            "fragment-cache": "^0.2.1",
-            "kind-of": "^6.0.2",
-            "nanomatch": "^1.2.9",
-            "object.pick": "^1.3.0",
-            "regex-not": "^1.0.0",
-            "snapdragon": "^0.8.1",
-            "to-regex": "^3.0.2"
+            "arr-diff": "^4.0.0",
+            "array-unique": "^0.3.2",
+            "braces": "^2.3.1",
+            "define-property": "^2.0.2",
+            "extend-shallow": "^3.0.2",
+            "extglob": "^2.0.4",
+            "fragment-cache": "^0.2.1",
+            "kind-of": "^6.0.2",
+            "nanomatch": "^1.2.9",
+            "object.pick": "^1.3.0",
+            "regex-not": "^1.0.0",
+            "snapdragon": "^0.8.1",
+            "to-regex": "^3.0.2"
+          }
+        }
+      }
+    },
+    "lines-and-columns": {
+      "version": "1.1.6",
+      "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz",
+      "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=",
+      "dev": true
+    },
+    "lint-staged": {
+      "version": "9.5.0",
+      "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-9.5.0.tgz",
+      "integrity": "sha512-nawMob9cb/G1J98nb8v3VC/E8rcX1rryUYXVZ69aT9kde6YWX+uvNOEHY5yf2gcWcTJGiD0kqXmCnS3oD75GIA==",
+      "dev": true,
+      "requires": {
+        "chalk": "^2.4.2",
+        "commander": "^2.20.0",
+        "cosmiconfig": "^5.2.1",
+        "debug": "^4.1.1",
+        "dedent": "^0.7.0",
+        "del": "^5.0.0",
+        "execa": "^2.0.3",
+        "listr": "^0.14.3",
+        "log-symbols": "^3.0.0",
+        "micromatch": "^4.0.2",
+        "normalize-path": "^3.0.0",
+        "please-upgrade-node": "^3.1.1",
+        "string-argv": "^0.3.0",
+        "stringify-object": "^3.3.0"
+      },
+      "dependencies": {
+        "ansi-styles": {
+          "version": "3.2.1",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+          "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+          "dev": true,
+          "requires": {
+            "color-convert": "^1.9.0"
+          }
+        },
+        "braces": {
+          "version": "3.0.2",
+          "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
+          "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
+          "dev": true,
+          "requires": {
+            "fill-range": "^7.0.1"
+          }
+        },
+        "chalk": {
+          "version": "2.4.2",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+          "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "^3.2.1",
+            "escape-string-regexp": "^1.0.5",
+            "supports-color": "^5.3.0"
+          }
+        },
+        "commander": {
+          "version": "2.20.3",
+          "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
+          "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
+          "dev": true
+        },
+        "cross-spawn": {
+          "version": "7.0.1",
+          "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.1.tgz",
+          "integrity": "sha512-u7v4o84SwFpD32Z8IIcPZ6z1/ie24O6RU3RbtL5Y316l3KuHVPx9ItBgWQ6VlfAFnRnTtMUrsQ9MUUTuEZjogg==",
+          "dev": true,
+          "requires": {
+            "path-key": "^3.1.0",
+            "shebang-command": "^2.0.0",
+            "which": "^2.0.1"
+          }
+        },
+        "debug": {
+          "version": "4.1.1",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
+          "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
+          "dev": true,
+          "requires": {
+            "ms": "^2.1.1"
+          }
+        },
+        "execa": {
+          "version": "2.1.0",
+          "resolved": "https://registry.npmjs.org/execa/-/execa-2.1.0.tgz",
+          "integrity": "sha512-Y/URAVapfbYy2Xp/gb6A0E7iR8xeqOCXsuuaoMn7A5PzrXUK84E1gyiEfq0wQd/GHA6GsoHWwhNq8anb0mleIw==",
+          "dev": true,
+          "requires": {
+            "cross-spawn": "^7.0.0",
+            "get-stream": "^5.0.0",
+            "is-stream": "^2.0.0",
+            "merge-stream": "^2.0.0",
+            "npm-run-path": "^3.0.0",
+            "onetime": "^5.1.0",
+            "p-finally": "^2.0.0",
+            "signal-exit": "^3.0.2",
+            "strip-final-newline": "^2.0.0"
+          }
+        },
+        "fill-range": {
+          "version": "7.0.1",
+          "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
+          "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
+          "dev": true,
+          "requires": {
+            "to-regex-range": "^5.0.1"
+          }
+        },
+        "get-stream": {
+          "version": "5.1.0",
+          "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.1.0.tgz",
+          "integrity": "sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw==",
+          "dev": true,
+          "requires": {
+            "pump": "^3.0.0"
+          }
+        },
+        "is-number": {
+          "version": "7.0.0",
+          "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+          "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+          "dev": true
+        },
+        "is-stream": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz",
+          "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==",
+          "dev": true
+        },
+        "micromatch": {
+          "version": "4.0.2",
+          "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz",
+          "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==",
+          "dev": true,
+          "requires": {
+            "braces": "^3.0.1",
+            "picomatch": "^2.0.5"
+          }
+        },
+        "mimic-fn": {
+          "version": "2.1.0",
+          "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
+          "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
+          "dev": true
+        },
+        "ms": {
+          "version": "2.1.2",
+          "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+          "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+          "dev": true
+        },
+        "normalize-path": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
+          "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
+          "dev": true
+        },
+        "npm-run-path": {
+          "version": "3.1.0",
+          "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-3.1.0.tgz",
+          "integrity": "sha512-Dbl4A/VfiVGLgQv29URL9xshU8XDY1GeLy+fsaZ1AA8JDSfjvr5P5+pzRbWqRSBxk6/DW7MIh8lTM/PaGnP2kg==",
+          "dev": true,
+          "requires": {
+            "path-key": "^3.0.0"
+          }
+        },
+        "onetime": {
+          "version": "5.1.0",
+          "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz",
+          "integrity": "sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==",
+          "dev": true,
+          "requires": {
+            "mimic-fn": "^2.1.0"
+          }
+        },
+        "p-finally": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-2.0.1.tgz",
+          "integrity": "sha512-vpm09aKwq6H9phqRQzecoDpD8TmVyGw70qmWlyq5onxY7tqyTTFVvxMykxQSQKILBSFlbXpypIw2T1Ml7+DDtw==",
+          "dev": true
+        },
+        "path-key": {
+          "version": "3.1.1",
+          "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+          "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+          "dev": true
+        },
+        "shebang-command": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
+          "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+          "dev": true,
+          "requires": {
+            "shebang-regex": "^3.0.0"
+          }
+        },
+        "shebang-regex": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
+          "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
+          "dev": true
+        },
+        "supports-color": {
+          "version": "5.5.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+          "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+          "dev": true,
+          "requires": {
+            "has-flag": "^3.0.0"
+          }
+        },
+        "to-regex-range": {
+          "version": "5.0.1",
+          "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+          "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+          "dev": true,
+          "requires": {
+            "is-number": "^7.0.0"
+          }
+        },
+        "which": {
+          "version": "2.0.2",
+          "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+          "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+          "dev": true,
+          "requires": {
+            "isexe": "^2.0.0"
+          }
+        }
+      }
+    },
+    "listr": {
+      "version": "0.14.3",
+      "resolved": "https://registry.npmjs.org/listr/-/listr-0.14.3.tgz",
+      "integrity": "sha512-RmAl7su35BFd/xoMamRjpIE4j3v+L28o8CT5YhAXQJm1fD+1l9ngXY8JAQRJ+tFK2i5njvi0iRUKV09vPwA0iA==",
+      "dev": true,
+      "requires": {
+        "@samverschueren/stream-to-observable": "^0.3.0",
+        "is-observable": "^1.1.0",
+        "is-promise": "^2.1.0",
+        "is-stream": "^1.1.0",
+        "listr-silent-renderer": "^1.1.1",
+        "listr-update-renderer": "^0.5.0",
+        "listr-verbose-renderer": "^0.5.0",
+        "p-map": "^2.0.0",
+        "rxjs": "^6.3.3"
+      },
+      "dependencies": {
+        "p-map": {
+          "version": "2.1.0",
+          "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz",
+          "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==",
+          "dev": true
+        }
+      }
+    },
+    "listr-silent-renderer": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/listr-silent-renderer/-/listr-silent-renderer-1.1.1.tgz",
+      "integrity": "sha1-kktaN1cVN3C/Go4/v3S4u/P5JC4=",
+      "dev": true
+    },
+    "listr-update-renderer": {
+      "version": "0.5.0",
+      "resolved": "https://registry.npmjs.org/listr-update-renderer/-/listr-update-renderer-0.5.0.tgz",
+      "integrity": "sha512-tKRsZpKz8GSGqoI/+caPmfrypiaq+OQCbd+CovEC24uk1h952lVj5sC7SqyFUm+OaJ5HN/a1YLt5cit2FMNsFA==",
+      "dev": true,
+      "requires": {
+        "chalk": "^1.1.3",
+        "cli-truncate": "^0.2.1",
+        "elegant-spinner": "^1.0.1",
+        "figures": "^1.7.0",
+        "indent-string": "^3.0.0",
+        "log-symbols": "^1.0.2",
+        "log-update": "^2.3.0",
+        "strip-ansi": "^3.0.1"
+      },
+      "dependencies": {
+        "indent-string": {
+          "version": "3.2.0",
+          "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-3.2.0.tgz",
+          "integrity": "sha1-Sl/W0nzDMvN+VBmlBNu4NxBckok=",
+          "dev": true
+        },
+        "log-symbols": {
+          "version": "1.0.2",
+          "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-1.0.2.tgz",
+          "integrity": "sha1-N2/3tY6jCGoPCfrMdGF+ylAeGhg=",
+          "dev": true,
+          "requires": {
+            "chalk": "^1.0.0"
+          }
+        }
+      }
+    },
+    "listr-verbose-renderer": {
+      "version": "0.5.0",
+      "resolved": "https://registry.npmjs.org/listr-verbose-renderer/-/listr-verbose-renderer-0.5.0.tgz",
+      "integrity": "sha512-04PDPqSlsqIOaaaGZ+41vq5FejI9auqTInicFRndCBgE3bXG8D6W1I+mWhk+1nqbHmyhla/6BUrd5OSiHwKRXw==",
+      "dev": true,
+      "requires": {
+        "chalk": "^2.4.1",
+        "cli-cursor": "^2.1.0",
+        "date-fns": "^1.27.2",
+        "figures": "^2.0.0"
+      },
+      "dependencies": {
+        "ansi-styles": {
+          "version": "3.2.1",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+          "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+          "dev": true,
+          "requires": {
+            "color-convert": "^1.9.0"
+          }
+        },
+        "chalk": {
+          "version": "2.4.2",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+          "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "^3.2.1",
+            "escape-string-regexp": "^1.0.5",
+            "supports-color": "^5.3.0"
+          }
+        },
+        "figures": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz",
+          "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=",
+          "dev": true,
+          "requires": {
+            "escape-string-regexp": "^1.0.5"
+          }
+        },
+        "supports-color": {
+          "version": "5.5.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+          "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+          "dev": true,
+          "requires": {
+            "has-flag": "^3.0.0"
           }
         }
       }
@@ -5311,6 +6427,84 @@
       "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=",
       "dev": true
     },
+    "log-symbols": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz",
+      "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==",
+      "dev": true,
+      "requires": {
+        "chalk": "^2.4.2"
+      },
+      "dependencies": {
+        "ansi-styles": {
+          "version": "3.2.1",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+          "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+          "dev": true,
+          "requires": {
+            "color-convert": "^1.9.0"
+          }
+        },
+        "chalk": {
+          "version": "2.4.2",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+          "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "^3.2.1",
+            "escape-string-regexp": "^1.0.5",
+            "supports-color": "^5.3.0"
+          }
+        },
+        "supports-color": {
+          "version": "5.5.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+          "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+          "dev": true,
+          "requires": {
+            "has-flag": "^3.0.0"
+          }
+        }
+      }
+    },
+    "log-update": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/log-update/-/log-update-2.3.0.tgz",
+      "integrity": "sha1-iDKP19HOeTiykoN0bwsbwSayRwg=",
+      "dev": true,
+      "requires": {
+        "ansi-escapes": "^3.0.0",
+        "cli-cursor": "^2.0.0",
+        "wrap-ansi": "^3.0.1"
+      },
+      "dependencies": {
+        "ansi-regex": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
+          "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
+          "dev": true
+        },
+        "strip-ansi": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
+          "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
+          "dev": true,
+          "requires": {
+            "ansi-regex": "^3.0.0"
+          }
+        },
+        "wrap-ansi": {
+          "version": "3.0.1",
+          "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-3.0.1.tgz",
+          "integrity": "sha1-KIoE2H7aXChuBg3+jxNc6NAH+Lo=",
+          "dev": true,
+          "requires": {
+            "string-width": "^2.1.1",
+            "strip-ansi": "^4.0.0"
+          }
+        }
+      }
+    },
     "lolex": {
       "version": "4.2.0",
       "resolved": "https://registry.npmjs.org/lolex/-/lolex-4.2.0.tgz",
@@ -5333,16 +6527,6 @@
         "signal-exit": "^3.0.0"
       }
     },
-    "lru-cache": {
-      "version": "4.1.5",
-      "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz",
-      "integrity": "sha1-i75Q6oW+1ZvJ4z3KuCNe6bz0Q80=",
-      "dev": true,
-      "requires": {
-        "pseudomap": "^1.0.2",
-        "yallist": "^2.1.2"
-      }
-    },
     "make-iterator": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/make-iterator/-/make-iterator-1.0.1.tgz",
@@ -5490,6 +6674,18 @@
       "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=",
       "dev": true
     },
+    "merge-stream": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
+      "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
+      "dev": true
+    },
+    "merge2": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.3.0.tgz",
+      "integrity": "sha512-2j4DAdlBOkiSZIsaXk4mTE3sRS02yBHAtfy127xRV3bQUFqXkjHCHLW6Scv7DwNRbIWNHH8zpnz9zMaKXIdvYw==",
+      "dev": true
+    },
     "methods": {
       "version": "1.1.2",
       "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
@@ -5696,9 +6892,9 @@
       "dev": true
     },
     "mute-stream": {
-      "version": "0.0.7",
-      "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz",
-      "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=",
+      "version": "0.0.8",
+      "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz",
+      "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==",
       "dev": true
     },
     "nan": {
@@ -5887,7 +7083,7 @@
     "normalize-package-data": {
       "version": "2.5.0",
       "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz",
-      "integrity": "sha1-5m2xg4sgDB38IzIl0SyzZSDiNKg=",
+      "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==",
       "dev": true,
       "requires": {
         "hosted-git-info": "^2.1.4",
@@ -6087,6 +7283,12 @@
       "integrity": "sha1-QsPhjslUZra/DcQvOilFw/DK2Pw=",
       "dev": true
     },
+    "opencollective-postinstall": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/opencollective-postinstall/-/opencollective-postinstall-2.0.2.tgz",
+      "integrity": "sha512-pVOEP16TrAO2/fjej1IdOyupJY8KDUM1CvsaScRbw6oddvpQoOfGk4ywha0HKKVAD6RkW4x6Q+tNBwhf3Bgpuw==",
+      "dev": true
+    },
     "opn": {
       "version": "4.0.2",
       "resolved": "https://registry.npmjs.org/opn/-/opn-4.0.2.tgz",
@@ -6115,31 +7317,23 @@
       }
     },
     "optionator": {
-      "version": "0.8.2",
-      "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz",
-      "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=",
+      "version": "0.8.3",
+      "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz",
+      "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==",
       "dev": true,
       "requires": {
         "deep-is": "~0.1.3",
-        "fast-levenshtein": "~2.0.4",
+        "fast-levenshtein": "~2.0.6",
         "levn": "~0.3.0",
         "prelude-ls": "~1.1.2",
         "type-check": "~0.3.2",
-        "wordwrap": "~1.0.0"
-      },
-      "dependencies": {
-        "wordwrap": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
-          "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=",
-          "dev": true
-        }
+        "word-wrap": "~1.2.3"
       }
     },
     "original": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/original/-/original-1.0.2.tgz",
-      "integrity": "sha1-5EKmHP/hxf0gpl8yYcJmY7MD8l8=",
+      "integrity": "sha512-hyBVl6iqqUOJ8FqRe+l/gS8H+kKYjrEndd5Pm1MfBtsEKA038HkkdbAl/72EAXGyonD/PFsvmVG+EvcIpliMBg==",
       "dev": true,
       "requires": {
         "url-parse": "^1.4.3"
@@ -6237,6 +7431,15 @@
         "p-limit": "^2.0.0"
       }
     },
+    "p-map": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz",
+      "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==",
+      "dev": true,
+      "requires": {
+        "aggregate-error": "^3.0.0"
+      }
+    },
     "p-try": {
       "version": "2.2.0",
       "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
@@ -6249,6 +7452,15 @@
       "integrity": "sha1-8/dSL073gjSNqBYbrZ7P1Rv4OnU=",
       "dev": true
     },
+    "parent-module": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
+      "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
+      "dev": true,
+      "requires": {
+        "callsites": "^3.0.0"
+      }
+    },
     "parse-filepath": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.2.tgz",
@@ -6323,12 +7535,6 @@
       "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
       "dev": true
     },
-    "path-is-inside": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz",
-      "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=",
-      "dev": true
-    },
     "path-key": {
       "version": "2.0.1",
       "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz",
@@ -6391,6 +7597,12 @@
       "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=",
       "dev": true
     },
+    "picomatch": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.1.1.tgz",
+      "integrity": "sha512-OYMyqkKzK7blWO/+XZYP6w8hH0LDvkBvdvKukti+7kqYFCiEAk+gI3DWnryapc0Dau05ugGTy0foQ6mqn4AHYA==",
+      "dev": true
+    },
     "pify": {
       "version": "2.3.0",
       "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
@@ -6412,11 +7624,59 @@
         "pinkie": "^2.0.0"
       }
     },
-    "pluralize": {
-      "version": "7.0.0",
-      "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-7.0.0.tgz",
-      "integrity": "sha1-KYuJ34uTsCIdv0Ia0rGx6iP8Z3c=",
-      "dev": true
+    "pkg-dir": {
+      "version": "4.2.0",
+      "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz",
+      "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==",
+      "dev": true,
+      "requires": {
+        "find-up": "^4.0.0"
+      },
+      "dependencies": {
+        "find-up": {
+          "version": "4.1.0",
+          "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
+          "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
+          "dev": true,
+          "requires": {
+            "locate-path": "^5.0.0",
+            "path-exists": "^4.0.0"
+          }
+        },
+        "locate-path": {
+          "version": "5.0.0",
+          "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
+          "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
+          "dev": true,
+          "requires": {
+            "p-locate": "^4.1.0"
+          }
+        },
+        "p-locate": {
+          "version": "4.1.0",
+          "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
+          "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
+          "dev": true,
+          "requires": {
+            "p-limit": "^2.2.0"
+          }
+        },
+        "path-exists": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
+          "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
+          "dev": true
+        }
+      }
+    },
+    "please-upgrade-node": {
+      "version": "3.2.0",
+      "resolved": "https://registry.npmjs.org/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz",
+      "integrity": "sha512-gQR3WpIgNIKwBMVLkpMUeR3e1/E1y42bqDQZfql+kDeXd8COYfM8PQA4X6y7a8u9Ua9FHmsrrmirW2vHs45hWg==",
+      "dev": true,
+      "requires": {
+        "semver-compare": "^1.0.0"
+      }
     },
     "portscanner": {
       "version": "1.2.0",
@@ -6445,6 +7705,12 @@
       "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=",
       "dev": true
     },
+    "prettier": {
+      "version": "1.19.1",
+      "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz",
+      "integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==",
+      "dev": true
+    },
     "pretty-bytes": {
       "version": "1.0.4",
       "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-1.0.4.tgz",
@@ -6476,7 +7742,7 @@
     "progress": {
       "version": "2.0.3",
       "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz",
-      "integrity": "sha1-foz42PW48jnBvGi+tOt4Vn1XLvg=",
+      "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==",
       "dev": true
     },
     "proxy-addr": {
@@ -6495,12 +7761,6 @@
       "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=",
       "dev": true
     },
-    "pseudomap": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz",
-      "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=",
-      "dev": true
-    },
     "psl": {
       "version": "1.1.31",
       "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.31.tgz",
@@ -7022,9 +8282,9 @@
       }
     },
     "regexpp": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-1.1.0.tgz",
-      "integrity": "sha1-DjUW3Qt5BPQT0tQZPc5GGMOmias=",
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz",
+      "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==",
       "dev": true
     },
     "regexpu": {
@@ -7150,16 +8410,6 @@
       "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=",
       "dev": true
     },
-    "require-uncached": {
-      "version": "1.0.3",
-      "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz",
-      "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=",
-      "dev": true,
-      "requires": {
-        "caller-path": "^0.1.0",
-        "resolve-from": "^1.0.0"
-      }
-    },
     "requirejs": {
       "version": "2.3.6",
       "resolved": "https://registry.npmjs.org/requirejs/-/requirejs-2.3.6.tgz",
@@ -7192,9 +8442,9 @@
       }
     },
     "resolve-from": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz",
-      "integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=",
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
+      "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
       "dev": true
     },
     "resolve-url": {
@@ -7219,6 +8469,12 @@
       "integrity": "sha1-uKSCXVvbH8P29Twrwz+BOIaBx7w=",
       "dev": true
     },
+    "reusify": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
+      "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
+      "dev": true
+    },
     "right-align": {
       "version": "0.1.3",
       "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz",
@@ -7277,19 +8533,25 @@
         "is-promise": "^2.1.0"
       }
     },
-    "rx-lite": {
-      "version": "4.0.8",
-      "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-4.0.8.tgz",
-      "integrity": "sha1-Cx4Rr4vESDbwSmQH6S2kJGe3lEQ=",
+    "run-node": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/run-node/-/run-node-1.0.0.tgz",
+      "integrity": "sha512-kc120TBlQ3mih1LSzdAJXo4xn/GWS2ec0l3S+syHDXP9uRr0JAT8Qd3mdMuyjqCzeZktgP3try92cEgf9Nks8A==",
       "dev": true
     },
-    "rx-lite-aggregates": {
-      "version": "4.0.8",
-      "resolved": "https://registry.npmjs.org/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz",
-      "integrity": "sha1-dTuHqJoRyVRnxKwWJsTvxOBcZ74=",
+    "run-parallel": {
+      "version": "1.1.9",
+      "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.9.tgz",
+      "integrity": "sha512-DEqnSRTDw/Tc3FXf49zedI638Z9onwUotBMiUFKmrO2sdFKIbXamXGQ3Axd4qgphxKB4kw/qP1w5kTxnfU1B9Q==",
+      "dev": true
+    },
+    "rxjs": {
+      "version": "6.5.3",
+      "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.3.tgz",
+      "integrity": "sha512-wuYsAYYFdWTAnAaPoKGNhfpWwKZbJW+HgAJ+mImp+Epl7BG8oNWBCTyRM8gba9k4lk8BgWdoYm21Mo/RYhhbgA==",
       "dev": true,
       "requires": {
-        "rx-lite": "*"
+        "tslib": "^1.9.0"
       }
     },
     "safe-buffer": {
@@ -7340,6 +8602,12 @@
       "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==",
       "dev": true
     },
+    "semver-compare": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz",
+      "integrity": "sha1-De4hahyUGrN+nvsXiPavxf9VN/w=",
+      "dev": true
+    },
     "send": {
       "version": "0.16.2",
       "resolved": "https://registry.npmjs.org/send/-/send-0.16.2.tgz",
@@ -7509,12 +8777,25 @@
       "dev": true
     },
     "slice-ansi": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-1.0.0.tgz",
-      "integrity": "sha1-BE8aSdiEL/MHqta1Be0Xi9lQE00=",
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz",
+      "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==",
       "dev": true,
       "requires": {
+        "ansi-styles": "^3.2.0",
+        "astral-regex": "^1.0.0",
         "is-fullwidth-code-point": "^2.0.0"
+      },
+      "dependencies": {
+        "ansi-styles": {
+          "version": "3.2.1",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+          "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+          "dev": true,
+          "requires": {
+            "color-convert": "^1.9.0"
+          }
+        }
       }
     },
     "snapdragon": {
@@ -7634,7 +8915,7 @@
     "sockjs": {
       "version": "0.3.19",
       "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.19.tgz",
-      "integrity": "sha1-2Xa76ACve9IK4IWY1YI5NQiZPA0=",
+      "integrity": "sha512-V48klKZl8T6MzatbLlzzRNhMepEys9Y4oGFpypBFFn1gLI/QQ9HtLLyWJNbPlwGLelOVOEijUbTTJeLLI59jLw==",
       "dev": true,
       "requires": {
         "faye-websocket": "^0.10.0",
@@ -7690,7 +8971,7 @@
     "source-map": {
       "version": "0.6.1",
       "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
-      "integrity": "sha1-dHIq8y6WFOnCh6jQu95IteLxomM="
+      "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
     },
     "source-map-resolve": {
       "version": "0.5.2",
@@ -7734,7 +9015,7 @@
     "spdx-correct": {
       "version": "3.1.0",
       "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz",
-      "integrity": "sha1-+4PlBERSaPFUsHTiGMh8ADzTHfQ=",
+      "integrity": "sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==",
       "dev": true,
       "requires": {
         "spdx-expression-parse": "^3.0.0",
@@ -7744,13 +9025,13 @@
     "spdx-exceptions": {
       "version": "2.2.0",
       "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz",
-      "integrity": "sha1-LqRQrudPKom/uUUZwH/Nb0EyKXc=",
+      "integrity": "sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA==",
       "dev": true
     },
     "spdx-expression-parse": {
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz",
-      "integrity": "sha1-meEZt6XaAOBUkcn6M4t5BII7QdA=",
+      "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==",
       "dev": true,
       "requires": {
         "spdx-exceptions": "^2.1.0",
@@ -7840,7 +9121,7 @@
     "stream-browserify": {
       "version": "2.0.2",
       "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz",
-      "integrity": "sha1-h1IdOKRKp+6RzhzSpH3wy0ndZgs=",
+      "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==",
       "dev": true,
       "requires": {
         "inherits": "~2.0.1",
@@ -7856,7 +9137,7 @@
     "stream-http": {
       "version": "2.8.3",
       "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz",
-      "integrity": "sha1-stJCRpKIpaJ+xP6JM6z2I95lFPw=",
+      "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==",
       "dev": true,
       "requires": {
         "builtin-status-codes": "^3.0.0",
@@ -7866,6 +9147,12 @@
         "xtend": "^4.0.0"
       }
     },
+    "string-argv": {
+      "version": "0.3.1",
+      "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.1.tgz",
+      "integrity": "sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg==",
+      "dev": true
+    },
     "string-template": {
       "version": "0.2.1",
       "resolved": "https://registry.npmjs.org/string-template/-/string-template-0.2.1.tgz",
@@ -7908,6 +9195,17 @@
         "safe-buffer": "~5.1.0"
       }
     },
+    "stringify-object": {
+      "version": "3.3.0",
+      "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz",
+      "integrity": "sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==",
+      "dev": true,
+      "requires": {
+        "get-own-enumerable-property-symbols": "^3.0.0",
+        "is-obj": "^1.0.1",
+        "is-regexp": "^1.0.0"
+      }
+    },
     "stringmap": {
       "version": "0.2.2",
       "resolved": "https://registry.npmjs.org/stringmap/-/stringmap-0.2.2.tgz",
@@ -7944,6 +9242,12 @@
       "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=",
       "dev": true
     },
+    "strip-final-newline": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz",
+      "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==",
+      "dev": true
+    },
     "strip-indent": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz",
@@ -7971,53 +9275,60 @@
       "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
       "dev": true
     },
+    "symbol-observable": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz",
+      "integrity": "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==",
+      "dev": true
+    },
     "table": {
-      "version": "4.0.2",
-      "resolved": "https://registry.npmjs.org/table/-/table-4.0.2.tgz",
-      "integrity": "sha1-ozRHN1OR52atNNNIbm4q7chNLjY=",
+      "version": "5.4.6",
+      "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz",
+      "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==",
       "dev": true,
       "requires": {
-        "ajv": "^5.2.3",
-        "ajv-keywords": "^2.1.0",
-        "chalk": "^2.1.0",
-        "lodash": "^4.17.4",
-        "slice-ansi": "1.0.0",
-        "string-width": "^2.1.1"
+        "ajv": "^6.10.2",
+        "lodash": "^4.17.14",
+        "slice-ansi": "^2.1.0",
+        "string-width": "^3.0.0"
       },
       "dependencies": {
-        "ansi-styles": {
-          "version": "3.2.1",
-          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
-          "integrity": "sha1-QfuyAkPlCxK+DwS43tvwdSDOhB0=",
-          "dev": true,
-          "requires": {
-            "color-convert": "^1.9.0"
-          }
+        "ansi-regex": {
+          "version": "4.1.0",
+          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
+          "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
+          "dev": true
         },
-        "chalk": {
-          "version": "2.4.2",
-          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
-          "integrity": "sha1-zUJUFnelQzPPVBpJEIwUMrRMlCQ=",
-          "dev": true,
-          "requires": {
-            "ansi-styles": "^3.2.1",
-            "escape-string-regexp": "^1.0.5",
-            "supports-color": "^5.3.0"
-          }
+        "emoji-regex": {
+          "version": "7.0.3",
+          "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz",
+          "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==",
+          "dev": true
         },
         "lodash": {
-          "version": "4.17.11",
-          "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz",
-          "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==",
+          "version": "4.17.15",
+          "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
+          "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==",
           "dev": true
         },
-        "supports-color": {
-          "version": "5.5.0",
-          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
-          "integrity": "sha1-4uaaRKyHcveKHsCzW2id9lMO/I8=",
+        "string-width": {
+          "version": "3.1.0",
+          "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
+          "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
           "dev": true,
           "requires": {
-            "has-flag": "^3.0.0"
+            "emoji-regex": "^7.0.1",
+            "is-fullwidth-code-point": "^2.0.0",
+            "strip-ansi": "^5.1.0"
+          }
+        },
+        "strip-ansi": {
+          "version": "5.2.0",
+          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
+          "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
+          "dev": true,
+          "requires": {
+            "ansi-regex": "^4.1.0"
           }
         }
       }
@@ -8095,7 +9406,7 @@
     "tmp": {
       "version": "0.0.33",
       "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
-      "integrity": "sha1-bTQzWIl2jSGyvNoKonfO07G/rfk=",
+      "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==",
       "dev": true,
       "requires": {
         "os-tmpdir": "~1.0.2"
@@ -8339,6 +9650,12 @@
       "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==",
       "dev": true
     },
+    "type-fest": {
+      "version": "0.6.0",
+      "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz",
+      "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==",
+      "dev": true
+    },
     "type-is": {
       "version": "1.6.16",
       "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.16.tgz",
@@ -8580,6 +9897,12 @@
       "integrity": "sha1-G0r0lV6zB3xQHCOHL8ZROBFYcTE=",
       "dev": true
     },
+    "v8-compile-cache": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.0.tgz",
+      "integrity": "sha512-usZBT3PW+LOjM25wbqIlZwPeJV+3OSz3M1k1Ws8snlW39dZyYL9lOGC5FgPVHfk0jKmjiDV8Z0mIbVQPiwFs7g==",
+      "dev": true
+    },
     "v8flags": {
       "version": "3.1.2",
       "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-3.1.2.tgz",
@@ -8592,7 +9915,7 @@
     "validate-npm-package-license": {
       "version": "3.0.4",
       "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",
-      "integrity": "sha1-/JH2uce6FchX9MssXe/uw51PQQo=",
+      "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==",
       "dev": true,
       "requires": {
         "spdx-correct": "^3.0.0",
@@ -8873,6 +10196,12 @@
       "integrity": "sha1-+OGqHuWlPsW/FR/6CXQqatdpeHY=",
       "dev": true
     },
+    "word-wrap": {
+      "version": "1.2.3",
+      "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz",
+      "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==",
+      "dev": true
+    },
     "wordwrap": {
       "version": "0.0.3",
       "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz",
@@ -8917,9 +10246,9 @@
       "dev": true
     },
     "write": {
-      "version": "0.2.1",
-      "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz",
-      "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=",
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz",
+      "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==",
       "dev": true,
       "requires": {
         "mkdirp": "^0.5.1"
@@ -8953,12 +10282,6 @@
       "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=",
       "dev": true
     },
-    "yallist": {
-      "version": "2.1.2",
-      "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
-      "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=",
-      "dev": true
-    },
     "yargs": {
       "version": "3.27.0",
       "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.27.0.tgz",
diff --git a/package.json b/package.json
index 74749d86b..df72801d3 100644
--- a/package.json
+++ b/package.json
@@ -39,6 +39,8 @@
     "dtslint": "^0.5.5",
     "dustjs-linkedin": "^2.0.2",
     "eco": "~1.1.0-rc-3",
+    "eslint": "^6.7.2",
+    "eslint-config-prettier": "^6.7.0",
     "eslint-plugin-compat": "^3.3.0",
     "eslint-plugin-es5": "^1.4.1",
     "grunt": "^1.0.3",
@@ -52,13 +54,15 @@
     "grunt-contrib-requirejs": "^1",
     "grunt-contrib-uglify": "^1",
     "grunt-contrib-watch": "^1.1.0",
-    "grunt-eslint": "^20.1.0",
     "grunt-webpack": "^1.0.8",
+    "husky": "^3.1.0",
     "istanbul": "^0.3.0",
     "jison": "~0.3.0",
+    "lint-staged": "^9.5.0",
     "mocha": "^5",
     "mock-stdin": "^0.3.0",
     "mustache": "^2.1.3",
+    "prettier": "^1.19.1",
     "semver": "^5.0.1",
     "sinon": "^7.5.0",
     "typescript": "^3.4.3",
@@ -76,6 +80,9 @@
     "handlebars": "bin/handlebars"
   },
   "scripts": {
+    "format": "prettier --write '**/*.js' && eslint --fix .",
+    "check-format": "prettier --check '**/*.js'",
+    "lint": "eslint .",
     "checkTypes": "dtslint types",
     "test": "grunt"
   },
@@ -98,5 +105,20 @@
     "release-notes.md",
     "runtime.js",
     "types/*.d.ts"
-  ]
+  ],
+  "husky": {
+    "hooks": {
+      "pre-commit": "lint-staged"
+    }
+  },
+  "lint-staged": {
+    "*.{js,css,json,md}": [
+      "prettier --write",
+      "git add"
+    ],
+    "*.js": [
+      "eslint --fix",
+      "git add"
+    ]
+  }
 }
diff --git a/prettier.config.js b/prettier.config.js
new file mode 100644
index 000000000..6593a6b7d
--- /dev/null
+++ b/prettier.config.js
@@ -0,0 +1,5 @@
+module.exports = {
+  tabWidth: 2,
+  semi: true,
+  singleQuote: true
+};
diff --git a/spec/.eslintrc b/spec/.eslintrc
index 4bec97f44..076b25a8e 100644
--- a/spec/.eslintrc
+++ b/spec/.eslintrc
@@ -1,7 +1,8 @@
 {
   "extends": [
     "../.eslintrc.js",
-    "plugin:es5/no-es2015"
+    "plugin:es5/no-es2015",
+    "prettier"
   ],
   "plugins": [
     "es5"
@@ -43,4 +44,4 @@
     "no-var": "off",
     "dot-notation": "off"
   }
-}
\ No newline at end of file
+}
diff --git a/spec/amd-runtime.html b/spec/amd-runtime.html
index fc413bd67..4cbfd5ca0 100644
--- a/spec/amd-runtime.html
+++ b/spec/amd-runtime.html
@@ -26,8 +26,8 @@
       window.expect = chai.expect;
       mocha.setup('bdd');
     </script>
-    <script src="/spec/env/json2.js"></script>
-    <script src="/spec/env/require.js"></script>
+    <script src="/spec/vendor/json2.js"></script>
+    <script src="/spec/vendor/require.js"></script>
 
     <script src="/spec/env/common.js"></script>
     <script>
diff --git a/spec/amd.html b/spec/amd.html
index 9ec44e686..1f783e02c 100644
--- a/spec/amd.html
+++ b/spec/amd.html
@@ -27,8 +27,8 @@
       window.expect = chai.expect;
       mocha.setup('bdd');
     </script>
-    <script src="/spec/env/json2.js"></script>
-    <script src="/spec/env/require.js"></script>
+    <script src="/spec/vendor/json2.js"></script>
+    <script src="/spec/vendor/require.js"></script>
 
     <script src="/spec/env/common.js"></script>
     <script>
diff --git a/spec/index.html b/spec/index.html
index b768dff76..3f2068ed1 100644
--- a/spec/index.html
+++ b/spec/index.html
@@ -28,7 +28,7 @@
       mocha.setup('bdd');
     </script>
     <script src="/dist/handlebars.js"></script>
-    <script src="/spec/env/json2.js"></script>
+    <script src="/spec/vendor/json2.js"></script>
     <script src="/spec/env/common.js"></script>
     <script>
       var CompilerContext = {
diff --git a/spec/umd-runtime.html b/spec/umd-runtime.html
index 212d4f2dc..49b721ded 100644
--- a/spec/umd-runtime.html
+++ b/spec/umd-runtime.html
@@ -26,8 +26,8 @@
       window.expect = chai.expect;
       mocha.setup('bdd');
     </script>
-    <script src="/spec/env/json2.js"></script>
-    <script src="/spec/env/require.js"></script>
+    <script src="/spec/vendor/json2.js"></script>
+    <script src="/spec/vendor/require.js"></script>
 
     <script src="/spec/env/common.js"></script>
     <script>
diff --git a/spec/umd.html b/spec/umd.html
index 53d6b2716..ae461ed69 100644
--- a/spec/umd.html
+++ b/spec/umd.html
@@ -27,8 +27,8 @@
       window.expect = chai.expect;
       mocha.setup('bdd');
     </script>
-    <script src="/spec/env/json2.js"></script>
-    <script src="/spec/env/require.js"></script>
+    <script src="/spec/vendor/json2.js"></script>
+    <script src="/spec/vendor/require.js"></script>
 
     <script src="/spec/env/common.js"></script>
     <script>
diff --git a/spec/env/json2.js b/spec/vendor/json2.js
similarity index 100%
rename from spec/env/json2.js
rename to spec/vendor/json2.js
diff --git a/spec/env/require.js b/spec/vendor/require.js
similarity index 100%
rename from spec/env/require.js
rename to spec/vendor/require.js

From e913dc5f12249299605dcacfa61453d8c40d0b2e Mon Sep 17 00:00:00 2001
From: Nils Knappmeier <github@knappi.org>
Date: Tue, 3 Dec 2019 22:00:18 +0100
Subject: [PATCH 05/24] chore: restructure build commands

- move dtslint (checkTypes) away from Gruntfile.js
  (as it disturbs debugging `grunt`)
  and call it directly as npm-script in travis-ci
- re-group task definition in Gruntfile.js
- use a multi-job travis build to
  run linting, format, dtslint and tests
  in parallel
- run only "npm test" on appveyor
- rename Grunt-tasks for be more descriptive
- SAUCE_USERNAME is not a secret variable anymore
  it can be easily guessed anyway and the
  [secure] value messes up with a lot of the
  log output

- linting on commit disable during transition
---
 .travis.yml                                   |  61 ++++--
 CONTRIBUTING.md                               |  40 +++-
 Gruntfile.js                                  |  47 +++--
 appveyor.yml                                  |   7 +-
 integration-testing/multi-nodejs-test/test.sh |   5 +-
 package-lock.json                             | 199 ++++++++++++++++++
 package.json                                  |  13 +-
 7 files changed, 310 insertions(+), 62 deletions(-)

diff --git a/.travis.yml b/.travis.yml
index a6b141a22..a5ff4c692 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,28 +1,47 @@
 language: node_js
-before_install:
-- npm install -g grunt-cli
-script:
-- npm run lint
-- npm run check-format
-- grunt --stack travis
+
+jobs:
+  include:
+    - stage: test
+      name: "check javascript (eslint)"
+      node_js: lts/*
+      script: npm run lint
+
+    - stage: test
+      name: "check formatting (prettier)"
+      node_js: lts/*
+      script: npm run check-format
+
+    - stage: test
+      name: "check typescript definitions (dtslint)"
+      node_js: lts/*
+      script: npm run dtslint
+
+    - stage: test
+      name: "extensive tests and publish to aws"
+      script: npm run extensive-tests-and-publish-to-aws
+      env:
+        - S3_BUCKET_NAME=builds.handlebarsjs.com
+        - secure: ckyEe5dzjdFDjmZ6wIrhGm0CFBEnKq8c1dYptfgVV/Q5/nJFGzu8T0yTjouS/ERxzdT2H327/63VCxhFnLCRHrsh4rlW/rCy4XI3O/0TeMLgFPa4TXkO8359qZ4CB44TBb3NsJyQXNMYdJpPLTCVTMpuiqqkFFOr+6OeggR7ufA=
+        - secure: Nm4AgSfsgNB21kgKrF9Tl7qVZU8YYREhouQunFracTcZZh2NZ2XH5aHuSiXCj88B13Cr/jGbJKsZ4T3QS3wWYtz6lkyVOx3H3iI+TMtqhD9RM3a7A4O+4vVN8IioB2YjhEu0OKjwgX5gp+0uF+pLEi7Hpj6fupD3AbbL5uYcKg8=
+        - SAUCE_USERNAME=handlebars
+        - secure: yERYCf7AwL11D9uMtacly/THGV8BlzsMmrt+iQVvGA3GaY6QMmfYqf6P6cCH98sH5etd1Y+1e6YrPeMjqI6lyRllT7FptoyOdHulazQe86VQN4sc0EpqMlH088kB7gGjTut9Z+X9ViooT5XEh9WA5jXEI9pXhQJNoIHkWPuwGuY=
+      node_js: "10"
+
+    - stage: test
+      name: "test with latest nodejs-lts"
+      node_js: lts/*
+      script: npm run test
+
+    - stage: test
+      name: "test with active nodejs"
+      node_js: node
+      script: npm run test
+
+cache: npm
 email:
   on_failure: change
   on_success: never
-env:
-  global:
-  - S3_BUCKET_NAME=builds.handlebarsjs.com
-  - secure: ckyEe5dzjdFDjmZ6wIrhGm0CFBEnKq8c1dYptfgVV/Q5/nJFGzu8T0yTjouS/ERxzdT2H327/63VCxhFnLCRHrsh4rlW/rCy4XI3O/0TeMLgFPa4TXkO8359qZ4CB44TBb3NsJyQXNMYdJpPLTCVTMpuiqqkFFOr+6OeggR7ufA=
-  - secure: Nm4AgSfsgNB21kgKrF9Tl7qVZU8YYREhouQunFracTcZZh2NZ2XH5aHuSiXCj88B13Cr/jGbJKsZ4T3QS3wWYtz6lkyVOx3H3iI+TMtqhD9RM3a7A4O+4vVN8IioB2YjhEu0OKjwgX5gp+0uF+pLEi7Hpj6fupD3AbbL5uYcKg8=
-matrix:
-  include:
-  - node_js: '10'
-    env:
-    - PUBLISH=true
-    - secure: pLTzghtVll9yGKJI0AaB0uI8GypfWxLTaIB0ZL8//yN3nAEIKMhf/RRilYTsn/rKj2NUa7vt2edYILi3lttOUlCBOwTc9amiRms1W8Lwr/3IdWPeBLvLuH1zNJRm2lBAwU4LBSqaOwhGaxOQr6KHTnWudhNhgOucxpZfvfI/dFw=
-    - secure: yERYCf7AwL11D9uMtacly/THGV8BlzsMmrt+iQVvGA3GaY6QMmfYqf6P6cCH98sH5etd1Y+1e6YrPeMjqI6lyRllT7FptoyOdHulazQe86VQN4sc0EpqMlH088kB7gGjTut9Z+X9ViooT5XEh9WA5jXEI9pXhQJNoIHkWPuwGuY=
-cache:
-  directories:
-  - node_modules
 
 git:
   depth: 100
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 5dc1c9fb5..d26df5ca9 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -12,8 +12,8 @@ Documentation issues on the handlebarsjs.com site should be reported on [handleb
 
 ## Branches
 
-* The branch `4.x` contains the currently released version. Bugfixes should be made in this branch.
-* The branch `master` contains the next version. A release date is not yet specified. Maintainers
+- The branch `4.x` contains the currently released version. Bugfixes should be made in this branch.
+- The branch `master` contains the next version. A release date is not yet specified. Maintainers
   should merge the branch `4.x` into the master branch regularly.
 
 ## Pull Requests
@@ -21,6 +21,7 @@ Documentation issues on the handlebarsjs.com site should be reported on [handleb
 We also accept [pull requests][pull-request]!
 
 Generally we like to see pull requests that
+
 - Maintain the existing code style
 - Are focused on a single change (i.e. avoid large refactoring or style adjustments in untouched code if not the primary goal of the pull request)
 - Have [good commit messages](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html)
@@ -31,8 +32,8 @@ Generally we like to see pull requests that
 
 To build Handlebars.js you'll need a few things installed.
 
-* Node.js
-* [Grunt](http://gruntjs.com/getting-started)
+- Node.js
+- [Grunt](http://gruntjs.com/getting-started)
 
 Before building, you need to make sure that the Git submodule `spec/mustache` is included (i.e. the directory `spec/mustache` should not be empty). To include it, if using Git version 1.6.5 or newer, use `git clone --recursive` rather than `git clone`. Or, if you already cloned without `--recursive`, use `git submodule update --init`.
 
@@ -51,11 +52,13 @@ If you notice any problems, please report them to the GitHub issue tracker at
 ##Running Tests
 
 To run tests locally, first install all dependencies.
+
 ```sh
 npm install
 ```
 
 Clone the mustache specs into the spec/mustache folder.
+
 ```sh
 cd spec
 rm -r mustache
@@ -63,10 +66,29 @@ git clone https://github.com/mustache/spec.git mustache
 ```
 
 From the root directory, run the tests.
+
 ```sh
 npm test
 ```
 
+## Linting and Formatting
+
+Handlebars uses `eslint` to enforce best-practices and `prettier` to auto-format files.
+We do linting and formatting in two phases:
+
+- Committed files are linted and formatted in a pre-commit hook. In this stage eslint-errors are forbidden,
+  while warnings are allowed.
+- The travis-ci job also lints all files and checks if they are formatted correctly. In this stage, warnings
+  are forbidden.
+
+You can use the following scripts to make sure that the travis-job does not fail:
+
+- **npm run lint** will run `eslint` and fail on warnings
+- **npm run format** will run `prettier` on all files
+- **npm run check-before-pull-request** will perform all most checks that travis does in its build-job, excluding the "integration-test".
+- **npm run integration-test** will run integration tests (using old NodeJS versions and integrations with webpack, babel and so on)
+  These tests only work on a Linux-machine with `nvm` installed (for running tests in multiple versions of NodeJS).
+
 ## Ember testing
 
 The current ember distribution should be tested as part of the handlebars release process. This requires building the `handlebars-source` gem locally and then executing the ember test script.
@@ -83,7 +105,7 @@ npm test
 
 ## Releasing the latest version
 
-*When releasing a previous version of Handlebars, please look into the CONTRIBUNG.md in the corresponding branch.*
+_When releasing a previous version of Handlebars, please look into the CONTRIBUNG.md in the corresponding branch._
 
 Handlebars utilizes the [release yeoman generator][generator-release] to perform most release tasks.
 
@@ -103,10 +125,10 @@ gem push handlebars-source-*.gem
 After the release, you should check that all places have really been updated. Especially verify that the `latest`-tags
 in those places still point to the latest version
 
-* [The npm-package](https://www.npmjs.com/package/handlebars) (check latest-tag)
-* [The bower package](https://github.com/components/handlebars.js) (check the package.json)
-* [The AWS S3 Bucket](https://s3.amazonaws.com/builds.handlebarsjs.com) (check latest-tag)
-* [RubyGems](https://rubygems.org/gems/handlebars-source)
+- [The npm-package](https://www.npmjs.com/package/handlebars) (check latest-tag)
+- [The bower package](https://github.com/components/handlebars.js) (check the package.json)
+- [The AWS S3 Bucket](https://s3.amazonaws.com/builds.handlebarsjs.com) (check latest-tag)
+- [RubyGems](https://rubygems.org/gems/handlebars-source)
 
 When everything is OK, the handlebars site needs to be updated to point to the new version numbers. The jsfiddle link should be updated to point to the most recent distribution for all instances in our documentation.
 
diff --git a/Gruntfile.js b/Gruntfile.js
index a471f67e7..d91783f5f 100644
--- a/Gruntfile.js
+++ b/Gruntfile.js
@@ -175,11 +175,6 @@ module.exports = function(grunt) {
     },
 
     bgShell: {
-      checkTypes: {
-        cmd: 'npm run checkTypes',
-        bg: false,
-        fail: true
-      },
       integrationTests: {
         cmd: './integration-testing/run-integration-tests.sh',
         bg: false,
@@ -195,25 +190,11 @@ module.exports = function(grunt) {
         },
 
         files: ['src/*', 'lib/**/*.js', 'spec/**/*.js'],
-        tasks: ['build', 'amd', 'tests', 'test']
+        tasks: ['on-file-change']
       }
     }
   });
 
-  // Build a new version of the library
-  this.registerTask('build', 'Builds a distributable version of the current project', [
-                    'bgShell:checkTypes',
-                    'parser',
-                    'node',
-                    'globals']);
-
-  this.registerTask('amd', ['babel:amd', 'requirejs']);
-  this.registerTask('node', ['babel:cjs']);
-  this.registerTask('globals', ['webpack']);
-  this.registerTask('tests', ['concat:tests']);
-
-  this.registerTask('release', 'Build final packages', ['amd', 'uglify', 'test:min', 'copy:dist', 'copy:components', 'copy:cdnjs']);
-
   // Load tasks from npm
   grunt.loadNpmTasks('grunt-contrib-clean');
   grunt.loadNpmTasks('grunt-contrib-concat');
@@ -229,11 +210,33 @@ module.exports = function(grunt) {
 
   grunt.task.loadTasks('tasks');
 
+  this.registerTask(
+      'build',
+      'Builds a distributable version of the current project',
+      ['parser', 'node', 'globals']
+  );
+
+  this.registerTask('node', ['babel:cjs']);
+  this.registerTask('globals', ['webpack']);
+
+  this.registerTask('release', 'Build final packages', [
+    'amd',
+    'uglify',
+    'test:min',
+    'copy:dist',
+    'copy:components',
+    'copy:cdnjs'
+  ]);
+
+  this.registerTask('amd', ['babel:amd', 'requirejs']);
+
   grunt.registerTask('bench', ['metrics']);
   grunt.registerTask('sauce', process.env.SAUCE_USERNAME ? ['tests', 'connect', 'saucelabs-mocha'] : []);
+  // Requires secret properties (saucelabs-credentials etc.) from .travis.yaml
+  grunt.registerTask('extensive-tests-and-publish-to-aws', ['default', 'bgShell:integrationTests', 'sauce', 'metrics', 'publish:latest']);
+  grunt.registerTask('on-file-change', ['build', 'amd', 'concat:tests', 'test']);
 
-  grunt.registerTask('travis', process.env.PUBLISH ? ['default', 'bgShell:integrationTests', 'sauce', 'metrics', 'publish:latest'] : ['default']);
-
+  // === Primary tasks ===
   grunt.registerTask('dev', ['clean', 'connect', 'watch']);
   grunt.registerTask('default', ['clean', 'build', 'test', 'release']);
   grunt.registerTask('integration-tests', ['default', 'bgShell:integrationTests']);
diff --git a/appveyor.yml b/appveyor.yml
index 563aaf93c..499e57995 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -13,8 +13,7 @@ install:
   # Clone submodules (mustache spec)
   - cmd: git submodule update --init --recursive
   # Install modules
-  - cmd: npm install
-  - cmd: npm install -g grunt-cli
+  - cmd: npm ci
 
 
 # Post-install test scripts
@@ -23,7 +22,7 @@ test_script:
   - cmd: node --version
   - cmd: npm --version
   # Run tests
-  - cmd: grunt --stack travis
+  - cmd: npm run test
 
 # Don't actually build
 build: off
@@ -34,4 +33,4 @@ on_failure:
 
 
 # Set build version format here instead of in the admin panel
-version: "{build}"
\ No newline at end of file
+version: "{build}"
diff --git a/integration-testing/multi-nodejs-test/test.sh b/integration-testing/multi-nodejs-test/test.sh
index 953949bb2..db2caf854 100755
--- a/integration-testing/multi-nodejs-test/test.sh
+++ b/integration-testing/multi-nodejs-test/test.sh
@@ -12,7 +12,8 @@ cd "$( dirname "$( readlink -f "$0" )" )" || exit 1
 # It does (almost) not test for correctness, because that is already done in the mocha-tests.
 # And it does not use any NodeJS based testing framwork to make this part independent of the Node version.
 
-# A list of NodeJS versions is expected as cli-args
+unset npm_config_prefix
+
 echo "Handlebars should be able to run in various versions of NodeJS"
 for i in  0.10 0.12 4 5 6 7 8 9 10 11 ; do
     rm target node_modules package-lock.json -rf
@@ -23,4 +24,4 @@ for i in  0.10 0.12 4 5 6 7 8 9 10 11 ; do
     nvm exec "$i" npm run test-precompile || exit 1
 
     echo Success
-done
\ No newline at end of file
+done
diff --git a/package-lock.json b/package-lock.json
index 3a36a15af..79fc1b9c4 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1561,6 +1561,193 @@
         "typedarray": "^0.0.6"
       }
     },
+    "concurrently": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-5.0.0.tgz",
+      "integrity": "sha512-1yDvK8mduTIdxIxV9C60KoiOySUl/lfekpdbI+U5GXaPrgdffEavFa9QZB3vh68oWOpbCC+TuvxXV9YRPMvUrA==",
+      "dev": true,
+      "requires": {
+        "chalk": "^2.4.2",
+        "date-fns": "^2.0.1",
+        "lodash": "^4.17.15",
+        "read-pkg": "^4.0.1",
+        "rxjs": "^6.5.2",
+        "spawn-command": "^0.0.2-1",
+        "supports-color": "^4.5.0",
+        "tree-kill": "^1.2.1",
+        "yargs": "^12.0.5"
+      },
+      "dependencies": {
+        "ansi-regex": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
+          "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
+          "dev": true
+        },
+        "ansi-styles": {
+          "version": "3.2.1",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+          "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+          "dev": true,
+          "requires": {
+            "color-convert": "^1.9.0"
+          }
+        },
+        "chalk": {
+          "version": "2.4.2",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+          "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "^3.2.1",
+            "escape-string-regexp": "^1.0.5",
+            "supports-color": "^5.3.0"
+          },
+          "dependencies": {
+            "supports-color": {
+              "version": "5.5.0",
+              "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+              "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+              "dev": true,
+              "requires": {
+                "has-flag": "^3.0.0"
+              }
+            }
+          }
+        },
+        "cliui": {
+          "version": "4.1.0",
+          "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz",
+          "integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==",
+          "dev": true,
+          "requires": {
+            "string-width": "^2.1.1",
+            "strip-ansi": "^4.0.0",
+            "wrap-ansi": "^2.0.0"
+          }
+        },
+        "date-fns": {
+          "version": "2.8.1",
+          "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.8.1.tgz",
+          "integrity": "sha512-EL/C8IHvYRwAHYgFRse4MGAPSqlJVlOrhVYZ75iQBKrnv+ZedmYsgwH3t+BCDuZDXpoo07+q9j4qgSSOa7irJg==",
+          "dev": true
+        },
+        "find-up": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
+          "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
+          "dev": true,
+          "requires": {
+            "locate-path": "^3.0.0"
+          }
+        },
+        "invert-kv": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz",
+          "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==",
+          "dev": true
+        },
+        "lcid": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz",
+          "integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==",
+          "dev": true,
+          "requires": {
+            "invert-kv": "^2.0.0"
+          }
+        },
+        "lodash": {
+          "version": "4.17.15",
+          "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
+          "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==",
+          "dev": true
+        },
+        "os-locale": {
+          "version": "3.1.0",
+          "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz",
+          "integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==",
+          "dev": true,
+          "requires": {
+            "execa": "^1.0.0",
+            "lcid": "^2.0.0",
+            "mem": "^4.0.0"
+          }
+        },
+        "parse-json": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz",
+          "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=",
+          "dev": true,
+          "requires": {
+            "error-ex": "^1.3.1",
+            "json-parse-better-errors": "^1.0.1"
+          }
+        },
+        "pify": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
+          "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
+          "dev": true
+        },
+        "read-pkg": {
+          "version": "4.0.1",
+          "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-4.0.1.tgz",
+          "integrity": "sha1-ljYlN48+HE1IyFhytabsfV0JMjc=",
+          "dev": true,
+          "requires": {
+            "normalize-package-data": "^2.3.2",
+            "parse-json": "^4.0.0",
+            "pify": "^3.0.0"
+          }
+        },
+        "strip-ansi": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
+          "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
+          "dev": true,
+          "requires": {
+            "ansi-regex": "^3.0.0"
+          }
+        },
+        "supports-color": {
+          "version": "4.5.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz",
+          "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=",
+          "dev": true,
+          "requires": {
+            "has-flag": "^2.0.0"
+          },
+          "dependencies": {
+            "has-flag": {
+              "version": "2.0.0",
+              "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
+              "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=",
+              "dev": true
+            }
+          }
+        },
+        "yargs": {
+          "version": "12.0.5",
+          "resolved": "https://registry.npmjs.org/yargs/-/yargs-12.0.5.tgz",
+          "integrity": "sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw==",
+          "dev": true,
+          "requires": {
+            "cliui": "^4.0.0",
+            "decamelize": "^1.2.0",
+            "find-up": "^3.0.0",
+            "get-caller-file": "^1.0.1",
+            "os-locale": "^3.0.0",
+            "require-directory": "^2.1.1",
+            "require-main-filename": "^1.0.1",
+            "set-blocking": "^2.0.0",
+            "string-width": "^2.0.0",
+            "which-module": "^2.0.0",
+            "y18n": "^3.2.1 || ^4.0.0",
+            "yargs-parser": "^11.1.1"
+          }
+        }
+      }
+    },
     "connect": {
       "version": "3.6.6",
       "resolved": "https://registry.npmjs.org/connect/-/connect-3.6.6.tgz",
@@ -9012,6 +9199,12 @@
       "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=",
       "dev": true
     },
+    "spawn-command": {
+      "version": "0.0.2-1",
+      "resolved": "https://registry.npmjs.org/spawn-command/-/spawn-command-0.0.2-1.tgz",
+      "integrity": "sha1-YvXpRmmBwbeW3Fkpk34RycaSG9A=",
+      "dev": true
+    },
     "spdx-correct": {
       "version": "3.1.0",
       "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz",
@@ -9484,6 +9677,12 @@
         }
       }
     },
+    "tree-kill": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.1.tgz",
+      "integrity": "sha512-4hjqbObwlh2dLyW4tcz0Ymw0ggoaVDMveUB9w8kFSQScdRLo0gxO9J7WFcUBo+W3C1TLdFIEwNOWebgZZ0RH9Q==",
+      "dev": true
+    },
     "trim-newlines": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz",
diff --git a/package.json b/package.json
index df72801d3..a925e0a65 100644
--- a/package.json
+++ b/package.json
@@ -35,6 +35,7 @@
     "babel-runtime": "^5.1.10",
     "benchmark": "~1.0",
     "chai": "^4.2.0",
+    "concurrently": "^5.0.0",
     "dirty-chai": "^2.0.1",
     "dtslint": "^0.5.5",
     "dustjs-linkedin": "^2.0.2",
@@ -82,9 +83,13 @@
   "scripts": {
     "format": "prettier --write '**/*.js' && eslint --fix .",
     "check-format": "prettier --check '**/*.js'",
-    "lint": "eslint .",
-    "checkTypes": "dtslint types",
-    "test": "grunt"
+    "lint": "eslint --max-warnings 0 . ",
+    "dtslint": "dtslint types",
+    "test": "grunt",
+    "extensive-tests-and-publish-to-aws": "grunt --stack extensive-tests-and-publish-to-aws",
+    "integration-test": "grunt integration-tests",
+    "--- combined tasks ---": "",
+    "check-before-pull-request": "concurrently --kill-others-on-fail npm:lint npm:dtslint npm:check-format npm:test"
   },
   "jspm": {
     "main": "handlebars",
@@ -108,7 +113,7 @@
   ],
   "husky": {
     "hooks": {
-      "pre-commit": "lint-staged"
+      "pre-commit": "true || lint-staged"
     }
   },
   "lint-staged": {

From e97685e989526a501d5884a9c265891d52bf3a3e Mon Sep 17 00:00:00 2001
From: Nils Knappmeier <github@knappi.org>
Date: Tue, 3 Dec 2019 22:37:15 +0100
Subject: [PATCH 06/24] style: reformat all files using prettier

---
 Gruntfile.js                                  | 146 ++-
 bench/dist-size.js                            |  17 +-
 bench/index.js                                |   2 +-
 bench/precompile-size.js                      |  13 +-
 bench/templates/arguments.js                  |   3 +-
 bench/templates/array-each.js                 |   9 +-
 bench/templates/array-mustache.js             |   9 +-
 bench/templates/complex.js                    |   6 +-
 bench/templates/data.js                       |   9 +-
 bench/templates/depth-1.js                    |  10 +-
 bench/templates/depth-2.js                    |  16 +-
 bench/templates/index.js                      |   2 +-
 bench/templates/partial-recursion.js          |   5 +-
 bench/templates/partial.js                    |  12 +-
 bench/templates/paths.js                      |   8 +-
 bench/templates/variables.js                  |   3 +-
 bench/throughput.js                           |  76 +-
 bench/util/benchwarmer.js                     |  69 +-
 bench/util/template-runner.js                 |   6 +-
 .../multi-nodejs-test/run-handlebars.js       |   2 +-
 .../src/handlebars-inline-precompile-test.js  |  10 +-
 .../webpack-babel-test/src/lib/assert.js      |   6 +-
 .../webpack-babel-test/webpack.config.js      |  48 +-
 .../handlebars-default-import-pre-4.2-test.js |   4 +-
 .../src/handlebars-default-import-test.js     |   5 +-
 .../src/handlebars-loader-test.js             |  10 +-
 .../src/handlebars-require-vs-import-test.js  |   6 +-
 ...handlebars-wildcard-import-pre-4.2-test.js |   4 +-
 .../src/handlebars-wildcard-import-test.js    |   4 +-
 .../webpack-test/src/lib/assert.js            |   6 +-
 .../webpack-test/webpack.config.js            |  26 +-
 lib/handlebars.js                             |   6 +-
 lib/handlebars/base.js                        |  20 +-
 lib/handlebars/compiler/ast.js                |  16 +-
 lib/handlebars/compiler/base.js               |   4 +-
 lib/handlebars/compiler/code-gen.js           |  37 +-
 lib/handlebars/compiler/compiler.js           | 148 ++-
 lib/handlebars/compiler/helpers.js            |  49 +-
 .../compiler/javascript-compiler.js           | 297 ++++--
 lib/handlebars/compiler/printer.js            |  31 +-
 lib/handlebars/compiler/visitor.js            |   9 +-
 lib/handlebars/compiler/whitespace-control.js |  76 +-
 lib/handlebars/decorators.js                  |   1 -
 lib/handlebars/decorators/inline.js           |   2 +-
 lib/handlebars/exception.js                   |  20 +-
 .../helpers/block-helper-missing.js           |  11 +-
 lib/handlebars/helpers/each.js                |  38 +-
 lib/handlebars/helpers/helper-missing.js      |   4 +-
 lib/handlebars/helpers/if.js                  |  18 +-
 lib/handlebars/helpers/log.js                 |   4 +-
 lib/handlebars/helpers/lookup.js              |   5 +-
 lib/handlebars/helpers/with.js                |  21 +-
 lib/handlebars/logger.js                      |  10 +-
 lib/handlebars/no-conflict.js                 |   3 +-
 lib/handlebars/runtime.js                     | 190 +++-
 lib/handlebars/utils.js                       |  27 +-
 lib/precompiler.js                            | 192 ++--
 spec/ast.js                                   | 244 +++--
 spec/basic.js                                 | 581 ++++++++---
 spec/blocks.js                                | 361 +++++--
 spec/builtins.js                              | 481 +++++++--
 spec/compiler.js                              | 147 ++-
 spec/data.js                                  | 189 +++-
 spec/env/browser.js                           |   8 +-
 spec/env/common.js                            |  66 +-
 spec/env/node.js                              |   1 -
 spec/env/runner.js                            |  20 +-
 spec/env/runtime.js                           |  14 +-
 spec/helpers.js                               | 974 +++++++++++++-----
 spec/javascript-compiler.js                   |  14 +-
 spec/parser.js                                | 358 +++++--
 spec/partials.js                              | 666 +++++++++---
 spec/precompiler.js                           | 277 +++--
 spec/regressions.js                           | 329 ++++--
 spec/require.js                               |   4 +-
 spec/runtime.js                               | 118 ++-
 spec/security.js                              | 322 +++---
 spec/source-map.js                            |  24 +-
 spec/spec.js                                  |  40 +-
 spec/strict.js                                | 195 ++--
 spec/string-params.js                         | 150 ++-
 spec/subexpressions.js                        |  96 +-
 spec/tokenizer.js                             | 443 +++++++-
 spec/track-ids.js                             | 316 ++++--
 spec/utils.js                                 |  21 +-
 spec/visitor.js                               |  78 +-
 spec/whitespace-control.js                    |  81 +-
 tasks/metrics.js                              |  15 +-
 tasks/parser.js                               |  16 +-
 tasks/publish.js                              |  47 +-
 tasks/test.js                                 |  48 +-
 tasks/util/git.js                             |  18 +-
 tasks/version.js                              |  78 +-
 93 files changed, 6238 insertions(+), 2393 deletions(-)

diff --git a/Gruntfile.js b/Gruntfile.js
index d91783f5f..9cf025960 100644
--- a/Gruntfile.js
+++ b/Gruntfile.js
@@ -1,32 +1,42 @@
 /* eslint-disable no-process-env */
 module.exports = function(grunt) {
-
   grunt.initConfig({
     pkg: grunt.file.readJSON('package.json'),
 
-    clean: ['tmp', 'dist', 'lib/handlebars/compiler/parser.js', 'integration-testing/**/node_modules'],
+    clean: [
+      'tmp',
+      'dist',
+      'lib/handlebars/compiler/parser.js',
+      'integration-testing/**/node_modules'
+    ],
 
     copy: {
       dist: {
         options: {
           processContent: function(content) {
-            return grunt.template.process('/**!\n\n @license\n <%= pkg.name %> v<%= pkg.version %>\n\n<%= grunt.file.read("LICENSE") %>\n*/\n')
-                + content;
+            return (
+              grunt.template.process(
+                '/**!\n\n @license\n <%= pkg.name %> v<%= pkg.version %>\n\n<%= grunt.file.read("LICENSE") %>\n*/\n'
+              ) + content
+            );
           }
         },
-        files: [
-          {expand: true, cwd: 'dist/', src: ['*.js'], dest: 'dist/'}
-        ]
+        files: [{ expand: true, cwd: 'dist/', src: ['*.js'], dest: 'dist/' }]
       },
       cdnjs: {
         files: [
-          {expand: true, cwd: 'dist/', src: ['*.js'], dest: 'dist/cdnjs'}
+          { expand: true, cwd: 'dist/', src: ['*.js'], dest: 'dist/cdnjs' }
         ]
       },
       components: {
         files: [
-          {expand: true, cwd: 'components/', src: ['**'], dest: 'dist/components'},
-          {expand: true, cwd: 'dist/', src: ['*.js'], dest: 'dist/components'}
+          {
+            expand: true,
+            cwd: 'components/',
+            src: ['**'],
+            dest: 'dist/components'
+          },
+          { expand: true, cwd: 'dist/', src: ['*.js'], dest: 'dist/components' }
         ]
       }
     },
@@ -41,24 +51,28 @@ module.exports = function(grunt) {
         options: {
           modules: 'amd'
         },
-        files: [{
-          expand: true,
-          cwd: 'lib/',
-          src: '**/!(index).js',
-          dest: 'dist/amd/'
-        }]
+        files: [
+          {
+            expand: true,
+            cwd: 'lib/',
+            src: '**/!(index).js',
+            dest: 'dist/amd/'
+          }
+        ]
       },
 
       cjs: {
         options: {
           modules: 'common'
         },
-        files: [{
-          cwd: 'lib/',
-          expand: true,
-          src: '**/!(index).js',
-          dest: 'dist/cjs/'
-        }]
+        files: [
+          {
+            cwd: 'lib/',
+            expand: true,
+            src: '**/!(index).js',
+            dest: 'dist/cjs/'
+          }
+        ]
       }
     },
     webpack: {
@@ -67,7 +81,12 @@ module.exports = function(grunt) {
         module: {
           loaders: [
             // the optional 'runtime' transformer tells babel to require the runtime instead of inlining it.
-            { test: /\.jsx?$/, exclude: /node_modules/, loader: 'babel-loader?optional=runtime&loose=es6.modules&auxiliaryCommentBefore=istanbul%20ignore%20next' }
+            {
+              test: /\.jsx?$/,
+              exclude: /node_modules/,
+              loader:
+                'babel-loader?optional=runtime&loose=es6.modules&auxiliaryCommentBefore=istanbul%20ignore%20next'
+            }
           ]
         },
         output: {
@@ -116,15 +135,17 @@ module.exports = function(grunt) {
         preserveComments: /(?:^!|@(?:license|preserve|cc_on))/
       },
       dist: {
-        files: [{
-          cwd: 'dist/',
-          expand: true,
-          src: ['handlebars*.js', '!*.min.js'],
-          dest: 'dist/',
-          rename: function(dest, src) {
-            return dest + src.replace(/\.js$/, '.min.js');
+        files: [
+          {
+            cwd: 'dist/',
+            expand: true,
+            src: ['handlebars*.js', '!*.min.js'],
+            dest: 'dist/',
+            rename: function(dest, src) {
+              return dest + src.replace(/\.js$/, '.min.js');
+            }
           }
-        }]
+        ]
       }
     },
 
@@ -148,28 +169,41 @@ module.exports = function(grunt) {
       all: {
         options: {
           build: process.env.TRAVIS_JOB_ID,
-          urls: ['http://localhost:9999/spec/?headless=true', 'http://localhost:9999/spec/amd.html?headless=true'],
+          urls: [
+            'http://localhost:9999/spec/?headless=true',
+            'http://localhost:9999/spec/amd.html?headless=true'
+          ],
           detailedError: true,
           concurrency: 4,
           browsers: [
-            {browserName: 'chrome'},
-            {browserName: 'firefox', platform: 'Linux'},
+            { browserName: 'chrome' },
+            { browserName: 'firefox', platform: 'Linux' },
             // {browserName: 'safari', version: 9, platform: 'OS X 10.11'},
             // {browserName: 'safari', version: 8, platform: 'OS X 10.10'},
-            {browserName: 'internet explorer', version: 11, platform: 'Windows 8.1'},
-            {browserName: 'internet explorer', version: 10, platform: 'Windows 8'}
+            {
+              browserName: 'internet explorer',
+              version: 11,
+              platform: 'Windows 8.1'
+            },
+            {
+              browserName: 'internet explorer',
+              version: 10,
+              platform: 'Windows 8'
+            }
           ]
         }
       },
       sanity: {
         options: {
           build: process.env.TRAVIS_JOB_ID,
-          urls: ['http://localhost:9999/spec/umd.html?headless=true', 'http://localhost:9999/spec/amd-runtime.html?headless=true', 'http://localhost:9999/spec/umd-runtime.html?headless=true'],
+          urls: [
+            'http://localhost:9999/spec/umd.html?headless=true',
+            'http://localhost:9999/spec/amd-runtime.html?headless=true',
+            'http://localhost:9999/spec/umd-runtime.html?headless=true'
+          ],
           detailedError: true,
           concurrency: 2,
-          browsers: [
-            {browserName: 'chrome'}
-          ]
+          browsers: [{ browserName: 'chrome' }]
         }
       }
     },
@@ -180,7 +214,6 @@ module.exports = function(grunt) {
         bg: false,
         fail: true
       }
-
     },
 
     watch: {
@@ -211,9 +244,9 @@ module.exports = function(grunt) {
   grunt.task.loadTasks('tasks');
 
   this.registerTask(
-      'build',
-      'Builds a distributable version of the current project',
-      ['parser', 'node', 'globals']
+    'build',
+    'Builds a distributable version of the current project',
+    ['parser', 'node', 'globals']
   );
 
   this.registerTask('node', ['babel:cjs']);
@@ -231,13 +264,30 @@ module.exports = function(grunt) {
   this.registerTask('amd', ['babel:amd', 'requirejs']);
 
   grunt.registerTask('bench', ['metrics']);
-  grunt.registerTask('sauce', process.env.SAUCE_USERNAME ? ['tests', 'connect', 'saucelabs-mocha'] : []);
+  grunt.registerTask(
+    'sauce',
+    process.env.SAUCE_USERNAME ? ['tests', 'connect', 'saucelabs-mocha'] : []
+  );
   // Requires secret properties (saucelabs-credentials etc.) from .travis.yaml
-  grunt.registerTask('extensive-tests-and-publish-to-aws', ['default', 'bgShell:integrationTests', 'sauce', 'metrics', 'publish:latest']);
-  grunt.registerTask('on-file-change', ['build', 'amd', 'concat:tests', 'test']);
+  grunt.registerTask('extensive-tests-and-publish-to-aws', [
+    'default',
+    'bgShell:integrationTests',
+    'sauce',
+    'metrics',
+    'publish:latest'
+  ]);
+  grunt.registerTask('on-file-change', [
+    'build',
+    'amd',
+    'concat:tests',
+    'test'
+  ]);
 
   // === Primary tasks ===
   grunt.registerTask('dev', ['clean', 'connect', 'watch']);
   grunt.registerTask('default', ['clean', 'build', 'test', 'release']);
-  grunt.registerTask('integration-tests', ['default', 'bgShell:integrationTests']);
+  grunt.registerTask('integration-tests', [
+    'default',
+    'bgShell:integrationTests'
+  ]);
 };
diff --git a/bench/dist-size.js b/bench/dist-size.js
index d0bd24892..5bbf7ee33 100644
--- a/bench/dist-size.js
+++ b/bench/dist-size.js
@@ -1,12 +1,14 @@
 var async = require('neo-async'),
-    fs = require('fs'),
-    zlib = require('zlib');
+  fs = require('fs'),
+  zlib = require('zlib');
 
 module.exports = function(grunt, callback) {
   var distFiles = fs.readdirSync('dist'),
-      distSizes = {};
+    distSizes = {};
 
-  async.each(distFiles, function(file, callback) {
+  async.each(
+    distFiles,
+    function(file, callback) {
       var content;
       try {
         content = fs.readFileSync('dist/' + file);
@@ -32,7 +34,10 @@ module.exports = function(grunt, callback) {
       });
     },
     function() {
-      grunt.log.writeln('Distribution sizes: ' + JSON.stringify(distSizes, undefined, 2));
+      grunt.log.writeln(
+        'Distribution sizes: ' + JSON.stringify(distSizes, undefined, 2)
+      );
       callback([distSizes]);
-    });
+    }
+  );
 };
diff --git a/bench/index.js b/bench/index.js
index 3e357e54a..462b046f5 100644
--- a/bench/index.js
+++ b/bench/index.js
@@ -2,7 +2,7 @@ var fs = require('fs');
 
 var metrics = fs.readdirSync(__dirname);
 metrics.forEach(function(metric) {
-  if (metric === 'index.js' || !(/(.*)\.js$/.test(metric))) {
+  if (metric === 'index.js' || !/(.*)\.js$/.test(metric)) {
     return;
   }
 
diff --git a/bench/precompile-size.js b/bench/precompile-size.js
index 66eacd025..5aca9423c 100644
--- a/bench/precompile-size.js
+++ b/bench/precompile-size.js
@@ -1,5 +1,5 @@
 var _ = require('underscore'),
-    templates = require('./templates');
+  templates = require('./templates');
 
 module.exports = function(grunt, callback) {
   // Deferring to here in case we have a build for parser, etc as part of this grunt exec
@@ -8,12 +8,17 @@ module.exports = function(grunt, callback) {
   var templateSizes = {};
   _.each(templates, function(info, template) {
     var src = info.handlebars,
-        compiled = Handlebars.precompile(src, {}),
-        knownHelpers = Handlebars.precompile(src, {knownHelpersOnly: true, knownHelpers: info.helpers});
+      compiled = Handlebars.precompile(src, {}),
+      knownHelpers = Handlebars.precompile(src, {
+        knownHelpersOnly: true,
+        knownHelpers: info.helpers
+      });
 
     templateSizes[template] = compiled.length;
     templateSizes['knownOnly_' + template] = knownHelpers.length;
   });
-  grunt.log.writeln('Precompiled sizes: ' + JSON.stringify(templateSizes, undefined, 2));
+  grunt.log.writeln(
+    'Precompiled sizes: ' + JSON.stringify(templateSizes, undefined, 2)
+  );
   callback([templateSizes]);
 };
diff --git a/bench/templates/arguments.js b/bench/templates/arguments.js
index aaa034686..f73d845f8 100644
--- a/bench/templates/arguments.js
+++ b/bench/templates/arguments.js
@@ -8,5 +8,6 @@ module.exports = {
     bar: true
   },
 
-  handlebars: '{{foo person "person" 1 true foo=bar foo="person" foo=1 foo=true}}'
+  handlebars:
+    '{{foo person "person" 1 true foo=bar foo="person" foo=1 foo=true}}'
 };
diff --git a/bench/templates/array-each.js b/bench/templates/array-each.js
index 50e1c02b8..ddf07a6fe 100644
--- a/bench/templates/array-each.js
+++ b/bench/templates/array-each.js
@@ -1,5 +1,12 @@
 module.exports = {
-  context: { names: [{name: 'Moe'}, {name: 'Larry'}, {name: 'Curly'}, {name: 'Shemp'}] },
+  context: {
+    names: [
+      { name: 'Moe' },
+      { name: 'Larry' },
+      { name: 'Curly' },
+      { name: 'Shemp' }
+    ]
+  },
   handlebars: '{{#each names}}{{name}}{{/each}}',
   dust: '{#names}{name}{/names}',
   mustache: '{{#names}}{{name}}{{/names}}',
diff --git a/bench/templates/array-mustache.js b/bench/templates/array-mustache.js
index 220c6fe47..e7b2355ac 100644
--- a/bench/templates/array-mustache.js
+++ b/bench/templates/array-mustache.js
@@ -1,4 +1,11 @@
 module.exports = {
-  context: { names: [{name: 'Moe'}, {name: 'Larry'}, {name: 'Curly'}, {name: 'Shemp'}] },
+  context: {
+    names: [
+      { name: 'Moe' },
+      { name: 'Larry' },
+      { name: 'Curly' },
+      { name: 'Shemp' }
+    ]
+  },
   handlebars: '{{#names}}{{name}}{{/names}}'
 };
diff --git a/bench/templates/complex.js b/bench/templates/complex.js
index 3e5e26c4e..545a479cb 100644
--- a/bench/templates/complex.js
+++ b/bench/templates/complex.js
@@ -7,9 +7,9 @@ module.exports = {
     },
     hasItems: true, // To make things fairer in mustache land due to no `{{if}}` construct on arrays
     items: [
-      {name: 'red', current: true, url: '#Red'},
-      {name: 'green', current: false, url: '#Green'},
-      {name: 'blue', current: false, url: '#Blue'}
+      { name: 'red', current: true, url: '#Red' },
+      { name: 'green', current: false, url: '#Green' },
+      { name: 'blue', current: false, url: '#Blue' }
     ]
   },
 
diff --git a/bench/templates/data.js b/bench/templates/data.js
index be10e8399..4cb969d66 100644
--- a/bench/templates/data.js
+++ b/bench/templates/data.js
@@ -1,4 +1,11 @@
 module.exports = {
-  context: { names: [{name: 'Moe'}, {name: 'Larry'}, {name: 'Curly'}, {name: 'Shemp'}] },
+  context: {
+    names: [
+      { name: 'Moe' },
+      { name: 'Larry' },
+      { name: 'Curly' },
+      { name: 'Shemp' }
+    ]
+  },
   handlebars: '{{#each names}}{{@index}}{{name}}{{/each}}'
 };
diff --git a/bench/templates/depth-1.js b/bench/templates/depth-1.js
index 0f2576f43..65cb33b71 100644
--- a/bench/templates/depth-1.js
+++ b/bench/templates/depth-1.js
@@ -1,5 +1,13 @@
 module.exports = {
-  context: { names: [{name: 'Moe'}, {name: 'Larry'}, {name: 'Curly'}, {name: 'Shemp'}], foo: 'bar' },
+  context: {
+    names: [
+      { name: 'Moe' },
+      { name: 'Larry' },
+      { name: 'Curly' },
+      { name: 'Shemp' }
+    ],
+    foo: 'bar'
+  },
   handlebars: '{{#each names}}{{../foo}}{{/each}}',
   mustache: '{{#names}}{{foo}}{{/names}}',
   eco: '<% for item in @names: %><%= @foo %><% end %>'
diff --git a/bench/templates/depth-2.js b/bench/templates/depth-2.js
index bff6ce850..bef804d1e 100644
--- a/bench/templates/depth-2.js
+++ b/bench/templates/depth-2.js
@@ -1,6 +1,16 @@
 module.exports = {
-  context: { names: [{bat: 'foo', name: ['Moe']}, {bat: 'foo', name: ['Larry']}, {bat: 'foo', name: ['Curly']}, {bat: 'foo', name: ['Shemp']}], foo: 'bar' },
-  handlebars: '{{#each names}}{{#each name}}{{../bat}}{{../../foo}}{{/each}}{{/each}}',
+  context: {
+    names: [
+      { bat: 'foo', name: ['Moe'] },
+      { bat: 'foo', name: ['Larry'] },
+      { bat: 'foo', name: ['Curly'] },
+      { bat: 'foo', name: ['Shemp'] }
+    ],
+    foo: 'bar'
+  },
+  handlebars:
+    '{{#each names}}{{#each name}}{{../bat}}{{../../foo}}{{/each}}{{/each}}',
   mustache: '{{#names}}{{#name}}{{bat}}{{foo}}{{/name}}{{/names}}',
-  eco: '<% for item in @names: %><% for child in item.name: %><%= item.bat %><%= @foo %><% end %><% end %>'
+  eco:
+    '<% for item in @names: %><% for child in item.name: %><%= item.bat %><%= @foo %><% end %><% end %>'
 };
diff --git a/bench/templates/index.js b/bench/templates/index.js
index 943f9cdfe..a718ea388 100644
--- a/bench/templates/index.js
+++ b/bench/templates/index.js
@@ -2,7 +2,7 @@ var fs = require('fs');
 
 var templates = fs.readdirSync(__dirname);
 templates.forEach(function(template) {
-  if (template === 'index.js' || !(/(.*)\.js$/.test(template))) {
+  if (template === 'index.js' || !/(.*)\.js$/.test(template)) {
     return;
   }
   module.exports[RegExp.$1] = require('./' + RegExp.$1);
diff --git a/bench/templates/partial-recursion.js b/bench/templates/partial-recursion.js
index b903553b5..ce3c32a74 100644
--- a/bench/templates/partial-recursion.js
+++ b/bench/templates/partial-recursion.js
@@ -1,5 +1,8 @@
 module.exports = {
-  context: { name: '1', kids: [{ name: '1.1', kids: [{name: '1.1.1', kids: []}] }] },
+  context: {
+    name: '1',
+    kids: [{ name: '1.1', kids: [{ name: '1.1.1', kids: [] }] }]
+  },
   partials: {
     mustache: { recursion: '{{name}}{{#kids}}{{>recursion}}{{/kids}}' },
     handlebars: { recursion: '{{name}}{{#each kids}}{{>recursion}}{{/each}}' }
diff --git a/bench/templates/partial.js b/bench/templates/partial.js
index 949e9c075..79a9d7dfa 100644
--- a/bench/templates/partial.js
+++ b/bench/templates/partial.js
@@ -1,8 +1,16 @@
 module.exports = {
-  context: { peeps: [{name: 'Moe', count: 15}, {name: 'Larry', count: 5}, {name: 'Curly', count: 1}] },
+  context: {
+    peeps: [
+      { name: 'Moe', count: 15 },
+      { name: 'Larry', count: 5 },
+      { name: 'Curly', count: 1 }
+    ]
+  },
   partials: {
     mustache: { variables: 'Hello {{name}}! You have {{count}} new messages.' },
-    handlebars: { variables: 'Hello {{name}}! You have {{count}} new messages.' }
+    handlebars: {
+      variables: 'Hello {{name}}! You have {{count}} new messages.'
+    }
   },
 
   handlebars: '{{#each peeps}}{{>variables}}{{/each}}',
diff --git a/bench/templates/paths.js b/bench/templates/paths.js
index fed039d51..3725e471c 100644
--- a/bench/templates/paths.js
+++ b/bench/templates/paths.js
@@ -1,7 +1,9 @@
 module.exports = {
-  context: { person: { name: {bar: {baz: 'Larry'}}, age: 45 } },
-  handlebars: '{{person.name.bar.baz}}{{person.age}}{{person.foo}}{{animal.age}}',
+  context: { person: { name: { bar: { baz: 'Larry' } }, age: 45 } },
+  handlebars:
+    '{{person.name.bar.baz}}{{person.age}}{{person.foo}}{{animal.age}}',
   dust: '{person.name.bar.baz}{person.age}{person.foo}{animal.age}',
-  eco: '<%= @person.name.bar.baz %><%= @person.age %><%= @person.foo %><% if @animal: %><%= @animal.age %><% end %>',
+  eco:
+    '<%= @person.name.bar.baz %><%= @person.age %><%= @person.foo %><% if @animal: %><%= @animal.age %><% end %>',
   mustache: '{{person.name.bar.baz}}{{person.age}}{{person.foo}}{{animal.age}}'
 };
diff --git a/bench/templates/variables.js b/bench/templates/variables.js
index 41e4feafe..fddece1bc 100644
--- a/bench/templates/variables.js
+++ b/bench/templates/variables.js
@@ -1,8 +1,7 @@
 module.exports = {
-  context: {name: 'Mick', count: 30},
+  context: { name: 'Mick', count: 30 },
   handlebars: 'Hello {{name}}! You have {{count}} new messages.',
   dust: 'Hello {name}! You have {count} new messages.',
   mustache: 'Hello {{name}}! You have {{count}} new messages.',
   eco: 'Hello <%= @name %>! You have <%= @count %> new messages.'
 };
-
diff --git a/bench/throughput.js b/bench/throughput.js
index e8ea5d910..b5e3a56a5 100644
--- a/bench/throughput.js
+++ b/bench/throughput.js
@@ -1,19 +1,27 @@
 var _ = require('underscore'),
-    runner = require('./util/template-runner'),
-
-    eco, dust, Handlebars, Mustache;
+  runner = require('./util/template-runner'),
+  eco,
+  dust,
+  Handlebars,
+  Mustache;
 
 try {
   dust = require('dustjs-linkedin');
-} catch (err) { /* NOP */ }
+} catch (err) {
+  /* NOP */
+}
 
 try {
   Mustache = require('mustache');
-} catch (err) { /* NOP */ }
+} catch (err) {
+  /* NOP */
+}
 
 try {
   eco = require('eco');
-} catch (err) { /* NOP */ }
+} catch (err) {
+  /* NOP */
+}
 
 function error() {
   throw new Error('EWOT');
@@ -22,21 +30,28 @@ function error() {
 function makeSuite(bench, name, template, handlebarsOnly) {
   // Create aliases to minimize any impact from having to walk up the closure tree.
   var templateName = name,
-
-      context = template.context,
-      partials = template.partials,
-
-      handlebarsOut,
-      compatOut,
-      dustOut,
-      ecoOut,
-      mustacheOut;
-
-  var handlebar = Handlebars.compile(template.handlebars, {data: false}),
-      compat = Handlebars.compile(template.handlebars, {data: false, compat: true}),
-      options = {helpers: template.helpers};
-  _.each(template.partials && template.partials.handlebars, function(partial, partialName) {
-    Handlebars.registerPartial(partialName, Handlebars.compile(partial, {data: false}));
+    context = template.context,
+    partials = template.partials,
+    handlebarsOut,
+    compatOut,
+    dustOut,
+    ecoOut,
+    mustacheOut;
+
+  var handlebar = Handlebars.compile(template.handlebars, { data: false }),
+    compat = Handlebars.compile(template.handlebars, {
+      data: false,
+      compat: true
+    }),
+    options = { helpers: template.helpers };
+  _.each(template.partials && template.partials.handlebars, function(
+    partial,
+    partialName
+  ) {
+    Handlebars.registerPartial(
+      partialName,
+      Handlebars.compile(partial, { data: false })
+    );
   });
 
   handlebarsOut = handlebar(context, options);
@@ -58,7 +73,9 @@ function makeSuite(bench, name, template, handlebarsOnly) {
       dustOut = false;
       dust.loadSource(dust.compile(template.dust, templateName));
 
-      dust.render(templateName, context, function(err, out) { dustOut = out; });
+      dust.render(templateName, context, function(err, out) {
+        dustOut = out;
+      });
 
       bench('dust', function() {
         dust.render(templateName, context, function() {});
@@ -84,7 +101,7 @@ function makeSuite(bench, name, template, handlebarsOnly) {
 
   if (Mustache) {
     var mustacheSource = template.mustache,
-        mustachePartials = partials && partials.mustache;
+      mustachePartials = partials && partials.mustache;
 
     if (mustacheSource) {
       mustacheOut = Mustache.to_html(mustacheSource, context, mustachePartials);
@@ -107,9 +124,16 @@ function makeSuite(bench, name, template, handlebarsOnly) {
     b = b.replace(/\s/g, '');
 
     if (handlebarsOut !== b) {
-      throw new Error('Template output mismatch: ' + name
-            + '\n\nHandlebars: ' + handlebarsOut
-            + '\n\n' + lang + ': ' + b);
+      throw new Error(
+        'Template output mismatch: ' +
+          name +
+          '\n\nHandlebars: ' +
+          handlebarsOut +
+          '\n\n' +
+          lang +
+          ': ' +
+          b
+      );
     }
   }
 
diff --git a/bench/util/benchwarmer.js b/bench/util/benchwarmer.js
index 58f138a0e..90415bf56 100644
--- a/bench/util/benchwarmer.js
+++ b/bench/util/benchwarmer.js
@@ -1,5 +1,5 @@
 var _ = require('underscore'),
-    Benchmark = require('benchmark');
+  Benchmark = require('benchmark');
 
 function BenchWarmer() {
   this.benchmarks = [];
@@ -33,16 +33,21 @@ BenchWarmer.prototype = {
       this.names.push(name);
     }
 
-    var first = this.first, suiteName = this.suiteName, self = this;
+    var first = this.first,
+      suiteName = this.suiteName,
+      self = this;
     this.first = false;
 
     var bench = new Benchmark(fn, {
       name: this.suiteName + ': ' + name,
       onComplete: function() {
-        if (first) { self.startLine(suiteName); }
+        if (first) {
+          self.startLine(suiteName);
+        }
         self.writeBench(bench);
         self.currentBenches.push(bench);
-      }, onError: function() {
+      },
+      onError: function() {
         self.errors[this.name] = this;
       }
     });
@@ -75,10 +80,14 @@ BenchWarmer.prototype = {
         });
         print('\n');
 
-        var errors = false, prop, bench;
+        var errors = false,
+          prop,
+          bench;
         for (prop in self.errors) {
-          if (Object.prototype.hasOwnProperty.call(self, prop)
-              && self.errors[prop].error.message !== 'EWOT') {
+          if (
+            Object.prototype.hasOwnProperty.call(self, prop) &&
+            self.errors[prop].error.message !== 'EWOT'
+          ) {
             errors = true;
             break;
           }
@@ -107,23 +116,39 @@ BenchWarmer.prototype = {
   },
 
   scaleTimes: function() {
-    var scaled = this.scaled = {};
-    _.each(this.times, function(times, name) {
-      var output = scaled[name] = {};
-
-      _.each(times, function(time, lang) {
-        output[lang] = ((time - this.minimum) / (this.maximum - this.minimum) * 100).toFixed(2);
-      }, this);
-    }, this);
+    var scaled = (this.scaled = {});
+    _.each(
+      this.times,
+      function(times, name) {
+        var output = (scaled[name] = {});
+
+        _.each(
+          times,
+          function(time, lang) {
+            output[lang] = (
+              ((time - this.minimum) / (this.maximum - this.minimum)) *
+              100
+            ).toFixed(2);
+          },
+          this
+        );
+      },
+      this
+    );
   },
 
   printHeader: function(title, winners) {
-    var benchSize = 0, names = this.names, i, l;
+    var benchSize = 0,
+      names = this.names,
+      i,
+      l;
 
     for (i = 0, l = names.length; i < l; i++) {
       var name = names[i];
 
-      if (benchSize < name.length) { benchSize = name.length; }
+      if (benchSize < name.length) {
+        benchSize = name.length;
+      }
     }
 
     this.nameSize = benchSize + 2;
@@ -146,7 +171,9 @@ BenchWarmer.prototype = {
   },
 
   startLine: function(name) {
-    var winners = Benchmark.map(this.winners(this.currentBenches), function(bench) {
+    var winners = Benchmark.map(this.winners(this.currentBenches), function(
+      bench
+    ) {
       return bench.name.split(': ')[1];
     });
 
@@ -164,9 +191,9 @@ BenchWarmer.prototype = {
 
     if (!bench.error) {
       var count = bench.hz,
-          moe = count * bench.stats.rme / 100,
-          minimum,
-          maximum;
+        moe = (count * bench.stats.rme) / 100,
+        minimum,
+        maximum;
 
       count = Math.round(count / 1000);
       moe = Math.round(moe / 1000);
diff --git a/bench/util/template-runner.js b/bench/util/template-runner.js
index b492ff3af..370e157ec 100644
--- a/bench/util/template-runner.js
+++ b/bench/util/template-runner.js
@@ -1,12 +1,12 @@
 var _ = require('underscore'),
-    BenchWarmer = require('./benchwarmer'),
-    templates = require('../templates');
+  BenchWarmer = require('./benchwarmer'),
+  templates = require('../templates');
 
 module.exports = function(grunt, makeSuite, callback) {
   var warmer = new BenchWarmer();
 
   var handlebarsOnly = grunt.option('handlebars-only'),
-      grep = grunt.option('grep');
+    grep = grunt.option('grep');
   if (grep) {
     grep = new RegExp(grep);
   }
diff --git a/integration-testing/multi-nodejs-test/run-handlebars.js b/integration-testing/multi-nodejs-test/run-handlebars.js
index 9aded26cf..6b0cbdca6 100755
--- a/integration-testing/multi-nodejs-test/run-handlebars.js
+++ b/integration-testing/multi-nodejs-test/run-handlebars.js
@@ -5,7 +5,7 @@ var Handlebars = require('handlebars');
 console.log('Testing built Handlebars with Node version ' + process.version);
 
 var template = Handlebars.compile('Author: {{author}}');
-var output = template({author: 'Yehuda'});
+var output = template({ author: 'Yehuda' });
 assert.strictEqual(output, 'Author: Yehuda');
 
 console.log('Success');
diff --git a/integration-testing/webpack-babel-test/src/handlebars-inline-precompile-test.js b/integration-testing/webpack-babel-test/src/handlebars-inline-precompile-test.js
index 7f764e328..2d54945c8 100644
--- a/integration-testing/webpack-babel-test/src/handlebars-inline-precompile-test.js
+++ b/integration-testing/webpack-babel-test/src/handlebars-inline-precompile-test.js
@@ -1,12 +1,12 @@
-import * as Handlebars from 'handlebars/runtime'
+import * as Handlebars from 'handlebars/runtime';
 import hbs from 'handlebars-inline-precompile';
-import {assertEquals} from "../../webpack-test/src/lib/assert";
+import { assertEquals } from '../../webpack-test/src/lib/assert';
 
 Handlebars.registerHelper('loud', function(text) {
-    return text.toUpperCase();
+  return text.toUpperCase();
 });
 
 const template = hbs`{{loud name}}`;
-const output = template({name: 'yehuda'})
+const output = template({ name: 'yehuda' });
 
-assertEquals(output, 'YEHUDA')
\ No newline at end of file
+assertEquals(output, 'YEHUDA');
diff --git a/integration-testing/webpack-babel-test/src/lib/assert.js b/integration-testing/webpack-babel-test/src/lib/assert.js
index 9f33188db..00095006a 100644
--- a/integration-testing/webpack-babel-test/src/lib/assert.js
+++ b/integration-testing/webpack-babel-test/src/lib/assert.js
@@ -1,5 +1,5 @@
 export function assertEquals(actual, expected) {
-    if (actual !== expected) {
-        throw new Error(`Expected "${actual}" to equal "${expected}"`);
-    }
+  if (actual !== expected) {
+    throw new Error(`Expected "${actual}" to equal "${expected}"`);
+  }
 }
diff --git a/integration-testing/webpack-babel-test/webpack.config.js b/integration-testing/webpack-babel-test/webpack.config.js
index 9ad0a09b2..bebb6ee0e 100644
--- a/integration-testing/webpack-babel-test/webpack.config.js
+++ b/integration-testing/webpack-babel-test/webpack.config.js
@@ -3,30 +3,30 @@ const fs = require('fs');
 const testFiles = fs.readdirSync('src');
 const entryPoints = {};
 testFiles
-    .filter(file => file.match(/-test.js$/))
-    .forEach(file => {
-        entryPoints[file] = `./src/${file}`;
-    });
+  .filter(file => file.match(/-test.js$/))
+  .forEach(file => {
+    entryPoints[file] = `./src/${file}`;
+  });
 
 module.exports = {
-    entry: entryPoints,
-    output: {
-        filename: '[name]',
-        path: __dirname + '/dist'
-    },
-    module: {
-        rules: [
-            {
-                test: /\.js?$/,
-                exclude: /node_modules/,
-                use: {
-                    loader: 'babel-loader',
-                    options: { cacheDirectory: false },
-                }
-            }
-        ]
-    },
-    optimization: {
-        minimize: false
-    }
+  entry: entryPoints,
+  output: {
+    filename: '[name]',
+    path: __dirname + '/dist'
+  },
+  module: {
+    rules: [
+      {
+        test: /\.js?$/,
+        exclude: /node_modules/,
+        use: {
+          loader: 'babel-loader',
+          options: { cacheDirectory: false }
+        }
+      }
+    ]
+  },
+  optimization: {
+    minimize: false
+  }
 };
diff --git a/integration-testing/webpack-test/src/handlebars-default-import-pre-4.2-test.js b/integration-testing/webpack-test/src/handlebars-default-import-pre-4.2-test.js
index 6bc630da3..b7ffe7119 100644
--- a/integration-testing/webpack-test/src/handlebars-default-import-pre-4.2-test.js
+++ b/integration-testing/webpack-test/src/handlebars-default-import-pre-4.2-test.js
@@ -1,6 +1,6 @@
 import Handlebars from 'handlebars/dist/handlebars';
 
-import {assertEquals} from './lib/assert';
+import { assertEquals } from './lib/assert';
 
 const template = Handlebars.compile('Author: {{author}}');
-assertEquals(template({author: 'Yehuda'}), 'Author: Yehuda');
+assertEquals(template({ author: 'Yehuda' }), 'Author: Yehuda');
diff --git a/integration-testing/webpack-test/src/handlebars-default-import-test.js b/integration-testing/webpack-test/src/handlebars-default-import-test.js
index 97fc3f8b7..d8730b6c7 100644
--- a/integration-testing/webpack-test/src/handlebars-default-import-test.js
+++ b/integration-testing/webpack-test/src/handlebars-default-import-test.js
@@ -1,6 +1,5 @@
 import Handlebars from 'handlebars';
-import {assertEquals} from './lib/assert';
-
+import { assertEquals } from './lib/assert';
 
 const template = Handlebars.compile('Author: {{author}}');
-assertEquals(template({author: 'Yehuda'}), 'Author: Yehuda');
+assertEquals(template({ author: 'Yehuda' }), 'Author: Yehuda');
diff --git a/integration-testing/webpack-test/src/handlebars-loader-test.js b/integration-testing/webpack-test/src/handlebars-loader-test.js
index 4727c7a3a..c6fc8d8d9 100644
--- a/integration-testing/webpack-test/src/handlebars-loader-test.js
+++ b/integration-testing/webpack-test/src/handlebars-loader-test.js
@@ -1,8 +1,10 @@
-import {assertEquals} from './lib/assert';
+import { assertEquals } from './lib/assert';
 
 import testTemplate from './test-template.handlebars';
-assertEquals(testTemplate({author: 'Yehuda'}).trim(), 'Author: Yehuda');
-
+assertEquals(testTemplate({ author: 'Yehuda' }).trim(), 'Author: Yehuda');
 
 const testTemplateRequire = require('./test-template.handlebars');
-assertEquals(testTemplateRequire({author: 'Yehuda'}).trim(), 'Author: Yehuda');
+assertEquals(
+  testTemplateRequire({ author: 'Yehuda' }).trim(),
+  'Author: Yehuda'
+);
diff --git a/integration-testing/webpack-test/src/handlebars-require-vs-import-test.js b/integration-testing/webpack-test/src/handlebars-require-vs-import-test.js
index 13e2c97d7..9c49f0cbd 100644
--- a/integration-testing/webpack-test/src/handlebars-require-vs-import-test.js
+++ b/integration-testing/webpack-test/src/handlebars-require-vs-import-test.js
@@ -1,10 +1,10 @@
 import * as HandlebarsViaImport from 'handlebars';
 const HandlebarsViaRequire = require('handlebars');
-import {assertEquals} from './lib/assert';
+import { assertEquals } from './lib/assert';
 
 HandlebarsViaImport.registerHelper('loud', function(text) {
-    return text.toUpperCase();
+  return text.toUpperCase();
 });
 
 const template = HandlebarsViaRequire.compile('Author: {{loud author}}');
-assertEquals(template({author: 'Yehuda'}), 'Author: YEHUDA');
+assertEquals(template({ author: 'Yehuda' }), 'Author: YEHUDA');
diff --git a/integration-testing/webpack-test/src/handlebars-wildcard-import-pre-4.2-test.js b/integration-testing/webpack-test/src/handlebars-wildcard-import-pre-4.2-test.js
index 3731c5ac8..2e4a1ff4d 100644
--- a/integration-testing/webpack-test/src/handlebars-wildcard-import-pre-4.2-test.js
+++ b/integration-testing/webpack-test/src/handlebars-wildcard-import-pre-4.2-test.js
@@ -1,6 +1,6 @@
 import * as Handlebars from 'handlebars/dist/handlebars';
 
-import {assertEquals} from './lib/assert';
+import { assertEquals } from './lib/assert';
 
 const template = Handlebars.compile('Author: {{author}}');
-assertEquals(template({author: 'Yehuda'}), 'Author: Yehuda');
+assertEquals(template({ author: 'Yehuda' }), 'Author: Yehuda');
diff --git a/integration-testing/webpack-test/src/handlebars-wildcard-import-test.js b/integration-testing/webpack-test/src/handlebars-wildcard-import-test.js
index 2ea0c1b49..bbf3bb81a 100644
--- a/integration-testing/webpack-test/src/handlebars-wildcard-import-test.js
+++ b/integration-testing/webpack-test/src/handlebars-wildcard-import-test.js
@@ -1,5 +1,5 @@
 import * as Handlebars from 'handlebars';
-import {assertEquals} from './lib/assert';
+import { assertEquals } from './lib/assert';
 
 const template = Handlebars.compile('Author: {{author}}');
-assertEquals(template({author: 'Yehuda'}), 'Author: Yehuda');
+assertEquals(template({ author: 'Yehuda' }), 'Author: Yehuda');
diff --git a/integration-testing/webpack-test/src/lib/assert.js b/integration-testing/webpack-test/src/lib/assert.js
index 9f33188db..00095006a 100644
--- a/integration-testing/webpack-test/src/lib/assert.js
+++ b/integration-testing/webpack-test/src/lib/assert.js
@@ -1,5 +1,5 @@
 export function assertEquals(actual, expected) {
-    if (actual !== expected) {
-        throw new Error(`Expected "${actual}" to equal "${expected}"`);
-    }
+  if (actual !== expected) {
+    throw new Error(`Expected "${actual}" to equal "${expected}"`);
+  }
 }
diff --git a/integration-testing/webpack-test/webpack.config.js b/integration-testing/webpack-test/webpack.config.js
index 957321223..207aed30c 100644
--- a/integration-testing/webpack-test/webpack.config.js
+++ b/integration-testing/webpack-test/webpack.config.js
@@ -3,20 +3,18 @@ const fs = require('fs');
 const testFiles = fs.readdirSync('src');
 const entryPoints = {};
 testFiles
-    .filter(file => file.match(/-test.js$/))
-    .forEach(file => {
-        entryPoints[file] = `./src/${file}`;
-    });
+  .filter(file => file.match(/-test.js$/))
+  .forEach(file => {
+    entryPoints[file] = `./src/${file}`;
+  });
 
 module.exports = {
-    entry: entryPoints,
-    output: {
-        filename: '[name]',
-        path: __dirname + '/dist'
-    },
-    module: {
-        rules: [
-            {test: /\.handlebars$/, loader: 'handlebars-loader'}
-        ]
-    }
+  entry: entryPoints,
+  output: {
+    filename: '[name]',
+    path: __dirname + '/dist'
+  },
+  module: {
+    rules: [{ test: /\.handlebars$/, loader: 'handlebars-loader' }]
+  }
 };
diff --git a/lib/handlebars.js b/lib/handlebars.js
index 69bcb410b..c4f8fc781 100644
--- a/lib/handlebars.js
+++ b/lib/handlebars.js
@@ -2,7 +2,11 @@ import runtime from './handlebars.runtime';
 
 // Compiler imports
 import AST from './handlebars/compiler/ast';
-import { parser as Parser, parse, parseWithoutProcessing } from './handlebars/compiler/base';
+import {
+  parser as Parser,
+  parse,
+  parseWithoutProcessing
+} from './handlebars/compiler/base';
 import { Compiler, compile, precompile } from './handlebars/compiler/compiler';
 import JavaScriptCompiler from './handlebars/compiler/javascript-compiler';
 import Visitor from './handlebars/compiler/visitor';
diff --git a/lib/handlebars/base.js b/lib/handlebars/base.js
index ad3541b53..c655e8f09 100644
--- a/lib/handlebars/base.js
+++ b/lib/handlebars/base.js
@@ -1,7 +1,7 @@
-import {createFrame, extend, toString} from './utils';
+import { createFrame, extend, toString } from './utils';
 import Exception from './exception';
-import {registerDefaultHelpers} from './helpers';
-import {registerDefaultDecorators} from './decorators';
+import { registerDefaultHelpers } from './helpers';
+import { registerDefaultDecorators } from './decorators';
 import logger from './logger';
 
 export const VERSION = '4.5.3';
@@ -38,7 +38,9 @@ HandlebarsEnvironment.prototype = {
 
   registerHelper: function(name, fn) {
     if (toString.call(name) === objectType) {
-      if (fn) { throw new Exception('Arg not supported with multiple helpers'); }
+      if (fn) {
+        throw new Exception('Arg not supported with multiple helpers');
+      }
       extend(this.helpers, name);
     } else {
       this.helpers[name] = fn;
@@ -53,7 +55,9 @@ HandlebarsEnvironment.prototype = {
       extend(this.partials, name);
     } else {
       if (typeof partial === 'undefined') {
-        throw new Exception(`Attempting to register a partial called "${name}" as undefined`);
+        throw new Exception(
+          `Attempting to register a partial called "${name}" as undefined`
+        );
       }
       this.partials[name] = partial;
     }
@@ -64,7 +68,9 @@ HandlebarsEnvironment.prototype = {
 
   registerDecorator: function(name, fn) {
     if (toString.call(name) === objectType) {
-      if (fn) { throw new Exception('Arg not supported with multiple decorators'); }
+      if (fn) {
+        throw new Exception('Arg not supported with multiple decorators');
+      }
       extend(this.decorators, name);
     } else {
       this.decorators[name] = fn;
@@ -77,4 +83,4 @@ HandlebarsEnvironment.prototype = {
 
 export let log = logger.log;
 
-export {createFrame, logger};
+export { createFrame, logger };
diff --git a/lib/handlebars/compiler/ast.js b/lib/handlebars/compiler/ast.js
index 1699569ba..d77629a52 100644
--- a/lib/handlebars/compiler/ast.js
+++ b/lib/handlebars/compiler/ast.js
@@ -5,24 +5,28 @@ let AST = {
     // * it is an eligible helper, and
     // * it has at least one parameter or hash segment
     helperExpression: function(node) {
-      return (node.type === 'SubExpression')
-          || ((node.type === 'MustacheStatement' || node.type === 'BlockStatement')
-            && !!((node.params && node.params.length) || node.hash));
+      return (
+        node.type === 'SubExpression' ||
+        ((node.type === 'MustacheStatement' ||
+          node.type === 'BlockStatement') &&
+          !!((node.params && node.params.length) || node.hash))
+      );
     },
 
     scopedId: function(path) {
-      return (/^\.|this\b/).test(path.original);
+      return /^\.|this\b/.test(path.original);
     },
 
     // an ID is simple if it only has one part, and that part is not
     // `..` or `this`.
     simpleId: function(path) {
-      return path.parts.length === 1 && !AST.helpers.scopedId(path) && !path.depth;
+      return (
+        path.parts.length === 1 && !AST.helpers.scopedId(path) && !path.depth
+      );
     }
   }
 };
 
-
 // Must be exported as an object rather than the root of the module as the jison lexer
 // must modify the object to operate properly.
 export default AST;
diff --git a/lib/handlebars/compiler/base.js b/lib/handlebars/compiler/base.js
index 19989ca5e..1dd5af1a4 100644
--- a/lib/handlebars/compiler/base.js
+++ b/lib/handlebars/compiler/base.js
@@ -10,7 +10,9 @@ extend(yy, Helpers);
 
 export function parseWithoutProcessing(input, options) {
   // Just return if an already-compiled AST was passed in.
-  if (input.type === 'Program') { return input; }
+  if (input.type === 'Program') {
+    return input;
+  }
 
   parser.yy = yy;
 
diff --git a/lib/handlebars/compiler/code-gen.js b/lib/handlebars/compiler/code-gen.js
index 30c5af740..4a174ba08 100644
--- a/lib/handlebars/compiler/code-gen.js
+++ b/lib/handlebars/compiler/code-gen.js
@@ -1,5 +1,5 @@
 /* global define */
-import {isArray} from '../utils';
+import { isArray } from '../utils';
 
 let SourceNode;
 
@@ -38,7 +38,7 @@ if (!SourceNode) {
       this.src = chunks + this.src;
     },
     toStringWithSourceMap: function() {
-      return {code: this.toString()};
+      return { code: this.toString() };
     },
     toString: function() {
       return this.src;
@@ -46,7 +46,6 @@ if (!SourceNode) {
   };
 }
 
-
 function castChunk(chunk, codeGen, loc) {
   if (isArray(chunk)) {
     let ret = [];
@@ -62,7 +61,6 @@ function castChunk(chunk, codeGen, loc) {
   return chunk;
 }
 
-
 function CodeGen(srcFile) {
   this.srcFile = srcFile;
   this.source = [];
@@ -94,17 +92,22 @@ CodeGen.prototype = {
   },
 
   empty: function() {
-    let loc = this.currentLocation || {start: {}};
+    let loc = this.currentLocation || { start: {} };
     return new SourceNode(loc.start.line, loc.start.column, this.srcFile);
   },
-  wrap: function(chunk, loc = this.currentLocation || {start: {}}) {
+  wrap: function(chunk, loc = this.currentLocation || { start: {} }) {
     if (chunk instanceof SourceNode) {
       return chunk;
     }
 
     chunk = castChunk(chunk, this, loc);
 
-    return new SourceNode(loc.start.line, loc.start.column, this.srcFile, chunk);
+    return new SourceNode(
+      loc.start.line,
+      loc.start.column,
+      this.srcFile,
+      chunk
+    );
   },
 
   functionCall: function(fn, type, params) {
@@ -113,13 +116,17 @@ CodeGen.prototype = {
   },
 
   quotedString: function(str) {
-    return '"' + (str + '')
-      .replace(/\\/g, '\\\\')
-      .replace(/"/g, '\\"')
-      .replace(/\n/g, '\\n')
-      .replace(/\r/g, '\\r')
-      .replace(/\u2028/g, '\\u2028') // Per Ecma-262 7.3 + 7.8.4
-      .replace(/\u2029/g, '\\u2029') + '"';
+    return (
+      '"' +
+      (str + '')
+        .replace(/\\/g, '\\\\')
+        .replace(/"/g, '\\"')
+        .replace(/\n/g, '\\n')
+        .replace(/\r/g, '\\r')
+        .replace(/\u2028/g, '\\u2028') // Per Ecma-262 7.3 + 7.8.4
+        .replace(/\u2029/g, '\\u2029') +
+      '"'
+    );
   },
 
   objectLiteral: function(obj) {
@@ -138,7 +145,6 @@ CodeGen.prototype = {
     return ret;
   },
 
-
   generateList: function(entries) {
     let ret = this.empty();
 
@@ -163,4 +169,3 @@ CodeGen.prototype = {
 };
 
 export default CodeGen;
-
diff --git a/lib/handlebars/compiler/compiler.js b/lib/handlebars/compiler/compiler.js
index b56ca5c26..33bd2b11a 100644
--- a/lib/handlebars/compiler/compiler.js
+++ b/lib/handlebars/compiler/compiler.js
@@ -1,7 +1,7 @@
 /* eslint-disable new-cap */
 
 import Exception from '../exception';
-import {isArray, indexOf, extend} from '../utils';
+import { isArray, indexOf, extend } from '../utils';
 import AST from './ast';
 
 const slice = [].slice;
@@ -24,8 +24,11 @@ Compiler.prototype = {
 
     for (let i = 0; i < len; i++) {
       let opcode = this.opcodes[i],
-          otherOpcode = other.opcodes[i];
-      if (opcode.opcode !== otherOpcode.opcode || !argEquals(opcode.args, otherOpcode.args)) {
+        otherOpcode = other.opcodes[i];
+      if (
+        opcode.opcode !== otherOpcode.opcode ||
+        !argEquals(opcode.args, otherOpcode.args)
+      ) {
         return false;
       }
     }
@@ -54,24 +57,28 @@ Compiler.prototype = {
 
     options.blockParams = options.blockParams || [];
 
-    options.knownHelpers = extend(Object.create(null), {
-      'helperMissing': true,
-      'blockHelperMissing': true,
-      'each': true,
-      'if': true,
-      'unless': true,
-      'with': true,
-      'log': true,
-      'lookup': true
-    }, options.knownHelpers);
+    options.knownHelpers = extend(
+      Object.create(null),
+      {
+        helperMissing: true,
+        blockHelperMissing: true,
+        each: true,
+        if: true,
+        unless: true,
+        with: true,
+        log: true,
+        lookup: true
+      },
+      options.knownHelpers
+    );
 
     return this.accept(program);
   },
 
   compileProgram: function(program) {
     let childCompiler = new this.compiler(), // eslint-disable-line new-cap
-        result = childCompiler.compile(program, this.options),
-        guid = this.guid++;
+      result = childCompiler.compile(program, this.options),
+      guid = this.guid++;
 
     this.usePartial = this.usePartial || result.usePartial;
 
@@ -97,7 +104,7 @@ Compiler.prototype = {
     this.options.blockParams.unshift(program.blockParams);
 
     let body = program.body,
-        bodyLength = body.length;
+      bodyLength = body.length;
     for (let i = 0; i < bodyLength; i++) {
       this.accept(body[i]);
     }
@@ -114,7 +121,7 @@ Compiler.prototype = {
     transformLiteralToPath(block);
 
     let program = block.program,
-        inverse = block.inverse;
+      inverse = block.inverse;
 
     program = program && this.compileProgram(program);
     inverse = inverse && this.compileProgram(inverse);
@@ -149,7 +156,7 @@ Compiler.prototype = {
   DecoratorBlock(decorator) {
     let program = decorator.program && this.compileProgram(decorator.program);
     let params = this.setupFullMustacheParams(decorator, program, undefined),
-        path = decorator.path;
+      path = decorator.path;
 
     this.useDecorators = true;
     this.opcode('registerDecorator', params.length, path.original);
@@ -165,17 +172,20 @@ Compiler.prototype = {
 
     let params = partial.params;
     if (params.length > 1) {
-      throw new Exception('Unsupported number of partial arguments: ' + params.length, partial);
+      throw new Exception(
+        'Unsupported number of partial arguments: ' + params.length,
+        partial
+      );
     } else if (!params.length) {
       if (this.options.explicitPartialContext) {
         this.opcode('pushLiteral', 'undefined');
       } else {
-        params.push({type: 'PathExpression', parts: [], depth: 0});
+        params.push({ type: 'PathExpression', parts: [], depth: 0 });
       }
     }
 
     let partialName = partial.name.original,
-        isDynamic = partial.name.type === 'SubExpression';
+      isDynamic = partial.name.type === 'SubExpression';
     if (isDynamic) {
       this.accept(partial.name);
     }
@@ -208,7 +218,6 @@ Compiler.prototype = {
     this.DecoratorBlock(decorator);
   },
 
-
   ContentStatement: function(content) {
     if (content.value) {
       this.opcode('appendContent', content.value);
@@ -231,8 +240,8 @@ Compiler.prototype = {
   },
   ambiguousSexpr: function(sexpr, program, inverse) {
     let path = sexpr.path,
-        name = path.parts[0],
-        isBlock = program != null || inverse != null;
+      name = path.parts[0],
+      isBlock = program != null || inverse != null;
 
     this.opcode('getContext', path.depth);
 
@@ -254,19 +263,27 @@ Compiler.prototype = {
 
   helperSexpr: function(sexpr, program, inverse) {
     let params = this.setupFullMustacheParams(sexpr, program, inverse),
-        path = sexpr.path,
-        name = path.parts[0];
+      path = sexpr.path,
+      name = path.parts[0];
 
     if (this.options.knownHelpers[name]) {
       this.opcode('invokeKnownHelper', params.length, name);
     } else if (this.options.knownHelpersOnly) {
-      throw new Exception('You specified knownHelpersOnly, but used the unknown helper ' + name, sexpr);
+      throw new Exception(
+        'You specified knownHelpersOnly, but used the unknown helper ' + name,
+        sexpr
+      );
     } else {
       path.strict = true;
       path.falsy = true;
 
       this.accept(path);
-      this.opcode('invokeHelper', params.length, path.original, AST.helpers.simpleId(path));
+      this.opcode(
+        'invokeHelper',
+        params.length,
+        path.original,
+        AST.helpers.simpleId(path)
+      );
     }
   },
 
@@ -275,8 +292,8 @@ Compiler.prototype = {
     this.opcode('getContext', path.depth);
 
     let name = path.parts[0],
-        scoped = AST.helpers.scopedId(path),
-        blockParamId = !path.depth && !scoped && this.blockParamIndex(name);
+      scoped = AST.helpers.scopedId(path),
+      blockParamId = !path.depth && !scoped && this.blockParamIndex(name);
 
     if (blockParamId) {
       this.opcode('lookupBlockParam', blockParamId, path.parts);
@@ -287,7 +304,13 @@ Compiler.prototype = {
       this.options.data = true;
       this.opcode('lookupData', path.depth, path.parts, path.strict);
     } else {
-      this.opcode('lookupOnContext', path.parts, path.falsy, path.strict, scoped);
+      this.opcode(
+        'lookupOnContext',
+        path.parts,
+        path.falsy,
+        path.strict,
+        scoped
+      );
     }
   },
 
@@ -313,8 +336,8 @@ Compiler.prototype = {
 
   Hash: function(hash) {
     let pairs = hash.pairs,
-        i = 0,
-        l = pairs.length;
+      i = 0,
+      l = pairs.length;
 
     this.opcode('pushHash');
 
@@ -329,7 +352,11 @@ Compiler.prototype = {
 
   // HELPERS
   opcode: function(name) {
-    this.opcodes.push({ opcode: name, args: slice.call(arguments, 1), loc: this.sourceNode[0].loc });
+    this.opcodes.push({
+      opcode: name,
+      args: slice.call(arguments, 1),
+      loc: this.sourceNode[0].loc
+    });
   },
 
   addDepth: function(depth) {
@@ -358,7 +385,7 @@ Compiler.prototype = {
     // An eligible helper is one that does not have a complex path, i.e. `this.foo`, `../foo` etc.
     if (isEligible && !isHelper) {
       let name = sexpr.path.parts[0],
-          options = this.options;
+        options = this.options;
       if (options.knownHelpers[name]) {
         isHelper = true;
       } else if (options.knownHelpersOnly) {
@@ -386,9 +413,7 @@ Compiler.prototype = {
 
     if (this.stringParams) {
       if (value.replace) {
-        value = value
-            .replace(/^(\.?\.\/)*/g, '')
-            .replace(/\//g, '.');
+        value = value.replace(/^(\.?\.\/)*/g, '').replace(/\//g, '.');
       }
 
       if (val.depth) {
@@ -406,7 +431,7 @@ Compiler.prototype = {
       if (this.trackIds) {
         let blockParamIndex;
         if (val.parts && !AST.helpers.scopedId(val) && !val.depth) {
-           blockParamIndex = this.blockParamIndex(val.parts[0]);
+          blockParamIndex = this.blockParamIndex(val.parts[0]);
         }
         if (blockParamIndex) {
           let blockParamChild = val.parts.slice(1).join('.');
@@ -415,9 +440,9 @@ Compiler.prototype = {
           value = val.original || value;
           if (value.replace) {
             value = value
-                .replace(/^this(?:\.|$)/, '')
-                .replace(/^\.\//, '')
-                .replace(/^\.$/, '');
+              .replace(/^this(?:\.|$)/, '')
+              .replace(/^\.\//, '')
+              .replace(/^\.$/, '');
           }
 
           this.opcode('pushId', val.type, value);
@@ -444,9 +469,13 @@ Compiler.prototype = {
   },
 
   blockParamIndex: function(name) {
-    for (let depth = 0, len = this.options.blockParams.length; depth < len; depth++) {
+    for (
+      let depth = 0, len = this.options.blockParams.length;
+      depth < len;
+      depth++
+    ) {
       let blockParams = this.options.blockParams[depth],
-          param = blockParams && indexOf(blockParams, name);
+        param = blockParams && indexOf(blockParams, name);
       if (blockParams && param >= 0) {
         return [depth, param];
       }
@@ -455,8 +484,14 @@ Compiler.prototype = {
 };
 
 export function precompile(input, options, env) {
-  if (input == null || (typeof input !== 'string' && input.type !== 'Program')) {
-    throw new Exception('You must pass a string or Handlebars AST to Handlebars.precompile. You passed ' + input);
+  if (
+    input == null ||
+    (typeof input !== 'string' && input.type !== 'Program')
+  ) {
+    throw new Exception(
+      'You must pass a string or Handlebars AST to Handlebars.precompile. You passed ' +
+        input
+    );
   }
 
   options = options || {};
@@ -468,13 +503,19 @@ export function precompile(input, options, env) {
   }
 
   let ast = env.parse(input, options),
-      environment = new env.Compiler().compile(ast, options);
+    environment = new env.Compiler().compile(ast, options);
   return new env.JavaScriptCompiler().compile(environment, options);
 }
 
 export function compile(input, options = {}, env) {
-  if (input == null || (typeof input !== 'string' && input.type !== 'Program')) {
-    throw new Exception('You must pass a string or Handlebars AST to Handlebars.compile. You passed ' + input);
+  if (
+    input == null ||
+    (typeof input !== 'string' && input.type !== 'Program')
+  ) {
+    throw new Exception(
+      'You must pass a string or Handlebars AST to Handlebars.compile. You passed ' +
+        input
+    );
   }
 
   options = extend({}, options);
@@ -489,8 +530,13 @@ export function compile(input, options = {}, env) {
 
   function compileInput() {
     let ast = env.parse(input, options),
-        environment = new env.Compiler().compile(ast, options),
-        templateSpec = new env.JavaScriptCompiler().compile(environment, options, undefined, true);
+      environment = new env.Compiler().compile(ast, options),
+      templateSpec = new env.JavaScriptCompiler().compile(
+        environment,
+        options,
+        undefined,
+        true
+      );
     return env.template(templateSpec);
   }
 
diff --git a/lib/handlebars/compiler/helpers.js b/lib/handlebars/compiler/helpers.js
index f26b4e15c..27033a1d5 100644
--- a/lib/handlebars/compiler/helpers.js
+++ b/lib/handlebars/compiler/helpers.js
@@ -4,9 +4,12 @@ function validateClose(open, close) {
   close = close.path ? close.path.original : close;
 
   if (open.path.original !== close) {
-    let errorNode = {loc: open.path.loc};
+    let errorNode = { loc: open.path.loc };
 
-    throw new Exception(open.path.original + " doesn't match " + close, errorNode);
+    throw new Exception(
+      open.path.original + " doesn't match " + close,
+      errorNode
+    );
   }
 }
 
@@ -38,27 +41,26 @@ export function stripFlags(open, close) {
 }
 
 export function stripComment(comment) {
-  return comment.replace(/^\{\{~?!-?-?/, '')
-                .replace(/-?-?~?\}\}$/, '');
+  return comment.replace(/^\{\{~?!-?-?/, '').replace(/-?-?~?\}\}$/, '');
 }
 
 export function preparePath(data, parts, loc) {
   loc = this.locInfo(loc);
 
   let original = data ? '@' : '',
-      dig = [],
-      depth = 0;
+    dig = [],
+    depth = 0;
 
   for (let i = 0, l = parts.length; i < l; i++) {
     let part = parts[i].part,
-        // If we have [] syntax then we do not treat path references as operators,
-        // i.e. foo.[this] resolves to approximately context.foo['this']
-        isLiteral = parts[i].original !== part;
+      // If we have [] syntax then we do not treat path references as operators,
+      // i.e. foo.[this] resolves to approximately context.foo['this']
+      isLiteral = parts[i].original !== part;
     original += (parts[i].separator || '') + part;
 
     if (!isLiteral && (part === '..' || part === '.' || part === 'this')) {
       if (dig.length > 0) {
-        throw new Exception('Invalid path: ' + original, {loc});
+        throw new Exception('Invalid path: ' + original, { loc });
       } else if (part === '..') {
         depth++;
       }
@@ -80,9 +82,9 @@ export function preparePath(data, parts, loc) {
 export function prepareMustache(path, params, hash, open, strip, locInfo) {
   // Must use charAt to support IE pre-10
   let escapeFlag = open.charAt(3) || open.charAt(2),
-      escaped = escapeFlag !== '{' && escapeFlag !== '&';
+    escaped = escapeFlag !== '{' && escapeFlag !== '&';
 
-  let decorator = (/\*/.test(open));
+  let decorator = /\*/.test(open);
   return {
     type: decorator ? 'Decorator' : 'MustacheStatement',
     path,
@@ -118,21 +120,30 @@ export function prepareRawBlock(openRawBlock, contents, close, locInfo) {
   };
 }
 
-export function prepareBlock(openBlock, program, inverseAndProgram, close, inverted, locInfo) {
+export function prepareBlock(
+  openBlock,
+  program,
+  inverseAndProgram,
+  close,
+  inverted,
+  locInfo
+) {
   if (close && close.path) {
     validateClose(openBlock, close);
   }
 
-  let decorator = (/\*/.test(openBlock.open));
+  let decorator = /\*/.test(openBlock.open);
 
   program.blockParams = openBlock.blockParams;
 
-  let inverse,
-      inverseStrip;
+  let inverse, inverseStrip;
 
   if (inverseAndProgram) {
     if (decorator) {
-      throw new Exception('Unexpected inverse block on decorator', inverseAndProgram);
+      throw new Exception(
+        'Unexpected inverse block on decorator',
+        inverseAndProgram
+      );
     }
 
     if (inverseAndProgram.chain) {
@@ -166,7 +177,7 @@ export function prepareBlock(openBlock, program, inverseAndProgram, close, inver
 export function prepareProgram(statements, loc) {
   if (!loc && statements.length) {
     const firstLoc = statements[0].loc,
-          lastLoc = statements[statements.length - 1].loc;
+      lastLoc = statements[statements.length - 1].loc;
 
     /* istanbul ignore else */
     if (firstLoc && lastLoc) {
@@ -192,7 +203,6 @@ export function prepareProgram(statements, loc) {
   };
 }
 
-
 export function preparePartialBlock(open, program, close, locInfo) {
   validateClose(open, close);
 
@@ -207,4 +217,3 @@ export function preparePartialBlock(open, program, close, locInfo) {
     loc: this.locInfo(locInfo)
   };
 }
-
diff --git a/lib/handlebars/compiler/javascript-compiler.js b/lib/handlebars/compiler/javascript-compiler.js
index 9a4c02daf..bcf9bb21c 100644
--- a/lib/handlebars/compiler/javascript-compiler.js
+++ b/lib/handlebars/compiler/javascript-compiler.js
@@ -1,8 +1,8 @@
 import { COMPILER_REVISION, REVISION_CHANGES } from '../base';
 import Exception from '../exception';
-import {isArray} from '../utils';
+import { isArray } from '../utils';
 import CodeGen from './code-gen';
-import {dangerousPropertyRegex} from '../helpers/lookup';
+import { dangerousPropertyRegex } from '../helpers/lookup';
 
 function Literal(value) {
   this.value = value;
@@ -13,9 +13,16 @@ function JavaScriptCompiler() {}
 JavaScriptCompiler.prototype = {
   // PUBLIC API: You can override these methods in a subclass to provide
   // alternative compiled forms for name lookup and buffering semantics
-  nameLookup: function(parent, name/* , type*/) {
+  nameLookup: function(parent, name /* , type*/) {
     if (dangerousPropertyRegex.test(name)) {
-      const isEnumerable = [ this.aliasable('container.propertyIsEnumerable'), '.call(', parent, ',', JSON.stringify(name), ')'];
+      const isEnumerable = [
+        this.aliasable('container.propertyIsEnumerable'),
+        '.call(',
+        parent,
+        ',',
+        JSON.stringify(name),
+        ')'
+      ];
       return ['(', isEnumerable, '?', _actualLookup(), ' : undefined)'];
     }
     return _actualLookup();
@@ -34,7 +41,7 @@ JavaScriptCompiler.prototype = {
 
   compilerInfo: function() {
     const revision = COMPILER_REVISION,
-          versions = REVISION_CHANGES[revision];
+      versions = REVISION_CHANGES[revision];
     return [revision, versions];
   },
 
@@ -91,14 +98,18 @@ JavaScriptCompiler.prototype = {
 
     this.compileChildren(environment, options);
 
-    this.useDepths = this.useDepths || environment.useDepths || environment.useDecorators || this.options.compat;
+    this.useDepths =
+      this.useDepths ||
+      environment.useDepths ||
+      environment.useDecorators ||
+      this.options.compat;
     this.useBlockParams = this.useBlockParams || environment.useBlockParams;
 
     let opcodes = environment.opcodes,
-        opcode,
-        firstLoc,
-        i,
-        l;
+      opcode,
+      firstLoc,
+      i,
+      l;
 
     for (i = 0, l = opcodes.length; i < l; i++) {
       opcode = opcodes[i];
@@ -124,9 +135,20 @@ JavaScriptCompiler.prototype = {
       this.decorators.push('return fn;');
 
       if (asObject) {
-        this.decorators = Function.apply(this, ['fn', 'props', 'container', 'depth0', 'data', 'blockParams', 'depths', this.decorators.merge()]);
+        this.decorators = Function.apply(this, [
+          'fn',
+          'props',
+          'container',
+          'depth0',
+          'data',
+          'blockParams',
+          'depths',
+          this.decorators.merge()
+        ]);
       } else {
-        this.decorators.prepend('function(fn, props, container, depth0, data, blockParams, depths) {\n');
+        this.decorators.prepend(
+          'function(fn, props, container, depth0, data, blockParams, depths) {\n'
+        );
         this.decorators.push('}\n');
         this.decorators = this.decorators.merge();
       }
@@ -146,7 +168,7 @@ JavaScriptCompiler.prototype = {
         ret.useDecorators = true;
       }
 
-      let {programs, decorators} = this.context;
+      let { programs, decorators } = this.context;
       for (i = 0, l = programs.length; i < l; i++) {
         if (programs[i]) {
           ret[i] = programs[i];
@@ -176,11 +198,11 @@ JavaScriptCompiler.prototype = {
       if (!asObject) {
         ret.compiler = JSON.stringify(ret.compiler);
 
-        this.source.currentLocation = {start: {line: 1, column: 0}};
+        this.source.currentLocation = { start: { line: 1, column: 0 } };
         ret = this.objectLiteral(ret);
 
         if (options.srcName) {
-          ret = ret.toStringWithSourceMap({file: options.destName});
+          ret = ret.toStringWithSourceMap({ file: options.destName });
           ret.map = ret.map && ret.map.toString();
         } else {
           ret = ret.toString();
@@ -221,7 +243,7 @@ JavaScriptCompiler.prototype = {
     Object.keys(this.aliases).forEach(alias => {
       let node = this.aliases[alias];
       if (node.children && node.referenceCount > 1) {
-        varDeclarations += ', alias' + (++aliasCount) + '=' + alias;
+        varDeclarations += ', alias' + ++aliasCount + '=' + alias;
         node.children[0] = 'alias' + aliasCount;
       }
     });
@@ -243,18 +265,23 @@ JavaScriptCompiler.prototype = {
 
       return Function.apply(this, params);
     } else {
-      return this.source.wrap(['function(', params.join(','), ') {\n  ', source, '}']);
+      return this.source.wrap([
+        'function(',
+        params.join(','),
+        ') {\n  ',
+        source,
+        '}'
+      ]);
     }
   },
   mergeSource: function(varDeclarations) {
     let isSimple = this.environment.isSimple,
-        appendOnly = !this.forceBuffer,
-        appendFirst,
-
-        sourceSeen,
-        bufferStart,
-        bufferEnd;
-    this.source.each((line) => {
+      appendOnly = !this.forceBuffer,
+      appendFirst,
+      sourceSeen,
+      bufferStart,
+      bufferEnd;
+    this.source.each(line => {
       if (line.appendToBuffer) {
         if (bufferStart) {
           line.prepend('  + ');
@@ -280,7 +307,6 @@ JavaScriptCompiler.prototype = {
       }
     });
 
-
     if (appendOnly) {
       if (bufferStart) {
         bufferStart.prepend('return ');
@@ -289,7 +315,8 @@ JavaScriptCompiler.prototype = {
         this.source.push('return "";');
       }
     } else {
-      varDeclarations += ', buffer = ' + (appendFirst ? '' : this.initializeBuffer());
+      varDeclarations +=
+        ', buffer = ' + (appendFirst ? '' : this.initializeBuffer());
 
       if (bufferStart) {
         bufferStart.prepend('return buffer + ');
@@ -300,7 +327,9 @@ JavaScriptCompiler.prototype = {
     }
 
     if (varDeclarations) {
-      this.source.prepend('var ' + varDeclarations.substring(2) + (appendFirst ? '' : ';\n'));
+      this.source.prepend(
+        'var ' + varDeclarations.substring(2) + (appendFirst ? '' : ';\n')
+      );
     }
 
     return this.source.merge();
@@ -316,8 +345,10 @@ JavaScriptCompiler.prototype = {
   // replace it on the stack with the result of properly
   // invoking blockHelperMissing.
   blockValue: function(name) {
-    let blockHelperMissing = this.aliasable('container.hooks.blockHelperMissing'),
-        params = [this.contextName(0)];
+    let blockHelperMissing = this.aliasable(
+        'container.hooks.blockHelperMissing'
+      ),
+      params = [this.contextName(0)];
     this.setupHelperArgs(name, 0, params);
 
     let blockName = this.popStack();
@@ -334,8 +365,10 @@ JavaScriptCompiler.prototype = {
   // On stack, after, if lastHelper: value
   ambiguousBlockValue: function() {
     // We're being a bit cheeky and reusing the options value from the prior exec
-    let blockHelperMissing = this.aliasable('container.hooks.blockHelperMissing'),
-        params = [this.contextName(0)];
+    let blockHelperMissing = this.aliasable(
+        'container.hooks.blockHelperMissing'
+      ),
+      params = [this.contextName(0)];
     this.setupHelperArgs('', 0, params, true);
 
     this.flushInline();
@@ -344,9 +377,14 @@ JavaScriptCompiler.prototype = {
     params.splice(1, 0, current);
 
     this.pushSource([
-      'if (!', this.lastHelper, ') { ',
-      current, ' = ', this.source.functionCall(blockHelperMissing, 'call', params),
-      '}']);
+      'if (!',
+      this.lastHelper,
+      ') { ',
+      current,
+      ' = ',
+      this.source.functionCall(blockHelperMissing, 'call', params),
+      '}'
+    ]);
   },
 
   // [appendContent]
@@ -376,14 +414,24 @@ JavaScriptCompiler.prototype = {
   // Otherwise, the empty string is appended
   append: function() {
     if (this.isInline()) {
-      this.replaceStack((current) => [' != null ? ', current, ' : ""']);
+      this.replaceStack(current => [' != null ? ', current, ' : ""']);
 
       this.pushSource(this.appendToBuffer(this.popStack()));
     } else {
       let local = this.popStack();
-      this.pushSource(['if (', local, ' != null) { ', this.appendToBuffer(local, undefined, true), ' }']);
+      this.pushSource([
+        'if (',
+        local,
+        ' != null) { ',
+        this.appendToBuffer(local, undefined, true),
+        ' }'
+      ]);
       if (this.environment.isSimple) {
-        this.pushSource(['else { ', this.appendToBuffer("''", undefined, true), ' }']);
+        this.pushSource([
+          'else { ',
+          this.appendToBuffer("''", undefined, true),
+          ' }'
+        ]);
       }
     }
   },
@@ -395,8 +443,14 @@ JavaScriptCompiler.prototype = {
   //
   // Escape `value` and append it to the buffer
   appendEscaped: function() {
-    this.pushSource(this.appendToBuffer(
-        [this.aliasable('container.escapeExpression'), '(', this.popStack(), ')']));
+    this.pushSource(
+      this.appendToBuffer([
+        this.aliasable('container.escapeExpression'),
+        '(',
+        this.popStack(),
+        ')'
+      ])
+    );
   },
 
   // [getContext]
@@ -480,7 +534,7 @@ JavaScriptCompiler.prototype = {
     let len = parts.length;
     for (; i < len; i++) {
       /* eslint-disable no-loop-func */
-      this.replaceStack((current) => {
+      this.replaceStack(current => {
         let lookup = this.nameLookup(current, parts[i], type);
         // We want to ensure that zero and false are handled properly if the context (falsy flag)
         // needs to have the special handling for these values.
@@ -503,7 +557,14 @@ JavaScriptCompiler.prototype = {
   // If the `value` is a lambda, replace it on the stack by
   // the return value of the lambda
   resolvePossibleLambda: function() {
-    this.push([this.aliasable('container.lambda'), '(', this.popStack(), ', ', this.contextName(0), ')']);
+    this.push([
+      this.aliasable('container.lambda'),
+      '(',
+      this.popStack(),
+      ', ',
+      this.contextName(0),
+      ')'
+    ]);
   },
 
   // [pushStringParam]
@@ -543,7 +604,7 @@ JavaScriptCompiler.prototype = {
     if (this.hash) {
       this.hashes.push(this.hash);
     }
-    this.hash = {values: {}, types: [], contexts: [], ids: []};
+    this.hash = { values: {}, types: [], contexts: [], ids: [] };
   },
   popHash: function() {
     let hash = this.hash;
@@ -607,11 +668,16 @@ JavaScriptCompiler.prototype = {
   // and inserts the decorator into the decorators list.
   registerDecorator(paramSize, name) {
     let foundDecorator = this.nameLookup('decorators', name, 'decorator'),
-        options = this.setupHelperArgs(name, paramSize);
+      options = this.setupHelperArgs(name, paramSize);
 
     this.decorators.push([
       'fn = ',
-      this.decorators.functionCall(foundDecorator, '', ['fn', 'props', 'container', options]),
+      this.decorators.functionCall(foundDecorator, '', [
+        'fn',
+        'props',
+        'container',
+        options
+      ]),
       ' || fn;'
     ]);
   },
@@ -627,21 +693,32 @@ JavaScriptCompiler.prototype = {
   // If the helper is not found, `helperMissing` is called.
   invokeHelper: function(paramSize, name, isSimple) {
     let nonHelper = this.popStack(),
-        helper = this.setupHelper(paramSize, name);
+      helper = this.setupHelper(paramSize, name);
 
     let possibleFunctionCalls = [];
 
-    if (isSimple) { // direct call to helper
+    if (isSimple) {
+      // direct call to helper
       possibleFunctionCalls.push(helper.name);
     }
     // call a function from the input object
     possibleFunctionCalls.push(nonHelper);
     if (!this.options.strict) {
-      possibleFunctionCalls.push(this.aliasable('container.hooks.helperMissing'));
+      possibleFunctionCalls.push(
+        this.aliasable('container.hooks.helperMissing')
+      );
     }
 
-    let functionLookupCode = ['(', this.itemsSeparatedBy(possibleFunctionCalls, '||'), ')'];
-    let functionCall = this.source.functionCall(functionLookupCode, 'call', helper.callParams);
+    let functionLookupCode = [
+      '(',
+      this.itemsSeparatedBy(possibleFunctionCalls, '||'),
+      ')'
+    ];
+    let functionCall = this.source.functionCall(
+      functionLookupCode,
+      'call',
+      helper.callParams
+    );
     this.push(functionCall);
   },
 
@@ -685,22 +762,31 @@ JavaScriptCompiler.prototype = {
     this.emptyHash();
     let helper = this.setupHelper(0, name, helperCall);
 
-    let helperName = this.lastHelper = this.nameLookup('helpers', name, 'helper');
+    let helperName = (this.lastHelper = this.nameLookup(
+      'helpers',
+      name,
+      'helper'
+    ));
 
     let lookup = ['(', '(helper = ', helperName, ' || ', nonHelper, ')'];
     if (!this.options.strict) {
       lookup[0] = '(helper = ';
       lookup.push(
-          ' != null ? helper : ',
-          this.aliasable('container.hooks.helperMissing')
+        ' != null ? helper : ',
+        this.aliasable('container.hooks.helperMissing')
       );
     }
 
     this.push([
-      '(', lookup,
-      (helper.paramsInit ? ['),(', helper.paramsInit] : []), '),',
-      '(typeof helper === ', this.aliasable('"function"'), ' ? ',
-      this.source.functionCall('helper', 'call', helper.callParams), ' : helper))'
+      '(',
+      lookup,
+      helper.paramsInit ? ['),(', helper.paramsInit] : [],
+      '),',
+      '(typeof helper === ',
+      this.aliasable('"function"'),
+      ' ? ',
+      this.source.functionCall('helper', 'call', helper.callParams),
+      ' : helper))'
     ]);
   },
 
@@ -713,7 +799,7 @@ JavaScriptCompiler.prototype = {
   // and pushes the result of the invocation back.
   invokePartial: function(isDynamic, name, indent) {
     let params = [],
-        options = this.setupParams(name, 1, params);
+      options = this.setupParams(name, 1, params);
 
     if (isDynamic) {
       name = this.popStack();
@@ -750,9 +836,9 @@ JavaScriptCompiler.prototype = {
   // Pops a value off the stack and assigns it to the current hash
   assignToHash: function(key) {
     let value = this.popStack(),
-        context,
-        type,
-        id;
+      context,
+      type,
+      id;
 
     if (this.trackIds) {
       id = this.popStack();
@@ -778,8 +864,13 @@ JavaScriptCompiler.prototype = {
   pushId: function(type, name, child) {
     if (type === 'BlockParam') {
       this.pushStackLiteral(
-          'blockParams[' + name[0] + '].path[' + name[1] + ']'
-          + (child ? ' + ' + JSON.stringify('.' + child) : ''));
+        'blockParams[' +
+          name[0] +
+          '].path[' +
+          name[1] +
+          ']' +
+          (child ? ' + ' + JSON.stringify('.' + child) : '')
+      );
     } else if (type === 'PathExpression') {
       this.pushString(name);
     } else if (type === 'SubExpression') {
@@ -794,7 +885,9 @@ JavaScriptCompiler.prototype = {
   compiler: JavaScriptCompiler,
 
   compileChildren: function(environment, options) {
-    let children = environment.children, child, compiler;
+    let children = environment.children,
+      child,
+      compiler;
 
     for (let i = 0, l = children.length; i < l; i++) {
       child = children[i];
@@ -807,7 +900,12 @@ JavaScriptCompiler.prototype = {
         let index = this.context.programs.length;
         child.index = index;
         child.name = 'program' + index;
-        this.context.programs[index] = compiler.compile(child, options, this.context, !this.precompile);
+        this.context.programs[index] = compiler.compile(
+          child,
+          options,
+          this.context,
+          !this.precompile
+        );
         this.context.decorators[index] = compiler.decorators;
         this.context.environments[index] = child;
 
@@ -835,7 +933,7 @@ JavaScriptCompiler.prototype = {
 
   programExpression: function(guid) {
     let child = this.environment.children[guid],
-        programParams = [child.index, 'data', child.blockParams];
+      programParams = [child.index, 'data', child.blockParams];
 
     if (this.useBlockParams || this.useDepths) {
       programParams.push('blockParams');
@@ -870,7 +968,11 @@ JavaScriptCompiler.prototype = {
   pushSource: function(source) {
     if (this.pendingContent) {
       this.source.push(
-          this.appendToBuffer(this.source.quotedString(this.pendingContent), this.pendingLocation));
+        this.appendToBuffer(
+          this.source.quotedString(this.pendingContent),
+          this.pendingLocation
+        )
+      );
       this.pendingContent = undefined;
     }
 
@@ -881,9 +983,9 @@ JavaScriptCompiler.prototype = {
 
   replaceStack: function(callback) {
     let prefix = ['('],
-        stack,
-        createdStack,
-        usedLiteral;
+      stack,
+      createdStack,
+      usedLiteral;
 
     /* istanbul ignore next */
     if (!this.isInline()) {
@@ -920,7 +1022,9 @@ JavaScriptCompiler.prototype = {
 
   incrStack: function() {
     this.stackSlot++;
-    if (this.stackSlot > this.stackVars.length) { this.stackVars.push('stack' + this.stackSlot); }
+    if (this.stackSlot > this.stackVars.length) {
+      this.stackVars.push('stack' + this.stackSlot);
+    }
     return this.topStackName();
   },
   topStackName: function() {
@@ -947,9 +1051,9 @@ JavaScriptCompiler.prototype = {
 
   popStack: function(wrapped) {
     let inline = this.isInline(),
-        item = (inline ? this.inlineStack : this.compileStack).pop();
+      item = (inline ? this.inlineStack : this.compileStack).pop();
 
-    if (!wrapped && (item instanceof Literal)) {
+    if (!wrapped && item instanceof Literal) {
       return item.value;
     } else {
       if (!inline) {
@@ -964,8 +1068,8 @@ JavaScriptCompiler.prototype = {
   },
 
   topStack: function() {
-    let stack = (this.isInline() ? this.inlineStack : this.compileStack),
-        item = stack[stack.length - 1];
+    let stack = this.isInline() ? this.inlineStack : this.compileStack,
+      item = stack[stack.length - 1];
 
     /* istanbul ignore if */
     if (item instanceof Literal) {
@@ -1007,9 +1111,13 @@ JavaScriptCompiler.prototype = {
 
   setupHelper: function(paramSize, name, blockHelper) {
     let params = [],
-        paramsInit = this.setupHelperArgs(name, paramSize, params, blockHelper);
+      paramsInit = this.setupHelperArgs(name, paramSize, params, blockHelper);
     let foundHelper = this.nameLookup('helpers', name, 'helper'),
-        callContext = this.aliasable(`${this.contextName(0)} != null ? ${this.contextName(0)} : (container.nullContext || {})`);
+      callContext = this.aliasable(
+        `${this.contextName(0)} != null ? ${this.contextName(
+          0
+        )} : (container.nullContext || {})`
+      );
 
     return {
       params: params,
@@ -1021,11 +1129,11 @@ JavaScriptCompiler.prototype = {
 
   setupParams: function(helper, paramSize, params) {
     let options = {},
-        contexts = [],
-        types = [],
-        ids = [],
-        objectArgs = !params,
-        param;
+      contexts = [],
+      types = [],
+      ids = [],
+      objectArgs = !params,
+      param;
 
     if (objectArgs) {
       params = [];
@@ -1043,7 +1151,7 @@ JavaScriptCompiler.prototype = {
     }
 
     let inverse = this.popStack(),
-        program = this.popStack();
+      program = this.popStack();
 
     // Avoid setting fn and inverse if neither are set. This allows
     // helpers to do a check for `if (options.fn)`
@@ -1106,7 +1214,6 @@ JavaScriptCompiler.prototype = {
   }
 };
 
-
 (function() {
   const reservedWords = (
     'break else new var' +
@@ -1127,21 +1234,24 @@ JavaScriptCompiler.prototype = {
     ' null true false'
   ).split(' ');
 
-  const compilerWords = JavaScriptCompiler.RESERVED_WORDS = {};
+  const compilerWords = (JavaScriptCompiler.RESERVED_WORDS = {});
 
   for (let i = 0, l = reservedWords.length; i < l; i++) {
     compilerWords[reservedWords[i]] = true;
   }
-}());
+})();
 
 JavaScriptCompiler.isValidJavaScriptVariableName = function(name) {
-  return !JavaScriptCompiler.RESERVED_WORDS[name] && (/^[a-zA-Z_$][0-9a-zA-Z_$]*$/).test(name);
+  return (
+    !JavaScriptCompiler.RESERVED_WORDS[name] &&
+    /^[a-zA-Z_$][0-9a-zA-Z_$]*$/.test(name)
+  );
 };
 
 function strictLookup(requireTerminal, compiler, parts, type) {
   let stack = compiler.popStack(),
-      i = 0,
-      len = parts.length;
+    i = 0,
+    len = parts.length;
   if (requireTerminal) {
     len--;
   }
@@ -1151,7 +1261,16 @@ function strictLookup(requireTerminal, compiler, parts, type) {
   }
 
   if (requireTerminal) {
-    return [compiler.aliasable('container.strict'), '(', stack, ', ', compiler.quotedString(parts[i]), ', ', JSON.stringify(compiler.source.currentLocation), ' )'];
+    return [
+      compiler.aliasable('container.strict'),
+      '(',
+      stack,
+      ', ',
+      compiler.quotedString(parts[i]),
+      ', ',
+      JSON.stringify(compiler.source.currentLocation),
+      ' )'
+    ];
   } else {
     return stack;
   }
diff --git a/lib/handlebars/compiler/printer.js b/lib/handlebars/compiler/printer.js
index 6ad43baec..e087806cd 100644
--- a/lib/handlebars/compiler/printer.js
+++ b/lib/handlebars/compiler/printer.js
@@ -24,13 +24,14 @@ PrintVisitor.prototype.pad = function(string) {
 
 PrintVisitor.prototype.Program = function(program) {
   let out = '',
-      body = program.body,
-      i, l;
+    body = program.body,
+    i,
+    l;
 
   if (program.blockParams) {
     let blockParams = 'BLOCK PARAMS: [';
     for (i = 0, l = program.blockParams.length; i < l; i++) {
-       blockParams += ' ' + program.blockParams[i];
+      blockParams += ' ' + program.blockParams[i];
     }
     blockParams += ' ]';
     out += this.pad(blockParams);
@@ -52,11 +53,14 @@ PrintVisitor.prototype.Decorator = function(mustache) {
   return this.pad('{{ DIRECTIVE ' + this.SubExpression(mustache) + ' }}');
 };
 
-PrintVisitor.prototype.BlockStatement =
-PrintVisitor.prototype.DecoratorBlock = function(block) {
+PrintVisitor.prototype.BlockStatement = PrintVisitor.prototype.DecoratorBlock = function(
+  block
+) {
   let out = '';
 
-  out += this.pad((block.type === 'DecoratorBlock' ? 'DIRECTIVE ' : '') + 'BLOCK:');
+  out += this.pad(
+    (block.type === 'DecoratorBlock' ? 'DIRECTIVE ' : '') + 'BLOCK:'
+  );
   this.padding++;
   out += this.pad(this.SubExpression(block));
   if (block.program) {
@@ -66,12 +70,16 @@ PrintVisitor.prototype.DecoratorBlock = function(block) {
     this.padding--;
   }
   if (block.inverse) {
-    if (block.program) { this.padding++; }
+    if (block.program) {
+      this.padding++;
+    }
     out += this.pad('{{^}}');
     this.padding++;
     out += this.accept(block.inverse);
     this.padding--;
-    if (block.program) { this.padding--; }
+    if (block.program) {
+      this.padding--;
+    }
   }
   this.padding--;
 
@@ -115,8 +123,8 @@ PrintVisitor.prototype.CommentStatement = function(comment) {
 
 PrintVisitor.prototype.SubExpression = function(sexpr) {
   let params = sexpr.params,
-      paramStrings = [],
-      hash;
+    paramStrings = [],
+    hash;
 
   for (let i = 0, l = params.length; i < l; i++) {
     paramStrings.push(this.accept(params[i]));
@@ -134,7 +142,6 @@ PrintVisitor.prototype.PathExpression = function(id) {
   return (id.data ? '@' : '') + 'PATH:' + path;
 };
 
-
 PrintVisitor.prototype.StringLiteral = function(string) {
   return '"' + string.value + '"';
 };
@@ -157,7 +164,7 @@ PrintVisitor.prototype.NullLiteral = function() {
 
 PrintVisitor.prototype.Hash = function(hash) {
   let pairs = hash.pairs,
-      joinedPairs = [];
+    joinedPairs = [];
 
   for (let i = 0, l = pairs.length; i < l; i++) {
     joinedPairs.push(this.accept(pairs[i]));
diff --git a/lib/handlebars/compiler/visitor.js b/lib/handlebars/compiler/visitor.js
index 2c504d1b2..76bb01f12 100644
--- a/lib/handlebars/compiler/visitor.js
+++ b/lib/handlebars/compiler/visitor.js
@@ -15,7 +15,14 @@ Visitor.prototype = {
       // Hacky sanity check: This may have a few false positives for type for the helper
       // methods but will generally do the right thing without a lot of overhead.
       if (value && !Visitor.prototype[value.type]) {
-        throw new Exception('Unexpected node type "' + value.type + '" found when accepting ' + name + ' on ' + node.type);
+        throw new Exception(
+          'Unexpected node type "' +
+            value.type +
+            '" found when accepting ' +
+            name +
+            ' on ' +
+            node.type
+        );
       }
       node[name] = value;
     }
diff --git a/lib/handlebars/compiler/whitespace-control.js b/lib/handlebars/compiler/whitespace-control.js
index 8ebfbef57..7db683983 100644
--- a/lib/handlebars/compiler/whitespace-control.js
+++ b/lib/handlebars/compiler/whitespace-control.js
@@ -14,18 +14,18 @@ WhitespaceControl.prototype.Program = function(program) {
   let body = program.body;
   for (let i = 0, l = body.length; i < l; i++) {
     let current = body[i],
-        strip = this.accept(current);
+      strip = this.accept(current);
 
     if (!strip) {
       continue;
     }
 
     let _isPrevWhitespace = isPrevWhitespace(body, i, isRoot),
-        _isNextWhitespace = isNextWhitespace(body, i, isRoot),
-
-        openStandalone = strip.openStandalone && _isPrevWhitespace,
-        closeStandalone = strip.closeStandalone && _isNextWhitespace,
-        inlineStandalone = strip.inlineStandalone && _isPrevWhitespace && _isNextWhitespace;
+      _isNextWhitespace = isNextWhitespace(body, i, isRoot),
+      openStandalone = strip.openStandalone && _isPrevWhitespace,
+      closeStandalone = strip.closeStandalone && _isNextWhitespace,
+      inlineStandalone =
+        strip.inlineStandalone && _isPrevWhitespace && _isNextWhitespace;
 
     if (strip.close) {
       omitRight(body, i, true);
@@ -41,7 +41,7 @@ WhitespaceControl.prototype.Program = function(program) {
         // If we are on a standalone node, save the indent info for partials
         if (current.type === 'PartialStatement') {
           // Pull out the whitespace from the final line
-          current.indent = (/([ \t]+$)/).exec(body[i - 1].original)[1];
+          current.indent = /([ \t]+$)/.exec(body[i - 1].original)[1];
         }
       }
     }
@@ -62,17 +62,17 @@ WhitespaceControl.prototype.Program = function(program) {
   return program;
 };
 
-WhitespaceControl.prototype.BlockStatement =
-WhitespaceControl.prototype.DecoratorBlock =
-WhitespaceControl.prototype.PartialBlockStatement = function(block) {
+WhitespaceControl.prototype.BlockStatement = WhitespaceControl.prototype.DecoratorBlock = WhitespaceControl.prototype.PartialBlockStatement = function(
+  block
+) {
   this.accept(block.program);
   this.accept(block.inverse);
 
   // Find the inverse program that is involed with whitespace stripping.
   let program = block.program || block.inverse,
-      inverse = block.program && block.inverse,
-      firstInverse = inverse,
-      lastInverse = inverse;
+    inverse = block.program && block.inverse,
+    firstInverse = inverse,
+    lastInverse = inverse;
 
   if (inverse && inverse.chained) {
     firstInverse = inverse.body[0].program;
@@ -112,9 +112,11 @@ WhitespaceControl.prototype.PartialBlockStatement = function(block) {
     }
 
     // Find standalone else statments
-    if (!this.options.ignoreStandalone
-        && isPrevWhitespace(program.body)
-        && isNextWhitespace(firstInverse.body)) {
+    if (
+      !this.options.ignoreStandalone &&
+      isPrevWhitespace(program.body) &&
+      isNextWhitespace(firstInverse.body)
+    ) {
       omitLeft(program.body);
       omitRight(firstInverse.body);
     }
@@ -125,13 +127,15 @@ WhitespaceControl.prototype.PartialBlockStatement = function(block) {
   return strip;
 };
 
-WhitespaceControl.prototype.Decorator =
-WhitespaceControl.prototype.MustacheStatement = function(mustache) {
+WhitespaceControl.prototype.Decorator = WhitespaceControl.prototype.MustacheStatement = function(
+  mustache
+) {
   return mustache.strip;
 };
 
-WhitespaceControl.prototype.PartialStatement =
-    WhitespaceControl.prototype.CommentStatement = function(node) {
+WhitespaceControl.prototype.PartialStatement = WhitespaceControl.prototype.CommentStatement = function(
+  node
+) {
   /* istanbul ignore next */
   let strip = node.strip || {};
   return {
@@ -141,7 +145,6 @@ WhitespaceControl.prototype.PartialStatement =
   };
 };
 
-
 function isPrevWhitespace(body, i, isRoot) {
   if (i === undefined) {
     i = body.length;
@@ -150,13 +153,15 @@ function isPrevWhitespace(body, i, isRoot) {
   // Nodes that end with newlines are considered whitespace (but are special
   // cased for strip operations)
   let prev = body[i - 1],
-      sibling = body[i - 2];
+    sibling = body[i - 2];
   if (!prev) {
     return isRoot;
   }
 
   if (prev.type === 'ContentStatement') {
-    return (sibling || !isRoot ? (/\r?\n\s*?$/) : (/(^|\r?\n)\s*?$/)).test(prev.original);
+    return (sibling || !isRoot ? /\r?\n\s*?$/ : /(^|\r?\n)\s*?$/).test(
+      prev.original
+    );
   }
 }
 function isNextWhitespace(body, i, isRoot) {
@@ -165,13 +170,15 @@ function isNextWhitespace(body, i, isRoot) {
   }
 
   let next = body[i + 1],
-      sibling = body[i + 2];
+    sibling = body[i + 2];
   if (!next) {
     return isRoot;
   }
 
   if (next.type === 'ContentStatement') {
-    return (sibling || !isRoot ? (/^\s*?\r?\n/) : (/^\s*?(\r?\n|$)/)).test(next.original);
+    return (sibling || !isRoot ? /^\s*?\r?\n/ : /^\s*?(\r?\n|$)/).test(
+      next.original
+    );
   }
 }
 
@@ -184,12 +191,19 @@ function isNextWhitespace(body, i, isRoot) {
 // content is met.
 function omitRight(body, i, multiple) {
   let current = body[i == null ? 0 : i + 1];
-  if (!current || current.type !== 'ContentStatement' || (!multiple && current.rightStripped)) {
+  if (
+    !current ||
+    current.type !== 'ContentStatement' ||
+    (!multiple && current.rightStripped)
+  ) {
     return;
   }
 
   let original = current.value;
-  current.value = current.value.replace(multiple ? (/^\s+/) : (/^[ \t]*\r?\n?/), '');
+  current.value = current.value.replace(
+    multiple ? /^\s+/ : /^[ \t]*\r?\n?/,
+    ''
+  );
   current.rightStripped = current.value !== original;
 }
 
@@ -202,13 +216,17 @@ function omitRight(body, i, multiple) {
 // content is met.
 function omitLeft(body, i, multiple) {
   let current = body[i == null ? body.length - 1 : i - 1];
-  if (!current || current.type !== 'ContentStatement' || (!multiple && current.leftStripped)) {
+  if (
+    !current ||
+    current.type !== 'ContentStatement' ||
+    (!multiple && current.leftStripped)
+  ) {
     return;
   }
 
   // We omit the last node if it's whitespace only and not preceded by a non-content node.
   let original = current.value;
-  current.value = current.value.replace(multiple ? (/\s+$/) : (/[ \t]+$/), '');
+  current.value = current.value.replace(multiple ? /\s+$/ : /[ \t]+$/, '');
   current.leftStripped = current.value !== original;
   return current.leftStripped;
 }
diff --git a/lib/handlebars/decorators.js b/lib/handlebars/decorators.js
index 6f5a61525..d9d5e8a96 100644
--- a/lib/handlebars/decorators.js
+++ b/lib/handlebars/decorators.js
@@ -3,4 +3,3 @@ import registerInline from './decorators/inline';
 export function registerDefaultDecorators(instance) {
   registerInline(instance);
 }
-
diff --git a/lib/handlebars/decorators/inline.js b/lib/handlebars/decorators/inline.js
index 214246620..02f5be7b5 100644
--- a/lib/handlebars/decorators/inline.js
+++ b/lib/handlebars/decorators/inline.js
@@ -1,4 +1,4 @@
-import {extend} from '../utils';
+import { extend } from '../utils';
 
 export default function(instance) {
   instance.registerDecorator('inline', function(fn, props, container, options) {
diff --git a/lib/handlebars/exception.js b/lib/handlebars/exception.js
index 6333f1907..b2fdc00bc 100644
--- a/lib/handlebars/exception.js
+++ b/lib/handlebars/exception.js
@@ -1,12 +1,20 @@
-
-const errorProps = ['description', 'fileName', 'lineNumber', 'endLineNumber', 'message', 'name', 'number', 'stack'];
+const errorProps = [
+  'description',
+  'fileName',
+  'lineNumber',
+  'endLineNumber',
+  'message',
+  'name',
+  'number',
+  'stack'
+];
 
 function Exception(message, node) {
   let loc = node && node.loc,
-      line,
-      endLineNumber,
-      column,
-      endColumn;
+    line,
+    endLineNumber,
+    column,
+    endColumn;
 
   if (loc) {
     line = loc.start.line;
diff --git a/lib/handlebars/helpers/block-helper-missing.js b/lib/handlebars/helpers/block-helper-missing.js
index 6639ddb9d..9aeea9b97 100644
--- a/lib/handlebars/helpers/block-helper-missing.js
+++ b/lib/handlebars/helpers/block-helper-missing.js
@@ -1,9 +1,9 @@
-import {appendContextPath, createFrame, isArray} from '../utils';
+import { appendContextPath, createFrame, isArray } from '../utils';
 
 export default function(instance) {
   instance.registerHelper('blockHelperMissing', function(context, options) {
     let inverse = options.inverse,
-        fn = options.fn;
+      fn = options.fn;
 
     if (context === true) {
       return fn(this);
@@ -22,8 +22,11 @@ export default function(instance) {
     } else {
       if (options.data && options.ids) {
         let data = createFrame(options.data);
-        data.contextPath = appendContextPath(options.data.contextPath, options.name);
-        options = {data: data};
+        data.contextPath = appendContextPath(
+          options.data.contextPath,
+          options.name
+        );
+        options = { data: data };
       }
 
       return fn(context, options);
diff --git a/lib/handlebars/helpers/each.js b/lib/handlebars/helpers/each.js
index 8e57b7782..c1fa20f39 100644
--- a/lib/handlebars/helpers/each.js
+++ b/lib/handlebars/helpers/each.js
@@ -1,4 +1,10 @@
-import {appendContextPath, blockParams, createFrame, isArray, isFunction} from '../utils';
+import {
+  appendContextPath,
+  blockParams,
+  createFrame,
+  isArray,
+  isFunction
+} from '../utils';
 import Exception from '../exception';
 
 export default function(instance) {
@@ -8,17 +14,20 @@ export default function(instance) {
     }
 
     let fn = options.fn,
-        inverse = options.inverse,
-        i = 0,
-        ret = '',
-        data,
-        contextPath;
+      inverse = options.inverse,
+      i = 0,
+      ret = '',
+      data,
+      contextPath;
 
     if (options.data && options.ids) {
-      contextPath = appendContextPath(options.data.contextPath, options.ids[0]) + '.';
+      contextPath =
+        appendContextPath(options.data.contextPath, options.ids[0]) + '.';
     }
 
-    if (isFunction(context)) { context = context.call(this); }
+    if (isFunction(context)) {
+      context = context.call(this);
+    }
 
     if (options.data) {
       data = createFrame(options.data);
@@ -36,10 +45,15 @@ export default function(instance) {
         }
       }
 
-      ret = ret + fn(context[field], {
-        data: data,
-        blockParams: blockParams([context[field], field], [contextPath + field, null])
-      });
+      ret =
+        ret +
+        fn(context[field], {
+          data: data,
+          blockParams: blockParams(
+            [context[field], field],
+            [contextPath + field, null]
+          )
+        });
     }
 
     if (context && typeof context === 'object') {
diff --git a/lib/handlebars/helpers/helper-missing.js b/lib/handlebars/helpers/helper-missing.js
index ec32e8245..f8869e9c9 100644
--- a/lib/handlebars/helpers/helper-missing.js
+++ b/lib/handlebars/helpers/helper-missing.js
@@ -7,7 +7,9 @@ export default function(instance) {
       return undefined;
     } else {
       // Someone is actually trying to call something, blow up.
-      throw new Exception('Missing helper: "' + arguments[arguments.length - 1].name + '"');
+      throw new Exception(
+        'Missing helper: "' + arguments[arguments.length - 1].name + '"'
+      );
     }
   });
 }
diff --git a/lib/handlebars/helpers/if.js b/lib/handlebars/helpers/if.js
index 5be88b70a..55241ecb7 100644
--- a/lib/handlebars/helpers/if.js
+++ b/lib/handlebars/helpers/if.js
@@ -3,8 +3,12 @@ import Exception from '../exception';
 
 export default function(instance) {
   instance.registerHelper('if', function(conditional, options) {
-    if (arguments.length != 2) { throw new Exception('#if requires exactly one argument');}
-    if (isFunction(conditional)) { conditional = conditional.call(this); }
+    if (arguments.length != 2) {
+      throw new Exception('#if requires exactly one argument');
+    }
+    if (isFunction(conditional)) {
+      conditional = conditional.call(this);
+    }
 
     // Default behavior is to render the positive path if the value is truthy and not empty.
     // The `includeZero` option may be set to treat the condtional as purely not empty based on the
@@ -17,7 +21,13 @@ export default function(instance) {
   });
 
   instance.registerHelper('unless', function(conditional, options) {
-    if (arguments.length != 2) { throw new Exception('#unless requires exactly one argument');}
-    return instance.helpers['if'].call(this, conditional, {fn: options.inverse, inverse: options.fn, hash: options.hash});
+    if (arguments.length != 2) {
+      throw new Exception('#unless requires exactly one argument');
+    }
+    return instance.helpers['if'].call(this, conditional, {
+      fn: options.inverse,
+      inverse: options.fn,
+      hash: options.hash
+    });
   });
 }
diff --git a/lib/handlebars/helpers/log.js b/lib/handlebars/helpers/log.js
index 4bde4a10d..ab0d73646 100644
--- a/lib/handlebars/helpers/log.js
+++ b/lib/handlebars/helpers/log.js
@@ -1,7 +1,7 @@
 export default function(instance) {
   instance.registerHelper('log', function(/* message, options */) {
     let args = [undefined],
-        options = arguments[arguments.length - 1];
+      options = arguments[arguments.length - 1];
     for (let i = 0; i < arguments.length - 1; i++) {
       args.push(arguments[i]);
     }
@@ -14,6 +14,6 @@ export default function(instance) {
     }
     args[0] = level;
 
-    instance.log(... args);
+    instance.log(...args);
   });
 }
diff --git a/lib/handlebars/helpers/lookup.js b/lib/handlebars/helpers/lookup.js
index 8c1b604be..66de538b6 100644
--- a/lib/handlebars/helpers/lookup.js
+++ b/lib/handlebars/helpers/lookup.js
@@ -5,7 +5,10 @@ export default function(instance) {
     if (!obj) {
       return obj;
     }
-    if (dangerousPropertyRegex.test(String(field)) && !Object.prototype.propertyIsEnumerable.call(obj, field)) {
+    if (
+      dangerousPropertyRegex.test(String(field)) &&
+      !Object.prototype.propertyIsEnumerable.call(obj, field)
+    ) {
       return undefined;
     }
     return obj[field];
diff --git a/lib/handlebars/helpers/with.js b/lib/handlebars/helpers/with.js
index cfeab4240..eb1cf1a90 100644
--- a/lib/handlebars/helpers/with.js
+++ b/lib/handlebars/helpers/with.js
@@ -1,10 +1,20 @@
-import { appendContextPath, blockParams, createFrame, isEmpty, isFunction } from '../utils';
+import {
+  appendContextPath,
+  blockParams,
+  createFrame,
+  isEmpty,
+  isFunction
+} from '../utils';
 import Exception from '../exception';
 
 export default function(instance) {
   instance.registerHelper('with', function(context, options) {
-    if (arguments.length != 2) { throw new Exception('#with requires exactly one argument');}
-    if (isFunction(context)) { context = context.call(this); }
+    if (arguments.length != 2) {
+      throw new Exception('#with requires exactly one argument');
+    }
+    if (isFunction(context)) {
+      context = context.call(this);
+    }
 
     let fn = options.fn;
 
@@ -12,7 +22,10 @@ export default function(instance) {
       let data = options.data;
       if (options.data && options.ids) {
         data = createFrame(options.data);
-        data.contextPath = appendContextPath(options.data.contextPath, options.ids[0]);
+        data.contextPath = appendContextPath(
+          options.data.contextPath,
+          options.ids[0]
+        );
       }
 
       return fn(context, {
diff --git a/lib/handlebars/logger.js b/lib/handlebars/logger.js
index 1e916a995..bc411b250 100644
--- a/lib/handlebars/logger.js
+++ b/lib/handlebars/logger.js
@@ -1,4 +1,4 @@
-import {indexOf} from './utils';
+import { indexOf } from './utils';
 
 let logger = {
   methodMap: ['debug', 'info', 'warn', 'error'],
@@ -22,9 +22,13 @@ let logger = {
   log: function(level, ...message) {
     level = logger.lookupLevel(level);
 
-    if (typeof console !== 'undefined' && logger.lookupLevel(logger.level) <= level) {
+    if (
+      typeof console !== 'undefined' &&
+      logger.lookupLevel(logger.level) <= level
+    ) {
       let method = logger.methodMap[level];
-      if (!console[method]) { // eslint-disable-line no-console
+      // eslint-disable-next-line no-console
+      if (!console[method]) {
         method = 'log';
       }
       console[method](...message); // eslint-disable-line no-console
diff --git a/lib/handlebars/no-conflict.js b/lib/handlebars/no-conflict.js
index 40a44d7a6..618b750f0 100644
--- a/lib/handlebars/no-conflict.js
+++ b/lib/handlebars/no-conflict.js
@@ -1,8 +1,7 @@
-/* global window */
 export default function(Handlebars) {
   /* istanbul ignore next */
   let root = typeof global !== 'undefined' ? global : window,
-      $Handlebars = root.Handlebars;
+    $Handlebars = root.Handlebars;
   /* istanbul ignore next */
   Handlebars.noConflict = function() {
     if (root.Handlebars === Handlebars) {
diff --git a/lib/handlebars/runtime.js b/lib/handlebars/runtime.js
index 59b1cc106..4d67895af 100644
--- a/lib/handlebars/runtime.js
+++ b/lib/handlebars/runtime.js
@@ -1,30 +1,47 @@
 import * as Utils from './utils';
 import Exception from './exception';
-import {COMPILER_REVISION, createFrame, LAST_COMPATIBLE_COMPILER_REVISION, REVISION_CHANGES} from './base';
-import {moveHelperToHooks} from './helpers';
+import {
+  COMPILER_REVISION,
+  createFrame,
+  LAST_COMPATIBLE_COMPILER_REVISION,
+  REVISION_CHANGES
+} from './base';
+import { moveHelperToHooks } from './helpers';
 
 export function checkRevision(compilerInfo) {
-  const compilerRevision = compilerInfo && compilerInfo[0] || 1,
-        currentRevision = COMPILER_REVISION;
+  const compilerRevision = (compilerInfo && compilerInfo[0]) || 1,
+    currentRevision = COMPILER_REVISION;
 
-  if (compilerRevision >= LAST_COMPATIBLE_COMPILER_REVISION && compilerRevision <= COMPILER_REVISION) {
+  if (
+    compilerRevision >= LAST_COMPATIBLE_COMPILER_REVISION &&
+    compilerRevision <= COMPILER_REVISION
+  ) {
     return;
   }
 
   if (compilerRevision < LAST_COMPATIBLE_COMPILER_REVISION) {
     const runtimeVersions = REVISION_CHANGES[currentRevision],
-          compilerVersions = REVISION_CHANGES[compilerRevision];
-    throw new Exception('Template was precompiled with an older version of Handlebars than the current runtime. ' +
-          'Please update your precompiler to a newer version (' + runtimeVersions + ') or downgrade your runtime to an older version (' + compilerVersions + ').');
+      compilerVersions = REVISION_CHANGES[compilerRevision];
+    throw new Exception(
+      'Template was precompiled with an older version of Handlebars than the current runtime. ' +
+        'Please update your precompiler to a newer version (' +
+        runtimeVersions +
+        ') or downgrade your runtime to an older version (' +
+        compilerVersions +
+        ').'
+    );
   } else {
     // Use the embedded version info since the runtime doesn't know about this revision yet
-    throw new Exception('Template was precompiled with a newer version of Handlebars than the current runtime. ' +
-          'Please update your runtime to a newer version (' + compilerInfo[1] + ').');
+    throw new Exception(
+      'Template was precompiled with a newer version of Handlebars than the current runtime. ' +
+        'Please update your runtime to a newer version (' +
+        compilerInfo[1] +
+        ').'
+    );
   }
 }
 
 export function template(templateSpec, env) {
-
   /* istanbul ignore next */
   if (!env) {
     throw new Exception('No environment passed to template');
@@ -40,7 +57,8 @@ export function template(templateSpec, env) {
   env.VM.checkRevision(templateSpec.compiler);
 
   // backwards compatibility for precompiled templates with compiler-version 7 (<4.3.0)
-  const templateWasPrecompiledWithCompilerV7 = templateSpec.compiler && templateSpec.compiler[0] === 7;
+  const templateWasPrecompiledWithCompilerV7 =
+    templateSpec.compiler && templateSpec.compiler[0] === 7;
 
   function invokePartialWrapper(partial, context, options) {
     if (options.hash) {
@@ -51,12 +69,21 @@ export function template(templateSpec, env) {
     }
     partial = env.VM.resolvePartial.call(this, partial, context, options);
 
-    let optionsWithHooks = Utils.extend({}, options, {hooks: this.hooks});
+    let optionsWithHooks = Utils.extend({}, options, { hooks: this.hooks });
 
-    let result = env.VM.invokePartial.call(this, partial, context, optionsWithHooks);
+    let result = env.VM.invokePartial.call(
+      this,
+      partial,
+      context,
+      optionsWithHooks
+    );
 
     if (result == null && env.compile) {
-      options.partials[options.name] = env.compile(partial, templateSpec.compilerOptions, env);
+      options.partials[options.name] = env.compile(
+        partial,
+        templateSpec.compilerOptions,
+        env
+      );
       result = options.partials[options.name](context, optionsWithHooks);
     }
     if (result != null) {
@@ -73,7 +100,11 @@ export function template(templateSpec, env) {
       }
       return result;
     } else {
-      throw new Exception('The partial ' + options.name + ' could not be compiled when running in runtime-only mode');
+      throw new Exception(
+        'The partial ' +
+          options.name +
+          ' could not be compiled when running in runtime-only mode'
+      );
     }
   }
 
@@ -81,7 +112,9 @@ export function template(templateSpec, env) {
   let container = {
     strict: function(obj, name, loc) {
       if (!obj || !(name in obj)) {
-        throw new Exception('"' + name + '" not defined in ' + obj, { loc: loc });
+        throw new Exception('"' + name + '" not defined in ' + obj, {
+          loc: loc
+        });
       }
       return obj[name];
     },
@@ -109,9 +142,17 @@ export function template(templateSpec, env) {
     programs: [],
     program: function(i, data, declaredBlockParams, blockParams, depths) {
       let programWrapper = this.programs[i],
-          fn = this.fn(i);
+        fn = this.fn(i);
       if (data || depths || blockParams || declaredBlockParams) {
-        programWrapper = wrapProgram(this, i, fn, data, declaredBlockParams, blockParams, depths);
+        programWrapper = wrapProgram(
+          this,
+          i,
+          fn,
+          data,
+          declaredBlockParams,
+          blockParams,
+          depths
+        );
       } else if (!programWrapper) {
         programWrapper = this.programs[i] = wrapProgram(this, i, fn);
       }
@@ -127,7 +168,7 @@ export function template(templateSpec, env) {
     mergeIfNeeded: function(param, common) {
       let obj = param || common;
 
-      if (param && common && (param !== common)) {
+      if (param && common && param !== common) {
         obj = Utils.extend({}, common, param);
       }
 
@@ -148,19 +189,40 @@ export function template(templateSpec, env) {
       data = initData(context, data);
     }
     let depths,
-        blockParams = templateSpec.useBlockParams ? [] : undefined;
+      blockParams = templateSpec.useBlockParams ? [] : undefined;
     if (templateSpec.useDepths) {
       if (options.depths) {
-        depths = context != options.depths[0] ? [context].concat(options.depths) : options.depths;
+        depths =
+          context != options.depths[0]
+            ? [context].concat(options.depths)
+            : options.depths;
       } else {
         depths = [context];
       }
     }
 
-    function main(context/*, options*/) {
-      return '' + templateSpec.main(container, context, container.helpers, container.partials, data, blockParams, depths);
+    function main(context /*, options*/) {
+      return (
+        '' +
+        templateSpec.main(
+          container,
+          context,
+          container.helpers,
+          container.partials,
+          data,
+          blockParams,
+          depths
+        )
+      );
     }
-    main = executeDecorators(templateSpec.main, main, container, options.depths || [], data, blockParams);
+    main = executeDecorators(
+      templateSpec.main,
+      main,
+      container,
+      options.depths || [],
+      data,
+      blockParams
+    );
     return main(context, options);
   }
   ret.isTop = true;
@@ -171,25 +233,32 @@ export function template(templateSpec, env) {
 
       if (templateSpec.usePartial) {
         // Use mergeIfNeeded here to prevent compiling global partials multiple times
-        container.partials = container.mergeIfNeeded(options.partials, env.partials);
+        container.partials = container.mergeIfNeeded(
+          options.partials,
+          env.partials
+        );
       }
       if (templateSpec.usePartial || templateSpec.useDecorators) {
-        container.decorators = Utils.extend({}, env.decorators, options.decorators);
+        container.decorators = Utils.extend(
+          {},
+          env.decorators,
+          options.decorators
+        );
       }
 
       container.hooks = {};
 
-      let keepHelperInHelpers = options.allowCallsToHelperMissing || templateWasPrecompiledWithCompilerV7;
+      let keepHelperInHelpers =
+        options.allowCallsToHelperMissing ||
+        templateWasPrecompiledWithCompilerV7;
       moveHelperToHooks(container, 'helperMissing', keepHelperInHelpers);
       moveHelperToHooks(container, 'blockHelperMissing', keepHelperInHelpers);
-
     } else {
       container.helpers = options.helpers;
       container.partials = options.partials;
       container.decorators = options.decorators;
       container.hooks = options.hooks;
     }
-
   };
 
   ret._child = function(i, data, blockParams, depths) {
@@ -200,24 +269,47 @@ export function template(templateSpec, env) {
       throw new Exception('must pass parent depths');
     }
 
-    return wrapProgram(container, i, templateSpec[i], data, 0, blockParams, depths);
+    return wrapProgram(
+      container,
+      i,
+      templateSpec[i],
+      data,
+      0,
+      blockParams,
+      depths
+    );
   };
   return ret;
 }
 
-export function wrapProgram(container, i, fn, data, declaredBlockParams, blockParams, depths) {
+export function wrapProgram(
+  container,
+  i,
+  fn,
+  data,
+  declaredBlockParams,
+  blockParams,
+  depths
+) {
   function prog(context, options = {}) {
     let currentDepths = depths;
-    if (depths && context != depths[0] && !(context === container.nullContext && depths[0] === null)) {
+    if (
+      depths &&
+      context != depths[0] &&
+      !(context === container.nullContext && depths[0] === null)
+    ) {
       currentDepths = [context].concat(depths);
     }
 
-    return fn(container,
-        context,
-        container.helpers, container.partials,
-        options.data || data,
-        blockParams && [options.blockParams].concat(blockParams),
-        currentDepths);
+    return fn(
+      container,
+      context,
+      container.helpers,
+      container.partials,
+      options.data || data,
+      blockParams && [options.blockParams].concat(blockParams),
+      currentDepths
+    );
   }
 
   prog = executeDecorators(fn, prog, container, depths, data, blockParams);
@@ -259,8 +351,10 @@ export function invokePartial(partial, context, options) {
     options.data = createFrame(options.data);
     // Wrapper function to get access to currentPartialBlock from the closure
     let fn = options.fn;
-    partialBlock = options.data['partial-block'] = function partialBlockWrapper(context, options = {}) {
-
+    partialBlock = options.data['partial-block'] = function partialBlockWrapper(
+      context,
+      options = {}
+    ) {
       // Restore the partial-block from the closure for the execution of the block
       // i.e. the part inside the block of the partial call.
       options.data = createFrame(options.data);
@@ -283,7 +377,9 @@ export function invokePartial(partial, context, options) {
   }
 }
 
-export function noop() { return ''; }
+export function noop() {
+  return '';
+}
 
 function initData(context, data) {
   if (!data || !('root' in data)) {
@@ -296,7 +392,15 @@ function initData(context, data) {
 function executeDecorators(fn, prog, container, depths, data, blockParams) {
   if (fn.decorator) {
     let props = {};
-    prog = fn.decorator(prog, props, container, depths && depths[0], data, blockParams, depths);
+    prog = fn.decorator(
+      prog,
+      props,
+      container,
+      depths && depths[0],
+      data,
+      blockParams,
+      depths
+    );
     Utils.extend(prog, props);
   }
   return prog;
diff --git a/lib/handlebars/utils.js b/lib/handlebars/utils.js
index 8e1a4014f..6fa43b23c 100644
--- a/lib/handlebars/utils.js
+++ b/lib/handlebars/utils.js
@@ -1,4 +1,3 @@
-
 const escape = {
   '&': '&amp;',
   '<': '&lt;',
@@ -10,13 +9,13 @@ const escape = {
 };
 
 const badChars = /[&<>"'`=]/g,
-      possible = /[&<>"'`=]/;
+  possible = /[&<>"'`=]/;
 
 function escapeChar(chr) {
   return escape[chr];
 }
 
-export function extend(obj/* , ...source */) {
+export function extend(obj /* , ...source */) {
   for (let i = 1; i < arguments.length; i++) {
     for (let key in arguments[i]) {
       if (Object.prototype.hasOwnProperty.call(arguments[i], key)) {
@@ -40,16 +39,23 @@ let isFunction = function(value) {
 /* istanbul ignore next */
 if (isFunction(/x/)) {
   isFunction = function(value) {
-    return typeof value === 'function' && toString.call(value) === '[object Function]';
+    return (
+      typeof value === 'function' &&
+      toString.call(value) === '[object Function]'
+    );
   };
 }
-export {isFunction};
+export { isFunction };
 /* eslint-enable func-style */
 
 /* istanbul ignore next */
-export const isArray = Array.isArray || function(value) {
-  return (value && typeof value === 'object') ? toString.call(value) === '[object Array]' : false;
-};
+export const isArray =
+  Array.isArray ||
+  function(value) {
+    return value && typeof value === 'object'
+      ? toString.call(value) === '[object Array]'
+      : false;
+  };
 
 // Older IE versions do not directly support indexOf so we must implement our own, sadly.
 export function indexOf(array, value) {
@@ -61,7 +67,6 @@ export function indexOf(array, value) {
   return -1;
 }
 
-
 export function escapeExpression(string) {
   if (typeof string !== 'string') {
     // don't escape SafeStrings, since they're already safe
@@ -79,7 +84,9 @@ export function escapeExpression(string) {
     string = '' + string;
   }
 
-  if (!possible.test(string)) { return string; }
+  if (!possible.test(string)) {
+    return string;
+  }
   return string.replace(badChars, escapeChar);
 }
 
diff --git a/lib/precompiler.js b/lib/precompiler.js
index ecf264eff..689c9f4d9 100644
--- a/lib/precompiler.js
+++ b/lib/precompiler.js
@@ -2,9 +2,8 @@
 import Async from 'neo-async';
 import fs from 'fs';
 import * as Handlebars from './handlebars';
-import {basename} from 'path';
-import {SourceMapConsumer, SourceNode} from 'source-map';
-
+import { basename } from 'path';
+import { SourceMapConsumer, SourceNode } from 'source-map';
 
 module.exports.loadTemplates = function(opts, callback) {
   loadStrings(opts, function(err, strings) {
@@ -25,14 +24,19 @@ module.exports.loadTemplates = function(opts, callback) {
 
 function loadStrings(opts, callback) {
   let strings = arrayCast(opts.string),
-      names = arrayCast(opts.name);
-
-  if (names.length !== strings.length
-      && strings.length > 1) {
-    return callback(new Handlebars.Exception('Number of names did not match the number of string inputs'));
+    names = arrayCast(opts.name);
+
+  if (names.length !== strings.length && strings.length > 1) {
+    return callback(
+      new Handlebars.Exception(
+        'Number of names did not match the number of string inputs'
+      )
+    );
   }
 
-  Async.map(strings, function(string, callback) {
+  Async.map(
+    strings,
+    function(string, callback) {
       if (string !== '-') {
         callback(undefined, string);
       } else {
@@ -55,80 +59,94 @@ function loadStrings(opts, callback) {
         source: string
       }));
       callback(err, strings);
-    });
+    }
+  );
 }
 
 function loadFiles(opts, callback) {
   // Build file extension pattern
-  let extension = (opts.extension || 'handlebars').replace(/[\\^$*+?.():=!|{}\-[\]]/g, function(arg) { return '\\' + arg; });
+  let extension = (opts.extension || 'handlebars').replace(
+    /[\\^$*+?.():=!|{}\-[\]]/g,
+    function(arg) {
+      return '\\' + arg;
+    }
+  );
   extension = new RegExp('\\.' + extension + '$');
 
   let ret = [],
-      queue = (opts.files || []).map((template) => ({template, root: opts.root}));
-  Async.whilst(() => queue.length, function(callback) {
-    let {template: path, root} = queue.shift();
+    queue = (opts.files || []).map(template => ({ template, root: opts.root }));
+  Async.whilst(
+    () => queue.length,
+    function(callback) {
+      let { template: path, root } = queue.shift();
 
-    fs.stat(path, function(err, stat) {
-      if (err) {
-        return callback(new Handlebars.Exception(`Unable to open template file "${path}"`));
-      }
-
-      if (stat.isDirectory()) {
-        opts.hasDirectory = true;
+      fs.stat(path, function(err, stat) {
+        if (err) {
+          return callback(
+            new Handlebars.Exception(`Unable to open template file "${path}"`)
+          );
+        }
 
-        fs.readdir(path, function(err, children) {
-          /* istanbul ignore next : Race condition that being too lazy to test */
-          if (err) {
-            return callback(err);
-          }
-          children.forEach(function(file) {
-            let childPath = path + '/' + file;
+        if (stat.isDirectory()) {
+          opts.hasDirectory = true;
 
-            if (extension.test(childPath) || fs.statSync(childPath).isDirectory()) {
-              queue.push({template: childPath, root: root || path});
+          fs.readdir(path, function(err, children) {
+            /* istanbul ignore next : Race condition that being too lazy to test */
+            if (err) {
+              return callback(err);
             }
+            children.forEach(function(file) {
+              let childPath = path + '/' + file;
+
+              if (
+                extension.test(childPath) ||
+                fs.statSync(childPath).isDirectory()
+              ) {
+                queue.push({ template: childPath, root: root || path });
+              }
+            });
+
+            callback();
           });
+        } else {
+          fs.readFile(path, 'utf8', function(err, data) {
+            /* istanbul ignore next : Race condition that being too lazy to test */
+            if (err) {
+              return callback(err);
+            }
 
-          callback();
-        });
-      } else {
-        fs.readFile(path, 'utf8', function(err, data) {
-          /* istanbul ignore next : Race condition that being too lazy to test */
-          if (err) {
-            return callback(err);
-          }
-
-          if (opts.bom && data.indexOf('\uFEFF') === 0) {
-            data = data.substring(1);
-          }
-
-          // Clean the template name
-          let name = path;
-          if (!root) {
-            name = basename(name);
-          } else if (name.indexOf(root) === 0) {
-            name = name.substring(root.length + 1);
-          }
-          name = name.replace(extension, '');
-
-          ret.push({
-            path: path,
-            name: name,
-            source: data
-          });
+            if (opts.bom && data.indexOf('\uFEFF') === 0) {
+              data = data.substring(1);
+            }
 
-          callback();
-        });
+            // Clean the template name
+            let name = path;
+            if (!root) {
+              name = basename(name);
+            } else if (name.indexOf(root) === 0) {
+              name = name.substring(root.length + 1);
+            }
+            name = name.replace(extension, '');
+
+            ret.push({
+              path: path,
+              name: name,
+              source: data
+            });
+
+            callback();
+          });
+        }
+      });
+    },
+    function(err) {
+      if (err) {
+        callback(err);
+      } else {
+        callback(undefined, ret);
       }
-    });
-  },
-  function(err) {
-    if (err) {
-      callback(err);
-    } else {
-      callback(undefined, ret);
     }
-  });
+  );
 }
 
 module.exports.cli = function(opts) {
@@ -138,7 +156,9 @@ module.exports.cli = function(opts) {
   }
 
   if (!opts.templates.length && !opts.hasDirectory) {
-    throw new Handlebars.Exception('Must define at least one template or directory.');
+    throw new Handlebars.Exception(
+      'Must define at least one template or directory.'
+    );
   }
 
   if (opts.simple && opts.min) {
@@ -147,12 +167,18 @@ module.exports.cli = function(opts) {
 
   const multiple = opts.templates.length !== 1 || opts.hasDirectory;
   if (opts.simple && multiple) {
-    throw new Handlebars.Exception('Unable to output multiple templates in simple mode');
+    throw new Handlebars.Exception(
+      'Unable to output multiple templates in simple mode'
+    );
   }
 
   // Force simple mode if we have only one template and it's unnamed.
-  if (!opts.amd && !opts.commonjs && opts.templates.length === 1
-      && !opts.templates[0].name) {
+  if (
+    !opts.amd &&
+    !opts.commonjs &&
+    opts.templates.length === 1 &&
+    !opts.templates[0].name
+  ) {
     opts.simple = true;
   }
 
@@ -172,7 +198,11 @@ module.exports.cli = function(opts) {
   let output = new SourceNode();
   if (!opts.simple) {
     if (opts.amd) {
-      output.add('define([\'' + opts.handlebarPath + 'handlebars.runtime\'], function(Handlebars) {\n  Handlebars = Handlebars["default"];');
+      output.add(
+        "define(['" +
+          opts.handlebarPath +
+          'handlebars.runtime\'], function(Handlebars) {\n  Handlebars = Handlebars["default"];'
+      );
     } else if (opts.commonjs) {
       output.add('var Handlebars = require("' + opts.commonjs + '");');
     } else {
@@ -206,7 +236,10 @@ module.exports.cli = function(opts) {
     // If we are generating a source map, we have to reconstruct the SourceNode object
     if (opts.map) {
       let consumer = new SourceMapConsumer(precompiled.map);
-      precompiled = SourceNode.fromStringWithSourceMap(precompiled.code, consumer);
+      precompiled = SourceNode.fromStringWithSourceMap(
+        precompiled.code,
+        consumer
+      );
     }
 
     if (opts.simple) {
@@ -219,7 +252,14 @@ module.exports.cli = function(opts) {
       if (opts.amd && !multiple) {
         output.add('return ');
       }
-      output.add([objectName, '[\'', template.name, '\'] = template(', precompiled, ');\n']);
+      output.add([
+        objectName,
+        "['",
+        template.name,
+        "'] = template(",
+        precompiled,
+        ');\n'
+      ]);
     }
   });
 
@@ -286,7 +326,9 @@ function minify(output, sourceMapFile) {
       throw e;
     }
     // it does not exist!
-    console.error('Code minimization is disabled due to missing uglify-js dependency');
+    console.error(
+      'Code minimization is disabled due to missing uglify-js dependency'
+    );
     return output;
   }
   return require('uglify-js').minify(output.code, {
diff --git a/spec/ast.js b/spec/ast.js
index ffd0a9589..1f4146ae0 100644
--- a/spec/ast.js
+++ b/spec/ast.js
@@ -7,44 +7,102 @@ describe('ast', function() {
 
   describe('BlockStatement', function() {
     it('should throw on mustache mismatch', function() {
-      shouldThrow(function() {
-        handlebarsEnv.parse('\n  {{#foo}}{{/bar}}');
-      }, Handlebars.Exception, "foo doesn't match bar - 2:5");
+      shouldThrow(
+        function() {
+          handlebarsEnv.parse('\n  {{#foo}}{{/bar}}');
+        },
+        Handlebars.Exception,
+        "foo doesn't match bar - 2:5"
+      );
     });
   });
 
   describe('helpers', function() {
     describe('#helperExpression', function() {
       it('should handle mustache statements', function() {
-        equals(AST.helpers.helperExpression({type: 'MustacheStatement', params: [], hash: undefined}), false);
-        equals(AST.helpers.helperExpression({type: 'MustacheStatement', params: [1], hash: undefined}), true);
-        equals(AST.helpers.helperExpression({type: 'MustacheStatement', params: [], hash: {}}), true);
+        equals(
+          AST.helpers.helperExpression({
+            type: 'MustacheStatement',
+            params: [],
+            hash: undefined
+          }),
+          false
+        );
+        equals(
+          AST.helpers.helperExpression({
+            type: 'MustacheStatement',
+            params: [1],
+            hash: undefined
+          }),
+          true
+        );
+        equals(
+          AST.helpers.helperExpression({
+            type: 'MustacheStatement',
+            params: [],
+            hash: {}
+          }),
+          true
+        );
       });
       it('should handle block statements', function() {
-        equals(AST.helpers.helperExpression({type: 'BlockStatement', params: [], hash: undefined}), false);
-        equals(AST.helpers.helperExpression({type: 'BlockStatement', params: [1], hash: undefined}), true);
-        equals(AST.helpers.helperExpression({type: 'BlockStatement', params: [], hash: {}}), true);
+        equals(
+          AST.helpers.helperExpression({
+            type: 'BlockStatement',
+            params: [],
+            hash: undefined
+          }),
+          false
+        );
+        equals(
+          AST.helpers.helperExpression({
+            type: 'BlockStatement',
+            params: [1],
+            hash: undefined
+          }),
+          true
+        );
+        equals(
+          AST.helpers.helperExpression({
+            type: 'BlockStatement',
+            params: [],
+            hash: {}
+          }),
+          true
+        );
       });
       it('should handle subexpressions', function() {
-        equals(AST.helpers.helperExpression({type: 'SubExpression'}), true);
+        equals(AST.helpers.helperExpression({ type: 'SubExpression' }), true);
       });
       it('should work with non-helper nodes', function() {
-        equals(AST.helpers.helperExpression({type: 'Program'}), false);
-
-        equals(AST.helpers.helperExpression({type: 'PartialStatement'}), false);
-        equals(AST.helpers.helperExpression({type: 'ContentStatement'}), false);
-        equals(AST.helpers.helperExpression({type: 'CommentStatement'}), false);
-
-        equals(AST.helpers.helperExpression({type: 'PathExpression'}), false);
-
-        equals(AST.helpers.helperExpression({type: 'StringLiteral'}), false);
-        equals(AST.helpers.helperExpression({type: 'NumberLiteral'}), false);
-        equals(AST.helpers.helperExpression({type: 'BooleanLiteral'}), false);
-        equals(AST.helpers.helperExpression({type: 'UndefinedLiteral'}), false);
-        equals(AST.helpers.helperExpression({type: 'NullLiteral'}), false);
-
-        equals(AST.helpers.helperExpression({type: 'Hash'}), false);
-        equals(AST.helpers.helperExpression({type: 'HashPair'}), false);
+        equals(AST.helpers.helperExpression({ type: 'Program' }), false);
+
+        equals(
+          AST.helpers.helperExpression({ type: 'PartialStatement' }),
+          false
+        );
+        equals(
+          AST.helpers.helperExpression({ type: 'ContentStatement' }),
+          false
+        );
+        equals(
+          AST.helpers.helperExpression({ type: 'CommentStatement' }),
+          false
+        );
+
+        equals(AST.helpers.helperExpression({ type: 'PathExpression' }), false);
+
+        equals(AST.helpers.helperExpression({ type: 'StringLiteral' }), false);
+        equals(AST.helpers.helperExpression({ type: 'NumberLiteral' }), false);
+        equals(AST.helpers.helperExpression({ type: 'BooleanLiteral' }), false);
+        equals(
+          AST.helpers.helperExpression({ type: 'UndefinedLiteral' }),
+          false
+        );
+        equals(AST.helpers.helperExpression({ type: 'NullLiteral' }), false);
+
+        equals(AST.helpers.helperExpression({ type: 'Hash' }), false);
+        equals(AST.helpers.helperExpression({ type: 'HashPair' }), false);
       });
     });
   });
@@ -61,17 +119,18 @@ describe('ast', function() {
 
     /* eslint-disable no-multi-spaces */
     ast = Handlebars.parse(
-              'line 1 {{line1Token}}\n'             // 1
-            + ' line 2 {{line2token}}\n'            // 2
-            + ' line 3 {{#blockHelperOnLine3}}\n'   // 3
-            + 'line 4{{line4token}}\n'              // 4
-            + 'line5{{else}}\n'                     // 5
-            + '{{line6Token}}\n'                    // 6
-            + '{{/blockHelperOnLine3}}\n'           // 7
-            + '{{#open}}\n'                         // 8
-            + '{{else inverse}}\n'                  // 9
-            + '{{else}}\n'                          // 10
-            + '{{/open}}');                         // 11
+      'line 1 {{line1Token}}\n' + // 1
+      ' line 2 {{line2token}}\n' + // 2
+      ' line 3 {{#blockHelperOnLine3}}\n' + // 3
+      'line 4{{line4token}}\n' + // 4
+      'line5{{else}}\n' + // 5
+      '{{line6Token}}\n' + // 6
+      '{{/blockHelperOnLine3}}\n' + // 7
+      '{{#open}}\n' + // 8
+      '{{else inverse}}\n' + // 9
+      '{{else}}\n' + // 10
+        '{{/open}}'
+    ); // 11
     /* eslint-enable no-multi-spaces */
     body = ast.body;
 
@@ -92,35 +151,35 @@ describe('ast', function() {
     it('gets MustacheStatement line numbers correct across newlines', function() {
       var secondMustacheStatement = body[3];
       testColumns(secondMustacheStatement, 2, 2, 8, 22);
-     });
+    });
 
-     it('gets the block helper information correct', function() {
-       var blockHelperNode = body[5];
-       testColumns(blockHelperNode, 3, 7, 8, 23);
-     });
+    it('gets the block helper information correct', function() {
+      var blockHelperNode = body[5];
+      testColumns(blockHelperNode, 3, 7, 8, 23);
+    });
 
-     it('correctly records the line numbers the program of a block helper', function() {
-       var blockHelperNode = body[5],
-           program = blockHelperNode.program;
+    it('correctly records the line numbers the program of a block helper', function() {
+      var blockHelperNode = body[5],
+        program = blockHelperNode.program;
 
-       testColumns(program, 3, 5, 31, 5);
-     });
+      testColumns(program, 3, 5, 31, 5);
+    });
 
-     it('correctly records the line numbers of an inverse of a block helper', function() {
-       var blockHelperNode = body[5],
-           inverse = blockHelperNode.inverse;
+    it('correctly records the line numbers of an inverse of a block helper', function() {
+      var blockHelperNode = body[5],
+        inverse = blockHelperNode.inverse;
 
-       testColumns(inverse, 5, 7, 13, 0);
-     });
+      testColumns(inverse, 5, 7, 13, 0);
+    });
 
-     it('correctly records the line number of chained inverses', function() {
-       var chainInverseNode = body[7];
+    it('correctly records the line number of chained inverses', function() {
+      var chainInverseNode = body[7];
 
-       testColumns(chainInverseNode.program, 8, 9, 9, 0);
-       testColumns(chainInverseNode.inverse, 9, 10, 16, 0);
-       testColumns(chainInverseNode.inverse.body[0].program, 9, 10, 16, 0);
-       testColumns(chainInverseNode.inverse.body[0].inverse, 10, 11, 8, 0);
-     });
+      testColumns(chainInverseNode.program, 8, 9, 9, 0);
+      testColumns(chainInverseNode.inverse, 9, 10, 16, 0);
+      testColumns(chainInverseNode.inverse.body[0].program, 9, 10, 16, 0);
+      testColumns(chainInverseNode.inverse.body[0].inverse, 10, 11, 8, 0);
+    });
   });
 
   describe('whitespace control', function() {
@@ -149,7 +208,9 @@ describe('ast', function() {
       });
 
       it('block statements', function() {
-        var ast = Handlebars.parseWithoutProcessing(' {{# comment~}} \nfoo\n {{~/comment}}');
+        var ast = Handlebars.parseWithoutProcessing(
+          ' {{# comment~}} \nfoo\n {{~/comment}}'
+        );
 
         equals(ast.body[0].value, ' ');
         equals(ast.body[1].program.body[0].value, ' \nfoo\n ');
@@ -167,7 +228,9 @@ describe('ast', function() {
     });
     describe('blocks - parseWithoutProcessing', function() {
       it('block mustaches', function() {
-        var ast = Handlebars.parseWithoutProcessing(' {{# comment}} \nfoo\n {{else}} \n  bar \n  {{/comment}} '),
+        var ast = Handlebars.parseWithoutProcessing(
+            ' {{# comment}} \nfoo\n {{else}} \n  bar \n  {{/comment}} '
+          ),
           block = ast.body[1];
 
         equals(ast.body[0].value, ' ');
@@ -178,13 +241,17 @@ describe('ast', function() {
         equals(ast.body[2].value, ' ');
       });
       it('initial block mustaches', function() {
-        var ast = Handlebars.parseWithoutProcessing('{{# comment}} \nfoo\n {{/comment}}'),
+        var ast = Handlebars.parseWithoutProcessing(
+            '{{# comment}} \nfoo\n {{/comment}}'
+          ),
           block = ast.body[0];
 
         equals(block.program.body[0].value, ' \nfoo\n ');
       });
       it('mustaches with children', function() {
-        var ast = Handlebars.parseWithoutProcessing('{{# comment}} \n{{foo}}\n {{/comment}}'),
+        var ast = Handlebars.parseWithoutProcessing(
+            '{{# comment}} \n{{foo}}\n {{/comment}}'
+          ),
           block = ast.body[0];
 
         equals(block.program.body[0].value, ' \n');
@@ -192,7 +259,9 @@ describe('ast', function() {
         equals(block.program.body[2].value, '\n ');
       });
       it('nested block mustaches', function() {
-        var ast = Handlebars.parseWithoutProcessing('{{#foo}} \n{{# comment}} \nfoo\n {{else}} \n  bar \n  {{/comment}} \n{{/foo}}'),
+        var ast = Handlebars.parseWithoutProcessing(
+            '{{#foo}} \n{{# comment}} \nfoo\n {{else}} \n  bar \n  {{/comment}} \n{{/foo}}'
+          ),
           body = ast.body[0].program.body,
           block = body[1];
 
@@ -202,8 +271,10 @@ describe('ast', function() {
         equals(block.inverse.body[0].value, ' \n  bar \n  ');
       });
       it('column 0 block mustaches', function() {
-        var ast = Handlebars.parseWithoutProcessing('test\n{{# comment}} \nfoo\n {{else}} \n  bar \n  {{/comment}} '),
-            block = ast.body[1];
+        var ast = Handlebars.parseWithoutProcessing(
+            'test\n{{# comment}} \nfoo\n {{else}} \n  bar \n  {{/comment}} '
+          ),
+          block = ast.body[1];
 
         equals(ast.body[0].omit, undefined);
 
@@ -215,8 +286,10 @@ describe('ast', function() {
     });
     describe('blocks', function() {
       it('marks block mustaches as standalone', function() {
-        var ast = Handlebars.parse(' {{# comment}} \nfoo\n {{else}} \n  bar \n  {{/comment}} '),
-            block = ast.body[1];
+        var ast = Handlebars.parse(
+            ' {{# comment}} \nfoo\n {{else}} \n  bar \n  {{/comment}} '
+          ),
+          block = ast.body[1];
 
         equals(ast.body[0].value, '');
 
@@ -227,22 +300,24 @@ describe('ast', function() {
       });
       it('marks initial block mustaches as standalone', function() {
         var ast = Handlebars.parse('{{# comment}} \nfoo\n {{/comment}}'),
-            block = ast.body[0];
+          block = ast.body[0];
 
         equals(block.program.body[0].value, 'foo\n');
       });
       it('marks mustaches with children as standalone', function() {
         var ast = Handlebars.parse('{{# comment}} \n{{foo}}\n {{/comment}}'),
-            block = ast.body[0];
+          block = ast.body[0];
 
         equals(block.program.body[0].value, '');
         equals(block.program.body[1].path.original, 'foo');
         equals(block.program.body[2].value, '\n');
       });
       it('marks nested block mustaches as standalone', function() {
-        var ast = Handlebars.parse('{{#foo}} \n{{# comment}} \nfoo\n {{else}} \n  bar \n  {{/comment}} \n{{/foo}}'),
-            body = ast.body[0].program.body,
-            block = body[1];
+        var ast = Handlebars.parse(
+            '{{#foo}} \n{{# comment}} \nfoo\n {{else}} \n  bar \n  {{/comment}} \n{{/foo}}'
+          ),
+          body = ast.body[0].program.body,
+          block = body[1];
 
         equals(body[0].value, '');
 
@@ -252,9 +327,11 @@ describe('ast', function() {
         equals(body[0].value, '');
       });
       it('does not mark nested block mustaches as standalone', function() {
-        var ast = Handlebars.parse('{{#foo}} {{# comment}} \nfoo\n {{else}} \n  bar \n  {{/comment}} {{/foo}}'),
-            body = ast.body[0].program.body,
-            block = body[1];
+        var ast = Handlebars.parse(
+            '{{#foo}} {{# comment}} \nfoo\n {{else}} \n  bar \n  {{/comment}} {{/foo}}'
+          ),
+          body = ast.body[0].program.body,
+          block = body[1];
 
         equals(body[0].omit, undefined);
 
@@ -264,9 +341,11 @@ describe('ast', function() {
         equals(body[0].omit, undefined);
       });
       it('does not mark nested initial block mustaches as standalone', function() {
-        var ast = Handlebars.parse('{{#foo}}{{# comment}} \nfoo\n {{else}} \n  bar \n  {{/comment}}{{/foo}}'),
-            body = ast.body[0].program.body,
-            block = body[0];
+        var ast = Handlebars.parse(
+            '{{#foo}}{{# comment}} \nfoo\n {{else}} \n  bar \n  {{/comment}}{{/foo}}'
+          ),
+          body = ast.body[0].program.body,
+          block = body[0];
 
         equals(block.program.body[0].value, ' \nfoo\n');
         equals(block.inverse.body[0].value, '  bar \n  ');
@@ -275,8 +354,10 @@ describe('ast', function() {
       });
 
       it('marks column 0 block mustaches as standalone', function() {
-        var ast = Handlebars.parse('test\n{{# comment}} \nfoo\n {{else}} \n  bar \n  {{/comment}} '),
-            block = ast.body[1];
+        var ast = Handlebars.parse(
+            'test\n{{# comment}} \nfoo\n {{else}} \n  bar \n  {{/comment}} '
+          ),
+          block = ast.body[1];
 
         equals(ast.body[0].omit, undefined);
 
@@ -348,4 +429,3 @@ describe('ast', function() {
     });
   });
 });
-
diff --git a/spec/basic.js b/spec/basic.js
index e4b253665..65d228729 100644
--- a/spec/basic.js
+++ b/spec/basic.js
@@ -18,8 +18,12 @@ describe('basic context', function() {
   });
 
   it('compiling with a basic context', function() {
-    shouldCompileTo('Goodbye\n{{cruel}}\n{{world}}!', {cruel: 'cruel', world: 'world'}, 'Goodbye\ncruel\nworld!',
-                    'It works if all the required keys are provided');
+    shouldCompileTo(
+      'Goodbye\n{{cruel}}\n{{world}}!',
+      { cruel: 'cruel', world: 'world' },
+      'Goodbye\ncruel\nworld!',
+      'It works if all the required keys are provided'
+    );
   });
 
   it('compiling with a string context', function() {
@@ -27,15 +31,26 @@ describe('basic context', function() {
   });
 
   it('compiling with an undefined context', function() {
-    shouldCompileTo('Goodbye\n{{cruel}}\n{{world.bar}}!', undefined, 'Goodbye\n\n!');
+    shouldCompileTo(
+      'Goodbye\n{{cruel}}\n{{world.bar}}!',
+      undefined,
+      'Goodbye\n\n!'
+    );
 
-    shouldCompileTo('{{#unless foo}}Goodbye{{../test}}{{test2}}{{/unless}}', undefined, 'Goodbye');
+    shouldCompileTo(
+      '{{#unless foo}}Goodbye{{../test}}{{test2}}{{/unless}}',
+      undefined,
+      'Goodbye'
+    );
   });
 
   it('comments', function() {
-    shouldCompileTo('{{! Goodbye}}Goodbye\n{{cruel}}\n{{world}}!',
-      {cruel: 'cruel', world: 'world'}, 'Goodbye\ncruel\nworld!',
-      'comments are ignored');
+    shouldCompileTo(
+      '{{! Goodbye}}Goodbye\n{{cruel}}\n{{world}}!',
+      { cruel: 'cruel', world: 'world' },
+      'Goodbye\ncruel\nworld!',
+      'comments are ignored'
+    );
 
     shouldCompileTo('    {{~! comment ~}}      blah', {}, 'blah');
     shouldCompileTo('    {{~!-- long-comment --~}}      blah', {}, 'blah');
@@ -47,237 +62,506 @@ describe('basic context', function() {
 
   it('boolean', function() {
     var string = '{{#goodbye}}GOODBYE {{/goodbye}}cruel {{world}}!';
-    shouldCompileTo(string, {goodbye: true, world: 'world'}, 'GOODBYE cruel world!',
-                    'booleans show the contents when true');
+    shouldCompileTo(
+      string,
+      { goodbye: true, world: 'world' },
+      'GOODBYE cruel world!',
+      'booleans show the contents when true'
+    );
 
-    shouldCompileTo(string, {goodbye: false, world: 'world'}, 'cruel world!',
-                    'booleans do not show the contents when false');
+    shouldCompileTo(
+      string,
+      { goodbye: false, world: 'world' },
+      'cruel world!',
+      'booleans do not show the contents when false'
+    );
   });
 
   it('zeros', function() {
-    shouldCompileTo('num1: {{num1}}, num2: {{num2}}', {num1: 42, num2: 0},
-        'num1: 42, num2: 0');
+    shouldCompileTo(
+      'num1: {{num1}}, num2: {{num2}}',
+      { num1: 42, num2: 0 },
+      'num1: 42, num2: 0'
+    );
     shouldCompileTo('num: {{.}}', 0, 'num: 0');
-    shouldCompileTo('num: {{num1/num2}}', {num1: {num2: 0}}, 'num: 0');
+    shouldCompileTo('num: {{num1/num2}}', { num1: { num2: 0 } }, 'num: 0');
   });
   it('false', function() {
     /* eslint-disable no-new-wrappers */
-    shouldCompileTo('val1: {{val1}}, val2: {{val2}}', {val1: false, val2: new Boolean(false)}, 'val1: false, val2: false');
+    shouldCompileTo(
+      'val1: {{val1}}, val2: {{val2}}',
+      { val1: false, val2: new Boolean(false) },
+      'val1: false, val2: false'
+    );
     shouldCompileTo('val: {{.}}', false, 'val: false');
-    shouldCompileTo('val: {{val1/val2}}', {val1: {val2: false}}, 'val: false');
+    shouldCompileTo(
+      'val: {{val1/val2}}',
+      { val1: { val2: false } },
+      'val: false'
+    );
 
-    shouldCompileTo('val1: {{{val1}}}, val2: {{{val2}}}', {val1: false, val2: new Boolean(false)}, 'val1: false, val2: false');
-    shouldCompileTo('val: {{{val1/val2}}}', {val1: {val2: false}}, 'val: false');
+    shouldCompileTo(
+      'val1: {{{val1}}}, val2: {{{val2}}}',
+      { val1: false, val2: new Boolean(false) },
+      'val1: false, val2: false'
+    );
+    shouldCompileTo(
+      'val: {{{val1/val2}}}',
+      { val1: { val2: false } },
+      'val: false'
+    );
     /* eslint-enable */
   });
 
   it('should handle undefined and null', function() {
-    shouldCompileTo('{{awesome undefined null}}',
-        {
-          awesome: function(_undefined, _null, options) {
-            return (_undefined === undefined) + ' ' + (_null === null) + ' ' + (typeof options);
-          }
-        },
-        'true true object');
-    shouldCompileTo('{{undefined}}',
-        {
-          'undefined': function() {
-            return 'undefined!';
-          }
-        },
-        'undefined!');
-    shouldCompileTo('{{null}}',
-        {
-          'null': function() {
-            return 'null!';
-          }
-        },
-        'null!');
+    shouldCompileTo(
+      '{{awesome undefined null}}',
+      {
+        awesome: function(_undefined, _null, options) {
+          return (
+            (_undefined === undefined) +
+            ' ' +
+            (_null === null) +
+            ' ' +
+            typeof options
+          );
+        }
+      },
+      'true true object'
+    );
+    shouldCompileTo(
+      '{{undefined}}',
+      {
+        undefined: function() {
+          return 'undefined!';
+        }
+      },
+      'undefined!'
+    );
+    shouldCompileTo(
+      '{{null}}',
+      {
+        null: function() {
+          return 'null!';
+        }
+      },
+      'null!'
+    );
   });
 
   it('newlines', function() {
-      shouldCompileTo("Alan's\nTest", {}, "Alan's\nTest");
-      shouldCompileTo("Alan's\rTest", {}, "Alan's\rTest");
+    shouldCompileTo("Alan's\nTest", {}, "Alan's\nTest");
+    shouldCompileTo("Alan's\rTest", {}, "Alan's\rTest");
   });
 
   it('escaping text', function() {
-    shouldCompileTo("Awesome's", {}, "Awesome's", "text is escaped so that it doesn't get caught on single quotes");
-    shouldCompileTo('Awesome\\', {}, 'Awesome\\', "text is escaped so that the closing quote can't be ignored");
-    shouldCompileTo('Awesome\\\\ foo', {}, 'Awesome\\\\ foo', "text is escaped so that it doesn't mess up backslashes");
-    shouldCompileTo('Awesome {{foo}}', {foo: '\\'}, 'Awesome \\', "text is escaped so that it doesn't mess up backslashes");
-    shouldCompileTo(" ' ' ", {}, " ' ' ", 'double quotes never produce invalid javascript');
+    shouldCompileTo(
+      "Awesome's",
+      {},
+      "Awesome's",
+      "text is escaped so that it doesn't get caught on single quotes"
+    );
+    shouldCompileTo(
+      'Awesome\\',
+      {},
+      'Awesome\\',
+      "text is escaped so that the closing quote can't be ignored"
+    );
+    shouldCompileTo(
+      'Awesome\\\\ foo',
+      {},
+      'Awesome\\\\ foo',
+      "text is escaped so that it doesn't mess up backslashes"
+    );
+    shouldCompileTo(
+      'Awesome {{foo}}',
+      { foo: '\\' },
+      'Awesome \\',
+      "text is escaped so that it doesn't mess up backslashes"
+    );
+    shouldCompileTo(
+      " ' ' ",
+      {},
+      " ' ' ",
+      'double quotes never produce invalid javascript'
+    );
   });
 
   it('escaping expressions', function() {
-   shouldCompileTo('{{{awesome}}}', {awesome: '&\'\\<>'}, '&\'\\<>',
-          "expressions with 3 handlebars aren't escaped");
+    shouldCompileTo(
+      '{{{awesome}}}',
+      { awesome: "&'\\<>" },
+      "&'\\<>",
+      "expressions with 3 handlebars aren't escaped"
+    );
 
-   shouldCompileTo('{{&awesome}}', {awesome: '&\'\\<>'}, '&\'\\<>',
-          "expressions with {{& handlebars aren't escaped");
+    shouldCompileTo(
+      '{{&awesome}}',
+      { awesome: "&'\\<>" },
+      "&'\\<>",
+      "expressions with {{& handlebars aren't escaped"
+    );
 
-   shouldCompileTo('{{awesome}}', {awesome: "&\"'`\\<>"}, '&amp;&quot;&#x27;&#x60;\\&lt;&gt;',
-          'by default expressions should be escaped');
+    shouldCompileTo(
+      '{{awesome}}',
+      { awesome: '&"\'`\\<>' },
+      '&amp;&quot;&#x27;&#x60;\\&lt;&gt;',
+      'by default expressions should be escaped'
+    );
 
-   shouldCompileTo('{{awesome}}', {awesome: 'Escaped, <b> looks like: &lt;b&gt;'}, 'Escaped, &lt;b&gt; looks like: &amp;lt;b&amp;gt;',
-          'escaping should properly handle amperstands');
+    shouldCompileTo(
+      '{{awesome}}',
+      { awesome: 'Escaped, <b> looks like: &lt;b&gt;' },
+      'Escaped, &lt;b&gt; looks like: &amp;lt;b&amp;gt;',
+      'escaping should properly handle amperstands'
+    );
   });
 
   it("functions returning safestrings shouldn't be escaped", function() {
-    var hash = {awesome: function() { return new Handlebars.SafeString('&\'\\<>'); }};
-    shouldCompileTo('{{awesome}}', hash, '&\'\\<>',
-        "functions returning safestrings aren't escaped");
+    var hash = {
+      awesome: function() {
+        return new Handlebars.SafeString("&'\\<>");
+      }
+    };
+    shouldCompileTo(
+      '{{awesome}}',
+      hash,
+      "&'\\<>",
+      "functions returning safestrings aren't escaped"
+    );
   });
 
   it('functions', function() {
-    shouldCompileTo('{{awesome}}', {awesome: function() { return 'Awesome'; }}, 'Awesome',
-                    'functions are called and render their output');
-    shouldCompileTo('{{awesome}}', {awesome: function() { return this.more; }, more: 'More awesome'}, 'More awesome',
-                    'functions are bound to the context');
+    shouldCompileTo(
+      '{{awesome}}',
+      {
+        awesome: function() {
+          return 'Awesome';
+        }
+      },
+      'Awesome',
+      'functions are called and render their output'
+    );
+    shouldCompileTo(
+      '{{awesome}}',
+      {
+        awesome: function() {
+          return this.more;
+        },
+        more: 'More awesome'
+      },
+      'More awesome',
+      'functions are bound to the context'
+    );
   });
 
   it('functions with context argument', function() {
-    shouldCompileTo('{{awesome frank}}',
-        {awesome: function(context) { return context; },
-          frank: 'Frank'},
-        'Frank', 'functions are called with context arguments');
+    shouldCompileTo(
+      '{{awesome frank}}',
+      {
+        awesome: function(context) {
+          return context;
+        },
+        frank: 'Frank'
+      },
+      'Frank',
+      'functions are called with context arguments'
+    );
   });
   it('pathed functions with context argument', function() {
-    shouldCompileTo('{{bar.awesome frank}}',
-        {bar: {awesome: function(context) { return context; }},
-          frank: 'Frank'},
-        'Frank', 'functions are called with context arguments');
+    shouldCompileTo(
+      '{{bar.awesome frank}}',
+      {
+        bar: {
+          awesome: function(context) {
+            return context;
+          }
+        },
+        frank: 'Frank'
+      },
+      'Frank',
+      'functions are called with context arguments'
+    );
   });
   it('depthed functions with context argument', function() {
-    shouldCompileTo('{{#with frank}}{{../awesome .}}{{/with}}',
-        {awesome: function(context) { return context; },
-          frank: 'Frank'},
-        'Frank', 'functions are called with context arguments');
+    shouldCompileTo(
+      '{{#with frank}}{{../awesome .}}{{/with}}',
+      {
+        awesome: function(context) {
+          return context;
+        },
+        frank: 'Frank'
+      },
+      'Frank',
+      'functions are called with context arguments'
+    );
   });
 
   it('block functions with context argument', function() {
-    shouldCompileTo('{{#awesome 1}}inner {{.}}{{/awesome}}',
-        {awesome: function(context, options) { return options.fn(context); }},
-        'inner 1', 'block functions are called with context and options');
+    shouldCompileTo(
+      '{{#awesome 1}}inner {{.}}{{/awesome}}',
+      {
+        awesome: function(context, options) {
+          return options.fn(context);
+        }
+      },
+      'inner 1',
+      'block functions are called with context and options'
+    );
   });
 
   it('depthed block functions with context argument', function() {
-    shouldCompileTo('{{#with value}}{{#../awesome 1}}inner {{.}}{{/../awesome}}{{/with}}',
-        {value: true, awesome: function(context, options) { return options.fn(context); }},
-        'inner 1', 'block functions are called with context and options');
+    shouldCompileTo(
+      '{{#with value}}{{#../awesome 1}}inner {{.}}{{/../awesome}}{{/with}}',
+      {
+        value: true,
+        awesome: function(context, options) {
+          return options.fn(context);
+        }
+      },
+      'inner 1',
+      'block functions are called with context and options'
+    );
   });
 
   it('block functions without context argument', function() {
-    shouldCompileTo('{{#awesome}}inner{{/awesome}}',
-        {awesome: function(options) { return options.fn(this); }},
-        'inner', 'block functions are called with options');
+    shouldCompileTo(
+      '{{#awesome}}inner{{/awesome}}',
+      {
+        awesome: function(options) {
+          return options.fn(this);
+        }
+      },
+      'inner',
+      'block functions are called with options'
+    );
   });
   it('pathed block functions without context argument', function() {
-    shouldCompileTo('{{#foo.awesome}}inner{{/foo.awesome}}',
-        {foo: {awesome: function() { return this; }}},
-        'inner', 'block functions are called with options');
+    shouldCompileTo(
+      '{{#foo.awesome}}inner{{/foo.awesome}}',
+      {
+        foo: {
+          awesome: function() {
+            return this;
+          }
+        }
+      },
+      'inner',
+      'block functions are called with options'
+    );
   });
   it('depthed block functions without context argument', function() {
-    shouldCompileTo('{{#with value}}{{#../awesome}}inner{{/../awesome}}{{/with}}',
-        {value: true, awesome: function() { return this; }},
-        'inner', 'block functions are called with options');
+    shouldCompileTo(
+      '{{#with value}}{{#../awesome}}inner{{/../awesome}}{{/with}}',
+      {
+        value: true,
+        awesome: function() {
+          return this;
+        }
+      },
+      'inner',
+      'block functions are called with options'
+    );
   });
 
-
   it('paths with hyphens', function() {
-    shouldCompileTo('{{foo-bar}}', {'foo-bar': 'baz'}, 'baz', 'Paths can contain hyphens (-)');
-    shouldCompileTo('{{foo.foo-bar}}', {foo: {'foo-bar': 'baz'}}, 'baz', 'Paths can contain hyphens (-)');
-    shouldCompileTo('{{foo/foo-bar}}', {foo: {'foo-bar': 'baz'}}, 'baz', 'Paths can contain hyphens (-)');
+    shouldCompileTo(
+      '{{foo-bar}}',
+      { 'foo-bar': 'baz' },
+      'baz',
+      'Paths can contain hyphens (-)'
+    );
+    shouldCompileTo(
+      '{{foo.foo-bar}}',
+      { foo: { 'foo-bar': 'baz' } },
+      'baz',
+      'Paths can contain hyphens (-)'
+    );
+    shouldCompileTo(
+      '{{foo/foo-bar}}',
+      { foo: { 'foo-bar': 'baz' } },
+      'baz',
+      'Paths can contain hyphens (-)'
+    );
   });
 
   it('nested paths', function() {
-    shouldCompileTo('Goodbye {{alan/expression}} world!', {alan: {expression: 'beautiful'}},
-                    'Goodbye beautiful world!', 'Nested paths access nested objects');
+    shouldCompileTo(
+      'Goodbye {{alan/expression}} world!',
+      { alan: { expression: 'beautiful' } },
+      'Goodbye beautiful world!',
+      'Nested paths access nested objects'
+    );
   });
 
   it('nested paths with empty string value', function() {
-    shouldCompileTo('Goodbye {{alan/expression}} world!', {alan: {expression: ''}},
-                    'Goodbye  world!', 'Nested paths access nested objects with empty string');
+    shouldCompileTo(
+      'Goodbye {{alan/expression}} world!',
+      { alan: { expression: '' } },
+      'Goodbye  world!',
+      'Nested paths access nested objects with empty string'
+    );
   });
 
   it('literal paths', function() {
-    shouldCompileTo('Goodbye {{[@alan]/expression}} world!', {'@alan': {expression: 'beautiful'}},
-        'Goodbye beautiful world!', 'Literal paths can be used');
-    shouldCompileTo('Goodbye {{[foo bar]/expression}} world!', {'foo bar': {expression: 'beautiful'}},
-        'Goodbye beautiful world!', 'Literal paths can be used');
+    shouldCompileTo(
+      'Goodbye {{[@alan]/expression}} world!',
+      { '@alan': { expression: 'beautiful' } },
+      'Goodbye beautiful world!',
+      'Literal paths can be used'
+    );
+    shouldCompileTo(
+      'Goodbye {{[foo bar]/expression}} world!',
+      { 'foo bar': { expression: 'beautiful' } },
+      'Goodbye beautiful world!',
+      'Literal paths can be used'
+    );
   });
 
   it('literal references', function() {
-    shouldCompileTo('Goodbye {{[foo bar]}} world!', {'foo bar': 'beautiful'}, 'Goodbye beautiful world!');
-    shouldCompileTo('Goodbye {{"foo bar"}} world!', {'foo bar': 'beautiful'}, 'Goodbye beautiful world!');
-    shouldCompileTo("Goodbye {{'foo bar'}} world!", {'foo bar': 'beautiful'}, 'Goodbye beautiful world!');
-    shouldCompileTo('Goodbye {{"foo[bar"}} world!', {'foo[bar': 'beautiful'}, 'Goodbye beautiful world!');
-    shouldCompileTo('Goodbye {{"foo\'bar"}} world!', {"foo'bar": 'beautiful'}, 'Goodbye beautiful world!');
-    shouldCompileTo("Goodbye {{'foo\"bar'}} world!", {'foo"bar': 'beautiful'}, 'Goodbye beautiful world!');
+    shouldCompileTo(
+      'Goodbye {{[foo bar]}} world!',
+      { 'foo bar': 'beautiful' },
+      'Goodbye beautiful world!'
+    );
+    shouldCompileTo(
+      'Goodbye {{"foo bar"}} world!',
+      { 'foo bar': 'beautiful' },
+      'Goodbye beautiful world!'
+    );
+    shouldCompileTo(
+      "Goodbye {{'foo bar'}} world!",
+      { 'foo bar': 'beautiful' },
+      'Goodbye beautiful world!'
+    );
+    shouldCompileTo(
+      'Goodbye {{"foo[bar"}} world!',
+      { 'foo[bar': 'beautiful' },
+      'Goodbye beautiful world!'
+    );
+    shouldCompileTo(
+      'Goodbye {{"foo\'bar"}} world!',
+      { "foo'bar": 'beautiful' },
+      'Goodbye beautiful world!'
+    );
+    shouldCompileTo(
+      "Goodbye {{'foo\"bar'}} world!",
+      { 'foo"bar': 'beautiful' },
+      'Goodbye beautiful world!'
+    );
   });
 
   it("that current context path ({{.}}) doesn't hit helpers", function() {
-    shouldCompileTo('test: {{.}}', [null, {helper: 'awesome'}], 'test: ');
+    shouldCompileTo('test: {{.}}', [null, { helper: 'awesome' }], 'test: ');
   });
 
   it('complex but empty paths', function() {
-    shouldCompileTo('{{person/name}}', {person: {name: null}}, '');
-    shouldCompileTo('{{person/name}}', {person: {}}, '');
+    shouldCompileTo('{{person/name}}', { person: { name: null } }, '');
+    shouldCompileTo('{{person/name}}', { person: {} }, '');
   });
 
   it('this keyword in paths', function() {
     var string = '{{#goodbyes}}{{this}}{{/goodbyes}}';
-    var hash = {goodbyes: ['goodbye', 'Goodbye', 'GOODBYE']};
-    shouldCompileTo(string, hash, 'goodbyeGoodbyeGOODBYE',
-      'This keyword in paths evaluates to current context');
+    var hash = { goodbyes: ['goodbye', 'Goodbye', 'GOODBYE'] };
+    shouldCompileTo(
+      string,
+      hash,
+      'goodbyeGoodbyeGOODBYE',
+      'This keyword in paths evaluates to current context'
+    );
 
     string = '{{#hellos}}{{this/text}}{{/hellos}}';
-    hash = {hellos: [{text: 'hello'}, {text: 'Hello'}, {text: 'HELLO'}]};
-    shouldCompileTo(string, hash, 'helloHelloHELLO', 'This keyword evaluates in more complex paths');
+    hash = {
+      hellos: [{ text: 'hello' }, { text: 'Hello' }, { text: 'HELLO' }]
+    };
+    shouldCompileTo(
+      string,
+      hash,
+      'helloHelloHELLO',
+      'This keyword evaluates in more complex paths'
+    );
   });
 
   it('this keyword nested inside path', function() {
-    shouldThrow(function() {
-      CompilerContext.compile('{{#hellos}}{{text/this/foo}}{{/hellos}}');
-    }, Error, 'Invalid path: text/this - 1:13');
+    shouldThrow(
+      function() {
+        CompilerContext.compile('{{#hellos}}{{text/this/foo}}{{/hellos}}');
+      },
+      Error,
+      'Invalid path: text/this - 1:13'
+    );
 
-    shouldCompileTo('{{[this]}}', {'this': 'bar'}, 'bar');
-    shouldCompileTo('{{text/[this]}}', {text: {'this': 'bar'}}, 'bar');
+    shouldCompileTo('{{[this]}}', { this: 'bar' }, 'bar');
+    shouldCompileTo('{{text/[this]}}', { text: { this: 'bar' } }, 'bar');
   });
 
   it('this keyword in helpers', function() {
-    var helpers = {foo: function(value) {
+    var helpers = {
+      foo: function(value) {
         return 'bar ' + value;
-    }};
+      }
+    };
     var string = '{{#goodbyes}}{{foo this}}{{/goodbyes}}';
-    var hash = {goodbyes: ['goodbye', 'Goodbye', 'GOODBYE']};
-    shouldCompileTo(string, [hash, helpers], 'bar goodbyebar Goodbyebar GOODBYE',
-      'This keyword in paths evaluates to current context');
+    var hash = { goodbyes: ['goodbye', 'Goodbye', 'GOODBYE'] };
+    shouldCompileTo(
+      string,
+      [hash, helpers],
+      'bar goodbyebar Goodbyebar GOODBYE',
+      'This keyword in paths evaluates to current context'
+    );
 
     string = '{{#hellos}}{{foo this/text}}{{/hellos}}';
-    hash = {hellos: [{text: 'hello'}, {text: 'Hello'}, {text: 'HELLO'}]};
-    shouldCompileTo(string, [hash, helpers], 'bar hellobar Hellobar HELLO', 'This keyword evaluates in more complex paths');
+    hash = {
+      hellos: [{ text: 'hello' }, { text: 'Hello' }, { text: 'HELLO' }]
+    };
+    shouldCompileTo(
+      string,
+      [hash, helpers],
+      'bar hellobar Hellobar HELLO',
+      'This keyword evaluates in more complex paths'
+    );
   });
 
   it('this keyword nested inside helpers param', function() {
     var string = '{{#hellos}}{{foo text/this/foo}}{{/hellos}}';
-    shouldThrow(function() {
-      CompilerContext.compile(string);
-    }, Error, 'Invalid path: text/this - 1:17');
+    shouldThrow(
+      function() {
+        CompilerContext.compile(string);
+      },
+      Error,
+      'Invalid path: text/this - 1:17'
+    );
 
     shouldCompileTo(
-        '{{foo [this]}}',
-        {foo: function(value) { return value; }, 'this': 'bar'},
-        'bar');
+      '{{foo [this]}}',
+      {
+        foo: function(value) {
+          return value;
+        },
+        this: 'bar'
+      },
+      'bar'
+    );
     shouldCompileTo(
-        '{{foo text/[this]}}',
-        {foo: function(value) { return value; }, text: {'this': 'bar'}},
-        'bar');
+      '{{foo text/[this]}}',
+      {
+        foo: function(value) {
+          return value;
+        },
+        text: { this: 'bar' }
+      },
+      'bar'
+    );
   });
 
   it('pass string literals', function() {
     shouldCompileTo('{{"foo"}}', {}, '');
     shouldCompileTo('{{"foo"}}', { foo: 'bar' }, 'bar');
-    shouldCompileTo('{{#"foo"}}{{.}}{{/"foo"}}', { foo: ['bar', 'baz'] }, 'barbaz');
+    shouldCompileTo(
+      '{{#"foo"}}{{.}}{{/"foo"}}',
+      { foo: ['bar', 'baz'] },
+      'barbaz'
+    );
   });
 
   it('pass number literals', function() {
@@ -285,13 +569,21 @@ describe('basic context', function() {
     shouldCompileTo('{{12}}', { '12': 'bar' }, 'bar');
     shouldCompileTo('{{12.34}}', {}, '');
     shouldCompileTo('{{12.34}}', { '12.34': 'bar' }, 'bar');
-    shouldCompileTo('{{12.34 1}}', { '12.34': function(arg) { return 'bar' + arg; } }, 'bar1');
+    shouldCompileTo(
+      '{{12.34 1}}',
+      {
+        '12.34': function(arg) {
+          return 'bar' + arg;
+        }
+      },
+      'bar1'
+    );
   });
 
   it('pass boolean literals', function() {
     shouldCompileTo('{{true}}', {}, '');
     shouldCompileTo('{{true}}', { '': 'foo' }, '');
-    shouldCompileTo('{{false}}', { 'false': 'foo' }, 'foo');
+    shouldCompileTo('{{false}}', { false: 'foo' }, 'foo');
   });
 
   it('should handle literals in subexpression', function() {
@@ -300,6 +592,17 @@ describe('basic context', function() {
         return arg;
       }
     };
-    shouldCompileTo('{{foo (false)}}', [{ 'false': function() { return 'bar'; } }, helpers], 'bar');
+    shouldCompileTo(
+      '{{foo (false)}}',
+      [
+        {
+          false: function() {
+            return 'bar';
+          }
+        },
+        helpers
+      ],
+      'bar'
+    );
   });
 });
diff --git a/spec/blocks.js b/spec/blocks.js
index 2fbaee7cc..1ef2d1be2 100644
--- a/spec/blocks.js
+++ b/spec/blocks.js
@@ -1,51 +1,99 @@
 describe('blocks', function() {
   it('array', function() {
     var string = '{{#goodbyes}}{{text}}! {{/goodbyes}}cruel {{world}}!';
-    var hash = {goodbyes: [{text: 'goodbye'}, {text: 'Goodbye'}, {text: 'GOODBYE'}], world: 'world'};
-    shouldCompileTo(string, hash, 'goodbye! Goodbye! GOODBYE! cruel world!',
-                    'Arrays iterate over the contents when not empty');
-
-    shouldCompileTo(string, {goodbyes: [], world: 'world'}, 'cruel world!',
-                    'Arrays ignore the contents when empty');
+    var hash = {
+      goodbyes: [{ text: 'goodbye' }, { text: 'Goodbye' }, { text: 'GOODBYE' }],
+      world: 'world'
+    };
+    shouldCompileTo(
+      string,
+      hash,
+      'goodbye! Goodbye! GOODBYE! cruel world!',
+      'Arrays iterate over the contents when not empty'
+    );
+
+    shouldCompileTo(
+      string,
+      { goodbyes: [], world: 'world' },
+      'cruel world!',
+      'Arrays ignore the contents when empty'
+    );
   });
 
   it('array without data', function() {
-    var string = '{{#goodbyes}}{{text}}{{/goodbyes}} {{#goodbyes}}{{text}}{{/goodbyes}}';
-    var hash = {goodbyes: [{text: 'goodbye'}, {text: 'Goodbye'}, {text: 'GOODBYE'}], world: 'world'};
-    shouldCompileTo(string, [hash,,, false], 'goodbyeGoodbyeGOODBYE goodbyeGoodbyeGOODBYE');
+    var string =
+      '{{#goodbyes}}{{text}}{{/goodbyes}} {{#goodbyes}}{{text}}{{/goodbyes}}';
+    var hash = {
+      goodbyes: [{ text: 'goodbye' }, { text: 'Goodbye' }, { text: 'GOODBYE' }],
+      world: 'world'
+    };
+    shouldCompileTo(
+      string,
+      [hash, , , false],
+      'goodbyeGoodbyeGOODBYE goodbyeGoodbyeGOODBYE'
+    );
   });
 
   it('array with @index', function() {
-    var string = '{{#goodbyes}}{{@index}}. {{text}}! {{/goodbyes}}cruel {{world}}!';
-    var hash = {goodbyes: [{text: 'goodbye'}, {text: 'Goodbye'}, {text: 'GOODBYE'}], world: 'world'};
+    var string =
+      '{{#goodbyes}}{{@index}}. {{text}}! {{/goodbyes}}cruel {{world}}!';
+    var hash = {
+      goodbyes: [{ text: 'goodbye' }, { text: 'Goodbye' }, { text: 'GOODBYE' }],
+      world: 'world'
+    };
 
     var template = CompilerContext.compile(string);
     var result = template(hash);
 
-    equal(result, '0. goodbye! 1. Goodbye! 2. GOODBYE! cruel world!', 'The @index variable is used');
+    equal(
+      result,
+      '0. goodbye! 1. Goodbye! 2. GOODBYE! cruel world!',
+      'The @index variable is used'
+    );
   });
 
   it('empty block', function() {
     var string = '{{#goodbyes}}{{/goodbyes}}cruel {{world}}!';
-    var hash = {goodbyes: [{text: 'goodbye'}, {text: 'Goodbye'}, {text: 'GOODBYE'}], world: 'world'};
-    shouldCompileTo(string, hash, 'cruel world!',
-                    'Arrays iterate over the contents when not empty');
-
-    shouldCompileTo(string, {goodbyes: [], world: 'world'}, 'cruel world!',
-                    'Arrays ignore the contents when empty');
+    var hash = {
+      goodbyes: [{ text: 'goodbye' }, { text: 'Goodbye' }, { text: 'GOODBYE' }],
+      world: 'world'
+    };
+    shouldCompileTo(
+      string,
+      hash,
+      'cruel world!',
+      'Arrays iterate over the contents when not empty'
+    );
+
+    shouldCompileTo(
+      string,
+      { goodbyes: [], world: 'world' },
+      'cruel world!',
+      'Arrays ignore the contents when empty'
+    );
   });
 
   it('block with complex lookup', function() {
     var string = '{{#goodbyes}}{{text}} cruel {{../name}}! {{/goodbyes}}';
-    var hash = {name: 'Alan', goodbyes: [{text: 'goodbye'}, {text: 'Goodbye'}, {text: 'GOODBYE'}]};
-
-    shouldCompileTo(string, hash, 'goodbye cruel Alan! Goodbye cruel Alan! GOODBYE cruel Alan! ',
-                    'Templates can access variables in contexts up the stack with relative path syntax');
+    var hash = {
+      name: 'Alan',
+      goodbyes: [{ text: 'goodbye' }, { text: 'Goodbye' }, { text: 'GOODBYE' }]
+    };
+
+    shouldCompileTo(
+      string,
+      hash,
+      'goodbye cruel Alan! Goodbye cruel Alan! GOODBYE cruel Alan! ',
+      'Templates can access variables in contexts up the stack with relative path syntax'
+    );
   });
 
   it('multiple blocks with complex lookup', function() {
     var string = '{{#goodbyes}}{{../name}}{{../name}}{{/goodbyes}}';
-    var hash = {name: 'Alan', goodbyes: [{text: 'goodbye'}, {text: 'Goodbye'}, {text: 'GOODBYE'}]};
+    var hash = {
+      name: 'Alan',
+      goodbyes: [{ text: 'goodbye' }, { text: 'Goodbye' }, { text: 'GOODBYE' }]
+    };
 
     shouldCompileTo(string, hash, 'AlanAlanAlanAlanAlanAlan');
   });
@@ -59,111 +107,201 @@ describe('blocks', function() {
   });
 
   it('block with deep nested complex lookup', function() {
-    var string = '{{#outer}}Goodbye {{#inner}}cruel {{../sibling}} {{../../omg}}{{/inner}}{{/outer}}';
-    var hash = {omg: 'OMG!', outer: [{ sibling: 'sad', inner: [{ text: 'goodbye' }] }] };
+    var string =
+      '{{#outer}}Goodbye {{#inner}}cruel {{../sibling}} {{../../omg}}{{/inner}}{{/outer}}';
+    var hash = {
+      omg: 'OMG!',
+      outer: [{ sibling: 'sad', inner: [{ text: 'goodbye' }] }]
+    };
 
     shouldCompileTo(string, hash, 'Goodbye cruel sad OMG!');
   });
 
   it('works with cached blocks', function() {
-    var template = CompilerContext.compile('{{#each person}}{{#with .}}{{first}} {{last}}{{/with}}{{/each}}', {data: false});
-
-    var result = template({person: [{first: 'Alan', last: 'Johnson'}, {first: 'Alan', last: 'Johnson'}]});
+    var template = CompilerContext.compile(
+      '{{#each person}}{{#with .}}{{first}} {{last}}{{/with}}{{/each}}',
+      { data: false }
+    );
+
+    var result = template({
+      person: [
+        { first: 'Alan', last: 'Johnson' },
+        { first: 'Alan', last: 'Johnson' }
+      ]
+    });
     equals(result, 'Alan JohnsonAlan Johnson');
   });
 
   describe('inverted sections', function() {
     it('inverted sections with unset value', function() {
-      var string = '{{#goodbyes}}{{this}}{{/goodbyes}}{{^goodbyes}}Right On!{{/goodbyes}}';
+      var string =
+        '{{#goodbyes}}{{this}}{{/goodbyes}}{{^goodbyes}}Right On!{{/goodbyes}}';
       var hash = {};
-      shouldCompileTo(string, hash, 'Right On!', "Inverted section rendered when value isn't set.");
+      shouldCompileTo(
+        string,
+        hash,
+        'Right On!',
+        "Inverted section rendered when value isn't set."
+      );
     });
 
     it('inverted section with false value', function() {
-      var string = '{{#goodbyes}}{{this}}{{/goodbyes}}{{^goodbyes}}Right On!{{/goodbyes}}';
-      var hash = {goodbyes: false};
-      shouldCompileTo(string, hash, 'Right On!', 'Inverted section rendered when value is false.');
+      var string =
+        '{{#goodbyes}}{{this}}{{/goodbyes}}{{^goodbyes}}Right On!{{/goodbyes}}';
+      var hash = { goodbyes: false };
+      shouldCompileTo(
+        string,
+        hash,
+        'Right On!',
+        'Inverted section rendered when value is false.'
+      );
     });
 
     it('inverted section with empty set', function() {
-      var string = '{{#goodbyes}}{{this}}{{/goodbyes}}{{^goodbyes}}Right On!{{/goodbyes}}';
-      var hash = {goodbyes: []};
-      shouldCompileTo(string, hash, 'Right On!', 'Inverted section rendered when value is empty set.');
+      var string =
+        '{{#goodbyes}}{{this}}{{/goodbyes}}{{^goodbyes}}Right On!{{/goodbyes}}';
+      var hash = { goodbyes: [] };
+      shouldCompileTo(
+        string,
+        hash,
+        'Right On!',
+        'Inverted section rendered when value is empty set.'
+      );
     });
 
     it('block inverted sections', function() {
-      shouldCompileTo('{{#people}}{{name}}{{^}}{{none}}{{/people}}', {none: 'No people'},
-        'No people');
+      shouldCompileTo(
+        '{{#people}}{{name}}{{^}}{{none}}{{/people}}',
+        { none: 'No people' },
+        'No people'
+      );
     });
     it('chained inverted sections', function() {
-      shouldCompileTo('{{#people}}{{name}}{{else if none}}{{none}}{{/people}}', {none: 'No people'},
-        'No people');
-      shouldCompileTo('{{#people}}{{name}}{{else if nothere}}fail{{else unless nothere}}{{none}}{{/people}}', {none: 'No people'},
-        'No people');
-      shouldCompileTo('{{#people}}{{name}}{{else if none}}{{none}}{{else}}fail{{/people}}', {none: 'No people'},
-        'No people');
+      shouldCompileTo(
+        '{{#people}}{{name}}{{else if none}}{{none}}{{/people}}',
+        { none: 'No people' },
+        'No people'
+      );
+      shouldCompileTo(
+        '{{#people}}{{name}}{{else if nothere}}fail{{else unless nothere}}{{none}}{{/people}}',
+        { none: 'No people' },
+        'No people'
+      );
+      shouldCompileTo(
+        '{{#people}}{{name}}{{else if none}}{{none}}{{else}}fail{{/people}}',
+        { none: 'No people' },
+        'No people'
+      );
     });
     it('chained inverted sections with mismatch', function() {
       shouldThrow(function() {
-        shouldCompileTo('{{#people}}{{name}}{{else if none}}{{none}}{{/if}}', {none: 'No people'},
-          'No people');
+        shouldCompileTo(
+          '{{#people}}{{name}}{{else if none}}{{none}}{{/if}}',
+          { none: 'No people' },
+          'No people'
+        );
       }, Error);
     });
 
     it('block inverted sections with empty arrays', function() {
-      shouldCompileTo('{{#people}}{{name}}{{^}}{{none}}{{/people}}', {none: 'No people', people: []},
-        'No people');
+      shouldCompileTo(
+        '{{#people}}{{name}}{{^}}{{none}}{{/people}}',
+        { none: 'No people', people: [] },
+        'No people'
+      );
     });
   });
 
   describe('standalone sections', function() {
     it('block standalone else sections', function() {
-      shouldCompileTo('{{#people}}\n{{name}}\n{{^}}\n{{none}}\n{{/people}}\n', {none: 'No people'},
-        'No people\n');
-      shouldCompileTo('{{#none}}\n{{.}}\n{{^}}\n{{none}}\n{{/none}}\n', {none: 'No people'},
-        'No people\n');
-      shouldCompileTo('{{#people}}\n{{name}}\n{{^}}\n{{none}}\n{{/people}}\n', {none: 'No people'},
-        'No people\n');
+      shouldCompileTo(
+        '{{#people}}\n{{name}}\n{{^}}\n{{none}}\n{{/people}}\n',
+        { none: 'No people' },
+        'No people\n'
+      );
+      shouldCompileTo(
+        '{{#none}}\n{{.}}\n{{^}}\n{{none}}\n{{/none}}\n',
+        { none: 'No people' },
+        'No people\n'
+      );
+      shouldCompileTo(
+        '{{#people}}\n{{name}}\n{{^}}\n{{none}}\n{{/people}}\n',
+        { none: 'No people' },
+        'No people\n'
+      );
     });
     it('block standalone else sections can be disabled', function() {
       shouldCompileTo(
         '{{#people}}\n{{name}}\n{{^}}\n{{none}}\n{{/people}}\n',
-        [{none: 'No people'}, {}, {}, {ignoreStandalone: true}],
-        '\nNo people\n\n');
+        [{ none: 'No people' }, {}, {}, { ignoreStandalone: true }],
+        '\nNo people\n\n'
+      );
       shouldCompileTo(
         '{{#none}}\n{{.}}\n{{^}}\nFail\n{{/none}}\n',
-        [{none: 'No people'}, {}, {}, {ignoreStandalone: true}],
-        '\nNo people\n\n');
+        [{ none: 'No people' }, {}, {}, { ignoreStandalone: true }],
+        '\nNo people\n\n'
+      );
     });
     it('block standalone chained else sections', function() {
-      shouldCompileTo('{{#people}}\n{{name}}\n{{else if none}}\n{{none}}\n{{/people}}\n', {none: 'No people'},
-        'No people\n');
-      shouldCompileTo('{{#people}}\n{{name}}\n{{else if none}}\n{{none}}\n{{^}}\n{{/people}}\n', {none: 'No people'},
-        'No people\n');
+      shouldCompileTo(
+        '{{#people}}\n{{name}}\n{{else if none}}\n{{none}}\n{{/people}}\n',
+        { none: 'No people' },
+        'No people\n'
+      );
+      shouldCompileTo(
+        '{{#people}}\n{{name}}\n{{else if none}}\n{{none}}\n{{^}}\n{{/people}}\n',
+        { none: 'No people' },
+        'No people\n'
+      );
     });
     it('should handle nesting', function() {
-      shouldCompileTo('{{#data}}\n{{#if true}}\n{{.}}\n{{/if}}\n{{/data}}\nOK.', {data: [1, 3, 5]}, '1\n3\n5\nOK.');
+      shouldCompileTo(
+        '{{#data}}\n{{#if true}}\n{{.}}\n{{/if}}\n{{/data}}\nOK.',
+        { data: [1, 3, 5] },
+        '1\n3\n5\nOK.'
+      );
     });
   });
 
   describe('compat mode', function() {
     it('block with deep recursive lookup lookup', function() {
-      var string = '{{#outer}}Goodbye {{#inner}}cruel {{omg}}{{/inner}}{{/outer}}';
-      var hash = {omg: 'OMG!', outer: [{ inner: [{ text: 'goodbye' }] }] };
+      var string =
+        '{{#outer}}Goodbye {{#inner}}cruel {{omg}}{{/inner}}{{/outer}}';
+      var hash = { omg: 'OMG!', outer: [{ inner: [{ text: 'goodbye' }] }] };
 
-      shouldCompileTo(string, [hash, undefined, undefined, true], 'Goodbye cruel OMG!');
+      shouldCompileTo(
+        string,
+        [hash, undefined, undefined, true],
+        'Goodbye cruel OMG!'
+      );
     });
     it('block with deep recursive pathed lookup', function() {
-      var string = '{{#outer}}Goodbye {{#inner}}cruel {{omg.yes}}{{/inner}}{{/outer}}';
-      var hash = {omg: {yes: 'OMG!'}, outer: [{ inner: [{ yes: 'no', text: 'goodbye' }] }] };
+      var string =
+        '{{#outer}}Goodbye {{#inner}}cruel {{omg.yes}}{{/inner}}{{/outer}}';
+      var hash = {
+        omg: { yes: 'OMG!' },
+        outer: [{ inner: [{ yes: 'no', text: 'goodbye' }] }]
+      };
 
-      shouldCompileTo(string, [hash, undefined, undefined, true], 'Goodbye cruel OMG!');
+      shouldCompileTo(
+        string,
+        [hash, undefined, undefined, true],
+        'Goodbye cruel OMG!'
+      );
     });
     it('block with missed recursive lookup', function() {
-      var string = '{{#outer}}Goodbye {{#inner}}cruel {{omg.yes}}{{/inner}}{{/outer}}';
-      var hash = {omg: {no: 'OMG!'}, outer: [{ inner: [{ yes: 'no', text: 'goodbye' }] }] };
+      var string =
+        '{{#outer}}Goodbye {{#inner}}cruel {{omg.yes}}{{/inner}}{{/outer}}';
+      var hash = {
+        omg: { no: 'OMG!' },
+        outer: [{ inner: [{ yes: 'no', text: 'goodbye' }] }]
+      };
 
-      shouldCompileTo(string, [hash, undefined, undefined, true], 'Goodbye cruel ');
+      shouldCompileTo(
+        string,
+        [hash, undefined, undefined, true],
+        'Goodbye cruel '
+      );
     });
   });
 
@@ -181,9 +319,10 @@ describe('blocks', function() {
         }
       };
       shouldCompileTo(
-          '{{#helper}}{{*decorator}}{{/helper}}',
-          {hash: {}, helpers: helpers, decorators: decorators},
-          'success');
+        '{{#helper}}{{*decorator}}{{/helper}}',
+        { hash: {}, helpers: helpers, decorators: decorators },
+        'success'
+      );
     });
     it('should apply allow undefined return', function() {
       var helpers = {
@@ -197,9 +336,10 @@ describe('blocks', function() {
         }
       };
       shouldCompileTo(
-          '{{#helper}}{{*decorator}}suc{{/helper}}',
-          {hash: {}, helpers: helpers, decorators: decorators},
-          'success');
+        '{{#helper}}{{*decorator}}suc{{/helper}}',
+        { hash: {}, helpers: helpers, decorators: decorators },
+        'success'
+      );
     });
 
     it('should apply block decorators', function() {
@@ -215,9 +355,10 @@ describe('blocks', function() {
         }
       };
       shouldCompileTo(
-          '{{#helper}}{{#*decorator}}success{{/decorator}}{{/helper}}',
-          {hash: {}, helpers: helpers, decorators: decorators},
-          'success');
+        '{{#helper}}{{#*decorator}}success{{/decorator}}{{/helper}}',
+        { hash: {}, helpers: helpers, decorators: decorators },
+        'success'
+      );
     });
     it('should support nested decorators', function() {
       var helpers = {
@@ -235,9 +376,10 @@ describe('blocks', function() {
         }
       };
       shouldCompileTo(
-          '{{#helper}}{{#*decorator}}{{#*nested}}suc{{/nested}}cess{{/decorator}}{{/helper}}',
-          {hash: {}, helpers: helpers, decorators: decorators},
-          'success');
+        '{{#helper}}{{#*decorator}}{{#*nested}}suc{{/nested}}cess{{/decorator}}{{/helper}}',
+        { hash: {}, helpers: helpers, decorators: decorators },
+        'success'
+      );
     });
 
     it('should apply multiple decorators', function() {
@@ -253,9 +395,10 @@ describe('blocks', function() {
         }
       };
       shouldCompileTo(
-          '{{#helper}}{{#*decorator}}suc{{/decorator}}{{#*decorator}}cess{{/decorator}}{{/helper}}',
-          {hash: {}, helpers: helpers, decorators: decorators},
-          'success');
+        '{{#helper}}{{#*decorator}}suc{{/decorator}}{{#*decorator}}cess{{/decorator}}{{/helper}}',
+        { hash: {}, helpers: helpers, decorators: decorators },
+        'success'
+      );
     });
 
     it('should access parent variables', function() {
@@ -271,9 +414,10 @@ describe('blocks', function() {
         }
       };
       shouldCompileTo(
-          '{{#helper}}{{*decorator foo}}{{/helper}}',
-          {hash: {'foo': 'success'}, helpers: helpers, decorators: decorators},
-          'success');
+        '{{#helper}}{{*decorator foo}}{{/helper}}',
+        { hash: { foo: 'success' }, helpers: helpers, decorators: decorators },
+        'success'
+      );
     });
     it('should work with root program', function() {
       var run;
@@ -285,9 +429,10 @@ describe('blocks', function() {
         }
       };
       shouldCompileTo(
-          '{{*decorator "success"}}',
-          {hash: {'foo': 'success'}, decorators: decorators},
-          '');
+        '{{*decorator "success"}}',
+        { hash: { foo: 'success' }, decorators: decorators },
+        ''
+      );
       equals(run, true);
     });
     it('should fail when accessing variables from root', function() {
@@ -300,9 +445,10 @@ describe('blocks', function() {
         }
       };
       shouldCompileTo(
-          '{{*decorator foo}}',
-          {hash: {'foo': 'fail'}, decorators: decorators},
-          '');
+        '{{*decorator foo}}',
+        { hash: { foo: 'fail' }, decorators: decorators },
+        ''
+      );
       equals(run, true);
     });
 
@@ -335,12 +481,23 @@ describe('blocks', function() {
         equals(handlebarsEnv.decorators.bar, undefined);
       });
       it('fails with multiple and args', function() {
-        shouldThrow(function() {
-          handlebarsEnv.registerDecorator({
-            world: function() { return 'world!'; },
-            testHelper: function() { return 'found it!'; }
-          }, {});
-        }, Error, 'Arg not supported with multiple decorators');
+        shouldThrow(
+          function() {
+            handlebarsEnv.registerDecorator(
+              {
+                world: function() {
+                  return 'world!';
+                },
+                testHelper: function() {
+                  return 'found it!';
+                }
+              },
+              {}
+            );
+          },
+          Error,
+          'Arg not supported with multiple decorators'
+        );
       });
     });
   });
diff --git a/spec/builtins.js b/spec/builtins.js
index b29927f06..d6bc29868 100644
--- a/spec/builtins.js
+++ b/spec/builtins.js
@@ -2,64 +2,156 @@ describe('builtin helpers', function() {
   describe('#if', function() {
     it('if', function() {
       var string = '{{#if goodbye}}GOODBYE {{/if}}cruel {{world}}!';
-      shouldCompileTo(string, {goodbye: true, world: 'world'}, 'GOODBYE cruel world!',
-                      'if with boolean argument shows the contents when true');
-      shouldCompileTo(string, {goodbye: 'dummy', world: 'world'}, 'GOODBYE cruel world!',
-                      'if with string argument shows the contents');
-      shouldCompileTo(string, {goodbye: false, world: 'world'}, 'cruel world!',
-                      'if with boolean argument does not show the contents when false');
-      shouldCompileTo(string, {world: 'world'}, 'cruel world!',
-                      'if with undefined does not show the contents');
-      shouldCompileTo(string, {goodbye: ['foo'], world: 'world'}, 'GOODBYE cruel world!',
-                      'if with non-empty array shows the contents');
-      shouldCompileTo(string, {goodbye: [], world: 'world'}, 'cruel world!',
-                      'if with empty array does not show the contents');
-      shouldCompileTo(string, {goodbye: 0, world: 'world'}, 'cruel world!',
-                      'if with zero does not show the contents');
-      shouldCompileTo('{{#if goodbye includeZero=true}}GOODBYE {{/if}}cruel {{world}}!',
-                      {goodbye: 0, world: 'world'}, 'GOODBYE cruel world!',
-                      'if with zero does not show the contents');
+      shouldCompileTo(
+        string,
+        { goodbye: true, world: 'world' },
+        'GOODBYE cruel world!',
+        'if with boolean argument shows the contents when true'
+      );
+      shouldCompileTo(
+        string,
+        { goodbye: 'dummy', world: 'world' },
+        'GOODBYE cruel world!',
+        'if with string argument shows the contents'
+      );
+      shouldCompileTo(
+        string,
+        { goodbye: false, world: 'world' },
+        'cruel world!',
+        'if with boolean argument does not show the contents when false'
+      );
+      shouldCompileTo(
+        string,
+        { world: 'world' },
+        'cruel world!',
+        'if with undefined does not show the contents'
+      );
+      shouldCompileTo(
+        string,
+        { goodbye: ['foo'], world: 'world' },
+        'GOODBYE cruel world!',
+        'if with non-empty array shows the contents'
+      );
+      shouldCompileTo(
+        string,
+        { goodbye: [], world: 'world' },
+        'cruel world!',
+        'if with empty array does not show the contents'
+      );
+      shouldCompileTo(
+        string,
+        { goodbye: 0, world: 'world' },
+        'cruel world!',
+        'if with zero does not show the contents'
+      );
+      shouldCompileTo(
+        '{{#if goodbye includeZero=true}}GOODBYE {{/if}}cruel {{world}}!',
+        { goodbye: 0, world: 'world' },
+        'GOODBYE cruel world!',
+        'if with zero does not show the contents'
+      );
     });
 
     it('if with function argument', function() {
       var string = '{{#if goodbye}}GOODBYE {{/if}}cruel {{world}}!';
-      shouldCompileTo(string, {goodbye: function() {return true; }, world: 'world'}, 'GOODBYE cruel world!',
-                      'if with function shows the contents when function returns true');
-      shouldCompileTo(string, {goodbye: function() {return this.world; }, world: 'world'}, 'GOODBYE cruel world!',
-                      'if with function shows the contents when function returns string');
-      shouldCompileTo(string, {goodbye: function() {return false; }, world: 'world'}, 'cruel world!',
-                      'if with function does not show the contents when returns false');
-      shouldCompileTo(string, {goodbye: function() {return this.foo; }, world: 'world'}, 'cruel world!',
-                      'if with function does not show the contents when returns undefined');
+      shouldCompileTo(
+        string,
+        {
+          goodbye: function() {
+            return true;
+          },
+          world: 'world'
+        },
+        'GOODBYE cruel world!',
+        'if with function shows the contents when function returns true'
+      );
+      shouldCompileTo(
+        string,
+        {
+          goodbye: function() {
+            return this.world;
+          },
+          world: 'world'
+        },
+        'GOODBYE cruel world!',
+        'if with function shows the contents when function returns string'
+      );
+      shouldCompileTo(
+        string,
+        {
+          goodbye: function() {
+            return false;
+          },
+          world: 'world'
+        },
+        'cruel world!',
+        'if with function does not show the contents when returns false'
+      );
+      shouldCompileTo(
+        string,
+        {
+          goodbye: function() {
+            return this.foo;
+          },
+          world: 'world'
+        },
+        'cruel world!',
+        'if with function does not show the contents when returns undefined'
+      );
     });
 
     it('should not change the depth list', function() {
-      var string = '{{#with foo}}{{#if goodbye}}GOODBYE cruel {{../world}}!{{/if}}{{/with}}';
-      shouldCompileTo(string, {foo: {goodbye: true}, world: 'world'}, 'GOODBYE cruel world!');
+      var string =
+        '{{#with foo}}{{#if goodbye}}GOODBYE cruel {{../world}}!{{/if}}{{/with}}';
+      shouldCompileTo(
+        string,
+        { foo: { goodbye: true }, world: 'world' },
+        'GOODBYE cruel world!'
+      );
     });
   });
 
   describe('#with', function() {
     it('with', function() {
       var string = '{{#with person}}{{first}} {{last}}{{/with}}';
-      shouldCompileTo(string, {person: {first: 'Alan', last: 'Johnson'}}, 'Alan Johnson');
+      shouldCompileTo(
+        string,
+        { person: { first: 'Alan', last: 'Johnson' } },
+        'Alan Johnson'
+      );
     });
     it('with with function argument', function() {
       var string = '{{#with person}}{{first}} {{last}}{{/with}}';
-      shouldCompileTo(string, {person: function() { return {first: 'Alan', last: 'Johnson'}; }}, 'Alan Johnson');
+      shouldCompileTo(
+        string,
+        {
+          person: function() {
+            return { first: 'Alan', last: 'Johnson' };
+          }
+        },
+        'Alan Johnson'
+      );
     });
     it('with with else', function() {
-      var string = '{{#with person}}Person is present{{else}}Person is not present{{/with}}';
+      var string =
+        '{{#with person}}Person is present{{else}}Person is not present{{/with}}';
       shouldCompileTo(string, {}, 'Person is not present');
     });
     it('with provides block parameter', function() {
       var string = '{{#with person as |foo|}}{{foo.first}} {{last}}{{/with}}';
-      shouldCompileTo(string, {person: {first: 'Alan', last: 'Johnson'}}, 'Alan Johnson');
+      shouldCompileTo(
+        string,
+        { person: { first: 'Alan', last: 'Johnson' } },
+        'Alan Johnson'
+      );
     });
     it('works when data is disabled', function() {
-      var template = CompilerContext.compile('{{#with person as |foo|}}{{foo.first}} {{last}}{{/with}}', {data: false});
+      var template = CompilerContext.compile(
+        '{{#with person as |foo|}}{{foo.first}} {{last}}{{/with}}',
+        { data: false }
+      );
 
-      var result = template({person: {first: 'Alan', last: 'Johnson'}});
+      var result = template({ person: { first: 'Alan', last: 'Johnson' } });
       equals(result, 'Alan Johnson');
     });
   });
@@ -73,92 +165,179 @@ describe('builtin helpers', function() {
 
     it('each', function() {
       var string = '{{#each goodbyes}}{{text}}! {{/each}}cruel {{world}}!';
-      var hash = {goodbyes: [{text: 'goodbye'}, {text: 'Goodbye'}, {text: 'GOODBYE'}], world: 'world'};
-      shouldCompileTo(string, hash, 'goodbye! Goodbye! GOODBYE! cruel world!',
-                      'each with array argument iterates over the contents when not empty');
-      shouldCompileTo(string, {goodbyes: [], world: 'world'}, 'cruel world!',
-                      'each with array argument ignores the contents when empty');
+      var hash = {
+        goodbyes: [
+          { text: 'goodbye' },
+          { text: 'Goodbye' },
+          { text: 'GOODBYE' }
+        ],
+        world: 'world'
+      };
+      shouldCompileTo(
+        string,
+        hash,
+        'goodbye! Goodbye! GOODBYE! cruel world!',
+        'each with array argument iterates over the contents when not empty'
+      );
+      shouldCompileTo(
+        string,
+        { goodbyes: [], world: 'world' },
+        'cruel world!',
+        'each with array argument ignores the contents when empty'
+      );
     });
 
     it('each without data', function() {
       var string = '{{#each goodbyes}}{{text}}! {{/each}}cruel {{world}}!';
-      var hash = {goodbyes: [{text: 'goodbye'}, {text: 'Goodbye'}, {text: 'GOODBYE'}], world: 'world'};
-      shouldCompileTo(string, [hash,,,, false], 'goodbye! Goodbye! GOODBYE! cruel world!');
+      var hash = {
+        goodbyes: [
+          { text: 'goodbye' },
+          { text: 'Goodbye' },
+          { text: 'GOODBYE' }
+        ],
+        world: 'world'
+      };
+      shouldCompileTo(
+        string,
+        [hash, , , , false],
+        'goodbye! Goodbye! GOODBYE! cruel world!'
+      );
 
-      hash = {goodbyes: 'cruel', world: 'world'};
-      shouldCompileTo('{{#each .}}{{.}}{{/each}}', [hash,,,, false], 'cruelworld');
+      hash = { goodbyes: 'cruel', world: 'world' };
+      shouldCompileTo(
+        '{{#each .}}{{.}}{{/each}}',
+        [hash, , , , false],
+        'cruelworld'
+      );
     });
 
     it('each without context', function() {
       var string = '{{#each goodbyes}}{{text}}! {{/each}}cruel {{world}}!';
-      shouldCompileTo(string, [,,,, ], 'cruel !');
+      shouldCompileTo(string, [, , , ,], 'cruel !');
     });
 
     it('each with an object and @key', function() {
-      var string = '{{#each goodbyes}}{{@key}}. {{text}}! {{/each}}cruel {{world}}!';
+      var string =
+        '{{#each goodbyes}}{{@key}}. {{text}}! {{/each}}cruel {{world}}!';
 
       function Clazz() {
-        this['<b>#1</b>'] = {text: 'goodbye'};
-        this[2] = {text: 'GOODBYE'};
+        this['<b>#1</b>'] = { text: 'goodbye' };
+        this[2] = { text: 'GOODBYE' };
       }
       Clazz.prototype.foo = 'fail';
-      var hash = {goodbyes: new Clazz(), world: 'world'};
+      var hash = { goodbyes: new Clazz(), world: 'world' };
 
       // Object property iteration order is undefined according to ECMA spec,
       // so we need to check both possible orders
       // @see http://stackoverflow.com/questions/280713/elements-order-in-a-for-in-loop
       var actual = compileWithPartials(string, hash);
-      var expected1 = '&lt;b&gt;#1&lt;/b&gt;. goodbye! 2. GOODBYE! cruel world!';
-      var expected2 = '2. GOODBYE! &lt;b&gt;#1&lt;/b&gt;. goodbye! cruel world!';
+      var expected1 =
+        '&lt;b&gt;#1&lt;/b&gt;. goodbye! 2. GOODBYE! cruel world!';
+      var expected2 =
+        '2. GOODBYE! &lt;b&gt;#1&lt;/b&gt;. goodbye! cruel world!';
 
-      equals(actual === expected1 || actual === expected2, true, 'each with object argument iterates over the contents when not empty');
-      shouldCompileTo(string, {goodbyes: {}, world: 'world'}, 'cruel world!');
+      equals(
+        actual === expected1 || actual === expected2,
+        true,
+        'each with object argument iterates over the contents when not empty'
+      );
+      shouldCompileTo(string, { goodbyes: {}, world: 'world' }, 'cruel world!');
     });
 
     it('each with @index', function() {
-      var string = '{{#each goodbyes}}{{@index}}. {{text}}! {{/each}}cruel {{world}}!';
-      var hash = {goodbyes: [{text: 'goodbye'}, {text: 'Goodbye'}, {text: 'GOODBYE'}], world: 'world'};
+      var string =
+        '{{#each goodbyes}}{{@index}}. {{text}}! {{/each}}cruel {{world}}!';
+      var hash = {
+        goodbyes: [
+          { text: 'goodbye' },
+          { text: 'Goodbye' },
+          { text: 'GOODBYE' }
+        ],
+        world: 'world'
+      };
 
       var template = CompilerContext.compile(string);
       var result = template(hash);
 
-      equal(result, '0. goodbye! 1. Goodbye! 2. GOODBYE! cruel world!', 'The @index variable is used');
+      equal(
+        result,
+        '0. goodbye! 1. Goodbye! 2. GOODBYE! cruel world!',
+        'The @index variable is used'
+      );
     });
 
     it('each with nested @index', function() {
-      var string = '{{#each goodbyes}}{{@index}}. {{text}}! {{#each ../goodbyes}}{{@index}} {{/each}}After {{@index}} {{/each}}{{@index}}cruel {{world}}!';
-      var hash = {goodbyes: [{text: 'goodbye'}, {text: 'Goodbye'}, {text: 'GOODBYE'}], world: 'world'};
+      var string =
+        '{{#each goodbyes}}{{@index}}. {{text}}! {{#each ../goodbyes}}{{@index}} {{/each}}After {{@index}} {{/each}}{{@index}}cruel {{world}}!';
+      var hash = {
+        goodbyes: [
+          { text: 'goodbye' },
+          { text: 'Goodbye' },
+          { text: 'GOODBYE' }
+        ],
+        world: 'world'
+      };
 
       var template = CompilerContext.compile(string);
       var result = template(hash);
 
-      equal(result, '0. goodbye! 0 1 2 After 0 1. Goodbye! 0 1 2 After 1 2. GOODBYE! 0 1 2 After 2 cruel world!', 'The @index variable is used');
+      equal(
+        result,
+        '0. goodbye! 0 1 2 After 0 1. Goodbye! 0 1 2 After 1 2. GOODBYE! 0 1 2 After 2 cruel world!',
+        'The @index variable is used'
+      );
     });
 
     it('each with block params', function() {
-      var string = '{{#each goodbyes as |value index|}}{{index}}. {{value.text}}! {{#each ../goodbyes as |childValue childIndex|}} {{index}} {{childIndex}}{{/each}} After {{index}} {{/each}}{{index}}cruel {{world}}!';
-      var hash = {goodbyes: [{text: 'goodbye'}, {text: 'Goodbye'}], world: 'world'};
+      var string =
+        '{{#each goodbyes as |value index|}}{{index}}. {{value.text}}! {{#each ../goodbyes as |childValue childIndex|}} {{index}} {{childIndex}}{{/each}} After {{index}} {{/each}}{{index}}cruel {{world}}!';
+      var hash = {
+        goodbyes: [{ text: 'goodbye' }, { text: 'Goodbye' }],
+        world: 'world'
+      };
 
       var template = CompilerContext.compile(string);
       var result = template(hash);
 
-      equal(result, '0. goodbye!  0 0 0 1 After 0 1. Goodbye!  1 0 1 1 After 1 cruel world!');
+      equal(
+        result,
+        '0. goodbye!  0 0 0 1 After 0 1. Goodbye!  1 0 1 1 After 1 cruel world!'
+      );
     });
 
     it('each object with @index', function() {
-      var string = '{{#each goodbyes}}{{@index}}. {{text}}! {{/each}}cruel {{world}}!';
-      var hash = {goodbyes: {'a': {text: 'goodbye'}, b: {text: 'Goodbye'}, c: {text: 'GOODBYE'}}, world: 'world'};
+      var string =
+        '{{#each goodbyes}}{{@index}}. {{text}}! {{/each}}cruel {{world}}!';
+      var hash = {
+        goodbyes: {
+          a: { text: 'goodbye' },
+          b: { text: 'Goodbye' },
+          c: { text: 'GOODBYE' }
+        },
+        world: 'world'
+      };
 
       var template = CompilerContext.compile(string);
       var result = template(hash);
 
-      equal(result, '0. goodbye! 1. Goodbye! 2. GOODBYE! cruel world!', 'The @index variable is used');
+      equal(
+        result,
+        '0. goodbye! 1. Goodbye! 2. GOODBYE! cruel world!',
+        'The @index variable is used'
+      );
     });
 
-
     it('each with @first', function() {
-      var string = '{{#each goodbyes}}{{#if @first}}{{text}}! {{/if}}{{/each}}cruel {{world}}!';
-      var hash = {goodbyes: [{text: 'goodbye'}, {text: 'Goodbye'}, {text: 'GOODBYE'}], world: 'world'};
+      var string =
+        '{{#each goodbyes}}{{#if @first}}{{text}}! {{/if}}{{/each}}cruel {{world}}!';
+      var hash = {
+        goodbyes: [
+          { text: 'goodbye' },
+          { text: 'Goodbye' },
+          { text: 'GOODBYE' }
+        ],
+        world: 'world'
+      };
 
       var template = CompilerContext.compile(string);
       var result = template(hash);
@@ -167,18 +346,34 @@ describe('builtin helpers', function() {
     });
 
     it('each with nested @first', function() {
-      var string = '{{#each goodbyes}}({{#if @first}}{{text}}! {{/if}}{{#each ../goodbyes}}{{#if @first}}{{text}}!{{/if}}{{/each}}{{#if @first}} {{text}}!{{/if}}) {{/each}}cruel {{world}}!';
-      var hash = {goodbyes: [{text: 'goodbye'}, {text: 'Goodbye'}, {text: 'GOODBYE'}], world: 'world'};
+      var string =
+        '{{#each goodbyes}}({{#if @first}}{{text}}! {{/if}}{{#each ../goodbyes}}{{#if @first}}{{text}}!{{/if}}{{/each}}{{#if @first}} {{text}}!{{/if}}) {{/each}}cruel {{world}}!';
+      var hash = {
+        goodbyes: [
+          { text: 'goodbye' },
+          { text: 'Goodbye' },
+          { text: 'GOODBYE' }
+        ],
+        world: 'world'
+      };
 
       var template = CompilerContext.compile(string);
       var result = template(hash);
 
-      equal(result, '(goodbye! goodbye! goodbye!) (goodbye!) (goodbye!) cruel world!', 'The @first variable is used');
+      equal(
+        result,
+        '(goodbye! goodbye! goodbye!) (goodbye!) (goodbye!) cruel world!',
+        'The @first variable is used'
+      );
     });
 
     it('each object with @first', function() {
-      var string = '{{#each goodbyes}}{{#if @first}}{{text}}! {{/if}}{{/each}}cruel {{world}}!';
-      var hash = {goodbyes: {'foo': {text: 'goodbye'}, bar: {text: 'Goodbye'}}, world: 'world'};
+      var string =
+        '{{#each goodbyes}}{{#if @first}}{{text}}! {{/if}}{{/each}}cruel {{world}}!';
+      var hash = {
+        goodbyes: { foo: { text: 'goodbye' }, bar: { text: 'Goodbye' } },
+        world: 'world'
+      };
 
       var template = CompilerContext.compile(string);
       var result = template(hash);
@@ -187,8 +382,16 @@ describe('builtin helpers', function() {
     });
 
     it('each with @last', function() {
-      var string = '{{#each goodbyes}}{{#if @last}}{{text}}! {{/if}}{{/each}}cruel {{world}}!';
-      var hash = {goodbyes: [{text: 'goodbye'}, {text: 'Goodbye'}, {text: 'GOODBYE'}], world: 'world'};
+      var string =
+        '{{#each goodbyes}}{{#if @last}}{{text}}! {{/if}}{{/each}}cruel {{world}}!';
+      var hash = {
+        goodbyes: [
+          { text: 'goodbye' },
+          { text: 'Goodbye' },
+          { text: 'GOODBYE' }
+        ],
+        world: 'world'
+      };
 
       var template = CompilerContext.compile(string);
       var result = template(hash);
@@ -197,8 +400,12 @@ describe('builtin helpers', function() {
     });
 
     it('each object with @last', function() {
-      var string = '{{#each goodbyes}}{{#if @last}}{{text}}! {{/if}}{{/each}}cruel {{world}}!';
-      var hash = {goodbyes: {'foo': {text: 'goodbye'}, bar: {text: 'Goodbye'}}, world: 'world'};
+      var string =
+        '{{#each goodbyes}}{{#if @last}}{{text}}! {{/if}}{{/each}}cruel {{world}}!';
+      var hash = {
+        goodbyes: { foo: { text: 'goodbye' }, bar: { text: 'Goodbye' } },
+        world: 'world'
+      };
 
       var template = CompilerContext.compile(string);
       var result = template(hash);
@@ -207,37 +414,78 @@ describe('builtin helpers', function() {
     });
 
     it('each with nested @last', function() {
-      var string = '{{#each goodbyes}}({{#if @last}}{{text}}! {{/if}}{{#each ../goodbyes}}{{#if @last}}{{text}}!{{/if}}{{/each}}{{#if @last}} {{text}}!{{/if}}) {{/each}}cruel {{world}}!';
-      var hash = {goodbyes: [{text: 'goodbye'}, {text: 'Goodbye'}, {text: 'GOODBYE'}], world: 'world'};
+      var string =
+        '{{#each goodbyes}}({{#if @last}}{{text}}! {{/if}}{{#each ../goodbyes}}{{#if @last}}{{text}}!{{/if}}{{/each}}{{#if @last}} {{text}}!{{/if}}) {{/each}}cruel {{world}}!';
+      var hash = {
+        goodbyes: [
+          { text: 'goodbye' },
+          { text: 'Goodbye' },
+          { text: 'GOODBYE' }
+        ],
+        world: 'world'
+      };
 
       var template = CompilerContext.compile(string);
       var result = template(hash);
 
-      equal(result, '(GOODBYE!) (GOODBYE!) (GOODBYE! GOODBYE! GOODBYE!) cruel world!', 'The @last variable is used');
+      equal(
+        result,
+        '(GOODBYE!) (GOODBYE!) (GOODBYE! GOODBYE! GOODBYE!) cruel world!',
+        'The @last variable is used'
+      );
     });
 
     it('each with function argument', function() {
       var string = '{{#each goodbyes}}{{text}}! {{/each}}cruel {{world}}!';
-      var hash = {goodbyes: function() { return [{text: 'goodbye'}, {text: 'Goodbye'}, {text: 'GOODBYE'}]; }, world: 'world'};
-      shouldCompileTo(string, hash, 'goodbye! Goodbye! GOODBYE! cruel world!',
-                'each with array function argument iterates over the contents when not empty');
-      shouldCompileTo(string, {goodbyes: [], world: 'world'}, 'cruel world!',
-                'each with array function argument ignores the contents when empty');
+      var hash = {
+        goodbyes: function() {
+          return [
+            { text: 'goodbye' },
+            { text: 'Goodbye' },
+            { text: 'GOODBYE' }
+          ];
+        },
+        world: 'world'
+      };
+      shouldCompileTo(
+        string,
+        hash,
+        'goodbye! Goodbye! GOODBYE! cruel world!',
+        'each with array function argument iterates over the contents when not empty'
+      );
+      shouldCompileTo(
+        string,
+        { goodbyes: [], world: 'world' },
+        'cruel world!',
+        'each with array function argument ignores the contents when empty'
+      );
     });
 
     it('each object when last key is an empty string', function() {
-      var string = '{{#each goodbyes}}{{@index}}. {{text}}! {{/each}}cruel {{world}}!';
-      var hash = {goodbyes: {'a': {text: 'goodbye'}, b: {text: 'Goodbye'}, '': {text: 'GOODBYE'}}, world: 'world'};
+      var string =
+        '{{#each goodbyes}}{{@index}}. {{text}}! {{/each}}cruel {{world}}!';
+      var hash = {
+        goodbyes: {
+          a: { text: 'goodbye' },
+          b: { text: 'Goodbye' },
+          '': { text: 'GOODBYE' }
+        },
+        world: 'world'
+      };
 
       var template = CompilerContext.compile(string);
       var result = template(hash);
 
-      equal(result, '0. goodbye! 1. Goodbye! 2. GOODBYE! cruel world!', 'Empty string key is not skipped');
+      equal(
+        result,
+        '0. goodbye! 1. Goodbye! 2. GOODBYE! cruel world!',
+        'Empty string key is not skipped'
+      );
     });
 
     it('data passed to helpers', function() {
       var string = '{{#each letters}}{{this}}{{detectDataInsideEach}}{{/each}}';
-      var hash = {letters: ['a', 'b', 'c']};
+      var hash = { letters: ['a', 'b', 'c'] };
 
       var template = CompilerContext.compile(string);
       var result = template(hash, {
@@ -249,10 +497,16 @@ describe('builtin helpers', function() {
     });
 
     it('each on implicit context', function() {
-      shouldThrow(function() {
-        var template = CompilerContext.compile('{{#each}}{{text}}! {{/each}}cruel world!');
-        template({});
-      }, handlebarsEnv.Exception, 'Must pass iterator to #each');
+      shouldThrow(
+        function() {
+          var template = CompilerContext.compile(
+            '{{#each}}{{text}}! {{/each}}cruel world!'
+          );
+          template({});
+        },
+        handlebarsEnv.Exception,
+        'Must pass iterator to #each'
+      );
     });
 
     if (global.Symbol && global.Symbol.iterator) {
@@ -276,13 +530,25 @@ describe('builtin helpers', function() {
           return new Iterator(this.arr);
         };
         var string = '{{#each goodbyes}}{{text}}! {{/each}}cruel {{world}}!';
-        var goodbyes = new Iterable([{text: 'goodbye'}, {text: 'Goodbye'}, {text: 'GOODBYE'}]);
+        var goodbyes = new Iterable([
+          { text: 'goodbye' },
+          { text: 'Goodbye' },
+          { text: 'GOODBYE' }
+        ]);
         var goodbyesEmpty = new Iterable([]);
-        var hash = {goodbyes: goodbyes, world: 'world'};
-        shouldCompileTo(string, hash, 'goodbye! Goodbye! GOODBYE! cruel world!',
-          'each with array argument iterates over the contents when not empty');
-        shouldCompileTo(string, {goodbyes: goodbyesEmpty, world: 'world'}, 'cruel world!',
-          'each with array argument ignores the contents when empty');
+        var hash = { goodbyes: goodbyes, world: 'world' };
+        shouldCompileTo(
+          string,
+          hash,
+          'goodbye! Goodbye! GOODBYE! cruel world!',
+          'each with array argument iterates over the contents when not empty'
+        );
+        shouldCompileTo(
+          string,
+          { goodbyes: goodbyesEmpty, world: 'world' },
+          'cruel world!',
+          'each with array argument ignores the contents when empty'
+        );
       });
     }
   });
@@ -293,9 +559,7 @@ describe('builtin helpers', function() {
       return;
     }
 
-    var $log,
-        $info,
-        $error;
+    var $log, $info, $error;
     beforeEach(function() {
       $log = console.log;
       $info = console.info;
@@ -331,7 +595,7 @@ describe('builtin helpers', function() {
         logArg = arg;
       };
 
-      shouldCompileTo(string, [hash,,,, {level: '03'}], '');
+      shouldCompileTo(string, [hash, , , , { level: '03' }], '');
       equals('03', levelArg);
       equals('whee', logArg);
     });
@@ -367,13 +631,13 @@ describe('builtin helpers', function() {
         console.error = $error;
       };
 
-      shouldCompileTo(string, [hash,,,, {level: '03'}], '');
+      shouldCompileTo(string, [hash, , , , { level: '03' }], '');
       equals(true, called);
     });
     it('should handle missing logger', function() {
       var string = '{{log blah}}';
       var hash = { blah: 'whee' },
-          called = false;
+        called = false;
 
       console.error = undefined;
       console.log = function(log) {
@@ -382,7 +646,7 @@ describe('builtin helpers', function() {
         console.log = $log;
       };
 
-      shouldCompileTo(string, [hash,,,, {level: '03'}], '');
+      shouldCompileTo(string, [hash, , , , { level: '03' }], '');
       equals(true, called);
     });
 
@@ -396,12 +660,12 @@ describe('builtin helpers', function() {
         called = true;
       };
 
-      shouldCompileTo(string, [hash,,,, {level: 'error'}], '');
+      shouldCompileTo(string, [hash, , , , { level: 'error' }], '');
       equals(true, called);
 
       called = false;
 
-      shouldCompileTo(string, [hash,,,, {level: 'ERROR'}], '');
+      shouldCompileTo(string, [hash, , , , { level: 'ERROR' }], '');
       equals(true, called);
     });
     it('should handle hash log levels', function() {
@@ -449,11 +713,10 @@ describe('builtin helpers', function() {
     /* eslint-enable no-console */
   });
 
-
   describe('#lookup', function() {
     it('should lookup arbitrary content', function() {
       var string = '{{#each goodbyes}}{{lookup ../data .}}{{/each}}',
-          hash = {goodbyes: [0, 1], data: ['foo', 'bar']};
+        hash = { goodbyes: [0, 1], data: ['foo', 'bar'] };
 
       var template = CompilerContext.compile(string);
       var result = template(hash);
@@ -462,7 +725,7 @@ describe('builtin helpers', function() {
     });
     it('should not fail on undefined value', function() {
       var string = '{{#each goodbyes}}{{lookup ../bar .}}{{/each}}',
-          hash = {goodbyes: [0, 1], data: ['foo', 'bar']};
+        hash = { goodbyes: [0, 1], data: ['foo', 'bar'] };
 
       var template = CompilerContext.compile(string);
       var result = template(hash);
diff --git a/spec/compiler.js b/spec/compiler.js
index 3d37b5940..fe394b720 100644
--- a/spec/compiler.js
+++ b/spec/compiler.js
@@ -13,37 +13,84 @@ describe('compiler', function() {
       equal(compile('foo').equals(compile('foo')), true);
       equal(compile('{{foo}}').equals(compile('{{foo}}')), true);
       equal(compile('{{foo.bar}}').equals(compile('{{foo.bar}}')), true);
-      equal(compile('{{foo.bar baz "foo" true false bat=1}}').equals(compile('{{foo.bar baz "foo" true false bat=1}}')), true);
-      equal(compile('{{foo.bar (baz bat=1)}}').equals(compile('{{foo.bar (baz bat=1)}}')), true);
-      equal(compile('{{#foo}} {{/foo}}').equals(compile('{{#foo}} {{/foo}}')), true);
+      equal(
+        compile('{{foo.bar baz "foo" true false bat=1}}').equals(
+          compile('{{foo.bar baz "foo" true false bat=1}}')
+        ),
+        true
+      );
+      equal(
+        compile('{{foo.bar (baz bat=1)}}').equals(
+          compile('{{foo.bar (baz bat=1)}}')
+        ),
+        true
+      );
+      equal(
+        compile('{{#foo}} {{/foo}}').equals(compile('{{#foo}} {{/foo}}')),
+        true
+      );
     });
     it('should treat as not equal', function() {
       equal(compile('foo').equals(compile('bar')), false);
       equal(compile('{{foo}}').equals(compile('{{bar}}')), false);
       equal(compile('{{foo.bar}}').equals(compile('{{bar.bar}}')), false);
-      equal(compile('{{foo.bar baz bat=1}}').equals(compile('{{foo.bar bar bat=1}}')), false);
-      equal(compile('{{foo.bar (baz bat=1)}}').equals(compile('{{foo.bar (bar bat=1)}}')), false);
-      equal(compile('{{#foo}} {{/foo}}').equals(compile('{{#bar}} {{/bar}}')), false);
-      equal(compile('{{#foo}} {{/foo}}').equals(compile('{{#foo}} {{foo}}{{/foo}}')), false);
+      equal(
+        compile('{{foo.bar baz bat=1}}').equals(
+          compile('{{foo.bar bar bat=1}}')
+        ),
+        false
+      );
+      equal(
+        compile('{{foo.bar (baz bat=1)}}').equals(
+          compile('{{foo.bar (bar bat=1)}}')
+        ),
+        false
+      );
+      equal(
+        compile('{{#foo}} {{/foo}}').equals(compile('{{#bar}} {{/bar}}')),
+        false
+      );
+      equal(
+        compile('{{#foo}} {{/foo}}').equals(
+          compile('{{#foo}} {{foo}}{{/foo}}')
+        ),
+        false
+      );
     });
   });
 
   describe('#compile', function() {
     it('should fail with invalid input', function() {
-      shouldThrow(function() {
-        Handlebars.compile(null);
-      }, Error, 'You must pass a string or Handlebars AST to Handlebars.compile. You passed null');
-      shouldThrow(function() {
-        Handlebars.compile({});
-      }, Error, 'You must pass a string or Handlebars AST to Handlebars.compile. You passed [object Object]');
+      shouldThrow(
+        function() {
+          Handlebars.compile(null);
+        },
+        Error,
+        'You must pass a string or Handlebars AST to Handlebars.compile. You passed null'
+      );
+      shouldThrow(
+        function() {
+          Handlebars.compile({});
+        },
+        Error,
+        'You must pass a string or Handlebars AST to Handlebars.compile. You passed [object Object]'
+      );
     });
 
     it('should include the location in the error (row and column)', function() {
       try {
         Handlebars.compile(' \n  {{#if}}\n{{/def}}')();
-        equal(true, false, 'Statement must throw exception. This line should not be executed.');
+        equal(
+          true,
+          false,
+          'Statement must throw exception. This line should not be executed.'
+        );
       } catch (err) {
-        equal(err.message, 'if doesn\'t match def - 2:5', 'Checking error message');
+        equal(
+          err.message,
+          "if doesn't match def - 2:5",
+          'Checking error message'
+        );
         if (Object.getOwnPropertyDescriptor(err, 'column').writable) {
           // In Safari 8, the column-property is read-only. This means that even if it is set with defineProperty,
           // its value won't change (https://github.com/jquery/esprima/issues/1290#issuecomment-132455482)
@@ -57,17 +104,28 @@ describe('compiler', function() {
     it('should include the location as enumerable property', function() {
       try {
         Handlebars.compile(' \n  {{#if}}\n{{/def}}')();
-        equal(true, false, 'Statement must throw exception. This line should not be executed.');
+        equal(
+          true,
+          false,
+          'Statement must throw exception. This line should not be executed.'
+        );
       } catch (err) {
-        equal(Object.prototype.propertyIsEnumerable.call(err, 'column'), true, 'Checking error column');
+        equal(
+          Object.prototype.propertyIsEnumerable.call(err, 'column'),
+          true,
+          'Checking error column'
+        );
       }
     });
 
     it('can utilize AST instance', function() {
-      equal(Handlebars.compile({
-        type: 'Program',
-        body: [ {type: 'ContentStatement', value: 'Hello'}]
-      })(), 'Hello');
+      equal(
+        Handlebars.compile({
+          type: 'Program',
+          body: [{ type: 'ContentStatement', value: 'Hello' }]
+        })(),
+        'Hello'
+      );
     });
 
     it('can pass through an empty string', function() {
@@ -75,33 +133,52 @@ describe('compiler', function() {
     });
 
     it('should not modify the options.data property(GH-1327)', function() {
-      var options = {data: [{a: 'foo'}, {a: 'bar'}]};
+      var options = { data: [{ a: 'foo' }, { a: 'bar' }] };
       Handlebars.compile('{{#each data}}{{@index}}:{{a}} {{/each}}', options)();
-      equal(JSON.stringify(options, 0, 2), JSON.stringify({data: [{a: 'foo'}, {a: 'bar'}]}, 0, 2));
+      equal(
+        JSON.stringify(options, 0, 2),
+        JSON.stringify({ data: [{ a: 'foo' }, { a: 'bar' }] }, 0, 2)
+      );
     });
 
     it('should not modify the options.knownHelpers property(GH-1327)', function() {
-      var options = {knownHelpers: {}};
+      var options = { knownHelpers: {} };
       Handlebars.compile('{{#each data}}{{@index}}:{{a}} {{/each}}', options)();
-      equal(JSON.stringify(options, 0, 2), JSON.stringify({knownHelpers: {}}, 0, 2));
+      equal(
+        JSON.stringify(options, 0, 2),
+        JSON.stringify({ knownHelpers: {} }, 0, 2)
+      );
     });
   });
 
   describe('#precompile', function() {
     it('should fail with invalid input', function() {
-      shouldThrow(function() {
-        Handlebars.precompile(null);
-      }, Error, 'You must pass a string or Handlebars AST to Handlebars.precompile. You passed null');
-      shouldThrow(function() {
-        Handlebars.precompile({});
-      }, Error, 'You must pass a string or Handlebars AST to Handlebars.precompile. You passed [object Object]');
+      shouldThrow(
+        function() {
+          Handlebars.precompile(null);
+        },
+        Error,
+        'You must pass a string or Handlebars AST to Handlebars.precompile. You passed null'
+      );
+      shouldThrow(
+        function() {
+          Handlebars.precompile({});
+        },
+        Error,
+        'You must pass a string or Handlebars AST to Handlebars.precompile. You passed [object Object]'
+      );
     });
 
     it('can utilize AST instance', function() {
-      equal(/return "Hello"/.test(Handlebars.precompile({
-        type: 'Program',
-        body: [ {type: 'ContentStatement', value: 'Hello'}]
-      })), true);
+      equal(
+        /return "Hello"/.test(
+          Handlebars.precompile({
+            type: 'Program',
+            body: [{ type: 'ContentStatement', value: 'Hello' }]
+          })
+        ),
+        true
+      );
     });
 
     it('can pass through an empty string', function() {
diff --git a/spec/data.js b/spec/data.js
index 547a2664e..0defdc14a 100644
--- a/spec/data.js
+++ b/spec/data.js
@@ -1,6 +1,6 @@
 describe('data', function() {
   it('passing in data to a compiled function that expects data - works with helpers', function() {
-    var template = CompilerContext.compile('{{hello}}', {data: true});
+    var template = CompilerContext.compile('{{hello}}', { data: true });
 
     var helpers = {
       hello: function(options) {
@@ -8,7 +8,10 @@ describe('data', function() {
       }
     };
 
-    var result = template({noun: 'cat'}, {helpers: helpers, data: {adjective: 'happy'}});
+    var result = template(
+      { noun: 'cat' },
+      { helpers: helpers, data: { adjective: 'happy' } }
+    );
     equals('happy cat', result, 'Data output by helper');
   });
 
@@ -19,7 +22,9 @@ describe('data', function() {
   });
 
   it('deep @foo triggers automatic top-level data', function() {
-    var template = CompilerContext.compile('{{#let world="world"}}{{#if foo}}{{#if foo}}Hello {{@world}}{{/if}}{{/if}}{{/let}}');
+    var template = CompilerContext.compile(
+      '{{#let world="world"}}{{#if foo}}{{#if foo}}Hello {{@world}}{{/if}}{{/if}}{{/let}}'
+    );
 
     var helpers = Handlebars.createFrame(handlebarsEnv.helpers);
 
@@ -47,7 +52,11 @@ describe('data', function() {
     };
 
     var result = template({}, { helpers: helpers, data: { world: 'world' } });
-    equals('Hello world', result, '@foo as a parameter retrieves template data');
+    equals(
+      'Hello world',
+      result,
+      '@foo as a parameter retrieves template data'
+    );
   });
 
   it('hash values can be looked up via @foo', function() {
@@ -59,7 +68,11 @@ describe('data', function() {
     };
 
     var result = template({}, { helpers: helpers, data: { world: 'world' } });
-    equals('Hello world', result, '@foo as a parameter retrieves template data');
+    equals(
+      'Hello world',
+      result,
+      '@foo as a parameter retrieves template data'
+    );
   });
 
   it('nested parameter data can be looked up via @foo.bar', function() {
@@ -70,8 +83,15 @@ describe('data', function() {
       }
     };
 
-    var result = template({}, { helpers: helpers, data: { world: {bar: 'world' } } });
-    equals('Hello world', result, '@foo as a parameter retrieves template data');
+    var result = template(
+      {},
+      { helpers: helpers, data: { world: { bar: 'world' } } }
+    );
+    equals(
+      'Hello world',
+      result,
+      '@foo as a parameter retrieves template data'
+    );
   });
 
   it('nested parameter data does not fail with @world.bar', function() {
@@ -82,8 +102,15 @@ describe('data', function() {
       }
     };
 
-    var result = template({}, { helpers: helpers, data: { foo: {bar: 'world' } } });
-    equals('Hello undefined', result, '@foo as a parameter retrieves template data');
+    var result = template(
+      {},
+      { helpers: helpers, data: { foo: { bar: 'world' } } }
+    );
+    equals(
+      'Hello undefined',
+      result,
+      '@foo as a parameter retrieves template data'
+    );
   });
 
   it('parameter data throws when using complex scope references', function() {
@@ -96,17 +123,38 @@ describe('data', function() {
 
   it('data can be functions', function() {
     var template = CompilerContext.compile('{{@hello}}');
-    var result = template({}, { data: { hello: function() { return 'hello'; } } });
+    var result = template(
+      {},
+      {
+        data: {
+          hello: function() {
+            return 'hello';
+          }
+        }
+      }
+    );
     equals('hello', result);
   });
   it('data can be functions with params', function() {
     var template = CompilerContext.compile('{{@hello "hello"}}');
-    var result = template({}, { data: { hello: function(arg) { return arg; } } });
+    var result = template(
+      {},
+      {
+        data: {
+          hello: function(arg) {
+            return arg;
+          }
+        }
+      }
+    );
     equals('hello', result);
   });
 
   it('data is inherited downstream', function() {
-    var template = CompilerContext.compile('{{#let foo=1 bar=2}}{{#let foo=bar.baz}}{{@bar}}{{@foo}}{{/let}}{{@foo}}{{/let}}', { data: true });
+    var template = CompilerContext.compile(
+      '{{#let foo=1 bar=2}}{{#let foo=bar.baz}}{{@bar}}{{@foo}}{{/let}}{{@foo}}{{/let}}',
+      { data: true }
+    );
     var helpers = {
       let: function(options) {
         var frame = Handlebars.createFrame(options.data);
@@ -115,19 +163,22 @@ describe('data', function() {
             frame[prop] = options.hash[prop];
           }
         }
-        return options.fn(this, {data: frame});
+        return options.fn(this, { data: frame });
       }
     };
 
-    var result = template({ bar: { baz: 'hello world' } }, { helpers: helpers, data: {} });
+    var result = template(
+      { bar: { baz: 'hello world' } },
+      { helpers: helpers, data: {} }
+    );
     equals('2hello world1', result, 'data variables are inherited downstream');
   });
 
   it('passing in data to a compiled function that expects data - works with helpers in partials', function() {
-    var template = CompilerContext.compile('{{>myPartial}}', {data: true});
+    var template = CompilerContext.compile('{{>myPartial}}', { data: true });
 
     var partials = {
-      myPartial: CompilerContext.compile('{{hello}}', {data: true})
+      myPartial: CompilerContext.compile('{{hello}}', { data: true })
     };
 
     var helpers = {
@@ -136,12 +187,15 @@ describe('data', function() {
       }
     };
 
-    var result = template({noun: 'cat'}, {helpers: helpers, partials: partials, data: {adjective: 'happy'}});
+    var result = template(
+      { noun: 'cat' },
+      { helpers: helpers, partials: partials, data: { adjective: 'happy' } }
+    );
     equals('happy cat', result, 'Data output by helper inside partial');
   });
 
   it('passing in data to a compiled function that expects data - works with helpers and parameters', function() {
-    var template = CompilerContext.compile('{{hello world}}', {data: true});
+    var template = CompilerContext.compile('{{hello world}}', { data: true });
 
     var helpers = {
       hello: function(noun, options) {
@@ -149,12 +203,17 @@ describe('data', function() {
       }
     };
 
-    var result = template({exclaim: true, world: 'world'}, {helpers: helpers, data: {adjective: 'happy'}});
+    var result = template(
+      { exclaim: true, world: 'world' },
+      { helpers: helpers, data: { adjective: 'happy' } }
+    );
     equals('happy world!', result, 'Data output by helper');
   });
 
   it('passing in data to a compiled function that expects data - works with block helpers', function() {
-    var template = CompilerContext.compile('{{#hello}}{{world}}{{/hello}}', {data: true});
+    var template = CompilerContext.compile('{{#hello}}{{world}}{{/hello}}', {
+      data: true
+    });
 
     var helpers = {
       hello: function(options) {
@@ -165,106 +224,140 @@ describe('data', function() {
       }
     };
 
-    var result = template({exclaim: true}, {helpers: helpers, data: {adjective: 'happy'}});
+    var result = template(
+      { exclaim: true },
+      { helpers: helpers, data: { adjective: 'happy' } }
+    );
     equals('happy world!', result, 'Data output by helper');
   });
 
   it('passing in data to a compiled function that expects data - works with block helpers that use ..', function() {
-    var template = CompilerContext.compile('{{#hello}}{{world ../zomg}}{{/hello}}', {data: true});
+    var template = CompilerContext.compile(
+      '{{#hello}}{{world ../zomg}}{{/hello}}',
+      { data: true }
+    );
 
     var helpers = {
       hello: function(options) {
-        return options.fn({exclaim: '?'});
+        return options.fn({ exclaim: '?' });
       },
       world: function(thing, options) {
         return options.data.adjective + ' ' + thing + (this.exclaim || '');
       }
     };
 
-    var result = template({exclaim: true, zomg: 'world'}, {helpers: helpers, data: {adjective: 'happy'}});
+    var result = template(
+      { exclaim: true, zomg: 'world' },
+      { helpers: helpers, data: { adjective: 'happy' } }
+    );
     equals('happy world?', result, 'Data output by helper');
   });
 
   it('passing in data to a compiled function that expects data - data is passed to with block helpers where children use ..', function() {
-    var template = CompilerContext.compile('{{#hello}}{{world ../zomg}}{{/hello}}', {data: true});
+    var template = CompilerContext.compile(
+      '{{#hello}}{{world ../zomg}}{{/hello}}',
+      { data: true }
+    );
 
     var helpers = {
       hello: function(options) {
-        return options.data.accessData + ' ' + options.fn({exclaim: '?'});
+        return options.data.accessData + ' ' + options.fn({ exclaim: '?' });
       },
       world: function(thing, options) {
         return options.data.adjective + ' ' + thing + (this.exclaim || '');
       }
     };
 
-    var result = template({exclaim: true, zomg: 'world'}, {helpers: helpers, data: {adjective: 'happy', accessData: '#win'}});
+    var result = template(
+      { exclaim: true, zomg: 'world' },
+      { helpers: helpers, data: { adjective: 'happy', accessData: '#win' } }
+    );
     equals('#win happy world?', result, 'Data output by helper');
   });
 
   it('you can override inherited data when invoking a helper', function() {
-    var template = CompilerContext.compile('{{#hello}}{{world zomg}}{{/hello}}', {data: true});
+    var template = CompilerContext.compile(
+      '{{#hello}}{{world zomg}}{{/hello}}',
+      { data: true }
+    );
 
     var helpers = {
       hello: function(options) {
-        return options.fn({exclaim: '?', zomg: 'world'}, { data: {adjective: 'sad'} });
+        return options.fn(
+          { exclaim: '?', zomg: 'world' },
+          { data: { adjective: 'sad' } }
+        );
       },
       world: function(thing, options) {
         return options.data.adjective + ' ' + thing + (this.exclaim || '');
       }
     };
 
-    var result = template({exclaim: true, zomg: 'planet'}, {helpers: helpers, data: {adjective: 'happy'}});
+    var result = template(
+      { exclaim: true, zomg: 'planet' },
+      { helpers: helpers, data: { adjective: 'happy' } }
+    );
     equals('sad world?', result, 'Overriden data output by helper');
   });
 
-
   it('you can override inherited data when invoking a helper with depth', function() {
-    var template = CompilerContext.compile('{{#hello}}{{world ../zomg}}{{/hello}}', {data: true});
+    var template = CompilerContext.compile(
+      '{{#hello}}{{world ../zomg}}{{/hello}}',
+      { data: true }
+    );
 
     var helpers = {
       hello: function(options) {
-        return options.fn({exclaim: '?'}, { data: {adjective: 'sad'} });
+        return options.fn({ exclaim: '?' }, { data: { adjective: 'sad' } });
       },
       world: function(thing, options) {
         return options.data.adjective + ' ' + thing + (this.exclaim || '');
       }
     };
 
-    var result = template({exclaim: true, zomg: 'world'}, {helpers: helpers, data: {adjective: 'happy'}});
+    var result = template(
+      { exclaim: true, zomg: 'world' },
+      { helpers: helpers, data: { adjective: 'happy' } }
+    );
     equals('sad world?', result, 'Overriden data output by helper');
   });
 
   describe('@root', function() {
     it('the root context can be looked up via @root', function() {
       var template = CompilerContext.compile('{{@root.foo}}');
-      var result = template({foo: 'hello'}, { data: {} });
+      var result = template({ foo: 'hello' }, { data: {} });
       equals('hello', result);
 
-      result = template({foo: 'hello'}, {});
+      result = template({ foo: 'hello' }, {});
       equals('hello', result);
     });
     it('passed root values take priority', function() {
       var template = CompilerContext.compile('{{@root.foo}}');
-      var result = template({}, { data: {root: {foo: 'hello'} } });
+      var result = template({}, { data: { root: { foo: 'hello' } } });
       equals('hello', result);
     });
   });
 
   describe('nesting', function() {
     it('the root context can be looked up via @root', function() {
-      var template = CompilerContext.compile('{{#helper}}{{#helper}}{{@./depth}} {{@../depth}} {{@../../depth}}{{/helper}}{{/helper}}');
-      var result = template({foo: 'hello'}, {
-        helpers: {
-          helper: function(options) {
-            var frame = Handlebars.createFrame(options.data);
-            frame.depth = options.data.depth + 1;
-            return options.fn(this, {data: frame});
+      var template = CompilerContext.compile(
+        '{{#helper}}{{#helper}}{{@./depth}} {{@../depth}} {{@../../depth}}{{/helper}}{{/helper}}'
+      );
+      var result = template(
+        { foo: 'hello' },
+        {
+          helpers: {
+            helper: function(options) {
+              var frame = Handlebars.createFrame(options.data);
+              frame.depth = options.data.depth + 1;
+              return options.fn(this, { data: frame });
+            }
+          },
+          data: {
+            depth: 0
           }
-        },
-        data: {
-          depth: 0
         }
-      });
+      );
       equals('2 1 0', result);
     });
   });
diff --git a/spec/env/browser.js b/spec/env/browser.js
index d1dab0d5e..28541b776 100644
--- a/spec/env/browser.js
+++ b/spec/env/browser.js
@@ -1,12 +1,11 @@
 require('./common');
 
 var fs = require('fs'),
-    vm = require('vm');
+  vm = require('vm');
 
 var chai = require('chai');
 var dirtyChai = require('dirty-chai');
 
-
 chai.use(dirtyChai);
 global.expect = chai.expect;
 
@@ -18,7 +17,10 @@ var filename = 'dist/handlebars.js';
 if (global.minimizedTest) {
   filename = 'dist/handlebars.min.js';
 }
-var distHandlebars = fs.readFileSync(require.resolve('../../' + filename), 'utf-8');
+var distHandlebars = fs.readFileSync(
+  require.resolve('../../' + filename),
+  'utf-8'
+);
 vm.runInThisContext(distHandlebars, filename);
 
 global.CompilerContext = {
diff --git a/spec/env/common.js b/spec/env/common.js
index ac9421845..64451fee4 100644
--- a/spec/env/common.js
+++ b/spec/env/common.js
@@ -1,6 +1,6 @@
 var global = (function() {
   return this;
-}());
+})();
 
 var AssertError;
 if (Error.captureStackTrace) {
@@ -28,10 +28,19 @@ global.shouldCompileTo = function(string, hashOrArray, expected, message) {
 /**
  * @deprecated Use "expectTemplate(template)...toCompileTo(output)" instead
  */
-global.shouldCompileToWithPartials = function shouldCompileToWithPartials(string, hashOrArray, partials, expected, message) {
+global.shouldCompileToWithPartials = function shouldCompileToWithPartials(
+  string,
+  hashOrArray,
+  partials,
+  expected,
+  message
+) {
   var result = compileWithPartials(string, hashOrArray, partials);
   if (result !== expected) {
-    throw new AssertError("'" + result + "' should === '" + expected + "': " + message, shouldCompileToWithPartials);
+    throw new AssertError(
+      "'" + result + "' should === '" + expected + "': " + message,
+      shouldCompileToWithPartials
+    );
   }
 };
 
@@ -39,17 +48,18 @@ global.shouldCompileToWithPartials = function shouldCompileToWithPartials(string
  * @deprecated Use "expectTemplate(template)...toCompileTo(output)" instead
  */
 global.compileWithPartials = function(string, hashOrArray, partials) {
-  var template,
-      ary,
-      options;
+  var template, ary, options;
   if (hashOrArray && hashOrArray.hash) {
     ary = [hashOrArray.hash, hashOrArray];
     delete hashOrArray.hash;
   } else if (Object.prototype.toString.call(hashOrArray) === '[object Array]') {
     ary = [];
     ary.push(hashOrArray[0]); // input
-    ary.push({helpers: hashOrArray[1], partials: hashOrArray[2]});
-    options = typeof hashOrArray[3] === 'object' ? hashOrArray[3] : {compat: hashOrArray[3]};
+    ary.push({ helpers: hashOrArray[1], partials: hashOrArray[2] });
+    options =
+      typeof hashOrArray[3] === 'object'
+        ? hashOrArray[3]
+        : { compat: hashOrArray[3] };
     if (hashOrArray[4] != null) {
       options.data = !!hashOrArray[4];
       ary[1].data = hashOrArray[4];
@@ -58,18 +68,23 @@ global.compileWithPartials = function(string, hashOrArray, partials) {
     ary = [hashOrArray];
   }
 
-  template = CompilerContext[partials ? 'compileWithPartial' : 'compile'](string, options);
+  template = CompilerContext[partials ? 'compileWithPartial' : 'compile'](
+    string,
+    options
+  );
   return template.apply(this, ary);
 };
 
-
 /**
  * @deprecated Use chai's expect-style API instead (`expect(actualValue).to.equal(expectedValue)`)
  * @see https://www.chaijs.com/api/bdd/
  */
 global.equals = global.equal = function equals(a, b, msg) {
   if (a !== b) {
-    throw new AssertError("'" + a + "' should === '" + b + "'" + (msg ? ': ' + msg : ''), equals);
+    throw new AssertError(
+      "'" + a + "' should === '" + b + "'" + (msg ? ': ' + msg : ''),
+      equals
+    );
   }
 };
 
@@ -86,8 +101,19 @@ global.shouldThrow = function(callback, type, msg) {
     if (type && !(caught instanceof type)) {
       throw new AssertError('Type failure: ' + caught);
     }
-    if (msg && !(msg.test ? msg.test(caught.message) : msg === caught.message)) {
-      throw new AssertError('Throw mismatch: Expected ' + caught.message + ' to match ' + msg + '\n\n' + caught.stack, shouldThrow);
+    if (
+      msg &&
+      !(msg.test ? msg.test(caught.message) : msg === caught.message)
+    ) {
+      throw new AssertError(
+        'Throw mismatch: Expected ' +
+          caught.message +
+          ' to match ' +
+          msg +
+          '\n\n' +
+          caught.stack,
+        shouldThrow
+      );
     }
   }
   if (failed) {
@@ -95,18 +121,17 @@ global.shouldThrow = function(callback, type, msg) {
   }
 };
 
-
 global.expectTemplate = function(templateAsString) {
   return new HandlebarsTestBench(templateAsString);
 };
 
-
 function HandlebarsTestBench(templateAsString) {
   this.templateAsString = templateAsString;
   this.helpers = {};
   this.partials = {};
   this.input = {};
-  this.message = 'Template' + templateAsString + ' does not evaluate to expected output';
+  this.message =
+    'Template' + templateAsString + ' does not evaluate to expected output';
   this.compileOptions = {};
   this.runtimeOptions = {};
 }
@@ -146,7 +171,11 @@ HandlebarsTestBench.prototype.toCompileTo = function(expectedOutputAsString) {
 };
 
 // see chai "to.throw" (https://www.chaijs.com/api/bdd/#method_throw)
-HandlebarsTestBench.prototype.toThrow = function(errorLike, errMsgMatcher, msg) {
+HandlebarsTestBench.prototype.toThrow = function(
+  errorLike,
+  errMsgMatcher,
+  msg
+) {
   var self = this;
   expect(function() {
     self._compileAndExeute();
@@ -154,7 +183,8 @@ HandlebarsTestBench.prototype.toThrow = function(errorLike, errMsgMatcher, msg)
 };
 
 HandlebarsTestBench.prototype._compileAndExeute = function() {
-  var compile = Object.keys(this.partials).length > 0
+  var compile =
+    Object.keys(this.partials).length > 0
       ? CompilerContext.compileWithPartial
       : CompilerContext.compile;
 
diff --git a/spec/env/node.js b/spec/env/node.js
index 0695468ba..1d1cd09c8 100644
--- a/spec/env/node.js
+++ b/spec/env/node.js
@@ -3,7 +3,6 @@ require('./common');
 var chai = require('chai');
 var dirtyChai = require('dirty-chai');
 
-
 chai.use(dirtyChai);
 global.expect = chai.expect;
 
diff --git a/spec/env/runner.js b/spec/env/runner.js
index a069c2d71..39c522cad 100644
--- a/spec/env/runner.js
+++ b/spec/env/runner.js
@@ -1,11 +1,11 @@
 /* eslint-disable no-console */
 var fs = require('fs'),
-    Mocha = require('mocha'),
-    path = require('path');
+  Mocha = require('mocha'),
+  path = require('path');
 
 var errors = 0,
-    testDir = path.dirname(__dirname),
-    grep = process.argv[2];
+  testDir = path.dirname(__dirname),
+  grep = process.argv[2];
 
 // Lazy hack, but whatever
 if (grep === '--min') {
@@ -13,9 +13,14 @@ if (grep === '--min') {
   grep = undefined;
 }
 
-var files = fs.readdirSync(testDir)
-      .filter(function(name) { return (/.*\.js$/).test(name); })
-      .map(function(name) { return testDir + path.sep + name; });
+var files = fs
+  .readdirSync(testDir)
+  .filter(function(name) {
+    return /.*\.js$/.test(name);
+  })
+  .map(function(name) {
+    return testDir + path.sep + name;
+  });
 
 if (global.minimizedTest) {
   run('./runtime', function() {
@@ -37,7 +42,6 @@ if (global.minimizedTest) {
   });
 }
 
-
 function run(env, callback) {
   var mocha = new Mocha();
   mocha.ui('bdd');
diff --git a/spec/env/runtime.js b/spec/env/runtime.js
index 4f6d28534..99b5bf785 100644
--- a/spec/env/runtime.js
+++ b/spec/env/runtime.js
@@ -1,12 +1,11 @@
 require('./common');
 
 var fs = require('fs'),
-    vm = require('vm');
+  vm = require('vm');
 
 var chai = require('chai');
 var dirtyChai = require('dirty-chai');
 
-
 chai.use(dirtyChai);
 global.expect = chai.expect;
 
@@ -18,7 +17,10 @@ var filename = 'dist/handlebars.runtime.js';
 if (global.minimizedTest) {
   filename = 'dist/handlebars.runtime.min.js';
 }
-vm.runInThisContext(fs.readFileSync(__dirname + '/../../' + filename), filename);
+vm.runInThisContext(
+  fs.readFileSync(__dirname + '/../../' + filename),
+  filename
+);
 
 var parse = require('../../dist/cjs/handlebars/compiler/base').parse;
 var compiler = require('../../dist/cjs/handlebars/compiler/compiler');
@@ -30,7 +32,11 @@ global.CompilerContext = {
   compile: function(template, options) {
     // Hack the compiler on to the environment for these specific tests
     handlebarsEnv.precompile = function(precompileTemplate, precompileOptions) {
-      return compiler.precompile(precompileTemplate, precompileOptions, handlebarsEnv);
+      return compiler.precompile(
+        precompileTemplate,
+        precompileOptions,
+        handlebarsEnv
+      );
     };
     handlebarsEnv.parse = parse;
     handlebarsEnv.Compiler = compiler.Compiler;
diff --git a/spec/helpers.js b/spec/helpers.js
index 634d7027e..9d4bc202e 100644
--- a/spec/helpers.js
+++ b/spec/helpers.js
@@ -1,35 +1,57 @@
 describe('helpers', function() {
   it('helper with complex lookup$', function() {
     var string = '{{#goodbyes}}{{{link ../prefix}}}{{/goodbyes}}';
-    var hash = {prefix: '/root', goodbyes: [{text: 'Goodbye', url: 'goodbye'}]};
-    var helpers = {link: function(prefix) {
-      return '<a href="' + prefix + '/' + this.url + '">' + this.text + '</a>';
-    }};
-    shouldCompileTo(string, [hash, helpers], '<a href="/root/goodbye">Goodbye</a>');
+    var hash = {
+      prefix: '/root',
+      goodbyes: [{ text: 'Goodbye', url: 'goodbye' }]
+    };
+    var helpers = {
+      link: function(prefix) {
+        return (
+          '<a href="' + prefix + '/' + this.url + '">' + this.text + '</a>'
+        );
+      }
+    };
+    shouldCompileTo(
+      string,
+      [hash, helpers],
+      '<a href="/root/goodbye">Goodbye</a>'
+    );
   });
 
   it('helper for raw block gets raw content', function() {
     var string = '{{{{raw}}}} {{test}} {{{{/raw}}}}';
     var hash = { test: 'hello' };
-    var helpers = { raw: function(options) {
+    var helpers = {
+      raw: function(options) {
         return options.fn();
-    } };
-    shouldCompileTo(string, [hash, helpers], ' {{test}} ',
-                    'raw block helper gets raw content');
+      }
+    };
+    shouldCompileTo(
+      string,
+      [hash, helpers],
+      ' {{test}} ',
+      'raw block helper gets raw content'
+    );
   });
 
   it('helper for raw block gets parameters', function() {
     var string = '{{{{raw 1 2 3}}}} {{test}} {{{{/raw}}}}';
     var hash = { test: 'hello' };
-    var helpers = { raw: function(a, b, c, options) {
+    var helpers = {
+      raw: function(a, b, c, options) {
         return options.fn() + a + b + c;
-    } };
-    shouldCompileTo(string, [hash, helpers], ' {{test}} 123',
-                    'raw block helper gets raw content');
+      }
+    };
+    shouldCompileTo(
+      string,
+      [hash, helpers],
+      ' {{test}} 123',
+      'raw block helper gets raw content'
+    );
   });
 
   describe('raw block parsing (with identity helper-function)', function() {
-
     function runWithIdentityHelper(template, expected) {
       var helpers = {
         identity: function(options) {
@@ -40,7 +62,10 @@ describe('helpers', function() {
     }
 
     it('helper for nested raw block gets raw content', function() {
-      runWithIdentityHelper('{{{{identity}}}} {{{{b}}}} {{{{/b}}}} {{{{/identity}}}}', ' {{{{b}}}} {{{{/b}}}} ');
+      runWithIdentityHelper(
+        '{{{{identity}}}} {{{{b}}}} {{{{/b}}}} {{{{/identity}}}}',
+        ' {{{{b}}}} {{{{/b}}}} '
+      );
     });
 
     it('helper for nested raw block works with empty content', function() {
@@ -52,11 +77,17 @@ describe('helpers', function() {
       // The test is deactivated, because in 3.x this template cases an exception and it also does not work in 4.4.3
       // If anyone can make this template work without breaking everything else, then go for it,
       // but for now, this is just a known bug, that will be documented.
-      runWithIdentityHelper('{{{{identity}}}} {{{{a}}}} {{{{ {{{{/ }}}} }}}} {{{{/identity}}}}', ' {{{{a}}}} {{{{ {{{{/ }}}} }}}} ');
+      runWithIdentityHelper(
+        '{{{{identity}}}} {{{{a}}}} {{{{ {{{{/ }}}} }}}} {{{{/identity}}}}',
+        ' {{{{a}}}} {{{{ {{{{/ }}}} }}}} '
+      );
     });
 
     it('helper for nested raw block closes after first matching close', function() {
-      runWithIdentityHelper('{{{{identity}}}}abc{{{{/identity}}}} {{{{identity}}}}abc{{{{/identity}}}}', 'abc abc');
+      runWithIdentityHelper(
+        '{{{{identity}}}}abc{{{{/identity}}}} {{{{identity}}}}abc{{{{/identity}}}}',
+        'abc abc'
+      );
     });
 
     it('helper for nested raw block throw exception when with missing closing braces', function() {
@@ -69,58 +100,121 @@ describe('helpers', function() {
 
   it('helper block with identical context', function() {
     var string = '{{#goodbyes}}{{name}}{{/goodbyes}}';
-    var hash = {name: 'Alan'};
-    var helpers = {goodbyes: function(options) {
-      var out = '';
-      var byes = ['Goodbye', 'goodbye', 'GOODBYE'];
-      for (var i = 0, j = byes.length; i < j; i++) {
-        out += byes[i] + ' ' + options.fn(this) + '! ';
+    var hash = { name: 'Alan' };
+    var helpers = {
+      goodbyes: function(options) {
+        var out = '';
+        var byes = ['Goodbye', 'goodbye', 'GOODBYE'];
+        for (var i = 0, j = byes.length; i < j; i++) {
+          out += byes[i] + ' ' + options.fn(this) + '! ';
+        }
+        return out;
       }
-      return out;
-    }};
-    shouldCompileTo(string, [hash, helpers], 'Goodbye Alan! goodbye Alan! GOODBYE Alan! ');
+    };
+    shouldCompileTo(
+      string,
+      [hash, helpers],
+      'Goodbye Alan! goodbye Alan! GOODBYE Alan! '
+    );
   });
   it('helper block with complex lookup expression', function() {
     var string = '{{#goodbyes}}{{../name}}{{/goodbyes}}';
-    var hash = {name: 'Alan'};
-    var helpers = {goodbyes: function(options) {
-      var out = '';
-      var byes = ['Goodbye', 'goodbye', 'GOODBYE'];
-      for (var i = 0, j = byes.length; i < j; i++) {
-        out += byes[i] + ' ' + options.fn({}) + '! ';
+    var hash = { name: 'Alan' };
+    var helpers = {
+      goodbyes: function(options) {
+        var out = '';
+        var byes = ['Goodbye', 'goodbye', 'GOODBYE'];
+        for (var i = 0, j = byes.length; i < j; i++) {
+          out += byes[i] + ' ' + options.fn({}) + '! ';
+        }
+        return out;
       }
-      return out;
-    }};
-    shouldCompileTo(string, [hash, helpers], 'Goodbye Alan! goodbye Alan! GOODBYE Alan! ');
+    };
+    shouldCompileTo(
+      string,
+      [hash, helpers],
+      'Goodbye Alan! goodbye Alan! GOODBYE Alan! '
+    );
   });
 
   it('helper with complex lookup and nested template', function() {
-    var string = '{{#goodbyes}}{{#link ../prefix}}{{text}}{{/link}}{{/goodbyes}}';
-    var hash = {prefix: '/root', goodbyes: [{text: 'Goodbye', url: 'goodbye'}]};
-    var helpers = {link: function(prefix, options) {
-        return '<a href="' + prefix + '/' + this.url + '">' + options.fn(this) + '</a>';
-    }};
-    shouldCompileToWithPartials(string, [hash, helpers], false, '<a href="/root/goodbye">Goodbye</a>');
+    var string =
+      '{{#goodbyes}}{{#link ../prefix}}{{text}}{{/link}}{{/goodbyes}}';
+    var hash = {
+      prefix: '/root',
+      goodbyes: [{ text: 'Goodbye', url: 'goodbye' }]
+    };
+    var helpers = {
+      link: function(prefix, options) {
+        return (
+          '<a href="' +
+          prefix +
+          '/' +
+          this.url +
+          '">' +
+          options.fn(this) +
+          '</a>'
+        );
+      }
+    };
+    shouldCompileToWithPartials(
+      string,
+      [hash, helpers],
+      false,
+      '<a href="/root/goodbye">Goodbye</a>'
+    );
   });
 
   it('helper with complex lookup and nested template in VM+Compiler', function() {
-    var string = '{{#goodbyes}}{{#link ../prefix}}{{text}}{{/link}}{{/goodbyes}}';
-    var hash = {prefix: '/root', goodbyes: [{text: 'Goodbye', url: 'goodbye'}]};
-    var helpers = {link: function(prefix, options) {
-        return '<a href="' + prefix + '/' + this.url + '">' + options.fn(this) + '</a>';
-    }};
-    shouldCompileToWithPartials(string, [hash, helpers], true, '<a href="/root/goodbye">Goodbye</a>');
+    var string =
+      '{{#goodbyes}}{{#link ../prefix}}{{text}}{{/link}}{{/goodbyes}}';
+    var hash = {
+      prefix: '/root',
+      goodbyes: [{ text: 'Goodbye', url: 'goodbye' }]
+    };
+    var helpers = {
+      link: function(prefix, options) {
+        return (
+          '<a href="' +
+          prefix +
+          '/' +
+          this.url +
+          '">' +
+          options.fn(this) +
+          '</a>'
+        );
+      }
+    };
+    shouldCompileToWithPartials(
+      string,
+      [hash, helpers],
+      true,
+      '<a href="/root/goodbye">Goodbye</a>'
+    );
   });
   it('helper returning undefined value', function() {
-    shouldCompileTo(' {{nothere}}', [{}, {nothere: function() {}}], ' ');
-    shouldCompileTo(' {{#nothere}}{{/nothere}}', [{}, {nothere: function() {}}], ' ');
+    shouldCompileTo(' {{nothere}}', [{}, { nothere: function() {} }], ' ');
+    shouldCompileTo(
+      ' {{#nothere}}{{/nothere}}',
+      [{}, { nothere: function() {} }],
+      ' '
+    );
   });
 
   it('block helper', function() {
     var string = '{{#goodbyes}}{{text}}! {{/goodbyes}}cruel {{world}}!';
     var template = CompilerContext.compile(string);
 
-    var result = template({world: 'world'}, { helpers: {goodbyes: function(options) { return options.fn({text: 'GOODBYE'}); }}});
+    var result = template(
+      { world: 'world' },
+      {
+        helpers: {
+          goodbyes: function(options) {
+            return options.fn({ text: 'GOODBYE' });
+          }
+        }
+      }
+    );
     equal(result, 'GOODBYE! cruel world!', 'Block helper executed');
   });
 
@@ -128,21 +222,41 @@ describe('helpers', function() {
     var string = '{{#form}}<p>{{name}}</p>{{/form}}';
     var template = CompilerContext.compile(string);
 
-    var result = template({name: 'Yehuda'}, {helpers: {form: function(options) { return '<form>' + options.fn(this) + '</form>'; } }});
-    equal(result, '<form><p>Yehuda</p></form>', 'Block helper executed with current context');
+    var result = template(
+      { name: 'Yehuda' },
+      {
+        helpers: {
+          form: function(options) {
+            return '<form>' + options.fn(this) + '</form>';
+          }
+        }
+      }
+    );
+    equal(
+      result,
+      '<form><p>Yehuda</p></form>',
+      'Block helper executed with current context'
+    );
   });
 
   it('block helper should have context in this', function() {
-    var source = '<ul>{{#people}}<li>{{#link}}{{name}}{{/link}}</li>{{/people}}</ul>';
+    var source =
+      '<ul>{{#people}}<li>{{#link}}{{name}}{{/link}}</li>{{/people}}</ul>';
     function link(options) {
       return '<a href="/people/' + this.id + '">' + options.fn(this) + '</a>';
     }
-    var data = { 'people': [
-      { 'name': 'Alan', 'id': 1 },
-      { 'name': 'Yehuda', 'id': 2 }
-    ]};
+    var data = {
+      people: [
+        { name: 'Alan', id: 1 },
+        { name: 'Yehuda', id: 2 }
+      ]
+    };
 
-    shouldCompileTo(source, [data, {link: link}], '<ul><li><a href="/people/1">Alan</a></li><li><a href="/people/2">Yehuda</a></li></ul>');
+    shouldCompileTo(
+      source,
+      [data, { link: link }],
+      '<ul><li><a href="/people/1">Alan</a></li><li><a href="/people/2">Yehuda</a></li></ul>'
+    );
   });
 
   it('block helper for undefined value', function() {
@@ -153,7 +267,16 @@ describe('helpers', function() {
     var string = '{{#form yehuda}}<p>{{name}}</p>{{/form}}';
     var template = CompilerContext.compile(string);
 
-    var result = template({yehuda: {name: 'Yehuda'}}, { helpers: {form: function(context, options) { return '<form>' + options.fn(context) + '</form>'; }}});
+    var result = template(
+      { yehuda: { name: 'Yehuda' } },
+      {
+        helpers: {
+          form: function(context, options) {
+            return '<form>' + options.fn(context) + '</form>';
+          }
+        }
+      }
+    );
     equal(result, '<form><p>Yehuda</p></form>', 'Context variable resolved');
   });
 
@@ -161,27 +284,52 @@ describe('helpers', function() {
     var string = '{{#form yehuda/cat}}<p>{{name}}</p>{{/form}}';
     var template = CompilerContext.compile(string);
 
-    var result = template({yehuda: {name: 'Yehuda', cat: {name: 'Harold'}}}, { helpers: {form: function(context, options) { return '<form>' + options.fn(context) + '</form>'; }}});
-    equal(result, '<form><p>Harold</p></form>', 'Complex path variable resolved');
+    var result = template(
+      { yehuda: { name: 'Yehuda', cat: { name: 'Harold' } } },
+      {
+        helpers: {
+          form: function(context, options) {
+            return '<form>' + options.fn(context) + '</form>';
+          }
+        }
+      }
+    );
+    equal(
+      result,
+      '<form><p>Harold</p></form>',
+      'Complex path variable resolved'
+    );
   });
 
   it('nested block helpers', function() {
-    var string = '{{#form yehuda}}<p>{{name}}</p>{{#link}}Hello{{/link}}{{/form}}';
+    var string =
+      '{{#form yehuda}}<p>{{name}}</p>{{#link}}Hello{{/link}}{{/form}}';
     var template = CompilerContext.compile(string);
 
-    var result = template({
-      yehuda: {name: 'Yehuda' }
-    }, {
-      helpers: {
-        link: function(options) { return '<a href="' + this.name + '">' + options.fn(this) + '</a>'; },
-        form: function(context, options) { return '<form>' + options.fn(context) + '</form>'; }
+    var result = template(
+      {
+        yehuda: { name: 'Yehuda' }
+      },
+      {
+        helpers: {
+          link: function(options) {
+            return '<a href="' + this.name + '">' + options.fn(this) + '</a>';
+          },
+          form: function(context, options) {
+            return '<form>' + options.fn(context) + '</form>';
+          }
+        }
       }
-    });
-    equal(result, '<form><p>Yehuda</p><a href="Yehuda">Hello</a></form>', 'Both blocks executed');
+    );
+    equal(
+      result,
+      '<form><p>Yehuda</p><a href="Yehuda">Hello</a></form>',
+      'Both blocks executed'
+    );
   });
 
   it('block helper inverted sections', function() {
-    var string = '{{#list people}}{{name}}{{^}}<em>Nobody\'s here</em>{{/list}}';
+    var string = "{{#list people}}{{name}}{{^}}<em>Nobody's here</em>{{/list}}";
     function list(context, options) {
       if (context.length > 0) {
         var out = '<ul>';
@@ -197,20 +345,35 @@ describe('helpers', function() {
       }
     }
 
-    var hash = {people: [{name: 'Alan'}, {name: 'Yehuda'}]};
-    var empty = {people: []};
+    var hash = { people: [{ name: 'Alan' }, { name: 'Yehuda' }] };
+    var empty = { people: [] };
     var rootMessage = {
       people: [],
-      message: 'Nobody\'s here'
+      message: "Nobody's here"
     };
 
     var messageString = '{{#list people}}Hello{{^}}{{message}}{{/list}}';
 
     // the meaning here may be kind of hard to catch, but list.not is always called,
     // so we should see the output of both
-    shouldCompileTo(string, [hash, { list: list }], '<ul><li>Alan</li><li>Yehuda</li></ul>', 'an inverse wrapper is passed in as a new context');
-    shouldCompileTo(string, [empty, { list: list }], '<p><em>Nobody\'s here</em></p>', 'an inverse wrapper can be optionally called');
-    shouldCompileTo(messageString, [rootMessage, { list: list }], '<p>Nobody&#x27;s here</p>', 'the context of an inverse is the parent of the block');
+    shouldCompileTo(
+      string,
+      [hash, { list: list }],
+      '<ul><li>Alan</li><li>Yehuda</li></ul>',
+      'an inverse wrapper is passed in as a new context'
+    );
+    shouldCompileTo(
+      string,
+      [empty, { list: list }],
+      "<p><em>Nobody's here</em></p>",
+      'an inverse wrapper can be optionally called'
+    );
+    shouldCompileTo(
+      messageString,
+      [rootMessage, { list: list }],
+      '<p>Nobody&#x27;s here</p>',
+      'the context of an inverse is the parent of the block'
+    );
   });
 
   it('pathed lambas with parameters', function() {
@@ -231,40 +394,97 @@ describe('helpers', function() {
 
   describe('helpers hash', function() {
     it('providing a helpers hash', function() {
-      shouldCompileTo('Goodbye {{cruel}} {{world}}!', [{cruel: 'cruel'}, {world: function() { return 'world'; }}], 'Goodbye cruel world!',
-                      'helpers hash is available');
+      shouldCompileTo(
+        'Goodbye {{cruel}} {{world}}!',
+        [
+          { cruel: 'cruel' },
+          {
+            world: function() {
+              return 'world';
+            }
+          }
+        ],
+        'Goodbye cruel world!',
+        'helpers hash is available'
+      );
 
-      shouldCompileTo('Goodbye {{#iter}}{{cruel}} {{world}}{{/iter}}!', [{iter: [{cruel: 'cruel'}]}, {world: function() { return 'world'; }}],
-                      'Goodbye cruel world!', 'helpers hash is available inside other blocks');
+      shouldCompileTo(
+        'Goodbye {{#iter}}{{cruel}} {{world}}{{/iter}}!',
+        [
+          { iter: [{ cruel: 'cruel' }] },
+          {
+            world: function() {
+              return 'world';
+            }
+          }
+        ],
+        'Goodbye cruel world!',
+        'helpers hash is available inside other blocks'
+      );
     });
 
     it('in cases of conflict, helpers win', function() {
-      shouldCompileTo('{{{lookup}}}', [{lookup: 'Explicit'}, {lookup: function() { return 'helpers'; }}], 'helpers',
-                      'helpers hash has precedence escaped expansion');
-      shouldCompileTo('{{lookup}}', [{lookup: 'Explicit'}, {lookup: function() { return 'helpers'; }}], 'helpers',
-                      'helpers hash has precedence simple expansion');
+      shouldCompileTo(
+        '{{{lookup}}}',
+        [
+          { lookup: 'Explicit' },
+          {
+            lookup: function() {
+              return 'helpers';
+            }
+          }
+        ],
+        'helpers',
+        'helpers hash has precedence escaped expansion'
+      );
+      shouldCompileTo(
+        '{{lookup}}',
+        [
+          { lookup: 'Explicit' },
+          {
+            lookup: function() {
+              return 'helpers';
+            }
+          }
+        ],
+        'helpers',
+        'helpers hash has precedence simple expansion'
+      );
     });
 
     it('the helpers hash is available is nested contexts', function() {
       shouldCompileTo(
         '{{#outer}}{{#inner}}{{helper}}{{/inner}}{{/outer}}',
         [
-          {'outer': {'inner': {'unused': []}}},
-          {'helper': function() { return 'helper'; }}
+          { outer: { inner: { unused: [] } } },
+          {
+            helper: function() {
+              return 'helper';
+            }
+          }
         ],
         'helper',
-        'helpers hash is available in nested contexts.');
+        'helpers hash is available in nested contexts.'
+      );
     });
 
     it('the helper hash should augment the global hash', function() {
-      handlebarsEnv.registerHelper('test_helper', function() { return 'found it!'; });
+      handlebarsEnv.registerHelper('test_helper', function() {
+        return 'found it!';
+      });
 
       shouldCompileTo(
-        '{{test_helper}} {{#if cruel}}Goodbye {{cruel}} {{world}}!{{/if}}', [
-          {cruel: 'cruel'},
-          {world: function() { return 'world!'; }}
+        '{{test_helper}} {{#if cruel}}Goodbye {{cruel}} {{world}}!{{/if}}',
+        [
+          { cruel: 'cruel' },
+          {
+            world: function() {
+              return 'world!';
+            }
+          }
         ],
-        'found it! Goodbye cruel world!!');
+        'found it! Goodbye cruel world!!'
+      );
     });
   });
 
@@ -284,55 +504,106 @@ describe('helpers', function() {
       handlebarsEnv.helpers = {};
 
       handlebarsEnv.registerHelper({
-        'if': helpers['if'],
-        world: function() { return 'world!'; },
-        testHelper: function() { return 'found it!'; }
+        if: helpers['if'],
+        world: function() {
+          return 'world!';
+        },
+        testHelper: function() {
+          return 'found it!';
+        }
       });
 
       shouldCompileTo(
         '{{testHelper}} {{#if cruel}}Goodbye {{cruel}} {{world}}!{{/if}}',
-        [{cruel: 'cruel'}],
-        'found it! Goodbye cruel world!!');
+        [{ cruel: 'cruel' }],
+        'found it! Goodbye cruel world!!'
+      );
     });
     it('fails with multiple and args', function() {
-      shouldThrow(function() {
-        handlebarsEnv.registerHelper({
-          world: function() { return 'world!'; },
-          testHelper: function() { return 'found it!'; }
-        }, {});
-      }, Error, 'Arg not supported with multiple helpers');
+      shouldThrow(
+        function() {
+          handlebarsEnv.registerHelper(
+            {
+              world: function() {
+                return 'world!';
+              },
+              testHelper: function() {
+                return 'found it!';
+              }
+            },
+            {}
+          );
+        },
+        Error,
+        'Arg not supported with multiple helpers'
+      );
     });
   });
 
   it('decimal number literals work', function() {
     var string = 'Message: {{hello -1.2 1.2}}';
-    var helpers = {hello: function(times, times2) {
-      if (typeof times !== 'number') { times = 'NaN'; }
-      if (typeof times2 !== 'number') { times2 = 'NaN'; }
-      return 'Hello ' + times + ' ' + times2 + ' times';
-    }};
-    shouldCompileTo(string, [{}, helpers], 'Message: Hello -1.2 1.2 times', 'template with a negative integer literal');
+    var helpers = {
+      hello: function(times, times2) {
+        if (typeof times !== 'number') {
+          times = 'NaN';
+        }
+        if (typeof times2 !== 'number') {
+          times2 = 'NaN';
+        }
+        return 'Hello ' + times + ' ' + times2 + ' times';
+      }
+    };
+    shouldCompileTo(
+      string,
+      [{}, helpers],
+      'Message: Hello -1.2 1.2 times',
+      'template with a negative integer literal'
+    );
   });
 
   it('negative number literals work', function() {
     var string = 'Message: {{hello -12}}';
-    var helpers = {hello: function(times) {
-      if (typeof times !== 'number') { times = 'NaN'; }
-      return 'Hello ' + times + ' times';
-    }};
-    shouldCompileTo(string, [{}, helpers], 'Message: Hello -12 times', 'template with a negative integer literal');
+    var helpers = {
+      hello: function(times) {
+        if (typeof times !== 'number') {
+          times = 'NaN';
+        }
+        return 'Hello ' + times + ' times';
+      }
+    };
+    shouldCompileTo(
+      string,
+      [{}, helpers],
+      'Message: Hello -12 times',
+      'template with a negative integer literal'
+    );
   });
 
   describe('String literal parameters', function() {
     it('simple literals work', function() {
       var string = 'Message: {{hello "world" 12 true false}}';
-      var helpers = {hello: function(param, times, bool1, bool2) {
-        if (typeof times !== 'number') { times = 'NaN'; }
-        if (typeof bool1 !== 'boolean') { bool1 = 'NaB'; }
-        if (typeof bool2 !== 'boolean') { bool2 = 'NaB'; }
-        return 'Hello ' + param + ' ' + times + ' times: ' + bool1 + ' ' + bool2;
-      }};
-      shouldCompileTo(string, [{}, helpers], 'Message: Hello world 12 times: true false', 'template with a simple String literal');
+      var helpers = {
+        hello: function(param, times, bool1, bool2) {
+          if (typeof times !== 'number') {
+            times = 'NaN';
+          }
+          if (typeof bool1 !== 'boolean') {
+            bool1 = 'NaB';
+          }
+          if (typeof bool2 !== 'boolean') {
+            bool2 = 'NaB';
+          }
+          return (
+            'Hello ' + param + ' ' + times + ' times: ' + bool1 + ' ' + bool2
+          );
+        }
+      };
+      shouldCompileTo(
+        string,
+        [{}, helpers],
+        'Message: Hello world 12 times: true false',
+        'template with a simple String literal'
+      );
     });
 
     it('using a quote in the middle of a parameter raises an error', function() {
@@ -344,57 +615,111 @@ describe('helpers', function() {
 
     it('escaping a String is possible', function() {
       var string = 'Message: {{{hello "\\"world\\""}}}';
-      var helpers = {hello: function(param) { return 'Hello ' + param; }};
-      shouldCompileTo(string, [{}, helpers], 'Message: Hello "world"', 'template with an escaped String literal');
+      var helpers = {
+        hello: function(param) {
+          return 'Hello ' + param;
+        }
+      };
+      shouldCompileTo(
+        string,
+        [{}, helpers],
+        'Message: Hello "world"',
+        'template with an escaped String literal'
+      );
     });
 
     it("it works with ' marks", function() {
       var string = 'Message: {{{hello "Alan\'s world"}}}';
-      var helpers = {hello: function(param) { return 'Hello ' + param; }};
-      shouldCompileTo(string, [{}, helpers], "Message: Hello Alan's world", "template with a ' mark");
+      var helpers = {
+        hello: function(param) {
+          return 'Hello ' + param;
+        }
+      };
+      shouldCompileTo(
+        string,
+        [{}, helpers],
+        "Message: Hello Alan's world",
+        "template with a ' mark"
+      );
     });
   });
 
   it('negative number literals work', function() {
     var string = 'Message: {{hello -12}}';
-    var helpers = {hello: function(times) {
-      if (typeof times !== 'number') { times = 'NaN'; }
-      return 'Hello ' + times + ' times';
-    }};
-    shouldCompileTo(string, [{}, helpers], 'Message: Hello -12 times', 'template with a negative integer literal');
+    var helpers = {
+      hello: function(times) {
+        if (typeof times !== 'number') {
+          times = 'NaN';
+        }
+        return 'Hello ' + times + ' times';
+      }
+    };
+    shouldCompileTo(
+      string,
+      [{}, helpers],
+      'Message: Hello -12 times',
+      'template with a negative integer literal'
+    );
   });
 
   describe('multiple parameters', function() {
     it('simple multi-params work', function() {
       var string = 'Message: {{goodbye cruel world}}';
-      var hash = {cruel: 'cruel', world: 'world'};
-      var helpers = {goodbye: function(cruel, world) { return 'Goodbye ' + cruel + ' ' + world; }};
-      shouldCompileTo(string, [hash, helpers], 'Message: Goodbye cruel world', 'regular helpers with multiple params');
+      var hash = { cruel: 'cruel', world: 'world' };
+      var helpers = {
+        goodbye: function(cruel, world) {
+          return 'Goodbye ' + cruel + ' ' + world;
+        }
+      };
+      shouldCompileTo(
+        string,
+        [hash, helpers],
+        'Message: Goodbye cruel world',
+        'regular helpers with multiple params'
+      );
     });
 
     it('block multi-params work', function() {
-      var string = 'Message: {{#goodbye cruel world}}{{greeting}} {{adj}} {{noun}}{{/goodbye}}';
-      var hash = {cruel: 'cruel', world: 'world'};
-      var helpers = {goodbye: function(cruel, world, options) {
-        return options.fn({greeting: 'Goodbye', adj: cruel, noun: world});
-      }};
-      shouldCompileTo(string, [hash, helpers], 'Message: Goodbye cruel world', 'block helpers with multiple params');
+      var string =
+        'Message: {{#goodbye cruel world}}{{greeting}} {{adj}} {{noun}}{{/goodbye}}';
+      var hash = { cruel: 'cruel', world: 'world' };
+      var helpers = {
+        goodbye: function(cruel, world, options) {
+          return options.fn({ greeting: 'Goodbye', adj: cruel, noun: world });
+        }
+      };
+      shouldCompileTo(
+        string,
+        [hash, helpers],
+        'Message: Goodbye cruel world',
+        'block helpers with multiple params'
+      );
     });
   });
 
   describe('hash', function() {
     it('helpers can take an optional hash', function() {
-      var template = CompilerContext.compile('{{goodbye cruel="CRUEL" world="WORLD" times=12}}');
+      var template = CompilerContext.compile(
+        '{{goodbye cruel="CRUEL" world="WORLD" times=12}}'
+      );
 
       var helpers = {
         goodbye: function(options) {
-          return 'GOODBYE ' + options.hash.cruel + ' ' + options.hash.world + ' ' + options.hash.times + ' TIMES';
+          return (
+            'GOODBYE ' +
+            options.hash.cruel +
+            ' ' +
+            options.hash.world +
+            ' ' +
+            options.hash.times +
+            ' TIMES'
+          );
         }
       };
 
       var context = {};
 
-      var result = template(context, {helpers: helpers});
+      var result = template(context, { helpers: helpers });
       equals(result, 'GOODBYE CRUEL WORLD 12 TIMES', 'Helper output hash');
     });
 
@@ -413,38 +738,62 @@ describe('helpers', function() {
 
       var context = {};
 
-      var template = CompilerContext.compile('{{goodbye cruel="CRUEL" world="WORLD" print=true}}');
-      var result = template(context, {helpers: helpers});
+      var template = CompilerContext.compile(
+        '{{goodbye cruel="CRUEL" world="WORLD" print=true}}'
+      );
+      var result = template(context, { helpers: helpers });
       equals(result, 'GOODBYE CRUEL WORLD', 'Helper output hash');
 
-      template = CompilerContext.compile('{{goodbye cruel="CRUEL" world="WORLD" print=false}}');
-      result = template(context, {helpers: helpers});
+      template = CompilerContext.compile(
+        '{{goodbye cruel="CRUEL" world="WORLD" print=false}}'
+      );
+      result = template(context, { helpers: helpers });
       equals(result, 'NOT PRINTING', 'Boolean helper parameter honored');
     });
 
     it('block helpers can take an optional hash', function() {
-      var template = CompilerContext.compile('{{#goodbye cruel="CRUEL" times=12}}world{{/goodbye}}');
+      var template = CompilerContext.compile(
+        '{{#goodbye cruel="CRUEL" times=12}}world{{/goodbye}}'
+      );
 
       var helpers = {
         goodbye: function(options) {
-          return 'GOODBYE ' + options.hash.cruel + ' ' + options.fn(this) + ' ' + options.hash.times + ' TIMES';
+          return (
+            'GOODBYE ' +
+            options.hash.cruel +
+            ' ' +
+            options.fn(this) +
+            ' ' +
+            options.hash.times +
+            ' TIMES'
+          );
         }
       };
 
-      var result = template({}, {helpers: helpers});
+      var result = template({}, { helpers: helpers });
       equals(result, 'GOODBYE CRUEL world 12 TIMES', 'Hash parameters output');
     });
 
     it('block helpers can take an optional hash with single quoted stings', function() {
-      var template = CompilerContext.compile('{{#goodbye cruel="CRUEL" times=12}}world{{/goodbye}}');
+      var template = CompilerContext.compile(
+        '{{#goodbye cruel="CRUEL" times=12}}world{{/goodbye}}'
+      );
 
       var helpers = {
         goodbye: function(options) {
-          return 'GOODBYE ' + options.hash.cruel + ' ' + options.fn(this) + ' ' + options.hash.times + ' TIMES';
+          return (
+            'GOODBYE ' +
+            options.hash.cruel +
+            ' ' +
+            options.fn(this) +
+            ' ' +
+            options.hash.times +
+            ' TIMES'
+          );
         }
       };
 
-      var result = template({}, {helpers: helpers});
+      var result = template({}, { helpers: helpers });
       equals(result, 'GOODBYE CRUEL world 12 TIMES', 'Hash parameters output');
     });
 
@@ -461,22 +810,30 @@ describe('helpers', function() {
         }
       };
 
-      var template = CompilerContext.compile('{{#goodbye cruel="CRUEL" print=true}}world{{/goodbye}}');
-      var result = template({}, {helpers: helpers});
+      var template = CompilerContext.compile(
+        '{{#goodbye cruel="CRUEL" print=true}}world{{/goodbye}}'
+      );
+      var result = template({}, { helpers: helpers });
       equals(result, 'GOODBYE CRUEL world', 'Boolean hash parameter honored');
 
-      template = CompilerContext.compile('{{#goodbye cruel="CRUEL" print=false}}world{{/goodbye}}');
-      result = template({}, {helpers: helpers});
+      template = CompilerContext.compile(
+        '{{#goodbye cruel="CRUEL" print=false}}world{{/goodbye}}'
+      );
+      result = template({}, { helpers: helpers });
       equals(result, 'NOT PRINTING', 'Boolean hash parameter honored');
     });
   });
 
   describe('helperMissing', function() {
     it('if a context is not found, helperMissing is used', function() {
-      shouldThrow(function() {
+      shouldThrow(
+        function() {
           var template = CompilerContext.compile('{{hello}} {{link_to world}}');
           template({});
-      }, undefined, /Missing helper: "link_to"/);
+        },
+        undefined,
+        /Missing helper: "link_to"/
+      );
     });
 
     it('if a context is not found, custom helperMissing is used', function() {
@@ -512,50 +869,91 @@ describe('helpers', function() {
 
   describe('knownHelpers', function() {
     it('Known helper should render helper', function() {
-      var template = CompilerContext.compile('{{hello}}', {knownHelpers: {hello: true}});
+      var template = CompilerContext.compile('{{hello}}', {
+        knownHelpers: { hello: true }
+      });
 
-      var result = template({}, {helpers: {hello: function() { return 'foo'; }}});
+      var result = template(
+        {},
+        {
+          helpers: {
+            hello: function() {
+              return 'foo';
+            }
+          }
+        }
+      );
       equal(result, 'foo', "'foo' should === '" + result);
     });
 
     it('Unknown helper in knownHelpers only mode should be passed as undefined', function() {
-      var template = CompilerContext.compile('{{typeof hello}}', {knownHelpers: {'typeof': true}, knownHelpersOnly: true});
+      var template = CompilerContext.compile('{{typeof hello}}', {
+        knownHelpers: { typeof: true },
+        knownHelpersOnly: true
+      });
 
-      var result = template({}, {helpers: {'typeof': function(arg) { return typeof arg; }, hello: function() { return 'foo'; }}});
+      var result = template(
+        {},
+        {
+          helpers: {
+            typeof: function(arg) {
+              return typeof arg;
+            },
+            hello: function() {
+              return 'foo';
+            }
+          }
+        }
+      );
       equal(result, 'undefined', "'undefined' should === '" + result);
     });
     it('Builtin helpers available in knownHelpers only mode', function() {
-      var template = CompilerContext.compile('{{#unless foo}}bar{{/unless}}', {knownHelpersOnly: true});
+      var template = CompilerContext.compile('{{#unless foo}}bar{{/unless}}', {
+        knownHelpersOnly: true
+      });
 
       var result = template({});
       equal(result, 'bar', "'bar' should === '" + result);
     });
     it('Field lookup works in knownHelpers only mode', function() {
-      var template = CompilerContext.compile('{{foo}}', {knownHelpersOnly: true});
+      var template = CompilerContext.compile('{{foo}}', {
+        knownHelpersOnly: true
+      });
 
-      var result = template({foo: 'bar'});
+      var result = template({ foo: 'bar' });
       equal(result, 'bar', "'bar' should === '" + result);
     });
     it('Conditional blocks work in knownHelpers only mode', function() {
-      var template = CompilerContext.compile('{{#foo}}bar{{/foo}}', {knownHelpersOnly: true});
+      var template = CompilerContext.compile('{{#foo}}bar{{/foo}}', {
+        knownHelpersOnly: true
+      });
 
-      var result = template({foo: 'baz'});
+      var result = template({ foo: 'baz' });
       equal(result, 'bar', "'bar' should === '" + result);
     });
     it('Invert blocks work in knownHelpers only mode', function() {
-      var template = CompilerContext.compile('{{^foo}}bar{{/foo}}', {knownHelpersOnly: true});
+      var template = CompilerContext.compile('{{^foo}}bar{{/foo}}', {
+        knownHelpersOnly: true
+      });
 
-      var result = template({foo: false});
+      var result = template({ foo: false });
       equal(result, 'bar', "'bar' should === '" + result);
     });
     it('Functions are bound to the context in knownHelpers only mode', function() {
-      var template = CompilerContext.compile('{{foo}}', {knownHelpersOnly: true});
-      var result = template({foo: function() { return this.bar; }, bar: 'bar'});
+      var template = CompilerContext.compile('{{foo}}', {
+        knownHelpersOnly: true
+      });
+      var result = template({
+        foo: function() {
+          return this.bar;
+        },
+        bar: 'bar'
+      });
       equal(result, 'bar', "'bar' should === '" + result);
     });
     it('Unknown helper call in knownHelpers only mode should throw', function() {
       shouldThrow(function() {
-        CompilerContext.compile('{{typeof hello}}', {knownHelpersOnly: true});
+        CompilerContext.compile('{{typeof hello}}', { knownHelpersOnly: true });
       }, Error);
     });
   });
@@ -563,12 +961,23 @@ describe('helpers', function() {
   describe('blockHelperMissing', function() {
     it('lambdas are resolved by blockHelperMissing, not handlebars proper', function() {
       var string = '{{#truthy}}yep{{/truthy}}';
-      var data = { truthy: function() { return true; } };
+      var data = {
+        truthy: function() {
+          return true;
+        }
+      };
       shouldCompileTo(string, data, 'yep');
     });
     it('lambdas resolved by blockHelperMissing are bound to the context', function() {
       var string = '{{#truthy}}yep{{/truthy}}';
-      var boundData = { truthy: function() { return this.truthiness(); }, truthiness: function() { return false; } };
+      var boundData = {
+        truthy: function() {
+          return this.truthiness();
+        },
+        truthiness: function() {
+          return false;
+        }
+      };
       shouldCompileTo(string, boundData, '');
     });
   });
@@ -594,26 +1003,49 @@ describe('helpers', function() {
       shouldCompileTo('{{helper 1}}', [context, helpers], 'ran: helper');
     });
     it('should include in ambiguous block calls', function() {
-      shouldCompileTo('{{#helper}}{{/helper}}', [context, helpers], 'ran: helper');
+      shouldCompileTo(
+        '{{#helper}}{{/helper}}',
+        [context, helpers],
+        'ran: helper'
+      );
     });
     it('should include in simple block calls', function() {
-      shouldCompileTo('{{#./helper}}{{/./helper}}', [context, helpers], 'missing: ./helper');
+      shouldCompileTo(
+        '{{#./helper}}{{/./helper}}',
+        [context, helpers],
+        'missing: ./helper'
+      );
     });
     it('should include in helper block calls', function() {
-      shouldCompileTo('{{#helper 1}}{{/helper}}', [context, helpers], 'ran: helper');
+      shouldCompileTo(
+        '{{#helper 1}}{{/helper}}',
+        [context, helpers],
+        'ran: helper'
+      );
     });
     it('should include in known helper calls', function() {
-      var template = CompilerContext.compile('{{helper}}', {knownHelpers: {'helper': true}, knownHelpersOnly: true});
+      var template = CompilerContext.compile('{{helper}}', {
+        knownHelpers: { helper: true },
+        knownHelpersOnly: true
+      });
 
-      equal(template({}, {helpers: helpers}), 'ran: helper');
+      equal(template({}, { helpers: helpers }), 'ran: helper');
     });
 
     it('should include full id', function() {
-      shouldCompileTo('{{#foo.helper}}{{/foo.helper}}', [{foo: {}}, helpers], 'missing: foo.helper');
+      shouldCompileTo(
+        '{{#foo.helper}}{{/foo.helper}}',
+        [{ foo: {} }, helpers],
+        'missing: foo.helper'
+      );
     });
 
     it('should include full id if a hash is passed', function() {
-      shouldCompileTo('{{#foo.helper bar=baz}}{{/foo.helper}}', [{foo: {}}, helpers], 'helper missing: foo.helper');
+      shouldCompileTo(
+        '{{#foo.helper bar=baz}}{{/foo.helper}}',
+        [{ foo: {} }, helpers],
+        'helper missing: foo.helper'
+      );
     });
   });
 
@@ -636,12 +1068,14 @@ describe('helpers', function() {
         world: 'world'
       };
 
-      var result = template(context, {helpers: helpers});
+      var result = template(context, { helpers: helpers });
       equals(result, 'GOODBYE cruel WORLD', 'Helper executed');
     });
 
     it('helpers take precedence over same-named context properties$', function() {
-      var template = CompilerContext.compile('{{#goodbye}} {{cruel world}}{{/goodbye}}');
+      var template = CompilerContext.compile(
+        '{{#goodbye}} {{cruel world}}{{/goodbye}}'
+      );
 
       var helpers = {
         goodbye: function(options) {
@@ -658,12 +1092,14 @@ describe('helpers', function() {
         world: 'world'
       };
 
-      var result = template(context, {helpers: helpers});
+      var result = template(context, { helpers: helpers });
       equals(result, 'GOODBYE cruel WORLD', 'Helper executed');
     });
 
     it('Scoped names take precedence over helpers', function() {
-      var template = CompilerContext.compile('{{this.goodbye}} {{cruel world}} {{cruel this.goodbye}}');
+      var template = CompilerContext.compile(
+        '{{this.goodbye}} {{cruel world}} {{cruel this.goodbye}}'
+      );
 
       var helpers = {
         goodbye: function() {
@@ -680,12 +1116,18 @@ describe('helpers', function() {
         world: 'world'
       };
 
-      var result = template(context, {helpers: helpers});
-      equals(result, 'goodbye cruel WORLD cruel GOODBYE', 'Helper not executed');
+      var result = template(context, { helpers: helpers });
+      equals(
+        result,
+        'goodbye cruel WORLD cruel GOODBYE',
+        'Helper not executed'
+      );
     });
 
     it('Scoped names take precedence over block helpers', function() {
-      var template = CompilerContext.compile('{{#goodbye}} {{cruel world}}{{/goodbye}} {{this.goodbye}}');
+      var template = CompilerContext.compile(
+        '{{#goodbye}} {{cruel world}}{{/goodbye}} {{this.goodbye}}'
+      );
 
       var helpers = {
         goodbye: function(options) {
@@ -702,21 +1144,25 @@ describe('helpers', function() {
         world: 'world'
       };
 
-      var result = template(context, {helpers: helpers});
+      var result = template(context, { helpers: helpers });
       equals(result, 'GOODBYE cruel WORLD goodbye', 'Helper executed');
     });
   });
 
   describe('block params', function() {
     it('should take presedence over context values', function() {
-      var hash = {value: 'foo'};
+      var hash = { value: 'foo' };
       var helpers = {
         goodbyes: function(options) {
           equals(options.fn.blockParams, 1);
-          return options.fn({value: 'bar'}, {blockParams: [1, 2]});
+          return options.fn({ value: 'bar' }, { blockParams: [1, 2] });
         }
       };
-      shouldCompileTo('{{#goodbyes as |value|}}{{value}}{{/goodbyes}}{{value}}', [hash, helpers], '1foo');
+      shouldCompileTo(
+        '{{#goodbyes as |value|}}{{value}}{{/goodbyes}}{{value}}',
+        [hash, helpers],
+        '1foo'
+      );
     });
     it('should take presedence over helper values', function() {
       var hash = {};
@@ -726,110 +1172,160 @@ describe('helpers', function() {
         },
         goodbyes: function(options) {
           equals(options.fn.blockParams, 1);
-          return options.fn({}, {blockParams: [1, 2]});
+          return options.fn({}, { blockParams: [1, 2] });
         }
       };
-      shouldCompileTo('{{#goodbyes as |value|}}{{value}}{{/goodbyes}}{{value}}', [hash, helpers], '1foo');
+      shouldCompileTo(
+        '{{#goodbyes as |value|}}{{value}}{{/goodbyes}}{{value}}',
+        [hash, helpers],
+        '1foo'
+      );
     });
     it('should not take presedence over pathed values', function() {
-      var hash = {value: 'bar'};
+      var hash = { value: 'bar' };
       var helpers = {
         value: function() {
           return 'foo';
         },
         goodbyes: function(options) {
           equals(options.fn.blockParams, 1);
-          return options.fn(this, {blockParams: [1, 2]});
+          return options.fn(this, { blockParams: [1, 2] });
         }
       };
-      shouldCompileTo('{{#goodbyes as |value|}}{{./value}}{{/goodbyes}}{{value}}', [hash, helpers], 'barfoo');
+      shouldCompileTo(
+        '{{#goodbyes as |value|}}{{./value}}{{/goodbyes}}{{value}}',
+        [hash, helpers],
+        'barfoo'
+      );
     });
     it('should take presednece over parent block params', function() {
-      var hash = {value: 'foo'},
-          value = 1;
+      var hash = { value: 'foo' },
+        value = 1;
       var helpers = {
         goodbyes: function(options) {
-          return options.fn({value: 'bar'}, {blockParams: options.fn.blockParams === 1 ? [value++, value++] : undefined});
+          return options.fn(
+            { value: 'bar' },
+            {
+              blockParams:
+                options.fn.blockParams === 1 ? [value++, value++] : undefined
+            }
+          );
         }
       };
-      shouldCompileTo('{{#goodbyes as |value|}}{{#goodbyes}}{{value}}{{#goodbyes as |value|}}{{value}}{{/goodbyes}}{{/goodbyes}}{{/goodbyes}}{{value}}', [hash, helpers], '13foo');
+      shouldCompileTo(
+        '{{#goodbyes as |value|}}{{#goodbyes}}{{value}}{{#goodbyes as |value|}}{{value}}{{/goodbyes}}{{/goodbyes}}{{/goodbyes}}{{value}}',
+        [hash, helpers],
+        '13foo'
+      );
     });
 
     it('should allow block params on chained helpers', function() {
-      var hash = {value: 'foo'};
+      var hash = { value: 'foo' };
       var helpers = {
         goodbyes: function(options) {
           equals(options.fn.blockParams, 1);
-          return options.fn({value: 'bar'}, {blockParams: [1, 2]});
+          return options.fn({ value: 'bar' }, { blockParams: [1, 2] });
         }
       };
-      shouldCompileTo('{{#if bar}}{{else goodbyes as |value|}}{{value}}{{/if}}{{value}}', [hash, helpers], '1foo');
+      shouldCompileTo(
+        '{{#if bar}}{{else goodbyes as |value|}}{{value}}{{/if}}{{value}}',
+        [hash, helpers],
+        '1foo'
+      );
     });
   });
 
   describe('built-in helpers malformed arguments ', function() {
     it('if helper - too few arguments', function() {
       var template = CompilerContext.compile('{{#if}}{{/if}}');
-        shouldThrow(function() {
-
-            template({});
-        }, undefined, /#if requires exactly one argument/);
+      shouldThrow(
+        function() {
+          template({});
+        },
+        undefined,
+        /#if requires exactly one argument/
+      );
     });
 
     it('if helper - too many arguments, string', function() {
       var template = CompilerContext.compile('{{#if test "string"}}{{/if}}');
-        shouldThrow(function() {
-
-            template({});
-        }, undefined, /#if requires exactly one argument/);
+      shouldThrow(
+        function() {
+          template({});
+        },
+        undefined,
+        /#if requires exactly one argument/
+      );
     });
 
     it('if helper - too many arguments, undefined', function() {
       var template = CompilerContext.compile('{{#if test undefined}}{{/if}}');
-        shouldThrow(function() {
-
-            template({});
-        }, undefined, /#if requires exactly one argument/);
+      shouldThrow(
+        function() {
+          template({});
+        },
+        undefined,
+        /#if requires exactly one argument/
+      );
     });
 
     it('if helper - too many arguments, null', function() {
       var template = CompilerContext.compile('{{#if test null}}{{/if}}');
-        shouldThrow(function() {
-
-            template({});
-        }, undefined, /#if requires exactly one argument/);
+      shouldThrow(
+        function() {
+          template({});
+        },
+        undefined,
+        /#if requires exactly one argument/
+      );
     });
 
     it('unless helper - too few arguments', function() {
       var template = CompilerContext.compile('{{#unless}}{{/unless}}');
-        shouldThrow(function() {
-
-            template({});
-        }, undefined, /#unless requires exactly one argument/);
+      shouldThrow(
+        function() {
+          template({});
+        },
+        undefined,
+        /#unless requires exactly one argument/
+      );
     });
 
     it('unless helper - too many arguments', function() {
-      var template = CompilerContext.compile('{{#unless test null}}{{/unless}}');
-        shouldThrow(function() {
-
-            template({});
-        }, undefined, /#unless requires exactly one argument/);
+      var template = CompilerContext.compile(
+        '{{#unless test null}}{{/unless}}'
+      );
+      shouldThrow(
+        function() {
+          template({});
+        },
+        undefined,
+        /#unless requires exactly one argument/
+      );
     });
 
     it('with helper - too few arguments', function() {
       var template = CompilerContext.compile('{{#with}}{{/with}}');
-        shouldThrow(function() {
-
-            template({});
-        }, undefined, /#with requires exactly one argument/);
+      shouldThrow(
+        function() {
+          template({});
+        },
+        undefined,
+        /#with requires exactly one argument/
+      );
     });
 
     it('with helper - too many arguments', function() {
-      var template = CompilerContext.compile('{{#with test "string"}}{{/with}}');
-        shouldThrow(function() {
-
-            template({});
-        }, undefined, /#with requires exactly one argument/);
+      var template = CompilerContext.compile(
+        '{{#with test "string"}}{{/with}}'
+      );
+      shouldThrow(
+        function() {
+          template({});
+        },
+        undefined,
+        /#with requires exactly one argument/
+      );
     });
   });
 });
diff --git a/spec/javascript-compiler.js b/spec/javascript-compiler.js
index 5a10388f0..21b8e2a0a 100644
--- a/spec/javascript-compiler.js
+++ b/spec/javascript-compiler.js
@@ -13,7 +13,10 @@ describe('javascript-compiler api', function() {
     });
 
     it('should allow override', function() {
-      handlebarsEnv.JavaScriptCompiler.prototype.nameLookup = function(parent, name) {
+      handlebarsEnv.JavaScriptCompiler.prototype.nameLookup = function(
+        parent,
+        name
+      ) {
         return parent + '.bar_' + name;
       };
       /* eslint-disable camelcase */
@@ -43,7 +46,7 @@ describe('javascript-compiler api', function() {
       };
       handlebarsEnv.VM.checkRevision = function(compilerInfo) {
         if (compilerInfo !== 'crazy') {
-          throw new Error('It didn\'t work');
+          throw new Error("It didn't work");
         }
       };
       shouldCompileTo('{{foo}} ', { foo: 'food' }, 'food ');
@@ -54,7 +57,8 @@ describe('javascript-compiler api', function() {
     beforeEach(function() {
       handlebarsEnv.JavaScriptCompiler.prototype.forceBuffer = true;
       $superAppend = handlebarsEnv.JavaScriptCompiler.prototype.appendToBuffer;
-      $superCreate = handlebarsEnv.JavaScriptCompiler.prototype.initializeBuffer;
+      $superCreate =
+        handlebarsEnv.JavaScriptCompiler.prototype.initializeBuffer;
     });
     afterEach(function() {
       handlebarsEnv.JavaScriptCompiler.prototype.forceBuffer = false;
@@ -69,7 +73,9 @@ describe('javascript-compiler api', function() {
       shouldCompileTo('{{foo}} ', { foo: 'food' }, 'foo_food ');
     });
     it('should allow append buffer override', function() {
-      handlebarsEnv.JavaScriptCompiler.prototype.appendToBuffer = function(string) {
+      handlebarsEnv.JavaScriptCompiler.prototype.appendToBuffer = function(
+        string
+      ) {
         return $superAppend.call(this, [string, ' + "_foo"']);
       };
       shouldCompileTo('{{foo}}', { foo: 'food' }, 'food_foo');
diff --git a/spec/parser.js b/spec/parser.js
index 856031c3b..2aa7e39ff 100644
--- a/spec/parser.js
+++ b/spec/parser.js
@@ -68,7 +68,10 @@ describe('parser', function() {
     equals(astFor('{{null}}'), '{{ NULL [] }}\n');
   });
   it('parses mustaches with undefined and null parameters', function() {
-    equals(astFor('{{foo undefined null}}'), '{{ PATH:foo [UNDEFINED, NULL] }}\n');
+    equals(
+      astFor('{{foo undefined null}}'),
+      '{{ PATH:foo [UNDEFINED, NULL] }}\n'
+    );
   });
 
   it('parses mustaches with DATA parameters', function() {
@@ -78,23 +81,53 @@ describe('parser', function() {
   it('parses mustaches with hash arguments', function() {
     equals(astFor('{{foo bar=baz}}'), '{{ PATH:foo [] HASH{bar=PATH:baz} }}\n');
     equals(astFor('{{foo bar=1}}'), '{{ PATH:foo [] HASH{bar=NUMBER{1}} }}\n');
-    equals(astFor('{{foo bar=true}}'), '{{ PATH:foo [] HASH{bar=BOOLEAN{true}} }}\n');
-    equals(astFor('{{foo bar=false}}'), '{{ PATH:foo [] HASH{bar=BOOLEAN{false}} }}\n');
-    equals(astFor('{{foo bar=@baz}}'), '{{ PATH:foo [] HASH{bar=@PATH:baz} }}\n');
-
-    equals(astFor('{{foo bar=baz bat=bam}}'), '{{ PATH:foo [] HASH{bar=PATH:baz, bat=PATH:bam} }}\n');
-    equals(astFor('{{foo bar=baz bat="bam"}}'), '{{ PATH:foo [] HASH{bar=PATH:baz, bat="bam"} }}\n');
+    equals(
+      astFor('{{foo bar=true}}'),
+      '{{ PATH:foo [] HASH{bar=BOOLEAN{true}} }}\n'
+    );
+    equals(
+      astFor('{{foo bar=false}}'),
+      '{{ PATH:foo [] HASH{bar=BOOLEAN{false}} }}\n'
+    );
+    equals(
+      astFor('{{foo bar=@baz}}'),
+      '{{ PATH:foo [] HASH{bar=@PATH:baz} }}\n'
+    );
+
+    equals(
+      astFor('{{foo bar=baz bat=bam}}'),
+      '{{ PATH:foo [] HASH{bar=PATH:baz, bat=PATH:bam} }}\n'
+    );
+    equals(
+      astFor('{{foo bar=baz bat="bam"}}'),
+      '{{ PATH:foo [] HASH{bar=PATH:baz, bat="bam"} }}\n'
+    );
 
     equals(astFor("{{foo bat='bam'}}"), '{{ PATH:foo [] HASH{bat="bam"} }}\n');
 
-    equals(astFor('{{foo omg bar=baz bat="bam"}}'), '{{ PATH:foo [PATH:omg] HASH{bar=PATH:baz, bat="bam"} }}\n');
-    equals(astFor('{{foo omg bar=baz bat="bam" baz=1}}'), '{{ PATH:foo [PATH:omg] HASH{bar=PATH:baz, bat="bam", baz=NUMBER{1}} }}\n');
-    equals(astFor('{{foo omg bar=baz bat="bam" baz=true}}'), '{{ PATH:foo [PATH:omg] HASH{bar=PATH:baz, bat="bam", baz=BOOLEAN{true}} }}\n');
-    equals(astFor('{{foo omg bar=baz bat="bam" baz=false}}'), '{{ PATH:foo [PATH:omg] HASH{bar=PATH:baz, bat="bam", baz=BOOLEAN{false}} }}\n');
+    equals(
+      astFor('{{foo omg bar=baz bat="bam"}}'),
+      '{{ PATH:foo [PATH:omg] HASH{bar=PATH:baz, bat="bam"} }}\n'
+    );
+    equals(
+      astFor('{{foo omg bar=baz bat="bam" baz=1}}'),
+      '{{ PATH:foo [PATH:omg] HASH{bar=PATH:baz, bat="bam", baz=NUMBER{1}} }}\n'
+    );
+    equals(
+      astFor('{{foo omg bar=baz bat="bam" baz=true}}'),
+      '{{ PATH:foo [PATH:omg] HASH{bar=PATH:baz, bat="bam", baz=BOOLEAN{true}} }}\n'
+    );
+    equals(
+      astFor('{{foo omg bar=baz bat="bam" baz=false}}'),
+      '{{ PATH:foo [PATH:omg] HASH{bar=PATH:baz, bat="bam", baz=BOOLEAN{false}} }}\n'
+    );
   });
 
   it('parses contents followed by a mustache', function() {
-    equals(astFor('foo bar {{baz}}'), 'CONTENT[ \'foo bar \' ]\n{{ PATH:baz [] }}\n');
+    equals(
+      astFor('foo bar {{baz}}'),
+      "CONTENT[ 'foo bar ' ]\n{{ PATH:baz [] }}\n"
+    );
   });
 
   it('parses a partial', function() {
@@ -108,47 +141,81 @@ describe('parser', function() {
   });
 
   it('parses a partial with hash', function() {
-    equals(astFor('{{> foo bar=bat}}'), '{{> PARTIAL:foo HASH{bar=PATH:bat} }}\n');
+    equals(
+      astFor('{{> foo bar=bat}}'),
+      '{{> PARTIAL:foo HASH{bar=PATH:bat} }}\n'
+    );
   });
 
   it('parses a partial with context and hash', function() {
-    equals(astFor('{{> foo bar bat=baz}}'), '{{> PARTIAL:foo PATH:bar HASH{bat=PATH:baz} }}\n');
+    equals(
+      astFor('{{> foo bar bat=baz}}'),
+      '{{> PARTIAL:foo PATH:bar HASH{bat=PATH:baz} }}\n'
+    );
   });
 
   it('parses a partial with a complex name', function() {
-    equals(astFor('{{> shared/partial?.bar}}'), '{{> PARTIAL:shared/partial?.bar }}\n');
+    equals(
+      astFor('{{> shared/partial?.bar}}'),
+      '{{> PARTIAL:shared/partial?.bar }}\n'
+    );
   });
 
   it('parsers partial blocks', function() {
-    equals(astFor('{{#> foo}}bar{{/foo}}'), '{{> PARTIAL BLOCK:foo PROGRAM:\n  CONTENT[ \'bar\' ]\n }}\n');
+    equals(
+      astFor('{{#> foo}}bar{{/foo}}'),
+      "{{> PARTIAL BLOCK:foo PROGRAM:\n  CONTENT[ 'bar' ]\n }}\n"
+    );
   });
   it('should handle parser block mismatch', function() {
-    shouldThrow(function() {
-      astFor('{{#> goodbyes}}{{/hellos}}');
-    }, Error, (/goodbyes doesn't match hellos/));
+    shouldThrow(
+      function() {
+        astFor('{{#> goodbyes}}{{/hellos}}');
+      },
+      Error,
+      /goodbyes doesn't match hellos/
+    );
   });
   it('parsers partial blocks with arguments', function() {
-    equals(astFor('{{#> foo context hash=value}}bar{{/foo}}'), '{{> PARTIAL BLOCK:foo PATH:context HASH{hash=PATH:value} PROGRAM:\n  CONTENT[ \'bar\' ]\n }}\n');
+    equals(
+      astFor('{{#> foo context hash=value}}bar{{/foo}}'),
+      "{{> PARTIAL BLOCK:foo PATH:context HASH{hash=PATH:value} PROGRAM:\n  CONTENT[ 'bar' ]\n }}\n"
+    );
   });
 
   it('parses a comment', function() {
-    equals(astFor('{{! this is a comment }}'), "{{! ' this is a comment ' }}\n");
+    equals(
+      astFor('{{! this is a comment }}'),
+      "{{! ' this is a comment ' }}\n"
+    );
   });
 
   it('parses a multi-line comment', function() {
-    equals(astFor('{{!\nthis is a multi-line comment\n}}'), "{{! '\nthis is a multi-line comment\n' }}\n");
+    equals(
+      astFor('{{!\nthis is a multi-line comment\n}}'),
+      "{{! '\nthis is a multi-line comment\n' }}\n"
+    );
   });
 
   it('parses an inverse section', function() {
-    equals(astFor('{{#foo}} bar {{^}} baz {{/foo}}'), "BLOCK:\n  PATH:foo []\n  PROGRAM:\n    CONTENT[ ' bar ' ]\n  {{^}}\n    CONTENT[ ' baz ' ]\n");
+    equals(
+      astFor('{{#foo}} bar {{^}} baz {{/foo}}'),
+      "BLOCK:\n  PATH:foo []\n  PROGRAM:\n    CONTENT[ ' bar ' ]\n  {{^}}\n    CONTENT[ ' baz ' ]\n"
+    );
   });
 
   it('parses an inverse (else-style) section', function() {
-    equals(astFor('{{#foo}} bar {{else}} baz {{/foo}}'), "BLOCK:\n  PATH:foo []\n  PROGRAM:\n    CONTENT[ ' bar ' ]\n  {{^}}\n    CONTENT[ ' baz ' ]\n");
+    equals(
+      astFor('{{#foo}} bar {{else}} baz {{/foo}}'),
+      "BLOCK:\n  PATH:foo []\n  PROGRAM:\n    CONTENT[ ' bar ' ]\n  {{^}}\n    CONTENT[ ' baz ' ]\n"
+    );
   });
 
   it('parses multiple inverse sections', function() {
-    equals(astFor('{{#foo}} bar {{else if bar}}{{else}} baz {{/foo}}'), "BLOCK:\n  PATH:foo []\n  PROGRAM:\n    CONTENT[ ' bar ' ]\n  {{^}}\n    BLOCK:\n      PATH:if [PATH:bar]\n      PROGRAM:\n      {{^}}\n        CONTENT[ ' baz ' ]\n");
+    equals(
+      astFor('{{#foo}} bar {{else if bar}}{{else}} baz {{/foo}}'),
+      "BLOCK:\n  PATH:foo []\n  PROGRAM:\n    CONTENT[ ' bar ' ]\n  {{^}}\n    BLOCK:\n      PATH:if [PATH:bar]\n      PROGRAM:\n      {{^}}\n        CONTENT[ ' baz ' ]\n"
+    );
   });
 
   it('parses empty blocks', function() {
@@ -156,31 +223,52 @@ describe('parser', function() {
   });
 
   it('parses empty blocks with empty inverse section', function() {
-    equals(astFor('{{#foo}}{{^}}{{/foo}}'), 'BLOCK:\n  PATH:foo []\n  PROGRAM:\n  {{^}}\n');
+    equals(
+      astFor('{{#foo}}{{^}}{{/foo}}'),
+      'BLOCK:\n  PATH:foo []\n  PROGRAM:\n  {{^}}\n'
+    );
   });
 
   it('parses empty blocks with empty inverse (else-style) section', function() {
-    equals(astFor('{{#foo}}{{else}}{{/foo}}'), 'BLOCK:\n  PATH:foo []\n  PROGRAM:\n  {{^}}\n');
+    equals(
+      astFor('{{#foo}}{{else}}{{/foo}}'),
+      'BLOCK:\n  PATH:foo []\n  PROGRAM:\n  {{^}}\n'
+    );
   });
 
   it('parses non-empty blocks with empty inverse section', function() {
-    equals(astFor('{{#foo}} bar {{^}}{{/foo}}'), "BLOCK:\n  PATH:foo []\n  PROGRAM:\n    CONTENT[ ' bar ' ]\n  {{^}}\n");
+    equals(
+      astFor('{{#foo}} bar {{^}}{{/foo}}'),
+      "BLOCK:\n  PATH:foo []\n  PROGRAM:\n    CONTENT[ ' bar ' ]\n  {{^}}\n"
+    );
   });
 
   it('parses non-empty blocks with empty inverse (else-style) section', function() {
-    equals(astFor('{{#foo}} bar {{else}}{{/foo}}'), "BLOCK:\n  PATH:foo []\n  PROGRAM:\n    CONTENT[ ' bar ' ]\n  {{^}}\n");
+    equals(
+      astFor('{{#foo}} bar {{else}}{{/foo}}'),
+      "BLOCK:\n  PATH:foo []\n  PROGRAM:\n    CONTENT[ ' bar ' ]\n  {{^}}\n"
+    );
   });
 
   it('parses empty blocks with non-empty inverse section', function() {
-    equals(astFor('{{#foo}}{{^}} bar {{/foo}}'), "BLOCK:\n  PATH:foo []\n  PROGRAM:\n  {{^}}\n    CONTENT[ ' bar ' ]\n");
+    equals(
+      astFor('{{#foo}}{{^}} bar {{/foo}}'),
+      "BLOCK:\n  PATH:foo []\n  PROGRAM:\n  {{^}}\n    CONTENT[ ' bar ' ]\n"
+    );
   });
 
   it('parses empty blocks with non-empty inverse (else-style) section', function() {
-    equals(astFor('{{#foo}}{{else}} bar {{/foo}}'), "BLOCK:\n  PATH:foo []\n  PROGRAM:\n  {{^}}\n    CONTENT[ ' bar ' ]\n");
+    equals(
+      astFor('{{#foo}}{{else}} bar {{/foo}}'),
+      "BLOCK:\n  PATH:foo []\n  PROGRAM:\n  {{^}}\n    CONTENT[ ' bar ' ]\n"
+    );
   });
 
   it('parses a standalone inverse section', function() {
-    equals(astFor('{{^foo}}bar{{/foo}}'), "BLOCK:\n  PATH:foo []\n  {{^}}\n    CONTENT[ 'bar' ]\n");
+    equals(
+      astFor('{{^foo}}bar{{/foo}}'),
+      "BLOCK:\n  PATH:foo []\n  {{^}}\n    CONTENT[ 'bar' ]\n"
+    );
   });
   it('throws on old inverse section', function() {
     shouldThrow(function() {
@@ -189,105 +277,179 @@ describe('parser', function() {
   });
 
   it('parses block with block params', function() {
-    equals(astFor('{{#foo as |bar baz|}}content{{/foo}}'), "BLOCK:\n  PATH:foo []\n  PROGRAM:\n    BLOCK PARAMS: [ bar baz ]\n    CONTENT[ 'content' ]\n");
+    equals(
+      astFor('{{#foo as |bar baz|}}content{{/foo}}'),
+      "BLOCK:\n  PATH:foo []\n  PROGRAM:\n    BLOCK PARAMS: [ bar baz ]\n    CONTENT[ 'content' ]\n"
+    );
   });
 
   it('parses inverse block with block params', function() {
-    equals(astFor('{{^foo as |bar baz|}}content{{/foo}}'), "BLOCK:\n  PATH:foo []\n  {{^}}\n    BLOCK PARAMS: [ bar baz ]\n    CONTENT[ 'content' ]\n");
+    equals(
+      astFor('{{^foo as |bar baz|}}content{{/foo}}'),
+      "BLOCK:\n  PATH:foo []\n  {{^}}\n    BLOCK PARAMS: [ bar baz ]\n    CONTENT[ 'content' ]\n"
+    );
   });
   it('parses chained inverse block with block params', function() {
-    equals(astFor('{{#foo}}{{else foo as |bar baz|}}content{{/foo}}'), "BLOCK:\n  PATH:foo []\n  PROGRAM:\n  {{^}}\n    BLOCK:\n      PATH:foo []\n      PROGRAM:\n        BLOCK PARAMS: [ bar baz ]\n        CONTENT[ 'content' ]\n");
-  });
-  it('raises if there\'s a Parse error', function() {
-    shouldThrow(function() {
-      astFor('foo{{^}}bar');
-    }, Error, /Parse error on line 1/);
-    shouldThrow(function() {
-      astFor('{{foo}');
-    }, Error, /Parse error on line 1/);
-    shouldThrow(function() {
-      astFor('{{foo &}}');
-    }, Error, /Parse error on line 1/);
-    shouldThrow(function() {
-      astFor('{{#goodbyes}}{{/hellos}}');
-    }, Error, /goodbyes doesn't match hellos/);
-
-    shouldThrow(function() {
-      astFor('{{{{goodbyes}}}} {{{{/hellos}}}}');
-    }, Error, /goodbyes doesn't match hellos/);
+    equals(
+      astFor('{{#foo}}{{else foo as |bar baz|}}content{{/foo}}'),
+      "BLOCK:\n  PATH:foo []\n  PROGRAM:\n  {{^}}\n    BLOCK:\n      PATH:foo []\n      PROGRAM:\n        BLOCK PARAMS: [ bar baz ]\n        CONTENT[ 'content' ]\n"
+    );
+  });
+  it("raises if there's a Parse error", function() {
+    shouldThrow(
+      function() {
+        astFor('foo{{^}}bar');
+      },
+      Error,
+      /Parse error on line 1/
+    );
+    shouldThrow(
+      function() {
+        astFor('{{foo}');
+      },
+      Error,
+      /Parse error on line 1/
+    );
+    shouldThrow(
+      function() {
+        astFor('{{foo &}}');
+      },
+      Error,
+      /Parse error on line 1/
+    );
+    shouldThrow(
+      function() {
+        astFor('{{#goodbyes}}{{/hellos}}');
+      },
+      Error,
+      /goodbyes doesn't match hellos/
+    );
+
+    shouldThrow(
+      function() {
+        astFor('{{{{goodbyes}}}} {{{{/hellos}}}}');
+      },
+      Error,
+      /goodbyes doesn't match hellos/
+    );
   });
 
   it('should handle invalid paths', function() {
-    shouldThrow(function() {
-      astFor('{{foo/../bar}}');
-    }, Error, /Invalid path: foo\/\.\. - 1:2/);
-    shouldThrow(function() {
-      astFor('{{foo/./bar}}');
-    }, Error, /Invalid path: foo\/\. - 1:2/);
-    shouldThrow(function() {
-      astFor('{{foo/this/bar}}');
-    }, Error, /Invalid path: foo\/this - 1:2/);
+    shouldThrow(
+      function() {
+        astFor('{{foo/../bar}}');
+      },
+      Error,
+      /Invalid path: foo\/\.\. - 1:2/
+    );
+    shouldThrow(
+      function() {
+        astFor('{{foo/./bar}}');
+      },
+      Error,
+      /Invalid path: foo\/\. - 1:2/
+    );
+    shouldThrow(
+      function() {
+        astFor('{{foo/this/bar}}');
+      },
+      Error,
+      /Invalid path: foo\/this - 1:2/
+    );
   });
 
   it('knows how to report the correct line number in errors', function() {
-    shouldThrow(function() {
-      astFor('hello\nmy\n{{foo}');
-    }, Error, /Parse error on line 3/);
-    shouldThrow(function() {
-      astFor('hello\n\nmy\n\n{{foo}');
-    }, Error, /Parse error on line 5/);
+    shouldThrow(
+      function() {
+        astFor('hello\nmy\n{{foo}');
+      },
+      Error,
+      /Parse error on line 3/
+    );
+    shouldThrow(
+      function() {
+        astFor('hello\n\nmy\n\n{{foo}');
+      },
+      Error,
+      /Parse error on line 5/
+    );
   });
 
   it('knows how to report the correct line number in errors when the first character is a newline', function() {
-    shouldThrow(function() {
-      astFor('\n\nhello\n\nmy\n\n{{foo}');
-    }, Error, /Parse error on line 7/);
+    shouldThrow(
+      function() {
+        astFor('\n\nhello\n\nmy\n\n{{foo}');
+      },
+      Error,
+      /Parse error on line 7/
+    );
   });
 
   describe('externally compiled AST', function() {
     it('can pass through an already-compiled AST', function() {
-      equals(astFor({
-        type: 'Program',
-        body: [ {type: 'ContentStatement', value: 'Hello'}]
-      }), 'CONTENT[ \'Hello\' ]\n');
+      equals(
+        astFor({
+          type: 'Program',
+          body: [{ type: 'ContentStatement', value: 'Hello' }]
+        }),
+        "CONTENT[ 'Hello' ]\n"
+      );
     });
   });
 
   describe('directives', function() {
     it('should parse block directives', function() {
-      equals(astFor('{{#* foo}}{{/foo}}'), 'DIRECTIVE BLOCK:\n  PATH:foo []\n  PROGRAM:\n');
+      equals(
+        astFor('{{#* foo}}{{/foo}}'),
+        'DIRECTIVE BLOCK:\n  PATH:foo []\n  PROGRAM:\n'
+      );
     });
     it('should parse directives', function() {
       equals(astFor('{{* foo}}'), '{{ DIRECTIVE PATH:foo [] }}\n');
     });
     it('should fail if directives have inverse', function() {
-      shouldThrow(function() {
-        astFor('{{#* foo}}{{^}}{{/foo}}');
-      }, Error, /Unexpected inverse/);
+      shouldThrow(
+        function() {
+          astFor('{{#* foo}}{{^}}{{/foo}}');
+        },
+        Error,
+        /Unexpected inverse/
+      );
     });
   });
 
   it('GH1024 - should track program location properly', function() {
-    var p = Handlebars.parse('\n'
-      + '  {{#if foo}}\n'
-      + '    {{bar}}\n'
-      + '       {{else}}    {{baz}}\n'
-      + '\n'
-      + '     {{/if}}\n'
-      + '    ');
+    var p = Handlebars.parse(
+      '\n' +
+        '  {{#if foo}}\n' +
+        '    {{bar}}\n' +
+        '       {{else}}    {{baz}}\n' +
+        '\n' +
+        '     {{/if}}\n' +
+        '    '
+    );
 
     // We really need a deep equals but for now this should be stable...
-    equals(JSON.stringify(p.loc), JSON.stringify({
-      start: { line: 1, column: 0 },
-      end: { line: 7, column: 4 }
-    }));
-    equals(JSON.stringify(p.body[1].program.loc), JSON.stringify({
-      start: { line: 2, column: 13 },
-      end: { line: 4, column: 7 }
-    }));
-    equals(JSON.stringify(p.body[1].inverse.loc), JSON.stringify({
-      start: { line: 4, column: 15 },
-      end: { line: 6, column: 5 }
-    }));
+    equals(
+      JSON.stringify(p.loc),
+      JSON.stringify({
+        start: { line: 1, column: 0 },
+        end: { line: 7, column: 4 }
+      })
+    );
+    equals(
+      JSON.stringify(p.body[1].program.loc),
+      JSON.stringify({
+        start: { line: 2, column: 13 },
+        end: { line: 4, column: 7 }
+      })
+    );
+    equals(
+      JSON.stringify(p.body[1].inverse.loc),
+      JSON.stringify({
+        start: { line: 4, column: 15 },
+        end: { line: 6, column: 5 }
+      })
+    );
   });
 });
diff --git a/spec/partials.js b/spec/partials.js
index 79f1dc881..d00d4147e 100644
--- a/spec/partials.js
+++ b/spec/partials.js
@@ -2,115 +2,224 @@ describe('partials', function() {
   it('basic partials', function() {
     var string = 'Dudes: {{#dudes}}{{> dude}}{{/dudes}}';
     var partial = '{{name}} ({{url}}) ';
-    var hash = {dudes: [{name: 'Yehuda', url: 'http://yehuda'}, {name: 'Alan', url: 'http://alan'}]};
-    shouldCompileToWithPartials(string, [hash, {}, {dude: partial}], true, 'Dudes: Yehuda (http://yehuda) Alan (http://alan) ');
-    shouldCompileToWithPartials(string, [hash, {}, {dude: partial},, false], true, 'Dudes: Yehuda (http://yehuda) Alan (http://alan) ');
+    var hash = {
+      dudes: [
+        { name: 'Yehuda', url: 'http://yehuda' },
+        { name: 'Alan', url: 'http://alan' }
+      ]
+    };
+    shouldCompileToWithPartials(
+      string,
+      [hash, {}, { dude: partial }],
+      true,
+      'Dudes: Yehuda (http://yehuda) Alan (http://alan) '
+    );
+    shouldCompileToWithPartials(
+      string,
+      [hash, {}, { dude: partial }, , false],
+      true,
+      'Dudes: Yehuda (http://yehuda) Alan (http://alan) '
+    );
   });
 
   it('dynamic partials', function() {
     var string = 'Dudes: {{#dudes}}{{> (partial)}}{{/dudes}}';
     var partial = '{{name}} ({{url}}) ';
-    var hash = {dudes: [{name: 'Yehuda', url: 'http://yehuda'}, {name: 'Alan', url: 'http://alan'}]};
+    var hash = {
+      dudes: [
+        { name: 'Yehuda', url: 'http://yehuda' },
+        { name: 'Alan', url: 'http://alan' }
+      ]
+    };
     var helpers = {
       partial: function() {
         return 'dude';
       }
     };
-    shouldCompileToWithPartials(string, [hash, helpers, {dude: partial}], true, 'Dudes: Yehuda (http://yehuda) Alan (http://alan) ');
-    shouldCompileToWithPartials(string, [hash, helpers, {dude: partial},, false], true, 'Dudes: Yehuda (http://yehuda) Alan (http://alan) ');
+    shouldCompileToWithPartials(
+      string,
+      [hash, helpers, { dude: partial }],
+      true,
+      'Dudes: Yehuda (http://yehuda) Alan (http://alan) '
+    );
+    shouldCompileToWithPartials(
+      string,
+      [hash, helpers, { dude: partial }, , false],
+      true,
+      'Dudes: Yehuda (http://yehuda) Alan (http://alan) '
+    );
   });
   it('failing dynamic partials', function() {
     var string = 'Dudes: {{#dudes}}{{> (partial)}}{{/dudes}}';
     var partial = '{{name}} ({{url}}) ';
-    var hash = {dudes: [{name: 'Yehuda', url: 'http://yehuda'}, {name: 'Alan', url: 'http://alan'}]};
+    var hash = {
+      dudes: [
+        { name: 'Yehuda', url: 'http://yehuda' },
+        { name: 'Alan', url: 'http://alan' }
+      ]
+    };
     var helpers = {
       partial: function() {
         return 'missing';
       }
     };
-    shouldThrow(function() {
-      shouldCompileToWithPartials(string, [hash, helpers, {dude: partial}], true, 'Dudes: Yehuda (http://yehuda) Alan (http://alan) ');
-    }, Handlebars.Exception, 'The partial missing could not be found');
+    shouldThrow(
+      function() {
+        shouldCompileToWithPartials(
+          string,
+          [hash, helpers, { dude: partial }],
+          true,
+          'Dudes: Yehuda (http://yehuda) Alan (http://alan) '
+        );
+      },
+      Handlebars.Exception,
+      'The partial missing could not be found'
+    );
   });
 
   it('partials with context', function() {
     var string = 'Dudes: {{>dude dudes}}';
     var partial = '{{#this}}{{name}} ({{url}}) {{/this}}';
-    var hash = {dudes: [{name: 'Yehuda', url: 'http://yehuda'}, {name: 'Alan', url: 'http://alan'}]};
-    shouldCompileToWithPartials(string, [hash, {}, {dude: partial}], true, 'Dudes: Yehuda (http://yehuda) Alan (http://alan) ',
-                    'Partials can be passed a context');
+    var hash = {
+      dudes: [
+        { name: 'Yehuda', url: 'http://yehuda' },
+        { name: 'Alan', url: 'http://alan' }
+      ]
+    };
+    shouldCompileToWithPartials(
+      string,
+      [hash, {}, { dude: partial }],
+      true,
+      'Dudes: Yehuda (http://yehuda) Alan (http://alan) ',
+      'Partials can be passed a context'
+    );
   });
 
   it('partials with no context', function() {
     var partial = '{{name}} ({{url}}) ';
-    var hash = {dudes: [{name: 'Yehuda', url: 'http://yehuda'}, {name: 'Alan', url: 'http://alan'}]};
+    var hash = {
+      dudes: [
+        { name: 'Yehuda', url: 'http://yehuda' },
+        { name: 'Alan', url: 'http://alan' }
+      ]
+    };
     shouldCompileToWithPartials(
-        'Dudes: {{#dudes}}{{>dude}}{{/dudes}}',
-        [hash, {}, {dude: partial}, {explicitPartialContext: true}],
-        true,
-        'Dudes:  ()  () ');
+      'Dudes: {{#dudes}}{{>dude}}{{/dudes}}',
+      [hash, {}, { dude: partial }, { explicitPartialContext: true }],
+      true,
+      'Dudes:  ()  () '
+    );
     shouldCompileToWithPartials(
-        'Dudes: {{#dudes}}{{>dude name="foo"}}{{/dudes}}',
-        [hash, {}, {dude: partial}, {explicitPartialContext: true}],
-        true,
-        'Dudes: foo () foo () ');
+      'Dudes: {{#dudes}}{{>dude name="foo"}}{{/dudes}}',
+      [hash, {}, { dude: partial }, { explicitPartialContext: true }],
+      true,
+      'Dudes: foo () foo () '
+    );
   });
 
   it('partials with string context', function() {
     var string = 'Dudes: {{>dude "dudes"}}';
     var partial = '{{.}}';
     var hash = {};
-    shouldCompileToWithPartials(string, [hash, {}, {dude: partial}], true, 'Dudes: dudes');
+    shouldCompileToWithPartials(
+      string,
+      [hash, {}, { dude: partial }],
+      true,
+      'Dudes: dudes'
+    );
   });
 
   it('partials with undefined context', function() {
     var string = 'Dudes: {{>dude dudes}}';
     var partial = '{{foo}} Empty';
     var hash = {};
-    shouldCompileToWithPartials(string, [hash, {}, {dude: partial}], true, 'Dudes:  Empty');
+    shouldCompileToWithPartials(
+      string,
+      [hash, {}, { dude: partial }],
+      true,
+      'Dudes:  Empty'
+    );
   });
 
   it('partials with duplicate parameters', function() {
-    shouldThrow(function() {
-      CompilerContext.compile('Dudes: {{>dude dudes foo bar=baz}}');
-    }, Error, 'Unsupported number of partial arguments: 2 - 1:7');
+    shouldThrow(
+      function() {
+        CompilerContext.compile('Dudes: {{>dude dudes foo bar=baz}}');
+      },
+      Error,
+      'Unsupported number of partial arguments: 2 - 1:7'
+    );
   });
 
   it('partials with parameters', function() {
     var string = 'Dudes: {{#dudes}}{{> dude others=..}}{{/dudes}}';
     var partial = '{{others.foo}}{{name}} ({{url}}) ';
-    var hash = {foo: 'bar', dudes: [{name: 'Yehuda', url: 'http://yehuda'}, {name: 'Alan', url: 'http://alan'}]};
-    shouldCompileToWithPartials(string, [hash, {}, {dude: partial}], true, 'Dudes: barYehuda (http://yehuda) barAlan (http://alan) ',
-                    'Basic partials output based on current context.');
+    var hash = {
+      foo: 'bar',
+      dudes: [
+        { name: 'Yehuda', url: 'http://yehuda' },
+        { name: 'Alan', url: 'http://alan' }
+      ]
+    };
+    shouldCompileToWithPartials(
+      string,
+      [hash, {}, { dude: partial }],
+      true,
+      'Dudes: barYehuda (http://yehuda) barAlan (http://alan) ',
+      'Basic partials output based on current context.'
+    );
   });
 
   it('partial in a partial', function() {
     var string = 'Dudes: {{#dudes}}{{>dude}}{{/dudes}}';
     var dude = '{{name}} {{> url}} ';
     var url = '<a href="{{url}}">{{url}}</a>';
-    var hash = {dudes: [{name: 'Yehuda', url: 'http://yehuda'}, {name: 'Alan', url: 'http://alan'}]};
-    shouldCompileToWithPartials(string, [hash, {}, {dude: dude, url: url}], true, 'Dudes: Yehuda <a href="http://yehuda">http://yehuda</a> Alan <a href="http://alan">http://alan</a> ', 'Partials are rendered inside of other partials');
+    var hash = {
+      dudes: [
+        { name: 'Yehuda', url: 'http://yehuda' },
+        { name: 'Alan', url: 'http://alan' }
+      ]
+    };
+    shouldCompileToWithPartials(
+      string,
+      [hash, {}, { dude: dude, url: url }],
+      true,
+      'Dudes: Yehuda <a href="http://yehuda">http://yehuda</a> Alan <a href="http://alan">http://alan</a> ',
+      'Partials are rendered inside of other partials'
+    );
   });
 
   it('rendering undefined partial throws an exception', function() {
-    shouldThrow(function() {
-      var template = CompilerContext.compile('{{> whatever}}');
-      template();
-    }, Handlebars.Exception, 'The partial whatever could not be found');
+    shouldThrow(
+      function() {
+        var template = CompilerContext.compile('{{> whatever}}');
+        template();
+      },
+      Handlebars.Exception,
+      'The partial whatever could not be found'
+    );
   });
 
   it('registering undefined partial throws an exception', function() {
-    shouldThrow(function() {
-      var undef;
-      handlebarsEnv.registerPartial('undefined_test', undef);
-    }, Handlebars.Exception, 'Attempting to register a partial called "undefined_test" as undefined');
+    shouldThrow(
+      function() {
+        var undef;
+        handlebarsEnv.registerPartial('undefined_test', undef);
+      },
+      Handlebars.Exception,
+      'Attempting to register a partial called "undefined_test" as undefined'
+    );
   });
 
   it('rendering template partial in vm mode throws an exception', function() {
-    shouldThrow(function() {
-      var template = CompilerContext.compile('{{> whatever}}');
-      template();
-    }, Handlebars.Exception, 'The partial whatever could not be found');
+    shouldThrow(
+      function() {
+        var template = CompilerContext.compile('{{> whatever}}');
+        template();
+      },
+      Handlebars.Exception,
+      'The partial whatever could not be found'
+    );
   });
 
   it('rendering function partial in vm mode', function() {
@@ -118,30 +227,57 @@ describe('partials', function() {
     function partial(context) {
       return context.name + ' (' + context.url + ') ';
     }
-    var hash = {dudes: [{name: 'Yehuda', url: 'http://yehuda'}, {name: 'Alan', url: 'http://alan'}]};
-    shouldCompileTo(string, [hash, {}, {dude: partial}], 'Dudes: Yehuda (http://yehuda) Alan (http://alan) ',
-                    'Function partials output based in VM.');
+    var hash = {
+      dudes: [
+        { name: 'Yehuda', url: 'http://yehuda' },
+        { name: 'Alan', url: 'http://alan' }
+      ]
+    };
+    shouldCompileTo(
+      string,
+      [hash, {}, { dude: partial }],
+      'Dudes: Yehuda (http://yehuda) Alan (http://alan) ',
+      'Function partials output based in VM.'
+    );
   });
 
   it('GH-14: a partial preceding a selector', function() {
     var string = 'Dudes: {{>dude}} {{anotherDude}}';
     var dude = '{{name}}';
-    var hash = {name: 'Jeepers', anotherDude: 'Creepers'};
-    shouldCompileToWithPartials(string, [hash, {}, {dude: dude}], true, 'Dudes: Jeepers Creepers', 'Regular selectors can follow a partial');
+    var hash = { name: 'Jeepers', anotherDude: 'Creepers' };
+    shouldCompileToWithPartials(
+      string,
+      [hash, {}, { dude: dude }],
+      true,
+      'Dudes: Jeepers Creepers',
+      'Regular selectors can follow a partial'
+    );
   });
 
   it('Partials with slash paths', function() {
     var string = 'Dudes: {{> shared/dude}}';
     var dude = '{{name}}';
-    var hash = {name: 'Jeepers', anotherDude: 'Creepers'};
-    shouldCompileToWithPartials(string, [hash, {}, {'shared/dude': dude}], true, 'Dudes: Jeepers', 'Partials can use literal paths');
+    var hash = { name: 'Jeepers', anotherDude: 'Creepers' };
+    shouldCompileToWithPartials(
+      string,
+      [hash, {}, { 'shared/dude': dude }],
+      true,
+      'Dudes: Jeepers',
+      'Partials can use literal paths'
+    );
   });
 
   it('Partials with slash and point paths', function() {
     var string = 'Dudes: {{> shared/dude.thing}}';
     var dude = '{{name}}';
-    var hash = {name: 'Jeepers', anotherDude: 'Creepers'};
-    shouldCompileToWithPartials(string, [hash, {}, {'shared/dude.thing': dude}], true, 'Dudes: Jeepers', 'Partials can use literal with points in paths');
+    var hash = { name: 'Jeepers', anotherDude: 'Creepers' };
+    shouldCompileToWithPartials(
+      string,
+      [hash, {}, { 'shared/dude.thing': dude }],
+      true,
+      'Dudes: Jeepers',
+      'Partials can use literal with points in paths'
+    );
   });
 
   it('Global Partials', function() {
@@ -149,8 +285,14 @@ describe('partials', function() {
 
     var string = 'Dudes: {{> shared/dude}} {{> globalTest}}';
     var dude = '{{name}}';
-    var hash = {name: 'Jeepers', anotherDude: 'Creepers'};
-    shouldCompileToWithPartials(string, [hash, {}, {'shared/dude': dude}], true, 'Dudes: Jeepers Creepers', 'Partials can use globals or passed');
+    var hash = { name: 'Jeepers', anotherDude: 'Creepers' };
+    shouldCompileToWithPartials(
+      string,
+      [hash, {}, { 'shared/dude': dude }],
+      true,
+      'Dudes: Jeepers Creepers',
+      'Partials can use globals or passed'
+    );
 
     handlebarsEnv.unregisterPartial('globalTest');
     equals(handlebarsEnv.partials.globalTest, undefined);
@@ -163,51 +305,95 @@ describe('partials', function() {
     });
 
     var string = 'Dudes: {{> shared/dude}} {{> globalTest}}';
-    var hash = {name: 'Jeepers', anotherDude: 'Creepers'};
-    shouldCompileToWithPartials(string, [hash], true, 'Dudes: Jeepers Creepers', 'Partials can use globals or passed');
+    var hash = { name: 'Jeepers', anotherDude: 'Creepers' };
+    shouldCompileToWithPartials(
+      string,
+      [hash],
+      true,
+      'Dudes: Jeepers Creepers',
+      'Partials can use globals or passed'
+    );
   });
 
   it('Partials with integer path', function() {
     var string = 'Dudes: {{> 404}}';
     var dude = '{{name}}';
-    var hash = {name: 'Jeepers', anotherDude: 'Creepers'};
-    shouldCompileToWithPartials(string, [hash, {}, {404: dude}], true, 'Dudes: Jeepers', 'Partials can use literal paths');
+    var hash = { name: 'Jeepers', anotherDude: 'Creepers' };
+    shouldCompileToWithPartials(
+      string,
+      [hash, {}, { 404: dude }],
+      true,
+      'Dudes: Jeepers',
+      'Partials can use literal paths'
+    );
   });
 
   it('Partials with complex path', function() {
     var string = 'Dudes: {{> 404/asdf?.bar}}';
     var dude = '{{name}}';
-    var hash = {name: 'Jeepers', anotherDude: 'Creepers'};
-    shouldCompileToWithPartials(string, [hash, {}, {'404/asdf?.bar': dude}], true, 'Dudes: Jeepers', 'Partials can use literal paths');
+    var hash = { name: 'Jeepers', anotherDude: 'Creepers' };
+    shouldCompileToWithPartials(
+      string,
+      [hash, {}, { '404/asdf?.bar': dude }],
+      true,
+      'Dudes: Jeepers',
+      'Partials can use literal paths'
+    );
   });
 
   it('Partials with escaped', function() {
     var string = 'Dudes: {{> [+404/asdf?.bar]}}';
     var dude = '{{name}}';
-    var hash = {name: 'Jeepers', anotherDude: 'Creepers'};
-    shouldCompileToWithPartials(string, [hash, {}, {'+404/asdf?.bar': dude}], true, 'Dudes: Jeepers', 'Partials can use literal paths');
+    var hash = { name: 'Jeepers', anotherDude: 'Creepers' };
+    shouldCompileToWithPartials(
+      string,
+      [hash, {}, { '+404/asdf?.bar': dude }],
+      true,
+      'Dudes: Jeepers',
+      'Partials can use literal paths'
+    );
   });
 
   it('Partials with string', function() {
-    var string = 'Dudes: {{> \'+404/asdf?.bar\'}}';
+    var string = "Dudes: {{> '+404/asdf?.bar'}}";
     var dude = '{{name}}';
-    var hash = {name: 'Jeepers', anotherDude: 'Creepers'};
-    shouldCompileToWithPartials(string, [hash, {}, {'+404/asdf?.bar': dude}], true, 'Dudes: Jeepers', 'Partials can use literal paths');
+    var hash = { name: 'Jeepers', anotherDude: 'Creepers' };
+    shouldCompileToWithPartials(
+      string,
+      [hash, {}, { '+404/asdf?.bar': dude }],
+      true,
+      'Dudes: Jeepers',
+      'Partials can use literal paths'
+    );
   });
 
   it('should handle empty partial', function() {
     var string = 'Dudes: {{#dudes}}{{> dude}}{{/dudes}}';
     var partial = '';
-    var hash = {dudes: [{name: 'Yehuda', url: 'http://yehuda'}, {name: 'Alan', url: 'http://alan'}]};
-    shouldCompileToWithPartials(string, [hash, {}, {dude: partial}], true, 'Dudes: ');
+    var hash = {
+      dudes: [
+        { name: 'Yehuda', url: 'http://yehuda' },
+        { name: 'Alan', url: 'http://alan' }
+      ]
+    };
+    shouldCompileToWithPartials(
+      string,
+      [hash, {}, { dude: partial }],
+      true,
+      'Dudes: '
+    );
   });
 
   it('throw on missing partial', function() {
     var compile = handlebarsEnv.compile;
     handlebarsEnv.compile = undefined;
-    shouldThrow(function() {
-      shouldCompileTo('{{> dude}}', [{}, {}, {dude: 'fail'}], '');
-    }, Error, /The partial dude could not be compiled/);
+    shouldThrow(
+      function() {
+        shouldCompileTo('{{> dude}}', [{}, {}, { dude: 'fail' }], '');
+      },
+      Error,
+      /The partial dude could not be compiled/
+    );
     handlebarsEnv.compile = compile;
   });
 
@@ -217,224 +403,309 @@ describe('partials', function() {
         '{{#> dude}}success{{/dude}}',
         [{}, {}, {}],
         true,
-        'success');
+        'success'
+      );
     });
     it('should execute default block with proper context', function() {
       shouldCompileToWithPartials(
         '{{#> dude context}}{{value}}{{/dude}}',
-        [{context: {value: 'success'}}, {}, {}],
+        [{ context: { value: 'success' } }, {}, {}],
         true,
-        'success');
+        'success'
+      );
     });
     it('should propagate block parameters to default block', function() {
       shouldCompileToWithPartials(
         '{{#with context as |me|}}{{#> dude}}{{me.value}}{{/dude}}{{/with}}',
-        [{context: {value: 'success'}}, {}, {}],
+        [{ context: { value: 'success' } }, {}, {}],
         true,
-        'success');
+        'success'
+      );
     });
 
     it('should not use partial block if partial exists', function() {
       shouldCompileToWithPartials(
         '{{#> dude}}fail{{/dude}}',
-        [{}, {}, {dude: 'success'}],
+        [{}, {}, { dude: 'success' }],
         true,
-        'success');
+        'success'
+      );
     });
 
     it('should render block from partial', function() {
       shouldCompileToWithPartials(
         '{{#> dude}}success{{/dude}}',
-        [{}, {}, {dude: '{{> @partial-block }}'}],
+        [{}, {}, { dude: '{{> @partial-block }}' }],
         true,
-        'success');
+        'success'
+      );
     });
     it('should be able to render the partial-block twice', function() {
       shouldCompileToWithPartials(
-          '{{#> dude}}success{{/dude}}',
-          [{}, {}, {dude: '{{> @partial-block }} {{> @partial-block }}'}],
-          true,
-          'success success');
+        '{{#> dude}}success{{/dude}}',
+        [{}, {}, { dude: '{{> @partial-block }} {{> @partial-block }}' }],
+        true,
+        'success success'
+      );
     });
     it('should render block from partial with context', function() {
       shouldCompileToWithPartials(
         '{{#> dude}}{{value}}{{/dude}}',
-        [{context: {value: 'success'}}, {}, {dude: '{{#with context}}{{> @partial-block }}{{/with}}'}],
+        [
+          { context: { value: 'success' } },
+          {},
+          { dude: '{{#with context}}{{> @partial-block }}{{/with}}' }
+        ],
         true,
-        'success');
+        'success'
+      );
     });
 
     it('should be able to access the @data frame from a partial-block', function() {
       shouldCompileToWithPartials(
         '{{#> dude}}in-block: {{@root/value}}{{/dude}}',
-        [{value: 'success'}, {}, {dude: '<code>before-block: {{@root/value}} {{>   @partial-block }}</code>'}],
+        [
+          { value: 'success' },
+          {},
+          {
+            dude:
+              '<code>before-block: {{@root/value}} {{>   @partial-block }}</code>'
+          }
+        ],
         true,
-        '<code>before-block: success in-block: success</code>');
+        '<code>before-block: success in-block: success</code>'
+      );
     });
 
     it('should allow the #each-helper to be used along with partial-blocks', function() {
       shouldCompileToWithPartials(
         '<template>{{#> list value}}value = {{.}}{{/list}}</template>',
         [
-          {value: ['a', 'b', 'c']},
+          { value: ['a', 'b', 'c'] },
           {},
           {
-            list: '<list>{{#each .}}<item>{{> @partial-block}}</item>{{/each}}</list>'
+            list:
+              '<list>{{#each .}}<item>{{> @partial-block}}</item>{{/each}}</list>'
           }
         ],
         true,
-        '<template><list><item>value = a</item><item>value = b</item><item>value = c</item></list></template>');
+        '<template><list><item>value = a</item><item>value = b</item><item>value = c</item></list></template>'
+      );
     });
     it('should render block from partial with context (twice)', function() {
       shouldCompileToWithPartials(
-          '{{#> dude}}{{value}}{{/dude}}',
-          [
-            {context: {value: 'success'}},
-            {},
-            {
-              dude: '{{#with context}}{{> @partial-block }} {{> @partial-block }}{{/with}}'
-            }
-          ],
-          true,
-          'success success');
+        '{{#> dude}}{{value}}{{/dude}}',
+        [
+          { context: { value: 'success' } },
+          {},
+          {
+            dude:
+              '{{#with context}}{{> @partial-block }} {{> @partial-block }}{{/with}}'
+          }
+        ],
+        true,
+        'success success'
+      );
     });
     it('should render block from partial with context', function() {
       shouldCompileToWithPartials(
         '{{#> dude}}{{../context/value}}{{/dude}}',
-        [{context: {value: 'success'}}, {}, {dude: '{{#with context}}{{> @partial-block }}{{/with}}'}],
+        [
+          { context: { value: 'success' } },
+          {},
+          { dude: '{{#with context}}{{> @partial-block }}{{/with}}' }
+        ],
         true,
-        'success');
+        'success'
+      );
     });
     it('should render block from partial with block params', function() {
       shouldCompileToWithPartials(
         '{{#with context as |me|}}{{#> dude}}{{me.value}}{{/dude}}{{/with}}',
-        [{context: {value: 'success'}}, {}, {dude: '{{> @partial-block }}'}],
+        [
+          { context: { value: 'success' } },
+          {},
+          { dude: '{{> @partial-block }}' }
+        ],
         true,
-        'success');
+        'success'
+      );
     });
     it('should render nested partial blocks', function() {
       shouldCompileToWithPartials(
         '<template>{{#> outer}}{{value}}{{/outer}}</template>',
         [
-          {value: 'success'},
+          { value: 'success' },
           {},
           {
-            outer: '<outer>{{#> nested}}<outer-block>{{> @partial-block}}</outer-block>{{/nested}}</outer>',
+            outer:
+              '<outer>{{#> nested}}<outer-block>{{> @partial-block}}</outer-block>{{/nested}}</outer>',
             nested: '<nested>{{> @partial-block}}</nested>'
           }
         ],
         true,
-        '<template><outer><nested><outer-block>success</outer-block></nested></outer></template>');
+        '<template><outer><nested><outer-block>success</outer-block></nested></outer></template>'
+      );
     });
     it('should render nested partial blocks at different nesting levels', function() {
       shouldCompileToWithPartials(
         '<template>{{#> outer}}{{value}}{{/outer}}</template>',
         [
-          {value: 'success'},
+          { value: 'success' },
           {},
           {
-            outer: '<outer>{{#> nested}}<outer-block>{{> @partial-block}}</outer-block>{{/nested}}{{> @partial-block}}</outer>',
+            outer:
+              '<outer>{{#> nested}}<outer-block>{{> @partial-block}}</outer-block>{{/nested}}{{> @partial-block}}</outer>',
             nested: '<nested>{{> @partial-block}}</nested>'
           }
         ],
         true,
-        '<template><outer><nested><outer-block>success</outer-block></nested>success</outer></template>');
+        '<template><outer><nested><outer-block>success</outer-block></nested>success</outer></template>'
+      );
     });
     it('should render nested partial blocks at different nesting levels (twice)', function() {
       shouldCompileToWithPartials(
         '<template>{{#> outer}}{{value}}{{/outer}}</template>',
         [
-          {value: 'success'},
+          { value: 'success' },
           {},
           {
-            outer: '<outer>{{#> nested}}<outer-block>{{> @partial-block}} {{> @partial-block}}</outer-block>{{/nested}}{{> @partial-block}}+{{> @partial-block}}</outer>',
+            outer:
+              '<outer>{{#> nested}}<outer-block>{{> @partial-block}} {{> @partial-block}}</outer-block>{{/nested}}{{> @partial-block}}+{{> @partial-block}}</outer>',
             nested: '<nested>{{> @partial-block}}</nested>'
           }
         ],
         true,
-        '<template><outer><nested><outer-block>success success</outer-block></nested>success+success</outer></template>');
+        '<template><outer><nested><outer-block>success success</outer-block></nested>success+success</outer></template>'
+      );
     });
     it('should render nested partial blocks (twice at each level)', function() {
       shouldCompileToWithPartials(
         '<template>{{#> outer}}{{value}}{{/outer}}</template>',
         [
-          {value: 'success'},
+          { value: 'success' },
           {},
           {
-            outer: '<outer>{{#> nested}}<outer-block>{{> @partial-block}} {{> @partial-block}}</outer-block>{{/nested}}</outer>',
+            outer:
+              '<outer>{{#> nested}}<outer-block>{{> @partial-block}} {{> @partial-block}}</outer-block>{{/nested}}</outer>',
             nested: '<nested>{{> @partial-block}}{{> @partial-block}}</nested>'
           }
         ],
         true,
         '<template><outer>' +
-        '<nested><outer-block>success success</outer-block><outer-block>success success</outer-block></nested>' +
-        '</outer></template>');
+          '<nested><outer-block>success success</outer-block><outer-block>success success</outer-block></nested>' +
+          '</outer></template>'
+      );
     });
   });
 
   describe('inline partials', function() {
     it('should define inline partials for template', function() {
-      shouldCompileTo('{{#*inline "myPartial"}}success{{/inline}}{{> myPartial}}', {}, 'success');
+      shouldCompileTo(
+        '{{#*inline "myPartial"}}success{{/inline}}{{> myPartial}}',
+        {},
+        'success'
+      );
     });
     it('should overwrite multiple partials in the same template', function() {
-      shouldCompileTo('{{#*inline "myPartial"}}fail{{/inline}}{{#*inline "myPartial"}}success{{/inline}}{{> myPartial}}', {}, 'success');
+      shouldCompileTo(
+        '{{#*inline "myPartial"}}fail{{/inline}}{{#*inline "myPartial"}}success{{/inline}}{{> myPartial}}',
+        {},
+        'success'
+      );
     });
     it('should define inline partials for block', function() {
-      shouldCompileTo('{{#with .}}{{#*inline "myPartial"}}success{{/inline}}{{> myPartial}}{{/with}}', {}, 'success');
-      shouldThrow(function() {
-        shouldCompileTo('{{#with .}}{{#*inline "myPartial"}}success{{/inline}}{{/with}}{{> myPartial}}', {}, 'success');
-      }, Error, /myPartial could not/);
+      shouldCompileTo(
+        '{{#with .}}{{#*inline "myPartial"}}success{{/inline}}{{> myPartial}}{{/with}}',
+        {},
+        'success'
+      );
+      shouldThrow(
+        function() {
+          shouldCompileTo(
+            '{{#with .}}{{#*inline "myPartial"}}success{{/inline}}{{/with}}{{> myPartial}}',
+            {},
+            'success'
+          );
+        },
+        Error,
+        /myPartial could not/
+      );
     });
     it('should override global partials', function() {
-      shouldCompileTo('{{#*inline "myPartial"}}success{{/inline}}{{> myPartial}}', {hash: {}, partials: {myPartial: function() { return 'fail'; }}}, 'success');
+      shouldCompileTo(
+        '{{#*inline "myPartial"}}success{{/inline}}{{> myPartial}}',
+        {
+          hash: {},
+          partials: {
+            myPartial: function() {
+              return 'fail';
+            }
+          }
+        },
+        'success'
+      );
     });
     it('should override template partials', function() {
-      shouldCompileTo('{{#*inline "myPartial"}}fail{{/inline}}{{#with .}}{{#*inline "myPartial"}}success{{/inline}}{{> myPartial}}{{/with}}', {}, 'success');
+      shouldCompileTo(
+        '{{#*inline "myPartial"}}fail{{/inline}}{{#with .}}{{#*inline "myPartial"}}success{{/inline}}{{> myPartial}}{{/with}}',
+        {},
+        'success'
+      );
     });
     it('should override partials down the entire stack', function() {
-      shouldCompileTo('{{#with .}}{{#*inline "myPartial"}}success{{/inline}}{{#with .}}{{#with .}}{{> myPartial}}{{/with}}{{/with}}{{/with}}', {}, 'success');
+      shouldCompileTo(
+        '{{#with .}}{{#*inline "myPartial"}}success{{/inline}}{{#with .}}{{#with .}}{{> myPartial}}{{/with}}{{/with}}{{/with}}',
+        {},
+        'success'
+      );
     });
 
     it('should define inline partials for partial call', function() {
       shouldCompileToWithPartials(
         '{{#*inline "myPartial"}}success{{/inline}}{{> dude}}',
-        [{}, {}, {dude: '{{> myPartial }}'}],
+        [{}, {}, { dude: '{{> myPartial }}' }],
         true,
-        'success');
+        'success'
+      );
     });
     it('should define inline partials in partial block call', function() {
       shouldCompileToWithPartials(
         '{{#> dude}}{{#*inline "myPartial"}}success{{/inline}}{{/dude}}',
-        [{}, {}, {dude: '{{> myPartial }}'}],
+        [{}, {}, { dude: '{{> myPartial }}' }],
         true,
-        'success');
+        'success'
+      );
     });
     it('should render nested inline partials', function() {
       shouldCompileToWithPartials(
         '{{#*inline "outer"}}{{#>inner}}<outer-block>{{>@partial-block}}</outer-block>{{/inner}}{{/inline}}' +
-        '{{#*inline "inner"}}<inner>{{>@partial-block}}</inner>{{/inline}}' +
-        '{{#>outer}}{{value}}{{/outer}}',
-        [{value: 'success'}, {}, {}],
+          '{{#*inline "inner"}}<inner>{{>@partial-block}}</inner>{{/inline}}' +
+          '{{#>outer}}{{value}}{{/outer}}',
+        [{ value: 'success' }, {}, {}],
         true,
-        '<inner><outer-block>success</outer-block></inner>');
+        '<inner><outer-block>success</outer-block></inner>'
+      );
     });
     it('should render nested inline partials with partial-blocks on different nesting levels', function() {
       shouldCompileToWithPartials(
         '{{#*inline "outer"}}{{#>inner}}<outer-block>{{>@partial-block}}</outer-block>{{/inner}}{{>@partial-block}}{{/inline}}' +
-        '{{#*inline "inner"}}<inner>{{>@partial-block}}</inner>{{/inline}}' +
-        '{{#>outer}}{{value}}{{/outer}}',
-        [{value: 'success'}, {}, {}],
+          '{{#*inline "inner"}}<inner>{{>@partial-block}}</inner>{{/inline}}' +
+          '{{#>outer}}{{value}}{{/outer}}',
+        [{ value: 'success' }, {}, {}],
         true,
-        '<inner><outer-block>success</outer-block></inner>success');
+        '<inner><outer-block>success</outer-block></inner>success'
+      );
     });
     it('should render nested inline partials (twice at each level)', function() {
       shouldCompileToWithPartials(
         '{{#*inline "outer"}}{{#>inner}}<outer-block>{{>@partial-block}} {{>@partial-block}}</outer-block>{{/inner}}{{/inline}}' +
-        '{{#*inline "inner"}}<inner>{{>@partial-block}}{{>@partial-block}}</inner>{{/inline}}' +
-        '{{#>outer}}{{value}}{{/outer}}',
-        [{value: 'success'}, {}, {}],
+          '{{#*inline "inner"}}<inner>{{>@partial-block}}{{>@partial-block}}</inner>{{/inline}}' +
+          '{{#>outer}}{{value}}{{/outer}}',
+        [{ value: 'success' }, {}, {}],
         true,
-        '<inner><outer-block>success success</outer-block><outer-block>success success</outer-block></inner>');
+        '<inner><outer-block>success success</outer-block><outer-block>success success</outer-block></inner>'
+      );
     });
   });
 
@@ -442,8 +713,8 @@ describe('partials', function() {
     if (Handlebars.compile) {
       var env = Handlebars.create();
       env.registerPartial('partial', '{{foo}}');
-      var template = env.compile('{{foo}} {{> partial}}', {noEscape: true});
-      equal(template({foo: '<'}), '< <');
+      var template = env.compile('{{foo}} {{> partial}}', { noEscape: true });
+      equal(template({ foo: '<' }), '< <');
     }
   });
 
@@ -451,25 +722,52 @@ describe('partials', function() {
     it('indented partials', function() {
       var string = 'Dudes:\n{{#dudes}}\n  {{>dude}}\n{{/dudes}}';
       var dude = '{{name}}\n';
-      var hash = {dudes: [{name: 'Yehuda', url: 'http://yehuda'}, {name: 'Alan', url: 'http://alan'}]};
-      shouldCompileToWithPartials(string, [hash, {}, {dude: dude}], true,
-            'Dudes:\n  Yehuda\n  Alan\n');
+      var hash = {
+        dudes: [
+          { name: 'Yehuda', url: 'http://yehuda' },
+          { name: 'Alan', url: 'http://alan' }
+        ]
+      };
+      shouldCompileToWithPartials(
+        string,
+        [hash, {}, { dude: dude }],
+        true,
+        'Dudes:\n  Yehuda\n  Alan\n'
+      );
     });
     it('nested indented partials', function() {
       var string = 'Dudes:\n{{#dudes}}\n  {{>dude}}\n{{/dudes}}';
       var dude = '{{name}}\n {{> url}}';
       var url = '{{url}}!\n';
-      var hash = {dudes: [{name: 'Yehuda', url: 'http://yehuda'}, {name: 'Alan', url: 'http://alan'}]};
-      shouldCompileToWithPartials(string, [hash, {}, {dude: dude, url: url}], true,
-            'Dudes:\n  Yehuda\n   http://yehuda!\n  Alan\n   http://alan!\n');
+      var hash = {
+        dudes: [
+          { name: 'Yehuda', url: 'http://yehuda' },
+          { name: 'Alan', url: 'http://alan' }
+        ]
+      };
+      shouldCompileToWithPartials(
+        string,
+        [hash, {}, { dude: dude, url: url }],
+        true,
+        'Dudes:\n  Yehuda\n   http://yehuda!\n  Alan\n   http://alan!\n'
+      );
     });
     it('prevent nested indented partials', function() {
       var string = 'Dudes:\n{{#dudes}}\n  {{>dude}}\n{{/dudes}}';
       var dude = '{{name}}\n {{> url}}';
       var url = '{{url}}!\n';
-      var hash = {dudes: [{name: 'Yehuda', url: 'http://yehuda'}, {name: 'Alan', url: 'http://alan'}]};
-      shouldCompileToWithPartials(string, [hash, {}, {dude: dude, url: url}, {preventIndent: true}], true,
-            'Dudes:\n  Yehuda\n http://yehuda!\n  Alan\n http://alan!\n');
+      var hash = {
+        dudes: [
+          { name: 'Yehuda', url: 'http://yehuda' },
+          { name: 'Alan', url: 'http://alan' }
+        ]
+      };
+      shouldCompileToWithPartials(
+        string,
+        [hash, {}, { dude: dude, url: url }, { preventIndent: true }],
+        true,
+        'Dudes:\n  Yehuda\n http://yehuda!\n  Alan\n http://alan!\n'
+      );
     });
   });
 
@@ -477,26 +775,70 @@ describe('partials', function() {
     it('partials can access parents', function() {
       var string = 'Dudes: {{#dudes}}{{> dude}}{{/dudes}}';
       var partial = '{{name}} ({{url}}) {{root}} ';
-      var hash = {root: 'yes', dudes: [{name: 'Yehuda', url: 'http://yehuda'}, {name: 'Alan', url: 'http://alan'}]};
-      shouldCompileToWithPartials(string, [hash, {}, {dude: partial}, true], true, 'Dudes: Yehuda (http://yehuda) yes Alan (http://alan) yes ');
+      var hash = {
+        root: 'yes',
+        dudes: [
+          { name: 'Yehuda', url: 'http://yehuda' },
+          { name: 'Alan', url: 'http://alan' }
+        ]
+      };
+      shouldCompileToWithPartials(
+        string,
+        [hash, {}, { dude: partial }, true],
+        true,
+        'Dudes: Yehuda (http://yehuda) yes Alan (http://alan) yes '
+      );
     });
     it('partials can access parents with custom context', function() {
       var string = 'Dudes: {{#dudes}}{{> dude "test"}}{{/dudes}}';
       var partial = '{{name}} ({{url}}) {{root}} ';
-      var hash = {root: 'yes', dudes: [{name: 'Yehuda', url: 'http://yehuda'}, {name: 'Alan', url: 'http://alan'}]};
-      shouldCompileToWithPartials(string, [hash, {}, {dude: partial}, true], true, 'Dudes: Yehuda (http://yehuda) yes Alan (http://alan) yes ');
+      var hash = {
+        root: 'yes',
+        dudes: [
+          { name: 'Yehuda', url: 'http://yehuda' },
+          { name: 'Alan', url: 'http://alan' }
+        ]
+      };
+      shouldCompileToWithPartials(
+        string,
+        [hash, {}, { dude: partial }, true],
+        true,
+        'Dudes: Yehuda (http://yehuda) yes Alan (http://alan) yes '
+      );
     });
     it('partials can access parents without data', function() {
       var string = 'Dudes: {{#dudes}}{{> dude}}{{/dudes}}';
       var partial = '{{name}} ({{url}}) {{root}} ';
-      var hash = {root: 'yes', dudes: [{name: 'Yehuda', url: 'http://yehuda'}, {name: 'Alan', url: 'http://alan'}]};
-      shouldCompileToWithPartials(string, [hash, {}, {dude: partial}, true, false], true, 'Dudes: Yehuda (http://yehuda) yes Alan (http://alan) yes ');
+      var hash = {
+        root: 'yes',
+        dudes: [
+          { name: 'Yehuda', url: 'http://yehuda' },
+          { name: 'Alan', url: 'http://alan' }
+        ]
+      };
+      shouldCompileToWithPartials(
+        string,
+        [hash, {}, { dude: partial }, true, false],
+        true,
+        'Dudes: Yehuda (http://yehuda) yes Alan (http://alan) yes '
+      );
     });
     it('partials inherit compat', function() {
       var string = 'Dudes: {{> dude}}';
       var partial = '{{#dudes}}{{name}} ({{url}}) {{root}} {{/dudes}}';
-      var hash = {root: 'yes', dudes: [{name: 'Yehuda', url: 'http://yehuda'}, {name: 'Alan', url: 'http://alan'}]};
-      shouldCompileToWithPartials(string, [hash, {}, {dude: partial}, true], true, 'Dudes: Yehuda (http://yehuda) yes Alan (http://alan) yes ');
+      var hash = {
+        root: 'yes',
+        dudes: [
+          { name: 'Yehuda', url: 'http://yehuda' },
+          { name: 'Alan', url: 'http://alan' }
+        ]
+      };
+      shouldCompileToWithPartials(
+        string,
+        [hash, {}, { dude: partial }, true],
+        true,
+        'Dudes: Yehuda (http://yehuda) yes Alan (http://alan) yes '
+      );
     });
   });
 });
diff --git a/spec/precompiler.js b/spec/precompiler.js
index 9f2a6442b..2261023cc 100644
--- a/spec/precompiler.js
+++ b/spec/precompiler.js
@@ -6,27 +6,24 @@ describe('precompiler', function() {
   }
 
   var Handlebars = require('../lib'),
-      Precompiler = require('../dist/cjs/precompiler'),
-      fs = require('fs'),
-      uglify = require('uglify-js');
+    Precompiler = require('../dist/cjs/precompiler'),
+    fs = require('fs'),
+    uglify = require('uglify-js');
 
   var log,
-      logFunction,
-      errorLog,
-      errorLogFunction,
-
-      precompile,
-      minify,
-
-      emptyTemplate = {
-        path: __dirname + '/artifacts/empty.handlebars',
-        name: 'empty',
-        source: ''
-      },
-
-      file,
-      content,
-      writeFileSync;
+    logFunction,
+    errorLog,
+    errorLogFunction,
+    precompile,
+    minify,
+    emptyTemplate = {
+      path: __dirname + '/artifacts/empty.handlebars',
+      name: 'empty',
+      source: ''
+    },
+    file,
+    content,
+    writeFileSync;
 
   /**
    * Mock the Module.prototype.require-function such that an error is thrown, when "uglify-js" is loaded.
@@ -87,102 +84,166 @@ describe('precompiler', function() {
   });
 
   it('should output version', function() {
-    Precompiler.cli({templates: [], version: true});
+    Precompiler.cli({ templates: [], version: true });
     equals(log, Handlebars.VERSION);
   });
   it('should throw if lacking templates', function() {
-    shouldThrow(function() {
-      Precompiler.cli({templates: []});
-    }, Handlebars.Exception, 'Must define at least one template or directory.');
+    shouldThrow(
+      function() {
+        Precompiler.cli({ templates: [] });
+      },
+      Handlebars.Exception,
+      'Must define at least one template or directory.'
+    );
   });
   it('should handle empty/filtered directories', function() {
-    Precompiler.cli({hasDirectory: true, templates: []});
+    Precompiler.cli({ hasDirectory: true, templates: [] });
     // Success is not throwing
   });
   it('should throw when combining simple and minimized', function() {
-    shouldThrow(function() {
-      Precompiler.cli({templates: [__dirname], simple: true, min: true});
-    }, Handlebars.Exception, 'Unable to minimize simple output');
+    shouldThrow(
+      function() {
+        Precompiler.cli({ templates: [__dirname], simple: true, min: true });
+      },
+      Handlebars.Exception,
+      'Unable to minimize simple output'
+    );
   });
   it('should throw when combining simple and multiple templates', function() {
-    shouldThrow(function() {
-      Precompiler.cli({templates: [__dirname + '/artifacts/empty.handlebars', __dirname + '/artifacts/empty.handlebars'], simple: true});
-    }, Handlebars.Exception, 'Unable to output multiple templates in simple mode');
+    shouldThrow(
+      function() {
+        Precompiler.cli({
+          templates: [
+            __dirname + '/artifacts/empty.handlebars',
+            __dirname + '/artifacts/empty.handlebars'
+          ],
+          simple: true
+        });
+      },
+      Handlebars.Exception,
+      'Unable to output multiple templates in simple mode'
+    );
   });
   it('should throw when missing name', function() {
-    shouldThrow(function() {
-      Precompiler.cli({templates: [{source: ''}], amd: true});
-    }, Handlebars.Exception, 'Name missing for template');
+    shouldThrow(
+      function() {
+        Precompiler.cli({ templates: [{ source: '' }], amd: true });
+      },
+      Handlebars.Exception,
+      'Name missing for template'
+    );
   });
   it('should throw when combining simple and directories', function() {
-    shouldThrow(function() {
-      Precompiler.cli({hasDirectory: true, templates: [1], simple: true});
-    }, Handlebars.Exception, 'Unable to output multiple templates in simple mode');
+    shouldThrow(
+      function() {
+        Precompiler.cli({ hasDirectory: true, templates: [1], simple: true });
+      },
+      Handlebars.Exception,
+      'Unable to output multiple templates in simple mode'
+    );
   });
 
   it('should output simple templates', function() {
-    Handlebars.precompile = function() { return 'simple'; };
-    Precompiler.cli({templates: [emptyTemplate], simple: true});
+    Handlebars.precompile = function() {
+      return 'simple';
+    };
+    Precompiler.cli({ templates: [emptyTemplate], simple: true });
     equal(log, 'simple\n');
   });
   it('should default to simple templates', function() {
-    Handlebars.precompile = function() { return 'simple'; };
-    Precompiler.cli({templates: [{source: ''}]});
+    Handlebars.precompile = function() {
+      return 'simple';
+    };
+    Precompiler.cli({ templates: [{ source: '' }] });
     equal(log, 'simple\n');
   });
   it('should output amd templates', function() {
-    Handlebars.precompile = function() { return 'amd'; };
-    Precompiler.cli({templates: [emptyTemplate], amd: true});
+    Handlebars.precompile = function() {
+      return 'amd';
+    };
+    Precompiler.cli({ templates: [emptyTemplate], amd: true });
     equal(/template\(amd\)/.test(log), true);
   });
   it('should output multiple amd', function() {
-    Handlebars.precompile = function() { return 'amd'; };
-    Precompiler.cli({templates: [emptyTemplate, emptyTemplate], amd: true, namespace: 'foo'});
+    Handlebars.precompile = function() {
+      return 'amd';
+    };
+    Precompiler.cli({
+      templates: [emptyTemplate, emptyTemplate],
+      amd: true,
+      namespace: 'foo'
+    });
     equal(/templates = foo = foo \|\|/.test(log), true);
     equal(/return templates/.test(log), true);
     equal(/template\(amd\)/.test(log), true);
   });
   it('should output amd partials', function() {
-    Handlebars.precompile = function() { return 'amd'; };
-    Precompiler.cli({templates: [emptyTemplate], amd: true, partial: true});
+    Handlebars.precompile = function() {
+      return 'amd';
+    };
+    Precompiler.cli({ templates: [emptyTemplate], amd: true, partial: true });
     equal(/return Handlebars\.partials\['empty'\]/.test(log), true);
     equal(/template\(amd\)/.test(log), true);
   });
   it('should output multiple amd partials', function() {
-    Handlebars.precompile = function() { return 'amd'; };
-    Precompiler.cli({templates: [emptyTemplate, emptyTemplate], amd: true, partial: true});
+    Handlebars.precompile = function() {
+      return 'amd';
+    };
+    Precompiler.cli({
+      templates: [emptyTemplate, emptyTemplate],
+      amd: true,
+      partial: true
+    });
     equal(/return Handlebars\.partials\[/.test(log), false);
     equal(/template\(amd\)/.test(log), true);
   });
   it('should output commonjs templates', function() {
-    Handlebars.precompile = function() { return 'commonjs'; };
-    Precompiler.cli({templates: [emptyTemplate], commonjs: true});
+    Handlebars.precompile = function() {
+      return 'commonjs';
+    };
+    Precompiler.cli({ templates: [emptyTemplate], commonjs: true });
     equal(/template\(commonjs\)/.test(log), true);
   });
 
   it('should set data flag', function() {
-    Handlebars.precompile = function(data, options) { equal(options.data, true); return 'simple'; };
-    Precompiler.cli({templates: [emptyTemplate], simple: true, data: true});
+    Handlebars.precompile = function(data, options) {
+      equal(options.data, true);
+      return 'simple';
+    };
+    Precompiler.cli({ templates: [emptyTemplate], simple: true, data: true });
     equal(log, 'simple\n');
   });
 
   it('should set known helpers', function() {
-    Handlebars.precompile = function(data, options) { equal(options.knownHelpers.foo, true); return 'simple'; };
-    Precompiler.cli({templates: [emptyTemplate], simple: true, known: 'foo'});
+    Handlebars.precompile = function(data, options) {
+      equal(options.knownHelpers.foo, true);
+      return 'simple';
+    };
+    Precompiler.cli({ templates: [emptyTemplate], simple: true, known: 'foo' });
     equal(log, 'simple\n');
   });
   it('should output to file system', function() {
-    Handlebars.precompile = function() { return 'simple'; };
-    Precompiler.cli({templates: [emptyTemplate], simple: true, output: 'file!'});
+    Handlebars.precompile = function() {
+      return 'simple';
+    };
+    Precompiler.cli({
+      templates: [emptyTemplate],
+      simple: true,
+      output: 'file!'
+    });
     equal(file, 'file!');
     equal(content, 'simple\n');
     equal(log, '');
   });
 
   it('should output minimized templates', function() {
-    Handlebars.precompile = function() { return 'amd'; };
-    uglify.minify = function() { return {code: 'min'}; };
-    Precompiler.cli({templates: [emptyTemplate], min: true});
+    Handlebars.precompile = function() {
+      return 'amd';
+    };
+    uglify.minify = function() {
+      return { code: 'min' };
+    };
+    Precompiler.cli({ templates: [emptyTemplate], min: true });
     equal(log, 'min');
   });
 
@@ -191,8 +252,10 @@ describe('precompiler', function() {
     error.code = 'MODULE_NOT_FOUND';
     mockRequireUglify(error, function() {
       var Precompiler = require('../dist/cjs/precompiler');
-      Handlebars.precompile = function() { return 'amd'; };
-      Precompiler.cli({templates: [emptyTemplate], min: true});
+      Handlebars.precompile = function() {
+        return 'amd';
+      };
+      Precompiler.cli({ templates: [emptyTemplate], min: true });
       equal(/template\(amd\)/.test(log), true);
       equal(/\n/.test(log), true);
       equal(/Code minimization is disabled/.test(errorLog), true);
@@ -201,23 +264,33 @@ describe('precompiler', function() {
 
   it('should fail on errors (other than missing module) while loading uglify-js', function() {
     mockRequireUglify(new Error('Mock Error'), function() {
-      shouldThrow(function() {
-        var Precompiler = require('../dist/cjs/precompiler');
-        Handlebars.precompile = function() { return 'amd'; };
-        Precompiler.cli({templates: [emptyTemplate], min: true});
-      }, Error, 'Mock Error');
+      shouldThrow(
+        function() {
+          var Precompiler = require('../dist/cjs/precompiler');
+          Handlebars.precompile = function() {
+            return 'amd';
+          };
+          Precompiler.cli({ templates: [emptyTemplate], min: true });
+        },
+        Error,
+        'Mock Error'
+      );
     });
   });
 
   it('should output map', function() {
-    Precompiler.cli({templates: [emptyTemplate], map: 'foo.js.map'});
+    Precompiler.cli({ templates: [emptyTemplate], map: 'foo.js.map' });
 
     equal(file, 'foo.js.map');
     equal(log.match(/sourceMappingURL=/g).length, 1);
   });
 
   it('should output map', function() {
-    Precompiler.cli({templates: [emptyTemplate], min: true, map: 'foo.js.map'});
+    Precompiler.cli({
+      templates: [emptyTemplate],
+      min: true,
+      map: 'foo.js.map'
+    });
 
     equal(file, 'foo.js.map');
     equal(log.match(/sourceMappingURL=/g).length, 1);
@@ -225,35 +298,48 @@ describe('precompiler', function() {
 
   describe('#loadTemplates', function() {
     it('should throw on missing template', function(done) {
-      Precompiler.loadTemplates({files: ['foo']}, function(err) {
+      Precompiler.loadTemplates({ files: ['foo'] }, function(err) {
         equal(err.message, 'Unable to open template file "foo"');
         done();
       });
     });
     it('should enumerate directories by extension', function(done) {
-      Precompiler.loadTemplates({files: [__dirname + '/artifacts'], extension: 'hbs'}, function(err, opts) {
-        equal(opts.templates.length, 1);
-        equal(opts.templates[0].name, 'example_2');
-        done(err);
-      });
+      Precompiler.loadTemplates(
+        { files: [__dirname + '/artifacts'], extension: 'hbs' },
+        function(err, opts) {
+          equal(opts.templates.length, 1);
+          equal(opts.templates[0].name, 'example_2');
+          done(err);
+        }
+      );
     });
     it('should enumerate all templates by extension', function(done) {
-      Precompiler.loadTemplates({files: [__dirname + '/artifacts'], extension: 'handlebars'}, function(err, opts) {
-        equal(opts.templates.length, 3);
-        equal(opts.templates[0].name, 'bom');
-        equal(opts.templates[1].name, 'empty');
-        equal(opts.templates[2].name, 'example_1');
-        done(err);
-      });
+      Precompiler.loadTemplates(
+        { files: [__dirname + '/artifacts'], extension: 'handlebars' },
+        function(err, opts) {
+          equal(opts.templates.length, 3);
+          equal(opts.templates[0].name, 'bom');
+          equal(opts.templates[1].name, 'empty');
+          equal(opts.templates[2].name, 'example_1');
+          done(err);
+        }
+      );
     });
     it('should handle regular expression characters in extensions', function(done) {
-      Precompiler.loadTemplates({files: [__dirname + '/artifacts'], extension: 'hb(s'}, function(err) {
-        // Success is not throwing
-        done(err);
-      });
+      Precompiler.loadTemplates(
+        { files: [__dirname + '/artifacts'], extension: 'hb(s' },
+        function(err) {
+          // Success is not throwing
+          done(err);
+        }
+      );
     });
     it('should handle BOM', function(done) {
-      var opts = {files: [__dirname + '/artifacts/bom.handlebars'], extension: 'handlebars', bom: true};
+      var opts = {
+        files: [__dirname + '/artifacts/bom.handlebars'],
+        extension: 'handlebars',
+        bom: true
+      };
       Precompiler.loadTemplates(opts, function(err, opts) {
         equal(opts.templates[0].source, 'a');
         done(err);
@@ -261,7 +347,11 @@ describe('precompiler', function() {
     });
 
     it('should handle different root', function(done) {
-      var opts = {files: [__dirname + '/artifacts/empty.handlebars'], simple: true, root: 'foo/'};
+      var opts = {
+        files: [__dirname + '/artifacts/empty.handlebars'],
+        simple: true,
+        root: 'foo/'
+      };
       Precompiler.loadTemplates(opts, function(err, opts) {
         equal(opts.templates[0].name, __dirname + '/artifacts/empty');
         done(err);
@@ -269,7 +359,7 @@ describe('precompiler', function() {
     });
 
     it('should accept string inputs', function(done) {
-      var opts = {string: ''};
+      var opts = { string: '' };
       Precompiler.loadTemplates(opts, function(err, opts) {
         equal(opts.templates[0].name, undefined);
         equal(opts.templates[0].source, '');
@@ -277,7 +367,7 @@ describe('precompiler', function() {
       });
     });
     it('should accept string array inputs', function(done) {
-      var opts = {string: ['', 'bar'], name: ['beep', 'boop']};
+      var opts = { string: ['', 'bar'], name: ['beep', 'boop'] };
       Precompiler.loadTemplates(opts, function(err, opts) {
         equal(opts.templates[0].name, 'beep');
         equal(opts.templates[0].source, '');
@@ -288,7 +378,7 @@ describe('precompiler', function() {
     });
     it('should accept stdin input', function(done) {
       var stdin = require('mock-stdin').stdin();
-      Precompiler.loadTemplates({string: '-'}, function(err, opts) {
+      Precompiler.loadTemplates({ string: '-' }, function(err, opts) {
         equal(opts.templates[0].source, 'foo');
         done(err);
       });
@@ -297,9 +387,12 @@ describe('precompiler', function() {
       stdin.end();
     });
     it('error on name missing', function(done) {
-      var opts = {string: ['', 'bar']};
+      var opts = { string: ['', 'bar'] };
       Precompiler.loadTemplates(opts, function(err) {
-        equal(err.message, 'Number of names did not match the number of string inputs');
+        equal(
+          err.message,
+          'Number of names did not match the number of string inputs'
+        );
         done();
       });
     });
diff --git a/spec/regressions.js b/spec/regressions.js
index 3eccb2817..821c48dc2 100644
--- a/spec/regressions.js
+++ b/spec/regressions.js
@@ -1,93 +1,134 @@
 describe('Regressions', function() {
   it('GH-94: Cannot read property of undefined', function() {
     var data = {
-      'books': [{
-        'title': 'The origin of species',
-        'author': {
-          'name': 'Charles Darwin'
+      books: [
+        {
+          title: 'The origin of species',
+          author: {
+            name: 'Charles Darwin'
+          }
+        },
+        {
+          title: 'Lazarillo de Tormes'
         }
-      }, {
-        'title': 'Lazarillo de Tormes'
-      }]
+      ]
     };
     var string = '{{#books}}{{title}}{{author.name}}{{/books}}';
-    shouldCompileTo(string, data, 'The origin of speciesCharles DarwinLazarillo de Tormes',
-                    'Renders without an undefined property error');
+    shouldCompileTo(
+      string,
+      data,
+      'The origin of speciesCharles DarwinLazarillo de Tormes',
+      'Renders without an undefined property error'
+    );
   });
 
   it("GH-150: Inverted sections print when they shouldn't", function() {
     var string = '{{^set}}not set{{/set}} :: {{#set}}set{{/set}}';
 
-    shouldCompileTo(string, {}, 'not set :: ', "inverted sections run when property isn't present in context");
-    shouldCompileTo(string, {set: undefined}, 'not set :: ', 'inverted sections run when property is undefined');
-    shouldCompileTo(string, {set: false}, 'not set :: ', 'inverted sections run when property is false');
-    shouldCompileTo(string, {set: true}, ' :: set', "inverted sections don't run when property is true");
+    shouldCompileTo(
+      string,
+      {},
+      'not set :: ',
+      "inverted sections run when property isn't present in context"
+    );
+    shouldCompileTo(
+      string,
+      { set: undefined },
+      'not set :: ',
+      'inverted sections run when property is undefined'
+    );
+    shouldCompileTo(
+      string,
+      { set: false },
+      'not set :: ',
+      'inverted sections run when property is false'
+    );
+    shouldCompileTo(
+      string,
+      { set: true },
+      ' :: set',
+      "inverted sections don't run when property is true"
+    );
   });
 
   it('GH-158: Using array index twice, breaks the template', function() {
     var string = '{{arr.[0]}}, {{arr.[1]}}';
-    var data = { 'arr': [1, 2] };
+    var data = { arr: [1, 2] };
 
     shouldCompileTo(string, data, '1, 2', 'it works as expected');
   });
 
   it("bug reported by @fat where lambdas weren't being properly resolved", function() {
-    var string = '<strong>This is a slightly more complicated {{thing}}.</strong>.\n'
-        + '{{! Just ignore this business. }}\n'
-        + 'Check this out:\n'
-        + '{{#hasThings}}\n'
-        + '<ul>\n'
-        + '{{#things}}\n'
-        + '<li class={{className}}>{{word}}</li>\n'
-        + '{{/things}}</ul>.\n'
-        + '{{/hasThings}}\n'
-        + '{{^hasThings}}\n'
-        + '\n'
-        + '<small>Nothing to check out...</small>\n'
-        + '{{/hasThings}}';
+    var string =
+      '<strong>This is a slightly more complicated {{thing}}.</strong>.\n' +
+      '{{! Just ignore this business. }}\n' +
+      'Check this out:\n' +
+      '{{#hasThings}}\n' +
+      '<ul>\n' +
+      '{{#things}}\n' +
+      '<li class={{className}}>{{word}}</li>\n' +
+      '{{/things}}</ul>.\n' +
+      '{{/hasThings}}\n' +
+      '{{^hasThings}}\n' +
+      '\n' +
+      '<small>Nothing to check out...</small>\n' +
+      '{{/hasThings}}';
     var data = {
       thing: function() {
         return 'blah';
       },
       things: [
-        {className: 'one', word: '@fat'},
-        {className: 'two', word: '@dhg'},
-        {className: 'three', word: '@sayrer'}
+        { className: 'one', word: '@fat' },
+        { className: 'two', word: '@dhg' },
+        { className: 'three', word: '@sayrer' }
       ],
       hasThings: function() {
         return true;
       }
     };
 
-    var output = '<strong>This is a slightly more complicated blah.</strong>.\n'
-        + 'Check this out:\n'
-        + '<ul>\n'
-        + '<li class=one>@fat</li>\n'
-        + '<li class=two>@dhg</li>\n'
-        + '<li class=three>@sayrer</li>\n'
-        + '</ul>.\n';
+    var output =
+      '<strong>This is a slightly more complicated blah.</strong>.\n' +
+      'Check this out:\n' +
+      '<ul>\n' +
+      '<li class=one>@fat</li>\n' +
+      '<li class=two>@dhg</li>\n' +
+      '<li class=three>@sayrer</li>\n' +
+      '</ul>.\n';
     shouldCompileTo(string, data, output);
   });
 
   it('GH-408: Multiple loops fail', function() {
     var context = [
       { name: 'John Doe', location: { city: 'Chicago' } },
-      { name: 'Jane Doe', location: { city: 'New York'} }
+      { name: 'Jane Doe', location: { city: 'New York' } }
     ];
 
-    var template = CompilerContext.compile('{{#.}}{{name}}{{/.}}{{#.}}{{name}}{{/.}}{{#.}}{{name}}{{/.}}');
+    var template = CompilerContext.compile(
+      '{{#.}}{{name}}{{/.}}{{#.}}{{name}}{{/.}}{{#.}}{{name}}{{/.}}'
+    );
 
     var result = template(context);
-    equals(result, 'John DoeJane DoeJohn DoeJane DoeJohn DoeJane Doe', 'It should output multiple times');
+    equals(
+      result,
+      'John DoeJane DoeJohn DoeJane DoeJohn DoeJane Doe',
+      'It should output multiple times'
+    );
   });
 
   it('GS-428: Nested if else rendering', function() {
-    var succeedingTemplate = '{{#inverse}} {{#blk}} Unexpected {{/blk}} {{else}}  {{#blk}} Expected {{/blk}} {{/inverse}}';
-    var failingTemplate = '{{#inverse}} {{#blk}} Unexpected {{/blk}} {{else}} {{#blk}} Expected {{/blk}} {{/inverse}}';
+    var succeedingTemplate =
+      '{{#inverse}} {{#blk}} Unexpected {{/blk}} {{else}}  {{#blk}} Expected {{/blk}} {{/inverse}}';
+    var failingTemplate =
+      '{{#inverse}} {{#blk}} Unexpected {{/blk}} {{else}} {{#blk}} Expected {{/blk}} {{/inverse}}';
 
     var helpers = {
-      blk: function(block) { return block.fn(''); },
-      inverse: function(block) { return block.inverse(''); }
+      blk: function(block) {
+        return block.fn('');
+      },
+      inverse: function(block) {
+        return block.inverse('');
+      }
     };
 
     shouldCompileTo(succeedingTemplate, [{}, helpers], '   Expected  ');
@@ -95,7 +136,7 @@ describe('Regressions', function() {
   });
 
   it('GH-458: Scoped this identifier', function() {
-    shouldCompileTo('{{./foo}}', {foo: 'bar'}, 'bar');
+    shouldCompileTo('{{./foo}}', { foo: 'bar' }, 'bar');
   });
 
   it('GH-375: Unicode line terminators', function() {
@@ -104,11 +145,11 @@ describe('Regressions', function() {
 
   it('GH-534: Object prototype aliases', function() {
     /* eslint-disable no-extend-native */
-    Object.prototype[0xD834] = true;
+    Object.prototype[0xd834] = true;
 
     shouldCompileTo('{{foo}}', { foo: 'bar' }, 'bar');
 
-    delete Object.prototype[0xD834];
+    delete Object.prototype[0xd834];
     /* eslint-enable no-extend-native */
   });
 
@@ -123,34 +164,46 @@ describe('Regressions', function() {
 
   it('GH-676: Using array in escaping mustache fails', function() {
     var string = '{{arr}}';
-    var data = { 'arr': [1, 2] };
+    var data = { arr: [1, 2] };
 
     shouldCompileTo(string, data, data.arr.toString(), 'it works as expected');
   });
 
   it('Mustache man page', function() {
-    var string = 'Hello {{name}}. You have just won ${{value}}!{{#in_ca}} Well, ${{taxed_value}}, after taxes.{{/in_ca}}';
+    var string =
+      'Hello {{name}}. You have just won ${{value}}!{{#in_ca}} Well, ${{taxed_value}}, after taxes.{{/in_ca}}';
     var data = {
-      'name': 'Chris',
-      'value': 10000,
-      'taxed_value': 10000 - (10000 * 0.4),
-      'in_ca': true
+      name: 'Chris',
+      value: 10000,
+      taxed_value: 10000 - 10000 * 0.4,
+      in_ca: true
     };
 
-    shouldCompileTo(string, data, 'Hello Chris. You have just won $10000! Well, $6000, after taxes.', 'the hello world mustache example works');
+    shouldCompileTo(
+      string,
+      data,
+      'Hello Chris. You have just won $10000! Well, $6000, after taxes.',
+      'the hello world mustache example works'
+    );
   });
 
   it('GH-731: zero context rendering', function() {
-    shouldCompileTo('{{#foo}} This is {{bar}} ~ {{/foo}}', {foo: 0, bar: 'OK'}, ' This is  ~ ');
+    shouldCompileTo(
+      '{{#foo}} This is {{bar}} ~ {{/foo}}',
+      { foo: 0, bar: 'OK' },
+      ' This is  ~ '
+    );
   });
 
   it('GH-820: zero pathed rendering', function() {
-    shouldCompileTo('{{foo.bar}}', {foo: 0}, '');
+    shouldCompileTo('{{foo.bar}}', { foo: 0 }, '');
   });
 
   it('GH-837: undefined values for helpers', function() {
     var helpers = {
-      str: function(value) { return value + ''; }
+      str: function(value) {
+        return value + '';
+      }
     };
 
     shouldCompileTo('{{str bar.baz}}', [{}, helpers], 'undefined');
@@ -159,15 +212,13 @@ describe('Regressions', function() {
   it('GH-926: Depths and de-dupe', function() {
     var context = {
       name: 'foo',
-      data: [
-        1
-      ],
-      notData: [
-        1
-      ]
+      data: [1],
+      notData: [1]
     };
 
-    var template = CompilerContext.compile('{{#if dater}}{{#each data}}{{../name}}{{/each}}{{else}}{{#each notData}}{{../name}}{{/each}}{{/if}}');
+    var template = CompilerContext.compile(
+      '{{#if dater}}{{#each data}}{{../name}}{{/each}}{{else}}{{#each notData}}{{../name}}{{/each}}{{/if}}'
+    );
 
     var result = template(context);
     equals(result, 'foo');
@@ -176,11 +227,15 @@ describe('Regressions', function() {
   it('GH-1021: Each empty string key', function() {
     var data = {
       '': 'foo',
-      'name': 'Chris',
-      'value': 10000
+      name: 'Chris',
+      value: 10000
     };
 
-    shouldCompileTo('{{#each data}}Key: {{@key}}\n{{/each}}', {data: data}, 'Key: \nKey: name\nKey: value\n');
+    shouldCompileTo(
+      '{{#each data}}Key: {{@key}}\n{{/each}}',
+      { data: data },
+      'Key: \nKey: name\nKey: value\n'
+    );
   });
 
   it('GH-1054: Should handle simple safe string responses', function() {
@@ -194,18 +249,27 @@ describe('Regressions', function() {
       }
     };
 
-    shouldCompileToWithPartials(root, [{}, helpers, partials], true, '<partial>');
+    shouldCompileToWithPartials(
+      root,
+      [{}, helpers, partials],
+      true,
+      '<partial>'
+    );
   });
 
   it('GH-1065: Sparse arrays', function() {
     var array = [];
     array[1] = 'foo';
     array[3] = 'bar';
-    shouldCompileTo('{{#each array}}{{@index}}{{.}}{{/each}}', {array: array}, '1foo3bar');
+    shouldCompileTo(
+      '{{#each array}}{{@index}}{{.}}{{/each}}',
+      { array: array },
+      '1foo3bar'
+    );
   });
 
   it('GH-1093: Undefined helper context', function() {
-    var obj = {foo: undefined, bar: 'bat'};
+    var obj = { foo: undefined, bar: 'bat' };
     var helpers = {
       helper: function() {
         // It's valid to execute a block against an undefined context, but
@@ -216,28 +280,45 @@ describe('Regressions', function() {
           }
         }
         // And to make IE happy, check for the known string as length is not enumerated.
-        return (this === 'bat' ? 'found' : 'not');
+        return this === 'bat' ? 'found' : 'not';
       }
     };
 
-    shouldCompileTo('{{#each obj}}{{{helper}}}{{.}}{{/each}}', [{obj: obj}, helpers], 'notfoundbat');
+    shouldCompileTo(
+      '{{#each obj}}{{{helper}}}{{.}}{{/each}}',
+      [{ obj: obj }, helpers],
+      'notfoundbat'
+    );
   });
 
   it('should support multiple levels of inline partials', function() {
-    var string = '{{#> layout}}{{#*inline "subcontent"}}subcontent{{/inline}}{{/layout}}';
+    var string =
+      '{{#> layout}}{{#*inline "subcontent"}}subcontent{{/inline}}{{/layout}}';
     var partials = {
       doctype: 'doctype{{> content}}',
-      layout: '{{#> doctype}}{{#*inline "content"}}layout{{> subcontent}}{{/inline}}{{/doctype}}'
+      layout:
+        '{{#> doctype}}{{#*inline "content"}}layout{{> subcontent}}{{/inline}}{{/doctype}}'
     };
-    shouldCompileToWithPartials(string, [{}, {}, partials], true, 'doctypelayoutsubcontent');
+    shouldCompileToWithPartials(
+      string,
+      [{}, {}, partials],
+      true,
+      'doctypelayoutsubcontent'
+    );
   });
   it('GH-1089: should support failover content in multiple levels of inline partials', function() {
     var string = '{{#> layout}}{{/layout}}';
     var partials = {
       doctype: 'doctype{{> content}}',
-      layout: '{{#> doctype}}{{#*inline "content"}}layout{{#> subcontent}}subcontent{{/subcontent}}{{/inline}}{{/doctype}}'
+      layout:
+        '{{#> doctype}}{{#*inline "content"}}layout{{#> subcontent}}subcontent{{/subcontent}}{{/inline}}{{/doctype}}'
     };
-    shouldCompileToWithPartials(string, [{}, {}, partials], true, 'doctypelayoutsubcontent');
+    shouldCompileToWithPartials(
+      string,
+      [{}, {}, partials],
+      true,
+      'doctypelayoutsubcontent'
+    );
   });
   it('GH-1099: should support greater than 3 nested levels of inline partials', function() {
     var string = '{{#> layout}}Outer{{/layout}}';
@@ -249,51 +330,63 @@ describe('Regressions', function() {
   });
 
   it('GH-1135 : Context handling within each iteration', function() {
-    var obj = {array: [1], name: 'John'};
+    var obj = { array: [1], name: 'John' };
     var helpers = {
       myif: function(conditional, options) {
         if (conditional) {
-            return options.fn(this);
+          return options.fn(this);
         } else {
-            return options.inverse(this);
+          return options.inverse(this);
         }
       }
     };
 
     shouldCompileTo(
-      '{{#each array}}\n'
-      + ' 1. IF: {{#if true}}{{../name}}-{{../../name}}-{{../../../name}}{{/if}}\n'
-      + ' 2. MYIF: {{#myif true}}{{../name}}={{../../name}}={{../../../name}}{{/myif}}\n'
-      + '{{/each}}', [obj, helpers],
-      ' 1. IF: John--\n'
-      + ' 2. MYIF: John==\n');
+      '{{#each array}}\n' +
+        ' 1. IF: {{#if true}}{{../name}}-{{../../name}}-{{../../../name}}{{/if}}\n' +
+        ' 2. MYIF: {{#myif true}}{{../name}}={{../../name}}={{../../../name}}{{/myif}}\n' +
+        '{{/each}}',
+      [obj, helpers],
+      ' 1. IF: John--\n' + ' 2. MYIF: John==\n'
+    );
   });
 
   it('GH-1186: Support block params for existing programs', function() {
     var string =
-        '{{#*inline "test"}}{{> @partial-block }}{{/inline}}'
-      + '{{#>test }}{{#each listOne as |item|}}{{ item }}{{/each}}{{/test}}'
-      + '{{#>test }}{{#each listTwo as |item|}}{{ item }}{{/each}}{{/test}}';
+      '{{#*inline "test"}}{{> @partial-block }}{{/inline}}' +
+      '{{#>test }}{{#each listOne as |item|}}{{ item }}{{/each}}{{/test}}' +
+      '{{#>test }}{{#each listTwo as |item|}}{{ item }}{{/each}}{{/test}}';
 
-    shouldCompileTo(string, { listOne: ['a'], listTwo: ['b']}, 'ab', '');
+    shouldCompileTo(string, { listOne: ['a'], listTwo: ['b'] }, 'ab', '');
   });
 
   it('GH-1319: "unless" breaks when "each" value equals "null"', function() {
-    var string = '{{#each list}}{{#unless ./prop}}parent={{../value}} {{/unless}}{{/each}}';
-    shouldCompileTo(string, { value: 'parent', list: [ null, 'a'] }, 'parent=parent parent=parent ', '');
+    var string =
+      '{{#each list}}{{#unless ./prop}}parent={{../value}} {{/unless}}{{/each}}';
+    shouldCompileTo(
+      string,
+      { value: 'parent', list: [null, 'a'] },
+      'parent=parent parent=parent ',
+      ''
+    );
   });
 
   it('GH-1341: 4.0.7 release breaks {{#if @partial-block}} usage', function() {
     var string = 'template {{>partial}} template';
     var partials = {
-      partialWithBlock: '{{#if @partial-block}} block {{> @partial-block}} block {{/if}}',
+      partialWithBlock:
+        '{{#if @partial-block}} block {{> @partial-block}} block {{/if}}',
       partial: '{{#> partialWithBlock}} partial {{/partialWithBlock}}'
     };
-    shouldCompileToWithPartials(string, [{}, {}, partials], true, 'template  block  partial  block  template');
+    shouldCompileToWithPartials(
+      string,
+      [{}, {}, partials],
+      true,
+      'template  block  partial  block  template'
+    );
   });
 
   describe('GH-1561: 4.3.x should still work with precompiled templates from 4.0.0 <= x < 4.3.0', function() {
-
     it('should compile and execute templates', function() {
       var newHandlebarsInstance = Handlebars.create();
 
@@ -301,31 +394,53 @@ describe('Regressions', function() {
       newHandlebarsInstance.registerHelper('loud', function(value) {
         return value.toUpperCase();
       });
-      var result = newHandlebarsInstance.templates['test.hbs']({name: 'yehuda'});
+      var result = newHandlebarsInstance.templates['test.hbs']({
+        name: 'yehuda'
+      });
       equals(result.trim(), 'YEHUDA');
     });
 
     it('should call "helperMissing" if a helper is missing', function() {
       var newHandlebarsInstance = Handlebars.create();
 
-      shouldThrow(function() {
-        registerTemplate(newHandlebarsInstance);
-        newHandlebarsInstance.templates['test.hbs']({});
-      }, Handlebars.Exception, 'Missing helper: "loud"');
+      shouldThrow(
+        function() {
+          registerTemplate(newHandlebarsInstance);
+          newHandlebarsInstance.templates['test.hbs']({});
+        },
+        Handlebars.Exception,
+        'Missing helper: "loud"'
+      );
     });
 
     // This is a only slightly modified precompiled templated from compiled with 4.2.1
     function registerTemplate(Handlebars) {
-      var template = Handlebars.template, templates = Handlebars.templates = Handlebars.templates || {};
-      templates['test.hbs'] = template({'compiler': [7, '>= 4.0.0'], 'main': function(container, depth0, helpers, partials, data) {
-          return container.escapeExpression((helpers.loud || (depth0 && depth0.loud) || helpers.helperMissing).call(depth0 != null ? depth0 : (container.nullContext || {}), (depth0 != null ? depth0.name : depth0), {'name': 'loud', 'hash': {}, 'data': data}))
-              + '\n\n';
-        }, 'useData': true});
+      var template = Handlebars.template,
+        templates = (Handlebars.templates = Handlebars.templates || {});
+      templates['test.hbs'] = template({
+        compiler: [7, '>= 4.0.0'],
+        main: function(container, depth0, helpers, partials, data) {
+          return (
+            container.escapeExpression(
+              (
+                helpers.loud ||
+                (depth0 && depth0.loud) ||
+                helpers.helperMissing
+              ).call(
+                depth0 != null ? depth0 : container.nullContext || {},
+                depth0 != null ? depth0.name : depth0,
+                { name: 'loud', hash: {}, data: data }
+              )
+            ) + '\n\n'
+          );
+        },
+        useData: true
+      });
     }
   });
 
   it('should allow hash with protected array names', function() {
-    var obj = {array: [1], name: 'John'};
+    var obj = { array: [1], name: 'John' };
     var helpers = {
       helpa: function(options) {
         return options.hash.length;
@@ -352,7 +467,7 @@ describe('Regressions', function() {
     it('should only compile global partials once', function() {
       var templateSpy = sinon.spy(newHandlebarsInstance, 'template');
       newHandlebarsInstance.registerPartial({
-        'dude': 'I am a partial'
+        dude: 'I am a partial'
       });
       var string = 'Dudes: {{> dude}} {{> dude}}';
       newHandlebarsInstance.compile(string)(); // This should compile template + partial once
diff --git a/spec/require.js b/spec/require.js
index 6c0b5ae46..f8ddba59a 100644
--- a/spec/require.js
+++ b/spec/require.js
@@ -5,7 +5,7 @@ if (typeof require !== 'undefined' && require.extensions['.handlebars']) {
       equal(template, require('./artifacts/example_1.handlebars'));
 
       var expected = 'foo\n';
-      var result = template({foo: 'foo'});
+      var result = template({ foo: 'foo' });
 
       equal(result, expected);
     });
@@ -15,7 +15,7 @@ if (typeof require !== 'undefined' && require.extensions['.handlebars']) {
       equal(template, require('./artifacts/example_2.hbs'));
 
       var expected = 'Hello, World!\n';
-      var result = template({name: 'World'});
+      var result = template({ name: 'World' });
 
       equal(result, expected);
     });
diff --git a/spec/runtime.js b/spec/runtime.js
index 3549640b7..7924a5f00 100644
--- a/spec/runtime.js
+++ b/spec/runtime.js
@@ -1,34 +1,58 @@
 describe('runtime', function() {
   describe('#template', function() {
     it('should throw on invalid templates', function() {
-      shouldThrow(function() {
-        Handlebars.template({});
-      }, Error, 'Unknown template object: object');
-      shouldThrow(function() {
-        Handlebars.template();
-      }, Error, 'Unknown template object: undefined');
-      shouldThrow(function() {
-        Handlebars.template('');
-      }, Error, 'Unknown template object: string');
+      shouldThrow(
+        function() {
+          Handlebars.template({});
+        },
+        Error,
+        'Unknown template object: object'
+      );
+      shouldThrow(
+        function() {
+          Handlebars.template();
+        },
+        Error,
+        'Unknown template object: undefined'
+      );
+      shouldThrow(
+        function() {
+          Handlebars.template('');
+        },
+        Error,
+        'Unknown template object: string'
+      );
     });
     it('should throw on version mismatch', function() {
-      shouldThrow(function() {
-        Handlebars.template({
-          main: {},
-          compiler: [Handlebars.COMPILER_REVISION + 1]
-        });
-      }, Error, /Template was precompiled with a newer version of Handlebars than the current runtime/);
-      shouldThrow(function() {
-        Handlebars.template({
-          main: {},
-          compiler: [Handlebars.LAST_COMPATIBLE_COMPILER_REVISION - 1]
-        });
-      }, Error, /Template was precompiled with an older version of Handlebars than the current runtime/);
-      shouldThrow(function() {
-        Handlebars.template({
-          main: {}
-        });
-      }, Error, /Template was precompiled with an older version of Handlebars than the current runtime/);
+      shouldThrow(
+        function() {
+          Handlebars.template({
+            main: {},
+            compiler: [Handlebars.COMPILER_REVISION + 1]
+          });
+        },
+        Error,
+        /Template was precompiled with a newer version of Handlebars than the current runtime/
+      );
+      shouldThrow(
+        function() {
+          Handlebars.template({
+            main: {},
+            compiler: [Handlebars.LAST_COMPATIBLE_COMPILER_REVISION - 1]
+          });
+        },
+        Error,
+        /Template was precompiled with an older version of Handlebars than the current runtime/
+      );
+      shouldThrow(
+        function() {
+          Handlebars.template({
+            main: {}
+          });
+        },
+        Error,
+        /Template was precompiled with an older version of Handlebars than the current runtime/
+      );
     });
   });
 
@@ -38,34 +62,42 @@ describe('runtime', function() {
     }
 
     it('should throw for depthed methods without depths', function() {
-      shouldThrow(function() {
-        var template = Handlebars.compile('{{#foo}}{{../bar}}{{/foo}}');
-        // Calling twice to hit the non-compiled case.
-        template._setup({});
-        template._setup({});
-        template._child(1);
-      }, Error, 'must pass parent depths');
+      shouldThrow(
+        function() {
+          var template = Handlebars.compile('{{#foo}}{{../bar}}{{/foo}}');
+          // Calling twice to hit the non-compiled case.
+          template._setup({});
+          template._setup({});
+          template._child(1);
+        },
+        Error,
+        'must pass parent depths'
+      );
     });
 
     it('should throw for block param methods without params', function() {
-      shouldThrow(function() {
-        var template = Handlebars.compile('{{#foo as |foo|}}{{foo}}{{/foo}}');
-        // Calling twice to hit the non-compiled case.
-        template._setup({});
-        template._setup({});
-        template._child(1);
-      }, Error, 'must pass block params');
+      shouldThrow(
+        function() {
+          var template = Handlebars.compile('{{#foo as |foo|}}{{foo}}{{/foo}}');
+          // Calling twice to hit the non-compiled case.
+          template._setup({});
+          template._setup({});
+          template._child(1);
+        },
+        Error,
+        'must pass block params'
+      );
     });
     it('should expose child template', function() {
       var template = Handlebars.compile('{{#foo}}bar{{/foo}}');
-        // Calling twice to hit the non-compiled case.
+      // Calling twice to hit the non-compiled case.
       equal(template._child(1)(), 'bar');
       equal(template._child(1)(), 'bar');
     });
     it('should render depthed content', function() {
       var template = Handlebars.compile('{{#foo}}{{../bar}}{{/foo}}');
-        // Calling twice to hit the non-compiled case.
-      equal(template._child(1, undefined, [], [{bar: 'baz'}])(), 'baz');
+      // Calling twice to hit the non-compiled case.
+      equal(template._child(1, undefined, [], [{ bar: 'baz' }])(), 'baz');
     });
   });
 
diff --git a/spec/security.js b/spec/security.js
index 18bfa5dd7..ed0189281 100644
--- a/spec/security.js
+++ b/spec/security.js
@@ -1,144 +1,208 @@
 describe('security issues', function() {
-    describe('GH-1495: Prevent Remote Code Execution via constructor', function() {
-        it('should not allow constructors to be accessed', function() {
-            expectTemplate('{{lookup (lookup this "constructor") "name"}}')
-                .withInput({})
-                .toCompileTo('');
-
-            expectTemplate('{{constructor.name}}')
-                .withInput({})
-                .toCompileTo('');
-        });
-
-        it('GH-1603: should not allow constructors to be accessed (lookup via toString)', function() {
-          expectTemplate('{{lookup (lookup this (list "constructor")) "name"}}')
-              .withInput({})
-              .withHelper('list', function(element) {
-                return [element];
-              })
-              .toCompileTo('');
-        });
-
-
-      it('should allow the "constructor" property to be accessed if it is enumerable', function() {
-            shouldCompileTo('{{constructor.name}}', {'constructor': {
-                'name': 'here we go'
-            }}, 'here we go');
-            shouldCompileTo('{{lookup (lookup this "constructor") "name"}}', {'constructor': {
-                'name': 'here we go'
-            }}, 'here we go');
-        });
-
-        it('should allow the "constructor" property to be accessed if it is enumerable', function() {
-            shouldCompileTo('{{lookup (lookup this "constructor") "name"}}', {'constructor': {
-                    'name': 'here we go'
-                }}, 'here we go');
-        });
-
-
-        it('should allow prototype properties that are not constructors', function() {
-            function TestClass() {
-            }
-
-            Object.defineProperty(TestClass.prototype, 'abc', {
-                get: function() {
-                    return 'xyz';
-                }
+  describe('GH-1495: Prevent Remote Code Execution via constructor', function() {
+    it('should not allow constructors to be accessed', function() {
+      expectTemplate('{{lookup (lookup this "constructor") "name"}}')
+        .withInput({})
+        .toCompileTo('');
+
+      expectTemplate('{{constructor.name}}')
+        .withInput({})
+        .toCompileTo('');
+    });
 
-            });
+    it('GH-1603: should not allow constructors to be accessed (lookup via toString)', function() {
+      expectTemplate('{{lookup (lookup this (list "constructor")) "name"}}')
+        .withInput({})
+        .withHelper('list', function(element) {
+          return [element];
+        })
+        .toCompileTo('');
+    });
 
-            shouldCompileTo('{{#with this as |obj|}}{{obj.abc}}{{/with}}',
-                new TestClass(), 'xyz');
-            shouldCompileTo('{{#with this as |obj|}}{{lookup obj "abc"}}{{/with}}',
-                new TestClass(), 'xyz');
+    it('should allow the "constructor" property to be accessed if it is enumerable', function() {
+      shouldCompileTo(
+        '{{constructor.name}}',
+        {
+          constructor: {
+            name: 'here we go'
+          }
+        },
+        'here we go'
+      );
+      shouldCompileTo(
+        '{{lookup (lookup this "constructor") "name"}}',
+        {
+          constructor: {
+            name: 'here we go'
+          }
+        },
+        'here we go'
+      );
+    });
 
-        });
+    it('should allow the "constructor" property to be accessed if it is enumerable', function() {
+      shouldCompileTo(
+        '{{lookup (lookup this "constructor") "name"}}',
+        {
+          constructor: {
+            name: 'here we go'
+          }
+        },
+        'here we go'
+      );
     });
 
-    describe('GH-1558: Prevent explicit call of helperMissing-helpers', function() {
-        if (!Handlebars.compile) {
-            return;
-        }
+    it('should allow prototype properties that are not constructors', function() {
+      function TestClass() {}
 
-        describe('without the option "allowExplicitCallOfHelperMissing"', function() {
-            it('should throw an exception when calling  "{{helperMissing}}" ', function() {
-                shouldThrow(function() {
-                    var template = Handlebars.compile('{{helperMissing}}');
-                    template({});
-                }, Error);
-            });
-            it('should throw an exception when calling  "{{#helperMissing}}{{/helperMissing}}" ', function() {
-                shouldThrow(function() {
-                    var template = Handlebars.compile('{{#helperMissing}}{{/helperMissing}}');
-                    template({});
-                }, Error);
-            });
-            it('should throw an exception when calling  "{{blockHelperMissing "abc" .}}" ', function() {
-                var functionCalls = [];
-                expect(function() {
-                    var template = Handlebars.compile('{{blockHelperMissing "abc" .}}');
-                    template({ fn: function() { functionCalls.push('called'); }});
-                }).to.throw(Error);
-                expect(functionCalls.length).to.equal(0);
-            });
-            it('should throw an exception when calling  "{{#blockHelperMissing .}}{{/blockHelperMissing}}"', function() {
-                shouldThrow(function() {
-                    var template = Handlebars.compile('{{#blockHelperMissing .}}{{/blockHelperMissing}}');
-                    template({ fn: function() { return 'functionInData';}});
-                }, Error);
-            });
-        });
+      Object.defineProperty(TestClass.prototype, 'abc', {
+        get: function() {
+          return 'xyz';
+        }
+      });
 
-        describe('with the option "allowCallsToHelperMissing" set to true', function() {
-            it('should not throw an exception when calling  "{{helperMissing}}" ', function() {
-                    var template = Handlebars.compile('{{helperMissing}}');
-                    template({}, {allowCallsToHelperMissing: true});
-            });
-            it('should not throw an exception when calling  "{{#helperMissing}}{{/helperMissing}}" ', function() {
-                    var template = Handlebars.compile('{{#helperMissing}}{{/helperMissing}}');
-                    template({}, {allowCallsToHelperMissing: true});
-            });
-            it('should not throw an exception when calling  "{{blockHelperMissing "abc" .}}" ', function() {
-                    var functionCalls = [];
-                    var template = Handlebars.compile('{{blockHelperMissing "abc" .}}');
-                    template({ fn: function() { functionCalls.push('called'); }}, {allowCallsToHelperMissing: true});
-                    equals(functionCalls.length, 1);
-            });
-            it('should not throw an exception when calling  "{{#blockHelperMissing .}}{{/blockHelperMissing}}"', function() {
-                    var template = Handlebars.compile('{{#blockHelperMissing true}}sdads{{/blockHelperMissing}}');
-                    template({}, {allowCallsToHelperMissing: true});
-            });
-        });
+      shouldCompileTo(
+        '{{#with this as |obj|}}{{obj.abc}}{{/with}}',
+        new TestClass(),
+        'xyz'
+      );
+      shouldCompileTo(
+        '{{#with this as |obj|}}{{lookup obj "abc"}}{{/with}}',
+        new TestClass(),
+        'xyz'
+      );
     });
-
-    describe('GH-1563', function() {
-        it('should not allow to access constructor after overriding via __defineGetter__', function() {
-            if (({}).__defineGetter__ == null || ({}).__lookupGetter__ == null) {
-                return this.skip(); // Browser does not support this exploit anyway
+  });
+
+  describe('GH-1558: Prevent explicit call of helperMissing-helpers', function() {
+    if (!Handlebars.compile) {
+      return;
+    }
+
+    describe('without the option "allowExplicitCallOfHelperMissing"', function() {
+      it('should throw an exception when calling  "{{helperMissing}}" ', function() {
+        shouldThrow(function() {
+          var template = Handlebars.compile('{{helperMissing}}');
+          template({});
+        }, Error);
+      });
+      it('should throw an exception when calling  "{{#helperMissing}}{{/helperMissing}}" ', function() {
+        shouldThrow(function() {
+          var template = Handlebars.compile(
+            '{{#helperMissing}}{{/helperMissing}}'
+          );
+          template({});
+        }, Error);
+      });
+      it('should throw an exception when calling  "{{blockHelperMissing "abc" .}}" ', function() {
+        var functionCalls = [];
+        expect(function() {
+          var template = Handlebars.compile('{{blockHelperMissing "abc" .}}');
+          template({
+            fn: function() {
+              functionCalls.push('called');
             }
-            expectTemplate('{{__defineGetter__ "undefined" valueOf }}' +
-                '{{#with __lookupGetter__ }}' +
-                '{{__defineGetter__ "propertyIsEnumerable" (this.bind (this.bind 1)) }}' +
-                '{{constructor.name}}' +
-                '{{/with}}')
-                .withInput({})
-                .toThrow(/Missing helper: "__defineGetter__"/);
-        });
+          });
+        }).to.throw(Error);
+        expect(functionCalls.length).to.equal(0);
+      });
+      it('should throw an exception when calling  "{{#blockHelperMissing .}}{{/blockHelperMissing}}"', function() {
+        shouldThrow(function() {
+          var template = Handlebars.compile(
+            '{{#blockHelperMissing .}}{{/blockHelperMissing}}'
+          );
+          template({
+            fn: function() {
+              return 'functionInData';
+            }
+          });
+        }, Error);
+      });
     });
 
-    describe('GH-1595', function() {
-      it('properties, that are required to be enumerable', function() {
-        expectTemplate('{{constructor}}').withInput({}).toCompileTo('');
-        expectTemplate('{{__defineGetter__}}').withInput({}).toCompileTo('');
-        expectTemplate('{{__defineSetter__}}').withInput({}).toCompileTo('');
-        expectTemplate('{{__lookupGetter__}}').withInput({}).toCompileTo('');
-        expectTemplate('{{__proto__}}').withInput({}).toCompileTo('');
-
-        expectTemplate('{{lookup "constructor"}}').withInput({}).toCompileTo('');
-        expectTemplate('{{lookup "__defineGetter__"}}').withInput({}).toCompileTo('');
-        expectTemplate('{{lookup "__defineSetter__"}}').withInput({}).toCompileTo('');
-        expectTemplate('{{lookup "__lookupGetter__"}}').withInput({}).toCompileTo('');
-        expectTemplate('{{lookup "__proto__"}}').withInput({}).toCompileTo('');
+    describe('with the option "allowCallsToHelperMissing" set to true', function() {
+      it('should not throw an exception when calling  "{{helperMissing}}" ', function() {
+        var template = Handlebars.compile('{{helperMissing}}');
+        template({}, { allowCallsToHelperMissing: true });
+      });
+      it('should not throw an exception when calling  "{{#helperMissing}}{{/helperMissing}}" ', function() {
+        var template = Handlebars.compile(
+          '{{#helperMissing}}{{/helperMissing}}'
+        );
+        template({}, { allowCallsToHelperMissing: true });
+      });
+      it('should not throw an exception when calling  "{{blockHelperMissing "abc" .}}" ', function() {
+        var functionCalls = [];
+        var template = Handlebars.compile('{{blockHelperMissing "abc" .}}');
+        template(
+          {
+            fn: function() {
+              functionCalls.push('called');
+            }
+          },
+          { allowCallsToHelperMissing: true }
+        );
+        equals(functionCalls.length, 1);
       });
+      it('should not throw an exception when calling  "{{#blockHelperMissing .}}{{/blockHelperMissing}}"', function() {
+        var template = Handlebars.compile(
+          '{{#blockHelperMissing true}}sdads{{/blockHelperMissing}}'
+        );
+        template({}, { allowCallsToHelperMissing: true });
+      });
+    });
+  });
+
+  describe('GH-1563', function() {
+    it('should not allow to access constructor after overriding via __defineGetter__', function() {
+      if ({}.__defineGetter__ == null || {}.__lookupGetter__ == null) {
+        return this.skip(); // Browser does not support this exploit anyway
+      }
+      expectTemplate(
+        '{{__defineGetter__ "undefined" valueOf }}' +
+          '{{#with __lookupGetter__ }}' +
+          '{{__defineGetter__ "propertyIsEnumerable" (this.bind (this.bind 1)) }}' +
+          '{{constructor.name}}' +
+          '{{/with}}'
+      )
+        .withInput({})
+        .toThrow(/Missing helper: "__defineGetter__"/);
+    });
+  });
+
+  describe('GH-1595', function() {
+    it('properties, that are required to be enumerable', function() {
+      expectTemplate('{{constructor}}')
+        .withInput({})
+        .toCompileTo('');
+      expectTemplate('{{__defineGetter__}}')
+        .withInput({})
+        .toCompileTo('');
+      expectTemplate('{{__defineSetter__}}')
+        .withInput({})
+        .toCompileTo('');
+      expectTemplate('{{__lookupGetter__}}')
+        .withInput({})
+        .toCompileTo('');
+      expectTemplate('{{__proto__}}')
+        .withInput({})
+        .toCompileTo('');
+
+      expectTemplate('{{lookup "constructor"}}')
+        .withInput({})
+        .toCompileTo('');
+      expectTemplate('{{lookup "__defineGetter__"}}')
+        .withInput({})
+        .toCompileTo('');
+      expectTemplate('{{lookup "__defineSetter__"}}')
+        .withInput({})
+        .toCompileTo('');
+      expectTemplate('{{lookup "__lookupGetter__"}}')
+        .withInput({})
+        .toCompileTo('');
+      expectTemplate('{{lookup "__proto__"}}')
+        .withInput({})
+        .toCompileTo('');
     });
+  });
 });
diff --git a/spec/source-map.js b/spec/source-map.js
index 54e5e4d91..024aaae60 100644
--- a/spec/source-map.js
+++ b/spec/source-map.js
@@ -1,7 +1,7 @@
 try {
   if (typeof define !== 'function' || !define.amd) {
     var SourceMap = require('source-map'),
-         SourceMapConsumer = SourceMap.SourceMapConsumer;
+      SourceMapConsumer = SourceMap.SourceMapConsumer;
   }
 } catch (err) {
   /* NOP for in browser */
@@ -13,22 +13,28 @@ describe('source-map', function() {
   }
 
   it('should safely include source map info', function() {
-    var template = Handlebars.precompile('{{hello}}', {destName: 'dest.js', srcName: 'src.hbs'});
+    var template = Handlebars.precompile('{{hello}}', {
+      destName: 'dest.js',
+      srcName: 'src.hbs'
+    });
 
     equal(!!template.code, true);
     equal(!!template.map, !CompilerContext.browser);
   });
   it('should map source properly', function() {
-    var templateSource = '  b{{hello}}  \n  {{bar}}a {{#block arg hash=(subex 1 subval)}}{{/block}}',
-        template = Handlebars.precompile(templateSource, {destName: 'dest.js', srcName: 'src.hbs'});
+    var templateSource =
+        '  b{{hello}}  \n  {{bar}}a {{#block arg hash=(subex 1 subval)}}{{/block}}',
+      template = Handlebars.precompile(templateSource, {
+        destName: 'dest.js',
+        srcName: 'src.hbs'
+      });
 
     if (template.map) {
       var consumer = new SourceMapConsumer(template.map),
-          lines = template.code.split('\n'),
-          srcLines = templateSource.split('\n'),
-
-          generated = grepLine('"  b"', lines),
-          source = grepLine('  b', srcLines);
+        lines = template.code.split('\n'),
+        srcLines = templateSource.split('\n'),
+        generated = grepLine('"  b"', lines),
+        source = grepLine('  b', srcLines);
 
       var mapped = consumer.originalPositionFor(generated);
       equal(mapped.line, source.line);
diff --git a/spec/spec.js b/spec/spec.js
index 805609d01..ff4d7bc98 100644
--- a/spec/spec.js
+++ b/spec/spec.js
@@ -5,11 +5,11 @@ describe('spec', function() {
   }
 
   var _ = require('underscore'),
-      fs = require('fs');
+    fs = require('fs');
 
   var specDir = __dirname + '/mustache/specs/';
   var specs = _.filter(fs.readdirSync(specDir), function(name) {
-    return (/.*\.json$/).test(name);
+    return /.*\.json$/.test(name);
   });
 
   _.each(specs, function(name) {
@@ -17,16 +17,17 @@ describe('spec', function() {
     _.each(spec.tests, function(test) {
       // Our lambda implementation knowingly deviates from the optional Mustace lambda spec
       // We also do not support alternative delimeters
-      if (name === '~lambdas.json'
-
-          // We also choose to throw if paritals are not found
-          || (name === 'partials.json' && test.name === 'Failed Lookup')
-
-          // We nest the entire response from partials, not just the literals
-          || (name === 'partials.json' && test.name === 'Standalone Indentation')
-
-          || (/\{\{=/).test(test.template)
-          || _.any(test.partials, function(partial) { return (/\{\{=/).test(partial); })) {
+      if (
+        name === '~lambdas.json' ||
+        // We also choose to throw if paritals are not found
+        (name === 'partials.json' && test.name === 'Failed Lookup') ||
+        // We nest the entire response from partials, not just the literals
+        (name === 'partials.json' && test.name === 'Standalone Indentation') ||
+        /\{\{=/.test(test.template) ||
+        _.any(test.partials, function(partial) {
+          return /\{\{=/.test(partial);
+        })
+      ) {
         it.skip(name + ' - ' + test.name);
         return;
       }
@@ -40,9 +41,20 @@ describe('spec', function() {
       }
       it(name + ' - ' + test.name, function() {
         if (test.partials) {
-          shouldCompileToWithPartials(test.template, [data, {}, test.partials, true], true, test.expected, test.desc + ' "' + test.template + '"');
+          shouldCompileToWithPartials(
+            test.template,
+            [data, {}, test.partials, true],
+            true,
+            test.expected,
+            test.desc + ' "' + test.template + '"'
+          );
         } else {
-          shouldCompileTo(test.template, [data, {}, {}, true], test.expected, test.desc + ' "' + test.template + '"');
+          shouldCompileTo(
+            test.template,
+            [data, {}, {}, true],
+            test.expected,
+            test.desc + ' "' + test.template + '"'
+          );
         }
       });
     });
diff --git a/spec/strict.js b/spec/strict.js
index 3bd7cc18e..680bbc0d8 100644
--- a/spec/strict.js
+++ b/spec/strict.js
@@ -3,43 +3,58 @@ var Exception = Handlebars.Exception;
 describe('strict', function() {
   describe('strict mode', function() {
     it('should error on missing property lookup', function() {
-      shouldThrow(function() {
-        var template = CompilerContext.compile('{{hello}}', {strict: true});
+      shouldThrow(
+        function() {
+          var template = CompilerContext.compile('{{hello}}', { strict: true });
 
-        template({});
-      }, Exception, /"hello" not defined in/);
+          template({});
+        },
+        Exception,
+        /"hello" not defined in/
+      );
     });
     it('should error on missing child', function() {
-      var template = CompilerContext.compile('{{hello.bar}}', {strict: true});
-      equals(template({hello: {bar: 'foo'}}), 'foo');
+      var template = CompilerContext.compile('{{hello.bar}}', { strict: true });
+      equals(template({ hello: { bar: 'foo' } }), 'foo');
 
-      shouldThrow(function() {
-        template({hello: {}});
-      }, Exception, /"bar" not defined in/);
+      shouldThrow(
+        function() {
+          template({ hello: {} });
+        },
+        Exception,
+        /"bar" not defined in/
+      );
     });
     it('should handle explicit undefined', function() {
-      var template = CompilerContext.compile('{{hello.bar}}', {strict: true});
+      var template = CompilerContext.compile('{{hello.bar}}', { strict: true });
 
-      equals(template({hello: {bar: undefined}}), '');
+      equals(template({ hello: { bar: undefined } }), '');
     });
     it('should error on missing property lookup in known helpers mode', function() {
-      shouldThrow(function() {
-        var template = CompilerContext.compile('{{hello}}', {strict: true, knownHelpersOnly: true});
-
-        template({});
-      }, Exception, /"hello" not defined in/);
+      shouldThrow(
+        function() {
+          var template = CompilerContext.compile('{{hello}}', {
+            strict: true,
+            knownHelpersOnly: true
+          });
+
+          template({});
+        },
+        Exception,
+        /"hello" not defined in/
+      );
     });
     it('should error on missing context', function() {
       shouldThrow(function() {
-        var template = CompilerContext.compile('{{hello}}', {strict: true});
+        var template = CompilerContext.compile('{{hello}}', { strict: true });
 
         template();
       }, Error);
     });
 
     it('should error on missing data lookup', function() {
-      var template = CompilerContext.compile('{{@hello}}', {strict: true});
-      equals(template(undefined, {data: {hello: 'foo'}}), 'foo');
+      var template = CompilerContext.compile('{{@hello}}', { strict: true });
+      equals(template(undefined, { data: { hello: 'foo' } }), 'foo');
 
       shouldThrow(function() {
         template();
@@ -47,45 +62,81 @@ describe('strict', function() {
     });
 
     it('should not run helperMissing for helper calls', function() {
-      shouldThrow(function() {
-        var template = CompilerContext.compile('{{hello foo}}', {strict: true});
-
-        template({foo: true});
-      }, Exception, /"hello" not defined in/);
-
-      shouldThrow(function() {
-        var template = CompilerContext.compile('{{#hello foo}}{{/hello}}', {strict: true});
-
-        template({foo: true});
-      }, Exception, /"hello" not defined in/);
+      shouldThrow(
+        function() {
+          var template = CompilerContext.compile('{{hello foo}}', {
+            strict: true
+          });
+
+          template({ foo: true });
+        },
+        Exception,
+        /"hello" not defined in/
+      );
+
+      shouldThrow(
+        function() {
+          var template = CompilerContext.compile('{{#hello foo}}{{/hello}}', {
+            strict: true
+          });
+
+          template({ foo: true });
+        },
+        Exception,
+        /"hello" not defined in/
+      );
     });
     it('should throw on ambiguous blocks', function() {
-      shouldThrow(function() {
-        var template = CompilerContext.compile('{{#hello}}{{/hello}}', {strict: true});
-
-        template({});
-      }, Exception, /"hello" not defined in/);
-
-      shouldThrow(function() {
-        var template = CompilerContext.compile('{{^hello}}{{/hello}}', {strict: true});
-
-        template({});
-      }, Exception, /"hello" not defined in/);
-
-      shouldThrow(function() {
-        var template = CompilerContext.compile('{{#hello.bar}}{{/hello.bar}}', {strict: true});
-
-        template({hello: {}});
-      }, Exception, /"bar" not defined in/);
+      shouldThrow(
+        function() {
+          var template = CompilerContext.compile('{{#hello}}{{/hello}}', {
+            strict: true
+          });
+
+          template({});
+        },
+        Exception,
+        /"hello" not defined in/
+      );
+
+      shouldThrow(
+        function() {
+          var template = CompilerContext.compile('{{^hello}}{{/hello}}', {
+            strict: true
+          });
+
+          template({});
+        },
+        Exception,
+        /"hello" not defined in/
+      );
+
+      shouldThrow(
+        function() {
+          var template = CompilerContext.compile(
+            '{{#hello.bar}}{{/hello.bar}}',
+            { strict: true }
+          );
+
+          template({ hello: {} });
+        },
+        Exception,
+        /"bar" not defined in/
+      );
     });
 
     it('should allow undefined parameters when passed to helpers', function() {
-      var template = CompilerContext.compile('{{#unless foo}}success{{/unless}}', {strict: true});
+      var template = CompilerContext.compile(
+        '{{#unless foo}}success{{/unless}}',
+        { strict: true }
+      );
       equals(template({}), 'success');
     });
 
     it('should allow undefined hash when passed to helpers', function() {
-      var template = CompilerContext.compile('{{helper value=@foo}}', {strict: true});
+      var template = CompilerContext.compile('{{helper value=@foo}}', {
+        strict: true
+      });
       var helpers = {
         helper: function(options) {
           equals('value' in options.hash, true);
@@ -93,19 +144,27 @@ describe('strict', function() {
           return 'success';
         }
       };
-      equals(template({}, {helpers: helpers}), 'success');
+      equals(template({}, { helpers: helpers }), 'success');
     });
 
     it('should show error location on missing property lookup', function() {
-      shouldThrow(function() {
-        var template = CompilerContext.compile('\n\n\n   {{hello}}', {strict: true});
-        template({});
-      }, Exception, '"hello" not defined in [object Object] - 4:5');
+      shouldThrow(
+        function() {
+          var template = CompilerContext.compile('\n\n\n   {{hello}}', {
+            strict: true
+          });
+          template({});
+        },
+        Exception,
+        '"hello" not defined in [object Object] - 4:5'
+      );
     });
 
     it('should error contains correct location properties on missing property lookup', function() {
       try {
-        var template = CompilerContext.compile('\n\n\n   {{hello}}', {strict: true});
+        var template = CompilerContext.compile('\n\n\n   {{hello}}', {
+          strict: true
+        });
         template({});
       } catch (error) {
         equals(error.lineNumber, 4);
@@ -118,25 +177,33 @@ describe('strict', function() {
 
   describe('assume objects', function() {
     it('should ignore missing property', function() {
-      var template = CompilerContext.compile('{{hello}}', {assumeObjects: true});
+      var template = CompilerContext.compile('{{hello}}', {
+        assumeObjects: true
+      });
 
       equal(template({}), '');
     });
     it('should ignore missing child', function() {
-      var template = CompilerContext.compile('{{hello.bar}}', {assumeObjects: true});
+      var template = CompilerContext.compile('{{hello.bar}}', {
+        assumeObjects: true
+      });
 
-      equal(template({hello: {}}), '');
+      equal(template({ hello: {} }), '');
     });
     it('should error on missing object', function() {
       shouldThrow(function() {
-        var template = CompilerContext.compile('{{hello.bar}}', {assumeObjects: true});
+        var template = CompilerContext.compile('{{hello.bar}}', {
+          assumeObjects: true
+        });
 
         template({});
       }, Error);
     });
     it('should error on missing context', function() {
       shouldThrow(function() {
-        var template = CompilerContext.compile('{{hello}}', {assumeObjects: true});
+        var template = CompilerContext.compile('{{hello}}', {
+          assumeObjects: true
+        });
 
         template();
       }, Error);
@@ -144,14 +211,18 @@ describe('strict', function() {
 
     it('should error on missing data lookup', function() {
       shouldThrow(function() {
-        var template = CompilerContext.compile('{{@hello.bar}}', {assumeObjects: true});
+        var template = CompilerContext.compile('{{@hello.bar}}', {
+          assumeObjects: true
+        });
 
         template();
       }, Error);
     });
 
     it('should execute blockHelperMissing', function() {
-      var template = CompilerContext.compile('{{^hello}}foo{{/hello}}', {assumeObjects: true});
+      var template = CompilerContext.compile('{{^hello}}foo{{/hello}}', {
+        assumeObjects: true
+      });
 
       equals(template({}), 'foo');
     });
diff --git a/spec/string-params.js b/spec/string-params.js
index b76f291f7..9f83611a4 100644
--- a/spec/string-params.js
+++ b/spec/string-params.js
@@ -1,6 +1,8 @@
 describe('string params mode', function() {
   it('arguments to helpers can be retrieved from options hash in string form', function() {
-    var template = CompilerContext.compile('{{wycats is.a slave.driver}}', {stringParams: true});
+    var template = CompilerContext.compile('{{wycats is.a slave.driver}}', {
+      stringParams: true
+    });
 
     var helpers = {
       wycats: function(passiveVoice, noun) {
@@ -8,57 +10,99 @@ describe('string params mode', function() {
       }
     };
 
-    var result = template({}, {helpers: helpers});
+    var result = template({}, { helpers: helpers });
 
-    equals(result, 'HELP ME MY BOSS is.a slave.driver', 'String parameters output');
+    equals(
+      result,
+      'HELP ME MY BOSS is.a slave.driver',
+      'String parameters output'
+    );
   });
 
   it('when using block form, arguments to helpers can be retrieved from options hash in string form', function() {
-    var template = CompilerContext.compile('{{#wycats is.a slave.driver}}help :({{/wycats}}', {stringParams: true});
+    var template = CompilerContext.compile(
+      '{{#wycats is.a slave.driver}}help :({{/wycats}}',
+      { stringParams: true }
+    );
 
     var helpers = {
       wycats: function(passiveVoice, noun, options) {
-        return 'HELP ME MY BOSS ' + passiveVoice + ' ' +
-                noun + ': ' + options.fn(this);
+        return (
+          'HELP ME MY BOSS ' +
+          passiveVoice +
+          ' ' +
+          noun +
+          ': ' +
+          options.fn(this)
+        );
       }
     };
 
-    var result = template({}, {helpers: helpers});
+    var result = template({}, { helpers: helpers });
 
-    equals(result, 'HELP ME MY BOSS is.a slave.driver: help :(', 'String parameters output');
+    equals(
+      result,
+      'HELP ME MY BOSS is.a slave.driver: help :(',
+      'String parameters output'
+    );
   });
 
   it('when inside a block in String mode, .. passes the appropriate context in the options hash', function() {
-    var template = CompilerContext.compile('{{#with dale}}{{tomdale ../need dad.joke}}{{/with}}', {stringParams: true});
+    var template = CompilerContext.compile(
+      '{{#with dale}}{{tomdale ../need dad.joke}}{{/with}}',
+      { stringParams: true }
+    );
 
     var helpers = {
       tomdale: function(desire, noun, options) {
-        return 'STOP ME FROM READING HACKER NEWS I ' +
-                options.contexts[0][desire] + ' ' + noun;
+        return (
+          'STOP ME FROM READING HACKER NEWS I ' +
+          options.contexts[0][desire] +
+          ' ' +
+          noun
+        );
       },
 
-      'with': function(context, options) {
+      with: function(context, options) {
         return options.fn(options.contexts[0][context]);
       }
     };
 
-    var result = template({
-      dale: {},
+    var result = template(
+      {
+        dale: {},
 
-      need: 'need-a'
-    }, {helpers: helpers});
-
-    equals(result, 'STOP ME FROM READING HACKER NEWS I need-a dad.joke', 'Proper context variable output');
+        need: 'need-a'
+      },
+      { helpers: helpers }
+    );
+
+    equals(
+      result,
+      'STOP ME FROM READING HACKER NEWS I need-a dad.joke',
+      'Proper context variable output'
+    );
   });
 
   it('information about the types is passed along', function() {
-    var template = CompilerContext.compile("{{tomdale 'need' dad.joke true false}}", { stringParams: true });
+    var template = CompilerContext.compile(
+      "{{tomdale 'need' dad.joke true false}}",
+      { stringParams: true }
+    );
 
     var helpers = {
       tomdale: function(desire, noun, trueBool, falseBool, options) {
         equal(options.types[0], 'StringLiteral', 'the string type is passed');
-        equal(options.types[1], 'PathExpression', 'the expression type is passed');
-        equal(options.types[2], 'BooleanLiteral', 'the expression type is passed');
+        equal(
+          options.types[1],
+          'PathExpression',
+          'the expression type is passed'
+        );
+        equal(
+          options.types[2],
+          'BooleanLiteral',
+          'the expression type is passed'
+        );
         equal(desire, 'need', 'the string form is passed for strings');
         equal(noun, 'dad.joke', 'the string form is passed for expressions');
         equal(trueBool, true, 'raw booleans are passed through');
@@ -72,7 +116,10 @@ describe('string params mode', function() {
   });
 
   it('hash parameters get type information', function() {
-    var template = CompilerContext.compile("{{tomdale he.says desire='need' noun=dad.joke bool=true}}", { stringParams: true });
+    var template = CompilerContext.compile(
+      "{{tomdale he.says desire='need' noun=dad.joke bool=true}}",
+      { stringParams: true }
+    );
 
     var helpers = {
       tomdale: function(exclamation, options) {
@@ -94,9 +141,12 @@ describe('string params mode', function() {
   });
 
   it('hash parameters get context information', function() {
-    var template = CompilerContext.compile("{{#with dale}}{{tomdale he.says desire='need' noun=../dad/joke bool=true}}{{/with}}", { stringParams: true });
+    var template = CompilerContext.compile(
+      "{{#with dale}}{{tomdale he.says desire='need' noun=../dad/joke bool=true}}{{/with}}",
+      { stringParams: true }
+    );
 
-    var context = {dale: {}};
+    var context = { dale: {} };
 
     var helpers = {
       tomdale: function(exclamation, options) {
@@ -110,7 +160,7 @@ describe('string params mode', function() {
         equal(options.hash.bool, true);
         return 'Helper called';
       },
-      'with': function(withContext, options) {
+      with: function(withContext, options) {
         return options.fn(options.contexts[0][withContext]);
       }
     };
@@ -120,34 +170,52 @@ describe('string params mode', function() {
   });
 
   it('when inside a block in String mode, .. passes the appropriate context in the options hash to a block helper', function() {
-    var template = CompilerContext.compile('{{#with dale}}{{#tomdale ../need dad.joke}}wot{{/tomdale}}{{/with}}', {stringParams: true});
+    var template = CompilerContext.compile(
+      '{{#with dale}}{{#tomdale ../need dad.joke}}wot{{/tomdale}}{{/with}}',
+      { stringParams: true }
+    );
 
     var helpers = {
       tomdale: function(desire, noun, options) {
-        return 'STOP ME FROM READING HACKER NEWS I ' +
-                options.contexts[0][desire] + ' ' + noun + ' ' +
-                options.fn(this);
+        return (
+          'STOP ME FROM READING HACKER NEWS I ' +
+          options.contexts[0][desire] +
+          ' ' +
+          noun +
+          ' ' +
+          options.fn(this)
+        );
       },
 
-      'with': function(context, options) {
+      with: function(context, options) {
         return options.fn(options.contexts[0][context]);
       }
     };
 
-    var result = template({
-      dale: {},
+    var result = template(
+      {
+        dale: {},
 
-      need: 'need-a'
-    }, {helpers: helpers});
-
-    equals(result, 'STOP ME FROM READING HACKER NEWS I need-a dad.joke wot', 'Proper context variable output');
+        need: 'need-a'
+      },
+      { helpers: helpers }
+    );
+
+    equals(
+      result,
+      'STOP ME FROM READING HACKER NEWS I need-a dad.joke wot',
+      'Proper context variable output'
+    );
   });
 
   it('with nested block ambiguous', function() {
-    var template = CompilerContext.compile('{{#with content}}{{#view}}{{firstName}} {{lastName}}{{/view}}{{/with}}', {stringParams: true});
+    var template = CompilerContext.compile(
+      '{{#with content}}{{#view}}{{firstName}} {{lastName}}{{/view}}{{/with}}',
+      { stringParams: true }
+    );
 
     var helpers = {
-      'with': function() {
+      with: function() {
         return 'WITH';
       },
       view: function() {
@@ -155,12 +223,14 @@ describe('string params mode', function() {
       }
     };
 
-    var result = template({}, {helpers: helpers});
+    var result = template({}, { helpers: helpers });
     equals(result, 'WITH');
   });
 
   it('should handle DATA', function() {
-    var template = CompilerContext.compile('{{foo @bar}}', { stringParams: true });
+    var template = CompilerContext.compile('{{foo @bar}}', {
+      stringParams: true
+    });
 
     var helpers = {
       foo: function(bar, options) {
diff --git a/spec/subexpressions.js b/spec/subexpressions.js
index dad741e4a..228510511 100644
--- a/spec/subexpressions.js
+++ b/spec/subexpressions.js
@@ -31,7 +31,7 @@ describe('subexpressions', function() {
   it('mixed paths and helpers', function() {
     var string = '{{blog baz.bat (equal a b) baz.bar}}';
 
-    var context = { bar: 'LOL', baz: {bat: 'foo!', bar: 'bar!'} };
+    var context = { bar: 'LOL', baz: { bat: 'foo!', bar: 'bar!' } };
     var helpers = {
       blog: function(val, that, theOther) {
         return 'val is ' + val + ', ' + that + ' and ' + theOther;
@@ -59,7 +59,7 @@ describe('subexpressions', function() {
   });
 
   it('GH-800 : Complex subexpressions', function() {
-    var context = {a: 'a', b: 'b', c: {c: 'c'}, d: 'd', e: {e: 'e'}};
+    var context = { a: 'a', b: 'b', c: { c: 'c' }, d: 'd', e: { e: 'e' } };
     var helpers = {
       dash: function(a, b) {
         return a + '-' + b;
@@ -69,7 +69,11 @@ describe('subexpressions', function() {
       }
     };
 
-    shouldCompileTo("{{dash 'abc' (concat a b)}}", [context, helpers], 'abc-ab');
+    shouldCompileTo(
+      "{{dash 'abc' (concat a b)}}",
+      [context, helpers],
+      'abc-ab'
+    );
     shouldCompileTo('{{dash d (concat a b)}}', [context, helpers], 'd-ab');
     shouldCompileTo('{{dash c.c (concat a b)}}', [context, helpers], 'c-ab');
     shouldCompileTo('{{dash (concat a b) c.c}}', [context, helpers], 'ab-c');
@@ -122,24 +126,36 @@ describe('subexpressions', function() {
   });
 
   it('multiple subexpressions in a hash', function() {
-    var string = '{{input aria-label=(t "Name") placeholder=(t "Example User")}}';
+    var string =
+      '{{input aria-label=(t "Name") placeholder=(t "Example User")}}';
 
     var helpers = {
       input: function(options) {
         var hash = options.hash;
         var ariaLabel = Handlebars.Utils.escapeExpression(hash['aria-label']);
         var placeholder = Handlebars.Utils.escapeExpression(hash.placeholder);
-        return new Handlebars.SafeString('<input aria-label="' + ariaLabel + '" placeholder="' + placeholder + '" />');
+        return new Handlebars.SafeString(
+          '<input aria-label="' +
+            ariaLabel +
+            '" placeholder="' +
+            placeholder +
+            '" />'
+        );
       },
       t: function(defaultString) {
         return new Handlebars.SafeString(defaultString);
       }
     };
-    shouldCompileTo(string, [{}, helpers], '<input aria-label="Name" placeholder="Example User" />');
+    shouldCompileTo(
+      string,
+      [{}, helpers],
+      '<input aria-label="Name" placeholder="Example User" />'
+    );
   });
 
   it('multiple subexpressions in a hash with context', function() {
-    var string = '{{input aria-label=(t item.field) placeholder=(t item.placeholder)}}';
+    var string =
+      '{{input aria-label=(t item.field) placeholder=(t item.placeholder)}}';
 
     var context = {
       item: {
@@ -153,44 +169,82 @@ describe('subexpressions', function() {
         var hash = options.hash;
         var ariaLabel = Handlebars.Utils.escapeExpression(hash['aria-label']);
         var placeholder = Handlebars.Utils.escapeExpression(hash.placeholder);
-        return new Handlebars.SafeString('<input aria-label="' + ariaLabel + '" placeholder="' + placeholder + '" />');
+        return new Handlebars.SafeString(
+          '<input aria-label="' +
+            ariaLabel +
+            '" placeholder="' +
+            placeholder +
+            '" />'
+        );
       },
       t: function(defaultString) {
         return new Handlebars.SafeString(defaultString);
       }
     };
-    shouldCompileTo(string, [context, helpers], '<input aria-label="Name" placeholder="Example User" />');
+    shouldCompileTo(
+      string,
+      [context, helpers],
+      '<input aria-label="Name" placeholder="Example User" />'
+    );
   });
 
   it('in string params mode,', function() {
-    var template = CompilerContext.compile('{{snog (blorg foo x=y) yeah a=b}}', {stringParams: true});
+    var template = CompilerContext.compile(
+      '{{snog (blorg foo x=y) yeah a=b}}',
+      { stringParams: true }
+    );
 
     var helpers = {
       snog: function(a, b, options) {
         equals(a, 'foo');
-        equals(options.types.length, 2, 'string params for outer helper processed correctly');
-        equals(options.types[0], 'SubExpression', 'string params for outer helper processed correctly');
-        equals(options.types[1], 'PathExpression', 'string params for outer helper processed correctly');
+        equals(
+          options.types.length,
+          2,
+          'string params for outer helper processed correctly'
+        );
+        equals(
+          options.types[0],
+          'SubExpression',
+          'string params for outer helper processed correctly'
+        );
+        equals(
+          options.types[1],
+          'PathExpression',
+          'string params for outer helper processed correctly'
+        );
         return a + b;
       },
 
       blorg: function(a, options) {
-        equals(options.types.length, 1, 'string params for inner helper processed correctly');
-        equals(options.types[0], 'PathExpression', 'string params for inner helper processed correctly');
+        equals(
+          options.types.length,
+          1,
+          'string params for inner helper processed correctly'
+        );
+        equals(
+          options.types[0],
+          'PathExpression',
+          'string params for inner helper processed correctly'
+        );
         return a;
       }
     };
 
-    var result = template({
-      foo: {},
-      yeah: {}
-    }, {helpers: helpers});
+    var result = template(
+      {
+        foo: {},
+        yeah: {}
+      },
+      { helpers: helpers }
+    );
 
     equals(result, 'fooyeah');
   });
 
   it('as hashes in string params mode', function() {
-    var template = CompilerContext.compile('{{blog fun=(bork)}}', {stringParams: true});
+    var template = CompilerContext.compile('{{blog fun=(bork)}}', {
+      stringParams: true
+    });
 
     var helpers = {
       blog: function(options) {
@@ -202,7 +256,7 @@ describe('subexpressions', function() {
       }
     };
 
-    var result = template({}, {helpers: helpers});
+    var result = template({}, { helpers: helpers });
     equals(result, 'val is BORK');
   });
 
diff --git a/spec/tokenizer.js b/spec/tokenizer.js
index ec15d597f..ed1666038 100644
--- a/spec/tokenizer.js
+++ b/spec/tokenizer.js
@@ -15,18 +15,18 @@ describe('Tokenizer', function() {
 
   function tokenize(template) {
     var parser = Handlebars.Parser,
-        lexer = parser.lexer;
+      lexer = parser.lexer;
 
     lexer.setInput(template);
     var out = [],
-        token;
+      token;
 
     while ((token = lexer.lex())) {
       var result = parser.terminals_[token] || token;
       if (!result || result === 'EOF' || result === 'INVALID') {
         break;
       }
-      out.push({name: result, text: lexer.yytext});
+      out.push({ name: result, text: lexer.yytext });
     }
 
     return out;
@@ -55,7 +55,16 @@ describe('Tokenizer', function() {
 
   it('supports escaping delimiters', function() {
     var result = tokenize('{{foo}} \\{{bar}} {{baz}}');
-    shouldMatchTokens(result, ['OPEN', 'ID', 'CLOSE', 'CONTENT', 'CONTENT', 'OPEN', 'ID', 'CLOSE']);
+    shouldMatchTokens(result, [
+      'OPEN',
+      'ID',
+      'CLOSE',
+      'CONTENT',
+      'CONTENT',
+      'OPEN',
+      'ID',
+      'CLOSE'
+    ]);
 
     shouldBeToken(result[3], 'CONTENT', ' ');
     shouldBeToken(result[4], 'CONTENT', '{{bar}} ');
@@ -63,7 +72,14 @@ describe('Tokenizer', function() {
 
   it('supports escaping multiple delimiters', function() {
     var result = tokenize('{{foo}} \\{{bar}} \\{{baz}}');
-    shouldMatchTokens(result, ['OPEN', 'ID', 'CLOSE', 'CONTENT', 'CONTENT', 'CONTENT']);
+    shouldMatchTokens(result, [
+      'OPEN',
+      'ID',
+      'CLOSE',
+      'CONTENT',
+      'CONTENT',
+      'CONTENT'
+    ]);
 
     shouldBeToken(result[3], 'CONTENT', ' ');
     shouldBeToken(result[4], 'CONTENT', '{{bar}} ');
@@ -72,14 +88,35 @@ describe('Tokenizer', function() {
 
   it('supports escaping a triple stash', function() {
     var result = tokenize('{{foo}} \\{{{bar}}} {{baz}}');
-    shouldMatchTokens(result, ['OPEN', 'ID', 'CLOSE', 'CONTENT', 'CONTENT', 'OPEN', 'ID', 'CLOSE']);
+    shouldMatchTokens(result, [
+      'OPEN',
+      'ID',
+      'CLOSE',
+      'CONTENT',
+      'CONTENT',
+      'OPEN',
+      'ID',
+      'CLOSE'
+    ]);
 
     shouldBeToken(result[4], 'CONTENT', '{{{bar}}} ');
   });
 
   it('supports escaping escape character', function() {
     var result = tokenize('{{foo}} \\\\{{bar}} {{baz}}');
-    shouldMatchTokens(result, ['OPEN', 'ID', 'CLOSE', 'CONTENT', 'OPEN', 'ID', 'CLOSE', 'CONTENT', 'OPEN', 'ID', 'CLOSE']);
+    shouldMatchTokens(result, [
+      'OPEN',
+      'ID',
+      'CLOSE',
+      'CONTENT',
+      'OPEN',
+      'ID',
+      'CLOSE',
+      'CONTENT',
+      'OPEN',
+      'ID',
+      'CLOSE'
+    ]);
 
     shouldBeToken(result[3], 'CONTENT', ' \\');
     shouldBeToken(result[5], 'ID', 'bar');
@@ -87,7 +124,19 @@ describe('Tokenizer', function() {
 
   it('supports escaping multiple escape characters', function() {
     var result = tokenize('{{foo}} \\\\{{bar}} \\\\{{baz}}');
-    shouldMatchTokens(result, ['OPEN', 'ID', 'CLOSE', 'CONTENT', 'OPEN', 'ID', 'CLOSE', 'CONTENT', 'OPEN', 'ID', 'CLOSE']);
+    shouldMatchTokens(result, [
+      'OPEN',
+      'ID',
+      'CLOSE',
+      'CONTENT',
+      'OPEN',
+      'ID',
+      'CLOSE',
+      'CONTENT',
+      'OPEN',
+      'ID',
+      'CLOSE'
+    ]);
 
     shouldBeToken(result[3], 'CONTENT', ' \\');
     shouldBeToken(result[5], 'ID', 'bar');
@@ -97,7 +146,18 @@ describe('Tokenizer', function() {
 
   it('supports escaped mustaches after escaped escape characters', function() {
     var result = tokenize('{{foo}} \\\\{{bar}} \\{{baz}}');
-    shouldMatchTokens(result, ['OPEN', 'ID', 'CLOSE', 'CONTENT', 'OPEN', 'ID', 'CLOSE', 'CONTENT', 'CONTENT', 'CONTENT']);
+    shouldMatchTokens(result, [
+      'OPEN',
+      'ID',
+      'CLOSE',
+      'CONTENT',
+      'OPEN',
+      'ID',
+      'CLOSE',
+      'CONTENT',
+      'CONTENT',
+      'CONTENT'
+    ]);
 
     shouldBeToken(result[3], 'CONTENT', ' \\');
     shouldBeToken(result[4], 'OPEN', '{{');
@@ -108,7 +168,17 @@ describe('Tokenizer', function() {
 
   it('supports escaped escape characters after escaped mustaches', function() {
     var result = tokenize('{{foo}} \\{{bar}} \\\\{{baz}}');
-    shouldMatchTokens(result, ['OPEN', 'ID', 'CLOSE', 'CONTENT', 'CONTENT', 'CONTENT', 'OPEN', 'ID', 'CLOSE']);
+    shouldMatchTokens(result, [
+      'OPEN',
+      'ID',
+      'CLOSE',
+      'CONTENT',
+      'CONTENT',
+      'CONTENT',
+      'OPEN',
+      'ID',
+      'CLOSE'
+    ]);
 
     shouldBeToken(result[4], 'CONTENT', '{{bar}} ');
     shouldBeToken(result[5], 'CONTENT', '\\');
@@ -118,7 +188,19 @@ describe('Tokenizer', function() {
 
   it('supports escaped escape character on a triple stash', function() {
     var result = tokenize('{{foo}} \\\\{{{bar}}} {{baz}}');
-    shouldMatchTokens(result, ['OPEN', 'ID', 'CLOSE', 'CONTENT', 'OPEN_UNESCAPED', 'ID', 'CLOSE_UNESCAPED', 'CONTENT', 'OPEN', 'ID', 'CLOSE']);
+    shouldMatchTokens(result, [
+      'OPEN',
+      'ID',
+      'CLOSE',
+      'CONTENT',
+      'OPEN_UNESCAPED',
+      'ID',
+      'CLOSE_UNESCAPED',
+      'CONTENT',
+      'OPEN',
+      'ID',
+      'CLOSE'
+    ]);
 
     shouldBeToken(result[3], 'CONTENT', ' \\');
     shouldBeToken(result[5], 'ID', 'bar');
@@ -133,7 +215,15 @@ describe('Tokenizer', function() {
     var result = tokenize('{{foo.bar}}');
     shouldMatchTokens(result, ['OPEN', 'ID', 'SEP', 'ID', 'CLOSE']);
 
-    shouldMatchTokens(tokenize('{{foo.bar.baz}}'), ['OPEN', 'ID', 'SEP', 'ID', 'SEP', 'ID', 'CLOSE']);
+    shouldMatchTokens(tokenize('{{foo.bar.baz}}'), [
+      'OPEN',
+      'ID',
+      'SEP',
+      'ID',
+      'SEP',
+      'ID',
+      'CLOSE'
+    ]);
   });
 
   it('allows path literals with []', function() {
@@ -143,7 +233,18 @@ describe('Tokenizer', function() {
 
   it('allows multiple path literals on a line with []', function() {
     var result = tokenize('{{foo.[bar]}}{{foo.[baz]}}');
-    shouldMatchTokens(result, ['OPEN', 'ID', 'SEP', 'ID', 'CLOSE', 'OPEN', 'ID', 'SEP', 'ID', 'CLOSE']);
+    shouldMatchTokens(result, [
+      'OPEN',
+      'ID',
+      'SEP',
+      'ID',
+      'CLOSE',
+      'OPEN',
+      'ID',
+      'SEP',
+      'ID',
+      'CLOSE'
+    ]);
   });
 
   it('allows escaped literals in []', function() {
@@ -158,13 +259,29 @@ describe('Tokenizer', function() {
 
   it('tokenizes a path as "OPEN (ID SEP)* ID CLOSE"', function() {
     var result = tokenize('{{../foo/bar}}');
-    shouldMatchTokens(result, ['OPEN', 'ID', 'SEP', 'ID', 'SEP', 'ID', 'CLOSE']);
+    shouldMatchTokens(result, [
+      'OPEN',
+      'ID',
+      'SEP',
+      'ID',
+      'SEP',
+      'ID',
+      'CLOSE'
+    ]);
     shouldBeToken(result[1], 'ID', '..');
   });
 
   it('tokenizes a path with .. as a parent path', function() {
     var result = tokenize('{{../foo.bar}}');
-    shouldMatchTokens(result, ['OPEN', 'ID', 'SEP', 'ID', 'SEP', 'ID', 'CLOSE']);
+    shouldMatchTokens(result, [
+      'OPEN',
+      'ID',
+      'SEP',
+      'ID',
+      'SEP',
+      'ID',
+      'CLOSE'
+    ]);
     shouldBeToken(result[1], 'ID', '..');
   });
 
@@ -216,7 +333,15 @@ describe('Tokenizer', function() {
 
   it('tokenizes a partial space at the }); as "OPEN_PARTIAL ID CLOSE"', function() {
     var result = tokenize('{{>foo/bar.baz  }}');
-    shouldMatchTokens(result, ['OPEN_PARTIAL', 'ID', 'SEP', 'ID', 'SEP', 'ID', 'CLOSE']);
+    shouldMatchTokens(result, [
+      'OPEN_PARTIAL',
+      'ID',
+      'SEP',
+      'ID',
+      'SEP',
+      'ID',
+      'CLOSE'
+    ]);
   });
 
   it('tokenizes partial block declarations', function() {
@@ -225,34 +350,69 @@ describe('Tokenizer', function() {
   });
   it('tokenizes a comment as "COMMENT"', function() {
     var result = tokenize('foo {{! this is a comment }} bar {{ baz }}');
-    shouldMatchTokens(result, ['CONTENT', 'COMMENT', 'CONTENT', 'OPEN', 'ID', 'CLOSE']);
+    shouldMatchTokens(result, [
+      'CONTENT',
+      'COMMENT',
+      'CONTENT',
+      'OPEN',
+      'ID',
+      'CLOSE'
+    ]);
     shouldBeToken(result[1], 'COMMENT', '{{! this is a comment }}');
   });
 
   it('tokenizes a block comment as "COMMENT"', function() {
     var result = tokenize('foo {{!-- this is a {{comment}} --}} bar {{ baz }}');
-    shouldMatchTokens(result, ['CONTENT', 'COMMENT', 'CONTENT', 'OPEN', 'ID', 'CLOSE']);
+    shouldMatchTokens(result, [
+      'CONTENT',
+      'COMMENT',
+      'CONTENT',
+      'OPEN',
+      'ID',
+      'CLOSE'
+    ]);
     shouldBeToken(result[1], 'COMMENT', '{{!-- this is a {{comment}} --}}');
   });
 
   it('tokenizes a block comment with whitespace as "COMMENT"', function() {
-    var result = tokenize('foo {{!-- this is a\n{{comment}}\n--}} bar {{ baz }}');
-    shouldMatchTokens(result, ['CONTENT', 'COMMENT', 'CONTENT', 'OPEN', 'ID', 'CLOSE']);
+    var result = tokenize(
+      'foo {{!-- this is a\n{{comment}}\n--}} bar {{ baz }}'
+    );
+    shouldMatchTokens(result, [
+      'CONTENT',
+      'COMMENT',
+      'CONTENT',
+      'OPEN',
+      'ID',
+      'CLOSE'
+    ]);
     shouldBeToken(result[1], 'COMMENT', '{{!-- this is a\n{{comment}}\n--}}');
   });
 
   it('tokenizes open and closing blocks as OPEN_BLOCK, ID, CLOSE ..., OPEN_ENDBLOCK ID CLOSE', function() {
     var result = tokenize('{{#foo}}content{{/foo}}');
-    shouldMatchTokens(result, ['OPEN_BLOCK', 'ID', 'CLOSE', 'CONTENT', 'OPEN_ENDBLOCK', 'ID', 'CLOSE']);
+    shouldMatchTokens(result, [
+      'OPEN_BLOCK',
+      'ID',
+      'CLOSE',
+      'CONTENT',
+      'OPEN_ENDBLOCK',
+      'ID',
+      'CLOSE'
+    ]);
   });
 
   it('tokenizes directives', function() {
-    shouldMatchTokens(
-        tokenize('{{#*foo}}content{{/foo}}'),
-        ['OPEN_BLOCK', 'ID', 'CLOSE', 'CONTENT', 'OPEN_ENDBLOCK', 'ID', 'CLOSE']);
-    shouldMatchTokens(
-        tokenize('{{*foo}}'),
-        ['OPEN', 'ID', 'CLOSE']);
+    shouldMatchTokens(tokenize('{{#*foo}}content{{/foo}}'), [
+      'OPEN_BLOCK',
+      'ID',
+      'CLOSE',
+      'CONTENT',
+      'OPEN_ENDBLOCK',
+      'ID',
+      'CLOSE'
+    ]);
+    shouldMatchTokens(tokenize('{{*foo}}'), ['OPEN', 'ID', 'CLOSE']);
   });
 
   it('tokenizes inverse sections as "INVERSE"', function() {
@@ -351,28 +511,98 @@ describe('Tokenizer', function() {
     shouldMatchTokens(result, ['OPEN', 'ID', 'ID', 'EQUALS', 'ID', 'CLOSE']);
 
     result = tokenize('{{ foo bar baz=bat }}');
-    shouldMatchTokens(result, ['OPEN', 'ID', 'ID', 'ID', 'EQUALS', 'ID', 'CLOSE']);
+    shouldMatchTokens(result, [
+      'OPEN',
+      'ID',
+      'ID',
+      'ID',
+      'EQUALS',
+      'ID',
+      'CLOSE'
+    ]);
 
     result = tokenize('{{ foo bar baz=1 }}');
-    shouldMatchTokens(result, ['OPEN', 'ID', 'ID', 'ID', 'EQUALS', 'NUMBER', 'CLOSE']);
+    shouldMatchTokens(result, [
+      'OPEN',
+      'ID',
+      'ID',
+      'ID',
+      'EQUALS',
+      'NUMBER',
+      'CLOSE'
+    ]);
 
     result = tokenize('{{ foo bar baz=true }}');
-    shouldMatchTokens(result, ['OPEN', 'ID', 'ID', 'ID', 'EQUALS', 'BOOLEAN', 'CLOSE']);
+    shouldMatchTokens(result, [
+      'OPEN',
+      'ID',
+      'ID',
+      'ID',
+      'EQUALS',
+      'BOOLEAN',
+      'CLOSE'
+    ]);
 
     result = tokenize('{{ foo bar baz=false }}');
-    shouldMatchTokens(result, ['OPEN', 'ID', 'ID', 'ID', 'EQUALS', 'BOOLEAN', 'CLOSE']);
+    shouldMatchTokens(result, [
+      'OPEN',
+      'ID',
+      'ID',
+      'ID',
+      'EQUALS',
+      'BOOLEAN',
+      'CLOSE'
+    ]);
 
     result = tokenize('{{ foo bar\n  baz=bat }}');
-    shouldMatchTokens(result, ['OPEN', 'ID', 'ID', 'ID', 'EQUALS', 'ID', 'CLOSE']);
+    shouldMatchTokens(result, [
+      'OPEN',
+      'ID',
+      'ID',
+      'ID',
+      'EQUALS',
+      'ID',
+      'CLOSE'
+    ]);
 
     result = tokenize('{{ foo bar baz="bat" }}');
-    shouldMatchTokens(result, ['OPEN', 'ID', 'ID', 'ID', 'EQUALS', 'STRING', 'CLOSE']);
+    shouldMatchTokens(result, [
+      'OPEN',
+      'ID',
+      'ID',
+      'ID',
+      'EQUALS',
+      'STRING',
+      'CLOSE'
+    ]);
 
     result = tokenize('{{ foo bar baz="bat" bam=wot }}');
-    shouldMatchTokens(result, ['OPEN', 'ID', 'ID', 'ID', 'EQUALS', 'STRING', 'ID', 'EQUALS', 'ID', 'CLOSE']);
+    shouldMatchTokens(result, [
+      'OPEN',
+      'ID',
+      'ID',
+      'ID',
+      'EQUALS',
+      'STRING',
+      'ID',
+      'EQUALS',
+      'ID',
+      'CLOSE'
+    ]);
 
     result = tokenize('{{foo omg bar=baz bat="bam"}}');
-    shouldMatchTokens(result, ['OPEN', 'ID', 'ID', 'ID', 'EQUALS', 'ID', 'ID', 'EQUALS', 'STRING', 'CLOSE']);
+    shouldMatchTokens(result, [
+      'OPEN',
+      'ID',
+      'ID',
+      'ID',
+      'EQUALS',
+      'ID',
+      'ID',
+      'EQUALS',
+      'STRING',
+      'CLOSE'
+    ]);
     shouldBeToken(result[2], 'ID', 'omg');
   });
 
@@ -386,7 +616,15 @@ describe('Tokenizer', function() {
     shouldBeToken(result[3], 'ID', 'bar');
 
     result = tokenize('{{ foo bar=@baz }}');
-    shouldMatchTokens(result, ['OPEN', 'ID', 'ID', 'EQUALS', 'DATA', 'ID', 'CLOSE']);
+    shouldMatchTokens(result, [
+      'OPEN',
+      'ID',
+      'ID',
+      'EQUALS',
+      'DATA',
+      'ID',
+      'CLOSE'
+    ]);
     shouldBeToken(result[5], 'ID', 'baz');
   });
 
@@ -400,12 +638,27 @@ describe('Tokenizer', function() {
 
   it('tokenizes subexpressions', function() {
     var result = tokenize('{{foo (bar)}}');
-    shouldMatchTokens(result, ['OPEN', 'ID', 'OPEN_SEXPR', 'ID', 'CLOSE_SEXPR', 'CLOSE']);
+    shouldMatchTokens(result, [
+      'OPEN',
+      'ID',
+      'OPEN_SEXPR',
+      'ID',
+      'CLOSE_SEXPR',
+      'CLOSE'
+    ]);
     shouldBeToken(result[1], 'ID', 'foo');
     shouldBeToken(result[3], 'ID', 'bar');
 
     result = tokenize('{{foo (a-x b-y)}}');
-    shouldMatchTokens(result, ['OPEN', 'ID', 'OPEN_SEXPR', 'ID', 'ID', 'CLOSE_SEXPR', 'CLOSE']);
+    shouldMatchTokens(result, [
+      'OPEN',
+      'ID',
+      'OPEN_SEXPR',
+      'ID',
+      'ID',
+      'CLOSE_SEXPR',
+      'CLOSE'
+    ]);
     shouldBeToken(result[1], 'ID', 'foo');
     shouldBeToken(result[3], 'ID', 'a-x');
     shouldBeToken(result[4], 'ID', 'b-y');
@@ -413,7 +666,21 @@ describe('Tokenizer', function() {
 
   it('tokenizes nested subexpressions', function() {
     var result = tokenize('{{foo (bar (lol rofl)) (baz)}}');
-    shouldMatchTokens(result, ['OPEN', 'ID', 'OPEN_SEXPR', 'ID', 'OPEN_SEXPR', 'ID', 'ID', 'CLOSE_SEXPR', 'CLOSE_SEXPR', 'OPEN_SEXPR', 'ID', 'CLOSE_SEXPR', 'CLOSE']);
+    shouldMatchTokens(result, [
+      'OPEN',
+      'ID',
+      'OPEN_SEXPR',
+      'ID',
+      'OPEN_SEXPR',
+      'ID',
+      'ID',
+      'CLOSE_SEXPR',
+      'CLOSE_SEXPR',
+      'OPEN_SEXPR',
+      'ID',
+      'CLOSE_SEXPR',
+      'CLOSE'
+    ]);
     shouldBeToken(result[3], 'ID', 'bar');
     shouldBeToken(result[5], 'ID', 'lol');
     shouldBeToken(result[6], 'ID', 'rofl');
@@ -421,29 +688,109 @@ describe('Tokenizer', function() {
   });
 
   it('tokenizes nested subexpressions: literals', function() {
-    var result = tokenize("{{foo (bar (lol true) false) (baz 1) (blah 'b') (blorg \"c\")}}");
-    shouldMatchTokens(result, ['OPEN', 'ID', 'OPEN_SEXPR', 'ID', 'OPEN_SEXPR', 'ID', 'BOOLEAN', 'CLOSE_SEXPR', 'BOOLEAN', 'CLOSE_SEXPR', 'OPEN_SEXPR', 'ID', 'NUMBER', 'CLOSE_SEXPR', 'OPEN_SEXPR', 'ID', 'STRING', 'CLOSE_SEXPR', 'OPEN_SEXPR', 'ID', 'STRING', 'CLOSE_SEXPR', 'CLOSE']);
+    var result = tokenize(
+      '{{foo (bar (lol true) false) (baz 1) (blah \'b\') (blorg "c")}}'
+    );
+    shouldMatchTokens(result, [
+      'OPEN',
+      'ID',
+      'OPEN_SEXPR',
+      'ID',
+      'OPEN_SEXPR',
+      'ID',
+      'BOOLEAN',
+      'CLOSE_SEXPR',
+      'BOOLEAN',
+      'CLOSE_SEXPR',
+      'OPEN_SEXPR',
+      'ID',
+      'NUMBER',
+      'CLOSE_SEXPR',
+      'OPEN_SEXPR',
+      'ID',
+      'STRING',
+      'CLOSE_SEXPR',
+      'OPEN_SEXPR',
+      'ID',
+      'STRING',
+      'CLOSE_SEXPR',
+      'CLOSE'
+    ]);
   });
 
   it('tokenizes block params', function() {
     var result = tokenize('{{#foo as |bar|}}');
-    shouldMatchTokens(result, ['OPEN_BLOCK', 'ID', 'OPEN_BLOCK_PARAMS', 'ID', 'CLOSE_BLOCK_PARAMS', 'CLOSE']);
+    shouldMatchTokens(result, [
+      'OPEN_BLOCK',
+      'ID',
+      'OPEN_BLOCK_PARAMS',
+      'ID',
+      'CLOSE_BLOCK_PARAMS',
+      'CLOSE'
+    ]);
 
     result = tokenize('{{#foo as |bar baz|}}');
-    shouldMatchTokens(result, ['OPEN_BLOCK', 'ID', 'OPEN_BLOCK_PARAMS', 'ID', 'ID', 'CLOSE_BLOCK_PARAMS', 'CLOSE']);
+    shouldMatchTokens(result, [
+      'OPEN_BLOCK',
+      'ID',
+      'OPEN_BLOCK_PARAMS',
+      'ID',
+      'ID',
+      'CLOSE_BLOCK_PARAMS',
+      'CLOSE'
+    ]);
 
     result = tokenize('{{#foo as | bar baz |}}');
-    shouldMatchTokens(result, ['OPEN_BLOCK', 'ID', 'OPEN_BLOCK_PARAMS', 'ID', 'ID', 'CLOSE_BLOCK_PARAMS', 'CLOSE']);
+    shouldMatchTokens(result, [
+      'OPEN_BLOCK',
+      'ID',
+      'OPEN_BLOCK_PARAMS',
+      'ID',
+      'ID',
+      'CLOSE_BLOCK_PARAMS',
+      'CLOSE'
+    ]);
 
     result = tokenize('{{#foo as as | bar baz |}}');
-    shouldMatchTokens(result, ['OPEN_BLOCK', 'ID', 'ID', 'OPEN_BLOCK_PARAMS', 'ID', 'ID', 'CLOSE_BLOCK_PARAMS', 'CLOSE']);
+    shouldMatchTokens(result, [
+      'OPEN_BLOCK',
+      'ID',
+      'ID',
+      'OPEN_BLOCK_PARAMS',
+      'ID',
+      'ID',
+      'CLOSE_BLOCK_PARAMS',
+      'CLOSE'
+    ]);
 
     result = tokenize('{{else foo as |bar baz|}}');
-    shouldMatchTokens(result, ['OPEN_INVERSE_CHAIN', 'ID', 'OPEN_BLOCK_PARAMS', 'ID', 'ID', 'CLOSE_BLOCK_PARAMS', 'CLOSE']);
+    shouldMatchTokens(result, [
+      'OPEN_INVERSE_CHAIN',
+      'ID',
+      'OPEN_BLOCK_PARAMS',
+      'ID',
+      'ID',
+      'CLOSE_BLOCK_PARAMS',
+      'CLOSE'
+    ]);
   });
 
   it('tokenizes raw blocks', function() {
-    var result = tokenize('{{{{a}}}} abc {{{{/a}}}} aaa {{{{a}}}} abc {{{{/a}}}}');
-    shouldMatchTokens(result, ['OPEN_RAW_BLOCK', 'ID', 'CLOSE_RAW_BLOCK', 'CONTENT', 'END_RAW_BLOCK', 'CONTENT', 'OPEN_RAW_BLOCK', 'ID', 'CLOSE_RAW_BLOCK', 'CONTENT', 'END_RAW_BLOCK']);
+    var result = tokenize(
+      '{{{{a}}}} abc {{{{/a}}}} aaa {{{{a}}}} abc {{{{/a}}}}'
+    );
+    shouldMatchTokens(result, [
+      'OPEN_RAW_BLOCK',
+      'ID',
+      'CLOSE_RAW_BLOCK',
+      'CONTENT',
+      'END_RAW_BLOCK',
+      'CONTENT',
+      'OPEN_RAW_BLOCK',
+      'ID',
+      'CLOSE_RAW_BLOCK',
+      'CONTENT',
+      'END_RAW_BLOCK'
+    ]);
   });
 });
diff --git a/spec/track-ids.js b/spec/track-ids.js
index 30a46617d..f7ad7abda 100644
--- a/spec/track-ids.js
+++ b/spec/track-ids.js
@@ -1,7 +1,7 @@
 describe('track ids', function() {
   var context;
   beforeEach(function() {
-    context = {is: {a: 'foo'}, slave: {driver: 'bar'}};
+    context = { is: { a: 'foo' }, slave: { driver: 'bar' } };
   });
 
   it('should not include anything without the flag', function() {
@@ -16,38 +16,70 @@ describe('track ids', function() {
       }
     };
 
-    equals(template({}, {helpers: helpers}), 'success');
+    equals(template({}, { helpers: helpers }), 'success');
   });
   it('should include argument ids', function() {
-    var template = CompilerContext.compile('{{wycats is.a slave.driver}}', {trackIds: true});
+    var template = CompilerContext.compile('{{wycats is.a slave.driver}}', {
+      trackIds: true
+    });
 
     var helpers = {
       wycats: function(passiveVoice, noun, options) {
         equal(options.ids[0], 'is.a');
         equal(options.ids[1], 'slave.driver');
 
-        return 'HELP ME MY BOSS ' + options.ids[0] + ':' + passiveVoice + ' ' + options.ids[1] + ':' + noun;
+        return (
+          'HELP ME MY BOSS ' +
+          options.ids[0] +
+          ':' +
+          passiveVoice +
+          ' ' +
+          options.ids[1] +
+          ':' +
+          noun
+        );
       }
     };
 
-    equals(template(context, {helpers: helpers}), 'HELP ME MY BOSS is.a:foo slave.driver:bar');
+    equals(
+      template(context, { helpers: helpers }),
+      'HELP ME MY BOSS is.a:foo slave.driver:bar'
+    );
   });
   it('should include hash ids', function() {
-    var template = CompilerContext.compile('{{wycats bat=is.a baz=slave.driver}}', {trackIds: true});
+    var template = CompilerContext.compile(
+      '{{wycats bat=is.a baz=slave.driver}}',
+      { trackIds: true }
+    );
 
     var helpers = {
       wycats: function(options) {
         equal(options.hashIds.bat, 'is.a');
         equal(options.hashIds.baz, 'slave.driver');
 
-        return 'HELP ME MY BOSS ' + options.hashIds.bat + ':' + options.hash.bat + ' ' + options.hashIds.baz + ':' + options.hash.baz;
+        return (
+          'HELP ME MY BOSS ' +
+          options.hashIds.bat +
+          ':' +
+          options.hash.bat +
+          ' ' +
+          options.hashIds.baz +
+          ':' +
+          options.hash.baz
+        );
       }
     };
 
-    equals(template(context, {helpers: helpers}), 'HELP ME MY BOSS is.a:foo slave.driver:bar');
+    equals(
+      template(context, { helpers: helpers }),
+      'HELP ME MY BOSS is.a:foo slave.driver:bar'
+    );
   });
   it('should note ../ and ./ references', function() {
-    var template = CompilerContext.compile('{{wycats ./is.a ../slave.driver this.is.a this}}', {trackIds: true});
+    var template = CompilerContext.compile(
+      '{{wycats ./is.a ../slave.driver this.is.a this}}',
+      { trackIds: true }
+    );
 
     var helpers = {
       wycats: function(passiveVoice, noun, thiz, thiz2, options) {
@@ -56,29 +88,57 @@ describe('track ids', function() {
         equal(options.ids[2], 'is.a');
         equal(options.ids[3], '');
 
-        return 'HELP ME MY BOSS ' + options.ids[0] + ':' + passiveVoice + ' ' + options.ids[1] + ':' + noun;
+        return (
+          'HELP ME MY BOSS ' +
+          options.ids[0] +
+          ':' +
+          passiveVoice +
+          ' ' +
+          options.ids[1] +
+          ':' +
+          noun
+        );
       }
     };
 
-    equals(template(context, {helpers: helpers}), 'HELP ME MY BOSS is.a:foo ../slave.driver:undefined');
+    equals(
+      template(context, { helpers: helpers }),
+      'HELP ME MY BOSS is.a:foo ../slave.driver:undefined'
+    );
   });
   it('should note @data references', function() {
-    var template = CompilerContext.compile('{{wycats @is.a @slave.driver}}', {trackIds: true});
+    var template = CompilerContext.compile('{{wycats @is.a @slave.driver}}', {
+      trackIds: true
+    });
 
     var helpers = {
       wycats: function(passiveVoice, noun, options) {
         equal(options.ids[0], '@is.a');
         equal(options.ids[1], '@slave.driver');
 
-        return 'HELP ME MY BOSS ' + options.ids[0] + ':' + passiveVoice + ' ' + options.ids[1] + ':' + noun;
+        return (
+          'HELP ME MY BOSS ' +
+          options.ids[0] +
+          ':' +
+          passiveVoice +
+          ' ' +
+          options.ids[1] +
+          ':' +
+          noun
+        );
       }
     };
 
-    equals(template({}, {helpers: helpers, data: context}), 'HELP ME MY BOSS @is.a:foo @slave.driver:bar');
+    equals(
+      template({}, { helpers: helpers, data: context }),
+      'HELP ME MY BOSS @is.a:foo @slave.driver:bar'
+    );
   });
 
   it('should return null for constants', function() {
-    var template = CompilerContext.compile('{{wycats 1 "foo" key=false}}', {trackIds: true});
+    var template = CompilerContext.compile('{{wycats 1 "foo" key=false}}', {
+      trackIds: true
+    });
 
     var helpers = {
       wycats: function(passiveVoice, noun, options) {
@@ -86,17 +146,31 @@ describe('track ids', function() {
         equal(options.ids[1], null);
         equal(options.hashIds.key, null);
 
-        return 'HELP ME MY BOSS ' + passiveVoice + ' ' + noun + ' ' + options.hash.key;
+        return (
+          'HELP ME MY BOSS ' +
+          passiveVoice +
+          ' ' +
+          noun +
+          ' ' +
+          options.hash.key
+        );
       }
     };
 
-    equals(template(context, {helpers: helpers}), 'HELP ME MY BOSS 1 foo false');
+    equals(
+      template(context, { helpers: helpers }),
+      'HELP ME MY BOSS 1 foo false'
+    );
   });
   it('should return true for subexpressions', function() {
-    var template = CompilerContext.compile('{{wycats (sub)}}', {trackIds: true});
+    var template = CompilerContext.compile('{{wycats (sub)}}', {
+      trackIds: true
+    });
 
     var helpers = {
-      sub: function() { return 1; },
+      sub: function() {
+        return 1;
+      },
       wycats: function(passiveVoice, options) {
         equal(options.ids[0], true);
 
@@ -104,28 +178,43 @@ describe('track ids', function() {
       }
     };
 
-    equals(template(context, {helpers: helpers}), 'HELP ME MY BOSS 1');
+    equals(template(context, { helpers: helpers }), 'HELP ME MY BOSS 1');
   });
 
   it('should use block param paths', function() {
-    var template = CompilerContext.compile('{{#doIt as |is|}}{{wycats is.a slave.driver is}}{{/doIt}}', {trackIds: true});
+    var template = CompilerContext.compile(
+      '{{#doIt as |is|}}{{wycats is.a slave.driver is}}{{/doIt}}',
+      { trackIds: true }
+    );
 
     var helpers = {
       doIt: function(options) {
         var blockParams = [this.is];
         blockParams.path = ['zomg'];
-        return options.fn(this, {blockParams: blockParams});
+        return options.fn(this, { blockParams: blockParams });
       },
       wycats: function(passiveVoice, noun, blah, options) {
         equal(options.ids[0], 'zomg.a');
         equal(options.ids[1], 'slave.driver');
         equal(options.ids[2], 'zomg');
 
-        return 'HELP ME MY BOSS ' + options.ids[0] + ':' + passiveVoice + ' ' + options.ids[1] + ':' + noun;
+        return (
+          'HELP ME MY BOSS ' +
+          options.ids[0] +
+          ':' +
+          passiveVoice +
+          ' ' +
+          options.ids[1] +
+          ':' +
+          noun
+        );
       }
     };
 
-    equals(template(context, {helpers: helpers}), 'HELP ME MY BOSS zomg.a:foo slave.driver:bar');
+    equals(
+      template(context, { helpers: helpers }),
+      'HELP ME MY BOSS zomg.a:foo slave.driver:bar'
+    );
   });
 
   describe('builtin helpers', function() {
@@ -140,53 +229,119 @@ describe('track ids', function() {
 
     describe('#each', function() {
       it('should track contextPath for arrays', function() {
-        var template = CompilerContext.compile('{{#each array}}{{wycats name}}{{/each}}', {trackIds: true});
-
-        equals(template({array: [{name: 'foo'}, {name: 'bar'}]}, {helpers: helpers}), 'foo:array.0\nbar:array.1\n');
+        var template = CompilerContext.compile(
+          '{{#each array}}{{wycats name}}{{/each}}',
+          { trackIds: true }
+        );
+
+        equals(
+          template(
+            { array: [{ name: 'foo' }, { name: 'bar' }] },
+            { helpers: helpers }
+          ),
+          'foo:array.0\nbar:array.1\n'
+        );
       });
       it('should track contextPath for keys', function() {
-        var template = CompilerContext.compile('{{#each object}}{{wycats name}}{{/each}}', {trackIds: true});
-
-        equals(template({object: {foo: {name: 'foo'}, bar: {name: 'bar'}}}, {helpers: helpers}), 'foo:object.foo\nbar:object.bar\n');
+        var template = CompilerContext.compile(
+          '{{#each object}}{{wycats name}}{{/each}}',
+          { trackIds: true }
+        );
+
+        equals(
+          template(
+            { object: { foo: { name: 'foo' }, bar: { name: 'bar' } } },
+            { helpers: helpers }
+          ),
+          'foo:object.foo\nbar:object.bar\n'
+        );
       });
       it('should handle nesting', function() {
-        var template = CompilerContext.compile('{{#each .}}{{#each .}}{{wycats name}}{{/each}}{{/each}}', {trackIds: true});
-
-        equals(template({array: [{name: 'foo'}, {name: 'bar'}]}, {helpers: helpers}), 'foo:.array..0\nbar:.array..1\n');
+        var template = CompilerContext.compile(
+          '{{#each .}}{{#each .}}{{wycats name}}{{/each}}{{/each}}',
+          { trackIds: true }
+        );
+
+        equals(
+          template(
+            { array: [{ name: 'foo' }, { name: 'bar' }] },
+            { helpers: helpers }
+          ),
+          'foo:.array..0\nbar:.array..1\n'
+        );
       });
       it('should handle block params', function() {
-        var template = CompilerContext.compile('{{#each array as |value|}}{{blockParams value.name}}{{/each}}', {trackIds: true});
-
-        equals(template({array: [{name: 'foo'}, {name: 'bar'}]}, {helpers: helpers}), 'foo:array.0.name\nbar:array.1.name\n');
+        var template = CompilerContext.compile(
+          '{{#each array as |value|}}{{blockParams value.name}}{{/each}}',
+          { trackIds: true }
+        );
+
+        equals(
+          template(
+            { array: [{ name: 'foo' }, { name: 'bar' }] },
+            { helpers: helpers }
+          ),
+          'foo:array.0.name\nbar:array.1.name\n'
+        );
       });
     });
     describe('#with', function() {
       it('should track contextPath', function() {
-        var template = CompilerContext.compile('{{#with field}}{{wycats name}}{{/with}}', {trackIds: true});
-
-        equals(template({field: {name: 'foo'}}, {helpers: helpers}), 'foo:field\n');
+        var template = CompilerContext.compile(
+          '{{#with field}}{{wycats name}}{{/with}}',
+          { trackIds: true }
+        );
+
+        equals(
+          template({ field: { name: 'foo' } }, { helpers: helpers }),
+          'foo:field\n'
+        );
       });
       it('should handle nesting', function() {
-        var template = CompilerContext.compile('{{#with bat}}{{#with field}}{{wycats name}}{{/with}}{{/with}}', {trackIds: true});
-
-        equals(template({bat: {field: {name: 'foo'}}}, {helpers: helpers}), 'foo:bat.field\n');
+        var template = CompilerContext.compile(
+          '{{#with bat}}{{#with field}}{{wycats name}}{{/with}}{{/with}}',
+          { trackIds: true }
+        );
+
+        equals(
+          template({ bat: { field: { name: 'foo' } } }, { helpers: helpers }),
+          'foo:bat.field\n'
+        );
       });
     });
     describe('#blockHelperMissing', function() {
       it('should track contextPath for arrays', function() {
-        var template = CompilerContext.compile('{{#field}}{{wycats name}}{{/field}}', {trackIds: true});
-
-        equals(template({field: [{name: 'foo'}]}, {helpers: helpers}), 'foo:field.0\n');
+        var template = CompilerContext.compile(
+          '{{#field}}{{wycats name}}{{/field}}',
+          { trackIds: true }
+        );
+
+        equals(
+          template({ field: [{ name: 'foo' }] }, { helpers: helpers }),
+          'foo:field.0\n'
+        );
       });
       it('should track contextPath for keys', function() {
-        var template = CompilerContext.compile('{{#field}}{{wycats name}}{{/field}}', {trackIds: true});
-
-        equals(template({field: {name: 'foo'}}, {helpers: helpers}), 'foo:field\n');
+        var template = CompilerContext.compile(
+          '{{#field}}{{wycats name}}{{/field}}',
+          { trackIds: true }
+        );
+
+        equals(
+          template({ field: { name: 'foo' } }, { helpers: helpers }),
+          'foo:field\n'
+        );
       });
       it('should handle nesting', function() {
-        var template = CompilerContext.compile('{{#bat}}{{#field}}{{wycats name}}{{/field}}{{/bat}}', {trackIds: true});
-
-        equals(template({bat: {field: {name: 'foo'}}}, {helpers: helpers}), 'foo:bat.field\n');
+        var template = CompilerContext.compile(
+          '{{#bat}}{{#field}}{{wycats name}}{{/field}}{{/bat}}',
+          { trackIds: true }
+        );
+
+        equals(
+          template({ bat: { field: { name: 'foo' } } }, { helpers: helpers }),
+          'foo:bat.field\n'
+        );
       });
     });
   });
@@ -202,36 +357,71 @@ describe('track ids', function() {
     };
 
     it('should pass track id for basic partial', function() {
-      var template = CompilerContext.compile('Dudes: {{#dudes}}{{> dude}}{{/dudes}}', {trackIds: true}),
-          hash = {dudes: [{name: 'Yehuda', url: 'http://yehuda'}, {name: 'Alan', url: 'http://alan'}]};
+      var template = CompilerContext.compile(
+          'Dudes: {{#dudes}}{{> dude}}{{/dudes}}',
+          { trackIds: true }
+        ),
+        hash = {
+          dudes: [
+            { name: 'Yehuda', url: 'http://yehuda' },
+            { name: 'Alan', url: 'http://alan' }
+          ]
+        };
 
       var partials = {
-        dude: CompilerContext.compile('{{wycats name}}', {trackIds: true})
+        dude: CompilerContext.compile('{{wycats name}}', { trackIds: true })
       };
 
-      equals(template(hash, {helpers: helpers, partials: partials}), 'Dudes: Yehuda:dudes.0\nAlan:dudes.1\n');
+      equals(
+        template(hash, { helpers: helpers, partials: partials }),
+        'Dudes: Yehuda:dudes.0\nAlan:dudes.1\n'
+      );
     });
 
     it('should pass track id for context partial', function() {
-      var template = CompilerContext.compile('Dudes: {{> dude dudes}}', {trackIds: true}),
-          hash = {dudes: [{name: 'Yehuda', url: 'http://yehuda'}, {name: 'Alan', url: 'http://alan'}]};
+      var template = CompilerContext.compile('Dudes: {{> dude dudes}}', {
+          trackIds: true
+        }),
+        hash = {
+          dudes: [
+            { name: 'Yehuda', url: 'http://yehuda' },
+            { name: 'Alan', url: 'http://alan' }
+          ]
+        };
 
       var partials = {
-        dude: CompilerContext.compile('{{#each this}}{{wycats name}}{{/each}}', {trackIds: true})
+        dude: CompilerContext.compile(
+          '{{#each this}}{{wycats name}}{{/each}}',
+          { trackIds: true }
+        )
       };
 
-      equals(template(hash, {helpers: helpers, partials: partials}), 'Dudes: Yehuda:dudes..0\nAlan:dudes..1\n');
+      equals(
+        template(hash, { helpers: helpers, partials: partials }),
+        'Dudes: Yehuda:dudes..0\nAlan:dudes..1\n'
+      );
     });
 
     it('should invalidate context for partials with parameters', function() {
-      var template = CompilerContext.compile('Dudes: {{#dudes}}{{> dude . bar="foo"}}{{/dudes}}', {trackIds: true}),
-          hash = {dudes: [{name: 'Yehuda', url: 'http://yehuda'}, {name: 'Alan', url: 'http://alan'}]};
+      var template = CompilerContext.compile(
+          'Dudes: {{#dudes}}{{> dude . bar="foo"}}{{/dudes}}',
+          { trackIds: true }
+        ),
+        hash = {
+          dudes: [
+            { name: 'Yehuda', url: 'http://yehuda' },
+            { name: 'Alan', url: 'http://alan' }
+          ]
+        };
 
       var partials = {
-        dude: CompilerContext.compile('{{wycats name}}', {trackIds: true})
+        dude: CompilerContext.compile('{{wycats name}}', { trackIds: true })
       };
 
-      equals(template(hash, {helpers: helpers, partials: partials}), 'Dudes: Yehuda:true\nAlan:true\n');
+      equals(
+        template(hash, { helpers: helpers, partials: partials }),
+        'Dudes: Yehuda:true\nAlan:true\n'
+      );
     });
   });
 });
diff --git a/spec/utils.js b/spec/utils.js
index 7248ac447..667aa0ed3 100644
--- a/spec/utils.js
+++ b/spec/utils.js
@@ -5,19 +5,30 @@ describe('utils', function() {
       if (!(safe instanceof Handlebars.SafeString)) {
         throw new Error('Must be instance of SafeString');
       }
-      equals(safe.toString(), 'testing 1, 2, 3', 'SafeString is equivalent to its underlying string');
+      equals(
+        safe.toString(),
+        'testing 1, 2, 3',
+        'SafeString is equivalent to its underlying string'
+      );
     });
 
     it('it should not escape SafeString properties', function() {
       var name = new Handlebars.SafeString('<em>Sean O&#x27;Malley</em>');
 
-      shouldCompileTo('{{name}}', [{name: name}], '<em>Sean O&#x27;Malley</em>');
+      shouldCompileTo(
+        '{{name}}',
+        [{ name: name }],
+        '<em>Sean O&#x27;Malley</em>'
+      );
     });
   });
 
   describe('#escapeExpression', function() {
     it('shouhld escape html', function() {
-      equals(Handlebars.Utils.escapeExpression('foo<&"\'>'), 'foo&lt;&amp;&quot;&#x27;&gt;');
+      equals(
+        Handlebars.Utils.escapeExpression('foo<&"\'>'),
+        'foo&lt;&amp;&quot;&#x27;&gt;'
+      );
       equals(Handlebars.Utils.escapeExpression('foo='), 'foo&#x3D;');
     });
     it('should not escape SafeString', function() {
@@ -58,7 +69,7 @@ describe('utils', function() {
       equals(Handlebars.Utils.isEmpty(0), false);
       equals(Handlebars.Utils.isEmpty([1]), false);
       equals(Handlebars.Utils.isEmpty('foo'), false);
-      equals(Handlebars.Utils.isEmpty({bar: 1}), false);
+      equals(Handlebars.Utils.isEmpty({ bar: 1 }), false);
     });
   });
 
@@ -69,7 +80,7 @@ describe('utils', function() {
       }
       A.prototype.b = 4;
 
-      var b = {b: 2};
+      var b = { b: 2 };
 
       Handlebars.Utils.extend(b, new A());
 
diff --git a/spec/visitor.js b/spec/visitor.js
index d3fb795e2..2bec356fe 100644
--- a/spec/visitor.js
+++ b/spec/visitor.js
@@ -7,7 +7,11 @@ describe('Visitor', function() {
     // Simply run the thing and make sure it does not fail and that all of the
     // stub methods are executed
     var visitor = new Handlebars.Visitor();
-    visitor.accept(Handlebars.parse('{{foo}}{{#foo (bar 1 "1" true undefined null) foo=@data}}{{!comment}}{{> bar }} {{/foo}}'));
+    visitor.accept(
+      Handlebars.parse(
+        '{{foo}}{{#foo (bar 1 "1" true undefined null) foo=@data}}{{!comment}}{{> bar }} {{/foo}}'
+      )
+    );
     visitor.accept(Handlebars.parse('{{#> bar }} {{/bar}}'));
     visitor.accept(Handlebars.parse('{{#* bar }} {{/bar}}'));
     visitor.accept(Handlebars.parse('{{* bar }}'));
@@ -40,7 +44,11 @@ describe('Visitor', function() {
       equal(comment.value, 'comment');
     };
 
-    visitor.accept(Handlebars.parse('{{#foo.bar (foo.bar 1 "2" true) foo=@foo.bar}}{{!comment}}{{> bar }} {{/foo.bar}}'));
+    visitor.accept(
+      Handlebars.parse(
+        '{{#foo.bar (foo.bar 1 "2" true) foo=@foo.bar}}{{!comment}}{{> bar }} {{/foo.bar}}'
+      )
+    );
   });
 
   describe('mutating', function() {
@@ -50,12 +58,15 @@ describe('Visitor', function() {
 
         visitor.mutating = true;
         visitor.StringLiteral = function(string) {
-          return {type: 'NumberLiteral', value: 42, loc: string.loc};
+          return { type: 'NumberLiteral', value: 42, loc: string.loc };
         };
 
         var ast = Handlebars.parse('{{foo foo="foo"}}');
         visitor.accept(ast);
-        equals(Handlebars.print(ast), '{{ PATH:foo [] HASH{foo=NUMBER{42}} }}\n');
+        equals(
+          Handlebars.print(ast),
+          '{{ PATH:foo [] HASH{foo=NUMBER{42}} }}\n'
+        );
       });
       it('should treat undefined resonse as identity', function() {
         var visitor = new Handlebars.Visitor();
@@ -63,7 +74,10 @@ describe('Visitor', function() {
 
         var ast = Handlebars.parse('{{foo foo=42}}');
         visitor.accept(ast);
-        equals(Handlebars.print(ast), '{{ PATH:foo [] HASH{foo=NUMBER{42}} }}\n');
+        equals(
+          Handlebars.print(ast),
+          '{{ PATH:foo [] HASH{foo=NUMBER{42}} }}\n'
+        );
       });
       it('should remove false responses', function() {
         var visitor = new Handlebars.Visitor();
@@ -78,30 +92,38 @@ describe('Visitor', function() {
         equals(Handlebars.print(ast), '{{ PATH:foo [] }}\n');
       });
       it('should throw when removing required values', function() {
-        shouldThrow(function() {
-          var visitor = new Handlebars.Visitor();
-
-          visitor.mutating = true;
-          visitor.PathExpression = function() {
-            return false;
-          };
-
-          var ast = Handlebars.parse('{{foo 42}}');
-          visitor.accept(ast);
-        }, Handlebars.Exception, 'MustacheStatement requires path');
+        shouldThrow(
+          function() {
+            var visitor = new Handlebars.Visitor();
+
+            visitor.mutating = true;
+            visitor.PathExpression = function() {
+              return false;
+            };
+
+            var ast = Handlebars.parse('{{foo 42}}');
+            visitor.accept(ast);
+          },
+          Handlebars.Exception,
+          'MustacheStatement requires path'
+        );
       });
       it('should throw when returning non-node responses', function() {
-        shouldThrow(function() {
-          var visitor = new Handlebars.Visitor();
-
-          visitor.mutating = true;
-          visitor.PathExpression = function() {
-            return {};
-          };
-
-          var ast = Handlebars.parse('{{foo 42}}');
-          visitor.accept(ast);
-        }, Handlebars.Exception, 'Unexpected node type "undefined" found when accepting path on MustacheStatement');
+        shouldThrow(
+          function() {
+            var visitor = new Handlebars.Visitor();
+
+            visitor.mutating = true;
+            visitor.PathExpression = function() {
+              return {};
+            };
+
+            var ast = Handlebars.parse('{{foo 42}}');
+            visitor.accept(ast);
+          },
+          Handlebars.Exception,
+          'Unexpected node type "undefined" found when accepting path on MustacheStatement'
+        );
       });
     });
     describe('arrays', function() {
@@ -110,7 +132,7 @@ describe('Visitor', function() {
 
         visitor.mutating = true;
         visitor.StringLiteral = function(string) {
-          return {type: 'NumberLiteral', value: 42, loc: string.locInfo};
+          return { type: 'NumberLiteral', value: 42, loc: string.locInfo };
         };
 
         var ast = Handlebars.parse('{{foo "foo"}}');
diff --git a/spec/whitespace-control.js b/spec/whitespace-control.js
index a5c9bf14d..b1a6db045 100644
--- a/spec/whitespace-control.js
+++ b/spec/whitespace-control.js
@@ -1,6 +1,6 @@
 describe('whitespace control', function() {
   it('should strip whitespace around mustache calls', function() {
-    var hash = {foo: 'bar<'};
+    var hash = { foo: 'bar<' };
 
     shouldCompileTo(' {{~foo~}} ', hash, 'bar&lt;');
     shouldCompileTo(' {{~foo}} ', hash, 'bar&lt; ');
@@ -14,15 +14,23 @@ describe('whitespace control', function() {
 
   describe('blocks', function() {
     it('should strip whitespace around simple block calls', function() {
-      var hash = {foo: 'bar<'};
+      var hash = { foo: 'bar<' };
 
       shouldCompileTo(' {{~#if foo~}} bar {{~/if~}} ', hash, 'bar');
       shouldCompileTo(' {{#if foo~}} bar {{/if~}} ', hash, ' bar ');
       shouldCompileTo(' {{~#if foo}} bar {{~/if}} ', hash, ' bar ');
       shouldCompileTo(' {{#if foo}} bar {{/if}} ', hash, '  bar  ');
 
-      shouldCompileTo(' \n\n{{~#if foo~}} \n\nbar \n\n{{~/if~}}\n\n ', hash, 'bar');
-      shouldCompileTo(' a\n\n{{~#if foo~}} \n\nbar \n\n{{~/if~}}\n\na ', hash, ' abara ');
+      shouldCompileTo(
+        ' \n\n{{~#if foo~}} \n\nbar \n\n{{~/if~}}\n\n ',
+        hash,
+        'bar'
+      );
+      shouldCompileTo(
+        ' a\n\n{{~#if foo~}} \n\nbar \n\n{{~/if~}}\n\na ',
+        hash,
+        ' abara '
+      );
     });
     it('should strip whitespace around inverse block calls', function() {
       var hash = {};
@@ -32,10 +40,14 @@ describe('whitespace control', function() {
       shouldCompileTo(' {{~^if foo}} bar {{~/if}} ', hash, ' bar ');
       shouldCompileTo(' {{^if foo}} bar {{/if}} ', hash, '  bar  ');
 
-      shouldCompileTo(' \n\n{{~^if foo~}} \n\nbar \n\n{{~/if~}}\n\n ', hash, 'bar');
+      shouldCompileTo(
+        ' \n\n{{~^if foo~}} \n\nbar \n\n{{~/if~}}\n\n ',
+        hash,
+        'bar'
+      );
     });
     it('should strip whitespace around complex block calls', function() {
-      var hash = {foo: 'bar<'};
+      var hash = { foo: 'bar<' };
 
       shouldCompileTo('{{#if foo~}} bar {{~^~}} baz {{~/if}}', hash, 'bar');
       shouldCompileTo('{{#if foo~}} bar {{^~}} baz {{/if}}', hash, 'bar ');
@@ -44,8 +56,16 @@ describe('whitespace control', function() {
 
       shouldCompileTo('{{#if foo~}} bar {{~else~}} baz {{~/if}}', hash, 'bar');
 
-      shouldCompileTo('\n\n{{~#if foo~}} \n\nbar \n\n{{~^~}} \n\nbaz \n\n{{~/if~}}\n\n', hash, 'bar');
-      shouldCompileTo('\n\n{{~#if foo~}} \n\n{{{foo}}} \n\n{{~^~}} \n\nbaz \n\n{{~/if~}}\n\n', hash, 'bar<');
+      shouldCompileTo(
+        '\n\n{{~#if foo~}} \n\nbar \n\n{{~^~}} \n\nbaz \n\n{{~/if~}}\n\n',
+        hash,
+        'bar'
+      );
+      shouldCompileTo(
+        '\n\n{{~#if foo~}} \n\n{{{foo}}} \n\n{{~^~}} \n\nbaz \n\n{{~/if~}}\n\n',
+        hash,
+        'bar<'
+      );
 
       hash = {};
 
@@ -56,21 +76,50 @@ describe('whitespace control', function() {
 
       shouldCompileTo('{{#if foo~}} bar {{~else~}} baz {{~/if}}', hash, 'baz');
 
-      shouldCompileTo('\n\n{{~#if foo~}} \n\nbar \n\n{{~^~}} \n\nbaz \n\n{{~/if~}}\n\n', hash, 'baz');
+      shouldCompileTo(
+        '\n\n{{~#if foo~}} \n\nbar \n\n{{~^~}} \n\nbaz \n\n{{~/if~}}\n\n',
+        hash,
+        'baz'
+      );
     });
   });
 
   it('should strip whitespace around partials', function() {
-    shouldCompileToWithPartials('foo {{~> dude~}} ', [{}, {}, {dude: 'bar'}], true, 'foobar');
-    shouldCompileToWithPartials('foo {{> dude~}} ', [{}, {}, {dude: 'bar'}], true, 'foo bar');
-    shouldCompileToWithPartials('foo {{> dude}} ', [{}, {}, {dude: 'bar'}], true, 'foo bar ');
-
-    shouldCompileToWithPartials('foo\n {{~> dude}} ', [{}, {}, {dude: 'bar'}], true, 'foobar');
-    shouldCompileToWithPartials('foo\n {{> dude}} ', [{}, {}, {dude: 'bar'}], true, 'foo\n bar');
+    shouldCompileToWithPartials(
+      'foo {{~> dude~}} ',
+      [{}, {}, { dude: 'bar' }],
+      true,
+      'foobar'
+    );
+    shouldCompileToWithPartials(
+      'foo {{> dude~}} ',
+      [{}, {}, { dude: 'bar' }],
+      true,
+      'foo bar'
+    );
+    shouldCompileToWithPartials(
+      'foo {{> dude}} ',
+      [{}, {}, { dude: 'bar' }],
+      true,
+      'foo bar '
+    );
+
+    shouldCompileToWithPartials(
+      'foo\n {{~> dude}} ',
+      [{}, {}, { dude: 'bar' }],
+      true,
+      'foobar'
+    );
+    shouldCompileToWithPartials(
+      'foo\n {{> dude}} ',
+      [{}, {}, { dude: 'bar' }],
+      true,
+      'foo\n bar'
+    );
   });
 
   it('should only strip whitespace once', function() {
-    var hash = {foo: 'bar'};
+    var hash = { foo: 'bar' };
 
     shouldCompileTo(' {{~foo~}} {{foo}} {{foo}} ', hash, 'barbar bar ');
   });
diff --git a/tasks/metrics.js b/tasks/metrics.js
index a1fa5c95a..f903ceb7b 100644
--- a/tasks/metrics.js
+++ b/tasks/metrics.js
@@ -1,14 +1,16 @@
 var _ = require('underscore'),
-    async = require('neo-async'),
-    metrics = require('../bench');
+  async = require('neo-async'),
+  metrics = require('../bench');
 
 module.exports = function(grunt) {
   grunt.registerTask('metrics', function() {
     var done = this.async(),
-        execName = grunt.option('name'),
-        events = {};
+      execName = grunt.option('name'),
+      events = {};
 
-    async.each(_.keys(metrics), function(name, complete) {
+    async.each(
+      _.keys(metrics),
+      function(name, complete) {
         if (/^_/.test(name) || (execName && name !== execName)) {
           return complete();
         }
@@ -18,6 +20,7 @@ module.exports = function(grunt) {
           complete();
         });
       },
-      done);
+      done
+    );
   });
 };
diff --git a/tasks/parser.js b/tasks/parser.js
index 7ff725850..0adba111d 100644
--- a/tasks/parser.js
+++ b/tasks/parser.js
@@ -7,10 +7,14 @@ module.exports = function(grunt) {
     var cmd = './node_modules/.bin/jison';
 
     if (process.platform === 'win32') {
-        cmd = 'node_modules\\.bin\\jison.cmd';
+      cmd = 'node_modules\\.bin\\jison.cmd';
     }
 
-    var child = childProcess.spawn(cmd, ['-m', 'js', 'src/handlebars.yy', 'src/handlebars.l'], {stdio: 'inherit'});
+    var child = childProcess.spawn(
+      cmd,
+      ['-m', 'js', 'src/handlebars.yy', 'src/handlebars.l'],
+      { stdio: 'inherit' }
+    );
     child.on('exit', function(code) {
       if (code != 0) {
         grunt.fatal('Jison failure: ' + code);
@@ -18,7 +22,13 @@ module.exports = function(grunt) {
         return;
       }
 
-      var src = ['src/parser-prefix.js', 'handlebars.js', 'src/parser-suffix.js'].map(grunt.file.read).join('');
+      var src = [
+        'src/parser-prefix.js',
+        'handlebars.js',
+        'src/parser-suffix.js'
+      ]
+        .map(grunt.file.read)
+        .join('');
       grunt.file.delete('handlebars.js');
 
       grunt.file.write('lib/handlebars/compiler/parser.js', src);
diff --git a/tasks/publish.js b/tasks/publish.js
index c3729596b..b22c9b8ea 100644
--- a/tasks/publish.js
+++ b/tasks/publish.js
@@ -1,8 +1,8 @@
 var _ = require('underscore'),
-    async = require('neo-async'),
-    AWS = require('aws-sdk'),
-    git = require('./util/git'),
-    semver = require('semver');
+  async = require('neo-async'),
+  AWS = require('aws-sdk'),
+  git = require('./util/git'),
+  semver = require('semver');
 
 module.exports = function(grunt) {
   grunt.registerTask('publish:latest', function() {
@@ -53,21 +53,27 @@ module.exports = function(grunt) {
 
   function initSDK() {
     var bucket = process.env.S3_BUCKET_NAME,
-        key = process.env.S3_ACCESS_KEY_ID,
-        secret = process.env.S3_SECRET_ACCESS_KEY;
+      key = process.env.S3_ACCESS_KEY_ID,
+      secret = process.env.S3_SECRET_ACCESS_KEY;
 
     if (!bucket || !key || !secret) {
       throw new Error('Missing S3 config values');
     }
 
-    AWS.config.update({accessKeyId: key, secretAccessKey: secret});
+    AWS.config.update({ accessKeyId: key, secretAccessKey: secret });
   }
   function publish(files, callback) {
     var s3 = new AWS.S3(),
-        bucket = process.env.S3_BUCKET_NAME;
+      bucket = process.env.S3_BUCKET_NAME;
 
-    async.each(_.keys(files), function(file, callback) {
-        var params = {Bucket: bucket, Key: file, Body: grunt.file.read(files[file])};
+    async.each(
+      _.keys(files),
+      function(file, callback) {
+        var params = {
+          Bucket: bucket,
+          Key: file,
+          Body: grunt.file.read(files[file])
+        };
         s3.putObject(params, function(err) {
           if (err) {
             throw err;
@@ -77,15 +83,24 @@ module.exports = function(grunt) {
           }
         });
       },
-      callback);
+      callback
+    );
   }
   function fileMap(suffixes) {
     var map = {};
-    _.each(['handlebars.js', 'handlebars.min.js', 'handlebars.runtime.js', 'handlebars.runtime.min.js'], function(file) {
-      _.each(suffixes, function(suffix) {
-        map[file.replace(/\.js$/, suffix + '.js')] = 'dist/' + file;
-      });
-    });
+    _.each(
+      [
+        'handlebars.js',
+        'handlebars.min.js',
+        'handlebars.runtime.js',
+        'handlebars.runtime.min.js'
+      ],
+      function(file) {
+        _.each(suffixes, function(suffix) {
+          map[file.replace(/\.js$/, suffix + '.js')] = 'dist/' + file;
+        });
+      }
+    );
     return map;
   }
 };
diff --git a/tasks/test.js b/tasks/test.js
index a17fc2a22..94fc8c25a 100644
--- a/tasks/test.js
+++ b/tasks/test.js
@@ -1,13 +1,13 @@
 var childProcess = require('child_process'),
-    fs = require('fs'),
-    os = require('os');
+  fs = require('fs'),
+  os = require('os');
 
 module.exports = function(grunt) {
   grunt.registerTask('test:bin', function() {
     var done = this.async();
 
     var cmd = './bin/handlebars';
-    var args = [ '-a', 'spec/artifacts/empty.handlebars' ];
+    var args = ['-a', 'spec/artifacts/empty.handlebars'];
 
     // On Windows, the executable handlebars.js file cannot be run directly
     if (os.platform() === 'win32') {
@@ -19,10 +19,19 @@ module.exports = function(grunt) {
         throw err;
       }
 
-      var expected = fs.readFileSync('./spec/expected/empty.amd.js').toString().replace(/\r\n/g, '\n');
+      var expected = fs
+        .readFileSync('./spec/expected/empty.amd.js')
+        .toString()
+        .replace(/\r\n/g, '\n');
 
       if (stdout.toString() !== expected) {
-        throw new Error('Expected binary output differed:\n\n"' + stdout + '"\n\n"' + expected + '"');
+        throw new Error(
+          'Expected binary output differed:\n\n"' +
+            stdout +
+            '"\n\n"' +
+            expected +
+            '"'
+        );
       }
 
       done();
@@ -31,7 +40,9 @@ module.exports = function(grunt) {
   grunt.registerTask('test:mocha', function() {
     var done = this.async();
 
-    var runner = childProcess.fork('./spec/env/runner', [], {stdio: 'inherit'});
+    var runner = childProcess.fork('./spec/env/runner', [], {
+      stdio: 'inherit'
+    });
     runner.on('close', function(code) {
       if (code !== 0) {
         grunt.fatal(code + ' tests failed');
@@ -42,7 +53,11 @@ module.exports = function(grunt) {
   grunt.registerTask('test:cov', function() {
     var done = this.async();
 
-    var runner = childProcess.fork('node_modules/istanbul/lib/cli.js', ['cover', '--source-map', '--', './spec/env/runner.js'], {stdio: 'inherit'});
+    var runner = childProcess.fork(
+      'node_modules/istanbul/lib/cli.js',
+      ['cover', '--source-map', '--', './spec/env/runner.js'],
+      { stdio: 'inherit' }
+    );
     runner.on('close', function(code) {
       if (code != 0) {
         grunt.fatal(code + ' tests failed');
@@ -53,7 +68,9 @@ module.exports = function(grunt) {
   grunt.registerTask('test:min', function() {
     var done = this.async();
 
-    var runner = childProcess.fork('./spec/env/runner', ['--min'], {stdio: 'inherit'});
+    var runner = childProcess.fork('./spec/env/runner', ['--min'], {
+      stdio: 'inherit'
+    });
     runner.on('close', function(code) {
       if (code !== 0) {
         grunt.fatal(code + ' tests failed');
@@ -65,7 +82,20 @@ module.exports = function(grunt) {
   grunt.registerTask('test:check-cov', function() {
     var done = this.async();
 
-    var runner = childProcess.fork('node_modules/istanbul/lib/cli.js', ['check-coverage', '--statements', '100', '--functions', '100', '--branches', '100', '--lines 100'], {stdio: 'inherit'});
+    var runner = childProcess.fork(
+      'node_modules/istanbul/lib/cli.js',
+      [
+        'check-coverage',
+        '--statements',
+        '100',
+        '--functions',
+        '100',
+        '--branches',
+        '100',
+        '--lines 100'
+      ],
+      { stdio: 'inherit' }
+    );
     runner.on('close', function(code) {
       if (code != 0) {
         grunt.fatal('Coverage check failed: ' + code);
diff --git a/tasks/util/git.js b/tasks/util/git.js
index 03802630d..5418bf03d 100644
--- a/tasks/util/git.js
+++ b/tasks/util/git.js
@@ -17,7 +17,10 @@ module.exports = {
     });
   },
   clean: function(callback) {
-    childProcess.exec('git diff-index --name-only HEAD --', {}, function(err, stdout) {
+    childProcess.exec('git diff-index --name-only HEAD --', {}, function(
+      err,
+      stdout
+    ) {
       callback(undefined, !err && !stdout);
     });
   },
@@ -47,10 +50,13 @@ module.exports = {
     });
   },
   master: function(callback) {
-    childProcess.exec('git rev-parse --short origin/master', {}, function(err, stdout) {
+    childProcess.exec('git rev-parse --short origin/master', {}, function(
+      err,
+      stdout
+    ) {
       // This will error if master was not checked out but in this case we know we are not master
       // so we can ignore.
-      if (err && !(/Needed a single revision/.test(err.message))) {
+      if (err && !/Needed a single revision/.test(err.message)) {
         throw new Error('git.master: ' + err.message);
       }
 
@@ -77,7 +83,9 @@ module.exports = {
     });
   },
   tag: function(name, callback) {
-    childProcess.exec('git tag -a --message=' + name + ' ' + name, {}, function(err) {
+    childProcess.exec('git tag -a --message=' + name + ' ' + name, {}, function(
+      err
+    ) {
       if (err) {
         throw new Error('git.tag: ' + err.message);
       }
@@ -98,7 +106,7 @@ module.exports = {
       });
 
       var versionTags = tags.filter(function(info) {
-        return (/^v/.test(info[0]));
+        return /^v/.test(info[0]);
       });
 
       callback(undefined, versionTags[0] || tags[0]);
diff --git a/tasks/version.js b/tasks/version.js
index 05f703419..05c05fa01 100644
--- a/tasks/version.js
+++ b/tasks/version.js
@@ -1,38 +1,64 @@
 var async = require('neo-async'),
-    git = require('./util/git'),
-    semver = require('semver');
+  git = require('./util/git'),
+  semver = require('semver');
 
 module.exports = function(grunt) {
-  grunt.registerTask('version', 'Updates the current release version', function() {
-    var done = this.async(),
+  grunt.registerTask(
+    'version',
+    'Updates the current release version',
+    function() {
+      var done = this.async(),
         pkg = grunt.config('pkg'),
         version = grunt.option('ver');
 
-    if (!semver.valid(version)) {
-      throw new Error('Must provide a version number (Ex: --ver=1.0.0):\n\t' + version + '\n\n');
-    }
+      if (!semver.valid(version)) {
+        throw new Error(
+          'Must provide a version number (Ex: --ver=1.0.0):\n\t' +
+            version +
+            '\n\n'
+        );
+      }
 
-    pkg.version = version;
-    grunt.config('pkg', pkg);
+      pkg.version = version;
+      grunt.config('pkg', pkg);
 
-    grunt.log.writeln('Updating to version ' + version);
+      grunt.log.writeln('Updating to version ' + version);
 
-    async.each([
-        ['lib/handlebars/base.js', (/const VERSION = ['"](.*)['"];/), 'const VERSION = \'' + version + '\';'],
-        ['components/bower.json', (/"version":.*/), '"version": "' + version + '",'],
-        ['components/package.json', /"version":.*/, '"version": "' + version + '",'],
-        ['components/handlebars.js.nuspec', (/<version>.*<\/version>/), '<version>' + version + '</version>']
-      ],
-      function(args, callback) {
-        replace.apply(undefined, args);
-        grunt.log.writeln('    - ' + args[0]);
-        git.add(args[0], callback);
-      },
-      function() {
-        grunt.task.run(['default']);
-        done();
-      });
-  });
+      async.each(
+        [
+          [
+            'lib/handlebars/base.js',
+            /const VERSION = ['"](.*)['"];/,
+            "const VERSION = '" + version + "';"
+          ],
+          [
+            'components/bower.json',
+            /"version":.*/,
+            '"version": "' + version + '",'
+          ],
+          [
+            'components/package.json',
+            /"version":.*/,
+            '"version": "' + version + '",'
+          ],
+          [
+            'components/handlebars.js.nuspec',
+            /<version>.*<\/version>/,
+            '<version>' + version + '</version>'
+          ]
+        ],
+        function(args, callback) {
+          replace.apply(undefined, args);
+          grunt.log.writeln('    - ' + args[0]);
+          git.add(args[0], callback);
+        },
+        function() {
+          grunt.task.run(['default']);
+          done();
+        }
+      );
+    }
+  );
 
   function replace(path, regex, value) {
     var content = grunt.file.read(path);

From 8901c28e9a13204f0d392834c9b93d20c69ae722 Mon Sep 17 00:00:00 2001
From: Nils Knappmeier <github@knappi.org>
Date: Tue, 3 Dec 2019 22:59:04 +0100
Subject: [PATCH 07/24] chore: fix task name in build

---
 Gruntfile.js | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/Gruntfile.js b/Gruntfile.js
index 9cf025960..6e32e162d 100644
--- a/Gruntfile.js
+++ b/Gruntfile.js
@@ -264,10 +264,13 @@ module.exports = function(grunt) {
   this.registerTask('amd', ['babel:amd', 'requirejs']);
 
   grunt.registerTask('bench', ['metrics']);
-  grunt.registerTask(
-    'sauce',
-    process.env.SAUCE_USERNAME ? ['tests', 'connect', 'saucelabs-mocha'] : []
-  );
+
+  if (process.env.SAUCE_USERNAME) {
+    grunt.registerTask('sauce', ['concat:tests', 'connect', 'saucelabs-mocha']);
+  } else {
+    grunt.registerTask('sauce', []);
+  }
+
   // Requires secret properties (saucelabs-credentials etc.) from .travis.yaml
   grunt.registerTask('extensive-tests-and-publish-to-aws', [
     'default',

From c40d9f33adc1a1a024d59e8f8fc2266aaded5d8f Mon Sep 17 00:00:00 2001
From: Nils Knappmeier <github@knappi.org>
Date: Thu, 5 Dec 2019 08:01:33 +0100
Subject: [PATCH 08/24] chore: active linting and formatting on commit

---
 package.json | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/package.json b/package.json
index a925e0a65..9ce188bb0 100644
--- a/package.json
+++ b/package.json
@@ -113,7 +113,7 @@
   ],
   "husky": {
     "hooks": {
-      "pre-commit": "true || lint-staged"
+      "pre-commit": "lint-staged"
     }
   },
   "lint-staged": {

From 04b19848cccabb7c31fd24265aa2ec4c6c705ebb Mon Sep 17 00:00:00 2001
From: Nils Knappmeier <npm@knappi.org>
Date: Sun, 8 Dec 2019 16:17:15 +0100
Subject: [PATCH 09/24] chore: try to fix saucelabs credentials (#1627)

---
 .travis.yml | 68 +++++++++++++++++++++++------------------------------
 1 file changed, 30 insertions(+), 38 deletions(-)

diff --git a/.travis.yml b/.travis.yml
index a5ff4c692..e7d347e27 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,47 +1,39 @@
 language: node_js
-
 jobs:
   include:
-    - stage: test
-      name: "check javascript (eslint)"
-      node_js: lts/*
-      script: npm run lint
-
-    - stage: test
-      name: "check formatting (prettier)"
-      node_js: lts/*
-      script: npm run check-format
-
-    - stage: test
-      name: "check typescript definitions (dtslint)"
-      node_js: lts/*
-      script: npm run dtslint
-
-    - stage: test
-      name: "extensive tests and publish to aws"
-      script: npm run extensive-tests-and-publish-to-aws
-      env:
-        - S3_BUCKET_NAME=builds.handlebarsjs.com
-        - secure: ckyEe5dzjdFDjmZ6wIrhGm0CFBEnKq8c1dYptfgVV/Q5/nJFGzu8T0yTjouS/ERxzdT2H327/63VCxhFnLCRHrsh4rlW/rCy4XI3O/0TeMLgFPa4TXkO8359qZ4CB44TBb3NsJyQXNMYdJpPLTCVTMpuiqqkFFOr+6OeggR7ufA=
-        - secure: Nm4AgSfsgNB21kgKrF9Tl7qVZU8YYREhouQunFracTcZZh2NZ2XH5aHuSiXCj88B13Cr/jGbJKsZ4T3QS3wWYtz6lkyVOx3H3iI+TMtqhD9RM3a7A4O+4vVN8IioB2YjhEu0OKjwgX5gp+0uF+pLEi7Hpj6fupD3AbbL5uYcKg8=
-        - SAUCE_USERNAME=handlebars
-        - secure: yERYCf7AwL11D9uMtacly/THGV8BlzsMmrt+iQVvGA3GaY6QMmfYqf6P6cCH98sH5etd1Y+1e6YrPeMjqI6lyRllT7FptoyOdHulazQe86VQN4sc0EpqMlH088kB7gGjTut9Z+X9ViooT5XEh9WA5jXEI9pXhQJNoIHkWPuwGuY=
-      node_js: "10"
-
-    - stage: test
-      name: "test with latest nodejs-lts"
-      node_js: lts/*
-      script: npm run test
-
-    - stage: test
-      name: "test with active nodejs"
-      node_js: node
-      script: npm run test
-
+  - stage: test
+    name: check javascript (eslint)
+    node_js: lts/*
+    script: npm run lint
+  - stage: test
+    name: check formatting (prettier)
+    node_js: lts/*
+    script: npm run check-format
+  - stage: test
+    name: check typescript definitions (dtslint)
+    node_js: lts/*
+    script: npm run dtslint
+  - stage: test
+    name: extensive tests and publish to aws
+    script: npm run extensive-tests-and-publish-to-aws
+    env:
+    - S3_BUCKET_NAME=builds.handlebarsjs.com
+    - secure: ckyEe5dzjdFDjmZ6wIrhGm0CFBEnKq8c1dYptfgVV/Q5/nJFGzu8T0yTjouS/ERxzdT2H327/63VCxhFnLCRHrsh4rlW/rCy4XI3O/0TeMLgFPa4TXkO8359qZ4CB44TBb3NsJyQXNMYdJpPLTCVTMpuiqqkFFOr+6OeggR7ufA=
+    - secure: Nm4AgSfsgNB21kgKrF9Tl7qVZU8YYREhouQunFracTcZZh2NZ2XH5aHuSiXCj88B13Cr/jGbJKsZ4T3QS3wWYtz6lkyVOx3H3iI+TMtqhD9RM3a7A4O+4vVN8IioB2YjhEu0OKjwgX5gp+0uF+pLEi7Hpj6fupD3AbbL5uYcKg8=
+    - SAUCE_USERNAME=handlebars
+    - secure: 1VkLQhbsEug4ZMQ52tTOus/WLvW3Etqe7GbCzZfzsI8d2ygJPjFfzU8fNm4pVVwoTI21MaM5AQq7SVPu8DWN1YbDjJycMdY1zO3DsB9aZBxTal98fIB7ZIUce9r5z2EP6mETrsbYjZkeckzIBI0A4UVa+F2BO4KbRDXP1Db3u3I=
+    node_js: '10'
+  - stage: test
+    name: test with latest nodejs-lts
+    node_js: lts/*
+    script: npm run test
+  - stage: test
+    name: test with active nodejs
+    node_js: node
+    script: npm run test
 cache: npm
 email:
   on_failure: change
   on_success: never
-
 git:
   depth: 100

From d1fb07b32b8cae4e230ee000fa4267c96dcc44c3 Mon Sep 17 00:00:00 2001
From: Marcos Marado <mindboosternoori@gmail.com>
Date: Fri, 6 Dec 2019 23:57:50 +0000
Subject: [PATCH 10/24] Update (C) year in the LICENSE file

Welcome to 2019!
---
 LICENSE | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/LICENSE b/LICENSE
index b802d14e7..4d9d5806f 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,4 +1,4 @@
-Copyright (C) 2011-2017 by Yehuda Katz
+Copyright (C) 2011-2019 by Yehuda Katz
 
 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal

From dc5495216d092de6890c9245e99453666376461f Mon Sep 17 00:00:00 2001
From: Nils Knappmeier <github@knappi.org>
Date: Wed, 11 Dec 2019 23:44:43 +0100
Subject: [PATCH 11/24] chore: change eslint-rules for tasks/

- use es2017 rules as NodeJS supports it today
- add "prefer-const"
---
 tasks/.eslintrc    | 16 ----------------
 tasks/.eslintrc.js | 12 ++++++++++++
 tasks/metrics.js   |  4 ++--
 tasks/parser.js    | 12 ++++++------
 tasks/publish.js   | 16 ++++++++--------
 tasks/test.js      | 30 +++++++++++++++---------------
 tasks/util/git.js  |  6 +++---
 tasks/version.js   |  6 +++---
 8 files changed, 49 insertions(+), 53 deletions(-)
 delete mode 100644 tasks/.eslintrc
 create mode 100644 tasks/.eslintrc.js

diff --git a/tasks/.eslintrc b/tasks/.eslintrc
deleted file mode 100644
index 346150294..000000000
--- a/tasks/.eslintrc
+++ /dev/null
@@ -1,16 +0,0 @@
-{
-  "globals": {
-    "require": true
-  },
-  "rules": {
-    // Disabling for tests, for now.
-    "no-path-concat": 0,
-
-    "no-var": 0,
-    "no-shadow": 0,
-    "handle-callback-err": 0,
-    "no-console": 0,
-    "no-process-env": 0,
-    "dot-notation": [2, {"allowKeywords": true}]
-  }
-}
\ No newline at end of file
diff --git a/tasks/.eslintrc.js b/tasks/.eslintrc.js
new file mode 100644
index 000000000..7c985caa8
--- /dev/null
+++ b/tasks/.eslintrc.js
@@ -0,0 +1,12 @@
+module.exports = {
+  extends: ['../.eslintrc.js'],
+  parserOptions: {
+    sourceType: 'module',
+    ecmaVersion: 2017,
+    ecmaFeatures: {}
+  },
+  rules: {
+    'no-process-env': 'off',
+    'prefer-const': 'warn'
+  }
+};
diff --git a/tasks/metrics.js b/tasks/metrics.js
index f903ceb7b..bcb76318f 100644
--- a/tasks/metrics.js
+++ b/tasks/metrics.js
@@ -1,10 +1,10 @@
-var _ = require('underscore'),
+const _ = require('underscore'),
   async = require('neo-async'),
   metrics = require('../bench');
 
 module.exports = function(grunt) {
   grunt.registerTask('metrics', function() {
-    var done = this.async(),
+    const done = this.async(),
       execName = grunt.option('name'),
       events = {};
 
diff --git a/tasks/parser.js b/tasks/parser.js
index 0adba111d..21e7442ad 100644
--- a/tasks/parser.js
+++ b/tasks/parser.js
@@ -1,16 +1,16 @@
-var childProcess = require('child_process');
+const childProcess = require('child_process');
 
 module.exports = function(grunt) {
   grunt.registerTask('parser', 'Generate jison parser.', function() {
-    var done = this.async();
+    const done = this.async();
 
-    var cmd = './node_modules/.bin/jison';
+    let cmd = './node_modules/.bin/jison';
 
     if (process.platform === 'win32') {
       cmd = 'node_modules\\.bin\\jison.cmd';
     }
 
-    var child = childProcess.spawn(
+    const child = childProcess.spawn(
       cmd,
       ['-m', 'js', 'src/handlebars.yy', 'src/handlebars.l'],
       { stdio: 'inherit' }
@@ -22,14 +22,14 @@ module.exports = function(grunt) {
         return;
       }
 
-      var src = [
+      const src = [
         'src/parser-prefix.js',
         'handlebars.js',
         'src/parser-suffix.js'
       ]
         .map(grunt.file.read)
         .join('');
-      grunt.file.delete('handlebars.js');
+      grunt.file['delete']('handlebars.js');
 
       grunt.file.write('lib/handlebars/compiler/parser.js', src);
       grunt.log.writeln('Parser "lib/handlebars/compiler/parser.js" created.');
diff --git a/tasks/publish.js b/tasks/publish.js
index b22c9b8ea..207e281fe 100644
--- a/tasks/publish.js
+++ b/tasks/publish.js
@@ -1,4 +1,4 @@
-var _ = require('underscore'),
+const _ = require('underscore'),
   async = require('neo-async'),
   AWS = require('aws-sdk'),
   git = require('./util/git'),
@@ -6,7 +6,7 @@ var _ = require('underscore'),
 
 module.exports = function(grunt) {
   grunt.registerTask('publish:latest', function() {
-    var done = this.async();
+    const done = this.async();
 
     git.debug(function(remotes, branches) {
       grunt.log.writeln('remotes: ' + remotes);
@@ -15,7 +15,7 @@ module.exports = function(grunt) {
       git.commitInfo(function(err, info) {
         grunt.log.writeln('tag: ' + info.tagName);
 
-        var files = [];
+        const files = [];
 
         // Publish the master as "latest" and with the commit-id
         if (info.isMaster) {
@@ -40,7 +40,7 @@ module.exports = function(grunt) {
     });
   });
   grunt.registerTask('publish:version', function() {
-    var done = this.async();
+    const done = this.async();
     initSDK();
 
     git.commitInfo(function(err, info) {
@@ -52,7 +52,7 @@ module.exports = function(grunt) {
   });
 
   function initSDK() {
-    var bucket = process.env.S3_BUCKET_NAME,
+    const bucket = process.env.S3_BUCKET_NAME,
       key = process.env.S3_ACCESS_KEY_ID,
       secret = process.env.S3_SECRET_ACCESS_KEY;
 
@@ -63,13 +63,13 @@ module.exports = function(grunt) {
     AWS.config.update({ accessKeyId: key, secretAccessKey: secret });
   }
   function publish(files, callback) {
-    var s3 = new AWS.S3(),
+    const s3 = new AWS.S3(),
       bucket = process.env.S3_BUCKET_NAME;
 
     async.each(
       _.keys(files),
       function(file, callback) {
-        var params = {
+        const params = {
           Bucket: bucket,
           Key: file,
           Body: grunt.file.read(files[file])
@@ -87,7 +87,7 @@ module.exports = function(grunt) {
     );
   }
   function fileMap(suffixes) {
-    var map = {};
+    const map = {};
     _.each(
       [
         'handlebars.js',
diff --git a/tasks/test.js b/tasks/test.js
index 94fc8c25a..c7279cf3b 100644
--- a/tasks/test.js
+++ b/tasks/test.js
@@ -1,13 +1,13 @@
-var childProcess = require('child_process'),
+const childProcess = require('child_process'),
   fs = require('fs'),
   os = require('os');
 
 module.exports = function(grunt) {
   grunt.registerTask('test:bin', function() {
-    var done = this.async();
+    const done = this.async();
 
-    var cmd = './bin/handlebars';
-    var args = ['-a', 'spec/artifacts/empty.handlebars'];
+    let cmd = './bin/handlebars';
+    const args = ['-a', 'spec/artifacts/empty.handlebars'];
 
     // On Windows, the executable handlebars.js file cannot be run directly
     if (os.platform() === 'win32') {
@@ -19,7 +19,7 @@ module.exports = function(grunt) {
         throw err;
       }
 
-      var expected = fs
+      const expected = fs
         .readFileSync('./spec/expected/empty.amd.js')
         .toString()
         .replace(/\r\n/g, '\n');
@@ -38,9 +38,9 @@ module.exports = function(grunt) {
     });
   });
   grunt.registerTask('test:mocha', function() {
-    var done = this.async();
+    const done = this.async();
 
-    var runner = childProcess.fork('./spec/env/runner', [], {
+    const runner = childProcess.fork('./spec/env/runner', [], {
       stdio: 'inherit'
     });
     runner.on('close', function(code) {
@@ -51,24 +51,24 @@ module.exports = function(grunt) {
     });
   });
   grunt.registerTask('test:cov', function() {
-    var done = this.async();
+    const done = this.async();
 
-    var runner = childProcess.fork(
+    const runner = childProcess.spawn(
       'node_modules/istanbul/lib/cli.js',
       ['cover', '--source-map', '--', './spec/env/runner.js'],
       { stdio: 'inherit' }
     );
-    runner.on('close', function(code) {
-      if (code != 0) {
+    runner.on('exit', function(code) {
+      if (code !== 0) {
         grunt.fatal(code + ' tests failed');
       }
       done();
     });
   });
   grunt.registerTask('test:min', function() {
-    var done = this.async();
+    const done = this.async();
 
-    var runner = childProcess.fork('./spec/env/runner', ['--min'], {
+    const runner = childProcess.fork('./spec/env/runner', ['--min'], {
       stdio: 'inherit'
     });
     runner.on('close', function(code) {
@@ -80,9 +80,9 @@ module.exports = function(grunt) {
   });
 
   grunt.registerTask('test:check-cov', function() {
-    var done = this.async();
+    const done = this.async();
 
-    var runner = childProcess.fork(
+    const runner = childProcess.fork(
       'node_modules/istanbul/lib/cli.js',
       [
         'check-coverage',
diff --git a/tasks/util/git.js b/tasks/util/git.js
index 5418bf03d..4dc5cbde0 100644
--- a/tasks/util/git.js
+++ b/tasks/util/git.js
@@ -1,4 +1,4 @@
-var childProcess = require('child_process');
+const childProcess = require('child_process');
 
 module.exports = {
   debug: function(callback) {
@@ -99,13 +99,13 @@ module.exports = {
         throw new Error('git.tagName: ' + err.message);
       }
 
-      var tags = stdout.trim().split(/\n/);
+      let tags = stdout.trim().split(/\n/);
       tags = tags.filter(function(info) {
         info = info.split('-');
         return info.length == 1;
       });
 
-      var versionTags = tags.filter(function(info) {
+      const versionTags = tags.filter(function(info) {
         return /^v/.test(info[0]);
       });
 
diff --git a/tasks/version.js b/tasks/version.js
index 05c05fa01..f9d5c5675 100644
--- a/tasks/version.js
+++ b/tasks/version.js
@@ -1,4 +1,4 @@
-var async = require('neo-async'),
+const async = require('neo-async'),
   git = require('./util/git'),
   semver = require('semver');
 
@@ -7,7 +7,7 @@ module.exports = function(grunt) {
     'version',
     'Updates the current release version',
     function() {
-      var done = this.async(),
+      const done = this.async(),
         pkg = grunt.config('pkg'),
         version = grunt.option('ver');
 
@@ -61,7 +61,7 @@ module.exports = function(grunt) {
   );
 
   function replace(path, regex, value) {
-    var content = grunt.file.read(path);
+    let content = grunt.file.read(path);
     content = content.replace(regex, value);
     grunt.file.write(path, content);
   }

From dde108e2836928ec4c0509fdfb32da052022357f Mon Sep 17 00:00:00 2001
From: Nils Knappmeier <github@knappi.org>
Date: Thu, 12 Dec 2019 01:00:57 +0100
Subject: [PATCH 12/24] test/style: refactor test-task to make it more readable

---
 Gruntfile.js        |   2 +
 tasks/.eslintrc.js  |   4 +-
 tasks/parser.js     |   2 +-
 tasks/test-bin.js   |  55 +++++++++++++++++++++++
 tasks/test-mocha.js |  66 +++++++++++++++++++++++++++
 tasks/test.js       | 107 --------------------------------------------
 6 files changed, 127 insertions(+), 109 deletions(-)
 create mode 100644 tasks/test-bin.js
 create mode 100644 tasks/test-mocha.js
 delete mode 100644 tasks/test.js

diff --git a/Gruntfile.js b/Gruntfile.js
index 6e32e162d..84a361581 100644
--- a/Gruntfile.js
+++ b/Gruntfile.js
@@ -263,6 +263,8 @@ module.exports = function(grunt) {
 
   this.registerTask('amd', ['babel:amd', 'requirejs']);
 
+  this.registerTask('test', ['test:bin', 'test:cov', 'test:check-cov']);
+
   grunt.registerTask('bench', ['metrics']);
 
   if (process.env.SAUCE_USERNAME) {
diff --git a/tasks/.eslintrc.js b/tasks/.eslintrc.js
index 7c985caa8..642a9ab06 100644
--- a/tasks/.eslintrc.js
+++ b/tasks/.eslintrc.js
@@ -7,6 +7,8 @@ module.exports = {
   },
   rules: {
     'no-process-env': 'off',
-    'prefer-const': 'warn'
+    'prefer-const': 'warn',
+    'compat/compat': 'off',
+    'dot-notation': ['error', { allowKeywords: true }]
   }
 };
diff --git a/tasks/parser.js b/tasks/parser.js
index 21e7442ad..a0c19e47e 100644
--- a/tasks/parser.js
+++ b/tasks/parser.js
@@ -29,7 +29,7 @@ module.exports = function(grunt) {
       ]
         .map(grunt.file.read)
         .join('');
-      grunt.file['delete']('handlebars.js');
+      grunt.file.delete('handlebars.js');
 
       grunt.file.write('lib/handlebars/compiler/parser.js', src);
       grunt.log.writeln('Parser "lib/handlebars/compiler/parser.js" created.');
diff --git a/tasks/test-bin.js b/tasks/test-bin.js
new file mode 100644
index 000000000..48c0ded87
--- /dev/null
+++ b/tasks/test-bin.js
@@ -0,0 +1,55 @@
+const childProcess = require('child_process'),
+  fs = require('fs'),
+  os = require('os'),
+  expect = require('chai').expect,
+  util = require('util');
+
+const readFile = util.promisify(fs.readFile);
+const execFile = util.promisify(childProcess.execFile);
+
+module.exports = function(grunt) {
+  grunt.registerTask(
+    'test:bin',
+    wrapAsync(async function() {
+      const { stdout } = await execFileWithWin32Fallback('./bin/handlebars', [
+        '-a',
+        'spec/artifacts/empty.handlebars'
+      ]);
+
+      const expectedOutput = await readFile(
+        './spec/expected/empty.amd.js',
+        'utf-8'
+      );
+
+      const normalizedOutput = normalizeCrlf(stdout);
+      const normalizedExpectedOutput = normalizeCrlf(expectedOutput);
+      expect(normalizedOutput).to.equal(normalizedExpectedOutput);
+    })
+  );
+
+  async function execFileWithWin32Fallback(command, args) {
+    // On Windows, the executable handlebars.js file cannot be run directly
+    if (os.platform() === 'win32') {
+      args.unshift(command);
+      command = process.argv[0];
+    }
+    return execFile(command, args, { encoding: 'utf-8' });
+  }
+
+  function normalizeCrlf(string) {
+    if (string != null) {
+      return string.replace(/\r\n/g, '\n');
+    }
+    return string;
+  }
+
+  function wrapAsync(asyncFunction) {
+    return function() {
+      asyncFunction()
+        .catch(error => {
+          grunt.fatal(error);
+        })
+        .finally(this.async());
+    };
+  }
+};
diff --git a/tasks/test-mocha.js b/tasks/test-mocha.js
new file mode 100644
index 000000000..9bed2c63e
--- /dev/null
+++ b/tasks/test-mocha.js
@@ -0,0 +1,66 @@
+const childProcess = require('child_process');
+
+module.exports = function(grunt) {
+  grunt.registerTask(
+    'test:mocha',
+    promiseBasedTask(async () => forkAndWait('./spec/env/runner'))
+  );
+
+  grunt.registerTask(
+    'test:cov',
+    promiseBasedTask(async () =>
+      forkAndWait(
+        'node_modules/istanbul/lib/cli.js',
+        'cover',
+        '--source-map',
+        '--',
+        './spec/env/runner.js'
+      )
+    )
+  );
+
+  grunt.registerTask(
+    'test:min',
+    promiseBasedTask(async () => forkAndWait('./spec/env/runner', '--min'))
+  );
+
+  grunt.registerTask(
+    'test:check-cov',
+    promiseBasedTask(() =>
+      forkAndWait(
+        'node_modules/istanbul/lib/cli.js',
+        'check-coverage',
+        '--statements',
+        '100',
+        '--functions',
+        '100',
+        '--branches',
+        '100',
+        '--lines 100'
+      )
+    )
+  );
+
+  function promiseBasedTask(asyncFunction) {
+    return function() {
+      asyncFunction()
+        .catch(error => {
+          grunt.fatal(error);
+        })
+        .finally(this.async());
+    };
+  }
+
+  async function forkAndWait(command, ...args) {
+    return new Promise((resolve, reject) => {
+      const child = childProcess.fork(command, args, { stdio: 'inherit' });
+      child.on('close', code => {
+        if (code !== 0) {
+          reject(new Error(`Child process failed with exit-code ${code}`));
+        }
+      });
+    });
+  }
+
+  grunt.registerTask('test', ['test:bin', 'test:cov', 'test:check-cov']);
+};
diff --git a/tasks/test.js b/tasks/test.js
deleted file mode 100644
index c7279cf3b..000000000
--- a/tasks/test.js
+++ /dev/null
@@ -1,107 +0,0 @@
-const childProcess = require('child_process'),
-  fs = require('fs'),
-  os = require('os');
-
-module.exports = function(grunt) {
-  grunt.registerTask('test:bin', function() {
-    const done = this.async();
-
-    let cmd = './bin/handlebars';
-    const args = ['-a', 'spec/artifacts/empty.handlebars'];
-
-    // On Windows, the executable handlebars.js file cannot be run directly
-    if (os.platform() === 'win32') {
-      args.unshift(cmd);
-      cmd = process.argv[0];
-    }
-    childProcess.execFile(cmd, args, function(err, stdout) {
-      if (err) {
-        throw err;
-      }
-
-      const expected = fs
-        .readFileSync('./spec/expected/empty.amd.js')
-        .toString()
-        .replace(/\r\n/g, '\n');
-
-      if (stdout.toString() !== expected) {
-        throw new Error(
-          'Expected binary output differed:\n\n"' +
-            stdout +
-            '"\n\n"' +
-            expected +
-            '"'
-        );
-      }
-
-      done();
-    });
-  });
-  grunt.registerTask('test:mocha', function() {
-    const done = this.async();
-
-    const runner = childProcess.fork('./spec/env/runner', [], {
-      stdio: 'inherit'
-    });
-    runner.on('close', function(code) {
-      if (code !== 0) {
-        grunt.fatal(code + ' tests failed');
-      }
-      done();
-    });
-  });
-  grunt.registerTask('test:cov', function() {
-    const done = this.async();
-
-    const runner = childProcess.spawn(
-      'node_modules/istanbul/lib/cli.js',
-      ['cover', '--source-map', '--', './spec/env/runner.js'],
-      { stdio: 'inherit' }
-    );
-    runner.on('exit', function(code) {
-      if (code !== 0) {
-        grunt.fatal(code + ' tests failed');
-      }
-      done();
-    });
-  });
-  grunt.registerTask('test:min', function() {
-    const done = this.async();
-
-    const runner = childProcess.fork('./spec/env/runner', ['--min'], {
-      stdio: 'inherit'
-    });
-    runner.on('close', function(code) {
-      if (code !== 0) {
-        grunt.fatal(code + ' tests failed');
-      }
-      done();
-    });
-  });
-
-  grunt.registerTask('test:check-cov', function() {
-    const done = this.async();
-
-    const runner = childProcess.fork(
-      'node_modules/istanbul/lib/cli.js',
-      [
-        'check-coverage',
-        '--statements',
-        '100',
-        '--functions',
-        '100',
-        '--branches',
-        '100',
-        '--lines 100'
-      ],
-      { stdio: 'inherit' }
-    );
-    runner.on('close', function(code) {
-      if (code != 0) {
-        grunt.fatal('Coverage check failed: ' + code);
-      }
-      done();
-    });
-  });
-  grunt.registerTask('test', ['test:bin', 'test:cov', 'test:check-cov']);
-};

From 3a5b65e02be8949e778cf2a93d71f6cc49a31232 Mon Sep 17 00:00:00 2001
From: Nils Knappmeier <github@knappi.org>
Date: Thu, 12 Dec 2019 22:19:30 +0100
Subject: [PATCH 13/24] test/style: refactor parser task

---
 tasks/parser.js                | 58 +++++++++++-------------
 tasks/test-bin.js              | 80 +++++++++++++++------------------
 tasks/test-mocha.js            | 82 +++++++++++-----------------------
 tasks/util/async-grunt-task.js | 13 ++++++
 tasks/util/exec-file.js        | 51 +++++++++++++++++++++
 5 files changed, 151 insertions(+), 133 deletions(-)
 create mode 100644 tasks/util/async-grunt-task.js
 create mode 100644 tasks/util/exec-file.js

diff --git a/tasks/parser.js b/tasks/parser.js
index a0c19e47e..252b8c267 100644
--- a/tasks/parser.js
+++ b/tasks/parser.js
@@ -1,39 +1,33 @@
-const childProcess = require('child_process');
+const { execFileWithInheritedOutput } = require('./util/exec-file');
+const { createRegisterAsyncTaskFn } = require('./util/async-grunt-task');
 
-module.exports = function(grunt) {
-  grunt.registerTask('parser', 'Generate jison parser.', function() {
-    const done = this.async();
+const OUTPUT_FILE = 'lib/handlebars/compiler/parser.js';
 
-    let cmd = './node_modules/.bin/jison';
+module.exports = function(grunt) {
+  const registerAsyncTask = createRegisterAsyncTaskFn(grunt);
 
-    if (process.platform === 'win32') {
-      cmd = 'node_modules\\.bin\\jison.cmd';
-    }
+  registerAsyncTask('parser', async () => {
+    await runJison();
+    combineWithPrefixAndSuffix();
+    grunt.log.writeln(`Parser "${OUTPUT_FILE}" created.`);
+  });
 
-    const child = childProcess.spawn(
-      cmd,
-      ['-m', 'js', 'src/handlebars.yy', 'src/handlebars.l'],
-      { stdio: 'inherit' }
-    );
-    child.on('exit', function(code) {
-      if (code != 0) {
-        grunt.fatal('Jison failure: ' + code);
-        done();
-        return;
-      }
+  async function runJison() {
+    await execFileWithInheritedOutput('jison', [
+      '-m',
+      'js',
+      'src/handlebars.yy',
+      'src/handlebars.l'
+    ]);
+  }
 
-      const src = [
-        'src/parser-prefix.js',
-        'handlebars.js',
-        'src/parser-suffix.js'
-      ]
-        .map(grunt.file.read)
-        .join('');
-      grunt.file.delete('handlebars.js');
+  function combineWithPrefixAndSuffix() {
+    const combinedParserSourceCode =
+      grunt.file.read('src/parser-prefix.js') +
+      grunt.file.read('handlebars.js') +
+      grunt.file.read('src/parser-suffix.js');
 
-      grunt.file.write('lib/handlebars/compiler/parser.js', src);
-      grunt.log.writeln('Parser "lib/handlebars/compiler/parser.js" created.');
-      done();
-    });
-  });
+    grunt.file.write(OUTPUT_FILE, combinedParserSourceCode);
+    grunt.file.delete('handlebars.js');
+  }
 };
diff --git a/tasks/test-bin.js b/tasks/test-bin.js
index 48c0ded87..8873c9f01 100644
--- a/tasks/test-bin.js
+++ b/tasks/test-bin.js
@@ -1,55 +1,45 @@
 const childProcess = require('child_process'),
   fs = require('fs'),
   os = require('os'),
-  expect = require('chai').expect,
-  util = require('util');
-
-const readFile = util.promisify(fs.readFile);
-const execFile = util.promisify(childProcess.execFile);
+  expect = require('chai').expect;
 
 module.exports = function(grunt) {
-  grunt.registerTask(
-    'test:bin',
-    wrapAsync(async function() {
-      const { stdout } = await execFileWithWin32Fallback('./bin/handlebars', [
-        '-a',
-        'spec/artifacts/empty.handlebars'
-      ]);
-
-      const expectedOutput = await readFile(
-        './spec/expected/empty.amd.js',
-        'utf-8'
-      );
-
-      const normalizedOutput = normalizeCrlf(stdout);
-      const normalizedExpectedOutput = normalizeCrlf(expectedOutput);
-      expect(normalizedOutput).to.equal(normalizedExpectedOutput);
-    })
-  );
-
-  async function execFileWithWin32Fallback(command, args) {
+  grunt.registerTask('test:bin', function() {
+    const stdout = executeBinHandlebars(
+      '-a',
+      'spec/artifacts/empty.handlebars'
+    );
+
+    const expectedOutput = fs.readFileSync(
+      './spec/expected/empty.amd.js',
+      'utf-8'
+    );
+
+    const normalizedOutput = normalizeCrlf(stdout);
+    const normalizedExpectedOutput = normalizeCrlf(expectedOutput);
+
+    expect(normalizedOutput).to.equal(normalizedExpectedOutput);
+  });
+};
+
+// helper functions
+
+function executeBinHandlebars(...args) {
+  if (os.platform() === 'win32') {
     // On Windows, the executable handlebars.js file cannot be run directly
-    if (os.platform() === 'win32') {
-      args.unshift(command);
-      command = process.argv[0];
-    }
-    return execFile(command, args, { encoding: 'utf-8' });
+    const nodeJs = process.argv[0];
+    return execFilesSyncUtf8(nodeJs, ['./bin/handlebars'].concat(args));
   }
+  return execFilesSyncUtf8('./bin/handlebars', args);
+}
 
-  function normalizeCrlf(string) {
-    if (string != null) {
-      return string.replace(/\r\n/g, '\n');
-    }
-    return string;
-  }
+function execFilesSyncUtf8(command, args) {
+  return childProcess.execFileSync(command, args, { encoding: 'utf-8' });
+}
 
-  function wrapAsync(asyncFunction) {
-    return function() {
-      asyncFunction()
-        .catch(error => {
-          grunt.fatal(error);
-        })
-        .finally(this.async());
-    };
+function normalizeCrlf(string) {
+  if (typeof string === 'string') {
+    return string.replace(/\r\n/g, '\n');
   }
-};
+  return string;
+}
diff --git a/tasks/test-mocha.js b/tasks/test-mocha.js
index 9bed2c63e..445a88cf3 100644
--- a/tasks/test-mocha.js
+++ b/tasks/test-mocha.js
@@ -1,66 +1,36 @@
-const childProcess = require('child_process');
+const { execNodeJsScriptWithInheritedOutput } = require('./util/exec-file');
+const { createRegisterAsyncTaskFn } = require('./util/async-grunt-task');
 
 module.exports = function(grunt) {
-  grunt.registerTask(
-    'test:mocha',
-    promiseBasedTask(async () => forkAndWait('./spec/env/runner'))
-  );
+  const registerAsyncTask = createRegisterAsyncTaskFn(grunt);
 
-  grunt.registerTask(
-    'test:cov',
-    promiseBasedTask(async () =>
-      forkAndWait(
-        'node_modules/istanbul/lib/cli.js',
-        'cover',
-        '--source-map',
-        '--',
-        './spec/env/runner.js'
-      )
-    )
+  registerAsyncTask('test:mocha', async () =>
+    execNodeJsScriptWithInheritedOutput('./spec/env/runner')
   );
 
-  grunt.registerTask(
-    'test:min',
-    promiseBasedTask(async () => forkAndWait('./spec/env/runner', '--min'))
+  registerAsyncTask('test:cov', async () =>
+    execNodeJsScriptWithInheritedOutput('node_modules/istanbul/lib/cli.js', [
+      'cover',
+      '--source-map',
+      '--',
+      './spec/env/runner.js'
+    ])
   );
 
-  grunt.registerTask(
-    'test:check-cov',
-    promiseBasedTask(() =>
-      forkAndWait(
-        'node_modules/istanbul/lib/cli.js',
-        'check-coverage',
-        '--statements',
-        '100',
-        '--functions',
-        '100',
-        '--branches',
-        '100',
-        '--lines 100'
-      )
-    )
+  registerAsyncTask('test:min', async () =>
+    execNodeJsScriptWithInheritedOutput('./spec/env/runner', ['--min'])
   );
 
-  function promiseBasedTask(asyncFunction) {
-    return function() {
-      asyncFunction()
-        .catch(error => {
-          grunt.fatal(error);
-        })
-        .finally(this.async());
-    };
-  }
-
-  async function forkAndWait(command, ...args) {
-    return new Promise((resolve, reject) => {
-      const child = childProcess.fork(command, args, { stdio: 'inherit' });
-      child.on('close', code => {
-        if (code !== 0) {
-          reject(new Error(`Child process failed with exit-code ${code}`));
-        }
-      });
-    });
-  }
-
-  grunt.registerTask('test', ['test:bin', 'test:cov', 'test:check-cov']);
+  registerAsyncTask('test:check-cov', async () =>
+    execNodeJsScriptWithInheritedOutput('node_modules/istanbul/lib/cli.js', [
+      'check-coverage',
+      '--statements',
+      '100',
+      '--functions',
+      '100',
+      '--branches',
+      '100',
+      '--lines 100'
+    ])
+  );
 };
diff --git a/tasks/util/async-grunt-task.js b/tasks/util/async-grunt-task.js
new file mode 100644
index 000000000..20360570f
--- /dev/null
+++ b/tasks/util/async-grunt-task.js
@@ -0,0 +1,13 @@
+module.exports = { createRegisterAsyncTaskFn };
+
+function createRegisterAsyncTaskFn(grunt) {
+  return function registerAsyncTask(name, asyncFunction) {
+    grunt.registerTask(name, function() {
+      asyncFunction()
+        .catch(error => {
+          grunt.fatal(error);
+        })
+        .finally(this.async());
+    });
+  };
+}
diff --git a/tasks/util/exec-file.js b/tasks/util/exec-file.js
new file mode 100644
index 000000000..66fd8e92a
--- /dev/null
+++ b/tasks/util/exec-file.js
@@ -0,0 +1,51 @@
+const childProcess = require('child_process');
+const fs = require('fs');
+const path = require('path');
+
+module.exports = {
+  execNodeJsScriptWithInheritedOutput,
+  execFileWithInheritedOutput
+};
+
+async function execNodeJsScriptWithInheritedOutput(command, args) {
+  return new Promise((resolve, reject) => {
+    const child = childProcess.fork(command, args, { stdio: 'inherit' });
+    child.on('close', code => {
+      if (code !== 0) {
+        reject(new Error(`Child process failed with exit-code ${code}`));
+      }
+      resolve();
+    });
+  });
+}
+
+async function execFileWithInheritedOutput(command, args) {
+  return new Promise((resolve, reject) => {
+    const resolvedCommand = preferLocalDependencies(command);
+    const child = childProcess.spawn(resolvedCommand, args, {
+      stdio: 'inherit'
+    });
+    child.on('exit', code => {
+      if (code !== 0) {
+        reject(new Error(`Child process failed with exit-code ${code}`));
+      }
+      resolve();
+    });
+  });
+}
+
+function preferLocalDependencies(command) {
+  const localCandidate = resolveLocalCandidate(command);
+
+  if (fs.existsSync(localCandidate)) {
+    return localCandidate;
+  }
+  return command;
+}
+
+function resolveLocalCandidate(command) {
+  if (process.platform === 'win32') {
+    return path.join('node_modules', '.bin', command + '.cmd');
+  }
+  return path.join('node_modules', '.bin', command);
+}

From 1ebce2b53cb62d81954b64f48bc0bc7112395c8a Mon Sep 17 00:00:00 2001
From: Nils Knappmeier <github@knappi.org>
Date: Thu, 12 Dec 2019 23:04:35 +0100
Subject: [PATCH 14/24] test/style: use nyc instead of istanbul, npm audit fix

---
 .istanbul.yml       |    2 -
 Gruntfile.js        |    2 +-
 nyc.config.js       |    9 +
 package-lock.json   | 1116 +++++++++++++++++++++++++++++++++----------
 package.json        |    4 +-
 spec/builtins.js    |   17 +
 tasks/test-mocha.js |   20 +-
 7 files changed, 905 insertions(+), 265 deletions(-)
 delete mode 100644 .istanbul.yml
 create mode 100644 nyc.config.js

diff --git a/.istanbul.yml b/.istanbul.yml
deleted file mode 100644
index 960643ef4..000000000
--- a/.istanbul.yml
+++ /dev/null
@@ -1,2 +0,0 @@
-instrumentation:
-    excludes: ['**/spec/**', '**/handlebars/compiler/parser.js']
diff --git a/Gruntfile.js b/Gruntfile.js
index 84a361581..0326cfc89 100644
--- a/Gruntfile.js
+++ b/Gruntfile.js
@@ -263,7 +263,7 @@ module.exports = function(grunt) {
 
   this.registerTask('amd', ['babel:amd', 'requirejs']);
 
-  this.registerTask('test', ['test:bin', 'test:cov', 'test:check-cov']);
+  this.registerTask('test', ['test:bin', 'test:cov']);
 
   grunt.registerTask('bench', ['metrics']);
 
diff --git a/nyc.config.js b/nyc.config.js
new file mode 100644
index 000000000..f516eb2b4
--- /dev/null
+++ b/nyc.config.js
@@ -0,0 +1,9 @@
+module.exports = {
+  'check-coverage': true,
+  branches: 100,
+  lines: 100,
+  functions: 100,
+  statements: 100,
+  exclude: ['**/spec/**', '**/handlebars/compiler/parser.js'],
+  reporter: 'html'
+};
diff --git a/package-lock.json b/package-lock.json
index 79fc1b9c4..9c79a3d74 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -13,6 +13,67 @@
         "@babel/highlight": "^7.0.0"
       }
     },
+    "@babel/generator": {
+      "version": "7.7.4",
+      "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.7.4.tgz",
+      "integrity": "sha512-m5qo2WgdOJeyYngKImbkyQrnUN1mPceaG5BV+G0E3gWsa4l/jCSryWJdM2x8OuGAOyh+3d5pVYfZWCiNFtynxg==",
+      "dev": true,
+      "requires": {
+        "@babel/types": "^7.7.4",
+        "jsesc": "^2.5.1",
+        "lodash": "^4.17.13",
+        "source-map": "^0.5.0"
+      },
+      "dependencies": {
+        "jsesc": {
+          "version": "2.5.2",
+          "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz",
+          "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==",
+          "dev": true
+        },
+        "lodash": {
+          "version": "4.17.15",
+          "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
+          "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==",
+          "dev": true
+        },
+        "source-map": {
+          "version": "0.5.7",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+          "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
+          "dev": true
+        }
+      }
+    },
+    "@babel/helper-function-name": {
+      "version": "7.7.4",
+      "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.7.4.tgz",
+      "integrity": "sha512-AnkGIdiBhEuiwdoMnKm7jfPfqItZhgRaZfMg1XX3bS25INOnLPjPG1Ppnajh8eqgt5kPJnfqrRHqFqmjKDZLzQ==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-get-function-arity": "^7.7.4",
+        "@babel/template": "^7.7.4",
+        "@babel/types": "^7.7.4"
+      }
+    },
+    "@babel/helper-get-function-arity": {
+      "version": "7.7.4",
+      "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.7.4.tgz",
+      "integrity": "sha512-QTGKEdCkjgzgfJ3bAyRwF4yyT3pg+vDgan8DSivq1eS0gwi+KGKE5x8kRcbeFTb/673mkO5SN1IZfmCfA5o+EA==",
+      "dev": true,
+      "requires": {
+        "@babel/types": "^7.7.4"
+      }
+    },
+    "@babel/helper-split-export-declaration": {
+      "version": "7.7.4",
+      "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.7.4.tgz",
+      "integrity": "sha512-guAg1SXFcVr04Guk9eq0S4/rWS++sbmyqosJzVs8+1fH5NI+ZcmkaSkc7dmtAFbHFva6yRJnjW3yAcGxjueDug==",
+      "dev": true,
+      "requires": {
+        "@babel/types": "^7.7.4"
+      }
+    },
     "@babel/highlight": {
       "version": "7.5.0",
       "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.5.0.tgz",
@@ -61,6 +122,12 @@
         }
       }
     },
+    "@babel/parser": {
+      "version": "7.7.5",
+      "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.7.5.tgz",
+      "integrity": "sha512-KNlOe9+/nk4i29g0VXgl8PEXIRms5xKLJeuZ6UptN0fHv+jDiriG+y94X6qAgWTR0h3KaoM1wK5G5h7MHFRSig==",
+      "dev": true
+    },
     "@babel/runtime": {
       "version": "7.6.3",
       "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.6.3.tgz",
@@ -70,6 +137,88 @@
         "regenerator-runtime": "^0.13.2"
       }
     },
+    "@babel/template": {
+      "version": "7.7.4",
+      "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.7.4.tgz",
+      "integrity": "sha512-qUzihgVPguAzXCK7WXw8pqs6cEwi54s3E+HrejlkuWO6ivMKx9hZl3Y2fSXp9i5HgyWmj7RKP+ulaYnKM4yYxw==",
+      "dev": true,
+      "requires": {
+        "@babel/code-frame": "^7.0.0",
+        "@babel/parser": "^7.7.4",
+        "@babel/types": "^7.7.4"
+      }
+    },
+    "@babel/traverse": {
+      "version": "7.7.4",
+      "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.7.4.tgz",
+      "integrity": "sha512-P1L58hQyupn8+ezVA2z5KBm4/Zr4lCC8dwKCMYzsa5jFMDMQAzaBNy9W5VjB+KAmBjb40U7a/H6ao+Xo+9saIw==",
+      "dev": true,
+      "requires": {
+        "@babel/code-frame": "^7.5.5",
+        "@babel/generator": "^7.7.4",
+        "@babel/helper-function-name": "^7.7.4",
+        "@babel/helper-split-export-declaration": "^7.7.4",
+        "@babel/parser": "^7.7.4",
+        "@babel/types": "^7.7.4",
+        "debug": "^4.1.0",
+        "globals": "^11.1.0",
+        "lodash": "^4.17.13"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "4.1.1",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
+          "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
+          "dev": true,
+          "requires": {
+            "ms": "^2.1.1"
+          }
+        },
+        "globals": {
+          "version": "11.12.0",
+          "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
+          "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
+          "dev": true
+        },
+        "lodash": {
+          "version": "4.17.15",
+          "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
+          "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==",
+          "dev": true
+        },
+        "ms": {
+          "version": "2.1.2",
+          "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+          "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+          "dev": true
+        }
+      }
+    },
+    "@babel/types": {
+      "version": "7.7.4",
+      "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.7.4.tgz",
+      "integrity": "sha512-cz5Ji23KCi4T+YIE/BolWosrJuSmoZeN1EFnRtBwF+KKLi8GG/Z2c2hOJJeCXPk4mwk4QFvTmwIodJowXgttRA==",
+      "dev": true,
+      "requires": {
+        "esutils": "^2.0.2",
+        "lodash": "^4.17.13",
+        "to-fast-properties": "^2.0.0"
+      },
+      "dependencies": {
+        "lodash": {
+          "version": "4.17.15",
+          "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
+          "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==",
+          "dev": true
+        },
+        "to-fast-properties": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
+          "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=",
+          "dev": true
+        }
+      }
+    },
     "@knappi/grunt-saucelabs": {
       "version": "9.0.2",
       "resolved": "https://registry.npmjs.org/@knappi/grunt-saucelabs/-/grunt-saucelabs-9.0.2.tgz",
@@ -393,6 +542,21 @@
         "normalize-path": "^2.0.0"
       }
     },
+    "append-transform": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-1.0.0.tgz",
+      "integrity": "sha512-P009oYkeHyU742iSZJzZZywj4QRJdnTWffaKuJQLablCZ1uz6/cW4yaRgcDaoQ+uwOxxnt0gRUcwfsNP2ri0gw==",
+      "dev": true,
+      "requires": {
+        "default-require-extensions": "^2.0.0"
+      }
+    },
+    "archy": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz",
+      "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=",
+      "dev": true
+    },
     "argparse": {
       "version": "1.0.10",
       "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
@@ -676,6 +840,15 @@
         "try-resolve": "^1.0.0"
       },
       "dependencies": {
+        "minimatch": {
+          "version": "2.0.10",
+          "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-2.0.10.tgz",
+          "integrity": "sha1-jQh8OcazjAAbl/ynzm0OHoCvusc=",
+          "dev": true,
+          "requires": {
+            "brace-expansion": "^1.0.0"
+          }
+        },
         "source-map": {
           "version": "0.5.7",
           "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
@@ -1120,6 +1293,18 @@
         }
       }
     },
+    "caching-transform": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-3.0.2.tgz",
+      "integrity": "sha512-Mtgcv3lh3U0zRii/6qVgQODdPA4G3zhG+jtbCWj39RXuUFTMzH0vcdMtaJS1jPowd+It2Pqr6y3NJMQqOqCE2w==",
+      "dev": true,
+      "requires": {
+        "hasha": "^3.0.0",
+        "make-dir": "^2.0.0",
+        "package-hash": "^3.0.0",
+        "write-file-atomic": "^2.4.2"
+      }
+    },
     "caller-callsite": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz",
@@ -1462,6 +1647,12 @@
       "resolved": "https://registry.npmjs.org/commander/-/commander-2.19.0.tgz",
       "integrity": "sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg=="
     },
+    "commondir": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz",
+      "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=",
+      "dev": true
+    },
     "commoner": {
       "version": "0.10.8",
       "resolved": "https://registry.npmjs.org/commoner/-/commoner-0.10.8.tgz",
@@ -1884,6 +2075,27 @@
         }
       }
     },
+    "cp-file": {
+      "version": "6.2.0",
+      "resolved": "https://registry.npmjs.org/cp-file/-/cp-file-6.2.0.tgz",
+      "integrity": "sha512-fmvV4caBnofhPe8kOcitBwSn2f39QLjnAnGq3gO9dfd75mUytzKNZB1hde6QHunW2Rt+OwuBOMc3i1tNElbszA==",
+      "dev": true,
+      "requires": {
+        "graceful-fs": "^4.1.2",
+        "make-dir": "^2.0.0",
+        "nested-error-stacks": "^2.0.0",
+        "pify": "^4.0.1",
+        "safe-buffer": "^5.0.1"
+      },
+      "dependencies": {
+        "pify": {
+          "version": "4.0.1",
+          "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz",
+          "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==",
+          "dev": true
+        }
+      }
+    },
     "cross-spawn": {
       "version": "6.0.5",
       "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz",
@@ -1991,6 +2203,23 @@
       "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=",
       "dev": true
     },
+    "default-require-extensions": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-2.0.0.tgz",
+      "integrity": "sha1-9fj7sYp9bVCyH2QfZJ67Uiz+JPc=",
+      "dev": true,
+      "requires": {
+        "strip-bom": "^3.0.0"
+      },
+      "dependencies": {
+        "strip-bom": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
+          "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=",
+          "dev": true
+        }
+      }
+    },
     "define-property": {
       "version": "2.0.2",
       "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz",
@@ -2489,6 +2718,12 @@
         "is-arrayish": "^0.2.1"
       }
     },
+    "es6-error": {
+      "version": "4.1.1",
+      "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz",
+      "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==",
+      "dev": true
+    },
     "es6-promise": {
       "version": "4.2.8",
       "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz",
@@ -2516,73 +2751,6 @@
       "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
       "dev": true
     },
-    "escodegen": {
-      "version": "1.7.1",
-      "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.7.1.tgz",
-      "integrity": "sha1-MOz89mypjcZ80v0WKr626vqM5vw=",
-      "dev": true,
-      "requires": {
-        "esprima": "^1.2.2",
-        "estraverse": "^1.9.1",
-        "esutils": "^2.0.2",
-        "optionator": "^0.5.0",
-        "source-map": "~0.2.0"
-      },
-      "dependencies": {
-        "esprima": {
-          "version": "1.2.5",
-          "resolved": "https://registry.npmjs.org/esprima/-/esprima-1.2.5.tgz",
-          "integrity": "sha1-CZNQL+r2aBODJXVvMPmlH+7sEek=",
-          "dev": true
-        },
-        "estraverse": {
-          "version": "1.9.3",
-          "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-1.9.3.tgz",
-          "integrity": "sha1-r2fy3JIlgkFZUJJgkaQAXSnJu0Q=",
-          "dev": true
-        },
-        "fast-levenshtein": {
-          "version": "1.0.7",
-          "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-1.0.7.tgz",
-          "integrity": "sha1-AXjc3uAjuSkFGTrwlZ6KdjnP3Lk=",
-          "dev": true
-        },
-        "levn": {
-          "version": "0.2.5",
-          "resolved": "https://registry.npmjs.org/levn/-/levn-0.2.5.tgz",
-          "integrity": "sha1-uo0znQykphDjo/FFucr0iAcVUFQ=",
-          "dev": true,
-          "requires": {
-            "prelude-ls": "~1.1.0",
-            "type-check": "~0.3.1"
-          }
-        },
-        "optionator": {
-          "version": "0.5.0",
-          "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.5.0.tgz",
-          "integrity": "sha1-t1qJlaLUF98ltuTjhi9QqohlE2g=",
-          "dev": true,
-          "requires": {
-            "deep-is": "~0.1.2",
-            "fast-levenshtein": "~1.0.0",
-            "levn": "~0.2.5",
-            "prelude-ls": "~1.1.1",
-            "type-check": "~0.3.1",
-            "wordwrap": "~0.0.2"
-          }
-        },
-        "source-map": {
-          "version": "0.2.0",
-          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.2.0.tgz",
-          "integrity": "sha1-2rc/vPwrqBm03gO9b26qSBZLP50=",
-          "dev": true,
-          "optional": true,
-          "requires": {
-            "amdefine": ">=0.0.4"
-          }
-        }
-      }
-    },
     "eslint": {
       "version": "6.7.2",
       "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.7.2.tgz",
@@ -3304,16 +3472,6 @@
       "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=",
       "dev": true
     },
-    "fileset": {
-      "version": "0.2.1",
-      "resolved": "https://registry.npmjs.org/fileset/-/fileset-0.2.1.tgz",
-      "integrity": "sha1-WI74lzxmI7KnbfRlEFaWuWqsgGc=",
-      "dev": true,
-      "requires": {
-        "glob": "5.x",
-        "minimatch": "2.x"
-      }
-    },
     "fill-range": {
       "version": "2.2.4",
       "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.4.tgz",
@@ -3342,6 +3500,37 @@
         "unpipe": "~1.0.0"
       }
     },
+    "find-cache-dir": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz",
+      "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==",
+      "dev": true,
+      "requires": {
+        "commondir": "^1.0.1",
+        "make-dir": "^2.0.0",
+        "pkg-dir": "^3.0.0"
+      },
+      "dependencies": {
+        "find-up": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
+          "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
+          "dev": true,
+          "requires": {
+            "locate-path": "^3.0.0"
+          }
+        },
+        "pkg-dir": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz",
+          "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==",
+          "dev": true,
+          "requires": {
+            "find-up": "^3.0.0"
+          }
+        }
+      }
+    },
     "find-up": {
       "version": "1.1.2",
       "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz",
@@ -3449,6 +3638,28 @@
         "for-in": "^1.0.1"
       }
     },
+    "foreground-child": {
+      "version": "1.5.6",
+      "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-1.5.6.tgz",
+      "integrity": "sha1-T9ca0t/elnibmApcCilZN8svXOk=",
+      "dev": true,
+      "requires": {
+        "cross-spawn": "^4",
+        "signal-exit": "^3.0.0"
+      },
+      "dependencies": {
+        "cross-spawn": {
+          "version": "4.0.2",
+          "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-4.0.2.tgz",
+          "integrity": "sha1-e5JHYhwjrf3ThWAEqCPL45dCTUE=",
+          "dev": true,
+          "requires": {
+            "lru-cache": "^4.0.1",
+            "which": "^1.2.9"
+          }
+        }
+      }
+    },
     "forever-agent": {
       "version": "0.6.1",
       "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
@@ -4268,9 +4479,9 @@
           }
         },
         "lodash": {
-          "version": "4.17.11",
-          "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz",
-          "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==",
+          "version": "4.17.15",
+          "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
+          "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==",
           "dev": true
         },
         "minimatch": {
@@ -4297,9 +4508,9 @@
       "dev": true
     },
     "grunt": {
-      "version": "1.0.3",
-      "resolved": "https://registry.npmjs.org/grunt/-/grunt-1.0.3.tgz",
-      "integrity": "sha512-/JzmZNPfKorlCrrmxWqQO4JVodO+DVd5XX4DkocL/1WlLlKVLE9+SdEIempOAxDhWPysLle6afvn/hg7Ck2k9g==",
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/grunt/-/grunt-1.0.4.tgz",
+      "integrity": "sha512-PYsMOrOC+MsdGEkFVwMaMyc6Ob7pKmq+deg1Sjr+vvMWp35sztfwKE7qoN51V+UEtHsyNuMcGdgMLFkBHvMxHQ==",
       "dev": true,
       "requires": {
         "coffeescript": "~1.10.0",
@@ -4313,7 +4524,7 @@
         "grunt-legacy-log": "~2.0.0",
         "grunt-legacy-util": "~1.1.1",
         "iconv-lite": "~0.4.13",
-        "js-yaml": "~3.5.2",
+        "js-yaml": "~3.13.0",
         "minimatch": "~3.0.2",
         "mkdirp": "~0.5.1",
         "nopt": "~3.0.6",
@@ -4353,15 +4564,6 @@
             "resolve": "~1.1.0"
           }
         },
-        "minimatch": {
-          "version": "3.0.4",
-          "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
-          "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
-          "dev": true,
-          "requires": {
-            "brace-expansion": "^1.1.7"
-          }
-        },
         "resolve": {
           "version": "1.1.7",
           "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz",
@@ -4494,9 +4696,9 @@
           "dev": true
         },
         "lodash": {
-          "version": "4.17.11",
-          "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz",
-          "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==",
+          "version": "4.17.15",
+          "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
+          "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==",
           "dev": true
         },
         "source-map": {
@@ -4559,9 +4761,9 @@
           }
         },
         "lodash": {
-          "version": "4.17.11",
-          "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz",
-          "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==",
+          "version": "4.17.15",
+          "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
+          "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==",
           "dev": true
         }
       }
@@ -4585,9 +4787,9 @@
       },
       "dependencies": {
         "lodash": {
-          "version": "4.17.11",
-          "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz",
-          "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==",
+          "version": "4.17.15",
+          "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
+          "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==",
           "dev": true
         }
       }
@@ -4623,9 +4825,9 @@
           }
         },
         "lodash": {
-          "version": "4.17.11",
-          "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz",
-          "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==",
+          "version": "4.17.15",
+          "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
+          "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==",
           "dev": true
         },
         "supports-color": {
@@ -4655,9 +4857,9 @@
       },
       "dependencies": {
         "lodash": {
-          "version": "4.17.11",
-          "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz",
-          "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==",
+          "version": "4.17.15",
+          "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
+          "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==",
           "dev": true
         }
       }
@@ -4672,9 +4874,9 @@
       },
       "dependencies": {
         "lodash": {
-          "version": "4.17.11",
-          "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz",
-          "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==",
+          "version": "4.17.15",
+          "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
+          "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==",
           "dev": true
         }
       }
@@ -4689,35 +4891,6 @@
         "concat-stream": "^1.4.1"
       }
     },
-    "handlebars": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.1.0.tgz",
-      "integrity": "sha512-l2jRuU1NAWK6AW5qqcTATWQJvNPEwkM7NEKSiv/gqOsoSQbVoWyqVEY5GS+XPQ88zLNmqASRpzfdm8d79hJS+w==",
-      "dev": true,
-      "requires": {
-        "async": "^2.5.0",
-        "optimist": "^0.6.1",
-        "source-map": "^0.6.1",
-        "uglify-js": "^3.1.4"
-      },
-      "dependencies": {
-        "async": {
-          "version": "2.6.2",
-          "resolved": "https://registry.npmjs.org/async/-/async-2.6.2.tgz",
-          "integrity": "sha512-H1qVYh1MYhEEFLsP97cVKqCGo7KfCyTt6uEWqsTBr9SO84oK9Uwbyd/yCW+6rKJLHksBNUVWZDAjfS+Ccx0Bbg==",
-          "dev": true,
-          "requires": {
-            "lodash": "^4.17.11"
-          }
-        },
-        "lodash": {
-          "version": "4.17.11",
-          "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz",
-          "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==",
-          "dev": true
-        }
-      }
-    },
     "har-schema": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
@@ -4835,9 +5008,18 @@
         }
       }
     },
-    "he": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz",
+    "hasha": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/hasha/-/hasha-3.0.0.tgz",
+      "integrity": "sha1-UqMvq4Vp1BymmmH/GiFPjrfIvTk=",
+      "dev": true,
+      "requires": {
+        "is-stream": "^1.0.1"
+      }
+    },
+    "he": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz",
       "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=",
       "dev": true
     },
@@ -4937,9 +5119,9 @@
           }
         },
         "lodash": {
-          "version": "4.17.11",
-          "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz",
-          "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==",
+          "version": "4.17.15",
+          "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
+          "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==",
           "dev": true
         }
       }
@@ -4968,9 +5150,9 @@
       "dev": true
     },
     "https-proxy-agent": {
-      "version": "2.2.2",
-      "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.2.tgz",
-      "integrity": "sha512-c8Ndjc9Bkpfx/vCJueCPy0jlP4ccCCSNDp8xwCZzPjKJUm+B+u9WX2x98Qx4n1PiMNTWo3D7KK5ifNV/yJyRzg==",
+      "version": "2.2.4",
+      "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz",
+      "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==",
       "dev": true,
       "requires": {
         "agent-base": "^4.3.0",
@@ -5647,69 +5829,119 @@
       "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=",
       "dev": true
     },
-    "istanbul": {
-      "version": "0.3.22",
-      "resolved": "https://registry.npmjs.org/istanbul/-/istanbul-0.3.22.tgz",
-      "integrity": "sha1-PhZNhQIf4ZyYXR8OfvDD4i0BLrY=",
+    "istanbul-lib-coverage": {
+      "version": "2.0.5",
+      "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz",
+      "integrity": "sha512-8aXznuEPCJvGnMSRft4udDRDtb1V3pkQkMMI5LI+6HuQz5oQ4J2UFn1H82raA3qJtyOLkkwVqICBQkjnGtn5mA==",
+      "dev": true
+    },
+    "istanbul-lib-hook": {
+      "version": "2.0.7",
+      "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-2.0.7.tgz",
+      "integrity": "sha512-vrRztU9VRRFDyC+aklfLoeXyNdTfga2EI3udDGn4cZ6fpSXpHLV9X6CHvfoMCPtggg8zvDDmC4b9xfu0z6/llA==",
       "dev": true,
       "requires": {
-        "abbrev": "1.0.x",
-        "async": "1.x",
-        "escodegen": "1.7.x",
-        "esprima": "2.5.x",
-        "fileset": "0.2.x",
-        "handlebars": "^4.0.1",
-        "js-yaml": "3.x",
-        "mkdirp": "0.5.x",
-        "nopt": "3.x",
-        "once": "1.x",
-        "resolve": "1.1.x",
-        "supports-color": "^3.1.0",
-        "which": "^1.1.1",
-        "wordwrap": "^1.0.0"
+        "append-transform": "^1.0.0"
+      }
+    },
+    "istanbul-lib-instrument": {
+      "version": "3.3.0",
+      "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-3.3.0.tgz",
+      "integrity": "sha512-5nnIN4vo5xQZHdXno/YDXJ0G+I3dAm4XgzfSVTPLQpj/zAV2dV6Juy0yaf10/zrJOJeHoN3fraFe+XRq2bFVZA==",
+      "dev": true,
+      "requires": {
+        "@babel/generator": "^7.4.0",
+        "@babel/parser": "^7.4.3",
+        "@babel/template": "^7.4.0",
+        "@babel/traverse": "^7.4.3",
+        "@babel/types": "^7.4.0",
+        "istanbul-lib-coverage": "^2.0.5",
+        "semver": "^6.0.0"
       },
       "dependencies": {
-        "abbrev": {
-          "version": "1.0.9",
-          "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz",
-          "integrity": "sha1-kbR5JYinc4wl813W9jdSovh3YTU=",
-          "dev": true
-        },
-        "esprima": {
-          "version": "2.5.0",
-          "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.5.0.tgz",
-          "integrity": "sha1-84ekb9NEwbGjm6+MIL+0O20AWMw=",
-          "dev": true
-        },
-        "has-flag": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz",
-          "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=",
-          "dev": true
-        },
-        "resolve": {
-          "version": "1.1.7",
-          "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz",
-          "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=",
+        "semver": {
+          "version": "6.3.0",
+          "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+          "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
           "dev": true
-        },
+        }
+      }
+    },
+    "istanbul-lib-report": {
+      "version": "2.0.8",
+      "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-2.0.8.tgz",
+      "integrity": "sha512-fHBeG573EIihhAblwgxrSenp0Dby6tJMFR/HvlerBsrCTD5bkUuoNtn3gVh29ZCS824cGGBPn7Sg7cNk+2xUsQ==",
+      "dev": true,
+      "requires": {
+        "istanbul-lib-coverage": "^2.0.5",
+        "make-dir": "^2.1.0",
+        "supports-color": "^6.1.0"
+      },
+      "dependencies": {
         "supports-color": {
-          "version": "3.2.3",
-          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz",
-          "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=",
+          "version": "6.1.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
+          "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
           "dev": true,
           "requires": {
-            "has-flag": "^1.0.0"
+            "has-flag": "^3.0.0"
+          }
+        }
+      }
+    },
+    "istanbul-lib-source-maps": {
+      "version": "3.0.6",
+      "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-3.0.6.tgz",
+      "integrity": "sha512-R47KzMtDJH6X4/YW9XTx+jrLnZnscW4VpNN+1PViSYTejLVPWv7oov+Duf8YQSPyVRUvueQqz1TcsC6mooZTXw==",
+      "dev": true,
+      "requires": {
+        "debug": "^4.1.1",
+        "istanbul-lib-coverage": "^2.0.5",
+        "make-dir": "^2.1.0",
+        "rimraf": "^2.6.3",
+        "source-map": "^0.6.1"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "4.1.1",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
+          "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
+          "dev": true,
+          "requires": {
+            "ms": "^2.1.1"
           }
         },
-        "wordwrap": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
-          "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=",
+        "ms": {
+          "version": "2.1.2",
+          "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+          "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
           "dev": true
         }
       }
     },
+    "istanbul-reports": {
+      "version": "2.2.6",
+      "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-2.2.6.tgz",
+      "integrity": "sha512-SKi4rnMyLBKe0Jy2uUdx28h8oG7ph2PPuQPvIAh31d+Ci+lSiEu4C+h3oBPuJ9+mPKhOyW0M8gY4U5NM1WLeXA==",
+      "dev": true,
+      "requires": {
+        "handlebars": "^4.1.2"
+      },
+      "dependencies": {
+        "handlebars": {
+          "version": "4.5.3",
+          "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.5.3.tgz",
+          "integrity": "sha512-3yPecJoJHK/4c6aZhSvxOyG4vJKDshV36VHp0iVCDVh7o9w2vwi3NSnL2MMPj3YdduqaBcu7cGbggJQM0br9xA==",
+          "dev": true,
+          "requires": {
+            "neo-async": "^2.6.0",
+            "optimist": "^0.6.1",
+            "source-map": "^0.6.1",
+            "uglify-js": "^3.1.4"
+          }
+        }
+      }
+    },
     "jison": {
       "version": "0.3.12",
       "resolved": "https://registry.npmjs.org/jison/-/jison-0.3.12.tgz",
@@ -5734,19 +5966,19 @@
       "dev": true
     },
     "js-yaml": {
-      "version": "3.5.5",
-      "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.5.5.tgz",
-      "integrity": "sha1-A3fDgBfKvHMisNH7zSWkkWQfL74=",
+      "version": "3.13.1",
+      "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz",
+      "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==",
       "dev": true,
       "requires": {
-        "argparse": "^1.0.2",
-        "esprima": "^2.6.0"
+        "argparse": "^1.0.7",
+        "esprima": "^4.0.0"
       },
       "dependencies": {
         "esprima": {
-          "version": "2.7.3",
-          "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz",
-          "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=",
+          "version": "4.0.1",
+          "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
+          "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
           "dev": true
         }
       }
@@ -6608,6 +6840,12 @@
       "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=",
       "dev": true
     },
+    "lodash.flattendeep": {
+      "version": "4.4.0",
+      "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz",
+      "integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=",
+      "dev": true
+    },
     "lodash.memoize": {
       "version": "4.1.2",
       "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz",
@@ -6714,6 +6952,34 @@
         "signal-exit": "^3.0.0"
       }
     },
+    "lru-cache": {
+      "version": "4.1.5",
+      "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz",
+      "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==",
+      "dev": true,
+      "requires": {
+        "pseudomap": "^1.0.2",
+        "yallist": "^2.1.2"
+      }
+    },
+    "make-dir": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz",
+      "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==",
+      "dev": true,
+      "requires": {
+        "pify": "^4.0.1",
+        "semver": "^5.6.0"
+      },
+      "dependencies": {
+        "pify": {
+          "version": "4.0.1",
+          "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz",
+          "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==",
+          "dev": true
+        }
+      }
+    },
     "make-iterator": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/make-iterator/-/make-iterator-1.0.1.tgz",
@@ -6861,6 +7127,15 @@
       "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=",
       "dev": true
     },
+    "merge-source-map": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/merge-source-map/-/merge-source-map-1.1.0.tgz",
+      "integrity": "sha512-Qkcp7P2ygktpMPh2mCQZaf3jhN6D3Z/qVZHSdWvQ+2Ef5HgRAPBO57A77+ENm0CPx2+1Ce/MYKi3ymqdfuqibw==",
+      "dev": true,
+      "requires": {
+        "source-map": "^0.6.1"
+      }
+    },
     "merge-stream": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
@@ -6928,12 +7203,12 @@
       "dev": true
     },
     "minimatch": {
-      "version": "2.0.10",
-      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-2.0.10.tgz",
-      "integrity": "sha1-jQh8OcazjAAbl/ynzm0OHoCvusc=",
+      "version": "3.0.4",
+      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
+      "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
       "dev": true,
       "requires": {
-        "brace-expansion": "^1.0.0"
+        "brace-expansion": "^1.1.7"
       }
     },
     "minimist": {
@@ -6942,9 +7217,9 @@
       "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8="
     },
     "mixin-deep": {
-      "version": "1.3.1",
-      "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.1.tgz",
-      "integrity": "sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ==",
+      "version": "1.3.2",
+      "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz",
+      "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==",
       "dev": true,
       "requires": {
         "for-in": "^1.0.2",
@@ -7147,6 +7422,12 @@
       "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.0.tgz",
       "integrity": "sha512-MFh0d/Wa7vkKO3Y3LlacqAEeHK0mckVqzDieUKTT+KGxi+zIpeVsFxymkIiRpbpDziHc290Xr9A1O4Om7otoRA=="
     },
+    "nested-error-stacks": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/nested-error-stacks/-/nested-error-stacks-2.1.0.tgz",
+      "integrity": "sha512-AO81vsIO1k1sM4Zrd6Hu7regmJN1NSiAja10gc4bX3F0wd+9rQmcuHQaHVQCYIEC8iFXnE+mavh23GOt7wBgug==",
+      "dev": true
+    },
     "nice-try": {
       "version": "1.0.5",
       "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz",
@@ -7303,6 +7584,204 @@
       "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=",
       "dev": true
     },
+    "nyc": {
+      "version": "14.1.1",
+      "resolved": "https://registry.npmjs.org/nyc/-/nyc-14.1.1.tgz",
+      "integrity": "sha512-OI0vm6ZGUnoGZv/tLdZ2esSVzDwUC88SNs+6JoSOMVxA+gKMB8Tk7jBwgemLx4O40lhhvZCVw1C+OYLOBOPXWw==",
+      "dev": true,
+      "requires": {
+        "archy": "^1.0.0",
+        "caching-transform": "^3.0.2",
+        "convert-source-map": "^1.6.0",
+        "cp-file": "^6.2.0",
+        "find-cache-dir": "^2.1.0",
+        "find-up": "^3.0.0",
+        "foreground-child": "^1.5.6",
+        "glob": "^7.1.3",
+        "istanbul-lib-coverage": "^2.0.5",
+        "istanbul-lib-hook": "^2.0.7",
+        "istanbul-lib-instrument": "^3.3.0",
+        "istanbul-lib-report": "^2.0.8",
+        "istanbul-lib-source-maps": "^3.0.6",
+        "istanbul-reports": "^2.2.4",
+        "js-yaml": "^3.13.1",
+        "make-dir": "^2.1.0",
+        "merge-source-map": "^1.1.0",
+        "resolve-from": "^4.0.0",
+        "rimraf": "^2.6.3",
+        "signal-exit": "^3.0.2",
+        "spawn-wrap": "^1.4.2",
+        "test-exclude": "^5.2.3",
+        "uuid": "^3.3.2",
+        "yargs": "^13.2.2",
+        "yargs-parser": "^13.0.0"
+      },
+      "dependencies": {
+        "ansi-regex": {
+          "version": "4.1.0",
+          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
+          "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
+          "dev": true
+        },
+        "ansi-styles": {
+          "version": "3.2.1",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+          "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+          "dev": true,
+          "requires": {
+            "color-convert": "^1.9.0"
+          }
+        },
+        "camelcase": {
+          "version": "5.3.1",
+          "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
+          "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
+          "dev": true
+        },
+        "cliui": {
+          "version": "5.0.0",
+          "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz",
+          "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==",
+          "dev": true,
+          "requires": {
+            "string-width": "^3.1.0",
+            "strip-ansi": "^5.2.0",
+            "wrap-ansi": "^5.1.0"
+          }
+        },
+        "emoji-regex": {
+          "version": "7.0.3",
+          "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz",
+          "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==",
+          "dev": true
+        },
+        "esprima": {
+          "version": "4.0.1",
+          "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
+          "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
+          "dev": true
+        },
+        "find-up": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
+          "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
+          "dev": true,
+          "requires": {
+            "locate-path": "^3.0.0"
+          }
+        },
+        "get-caller-file": {
+          "version": "2.0.5",
+          "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
+          "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
+          "dev": true
+        },
+        "glob": {
+          "version": "7.1.6",
+          "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
+          "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
+          "dev": true,
+          "requires": {
+            "fs.realpath": "^1.0.0",
+            "inflight": "^1.0.4",
+            "inherits": "2",
+            "minimatch": "^3.0.4",
+            "once": "^1.3.0",
+            "path-is-absolute": "^1.0.0"
+          }
+        },
+        "js-yaml": {
+          "version": "3.13.1",
+          "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz",
+          "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==",
+          "dev": true,
+          "requires": {
+            "argparse": "^1.0.7",
+            "esprima": "^4.0.0"
+          }
+        },
+        "minimatch": {
+          "version": "3.0.4",
+          "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
+          "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
+          "dev": true,
+          "requires": {
+            "brace-expansion": "^1.1.7"
+          }
+        },
+        "require-main-filename": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz",
+          "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==",
+          "dev": true
+        },
+        "string-width": {
+          "version": "3.1.0",
+          "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
+          "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
+          "dev": true,
+          "requires": {
+            "emoji-regex": "^7.0.1",
+            "is-fullwidth-code-point": "^2.0.0",
+            "strip-ansi": "^5.1.0"
+          }
+        },
+        "strip-ansi": {
+          "version": "5.2.0",
+          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
+          "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
+          "dev": true,
+          "requires": {
+            "ansi-regex": "^4.1.0"
+          }
+        },
+        "wrap-ansi": {
+          "version": "5.1.0",
+          "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz",
+          "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "^3.2.0",
+            "string-width": "^3.0.0",
+            "strip-ansi": "^5.0.0"
+          }
+        },
+        "y18n": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz",
+          "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==",
+          "dev": true
+        },
+        "yargs": {
+          "version": "13.3.0",
+          "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.0.tgz",
+          "integrity": "sha512-2eehun/8ALW8TLoIl7MVaRUrg+yCnenu8B4kBlRxj3GJGDKU1Og7sMXPNm1BYyM1DOJmTZ4YeN/Nwxv+8XJsUA==",
+          "dev": true,
+          "requires": {
+            "cliui": "^5.0.0",
+            "find-up": "^3.0.0",
+            "get-caller-file": "^2.0.1",
+            "require-directory": "^2.1.1",
+            "require-main-filename": "^2.0.0",
+            "set-blocking": "^2.0.0",
+            "string-width": "^3.0.0",
+            "which-module": "^2.0.0",
+            "y18n": "^4.0.0",
+            "yargs-parser": "^13.1.1"
+          }
+        },
+        "yargs-parser": {
+          "version": "13.1.1",
+          "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.1.tgz",
+          "integrity": "sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ==",
+          "dev": true,
+          "requires": {
+            "camelcase": "^5.0.0",
+            "decamelize": "^1.2.0"
+          }
+        }
+      }
+    },
     "oauth-sign": {
       "version": "0.9.0",
       "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
@@ -7633,6 +8112,18 @@
       "integrity": "sha1-yyhoVA4xPWHeWPr741zpAE1VQOY=",
       "dev": true
     },
+    "package-hash": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/package-hash/-/package-hash-3.0.0.tgz",
+      "integrity": "sha512-lOtmukMDVvtkL84rJHI7dpTYq+0rli8N2wlnqUcBuDWCfVhRUfOmnR9SsoHFMLpACvEV60dX7rd0rFaYDZI+FA==",
+      "dev": true,
+      "requires": {
+        "graceful-fs": "^4.1.15",
+        "hasha": "^3.0.0",
+        "lodash.flattendeep": "^4.4.0",
+        "release-zalgo": "^1.0.0"
+      }
+    },
     "pako": {
       "version": "0.2.9",
       "resolved": "https://registry.npmjs.org/pako/-/pako-0.2.9.tgz",
@@ -7948,6 +8439,12 @@
       "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=",
       "dev": true
     },
+    "pseudomap": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz",
+      "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=",
+      "dev": true
+    },
     "psl": {
       "version": "1.1.31",
       "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.31.tgz",
@@ -8510,6 +9007,15 @@
         "jsesc": "~0.5.0"
       }
     },
+    "release-zalgo": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz",
+      "integrity": "sha1-CXALflB0Mpc5Mw5TXFqQ+2eFFzA=",
+      "dev": true,
+      "requires": {
+        "es6-error": "^4.0.1"
+      }
+    },
     "remove-trailing-separator": {
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz",
@@ -8858,9 +9364,9 @@
       "dev": true
     },
     "set-value": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz",
-      "integrity": "sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==",
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz",
+      "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==",
       "dev": true,
       "requires": {
         "extend-shallow": "^2.0.1",
@@ -9205,6 +9711,20 @@
       "integrity": "sha1-YvXpRmmBwbeW3Fkpk34RycaSG9A=",
       "dev": true
     },
+    "spawn-wrap": {
+      "version": "1.4.3",
+      "resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-1.4.3.tgz",
+      "integrity": "sha512-IgB8md0QW/+tWqcavuFgKYR/qIRvJkRLPJDFaoXtLLUaVcCDK0+HeFTkmQHj3eprcYhc+gOl0aEA1w7qZlYezw==",
+      "dev": true,
+      "requires": {
+        "foreground-child": "^1.5.6",
+        "mkdirp": "^0.5.0",
+        "os-homedir": "^1.0.1",
+        "rimraf": "^2.6.2",
+        "signal-exit": "^3.0.2",
+        "which": "^1.3.0"
+      }
+    },
     "spdx-correct": {
       "version": "3.1.0",
       "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz",
@@ -9532,6 +10052,122 @@
       "integrity": "sha1-KcNXB8K3DlDQdIK10gLo7URtr9Q=",
       "dev": true
     },
+    "test-exclude": {
+      "version": "5.2.3",
+      "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-5.2.3.tgz",
+      "integrity": "sha512-M+oxtseCFO3EDtAaGH7iiej3CBkzXqFMbzqYAACdzKui4eZA+pq3tZEwChvOdNfa7xxy8BfbmgJSIr43cC/+2g==",
+      "dev": true,
+      "requires": {
+        "glob": "^7.1.3",
+        "minimatch": "^3.0.4",
+        "read-pkg-up": "^4.0.0",
+        "require-main-filename": "^2.0.0"
+      },
+      "dependencies": {
+        "find-up": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
+          "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
+          "dev": true,
+          "requires": {
+            "locate-path": "^3.0.0"
+          }
+        },
+        "glob": {
+          "version": "7.1.6",
+          "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
+          "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
+          "dev": true,
+          "requires": {
+            "fs.realpath": "^1.0.0",
+            "inflight": "^1.0.4",
+            "inherits": "2",
+            "minimatch": "^3.0.4",
+            "once": "^1.3.0",
+            "path-is-absolute": "^1.0.0"
+          }
+        },
+        "load-json-file": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz",
+          "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=",
+          "dev": true,
+          "requires": {
+            "graceful-fs": "^4.1.2",
+            "parse-json": "^4.0.0",
+            "pify": "^3.0.0",
+            "strip-bom": "^3.0.0"
+          }
+        },
+        "minimatch": {
+          "version": "3.0.4",
+          "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
+          "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
+          "dev": true,
+          "requires": {
+            "brace-expansion": "^1.1.7"
+          }
+        },
+        "parse-json": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz",
+          "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=",
+          "dev": true,
+          "requires": {
+            "error-ex": "^1.3.1",
+            "json-parse-better-errors": "^1.0.1"
+          }
+        },
+        "path-type": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz",
+          "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==",
+          "dev": true,
+          "requires": {
+            "pify": "^3.0.0"
+          }
+        },
+        "pify": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
+          "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
+          "dev": true
+        },
+        "read-pkg": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz",
+          "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=",
+          "dev": true,
+          "requires": {
+            "load-json-file": "^4.0.0",
+            "normalize-package-data": "^2.3.2",
+            "path-type": "^3.0.0"
+          }
+        },
+        "read-pkg-up": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-4.0.0.tgz",
+          "integrity": "sha512-6etQSH7nJGsK0RbG/2TeDzZFa8shjQ1um+SwQQ5cwKy0dhSXdOncEhb1CPpvQG4h7FyOV6EB6YlV0yJvZQNAkA==",
+          "dev": true,
+          "requires": {
+            "find-up": "^3.0.0",
+            "read-pkg": "^3.0.0"
+          }
+        },
+        "require-main-filename": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz",
+          "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==",
+          "dev": true
+        },
+        "strip-bom": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
+          "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=",
+          "dev": true
+        }
+      }
+    },
     "text-table": {
       "version": "0.2.0",
       "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
@@ -9916,38 +10552,15 @@
       }
     },
     "union-value": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz",
-      "integrity": "sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ=",
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz",
+      "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==",
       "dev": true,
       "requires": {
         "arr-union": "^3.1.0",
         "get-value": "^2.0.6",
         "is-extendable": "^0.1.1",
-        "set-value": "^0.4.3"
-      },
-      "dependencies": {
-        "extend-shallow": {
-          "version": "2.0.1",
-          "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
-          "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
-          "dev": true,
-          "requires": {
-            "is-extendable": "^0.1.0"
-          }
-        },
-        "set-value": {
-          "version": "0.4.3",
-          "resolved": "https://registry.npmjs.org/set-value/-/set-value-0.4.3.tgz",
-          "integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=",
-          "dev": true,
-          "requires": {
-            "extend-shallow": "^2.0.1",
-            "is-extendable": "^0.1.1",
-            "is-plain-object": "^2.0.1",
-            "to-object-path": "^0.3.0"
-          }
-        }
+        "set-value": "^2.0.1"
       }
     },
     "universalify": {
@@ -10453,6 +11066,17 @@
         "mkdirp": "^0.5.1"
       }
     },
+    "write-file-atomic": {
+      "version": "2.4.3",
+      "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.3.tgz",
+      "integrity": "sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==",
+      "dev": true,
+      "requires": {
+        "graceful-fs": "^4.1.11",
+        "imurmurhash": "^0.1.4",
+        "signal-exit": "^3.0.2"
+      }
+    },
     "xml2js": {
       "version": "0.4.19",
       "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.19.tgz",
@@ -10481,6 +11105,12 @@
       "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=",
       "dev": true
     },
+    "yallist": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
+      "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=",
+      "dev": true
+    },
     "yargs": {
       "version": "3.27.0",
       "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.27.0.tgz",
diff --git a/package.json b/package.json
index 9ce188bb0..6c8ca555d 100644
--- a/package.json
+++ b/package.json
@@ -44,7 +44,7 @@
     "eslint-config-prettier": "^6.7.0",
     "eslint-plugin-compat": "^3.3.0",
     "eslint-plugin-es5": "^1.4.1",
-    "grunt": "^1.0.3",
+    "grunt": "^1.0.4",
     "grunt-babel": "^5.0.0",
     "grunt-bg-shell": "^2.3.3",
     "grunt-cli": "^1",
@@ -57,12 +57,12 @@
     "grunt-contrib-watch": "^1.1.0",
     "grunt-webpack": "^1.0.8",
     "husky": "^3.1.0",
-    "istanbul": "^0.3.0",
     "jison": "~0.3.0",
     "lint-staged": "^9.5.0",
     "mocha": "^5",
     "mock-stdin": "^0.3.0",
     "mustache": "^2.1.3",
+    "nyc": "^14.1.1",
     "prettier": "^1.19.1",
     "semver": "^5.0.1",
     "sinon": "^7.5.0",
diff --git a/spec/builtins.js b/spec/builtins.js
index d6bc29868..c74092e1b 100644
--- a/spec/builtins.js
+++ b/spec/builtins.js
@@ -710,6 +710,23 @@ describe('builtin helpers', function() {
       shouldCompileTo(string, hash, '');
       equals(true, called);
     });
+
+    it('should pass zero log arguments', function() {
+      var string = '{{log}}';
+      var hash = { blah: 'whee' };
+      var called;
+
+      console.info = console.log = function() {
+        expect(arguments.length).to.equal(0);
+        called = true;
+        console.log = $log;
+      };
+
+      expectTemplate(string)
+        .withInput(hash)
+        .toCompileTo('');
+      expect(called).to.be.true();
+    });
     /* eslint-enable no-console */
   });
 
diff --git a/tasks/test-mocha.js b/tasks/test-mocha.js
index 445a88cf3..b412c8c05 100644
--- a/tasks/test-mocha.js
+++ b/tasks/test-mocha.js
@@ -1,5 +1,6 @@
 const { execNodeJsScriptWithInheritedOutput } = require('./util/exec-file');
 const { createRegisterAsyncTaskFn } = require('./util/async-grunt-task');
+const nodeJs = process.argv0;
 
 module.exports = function(grunt) {
   const registerAsyncTask = createRegisterAsyncTaskFn(grunt);
@@ -9,10 +10,8 @@ module.exports = function(grunt) {
   );
 
   registerAsyncTask('test:cov', async () =>
-    execNodeJsScriptWithInheritedOutput('node_modules/istanbul/lib/cli.js', [
-      'cover',
-      '--source-map',
-      '--',
+    execNodeJsScriptWithInheritedOutput('node_modules/nyc/bin/nyc', [
+      nodeJs,
       './spec/env/runner.js'
     ])
   );
@@ -20,17 +19,4 @@ module.exports = function(grunt) {
   registerAsyncTask('test:min', async () =>
     execNodeJsScriptWithInheritedOutput('./spec/env/runner', ['--min'])
   );
-
-  registerAsyncTask('test:check-cov', async () =>
-    execNodeJsScriptWithInheritedOutput('node_modules/istanbul/lib/cli.js', [
-      'check-coverage',
-      '--statements',
-      '100',
-      '--functions',
-      '100',
-      '--branches',
-      '100',
-      '--lines 100'
-    ])
-  );
 };

From 1ec1737d24a1a37e39ca4c24b0fdb7efd877e628 Mon Sep 17 00:00:00 2001
From: Nils Knappmeier <github@knappi.org>
Date: Sat, 14 Dec 2019 01:49:55 +0100
Subject: [PATCH 15/24] test/style: refactor remaining grunt tasks to use
 promises instead of callbacks

---
 tasks/metrics.js  |  37 +++++-----
 tasks/publish.js  | 170 ++++++++++++++++++++++------------------------
 tasks/util/git.js | 155 ++++++++++++++++--------------------------
 tasks/version.js  | 108 ++++++++++++++---------------
 4 files changed, 211 insertions(+), 259 deletions(-)

diff --git a/tasks/metrics.js b/tasks/metrics.js
index bcb76318f..acc3cece4 100644
--- a/tasks/metrics.js
+++ b/tasks/metrics.js
@@ -1,26 +1,29 @@
-const _ = require('underscore'),
-  async = require('neo-async'),
-  metrics = require('../bench');
+const metrics = require('../bench');
+const { createRegisterAsyncTaskFn } = require('./util/async-grunt-task');
 
 module.exports = function(grunt) {
-  grunt.registerTask('metrics', function() {
-    const done = this.async(),
-      execName = grunt.option('name'),
-      events = {};
+  const registerAsyncTask = createRegisterAsyncTaskFn(grunt);
 
-    async.each(
-      _.keys(metrics),
-      function(name, complete) {
-        if (/^_/.test(name) || (execName && name !== execName)) {
-          return complete();
-        }
+  registerAsyncTask('metrics', function() {
+    const onlyExecuteName = grunt.option('name');
+    const events = {};
 
+    const promises = Object.keys(metrics).map(async name => {
+      if (/^_/.test(name)) {
+        return;
+      }
+      if (onlyExecuteName != null && name !== onlyExecuteName) {
+        return;
+      }
+
+      return new Promise(resolve => {
         metrics[name](grunt, function(data) {
           events[name] = data;
-          complete();
+          resolve();
         });
-      },
-      done
-    );
+      });
+    });
+
+    return Promise.all(promises);
   });
 };
diff --git a/tasks/publish.js b/tasks/publish.js
index 207e281fe..54c99f5ca 100644
--- a/tasks/publish.js
+++ b/tasks/publish.js
@@ -1,54 +1,38 @@
-const _ = require('underscore'),
-  async = require('neo-async'),
-  AWS = require('aws-sdk'),
-  git = require('./util/git'),
-  semver = require('semver');
+const AWS = require('aws-sdk');
+const git = require('./util/git');
+const { createRegisterAsyncTaskFn } = require('./util/async-grunt-task');
+const semver = require('semver');
 
 module.exports = function(grunt) {
-  grunt.registerTask('publish:latest', function() {
-    const done = this.async();
-
-    git.debug(function(remotes, branches) {
-      grunt.log.writeln('remotes: ' + remotes);
-      grunt.log.writeln('branches: ' + branches);
-
-      git.commitInfo(function(err, info) {
-        grunt.log.writeln('tag: ' + info.tagName);
-
-        const files = [];
-
-        // Publish the master as "latest" and with the commit-id
-        if (info.isMaster) {
-          files.push('-latest');
-          files.push('-' + info.head);
-        }
-
-        // Publish tags by their tag-name
-        if (info.tagName && semver.valid(info.tagName)) {
-          files.push('-' + info.tagName);
-        }
-
-        if (files.length > 0) {
-          initSDK();
-          grunt.log.writeln('publishing files: ' + JSON.stringify(files));
-          publish(fileMap(files), done);
-        } else {
-          // Silently ignore for branches
-          done();
-        }
-      });
-    });
-  });
-  grunt.registerTask('publish:version', function() {
-    const done = this.async();
-    initSDK();
+  const registerAsyncTask = createRegisterAsyncTaskFn(grunt);
 
-    git.commitInfo(function(err, info) {
-      if (!info.tagName) {
-        throw new Error('The current commit must be tagged');
-      }
-      publish(fileMap(['-' + info.tagName]), done);
-    });
+  registerAsyncTask('publish:latest', async () => {
+    grunt.log.writeln('remotes: ' + (await git.remotes()));
+    grunt.log.writeln('branches: ' + (await git.branches()));
+
+    const commitInfo = await git.commitInfo();
+    grunt.log.writeln('tag: ' + commitInfo.tagName);
+
+    const suffixes = [];
+
+    // Publish the master as "latest" and with the commit-id
+    if (commitInfo.isMaster) {
+      suffixes.push('-latest');
+      suffixes.push('-' + commitInfo.headSha);
+    }
+
+    // Publish tags by their tag-name
+    if (commitInfo.tagName && semver.valid(commitInfo.tagName)) {
+      suffixes.push('-' + commitInfo.tagName);
+    }
+
+    if (suffixes.length > 0) {
+      initSDK();
+      grunt.log.writeln(
+        'publishing file-suffixes: ' + JSON.stringify(suffixes)
+      );
+      await publish(suffixes);
+    }
   });
 
   function initSDK() {
@@ -62,45 +46,57 @@ module.exports = function(grunt) {
 
     AWS.config.update({ accessKeyId: key, secretAccessKey: secret });
   }
-  function publish(files, callback) {
-    const s3 = new AWS.S3(),
-      bucket = process.env.S3_BUCKET_NAME;
-
-    async.each(
-      _.keys(files),
-      function(file, callback) {
-        const params = {
-          Bucket: bucket,
-          Key: file,
-          Body: grunt.file.read(files[file])
-        };
-        s3.putObject(params, function(err) {
-          if (err) {
-            throw err;
-          } else {
-            grunt.log.writeln('Published ' + file + ' to build server.');
-            callback();
-          }
-        });
-      },
-      callback
-    );
+
+  async function publish(suffixes) {
+    const publishPromises = suffixes.map(suffix => publishSuffix(suffix));
+    return Promise.all(publishPromises);
   }
-  function fileMap(suffixes) {
-    const map = {};
-    _.each(
-      [
-        'handlebars.js',
-        'handlebars.min.js',
-        'handlebars.runtime.js',
-        'handlebars.runtime.min.js'
-      ],
-      function(file) {
-        _.each(suffixes, function(suffix) {
-          map[file.replace(/\.js$/, suffix + '.js')] = 'dist/' + file;
-        });
-      }
-    );
-    return map;
+
+  async function publishSuffix(suffix) {
+    const filenames = [
+      'handlebars.js',
+      'handlebars.min.js',
+      'handlebars.runtime.js',
+      'handlebars.runtime.min.js'
+    ];
+    const publishPromises = filenames.map(filename => {
+      const nameInBucket = getNameInBucket(filename, suffix);
+      const localFile = getLocalFile(filename);
+      uploadToBucket(localFile, nameInBucket);
+      grunt.log.writeln(
+        `Published ${localFile} to build server (${nameInBucket})`
+      );
+    });
+    return Promise.all(publishPromises);
+  }
+
+  async function uploadToBucket(localFile, nameInBucket) {
+    const bucket = process.env.S3_BUCKET_NAME;
+    const uploadParams = {
+      Bucket: bucket,
+      Key: nameInBucket,
+      Body: grunt.file.read(localFile)
+    };
+    return s3PutObject(uploadParams);
   }
 };
+
+function s3PutObject(uploadParams) {
+  const s3 = new AWS.S3();
+  return new Promise((resolve, reject) => {
+    s3.putObject(uploadParams, err => {
+      if (err != null) {
+        return reject(err);
+      }
+      resolve();
+    });
+  });
+}
+
+function getNameInBucket(filename, suffix) {
+  return filename.replace(/\.js$/, suffix + '.js');
+}
+
+function getLocalFile(filename) {
+  return 'dist/' + filename;
+}
diff --git a/tasks/util/git.js b/tasks/util/git.js
index 4dc5cbde0..a86fcbb6e 100644
--- a/tasks/util/git.js
+++ b/tasks/util/git.js
@@ -1,115 +1,74 @@
 const childProcess = require('child_process');
 
 module.exports = {
-  debug: function(callback) {
-    childProcess.exec('git remote -v', {}, function(err, remotes) {
-      if (err) {
-        throw new Error('git.remote: ' + err.message);
-      }
-
-      childProcess.exec('git branch -a', {}, function(err, branches) {
-        if (err) {
-          throw new Error('git.branch: ' + err.message);
-        }
-
-        callback(remotes, branches);
-      });
-    });
+  async remotes() {
+    return git('remotes', '-v');
   },
-  clean: function(callback) {
-    childProcess.exec('git diff-index --name-only HEAD --', {}, function(
-      err,
-      stdout
-    ) {
-      callback(undefined, !err && !stdout);
-    });
+  async branches() {
+    return git('branch', '-a');
   },
-
-  commitInfo: function(callback) {
-    module.exports.head(function(err, headSha) {
-      module.exports.master(function(err, masterSha) {
-        module.exports.tagName(function(err, tagName) {
-          callback(undefined, {
-            head: headSha,
-            master: masterSha,
-            tagName: tagName,
-            isMaster: headSha === masterSha
-          });
-        });
-      });
-    });
+  async clean() {
+    const stdout = git('diff-index', '--name-only', 'HEAD', '--');
+    return stdout === '';
   },
-
-  head: function(callback) {
-    childProcess.exec('git rev-parse --short HEAD', {}, function(err, stdout) {
-      if (err) {
-        throw new Error('git.head: ' + err.message);
-      }
-
-      callback(undefined, stdout.trim());
-    });
+  async commitInfo() {
+    const headSha = await this.headSha();
+    const masterSha = await this.masterSha();
+    return {
+      headSha,
+      masterSha,
+      tagName: await this.tagName(),
+      isMaster: headSha === masterSha
+    };
   },
-  master: function(callback) {
-    childProcess.exec('git rev-parse --short origin/master', {}, function(
-      err,
-      stdout
-    ) {
-      // This will error if master was not checked out but in this case we know we are not master
-      // so we can ignore.
-      if (err && !/Needed a single revision/.test(err.message)) {
-        throw new Error('git.master: ' + err.message);
-      }
-
-      callback(undefined, stdout.trim());
-    });
+  async headSha() {
+    const stdout = await git(' rev-parse', '--short', 'HEAD');
+    return stdout.trim();
   },
-
-  add: function(path, callback) {
-    childProcess.exec('git add -f ' + path, {}, function(err) {
-      if (err) {
-        throw new Error('git.add: ' + err.message);
+  async masterSha() {
+    try {
+      const stdout = await git('rev-parse', '--short', 'origin/master');
+      return stdout.trim();
+    } catch (error) {
+      if (/Needed a single revision/.test(error.message)) {
+        // Master was not checked out but in this case, so we know we are not master. We can ignore this
+        return '';
       }
-
-      callback();
-    });
+      throw error;
+    }
   },
-  commit: function(name, callback) {
-    childProcess.exec('git commit --message=' + name, {}, function(err) {
-      if (err) {
-        throw new Error('git.commit: ' + err.message);
-      }
 
-      callback();
-    });
+  async add(path) {
+    return git('add', '-f', path);
   },
-  tag: function(name, callback) {
-    childProcess.exec('git tag -a --message=' + name + ' ' + name, {}, function(
-      err
-    ) {
-      if (err) {
-        throw new Error('git.tag: ' + err.message);
-      }
-
-      callback();
-    });
+  async commit(message) {
+    return git('commit', '--message', message);
   },
-  tagName: function(callback) {
-    childProcess.exec('git describe --tags', {}, function(err, stdout) {
-      if (err) {
-        throw new Error('git.tagName: ' + err.message);
-      }
-
-      let tags = stdout.trim().split(/\n/);
-      tags = tags.filter(function(info) {
-        info = info.split('-');
-        return info.length == 1;
-      });
+  async tag(name) {
+    return git('tag', '-a', `--message=${name}`, name);
+  },
+  async tagName() {
+    const stdout = await git('tag', '-l', '--points-at', 'HEAD');
 
-      const versionTags = tags.filter(function(info) {
-        return /^v/.test(info[0]);
-      });
+    const tags = stdout.trim().split(/\n|\r\n/);
+    const versionTags = tags.filter(tag => /^v/.test(tag));
 
-      callback(undefined, versionTags[0] || tags[0]);
-    });
+    if (versionTags[0] != null) {
+      return versionTags;
+    }
+    return tags[0];
   }
 };
+
+async function git(...args) {
+  return new Promise((resolve, reject) =>
+    childProcess.execFile('git', args, (err, stdout) => {
+      if (err != null) {
+        return reject(
+          new Error(`"git ${args.join(' ')}" caused error: ${err.message}`)
+        );
+      }
+      resolve(stdout);
+    })
+  );
+}
diff --git a/tasks/version.js b/tasks/version.js
index f9d5c5675..ba89d1fd7 100644
--- a/tasks/version.js
+++ b/tasks/version.js
@@ -1,68 +1,62 @@
-const async = require('neo-async'),
-  git = require('./util/git'),
-  semver = require('semver');
+const git = require('./util/git');
+const semver = require('semver');
+const { createRegisterAsyncTaskFn } = require('./util/async-grunt-task');
 
 module.exports = function(grunt) {
-  grunt.registerTask(
-    'version',
-    'Updates the current release version',
-    function() {
-      const done = this.async(),
-        pkg = grunt.config('pkg'),
-        version = grunt.option('ver');
+  const registerAsyncTask = createRegisterAsyncTaskFn(grunt);
 
-      if (!semver.valid(version)) {
-        throw new Error(
-          'Must provide a version number (Ex: --ver=1.0.0):\n\t' +
-            version +
-            '\n\n'
-        );
-      }
-
-      pkg.version = version;
-      grunt.config('pkg', pkg);
-
-      grunt.log.writeln('Updating to version ' + version);
-
-      async.each(
-        [
-          [
-            'lib/handlebars/base.js',
-            /const VERSION = ['"](.*)['"];/,
-            "const VERSION = '" + version + "';"
-          ],
-          [
-            'components/bower.json',
-            /"version":.*/,
-            '"version": "' + version + '",'
-          ],
-          [
-            'components/package.json',
-            /"version":.*/,
-            '"version": "' + version + '",'
-          ],
-          [
-            'components/handlebars.js.nuspec',
-            /<version>.*<\/version>/,
-            '<version>' + version + '</version>'
-          ]
-        ],
-        function(args, callback) {
-          replace.apply(undefined, args);
-          grunt.log.writeln('    - ' + args[0]);
-          git.add(args[0], callback);
-        },
-        function() {
-          grunt.task.run(['default']);
-          done();
-        }
+  registerAsyncTask('version', async () => {
+    const pkg = grunt.config('pkg');
+    const version = grunt.option('ver');
+    if (!semver.valid(version)) {
+      throw new Error(
+        'Must provide a version number (Ex: --ver=1.0.0):\n\t' +
+          version +
+          '\n\n'
       );
     }
-  );
+    pkg.version = version;
+    grunt.config('pkg', pkg);
+
+    const replaceSpec = [
+      {
+        path: 'lib/handlebars/base.js',
+        regex: /const VERSION = ['"](.*)['"];/,
+        replacement: `const VERSION = '${version}';`
+      },
+      {
+        path: 'components/bower.json',
+        regex: /"version":.*/,
+        replacement: `"version": "${version}",`
+      },
+      {
+        path: 'components/package.json',
+        regex: /"version":.*/,
+        replacement: `"version": "${version}",`
+      },
+      {
+        path: 'components/handlebars.js.nuspec',
+        regex: /<version>.*<\/version>/,
+        replacement: `<version>${version}</version>`
+      }
+    ];
+
+    await Promise.all(
+      replaceSpec.map(replaceSpec =>
+        replaceAndAdd(
+          replaceSpec.path,
+          replaceSpec.regex,
+          replaceSpec.replacement
+        )
+      )
+    );
+    grunt.task.run(['default']);
+  });
 
-  function replace(path, regex, value) {
+  async function replaceAndAdd(path, regex, value) {
     let content = grunt.file.read(path);
     content = content.replace(regex, value);
     grunt.file.write(path, content);
+    await git.add(path);
   }
 };

From 14b621caf5bcdcbf7476b3286afbc30380d2cc3f Mon Sep 17 00:00:00 2001
From: Nils Knappmeier <github@knappi.org>
Date: Sat, 14 Dec 2019 17:39:39 +0100
Subject: [PATCH 16/24] test/style: remove or hide unused code in git.js, add
 tests

---
 .eslintrc.js                            |   2 +-
 Gruntfile.js                            |   2 +-
 package-lock.json                       |  31 +++++-
 package.json                            |   3 +-
 tasks/{publish.js => publish-to-aws.js} |   6 +-
 tasks/task-tests/.eslintrc.js           |   9 ++
 tasks/task-tests/README.md              |   1 +
 tasks/task-tests/git.test.js            | 121 ++++++++++++++++++++++++
 tasks/task-tests/mocha.opts             |   0
 tasks/util/git.js                       |  71 +++++++-------
 10 files changed, 199 insertions(+), 47 deletions(-)
 rename tasks/{publish.js => publish-to-aws.js} (93%)
 create mode 100644 tasks/task-tests/.eslintrc.js
 create mode 100644 tasks/task-tests/README.md
 create mode 100644 tasks/task-tests/git.test.js
 create mode 100644 tasks/task-tests/mocha.opts

diff --git a/.eslintrc.js b/.eslintrc.js
index 0abcd5806..65c240939 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -17,7 +17,7 @@ module.exports = {
     // Best Practices //
     //----------------//
     'default-case': 'warn',
-    'dot-notation': ['error', { allowKeywords: false }],
+    'dot-notation': 'warn',
     'guard-for-in': 'warn',
     'no-alert': 'error',
     'no-caller': 'error',
diff --git a/Gruntfile.js b/Gruntfile.js
index 0326cfc89..65e0b8f33 100644
--- a/Gruntfile.js
+++ b/Gruntfile.js
@@ -279,7 +279,7 @@ module.exports = function(grunt) {
     'bgShell:integrationTests',
     'sauce',
     'metrics',
-    'publish:latest'
+    'publish-to-aws'
   ]);
   grunt.registerTask('on-file-change', [
     'build',
diff --git a/package-lock.json b/package-lock.json
index 9c79a3d74..5d119122f 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -2594,6 +2594,19 @@
         "strip-json-comments": "^2.0.1",
         "tslint": "^5.14.0",
         "typescript": "^3.4.3"
+      },
+      "dependencies": {
+        "fs-extra": {
+          "version": "6.0.1",
+          "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-6.0.1.tgz",
+          "integrity": "sha512-GnyIkKhhzXZUWFCaJzvyDLEEgDkPfb4/TPvJCJVuS8MWZgoSsErf++QpiAlDnKFcqhRlm+tIOcencCjyJE6ZCA==",
+          "dev": true,
+          "requires": {
+            "graceful-fs": "^4.1.2",
+            "jsonfile": "^4.0.0",
+            "universalify": "^0.1.0"
+          }
+        }
       }
     },
     "dustjs-linkedin": {
@@ -3699,14 +3712,22 @@
       "dev": true
     },
     "fs-extra": {
-      "version": "6.0.1",
-      "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-6.0.1.tgz",
-      "integrity": "sha1-irwSj3lG4xATXdyTuYvdtBDno0s=",
+      "version": "8.1.0",
+      "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz",
+      "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==",
       "dev": true,
       "requires": {
-        "graceful-fs": "^4.1.2",
+        "graceful-fs": "^4.2.0",
         "jsonfile": "^4.0.0",
         "universalify": "^0.1.0"
+      },
+      "dependencies": {
+        "graceful-fs": {
+          "version": "4.2.3",
+          "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz",
+          "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==",
+          "dev": true
+        }
       }
     },
     "fs-readdir-recursive": {
@@ -10566,7 +10587,7 @@
     "universalify": {
       "version": "0.1.2",
       "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
-      "integrity": "sha1-tkb2m+OULavOzJ1mOcgNwQXvqmY=",
+      "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==",
       "dev": true
     },
     "unpipe": {
diff --git a/package.json b/package.json
index 6c8ca555d..19f096a5a 100644
--- a/package.json
+++ b/package.json
@@ -44,6 +44,7 @@
     "eslint-config-prettier": "^6.7.0",
     "eslint-plugin-compat": "^3.3.0",
     "eslint-plugin-es5": "^1.4.1",
+    "fs-extra": "^8.1.0",
     "grunt": "^1.0.4",
     "grunt-babel": "^5.0.0",
     "grunt-bg-shell": "^2.3.3",
@@ -86,7 +87,7 @@
     "lint": "eslint --max-warnings 0 . ",
     "dtslint": "dtslint types",
     "test": "grunt",
-    "extensive-tests-and-publish-to-aws": "grunt --stack extensive-tests-and-publish-to-aws",
+    "extensive-tests-and-publish-to-aws": "npx mocha tasks/task-tests/ && grunt --stack extensive-tests-and-publish-to-aws",
     "integration-test": "grunt integration-tests",
     "--- combined tasks ---": "",
     "check-before-pull-request": "concurrently --kill-others-on-fail npm:lint npm:dtslint npm:check-format npm:test"
diff --git a/tasks/publish.js b/tasks/publish-to-aws.js
similarity index 93%
rename from tasks/publish.js
rename to tasks/publish-to-aws.js
index 54c99f5ca..b551e1c95 100644
--- a/tasks/publish.js
+++ b/tasks/publish-to-aws.js
@@ -6,12 +6,12 @@ const semver = require('semver');
 module.exports = function(grunt) {
   const registerAsyncTask = createRegisterAsyncTaskFn(grunt);
 
-  registerAsyncTask('publish:latest', async () => {
+  registerAsyncTask('publish-to-aws', async () => {
     grunt.log.writeln('remotes: ' + (await git.remotes()));
     grunt.log.writeln('branches: ' + (await git.branches()));
 
     const commitInfo = await git.commitInfo();
-    grunt.log.writeln('tag: ' + commitInfo.tagName);
+    grunt.log.writeln('tag: ', commitInfo.tagName);
 
     const suffixes = [];
 
@@ -22,7 +22,7 @@ module.exports = function(grunt) {
     }
 
     // Publish tags by their tag-name
-    if (commitInfo.tagName && semver.valid(commitInfo.tagName)) {
+    if (commitInfo.tagName != null && semver.valid(commitInfo.tagName)) {
       suffixes.push('-' + commitInfo.tagName);
     }
 
diff --git a/tasks/task-tests/.eslintrc.js b/tasks/task-tests/.eslintrc.js
new file mode 100644
index 000000000..604aeb2c0
--- /dev/null
+++ b/tasks/task-tests/.eslintrc.js
@@ -0,0 +1,9 @@
+module.exports = {
+  extends: '../../.eslintrc.js',
+  env: {
+    mocha: true
+  },
+  parserOptions: {
+    ecmaVersion: 2018
+  }
+};
diff --git a/tasks/task-tests/README.md b/tasks/task-tests/README.md
new file mode 100644
index 000000000..f4a88806c
--- /dev/null
+++ b/tasks/task-tests/README.md
@@ -0,0 +1 @@
+Use `mocha tasks/task-tests` to run these tests
diff --git a/tasks/task-tests/git.test.js b/tasks/task-tests/git.test.js
new file mode 100644
index 000000000..89546a8b8
--- /dev/null
+++ b/tasks/task-tests/git.test.js
@@ -0,0 +1,121 @@
+const os = require('os');
+const path = require('path');
+const fs = require('fs-extra');
+const chai = require('chai');
+chai.use(require('dirty-chai'));
+
+const git = require('../util/git');
+
+const expect = chai.expect;
+
+const tmpBaseDir = path.join(os.tmpdir(), 'handlebars-task-tests');
+const tmpDir = path.join(tmpBaseDir, Date.now().toString(36));
+const remoteDir = path.join(tmpDir, 'remote-repo');
+const cloneDir = path.join(tmpDir, 'clone-repo');
+const oldCwd = process.cwd();
+
+describe('utils/git', function() {
+  beforeEach(async function() {
+    await fs.remove(tmpDir);
+    await createRepositoryThatActsAsRemote();
+    process.chdir(tmpDir);
+    await git.git('clone', 'remote-repo', 'clone-repo');
+    process.chdir(cloneDir);
+  });
+
+  async function createRepositoryThatActsAsRemote() {
+    await fs.mkdirp(remoteDir);
+    process.chdir(remoteDir);
+
+    await git.git('init');
+    await fs.writeFile('testfile.txt', 'Testfile');
+    await git.add('testfile.txt');
+    await git.commit('commit message');
+  }
+
+  afterEach(function() {
+    process.chdir(oldCwd);
+  });
+
+  describe('the "remotes"-function', function() {
+    it('should list all remotes', async function() {
+      await git.git('remote', 'set-url', 'origin', 'https://test.org/test');
+      await git.git('remote', 'add', 'second-remote', 'https://test.org/test2');
+
+      const result = await git.remotes();
+
+      expect(result.trim().split('\n')).to.deep.equal([
+        'origin\thttps://test.org/test (fetch)',
+        'origin\thttps://test.org/test (push)',
+        'second-remote\thttps://test.org/test2 (fetch)',
+        'second-remote\thttps://test.org/test2 (push)'
+      ]);
+    });
+  });
+
+  describe('the "branches"-function', function() {
+    it('should list all branches', async function() {
+      await git.git('branch', 'test');
+      await git.git('branch', 'test2');
+
+      const result = await git.branches();
+      expect(result.trim().split('\n')).to.deep.equal([
+        '* master',
+        '  test',
+        '  test2',
+        '  remotes/origin/HEAD -> origin/master',
+        '  remotes/origin/master'
+      ]);
+    });
+  });
+
+  describe('the "commitInfo"-function', function() {
+    it('should list head and master sha', async function() {
+      const result = await git.commitInfo();
+      expect(result.masterSha).to.equal(result.headSha);
+      expect(result.masterSha).to.match(/^[0-9a-f]+$/);
+      expect(result.headSha).to.match(/^[0-9a-f]+$/);
+    });
+
+    it('should have "isMaster=true" if the master branch is checked out', async function() {
+      const result = await git.commitInfo();
+      expect(result.isMaster).to.be.true();
+    });
+
+    it('should have "isMaster=true" if the current commit is the last commit of the master branch', async function() {
+      await git.git('checkout', '-b', 'new-branch');
+
+      const result = await git.commitInfo();
+      expect(result.isMaster).to.be.true();
+    });
+
+    it('should have "isMaster=false" if the current commit is NOT the last commit of the master branch', async function() {
+      await git.git('checkout', '-b', 'new-branch');
+      fs.writeFile('new-file.txt', 'new-file');
+      await git.add('new-file.txt');
+      await git.commit('added new file');
+
+      const result = await git.commitInfo();
+      expect(result.isMaster).to.be.false();
+    });
+
+    it('should show the current tag', async function() {
+      await git.git('tag', 'test-tag');
+      const result = await git.commitInfo();
+      expect(result.tagName).to.be.equal('test-tag');
+    });
+
+    it('should show a version tag rather than standard tags', async function() {
+      await git.git('tag', 'test-tag');
+      await git.git('tag', 'v1.2');
+      await git.git('tag', 'test-tag2');
+      const result = await git.commitInfo();
+      expect(result.tagName).to.be.equal('v1.2');
+    });
+
+    it('should show no tag if there is no tag', async function() {
+      const result = await git.commitInfo();
+      expect(result.tagName).to.be.null();
+    });
+  });
+});
diff --git a/tasks/task-tests/mocha.opts b/tasks/task-tests/mocha.opts
new file mode 100644
index 000000000..e69de29bb
diff --git a/tasks/util/git.js b/tasks/util/git.js
index a86fcbb6e..46c9cbe7c 100644
--- a/tasks/util/git.js
+++ b/tasks/util/git.js
@@ -2,63 +2,62 @@ const childProcess = require('child_process');
 
 module.exports = {
   async remotes() {
-    return git('remotes', '-v');
+    return git('remote', '-v');
   },
   async branches() {
     return git('branch', '-a');
   },
-  async clean() {
-    const stdout = git('diff-index', '--name-only', 'HEAD', '--');
-    return stdout === '';
-  },
   async commitInfo() {
-    const headSha = await this.headSha();
-    const masterSha = await this.masterSha();
+    const headSha = await getHeadSha();
+    const masterSha = await getMasterSha();
     return {
       headSha,
       masterSha,
-      tagName: await this.tagName(),
+      tagName: await getTagName(),
       isMaster: headSha === masterSha
     };
   },
-  async headSha() {
-    const stdout = await git(' rev-parse', '--short', 'HEAD');
-    return stdout.trim();
-  },
-  async masterSha() {
-    try {
-      const stdout = await git('rev-parse', '--short', 'origin/master');
-      return stdout.trim();
-    } catch (error) {
-      if (/Needed a single revision/.test(error.message)) {
-        // Master was not checked out but in this case, so we know we are not master. We can ignore this
-        return '';
-      }
-      throw error;
-    }
-  },
-
   async add(path) {
     return git('add', '-f', path);
   },
   async commit(message) {
     return git('commit', '--message', message);
   },
-  async tag(name) {
-    return git('tag', '-a', `--message=${name}`, name);
-  },
-  async tagName() {
-    const stdout = await git('tag', '-l', '--points-at', 'HEAD');
+  git // visible for testing
+};
 
-    const tags = stdout.trim().split(/\n|\r\n/);
-    const versionTags = tags.filter(tag => /^v/.test(tag));
+async function getHeadSha() {
+  const stdout = await git('rev-parse', '--short', 'HEAD');
+  return stdout.trim();
+}
 
-    if (versionTags[0] != null) {
-      return versionTags;
+async function getMasterSha() {
+  try {
+    const stdout = await git('rev-parse', '--short', 'origin/master');
+    return stdout.trim();
+  } catch (error) {
+    if (/Needed a single revision/.test(error.message)) {
+      // Master was not checked out but in this case, so we know we are not master. We can ignore this
+      return '';
     }
-    return tags[0];
+    throw error;
   }
-};
+}
+
+async function getTagName() {
+  const stdout = await git('tag', '-l', '--points-at', 'HEAD');
+  const trimmedStdout = stdout.trim();
+  if (trimmedStdout === '') {
+    return null; // there is no tag
+  }
+
+  const tags = trimmedStdout.split(/\n|\r\n/);
+  const versionTags = tags.filter(tag => /^v/.test(tag));
+  if (versionTags[0] != null) {
+    return versionTags[0];
+  }
+  return tags[0];
+}
 
 async function git(...args) {
   return new Promise((resolve, reject) =>

From ac4655ee9516d5fc1b29d4d52e17c1751ffc8324 Mon Sep 17 00:00:00 2001
From: Nils Knappmeier <github@knappi.org>
Date: Sat, 14 Dec 2019 17:48:08 +0100
Subject: [PATCH 17/24] chore: disable "dot-notation" rule

- I don't think it makes much sense. In some cases,
  it is more readable to wrap property access in quotes,
  some times not, but there is no universal rule
  for that.
- a promises "catch"-function should not be wrapped, but it has to
  be, if "allow-keywords" is set to false
- an "if"-helper should be wrapped, but it is not allowed to be
  if "allow-keywords" is set to true (default).
---
 .eslintrc.js | 1 -
 1 file changed, 1 deletion(-)

diff --git a/.eslintrc.js b/.eslintrc.js
index 65c240939..2ac729358 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -17,7 +17,6 @@ module.exports = {
     // Best Practices //
     //----------------//
     'default-case': 'warn',
-    'dot-notation': 'warn',
     'guard-for-in': 'warn',
     'no-alert': 'error',
     'no-caller': 'error',

From 164b7ff0de3041532b0ba671b3eefb7c0c5b5338 Mon Sep 17 00:00:00 2001
From: Nils Knappmeier <github@knappi.org>
Date: Sat, 14 Dec 2019 17:49:42 +0100
Subject: [PATCH 18/24] chore: ignore .nyc_output

---
 .eslintignore   | 1 +
 .gitignore      | 1 +
 .prettierignore | 1 +
 3 files changed, 3 insertions(+)

diff --git a/.eslintignore b/.eslintignore
index a64673018..714d84019 100644
--- a/.eslintignore
+++ b/.eslintignore
@@ -9,6 +9,7 @@ sauce_connect.log*
 yarn-error.log
 node_modules
 /handlebars-release.tgz
+.nyc_output
 
 # Generated files
 lib/handlebars/compiler/parser.js
diff --git a/.gitignore b/.gitignore
index 8922abaf6..59019b37d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -10,6 +10,7 @@ sauce_connect.log*
 /yarn.lock
 node_modules
 /handlebars-release.tgz
+.nyc_output
 
 # Generated files
 lib/handlebars/compiler/parser.js
diff --git a/.prettierignore b/.prettierignore
index b6bc46217..724620669 100644
--- a/.prettierignore
+++ b/.prettierignore
@@ -9,6 +9,7 @@ sauce_connect.log*
 yarn-error.log
 node_modules
 /handlebars-release.tgz
+.nyc_output
 
 # Generated files
 lib/handlebars/compiler/parser.js

From d03b6ecfc44e350fd08df752a9551d824287d7f5 Mon Sep 17 00:00:00 2001
From: Nils Knappmeier <github@knappi.org>
Date: Mon, 16 Dec 2019 21:44:55 +0100
Subject: [PATCH 19/24] feat: access control to prototype properties via
 whitelist

Disallow access to prototype properties and methods by default.
Access to properties is always checked via
`Object.prototype.hasOwnProperty.call(parent, propertyName)`.

New runtime options:
- **allowedProtoMethods**: a string-to-boolean map of property-names that are allowed if they are methods of the parent object.
- **allowedProtoProperties**: a string-to-boolean map of property-names that are allowed if they are properties but not methods of the parent object.

```js
const template = handlebars.compile('{{aString.trim}}')
const result = template({ aString: '  abc  ' })
// result is empty, because trim is defined at String prototype
```

```js
const template = handlebars.compile('{{aString.trim}}')
const result = template({ aString: '  abc  ' }, {
  allowedProtoMethods: {
    trim: true
  }
})
// result = 'abc'
```

Implementation details: The method now "container.lookupProperty"
handles the prototype-checks and the white-lists. It is used in
- JavaScriptCompiler#nameLookup
- The "lookup"-helper (passed to all helpers as "options.lookupProperty")
- The "lookup" function at the container, which is used for recursive lookups in "compat" mode

Compatibility:
- **Old precompiled templates work with new runtimes**: The "options.lookupPropery"-function is passed to the helper by a wrapper, not by the compiled templated.
- **New templates work with old runtimes**: The template contains a function that is used as fallback if the "lookupProperty"-function cannot be found at the container. However, the runtime-options "allowedProtoProperties" and "allowedProtoMethods" only work with the newest runtime.

BREAKING CHANGE:
- access to prototype properties is forbidden completely by default
---
 .../compiler/javascript-compiler.js           |  54 +++---
 lib/handlebars/helpers/lookup.js              |  13 +-
 .../internal/createNewLookupObject.js         |  11 ++
 lib/handlebars/internal/wrapHelper.js         |   8 +
 lib/handlebars/runtime.js                     |  56 +++++-
 spec/blocks.js                                |   1 +
 spec/helpers.js                               |  11 ++
 spec/javascript-compiler.js                   |  25 +++
 spec/regressions.js                           |  54 +++++-
 spec/security.js                              | 182 +++++++++++++++---
 types/index.d.ts                              |   2 +
 types/test.ts                                 |  10 +
 12 files changed, 354 insertions(+), 73 deletions(-)
 create mode 100644 lib/handlebars/internal/createNewLookupObject.js
 create mode 100644 lib/handlebars/internal/wrapHelper.js

diff --git a/lib/handlebars/compiler/javascript-compiler.js b/lib/handlebars/compiler/javascript-compiler.js
index bcf9bb21c..63f90bdc2 100644
--- a/lib/handlebars/compiler/javascript-compiler.js
+++ b/lib/handlebars/compiler/javascript-compiler.js
@@ -2,7 +2,6 @@ import { COMPILER_REVISION, REVISION_CHANGES } from '../base';
 import Exception from '../exception';
 import { isArray } from '../utils';
 import CodeGen from './code-gen';
-import { dangerousPropertyRegex } from '../helpers/lookup';
 
 function Literal(value) {
   this.value = value;
@@ -13,27 +12,8 @@ function JavaScriptCompiler() {}
 JavaScriptCompiler.prototype = {
   // PUBLIC API: You can override these methods in a subclass to provide
   // alternative compiled forms for name lookup and buffering semantics
-  nameLookup: function(parent, name /* , type*/) {
-    if (dangerousPropertyRegex.test(name)) {
-      const isEnumerable = [
-        this.aliasable('container.propertyIsEnumerable'),
-        '.call(',
-        parent,
-        ',',
-        JSON.stringify(name),
-        ')'
-      ];
-      return ['(', isEnumerable, '?', _actualLookup(), ' : undefined)'];
-    }
-    return _actualLookup();
-
-    function _actualLookup() {
-      if (JavaScriptCompiler.isValidJavaScriptVariableName(name)) {
-        return [parent, '.', name];
-      } else {
-        return [parent, '[', JSON.stringify(name), ']'];
-      }
-    }
+  nameLookup: function(parent, name /*,  type */) {
+    return this.internalNameLookup(parent, name);
   },
   depthedLookup: function(name) {
     return [this.aliasable('container.lookup'), '(depths, "', name, '")'];
@@ -69,6 +49,12 @@ JavaScriptCompiler.prototype = {
     return this.quotedString('');
   },
   // END PUBLIC API
+  internalNameLookup: function(parent, name) {
+    this.lookupPropertyFunctionIsUsed = true;
+    return ['lookupProperty(', parent, ',', JSON.stringify(name), ')'];
+  },
+
+  lookupPropertyFunctionIsUsed: false,
 
   compile: function(environment, options, context, asObject) {
     this.environment = environment;
@@ -131,7 +117,11 @@ JavaScriptCompiler.prototype = {
     if (!this.decorators.isEmpty()) {
       this.useDecorators = true;
 
-      this.decorators.prepend('var decorators = container.decorators;\n');
+      this.decorators.prepend([
+        'var decorators = container.decorators, ',
+        this.lookupPropertyFunctionVarDeclaration(),
+        ';\n'
+      ]);
       this.decorators.push('return fn;');
 
       if (asObject) {
@@ -248,6 +238,10 @@ JavaScriptCompiler.prototype = {
       }
     });
 
+    if (this.lookupPropertyFunctionIsUsed) {
+      varDeclarations += ', ' + this.lookupPropertyFunctionVarDeclaration();
+    }
+
     let params = ['container', 'depth0', 'helpers', 'partials', 'data'];
 
     if (this.useBlockParams || this.useDepths) {
@@ -335,6 +329,17 @@ JavaScriptCompiler.prototype = {
     return this.source.merge();
   },
 
+  lookupPropertyFunctionVarDeclaration: function() {
+    return `
+      lookupProperty = container.lookupProperty || function(parent, propertyName) {
+        if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
+          return parent[propertyName];
+        }
+        return undefined
+    }
+    `.trim();
+  },
+
   // [blockValue]
   //
   // On stack, before: hash, inverse, program, value
@@ -1241,6 +1246,9 @@ JavaScriptCompiler.prototype = {
   }
 })();
 
+/**
+ * @deprecated May be removed in the next major version
+ */
 JavaScriptCompiler.isValidJavaScriptVariableName = function(name) {
   return (
     !JavaScriptCompiler.RESERVED_WORDS[name] &&
diff --git a/lib/handlebars/helpers/lookup.js b/lib/handlebars/helpers/lookup.js
index 66de538b6..5620aba32 100644
--- a/lib/handlebars/helpers/lookup.js
+++ b/lib/handlebars/helpers/lookup.js
@@ -1,16 +1,9 @@
-export const dangerousPropertyRegex = /^(constructor|__defineGetter__|__defineSetter__|__lookupGetter__|__proto__)$/;
-
 export default function(instance) {
-  instance.registerHelper('lookup', function(obj, field) {
+  instance.registerHelper('lookup', function(obj, field, options) {
     if (!obj) {
+      // Note for 5.0: Change to "obj == null" in 5.0
       return obj;
     }
-    if (
-      dangerousPropertyRegex.test(String(field)) &&
-      !Object.prototype.propertyIsEnumerable.call(obj, field)
-    ) {
-      return undefined;
-    }
-    return obj[field];
+    return options.lookupProperty(obj, field);
   });
 }
diff --git a/lib/handlebars/internal/createNewLookupObject.js b/lib/handlebars/internal/createNewLookupObject.js
new file mode 100644
index 000000000..256f1eca1
--- /dev/null
+++ b/lib/handlebars/internal/createNewLookupObject.js
@@ -0,0 +1,11 @@
+import { extend } from '../utils';
+
+/**
+ * Create a new object with "null"-prototype to avoid truthy results on prototype properties.
+ * The resulting object can be used with "object[property]" to check if a property exists
+ * @param {...object} sources a varargs parameter of source objects that will be merged
+ * @returns {object}
+ */
+export function createNewLookupObject(...sources) {
+  return extend(Object.create(null), ...sources);
+}
diff --git a/lib/handlebars/internal/wrapHelper.js b/lib/handlebars/internal/wrapHelper.js
new file mode 100644
index 000000000..0010eb8c2
--- /dev/null
+++ b/lib/handlebars/internal/wrapHelper.js
@@ -0,0 +1,8 @@
+export function wrapHelper(helper, transformOptionsFn) {
+  let wrapper = function(/* dynamic arguments */) {
+    const options = arguments[arguments.length - 1];
+    arguments[arguments.length - 1] = transformOptionsFn(options);
+    return helper.apply(this, arguments);
+  };
+  return wrapper;
+}
diff --git a/lib/handlebars/runtime.js b/lib/handlebars/runtime.js
index 4d67895af..7d63e87b8 100644
--- a/lib/handlebars/runtime.js
+++ b/lib/handlebars/runtime.js
@@ -7,6 +7,8 @@ import {
   REVISION_CHANGES
 } from './base';
 import { moveHelperToHooks } from './helpers';
+import { wrapHelper } from './internal/wrapHelper';
+import { createNewLookupObject } from './internal/createNewLookupObject';
 
 export function checkRevision(compilerInfo) {
   const compilerRevision = (compilerInfo && compilerInfo[0]) || 1,
@@ -69,13 +71,17 @@ export function template(templateSpec, env) {
     }
     partial = env.VM.resolvePartial.call(this, partial, context, options);
 
-    let optionsWithHooks = Utils.extend({}, options, { hooks: this.hooks });
+    let extendedOptions = Utils.extend({}, options, {
+      hooks: this.hooks,
+      allowedProtoMethods: this.allowedProtoMethods,
+      allowedProtoProperties: this.allowedProtoProperties
+    });
 
     let result = env.VM.invokePartial.call(
       this,
       partial,
       context,
-      optionsWithHooks
+      extendedOptions
     );
 
     if (result == null && env.compile) {
@@ -84,7 +90,7 @@ export function template(templateSpec, env) {
         templateSpec.compilerOptions,
         env
       );
-      result = options.partials[options.name](context, optionsWithHooks);
+      result = options.partials[options.name](context, extendedOptions);
     }
     if (result != null) {
       if (options.indent) {
@@ -118,10 +124,26 @@ export function template(templateSpec, env) {
       }
       return obj[name];
     },
+    lookupProperty: function(parent, propertyName) {
+      let result = parent[propertyName];
+      if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
+        return result;
+      }
+      const whitelist =
+        typeof result === 'function'
+          ? container.allowedProtoMethods
+          : container.allowedProtoProperties;
+
+      if (whitelist[propertyName] === true) {
+        return result;
+      }
+      return undefined;
+    },
     lookup: function(depths, name) {
       const len = depths.length;
       for (let i = 0; i < len; i++) {
-        if (depths[i] && depths[i][name] != null) {
+        let result = depths[i] && container.lookupProperty(depths[i], name);
+        if (result != null) {
           return depths[i][name];
         }
       }
@@ -229,7 +251,9 @@ export function template(templateSpec, env) {
 
   ret._setup = function(options) {
     if (!options.partial) {
-      container.helpers = Utils.extend({}, env.helpers, options.helpers);
+      let mergedHelpers = Utils.extend({}, env.helpers, options.helpers);
+      wrapHelpersToPassLookupProperty(mergedHelpers, container);
+      container.helpers = mergedHelpers;
 
       if (templateSpec.usePartial) {
         // Use mergeIfNeeded here to prevent compiling global partials multiple times
@@ -247,6 +271,12 @@ export function template(templateSpec, env) {
       }
 
       container.hooks = {};
+      container.allowedProtoProperties = createNewLookupObject(
+        options.allowedProtoProperties
+      );
+      container.allowedProtoMethods = createNewLookupObject(
+        options.allowedProtoMethods
+      );
 
       let keepHelperInHelpers =
         options.allowCallsToHelperMissing ||
@@ -254,6 +284,8 @@ export function template(templateSpec, env) {
       moveHelperToHooks(container, 'helperMissing', keepHelperInHelpers);
       moveHelperToHooks(container, 'blockHelperMissing', keepHelperInHelpers);
     } else {
+      container.allowedProtoProperties = options.allowedProtoProperties;
+      container.allowedProtoMethods = options.allowedProtoMethods;
       container.helpers = options.helpers;
       container.partials = options.partials;
       container.decorators = options.decorators;
@@ -405,3 +437,17 @@ function executeDecorators(fn, prog, container, depths, data, blockParams) {
   }
   return prog;
 }
+
+function wrapHelpersToPassLookupProperty(mergedHelpers, container) {
+  Object.keys(mergedHelpers).forEach(helperName => {
+    let helper = mergedHelpers[helperName];
+    mergedHelpers[helperName] = passLookupPropertyOption(helper, container);
+  });
+}
+
+function passLookupPropertyOption(helper, container) {
+  const lookupProperty = container.lookupProperty;
+  return wrapHelper(helper, options => {
+    return Utils.extend({ lookupProperty }, options);
+  });
+}
diff --git a/spec/blocks.js b/spec/blocks.js
index 1ef2d1be2..ad534aaba 100644
--- a/spec/blocks.js
+++ b/spec/blocks.js
@@ -275,6 +275,7 @@ describe('blocks', function() {
         'Goodbye cruel OMG!'
       );
     });
+
     it('block with deep recursive pathed lookup', function() {
       var string =
         '{{#outer}}Goodbye {{#inner}}cruel {{omg.yes}}{{/inner}}{{/outer}}';
diff --git a/spec/helpers.js b/spec/helpers.js
index 9d4bc202e..60140a096 100644
--- a/spec/helpers.js
+++ b/spec/helpers.js
@@ -1328,4 +1328,15 @@ describe('helpers', function() {
       );
     });
   });
+
+  describe('the lookupProperty-option', function() {
+    it('should be passed to custom helpers', function() {
+      expectTemplate('{{testHelper}}')
+        .withHelper('testHelper', function testHelper(options) {
+          return options.lookupProperty(this, 'testProperty');
+        })
+        .withInput({ testProperty: 'abc' })
+        .toCompileTo('abc');
+    });
+  });
 });
diff --git a/spec/javascript-compiler.js b/spec/javascript-compiler.js
index 21b8e2a0a..e97cbb083 100644
--- a/spec/javascript-compiler.js
+++ b/spec/javascript-compiler.js
@@ -81,4 +81,29 @@ describe('javascript-compiler api', function() {
       shouldCompileTo('{{foo}}', { foo: 'food' }, 'food_foo');
     });
   });
+
+  describe('#isValidJavaScriptVariableName', function() {
+    // It is there and accessible and could be used by someone. That's why we don't remove it
+    // it 4.x. But if we keep it, we add a test
+    // This test should not encourage you to use the function. It is not needed any more
+    // and might be removed in 5.0
+    ['test', 'abc123', 'abc_123'].forEach(function(validVariableName) {
+      it("should return true for '" + validVariableName + "'", function() {
+        expect(
+          handlebarsEnv.JavaScriptCompiler.isValidJavaScriptVariableName(
+            validVariableName
+          )
+        ).to.be.true();
+      });
+    });
+    [('123test', 'abc()', 'abc.cde')].forEach(function(invalidVariableName) {
+      it("should return true for '" + invalidVariableName + "'", function() {
+        expect(
+          handlebarsEnv.JavaScriptCompiler.isValidJavaScriptVariableName(
+            invalidVariableName
+          )
+        ).to.be.false();
+      });
+    });
+  });
 });
diff --git a/spec/regressions.js b/spec/regressions.js
index 821c48dc2..3a84dd7da 100644
--- a/spec/regressions.js
+++ b/spec/regressions.js
@@ -390,7 +390,7 @@ describe('Regressions', function() {
     it('should compile and execute templates', function() {
       var newHandlebarsInstance = Handlebars.create();
 
-      registerTemplate(newHandlebarsInstance);
+      registerTemplate(newHandlebarsInstance, compiledTemplateVersion7());
       newHandlebarsInstance.registerHelper('loud', function(value) {
         return value.toUpperCase();
       });
@@ -405,7 +405,7 @@ describe('Regressions', function() {
 
       shouldThrow(
         function() {
-          registerTemplate(newHandlebarsInstance);
+          registerTemplate(newHandlebarsInstance, compiledTemplateVersion7());
           newHandlebarsInstance.templates['test.hbs']({});
         },
         Handlebars.Exception,
@@ -413,11 +413,31 @@ describe('Regressions', function() {
       );
     });
 
-    // This is a only slightly modified precompiled templated from compiled with 4.2.1
-    function registerTemplate(Handlebars) {
+    it('should pass "options.lookupProperty" to "lookup"-helper, even with old templates', function() {
+      var newHandlebarsInstance = Handlebars.create();
+      registerTemplate(
+        newHandlebarsInstance,
+        compiledTemplateVersion7_usingLookupHelper()
+      );
+
+      newHandlebarsInstance.templates['test.hbs']({});
+
+      expect(
+        newHandlebarsInstance.templates['test.hbs']({
+          property: 'a',
+          test: { a: 'b' }
+        })
+      ).to.equal('b');
+    });
+
+    function registerTemplate(Handlebars, compileTemplate) {
       var template = Handlebars.template,
         templates = (Handlebars.templates = Handlebars.templates || {});
-      templates['test.hbs'] = template({
+      templates['test.hbs'] = template(compileTemplate);
+    }
+
+    function compiledTemplateVersion7() {
+      return {
         compiler: [7, '>= 4.0.0'],
         main: function(container, depth0, helpers, partials, data) {
           return (
@@ -435,7 +455,29 @@ describe('Regressions', function() {
           );
         },
         useData: true
-      });
+      };
+    }
+
+    function compiledTemplateVersion7_usingLookupHelper() {
+      // This is the compiled version of "{{lookup test property}}"
+      return {
+        compiler: [7, '>= 4.0.0'],
+        main: function(container, depth0, helpers, partials, data) {
+          return container.escapeExpression(
+            helpers.lookup.call(
+              depth0 != null ? depth0 : container.nullContext || {},
+              depth0 != null ? depth0.test : depth0,
+              depth0 != null ? depth0.property : depth0,
+              {
+                name: 'lookup',
+                hash: {},
+                data: data
+              }
+            )
+          );
+        },
+        useData: true
+      };
     }
   });
 
diff --git a/spec/security.js b/spec/security.js
index ed0189281..7bf9d89a0 100644
--- a/spec/security.js
+++ b/spec/security.js
@@ -19,7 +19,7 @@ describe('security issues', function() {
         .toCompileTo('');
     });
 
-    it('should allow the "constructor" property to be accessed if it is enumerable', function() {
+    it('should allow the "constructor" property to be accessed if it is an "ownProperty"', function() {
       shouldCompileTo(
         '{{constructor.name}}',
         {
@@ -40,7 +40,7 @@ describe('security issues', function() {
       );
     });
 
-    it('should allow the "constructor" property to be accessed if it is enumerable', function() {
+    it('should allow the "constructor" property to be accessed if it is an "own property"', function() {
       shouldCompileTo(
         '{{lookup (lookup this "constructor") "name"}}',
         {
@@ -51,27 +51,6 @@ describe('security issues', function() {
         'here we go'
       );
     });
-
-    it('should allow prototype properties that are not constructors', function() {
-      function TestClass() {}
-
-      Object.defineProperty(TestClass.prototype, 'abc', {
-        get: function() {
-          return 'xyz';
-        }
-      });
-
-      shouldCompileTo(
-        '{{#with this as |obj|}}{{obj.abc}}{{/with}}',
-        new TestClass(),
-        'xyz'
-      );
-      shouldCompileTo(
-        '{{#with this as |obj|}}{{lookup obj "abc"}}{{/with}}',
-        new TestClass(),
-        'xyz'
-      );
-    });
   });
 
   describe('GH-1558: Prevent explicit call of helperMissing-helpers', function() {
@@ -171,38 +150,183 @@ describe('security issues', function() {
   });
 
   describe('GH-1595', function() {
-    it('properties, that are required to be enumerable', function() {
+    it('properties, that are required to be own properties', function() {
       expectTemplate('{{constructor}}')
         .withInput({})
         .toCompileTo('');
+
       expectTemplate('{{__defineGetter__}}')
         .withInput({})
         .toCompileTo('');
+
       expectTemplate('{{__defineSetter__}}')
         .withInput({})
         .toCompileTo('');
+
       expectTemplate('{{__lookupGetter__}}')
         .withInput({})
         .toCompileTo('');
+
       expectTemplate('{{__proto__}}')
         .withInput({})
         .toCompileTo('');
 
-      expectTemplate('{{lookup "constructor"}}')
+      expectTemplate('{{lookup this "constructor"}}')
         .withInput({})
         .toCompileTo('');
-      expectTemplate('{{lookup "__defineGetter__"}}')
+
+      expectTemplate('{{lookup this "__defineGetter__"}}')
         .withInput({})
         .toCompileTo('');
-      expectTemplate('{{lookup "__defineSetter__"}}')
+
+      expectTemplate('{{lookup this "__defineSetter__"}}')
         .withInput({})
         .toCompileTo('');
-      expectTemplate('{{lookup "__lookupGetter__"}}')
+
+      expectTemplate('{{lookup this "__lookupGetter__"}}')
         .withInput({})
         .toCompileTo('');
-      expectTemplate('{{lookup "__proto__"}}')
+
+      expectTemplate('{{lookup this "__proto__"}}')
         .withInput({})
         .toCompileTo('');
     });
+
+    describe('GH-1631: disallow access to prototype functions', function() {
+      function TestClass() {}
+
+      TestClass.prototype.aProperty = 'propertyValue';
+      TestClass.prototype.aMethod = function() {
+        return 'returnValue';
+      };
+
+      describe('control access to prototype methods via "allowedProtoMethods"', function() {
+        it('should be prohibited by default', function() {
+          expectTemplate('{{aMethod}}')
+            .withInput(new TestClass())
+            .toCompileTo('');
+        });
+
+        it('can be allowed', function() {
+          expectTemplate('{{aMethod}}')
+            .withInput(new TestClass())
+            .withRuntimeOptions({
+              allowedProtoMethods: {
+                aMethod: true
+              }
+            })
+            .toCompileTo('returnValue');
+        });
+
+        it('should be prohibited by default (in "compat" mode)', function() {
+          expectTemplate('{{aMethod}}')
+            .withInput(new TestClass())
+            .withCompileOptions({ compat: true })
+            .toCompileTo('');
+        });
+
+        it('can be allowed (in "compat" mode)', function() {
+          expectTemplate('{{aMethod}}')
+            .withInput(new TestClass())
+            .withCompileOptions({ compat: true })
+            .withRuntimeOptions({
+              allowedProtoMethods: {
+                aMethod: true
+              }
+            })
+            .toCompileTo('returnValue');
+        });
+
+        it('should cause the recursive lookup by default (in "compat" mode)', function() {
+          expectTemplate('{{#aString}}{{trim}}{{/aString}}')
+            .withInput({ aString: '  abc  ', trim: 'trim' })
+            .withCompileOptions({ compat: true })
+            .toCompileTo('trim');
+        });
+
+        it('should not cause the recursive lookup if allowed through options(in "compat" mode)', function() {
+          expectTemplate('{{#aString}}{{trim}}{{/aString}}')
+            .withInput({ aString: '  abc  ', trim: 'trim' })
+            .withCompileOptions({ compat: true })
+            .withRuntimeOptions({
+              allowedProtoMethods: {
+                trim: true
+              }
+            })
+            .toCompileTo('abc');
+        });
+      });
+
+      describe('control access to prototype non-methods via "allowedProtoProperties"', function() {
+        it('should be prohibited by default', function() {
+          expectTemplate('{{aProperty}}')
+            .withInput(new TestClass())
+            .toCompileTo('');
+        });
+
+        it('can be turned on', function() {
+          expectTemplate('{{aProperty}}')
+            .withInput(new TestClass())
+            .withRuntimeOptions({
+              allowedProtoProperties: {
+                aProperty: true
+              }
+            })
+            .toCompileTo('propertyValue');
+        });
+
+        it('should be prohibited by default (in "compat" mode)', function() {
+          expectTemplate('{{aProperty}}')
+            .withInput(new TestClass())
+            .withCompileOptions({ compat: true })
+            .toCompileTo('');
+        });
+
+        it('can be turned on (in "compat" mode)', function() {
+          expectTemplate('{{aProperty}}')
+            .withInput(new TestClass())
+            .withCompileOptions({ compat: true })
+            .withRuntimeOptions({
+              allowedProtoProperties: {
+                aProperty: true
+              }
+            })
+            .toCompileTo('propertyValue');
+        });
+      });
+
+      describe('compatibility with old runtimes, that do not provide the function "container.lookupProperty"', function() {
+        beforeEach(function simulateRuntimeWithoutLookupProperty() {
+          var oldTemplateMethod = handlebarsEnv.template;
+          sinon.replace(handlebarsEnv, 'template', function(templateSpec) {
+            templateSpec.main = wrapToAdjustContainer(templateSpec.main);
+            return oldTemplateMethod.call(this, templateSpec);
+          });
+        });
+
+        afterEach(function() {
+          sinon.restore();
+        });
+
+        it('should work with simple properties', function() {
+          expectTemplate('{{aProperty}}')
+            .withInput({ aProperty: 'propertyValue' })
+            .toCompileTo('propertyValue');
+        });
+
+        it('should work with Array.prototype.length', function() {
+          expectTemplate('{{anArray.length}}')
+            .withInput({ anArray: ['a', 'b', 'c'] })
+            .toCompileTo('3');
+        });
+      });
+    });
   });
 });
+
+function wrapToAdjustContainer(precompiledTemplateFunction) {
+  return function templateFunctionWrapper(container /*, more args */) {
+    delete container.lookupProperty;
+    return precompiledTemplateFunction.apply(this, arguments);
+  };
+}
diff --git a/types/index.d.ts b/types/index.d.ts
index bb0656a51..606741f5a 100644
--- a/types/index.d.ts
+++ b/types/index.d.ts
@@ -30,6 +30,8 @@ declare namespace Handlebars {
       data?: any;
       blockParams?: any[];
       allowCallsToHelperMissing?: boolean;
+      allowedProtoProperties?: { [name: string]: boolean }
+      allowedProtoMethods?: { [name: string]: boolean }
   }
 
   export interface HelperOptions {
diff --git a/types/test.ts b/types/test.ts
index fa9832683..b081ae4fb 100644
--- a/types/test.ts
+++ b/types/test.ts
@@ -240,3 +240,13 @@ function testExceptionWithNodeTypings() {
   let fileName: string = exception.fileName;
   let stack: string | undefined = exception.stack;
 }
+
+function testProtoPropertyControlOptions() {
+  Handlebars.compile('test')(
+    {},
+    {
+      allowedProtoMethods: { allowedMethod: true, forbiddenMethod: false },
+      allowedProtoProperties: { allowedProperty: true, forbiddenProperty: false }
+    }
+  );
+}

From d337f40d0efd59e163f871ed7a73e900322473a6 Mon Sep 17 00:00:00 2001
From: Nils Knappmeier <github@knappi.org>
Date: Wed, 1 Jan 2020 21:21:24 +0100
Subject: [PATCH 20/24] test: show diff when test:bin fails

---
 package-lock.json | 17 +++++++++++++++++
 package.json      |  3 ++-
 tasks/test-bin.js | 13 ++++++++-----
 3 files changed, 27 insertions(+), 6 deletions(-)

diff --git a/package-lock.json b/package-lock.json
index 5d119122f..2223f0b86 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1394,6 +1394,23 @@
         "type-detect": "^4.0.5"
       }
     },
+    "chai-diff": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/chai-diff/-/chai-diff-1.0.1.tgz",
+      "integrity": "sha1-bGaJRwDYDNkDUKtORANiXU9TocE=",
+      "dev": true,
+      "requires": {
+        "diff": "^2.2.1"
+      },
+      "dependencies": {
+        "diff": {
+          "version": "2.2.3",
+          "resolved": "https://registry.npmjs.org/diff/-/diff-2.2.3.tgz",
+          "integrity": "sha1-YOr9DSjukG5Oj/ClLBIpUhAzv5k=",
+          "dev": true
+        }
+      }
+    },
     "chalk": {
       "version": "1.1.3",
       "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
diff --git a/package.json b/package.json
index 19f096a5a..c164ea9c2 100644
--- a/package.json
+++ b/package.json
@@ -35,6 +35,7 @@
     "babel-runtime": "^5.1.10",
     "benchmark": "~1.0",
     "chai": "^4.2.0",
+    "chai-diff": "^1.0.1",
     "concurrently": "^5.0.0",
     "dirty-chai": "^2.0.1",
     "dtslint": "^0.5.5",
@@ -84,7 +85,7 @@
   "scripts": {
     "format": "prettier --write '**/*.js' && eslint --fix .",
     "check-format": "prettier --check '**/*.js'",
-    "lint": "eslint --max-warnings 0 . ",
+    "lint": "eslint --max-warnings 0 .",
     "dtslint": "dtslint types",
     "test": "grunt",
     "extensive-tests-and-publish-to-aws": "npx mocha tasks/task-tests/ && grunt --stack extensive-tests-and-publish-to-aws",
diff --git a/tasks/test-bin.js b/tasks/test-bin.js
index 8873c9f01..077e6d4f3 100644
--- a/tasks/test-bin.js
+++ b/tasks/test-bin.js
@@ -1,7 +1,10 @@
-const childProcess = require('child_process'),
-  fs = require('fs'),
-  os = require('os'),
-  expect = require('chai').expect;
+const childProcess = require('child_process');
+const fs = require('fs');
+const os = require('os');
+
+const chai = require('chai');
+chai.use(require('chai-diff'));
+const expect = chai.expect;
 
 module.exports = function(grunt) {
   grunt.registerTask('test:bin', function() {
@@ -18,7 +21,7 @@ module.exports = function(grunt) {
     const normalizedOutput = normalizeCrlf(stdout);
     const normalizedExpectedOutput = normalizeCrlf(expectedOutput);
 
-    expect(normalizedOutput).to.equal(normalizedExpectedOutput);
+    expect(normalizedOutput).not.to.be.differentFrom(normalizedExpectedOutput);
   });
 };
 

From 187d611e8c2a7dc849f62f283ac70714fa637e84 Mon Sep 17 00:00:00 2001
From: Nils Knappmeier <github@knappi.org>
Date: Thu, 2 Jan 2020 15:47:09 +0100
Subject: [PATCH 21/24] test: add path to nodeJs when running test:bin

- this allows the test to be run in a debugger
  without the complete PATH
---
 tasks/test-bin.js | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/tasks/test-bin.js b/tasks/test-bin.js
index 077e6d4f3..3a9c43095 100644
--- a/tasks/test-bin.js
+++ b/tasks/test-bin.js
@@ -1,6 +1,7 @@
 const childProcess = require('child_process');
 const fs = require('fs');
 const os = require('os');
+const path = require('path');
 
 const chai = require('chai');
 chai.use(require('chai-diff'));
@@ -37,7 +38,13 @@ function executeBinHandlebars(...args) {
 }
 
 function execFilesSyncUtf8(command, args) {
-  return childProcess.execFileSync(command, args, { encoding: 'utf-8' });
+  const env = process.env;
+  env.PATH = addPathToNodeJs(env.PATH);
+  return childProcess.execFileSync(command, args, { encoding: 'utf-8', env });
+}
+
+function addPathToNodeJs(pathEnvironment) {
+  return path.dirname(process.argv0) + path.delimiter + pathEnvironment;
 }
 
 function normalizeCrlf(string) {

From d7f0dcf2bb91a1d27961941995d75c9800efc7ba Mon Sep 17 00:00:00 2001
From: Nils Knappmeier <github@knappi.org>
Date: Thu, 2 Jan 2020 15:49:41 +0100
Subject: [PATCH 22/24] refactor: fix typo in private test method

---
 spec/env/common.js | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/spec/env/common.js b/spec/env/common.js
index 64451fee4..0ecebcf45 100644
--- a/spec/env/common.js
+++ b/spec/env/common.js
@@ -167,7 +167,7 @@ HandlebarsTestBench.prototype.withMessage = function(message) {
 };
 
 HandlebarsTestBench.prototype.toCompileTo = function(expectedOutputAsString) {
-  expect(this._compileAndExeute()).to.equal(expectedOutputAsString);
+  expect(this._compileAndExecute()).to.equal(expectedOutputAsString);
 };
 
 // see chai "to.throw" (https://www.chaijs.com/api/bdd/#method_throw)
@@ -178,11 +178,11 @@ HandlebarsTestBench.prototype.toThrow = function(
 ) {
   var self = this;
   expect(function() {
-    self._compileAndExeute();
+    self._compileAndExecute();
   }).to.throw(errorLike, errMsgMatcher, msg);
 };
 
-HandlebarsTestBench.prototype._compileAndExeute = function() {
+HandlebarsTestBench.prototype._compileAndExecute = function() {
   var compile =
     Object.keys(this.partials).length > 0
       ? CompilerContext.compileWithPartial

From 770d746e600eb1939501ab91d4bc81ed6b4cde94 Mon Sep 17 00:00:00 2001
From: Nils Knappmeier <github@knappi.org>
Date: Wed, 8 Jan 2020 23:44:46 +0100
Subject: [PATCH 23/24] Update release notes

---
 release-notes.md | 218 ++++++++++++++++++++++++++++++++++-------------
 1 file changed, 157 insertions(+), 61 deletions(-)

diff --git a/release-notes.md b/release-notes.md
index 199c39bf5..d75b32024 100644
--- a/release-notes.md
+++ b/release-notes.md
@@ -2,173 +2,223 @@
 
 ## Development
 
-[Commits](https://github.com/wycats/handlebars.js/compare/v4.5.3...master)
+[Commits](https://github.com/wycats/handlebars.js/compare/v4.6.0...master)
+
+## v4.6.0 - January 8th, 2020
+
+Features:
+
+- feat: access control to prototype properties via whitelist (#1633)- d03b6ec
+
+Bugfixes:
+
+- fix(runtime.js): partials compile not caching (#1600) - 23d58e7
+
+Chores, docs:
+
+- various refactorings and improvements to tests - d7f0dcf, 187d611, d337f40
+- modernize the build-setup
+  - use prettier to format and eslint to verify - c40d9f3, 8901c28, e97685e, 1f61f21
+  - use nyc instead of istanbul to collect coverage - 164b7ff, 1ebce2b
+  - update build code to use modern javascript and make it cleaner - 14b621c, 1ec1737, 3a5b65e, dde108e, 04b1984, 587e7a3
+  - restructur build commands - e913dc5,
+- eslint rule changes - ac4655e, dc54952
+- Update (C) year in the LICENSE file - d1fb07b
+- chore: try to fix saucelabs credentials (#1627) -
+- Update readme.md with updated links (#1620) - edcc84f
+
+BREAKING CHANGES:
+
+- access to prototype properties is forbidden completely by default,
+  specific properties or methods can be allow via runtime-options.
+  See #1633 for details.
+  If you are using Handlebars as documented, you should not be accessing prototype
+  properties from your template anyway, so the changes should not be a problem
+  for you. Only the use of undocumented features can break your build.
+
+  That is why we only bump the minor version despite mentioning breaking changes
+
+[Commits](https://github.com/wycats/handlebars.js/compare/v4.5.3...v4.6.0)
 
 ## v4.5.3 - November 18th, 2019
+
 Bugfixes:
 
 - fix: add "no-prototype-builtins" eslint-rule and fix all occurences - f7f05d7
 - fix: add more properties required to be enumerable - 1988878
 
 Chores / Build:
+
 - fix: use !== 0 instead of != 0 - c02b05f
-- add chai and dirty-chai and sinon, for cleaner test-assertions and spies, 
-  deprecate old assertion-methods  - 93e284e, 886ba86, 0817dad, 93516a0
+- add chai and dirty-chai and sinon, for cleaner test-assertions and spies,
+  deprecate old assertion-methods - 93e284e, 886ba86, 0817dad, 93516a0
 
 Security:
 
-- The properties `__proto__`, `__defineGetter__`, `__defineSetter__` and `__lookupGetter__` 
+- The properties `__proto__`, `__defineGetter__`, `__defineSetter__` and `__lookupGetter__`
   have been added to the list of "properties that must be enumerable".
-  If a property by that name is found and not enumerable on its parent, 
-  it will silently evaluate to `undefined`. This is done in both the compiled template and the "lookup"-helper. 
+  If a property by that name is found and not enumerable on its parent,
+  it will silently evaluate to `undefined`. This is done in both the compiled template and the "lookup"-helper.
   This will prevent new Remote-Code-Execution exploits that have been
   published recently.
 
-Compatibility notes: 
+Compatibility notes:
 
 - Due to the security-fixes. The semantics of the templates using
-  `__proto__`, `__defineGetter__`, `__defineSetter__` and `__lookupGetter__` in the respect that those expression now return 
+  `__proto__`, `__defineGetter__`, `__defineSetter__` and `__lookupGetter__` in the respect that those expression now return
   `undefined` rather than their actual value from the proto.
-- The semantics have not changed in cases where the properties are  enumerable, as in:
+- The semantics have not changed in cases where the properties are enumerable, as in:
 
 ```js
 {
-  __proto__: 'some string'
+  __proto__: 'some string';
 }
 ```
 
-- The change may be breaking in that respect, but we still only 
+- The change may be breaking in that respect, but we still only
   increase the patch-version, because the incompatible use-cases
   are not intended, undocumented and far less important than fixing
   Remote-Code-Execution exploits on existing systems.
 
-
-
 [Commits](https://github.com/wycats/handlebars.js/compare/v4.5.2...v4.5.3)
 
 ## v4.5.2 - November 13th, 2019
+
 # Bugfixes
 
 - fix: use String(field) in lookup when checking for "constructor" - d541378
 - test: add fluent API for testing Handlebars - c2ac79c
 
 Compatibility notes:
+
 - no incompatibility are to be expected
 
 [Commits](https://github.com/wycats/handlebars.js/compare/v4.5.1...v4.5.2)
 
 ## v4.5.1 - October 29th, 2019
+
 Bugfixs
 
 - fix: move "eslint-plugin-compat" to devDependencies - 5e9d17f (#1589)
 
 Compatibility notes:
-- No compatibility issues are to be expected
 
+- No compatibility issues are to be expected
 
 [Commits](https://github.com/wycats/handlebars.js/compare/v4.5.0...v4.5.1)
 
 ## v4.5.0 - October 28th, 2019
+
 Features / Improvements
+
 - Add method Handlebars.parseWithoutProcessing (#1584) - 62ed3c2
 - add guard to if & unless helpers (#1549)
 - show source location for the strict lookup exceptions - feb60f8
 
 Bugfixes:
+
 - Use objects for hash value tracking - 7fcf9d2
 
 Chore:
+
 - Resolve deprecation warning message from eslint while running eslint (#1586) - 7052e88
 - chore: add eslint-plugin-compat and eslint-plugin-es5 - 088e618
 
 Compatibility notes:
+
 - No compatibility issues are to be expected
 
 [Commits](https://github.com/wycats/handlebars.js/compare/v4.4.5...v4.5.0)
 
 ## v4.4.5 - October 20th, 2019
-Bugfixes: 
-
-- Contents of raw-blocks must be matched with non-eager regex-matching - 8d5530e, #1579
 
+Bugfixes:
 
+- Contents of raw-blocks must be matched with non-eager regex-matching - 8d5530e, #1579
 
 [Commits](https://github.com/wycats/handlebars.js/compare/v4.4.4...v4.4.5)
 
 ## v4.4.4 - October 20th, 2019
+
 Bugfixes:
+
 - fix: prevent zero length tokens in raw-blocks (#1577, #1578) - f1752fe
 
-Chore: 
+Chore:
+
 - chore: link to s3 bucket with https, add "npm ci" to build instructions - 0b593bf
 
 Compatibility notes:
+
 - no compatibility issues are expected
 
 [Commits](https://github.com/wycats/handlebars.js/compare/v4.4.3...v4.4.4)
 
 ## v4.4.3 - October 8th, 2019
+
 Bugfixes
 
 Typings:
-- add missing type fields to AST typings and add tests for them - 0440af2
-
 
+- add missing type fields to AST typings and add tests for them - 0440af2
 
 [Commits](https://github.com/wycats/handlebars.js/compare/v4.4.2...v4.4.3)
 
 ## v4.4.2 - October 2nd, 2019
-- chore: fix grunt-saucelabs dependency - b7eada0
 
+- chore: fix grunt-saucelabs dependency - b7eada0
 
 [Commits](https://github.com/wycats/handlebars.js/compare/v4.4.1...v4.4.2)
 
 ## v4.4.1 - October 2nd, 2019
-- [#1562](https://github.com/wycats/handlebars.js/issues/1562) - Error message for syntax error missing location in 4.2.1+
-
 
+- [#1562](https://github.com/wycats/handlebars.js/issues/1562) - Error message for syntax error missing location in 4.2.1+
 
 [Commits](https://github.com/wycats/handlebars.js/compare/v4.4.0...v4.4.1)
 
 ## v4.4.0 - September 29th, 2019
-- Added support for iterable objects in {{#each}} helper (#1557) - cf7545e
 
+- Added support for iterable objects in {{#each}} helper (#1557) - cf7545e
 
 [Commits](https://github.com/wycats/handlebars.js/compare/v4.3.4...v4.4.0)
 
 ## v4.3.4 - September 28th, 2019
+
 - fix: harden "propertyIsEnumerable"-check - ff4d827
 
 Compatibility notes:
+
 - No incompatibilities are known.
 
 [Commits](https://github.com/wycats/handlebars.js/compare/v4.3.3...v4.3.4)
 
 ## v4.3.3 - September 27th, 2019
- - fix test case for browsers that do not support __defineGetter__ - 8742bde
 
+- fix test case for browsers that do not support **defineGetter** - 8742bde
 
 [Commits](https://github.com/wycats/handlebars.js/compare/v4.3.2...v4.3.3)
 
 ## v4.3.2 - September 26th, 2019
+
 - Use Object.prototype.propertyIsEnumerable to check for constructors - 213c0bb, #1563
 
 Compatibility notes:
+
 - There are no breaking changes
 
 [Commits](https://github.com/wycats/handlebars.js/compare/v4.3.1...v4.3.2)
 
 ## v4.3.1 - September 25th, 2019
+
 Fixes:
 
 - do not break on precompiled templates from Handlebars >=4.0.0 <4.3.0 - 1266838, #1561
 - Ensure allowCallsToHelperMissing runtime option is optional in typings - 93444c5, 64ecb9e, #1560
 
-
-
 [Commits](https://github.com/wycats/handlebars.js/compare/v4.3.0...v4.3.1)
 
 ## v4.3.0 - September 24th, 2019
+
 Fixes:
 
 - Security: Disallow calling "helperMissing" and "blockHelperMissing" directly - 2078c72
@@ -181,18 +231,20 @@ Features:
 Breaking changes:
 
 Compatibility notes:
+
 - Compiler revision increased - 06b7224
+
   - This means that template compiled with versions prior to 4.3.0 will not work with runtimes >= 4.3.0
     The increase was done because the "helperMissing" and "blockHelperMissing" are now moved from the helpers
     to the internal "container.hooks" object, so old templates will not be able to call them anymore. We suggest
     that you always recompile your templates with the latest compiler in your build pipelines.
 
 - Disallow calling "helperMissing" and "blockHelperMissing" directly - 2078c72
-  - Calling "helperMissing" and "blockHelperMissing" directly from a template (like in `{{blockHelperMissing}}` was 
-    never intended and was part of the exploits that have been revealed early in 2019 
-    (see https://github.com/wycats/handlebars.js/issues/1495). *It is also part of a new exploit that 
-    is not captured by the earlier fix.* In order to harden Handlebars against such exploits, calling thos helpers 
-    is now not possible anymore. *Overriding* those helpers is still possible.
+  - Calling "helperMissing" and "blockHelperMissing" directly from a template (like in `{{blockHelperMissing}}` was
+    never intended and was part of the exploits that have been revealed early in 2019
+    (see https://github.com/wycats/handlebars.js/issues/1495). _It is also part of a new exploit that
+    is not captured by the earlier fix._ In order to harden Handlebars against such exploits, calling thos helpers
+    is now not possible anymore. _Overriding_ those helpers is still possible.
   - If you really need this behavior, you can set the runtime option `allowCallsToHelperMissing` to `true` and the
     calls will again be possible
 
@@ -200,86 +252,97 @@ Both bullet points imly that Handlebars is not 100% percent compatible to 4.2.0,
 
 We consider it more important to resolve a major security issue than to maintain 100% compatibility.
 
-    
-
 [Commits](https://github.com/wycats/handlebars.js/compare/v4.2.1...v4.3.0)
 
 ## v4.2.1 - September 20th, 2019
-Bugfixes: 
+
+Bugfixes:
 
 - The "browser" property in the package.json has been updated to use the common-js builds instead of the minified UMD - c55a7be, #1553
 
 Compatibility notes:
+
 - No compatibility issues should arise
 
 [Commits](https://github.com/wycats/handlebars.js/compare/v4.2.0...v4.2.1)
 
 ## v4.2.0 - September 3rd, 2019
+
 Chore/Test:
+
 - Use custom `grunt-saucelab` with current sauce-connect proxy - f119497
 - Add framework for various integration tests - f9cce4d
 - Add integration test for webpack - a57b682
 
-
 Bugfixes:
+
 - [#1544](https://github.com/wycats/handlebars.js/issues/1544) - Typescript types: `knownHelpers` doesnt allow for custom helpers ([@NickCis](https://api.github.com/users/NickCis))
 - [#1534](https://github.com/wycats/handlebars.js/pull/1534) - Add typings for "Handlebars.VM.resolvePartial ([@AndrewLeedham](https://api.github.com/users/AndrewLeedham))
 
 Features:
+
 - [#1540](https://github.com/wycats/handlebars.js/pull/1540) - added "browser"-property to package.json, resolves #1102 ([@ouijan](https://api.github.com/users/ouijan))
 
 Compatibility notes:
-- The new "browser"-property should not break anything, but you can never be sure. The integration test for webpack 
-  shows that it works, but if it doesn't please open an issue.
-
 
+- The new "browser"-property should not break anything, but you can never be sure. The integration test for webpack
+  shows that it works, but if it doesn't please open an issue.
 
 [Commits](https://github.com/wycats/handlebars.js/compare/v4.1.2-0...v4.2.0)
 
 ## v4.1.2-0 - August 25th, 2019
+
 [#1540](https://github.com/wycats/handlebars.js/pull/1540) - added browser to package.json, resolves #1102 ([@ouijan](https://api.github.com/users/ouijan))
 
 Compatibility notes:
+
 - We are not sure if imports via webpack are still working, which is why this release is a pre-release
 
 [Commits](https://github.com/wycats/handlebars.js/compare/v4.1.2...v4.1.2-0)
 
 ## v4.1.2 - April 13th, 2019
+
 Chore/Test:
+
 - [#1515](https://github.com/wycats/handlebars.js/pull/1515) - Port over linting and test for typings ([@zimmi88](https://api.github.com/users/zimmi88))
 - chore: add missing typescript dependency, add package-lock.json - 594f1e3
 - test: remove safari from saucelabs - 871accc
 
-Bugfixes: 
+Bugfixes:
+
 - fix: prevent RCE through the "lookup"-helper - cd38583
 
 Compatibility notes:
 
-Access to the constructor of a class thought `{{lookup obj "constructor" }}` is now prohibited. This closes 
+Access to the constructor of a class thought `{{lookup obj "constructor" }}` is now prohibited. This closes
 a leak that only half closed in versions 4.0.13 and 4.1.0, but it is a slight incompatibility.
 
 This kind of access is not the intended use of Handlebars and leads to the vulnerability described
-in #1495. We will **not** increase the major version, because such use is not intended or documented, 
+in #1495. We will **not** increase the major version, because such use is not intended or documented,
 and because of the potential impact of the issue (we fear that most people won't use a new major version
-and the issue may not be resolved on many systems). 
+and the issue may not be resolved on many systems).
 
 [Commits](https://github.com/wycats/handlebars.js/compare/v4.1.1...v4.1.2)
 
 ## v4.1.1 - March 16th, 2019
+
 Bugfixes:
+
 - fix: add "runtime.d.ts" to allow "require('handlebars/runtime')" in TypeScript - 5cedd62
 
 Refactorings:
+
 - replace "async" with "neo-async" - 048f2ce
 - use "substring"-function instead of "substr" - 445ae12
 
 Compatibility notes:
-- This is a bugfix release. There are no breaking change and no new features.
 
+- This is a bugfix release. There are no breaking change and no new features.
 
 [Commits](https://github.com/wycats/handlebars.js/compare/v4.1.0...v4.1.1)
 
 ## v4.1.0 - February 7th, 2019
+
 New Features
 
 - import TypeScript typings - 27ac1ee
@@ -312,11 +375,10 @@ document.getElementById('output').innerHTML = template(new SomeClass());
 
 This kind of access is not the intended use of Handlebars and leads to the vulnerability described in #1495. We will **not** increase the major version, because such use is not intended or documented, and because of the potential impact of the issue (we fear that most people won't use a new major version and the issue may not be resolved on many systems).
 
-
-
 [Commits](https://github.com/wycats/handlebars.js/compare/v4.0.12...v4.1.0)
 
 ## v4.0.12 - September 4th, 2018
+
 New features:
 
 - none
@@ -341,24 +403,26 @@ Removed obsolete code:
 - Update jsfiddle to 4.0.11 - 8947dd0
 
 Compatibility notes:
+
 - No compatibility issues are to be expected
 
 [Commits](https://github.com/wycats/handlebars.js/compare/v4.0.11...v4.0.12)
 
 ## v4.0.11 - October 17th, 2017
+
 - [#1391](https://github.com/wycats/handlebars.js/issues/1391) - `uglify-js` is unconditionally imported, but only listed as optional dependency ([@Turbo87](https://github.com/Turbo87))
 - [#1233](https://github.com/wycats/handlebars.js/issues/1233) - Unable to build under windows - error at test:bin task ([@blikblum](https://github.com/blikblum))
 - Update (C) year in the LICENSE file - 21386b6
 
 Compatibility notes:
+
 - This is a bugfix release. There are no breaking change and no new features.
 
 [Commits](https://github.com/wycats/handlebars.js/compare/v4.0.10...v4.0.11)
 
 ## v4.0.10 - May 21st, 2017
-- Fix regression in 4.0.9: Replace "Object.assign" (not support in IE) by "util/extend" - 0e953d1
-
 
+- Fix regression in 4.0.9: Replace "Object.assign" (not support in IE) by "util/extend" - 0e953d1
 
 [Commits](https://github.com/wycats/handlebars.js/compare/v4.0.9...v4.0.10)
 
@@ -367,30 +431,34 @@ Compatibility notes:
 - [#1327](https://github.com/wycats/handlebars.js/issues/1327) Handlebars.compile() does not modify "options" anymore
 - pending [#1331](https://github.com/wycats/handlebars.js/issues/1331) Attempts to build Handlebars in a Windows environment
   - Fix build in windows - cc554a5
-  - Ensure LF line-edings in handlebars-template fixtures (*.hbs) - ed879a6
+  - Ensure LF line-edings in handlebars-template fixtures (\*.hbs) - ed879a6
   - Run integration test with `node handlebars -a ...` on Windows - 2e21e2b
-  - Ensure LF line-edings in lexer-files (*.l) - bdfdbea
+  - Ensure LF line-edings in lexer-files (\*.l) - bdfdbea
   - Force LF line-endings for spec/artifacts - b50ef03
   - Use istanbul/lib/cli.js instead of node_modules/.bin/istanbul - 6e6269f
 - TravisCI: Publish valid semver tags independently of the branch - 7378f85
 
 Compatibility notes:
+
 - No compatibility issues are expected.
 
 [Commits](https://github.com/wycats/handlebars.js/compare/v4.0.8...v4.0.9)
 
 ## v4.0.8 - May 2nd, 2017
+
 - [#1341](https://github.com/wycats/handlebars.js/issues/1341) [#1342](https://github.com/wycats/handlebars.js/issues/1342) Allow partial-blocks to be executed without "options" ([@nknapp](https://github.com/nknapp)) - a00c598
 
 Compatibility notes:
+
 - No breaking changes
 
 [Commits](https://github.com/wycats/handlebars.js/compare/v4.0.7...v4.0.8)
 
 ## v4.0.7 - April 29th, 2017
+
 - [#1319](https://github.com/wycats/handlebars.js/issues/1319): Fix context-stack when calling block-helpers on null values ([@nknapp](https://github.com/nknapp)) - c8f4b57
 - [#1315](https://github.com/wycats/handlebars.js/pull/1315) Parser: Change suffix to use ES6 default module export ([@Turbo87](https://github.com/Turbo87))- b617375
-- [#1290](https://github.com/wycats/handlebars.js/pull/1290) [#1252](https://github.com/wycats/handlebars.js/issue/1290) Add more tests for partial-blocks and inline partials ([@nknapp](https://github.com/nknapp)) -  63a8e0c
+- [#1290](https://github.com/wycats/handlebars.js/pull/1290) [#1252](https://github.com/wycats/handlebars.js/issue/1290) Add more tests for partial-blocks and inline partials ([@nknapp](https://github.com/nknapp)) - 63a8e0c
 - [#1252](https://github.com/wycats/handlebars.js/issue/1290) Using @partial-block twice in a template not possible ([@nknapp](https://github.com/nknapp)) - 5a164d0
 - [#1310](https://github.com/wycats/handlebars.js/pull/1310) Avoid duplicate "sourceMappingURL=" lines. ([@joonas-lahtinen](https://github.com/joonas-lahtinen)) - 01b0f65
 - [#1275](https://github.com/wycats/handlebars.js/pull/1275) require('sys') is deprecated, using 'util' instead ([@travnels](https://github.com/travnels)) - 406f2ee
@@ -400,6 +468,7 @@ Compatibility notes:
 [Commits](https://github.com/lawnsea/handlebars.js/compare/v4.0.6...v4.0.7)
 
 ## v4.0.6 - November 12th, 2016
+
 - [#1243](https://github.com/wycats/handlebars.js/pull/1243) - Walk up data frames for nested @partial-block ([@lawnsea](https://github.com/lawnsea))
 - [#1210](https://github.com/wycats/handlebars.js/pull/1210) - Add a new lightweight package based on handlebars in the README ([@kabirbaidhya](https://github.com/kabirbaidhya))
 - [#1187](https://github.com/wycats/handlebars.js/pull/1187) - Ensure that existing blockParams and depths are respected on dupe programs ([@charleso](https://github.com/charleso))
@@ -407,7 +476,7 @@ Compatibility notes:
 - [#1177](https://github.com/wycats/handlebars.js/pull/1177) - Preserve License info in Closure Compiler ([@gennadiylitvinyuk](https://github.com/gennadiylitvinyuk))
 - [#1171](https://github.com/wycats/handlebars.js/pull/1171) - Contributing doc fix: failing thats -> failing tests ([@paulfalgout](https://github.com/paulfalgout))
 - [#1166](https://github.com/wycats/handlebars.js/pull/1166) - Update license date ([@timwangdev](https://github.com/timwangdev))
--  Update jsfiddle to point to latest - 959ee55 (originally dfc7554 by [@kpdecker](https://github.com/kpdecker))
+- Update jsfiddle to point to latest - 959ee55 (originally dfc7554 by [@kpdecker](https://github.com/kpdecker))
 - [#1163](https://github.com/wycats/handlebars.js/pull/1163) - Fix typos on decorators-api.md. ([@adjohnson916](https://github.com/adjohnson916))
 - Drop extra Error params - 8c19874 (originally 63fdb92 by [@kpdecker](https://github.com/kpdecker))
 - [#1153](https://github.com/wycats/handlebars.js/pull/1153) - Add documentation for running tests to contributing.md ([@ryanmurakami](https://github.com/ryanmurakami))
@@ -421,6 +490,7 @@ Compatibility notes:
 [Commits](https://github.com/wycats/handlebars.js/compare/v4.0.5...v4.0.6)
 
 ## v4.0.5 - November 19th, 2015
+
 - [#1132](https://github.com/wycats/handlebars.js/pull/1132) - Update uglify-js to avoid vulnerability ([@plynchnlm](https://github.com/plynchnlm))
 - [#1129](https://github.com/wycats/handlebars.js/issues/1129) - Minified lib returns an empty string ([@bricss](https://github.com/bricss))
 - Return current handlebars instance from noConflict - 685cf92
@@ -433,12 +503,14 @@ Compatibility notes:
 [Commits](https://github.com/wycats/handlebars.js/compare/v4.0.4...v4.0.5)
 
 ## v4.0.4 - October 29th, 2015
+
 - [#1121](https://github.com/wycats/handlebars.js/pull/1121) - Include partial name in 'undefined partial' exception message ([@shinypb](https://github.com/shinypb))
 - [#1125](https://github.com/wycats/handlebars.js/pull/1125) - Add promised-handlebars to "in-the-wild"-list ([@nknapp](https://github.com/nknapp))
 
 [Commits](https://github.com/wycats/handlebars.js/compare/v4.0.3...v4.0.4)
 
 ## v4.0.3 - September 23rd, 2015
+
 - [#1099](https://github.com/wycats/handlebars.js/issues/1099) - @partial-block is overridden ([@btmorex](https://github.com/btmorex))
 - [#1093](https://github.com/wycats/handlebars.js/issues/1093) - #each skips iteration on undefined values ([@florianpilz](https://github.com/florianpilz))
 - [#1092](https://github.com/wycats/handlebars.js/issues/1092) - Square braces in key name ([@distantnative](https://github.com/distantnative))
@@ -446,22 +518,26 @@ Compatibility notes:
 - [#1090](https://github.com/wycats/handlebars.js/pull/1090) - grammar fixes in 4.0.0 release notes ([@nikolas](https://github.com/nikolas))
 
 Compatibility notes:
+
 - `each` iteration with `undefined` values has been restored to the 3.0 behaviors. Helper calls with undefined context values will now execute against an arbitrary empty object to avoid executing against global object in non-strict mode.
 - `]` can now be included in `[]` wrapped identifiers by escaping with `\`. Any `[]` identifiers that include `\` will now have to properly escape these values.
 
 [Commits](https://github.com/wycats/handlebars.js/compare/v4.0.2...v4.0.3)
 
 ## v4.0.2 - September 4th, 2015
+
 - [#1089](https://github.com/wycats/handlebars.js/issues/1089) - "Failover content" not working in multiple levels of inline partials ([@michaellopez](https://github.com/michaellopez))
 
 [Commits](https://github.com/wycats/handlebars.js/compare/v4.0.1...v4.0.2)
 
 ## v4.0.1 - September 2nd, 2015
+
 - Fix failure when using decorators in partials - 05b82a2
 
 [Commits](https://github.com/wycats/handlebars.js/compare/v4.0.0...v4.0.1)
 
 ## v4.0.0 - September 1st, 2015
+
 - [#1082](https://github.com/wycats/handlebars.js/pull/1082) - Decorators and Inline Partials ([@kpdecker](https://github.com/kpdecker))
 - [#1076](https://github.com/wycats/handlebars.js/pull/1076) - Implement partial blocks ([@kpdecker](https://github.com/kpdecker))
 - [#1087](https://github.com/wycats/handlebars.js/pull/1087) - Fix #each when last object entry has empty key ([@denniskuczynski](https://github.com/denniskuczynski))
@@ -497,6 +573,7 @@ Compatibility notes:
 - Fix location information for programs - [93faffa](https://github.com/wycats/handlebars.js/commit/93faffa)
 
 Compatibility notes:
+
 - Depthed paths are now conditionally pushed on to the stack. If the helper uses the same context, then a new stack is not created. This leads to behavior that better matches expectations for helpers like `if` that do not seem to alter the context. Any instances of `../` in templates will need to be checked for the correct behavior under 4.0.0. In general templates will either reduce the number of `../` instances or leave them as is. See [#1028](https://github.com/wycats/handlebars.js/issues/1028).
 - The `=` character is now HTML escaped. This closes a potential exploit case when using unquoted attributes, i.e. `<div foo={{bar}}>`. In general it's recommended that attributes always be quoted when their values are generated from a mustache to avoid any potential exploit surfaces.
 - AST constructors have been dropped in favor of plain old javascript objects
@@ -505,22 +582,25 @@ Compatibility notes:
 [Commits](https://github.com/wycats/handlebars.js/compare/v3.0.3...v4.0.0)
 
 ## v3.0.3 - April 28th, 2015
+
 - [#1004](https://github.com/wycats/handlebars.js/issues/1004) - Latest version breaks with RequireJS (global is undefined) ([@boskee](https://github.com/boskee))
 
 [Commits](https://github.com/wycats/handlebars.js/compare/v3.0.2...v3.0.3)
 
 ## v3.0.2 - April 20th, 2015
+
 - [#998](https://github.com/wycats/handlebars.js/pull/998) - Add full support for es6 ([@kpdecker](https://github.com/kpdecker))
 - [#994](https://github.com/wycats/handlebars.js/issues/994) - Access Handlebars.Visitor in browser ([@tamlyn](https://github.com/tamlyn))
 - [#990](https://github.com/wycats/handlebars.js/issues/990) - Allow passing null/undefined literals subexpressions ([@blimmer](https://github.com/blimmer))
 - [#989](https://github.com/wycats/handlebars.js/issues/989) - Source-map error with requirejs ([@SteppeEagle](https://github.com/SteppeEagle))
-- [#967](https://github.com/wycats/handlebars.js/issues/967) - can't access "this" property  ([@75lb](https://github.com/75lb))
+- [#967](https://github.com/wycats/handlebars.js/issues/967) - can't access "this" property ([@75lb](https://github.com/75lb))
 - Use captureStackTrace for error handler - a009a97
 - Ignore branches tested without coverage monitoring - 37a664b
 
 [Commits](https://github.com/wycats/handlebars.js/compare/v3.0.1...v3.0.2)
 
 ## v3.0.1 - March 24th, 2015
+
 - [#984](https://github.com/wycats/handlebars.js/pull/984) - Adding documentation for passing arguments into partials ([@johneke](https://github.com/johneke))
 - [#973](https://github.com/wycats/handlebars.js/issues/973) - version 3 is slower than version 2 ([@elover](https://github.com/elover))
 - [#966](https://github.com/wycats/handlebars.js/issues/966) - "handlebars --version" does not work with v3.0.0 ([@abloomston](https://github.com/abloomston))
@@ -530,6 +610,7 @@ Compatibility notes:
 [Commits](https://github.com/wycats/handlebars.js/compare/v3.0.0...v3.0.1)
 
 ## v3.0.0 - February 10th, 2015
+
 - [#941](https://github.com/wycats/handlebars.js/pull/941) - Add support for dynamic partial names ([@kpdecker](https://github.com/kpdecker))
 - [#940](https://github.com/wycats/handlebars.js/pull/940) - Add missing reserved words so compiler knows to use array syntax: ([@mattflaschen](https://github.com/mattflaschen))
 - [#938](https://github.com/wycats/handlebars.js/pull/938) - Fix example using #with helper ([@diwo](https://github.com/diwo))
@@ -559,6 +640,7 @@ Compatibility notes:
 - Lookup partials when undefined - 617dd57
 
 Compatibility notes:
+
 - Runtime breaking changes. Must match 3.x runtime and precompiler.
 - The AST has been upgraded to a public API.
   - There are a number of changes to this, but the format is now documented in docs/compiler-api.md
@@ -568,6 +650,7 @@ Compatibility notes:
 - `SafeString` is now duck typed on `toHTML`
 
 New Features:
+
 - noConflict
 - Source Maps
 - Block Params
@@ -580,6 +663,7 @@ New Features:
 [Commits](https://github.com/wycats/handlebars.js/compare/v2.0.0...v3.0.0)
 
 ## v2.0.0 - September 1st, 2014
+
 - Update jsfiddle to 2.0.0-beta.1 - 0670f65
 - Add contrib note regarding handlebarsjs.com docs - 4d17e3c
 - Play nice with gemspec version numbers - 64d5481
@@ -587,6 +671,7 @@ New Features:
 [Commits](https://github.com/wycats/handlebars.js/compare/v2.0.0-beta.1...v2.0.0)
 
 ## v2.0.0-beta.1 - August 26th, 2014
+
 - [#787](https://github.com/wycats/handlebars.js/pull/787) - Remove whitespace surrounding standalone statements ([@kpdecker](https://github.com/kpdecker))
 - [#827](https://github.com/wycats/handlebars.js/issues/827) - Render false literal as “false” ([@scoot557](https://github.com/scoot557))
 - [#767](https://github.com/wycats/handlebars.js/issues/767) - Subexpressions bug with hash and context ([@evensoul](https://github.com/evensoul))
@@ -596,7 +681,7 @@ New Features:
   - [#837](https://github.com/wycats/handlebars.js/issues/837) - Strange input for custom helper ( foo.bar == false when foo is undefined ) ([@zordius](https://github.com/zordius))
 - [#819](https://github.com/wycats/handlebars.js/pull/819) - Implement recursive field lookup ([@kpdecker](https://github.com/kpdecker))
 - [#764](https://github.com/wycats/handlebars.js/issues/764) - This reference not working for helpers ([@kpdecker](https://github.com/kpdecker))
-- [#773](https://github.com/wycats/handlebars.js/issues/773) - Implicit parameters in {{#each}} introduces a peculiarity in helpers calling convention  ([@Bertrand](https://github.com/Bertrand))
+- [#773](https://github.com/wycats/handlebars.js/issues/773) - Implicit parameters in {{#each}} introduces a peculiarity in helpers calling convention ([@Bertrand](https://github.com/Bertrand))
 - [#783](https://github.com/wycats/handlebars.js/issues/783) - helperMissing and consistency for different expression types ([@ErisDS](https://github.com/ErisDS))
 - [#795](https://github.com/wycats/handlebars.js/pull/795) - Turn the precompile script into a wrapper around a module. ([@jwietelmann](https://github.com/jwietelmann))
 - [#823](https://github.com/wycats/handlebars.js/pull/823) - Support inverse sections on the with helper ([@dan-manges](https://github.com/dan-manges))
@@ -609,13 +694,14 @@ New Features:
 - Fix compiler program de-duping - 9e3f824
 
 Compatibility notes:
+
 - The default build now outputs a generic UMD wrapper. This should be transparent change but may cause issues in some environments.
 - Runtime compatibility breaks in both directions. Ensure that both compiler and client are upgraded to 2.0.0-beta.1 or higher at the same time.
   - `programWithDepth` has been removed an instead an array of context values is passed to fields needing depth lookups.
 - `false` values are now printed to output rather than silently dropped
 - Lines containing only block statements and whitespace are now removed. This matches the Mustache spec but may cause issues with code that expects whitespace to exist but would not otherwise.
 - Partials that are standalone will now indent their rendered content
-- `AST.ProgramNode`'s signature has changed. 
+- `AST.ProgramNode`'s signature has changed.
 - Numerious methods/features removed from pseudo-API classes
   - `JavaScriptCompiler.register`
   - `JavaScriptCompiler.replaceStack` no longer supports non-inline replace
@@ -630,11 +716,13 @@ Compatibility notes:
 [Commits](https://github.com/wycats/handlebars.js/compare/v2.0.0-alpha.4...v2.0.0-beta.1)
 
 ## v2.0.0-alpha.4 - May 19th, 2014
+
 - Expose setup wrappers for compiled templates - 3638874
 
 [Commits](https://github.com/wycats/handlebars.js/compare/v2.0.0-alpha.3...v2.0.0-alpha.4)
 
 ## v2.0.0-alpha.3 - May 19th, 2014
+
 - [#797](https://github.com/wycats/handlebars.js/pull/797) - Pass full helper ID to helperMissing when options are provided ([@tomdale](https://github.com/tomdale))
 - [#793](https://github.com/wycats/handlebars.js/pull/793) - Ensure isHelper is coerced to a boolean ([@mmun](https://github.com/mmun))
 - Refactor template init logic - 085e5e1
@@ -642,6 +730,7 @@ Compatibility notes:
 [Commits](https://github.com/wycats/handlebars.js/compare/v2.0.0-alpha.2...v2.0.0-alpha.3)
 
 ## v2.0.0-alpha.2 - March 6th, 2014
+
 - [#756](https://github.com/wycats/handlebars.js/pull/756) - fix bug in IE<=8 (no Array::map), closes #751 ([@jenseng](https://github.com/jenseng))
 - [#749](https://github.com/wycats/handlebars.js/pull/749) - properly handle multiple subexpressions in the same hash, fixes #748 ([@jenseng](https://github.com/jenseng))
 - [#743](https://github.com/wycats/handlebars.js/issues/743) - subexpression confusion/problem? ([@waynedpj](https://github.com/waynedpj))
@@ -651,11 +740,13 @@ Compatibility notes:
 - Temporarily kill the AWS publish CI step - 8347ee2
 
 Compatibility notes:
+
 - A JSON polyfill is required to run the compiler under IE8 and below. It's recommended that the precompiler be used in lieu of running the compiler on these legacy environments.
 
 [Commits](https://github.com/wycats/handlebars.js/compare/v2.0.0-alpha.1...v2.0.0-alpha.2)
 
 ## v2.0.0-alpha.1 - February 10th, 2014
+
 - [#182](https://github.com/wycats/handlebars.js/pull/182) - Allow passing hash parameters to partials ([@kpdecker](https://github.com/kpdecker))
 - [#392](https://github.com/wycats/handlebars.js/pull/392) - Access to root context in partials and helpers ([@kpdecker](https://github.com/kpdecker))
 - [#472](https://github.com/wycats/handlebars.js/issues/472) - Helpers cannot have decimal parameters ([@kayleg](https://github.com/kayleg))
@@ -678,6 +769,7 @@ Compatibility notes:
 - [#704](https://github.com/wycats/handlebars.js/pull/704) - JavaScript Compiler Cleanup ([@blakeembrey](https://github.com/blakeembrey))
 
 Compatibility notes:
+
 - `helperMissing` helper no longer has the indexed name argument. Helper name is now available via `options.name`.
 - Precompiler output has changed, which breaks compatibility with prior versions of the runtime and precompiled output.
 - `JavaScriptCompiler.compilerInfo` now returns generic objects rather than javascript source.
@@ -690,6 +782,7 @@ Compatibility notes:
 [Commits](https://github.com/wycats/handlebars.js/compare/v1.3.0...v2.0.0-alpha.1)
 
 ## v1.3.0 - January 1st, 2014
+
 - [#690](https://github.com/wycats/handlebars.js/pull/690) - Added support for subexpressions ([@machty](https://github.com/machty))
 - [#696](https://github.com/wycats/handlebars.js/pull/696) - Fix for reserved keyword "default" ([@nateirwin](https://github.com/nateirwin))
 - [#692](https://github.com/wycats/handlebars.js/pull/692) - add line numbers to nodes when parsing ([@fivetanley](https://github.com/fivetanley))
@@ -704,12 +797,14 @@ Compatibility notes:
 [Commits](https://github.com/wycats/handlebars.js/compare/v1.2.1...v1.3.0)
 
 ## v1.2.1 - December 26th, 2013
+
 - [#684](https://github.com/wycats/handlebars.js/pull/684) - Allow any number of trailing characters for valid JavaScript variable ([@blakeembrey](https://github.com/blakeembrey))
 - [#686](https://github.com/wycats/handlebars.js/pull/686) - Falsy AMD module names in version 1.2.0 ([@kpdecker](https://github.com/kpdecker))
 
 [Commits](https://github.com/wycats/handlebars.js/compare/v1.2.0...v1.2.1)
 
 ## v1.2.0 - December 23rd, 2013
+
 - [#675](https://github.com/wycats/handlebars.js/issues/675) - Cannot compile empty template for partial ([@erwinw](https://github.com/erwinw))
 - [#677](https://github.com/wycats/handlebars.js/issues/677) - Triple brace statements fail under IE ([@hamzaCM](https://github.com/hamzaCM))
 - [#655](https://github.com/wycats/handlebars.js/issues/655) - Loading Handlebars using bower ([@niki4810](https://github.com/niki4810))
@@ -729,6 +824,7 @@ Compatibility notes:
 - Fix handling of boolean escape in MustacheNode - b4968bb
 
 Compatibility notes:
+
 - `@index` and `@first` are now supported for `each` iteration on objects
 - `Handlebars.VM.checkRevision` and `Handlebars.JavaScriptCompiler.prototype.compilerInfo` now available to modify the version checking behavior.
 - Browserify users may link to the runtime library via `require('handlebars/runtime')`
@@ -770,16 +866,15 @@ Compatibility notes:
 - [#571](https://github.com/wycats/handlebars.js/issues/571) - uglify upgrade breaks compatibility with older versions of node
 - [#587](https://github.com/wycats/handlebars.js/issues/587) - Partial inside partial breaks?
 
-
 Compatibility notes:
-- The project now includes separate artifacts for AMD, CommonJS, and global objects. 
+
+- The project now includes separate artifacts for AMD, CommonJS, and global objects.
   - AMD: Users may load the bundled `handlebars.amd.js` or `handlebars.runtime.amd.js` files or load individual modules directly. AMD users should also note that the handlebars object is exposed via the `default` field on the imported object. This [gist](https://gist.github.com/wycats/7417be0dc361a69d5916) provides some discussion of possible compatibility shims.
   - CommonJS/Node: Node loading occurs as normal via `require`
   - Globals: The `handlebars.js` and `handlebars.runtime.js` files should behave in the same manner as the v1.0.12 / 1.0.0 release.
-- Build artifacts have been removed from the repository. [npm][npm], [components/handlebars.js][components], [cdnjs][cdnjs], or the [builds page][builds-page] should now be used as the source of built artifacts. 
+- Build artifacts have been removed from the repository. [npm][npm], [components/handlebars.js][components], [cdnjs][cdnjs], or the [builds page][builds-page] should now be used as the source of built artifacts.
 - Context-stored helpers are now always passed the `options` hash. Previously no-argument helpers did not have this argument.
 
-
 [Commits](https://github.com/wycats/handlebars.js/compare/v1.0.12...v1.1.0)
 
 ## v1.0.12 / 1.0.0 - May 31 2013
@@ -797,6 +892,7 @@ Compatibility notes:
 - Docs updates
 
 Compatibility notes:
+
 - The parser is now stricter on `{{{`, requiring that the end token be `}}}`. Templates that do not
   follow this convention should add the additional brace value.
 - Code that relies on global the namespace being muted when custom helpers or partials are passed will need to explicitly pass an `undefined` value for any helpers that should not be available.
@@ -863,13 +959,13 @@ changed.
 Instead of:
 
 ```js
-template(context, helpers, partials, [data])
+template(context, helpers, partials, [data]);
 ```
 
 Use:
 
 ```js
-template(context, {helpers: helpers, partials: partials, data: data})
+template(context, { helpers: helpers, partials: partials, data: data });
 ```
 
 [builds-page]: http://builds.handlebarsjs.com.s3.amazonaws.com/index.html

From 91a1b5d2f456cb733cbd88149fc9270973db79d7 Mon Sep 17 00:00:00 2001
From: Nils Knappmeier <github@knappi.org>
Date: Wed, 8 Jan 2020 23:45:15 +0100
Subject: [PATCH 24/24] v4.6.0

---
 components/bower.json           | 2 +-
 components/handlebars.js.nuspec | 2 +-
 components/package.json         | 2 +-
 lib/handlebars/base.js          | 2 +-
 package.json                    | 2 +-
 5 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/components/bower.json b/components/bower.json
index 07e2baa96..c4501c0f9 100644
--- a/components/bower.json
+++ b/components/bower.json
@@ -1,6 +1,6 @@
 {
   "name": "handlebars",
-  "version": "4.5.3",
+  "version": "4.6.0",
   "main": "handlebars.js",
   "license": "MIT",
   "dependencies": {}
diff --git a/components/handlebars.js.nuspec b/components/handlebars.js.nuspec
index e8d52d4ca..34886aea7 100644
--- a/components/handlebars.js.nuspec
+++ b/components/handlebars.js.nuspec
@@ -2,7 +2,7 @@
 <package>
 	<metadata>
 		<id>handlebars.js</id>
-		<version>4.5.3</version>
+		<version>4.6.0</version>
 		<authors>handlebars.js Authors</authors>
 		<licenseUrl>https://github.com/wycats/handlebars.js/blob/master/LICENSE</licenseUrl>
 		<projectUrl>https://github.com/wycats/handlebars.js/</projectUrl>
diff --git a/components/package.json b/components/package.json
index 9623086b4..8e66182b2 100644
--- a/components/package.json
+++ b/components/package.json
@@ -1,6 +1,6 @@
 {
   "name": "handlebars",
-  "version": "4.5.3",
+  "version": "4.6.0",
   "license": "MIT",
   "jspm": {
     "main": "handlebars",
diff --git a/lib/handlebars/base.js b/lib/handlebars/base.js
index c655e8f09..88ba0ddcc 100644
--- a/lib/handlebars/base.js
+++ b/lib/handlebars/base.js
@@ -4,7 +4,7 @@ import { registerDefaultHelpers } from './helpers';
 import { registerDefaultDecorators } from './decorators';
 import logger from './logger';
 
-export const VERSION = '4.5.3';
+export const VERSION = '4.6.0';
 export const COMPILER_REVISION = 8;
 export const LAST_COMPATIBLE_COMPILER_REVISION = 7;
 
diff --git a/package.json b/package.json
index c164ea9c2..dadcbb543 100644
--- a/package.json
+++ b/package.json
@@ -1,7 +1,7 @@
 {
   "name": "handlebars",
   "barename": "handlebars",
-  "version": "4.5.3",
+  "version": "4.6.0",
   "description": "Handlebars provides the power necessary to let you build semantic templates effectively with no frustration",
   "homepage": "http://www.handlebarsjs.com/",
   "keywords": [
