Full Code of gotwarlost/istanbul for AI

master d38443f6a2b4 cached
202 files
707.1 KB
192.4k tokens
227 symbols
1 requests
Download .txt
Showing preview only (758K chars total). Download the full file or copy to clipboard to get everything.
Repository: gotwarlost/istanbul
Branch: master
Commit: d38443f6a2b4
Files: 202
Total size: 707.1 KB

Directory structure:
gitextract_lf9e4zzz/

├── .gitignore
├── .jshintignore
├── .jshintrc
├── .travis.yml
├── CHANGELOG.md
├── LICENSE
├── README.md
├── coverage.json.md
├── download-escodegen-browser.sh
├── generate-pages.sh
├── ignoring-code-for-coverage.md
├── index.js
├── lib/
│   ├── assets/
│   │   ├── base.css
│   │   ├── sorter.js
│   │   └── vendor/
│   │       ├── prettify.css
│   │       └── prettify.js
│   ├── cli.js
│   ├── collector.js
│   ├── command/
│   │   ├── check-coverage.js
│   │   ├── common/
│   │   │   └── run-with-cover.js
│   │   ├── cover.js
│   │   ├── help.js
│   │   ├── index.js
│   │   ├── instrument.js
│   │   ├── report.js
│   │   └── test.js
│   ├── config.js
│   ├── hook.js
│   ├── instrumenter.js
│   ├── object-utils.js
│   ├── register-plugins.js
│   ├── report/
│   │   ├── clover.js
│   │   ├── cobertura.js
│   │   ├── common/
│   │   │   └── defaults.js
│   │   ├── html.js
│   │   ├── index.js
│   │   ├── json-summary.js
│   │   ├── json.js
│   │   ├── lcov.js
│   │   ├── lcovonly.js
│   │   ├── none.js
│   │   ├── teamcity.js
│   │   ├── templates/
│   │   │   ├── foot.txt
│   │   │   └── head.txt
│   │   ├── text-lcov.js
│   │   ├── text-summary.js
│   │   └── text.js
│   ├── reporter.js
│   ├── store/
│   │   ├── fslookup.js
│   │   ├── index.js
│   │   ├── memory.js
│   │   └── tmp.js
│   └── util/
│       ├── factory.js
│       ├── file-matcher.js
│       ├── file-writer.js
│       ├── help-formatter.js
│       ├── input-error.js
│       ├── insertion-text.js
│       ├── meta.js
│       ├── tree-summarizer.js
│       ├── writer.js
│       └── yui-load-hook.js
├── misc/
│   ├── ast/
│   │   ├── assign.js
│   │   ├── block-label.js
│   │   ├── cond.js
│   │   ├── defun-compact.js
│   │   ├── defun.js
│   │   ├── do-statement.js
│   │   ├── dot.js
│   │   ├── eq.js
│   │   ├── expr.js
│   │   ├── for-block.js
│   │   ├── for-compact.js
│   │   ├── for-multi.js
│   │   ├── for-statement.js
│   │   ├── forin-block.js
│   │   ├── forin-compact.js
│   │   ├── forin-statement.js
│   │   ├── func.js
│   │   ├── if-block.js
│   │   ├── if-compact.js
│   │   ├── if-only.js
│   │   ├── if-statement.js
│   │   ├── incr-slice.js
│   │   ├── label.js
│   │   ├── nested-if.js
│   │   ├── pfcall.js
│   │   ├── preamble.js
│   │   ├── switch-statement.js
│   │   ├── try-block.js
│   │   ├── try-statement.js
│   │   ├── while-block.js
│   │   ├── while-compact.js
│   │   ├── while-for.js
│   │   └── while-statement.js
│   ├── config/
│   │   ├── istanbul-config-alt.json
│   │   └── istanbul-config.json
│   └── samples/
│       └── coverage.js
├── package.json
├── test/
│   ├── browser/
│   │   ├── support/
│   │   │   ├── index.html
│   │   │   ├── phantom-test.client.js
│   │   │   ├── server.js
│   │   │   └── vendor/
│   │   │       └── yui-support.js
│   │   └── test-browser-instrumentation.js
│   ├── cli/
│   │   ├── package.json
│   │   ├── sample-project/
│   │   │   ├── .gitignore
│   │   │   ├── amd/
│   │   │   │   ├── ipsum.js
│   │   │   │   └── lorem.js
│   │   │   ├── config-check-each.istanbul.yml
│   │   │   ├── config-check-global.istanbul.yml
│   │   │   ├── config-check-mixed.istanbul.yml
│   │   │   ├── config.istanbul.yml
│   │   │   ├── includeAllSources/
│   │   │   │   ├── unloadedFile.js
│   │   │   │   └── unloadedFileWithFunctionDeclaration.js
│   │   │   ├── lib/
│   │   │   │   ├── bar.js
│   │   │   │   ├── foo.js
│   │   │   │   └── util/
│   │   │   │       ├── bad.js
│   │   │   │       ├── es-module.js
│   │   │   │       ├── generate-names.js
│   │   │   │       └── unused.js
│   │   │   ├── test/
│   │   │   │   ├── amd-run.js
│   │   │   │   ├── global-leak.js
│   │   │   │   └── run.js
│   │   │   └── vendor/
│   │   │       └── dummy_vendor_lib.js
│   │   ├── test-base-cli.js
│   │   ├── test-check-coverage-command.js
│   │   ├── test-clover-report.js
│   │   ├── test-cobertura-report.js
│   │   ├── test-cover-command.js
│   │   ├── test-html-report.js
│   │   ├── test-include-pid.js
│   │   ├── test-instrument-command.js
│   │   ├── test-json-report.js
│   │   ├── test-json-summary-report.js
│   │   ├── test-lcov-report.js
│   │   ├── test-lcovonly-report.js
│   │   ├── test-lots-of-files.js
│   │   ├── test-none-report.js
│   │   ├── test-report-command.js
│   │   ├── test-teamcity-report.js
│   │   ├── test-test-command.js
│   │   └── test-text-lcov-report.js
│   ├── cli-helper.js
│   ├── common.js
│   ├── es6.js
│   ├── helper.js
│   ├── instrumentation/
│   │   ├── test-do.js
│   │   ├── test-es6-arrow-fn.js
│   │   ├── test-es6-export.js
│   │   ├── test-es6-forof.js
│   │   ├── test-es6-import.js
│   │   ├── test-es6-super.js
│   │   ├── test-es6-yield.js
│   │   ├── test-expressions.js
│   │   ├── test-for.js
│   │   ├── test-forin.js
│   │   ├── test-functions.js
│   │   ├── test-if-with-hints.js
│   │   ├── test-if.js
│   │   ├── test-locations.js
│   │   ├── test-misc.js
│   │   ├── test-statement-with-hints.js
│   │   ├── test-statement.js
│   │   ├── test-strict.js
│   │   ├── test-switch.js
│   │   ├── test-try.js
│   │   ├── test-while.js
│   │   └── test-with.js
│   ├── loader.js
│   ├── other/
│   │   ├── config-data/
│   │   │   ├── .istanbul.yml
│   │   │   └── cfg.json
│   │   ├── data/
│   │   │   ├── bar.es6
│   │   │   ├── baz.js
│   │   │   ├── foo.js
│   │   │   └── matcher/
│   │   │       ├── .gitignore
│   │   │       ├── general/
│   │   │       │   ├── .gitignore
│   │   │       │   └── general.js
│   │   │       ├── lib/
│   │   │       │   └── lib-top.js
│   │   │       └── top.js
│   │   ├── data-complete-copy/
│   │   │   ├── baz.js
│   │   │   ├── fixture.xml
│   │   │   ├── foo.js
│   │   │   ├── myfile1
│   │   │   ├── myfile2
│   │   │   └── subdir/
│   │   │       └── x.css
│   │   ├── test-collector.js
│   │   ├── test-command-xface.js
│   │   ├── test-config.js
│   │   ├── test-file-writer.js
│   │   ├── test-help-formatter.js
│   │   ├── test-hook.js
│   │   ├── test-index-xface.js
│   │   ├── test-input-error.js
│   │   ├── test-insertion-text.js
│   │   ├── test-matcher.js
│   │   ├── test-object-utils.js
│   │   ├── test-store.js
│   │   └── test-summarizer.js
│   ├── run-again.js
│   └── run.js
├── yui-coverage-comparison.md
└── yuidoc.json

================================================
FILE CONTENTS
================================================

================================================
FILE: .gitignore
================================================
lib-cov
.DS_Store
*.seed
*.log
*.csv
*.dat
*.out
*.pid
*.gz

pids
logs
results

node_modules/
bower_components/
.idea/
html-report/
build/
public/
test/other/output/
test/cli/output/

npm-debug.log


================================================
FILE: .jshintignore
================================================
lib/assets/vendor
test/cli/sample-project
test/cli/sample-project-link
test/browser/support/vendor




================================================
FILE: .jshintrc
================================================
{
    "bitwise": true,
    "camelcase": false,
    "curly": true,
    "eqeqeq": true,
    "forin": true,
    "freeze": true,
    "immed": true,
    "latedef": true,
    "maxlen": 150,
    "newcap": true,
    "noarg": true,
    "nonbsp": true,
    "nonew": true,
    "plusplus": true,
    "trailing": true,
    "undef": true,
    "unused": true,

    "strict": false,

    "asi": false,
    "boss": false,
    "debug": false,
    "eqnull": false,
    "esnext": false,
    "evil": false,
    "expr": false,
    "funcscope": false,
    "globalstrict": false,
    "iterator": false,
    "lastsemic": false,
    "laxbreak": true,
    "laxcomma": false,
    "loopfunc": false,
    "multistr": false,
    "notypeof": false,
    "proto": false,
    "scripturl": false,
    "smarttabs": false,
    "shadow": false,
    "sub": false,
    "supernew": false,
    "validthis": false,
    "noyield": false,

    "browser": true,
    "node": true,

    "nomen": false,
    "onevar": true,
    "passfail": false,
    "white": false
}


================================================
FILE: .travis.yml
================================================
language: node_js

node_js:
  - "0.10"
  - "0.12"

sudo: false

branches:
  except:
    - gh-pages

script:
  - npm test --cover

after_script:
  - if [[ `node --version` == *v0.12* ]]; then cat ./build/coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js; fi


================================================
FILE: CHANGELOG.md
================================================
Changelog
---------

<table>
<tr>
<td>0.4.5</td>
<td>
    <ul>
        <li>log filename when file fails to parse using esprima, thanks to @djorg83</li>
        <li>swap fileset for glob (security fix), thanks to @popomore and @graingert</li>
    </ul>
</td>
</tr>
<tr>
<td>0.4.4</td>
<td>
    <ul>
        <li>Handle ExportNamedDeclaration, thanks to @VictoryStick</li>
        <li>Use tmpdir setting in temp store, thanks to @inversion</li>
        <li>Set "medium" coverage CSS color scheme to yellow, thanks to @JamesMGreene</li>
        <li>use os.tmpdir() instead of os.tmpDir(), thanks to @ChALkeR</li>
    </ul>
</td>
</tr>
<tr>
<td>0.4.3</td>
<td>
    <ul>
        <li>Create new handlebars instance for the HTML report, thanks to @doowb</li>
        <li>MetaProperty support thanks to @steve-gray</li>
        <li>Use ansi colors from 16-color palette for better console support, thanks to @jtangelder</li>
        <li>Misc doc/ css fixes thanks to @pra85, @abejfehr</li>
    </ul>
</td>
</tr>
<tr>
<td>0.4.2</td>
<td>Fix confusing error message on check-coverage failures, thanks to @isaacs/td>
</tr>
<tr>
<td>v0.4.1</td>
<td>
    <ul>
        <li>Update esprima to 2.7.x, thanks to @ariya</li>
        <li>Make table header clickable in HTML report, thanks to @iphands</li>
        <li>Fix strict mode issues thanks to @kpdecker</li>
        <li>update ignore code example for UMD, thanks to @pgurnee</li>
        <li>misc build fixes, no user visible changes, thanks to @ariya</li>
    </ul>
</td>
</tr>
<tr>
<td>v0.4.0</td>
<td>
    <ul>
        <li>HTML report design, thanks a bunch to @tmcw</li>
        <li>"loading config file" message on the console is now tied to the verbose state, thanks @asa-git</li>
        <li>Add the `l` property to documentation, thanks @kitsonk</li>

    </ul>
</td>
</tr>
<tr>
<td>v0.3.21</td>
<td>
    <ul>
        <li>Updated dependencies to the latest</li>
    </ul>
</td>
</tr>
<tr>
<td>v0.3.20</td>
<td>
    <ul>
        <li>Fix broken es6 `super` support, thanks @sterlinghw</li>
        <li>Improve readability via better lineHeight, thanks @dhoko</li>
        <li>Adding ability to set custom block name in teamcity report, thanks @aryelu</li>
        <li>Replaced deprecated util.puts with console.log, thanks @arty-name
    </ul>
</td>
</tr>
<tr>
<td>v0.3.19</td>
<td>Fix instrumenter for multiple blank array positions, thanks @alexdunphy</td>
</tr>
<tr>
<tr>
<td>v0.3.18</td>
<td>Upgrade esprima, get support for more ES6 features</td>
</tr>
<tr>
<td>v0.3.17</td>
<td>Upgrade esprima, get correct for-of support</td>
</tr>
<tr>
<td>v0.3.16</td>
<td>
    <ul>
        <li>upgrades to filset and async modules, thanks to @roderickhsiao, @popomore</li>
        <li>updated text reporter so that it displays a list of the lines missing coverage, thanks @bcoe</li>
    </ul>
</td>
</tr>
<tr>
<td>v0.3.15</td>
<td>
    <ul>
        <li>Fix #375: add nodir option to exclude directory for *.js matcher thanks to @yurenju</li>
        <li>Fix #362: When setting up the `reportDir` add it to `reporter.dir`</li>
        <li>Fixes #238 (added a poorman's clone)</li>
        <li>Incrementing hits on ignored statements implemented</li>
        <li>`a:visited color: #777` (a nice gray color)</li>
    </ul>
</td>
</tr>
<tr>
<td>v0.3.14</td>
<td>
    Add text-lcov report format to emit lcov to console, thanks to @bcoe
</td>
</tr>
<tr>
<td>v0.3.13</td>
<td>
    Fix #339
</td>
</tr>
<tr>
<td>v0.3.12</td>
<td>
    Allow other-than-dot-js files to be hooked, thanks to @sethpollack
</td>
</tr>
<tr>
<td>v0.3.11</td>
<td>
    Avoid modification of global objects, thanks to @dominykas
</td>
</tr>
<tr>
<td>v0.3.10</td>
<td>
    Update escodegen to 1.6.x and add browser download script
</td>
</tr>
<tr>
<td>v0.3.9</td>
<td>
    <ul>
        <li>Merge harmony branch and start adding ES6 features to istanbul</li>
        <li>Arrow functions are the only feature of interest now</li>
        <li>`for-of` and `yield` support exist but not present in mainline esprima yet</li>
    </ul>
</td>
</tr>
<tr>
<td>v0.3.8</td>
<td>
    <ul>
        <li>Fail check coverage command when no coverage files found, thanks to @nexus-uw</li>
        <li>handle relative paths in check-coverage, thanks to @dragn</li>
        <li>support explicit includes for cover, thanks to @tonylukasavage</li>
    </ul>
</td>
</tr>
<tr>
<td>v0.3.7</td>
<td>
    Fix asset paths on windows, thanks to @juangabreil
</td>
</tr>
<tr>
<td>v0.3.6</td>
<td>
    <ul>
        <li>Update to Esprima 2.0</li>
        <li>Remove YUI dependency and provide custom sort code. No network access needed for HTML report view</li>
        <li>use supports-color module to colorize output, thanks to @gustavnikolaj</li>
        <li>Fix tests to work on Windows, thanks to @dougwilson</li>
        <li>Docs: "Instrument code" API example correction thanks to @robatron</li>
        <li>Extracted embedded CSS and JavaScript and made them external files, thanks to @booleangate</td>
    </ul>
</td>
</tr>
<tr>
<td>v0.3.5</td>
<td>
<p>Merge #275 - `--include-all-sources` option. Thanks @gustavnikolaj</p>
<p>
The `--preload-sources` option is now deprecated and superseded by the
`--include-all-sources` option instead. This provides a better coverage representation
of the code that has not been included for testing.
</p>
</td>
</tr>
<tr>
<td>v0.3.4</td>
<td>Merge #219 - Support reporting within symlink/junction. Thanks to @dougwilson</td>
</tr>
<tr>
<td>v0.3.3</td>
<td>Merge #268 - per file coverage enforcement. Thanks to @ryan-roemer</td>
</tr>
<tr>
<td>v0.3.2</td>
<td>Republish 0.3.1 because of bad shasum</td>
</tr>
<tr>
<td>v0.3.1</td>
<td>Fixes #249</td>
</tr>
<tr>
<td>v0.3.0</td>
<td>
    The *reports* release. **Potentially backwards-incompatible** if you are using
    undocumented features or custom report implementations.
    <ul>
        <li>Change report command line to support multiple reports, add back-compat processing with warnings</li>
        <li>Enable `report` command to read report list from config, thanks to @piuccio</li>
        <li>Support multiple reports for `cover` and `report` commands</li>
        <li>Support per-report config options in configuration file</li>
        <li>Turn reports into event emitters so they can signal `done`</li>
        <li>Add `Reporter` class to be able to generate multiple reports</li>
        <li>Add a bunch of API docs, refactor README</li>
    </ul>
</td>
</tr>
<tr>
<td>v0.2.16</td><td>Make YUI links https-always since relative links break local
filesystem use-case
</td>
</tr>
<tr>
<td>v0.2.15</td><td>make link protocols relative so they don't break on https connections
(thanks to @yasyf)
</td>
</tr>
<tr>
<td>v0.2.14</td><td>Fix hook to deal with non-string/ missing filenames
(thanks to @jason0x43), update dependencies
</td>
</tr>
<tr>
<td>v0.2.13</td><td>Add `--preload-sources` option to `cover` command to make
code not required by tests to appear in the coverage report.
</td>
</tr>
<tr>
<td>v0.2.12</td><td>Text summary as valid markdown, thanks to @smikes</td>
</tr>
<tr>
<td>v0.2.11</td><td>Allow source map generation, thanks to @jason0x43</td>
</tr>
<tr>
<td>v0.2.10</td><td>Add flag to handle sigints and dump coverage, thanks to @samccone</td>
</tr>
<tr>
<td>v0.2.9</td><td>Fix #202</td>
</tr>
<tr>
<tr>
<td>v0.2.8</td><td>Upgrade esprima</td>
</tr>
<tr>
<td>v0.2.7</td><td><ul>
    <li>Upgrade esprima</li>
    <li>Misc jshint fixes</li>
</ul></td>
</tr>
<tr>
<td>v0.2.6</td><td><ul>
    <li>Revert bad commit for tree summarizer</li>
</ul></td>
</tr>
<tr>
<td>v0.2.5</td><td><ul>
    <li>Add clover report, thanks to @bixdeng, @mpderbec</li>
    <li>Fix cobertura report bug for relative paths, thanks to @jxiaodev</li>
    <li>Run self-coverage on tests always</li>
    <li>Fix tree summarizer when relative paths are involved, thanks to @Swatinem</li>
</ul></td>
</tr>
<tr>
<td>v0.2.4</td><td><ul>
    <li>Fix line-split algo to handle Mac lin separators, thanks to @asifrc</li>
    <li>Update README for quick intro to ignoring code for coverage, thanks to @gergelyke</li>
</ul></td>
</tr>
<tr>
<td>v0.2.3</td><td><ul>
    <li>Add YAML config file. `istanbul help config` has more details</li>
    <li>Support custom reporting thresholds using the `watermarks` section of the config file</li>
</ul></td>
</tr>
<tr><td>v0.2.2</td><td>update escodegen, handlebars and resolve dependency versions</td></tr>
<tr>
<td>v0.2.1</td><td><ul>
    <li>Add ability to skip branches and other hard-to-test code using comments.
        See <a href="https://github.com/gotwarlost/istanbul/blob/master/ignoring-code-for-coverage.md">the doc</a> for more details</li>
    <li>Turn `util.error` into `console.error` for node 0.11 compatibility, thanks to @pornel</li>
</ul></td>
</tr>
<tr><td>v0.2.0</td><td><ul>
    <li>Add --preserve-comments to instrumenter options, thanks to @arikon</li>
    <li>Support 'use strict;' in file scope, thanks to @pornel</li>
</ul>
    Up minor version due to the new way in which the global object is accessed.
    This _should_ be backwards-compatible but has not been tested in the wild.
</td></tr>
<tr><td>v0.1.46</td><td>Fix #114</td></tr>
<tr><td>v0.1.45</td><td>Add teamcity reporter, thanks to @chrisgladd</td></tr>
<tr><td>v0.1.44</td><td>Fix inconsistency in processing empty switch with latest esprima, up deps</td></tr>
<tr><td>v0.1.43</td><td>Add colors to text report thanks to @runk</td></tr>
<tr><td>v0.1.42</td><td>fix #78: embed source regression introduced in v0.1.38. Fix broken test for this</td></tr>
<tr><td>v0.1.41</td><td>add json report to dump coverage object for certain use cases</td></tr>
<tr><td>v0.1.40</td><td>forward sourceStore from lcov to html report, pull request by @vojtajina</td></tr>
<tr><td>v0.1.39</td><td>add <source> tag to cobertura report, pull request by @jhansche</td></tr>
<tr><td>v0.1.38</td><td><ul>
        <li>factor out AST instrumentation into own instrumentASTSync method</li>
        <li>always set function declaration coverage stats to 1 since every such declaration is "executed" exactly one time by the compiler</li>
    </ul></td></tr>
<tr><td>v0.1.37</td><td>--complete-copy flag contrib from @kami, correct strict mode semantics for instrumented functions</td></tr>
<tr><td>v0.1.36</td><td>real quiet when --print=none specified, add repo URL to package.json, add contributors</td></tr>
<tr><td>v0.1.35</td><td>accept cobertura contrib from @nbrownus, fix #52</td></tr>
<tr><td>v0.1.34</td><td>fix async reporting, update dependencies, accept html cleanup contrib from @mathiasbynens</td></tr>
<tr><td>v0.1.33</td><td>initialize global coverage object before running tests to workaround mocha leak detection</td></tr>
<tr><td>v0.1.32</td><td>Fix for null nodes in array expressions, add @unindented as contributor</td></tr>
<tr><td>v0.1.31</td><td>Misc internal fixes and test changes</td></tr>
<tr><td>v0.1.30</td><td>Write standard blurbs ("writing coverage object..." etc.) to stderr rather than stdout</td></tr>
<tr><td>v0.1.29</td><td>Allow --post-require-hook to be a module that can be `require`-d</td></tr>
<tr><td>v0.1.28</td><td>Add --post-require-hook switch to support use-cases similar to the YUI loader</td></tr>
<tr><td>v0.1.27</td><td>Add --hook-run-in-context switch to support RequireJS modules. Thanks to @millermedeiros for the pull request</td></tr>
<tr><td>v0.1.26</td><td>Add support for minimum uncovered unit for check-coverage. Fixes #25</td></tr>
<tr><td>v0.1.25</td><td>Allow for relative paths in the YUI loader hook</td></tr>
<tr><td>v0.1.24</td><td>Add lcov summaries. Fixes issue #20</td></tr>
<tr><td>v0.1.23</td><td>Add ability to save a baseline coverage file for the instrument command. Fixes issue #19</td></tr>
<tr><td>v0.1.22</td><td>Add signature attribute to cobertura method tags to fix NPE by the Hudson publisher</td></tr>
<tr><td>v0.1.21</td><td>Add cobertura XML report format; exprimental for now</td></tr>
<tr><td>v0.1.20</td><td>Fix HTML/ lcov report interface to be more customizable for middleware needs</td></tr>
<tr><td>v0.1.19</td><td>make all hooking non-destructive in that already loaded modules are never reloaded. Add self-test mode so that already loaded istanbul modules can be unloaded prior to hooking.</td></tr>
<tr><td>v0.1.18</td><td>Add option to hook in non-destructive mode; i.e. the require cache is not unloaded when hooking</td></tr>
<tr><td>v0.1.17</td><td>Export some more objects; undocumented for now</td></tr>
<tr><td>v0.1.16</td><td>Fix npm keywords for istanbul which expects an array of strings but was being fed a single string with keywords instead</td></tr>
<tr><td>v0.1.15</td><td>Add the 'check-coverage' command so that Istanbul can be used as a posttest script to enforce minimum coverage</td></tr>
<tr><td>v0.1.14</td><td>Expose the experimental YUI load hook in the interface</td></tr>
<tr><td>v0.1.13</td><td>Internal jshint cleanup, no features or fixes</td></tr>
<tr><td>v0.1.12</td><td>Give npm the README that was getting inadvertently excluded</td></tr>
<tr><td>v0.1.11</td><td>Merge pull request #14 for HTML tweaks. Thanks @davglass. Add @davglass and @nowamasa as contributors in `package.json`</td></tr>
<tr><td>v0.1.10</td><td>Fix to issue #12. Do not install `uncaughtException` handler and pass input error back to CLI using a callback as opposed to throwing.</td></tr>
<tr><td>v0.1.9</td><td>Attempt to create reporting directory again just before writing coverage in addition to initial creation</td></tr>
<tr><td>v0.1.8</td><td>Fix issue #11.</td></tr>
<tr><td>v0.1.7</td><td>Add text summary and detailed reporting available as --print [summary|detail|both|none]. summary is the default if nothing specified.</td></tr>
<tr><td>v0.1.6</td><td>Handle backslashes in the file path correctly in emitted code. Fixes #9. Thanks to @nowamasa for bug report and fix</td></tr>
<tr><td>v0.1.5</td><td>make object-utils.js work on a browser as-is</td></tr>
<tr><td>v0.1.4</td><td>partial fix for issue #4; add titles to missing coverage spans, remove negative margin for missing if/else indicators</td></tr>
<tr><td>v0.1.3</td><td>Set the environment variable running_under_istanbul to 1 when that is the case. This allows test runners that use istanbul as a library to back off on using it when set.</td></tr>
<tr><td>v0.1.2</td><td>HTML reporting cosmetics. Reports now show syntax-colored JS using `prettify`. Summary tables no longer wrap in awkward places.</td></tr>
<tr><td>v0.1.1</td><td>Fixes issue #1. HTML reports use sources embedded inside the file coverage objects if found rather than reading from the filesystem</td></tr>
<tr><td>v0.1.0</td><td>Initial version</td></tr>
</td></tr>
</table>



================================================
FILE: LICENSE
================================================
Copyright 2012 Yahoo! Inc.
All rights reserved.

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.
    * Neither the name of the Yahoo! Inc. nor the
      names of its contributors may be used to endorse or promote products
      derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 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 YAHOO! INC. 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.


================================================
FILE: README.md
================================================
## Istanbul - a JS code coverage tool written in JS

