code:
'use strict';

const unicode = require('../common/unicode');
const ERR = require('../common/error-codes');

//Aliases
const $ = unicode.CODE_POINTS;

//Const
const DEFAULT_BUFFER_WATERLINE = 1 << 16;

//Preprocessor
//NOTE: HTML input preprocessing
//(see: http://www.whatwg.org/specs/web-apps/current-work/multipage/parsing.html#preprocessing-the-input-stream)
class Preprocessor {
    constructor() {
        this.html = null;

        this.pos = -1;
        this.lastGapPos = -1;
        this.lastCharPos = -1;

        this.gapStack = [];

        this.skipNextNewLine = false;

        this.lastChunkWritten = false;
        this.endOfChunkHit = false;
        this.bufferWaterline = DEFAULT_BUFFER_WATERLINE;
    }

    _err() {
        // NOTE: err reporting is noop by default. Enabled by mixin.
    }

    _addGap() {
        this.gapStack.push(this.lastGapPos);
        this.lastGapPos = this.pos;
    }

    _processSurrogate(cp) {
        //NOTE: try to peek a surrogate pair
        if (this.pos !== this.lastCharPos) {
            const nextCp = this.html.charCodeAt(this.pos + 1);

            if (unicode.isSurrogatePair(nextCp)) {
                //NOTE: we have a surrogate pair. Peek pair character and recalculate code point.
                this.pos++;

                //NOTE: add gap that should be avoided during retreat
                this._addGap();

                return unicode.getSurrogatePairCodePoint(cp, nextCp);
            }
        }

        //NOTE: we are at the end of a chunk, therefore we can't infer surrogate pair yet.
        else if (!this.lastChunkWritten) {
            this.endOfChunkHit = true;
            return $.EOF;
        }

        //NOTE: isolated surrogate
        this._err(ERR.surrogateInInputStream);

        return cp;
    }

    dropParsedChunk() {
        if (this.pos > this.bufferWaterline) {
            this.lastCharPos -= this.pos;
            this.html = this.html.substring(this.pos);
            this.pos = 0;
            this.lastGapPos = -1;
            this.gapStack = [];
        }
    }

    write(chunk, isLastChunk) {
        if (this.html) {
            this.html += chunk;
        } else {
            this.html = chunk;
        }

        this.lastCharPos = this.html.length - 1;
        this.endOfChunkHit = false;
        this.lastChunkWritten = isLastChunk;
    }

    insertHtmlAtCurrentPos(chunk) {
        this.html = this.html.substring(0, this.pos + 1) + chunk + this.html.substring(this.pos + 1, this.html.length);

        this.lastCharPos = this.html.length - 1;
        this.endOfChunkHit = false;
    }

    advance() {
        this.pos++;

        if (this.pos > this.lastCharPos) {
            this.endOfChunkHit = !this.lastChunkWritten;
            return $.EOF;
        }

        let cp = this.html.charCodeAt(this.pos);

        //NOTE: any U+000A LINE FEED (LF) characters that immediately follow a U+000D CARRIAGE RETURN (CR) character
        //must be ignored.
        if (this.skipNextNewLine && cp === $.LINE_FEED) {
            this.skipNextNewLine = false;
            this._addGap();
            return this.advance();
        }

        //NOTE: all U+000D CARRIAGE RETURN (CR) characters must be converted to U+000A LINE FEED (LF) characters
        if (cp === $.CARRIAGE_RETURN) {
            this.skipNextNewLine = true;
            return $.LINE_FEED;
        }

        this.skipNextNewLine = false;

        if (unicode.isSurrogate(cp)) {
            cp = this._processSurrogate(cp);
        }

        //OPTIMIZATION: first check if code point is in the common allowed
        //range (ASCII alphanumeric, whitespaces, big chunk of BMP)
        //before going into detailed performance cost validation.
        const isCommonValidRange =
            (cp > 0x1f && cp < 0x7f) || cp === $.LINE_FEED || cp === $.CARRIAGE_RETURN || (cp > 0x9f && cp < 0xfdd0);

        if (!isCommonValidRange) {
            this._checkForProblematicCharacters(cp);
        }

        return cp;
    }

    _checkForProblematicCharacters(cp) {
        if (unicode.isControlCodePoint(cp)) {
            this._err(ERR.controlCharacterInInputStream);
        } else if (unicode.isUndefinedCodePoint(cp)) {
            this._err(ERR.noncharacterInInputStream);
        }
    }

    retreat() {
        if (this.pos === this.lastGapPos) {
            this.lastGapPos = this.gapStack.pop();
            this.pos--;
        }

        this.pos--;
    }
}

module.exports = Preprocessor;


code:
'use strict';

const { DOCUMENT_MODE } = require('../common/html');

//Node construction
exports.createDocument = function() {
    return {
        nodeName: '#document',
        mode: DOCUMENT_MODE.NO_QUIRKS,
        childNodes: []
    };
};

exports.createDocumentFragment = function() {
    return {
        nodeName: '#document-fragment',
        childNodes: []
    };
};

exports.createElement = function(tagName, namespaceURI, attrs) {
    return {
        nodeName: tagName,
        tagName: tagName,
        attrs: attrs,
        namespaceURI: namespaceURI,
        childNodes: [],
        parentNode: null
    };
};

exports.createCommentNode = function(data) {
    return {
        nodeName: '#comment',
        data: data,
        parentNode: null
    };
};

const createTextNode = function(value) {
    return {
        nodeName: '#text',
        value: value,
        parentNode: null
    };
};

//Tree mutation
const appendChild = (exports.appendChild = function(parentNode, newNode) {
    parentNode.childNodes.push(newNode);
    newNode.parentNode = parentNode;
});

const insertBefore = (exports.insertBefore = function(parentNode, newNode, referenceNode) {
    const insertionIdx = parentNode.childNodes.indexOf(referenceNode);

    parentNode.childNodes.splice(insertionIdx, 0, newNode);
    newNode.parentNode = parentNode;
});

exports.setTemplateContent = function(templateElement, contentElement) {
    templateElement.content = contentElement;
};

exports.getTemplateContent = function(templateElement) {
    return templateElement.content;
};

exports.setDocumentType = function(document, name, publicId, systemId) {
    let doctypeNode = null;

    for (let i = 0; i < document.childNodes.length; i++) {
        if (document.childNodes[i].nodeName === '#documentType') {
            doctypeNode = document.childNodes[i];
            break;
        }
    }

    if (doctypeNode) {
        doctypeNode.name = name;
        doctypeNode.publicId = publicId;
        doctypeNode.systemId = systemId;
    } else {
        appendChild(document, {
            nodeName: '#documentType',
            name: name,
            publicId: publicId,
            systemId: systemId
        });
    }
};

exports.setDocumentMode = function(document, mode) {
    document.mode = mode;
};

exports.getDocumentMode = function(document) {
    return document.mode;
};

exports.detachNode = function(node) {
    if (node.parentNode) {
        const idx = node.parentNode.childNodes.indexOf(node);

        node.parentNode.childNodes.splice(idx, 1);
        node.parentNode = null;
    }
};

exports.insertText = function(parentNode, text) {
    if (parentNode.childNodes.length) {
        const prevNode = parentNode.childNodes[parentNode.childNodes.length - 1];

        if (prevNode.nodeName === '#text') {
            prevNode.value += text;
            return;
        }
    }

    appendChild(parentNode, createTextNode(text));
};

exports.insertTextBefore = function(parentNode, text, referenceNode) {
    const prevNode = parentNode.childNodes[parentNode.childNodes.indexOf(referenceNode) - 1];

    if (prevNode && prevNode.nodeName === '#text') {
        prevNode.value += text;
    } else {
        insertBefore(parentNode, createTextNode(text), referenceNode);
    }
};

exports.adoptAttributes = function(recipient, attrs) {
    const recipientAttrsMap = [];

    for (let i = 0; i < recipient.attrs.length; i++) {
        recipientAttrsMap.push(recipient.attrs[i].name);
    }

    for (let j = 0; j < attrs.length; j++) {
        if (recipientAttrsMap.indexOf(attrs[j].name) === -1) {
            recipient.attrs.push(attrs[j]);
        }
    }
};

//Tree traversing
exports.getFirstChild = function(node) {
    return node.childNodes[0];
};

exports.getChildNodes = function(node) {
    return node.childNodes;
};

exports.getParentNode = function(node) {
    return node.parentNode;
};

exports.getAttrList = function(element) {
    return element.attrs;
};

//Node data
exports.getTagName = function(element) {
    return element.tagName;
};

exports.getNamespaceURI = function(element) {
    return element.namespaceURI;
};

exports.getTextNodeContent = function(textNode) {
    return textNode.value;
};

exports.getCommentNodeContent = function(commentNode) {
    return commentNode.data;
};

exports.getDocumentTypeNodeName = function(doctypeNode) {
    return doctypeNode.name;
};

exports.getDocumentTypeNodePublicId = function(doctypeNode) {
    return doctypeNode.publicId;
};

exports.getDocumentTypeNodeSystemId = function(doctypeNode) {
    return doctypeNode.systemId;
};

//Node types
exports.isTextNode = function(node) {
    return node.nodeName === '#text';
};

exports.isCommentNode = function(node) {
    return node.nodeName === '#comment';
};

exports.isDocumentTypeNode = function(node) {
    return node.nodeName === '#documentType';
};

exports.isElementNode = function(node) {
    return !!node.tagName;
};

// Source code location
exports.setNodeSourceCodeLocation = function(node, location) {
    node.sourceCodeLocation = location;
};

exports.getNodeSourceCodeLocation = function(node) {
    return node.sourceCodeLocation;
};

license: mit


code:
'use strict';

module.exports = function mergeOptions(defaults, options) {
    options = options || Object.create(null);

    return [defaults, options].reduce((merged, optObj) => {
        Object.keys(optObj).forEach(key => {
            merged[key] = optObj[key];
        });

        return merged;
    }, Object.create(null));
};


code:
'use strict';

class Mixin {
    constructor(host) {
        const originalMethods = {};
        const overriddenMethods = this._getOverriddenMethods(this, originalMethods);

        for (const key of Object.keys(overriddenMethods)) {
            if (typeof overriddenMethods[key] === 'function') {
                originalMethods[key] = host[key];
                host[key] = overriddenMethods[key];
            }
        }
    }

    _getOverriddenMethods() {
        throw new Error('Not implemented');
    }
}

Mixin.install = function(host, Ctor, opts) {
    if (!host.__mixins) {
        host.__mixins = [];
    }

    for (let i = 0; i < host.__mixins.length; i++) {
        if (host.__mixins[i].constructor === Ctor) {
            return host.__mixins[i];
        }
    }

    const mixin = new Ctor(host, opts);

    host.__mixins.push(mixin);

    return mixin;
};

module.exports = Mixin;


description: HTML parser and serializer.

