| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386 | 
							- 'use strict';
 
- var regexNot = require('regex-not');
 
- var toRegex = require('to-regex');
 
- /**
 
-  * Characters to use in negation regex (we want to "not" match
 
-  * characters that are matched by other parsers)
 
-  */
 
- var cached;
 
- var NOT_REGEX = '[\\[!*+?$^"\'.\\\\/]+';
 
- var not = createTextRegex(NOT_REGEX);
 
- /**
 
-  * Nanomatch parsers
 
-  */
 
- module.exports = function(nanomatch, options) {
 
-   var parser = nanomatch.parser;
 
-   var opts = parser.options;
 
-   parser.state = {
 
-     slashes: 0,
 
-     paths: []
 
-   };
 
-   parser.ast.state = parser.state;
 
-   parser
 
-     /**
 
-      * Beginning-of-string
 
-      */
 
-     .capture('prefix', function() {
 
-       if (this.parsed) return;
 
-       var m = this.match(/^\.[\\/]/);
 
-       if (!m) return;
 
-       this.state.strictOpen = !!this.options.strictOpen;
 
-       this.state.addPrefix = true;
 
-     })
 
-     /**
 
-      * Escape: "\\."
 
-      */
 
-     .capture('escape', function() {
 
-       if (this.isInside('bracket')) return;
 
-       var pos = this.position();
 
-       var m = this.match(/^(?:\\(.)|([$^]))/);
 
-       if (!m) return;
 
-       return pos({
 
-         type: 'escape',
 
-         val: m[2] || m[1]
 
-       });
 
-     })
 
-     /**
 
-      * Quoted strings
 
-      */
 
-     .capture('quoted', function() {
 
-       var pos = this.position();
 
-       var m = this.match(/^["']/);
 
-       if (!m) return;
 
-       var quote = m[0];
 
-       if (this.input.indexOf(quote) === -1) {
 
-         return pos({
 
-           type: 'escape',
 
-           val: quote
 
-         });
 
-       }
 
-       var tok = advanceTo(this.input, quote);
 
-       this.consume(tok.len);
 
-       return pos({
 
-         type: 'quoted',
 
-         val: tok.esc
 
-       });
 
-     })
 
-     /**
 
-      * Negations: "!"
 
-      */
 
-     .capture('not', function() {
 
-       var parsed = this.parsed;
 
-       var pos = this.position();
 
-       var m = this.match(this.notRegex || /^!+/);
 
-       if (!m) return;
 
-       var val = m[0];
 
-       var isNegated = (val.length % 2) === 1;
 
-       if (parsed === '' && !isNegated) {
 
-         val = '';
 
-       }
 
-       // if nothing has been parsed, we know `!` is at the start,
 
-       // so we need to wrap the result in a negation regex
 
-       if (parsed === '' && isNegated && this.options.nonegate !== true) {
 
-         this.bos.val = '(?!^(?:';
 
-         this.append = ')$).*';
 
-         val = '';
 
-       }
 
-       return pos({
 
-         type: 'not',
 
-         val: val
 
-       });
 
-     })
 
-     /**
 
-      * Dot: "."
 
-      */
 
-     .capture('dot', function() {
 
-       var parsed = this.parsed;
 
-       var pos = this.position();
 
-       var m = this.match(/^\.+/);
 
-       if (!m) return;
 
-       var val = m[0];
 
-       this.state.dot = val === '.' && (parsed === '' || parsed.slice(-1) === '/');
 
-       return pos({
 
-         type: 'dot',
 
-         dotfiles: this.state.dot,
 
-         val: val
 
-       });
 
-     })
 
-     /**
 
-      * Plus: "+"
 
-      */
 
-     .capture('plus', /^\+(?!\()/)
 
-     /**
 
-      * Question mark: "?"
 
-      */
 
-     .capture('qmark', function() {
 
-       var parsed = this.parsed;
 
-       var pos = this.position();
 
-       var m = this.match(/^\?+(?!\()/);
 
-       if (!m) return;
 
-       this.state.metachar = true;
 
-       this.state.qmark = true;
 
-       return pos({
 
-         type: 'qmark',
 
-         parsed: parsed,
 
-         val: m[0]
 
-       });
 
-     })
 
-     /**
 
-      * Globstar: "**"
 
-      */
 
-     .capture('globstar', function() {
 
-       var parsed = this.parsed;
 
-       var pos = this.position();
 
-       var m = this.match(/^\*{2}(?![*(])(?=[,)/]|$)/);
 
-       if (!m) return;
 
-       var type = opts.noglobstar !== true ? 'globstar' : 'star';
 
-       var node = pos({type: type, parsed: parsed});
 
-       this.state.metachar = true;
 
-       while (this.input.slice(0, 4) === '/**/') {
 
-         this.input = this.input.slice(3);
 
-       }
 
-       node.isInside = {
 
-         brace: this.isInside('brace'),
 
-         paren: this.isInside('paren')
 
-       };
 
-       if (type === 'globstar') {
 
-         this.state.globstar = true;
 
-         node.val = '**';
 
-       } else {
 
-         this.state.star = true;
 
-         node.val = '*';
 
-       }
 
-       return node;
 
-     })
 
-     /**
 
-      * Star: "*"
 
-      */
 
-     .capture('star', function() {
 
-       var pos = this.position();
 
-       var starRe = /^(?:\*(?![*(])|[*]{3,}(?!\()|[*]{2}(?![(/]|$)|\*(?=\*\())/;
 
-       var m = this.match(starRe);
 
-       if (!m) return;
 
-       this.state.metachar = true;
 
-       this.state.star = true;
 
-       return pos({
 
-         type: 'star',
 
-         val: m[0]
 
-       });
 
-     })
 
-     /**
 
-      * Slash: "/"
 
-      */
 
-     .capture('slash', function() {
 
-       var pos = this.position();
 
-       var m = this.match(/^\//);
 
-       if (!m) return;
 
-       this.state.slashes++;
 
-       return pos({
 
-         type: 'slash',
 
-         val: m[0]
 
-       });
 
-     })
 
-     /**
 
-      * Backslash: "\\"
 
-      */
 
-     .capture('backslash', function() {
 
-       var pos = this.position();
 
-       var m = this.match(/^\\(?![*+?(){}[\]'"])/);
 
-       if (!m) return;
 
-       var val = m[0];
 
-       if (this.isInside('bracket')) {
 
-         val = '\\';
 
-       } else if (val.length > 1) {
 
-         val = '\\\\';
 
-       }
 
-       return pos({
 
-         type: 'backslash',
 
-         val: val
 
-       });
 
-     })
 
-     /**
 
-      * Square: "[.]"
 
-      */
 
-     .capture('square', function() {
 
-       if (this.isInside('bracket')) return;
 
-       var pos = this.position();
 
-       var m = this.match(/^\[([^!^\\])\]/);
 
-       if (!m) return;
 
-       return pos({
 
-         type: 'square',
 
-         val: m[1]
 
-       });
 
-     })
 
-     /**
 
-      * Brackets: "[...]" (basic, this can be overridden by other parsers)
 
-      */
 
-     .capture('bracket', function() {
 
-       var pos = this.position();
 
-       var m = this.match(/^(?:\[([!^]?)([^\]]+|\]-)(\]|[^*+?]+)|\[)/);
 
-       if (!m) return;
 
-       var val = m[0];
 
-       var negated = m[1] ? '^' : '';
 
-       var inner = (m[2] || '').replace(/\\\\+/, '\\\\');
 
-       var close = m[3] || '';
 
-       if (m[2] && inner.length < m[2].length) {
 
-         val = val.replace(/\\\\+/, '\\\\');
 
-       }
 
-       var esc = this.input.slice(0, 2);
 
-       if (inner === '' && esc === '\\]') {
 
-         inner += esc;
 
-         this.consume(2);
 
-         var str = this.input;
 
-         var idx = -1;
 
-         var ch;
 
-         while ((ch = str[++idx])) {
 
-           this.consume(1);
 
-           if (ch === ']') {
 
-             close = ch;
 
-             break;
 
-           }
 
-           inner += ch;
 
-         }
 
-       }
 
-       return pos({
 
-         type: 'bracket',
 
-         val: val,
 
-         escaped: close !== ']',
 
-         negated: negated,
 
-         inner: inner,
 
-         close: close
 
-       });
 
-     })
 
-     /**
 
-      * Text
 
-      */
 
-     .capture('text', function() {
 
-       if (this.isInside('bracket')) return;
 
-       var pos = this.position();
 
-       var m = this.match(not);
 
-       if (!m || !m[0]) return;
 
-       return pos({
 
-         type: 'text',
 
-         val: m[0]
 
-       });
 
-     });
 
-   /**
 
-    * Allow custom parsers to be passed on options
 
-    */
 
-   if (options && typeof options.parsers === 'function') {
 
-     options.parsers(nanomatch.parser);
 
-   }
 
- };
 
- /**
 
-  * Advance to the next non-escaped character
 
-  */
 
- function advanceTo(input, endChar) {
 
-   var ch = input.charAt(0);
 
-   var tok = { len: 1, val: '', esc: '' };
 
-   var idx = 0;
 
-   function advance() {
 
-     if (ch !== '\\') {
 
-       tok.esc += '\\' + ch;
 
-       tok.val += ch;
 
-     }
 
-     ch = input.charAt(++idx);
 
-     tok.len++;
 
-     if (ch === '\\') {
 
-       advance();
 
-       advance();
 
-     }
 
-   }
 
-   while (ch && ch !== endChar) {
 
-     advance();
 
-   }
 
-   return tok;
 
- }
 
- /**
 
-  * Create text regex
 
-  */
 
- function createTextRegex(pattern) {
 
-   if (cached) return cached;
 
-   var opts = {contains: true, strictClose: false};
 
-   var not = regexNot.create(pattern, opts);
 
-   var re = toRegex('^(?:[*]\\((?=.)|' + not + ')', opts);
 
-   return (cached = re);
 
- }
 
- /**
 
-  * Expose negation string
 
-  */
 
- module.exports.not = NOT_REGEX;
 
 
  |