<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[174852] trunk/Source/WebInspectorUI</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/174852">174852</a></dd>
<dt>Author</dt> <dd>jonowells@apple.com</dd>
<dt>Date</dt> <dd>2014-10-17 16:50:49 -0700 (Fri, 17 Oct 2014)</dd>
</dl>

<h3>Log Message</h3>
<pre>Web Inspector: Add ESLint open source library to the inspector
https://bugs.webkit.org/show_bug.cgi?id=137714

Reviewed by Joseph Pecoraro.

This adds back the eslint.js external library with a correction to Scripts/copy-user-interface-resources.pl
to prevent a build failure.

* Scripts/copy-user-interface-resources.pl: Added copy commands for ESLint.js.
* UserInterface/External/ESLint/LICENSE: Added.
* UserInterface/External/ESLint/eslint.js: Added.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebInspectorUIChangeLog">trunk/Source/WebInspectorUI/ChangeLog</a></li>
<li><a href="#trunkSourceWebInspectorUIScriptscopyuserinterfaceresourcespl">trunk/Source/WebInspectorUI/Scripts/copy-user-interface-resources.pl</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceExternalESLintLICENSE">trunk/Source/WebInspectorUI/UserInterface/External/ESLint/LICENSE</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceExternalESLinteslintjs">trunk/Source/WebInspectorUI/UserInterface/External/ESLint/eslint.js</a></li>
</ul>

<h3>Property Changed</h3>
<ul>
<li><a href="#trunkSourceWebInspectorUIScriptscopyuserinterfaceresourcespl">trunk/Source/WebInspectorUI/Scripts/copy-user-interface-resources.pl</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebInspectorUIChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/ChangeLog (174851 => 174852)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/ChangeLog        2014-10-17 23:26:12 UTC (rev 174851)
+++ trunk/Source/WebInspectorUI/ChangeLog        2014-10-17 23:50:49 UTC (rev 174852)
</span><span class="lines">@@ -1,3 +1,17 @@
</span><ins>+2014-10-17  Jono Wells  &lt;jonowells@apple.com&gt;
+
+        Web Inspector: Add ESLint open source library to the inspector
+        https://bugs.webkit.org/show_bug.cgi?id=137714
+
+        Reviewed by Joseph Pecoraro.
+
+        This adds back the eslint.js external library with a correction to Scripts/copy-user-interface-resources.pl
+        to prevent a build failure.
+
+        * Scripts/copy-user-interface-resources.pl: Added copy commands for ESLint.js.
+        * UserInterface/External/ESLint/LICENSE: Added.
+        * UserInterface/External/ESLint/eslint.js: Added.
+
</ins><span class="cx"> 2014-10-14  Jono Wells  &lt;jonowells@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Web Inspector: Add ESLint open source library to the inspector
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIScriptscopyuserinterfaceresourcespl"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/Scripts/copy-user-interface-resources.pl (174851 => 174852)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/Scripts/copy-user-interface-resources.pl        2014-10-17 23:26:12 UTC (rev 174851)
+++ trunk/Source/WebInspectorUI/Scripts/copy-user-interface-resources.pl        2014-10-17 23:50:49 UTC (rev 174852)
</span><span class="lines">@@ -100,9 +100,11 @@
</span><span class="cx"> my $protocolDir = File::Spec-&gt;catdir($targetResourcePath, 'Protocol');
</span><span class="cx"> my $codeMirrorPath = File::Spec-&gt;catdir($uiRoot, 'External', 'CodeMirror');
</span><span class="cx"> my $esprimaPath = File::Spec-&gt;catdir($uiRoot, 'External', 'Esprima');
</span><ins>+my $eslintPath = File::Spec-&gt;catdir($uiRoot, 'External', 'ESLint');
</ins><span class="cx"> 
</span><span class="cx"> my $codeMirrorLicense = readLicenseFile(File::Spec-&gt;catfile($codeMirrorPath, 'LICENSE'));
</span><del>-my $esprimaMirrorLicense = readLicenseFile(File::Spec-&gt;catfile($esprimaPath, 'LICENSE'));
</del><ins>+my $esprimaLicense = readLicenseFile(File::Spec-&gt;catfile($esprimaPath, 'LICENSE'));
+my $eslintLicense = readLicenseFile(File::Spec-&gt;catfile($eslintPath, 'LICENSE'));
</ins><span class="cx"> 
</span><span class="cx"> make_path($protocolDir, $targetResourcePath);
</span><span class="cx"> 
</span><span class="lines">@@ -123,6 +125,9 @@
</span><span class="cx">     # Combine the Esprima JavaScript files in Production builds into a single file (Esprima.js).
</span><span class="cx">     system($combineResourcesCmd, '--input-dir', 'External/Esprima', '--input-html', $derivedSourcesMainHTML, '--input-html-dir', $uiRoot, '--derived-sources-dir', $derivedSourcesDir, '--output-dir', $derivedSourcesDir, '--output-script-name', 'Esprima.js');
</span><span class="cx"> 
</span><ins>+    # Combine the ESLint JavaScript files in Production builds into a single file (ESLint.js).
+    system($combineResourcesCmd, '--input-dir', 'External/ESLint', '--input-html', $derivedSourcesMainHTML, '--input-html-dir', $uiRoot, '--derived-sources-dir', $derivedSourcesDir, '--output-dir', $derivedSourcesDir, '--output-script-name', 'ESLint.js');
+
</ins><span class="cx">     # Remove console.assert calls from the Main.js file.
</span><span class="cx">     my $derivedSourcesMainJS = File::Spec-&gt;catfile($derivedSourcesDir, 'Main.js');
</span><span class="cx">     system(File::Spec-&gt;catfile($scriptsRoot, 'remove-console-asserts.pl'), '--input-script', $derivedSourcesMainJS, '--output-script', $derivedSourcesMainJS);
</span><span class="lines">@@ -155,8 +160,12 @@
</span><span class="cx"> 
</span><span class="cx">     # Export the license into Esprima.js.
</span><span class="cx">     my $targetEsprimaJS = File::Spec-&gt;catfile($targetResourcePath, 'Esprima.js');
</span><del>-    seedFile($targetEsprimaJS, $esprimaMirrorLicense);
</del><ins>+    seedFile($targetEsprimaJS, $esprimaLicense);
</ins><span class="cx"> 
</span><ins>+    # Export the license into ESLint.js.
+    my $targetESLintJS = File::Spec-&gt;catfile($targetResourcePath, 'ESLint.js');
+    seedFile($targetESLintJS, $eslintLicense);
+
</ins><span class="cx">     # Minify the Main.js and Main.css files, with Main.js appending to the license that was exported above.
</span><span class="cx">     my $jsMinScript = File::Spec-&gt;catfile($scriptsRoot, 'jsmin.py');
</span><span class="cx">     my $cssMinScript = File::Spec-&gt;catfile($scriptsRoot, 'cssmin.py');
</span><span class="lines">@@ -173,6 +182,10 @@
</span><span class="cx">     my $derivedSouressEsprimaJS = File::Spec-&gt;catfile($derivedSourcesDir, 'Esprima.js');
</span><span class="cx">     system(qq(&quot;$python&quot; &quot;$jsMinScript&quot; &lt; &quot;$derivedSouressEsprimaJS&quot; &gt;&gt; &quot;$targetEsprimaJS&quot;)) and die &quot;Failed to minify $derivedSouressEsprimaJS: $!&quot;;
</span><span class="cx"> 
</span><ins>+    # Minify the ESLint.js file, appending to the license that was exported above.
+    my $derivedSouressESLintJS = File::Spec-&gt;catfile($derivedSourcesDir, 'ESLint.js');
+    system(qq(&quot;$python&quot; &quot;$jsMinScript&quot; &lt; &quot;$derivedSouressESLintJS&quot; &gt;&gt; &quot;$targetESLintJS&quot;)) and die &quot;Failed to minify $derivedSouressESLintJS: $!&quot;;
+
</ins><span class="cx">     # Copy over Main.html and the Images directory.
</span><span class="cx">     copy($derivedSourcesMainHTML, File::Spec-&gt;catfile($targetResourcePath, 'Main.html'));
</span><span class="cx"> 
</span><span class="cx">Property changes on: trunk/Source/WebInspectorUI/Scripts/copy-user-interface-resources.pl
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="allowtabs"></a>
<div class="addfile"><h4>Added: allow-tabs</h4></div>
<a id="trunkSourceWebInspectorUIUserInterfaceExternalESLintLICENSE"></a>
<div class="addfile"><h4>Added: trunk/Source/WebInspectorUI/UserInterface/External/ESLint/LICENSE (0 => 174852)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/External/ESLint/LICENSE                                (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/External/ESLint/LICENSE        2014-10-17 23:50:49 UTC (rev 174852)
</span><span class="lines">@@ -0,0 +1,19 @@
</span><ins>+Copyright (c) 2014 TJ Holowaychuk &lt;tj@vision-media.ca&gt;
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the 'Software'), to deal
+in the Software without restriction, including without limitation the rights to 
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
</ins></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceExternalESLinteslintjs"></a>
<div class="addfile"><h4>Added: trunk/Source/WebInspectorUI/UserInterface/External/ESLint/eslint.js (0 => 174852)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/External/ESLint/eslint.js                                (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/External/ESLint/eslint.js        2014-10-17 23:50:49 UTC (rev 174852)
</span><span class="lines">@@ -0,0 +1,18223 @@
</span><ins>+!function(e){if(&quot;object&quot;==typeof exports&amp;&amp;&quot;undefined&quot;!=typeof module)module.exports=e();else if(&quot;function&quot;==typeof define&amp;&amp;define.amd)define([],e);else{var f;&quot;undefined&quot;!=typeof window?f=window:&quot;undefined&quot;!=typeof global?f=global:&quot;undefined&quot;!=typeof self&amp;&amp;(f=self),f.eslint=e()}}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require==&quot;function&quot;&amp;&amp;require;if(!u&amp;&amp;a)return a(o,!0);if(i)return i(o,!0);var f=new Error(&quot;Cannot find module '&quot;+o+&quot;'&quot;);throw f.code=&quot;MODULE_NOT_FOUND&quot;,f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require==&quot;function&quot;&amp;&amp;require;for(var o=0;o&lt;r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
+module.exports={
+    &quot;builtin&quot;: {
+        &quot;NaN&quot;: false,
+        &quot;Infinity&quot;: false,
+        &quot;undefined&quot;: false,
+        &quot;eval&quot;: false,
+
+        &quot;parseFloat&quot;: false,
+        &quot;parseInt&quot;: false,
+        &quot;isNaN&quot;: false,
+        &quot;isFinite&quot;: false,
+
+        &quot;decodeURI&quot;: false,
+        &quot;decodeURIComponent&quot;: false,
+        &quot;encodeURI&quot;: false,
+        &quot;encodeURIComponent&quot;: false,
+
+        &quot;Object&quot;: false,
+        &quot;Function&quot;: false,
+        &quot;Array&quot;: false,
+        &quot;String&quot;: false,
+        &quot;Boolean&quot;: false,
+        &quot;Map&quot;: false,
+        &quot;Number&quot;: false,
+        &quot;Date&quot;: false,
+        &quot;RegExp&quot;: false,
+        &quot;Error&quot;: false,
+        &quot;EvalError&quot;: false,
+        &quot;RangeError&quot;: false,
+        &quot;ReferenceError&quot;: false,
+        &quot;Set&quot;: false,
+        &quot;SyntaxError&quot;: false,
+        &quot;TypeError&quot;: false,
+        &quot;URIError&quot;: false,
+        &quot;WeakMap&quot;: false,
+        &quot;WeakSet&quot;: false,
+
+        &quot;ArrayBuffer&quot;: false,
+        &quot;Float32Array&quot;: false,
+        &quot;Float64Array&quot;: false,
+        &quot;Int16Array&quot;: false,
+        &quot;Int32Array&quot;: false,
+        &quot;Int8Array&quot;: false,
+        &quot;Uint16Array&quot;: false,
+        &quot;Uint32Array&quot;: false,
+        &quot;Uint8Array&quot;: false,
+        &quot;Uint8ClampedArray&quot;: false,
+
+        &quot;Math&quot;: false,
+        &quot;JSON&quot;: false,
+
+        &quot;toString&quot;: false,
+        &quot;hasOwnProperty&quot;: false,
+        &quot;valueOf&quot;: false,
+        &quot;propertyIsEnumerable&quot;: false,
+        &quot;constructor&quot;: false,
+        &quot;isPrototypeOf&quot;: false,
+        &quot;toLocaleString&quot;: false
+    },
+
+    &quot;browser&quot;: {
+        &quot;globals&quot;: {
+            &quot;addEventListener&quot;: false,
+            &quot;applicationCache&quot;: false,
+            &quot;atob&quot;: false,
+            &quot;Audio&quot;: false,
+            &quot;Blob&quot;: false,
+            &quot;blur&quot;: false,
+            &quot;btoa&quot;: false,
+            &quot;cancelAnimationFrame&quot;: false,
+            &quot;clearInterval&quot;: false,
+            &quot;clearTimeout&quot;: false,
+            &quot;close&quot;: false,
+            &quot;closed&quot;: false,
+            &quot;crypto&quot;: false,
+            &quot;DataView&quot;: false,
+            &quot;defaultStatus&quot;: false,
+            &quot;devicePixelRatio&quot;: false,
+            &quot;dispatchEvent&quot;: false,
+            &quot;document&quot;: false,
+            &quot;DOMParser&quot;: false,
+            &quot;Element&quot;: false,
+            &quot;FileReader&quot;: false,
+            &quot;find&quot;: false,
+            &quot;focus&quot;: false,
+            &quot;FormData&quot;: false,
+            &quot;frameElement&quot;: false,
+            &quot;frames&quot;: false,
+            &quot;getComputedStyle&quot;: false,
+            &quot;getSelection&quot;: false,
+            &quot;history&quot;: false,
+            &quot;HTMLAnchorElement&quot;: false,
+            &quot;HTMLBaseElement&quot;: false,
+            &quot;HTMLBodyElement&quot;: false,
+            &quot;HTMLBRElement&quot;: false,
+            &quot;HTMLButtonElement&quot;: false,
+            &quot;HTMLCanvasElement&quot;: false,
+            &quot;HTMLDirectoryElement&quot;: false,
+            &quot;HTMLDivElement&quot;: false,
+            &quot;HTMLDListElement&quot;: false,
+            &quot;HTMLElement&quot;: false,
+            &quot;HTMLFieldSetElement&quot;: false,
+            &quot;HTMLFontElement&quot;: false,
+            &quot;HTMLFormElement&quot;: false,
+            &quot;HTMLFrameElement&quot;: false,
+            &quot;HTMLFrameSetElement&quot;: false,
+            &quot;HTMLHeadElement&quot;: false,
+            &quot;HTMLHeadingElement&quot;: false,
+            &quot;HTMLHRElement&quot;: false,
+            &quot;HTMLHtmlElement&quot;: false,
+            &quot;HTMLIFrameElement&quot;: false,
+            &quot;HTMLImageElement&quot;: false,
+            &quot;HTMLInputElement&quot;: false,
+            &quot;HTMLLabelElement&quot;: false,
+            &quot;HTMLLegendElement&quot;: false,
+            &quot;HTMLLIElement&quot;: false,
+            &quot;HTMLLinkElement&quot;: false,
+            &quot;HTMLMapElement&quot;: false,
+            &quot;HTMLMenuElement&quot;: false,
+            &quot;HTMLMetaElement&quot;: false,
+            &quot;HTMLModElement&quot;: false,
+            &quot;HTMLObjectElement&quot;: false,
+            &quot;HTMLOListElement&quot;: false,
+            &quot;HTMLOptGroupElement&quot;: false,
+            &quot;HTMLOptionElement&quot;: false,
+            &quot;HTMLParagraphElement&quot;: false,
+            &quot;HTMLParamElement&quot;: false,
+            &quot;HTMLPreElement&quot;: false,
+            &quot;HTMLQuoteElement&quot;: false,
+            &quot;HTMLScriptElement&quot;: false,
+            &quot;HTMLSelectElement&quot;: false,
+            &quot;HTMLStyleElement&quot;: false,
+            &quot;HTMLTableCaptionElement&quot;: false,
+            &quot;HTMLTableCellElement&quot;: false,
+            &quot;HTMLTableColElement&quot;: false,
+            &quot;HTMLTableElement&quot;: false,
+            &quot;HTMLTableRowElement&quot;: false,
+            &quot;HTMLTableSectionElement&quot;: false,
+            &quot;HTMLTextAreaElement&quot;: false,
+            &quot;HTMLTitleElement&quot;: false,
+            &quot;HTMLUListElement&quot;: false,
+            &quot;HTMLVideoElement&quot;: false,
+            &quot;Image&quot;: false,
+            &quot;indexedDB&quot;: false,
+            &quot;innerHeight&quot;: false,
+            &quot;innerWidth&quot;: false,
+            &quot;Intl&quot;: false,
+            &quot;length&quot;: false,
+            &quot;localStorage&quot;: false,
+            &quot;location&quot;: false,
+            &quot;matchMedia&quot;: false,
+            &quot;MessageChannel&quot;: false,
+            &quot;MessageEvent&quot;: false,
+            &quot;MessagePort&quot;: false,
+            &quot;moveBy&quot;: false,
+            &quot;moveTo&quot;: false,
+            &quot;MutationObserver&quot;: false,
+            &quot;name&quot;: false,
+            &quot;navigator&quot;: false,
+            &quot;Node&quot;: false,
+            &quot;NodeFilter&quot;: false,
+            &quot;onbeforeunload&quot;: true,
+            &quot;onblur&quot;: true,
+            &quot;onerror&quot;: true,
+            &quot;onfocus&quot;: true,
+            &quot;onload&quot;: true,
+            &quot;onresize&quot;: true,
+            &quot;onunload&quot;: true,
+            &quot;open&quot;: false,
+            &quot;openDatabase&quot;: false,
+            &quot;opener&quot;: false,
+            &quot;Option&quot;: false,
+            &quot;outerHeight&quot;: false,
+            &quot;outerWidth&quot;: false,
+            &quot;pageXOffset&quot;: false,
+            &quot;pageYOffset&quot;: false,
+            &quot;parent&quot;: false,
+            &quot;postMessage&quot;: false,
+            &quot;print&quot;: false,
+            &quot;removeEventListener&quot;: false,
+            &quot;requestAnimationFrame&quot;: false,
+            &quot;resizeBy&quot;: false,
+            &quot;resizeTo&quot;: false,
+            &quot;screen&quot;: false,
+            &quot;screenX&quot;: false,
+            &quot;screenY&quot;: false,
+            &quot;scroll&quot;: false,
+            &quot;scrollbars&quot;: false,
+            &quot;scrollBy&quot;: false,
+            &quot;scrollTo&quot;: false,
+            &quot;scrollX&quot;: false,
+            &quot;scrollY&quot;: false,
+            &quot;self&quot;: false,
+            &quot;sessionStorage&quot;: false,
+            &quot;setInterval&quot;: false,
+            &quot;setTimeout&quot;: false,
+            &quot;SharedWorker&quot;: false,
+            &quot;showModalDialog&quot;: false,
+            &quot;stop&quot;: false,
+            &quot;SVGAElement&quot;: false,
+            &quot;SVGAltGlyphDefElement&quot;: false,
+            &quot;SVGAltGlyphElement&quot;: false,
+            &quot;SVGAltGlyphItemElement&quot;: false,
+            &quot;SVGAngle&quot;: false,
+            &quot;SVGAnimateColorElement&quot;: false,
+            &quot;SVGAnimatedAngle&quot;: false,
+            &quot;SVGAnimatedBoolean&quot;: false,
+            &quot;SVGAnimatedEnumeration&quot;: false,
+            &quot;SVGAnimatedInteger&quot;: false,
+            &quot;SVGAnimatedLength&quot;: false,
+            &quot;SVGAnimatedLengthList&quot;: false,
+            &quot;SVGAnimatedNumber&quot;: false,
+            &quot;SVGAnimatedNumberList&quot;: false,
+            &quot;SVGAnimatedPreserveAspectRatio&quot;: false,
+            &quot;SVGAnimatedRect&quot;: false,
+            &quot;SVGAnimatedString&quot;: false,
+            &quot;SVGAnimatedTransformList&quot;: false,
+            &quot;SVGAnimateElement&quot;: false,
+            &quot;SVGAnimateMotionElement&quot;: false,
+            &quot;SVGAnimateTransformElement&quot;: false,
+            &quot;SVGAnimationElement&quot;: false,
+            &quot;SVGCircleElement&quot;: false,
+            &quot;SVGClipPathElement&quot;: false,
+            &quot;SVGColor&quot;: false,
+            &quot;SVGComponentTransferFunctionElement&quot;: false,
+            &quot;SVGCursorElement&quot;: false,
+            &quot;SVGDefsElement&quot;: false,
+            &quot;SVGDescElement&quot;: false,
+            &quot;SVGDocument&quot;: false,
+            &quot;SVGElement&quot;: false,
+            &quot;SVGElementInstance&quot;: false,
+            &quot;SVGElementInstanceList&quot;: false,
+            &quot;SVGEllipseElement&quot;: false,
+            &quot;SVGFEBlendElement&quot;: false,
+            &quot;SVGFEColorMatrixElement&quot;: false,
+            &quot;SVGFEComponentTransferElement&quot;: false,
+            &quot;SVGFECompositeElement&quot;: false,
+            &quot;SVGFEConvolveMatrixElement&quot;: false,
+            &quot;SVGFEDiffuseLightingElement&quot;: false,
+            &quot;SVGFEDisplacementMapElement&quot;: false,
+            &quot;SVGFEDistantLightElement&quot;: false,
+            &quot;SVGFEFloodElement&quot;: false,
+            &quot;SVGFEFuncAElement&quot;: false,
+            &quot;SVGFEFuncBElement&quot;: false,
+            &quot;SVGFEFuncGElement&quot;: false,
+            &quot;SVGFEFuncRElement&quot;: false,
+            &quot;SVGFEGaussianBlurElement&quot;: false,
+            &quot;SVGFEImageElement&quot;: false,
+            &quot;SVGFEMergeElement&quot;: false,
+            &quot;SVGFEMergeNodeElement&quot;: false,
+            &quot;SVGFEMorphologyElement&quot;: false,
+            &quot;SVGFEOffsetElement&quot;: false,
+            &quot;SVGFEPointLightElement&quot;: false,
+            &quot;SVGFESpecularLightingElement&quot;: false,
+            &quot;SVGFESpotLightElement&quot;: false,
+            &quot;SVGFETileElement&quot;: false,
+            &quot;SVGFETurbulenceElement&quot;: false,
+            &quot;SVGFilterElement&quot;: false,
+            &quot;SVGFontElement&quot;: false,
+            &quot;SVGFontFaceElement&quot;: false,
+            &quot;SVGFontFaceFormatElement&quot;: false,
+            &quot;SVGFontFaceNameElement&quot;: false,
+            &quot;SVGFontFaceSrcElement&quot;: false,
+            &quot;SVGFontFaceUriElement&quot;: false,
+            &quot;SVGForeignObjectElement&quot;: false,
+            &quot;SVGGElement&quot;: false,
+            &quot;SVGGlyphElement&quot;: false,
+            &quot;SVGGlyphRefElement&quot;: false,
+            &quot;SVGGradientElement&quot;: false,
+            &quot;SVGHKernElement&quot;: false,
+            &quot;SVGImageElement&quot;: false,
+            &quot;SVGLength&quot;: false,
+            &quot;SVGLengthList&quot;: false,
+            &quot;SVGLinearGradientElement&quot;: false,
+            &quot;SVGLineElement&quot;: false,
+            &quot;SVGMarkerElement&quot;: false,
+            &quot;SVGMaskElement&quot;: false,
+            &quot;SVGMatrix&quot;: false,
+            &quot;SVGMetadataElement&quot;: false,
+            &quot;SVGMissingGlyphElement&quot;: false,
+            &quot;SVGMPathElement&quot;: false,
+            &quot;SVGNumber&quot;: false,
+            &quot;SVGNumberList&quot;: false,
+            &quot;SVGPaint&quot;: false,
+            &quot;SVGPathElement&quot;: false,
+            &quot;SVGPathSeg&quot;: false,
+            &quot;SVGPathSegArcAbs&quot;: false,
+            &quot;SVGPathSegArcRel&quot;: false,
+            &quot;SVGPathSegClosePath&quot;: false,
+            &quot;SVGPathSegCurvetoCubicAbs&quot;: false,
+            &quot;SVGPathSegCurvetoCubicRel&quot;: false,
+            &quot;SVGPathSegCurvetoCubicSmoothAbs&quot;: false,
+            &quot;SVGPathSegCurvetoCubicSmoothRel&quot;: false,
+            &quot;SVGPathSegCurvetoQuadraticAbs&quot;: false,
+            &quot;SVGPathSegCurvetoQuadraticRel&quot;: false,
+            &quot;SVGPathSegCurvetoQuadraticSmoothAbs&quot;: false,
+            &quot;SVGPathSegCurvetoQuadraticSmoothRel&quot;: false,
+            &quot;SVGPathSegLinetoAbs&quot;: false,
+            &quot;SVGPathSegLinetoHorizontalAbs&quot;: false,
+            &quot;SVGPathSegLinetoHorizontalRel&quot;: false,
+            &quot;SVGPathSegLinetoRel&quot;: false,
+            &quot;SVGPathSegLinetoVerticalAbs&quot;: false,
+            &quot;SVGPathSegLinetoVerticalRel&quot;: false,
+            &quot;SVGPathSegList&quot;: false,
+            &quot;SVGPathSegMovetoAbs&quot;: false,
+            &quot;SVGPathSegMovetoRel&quot;: false,
+            &quot;SVGPatternElement&quot;: false,
+            &quot;SVGPoint&quot;: false,
+            &quot;SVGPointList&quot;: false,
+            &quot;SVGPolygonElement&quot;: false,
+            &quot;SVGPolylineElement&quot;: false,
+            &quot;SVGPreserveAspectRatio&quot;: false,
+            &quot;SVGRadialGradientElement&quot;: false,
+            &quot;SVGRect&quot;: false,
+            &quot;SVGRectElement&quot;: false,
+            &quot;SVGRenderingIntent&quot;: false,
+            &quot;SVGScriptElement&quot;: false,
+            &quot;SVGSetElement&quot;: false,
+            &quot;SVGStopElement&quot;: false,
+            &quot;SVGStringList&quot;: false,
+            &quot;SVGStyleElement&quot;: false,
+            &quot;SVGSVGElement&quot;: false,
+            &quot;SVGSwitchElement&quot;: false,
+            &quot;SVGSymbolElement&quot;: false,
+            &quot;SVGTextContentElement&quot;: false,
+            &quot;SVGTextElement&quot;: false,
+            &quot;SVGTextPathElement&quot;: false,
+            &quot;SVGTextPositioningElement&quot;: false,
+            &quot;SVGTitleElement&quot;: false,
+            &quot;SVGTransform&quot;: false,
+            &quot;SVGTransformList&quot;: false,
+            &quot;SVGTRefElement&quot;: false,
+            &quot;SVGTSpanElement&quot;: false,
+            &quot;SVGUnitTypes&quot;: false,
+            &quot;SVGUseElement&quot;: false,
+            &quot;SVGViewElement&quot;: false,
+            &quot;SVGViewSpec&quot;: false,
+            &quot;SVGVKernElement&quot;: false,
+            &quot;top&quot;: false,
+            &quot;WebSocket&quot;: false,
+            &quot;window&quot;: false,
+            &quot;Worker&quot;: false,
+            &quot;XMLHttpRequest&quot;: false,
+            &quot;XMLSerializer&quot;: false,
+            &quot;XPathEvaluator&quot;: false,
+            &quot;XPathExpression&quot;: false,
+            &quot;XPathResult&quot;: false
+        }
+    },
+
+    &quot;node&quot;: {
+        &quot;globals&quot;: {
+            &quot;__filename&quot;: false,
+            &quot;__dirname&quot;: false,
+            &quot;Buffer&quot;: false,
+            &quot;DataView&quot;: false,
+            &quot;console&quot;: false,
+            &quot;exports&quot;: true,
+            &quot;GLOBAL&quot;: false,
+            &quot;global&quot;: false,
+            &quot;module&quot;: false,
+            &quot;process&quot;: false,
+            &quot;require&quot;: false,
+            &quot;setTimeout&quot;: false,
+            &quot;clearTimeout&quot;: false,
+            &quot;setInterval&quot;: false,
+            &quot;clearInterval&quot;: false,
+            &quot;setImmediate&quot;: false,
+            &quot;clearImmediate&quot;: false
+        },
+
+        &quot;rules&quot;: {
+            &quot;no-catch-shadow&quot;: 0,
+            &quot;no-console&quot;: 0,
+            &quot;no-mixed-requires&quot;: 2,
+            &quot;no-new-require&quot;: 2,
+            &quot;no-path-concat&quot;: 2,
+            &quot;no-process-exit&quot;: 2,
+            &quot;global-strict&quot;: [0, &quot;always&quot;],
+            &quot;handle-callback-err&quot;: [2, &quot;err&quot;]
+        }
+    },
+
+    &quot;amd&quot;: {
+        &quot;globals&quot;: {
+            &quot;require&quot;: false,
+            &quot;define&quot;: false
+        }
+    },
+
+    &quot;mocha&quot;: {
+        &quot;globals&quot;: {
+            &quot;describe&quot;: false,
+            &quot;it&quot;: false,
+            &quot;before&quot;: false,
+            &quot;after&quot;: false,
+            &quot;beforeEach&quot;: false,
+            &quot;afterEach&quot;: false,
+
+            &quot;suite&quot;: false,
+            &quot;test&quot;: false,
+            &quot;setup&quot;: false,
+            &quot;teardown&quot;: false,
+            &quot;suiteSetup&quot;: false,
+            &quot;suiteTeardown&quot;: false
+        }
+    },
+
+    &quot;jasmine&quot;: {
+        &quot;globals&quot;: {
+            &quot;afterEach&quot;: false,
+            &quot;beforeEach&quot;: false,
+            &quot;describe&quot;: false,
+            &quot;expect&quot;: false,
+            &quot;it&quot;: false,
+            &quot;jasmine&quot;: false,
+            &quot;pending&quot;: false,
+            &quot;spyOn&quot;: false,
+            &quot;waits&quot;: false,
+            &quot;waitsFor&quot;: false,
+            &quot;xdescribe&quot;: false,
+            &quot;xit&quot;: false
+        }
+    }
+}
+
+},{}],2:[function(require,module,exports){
+module.exports={
+    &quot;env&quot;: {
+        &quot;browser&quot;: false,
+        &quot;node&quot;: false,
+        &quot;amd&quot;: false,
+        &quot;mocha&quot;: false,
+        &quot;jasmine&quot;: false
+    },
+
+    &quot;rules&quot;: {
+        &quot;no-alert&quot;: 2,
+        &quot;no-array-constructor&quot;: 2,
+        &quot;no-bitwise&quot;: 0,
+        &quot;no-caller&quot;: 2,
+        &quot;no-catch-shadow&quot;: 2,
+        &quot;no-comma-dangle&quot;: 2,
+        &quot;no-cond-assign&quot;: 2,
+        &quot;no-console&quot;: 2,
+        &quot;no-constant-condition&quot;: 2,
+        &quot;no-control-regex&quot;: 2,
+        &quot;no-debugger&quot;: 2,
+        &quot;no-delete-var&quot;: 2,
+        &quot;no-div-regex&quot;: 0,
+        &quot;no-dupe-keys&quot;: 2,
+        &quot;no-else-return&quot;: 0,
+        &quot;no-empty&quot;: 2,
+        &quot;no-empty-class&quot;: 2,
+        &quot;no-empty-label&quot;: 2,
+        &quot;no-eq-null&quot;: 0,
+        &quot;no-eval&quot;: 2,
+        &quot;no-ex-assign&quot;: 2,
+        &quot;no-extend-native&quot;: 2,
+        &quot;no-extra-bind&quot;: 2,
+        &quot;no-extra-boolean-cast&quot;: 2,
+        &quot;no-extra-parens&quot;: 0,
+        &quot;no-extra-semi&quot;: 2,
+        &quot;no-extra-strict&quot;: 2,
+        &quot;no-fallthrough&quot;: 2,
+        &quot;no-floating-decimal&quot;: 0,
+        &quot;no-func-assign&quot;: 2,
+        &quot;no-implied-eval&quot;: 2,
+        &quot;no-inner-declarations&quot;: [2, &quot;functions&quot;],
+        &quot;no-invalid-regexp&quot;: 2,
+        &quot;no-iterator&quot;: 2,
+        &quot;no-label-var&quot;: 2,
+        &quot;no-labels&quot;: 2,
+        &quot;no-lone-blocks&quot;: 2,
+        &quot;no-lonely-if&quot;: 0,
+        &quot;no-loop-func&quot;: 2,
+        &quot;no-mixed-requires&quot;: [0, false],
+        &quot;no-mixed-spaces-and-tabs&quot;: [2, false],
+        &quot;no-multi-spaces&quot;: 2,
+        &quot;no-multi-str&quot;: 2,
+        &quot;no-multiple-empty-lines&quot;: [0, {&quot;max&quot;: 2}],
+        &quot;no-native-reassign&quot;: 2,
+        &quot;no-negated-in-lhs&quot;: 2,
+        &quot;no-nested-ternary&quot;: 0,
+        &quot;no-new&quot;: 2,
+        &quot;no-new-func&quot;: 2,
+        &quot;no-new-object&quot;: 2,
+        &quot;no-new-require&quot;: 0,
+        &quot;no-new-wrappers&quot;: 2,
+        &quot;no-obj-calls&quot;: 2,
+        &quot;no-octal&quot;: 2,
+        &quot;no-octal-escape&quot;: 2,
+        &quot;no-path-concat&quot;: 0,
+        &quot;no-plusplus&quot;: 0,
+        &quot;no-process-env&quot;: 0,
+        &quot;no-process-exit&quot;: 2,
+        &quot;no-proto&quot;: 2,
+        &quot;no-redeclare&quot;: 2,
+        &quot;no-regex-spaces&quot;: 2,
+        &quot;no-reserved-keys&quot;: 0,
+        &quot;no-restricted-modules&quot;: 0,
+        &quot;no-return-assign&quot;: 2,
+        &quot;no-script-url&quot;: 2,
+        &quot;no-self-compare&quot;: 0,
+        &quot;no-sequences&quot;: 2,
+        &quot;no-shadow&quot;: 2,
+        &quot;no-shadow-restricted-names&quot;: 2,
+        &quot;no-space-before-semi&quot;: 2,
+        &quot;no-spaced-func&quot;: 2,
+        &quot;no-sparse-arrays&quot;: 2,
+        &quot;no-sync&quot;: 0,
+        &quot;no-ternary&quot;: 0,
+        &quot;no-trailing-spaces&quot;: 2,
+        &quot;no-undef&quot;: 2,
+        &quot;no-undef-init&quot;: 2,
+        &quot;no-undefined&quot;: 0,
+        &quot;no-underscore-dangle&quot;: 2,
+        &quot;no-unreachable&quot;: 2,
+        &quot;no-unused-expressions&quot;: 2,
+        &quot;no-unused-vars&quot;: [2, {&quot;vars&quot;: &quot;all&quot;, &quot;args&quot;: &quot;after-used&quot;}],
+        &quot;no-use-before-define&quot;: 2,
+        &quot;no-void&quot;: 0,
+        &quot;no-warning-comments&quot;: [0, { &quot;terms&quot;: [&quot;todo&quot;, &quot;fixme&quot;, &quot;xxx&quot;], &quot;location&quot;: &quot;start&quot; }],
+        &quot;no-with&quot;: 2,
+        &quot;no-wrap-func&quot;: 2,
+
+        &quot;block-scoped-var&quot;: 0,
+        &quot;brace-style&quot;: [0, &quot;1tbs&quot;],
+        &quot;camelcase&quot;: 2,
+        &quot;comma-spacing&quot;: 2,
+        &quot;comma-style&quot;: 0,
+        &quot;complexity&quot;: [0, 11],
+        &quot;consistent-return&quot;: 2,
+        &quot;consistent-this&quot;: [0, &quot;that&quot;],
+        &quot;curly&quot;: [2, &quot;all&quot;],
+        &quot;default-case&quot;: 0,
+        &quot;dot-notation&quot;: 2,
+        &quot;eol-last&quot;: 2,
+        &quot;eqeqeq&quot;: 2,
+        &quot;func-names&quot;: 0,
+        &quot;func-style&quot;: [0, &quot;declaration&quot;],
+        &quot;global-strict&quot;: [2, &quot;never&quot;],
+        &quot;guard-for-in&quot;: 0,
+        &quot;handle-callback-err&quot;: 0,
+        &quot;key-spacing&quot;: [2, { &quot;beforeColon&quot;: false, &quot;afterColon&quot;: true }],
+        &quot;max-depth&quot;: [0, 4],
+        &quot;max-len&quot;: [0, 80, 4],
+        &quot;max-nested-callbacks&quot;: [0, 2],
+        &quot;max-params&quot;: [0, 3],
+        &quot;max-statements&quot;: [0, 10],
+        &quot;new-cap&quot;: 2,
+        &quot;new-parens&quot;: 2,
+        &quot;one-var&quot;: 0,
+        &quot;padded-blocks&quot;: 0,
+        &quot;quote-props&quot;: 0,
+        &quot;quotes&quot;: [2, &quot;double&quot;],
+        &quot;radix&quot;: 0,
+        &quot;semi&quot;: 2,
+        &quot;sort-vars&quot;: 0,
+        &quot;space-after-keywords&quot;: [0, &quot;always&quot;],
+        &quot;space-before-blocks&quot;: [0, &quot;always&quot;],
+        &quot;space-in-brackets&quot;: [0, &quot;never&quot;],
+        &quot;space-in-parens&quot;: [0, &quot;never&quot;],
+        &quot;space-infix-ops&quot;: 2,
+        &quot;space-return-throw-case&quot;: 2,
+        &quot;space-unary-word-ops&quot;: 0,
+        &quot;spaced-line-comment&quot;: [0, &quot;always&quot;],
+        &quot;strict&quot;: 2,
+        &quot;use-isnan&quot;: 2,
+        &quot;valid-jsdoc&quot;: 0,
+        &quot;valid-typeof&quot;: 2,
+        &quot;vars-on-top&quot;: 0,
+        &quot;wrap-iife&quot;: 0,
+        &quot;wrap-regex&quot;: 0,
+        &quot;yoda&quot;: [2, &quot;never&quot;]
+    }
+}
+
+},{}],3:[function(require,module,exports){
+// Copyright Joyent, Inc. and other Node contributors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// &quot;Software&quot;), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to permit
+// persons to whom the Software is furnished to do so, subject to the
+// following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED &quot;AS IS&quot;, WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+// USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+function EventEmitter() {
+  this._events = this._events || {};
+  this._maxListeners = this._maxListeners || undefined;
+}
+module.exports = EventEmitter;
+
+// Backwards-compat with node 0.10.x
+EventEmitter.EventEmitter = EventEmitter;
+
+EventEmitter.prototype._events = undefined;
+EventEmitter.prototype._maxListeners = undefined;
+
+// By default EventEmitters will print a warning if more than 10 listeners are
+// added to it. This is a useful default which helps finding memory leaks.
+EventEmitter.defaultMaxListeners = 10;
+
+// Obviously not all Emitters should be limited to 10. This function allows
+// that to be increased. Set to zero for unlimited.
+EventEmitter.prototype.setMaxListeners = function(n) {
+  if (!isNumber(n) || n &lt; 0 || isNaN(n))
+    throw TypeError('n must be a positive number');
+  this._maxListeners = n;
+  return this;
+};
+
+EventEmitter.prototype.emit = function(type) {
+  var er, handler, len, args, i, listeners;
+
+  if (!this._events)
+    this._events = {};
+
+  // If there is no 'error' event listener then throw.
+  if (type === 'error') {
+    if (!this._events.error ||
+        (isObject(this._events.error) &amp;&amp; !this._events.error.length)) {
+      er = arguments[1];
+      if (er instanceof Error) {
+        throw er; // Unhandled 'error' event
+      }
+      throw TypeError('Uncaught, unspecified &quot;error&quot; event.');
+    }
+  }
+
+  handler = this._events[type];
+
+  if (isUndefined(handler))
+    return false;
+
+  if (isFunction(handler)) {
+    switch (arguments.length) {
+      // fast cases
+      case 1:
+        handler.call(this);
+        break;
+      case 2:
+        handler.call(this, arguments[1]);
+        break;
+      case 3:
+        handler.call(this, arguments[1], arguments[2]);
+        break;
+      // slower
+      default:
+        len = arguments.length;
+        args = new Array(len - 1);
+        for (i = 1; i &lt; len; i++)
+          args[i - 1] = arguments[i];
+        handler.apply(this, args);
+    }
+  } else if (isObject(handler)) {
+    len = arguments.length;
+    args = new Array(len - 1);
+    for (i = 1; i &lt; len; i++)
+      args[i - 1] = arguments[i];
+
+    listeners = handler.slice();
+    len = listeners.length;
+    for (i = 0; i &lt; len; i++)
+      listeners[i].apply(this, args);
+  }
+
+  return true;
+};
+
+EventEmitter.prototype.addListener = function(type, listener) {
+  var m;
+
+  if (!isFunction(listener))
+    throw TypeError('listener must be a function');
+
+  if (!this._events)
+    this._events = {};
+
+  // To avoid recursion in the case that type === &quot;newListener&quot;! Before
+  // adding it to the listeners, first emit &quot;newListener&quot;.
+  if (this._events.newListener)
+    this.emit('newListener', type,
+              isFunction(listener.listener) ?
+              listener.listener : listener);
+
+  if (!this._events[type])
+    // Optimize the case of one listener. Don't need the extra array object.
+    this._events[type] = listener;
+  else if (isObject(this._events[type]))
+    // If we've already got an array, just append.
+    this._events[type].push(listener);
+  else
+    // Adding the second element, need to change to array.
+    this._events[type] = [this._events[type], listener];
+
+  // Check for listener leak
+  if (isObject(this._events[type]) &amp;&amp; !this._events[type].warned) {
+    var m;
+    if (!isUndefined(this._maxListeners)) {
+      m = this._maxListeners;
+    } else {
+      m = EventEmitter.defaultMaxListeners;
+    }
+
+    if (m &amp;&amp; m &gt; 0 &amp;&amp; this._events[type].length &gt; m) {
+      this._events[type].warned = true;
+      console.error('(node) warning: possible EventEmitter memory ' +
+                    'leak detected. %d listeners added. ' +
+                    'Use emitter.setMaxListeners() to increase limit.',
+                    this._events[type].length);
+      if (typeof console.trace === 'function') {
+        // not supported in IE 10
+        console.trace();
+      }
+    }
+  }
+
+  return this;
+};
+
+EventEmitter.prototype.on = EventEmitter.prototype.addListener;
+
+EventEmitter.prototype.once = function(type, listener) {
+  if (!isFunction(listener))
+    throw TypeError('listener must be a function');
+
+  var fired = false;
+
+  function g() {
+    this.removeListener(type, g);
+
+    if (!fired) {
+      fired = true;
+      listener.apply(this, arguments);
+    }
+  }
+
+  g.listener = listener;
+  this.on(type, g);
+
+  return this;
+};
+
+// emits a 'removeListener' event iff the listener was removed
+EventEmitter.prototype.removeListener = function(type, listener) {
+  var list, position, length, i;
+
+  if (!isFunction(listener))
+    throw TypeError('listener must be a function');
+
+  if (!this._events || !this._events[type])
+    return this;
+
+  list = this._events[type];
+  length = list.length;
+  position = -1;
+
+  if (list === listener ||
+      (isFunction(list.listener) &amp;&amp; list.listener === listener)) {
+    delete this._events[type];
+    if (this._events.removeListener)
+      this.emit('removeListener', type, listener);
+
+  } else if (isObject(list)) {
+    for (i = length; i-- &gt; 0;) {
+      if (list[i] === listener ||
+          (list[i].listener &amp;&amp; list[i].listener === listener)) {
+        position = i;
+        break;
+      }
+    }
+
+    if (position &lt; 0)
+      return this;
+
+    if (list.length === 1) {
+      list.length = 0;
+      delete this._events[type];
+    } else {
+      list.splice(position, 1);
+    }
+
+    if (this._events.removeListener)
+      this.emit('removeListener', type, listener);
+  }
+
+  return this;
+};
+
+EventEmitter.prototype.removeAllListeners = function(type) {
+  var key, listeners;
+
+  if (!this._events)
+    return this;
+
+  // not listening for removeListener, no need to emit
+  if (!this._events.removeListener) {
+    if (arguments.length === 0)
+      this._events = {};
+    else if (this._events[type])
+      delete this._events[type];
+    return this;
+  }
+
+  // emit removeListener for all listeners on all events
+  if (arguments.length === 0) {
+    for (key in this._events) {
+      if (key === 'removeListener') continue;
+      this.removeAllListeners(key);
+    }
+    this.removeAllListeners('removeListener');
+    this._events = {};
+    return this;
+  }
+
+  listeners = this._events[type];
+
+  if (isFunction(listeners)) {
+    this.removeListener(type, listeners);
+  } else {
+    // LIFO order
+    while (listeners.length)
+      this.removeListener(type, listeners[listeners.length - 1]);
+  }
+  delete this._events[type];
+
+  return this;
+};
+
+EventEmitter.prototype.listeners = function(type) {
+  var ret;
+  if (!this._events || !this._events[type])
+    ret = [];
+  else if (isFunction(this._events[type]))
+    ret = [this._events[type]];
+  else
+    ret = this._events[type].slice();
+  return ret;
+};
+
+EventEmitter.listenerCount = function(emitter, type) {
+  var ret;
+  if (!emitter._events || !emitter._events[type])
+    ret = 0;
+  else if (isFunction(emitter._events[type]))
+    ret = 1;
+  else
+    ret = emitter._events[type].length;
+  return ret;
+};
+
+function isFunction(arg) {
+  return typeof arg === 'function';
+}
+
+function isNumber(arg) {
+  return typeof arg === 'number';
+}
+
+function isObject(arg) {
+  return typeof arg === 'object' &amp;&amp; arg !== null;
+}
+
+function isUndefined(arg) {
+  return arg === void 0;
+}
+
+},{}],4:[function(require,module,exports){
+/*
+  Copyright (C) 2012-2014 Yusuke Suzuki &lt;utatane.tea@gmail.com&gt;
+  Copyright (C) 2014 Dan Tao &lt;daniel.tao@gmail.com&gt;
+  Copyright (C) 2013 Andrew Eisenberg &lt;andrew@eisenberg.as&gt;
+
+  Redistribution and use in source and binary forms, with or without
+  modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in the
+      documentation and/or other materials provided with the distribution.
+
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS &quot;AS IS&quot;
+  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  ARE DISCLAIMED. IN NO EVENT SHALL &lt;COPYRIGHT HOLDER&gt; BE LIABLE FOR ANY
+  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/*jslint bitwise:true plusplus:true eqeq:true nomen:true*/
+/*global doctrine:true, exports:true, parseTypeExpression:true, parseTop:true*/
+
+(function (exports) {
+    'use strict';
+
+    var VERSION,
+        Regex,
+        CanAccessStringByIndex,
+        typed,
+        jsdoc,
+        isArray,
+        hasOwnProperty;
+
+    // Sync with package.json.
+    VERSION = '0.5.2-dev';
+
+    // See also tools/generate-unicode-regex.py.
+    Regex = {
+        NonAsciiIdentifierStart: new RegExp('[\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0370-\u0374\u0376\u0377\u037a-\u037d\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u048a-\u0527\u0531-\u0556\u0559\u0561-\u0587\u05d0-\u05ea\u05f0-\u05f2\u0620-\u064a\u066e\u066f\u0671-\u06d3\u06d5\u06e5\u06e6\u06ee\u06ef\u06fa-\u06fc\u06ff\u0710\u0712-\u072f\u074d-\u07a5\u07b1\u07ca-\u07ea\u07f4\u07f5\u07fa\u0800-\u0815\u081a\u0824\u0828\u0840-\u0858\u08a0\u08a2-\u08ac\u0904-\u0939\u093d\u0950\u0958-\u0961\u0971-\u0977\u0979-\u097f\u0985-\u098c\u098f\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bd\u09ce\u09dc\u09dd\u09df-\u09e1\u09f0\u09f1\u0a05-\u0a0a\u0a0f\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a59-\u0a5c\u0a5e\u0a72-\u0a74\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2\u0ab3\u0ab5-\u0ab9\u0abd\u0ad0\u0ae0\u0ae1\u0b05-\u0b0c\u0b0f\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32\u0b33\u0b35
 -\u0b39\u0b3d\u0b5c\u0b5d\u0b5f-\u0b61\u0b71\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0bd0\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c33\u0c35-\u0c39\u0c3d\u0c58\u0c59\u0c60\u0c61\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbd\u0cde\u0ce0\u0ce1\u0cf1\u0cf2\u0d05-\u0d0c\u0d0e-\u0d10\u0d12-\u0d3a\u0d3d\u0d4e\u0d60\u0d61\u0d7a-\u0d7f\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0e01-\u0e30\u0e32\u0e33\u0e40-\u0e46\u0e81\u0e82\u0e84\u0e87\u0e88\u0e8a\u0e8d\u0e94-\u0e97\u0e99-\u0e9f\u0ea1-\u0ea3\u0ea5\u0ea7\u0eaa\u0eab\u0ead-\u0eb0\u0eb2\u0eb3\u0ebd\u0ec0-\u0ec4\u0ec6\u0edc-\u0edf\u0f00\u0f40-\u0f47\u0f49-\u0f6c\u0f88-\u0f8c\u1000-\u102a\u103f\u1050-\u1055\u105a-\u105d\u1061\u1065\u1066\u106e-\u1070\u1075-\u1081\u108e\u10a0-\u10c5\u10c7\u10cd\u10d0-\u10fa\u10fc-\u1248\u124a-\u124d\u1250-\u1256\u1258\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u
 12b8-\u12be\u12c0\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u1380-\u138f\u13a0-\u13f4\u1401-\u166c\u166f-\u167f\u1681-\u169a\u16a0-\u16ea\u16ee-\u16f0\u1700-\u170c\u170e-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176c\u176e-\u1770\u1780-\u17b3\u17d7\u17dc\u1820-\u1877\u1880-\u18a8\u18aa\u18b0-\u18f5\u1900-\u191c\u1950-\u196d\u1970-\u1974\u1980-\u19ab\u19c1-\u19c7\u1a00-\u1a16\u1a20-\u1a54\u1aa7\u1b05-\u1b33\u1b45-\u1b4b\u1b83-\u1ba0\u1bae\u1baf\u1bba-\u1be5\u1c00-\u1c23\u1c4d-\u1c4f\u1c5a-\u1c7d\u1ce9-\u1cec\u1cee-\u1cf1\u1cf5\u1cf6\u1d00-\u1dbf\u1e00-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d\u1f50-\u1f57\u1f59\u1f5b\u1f5d\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec\u1ff2-\u1ff4\u1ff6-\u1ffc\u2071\u207f\u2090-\u209c\u2102\u2107\u210a-\u2113\u2115\u2119-\u211d\u2124\u2126\u2128\u212a-\u212d\u212f-\u2139\u213c-\u213f\u2145-\u2149\u214e\u2160-\u2188\u2c00-\u2c2e\u2c30-\u2c5e\u2c60-\u2ce4\
 u2ceb-\u2cee\u2cf2\u2cf3\u2d00-\u2d25\u2d27\u2d2d\u2d30-\u2d67\u2d6f\u2d80-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u2e2f\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303c\u3041-\u3096\u309d-\u309f\u30a1-\u30fa\u30fc-\u30ff\u3105-\u312d\u3131-\u318e\u31a0-\u31ba\u31f0-\u31ff\u3400-\u4db5\u4e00-\u9fcc\ua000-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua61f\ua62a\ua62b\ua640-\ua66e\ua67f-\ua697\ua6a0-\ua6ef\ua717-\ua71f\ua722-\ua788\ua78b-\ua78e\ua790-\ua793\ua7a0-\ua7aa\ua7f8-\ua801\ua803-\ua805\ua807-\ua80a\ua80c-\ua822\ua840-\ua873\ua882-\ua8b3\ua8f2-\ua8f7\ua8fb\ua90a-\ua925\ua930-\ua946\ua960-\ua97c\ua984-\ua9b2\ua9cf\uaa00-\uaa28\uaa40-\uaa42\uaa44-\uaa4b\uaa60-\uaa76\uaa7a\uaa80-\uaaaf\uaab1\uaab5\uaab6\uaab9-\uaabd\uaac0\uaac2\uaadb-\uaadd\uaae0-\uaaea\uaaf2-\uaaf4\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uabc0-\uabe2\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\uf900-\ufa6d\ufa70-\uf
 ad9\ufb00-\ufb06\ufb13-\ufb17\ufb1d\ufb1f-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40\ufb41\ufb43\ufb44\ufb46-\ufbb1\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfb\ufe70-\ufe74\ufe76-\ufefc\uff21-\uff3a\uff41-\uff5a\uff66-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc]'),
+        NonAsciiIdentifierPart: new RegExp('[\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0300-\u0374\u0376\u0377\u037a-\u037d\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u0483-\u0487\u048a-\u0527\u0531-\u0556\u0559\u0561-\u0587\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u05d0-\u05ea\u05f0-\u05f2\u0610-\u061a\u0620-\u0669\u066e-\u06d3\u06d5-\u06dc\u06df-\u06e8\u06ea-\u06fc\u06ff\u0710-\u074a\u074d-\u07b1\u07c0-\u07f5\u07fa\u0800-\u082d\u0840-\u085b\u08a0\u08a2-\u08ac\u08e4-\u08fe\u0900-\u0963\u0966-\u096f\u0971-\u0977\u0979-\u097f\u0981-\u0983\u0985-\u098c\u098f\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bc-\u09c4\u09c7\u09c8\u09cb-\u09ce\u09d7\u09dc\u09dd\u09df-\u09e3\u09e6-\u09f1\u0a01-\u0a03\u0a05-\u0a0a\u0a0f\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a3c\u0a3e-\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a59-\u0a5c\u0a5e\u0a66-\u0a75\u0a81-\u0a83\u0a85-\u0a8d\u0a8f-\u0a91\u0a9
 3-\u0aa8\u0aaa-\u0ab0\u0ab2\u0ab3\u0ab5-\u0ab9\u0abc-\u0ac5\u0ac7-\u0ac9\u0acb-\u0acd\u0ad0\u0ae0-\u0ae3\u0ae6-\u0aef\u0b01-\u0b03\u0b05-\u0b0c\u0b0f\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32\u0b33\u0b35-\u0b39\u0b3c-\u0b44\u0b47\u0b48\u0b4b-\u0b4d\u0b56\u0b57\u0b5c\u0b5d\u0b5f-\u0b63\u0b66-\u0b6f\u0b71\u0b82\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0bbe-\u0bc2\u0bc6-\u0bc8\u0bca-\u0bcd\u0bd0\u0bd7\u0be6-\u0bef\u0c01-\u0c03\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c33\u0c35-\u0c39\u0c3d-\u0c44\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c58\u0c59\u0c60-\u0c63\u0c66-\u0c6f\u0c82\u0c83\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbc-\u0cc4\u0cc6-\u0cc8\u0cca-\u0ccd\u0cd5\u0cd6\u0cde\u0ce0-\u0ce3\u0ce6-\u0cef\u0cf1\u0cf2\u0d02\u0d03\u0d05-\u0d0c\u0d0e-\u0d10\u0d12-\u0d3a\u0d3d-\u0d44\u0d46-\u0d48\u0d4a-\u0d4e\u0d57\u0d60-\u0d63\u0d66-\u0d6f\u0d7a-\u0d7f\u0d82\u0d83\u0d85-\u0d96\u0d9a-
 \u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0dca\u0dcf-\u0dd4\u0dd6\u0dd8-\u0ddf\u0df2\u0df3\u0e01-\u0e3a\u0e40-\u0e4e\u0e50-\u0e59\u0e81\u0e82\u0e84\u0e87\u0e88\u0e8a\u0e8d\u0e94-\u0e97\u0e99-\u0e9f\u0ea1-\u0ea3\u0ea5\u0ea7\u0eaa\u0eab\u0ead-\u0eb9\u0ebb-\u0ebd\u0ec0-\u0ec4\u0ec6\u0ec8-\u0ecd\u0ed0-\u0ed9\u0edc-\u0edf\u0f00\u0f18\u0f19\u0f20-\u0f29\u0f35\u0f37\u0f39\u0f3e-\u0f47\u0f49-\u0f6c\u0f71-\u0f84\u0f86-\u0f97\u0f99-\u0fbc\u0fc6\u1000-\u1049\u1050-\u109d\u10a0-\u10c5\u10c7\u10cd\u10d0-\u10fa\u10fc-\u1248\u124a-\u124d\u1250-\u1256\u1258\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u12b8-\u12be\u12c0\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u135d-\u135f\u1380-\u138f\u13a0-\u13f4\u1401-\u166c\u166f-\u167f\u1681-\u169a\u16a0-\u16ea\u16ee-\u16f0\u1700-\u170c\u170e-\u1714\u1720-\u1734\u1740-\u1753\u1760-\u176c\u176e-\u1770\u1772\u1773\u1780-\u17d3\u17d7\u17dc\u17dd\u17e0-\u17e9\u180b-\u180d\u1810-\u1819\u1820-\u1877\u1880-\u18aa\u18b
 0-\u18f5\u1900-\u191c\u1920-\u192b\u1930-\u193b\u1946-\u196d\u1970-\u1974\u1980-\u19ab\u19b0-\u19c9\u19d0-\u19d9\u1a00-\u1a1b\u1a20-\u1a5e\u1a60-\u1a7c\u1a7f-\u1a89\u1a90-\u1a99\u1aa7\u1b00-\u1b4b\u1b50-\u1b59\u1b6b-\u1b73\u1b80-\u1bf3\u1c00-\u1c37\u1c40-\u1c49\u1c4d-\u1c7d\u1cd0-\u1cd2\u1cd4-\u1cf6\u1d00-\u1de6\u1dfc-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d\u1f50-\u1f57\u1f59\u1f5b\u1f5d\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec\u1ff2-\u1ff4\u1ff6-\u1ffc\u200c\u200d\u203f\u2040\u2054\u2071\u207f\u2090-\u209c\u20d0-\u20dc\u20e1\u20e5-\u20f0\u2102\u2107\u210a-\u2113\u2115\u2119-\u211d\u2124\u2126\u2128\u212a-\u212d\u212f-\u2139\u213c-\u213f\u2145-\u2149\u214e\u2160-\u2188\u2c00-\u2c2e\u2c30-\u2c5e\u2c60-\u2ce4\u2ceb-\u2cf3\u2d00-\u2d25\u2d27\u2d2d\u2d30-\u2d67\u2d6f\u2d7f-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u2de0-\u2dff\u2e2f\u300
 5-\u3007\u3021-\u302f\u3031-\u3035\u3038-\u303c\u3041-\u3096\u3099\u309a\u309d-\u309f\u30a1-\u30fa\u30fc-\u30ff\u3105-\u312d\u3131-\u318e\u31a0-\u31ba\u31f0-\u31ff\u3400-\u4db5\u4e00-\u9fcc\ua000-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua62b\ua640-\ua66f\ua674-\ua67d\ua67f-\ua697\ua69f-\ua6f1\ua717-\ua71f\ua722-\ua788\ua78b-\ua78e\ua790-\ua793\ua7a0-\ua7aa\ua7f8-\ua827\ua840-\ua873\ua880-\ua8c4\ua8d0-\ua8d9\ua8e0-\ua8f7\ua8fb\ua900-\ua92d\ua930-\ua953\ua960-\ua97c\ua980-\ua9c0\ua9cf-\ua9d9\uaa00-\uaa36\uaa40-\uaa4d\uaa50-\uaa59\uaa60-\uaa76\uaa7a\uaa7b\uaa80-\uaac2\uaadb-\uaadd\uaae0-\uaaef\uaaf2-\uaaf6\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uabc0-\uabea\uabec\uabed\uabf0-\uabf9\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\uf900-\ufa6d\ufa70-\ufad9\ufb00-\ufb06\ufb13-\ufb17\ufb1d-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40\ufb41\ufb43\ufb44\ufb46-\ufbb1\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfb\ufe00-\ufe0f\ufe20-\ufe26\ufe33\ufe34\ufe4d-\ufe4f
 \ufe70-\ufe74\ufe76-\ufefc\uff10-\uff19\uff21-\uff3a\uff3f\uff41-\uff5a\uff66-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc]')
+    };
+
+    CanAccessStringByIndex = typeof 'doctrine'[0] !== undefined;
+
+    function sliceSource(source, index, last) {
+        var output;
+        if (!CanAccessStringByIndex) {
+            output = source.slice(index, last).join('');
+        } else {
+            output = source.slice(index, last);
+        }
+        return output;
+    }
+
+    isArray = Array.isArray;
+    if (!isArray) {
+        isArray = function isArray(ary) {
+            return Object.prototype.toString.call(ary) === '[object Array]';
+        };
+    }
+
+    hasOwnProperty = (function () {
+        var func = Object.prototype.hasOwnProperty;
+        return function hasOwnProperty(obj, name) {
+            return func.call(obj, name);
+        };
+    }());
+
+    function shallowCopy(obj) {
+        var ret = {}, key;
+        for (key in obj) {
+            if (obj.hasOwnProperty(key)) {
+                ret[key] = obj[key];
+            }
+        }
+        return ret;
+    }
+
+    function isLineTerminator(ch) {
+        return ch === '\n' || ch === '\r' || ch === '\u2028' || ch === '\u2029';
+    }
+
+    function isWhiteSpace(ch) {
+        return (ch === ' ') || (ch === '\u0009') || (ch === '\u000B') ||
+            (ch === '\u000C') || (ch === '\u00A0') ||
+            (ch.charCodeAt(0) &gt;= 0x1680 &amp;&amp;
+             '\u1680\u180E\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\uFEFF'.indexOf(ch) &gt;= 0);
+    }
+
+    function isDecimalDigit(ch) {
+        return '0123456789'.indexOf(ch) &gt;= 0;
+    }
+
+    function isHexDigit(ch) {
+        return '0123456789abcdefABCDEF'.indexOf(ch) &gt;= 0;
+    }
+
+    function isOctalDigit(ch) {
+        return '01234567'.indexOf(ch) &gt;= 0;
+    }
+
+    function isASCIIAlphanumeric(ch) {
+        return (ch &gt;= 'a' &amp;&amp; ch &lt;= 'z') || (ch &gt;= 'A' &amp;&amp; ch &lt;= 'Z') || (ch &gt;= '0' &amp;&amp; ch &lt;= '9');
+    }
+
+    function isIdentifierStart(ch) {
+        return (ch === '$') || (ch === '_') || (ch === '\\') ||
+            (ch &gt;= 'a' &amp;&amp; ch &lt;= 'z') || (ch &gt;= 'A' &amp;&amp; ch &lt;= 'Z') ||
+            ((ch.charCodeAt(0) &gt;= 0x80) &amp;&amp; Regex.NonAsciiIdentifierStart.test(ch));
+    }
+
+    function isIdentifierPart(ch) {
+        return (ch === '$') || (ch === '_') || (ch === '\\') ||
+            (ch &gt;= 'a' &amp;&amp; ch &lt;= 'z') || (ch &gt;= 'A' &amp;&amp; ch &lt;= 'Z') ||
+            ((ch &gt;= '0') &amp;&amp; (ch &lt;= '9')) ||
+            ((ch.charCodeAt(0) &gt;= 0x80) &amp;&amp; Regex.NonAsciiIdentifierPart.test(ch));
+    }
+
+    function isTypeName(ch) {
+        return '&gt;&lt;(){}[],:*|?!='.indexOf(ch) === -1 &amp;&amp; !isWhiteSpace(ch) &amp;&amp; !isLineTerminator(ch);
+    }
+
+    function isParamTitle(title) {
+        return title === 'param' || title === 'argument' || title === 'arg';
+    }
+
+    function isProperty(title) {
+        return title === 'property' || title === 'prop';
+    }
+
+    function isNameParameterRequired(title) {
+        return isParamTitle(title) || isProperty(title) ||
+            title === 'alias' || title === 'this' || title === 'mixes' || title === 'requires';
+    }
+
+    function isAllowedName(title) {
+        return isNameParameterRequired(title) || title === 'const' || title === 'constant';
+    }
+
+    function isAllowedNested(title) {
+        return isProperty(title) || isParamTitle(title);
+    }
+
+    function isTypeParameterRequired(title) {
+        return isParamTitle(title) || title === 'define' || title === 'enum' ||
+            title === 'implements' || title === 'return' ||
+            title === 'this' || title === 'type' || title === 'typedef' ||
+            title === 'returns' || isProperty(title);
+    }
+
+    // Consider deprecation instead using 'isTypeParameterRequired' and 'Rules' declaration to pick when a type is optional/required
+    // This would require changes to 'parseType'
+    function isAllowedType(title) {
+        return isTypeParameterRequired(title) || title === 'throws' || title === 'const' || title === 'constant' ||
+            title === 'namespace' || title === 'member' || title === 'var' || title === 'module' ||
+            title === 'constructor' || title === 'class' || title === 'extends' || title === 'augments' ||
+            title === 'public' || title === 'private' || title === 'protected';
+    }
+
+    function DoctrineError(message) {
+        this.name = 'DoctrineError';
+        this.message = message;
+    }
+    DoctrineError.prototype = new Error();
+    DoctrineError.prototype.constructor = DoctrineError;
+
+    function throwError(message) {
+        throw new DoctrineError(message);
+    }
+
+    function assert(cond, text) {
+        if (VERSION.slice(-3) === 'dev') {
+            if (!cond) {
+                throwError(text);
+            }
+        }
+    }
+
+    function trim(str) {
+        return str.replace(/^\s+/, '').replace(/\s+$/, '');
+    }
+
+    function unwrapComment(doc) {
+        // JSDoc comment is following form
+        //   /**
+        //    * .......
+        //    */
+        // remove /**, */ and *
+        var BEFORE_STAR = 0,
+            STAR = 1,
+            AFTER_STAR = 2,
+            index,
+            len,
+            mode,
+            result,
+            ch;
+
+        doc = doc.replace(/^\/\*\*?/, '').replace(/\*\/$/, '');
+        index = 0;
+        len = doc.length;
+        mode = BEFORE_STAR;
+        result = '';
+
+        while (index &lt; len) {
+            ch = doc[index];
+            switch (mode) {
+            case BEFORE_STAR:
+                if (isLineTerminator(ch)) {
+                    result += ch;
+                } else if (ch === '*') {
+                    mode = STAR;
+                } else if (!isWhiteSpace(ch)) {
+                    result += ch;
+                    mode = AFTER_STAR;
+                }
+                break;
+
+            case STAR:
+                if (!isWhiteSpace(ch)) {
+                    result += ch;
+                }
+                mode = isLineTerminator(ch) ? BEFORE_STAR : AFTER_STAR;
+                break;
+
+            case AFTER_STAR:
+                result += ch;
+                if (isLineTerminator(ch)) {
+                    mode = BEFORE_STAR;
+                }
+                break;
+            }
+            index += 1;
+        }
+
+        return result;
+    }
+
+    // Type Expression Parser
+
+    (function (exports) {
+        var Syntax,
+            Token,
+            source,
+            length,
+            index,
+            previous,
+            token,
+            value;
+
+        Syntax = {
+            NullableLiteral: 'NullableLiteral',
+            AllLiteral: 'AllLiteral',
+            NullLiteral: 'NullLiteral',
+            UndefinedLiteral: 'UndefinedLiteral',
+            VoidLiteral: 'VoidLiteral',
+            UnionType: 'UnionType',
+            ArrayType: 'ArrayType',
+            RecordType: 'RecordType',
+            FieldType: 'FieldType',
+            FunctionType: 'FunctionType',
+            ParameterType: 'ParameterType',
+            RestType: 'RestType',
+            NonNullableType: 'NonNullableType',
+            OptionalType: 'OptionalType',
+            NullableType: 'NullableType',
+            NameExpression: 'NameExpression',
+            TypeApplication: 'TypeApplication'
+        };
+
+        Token = {
+            ILLEGAL: 0,    // ILLEGAL
+            DOT: 1,        // .
+            DOT_LT: 2,     // .&lt;
+            REST: 3,       // ...
+            LT: 4,         // &lt;
+            GT: 5,         // &gt;
+            LPAREN: 6,     // (
+            RPAREN: 7,     // )
+            LBRACE: 8,     // {
+            RBRACE: 9,     // }
+            LBRACK: 10,    // [
+            RBRACK: 11,    // ]
+            COMMA: 12,     // ,
+            COLON: 13,     // :
+            STAR: 14,      // *
+            PIPE: 15,      // |
+            QUESTION: 16,  // ?
+            BANG: 17,      // !
+            EQUAL: 18,     // =
+            NAME: 19,      // name token
+            STRING: 20,    // string
+            NUMBER: 21,    // number
+            EOF: 22
+        };
+
+        function Context(previous, index, token, value) {
+            this._previous = previous;
+            this._index = index;
+            this._token = token;
+            this._value = value;
+        }
+
+        Context.prototype.restore = function () {
+            previous = this._previous;
+            index = this._index;
+            token = this._token;
+            value = this._value;
+        };
+
+        Context.save = function () {
+            return new Context(previous, index, token, value);
+        };
+
+        function advance() {
+            var ch = source[index];
+            index += 1;
+            return ch;
+        }
+
+        function scanHexEscape(prefix) {
+            var i, len, ch, code = 0;
+
+            len = (prefix === 'u') ? 4 : 2;
+            for (i = 0; i &lt; len; ++i) {
+                if (index &lt; length &amp;&amp; isHexDigit(source[index])) {
+                    ch = advance();
+                    code = code * 16 + '0123456789abcdef'.indexOf(ch.toLowerCase());
+                } else {
+                    return '';
+                }
+            }
+            return String.fromCharCode(code);
+        }
+
+        function scanString() {
+            var str = '', quote, ch, code, unescaped, restore; //TODO review removal octal = false
+            quote = source[index];
+            ++index;
+
+            while (index &lt; length) {
+                ch = advance();
+
+                if (ch === quote) {
+                    quote = '';
+                    break;
+                } else if (ch === '\\') {
+                    ch = advance();
+                    if (!isLineTerminator(ch)) {
+                        switch (ch) {
+                        case 'n':
+                            str += '\n';
+                            break;
+                        case 'r':
+                            str += '\r';
+                            break;
+                        case 't':
+                            str += '\t';
+                            break;
+                        case 'u':
+                        case 'x':
+                            restore = index;
+                            unescaped = scanHexEscape(ch);
+                            if (unescaped) {
+                                str += unescaped;
+                            } else {
+                                index = restore;
+                                str += ch;
+                            }
+                            break;
+                        case 'b':
+                            str += '\b';
+                            break;
+                        case 'f':
+                            str += '\f';
+                            break;
+                        case 'v':
+                            str += '\v';
+                            break;
+
+                        default:
+                            if (isOctalDigit(ch)) {
+                                code = '01234567'.indexOf(ch);
+
+                                // \0 is not octal escape sequence
+                                // Deprecating unused code. TODO review removal
+                                //if (code !== 0) {
+                                //    octal = true;
+                                //}
+
+                                if (index &lt; length &amp;&amp; isOctalDigit(source[index])) {
+                                    //TODO Review Removal octal = true;
+                                    code = code * 8 + '01234567'.indexOf(advance());
+
+                                    // 3 digits are only allowed when string starts
+                                    // with 0, 1, 2, 3
+                                    if ('0123'.indexOf(ch) &gt;= 0 &amp;&amp;
+                                            index &lt; length &amp;&amp;
+                                            isOctalDigit(source[index])) {
+                                        code = code * 8 + '01234567'.indexOf(advance());
+                                    }
+                                }
+                                str += String.fromCharCode(code);
+                            } else {
+                                str += ch;
+                            }
+                            break;
+                        }
+                    } else {
+                        if (ch ===  '\r' &amp;&amp; source[index] === '\n') {
+                            ++index;
+                        }
+                    }
+                } else if (isLineTerminator(ch)) {
+                    break;
+                } else {
+                    str += ch;
+                }
+            }
+
+            if (quote !== '') {
+                throwError('unexpected quote');
+            }
+
+            value = str;
+            return Token.STRING;
+        }
+
+        function scanNumber() {
+            var number, ch;
+
+            number = '';
+            if (ch !== '.') {
+                number = advance();
+                ch = source[index];
+
+                if (number === '0') {
+                    if (ch === 'x' || ch === 'X') {
+                        number += advance();
+                        while (index &lt; length) {
+                            ch = source[index];
+                            if (!isHexDigit(ch)) {
+                                break;
+                            }
+                            number += advance();
+                        }
+
+                        if (number.length &lt;= 2) {
+                            // only 0x
+                            throwError('unexpected token');
+                        }
+
+                        if (index &lt; length) {
+                            ch = source[index];
+                            if (isIdentifierStart(ch)) {
+                                throwError('unexpected token');
+                            }
+                        }
+                        value = parseInt(number, 16);
+                        return Token.NUMBER;
+                    }
+
+                    if (isOctalDigit(ch)) {
+                        number += advance();
+                        while (index &lt; length) {
+                            ch = source[index];
+                            if (!isOctalDigit(ch)) {
+                                break;
+                            }
+                            number += advance();
+                        }
+
+                        if (index &lt; length) {
+                            ch = source[index];
+                            if (isIdentifierStart(ch) || isDecimalDigit(ch)) {
+                                throwError('unexpected token');
+                            }
+                        }
+                        value = parseInt(number, 8);
+                        return Token.NUMBER;
+                    }
+
+                    if (isDecimalDigit(ch)) {
+                        throwError('unexpected token');
+                    }
+                }
+
+                while (index &lt; length) {
+                    ch = source[index];
+                    if (!isDecimalDigit(ch)) {
+                        break;
+                    }
+                    number += advance();
+                }
+            }
+
+            if (ch === '.') {
+                number += advance();
+                while (index &lt; length) {
+                    ch = source[index];
+                    if (!isDecimalDigit(ch)) {
+                        break;
+                    }
+                    number += advance();
+                }
+            }
+
+            if (ch === 'e' || ch === 'E') {
+                number += advance();
+
+                ch = source[index];
+                if (ch === '+' || ch === '-') {
+                    number += advance();
+                }
+
+                ch = source[index];
+                if (isDecimalDigit(ch)) {
+                    number += advance();
+                    while (index &lt; length) {
+                        ch = source[index];
+                        if (!isDecimalDigit(ch)) {
+                            break;
+                        }
+                        number += advance();
+                    }
+                } else {
+                    throwError('unexpected token');
+                }
+            }
+
+            if (index &lt; length) {
+                ch = source[index];
+                if (isIdentifierStart(ch)) {
+                    throwError('unexpected token');
+                }
+            }
+
+            value = parseFloat(number);
+            return Token.NUMBER;
+        }
+
+
+        function scanTypeName() {
+            var ch, ch2;
+
+            value = advance();
+            while (index &lt; length &amp;&amp; isTypeName(source[index])) {
+                ch = source[index];
+                if (ch === '.') {
+                    if ((index + 1) &lt; length) {
+                        ch2 = source[index + 1];
+                        if (ch2 === '&lt;') {
+                            break;
+                        }
+                    }
+                }
+                value += advance();
+            }
+            return Token.NAME;
+        }
+
+        function next() {
+            var ch;
+
+            previous = index;
+
+            while (index &lt; length &amp;&amp; isWhiteSpace(source[index])) {
+                advance();
+            }
+            if (index &gt;= length) {
+                token = Token.EOF;
+                return token;
+            }
+
+            ch = source[index];
+            switch (ch) {
+            case '&quot;':
+                token = scanString();
+                return token;
+
+            case ':':
+                advance();
+                token = Token.COLON;
+                return token;
+
+            case ',':
+                advance();
+                token = Token.COMMA;
+                return token;
+
+            case '(':
+                advance();
+                token = Token.LPAREN;
+                return token;
+
+            case ')':
+                advance();
+                token = Token.RPAREN;
+                return token;
+
+            case '[':
+                advance();
+                token = Token.LBRACK;
+                return token;
+
+            case ']':
+                advance();
+                token = Token.RBRACK;
+                return token;
+
+            case '{':
+                advance();
+                token = Token.LBRACE;
+                return token;
+
+            case '}':
+                advance();
+                token = Token.RBRACE;
+                return token;
+
+            case '.':
+                advance();
+                if (index &lt; length) {
+                    ch = source[index];
+                    if (ch === '&lt;') {
+                        advance();
+                        token = Token.DOT_LT;
+                        return token;
+                    }
+
+                    if (ch === '.' &amp;&amp; index + 1 &lt; length &amp;&amp; source[index + 1] === '.') {
+                        advance();
+                        advance();
+                        token = Token.REST;
+                        return token;
+                    }
+
+                    if (isDecimalDigit(ch)) {
+                        token = scanNumber();
+                        return token;
+                    }
+                }
+                token = Token.DOT;
+                return token;
+
+            case '&lt;':
+                advance();
+                token = Token.LT;
+                return token;
+
+            case '&gt;':
+                advance();
+                token = Token.GT;
+                return token;
+
+            case '*':
+                advance();
+                token = Token.STAR;
+                return token;
+
+            case '|':
+                advance();
+                token = Token.PIPE;
+                return token;
+
+            case '?':
+                advance();
+                token = Token.QUESTION;
+                return token;
+
+            case '!':
+                advance();
+                token = Token.BANG;
+                return token;
+
+            case '=':
+                advance();
+                token = Token.EQUAL;
+                return token;
+
+            default:
+                if (isDecimalDigit(ch)) {
+                    token = scanNumber();
+                    return token;
+                }
+
+                // type string permits following case,
+                //
+                // namespace.module.MyClass
+                //
+                // this reduced 1 token TK_NAME
+                if (isTypeName(ch)) {
+                    token = scanTypeName();
+                    return token;
+                }
+
+                token = Token.ILLEGAL;
+                return token;
+            }
+        }
+
+        function consume(target, text) {
+            assert(token === target, text || 'consumed token not matched');
+            next();
+        }
+
+        function expect(target) {
+            if (token !== target) {
+                throwError('unexpected token');
+            }
+            next();
+        }
+
+        // UnionType := '(' TypeUnionList ')'
+        //
+        // TypeUnionList :=
+        //     &lt;&lt;empty&gt;&gt;
+        //   | NonemptyTypeUnionList
+        //
+        // NonemptyTypeUnionList :=
+        //     TypeExpression
+        //   | TypeExpression '|' NonemptyTypeUnionList
+        function parseUnionType() {
+            var elements;
+            consume(Token.LPAREN, 'UnionType should start with (');
+            elements = [];
+            if (token !== Token.RPAREN) {
+                while (true) {
+                    elements.push(parseTypeExpression());
+                    if (token === Token.RPAREN) {
+                        break;
+                    }
+                    expect(Token.PIPE);
+                }
+            }
+            consume(Token.RPAREN, 'UnionType should end with )');
+            return {
+                type: Syntax.UnionType,
+                elements: elements
+            };
+        }
+
+        // ArrayType := '[' ElementTypeList ']'
+        //
+        // ElementTypeList :=
+        //     &lt;&lt;empty&gt;&gt;
+        //  | TypeExpression
+        //  | '...' TypeExpression
+        //  | TypeExpression ',' ElementTypeList
+        function parseArrayType() {
+            var elements;
+            consume(Token.LBRACK, 'ArrayType should start with [');
+            elements = [];
+            while (token !== Token.RBRACK) {
+                if (token === Token.REST) {
+                    consume(Token.REST);
+                    elements.push({
+                        type: Syntax.RestType,
+                        expression: parseTypeExpression()
+                    });
+                    break;
+                } else {
+                    elements.push(parseTypeExpression());
+                }
+                if (token !== Token.RBRACK) {
+                    expect(Token.COMMA);
+                }
+            }
+            expect(Token.RBRACK);
+            return {
+                type: Syntax.ArrayType,
+                elements: elements
+            };
+        }
+
+        function parseFieldName() {
+            var v = value;
+            if (token === Token.NAME || token === Token.STRING) {
+                next();
+                return v;
+            }
+
+            if (token === Token.NUMBER) {
+                consume(Token.NUMBER);
+                return String(v);
+            }
+
+            throwError('unexpected token');
+        }
+
+        // FieldType :=
+        //     FieldName
+        //   | FieldName ':' TypeExpression
+        //
+        // FieldName :=
+        //     NameExpression
+        //   | StringLiteral
+        //   | NumberLiteral
+        //   | ReservedIdentifier
+        function parseFieldType() {
+            var key;
+
+            key = parseFieldName();
+            if (token === Token.COLON) {
+                consume(Token.COLON);
+                return {
+                    type: Syntax.FieldType,
+                    key: key,
+                    value: parseTypeExpression()
+                };
+            }
+            return {
+                type: Syntax.FieldType,
+                key: key,
+                value: null
+            };
+        }
+
+        // RecordType := '{' FieldTypeList '}'
+        //
+        // FieldTypeList :=
+        //     &lt;&lt;empty&gt;&gt;
+        //   | FieldType
+        //   | FieldType ',' FieldTypeList
+        function parseRecordType() {
+            var fields;
+
+            consume(Token.LBRACE, 'RecordType should start with {');
+            fields = [];
+            if (token === Token.COMMA) {
+                consume(Token.COMMA);
+            } else {
+                while (token !== Token.RBRACE) {
+                    fields.push(parseFieldType());
+                    if (token !== Token.RBRACE) {
+                        expect(Token.COMMA);
+                    }
+                }
+            }
+            expect(Token.RBRACE);
+            return {
+                type: Syntax.RecordType,
+                fields: fields
+            };
+        }
+
+        function parseNameExpression() {
+            var name = value;
+            expect(Token.NAME);
+            return {
+                type: Syntax.NameExpression,
+                name: name
+            };
+        }
+
+        // TypeExpressionList :=
+        //     TopLevelTypeExpression
+        //   | TopLevelTypeExpression ',' TypeExpressionList
+        function parseTypeExpressionList() {
+            var elements = [];
+
+            elements.push(parseTop());
+            while (token === Token.COMMA) {
+                consume(Token.COMMA);
+                elements.push(parseTop());
+            }
+            return elements;
+        }
+
+        // TypeName :=
+        //     NameExpression
+        //   | NameExpression TypeApplication
+        //
+        // TypeApplication :=
+        //     '.&lt;' TypeExpressionList '&gt;'
+        //   | '&lt;' TypeExpressionList '&gt;'   // this is extension of doctrine
+        function parseTypeName() {
+            var expr, applications;
+
+            expr = parseNameExpression();
+            if (token === Token.DOT_LT || token === Token.LT) {
+                next();
+                applications = parseTypeExpressionList();
+                expect(Token.GT);
+                return {
+                    type: Syntax.TypeApplication,
+                    expression: expr,
+                    applications: applications
+                };
+            }
+            return expr;
+        }
+
+        // ResultType :=
+        //     &lt;&lt;empty&gt;&gt;
+        //   | ':' void
+        //   | ':' TypeExpression
+        //
+        // BNF is above
+        // but, we remove &lt;&lt;empty&gt;&gt; pattern, so token is always TypeToken::COLON
+        function parseResultType() {
+            consume(Token.COLON, 'ResultType should start with :');
+            if (token === Token.NAME &amp;&amp; value === 'void') {
+                consume(Token.NAME);
+                return {
+                    type: Syntax.VoidLiteral
+                };
+            }
+            return parseTypeExpression();
+        }
+
+        // ParametersType :=
+        //     RestParameterType
+        //   | NonRestParametersType
+        //   | NonRestParametersType ',' RestParameterType
+        //
+        // RestParameterType :=
+        //     '...'
+        //     '...' Identifier
+        //
+        // NonRestParametersType :=
+        //     ParameterType ',' NonRestParametersType
+        //   | ParameterType
+        //   | OptionalParametersType
+        //
+        // OptionalParametersType :=
+        //     OptionalParameterType
+        //   | OptionalParameterType, OptionalParametersType
+        //
+        // OptionalParameterType := ParameterType=
+        //
+        // ParameterType := TypeExpression | Identifier ':' TypeExpression
+        //
+        // Identifier is &quot;new&quot; or &quot;this&quot;
+        function parseParametersType() {
+            var params = [], normal = true, expr, rest = false;
+
+            while (token !== Token.RPAREN) {
+                if (token === Token.REST) {
+                    // RestParameterType
+                    consume(Token.REST);
+                    rest = true;
+                }
+
+                expr = parseTypeExpression();
+                if (expr.type === Syntax.NameExpression &amp;&amp; token === Token.COLON) {
+                    // Identifier ':' TypeExpression
+                    consume(Token.COLON);
+                    expr = {
+                        type: Syntax.ParameterType,
+                        name: expr.name,
+                        expression: parseTypeExpression()
+                    };
+                }
+                if (token === Token.EQUAL) {
+                    consume(Token.EQUAL);
+                    expr = {
+                        type: Syntax.OptionalType,
+                        expression: expr
+                    };
+                    normal = false;
+                } else {
+                    if (!normal) {
+                        throwError('unexpected token');
+                    }
+                }
+                if (rest) {
+                    expr = {
+                        type: Syntax.RestType,
+                        expression: expr
+                    };
+                }
+                params.push(expr);
+                if (token !== Token.RPAREN) {
+                    expect(Token.COMMA);
+                }
+            }
+            return params;
+        }
+
+        // FunctionType := 'function' FunctionSignatureType
+        //
+        // FunctionSignatureType :=
+        //   | TypeParameters '(' ')' ResultType
+        //   | TypeParameters '(' ParametersType ')' ResultType
+        //   | TypeParameters '(' 'this' ':' TypeName ')' ResultType
+        //   | TypeParameters '(' 'this' ':' TypeName ',' ParametersType ')' ResultType
+        function parseFunctionType() {
+            var isNew, thisBinding, params, result, fnType;
+            assert(token === Token.NAME &amp;&amp; value === 'function', 'FunctionType should start with \'function\'');
+            consume(Token.NAME);
+
+            // Google Closure Compiler is not implementing TypeParameters.
+            // So we do not. if we don't get '(', we see it as error.
+            expect(Token.LPAREN);
+
+            isNew = false;
+            params = [];
+            thisBinding = null;
+            if (token !== Token.RPAREN) {
+                // ParametersType or 'this'
+                if (token === Token.NAME &amp;&amp;
+                        (value === 'this' || value === 'new')) {
+                    // 'this' or 'new'
+                    // 'new' is Closure Compiler extension
+                    isNew = value === 'new';
+                    consume(Token.NAME);
+                    expect(Token.COLON);
+                    thisBinding = parseTypeName();
+                    if (token === Token.COMMA) {
+                        consume(Token.COMMA);
+                        params = parseParametersType();
+                    }
+                } else {
+                    params = parseParametersType();
+                }
+            }
+
+            expect(Token.RPAREN);
+
+            result = null;
+            if (token === Token.COLON) {
+                result = parseResultType();
+            }
+
+            fnType = {
+                type: Syntax.FunctionType,
+                params: params,
+                result: result
+            };
+            if (thisBinding) {
+                // avoid adding null 'new' and 'this' properties
+                fnType['this'] = thisBinding;
+                if (isNew) {
+                    fnType['new'] = true;
+                }
+            }
+            return fnType;
+        }
+
+        // BasicTypeExpression :=
+        //     '*'
+        //   | 'null'
+        //   | 'undefined'
+        //   | TypeName
+        //   | FunctionType
+        //   | UnionType
+        //   | RecordType
+        //   | ArrayType
+        function parseBasicTypeExpression() {
+            var context;
+            switch (token) {
+            case Token.STAR:
+                consume(Token.STAR);
+                return {
+                    type: Syntax.AllLiteral
+                };
+
+            case Token.LPAREN:
+                return parseUnionType();
+
+            case Token.LBRACK:
+                return parseArrayType();
+
+            case Token.LBRACE:
+                return parseRecordType();
+
+            case Token.NAME:
+                if (value === 'null') {
+                    consume(Token.NAME);
+                    return {
+                        type: Syntax.NullLiteral
+                    };
+                }
+
+                if (value === 'undefined') {
+                    consume(Token.NAME);
+                    return {
+                        type: Syntax.UndefinedLiteral
+                    };
+                }
+
+                context = Context.save();
+                if (value === 'function') {
+                    try {
+                        return parseFunctionType();
+                    } catch (e) {
+                        context.restore();
+                    }
+                }
+
+                return parseTypeName();
+
+            default:
+                throwError('unexpected token');
+            }
+        }
+
+        // TypeExpression :=
+        //     BasicTypeExpression
+        //   | '?' BasicTypeExpression
+        //   | '!' BasicTypeExpression
+        //   | BasicTypeExpression '?'
+        //   | BasicTypeExpression '!'
+        //   | '?'
+        //   | BasicTypeExpression '[]'
+        function parseTypeExpression() {
+            var expr;
+
+            if (token === Token.QUESTION) {
+                consume(Token.QUESTION);
+                if (token === Token.COMMA || token === Token.EQUAL || token === Token.RBRACE ||
+                        token === Token.RPAREN || token === Token.PIPE || token === Token.EOF ||
+                        token === Token.RBRACK) {
+                    return {
+                        type: Syntax.NullableLiteral
+                    };
+                }
+                return {
+                    type: Syntax.NullableType,
+                    expression: parseBasicTypeExpression(),
+                    prefix: true
+                };
+            }
+
+            if (token === Token.BANG) {
+                consume(Token.BANG);
+                return {
+                    type: Syntax.NonNullableType,
+                    expression: parseBasicTypeExpression(),
+                    prefix: true
+                };
+            }
+
+            expr = parseBasicTypeExpression();
+            if (token === Token.BANG) {
+                consume(Token.BANG);
+                return {
+                    type: Syntax.NonNullableType,
+                    expression: expr,
+                    prefix: false
+                };
+            }
+
+            if (token === Token.QUESTION) {
+                consume(Token.QUESTION);
+                return {
+                    type: Syntax.NullableType,
+                    expression: expr,
+                    prefix: false
+                };
+            }
+
+            if (token === Token.LBRACK) {
+                consume(Token.LBRACK);
+                consume(Token.RBRACK, 'expected an array-style type declaration (' + value + '[])');
+                return {
+                    type: Syntax.TypeApplication,
+                    expression: {
+                        type: Syntax.NameExpression,
+                        name: 'Array'
+                    },
+                    applications: [expr]
+                };
+            }
+
+            return expr;
+        }
+
+        // TopLevelTypeExpression :=
+        //      TypeExpression
+        //    | TypeUnionList
+        //
+        // This rule is Google Closure Compiler extension, not ES4
+        // like,
+        //   { number | string }
+        // If strict to ES4, we should write it as
+        //   { (number|string) }
+        function parseTop() {
+            var expr, elements;
+
+            expr = parseTypeExpression();
+            if (token !== Token.PIPE) {
+                return expr;
+            }
+
+            elements = [ expr ];
+            consume(Token.PIPE);
+            while (true) {
+                elements.push(parseTypeExpression());
+                if (token !== Token.PIPE) {
+                    break;
+                }
+                consume(Token.PIPE);
+            }
+
+            return {
+                type: Syntax.UnionType,
+                elements: elements
+            };
+        }
+
+        function parseTopParamType() {
+            var expr;
+
+            if (token === Token.REST) {
+                consume(Token.REST);
+                return {
+                    type: Syntax.RestType,
+                    expression: parseTop()
+                };
+            }
+
+            expr = parseTop();
+            if (token === Token.EQUAL) {
+                consume(Token.EQUAL);
+                return {
+                    type: Syntax.OptionalType,
+                    expression: expr
+                };
+            }
+
+            return expr;
+        }
+
+        function parseType(src, opt) {
+            var expr;
+
+            source = src;
+            length = source.length;
+            index = 0;
+            previous = 0;
+
+            if (!CanAccessStringByIndex) {
+                source = source.split('');
+            }
+
+            next();
+            expr = parseTop();
+
+            if (opt &amp;&amp; opt.midstream) {
+                return {
+                    expression: expr,
+                    index: previous
+                };
+            }
+
+            if (token !== Token.EOF) {
+                throwError('not reach to EOF');
+            }
+
+            return expr;
+        }
+
+        function parseParamType(src, opt) {
+            var expr;
+
+            source = src;
+            length = source.length;
+            index = 0;
+            previous = 0;
+
+            if (!CanAccessStringByIndex) {
+                source = source.split('');
+            }
+
+            next();
+            expr = parseTopParamType();
+
+            if (opt &amp;&amp; opt.midstream) {
+                return {
+                    expression: expr,
+                    index: previous
+                };
+            }
+
+            if (token !== Token.EOF) {
+                throwError('not reach to EOF');
+            }
+
+            return expr;
+        }
+
+        function stringifyImpl(node, compact, topLevel) {
+            var result, i, iz;
+
+            switch (node.type) {
+            case Syntax.NullableLiteral:
+                result = '?';
+                break;
+
+            case Syntax.AllLiteral:
+                result = '*';
+                break;
+
+            case Syntax.NullLiteral:
+                result = 'null';
+                break;
+
+            case Syntax.UndefinedLiteral:
+                result = 'undefined';
+                break;
+
+            case Syntax.VoidLiteral:
+                result = 'void';
+                break;
+
+            case Syntax.UnionType:
+                if (!topLevel) {
+                    result = '(';
+                } else {
+                    result = '';
+                }
+
+                for (i = 0, iz = node.elements.length; i &lt; iz; ++i) {
+                    result += stringifyImpl(node.elements[i], compact);
+                    if ((i + 1) !== iz) {
+                        result += '|';
+                    }
+                }
+
+                if (!topLevel) {
+                    result += ')';
+                }
+                break;
+
+            case Syntax.ArrayType:
+                result = '[';
+                for (i = 0, iz = node.elements.length; i &lt; iz; ++i) {
+                    result += stringifyImpl(node.elements[i], compact);
+                    if ((i + 1) !== iz) {
+                        result += compact ? ',' : ', ';
+                    }
+                }
+                result += ']';
+                break;
+
+            case Syntax.RecordType:
+                result = '{';
+                for (i = 0, iz = node.fields.length; i &lt; iz; ++i) {
+                    result += stringifyImpl(node.fields[i], compact);
+                    if ((i + 1) !== iz) {
+                        result += compact ? ',' : ', ';
+                    }
+                }
+                result += '}';
+                break;
+
+            case Syntax.FieldType:
+                if (node.value) {
+                    result = node.key + (compact ? ':' : ': ') + stringifyImpl(node.value, compact);
+                } else {
+                    result = node.key;
+                }
+                break;
+
+            case Syntax.FunctionType:
+                result = compact ? 'function(' : 'function (';
+
+                if (node['this']) {
+                    if (node['new']) {
+                        result += (compact ? 'new:' : 'new: ');
+                    } else {
+                        result += (compact ? 'this:' : 'this: ');
+                    }
+
+                    result += stringifyImpl(node['this'], compact);
+
+                    if (node.params.length !== 0) {
+                        result += compact ? ',' : ', ';
+                    }
+                }
+
+                for (i = 0, iz = node.params.length; i &lt; iz; ++i) {
+                    result += stringifyImpl(node.params[i], compact);
+                    if ((i + 1) !== iz) {
+                        result += compact ? ',' : ', ';
+                    }
+                }
+
+                result += ')';
+
+                if (node.result) {
+                    result += (compact ? ':' : ': ') + stringifyImpl(node.result, compact);
+                }
+                break;
+
+            case Syntax.ParameterType:
+                result = node.name + (compact ? ':' : ': ') + stringifyImpl(node.expression, compact);
+                break;
+
+            case Syntax.RestType:
+                result = '...';
+                if (node.expression) {
+                    result += stringifyImpl(node.expression, compact);
+                }
+                break;
+
+            case Syntax.NonNullableType:
+                if (node.prefix) {
+                    result = '!' + stringifyImpl(node.expression, compact);
+                } else {
+                    result = stringifyImpl(node.expression, compact) + '!';
+                }
+                break;
+
+            case Syntax.OptionalType:
+                result = stringifyImpl(node.expression, compact) + '=';
+                break;
+
+            case Syntax.NullableType:
+                if (node.prefix) {
+                    result = '?' + stringifyImpl(node.expression, compact);
+                } else {
+                    result = stringifyImpl(node.expression, compact) + '?';
+                }
+                break;
+
+            case Syntax.NameExpression:
+                result = node.name;
+                break;
+
+            case Syntax.TypeApplication:
+                result = stringifyImpl(node.expression, compact) + '.&lt;';
+                for (i = 0, iz = node.applications.length; i &lt; iz; ++i) {
+                    result += stringifyImpl(node.applications[i], compact);
+                    if ((i + 1) !== iz) {
+                        result += compact ? ',' : ', ';
+                    }
+                }
+                result += '&gt;';
+                break;
+
+            default:
+                throwError('Unknown type ' + node.type);
+            }
+
+            return result;
+        }
+
+        function stringify(node, options) {
+            if (options == null) {
+                options = {};
+            }
+            return stringifyImpl(node, options.compact, options.topLevel);
+        }
+
+        exports.parseType = parseType;
+        exports.parseParamType = parseParamType;
+        exports.stringify = stringify;
+        exports.Syntax = Syntax;
+    }(typed = {}));
+
+    // JSDoc Tag Parser
+
+    (function (exports) {
+        var Rules,
+            index,
+            lineNumber,
+            length,
+            source,
+            recoverable,
+            sloppy,
+            strict;
+
+        function advance() {
+            var ch = source[index];
+            index += 1;
+            if (isLineTerminator(ch)) {
+                lineNumber += 1;
+            }
+            return ch;
+        }
+
+        function scanTitle() {
+            var title = '';
+            // waste '@'
+            advance();
+
+            while (index &lt; length &amp;&amp; isASCIIAlphanumeric(source[index])) {
+                title += advance();
+            }
+
+            return title;
+        }
+
+        function seekContent() {
+            var ch, waiting, last = index;
+
+            waiting = false;
+            while (last &lt; length) {
+                ch = source[last];
+                if (isLineTerminator(ch)) {
+                    lineNumber += 1;
+                    waiting = true;
+                } else if (waiting) {
+                    if (ch === '@') {
+                        break;
+                    }
+                    if (!isWhiteSpace(ch)) {
+                        waiting = false;
+                    }
+                }
+                last += 1;
+            }
+            return last;
+        }
+
+        // type expression may have nest brace, such as,
+        // { { ok: string } }
+        //
+        // therefore, scanning type expression with balancing braces.
+        function parseType(title, last) {
+            var ch, brace, type, direct = false;
+
+            // search '{'
+            while (index &lt; last) {
+                ch = source[index];
+                if (isWhiteSpace(ch)) {
+                    advance();
+                } else if (ch === '{') {
+                    advance();
+                    break;
+                } else {
+                    // this is direct pattern
+                    direct = true;
+                    break;
+                }
+            }
+
+            if (!direct) {
+                // type expression { is found
+                brace = 1;
+                type = '';
+                while (index &lt; last) {
+                    ch = source[index];
+                    if (isLineTerminator(ch)) {
+                        advance();
+                    } else {
+                        if (ch === '}') {
+                            brace -= 1;
+                            if (brace === 0) {
+                                advance();
+                                break;
+                            }
+                        } else if (ch === '{') {
+                            brace += 1;
+                        }
+                        type += advance();
+                    }
+                }
+
+                if (brace !== 0) {
+                    // braces is not balanced
+                    return throwError('Braces are not balanced');
+                }
+
+                try {
+                    if (isParamTitle(title)) {
+                        return typed.parseParamType(type);
+                    }
+                    return typed.parseType(type);
+                } catch (e1) {
+                    // parse failed
+                    return null;
+                }
+            } else {
+                return null;
+            }
+        }
+
+        function scanIdentifier(last) {
+            var identifier;
+            if (!isIdentifierStart(source[index])) {
+                return null;
+            }
+            identifier = advance();
+            while (index &lt; last &amp;&amp; isIdentifierPart(source[index])) {
+                identifier += advance();
+            }
+            return identifier;
+        }
+
+        function skipWhiteSpace(last) {
+            while (index &lt; last &amp;&amp; (isWhiteSpace(source[index]) || isLineTerminator(source[index]))) {
+                advance();
+            }
+        }
+
+        function parseName(last, allowBrackets, allowNestedParams) {
+            var name = '', useBrackets;
+
+            skipWhiteSpace(last);
+
+            if (index &gt;= last) {
+                return null;
+            }
+
+            if (allowBrackets &amp;&amp; source[index] === '[') {
+                useBrackets = true;
+                name = advance();
+            }
+
+            if (!isIdentifierStart(source[index])) {
+                return null;
+            }
+
+            name += scanIdentifier(last);
+
+            if (allowNestedParams) {
+                while (source[index] === '.') {
+                    name += '.';
+                    index += 1;
+                    name += scanIdentifier(last);
+                }
+            }
+
+            if (useBrackets) {
+                // do we have a default value for this?
+                if (source[index] === '=') {
+
+                    // consume the '='' symbol
+                    name += advance();
+                    // scan in the default value
+                    while (index &lt; last &amp;&amp; source[index] !== ']') {
+                        name += advance();
+                    }
+                }
+
+                if (index &gt;= last  || source[index] !== ']') {
+                    // we never found a closing ']'
+                    return null;
+                }
+
+                // collect the last ']'
+                name += advance();
+            }
+
+            return name;
+        }
+
+        function skipToTag() {
+            while (index &lt; length &amp;&amp; source[index] !== '@') {
+                advance();
+            }
+            if (index &gt;= length) {
+                return false;
+            }
+            assert(source[index] === '@');
+            return true;
+        }
+
+        function TagParser(options, title) {
+            this._options = options;
+            this._title = title;
+            this._tag = {
+                title: title,
+                description: null
+            };
+            if (this._options.lineNumbers) {
+                this._tag.lineNumber = lineNumber;
+            }
+            this._last = 0;
+            // space to save special information for title parsers.
+            this._extra = { };
+        }
+
+        // addError(err, ...)
+        TagParser.prototype.addError = function addError(errorText) {
+            var args = Array.prototype.slice.call(arguments, 1),
+                msg = errorText.replace(
+                    /%(\d)/g,
+                    function (whole, index) {
+                        assert(index &lt; args.length, 'Message reference must be in range');
+                        return args[index];
+                    }
+                );
+
+            if (!this._tag.errors) {
+                this._tag.errors = [];
+            }
+            if (strict) {
+                throwError(msg);
+            }
+            this._tag.errors.push(msg);
+            return recoverable;
+        };
+
+        TagParser.prototype.parseType = function () {
+            // type required titles
+            if (isTypeParameterRequired(this._title)) {
+                try {
+                    this._tag.type = parseType(this._title, this._last);
+                    if (!this._tag.type) {
+                        if (!isParamTitle(this._title)) {
+                            if (!this.addError('Missing or invalid tag type')) {
+                                return false;
+                            }
+                        }
+                    }
+                } catch (error) {
+                    this._tag.type = null;
+                    if (!this.addError(error.message)) {
+                        return false;
+                    }
+                }
+            } else if (isAllowedType(this._title)) {
+                // optional types
+                try {
+                    this._tag.type = parseType(this._title, this._last);
+                } catch (e) {
+                    //For optional types, lets drop the thrown error when we hit the end of the file
+                }
+            }
+            return true;
+        };
+
+        TagParser.prototype._parseNamePath = function (optional) {
+            var name;
+            name = parseName(this._last, sloppy &amp;&amp; isParamTitle(this._title), true);
+            if (!name) {
+                if (!optional) {
+                    if (!this.addError('Missing or invalid tag name')) {
+                        return false;
+                    }
+                }
+            }
+            this._tag.name = name;
+            return true;
+        };
+
+        TagParser.prototype.parseNamePath = function () {
+            return this._parseNamePath(false);
+        };
+
+        TagParser.prototype.parseNamePathOptional = function () {
+            return this._parseNamePath(true);
+        };
+
+
+        TagParser.prototype.parseName = function () {
+            var assign, name;
+
+            // param, property requires name
+            if (isAllowedName(this._title)) {
+                this._tag.name = parseName(this._last, sloppy &amp;&amp; isParamTitle(this._title), isAllowedNested(this._title));
+                if (!this._tag.name) {
+                    if (!isNameParameterRequired(this._title)) {
+                        return true;
+                    }
+
+                    // it's possible the name has already been parsed but interpreted as a type
+                    // it's also possible this is a sloppy declaration, in which case it will be
+                    // fixed at the end
+                    if (isParamTitle(this._title) &amp;&amp; this._tag.type.name) {
+                        this._extra.name = this._tag.type;
+                        this._tag.name = this._tag.type.name;
+                        this._tag.type = null;
+                    } else {
+                        if (!this.addError('Missing or invalid tag name')) {
+                            return false;
+                        }
+                    }
+                } else {
+                    name = this._tag.name;
+                    if (name.charAt(0) === '[' &amp;&amp; name.charAt(name.length - 1) === ']') {
+                        // extract the default value if there is one
+                        // example: @param {string} [somebody=John Doe] description
+                        assign = name.substring(1, name.length - 1).split('=');
+                        if (assign[1]) {
+                            this._tag['default'] = assign[1];
+                        }
+                        this._tag.name = assign[0];
+
+                        // convert to an optional type
+                        if (this._tag.type.type !== 'OptionalType') {
+                            this._tag.type = {
+                                type: 'OptionalType',
+                                expression: this._tag.type
+                            };
+                        }
+                    }
+                }
+            }
+
+            return true;
+        };
+
+        TagParser.prototype.parseDescription = function parseDescription() {
+            var description = trim(sliceSource(source, index, this._last));
+            if (description) {
+                if ((/^-\s+/).test(description)) {
+                    description = description.substring(2);
+                }
+                this._tag.description = description;
+            }
+            return true;
+        };
+
+        TagParser.prototype.parseKind = function parseKind() {
+            var kind, kinds;
+            kinds = {
+                'class': true,
+                'constant': true,
+                'event': true,
+                'external': true,
+                'file': true,
+                'function': true,
+                'member': true,
+                'mixin': true,
+                'module': true,
+                'namespace': true,
+                'typedef': true
+            };
+            kind = trim(sliceSource(source, index, this._last));
+            this._tag.kind = kind;
+            if (!hasOwnProperty(kinds, kind)) {
+                if (!this.addError('Invalid kind name \'%0\'', kind)) {
+                    return false;
+                }
+            }
+            return true;
+        };
+
+        TagParser.prototype.parseAccess = function parseAccess() {
+            var access;
+            access = trim(sliceSource(source, index, this._last));
+            this._tag.access = access;
+            if (access !== 'private' &amp;&amp; access !== 'protected' &amp;&amp; access !== 'public') {
+                if (!this.addError('Invalid access name \'%0\'', access)) {
+                    return false;
+                }
+            }
+            return true;
+        };
+
+        TagParser.prototype.parseVariation = function parseVariation() {
+            var variation, text;
+            text = trim(sliceSource(source, index, this._last));
+            variation = parseFloat(text, 10);
+            this._tag.variation = variation;
+            if (isNaN(variation)) {
+                if (!this.addError('Invalid variation \'%0\'', text)) {
+                    return false;
+                }
+            }
+            return true;
+        };
+
+        TagParser.prototype.ensureEnd = function () {
+            var shouldBeEmpty = trim(sliceSource(source, index, this._last));
+            if (shouldBeEmpty) {
+                if (!this.addError('Unknown content \'%0\'', shouldBeEmpty)) {
+                    return false;
+                }
+            }
+            return true;
+        };
+
+        TagParser.prototype.epilogue = function epilogue() {
+            var description;
+
+            description = this._tag.description;
+            // un-fix potentially sloppy declaration
+            if (isParamTitle(this._title) &amp;&amp; !this._tag.type &amp;&amp; description &amp;&amp; description.charAt(0) === '[') {
+                this._tag.type = this._extra.name;
+                this._tag.name = undefined;
+
+                if (!sloppy) {
+                    if (!this.addError('Missing or invalid tag name')) {
+                        return false;
+                    }
+                }
+            }
+
+            return true;
+        };
+
+        Rules = {
+            // http://usejsdoc.org/tags-access.html
+            'access': ['parseAccess'],
+            // http://usejsdoc.org/tags-alias.html
+            'alias': ['parseNamePath', 'ensureEnd'],
+            // http://usejsdoc.org/tags-augments.html
+            'augments': ['parseType', 'parseNamePathOptional', 'ensureEnd'],
+            // http://usejsdoc.org/tags-constructor.html
+            'constructor': ['parseType', 'parseNamePathOptional', 'ensureEnd'],
+            // Synonym: http://usejsdoc.org/tags-constructor.html
+            'class': ['parseType', 'parseNamePathOptional', 'ensureEnd'],
+            // Synonym: http://usejsdoc.org/tags-extends.html
+            'extends': ['parseType', 'parseNamePathOptional', 'ensureEnd'],
+            // http://usejsdoc.org/tags-deprecated.html
+            'deprecated': ['parseDescription'],
+            // http://usejsdoc.org/tags-global.html
+            'global': ['ensureEnd'],
+            // http://usejsdoc.org/tags-inner.html
+            'inner': ['ensureEnd'],
+            // http://usejsdoc.org/tags-instance.html
+            'instance': ['ensureEnd'],
+            // http://usejsdoc.org/tags-kind.html
+            'kind': ['parseKind'],
+            // http://usejsdoc.org/tags-mixes.html
+            'mixes': ['parseNamePath', 'ensureEnd'],
+            // http://usejsdoc.org/tags-mixin.html
+            'mixin': ['parseNamePathOptional', 'ensureEnd'],
+            // http://usejsdoc.org/tags-member.html
+            'member': ['parseType', 'parseNamePathOptional', 'ensureEnd'],
+            // http://usejsdoc.org/tags-method.html
+            'method': ['parseNamePathOptional', 'ensureEnd'],
+            // http://usejsdoc.org/tags-module.html
+            'module': ['parseType', 'parseNamePathOptional', 'ensureEnd'],
+            // Synonym: http://usejsdoc.org/tags-method.html
+            'func': ['parseNamePathOptional', 'ensureEnd'],
+            // Synonym: http://usejsdoc.org/tags-method.html
+            'function': ['parseNamePathOptional', 'ensureEnd'],
+            // Synonym: http://usejsdoc.org/tags-member.html
+            'var': ['parseType', 'parseNamePathOptional', 'ensureEnd'],
+            // http://usejsdoc.org/tags-name.html
+            'name': ['parseNamePath', 'ensureEnd'],
+            // http://usejsdoc.org/tags-namespace.html
+            'namespace': ['parseType', 'parseNamePathOptional', 'ensureEnd'],
+            // http://usejsdoc.org/tags-private.html
+            'private': ['parseType', 'parseDescription'],
+            // http://usejsdoc.org/tags-protected.html
+            'protected': ['parseType', 'parseDescription'],
+            // http://usejsdoc.org/tags-public.html
+            'public': ['parseType', 'parseDescription'],
+            // http://usejsdoc.org/tags-readonly.html
+            'readonly': ['ensureEnd'],
+            // http://usejsdoc.org/tags-requires.html
+            'requires': ['parseNamePath', 'ensureEnd'],
+            // http://usejsdoc.org/tags-since.html
+            'since': ['parseDescription'],
+            // http://usejsdoc.org/tags-static.html
+            'static': ['ensureEnd'],
+            // http://usejsdoc.org/tags-summary.html
+            'summary': ['parseDescription'],
+            // http://usejsdoc.org/tags-this.html
+            'this': ['parseNamePath', 'ensureEnd'],
+            // http://usejsdoc.org/tags-todo.html
+            'todo': ['parseDescription'],
+            // http://usejsdoc.org/tags-variation.html
+            'variation': ['parseVariation'],
+            // http://usejsdoc.org/tags-version.html
+            'version': ['parseDescription']
+        };
+
+        TagParser.prototype.parse = function parse() {
+            var i, iz, sequences, method;
+
+            // empty title
+            if (!this._title) {
+                if (!this.addError('Missing or invalid title')) {
+                    return null;
+                }
+            }
+
+            // Seek to content last index.
+            this._last = seekContent(this._title);
+
+            if (hasOwnProperty(Rules, this._title)) {
+                sequences = Rules[this._title];
+            } else {
+                // default sequences
+                sequences = ['parseType', 'parseName', 'parseDescription', 'epilogue'];
+            }
+
+            for (i = 0, iz = sequences.length; i &lt; iz; ++i) {
+                method = sequences[i];
+                if (!this[method]()) {
+                    return null;
+                }
+            }
+
+            // Seek global index to end of this tag.
+            index = this._last;
+            return this._tag;
+        };
+
+        function parseTag(options) {
+            var title, parser;
+
+            // skip to tag
+            if (!skipToTag()) {
+                return null;
+            }
+
+            // scan title
+            title = scanTitle();
+
+            // construct tag parser
+            parser = new TagParser(options, title);
+            return parser.parse();
+        }
+
+        //
+        // Parse JSDoc
+        //
+
+        function scanJSDocDescription() {
+            var description = '', ch, atAllowed;
+
+            atAllowed = true;
+            while (index &lt; length) {
+                ch = source[index];
+
+                if (atAllowed &amp;&amp; ch === '@') {
+                    break;
+                }
+
+                if (isLineTerminator(ch)) {
+                    atAllowed = true;
+                } else if (atAllowed &amp;&amp; !isWhiteSpace(ch)) {
+                    atAllowed = false;
+                }
+
+                description += advance();
+            }
+            return trim(description);
+        }
+
+        function parse(comment, options) {
+            var tags = [], tag, description, interestingTags, i, iz;
+
+            if (options === undefined) {
+                options = {};
+            }
+
+            if (typeof options.unwrap === 'boolean' &amp;&amp; options.unwrap) {
+                source = unwrapComment(comment);
+            } else {
+                source = comment;
+            }
+
+            // array of relevant tags
+            if (options.tags) {
+                if (isArray(options.tags)) {
+                    interestingTags = { };
+                    for (i = 0, iz = options.tags.length; i &lt; iz; i++) {
+                        if (typeof options.tags[i] === 'string') {
+                            interestingTags[options.tags[i]] = true;
+                        } else {
+                            throwError('Invalid &quot;tags&quot; parameter: ' + options.tags);
+                        }
+                    }
+                } else {
+                    throwError('Invalid &quot;tags&quot; parameter: ' + options.tags);
+                }
+            }
+
+            if (!CanAccessStringByIndex) {
+                source = source.split('');
+            }
+
+            length = source.length;
+            index = 0;
+            lineNumber = 0;
+            recoverable = options.recoverable;
+            sloppy = options.sloppy;
+            strict = options.strict;
+
+            description = scanJSDocDescription();
+
+            while (true) {
+                tag = parseTag(options);
+                if (!tag) {
+                    break;
+                }
+                if (!interestingTags || interestingTags.hasOwnProperty(tag.title)) {
+                    tags.push(tag);
+                }
+            }
+
+            return {
+                description: description,
+                tags: tags
+            };
+        }
+        exports.parse = parse;
+    }(jsdoc = {}));
+
+    exports.version = VERSION;
+    exports.parse = jsdoc.parse;
+    exports.parseType = typed.parseType;
+    exports.parseParamType = typed.parseParamType;
+    exports.unwrapComment = unwrapComment;
+    exports.Syntax = shallowCopy(typed.Syntax);
+    exports.Error = DoctrineError;
+    exports.type = {
+        Syntax: exports.Syntax,
+        parseType: typed.parseType,
+        parseParamType: typed.parseParamType,
+        stringify: typed.stringify
+    };
+}(typeof exports === 'undefined' ? (doctrine = {}) : exports));
+/* vim: set sw=4 ts=4 et tw=80 : */
+
+},{}],5:[function(require,module,exports){
+/*
+  Copyright (C) 2012-2013 Yusuke Suzuki &lt;utatane.tea@gmail.com&gt;
+  Copyright (C) 2013 Alex Seville &lt;hi@alexanderseville.com&gt;
+
+  Redistribution and use in source and binary forms, with or without
+  modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in the
+      documentation and/or other materials provided with the distribution.
+
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS &quot;AS IS&quot;
+  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  ARE DISCLAIMED. IN NO EVENT SHALL &lt;COPYRIGHT HOLDER&gt; BE LIABLE FOR ANY
+  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/**
+ * Escope (&lt;a href=&quot;http://github.com/Constellation/escope&quot;&gt;escope&lt;/a&gt;) is an &lt;a
+ * href=&quot;http://www.ecma-international.org/publications/standards/Ecma-262.htm&quot;&gt;ECMAScript&lt;/a&gt;
+ * scope analyzer extracted from the &lt;a
+ * href=&quot;http://github.com/Constellation/esmangle&quot;&gt;esmangle project&lt;/a/&gt;.
+ * &lt;p&gt;
+ * &lt;em&gt;escope&lt;/em&gt; finds lexical scopes in a source program, i.e. areas of that
+ * program where different occurrences of the same identifier refer to the same
+ * variable. With each scope the contained variables are collected, and each
+ * identifier reference in code is linked to its corresponding variable (if
+ * possible).
+ * &lt;p&gt;
+ * &lt;em&gt;escope&lt;/em&gt; works on a syntax tree of the parsed source code which has
+ * to adhere to the &lt;a
+ * href=&quot;https://developer.mozilla.org/en-US/docs/SpiderMonkey/Parser_API&quot;&gt;
+ * Mozilla Parser API&lt;/a&gt;. E.g. &lt;a href=&quot;http://esprima.org&quot;&gt;esprima&lt;/a&gt; is a parser
+ * that produces such syntax trees.
+ * &lt;p&gt;
+ * The main interface is the {@link analyze} function.
+ * @module
+ */
+
+/*jslint bitwise:true */
+/*global exports:true, define:true, require:true*/
+(function (factory, global) {
+    'use strict';
+
+    function namespace(str, obj) {
+        var i, iz, names, name;
+        names = str.split('.');
+        for (i = 0, iz = names.length; i &lt; iz; ++i) {
+            name = names[i];
+            if (obj.hasOwnProperty(name)) {
+                obj = obj[name];
+            } else {
+                obj = (obj[name] = {});
+            }
+        }
+        return obj;
+    }
+
+    // Universal Module Definition (UMD) to support AMD, CommonJS/Node.js,
+    // and plain browser loading,
+    if (typeof define === 'function' &amp;&amp; define.amd) {
+        define('escope', ['exports', 'estraverse'], function (exports, estraverse) {
+            factory(exports, global, estraverse);
+        });
+    } else if (typeof exports !== 'undefined') {
+        factory(exports, global, require('estraverse'));
+    } else {
+        factory(namespace('escope', global), global, global.estraverse);
+    }
+}(function (exports, global, estraverse) {
+    'use strict';
+
+    var Syntax,
+        Map,
+        currentScope,
+        globalScope,
+        scopes,
+        options;
+
+    Syntax = estraverse.Syntax;
+
+    if (typeof global.Map !== 'undefined') {
+        // ES6 Map
+        Map = global.Map;
+    } else {
+        Map = function Map() {
+            this.__data = {};
+        };
+
+        Map.prototype.get = function MapGet(key) {
+            key = '$' + key;
+            if (this.__data.hasOwnProperty(key)) {
+                return this.__data[key];
+            }
+            return undefined;
+        };
+
+        Map.prototype.has = function MapHas(key) {
+            key = '$' + key;
+            return this.__data.hasOwnProperty(key);
+        };
+
+        Map.prototype.set = function MapSet(key, val) {
+            key = '$' + key;
+            this.__data[key] = val;
+        };
+
+        Map.prototype['delete'] = function MapDelete(key) {
+            key = '$' + key;
+            return delete this.__data[key];
+        };
+    }
+
+    function assert(cond, text) {
+        if (!cond) {
+            throw new Error(text);
+        }
+    }
+
+    function defaultOptions() {
+        return {
+            optimistic: false,
+            directive: false
+        };
+    }
+
+    function updateDeeply(target, override) {
+        var key, val;
+
+        function isHashObject(target) {
+            return typeof target === 'object' &amp;&amp; target instanceof Object &amp;&amp; !(target instanceof RegExp);
+        }
+
+        for (key in override) {
+            if (override.hasOwnProperty(key)) {
+                val = override[key];
+                if (isHashObject(val)) {
+                    if (isHashObject(target[key])) {
+                        updateDeeply(target[key], val);
+                    } else {
+                        target[key] = updateDeeply({}, val);
+                    }
+                } else {
+                    target[key] = val;
+                }
+            }
+        }
+        return target;
+    }
+
+    /**
+     * A Reference represents a single occurrence of an identifier in code.
+     * @class Reference
+     */
+    function Reference(ident, scope, flag, writeExpr, maybeImplicitGlobal) {
+        /** 
+         * Identifier syntax node.
+         * @member {esprima#Identifier} Reference#identifier 
+         */
+        this.identifier = ident;
+        /** 
+         * Reference to the enclosing Scope.
+         * @member {Scope} Reference#from 
+         */
+        this.from = scope;
+        /**
+         * Whether the reference comes from a dynamic scope (such as 'eval',
+         * 'with', etc.), and may be trapped by dynamic scopes.
+         * @member {boolean} Reference#tainted
+         */
+        this.tainted = false;
+        /** 
+         * The variable this reference is resolved with.
+         * @member {Variable} Reference#resolved 
+         */
+        this.resolved = null;
+        /** 
+         * The read-write mode of the reference. (Value is one of {@link
+         * Reference.READ}, {@link Reference.RW}, {@link Reference.WRITE}).
+         * @member {number} Reference#flag 
+         * @private
+         */
+        this.flag = flag;
+        if (this.isWrite()) {
+            /** 
+             * If reference is writeable, this is the tree being written to it.
+             * @member {esprima#Node} Reference#writeExpr 
+             */
+            this.writeExpr = writeExpr;
+        }
+        /** 
+         * Whether the Reference might refer to a global variable.
+         * @member {boolean} Reference#__maybeImplicitGlobal 
+         * @private
+         */
+        this.__maybeImplicitGlobal = maybeImplicitGlobal;
+    }
+
+    /** 
+     * @constant Reference.READ 
+     * @private
+     */
+    Reference.READ = 0x1;
+    /** 
+     * @constant Reference.WRITE 
+     * @private
+     */
+    Reference.WRITE = 0x2;
+    /** 
+     * @constant Reference.RW 
+     * @private
+     */
+    Reference.RW = 0x3;
+
+    /**
+     * Whether the reference is static.
+     * @method Reference#isStatic
+     * @return {boolean}
+     */
+    Reference.prototype.isStatic = function isStatic() {
+        return !this.tainted &amp;&amp; this.resolved &amp;&amp; this.resolved.scope.isStatic();
+    };
+
+    /**
+     * Whether the reference is writeable.
+     * @method Reference#isWrite
+     * @return {boolean}
+     */
+    Reference.prototype.isWrite = function isWrite() {
+        return this.flag &amp; Reference.WRITE;
+    };
+
+    /**
+     * Whether the reference is readable.
+     * @method Reference#isRead
+     * @return {boolean}
+     */
+    Reference.prototype.isRead = function isRead() {
+        return this.flag &amp; Reference.READ;
+    };
+
+    /**
+     * Whether the reference is read-only.
+     * @method Reference#isReadOnly
+     * @return {boolean}
+     */
+    Reference.prototype.isReadOnly = function isReadOnly() {
+        return this.flag === Reference.READ;
+    };
+
+    /**
+     * Whether the reference is write-only.
+     * @method Reference#isWriteOnly
+     * @return {boolean}
+     */
+    Reference.prototype.isWriteOnly = function isWriteOnly() {
+        return this.flag === Reference.WRITE;
+    };
+
+    /**
+     * Whether the reference is read-write.
+     * @method Reference#isReadWrite
+     * @return {boolean}
+     */
+    Reference.prototype.isReadWrite = function isReadWrite() {
+        return this.flag === Reference.RW;
+    };
+
+    /**
+     * A Variable represents a locally scoped identifier. These include arguments to
+     * functions.
+     * @class Variable
+     */
+    function Variable(name, scope) {
+        /**  
+         * The variable name, as given in the source code.
+         * @member {String} Variable#name 
+         */
+        this.name = name;
+        /**
+         * List of defining occurrences of this variable (like in 'var ...'
+         * statements or as parameter), as AST nodes.
+         * @member {esprima.Identifier[]} Variable#identifiers
+         */
+        this.identifiers = [];
+        /**
+         * List of {@link Reference|references} of this variable (excluding parameter entries)
+         * in its defining scope and all nested scopes. For defining
+         * occurrences only see {@link Variable#defs}.
+         * @member {Reference[]} Variable#references
+         */
+        this.references = [];
+
+        /**
+         * List of defining occurrences of this variable (like in 'var ...'
+         * statements or as parameter), as custom objects.
+         * @typedef {Object} DefEntry
+         * @property {String} DefEntry.type - the type of the occurrence (e.g.
+         *      &quot;Parameter&quot;, &quot;Variable&quot;, ...)
+         * @property {esprima.Identifier} DefEntry.name - the identifier AST node of the occurrence
+         * @property {esprima.Node} DefEntry.node - the enclosing node of the
+         *      identifier
+         * @property {esprima.Node} [DefEntry.parent] - the enclosing statement
+         *      node of the identifier
+         * @member {DefEntry[]} Variable#defs
+         */
+        this.defs = [];
+
+        this.tainted = false;
+        /**
+         * Whether this is a stack variable.
+         * @member {boolean} Variable#stack
+         */
+        this.stack = true;
+        /** 
+         * Reference to the enclosing Scope.
+         * @member {Scope} Variable#scope 
+         */
+        this.scope = scope;
+    }
+
+    Variable.CatchClause = 'CatchClause';
+    Variable.Parameter = 'Parameter';
+    Variable.FunctionName = 'FunctionName';
+    Variable.Variable = 'Variable';
+    Variable.ImplicitGlobalVariable = 'ImplicitGlobalVariable';
+
+    function isStrictScope(scope, block) {
+        var body, i, iz, stmt, expr;
+
+        // When upper scope is exists and strict, inner scope is also strict.
+        if (scope.upper &amp;&amp; scope.upper.isStrict) {
+            return true;
+        }
+
+        if (scope.type === 'function') {
+            body = block.body;
+        } else if (scope.type === 'global') {
+            body = block;
+        } else {
+            return false;
+        }
+
+        if (options.directive) {
+            for (i = 0, iz = body.body.length; i &lt; iz; ++i) {
+                stmt = body.body[i];
+                if (stmt.type !== 'DirectiveStatement') {
+                    break;
+                }
+                if (stmt.raw === '&quot;use strict&quot;' || stmt.raw === '\'use strict\'') {
+                    return true;
+                }
+            }
+        } else {
+            for (i = 0, iz = body.body.length; i &lt; iz; ++i) {
+                stmt = body.body[i];
+                if (stmt.type !== Syntax.ExpressionStatement) {
+                    break;
+                }
+                expr = stmt.expression;
+                if (expr.type !== Syntax.Literal || typeof expr.value !== 'string') {
+                    break;
+                }
+                if (expr.raw != null) {
+                    if (expr.raw === '&quot;use strict&quot;' || expr.raw === '\'use strict\'') {
+                        return true;
+                    }
+                } else {
+                    if (expr.value === 'use strict') {
+                        return true;
+                    }
+                }
+            }
+        }
+        return false;
+    }
+
+    /**
+     * @class Scope
+     */
+    function Scope(block, opt) {
+        var variable, body;
+
+        /**
+         * One of 'catch', 'with', 'function' or 'global'.
+         * @member {String} Scope#type
+         */
+        this.type =
+            (block.type === Syntax.CatchClause) ? 'catch' :
+            (block.type === Syntax.WithStatement) ? 'with' :
+            (block.type === Syntax.Program) ? 'global' : 'function';
+         /**
+         * The scoped {@link Variable}s of this scope, as &lt;code&gt;{ Variable.name
+         * : Variable }&lt;/code&gt;.
+         * @member {Map} Scope#set
+         */
+        this.set = new Map();
+        /**
+         * The tainted variables of this scope, as &lt;code&gt;{ Variable.name :
+         * boolean }&lt;/code&gt;.
+         * @member {Map} Scope#taints */
+        this.taints = new Map();
+        /**
+         * Generally, through the lexical scoping of JS you can always know
+         * which variable an identifier in the source code refers to. There are
+         * a few exceptions to this rule. With 'global' and 'with' scopes you
+         * can only decide at runtime which variable a reference refers to.
+         * Moreover, if 'eval()' is used in a scope, it might introduce new
+         * bindings in this or its prarent scopes.
+         * All those scopes are considered 'dynamic'.
+         * @member {boolean} Scope#dynamic
+         */
+        this.dynamic = this.type === 'global' || this.type === 'with';
+        /**
+         * A reference to the scope-defining syntax node.
+         * @member {esprima.Node} Scope#block
+         */
+        this.block = block;
+         /**
+         * The {@link Reference|references} that are not resolved with this scope.
+         * @member {Reference[]} Scope#through
+         */
+        this.through = [];
+         /**
+         * The scoped {@link Variable}s of this scope. In the case of a
+         * 'function' scope this includes the automatic argument &lt;em&gt;arguments&lt;/em&gt; as
+         * its first element, as well as all further formal arguments.
+         * @member {Variable[]} Scope#variables
+         */
+        this.variables = [];
+         /**
+         * Any variable {@link Reference|reference} found in this scope. This
+         * includes occurrences of local variables as well as variables from
+         * parent scopes (including the global scope). For local variables
+         * this also includes defining occurrences (like in a 'var' statement).
+         * In a 'function' scope this does not include the occurrences of the
+         * formal parameter in the parameter list.
+         * @member {Reference[]} Scope#references
+         */
+        this.references = [];
+         /**
+         * List of {@link Reference}s that are left to be resolved (i.e. which
+         * need to be linked to the variable they refer to). Used internally to
+         * resolve bindings during scope analysis. On a finalized scope
+         * analysis, all sopes have &lt;em&gt;left&lt;/em&gt; value &lt;strong&gt;null&lt;/strong&gt;.
+         * @member {Reference[]} Scope#left
+         */
+        this.left = [];
+         /**
+         * For 'global' and 'function' scopes, this is a self-reference. For
+         * other scope types this is the &lt;em&gt;variableScope&lt;/em&gt; value of the
+         * parent scope.
+         * @member {Scope} Scope#variableScope
+         */
+        this.variableScope =
+            (this.type === 'global' || this.type === 'function') ? this : currentScope.variableScope;
+         /**
+         * Whether this scope is created by a FunctionExpression.
+         * @member {boolean} Scope#functionExpressionScope
+         */
+        this.functionExpressionScope = false;
+         /**
+         * Whether this is a scope that contains an 'eval()' invocation.
+         * @member {boolean} Scope#directCallToEvalScope
+         */
+        this.directCallToEvalScope = false;
+         /**
+         * @member {boolean} Scope#thisFound
+         */
+        this.thisFound = false;
+        body = this.type === 'function' ? block.body : block;
+        if (opt.naming) {
+            this.__define(block.id, {
+                type: Variable.FunctionName,
+                name: block.id,
+                node: block
+            });
+            this.functionExpressionScope = true;
+        } else {
+            if (this.type === 'function') {
+                variable = new Variable('arguments', this);
+                this.taints.set('arguments', true);
+                this.set.set('arguments', variable);
+                this.variables.push(variable);
+            }
+
+            if (block.type === Syntax.FunctionExpression &amp;&amp; block.id) {
+                new Scope(block, { naming: true });
+            }
+        }
+
+         /**
+         * Reference to the parent {@link Scope|scope}.
+         * @member {Scope} Scope#upper
+         */
+        this.upper = currentScope;
+         /**
+         * Whether 'use strict' is in effect in this scope.
+         * @member {boolean} Scope#isStrict
+         */
+        this.isStrict = isStrictScope(this, block);
+
+         /**
+         * List of nested {@link Scope}s.
+         * @member {Scope[]} Scope#childScopes
+         */
+        this.childScopes = [];
+        if (currentScope) {
+            currentScope.childScopes.push(this);
+        }
+
+
+        // RAII
+        currentScope = this;
+        if (this.type === 'global') {
+            globalScope = this;
+            globalScope.implicit = {
+                set: new Map(),
+                variables: []
+            };
+        }
+        scopes.push(this);
+    }
+
+    Scope.prototype.__close = function __close() {
+        var i, iz, ref, current, node, implicit;
+
+        // Because if this is global environment, upper is null
+        if (!this.dynamic || options.optimistic) {
+            // static resolve
+            for (i = 0, iz = this.left.length; i &lt; iz; ++i) {
+                ref = this.left[i];
+                if (!this.__resolve(ref)) {
+                    this.__delegateToUpperScope(ref);
+                }
+            }
+        } else {
+            // this is &quot;global&quot; / &quot;with&quot; / &quot;function with eval&quot; environment
+            if (this.type === 'with') {
+                for (i = 0, iz = this.left.length; i &lt; iz; ++i) {
+                    ref = this.left[i];
+                    ref.tainted = true;
+                    this.__delegateToUpperScope(ref);
+                }
+            } else {
+                for (i = 0, iz = this.left.length; i &lt; iz; ++i) {
+                    // notify all names are through to global
+                    ref = this.left[i];
+                    current = this;
+                    do {
+                        current.through.push(ref);
+                        current = current.upper;
+                    } while (current);
+                }
+            }
+        }
+
+        if (this.type === 'global') {
+            implicit = [];
+            for (i = 0, iz = this.left.length; i &lt; iz; ++i) {
+                ref = this.left[i];
+                if (ref.__maybeImplicitGlobal &amp;&amp; !this.set.has(ref.identifier.name)) {
+                    implicit.push(ref.__maybeImplicitGlobal);
+                }
+            }
+
+            // create an implicit global variable from assignment expression
+            for (i = 0, iz = implicit.length; i &lt; iz; ++i) {
+                node = implicit[i];
+                this.__defineImplicit(node.left, {
+                    type: Variable.ImplicitGlobalVariable,
+                    name: node.left,
+                    node: node
+                });
+            }
+        }
+
+        this.left = null;
+        currentScope = this.upper;
+    };
+
+    Scope.prototype.__resolve = function __resolve(ref) {
+        var variable, name;
+        name = ref.identifier.name;
+        if (this.set.has(name)) {
+            variable = this.set.get(name);
+            variable.references.push(ref);
+            variable.stack = variable.stack &amp;&amp; ref.from.variableScope === this.variableScope;
+            if (ref.tainted) {
+                variable.tainted = true;
+                this.taints.set(variable.name, true);
+            }
+            ref.resolved = variable;
+            return true;
+        }
+        return false;
+    };
+
+    Scope.prototype.__delegateToUpperScope = function __delegateToUpperScope(ref) {
+        if (this.upper) {
+            this.upper.left.push(ref);
+        }
+        this.through.push(ref);
+    };
+
+    Scope.prototype.__defineImplicit = function __defineImplicit(node, info) {
+        var name, variable;
+        if (node &amp;&amp; node.type === Syntax.Identifier) {
+            name = node.name;
+            if (!this.implicit.set.has(name)) {
+                variable = new Variable(name, this);
+                variable.identifiers.push(node);
+                variable.defs.push(info);
+                this.implicit.set.set(name, variable);
+                this.implicit.variables.push(variable);
+            } else {
+                variable = this.implicit.set.get(name);
+                variable.identifiers.push(node);
+                variable.defs.push(info);
+            }
+        }
+    };
+
+    Scope.prototype.__define = function __define(node, info) {
+        var name, variable;
+        if (node &amp;&amp; node.type === Syntax.Identifier) {
+            name = node.name;
+            if (!this.set.has(name)) {
+                variable = new Variable(name, this);
+                variable.identifiers.push(node);
+                variable.defs.push(info);
+                this.set.set(name, variable);
+                this.variables.push(variable);
+            } else {
+                variable = this.set.get(name);
+                variable.identifiers.push(node);
+                variable.defs.push(info);
+            }
+        }
+    };
+
+    Scope.prototype.__referencing = function __referencing(node, assign, writeExpr, maybeImplicitGlobal) {
+        var ref;
+        // because Array element may be null
+        if (node &amp;&amp; node.type === Syntax.Identifier) {
+            ref = new Reference(node, this, assign || Reference.READ, writeExpr, maybeImplicitGlobal);
+            this.references.push(ref);
+            this.left.push(ref);
+        }
+    };
+
+    Scope.prototype.__detectEval = function __detectEval() {
+        var current;
+        current = this;
+        this.directCallToEvalScope = true;
+        do {
+            current.dynamic = true;
+            current = current.upper;
+        } while (current);
+    };
+
+    Scope.prototype.__detectThis = function __detectThis() {
+        this.thisFound = true;
+    };
+
+    Scope.prototype.__isClosed = function isClosed() {
+        return this.left === null;
+    };
+
+    // API Scope#resolve(name)
+    // returns resolved reference
+    Scope.prototype.resolve = function resolve(ident) {
+        var ref, i, iz;
+        assert(this.__isClosed(), 'scope should be closed');
+        assert(ident.type === Syntax.Identifier, 'target should be identifier');
+        for (i = 0, iz = this.references.length; i &lt; iz; ++i) {
+            ref = this.references[i];
+            if (ref.identifier === ident) {
+                return ref;
+            }
+        }
+        return null;
+    };
+
+    // API Scope#isStatic
+    // returns this scope is static
+    Scope.prototype.isStatic = function isStatic() {
+        return !this.dynamic;
+    };
+
+    // API Scope#isArgumentsMaterialized
+    // return this scope has materialized arguments
+    Scope.prototype.isArgumentsMaterialized = function isArgumentsMaterialized() {
+        // TODO(Constellation)
+        // We can more aggressive on this condition like this.
+        //
+        // function t() {
+        //     // arguments of t is always hidden.
+        //     function arguments() {
+        //     }
+        // }
+        var variable;
+
+        // This is not function scope
+        if (this.type !== 'function') {
+            return true;
+        }
+
+        if (!this.isStatic()) {
+            return true;
+        }
+
+        variable = this.set.get('arguments');
+        assert(variable, 'always have arguments variable');
+        return variable.tainted || variable.references.length  !== 0;
+    };
+
+    // API Scope#isThisMaterialized
+    // return this scope has materialized `this` reference
+    Scope.prototype.isThisMaterialized = function isThisMaterialized() {
+        // This is not function scope
+        if (this.type !== 'function') {
+            return true;
+        }
+        if (!this.isStatic()) {
+            return true;
+        }
+        return this.thisFound;
+    };
+
+    Scope.mangledName = '__$escope$__';
+
+    Scope.prototype.attach = function attach() {
+        if (!this.functionExpressionScope) {
+            this.block[Scope.mangledName] = this;
+        }
+    };
+
+    Scope.prototype.detach = function detach() {
+        if (!this.functionExpressionScope) {
+            delete this.block[Scope.mangledName];
+        }
+    };
+
+    Scope.prototype.isUsedName = function (name) {
+        if (this.set.has(name)) {
+            return true;
+        }
+        for (var i = 0, iz = this.through.length; i &lt; iz; ++i) {
+            if (this.through[i].identifier.name === name) {
+                return true;
+            }
+        }
+        return false;
+    };
+
+    /**
+     * @class ScopeManager
+     */
+    function ScopeManager(scopes) {
+        this.scopes = scopes;
+        this.attached = false;
+    }
+
+    // Returns appropliate scope for this node
+    ScopeManager.prototype.__get = function __get(node) {
+        var i, iz, scope;
+        if (this.attached) {
+            return node[Scope.mangledName] || null;
+        }
+        if (Scope.isScopeRequired(node)) {
+            for (i = 0, iz = this.scopes.length; i &lt; iz; ++i) {
+                scope = this.scopes[i];
+                if (!scope.functionExpressionScope) {
+                    if (scope.block === node) {
+                        return scope;
+                    }
+                }
+            }
+        }
+        return null;
+    };
+
+    ScopeManager.prototype.acquire = function acquire(node) {
+        return this.__get(node);
+    };
+
+    ScopeManager.prototype.release = function release(node) {
+        var scope = this.__get(node);
+        if (scope) {
+            scope = scope.upper;
+            while (scope) {
+                if (!scope.functionExpressionScope) {
+                    return scope;
+                }
+                scope = scope.upper;
+            }
+        }
+        return null;
+    };
+
+    ScopeManager.prototype.attach = function attach() {
+        var i, iz;
+        for (i = 0, iz = this.scopes.length; i &lt; iz; ++i) {
+            this.scopes[i].attach();
+        }
+        this.attached = true;
+    };
+
+    ScopeManager.prototype.detach = function detach() {
+        var i, iz;
+        for (i = 0, iz = this.scopes.length; i &lt; iz; ++i) {
+            this.scopes[i].detach();
+        }
+        this.attached = false;
+    };
+
+    Scope.isScopeRequired = function isScopeRequired(node) {
+        return Scope.isVariableScopeRequired(node) || node.type === Syntax.WithStatement || node.type === Syntax.CatchClause;
+    };
+
+    Scope.isVariableScopeRequired = function isVariableScopeRequired(node) {
+        return node.type === Syntax.Program || node.type === Syntax.FunctionExpression || node.type === Syntax.FunctionDeclaration;
+    };
+
+    /**
+     * Main interface function. Takes an Esprima syntax tree and returns the
+     * analyzed scopes.
+     * @function analyze
+     * @param {esprima.Tree} tree
+     * @param {Object} providedOptions - Options that tailor the scope analysis
+     * @param {boolean} [providedOptions.optimistic=false] - the optimistic flag
+     * @param {boolean} [providedOptions.directive=false]- the directive flag
+     * @param {boolean} [providedOptions.ignoreEval=false]- whether to check 'eval()' calls
+     * @return {ScopeManager}
+     */
+    function analyze(tree, providedOptions) {
+        var resultScopes;
+
+        options = updateDeeply(defaultOptions(), providedOptions);
+        resultScopes = scopes = [];
+        currentScope = null;
+        globalScope = null;
+
+        // attach scope and collect / resolve names
+        estraverse.traverse(tree, {
+            enter: function enter(node) {
+                var i, iz, decl;
+                if (Scope.isScopeRequired(node)) {
+                    new Scope(node, {});
+                }
+
+                switch (node.type) {
+                case Syntax.AssignmentExpression:
+                    if (node.operator === '=') {
+                        currentScope.__referencing(node.left, Reference.WRITE, node.right, (!currentScope.isStrict &amp;&amp; node.left.name != null) &amp;&amp; node);
+                    } else {
+                        currentScope.__referencing(node.left, Reference.RW, node.right);
+                    }
+                    currentScope.__referencing(node.right);
+                    break;
+
+                case Syntax.ArrayExpression:
+                    for (i = 0, iz = node.elements.length; i &lt; iz; ++i) {
+                        currentScope.__referencing(node.elements[i]);
+                    }
+                    break;
+
+                case Syntax.BlockStatement:
+                    break;
+
+                case Syntax.BinaryExpression:
+                    currentScope.__referencing(node.left);
+                    currentScope.__referencing(node.right);
+                    break;
+
+                case Syntax.BreakStatement:
+                    break;
+
+                case Syntax.CallExpression:
+                    currentScope.__referencing(node.callee);
+                    for (i = 0, iz = node['arguments'].length; i &lt; iz; ++i) {
+                        currentScope.__referencing(node['arguments'][i]);
+                    }
+
+                    // check this is direct call to eval
+                    if (!options.ignoreEval &amp;&amp; node.callee.type === Syntax.Identifier &amp;&amp; node.callee.name === 'eval') {
+                        currentScope.variableScope.__detectEval();
+                    }
+                    break;
+
+                case Syntax.CatchClause:
+                    currentScope.__define(node.param, {
+                        type: Variable.CatchClause,
+                        name: node.param,
+                        node: node
+                    });
+                    break;
+
+                case Syntax.ConditionalExpression:
+                    currentScope.__referencing(node.test);
+                    currentScope.__referencing(node.consequent);
+                    currentScope.__referencing(node.alternate);
+                    break;
+
+                case Syntax.ContinueStatement:
+                    break;
+
+                case Syntax.DirectiveStatement:
+                    break;
+
+                case Syntax.DoWhileStatement:
+                    currentScope.__referencing(node.test);
+                    break;
+
+                case Syntax.DebuggerStatement:
+                    break;
+
+                case Syntax.EmptyStatement:
+                    break;
+
+                case Syntax.ExpressionStatement:
+                    currentScope.__referencing(node.expression);
+                    break;
+
+                case Syntax.ForStatement:
+                    currentScope.__referencing(node.init);
+                    currentScope.__referencing(node.test);
+                    currentScope.__referencing(node.update);
+                    break;
+
+                case Syntax.ForInStatement:
+                    if (node.left.type === Syntax.VariableDeclaration) {
+                        currentScope.__referencing(node.left.declarations[0].id, Reference.WRITE, null, false);
+                    } else {
+                        currentScope.__referencing(node.left, Reference.WRITE, null, (!currentScope.isStrict &amp;&amp; node.left.name != null) &amp;&amp; node);
+                    }
+                    currentScope.__referencing(node.right);
+                    break;
+
+                case Syntax.FunctionDeclaration:
+                    // FunctionDeclaration name is defined in upper scope
+                    currentScope.upper.__define(node.id, {
+                        type: Variable.FunctionName,
+                        name: node.id,
+                        node: node
+                    });
+                    for (i = 0, iz = node.params.length; i &lt; iz; ++i) {
+                        currentScope.__define(node.params[i], {
+                            type: Variable.Parameter,
+                            name: node.params[i],
+                            node: node,
+                            index: i
+                        });
+                    }
+                    break;
+
+                case Syntax.FunctionExpression:
+                    // id is defined in upper scope
+                    for (i = 0, iz = node.params.length; i &lt; iz; ++i) {
+                        currentScope.__define(node.params[i], {
+                            type: Variable.Parameter,
+                            name: node.params[i],
+                            node: node,
+                            index: i
+                        });
+                    }
+                    break;
+
+                case Syntax.Identifier:
+                    break;
+
+                case Syntax.IfStatement:
+                    currentScope.__referencing(node.test);
+                    break;
+
+                case Syntax.Literal:
+                    break;
+
+                case Syntax.LabeledStatement:
+                    break;
+
+                case Syntax.LogicalExpression:
+                    currentScope.__referencing(node.left);
+                    currentScope.__referencing(node.right);
+                    break;
+
+                case Syntax.MemberExpression:
+                    currentScope.__referencing(node.object);
+                    if (node.computed) {
+                        currentScope.__referencing(node.property);
+                    }
+                    break;
+
+                case Syntax.NewExpression:
+                    currentScope.__referencing(node.callee);
+                    for (i = 0, iz = node['arguments'].length; i &lt; iz; ++i) {
+                        currentScope.__referencing(node['arguments'][i]);
+                    }
+                    break;
+
+                case Syntax.ObjectExpression:
+                    break;
+
+                case Syntax.Program:
+                    break;
+
+                case Syntax.Property:
+                    currentScope.__referencing(node.value);
+                    break;
+
+                case Syntax.ReturnStatement:
+                    currentScope.__referencing(node.argument);
+                    break;
+
+                case Syntax.SequenceExpression:
+                    for (i = 0, iz = node.expressions.length; i &lt; iz; ++i) {
+                        currentScope.__referencing(node.expressions[i]);
+                    }
+                    break;
+
+                case Syntax.SwitchStatement:
+                    currentScope.__referencing(node.discriminant);
+                    break;
+
+                case Syntax.SwitchCase:
+                    currentScope.__referencing(node.test);
+                    break;
+
+                case Syntax.ThisExpression:
+                    currentScope.variableScope.__detectThis();
+                    break;
+
+                case Syntax.ThrowStatement:
+                    currentScope.__referencing(node.argument);
+                    break;
+
+                case Syntax.TryStatement:
+                    break;
+
+                case Syntax.UnaryExpression:
+                    currentScope.__referencing(node.argument);
+                    break;
+
+                case Syntax.UpdateExpression:
+                    currentScope.__referencing(node.argument, Reference.RW, null);
+                    break;
+
+                case Syntax.VariableDeclaration:
+                    for (i = 0, iz = node.declarations.length; i &lt; iz; ++i) {
+                        decl = node.declarations[i];
+                        currentScope.variableScope.__define(decl.id, {
+                            type: Variable.Variable,
+                            name: decl.id,
+                            node: decl,
+                            index: i,
+                            parent: node
+                        });
+                        if (decl.init) {
+                            // initializer is found
+                            currentScope.__referencing(decl.id, Reference.WRITE, decl.init, false);
+                            currentScope.__referencing(decl.init);
+                        }
+                    }
+                    break;
+
+                case Syntax.VariableDeclarator:
+                    break;
+
+                case Syntax.WhileStatement:
+                    currentScope.__referencing(node.test);
+                    break;
+
+                case Syntax.WithStatement:
+                    // WithStatement object is referenced at upper scope
+                    currentScope.upper.__referencing(node.object);
+                    break;
+                }
+            },
+
+            leave: function leave(node) {
+                while (currentScope &amp;&amp; node === currentScope.block) {
+                    currentScope.__close();
+                }
+            }
+        });
+
+        assert(currentScope === null);
+        globalScope = null;
+        scopes = null;
+        options = null;
+
+        return new ScopeManager(resultScopes);
+    }
+
+    /** @name module:escope.version */
+    exports.version = '1.0.1';
+    /** @name module:escope.Reference */
+    exports.Reference = Reference;
+    /** @name module:escope.Variable */
+    exports.Variable = Variable;
+    /** @name module:escope.Scope */
+    exports.Scope = Scope;
+    /** @name module:escope.ScopeManager */
+    exports.ScopeManager = ScopeManager;
+    /** @name module:escope.analyze */
+    exports.analyze = analyze;
+}, this));
+/* vim: set sw=4 ts=4 et tw=80 : */
+
+},{&quot;estraverse&quot;:7}],6:[function(require,module,exports){
+/*
+  Copyright (C) 2013 Ariya Hidayat &lt;ariya.hidayat@gmail.com&gt;
+  Copyright (C) 2013 Thaddee Tyl &lt;thaddee.tyl@gmail.com&gt;
+  Copyright (C) 2013 Mathias Bynens &lt;mathias@qiwi.be&gt;
+  Copyright (C) 2012 Ariya Hidayat &lt;ariya.hidayat@gmail.com&gt;
+  Copyright (C) 2012 Mathias Bynens &lt;mathias@qiwi.be&gt;
+  Copyright (C) 2012 Joost-Wim Boekesteijn &lt;joost-wim@boekesteijn.nl&gt;
+  Copyright (C) 2012 Kris Kowal &lt;kris.kowal@cixar.com&gt;
+  Copyright (C) 2012 Yusuke Suzuki &lt;utatane.tea@gmail.com&gt;
+  Copyright (C) 2012 Arpad Borsos &lt;arpad.borsos@googlemail.com&gt;
+  Copyright (C) 2011 Ariya Hidayat &lt;ariya.hidayat@gmail.com&gt;
+
+  Redistribution and use in source and binary forms, with or without
+  modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in the
+      documentation and/or other materials provided with the distribution.
+
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS &quot;AS IS&quot;
+  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  ARE DISCLAIMED. IN NO EVENT SHALL &lt;COPYRIGHT HOLDER&gt; BE LIABLE FOR ANY
+  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/*jslint bitwise:true plusplus:true */
+/*global esprima:true, define:true, exports:true, window: true,
+throwErrorTolerant: true,
+throwError: true, generateStatement: true, peek: true,
+parseAssignmentExpression: true, parseBlock: true, parseExpression: true,
+parseFunctionDeclaration: true, parseFunctionExpression: true,
+parseFunctionSourceElements: true, parseVariableIdentifier: true,
+parseLeftHandSideExpression: true,
+parseUnaryExpression: true,
+parseStatement: true, parseSourceElement: true */
+
+(function (root, factory) {
+    'use strict';
+
+    // Universal Module Definition (UMD) to support AMD, CommonJS/Node.js,
+    // Rhino, and plain browser loading.
+
+    /* istanbul ignore next */
+    if (typeof define === 'function' &amp;&amp; define.amd) {
+        define(['exports'], factory);
+    } else if (typeof exports !== 'undefined') {
+        factory(exports);
+    } else {
+        factory((root.esprima = {}));
+    }
+}(this, function (exports) {
+    'use strict';
+
+    var Token,
+        TokenName,
+        FnExprTokens,
+        Syntax,
+        PropertyKind,
+        Messages,
+        Regex,
+        SyntaxTreeDelegate,
+        source,
+        strict,
+        index,
+        lineNumber,
+        lineStart,
+        length,
+        delegate,
+        lookahead,
+        state,
+        extra;
+
+    Token = {
+        BooleanLiteral: 1,
+        EOF: 2,
+        Identifier: 3,
+        Keyword: 4,
+        NullLiteral: 5,
+        NumericLiteral: 6,
+        Punctuator: 7,
+        StringLiteral: 8,
+        RegularExpression: 9
+    };
+
+    TokenName = {};
+    TokenName[Token.BooleanLiteral] = 'Boolean';
+    TokenName[Token.EOF] = '&lt;end&gt;';
+    TokenName[Token.Identifier] = 'Identifier';
+    TokenName[Token.Keyword] = 'Keyword';
+    TokenName[Token.NullLiteral] = 'Null';
+    TokenName[Token.NumericLiteral] = 'Numeric';
+    TokenName[Token.Punctuator] = 'Punctuator';
+    TokenName[Token.StringLiteral] = 'String';
+    TokenName[Token.RegularExpression] = 'RegularExpression';
+
+    // A function following one of those tokens is an expression.
+    FnExprTokens = ['(', '{', '[', 'in', 'typeof', 'instanceof', 'new',
+                    'return', 'case', 'delete', 'throw', 'void',
+                    // assignment operators
+                    '=', '+=', '-=', '*=', '/=', '%=', '&lt;&lt;=', '&gt;&gt;=', '&gt;&gt;&gt;=',
+                    '&amp;=', '|=', '^=', ',',
+                    // binary/unary operators
+                    '+', '-', '*', '/', '%', '++', '--', '&lt;&lt;', '&gt;&gt;', '&gt;&gt;&gt;', '&amp;',
+                    '|', '^', '!', '~', '&amp;&amp;', '||', '?', ':', '===', '==', '&gt;=',
+                    '&lt;=', '&lt;', '&gt;', '!=', '!=='];
+
+    Syntax = {
+        AssignmentExpression: 'AssignmentExpression',
+        ArrayExpression: 'ArrayExpression',
+        BlockStatement: 'BlockStatement',
+        BinaryExpression: 'BinaryExpression',
+        BreakStatement: 'BreakStatement',
+        CallExpression: 'CallExpression',
+        CatchClause: 'CatchClause',
+        ConditionalExpression: 'ConditionalExpression',
+        ContinueStatement: 'ContinueStatement',
+        DoWhileStatement: 'DoWhileStatement',
+        DebuggerStatement: 'DebuggerStatement',
+        EmptyStatement: 'EmptyStatement',
+        ExpressionStatement: 'ExpressionStatement',
+        ForStatement: 'ForStatement',
+        ForInStatement: 'ForInStatement',
+        FunctionDeclaration: 'FunctionDeclaration',
+        FunctionExpression: 'FunctionExpression',
+        Identifier: 'Identifier',
+        IfStatement: 'IfStatement',
+        Literal: 'Literal',
+        LabeledStatement: 'LabeledStatement',
+        LogicalExpression: 'LogicalExpression',
+        MemberExpression: 'MemberExpression',
+        NewExpression: 'NewExpression',
+        ObjectExpression: 'ObjectExpression',
+        Program: 'Program',
+        Property: 'Property',
+        ReturnStatement: 'ReturnStatement',
+        SequenceExpression: 'SequenceExpression',
+        SwitchStatement: 'SwitchStatement',
+        SwitchCase: 'SwitchCase',
+        ThisExpression: 'ThisExpression',
+        ThrowStatement: 'ThrowStatement',
+        TryStatement: 'TryStatement',
+        UnaryExpression: 'UnaryExpression',
+        UpdateExpression: 'UpdateExpression',
+        VariableDeclaration: 'VariableDeclaration',
+        VariableDeclarator: 'VariableDeclarator',
+        WhileStatement: 'WhileStatement',
+        WithStatement: 'WithStatement'
+    };
+
+    PropertyKind = {
+        Data: 1,
+        Get: 2,
+        Set: 4
+    };
+
+    // Error messages should be identical to V8.
+    Messages = {
+        UnexpectedToken:  'Unexpected token %0',
+        UnexpectedNumber:  'Unexpected number',
+        UnexpectedString:  'Unexpected string',
+        UnexpectedIdentifier:  'Unexpected identifier',
+        UnexpectedReserved:  'Unexpected reserved word',
+        UnexpectedEOS:  'Unexpected end of input',
+        NewlineAfterThrow:  'Illegal newline after throw',
+        InvalidRegExp: 'Invalid regular expression',
+        UnterminatedRegExp:  'Invalid regular expression: missing /',
+        InvalidLHSInAssignment:  'Invalid left-hand side in assignment',
+        InvalidLHSInForIn:  'Invalid left-hand side in for-in',
+        MultipleDefaultsInSwitch: 'More than one default clause in switch statement',
+        NoCatchOrFinally:  'Missing catch or finally after try',
+        UnknownLabel: 'Undefined label \'%0\'',
+        Redeclaration: '%0 \'%1\' has already been declared',
+        IllegalContinue: 'Illegal continue statement',
+        IllegalBreak: 'Illegal break statement',
+        IllegalReturn: 'Illegal return statement',
+        StrictModeWith:  'Strict mode code may not include a with statement',
+        StrictCatchVariable:  'Catch variable may not be eval or arguments in strict mode',
+        StrictVarName:  'Variable name may not be eval or arguments in strict mode',
+        StrictParamName:  'Parameter name eval or arguments is not allowed in strict mode',
+        StrictParamDupe: 'Strict mode function may not have duplicate parameter names',
+        StrictFunctionName:  'Function name may not be eval or arguments in strict mode',
+        StrictOctalLiteral:  'Octal literals are not allowed in strict mode.',
+        StrictDelete:  'Delete of an unqualified identifier in strict mode.',
+        StrictDuplicateProperty:  'Duplicate data property in object literal not allowed in strict mode',
+        AccessorDataProperty:  'Object literal may not have data and accessor property with the same name',
+        AccessorGetSet:  'Object literal may not have multiple get/set accessors with the same name',
+        StrictLHSAssignment:  'Assignment to eval or arguments is not allowed in strict mode',
+        StrictLHSPostfix:  'Postfix increment/decrement may not have eval or arguments operand in strict mode',
+        StrictLHSPrefix:  'Prefix increment/decrement may not have eval or arguments operand in strict mode',
+        StrictReservedWord:  'Use of future reserved word in strict mode'
+    };
+
+    // See also tools/generate-unicode-regex.py.
+    Regex = {
+        NonAsciiIdentifierStart: new RegExp('[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u0527\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0\u08A2-\u08AC\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0977\u0979-\u097F\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35
 -\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C33\u0C35-\u0C39\u0C3D\u0C58\u0C59\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D60\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u
 12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F4\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F0\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191C\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19C1-\u19C7\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\
 u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA697\uA6A0-\uA6EF\uA717-\uA71F\uA722-\uA788\uA78B-\uA78E\uA790-\uA793\uA7A0-\uA7AA\uA7F8-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA80-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uF
 AD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]'),
+        NonAsciiIdentifierPart: new RegExp('[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0300-\u0374\u0376\u0377\u037A-\u037D\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u0483-\u0487\u048A-\u0527\u0531-\u0556\u0559\u0561-\u0587\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u05D0-\u05EA\u05F0-\u05F2\u0610-\u061A\u0620-\u0669\u066E-\u06D3\u06D5-\u06DC\u06DF-\u06E8\u06EA-\u06FC\u06FF\u0710-\u074A\u074D-\u07B1\u07C0-\u07F5\u07FA\u0800-\u082D\u0840-\u085B\u08A0\u08A2-\u08AC\u08E4-\u08FE\u0900-\u0963\u0966-\u096F\u0971-\u0977\u0979-\u097F\u0981-\u0983\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BC-\u09C4\u09C7\u09C8\u09CB-\u09CE\u09D7\u09DC\u09DD\u09DF-\u09E3\u09E6-\u09F1\u0A01-\u0A03\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A59-\u0A5C\u0A5E\u0A66-\u0A75\u0A81-\u0A83\u0A85-\u0A8D\u0A8F-\u0A91\u0A9
 3-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABC-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AD0\u0AE0-\u0AE3\u0AE6-\u0AEF\u0B01-\u0B03\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3C-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B5C\u0B5D\u0B5F-\u0B63\u0B66-\u0B6F\u0B71\u0B82\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD0\u0BD7\u0BE6-\u0BEF\u0C01-\u0C03\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C33\u0C35-\u0C39\u0C3D-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C58\u0C59\u0C60-\u0C63\u0C66-\u0C6F\u0C82\u0C83\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBC-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CDE\u0CE0-\u0CE3\u0CE6-\u0CEF\u0CF1\u0CF2\u0D02\u0D03\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D-\u0D44\u0D46-\u0D48\u0D4A-\u0D4E\u0D57\u0D60-\u0D63\u0D66-\u0D6F\u0D7A-\u0D7F\u0D82\u0D83\u0D85-\u0D96\u0D9A-
 \u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DF2\u0DF3\u0E01-\u0E3A\u0E40-\u0E4E\u0E50-\u0E59\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB9\u0EBB-\u0EBD\u0EC0-\u0EC4\u0EC6\u0EC8-\u0ECD\u0ED0-\u0ED9\u0EDC-\u0EDF\u0F00\u0F18\u0F19\u0F20-\u0F29\u0F35\u0F37\u0F39\u0F3E-\u0F47\u0F49-\u0F6C\u0F71-\u0F84\u0F86-\u0F97\u0F99-\u0FBC\u0FC6\u1000-\u1049\u1050-\u109D\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u135D-\u135F\u1380-\u138F\u13A0-\u13F4\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F0\u1700-\u170C\u170E-\u1714\u1720-\u1734\u1740-\u1753\u1760-\u176C\u176E-\u1770\u1772\u1773\u1780-\u17D3\u17D7\u17DC\u17DD\u17E0-\u17E9\u180B-\u180D\u1810-\u1819\u1820-\u1877\u1880-\u18AA\u18B
 0-\u18F5\u1900-\u191C\u1920-\u192B\u1930-\u193B\u1946-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u19D0-\u19D9\u1A00-\u1A1B\u1A20-\u1A5E\u1A60-\u1A7C\u1A7F-\u1A89\u1A90-\u1A99\u1AA7\u1B00-\u1B4B\u1B50-\u1B59\u1B6B-\u1B73\u1B80-\u1BF3\u1C00-\u1C37\u1C40-\u1C49\u1C4D-\u1C7D\u1CD0-\u1CD2\u1CD4-\u1CF6\u1D00-\u1DE6\u1DFC-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u200C\u200D\u203F\u2040\u2054\u2071\u207F\u2090-\u209C\u20D0-\u20DC\u20E1\u20E5-\u20F0\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D7F-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2DE0-\u2DFF\u2E2F\u300
 5-\u3007\u3021-\u302F\u3031-\u3035\u3038-\u303C\u3041-\u3096\u3099\u309A\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA62B\uA640-\uA66F\uA674-\uA67D\uA67F-\uA697\uA69F-\uA6F1\uA717-\uA71F\uA722-\uA788\uA78B-\uA78E\uA790-\uA793\uA7A0-\uA7AA\uA7F8-\uA827\uA840-\uA873\uA880-\uA8C4\uA8D0-\uA8D9\uA8E0-\uA8F7\uA8FB\uA900-\uA92D\uA930-\uA953\uA960-\uA97C\uA980-\uA9C0\uA9CF-\uA9D9\uAA00-\uAA36\uAA40-\uAA4D\uAA50-\uAA59\uAA60-\uAA76\uAA7A\uAA7B\uAA80-\uAAC2\uAADB-\uAADD\uAAE0-\uAAEF\uAAF2-\uAAF6\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uABC0-\uABEA\uABEC\uABED\uABF0-\uABF9\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE00-\uFE0F\uFE20-\uFE26\uFE33\uFE34\uFE4D-\uFE4F
 \uFE70-\uFE74\uFE76-\uFEFC\uFF10-\uFF19\uFF21-\uFF3A\uFF3F\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]')
+    };
+
+    // Ensure the condition is true, otherwise throw an error.
+    // This is only to have a better contract semantic, i.e. another safety net
+    // to catch a logic error. The condition shall be fulfilled in normal case.
+    // Do NOT use this to enforce a certain condition on any user input.
+
+    function assert(condition, message) {
+        /* istanbul ignore if */
+        if (!condition) {
+            throw new Error('ASSERT: ' + message);
+        }
+    }
+
+    function isDecimalDigit(ch) {
+        return (ch &gt;= 48 &amp;&amp; ch &lt;= 57);   // 0..9
+    }
+
+    function isHexDigit(ch) {
+        return '0123456789abcdefABCDEF'.indexOf(ch) &gt;= 0;
+    }
+
+    function isOctalDigit(ch) {
+        return '01234567'.indexOf(ch) &gt;= 0;
+    }
+
+
+    // 7.2 White Space
+
+    function isWhiteSpace(ch) {
+        return (ch === 0x20) || (ch === 0x09) || (ch === 0x0B) || (ch === 0x0C) || (ch === 0xA0) ||
+            (ch &gt;= 0x1680 &amp;&amp; [0x1680, 0x180E, 0x2000, 0x2001, 0x2002, 0x2003, 0x2004, 0x2005, 0x2006, 0x2007, 0x2008, 0x2009, 0x200A, 0x202F, 0x205F, 0x3000, 0xFEFF].indexOf(ch) &gt;= 0);
+    }
+
+    // 7.3 Line Terminators
+
+    function isLineTerminator(ch) {
+        return (ch === 0x0A) || (ch === 0x0D) || (ch === 0x2028) || (ch === 0x2029);
+    }
+
+    // 7.6 Identifier Names and Identifiers
+
+    function isIdentifierStart(ch) {
+        return (ch === 0x24) || (ch === 0x5F) ||  // $ (dollar) and _ (underscore)
+            (ch &gt;= 0x41 &amp;&amp; ch &lt;= 0x5A) ||         // A..Z
+            (ch &gt;= 0x61 &amp;&amp; ch &lt;= 0x7A) ||         // a..z
+            (ch === 0x5C) ||                      // \ (backslash)
+            ((ch &gt;= 0x80) &amp;&amp; Regex.NonAsciiIdentifierStart.test(String.fromCharCode(ch)));
+    }
+
+    function isIdentifierPart(ch) {
+        return (ch === 0x24) || (ch === 0x5F) ||  // $ (dollar) and _ (underscore)
+            (ch &gt;= 0x41 &amp;&amp; ch &lt;= 0x5A) ||         // A..Z
+            (ch &gt;= 0x61 &amp;&amp; ch &lt;= 0x7A) ||         // a..z
+            (ch &gt;= 0x30 &amp;&amp; ch &lt;= 0x39) ||         // 0..9
+            (ch === 0x5C) ||                      // \ (backslash)
+            ((ch &gt;= 0x80) &amp;&amp; Regex.NonAsciiIdentifierPart.test(String.fromCharCode(ch)));
+    }
+
+    // 7.6.1.2 Future Reserved Words
+
+    function isFutureReservedWord(id) {
+        switch (id) {
+        case 'class':
+        case 'enum':
+        case 'export':
+        case 'extends':
+        case 'import':
+        case 'super':
+            return true;
+        default:
+            return false;
+        }
+    }
+
+    function isStrictModeReservedWord(id) {
+        switch (id) {
+        case 'implements':
+        case 'interface':
+        case 'package':
+        case 'private':
+        case 'protected':
+        case 'public':
+        case 'static':
+        case 'yield':
+        case 'let':
+            return true;
+        default:
+            return false;
+        }
+    }
+
+    function isRestrictedWord(id) {
+        return id === 'eval' || id === 'arguments';
+    }
+
+    // 7.6.1.1 Keywords
+
+    function isKeyword(id) {
+        if (strict &amp;&amp; isStrictModeReservedWord(id)) {
+            return true;
+        }
+
+        // 'const' is specialized as Keyword in V8.
+        // 'yield' and 'let' are for compatiblity with SpiderMonkey and ES.next.
+        // Some others are from future reserved words.
+
+        switch (id.length) {
+        case 2:
+            return (id === 'if') || (id === 'in') || (id === 'do');
+        case 3:
+            return (id === 'var') || (id === 'for') || (id === 'new') ||
+                (id === 'try') || (id === 'let');
+        case 4:
+            return (id === 'this') || (id === 'else') || (id === 'case') ||
+                (id === 'void') || (id === 'with') || (id === 'enum');
+        case 5:
+            return (id === 'while') || (id === 'break') || (id === 'catch') ||
+                (id === 'throw') || (id === 'const') || (id === 'yield') ||
+                (id === 'class') || (id === 'super');
+        case 6:
+            return (id === 'return') || (id === 'typeof') || (id === 'delete') ||
+                (id === 'switch') || (id === 'export') || (id === 'import');
+        case 7:
+            return (id === 'default') || (id === 'finally') || (id === 'extends');
+        case 8:
+            return (id === 'function') || (id === 'continue') || (id === 'debugger');
+        case 10:
+            return (id === 'instanceof');
+        default:
+            return false;
+        }
+    }
+
+    // 7.4 Comments
+
+    function addComment(type, value, start, end, loc) {
+        var comment, attacher;
+
+        assert(typeof start === 'number', 'Comment must have valid position');
+
+        // Because the way the actual token is scanned, often the comments
+        // (if any) are skipped twice during the lexical analysis.
+        // Thus, we need to skip adding a comment if the comment array already
+        // handled it.
+        if (state.lastCommentStart &gt;= start) {
+            return;
+        }
+        state.lastCommentStart = start;
+
+        comment = {
+            type: type,
+            value: value
+        };
+        if (extra.range) {
+            comment.range = [start, end];
+        }
+        if (extra.loc) {
+            comment.loc = loc;
+        }
+        extra.comments.push(comment);
+        if (extra.attachComment) {
+            extra.leadingComments.push(comment);
+            extra.trailingComments.push(comment);
+        }
+    }
+
+    function skipSingleLineComment(offset) {
+        var start, loc, ch, comment;
+
+        start = index - offset;
+        loc = {
+            start: {
+                line: lineNumber,
+                column: index - lineStart - offset
+            }
+        };
+
+        while (index &lt; length) {
+            ch = source.charCodeAt(index);
+            ++index;
+            if (isLineTerminator(ch)) {
+                if (extra.comments) {
+                    comment = source.slice(start + offset, index - 1);
+                    loc.end = {
+                        line: lineNumber,
+                        column: index - lineStart - 1
+                    };
+                    addComment('Line', comment, start, index - 1, loc);
+                }
+                if (ch === 13 &amp;&amp; source.charCodeAt(index) === 10) {
+                    ++index;
+                }
+                ++lineNumber;
+                lineStart = index;
+                return;
+            }
+        }
+
+        if (extra.comments) {
+            comment = source.slice(start + offset, index);
+            loc.end = {
+                line: lineNumber,
+                column: index - lineStart
+            };
+            addComment('Line', comment, start, index, loc);
+        }
+    }
+
+    function skipMultiLineComment() {
+        var start, loc, ch, comment;
+
+        if (extra.comments) {
+            start = index - 2;
+            loc = {
+                start: {
+                    line: lineNumber,
+                    column: index - lineStart - 2
+                }
+            };
+        }
+
+        while (index &lt; length) {
+            ch = source.charCodeAt(index);
+            if (isLineTerminator(ch)) {
+                if (ch === 0x0D &amp;&amp; source.charCodeAt(index + 1) === 0x0A) {
+                    ++index;
+                }
+                ++lineNumber;
+                ++index;
+                lineStart = index;
+                if (index &gt;= length) {
+                    throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
+                }
+            } else if (ch === 0x2A) {
+                // Block comment ends with '*/'.
+                if (source.charCodeAt(index + 1) === 0x2F) {
+                    ++index;
+                    ++index;
+                    if (extra.comments) {
+                        comment = source.slice(start + 2, index - 2);
+                        loc.end = {
+                            line: lineNumber,
+                            column: index - lineStart
+                        };
+                        addComment('Block', comment, start, index, loc);
+                    }
+                    return;
+                }
+                ++index;
+            } else {
+                ++index;
+            }
+        }
+
+        throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
+    }
+
+    function skipComment() {
+        var ch, start;
+
+        start = (index === 0);
+        while (index &lt; length) {
+            ch = source.charCodeAt(index);
+
+            if (isWhiteSpace(ch)) {
+                ++index;
+            } else if (isLineTerminator(ch)) {
+                ++index;
+                if (ch === 0x0D &amp;&amp; source.charCodeAt(index) === 0x0A) {
+                    ++index;
+                }
+                ++lineNumber;
+                lineStart = index;
+                start = true;
+            } else if (ch === 0x2F) { // U+002F is '/'
+                ch = source.charCodeAt(index + 1);
+                if (ch === 0x2F) {
+                    ++index;
+                    ++index;
+                    skipSingleLineComment(2);
+                    start = true;
+                } else if (ch === 0x2A) {  // U+002A is '*'
+                    ++index;
+                    ++index;
+                    skipMultiLineComment();
+                } else {
+                    break;
+                }
+            } else if (start &amp;&amp; ch === 0x2D) { // U+002D is '-'
+                // U+003E is '&gt;'
+                if ((source.charCodeAt(index + 1) === 0x2D) &amp;&amp; (source.charCodeAt(index + 2) === 0x3E)) {
+                    // '--&gt;' is a single-line comment
+                    index += 3;
+                    skipSingleLineComment(3);
+                } else {
+                    break;
+                }
+            } else if (ch === 0x3C) { // U+003C is '&lt;'
+                if (source.slice(index + 1, index + 4) === '!--') {
+                    ++index; // `&lt;`
+                    ++index; // `!`
+                    ++index; // `-`
+                    ++index; // `-`
+                    skipSingleLineComment(4);
+                } else {
+                    break;
+                }
+            } else {
+                break;
+            }
+        }
+    }
+
+    function scanHexEscape(prefix) {
+        var i, len, ch, code = 0;
+
+        len = (prefix === 'u') ? 4 : 2;
+        for (i = 0; i &lt; len; ++i) {
+            if (index &lt; length &amp;&amp; isHexDigit(source[index])) {
+                ch = source[index++];
+                code = code * 16 + '0123456789abcdef'.indexOf(ch.toLowerCase());
+            } else {
+                return '';
+            }
+        }
+        return String.fromCharCode(code);
+    }
+
+    function getEscapedIdentifier() {
+        var ch, id;
+
+        ch = source.charCodeAt(index++);
+        id = String.fromCharCode(ch);
+
+        // '\u' (U+005C, U+0075) denotes an escaped character.
+        if (ch === 0x5C) {
+            if (source.charCodeAt(index) !== 0x75) {
+                throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
+            }
+            ++index;
+            ch = scanHexEscape('u');
+            if (!ch || ch === '\\' || !isIdentifierStart(ch.charCodeAt(0))) {
+                throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
+            }
+            id = ch;
+        }
+
+        while (index &lt; length) {
+            ch = source.charCodeAt(index);
+            if (!isIdentifierPart(ch)) {
+                break;
+            }
+            ++index;
+            id += String.fromCharCode(ch);
+
+            // '\u' (U+005C, U+0075) denotes an escaped character.
+            if (ch === 0x5C) {
+                id = id.substr(0, id.length - 1);
+                if (source.charCodeAt(index) !== 0x75) {
+                    throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
+                }
+                ++index;
+                ch = scanHexEscape('u');
+                if (!ch || ch === '\\' || !isIdentifierPart(ch.charCodeAt(0))) {
+                    throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
+                }
+                id += ch;
+            }
+        }
+
+        return id;
+    }
+
+    function getIdentifier() {
+        var start, ch;
+
+        start = index++;
+        while (index &lt; length) {
+            ch = source.charCodeAt(index);
+            if (ch === 0x5C) {
+                // Blackslash (U+005C) marks Unicode escape sequence.
+                index = start;
+                return getEscapedIdentifier();
+            }
+            if (isIdentifierPart(ch)) {
+                ++index;
+            } else {
+                break;
+            }
+        }
+
+        return source.slice(start, index);
+    }
+
+    function scanIdentifier() {
+        var start, id, type;
+
+        start = index;
+
+        // Backslash (U+005C) starts an escaped character.
+        id = (source.charCodeAt(index) === 0x5C) ? getEscapedIdentifier() : getIdentifier();
+
+        // There is no keyword or literal with only one character.
+        // Thus, it must be an identifier.
+        if (id.length === 1) {
+            type = Token.Identifier;
+        } else if (isKeyword(id)) {
+            type = Token.Keyword;
+        } else if (id === 'null') {
+            type = Token.NullLiteral;
+        } else if (id === 'true' || id === 'false') {
+            type = Token.BooleanLiteral;
+        } else {
+            type = Token.Identifier;
+        }
+
+        return {
+            type: type,
+            value: id,
+            lineNumber: lineNumber,
+            lineStart: lineStart,
+            start: start,
+            end: index
+        };
+    }
+
+
+    // 7.7 Punctuators
+
+    function scanPunctuator() {
+        var start = index,
+            code = source.charCodeAt(index),
+            code2,
+            ch1 = source[index],
+            ch2,
+            ch3,
+            ch4;
+
+        switch (code) {
+
+        // Check for most common single-character punctuators.
+        case 0x2E:  // . dot
+        case 0x28:  // ( open bracket
+        case 0x29:  // ) close bracket
+        case 0x3B:  // ; semicolon
+        case 0x2C:  // , comma
+        case 0x7B:  // { open curly brace
+        case 0x7D:  // } close curly brace
+        case 0x5B:  // [
+        case 0x5D:  // ]
+        case 0x3A:  // :
+        case 0x3F:  // ?
+        case 0x7E:  // ~
+            ++index;
+            if (extra.tokenize) {
+                if (code === 0x28) {
+                    extra.openParenToken = extra.tokens.length;
+                } else if (code === 0x7B) {
+                    extra.openCurlyToken = extra.tokens.length;
+                }
+            }
+            return {
+                type: Token.Punctuator,
+                value: String.fromCharCode(code),
+                lineNumber: lineNumber,
+                lineStart: lineStart,
+                start: start,
+                end: index
+            };
+
+        default:
+            code2 = source.charCodeAt(index + 1);
+
+            // '=' (U+003D) marks an assignment or comparison operator.
+            if (code2 === 0x3D) {
+                switch (code) {
+                case 0x2B:  // +
+                case 0x2D:  // -
+                case 0x2F:  // /
+                case 0x3C:  // &lt;
+                case 0x3E:  // &gt;
+                case 0x5E:  // ^
+                case 0x7C:  // |
+                case 0x25:  // %
+                case 0x26:  // &amp;
+                case 0x2A:  // *
+                    index += 2;
+                    return {
+                        type: Token.Punctuator,
+                        value: String.fromCharCode(code) + String.fromCharCode(code2),
+                        lineNumber: lineNumber,
+                        lineStart: lineStart,
+                        start: start,
+                        end: index
+                    };
+
+                case 0x21: // !
+                case 0x3D: // =
+                    index += 2;
+
+                    // !== and ===
+                    if (source.charCodeAt(index) === 0x3D) {
+                        ++index;
+                    }
+                    return {
+                        type: Token.Punctuator,
+                        value: source.slice(start, index),
+                        lineNumber: lineNumber,
+                        lineStart: lineStart,
+                        start: start,
+                        end: index
+                    };
+                }
+            }
+        }
+
+        // 4-character punctuator: &gt;&gt;&gt;=
+
+        ch4 = source.substr(index, 4);
+
+        if (ch4 === '&gt;&gt;&gt;=') {
+            index += 4;
+            return {
+                type: Token.Punctuator,
+                value: ch4,
+                lineNumber: lineNumber,
+                lineStart: lineStart,
+                start: start,
+                end: index
+            };
+        }
+
+        // 3-character punctuators: === !== &gt;&gt;&gt; &lt;&lt;= &gt;&gt;=
+
+        ch3 = ch4.substr(0, 3);
+
+        if (ch3 === '&gt;&gt;&gt;' || ch3 === '&lt;&lt;=' || ch3 === '&gt;&gt;=') {
+            index += 3;
+            return {
+                type: Token.Punctuator,
+                value: ch3,
+                lineNumber: lineNumber,
+                lineStart: lineStart,
+                start: start,
+                end: index
+            };
+        }
+
+        // Other 2-character punctuators: ++ -- &lt;&lt; &gt;&gt; &amp;&amp; ||
+        ch2 = ch3.substr(0, 2);
+
+        if ((ch1 === ch2[1] &amp;&amp; ('+-&lt;&gt;&amp;|'.indexOf(ch1) &gt;= 0)) || ch2 === '=&gt;') {
+            index += 2;
+            return {
+                type: Token.Punctuator,
+                value: ch2,
+                lineNumber: lineNumber,
+                lineStart: lineStart,
+                start: start,
+                end: index
+            };
+        }
+
+        // 1-character punctuators: &lt; &gt; = ! + - * % &amp; | ^ /
+        if ('&lt;&gt;=!+-*%&amp;|^/'.indexOf(ch1) &gt;= 0) {
+            ++index;
+            return {
+                type: Token.Punctuator,
+                value: ch1,
+                lineNumber: lineNumber,
+                lineStart: lineStart,
+                start: start,
+                end: index
+            };
+        }
+
+        throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
+    }
+
+    // 7.8.3 Numeric Literals
+
+    function scanHexLiteral(start) {
+        var number = '';
+
+        while (index &lt; length) {
+            if (!isHexDigit(source[index])) {
+                break;
+            }
+            number += source[index++];
+        }
+
+        if (number.length === 0) {
+            throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
+        }
+
+        if (isIdentifierStart(source.charCodeAt(index))) {
+            throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
+        }
+
+        return {
+            type: Token.NumericLiteral,
+            value: parseInt('0x' + number, 16),
+            lineNumber: lineNumber,
+            lineStart: lineStart,
+            start: start,
+            end: index
+        };
+    }
+
+    function scanOctalLiteral(start) {
+        var number = '0' + source[index++];
+        while (index &lt; length) {
+            if (!isOctalDigit(source[index])) {
+                break;
+            }
+            number += source[index++];
+        }
+
+        if (isIdentifierStart(source.charCodeAt(index)) || isDecimalDigit(source.charCodeAt(index))) {
+            throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
+        }
+
+        return {
+            type: Token.NumericLiteral,
+            value: parseInt(number, 8),
+            octal: true,
+            lineNumber: lineNumber,
+            lineStart: lineStart,
+            start: start,
+            end: index
+        };
+    }
+
+    function scanNumericLiteral() {
+        var number, start, ch;
+
+        ch = source[index];
+        assert(isDecimalDigit(ch.charCodeAt(0)) || (ch === '.'),
+            'Numeric literal must start with a decimal digit or a decimal point');
+
+        start = index;
+        number = '';
+        if (ch !== '.') {
+            number = source[index++];
+            ch = source[index];
+
+            // Hex number starts with '0x'.
+            // Octal number starts with '0'.
+            if (number === '0') {
+                if (ch === 'x' || ch === 'X') {
+                    ++index;
+                    return scanHexLiteral(start);
+                }
+                if (isOctalDigit(ch)) {
+                    return scanOctalLiteral(start);
+                }
+
+                // decimal number starts with '0' such as '09' is illegal.
+                if (ch &amp;&amp; isDecimalDigit(ch.charCodeAt(0))) {
+                    throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
+                }
+            }
+
+            while (isDecimalDigit(source.charCodeAt(index))) {
+                number += source[index++];
+            }
+            ch = source[index];
+        }
+
+        if (ch === '.') {
+            number += source[index++];
+            while (isDecimalDigit(source.charCodeAt(index))) {
+                number += source[index++];
+            }
+            ch = source[index];
+        }
+
+        if (ch === 'e' || ch === 'E') {
+            number += source[index++];
+
+            ch = source[index];
+            if (ch === '+' || ch === '-') {
+                number += source[index++];
+            }
+            if (isDecimalDigit(source.charCodeAt(index))) {
+                while (isDecimalDigit(source.charCodeAt(index))) {
+                    number += source[index++];
+                }
+            } else {
+                throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
+            }
+        }
+
+        if (isIdentifierStart(source.charCodeAt(index))) {
+            throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
+        }
+
+        return {
+            type: Token.NumericLiteral,
+            value: parseFloat(number),
+            lineNumber: lineNumber,
+            lineStart: lineStart,
+            start: start,
+            end: index
+        };
+    }
+
+    // 7.8.4 String Literals
+
+    function scanStringLiteral() {
+        var str = '', quote, start, ch, code, unescaped, restore, octal = false, startLineNumber, startLineStart;
+        startLineNumber = lineNumber;
+        startLineStart = lineStart;
+
+        quote = source[index];
+        assert((quote === '\'' || quote === '&quot;'),
+            'String literal must starts with a quote');
+
+        start = index;
+        ++index;
+
+        while (index &lt; length) {
+            ch = source[index++];
+
+            if (ch === quote) {
+                quote = '';
+                break;
+            } else if (ch === '\\') {
+                ch = source[index++];
+                if (!ch || !isLineTerminator(ch.charCodeAt(0))) {
+                    switch (ch) {
+                    case 'u':
+                    case 'x':
+                        restore = index;
+                        unescaped = scanHexEscape(ch);
+                        if (unescaped) {
+                            str += unescaped;
+                        } else {
+                            index = restore;
+                            str += ch;
+                        }
+                        break;
+                    case 'n':
+                        str += '\n';
+                        break;
+                    case 'r':
+                        str += '\r';
+                        break;
+                    case 't':
+                        str += '\t';
+                        break;
+                    case 'b':
+                        str += '\b';
+                        break;
+                    case 'f':
+                        str += '\f';
+                        break;
+                    case 'v':
+                        str += '\x0B';
+                        break;
+
+                    default:
+                        if (isOctalDigit(ch)) {
+                            code = '01234567'.indexOf(ch);
+
+                            // \0 is not octal escape sequence
+                            if (code !== 0) {
+                                octal = true;
+                            }
+
+                            if (index &lt; length &amp;&amp; isOctalDigit(source[index])) {
+                                octal = true;
+                                code = code * 8 + '01234567'.indexOf(source[index++]);
+
+                                // 3 digits are only allowed when string starts
+                                // with 0, 1, 2, 3
+                                if ('0123'.indexOf(ch) &gt;= 0 &amp;&amp;
+                                        index &lt; length &amp;&amp;
+                                        isOctalDigit(source[index])) {
+                                    code = code * 8 + '01234567'.indexOf(source[index++]);
+                                }
+                            }
+                            str += String.fromCharCode(code);
+                        } else {
+                            str += ch;
+                        }
+                        break;
+                    }
+                } else {
+                    ++lineNumber;
+                    if (ch ===  '\r' &amp;&amp; source[index] === '\n') {
+                        ++index;
+                    }
+                    lineStart = index;
+                }
+            } else if (isLineTerminator(ch.charCodeAt(0))) {
+                break;
+            } else {
+                str += ch;
+            }
+        }
+
+        if (quote !== '') {
+            throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
+        }
+
+        return {
+            type: Token.StringLiteral,
+            value: str,
+            octal: octal,
+            startLineNumber: startLineNumber,
+            startLineStart: startLineStart,
+            lineNumber: lineNumber,
+            lineStart: lineStart,
+            start: start,
+            end: index
+        };
+    }
+
+    function testRegExp(pattern, flags) {
+        var value;
+        try {
+            value = new RegExp(pattern, flags);
+        } catch (e) {
+            throwError({}, Messages.InvalidRegExp);
+        }
+        return value;
+    }
+
+    function scanRegExpBody() {
+        var ch, str, classMarker, terminated, body;
+
+        ch = source[index];
+        assert(ch === '/', 'Regular expression literal must start with a slash');
+        str = source[index++];
+
+        classMarker = false;
+        terminated = false;
+        while (index &lt; length) {
+            ch = source[index++];
+            str += ch;
+            if (ch === '\\') {
+                ch = source[index++];
+                // ECMA-262 7.8.5
+                if (isLineTerminator(ch.charCodeAt(0))) {
+                    throwError({}, Messages.UnterminatedRegExp);
+                }
+                str += ch;
+            } else if (isLineTerminator(ch.charCodeAt(0))) {
+                throwError({}, Messages.UnterminatedRegExp);
+            } else if (classMarker) {
+                if (ch === ']') {
+                    classMarker = false;
+                }
+            } else {
+                if (ch === '/') {
+                    terminated = true;
+                    break;
+                } else if (ch === '[') {
+                    classMarker = true;
+                }
+            }
+        }
+
+        if (!terminated) {
+            throwError({}, Messages.UnterminatedRegExp);
+        }
+
+        // Exclude leading and trailing slash.
+        body = str.substr(1, str.length - 2);
+        return {
+            value: body,
+            literal: str
+        };
+    }
+
+    function scanRegExpFlags() {
+        var ch, str, flags, restore;
+
+        str = '';
+        flags = '';
+        while (index &lt; length) {
+            ch = source[index];
+            if (!isIdentifierPart(ch.charCodeAt(0))) {
+                break;
+            }
+
+            ++index;
+            if (ch === '\\' &amp;&amp; index &lt; length) {
+                ch = source[index];
+                if (ch === 'u') {
+                    ++index;
+                    restore = index;
+                    ch = scanHexEscape('u');
+                    if (ch) {
+                        flags += ch;
+                        for (str += '\\u'; restore &lt; index; ++restore) {
+                            str += source[restore];
+                        }
+                    } else {
+                        index = restore;
+                        flags += 'u';
+                        str += '\\u';
+                    }
+                    throwErrorTolerant({}, Messages.UnexpectedToken, 'ILLEGAL');
+                } else {
+                    str += '\\';
+                    throwErrorTolerant({}, Messages.UnexpectedToken, 'ILLEGAL');
+                }
+            } else {
+                flags += ch;
+                str += ch;
+            }
+        }
+
+        return {
+            value: flags,
+            literal: str
+        };
+    }
+
+    function scanRegExp() {
+        var start, body, flags, pattern, value;
+
+        lookahead = null;
+        skipComment();
+        start = index;
+
+        body = scanRegExpBody();
+        flags = scanRegExpFlags();
+        value = testRegExp(body.value, flags.value);
+
+        if (extra.tokenize) {
+            return {
+                type: Token.RegularExpression,
+                value: value,
+                lineNumber: lineNumber,
+                lineStart: lineStart,
+                start: start,
+                end: index
+            };
+        }
+
+        return {
+            literal: body.literal + flags.literal,
+            value: value,
+            start: start,
+            end: index
+        };
+    }
+
+    function collectRegex() {
+        var pos, loc, regex, token;
+
+        skipComment();
+
+        pos = index;
+        loc = {
+            start: {
+                line: lineNumber,
+                column: index - lineStart
+            }
+        };
+
+        regex = scanRegExp();
+        loc.end = {
+            line: lineNumber,
+            column: index - lineStart
+        };
+
+        /* istanbul ignore next */
+        if (!extra.tokenize) {
+            // Pop the previous token, which is likely '/' or '/='
+            if (extra.tokens.length &gt; 0) {
+                token = extra.tokens[extra.tokens.length - 1];
+                if (token.range[0] === pos &amp;&amp; token.type === 'Punctuator') {
+                    if (token.value === '/' || token.value === '/=') {
+                        extra.tokens.pop();
+                    }
+                }
+            }
+
+            extra.tokens.push({
+                type: 'RegularExpression',
+                value: regex.literal,
+                range: [pos, index],
+                loc: loc
+            });
+        }
+
+        return regex;
+    }
+
+    function isIdentifierName(token) {
+        return token.type === Token.Identifier ||
+            token.type === Token.Keyword ||
+            token.type === Token.BooleanLiteral ||
+            token.type === Token.NullLiteral;
+    }
+
+    function advanceSlash() {
+        var prevToken,
+            checkToken;
+        // Using the following algorithm:
+        // https://github.com/mozilla/sweet.js/wiki/design
+        prevToken = extra.tokens[extra.tokens.length - 1];
+        if (!prevToken) {
+            // Nothing before that: it cannot be a division.
+            return collectRegex();
+        }
+        if (prevToken.type === 'Punctuator') {
+            if (prevToken.value === ']') {
+                return scanPunctuator();
+            }
+            if (prevToken.value === ')') {
+                checkToken = extra.tokens[extra.openParenToken - 1];
+                if (checkToken &amp;&amp;
+                        checkToken.type === 'Keyword' &amp;&amp;
+                        (checkToken.value === 'if' ||
+                         checkToken.value === 'while' ||
+                         checkToken.value === 'for' ||
+                         checkToken.value === 'with')) {
+                    return collectRegex();
+                }
+                return scanPunctuator();
+            }
+            if (prevToken.value === '}') {
+                // Dividing a function by anything makes little sense,
+                // but we have to check for that.
+                if (extra.tokens[extra.openCurlyToken - 3] &amp;&amp;
+                        extra.tokens[extra.openCurlyToken - 3].type === 'Keyword') {
+                    // Anonymous function.
+                    checkToken = extra.tokens[extra.openCurlyToken - 4];
+                    if (!checkToken) {
+                        return scanPunctuator();
+                    }
+                } else if (extra.tokens[extra.openCurlyToken - 4] &amp;&amp;
+                        extra.tokens[extra.openCurlyToken - 4].type === 'Keyword') {
+                    // Named function.
+                    checkToken = extra.tokens[extra.openCurlyToken - 5];
+                    if (!checkToken) {
+                        return collectRegex();
+                    }
+                } else {
+                    return scanPunctuator();
+                }
+                // checkToken determines whether the function is
+                // a declaration or an expression.
+                if (FnExprTokens.indexOf(checkToken.value) &gt;= 0) {
+                    // It is an expression.
+                    return scanPunctuator();
+                }
+                // It is a declaration.
+                return collectRegex();
+            }
+            return collectRegex();
+        }
+        if (prevToken.type === 'Keyword') {
+            return collectRegex();
+        }
+        return scanPunctuator();
+    }
+
+    function advance() {
+        var ch;
+
+        skipComment();
+
+        if (index &gt;= length) {
+            return {
+                type: Token.EOF,
+                lineNumber: lineNumber,
+                lineStart: lineStart,
+                start: index,
+                end: index
+            };
+        }
+
+        ch = source.charCodeAt(index);
+
+        if (isIdentifierStart(ch)) {
+            return scanIdentifier();
+        }
+
+        // Very common: ( and ) and ;
+        if (ch === 0x28 || ch === 0x29 || ch === 0x3B) {
+            return scanPunctuator();
+        }
+
+        // String literal starts with single quote (U+0027) or double quote (U+0022).
+        if (ch === 0x27 || ch === 0x22) {
+            return scanStringLiteral();
+        }
+
+
+        // Dot (.) U+002E can also start a floating-point number, hence the need
+        // to check the next character.
+        if (ch === 0x2E) {
+            if (isDecimalDigit(source.charCodeAt(index + 1))) {
+                return scanNumericLiteral();
+            }
+            return scanPunctuator();
+        }
+
+        if (isDecimalDigit(ch)) {
+            return scanNumericLiteral();
+        }
+
+        // Slash (/) U+002F can also start a regex.
+        if (extra.tokenize &amp;&amp; ch === 0x2F) {
+            return advanceSlash();
+        }
+
+        return scanPunctuator();
+    }
+
+    function collectToken() {
+        var loc, token, range, value;
+
+        skipComment();
+        loc = {
+            start: {
+                line: lineNumber,
+                column: index - lineStart
+            }
+        };
+
+        token = advance();
+        loc.end = {
+            line: lineNumber,
+            column: index - lineStart
+        };
+
+        if (token.type !== Token.EOF) {
+            value = source.slice(token.start, token.end);
+            extra.tokens.push({
+                type: TokenName[token.type],
+                value: value,
+                range: [token.start, token.end],
+                loc: loc
+            });
+        }
+
+        return token;
+    }
+
+    function lex() {
+        var token;
+
+        token = lookahead;
+        index = token.end;
+        lineNumber = token.lineNumber;
+        lineStart = token.lineStart;
+
+        lookahead = (typeof extra.tokens !== 'undefined') ? collectToken() : advance();
+
+        index = token.end;
+        lineNumber = token.lineNumber;
+        lineStart = token.lineStart;
+
+        return token;
+    }
+
+    function peek() {
+        var pos, line, start;
+
+        pos = index;
+        line = lineNumber;
+        start = lineStart;
+        lookahead = (typeof extra.tokens !== 'undefined') ? collectToken() : advance();
+        index = pos;
+        lineNumber = line;
+        lineStart = start;
+    }
+
+    function Position(line, column) {
+        this.line = line;
+        this.column = column;
+    }
+
+    function SourceLocation(startLine, startColumn, line, column) {
+        this.start = new Position(startLine, startColumn);
+        this.end = new Position(line, column);
+    }
+
+    SyntaxTreeDelegate = {
+
+        name: 'SyntaxTree',
+
+        processComment: function (node) {
+            var lastChild, trailingComments;
+
+            if (node.type === Syntax.Program) {
+                if (node.body.length &gt; 0) {
+                    return;
+                }
+            }
+
+            if (extra.trailingComments.length &gt; 0) {
+                if (extra.trailingComments[0].range[0] &gt;= node.range[1]) {
+                    trailingComments = extra.trailingComments;
+                    extra.trailingComments = [];
+                } else {
+                    extra.trailingComments.length = 0;
+                }
+            } else {
+                if (extra.bottomRightStack.length &gt; 0 &amp;&amp;
+                        extra.bottomRightStack[extra.bottomRightStack.length - 1].trailingComments &amp;&amp;
+                        extra.bottomRightStack[extra.bottomRightStack.length - 1].trailingComments[0].range[0] &gt;= node.range[1]) {
+                    trailingComments = extra.bottomRightStack[extra.bottomRightStack.length - 1].trailingComments;
+                    delete extra.bottomRightStack[extra.bottomRightStack.length - 1].trailingComments;
+                }
+            }
+
+            // Eating the stack.
+            while (extra.bottomRightStack.length &gt; 0 &amp;&amp; extra.bottomRightStack[extra.bottomRightStack.length - 1].range[0] &gt;= node.range[0]) {
+                lastChild = extra.bottomRightStack.pop();
+            }
+
+            if (lastChild) {
+                if (lastChild.leadingComments &amp;&amp; lastChild.leadingComments[lastChild.leadingComments.length - 1].range[1] &lt;= node.range[0]) {
+                    node.leadingComments = lastChild.leadingComments;
+                    delete lastChild.leadingComments;
+                }
+            } else if (extra.leadingComments.length &gt; 0 &amp;&amp; extra.leadingComments[extra.leadingComments.length - 1].range[1] &lt;= node.range[0]) {
+                node.leadingComments = extra.leadingComments;
+                extra.leadingComments = [];
+            }
+
+
+            if (trailingComments) {
+                node.trailingComments = trailingComments;
+            }
+
+            extra.bottomRightStack.push(node);
+        },
+
+        markEnd: function (node, startToken) {
+            if (extra.range) {
+                node.range = [startToken.start, index];
+            }
+            if (extra.loc) {
+                node.loc = new SourceLocation(
+                    startToken.startLineNumber === undefined ?  startToken.lineNumber : startToken.startLineNumber,
+                    startToken.start - (startToken.startLineStart === undefined ?  startToken.lineStart : startToken.startLineStart),
+                    lineNumber,
+                    index - lineStart
+                );
+                this.postProcess(node);
+            }
+
+            if (extra.attachComment) {
+                this.processComment(node);
+            }
+            return node;
+        },
+
+        postProcess: function (node) {
+            if (extra.source) {
+                node.loc.source = extra.source;
+            }
+            return node;
+        },
+
+        createArrayExpression: function (elements) {
+            return {
+                type: Syntax.ArrayExpression,
+                elements: elements
+            };
+        },
+
+        createAssignmentExpression: function (operator, left, right) {
+            return {
+                type: Syntax.AssignmentExpression,
+                operator: operator,
+                left: left,
+                right: right
+            };
+        },
+
+        createBinaryExpression: function (operator, left, right) {
+            var type = (operator === '||' || operator === '&amp;&amp;') ? Syntax.LogicalExpression :
+                        Syntax.BinaryExpression;
+            return {
+                type: type,
+                operator: operator,
+                left: left,
+                right: right
+            };
+        },
+
+        createBlockStatement: function (body) {
+            return {
+                type: Syntax.BlockStatement,
+                body: body
+            };
+        },
+
+        createBreakStatement: function (label) {
+            return {
+                type: Syntax.BreakStatement,
+                label: label
+            };
+        },
+
+        createCallExpression: function (callee, args) {
+            return {
+                type: Syntax.CallExpression,
+                callee: callee,
+                'arguments': args
+            };
+        },
+
+        createCatchClause: function (param, body) {
+            return {
+                type: Syntax.CatchClause,
+                param: param,
+                body: body
+            };
+        },
+
+        createConditionalExpression: function (test, consequent, alternate) {
+            return {
+                type: Syntax.ConditionalExpression,
+                test: test,
+                consequent: consequent,
+                alternate: alternate
+            };
+        },
+
+        createContinueStatement: function (label) {
+            return {
+                type: Syntax.ContinueStatement,
+                label: label
+            };
+        },
+
+        createDebuggerStatement: function () {
+            return {
+                type: Syntax.DebuggerStatement
+            };
+        },
+
+        createDoWhileStatement: function (body, test) {
+            return {
+                type: Syntax.DoWhileStatement,
+                body: body,
+                test: test
+            };
+        },
+
+        createEmptyStatement: function () {
+            return {
+                type: Syntax.EmptyStatement
+            };
+        },
+
+        createExpressionStatement: function (expression) {
+            return {
+                type: Syntax.ExpressionStatement,
+                expression: expression
+            };
+        },
+
+        createForStatement: function (init, test, update, body) {
+            return {
+                type: Syntax.ForStatement,
+                init: init,
+                test: test,
+                update: update,
+                body: body
+            };
+        },
+
+        createForInStatement: function (left, right, body) {
+            return {
+                type: Syntax.ForInStatement,
+                left: left,
+                right: right,
+                body: body,
+                each: false
+            };
+        },
+
+        createFunctionDeclaration: function (id, params, defaults, body) {
+            return {
+                type: Syntax.FunctionDeclaration,
+                id: id,
+                params: params,
+                defaults: defaults,
+                body: body,
+                rest: null,
+                generator: false,
+                expression: false
+            };
+        },
+
+        createFunctionExpression: function (id, params, defaults, body) {
+            return {
+                type: Syntax.FunctionExpression,
+                id: id,
+                params: params,
+                defaults: defaults,
+                body: body,
+                rest: null,
+                generator: false,
+                expression: false
+            };
+        },
+
+        createIdentifier: function (name) {
+            return {
+                type: Syntax.Identifier,
+                name: name
+            };
+        },
+
+        createIfStatement: function (test, consequent, alternate) {
+            return {
+                type: Syntax.IfStatement,
+                test: test,
+                consequent: consequent,
+                alternate: alternate
+            };
+        },
+
+        createLabeledStatement: function (label, body) {
+            return {
+                type: Syntax.LabeledStatement,
+                label: label,
+                body: body
+            };
+        },
+
+        createLiteral: function (token) {
+            return {
+                type: Syntax.Literal,
+                value: token.value,
+                raw: source.slice(token.start, token.end)
+            };
+        },
+
+        createMemberExpression: function (accessor, object, property) {
+            return {
+                type: Syntax.MemberExpression,
+                computed: accessor === '[',
+                object: object,
+                property: property
+            };
+        },
+
+        createNewExpression: function (callee, args) {
+            return {
+                type: Syntax.NewExpression,
+                callee: callee,
+                'arguments': args
+            };
+        },
+
+        createObjectExpression: function (properties) {
+            return {
+                type: Syntax.ObjectExpression,
+                properties: properties
+            };
+        },
+
+        createPostfixExpression: function (operator, argument) {
+            return {
+                type: Syntax.UpdateExpression,
+                operator: operator,
+                argument: argument,
+                prefix: false
+            };
+        },
+
+        createProgram: function (body) {
+            return {
+                type: Syntax.Program,
+                body: body
+            };
+        },
+
+        createProperty: function (kind, key, value) {
+            return {
+                type: Syntax.Property,
+                key: key,
+                value: value,
+                kind: kind
+            };
+        },
+
+        createReturnStatement: function (argument) {
+            return {
+                type: Syntax.ReturnStatement,
+                argument: argument
+            };
+        },
+
+        createSequenceExpression: function (expressions) {
+            return {
+                type: Syntax.SequenceExpression,
+                expressions: expressions
+            };
+        },
+
+        createSwitchCase: function (test, consequent) {
+            return {
+                type: Syntax.SwitchCase,
+                test: test,
+                consequent: consequent
+            };
+        },
+
+        createSwitchStatement: function (discriminant, cases) {
+            return {
+                type: Syntax.SwitchStatement,
+                discriminant: discriminant,
+                cases: cases
+            };
+        },
+
+        createThisExpression: function () {
+            return {
+                type: Syntax.ThisExpression
+            };
+        },
+
+        createThrowStatement: function (argument) {
+            return {
+                type: Syntax.ThrowStatement,
+                argument: argument
+            };
+        },
+
+        createTryStatement: function (block, guardedHandlers, handlers, finalizer) {
+            return {
+                type: Syntax.TryStatement,
+                block: block,
+                guardedHandlers: guardedHandlers,
+                handlers: handlers,
+                finalizer: finalizer
+            };
+        },
+
+        createUnaryExpression: function (operator, argument) {
+            if (operator === '++' || operator === '--') {
+                return {
+                    type: Syntax.UpdateExpression,
+                    operator: operator,
+                    argument: argument,
+                    prefix: true
+                };
+            }
+            return {
+                type: Syntax.UnaryExpression,
+                operator: operator,
+                argument: argument,
+                prefix: true
+            };
+        },
+
+        createVariableDeclaration: function (declarations, kind) {
+            return {
+                type: Syntax.VariableDeclaration,
+                declarations: declarations,
+                kind: kind
+            };
+        },
+
+        createVariableDeclarator: function (id, init) {
+            return {
+                type: Syntax.VariableDeclarator,
+                id: id,
+                init: init
+            };
+        },
+
+        createWhileStatement: function (test, body) {
+            return {
+                type: Syntax.WhileStatement,
+                test: test,
+                body: body
+            };
+        },
+
+        createWithStatement: function (object, body) {
+            return {
+                type: Syntax.WithStatement,
+                object: object,
+                body: body
+            };
+        }
+    };
+
+    // Return true if there is a line terminator before the next token.
+
+    function peekLineTerminator() {
+        var pos, line, start, found;
+
+        pos = index;
+        line = lineNumber;
+        start = lineStart;
+        skipComment();
+        found = lineNumber !== line;
+        index = pos;
+        lineNumber = line;
+        lineStart = start;
+
+        return found;
+    }
+
+    // Throw an exception
+
+    function throwError(token, messageFormat) {
+        var error,
+            args = Array.prototype.slice.call(arguments, 2),
+            msg = messageFormat.replace(
+                /%(\d)/g,
+                function (whole, index) {
+                    assert(index &lt; args.length, 'Message reference must be in range');
+                    return args[index];
+                }
+            );
+
+        if (typeof token.lineNumber === 'number') {
+            error = new Error('Line ' + token.lineNumber + ': ' + msg);
+            error.index = token.start;
+            error.lineNumber = token.lineNumber;
+            error.column = token.start - lineStart + 1;
+        } else {
+            error = new Error('Line ' + lineNumber + ': ' + msg);
+            error.index = index;
+            error.lineNumber = lineNumber;
+            error.column = index - lineStart + 1;
+        }
+
+        error.description = msg;
+        throw error;
+    }
+
+    function throwErrorTolerant() {
+        try {
+            throwError.apply(null, arguments);
+        } catch (e) {
+            if (extra.errors) {
+                extra.errors.push(e);
+            } else {
+                throw e;
+            }
+        }
+    }
+
+
+    // Throw an exception because of the token.
+
+    function throwUnexpected(token) {
+        if (token.type === Token.EOF) {
+            throwError(token, Messages.UnexpectedEOS);
+        }
+
+        if (token.type === Token.NumericLiteral) {
+            throwError(token, Messages.UnexpectedNumber);
+        }
+
+        if (token.type === Token.StringLiteral) {
+            throwError(token, Messages.UnexpectedString);
+        }
+
+        if (token.type === Token.Identifier) {
+            throwError(token, Messages.UnexpectedIdentifier);
+        }
+
+        if (token.type === Token.Keyword) {
+            if (isFutureReservedWord(token.value)) {
+                throwError(token, Messages.UnexpectedReserved);
+            } else if (strict &amp;&amp; isStrictModeReservedWord(token.value)) {
+                throwErrorTolerant(token, Messages.StrictReservedWord);
+                return;
+            }
+            throwError(token, Messages.UnexpectedToken, token.value);
+        }
+
+        // BooleanLiteral, NullLiteral, or Punctuator.
+        throwError(token, Messages.UnexpectedToken, token.value);
+    }
+
+    // Expect the next token to match the specified punctuator.
+    // If not, an exception will be thrown.
+
+    function expect(value) {
+        var token = lex();
+        if (token.type !== Token.Punctuator || token.value !== value) {
+            throwUnexpected(token);
+        }
+    }
+
+    // Expect the next token to match the specified keyword.
+    // If not, an exception will be thrown.
+
+    function expectKeyword(keyword) {
+        var token = lex();
+        if (token.type !== Token.Keyword || token.value !== keyword) {
+            throwUnexpected(token);
+        }
+    }
+
+    // Return true if the next token matches the specified punctuator.
+
+    function match(value) {
+        return lookahead.type === Token.Punctuator &amp;&amp; lookahead.value === value;
+    }
+
+    // Return true if the next token matches the specified keyword
+
+    function matchKeyword(keyword) {
+        return lookahead.type === Token.Keyword &amp;&amp; lookahead.value === keyword;
+    }
+
+    // Return true if the next token is an assignment operator
+
+    function matchAssign() {
+        var op;
+
+        if (lookahead.type !== Token.Punctuator) {
+            return false;
+        }
+        op = lookahead.value;
+        return op === '=' ||
+            op === '*=' ||
+            op === '/=' ||
+            op === '%=' ||
+            op === '+=' ||
+            op === '-=' ||
+            op === '&lt;&lt;=' ||
+            op === '&gt;&gt;=' ||
+            op === '&gt;&gt;&gt;=' ||
+            op === '&amp;=' ||
+            op === '^=' ||
+            op === '|=';
+    }
+
+    function consumeSemicolon() {
+        var line;
+
+        // Catch the very common case first: immediately a semicolon (U+003B).
+        if (source.charCodeAt(index) === 0x3B || match(';')) {
+            lex();
+            return;
+        }
+
+        line = lineNumber;
+        skipComment();
+        if (lineNumber !== line) {
+            return;
+        }
+
+        if (lookahead.type !== Token.EOF &amp;&amp; !match('}')) {
+            throwUnexpected(lookahead);
+        }
+    }
+
+    // Return true if provided expression is LeftHandSideExpression
+
+    function isLeftHandSide(expr) {
+        return expr.type === Syntax.Identifier || expr.type === Syntax.MemberExpression;
+    }
+
+    // 11.1.4 Array Initialiser
+
+    function parseArrayInitialiser() {
+        var elements = [], startToken;
+
+        startToken = lookahead;
+        expect('[');
+
+        while (!match(']')) {
+            if (match(',')) {
+                lex();
+                elements.push(null);
+            } else {
+                elements.push(parseAssignmentExpression());
+
+                if (!match(']')) {
+                    expect(',');
+                }
+            }
+        }
+
+        lex();
+
+        return delegate.markEnd(delegate.createArrayExpression(elements), startToken);
+    }
+
+    // 11.1.5 Object Initialiser
+
+    function parsePropertyFunction(param, first) {
+        var previousStrict, body, startToken;
+
+        previousStrict = strict;
+        startToken = lookahead;
+        body = parseFunctionSourceElements();
+        if (first &amp;&amp; strict &amp;&amp; isRestrictedWord(param[0].name)) {
+            throwErrorTolerant(first, Messages.StrictParamName);
+        }
+        strict = previousStrict;
+        return delegate.markEnd(delegate.createFunctionExpression(null, param, [], body), startToken);
+    }
+
+    function parseObjectPropertyKey() {
+        var token, startToken;
+
+        startToken = lookahead;
+        token = lex();
+
+        // Note: This function is called only from parseObjectProperty(), where
+        // EOF and Punctuator tokens are already filtered out.
+
+        if (token.type === Token.StringLiteral || token.type === Token.NumericLiteral) {
+            if (strict &amp;&amp; token.octal) {
+                throwErrorTolerant(token, Messages.StrictOctalLiteral);
+            }
+            return delegate.markEnd(delegate.createLiteral(token), startToken);
+        }
+
+        return delegate.markEnd(delegate.createIdentifier(token.value), startToken);
+    }
+
+    function parseObjectProperty() {
+        var token, key, id, value, param, startToken;
+
+        token = lookahead;
+        startToken = lookahead;
+
+        if (token.type === Token.Identifier) {
+
+            id = parseObjectPropertyKey();
+
+            // Property Assignment: Getter and Setter.
+
+            if (token.value === 'get' &amp;&amp; !match(':')) {
+                key = parseObjectPropertyKey();
+                expect('(');
+                expect(')');
+                value = parsePropertyFunction([]);
+                return delegate.markEnd(delegate.createProperty('get', key, value), startToken);
+            }
+            if (token.value === 'set' &amp;&amp; !match(':')) {
+                key = parseObjectPropertyKey();
+                expect('(');
+                token = lookahead;
+                if (token.type !== Token.Identifier) {
+                    expect(')');
+                    throwErrorTolerant(token, Messages.UnexpectedToken, token.value);
+                    value = parsePropertyFunction([]);
+                } else {
+                    param = [ parseVariableIdentifier() ];
+                    expect(')');
+                    value = parsePropertyFunction(param, token);
+                }
+                return delegate.markEnd(delegate.createProperty('set', key, value), startToken);
+            }
+            expect(':');
+            value = parseAssignmentExpression();
+            return delegate.markEnd(delegate.createProperty('init', id, value), startToken);
+        }
+        if (token.type === Token.EOF || token.type === Token.Punctuator) {
+            throwUnexpected(token);
+        } else {
+            key = parseObjectPropertyKey();
+            expect(':');
+            value = parseAssignmentExpression();
+            return delegate.markEnd(delegate.createProperty('init', key, value), startToken);
+        }
+    }
+
+    function parseObjectInitialiser() {
+        var properties = [], property, name, key, kind, map = {}, toString = String, startToken;
+
+        startToken = lookahead;
+
+        expect('{');
+
+        while (!match('}')) {
+            property = parseObjectProperty();
+
+            if (property.key.type === Syntax.Identifier) {
+                name = property.key.name;
+            } else {
+                name = toString(property.key.value);
+            }
+            kind = (property.kind === 'init') ? PropertyKind.Data : (property.kind === 'get') ? PropertyKind.Get : PropertyKind.Set;
+
+            key = '$' + name;
+            if (Object.prototype.hasOwnProperty.call(map, key)) {
+                if (map[key] === PropertyKind.Data) {
+                    if (strict &amp;&amp; kind === PropertyKind.Data) {
+                        throwErrorTolerant({}, Messages.StrictDuplicateProperty);
+                    } else if (kind !== PropertyKind.Data) {
+                        throwErrorTolerant({}, Messages.AccessorDataProperty);
+                    }
+                } else {
+                    if (kind === PropertyKind.Data) {
+                        throwErrorTolerant({}, Messages.AccessorDataProperty);
+                    } else if (map[key] &amp; kind) {
+                        throwErrorTolerant({}, Messages.AccessorGetSet);
+                    }
+                }
+                map[key] |= kind;
+            } else {
+                map[key] = kind;
+            }
+
+            properties.push(property);
+
+            if (!match('}')) {
+                expect(',');
+            }
+        }
+
+        expect('}');
+
+        return delegate.markEnd(delegate.createObjectExpression(properties), startToken);
+    }
+
+    // 11.1.6 The Grouping Operator
+
+    function parseGroupExpression() {
+        var expr;
+
+        expect('(');
+
+        expr = parseExpression();
+
+        expect(')');
+
+        return expr;
+    }
+
+
+    // 11.1 Primary Expressions
+
+    function parsePrimaryExpression() {
+        var type, token, expr, startToken;
+
+        if (match('(')) {
+            return parseGroupExpression();
+        }
+
+        if (match('[')) {
+            return parseArrayInitialiser();
+        }
+
+        if (match('{')) {
+            return parseObjectInitialiser();
+        }
+
+        type = lookahead.type;
+        startToken = lookahead;
+
+        if (type === Token.Identifier) {
+            expr =  delegate.createIdentifier(lex().value);
+        } else if (type === Token.StringLiteral || type === Token.NumericLiteral) {
+            if (strict &amp;&amp; lookahead.octal) {
+                throwErrorTolerant(lookahead, Messages.StrictOctalLiteral);
+            }
+            expr = delegate.createLiteral(lex());
+        } else if (type === Token.Keyword) {
+            if (matchKeyword('function')) {
+                return parseFunctionExpression();
+            }
+            if (matchKeyword('this')) {
+                lex();
+                expr = delegate.createThisExpression();
+            } else {
+                throwUnexpected(lex());
+            }
+        } else if (type === Token.BooleanLiteral) {
+            token = lex();
+            token.value = (token.value === 'true');
+            expr = delegate.createLiteral(token);
+        } else if (type === Token.NullLiteral) {
+            token = lex();
+            token.value = null;
+            expr = delegate.createLiteral(token);
+        } else if (match('/') || match('/=')) {
+            if (typeof extra.tokens !== 'undefined') {
+                expr = delegate.createLiteral(collectRegex());
+            } else {
+                expr = delegate.createLiteral(scanRegExp());
+            }
+            peek();
+        } else {
+            throwUnexpected(lex());
+        }
+
+        return delegate.markEnd(expr, startToken);
+    }
+
+    // 11.2 Left-Hand-Side Expressions
+
+    function parseArguments() {
+        var args = [];
+
+        expect('(');
+
+        if (!match(')')) {
+            while (index &lt; length) {
+                args.push(parseAssignmentExpression());
+                if (match(')')) {
+                    break;
+                }
+                expect(',');
+            }
+        }
+
+        expect(')');
+
+        return args;
+    }
+
+    function parseNonComputedProperty() {
+        var token, startToken;
+
+        startToken = lookahead;
+        token = lex();
+
+        if (!isIdentifierName(token)) {
+            throwUnexpected(token);
+        }
+
+        return delegate.markEnd(delegate.createIdentifier(token.value), startToken);
+    }
+
+    function parseNonComputedMember() {
+        expect('.');
+
+        return parseNonComputedProperty();
+    }
+
+    function parseComputedMember() {
+        var expr;
+
+        expect('[');
+
+        expr = parseExpression();
+
+        expect(']');
+
+        return expr;
+    }
+
+    function parseNewExpression() {
+        var callee, args, startToken;
+
+        startToken = lookahead;
+        expectKeyword('new');
+        callee = parseLeftHandSideExpression();
+        args = match('(') ? parseArguments() : [];
+
+        return delegate.markEnd(delegate.createNewExpression(callee, args), startToken);
+    }
+
+    function parseLeftHandSideExpressionAllowCall() {
+        var previousAllowIn, expr, args, property, startToken;
+
+        startToken = lookahead;
+
+        previousAllowIn = state.allowIn;
+        state.allowIn = true;
+        expr = matchKeyword('new') ? parseNewExpression() : parsePrimaryExpression();
+        state.allowIn = previousAllowIn;
+
+        for (;;) {
+            if (match('.')) {
+                property = parseNonComputedMember();
+                expr = delegate.createMemberExpression('.', expr, property);
+            } else if (match('(')) {
+                args = parseArguments();
+                expr = delegate.createCallExpression(expr, args);
+            } else if (match('[')) {
+                property = parseComputedMember();
+                expr = delegate.createMemberExpression('[', expr, property);
+            } else {
+                break;
+            }
+            delegate.markEnd(expr, startToken);
+        }
+
+        return expr;
+    }
+
+    function parseLeftHandSideExpression() {
+        var previousAllowIn, expr, property, startToken;
+
+        startToken = lookahead;
+
+        previousAllowIn = state.allowIn;
+        expr = matchKeyword('new') ? parseNewExpression() : parsePrimaryExpression();
+        state.allowIn = previousAllowIn;
+
+        while (match('.') || match('[')) {
+            if (match('[')) {
+                property = parseComputedMember();
+                expr = delegate.createMemberExpression('[', expr, property);
+            } else {
+                property = parseNonComputedMember();
+                expr = delegate.createMemberExpression('.', expr, property);
+            }
+            delegate.markEnd(expr, startToken);
+        }
+
+        return expr;
+    }
+
+    // 11.3 Postfix Expressions
+
+    function parsePostfixExpression() {
+        var expr, token, startToken = lookahead;
+
+        expr = parseLeftHandSideExpressionAllowCall();
+
+        if (lookahead.type === Token.Punctuator) {
+            if ((match('++') || match('--')) &amp;&amp; !peekLineTerminator()) {
+                // 11.3.1, 11.3.2
+                if (strict &amp;&amp; expr.type === Syntax.Identifier &amp;&amp; isRestrictedWord(expr.name)) {
+                    throwErrorTolerant({}, Messages.StrictLHSPostfix);
+                }
+
+                if (!isLeftHandSide(expr)) {
+                    throwErrorTolerant({}, Messages.InvalidLHSInAssignment);
+                }
+
+                token = lex();
+                expr = delegate.markEnd(delegate.createPostfixExpression(token.value, expr), startToken);
+            }
+        }
+
+        return expr;
+    }
+
+    // 11.4 Unary Operators
+
+    function parseUnaryExpression() {
+        var token, expr, startToken;
+
+        if (lookahead.type !== Token.Punctuator &amp;&amp; lookahead.type !== Token.Keyword) {
+            expr = parsePostfixExpression();
+        } else if (match('++') || match('--')) {
+            startToken = lookahead;
+            token = lex();
+            expr = parseUnaryExpression();
+            // 11.4.4, 11.4.5
+            if (strict &amp;&amp; expr.type === Syntax.Identifier &amp;&amp; isRestrictedWord(expr.name)) {
+                throwErrorTolerant({}, Messages.StrictLHSPrefix);
+            }
+
+            if (!isLeftHandSide(expr)) {
+                throwErrorTolerant({}, Messages.InvalidLHSInAssignment);
+            }
+
+            expr = delegate.createUnaryExpression(token.value, expr);
+            expr = delegate.markEnd(expr, startToken);
+        } else if (match('+') || match('-') || match('~') || match('!')) {
+            startToken = lookahead;
+            token = lex();
+            expr = parseUnaryExpression();
+            expr = delegate.createUnaryExpression(token.value, expr);
+            expr = delegate.markEnd(expr, startToken);
+        } else if (matchKeyword('delete') || matchKeyword('void') || matchKeyword('typeof')) {
+            startToken = lookahead;
+            token = lex();
+            expr = parseUnaryExpression();
+            expr = delegate.createUnaryExpression(token.value, expr);
+            expr = delegate.markEnd(expr, startToken);
+            if (strict &amp;&amp; expr.operator === 'delete' &amp;&amp; expr.argument.type === Syntax.Identifier) {
+                throwErrorTolerant({}, Messages.StrictDelete);
+            }
+        } else {
+            expr = parsePostfixExpression();
+        }
+
+        return expr;
+    }
+
+    function binaryPrecedence(token, allowIn) {
+        var prec = 0;
+
+        if (token.type !== Token.Punctuator &amp;&amp; token.type !== Token.Keyword) {
+            return 0;
+        }
+
+        switch (token.value) {
+        case '||':
+            prec = 1;
+            break;
+
+        case '&amp;&amp;':
+            prec = 2;
+            break;
+
+        case '|':
+            prec = 3;
+            break;
+
+        case '^':
+            prec = 4;
+            break;
+
+        case '&amp;':
+            prec = 5;
+            break;
+
+        case '==':
+        case '!=':
+        case '===':
+        case '!==':
+            prec = 6;
+            break;
+
+        case '&lt;':
+        case '&gt;':
+        case '&lt;=':
+        case '&gt;=':
+        case 'instanceof':
+            prec = 7;
+            break;
+
+        case 'in':
+            prec = allowIn ? 7 : 0;
+            break;
+
+        case '&lt;&lt;':
+        case '&gt;&gt;':
+        case '&gt;&gt;&gt;':
+            prec = 8;
+            break;
+
+        case '+':
+        case '-':
+            prec = 9;
+            break;
+
+        case '*':
+        case '/':
+        case '%':
+            prec = 11;
+            break;
+
+        default:
+            break;
+        }
+
+        return prec;
+    }
+
+    // 11.5 Multiplicative Operators
+    // 11.6 Additive Operators
+    // 11.7 Bitwise Shift Operators
+    // 11.8 Relational Operators
+    // 11.9 Equality Operators
+    // 11.10 Binary Bitwise Operators
+    // 11.11 Binary Logical Operators
+
+    function parseBinaryExpression() {
+        var marker, markers, expr, token, prec, stack, right, operator, left, i;
+
+        marker = lookahead;
+        left = parseUnaryExpression();
+
+        token = lookahead;
+        prec = binaryPrecedence(token, state.allowIn);
+        if (prec === 0) {
+            return left;
+        }
+        token.prec = prec;
+        lex();
+
+        markers = [marker, lookahead];
+        right = parseUnaryExpression();
+
+        stack = [left, token, right];
+
+        while ((prec = binaryPrecedence(lookahead, state.allowIn)) &gt; 0) {
+
+            // Reduce: make a binary expression from the three topmost entries.
+            while ((stack.length &gt; 2) &amp;&amp; (prec &lt;= stack[stack.length - 2].prec)) {
+                right = stack.pop();
+                operator = stack.pop().value;
+                left = stack.pop();
+                expr = delegate.createBinaryExpression(operator, left, right);
+                markers.pop();
+                marker = markers[markers.length - 1];
+                delegate.markEnd(expr, marker);
+                stack.push(expr);
+            }
+
+            // Shift.
+            token = lex();
+            token.prec = prec;
+            stack.push(token);
+            markers.push(lookahead);
+            expr = parseUnaryExpression();
+            stack.push(expr);
+        }
+
+        // Final reduce to clean-up the stack.
+        i = stack.length - 1;
+        expr = stack[i];
+        markers.pop();
+        while (i &gt; 1) {
+            expr = delegate.createBinaryExpression(stack[i - 1].value, stack[i - 2], expr);
+            i -= 2;
+            marker = markers.pop();
+            delegate.markEnd(expr, marker);
+        }
+
+        return expr;
+    }
+
+
+    // 11.12 Conditional Operator
+
+    function parseConditionalExpression() {
+        var expr, previousAllowIn, consequent, alternate, startToken;
+
+        startToken = lookahead;
+
+        expr = parseBinaryExpression();
+
+        if (match('?')) {
+            lex();
+            previousAllowIn = state.allowIn;
+            state.allowIn = true;
+            consequent = parseAssignmentExpression();
+            state.allowIn = previousAllowIn;
+            expect(':');
+            alternate = parseAssignmentExpression();
+
+            expr = delegate.createConditionalExpression(expr, consequent, alternate);
+            delegate.markEnd(expr, startToken);
+        }
+
+        return expr;
+    }
+
+    // 11.13 Assignment Operators
+
+    function parseAssignmentExpression() {
+        var token, left, right, node, startToken;
+
+        token = lookahead;
+        startToken = lookahead;
+
+        node = left = parseConditionalExpression();
+
+        if (matchAssign()) {
+            // LeftHandSideExpression
+            if (!isLeftHandSide(left)) {
+                throwErrorTolerant({}, Messages.InvalidLHSInAssignment);
+            }
+
+            // 11.13.1
+            if (strict &amp;&amp; left.type === Syntax.Identifier &amp;&amp; isRestrictedWord(left.name)) {
+                throwErrorTolerant(token, Messages.StrictLHSAssignment);
+            }
+
+            token = lex();
+            right = parseAssignmentExpression();
+            node = delegate.markEnd(delegate.createAssignmentExpression(token.value, left, right), startToken);
+        }
+
+        return node;
+    }
+
+    // 11.14 Comma Operator
+
+    function parseExpression() {
+        var expr, startToken = lookahead;
+
+        expr = parseAssignmentExpression();
+
+        if (match(',')) {
+            expr = delegate.createSequenceExpression([ expr ]);
+
+            while (index &lt; length) {
+                if (!match(',')) {
+                    break;
+                }
+                lex();
+                expr.expressions.push(parseAssignmentExpression());
+            }
+
+            delegate.markEnd(expr, startToken);
+        }
+
+        return expr;
+    }
+
+    // 12.1 Block
+
+    function parseStatementList() {
+        var list = [],
+            statement;
+
+        while (index &lt; length) {
+            if (match('}')) {
+                break;
+            }
+            statement = parseSourceElement();
+            if (typeof statement === 'undefined') {
+                break;
+            }
+            list.push(statement);
+        }
+
+        return list;
+    }
+
+    function parseBlock() {
+        var block, startToken;
+
+        startToken = lookahead;
+        expect('{');
+
+        block = parseStatementList();
+
+        expect('}');
+
+        return delegate.markEnd(delegate.createBlockStatement(block), startToken);
+    }
+
+    // 12.2 Variable Statement
+
+    function parseVariableIdentifier() {
+        var token, startToken;
+
+        startToken = lookahead;
+        token = lex();
+
+        if (token.type !== Token.Identifier) {
+            throwUnexpected(token);
+        }
+
+        return delegate.markEnd(delegate.createIdentifier(token.value), startToken);
+    }
+
+    function parseVariableDeclaration(kind) {
+        var init = null, id, startToken;
+
+        startToken = lookahead;
+        id = parseVariableIdentifier();
+
+        // 12.2.1
+        if (strict &amp;&amp; isRestrictedWord(id.name)) {
+            throwErrorTolerant({}, Messages.StrictVarName);
+        }
+
+        if (kind === 'const') {
+            expect('=');
+            init = parseAssignmentExpression();
+        } else if (match('=')) {
+            lex();
+            init = parseAssignmentExpression();
+        }
+
+        return delegate.markEnd(delegate.createVariableDeclarator(id, init), startToken);
+    }
+
+    function parseVariableDeclarationList(kind) {
+        var list = [];
+
+        do {
+            list.push(parseVariableDeclaration(kind));
+            if (!match(',')) {
+                break;
+            }
+            lex();
+        } while (index &lt; length);
+
+        return list;
+    }
+
+    function parseVariableStatement() {
+        var declarations;
+
+        expectKeyword('var');
+
+        declarations = parseVariableDeclarationList();
+
+        consumeSemicolon();
+
+        return delegate.createVariableDeclaration(declarations, 'var');
+    }
+
+    // kind may be `const` or `let`
+    // Both are experimental and not in the specification yet.
+    // see http://wiki.ecmascript.org/doku.php?id=harmony:const
+    // and http://wiki.ecmascript.org/doku.php?id=harmony:let
+    function parseConstLetDeclaration(kind) {
+        var declarations, startToken;
+
+        startToken = lookahead;
+
+        expectKeyword(kind);
+
+        declarations = parseVariableDeclarationList(kind);
+
+        consumeSemicolon();
+
+        return delegate.markEnd(delegate.createVariableDeclaration(declarations, kind), startToken);
+    }
+
+    // 12.3 Empty Statement
+
+    function parseEmptyStatement() {
+        expect(';');
+        return delegate.createEmptyStatement();
+    }
+
+    // 12.4 Expression Statement
+
+    function parseExpressionStatement() {
+        var expr = parseExpression();
+        consumeSemicolon();
+        return delegate.createExpressionStatement(expr);
+    }
+
+    // 12.5 If statement
+
+    function parseIfStatement() {
+        var test, consequent, alternate;
+
+        expectKeyword('if');
+
+        expect('(');
+
+        test = parseExpression();
+
+        expect(')');
+
+        consequent = parseStatement();
+
+        if (matchKeyword('else')) {
+            lex();
+            alternate = parseStatement();
+        } else {
+            alternate = null;
+        }
+
+        return delegate.createIfStatement(test, consequent, alternate);
+    }
+
+    // 12.6 Iteration Statements
+
+    function parseDoWhileStatement() {
+        var body, test, oldInIteration;
+
+        expectKeyword('do');
+
+        oldInIteration = state.inIteration;
+        state.inIteration = true;
+
+        body = parseStatement();
+
+        state.inIteration = oldInIteration;
+
+        expectKeyword('while');
+
+        expect('(');
+
+        test = parseExpression();
+
+        expect(')');
+
+        if (match(';')) {
+            lex();
+        }
+
+        return delegate.createDoWhileStatement(body, test);
+    }
+
+    function parseWhileStatement() {
+        var test, body, oldInIteration;
+
+        expectKeyword('while');
+
+        expect('(');
+
+        test = parseExpression();
+
+        expect(')');
+
+        oldInIteration = state.inIteration;
+        state.inIteration = true;
+
+        body = parseStatement();
+
+        state.inIteration = oldInIteration;
+
+        return delegate.createWhileStatement(test, body);
+    }
+
+    function parseForVariableDeclaration() {
+        var token, declarations, startToken;
+
+        startToken = lookahead;
+        token = lex();
+        declarations = parseVariableDeclarationList();
+
+        return delegate.markEnd(delegate.createVariableDeclaration(declarations, token.value), startToken);
+    }
+
+    function parseForStatement() {
+        var init, test, update, left, right, body, oldInIteration;
+
+        init = test = update = null;
+
+        expectKeyword('for');
+
+        expect('(');
+
+        if (match(';')) {
+            lex();
+        } else {
+            if (matchKeyword('var') || matchKeyword('let')) {
+                state.allowIn = false;
+                init = parseForVariableDeclaration();
+                state.allowIn = true;
+
+                if (init.declarations.length === 1 &amp;&amp; matchKeyword('in')) {
+                    lex();
+                    left = init;
+                    right = parseExpression();
+                    init = null;
+                }
+            } else {
+                state.allowIn = false;
+                init = parseExpression();
+                state.allowIn = true;
+
+                if (matchKeyword('in')) {
+                    // LeftHandSideExpression
+                    if (!isLeftHandSide(init)) {
+                        throwErrorTolerant({}, Messages.InvalidLHSInForIn);
+                    }
+
+                    lex();
+                    left = init;
+                    right = parseExpression();
+                    init = null;
+                }
+            }
+
+            if (typeof left === 'undefined') {
+                expect(';');
+            }
+        }
+
+        if (typeof left === 'undefined') {
+
+            if (!match(';')) {
+                test = parseExpression();
+            }
+            expect(';');
+
+            if (!match(')')) {
+                update = parseExpression();
+            }
+        }
+
+        expect(')');
+
+        oldInIteration = state.inIteration;
+        state.inIteration = true;
+
+        body = parseStatement();
+
+        state.inIteration = oldInIteration;
+
+        return (typeof left === 'undefined') ?
+                delegate.createForStatement(init, test, update, body) :
+                delegate.createForInStatement(left, right, body);
+    }
+
+    // 12.7 The continue statement
+
+    function parseContinueStatement() {
+        var label = null, key;
+
+        expectKeyword('continue');
+
+        // Optimize the most common form: 'continue;'.
+        if (source.charCodeAt(index) === 0x3B) {
+            lex();
+
+            if (!state.inIteration) {
+                throwError({}, Messages.IllegalContinue);
+            }
+
+            return delegate.createContinueStatement(null);
+        }
+
+        if (peekLineTerminator()) {
+            if (!state.inIteration) {
+                throwError({}, Messages.IllegalContinue);
+            }
+
+            return delegate.createContinueStatement(null);
+        }
+
+        if (lookahead.type === Token.Identifier) {
+            label = parseVariableIdentifier();
+
+            key = '$' + label.name;
+            if (!Object.prototype.hasOwnProperty.call(state.labelSet, key)) {
+                throwError({}, Messages.UnknownLabel, label.name);
+            }
+        }
+
+        consumeSemicolon();
+
+        if (label === null &amp;&amp; !state.inIteration) {
+            throwError({}, Messages.IllegalContinue);
+        }
+
+        return delegate.createContinueStatement(label);
+    }
+
+    // 12.8 The break statement
+
+    function parseBreakStatement() {
+        var label = null, key;
+
+        expectKeyword('break');
+
+        // Catch the very common case first: immediately a semicolon (U+003B).
+        if (source.charCodeAt(index) === 0x3B) {
+            lex();
+
+            if (!(state.inIteration || state.inSwitch)) {
+                throwError({}, Messages.IllegalBreak);
+            }
+
+            return delegate.createBreakStatement(null);
+        }
+
+        if (peekLineTerminator()) {
+            if (!(state.inIteration || state.inSwitch)) {
+                throwError({}, Messages.IllegalBreak);
+            }
+
+            return delegate.createBreakStatement(null);
+        }
+
+        if (lookahead.type === Token.Identifier) {
+            label = parseVariableIdentifier();
+
+            key = '$' + label.name;
+            if (!Object.prototype.hasOwnProperty.call(state.labelSet, key)) {
+                throwError({}, Messages.UnknownLabel, label.name);
+            }
+        }
+
+        consumeSemicolon();
+
+        if (label === null &amp;&amp; !(state.inIteration || state.inSwitch)) {
+            throwError({}, Messages.IllegalBreak);
+        }
+
+        return delegate.createBreakStatement(label);
+    }
+
+    // 12.9 The return statement
+
+    function parseReturnStatement() {
+        var argument = null;
+
+        expectKeyword('return');
+
+        if (!state.inFunctionBody) {
+            throwErrorTolerant({}, Messages.IllegalReturn);
+        }
+
+        // 'return' followed by a space and an identifier is very common.
+        if (source.charCodeAt(index) === 0x20) {
+            if (isIdentifierStart(source.charCodeAt(index + 1))) {
+                argument = parseExpression();
+                consumeSemicolon();
+                return delegate.createReturnStatement(argument);
+            }
+        }
+
+        if (peekLineTerminator()) {
+            return delegate.createReturnStatement(null);
+        }
+
+        if (!match(';')) {
+            if (!match('}') &amp;&amp; lookahead.type !== Token.EOF) {
+                argument = parseExpression();
+            }
+        }
+
+        consumeSemicolon();
+
+        return delegate.createReturnStatement(argument);
+    }
+
+    // 12.10 The with statement
+
+    function parseWithStatement() {
+        var object, body;
+
+        if (strict) {
+            // TODO(ikarienator): Should we update the test cases instead?
+            skipComment();
+            throwErrorTolerant({}, Messages.StrictModeWith);
+        }
+
+        expectKeyword('with');
+
+        expect('(');
+
+        object = parseExpression();
+
+        expect(')');
+
+        body = parseStatement();
+
+        return delegate.createWithStatement(object, body);
+    }
+
+    // 12.10 The swith statement
+
+    function parseSwitchCase() {
+        var test, consequent = [], statement, startToken;
+
+        startToken = lookahead;
+        if (matchKeyword('default')) {
+            lex();
+            test = null;
+        } else {
+            expectKeyword('case');
+            test = parseExpression();
+        }
+        expect(':');
+
+        while (index &lt; length) {
+            if (match('}') || matchKeyword('default') || matchKeyword('case')) {
+                break;
+            }
+            statement = parseStatement();
+            consequent.push(statement);
+        }
+
+        return delegate.markEnd(delegate.createSwitchCase(test, consequent), startToken);
+    }
+
+    function parseSwitchStatement() {
+        var discriminant, cases, clause, oldInSwitch, defaultFound;
+
+        expectKeyword('switch');
+
+        expect('(');
+
+        discriminant = parseExpression();
+
+        expect(')');
+
+        expect('{');
+
+        cases = [];
+
+        if (match('}')) {
+            lex();
+            return delegate.createSwitchStatement(discriminant, cases);
+        }
+
+        oldInSwitch = state.inSwitch;
+        state.inSwitch = true;
+        defaultFound = false;
+
+        while (index &lt; length) {
+            if (match('}')) {
+                break;
+            }
+            clause = parseSwitchCase();
+            if (clause.test === null) {
+                if (defaultFound) {
+                    throwError({}, Messages.MultipleDefaultsInSwitch);
+                }
+                defaultFound = true;
+            }
+            cases.push(clause);
+        }
+
+        state.inSwitch = oldInSwitch;
+
+        expect('}');
+
+        return delegate.createSwitchStatement(discriminant, cases);
+    }
+
+    // 12.13 The throw statement
+
+    function parseThrowStatement() {
+        var argument;
+
+        expectKeyword('throw');
+
+        if (peekLineTerminator()) {
+            throwError({}, Messages.NewlineAfterThrow);
+        }
+
+        argument = parseExpression();
+
+        consumeSemicolon();
+
+        return delegate.createThrowStatement(argument);
+    }
+
+    // 12.14 The try statement
+
+    function parseCatchClause() {
+        var param, body, startToken;
+
+        startToken = lookahead;
+        expectKeyword('catch');
+
+        expect('(');
+        if (match(')')) {
+            throwUnexpected(lookahead);
+        }
+
+        param = parseVariableIdentifier();
+        // 12.14.1
+        if (strict &amp;&amp; isRestrictedWord(param.name)) {
+            throwErrorTolerant({}, Messages.StrictCatchVariable);
+        }
+
+        expect(')');
+        body = parseBlock();
+        return delegate.markEnd(delegate.createCatchClause(param, body), startToken);
+    }
+
+    function parseTryStatement() {
+        var block, handlers = [], finalizer = null;
+
+        expectKeyword('try');
+
+        block = parseBlock();
+
+        if (matchKeyword('catch')) {
+            handlers.push(parseCatchClause());
+        }
+
+        if (matchKeyword('finally')) {
+            lex();
+            finalizer = parseBlock();
+        }
+
+        if (handlers.length === 0 &amp;&amp; !finalizer) {
+            throwError({}, Messages.NoCatchOrFinally);
+        }
+
+        return delegate.createTryStatement(block, [], handlers, finalizer);
+    }
+
+    // 12.15 The debugger statement
+
+    function parseDebuggerStatement() {
+        expectKeyword('debugger');
+
+        consumeSemicolon();
+
+        return delegate.createDebuggerStatement();
+    }
+
+    // 12 Statements
+
+    function parseStatement() {
+        var type = lookahead.type,
+            expr,
+            labeledBody,
+            key,
+            startToken;
+
+        if (type === Token.EOF) {
+            throwUnexpected(lookahead);
+        }
+
+        if (type === Token.Punctuator &amp;&amp; lookahead.value === '{') {
+            return parseBlock();
+        }
+
+        startToken = lookahead;
+
+        if (type === Token.Punctuator) {
+            switch (lookahead.value) {
+            case ';':
+                return delegate.markEnd(parseEmptyStatement(), startToken);
+            case '(':
+                return delegate.markEnd(parseExpressionStatement(), startToken);
+            default:
+                break;
+            }
+        }
+
+        if (type === Token.Keyword) {
+            switch (lookahead.value) {
+            case 'break':
+                return delegate.markEnd(parseBreakStatement(), startToken);
+            case 'continue':
+                return delegate.markEnd(parseContinueStatement(), startToken);
+            case 'debugger':
+                return delegate.markEnd(parseDebuggerStatement(), startToken);
+            case 'do':
+                return delegate.markEnd(parseDoWhileStatement(), startToken);
+            case 'for':
+                return delegate.markEnd(parseForStatement(), startToken);
+            case 'function':
+                return delegate.markEnd(parseFunctionDeclaration(), startToken);
+            case 'if':
+                return delegate.markEnd(parseIfStatement(), startToken);
+            case 'return':
+                return delegate.markEnd(parseReturnStatement(), startToken);
+            case 'switch':
+                return delegate.markEnd(parseSwitchStatement(), startToken);
+            case 'throw':
+                return delegate.markEnd(parseThrowStatement(), startToken);
+            case 'try':
+                return delegate.markEnd(parseTryStatement(), startToken);
+            case 'var':
+                return delegate.markEnd(parseVariableStatement(), startToken);
+            case 'while':
+                return delegate.markEnd(parseWhileStatement(), startToken);
+            case 'with':
+                return delegate.markEnd(parseWithStatement(), startToken);
+            default:
+                break;
+            }
+        }
+
+        expr = parseExpression();
+
+        // 12.12 Labelled Statements
+        if ((expr.type === Syntax.Identifier) &amp;&amp; match(':')) {
+            lex();
+
+            key = '$' + expr.name;
+            if (Object.prototype.hasOwnProperty.call(state.labelSet, key)) {
+                throwError({}, Messages.Redeclaration, 'Label', expr.name);
+            }
+
+            state.labelSet[key] = true;
+            labeledBody = parseStatement();
+            delete state.labelSet[key];
+            return delegate.markEnd(delegate.createLabeledStatement(expr, labeledBody), startToken);
+        }
+
+        consumeSemicolon();
+
+        return delegate.markEnd(delegate.createExpressionStatement(expr), startToken);
+    }
+
+    // 13 Function Definition
+
+    function parseFunctionSourceElements() {
+        var sourceElement, sourceElements = [], token, directive, firstRestricted,
+            oldLabelSet, oldInIteration, oldInSwitch, oldInFunctionBody, startToken;
+
+        startToken = lookahead;
+        expect('{');
+
+        while (index &lt; length) {
+            if (lookahead.type !== Token.StringLiteral) {
+                break;
+            }
+            token = lookahead;
+
+            sourceElement = parseSourceElement();
+            sourceElements.push(sourceElement);
+            if (sourceElement.expression.type !== Syntax.Literal) {
+                // this is not directive
+                break;
+            }
+            directive = source.slice(token.start + 1, token.end - 1);
+            if (directive === 'use strict') {
+                strict = true;
+                if (firstRestricted) {
+                    throwErrorTolerant(firstRestricted, Messages.StrictOctalLiteral);
+                }
+            } else {
+                if (!firstRestricted &amp;&amp; token.octal) {
+                    firstRestricted = token;
+                }
+            }
+        }
+
+        oldLabelSet = state.labelSet;
+        oldInIteration = state.inIteration;
+        oldInSwitch = state.inSwitch;
+        oldInFunctionBody = state.inFunctionBody;
+
+        state.labelSet = {};
+        state.inIteration = false;
+        state.inSwitch = false;
+        state.inFunctionBody = true;
+
+        while (index &lt; length) {
+            if (match('}')) {
+                break;
+            }
+            sourceElement = parseSourceElement();
+            if (typeof sourceElement === 'undefined') {
+                break;
+            }
+            sourceElements.push(sourceElement);
+        }
+
+        expect('}');
+
+        state.labelSet = oldLabelSet;
+        state.inIteration = oldInIteration;
+        state.inSwitch = oldInSwitch;
+        state.inFunctionBody = oldInFunctionBody;
+
+        return delegate.markEnd(delegate.createBlockStatement(sourceElements), startToken);
+    }
+
+    function parseParams(firstRestricted) {
+        var param, params = [], token, stricted, paramSet, key, message;
+        expect('(');
+
+        if (!match(')')) {
+            paramSet = {};
+            while (index &lt; length) {
+                token = lookahead;
+                param = parseVariableIdentifier();
+                key = '$' + token.value;
+                if (strict) {
+                    if (isRestrictedWord(token.value)) {
+                        stricted = token;
+                        message = Messages.StrictParamName;
+                    }
+                    if (Object.prototype.hasOwnProperty.call(paramSet, key)) {
+                        stricted = token;
+                        message = Messages.StrictParamDupe;
+                    }
+                } else if (!firstRestricted) {
+                    if (isRestrictedWord(token.value)) {
+                        firstRestricted = token;
+                        message = Messages.StrictParamName;
+                    } else if (isStrictModeReservedWord(token.value)) {
+                        firstRestricted = token;
+                        message = Messages.StrictReservedWord;
+                    } else if (Object.prototype.hasOwnProperty.call(paramSet, key)) {
+                        firstRestricted = token;
+                        message = Messages.StrictParamDupe;
+                    }
+                }
+                params.push(param);
+                paramSet[key] = true;
+                if (match(')')) {
+                    break;
+                }
+                expect(',');
+            }
+        }
+
+        expect(')');
+
+        return {
+            params: params,
+            stricted: stricted,
+            firstRestricted: firstRestricted,
+            message: message
+        };
+    }
+
+    function parseFunctionDeclaration() {
+        var id, params = [], body, token, stricted, tmp, firstRestricted, message, previousStrict, startToken;
+
+        startToken = lookahead;
+
+        expectKeyword('function');
+        token = lookahead;
+        id = parseVariableIdentifier();
+        if (strict) {
+            if (isRestrictedWord(token.value)) {
+                throwErrorTolerant(token, Messages.StrictFunctionName);
+            }
+        } else {
+            if (isRestrictedWord(token.value)) {
+                firstRestricted = token;
+                message = Messages.StrictFunctionName;
+            } else if (isStrictModeReservedWord(token.value)) {
+                firstRestricted = token;
+                message = Messages.StrictReservedWord;
+            }
+        }
+
+        tmp = parseParams(firstRestricted);
+        params = tmp.params;
+        stricted = tmp.stricted;
+        firstRestricted = tmp.firstRestricted;
+        if (tmp.message) {
+            message = tmp.message;
+        }
+
+        previousStrict = strict;
+        body = parseFunctionSourceElements();
+        if (strict &amp;&amp; firstRestricted) {
+            throwError(firstRestricted, message);
+        }
+        if (strict &amp;&amp; stricted) {
+            throwErrorTolerant(stricted, message);
+        }
+        strict = previousStrict;
+
+        return delegate.markEnd(delegate.createFunctionDeclaration(id, params, [], body), startToken);
+    }
+
+    function parseFunctionExpression() {
+        var token, id = null, stricted, firstRestricted, message, tmp, params = [], body, previousStrict, startToken;
+
+        startToken = lookahead;
+        expectKeyword('function');
+
+        if (!match('(')) {
+            token = lookahead;
+            id = parseVariableIdentifier();
+            if (strict) {
+                if (isRestrictedWord(token.value)) {
+                    throwErrorTolerant(token, Messages.StrictFunctionName);
+                }
+            } else {
+                if (isRestrictedWord(token.value)) {
+                    firstRestricted = token;
+                    message = Messages.StrictFunctionName;
+                } else if (isStrictModeReservedWord(token.value)) {
+                    firstRestricted = token;
+                    message = Messages.StrictReservedWord;
+                }
+            }
+        }
+
+        tmp = parseParams(firstRestricted);
+        params = tmp.params;
+        stricted = tmp.stricted;
+        firstRestricted = tmp.firstRestricted;
+        if (tmp.message) {
+            message = tmp.message;
+        }
+
+        previousStrict = strict;
+        body = parseFunctionSourceElements();
+        if (strict &amp;&amp; firstRestricted) {
+            throwError(firstRestricted, message);
+        }
+        if (strict &amp;&amp; stricted) {
+            throwErrorTolerant(stricted, message);
+        }
+        strict = previousStrict;
+
+        return delegate.markEnd(delegate.createFunctionExpression(id, params, [], body), startToken);
+    }
+
+    // 14 Program
+
+    function parseSourceElement() {
+        if (lookahead.type === Token.Keyword) {
+            switch (lookahead.value) {
+            case 'const':
+            case 'let':
+                return parseConstLetDeclaration(lookahead.value);
+            case 'function':
+                return parseFunctionDeclaration();
+            default:
+                return parseStatement();
+            }
+        }
+
+        if (lookahead.type !== Token.EOF) {
+            return parseStatement();
+        }
+    }
+
+    function parseSourceElements() {
+        var sourceElement, sourceElements = [], token, directive, firstRestricted;
+
+        while (index &lt; length) {
+            token = lookahead;
+            if (token.type !== Token.StringLiteral) {
+                break;
+            }
+
+            sourceElement = parseSourceElement();
+            sourceElements.push(sourceElement);
+            if (sourceElement.expression.type !== Syntax.Literal) {
+                // this is not directive
+                break;
+            }
+            directive = source.slice(token.start + 1, token.end - 1);
+            if (directive === 'use strict') {
+                strict = true;
+                if (firstRestricted) {
+                    throwErrorTolerant(firstRestricted, Messages.StrictOctalLiteral);
+                }
+            } else {
+                if (!firstRestricted &amp;&amp; token.octal) {
+                    firstRestricted = token;
+                }
+            }
+        }
+
+        while (index &lt; length) {
+            sourceElement = parseSourceElement();
+            /* istanbul ignore if */
+            if (typeof sourceElement === 'undefined') {
+                break;
+            }
+            sourceElements.push(sourceElement);
+        }
+        return sourceElements;
+    }
+
+    function parseProgram() {
+        var body, startToken;
+
+        skipComment();
+        peek();
+        startToken = lookahead;
+        strict = false;
+
+        body = parseSourceElements();
+        return delegate.markEnd(delegate.createProgram(body), startToken);
+    }
+
+    function filterTokenLocation() {
+        var i, entry, token, tokens = [];
+
+        for (i = 0; i &lt; extra.tokens.length; ++i) {
+            entry = extra.tokens[i];
+            token = {
+                type: entry.type,
+                value: entry.value
+            };
+            if (extra.range) {
+                token.range = entry.range;
+            }
+            if (extra.loc) {
+                token.loc = entry.loc;
+            }
+            tokens.push(token);
+        }
+
+        extra.tokens = tokens;
+    }
+
+    function tokenize(code, options) {
+        var toString,
+            token,
+            tokens;
+
+        toString = String;
+        if (typeof code !== 'string' &amp;&amp; !(code instanceof String)) {
+            code = toString(code);
+        }
+
+        delegate = SyntaxTreeDelegate;
+        source = code;
+        index = 0;
+        lineNumber = (source.length &gt; 0) ? 1 : 0;
+        lineStart = 0;
+        length = source.length;
+        lookahead = null;
+        state = {
+            allowIn: true,
+            labelSet: {},
+            inFunctionBody: false,
+            inIteration: false,
+            inSwitch: false,
+            lastCommentStart: -1
+        };
+
+        extra = {};
+
+        // Options matching.
+        options = options || {};
+
+        // Of course we collect tokens here.
+        options.tokens = true;
+        extra.tokens = [];
+        extra.tokenize = true;
+        // The following two fields are necessary to compute the Regex tokens.
+        extra.openParenToken = -1;
+        extra.openCurlyToken = -1;
+
+        extra.range = (typeof options.range === 'boolean') &amp;&amp; options.range;
+        extra.loc = (typeof options.loc === 'boolean') &amp;&amp; options.loc;
+
+        if (typeof options.comment === 'boolean' &amp;&amp; options.comment) {
+            extra.comments = [];
+        }
+        if (typeof options.tolerant === 'boolean' &amp;&amp; options.tolerant) {
+            extra.errors = [];
+        }
+
+        try {
+            peek();
+            if (lookahead.type === Token.EOF) {
+                return extra.tokens;
+            }
+
+            token = lex();
+            while (lookahead.type !== Token.EOF) {
+                try {
+                    token = lex();
+                } catch (lexError) {
+                    token = lookahead;
+                    if (extra.errors) {
+                        extra.errors.push(lexError);
+                        // We have to break on the first error
+                        // to avoid infinite loops.
+                        break;
+                    } else {
+                        throw lexError;
+                    }
+                }
+            }
+
+            filterTokenLocation();
+            tokens = extra.tokens;
+            if (typeof extra.comments !== 'undefined') {
+                tokens.comments = extra.comments;
+            }
+            if (typeof extra.errors !== 'undefined') {
+                tokens.errors = extra.errors;
+            }
+        } catch (e) {
+            throw e;
+        } finally {
+            extra = {};
+        }
+        return tokens;
+    }
+
+    function parse(code, options) {
+        var program, toString;
+
+        toString = String;
+        if (typeof code !== 'string' &amp;&amp; !(code instanceof String)) {
+            code = toString(code);
+        }
+
+        delegate = SyntaxTreeDelegate;
+        source = code;
+        index = 0;
+        lineNumber = (source.length &gt; 0) ? 1 : 0;
+        lineStart = 0;
+        length = source.length;
+        lookahead = null;
+        state = {
+            allowIn: true,
+            labelSet: {},
+            inFunctionBody: false,
+            inIteration: false,
+            inSwitch: false,
+            lastCommentStart: -1
+        };
+
+        extra = {};
+        if (typeof options !== 'undefined') {
+            extra.range = (typeof options.range === 'boolean') &amp;&amp; options.range;
+            extra.loc = (typeof options.loc === 'boolean') &amp;&amp; options.loc;
+            extra.attachComment = (typeof options.attachComment === 'boolean') &amp;&amp; options.attachComment;
+
+            if (extra.loc &amp;&amp; options.source !== null &amp;&amp; options.source !== undefined) {
+                extra.source = toString(options.source);
+            }
+
+            if (typeof options.tokens === 'boolean' &amp;&amp; options.tokens) {
+                extra.tokens = [];
+            }
+            if (typeof options.comment === 'boolean' &amp;&amp; options.comment) {
+                extra.comments = [];
+            }
+            if (typeof options.tolerant === 'boolean' &amp;&amp; options.tolerant) {
+                extra.errors = [];
+            }
+            if (extra.attachComment) {
+                extra.range = true;
+                extra.comments = [];
+                extra.bottomRightStack = [];
+                extra.trailingComments = [];
+                extra.leadingComments = [];
+            }
+        }
+
+        try {
+            program = parseProgram();
+            if (typeof extra.comments !== 'undefined') {
+                program.comments = extra.comments;
+            }
+            if (typeof extra.tokens !== 'undefined') {
+                filterTokenLocation();
+                program.tokens = extra.tokens;
+            }
+            if (typeof extra.errors !== 'undefined') {
+                program.errors = extra.errors;
+            }
+        } catch (e) {
+            throw e;
+        } finally {
+            extra = {};
+        }
+
+        return program;
+    }
+
+    // Sync with *.json manifests.
+    exports.version = '1.2.2';
+
+    exports.tokenize = tokenize;
+
+    exports.parse = parse;
+
+    // Deep copy.
+   /* istanbul ignore next */
+    exports.Syntax = (function () {
+        var name, types = {};
+
+        if (typeof Object.create === 'function') {
+            types = Object.create(null);
+        }
+
+        for (name in Syntax) {
+            if (Syntax.hasOwnProperty(name)) {
+                types[name] = Syntax[name];
+            }
+        }
+
+        if (typeof Object.freeze === 'function') {
+            Object.freeze(types);
+        }
+
+        return types;
+    }());
+
+}));
+/* vim: set sw=4 ts=4 et tw=80 : */
+
+},{}],7:[function(require,module,exports){
+/*
+  Copyright (C) 2012-2013 Yusuke Suzuki &lt;utatane.tea@gmail.com&gt;
+  Copyright (C) 2012 Ariya Hidayat &lt;ariya.hidayat@gmail.com&gt;
+
+  Redistribution and use in source and binary forms, with or without
+  modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in the
+      documentation and/or other materials provided with the distribution.
+
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS &quot;AS IS&quot;
+  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  ARE DISCLAIMED. IN NO EVENT SHALL &lt;COPYRIGHT HOLDER&gt; BE LIABLE FOR ANY
+  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/*jslint vars:false, bitwise:true*/
+/*jshint indent:4*/
+/*global exports:true, define:true*/
+(function (root, factory) {
+    'use strict';
+
+    // Universal Module Definition (UMD) to support AMD, CommonJS/Node.js,
+    // and plain browser loading,
+    if (typeof define === 'function' &amp;&amp; define.amd) {
+        define(['exports'], factory);
+    } else if (typeof exports !== 'undefined') {
+        factory(exports);
+    } else {
+        factory((root.estraverse = {}));
+    }
+}(this, function (exports) {
+    'use strict';
+
+    var Syntax,
+        isArray,
+        VisitorOption,
+        VisitorKeys,
+        BREAK,
+        SKIP;
+
+    Syntax = {
+        AssignmentExpression: 'AssignmentExpression',
+        ArrayExpression: 'ArrayExpression',
+        ArrayPattern: 'ArrayPattern',
+        ArrowFunctionExpression: 'ArrowFunctionExpression',
+        BlockStatement: 'BlockStatement',
+        BinaryExpression: 'BinaryExpression',
+        BreakStatement: 'BreakStatement',
+        CallExpression: 'CallExpression',
+        CatchClause: 'CatchClause',
+        ClassBody: 'ClassBody',
+        ClassDeclaration: 'ClassDeclaration',
+        ClassExpression: 'ClassExpression',
+        ConditionalExpression: 'ConditionalExpression',
+        ContinueStatement: 'ContinueStatement',
+        DebuggerStatement: 'DebuggerStatement',
+        DirectiveStatement: 'DirectiveStatement',
+        DoWhileStatement: 'DoWhileStatement',
+        EmptyStatement: 'EmptyStatement',
+        ExpressionStatement: 'ExpressionStatement',
+        ForStatement: 'ForStatement',
+        ForInStatement: 'ForInStatement',
+        FunctionDeclaration: 'FunctionDeclaration',
+        FunctionExpression: 'FunctionExpression',
+        Identifier: 'Identifier',
+        IfStatement: 'IfStatement',
+        Literal: 'Literal',
+        LabeledStatement: 'LabeledStatement',
+        LogicalExpression: 'LogicalExpression',
+        MemberExpression: 'MemberExpression',
+        MethodDefinition: 'MethodDefinition',
+        NewExpression: 'NewExpression',
+        ObjectExpression: 'ObjectExpression',
+        ObjectPattern: 'ObjectPattern',
+        Program: 'Program',
+        Property: 'Property',
+        ReturnStatement: 'ReturnStatement',
+        SequenceExpression: 'SequenceExpression',
+        SwitchStatement: 'SwitchStatement',
+        SwitchCase: 'SwitchCase',
+        ThisExpression: 'ThisExpression',
+        ThrowStatement: 'ThrowStatement',
+        TryStatement: 'TryStatement',
+        UnaryExpression: 'UnaryExpression',
+        UpdateExpression: 'UpdateExpression',
+        VariableDeclaration: 'VariableDeclaration',
+        VariableDeclarator: 'VariableDeclarator',
+        WhileStatement: 'WhileStatement',
+        WithStatement: 'WithStatement',
+        YieldExpression: 'YieldExpression'
+    };
+
+    function ignoreJSHintError() { }
+
+    isArray = Array.isArray;
+    if (!isArray) {
+        isArray = function isArray(array) {
+            return Object.prototype.toString.call(array) === '[object Array]';
+        };
+    }
+
+    function deepCopy(obj) {
+        var ret = {}, key, val;
+        for (key in obj) {
+            if (obj.hasOwnProperty(key)) {
+                val = obj[key];
+                if (typeof val === 'object' &amp;&amp; val !== null) {
+                    ret[key] = deepCopy(val);
+                } else {
+                    ret[key] = val;
+                }
+            }
+        }
+        return ret;
+    }
+
+    function shallowCopy(obj) {
+        var ret = {}, key;
+        for (key in obj) {
+            if (obj.hasOwnProperty(key)) {
+                ret[key] = obj[key];
+            }
+        }
+        return ret;
+    }
+    ignoreJSHintError(shallowCopy);
+
+    // based on LLVM libc++ upper_bound / lower_bound
+    // MIT License
+
+    function upperBound(array, func) {
+        var diff, len, i, current;
+
+        len = array.length;
+        i = 0;
+
+        while (len) {
+            diff = len &gt;&gt;&gt; 1;
+            current = i + diff;
+            if (func(array[current])) {
+                len = diff;
+            } else {
+                i = current + 1;
+                len -= diff + 1;
+            }
+        }
+        return i;
+    }
+
+    function lowerBound(array, func) {
+        var diff, len, i, current;
+
+        len = array.length;
+        i = 0;
+
+        while (len) {
+            diff = len &gt;&gt;&gt; 1;
+            current = i + diff;
+            if (func(array[current])) {
+                i = current + 1;
+                len -= diff + 1;
+            } else {
+                len = diff;
+            }
+        }
+        return i;
+    }
+    ignoreJSHintError(lowerBound);
+
+    VisitorKeys = {
+        AssignmentExpression: ['left', 'right'],
+        ArrayExpression: ['elements'],
+        ArrayPattern: ['elements'],
+        ArrowFunctionExpression: ['params', 'defaults', 'rest', 'body'],
+        BlockStatement: ['body'],
+        BinaryExpression: ['left', 'right'],
+        BreakStatement: ['label'],
+        CallExpression: ['callee', 'arguments'],
+        CatchClause: ['param', 'body'],
+        ClassBody: ['body'],
+        ClassDeclaration: ['id', 'body', 'superClass'],
+        ClassExpression: ['id', 'body', 'superClass'],
+        ConditionalExpression: ['test', 'consequent', 'alternate'],
+        ContinueStatement: ['label'],
+        DebuggerStatement: [],
+        DirectiveStatement: [],
+        DoWhileStatement: ['body', 'test'],
+        EmptyStatement: [],
+        ExpressionStatement: ['expression'],
+        ForStatement: ['init', 'test', 'update', 'body'],
+        ForInStatement: ['left', 'right', 'body'],
+        ForOfStatement: ['left', 'right', 'body'],
+        FunctionDeclaration: ['id', 'params', 'defaults', 'rest', 'body'],
+        FunctionExpression: ['id', 'params', 'defaults', 'rest', 'body'],
+        Identifier: [],
+        IfStatement: ['test', 'consequent', 'alternate'],
+        Literal: [],
+        LabeledStatement: ['label', 'body'],
+        LogicalExpression: ['left', 'right'],
+        MemberExpression: ['object', 'property'],
+        MethodDefinition: ['key', 'value'],
+        NewExpression: ['callee', 'arguments'],
+        ObjectExpression: ['properties'],
+        ObjectPattern: ['properties'],
+        Program: ['body'],
+        Property: ['key', 'value'],
+        ReturnStatement: ['argument'],
+        SequenceExpression: ['expressions'],
+        SwitchStatement: ['discriminant', 'cases'],
+        SwitchCase: ['test', 'consequent'],
+        ThisExpression: [],
+        ThrowStatement: ['argument'],
+        TryStatement: ['block', 'handlers', 'handler', 'guardedHandlers', 'finalizer'],
+        UnaryExpression: ['argument'],
+        UpdateExpression: ['argument'],
+        VariableDeclaration: ['declarations'],
+        VariableDeclarator: ['id', 'init'],
+        WhileStatement: ['test', 'body'],
+        WithStatement: ['object', 'body'],
+        YieldExpression: ['argument']
+    };
+
+    // unique id
+    BREAK = {};
+    SKIP = {};
+
+    VisitorOption = {
+        Break: BREAK,
+        Skip: SKIP
+    };
+
+    function Reference(parent, key) {
+        this.parent = parent;
+        this.key = key;
+    }
+
+    Reference.prototype.replace = function replace(node) {
+        this.parent[this.key] = node;
+    };
+
+    function Element(node, path, wrap, ref) {
+        this.node = node;
+        this.path = path;
+        this.wrap = wrap;
+        this.ref = ref;
+    }
+
+    function Controller() { }
+
+    // API:
+    // return property path array from root to current node
+    Controller.prototype.path = function path() {
+        var i, iz, j, jz, result, element;
+
+        function addToPath(result, path) {
+            if (isArray(path)) {
+                for (j = 0, jz = path.length; j &lt; jz; ++j) {
+                    result.push(path[j]);
+                }
+            } else {
+                result.push(path);
+            }
+        }
+
+        // root node
+        if (!this.__current.path) {
+            return null;
+        }
+
+        // first node is sentinel, second node is root element
+        result = [];
+        for (i = 2, iz = this.__leavelist.length; i &lt; iz; ++i) {
+            element = this.__leavelist[i];
+            addToPath(result, element.path);
+        }
+        addToPath(result, this.__current.path);
+        return result;
+    };
+
+    // API:
+    // return array of parent elements
+    Controller.prototype.parents = function parents() {
+        var i, iz, result;
+
+        // first node is sentinel
+        result = [];
+        for (i = 1, iz = this.__leavelist.length; i &lt; iz; ++i) {
+            result.push(this.__leavelist[i].node);
+        }
+
+        return result;
+    };
+
+    // API:
+    // return current node
+    Controller.prototype.current = function current() {
+        return this.__current.node;
+    };
+
+    Controller.prototype.__execute = function __execute(callback, element) {
+        var previous, result;
+
+        result = undefined;
+
+        previous  = this.__current;
+        this.__current = element;
+        this.__state = null;
+        if (callback) {
+            result = callback.call(this, element.node, this.__leavelist[this.__leavelist.length - 1].node);
+        }
+        this.__current = previous;
+
+        return result;
+    };
+
+    // API:
+    // notify control skip / break
+    Controller.prototype.notify = function notify(flag) {
+        this.__state = flag;
+    };
+
+    // API:
+    // skip child nodes of current node
+    Controller.prototype.skip = function () {
+        this.notify(SKIP);
+    };
+
+    // API:
+    // break traversals
+    Controller.prototype['break'] = function () {
+        this.notify(BREAK);
+    };
+
+    Controller.prototype.__initialize = function(root, visitor) {
+        this.visitor = visitor;
+        this.root = root;
+        this.__worklist = [];
+        this.__leavelist = [];
+        this.__current = null;
+        this.__state = null;
+    };
+
+    Controller.prototype.traverse = function traverse(root, visitor) {
+        var worklist,
+            leavelist,
+            element,
+            node,
+            nodeType,
+            ret,
+            key,
+            current,
+            current2,
+            candidates,
+            candidate,
+            sentinel;
+
+        this.__initialize(root, visitor);
+
+        sentinel = {};
+
+        // reference
+        worklist = this.__worklist;
+        leavelist = this.__leavelist;
+
+        // initialize
+        worklist.push(new Element(root, null, null, null));
+        leavelist.push(new Element(null, null, null, null));
+
+        while (worklist.length) {
+            element = worklist.pop();
+
+            if (element === sentinel) {
+                element = leavelist.pop();
+
+                ret = this.__execute(visitor.leave, element);
+
+                if (this.__state === BREAK || ret === BREAK) {
+                    return;
+                }
+                continue;
+            }
+
+            if (element.node) {
+
+                ret = this.__execute(visitor.enter, element);
+
+                if (this.__state === BREAK || ret === BREAK) {
+                    return;
+                }
+
+                worklist.push(sentinel);
+                leavelist.push(element);
+
+                if (this.__state === SKIP || ret === SKIP) {
+                    continue;
+                }
+
+                node = element.node;
+                nodeType = element.wrap || node.type;
+                candidates = VisitorKeys[nodeType];
+
+                current = candidates.length;
+                while ((current -= 1) &gt;= 0) {
+                    key = candidates[current];
+                    candidate = node[key];
+                    if (!candidate) {
+                        continue;
+                    }
+
+                    if (!isArray(candidate)) {
+                        worklist.push(new Element(candidate, key, null, null));
+                        continue;
+                    }
+
+                    current2 = candidate.length;
+                    while ((current2 -= 1) &gt;= 0) {
+                        if (!candidate[current2]) {
+                            continue;
+                        }
+                        if ((nodeType === Syntax.ObjectExpression || nodeType === Syntax.ObjectPattern) &amp;&amp; 'properties' === candidates[current]) {
+                            element = new Element(candidate[current2], [key, current2], 'Property', null);
+                        } else {
+                            element = new Element(candidate[current2], [key, current2], null, null);
+                        }
+                        worklist.push(element);
+                    }
+                }
+            }
+        }
+    };
+
+    Controller.prototype.replace = function replace(root, visitor) {
+        var worklist,
+            leavelist,
+            node,
+            nodeType,
+            target,
+            element,
+            current,
+            current2,
+            candidates,
+            candidate,
+            sentinel,
+            outer,
+            key;
+
+        this.__initialize(root, visitor);
+
+        sentinel = {};
+
+        // reference
+        worklist = this.__worklist;
+        leavelist = this.__leavelist;
+
+        // initialize
+        outer = {
+            root: root
+        };
+        element = new Element(root, null, null, new Reference(outer, 'root'));
+        worklist.push(element);
+        leavelist.push(element);
+
+        while (worklist.length) {
+            element = worklist.pop();
+
+            if (element === sentinel) {
+                element = leavelist.pop();
+
+                target = this.__execute(visitor.leave, element);
+
+                // node may be replaced with null,
+                // so distinguish between undefined and null in this place
+                if (target !== undefined &amp;&amp; target !== BREAK &amp;&amp; target !== SKIP) {
+                    // replace
+                    element.ref.replace(target);
+                }
+
+                if (this.__state === BREAK || target === BREAK) {
+                    return outer.root;
+                }
+                continue;
+            }
+
+            target = this.__execute(visitor.enter, element);
+
+            // node may be replaced with null,
+            // so distinguish between undefined and null in this place
+            if (target !== undefined &amp;&amp; target !== BREAK &amp;&amp; target !== SKIP) {
+                // replace
+                element.ref.replace(target);
+                element.node = target;
+            }
+
+            if (this.__state === BREAK || target === BREAK) {
+                return outer.root;
+            }
+
+            // node may be null
+            node = element.node;
+            if (!node) {
+                continue;
+            }
+
+            worklist.push(sentinel);
+            leavelist.push(element);
+
+            if (this.__state === SKIP || target === SKIP) {
+                continue;
+            }
+
+            nodeType = element.wrap || node.type;
+            candidates = VisitorKeys[nodeType];
+
+            current = candidates.length;
+            while ((current -= 1) &gt;= 0) {
+                key = candidates[current];
+                candidate = node[key];
+                if (!candidate) {
+                    continue;
+                }
+
+                if (!isArray(candidate)) {
+                    worklist.push(new Element(candidate, key, null, new Reference(node, key)));
+                    continue;
+                }
+
+                current2 = candidate.length;
+                while ((current2 -= 1) &gt;= 0) {
+                    if (!candidate[current2]) {
+                        continue;
+                    }
+                    if (nodeType === Syntax.ObjectExpression &amp;&amp; 'properties' === candidates[current]) {
+                        element = new Element(candidate[current2], [key, current2], 'Property', new Reference(candidate, current2));
+                    } else {
+                        element = new Element(candidate[current2], [key, current2], null, new Reference(candidate, current2));
+                    }
+                    worklist.push(element);
+                }
+            }
+        }
+
+        return outer.root;
+    };
+
+    function traverse(root, visitor) {
+        var controller = new Controller();
+        return controller.traverse(root, visitor);
+    }
+
+    function replace(root, visitor) {
+        var controller = new Controller();
+        return controller.replace(root, visitor);
+    }
+
+    function extendCommentRange(comment, tokens) {
+        var target;
+
+        target = upperBound(tokens, function search(token) {
+            return token.range[0] &gt; comment.range[0];
+        });
+
+        comment.extendedRange = [comment.range[0], comment.range[1]];
+
+        if (target !== tokens.length) {
+            comment.extendedRange[1] = tokens[target].range[0];
+        }
+
+        target -= 1;
+        if (target &gt;= 0) {
+            comment.extendedRange[0] = tokens[target].range[1];
+        }
+
+        return comment;
+    }
+
+    function attachComments(tree, providedComments, tokens) {
+        // At first, we should calculate extended comment ranges.
+        var comments = [], comment, len, i, cursor;
+
+        if (!tree.range) {
+            throw new Error('attachComments needs range information');
+        }
+
+        // tokens array is empty, we attach comments to tree as 'leadingComments'
+        if (!tokens.length) {
+            if (providedComments.length) {
+                for (i = 0, len = providedComments.length; i &lt; len; i += 1) {
+                    comment = deepCopy(providedComments[i]);
+                    comment.extendedRange = [0, tree.range[0]];
+                    comments.push(comment);
+                }
+                tree.leadingComments = comments;
+            }
+            return tree;
+        }
+
+        for (i = 0, len = providedComments.length; i &lt; len; i += 1) {
+            comments.push(extendCommentRange(deepCopy(providedComments[i]), tokens));
+        }
+
+        // This is based on John Freeman's implementation.
+        cursor = 0;
+        traverse(tree, {
+            enter: function (node) {
+                var comment;
+
+                while (cursor &lt; comments.length) {
+                    comment = comments[cursor];
+                    if (comment.extendedRange[1] &gt; node.range[0]) {
+                        break;
+                    }
+
+                    if (comment.extendedRange[1] === node.range[0]) {
+                        if (!node.leadingComments) {
+                            node.leadingComments = [];
+                        }
+                        node.leadingComments.push(comment);
+                        comments.splice(cursor, 1);
+                    } else {
+                        cursor += 1;
+                    }
+                }
+
+                // already out of owned node
+                if (cursor === comments.length) {
+                    return VisitorOption.Break;
+                }
+
+                if (comments[cursor].extendedRange[0] &gt; node.range[1]) {
+                    return VisitorOption.Skip;
+                }
+            }
+        });
+
+        cursor = 0;
+        traverse(tree, {
+            leave: function (node) {
+                var comment;
+
+                while (cursor &lt; comments.length) {
+                    comment = comments[cursor];
+                    if (node.range[1] &lt; comment.extendedRange[0]) {
+                        break;
+                    }
+
+                    if (node.range[1] === comment.extendedRange[0]) {
+                        if (!node.trailingComments) {
+                            node.trailingComments = [];
+                        }
+                        node.trailingComments.push(comment);
+                        comments.splice(cursor, 1);
+                    } else {
+                        cursor += 1;
+                    }
+                }
+
+                // already out of owned node
+                if (cursor === comments.length) {
+                    return VisitorOption.Break;
+                }
+
+                if (comments[cursor].extendedRange[0] &gt; node.range[1]) {
+                    return VisitorOption.Skip;
+                }
+            }
+        });
+
+        return tree;
+    }
+
+    exports.version = '1.5.1-dev';
+    exports.Syntax = Syntax;
+    exports.traverse = traverse;
+    exports.replace = replace;
+    exports.attachComments = attachComments;
+    exports.VisitorKeys = VisitorKeys;
+    exports.VisitorOption = VisitorOption;
+    exports.Controller = Controller;
+}));
+/* vim: set sw=4 ts=4 et tw=80 : */
+
+},{}],8:[function(require,module,exports){
+'use strict';
+
+function ToObject(val) {
+        if (val == null) {
+                throw new TypeError('Object.assign cannot be called with null or undefined');
+        }
+
+        return Object(val);
+}
+
+module.exports = Object.assign || function (target, source) {
+        var pendingException;
+        var from;
+        var keys;
+        var to = ToObject(target);
+
+        for (var s = 1; s &lt; arguments.length; s++) {
+                from = arguments[s];
+                keys = Object.keys(Object(from));
+
+                for (var i = 0; i &lt; keys.length; i++) {
+                        try {
+                                to[keys[i]] = from[keys[i]];
+                        } catch (err) {
+                                if (pendingException === undefined) {
+                                        pendingException = err;
+                                }
+                        }
+                }
+        }
+
+        if (pendingException) {
+                throw pendingException;
+        }
+
+        return to;
+};
+
+},{}],9:[function(require,module,exports){
+/**
+ * @fileoverview Main ESLint object.
+ * @author Nicholas C. Zakas
+ */
+&quot;use strict&quot;;
+
+//------------------------------------------------------------------------------
+// Requirements
+//------------------------------------------------------------------------------
+
+var esprima = require(&quot;esprima&quot;),
+    estraverse = require(&quot;estraverse&quot;),
+    escope = require(&quot;escope&quot;),
+    environments = require(&quot;../conf/environments.json&quot;),
+    assign = require(&quot;object-assign&quot;),
+    rules = require(&quot;./rules&quot;),
+    util = require(&quot;./util&quot;),
+    RuleContext = require(&quot;./rule-context&quot;),
+    EventEmitter = require(&quot;events&quot;).EventEmitter;
+
+//------------------------------------------------------------------------------
+// Helpers
+//------------------------------------------------------------------------------
+
+function escapeRegExp(rx) {
+    return rx.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, &quot;\\$&amp;&quot;);
+}
+
+/**
+ * Parses a list of &quot;name:boolean_value&quot; or/and &quot;name&quot; options divided by comma or
+ * whitespace.
+ * @param {string} string The string to parse.
+ * @returns {Object} Result map object of names and boolean values
+ */
+function parseBooleanConfig(string) {
+    var items = {};
+    // Collapse whitespace around : to make parsing easier
+    string = string.replace(/\s*:\s*/g, &quot;:&quot;);
+    // Collapse whitespace around ,
+    string = string.replace(/\s*,\s*/g, &quot;,&quot;);
+    string.split(/\s|,+/).forEach(function(name) {
+        if (!name) {
+            return;
+        }
+        var pos = name.indexOf(&quot;:&quot;),
+            value;
+        if (pos !== -1) {
+            value = name.substring(pos + 1, name.length);
+            name = name.substring(0, pos);
+        }
+
+        items[name] = (value === &quot;true&quot;);
+
+    });
+    return items;
+}
+
+/**
+ * Parses a JSON-like config.
+ * @param {string} string The string to parse.
+ * @returns {Object} Result map object
+ */
+function parseJsonConfig(string) {
+    var items = {};
+    string = string.replace(/([a-z0-9\-\/]+):/g, &quot;\&quot;$1\&quot;:&quot;).replace(/(\]|[0-9])\s+(?=&quot;)/, &quot;$1,&quot;);
+    try {
+        items = JSON.parse(&quot;{&quot; + string + &quot;}&quot;);
+    } catch(e) { }
+
+    return items;
+}
+
+/**
+ * Parses a config of values separated by comma.
+ * @param {string} string The string to parse.
+ * @returns {Object} Result map of values and true values
+ */
+function parseListConfig(string) {
+    var items = {};
+    // Collapse whitespace around ,
+    string = string.replace(/\s*,\s*/g, &quot;,&quot;);
+    string.split(/,+/).forEach(function(name) {
+        name = name.trim();
+        if (!name) {
+            return;
+        }
+        items[name] = true;
+    });
+    return items;
+}
+
+/**
+ * @param {Scope} scope The scope object to check.
+ * @param {string} name The name of the variable to look up.
+ * @returns {Variable} The variable object if found or null if not.
+ */
+function getVariable(scope, name) {
+    var variable = null;
+    scope.variables.some(function(v) {
+        if (v.name === name) {
+            variable = v;
+            return true;
+        } else {
+            return false;
+        }
+
+    });
+    return variable;
+}
+
+/**
+ * Ensures that variables representing built-in properties of the Global Object,
+ * and any globals declared by special block comments, are present in the global
+ * scope.
+ * @param {ASTNode} program The top node of the AST.
+ * @param {Scope} globalScope The global scope.
+ * @param {Object} config The existing configuration data.
+ * @returns {void}
+ */
+function addDeclaredGlobals(program, globalScope, config) {
+    var declaredGlobals = {},
+        explicitGlobals = {},
+        builtin = environments.builtin;
+
+    assign(declaredGlobals, builtin);
+
+    Object.keys(config.env).forEach(function (name) {
+        if (config.env[name]) {
+            var environmentGlobals = environments[name] &amp;&amp; environments[name].globals;
+            if (environmentGlobals) {
+                assign(declaredGlobals, environmentGlobals);
+            }
+        }
+    });
+
+    assign(declaredGlobals, config.globals);
+    assign(explicitGlobals, config.astGlobals);
+
+    Object.keys(declaredGlobals).forEach(function(name) {
+        var variable = getVariable(globalScope, name);
+        if (!variable) {
+            variable = new escope.Variable(name, globalScope);
+            variable.eslintExplicitGlobal = false;
+            globalScope.variables.push(variable);
+        }
+        variable.writeable = declaredGlobals[name];
+    });
+
+    Object.keys(explicitGlobals).forEach(function(name) {
+        var variable = getVariable(globalScope, name);
+        if (!variable) {
+            variable = new escope.Variable(name, globalScope);
+            variable.eslintExplicitGlobal = true;
+            globalScope.variables.push(variable);
+        }
+        variable.writeable = explicitGlobals[name];
+    });
+}
+
+/**
+ * Add data to reporting configuration to disable reporting for list of rules
+ * starting from start location
+ * @param  {Object[]} reportingConfig Current reporting configuration
+ * @param  {Object} start Position to start
+ * @param  {string[]} rules List of rules
+ * @returns {void}
+ */
+function disableReporting(reportingConfig, start, rules) {
+
+    if (rules.length) {
+        rules.forEach(function(rule) {
+            reportingConfig.push({
+                start: start,
+                end: null,
+                rule: rule
+            });
+        });
+    } else {
+        reportingConfig.push({
+            start: start,
+            end: null,
+            rule: null
+        });
+    }
+}
+
+/**
+ * Add data to reporting configuration to enable reporting for list of rules
+ * starting from start location
+ * @param  {Object[]} reportingConfig Current reporting configuration
+ * @param  {Object} start Position to start
+ * @param  {string[]} rules List of rules
+ * @returns {void}
+ */
+function enableReporting(reportingConfig, start, rules) {
+    var i;
+
+    if (rules.length) {
+        rules.forEach(function(rule) {
+            for (i = reportingConfig.length - 1; i &gt;= 0; i--) {
+                if (!reportingConfig[i].end &amp;&amp; reportingConfig[i].rule === rule ) {
+                    reportingConfig[i].end = start;
+                    break;
+                }
+            }
+        });
+    } else {
+        // find all previous disabled locations if they was started as list of rules
+        var prevStart;
+        for (i = reportingConfig.length - 1; i &gt;= 0; i--) {
+            if (prevStart &amp;&amp; prevStart !== reportingConfig[i].start) {
+                break;
+            }
+
+            if (!reportingConfig[i].end) {
+                reportingConfig[i].end = start;
+                prevStart = reportingConfig[i].start;
+            }
+        }
+    }
+}
+
+
+/**
+ * Parses comments in file to extract file-specific config of rules, globals
+ * and environments and merges them with global config; also code blocks
+ * where reporting is disabled or enabled and merges them with reporting config.
+ * @param {ASTNode} ast The top node of the AST.
+ * @param {Object} config The existing configuration data.
+ * @param {Object[]} reportingConfig The existing reporting configuration data.
+ * @returns {void}
+ */
+function modifyConfigsFromComments(ast, config, reportingConfig) {
+
+    var commentConfig = {
+        astGlobals: {},
+        rules: {},
+        env: {}
+    };
+    var commentRules = {};
+
+    ast.comments.forEach(function(comment) {
+        if (comment.type === &quot;Block&quot;) {
+
+            var value = comment.value.trim();
+            var match = /^(eslint-\w+|eslint|globals?)(\s|$)/.exec(value);
+
+            if (match) {
+                value = value.substring(match.index + match[1].length);
+
+                switch (match[1]) {
+                    case &quot;globals&quot;:
+                    case &quot;global&quot;:
+                        util.mixin(commentConfig.astGlobals, parseBooleanConfig(value));
+                        break;
+
+                    case &quot;eslint-env&quot;:
+                        util.mixin(commentConfig.env, parseListConfig(value));
+                        break;
+
+                    case &quot;eslint-disable&quot;:
+                        disableReporting(reportingConfig, comment.loc.start, Object.keys(parseListConfig(value)));
+                        break;
+
+                    case &quot;eslint-enable&quot;:
+                        enableReporting(reportingConfig, comment.loc.start, Object.keys(parseListConfig(value)));
+                        break;
+
+                    case &quot;eslint&quot;:
+                        var items = parseJsonConfig(value);
+                        Object.keys(items).forEach(function(name) {
+                            var ruleValue = items[name];
+                            if (typeof ruleValue === &quot;number&quot; || (Array.isArray(ruleValue) &amp;&amp; typeof ruleValue[0] === &quot;number&quot;)) {
+                                commentRules[name] = ruleValue;
+                            }
+                        });
+                        break;
+
+                    // no default
+                }
+            }
+        }
+    });
+
+    // apply environment rules before user rules
+    Object.keys(commentConfig.env).forEach(function (name) {
+        var environmentRules = environments[name] &amp;&amp; environments[name].rules;
+        if (commentConfig.env[name] &amp;&amp; environmentRules) {
+            util.mixin(commentConfig.rules, environmentRules);
+        }
+    });
+    util.mixin(commentConfig.rules, commentRules);
+
+    util.mergeConfigs(config, commentConfig);
+}
+
+/**
+ * Check if message of rule with ruleId should be ignored in location
+ * @param  {Object[]} reportingConfig  Collection of ignore records
+ * @param  {string} ruleId   Id of rule
+ * @param  {Object} location Location of message
+ * @returns {boolean}          True if message should be ignored, false otherwise
+ */
+function isDisabledByReportingConfig(reportingConfig, ruleId, location) {
+
+    for (var i = 0, c = reportingConfig.length; i &lt; c; i++) {
+
+        var ignore = reportingConfig[i];
+        if ((!ignore.rule || ignore.rule === ruleId) &amp;&amp;
+            (location.line &gt; ignore.start.line || (location.line === ignore.start.line &amp;&amp; location.column &gt;= ignore.start.column)) &amp;&amp;
+            (!ignore.end || (location.line &lt; ignore.end.line || (location.line === ignore.end.line &amp;&amp; location.column &lt;= ignore.end.column)))) {
+                return true;
+        }
+    }
+
+    return false;
+}
+
+/**
+ * Process initial config to make it safe to extend by file comment config
+ * @param  {Object} config Initial config
+ * @returns {Object}        Processed config
+ */
+function prepareConfig(config) {
+
+    config.globals = config.globals || config.global || {};
+    delete config.global;
+
+    var copiedRules = {};
+    if (typeof config.rules === &quot;object&quot;) {
+        Object.keys(config.rules).forEach(function(k) {
+            var rule = config.rules[k];
+            if (Array.isArray(rule)) {
+                copiedRules[k] = rule.slice();
+            } else {
+                copiedRules[k] = rule;
+            }
+        });
+    }
+
+    return {
+        rules: copiedRules,
+        globals: util.mergeConfigs({}, config.globals),
+        env: util.mergeConfigs({}, config.env || {}),
+        settings: util.mergeConfigs({}, config.settings || {})
+    };
+}
+
+//------------------------------------------------------------------------------
+// Public Interface
+//------------------------------------------------------------------------------
+
+/**
+ * Object that is responsible for verifying JavaScript text
+ * @name eslint
+ */
+module.exports = (function() {
+
+    var api = Object.create(new EventEmitter()),
+        messages = [],
+        currentText = null,
+        currentTextLines = [],
+        currentConfig = null,
+        currentTokens = null,
+        currentScopes = null,
+        scopeMap = null,
+        currentFilename = null,
+        controller = null,
+        reportingConfig = [],
+        commentLocsEnter = [],
+        commentLocsExit = [];
+
+    /**
+     * Parses text into an AST. Moved out here because the try-catch prevents
+     * optimization of functions, so it's best to keep the try-catch as isolated
+     * as possible
+     * @param {string} text The text to parse.
+     * @returns {ASTNode} The AST if successful or null if not.
+     * @private
+     */
+    function parse(text) {
+        /*
+         * Check for parsing errors first. If there's a parsing error, nothing
+         * else can happen. However, a parsing error does not throw an error
+         * from this method - it's just considered a fatal error message, a
+         * problem that ESLint identified just like any other.
+         */
+        try {
+            return esprima.parse(text, {
+                loc: true,
+                range: true,
+                raw: true,
+                tokens: true,
+                comment: true,
+                attachComment: true
+            });
+        } catch (ex) {
+
+            messages.push({
+                fatal: true,
+                severity: 2,
+
+                // messages come as &quot;Line X: Unexpected token foo&quot;, so strip off leading part
+                message: ex.message.substring(ex.message.indexOf(&quot;:&quot;) + 1).trim(),
+
+                line: ex.lineNumber,
+                column: ex.column
+            });
+
+            return null;
+        }
+    }
+
+    /**
+     * Check collection of comments to prevent double event for comment as
+     * leading and trailing, then emit event if passing
+     * @param {ASTNode[]} comments Collection of comment nodes
+     * @param {Object[]} locs List of locations of previous comment nodes
+     * @param {string} eventName Event name postfix
+     * @returns {void}
+     */
+    function emitComments(comments, locs, eventName) {
+
+        if (comments.length) {
+            comments.forEach(function(node) {
+                if (locs.indexOf(node.loc) &gt;= 0) {
+                    locs.splice(locs.indexOf(node.loc), 1);
+                } else {
+                    locs.push(node.loc);
+                    api.emit(node.type + eventName, node);
+                }
+            });
+        }
+    }
+
+    /**
+     * Shortcut to check and emit enter of comment nodes
+     * @param {ASTNode[]} comments Collection of comment nodes
+     * @returns {void}
+     */
+    function emitCommentsEnter(comments) {
+        emitComments(comments, commentLocsEnter, &quot;Comment&quot;);
+    }
+
+    /**
+     * Shortcut to check and emit exit of comment nodes
+     * @param {ASTNode[]} comments Collection of comment nodes
+     * @returns {void}
+     */
+    function emitCommentsExit(comments) {
+        emitComments(comments, commentLocsExit, &quot;Comment:exit&quot;);
+    }
+
+    /**
+     * Get the severity level of a rule (0 - none, 1 - warning, 2 - error)
+     * Returns 0 if the rule config is not valid (an Array or a number)
+     * @param {Array|number} ruleConfig rule configuration
+     * @returns {number} 0, 1, or 2, indicating rule severity
+     */
+    function getRuleSeverity(ruleConfig) {
+        if (typeof ruleConfig === &quot;number&quot;) {
+            return ruleConfig;
+        } else if (Array.isArray(ruleConfig)) {
+            return ruleConfig[0];
+        } else {
+            return 0;
+        }
+    }
+
+    /**
+     * Get the options for a rule (not including severity), if any
+     * @param {Array|number} ruleConfig rule configuration
+     * @returns {Array} of rule options, empty Array if none
+     */
+    function getRuleOptions(ruleConfig) {
+        if (Array.isArray(ruleConfig)) {
+            return ruleConfig.slice(1);
+        } else {
+            return [];
+        }
+    }
+
+    // set unlimited listeners (see https://github.com/eslint/eslint/issues/524)
+    api.setMaxListeners(0);
+
+    /**
+     * Resets the internal state of the object.
+     * @returns {void}
+     */
+    api.reset = function() {
+        this.removeAllListeners();
+        messages = [];
+        currentConfig = null;
+        currentText = null;
+        currentTextLines = [];
+        currentTokens = null;
+        currentScopes = null;
+        scopeMap = null;
+        controller = null;
+        reportingConfig = [];
+        commentLocsEnter = [];
+        commentLocsExit = [];
+    };
+
+    /**
+     * Verifies the text against the rules specified by the second argument.
+     * @param {string} text The JavaScript text to verify.
+     * @param {Object} config An object whose keys specify the rules to use.
+     * @param {string=} filename The optional filename of the file being checked.
+     *      If this is not set, the filename will default to '&lt;input&gt;' in the rule context.
+     * @param {boolean=} saveState Indicates if the state from the last run should be saved.
+     *      Mostly useful for testing purposes.
+     * @returns {Object[]} The results as an array of messages or null if no messages.
+     */
+    api.verify = function(text, config, filename, saveState) {
+
+        var ast;
+
+        // set the current parsed filename
+        currentFilename = filename;
+
+        if (!saveState) {
+            this.reset();
+        }
+
+        ast = parse(text.replace(/^#!([^\r\n]+[\r\n]+)/, &quot;//$1&quot;));
+
+        // if Esprima failed to parse the file, there's no sense in setting up rules
+        if (ast) {
+            // process initial config to make it safe to extend
+            config = prepareConfig(config);
+
+            // parse global comments and modify config
+            modifyConfigsFromComments(ast, config, reportingConfig);
+
+            // enable appropriate rules
+            Object.keys(config.rules).filter(function(key) {
+                return getRuleSeverity(config.rules[key]) &gt; 0;
+            }).forEach(function(key) {
+
+                var ruleCreator = rules.get(key),
+                    severity = getRuleSeverity(config.rules[key]),
+                    options = getRuleOptions(config.rules[key]),
+                    rule;
+
+                if (ruleCreator) {
+                    try {
+                        rule = ruleCreator(new RuleContext(key, api, severity, options, config.settings));
+
+                        // add all the node types as listeners
+                        Object.keys(rule).forEach(function(nodeType) {
+                            api.on(nodeType, rule[nodeType]);
+                        });
+                    } catch(ex) {
+                        ex.message = &quot;Error while loading rule '&quot; + key + &quot;': &quot; + ex.message;
+                        throw ex;
+                    }
+
+                } else {
+                    throw new Error(&quot;Definition for rule '&quot; + key + &quot;' was not found.&quot;);
+                }
+            });
+
+            // save config so rules can access as necessary
+            currentConfig = config;
+            currentText = text;
+            controller = new estraverse.Controller();
+
+            // gather data that may be needed by the rules
+            currentScopes = escope.analyze(ast, { ignoreEval: true }).scopes;
+
+            /*
+             * Index the scopes by the start range of their block for efficient
+             * lookup in getScope.
+             */
+            scopeMap = [];
+            currentScopes.forEach(function (scope, index) {
+                var range = scope.block.range[0];
+
+                // Sometimes two scopes are returned for a given node. This is
+                // handled later in a known way, so just don't overwrite here.
+                if (!scopeMap[range]) {
+                    scopeMap[range] = index;
+                }
+            });
+
+            /*
+             * Split text here into array of lines so
+             * it's not being done repeatedly
+             * by individual rules.
+             */
+            currentTextLines = currentText.split(/\r?\n/g);
+
+            // Freezing so array isn't accidentally changed by a rule.
+            Object.freeze(currentTextLines);
+
+            /* get all tokens from the ast and store them as a hashtable to
+             * improve traversal speed when wanting to find tokens for a given
+             * node
+             */
+            currentTokens = [];
+            ast.tokens.forEach(function(token) {
+                currentTokens[token.range[0]] = token;
+            });
+
+            // augment global scope with declared global variables
+            addDeclaredGlobals(ast, currentScopes[0], currentConfig);
+
+            /*
+             * Each node has a type property. Whenever a particular type of node is found,
+             * an event is fired. This allows any listeners to automatically be informed
+             * that this type of node has been found and react accordingly.
+             */
+            controller.traverse(ast, {
+                enter: function(node, parent) {
+
+                    var comments = api.getComments(node);
+
+                    emitCommentsEnter(comments.leading);
+                    node.parent = parent;
+                    api.emit(node.type, node);
+                    emitCommentsEnter(comments.trailing);
+                },
+                leave: function(node) {
+
+                    var comments = api.getComments(node);
+
+                    emitCommentsExit(comments.trailing);
+                    api.emit(node.type + &quot;:exit&quot;, node);
+                    emitCommentsExit(comments.leading);
+                }
+            });
+
+        }
+
+        return messages;
+    };
+
+    /**
+     * Reports a message from one of the rules.
+     * @param {string} ruleId The ID of the rule causing the message.
+     * @param {number} severity The severity level of the rule as configured.
+     * @param {ASTNode} node The AST node that the message relates to.
+     * @param {Object=} location An object containing the error line and column
+     *      numbers. If location is not provided the node's start location will
+     *      be used.
+     * @param {string} message The actual message.
+     * @param {Object} opts Optional template data which produces a formatted message
+     *     with symbols being replaced by this object's values.
+     * @returns {void}
+     */
+    api.report = function(ruleId, severity, node, location, message, opts) {
+
+        if (typeof location === &quot;string&quot;) {
+            opts = message;
+            message = location;
+            location = node.loc.start;
+        }
+
+        Object.keys(opts || {}).forEach(function (key) {
+            var rx = new RegExp(&quot;{{&quot; + escapeRegExp(key) + &quot;}}&quot;, &quot;g&quot;);
+            message = message.replace(rx, opts[key]);
+        });
+
+        if (isDisabledByReportingConfig(reportingConfig, ruleId, location)) {
+            return;
+        }
+
+        messages.push({
+            ruleId: ruleId,
+            severity: severity,
+            node: node,
+            message: message,
+            line: location.line,
+            column: location.column,
+            source: api.getSource(node)
+        });
+    };
+
+    /**
+     * Gets the source code for the given node.
+     * @param {ASTNode=} node The AST node to get the text for.
+     * @param {int=} beforeCount The number of characters before the node to retrieve.
+     * @param {int=} afterCount The number of characters after the node to retrieve.
+     * @returns {string} The text representing the AST node.
+     */
+    api.getSource = function(node, beforeCount, afterCount) {
+        if (node) {
+            return (currentText !== null) ? currentText.slice(node.range[0] - (beforeCount || 0),
+                node.range[1] + (afterCount || 0)) : null;
+        } else {
+            return currentText;
+        }
+
+    };
+
+    /**
+     * Gets the entire source text split into an array of lines.
+     * @returns {Array} The source text as an array of lines.
+     */
+    api.getSourceLines = function() {
+        return currentTextLines;
+    };
+
+    /**
+     * Gets all comments for the given node.
+     * @param {ASTNode} node The AST node to get the comments for.
+     * @returns {Object} The list of comments indexed by their position.
+     */
+    api.getComments = function(node) {
+
+        var leadingComments = node.leadingComments || [],
+            trailingComments = node.trailingComments || [];
+
+        /*
+         * Esprima adds a &quot;comments&quot; array on Program nodes rather than
+         * leadingComments/trailingComments. Comments are only left in the
+         * Program node comments array if there is no executable code.
+         */
+        if (node.type === &quot;Program&quot;) {
+            if (node.body.length === 0) {
+                leadingComments = node.comments;
+            }
+        }
+
+        return {
+            leading: leadingComments,
+            trailing: trailingComments
+        };
+    };
+
+    /**
+     * Retrieves the JSDoc comment for a given node.
+     * @param {ASTNode} node The AST node to get the comment for.
+     * @returns {ASTNode} The BlockComment node containing the JSDoc for the
+     *      given node or null if not found.
+     */
+    api.getJSDocComment = function(node) {
+
+        var parent = node.parent,
+            line = node.loc.start.line;
+
+        /**
+         * Finds a JSDoc comment node in an array of comment nodes.
+         * @param {ASTNode[]} comments The array of comment nodes to search.
+         * @returns {ASTNode} The node if found, null if not.
+         * @private
+         */
+        function findJSDocComment(comments) {
+
+            if (comments) {
+                for (var i = comments.length - 1; i &gt;= 0; i--) {
+                    if (comments[i].type === &quot;Block&quot; &amp;&amp; comments[i].value.charAt(0) === &quot;*&quot;) {
+
+                        if (line - comments[i].loc.end.line &lt;= 1) {
+                            return comments[i];
+                        } else {
+                            break;
+                        }
+                    }
+                }
+            }
+
+            return null;
+        }
+
+        switch (node.type) {
+            case &quot;FunctionDeclaration&quot;:
+                return findJSDocComment(node.leadingComments);
+
+            case &quot;FunctionExpression&quot;:
+
+                if (parent.type !== &quot;CallExpression&quot; || parent.callee !== node) {
+                    while (parent &amp;&amp; !parent.leadingComments &amp;&amp; parent.type !== &quot;FunctionExpression&quot; &amp;&amp; parent.type !== &quot;FunctionDeclaration&quot;) {
+                        parent = parent.parent;
+                    }
+
+                    return parent &amp;&amp; (parent.type !== &quot;FunctionDeclaration&quot;) ? findJSDocComment(parent.leadingComments) : null;
+                }
+
+                // falls through
+
+            default:
+                return null;
+        }
+    };
+
+    /**
+     * Gets a number of tokens that precede a given node's tokens in the token stream.
+     * @param {ASTNode} node The AST node.
+     * @param {int} [beforeCount=0] The number of tokens before the node to retrieve.
+     * @returns {[Token]} Array of objects representing tokens.
+     */
+    api.getTokensBefore = function(node, beforeCount) {
+        var beforeTokens = [], cursor = node.range[0] - 1;
+        while (beforeCount &gt; 0 &amp;&amp; cursor &gt;= 0) {
+            if (currentTokens[cursor]) {
+                beforeTokens.unshift(currentTokens[cursor]);
+                --beforeCount;
+            }
+            --cursor;
+        }
+        return beforeTokens;
+    };
+
+    /**
+     * Gets the token that precedes a given node's tokens in the token stream.
+     * @param {ASTNode} node The AST node.
+     * @param {int} [skip=0] A number of tokens to skip before the given node.
+     * @returns {Token} An object representing the token.
+     */
+    api.getTokenBefore = function(node, skip) {
+        for (var cursor = node.range[0] - 1; cursor &gt;= 0; --cursor) {
+            if (currentTokens[cursor]) {
+                if (skip &gt; 0) {
+                    --skip;
+                } else {
+                    return currentTokens[cursor];
+                }
+            }
+        }
+    };
+
+    /**
+     * Gets a number of tokens that precede a given node's tokens in the token stream.
+     * @param {ASTNode} node The AST node.
+     * @param {int} [afterCount=0] The number of tokens after the node to retrieve.
+     * @returns {[Token]} Array of objects representing tokens.
+     */
+    api.getTokensAfter = function(node, afterCount) {
+        var afterTokens = [], cursor = node.range[1];
+        while (afterCount &gt; 0 &amp;&amp; cursor &lt; currentTokens.length) {
+            if (currentTokens[cursor]) {
+                afterTokens.push(currentTokens[cursor]);
+                --afterCount;
+                cursor = currentTokens[cursor].range[1];
+            } else {
+                ++cursor;
+            }
+        }
+        return afterTokens;
+    };
+
+    /**
+     * Gets the token that follows a given node's tokens in the token stream.
+     * @param {ASTNode} node The AST node.
+     * @param {int} [skip=0] A number of tokens to skip after the given node.
+     * @returns {Token} An object representing the token.
+     */
+    api.getTokenAfter = function(node, skip) {
+        for (var cursor = node.range[1]; cursor &lt; currentTokens.length; ++cursor) {
+            if (currentTokens[cursor]) {
+                if (skip &gt; 0) {
+                    --skip;
+                } else {
+                    return currentTokens[cursor];
+                }
+            }
+        }
+    };
+
+    /**
+     * Gets all tokens that are related to the given node.
+     * @param {ASTNode} node The AST node.
+     * @param {int} [beforeCount=0] The number of tokens before the node to retrieve.
+     * @param {int} [afterCount=0] The number of tokens after the node to retrieve.
+     * @returns {[Token]} Array of objects representing tokens.
+     */
+    api.getTokens = function(node, beforeCount, afterCount) {
+        var beforeTokens = api.getTokensBefore(node, beforeCount),
+            afterTokens = api.getTokensAfter(node, afterCount),
+            tokens = [],
+            cursor = node.range[0];
+        while (cursor &lt; node.range[1]) {
+            if (currentTokens[cursor]) {
+                tokens.push(currentTokens[cursor]);
+                cursor = currentTokens[cursor].range[1];
+            } else {
+                ++cursor;
+            }
+        }
+        return beforeTokens.concat(tokens, afterTokens);
+    };
+
+    /**
+     * Gets the first `count` tokens of the given node's token stream.
+     * @param {ASTNode} node The AST node.
+     * @param {int} [count=0] The number of tokens of the node to retrieve.
+     * @returns {[Token]} Array of objects representing tokens.
+     */
+    api.getFirstTokens = function(node, count) {
+        var tokens = [], cursor = node.range[0];
+        while (count &gt; 0 &amp;&amp; cursor &lt; node.range[1]) {
+            if (currentTokens[cursor]) {
+                tokens.push(currentTokens[cursor]);
+                --count;
+                cursor = currentTokens[cursor].range[1];
+            } else {
+                ++cursor;
+            }
+        }
+        return tokens;
+    };
+
+    /**
+     * Gets the first token of the given node's token stream.
+     * @param {ASTNode} node The AST node.
+     * @param {int} [skip=0] A number of tokens to skip.
+     * @returns {Token} An object representing the token.
+     */
+    api.getFirstToken = function(node, skip) {
+        for (var cursor = node.range[0]; cursor &lt; node.range[1]; ++cursor) {
+            if (currentTokens[cursor]) {
+                if (skip &gt; 0) {
+                    --skip;
+                } else {
+                    return currentTokens[cursor];
+                }
+            }
+        }
+    };
+
+    /**
+     * Gets the last `count` tokens of the given node.
+     * @param {ASTNode} node The AST node.
+     * @param {int} [count=0] The number of tokens of the node to retrieve.
+     * @returns {[Token]} Array of objects representing tokens.
+     */
+    api.getLastTokens = function(node, count) {
+        var tokens = [], cursor = node.range[1] - 1;
+        while (count &gt; 0 &amp;&amp; cursor &gt;= node.range[0]) {
+            if (currentTokens[cursor]) {
+                tokens.unshift(currentTokens[cursor]);
+                --count;
+            }
+            --cursor;
+        }
+        return tokens;
+    };
+
+    /**
+     * Gets the last token of the given node's token stream.
+     * @param {ASTNode} node The AST node.
+     * @param {int} [skip=0] A number of tokens to skip.
+     * @returns {Token} An object representing the token.
+     */
+    api.getLastToken = function(node, skip) {
+        for (var cursor = node.range[1] - 1; cursor &gt;= node.range[0]; --cursor) {
+            if (currentTokens[cursor]) {
+                if (skip &gt; 0) {
+                    --skip;
+                } else {
+                    return currentTokens[cursor];
+                }
+            }
+        }
+    };
+
+    /**
+     * Gets nodes that are ancestors of current node.
+     * @returns {ASTNode[]} Array of objects representing ancestors.
+     */
+    api.getAncestors = function() {
+        return controller.parents();
+    };
+
+
+    /**
+     * Gets the scope for the current node.
+     * @returns {Object} An object representing the current node's scope.
+     */
+    api.getScope = function() {
+        var parents = controller.parents(),
+            innerBlock = null,
+            selectedScopeIndex;
+
+        // Don't do this for Program nodes - they have no parents
+        if (parents.length) {
+
+            // if current node is function declaration, add it to the list
+            var current = controller.current();
+            if (current.type === &quot;FunctionDeclaration&quot; || current.type === &quot;FunctionExpression&quot;) {
+                parents.push(current);
+            }
+
+            // Ascend the current node's parents
+            for (var i = parents.length - 1; i &gt;= 0; --i) {
+
+                // The first node that requires a scope is the node that will be
+                // our current node's innermost scope.
+                if (escope.Scope.isScopeRequired(parents[i])) {
+                    innerBlock = parents[i];
+                    break;
+                }
+            }
+
+            // Find and return the innermost scope
+            selectedScopeIndex = scopeMap[innerBlock.range[0]];
+
+            // Named function expressions create two nested scope objects. The
+            // outer scope contains only the function expression name. We return
+            // the inner scope.
+            if (innerBlock.type === &quot;FunctionExpression&quot; &amp;&amp; innerBlock.id &amp;&amp; innerBlock.id.name) {
+                ++selectedScopeIndex;
+            }
+
+            return currentScopes[selectedScopeIndex];
+        } else {
+            return currentScopes[0];    // global scope
+        }
+    };
+
+    /**
+     * Gets the filename for the currently parsed source.
+     * @returns {string} The filename associated with the source being parsed.
+     *     Defaults to &quot;&lt;input&gt;&quot; if no filename info is present.
+     */
+    api.getFilename = function() {
+        if (typeof currentFilename === &quot;string&quot;) {
+            return currentFilename;
+        } else {
+            return &quot;&lt;input&gt;&quot;;
+        }
+    };
+
+    /**
+     * Defines a new linting rule.
+     * @param {string} ruleId A unique rule identifier
+     * @param {Function} ruleModule Function from context to object mapping AST node types to event handlers
+     * @returns {void}
+     */
+    var defineRule = api.defineRule = function(ruleId, ruleModule) {
+        rules.define(ruleId, ruleModule);
+    };
+
+    /**
+     * Defines many new linting rules.
+     * @param {object} rules map from unique rule identifier to rule
+     * @returns {void}
+     */
+    api.defineRules = function(rules) {
+        Object.getOwnPropertyNames(rules).forEach(function(ruleId) {
+            defineRule(ruleId, rules[ruleId]);
+        });
+    };
+
+    /**
+     * Gets the default eslint configuration.
+     * @returns {Object} Object mapping rule IDs to their default configurations
+     */
+    api.defaults = function() {
+        return require(&quot;../conf/eslint.json&quot;);
+    };
+
+    return api;
+
+}());
+
+},{&quot;../conf/environments.json&quot;:1,&quot;../conf/eslint.json&quot;:2,&quot;./rule-context&quot;:11,&quot;./rules&quot;:12,&quot;./util&quot;:150,&quot;escope&quot;:5,&quot;esprima&quot;:6,&quot;estraverse&quot;:7,&quot;events&quot;:3,&quot;object-assign&quot;:8}],10:[function(require,module,exports){
+module.exports = function() {
+    var rules = Object.create(null);
+    rules[&quot;block-scoped-var&quot;] = require(&quot;./rules/block-scoped-var&quot;);
+    rules[&quot;brace-style&quot;] = require(&quot;./rules/brace-style&quot;);
+    rules[&quot;camelcase&quot;] = require(&quot;./rules/camelcase&quot;);
+    rules[&quot;comma-spacing&quot;] = require(&quot;./rules/comma-spacing&quot;);
+    rules[&quot;comma-style&quot;] = require(&quot;./rules/comma-style&quot;);
+    rules[&quot;complexity&quot;] = require(&quot;./rules/complexity&quot;);
+    rules[&quot;consistent-return&quot;] = require(&quot;./rules/consistent-return&quot;);
+    rules[&quot;consistent-this&quot;] = require(&quot;./rules/consistent-this&quot;);
+    rules[&quot;curly&quot;] = require(&quot;./rules/curly&quot;);
+    rules[&quot;default-case&quot;] = require(&quot;./rules/default-case&quot;);
+    rules[&quot;dot-notation&quot;] = require(&quot;./rules/dot-notation&quot;);
+    rules[&quot;eol-last&quot;] = require(&quot;./rules/eol-last&quot;);
+    rules[&quot;eqeqeq&quot;] = require(&quot;./rules/eqeqeq&quot;);
+    rules[&quot;func-names&quot;] = require(&quot;./rules/func-names&quot;);
+    rules[&quot;func-style&quot;] = require(&quot;./rules/func-style&quot;);
+    rules[&quot;global-strict&quot;] = require(&quot;./rules/global-strict&quot;);
+    rules[&quot;guard-for-in&quot;] = require(&quot;./rules/guard-for-in&quot;);
+    rules[&quot;handle-callback-err&quot;] = require(&quot;./rules/handle-callback-err&quot;);
+    rules[&quot;key-spacing&quot;] = require(&quot;./rules/key-spacing&quot;);
+    rules[&quot;max-depth&quot;] = require(&quot;./rules/max-depth&quot;);
+    rules[&quot;max-len&quot;] = require(&quot;./rules/max-len&quot;);
+    rules[&quot;max-nested-callbacks&quot;] = require(&quot;./rules/max-nested-callbacks&quot;);
+    rules[&quot;max-params&quot;] = require(&quot;./rules/max-params&quot;);
+    rules[&quot;max-statements&quot;] = require(&quot;./rules/max-statements&quot;);
+    rules[&quot;new-cap&quot;] = require(&quot;./rules/new-cap&quot;);
+    rules[&quot;new-parens&quot;] = require(&quot;./rules/new-parens&quot;);
+    rules[&quot;no-alert&quot;] = require(&quot;./rules/no-alert&quot;);
+    rules[&quot;no-array-constructor&quot;] = require(&quot;./rules/no-array-constructor&quot;);
+    rules[&quot;no-bitwise&quot;] = require(&quot;./rules/no-bitwise&quot;);
+    rules[&quot;no-caller&quot;] = require(&quot;./rules/no-caller&quot;);
+    rules[&quot;no-catch-shadow&quot;] = require(&quot;./rules/no-catch-shadow&quot;);
+    rules[&quot;no-comma-dangle&quot;] = require(&quot;./rules/no-comma-dangle&quot;);
+    rules[&quot;no-cond-assign&quot;] = require(&quot;./rules/no-cond-assign&quot;);
+    rules[&quot;no-console&quot;] = require(&quot;./rules/no-console&quot;);
+    rules[&quot;no-constant-condition&quot;] = require(&quot;./rules/no-constant-condition&quot;);
+    rules[&quot;no-control-regex&quot;] = require(&quot;./rules/no-control-regex&quot;);
+    rules[&quot;no-debugger&quot;] = require(&quot;./rules/no-debugger&quot;);
+    rules[&quot;no-delete-var&quot;] = require(&quot;./rules/no-delete-var&quot;);
+    rules[&quot;no-div-regex&quot;] = require(&quot;./rules/no-div-regex&quot;);
+    rules[&quot;no-dupe-keys&quot;] = require(&quot;./rules/no-dupe-keys&quot;);
+    rules[&quot;no-else-return&quot;] = require(&quot;./rules/no-else-return&quot;);
+    rules[&quot;no-empty-class&quot;] = require(&quot;./rules/no-empty-class&quot;);
+    rules[&quot;no-empty-label&quot;] = require(&quot;./rules/no-empty-label&quot;);
+    rules[&quot;no-empty&quot;] = require(&quot;./rules/no-empty&quot;);
+    rules[&quot;no-eq-null&quot;] = require(&quot;./rules/no-eq-null&quot;);
+    rules[&quot;no-eval&quot;] = require(&quot;./rules/no-eval&quot;);
+    rules[&quot;no-ex-assign&quot;] = require(&quot;./rules/no-ex-assign&quot;);
+    rules[&quot;no-extend-native&quot;] = require(&quot;./rules/no-extend-native&quot;);
+    rules[&quot;no-extra-bind&quot;] = require(&quot;./rules/no-extra-bind&quot;);
+    rules[&quot;no-extra-boolean-cast&quot;] = require(&quot;./rules/no-extra-boolean-cast&quot;);
+    rules[&quot;no-extra-parens&quot;] = require(&quot;./rules/no-extra-parens&quot;);
+    rules[&quot;no-extra-semi&quot;] = require(&quot;./rules/no-extra-semi&quot;);
+    rules[&quot;no-extra-strict&quot;] = require(&quot;./rules/no-extra-strict&quot;);
+    rules[&quot;no-fallthrough&quot;] = require(&quot;./rules/no-fallthrough&quot;);
+    rules[&quot;no-floating-decimal&quot;] = require(&quot;./rules/no-floating-decimal&quot;);
+    rules[&quot;no-func-assign&quot;] = require(&quot;./rules/no-func-assign&quot;);
+    rules[&quot;no-implied-eval&quot;] = require(&quot;./rules/no-implied-eval&quot;);
+    rules[&quot;no-inner-declarations&quot;] = require(&quot;./rules/no-inner-declarations&quot;);
+    rules[&quot;no-invalid-regexp&quot;] = require(&quot;./rules/no-invalid-regexp&quot;);
+    rules[&quot;no-iterator&quot;] = require(&quot;./rules/no-iterator&quot;);
+    rules[&quot;no-label-var&quot;] = require(&quot;./rules/no-label-var&quot;);
+    rules[&quot;no-labels&quot;] = require(&quot;./rules/no-labels&quot;);
+    rules[&quot;no-lone-blocks&quot;] = require(&quot;./rules/no-lone-blocks&quot;);
+    rules[&quot;no-lonely-if&quot;] = require(&quot;./rules/no-lonely-if&quot;);
+    rules[&quot;no-loop-func&quot;] = require(&quot;./rules/no-loop-func&quot;);
+    rules[&quot;no-mixed-requires&quot;] = require(&quot;./rules/no-mixed-requires&quot;);
+    rules[&quot;no-mixed-spaces-and-tabs&quot;] = require(&quot;./rules/no-mixed-spaces-and-tabs&quot;);
+    rules[&quot;no-multi-spaces&quot;] = require(&quot;./rules/no-multi-spaces&quot;);
+    rules[&quot;no-multi-str&quot;] = require(&quot;./rules/no-multi-str&quot;);
+    rules[&quot;no-multiple-empty-lines&quot;] = require(&quot;./rules/no-multiple-empty-lines&quot;);
+    rules[&quot;no-native-reassign&quot;] = require(&quot;./rules/no-native-reassign&quot;);
+    rules[&quot;no-negated-in-lhs&quot;] = require(&quot;./rules/no-negated-in-lhs&quot;);
+    rules[&quot;no-nested-ternary&quot;] = require(&quot;./rules/no-nested-ternary&quot;);
+    rules[&quot;no-new-func&quot;] = require(&quot;./rules/no-new-func&quot;);
+    rules[&quot;no-new-object&quot;] = require(&quot;./rules/no-new-object&quot;);
+    rules[&quot;no-new-require&quot;] = require(&quot;./rules/no-new-require&quot;);
+    rules[&quot;no-new-wrappers&quot;] = require(&quot;./rules/no-new-wrappers&quot;);
+    rules[&quot;no-new&quot;] = require(&quot;./rules/no-new&quot;);
+    rules[&quot;no-obj-calls&quot;] = require(&quot;./rules/no-obj-calls&quot;);
+    rules[&quot;no-octal-escape&quot;] = require(&quot;./rules/no-octal-escape&quot;);
+    rules[&quot;no-octal&quot;] = require(&quot;./rules/no-octal&quot;);
+    rules[&quot;no-path-concat&quot;] = require(&quot;./rules/no-path-concat&quot;);
+    rules[&quot;no-plusplus&quot;] = require(&quot;./rules/no-plusplus&quot;);
+    rules[&quot;no-process-env&quot;] = require(&quot;./rules/no-process-env&quot;);
+    rules[&quot;no-process-exit&quot;] = require(&quot;./rules/no-process-exit&quot;);
+    rules[&quot;no-proto&quot;] = require(&quot;./rules/no-proto&quot;);
+    rules[&quot;no-redeclare&quot;] = require(&quot;./rules/no-redeclare&quot;);
+    rules[&quot;no-regex-spaces&quot;] = require(&quot;./rules/no-regex-spaces&quot;);
+    rules[&quot;no-reserved-keys&quot;] = require(&quot;./rules/no-reserved-keys&quot;);
+    rules[&quot;no-restricted-modules&quot;] = require(&quot;./rules/no-restricted-modules&quot;);
+    rules[&quot;no-return-assign&quot;] = require(&quot;./rules/no-return-assign&quot;);
+    rules[&quot;no-script-url&quot;] = require(&quot;./rules/no-script-url&quot;);
+    rules[&quot;no-self-compare&quot;] = require(&quot;./rules/no-self-compare&quot;);
+    rules[&quot;no-sequences&quot;] = require(&quot;./rules/no-sequences&quot;);
+    rules[&quot;no-shadow-restricted-names&quot;] = require(&quot;./rules/no-shadow-restricted-names&quot;);
+    rules[&quot;no-shadow&quot;] = require(&quot;./rules/no-shadow&quot;);
+    rules[&quot;no-space-before-semi&quot;] = require(&quot;./rules/no-space-before-semi&quot;);
+    rules[&quot;no-spaced-func&quot;] = require(&quot;./rules/no-spaced-func&quot;);
+    rules[&quot;no-sparse-arrays&quot;] = require(&quot;./rules/no-sparse-arrays&quot;);
+    rules[&quot;no-sync&quot;] = require(&quot;./rules/no-sync&quot;);
+    rules[&quot;no-ternary&quot;] = require(&quot;./rules/no-ternary&quot;);
+    rules[&quot;no-trailing-spaces&quot;] = require(&quot;./rules/no-trailing-spaces&quot;);
+    rules[&quot;no-undef-init&quot;] = require(&quot;./rules/no-undef-init&quot;);
+    rules[&quot;no-undef&quot;] = require(&quot;./rules/no-undef&quot;);
+    rules[&quot;no-undefined&quot;] = require(&quot;./rules/no-undefined&quot;);
+    rules[&quot;no-underscore-dangle&quot;] = require(&quot;./rules/no-underscore-dangle&quot;);
+    rules[&quot;no-unreachable&quot;] = require(&quot;./rules/no-unreachable&quot;);
+    rules[&quot;no-unused-expressions&quot;] = require(&quot;./rules/no-unused-expressions&quot;);
+    rules[&quot;no-unused-vars&quot;] = require(&quot;./rules/no-unused-vars&quot;);
+    rules[&quot;no-use-before-define&quot;] = require(&quot;./rules/no-use-before-define&quot;);
+    rules[&quot;no-void&quot;] = require(&quot;./rules/no-void&quot;);
+    rules[&quot;no-warning-comments&quot;] = require(&quot;./rules/no-warning-comments&quot;);
+    rules[&quot;no-with&quot;] = require(&quot;./rules/no-with&quot;);
+    rules[&quot;no-wrap-func&quot;] = require(&quot;./rules/no-wrap-func&quot;);
+    rules[&quot;one-var&quot;] = require(&quot;./rules/one-var&quot;);
+    rules[&quot;padded-blocks&quot;] = require(&quot;./rules/padded-blocks&quot;);
+    rules[&quot;quote-props&quot;] = require(&quot;./rules/quote-props&quot;);
+    rules[&quot;quotes&quot;] = require(&quot;./rules/quotes&quot;);
+    rules[&quot;radix&quot;] = require(&quot;./rules/radix&quot;);
+    rules[&quot;semi&quot;] = require(&quot;./rules/semi&quot;);
+    rules[&quot;sort-vars&quot;] = require(&quot;./rules/sort-vars&quot;);
+    rules[&quot;space-after-keywords&quot;] = require(&quot;./rules/space-after-keywords&quot;);
+    rules[&quot;space-before-blocks&quot;] = require(&quot;./rules/space-before-blocks&quot;);
+    rules[&quot;space-in-brackets&quot;] = require(&quot;./rules/space-in-brackets&quot;);
+    rules[&quot;space-in-parens&quot;] = require(&quot;./rules/space-in-parens&quot;);
+    rules[&quot;space-infix-ops&quot;] = require(&quot;./rules/space-infix-ops&quot;);
+    rules[&quot;space-return-throw-case&quot;] = require(&quot;./rules/space-return-throw-case&quot;);
+    rules[&quot;space-unary-word-ops&quot;] = require(&quot;./rules/space-unary-word-ops&quot;);
+    rules[&quot;spaced-line-comment&quot;] = require(&quot;./rules/spaced-line-comment&quot;);
+    rules[&quot;strict&quot;] = require(&quot;./rules/strict&quot;);
+    rules[&quot;use-isnan&quot;] = require(&quot;./rules/use-isnan&quot;);
+    rules[&quot;valid-jsdoc&quot;] = require(&quot;./rules/valid-jsdoc&quot;);
+    rules[&quot;valid-typeof&quot;] = require(&quot;./rules/valid-typeof&quot;);
+    rules[&quot;vars-on-top&quot;] = require(&quot;./rules/vars-on-top&quot;);
+    rules[&quot;wrap-iife&quot;] = require(&quot;./rules/wrap-iife&quot;);
+    rules[&quot;wrap-regex&quot;] = require(&quot;./rules/wrap-regex&quot;);
+    rules[&quot;yoda&quot;] = require(&quot;./rules/yoda&quot;);
+
+    return rules;
+};
+},{&quot;./rules/block-scoped-var&quot;:13,&quot;./rules/brace-style&quot;:14,&quot;./rules/camelcase&quot;:15,&quot;./rules/comma-spacing&quot;:16,&quot;./rules/comma-style&quot;:17,&quot;./rules/complexity&quot;:18,&quot;./rules/consistent-return&quot;:19,&quot;./rules/consistent-this&quot;:20,&quot;./rules/curly&quot;:21,&quot;./rules/default-case&quot;:22,&quot;./rules/dot-notation&quot;:23,&quot;./rules/eol-last&quot;:24,&quot;./rules/eqeqeq&quot;:25,&quot;./rules/func-names&quot;:26,&quot;./rules/func-style&quot;:27,&quot;./rules/global-strict&quot;:28,&quot;./rules/guard-for-in&quot;:29,&quot;./rules/handle-callback-err&quot;:30,&quot;./rules/key-spacing&quot;:31,&quot;./rules/max-depth&quot;:32,&quot;./rules/max-len&quot;:33,&quot;./rules/max-nested-callbacks&quot;:34,&quot;./rules/max-params&quot;:35,&quot;./rules/max-statements&quot;:36,&quot;./rules/new-cap&quot;:37,&quot;./rules/new-parens&quot;:38,&quot;./rules/no-alert&quot;:39,&quot;./rules/no-array-constructo
 r&quot;:40,&quot;./rules/no-bitwise&quot;:41,&quot;./rules/no-caller&quot;:42,&quot;./rules/no-catch-shadow&quot;:43,&quot;./rules/no-comma-dangle&quot;:44,&quot;./rules/no-cond-assign&quot;:45,&quot;./rules/no-console&quot;:46,&quot;./rules/no-constant-condition&quot;:47,&quot;./rules/no-control-regex&quot;:48,&quot;./rules/no-debugger&quot;:49,&quot;./rules/no-delete-var&quot;:50,&quot;./rules/no-div-regex&quot;:51,&quot;./rules/no-dupe-keys&quot;:52,&quot;./rules/no-else-return&quot;:53,&quot;./rules/no-empty&quot;:56,&quot;./rules/no-empty-class&quot;:54,&quot;./rules/no-empty-label&quot;:55,&quot;./rules/no-eq-null&quot;:57,&quot;./rules/no-eval&quot;:58,&quot;./rules/no-ex-assign&quot;:59,&quot;./rules/no-extend-native&quot;:60,&quot;./rules/no-extra-bind&quot;:61,&quot;./rules/no-extra-boolean-cast&quot;:62,&quot;./rules/no-extra-parens&quot;:63,&quot;./rules/no-extra-semi&quot;:64,&quot;./rules/no-extra-strict&quot;:65,&quot;./rules/no-fallthrough&quot;:66,&quot;./ru
 les/no-floating-decimal&quot;:67,&quot;./rules/no-func-assign&quot;:68,&quot;./rules/no-implied-eval&quot;:69,&quot;./rules/no-inner-declarations&quot;:70,&quot;./rules/no-invalid-regexp&quot;:71,&quot;./rules/no-iterator&quot;:72,&quot;./rules/no-label-var&quot;:73,&quot;./rules/no-labels&quot;:74,&quot;./rules/no-lone-blocks&quot;:75,&quot;./rules/no-lonely-if&quot;:76,&quot;./rules/no-loop-func&quot;:77,&quot;./rules/no-mixed-requires&quot;:78,&quot;./rules/no-mixed-spaces-and-tabs&quot;:79,&quot;./rules/no-multi-spaces&quot;:80,&quot;./rules/no-multi-str&quot;:81,&quot;./rules/no-multiple-empty-lines&quot;:82,&quot;./rules/no-native-reassign&quot;:83,&quot;./rules/no-negated-in-lhs&quot;:84,&quot;./rules/no-nested-ternary&quot;:85,&quot;./rules/no-new&quot;:90,&quot;./rules/no-new-func&quot;:86,&quot;./rules/no-new-object&quot;:87,&quot;./rules/no-new-require&quot;:88,&quot;./rules/no-new-wrappers&quot;:89,&quot;./rules/no-obj-calls&quot;:91,&quot;./rules/no-octal&quot;:
 93,&quot;./rules/no-octal-escape&quot;:92,&quot;./rules/no-path-concat&quot;:94,&quot;./rules/no-plusplus&quot;:95,&quot;./rules/no-process-env&quot;:96,&quot;./rules/no-process-exit&quot;:97,&quot;./rules/no-proto&quot;:98,&quot;./rules/no-redeclare&quot;:99,&quot;./rules/no-regex-spaces&quot;:100,&quot;./rules/no-reserved-keys&quot;:101,&quot;./rules/no-restricted-modules&quot;:102,&quot;./rules/no-return-assign&quot;:103,&quot;./rules/no-script-url&quot;:104,&quot;./rules/no-self-compare&quot;:105,&quot;./rules/no-sequences&quot;:106,&quot;./rules/no-shadow&quot;:108,&quot;./rules/no-shadow-restricted-names&quot;:107,&quot;./rules/no-space-before-semi&quot;:109,&quot;./rules/no-spaced-func&quot;:110,&quot;./rules/no-sparse-arrays&quot;:111,&quot;./rules/no-sync&quot;:112,&quot;./rules/no-ternary&quot;:113,&quot;./rules/no-trailing-spaces&quot;:114,&quot;./rules/no-undef&quot;:116,&quot;./rules/no-undef-init&quot;:115,&quot;./rules/no-undefined&quot;:117,&quot;./rules/no-u
 nderscore-dangle&quot;:118,&quot;./rules/no-unreachable&quot;:119,&quot;./rules/no-unused-expressions&quot;:120,&quot;./rules/no-unused-vars&quot;:121,&quot;./rules/no-use-before-define&quot;:122,&quot;./rules/no-void&quot;:123,&quot;./rules/no-warning-comments&quot;:124,&quot;./rules/no-with&quot;:125,&quot;./rules/no-wrap-func&quot;:126,&quot;./rules/one-var&quot;:127,&quot;./rules/padded-blocks&quot;:128,&quot;./rules/quote-props&quot;:129,&quot;./rules/quotes&quot;:130,&quot;./rules/radix&quot;:131,&quot;./rules/semi&quot;:132,&quot;./rules/sort-vars&quot;:133,&quot;./rules/space-after-keywords&quot;:134,&quot;./rules/space-before-blocks&quot;:135,&quot;./rules/space-in-brackets&quot;:136,&quot;./rules/space-in-parens&quot;:137,&quot;./rules/space-infix-ops&quot;:138,&quot;./rules/space-return-throw-case&quot;:139,&quot;./rules/space-unary-word-ops&quot;:140,&quot;./rules/spaced-line-comment&quot;:141,&quot;./rules/strict&quot;:142,&quot;./rules/use-isnan&quot;:143,&quot
 ;./rules/valid-jsdoc&quot;:144,&quot;./rules/valid-typeof&quot;:145,&quot;./rules/vars-on-top&quot;:146,&quot;./rules/wrap-iife&quot;:147,&quot;./rules/wrap-regex&quot;:148,&quot;./rules/yoda&quot;:149}],11:[function(require,module,exports){
+/**
+ * @fileoverview RuleContext utility for rules
+ * @author Nicholas C. Zakas
+ */
+&quot;use strict&quot;;
+
+//------------------------------------------------------------------------------
+// Constants
+//------------------------------------------------------------------------------
+
+var PASSTHROUGHS = [
+        &quot;getSource&quot;,
+        &quot;getSourceLines&quot;,
+        &quot;getTokens&quot;,
+        &quot;getTokensBefore&quot;,
+        &quot;getTokenBefore&quot;,
+        &quot;getTokensAfter&quot;,
+        &quot;getTokenAfter&quot;,
+        &quot;getFirstTokens&quot;,
+        &quot;getFirstToken&quot;,
+        &quot;getLastTokens&quot;,
+        &quot;getLastToken&quot;,
+        &quot;getComments&quot;,
+        &quot;getAncestors&quot;,
+        &quot;getScope&quot;,
+        &quot;getJSDocComment&quot;,
+        &quot;getFilename&quot;
+    ];
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+/**
+ * Acts as an abstraction layer between rules and the main eslint object.
+ * @constructor
+ * @param {string} ruleId The ID of the rule using this object.
+ * @param {eslint} eslint The eslint object.
+ * @param {number} severity The configured severity level of the rule.
+ * @param {array} options The configuration information to be added to the rule.
+ * @param {object} settings The configuration settings passed from the config file.
+ */
+function RuleContext(ruleId, eslint, severity, options, settings) {
+
+    /**
+     * The read-only ID of the rule.
+     */
+    Object.defineProperty(this, &quot;id&quot;, {
+        value: ruleId
+    });
+
+    /**
+     * The read-only options of the rule
+     */
+    Object.defineProperty(this, &quot;options&quot;, {
+        value: options
+    });
+
+    /**
+     * The read-only settings shared between all rules
+     */
+    Object.defineProperty(this, &quot;settings&quot;, {
+        value: settings
+    });
+
+    // copy over passthrough methods
+    PASSTHROUGHS.forEach(function(name) {
+        this[name] = function() {
+            return eslint[name].apply(eslint, arguments);
+        };
+    }, this);
+
+    /**
+     * Passthrough to eslint.report() that automatically assigns the rule ID and severity.
+     * @param {ASTNode} node The AST node related to the message.
+     * @param {Object=} location The location of the error.
+     * @param {string} message The message to display to the user.
+     * @param {Object} opts Optional template data which produces a formatted message
+     *     with symbols being replaced by this object's values.
+     * @returns {void}
+     */
+    this.report = function(node, location, message, opts) {
+        eslint.report(ruleId, severity, node, location, message, opts);
+    };
+
+}
+
+RuleContext.prototype = {
+    constructor: RuleContext
+};
+
+module.exports = RuleContext;
+
+},{}],12:[function(require,module,exports){
+/**
+ * @fileoverview Defines a storage for rules.
+ * @author Nicholas C. Zakas
+ */
+
+&quot;use strict&quot;;
+
+//------------------------------------------------------------------------------
+// Requirements
+//------------------------------------------------------------------------------
+
+var loadRules = require(&quot;./load-rules&quot;);
+
+//------------------------------------------------------------------------------
+// Privates
+//------------------------------------------------------------------------------
+
+var rules = Object.create(null);
+
+//------------------------------------------------------------------------------
+// Public Interface
+//------------------------------------------------------------------------------
+
+/**
+ * Registers a rule module for rule id in storage.
+ * @param {String} ruleId Rule id (file name).
+ * @param {Function} ruleModule Rule handler.
+ * @returns {void}
+ */
+function define(ruleId, ruleModule) {
+    rules[ruleId] = ruleModule;
+}
+
+exports.define = define;
+
+/**
+ * Loads and registers all rules from passed rules directory.
+ * @param {String} [rulesDir] Path to rules directory, may be relative. Defaults to `lib/rules`.
+ * @returns {void}
+ */
+function load(rulesDir) {
+    var newRules = loadRules(rulesDir);
+    Object.keys(newRules).forEach(function(ruleId) {
+        define(ruleId, newRules[ruleId]);
+    });
+}
+
+exports.load = load;
+
+/**
+ * Registers all given rules of a plugin.
+ * @param {Object} pluginRules A key/value map of rule definitions.
+ * @param {String} pluginName The name of the plugin without prefix (`eslint-plugin-`).
+ * @returns {void}
+ */
+exports.import = function (pluginRules, pluginName) {
+    Object.keys(pluginRules).forEach(function (ruleId) {
+        var qualifiedRuleId = pluginName + &quot;/&quot; + ruleId,
+            rule = pluginRules[ruleId];
+
+        define(qualifiedRuleId, rule);
+    });
+};
+
+/**
+ * Access rule handler by id (file name).
+ * @param {String} ruleId Rule id (file name).
+ * @returns {Function} Rule handler.
+ */
+exports.get = function(ruleId) {
+    return rules[ruleId];
+};
+
+/**
+ * Reset rules storage.
+ * Should be used only in tests.
+ * @returns {void}
+ */
+exports.testClear = function() {
+    rules = Object.create(null);
+};
+
+//------------------------------------------------------------------------------
+// Initialization
+//------------------------------------------------------------------------------
+
+// loads built-in rules
+load();
+
+},{&quot;./load-rules&quot;:10}],13:[function(require,module,exports){
+/**
+ * @fileoverview Rule to check for &quot;block scoped&quot; variables by binding context
+ * @author Matt DuVall &lt;http://www.mattduvall.com&gt;
+ */
+&quot;use strict&quot;;
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+    var scopeStack = [];
+
+    //--------------------------------------------------------------------------
+    // Helpers
+    //--------------------------------------------------------------------------
+
+    /**
+     * Determines whether an identifier is in declaration position or is a non-declaration reference.
+     * @param {ASTNode} id The identifier.
+     * @param {ASTNode} parent The identifier's parent AST node.
+     * @returns {Boolean} true when the identifier is in declaration position.
+     */
+    function isDeclaration(id, parent) {
+        switch (parent.type) {
+            case &quot;FunctionDeclaration&quot;:
+            case &quot;FunctionExpression&quot;:
+                return parent.params.indexOf(id) &gt; -1 || id === parent.id;
+
+            case &quot;VariableDeclarator&quot;:
+                return id === parent.id;
+
+            case &quot;CatchClause&quot;:
+                return id === parent.param;
+
+            default:
+                return false;
+        }
+    }
+
+    /**
+     * Determines whether an identifier is in property position.
+     * @param {ASTNode} id The identifier.
+     * @param {ASTNode} parent The identifier's parent AST node.
+     * @returns {Boolean} true when the identifier is in property position.
+     */
+    function isProperty(id, parent) {
+        switch (parent.type) {
+            case &quot;MemberExpression&quot;:
+                return id === parent.property &amp;&amp; !parent.computed;
+
+            case &quot;Property&quot;:
+                return id === parent.key;
+
+            default:
+                return false;
+        }
+    }
+
+    /**
+     * Pushes a new scope object on the scope stack.
+     * @returns {void}
+     */
+    function pushScope() {
+        scopeStack.push([]);
+    }
+
+    /**
+     * Removes the topmost scope object from the scope stack.
+     * @returns {void}
+     */
+    function popScope() {
+        scopeStack.pop();
+    }
+
+    /**
+     * Declares the given names in the topmost scope object.
+     * @param {[String]} names A list of names to declare.
+     * @returns {void}
+     */
+    function declare(names) {
+        [].push.apply(scopeStack[scopeStack.length - 1], names);
+    }
+
+    //--------------------------------------------------------------------------
+    // Public API
+    //--------------------------------------------------------------------------
+
+    function functionHandler(node) {
+        pushScope();
+        declare(node.params.map(function(id) {
+            return id.name;
+        }));
+        declare(node.id ? [node.id.name] : []);
+        declare([&quot;arguments&quot;]);
+    }
+
+    function variableDeclarationHandler(node) {
+        declare(node.declarations.map(function(decl) {
+            return decl.id.name;
+        }));
+    }
+
+    return {
+        &quot;Program&quot;: function() {
+            scopeStack = [context.getScope().variables.map(function(v) {
+                return v.name;
+            })];
+        },
+
+        &quot;BlockStatement&quot;: function(node) {
+            var statements = node.body;
+            pushScope();
+            statements.forEach(function(stmt) {
+                if (stmt.type === &quot;VariableDeclaration&quot;) {
+                    variableDeclarationHandler(stmt);
+                } else if (stmt.type === &quot;FunctionDeclaration&quot;) {
+                    declare([stmt.id.name]);
+                }
+            });
+        },
+
+        &quot;BlockStatement:exit&quot;: popScope,
+
+        &quot;CatchClause&quot;: function(node) {
+            pushScope();
+            declare([node.param.name]);
+        },
+        &quot;CatchClause:exit&quot;: popScope,
+
+        &quot;FunctionDeclaration&quot;: functionHandler,
+        &quot;FunctionDeclaration:exit&quot;: popScope,
+
+        &quot;FunctionExpression&quot;: functionHandler,
+        &quot;FunctionExpression:exit&quot;: popScope,
+
+        &quot;ForStatement&quot;: function(node) {
+            pushScope();
+            if (node.init &amp;&amp; node.init.type === &quot;VariableDeclaration&quot;) {
+                variableDeclarationHandler(node.init);
+            }
+        },
+        &quot;ForStatement:exit&quot;: popScope,
+
+        &quot;ForInStatement&quot;: function(node) {
+            pushScope();
+            if (node.left.type === &quot;VariableDeclaration&quot;) {
+                variableDeclarationHandler(node.left);
+            }
+        },
+        &quot;ForInStatement:exit&quot;: popScope,
+
+        &quot;Identifier&quot;: function(node) {
+            var ancestor = context.getAncestors().pop();
+            if (isDeclaration(node, ancestor) || isProperty(node, ancestor)) {
+                return;
+            }
+            for (var i = 0, l = scopeStack.length; i &lt; l; i++) {
+                if (scopeStack[i].indexOf(node.name) &gt; -1) {
+                    return;
+                }
+            }
+
+            context.report(node, &quot;\&quot;&quot; + node.name + &quot;\&quot; used outside of binding context.&quot;);
+        }
+    };
+
+};
+
+},{}],14:[function(require,module,exports){
+/**
+ * @fileoverview Rule to flag block statements that do not use the one true brace style
+ * @author Ian Christian Myers
+ */
+
+&quot;use strict&quot;;
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+    var style = context.options[0] || &quot;1tbs&quot;;
+    var params = context.options[1] || {};
+
+    var OPEN_MESSAGE = &quot;Opening curly brace does not appear on the same line as controlling statement.&quot;,
+        BODY_MESSAGE = &quot;Statement inside of curly braces should be on next line.&quot;,
+        CLOSE_MESSAGE = &quot;Closing curly brace does not appear on the same line as the subsequent block.&quot;,
+        CLOSE_MESSAGE_SINGLE = &quot;Closing curly brace should be on the same line as opening curly brace or on the line after the previous block.&quot;,
+        CLOSE_MESSAGE_STROUSTRUP = &quot;Closing curly brace appears on the same line as the subsequent block.&quot;;
+
+    //--------------------------------------------------------------------------
+    // Helpers
+    //--------------------------------------------------------------------------
+
+    /**
+     * Binds a list of properties to a function that verifies that the opening
+     * curly brace is on the same line as its controlling statement of a given
+     * node.
+     * @param {...string} The properties to check on the node.
+     * @returns {Function} A function that will perform the check on a node
+     */
+    function checkBlock() {
+        var blockProperties = arguments;
+        return function(node) {
+            [].forEach.call(blockProperties, function(blockProp) {
+                var block = node[blockProp], previousToken, curlyToken, curlyTokenEnd, curlyTokensOnSameLine;
+                block = node[blockProp];
+                if (block &amp;&amp; block.type === &quot;BlockStatement&quot;) {
+                    previousToken = context.getTokenBefore(block);
+                    curlyToken = context.getFirstToken(block);
+                    curlyTokenEnd = context.getLastToken(block);
+                    curlyTokensOnSameLine = curlyToken.loc.start.line === curlyTokenEnd.loc.start.line;
+
+                    if (previousToken.loc.start.line !== curlyToken.loc.start.line) {
+                        context.report(node, OPEN_MESSAGE);
+                    } else if (block.body.length &amp;&amp; params.allowSingleLine) {
+                        if (curlyToken.loc.start.line === block.body[0].loc.start.line &amp;&amp; !curlyTokensOnSameLine) {
+                            context.report(block.body[0], BODY_MESSAGE);
+                        } else if (curlyTokenEnd.loc.start.line === block.body[block.body.length - 1].loc.start.line &amp;&amp; !curlyTokensOnSameLine) {
+                            context.report(block.body[block.body.length - 1], CLOSE_MESSAGE_SINGLE);
+                        }
+                    } else if (block.body.length &amp;&amp; curlyToken.loc.start.line === block.body[0].loc.start.line) {
+                        context.report(block.body[0], BODY_MESSAGE);
+                    }
+                }
+            });
+        };
+    }
+
+    /**
+     * Enforces the configured brace style on IfStatements
+     * @param {ASTNode} node An IfStatement node.
+     * @returns {void}
+     */
+    function checkIfStatement(node) {
+        var tokens;
+
+        checkBlock(&quot;consequent&quot;, &quot;alternate&quot;)(node);
+
+        if (node.alternate &amp;&amp; node.alternate.type === &quot;BlockStatement&quot;) {
+            tokens = context.getTokensBefore(node.alternate, 2);
+            if (style === &quot;1tbs&quot;) {
+                if (tokens[0].loc.start.line !== tokens[1].loc.start.line) {
+                    context.report(node.alternate, CLOSE_MESSAGE);
+                }
+            } else if (style === &quot;stroustrup&quot;) {
+                if (tokens[0].loc.start.line === tokens[1].loc.start.line) {
+                    context.report(node.alternate, CLOSE_MESSAGE_STROUSTRUP);
+                }
+            }
+        }
+    }
+
+    /**
+     * Enforces the configured brace style on TryStatements
+     * @param {ASTNode} node A TryStatement node.
+     * @returns {void}
+     */
+    function checkTryStatement(node) {
+        var tokens;
+
+        checkBlock(&quot;block&quot;, &quot;finalizer&quot;)(node);
+
+        if (node.finalizer &amp;&amp; node.finalizer.type === &quot;BlockStatement&quot;) {
+            tokens = context.getTokensBefore(node.finalizer, 2);
+            if (style === &quot;1tbs&quot;) {
+                if (tokens[0].loc.start.line !== tokens[1].loc.start.line) {
+                    context.report(node.finalizer, CLOSE_MESSAGE);
+                }
+            } else if (style === &quot;stroustrup&quot;) {
+                if (tokens[0].loc.start.line === tokens[1].loc.start.line) {
+                    context.report(node.finalizer, CLOSE_MESSAGE_STROUSTRUP);
+                }
+            }
+        }
+    }
+
+    /**
+     * Enforces the configured brace style on CatchClauses
+     * @param {ASTNode} node A CatchClause node.
+     * @returns {void}
+     */
+    function checkCatchClause(node) {
+        var previousToken = context.getTokenBefore(node),
+            firstToken = context.getFirstToken(node);
+
+        checkBlock(&quot;body&quot;)(node);
+
+        if (node.body &amp;&amp; node.body.type === &quot;BlockStatement&quot;) {
+            if (style === &quot;1tbs&quot;) {
+                if (previousToken.loc.start.line !== firstToken.loc.start.line) {
+                    context.report(node, CLOSE_MESSAGE);
+                }
+            } else if (style === &quot;stroustrup&quot;) {
+                if (previousToken.loc.start.line === firstToken.loc.start.line) {
+                    context.report(node, CLOSE_MESSAGE_STROUSTRUP);
+                }
+            }
+        }
+    }
+
+    /**
+     * Enforces the configured brace style on SwitchStatements
+     * @param {ASTNode} node A SwitchStatement node.
+     * @returns {void}
+     */
+    function checkSwitchStatement(node) {
+        var tokens;
+        if (node.cases &amp;&amp; node.cases.length) {
+            tokens = context.getTokensBefore(node.cases[0], 2);
+            if (tokens[0].loc.start.line !== tokens[1].loc.start.line) {
+                context.report(node, OPEN_MESSAGE);
+            }
+        } else {
+            tokens = context.getLastTokens(node, 3);
+            if (tokens[0].loc.start.line !== tokens[1].loc.start.line) {
+                context.report(node, OPEN_MESSAGE);
+            }
+        }
+    }
+
+    //--------------------------------------------------------------------------
+    // Public API
+    //--------------------------------------------------------------------------
+
+    return {
+        &quot;FunctionDeclaration&quot;: checkBlock(&quot;body&quot;),
+        &quot;FunctionExpression&quot;: checkBlock(&quot;body&quot;),
+        &quot;IfStatement&quot;: checkIfStatement,
+        &quot;TryStatement&quot;: checkTryStatement,
+        &quot;CatchClause&quot;: checkCatchClause,
+        &quot;DoWhileStatement&quot;: checkBlock(&quot;body&quot;),
+        &quot;WhileStatement&quot;: checkBlock(&quot;body&quot;),
+        &quot;WithStatement&quot;: checkBlock(&quot;body&quot;),
+        &quot;ForStatement&quot;: checkBlock(&quot;body&quot;),
+        &quot;ForInStatement&quot;: checkBlock(&quot;body&quot;),
+        &quot;SwitchStatement&quot;: checkSwitchStatement
+    };
+
+};
+
+},{}],15:[function(require,module,exports){
+/**
+ * @fileoverview Rule to flag non-camelcased identifiers
+ * @author Nicholas C. Zakas
+ */
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+    &quot;use strict&quot;;
+
+    //--------------------------------------------------------------------------
+    // Helpers
+    //--------------------------------------------------------------------------
+
+    /**
+     * Checks if a string contains an underscore and isn't all upper-case
+     * @param {String} name The string to check.
+     * @returns {boolean} if the string is underscored
+     * @private
+     */
+    function isUnderscored(name) {
+
+        // if there's an underscore, it might be A_CONSTANT, which is okay
+        return name.indexOf(&quot;_&quot;) &gt; -1 &amp;&amp; name !== name.toUpperCase();
+    }
+
+    /**
+     * Reports an AST node as a rule violation.
+     * @param {ASTNode} node The node to report.
+     * @returns {void}
+     * @private
+     */
+    function report(node) {
+        context.report(node, &quot;Identifier '{{name}}' is not in camel case.&quot;, { name: node.name });
+    }
+
+    return {
+
+        &quot;Identifier&quot;: function(node) {
+
+            // Leading and trailing underscores are commonly used to flag private/protected identifiers, strip them
+            var name = node.name.replace(/^_+|_+$/g, &quot;&quot;),
+                effectiveParent = (node.parent.type === &quot;MemberExpression&quot;) ? node.parent.parent : node.parent;
+
+            // MemberExpressions get special rules
+            if (node.parent.type === &quot;MemberExpression&quot;) {
+
+                // Always report underscored object names
+                if (node.parent.object.type === &quot;Identifier&quot; &amp;&amp;
+                        node.parent.object.name === node.name &amp;&amp;
+                        isUnderscored(name)) {
+                    report(node);
+
+                // Report AssignmentExpressions only if they are the left side of the assignment
+                } else if (effectiveParent.type === &quot;AssignmentExpression&quot; &amp;&amp;
+                        isUnderscored(name) &amp;&amp;
+                        (effectiveParent.right.type !== &quot;MemberExpression&quot; ||
+                        effectiveParent.left.type === &quot;MemberExpression&quot; &amp;&amp;
+                        effectiveParent.left.property.name === node.name)) {
+                    report(node);
+                }
+
+            // Report anything that is underscored that isn't a CallExpression
+            } else if (isUnderscored(name) &amp;&amp; effectiveParent.type !== &quot;CallExpression&quot;) {
+                report(node);
+            }
+        }
+    };
+
+};
+
+},{}],16:[function(require,module,exports){
+/**
+ * @fileoverview Comma spacing - validates spacing before and after comma
+ * @author Vignesh Anand aka vegetableman.
+ * @copyright 2014 Vignesh Anand. All rights reserved.
+ */
+&quot;use strict&quot;;
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+    var options = {
+        before: context.options[0] ? !!context.options[0].before : false,
+        after: context.options[0] ? !!context.options[0].after : true
+    };
+
+    //--------------------------------------------------------------------------
+    // Helpers
+    //--------------------------------------------------------------------------
+
+    /**
+     * Determines whether two adjacent tokens have whitespace between them.
+     * @param {Object} left - The left token object.
+     * @param {Object} right - The right token object.
+     * @returns {boolean} Whether or not there is space between the tokens.
+     */
+    function isSpaced(left, right) {
+        return left.range[1] &lt; right.range[0];
+    }
+
+    /**
+     * Run report.
+     * @param {ASTNode} node The binary expression node to check.
+     * @param {string} msg The error msg to show.
+     * @private
+     * @returns {void}
+     */
+    function report(node, msg) {
+        context.report(node, msg);
+    }
+
+    /**
+     * Show space required message.
+     * @param {string} dir The location of spacing.
+     * @private
+     * @returns {string} The spacing error msg.
+     */
+    function getSpaceReqMsg(dir) {
+        return &quot;A space is required &quot; + dir + &quot; ','.&quot;;
+    }
+
+    /**
+     * Show no space message.
+     * @param {string} dir The location of spacing
+     * @private
+     * @returns {string} The spacing error msg.
+     */
+    function getNoSpaceMsg(dir) {
+        return &quot;There should be no space &quot; + dir + &quot; ','.&quot;;
+    }
+
+    /**
+     * Validates the spacing before and after commas.
+     * @param {ASTNode} node The binary expression node to check.
+     * @param {string} property The property of the node.
+     * @private
+     * @returns {void}
+     */
+    function validateCommaSpacing(node, property) {
+        var items = node[property];
+
+        if (items &amp;&amp; items.length &gt; 1) {
+            items.forEach(function(item, index) {
+                var tokenBefore = context.getTokenBefore(item),
+                    itemBefore = items[index - 1],
+                    tokenEndLine;
+
+                if (tokenBefore &amp;&amp; tokenBefore.value === &quot;,&quot;) {
+                    tokenEndLine = tokenBefore.loc.end.line;
+
+                    // single line
+                    if (tokenEndLine === itemBefore.loc.end.line &amp;&amp;
+                        tokenEndLine === item.loc.start.line) {
+                        if (options.before &amp;&amp; options.after) {
+                            if (!isSpaced(itemBefore, tokenBefore)) {
+                                report(item, getSpaceReqMsg(&quot;before&quot;));
+                            }
+                            if (!isSpaced(tokenBefore, item)) {
+                                report(item, getSpaceReqMsg(&quot;after&quot;));
+                            }
+                        } else if (options.before) {
+                            if (!isSpaced(itemBefore, tokenBefore)) {
+                                report(item, getSpaceReqMsg(&quot;before&quot;));
+                            }
+                            if (isSpaced(tokenBefore, item)) {
+                                report(item, getNoSpaceMsg(&quot;after&quot;));
+                            }
+                        } else if (options.after) {
+                            if (!isSpaced(tokenBefore, item)) {
+                                report(item, getSpaceReqMsg(&quot;after&quot;));
+                            }
+                            if (isSpaced(itemBefore, tokenBefore)) {
+                                report(item, getNoSpaceMsg(&quot;before&quot;));
+                            }
+                        } else {
+                            if (isSpaced(itemBefore, tokenBefore)) {
+                                report(item, getNoSpaceMsg(&quot;before&quot;));
+                            }
+                            if (isSpaced(tokenBefore, item)) {
+                                report(item, getNoSpaceMsg(&quot;after&quot;));
+                            }
+                        }
+                    }
+                }
+            });
+        }
+    }
+
+    //--------------------------------------------------------------------------
+    // Public
+    //--------------------------------------------------------------------------
+
+    return {
+        &quot;VariableDeclaration&quot;: function(node) {
+            validateCommaSpacing(node, &quot;declarations&quot;);
+        },
+        &quot;ObjectExpression&quot;: function(node) {
+            validateCommaSpacing(node, &quot;properties&quot;);
+        },
+        &quot;ArrayExpression&quot;: function(node) {
+            validateCommaSpacing(node, &quot;elements&quot;);
+        },
+        &quot;SequenceExpression&quot;: function(node) {
+            validateCommaSpacing(node, &quot;expressions&quot;);
+        },
+        &quot;FunctionExpression&quot;: function(node) {
+            validateCommaSpacing(node, &quot;params&quot;);
+        },
+        &quot;FunctionDeclaration&quot;: function(node) {
+            validateCommaSpacing(node, &quot;params&quot;);
+        }
+    };
+
+};
+
+},{}],17:[function(require,module,exports){
+/**
+ * @fileoverview Comma style - enforces comma styles of two types: last and first
+ * @author Vignesh Anand aka vegetableman
+ * @copyright 2014 Vignesh Anand. All rights reserved.
+ */
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+    &quot;use strict&quot;;
+
+    var style = context.options[0] || &quot;last&quot;;
+
+    //--------------------------------------------------------------------------
+    // Helpers
+    //--------------------------------------------------------------------------
+
+    /**
+     * Checks the comma placement with regards to a declaration/property/element
+     * @param {ASTNode} node The binary expression node to check
+     * @private
+     * @returns {void}
+     */
+    function validateComma(node) {
+        var items = node.declarations || node.properties || node.elements;
+
+        if (items.length &gt; 1) {
+            items.forEach(function(item, index) {
+                var tokenBefore = context.getTokenBefore(item),
+                    itemBefore = items[index - 1];
+
+                if (tokenBefore.value === &quot;,&quot;) {
+                    // if single line
+                    if (tokenBefore.loc.end.line === item.loc.start.line &amp;&amp;
+                        tokenBefore.loc.end.line === itemBefore.loc.end.line) {
+                        return;
+                    }
+                    // lone comma
+                    else if (tokenBefore.loc.end.line !== item.loc.start.line &amp;&amp;
+                        tokenBefore.loc.end.line !== itemBefore.loc.end.line) {
+                        context.report(item, {
+                            line: tokenBefore.loc.end.line,
+                            column: tokenBefore.loc.start.column
+                        }, &quot;Bad line breaking before and after ','.&quot;);
+                    }
+                    else if (style === &quot;first&quot; &amp;&amp;
+                        tokenBefore.loc.start.line !== item.loc.start.line) {
+                        context.report(item, &quot;',' should be placed first.&quot;);
+                    }
+                    else if (style === &quot;last&quot; &amp;&amp;
+                        tokenBefore.loc.end.line === item.loc.start.line) {
+                        context.report(item, {
+                            line: itemBefore.loc.end.line,
+                            column: itemBefore.loc.end.column
+                        }, &quot;',' should be placed last.&quot;);
+                    }
+                }
+            });
+        }
+    }
+
+    //--------------------------------------------------------------------------
+    // Public
+    //--------------------------------------------------------------------------
+
+    return {
+        &quot;VariableDeclaration&quot;: validateComma,
+        &quot;ObjectExpression&quot;: validateComma,
+        &quot;ArrayExpression&quot;: validateComma
+    };
+
+};
+
+},{}],18:[function(require,module,exports){
+/**
+ * @fileoverview Counts the cyclomatic complexity of each function of the script. See http://en.wikipedia.org/wiki/Cyclomatic_complexity.
+ * Counts the number of if, conditional, for, whilte, try, switch/case,
+ * @author Patrick Brosset
+ */
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+    &quot;use strict&quot;;
+
+    var THRESHOLD = context.options[0];
+
+    //--------------------------------------------------------------------------
+    // Helpers
+    //--------------------------------------------------------------------------
+
+    // Using a stack to store complexity (handling nested functions)
+    var fns = [];
+
+    // When parsing a new function, store it in our function stack
+    function startFunction() {
+        fns.push(1);
+    }
+
+    function endFunction(node) {
+        var complexity = fns.pop(), name = &quot;anonymous&quot;;
+
+        if (node.id) {
+            name = node.id.name;
+        }
+        if (complexity &gt; THRESHOLD) {
+            context.report(node, &quot;Function '{{name}}' has a complexity of {{complexity}}.&quot;, { name: name, complexity: complexity });
+        }
+    }
+
+    function increaseComplexity() {
+        if (fns.length) {
+            fns[fns.length - 1] ++;
+        }
+    }
+
+    function increaseSwitchComplexity(node) {
+        // Avoiding `default`
+        if (node.test) {
+            increaseComplexity(node);
+        }
+    }
+
+    function increaseLogicalComplexity(node) {
+        // Avoiding &amp;&amp;
+        if (node.operator === &quot;||&quot;) {
+            increaseComplexity(node);
+        }
+    }
+
+    //--------------------------------------------------------------------------
+    // Public API
+    //--------------------------------------------------------------------------
+
+    return {
+        &quot;FunctionDeclaration&quot;: startFunction,
+        &quot;FunctionExpression&quot;: startFunction,
+        &quot;FunctionDeclaration:exit&quot;: endFunction,
+        &quot;FunctionExpression:exit&quot;: endFunction,
+
+        &quot;CatchClause&quot;: increaseComplexity,
+        &quot;ConditionalExpression&quot;: increaseComplexity,
+        &quot;LogicalExpression&quot;: increaseLogicalComplexity,
+        &quot;ForStatement&quot;: increaseComplexity,
+        &quot;ForInStatement&quot;: increaseComplexity,
+        &quot;IfStatement&quot;: increaseComplexity,
+        &quot;SwitchCase&quot;: increaseSwitchComplexity,
+        &quot;WhileStatement&quot;: increaseComplexity,
+        &quot;DoWhileStatement&quot;: increaseComplexity
+    };
+
+};
+
+},{}],19:[function(require,module,exports){
+/**
+ * @fileoverview Rule to flag consistent return values
+ * @author Nicholas C. Zakas
+ */
+&quot;use strict&quot;;
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+    var functions = [];
+
+    //--------------------------------------------------------------------------
+    // Helpers
+    //--------------------------------------------------------------------------
+
+    function enterFunction() {
+        functions.push({});
+    }
+
+    function exitFunction() {
+        functions.pop();
+    }
+
+
+    //--------------------------------------------------------------------------
+    // Public
+    //--------------------------------------------------------------------------
+
+    return {
+
+        &quot;FunctionDeclaration&quot;: enterFunction,
+        &quot;FunctionExpression&quot;: enterFunction,
+        &quot;FunctionDeclaration:exit&quot;: exitFunction,
+        &quot;FunctionExpression:exit&quot;: exitFunction,
+
+        &quot;ReturnStatement&quot;: function(node) {
+
+            var returnInfo = functions[functions.length - 1],
+                returnTypeDefined = &quot;type&quot; in returnInfo;
+
+            if (returnTypeDefined) {
+
+                if (returnInfo.type !== !!node.argument) {
+                    context.report(node, &quot;Expected &quot; + (returnInfo.type ? &quot;a&quot; : &quot;no&quot;) + &quot; return value.&quot;);
+                }
+
+            } else {
+                returnInfo.type = !!node.argument;
+            }
+
+        }
+    };
+
+};
+
+},{}],20:[function(require,module,exports){
+/**
+ * @fileoverview Rule to enforce consistent naming of &quot;this&quot; context variables
+ * @author Raphael Pigulla
+ */
+&quot;use strict&quot;;
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+    return {
+
+        &quot;VariableDeclaration&quot;: function(node) {
+            var alias = context.options[0];
+
+            node.declarations.forEach(function(declaration) {
+                if (declaration.id.name === alias &amp;&amp;
+                        !(declaration.init &amp;&amp; declaration.init.type === &quot;ThisExpression&quot;)) {
+
+                    context.report(
+                        node,
+                        &quot;Designated 'this' alias '{{alias}}' is not assigned &quot; +
+                            &quot;to the current execution context.&quot;,
+                        { alias: declaration.id.name }
+                    );
+                }
+
+                if (declaration.init &amp;&amp;
+                        declaration.init.type === &quot;ThisExpression&quot; &amp;&amp;
+                        declaration.id.name !== alias) {
+
+                    context.report(
+                        node,
+                        &quot;Unexpected alias '{{alias}}' for 'this'.&quot;,
+                        { alias: declaration.id.name }
+                    );
+                }
+            });
+        }
+    };
+
+};
+
+},{}],21:[function(require,module,exports){
+/**
+ * @fileoverview Rule to flag statements without curly braces
+ * @author Nicholas C. Zakas
+ */
+&quot;use strict&quot;;
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+    var multiOnly = (context.options[0] === &quot;multi&quot;);
+
+    //--------------------------------------------------------------------------
+    // Helpers
+    //--------------------------------------------------------------------------
+
+    /**
+     * Checks the body of a node to see if it's a block statement. Depending on
+     * the rule options, reports the appropriate problems.
+     * @param {ASTNode} node The node to report if there's a problem.
+     * @param {ASTNode} body The body node to check for blocks.
+     * @param {string} name The name to report if there's a problem.
+     * @param {string} suffix Additional string to add to the end of a report.
+     * @returns {void}
+     */
+    function checkBody(node, body, name, suffix) {
+        var hasBlock = (body.type === &quot;BlockStatement&quot;);
+
+        if (multiOnly) {
+            if (hasBlock &amp;&amp; body.body.length === 1) {
+                context.report(node, &quot;Unnecessary { after '{{name}}'{{suffix}}.&quot;,
+                    {
+                        name: name,
+                        suffix: (suffix ? &quot; &quot; + suffix : &quot;&quot;)
+                    }
+                );
+            }
+        } else {
+            if (!hasBlock) {
+                context.report(node, &quot;Expected { after '{{name}}'{{suffix}}.&quot;,
+                    {
+                        name: name,
+                        suffix: (suffix ? &quot; &quot; + suffix : &quot;&quot;)
+                    }
+                );
+            }
+        }
+    }
+
+    //--------------------------------------------------------------------------
+    // Public
+    //--------------------------------------------------------------------------
+
+    return {
+
+        &quot;IfStatement&quot;: function(node) {
+
+            checkBody(node, node.consequent, &quot;if&quot;, &quot;condition&quot;);
+
+            if (node.alternate &amp;&amp; node.alternate.type !== &quot;IfStatement&quot;) {
+                checkBody(node, node.alternate, &quot;else&quot;);
+            }
+
+        },
+
+        &quot;WhileStatement&quot;: function(node) {
+            checkBody(node, node.body, &quot;while&quot;, &quot;condition&quot;);
+        },
+
+        &quot;DoWhileStatement&quot;: function (node) {
+            checkBody(node, node.body, &quot;do&quot;);
+        },
+
+        &quot;ForStatement&quot;: function(node) {
+            checkBody(node, node.body, &quot;for&quot;, &quot;condition&quot;);
+        }
+    };
+
+};
+
+},{}],22:[function(require,module,exports){
+/**
+ * @fileoverview require default case in switch statements
+ * @author Aliaksei Shytkin
+ */
+&quot;use strict&quot;;
+
+var COMMENT_VALUE = &quot;no default&quot;;
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+    //--------------------------------------------------------------------------
+    // Helpers
+    //--------------------------------------------------------------------------
+
+    /**
+     * Shortcut to get last element of array
+     * @param  {*[]} collection Array
+     * @returns {*} Last element
+     */
+    function last(collection) {
+        return collection[collection.length - 1];
+    }
+
+    //--------------------------------------------------------------------------
+    // Public
+    //--------------------------------------------------------------------------
+
+    return {
+
+        &quot;SwitchStatement&quot;: function(node) {
+
+            if (!node.cases.length) {
+                // skip check of empty switch because there is no easy way
+                // to extract comments inside it now
+                return;
+            }
+
+            var hasDefault = node.cases.some(function(v) {
+                return v.test === null;
+            });
+
+            if (!hasDefault) {
+
+                var comment;
+                var comments;
+
+                var lastCase = last(node.cases);
+                comments = context.getComments(lastCase).trailing;
+
+                if (comments.length) {
+                    comment = last(comments);
+                }
+
+                if (!comment || comment.value.trim() !== COMMENT_VALUE) {
+                    context.report(node, &quot;Expected a default case.&quot;);
+                }
+            }
+        }
+    };
+};
+
+},{}],23:[function(require,module,exports){
+/**
+ * @fileoverview Rule to warn about using dot notation instead of square bracket notation when possible.
+ * @author Josh Perez
+ */
+&quot;use strict&quot;;
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+var validIdentifier = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/;
+var keywords = [
+    &quot;this&quot;,
+    &quot;function&quot;,
+    &quot;if&quot;,
+    &quot;return&quot;,
+    &quot;var&quot;,
+    &quot;else&quot;,
+    &quot;for&quot;,
+    &quot;new&quot;,
+    &quot;arguments&quot;,
+    &quot;in&quot;,
+    &quot;typeof&quot;,
+    &quot;while&quot;,
+    &quot;case&quot;,
+    &quot;break&quot;,
+    &quot;try&quot;,
+    &quot;catch&quot;,
+    &quot;delete&quot;,
+    &quot;throw&quot;,
+    &quot;switch&quot;,
+    &quot;continue&quot;,
+    &quot;default&quot;,
+    &quot;instanceof&quot;,
+    &quot;do&quot;,
+    &quot;void&quot;,
+    &quot;finally&quot;,
+    &quot;with&quot;,
+    &quot;debugger&quot;,
+    &quot;eval&quot;,
+    &quot;implements&quot;,
+    &quot;interface&quot;,
+    &quot;package&quot;,
+    &quot;private&quot;,
+    &quot;protected&quot;,
+    &quot;public&quot;,
+    &quot;static&quot;,
+    &quot;yield&quot;,
+    &quot;let&quot;,
+    &quot;class&quot;,
+    &quot;enum&quot;,
+    &quot;export&quot;,
+    &quot;extends&quot;,
+    &quot;import&quot;,
+    &quot;super&quot;,
+    &quot;true&quot;,
+    &quot;false&quot;,
+    &quot;null&quot;,
+    &quot;abstract&quot;,
+    &quot;boolean&quot;,
+    &quot;byte&quot;,
+    &quot;char&quot;,
+    &quot;const&quot;,
+    &quot;double&quot;,
+    &quot;final&quot;,
+    &quot;float&quot;,
+    &quot;goto&quot;,
+    &quot;int&quot;,
+    &quot;long&quot;,
+    &quot;native&quot;,
+    &quot;short&quot;,
+    &quot;synchronized&quot;,
+    &quot;throws&quot;,
+    &quot;transient&quot;,
+    &quot;volatile&quot;
+];
+
+function canBeWrittenInDotNotation(node) {
+    return node.computed === true &amp;&amp;
+        node.property.type === &quot;Literal&quot; &amp;&amp;
+        validIdentifier.test(node.property.value) &amp;&amp;
+        keywords.indexOf(&quot;&quot; + node.property.value) === -1;
+}
+
+module.exports = function(context) {
+    return {
+        &quot;MemberExpression&quot;: function(node) {
+            if (canBeWrittenInDotNotation(node)) {
+                context.report(node, &quot;['&quot; + node.property.value + &quot;'] is better written in dot notation.&quot;);
+            }
+        }
+    };
+};
+
+},{}],24:[function(require,module,exports){
+/**
+ * @fileoverview Require file to end with single newline.
+ * @author Nodeca Team &lt;https://github.com/nodeca&gt;
+ */
+&quot;use strict&quot;;
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+    //--------------------------------------------------------------------------
+    // Public
+    //--------------------------------------------------------------------------
+
+    return {
+
+        &quot;Program&quot;: function checkBadEOF(node) {
+            // Get the whole source code, not for node only.
+            var src = context.getSource(), location = {column: 1};
+
+            if (src.length === 0) {
+                return;
+            }
+
+            if (src[src.length - 1] !== &quot;\n&quot;) {
+                // file is not newline-terminated
+                location.line = src.split(/\n/g).length;
+                context.report(node, location, &quot;Newline required at end of file but not found.&quot;);
+            } else if (/\n\s*\n$/.test(src)) {
+                // last line is empty
+                location.line = src.split(/\n/g).length - 1;
+                context.report(node, location, &quot;Unexpected blank line at end of file.&quot;);
+            }
+        }
+
+    };
+
+};
+
+},{}],25:[function(require,module,exports){
+/**
+ * @fileoverview Rule to flag statements that use != and == instead of !== and ===
+ * @author Nicholas C. Zakas
+ */
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+    &quot;use strict&quot;;
+
+    /**
+     * Checks if either operand of a binary expression is a typeof operation
+     * @param {ASTNode} node The node to check
+     * @returns {boolean} if one of the operands is typeof
+     * @private
+     */
+    function isTypeOf(node) {
+        return [node.left, node.right].some(function(node) {
+            return node.type === &quot;UnaryExpression&quot; &amp;&amp; node.operator === &quot;typeof&quot;;
+        });
+    }
+
+    /**
+     * Checks if operands are literals of the same type (via typeof)
+     * @param {ASTNode} node The node to check
+     * @returns {boolean} if operands are of same type
+     * @private
+     */
+    function areLiteralsAndSameType(node) {
+        return node.left.type === &quot;Literal&quot; &amp;&amp; node.right.type === &quot;Literal&quot; &amp;&amp;
+                typeof node.left.value === typeof node.right.value;
+    }
+
+    /**
+     * Checks if one of the operands is a literal null
+     * @param {ASTNode} node The node to check
+     * @returns {boolean} if operands are null
+     * @private
+     */
+    function isNullCheck(node) {
+        return (node.right.type === &quot;Literal&quot; &amp;&amp; node.right.value === null) ||
+                (node.left.type === &quot;Literal&quot; &amp;&amp; node.left.value === null);
+    }
+
+    /**
+     * Gets the location (line and column) of the binary expression's operator
+     * @param {ASTNode} node The binary expression node to check
+     * @param {String} operator The operator to find
+     * @returns {Object} { line, column } location of operator
+     * @private
+     */
+    function getOperatorLocation(node) {
+        var opToken = context.getTokens(node)[context.getTokens(node.left).length];
+        return {line: opToken.loc.start.line, column: opToken.loc.start.column};
+    }
+
+    return {
+        &quot;BinaryExpression&quot;: function(node) {
+            if (node.operator !== &quot;==&quot; &amp;&amp; node.operator !== &quot;!=&quot;) {
+                return;
+            }
+
+            if (context.options[0] === &quot;smart&quot; &amp;&amp; (isTypeOf(node) ||
+                    areLiteralsAndSameType(node)) || isNullCheck(node)) {
+                return;
+            }
+
+            if (context.options[0] === &quot;allow-null&quot; &amp;&amp; isNullCheck(node)) {
+                return;
+            }
+
+            context.report(
+                node, getOperatorLocation(node),
+                &quot;Expected '{{op}}=' and instead saw '{{op}}'.&quot;,
+                {op: node.operator}
+            );
+        }
+    };
+
+};
+
+},{}],26:[function(require,module,exports){
+/**
+ * @fileoverview Rule to warn when a function expression does not have a name.
+ * @author Kyle T. Nunery
+ */
+ &quot;use strict&quot;;
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+    return {
+        &quot;FunctionExpression&quot;: function(node) {
+
+            var name = node.id &amp;&amp; node.id.name;
+
+            if (!name) {
+                context.report(node, &quot;Missing function expression name.&quot;);
+            }
+        }
+    };
+};
+
+},{}],27:[function(require,module,exports){
+/**
+ * @fileoverview Rule to enforce a particular function style
+ * @author Nicholas C. Zakas
+ */
+&quot;use strict&quot;;
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+    var style = context.options[0],
+        enforceDeclarations = (style === &quot;declaration&quot;);
+
+    return {
+
+        &quot;FunctionDeclaration&quot;: function(node) {
+            if (!enforceDeclarations) {
+                context.report(node, &quot;Expected a function expression.&quot;);
+            }
+        },
+
+        &quot;FunctionExpression&quot;: function() {
+            var parent = context.getAncestors().pop();
+
+            if (enforceDeclarations &amp;&amp; parent.type === &quot;VariableDeclarator&quot;) {
+                context.report(parent, &quot;Expected a function declaration.&quot;);
+            }
+        }
+    };
+
+};
+
+},{}],28:[function(require,module,exports){
+/**
+ * @fileoverview Rule to flag or require global strict mode.
+ * @author Nicholas C. Zakas
+ */
+&quot;use strict&quot;;
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+    var mode = context.options[0];
+
+    if (mode === &quot;always&quot;) {
+
+        return {
+            &quot;Program&quot;: function(node) {
+                if (node.body.length &gt; 0) {
+                    var statement = node.body[0];
+
+                    if (!(statement.type === &quot;ExpressionStatement&quot; &amp;&amp; statement.expression.value === &quot;use strict&quot;)) {
+                        context.report(node, &quot;Use the global form of \&quot;use strict\&quot;.&quot;);
+                    }
+                }
+            }
+        };
+
+    } else { // mode = &quot;never&quot;
+
+        return {
+            &quot;ExpressionStatement&quot;: function(node) {
+                var parent = context.getAncestors().pop();
+
+                if (node.expression.value === &quot;use strict&quot; &amp;&amp; parent.type === &quot;Program&quot;) {
+                    context.report(node, &quot;Use the function form of \&quot;use strict\&quot;.&quot;);
+                }
+            }
+        };
+
+    }
+
+};
+
+},{}],29:[function(require,module,exports){
+/**
+ * @fileoverview Rule to flag for-in loops without if statements inside
+ * @author Nicholas C. Zakas
+ */
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+    &quot;use strict&quot;;
+
+    return {
+
+        &quot;ForInStatement&quot;: function(node) {
+
+            /*
+             * If the for-in statement has {}, then the real body is the body
+             * of the BlockStatement. Otherwise, just use body as provided.
+             */
+            var body = node.body.type === &quot;BlockStatement&quot; ? node.body.body[0] : node.body;
+
+            if (body &amp;&amp; body.type !== &quot;IfStatement&quot;) {
+                context.report(node, &quot;The body of a for-in should be wrapped in an if statement to filter unwanted properties from the prototype.&quot;);
+            }
+        }
+    };
+
+};
+
+},{}],30:[function(require,module,exports){
+/**
+ * @fileoverview Ensure handling of errors when we know they exist.
+ * @author Jamund Ferguson
+ */
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+    &quot;use strict&quot;;
+
+    var errorArgument = context.options[0] || &quot;err&quot;;
+    var callbacks = [];
+    var scopes = 0;
+
+    /**
+     * Checks if the given argument should be interpreted as a regexp pattern.
+     * @param {string} stringToCheck The string which should be checked.
+     * @returns {boolean} Whether or not the string should be interpreted as a pattern.
+     */
+    function isPattern(stringToCheck) {
+        var firstChar = stringToCheck[0];
+        return firstChar === &quot;^&quot;;
+    }
+
+    /**
+     * Checks if the given name matches the configured error argument.
+     * @param {string} name The name which should be compared.
+     * @returns {boolean} Whether or not the given name matches the configured error variable name.
+     */
+    function matchesConfiguredErrorName(name) {
+        if (isPattern(errorArgument)) {
+            var regexp = new RegExp(errorArgument);
+            return regexp.test(name);
+        }
+        return name === errorArgument;
+    }
+
+    /**
+     * Check the arguments to see if we need to start tracking the error object.
+     * @param {ASTNode} node The AST node to check.
+     * @returns {void}
+     */
+    function startFunction(node) {
+
+        // keep track of nested scopes
+        scopes++;
+
+        // check if the first argument matches our argument name
+        var firstArg = node.params &amp;&amp; node.params[0];
+        if (firstArg &amp;&amp; matchesConfiguredErrorName(firstArg.name)) {
+            callbacks.push({handled: false, depth: scopes, errorVariableName: firstArg.name});
+        }
+    }
+
+    /**
+     * At the end of a function check to see if the error was handled.
+     * @param {ASTNode} node The AST node to check.
+     * @returns {void}
+     */
+    function endFunction(node) {
+
+        var callback = callbacks[callbacks.length - 1] || {};
+
+        // check if a callback is ending, if so pop it off the stack
+        if (callback.depth === scopes) {
+            callbacks.pop();
+
+            // check if there were no handled errors since the last callback
+            if (!callback.handled) {
+                context.report(node, &quot;Expected error to be handled.&quot;);
+            }
+        }
+
+        // less nested functions
+        scopes--;
+
+    }
+
+    /**
+     * Check to see if we're handling the error object properly.
+     * @param {ASTNode} node The AST node to check.
+     * @returns {void}
+     */
+    function checkForError(node) {
+        if (callbacks.length &gt; 0) {
+            var callback = callbacks[callbacks.length - 1] || {};
+
+            // make sure the node's name matches our error argument name
+            var isAboutError = node.name === callback.errorVariableName;
+
+            // we don't consider these use cases as &quot;handling&quot; the error
+            var doNotCount = [&quot;FunctionDeclaration&quot;, &quot;FunctionExpression&quot;, &quot;CatchClause&quot;];
+
+            // make sure this identifier isn't used as part of one of them
+            var isHandled = doNotCount.indexOf(node.parent.type) === -1;
+
+            if (isAboutError &amp;&amp; isHandled) {
+                // record that this callback handled its error
+                callback.handled = true;
+            }
+        }
+    }
+
+    return {
+        &quot;FunctionDeclaration&quot;: startFunction,
+        &quot;FunctionExpression&quot;: startFunction,
+        &quot;Identifier&quot;: checkForError,
+        &quot;FunctionDeclaration:exit&quot;: endFunction,
+        &quot;FunctionExpression:exit&quot;: endFunction
+    };
+
+};
+
+},{}],31:[function(require,module,exports){
+/**
+ * @fileoverview Rule to specify spacing of object literal keys and values
+ * @author Brandon Mills
+ * @copyright 2014 Brandon Mills. All rights reserved.
+ */
+&quot;use strict&quot;;
+
+//------------------------------------------------------------------------------
+// Helpers
+//------------------------------------------------------------------------------
+
+/**
+ * Gets an object literal property's key as the identifier name or string value.
+ * @param {ASTNode} property Property node whose key to retrieve.
+ * @returns {string} The property's key.
+ */
+function getKey(property) {
+    return property.key.name || property.key.value;
+}
+
+/**
+ * Gets the number of characters in a key, including quotes around string keys.
+ * @param {ASTNode} property Property of on object literal.
+ * @returns {int} Width of the key, including string quotes where present.
+ */
+function getKeyWidth(property) {
+    var key = property.key;
+    return (key.type === &quot;Identifier&quot; ? key.name : key.raw).length;
+}
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+var messages = {
+    key: &quot;{{error}} space after key \&quot;{{key}}\&quot;.&quot;,
+    value: &quot;{{error}} space before value for key \&quot;{{key}}\&quot;.&quot;
+};
+
+module.exports = function(context) {
+
+    /**
+     * OPTIONS
+     * &quot;key-spacing&quot;: [2, {
+     *     beforeColon: false,
+     *     afterColon: true,
+     *     align: &quot;colon&quot; // Optional, or &quot;value&quot;
+     * }
+     */
+
+    var options = context.options[0] || {},
+        align = options.align,
+        beforeColon = +!!options.beforeColon, // Defaults to false
+        afterColon = +!(options.afterColon === false); // Defaults to true
+
+    /**
+     * Gets the spacing around the colon in an object literal property
+     * @param {ASTNode} property Property node from an object literal
+     * @returns {Object} Spacing before and after the property's colon
+     */
+    function getPropertySpacing(property) {
+        var whitespace = /^(\s*):(\s*)/.exec(context.getSource().slice(
+            property.key.range[1], property.value.range[0]
+        ));
+
+        if (whitespace) {
+            return {
+                beforeColon: whitespace[1].length,
+                afterColon: whitespace[2].length
+            };
+        }
+    }
+
+    /**
+     * Reports an appropriately-formatted error if spacing is incorrect on one
+     * side of the colon.
+     * @param {ASTNode} property Key-value pair in an object literal.
+     * @param {string} side Side being verified - either &quot;key&quot; or &quot;value&quot;.
+     * @param {int} diff Difference between actual and expected spacing.
+     * @returns {void}
+     */
+    function report(property, side, diff) {
+        if (diff) {
+            context.report(property[side], messages[side], {
+                error: diff &gt; 0 ? &quot;Extra&quot; : &quot;Missing&quot;,
+                key: getKey(property)
+            });
+        }
+    }
+
+    if (align) { // Verify vertical alignment
+
+        return {
+            &quot;ObjectExpression&quot;: function(node) {
+                var properties = node.properties,
+                    length = properties.length,
+                    widths = properties.map(getKeyWidth), // Width of keys, including quotes
+                    targetWidth = Math.max.apply(null, widths),
+                    i, property, spacing, width;
+
+                // Conditionally include one space before or after colon
+                targetWidth += (align === &quot;colon&quot; ? beforeColon : afterColon);
+
+                for (i = 0; i &lt; length; i++) {
+                    property = properties[i];
+                    spacing = getPropertySpacing(property);
+
+                    if (!spacing) {
+                        continue; // Object literal getters/setters lack a colon
+                    }
+
+                    width = widths[i];
+
+                    if (align === &quot;value&quot;) {
+                        report(property, &quot;key&quot;, spacing.beforeColon - beforeColon);
+                        report(property, &quot;value&quot;, (width + spacing.afterColon) - targetWidth);
+                    } else { // align = &quot;colon&quot;
+                        report(property, &quot;key&quot;, (width + spacing.beforeColon) - targetWidth);
+                        report(property, &quot;value&quot;, spacing.afterColon - afterColon);
+                    }
+                }
+            }
+        };
+
+    } else { // Strictly obey beforeColon and afterColon in each property
+
+        return {
+            &quot;Property&quot;: function (node) {
+                var spacing = getPropertySpacing(node);
+                if (spacing) { // Object literal getters/setters lack colon spacing
+                    report(node, &quot;key&quot;, spacing.beforeColon - beforeColon);
+                    report(node, &quot;value&quot;, spacing.afterColon - afterColon);
+                }
+            }
+        };
+
+    }
+
+};
+
+},{}],32:[function(require,module,exports){
+/**
+ * @fileoverview A rule to set the maximum depth block can be nested in a function.
+ * @author Ian Christian Myers
+ */
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+    &quot;use strict&quot;;
+
+    //--------------------------------------------------------------------------
+    // Helpers
+    //--------------------------------------------------------------------------
+
+    var functionStack = [],
+        maxDepth = context.options[0] || 4;
+
+    function startFunction() {
+        functionStack.push(0);
+    }
+
+    function endFunction() {
+        functionStack.pop();
+    }
+
+    function pushBlock(node) {
+        var len = ++functionStack[functionStack.length - 1];
+
+        if (len &gt; maxDepth) {
+            context.report(node, &quot;Blocks are nested too deeply ({{depth}}).&quot;,
+                    { depth: len });
+        }
+    }
+
+    function popBlock() {
+        functionStack[functionStack.length - 1]--;
+    }
+
+    //--------------------------------------------------------------------------
+    // Public API
+    //--------------------------------------------------------------------------
+
+    return {
+        &quot;Program&quot;: startFunction,
+        &quot;FunctionDeclaration&quot;: startFunction,
+        &quot;FunctionExpression&quot;: startFunction,
+
+        &quot;IfStatement&quot;: pushBlock,
+        &quot;SwitchStatement&quot;: pushBlock,
+        &quot;TryStatement&quot;: pushBlock,
+        &quot;DoWhileStatement&quot;: pushBlock,
+        &quot;WhileStatement&quot;: pushBlock,
+        &quot;WithStatement&quot;: pushBlock,
+        &quot;ForStatement&quot;: pushBlock,
+        &quot;ForInStatement&quot;: pushBlock,
+
+        &quot;IfStatement:exit&quot;: popBlock,
+        &quot;SwitchStatement:exit&quot;: popBlock,
+        &quot;TryStatement:exit&quot;: popBlock,
+        &quot;DoWhileStatement:exit&quot;: popBlock,
+        &quot;WhileStatement:exit&quot;: popBlock,
+        &quot;WithStatement:exit&quot;: popBlock,
+        &quot;ForStatement:exit&quot;: popBlock,
+        &quot;ForInStatement:exit&quot;: popBlock,
+
+        &quot;FunctionDeclaration:exit&quot;: endFunction,
+        &quot;FunctionExpression:exit&quot;: endFunction,
+        &quot;Program:exit&quot;: endFunction
+    };
+
+};
+
+},{}],33:[function(require,module,exports){
+/**
+ * @fileoverview Rule to check for max length on a line.
+ * @author Matt DuVall &lt;http://www.mattduvall.com&gt;
+ * @copyright 2013 Matt DuVall. All rights reserved.
+ */
+
+&quot;use strict&quot;;
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+    /**
+     * Creates a string that is made up of repeating a given string a certain
+     * number of times. This uses exponentiation of squares to achieve significant
+     * performance gains over the more traditional implementation of such
+     * functionality.
+     * @param {string} str The string to repeat.
+     * @param {int} num The number of times to repeat the string.
+     * @returns {string} The created string.
+     * @private
+     */
+    function stringRepeat(str, num) {
+        var result = &quot;&quot;;
+        for (num |= 0; num &gt; 0; num &gt;&gt;&gt;= 1, str += str) {
+            if (num &amp; 1) {
+                result += str;
+            }
+        }
+        return result;
+    }
+
+    var tabWidth = context.options[1];
+
+    var maxLength = context.options[0],
+        tabString = stringRepeat(&quot; &quot;, tabWidth);
+
+    //--------------------------------------------------------------------------
+    // Helpers
+    //--------------------------------------------------------------------------
+    function checkProgramForMaxLength(node) {
+        var lines = context.getSourceLines();
+
+        // Replace the tabs
+        // Split (honors line-ending)
+        // Iterate
+        lines.forEach(function(line, i) {
+            if (line.replace(/\t/g, tabString).length &gt; maxLength) {
+                context.report(node, { line: i + 1, col: 1 }, &quot;Line &quot; + (i + 1) + &quot; exceeds the maximum line length of &quot; + maxLength + &quot;.&quot;);
+            }
+        });
+    }
+
+
+    //--------------------------------------------------------------------------
+    // Public API
+    //--------------------------------------------------------------------------
+
+    return {
+        &quot;Program&quot;: checkProgramForMaxLength
+    };
+
+};
+
+},{}],34:[function(require,module,exports){
+/**
+ * @fileoverview Rule to enforce a maximum number of nested callbacks.
+ * @author Ian Christian Myers
+ */
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+    &quot;use strict&quot;;
+
+    //--------------------------------------------------------------------------
+    // Constants
+    //--------------------------------------------------------------------------
+
+    var THRESHOLD = context.options[0];
+
+    //--------------------------------------------------------------------------
+    // Public API
+    //--------------------------------------------------------------------------
+
+    var callbackStack = [];
+
+    return {
+
+        &quot;FunctionExpression&quot;: function (node) {
+            var parent = context.getAncestors().pop();
+
+            if (parent.type === &quot;CallExpression&quot;) {
+                callbackStack.push(node);
+            }
+
+            if (callbackStack.length &gt; THRESHOLD) {
+                var opts = {num: callbackStack.length, max: THRESHOLD};
+                context.report(node, &quot;Too many nested callbacks ({{num}}). Maximum allowed is {{max}}.&quot;, opts);
+            }
+        },
+
+
+        &quot;FunctionExpression:exit&quot;: function() {
+            callbackStack.pop();
+        }
+
+    };
+
+};
+
+},{}],35:[function(require,module,exports){
+/**
+ * @fileoverview Rule to flag when a function has too many parameters
+ * @author Ilya Volodin
+ */
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+    &quot;use strict&quot;;
+
+    var numParams = context.options[0] || 3;
+
+    return {
+
+        &quot;FunctionDeclaration&quot;: function(node) {
+            if (node.params.length &gt; numParams) {
+                context.report(node, &quot;This function has too many parameters ({{count}}). Maximum allowed is {{max}}.&quot;, {
+                    count: node.params.length,
+                    max: numParams
+                });
+            }
+        },
+
+        &quot;FunctionExpression&quot;: function(node) {
+            if (node.params.length &gt; numParams) {
+                context.report(node, &quot;This function has too many parameters ({{count}}). Maximum allowed is {{max}}.&quot;, {
+                    count: node.params.length,
+                    max: numParams
+                });
+            }
+        }
+    };
+
+};
+
+},{}],36:[function(require,module,exports){
+/**
+ * @fileoverview A rule to set the maximum number of statements in a function.
+ * @author Ian Christian Myers
+ */
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+    &quot;use strict&quot;;
+
+    //--------------------------------------------------------------------------
+    // Helpers
+    //--------------------------------------------------------------------------
+
+    var functionStack = [],
+        maxStatements = context.options[0] || 10;
+
+    function startFunction() {
+        functionStack.push(0);
+    }
+
+    function endFunction(node) {
+        var count = functionStack.pop();
+
+        if (count &gt; maxStatements) {
+            context.report(node, &quot;This function has too many statements ({{count}}). Maximum allowed is {{max}}.&quot;,
+                    { count: count, max: maxStatements });
+        }
+    }
+
+    function countStatements(node) {
+        functionStack[functionStack.length - 1] += node.body.length;
+    }
+
+    //--------------------------------------------------------------------------
+    // Public API
+    //--------------------------------------------------------------------------
+
+    return {
+        &quot;FunctionDeclaration&quot;: startFunction,
+        &quot;FunctionExpression&quot;: startFunction,
+
+        &quot;BlockStatement&quot;: countStatements,
+
+        &quot;FunctionDeclaration:exit&quot;: endFunction,
+        &quot;FunctionExpression:exit&quot;: endFunction
+    };
+
+};
+
+},{}],37:[function(require,module,exports){
+/**
+ * @fileoverview Rule to flag use of constructors without capital letters
+ * @author Nicholas C. Zakas
+ * @copyright 2013-2014 Nicholas C. Zakas. All rights reserved.
+ */
+
+&quot;use strict&quot;;
+
+var CAPS_ALLOWED = [
+    &quot;Number&quot;,
+    &quot;String&quot;,
+    &quot;Boolean&quot;,
+    &quot;Date&quot;,
+    &quot;Array&quot;,
+    &quot;Symbol&quot;,
+    &quot;RegExp&quot;
+];
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+    var config = context.options[0] || {};
+    config.newIsCap = config.newIsCap === false ? false : true;
+    config.capIsNew = config.capIsNew === false ? false : true;
+
+    var listeners = {};
+
+    //--------------------------------------------------------------------------
+    // Helpers
+    //--------------------------------------------------------------------------
+
+    /**
+     * Get exact callee name from expression
+     * @param {ASTNode} node CallExpression or NewExpression node
+     * @returns {String} name
+     */
+    function extractNameFromExpression(node) {
+
+        var name = &quot;&quot;,
+            property;
+
+        if (node.callee.type === &quot;MemberExpression&quot;) {
+            property = node.callee.property;
+
+            if (property.type === &quot;Literal&quot; &amp;&amp; (typeof property.value === &quot;string&quot;)) {
+                name = property.value;
+            } else if (property.type === &quot;Identifier&quot; &amp;&amp; !node.callee.computed) {
+                name = property.name;
+            }
+        } else {
+            name = node.callee.name;
+        }
+        return name;
+    }
+
+    /**
+     * Returns the capitalization state of the string -
+     * Whether the first character is uppercase, lowercase, or non-alphabetic
+     * @param {String} str String
+     * @returns {String} capitalization state: &quot;non-alpha&quot;, &quot;lower&quot;, or &quot;upper&quot;
+     */
+    function getCap(str) {
+        var firstChar = str.charAt(0);
+
+        var firstCharLower = firstChar.toLowerCase();
+        var firstCharUpper = firstChar.toUpperCase();
+
+        if (firstCharLower === firstCharUpper) {
+            // char has no uppercase variant, so it's non-alphabetic
+            return &quot;non-alpha&quot;;
+        } else if (firstChar === firstCharLower) {
+            return &quot;lower&quot;;
+        } else {
+            return &quot;upper&quot;;
+        }
+    }
+
+    /**
+     * Check if capitalization is allowed for a CallExpression
+     * @param {ASTNode} node CallExpression node
+     * @param {String} calleeName Capitalized callee name from a CallExpression
+     * @returns {Boolean} Returns true if the callee may be capitalized
+     */
+    function isCapAllowed(node, calleeName) {
+        if (CAPS_ALLOWED.indexOf(calleeName) &gt;= 0) {
+            return true;
+        }
+        if (calleeName === &quot;UTC&quot; &amp;&amp; node.callee.type === &quot;MemberExpression&quot;) {
+            // allow if callee is Date.UTC
+            return node.callee.object.type === &quot;Identifier&quot; &amp;&amp;
+                   node.callee.object.name === &quot;Date&quot;;
+        }
+        return false;
+    }
+
+    //--------------------------------------------------------------------------
+    // Public
+    //--------------------------------------------------------------------------
+
+    if (config.newIsCap) {
+        listeners.NewExpression = function(node) {
+
+            var constructorName = extractNameFromExpression(node);
+            if (constructorName &amp;&amp; getCap(constructorName) === &quot;lower&quot;) {
+                context.report(node, &quot;A constructor name should not start with a lowercase letter.&quot;);
+            }
+        };
+    }
+
+    if (config.capIsNew) {
+        listeners.CallExpression = function(node) {
+
+            var calleeName = extractNameFromExpression(node);
+            if (calleeName &amp;&amp; getCap(calleeName) === &quot;upper&quot; &amp;&amp; !isCapAllowed(node, calleeName)) {
+                context.report(node, &quot;A function with a name starting with an uppercase letter should only be used as a constructor.&quot;);
+            }
+        };
+    }
+
+    return listeners;
+};
+
+},{}],38:[function(require,module,exports){
+/**
+ * @fileoverview Rule to flag when using constructor without parentheses
+ * @author Ilya Volodin
+ */
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+    &quot;use strict&quot;;
+
+    return {
+
+        &quot;NewExpression&quot;: function(node) {
+            var tokens = context.getTokens(node);
+            var prenticesTokens = tokens.filter(function(token) {
+                return token.value === &quot;(&quot; || token.value === &quot;)&quot;;
+            });
+            if (prenticesTokens.length &lt; 2) {
+                context.report(node, &quot;Missing '()' invoking a constructor&quot;);
+            }
+        }
+    };
+
+};
+
+},{}],39:[function(require,module,exports){
+/**
+ * @fileoverview Rule to flag use of alert, confirm, prompt
+ * @author Nicholas C. Zakas
+ */
+&quot;use strict&quot;;
+
+//------------------------------------------------------------------------------
+// Helpers
+//------------------------------------------------------------------------------
+
+function matchProhibited(name) {
+    return name.match(/^(alert|confirm|prompt)$/);
+}
+
+function report(context, node, result) {
+    context.report(node, &quot;Unexpected {{name}}.&quot;, { name: result[1] });
+}
+
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+    return {
+
+        &quot;CallExpression&quot;: function(node) {
+
+            var result;
+
+            // without window.
+            if (node.callee.type === &quot;Identifier&quot;) {
+
+                result = matchProhibited(node.callee.name);
+
+                if (result) {
+                    report(context, node, result);
+                }
+
+            } else if (node.callee.type === &quot;MemberExpression&quot; &amp;&amp; node.callee.property.type === &quot;Identifier&quot;) {
+
+                result = matchProhibited(node.callee.property.name);
+
+                if (result &amp;&amp; node.callee.object.name === &quot;window&quot;) {
+                    report(context, node, result);
+                }
+
+            }
+
+        }
+    };
+
+};
+
+},{}],40:[function(require,module,exports){
+/**
+ * @fileoverview Disallow construction of dense arrays using the Array constructor
+ * @author Matt DuVall &lt;http://www.mattduvall.com/&gt;
+ */
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+    &quot;use strict&quot;;
+
+    function check(node) {
+        if (
+            node.arguments.length !== 1 &amp;&amp;
+            node.callee.type === &quot;Identifier&quot; &amp;&amp;
+            node.callee.name === &quot;Array&quot;
+        ) {
+            context.report(node, &quot;The array literal notation [] is preferrable.&quot;);
+        }
+    }
+
+    return {
+        &quot;CallExpression&quot;: check,
+        &quot;NewExpression&quot;: check
+    };
+
+};
+
+},{}],41:[function(require,module,exports){
+/**
+ * @fileoverview Rule to flag bitwise identifiers
+ * @author Nicholas C. Zakas
+ */
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+    &quot;use strict&quot;;
+
+    function report(node) {
+        context.report(node, &quot;Unexpected use of '{{operator}}'.&quot;, { operator: node.operator });
+    }
+
+    return {
+        &quot;BinaryExpression&quot;: function(node) {
+
+            // warn for ^ | &amp; ~ &lt;&lt; &gt;&gt; &gt;&gt;&gt;
+            if (node.operator.match(/^(?:[\^&amp;\|~]|&lt;&lt;|&gt;&gt;&gt;?)$/)) {
+                report(node);
+            }
+
+        },
+
+        &quot;UnaryExpression&quot;: function(node) {
+
+            // warn for ~
+            if (node.operator === &quot;~&quot;) {
+                report(node);
+            }
+
+        }
+    };
+
+};
+
+},{}],42:[function(require,module,exports){
+/**
+ * @fileoverview Rule to flag use of arguments.callee and arguments.caller.
+ * @author Nicholas C. Zakas
+ */
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+    &quot;use strict&quot;;
+
+    return {
+
+        &quot;MemberExpression&quot;: function(node) {
+            var objectName = node.object.name,
+                propertyName = node.property.name;
+
+            if (objectName === &quot;arguments&quot; &amp;&amp; !node.computed &amp;&amp; propertyName &amp;&amp; propertyName.match(/^calle[er]$/)) {
+                context.report(node, &quot;Avoid arguments.{{property}}.&quot;, { property: propertyName });
+            }
+
+        }
+    };
+
+};
+
+},{}],43:[function(require,module,exports){
+/**
+ * @fileoverview Rule to flag variable leak in CatchClauses in IE 8 and earlier
+ * @author Ian Christian Myers
+ */
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+    &quot;use strict&quot;;
+
+    //--------------------------------------------------------------------------
+    // Helpers
+    //--------------------------------------------------------------------------
+
+    function paramIsShadowing(scope, name) {
+        var found = scope.variables.some(function(variable) {
+            return variable.name === name;
+        });
+
+        if (found) {
+            return true;
+        }
+
+        if (scope.upper) {
+            return paramIsShadowing(scope.upper, name);
+        }
+
+        return false;
+    }
+
+    //--------------------------------------------------------------------------
+    // Public API
+    //--------------------------------------------------------------------------
+
+    return {
+
+        &quot;CatchClause&quot;: function(node) {
+            var scope = context.getScope();
+
+            if (paramIsShadowing(scope, node.param.name)) {
+                context.report(node, &quot;Value of '{{name}}' may be overwritten in IE 8 and earlier.&quot;,
+                        { name: node.param.name });
+            }
+        }
+    };
+
+};
+
+},{}],44:[function(require,module,exports){
+/**
+ * @fileoverview Rule to flag trailing commas in object literals.
+ * @author Ian Christian Myers
+ */
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+    &quot;use strict&quot;;
+
+     //-------------------------------------------------------------------------
+     // Helpers
+     //-------------------------------------------------------------------------
+
+    function checkForTrailingComma(node) {
+        var secondToLastToken = context.getLastTokens(node, 2)[0];
+
+        var items = node.properties || node.elements,
+            lastItem = items[items.length - 1];
+        // The last token in an object/array literal will always be a closing
+        // curly, so we check the second to last token for a comma.
+        if (secondToLastToken.value === &quot;,&quot; &amp;&amp; items.length &amp;&amp; lastItem) {
+            context.report(lastItem, secondToLastToken.loc.start, &quot;Trailing comma.&quot;);
+        }
+    }
+
+    //--------------------------------------------------------------------------
+    // Public API
+    //--------------------------------------------------------------------------
+
+    return {
+        &quot;ObjectExpression&quot;: checkForTrailingComma,
+        &quot;ArrayExpression&quot;: checkForTrailingComma
+    };
+
+};
+
+},{}],45:[function(require,module,exports){
+/**
+ * @fileoverview Rule to flag assignment in a conditional expression
+ * @author Stephen Murray &lt;spmurrayzzz&gt;
+ */
+&quot;use strict&quot;;
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+    function isParenthesised(node) {
+        var previousToken = context.getTokenBefore(node),
+            nextToken = context.getTokenAfter(node);
+
+        return previousToken.value === &quot;(&quot; &amp;&amp; previousToken.range[1] &lt;= node.range[0] &amp;&amp;
+            nextToken.value === &quot;)&quot; &amp;&amp; nextToken.range[0] &gt;= node.range[1];
+    }
+
+    function isParenthesisedTwice(node) {
+        var previousToken = context.getTokenBefore(node, 1),
+            nextToken = context.getTokenAfter(node, 1);
+
+        return isParenthesised(node) &amp;&amp;
+            previousToken.value === &quot;(&quot; &amp;&amp; previousToken.range[1] &lt;= node.range[0] &amp;&amp;
+            nextToken.value === &quot;)&quot; &amp;&amp; nextToken.range[0] &gt;= node.range[1];
+    }
+
+    function testForAssign(node) {
+        if (node.test &amp;&amp; (node.test.type === &quot;AssignmentExpression&quot;) &amp;&amp; !isParenthesisedTwice(node.test)) {
+            context.report(node, &quot;Expected a conditional expression and instead saw an assignment.&quot;);
+        }
+    }
+
+    return {
+        &quot;IfStatement&quot;: testForAssign,
+        &quot;WhileStatement&quot;: testForAssign,
+        &quot;DoWhileStatement&quot;: testForAssign,
+        &quot;ForStatement&quot;: testForAssign
+    };
+
+};
+
+},{}],46:[function(require,module,exports){
+/**
+ * @fileoverview Rule to flag use of console object
+ * @author Nicholas C. Zakas
+ */
+
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+    &quot;use strict&quot;;
+
+    return {
+
+        &quot;MemberExpression&quot;: function(node) {
+
+            if (node.object.name === &quot;console&quot;) {
+                context.report(node, &quot;Unexpected console statement.&quot;);
+            }
+
+        }
+    };
+
+};
+
+},{}],47:[function(require,module,exports){
+/**
+ * @fileoverview Rule to flag use constant conditions
+ * @author Christian Schulz &lt;http://rndm.de&gt;
+ */
+
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+    &quot;use strict&quot;;
+
+    //--------------------------------------------------------------------------
+    // Helpers
+    //--------------------------------------------------------------------------
+
+    /**
+     * Checks if a node has a constant truthiness value.
+     * @param {ASTNode} node The AST node to check.
+     * @returns {Bool} true when node's truthiness is constant
+     * @private
+     */
+    function isConstant(node) {
+        switch (node.type) {
+        case &quot;Literal&quot;:
+        case &quot;FunctionExpression&quot;:
+        case &quot;ObjectExpression&quot;:
+        case &quot;ArrayExpression&quot;:
+            return true;
+        case &quot;UnaryExpression&quot;:
+            return isConstant(node.argument);
+        case &quot;BinaryExpression&quot;:
+        case &quot;LogicalExpression&quot;:
+            return isConstant(node.left) &amp;&amp; isConstant(node.right);
+        case &quot;AssignmentExpression&quot;:
+            return isConstant(node.right);
+        case &quot;SequenceExpression&quot;:
+            return isConstant(node.expressions[node.expressions.length - 1]);
+        // no default
+        }
+        return false;
+    }
+
+    /**
+     * Reports when the given node contains a constant condition.
+     * @param {ASTNode} node The AST node to check.
+     * @returns {void}
+     * @private
+     */
+    function checkConstantCondition(node) {
+        if (node.test &amp;&amp; isConstant(node.test)) {
+            context.report(node, &quot;Unexpected constant condition.&quot;);
+        }
+    }
+
+    //--------------------------------------------------------------------------
+    // Public
+    //--------------------------------------------------------------------------
+
+    return {
+        &quot;ConditionalExpression&quot;: checkConstantCondition,
+        &quot;IfStatement&quot;: checkConstantCondition,
+        &quot;WhileStatement&quot;: checkConstantCondition,
+        &quot;DoWhileStatement&quot;: checkConstantCondition,
+        &quot;ForStatement&quot;: checkConstantCondition
+    };
+
+};
+
+},{}],48:[function(require,module,exports){
+/**
+ * @fileoverview Rule to forbid control charactes from regular expressions.
+ * @author Nicholas C. Zakas
+ */
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+    &quot;use strict&quot;;
+
+
+    function getRegExp(node) {
+
+        if (node.value instanceof RegExp) {
+            return node.value;
+        } else if (typeof node.value === &quot;string&quot;) {
+
+            var parent = context.getAncestors().pop();
+            if ((parent.type === &quot;NewExpression&quot; || parent.type === &quot;CallExpression&quot;) &amp;&amp;
+            parent.callee.type === &quot;Identifier&quot; &amp;&amp; parent.callee.name === &quot;RegExp&quot;) {
+
+                // there could be an invalid regular expression string
+                try {
+                    return new RegExp(node.value);
+                } catch (ex) {
+                    return null;
+                }
+
+            }
+        } else {
+            return null;
+        }
+
+    }
+
+
+
+    return {
+
+        &quot;Literal&quot;: function(node) {
+
+            var computedValue,
+                regex = getRegExp(node);
+
+            if (regex) {
+                computedValue = regex.toString();
+                if (/[\x00-\x1f]/.test(computedValue)) {
+                    context.report(node, &quot;Unexpected control character in regular expression.&quot;);
+                }
+            }
+        }
+    };
+
+};
+
+},{}],49:[function(require,module,exports){
+/**
+ * @fileoverview Rule to flag use of a debugger statement
+ * @author Nicholas C. Zakas
+ */
+
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+    &quot;use strict&quot;;
+
+    return {
+        &quot;DebuggerStatement&quot;: function(node) {
+            context.report(node, &quot;Unexpected 'debugger' statement.&quot;);
+        }
+    };
+
+};
+
+},{}],50:[function(require,module,exports){
+/**
+ * @fileoverview Rule to flag when deleting variables
+ * @author Ilya Volodin
+ */
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+    &quot;use strict&quot;;
+
+    return {
+
+        &quot;UnaryExpression&quot;: function(node) {
+            if (node.operator === &quot;delete&quot; &amp;&amp; node.argument.type === &quot;Identifier&quot;) {
+                context.report(node, &quot;Variables should not be deleted.&quot;);
+            }
+        }
+    };
+
+};
+
+},{}],51:[function(require,module,exports){
+/**
+ * @fileoverview Rule to check for ambiguous div operator in regexes
+ * @author Matt DuVall &lt;http://www.mattduvall.com&gt;
+ */
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+    &quot;use strict&quot;;
+
+    return {
+
+        &quot;Literal&quot;: function(node) {
+            var token = context.getFirstTokens(node, 1)[0],
+                nodeType = token.type,
+                source;
+
+            if (nodeType === &quot;RegularExpression&quot;) {
+                source = context.getFirstTokens(node, 1)[0].value;
+
+                if (source[1] === &quot;=&quot;) {
+                    context.report(node, &quot;A regular expression literal can be confused with '/='.&quot;);
+                }
+            }
+        }
+    };
+
+};
+
+},{}],52:[function(require,module,exports){
+/**
+ * @fileoverview Rule to flag use of duplicate keys in an object.
+ * @author Ian Christian Myers
+ */
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+    &quot;use strict&quot;;
+
+    return {
+
+        &quot;ObjectExpression&quot;: function(node) {
+
+            // Object that will be a map of properties--safe because we will
+            // prefix all of the keys.
+            var nodeProps = {};
+
+            node.properties.forEach(function(property) {
+                var keyName = property.key.name || property.key.value;
+                var key = property.kind + &quot;-&quot; + keyName;
+
+                if (nodeProps[key]) {
+                    context.report(node, &quot;Duplicate key '{{key}}'.&quot;, { key: keyName });
+                } else {
+                    nodeProps[key] = true;
+                }
+            });
+
+        }
+    };
+
+};
+
+},{}],53:[function(require,module,exports){
+/**
+ * @fileoverview Rule to flag `else` after a `return` in `if`
+ * @author Ian Christian Myers
+ */
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+    &quot;use strict&quot;;
+
+    //--------------------------------------------------------------------------
+    // Helpers
+    //--------------------------------------------------------------------------
+
+    function checkForReturnStatement(node, alternate) {
+        if (node.type === &quot;ReturnStatement&quot;) {
+            context.report(alternate, &quot;Unexpected 'else' after 'return'.&quot;);
+        }
+    }
+
+    //--------------------------------------------------------------------------
+    // Public API
+    //--------------------------------------------------------------------------
+
+    return {
+
+        &quot;IfStatement&quot;: function(node) {
+
+            // Don't bother finding a ReturnStatement, if there's no `else`
+            // or if the alternate is also an if (indicating an else if).
+            if (node.alternate &amp;&amp; node.consequent &amp;&amp; node.alternate.type !== &quot;IfStatement&quot;) {
+
+                // If we have a BlockStatement, check each consequent body node.
+                if (node.consequent.type === &quot;BlockStatement&quot;) {
+                    node.consequent.body.forEach(function (bodyNode) {
+                        checkForReturnStatement(bodyNode, node.alternate);
+                    });
+
+                // If not a block statement, make sure the consequent isn't a
+                // ReturnStatement
+                } else {
+                    checkForReturnStatement(node.consequent, node.alternate);
+                }
+            }
+        }
+
+    };
+
+};
+
+},{}],54:[function(require,module,exports){
+/**
+ * @fileoverview Rule to flag the use of empty character classes in regular expressions
+ * @author Ian Christian Myers
+ */
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+    &quot;use strict&quot;;
+
+    return {
+
+        &quot;Literal&quot;: function(node) {
+            var tokens = context.getTokens(node);
+            tokens.forEach(function (token) {
+                /*
+                plain-English description of the following regexp:
+                0. `^` fix the match at the beginning of the string
+                1. `\/`: the `/` that begins the regexp
+                2. `([^\\[]|\\.|\[([^\\\]]|\\.)+\])*`: regexp contents; 0 or more of the following
+                  2.0. `[^\\[]`: any character that's not a `\` or a `[` (anything but escape sequences and character classes)
+                  2.1. `\\.`: an escape sequence
+                  2.2. `\[([^\\\]]|\\.)+\]`: a character class that isn't empty
+                3. `\/` the `/` that ends the regexp
+                4. `[gimy]*`: optional regexp flags
+                5. `$`: fix the match at the end of the string
+                */
+                if (token.type === &quot;RegularExpression&quot; &amp;&amp;
+                !/^\/([^\\[]|\\.|\[([^\\\]]|\\.)+\])*\/[gimy]*$/.test(token.value)) {
+                    context.report(node, &quot;Empty class.&quot;);
+                }
+            });
+        }
+
+    };
+
+};
+
+},{}],55:[function(require,module,exports){
+/**
+ * @fileoverview Rule to flag when label is not used for a loop or switch
+ * @author Ilya Volodin
+ */
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+    &quot;use strict&quot;;
+
+    return {
+
+        &quot;LabeledStatement&quot;: function(node) {
+            if (node.body.type !== &quot;ForStatement&quot; &amp;&amp; node.body.type !== &quot;WhileStatement&quot; &amp;&amp; node.body.type !== &quot;DoWhileStatement&quot; &amp;&amp; node.body.type !== &quot;SwitchStatement&quot; &amp;&amp; node.body.type !== &quot;ForInStatement&quot;) {
+                context.report(node, &quot;Unexpected label {{l}}&quot;, {l: node.label.name});
+            }
+        }
+    };
+
+};
+
+},{}],56:[function(require,module,exports){
+/**
+ * @fileoverview Rule to flag use of an empty block statement
+ * @author Nicholas C. Zakas
+ */
+&quot;use strict&quot;;
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+    return {
+
+        &quot;BlockStatement&quot;: function(node) {
+            var ancestors = context.getAncestors(),
+                parent = ancestors[ancestors.length - 1],
+                parentType = parent.type,
+                isFinallyBlock = (parentType === &quot;TryStatement&quot;) &amp;&amp; (parent.finalizer === node);
+
+            if (/FunctionExpression|FunctionDeclaration|CatchClause/.test(parentType) ||
+                    (isFinallyBlock &amp;&amp; !parent.handlers.length)) {
+                return;
+            }
+
+            if (node.body.length === 0) {
+                context.report(node, &quot;Empty block statement.&quot;);
+            }
+        },
+
+        &quot;SwitchStatement&quot;: function(node) {
+
+            if (typeof node.cases === &quot;undefined&quot; || node.cases.length === 0) {
+                context.report(node, &quot;Empty switch statement.&quot;);
+            }
+        }
+    };
+
+};
+
+},{}],57:[function(require,module,exports){
+/**
+ * @fileoverview Rule to flag comparisons to null without a type-checking
+ * operator.
+ * @author Ian Christian Myers
+ */
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+    &quot;use strict&quot;;
+
+    return {
+
+        &quot;BinaryExpression&quot;: function(node) {
+            var badOperator = node.operator === &quot;==&quot; || node.operator === &quot;!=&quot;;
+
+            if (node.right.type === &quot;Literal&quot; &amp;&amp; node.right.raw === &quot;null&quot; &amp;&amp; badOperator ||
+                    node.left.type === &quot;Literal&quot; &amp;&amp; node.left.raw === &quot;null&quot; &amp;&amp; badOperator) {
+                context.report(node, &quot;Use â€˜===’ to compare with â€˜null’.&quot;);
+            }
+        }
+    };
+
+};
+
+},{}],58:[function(require,module,exports){
+/**
+ * @fileoverview Rule to flag use of eval() statement
+ * @author Nicholas C. Zakas
+ */
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+    &quot;use strict&quot;;
+
+    var IMPLIED_EVAL = /set(?:Timeout|Interval)/;
+
+    //--------------------------------------------------------------------------
+    // Helpers
+    //--------------------------------------------------------------------------
+
+    /**
+     * Determines if a node represents a call to setTimeout/setInterval with
+     * a string argument.
+     * @param {ASTNode} node The node to check.
+     * @returns {boolean} True if the node matches, false if not.
+     * @private
+     */
+    function isImpliedEval(node) {
+
+        var isMemberExpression = (node.callee.type === &quot;MemberExpression&quot;),
+            isIdentifier = (node.callee.type === &quot;Identifier&quot;),
+            isSetMethod = (isIdentifier &amp;&amp; IMPLIED_EVAL.test(node.callee.name)) ||
+                (isMemberExpression &amp;&amp; node.callee.object.name === &quot;window&quot; &amp;&amp;
+                IMPLIED_EVAL.test(node.callee.property.name)),
+            hasStringArgument = node.arguments.length &amp;&amp; (typeof node.arguments[0].value === &quot;string&quot;);
+
+        return isSetMethod &amp;&amp; hasStringArgument;
+    }
+
+
+    //--------------------------------------------------------------------------
+    // Public
+    //--------------------------------------------------------------------------
+
+    return {
+        &quot;CallExpression&quot;: function(node) {
+            if (node.callee.name === &quot;eval&quot;) {
+                context.report(node, &quot;eval can be harmful.&quot;);
+            } else if (isImpliedEval(node)) {
+                if (node.arguments.length &amp;&amp; (typeof node.arguments[0].value === &quot;string&quot;)) {
+                    context.report(node, &quot;Implied eval can be harmful. Pass a function instead of a string.&quot;);
+                }
+            }
+        }
+    };
+
+};
+
+},{}],59:[function(require,module,exports){
+/**
+ * @fileoverview Rule to flag assignment of the exception parameter
+ * @author Stephen Murray &lt;spmurrayzzz&gt;
+ */
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+    &quot;use strict&quot;;
+
+    var inCatch = false,
+        exceptionName = null;
+
+    return {
+
+        &quot;CatchClause&quot;: function(node) {
+            inCatch = true;
+            exceptionName = node.param.name;
+        },
+
+        &quot;CatchClause:exit&quot;: function() {
+            inCatch = false;
+            exceptionName = null;
+        },
+
+        &quot;AssignmentExpression&quot;: function(node) {
+
+            if (inCatch) {
+
+                if (node.left.name === exceptionName) {
+                    context.report(node, &quot;Do not assign to the exception parameter.&quot;);
+                }
+            }
+        }
+
+    };
+
+};
+
+},{}],60:[function(require,module,exports){
+/**
+ * @fileoverview Rule to flag adding properties to native object's prototypes.
+ * @author David Nelson
+ */
+
+//------------------------------------------------------------------------------
+// Requirements
+//------------------------------------------------------------------------------
+
+var BUILTINS = [
+    &quot;Object&quot;, &quot;Function&quot;, &quot;Array&quot;, &quot;String&quot;, &quot;Boolean&quot;, &quot;Number&quot;, &quot;Date&quot;,
+    &quot;RegExp&quot;, &quot;Error&quot;, &quot;EvalError&quot;, &quot;RangeError&quot;, &quot;ReferenceError&quot;,
+    &quot;SyntaxError&quot;, &quot;TypeError&quot;, &quot;URIError&quot;
+];
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+    &quot;use strict&quot;;
+
+    return {
+
+        // handle the Array.prototype.extra style case
+        &quot;AssignmentExpression&quot;: function(node) {
+            var lhs = node.left, affectsProto;
+
+            if (lhs.type !== &quot;MemberExpression&quot; || lhs.object.type !== &quot;MemberExpression&quot;) {
+                return;
+            }
+
+            affectsProto = lhs.object.computed ?
+                lhs.object.property.type === &quot;Literal&quot; &amp;&amp; lhs.object.property.value === &quot;prototype&quot; :
+                lhs.object.property.name === &quot;prototype&quot;;
+
+            if (!affectsProto) {
+                return;
+            }
+
+            BUILTINS.forEach(function(builtin) {
+                if (lhs.object.object.name === builtin) {
+                    context.report(node, builtin + &quot; prototype is read only, properties should not be added.&quot;);
+                }
+            });
+        },
+
+        // handle the Object.defineProperty(Array.prototype) case
+        &quot;CallExpression&quot;: function(node) {
+
+            var callee = node.callee,
+                subject,
+                object;
+
+            // only worry about Object.defineProperty
+            if (callee.type === &quot;MemberExpression&quot; &amp;&amp;
+                callee.object.name === &quot;Object&quot; &amp;&amp;
+                callee.property.name === &quot;defineProperty&quot;) {
+
+                // verify the object being added to is a native prototype
+                subject = node.arguments[0];
+                object = subject.object;
+
+                if (object &amp;&amp;
+                    object.type === &quot;Identifier&quot; &amp;&amp;
+                    (BUILTINS.indexOf(object.name) &gt; -1) &amp;&amp;
+                    subject.property.name === &quot;prototype&quot;) {
+
+                    context.report(node, object.name + &quot; prototype is read only, properties should not be added.&quot;);
+                }
+            }
+
+        }
+    };
+
+};
+
+},{}],61:[function(require,module,exports){
+/**
+ * @fileoverview Rule to flag unnecessary bind calls
+ * @author Bence Dányi &lt;bence@danyi.me&gt;
+ * @copyright 2014 Bence Dányi. All rights reserved.
+ */
+&quot;use strict&quot;;
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+    var scope = [{
+        depth: -1,
+        found: 0
+    }];
+
+    /**
+     * Get the topmost scope
+     * @returns {Object} The topmost scope
+     */
+    function getTopScope() {
+        return scope[scope.length - 1];
+    }
+
+    /**
+     * Increment the depth of the top scope
+     * @returns {void}
+     */
+    function incrementScopeDepth() {
+        var top = getTopScope();
+        top.depth++;
+    }
+
+    /**
+     * Decrement the depth of the top scope
+     * @returns {void}
+     */
+    function decrementScopeDepth() {
+        var top = getTopScope();
+        top.depth--;
+    }
+
+    return {
+        &quot;CallExpression&quot;: function(node) {
+            if (node.arguments.length === 1 &amp;&amp;
+                node.callee.type === &quot;MemberExpression&quot; &amp;&amp;
+                node.callee.property.name === &quot;bind&quot; &amp;&amp;
+                node.callee.object.type === &quot;FunctionExpression&quot;) {
+                scope.push({
+                    call: node,
+                    depth: -1,
+                    found: 0
+                });
+            }
+        },
+        &quot;CallExpression:exit&quot;: function(node) {
+            var top = getTopScope();
+            if (top.call === node &amp;&amp; top.found === 0) {
+                context.report(node, &quot;The function binding is unnecessary.&quot;);
+                scope.pop();
+            }
+        },
+        &quot;FunctionExpression&quot;: incrementScopeDepth,
+        &quot;FunctionExpression:exit&quot;: decrementScopeDepth,
+        &quot;FunctionDeclaration&quot;: incrementScopeDepth,
+        &quot;FunctionDeclaration:exit&quot;: decrementScopeDepth,
+        &quot;ThisExpression&quot;: function() {
+            var top = getTopScope();
+            if (top.depth === 0) {
+                top.found++;
+            }
+        }
+    };
+
+};
+
+},{}],62:[function(require,module,exports){
+/**
+ * @fileoverview Rule to flag unnecessary double negation in Boolean contexts
+ * @author Brandon Mills
+ */
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+    &quot;use strict&quot;;
+
+    return {
+        &quot;UnaryExpression&quot;: function (node) {
+            var ancestors = context.getAncestors(),
+                parent = ancestors.pop(),
+                grandparent = ancestors.pop();
+
+            // Exit early if it's guaranteed not to match
+            if (node.operator !== &quot;!&quot; ||
+                    parent.type !== &quot;UnaryExpression&quot; ||
+                    parent.operator !== &quot;!&quot;) {
+                return;
+            }
+
+            // if (&lt;bool&gt;) ...
+            if (grandparent.type === &quot;IfStatement&quot;) {
+                context.report(node, &quot;Redundant double negation in an if statement condition.&quot;);
+
+            // do ... while (&lt;bool&gt;)
+            } else if (grandparent.type === &quot;DoWhileStatement&quot;) {
+                context.report(node, &quot;Redundant double negation in a do while loop condition.&quot;);
+
+            // while (&lt;bool&gt;) ...
+            } else if (grandparent.type === &quot;WhileStatement&quot;) {
+                context.report(node, &quot;Redundant double negation in a while loop condition.&quot;);
+
+            // &lt;bool&gt; ? ... : ...
+            } else if ((grandparent.type === &quot;ConditionalExpression&quot; &amp;&amp;
+                    parent === grandparent.test)) {
+                context.report(node, &quot;Redundant double negation in a ternary condition.&quot;);
+
+            // for (...; &lt;bool&gt;; ...) ...
+            } else if ((grandparent.type === &quot;ForStatement&quot; &amp;&amp;
+                    parent === grandparent.test)) {
+                context.report(node, &quot;Redundant double negation in a for loop condition.&quot;);
+
+            // !&lt;bool&gt;
+            } else if ((grandparent.type === &quot;UnaryExpression&quot; &amp;&amp;
+                    grandparent.operator === &quot;!&quot;)) {
+                context.report(node, &quot;Redundant multiple negation.&quot;);
+
+            // Boolean(&lt;bool&gt;)
+            } else if ((grandparent.type === &quot;CallExpression&quot; &amp;&amp;
+                    grandparent.callee.type === &quot;Identifier&quot; &amp;&amp;
+                    grandparent.callee.name === &quot;Boolean&quot;)) {
+                context.report(node, &quot;Redundant double negation in call to Boolean().&quot;);
+
+            // new Boolean(&lt;bool&gt;)
+            } else if ((grandparent.type === &quot;NewExpression&quot; &amp;&amp;
+                    grandparent.callee.type === &quot;Identifier&quot; &amp;&amp;
+                    grandparent.callee.name === &quot;Boolean&quot;)) {
+                context.report(node, &quot;Redundant double negation in Boolean constructor call.&quot;);
+            }
+        }
+    };
+
+};
+
+},{}],63:[function(require,module,exports){
+/**
+ * @fileoverview Disallow parenthesesisng higher precedence subexpressions.
+ * @author Michael Ficarra
+ */
+&quot;use strict&quot;;
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+    function isParenthesised(node) {
+        var previousToken = context.getTokenBefore(node),
+            nextToken = context.getTokenAfter(node);
+
+        return previousToken &amp;&amp; nextToken &amp;&amp;
+            previousToken.value === &quot;(&quot; &amp;&amp; previousToken.range[1] &lt;= node.range[0] &amp;&amp;
+            nextToken.value === &quot;)&quot; &amp;&amp; nextToken.range[0] &gt;= node.range[1];
+    }
+
+    function isParenthesisedTwice(node) {
+        var previousToken = context.getTokenBefore(node, 1),
+            nextToken = context.getTokenAfter(node, 1);
+
+        return isParenthesised(node) &amp;&amp; previousToken &amp;&amp; nextToken &amp;&amp;
+            previousToken.value === &quot;(&quot; &amp;&amp; previousToken.range[1] &lt;= node.range[0] &amp;&amp;
+            nextToken.value === &quot;)&quot; &amp;&amp; nextToken.range[0] &gt;= node.range[1];
+    }
+
+    function precedence(node) {
+
+        switch (node.type) {
+            case &quot;SequenceExpression&quot;:
+                return 0;
+
+            case &quot;AssignmentExpression&quot;:
+                return 1;
+
+            case &quot;ConditionalExpression&quot;:
+                return 3;
+
+            case &quot;LogicalExpression&quot;:
+                switch (node.operator) {
+                    case &quot;||&quot;:
+                        return 4;
+                    case &quot;&amp;&amp;&quot;:
+                        return 5;
+                    // no default
+                }
+
+                /* falls through */
+            case &quot;BinaryExpression&quot;:
+                switch (node.operator) {
+                    case &quot;|&quot;:
+                        return 6;
+                    case &quot;^&quot;:
+                        return 7;
+                    case &quot;&amp;&quot;:
+                        return 8;
+                    case &quot;==&quot;:
+                    case &quot;!=&quot;:
+                    case &quot;===&quot;:
+                    case &quot;!==&quot;:
+                        return 9;
+                    case &quot;&lt;&quot;:
+                    case &quot;&lt;=&quot;:
+                    case &quot;&gt;&quot;:
+                    case &quot;&gt;=&quot;:
+                    case &quot;in&quot;:
+                    case &quot;instanceof&quot;:
+                        return 10;
+                    case &quot;&lt;&lt;&quot;:
+                    case &quot;&gt;&gt;&quot;:
+                    case &quot;&gt;&gt;&gt;&quot;:
+                        return 11;
+                    case &quot;+&quot;:
+                    case &quot;-&quot;:
+                        return 12;
+                    case &quot;*&quot;:
+                    case &quot;/&quot;:
+                    case &quot;%&quot;:
+                        return 13;
+                    // no default
+                }
+                /* falls through */
+            case &quot;UnaryExpression&quot;:
+                return 14;
+            case &quot;UpdateExpression&quot;:
+                return 15;
+            case &quot;CallExpression&quot;:
+                // IIFE is allowed to have parens in any position (#655)
+                if (node.callee.type === &quot;FunctionExpression&quot;) {
+                    return -1;
+                }
+                return 16;
+            case &quot;NewExpression&quot;:
+                return 17;
+            // no default
+        }
+        return 18;
+    }
+
+    function report(node) {
+        context.report(node, &quot;Gratuitous parentheses around expression.&quot;);
+    }
+
+    function dryUnaryUpdate(node) {
+        if (isParenthesised(node.argument) &amp;&amp; precedence(node.argument) &gt;= precedence(node)) {
+            report(node.argument);
+        }
+    }
+
+    function dryCallNew(node) {
+        if (isParenthesised(node.callee) &amp;&amp; precedence(node.callee) &gt;= precedence(node) &amp;&amp;
+        !(node.type === &quot;CallExpression&quot; &amp;&amp; node.callee.type === &quot;FunctionExpression&quot;)) {
+            report(node.callee);
+        }
+        if (node.arguments.length === 1) {
+            if (isParenthesisedTwice(node.arguments[0]) &amp;&amp; precedence(node.arguments[0]) &gt;= precedence({type: &quot;AssignmentExpression&quot;})) {
+                report(node.arguments[0]);
+            }
+        } else {
+            [].forEach.call(node.arguments, function(arg) {
+                if (isParenthesised(arg) &amp;&amp; precedence(arg) &gt;= precedence({type: &quot;AssignmentExpression&quot;})) {
+                    report(arg);
+                }
+            });
+        }
+    }
+
+    function dryBinaryLogical(node) {
+        var prec = precedence(node);
+        if (isParenthesised(node.left) &amp;&amp; precedence(node.left) &gt;= prec) {
+            report(node.left);
+        }
+        if (isParenthesised(node.right) &amp;&amp; precedence(node.right) &gt; prec) {
+            report(node.right);
+        }
+    }
+
+    return {
+        &quot;ArrayExpression&quot;: function(node) {
+            [].forEach.call(node.elements, function(e) {
+                if (e &amp;&amp; isParenthesised(e) &amp;&amp; precedence(e) &gt;= precedence({type: &quot;AssignmentExpression&quot;})) {
+                    report(e);
+                }
+            });
+        },
+        &quot;AssignmentExpression&quot;: function(node) {
+            if (isParenthesised(node.right) &amp;&amp; precedence(node.right) &gt;= precedence(node)) {
+                report(node.right);
+            }
+        },
+        &quot;BinaryExpression&quot;: dryBinaryLogical,
+        &quot;CallExpression&quot;: dryCallNew,
+        &quot;ConditionalExpression&quot;: function(node) {
+            if (isParenthesised(node.test) &amp;&amp; precedence(node.test) &gt;= precedence({type: &quot;LogicalExpression&quot;, operator: &quot;||&quot;})) {
+                report(node.test);
+            }
+            if (isParenthesised(node.consequent) &amp;&amp; precedence(node.consequent) &gt;= precedence({type: &quot;AssignmentExpression&quot;})) {
+                report(node.consequent);
+            }
+            if (isParenthesised(node.alternate) &amp;&amp; precedence(node.alternate) &gt;= precedence({type: &quot;AssignmentExpression&quot;})) {
+                report(node.alternate);
+            }
+        },
+        &quot;DoWhileStatement&quot;: function(node) {
+            if (isParenthesisedTwice(node.test)) {
+                report(node.test);
+            }
+        },
+        &quot;ExpressionStatement&quot;: function(node) {
+            var firstToken;
+            if (isParenthesised(node.expression)) {
+                firstToken = context.getFirstToken(node.expression);
+                if (firstToken.value !== &quot;function&quot; &amp;&amp; firstToken.value !== &quot;{&quot;) {
+                    report(node.expression);
+                }
+            }
+        },
+        &quot;ForInStatement&quot;: function(node) {
+            if (isParenthesised(node.right)) {
+                report(node.right);
+            }
+        },
+        &quot;ForStatement&quot;: function(node) {
+            if (node.init &amp;&amp; isParenthesised(node.init)) {
+                report(node.init);
+            }
+
+            if (node.test &amp;&amp; isParenthesised(node.test)) {
+                report(node.test);
+            }
+
+            if (node.update &amp;&amp; isParenthesised(node.update)) {
+                report(node.update);
+            }
+        },
+        &quot;IfStatement&quot;: function(node) {
+            if (isParenthesisedTwice(node.test)) {
+                report(node.test);
+            }
+        },
+        &quot;LogicalExpression&quot;: dryBinaryLogical,
+        &quot;MemberExpression&quot;: function(node) {
+            if (
+                isParenthesised(node.object) &amp;&amp;
+                precedence(node.object) &gt;= precedence(node) &amp;&amp;
+                (
+                    node.computed ||
+                    !(
+                        node.object.type === &quot;Literal&quot; &amp;&amp;
+                        typeof node.object.value === &quot;number&quot; &amp;&amp;
+                        /^[0-9]+$/.test(context.getFirstToken(node.object).value)
+                    )
+                )
+            ) {
+                report(node.object);
+            }
+        },
+        &quot;NewExpression&quot;: dryCallNew,
+        &quot;ObjectExpression&quot;: function(node) {
+            [].forEach.call(node.properties, function(e) {
+                var v = e.value;
+                if (v &amp;&amp; isParenthesised(v) &amp;&amp; precedence(v) &gt;= precedence({type: &quot;AssignmentExpression&quot;})) {
+                    report(v);
+                }
+            });
+        },
+        &quot;ReturnStatement&quot;: function(node) {
+            if (node.argument &amp;&amp; isParenthesised(node.argument)) {
+                report(node.argument);
+            }
+        },
+        &quot;SequenceExpression&quot;: function(node) {
+            [].forEach.call(node.expressions, function(e) {
+                if (isParenthesised(e) &amp;&amp; precedence(e) &gt;= precedence(node)) {
+                    report(e);
+                }
+            });
+        },
+        &quot;SwitchCase&quot;: function(node) {
+            if (node.test &amp;&amp; isParenthesised(node.test)) {
+                report(node.test);
+            }
+        },
+        &quot;SwitchStatement&quot;: function(node) {
+            if (isParenthesisedTwice(node.discriminant)) {
+                report(node.discriminant);
+            }
+        },
+        &quot;ThrowStatement&quot;: function(node) {
+            if (isParenthesised(node.argument)) {
+                report(node.argument);
+            }
+        },
+        &quot;UnaryExpression&quot;: dryUnaryUpdate,
+        &quot;UpdateExpression&quot;: dryUnaryUpdate,
+        &quot;VariableDeclarator&quot;: function(node) {
+            if (node.init &amp;&amp; isParenthesised(node.init) &amp;&amp; precedence(node.init) &gt;= precedence({type: &quot;AssignmentExpression&quot;})) {
+                report(node.init);
+            }
+        },
+        &quot;WhileStatement&quot;: function(node) {
+            if (isParenthesisedTwice(node.test)) {
+                report(node.test);
+            }
+        },
+        &quot;WithStatement&quot;: function(node) {
+            if (isParenthesisedTwice(node.object)) {
+                report(node.object);
+            }
+        }
+    };
+
+};
+
+},{}],64:[function(require,module,exports){
+/**
+ * @fileoverview Rule to flag use of unnecessary semicolons
+ * @author Nicholas C. Zakas
+ */
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+    &quot;use strict&quot;;
+
+    return {
+
+        &quot;EmptyStatement&quot;: function(node) {
+            context.report(node, &quot;Unnecessary semicolon.&quot;);
+        }
+    };
+
+};
+
+},{}],65:[function(require,module,exports){
+/**
+ * @fileoverview Rule to flag unnecessary strict directives.
+ * @author Ian Christian Myers
+ */
+&quot;use strict&quot;;
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+    function directives(block) {
+        var ds = [], body = block.body, e, i, l;
+
+        for (i = 0, l = body.length; i &lt; l; ++i) {
+            e = body[i];
+
+            if (
+                e.type === &quot;ExpressionStatement&quot; &amp;&amp;
+                e.expression.type === &quot;Literal&quot; &amp;&amp;
+                typeof e.expression.value === &quot;string&quot;
+            ) {
+                ds.push(e.expression);
+            } else {
+                break;
+            }
+        }
+        return ds;
+    }
+
+    function isStrict(directive) {
+        return directive.value === &quot;use strict&quot;;
+    }
+
+    function checkForUnnecessaryUseStrict(node) {
+        var useStrictDirectives, scope, upper;
+        useStrictDirectives = directives(node).filter(isStrict);
+
+        switch (useStrictDirectives.length) {
+            case 0:
+                break;
+
+            case 1:
+                scope = context.getScope();
+                upper = scope.upper;
+
+                if (upper &amp;&amp; upper.functionExpressionScope) {
+                    upper = upper.upper;
+                }
+
+                if (upper &amp;&amp; upper.isStrict) {
+                    context.report(useStrictDirectives[0], &quot;Unnecessary 'use strict'.&quot;);
+                }
+                break;
+
+            default:
+                context.report(useStrictDirectives[1], &quot;Multiple 'use strict' directives.&quot;);
+        }
+    }
+
+    return {
+
+        &quot;Program&quot;: checkForUnnecessaryUseStrict,
+
+        &quot;FunctionExpression&quot;: function(node) {
+            checkForUnnecessaryUseStrict(node.body);
+        },
+
+        &quot;FunctionDeclaration&quot;: function(node) {
+            checkForUnnecessaryUseStrict(node.body);
+        }
+    };
+
+};
+
+},{}],66:[function(require,module,exports){
+/**
+ * @fileoverview Rule to flag fall-through cases in switch statements.
+ * @author Matt DuVall &lt;http://mattduvall.com/&gt;
+ */
+&quot;use strict&quot;;
+
+
+var FALLTHROUGH_COMMENT = /falls\sthrough/;
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+    var switches = [];
+
+    return {
+
+        &quot;SwitchCase&quot;: function(node) {
+
+            var consequent = node.consequent,
+                switchData = switches[switches.length - 1],
+                i,
+                comments,
+                comment;
+
+            /*
+             * Some developers wrap case bodies in blocks, so if there is just one
+             * node and it's a block statement, check inside.
+             */
+            if (consequent.length === 1 &amp;&amp; consequent[0].type === &quot;BlockStatement&quot;) {
+                consequent = consequent[0];
+            }
+
+            // checking on previous case
+            if (!switchData.lastCaseClosed) {
+
+                // a fall through comment will be the last trailing comment of the last case
+                comments = context.getComments(switchData.lastCase).trailing;
+                comment = comments[comments.length - 1];
+
+                // check for comment
+                if (!comment || !FALLTHROUGH_COMMENT.test(comment.value)) {
+                    context.report(switchData.lastCase,
+                        &quot;Expected a \&quot;break\&quot; statement before \&quot;{{code}}\&quot;.&quot;,
+                        { code: node.test ? &quot;case&quot; : &quot;default&quot; });
+                }
+            }
+
+            // now dealing with the current case
+            switchData.lastCaseClosed = false;
+            switchData.lastCase = node;
+
+            // try to verify using statements - go backwards as a fast path for the search
+            if (consequent.length) {
+                for (i = consequent.length - 1; i &gt;= 0; i--) {
+                    if (/(?:Break|Continue|Return|Throw)Statement/.test(consequent[i].type)) {
+                        switchData.lastCaseClosed = true;
+                        break;
+                    }
+                }
+            } else {
+                // the case statement has no statements, so it must logically fall through
+                switchData.lastCaseClosed = true;
+            }
+
+            /*
+             * Any warnings are triggered when the next SwitchCase occurs.
+             * There is no need to warn on the last SwitchCase, since it can't
+             * fall through to anything.
+             */
+        },
+
+        &quot;SwitchStatement&quot;: function(node) {
+            switches.push({
+                node: node,
+                lastCaseClosed: true,
+                lastCase: null
+            });
+        },
+
+        &quot;SwitchStatement:exit&quot;: function() {
+            switches.pop();
+        }
+    };
+
+};
+
+},{}],67:[function(require,module,exports){
+/**
+ * @fileoverview Rule to flag use of a leading/trailing decimal point in a numeric literal
+ * @author James Allardice
+ */
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+    &quot;use strict&quot;;
+
+    return {
+        &quot;Literal&quot;: function(node) {
+
+            if (typeof node.value === &quot;number&quot;) {
+                if (node.raw.indexOf(&quot;.&quot;) === 0) {
+                    context.report(node, &quot;A leading decimal point can be confused with a dot.&quot;);
+                }
+                if (node.raw.indexOf(&quot;.&quot;) === node.raw.length - 1) {
+                    context.report(node, &quot;A trailing decimal point can be confused with a dot.&quot;);
+                }
+            }
+        }
+    };
+
+};
+
+},{}],68:[function(require,module,exports){
+/**
+ * @fileoverview Rule to flag use of function declaration identifiers as variables.
+ * @author Ian Christian Myers
+ */
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+    &quot;use strict&quot;;
+
+    //--------------------------------------------------------------------------
+    // Helpers
+    //--------------------------------------------------------------------------
+
+    /*
+     * Walk the scope chain looking for either a FunctionDeclaration or a
+     * VariableDeclaration with the same name as left-hand side of the
+     * AssignmentExpression. If we find the FunctionDeclaration first, then we
+     * warn, because a FunctionDeclaration is trying to become a Variable or a
+     * FunctionExpression. If we find a VariableDeclaration first, then we have
+     * a legitimate shadow variable.
+     */
+    function checkIfIdentifierIsFunction(scope, name) {
+        var variable,
+            def,
+            i,
+            j;
+
+        // Loop over all of the identifiers available in scope.
+        for (i = 0; i &lt; scope.variables.length; i++) {
+            variable = scope.variables[i];
+
+            // For each identifier, see if it was defined in _this_ scope.
+            for (j = 0; j &lt; variable.defs.length; j++) {
+                def = variable.defs[j];
+
+                // Identifier is a function and was declared in this scope
+                if (def.name.name === name &amp;&amp; def.type === &quot;FunctionName&quot;) {
+                    return true;
+                }
+
+                // Identifier is a variable and was declared in this scope. This
+                // is a legitimate shadow variable.
+                if (def.name.name === name) {
+                    return false;
+                }
+            }
+        }
+
+        // Check the upper scope.
+        if (scope.upper) {
+            return checkIfIdentifierIsFunction(scope.upper, name);
+        }
+
+        // We've reached the global scope and haven't found anything.
+        return false;
+    }
+
+    //--------------------------------------------------------------------------
+    // Public API
+    //--------------------------------------------------------------------------
+
+    return {
+
+        &quot;AssignmentExpression&quot;: function(node) {
+            var scope = context.getScope(),
+                name = node.left.name;
+
+            if (checkIfIdentifierIsFunction(scope, name)) {
+                context.report(node, &quot;'{{name}}' is a function.&quot;, { name: name });
+            }
+
+        }
+
+    };
+
+};
+
+},{}],69:[function(require,module,exports){
+/**
+ * @fileoverview Rule to flag use of implied eval via setTimeout and setInterval
+ * @author James Allardice
+ */
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+    &quot;use strict&quot;;
+
+    return {
+        &quot;CallExpression&quot;: function(node) {
+
+            if (node.callee.type === &quot;Identifier&quot;) {
+                var callee = node.callee.name;
+
+                if (callee === &quot;setTimeout&quot; || callee === &quot;setInterval&quot;) {
+                    var argument = node.arguments[0];
+                    if (argument &amp;&amp; argument.type === &quot;Literal&quot; &amp;&amp; typeof argument.value === &quot;string&quot;) {
+                        context.report(node, &quot;Implied eval. Consider passing a function instead of a string.&quot;);
+                    }
+                }
+            }
+        }
+    };
+
+};
+
+},{}],70:[function(require,module,exports){
+/**
+ * @fileoverview Rule to enforce declarations in program or function body root.
+ * @author Brandon Mills
+ */
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+    &quot;use strict&quot;;
+
+    /**
+     * Find the nearest Program or Function ancestor node.
+     * @returns {Object} Ancestor's type and distance from node.
+     */
+    function nearestBody() {
+        var ancestors = context.getAncestors(),
+            ancestor = ancestors.pop(),
+            generation = 1;
+
+        while (ancestor &amp;&amp; [&quot;Program&quot;, &quot;FunctionDeclaration&quot;,
+                &quot;FunctionExpression&quot;].indexOf(ancestor.type) &lt; 0) {
+            generation += 1;
+            ancestor = ancestors.pop();
+        }
+
+        return {
+            // Type of containing ancestor
+            type: ancestor.type,
+            // Separation between ancestor and node
+            distance: generation
+        };
+    }
+
+    /**
+     * Ensure that a given node is at a program or function body's root.
+     * @param {ASTNode} node Declaration node to check.
+     * @returns {void}
+     */
+    function check(node) {
+        var body = nearestBody(node),
+            valid = ((body.type === &quot;Program&quot; &amp;&amp; body.distance === 1) ||
+                body.distance === 2);
+
+        if (!valid) {
+            context.report(node, &quot;Move {{type}} declaration to {{body}} root.&quot;,
+                {
+                    type: (node.type === &quot;FunctionDeclaration&quot; ?
+                        &quot;function&quot; : &quot;variable&quot;),
+                    body: (body.type === &quot;Program&quot; ?
+                        &quot;program&quot; : &quot;function body&quot;)
+                }
+            );
+        }
+    }
+
+    return {
+
+        &quot;FunctionDeclaration&quot;: check,
+        &quot;VariableDeclaration&quot;: function(node) {
+            if (context.options[0] === &quot;both&quot;) {
+                check(node);
+            }
+        }
+
+    };
+
+};
+
+},{}],71:[function(require,module,exports){
+/**
+ * @fileoverview Validate strings passed to the RegExp constructor
+ * @author Michael Ficarra
+ */
+&quot;use strict&quot;;
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+    function isString(node) {
+        return node &amp;&amp; node.type === &quot;Literal&quot; &amp;&amp; typeof node.value === &quot;string&quot;;
+    }
+
+    function check(node) {
+        if (node.callee.type === &quot;Identifier&quot; &amp;&amp; node.callee.name === &quot;RegExp&quot; &amp;&amp; isString(node.arguments[0])) {
+            try {
+                if (isString(node.arguments[1])) {
+                    void new RegExp(node.arguments[0].value, node.arguments[1].value);
+                } else {
+                    void new RegExp(node.arguments[0].value);
+                }
+            } catch(e) {
+                context.report(node, e.message);
+            }
+        }
+    }
+
+    return {
+        &quot;CallExpression&quot;: check,
+        &quot;NewExpression&quot;: check
+    };
+
+};
+
+},{}],72:[function(require,module,exports){
+/**
+ * @fileoverview Rule to flag usage of __iterator__ property
+ * @author Ian Christian Myers
+ */
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+    &quot;use strict&quot;;
+
+    return {
+
+        &quot;MemberExpression&quot;: function(node) {
+
+            if (node.property &amp;&amp;
+                    (node.property.type === &quot;Identifier&quot; &amp;&amp; node.property.name === &quot;__iterator__&quot; &amp;&amp; !node.computed) ||
+                    (node.property.type === &quot;Literal&quot; &amp;&amp; node.property.value === &quot;__iterator__&quot;)) {
+                context.report(node, &quot;Reserved name '__iterator__'.&quot;);
+            }
+        }
+    };
+
+};
+
+},{}],73:[function(require,module,exports){
+/**
+ * @fileoverview Rule to flag labels that are the same as an identifier
+ * @author Ian Christian Myers
+ */
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+    &quot;use strict&quot;;
+
+    //--------------------------------------------------------------------------
+    // Helpers
+    //--------------------------------------------------------------------------
+
+    function findIdentifier(scope, identifier) {
+        var found = false;
+
+        scope.variables.forEach(function(variable) {
+            if (variable.name === identifier) {
+                found = true;
+            }
+        });
+
+        scope.references.forEach(function(reference) {
+            if (reference.identifier.name === identifier) {
+                found = true;
+            }
+        });
+
+        // If we have not found the identifier in this scope, check the parent
+        // scope.
+        if (scope.upper &amp;&amp; !found) {
+            return findIdentifier(scope.upper, identifier);
+        }
+
+        return found;
+    }
+
+    //--------------------------------------------------------------------------
+    // Public API
+    //--------------------------------------------------------------------------
+
+    return {
+
+        &quot;LabeledStatement&quot;: function(node) {
+
+            // Fetch the innermost scope.
+            var scope = context.getScope();
+
+            // Recursively find the identifier walking up the scope, starting
+            // with the innermost scope.
+            if (findIdentifier(scope, node.label.name)) {
+                context.report(node, &quot;Found identifier with same name as label.&quot;);
+            }
+        }
+
+    };
+
+};
+
+},{}],74:[function(require,module,exports){
+/**
+ * @fileoverview Disallow Labeled Statements
+ * @author Nicholas C. Zakas
+ */
+&quot;use strict&quot;;
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+    //--------------------------------------------------------------------------
+    // Public
+    //--------------------------------------------------------------------------
+
+    return {
+
+        &quot;LabeledStatement&quot;: function(node) {
+            context.report(node, &quot;Unexpected labeled statement.&quot;);
+        },
+
+        &quot;BreakStatement&quot;: function(node) {
+
+            if (node.label) {
+                context.report(node, &quot;Unexpected label in break statement.&quot;);
+            }
+
+        },
+
+        &quot;ContinueStatement&quot;: function(node) {
+
+            if (node.label) {
+                context.report(node, &quot;Unexpected label in continue statement.&quot;);
+            }
+
+        }
+
+
+    };
+
+};
+
+},{}],75:[function(require,module,exports){
+/**
+ * @fileoverview Rule to flag blocks with no reason to exist
+ * @author Brandon Mills
+ */
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+    &quot;use strict&quot;;
+
+    return {
+        &quot;BlockStatement&quot;: function (node) {
+            // Check for any occurrence of BlockStatement &gt; BlockStatement or
+            // Program &gt; BlockStatement
+            var parent = context.getAncestors().pop();
+            if (parent.type === &quot;BlockStatement&quot; || parent.type === &quot;Program&quot;) {
+                context.report(node, &quot;Block is nested inside another block.&quot;);
+            }
+        }
+    };
+
+};
+
+},{}],76:[function(require,module,exports){
+/**
+ * @fileoverview Rule to disallow if as the only statmenet in an else block
+ * @author Brandon Mills
+ */
+&quot;use strict&quot;;
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+    return {
+        &quot;IfStatement&quot;: function(node) {
+            var ancestors = context.getAncestors(),
+                parent = ancestors.pop(),
+                grandparent = ancestors.pop();
+
+            if (parent &amp;&amp; parent.type === &quot;BlockStatement&quot; &amp;&amp;
+                    parent.body.length === 1 &amp;&amp; grandparent &amp;&amp;
+                    grandparent.type === &quot;IfStatement&quot; &amp;&amp;
+                    parent === grandparent.alternate) {
+                context.report(node, &quot;Unexpected if as the only statement in an else block.&quot;);
+            }
+        }
+    };
+
+};
+
+},{}],77:[function(require,module,exports){
+/**
+ * @fileoverview Rule to flag creation of function inside a loop
+ * @author Ilya Volodin
+ */
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+    &quot;use strict&quot;;
+
+    function checkForLoops(node) {
+        var ancestors = context.getAncestors();
+
+        if (ancestors.some(function(ancestor) {
+            return ancestor.type === &quot;ForStatement&quot; || ancestor.type === &quot;WhileStatement&quot; || ancestor.type === &quot;DoWhileStatement&quot;;
+        })) {
+            context.report(node, &quot;Don't make functions within a loop&quot;);
+        }
+    }
+
+    return {
+        &quot;FunctionExpression&quot;: checkForLoops,
+        &quot;FunctionDeclaration&quot;: checkForLoops
+    };
+};
+
+},{}],78:[function(require,module,exports){
+/**
+ * @fileoverview Rule to enforce grouped require statements for Node.JS
+ * @author Raphael Pigulla
+ */
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+    &quot;use strict&quot;;
+
+    /**
+     * Returns the list of built-in modules.
+     *
+     * @returns {string[]} An array of built-in Node.js modules.
+     */
+    function getBuiltinModules() {
+        // This list is generated using `require(&quot;repl&quot;)._builtinLibs.concat('repl').sort()`
+        // This particular list was generated using node v0.11.9
+        return [
+            &quot;assert&quot;, &quot;buffer&quot;, &quot;child_process&quot;, &quot;cluster&quot;, &quot;crypto&quot;,
+            &quot;dgram&quot;, &quot;dns&quot;, &quot;domain&quot;, &quot;events&quot;, &quot;fs&quot;, &quot;http&quot;, &quot;https&quot;,
+            &quot;net&quot;, &quot;os&quot;, &quot;path&quot;, &quot;punycode&quot;, &quot;querystring&quot;, &quot;readline&quot;,
+            &quot;repl&quot;, &quot;smalloc&quot;, &quot;stream&quot;, &quot;string_decoder&quot;, &quot;tls&quot;, &quot;tty&quot;,
+            &quot;url&quot;, &quot;util&quot;, &quot;vm&quot;, &quot;zlib&quot;
+        ];
+    }
+
+    var BUILTIN_MODULES = getBuiltinModules();
+
+    var DECL_REQUIRE = &quot;require&quot;,
+        DECL_UNINITIALIZED = &quot;uninitialized&quot;,
+        DECL_OTHER = &quot;other&quot;;
+
+    var REQ_CORE = &quot;core&quot;,
+        REQ_FILE = &quot;file&quot;,
+        REQ_MODULE = &quot;module&quot;,
+        REQ_COMPUTED = &quot;computed&quot;;
+
+    /**
+     * Determines the type of a declaration statement.
+     * @param {ASTNode} initExpression The init node of the VariableDeclarator.
+     * @returns {string} The type of declaration represented by the expression.
+     */
+    function getDeclarationType(initExpression) {
+        if (!initExpression) {
+            // &quot;var x;&quot;
+            return DECL_UNINITIALIZED;
+        }
+
+        if (initExpression.type === &quot;CallExpression&quot; &amp;&amp;
+            initExpression.callee.type === &quot;Identifier&quot; &amp;&amp;
+            initExpression.callee.name === &quot;require&quot;
+        ) {
+            // &quot;var x = require('util');&quot;
+            return DECL_REQUIRE;
+        } else if (initExpression.type === &quot;MemberExpression&quot;) {
+            // &quot;var x = require('glob').Glob;&quot;
+            return getDeclarationType(initExpression.object);
+        }
+
+        // &quot;var x = 42;&quot;
+        return DECL_OTHER;
+    }
+
+    /**
+     * Determines the type of module that is loaded via require.
+     * @param {ASTNode} initExpression The init node of the VariableDeclarator.
+     * @returns {string} The module type.
+     */
+    function inferModuleType(initExpression) {
+        if (initExpression.type === &quot;MemberExpression&quot;) {
+            // &quot;var x = require('glob').Glob;&quot;
+            return inferModuleType(initExpression.object);
+        } else if (initExpression[&quot;arguments&quot;].length === 0) {
+            // &quot;var x = require();&quot;
+            return REQ_COMPUTED;
+        }
+
+        var arg = initExpression[&quot;arguments&quot;][0];
+
+        if (arg.type !== &quot;Literal&quot; || typeof arg.value !== &quot;string&quot;) {
+            // &quot;var x = require(42);&quot;
+            return REQ_COMPUTED;
+        }
+
+        if (BUILTIN_MODULES.indexOf(arg.value) !== -1) {
+            // &quot;var fs = require('fs');&quot;
+            return REQ_CORE;
+        } else if (/^\.{0,2}\//.test(arg.value)) {
+            // &quot;var utils = require('./utils');&quot;
+            return REQ_FILE;
+        } else {
+            // &quot;var async = require('async');&quot;
+            return REQ_MODULE;
+        }
+    }
+
+    /**
+     * Check if the list of variable declarations is mixed, i.e. whether it
+     * contains both require and other declarations.
+     * @param {ASTNode} declarations The list of VariableDeclarators.
+     * @returns {boolean} True if the declarations are mixed, false if not.
+     */
+    function isMixed(declarations) {
+        var contains = {};
+
+        declarations.forEach(function (declaration) {
+            var type = getDeclarationType(declaration.init);
+            contains[type] = true;
+        });
+
+        return !!(
+            contains[DECL_REQUIRE] &amp;&amp;
+            (contains[DECL_UNINITIALIZED] || contains[DECL_OTHER])
+        );
+    }
+
+    /**
+     * Check if all require declarations in the given list are of the same
+     * type.
+     * @param {ASTNode} declarations The list of VariableDeclarators.
+     * @returns {boolean} True if the declarations are grouped, false if not.
+     */
+    function isGrouped(declarations) {
+        var found = {};
+
+        declarations.forEach(function (declaration) {
+            if (getDeclarationType(declaration.init) === DECL_REQUIRE) {
+                found[inferModuleType(declaration.init)] = true;
+            }
+        });
+
+        return Object.keys(found).length &lt;= 1;
+    }
+
+
+    return {
+
+        &quot;VariableDeclaration&quot;: function(node) {
+            var grouping = !!context.options[0];
+
+            if (isMixed(node.declarations)) {
+                context.report(
+                    node,
+                    &quot;Do not mix 'require' and other declarations.&quot;
+                );
+            } else if (grouping &amp;&amp; !isGrouped(node.declarations)) {
+                context.report(
+                    node,
+                    &quot;Do not mix core, module, file and computed requires.&quot;
+                );
+            }
+        }
+    };
+
+};
+
+},{}],79:[function(require,module,exports){
+/**
+ * @fileoverview Disallow mixed spaces and tabs for indentation
+ * @author Jary Niebur
+ * @copyright 2014 Nicholas C. Zakas. All rights reserved.
+ * @copyright 2014 Jary Niebur. All rights reserved.
+ */
+&quot;use strict&quot;;
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+    var smartTabs = context.options[0];
+
+    var COMMENT_START = /^\s*\/\*/,
+        MAYBE_COMMENT = /^\s*\*/;
+
+    //--------------------------------------------------------------------------
+    // Public
+    //--------------------------------------------------------------------------
+
+    return {
+
+        &quot;Program&quot;: function(node) {
+            /*
+             * At least one space followed by a tab
+             * or the reverse before non-tab/-space
+             * characters begin.
+             */
+            var regex = /^(?=[\t ]*(\t | \t))/,
+                match,
+                lines = context.getSourceLines();
+
+            if (smartTabs) {
+                /*
+                 * At least one space followed by a tab
+                 * before non-tab/-space characters begin.
+                 */
+                regex = /^(?=[\t ]* \t)/;
+            }
+
+            lines.forEach(function(line, i) {
+                match = regex.exec(line);
+
+                if (match) {
+
+                    if (!MAYBE_COMMENT.test(line) &amp;&amp; !COMMENT_START.test(lines[i - 1])) {
+                        context.report(node, { line: i + 1, column: match.index + 1 }, &quot;Mixed spaces and tabs.&quot;);
+                    }
+
+                }
+            });
+        }
+
+    };
+
+};
+
+},{}],80:[function(require,module,exports){
+/**
+ * @fileoverview Disallow use of multiple spaces.
+ * @author Vignesh Anand aka vegetableman.
+ * @copyright 2014 Vignesh Anand. All rights reserved.
+ */
+&quot;use strict&quot;;
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+    var OPERATORS = [
+        &quot;*&quot;, &quot;/&quot;, &quot;%&quot;, &quot;+&quot;, &quot;-&quot;, &quot;&lt;&lt;&quot;, &quot;&gt;&gt;&quot;, &quot;&gt;&gt;&gt;&quot;, &quot;&lt;&quot;, &quot;&lt;=&quot;, &quot;&gt;&quot;, &quot;&gt;=&quot;, &quot;in&quot;,
+        &quot;instanceof&quot;, &quot;==&quot;, &quot;!=&quot;, &quot;===&quot;, &quot;!==&quot;, &quot;&amp;&quot;, &quot;^&quot;, &quot;|&quot;, &quot;&amp;&amp;&quot;, &quot;||&quot;, &quot;=&quot;,
+        &quot;+=&quot;, &quot;-=&quot;, &quot;*=&quot;, &quot;/=&quot;, &quot;%=&quot;, &quot;&lt;&lt;=&quot;, &quot;&gt;&gt;=&quot;, &quot;&gt;&gt;&gt;=&quot;, &quot;&amp;=&quot;, &quot;^=&quot;, &quot;|=&quot;,
+        &quot;?&quot;, &quot;:&quot;, &quot;,&quot;
+    ], errOps = [];
+
+    //--------------------------------------------------------------------------
+    // Helpers
+    //--------------------------------------------------------------------------
+
+    /**
+     * Reports an AST node as a rule violation.
+     * @param {ASTNode} node The node to report.
+     * @returns {void}
+     * @private
+     */
+    function report(node) {
+        context.report(node, &quot;Multiple spaces found around '&quot; + errOps.shift() + &quot;'.&quot;);
+    }
+
+    /**
+     * Checks whether the operator is in same line as two adjacent tokens.
+     * @param {ASTNode} left The token left to the operator.
+     * @param {ASTNode} right The token right to the operator.
+     * @param {ASTNode} operator The operator.
+     * @returns {boolean} Whether the operator is in same line as two adjacent tokens.
+     * @private
+     */
+    function isSameLine(left, right, operator) {
+        return operator.loc.end.line === left.loc.end.line &amp;&amp;
+                        operator.loc.end.line === right.loc.start.line;
+    }
+
+    /**
+     * Check whether there are multiple spaces around the operator.
+     * @param {ASTNode} left The token left to the operator.
+     * @param {ASTNode} right The token right to the operator.
+     * @param {ASTNode} operator The operator.
+     * @returns {boolean} Whether there are multiple spaces.
+     * @private
+     */
+    function isMultiSpaced(left, right, operator) {
+        return operator.range[0] - left.range[1] &gt; 1 ||
+                right.range[0] - operator.range[1] &gt; 1;
+    }
+
+    /**
+     * Get tokens and validate the spacing.
+     * @param {ASTNode} left The token left to the operator.
+     * @param {ASTNode} right The token right to the operator.
+     * @returns {boolean} Whether multiple spaces were found.
+     * @private
+     */
+    function validateSpacing(left, right) {
+        var tokens = context.getTokens({range: [left.range[1], right.range[0]]}, 1, 1),
+            operator;
+
+        for (var i = 1, l = tokens.length - 1; i &lt; l; ++i) {
+            left = tokens[i - 1];
+            operator = tokens[i];
+            right = tokens[i + 1];
+
+            if (operator &amp;&amp; operator.type === &quot;Punctuator&quot; &amp;&amp; OPERATORS.indexOf(operator.value) &gt;= 0 &amp;&amp;
+                isSameLine(left, right, operator) &amp;&amp; isMultiSpaced(left, right, operator)) {
+                errOps.push(operator.value);
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+
+    /**
+     * Report if there are multiple spaces on the expression.
+     * @param {ASTNode} node The node to check.
+     * @returns {void}
+     * @private
+     */
+    function checkExpression(node) {
+        if (validateSpacing(node.left, node.right)) {
+            report(node);
+        }
+    }
+
+    /**
+     * Report if there are multiple spaces around conditional ternary operators.
+     * @param {ASTNode} node The node to check.
+     * @returns {void}
+     * @private
+     */
+    function checkConditional(node) {
+        if (validateSpacing(node.test, node.consequent)) {
+            report(node);
+        }
+        if (validateSpacing(node.consequent, node.alternate)) {
+            report(node);
+        }
+    }
+
+    /**
+     * Report if there are multiple spaces around equal operator in variable declaration.
+     * @param {ASTNode} node The node to check.
+     * @returns {void}
+     * @private
+     */
+    function checkVar(node) {
+        if (node.init &amp;&amp; validateSpacing(node.id, node.init)) {
+            report(node);
+        }
+    }
+
+    /**
+     * Report if there are multiple spaces around list of items in objects, arrays,
+     * function parameters, sequences and declarations.
+     * @param {ASTNode} node The node to check.
+     * @param {string} property The property of node.
+     * @returns {void}
+     * @private
+     */
+    function checkList(node, property) {
+        var items = node[property];
+
+        for (var i = 0, l = items.length; i &lt; l; i++) {
+            var left = items[i - 1],
+                right = items[i],
+                operator = context.getTokenBefore(right);
+
+            if (operator &amp;&amp; operator.type === &quot;Punctuator&quot; &amp;&amp; operator.value === &quot;,&quot;) {
+                if (isSameLine(left, right, operator) &amp;&amp; isMultiSpaced(left, right, operator)) {
+                    errOps.push(operator.value);
+                    report(right);
+                }
+            }
+        }
+    }
+
+    //--------------------------------------------------------------------------
+    // Public
+    //--------------------------------------------------------------------------
+
+    return {
+        &quot;AssignmentExpression&quot;: checkExpression,
+        &quot;BinaryExpression&quot;: checkExpression,
+        &quot;LogicalExpression&quot;: checkExpression,
+        &quot;ConditionalExpression&quot;: checkConditional,
+        &quot;VariableDeclarator&quot;: checkVar,
+        &quot;ArrayExpression&quot;: function(node) {
+            checkList(node, &quot;elements&quot;);
+        },
+        &quot;ObjectExpression&quot;: function(node) {
+            checkList(node, &quot;properties&quot;);
+        },
+        &quot;SequenceExpression&quot;: function(node) {
+            checkList(node, &quot;expressions&quot;);
+        },
+        &quot;FunctionExpression&quot;: function(node) {
+            checkList(node, &quot;params&quot;);
+        },
+        &quot;FunctionDeclaration&quot;: function(node) {
+            checkList(node, &quot;params&quot;);
+        },
+        &quot;VariableDeclaration&quot;: function(node) {
+            checkList(node, &quot;declarations&quot;);
+        }
+    };
+
+};
+
+},{}],81:[function(require,module,exports){
+/**
+ * @fileoverview Rule to flag when using multiline strings
+ * @author Ilya Volodin
+ */
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+    &quot;use strict&quot;;
+
+    return {
+
+        &quot;Literal&quot;: function(node) {
+            var lineBreak = /\n/;
+            if (lineBreak.test(node.raw)) {
+                context.report(node, &quot;Multiline support is limited to browsers supporting ES5 only.&quot;);
+            }
+        }
+    };
+
+};
+
+},{}],82:[function(require,module,exports){
+/**
+ * @fileoverview Disallows multiple blank lines.
+ * implementation adapted from the no-trailing-spaces rule.
+ * @author Greg Cochard
+ * @copyright 2014 Greg Cochard. All rights reserved.
+ */
+&quot;use strict&quot;;
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+    // Use options.max or 2 as default
+    var numLines = 2;
+
+    if (context.options.length) {
+        numLines = context.options[0].max;
+    }
+
+    //--------------------------------------------------------------------------
+    // Public
+    //--------------------------------------------------------------------------
+
+    return {
+
+        &quot;Program&quot;: function checkBlankLines(node) {
+            var lines = context.getSourceLines(),
+                currentLocation = -1,
+                lastLocation,
+                blankCounter = 0,
+                location,
+                trimmedLines = lines.map(function(str) {
+                    return str.trim();
+                });
+
+            // Aggregate and count blank lines
+            do {
+                lastLocation = currentLocation;
+                currentLocation = trimmedLines.indexOf(&quot;&quot;,currentLocation + 1);
+                if (lastLocation === currentLocation - 1) {
+                    blankCounter++;
+                } else {
+                    if (blankCounter &gt;= numLines) {
+                        location = {
+                            line: lastLocation + 1,
+                            column: lines[lastLocation].length
+                        };
+                        context.report(node, location, &quot;Multiple blank lines not allowed.&quot;);
+                    }
+
+                    // Finally, reset the blank counter
+                    blankCounter = 0;
+                }
+            } while (currentLocation !== -1);
+        }
+    };
+
+};
+
+},{}],83:[function(require,module,exports){
+/**
+ * @fileoverview Rule to flag when re-assigning native objects
+ * @author Ilya Volodin
+ */
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+    &quot;use strict&quot;;
+
+    var nativeObjects = [&quot;Array&quot;, &quot;Boolean&quot;, &quot;Date&quot;, &quot;decodeURI&quot;,
+                        &quot;decodeURIComponent&quot;, &quot;encodeURI&quot;, &quot;encodeURIComponent&quot;,
+                        &quot;Error&quot;, &quot;eval&quot;, &quot;EvalError&quot;, &quot;Function&quot;, &quot;isFinite&quot;,
+                        &quot;isNaN&quot;, &quot;JSON&quot;, &quot;Math&quot;, &quot;Number&quot;, &quot;Object&quot;, &quot;parseInt&quot;,
+                        &quot;parseFloat&quot;, &quot;RangeError&quot;, &quot;ReferenceError&quot;, &quot;RegExp&quot;,
+                        &quot;String&quot;, &quot;SyntaxError&quot;, &quot;TypeError&quot;, &quot;URIError&quot;,
+                        &quot;Map&quot;, &quot;NaN&quot;, &quot;Set&quot;, &quot;WeakMap&quot;, &quot;Infinity&quot;, &quot;undefined&quot;];
+
+    return {
+
+        &quot;AssignmentExpression&quot;: function(node) {
+            if (nativeObjects.indexOf(node.left.name) &gt;= 0) {
+                context.report(node, node.left.name + &quot; is a read-only native object.&quot;);
+            }
+        },
+
+        &quot;VariableDeclarator&quot;: function(node) {
+            if (nativeObjects.indexOf(node.id.name) &gt;= 0) {
+                context.report(node, &quot;Redefinition of '{{nativeObject}}'.&quot;, { nativeObject: node.id.name });
+            }
+        }
+    };
+
+};
+
+},{}],84:[function(require,module,exports){
+/**
+ * @fileoverview A rule to disallow negated left operands of the `in` operator
+ * @author Michael Ficarra
+ */
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+    &quot;use strict&quot;;
+
+    return {
+
+        &quot;BinaryExpression&quot;: function(node) {
+            if (node.operator === &quot;in&quot; &amp;&amp; node.left.type === &quot;UnaryExpression&quot; &amp;&amp; node.left.operator === &quot;!&quot;) {
+                context.report(node, &quot;The `in` expression's left operand is negated&quot;);
+            }
+        }
+    };
+
+};
+
+},{}],85:[function(require,module,exports){
+/**
+ * @fileoverview Rule to flag nested ternary expressions
+ * @author Ian Christian Myers
+ */
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+    &quot;use strict&quot;;
+
+    return {
+        &quot;ConditionalExpression&quot;: function(node) {
+            if (node.alternate.type === &quot;ConditionalExpression&quot; ||
+                    node.consequent.type === &quot;ConditionalExpression&quot;) {
+                context.report(node, &quot;Do not nest ternary expressions&quot;);
+            }
+        }
+    };
+};
+
+},{}],86:[function(require,module,exports){
+/**
+ * @fileoverview Rule to flag when using new Function
+ * @author Ilya Volodin
+ */
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+    &quot;use strict&quot;;
+
+    return {
+
+        &quot;NewExpression&quot;: function(node) {
+            if (node.callee.name === &quot;Function&quot;) {
+                context.report(node, &quot;The Function constructor is eval.&quot;);
+            }
+        }
+    };
+
+};
+
+},{}],87:[function(require,module,exports){
+/**
+ * @fileoverview A rule to disallow calls to the Object constructor
+ * @author Matt DuVall &lt;http://www.mattduvall.com/&gt;
+ */
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+    &quot;use strict&quot;;
+
+    return {
+
+        &quot;NewExpression&quot;: function(node) {
+            if (node.callee.name === &quot;Object&quot;) {
+                context.report(node, &quot;The object literal notation {} is preferrable.&quot;);
+            }
+        }
+    };
+
+};
+
+},{}],88:[function(require,module,exports){
+/**
+ * @fileoverview Rule to disallow use of new operator with the `require` function
+ * @author Wil Moore III
+ */
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+    &quot;use strict&quot;;
+
+    return {
+
+        &quot;NewExpression&quot;: function(node) {
+            if (node.callee.type === &quot;Identifier&quot; &amp;&amp; node.callee.name === &quot;require&quot;) {
+                context.report(node, &quot;Unexpected use of new with require.&quot;);
+            }
+        }
+    };
+
+};
+
+},{}],89:[function(require,module,exports){
+/**
+ * @fileoverview Rule to flag when using constructor for wrapper objects
+ * @author Ilya Volodin
+ */
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+    &quot;use strict&quot;;
+
+    return {
+
+        &quot;NewExpression&quot;: function(node) {
+            var wrapperObjects = [&quot;String&quot;, &quot;Number&quot;, &quot;Boolean&quot;, &quot;Math&quot;, &quot;JSON&quot;];
+            if (wrapperObjects.indexOf(node.callee.name) &gt; -1) {
+                context.report(node, &quot;Do not use {{fn}} as a constructor.&quot;, { fn: node.callee.name });
+            }
+        }
+    };
+
+};
+
+},{}],90:[function(require,module,exports){
+/**
+ * @fileoverview Rule to flag statements with function invocation preceded by
+ * &quot;new&quot; and not part of assignment
+ * @author Ilya Volodin
+ */
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+    &quot;use strict&quot;;
+
+    return {
+
+        &quot;ExpressionStatement&quot;: function(node) {
+
+            if (node.expression.type === &quot;NewExpression&quot;) {
+                context.report(node, &quot;Do not use 'new' for side effects.&quot;);
+            }
+        }
+    };
+
+};
+
+},{}],91:[function(require,module,exports){
+/**
+ * @fileoverview Rule to flag use of an object property of the global object (Math and JSON) as a function
+ * @author James Allardice
+ */
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+    &quot;use strict&quot;;
+
+    return {
+        &quot;CallExpression&quot;: function(node) {
+
+            if (node.callee.type === &quot;Identifier&quot;) {
+                var name = node.callee.name;
+                if (name === &quot;Math&quot; || name === &quot;JSON&quot;) {
+                    context.report(node, &quot;'{{name}}' is not a function.&quot;, { name: name });
+                }
+            }
+        }
+    };
+
+};
+
+},{}],92:[function(require,module,exports){
+/**
+ * @fileoverview Rule to flag octal escape sequences in string literals.
+ * @author Ian Christian Myers
+ */
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+    &quot;use strict&quot;;
+
+    return {
+
+        &quot;Literal&quot;: function(node) {
+            if (typeof node.value !== &quot;string&quot;) {
+                return;
+            }
+            var match = node.raw.match(/^([^\\]|\\[^0-7])*\\([0-7])/),
+                octalDigit;
+
+            if (match) {
+                octalDigit = match[2];
+                context.report(node, &quot;Don't use octal: '\\{{octalDigit}}'. Use '\\u....' instead.&quot;,
+                        { octalDigit: octalDigit });
+            }
+        }
+
+    };
+
+};
+
+},{}],93:[function(require,module,exports){
+/**
+ * @fileoverview Rule to flag when initializing octal literal
+ * @author Ilya Volodin
+ */
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+    &quot;use strict&quot;;
+
+    return {
+
+        &quot;Literal&quot;: function(node) {
+            if (typeof node.value === &quot;number&quot; &amp;&amp; /^0[0-7]/.test(node.raw)) {
+                context.report(node, &quot;Octal literals should not be used.&quot;);
+            }
+        }
+    };
+
+};
+
+},{}],94:[function(require,module,exports){
+/**
+ * @fileoverview Disallow string concatenation when using __dirname and __filename
+ * @author Nicholas C. Zakas
+ */
+&quot;use strict&quot;;
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+    var MATCHER = /^__(?:dir|file)name$/;
+
+    //--------------------------------------------------------------------------
+    // Public
+    //--------------------------------------------------------------------------
+
+    return {
+
+        &quot;BinaryExpression&quot;: function(node) {
+
+            var left = node.left,
+                right = node.right;
+
+            if (node.operator === &quot;+&quot; &amp;&amp;
+                    ((left.type === &quot;Identifier&quot; &amp;&amp; MATCHER.test(left.name)) ||
+                    (right.type === &quot;Identifier&quot; &amp;&amp; MATCHER.test(right.name)))
+            ) {
+
+                context.report(node, &quot;Use path.join() or path.resolve() instead of + to create paths.&quot;);
+            }
+        }
+
+    };
+
+};
+
+},{}],95:[function(require,module,exports){
+/**
+ * @fileoverview Rule to flag use of unary increment and decrement operators.
+ * @author Ian Christian Myers
+ */
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+    &quot;use strict&quot;;
+
+    return {
+
+        &quot;UpdateExpression&quot;: function(node) {
+            context.report(node, &quot;Unary operator '&quot; + node.operator + &quot;' used.&quot;);
+        }
+
+    };
+
+};
+
+},{}],96:[function(require,module,exports){
+/**
+ * @fileoverview Disallow the use of process.env()
+ * @author Vignesh Anand
+ * @copyright 2014 Vignesh Anand. All rights reserved.
+ */
+&quot;use strict&quot;;
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+    return {
+
+        &quot;MemberExpression&quot;: function(node) {
+            var objectName = node.object.name,
+                propertyName = node.property.name;
+
+            if (objectName === &quot;process&quot; &amp;&amp; !node.computed &amp;&amp; propertyName &amp;&amp; propertyName === &quot;env&quot;) {
+                context.report(node, &quot;Unexpected use of process.env.&quot;);
+            }
+
+        }
+
+    };
+
+};
+
+},{}],97:[function(require,module,exports){
+/**
+ * @fileoverview Disallow the use of process.exit()
+ * @author Nicholas C. Zakas
+ */
+&quot;use strict&quot;;
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+    //--------------------------------------------------------------------------
+    // Public
+    //--------------------------------------------------------------------------
+
+    return {
+
+        &quot;CallExpression&quot;: function(node) {
+            var callee = node.callee;
+
+            if (callee.type === &quot;MemberExpression&quot; &amp;&amp; callee.object.name === &quot;process&quot; &amp;&amp;
+                callee.property.name === &quot;exit&quot;
+            ) {
+                context.report(node, &quot;Don't use process.exit(); throw an error instead.&quot;);
+            }
+        }
+
+    };
+
+};
+
+},{}],98:[function(require,module,exports){
+/**
+ * @fileoverview Rule to flag usage of __proto__ property
+ * @author Ilya Volodin
+ */
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+    &quot;use strict&quot;;
+
+    return {
+
+        &quot;MemberExpression&quot;: function(node) {
+
+            if (node.property &amp;&amp;
+                    (node.property.type === &quot;Identifier&quot; &amp;&amp; node.property.name === &quot;__proto__&quot; &amp;&amp; !node.computed) ||
+                    (node.property.type === &quot;Literal&quot; &amp;&amp; node.property.value === &quot;__proto__&quot;)) {
+                context.report(node, &quot;The '__proto__' property is deprecated.&quot;);
+            }
+        }
+    };
+
+};
+
+},{}],99:[function(require,module,exports){
+/**
+ * @fileoverview Rule to flag when the same variable is declared more then once.
+ * @author Ilya Volodin
+ */
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+    &quot;use strict&quot;;
+
+    function findVariables() {
+        var scope = context.getScope();
+
+        scope.variables.forEach(function(variable) {
+            if (variable.identifiers &amp;&amp; variable.identifiers.length &gt; 1) {
+                variable.identifiers.sort(function(a, b) {
+                    return a.range[1] - b.range[1];
+                });
+
+                for (var i = 1, l = variable.identifiers.length; i &lt; l; i++) {
+                    context.report(variable.identifiers[i], &quot;{{a}} is already defined&quot;, {a: variable.name});
+                }
+            }
+        });
+    }
+
+    return {
+        &quot;Program&quot;: findVariables,
+        &quot;FunctionExpression&quot;: findVariables,
+        &quot;FunctionDeclaration&quot;: findVariables
+    };
+};
+
+},{}],100:[function(require,module,exports){
+/**
+ * @fileoverview Rule to count multiple spaces in regular expressions
+ * @author Matt DuVall &lt;http://www.mattduvall.com/&gt;
+ */
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+    &quot;use strict&quot;;
+
+    return {
+
+        &quot;Literal&quot;: function(node) {
+            var token = context.getFirstTokens(node, 1)[0],
+                nodeType = token.type,
+                nodeValue = token.value,
+                multipleSpacesRegex = /( {2,})+?/,
+                regexResults;
+
+            if (nodeType === &quot;RegularExpression&quot;) {
+                regexResults = multipleSpacesRegex.exec(nodeValue);
+
+                if (regexResults !== null) {
+                    context.report(node, &quot;Spaces are hard to count. Use {&quot; + regexResults[0].length + &quot;}.&quot;);
+                }
+            }
+        }
+    };
+
+};
+
+},{}],101:[function(require,module,exports){
+/**
+ * @fileoverview Rule to disallow reserved words being used as keys
+ * @author Emil Bay
+ * @copyright 2014 Emil Bay. All rights reserved.
+ */
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+    &quot;use strict&quot;;
+
+    var MESSAGE = &quot;Reserved word '{{key}}' used as key.&quot;;
+
+    var reservedWords = [
+        &quot;abstract&quot;,
+        &quot;boolean&quot;, &quot;break&quot;, &quot;byte&quot;,
+        &quot;case&quot;, &quot;catch&quot;, &quot;char&quot;, &quot;class&quot;, &quot;const&quot;, &quot;continue&quot;,
+        &quot;debugger&quot;, &quot;default&quot;, &quot;delete&quot;, &quot;do&quot;, &quot;double&quot;,
+        &quot;else&quot;, &quot;enum&quot;, &quot;export&quot;, &quot;extends&quot;,
+        &quot;final&quot;, &quot;finally&quot;, &quot;float&quot;, &quot;for&quot;, &quot;function&quot;,
+        &quot;goto&quot;,
+        &quot;if&quot;, &quot;implements&quot;, &quot;import&quot;, &quot;in&quot;, &quot;instanceof&quot;, &quot;int&quot;, &quot;interface&quot;,
+        &quot;long&quot;,
+        &quot;native&quot;, &quot;new&quot;,
+        &quot;package&quot;, &quot;private&quot;, &quot;protected&quot;, &quot;public&quot;,
+        &quot;return&quot;,
+        &quot;short&quot;, &quot;static&quot;, &quot;super&quot;, &quot;switch&quot;, &quot;synchronized&quot;,
+        &quot;this&quot;, &quot;throw&quot;, &quot;throws&quot;, &quot;transient&quot;, &quot;try&quot;, &quot;typeof&quot;,
+        &quot;var&quot;, &quot;void&quot;, &quot;volatile&quot;,
+        &quot;while&quot;, &quot;with&quot;
+    ];
+
+    return {
+
+        &quot;ObjectExpression&quot;: function(node) {
+            node.properties.forEach(function(property) {
+
+                if (property.key.type === &quot;Identifier&quot;) {
+                    var keyName = property.key.name;
+
+                    if (reservedWords.indexOf(&quot;&quot; + keyName) !== -1) {
+                        context.report(node, MESSAGE, { key: keyName });
+                    }
+                }
+
+            });
+
+        }
+    };
+
+};
+
+},{}],102:[function(require,module,exports){
+/**
+ * @fileoverview Restrict usage of specified node modules.
+ * @author Christian Schulz
+ */
+&quot;use strict&quot;;
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function (context) {
+    // trim restricted module names
+    var restrictedModules = context.options;
+
+    // if no modules are restricted we don't need to check the CallExpressions
+    if (restrictedModules.length === 0) {
+        return {};
+    }
+
+    /**
+     * Function to check if a node is a string literal.
+     * @param {ASTNode} node The node to check.
+     * @returns {boolean} If the node is a string literal.
+     */
+    function isString(node) {
+        return node &amp;&amp; node.type === &quot;Literal&quot; &amp;&amp; typeof node.value === &quot;string&quot;;
+    }
+
+    /**
+     * Function to check if a node is a require call.
+     * @param {ASTNode} node The node to check.
+     * @returns {boolean} If the node is a require call.
+     */
+    function isRequireCall(node) {
+        return node.callee.type === &quot;Identifier&quot; &amp;&amp; node.callee.name === &quot;require&quot;;
+    }
+
+    /**
+     * Function to check if a node has an argument that is an restricted module and return its name.
+     * @param {ASTNode} node The node to check
+     * @returns {undefined|String} restricted module name or undefined if node argument isn't restricted.
+     */
+    function getRestrictedModuleName(node) {
+        var moduleName;
+
+        // node has arguments and first argument is string
+        if (node.arguments.length &amp;&amp; isString(node.arguments[0])) {
+            var argumentValue = node.arguments[0].value.trim();
+
+            // check if argument value is in restricted modules array
+            if (restrictedModules.indexOf(argumentValue) !== -1) {
+                moduleName = argumentValue;
+            }
+        }
+
+        return moduleName;
+    }
+
+    return {
+        &quot;CallExpression&quot;: function (node) {
+            if (isRequireCall(node)) {
+                var restrictedModuleName = getRestrictedModuleName(node);
+
+                if (restrictedModuleName) {
+                    context.report(node, &quot;'{{moduleName}}' module is restricted from being used.&quot;, {
+                        moduleName: restrictedModuleName
+                    });
+                }
+            }
+        }
+    };
+};
+
+},{}],103:[function(require,module,exports){
+/**
+ * @fileoverview Rule to flag when return statement contains assignment
+ * @author Ilya Volodin
+ */
+&quot;use strict&quot;;
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+    return {
+
+        &quot;ReturnStatement&quot;: function(node) {
+            if (node.argument &amp;&amp; node.argument.type === &quot;AssignmentExpression&quot;) {
+                context.report(node, &quot;Return statement should not contain assignment.&quot;);
+            }
+        }
+    };
+
+};
+
+},{}],104:[function(require,module,exports){
+/**
+ * @fileoverview Rule to flag when using javascript: urls
+ * @author Ilya Volodin
+ */
+/*jshint scripturl: true */
+/*eslint no-script-url: 0*/
+
+&quot;use strict&quot;;
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+    return {
+
+        &quot;Literal&quot;: function(node) {
+
+            var value;
+
+            if (node.value &amp;&amp; typeof(node.value) === &quot;string&quot;) {
+                value = node.value.toLowerCase();
+
+                if (value.indexOf(&quot;javascript:&quot;) === 0) {
+                    context.report(node, &quot;Script URL is a form of eval.&quot;);
+                }
+            }
+        }
+    };
+
+};
+
+},{}],105:[function(require,module,exports){
+/**
+ * @fileoverview Rule to flag comparison where left part is the same as the right
+ * part.
+ * @author Ilya Volodin
+ */
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+    &quot;use strict&quot;;
+
+    return {
+
+        &quot;BinaryExpression&quot;: function(node) {
+            var operators = [&quot;===&quot;, &quot;==&quot;, &quot;!==&quot;, &quot;!=&quot;, &quot;&gt;&quot;, &quot;&lt;&quot;, &quot;&gt;=&quot;, &quot;&lt;=&quot;];
+            if (operators.indexOf(node.operator) &gt; -1 &amp;&amp;
+                (node.left.type === &quot;Identifier&quot; &amp;&amp; node.right.type === &quot;Identifier&quot; &amp;&amp; node.left.name === node.right.name ||
+                node.left.type === &quot;Literal&quot; &amp;&amp; node.right.type === &quot;Literal&quot; &amp;&amp; node.left.value === node.right.value)) {
+                context.report(node, &quot;Comparing to itself is potentially pointless.&quot;);
+            }
+        }
+    };
+
+};
+
+},{}],106:[function(require,module,exports){
+/**
+ * @fileoverview Rule to flag use of comma operator
+ * @author Brandon Mills
+ */
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+    &quot;use strict&quot;;
+
+    /**
+     * Parts of the grammar that are required to have parens.
+     */
+    var parenthesized = {
+        &quot;DoWhileStatement&quot;: &quot;test&quot;,
+        &quot;IfStatement&quot;: &quot;test&quot;,
+        &quot;SwitchStatement&quot;: &quot;discriminant&quot;,
+        &quot;WhileStatement&quot;: &quot;test&quot;,
+        &quot;WithStatement&quot;: &quot;object&quot;
+
+        // Omitting CallExpression - commas are parsed as argument separators
+        // Omitting NewExpression - commas are parsed as argument separators
+        // Omitting ForInStatement - parts aren't individually parenthesised
+        // Omitting ForStatement - parts aren't individually parenthesised
+    };
+
+    /**
+     * Determines whether a node is required by the grammar to be wrapped in
+     * parens, e.g. the test of an if statement.
+     * @param {ASTNode} node - The AST node
+     * @returns {boolean} True if parens around node belong to parent node.
+     */
+    function requiresExtraParens(node) {
+        return node.parent &amp;&amp; parenthesized[node.parent.type] != null &amp;&amp;
+                node === node.parent[parenthesized[node.parent.type]];
+    }
+
+    /**
+     * Check if a node is wrapped in parens.
+     * @param {ASTNode} node - The AST node
+     * @returns {boolean} True if the node has a paren on each side.
+     */
+    function isParenthesised(node) {
+        var previousToken = context.getTokenBefore(node),
+            nextToken = context.getTokenAfter(node);
+
+        return previousToken &amp;&amp; nextToken &amp;&amp;
+            previousToken.value === &quot;(&quot; &amp;&amp; previousToken.range[1] &lt;= node.range[0] &amp;&amp;
+            nextToken.value === &quot;)&quot; &amp;&amp; nextToken.range[0] &gt;= node.range[1];
+    }
+
+    /**
+     * Check if a node is wrapped in two levels of parens.
+     * @param {ASTNode} node - The AST node
+     * @returns {boolean} True if two parens surround the node on each side.
+     */
+    function isParenthesisedTwice(node) {
+        var previousToken = context.getTokenBefore(node, 1),
+            nextToken = context.getTokenAfter(node, 1);
+
+        return isParenthesised(node) &amp;&amp; previousToken &amp;&amp; nextToken &amp;&amp;
+            previousToken.value === &quot;(&quot; &amp;&amp; previousToken.range[1] &lt;= node.range[0] &amp;&amp;
+            nextToken.value === &quot;)&quot; &amp;&amp; nextToken.range[0] &gt;= node.range[1];
+    }
+
+    return {
+        &quot;SequenceExpression&quot;: function(node) {
+            // Always allow sequences in for statement update
+            if (node.parent.type === &quot;ForStatement&quot; &amp;&amp;
+                    (node === node.parent.init || node === node.parent.update)) {
+                return;
+            }
+
+            // Wrapping a sequence in extra parens indicates intent
+            if (requiresExtraParens(node)) {
+                if (isParenthesisedTwice(node)) {
+                    return;
+                }
+            } else {
+                if (isParenthesised(node)) {
+                    return;
+                }
+            }
+
+            context.report(node, &quot;Unexpected use of comma operator.&quot;);
+        }
+    };
+
+};
+
+},{}],107:[function(require,module,exports){
+/**
+ * @fileoverview Disallow shadowing of NaN, undefined, and Infinity (ES5 section 15.1.1)
+ * @author Michael Ficarra
+ */
+&quot;use strict&quot;;
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+    var RESTRICTED = [&quot;undefined&quot;, &quot;NaN&quot;, &quot;Infinity&quot;, &quot;arguments&quot;, &quot;eval&quot;];
+
+    function checkForViolation(id) {
+        if (RESTRICTED.indexOf(id.name) &gt; -1) {
+            context.report(id, &quot;Shadowing of global property \&quot;&quot; + id.name + &quot;\&quot;.&quot;);
+        }
+    }
+
+    return {
+        &quot;VariableDeclarator&quot;: function(node) {
+            checkForViolation(node.id);
+        },
+        &quot;FunctionExpression&quot;: function(node) {
+            if (node.id) {
+                checkForViolation(node.id);
+            }
+            [].map.call(node.params, checkForViolation);
+        },
+        &quot;FunctionDeclaration&quot;: function(node) {
+            checkForViolation(node.id);
+            [].map.call(node.params, checkForViolation);
+        },
+        &quot;CatchClause&quot;: function(node) {
+            checkForViolation(node.param);
+        }
+    };
+
+};
+
+},{}],108:[function(require,module,exports){
+/**
+ * @fileoverview Rule to flag on declaring variables already declared in the outer scope
+ * @author Ilya Volodin
+ */
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+    &quot;use strict&quot;;
+
+    /**
+     * Checks if a variable is contained in the list of given scope variables.
+     * @param {Object} variable The variable to check.
+     * @param {Array} scopeVars The scope variables to look for.
+     * @returns {boolean} Whether or not the variable is contains in the list of scope variables.
+     */
+    function isContainedInScopeVars(variable, scopeVars) {
+        return scopeVars.some(function (scopeVar) {
+            if (scopeVar.identifiers.length &gt; 0) {
+                return variable.name === scopeVar.name;
+            }
+            return false;
+        });
+    }
+
+    /**
+     * Checks if the given variables are shadowed in the given scope.
+     * @param {Array} variables The variables to look for
+     * @param {Object} scope The scope to be checked.
+     * @returns {void}
+     */
+    function checkShadowsInScope(variables, scope) {
+        variables.forEach(function (variable) {
+            if (isContainedInScopeVars(variable, scope.variables)) {
+                context.report(variable.identifiers[0], &quot;{{a}} is already declared in the upper scope.&quot;, {a: variable.name});
+            }
+        });
+    }
+
+    /**
+     * Filters all variables of a list which already occur in another list.
+     * @param {Array} variableListA List of variables which should be filtered.
+     * @param {Array} variableListB List of variables which should no occur in variableListA.
+     * @returns {Array} Filtered list of variables.
+     */
+    function filterVariableList(variableListA, variableListB) {
+        return variableListA.filter(function (variableA) {
+            return !variableListB.some(function (variableB) {
+                return variableA.name === variableB.name;
+            });
+        });
+    }
+
+    /**
+     * Checks the given node for shadowed variables.
+     * @param {ASTNode} node The AST node of a FunctionDeclaration or FunctionExpression.
+     * @returns {void}
+     */
+    function checkForShadows(node) {
+        var scope = context.getScope(),
+            args = node.params,
+            variables = filterVariableList(scope.variables, args);
+
+        // iterate through the array of variables and find duplicates with the upper scope
+        var upper = scope.upper;
+        while (upper) {
+            checkShadowsInScope(variables, upper);
+            upper = upper.upper;
+        }
+    }
+
+    return {
+        &quot;FunctionDeclaration&quot;: checkForShadows,
+        &quot;FunctionExpression&quot;: checkForShadows
+    };
+
+};
+
+},{}],109:[function(require,module,exports){
+/**
+ * @fileoverview Rule to require variables declared without whitespace before the lines semicolon
+ * @author Jonathan Kingston
+ */
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+    &quot;use strict&quot;;
+
+    var semicolonWhitespace = /\s;$/;
+
+    return {
+        &quot;VariableDeclaration&quot;: function(node) {
+            var source = context.getSource(node);
+            if (semicolonWhitespace.test(source)) {
+                context.report(node, &quot;Variable declared with trailing whitespace before semicolon&quot;);
+            }
+        },
+        &quot;ExpressionStatement&quot;: function(node) {
+            var source = context.getSource(node);
+            if (semicolonWhitespace.test(source)) {
+                context.report(node, &quot;Expression called with trailing whitespace before semicolon&quot;);
+            }
+        }
+    };
+};
+
+},{}],110:[function(require,module,exports){
+/**
+ * @fileoverview Rule to check that spaced function application
+ * @author Matt DuVall &lt;http://www.mattduvall.com&gt;
+ */
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+    &quot;use strict&quot;;
+
+    function detectOpenSpaces(node) {
+        var lastCalleeToken = context.getLastToken(node.callee);
+        var tokens = context.getTokens(node);
+        var i = tokens.indexOf(lastCalleeToken), l = tokens.length;
+        while (i &lt; l &amp;&amp; tokens[i].value !== &quot;(&quot;) {
+            ++i;
+        }
+        if (i &gt;= l) {
+            return;
+        }
+        // look for a space between the callee and the open paren
+        if (tokens[i - 1].range[1] !== tokens[i].range[0]) {
+            context.report(node, &quot;Unexpected space between function name and paren.&quot;);
+        }
+    }
+
+    return {
+        &quot;CallExpression&quot;: detectOpenSpaces,
+        &quot;NewExpression&quot;: detectOpenSpaces
+    };
+
+};
+
+},{}],111:[function(require,module,exports){
+/**
+ * @fileoverview Disallow sparse arrays
+ * @author Nicholas C. Zakas
+ */
+&quot;use strict&quot;;
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+
+    //--------------------------------------------------------------------------
+    // Public
+    //--------------------------------------------------------------------------
+
+    return {
+
+        &quot;ArrayExpression&quot;: function(node) {
+
+            var emptySpot = node.elements.indexOf(null) &gt; -1;
+
+            if (emptySpot) {
+                context.report(node, &quot;Unexpected comma in middle of array.&quot;);
+            }
+        }
+
+    };
+
+};
+
+},{}],112:[function(require,module,exports){
+/**
+ * @fileoverview Rule to check for properties whose identifier ends with the string Sync
+ * @author Matt DuVall&lt;http://mattduvall.com/&gt;
+ */
+
+/*jshint node:true*/
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+    &quot;use strict&quot;;
+
+    return {
+
+        &quot;MemberExpression&quot;: function(node) {
+            var propertyName = node.property.name,
+                syncRegex = /.*Sync$/;
+
+            if (syncRegex.exec(propertyName) !== null) {
+                context.report(node, &quot;Unexpected sync method: '&quot; + propertyName + &quot;'.&quot;);
+            }
+        }
+    };
+
+};
+
+},{}],113:[function(require,module,exports){
+/**
+ * @fileoverview Rule to flag use of ternary operators.
+ * @author Ian Christian Myers
+ */
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+    &quot;use strict&quot;;
+
+    return {
+
+        &quot;ConditionalExpression&quot;: function(node) {
+            context.report(node, &quot;Ternary operator used.&quot;);
+        }
+
+    };
+
+};
+
+},{}],114:[function(require,module,exports){
+/**
+ * @fileoverview Disallow trailing spaces at the end of lines.
+ * @author Nodeca Team &lt;https://github.com/nodeca&gt;
+ */
+&quot;use strict&quot;;
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+    var TRAILER = &quot;[ \t\u00a0\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u200b\u2028\u2029\u3000]+$&quot;;
+
+    //--------------------------------------------------------------------------
+    // Public
+    //--------------------------------------------------------------------------
+
+    return {
+
+        &quot;Program&quot;: function checkTrailingSpaces(node) {
+
+            // Let's hack. Since Esprima does not return whitespace nodes,
+            // fetch the source code and do black magic via regexps.
+
+            var src = context.getSource(),
+                re = new RegExp(TRAILER, &quot;mg&quot;),
+                match, lines, location;
+
+            while ((match = re.exec(src)) !== null) {
+                lines = src.slice(0, re.lastIndex).split(/\r?\n/g);
+
+                location = {
+                    line: lines.length,
+                    column: lines[lines.length - 1].length - match[0].length + 1
+                };
+
+                // Passing node is a bit dirty, because message data will contain
+                // big text in `source`. But... who cares :) ?
+                // One more kludge will not make worse the bloody wizardry of this plugin.
+                context.report(node, location, &quot;Trailing spaces not allowed.&quot;);
+            }
+        }
+
+    };
+};
+
+},{}],115:[function(require,module,exports){
+/**
+ * @fileoverview Rule to flag when initializing to undefined
+ * @author Ilya Volodin
+ */
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+    &quot;use strict&quot;;
+
+    return {
+
+        &quot;VariableDeclarator&quot;: function(node) {
+            var name = node.id.name;
+            var init = node.init &amp;&amp; node.init.name;
+
+            if (init === &quot;undefined&quot;) {
+                context.report(node, &quot;It's not necessary to initialize '{{name}}' to undefined.&quot;, { name: name });
+            }
+        }
+    };
+
+};
+
+},{}],116:[function(require,module,exports){
+/**
+ * @fileoverview Rule to flag references to undeclared variables.
+ * @author Mark Macdonald
+ */
+&quot;use strict&quot;;
+
+//------------------------------------------------------------------------------
+// Helpers
+//------------------------------------------------------------------------------
+
+function isImplicitGlobal(variable) {
+    return variable.defs.every(function(def) {
+        return def.type === &quot;ImplicitGlobalVariable&quot;;
+    });
+}
+
+/**
+ * Gets the declared variable, defined in `scope`, that `ref` refers to.
+ * @param {Scope} scope The scope in which to search.
+ * @param {Reference} ref The reference to find in the scope.
+ * @returns {Variable} The variable, or null if ref refers to an undeclared variable.
+ */
+function getDeclaredGlobalVariable(scope, ref) {
+    var declaredGlobal = null;
+    scope.variables.some(function(variable) {
+        if (variable.name === ref.identifier.name) {
+            // If it's an implicit global, it must have a `writeable` field (indicating it was declared)
+            if (!isImplicitGlobal(variable) || {}.hasOwnProperty.call(variable, &quot;writeable&quot;)) {
+                declaredGlobal = variable;
+                return true;
+            }
+        }
+        return false;
+    });
+    return declaredGlobal;
+}
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+    return {
+
+        &quot;Program&quot;: function(/*node*/) {
+
+            var globalScope = context.getScope();
+
+            globalScope.through.forEach(function(ref) {
+                var variable = getDeclaredGlobalVariable(globalScope, ref),
+                    name = ref.identifier.name;
+                if (!variable) {
+                    context.report(ref.identifier, &quot;'{{name}}' is not defined.&quot;, { name: name });
+                } else if (ref.isWrite() &amp;&amp; variable.writeable === false) {
+                    context.report(ref.identifier, &quot;'{{name}}' is read only.&quot;, { name: name });
+                }
+            });
+        }
+    };
+
+};
+
+},{}],117:[function(require,module,exports){
+/**
+ * @fileoverview Rule to flag references to the undefined variable.
+ * @author Michael Ficarra
+ */
+&quot;use strict&quot;;
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+    return {
+
+        &quot;Identifier&quot;: function(node) {
+            if (node.name === &quot;undefined&quot;) {
+                var parent = context.getAncestors().pop();
+                if (!parent || parent.type !== &quot;MemberExpression&quot; || node !== parent.property || parent.computed) {
+                    context.report(node, &quot;Unexpected use of undefined.&quot;);
+                }
+            }
+        }
+    };
+
+};
+
+},{}],118:[function(require,module,exports){
+/**
+ * @fileoverview Rule to flag trailing underscores in variable declarations.
+ * @author Matt DuVall &lt;http://www.mattduvall.com&gt;
+ */
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+    &quot;use strict&quot;;
+
+    //-------------------------------------------------------------------------
+    // Helpers
+    //-------------------------------------------------------------------------
+
+    function hasTrailingUnderscore(identifier) {
+        var len = identifier.length;
+
+        return identifier !== &quot;_&quot; &amp;&amp; (identifier[0] === &quot;_&quot; || identifier[len - 1] === &quot;_&quot;);
+    }
+
+    function isSpecialCaseIdentifierForMemberExpression(identifier) {
+        return identifier === &quot;__proto__&quot;;
+    }
+
+    function isSpecialCaseIdentifierInVariableExpression(identifier) {
+        // Checks for the underscore library usage here
+        return identifier === &quot;_&quot;;
+    }
+
+    function checkForTrailingUnderscoreInFunctionDeclaration(node) {
+        var identifier = node.id.name;
+
+        if (typeof identifier !== &quot;undefined&quot; &amp;&amp; hasTrailingUnderscore(identifier)) {
+            context.report(node, &quot;Unexpected dangling '_' in '&quot; + identifier + &quot;'.&quot;);
+        }
+    }
+
+    function checkForTrailingUnderscoreInVariableExpression(node) {
+        var identifier = node.id.name;
+
+        if (typeof identifier !== &quot;undefined&quot; &amp;&amp; hasTrailingUnderscore(identifier) &amp;&amp;
+            !isSpecialCaseIdentifierInVariableExpression(identifier)) {
+            context.report(node, &quot;Unexpected dangling '_' in '&quot; + identifier + &quot;'.&quot;);
+        }
+    }
+
+    function checkForTrailingUnderscoreInMemberExpression(node) {
+        var identifier = node.property.name;
+
+        if (typeof identifier !== &quot;undefined&quot; &amp;&amp; hasTrailingUnderscore(identifier) &amp;&amp;
+            !isSpecialCaseIdentifierForMemberExpression(identifier)) {
+            context.report(node, &quot;Unexpected dangling '_' in '&quot; + identifier + &quot;'.&quot;);
+        }
+    }
+
+    //--------------------------------------------------------------------------
+    // Public API
+    //--------------------------------------------------------------------------
+
+    return {
+        &quot;FunctionDeclaration&quot;: checkForTrailingUnderscoreInFunctionDeclaration,
+        &quot;VariableDeclarator&quot;: checkForTrailingUnderscoreInVariableExpression,
+        &quot;MemberExpression&quot;: checkForTrailingUnderscoreInMemberExpression
+    };
+
+};
+
+},{}],119:[function(require,module,exports){
+/**
+ * @fileoverview Checks for unreachable code due to return, throws, break, and continue.
+ * @author Joel Feenstra
+ */
+&quot;use strict&quot;;
+
+//------------------------------------------------------------------------------
+// Helpers
+//------------------------------------------------------------------------------
+
+
+function report(context, node, unreachableType) {
+    var keyword;
+    switch (unreachableType) {
+        case &quot;BreakStatement&quot;:
+            keyword = &quot;break&quot;;
+            break;
+        case &quot;ContinueStatement&quot;:
+            keyword = &quot;continue&quot;;
+            break;
+        case &quot;ReturnStatement&quot;:
+            keyword = &quot;return&quot;;
+            break;
+        case &quot;ThrowStatement&quot;:
+            keyword = &quot;throw&quot;;
+            break;
+        default:
+            return;
+    }
+    context.report(node, &quot;Found unexpected statement after a {{type}}.&quot;, { type: keyword });
+}
+
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+    /**
+     * Checks if a node is an exception for no-unreachable because of variable/function hoisting
+     * @param {ASTNode} node The AST node to check.
+     * @returns {boolean} if the node doesn't trigger unreachable
+     * @private
+     */
+    function isUnreachableAllowed(node) {
+        return node.type === &quot;FunctionDeclaration&quot; ||
+            node.type === &quot;VariableDeclaration&quot; &amp;&amp;
+            node.declarations.every(function(declaration) {
+                return declaration.type === &quot;VariableDeclarator&quot; &amp;&amp; declaration.init === null;
+            });
+    }
+
+    /*
+     * Verifies that the given node is the last node or followed exclusively by
+     * hoisted declarations
+     * @param {ASTNode} node Node that should be the last node
+     * @returns {void}
+     * @private
+     */
+    function checkNode(node) {
+        var parent = context.getAncestors().pop();
+        var field, i, sibling;
+
+        switch (parent.type) {
+            case &quot;SwitchCase&quot;:
+                field = &quot;consequent&quot;;
+                break;
+            case &quot;Program&quot;:
+            case &quot;BlockStatement&quot;:
+                field = &quot;body&quot;;
+                break;
+            default:
+                return;
+        }
+
+        for (i = parent[field].length - 1; i &gt;= 0; i--) {
+            sibling = parent[field][i];
+            if (sibling === node) {
+                return; // Found the last reachable statement, all done
+            }
+
+            if (!isUnreachableAllowed(sibling)) {
+                report(context, sibling, node.type);
+            }
+        }
+    }
+
+    return {
+        &quot;ReturnStatement&quot;: checkNode,
+        &quot;ThrowStatement&quot;: checkNode,
+        &quot;ContinueStatement&quot;: checkNode,
+        &quot;BreakStatement&quot;: checkNode
+    };
+
+};
+
+},{}],120:[function(require,module,exports){
+/**
+ * @fileoverview Flag expressions in statement position that do not side effect
+ * @author Michael Ficarra
+ */
+&quot;use strict&quot;;
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+    /**
+     * @param {ASTNode} node - any node
+     * @returns {Boolean} whether the given node structurally represents a directive
+     */
+    function looksLikeDirective(node) {
+       return node.type === &quot;ExpressionStatement&quot; &amp;&amp;
+           node.expression.type === &quot;Literal&quot; &amp;&amp; typeof node.expression.value === &quot;string&quot;;
+    }
+
+    /**
+     * @param {Function} predicate - ([a] -&gt; Boolean) the function used to make the determination
+     * @param {a[]} list - the input list
+     * @returns {a[]} the leading sequence of members in the given list that pass the given predicate
+     */
+    function takeWhile(predicate, list) {
+        for (var i = 0, l = list.length; i &lt; l; ++i) {
+            if (!predicate(list[i])) {
+                break;
+            }
+        }
+        return [].slice.call(list, 0, i);
+    }
+
+    /**
+     * @param {ASTNode} node - a Program or BlockStatement node
+     * @returns {ASTNode[]} the leading sequence of directive nodes in the given node's body
+     */
+    function directives(node) {
+        return takeWhile(looksLikeDirective, node.body);
+    }
+
+    /**
+     * @param {ASTNode} node - any node
+     * @param {ASTNode[]} ancestors - the given node's ancestors
+     * @returns {Boolean} whether the given node is considered a directive in its current position
+     */
+    function isDirective(node, ancestors) {
+        var parent = ancestors[ancestors.length - 1],
+            grandparent = ancestors[ancestors.length - 2];
+        return (parent.type === &quot;Program&quot; || parent.type === &quot;BlockStatement&quot; &amp;&amp; (grandparent.type === &quot;FunctionExpression&quot; || grandparent.type === &quot;FunctionDeclaration&quot;)) &amp;&amp;
+            directives(parent).indexOf(node) &gt;= 0;
+    }
+
+    return {
+        &quot;ExpressionStatement&quot;: function(node) {
+
+            var type = node.expression.type,
+                ancestors = context.getAncestors();
+
+            if (
+                !/^(?:Assignment|Call|New|Update)Expression$/.test(type) &amp;&amp;
+                (type !== &quot;UnaryExpression&quot; || [&quot;delete&quot;, &quot;void&quot;].indexOf(node.expression.operator) &lt; 0) &amp;&amp;
+                !isDirective(node, ancestors)
+            ) {
+                context.report(node, &quot;Expected an assignment or function call and instead saw an expression.&quot;);
+            }
+        }
+    };
+
+};
+
+},{}],121:[function(require,module,exports){
+/**
+ * @fileoverview Rule to flag declared but unused variables
+ * @author Ilya Volodin
+ */
+
+&quot;use strict&quot;;
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+    var config = {
+        vars: &quot;all&quot;,
+        args: &quot;after-used&quot;
+    };
+
+    if (context.options[0]) {
+        if (typeof(context.options[0]) === &quot;string&quot;) {
+            config.vars = context.options[0];
+        } else {
+            config.vars = context.options[0].vars || config.vars;
+            config.args = context.options[0].args || config.args;
+        }
+    }
+
+    var MESSAGE = &quot;{{name}} is defined but never used&quot;;
+
+    /**
+     * @param {Reference} ref - an escope Reference
+     * @returns {Boolean} whether the given reference represents a read operation
+     */
+    function isReadRef(ref) {
+        return ref.isRead();
+    }
+
+    /**
+     * @param {Scope} scope - an escope Scope object
+     * @returns {Variable[]} most of the local variables with no read references
+     */
+    function unusedLocals(scope) {
+        var unused = [];
+        var variables = scope.variables;
+        if (scope.type !== &quot;global&quot;) {
+            for (var i = 0, l = variables.length; i &lt; l; ++i) {
+                // skip function expression names
+                if (scope.functionExpressionScope) {
+                    continue;
+                }
+                // skip implicit &quot;arguments&quot; variable
+                if (scope.type === &quot;function&quot; &amp;&amp; variables[i].name === &quot;arguments&quot; &amp;&amp; variables[i].identifiers.length === 0) {
+                    continue;
+                }
+                var type = variables[i].defs[0].type;
+                // skip catch variables
+                if (type === &quot;CatchClause&quot;) {
+                    continue;
+                }
+                // if &quot;args&quot; option is &quot;none&quot;, skip any parameter
+                if (config.args === &quot;none&quot; &amp;&amp; type === &quot;Parameter&quot;) {
+                    continue;
+                }
+                // if &quot;args&quot; option is &quot;after-used&quot;, skip all but the last parameter
+                if (config.args === &quot;after-used&quot; &amp;&amp; type === &quot;Parameter&quot; &amp;&amp; variables[i].defs[0].index &lt; variables[i].defs[0].node.params.length - 1) {
+                    continue;
+                }
+                if (variables[i].references.filter(isReadRef).length === 0) {
+                    unused.push(variables[i]);
+                }
+            }
+        }
+        return [].concat.apply(unused, [].map.call(scope.childScopes, unusedLocals));
+    }
+
+    return {
+        &quot;Program&quot;: function(programNode) {
+            var globalScope = context.getScope();
+            var unused = unusedLocals(globalScope);
+            var i, l;
+
+            // determine unused globals
+            if (config.vars === &quot;all&quot;) {
+                var unresolvedRefs = globalScope.through.filter(isReadRef).map(function(ref) {
+                    return ref.identifier.name;
+                });
+                for (i = 0, l = globalScope.variables.length; i &lt; l; ++i) {
+                    if (unresolvedRefs.indexOf(globalScope.variables[i].name) &lt; 0) {
+                        unused.push(globalScope.variables[i]);
+                    }
+                }
+            }
+
+            for (i = 0, l = unused.length; i &lt; l; ++i) {
+                if (unused[i].eslintExplicitGlobal) {
+                    context.report(programNode, MESSAGE, unused[i]);
+                } else if (unused[i].defs.length &gt; 0) {
+                    context.report(unused[i].identifiers[0], MESSAGE, unused[i]);
+                }
+            }
+        }
+    };
+
+};
+
+},{}],122:[function(require,module,exports){
+/**
+ * @fileoverview Rule to flag use of variables before they are defined
+ * @author Ilya Volodin
+ */
+
+//------------------------------------------------------------------------------
+// Constants
+//------------------------------------------------------------------------------
+
+var NO_FUNC = &quot;nofunc&quot;;
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+    &quot;use strict&quot;;
+
+    function findDeclaration(name, scope) {
+        // try searching in the current scope first
+        for (var i = 0, l = scope.variables.length; i &lt; l; i++) {
+            if (scope.variables[i].name === name) {
+                return scope.variables[i];
+            }
+        }
+        // check if there's upper scope and call recursivly till we find the variable
+        if (scope.upper) {
+            return findDeclaration(name, scope.upper);
+        }
+    }
+
+    function findVariables() {
+        var scope = context.getScope();
+        var typeOption = context.options[0];
+
+        function checkLocationAndReport(reference, declaration) {
+            if (typeOption !== NO_FUNC || declaration.defs[0].type !== &quot;FunctionName&quot;) {
+                if (declaration.identifiers[0].range[1] &gt; reference.identifier.range[1]) {
+                    context.report(reference.identifier, &quot;{{a}} was used before it was defined&quot;, {a: reference.identifier.name});
+                }
+            }
+        }
+
+        scope.references.forEach(function(reference) {
+            // if the reference is resolved check for declaration location
+            // if not, it could be function invocation, try to find manually
+            if (reference.resolved &amp;&amp; reference.resolved.identifiers.length &gt; 0) {
+                checkLocationAndReport(reference, reference.resolved);
+            } else {
+                var declaration = findDeclaration(reference.identifier.name, scope);
+                // if there're no identifiers, this is a global environment variable
+                if (declaration &amp;&amp; declaration.identifiers.length !== 0) {
+                    checkLocationAndReport(reference, declaration);
+                }
+            }
+        });
+    }
+
+    return {
+        &quot;Program&quot;: findVariables,
+        &quot;FunctionExpression&quot;: findVariables,
+        &quot;FunctionDeclaration&quot;: findVariables
+    };
+};
+
+},{}],123:[function(require,module,exports){
+/**
+ * @fileoverview Rule to disallow use of void operator.
+ * @author Mike Sidorov
+ * @copyright 2014 Mike Sidorov. All rights reserved.
+ */
+&quot;use strict&quot;;
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+    //--------------------------------------------------------------------------
+    // Public
+    //--------------------------------------------------------------------------
+
+    return {
+        &quot;UnaryExpression&quot;: function(node) {
+            if (node.operator === &quot;void&quot;) {
+                context.report(node, &quot;Expected 'undefined' and instead saw 'void'.&quot;);
+            }
+        }
+    };
+
+};
+
+},{}],124:[function(require,module,exports){
+/**
+ * @fileoverview Rule that warns about used warning comments
+ * @author Alexander Schmidt &lt;https://github.com/lxanders&gt;
+ */
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function (context) {
+    &quot;use strict&quot;;
+
+    var configuration = context.options[0] || {},
+        warningTerms = configuration.terms || [&quot;todo&quot;, &quot;fixme&quot;, &quot;xxx&quot;],
+        location = configuration.location || &quot;start&quot;;
+
+    /**
+     * Prepares a specified comment for being checked.
+     * @param {String} comment The comment to prepare.
+     * @returns {String} The specified comment prepared for being checked.
+     */
+    function prepareCommentForChecking(comment) {
+        var commentToCheck;
+
+        commentToCheck = comment.toLowerCase();
+        commentToCheck = commentToCheck.trim();
+
+        return commentToCheck;
+    }
+
+    /**
+     * Checks if the specified comment starts with a specified term.
+     * @param {String} commentToCheck The comment to check.
+     * @param {String} lowerCaseTerm The term to search for.
+     * @returns {Boolean} True if the comment started with the specified term, else false.
+     */
+    function commentStartsWithTerm(commentToCheck, lowerCaseTerm) {
+        return commentToCheck.indexOf(lowerCaseTerm) === 0;
+    }
+
+    /**
+     * Checks if the specified comment contains a specified term at any location.
+     * @param {String} commentToCheck The comment to check.
+     * @param {String} lowerCaseTerm The term to search for.
+     * @returns {Boolean} True if the term was contained in the comment, else false.
+     */
+    function commentContainsTerm(commentToCheck, lowerCaseTerm) {
+        return commentToCheck.indexOf(lowerCaseTerm) !== -1;
+    }
+
+
+    /**
+     * Checks the specified comment for matches of the configured warning terms and returns the matches.
+     * @param {String} comment The comment which is checked.
+     * @returns {Array} All matched warning terms for this comment.
+     */
+    function commentContainsWarningTerm(comment) {
+        var matches = [];
+
+        warningTerms.forEach(function (term) {
+            var lowerCaseTerm = term.toLowerCase(),
+                commentToCheck = prepareCommentForChecking(comment);
+
+            if (location === &quot;start&quot;) {
+                if (commentStartsWithTerm(commentToCheck, lowerCaseTerm)) {
+                    matches.push(term);
+                }
+            } else if (location === &quot;anywhere&quot;) {
+                if (commentContainsTerm(commentToCheck, lowerCaseTerm)) {
+                    matches.push(term);
+                }
+            }
+        });
+
+        return matches;
+    }
+
+    /**
+     * Checks the specified node for matching warning comments and reports them.
+     * @param {ASTNode} node The AST node being checked.
+     * @returns {void} undefined.
+     */
+    function checkComment(node) {
+        var matches = commentContainsWarningTerm(node.value);
+
+        matches.forEach(function (matchedTerm) {
+            context.report(node, &quot;Unexpected &quot; + matchedTerm + &quot; comment.&quot;);
+        });
+    }
+
+    return {
+        &quot;BlockComment&quot;: checkComment,
+        &quot;LineComment&quot;: checkComment
+    };
+};
+
+},{}],125:[function(require,module,exports){
+/**
+ * @fileoverview Rule to flag use of with statement
+ * @author Nicholas C. Zakas
+ */
+
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+    &quot;use strict&quot;;
+
+    return {
+        &quot;WithStatement&quot;: function(node) {
+            context.report(node, &quot;Unexpected use of 'with' statement.&quot;);
+        }
+    };
+
+};
+
+},{}],126:[function(require,module,exports){
+/**
+ * @fileoverview Rule to flag wrapping none-iffe in parens
+ * @author Ilya Volodin
+ */
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+    &quot;use strict&quot;;
+
+    return {
+
+        &quot;FunctionExpression&quot;: function(node) {
+            var ancestors = context.getAncestors(),
+                previousToken, nextToken;
+
+            if (!/CallExpression|NewExpression/.test(ancestors.pop().type)) {
+                previousToken = context.getTokenBefore(node);
+                nextToken = context.getTokenAfter(node);
+                if (previousToken.value === &quot;(&quot; &amp;&amp; nextToken.value === &quot;)&quot;) {
+                    context.report(node, &quot;Wrapping non-IIFE function literals in parens is unnecessary.&quot;);
+                }
+            }
+        }
+    };
+
+};
+
+},{}],127:[function(require,module,exports){
+/**
+ * @fileoverview A rule to ensure the use of a single variable declaration.
+ * @author Ian Christian Myers
+ */
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+    &quot;use strict&quot;;
+
+    //--------------------------------------------------------------------------
+    // Helpers
+    //--------------------------------------------------------------------------
+
+    var functionStack = [];
+
+    function startFunction() {
+        functionStack.push(false);
+    }
+
+    function endFunction() {
+        functionStack.pop();
+    }
+
+    function checkDeclarations(node) {
+        if (functionStack[functionStack.length - 1]) {
+            context.report(node, &quot;Combine this with the previous 'var' statement.&quot;);
+        } else {
+            functionStack[functionStack.length - 1] = true;
+        }
+    }
+
+    //--------------------------------------------------------------------------
+    // Public API
+    //--------------------------------------------------------------------------
+
+    return {
+        &quot;Program&quot;: startFunction,
+        &quot;FunctionDeclaration&quot;: startFunction,
+        &quot;FunctionExpression&quot;: startFunction,
+
+        &quot;VariableDeclaration&quot;: checkDeclarations,
+
+        &quot;Program:exit&quot;: endFunction,
+        &quot;FunctionDeclaration:exit&quot;: endFunction,
+        &quot;FunctionExpression:exit&quot;: endFunction
+    };
+
+};
+
+},{}],128:[function(require,module,exports){
+/**
+ * @fileoverview A rule to ensure blank lines within blocks.
+ * @author Mathias Schreck &lt;https://github.com/lo1tuma&gt;
+ * @copyright 2014 Mathias Schreck. All rights reserved.
+ */
+
+&quot;use strict&quot;;
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function (context) {
+    var requirePadding = context.options[0] !== &quot;never&quot;;
+
+    /**
+     * Checks if the given non empty block node has a blank line before its first child node.
+     * @param {ASTNode} node The AST node of a BlockStatement.
+     * @returns {boolean} Whether or not the block starts with a blank line.
+     */
+    function isNonEmptyBlockTopPadded(node) {
+        var blockStart = node.loc.start.line,
+            first = node.body[0],
+            firstLine = first.loc.start.line,
+            expectedFirstLine = blockStart + 2,
+            leadingComments = context.getComments(first).leading;
+
+        if (leadingComments.length &gt; 0) {
+            firstLine = leadingComments[0].loc.start.line;
+        }
+
+        return expectedFirstLine &lt;= firstLine;
+    }
+
+    /**
+     * Checks if the given non empty block node has a blank line after its last child node.
+     * @param {ASTNode} node The AST node of a BlockStatement.
+     * @returns {boolean} Whether or not the block ends with a blank line.
+     */
+    function isNonEmptyBlockBottomPadded(node) {
+        var blockEnd = node.loc.end.line,
+            last = node.body[node.body.length - 1],
+            lastLine = last.loc.end.line,
+            expectedLastLine = blockEnd - 2,
+            trailingComments = context.getComments(last).trailing;
+
+        if (trailingComments.length &gt; 0) {
+            lastLine = trailingComments[trailingComments.length - 1].loc.end.line;
+        }
+
+        return lastLine &lt;= expectedLastLine;
+    }
+
+    /**
+     * Checks if the given non empty block node starts AND ends with a blank line.
+     * @param {ASTNode} node The AST node of a BlockStatement.
+     * @returns {boolean} Whether or not the block starts and ends with a blank line.
+     */
+    function isNonEmptyBlockPadded(node) {
+        return isNonEmptyBlockTopPadded(node) &amp;&amp; isNonEmptyBlockBottomPadded(node);
+    }
+
+    /**
+     * Checks if the given non empty block node starts OR ends with a blank line.
+     * @param {ASTNode} node The AST node of a BlockStatement.
+     * @returns {boolean} Whether or not the block starts and ends with a blank line.
+     */
+    function hasNonEmptyBlockExtraPadding(node) {
+        return isNonEmptyBlockTopPadded(node) || isNonEmptyBlockBottomPadded(node);
+    }
+
+    /**
+     * Checks the given BlockStatement node to be padded if the block is not empty.
+     * @param {ASTNode} node The AST node of a BlockStatement.
+     * @returns {void} undefined.
+     */
+    function checkPadding(node) {
+        if (node.body.length &gt; 0) {
+            if (requirePadding) {
+                if (!isNonEmptyBlockPadded(node)) {
+                    context.report(node, &quot;Block must be padded by blank lines.&quot;);
+                }
+            } else {
+                if (hasNonEmptyBlockExtraPadding(node)) {
+                    context.report(node, &quot;Block must not be padded by blank lines.&quot;);
+                }
+            }
+        }
+    }
+
+    return {
+        &quot;BlockStatement&quot;: checkPadding
+    };
+
+};
+
+},{}],129:[function(require,module,exports){
+/**
+ * @fileoverview Rule to flag non-quoted property names in object literals.
+ * @author Mathias Bynens &lt;http://mathiasbynens.be/&gt;
+ */
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+var esprima = require(&quot;esprima&quot;);
+
+module.exports = function(context) {
+
+    &quot;use strict&quot;;
+
+    var MODE = context.options[0];
+
+    switch (MODE) {
+
+        case &quot;as-needed&quot;:
+            return {
+                Property: function(node) {
+                    var key = node.key;
+                    // Ensure that any quoted property names required quoting
+                    if (key.type === &quot;Literal&quot; &amp;&amp; typeof key.value === &quot;string&quot;) {
+                        try {
+                            var tokens = esprima.tokenize(key.value);
+                            if (tokens.length !== 1) {
+                                return;
+                            }
+                            var t = tokens[0];
+                        } catch(e) {
+                            return;
+                        }
+                        if (t.type === &quot;Identifier&quot; || t.type === &quot;Null&quot; || t.type === &quot;Boolean&quot; || t.type === &quot;Numeric&quot; &amp;&amp; &quot;&quot; + +t.value === t.value) {
+                            context.report(node, &quot;Unnecessarily quoted property `{{name}}` found.&quot;, key);
+                        }
+                    }
+                }
+            };
+
+        default:
+            return {
+                Property: function(node) {
+                    var key = node.key;
+                    // Ensure all property names are quoted
+                    if (key.type !== &quot;Literal&quot; || typeof key.value !== &quot;string&quot;) {
+                        context.report(node, &quot;Unquoted property `{{name}}` found.&quot;, key);
+                    }
+                }
+            };
+
+    }
+
+};
+
+},{&quot;esprima&quot;:6}],130:[function(require,module,exports){
+/**
+ * @fileoverview A rule to choose between single and double quote marks
+ * @author Matt DuVall &lt;http://www.mattduvall.com/&gt;, Brandon Payton
+ */
+
+//------------------------------------------------------------------------------
+// Constants
+//------------------------------------------------------------------------------
+
+var QUOTE_SETTINGS = {
+    &quot;double&quot;: {
+        quote: &quot;\&quot;&quot;,
+        alternateQuote: &quot;'&quot;,
+        description: &quot;doublequote&quot;
+    },
+    &quot;single&quot;: {
+        quote: &quot;'&quot;,
+        alternateQuote: &quot;\&quot;&quot;,
+        description: &quot;singlequote&quot;
+    }
+};
+
+var AVOID_ESCAPE = &quot;avoid-escape&quot;;
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+    &quot;use strict&quot;;
+
+    /**
+     * Validate that a string passed in is surrounded by the specified character
+     * @param  {string} val The text to check.
+     * @param  {string} character The character to see if it's surrounded by.
+     * @returns {boolean} True if the text is surrounded by the character, false if not.
+     */
+    function isSurroundedBy(val, character) {
+        return val[0] === character &amp;&amp; val[val.length - 1] === character;
+    }
+
+    return {
+
+        &quot;Literal&quot;: function(node) {
+            var val = node.value,
+                rawVal = node.raw,
+                quoteOption = context.options[0],
+                settings = QUOTE_SETTINGS[quoteOption],
+                avoidEscape = context.options[1] === AVOID_ESCAPE,
+                isValid;
+
+            if (settings &amp;&amp; typeof val === &quot;string&quot;) {
+                isValid = isSurroundedBy(rawVal, settings.quote);
+
+                if (!isValid &amp;&amp; avoidEscape) {
+                    isValid = isSurroundedBy(rawVal, settings.alternateQuote) &amp;&amp; rawVal.indexOf(settings.quote) &gt;= 0;
+                }
+
+                if (!isValid) {
+                    context.report(node, &quot;Strings must use &quot; + settings.description + &quot;.&quot;);
+                }
+            }
+        }
+    };
+
+};
+
+},{}],131:[function(require,module,exports){
+/**
+ * @fileoverview Rule to flag use of parseInt without a radix argument
+ * @author James Allardice
+ */
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+    &quot;use strict&quot;;
+
+    return {
+        &quot;CallExpression&quot;: function(node) {
+
+            var radix;
+
+            if (node.callee.name === &quot;parseInt&quot;) {
+
+                if (node.arguments.length &lt; 2) {
+                    context.report(node, &quot;Missing radix parameter.&quot;);
+                } else {
+
+                    radix = node.arguments[1];
+
+                    // don't allow non-numeric literals or undefined
+                    if ((radix.type === &quot;Literal&quot; &amp;&amp; typeof radix.value !== &quot;number&quot;) ||
+                        (radix.type === &quot;Identifier&quot; &amp;&amp; radix.name === &quot;undefined&quot;)
+                    ) {
+                        context.report(node, &quot;Invalid radix parameter.&quot;);
+                    }
+                }
+
+            }
+        }
+    };
+
+};
+
+},{}],132:[function(require,module,exports){
+/**
+ * @fileoverview Rule to flag missing semicolons.
+ * @author Nicholas C. Zakas
+ */
+&quot;use strict&quot;;
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+module.exports = function(context) {
+
+    var OPT_OUT_PATTERN = /[\[\(\/\+\-]/;
+
+    var always = context.options[0] !== &quot;never&quot;;
+
+    //--------------------------------------------------------------------------
+    // Helpers
+    //--------------------------------------------------------------------------
+
+    /**
+     * Checks a node to see if it's followed by a semicolon.
+     * @param {ASTNode} node The node to check.
+     * @returns {void}
+     */
+    function checkForSemicolon(node) {
+        var lastToken = context.getLastToken(node),
+            nextToken = context.getTokenAfter(node);
+
+        if (always) {
+            if (lastToken.type !== &quot;Punctuator&quot; || lastToken.value !== &quot;;&quot;) {
+                context.report(node, lastToken.loc.end, &quot;Missing semicolon.&quot;);
+            }
+        } else {
+            if (lastToken.type === &quot;Punctuator&quot; &amp;&amp; lastToken.value === &quot;;&quot;) {
+
+                if (!nextToken || !(OPT_OUT_PATTERN.test(nextToken.value))) {
+                    context.report(node, node.loc.end, &quot;Extra semicolon.&quot;);
+                }
+
+            }
+        }
+    }
+
+    /**
+     * Checks to see if there's a semicolon after a variable declaration.
+     * @param {ASTNode} node The node to check.
+     * @returns {void}
+     */
+    function checkForSemicolonForVariableDeclaration(node) {
+
+        var ancestors = context.getAncestors(),
+            parentIndex = ancestors.length - 1,
+            parent = ancestors[parentIndex];
+
+        if ((parent.type !== &quot;ForStatement&quot; || parent.init !== node) &amp;&amp;
+            (parent.type !== &quot;ForInStatement&quot; || parent.left !== node)
+        ) {
+            checkForSemicolon(node);
+        }
+    }
+
+    //--------------------------------------------------------------------------
+    // Public API
+    //--------------------------------------------------------------------------
+
+    return {
+
+        &quot;VariableDeclaration&quot;: checkForSemicolonForVariableDeclaration,
+        &quot;ExpressionStatement&quot;: checkForSemicolon,
+        &quot;ReturnStatement&quot;: checkForSemicolon,
+        &quot;DebuggerStatement&quot;: checkForSemicolon,
+        &quot;BreakStatement&quot;: checkForSemicolon,
+        &quot;ContinueStatement&quot;: checkForSemicolon,
+        &quot;EmptyStatement&quot;: function (node) {
+            var nextToken;
+
+            if (!always) {
+                nextToken = context.getTokenAfter(node) || context.getLastToken(node);
+
+                if (!(OPT_OUT_PATTERN.test(nextToken.value))) {
+                    context.report(node, &quot;Extra semicolon.&quot;);
+                }
+            }
+
+
+        }
+    };
+
+};
+
+},{}],133:[function(require,module,exports){
+/**
+ * @fileoverview Rule to require sorting of variables within a single Variable Declaration block
+ * @author Ilya Volodin
+ */
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+    &quot;use strict&quot;;
+
+    var configuration = context.options[0] || {},
+        ignoreCase = configuration.ignoreCase || false;
+
+    return {
+        &quot;VariableDeclaration&quot;: function(node) {
+            node.declarations.reduce(function(memo, decl) {
+                var lastVariableName = memo.id.name,
+                    currenVariableName = decl.id.name;
+
+                if (ignoreCase) {
+                    lastVariableName = lastVariableName.toLowerCase();
+                    currenVariableName = currenVariableName.toLowerCase();
+                }
+
+                if (currenVariableName &lt; lastVariableName) {
+                    context.report(decl, &quot;Variables within the same declaration block should be sorted alphabetically&quot;);
+                    return memo;
+                } else {
+                    return decl;
+                }
+            }, node.declarations[0]);
+        }
+    };
+};
+
+},{}],134:[function(require,module,exports){
+/**
+ * @fileoverview Rule to enforce the number of spaces after certain keywords
+ * @author Nick Fisher
+ */
+&quot;use strict&quot;;
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+    // unless the first option is `&quot;never&quot;`, then a space is required
+    var requiresSpace = context.options[0] !== &quot;never&quot;,
+        config = context.options[1] || { checkFunctionKeyword: false };
+
+    /**
+     * Check if the separation of two adjacent tokens meets the spacing rules, and report a problem if not.
+     *
+     * @param {ASTNode} node  The node to which the potential problem belongs.
+     * @param {Token} left    The first token.
+     * @param {Token} right   The second token
+     * @returns {void}
+     */
+    function checkTokens(node, left, right) {
+        var hasSpace = left.range[1] &lt; right.range[0],
+            value = left.value;
+
+        if (hasSpace !== requiresSpace) {
+            context.report(node, &quot;Keyword \&quot;{{value}}\&quot; must {{not}}be followed by whitespace.&quot;, {
+                value: value,
+                not: requiresSpace ? &quot;&quot; : &quot;not &quot;
+            });
+        }
+    }
+
+    /**
+     * Check if the given node (`if`, `for`, `while`, etc), has the correct spacing after it.
+     * @param {ASTNode} node The node to check.
+     * @returns {void}
+     */
+    function check(node) {
+        var tokens = context.getFirstTokens(node, 2);
+        checkTokens(node, tokens[0], tokens[1]);
+    }
+
+    return {
+        &quot;IfStatement&quot;: function (node) {
+            check(node);
+            // check the `else`
+            if (node.alternate &amp;&amp; node.alternate.type !== &quot;IfStatement&quot;) {
+                checkTokens(node.alternate, context.getTokenBefore(node.alternate), context.getFirstToken(node.alternate));
+            }
+        },
+        &quot;ForStatement&quot;: check,
+        &quot;ForOfStatement&quot;: check,
+        &quot;ForInStatement&quot;: check,
+        &quot;WhileStatement&quot;: check,
+        &quot;DoWhileStatement&quot;: function (node) {
+            check(node);
+            // check the `while`
+            var whileTokens = context.getTokensBefore(node.test, 2);
+            checkTokens(node, whileTokens[0], whileTokens[1]);
+        },
+        &quot;SwitchStatement&quot;: check,
+        &quot;TryStatement&quot;: function (node) {
+            check(node);
+            // check the `finally`
+            if (node.finalizer) {
+                checkTokens(node.finalizer, context.getTokenBefore(node.finalizer), context.getFirstToken(node.finalizer));
+            }
+        },
+        &quot;CatchStatement&quot;: check,
+        &quot;WithStatement&quot;: check,
+        &quot;FunctionExpression&quot;: function (node) {
+            if (config.checkFunctionKeyword) {
+                check(node);
+            }
+        }
+    };
+};
+
+},{}],135:[function(require,module,exports){
+/**
+ * @fileoverview A rule to ensure whitespace before blocks.
+ * @author Mathias Schreck &lt;https://github.com/lo1tuma&gt;
+ * @copyright 2014 Mathias Schreck. All rights reserved.
+ */
+
+&quot;use strict&quot;;
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function (context) {
+    var requireSpace = context.options[0] !== &quot;never&quot;;
+
+    /**
+     * Determines whether two adjacent tokens are have whitespace between them.
+     * @param {Object} left - The left token object.
+     * @param {Object} right - The right token object.
+     * @returns {boolean} Whether or not there is space between the tokens.
+     */
+    function isSpaced(left, right) {
+        return left.range[1] &lt; right.range[0];
+    }
+
+    /**
+     * Determines whether two adjacent tokens are on the same line.
+     * @param {Object} left - The left token object.
+     * @param {Object} right - The right token object.
+     * @returns {boolean} Whether or not the tokens are on the same line.
+     */
+    function isSameLine(left, right) {
+        return left.loc.start.line === right.loc.start.line;
+    }
+
+    /**
+     * Checks the given BlockStatement node has a preceding space if it doesn’t start on a new line.
+     * @param {ASTNode} node The AST node of a BlockStatement.
+     * @returns {void} undefined.
+     */
+    function checkPrecedingSpace(node) {
+        var precedingToken = context.getTokenBefore(node),
+            hasSpace;
+
+        if (precedingToken &amp;&amp; isSameLine(precedingToken, node)) {
+            hasSpace = isSpaced(precedingToken, node);
+
+            if (requireSpace) {
+                if (!hasSpace) {
+                    context.report(node, &quot;Missing space before opening brace.&quot;);
+                }
+            } else {
+                if (hasSpace) {
+                    context.report(node, &quot;Unexpected space before opening brace.&quot;);
+                }
+            }
+        }
+    }
+
+    return {
+        &quot;BlockStatement&quot;: checkPrecedingSpace
+    };
+
+};
+
+},{}],136:[function(require,module,exports){
+/**
+ * @fileoverview Disallows or enforces spaces inside of brackets.
+ * @author Ian Christian Myers
+ * @copyright 2014 Brandyn Bennett. All rights reserved.
+ * @copyright 2014 Michael Ficarra. No rights reserved.
+ */
+&quot;use strict&quot;;
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+    var options = {
+        spaced: context.options[0] === &quot;always&quot;,
+        singleElementException: context.options[1] != null &amp;&amp; !!context.options[1].singleValue,
+        objectsInArraysException: context.options[1] != null &amp;&amp; !!context.options[1].objectsInArrays,
+        arraysInArraysException: context.options[1] != null &amp;&amp; !!context.options[1].arraysInArrays,
+        propertyName: context.options[1] == null || context.options[1].propertyName == null || !!context.options[1].propertyName
+    };
+
+    //--------------------------------------------------------------------------
+    // Helpers
+    //--------------------------------------------------------------------------
+
+    /**
+     * Determines whether two adjacent tokens are have whitespace between them.
+     * @param {Object} left - The left token object.
+     * @param {Object} right - The right token object.
+     * @returns {boolean} Whether or not there is space between the tokens.
+     */
+    function isSpaced(left, right) {
+        return left.range[1] &lt; right.range[0];
+    }
+
+    /**
+     * Determines whether two adjacent tokens are on the same line.
+     * @param {Object} left - The left token object.
+     * @param {Object} right - The right token object.
+     * @returns {boolean} Whether or not the tokens are on the same line.
+     */
+    function isSameLine(left, right) {
+        return left.loc.start.line === right.loc.start.line;
+    }
+
+    /**
+    * Reports that there shouldn't be a space after the first token
+    * @param {ASTNode} node - The node to report in the event of an error.
+    * @param {Object[]} tokens - The tokens to be checked for spacing.
+    * @returns {void}
+    */
+    function reportNoBeginningSpace(node, tokens) {
+        context.report(node, tokens[0].loc.start,
+                    &quot;There should be no space after '&quot; + tokens[0].value + &quot;'&quot;);
+    }
+
+    /**
+    * Reports that there shouldn't be a space before the last token
+    * @param {ASTNode} node - The node to report in the event of an error.
+    * @param {Object[]} tokens - The tokens to be checked for spacing.
+    * @returns {void}
+    */
+    function reportNoEndingSpace(node, tokens) {
+        context.report(node, tokens[tokens.length - 1].loc.start,
+                    &quot;There should be no space before '&quot; + tokens[tokens.length - 1].value + &quot;'&quot;);
+    }
+
+    /**
+    * Reports that there should be a space after the first token
+    * @param {ASTNode} node - The node to report in the event of an error.
+    * @param {Object[]} tokens - The tokens to be checked for spacing.
+    * @returns {void}
+    */
+    function reportRequiredBeginningSpace(node, tokens) {
+        context.report(node, tokens[0].loc.start,
+                    &quot;A space is required after '&quot; + tokens[0].value + &quot;'&quot;);
+    }
+
+    /**
+    * Reports that there should be a space before the last token
+    * @param {ASTNode} node - The node to report in the event of an error.
+    * @param {Object[]} tokens - The tokens to be checked for spacing.
+    * @returns {void}
+    */
+    function reportRequiredEndingSpace(node, tokens) {
+        context.report(node, tokens[tokens.length - 1].loc.start,
+                    &quot;A space is required before '&quot; + tokens[tokens.length - 1].value + &quot;'&quot;);
+    }
+
+
+    //--------------------------------------------------------------------------
+    // Public
+    //--------------------------------------------------------------------------
+
+    return {
+
+        MemberExpression: options.propertyName ? function checkMember(node) {
+            if (node.computed) {
+                var tokens = context.getTokens(node.property, 1, 1);
+                var tokenA = tokens[0], tokenB = tokens[1],
+                    tokenC = tokens[tokens.length - 2], tokenD = tokens[tokens.length - 1];
+                if (isSameLine(tokenA, tokenB) || isSameLine(tokenC, tokenD)) {
+                    if (options.spaced) {
+                        if (!isSpaced(tokenA, tokenB) &amp;&amp; isSameLine(tokenA, tokenB)) {
+                            reportRequiredBeginningSpace(node, tokens);
+                        }
+                        if (!isSpaced(tokenC, tokenD) &amp;&amp; isSameLine(tokenC, tokenD)) {
+                            reportRequiredEndingSpace(node, tokens);
+                        }
+                    } else {
+                        if (isSpaced(tokenA, tokenB)) {
+                            reportNoBeginningSpace(node, tokens);
+                        }
+                        if (isSpaced(tokenC, tokenD)) {
+                            reportNoEndingSpace(node, tokens);
+                        }
+                    }
+                }
+            }
+        } : function() {},
+
+        ArrayExpression: function(node) {
+            if (node.elements.length === 0) {
+                return;
+            }
+            var tokens = context.getTokens(node);
+            var tokenA = tokens[0], tokenB = tokens[1],
+                tokenC = tokens[tokens.length - 2], tokenD = tokens[tokens.length - 1];
+
+            var openingBracketMustBeSpaced =
+                options.objectsInArraysException &amp;&amp; tokenB.value === &quot;{&quot; ||
+                options.arraysInArraysException &amp;&amp; tokenB.value === &quot;[&quot; ||
+                options.singleElementException &amp;&amp; node.elements.length === 1
+                ? !options.spaced : options.spaced;
+
+            var closingBracketMustBeSpaced =
+                options.objectsInArraysException &amp;&amp; tokenC.value === &quot;}&quot; ||
+                options.arraysInArraysException &amp;&amp; tokenC.value === &quot;]&quot; ||
+                options.singleElementException &amp;&amp; node.elements.length === 1
+                ? !options.spaced : options.spaced;
+
+            if (isSameLine(tokenA, tokenB) || isSameLine(tokenC, tokenD)) {
+                if (openingBracketMustBeSpaced &amp;&amp; !isSpaced(tokenA, tokenB)) {
+                    reportRequiredBeginningSpace(node, tokens);
+                } else if (!openingBracketMustBeSpaced &amp;&amp; isSpaced(tokenA, tokenB)) {
+                    reportNoBeginningSpace(node, tokens);
+                }
+                if (closingBracketMustBeSpaced &amp;&amp; !isSpaced(tokenC, tokenD)) {
+                    reportRequiredEndingSpace(node, tokens);
+                } else if (!closingBracketMustBeSpaced &amp;&amp; isSpaced(tokenC, tokenD)) {
+                    reportNoEndingSpace(node, tokens);
+                }
+            }
+        },
+
+        ObjectExpression: function(node) {
+            if (node.properties.length === 0) {
+                return;
+            }
+            var tokens = context.getTokens(node);
+            var tokenA = tokens[0], tokenB = tokens[1],
+                tokenC = tokens[tokens.length - 2], tokenD = tokens[tokens.length - 1];
+            if (isSameLine(tokenA, tokenB) || isSameLine(tokenC, tokenD)) {
+                if (options.spaced) {
+                    if (!isSpaced(tokenA, tokenB)) {
+                        reportRequiredBeginningSpace(node, tokens);
+                    }
+                    if (!isSpaced(tokenC, tokenD)) {
+                        reportRequiredEndingSpace(node, tokens);
+                    }
+                } else {
+                    if (isSpaced(tokenA, tokenB)) {
+                        reportNoBeginningSpace(node, tokens);
+                    }
+                    if (isSpaced(tokenC, tokenD)) {
+                        reportNoEndingSpace(node, tokens);
+                    }
+                }
+            }
+        }
+
+    };
+
+};
+
+},{}],137:[function(require,module,exports){
+/**
+ * @fileoverview Disallows or enforces spaces inside of parentheses.
+ * @author Jonathan Rajavuori
+ * @copyright 2014 Jonathan Rajavuori. All rights reserved.
+ */
+&quot;use strict&quot;;
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+    var RE, MESSAGE;
+
+    if (context.options[0] === &quot;always&quot;) {
+        RE = /\([^ \)]|[^ \(]\)/mg;
+        MESSAGE = &quot;There must be a space inside this paren.&quot;;
+    } else {
+        RE = /\( | \)/mg;
+        MESSAGE = &quot;There should be no spaces inside this paren.&quot;;
+    }
+
+
+    //--------------------------------------------------------------------------
+    // Helpers
+    //--------------------------------------------------------------------------
+
+    var skipRanges = [];
+
+    /**
+     * Adds the range of a node to the set to be skipped when checking parens
+     * @param {ASTNode} node The node to skip
+     * @returns {void}
+     * @private
+     */
+    function addSkipRange(node) {
+        skipRanges.push(node.range);
+    }
+
+    /**
+     * Sorts the skipRanges array. Must be called before shouldSkip
+     * @returns {void}
+     * @private
+     */
+    function sortSkipRanges() {
+        skipRanges.sort(function (a, b) {
+            return a[0] - b[0];
+        });
+    }
+
+    /**
+     * Checks if a certain position in the source should be skipped
+     * @param {Number} pos The 0-based index in the source
+     * @returns {boolean} whether the position should be skipped
+     * @private
+     */
+    function shouldSkip(pos) {
+        var i, len, range;
+        for (i = 0, len = skipRanges.length; i &lt; len; i += 1) {
+            range = skipRanges[i];
+            if (pos &lt; range[0]) {
+                break;
+            } else if (pos &lt; range[1]) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    //--------------------------------------------------------------------------
+    // Public
+    //--------------------------------------------------------------------------
+
+    return {
+
+        &quot;Program:exit&quot;: function checkParenSpaces(node) {
+
+            var match,
+                nextLine,
+                column,
+                line = 1,
+                source = context.getSource(),
+                pos = 0;
+
+            sortSkipRanges();
+
+            while ((match = RE.exec(source)) !== null) {
+                if (source.charAt(match.index) !== &quot;(&quot;) {
+                    // Matched a closing paren pattern
+                    match.index += 1;
+                }
+
+                if (!shouldSkip(match.index)) {
+                    while ((nextLine = source.indexOf(&quot;\n&quot;, pos)) !== -1 &amp;&amp; nextLine &lt; match.index) {
+                        pos = nextLine + 1;
+                        line += 1;
+                    }
+                    column = match.index - pos;
+
+                    context.report(node, { line: line, column: column }, MESSAGE);
+                }
+            }
+
+        },
+
+
+        // These nodes can contain parentheses that this rule doesn't care about
+
+        LineComment: addSkipRange,
+
+        BlockComment: addSkipRange,
+
+        Literal: addSkipRange
+
+    };
+
+};
+
+},{}],138:[function(require,module,exports){
+/**
+ * @fileoverview Require spaces around infix operators
+ * @author Michael Ficarra
+ */
+&quot;use strict&quot;;
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+    var OPERATORS = [
+        &quot;*&quot;, &quot;/&quot;, &quot;%&quot;, &quot;+&quot;, &quot;-&quot;, &quot;&lt;&lt;&quot;, &quot;&gt;&gt;&quot;, &quot;&gt;&gt;&gt;&quot;, &quot;&lt;&quot;, &quot;&lt;=&quot;, &quot;&gt;&quot;, &quot;&gt;=&quot;, &quot;in&quot;,
+        &quot;instanceof&quot;, &quot;==&quot;, &quot;!=&quot;, &quot;===&quot;, &quot;!==&quot;, &quot;&amp;&quot;, &quot;^&quot;, &quot;|&quot;, &quot;&amp;&amp;&quot;, &quot;||&quot;, &quot;=&quot;,
+        &quot;+=&quot;, &quot;-=&quot;, &quot;*=&quot;, &quot;/=&quot;, &quot;%=&quot;, &quot;&lt;&lt;=&quot;, &quot;&gt;&gt;=&quot;, &quot;&gt;&gt;&gt;=&quot;, &quot;&amp;=&quot;, &quot;^=&quot;, &quot;|=&quot;,
+        &quot;?&quot;, &quot;:&quot;, &quot;,&quot;
+    ];
+
+    function isSpaced(left, right) {
+        var op, tokens = context.getTokens({range: [left.range[1], right.range[0]]}, 1, 1);
+        for (var i = 1, l = tokens.length - 1; i &lt; l; ++i) {
+            op = tokens[i];
+            if (
+                op.type === &quot;Punctuator&quot; &amp;&amp;
+                OPERATORS.indexOf(op.value) &gt;= 0 &amp;&amp;
+                (tokens[i - 1].range[1] &gt;= op.range[0] || op.range[1] &gt;= tokens[i + 1].range[0])
+            ) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    function isRightSpaced(left, right) {
+        var op, tokens = context.getTokens({range: [left.range[1], right.range[0]]}, 1, 1);
+        for (var i = 1, l = tokens.length - 1; i &lt; l; ++i) {
+            op = tokens[i];
+            if (
+                op.type === &quot;Punctuator&quot; &amp;&amp;
+                OPERATORS.indexOf(op.value) &gt;= 0 &amp;&amp;
+                op.range[1] &gt;= tokens[i + 1].range[0]
+            ) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    function report(node) {
+        context.report(node, &quot;Infix operators must be spaced.&quot;);
+    }
+
+    function checkBinary(node) {
+        if (!isSpaced(node.left, node.right)) {
+            report(node);
+        }
+    }
+
+    function checkSequence(node) {
+        for (var i = 0, l = node.expressions.length - 1; i &lt; l; ++i) {
+            if (!isRightSpaced(node.expressions[i], node.expressions[i + 1])) {
+                report(node);
+                break;
+            }
+        }
+    }
+
+    function checkConditional(node) {
+        if (!isSpaced(node.test, node.consequent) || !isSpaced(node.consequent, node.alternate)) {
+            report(node);
+        }
+    }
+
+    function checkVar(node) {
+        if (node.init &amp;&amp; !isSpaced(node.id, node.init)) {
+            report(node);
+        }
+    }
+
+    return {
+        &quot;AssignmentExpression&quot;: checkBinary,
+        &quot;BinaryExpression&quot;: checkBinary,
+        &quot;LogicalExpression&quot;: checkBinary,
+        &quot;ConditionalExpression&quot;: checkConditional,
+        &quot;SequenceExpression&quot;: checkSequence,
+        &quot;VariableDeclarator&quot;: checkVar
+    };
+
+};
+
+},{}],139:[function(require,module,exports){
+/**
+ * @fileoverview Require spaces following return, throw, and case
+ * @author Michael Ficarra
+ */
+&quot;use strict&quot;;
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+    function check(node) {
+        var tokens = context.getFirstTokens(node, 2),
+            value = tokens[0].value;
+
+        if (tokens[0].range[1] &gt;= tokens[1].range[0]) {
+            context.report(node, &quot;Keyword \&quot;&quot; + value + &quot;\&quot; must be followed by whitespace.&quot;);
+        }
+    }
+
+    return {
+        &quot;ReturnStatement&quot;: function(node) {
+            if (node.argument) {
+                check(node);
+            }
+        },
+        &quot;SwitchCase&quot;: function(node) {
+            if (node.test) {
+                check(node);
+            }
+        },
+        &quot;ThrowStatement&quot;: check
+    };
+
+};
+
+},{}],140:[function(require,module,exports){
+/**
+ * @fileoverview Require spaces following unary word operators
+ * @author Michael Ficarra
+ */
+&quot;use strict&quot;;
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+    function check(node) {
+        var tokens;
+        tokens = context.getFirstTokens(node, 2);
+        if (tokens[0].range[1] &gt;= tokens[1].range[0]) {
+            switch (tokens[0].value) {
+                case &quot;delete&quot;:
+                case &quot;new&quot;:
+                case &quot;typeof&quot;:
+                case &quot;void&quot;:
+                    context.report(node, &quot;Unary word operator \&quot;&quot; + tokens[0].value + &quot;\&quot; must be followed by whitespace.&quot;);
+                    break;
+                // no default
+            }
+        }
+    }
+
+    return {
+        &quot;NewExpression&quot;: check,
+        &quot;UnaryExpression&quot;: check
+    };
+
+};
+
+},{}],141:[function(require,module,exports){
+/**
+ * @fileoverview Enforces or disallows a space beginning a single-line comment.
+ * @author Greg Cochard
+ * @copyright 2014 Greg Cochard. All rights reserved.
+ */
+&quot;use strict&quot;;
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+    // Unless the first option is never, require a space
+    var requireSpace = context.options[0] !== &quot;never&quot;;
+
+    // Default to match anything, so all will fail if there are no exceptions
+    var exceptionMatcher = new RegExp(&quot; &quot;);
+
+    // Grab the exceptions array and build a RegExp matcher for it
+    var hasExceptions = context.options.length === 2;
+    var unescapedExceptions = hasExceptions ? context.options[1].exceptions : [];
+    var exceptions;
+
+    if (unescapedExceptions.length) {
+        exceptions = unescapedExceptions.map(function(s) {
+            return s.replace(/([.*+?${}()|\^\[\]\/\\])/g, &quot;\\$1&quot;);
+        });
+        exceptionMatcher = new RegExp(&quot;(^(&quot; + exceptions.join(&quot;)+$)|(^(&quot;) + &quot;)+$)&quot;);
+    }
+
+
+    //--------------------------------------------------------------------------
+    // Public
+    //--------------------------------------------------------------------------
+
+    return {
+
+        &quot;LineComment&quot;: function checkCommentForSpace(node) {
+
+            if (node.loc.start.line === 1 &amp;&amp; /^#!/.test(context.getSourceLines()[0])) {
+
+                /*
+                 * HACK: return if we are on the first line and
+                 * encounter a shebang at the beginning.
+                 * It seems the parser will return this as a
+                 * comment and filter out the # so we must fetch
+                 * the actual source line. Is this being caused
+                 * by esprima or eslint? Something else?
+                 */
+                return;
+            }
+
+            if (requireSpace) {
+
+                // Space expected and not found
+                if (node.value.indexOf(&quot; &quot;) !== 0) {
+
+                    /*
+                     * Do two tests; one for space starting the line,
+                     * and one for a comment comprised only of exceptions
+                     */
+                    if (hasExceptions &amp;&amp; !exceptionMatcher.test(node.value)) {
+                        context.report(node, &quot;Expected exception block or space after // in comment.&quot;);
+                    } else if (!hasExceptions) {
+                        context.report(node, &quot;Expected space after // in comment.&quot;);
+                    }
+                }
+
+            } else {
+
+                if (node.value.indexOf(&quot; &quot;) === 0) {
+                    context.report(node, &quot;Unexpected space after // in comment.&quot;);
+                }
+            }
+        }
+
+    };
+};
+
+},{}],142:[function(require,module,exports){
+/**
+ * @fileoverview Rule to ensure code is running in strict mode.
+ * @author Nicholas C. Zakas
+ * @copyright 2013-2014 Nicholas C. Zakas. All rights reserved.
+ */
+&quot;use strict&quot;;
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+    var scopes = [];
+
+    /**
+     * Determines if a given node is &quot;use strict&quot;.
+     * @param {ASTNode} node The node to check.
+     * @returns {boolean} True if the node is a strict pragma, false if not.
+     * @void
+     */
+    function isStrictPragma(node) {
+        return (node &amp;&amp; node.type === &quot;ExpressionStatement&quot; &amp;&amp;
+                node.expression.value === &quot;use strict&quot;);
+    }
+
+    /**
+     * When you enter a scope, push the strict value from the previous scope
+     * onto the stack.
+     * @param {ASTNode} node The AST node being checked.
+     * @returns {void}
+     * @private
+     */
+    function enterScope(node) {
+
+        var isStrict = false,
+            isProgram = (node.type === &quot;Program&quot;),
+            isParentGlobal = scopes.length === 1,
+            isParentStrict = scopes.length ? scopes[scopes.length - 1] : false;
+
+        // look for the &quot;use strict&quot; pragma
+        if (isProgram) {
+            isStrict = isStrictPragma(node.body[0]) || isParentStrict;
+        } else {
+            isStrict = isStrictPragma(node.body.body[0]) || isParentStrict;
+        }
+
+        scopes.push(isStrict);
+
+        // never warn if the parent is strict or the function is strict
+        if (!isParentStrict &amp;&amp; !isStrict &amp;&amp; isParentGlobal) {
+            context.report(node, &quot;Missing \&quot;use strict\&quot; statement.&quot;);
+        }
+    }
+
+    /**
+     * When you exit a scope, pop off the top scope and see if it's true or
+     * false.
+     * @returns {void}
+     * @private
+     */
+    function exitScope() {
+        scopes.pop();
+    }
+
+    return {
+
+        &quot;Program&quot;: enterScope,
+        &quot;FunctionDeclaration&quot;: enterScope,
+        &quot;FunctionExpression&quot;: enterScope,
+
+        &quot;Program:exit&quot;: exitScope,
+        &quot;FunctionDeclaration:exit&quot;: exitScope,
+        &quot;FunctionExpression:exit&quot;: exitScope
+    };
+
+};
+
+},{}],143:[function(require,module,exports){
+/**
+ * @fileoverview Rule to flag comparisons to the value NaN
+ * @author James Allardice
+ */
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+    &quot;use strict&quot;;
+
+    return {
+        &quot;BinaryExpression&quot;: function(node) {
+
+            if (!/^[|&amp;^]$/.test(node.operator) &amp;&amp; node.left.name === &quot;NaN&quot; || node.right.name === &quot;NaN&quot;) {
+                context.report(node, &quot;Use the isNaN function to compare with NaN.&quot;);
+            }
+        }
+    };
+
+};
+
+},{}],144:[function(require,module,exports){
+/**
+ * @fileoverview Validates JSDoc comments are syntactically correct
+ * @author Nicholas C. Zakas
+ */
+&quot;use strict&quot;;
+
+//------------------------------------------------------------------------------
+// Requirements
+//------------------------------------------------------------------------------
+
+var doctrine = require(&quot;doctrine&quot;);
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+    var options = context.options[0] || {},
+        prefer = options.prefer || {},
+
+        // these both default to true, so you have to explicitly make them false
+        requireReturn = options.requireReturn === false ? false : true,
+        requireParamDescription = options.requireParamDescription === false ? false : true;
+
+    //--------------------------------------------------------------------------
+    // Helpers
+    //--------------------------------------------------------------------------
+
+    // Using a stack to store if a function returns or not (handling nested functions)
+    var fns = [];
+
+    /**
+     * When parsing a new function, store it in our function stack.
+     * @returns {void}
+     * @private
+     */
+    function startFunction() {
+        fns.push({returnPresent: false});
+    }
+
+    /**
+     * Indicate that return has been found in the current function.
+     * @param {ASTNode} node The return node.
+     * @returns {void}
+     * @private
+     */
+    function addReturn(node) {
+        var functionState = fns[fns.length - 1];
+
+        if (functionState &amp;&amp; node.argument !== null) {
+            functionState.returnPresent = true;
+        }
+    }
+
+    /**
+     * Validate the JSDoc node and output warnings if anything is wrong.
+     * @param {ASTNode} node The AST node to check.
+     * @returns {void}
+     * @private
+     */
+    function checkJSDoc(node) {
+        var jsdocNode = context.getJSDocComment(node),
+            functionData = fns.pop(),
+            hasReturns = false,
+            hasConstructor = false,
+            params = Object.create(null),
+            jsdoc;
+
+        // make sure only to validate JSDoc comments
+        if (jsdocNode) {
+
+            try {
+                jsdoc = doctrine.parse(jsdocNode.value, {
+                    strict: true,
+                    unwrap: true,
+                    sloppy: true
+                });
+            } catch (ex) {
+
+                if (/braces/i.test(ex.message)) {
+                    context.report(jsdocNode, &quot;JSDoc type missing brace.&quot;);
+                } else {
+                    context.report(jsdocNode, &quot;JSDoc syntax error.&quot;);
+                }
+
+                return;
+            }
+
+            jsdoc.tags.forEach(function(tag) {
+
+                switch (tag.title) {
+
+                    case &quot;param&quot;:
+                        if (!tag.type) {
+                            context.report(jsdocNode, &quot;Missing JSDoc parameter type for '{{name}}'.&quot;, { name: tag.name });
+                        }
+
+                        if (!tag.description &amp;&amp; requireParamDescription) {
+                            context.report(jsdocNode, &quot;Missing JSDoc parameter description for '{{name}}'.&quot;, { name: tag.name });
+                        }
+
+                        if (params[tag.name]) {
+                            context.report(jsdocNode, &quot;Duplicate JSDoc parameter '{{name}}'.&quot;, { name: tag.name });
+                        } else if (tag.name.indexOf(&quot;.&quot;) === - 1) {
+                            params[tag.name] = 1;
+                        }
+                        break;
+
+                    case &quot;return&quot;:
+                    case &quot;returns&quot;:
+                        hasReturns = true;
+
+                        if (!requireReturn &amp;&amp; !functionData.returnPresent &amp;&amp; tag.type.name !== &quot;void&quot; &amp;&amp; tag.type.name !== &quot;undefined&quot;) {
+                            context.report(jsdocNode, &quot;Unexpected @&quot; + tag.title + &quot; tag; function has no return statement.&quot;);
+                        } else {
+                            if (!tag.type) {
+                                context.report(jsdocNode, &quot;Missing JSDoc return type.&quot;);
+                            }
+
+                            if (tag.type.name !== &quot;void&quot; &amp;&amp; !tag.description) {
+                                context.report(jsdocNode, &quot;Missing JSDoc return description.&quot;);
+                            }
+                        }
+
+                        break;
+
+                    case &quot;constructor&quot;:
+                        hasConstructor = true;
+                        break;
+
+                    // no default
+                }
+
+                // check tag preferences
+                if (prefer.hasOwnProperty(tag.title)) {
+                    context.report(jsdocNode, &quot;Use @{{name}} instead.&quot;, { name: prefer[tag.title] });
+                }
+
+            });
+
+            // check for functions missing @returns
+            if (!hasReturns &amp;&amp; !hasConstructor) {
+                if (requireReturn || functionData.returnPresent) {
+                    context.report(jsdocNode, &quot;Missing JSDoc @returns for function.&quot;);
+                }
+            }
+
+            // check the parameters
+            var jsdocParams = Object.keys(params);
+
+            node.params.forEach(function(param, i) {
+                var name = param.name;
+
+                if (jsdocParams[i] &amp;&amp; (name !== jsdocParams[i])) {
+                    context.report(jsdocNode, &quot;Expected JSDoc for '{{name}}' but found '{{jsdocName}}'.&quot;, {
+                        name: name,
+                        jsdocName: jsdocParams[i]
+                    });
+                } else if (!params[name]) {
+                    context.report(jsdocNode, &quot;Missing JSDoc for parameter '{{name}}'.&quot;, {
+                        name: name
+                    });
+                }
+            });
+
+        }
+
+    }
+
+    //--------------------------------------------------------------------------
+    // Public
+    //--------------------------------------------------------------------------
+
+    return {
+        &quot;FunctionExpression&quot;: startFunction,
+        &quot;FunctionDeclaration&quot;: startFunction,
+        &quot;FunctionExpression:exit&quot;: checkJSDoc,
+        &quot;FunctionDeclaration:exit&quot;: checkJSDoc,
+        &quot;ReturnStatement&quot;: addReturn
+    };
+
+};
+
+},{&quot;doctrine&quot;:4}],145:[function(require,module,exports){
+/**
+ * @fileoverview Ensures that the results of typeof are compared against a valid string
+ * @author Ian Christian Myers
+ */
+&quot;use strict&quot;;
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+    var VALID_TYPES = [&quot;symbol&quot;, &quot;undefined&quot;, &quot;object&quot;, &quot;boolean&quot;, &quot;number&quot;, &quot;string&quot;, &quot;function&quot;],
+        OPERATORS = [&quot;==&quot;, &quot;===&quot;, &quot;!=&quot;, &quot;!==&quot;];
+
+    //--------------------------------------------------------------------------
+    // Public
+    //--------------------------------------------------------------------------
+
+    return {
+
+        &quot;UnaryExpression&quot;: function (node) {
+            var parent, sibling;
+
+            if (node.operator === &quot;typeof&quot;) {
+                parent = context.getAncestors().pop();
+
+                if (parent.type === &quot;BinaryExpression&quot; &amp;&amp; OPERATORS.indexOf(parent.operator) !== -1) {
+                    sibling = parent.left === node ? parent.right : parent.left;
+
+                    if (sibling.type === &quot;Literal&quot; &amp;&amp; VALID_TYPES.indexOf(sibling.value) === -1) {
+                        context.report(sibling, &quot;Invalid typeof comparison value&quot;);
+                    }
+                }
+            }
+        }
+
+    };
+
+};
+
+},{}],146:[function(require,module,exports){
+/**
+ * @fileoverview Rule to enforce var declarations are only at the top of a function.
+ * @author Danny Fritz
+ * @author Gyandeep Singh
+ * @copyright 2014 Danny Fritz. All rights reserved.
+ * @copyright 2014 Gyandeep Singh. All rights reserved.
+ */
+&quot;use strict&quot;;
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function (context) {
+    var errorMessage = &quot;All \&quot;var\&quot; declarations must be at the top of the function scope.&quot;;
+
+    //--------------------------------------------------------------------------
+    // Helpers
+    //--------------------------------------------------------------------------
+
+    /**
+     * @param {ASTNode} node - any node
+     * @returns {Boolean} whether the given node structurally represents a directive
+     */
+    function looksLikeDirective(node) {
+       return node.type === &quot;ExpressionStatement&quot; &amp;&amp;
+           node.expression.type === &quot;Literal&quot; &amp;&amp; typeof node.expression.value === &quot;string&quot;;
+    }
+
+    /**
+     * Checks whether this variable is on top of the block body
+     * @param {ASTNode} node - The node to check
+     * @param {ASTNode[]} statements - collection of ASTNodes for the parent node block
+     * @returns {Boolean} True if var is on top otherwise false
+     */
+    function isVarOnTop (node, statements) {
+        var i = 0, l = statements.length;
+
+        // skip over directives
+        for (; i &lt; l; ++i) {
+            if (!looksLikeDirective(statements[i])) {
+                break;
+            }
+        }
+
+        for (; i &lt; l; ++i) {
+            if (statements[i].type !== &quot;VariableDeclaration&quot;) {
+                return false;
+            }
+            if (statements[i] === node) {
+                return true;
+            }
+        }
+    }
+
+    /**
+     * Checks whether variable is on top at the global level
+     * @param {ASTNode} node - The node to check
+     * @param {ASTNode} parent - Parent of the node
+     * @returns {void}
+     */
+    function globalVarCheck (node, parent) {
+        if (!isVarOnTop(node, parent.body)) {
+            context.report(node, errorMessage);
+        }
+    }
+
+    /**
+     * Checks whether variable is on top at functional block scope level
+     * @param {ASTNode} node - The node to check
+     * @param {ASTNode} parent - Parent of the node
+     * @param {ASTNode} grandParent - Parent of the node's parent
+     * @returns {void}
+     */
+    function blockScopeVarCheck (node, parent, grandParent) {
+        if (!((grandParent.type === &quot;FunctionDeclaration&quot;
+            || grandParent.type === &quot;FunctionExpression&quot;)
+            &amp;&amp; parent.type === &quot;BlockStatement&quot;
+            &amp;&amp; isVarOnTop(node, parent.body))) {
+            context.report(node, errorMessage);
+        }
+    }
+
+    //--------------------------------------------------------------------------
+    // Public API
+    //--------------------------------------------------------------------------
+
+    return {
+        &quot;VariableDeclaration&quot;: function (node) {
+            var ancestors = context.getAncestors();
+            var parent = ancestors.pop();
+            var grandParent = ancestors.pop();
+
+            if (node.kind === &quot;var&quot;) {// check variable is `var` type and not `let` or `const`
+                if (parent.type === &quot;Program&quot;) {// That means its a global variable
+                    globalVarCheck(node, parent);
+                } else {
+                    blockScopeVarCheck(node, parent, grandParent);
+                }
+            }
+        }
+    };
+
+};
+
+},{}],147:[function(require,module,exports){
+/**
+ * @fileoverview Rule to flag when IIFE is not wrapped in parens
+ * @author Ilya Volodin
+ */
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+    &quot;use strict&quot;;
+    var style = context.options[0] || &quot;outside&quot;;
+
+    function wrapped(node) {
+        var previousToken = context.getTokenBefore(node),
+            nextToken = context.getTokenAfter(node);
+        return previousToken &amp;&amp; previousToken.value === &quot;(&quot; &amp;&amp;
+            nextToken &amp;&amp; nextToken.value === &quot;)&quot;;
+    }
+
+    return {
+
+        &quot;CallExpression&quot;: function(node) {
+            if (node.callee.type === &quot;FunctionExpression&quot;) {
+                var callExpressionWrapped = wrapped(node),
+                    functionExpressionWrapped = wrapped(node.callee);
+
+                if (!callExpressionWrapped &amp;&amp; !functionExpressionWrapped) {
+                    context.report(node, &quot;Wrap an immediate function invocation in parentheses.&quot;);
+                } else if (style === &quot;inside&quot; &amp;&amp; !functionExpressionWrapped) {
+                    context.report(node, &quot;Wrap only the function expression in parens.&quot;);
+                } else if (style === &quot;outside&quot; &amp;&amp; !callExpressionWrapped) {
+                    context.report(node, &quot;Move the invocation into the parens that contain the function.&quot;);
+                }
+            }
+        }
+    };
+
+};
+
+},{}],148:[function(require,module,exports){
+/**
+ * @fileoverview Rule to flag when regex literals are not wrapped in parens
+ * @author Matt DuVall &lt;http://www.mattduvall.com&gt;
+ */
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function(context) {
+
+    &quot;use strict&quot;;
+
+    return {
+
+        &quot;Literal&quot;: function(node) {
+            var token = context.getFirstToken(node),
+                nodeType = token.type,
+                source,
+                grandparent,
+                ancestors;
+
+            if (nodeType === &quot;RegularExpression&quot;) {
+                source = context.getTokenBefore(node);
+                ancestors = context.getAncestors();
+                grandparent = ancestors[ancestors.length - 1];
+
+                if (grandparent.type === &quot;MemberExpression&quot; &amp;&amp; grandparent.object === node &amp;&amp;
+                    (!source || source.value !== &quot;(&quot;)) {
+                    context.report(node, &quot;Wrap the regexp literal in parens to disambiguate the slash.&quot;);
+                }
+            }
+        }
+    };
+
+};
+
+},{}],149:[function(require,module,exports){
+/**
+ * @fileoverview Rule to require or disallow yoda comparisons
+ * @author Nicholas C. Zakas
+ */
+&quot;use strict&quot;;
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = function (context) {
+
+    // Default to &quot;never&quot; (!always) if no option
+
+    var always = (context.options[0] === &quot;always&quot;);
+
+    //--------------------------------------------------------------------------
+    // Helpers
+    //--------------------------------------------------------------------------
+
+    /**
+     * Determines whether an operator is a comparison operator.
+     * @param {String} operator The operator to check.
+     * @returns {Boolean} Whether or not it is a comparison operator.
+     */
+    function isComparisonOperator(operator) {
+        return (/^(==|===|!=|!==|&lt;|&gt;|&lt;=|&gt;=)$/).test(operator);
+    }
+
+    //--------------------------------------------------------------------------
+    // Public
+    //--------------------------------------------------------------------------
+
+    return {
+
+        &quot;BinaryExpression&quot;: function (node) {
+
+            if (always) {
+
+                // Comparisons must always be yoda-style: if (&quot;blue&quot; === color)
+
+                if (node.right.type === &quot;Literal&quot; &amp;&amp; isComparisonOperator(node.operator)) {
+                    context.report(node, &quot;Expected literal to be on the left side of &quot; + node.operator + &quot;.&quot;);
+                }
+
+            } else {
+
+                // Comparisons must never be yoda-style (default)
+
+                if (node.left.type === &quot;Literal&quot; &amp;&amp; isComparisonOperator(node.operator)) {
+                    context.report(node, &quot;Expected literal to be on the right side of &quot; + node.operator + &quot;.&quot;);
+                }
+
+            }
+
+        }
+
+    };
+
+};
+
+},{}],150:[function(require,module,exports){
+/**
+ * @fileoverview Common utilities.
+ */
+&quot;use strict&quot;;
+
+//------------------------------------------------------------------------------
+// Public Interface
+//------------------------------------------------------------------------------
+/**
+ * Merges two objects together and assigns the result to the initial object. Can be used for shallow cloning.
+ * @param {Object} target of the cloning operation
+ * @param {Object} source object
+ * @returns {void}
+ */
+exports.mixin = function(target, source) {
+    Object.keys(source).forEach(function(key) {
+        target[key] = source[key];
+    });
+};
+
+/**
+ * Merges two config objects. This will not only add missing keys, but will also modify values to match.
+ * @param {Object} base config object
+ * @param {Object} custom config object. Overrides in this config object will take priority over base.
+ * @returns {Object} merged config object.
+ */
+exports.mergeConfigs = function mergeConfigs(base, custom) {
+
+    Object.keys(custom).forEach(function (key) {
+        var property = custom[key];
+
+        if (key === &quot;plugins&quot;) {
+            if (!base[key]) {
+                base[key] = [];
+            }
+
+            property.forEach(function (plugin) {
+                // skip duplicates
+                if (base[key].indexOf(plugin) === -1) {
+                    base[key].push(plugin);
+                }
+            });
+            return;
+        }
+
+        if (Array.isArray(base[key]) &amp;&amp; !Array.isArray(property) &amp;&amp; typeof property === &quot;number&quot;) {
+            // assume that we are just overriding first attribute
+            base[key][0] = custom[key];
+            return;
+        }
+
+        if (typeof property === &quot;object&quot; &amp;&amp; !Array.isArray(property)) {
+            // base[key] might not exist, so be careful with recursion here
+            base[key] = mergeConfigs(base[key] || {}, custom[key]);
+        } else {
+            base[key] = custom[key];
+        }
+    });
+
+    return base;
+};
+
+},{}]},{},[9])(9)
+});
</ins><span class="cx">\ No newline at end of file
</span><span class="cx">Property changes on: trunk/Source/WebInspectorUI/UserInterface/External/ESLint/eslint.js
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="allowtabs"></a>
<div class="addfile"><h4>Added: allow-tabs</h4></div>
</div>

</body>
</html>