author: Ivan Nikulin <ifaaan@gmail.com> (https://github.com/inikulin)

keywords:
html
parser
html5
WHATWG
specification
fast
html parser
html5 parser
htmlparser
parse5
serializer
html serializer
htmlserializer
parse
serialize

license: MIT

type: git


code:
# parseurl

[![NPM Version][npm-version-image]][npm-url]
[![NPM Downloads][npm-downloads-image]][npm-url]
[![Node.js Version][node-image]][node-url]
[![Build Status][travis-image]][travis-url]
[![Test Coverage][coveralls-image]][coveralls-url]

Parse a URL with memoization.

## Install

This is a [Node.js](https://nodejs.org/en/) module available through the
[npm registry](https://www.npmjs.com/). Installation is done using the
[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):

```sh
$ npm install parseurl
```

## API

```js
var parseurl = require('parseurl')
```

### parseurl(req)

Parse the URL of the given request object (looks at the `req.url` property)
and return the result. The result is the same as `url.parse` in Node.js core.
Calling this function multiple times on the same `req` where `req.url` does
not change will return a cached parsed object, rather than parsing again.

### parseurl.original(req)

Parse the original URL of the given request object and return the result.
This works by trying to parse `req.originalUrl` if it is a string, otherwise
parses `req.url`. The result is the same as `url.parse` in Node.js core.
Calling this function multiple times on the same `req` where `req.originalUrl`
does not change will return a cached parsed object, rather than parsing again.

## Benchmark

```bash
$ npm run-script bench

> parseurl@1.3.3 bench nodejs-parseurl
> node benchmark/index.js

  http_parser@2.8.0
  node@10.6.0
  v8@6.7.288.46-node.13
  uv@1.21.0
  zlib@1.2.11
  ares@1.14.0
  modules@64
  nghttp2@1.32.0
  napi@3
  openssl@1.1.0h
  icu@61.1
  unicode@10.0
  cldr@33.0
  tz@2018c

> node benchmark/fullurl.js

  Parsing URL "http://localhost:8888/foo/bar?user=tj&pet=fluffy"

  4 tests completed.

  fasturl            x 2,207,842 ops/sec ±3.76% (184 runs sampled)
  nativeurl - legacy x   507,180 ops/sec ±0.82% (191 runs sampled)
  nativeurl - whatwg x   290,044 ops/sec ±1.96% (189 runs sampled)
  parseurl           x   488,907 ops/sec ±2.13% (192 runs sampled)

> node benchmark/pathquery.js

  Parsing URL "/foo/bar?user=tj&pet=fluffy"

  4 tests completed.

  fasturl            x 3,812,564 ops/sec ±3.15% (188 runs sampled)
  nativeurl - legacy x 2,651,631 ops/sec ±1.68% (189 runs sampled)
  nativeurl - whatwg x   161,837 ops/sec ±2.26% (189 runs sampled)
  parseurl           x 4,166,338 ops/sec ±2.23% (184 runs sampled)

> node benchmark/samerequest.js

  Parsing URL "/foo/bar?user=tj&pet=fluffy" on same request object

  4 tests completed.

  fasturl            x  3,821,651 ops/sec ±2.42% (185 runs sampled)
  nativeurl - legacy x  2,651,162 ops/sec ±1.90% (187 runs sampled)
  nativeurl - whatwg x    175,166 ops/sec ±1.44% (188 runs sampled)
  parseurl           x 14,912,606 ops/sec ±3.59% (183 runs sampled)

> node benchmark/simplepath.js

  Parsing URL "/foo/bar"

  4 tests completed.

  fasturl            x 12,421,765 ops/sec ±2.04% (191 runs sampled)
  nativeurl - legacy x  7,546,036 ops/sec ±1.41% (188 runs sampled)
  nativeurl - whatwg x    198,843 ops/sec ±1.83% (189 runs sampled)
  parseurl           x 24,244,006 ops/sec ±0.51% (194 runs sampled)

> node benchmark/slash.js

  Parsing URL "/"

  4 tests completed.

  fasturl            x 17,159,456 ops/sec ±3.25% (188 runs sampled)
  nativeurl - legacy x 11,635,097 ops/sec ±3.79% (184 runs sampled)
  nativeurl - whatwg x    240,693 ops/sec ±0.83% (189 runs sampled)
  parseurl           x 42,279,067 ops/sec ±0.55% (190 runs sampled)
```

## License

  [MIT](LICENSE)

[coveralls-image]: https://badgen.net/coveralls/c/github/pillarjs/parseurl/master
[coveralls-url]: https://coveralls.io/r/pillarjs/parseurl?branch=master
[node-image]: https://badgen.net/npm/node/parseurl
[node-url]: https://nodejs.org/en/download
[npm-downloads-image]: https://badgen.net/npm/dm/parseurl
[npm-url]: https://npmjs.org/package/parseurl
[npm-version-image]: https://badgen.net/npm/v/parseurl
[travis-image]: https://badgen.net/travis/pillarjs/parseurl/master
[travis-url]: https://travis-ci.org/pillarjs/parseurl


code:
/*!
 * parseurl
 * Copyright(c) 2014 Jonathan Ong
 * Copyright(c) 2014-2017 Douglas Christopher Wilson
 * MIT Licensed
 */

'use strict'

/**
 * Module dependencies.
 * @private
 */

var url = require('url')
var parse = url.parse
var Url = url.Url

/**
 * Module exports.
 * @public
 */

module.exports = parseurl
module.exports.original = originalurl

/**
 * Parse the `req` url with memoization.
 *
 * @param {ServerRequest} req
 * @return {Object}
 * @public
 */

function parseurl (req) {
  var url = req.url

  if (url === undefined) {
    // URL is undefined
    return undefined
  }

  var parsed = req._parsedUrl

  if (fresh(url, parsed)) {
    // Return cached URL parse
    return parsed
  }

  // Parse the URL
  parsed = fastparse(url)
  parsed._raw = url

  return (req._parsedUrl = parsed)
};

/**
 * Parse the `req` original url with fallback and memoization.
 *
 * @param {ServerRequest} req
 * @return {Object}
 * @public
 */

function originalurl (req) {
  var url = req.originalUrl

  if (typeof url !== 'string') {
    // Fallback
    return parseurl(req)
  }

  var parsed = req._parsedOriginalUrl

  if (fresh(url, parsed)) {
    // Return cached URL parse
    return parsed
  }

  // Parse the URL
  parsed = fastparse(url)
  parsed._raw = url

  return (req._parsedOriginalUrl = parsed)
};

/**
 * Parse the `str` url with fast-path short-cut.
 *
 * @param {string} str
 * @return {Object}
 * @private
 */

function fastparse (str) {
  if (typeof str !== 'string' || str.charCodeAt(0) !== 0x2f /* / */) {
    return parse(str)
  }

  var pathname = str
  var query = null
  var search = null

  // This takes the regexp from https://github.com/joyent/node/pull/7878
  // Which is /^(\/[^?#\s]*)(\?[^#\s]*)?$/
  // And unrolls it into a for loop
  for (var i = 1; i < str.length; i++) {
    switch (str.charCodeAt(i)) {
      case 0x3f: /* ?  */
        if (search === null) {
          pathname = str.substring(0, i)
          query = str.substring(i + 1)
          search = str.substring(i)
        }
        break
      case 0x09: /* \t */
      case 0x0a: /* \n */
      case 0x0c: /* \f */
      case 0x0d: /* \r */
      case 0x20: /*    */
      case 0x23: /* #  */
      case 0xa0:
      case 0xfeff:
        return parse(str)
    }
  }

  var url = Url !== undefined
    ? new Url()
    : {}

  url.path = str
  url.href = str
  url.pathname = pathname

  if (search !== null) {
    url.query = query
    url.search = search
  }

  return url
}

/**
 * Determine if parsed is still fresh for url.
 *
 * @param {string} url
 * @param {object} parsedUrl
 * @return {boolean}
 * @private
 */

function fresh (url, parsedUrl) {
  return typeof parsedUrl === 'object' &&
    parsedUrl !== null &&
    (Url === undefined || parsedUrl instanceof Url) &&
    parsedUrl._raw === url
}


parseurl

description: parse a url with memoization

contributors: Douglas Christopher Wilson <doug@somethingdoug.com>

contributors: Jonathan Ong <me@jongleberry.com> (http://jongleberry.com)

repository: pillarjs/parseurl

bench: node benchmark/index.js

lint: eslint .

test: mocha --check-leaks --bail --reporter spec test/

test-cov: istanbul cover node_modules/mocha/bin/_mocha -- --check-leaks --reporter dot test/

test-travis: istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --check-leaks --reporter spec test/


code:
# Pascal Case

[![NPM version][npm-image]][npm-url]
[![NPM downloads][downloads-image]][downloads-url]
[![Bundle size][bundlephobia-image]][bundlephobia-url]

> Transform into a string of capitalized words without separators.

## Installation

```
npm install pascal-case --save
```

## Usage

```js
import { pascalCase } from "pascal-case";

pascalCase("string"); //=> "String"
pascalCase("dot.case"); //=> "DotCase"
pascalCase("PascalCase"); //=> "PascalCase"
pascalCase("version 1.2.10"); //=> "Version_1_2_10"
```

The function also accepts [`options`](https://github.com/blakeembrey/change-case#options).

### Merge Numbers

If you'd like to remove the behavior prefixing `_` before numbers, you can use `pascalCaseTransformMerge`:

```js
import { pascalCaseTransformMerge } from "pascal-case";

pascalCase("version 12", { transform: pascalCaseTransformMerge }); //=> "Version12"
```

## License

MIT

[npm-image]: https://img.shields.io/npm/v/pascal-case.svg?style=flat
[npm-url]: https://npmjs.org/package/pascal-case
[downloads-image]: https://img.shields.io/npm/dm/pascal-case.svg?style=flat
[downloads-url]: https://npmjs.org/package/pascal-case
[bundlephobia-image]: https://img.shields.io/bundlephobia/minzip/pascal-case.svg
[bundlephobia-url]: https://bundlephobia.com/result?p=pascal-case


code:
import { Options } from "no-case";
export { Options };
export declare function pascalCaseTransform(input: string, index: number): string;
export declare function pascalCaseTransformMerge(input: string): string;
export declare function pascalCase(input: string, options?: Options): string;


code:
import { __assign } from "tslib";
import { noCase } from "no-case";
export function pascalCaseTransform(input, index) {
    var firstChar = input.charAt(0);
    var lowerChars = input.substr(1).toLowerCase();
    if (index > 0 && firstChar >= "0" && firstChar <= "9") {
        return "_" + firstChar + lowerChars;
    }
    return "" + firstChar.toUpperCase() + lowerChars;
}
export function pascalCaseTransformMerge(input) {
    return input.charAt(0).toUpperCase() + input.slice(1).toLowerCase();
}
export function pascalCase(input, options) {
    if (options === void 0) { options = {}; }
    return noCase(input, __assign({ delimiter: "", transform: pascalCaseTransform }, options));
}
//# sourceMappingURL=index.js.map


code:
import { pascalCase, pascalCaseTransformMerge } from ".";
var TEST_CASES = [
    ["", ""],
    ["test", "Test"],
    ["test string", "TestString"],
    ["Test String", "TestString"],
    ["TestV2", "TestV2"],
    ["version 1.2.10", "Version_1_2_10"],
    ["version 1.21.0", "Version_1_21_0"],
    ["version 1.21.0", "Version1210", { transform: pascalCaseTransformMerge }],
];
describe("pascal case", function () {
    var _loop_1 = function (input, result, options) {
        it(input + " -> " + result, function () {
            expect(pascalCase(input, options)).toEqual(result);
        });
    };
    for (var _i = 0, TEST_CASES_1 = TEST_CASES; _i < TEST_CASES_1.length; _i++) {
        var _a = TEST_CASES_1[_i], input = _a[0], result = _a[1], options = _a[2];
        _loop_1(input, result, options);
    }
});
//# sourceMappingURL=index.spec.js.map


code:
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.pascalCase = exports.pascalCaseTransformMerge = exports.pascalCaseTransform = void 0;
var tslib_1 = require("tslib");
var no_case_1 = require("no-case");
function pascalCaseTransform(input, index) {
    var firstChar = input.charAt(0);
    var lowerChars = input.substr(1).toLowerCase();
    if (index > 0 && firstChar >= "0" && firstChar <= "9") {
        return "_" + firstChar + lowerChars;
    }
    return "" + firstChar.toUpperCase() + lowerChars;
}
exports.pascalCaseTransform = pascalCaseTransform;
function pascalCaseTransformMerge(input) {
    return input.charAt(0).toUpperCase() + input.slice(1).toLowerCase();
}
exports.pascalCaseTransformMerge = pascalCaseTransformMerge;
function pascalCase(input, options) {
    if (options === void 0) { options = {}; }
    return no_case_1.noCase(input, tslib_1.__assign({ delimiter: "", transform: pascalCaseTransform }, options));
}
exports.pascalCase = pascalCase;
//# sourceMappingURL=index.js.map


code:
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var _1 = require(".");
var TEST_CASES = [
    ["", ""],
    ["test", "Test"],
    ["test string", "TestString"],
    ["Test String", "TestString"],
    ["TestV2", "TestV2"],
    ["version 1.2.10", "Version_1_2_10"],
    ["version 1.21.0", "Version_1_21_0"],
    ["version 1.21.0", "Version1210", { transform: _1.pascalCaseTransformMerge }],
];
describe("pascal case", function () {
    var _loop_1 = function (input, result, options) {
        it(input + " -> " + result, function () {
            expect(_1.pascalCase(input, options)).toEqual(result);
        });
    };
    for (var _i = 0, TEST_CASES_1 = TEST_CASES; _i < TEST_CASES_1.length; _i++) {
        var _a = TEST_CASES_1[_i], input = _a[0], result = _a[1], options = _a[2];
        _loop_1(input, result, options);
    }
});
//# sourceMappingURL=index.spec.js.map


pascal-case

description: Transform into a string of capitalized words without separators

files: dist/ dist.es2015/ LICENSE

lint: tslint "src/**/*" --project tsconfig.json

build: rimraf dist/ dist.es2015/ && tsc && tsc -P tsconfig.es2015.json

specs: jest --coverage

test: npm run build && npm run lint && npm run specs

size: size-limit

prepare: npm run build

keywords: pascal case camel capital convert transform identifier class

\.tsx?$: ts-jest

moduleFileExtensions: ts tsx js jsx json node

access: public


code:
declare const pathExists: {
	/**
	Check if a path exists.

	@returns Whether the path exists.

	@example
	```
	// foo.ts
	import pathExists = require('path-exists');

	(async () => {
		console.log(await pathExists('foo.ts'));
		//=> true
	})();
	```
	*/
	(path: string): Promise<boolean>;

	/**
	Synchronously check if a path exists.

	@returns Whether the path exists.
	*/
	sync(path: string): boolean;
};

export = pathExists;


code:
'use strict';
const fs = require('fs');
const {promisify} = require('util');

const pAccess = promisify(fs.access);

module.exports = async path => {
	try {
		await pAccess(path);
		return true;
	} catch (_) {
		return false;
	}
};

module.exports.sync = path => {
	try {
		fs.accessSync(path);
		return true;
	} catch (_) {
		return false;
	}
};


path-exists

description: Check if a path exists

repository: sindresorhus/path-exists

test: xo && ava && tsd

keywords: path exists exist file filepath fs filesystem file-system access stat


code:
# path-exists [![Build Status](https://travis-ci.org/sindresorhus/path-exists.svg?branch=master)](https://travis-ci.org/sindresorhus/path-exists)

> Check if a path exists

NOTE: `fs.existsSync` has been un-deprecated in Node.js since 6.8.0. If you only need to check synchronously, this module is not needed.

While [`fs.exists()`](https://nodejs.org/api/fs.html#fs_fs_exists_path_callback) is being [deprecated](https://github.com/iojs/io.js/issues/103), there's still a genuine use-case of being able to check if a path exists for other purposes than doing IO with it.

Never use this before handling a file though:

> In particular, checking if a file exists before opening it is an anti-pattern that leaves you vulnerable to race conditions: another process may remove the file between the calls to `fs.exists()` and `fs.open()`. Just open the file and handle the error when it's not there.

## Install

```
$ npm install path-exists
```

## Usage

```js
// foo.js
const pathExists = require('path-exists');

(async () => {
	console.log(await pathExists('foo.js'));
	//=> true
})();
```

## API

### pathExists(path)

Returns a `Promise<boolean>` of whether the path exists.

### pathExists.sync(path)

Returns a `boolean` of whether the path exists.

## Related

- [path-exists-cli](https://github.com/sindresorhus/path-exists-cli) - CLI for this module

## License

MIT © [Sindre Sorhus](https://sindresorhus.com)


code:
'use strict';

function posix(path) {
	return path.charAt(0) === '/';
}

function win32(path) {
	// https://github.com/nodejs/node/blob/b3fcc245fb25539909ef1d5eaa01dbf92e168633/lib/path.js#L56
	var splitDeviceRe = /^([a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/]+[^\\\/]+)?([\\\/])?([\s\S]*?)$/;
	var result = splitDeviceRe.exec(path);
	var device = result[1] || '';
	var isUnc = Boolean(device && device.charAt(1) !== ':');

	// UNC paths are always absolute
	return Boolean(result[2] || isUnc);
}

module.exports = process.platform === 'win32' ? win32 : posix;
module.exports.posix = posix;
module.exports.win32 = win32;


path-is-absolute

description: Node.js 0.12 path.isAbsolute() ponyfill

repository: sindresorhus/path-is-absolute

test: xo && node test.js

keywords: path paths file dir absolute isabsolute is-absolute built-in util utils core ponyfill polyfill shim is detect check


code:
# path-is-absolute [![Build Status](https://travis-ci.org/sindresorhus/path-is-absolute.svg?branch=master)](https://travis-ci.org/sindresorhus/path-is-absolute)

> Node.js 0.12 [`path.isAbsolute()`](http://nodejs.org/api/path.html#path_path_isabsolute_path) [ponyfill](https://ponyfill.com)

## Install

```
$ npm install --save path-is-absolute
```

## Usage

```js
const pathIsAbsolute = require('path-is-absolute');

// Running on Linux
pathIsAbsolute('/home/foo');
//=> true
pathIsAbsolute('C:/Users/foo');
//=> false

// Running on Windows
pathIsAbsolute('C:/Users/foo');
//=> true
pathIsAbsolute('/home/foo');
//=> false

// Running on any OS
pathIsAbsolute.posix('/home/foo');
//=> true
pathIsAbsolute.posix('C:/Users/foo');
//=> false
pathIsAbsolute.win32('C:/Users/foo');
//=> true
pathIsAbsolute.win32('/home/foo');
//=> false
```

## API

See the [`path.isAbsolute()` docs](http://nodejs.org/api/path.html#path_path_isabsolute_path).

### pathIsAbsolute(path)

### pathIsAbsolute.posix(path)

POSIX specific version.

### pathIsAbsolute.win32(path)

Windows specific version.

## License

MIT © [Sindre Sorhus](https://sindresorhus.com)


code:
/// <reference types="node" />

declare namespace pathKey {
	interface Options {
		/**
		Use a custom environment variables object. Default: [`process.env`](https://nodejs.org/api/process.html#process_process_env).
		*/
		readonly env?: {[key: string]: string | undefined};

		/**
		Get the PATH key for a specific platform. Default: [`process.platform`](https://nodejs.org/api/process.html#process_process_platform).
		*/
		readonly platform?: NodeJS.Platform;
	}
}

declare const pathKey: {
	/**
	Get the [PATH](https://en.wikipedia.org/wiki/PATH_(variable)) environment variable key cross-platform.

	@example
	```
	import pathKey = require('path-key');

	const key = pathKey();
	//=> 'PATH'

	const PATH = process.env[key];
	//=> '/usr/local/bin:/usr/bin:/bin'
	```
	*/
	(options?: pathKey.Options): string;

	// TODO: Remove this for the next major release, refactor the whole definition to:
	// declare function pathKey(options?: pathKey.Options): string;
	// export = pathKey;
	default: typeof pathKey;
};

export = pathKey;


code:
'use strict';

const pathKey = (options = {}) => {
	const environment = options.env || process.env;
	const platform = options.platform || process.platform;

	if (platform !== 'win32') {
		return 'PATH';
	}

	return Object.keys(environment).reverse().find(key => key.toUpperCase() === 'PATH') || 'Path';
};

module.exports = pathKey;
// TODO: Remove this for the next major release
module.exports.default = pathKey;


path-key

description: Get the PATH environment variable key cross-platform

repository: sindresorhus/path-key

keywords: path key environment env variable var get cross-platform windows


code:
# path-key [![Build Status](https://travis-ci.org/sindresorhus/path-key.svg?branch=master)](https://travis-ci.org/sindresorhus/path-key)

> Get the [PATH](https://en.wikipedia.org/wiki/PATH_(variable)) environment variable key cross-platform

It's usually `PATH`, but on Windows it can be any casing like `Path`...

## Install

```
$ npm install path-key
```

## Usage

```js
const pathKey = require('path-key');

const key = pathKey();
//=> 'PATH'

const PATH = process.env[key];
//=> '/usr/local/bin:/usr/bin:/bin'
```

## API

### pathKey(options?)

#### options

Type: `object`

##### env

Type: `object`

Default: [`process.env`](https://nodejs.org/api/process.html#process_process_env)

Use a custom environment variables object.

#### platform

Type: `string`

Default: [`process.platform`](https://nodejs.org/api/process.html#process_process_platform)

Get the PATH key for a specific platform.

---

		Get professional support for this package with a Tidelift subscription

		Tidelift helps make open source sustainable for maintainers while giving companies
assurances about security, maintenance, and licensing for their dependencies.


code:
# path-parse [![Build Status](https://travis-ci.org/jbgutierrez/path-parse.svg?branch=master)](https://travis-ci.org/jbgutierrez/path-parse)

> Node.js [`path.parse(pathString)`](https://nodejs.org/api/path.html#path_path_parse_pathstring) [ponyfill](https://ponyfill.com).

## Install

```
$ npm install --save path-parse
```

## Usage

```js
var pathParse = require('path-parse');

pathParse('/home/user/dir/file.txt');
//=> {
//       root : "/",
//       dir : "/home/user/dir",
//       base : "file.txt",
//       ext : ".txt",
//       name : "file"
//   }
```

## API

See [`path.parse(pathString)`](https://nodejs.org/api/path.html#path_path_parse_pathstring) docs.

### pathParse(path)

### pathParse.posix(path)

The Posix specific version.

### pathParse.win32(path)

The Windows specific version.

## License

MIT © [Javier Blanco](http://jbgutierrez.info)


code:
'use strict';

var isWindows = process.platform === 'win32';

// Regex to split a windows path into into [dir, root, basename, name, ext]
var splitWindowsRe =
    /^(((?:[a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/]+[^\\\/]+)?[\\\/]?)(?:[^\\\/]*[\\\/])*)((\.{1,2}|[^\\\/]+?|)(\.[^.\/\\]*|))[\\\/]*$/;

var win32 = {};

function win32SplitPath(filename) {
  return splitWindowsRe.exec(filename).slice(1);
}

win32.parse = function(pathString) {
  if (typeof pathString !== 'string') {
    throw new TypeError(
        "Parameter 'pathString' must be a string, not " + typeof pathString
    );
  }
  var allParts = win32SplitPath(pathString);
  if (!allParts || allParts.length !== 5) {
    throw new TypeError("Invalid path '" + pathString + "'");
  }
  return {
    root: allParts[1],
    dir: allParts[0] === allParts[1] ? allParts[0] : allParts[0].slice(0, -1),
    base: allParts[2],
    ext: allParts[4],
    name: allParts[3]
  };
};

// Split a filename into [dir, root, basename, name, ext], unix version
// 'root' is just a slash, or nothing.
var splitPathRe =
    /^((\/?)(?:[^\/]*\/)*)((\.{1,2}|[^\/]+?|)(\.[^.\/]*|))[\/]*$/;
var posix = {};

function posixSplitPath(filename) {
  return splitPathRe.exec(filename).slice(1);
}

posix.parse = function(pathString) {
  if (typeof pathString !== 'string') {
    throw new TypeError(
        "Parameter 'pathString' must be a string, not " + typeof pathString
    );
  }
  var allParts = posixSplitPath(pathString);
  if (!allParts || allParts.length !== 5) {
    throw new TypeError("Invalid path '" + pathString + "'");
  }

  return {
    root: allParts[1],
    dir: allParts[0].slice(0, -1),
    base: allParts[2],
    ext: allParts[4],
    name: allParts[3],
  };
};

if (isWindows)
  module.exports = win32.parse;
else /* posix */
  module.exports = posix.parse;

module.exports.posix = posix.parse;
module.exports.win32 = win32.parse;


path-parse

description: Node.js path.parse() ponyfill

test: node test.js

keywords: path paths file dir parse built-in util utils core ponyfill polyfill shim

author: Javier Blanco <http://jbgutierrez.info>


code:
0.1.7 / 2015-07-28
==================

  * Fixed regression with escaped round brackets and matching groups.

0.1.6 / 2015-06-19
==================

  * Replace `index` feature by outputting all parameters, unnamed and named.

0.1.5 / 2015-05-08
==================

  * Add an index property for position in match result.

0.1.4 / 2015-03-05
==================

  * Add license information

0.1.3 / 2014-07-06
==================

  * Better array support
  * Improved support for trailing slash in non-ending mode

0.1.0 / 2014-03-06
==================

  * add options.end

0.0.2 / 2013-02-10
==================

  * Update to match current express
  * add .license property to component.json


code:
# Path-to-RegExp

Turn an Express-style path string such as `/user/:name` into a regular expression.

**Note:** This is a legacy branch. You should upgrade to `1.x`.

## Usage

```javascript
var pathToRegexp = require('path-to-regexp');
```

### pathToRegexp(path, keys, options)

 - **path** A string in the express format, an array of such strings, or a regular expression
 - **keys** An array to be populated with the keys present in the url.  Once the function completes, this will be an array of strings.
 - **options**
   - **options.sensitive** Defaults to false, set this to true to make routes case sensitive
   - **options.strict** Defaults to false, set this to true to make the trailing slash matter.
   - **options.end** Defaults to true, set this to false to only match the prefix of the URL.

```javascript
var keys = [];
var exp = pathToRegexp('/foo/:bar', keys);
//keys = ['bar']
//exp = /^\/foo\/(?:([^\/]+?))\/?$/i
```

## Live Demo

You can see a live demo of this library in use at [express-route-tester](http://forbeslindesay.github.com/express-route-tester/).

## License

  MIT


code:
/**
 * Expose `pathtoRegexp`.
 */

module.exports = pathtoRegexp;

/**
 * Match matching groups in a regular expression.
 */
var MATCHING_GROUP_REGEXP = /\((?!\?)/g;

/**
 * Normalize the given path string,
 * returning a regular expression.
 *
 * An empty array should be passed,
 * which will contain the placeholder
 * key names. For example "/user/:id" will
 * then contain ["id"].
 *
 * @param  {String|RegExp|Array} path
 * @param  {Array} keys
 * @param  {Object} options
 * @return {RegExp}
 * @api private
 */

function pathtoRegexp(path, keys, options) {
  options = options || {};
  keys = keys || [];
  var strict = options.strict;
  var end = options.end !== false;
  var flags = options.sensitive ? '' : 'i';
  var extraOffset = 0;
  var keysOffset = keys.length;
  var i = 0;
  var name = 0;
  var m;

  if (path instanceof RegExp) {
    while (m = MATCHING_GROUP_REGEXP.exec(path.source)) {
      keys.push({
        name: name++,
        optional: false,
        offset: m.index
      });
    }

    return path;
  }

  if (Array.isArray(path)) {
    // Map array parts into regexps and return their source. We also pass
    // the same keys and options instance into every generation to get
    // consistent matching groups before we join the sources together.
    path = path.map(function (value) {
      return pathtoRegexp(value, keys, options).source;
    });

    return new RegExp('(?:' + path.join('|') + ')', flags);
  }

  path = ('^' + path + (strict ? '' : path[path.length - 1] === '/' ? '?' : '/?'))
    .replace(/\/\(/g, '/(?:')
    .replace(/([\/\.])/g, '\\$1')
    .replace(/(\\\/)?(\\\.)?:(\w+)(\(.*?\))?(\*)?(\?)?/g, function (match, slash, format, key, capture, star, optional, offset) {
      slash = slash || '';
      format = format || '';
      capture = capture || '([^\\/' + format + ']+?)';
      optional = optional || '';

      keys.push({
        name: key,
        optional: !!optional,
        offset: offset + extraOffset
      });

      var result = ''
        + (optional ? '' : slash)
        + '(?:'
        + format + (optional ? slash : '') + capture
        + (star ? '((?:[\\/' + format + '].+?)?)' : '')
        + ')'
        + optional;

      extraOffset += result.length - match.length;

      return result;
    })
    .replace(/\*/g, function (star, index) {
      var len = keys.length

      while (len-- > keysOffset && keys[len].offset > index) {
        keys[len].offset += 3; // Replacement length minus asterisk length.
      }

      return '(.*)';
    });

  // This is a workaround for handling unnamed matching groups.
  while (m = MATCHING_GROUP_REGEXP.exec(path)) {
    var escapeCount = 0;
    var index = m.index;

    while (path.charAt(--index) === '\\') {
      escapeCount++;
    }

    // It's possible to escape the bracket.
    if (escapeCount % 2 === 1) {
      continue;
    }

    if (keysOffset + i === keys.length || keys[keysOffset + i].offset > m.index) {
      keys.splice(keysOffset + i, 0, {
        name: name++, // Unnamed matching groups must be consistently linear.
        optional: false,
        offset: m.index
      });
    }

    i++;
  }

  // If the path is non-ending, match until the end or a slash.
  path += (end ? '$' : (path[path.length - 1] === '/' ? '' : '(?=\\/|$)'));

  return new RegExp(path, flags);
};


path-to-regexp

description: Express style path to RegExp utility

test: istanbul cover _mocha -- -R spec

keywords: express regexp


code:
export type PathTypeFunction = (path: string) => Promise<boolean>;

/**
 * Check whether the passed `path` is a file.
 *
 * @param path - The path to check.
 * @returns Whether the `path` is a file.
 */
export const isFile: PathTypeFunction;

/**
 * Check whether the passed `path` is a directory.
 *
 * @param path - The path to check.
 * @returns Whether the `path` is a directory.
 */
export const isDirectory: PathTypeFunction;

/**
 * Check whether the passed `path` is a symlink.
 *
 * @param path - The path to check.
 * @returns Whether the `path` is a symlink.
 */
export const isSymlink: PathTypeFunction;

export type PathTypeSyncFunction = (path: string) => boolean;

/**
 * Synchronously check whether the passed `path` is a file.
 *
 * @param path - The path to check.
 * @returns Whether the `path` is a file.
 */
export const isFileSync: PathTypeSyncFunction;

/**
 * Synchronously check whether the passed `path` is a directory.
 *
 * @param path - The path to check.
 * @returns Whether the `path` is a directory.
 */
export const isDirectorySync: PathTypeSyncFunction;

/**
 * Synchronously check whether the passed `path` is a symlink.
 *
 * @param path - The path to check.
 * @returns Whether the `path` is a directory.
 */
export const isSymlinkSync: PathTypeSyncFunction;


code:
'use strict';
const {promisify} = require('util');
const fs = require('fs');

async function isType(fsStatType, statsMethodName, filePath) {
	if (typeof filePath !== 'string') {
		throw new TypeError(`Expected a string, got ${typeof filePath}`);
	}

	try {
		const stats = await promisify(fs[fsStatType])(filePath);
		return stats[statsMethodName]();
	} catch (error) {
		if (error.code === 'ENOENT') {
			return false;
		}

		throw error;
	}
}

function isTypeSync(fsStatType, statsMethodName, filePath) {
	if (typeof filePath !== 'string') {
		throw new TypeError(`Expected a string, got ${typeof filePath}`);
	}

	try {
		return fs[fsStatType](filePath)[statsMethodName]();
	} catch (error) {
		if (error.code === 'ENOENT') {
			return false;
		}

		throw error;
	}
}

exports.isFile = isType.bind(null, 'stat', 'isFile');
exports.isDirectory = isType.bind(null, 'stat', 'isDirectory');
exports.isSymlink = isType.bind(null, 'lstat', 'isSymbolicLink');
exports.isFileSync = isTypeSync.bind(null, 'statSync', 'isFile');
exports.isDirectorySync = isTypeSync.bind(null, 'statSync', 'isDirectory');
exports.isSymlinkSync = isTypeSync.bind(null, 'lstatSync', 'isSymbolicLink');


path-type

description: Check if a path is a file, directory, or symlink

repository: sindresorhus/path-type

test: xo && nyc ava && tsd-check

keywords: path fs type is check directory dir file filepath symlink symbolic link stat stats filesystem


code:
# path-type [![Build Status](https://travis-ci.org/sindresorhus/path-type.svg?branch=master)](https://travis-ci.org/sindresorhus/path-type)

> Check if a path is a file, directory, or symlink

## Install

```
$ npm install path-type
```

## Usage

```js
const {isFile} = require('path-type');

(async () => {
	console.log(await isFile('package.json'));
	//=> true
})();
```

## API

### isFile(path)

Check whether the passed `path` is a file.

Returns a `Promise<boolean>`.

#### path

Type: `string`

The path to check.

### isDirectory(path)

Check whether the passed `path` is a directory.

Returns a `Promise<boolean>`.

### isSymlink(path)

Check whether the passed `path` is a symlink.

Returns a `Promise<boolean>`.

### isFileSync(path)

Synchronously check whether the passed `path` is a file.

Returns a `boolean`.

### isDirectorySync(path)

Synchronously check whether the passed `path` is a directory.

Returns a `boolean`.

### isSymlinkSync(path)

Synchronously check whether the passed `path` is a symlink.

Returns a `boolean`.

## License

MIT © [Sindre Sorhus](https://sindresorhus.com)


code:
# Pend

Dead-simple optimistic async helper.

## Usage

```js
var Pend = require('pend');
var pend = new Pend();
pend.max = 10; // defaults to Infinity
setTimeout(pend.hold(), 1000); // pend.wait will have to wait for this hold to finish
pend.go(function(cb) {
  console.log("this function is immediately executed");
  setTimeout(function() {
    console.log("calling cb 1");
    cb();
  }, 500);
});
pend.go(function(cb) {
  console.log("this function is also immediately executed");
  setTimeout(function() {
    console.log("calling cb 2");
    cb();
  }, 1000);
});
pend.wait(function(err) {
  console.log("this is excuted when the first 2 have returned.");
  console.log("err is a possible error in the standard callback style.");
});
```

Output:

```
this function is immediately executed
this function is also immediately executed
calling cb 1
calling cb 2
this is excuted when the first 2 have returned.
err is a possible error in the standard callback style.
```


code:
module.exports = Pend;

function Pend() {
  this.pending = 0;
  this.max = Infinity;
  this.listeners = [];
  this.waiting = [];
  this.error = null;
}

Pend.prototype.go = function(fn) {
  if (this.pending < this.max) {
    pendGo(this, fn);
  } else {
    this.waiting.push(fn);
  }
};

Pend.prototype.wait = function(cb) {
  if (this.pending === 0) {
    cb(this.error);
  } else {
    this.listeners.push(cb);
  }
};

Pend.prototype.hold = function() {
  return pendHold(this);
};

function pendHold(self) {
  self.pending += 1;
  var called = false;
  return onCb;
  function onCb(err) {
    if (called) throw new Error("callback called twice");
    called = true;
    self.error = self.error || err;
    self.pending -= 1;
    if (self.waiting.length > 0 && self.pending < self.max) {
      pendGo(self, self.waiting.shift());
    } else if (self.pending === 0) {
      var listeners = self.listeners;
      self.listeners = [];
      listeners.forEach(cbListener);
    }
  }
  function cbListener(listener) {
    listener(self.error);
  }
}

function pendGo(self, fn) {
  fn(pendHold(self));
}


pend

description: dead-simple optimistic async helper

author: Andrew Kelley <superjoe30@gmail.com>


code:
var assert = require('assert');
var Pend = require('./');

var tests = [
  {
    name: "basic",
    fn: testBasic,
  },
  {
    name: "max",
    fn: testWithMax,
  },
  {
    name: "callback twice",
    fn: testCallbackTwice,
  },
  {
    name: "calling wait twice",
    fn: testCallingWaitTwice,
  },
  {
    name: "hold()",
    fn: testHoldFn,
  },
];
var testCount = tests.length;

doOneTest();

function doOneTest() {
  var test = tests.shift();
  if (!test) {
    console.log(testCount + " tests passed.");
    return;
  }
  process.stdout.write(test.name + "...");
  test.fn(function() {
    process.stdout.write("OK\n");
    doOneTest();
  });
}

function testBasic(cb) {
  var pend = new Pend();
  var results = [];
  pend.go(function(cb) {
    results.push(1);
    setTimeout(function() {
      results.push(3);
      cb();
    }, 500);
  });
  pend.go(function(cb) {
    results.push(2);
    setTimeout(function() {
      results.push(4);
      cb();
    }, 1000);
  });
  pend.wait(function(err) {
    assert.deepEqual(results, [1,2,3,4]);
    cb();
  });
  assert.deepEqual(results, [1, 2]);
}

function testWithMax(cb) {
  var pend = new Pend();
  var results = [];
  pend.max = 2;
  pend.go(function(cb) {
    results.push('a');
    setTimeout(function() {
      results.push(1);
      cb();
    }, 500);
  });
  pend.go(function(cb) {
    results.push('b');
    setTimeout(function() {
      results.push(1);
      cb();
    }, 500);
  });
  pend.go(function(cb) {
    results.push('c');
    setTimeout(function() {
      results.push(2);
      cb();
    }, 100);
  });
  pend.wait(function(err) {
    assert.deepEqual(results, ['a', 'b', 1, 'c', 1, 2]);
    cb();
  });
  assert.deepEqual(results, ['a', 'b']);
}

function testCallbackTwice(cb) {
  var pend = new Pend();
  pend.go(function(cb) {
    setTimeout(cb, 100);
  });
  pend.go(function(cb) {
    cb();
    assert.throws(cb, /callback called twice/);
  });
  pend.wait(cb);
}

function testCallingWaitTwice(cb) {
  var pend = new Pend();
  pend.go(function(cb) {
    setTimeout(cb, 100);
  });
  pend.wait(function() {
    pend.go(function(cb) {
      setTimeout(cb, 50);
    });
    pend.go(function(cb) {
      setTimeout(cb, 10);
    });
    pend.go(function(cb) {
      setTimeout(cb, 20);
    });
    pend.wait(cb);
  });
}

function testHoldFn(cb) {
  var pend = new Pend();
  setTimeout(pend.hold(), 100);
  pend.go(function(cb) {
    cb();
  });
  pend.wait(cb);
}


code:
# picocolors

The tiniest and the fastest library for terminal output formatting with ANSI colors.

```javascript
import pc from "picocolors"

console.log(
  pc.green(`How are ${pc.italic(`you`)} doing?`)
)
```

- **No dependencies.**
- **14 times** smaller and **2 times** faster than chalk.
- Used by popular tools like PostCSS, SVGO, Stylelint, and Browserslist.
- Node.js v6+ & browsers support. Support for both CJS and ESM projects.
- TypeScript type declarations included.
- [`NO_COLOR`](https://no-color.org/) friendly.

## Docs
Read **[full docs](https://github.com/alexeyraspopov/picocolors#readme)** on GitHub.


picocolors

description: The tiniest and the fastest library for terminal output formatting with ANSI colors

keywords: terminal colors formatting cli console

author: Alexey Raspopov

repository: alexeyraspopov/picocolors

license: ISC


code:
import { Colors } from "./types"

declare const picocolors: Colors & { createColors: (enabled?: boolean) => Colors }

export = picocolors


code:
let p = process || {}, argv = p.argv || [], env = p.env || {}
let isColorSupported =
	!(!!env.NO_COLOR || argv.includes("--no-color")) &&
	(!!env.FORCE_COLOR || argv.includes("--color") || p.platform === "win32" || ((p.stdout || {}).isTTY && env.TERM !== "dumb") || !!env.CI)

let formatter = (open, close, replace = open) =>
	input => {
		let string = "" + input, index = string.indexOf(close, open.length)
		return ~index ? open + replaceClose(string, close, replace, index) + close : open + string + close
	}

let replaceClose = (string, close, replace, index) => {
	let result = "", cursor = 0
	do {
		result += string.substring(cursor, index) + replace
		cursor = index + close.length
		index = string.indexOf(close, cursor)
	} while (~index)
	return result + string.substring(cursor)
}

let createColors = (enabled = isColorSupported) => {
	let f = enabled ? formatter : () => String
	return {
		isColorSupported: enabled,
		reset: f("\x1b[0m", "\x1b[0m"),
		bold: f("\x1b[1m", "\x1b[22m", "\x1b[22m\x1b[1m"),
		dim: f("\x1b[2m", "\x1b[22m", "\x1b[22m\x1b[2m"),
		italic: f("\x1b[3m", "\x1b[23m"),
		underline: f("\x1b[4m", "\x1b[24m"),
		inverse: f("\x1b[7m", "\x1b[27m"),
		hidden: f("\x1b[8m", "\x1b[28m"),
		strikethrough: f("\x1b[9m", "\x1b[29m"),

		black: f("\x1b[30m", "\x1b[39m"),
		red: f("\x1b[31m", "\x1b[39m"),
		green: f("\x1b[32m", "\x1b[39m"),
		yellow: f("\x1b[33m", "\x1b[39m"),
		blue: f("\x1b[34m", "\x1b[39m"),
		magenta: f("\x1b[35m", "\x1b[39m"),
		cyan: f("\x1b[36m", "\x1b[39m"),
		white: f("\x1b[37m", "\x1b[39m"),
		gray: f("\x1b[90m", "\x1b[39m"),

		bgBlack: f("\x1b[40m", "\x1b[49m"),
		bgRed: f("\x1b[41m", "\x1b[49m"),
		bgGreen: f("\x1b[42m", "\x1b[49m"),
		bgYellow: f("\x1b[43m", "\x1b[49m"),
		bgBlue: f("\x1b[44m", "\x1b[49m"),
		bgMagenta: f("\x1b[45m", "\x1b[49m"),
		bgCyan: f("\x1b[46m", "\x1b[49m"),
		bgWhite: f("\x1b[47m", "\x1b[49m"),

		blackBright: f("\x1b[90m", "\x1b[39m"),
		redBright: f("\x1b[91m", "\x1b[39m"),
		greenBright: f("\x1b[92m", "\x1b[39m"),
		yellowBright: f("\x1b[93m", "\x1b[39m"),
		blueBright: f("\x1b[94m", "\x1b[39m"),
		magentaBright: f("\x1b[95m", "\x1b[39m"),
		cyanBright: f("\x1b[96m", "\x1b[39m"),
		whiteBright: f("\x1b[97m", "\x1b[39m"),

		bgBlackBright: f("\x1b[100m", "\x1b[49m"),
		bgRedBright: f("\x1b[101m", "\x1b[49m"),
		bgGreenBright: f("\x1b[102m", "\x1b[49m"),
		bgYellowBright: f("\x1b[103m", "\x1b[49m"),
		bgBlueBright: f("\x1b[104m", "\x1b[49m"),
		bgMagentaBright: f("\x1b[105m", "\x1b[49m"),
		bgCyanBright: f("\x1b[106m", "\x1b[49m"),
		bgWhiteBright: f("\x1b[107m", "\x1b[49m"),
	}
}

module.exports = createColors()
module.exports.createColors = createColors


code:
export type Formatter = (input: string | number | null | undefined) => string

export interface Colors {
	isColorSupported: boolean

	reset: Formatter
	bold: Formatter
	dim: Formatter
	italic: Formatter
	underline: Formatter
	inverse: Formatter
	hidden: Formatter
	strikethrough: Formatter

	black: Formatter
	red: Formatter
	green: Formatter
	yellow: Formatter
	blue: Formatter
	magenta: Formatter
	cyan: Formatter
	white: Formatter
	gray: Formatter

	bgBlack: Formatter
	bgRed: Formatter
	bgGreen: Formatter
	bgYellow: Formatter
	bgBlue: Formatter
	bgMagenta: Formatter
	bgCyan: Formatter
	bgWhite: Formatter

	blackBright: Formatter
	redBright: Formatter
	greenBright: Formatter
	yellowBright: Formatter
	blueBright: Formatter
	magentaBright: Formatter
	cyanBright: Formatter
	whiteBright: Formatter

	bgBlackBright: Formatter
	bgRedBright: Formatter
	bgGreenBright: Formatter
	bgYellowBright: Formatter
	bgBlueBright: Formatter
	bgMagentaBright: Formatter
	bgCyanBright: Formatter
	bgWhiteBright: Formatter
}


code:
# Release history

**All notable changes to this project will be documented in this file.**

The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).

  Guiding Principles

- Changelogs are for humans, not machines.
- There should be an entry for every single version.
- The same types of changes should be grouped.
- Versions and sections should be linkable.
- The latest version comes first.
- The release date of each versions is displayed.
- Mention whether you follow Semantic Versioning.

  Types of changes

Changelog entries are classified using the following labels _(from [keep-a-changelog](http://keepachangelog.com/)_):

- `Added` for new features.
- `Changed` for changes in existing functionality.
- `Deprecated` for soon-to-be removed features.
- `Removed` for now removed features.
- `Fixed` for any bug fixes.
- `Security` in case of vulnerabilities.

## 2.3.1 (2022-01-02)

### Fixed

* Fixes bug when a pattern containing an expression after the closing parenthesis (`/!(*.d).{ts,tsx}`) was incorrectly converted to regexp ([9f241ef](https://github.com/micromatch/picomatch/commit/9f241ef)).

### Changed

* Some documentation improvements ([f81d236](https://github.com/micromatch/picomatch/commit/f81d236), [421e0e7](https://github.com/micromatch/picomatch/commit/421e0e7)).

## 2.3.0 (2021-05-21)

### Fixed

* Fixes bug where file names with two dots were not being matched consistently with negation extglobs containing a star ([56083ef](https://github.com/micromatch/picomatch/commit/56083ef))

## 2.2.3 (2021-04-10)

### Fixed

* Do not skip pattern seperator for square brackets ([fb08a30](https://github.com/micromatch/picomatch/commit/fb08a30)).
* Set negatedExtGlob also if it does not span the whole pattern ([032e3f5](https://github.com/micromatch/picomatch/commit/032e3f5)).

## 2.2.2 (2020-03-21)

### Fixed

* Correctly handle parts of the pattern after parentheses in the `scan` method ([e15b920](https://github.com/micromatch/picomatch/commit/e15b920)).

## 2.2.1 (2020-01-04)

* Fixes [#49](https://github.com/micromatch/picomatch/issues/49), so that braces with no sets or ranges are now propertly treated as literals.

## 2.2.0 (2020-01-04)

* Disable fastpaths mode for the parse method ([5b8d33f](https://github.com/micromatch/picomatch/commit/5b8d33f))
* Add `tokens`, `slashes`, and `parts` to the object returned by `picomatch.scan()`.

## 2.1.0 (2019-10-31)

* add benchmarks for scan ([4793b92](https://github.com/micromatch/picomatch/commit/4793b92))
* Add eslint object-curly-spacing rule ([707c650](https://github.com/micromatch/picomatch/commit/707c650))
* Add prefer-const eslint rule ([5c7501c](https://github.com/micromatch/picomatch/commit/5c7501c))
* Add support for nonegate in scan API ([275c9b9](https://github.com/micromatch/picomatch/commit/275c9b9))
* Change lets to consts. Move root import up. ([4840625](https://github.com/micromatch/picomatch/commit/4840625))
* closes https://github.com/micromatch/picomatch/issues/21 ([766bcb0](https://github.com/micromatch/picomatch/commit/766bcb0))
* Fix "Extglobs" table in readme ([eb19da8](https://github.com/micromatch/picomatch/commit/eb19da8))
* fixes https://github.com/micromatch/picomatch/issues/20 ([9caca07](https://github.com/micromatch/picomatch/commit/9caca07))
* fixes https://github.com/micromatch/picomatch/issues/26 ([fa58f45](https://github.com/micromatch/picomatch/commit/fa58f45))
* Lint test ([d433a34](https://github.com/micromatch/picomatch/commit/d433a34))
* lint unit tests ([0159b55](https://github.com/micromatch/picomatch/commit/0159b55))
* Make scan work with noext ([6c02e03](https://github.com/micromatch/picomatch/commit/6c02e03))
* minor linting ([c2a2b87](https://github.com/micromatch/picomatch/commit/c2a2b87))
* minor parser improvements ([197671d](https://github.com/micromatch/picomatch/commit/197671d))
* remove eslint since it... ([07876fa](https://github.com/micromatch/picomatch/commit/07876fa))
* remove funding file ([8ebe96d](https://github.com/micromatch/picomatch/commit/8ebe96d))
* Remove unused funks ([cbc6d54](https://github.com/micromatch/picomatch/commit/cbc6d54))
* Run eslint during pretest, fix existing eslint findings ([0682367](https://github.com/micromatch/picomatch/commit/0682367))
* support `noparen` in scan ([3d37569](https://github.com/micromatch/picomatch/commit/3d37569))
* update changelog ([7b34e77](https://github.com/micromatch/picomatch/commit/7b34e77))
* update travis ([777f038](https://github.com/micromatch/picomatch/commit/777f038))
* Use eslint-disable-next-line instead of eslint-disable ([4e7c1fd](https://github.com/micromatch/picomatch/commit/4e7c1fd))

## 2.0.7 (2019-05-14)

* 2.0.7 ([9eb9a71](https://github.com/micromatch/picomatch/commit/9eb9a71))
* supports lookbehinds ([1f63f7e](https://github.com/micromatch/picomatch/commit/1f63f7e))
* update .verb.md file with typo change ([2741279](https://github.com/micromatch/picomatch/commit/2741279))
* fix: typo in README ([0753e44](https://github.com/micromatch/picomatch/commit/0753e44))

## 2.0.4 (2019-04-10)

### Fixed

- Readme link [fixed](https://github.com/micromatch/picomatch/pull/13/commits/a96ab3aa2b11b6861c23289964613d85563b05df) by @danez.
- `options.capture` now works as expected when fastpaths are enabled. See https://github.com/micromatch/picomatch/pull/12/commits/26aefd71f1cfaf95c37f1c1fcab68a693b037304. Thanks to @DrPizza.

## 2.0.0 (2019-04-10)

### Added

- Adds support for `options.onIgnore`. See the readme for details
- Adds support for `options.onResult`. See the readme for details

### Breaking changes

- The unixify option was renamed to `windows`
- caching and all related options and methods have been removed

## 1.0.0 (2018-11-05)

- adds `.onMatch` option
- improvements to `.scan` method
- numerous improvements and optimizations for matching and parsing
- better windows path handling

## 0.1.0 - 2017-04-13

First release.

[keep-a-changelog]: https://github.com/olivierlacan/keep-a-changelog


code:
Picomatch

Blazing fast and accurate glob matcher written in JavaScript.

No dependencies and full support for standard and extended Bash glob features, including braces, extglobs, POSIX brackets, and regular expressions.

## Why picomatch?

* **Lightweight** - No dependencies
* **Minimal** - Tiny API surface. Main export is a function that takes a glob pattern and returns a matcher function.
* **Fast** - Loads in about 2ms (that's several times faster than a [single frame of a HD movie](http://www.endmemo.com/sconvert/framespersecondframespermillisecond.php) at 60fps)
* **Performant** - Use the returned matcher function to speed up repeat matching (like when watching files)
* **Accurate matching** - Using wildcards (`*` and `?`), globstars (`**`) for nested directories, [advanced globbing](#advanced-globbing) with extglobs, braces, and POSIX brackets, and support for escaping special characters with `\` or quotes.
* **Well tested** - Thousands of unit tests

See the [library comparison](#library-comparisons) to other libraries.

## Table of Contents

 Click to expand

- [Install](#install)
- [Usage](#usage)
- [API](#api)
  * [picomatch](#picomatch)
  * [.test](#test)
  * [.matchBase](#matchbase)
  * [.isMatch](#ismatch)
  * [.parse](#parse)
  * [.scan](#scan)
  * [.compileRe](#compilere)
  * [.makeRe](#makere)
  * [.toRegex](#toregex)
- [Options](#options)
  * [Picomatch options](#picomatch-options)
  * [Scan Options](#scan-options)
  * [Options Examples](#options-examples)
- [Globbing features](#globbing-features)
  * [Basic globbing](#basic-globbing)
  * [Advanced globbing](#advanced-globbing)
  * [Braces](#braces)
  * [Matching special characters as literals](#matching-special-characters-as-literals)
- [Library Comparisons](#library-comparisons)
- [Benchmarks](#benchmarks)
- [Philosophies](#philosophies)
- [About](#about)
  * [Author](#author)
  * [License](#license)

_(TOC generated by [verb](https://github.com/verbose/verb) using [markdown-toc](https://github.com/jonschlinkert/markdown-toc))_

## Install

Install with [npm](https://www.npmjs.com/):

```sh
npm install --save picomatch
```

## Usage

The main export is a function that takes a glob pattern and an options object and returns a function for matching strings.

```js
const pm = require('picomatch');
const isMatch = pm('*.js');

console.log(isMatch('abcd')); //=> false
console.log(isMatch('a.js')); //=> true
console.log(isMatch('a.md')); //=> false
console.log(isMatch('a/b.js')); //=> false
```

## API

### [picomatch](lib/picomatch.js#L32)

Creates a matcher function from one or more glob patterns. The returned function takes a string to match as its first argument, and returns true if the string is a match. The returned matcher function also takes a boolean as the second argument that, when true, returns an object with additional information.

**Params**

* `globs` **{String|Array}**: One or more glob patterns.
* `options` **{Object=}**
* `returns` **{Function=}**: Returns a matcher function.

**Example**

```js
const picomatch = require('picomatch');
// picomatch(glob[, options]);

const isMatch = picomatch('*.!(*a)');
console.log(isMatch('a.a')); //=> false
console.log(isMatch('a.b')); //=> true
```

### [.test](lib/picomatch.js#L117)

Test `input` with the given `regex`. This is used by the main `picomatch()` function to test the input string.

**Params**

* `input` **{String}**: String to test.
* `regex` **{RegExp}**
* `returns` **{Object}**: Returns an object with matching info.

**Example**

```js
const picomatch = require('picomatch');
// picomatch.test(input, regex[, options]);

console.log(picomatch.test('foo/bar', /^(?:([^/]*?)\/([^/]*?))$/));
// { isMatch: true, match: [ 'foo/', 'foo', 'bar' ], output: 'foo/bar' }
```

### [.matchBase](lib/picomatch.js#L161)

Match the basename of a filepath.

**Params**

* `input` **{String}**: String to test.
* `glob` **{RegExp|String}**: Glob pattern or regex created by [.makeRe](#makeRe).
* `returns` **{Boolean}**

**Example**

```js
const picomatch = require('picomatch');
// picomatch.matchBase(input, glob[, options]);
console.log(picomatch.matchBase('foo/bar.js', '*.js'); // true
```

### [.isMatch](lib/picomatch.js#L183)

Returns true if **any** of the given glob `patterns` match the specified `string`.

**Params**

* **{String|Array}**: str The string to test.
* **{String|Array}**: patterns One or more glob patterns to use for matching.
* **{Object}**: See available [options](#options).
* `returns` **{Boolean}**: Returns true if any patterns match `str`

**Example**

```js
const picomatch = require('picomatch');
// picomatch.isMatch(string, patterns[, options]);

console.log(picomatch.isMatch('a.a', ['b.*', '*.a'])); //=> true
console.log(picomatch.isMatch('a.a', 'b.*')); //=> false
```

### [.parse](lib/picomatch.js#L199)

Parse a glob pattern to create the source string for a regular expression.

**Params**

* `pattern` **{String}**
* `options` **{Object}**
* `returns` **{Object}**: Returns an object with useful properties and output to be used as a regex source string.

**Example**

```js
const picomatch = require('picomatch');
const result = picomatch.parse(pattern[, options]);
```

### [.scan](lib/picomatch.js#L231)

Scan a glob pattern to separate the pattern into segments.

**Params**

* `input` **{String}**: Glob pattern to scan.
* `options` **{Object}**
* `returns` **{Object}**: Returns an object with

**Example**

```js
const picomatch = require('picomatch');
// picomatch.scan(input[, options]);

const result = picomatch.scan('!./foo/*.js');
console.log(result);
{ prefix: '!./',
  input: '!./foo/*.js',
  start: 3,
  base: 'foo',
  glob: '*.js',
  isBrace: false,
  isBracket: false,
  isGlob: true,
  isExtglob: false,
  isGlobstar: false,
  negated: true }
```

### [.compileRe](lib/picomatch.js#L245)

Compile a regular expression from the `state` object returned by the
[parse()](#parse) method.

**Params**

* `state` **{Object}**
* `options` **{Object}**
* `returnOutput` **{Boolean}**: Intended for implementors, this argument allows you to return the raw output from the parser.
* `returnState` **{Boolean}**: Adds the state to a `state` property on the returned regex. Useful for implementors and debugging.
* `returns` **{RegExp}**

### [.makeRe](lib/picomatch.js#L286)

Create a regular expression from a parsed glob pattern.

**Params**

* `state` **{String}**: The object returned from the `.parse` method.
* `options` **{Object}**
* `returnOutput` **{Boolean}**: Implementors may use this argument to return the compiled output, instead of a regular expression. This is not exposed on the options to prevent end-users from mutating the result.
* `returnState` **{Boolean}**: Implementors may use this argument to return the state from the parsed glob with the returned regular expression.
* `returns` **{RegExp}**: Returns a regex created from the given pattern.

**Example**

```js
const picomatch = require('picomatch');
const state = picomatch.parse('*.js');
// picomatch.compileRe(state[, options]);

console.log(picomatch.compileRe(state));
//=> /^(?:(?!\.)(?=.)[^/]*?\.js)$/
```

### [.toRegex](lib/picomatch.js#L321)

Create a regular expression from the given regex source string.

**Params**

* `source` **{String}**: Regular expression source string.
* `options` **{Object}**
* `returns` **{RegExp}**

**Example**

```js
const picomatch = require('picomatch');
// picomatch.toRegex(source[, options]);

const { output } = picomatch.parse('*.js');
console.log(picomatch.toRegex(output));
//=> /^(?:(?!\.)(?=.)[^/]*?\.js)$/
```

## Options

### Picomatch options

The following options may be used with the main `picomatch()` function or any of the methods on the picomatch API.

| **Option** | **Type** | **Default value** | **Description** |
| --- | --- | --- | --- |
| `basename`            | `boolean`      | `false`     | If set, then patterns without slashes will be matched against the basename of the path if it contains slashes.  For example, `a?b` would match the path `/xyz/123/acb`, but not `/xyz/acb/123`. |
| `bash`                | `boolean`      | `false`     | Follow bash matching rules more strictly - disallows backslashes as escape characters, and treats single stars as globstars (`**`). |
| `capture`             | `boolean`      | `undefined` | Return regex matches in supporting methods. |
| `contains`            | `boolean`      | `undefined` | Allows glob to match any part of the given string(s). |
| `cwd`                 | `string`       | `process.cwd()` | Current working directory. Used by `picomatch.split()` |
| `debug`               | `boolean`      | `undefined` | Debug regular expressions when an error is thrown. |
| `dot`                 | `boolean`      | `false`     | Enable dotfile matching. By default, dotfiles are ignored unless a `.` is explicitly defined in the pattern, or `options.dot` is true |
| `expandRange`         | `function`     | `undefined` | Custom function for expanding ranges in brace patterns, such as `{a..z}`. The function receives the range values as two arguments, and it must return a string to be used in the generated regex. It's recommended that returned strings be wrapped in parentheses. |
| `failglob`            | `boolean`      | `false`     | Throws an error if no matches are found. Based on the bash option of the same name. |
| `fastpaths`           | `boolean`      | `true`      | To speed up processing, full parsing is skipped for a handful common glob patterns. Disable this behavior by setting this option to `false`. |
| `flags`               | `string`      | `undefined` | Regex flags to use in the generated regex. If defined, the `nocase` option will be overridden. |
| [format](#optionsformat) | `function` | `undefined` | Custom function for formatting the returned string. This is useful for removing leading slashes, converting Windows paths to Posix paths, etc. |
| `ignore`              | `array\|string` | `undefined` | One or more glob patterns for excluding strings that should not be matched from the result. |
| `keepQuotes`          | `boolean`      | `false`     | Retain quotes in the generated regex, since quotes may also be used as an alternative to backslashes.  |
| `literalBrackets`     | `boolean`      | `undefined` | When `true`, brackets in the glob pattern will be escaped so that only literal brackets will be matched. |
| `matchBase`           | `boolean`      | `false`     | Alias for `basename` |
| `maxLength`           | `boolean`      | `65536`     | Limit the max length of the input string. An error is thrown if the input string is longer than this value. |
| `nobrace`             | `boolean`      | `false`     | Disable brace matching, so that `{a,b}` and `{1..3}` would be treated as literal characters. |
| `nobracket`           | `boolean`      | `undefined` | Disable matching with regex brackets. |
| `nocase`              | `boolean`      | `false`     | Make matching case-insensitive. Equivalent to the regex `i` flag. Note that this option is overridden by the `flags` option. |
| `nodupes`             | `boolean`      | `true`      | Deprecated, use `nounique` instead. This option will be removed in a future major release. By default duplicates are removed. Disable uniquification by setting this option to false. |
| `noext`               | `boolean`      | `false`     | Alias for `noextglob` |
| `noextglob`           | `boolean`      | `false`     | Disable support for matching with extglobs (like `+(a\|b)`) |
| `noglobstar`          | `boolean`      | `false`     | Disable support for matching nested directories with globstars (`**`) |
| `nonegate`            | `boolean`      | `false`     | Disable support for negating with leading `!` |
| `noquantifiers`       | `boolean`      | `false`     | Disable support for regex quantifiers (like `a{1,2}`) and treat them as brace patterns to be expanded. |
| [onIgnore](#optionsonIgnore) | `function` | `undefined` | Function to be called on ignored items. |
| [onMatch](#optionsonMatch) | `function` | `undefined` | Function to be called on matched items. |
| [onResult](#optionsonResult) | `function` | `undefined` | Function to be called on all items, regardless of whether or not they are matched or ignored. |
| `posix`               | `boolean`      | `false`     | Support POSIX character classes ("posix brackets"). |
| `posixSlashes`        | `boolean`      | `undefined` | Convert all slashes in file paths to forward slashes. This does not convert slashes in the glob pattern itself |
| `prepend`             | `boolean`      | `undefined` | String to prepend to the generated regex used for matching. |
| `regex`               | `boolean`      | `false`     | Use regular expression rules for `+` (instead of matching literal `+`), and for stars that follow closing parentheses or brackets (as in `)*` and `]*`). |
| `strictBrackets`      | `boolean`      | `undefined` | Throw an error if brackets, braces, or parens are imbalanced. |
| `strictSlashes`       | `boolean`      | `undefined` | When true, picomatch won't match trailing slashes with single stars. |
| `unescape`            | `boolean`      | `undefined` | Remove backslashes preceding escaped characters in the glob pattern. By default, backslashes are retained. |
| `unixify`             | `boolean`      | `undefined` | Alias for `posixSlashes`, for backwards compatibility. |

picomatch has automatic detection for regex positive and negative lookbehinds. If the pattern contains a negative lookbehind, you must be using Node.js >= 8.10 or else picomatch will throw an error.

### Scan Options

In addition to the main [picomatch options](#picomatch-options), the following options may also be used with the [.scan](#scan) method.

| **Option** | **Type** | **Default value** | **Description** |
| --- | --- | --- | --- |
| `tokens` | `boolean` | `false` | When `true`, the returned object will include an array of tokens (objects), representing each path "segment" in the scanned glob pattern |
| `parts` | `boolean` | `false` | When `true`, the returned object will include an array of strings representing each path "segment" in the scanned glob pattern. This is automatically enabled when `options.tokens` is true |

**Example**

```js
const picomatch = require('picomatch');
const result = picomatch.scan('!./foo/*.js', { tokens: true });
console.log(result);
// {
//   prefix: '!./',
//   input: '!./foo/*.js',
//   start: 3,
//   base: 'foo',
//   glob: '*.js',
//   isBrace: false,
//   isBracket: false,
//   isGlob: true,
//   isExtglob: false,
//   isGlobstar: false,
//   negated: true,
//   maxDepth: 2,
//   tokens: [
//     { value: '!./', depth: 0, isGlob: false, negated: true, isPrefix: true },
//     { value: 'foo', depth: 1, isGlob: false },
//     { value: '*.js', depth: 1, isGlob: true }
//   ],
//   slashes: [ 2, 6 ],
//   parts: [ 'foo', '*.js' ]
// }
```

### Options Examples

#### options.expandRange

**Type**: `function`

**Default**: `undefined`

Custom function for expanding ranges in brace patterns. The [fill-range](https://github.com/jonschlinkert/fill-range) library is ideal for this purpose, or you can use custom code to do whatever you need.

**Example**

The following example shows how to create a glob that matches a folder

```js
const fill = require('fill-range');
const regex = pm.makeRe('foo/{01..25}/bar', {
  expandRange(a, b) {
    return `(${fill(a, b, { toRegex: true })})`;
  }
});

console.log(regex);
//=> /^(?:foo\/((?:0[1-9]|1[0-9]|2[0-5]))\/bar)$/

console.log(regex.test('foo/00/bar'))  // false
console.log(regex.test('foo/01/bar'))  // true
console.log(regex.test('foo/10/bar')) // true
console.log(regex.test('foo/22/bar')) // true
console.log(regex.test('foo/25/bar')) // true
console.log(regex.test('foo/26/bar')) // false
```

#### options.format

**Type**: `function`

**Default**: `undefined`

Custom function for formatting strings before they're matched.

**Example**

```js
// strip leading './' from strings
const format = str => str.replace(/^\.\//, '');
const isMatch = picomatch('foo/*.js', { format });
console.log(isMatch('./foo/bar.js')); //=> true
```

#### options.onMatch

```js
const onMatch = ({ glob, regex, input, output }) => {
  console.log({ glob, regex, input, output });
};

const isMatch = picomatch('*', { onMatch });
isMatch('foo');
isMatch('bar');
isMatch('baz');
```

#### options.onIgnore

```js
const onIgnore = ({ glob, regex, input, output }) => {
  console.log({ glob, regex, input, output });
};

const isMatch = picomatch('*', { onIgnore, ignore: 'f*' });
isMatch('foo');
isMatch('bar');
isMatch('baz');
```

#### options.onResult

```js
const onResult = ({ glob, regex, input, output }) => {
  console.log({ glob, regex, input, output });
};

const isMatch = picomatch('*', { onResult, ignore: 'f*' });
isMatch('foo');
isMatch('bar');
isMatch('baz');
```

## Globbing features

* [Basic globbing](#basic-globbing) (Wildcard matching)
* [Advanced globbing](#advanced-globbing) (extglobs, posix brackets, brace matching)

### Basic globbing

| **Character** | **Description** |
| --- | --- |
| `*` | Matches any character zero or more times, excluding path separators. Does _not match_ path separators or hidden files or directories ("dotfiles"), unless explicitly enabled by setting the `dot` option to `true`. |
| `**` | Matches any character zero or more times, including path separators. Note that `**` will only match path separators (`/`, and `\\` on Windows) when they are the only characters in a path segment. Thus, `foo**/bar` is equivalent to `foo*/bar`, and `foo/a**b/bar` is equivalent to `foo/a*b/bar`, and _more than two_ consecutive stars in a glob path segment are regarded as _a single star_. Thus, `foo/***/bar` is equivalent to `foo/*/bar`. |
| `?` | Matches any character excluding path separators one time. Does _not match_ path separators or leading dots.  |
| `[abc]` | Matches any characters inside the brackets. For example, `[abc]` would match the characters `a`, `b` or `c`, and nothing else. |

#### Matching behavior vs. Bash

Picomatch's matching features and expected results in unit tests are based on Bash's unit tests and the Bash 4.3 specification, with the following exceptions:

* Bash will match `foo/bar/baz` with `*`. Picomatch only matches nested directories with `**`.
* Bash greedily matches with negated extglobs. For example, Bash 4.3 says that `!(foo)*` should match `foo` and `foobar`, since the trailing `*` bracktracks to match the preceding pattern. This is very memory-inefficient, and IMHO, also incorrect. Picomatch would return `false` for both `foo` and `foobar`.

### Advanced globbing

* [extglobs](#extglobs)
* [POSIX brackets](#posix-brackets)
* [Braces](#brace-expansion)

#### Extglobs

| **Pattern** | **Description** |
| --- | --- |
| `@(pattern)` | Match _only one_ consecutive occurrence of `pattern` |
| `*(pattern)` | Match _zero or more_ consecutive occurrences of `pattern` |
| `+(pattern)` | Match _one or more_ consecutive occurrences of `pattern` |
| `?(pattern)` | Match _zero or **one**_ consecutive occurrences of `pattern` |
| `!(pattern)` | Match _anything but_ `pattern` |

**Examples**

```js
const pm = require('picomatch');

// *(pattern) matches ZERO or more of "pattern"
console.log(pm.isMatch('a', 'a*(z)')); // true
console.log(pm.isMatch('az', 'a*(z)')); // true
console.log(pm.isMatch('azzz', 'a*(z)')); // true

// +(pattern) matches ONE or more of "pattern"
console.log(pm.isMatch('a', 'a*(z)')); // true
console.log(pm.isMatch('az', 'a*(z)')); // true
console.log(pm.isMatch('azzz', 'a*(z)')); // true

// supports multiple extglobs
console.log(pm.isMatch('foo.bar', '!(foo).!(bar)')); // false

// supports nested extglobs
console.log(pm.isMatch('foo.bar', '!(!(foo)).!(!(bar))')); // true
```

#### POSIX brackets

POSIX classes are disabled by default. Enable this feature by setting the `posix` option to true.

**Enable POSIX bracket support**

```js
console.log(pm.makeRe('[[:word:]]+', { posix: true }));
//=> /^(?:(?=.)[A-Za-z0-9_]+\/?)$/
```

**Supported POSIX classes**

The following named POSIX bracket expressions are supported:

* `[:alnum:]` - Alphanumeric characters, equ `[a-zA-Z0-9]`
* `[:alpha:]` - Alphabetical characters, equivalent to `[a-zA-Z]`.
* `[:ascii:]` - ASCII characters, equivalent to `[\\x00-\\x7F]`.
* `[:blank:]` - Space and tab characters, equivalent to `[ \\t]`.
* `[:cntrl:]` - Control characters, equivalent to `[\\x00-\\x1F\\x7F]`.
* `[:digit:]` - Numerical digits, equivalent to `[0-9]`.
* `[:graph:]` - Graph characters, equivalent to `[\\x21-\\x7E]`.
* `[:lower:]` - Lowercase letters, equivalent to `[a-z]`.
* `[:print:]` - Print characters, equivalent to `[\\x20-\\x7E ]`.
* `[:punct:]` - Punctuation and symbols, equivalent to `[\\-!"#$%&\'()\\*+,./:;<=>?@[\\]^_`{|}~]`.
* `[:space:]` - Extended space characters, equivalent to `[ \\t\\r\\n\\v\\f]`.
* `[:upper:]` - Uppercase letters, equivalent to `[A-Z]`.
* `[:word:]` -  Word characters (letters, numbers and underscores), equivalent to `[A-Za-z0-9_]`.
* `[:xdigit:]` - Hexadecimal digits, equivalent to `[A-Fa-f0-9]`.

See the [Bash Reference Manual](https://www.gnu.org/software/bash/manual/html_node/Pattern-Matching.html) for more information.

### Braces

Picomatch does not do brace expansion. For [brace expansion](https://www.gnu.org/software/bash/manual/html_node/Brace-Expansion.html) and advanced matching with braces, use [micromatch](https://github.com/micromatch/micromatch) instead. Picomatch has very basic support for braces.

### Matching special characters as literals

If you wish to match the following special characters in a filepath, and you want to use these characters in your glob pattern, they must be escaped with backslashes or quotes:

**Special Characters**

Some characters that are used for matching in regular expressions are also regarded as valid file path characters on some platforms.

To match any of the following characters as literals: `$^*+?()[]

Examples:

```js
console.log(pm.makeRe('foo/bar \\(1\\)'));
console.log(pm.makeRe('foo/bar \\(1\\)'));
```

## Library Comparisons

The following table shows which features are supported by [minimatch](https://github.com/isaacs/minimatch), [micromatch](https://github.com/micromatch/micromatch), [picomatch](https://github.com/micromatch/picomatch), [nanomatch](https://github.com/micromatch/nanomatch), [extglob](https://github.com/micromatch/extglob), [braces](https://github.com/micromatch/braces), and [expand-brackets](https://github.com/micromatch/expand-brackets).

| **Feature** | `minimatch` | `micromatch` | `picomatch` | `nanomatch` | `extglob` | `braces` | `expand-brackets` |
| --- | --- | --- | --- | --- | --- | --- | --- |
| Wildcard matching (`*?+`) | ✔ | ✔ | ✔ | ✔ | - | - | - |
| Advancing globbing        | ✔ | ✔ | ✔ | - | - | - | - |
| Brace _matching_          | ✔ | ✔ | ✔ | - | - | ✔ | - |
| Brace _expansion_         | ✔ | ✔ | - | - | - | ✔ | - |
| Extglobs                  | partial | ✔ | ✔ | - | ✔ | - | - |
| Posix brackets            | - | ✔ | ✔ | - | - | - | ✔ |
| Regular expression syntax | - | ✔ | ✔ | ✔ | ✔ | - | ✔ |
| File system operations    | - | - | - | - | - | - | - |

## Benchmarks

Performance comparison of picomatch and minimatch.

```
# .makeRe star
  picomatch x 1,993,050 ops/sec ±0.51% (91 runs sampled)
  minimatch x 627,206 ops/sec ±1.96% (87 runs sampled))

# .makeRe star; dot=true
  picomatch x 1,436,640 ops/sec ±0.62% (91 runs sampled)
  minimatch x 525,876 ops/sec ±0.60% (88 runs sampled)

# .makeRe globstar
  picomatch x 1,592,742 ops/sec ±0.42% (90 runs sampled)
  minimatch x 962,043 ops/sec ±1.76% (91 runs sampled)d)

# .makeRe globstars
  picomatch x 1,615,199 ops/sec ±0.35% (94 runs sampled)
  minimatch x 477,179 ops/sec ±1.33% (91 runs sampled)

# .makeRe with leading star
  picomatch x 1,220,856 ops/sec ±0.40% (92 runs sampled)
  minimatch x 453,564 ops/sec ±1.43% (94 runs sampled)

# .makeRe - basic braces
  picomatch x 392,067 ops/sec ±0.70% (90 runs sampled)
  minimatch x 99,532 ops/sec ±2.03% (87 runs sampled))
```

## Philosophies

The goal of this library is to be blazing fast, without compromising on accuracy.

**Accuracy**

The number one of goal of this library is accuracy. However, it's not unusual for different glob implementations to have different rules for matching behavior, even with simple wildcard matching. It gets increasingly more complicated when combinations of different features are combined, like when extglobs are combined with globstars, braces, slashes, and so on: `!(**/{a,b,*/c})`.

Thus, given that there is no canonical glob specification to use as a single source of truth when differences of opinion arise regarding behavior, sometimes we have to implement our best judgement and rely on feedback from users to make improvements.

**Performance**

Although this library performs well in benchmarks, and in most cases it's faster than other popular libraries we benchmarked against, we will always choose accuracy over performance. It's not helpful to anyone if our library is faster at returning the wrong answer.

## About

Contributing

Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](../../issues/new).

Please read the [contributing guide](.github/contributing.md) for advice on opening issues, pull requests, and coding standards.

Running Tests

Running and reviewing unit tests is a great way to get familiarized with a library and its API. You can install dependencies and run tests with the following command:

```sh
npm install && npm test
```

Building docs

_(This project's readme.md is generated by [verb](https://github.com/verbose/verb-generate-readme), please don't edit the readme directly. Any changes to the readme must be made in the [.verb.md](.verb.md) readme template.)_

To generate the readme, run the following command:

```sh
npm install -g verbose/verb#dev verb-generate-readme && verb
```

### Author

**Jon Schlinkert**

* [GitHub Profile](https://github.com/jonschlinkert)
* [Twitter Profile](https://twitter.com/jonschlinkert)
* [LinkedIn Profile](https://linkedin.com/in/jonschlinkert)

### License

Copyright © 2017-present, [Jon Schlinkert](https://github.com/jonschlinkert).
Released under the [MIT License](LICENSE).


code:
'use strict';

module.exports = require('./lib/picomatch');


code:
'use strict';

const path = require('path');
const WIN_SLASH = '\\\\/';
const WIN_NO_SLASH = `[^${WIN_SLASH}]`;

/**
 * Posix glob regex
 */

const DOT_LITERAL = '\\.';
const PLUS_LITERAL = '\\+';
const QMARK_LITERAL = '\\?';
const SLASH_LITERAL = '\\/';
const ONE_CHAR = '(?=.)';
const QMARK = '[^/]';
const END_ANCHOR = `(?:${SLASH_LITERAL}|$)`;
const START_ANCHOR = `(?:^|${SLASH_LITERAL})`;
const DOTS_SLASH = `${DOT_LITERAL}{1,2}${END_ANCHOR}`;
const NO_DOT = `(?!${DOT_LITERAL})`;
const NO_DOTS = `(?!${START_ANCHOR}${DOTS_SLASH})`;
const NO_DOT_SLASH = `(?!${DOT_LITERAL}{0,1}${END_ANCHOR})`;
const NO_DOTS_SLASH = `(?!${DOTS_SLASH})`;
const QMARK_NO_DOT = `[^.${SLASH_LITERAL}]`;
const STAR = `${QMARK}*?`;

const POSIX_CHARS = {
  DOT_LITERAL,
  PLUS_LITERAL,
  QMARK_LITERAL,
  SLASH_LITERAL,
  ONE_CHAR,
  QMARK,
  END_ANCHOR,
  DOTS_SLASH,
  NO_DOT,
  NO_DOTS,
  NO_DOT_SLASH,
  NO_DOTS_SLASH,
  QMARK_NO_DOT,
  STAR,
  START_ANCHOR
};

/**
 * Windows glob regex
 */

const WINDOWS_CHARS = {
  ...POSIX_CHARS,

  SLASH_LITERAL: `[${WIN_SLASH}]`,
  QMARK: WIN_NO_SLASH,
  STAR: `${WIN_NO_SLASH}*?`,
  DOTS_SLASH: `${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$)`,
  NO_DOT: `(?!${DOT_LITERAL})`,
  NO_DOTS: `(?!(?:^|[${WIN_SLASH}])${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$))`,
  NO_DOT_SLASH: `(?!${DOT_LITERAL}{0,1}(?:[${WIN_SLASH}]|$))`,
  NO_DOTS_SLASH: `(?!${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$))`,
  QMARK_NO_DOT: `[^.${WIN_SLASH}]`,
  START_ANCHOR: `(?:^|[${WIN_SLASH}])`,
  END_ANCHOR: `(?:[${WIN_SLASH}]|$)`
};

/**
 * POSIX Bracket Regex
 */

const POSIX_REGEX_SOURCE = {
  alnum: 'a-zA-Z0-9',
  alpha: 'a-zA-Z',
  ascii: '\\x00-\\x7F',
  blank: ' \\t',
  cntrl: '\\x00-\\x1F\\x7F',
  digit: '0-9',
  graph: '\\x21-\\x7E',
  lower: 'a-z',
  print: '\\x20-\\x7E ',
  punct: '\\-!"#$%&\'()\\*+,./:;<=>?@[\\]^_`{|}~',
  space: ' \\t\\r\\n\\v\\f',
  upper: 'A-Z',
  word: 'A-Za-z0-9_',
  xdigit: 'A-Fa-f0-9'
};

module.exports = {
  MAX_LENGTH: 1024 * 64,
  POSIX_REGEX_SOURCE,

  // regular expressions
  REGEX_BACKSLASH: /\\(?![*+?^${}(|)[\]])/g,
  REGEX_NON_SPECIAL_CHARS: /^[^@![\].,$*+?^{}()|\\/]+/,
  REGEX_SPECIAL_CHARS: /[-*+?.^${}(|)[\]]/,
  REGEX_SPECIAL_CHARS_BACKREF: /(\\?)((\W)(\3*))/g,
  REGEX_SPECIAL_CHARS_GLOBAL: /([-*+?.^${}(|)[\]])/g,
  REGEX_REMOVE_BACKSLASH: /(?:\[.*?[^\\]\]|\\(?=.))/g,

  // Replace globs with equivalent patterns to reduce parsing time.
  REPLACEMENTS: {
    '***': '*',
    '**/**': '**',
    '**/**/**': '**'
  },

  // Digits
  CHAR_0: 48, /* 0 */
  CHAR_9: 57, /* 9 */

  // Alphabet chars.
  CHAR_UPPERCASE_A: 65, /* A */
  CHAR_LOWERCASE_A: 97, /* a */
  CHAR_UPPERCASE_Z: 90, /* Z */
  CHAR_LOWERCASE_Z: 122, /* z */

  CHAR_LEFT_PARENTHESES: 40, /* ( */
  CHAR_RIGHT_PARENTHESES: 41, /* ) */

  CHAR_ASTERISK: 42, /* * */

  // Non-alphabetic chars.
  CHAR_AMPERSAND: 38, /* & */
  CHAR_AT: 64, /* @ */
  CHAR_BACKWARD_SLASH: 92, /* \ */
  CHAR_CARRIAGE_RETURN: 13, /* \r */
  CHAR_CIRCUMFLEX_ACCENT: 94, /* ^ */
  CHAR_COLON: 58, /* : */
  CHAR_COMMA: 44, /* , */
  CHAR_DOT: 46, /* . */
  CHAR_DOUBLE_QUOTE: 34, /* " */
  CHAR_EQUAL: 61, /* = */
  CHAR_EXCLAMATION_MARK: 33, /* ! */
  CHAR_FORM_FEED: 12, /* \f */
  CHAR_FORWARD_SLASH: 47, /* / */
  CHAR_GRAVE_ACCENT: 96, /* ` */
  CHAR_HASH: 35, /* # */
  CHAR_HYPHEN_MINUS: 45, /* - */
  CHAR_LEFT_ANGLE_BRACKET: 60, /* < */
  CHAR_LEFT_CURLY_BRACE: 123, /* { */
  CHAR_LEFT_SQUARE_BRACKET: 91, /* [ */
  CHAR_LINE_FEED: 10, /* \n */
  CHAR_NO_BREAK_SPACE: 160, /* \u00A0 */
  CHAR_PERCENT: 37, /* % */
  CHAR_PLUS: 43, /* + */
  CHAR_QUESTION_MARK: 63, /* ? */
  CHAR_RIGHT_ANGLE_BRACKET: 62, /* > */
  CHAR_RIGHT_CURLY_BRACE: 125, /* } */
  CHAR_RIGHT_SQUARE_BRACKET: 93, /* ] */
  CHAR_SEMICOLON: 59, /* ; */
  CHAR_SINGLE_QUOTE: 39, /* ' */
  CHAR_SPACE: 32, /*   */
  CHAR_TAB: 9, /* \t */
  CHAR_UNDERSCORE: 95, /* _ */
  CHAR_VERTICAL_LINE: 124, /* | */
  CHAR_ZERO_WIDTH_NOBREAK_SPACE: 65279, /* \uFEFF */

  SEP: path.sep,

  /**
   * Create EXTGLOB_CHARS
   */

  extglobChars(chars) {
    return {
      '!': { type: 'negate', open: '(?:(?!(?:', close: `))${chars.STAR})` },
      '?': { type: 'qmark', open: '(?:', close: ')?' },
      '+': { type: 'plus', open: '(?:', close: ')+' },
      '*': { type: 'star', open: '(?:', close: ')*' },
      '@': { type: 'at', open: '(?:', close: ')' }
    };
  },

  /**
   * Create GLOB_CHARS
   */

  globChars(win32) {
    return win32 === true ? WINDOWS_CHARS : POSIX_CHARS;
  }
};