**Archive notice: This repo has been inactive for 7 years and is now archived. 
Please use [the supported version](https://github.com/istanbuljs) instead.**


[![Build Status](https://secure.travis-ci.org/gotwarlost/istanbul.svg?branch=master)](http://travis-ci.org/gotwarlost/istanbul)
[![Dependency Status](https://gemnasium.com/gotwarlost/istanbul.svg)](https://gemnasium.com/gotwarlost/istanbul)
[![Coverage Status](https://img.shields.io/coveralls/gotwarlost/istanbul.svg)](https://coveralls.io/r/gotwarlost/istanbul?branch=master)
[![bitHound Score](https://www.bithound.io/github/gotwarlost/istanbul/badges/score.svg)](https://www.bithound.io/github/gotwarlost/istanbul)

[![NPM](https://nodei.co/npm/istanbul.png?downloads=true)](https://nodei.co/npm/istanbul/)

> *Deprecation Notice:* this version of _istanbul_ is deprecated, we will not be
  landing pull requests or releasing new versions. But don't worry, the [Istanbul 2.0
  API is now available](https://istanbul.js.org/) and is being actively developed
  in the new [istanbuljs organization](https://github.com/istanbuljs).

**New** `v0.4.0` now has beautiful HTML reports. Props to Tom MacWright @tmcw for a fantastic job!

* [Features and use cases](#features)
* [Getting started and configuration](#getting-started)
* [Usage on Windows](#usage-on-windows)
* [The command line](#the-command-line)
* [Ignoring code for coverage](#ignoring-code-for-coverage)
* [API](#api)
* [Changelog](https://github.com/gotwarlost/istanbul/blob/master/CHANGELOG.md)
* [License and credits](#license)

### Features

* All-javascript instrumentation library that tracks **statement, branch,
and function coverage**.
* **Module loader hooks** to instrument code on the fly
* **Command line tools** to run node unit tests "with coverage turned on" and no cooperation
whatsoever from the test runner
* Multiple report formats: **HTML**, **LCOV**, **Cobertura** and more.
* Ability to use as [middleware](https://github.com/gotwarlost/istanbul-middleware) when serving JS files that need to be tested on the browser.
* Can be used on the **command line** as well as a **library**
* Based on the awesome `esprima` parser and the equally awesome `escodegen` code generator
* Well-tested on node (prev, current and next versions) and the browser (instrumentation library only)

### Use cases

Supports the following use cases and more

* transparent coverage of nodejs unit tests
* instrumentation/ reporting of files in batch mode for browser tests
* Server side code coverage for nodejs by embedding it as [custom middleware](https://github.com/gotwarlost/istanbul-middleware)

### Getting started

    $ npm install -g istanbul

The best way to see it in action is to run node unit tests. Say you have a test
script `test.js` that runs all tests for your node project without coverage.

Simply:

    $ cd /path/to/your/source/root
    $ istanbul cover test.js

and this should produce a `coverage.json`, `lcov.info` and `lcov-report/*html` under `./coverage`

Sample of code coverage reports produced by this tool (for this tool!):

[HTML reports](http://gotwarlost.github.com/istanbul/public/coverage/lcov-report/index.html)

### Usage on Windows

Istanbul assumes that the `command` passed to it is a JS file (e.g. Jasmine, vows etc.),
this is however not true on Windows where npm wrap bin files in a `.cmd` file.
Since Istanbul can not parse `.cmd` files you need to reference the bin file manually.

Here is an example using Jasmine 2:

    istanbul cover node_modules\jasmine\bin\jasmine.js

In order to use this cross platform (e.i. Linux, Mac and Windows), you can insert
the above line into the script object in your package.json file but with normal
slash.

    "scripts": {
        "test": "istanbul cover node_modules/jasmine/bin/jasmine.js"
    }

### Configuring

Drop a `.istanbul.yml` file at the top of the source tree to configure istanbul.
`istanbul help config` tells you more about the config file format.

### The command line

    $ istanbul help

gives you detailed help on all commands.

```
Usage: istanbul help config | <command>

`config` provides help with istanbul configuration

Available commands are:

      check-coverage
              checks overall/per-file coverage against thresholds from coverage
              JSON files. Exits 1 if thresholds are not met, 0 otherwise


      cover   transparently adds coverage information to a node command. Saves
              coverage.json and reports at the end of execution


      help    shows help


      instrument
              instruments a file or a directory tree and writes the
              instrumented code to the desired output location


      report  writes reports for coverage JSON objects produced in a previous
              run


      test    cover a node command only when npm_config_coverage is set. Use in
              an `npm test` script for conditional coverage


Command names can be abbreviated as long as the abbreviation is unambiguous
```

To get detailed help for a command and what command-line options it supports, run:

    istanbul help <command>

(Most of the command line options are not covered in this document.)

#### The `cover` command

    $ istanbul cover my-test-script.js -- my test args
    # note the -- between the command name and the arguments to be passed

The `cover` command can be used to get a coverage object and reports for any arbitrary
node script. By default, coverage information is written under `./coverage` - this
can be changed using command-line options.

The `cover` command can also be passed an optional `--handle-sigint` flag to
enable writing reports when a user triggers a manual SIGINT of the process that is
being covered. This can be useful when you are generating coverage for a long lived process.

#### The `test` command

The `test` command has almost the same behavior as the `cover` command, except that
it skips coverage unless the `npm_config_coverage` environment variable is set.

**This command is deprecated** since the latest versions of npm do not seem to
set the `npm_config_coverage` variable.

#### The `instrument` command

Instruments a single JS file or an entire directory tree and produces an output
directory tree with instrumented code. This should not be required for running node
unit tests but is useful for tests to be run on the browser.

#### The `report` command

Writes reports using `coverage*.json` files as the source of coverage information.
Reports are available in multiple formats and can be individually configured
using the istanbul config file. See `istanbul help report` for more details.

#### The `check-coverage` command

Checks the coverage of statements, functions, branches, and lines against the
provided thresholds. Positive thresholds are taken to be the minimum percentage
required and negative numbers are taken to be the number of uncovered entities
allowed.

### Ignoring code for coverage

* Skip an `if` or `else` path with `/* istanbul ignore if */` or `/* istanbul ignore else */` respectively.
* For all other cases, skip the next 'thing' in the source with: `/* istanbul ignore next */`

See [ignoring-code-for-coverage.md](ignoring-code-for-coverage.md) for the spec.


### API

All the features of istanbul can be accessed as a library.

#### Instrument code

```javascript
    var istanbul = require('istanbul');
    var instrumenter = new istanbul.Instrumenter();

    var generatedCode = instrumenter.instrumentSync('function meaningOfLife() { return 42; }',
        'filename.js');
```

#### Generate reports given a bunch of coverage JSON objects

```javascript
    var istanbul = require('istanbul'),
        collector = new istanbul.Collector(),
        reporter = new istanbul.Reporter(),
        sync = false;

    collector.add(obj1);
    collector.add(obj2); //etc.

    reporter.add('text');
    reporter.addAll([ 'lcov', 'clover' ]);
    reporter.write(collector, sync, function () {
        console.log('All reports generated');
    });
```

For the gory details consult the [public API](http://gotwarlost.github.com/istanbul/public/apidocs/index.html)


### Multiple Process Usage

Istanbul can be used in a multiple process environment by running each process
with Istanbul, writing a unique coverage file for each process, and combining
the results when generating reports. The method used to perform this will
depend on the process forking API used. For example when using the
[cluster module](http://nodejs.org/api/cluster.html) you must setup the master
to start child processes with Istanbul coverage, disable reporting, and output
coverage files that include the PID in the filename.  Before each run you may
need to clear out the coverage data directory.

```javascript
    if(cluster.isMaster) {
        // setup cluster if running with istanbul coverage
        if(process.env.running_under_istanbul) {
            // use coverage for forked process
            // disabled reporting and output for child process
            // enable pid in child process coverage filename
            cluster.setupMaster({
                exec: './node_modules/.bin/istanbul',
                args: [
                    'cover', '--report', 'none', '--print', 'none', '--include-pid',
                    process.argv[1], '--'].concat(process.argv.slice(2))
            });
        }
        // ...
        // ... cluster.fork();
        // ...
    } else {
        // ... worker code
    }
```

### Coverage.json

For details on the format of the coverage.json object, [see here](./coverage.json.md).

### License

istanbul is licensed under the [BSD License](http://github.com/gotwarlost/istanbul/raw/master/LICENSE).

### Third-party libraries

The following third-party libraries are used by this module:

* abbrev: https://github.com/isaacs/abbrev-js -  to handle command abbreviations
* async: https://github.com/caolan/async - for parallel instrumentation of files
* escodegen: https://github.com/Constellation/escodegen - for JS code generation
* esprima: https://github.com/ariya/esprima - for JS parsing
* glob: https://github.com/isaacs/node-glob - for loading and matching path expressions
* handlebars: https://github.com/wycats/handlebars.js/ - for report template expansion
* js-yaml: https://github.com/nodeca/js-yaml - for YAML config file load
* mkdirp: https://github.com/substack/node-mkdirp - to create output directories
* nodeunit: https://github.com/caolan/nodeunit - dev dependency for unit tests
* nopt: https://github.com/isaacs/nopt - for option parsing
* once: https://github.com/isaacs/once - to ensure callbacks are called once
* resolve: https://github.com/substack/node-resolve - for resolving a post-require hook module name into its main file.
* rimraf - https://github.com/isaacs/rimraf - dev dependency for unit tests
* which: https://github.com/isaacs/node-which - to resolve a node command to a file for the `cover` command
* wordwrap: https://github.com/substack/node-wordwrap - for prettier help
* prettify: http://code.google.com/p/google-code-prettify/ - for syntax colored HTML reports. Files checked in under `lib/vendor/`

### Inspired by

* YUI test coverage - https://github.com/yui/yuitest - the grand-daddy of JS coverage tools. Istanbul has been specifically designed to offer an alternative to this library with an easy migration path.
* cover: https://github.com/itay/node-cover - the inspiration for the `cover` command, modeled after the `run` command in that tool. The coverage methodology used by istanbul is quite different, however

### Shout out to

   * [mfncooper](https://github.com/mfncooper) - for great brainstorming discussions
   * [reid](https://github.com/reid), [davglass](https://github.com/davglass), the YUI dudes, for interesting conversations, encouragement, support and gentle pressure to get it done :)

### Why the funky name?

Since all the good ones are taken. Comes from the loose association of ideas across
coverage, carpet-area coverage, the country that makes good carpets and so on...


================================================
FILE: coverage.json.md
================================================
# Format of coverage.json

`coverage.json` contains a report object, which is a hash where keys are file names (absolute
paths), and values are coverage data for that file (the result of
`json.stringify(collector.fileCoverageFor(filename))`)  Each entry consists of:

* `path` - The path to the file.  This is an absolute path, and should be the same as the
  key in the report object.
* `s` - Hash of statement counts, where keys as statement IDs.
* `b` - Hash of branch counts, where keys are branch IDs and values are arrays of counts.
  For an if statement, the value would have two counts; one for the if, and one for the
  else.  Switch statements would have an array of values for each case.
* `f` - Hash of function counts, where keys are function IDs.
* `fnMap` - Hash of functions where keys are function IDs, and values are `{name, line, loc, skip}`,
  where `name` is the name of the function, `line` is the line the function is declared on,
  and `loc` is the `Location` of the function declaration (just the declaration, not the entire
  function body - see 'Location Objects' below.)  If `skip` is present and true, then this
  indicates that this function was ignored by a `### instabul ignore ... ###` pragma.  Note that
  if a function is not ignored the `skip` field will be missing entirely.
* `statementMap` - Hash where keys are statement IDs, and values are `Location` objects for each
  statement.  The `Location` for a function definition is really an assignment, and should
  include the entire function.  In addition to the normal location object fields, a
  `statementMap` entry can also have an optional `skip` field.
* `branchMap` - Hash where keys are branch IDs, and values are `{line, type, locations}` objects.
  `line` is the line the branch starts on.  `type` is the type of the branch (e.g. "if", "switch").
  `locations` is an array of `Location` objects, one for each possible outcome of the branch.
  Note for an `if` statement where there is no `else` clause, there will still be two `locations`
  generated.  Istanbul does *not* generate coverage for the `default` case of a switch statement
  if `default` is not explicitly present in the source code.
* `l` - Hash of line counts, where keys are the line number.

  `locations` for an if statement are always 0-length and located at the start of the `if` (even
  the location for the "else").  For a `switch` statement, `locations` start at the start of the
  `case` statement and go to the end of the line before the next case statement (note Istanbul
  does nothing clever here if a `case` is missing a `break`.)  Each location in `locations` can
  also optionally have a `skip: true` field to indicate that this branch was ignored.

IDs used in the fnMap, statementMap, and branchMap are sequential integers, starting at 1.

## Location Objects

Location objects are a `{start: {line, column}, end: {line, column}}` object that describes
the start and end of a piece of code.  Note that `line` is 1-based, but `column` is 0-based.


================================================
FILE: download-escodegen-browser.sh
================================================
#!/bin/sh

ESCG_DIR=node_modules/escodegen
ESCG_VERSION=`grep '"version"' ${ESCG_DIR}/package.json  | awk '{print $2}' | sed 's/[",]//g'`
OUT_FILE=${ESCG_DIR}/escodegen.browser.min.js
if [ ! -f ${OUT_FILE} ]
then
    set -v
    rm -rf __escodegen_clone__
    git clone --branch ${ESCG_VERSION} https://github.com/estools/escodegen.git __escodegen_clone__
    cd __escodegen_clone__

    # Temporarily ignore missing package, see #489
    perl -i -ne '/esprima\-moz/ or print' package.json

    npm i && npm run build-min
    mv escodegen.browser.min.js ../${OUT_FILE}
    cd -
    rm -rf __escodegen_clone__
fi



================================================
FILE: generate-pages.sh
================================================
set -ex
export PAGES_DIR=../istanbul-pages
npm test --coverage
mkdir -p public/apidocs
yuidoc .
rsync -rvt ./public/apidocs/ ${PAGES_DIR}/public/apidocs/
rsync -rvt ./build/coverage/ ${PAGES_DIR}/public/coverage



================================================
FILE: ignoring-code-for-coverage.md
================================================
## Ignoring code for coverage purposes

Some branches in JS code are typically hard, if not impossible to test.

Examples are a `hasOwnProperty` check, [UMD wrappers](https://github.com/umdjs/umd) and so on. Istanbul now has a
facility by which coverage can be excluded for certain sections of code.

### The interface

1. Coverage can be explicitly skipped using comments. There is no automatic pattern match of expressions to determine
if they should be skipped for coverage.
2. A coverage skip hint looks like `/* istanbul ignore <word>[non-word] [optional-docs] */`
3. For `if` conditions you can say `/* istanbul ignore if */` or `/* istanbul ignore else */` and that will end up
ignoring whichever path was required to be ignored.
4. For all other cases, the Swiss army knife `/* istanbul ignore next */` may be used which skips the "next thing" in
the source code
5. The "next" thing may be, among other things:
  * A JS statement (including assignments, ifs, loops, switches, functions) in which case all of the statement is
  ignored for all forms of coverage.
  * A switch case statement, in which case the particular case is ignored for branch coverage and its contents ignored
  for all forms
  * A conditional inside a ternary expression in which case the branch is ignored
  * A part of a logical expression in which case that part of the expression is ignored for branch coverage
6. It is up to the caller to scope this as narrowly as possible. For example, if you have a source file that is wrapped
in a function expression, adding `/* istanbul ignore next */` at the top of the file will ignore the whole file!

### How it works

When some part of the JS is considered skipped, nothing actually happens in terms of changes to the instrumentation. Everything is calculated as though nothing was skipped - all that changes is that there is a `skip` attribute added to the metadata of the statement, function or branch as applicable.

Coverage reporting however takes the `skip` attribute into account and artificially increments counts, when 0 and skipped to pretend that the thing in question was covered. The HTML report shows the coverage after taking skips into account but at the same time colors the skipped statements with a gray color for easy visual scan.

This design makes it possible to report on either of the coverage numbers ("raw" v/s "processed"), show a count of statements/ functions/ branches skipped etc. The HTML and text summary reports display counts of how many statements, branches and functions were ignored.

### Some practical examples

#### Ignore an else path

```javascript
/* istanbul ignore else  */
if (foo.hasOwnProperty('bar')) {
    // do something
}
```

Usually istanbul would complain about missing coverage for the `else` branch but it won't do so because of the comment.

#### Ignore an if path

```javascript
/* istanbul ignore if  */
if (hardToReproduceError)) {
    return callback(hardToReproduceError);
}
```

In this case, you do not have to produce the error to have full branch coverage.

#### Ignore specific switch cases

```javascript
switch (foo) {
    case 1: /* some code */; break;
    /* istanbul ignore next */
    case 2: // really difficult to enter in a unit test for some reason
        someCode();
}
```

In the above example, the `case 2` branch is treated as covered.

#### Ignore default assignments

```javascript
var object = parameter || /* istanbul ignore next: tired of writing tests */ {};
```

In the above example, the entire line will be treated a covered even if you don't have a test for a falsy `parameter` value. In this example the trailing `: tired of writing tests` string is an explanatory comment for your future self. It can be anything.

#### Ignore specific conditions in an expression

```javascript
if (simpleError ||
    /* istanbul ignore next */ reallyDifficultToProduceError) {

}
```

You get the idea by now.

#### Ignore a UMD wrapper

```javascript
(function (root, factory) {
    'use strict';
    /* istanbul ignore next */
    if (typeof exports === 'object') {
        // CommonJS
        module.exports = factory();
    } else if (typeof define === 'function' && define.amd) {
        // AMD. Register as an anonymous module.
        define(factory);
    } else {
        // Browser globals
        root.module = factory();
    }
})(this, fn);
```

This will cause the entire function expression to be skipped for coverage.


================================================
FILE: index.js
================================================
/*
Copyright (c) 2012, Yahoo! Inc.  All rights reserved.
Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms.
*/

/*jslint nomen: true */
var path = require('path'),
    Store = require('./lib/store'),
    Report = require('./lib/report'),
    meta = require('./lib/util/meta');

//register our standard plugins
require('./lib/register-plugins');

/**
 * the top-level API for `istanbul`. provides access to the key libraries in
 * istanbul so you can write your own tools using `istanbul` as a library.
 *
 * Usage
 * -----
 *
 *      var istanbul = require('istanbul');
 *
 *
 * @class Istanbul
 * @static
 * @module main
 * @main main
 */

module.exports = {
    /**
     * the Instrumenter class.
     * @property Instrumenter
     * @type Instrumenter
     * @static
     */
    Instrumenter: require('./lib/instrumenter'),
    /**
     * the Store class.
     * @property  Store
     * @type Store
     * @static
     */
    Store: Store,
    /**
     * the Collector class
     * @property  Collector
     * @type Collector
     * @static
     */
    Collector: require('./lib/collector'),
    /**
     * the hook module
     * @property hook
     * @type Hook
     * @static
     */
    hook: require('./lib/hook'),
    /**
     * the Report class
     * @property Report
     * @type Report
     * @static
     */
    Report: Report,
    /**
     * the config module
     * @property config
     * @type Config
     * @static
     */
    config: require('./lib/config'),
    /**
     * the Reporter class
     * @property Reporter
     * @type Reporter
     * @static
     */
    Reporter: require('./lib/reporter'),
    /**
     * utility for processing coverage objects
     * @property utils
     * @type ObjectUtils
     * @static
     */
    utils: require('./lib/object-utils'),
    /**
     * asynchronously returns a function that can match filesystem paths.
     * The function returned in the callback may be passed directly as a `matcher`
     * to the functions in the `hook` module.
     *
     * When no options are passed, the match function is one that matches all JS
     * files under the current working directory except ones under `node_modules`
     *
     * Match patterns are `ant`-style patterns processed using the `glob` library.
     * Examples not provided due to limitations in putting asterisks inside
     * jsdoc comments. Please refer to tests under `test/other/test-matcher.js`
     * for examples.
     *
     * @method matcherFor
     * @static
     * @param {Object} options Optional. Lookup options.
     * @param {String} [options.root] the root of the filesystem tree under
     *     which to match files. Defaults to `process.cwd()`
     * @param {Array} [options.includes] an array of include patterns to match.
     *     Defaults to all JS files under the root.
     * @param {Array} [options.excludes] and array of exclude patterns. File paths
     *     matching these patterns will be excluded by the returned matcher.
     *     Defaults to files under `node_modules` found anywhere under root.
     * @param {Function(err, matchFunction)} callback  The callback that is
     *      called with two arguments. The first is an `Error` object in case
     *      of errors or a falsy value if there were no errors. The second
     *      is a function that may be use as a matcher.
     */
    matcherFor: require('./lib/util/file-matcher').matcherFor,
    /**
     * the version of the library
     * @property VERSION
     * @type String
     * @static
     */
    VERSION: meta.VERSION,
    /**
     * the abstract Writer class
     * @property Writer
     * @type Writer
     * @static
     */
    Writer: require('./lib/util/writer').Writer,
    /**
     * the abstract ContentWriter class
     * @property ContentWriter
     * @type ContentWriter
     * @static
     */
    ContentWriter: require('./lib/util/writer').ContentWriter,
    /**
     * the concrete FileWriter class
     * @property FileWriter
     * @type FileWriter
     * @static
     */
    FileWriter: require('./lib/util/file-writer'),
    //undocumented
    _yuiLoadHook: require('./lib/util/yui-load-hook'),
    //undocumented
    TreeSummarizer: require('./lib/util/tree-summarizer'),
    //undocumented
    assetsDir: path.resolve(__dirname, 'lib', 'assets')
};




================================================
FILE: lib/assets/base.css
================================================
body, html {
  margin:0; padding: 0;
  height: 100%;
}
body {
    font-family: Helvetica Neue, Helvetica, Arial;
    font-size: 14px;
    color:#333;
}
.small { font-size: 12px; }
*, *:after, *:before {
  -webkit-box-sizing:border-box;
     -moz-box-sizing:border-box;
          box-sizing:border-box;
  }
h1 { font-size: 20px; margin: 0;}
h2 { font-size: 14px; }
pre {
    font: 12px/1.4 Consolas, "Liberation Mono", Menlo, Courier, monospace;
    margin: 0;
    padding: 0;
    -moz-tab-size: 2;
    -o-tab-size:  2;
    tab-size: 2;
}
a { color:#0074D9; text-decoration:none; }
a:hover { text-decoration:underline; }
.strong { font-weight: bold; }
.space-top1 { padding: 10px 0 0 0; }
.pad2y { padding: 20px 0; }
.pad1y { padding: 10px 0; }
.pad2x { padding: 0 20px; }
.pad2 { padding: 20px; }
.pad1 { padding: 10px; }
.space-left2 { padding-left:55px; }
.space-right2 { padding-right:20px; }
.center { text-align:center; }
.clearfix { display:block; }
.clearfix:after {
  content:'';
  display:block;
  height:0;
  clear:both;
  visibility:hidden;
  }
.fl { float: left; }
@media only screen and (max-width:640px) {
  .col3 { width:100%; max-width:100%; }
  .hide-mobile { display:none!important; }
}

.quiet {
  color: #7f7f7f;
  color: rgba(0,0,0,0.5);
}
.quiet a { opacity: 0.7; }

.fraction {
  font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace;
  font-size: 10px;
  color: #555;
  background: #E8E8E8;
  padding: 4px 5px;
  border-radius: 3px;
  vertical-align: middle;
}

div.path a:link, div.path a:visited { color: #333; }
table.coverage {
  border-collapse: collapse;
  margin: 10px 0 0 0;
  padding: 0;
}

table.coverage td {
  margin: 0;
  padding: 0;
  vertical-align: top;
}
table.coverage td.line-count {
    text-align: right;
    padding: 0 5px 0 20px;
}
table.coverage td.line-coverage {
    text-align: right;
    padding-right: 10px;
    min-width:20px;
}

table.coverage td span.cline-any {
    display: inline-block;
    padding: 0 5px;
    width: 100%;
}
.missing-if-branch {
    display: inline-block;
    margin-right: 5px;
    border-radius: 3px;
    position: relative;
    padding: 0 4px;
    background: #333;
    color: yellow;
}

.skip-if-branch {
    display: none;
    margin-right: 10px;
    position: relative;
    padding: 0 4px;
    background: #ccc;
    color: white;
}
.missing-if-branch .typ, .skip-if-branch .typ {
    color: inherit !important;
}
.coverage-summary {
  border-collapse: collapse;
  width: 100%;
}
.coverage-summary tr { border-bottom: 1px solid #bbb; }
.keyline-all { border: 1px solid #ddd; }
.coverage-summary td, .coverage-summary th { padding: 10px; }
.coverage-summary tbody { border: 1px solid #bbb; }
.coverage-summary td { border-right: 1px solid #bbb; }
.coverage-summary td:last-child { border-right: none; }
.coverage-summary th {
  text-align: left;
  font-weight: normal;
  white-space: nowrap;
}
.coverage-summary th.file { border-right: none !important; }
.coverage-summary th.pct { }
.coverage-summary th.pic,
.coverage-summary th.abs,
.coverage-summary td.pct,
.coverage-summary td.abs { text-align: right; }
.coverage-summary td.file { white-space: nowrap;  }
.coverage-summary td.pic { min-width: 120px !important;  }
.coverage-summary tfoot td { }

.coverage-summary .sorter {
    height: 10px;
    width: 7px;
    display: inline-block;
    margin-left: 0.5em;
    background: url(sort-arrow-sprite.png) no-repeat scroll 0 0 transparent;
}
.coverage-summary .sorted .sorter {
    background-position: 0 -20px;
}
.coverage-summary .sorted-desc .sorter {
    background-position: 0 -10px;
}
.status-line {  height: 10px; }
/* dark red */
.red.solid, .status-line.low, .low .cover-fill { background:#C21F39 }
.low .chart { border:1px solid #C21F39 }
/* medium red */
.cstat-no, .fstat-no, .cbranch-no, .cbranch-no { background:#F6C6CE }
/* light red */
.low, .cline-no { background:#FCE1E5 }
/* light green */
.high, .cline-yes { background:rgb(230,245,208) }
/* medium green */
.cstat-yes { background:rgb(161,215,106) }
/* dark green */
.status-line.high, .high .cover-fill { background:rgb(77,146,33) }
.high .chart { border:1px solid rgb(77,146,33) }
/* dark yellow (gold) */
.medium .chart { border:1px solid #f9cd0b; }
.status-line.medium, .medium .cover-fill { background: #f9cd0b; }
/* light yellow */
.medium { background: #fff4c2; }
/* light gray */
span.cline-neutral { background: #eaeaea; }

.cbranch-no { background:  yellow !important; color: #111; }

.cstat-skip { background: #ddd; color: #111; }
.fstat-skip { background: #ddd; color: #111 !important; }
.cbranch-skip { background: #ddd !important; color: #111; }


.cover-fill, .cover-empty {
  display:inline-block;
  height: 12px;
}
.chart {
  line-height: 0;
}
.cover-empty {
    background: white;
}
.cover-full {
    border-right: none !important;
}
pre.prettyprint {
    border: none !important;
    padding: 0 !important;
    margin: 0 !important;
}
.com { color: #999 !important; }
.ignore-none { color: #999; font-weight: normal; }

.wrapper {
  min-height: 100%;
  height: auto !important;
  height: 100%;
  margin: 0 auto -48px;
}
.footer, .push {
  height: 48px;
}


================================================
FILE: lib/assets/sorter.js
================================================
var addSorting = (function () {
    "use strict";
    var cols,
        currentSort = {
            index: 0,
            desc: false
        };

    // returns the summary table element
    function getTable() { return document.querySelector('.coverage-summary'); }
    // returns the thead element of the summary table
    function getTableHeader() { return getTable().querySelector('thead tr'); }
    // returns the tbody element of the summary table
    function getTableBody() { return getTable().querySelector('tbody'); }
    // returns the th element for nth column
    function getNthColumn(n) { return getTableHeader().querySelectorAll('th')[n]; }

    // loads all columns
    function loadColumns() {
        var colNodes = getTableHeader().querySelectorAll('th'),
            colNode,
            cols = [],
            col,
            i;

        for (i = 0; i < colNodes.length; i += 1) {
            colNode = colNodes[i];
            col = {
                key: colNode.getAttribute('data-col'),
                sortable: !colNode.getAttribute('data-nosort'),
                type: colNode.getAttribute('data-type') || 'string'
            };
            cols.push(col);
            if (col.sortable) {
                col.defaultDescSort = col.type === 'number';
                colNode.innerHTML = colNode.innerHTML + '<span class="sorter"></span>';
            }
        }
        return cols;
    }
    // attaches a data attribute to every tr element with an object
    // of data values keyed by column name
    function loadRowData(tableRow) {
        var tableCols = tableRow.querySelectorAll('td'),
            colNode,
            col,
            data = {},
            i,
            val;
        for (i = 0; i < tableCols.length; i += 1) {
            colNode = tableCols[i];
            col = cols[i];
            val = colNode.getAttribute('data-value');
            if (col.type === 'number') {
                val = Number(val);
            }
            data[col.key] = val;
        }
        return data;
    }
    // loads all row data
    function loadData() {
        var rows = getTableBody().querySelectorAll('tr'),
            i;

        for (i = 0; i < rows.length; i += 1) {
            rows[i].data = loadRowData(rows[i]);
        }
    }
    // sorts the table using the data for the ith column
    function sortByIndex(index, desc) {
        var key = cols[index].key,
            sorter = function (a, b) {
                a = a.data[key];
                b = b.data[key];
                return a < b ? -1 : a > b ? 1 : 0;
            },
            finalSorter = sorter,
            tableBody = document.querySelector('.coverage-summary tbody'),
            rowNodes = tableBody.querySelectorAll('tr'),
            rows = [],
            i;

        if (desc) {
            finalSorter = function (a, b) {
                return -1 * sorter(a, b);
            };
        }

        for (i = 0; i < rowNodes.length; i += 1) {
            rows.push(rowNodes[i]);
            tableBody.removeChild(rowNodes[i]);
        }

        rows.sort(finalSorter);

        for (i = 0; i < rows.length; i += 1) {
            tableBody.appendChild(rows[i]);
        }
    }
    // removes sort indicators for current column being sorted
    function removeSortIndicators() {
        var col = getNthColumn(currentSort.index),
            cls = col.className;

        cls = cls.replace(/ sorted$/, '').replace(/ sorted-desc$/, '');
        col.className = cls;
    }
    // adds sort indicators for current column being sorted
    function addSortIndicators() {
        getNthColumn(currentSort.index).className += currentSort.desc ? ' sorted-desc' : ' sorted';
    }
    // adds event listeners for all sorter widgets
    function enableUI() {
        var i,
            el,
            ithSorter = function ithSorter(i) {
                var col = cols[i];

                return function () {
                    var desc = col.defaultDescSort;

                    if (currentSort.index === i) {
                        desc = !currentSort.desc;
                    }
                    sortByIndex(i, desc);
                    removeSortIndicators();
                    currentSort.index = i;
                    currentSort.desc = desc;
                    addSortIndicators();
                };
            };
        for (i =0 ; i < cols.length; i += 1) {
            if (cols[i].sortable) {
                // add the click event handler on the th so users
                // dont have to click on those tiny arrows
                el = getNthColumn(i).querySelector('.sorter').parentElement;
                if (el.addEventListener) {
                    el.addEventListener('click', ithSorter(i));
                } else {
                    el.attachEvent('onclick', ithSorter(i));
                }
            }
        }
    }
    // adds sorting functionality to the UI
    return function () {
        if (!getTable()) {
            return;
        }
        cols = loadColumns();
        loadData(cols);
        addSortIndicators();
        enableUI();
    };
})();

window.addEventListener('load', addSorting);


================================================
FILE: lib/assets/vendor/prettify.css
================================================
.pln{color:#000}@media screen{.str{color:#080}.kwd{color:#008}.com{color:#800}.typ{color:#606}.lit{color:#066}.pun,.opn,.clo{color:#660}.tag{color:#008}.atn{color:#606}.atv{color:#080}.dec,.var{color:#606}.fun{color:red}}@media print,projection{.str{color:#060}.kwd{color:#006;font-weight:bold}.com{color:#600;font-style:italic}.typ{color:#404;font-weight:bold}.lit{color:#044}.pun,.opn,.clo{color:#440}.tag{color:#006;font-weight:bold}.atn{color:#404}.atv{color:#060}}pre.prettyprint{padding:2px;border:1px solid #888}ol.linenums{margin-top:0;margin-bottom:0}li.L0,li.L1,li.L2,li.L3,li.L5,li.L6,li.L7,li.L8{list-style-type:none}li.L1,li.L3,li.L5,li.L7,li.L9{background:#eee}


================================================
FILE: lib/assets/vendor/prettify.js
================================================
window.PR_SHOULD_USE_CONTINUATION=true;(function(){var h=["break,continue,do,else,for,if,return,while"];var u=[h,"auto,case,char,const,default,double,enum,extern,float,goto,int,long,register,short,signed,sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"];var p=[u,"catch,class,delete,false,import,new,operator,private,protected,public,this,throw,true,try,typeof"];var l=[p,"alignof,align_union,asm,axiom,bool,concept,concept_map,const_cast,constexpr,decltype,dynamic_cast,explicit,export,friend,inline,late_check,mutable,namespace,nullptr,reinterpret_cast,static_assert,static_cast,template,typeid,typename,using,virtual,where"];var x=[p,"abstract,boolean,byte,extends,final,finally,implements,import,instanceof,null,native,package,strictfp,super,synchronized,throws,transient"];var R=[x,"as,base,by,checked,decimal,delegate,descending,dynamic,event,fixed,foreach,from,group,implicit,in,interface,internal,into,is,lock,object,out,override,orderby,params,partial,readonly,ref,sbyte,sealed,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,var"];var r="all,and,by,catch,class,else,extends,false,finally,for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then,true,try,unless,until,when,while,yes";var w=[p,"debugger,eval,export,function,get,null,set,undefined,var,with,Infinity,NaN"];var s="caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END";var I=[h,"and,as,assert,class,def,del,elif,except,exec,finally,from,global,import,in,is,lambda,nonlocal,not,or,pass,print,raise,try,with,yield,False,True,None"];var f=[h,"alias,and,begin,case,class,def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo,rescue,retry,self,super,then,true,undef,unless,until,when,yield,BEGIN,END"];var H=[h,"case,done,elif,esac,eval,fi,function,in,local,set,then,until"];var A=[l,R,w,s+I,f,H];var e=/^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\d*)/;var C="str";var z="kwd";var j="com";var O="typ";var G="lit";var L="pun";var F="pln";var m="tag";var E="dec";var J="src";var P="atn";var n="atv";var N="nocode";var M="(?:^^\\.?|[+-]|\\!|\\!=|\\!==|\\#|\\%|\\%=|&|&&|&&=|&=|\\(|\\*|\\*=|\\+=|\\,|\\-=|\\->|\\/|\\/=|:|::|\\;|<|<<|<<=|<=|=|==|===|>|>=|>>|>>=|>>>|>>>=|\\?|\\@|\\[|\\^|\\^=|\\^\\^|\\^\\^=|\\{|\\||\\|=|\\|\\||\\|\\|=|\\~|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\\s*";function k(Z){var ad=0;var S=false;var ac=false;for(var V=0,U=Z.length;V<U;++V){var ae=Z[V];if(ae.ignoreCase){ac=true}else{if(/[a-z]/i.test(ae.source.replace(/\\u[0-9a-f]{4}|\\x[0-9a-f]{2}|\\[^ux]/gi,""))){S=true;ac=false;break}}}var Y={b:8,t:9,n:10,v:11,f:12,r:13};function ab(ah){var ag=ah.charCodeAt(0);if(ag!==92){return ag}var af=ah.charAt(1);ag=Y[af];if(ag){return ag}else{if("0"<=af&&af<="7"){return parseInt(ah.substring(1),8)}else{if(af==="u"||af==="x"){return parseInt(ah.substring(2),16)}else{return ah.charCodeAt(1)}}}}function T(af){if(af<32){return(af<16?"\\x0":"\\x")+af.toString(16)}var ag=String.fromCharCode(af);if(ag==="\\"||ag==="-"||ag==="["||ag==="]"){ag="\\"+ag}return ag}function X(am){var aq=am.substring(1,am.length-1).match(new RegExp("\\\\u[0-9A-Fa-f]{4}|\\\\x[0-9A-Fa-f]{2}|\\\\[0-3][0-7]{0,2}|\\\\[0-7]{1,2}|\\\\[\\s\\S]|-|[^-\\\\]","g"));var ak=[];var af=[];var ao=aq[0]==="^";for(var ar=ao?1:0,aj=aq.length;ar<aj;++ar){var ah=aq[ar];if(/\\[bdsw]/i.test(ah)){ak.push(ah)}else{var ag=ab(ah);var al;if(ar+2<aj&&"-"===aq[ar+1]){al=ab(aq[ar+2]);ar+=2}else{al=ag}af.push([ag,al]);if(!(al<65||ag>122)){if(!(al<65||ag>90)){af.push([Math.max(65,ag)|32,Math.min(al,90)|32])}if(!(al<97||ag>122)){af.push([Math.max(97,ag)&~32,Math.min(al,122)&~32])}}}}af.sort(function(av,au){return(av[0]-au[0])||(au[1]-av[1])});var ai=[];var ap=[NaN,NaN];for(var ar=0;ar<af.length;++ar){var at=af[ar];if(at[0]<=ap[1]+1){ap[1]=Math.max(ap[1],at[1])}else{ai.push(ap=at)}}var an=["["];if(ao){an.push("^")}an.push.apply(an,ak);for(var ar=0;ar<ai.length;++ar){var at=ai[ar];an.push(T(at[0]));if(at[1]>at[0]){if(at[1]+1>at[0]){an.push("-")}an.push(T(at[1]))}}an.push("]");return an.join("")}function W(al){var aj=al.source.match(new RegExp("(?:\\[(?:[^\\x5C\\x5D]|\\\\[\\s\\S])*\\]|\\\\u[A-Fa-f0-9]{4}|\\\\x[A-Fa-f0-9]{2}|\\\\[0-9]+|\\\\[^ux0-9]|\\(\\?[:!=]|[\\(\\)\\^]|[^\\x5B\\x5C\\(\\)\\^]+)","g"));var ah=aj.length;var an=[];for(var ak=0,am=0;ak<ah;++ak){var ag=aj[ak];if(ag==="("){++am}else{if("\\"===ag.charAt(0)){var af=+ag.substring(1);if(af&&af<=am){an[af]=-1}}}}for(var ak=1;ak<an.length;++ak){if(-1===an[ak]){an[ak]=++ad}}for(var ak=0,am=0;ak<ah;++ak){var ag=aj[ak];if(ag==="("){++am;if(an[am]===undefined){aj[ak]="(?:"}}else{if("\\"===ag.charAt(0)){var af=+ag.substring(1);if(af&&af<=am){aj[ak]="\\"+an[am]}}}}for(var ak=0,am=0;ak<ah;++ak){if("^"===aj[ak]&&"^"!==aj[ak+1]){aj[ak]=""}}if(al.ignoreCase&&S){for(var ak=0;ak<ah;++ak){var ag=aj[ak];var ai=ag.charAt(0);if(ag.length>=2&&ai==="["){aj[ak]=X(ag)}else{if(ai!=="\\"){aj[ak]=ag.replace(/[a-zA-Z]/g,function(ao){var ap=ao.charCodeAt(0);return"["+String.fromCharCode(ap&~32,ap|32)+"]"})}}}}return aj.join("")}var aa=[];for(var V=0,U=Z.length;V<U;++V){var ae=Z[V];if(ae.global||ae.multiline){throw new Error(""+ae)}aa.push("(?:"+W(ae)+")")}return new RegExp(aa.join("|"),ac?"gi":"g")}function a(V){var U=/(?:^|\s)nocode(?:\s|$)/;var X=[];var T=0;var Z=[];var W=0;var S;if(V.currentStyle){S=V.currentStyle.whiteSpace}else{if(window.getComputedStyle){S=document.defaultView.getComputedStyle(V,null).getPropertyValue("white-space")}}var Y=S&&"pre"===S.substring(0,3);function aa(ab){switch(ab.nodeType){case 1:if(U.test(ab.className)){return}for(var ae=ab.firstChild;ae;ae=ae.nextSibling){aa(ae)}var ad=ab.nodeName;if("BR"===ad||"LI"===ad){X[W]="\n";Z[W<<1]=T++;Z[(W++<<1)|1]=ab}break;case 3:case 4:var ac=ab.nodeValue;if(ac.length){if(!Y){ac=ac.replace(/[ \t\r\n]+/g," ")}else{ac=ac.replace(/\r\n?/g,"\n")}X[W]=ac;Z[W<<1]=T;T+=ac.length;Z[(W++<<1)|1]=ab}break}}aa(V);return{sourceCode:X.join("").replace(/\n$/,""),spans:Z}}function B(S,U,W,T){if(!U){return}var V={sourceCode:U,basePos:S};W(V);T.push.apply(T,V.decorations)}var v=/\S/;function o(S){var V=undefined;for(var U=S.firstChild;U;U=U.nextSibling){var T=U.nodeType;V=(T===1)?(V?S:U):(T===3)?(v.test(U.nodeValue)?S:V):V}return V===S?undefined:V}function g(U,T){var S={};var V;(function(){var ad=U.concat(T);var ah=[];var ag={};for(var ab=0,Z=ad.length;ab<Z;++ab){var Y=ad[ab];var ac=Y[3];if(ac){for(var ae=ac.length;--ae>=0;){S[ac.charAt(ae)]=Y}}var af=Y[1];var aa=""+af;if(!ag.hasOwnProperty(aa)){ah.push(af);ag[aa]=null}}ah.push(/[\0-\uffff]/);V=k(ah)})();var X=T.length;var W=function(ah){var Z=ah.sourceCode,Y=ah.basePos;var ad=[Y,F];var af=0;var an=Z.match(V)||[];var aj={};for(var ae=0,aq=an.length;ae<aq;++ae){var ag=an[ae];var ap=aj[ag];var ai=void 0;var am;if(typeof ap==="string"){am=false}else{var aa=S[ag.charAt(0)];if(aa){ai=ag.match(aa[1]);ap=aa[0]}else{for(var ao=0;ao<X;++ao){aa=T[ao];ai=ag.match(aa[1]);if(ai){ap=aa[0];break}}if(!ai){ap=F}}am=ap.length>=5&&"lang-"===ap.substring(0,5);if(am&&!(ai&&typeof ai[1]==="string")){am=false;ap=J}if(!am){aj[ag]=ap}}var ab=af;af+=ag.length;if(!am){ad.push(Y+ab,ap)}else{var al=ai[1];var ak=ag.indexOf(al);var ac=ak+al.length;if(ai[2]){ac=ag.length-ai[2].length;ak=ac-al.length}var ar=ap.substring(5);B(Y+ab,ag.substring(0,ak),W,ad);B(Y+ab+ak,al,q(ar,al),ad);B(Y+ab+ac,ag.substring(ac),W,ad)}}ah.decorations=ad};return W}function i(T){var W=[],S=[];if(T.tripleQuotedStrings){W.push([C,/^(?:\'\'\'(?:[^\'\\]|\\[\s\S]|\'{1,2}(?=[^\']))*(?:\'\'\'|$)|\"\"\"(?:[^\"\\]|\\[\s\S]|\"{1,2}(?=[^\"]))*(?:\"\"\"|$)|\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$))/,null,"'\""])}else{if(T.multiLineStrings){W.push([C,/^(?:\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$)|\`(?:[^\\\`]|\\[\s\S])*(?:\`|$))/,null,"'\"`"])}else{W.push([C,/^(?:\'(?:[^\\\'\r\n]|\\.)*(?:\'|$)|\"(?:[^\\\"\r\n]|\\.)*(?:\"|$))/,null,"\"'"])}}if(T.verbatimStrings){S.push([C,/^@\"(?:[^\"]|\"\")*(?:\"|$)/,null])}var Y=T.hashComments;if(Y){if(T.cStyleComments){if(Y>1){W.push([j,/^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/,null,"#"])}else{W.push([j,/^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\r\n]*)/,null,"#"])}S.push([C,/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h|[a-z]\w*)>/,null])}else{W.push([j,/^#[^\r\n]*/,null,"#"])}}if(T.cStyleComments){S.push([j,/^\/\/[^\r\n]*/,null]);S.push([j,/^\/\*[\s\S]*?(?:\*\/|$)/,null])}if(T.regexLiterals){var X=("/(?=[^/*])(?:[^/\\x5B\\x5C]|\\x5C[\\s\\S]|\\x5B(?:[^\\x5C\\x5D]|\\x5C[\\s\\S])*(?:\\x5D|$))+/");S.push(["lang-regex",new RegExp("^"+M+"("+X+")")])}var V=T.types;if(V){S.push([O,V])}var U=(""+T.keywords).replace(/^ | $/g,"");if(U.length){S.push([z,new RegExp("^(?:"+U.replace(/[\s,]+/g,"|")+")\\b"),null])}W.push([F,/^\s+/,null," \r\n\t\xA0"]);S.push([G,/^@[a-z_$][a-z_$@0-9]*/i,null],[O,/^(?:[@_]?[A-Z]+[a-z][A-Za-z_$@0-9]*|\w+_t\b)/,null],[F,/^[a-z_$][a-z_$@0-9]*/i,null],[G,new RegExp("^(?:0x[a-f0-9]+|(?:\\d(?:_\\d+)*\\d*(?:\\.\\d*)?|\\.\\d\\+)(?:e[+\\-]?\\d+)?)[a-z]*","i"),null,"0123456789"],[F,/^\\[\s\S]?/,null],[L,/^.[^\s\w\.$@\'\"\`\/\#\\]*/,null]);return g(W,S)}var K=i({keywords:A,hashComments:true,cStyleComments:true,multiLineStrings:true,regexLiterals:true});function Q(V,ag){var U=/(?:^|\s)nocode(?:\s|$)/;var ab=/\r\n?|\n/;var ac=V.ownerDocument;var S;if(V.currentStyle){S=V.currentStyle.whiteSpace}else{if(window.getComputedStyle){S=ac.defaultView.getComputedStyle(V,null).getPropertyValue("white-space")}}var Z=S&&"pre"===S.substring(0,3);var af=ac.createElement("LI");while(V.firstChild){af.appendChild(V.firstChild)}var W=[af];function ae(al){switch(al.nodeType){case 1:if(U.test(al.className)){break}if("BR"===al.nodeName){ad(al);if(al.parentNode){al.parentNode.removeChild(al)}}else{for(var an=al.firstChild;an;an=an.nextSibling){ae(an)}}break;case 3:case 4:if(Z){var am=al.nodeValue;var aj=am.match(ab);if(aj){var ai=am.substring(0,aj.index);al.nodeValue=ai;var ah=am.substring(aj.index+aj[0].length);if(ah){var ak=al.parentNode;ak.insertBefore(ac.createTextNode(ah),al.nextSibling)}ad(al);if(!ai){al.parentNode.removeChild(al)}}}break}}function ad(ak){while(!ak.nextSibling){ak=ak.parentNode;if(!ak){return}}function ai(al,ar){var aq=ar?al.cloneNode(false):al;var ao=al.parentNode;if(ao){var ap=ai(ao,1);var an=al.nextSibling;ap.appendChild(aq);for(var am=an;am;am=an){an=am.nextSibling;ap.appendChild(am)}}return aq}var ah=ai(ak.nextSibling,0);for(var aj;(aj=ah.parentNode)&&aj.nodeType===1;){ah=aj}W.push(ah)}for(var Y=0;Y<W.length;++Y){ae(W[Y])}if(ag===(ag|0)){W[0].setAttribute("value",ag)}var aa=ac.createElement("OL");aa.className="linenums";var X=Math.max(0,((ag-1))|0)||0;for(var Y=0,T=W.length;Y<T;++Y){af=W[Y];af.className="L"+((Y+X)%10);if(!af.firstChild){af.appendChild(ac.createTextNode("\xA0"))}aa.appendChild(af)}V.appendChild(aa)}function D(ac){var aj=/\bMSIE\b/.test(navigator.userAgent);var am=/\n/g;var al=ac.sourceCode;var an=al.length;var V=0;var aa=ac.spans;var T=aa.length;var ah=0;var X=ac.decorations;var Y=X.length;var Z=0;X[Y]=an;var ar,aq;for(aq=ar=0;aq<Y;){if(X[aq]!==X[aq+2]){X[ar++]=X[aq++];X[ar++]=X[aq++]}else{aq+=2}}Y=ar;for(aq=ar=0;aq<Y;){var at=X[aq];var ab=X[aq+1];var W=aq+2;while(W+2<=Y&&X[W+1]===ab){W+=2}X[ar++]=at;X[ar++]=ab;aq=W}Y=X.length=ar;var ae=null;while(ah<T){var af=aa[ah];var S=aa[ah+2]||an;var ag=X[Z];var ap=X[Z+2]||an;var W=Math.min(S,ap);var ak=aa[ah+1];var U;if(ak.nodeType!==1&&(U=al.substring(V,W))){if(aj){U=U.replace(am,"\r")}ak.nodeValue=U;var ai=ak.ownerDocument;var ao=ai.createElement("SPAN");ao.className=X[Z+1];var ad=ak.parentNode;ad.replaceChild(ao,ak);ao.appendChild(ak);if(V<S){aa[ah+1]=ak=ai.createTextNode(al.substring(W,S));ad.insertBefore(ak,ao.nextSibling)}}V=W;if(V>=S){ah+=2}if(V>=ap){Z+=2}}}var t={};function c(U,V){for(var S=V.length;--S>=0;){var T=V[S];if(!t.hasOwnProperty(T)){t[T]=U}else{if(window.console){console.warn("cannot override language handler %s",T)}}}}function q(T,S){if(!(T&&t.hasOwnProperty(T))){T=/^\s*</.test(S)?"default-markup":"default-code"}return t[T]}c(K,["default-code"]);c(g([],[[F,/^[^<?]+/],[E,/^<!\w[^>]*(?:>|$)/],[j,/^<\!--[\s\S]*?(?:-\->|$)/],["lang-",/^<\?([\s\S]+?)(?:\?>|$)/],["lang-",/^<%([\s\S]+?)(?:%>|$)/],[L,/^(?:<[%?]|[%?]>)/],["lang-",/^<xmp\b[^>]*>([\s\S]+?)<\/xmp\b[^>]*>/i],["lang-js",/^<script\b[^>]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-css",/^<style\b[^>]*>([\s\S]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i]]),["default-markup","htm","html","mxml","xhtml","xml","xsl"]);c(g([[F,/^[\s]+/,null," \t\r\n"],[n,/^(?:\"[^\"]*\"?|\'[^\']*\'?)/,null,"\"'"]],[[m,/^^<\/?[a-z](?:[\w.:-]*\w)?|\/?>$/i],[P,/^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],["lang-uq.val",/^=\s*([^>\'\"\s]*(?:[^>\'\"\s\/]|\/(?=\s)))/],[L,/^[=<>\/]+/],["lang-js",/^on\w+\s*=\s*\"([^\"]+)\"/i],["lang-js",/^on\w+\s*=\s*\'([^\']+)\'/i],["lang-js",/^on\w+\s*=\s*([^\"\'>\s]+)/i],["lang-css",/^style\s*=\s*\"([^\"]+)\"/i],["lang-css",/^style\s*=\s*\'([^\']+)\'/i],["lang-css",/^style\s*=\s*([^\"\'>\s]+)/i]]),["in.tag"]);c(g([],[[n,/^[\s\S]+/]]),["uq.val"]);c(i({keywords:l,hashComments:true,cStyleComments:true,types:e}),["c","cc","cpp","cxx","cyc","m"]);c(i({keywords:"null,true,false"}),["json"]);c(i({keywords:R,hashComments:true,cStyleComments:true,verbatimStrings:true,types:e}),["cs"]);c(i({keywords:x,cStyleComments:true}),["java"]);c(i({keywords:H,hashComments:true,multiLineStrings:true}),["bsh","csh","sh"]);c(i({keywords:I,hashComments:true,multiLineStrings:true,tripleQuotedStrings:true}),["cv","py"]);c(i({keywords:s,hashComments:true,multiLineStrings:true,regexLiterals:true}),["perl","pl","pm"]);c(i({keywords:f,hashComments:true,multiLineStrings:true,regexLiterals:true}),["rb"]);c(i({keywords:w,cStyleComments:true,regexLiterals:true}),["js"]);c(i({keywords:r,hashComments:3,cStyleComments:true,multilineStrings:true,tripleQuotedStrings:true,regexLiterals:true}),["coffee"]);c(g([],[[C,/^[\s\S]+/]]),["regex"]);function d(V){var U=V.langExtension;try{var S=a(V.sourceNode);var T=S.sourceCode;V.sourceCode=T;V.spans=S.spans;V.basePos=0;q(U,T)(V);D(V)}catch(W){if("console" in window){console.log(W&&W.stack?W.stack:W)}}}function y(W,V,U){var S=document.createElement("PRE");S.innerHTML=W;if(U){Q(S,U)}var T={langExtension:V,numberLines:U,sourceNode:S};d(T);return S.innerHTML}function b(ad){function Y(af){return document.getElementsByTagName(af)}var ac=[Y("pre"),Y("code"),Y("xmp")];var T=[];for(var aa=0;aa<ac.length;++aa){for(var Z=0,V=ac[aa].length;Z<V;++Z){T.push(ac[aa][Z])}}ac=null;var W=Date;if(!W.now){W={now:function(){return +(new Date)}}}var X=0;var S;var ab=/\blang(?:uage)?-([\w.]+)(?!\S)/;var ae=/\bprettyprint\b/;function U(){var ag=(window.PR_SHOULD_USE_CONTINUATION?W.now()+250:Infinity);for(;X<T.length&&W.now()<ag;X++){var aj=T[X];var ai=aj.className;if(ai.indexOf("prettyprint")>=0){var ah=ai.match(ab);var am;if(!ah&&(am=o(aj))&&"CODE"===am.tagName){ah=am.className.match(ab)}if(ah){ah=ah[1]}var al=false;for(var ak=aj.parentNode;ak;ak=ak.parentNode){if((ak.tagName==="pre"||ak.tagName==="code"||ak.tagName==="xmp")&&ak.className&&ak.className.indexOf("prettyprint")>=0){al=true;break}}if(!al){var af=aj.className.match(/\blinenums\b(?::(\d+))?/);af=af?af[1]&&af[1].length?+af[1]:true:false;if(af){Q(aj,af)}S={langExtension:ah,sourceNode:aj,numberLines:af};d(S)}}}if(X<T.length){setTimeout(U,250)}else{if(ad){ad()}}}U()}window.prettyPrintOne=y;window.prettyPrint=b;window.PR={createSimpleLexer:g,registerLangHandler:c,sourceDecorator:i,PR_ATTRIB_NAME:P,PR_ATTRIB_VALUE:n,PR_COMMENT:j,PR_DECLARATION:E,PR_KEYWORD:z,PR_LITERAL:G,PR_NOCODE:N,PR_PLAIN:F,PR_PUNCTUATION:L,PR_SOURCE:J,PR_STRING:C,PR_TAG:m,PR_TYPE:O}})();PR.registerLangHandler(PR.createSimpleLexer([],[[PR.PR_DECLARATION,/^<!\w[^>]*(?:>|$)/],[PR.PR_COMMENT,/^<\!--[\s\S]*?(?:-\->|$)/],[PR.PR_PUNCTUATION,/^(?:<[%?]|[%?]>)/],["lang-",/^<\?([\s\S]+?)(?:\?>|$)/],["lang-",/^<%([\s\S]+?)(?:%>|$)/],["lang-",/^<xmp\b[^>]*>([\s\S]+?)<\/xmp\b[^>]*>/i],["lang-handlebars",/^<script\b[^>]*type\s*=\s*['"]?text\/x-handlebars-template['"]?\b[^>]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-js",/^<script\b[^>]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-css",/^<style\b[^>]*>([\s\S]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i],[PR.PR_DECLARATION,/^{{[#^>/]?\s*[\w.][^}]*}}/],[PR.PR_DECLARATION,/^{{&?\s*[\w.][^}]*}}/],[PR.PR_DECLARATION,/^{{{>?\s*[\w.][^}]*}}}/],[PR.PR_COMMENT,/^{{![^}]*}}/]]),["handlebars","hbs"]);PR.registerLangHandler(PR.createSimpleLexer([[PR.PR_PLAIN,/^[ \t\r\n\f]+/,null," \t\r\n\f"]],[[PR.PR_STRING,/^\"(?:[^\n\r\f\\\"]|\\(?:\r\n?|\n|\f)|\\[\s\S])*\"/,null],[PR.PR_STRING,/^\'(?:[^\n\r\f\\\']|\\(?:\r\n?|\n|\f)|\\[\s\S])*\'/,null],["lang-css-str",/^url\(([^\)\"\']*)\)/i],[PR.PR_KEYWORD,/^(?:url|rgb|\!important|@import|@page|@media|@charset|inherit)(?=[^\-\w]|$)/i,null],["lang-css-kw",/^(-?(?:[_a-z]|(?:\\[0-9a-f]+ ?))(?:[_a-z0-9\-]|\\(?:\\[0-9a-f]+ ?))*)\s*:/i],[PR.PR_COMMENT,/^\/\*[^*]*\*+(?:[^\/*][^*]*\*+)*\//],[PR.PR_COMMENT,/^(?:<!--|-->)/],[PR.PR_LITERAL,/^(?:\d+|\d*\.\d+)(?:%|[a-z]+)?/i],[PR.PR_LITERAL,/^#(?:[0-9a-f]{3}){1,2}/i],[PR.PR_PLAIN,/^-?(?:[_a-z]|(?:\\[\da-f]+ ?))(?:[_a-z\d\-]|\\(?:\\[\da-f]+ ?))*/i],[PR.PR_PUNCTUATION,/^[^\s\w\'\"]+/]]),["css"]);PR.registerLangHandler(PR.createSimpleLexer([],[[PR.PR_KEYWORD,/^-?(?:[_a-z]|(?:\\[\da-f]+ ?))(?:[_a-z\d\-]|\\(?:\\[\da-f]+ ?))*/i]]),["css-kw"]);PR.registerLangHandler(PR.createSimpleLexer([],[[PR.PR_STRING,/^[^\)\"\']+/]]),["css-str"]);


================================================
FILE: lib/cli.js
================================================
#!/usr/bin/env node

/*
 Copyright (c) 2012, Yahoo! Inc.  All rights reserved.
 Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms.
 */


var async = require('async'),
    Command = require('./command'),
    inputError = require('./util/input-error'),
    exitProcess = process.exit; //hold a reference to original process.exit so that we are not affected even when a test changes it

require('./register-plugins');

function findCommandPosition(args) {
    var i;

    for (i = 0; i < args.length; i += 1) {
        if (args[i].charAt(0) !== '-') {
            return i;
        }
    }

    return -1;
}

function exit(ex, code) {
  // flush output for Node.js Windows pipe bug
  // https://github.com/joyent/node/issues/6247 is just one bug example
  // https://github.com/visionmedia/mocha/issues/333 has a good discussion
  var streams = [process.stdout, process.stderr];
  async.forEach(streams, function (stream, done) {
    // submit a write request and wait until it's written
    stream.write('', done);
  }, function () {
    if (ex) {
        if (typeof ex === 'string') {
            console.error(ex);
            exitProcess(1);
        } else {
            throw ex; // turn it into an uncaught exception
        }
    } else {
        exitProcess(code);
    }
  });
}

function errHandler (ex) {
    if (!ex) { return; }
    if (!ex.inputError) {
        // exit with exception stack trace
        exit(ex);
    } else {
        //don't print nasty traces but still exit(1)
        console.error(ex.message);
        console.error('Try "istanbul help" for usage');
        exit(null, 1);
    }
}

function runCommand(args, callback) {
    var pos = findCommandPosition(args),
        command,
        commandArgs,
        commandObject;

    if (pos < 0) {
        return callback(inputError.create('Need a command to run'));
    }

    commandArgs = args.slice(0, pos);
    command = args[pos];
    commandArgs.push.apply(commandArgs, args.slice(pos + 1));

    try {
        commandObject = Command.create(command);
    } catch (ex) {
        errHandler(inputError.create(ex.message));
        return;
    }
    commandObject.run(commandArgs, errHandler);
}

function runToCompletion(args) {
    runCommand(args, errHandler);
}

/* istanbul ignore if: untestable */
if (require.main === module) {
    var args = Array.prototype.slice.call(process.argv, 2);
    runToCompletion(args);
}

module.exports = {
    runToCompletion: runToCompletion
};



================================================
FILE: lib/collector.js
================================================
/*
 Copyright (c) 2012, Yahoo! Inc.  All rights reserved.
 Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms.
 */
"use strict";
var MemoryStore = require('./store/memory'),
    utils = require('./object-utils');

/**
 * a mechanism to merge multiple coverage objects into one. Handles the use case
 * of overlapping coverage information for the same files in multiple coverage
 * objects and does not double-count in this situation. For example, if
 * you pass the same coverage object multiple times, the final merged object will be
 * no different that any of the objects passed in (except for execution counts).
 *
 * The `Collector` is built for scale to handle thousands of coverage objects.
 * By default, all processing is done in memory since the common use-case is of
 * one or a few coverage objects. You can work around memory
 * issues by passing in a `Store` implementation that stores temporary computations
 * on disk (the `tmp` store, for example).
 *
 * The `getFinalCoverage` method returns an object with merged coverage information
 * and is provided as a convenience for implementors working with coverage information
 * that can fit into memory. Reporters, in the interest of generality, should *not* use this method for
 * creating reports.
 *
 * Usage
 * -----
 *
 *      var collector = new require('istanbul').Collector();
 *
 *      files.forEach(function (f) {
 *          //each coverage object can have overlapping information about multiple files
 *          collector.add(JSON.parse(fs.readFileSync(f, 'utf8')));
 *      });
 *
 *      collector.files().forEach(function(file) {
 *          var fileCoverage = collector.fileCoverageFor(file);
 *          console.log('Coverage for ' + file + ' is:' + JSON.stringify(fileCoverage));
 *      });
 *
 *      // convenience method: do not use this when dealing with a large number of files
 *      var finalCoverage = collector.getFinalCoverage();
 *
 * @class Collector
 * @module main
 * @constructor
 * @param {Object} options Optional. Configuration options.
 * @param {Store} options.store - an implementation of `Store` to use for temporary
 *      calculations.
 */
function Collector(options) {
    options = options || {};
    this.store = options.store || new MemoryStore();
}

Collector.prototype = {
    /**
     * adds a coverage object to the collector.
     *
     * @method add
     * @param {Object} coverage the coverage object.
     * @param {String} testName Optional. The name of the test used to produce the object.
     *      This is currently not used.
     */
    add: function (coverage /*, testName */) {
        var store = this.store;
        Object.keys(coverage).forEach(function (key) {
            var fileCoverage = coverage[key];
            if (store.hasKey(key)) {
                store.setObject(key, utils.mergeFileCoverage(fileCoverage, store.getObject(key)));
            } else {
                store.setObject(key, fileCoverage);
            }
        });
    },
    /**
     * returns a list of unique file paths for which coverage information has been added.
     * @method files
     * @return {Array} an array of file paths for which coverage information is present.
     */
    files: function () {
        return this.store.keys();
    },
    /**
     * return file coverage information for a single file
     * @method fileCoverageFor
     * @param {String} fileName the path for the file for which coverage information is
     *      required. Must be one of the values returned in the `files()` method.
     * @return {Object} the coverage information for the specified file.
     */
    fileCoverageFor: function (fileName) {
        var ret = this.store.getObject(fileName);
        utils.addDerivedInfoForFile(ret);
        return ret;
    },
    /**
     * returns file coverage information for all files. This has the same format as
     * any of the objects passed in to the `add` method. The number of keys in this
     * object will be a superset of all keys found in the objects passed to `add()`
     * @method getFinalCoverage
     * @return {Object} the merged coverage information
     */
    getFinalCoverage: function () {
        var ret = {},
            that = this;
        this.files().forEach(function (file) {
            ret[file] = that.fileCoverageFor(file);
        });
        return ret;
    },
    /**
     * disposes this collector and reclaims temporary resources used in the
     * computation. Calls `dispose()` on the underlying store.
     * @method dispose
     */
    dispose: function () {
        this.store.dispose();
    }
};

module.exports = Collector;

================================================
FILE: lib/command/check-coverage.js
================================================
/*
 Copyright (c) 2012, Yahoo! Inc.  All rights reserved.
 Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms.
 */

var nopt = require('nopt'),
    path = require('path'),
    fs = require('fs'),
    Collector = require('../collector'),
    formatOption = require('../util/help-formatter').formatOption,
    util = require('util'),
    utils = require('../object-utils'),
    filesFor = require('../util/file-matcher').filesFor,
    Command = require('./index'),
    configuration = require('../config');

function isAbsolute(file) {
    if (path.isAbsolute) {
        return path.isAbsolute(file);
    }

    return path.resolve(file) === path.normalize(file);
}

function CheckCoverageCommand() {
    Command.call(this);
}

function removeFiles(covObj, root, files) {
    var filesObj = {},
        obj = {};

    // Create lookup table.
    files.forEach(function (file) {
        filesObj[file] = true;
    });

    Object.keys(covObj).forEach(function (key) {
        // Exclude keys will always be relative, but covObj keys can be absolute or relative
        var excludeKey = isAbsolute(key) ? path.relative(root, key) : key;
        // Also normalize for files that start with `./`, etc.
        excludeKey = path.normalize(excludeKey);
        if (filesObj[excludeKey] !== true) {
            obj[key] = covObj[key];
        }
    });

    return obj;
}

CheckCoverageCommand.TYPE = 'check-coverage';
util.inherits(CheckCoverageCommand, Command);

Command.mix(CheckCoverageCommand, {
    synopsis: function () {
        return "checks overall/per-file coverage against thresholds from coverage JSON files. Exits 1 if thresholds are not met, 0 otherwise";
    },

    usage: function () {
        console.error('\nUsage: ' + this.toolName() + ' ' + this.type() + ' <options> [<include-pattern>]\n\nOptions are:\n\n' +
            [
                formatOption('--statements <threshold>', 'global statement coverage threshold'),
                formatOption('--functions <threshold>', 'global function coverage threshold'),
                formatOption('--branches <threshold>', 'global branch coverage threshold'),
                formatOption('--lines <threshold>', 'global line coverage threshold')
            ].join('\n\n') + '\n');

        console.error('\n\n');

        console.error('Thresholds, when specified as a positive number are taken to be the minimum percentage required.');
        console.error('When a threshold is specified as a negative number it represents the maximum number of uncovered entities allowed.\n');
        console.error('For example, --statements 90 implies minimum statement coverage is 90%.');
        console.error('             --statements -10 implies that no more than 10 uncovered statements are allowed\n');
        console.error('Per-file thresholds can be specified via a configuration file.\n');
        console.error('<include-pattern> is a glob pattern that can be used to select one or more coverage files ' +
            'for merge. This defaults to "**/coverage*.json"');

        console.error('\n');
    },

    run: function (args, callback) {

        var template = {
                config: path,
                root: path,
                statements: Number,
                lines: Number,
                branches: Number,
                functions: Number,
                verbose: Boolean
            },
            opts = nopt(template, { v : '--verbose' }, args, 0),
            // Translate to config opts.
            config = configuration.loadFile(opts.config, {
                verbose: opts.verbose,
                check: {
                    global: {
                        statements: opts.statements,
                        lines: opts.lines,
                        branches: opts.branches,
                        functions: opts.functions
                    }
                }
            }),
            includePattern = '**/coverage*.json',
            root,
            collector = new Collector(),
            errors = [];

        if (opts.argv.remain.length > 0) {
            includePattern = opts.argv.remain[0];
        }

        root = opts.root || process.cwd();
        filesFor({
            root: root,
            includes: [ includePattern ]
        }, function (err, files) {
            if (err) { throw err; }
            if (files.length === 0) {
               return callback('ERROR: No coverage files found.');
            }
            files.forEach(function (file) {
                var coverageObject = JSON.parse(fs.readFileSync(file, 'utf8'));
                collector.add(coverageObject);
            });
            var thresholds = {
                global: {
                    statements: config.check.global.statements || 0,
                    branches: config.check.global.branches || 0,
                    lines: config.check.global.lines || 0,
                    functions: config.check.global.functions || 0,
                    excludes: config.check.global.excludes || []
                },
                each: {
                    statements: config.check.each.statements || 0,
                    branches: config.check.each.branches || 0,
                    lines: config.check.each.lines || 0,
                    functions: config.check.each.functions || 0,
                    excludes: config.check.each.excludes || []
                }
            },
                rawCoverage = collector.getFinalCoverage(),
                globalResults = utils.summarizeCoverage(removeFiles(rawCoverage, root, thresholds.global.excludes)),
                eachResults = removeFiles(rawCoverage, root, thresholds.each.excludes);

            // Summarize per-file results and mutate original results.
            Object.keys(eachResults).forEach(function (key) {
                eachResults[key] = utils.summarizeFileCoverage(eachResults[key]);
            });

            if (config.verbose) {
                console.log('Compare actuals against thresholds');
                console.log(JSON.stringify({ global: globalResults, each: eachResults, thresholds: thresholds }, undefined, 4));
            }

            function check(name, thresholds, actuals) {
                [
                    "statements",
                    "branches",
                    "lines",
                    "functions"
                ].forEach(function (key) {
                    var actual = actuals[key].pct,
                        actualUncovered = actuals[key].total - actuals[key].covered,
                        threshold = thresholds[key];

                    if (threshold < 0) {
                        if (threshold * -1 < actualUncovered) {
                            errors.push('ERROR: Uncovered count for ' + key + ' (' + actualUncovered +
                                ') exceeds ' + name + ' threshold (' + -1 * threshold + ')');
                        }
                    } else {
                        if (actual < threshold) {
                            errors.push('ERROR: Coverage for ' + key + ' (' + actual +
                                '%) does not meet ' + name + ' threshold (' + threshold + '%)');
                        }
                    }
                });
            }

            check("global", thresholds.global, globalResults);

            Object.keys(eachResults).forEach(function (key) {
                check("per-file" + " (" + key + ") ", thresholds.each, eachResults[key]);
            });

            return callback(errors.length === 0 ? null : errors.join("\n"));
        });
    }
});

module.exports = CheckCoverageCommand;




================================================
FILE: lib/command/common/run-with-cover.js
================================================
/*
 Copyright (c) 2012, Yahoo! Inc.  All rights reserved.
 Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms.
 */
var Module = require('module'),
    path = require('path'),
    fs = require('fs'),
    nopt = require('nopt'),
    which = require('which'),
    mkdirp = require('mkdirp'),
    existsSync = fs.existsSync || path.existsSync,
    inputError = require('../../util/input-error'),
    matcherFor = require('../../util/file-matcher').matcherFor,
    Instrumenter = require('../../instrumenter'),
    Collector = require('../../collector'),
    formatOption = require('../../util/help-formatter').formatOption,
    hook = require('../../hook'),
    Reporter = require('../../reporter'),
    resolve = require('resolve'),
    configuration = require('../../config');

function usage(arg0, command) {

    console.error('\nUsage: ' + arg0 + ' ' + command + ' [<options>] <executable-js-file-or-command> [-- <arguments-to-jsfile>]\n\nOptions are:\n\n'
        + [
            formatOption('--config <path-to-config>', 'the configuration file to use, defaults to .istanbul.yml'),
            formatOption('--root <path> ', 'the root path to look for files to instrument, defaults to .'),
            formatOption('-x <exclude-pattern> [-x <exclude-pattern>]', 'one or more glob patterns e.g. "**/vendor/**"'),
            formatOption('-i <include-pattern> [-i <include-pattern>]', 'one or more glob patterns e.g. "**/*.js"'),
            formatOption('--[no-]default-excludes', 'apply default excludes [ **/node_modules/**, **/test/**, **/tests/** ], defaults to true'),
            formatOption('--hook-run-in-context', 'hook vm.runInThisContext in addition to require (supports RequireJS), defaults to false'),
            formatOption('--post-require-hook <file> | <module>', 'JS module that exports a function for post-require processing'),
            formatOption('--report <format> [--report <format>] ', 'report format, defaults to lcov (= lcov.info + HTML)'),
            formatOption('--dir <report-dir>', 'report directory, defaults to ./coverage'),
            formatOption('--print <type>', 'type of report to print to console, one of summary (default), detail, both or none'),
            formatOption('--verbose, -v', 'verbose mode'),
            formatOption('--[no-]preserve-comments', 'remove / preserve comments in the output, defaults to false'),
            formatOption('--include-all-sources', 'instrument all unused sources after running tests, defaults to false'),
            formatOption('--[no-]include-pid', 'include PID in output coverage filename')
        ].join('\n\n') + '\n');
    console.error('\n');
}

function run(args, commandName, enableHooks, callback) {

    var template = {
            config: path,
            root: path,
            x: [ Array, String ],
            report: [Array, String ],
            dir: path,
            verbose: Boolean,
            yui: Boolean,
            'default-excludes': Boolean,
            print: String,
            'self-test': Boolean,
            'hook-run-in-context': Boolean,
            'post-require-hook': String,
            'preserve-comments': Boolean,
            'include-all-sources': Boolean,
            'preload-sources': Boolean,
            i: [ Array, String ],
            'include-pid': Boolean
        },
        opts = nopt(template, { v : '--verbose' }, args, 0),
        overrides = {
            verbose: opts.verbose,
            instrumentation: {
                root: opts.root,
                'default-excludes': opts['default-excludes'],
                excludes: opts.x,
                'include-all-sources': opts['include-all-sources'],
                'preload-sources': opts['preload-sources'],
                'include-pid': opts['include-pid']
            },
            reporting: {
                reports: opts.report,
                print: opts.print,
                dir: opts.dir
            },
            hooks: {
                'hook-run-in-context': opts['hook-run-in-context'],
                'post-require-hook': opts['post-require-hook'],
                'handle-sigint': opts['handle-sigint']
            }
        },
        config = configuration.loadFile(opts.config, overrides),
        verbose = config.verbose,
        cmdAndArgs = opts.argv.remain,
        preserveComments = opts['preserve-comments'],
        includePid = opts['include-pid'],
        cmd,
        cmdArgs,
        reportingDir,
        reporter = new Reporter(config),
        runFn,
        excludes;

    if (cmdAndArgs.length === 0) {
        return callback(inputError.create('Need a filename argument for the ' + commandName + ' command!'));
    }

    cmd = cmdAndArgs.shift();
    cmdArgs = cmdAndArgs;

    if (!existsSync(cmd)) {
        try {
            cmd = which.sync(cmd);
        } catch (ex) {
            return callback(inputError.create('Unable to resolve file [' + cmd + ']'));
        }
    } else {
        cmd = path.resolve(cmd);
    }

    runFn = function () {
        process.argv = ["node", cmd].concat(cmdArgs);
        if (verbose) {
            console.log('Running: ' + process.argv.join(' '));
        }
        process.env.running_under_istanbul=1;
        Module.runMain(cmd, null, true);
    };

    excludes = config.instrumentation.excludes(true);

    if (enableHooks) {
        reportingDir = path.resolve(config.reporting.dir());
        mkdirp.sync(reportingDir); //ensure we fail early if we cannot do this
        reporter.dir = reportingDir;
        reporter.addAll(config.reporting.reports());
        if (config.reporting.print() !== 'none') {
            switch (config.reporting.print()) {
            case 'detail':
                reporter.add('text');
                break;
            case 'both':
                reporter.add('text');
                reporter.add('text-summary');
                break;
            default:
                reporter.add('text-summary');
                break;
            }
        }

        excludes.push(path.relative(process.cwd(), path.join(reportingDir, '**', '*')));
        matcherFor({
            root: config.instrumentation.root() || process.cwd(),
            includes: opts.i || config.instrumentation.extensions().map(function (ext) {
                return '**/*' + ext;
            }),
            excludes: excludes
        },
            function (err, matchFn) {
                if (err) { return callback(err); }

                var coverageVar = '$$cov_' + new Date().getTime() + '$$',
                    instrumenter = new Instrumenter({ coverageVariable: coverageVar , preserveComments: preserveComments}),
                    transformer = instrumenter.instrumentSync.bind(instrumenter),
                    hookOpts = { verbose: verbose, extensions: config.instrumentation.extensions() },
                    postRequireHook = config.hooks.postRequireHook(),
                    postLoadHookFile;

                if (postRequireHook) {
                    postLoadHookFile = path.resolve(postRequireHook);
                } else if (opts.yui) { //EXPERIMENTAL code: do not rely on this in anyway until the docs say it is allowed
                    postLoadHookFile = path.resolve(__dirname, '../../util/yui-load-hook');
                }

                if (postRequireHook) {
                    if (!existsSync(postLoadHookFile)) { //assume it is a module name and resolve it
                        try {
                            postLoadHookFile = resolve.sync(postRequireHook, { basedir: process.cwd() });
                        } catch (ex) {
                            if (verbose) { console.error('Unable to resolve [' + postRequireHook + '] as a node module'); }
                            callback(ex);
                            return;
                        }
                    }
                }
                if (postLoadHookFile) {
                    if (verbose) { console.error('Use post-load-hook: ' + postLoadHookFile); }
                    hookOpts.postLoadHook = require(postLoadHookFile)(matchFn, transformer, verbose);
                }

                if (opts['self-test']) {
                    hook.unloadRequireCache(matchFn);
                }
                // runInThisContext is used by RequireJS [issue #23]
                if (config.hooks.hookRunInContext()) {
                    hook.hookRunInThisContext(matchFn, transformer, hookOpts);
                }
                hook.hookRequire(matchFn, transformer, hookOpts);

                //initialize the global variable to stop mocha from complaining about leaks
                global[coverageVar] = {};

                // enable passing --handle-sigint to write reports on SIGINT.
                // This allows a user to manually kill a process while
                // still getting the istanbul report.
                if (config.hooks.handleSigint()) {
                    process.once('SIGINT', process.exit);
                }

                process.once('exit', function () {
                    var pidExt = includePid ? ('-' + process.pid) : '',
                        file = path.resolve(reportingDir, 'coverage' + pidExt + '.json'),
                        collector,
                        cov;
                    if (typeof global[coverageVar] === 'undefined' || Object.keys(global[coverageVar]).length === 0) {
                        console.error('No coverage information was collected, exit without writing coverage information');
                        return;
                    } else {
                        cov = global[coverageVar];
                    }
                    //important: there is no event loop at this point
                    //everything that happens in this exit handler MUST be synchronous
                    if (config.instrumentation.includeAllSources()) {
                        // Files that are not touched by code ran by the test runner is manually instrumented, to
                        // illustrate the missing coverage.
                        matchFn.files.forEach(function (file) {
                            if (!cov[file]) {
                                transformer(fs.readFileSync(file, 'utf-8'), file);

                                // When instrumenting the code, istanbul will give each FunctionDeclaration a value of 1 in coverState.s,
                                // presumably to compensate for function hoisting. We need to reset this, as the function was not hoisted,
                                // as it was never loaded.
                                Object.keys(instrumenter.coverState.s).forEach(function (key) {
                                    instrumenter.coverState.s[key] = 0;
                                });

                                cov[file] = instrumenter.coverState;
                            }
                        });
                    }
                    mkdirp.sync(reportingDir); //yes, do this again since some test runners could clean the dir initially created
                    if (config.reporting.print() !== 'none') {
                        console.error('=============================================================================');
                        console.error('Writing coverage object [' + file + ']');
                    }
                    fs.writeFileSync(file, JSON.stringify(cov), 'utf8');
                    collector = new Collector();
                    collector.add(cov);
                    if (config.reporting.print() !== 'none') {
                        console.error('Writing coverage reports at [' + reportingDir + ']');
                        console.error('=============================================================================');
                    }
                    reporter.write(collector, true, callback);
                });
                runFn();
            });
    } else {
        runFn();
    }
}

module.exports = {
    run: run,
    usage: usage
};


================================================
FILE: lib/command/cover.js
================================================
/*
 Copyright (c) 2012, Yahoo! Inc.  All rights reserved.
 Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms.
 */

var runWithCover = require('./common/run-with-cover'),
    util = require('util'),
    Command = require('./index');

function CoverCommand() {
    Command.call(this);
}

CoverCommand.TYPE = 'cover';
util.inherits(CoverCommand, Command);

Command.mix(CoverCommand, {
    synopsis: function () {
        return "transparently adds coverage information to a node command. Saves coverage.json and reports at the end of execution";
    },

    usage: function () {
        runWithCover.usage(this.toolName(), this.type());
    },

    run: function (args, callback) {
        runWithCover.run(args, this.type(), true, callback);
    }
});


module.exports = CoverCommand;



================================================
FILE: lib/command/help.js
================================================
/*
 Copyright (c) 2012, Yahoo! Inc.  All rights reserved.
 Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms.
 */

var Command = require('./index.js'),
    util = require('util'),
    formatOption = require('../util/help-formatter').formatOption,
    VERSION = require('../../index').VERSION,
    configuration = require('../config'),
    yaml = require('js-yaml'),
    formatPara = require('../util/help-formatter').formatPara;

function showConfigHelp(toolName) {

    console.error('\nConfiguring ' + toolName);
    console.error('====================');
    console.error('\n' +
        formatPara(toolName + ' can be configured globally using a .istanbul.yml YAML file ' +
            'at the root of your source tree. Every command also accepts a --config=<config-file> argument to ' +
            'customize its location per command. The alternate config file can be in YAML, JSON or node.js ' +
            '(exporting the config object).'));
    console.error('\n' +
        formatPara('The config file currently has four sections for instrumentation, reporting, hooks, ' +
            'and checking. Note that certain commands (like `cover`) use information from multiple sections.'));
    console.error('\n' +
        formatPara('Keys in the config file usually correspond to command line parameters with the same name. ' +
            'The verbose option for every command shows you the exact configuration used. See the api ' +
            'docs for an explanation of each key.'));

    console.error('\n' +
        formatPara('You only need to specify the keys that you want to override. Your overrides will be merged ' +
            'with the default config.'));
    console.error('\nThe default configuration is as follows:\n');
    console.error(yaml.safeDump(configuration.defaultConfig(), { indent: 4, flowLevel: 3 }));
    console.error('\n' +
        formatPara('The `watermarks` section does not have a command line equivalent. It allows you to set up ' +
            'low and high watermark percentages for reporting. These are honored by all reporters that colorize ' +
            'their output based on low/ medium/ high coverage.'));
    console.error('\n' +
        formatPara('The `reportConfig` section allows you to configure each report format independently ' +
            'and has no command-line equivalent either.'));
    console.error('\n' +
        formatPara('The `check` section configures minimum threshold enforcement for coverage results. ' +
            '`global` applies to all files together and `each` on a per-file basis. A list of files can ' +
            'be excluded from enforcement relative to root via the `exclude` property.'));
    console.error('');
}

function HelpCommand() {
    Command.call(this);
}

HelpCommand.TYPE = 'help';
util.inherits(HelpCommand, Command);

Command.mix(HelpCommand, {
    synopsis: function () {
        return "shows help";
    },

    usage: function () {

        console.error('\nUsage: ' + this.toolName() + ' ' + this.type() + ' config | <command>\n');
        console.error('`config` provides help with istanbul configuration\n');
        console.error('Available commands are:\n');

        var commandObj;
        Command.getCommandList().forEach(function (cmd) {
            commandObj = Command.create(cmd);
            console.error(formatOption(cmd, commandObj.synopsis()));
            console.error("\n");
        });
        console.error("Command names can be abbreviated as long as the abbreviation is unambiguous");
        console.error(this.toolName() + ' version:' + VERSION);
        console.error("\n");
    },
    run: function (args, callback) {
        var command;
        if (args.length === 0) {
            this.usage();
        } else {
            if (args[0] === 'config') {
                showConfigHelp(this.toolName());
            } else {
                try {
                    command = Command.create(args[0]);
                    command.usage('istanbul', Command.resolveCommandName(args[0]));
                } catch (ex) {
                    console.error('Invalid command: ' + args[0]);
                    this.usage();
                }
            }
        }
        return callback();
    }
});


module.exports = HelpCommand;




================================================
FILE: lib/command/index.js
================================================
/*
 Copyright (c) 2012, Yahoo! Inc.  All rights reserved.
 Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms.
 */

var Factory = require('../util/factory'),
    factory = new Factory('command', __dirname, true);

function Command() {}
// add register, create, mix, loadAll, getCommandList, resolveCommandName to the Command object
factory.bindClassMethods(Command);

Command.prototype = {
    toolName: function () {
        return require('../util/meta').NAME;
    },

    type: function () {
        return this.constructor.TYPE;
    },
    synopsis: /* istanbul ignore next: base method */ function () {
        return "the developer has not written a one-line summary of the " + this.type() + " command";
    },
    usage: /* istanbul ignore next: base method */ function () {
        console.error("the developer has not provided a usage for the " + this.type() + " command");
    },
    run: /* istanbul ignore next: abstract method */ function (args, callback) {
        return callback(new Error("run: must be overridden for the " + this.type() + " command"));
    }
};

module.exports = Command;



================================================
FILE: lib/command/instrument.js
================================================
/*
 Copyright (c) 2012, Yahoo! Inc.  All rights reserved.
 Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms.
 */

var path = require('path'),
    mkdirp = require('mkdirp'),
    once = require('once'),
    async = require('async'),
    fs = require('fs'),
    filesFor = require('../util/file-matcher').filesFor,
    nopt = require('nopt'),
    Instrumenter = require('../instrumenter'),
    inputError = require('../util/input-error'),
    formatOption = require('../util/help-formatter').formatOption,
    util = require('util'),
    Command = require('./index'),
    Collector = require('../collector'),
    configuration = require('../config'),
    verbose;


/*
 * Chunk file size to use when reading non JavaScript files in memory
 * and copying them over when using complete-copy flag.
 */
var READ_FILE_CHUNK_SIZE = 64 * 1024;

function BaselineCollector(instrumenter) {
    this.instrumenter = instrumenter;
    this.collector = new Collector();
    this.instrument = instrumenter.instrument.bind(this.instrumenter);

    var origInstrumentSync = instrumenter.instrumentSync;
    this.instrumentSync = function () {
        var args = Array.prototype.slice.call(arguments),
            ret = origInstrumentSync.apply(this.instrumenter, args),
            baseline = this.instrumenter.lastFileCoverage(),
            coverage = {};
        coverage[baseline.path] = baseline;
        this.collector.add(coverage);
        return ret;
    };
    //monkey patch the instrumenter to call our version instead
    instrumenter.instrumentSync = this.instrumentSync.bind(this);
}

BaselineCollector.prototype = {
    getCoverage: function () {
        return this.collector.getFinalCoverage();
    }
};


function processFiles(instrumenter, inputDir, outputDir, relativeNames, extensions) {
    var processor = function (name, callback) {
            var inputFile = path.resolve(inputDir, name),
                outputFile = path.resolve(outputDir, name),
                inputFileExtenstion = path.extname(inputFile),
                isJavaScriptFile = extensions.indexOf(inputFileExtenstion) > -1,
                oDir = path.dirname(outputFile),
                readStream, writeStream;

            callback = once(callback);
            mkdirp.sync(oDir);

            if (fs.statSync(inputFile).isDirectory()) {
                return callback(null, name);
            }

            if (isJavaScriptFile) {
                fs.readFile(inputFile, 'utf8', function (err, data) {
                    if (err) { return callback(err, name); }
                    instrumenter.instrument(data, inputFile, function (iErr, instrumented) {
                        if (iErr) { return callback(iErr, name); }
                        fs.writeFile(outputFile, instrumented, 'utf8', function (err) {
                            return callback(err, name);
                        });
                    });
                });
            }
            else {
                // non JavaScript file, copy it as is
                readStream = fs.createReadStream(inputFile, {'bufferSize': READ_FILE_CHUNK_SIZE});
                writeStream = fs.createWriteStream(outputFile);

                readStream.on('error', callback);
                writeStream.on('error', callback);

                readStream.pipe(writeStream);
                readStream.on('end', function() {
                    callback(null, name);
                });
            }
        },
        q = async.queue(processor, 10),
        errors = [],
        count = 0,
        startTime = new Date().getTime();

    q.push(relativeNames, function (err, name) {
        var inputFile, outputFile;
        if (err) {
            errors.push({ file: name, error: err.message || err.toString() });
            inputFile = path.resolve(inputDir, name);
            outputFile = path.resolve(outputDir, name);
            fs.writeFileSync(outputFile, fs.readFileSync(inputFile));
        }
        if (verbose) {
            console.log('Processed: ' + name);
        } else {
            if (count % 100 === 0) { process.stdout.write('.'); }
        }
        count += 1;
    });

    q.drain = function () {
        var endTime = new Date().getTime();
        console.log('\nProcessed [' + count + '] files in ' + Math.floor((endTime - startTime) / 1000) + ' secs');
        if (errors.length > 0) {
            console.log('The following ' + errors.length + ' file(s) had errors and were copied as-is');
            console.log(errors);
        }
    };
}


function InstrumentCommand() {
    Command.call(this);
}

InstrumentCommand.TYPE = 'instrument';
util.inherits(InstrumentCommand, Command);

Command.mix(InstrumentCommand, {
    synopsis: function synopsis() {
        return "instruments a file or a directory tree and writes the instrumented code to the desired output location";
    },

    usage: function () {
        console.error('\nUsage: ' + this.toolName() + ' ' + this.type() + ' <options> <file-or-directory>\n\nOptions are:\n\n' +
            [
                formatOption('--config <path-to-config>', 'the configuration file to use, defaults to .istanbul.yml'),
                formatOption('--output <file-or-dir>', 'The output file or directory. This is required when the input is a directory, ' +
                    'defaults to standard output when input is a file'),
                formatOption('-x <exclude-pattern> [-x <exclude-pattern>]', 'one or more glob patterns (e.g. "**/vendor/**" to ignore all files ' +
                    'under a vendor directory). Also see the --default-excludes option'),
                formatOption('--variable <global-coverage-variable-name>', 'change the variable name of the global coverage variable from the ' +
                    'default value of `__coverage__` to something else'),
                formatOption('--embed-source', 'embed source code into the coverage object, defaults to false'),
                formatOption('--[no-]compact', 'produce [non]compact output, defaults to compact'),
                formatOption('--[no-]preserve-comments', 'remove / preserve comments in the output, defaults to false'),
                formatOption('--[no-]complete-copy', 'also copy non-javascript files to the ouput directory as is, defaults to false'),
                formatOption('--save-baseline', 'produce a baseline coverage.json file out of all files instrumented'),
                formatOption('--baseline-file <file>', 'filename of baseline file, defaults to coverage/coverage-baseline.json'),
                formatOption('--es-modules', 'source code uses es import/export module syntax')
            ].join('\n\n') + '\n');
        console.error('\n');
    },

    run: function (args, callback) {

        var template = {
                config: path,
                output: path,
                x: [Array, String],
                variable: String,
                compact: Boolean,
                'complete-copy': Boolean,
                verbose: Boolean,
                'save-baseline': Boolean,
                'baseline-file': path,
                'embed-source': Boolean,
                'preserve-comments': Boolean,
                'es-modules': Boolean
            },
            opts = nopt(template, { v : '--verbose' }, args, 0),
            overrides = {
                verbose: opts.verbose,
                instrumentation: {
                    variable: opts.variable,
                    compact: opts.compact,
                    'embed-source': opts['embed-source'],
                    'preserve-comments': opts['preserve-comments'],
                    excludes: opts.x,
                    'complete-copy': opts['complete-copy'],
                    'save-baseline': opts['save-baseline'],
                    'baseline-file': opts['baseline-file'],
                    'es-modules': opts['es-modules']
                }
            },
            config = configuration.loadFile(opts.config, overrides),
            iOpts = config.instrumentation,
            cmdArgs = opts.argv.remain,
            file,
            stats,
            stream,
            includes,
            instrumenter,
            needBaseline = iOpts.saveBaseline(),
            baselineFile = path.resolve(iOpts.baselineFile()),
            output = opts.output;

        verbose = config.verbose;
        if (cmdArgs.length !== 1) {
            return callback(inputError.create('Need exactly one filename/ dirname argument for the instrument command!'));
        }

        if (iOpts.completeCopy()) {
            includes = ['**/*'];
        }
        else {
            includes = iOpts.extensions().map(function(ext) {
                return '**/*' + ext;
            });
        }

        instrumenter = new Instrumenter({
            coverageVariable: iOpts.variable(),
            embedSource: iOpts.embedSource(),
            noCompact: !iOpts.compact(),
            preserveComments: iOpts.preserveComments(),
            esModules: iOpts.esModules()
        });

        if (needBaseline) {
            mkdirp.sync(path.dirname(baselineFile));
            instrumenter = new BaselineCollector(instrumenter);
            process.on('exit', function () {
                console.log('Saving baseline coverage at: ' + baselineFile);
                fs.writeFileSync(baselineFile, JSON.stringify(instrumenter.getCoverage()), 'utf8');
            });
        }

        file = path.resolve(cmdArgs[0]);
        stats = fs.statSync(file);
        if (stats.isDirectory()) {
            if (!output) { return callback(inputError.create('Need an output directory [-o <dir>] when input is a directory!')); }
            if (output === file) { return callback(inputError.create('Cannot instrument into the same directory/ file as input!')); }
            mkdirp.sync(output);
            filesFor({
                root: file,
                includes: includes,
                excludes: opts.x || iOpts.excludes(false), // backwards-compat, *sigh*
                relative: true
            }, function (err, files) {
                if (err) { return callback(err); }
                processFiles(instrumenter, file, output, files, iOpts.extensions());
            });
        } else {
            if (output) {
                stream = fs.createWriteStream(output);
            } else {
                stream = process.stdout;
            }
            stream.write(instrumenter.instrumentSync(fs.readFileSync(file, 'utf8'), file));
            if (stream !== process.stdout) {
                stream.end();
            }
        }
    }
});

module.exports = InstrumentCommand;



================================================
FILE: lib/command/report.js
================================================
/*
 Copyright (c) 2012, Yahoo! Inc.  All rights reserved.
 Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms.
 */

var nopt = require('nopt'),
    Report = require('../report'),
    Reporter = require('../reporter'),
    path = require('path'),
    fs = require('fs'),
    Collector = require('../collector'),
    helpFormatter = require('../util/help-formatter'),
    formatOption = helpFormatter.formatOption,
    formatPara = helpFormatter.formatPara,
    filesFor = require('../util/file-matcher').filesFor,
    util = require('util'),
    Command = require('./index'),
    configuration = require('../config');

function ReportCommand() {
    Command.call(this);
}

ReportCommand.TYPE = 'report';
util.inherits(ReportCommand, Command);

function printDeprecationMessage(pat, fmt) {
    console.error('**********************************************************************');
    console.error('DEPRECATION WARNING! You are probably using the old format of the report command');
    console.error('This will stop working soon, see `istanbul help report` for the new command format');
    console.error('Assuming you meant: istanbul report --include=' + pat + ' ' + fmt);
    console.error('**********************************************************************');
}

Command.mix(ReportCommand, {
    synopsis: function () {
        return "writes reports for coverage JSON objects produced in a previous run";
    },

    usage: function () {
        console.error('\nUsage: ' + this.toolName() + ' ' + this.type() + ' <options> [ <format> ... ]\n\nOptions are:\n\n' +
            [
                formatOption('--config <path-to-config>', 'the configuration file to use, defaults to .istanbul.yml'),
                formatOption('--root <input-directory>', 'The input root directory for finding coverage files'),
                formatOption('--dir <report-directory>', 'The output directory where files will be written. This defaults to ./coverage/'),
                formatOption('--include <glob>', 'The glob pattern to select one or more coverage files, defaults to **/coverage*.json'),
                formatOption('--verbose, -v', 'verbose mode')
            ].join('\n\n'));

        console.error('\n');
        console.error('<format> is one of ');
        Report.getReportList().forEach(function (name) {
           console.error(formatOption(name, Report.create(name).synopsis()));
        });
        console.error("");
        console.error(formatPara([
            'Default format is lcov unless otherwise specified in the config file.',
            'In addition you can tweak the file names for various reports using the config file.',
            'Type `istanbul help config` to see what can be tweaked.'
        ].join(' ')));
        console.error('\n');
    },

    run: function (args, callback) {

        var template = {
                config: path,
                root: path,
                dir: path,
                include: String,
                verbose: Boolean
            },
            opts = nopt(template, { v : '--verbose' }, args, 0),
            includePattern = opts.include || '**/coverage*.json',
            root,
            collector = new Collector(),
            config = configuration.loadFile(opts.config, {
                verbose: opts.verbose,
                reporting: {
                    dir: opts.dir
                }
            }),
            formats = opts.argv.remain,
            reporter = new Reporter(config);

        // Start: backward compatible processing
        if (formats.length === 2 &&
                Report.getReportList().indexOf(formats[1]) < 0) {
            includePattern = formats[1];
            formats = [ formats[0] ];
            printDeprecationMessage(includePattern, formats[0]);
        }
        // End: backward compatible processing

        if (formats.length === 0) {
            formats = config.reporting.reports();
        }
        if (formats.length === 0) {
            formats = [ 'lcov' ];
        }
        reporter.addAll(formats);

        root = opts.root || process.cwd();
        filesFor({
            root: root,
            includes: [ includePattern ]
        }, function (err, files) {
            if (err) { throw err; }
            files.forEach(function (file) {
                var coverageObject =  JSON.parse(fs.readFileSync(file, 'utf8'));
                collector.add(coverageObject);
            });
            reporter.write(collector, false, function (err) {
                console.log('Done');
                return callback(err);
            });
        });
    }
});

module.exports = ReportCommand;




================================================
FILE: lib/command/test.js
================================================
/*
 Copyright (c) 2012, Yahoo! Inc.  All rights reserved.
 Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms.
 */

var runWithCover = require('./common/run-with-cover'),
    util = require('util'),
    Command = require('./index');

function TestCommand() {
    Command.call(this);
}

TestCommand.TYPE = 'test';
util.inherits(TestCommand, Command);

Command.mix(TestCommand, {
    synopsis: function () {
        return "cover a node command only when npm_config_coverage is set. Use in an `npm test` script for conditional coverage";
    },

    usage: function () {
        runWithCover.usage(this.toolName(), this.type());
    },

    run: function (args, callback) {
        runWithCover.run(args, this.type(), !!process.env.npm_config_coverage, callback);
    }
});

module.exports = TestCommand;


================================================
FILE: lib/config.js
================================================
/*
 Copyright (c) 2013, Yahoo! Inc.  All rights reserved.
 Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms.
 */
var path = require('path'),
    fs = require('fs'),
    existsSync = fs.existsSync || path.existsSync,
    CAMEL_PATTERN = /([a-z])([A-Z])/g,
    YML_PATTERN = /\.ya?ml$/,
    yaml = require('js-yaml'),
    defaults = require('./report/common/defaults');

function defaultConfig(includeBackCompatAttrs) {
    var ret = {
        verbose: false,
        instrumentation: {
            root: '.',
            extensions: ['.js'],
            'default-excludes': true,
            excludes: [],
            'embed-source': false,
            variable: '__coverage__',
            compact: true,
            'preserve-comments': false,
            'complete-copy': false,
            'save-baseline': false,
            'baseline-file': './coverage/coverage-baseline.json',
            'include-all-sources': false,
            'include-pid': false,
            'es-modules': false
        },
        reporting: {
            print: 'summary',
            reports: [ 'lcov' ],
            dir: './coverage'
        },
        hooks: {
            'hook-run-in-context': false,
            'post-require-hook': null,
            'handle-sigint': false
        },
        check: {
            global: {
                statements: 0,
                lines: 0,
                branches: 0,
                functions: 0,
                excludes: [] // Currently list of files (root + path). For future, extend to patterns.
            },
            each: {
                statements: 0,
                lines: 0,
                branches: 0,
                functions: 0,
                excludes: []
            }
        }
    };
    ret.reporting.watermarks = defaults.watermarks();
    ret.reporting['report-config'] = defaults.defaultReportConfig();

    if (includeBackCompatAttrs) {
        ret.instrumentation['preload-sources'] = false;
    }

    return ret;
}

function dasherize(word) {
    return word.replace(CAMEL_PATTERN, function (match, lch, uch) {
        return lch + '-' + uch.toLowerCase();
    });
}
function isScalar(v) {
    if (v === null) { return true; }
    return v !== undefined && !Array.isArray(v) && typeof v !== 'object';
}

function isObject(v) {
    return typeof v === 'object' && v !== null && !Array.isArray(v);
}

function mergeObjects(explicit, template) {

    var ret = {};

    Object.keys(template).forEach(function (k) {
        var v1 = template[k],
            v2 = explicit[k];

        if (Array.isArray(v1)) {
            ret[k] = Array.isArray(v2) && v2.length > 0 ? v2 : v1;
        } else if (isObject(v1)) {
            v2 = isObject(v2) ? v2 : {};
            ret[k] = mergeObjects(v2, v1);
        } else {
            ret[k] = isScalar(v2) ? v2 : v1;
        }
    });
    return ret;
}

function mergeDefaults(explicit, implicit) {
    return mergeObjects(explicit || {}, implicit);
}

function addMethods() {
    var args = Array.prototype.slice.call(arguments),
        cons = args.shift();

    args.forEach(function (arg) {
        var method = arg,
            property = dasherize(arg);
        cons.prototype[method] = function () {
            return this.config[property];
        };
    });
}

/**
 * Object that returns instrumentation options
 * @class InstrumentOptions
 * @module config
 * @constructor
 * @param config the instrumentation part of the config object
 */
function InstrumentOptions(config) {
    if (config['preload-sources']) {
        console.error('The preload-sources option is deprecated, please use include-all-sources instead.');
        config['include-all-sources'] = config['preload-sources'];
    }
    this.config = config;
}

/**
 * returns if default excludes should be turned on. Used by the `cover` command.
 * @method defaultExcludes
 * @return {Boolean} true if default excludes should be turned on
 */
/**
 * returns if non-JS files should be copied during instrumentation. Used by the
 * `instrument` command.
 * @method completeCopy
 * @return {Boolean} true if non-JS files should be copied
 */
/**
 * returns if the source should be embedded in the instrumented code. Used by the
 * `instrument` command.
 * @method embedSource
 * @return {Boolean} true if the source should be embedded in the instrumented code
 */
/**
 * the coverage variable name to use. Used by the `instrument` command.
 * @method variable
 * @return {String} the coverage variable name to use
 */
/**
 * returns if the output should be compact JS. Used by the `instrument` command.
 * @method compact
 * @return {Boolean} true if the output should be compact
 */
/**
 * returns if comments should be preserved in the generated JS. Used by the
 * `cover` and `instrument` commands.
 * @method preserveComments
 * @return {Boolean} true if comments should be preserved in the generated JS
 */
/**
 * returns if a zero-coverage baseline file should be written as part of
 * instrumentation. This allows reporting to display numbers for files that have
 * no tests. Used by the  `instrument` command.
 * @method saveBaseline
 * @return {Boolean} true if a baseline coverage file should be written.
 */
/**
 * Sets the baseline coverage filename. Used by the  `instrument` command.
 * @method baselineFile
 * @return {String} the name of the baseline coverage file.
 */
/**
 * returns if comments the JS to instrument contains es6 Module syntax.
 * @method esModules
 * @return {Boolean} true if code contains es6 import/export statements.
 */
/**
 * returns if the coverage filename should include the PID. Used by the  `instrument` command.
 * @method includePid
 * @return {Boolean} true to include pid in coverage filename.
 */


addMethods(InstrumentOptions,
    'extensions', 'defaultExcludes', 'completeCopy',
    'embedSource', 'variable', 'compact', 'preserveComments',
    'saveBaseline', 'baselineFile', 'esModules',
    'includeAllSources', 'includePid');

/**
 * returns the root directory used by istanbul which is typically the root of the
 * source tree. Used by the `cover` and `report` commands.
 * @method root
 * @return {String} the root directory used by istanbul.
 */
InstrumentOptions.prototype.root = function () { return path.resolve(this.config.root); };
/**
 * returns an array of glob patterns that should be excluded for instrumentation.
 * Used by the `instrument` and `cover` commands.
 * @method excludes
 * @return {Array} an array of glob patterns that should be excluded for
 *  instrumentation.
 */
InstrumentOptions.prototype.excludes = function (excludeTests) {
    var defs;
    if (this.defaultExcludes()) {
        defs = [ '**/node_modules/**' ];
        if (excludeTests) {
            defs = defs.concat(['**/test/**', '**/tests/**']);
        }
        return defs.concat(this.config.excludes);
    }
    return this.config.excludes;
};

/**
 * Object that returns reporting options
 * @class ReportingOptions
 * @module config
 * @constructor
 * @param config the reporting part of the config object
 */
function ReportingOptions(config) {
    this.config = config;
}

/**
 * returns the kind of information to be printed on the console. May be one
 * of `summary`, `detail`, `both` or `none`. Used by the
 * `cover` command.
 * @method print
 * @return {String} the kind of information to print to the console at the end
 * of the `cover` command execution.
 */
/**
 * returns a list of reports that should be generated at the end of a run. Used
 * by the `cover` and `report` commands.
 * @method reports
 * @return {Array} an array of reports that should be produced
 */
/**
 * returns the directory under which reports should be generated. Used by the
 * `cover` and `report` commands.
 *
 * @method dir
 * @return {String} the directory under which reports should be generated.
 */
/**
 * returns an object that has keys that are report format names and values that are objects
 * containing detailed configuration for each format. Running `istanbul help config`
 * will give you all the keys per report format that can be overridden.
 * Used by the `cover` and `report` commands.
 * @method reportConfig
 * @return {Object} detailed report configuration per report format.
 */
addMethods(ReportingOptions, 'print', 'reports', 'dir', 'reportConfig');

function isInvalidMark(v, key) {
    var prefix = 'Watermark for [' + key + '] :';

    if (v.length !== 2) {
        return prefix + 'must be an array of length 2';
    }
    v[0] = Number(v[0]);
    v[1] = Number(v[1]);

    if (isNaN(v[0]) || isNaN(v[1])) {
        return prefix + 'must have valid numbers';
    }
    if (v[0] < 0 || v[1] < 0) {
        return prefix + 'must be positive numbers';
    }
    if (v[1] > 100) {
        return prefix + 'cannot exceed 100';
    }
    if (v[1] <= v[0]) {
        return prefix + 'low must be less than high';
    }
    return null;
}

/**
 * returns the low and high watermarks to be used to designate whether coverage
 * is `low`, `medium` or `high`. Statements, functions, branches and lines can
 * have independent watermarks. These are respected by all reports
 * that color for low, medium and high coverage. See the default configuration for exact syntax
 * using `istanbul help config`. Used by the `cover` and `report` commands.
 *
 * @method watermarks
 * @return {Object} an object containing low and high watermarks for statements,
 *  branches, functions and lines.
 */
ReportingOptions.prototype.watermarks = function () {
    var v = this.config.watermarks,
        defs = defaults.watermarks(),
        ret = {};

    Object.keys(defs).forEach(function (k) {
        var mark = v[k], //it will already be a non-zero length array because of the way the merge works
            message = isInvalidMark(mark, k);
        if (message) {
            console.error(message);
            ret[k] = defs[k];
        } else {
            ret[k] = mark;
        }
    });
    return ret;
};

/**
 * Object that returns hook options. Note that istanbul does not provide an
 * option to hook `require`. This is always done by the `cover` command.
 * @class HookOptions
 * @module config
 * @constructor
 * @param config the hooks part of the config object
 */
function HookOptions(config) {
    this.config = config;
}

/**
 * returns if `vm.runInThisContext` needs to be hooked, in addition to the standard
 * `require` hooks added by istanbul. This should be true for code that uses
 * RequireJS for example. Used by the `cover` command.
 * @method hookRunInContext
 * @return {Boolean} true if `vm.runInThisContext` needs to be hooked for coverage
 */
/**
 * returns a path to JS file or a dependent module that should be used for
 * post-processing files after they have been required. See the `yui-istanbul` module for
 * an example of a post-require hook. This particular hook modifies the yui loader when
 * that file is required to add istanbul interceptors. Use by the `cover` command
 *
 * @method postRequireHook
 * @return {String} a path to a JS file or the name of a node module that needs
 * to be used as a `require` post-processor
 */
/**
 * returns if istanbul needs to add a SIGINT (control-c, usually) handler to
 * save coverage information. Useful for getting code coverage out of processes
 * that run forever and need a SIGINT to terminate.
 * @method handleSigint
 * @return {Boolean} true if SIGINT needs to be hooked to write coverage information
 */

addMethods(HookOptions, 'hookRunInContext', 'postRequireHook', 'handleSigint');

/**
 * represents the istanbul configuration and provides sub-objects that can
 * return instrumentation, reporting and hook options respectively.
 * Usage
 * -----
 *
 *      var configObj = require('istanbul').config.loadFile();
 *
 *      console.log(configObj.reporting.reports());
 *
 * @class Configuration
 * @module config
 * @param {Object} obj  the base object to use as the configuration
 * @param {Object} overrides optional - override attributes that are merged into
 *  the base config
 * @constructor
 */
function Configuration(obj, overrides) {

    var config = mergeDefaults(obj, defaultConfig(true));
    if (isObject(overrides)) {
        config = mergeDefaults(overrides, config);
    }
    if (config.verbose) {
        console.error('Using configuration');
        console.error('-------------------');
        console.error(yaml.safeDump(config, { indent: 4, flowLevel: 3 }));
        console.error('-------------------\n');
    }
    this.verbose = config.verbose;
    this.instrumentation = new InstrumentOptions(config.instrumentation);
    this.reporting = new ReportingOptions(config.reporting);
    this.hooks = new HookOptions(config.hooks);
    this.check = config.check; // Pass raw config sub-object.
}

/**
 * true if verbose logging is required
 * @property verbose
 * @type Boolean
 */
/**
 * instrumentation options
 * @property instrumentation
 * @type InstrumentOptions
 */
/**
 * reporting options
 * @property reporting
 * @type ReportingOptions
 */
/**
 * hook options
 * @property hooks
 * @type HookOptions
 */


function loadFile(file, overrides) {
    var defaultConfigFile = path.resolve('.istanbul.yml'),
        configObject;

    if (file) {
        if (!existsSync(file)) {
            throw new Error('Invalid configuration file specified:' + file);
        }
    } else {
        if (existsSync(defaultConfigFile)) {
            file = defaultConfigFile;
        }
    }

    if (file) {
        if (overrides && overrides.verbose === true) {
            console.error('Loading config: ' + file);
        }
        configObject = file.match(YML_PATTERN) ?
            yaml.safeLoad(fs.readFileSync(file, 'utf8'), { filename: file }) :
            require(path.resolve(file));
    }

    return new Configuration(configObject, overrides);
}

function loadObject(obj, overrides) {
    return new Configuration(obj, overrides);
}

/**
 * methods to load the configuration object.
 * Usage
 * -----
 *
 *      var config = require('istanbul').config,
 *          configObj = config.loadFile();
 *
 *      console.log(configObj.reporting.reports());
 *
 * @class Config
 * @module main
 * @static
 */
module.exports = {
    /**
     * loads the specified configuration file with optional overrides. Throws
     * when a file is specified and it is not found.
     * @method loadFile
     * @static
     * @param {String} file the file to load. If falsy, the default config file, if present, is loaded.
     *  If not a default config is used.
     * @param {Object} overrides - an object with override keys that are merged into the
     *  config object loaded
     * @return {Configuration} the config object with overrides applied
     */
    loadFile: loadFile,
    /**
     * loads the specified configuration object with optional overrides.
     * @method loadObject
     * @static
     * @param {Object} obj the object to use as the base configuration.
     * @param {Object} overrides - an object with override keys that are merged into the
     *  config object
     * @return {Configuration} the config object with overrides applied
     */
    loadObject: loadObject,
    /**
     * returns the default configuration object. Note that this is a plain object
     * and not a `Configuration` instance.
     * @method defaultConfig
     * @static
     * @return {Object} an object that represents the default config
     */
    defaultConfig: defaultConfig
};


================================================
FILE: lib/hook.js
================================================
/*
 Copyright (c) 2012, Yahoo! Inc.  All rights reserved.
 Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms.
 */

/**
 * provides a mechanism to transform code in the scope of `require` or `vm.createScript`.
 * This mechanism is general and relies on a user-supplied `matcher` function that determines when transformations should be
 * performed and a user-supplied `transformer` function that performs the actual transform.
 * Instrumenting code for coverage is one specific example of useful hooking.
 *
 * Note that both the `matcher` and `transformer` must execute synchronously.
 *
 * For the common case of matching filesystem paths based on inclusion/ exclusion patterns, use the `matcherFor`
 * function in the istanbul API to get a matcher.
 *
 * It is up to the transformer to perform processing with side-effects, such as caching, storing the original
 * source code to disk in case of dynamically generated scripts etc. The `Store` class can help you with this.
 *
 * Usage
 * -----
 *
 *      var hook = require('istanbul').hook,
 *          myMatcher = function (file) { return file.match(/foo/); },
 *          myTransformer = function (code, file) { return 'console.log("' + file + '");' + code; };
 *
 *      hook.hookRequire(myMatcher, myTransformer);
 *
 *      var foo = require('foo'); //will now print foo's module path to console
 *
 * @class Hook
 * @module main
 */
var path = require('path'),
    fs = require('fs'),
    Module = require('module'),
    vm = require('vm'),
    originalLoaders = {},
    originalCreateScript = vm.createScript,
    originalRunInThisContext = vm.runInThisContext;

function transformFn(matcher, transformer, verbose) {

    return function (code, filename) {
        var shouldHook = typeof filename === 'string' && matcher(path.resolve(filename)),
            transformed,
            changed = false;

        if (shouldHook) {
            if (verbose) {
                console.error('Module load hook: transform [' + filename + ']');
            }
            try {
                transformed = transformer(code, filename);
                changed = true;
            } catch (ex) {
                console.error('Transformation error; return original code');
                console.error(ex);
                transformed = code;
            }
        } else {
            transformed = code;
        }
        return { code: transformed, changed: changed };
    };
}

function unloadRequireCache(matcher) {
    if (matcher && typeof require !== 'undefined' && require && require.cache) {
        Object.keys(require.cache).forEach(function (filename) {
            if (matcher(filename)) {
                delete require.cache[filename];
            }
        });
    }
}
/**
 * hooks `require` to return transformed code to the node module loader.
 * Exceptions in the transform result in the original code being used instead.
 * @method hookRequire
 * @static
 * @param matcher {Function(filePath)} a function that is called with the absolute path to the file being
 *  `require`-d. Should return a truthy value when transformations need to be applied to the code, a falsy value otherwise
 * @param transformer {Function(code, filePath)} a function called with the original code and the associated path of the file
 *  from where the code was loaded. Should return the transformed code.
 * @param options {Object} options Optional.
 * @param {Boolean} [options.verbose] write a line to standard error every time the transformer is called
 * @param {Function} [options.postLoadHook] a function that is called with the name of the file being
 *  required. This is called after the require is processed irrespective of whether it was transformed.
 */
function hookRequire(matcher, transformer, options) {
    options = options || {};
    var extensions,
        fn = transformFn(matcher, transformer, options.verbose),
        postLoadHook = options.postLoadHook &&
            typeof options.postLoadHook === 'function' ? options.postLoadHook : null;

    extensions = options.extensions || ['.js'];

    extensions.forEach(function(ext){
        if (!(ext in originalLoaders)) {
            originalLoaders[ext] = Module._extensions[ext] || Module._extensions['.js'];
        }
        Module._extensions[ext] = function (module, filename) {
            var ret = fn(fs.readFileSync(filename, 'utf8'), filename);
            if (ret.changed) {
                module._compile(ret.code, filename);
            } else {
                originalLoaders[ext](module, filename);
            }
            if (postLoadHook) {
                postLoadHook(filename);
            }
        };
    });
}
/**
 * unhook `require` to restore it to its original state.
 * @method unhookRequire
 * @static
 */
function unhookRequire() {
    Object.keys(originalLoaders).forEach(function(ext) {
        Module._extensions[ext] = originalLoaders[ext];
    });
}
/**
 * hooks `vm.createScript` to return transformed code out of which a `Script` object will be created.
 * Exceptions in the transform result in the original code being used instead.
 * @method hookCreateScript
 * @static
 * @param matcher {Function(filePath)} a function that is called with the filename passed to `vm.createScript`
 *  Should return a truthy value when transformations need to be applied to the code, a falsy value otherwise
 * @param transformer {Function(code, filePath)} a function called with the original code and the filename passed to
 *  `vm.createScript`. Should return the transformed code.
 * @param options {Object} options Optional.
 * @param {Boolean} [options.verbose] write a line to standard error every time the transformer is called
 */
function hookCreateScript(matcher, transformer, opts) {
    opts = opts || {};
    var fn = transformFn(matcher, transformer, opts.verbose);
    vm.createScript = function (code, file) {
        var ret = fn(code, file);
        return originalCreateScript(ret.code, file);
    };
}

/**
 * unhooks vm.createScript, restoring it to its original state.
 * @method unhookCreateScript
 * @static
 */
function unhookCreateScript() {
    vm.createScript = originalCreateScript;
}


/**
 * hooks `vm.runInThisContext` to return transformed code.
 * @method hookRunInThisContext
 * @static
 * @param matcher {Function(filePath)} a function that is called with the filename passed to `vm.createScript`
 *  Should return a truthy value when transformations need to be applied to the code, a falsy value otherwise
 * @param transformer {Function(code, filePath)} a function called with the original code and the filename passed to
 *  `vm.createScript`. Should return the transformed code.
 * @param options {Object} options Optional.
 * @param {Boolean} [options.verbose] write a line to standard error every time the transformer is called
 */
function hookRunInThisContext(matcher, transformer, opts) {
    opts = opts || {};
    var fn = transformFn(matcher, transformer, opts.verbose);
    vm.runInThisContext = function (code, file) {
        var ret = fn(code, file);
        return originalRunInThisContext(ret.code, file);
    };
}

/**
 * unhooks vm.runInThisContext, restoring it to its original state.
 * @method unhookRunInThisContext
 * @static
 */
function unhookRunInThisContext() {
    vm.runInThisContext = originalRunInThisContext;
}


module.exports = {
    hookRequire: hookRequire,
    unhookRequire: unhookRequire,
    hookCreateScript: hookCreateScript,
    unhookCreateScript: unhookCreateScript,
    hookRunInThisContext : hookRunInThisContext,
    unhookRunInThisContext : unhookRunInThisContext,
    unloadRequireCache: unloadRequireCache
};




================================================
FILE: lib/instrumenter.js
================================================
/*
 Copyright (c) 2012, Yahoo! Inc.  All rights reserved.
 Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms.
 */

/*global esprima, escodegen, window */
(function (isNode) {
    "use strict";
    var SYNTAX,
        nodeType,
        ESP = isNode ? require('esprima') : esprima,
        ESPGEN = isNode ? require('escodegen') : escodegen,  //TODO - package as dependency
        crypto = isNode ? require('crypto') : null,
        LEADER_WRAP = '(function () { ',
        TRAILER_WRAP = '\n}());',
        COMMENT_RE = /^\s*istanbul\s+ignore\s+(if|else|next)(?=\W|$)/,
        astgen,
        preconditions,
        cond,
        isArray = Array.isArray;

    /* istanbul ignore if: untestable */
    if (!isArray) {
        isArray = function (thing) { return thing &&  Object.prototype.toString.call(thing) === '[object Array]'; };
    }

    if (!isNode) {
        preconditions = {
            'Could not find esprima': ESP,
            'Could not find escodegen': ESPGEN,
            'JSON object not in scope': JSON,
            'Array does not implement push': [].push,
            'Array does not implement unshift': [].unshift
        };
        /* istanbul ignore next: untestable */
        for (cond in preconditions) {
            if (preconditions.hasOwnProperty(cond)) {
                if (!preconditions[cond]) { throw new Error(cond); }
            }
        }
    }

    function generateTrackerVar(filename, omitSuffix) {
        var hash, suffix;
        if (crypto !== null) {
            hash = crypto.createHash('md5');
            hash.update(filename);
            suffix = hash.digest('base64');
            //trim trailing equal signs, turn identifier unsafe chars to safe ones + => _ and / => $
            suffix = suffix.replace(new RegExp('=', 'g'), '')
                .replace(new RegExp('\\+', 'g'), '_')
                .replace(new RegExp('/', 'g'), '$');
        } else {
            window.__cov_seq = window.__cov_seq || 0;
            window.__cov_seq += 1;
            suffix = window.__cov_seq;
        }
        return '__cov_' + (omitSuffix ? '' : suffix);
    }

    function pushAll(ary, thing) {
        if (!isArray(thing)) {
            thing = [ thing ];
        }
        Array.prototype.push.apply(ary, thing);
    }

    SYNTAX = {
        // keep in sync with estraverse's VisitorKeys
        AssignmentExpression: ['left', 'right'],
        AssignmentPattern: ['left', 'right'],
        ArrayExpression: ['elements'],
        ArrayPattern: ['elements'],
        ArrowFunctionExpression: ['params', 'body'],
        AwaitExpression: ['argument'], // CAUTION: It's deferred to ES7.
        BlockStatement: ['body'],
        BinaryExpression: ['left', 'right'],
        BreakStatement: ['label'],
        CallExpression: ['callee', 'arguments'],
        CatchClause: ['param', 'body'],
        ClassBody: ['body'],
        ClassDeclaration: ['id', 'superClass', 'body'],
        ClassExpression: ['id', 'superClass', 'body'],
        ComprehensionBlock: ['left', 'right'],  // CAUTION: It's deferred to ES7.
        ComprehensionExpression: ['blocks', 'filter', 'body'],  // CAUTION: It's deferred to ES7.
        ConditionalExpression: ['test', 'consequent', 'alternate'],
        ContinueStatement: ['label'],
        DebuggerStatement: [],
        DirectiveStatement: [],
        DoWhileStatement: ['body', 'test'],
        EmptyStatement: [],
        ExportAllDeclaration: ['source'],
        ExportDefaultDeclaration: ['declaration'],
        ExportNamedDeclaration: ['declaration', 'specifiers', 'source'],
        ExportSpecifier: ['exported', 'local'],
        ExpressionStatement: ['expression'],
        ForStatement: ['init', 'test', 'update', 'body'],
        ForInStatement: ['left', 'right', 'body'],
        ForOfStatement: ['left', 'right', 'body'],
        FunctionDeclaration: ['id', 'params', 'body'],
        FunctionExpression: ['id', 'params', 'body'],
        GeneratorExpression: ['blocks', 'filter', 'body'],  // CAUTION: It's deferred to ES7.
        Identifier: [],
        IfStatement: ['test', 'consequent', 'alternate'],
        ImportDeclaration: ['specifiers', 'source'],
        ImportDefaultSpecifier: ['local'],
        ImportNamespaceSpecifier: ['local'],
        ImportSpecifier: ['imported', 'local'],
        Literal: [],
        LabeledStatement: ['label', 'body'],
        LogicalExpression: ['left', 'right'],
        MetaProperty: ['meta', 'property'],
        MemberExpression: ['object', 'property'],
        MethodDefinition: ['key', 'value'],
        ModuleSpecifier: [],
        NewExpression: ['callee', 'arguments'],
        ObjectExpression: ['properties'],
        ObjectPattern: ['properties'],
        Program: ['body'],
        Property: ['key', 'value'],
        RestElement: [ 'argument' ],
        ReturnStatement: ['argument'],
        SequenceExpression: ['expressions'],
        SpreadElement: ['argument'],
        Super: [],
        SwitchStatement: ['discriminant', 'cases'],
        SwitchCase: ['test', 'consequent'],
        TaggedTemplateExpression: ['tag', 'quasi'],
        TemplateElement: [],
        TemplateLiteral: ['quasis', 'expressions'],
        ThisExpression: [],
        ThrowStatement: ['argument'],
        TryStatement: ['block', 'handler', 'finalizer'],
        UnaryExpression: ['argument'],
        UpdateExpression: ['argument'],
        VariableDeclaration: ['declarations'],
        VariableDeclarator: ['id', 'init'],
        WhileStatement: ['test', 'body'],
        WithStatement: ['object', 'body'],
        YieldExpression: ['argument']
    };

    for (nodeType in SYNTAX) {
        /* istanbul ignore else: has own property */
        if (SYNTAX.hasOwnProperty(nodeType)) {
            SYNTAX[nodeType] = { name: nodeType, children: SYNTAX[nodeType] };
        }
    }

    astgen = {
        variable: function (name) { return { type: SYNTAX.Identifier.name, name: name }; },
        stringLiteral: function (str) { return { type: SYNTAX.Literal.name, value: String(str) }; },
        numericLiteral: function (num) { return { type: SYNTAX.Literal.name, value: Number(num) }; },
        statement: function (contents) { return { type: SYNTAX.ExpressionStatement.name, expression: contents }; },
        dot: function (obj, field) { return { type: SYNTAX.MemberExpression.name, computed: false, object: obj, property: field }; },
        subscript: function (obj, sub) { return { type: SYNTAX.MemberExpression.name, computed: true, object: obj, property: sub }; },
        postIncrement: function (obj) { return { type: SYNTAX.UpdateExpression.name, operator: '++', prefix: false, argument: obj }; },
        sequence: function (one, two) { return { type: SYNTAX.SequenceExpression.name, expressions: [one, two] }; },
        returnStatement: function (expr) { return { type: SYNTAX.ReturnStatement.name, argument: expr }; }
    };

    function Walker(walkMap, preprocessor, scope, debug) {
        this.walkMap = walkMap;
        this.preprocessor = preprocessor;
        this.scope = scope;
        this.debug = debug;
        if (this.debug) {
            this.level = 0;
            this.seq = true;
        }
    }

    function defaultWalker(node, walker) {

        var type = node.type,
            preprocessor,
            postprocessor,
            children = SYNTAX[type],
            // don't run generated nodes thru custom walks otherwise we will attempt to instrument the instrumentation code :)
            applyCustomWalker = !!node.loc || node.type === SYNTAX.Program.name,
            walkerFn = applyCustomWalker ? walker.walkMap[type] : null,
            i,
            j,
            walkFnIndex,
            childType,
            childNode,
            ret,
            childArray,
            childElement,
            pathElement,
            assignNode,
            isLast;

        if (!SYNTAX[type]) {
            console.error(node);
            console.error('Unsupported node type:' + type);
            return;
        }
        children = SYNTAX[type].children;
        /* istanbul ignore if: guard */
        if (node.walking) { throw new Error('Infinite regress: Custom walkers may NOT call walker.apply(node)'); }
        node.walking = true;

        ret = walker.apply(node, walker.preprocessor);

        preprocessor = ret.preprocessor;
        if (preprocessor) {
            delete ret.preprocessor;
            ret = walker.apply(node, preprocessor);
        }

        if (isArray(walkerFn)) {
            for (walkFnIndex = 0; walkFnIndex < walkerFn.length; walkFnIndex += 1) {
                isLast = walkFnIndex === walkerFn.length - 1;
                ret = walker.apply(ret, walkerFn[walkFnIndex]);
                /*istanbul ignore next: paranoid check */
                if (ret.type !== type && !isLast) {
                    throw new Error('Only the last walker is allowed to change the node type: [type was: ' + type + ' ]');
                }
            }
        } else {
            if (walkerFn) {
                ret = walker.apply(node, walkerFn);
            }
        }

        if (node.skipSelf) {
            return;
        }

        for (i = 0; i < children.length; i += 1) {
            childType = children[i];
            childNode = node[childType];
            if (childNode && !childNode.skipWalk) {
                pathElement = { node: node, property: childType };
                if (isArray(childNode)) {
                    childArray = [];
                    for (j = 0; j < childNode.length; j += 1) {
                        childElement = childNode[j];
                        pathElement.index = j;
                        if (childElement) {
                          assignNode = walker.apply(childElement, null, pathElement);
                          if (isArray(assignNode.prepend)) {
                              pushAll(childArray, assignNode.prepend);
                              delete assignNode.prepend;
                          }
                        } else {
                            assignNode = undefined;
                        }
                        pushAll(childArray, assignNode);
                    }
                    node[childType] = childArray;
                } else {
                    assignNode = walker.apply(childNode, null, pathElement);
                    /*istanbul ignore if: paranoid check */
                    if (isArray(assignNode.prepend)) {
                        throw new Error('Internal error: attempt to prepend statements in disallowed (non-array) context');
                        /* if this should be allowed, this is how to solve it
                        tmpNode = { type: 'BlockStatement', body: [] };
                        pushAll(tmpNode.body, assignNode.prepend);
                        pushAll(tmpNode.body, assignNode);
                        node[childType] = tmpNode;
                        delete assignNode.prepend;
                        */
                    } else {
                        node[childType] = assignNode;
                    }
                }
            }
        }

        postprocessor = ret.postprocessor;
        if (postprocessor) {
            delete ret.postprocessor;
            ret = walker.apply(ret, postprocessor);
        }

        delete node.walking;

        return ret;
    }

    Walker.prototype = {
        startWalk: function (node) {
            this.path = [];
            this.apply(node);
        },

        apply: function (node, walkFn, pathElement) {
            var ret, i, seq, prefix;

            walkFn = walkFn || defaultWalker;
            if (this.debug) {
                this.seq += 1;
                this.level += 1;
                seq = this.seq;
                prefix = '';
                for (i = 0; i < this.level; i += 1) { prefix += '    '; }
                console.log(prefix + 'Enter (' + seq + '):' + node.type);
            }
            if (pathElement) { this.path.push(pathElement); }
            ret = walkFn.call(this.scope, node, this);
            if (pathElement) { this.path.pop(); }
            if (this.debug) {
                this.level -= 1;
                console.log(prefix + 'Return (' + seq + '):' + node.type);
            }
            return ret || node;
        },

        startLineForNode: function (node) {
            return node && node.loc && node.loc.start ? node.loc.start.line : /* istanbul ignore next: guard */ null;
        },

        ancestor: function (n) {
            return this.path.length > n - 1 ? this.path[this.path.length - n] : /* istanbul ignore next: guard */ null;
        },

        parent: function () {
            return this.ancestor(1);
        },

        isLabeled: function () {
            var el = this.parent();
            return el && el.node.type === SYNTAX.LabeledStatement.name;
        }
    };

    /**
     * mechanism to instrument code for coverage. It uses the `esprima` and
     * `escodegen` libraries for JS parsing and code generation respectively.
     *
     * Works on `node` as well as the browser.
     *
     * Usage on nodejs
     * ---------------
     *
     *      var instrumenter = new require('istanbul').Instrumenter(),
     *          changed = instrumenter.instrumentSync('function meaningOfLife() { return 42; }', 'filename.js');
     *
     * Usage in a browser
     * ------------------
     *
     * Load `esprima.js`, `escodegen.js` and `instrumenter.js` (this file) using `script` tags or other means.
     *
     * Create an instrumenter object as:
     *
     *      var instrumenter = new Instrumenter(),
     *          changed = instrumenter.instrumentSync('function meaningOfLife() { return 42; }', 'filename.js');
     *
     * Aside from demonstration purposes, it is unclear why you would want to instrument code in a browser.
     *
     * @class Instrumenter
     * @constructor
     * @param {Object} options Optional. Configuration options.
     * @param {String} [options.coverageVariable] the global variable name to use for
     *      tracking coverage. Defaults to `__coverage__`
     * @param {Boolean} [options.embedSource] whether to embed the source code of every
     *      file as an array in the file coverage object for that file. Defaults to `false`
     * @param {Boolean} [options.preserveComments] whether comments should be preserved in the output. Defaults to `false`
     * @param {Boolean} [options.noCompact] emit readable code when set. Defaults to `false`
     * @param {Boolean} [options.esModules] whether the code to instrument contains uses es
     *      imports or exports.
     * @param {Boolean} [options.noAutoWrap] do not automatically wrap the source in
     *      an anonymous function before covering it. By default, code is wrapped in
     *      an anonymous function before it is parsed. This is done because
     *      some nodejs libraries have `return` statements outside of
     *      a function which is technically invalid Javascript and causes the parser to fail.
     *      This construct, however, works correctly in node since module loading
     *      is done in the context of an anonymous function.
     *
     * Note that the semantics of the code *returned* by the instrumenter does not change in any way.
     * The function wrapper is "unwrapped" before the instrumented code is generated.
     * @param {Object} [options.codeGenerationOptions] an object that is directly passed to the `escodegen`
     *      library as configuration for code generation. The `noCompact` setting is not honored when this
     *      option is specified
     * @param {Boolean} [options.debug] assist in debugging. Currently, the only effect of
     *      setting this option is a pretty-print of the coverage variable. Defaults to `false`
     * @param {Boolean} [options.walkDebug] assist in debugging of the AST walker used by this class.
     *
     */
    function Instrumenter(options) {
        this.opts = options || {
            debug: false,
            walkDebug: false,
            coverageVariable: '__coverage__',
            codeGenerationOptions: undefined,
            noAutoWrap: false,
            noCompact: false,
            embedSource: false,
            preserveComments: false,
            esModules: false
        };

        if (this.opts.esModules && !this.opts.noAutoWrap) {
            this.opts.noAutoWrap = true;
            if (this.opts.debug) {
                console.log('Setting noAutoWrap to true as required by esModules');
            }
        }

        this.walker = new Walker({
            ArrowFunctionExpression: [ this.arrowBlockConverter ],
            ExpressionStatement: this.coverStatement,
            ExportNamedDeclaration: this.coverExport,
            BreakStatement: this.coverStatement,
            ContinueStatement: this.coverStatement,
            DebuggerStatement: this.coverStatement,
            ReturnStatement: this.coverStatement,
            ThrowStatement: this.coverStatement,
            TryStatement: [ this.paranoidHandlerCheck, this.coverStatement],
            VariableDeclaration: this.coverStatement,
            IfStatement: [ this.ifBlockConverter, this.coverStatement, this.ifBranchInjector ],
            ForStatement: [ this.skipInit, this.loopBlockConverter, this.coverStatement ],
            ForInStatement: [ this.skipLeft, this.loopBlockConverter, this.coverStatement ],
            ForOfStatement: [ this.skipLeft, this.loopBlockConverter, this.coverStatement ],
            WhileStatement: [ this.loopBlockConverter, this.coverStatement ],
            DoWhileStatement: [ this.loopBlockConverter, this.coverStatement ],
            SwitchStatement: [ this.coverStatement, this.switchBranchInjector ],
            SwitchCase: [ this.switchCaseInjector ],
            WithStatement: [ this.withBlockConverter, this.coverStatement ],
            FunctionDeclaration: [ this.coverFunction, this.coverStatement ],
            FunctionExpression: this.coverFunction,
            LabeledStatement: this.coverStatement,
            ConditionalExpression: this.conditionalBranchInjector,
            LogicalExpression: this.logicalExpressionBranchInjector,
            ObjectExpression: this.maybeAddType,
            MetaProperty: this.coverMetaProperty,
        }, this.extractCurrentHint, this, this.opts.walkDebug);

        //unit testing purposes only
        if (this.opts.backdoor && this.opts.backdoor.omitTrackerSuffix) {
            this.omitTrackerSuffix = true;
        }
    }

    Instrumenter.prototype = {
        /**
         * synchronous instrumentation method. Throws when illegal code is passed to it
         * @method instrumentSync
         * @param {String} code the code to be instrumented as a String
         * @param {String} filename Optional. The name of the file from which
         *  the code was read. A temporary filename is generated when not specified.
         *  Not specifying a filename is only useful for unit tests and demonstrations
         *  of this library.
         */
        instrumentSync: function (code, filename) {
            var program;

            //protect from users accidentally passing in a Buffer object instead
            if (typeof code !== 'string') { throw new Error('Code must be string'); }
            if (code.charAt(0) === '#') { //shebang, 'comment' it out, won't affect syntax tree locations for things we care about
                code = '//' + code;
            }
            if (!this.opts.noAutoWrap) {
                code = LEADER_WRAP + code + TRAILER_WRAP;
            }
            try {
                program = ESP.parse(code, {
                    loc: true,
                    range: true,
                    tokens: this.opts.preserveComments,
                    comment: true,
                    sourceType: this.opts.esModules ? 'module' : 'script'
                });
            } catch (e) {
                console.log('Failed to parse file: ' + filename);
                throw e;
            }
            if (this.opts.preserveComments) {
                program = ESPGEN.attachComments(program, program.comments, program.tokens);
            }
            if (!this.opts.noAutoWrap) {
                program = {
                    type: SYNTAX.Program.name,
                    body: program.body[0].expression.callee.body.body,
                    comments: program.comments
                };
            }
            return this.instrumentASTSync(program, filename, code);
        },
        filterHints: function (comments) {
            var ret = [],
                i,
                comment,
                groups;
            if (!(comments && isArray(comments))) {
                return ret;
            }
            for (i = 0; i < comments.length; i += 1) {
                comment = comments[i];
                /* istanbul ignore else: paranoid check */
                if (comment && comment.value && comment.range && isArray(comment.range)) {
                    groups = String(comment.value).match(COMMENT_RE);
                    if (groups) {
                        ret.push({ type: groups[1], start: comment.range[0], end: comment.range[1] });
                    }
                }
            }
            return ret;
        },
        extractCurrentHint: function (node) {
            if (!node.range) { return; }
            var i = this.currentState.lastHintPosition + 1,
                hints = this.currentState.hints,
                nodeStart = node.range[0],
                hint;
            this.currentState.currentHint = null;
            while (i < hints.length) {
                hint = hints[i];
                if (hint.end < nodeStart) {
                    this.currentState.currentHint = hint;
                    this.currentState.lastHintPosition = i;
                    i += 1;
                } else {
                    break;
                }
            }
        },
        /**
         * synchronous instrumentation method that instruments an AST instead.
         * @method instrumentASTSync
         * @param {String} program the AST to be instrumented
         * @param {String} filename Optional. The name of the file from which
         *  the code was read. A temporary filename is generated when not specified.
         *  Not specifying a filename is only useful for unit tests and demonstrations
         *  of this library.
         *  @param {String} originalCode the original code corresponding to the AST,
         *  used for embedding the source into the coverage object
         */
        instrumentASTSync: function (program, filename, originalCode) {
            var usingStrict = false,
                codegenOptions,
                generated,
                preamble,
                lineCount,
                i;
            filename = filename || String(new Date().getTime()) + '.js';
            this.sourceMap = null;
            this.coverState = {
                path: filename,
                s: {},
                b: {},
                f: {},
                fnMap: {},
                statementMap: {},
                branchMap: {}
            };
            this.currentState = {
                trackerVar: generateTrackerVar(filename, this.omitTrackerSuffix),
                func: 0,
                branch: 0,
                variable: 0,
                statement: 0,
                hints: this.filterHints(program.comments),
                currentHint: null,
                lastHintPosition: -1,
                ignoring: 0
            };
            if (program.body && program.body.length > 0 && this.isUseStrictExpression(program.body[0])) {
                //nuke it
                program.body.shift();
                //and add it back at code generation time
                usingStrict = true;
            }
            this.walker.startWalk(program);
            codegenOptions = this.opts.codeGenerationOptions || { format: { compact: !this.opts.noCompact }};
            codegenOptions.comment = this.opts.preserveComments;
            //console.log(JSON.stringify(program, undefined, 2));

            generated = ESPGEN.generate(program, codegenOptions);
            preamble = this.getPreamble(originalCode || '', usingStrict);

            if (generated.map && generated.code) {
                lineCount = preamble.split(/\r\n|\r|\n/).length;
                // offset all the generated line numbers by the number of lines in the preamble
                for (i = 0; i < generated.map._mappings._array.length; i += 1) {
                    generated.map._mappings._array[i].generatedLine += lineCount;
                }
                this.sourceMap = generated.map;
                generated = generated.code;
            }

            return preamble + '\n' + generated + '\n';
        },
        /**
         * Callback based instrumentation. Note that this still executes synchronously in the same process tick
         * and calls back immediately. It only provides the options for callback style error handling as
         * opposed to a `try-catch` style and nothing more. Implemented as a wrapper over `instrumentSync`
         *
         * @method instrument
         * @param {String} code the code to be instrumented as a String
         * @param {String} filename Optional. The name of the file from which
         *  the code was read. A temporary filename is generated when not specified.
         *  Not specifying a filename is only useful for unit tests and demonstrations
         *  of this library.
         * @param {Function(err, instrumentedCode)} callback - the callback function
         */
        instrument: function (code, filename, callback) {

            if (!callback && typeof filename === 'function') {
                callback = filename;
                filename = null;
            }
            try {
                callback(null, this.instrumentSync(code, filename));
            } catch (ex) {
                callback(ex);
            }
        },
        /**
         * returns the file coverage object for the code that was instrumented
         * just before calling this method. Note that this represents a
         * "zero-coverage" object which is not even representative of the code
         * being loaded in node or a browser (which would increase the statement
         * counts for mainline code).
         * @method lastFileCoverage
         * @return {Object} a "zero-coverage" file coverage object for the code last instrumented
         * by this instrumenter
         */
        lastFileCoverage: function () {
            return this.coverState;
        },
        /**
         * returns the source map object for the code that was instrumented
         * just before calling this method.
         * @method lastSourceMap
         * @return {Object} a source map object for the code last instrumented
         * by this instrumenter
         */
        lastSourceMap: function () {
            return this.sourceMap;
        },
        fixColumnPositions: function (coverState) {
            var offset = LEADER_WRAP.length,
                fixer = function (loc) {
                    if (loc.start.line === 1) {
                        loc.start.column -= offset;
                    }
                    if (loc.end.line === 1) {
                        loc.end.column -= offset;
                    }
                },
                k,
                obj,
                i,
                locations;

            obj = coverState.statementMap;
            for (k in obj) {
                /* istanbul ignore else: has own property */
                if (obj.hasOwnProperty(k)) { fixer(obj[k]); }
            }
            obj = coverState.fnMap;
            for (k in obj) {
                /* istanbul ignore else: has own property */
                if (obj.hasOwnProperty(k)) { fixer(obj[k].loc); }
            }
            obj = coverState.branchMap;
            for (k in obj) {
                /* istanbul ignore else: has own property */
                if (obj.hasOwnProperty(k)) {
                    locations = obj[k].locations;
                    for (i = 0; i < locations.length; i += 1) {
                        fixer(locations[i]);
                    }
                }
            }
        },

        getPreamble: function (sourceCode, emitUseStrict) {
            var varName = this.opts.coverageVariable || '__coverage__',
                file = this.coverState.path.replace(/\\/g, '\\\\'),
                tracker = this.currentState.trackerVar,
                coverState,
                strictLine = emitUseStrict ? '"use strict";' : '',
                // return replacements using the function to ensure that the replacement is
                // treated like a dumb string and not as a string with RE replacement patterns
                replacer = function (s) {
                    return function () { return s; };
                },
                code;
            if (!this.opts.noAutoWrap) {
                this.fixColumnPositions(this.coverState);
            }
            if (this.opts.embedSource) {
                this.coverState.code = sourceCode.split(/(?:\r?\n)|\r/);
            }
            coverState = this.opts.debug ? JSON.stringify(this.coverState, undefined, 4) : JSON.stringify(this.coverState);
            code = [
                "%STRICT%",
                "var %VAR% = (Function('return this'))();",
                "if (!%VAR%.%GLOBAL%) { %VAR%.%GLOBAL% = {}; }",
                "%VAR% = %VAR%.%GLOBAL%;",
                "if (!(%VAR%['%FILE%'])) {",
                "   %VAR%['%FILE%'] = %OBJECT%;",
                "}",
                "%VAR% = %VAR%['%FILE%'];"
            ].join("\n")
                .replace(/%STRICT%/g, replacer(strictLine))
                .replace(/%VAR%/g, replacer(tracker))
                .replace(/%GLOBAL%/g, replacer(varName))
                .replace(/%FILE%/g, replacer(file))
                .replace(/%OBJECT%/g, replacer(coverState));
            return code;
        },

        startIgnore: function () {
            this.currentState.ignoring += 1;
        },

        endIgnore: function () {
            this.currentState.ignoring -= 1;
        },

        convertToBlock: function (node) {
            if (!node) {
                return { type: 'BlockStatement', body: [] };
            } else if (node.type === 'BlockStatement') {
                return node;
            } else {
                return { type: 'BlockStatement', body: [ node ] };
            }
        },

        arrowBlockConverter: function (node) {
            var retStatement;
            if (node.expression) { // turn expression nodes into a block with a return statement
                retStatement = astgen.returnStatement(node.body);
                // ensure the generated return statement is covered
                retStatement.loc = node.body.loc;
                node.body = this.convertToBlock(retStatement);
                node.expression = false;
            }
        },

        paranoidHandlerCheck: function (node) {
            // if someone is using an older esprima on the browser
            // convert handlers array to single handler attribute
            // containing its first element
            /* istanbul ignore next */
            if (!node.handler && node.handlers) {
                node.handler = node.handlers[0];
            }
        },

        ifBlockConverter: function (node) {
            node.consequent = this.convertToBlock(node.consequent);
            node.alternate = this.convertToBlock(node.alternate);
        },

        loopBlockConverter: function (node) {
            node.body = this.convertToBlock(node.body);
        },

        withBlockConverter: function (node) {
            node.body = this.convertToBlock(node.body);
        },

        statementName: function (location, initValue) {
            var sName,
                ignoring = !!this.currentState.ignoring;

            location.skip = ignoring || undefined;
            initValue = initValue || 0;
            this.currentState.statement += 1;
            sName = this.currentState.statement;
            this.coverState.statementMap[sName] = location;
            this.coverState.s[sName] = initValue;
            return sName;
        },

        skipInit: function (node /*, walker */) {
            if (node.init) {
                node.init.skipWalk = true;
            }
        },

        skipLeft: function (node /*, walker */) {
            node.left.skipWalk = true;
        },

        isUseStrictExpression: function (node) {
            return node && node.type === SYNTAX.ExpressionStatement.name &&
                node.expression  && node.expression.type === SYNTAX.Literal.name &&
                node.expression.value === 'use strict';
        },

        maybeSkipNode: function (node, type) {
            var alreadyIgnoring = !!this.currentState.ignoring,
                hint = this.currentState.currentHint,
                ignoreThis = !alreadyIgnoring && hint && hint.type === type;

            if (ignoreThis) {
                this.startIgnore();
                node.postprocessor = this.endIgnore;
                return true;
            }
            return false;
        },

        coverMetaProperty: function(node /* , walker */) {
           node.skipSelf = true;
        },

        coverStatement: function (node, walker) {
            var sName,
                incrStatementCount,
                parent,
                grandParent;

            this.maybeSkipNode(node, 'next');

            if (this.isUseStrictExpression(node)) {
                grandParent = walker.ancestor(2);
                /* istanbul ignore else: difficult to test */
                if (grandParent) {
                    if ((grandParent.node.type === SYNTAX.FunctionExpression.name ||
                        grandParent.node.type === SYNTAX.FunctionDeclaration.name)  &&
                        walker.parent().node.body[0] === node) {
                        return;
                    }
                }
            }

            if (node.type === SYNTAX.FunctionDeclaration.name) {
                // Called for the side-effect of setting the function's statement count to 1.
                this.statementName(node.loc, 1);
            } else {
                // We let `coverExport` handle ExportNamedDeclarations.
                parent = walker.parent();
                if (parent && parent.node.type === SYNTAX.ExportNamedDeclaration.name) {
                    return;
                }

                sName = this.statementName(node.loc);

                incrStatementCount = astgen.statement(
                    astgen.postIncrement(
                        astgen.subscript(
                            astgen.dot(astgen.variable(this.currentState.trackerVar), astgen.variable('s')),
                            astgen.stringLiteral(sName)
                        )
                    )
                );

                this.splice(incrStatementCount, node, walker);
            }
        },

        coverExport: function (node, walker) {
            var sName, incrStatementCount;

            if ( !node.declaration || !node.declaration.declarations ) { return; }

            this.maybeSkipNode(node, 'next');

            sName = this.statementName(node.declaration.loc);
            incrStatementCount = astgen.statement(
                astgen.postIncrement(
                    astgen.subscript(
                        astgen.dot(astgen.variable(this.currentState.trackerVar), astgen.variable('s')),
                        astgen.stringLiteral(sName)
                    )
                )
            );

            this.splice(incrStatementCount, node, walker);
        },

        splice: function (statements, node, walker) {
            var targetNode = walker.isLabeled() ? walker.parent().node : node;
            targetNode.prepend = targetNode.prepend || [];
            pushAll(targetNode.prepend, statements);
        },

        functionName: function (node, line, location) {
            this.currentState.func += 1;
            var id = this.currentState.func,
                ignoring = !!this.currentState.ignoring,
                name = node.id ? node.id.name : '(anonymous_' + id + ')',
                clone = function (attr) {
                    var obj = location[attr] || /* istanbul ignore next */ {};
                    return { line: obj.line, column: obj.column };
                };
            this.coverState.fnMap[id] = {
                name: name, line: line,
                loc: {
                    start: clone('start'),
                    end: clone('end')
                },
                skip: ignoring || undefined
            };
            this.coverState.f[id] = 0;
            return id;
        },

        coverFunction: function (node, walker) {
            var id,
                body = node.body,
                blockBody = body.body,
                popped;

            this.maybeSkipNode(node, 'next');

            id = this.functionName(node, walker.startLineForNode(node), {
                start: node.loc.start,
                end: { line: node.body.loc.start.line, column: node.body.loc.start.column }
            });

            if (blockBody.length > 0 && this.isUseStrictExpression(blockBody[0])) {
                popped = blockBody.shift();
            }
            blockBody.unshift(
                astgen.statement(
                    astgen.postIncrement(
                        astgen.subscript(
                            astgen.dot(astgen.variable(this.currentState.trackerVar), astgen.variable('f')),
                            astgen.stringLiteral(id)
                        )
                    )
                )
            );
            if (popped) {
                blockBody.unshift(popped);
            }
        },

        branchName: function (type, startLine, pathLocations) {
            var bName,
                paths = [],
                locations = [],
                i,
                ignoring = !!this.currentState.ignoring;
            this.currentState.branch += 1;
            bName = this.currentState.branch;
            for (i = 0; i < pathLocations.length; i += 1) {
                pathLocations[i].skip = pathLocations[i].skip || ignoring || undefined;
                locations.push(pathLocations[i]);
                paths.push(0);
            }
            this.coverState.b[bName] = paths;
            this.coverState.branchMap[bName] = { line: startLine, type: type, locations: locations };
            return bName;
        },

        branchIncrementExprAst: function (varName, branchIndex, down) {
            var ret = astgen.postIncrement(
                astgen.subscript(
                    astgen.subscript(
                        astgen.dot(astgen.variable(this.currentState.trackerVar), astgen.variable('b')),
                        astgen.stringLiteral(varName)
                    ),
                    astgen.numericLiteral(branchIndex)
                ),
                down
            );
            return ret;
        },

        locationsForNodes: function (nodes) {
            var ret = [],
                i;
            for (i = 0; i < nodes.length; i += 1) {
                ret.push(nodes[i].loc);
            }
            return ret;
        },

        ifBranchInjector: function (node, walker) {
            var alreadyIgnoring = !!this.currentState.ignoring,
                hint = this.currentState.currentHint,
                ignoreThen = !alreadyIgnoring && hint && hint.type === 'if',
                ignoreElse = !alreadyIgnoring && hint && hint.type === 'else',
                line = node.loc.start.line,
                col = node.loc.start.column,
                makeLoc = function () { return  { line: line, column: col }; },
                bName = this.branchName('if', walker.startLineForNode(node), [
                    { start: makeLoc(), end: makeLoc(), skip: ignoreThen || undefined },
                    { start: makeLoc(), end: makeLoc(), skip: ignoreElse || undefined }
                ]),
                thenBody = node.consequent.body,
                elseBody = node.alternate.body,
                child;
            thenBody.unshift(astgen.statement(this.branchIncrementExprAst(bName, 0)));
            elseBody.unshift(astgen.statement(this.branchIncrementExprAst(bName, 1)));
            if (ignoreThen) { child = node.consequent; child.preprocessor = this.startIgnore; child.postprocessor = this.endIgnore; }
            if (ignoreElse) { child = node.alternate; child.preprocessor = this.startIgnore; child.postprocessor = this.endIgnore; }
        },

        branchLocationFor: function (name, index) {
            return this.coverState.branchMap[name].locations[index];
        },

        switchBranchInjector: function (node, walker) {
            var cases = node.cases,
                bName,
                i;

            if (!(cases && cases.length > 0)) {
                return;
            }
            bName = this.branchName('switch', walker.startLineForNode(node), this.locationsForNodes(cases));
            for (i = 0; i < cases.length; i += 1) {
                cases[i].branchLocation = this.branchLocationFor(bName, i);
                cases[i].consequent.unshift(astgen.statement(this.branchIncrementExprAst(bName, i)));
            }
        },

        switchCaseInjector: function (node) {
            var location = node.branchLocation;
            delete node.branchLocation;
            if (this.maybeSkipNode(node, 'next')) {
                location.skip = true;
            }
        },

        conditionalBranchInjector: function (node, walker) {
            var bName = this.branchName('cond-expr', walker.startLineForNode(node), this.locationsForNodes([ node.consequent, node.alternate ])),
                ast1 = this.branchIncrementExprAst(bName, 0),
                ast2 = this.branchIncrementExprAst(bName, 1);

            node.consequent.preprocessor = this.maybeAddSkip(this.branchLocationFor(bName, 0));
            node.alternate.preprocessor = this.maybeAddSkip(this.branchLocationFor(bName, 1));
            node.consequent = astgen.sequence(ast1, node.consequent);
            node.alternate = astgen.sequence(ast2, node.alternate);
        },

        maybeAddSkip: function (branchLocation) {
            return function (node) {
                var alreadyIgnoring = !!this.currentState.ignoring,
                    hint = this.currentState.currentHint,
                    ignoreThis = !alreadyIgnoring && hint && hint.type === 'next';
                if (ignoreThis) {
                    this.startIgnore();
                    node.postprocessor = this.endIgnore;
                }
                if (ignoreThis || alreadyIgnoring) {
                    branchLocation.skip = true;
                }
            };
        },

        logicalExpressionBranchInjector: function (node, walker) {
            var parent = walker.parent(),
                leaves = [],
                bName,
                tuple,
                i;

            this.maybeSkipNode(node, 'next');

            if (parent && parent.node.type === SYNTAX.LogicalExpression.name) {
                //already covered
                return;
            }

            this.findLeaves(node, leaves);
            bName = this.branchName('binary-expr',
                walker.startLineForNode(node),
                this.locationsForNodes(leaves.map(function (item) { return item.node; }))
            );
            for (i = 0; i < leaves.length; i += 1) {
                tuple = leaves[i];
                tuple.parent[tuple.property] = astgen.sequence(this.branchIncrementExprAst(bName, i), tuple.node);
                tuple.node.preprocessor = this.maybeAddSkip(this.branchLocationFor(bName, i));
            }
        },

        findLeaves: function (node, accumulator, parent, property) {
            if (node.type === SYNTAX.LogicalExpression.name) {
                this.findLeaves(node.left, accumulator, node, 'left');
                this.findLeaves(node.right, accumulator, node, 'right');
            } else {
                accumulator.push({ node: node, parent: parent, property: property });
            }
        },
        maybeAddType: function (node /*, walker */) {
            var props = node.properties,
                i,
                child;
            for (i = 0; i < props.length; i += 1) {
                child = props[i];
                if (!child.type) {
                    child.type = SYNTAX.Property.name;
                }
            }
        },
    };

    if (isNode) {
        module.exports = Instrumenter;
    } else {
        window.Instrumenter = Instrumenter;
    }

}(typeof module !== 'undefined' && typeof module.exports !== 'undefined' && typeof exports !== 'undefined'));


================================================
FILE: lib/object-utils.js
================================================
/*
 Copyright (c) 2012, Yahoo! Inc.  All rights reserved.
 Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms.
 */

/**
 * utility methods to process coverage objects. A coverage object has the following
 * format.
 *
 *      {
 *          "/path/to/file1.js": { file1 coverage },
 *          "/path/to/file2.js": { file2 coverage }
 *      }
 *
 *  The internals of the file coverage object are intentionally not documented since
 *  it is not a public interface.
 *
 *  *Note:* When a method of this module has the word `File` in it, it will accept
 *  one of the sub-objects of the main coverage object as an argument. Other
 *  methods accept the higher level coverage object with multiple keys.
 *
 * Works on `node` as well as the browser.
 *
 * Usage on nodejs
 * ---------------
 *
 *      var objectUtils = require('istanbul').utils;
 *
 * Usage in a browser
 * ------------------
 *
 * Load this file using a `script` tag or other means. This will set `window.coverageUtils`
 * to this module's exports.
 *
 * @class ObjectUtils
 * @module main
 * @static
 */
(function (isNode) {
    /**
     * adds line coverage information to a file coverage object, reverse-engineering
     * it from statement coverage. The object passed in is updated in place.
     *
     * Note that if line coverage information is already present in the object,
     * it is not recomputed.
     *
     * @method addDerivedInfoForFile
     * @static
     * @param {Object} fileCoverage the coverage object for a single file
     */
    function addDerivedInfoForFile(fileCoverage) {
        var statementMap = fileCoverage.statementMap,
            statements = fileCoverage.s,
            lineMap;

        if (!fileCoverage.l) {
            fileCoverage.l = lineMap = {};
            Object.keys(statements).forEach(function (st) {
                var line = statementMap[st].start.line,
                    count = statements[st],
                    prevVal = lineMap[line];
                if (count === 0 && statementMap[st].skip) { count = 1; }
                if (typeof prevVal === 'undefined' || prevVal < count) {
                    lineMap[line] = count;
                }
            });
        }
    }
    /**
     * adds line coverage information to all file coverage objects.
     *
     * @method addDerivedInfo
     * @static
     * @param {Object} coverage the coverage object
     */
    function addDerivedInfo(coverage) {
        Object.keys(coverage).forEach(function (k) {
            addDerivedInfoForFile(coverage[k]);
        });
    }
    /**
     * removes line coverage information from all file coverage objects
     * @method removeDerivedInfo
     * @static
     * @param {Object} coverage the coverage object
     */
    function removeDerivedInfo(coverage) {
        Object.keys(coverage).forEach(function (k) {
            delete coverage[k].l;
        });
    }

    function percent(covered, total) {
        var tmp;
        if (total > 0) {
            tmp = 1000 * 100 * covered / total + 5;
            return Math.floor(tmp / 10) / 100;
        } else {
            return 100.00;
        }
    }

    function computeSimpleTotals(fileCoverage, property, mapProperty) {
        var stats = fileCoverage[property],
            map = mapProperty ? fileCoverage[mapProperty] : null,
            ret = { total: 0, covered: 0, skipped: 0 };

        Object.keys(stats).forEach(function (key) {
            var covered = !!stats[key],
                skipped = map && map[key].skip;
            ret.total += 1;
            if (covered || skipped) {
                ret.covered += 1;
            }
            if (!covered && skipped) {
                ret.skipped += 1;
            }
        });
        ret.pct = percent(ret.covered, ret.total);
        return ret;
    }

    function computeBranchTotals(fileCoverage) {
        var stats = fileCoverage.b,
            branchMap = fileCoverage.branchMap,
            ret = { total: 0, covered: 0, skipped: 0 };

        Object.keys(stats).forEach(function (key) {
            var branches = stats[key],
                map = branchMap[key],
                covered,
                skipped,
                i;
            for (i = 0; i < branches.length; i += 1) {
                covered = branches[i] > 0;
                skipped = map.locations && map.locations[i] && map.locations[i].skip;
                if (covered || skipped) {
                    ret.covered += 1;
                }
                if (!covered && skipped) {
                    ret.skipped += 1;
                }
            }
            ret.total += branches.length;
        });
        ret.pct = percent(ret.covered, ret.total);
        return ret;
    }
    /**
     * returns a blank summary metrics object. A metrics object has the following
     * format.
     *
     *      {
     *          lines: lineMetrics,
     *          statements: statementMetrics,
     *          functions: functionMetrics,
     *          branches: branchMetrics
     *          linesCovered: lineCoveredCount
     *      }
     *
     *  Each individual metric object looks as follows:
     *
     *      {
     *          total: n,
     *          covered: m,
     *          pct: percent
     *      }
     *
     * @method blankSummary
     * @static
     * @return {Object} a blank metrics object
     */
    function blankSummary() {
        return {
            lines: {
                total: 0,
                covered: 0,
                skipped: 0,
                pct: 'Unknown'
            },
            statements: {
                total: 0,
                covered: 0,
                skipped: 0,
                pct: 'Unknown'
            },
            functions: {
                total: 0,
                covered: 0,
                skipped: 0,
                pct: 'Unknown'
            },
            branches: {
                total: 0,
                covered: 0,
                skipped: 0,
                pct: 'Unknown'
            },
            linesCovered: {}
        };
    }
    /**
     * returns the summary metrics given the coverage object for a single file. See `blankSummary()`
     * to understand the format of the returned object.
     *
     * @method summarizeFileCoverage
     * @static
     * @param {Object} fileCoverage the coverage object for a single file.
     * @return {Object} the summary metrics for the file
     */
    function summarizeFileCoverage(fileCoverage) {
        var ret = blankSummary();
        addDerivedInfoForFile(fileCoverage);
        ret.lines = computeSimpleTotals(fileCoverage, 'l');
        ret.functions = computeSimpleTotals(fileCoverage, 'f', 'fnMap');
        ret.statements = computeSimpleTotals(fileCoverage, 's', 'statementMap');
        ret.branches = computeBranchTotals(fileCoverage);
        ret.linesCovered = fileCoverage.l;
        return ret;
    }
    /**
     * merges two instances of file coverage objects *for the same file*
     * such that the execution counts are correct.
     *
     * @method mergeFileCoverage
     * @static
     * @param {Object} first the first file coverage object for a given file
     * @param {Object} second the second file coverage object for the same file
     * @return {Object} an object that is a result of merging the two. Note that
     *      the input objects are not changed in any way.
     */
    function mergeFileCoverage(first, second) {
        var ret =
Download .txt
gitextract_lf9e4zzz/

├── .gitignore
├── .jshintignore
├── .jshintrc
├── .travis.yml
├── CHANGELOG.md
├── LICENSE
├── README.md
├── coverage.json.md
├── download-escodegen-browser.sh
├── generate-pages.sh
├── ignoring-code-for-coverage.md
├── index.js
├── lib/
│   ├── assets/
│   │   ├── base.css
│   │   ├── sorter.js
│   │   └── vendor/
│   │       ├── prettify.css
│   │       └── prettify.js
│   ├── cli.js
│   ├── collector.js
│   ├── command/
│   │   ├── check-coverage.js
│   │   ├── common/
│   │   │   └── run-with-cover.js
│   │   ├── cover.js
│   │   ├── help.js
│   │   ├── index.js
│   │   ├── instrument.js
│   │   ├── report.js
│   │   └── test.js
│   ├── config.js
│   ├── hook.js
│   ├── instrumenter.js
│   ├── object-utils.js
│   ├── register-plugins.js
│   ├── report/
│   │   ├── clover.js
│   │   ├── cobertura.js
│   │   ├── common/
│   │   │   └── defaults.js
│   │   ├── html.js
│   │   ├── index.js
│   │   ├── json-summary.js
│   │   ├── json.js
│   │   ├── lcov.js
│   │   ├── lcovonly.js
│   │   ├── none.js
│   │   ├── teamcity.js
│   │   ├── templates/
│   │   │   ├── foot.txt
│   │   │   └── head.txt
│   │   ├── text-lcov.js
│   │   ├── text-summary.js
│   │   └── text.js
│   ├── reporter.js
│   ├── store/
│   │   ├── fslookup.js
│   │   ├── index.js
│   │   ├── memory.js
│   │   └── tmp.js
│   └── util/
│       ├── factory.js
│       ├── file-matcher.js
│       ├── file-writer.js
│       ├── help-formatter.js
│       ├── input-error.js
│       ├── insertion-text.js
│       ├── meta.js
│       ├── tree-summarizer.js
│       ├── writer.js
│       └── yui-load-hook.js
├── misc/
│   ├── ast/
│   │   ├── assign.js
│   │   ├── block-label.js
│   │   ├── cond.js
│   │   ├── defun-compact.js
│   │   ├── defun.js
│   │   ├── do-statement.js
│   │   ├── dot.js
│   │   ├── eq.js
│   │   ├── expr.js
│   │   ├── for-block.js
│   │   ├── for-compact.js
│   │   ├── for-multi.js
│   │   ├── for-statement.js
│   │   ├── forin-block.js
│   │   ├── forin-compact.js
│   │   ├── forin-statement.js
│   │   ├── func.js
│   │   ├── if-block.js
│   │   ├── if-compact.js
│   │   ├── if-only.js
│   │   ├── if-statement.js
│   │   ├── incr-slice.js
│   │   ├── label.js
│   │   ├── nested-if.js
│   │   ├── pfcall.js
│   │   ├── preamble.js
│   │   ├── switch-statement.js
│   │   ├── try-block.js
│   │   ├── try-statement.js
│   │   ├── while-block.js
│   │   ├── while-compact.js
│   │   ├── while-for.js
│   │   └── while-statement.js
│   ├── config/
│   │   ├── istanbul-config-alt.json
│   │   └── istanbul-config.json
│   └── samples/
│       └── coverage.js
├── package.json
├── test/
│   ├── browser/
│   │   ├── support/
│   │   │   ├── index.html
│   │   │   ├── phantom-test.client.js
│   │   │   ├── server.js
│   │   │   └── vendor/
│   │   │       └── yui-support.js
│   │   └── test-browser-instrumentation.js
│   ├── cli/
│   │   ├── package.json
│   │   ├── sample-project/
│   │   │   ├── .gitignore
│   │   │   ├── amd/
│   │   │   │   ├── ipsum.js
│   │   │   │   └── lorem.js
│   │   │   ├── config-check-each.istanbul.yml
│   │   │   ├── config-check-global.istanbul.yml
│   │   │   ├── config-check-mixed.istanbul.yml
│   │   │   ├── config.istanbul.yml
│   │   │   ├── includeAllSources/
│   │   │   │   ├── unloadedFile.js
│   │   │   │   └── unloadedFileWithFunctionDeclaration.js
│   │   │   ├── lib/
│   │   │   │   ├── bar.js
│   │   │   │   ├── foo.js
│   │   │   │   └── util/
│   │   │   │       ├── bad.js
│   │   │   │       ├── es-module.js
│   │   │   │       ├── generate-names.js
│   │   │   │       └── unused.js
│   │   │   ├── test/
│   │   │   │   ├── amd-run.js
│   │   │   │   ├── global-leak.js
│   │   │   │   └── run.js
│   │   │   └── vendor/
│   │   │       └── dummy_vendor_lib.js
│   │   ├── test-base-cli.js
│   │   ├── test-check-coverage-command.js
│   │   ├── test-clover-report.js
│   │   ├── test-cobertura-report.js
│   │   ├── test-cover-command.js
│   │   ├── test-html-report.js
│   │   ├── test-include-pid.js
│   │   ├── test-instrument-command.js
│   │   ├── test-json-report.js
│   │   ├── test-json-summary-report.js
│   │   ├── test-lcov-report.js
│   │   ├── test-lcovonly-report.js
│   │   ├── test-lots-of-files.js
│   │   ├── test-none-report.js
│   │   ├── test-report-command.js
│   │   ├── test-teamcity-report.js
│   │   ├── test-test-command.js
│   │   └── test-text-lcov-report.js
│   ├── cli-helper.js
│   ├── common.js
│   ├── es6.js
│   ├── helper.js
│   ├── instrumentation/
│   │   ├── test-do.js
│   │   ├── test-es6-arrow-fn.js
│   │   ├── test-es6-export.js
│   │   ├── test-es6-forof.js
│   │   ├── test-es6-import.js
│   │   ├── test-es6-super.js
│   │   ├── test-es6-yield.js
│   │   ├── test-expressions.js
│   │   ├── test-for.js
│   │   ├── test-forin.js
│   │   ├── test-functions.js
│   │   ├── test-if-with-hints.js
│   │   ├── test-if.js
│   │   ├── test-locations.js
│   │   ├── test-misc.js
│   │   ├── test-statement-with-hints.js
│   │   ├── test-statement.js
│   │   ├── test-strict.js
│   │   ├── test-switch.js
│   │   ├── test-try.js
│   │   ├── test-while.js
│   │   └── test-with.js
│   ├── loader.js
│   ├── other/
│   │   ├── config-data/
│   │   │   ├── .istanbul.yml
│   │   │   └── cfg.json
│   │   ├── data/
│   │   │   ├── bar.es6
│   │   │   ├── baz.js
│   │   │   ├── foo.js
│   │   │   └── matcher/
│   │   │       ├── .gitignore
│   │   │       ├── general/
│   │   │       │   ├── .gitignore
│   │   │       │   └── general.js
│   │   │       ├── lib/
│   │   │       │   └── lib-top.js
│   │   │       └── top.js
│   │   ├── data-complete-copy/
│   │   │   ├── baz.js
│   │   │   ├── fixture.xml
│   │   │   ├── foo.js
│   │   │   ├── myfile1
│   │   │   ├── myfile2
│   │   │   └── subdir/
│   │   │       └── x.css
│   │   ├── test-collector.js
│   │   ├── test-command-xface.js
│   │   ├── test-config.js
│   │   ├── test-file-writer.js
│   │   ├── test-help-formatter.js
│   │   ├── test-hook.js
│   │   ├── test-index-xface.js
│   │   ├── test-input-error.js
│   │   ├── test-insertion-text.js
│   │   ├── test-matcher.js
│   │   ├── test-object-utils.js
│   │   ├── test-store.js
│   │   └── test-summarizer.js
│   ├── run-again.js
│   └── run.js
├── yui-coverage-comparison.md
└── yuidoc.json
Download .txt
SYMBOL INDEX (227 symbols across 61 files)

FILE: lib/assets/sorter.js
  function getTable (line 10) | function getTable() { return document.querySelector('.coverage-summary'); }
  function getTableHeader (line 12) | function getTableHeader() { return getTable().querySelector('thead tr'); }
  function getTableBody (line 14) | function getTableBody() { return getTable().querySelector('tbody'); }
  function getNthColumn (line 16) | function getNthColumn(n) { return getTableHeader().querySelectorAll('th'...
  function loadColumns (line 19) | function loadColumns() {
  function loadRowData (line 43) | function loadRowData(tableRow) {
  function loadData (line 62) | function loadData() {
  function sortByIndex (line 71) | function sortByIndex(index, desc) {
  function removeSortIndicators (line 102) | function removeSortIndicators() {
  function addSortIndicators (line 110) | function addSortIndicators() {
  function enableUI (line 114) | function enableUI() {

FILE: lib/assets/vendor/prettify.js
  function k (line 1) | function k(Z){var ad=0;var S=false;var ac=false;for(var V=0,U=Z.length;V...
  function a (line 1) | function a(V){var U=/(?:^|\s)nocode(?:\s|$)/;var X=[];var T=0;var Z=[];v...
  function B (line 1) | function B(S,U,W,T){if(!U){return}var V={sourceCode:U,basePos:S};W(V);T....
  function o (line 1) | function o(S){var V=undefined;for(var U=S.firstChild;U;U=U.nextSibling){...
  function g (line 1) | function g(U,T){var S={};var V;(function(){var ad=U.concat(T);var ah=[];...
  function i (line 1) | function i(T){var W=[],S=[];if(T.tripleQuotedStrings){W.push([C,/^(?:\'\...
  function Q (line 1) | function Q(V,ag){var U=/(?:^|\s)nocode(?:\s|$)/;var ab=/\r\n?|\n/;var ac...
  function D (line 1) | function D(ac){var aj=/\bMSIE\b/.test(navigator.userAgent);var am=/\n/g;...
  function c (line 1) | function c(U,V){for(var S=V.length;--S>=0;){var T=V[S];if(!t.hasOwnPrope...
  function q (line 1) | function q(T,S){if(!(T&&t.hasOwnProperty(T))){T=/^\s*</.test(S)?"default...
  function d (line 1) | function d(V){var U=V.langExtension;try{var S=a(V.sourceNode);var T=S.so...
  function y (line 1) | function y(W,V,U){var S=document.createElement("PRE");S.innerHTML=W;if(U...
  function b (line 1) | function b(ad){function Y(af){return document.getElementsByTagName(af)}v...

FILE: lib/cli.js
  function findCommandPosition (line 16) | function findCommandPosition(args) {
  function exit (line 28) | function exit(ex, code) {
  function errHandler (line 50) | function errHandler (ex) {
  function runCommand (line 63) | function runCommand(args, callback) {
  function runToCompletion (line 86) | function runToCompletion(args) {

FILE: lib/collector.js
  function Collector (line 52) | function Collector(options) {

FILE: lib/command/check-coverage.js
  function isAbsolute (line 17) | function isAbsolute(file) {
  function CheckCoverageCommand (line 25) | function CheckCoverageCommand() {
  function removeFiles (line 29) | function removeFiles(covObj, root, files) {
  function check (line 157) | function check(name, thresholds, actuals) {

FILE: lib/command/common/run-with-cover.js
  function usage (line 22) | function usage(arg0, command) {
  function run (line 44) | function run(args, commandName, enableHooks, callback) {

FILE: lib/command/cover.js
  function CoverCommand (line 10) | function CoverCommand() {

FILE: lib/command/help.js
  function showConfigHelp (line 14) | function showConfigHelp(toolName) {
  function HelpCommand (line 50) | function HelpCommand() {

FILE: lib/command/index.js
  function Command (line 9) | function Command() {}

FILE: lib/command/instrument.js
  function BaselineCollector (line 29) | function BaselineCollector(instrumenter) {
  function processFiles (line 55) | function processFiles(instrumenter, inputDir, outputDir, relativeNames, ...
  function InstrumentCommand (line 128) | function InstrumentCommand() {

FILE: lib/command/report.js
  function ReportCommand (line 20) | function ReportCommand() {
  function printDeprecationMessage (line 27) | function printDeprecationMessage(pat, fmt) {

FILE: lib/command/test.js
  function TestCommand (line 10) | function TestCommand() {

FILE: lib/config.js
  function defaultConfig (line 13) | function defaultConfig(includeBackCompatAttrs) {
  function dasherize (line 69) | function dasherize(word) {
  function isScalar (line 74) | function isScalar(v) {
  function isObject (line 79) | function isObject(v) {
  function mergeObjects (line 83) | function mergeObjects(explicit, template) {
  function mergeDefaults (line 103) | function mergeDefaults(explicit, implicit) {
  function addMethods (line 107) | function addMethods() {
  function InstrumentOptions (line 127) | function InstrumentOptions(config) {
  function ReportingOptions (line 231) | function ReportingOptions(config) {
  function isInvalidMark (line 266) | function isInvalidMark(v, key) {
  function HookOptions (line 327) | function HookOptions(config) {
  function Configuration (line 375) | function Configuration(obj, overrides) {
  function loadFile (line 416) | function loadFile(file, overrides) {
  function loadObject (line 442) | function loadObject(obj, overrides) {

FILE: lib/hook.js
  function transformFn (line 42) | function transformFn(matcher, transformer, verbose) {
  function unloadRequireCache (line 68) | function unloadRequireCache(matcher) {
  function hookRequire (line 91) | function hookRequire(matcher, transformer, options) {
  function unhookRequire (line 122) | function unhookRequire() {
  function hookCreateScript (line 139) | function hookCreateScript(matcher, transformer, opts) {
  function unhookCreateScript (line 153) | function unhookCreateScript() {
  function hookRunInThisContext (line 169) | function hookRunInThisContext(matcher, transformer, opts) {
  function unhookRunInThisContext (line 183) | function unhookRunInThisContext() {

FILE: lib/instrumenter.js
  function generateTrackerVar (line 43) | function generateTrackerVar(filename, omitSuffix) {
  function pushAll (line 61) | function pushAll(ary, thing) {
  function Walker (line 162) | function Walker(walkMap, preprocessor, scope, debug) {
  function defaultWalker (line 173) | function defaultWalker(node, walker) {
  function Instrumenter (line 382) | function Instrumenter(options) {

FILE: lib/object-utils.js
  function addDerivedInfoForFile (line 51) | function addDerivedInfoForFile(fileCoverage) {
  function addDerivedInfo (line 76) | function addDerivedInfo(coverage) {
  function removeDerivedInfo (line 87) | function removeDerivedInfo(coverage) {
  function percent (line 93) | function percent(covered, total) {
  function computeSimpleTotals (line 103) | function computeSimpleTotals(fileCoverage, property, mapProperty) {
  function computeBranchTotals (line 123) | function computeBranchTotals(fileCoverage) {
  function blankSummary (line 173) | function blankSummary() {
  function summarizeFileCoverage (line 211) | function summarizeFileCoverage(fileCoverage) {
  function mergeFileCoverage (line 232) | function mergeFileCoverage(first, second) {
  function mergeSummaryObjects (line 264) | function mergeSummaryObjects() {
  function summarizeCoverage (line 304) | function summarizeCoverage(coverage) {
  function toYUICoverage (line 322) | function toYUICoverage(coverage) {
  function incrementIgnoredTotals (line 370) | function incrementIgnoredTotals(cov) {

FILE: lib/report/clover.js
  function CloverReport (line 24) | function CloverReport(opts) {
  function asJavaPackage (line 36) | function asJavaPackage(node) {
  function asClassName (line 43) | function asClassName(node) {
  function quote (line 48) | function quote(thing) {
  function attr (line 52) | function attr(n, v) {
  function branchCoverageByLine (line 56) | function branchCoverageByLine(fileCoverage) {
  function addClassStats (line 75) | function addClassStats(node, fileCoverage, writer) {
  function walk (line 118) | function walk(node, collector, writer, level, projectRoot) {

FILE: lib/report/cobertura.js
  function CoberturaReport (line 29) | function CoberturaReport(opts) {
  function asJavaPackage (line 41) | function asJavaPackage(node) {
  function asClassName (line 48) | function asClassName(node) {
  function quote (line 53) | function quote(thing) {
  function attr (line 57) | function attr(n, v) {
  function branchCoverageByLine (line 61) | function branchCoverageByLine(fileCoverage) {
  function addClassStats (line 80) | function addClassStats(node, fileCoverage, writer, projectRoot) {
  function walk (line 146) | function walk(node, collector, writer, level, projectRoot) {

FILE: lib/report/html.js
  function customEscape (line 152) | function customEscape(text) {
  function title (line 170) | function title(str) {
  function annotateLines (line 174) | function annotateLines(fileCoverage, structuredText) {
  function annotateStatements (line 190) | function annotateStatements(fileCoverage, structuredText) {
  function annotateFunctions (line 219) | function annotateFunctions(fileCoverage, structuredText) {
  function annotateBranches (line 250) | function annotateBranches(fileCoverage, structuredText) {
  function getReportClass (line 305) | function getReportClass(stats, watermark) {
  function cleanPath (line 315) | function cleanPath(name) {
  function isEmptySourceStore (line 320) | function isEmptySourceStore(sourceStore) {
  function HtmlReport (line 345) | function HtmlReport(opts) {

FILE: lib/report/index.js
  function Report (line 37) | function Report(/* options */) {

FILE: lib/report/json-summary.js
  function JsonSummaryReport (line 27) | function JsonSummaryReport(opts) {

FILE: lib/report/json.js
  function JsonReport (line 26) | function JsonReport(opts) {

FILE: lib/report/lcov.js
  function LcovReport (line 31) | function LcovReport(opts) {

FILE: lib/report/lcovonly.js
  function LcovOnlyReport (line 27) | function LcovOnlyReport(opts) {

FILE: lib/report/none.js
  function NoneReport (line 24) | function NoneReport() {

FILE: lib/report/teamcity.js
  function TeamcityReport (line 29) | function TeamcityReport(opts) {
  function lineForKey (line 40) | function lineForKey(value, teamcityVar) {

FILE: lib/report/text-lcov.js
  function TextLcov (line 20) | function TextLcov(opts) {

FILE: lib/report/text-summary.js
  function TextSummaryReport (line 30) | function TextSummaryReport(opts) {
  function lineForKey (line 41) | function lineForKey(summary, key, watermarks) {

FILE: lib/report/text.js
  function TextReport (line 38) | function TextReport(opts) {
  function padding (line 51) | function padding(num, ch) {
  function fill (line 61) | function fill(str, width, right, tabs, clazz) {
  function formatName (line 86) | function formatName(name, maxCols, level, clazz) {
  function formatPct (line 90) | function formatPct(pct, clazz, width) {
  function nodeName (line 94) | function nodeName(node) {
  function tableHeader (line 98) | function tableHeader(maxNameCols) {
  function collectMissingLines (line 109) | function collectMissingLines(kind, linesCovered) {
  function tableRow (line 125) | function tableRow(node, maxNameCols, level, watermarks) {
  function findNameWidth (line 144) | function findNameWidth(node, level, last) {
  function makeLine (line 157) | function makeLine(nameWidth) {
  function walk (line 171) | function walk(node, nameWidth, array, level, watermarks) {

FILE: lib/reporter.js
  function Reporter (line 33) | function Reporter(cfg, dir) {

FILE: lib/store/fslookup.js
  function LookupStore (line 28) | function LookupStore(opts) {

FILE: lib/store/index.js
  function Store (line 42) | function Store(/* options */) {}

FILE: lib/store/memory.js
  function MemoryStore (line 23) | function MemoryStore() {

FILE: lib/store/tmp.js
  function makeTempDir (line 13) | function makeTempDir() {
  function TmpStore (line 35) | function TmpStore(opts) {

FILE: lib/util/factory.js
  function Factory (line 11) | function Factory(kind, dir, allowAbbreviations) {

FILE: lib/util/file-matcher.js
  function filesFor (line 12) | function filesFor(options, callback) {
  function matcherFor (line 50) | function matcherFor(options, callback) {

FILE: lib/util/file-writer.js
  function extend (line 15) | function extend(cons, proto) {
  function BufferedContentWriter (line 21) | function BufferedContentWriter() {
  function StreamContentWriter (line 36) | function StreamContentWriter(stream) {
  function SyncFileWriter (line 48) | function SyncFileWriter() {
  function AsyncFileWriter (line 65) | function AsyncFileWriter() {
  function FileWriter (line 131) | function FileWriter(sync) {

FILE: lib/util/help-formatter.js
  function formatPara (line 13) | function formatPara(text) {
  function formatOption (line 17) | function formatOption(option, helpText) {

FILE: lib/util/insertion-text.js
  function InsertionText (line 6) | function InsertionText(text, consumeBlanks) {

FILE: lib/util/tree-summarizer.js
  function commonArrayPrefix (line 10) | function commonArrayPrefix(first, second) {
  function findCommonArrayPrefix (line 24) | function findCommonArrayPrefix(args) {
  function Node (line 39) | function Node(fullName, kind, metrics) {
  function TreeSummary (line 72) | function TreeSummary(summaryMap, commonPrefix) {
  function TreeSummarizer (line 199) | function TreeSummarizer() {

FILE: lib/util/writer.js
  function extend (line 9) | function extend(cons, proto) {
  function ContentWriter (line 23) | function ContentWriter() {
  function Writer (line 52) | function Writer() {

FILE: misc/ast/defun-compact.js
  function bar (line 5) | function bar() { return 'bar'; }

FILE: misc/ast/defun.js
  function bar (line 6) | function bar() {

FILE: misc/ast/label.js
  function foo (line 4) | function foo()

FILE: misc/samples/coverage.js
  function addInstrumentCandidate (line 41) | function addInstrumentCandidate(file) {
  function hookRequire (line 50) | function hookRequire(verbose) {
  function unhookRequire (line 65) | function unhookRequire() {
  function getCollector (line 73) | function getCollector() {
  function addCoverage (line 92) | function addCoverage(coverageObject) {
  function getFinalCoverage (line 99) | function getFinalCoverage() {
  function writeReportsFor (line 109) | function writeReportsFor(fileList, dir) {
  function writeReports (line 123) | function writeReports(dir) {
  function writeReportsInternal (line 127) | function writeReportsInternal(dir, collector) {
  function instrumentCode (line 142) | function instrumentCode(code, filename) {
  function instrumentFile (line 151) | function instrumentFile(file) {

FILE: test/browser/support/server.js
  function handleInitialPage (line 19) | function handleInitialPage(request, response) {
  function handleYui (line 25) | function handleYui(request, response) {
  function handleEsprima (line 30) | function handleEsprima(request, response) {
  function handleEscodegen (line 35) | function handleEscodegen(request, response) {
  function handleInstrumenter (line 40) | function handleInstrumenter(request, response) {
  function handleFile (line 52) | function handleFile(request, response) {
  function getData (line 66) | function getData(request, callback) {
  function handleInstrumented (line 75) | function handleInstrumented(request, response) {
  function handleEnd (line 93) | function handleEnd(request, response) {
  function handler (line 109) | function handler(request, response) {
  function create (line 144) | function create(port, instrumenter, root, demo) {

FILE: test/browser/support/vendor/yui-support.js
  function m (line 9) | function m(e,t,n){var r,i;t||(t=0);if(n||m.test(e))try{return d.slice.ca...
  function g (line 9) | function g(){this._init(),this.add.apply(this,arguments)}
  function e (line 10) | function e(){}
  function c (line 12) | function c(){u._progress("Failed to load "+t.url,t)}
  function h (line 12) | function h(){f&&clearTimeout(f),u._progress(null,t)}
  function i (line 13) | function i(e,t){return e==="ok"?!0:t}
  function a (line 13) | function a(e){var t;for(t=0;t<r.length;t+=1)if(e.toLowerCase()===r[t].to...
  function a (line 22) | function a(t,n,i,s,o){if(t&&t[o]&&t!==e)return t[o].call(t,n,i);switch(r...
  function o (line 48) | function o(t){var n=this;n._uid="io:"+s++,n._init(t),e.io._map[n._uid]=n}
  function i (line 65) | function i(e,t){return e==="ok"?!0:t}
  function f (line 131) | function f(t,r,u,l){var c=n(arguments,0,!0),h=i(u)?u:null,p,d,v,m,g,y,b,...
  function r (line 147) | function r(){this._plugins={}}

FILE: test/browser/test-browser-instrumentation.js
  function runPhantom (line 16) | function runPhantom(cmd, script, port, files) {

FILE: test/cli-helper.js
  function setVerbose (line 58) | function setVerbose(flag) {
  function setOpts (line 61) | function setOpts(userOpts) {
  function resetOpts (line 65) | function resetOpts() {
  function runCommand (line 69) | function runCommand(command, args, envVars, callback) {
  function customHook (line 151) | function customHook(lazyHook, callback) {

FILE: test/cli/sample-project/amd/ipsum.js
  function sum (line 3) | function sum(a, b) {

FILE: test/cli/sample-project/includeAllSources/unloadedFileWithFunctionDeclaration.js
  function foo (line 1) | function foo() {

FILE: test/cli/sample-project/lib/util/es-module.js
  function bar (line 3) | function bar() {

FILE: test/cli/sample-project/test/global-leak.js
  function copyGlobals (line 9) | function copyGlobals(target) {

FILE: test/cli/test-lots-of-files.js
  function fileFor (line 16) | function fileFor(i) {
  function createCode (line 20) | function createCode() {
  function createTest (line 33) | function createTest() {

FILE: test/es6.js
  function tryThis (line 3) | function tryThis(str, feature) {

FILE: test/helper.js
  function Verifier (line 8) | function Verifier(opts) {
  function pad (line 18) | function pad(str, len) {
  function annotatedCode (line 26) | function annotatedCode(code) {
  function setup (line 74) | function setup(file, codeArray, opts) {

FILE: test/loader.js
  function loadDirTests (line 7) | function loadDirTests(dir, pat) {
  function runTests (line 17) | function runTests(pat, reporter, opts, callback) {

FILE: test/other/test-file-writer.js
  function testContents (line 14) | function testContents(test) {
  function fileNames (line 19) | function fileNames() {
  function testAllFiles (line 28) | function testAllFiles(test) {
  function battery (line 36) | function battery(sync) {

FILE: test/other/test-store.js
  function NStore (line 78) | function NStore() {
  function NStore (line 93) | function NStore() {}
  function NStore (line 110) | function NStore() {}

FILE: test/run-again.js
  function runTests (line 8) | function runTests() {

FILE: test/run.js
  function runTests (line 40) | function runTests(pat, forceCover) {
Condensed preview — 202 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (759K chars).
[
  {
    "path": ".gitignore",
    "chars": 198,
    "preview": "lib-cov\n.DS_Store\n*.seed\n*.log\n*.csv\n*.dat\n*.out\n*.pid\n*.gz\n\npids\nlogs\nresults\n\nnode_modules/\nbower_components/\n.idea/\nh"
  },
  {
    "path": ".jshintignore",
    "chars": 101,
    "preview": "lib/assets/vendor\ntest/cli/sample-project\ntest/cli/sample-project-link\ntest/browser/support/vendor\n\n\n"
  },
  {
    "path": ".jshintrc",
    "chars": 1018,
    "preview": "{\n    \"bitwise\": true,\n    \"camelcase\": false,\n    \"curly\": true,\n    \"eqeqeq\": true,\n    \"forin\": true,\n    \"freeze\": t"
  },
  {
    "path": ".travis.yml",
    "chars": 270,
    "preview": "language: node_js\n\nnode_js:\n  - \"0.10\"\n  - \"0.12\"\n\nsudo: false\n\nbranches:\n  except:\n    - gh-pages\n\nscript:\n  - npm test"
  },
  {
    "path": "CHANGELOG.md",
    "chars": 14688,
    "preview": "Changelog\n---------\n\n<table>\n<tr>\n<td>0.4.5</td>\n<td>\n    <ul>\n        <li>log filename when file fails to parse using e"
  },
  {
    "path": "LICENSE",
    "chars": 1483,
    "preview": "Copyright 2012 Yahoo! Inc.\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodi"
  },
  {
    "path": "README.md",
    "chars": 12107,
    "preview": "## Istanbul - a JS code coverage tool written in JS\n\n**Archive notice: This repo has been inactive for 7 years and is no"
  },
  {
    "path": "coverage.json.md",
    "chars": 3027,
    "preview": "# Format of coverage.json\n\n`coverage.json` contains a report object, which is a hash where keys are file names (absolute"
  },
  {
    "path": "download-escodegen-browser.sh",
    "chars": 612,
    "preview": "#!/bin/sh\n\nESCG_DIR=node_modules/escodegen\nESCG_VERSION=`grep '\"version\"' ${ESCG_DIR}/package.json  | awk '{print $2}' |"
  },
  {
    "path": "generate-pages.sh",
    "chars": 213,
    "preview": "set -ex\nexport PAGES_DIR=../istanbul-pages\nnpm test --coverage\nmkdir -p public/apidocs\nyuidoc .\nrsync -rvt ./public/apid"
  },
  {
    "path": "ignoring-code-for-coverage.md",
    "chars": 4443,
    "preview": "## Ignoring code for coverage purposes\n\nSome branches in JS code are typically hard, if not impossible to test.\n\nExample"
  },
  {
    "path": "index.js",
    "chars": 4337,
    "preview": "/*\nCopyright (c) 2012, Yahoo! Inc.  All rights reserved.\nCopyrights licensed under the New BSD License. See the accompan"
  },
  {
    "path": "lib/assets/base.css",
    "chars": 5143,
    "preview": "body, html {\n  margin:0; padding: 0;\n  height: 100%;\n}\nbody {\n    font-family: Helvetica Neue, Helvetica, Arial;\n    fon"
  },
  {
    "path": "lib/assets/sorter.js",
    "chars": 5174,
    "preview": "var addSorting = (function () {\n    \"use strict\";\n    var cols,\n        currentSort = {\n            index: 0,\n          "
  },
  {
    "path": "lib/assets/vendor/prettify.css",
    "chars": 676,
    "preview": ".pln{color:#000}@media screen{.str{color:#080}.kwd{color:#008}.com{color:#800}.typ{color:#606}.lit{color:#066}.pun,.opn,"
  },
  {
    "path": "lib/assets/vendor/prettify.js",
    "chars": 17569,
    "preview": "window.PR_SHOULD_USE_CONTINUATION=true;(function(){var h=[\"break,continue,do,else,for,if,return,while\"];var u=[h,\"auto,c"
  },
  {
    "path": "lib/cli.js",
    "chars": 2506,
    "preview": "#!/usr/bin/env node\n\n/*\n Copyright (c) 2012, Yahoo! Inc.  All rights reserved.\n Copyrights licensed under the New BSD Li"
  },
  {
    "path": "lib/collector.js",
    "chars": 4668,
    "preview": "/*\n Copyright (c) 2012, Yahoo! Inc.  All rights reserved.\n Copyrights licensed under the New BSD License. See the accomp"
  },
  {
    "path": "lib/command/check-coverage.js",
    "chars": 7669,
    "preview": "/*\n Copyright (c) 2012, Yahoo! Inc.  All rights reserved.\n Copyrights licensed under the New BSD License. See the accomp"
  },
  {
    "path": "lib/command/common/run-with-cover.js",
    "chars": 12060,
    "preview": "/*\n Copyright (c) 2012, Yahoo! Inc.  All rights reserved.\n Copyrights licensed under the New BSD License. See the accomp"
  },
  {
    "path": "lib/command/cover.js",
    "chars": 825,
    "preview": "/*\n Copyright (c) 2012, Yahoo! Inc.  All rights reserved.\n Copyrights licensed under the New BSD License. See the accomp"
  },
  {
    "path": "lib/command/help.js",
    "chars": 4312,
    "preview": "/*\n Copyright (c) 2012, Yahoo! Inc.  All rights reserved.\n Copyrights licensed under the New BSD License. See the accomp"
  },
  {
    "path": "lib/command/index.js",
    "chars": 1147,
    "preview": "/*\n Copyright (c) 2012, Yahoo! Inc.  All rights reserved.\n Copyrights licensed under the New BSD License. See the accomp"
  },
  {
    "path": "lib/command/instrument.js",
    "chars": 10686,
    "preview": "/*\n Copyright (c) 2012, Yahoo! Inc.  All rights reserved.\n Copyrights licensed under the New BSD License. See the accomp"
  },
  {
    "path": "lib/command/report.js",
    "chars": 4688,
    "preview": "/*\n Copyright (c) 2012, Yahoo! Inc.  All rights reserved.\n Copyrights licensed under the New BSD License. See the accomp"
  },
  {
    "path": "lib/command/test.js",
    "chars": 843,
    "preview": "/*\n Copyright (c) 2012, Yahoo! Inc.  All rights reserved.\n Copyrights licensed under the New BSD License. See the accomp"
  },
  {
    "path": "lib/config.js",
    "chars": 15463,
    "preview": "/*\n Copyright (c) 2013, Yahoo! Inc.  All rights reserved.\n Copyrights licensed under the New BSD License. See the accomp"
  },
  {
    "path": "lib/hook.js",
    "chars": 7690,
    "preview": "/*\n Copyright (c) 2012, Yahoo! Inc.  All rights reserved.\n Copyrights licensed under the New BSD License. See the accomp"
  },
  {
    "path": "lib/instrumenter.js",
    "chars": 45147,
    "preview": "/*\n Copyright (c) 2012, Yahoo! Inc.  All rights reserved.\n Copyrights licensed under the New BSD License. See the accomp"
  },
  {
    "path": "lib/object-utils.js",
    "chars": 14309,
    "preview": "/*\n Copyright (c) 2012, Yahoo! Inc.  All rights reserved.\n Copyrights licensed under the New BSD License. See the accomp"
  },
  {
    "path": "lib/register-plugins.js",
    "chars": 316,
    "preview": "\n/*\n Copyright (c) 2012, Yahoo! Inc.  All rights reserved.\n Copyrights licensed under the New BSD License. See the accom"
  },
  {
    "path": "lib/report/clover.js",
    "chars": 7760,
    "preview": "var path = require('path'),\n    util = require('util'),\n    Report = require('./index'),\n    FileWriter = require('../ut"
  },
  {
    "path": "lib/report/cobertura.js",
    "chars": 7317,
    "preview": "/*\n Copyright (c) 2012, Yahoo! Inc.  All rights reserved.\n Copyrights licensed under the New BSD License. See the accomp"
  },
  {
    "path": "lib/report/common/defaults.js",
    "chars": 1362,
    "preview": "/*\n Copyright (c) 2013, Yahoo! Inc.  All rights reserved.\n Copyrights licensed under the New BSD License. See the accomp"
  },
  {
    "path": "lib/report/html.js",
    "chars": 22193,
    "preview": "/*\n Copyright (c) 2012, Yahoo! Inc.  All rights reserved.\n Copyrights licensed under the New BSD License. See the accomp"
  },
  {
    "path": "lib/report/index.js",
    "chars": 3374,
    "preview": "/*\n Copyright (c) 2012, Yahoo! Inc.  All rights reserved.\n Copyrights licensed under the New BSD License. See the accomp"
  },
  {
    "path": "lib/report/json-summary.js",
    "chars": 2570,
    "preview": "/*\n Copyright (c) 2012, Yahoo! Inc.  All rights reserved.\n Copyrights licensed under the New BSD License. See the accomp"
  },
  {
    "path": "lib/report/json.js",
    "chars": 2136,
    "preview": "/*\n Copyright (c) 2012, Yahoo! Inc.  All rights reserved.\n Copyrights licensed under the New BSD License. See the accomp"
  },
  {
    "path": "lib/report/lcov.js",
    "chars": 2097,
    "preview": "/*\n Copyright (c) 2012, Yahoo! Inc.  All rights reserved.\n Copyrights licensed under the New BSD License. See the accomp"
  },
  {
    "path": "lib/report/lcovonly.js",
    "chars": 3503,
    "preview": "/*\n Copyright (c) 2012, Yahoo! Inc.  All rights reserved.\n Copyrights licensed under the New BSD License. See the accomp"
  },
  {
    "path": "lib/report/none.js",
    "chars": 895,
    "preview": "/*\n Copyright (c) 2012, Yahoo! Inc.  All rights reserved.\n Copyrights licensed under the New BSD License. See the accomp"
  },
  {
    "path": "lib/report/teamcity.js",
    "chars": 3083,
    "preview": "/*\n Copyright (c) 2012, Yahoo! Inc.  All rights reserved.\n Copyrights licensed under the New BSD License. See the accomp"
  },
  {
    "path": "lib/report/templates/foot.txt",
    "chars": 512,
    "preview": "<div class='push'></div><!-- for sticky footer -->\n</div><!-- /wrapper -->\n<div class='footer quiet pad2 space-top1 cent"
  },
  {
    "path": "lib/report/templates/head.txt",
    "chars": 1927,
    "preview": "<!doctype html>\n<html lang=\"en\">\n<head>\n    <title>Code coverage report for {{entity}}</title>\n    <meta charset=\"utf-8\""
  },
  {
    "path": "lib/report/text-lcov.js",
    "chars": 1104,
    "preview": "var LcovOnly = require('./lcovonly'),\n  util = require('util');\n\n/**\n * a `Report` implementation that produces an LCOV "
  },
  {
    "path": "lib/report/text-summary.js",
    "chars": 3303,
    "preview": "/*\n Copyright (c) 2012, Yahoo! Inc.  All rights reserved.\n Copyrights licensed under the New BSD License. See the accomp"
  },
  {
    "path": "lib/report/text.js",
    "chars": 7059,
    "preview": "/*\n Copyright (c) 2012, Yahoo! Inc.  All rights reserved.\n Copyrights licensed under the New BSD License. See the accomp"
  },
  {
    "path": "lib/reporter.js",
    "chars": 3677,
    "preview": "/*\n Copyright (c) 2014, Yahoo! Inc.  All rights reserved.\n Copyrights licensed under the New BSD License. See the accomp"
  },
  {
    "path": "lib/store/fslookup.js",
    "chars": 1535,
    "preview": "/*\n Copyright (c) 2012, Yahoo! Inc.  All rights reserved.\n Copyrights licensed under the New BSD License. See the accomp"
  },
  {
    "path": "lib/store/index.js",
    "chars": 4077,
    "preview": "/*\n Copyright (c) 2012, Yahoo! Inc.  All rights reserved.\n Copyrights licensed under the New BSD License. See the accomp"
  },
  {
    "path": "lib/store/memory.js",
    "chars": 1105,
    "preview": "/*\n Copyright (c) 2012, Yahoo! Inc.  All rights reserved.\n Copyrights licensed under the New BSD License. See the accomp"
  },
  {
    "path": "lib/store/tmp.js",
    "chars": 2094,
    "preview": "/*\n Copyright (c) 2012, Yahoo! Inc.  All rights reserved.\n Copyrights licensed under the New BSD License. See the accomp"
  },
  {
    "path": "lib/util/factory.js",
    "chars": 2822,
    "preview": "/*\n Copyright (c) 2012, Yahoo! Inc.  All rights reserved.\n Copyrights licensed under the New BSD License. See the accomp"
  },
  {
    "path": "lib/util/file-matcher.js",
    "chars": 2314,
    "preview": "/*\n Copyright (c) 2012, Yahoo! Inc.  All rights reserved.\n Copyrights licensed under the New BSD License. See the accomp"
  },
  {
    "path": "lib/util/file-writer.js",
    "chars": 4160,
    "preview": "/*\n Copyright (c) 2012, Yahoo! Inc.  All rights reserved.\n Copyrights licensed under the New BSD License. See the accomp"
  },
  {
    "path": "lib/util/help-formatter.js",
    "chars": 798,
    "preview": "/*\n Copyright (c) 2012, Yahoo! Inc.  All rights reserved.\n Copyrights licensed under the New BSD License. See the accomp"
  },
  {
    "path": "lib/util/input-error.js",
    "chars": 283,
    "preview": "/*\n Copyright (c) 2012, Yahoo! Inc.  All rights reserved.\n Copyrights licensed under the New BSD License. See the accomp"
  },
  {
    "path": "lib/util/insertion-text.js",
    "chars": 3117,
    "preview": "/*\n Copyright (c) 2012, Yahoo! Inc.  All rights reserved.\n Copyrights licensed under the New BSD License. See the accomp"
  },
  {
    "path": "lib/util/meta.js",
    "chars": 376,
    "preview": "/*\n Copyright (c) 2012, Yahoo! Inc.  All rights reserved.\n Copyrights licensed under the New BSD License. See the accomp"
  },
  {
    "path": "lib/util/tree-summarizer.js",
    "chars": 6473,
    "preview": "/*\n Copyright (c) 2012, Yahoo! Inc.  All rights reserved.\n Copyrights licensed under the New BSD License. See the accomp"
  },
  {
    "path": "lib/util/writer.js",
    "chars": 2741,
    "preview": "/*\n Copyright (c) 2012, Yahoo! Inc.  All rights reserved.\n Copyrights licensed under the New BSD License. See the accomp"
  },
  {
    "path": "lib/util/yui-load-hook.js",
    "chars": 1827,
    "preview": "/*\n Copyright (c) 2012, Yahoo! Inc.  All rights reserved.\n Copyrights licensed under the New BSD License. See the accomp"
  },
  {
    "path": "misc/ast/assign.js",
    "chars": 30,
    "preview": "var x = args[0];\noutput = x;\n\n"
  },
  {
    "path": "misc/ast/block-label.js",
    "chars": 457,
    "preview": "\nvar tok = { type: 'keyword', length: 7 },\n    max_line_length = 6,\n    prev_token = { type: \"keyword\" };\n\nout: {\n    if"
  },
  {
    "path": "misc/ast/cond.js",
    "chars": 104,
    "preview": "var x = 10, y, z;\n\ny = (z=10,x < 10) ? (z--,1) : (z++,2);\nconsole.log('Y=' + y);\nconsole.log('Z=' + z);\n"
  },
  {
    "path": "misc/ast/defun-compact.js",
    "chars": 93,
    "preview": "var foo =function () { var ret = 'foo';\n    return ret;\n};\n\nfunction bar() { return 'bar'; }\n"
  },
  {
    "path": "misc/ast/defun.js",
    "chars": 138,
    "preview": "var foo =function () {\n    var ret = 'foo';\n    return ret;\n};\n\nfunction bar() {\n    return 'bar';\n}\n\nconsole.log(foo() "
  },
  {
    "path": "misc/ast/do-statement.js",
    "chars": 37,
    "preview": "var i = 5;\ndo\n\ti--;\n while (i > 0);\n\n"
  },
  {
    "path": "misc/ast/dot.js",
    "chars": 59,
    "preview": "var foo = { bar: { baz: [ 1, 2 ] } };\nfoo.bar.baz[0] = 3;\n\n"
  },
  {
    "path": "misc/ast/eq.js",
    "chars": 38,
    "preview": " if (1 === 2) { console.log('foo'); }\n"
  },
  {
    "path": "misc/ast/expr.js",
    "chars": 36,
    "preview": "var a = 5,\n    b =  a > 0 && a < 4;\n"
  },
  {
    "path": "misc/ast/for-block.js",
    "chars": 50,
    "preview": "for (var i =0; i<10; i++) {\n    console.log(i);\n}\n"
  },
  {
    "path": "misc/ast/for-compact.js",
    "chars": 42,
    "preview": "for (var i =0; i<10; i++) console.log(i);\n"
  },
  {
    "path": "misc/ast/for-multi.js",
    "chars": 61,
    "preview": "for (var i = 0, j=0; i<10; i++, j++)\n    console.log(i + j);\n"
  },
  {
    "path": "misc/ast/for-statement.js",
    "chars": 49,
    "preview": "var i;\nfor (i =0; i<10; i++)\n    console.log(i);\n"
  },
  {
    "path": "misc/ast/forin-block.js",
    "chars": 86,
    "preview": "var foo = { a: 10, b: 20 };\nfor (var k in foo) {\n    console.log(k + '=' + foo[k]);\n}\n"
  },
  {
    "path": "misc/ast/forin-compact.js",
    "chars": 79,
    "preview": "var foo = { a: 10, b: 20 };\nfor (var k in foo) console.log(k + '=' + foo[k]);\n\n"
  },
  {
    "path": "misc/ast/forin-statement.js",
    "chars": 83,
    "preview": "var foo = { a: 10, b: 20 };\nfor (var k in foo)\n    console.log(k + '=' + foo[k]);\n\n"
  },
  {
    "path": "misc/ast/func.js",
    "chars": 76,
    "preview": "var x = 2, output;\noutput = x < 5 ?\n   (function() { return 42; }())\n : 15;\n"
  },
  {
    "path": "misc/ast/if-block.js",
    "chars": 117,
    "preview": "if (20 > 10) {\n    console.log('>10');\n} else if (x < 10) {\n    console.log('<10');\n} else {\n    console.log('10');\n}"
  },
  {
    "path": "misc/ast/if-compact.js",
    "chars": 94,
    "preview": "if (20 > 10) console.log('>10'); else if (x < 10) console.log('<10'); else console.log('10');\n"
  },
  {
    "path": "misc/ast/if-only.js",
    "chars": 34,
    "preview": "if (20 > 10) console.log('Yay!');\n"
  },
  {
    "path": "misc/ast/if-statement.js",
    "chars": 117,
    "preview": "var x = 25;\nif (x > 10)\n    console.log('>10');\nelse if (x < 10)\n    console.log('<10');\nelse\n    console.log('10');\n"
  },
  {
    "path": "misc/ast/incr-slice.js",
    "chars": 70,
    "preview": "var foo = { lineMap: { 1: 0 }}, bar = {\n    2: 0\n};\nfoo.lineMap[1]++;\n"
  },
  {
    "path": "misc/ast/label.js",
    "chars": 250,
    "preview": "var items= [],itemsPassed = 0;\nvar i, j;\n\nfunction foo()\n{\ntop:\n    for (i = 0; i < items.length; i++){\n        for (j ="
  },
  {
    "path": "misc/ast/nested-if.js",
    "chars": 74,
    "preview": "if (process.argv[2])\n    if (process.argv[3])\n        console.log('TT');\n\n"
  },
  {
    "path": "misc/ast/pfcall.js",
    "chars": 51,
    "preview": "(function () { (function() { return 1; })(); })();\n"
  },
  {
    "path": "misc/ast/preamble.js",
    "chars": 3632,
    "preview": "if (typeof __yct__ === 'undefined') {\n    __yct__ = {};\n}\nvar __ycf14f8be05b4467d47fccdd98300cc2c30 = __yct__['/Users/an"
  },
  {
    "path": "misc/ast/switch-statement.js",
    "chars": 214,
    "preview": "var foo = '10';\n\nswitch (foo) {\n    case 5:\n    case 10:\n        console.log('10');\n        break;\n    case 20:\n        "
  },
  {
    "path": "misc/ast/try-block.js",
    "chars": 139,
    "preview": "try {\n    if (process.argv[2]) {\n        throw \"foo\";\n    }\n} catch(ex) {\n    console.log(ex);\n}\n//finally {\n//    conso"
  },
  {
    "path": "misc/ast/try-statement.js",
    "chars": 105,
    "preview": "try { if (process.argv[2]) throw \"foo\"; } catch(ex) { console.log(ex); } finally { console.log('done'); }"
  },
  {
    "path": "misc/ast/while-block.js",
    "chars": 47,
    "preview": "var i = 10;\nwhile (i--) {\n    console.log(i);\n}"
  },
  {
    "path": "misc/ast/while-compact.js",
    "chars": 37,
    "preview": "var i=10;\nwhile (i--) console.log(i);"
  },
  {
    "path": "misc/ast/while-for.js",
    "chars": 79,
    "preview": "var i = 10,\n    j;\nwhile (i--)\n    for (j=0; j<i; j++)\n        console.log(j);\n"
  },
  {
    "path": "misc/ast/while-statement.js",
    "chars": 81,
    "preview": "var i = 10;\nfoo: while (i--) {\n    if (i === 2) break foo;\n    console.log(i);\n}\n"
  },
  {
    "path": "misc/config/istanbul-config-alt.json",
    "chars": 855,
    "preview": "{\n    \"//\": \"None of this is implemented; just ideas at this point - responsibility-specific config\",\n\n    \"verbose\": fa"
  },
  {
    "path": "misc/config/istanbul-config.json",
    "chars": 919,
    "preview": "{\n    \"//\": \"None of this is implemented; just ideas at this point - command specific config\",\n    \"cover\": {\n        \"r"
  },
  {
    "path": "misc/samples/coverage.js",
    "chars": 5156,
    "preview": "var path = require('path'),\n    fs = require('fs'),\n    istanbul = require('istanbul'),\n    hook = istanbul.hook,\n    In"
  },
  {
    "path": "package.json",
    "chars": 4699,
    "preview": "{\n  \"name\": \"istanbul\",\n  \"version\": \"0.4.5\",\n  \"description\": \"Yet another JS code coverage tool that computes statemen"
  },
  {
    "path": "test/browser/support/index.html",
    "chars": 5239,
    "preview": "<!doctype html>\n<html>\n<head>\n<meta charset='utf-8'>\n<title>Instrumentation test on the browser</title>\n<script src='/_e"
  },
  {
    "path": "test/browser/support/phantom-test.client.js",
    "chars": 1409,
    "preview": "/*global phantom, window,document */\nvar system = require('system'),\n    page = require('webpage').create(),\n    args = "
  },
  {
    "path": "test/browser/support/server.js",
    "chars": 5029,
    "preview": "/*jslint nomen: true */\nvar handlebars = require('handlebars'),\n    path = require('path'),\n    fs = require('fs'),\n    "
  },
  {
    "path": "test/browser/support/vendor/yui-support.js",
    "chars": 115090,
    "preview": "/*\n YUI 3.17.2 (build 9c3c78e)\n Copyright 2014 Yahoo! Inc. All rights reserved.\n Licensed under the BSD License.\n http:/"
  },
  {
    "path": "test/browser/test-browser-instrumentation.js",
    "chars": 3572,
    "preview": "/*jslint nomen: true */\nvar which = require('which'),\n    phantom,\n    path = require('path'),\n    fs = require('fs'),\n "
  },
  {
    "path": "test/cli/package.json",
    "chars": 182,
    "preview": "{\n    \"name\": \"istanbul-demo-project\",\n    \"version\": \"0.0.1-12\",\n    \"description\": \"Dummy project for testing istanbul"
  },
  {
    "path": "test/cli/sample-project/.gitignore",
    "chars": 16,
    "preview": "!node_modules/\n\n"
  },
  {
    "path": "test/cli/sample-project/amd/ipsum.js",
    "chars": 117,
    "preview": "define(function(){\n\n    function sum(a, b) {\n        return a + b;\n    }\n\n    return {\n        sum : sum\n    };\n\n});\n"
  },
  {
    "path": "test/cli/sample-project/amd/lorem.js",
    "chars": 123,
    "preview": "define(['./ipsum'], function (ipsum) {\n\n    return function exec(a, b, c){\n        return ipsum.sum(a, b) * c;\n    };\n\n}"
  },
  {
    "path": "test/cli/sample-project/config-check-each.istanbul.yml",
    "chars": 133,
    "preview": "check:\n  each:\n    statements: 72\n    functions: 50\n    branches: 72\n    lines: 72\n    excludes:\n        - lib/bar.js # "
  },
  {
    "path": "test/cli/sample-project/config-check-global.istanbul.yml",
    "chars": 312,
    "preview": "check:\n  global:\n    statements: 72\n    functions: 50\n    branches: 72\n    lines: 72\n    # Example: Could exclude all fi"
  },
  {
    "path": "test/cli/sample-project/config-check-mixed.istanbul.yml",
    "chars": 211,
    "preview": "check:\n  global:\n    statements: 80\n    functions: 80\n    branches: 40\n    lines: 40\n  each:\n    statements: 72\n    func"
  },
  {
    "path": "test/cli/sample-project/config.istanbul.yml",
    "chars": 118,
    "preview": "reporting:\n  reports:\n    - cobertura\n    - html\n    - lcovonly\n  report-config:\n    cobertura:\n      file: 'foo.xml'\n"
  },
  {
    "path": "test/cli/sample-project/includeAllSources/unloadedFile.js",
    "chars": 40,
    "preview": "var foo = 'bar';\n\nmodule.exports = foo;\n"
  },
  {
    "path": "test/cli/sample-project/includeAllSources/unloadedFileWithFunctionDeclaration.js",
    "chars": 60,
    "preview": "function foo() {\n    return 'bar';\n}\n\nmodule.exports = foo;\n"
  },
  {
    "path": "test/cli/sample-project/lib/bar.js",
    "chars": 265,
    "preview": "var dep = require('dependency'),\n    vendor = require('../vendor/dummy_vendor_lib'),\n    generator = require('./util/gen"
  },
  {
    "path": "test/cli/sample-project/lib/foo.js",
    "chars": 385,
    "preview": "var dep = require('dependency'),\n    vendor = require('../vendor/dummy_vendor_lib'),\n    generator = require('./util/gen"
  },
  {
    "path": "test/cli/sample-project/lib/util/bad.js",
    "chars": 24,
    "preview": "var junk = 10 : 5 : 10;\n"
  },
  {
    "path": "test/cli/sample-project/lib/util/es-module.js",
    "chars": 75,
    "preview": "import foo from 'foo';\n\nexport default function bar() {\n   return foo();\n};"
  },
  {
    "path": "test/cli/sample-project/lib/util/generate-names.js",
    "chars": 112,
    "preview": "module.exports = {\n    generateName: function () {\n        return 'generated-' + new Date().getTime();\n    }\n};\n"
  },
  {
    "path": "test/cli/sample-project/lib/util/unused.js",
    "chars": 87,
    "preview": "module.exports = {\n    sayHello: function () {\n        console.log('Hello');\n    }\n};\n\n"
  },
  {
    "path": "test/cli/sample-project/test/amd-run.js",
    "chars": 336,
    "preview": "// RequireJS uses `vm.runInThisContext` see issue #23\n// make sure we add hooks for it as well\n\nvar rjs = require('requi"
  },
  {
    "path": "test/cli/sample-project/test/global-leak.js",
    "chars": 801,
    "preview": "#!/usr/bin/env node\n\n/*globals global */\nvar assert = require('assert'),\n    g1 = {},\n    g2 = {},\n    keys;\n\nfunction c"
  },
  {
    "path": "test/cli/sample-project/test/run.js",
    "chars": 569,
    "preview": "#!/usr/bin/env node\n\nvar assert = require('assert'),\n    foo = require('../lib/foo'),\n    bar = require('../lib/bar'),\n "
  },
  {
    "path": "test/cli/sample-project/vendor/dummy_vendor_lib.js",
    "chars": 214,
    "preview": "module.exports = {\n    vendorFoo: function (input) {\n        return input < 10 ? input : input + 100;\n    },\n    vendorB"
  },
  {
    "path": "test/cli/test-base-cli.js",
    "chars": 1857,
    "preview": "/*jslint nomen: true */\nvar helper = require('../cli-helper');\n\nmodule.exports = {\n    setUp: function (cb) {\n        he"
  },
  {
    "path": "test/cli/test-check-coverage-command.js",
    "chars": 13168,
    "preview": "/*jslint nomen: true */\nvar path = require('path'),\n    fs = require('fs'),\n    rimraf = require('rimraf'),\n    mkdirp ="
  },
  {
    "path": "test/cli/test-clover-report.js",
    "chars": 1887,
    "preview": "/*jslint nomen: true */\nvar path = require('path'),\n    fs = require('fs'),\n    rimraf = require('rimraf'),\n    mkdirp ="
  },
  {
    "path": "test/cli/test-cobertura-report.js",
    "chars": 1919,
    "preview": "/*jslint nomen: true */\nvar path = require('path'),\n    fs = require('fs'),\n    rimraf = require('rimraf'),\n    mkdirp ="
  },
  {
    "path": "test/cli/test-cover-command.js",
    "chars": 14657,
    "preview": "/*jslint nomen: true */\nvar path = require('path'),\n    fs = require('fs'),\n    rimraf = require('rimraf'),\n    mkdirp ="
  },
  {
    "path": "test/cli/test-html-report.js",
    "chars": 11615,
    "preview": "/*jslint nomen: true */\nvar path = require('path'),\n    fs = require('fs'),\n    rimraf = require('rimraf'),\n    mkdirp ="
  },
  {
    "path": "test/cli/test-include-pid.js",
    "chars": 3419,
    "preview": "/*jslint nomen: true */\nvar path = require('path'),\n    fs = require('fs'),\n    glob = require('glob'),\n    rimraf = req"
  },
  {
    "path": "test/cli/test-instrument-command.js",
    "chars": 7922,
    "preview": "/*jslint nomen: true */\nvar path = require('path'),\n    fs = require('fs'),\n    existsSync = fs.existsSync || path.exist"
  },
  {
    "path": "test/cli/test-json-report.js",
    "chars": 2131,
    "preview": "/*jslint nomen: true */\nvar path = require('path'),\n    fs = require('fs'),\n    rimraf = require('rimraf'),\n    mkdirp ="
  },
  {
    "path": "test/cli/test-json-summary-report.js",
    "chars": 2466,
    "preview": "/*jslint nomen: true */\nvar path = require('path'),\n    fs = require('fs'),\n    rimraf = require('rimraf'),\n    mkdirp ="
  },
  {
    "path": "test/cli/test-lcov-report.js",
    "chars": 2080,
    "preview": "/*jslint nomen: true */\nvar path = require('path'),\n    fs = require('fs'),\n    rimraf = require('rimraf'),\n    mkdirp ="
  },
  {
    "path": "test/cli/test-lcovonly-report.js",
    "chars": 2348,
    "preview": "/*jslint nomen: true */\nvar path = require('path'),\n    fs = require('fs'),\n    rimraf = require('rimraf'),\n    mkdirp ="
  },
  {
    "path": "test/cli/test-lots-of-files.js",
    "chars": 2693,
    "preview": "/*jslint nomen: true */\n/*jslint nomen: true */\nvar path = require('path'),\n    fs = require('fs'),\n    rimraf = require"
  },
  {
    "path": "test/cli/test-none-report.js",
    "chars": 551,
    "preview": "/*jslint nomen: true */\nvar Reporter = require('../../lib/report/none'),\n    Report = require('../../lib/report');\n\nmodu"
  },
  {
    "path": "test/cli/test-report-command.js",
    "chars": 4004,
    "preview": "/*jslint nomen: true */\nvar path = require('path'),\n    fs = require('fs'),\n    rimraf = require('rimraf'),\n    mkdirp ="
  },
  {
    "path": "test/cli/test-teamcity-report.js",
    "chars": 2793,
    "preview": "/*jslint nomen: true */\nvar path = require('path'),\n    fs = require('fs'),\n    rimraf = require('rimraf'),\n    mkdirp ="
  },
  {
    "path": "test/cli/test-test-command.js",
    "chars": 1626,
    "preview": "/*jslint nomen: true */\nvar path = require('path'),\n    fs = require('fs'),\n    rimraf = require('rimraf'),\n    mkdirp ="
  },
  {
    "path": "test/cli/test-text-lcov-report.js",
    "chars": 1363,
    "preview": "/*jslint nomen: true */\nvar path = require('path'),\n    fs = require('fs'),\n    mkdirp = require('mkdirp'),\n    rimraf ="
  },
  {
    "path": "test/cli-helper.js",
    "chars": 7652,
    "preview": "/*jslint nomen: true */\nvar path = require('path'),\n    fs = require('fs'),\n    cp = require('child_process'),\n    Modul"
  },
  {
    "path": "test/common.js",
    "chars": 451,
    "preview": "/*jslint nomen:true*/\nvar path = require('path'),\n    buildDir = path.resolve(__dirname, '..', 'build');\n\nmodule.exports"
  },
  {
    "path": "test/es6.js",
    "chars": 1533,
    "preview": "var esprima = require('esprima');\n\nfunction tryThis(str, feature) {\n    try {\n        /*jshint evil: true */\n        eva"
  },
  {
    "path": "test/helper.js",
    "chars": 5043,
    "preview": "/*jslint nomen: true */\nvar Instrumenter = require('../lib/instrumenter'),\n    vm = require('vm'),\n    NO_OP = function "
  },
  {
    "path": "test/instrumentation/test-do.js",
    "chars": 2602,
    "preview": "/*jslint nomen: true */\nvar helper = require('../helper'),\n    code,\n    verifier;\n\n/*jshint maxlen: 500 */\nmodule.expor"
  },
  {
    "path": "test/instrumentation/test-es6-arrow-fn.js",
    "chars": 1908,
    "preview": "/*jslint nomen: true */\nvar helper = require('../helper'),\n    code,\n    verifier;\n\n/*jshint maxlen: 500 */\nif (require("
  },
  {
    "path": "test/instrumentation/test-es6-export.js",
    "chars": 1296,
    "preview": "/*jslint nomen: true */\nvar helper = require('../helper'),\n   code,\n   verifier;\n\nif (require('../es6').isExportAvailabl"
  },
  {
    "path": "test/instrumentation/test-es6-forof.js",
    "chars": 1711,
    "preview": "/*jslint nomen: true */\nvar helper = require('../helper'),\n    code,\n    verifier;\n\n/*jshint maxlen: 500 */\nif (require("
  },
  {
    "path": "test/instrumentation/test-es6-import.js",
    "chars": 746,
    "preview": "/*jslint nomen: true */\nvar helper = require('../helper'),\n   code,\n   verifier;\n\nif (require('../es6').isImportAvailabl"
  },
  {
    "path": "test/instrumentation/test-es6-super.js",
    "chars": 2195,
    "preview": "/*jslint nomen: true */\nvar helper = require('../helper'),\n    code,\n    verifier;\n\nif (require('../es6').isSuperAvailab"
  },
  {
    "path": "test/instrumentation/test-es6-yield.js",
    "chars": 1025,
    "preview": "/*jslint nomen: true */\nvar helper = require('../helper'),\n    code,\n    verifier;\n\nif (require('../es6').isYieldAvailab"
  },
  {
    "path": "test/instrumentation/test-expressions.js",
    "chars": 2860,
    "preview": "/*jslint nomen: true */\nvar helper = require('../helper'),\n    code,\n    verifier;\n\n/*jshint maxlen: 500 */\nmodule.expor"
  },
  {
    "path": "test/instrumentation/test-for.js",
    "chars": 6670,
    "preview": "/*jslint nomen: true */\nvar helper = require('../helper'),\n    code,\n    verifier;\n\nmodule.exports = {\n    \"with a simpl"
  },
  {
    "path": "test/instrumentation/test-forin.js",
    "chars": 1657,
    "preview": "/*jslint nomen: true */\nvar helper = require('../helper'),\n    code,\n    verifier;\n\n/*jshint maxlen: 500 */\nmodule.expor"
  },
  {
    "path": "test/instrumentation/test-functions.js",
    "chars": 3794,
    "preview": "/*jslint nomen: true */\nvar helper = require('../helper'),\n    code,\n    verifier;\n\n/*jshint maxlen: 500 */\nmodule.expor"
  },
  {
    "path": "test/instrumentation/test-if-with-hints.js",
    "chars": 8185,
    "preview": "/*jslint nomen: true */\nvar helper = require('../helper'),\n    code,\n    verifier;\n\n/*jshint maxlen: 500 */\nmodule.expor"
  },
  {
    "path": "test/instrumentation/test-if.js",
    "chars": 21960,
    "preview": "/*jslint nomen: true */\nvar helper = require('../helper'),\n    code,\n    verifier;\n\n/*jshint maxlen: 500 */\nmodule.expor"
  },
  {
    "path": "test/instrumentation/test-locations.js",
    "chars": 4274,
    "preview": "/*jslint nomen: true */\nvar helper = require('../helper'),\n    verifier,\n    code;\n\n/*jshint maxlen: 500 */\nmodule.expor"
  },
  {
    "path": "test/instrumentation/test-misc.js",
    "chars": 2367,
    "preview": "/*jslint nomen: true */\nvar Instrumenter = require('../../lib/instrumenter'),\n    esprima = require('esprima'),\n    inst"
  },
  {
    "path": "test/instrumentation/test-statement-with-hints.js",
    "chars": 8722,
    "preview": "/*jslint nomen: true */\nvar helper = require('../helper'),\n    code,\n    verifier;\n\nmodule.exports = {\n    \"with a simpl"
  },
  {
    "path": "test/instrumentation/test-statement.js",
    "chars": 8678,
    "preview": "/*jslint nomen: true */\nvar helper = require('../helper'),\n    Instrumenter = require('../../lib/instrumenter'),\n    cod"
  },
  {
    "path": "test/instrumentation/test-strict.js",
    "chars": 4133,
    "preview": "/*jslint nomen: true */\nvar helper = require('../helper'),\n    code,\n    verifier;\n\nmodule.exports = {\n    \"with a funct"
  },
  {
    "path": "test/instrumentation/test-switch.js",
    "chars": 7816,
    "preview": "/*jslint nomen: true */\nvar helper = require('../helper'),\n    code,\n    verifier;\n\n/*jshint maxlen: 500 */\nmodule.expor"
  },
  {
    "path": "test/instrumentation/test-try.js",
    "chars": 1187,
    "preview": "/*jslint nomen: true */\nvar helper = require('../helper'),\n    code,\n    verifier;\n\n/*jshint maxlen: 500 */\nmodule.expor"
  },
  {
    "path": "test/instrumentation/test-while.js",
    "chars": 3816,
    "preview": "/*jslint nomen: true */\nvar helper = require('../helper'),\n    code,\n    verifier;\n\n/*jshint maxlen: 500 */\nmodule.expor"
  },
  {
    "path": "test/instrumentation/test-with.js",
    "chars": 1103,
    "preview": "/*jslint nomen: true */\nvar helper = require('../helper'),\n    code,\n    verifier;\n\n/*jshint maxlen: 500 */\nmodule.expor"
  },
  {
    "path": "test/loader.js",
    "chars": 1122,
    "preview": "/*jslint nomen: true, regexp: true */\nvar path = require('path'),\n    fs = require('fs');\n\nrequire('../lib/register-plug"
  },
  {
    "path": "test/other/config-data/.istanbul.yml",
    "chars": 105,
    "preview": "instrumentation:\n  compact: false\n  save-baseline: true\nreporting:\n  reports:\n    - lcov\n    - cobertura\n"
  },
  {
    "path": "test/other/config-data/cfg.json",
    "chars": 130,
    "preview": "{\n    \"instrumentation\": {\n        \"save-baseline\": true\n    },\n    \"hooks\": {\n        \"post-require-hook\": \"yui-istanbu"
  },
  {
    "path": "test/other/data/bar.es6",
    "chars": 62,
    "preview": "module.exports = {\n    bar: function () { return 'bar'; }\n};\n\n"
  },
  {
    "path": "test/other/data/baz.js",
    "chars": 61,
    "preview": "module.exports = {\n    baz: function () { return 'baz'; }\n};\n"
  },
  {
    "path": "test/other/data/foo.js",
    "chars": 62,
    "preview": "module.exports = {\n    foo: function () { return 'foo'; }\n};\n\n"
  },
  {
    "path": "test/other/data/matcher/.gitignore",
    "chars": 15,
    "preview": "!node_modules/\n"
  },
  {
    "path": "test/other/data/matcher/general/.gitignore",
    "chars": 16,
    "preview": "!node_modules/\n\n"
  },
  {
    "path": "test/other/data/matcher/general/general.js",
    "chars": 46,
    "preview": "module.exports = function () { return 42; };\n\n"
  },
  {
    "path": "test/other/data/matcher/lib/lib-top.js",
    "chars": 46,
    "preview": "module.exports = function () { return 42; };\n\n"
  },
  {
    "path": "test/other/data/matcher/top.js",
    "chars": 46,
    "preview": "module.exports = function () { return 32; };\n\n"
  },
  {
    "path": "test/other/data-complete-copy/baz.js",
    "chars": 61,
    "preview": "module.exports = {\n    baz: function () { return 'baz'; }\n};\n"
  },
  {
    "path": "test/other/data-complete-copy/fixture.xml",
    "chars": 8,
    "preview": "<xml />\n"
  },
  {
    "path": "test/other/data-complete-copy/foo.js",
    "chars": 62,
    "preview": "module.exports = {\n    foo: function () { return 'foo'; }\n};\n\n"
  },
  {
    "path": "test/other/data-complete-copy/myfile1",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "test/other/data-complete-copy/myfile2",
    "chars": 13,
    "preview": "some content\n"
  },
  {
    "path": "test/other/data-complete-copy/subdir/x.css",
    "chars": 34,
    "preview": "body {\n    font-family: verdana;\n}"
  },
  {
    "path": "test/other/test-collector.js",
    "chars": 3553,
    "preview": "var Collector = require('../../lib/collector'),\n    utils = require('../../lib/object-utils'),\n    coverageObj,\n    cove"
  },
  {
    "path": "test/other/test-command-xface.js",
    "chars": 1288,
    "preview": "var Command = require('../../lib/command');\n\nmodule.exports = {\n    \"should return command list\": function (test) {\n    "
  },
  {
    "path": "test/other/test-config.js",
    "chars": 9329,
    "preview": "var path = require('path'),\n    configuration = require('../../lib/config'),\n    oldCwd = process.cwd(),\n    newCwd = pa"
  },
  {
    "path": "test/other/test-file-writer.js",
    "chars": 1970,
    "preview": "/*jslint nomen: true */\n\nvar path = require('path'),\n    fs = require('fs'),\n    mkdirp = require('mkdirp'),\n    rimraf "
  },
  {
    "path": "test/other/test-help-formatter.js",
    "chars": 1451,
    "preview": "var formatOption = require('../../lib/util/help-formatter').formatOption,\n    THRESHOLD = 20;\n\nmodule.exports = {\n    \"s"
  },
  {
    "path": "test/other/test-hook.js",
    "chars": 6191,
    "preview": "/*jslint nomen: true */\nvar hook = require('../../lib/hook'),\n    currentHook,\n    matcher = function (file) { return fi"
  },
  {
    "path": "test/other/test-index-xface.js",
    "chars": 694,
    "preview": "var main = require('../../index');\n\n\nmodule.exports = {\n    \"xface\": function (test) {\n        [ 'Instrumenter', 'Store'"
  },
  {
    "path": "test/other/test-input-error.js",
    "chars": 323,
    "preview": "var inputError = require('../../lib/util/input-error');\n\nmodule.exports = {\n    \"should produce an Error object distingu"
  },
  {
    "path": "test/other/test-insertion-text.js",
    "chars": 4509,
    "preview": "/*jslint nomen: true */\nvar InsertionText = require('../../lib/util/insertion-text'),\n    it;\n\nmodule.exports = {\n    \"w"
  },
  {
    "path": "test/other/test-matcher.js",
    "chars": 4035,
    "preview": "/*jslint nomen: true */\nvar path = require('path'),\n    glob = require('glob'),\n    root = path.resolve(__dirname, 'data"
  },
  {
    "path": "test/other/test-object-utils.js",
    "chars": 10122,
    "preview": "/*jslint nomen: true */\nvar utils = require('../../lib/object-utils'),\n    it,\n    it2,\n    it3;\n\nmodule.exports = {\n   "
  },
  {
    "path": "test/other/test-store.js",
    "chars": 4048,
    "preview": "/*jslint nomen: true */\nvar Store = require('../../lib/store'),\n    path = require('path'),\n    fs = require('fs'),\n    "
  },
  {
    "path": "test/other/test-summarizer.js",
    "chars": 8964,
    "preview": "var path = require('path'),\n    SEP = path.sep || '/',\n    TreeSummarizer = require('../../lib/util/tree-summarizer'),\n "
  },
  {
    "path": "test/run-again.js",
    "chars": 404,
    "preview": "#!/usr/bin/env node\n\nvar nodeunit = require('nodeunit'),\n    mkdirp = require('mkdirp'),\n    loader = require('./loader'"
  },
  {
    "path": "test/run.js",
    "chars": 4717,
    "preview": "#!/usr/bin/env node\n\n/*\n * Test runner for all unit tests, also set up as the \"npm test\" command for the package.\n *\n * "
  }
]

// ... and 2 more files (download for full content)

About this extraction

This page contains the full source code of the gotwarlost/istanbul GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 202 files (707.1 KB), approximately 192.4k tokens, and a symbol index with 227 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!