source: node_modules/rollup/dist/es/shared/watch.js@ 57e58a3

Last change on this file since 57e58a3 was 57e58a3, checked in by ste08 <sjovanoska@…>, 4 months ago

Initial commit

  • Property mode set to 100644
File size: 245.1 KB
Line 
1/*
2 @license
3 Rollup.js v4.34.4
4 Wed, 05 Feb 2025 21:30:40 GMT - commit 19312a762c3cda56a0f6dc80a0887a4499db2257
5
6 https://github.com/rollup/rollup
7
8 Released under the MIT License.
9*/
10import { getAugmentedNamespace, fseventsImporter, getDefaultExportFromCjs, createFilter, rollupInternal } from './node-entry.js';
11import path from 'node:path';
12import process$1 from 'node:process';
13import require$$0$1 from 'path';
14import require$$2 from 'util';
15import require$$0$2 from 'fs';
16import require$$1 from 'stream';
17import require$$2$1 from 'os';
18import require$$0$3 from 'events';
19import { platform } from 'node:os';
20import './parseAst.js';
21import '../../native.js';
22import 'node:perf_hooks';
23import 'node:fs/promises';
24
25var chokidar$1 = {};
26
27var utils$2 = {};
28
29var constants$3;
30var hasRequiredConstants$3;
31
32function requireConstants$3 () {
33 if (hasRequiredConstants$3) return constants$3;
34 hasRequiredConstants$3 = 1;
35
36 const path = require$$0$1;
37 const WIN_SLASH = '\\\\/';
38 const WIN_NO_SLASH = `[^${WIN_SLASH}]`;
39
40 /**
41 * Posix glob regex
42 */
43
44 const DOT_LITERAL = '\\.';
45 const PLUS_LITERAL = '\\+';
46 const QMARK_LITERAL = '\\?';
47 const SLASH_LITERAL = '\\/';
48 const ONE_CHAR = '(?=.)';
49 const QMARK = '[^/]';
50 const END_ANCHOR = `(?:${SLASH_LITERAL}|$)`;
51 const START_ANCHOR = `(?:^|${SLASH_LITERAL})`;
52 const DOTS_SLASH = `${DOT_LITERAL}{1,2}${END_ANCHOR}`;
53 const NO_DOT = `(?!${DOT_LITERAL})`;
54 const NO_DOTS = `(?!${START_ANCHOR}${DOTS_SLASH})`;
55 const NO_DOT_SLASH = `(?!${DOT_LITERAL}{0,1}${END_ANCHOR})`;
56 const NO_DOTS_SLASH = `(?!${DOTS_SLASH})`;
57 const QMARK_NO_DOT = `[^.${SLASH_LITERAL}]`;
58 const STAR = `${QMARK}*?`;
59
60 const POSIX_CHARS = {
61 DOT_LITERAL,
62 PLUS_LITERAL,
63 QMARK_LITERAL,
64 SLASH_LITERAL,
65 ONE_CHAR,
66 QMARK,
67 END_ANCHOR,
68 DOTS_SLASH,
69 NO_DOT,
70 NO_DOTS,
71 NO_DOT_SLASH,
72 NO_DOTS_SLASH,
73 QMARK_NO_DOT,
74 STAR,
75 START_ANCHOR
76 };
77
78 /**
79 * Windows glob regex
80 */
81
82 const WINDOWS_CHARS = {
83 ...POSIX_CHARS,
84
85 SLASH_LITERAL: `[${WIN_SLASH}]`,
86 QMARK: WIN_NO_SLASH,
87 STAR: `${WIN_NO_SLASH}*?`,
88 DOTS_SLASH: `${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$)`,
89 NO_DOT: `(?!${DOT_LITERAL})`,
90 NO_DOTS: `(?!(?:^|[${WIN_SLASH}])${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$))`,
91 NO_DOT_SLASH: `(?!${DOT_LITERAL}{0,1}(?:[${WIN_SLASH}]|$))`,
92 NO_DOTS_SLASH: `(?!${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$))`,
93 QMARK_NO_DOT: `[^.${WIN_SLASH}]`,
94 START_ANCHOR: `(?:^|[${WIN_SLASH}])`,
95 END_ANCHOR: `(?:[${WIN_SLASH}]|$)`
96 };
97
98 /**
99 * POSIX Bracket Regex
100 */
101
102 const POSIX_REGEX_SOURCE = {
103 alnum: 'a-zA-Z0-9',
104 alpha: 'a-zA-Z',
105 ascii: '\\x00-\\x7F',
106 blank: ' \\t',
107 cntrl: '\\x00-\\x1F\\x7F',
108 digit: '0-9',
109 graph: '\\x21-\\x7E',
110 lower: 'a-z',
111 print: '\\x20-\\x7E ',
112 punct: '\\-!"#$%&\'()\\*+,./:;<=>?@[\\]^_`{|}~',
113 space: ' \\t\\r\\n\\v\\f',
114 upper: 'A-Z',
115 word: 'A-Za-z0-9_',
116 xdigit: 'A-Fa-f0-9'
117 };
118
119 constants$3 = {
120 MAX_LENGTH: 1024 * 64,
121 POSIX_REGEX_SOURCE,
122
123 // regular expressions
124 REGEX_BACKSLASH: /\\(?![*+?^${}(|)[\]])/g,
125 REGEX_NON_SPECIAL_CHARS: /^[^@![\].,$*+?^{}()|\\/]+/,
126 REGEX_SPECIAL_CHARS: /[-*+?.^${}(|)[\]]/,
127 REGEX_SPECIAL_CHARS_BACKREF: /(\\?)((\W)(\3*))/g,
128 REGEX_SPECIAL_CHARS_GLOBAL: /([-*+?.^${}(|)[\]])/g,
129 REGEX_REMOVE_BACKSLASH: /(?:\[.*?[^\\]\]|\\(?=.))/g,
130
131 // Replace globs with equivalent patterns to reduce parsing time.
132 REPLACEMENTS: {
133 '***': '*',
134 '**/**': '**',
135 '**/**/**': '**'
136 },
137
138 // Digits
139 CHAR_0: 48, /* 0 */
140 CHAR_9: 57, /* 9 */
141
142 // Alphabet chars.
143 CHAR_UPPERCASE_A: 65, /* A */
144 CHAR_LOWERCASE_A: 97, /* a */
145 CHAR_UPPERCASE_Z: 90, /* Z */
146 CHAR_LOWERCASE_Z: 122, /* z */
147
148 CHAR_LEFT_PARENTHESES: 40, /* ( */
149 CHAR_RIGHT_PARENTHESES: 41, /* ) */
150
151 CHAR_ASTERISK: 42, /* * */
152
153 // Non-alphabetic chars.
154 CHAR_AMPERSAND: 38, /* & */
155 CHAR_AT: 64, /* @ */
156 CHAR_BACKWARD_SLASH: 92, /* \ */
157 CHAR_CARRIAGE_RETURN: 13, /* \r */
158 CHAR_CIRCUMFLEX_ACCENT: 94, /* ^ */
159 CHAR_COLON: 58, /* : */
160 CHAR_COMMA: 44, /* , */
161 CHAR_DOT: 46, /* . */
162 CHAR_DOUBLE_QUOTE: 34, /* " */
163 CHAR_EQUAL: 61, /* = */
164 CHAR_EXCLAMATION_MARK: 33, /* ! */
165 CHAR_FORM_FEED: 12, /* \f */
166 CHAR_FORWARD_SLASH: 47, /* / */
167 CHAR_GRAVE_ACCENT: 96, /* ` */
168 CHAR_HASH: 35, /* # */
169 CHAR_HYPHEN_MINUS: 45, /* - */
170 CHAR_LEFT_ANGLE_BRACKET: 60, /* < */
171 CHAR_LEFT_CURLY_BRACE: 123, /* { */
172 CHAR_LEFT_SQUARE_BRACKET: 91, /* [ */
173 CHAR_LINE_FEED: 10, /* \n */
174 CHAR_NO_BREAK_SPACE: 160, /* \u00A0 */
175 CHAR_PERCENT: 37, /* % */
176 CHAR_PLUS: 43, /* + */
177 CHAR_QUESTION_MARK: 63, /* ? */
178 CHAR_RIGHT_ANGLE_BRACKET: 62, /* > */
179 CHAR_RIGHT_CURLY_BRACE: 125, /* } */
180 CHAR_RIGHT_SQUARE_BRACKET: 93, /* ] */
181 CHAR_SEMICOLON: 59, /* ; */
182 CHAR_SINGLE_QUOTE: 39, /* ' */
183 CHAR_SPACE: 32, /* */
184 CHAR_TAB: 9, /* \t */
185 CHAR_UNDERSCORE: 95, /* _ */
186 CHAR_VERTICAL_LINE: 124, /* | */
187 CHAR_ZERO_WIDTH_NOBREAK_SPACE: 65279, /* \uFEFF */
188
189 SEP: path.sep,
190
191 /**
192 * Create EXTGLOB_CHARS
193 */
194
195 extglobChars(chars) {
196 return {
197 '!': { type: 'negate', open: '(?:(?!(?:', close: `))${chars.STAR})` },
198 '?': { type: 'qmark', open: '(?:', close: ')?' },
199 '+': { type: 'plus', open: '(?:', close: ')+' },
200 '*': { type: 'star', open: '(?:', close: ')*' },
201 '@': { type: 'at', open: '(?:', close: ')' }
202 };
203 },
204
205 /**
206 * Create GLOB_CHARS
207 */
208
209 globChars(win32) {
210 return win32 === true ? WINDOWS_CHARS : POSIX_CHARS;
211 }
212 };
213 return constants$3;
214}
215
216var hasRequiredUtils$2;
217
218function requireUtils$2 () {
219 if (hasRequiredUtils$2) return utils$2;
220 hasRequiredUtils$2 = 1;
221 (function (exports) {
222
223 const path = require$$0$1;
224 const win32 = process.platform === 'win32';
225 const {
226 REGEX_BACKSLASH,
227 REGEX_REMOVE_BACKSLASH,
228 REGEX_SPECIAL_CHARS,
229 REGEX_SPECIAL_CHARS_GLOBAL
230 } = /*@__PURE__*/ requireConstants$3();
231
232 exports.isObject = val => val !== null && typeof val === 'object' && !Array.isArray(val);
233 exports.hasRegexChars = str => REGEX_SPECIAL_CHARS.test(str);
234 exports.isRegexChar = str => str.length === 1 && exports.hasRegexChars(str);
235 exports.escapeRegex = str => str.replace(REGEX_SPECIAL_CHARS_GLOBAL, '\\$1');
236 exports.toPosixSlashes = str => str.replace(REGEX_BACKSLASH, '/');
237
238 exports.removeBackslashes = str => {
239 return str.replace(REGEX_REMOVE_BACKSLASH, match => {
240 return match === '\\' ? '' : match;
241 });
242 };
243
244 exports.supportsLookbehinds = () => {
245 const segs = process.version.slice(1).split('.').map(Number);
246 if (segs.length === 3 && segs[0] >= 9 || (segs[0] === 8 && segs[1] >= 10)) {
247 return true;
248 }
249 return false;
250 };
251
252 exports.isWindows = options => {
253 if (options && typeof options.windows === 'boolean') {
254 return options.windows;
255 }
256 return win32 === true || path.sep === '\\';
257 };
258
259 exports.escapeLast = (input, char, lastIdx) => {
260 const idx = input.lastIndexOf(char, lastIdx);
261 if (idx === -1) return input;
262 if (input[idx - 1] === '\\') return exports.escapeLast(input, char, idx - 1);
263 return `${input.slice(0, idx)}\\${input.slice(idx)}`;
264 };
265
266 exports.removePrefix = (input, state = {}) => {
267 let output = input;
268 if (output.startsWith('./')) {
269 output = output.slice(2);
270 state.prefix = './';
271 }
272 return output;
273 };
274
275 exports.wrapOutput = (input, state = {}, options = {}) => {
276 const prepend = options.contains ? '' : '^';
277 const append = options.contains ? '' : '$';
278
279 let output = `${prepend}(?:${input})${append}`;
280 if (state.negated === true) {
281 output = `(?:^(?!${output}).*$)`;
282 }
283 return output;
284 };
285 } (utils$2));
286 return utils$2;
287}
288
289var scan_1$1;
290var hasRequiredScan$1;
291
292function requireScan$1 () {
293 if (hasRequiredScan$1) return scan_1$1;
294 hasRequiredScan$1 = 1;
295
296 const utils = /*@__PURE__*/ requireUtils$2();
297 const {
298 CHAR_ASTERISK, /* * */
299 CHAR_AT, /* @ */
300 CHAR_BACKWARD_SLASH, /* \ */
301 CHAR_COMMA, /* , */
302 CHAR_DOT, /* . */
303 CHAR_EXCLAMATION_MARK, /* ! */
304 CHAR_FORWARD_SLASH, /* / */
305 CHAR_LEFT_CURLY_BRACE, /* { */
306 CHAR_LEFT_PARENTHESES, /* ( */
307 CHAR_LEFT_SQUARE_BRACKET, /* [ */
308 CHAR_PLUS, /* + */
309 CHAR_QUESTION_MARK, /* ? */
310 CHAR_RIGHT_CURLY_BRACE, /* } */
311 CHAR_RIGHT_PARENTHESES, /* ) */
312 CHAR_RIGHT_SQUARE_BRACKET /* ] */
313 } = /*@__PURE__*/ requireConstants$3();
314
315 const isPathSeparator = code => {
316 return code === CHAR_FORWARD_SLASH || code === CHAR_BACKWARD_SLASH;
317 };
318
319 const depth = token => {
320 if (token.isPrefix !== true) {
321 token.depth = token.isGlobstar ? Infinity : 1;
322 }
323 };
324
325 /**
326 * Quickly scans a glob pattern and returns an object with a handful of
327 * useful properties, like `isGlob`, `path` (the leading non-glob, if it exists),
328 * `glob` (the actual pattern), `negated` (true if the path starts with `!` but not
329 * with `!(`) and `negatedExtglob` (true if the path starts with `!(`).
330 *
331 * ```js
332 * const pm = require('picomatch');
333 * console.log(pm.scan('foo/bar/*.js'));
334 * { isGlob: true, input: 'foo/bar/*.js', base: 'foo/bar', glob: '*.js' }
335 * ```
336 * @param {String} `str`
337 * @param {Object} `options`
338 * @return {Object} Returns an object with tokens and regex source string.
339 * @api public
340 */
341
342 const scan = (input, options) => {
343 const opts = options || {};
344
345 const length = input.length - 1;
346 const scanToEnd = opts.parts === true || opts.scanToEnd === true;
347 const slashes = [];
348 const tokens = [];
349 const parts = [];
350
351 let str = input;
352 let index = -1;
353 let start = 0;
354 let lastIndex = 0;
355 let isBrace = false;
356 let isBracket = false;
357 let isGlob = false;
358 let isExtglob = false;
359 let isGlobstar = false;
360 let braceEscaped = false;
361 let backslashes = false;
362 let negated = false;
363 let negatedExtglob = false;
364 let finished = false;
365 let braces = 0;
366 let prev;
367 let code;
368 let token = { value: '', depth: 0, isGlob: false };
369
370 const eos = () => index >= length;
371 const peek = () => str.charCodeAt(index + 1);
372 const advance = () => {
373 prev = code;
374 return str.charCodeAt(++index);
375 };
376
377 while (index < length) {
378 code = advance();
379 let next;
380
381 if (code === CHAR_BACKWARD_SLASH) {
382 backslashes = token.backslashes = true;
383 code = advance();
384
385 if (code === CHAR_LEFT_CURLY_BRACE) {
386 braceEscaped = true;
387 }
388 continue;
389 }
390
391 if (braceEscaped === true || code === CHAR_LEFT_CURLY_BRACE) {
392 braces++;
393
394 while (eos() !== true && (code = advance())) {
395 if (code === CHAR_BACKWARD_SLASH) {
396 backslashes = token.backslashes = true;
397 advance();
398 continue;
399 }
400
401 if (code === CHAR_LEFT_CURLY_BRACE) {
402 braces++;
403 continue;
404 }
405
406 if (braceEscaped !== true && code === CHAR_DOT && (code = advance()) === CHAR_DOT) {
407 isBrace = token.isBrace = true;
408 isGlob = token.isGlob = true;
409 finished = true;
410
411 if (scanToEnd === true) {
412 continue;
413 }
414
415 break;
416 }
417
418 if (braceEscaped !== true && code === CHAR_COMMA) {
419 isBrace = token.isBrace = true;
420 isGlob = token.isGlob = true;
421 finished = true;
422
423 if (scanToEnd === true) {
424 continue;
425 }
426
427 break;
428 }
429
430 if (code === CHAR_RIGHT_CURLY_BRACE) {
431 braces--;
432
433 if (braces === 0) {
434 braceEscaped = false;
435 isBrace = token.isBrace = true;
436 finished = true;
437 break;
438 }
439 }
440 }
441
442 if (scanToEnd === true) {
443 continue;
444 }
445
446 break;
447 }
448
449 if (code === CHAR_FORWARD_SLASH) {
450 slashes.push(index);
451 tokens.push(token);
452 token = { value: '', depth: 0, isGlob: false };
453
454 if (finished === true) continue;
455 if (prev === CHAR_DOT && index === (start + 1)) {
456 start += 2;
457 continue;
458 }
459
460 lastIndex = index + 1;
461 continue;
462 }
463
464 if (opts.noext !== true) {
465 const isExtglobChar = code === CHAR_PLUS
466 || code === CHAR_AT
467 || code === CHAR_ASTERISK
468 || code === CHAR_QUESTION_MARK
469 || code === CHAR_EXCLAMATION_MARK;
470
471 if (isExtglobChar === true && peek() === CHAR_LEFT_PARENTHESES) {
472 isGlob = token.isGlob = true;
473 isExtglob = token.isExtglob = true;
474 finished = true;
475 if (code === CHAR_EXCLAMATION_MARK && index === start) {
476 negatedExtglob = true;
477 }
478
479 if (scanToEnd === true) {
480 while (eos() !== true && (code = advance())) {
481 if (code === CHAR_BACKWARD_SLASH) {
482 backslashes = token.backslashes = true;
483 code = advance();
484 continue;
485 }
486
487 if (code === CHAR_RIGHT_PARENTHESES) {
488 isGlob = token.isGlob = true;
489 finished = true;
490 break;
491 }
492 }
493 continue;
494 }
495 break;
496 }
497 }
498
499 if (code === CHAR_ASTERISK) {
500 if (prev === CHAR_ASTERISK) isGlobstar = token.isGlobstar = true;
501 isGlob = token.isGlob = true;
502 finished = true;
503
504 if (scanToEnd === true) {
505 continue;
506 }
507 break;
508 }
509
510 if (code === CHAR_QUESTION_MARK) {
511 isGlob = token.isGlob = true;
512 finished = true;
513
514 if (scanToEnd === true) {
515 continue;
516 }
517 break;
518 }
519
520 if (code === CHAR_LEFT_SQUARE_BRACKET) {
521 while (eos() !== true && (next = advance())) {
522 if (next === CHAR_BACKWARD_SLASH) {
523 backslashes = token.backslashes = true;
524 advance();
525 continue;
526 }
527
528 if (next === CHAR_RIGHT_SQUARE_BRACKET) {
529 isBracket = token.isBracket = true;
530 isGlob = token.isGlob = true;
531 finished = true;
532 break;
533 }
534 }
535
536 if (scanToEnd === true) {
537 continue;
538 }
539
540 break;
541 }
542
543 if (opts.nonegate !== true && code === CHAR_EXCLAMATION_MARK && index === start) {
544 negated = token.negated = true;
545 start++;
546 continue;
547 }
548
549 if (opts.noparen !== true && code === CHAR_LEFT_PARENTHESES) {
550 isGlob = token.isGlob = true;
551
552 if (scanToEnd === true) {
553 while (eos() !== true && (code = advance())) {
554 if (code === CHAR_LEFT_PARENTHESES) {
555 backslashes = token.backslashes = true;
556 code = advance();
557 continue;
558 }
559
560 if (code === CHAR_RIGHT_PARENTHESES) {
561 finished = true;
562 break;
563 }
564 }
565 continue;
566 }
567 break;
568 }
569
570 if (isGlob === true) {
571 finished = true;
572
573 if (scanToEnd === true) {
574 continue;
575 }
576
577 break;
578 }
579 }
580
581 if (opts.noext === true) {
582 isExtglob = false;
583 isGlob = false;
584 }
585
586 let base = str;
587 let prefix = '';
588 let glob = '';
589
590 if (start > 0) {
591 prefix = str.slice(0, start);
592 str = str.slice(start);
593 lastIndex -= start;
594 }
595
596 if (base && isGlob === true && lastIndex > 0) {
597 base = str.slice(0, lastIndex);
598 glob = str.slice(lastIndex);
599 } else if (isGlob === true) {
600 base = '';
601 glob = str;
602 } else {
603 base = str;
604 }
605
606 if (base && base !== '' && base !== '/' && base !== str) {
607 if (isPathSeparator(base.charCodeAt(base.length - 1))) {
608 base = base.slice(0, -1);
609 }
610 }
611
612 if (opts.unescape === true) {
613 if (glob) glob = utils.removeBackslashes(glob);
614
615 if (base && backslashes === true) {
616 base = utils.removeBackslashes(base);
617 }
618 }
619
620 const state = {
621 prefix,
622 input,
623 start,
624 base,
625 glob,
626 isBrace,
627 isBracket,
628 isGlob,
629 isExtglob,
630 isGlobstar,
631 negated,
632 negatedExtglob
633 };
634
635 if (opts.tokens === true) {
636 state.maxDepth = 0;
637 if (!isPathSeparator(code)) {
638 tokens.push(token);
639 }
640 state.tokens = tokens;
641 }
642
643 if (opts.parts === true || opts.tokens === true) {
644 let prevIndex;
645
646 for (let idx = 0; idx < slashes.length; idx++) {
647 const n = prevIndex ? prevIndex + 1 : start;
648 const i = slashes[idx];
649 const value = input.slice(n, i);
650 if (opts.tokens) {
651 if (idx === 0 && start !== 0) {
652 tokens[idx].isPrefix = true;
653 tokens[idx].value = prefix;
654 } else {
655 tokens[idx].value = value;
656 }
657 depth(tokens[idx]);
658 state.maxDepth += tokens[idx].depth;
659 }
660 if (idx !== 0 || value !== '') {
661 parts.push(value);
662 }
663 prevIndex = i;
664 }
665
666 if (prevIndex && prevIndex + 1 < input.length) {
667 const value = input.slice(prevIndex + 1);
668 parts.push(value);
669
670 if (opts.tokens) {
671 tokens[tokens.length - 1].value = value;
672 depth(tokens[tokens.length - 1]);
673 state.maxDepth += tokens[tokens.length - 1].depth;
674 }
675 }
676
677 state.slashes = slashes;
678 state.parts = parts;
679 }
680
681 return state;
682 };
683
684 scan_1$1 = scan;
685 return scan_1$1;
686}
687
688var parse_1$2;
689var hasRequiredParse$2;
690
691function requireParse$2 () {
692 if (hasRequiredParse$2) return parse_1$2;
693 hasRequiredParse$2 = 1;
694
695 const constants = /*@__PURE__*/ requireConstants$3();
696 const utils = /*@__PURE__*/ requireUtils$2();
697
698 /**
699 * Constants
700 */
701
702 const {
703 MAX_LENGTH,
704 POSIX_REGEX_SOURCE,
705 REGEX_NON_SPECIAL_CHARS,
706 REGEX_SPECIAL_CHARS_BACKREF,
707 REPLACEMENTS
708 } = constants;
709
710 /**
711 * Helpers
712 */
713
714 const expandRange = (args, options) => {
715 if (typeof options.expandRange === 'function') {
716 return options.expandRange(...args, options);
717 }
718
719 args.sort();
720 const value = `[${args.join('-')}]`;
721
722 return value;
723 };
724
725 /**
726 * Create the message for a syntax error
727 */
728
729 const syntaxError = (type, char) => {
730 return `Missing ${type}: "${char}" - use "\\\\${char}" to match literal characters`;
731 };
732
733 /**
734 * Parse the given input string.
735 * @param {String} input
736 * @param {Object} options
737 * @return {Object}
738 */
739
740 const parse = (input, options) => {
741 if (typeof input !== 'string') {
742 throw new TypeError('Expected a string');
743 }
744
745 input = REPLACEMENTS[input] || input;
746
747 const opts = { ...options };
748 const max = typeof opts.maxLength === 'number' ? Math.min(MAX_LENGTH, opts.maxLength) : MAX_LENGTH;
749
750 let len = input.length;
751 if (len > max) {
752 throw new SyntaxError(`Input length: ${len}, exceeds maximum allowed length: ${max}`);
753 }
754
755 const bos = { type: 'bos', value: '', output: opts.prepend || '' };
756 const tokens = [bos];
757
758 const capture = opts.capture ? '' : '?:';
759 const win32 = utils.isWindows(options);
760
761 // create constants based on platform, for windows or posix
762 const PLATFORM_CHARS = constants.globChars(win32);
763 const EXTGLOB_CHARS = constants.extglobChars(PLATFORM_CHARS);
764
765 const {
766 DOT_LITERAL,
767 PLUS_LITERAL,
768 SLASH_LITERAL,
769 ONE_CHAR,
770 DOTS_SLASH,
771 NO_DOT,
772 NO_DOT_SLASH,
773 NO_DOTS_SLASH,
774 QMARK,
775 QMARK_NO_DOT,
776 STAR,
777 START_ANCHOR
778 } = PLATFORM_CHARS;
779
780 const globstar = opts => {
781 return `(${capture}(?:(?!${START_ANCHOR}${opts.dot ? DOTS_SLASH : DOT_LITERAL}).)*?)`;
782 };
783
784 const nodot = opts.dot ? '' : NO_DOT;
785 const qmarkNoDot = opts.dot ? QMARK : QMARK_NO_DOT;
786 let star = opts.bash === true ? globstar(opts) : STAR;
787
788 if (opts.capture) {
789 star = `(${star})`;
790 }
791
792 // minimatch options support
793 if (typeof opts.noext === 'boolean') {
794 opts.noextglob = opts.noext;
795 }
796
797 const state = {
798 input,
799 index: -1,
800 start: 0,
801 dot: opts.dot === true,
802 consumed: '',
803 output: '',
804 prefix: '',
805 backtrack: false,
806 negated: false,
807 brackets: 0,
808 braces: 0,
809 parens: 0,
810 quotes: 0,
811 globstar: false,
812 tokens
813 };
814
815 input = utils.removePrefix(input, state);
816 len = input.length;
817
818 const extglobs = [];
819 const braces = [];
820 const stack = [];
821 let prev = bos;
822 let value;
823
824 /**
825 * Tokenizing helpers
826 */
827
828 const eos = () => state.index === len - 1;
829 const peek = state.peek = (n = 1) => input[state.index + n];
830 const advance = state.advance = () => input[++state.index] || '';
831 const remaining = () => input.slice(state.index + 1);
832 const consume = (value = '', num = 0) => {
833 state.consumed += value;
834 state.index += num;
835 };
836
837 const append = token => {
838 state.output += token.output != null ? token.output : token.value;
839 consume(token.value);
840 };
841
842 const negate = () => {
843 let count = 1;
844
845 while (peek() === '!' && (peek(2) !== '(' || peek(3) === '?')) {
846 advance();
847 state.start++;
848 count++;
849 }
850
851 if (count % 2 === 0) {
852 return false;
853 }
854
855 state.negated = true;
856 state.start++;
857 return true;
858 };
859
860 const increment = type => {
861 state[type]++;
862 stack.push(type);
863 };
864
865 const decrement = type => {
866 state[type]--;
867 stack.pop();
868 };
869
870 /**
871 * Push tokens onto the tokens array. This helper speeds up
872 * tokenizing by 1) helping us avoid backtracking as much as possible,
873 * and 2) helping us avoid creating extra tokens when consecutive
874 * characters are plain text. This improves performance and simplifies
875 * lookbehinds.
876 */
877
878 const push = tok => {
879 if (prev.type === 'globstar') {
880 const isBrace = state.braces > 0 && (tok.type === 'comma' || tok.type === 'brace');
881 const isExtglob = tok.extglob === true || (extglobs.length && (tok.type === 'pipe' || tok.type === 'paren'));
882
883 if (tok.type !== 'slash' && tok.type !== 'paren' && !isBrace && !isExtglob) {
884 state.output = state.output.slice(0, -prev.output.length);
885 prev.type = 'star';
886 prev.value = '*';
887 prev.output = star;
888 state.output += prev.output;
889 }
890 }
891
892 if (extglobs.length && tok.type !== 'paren') {
893 extglobs[extglobs.length - 1].inner += tok.value;
894 }
895
896 if (tok.value || tok.output) append(tok);
897 if (prev && prev.type === 'text' && tok.type === 'text') {
898 prev.value += tok.value;
899 prev.output = (prev.output || '') + tok.value;
900 return;
901 }
902
903 tok.prev = prev;
904 tokens.push(tok);
905 prev = tok;
906 };
907
908 const extglobOpen = (type, value) => {
909 const token = { ...EXTGLOB_CHARS[value], conditions: 1, inner: '' };
910
911 token.prev = prev;
912 token.parens = state.parens;
913 token.output = state.output;
914 const output = (opts.capture ? '(' : '') + token.open;
915
916 increment('parens');
917 push({ type, value, output: state.output ? '' : ONE_CHAR });
918 push({ type: 'paren', extglob: true, value: advance(), output });
919 extglobs.push(token);
920 };
921
922 const extglobClose = token => {
923 let output = token.close + (opts.capture ? ')' : '');
924 let rest;
925
926 if (token.type === 'negate') {
927 let extglobStar = star;
928
929 if (token.inner && token.inner.length > 1 && token.inner.includes('/')) {
930 extglobStar = globstar(opts);
931 }
932
933 if (extglobStar !== star || eos() || /^\)+$/.test(remaining())) {
934 output = token.close = `)$))${extglobStar}`;
935 }
936
937 if (token.inner.includes('*') && (rest = remaining()) && /^\.[^\\/.]+$/.test(rest)) {
938 // Any non-magical string (`.ts`) or even nested expression (`.{ts,tsx}`) can follow after the closing parenthesis.
939 // In this case, we need to parse the string and use it in the output of the original pattern.
940 // Suitable patterns: `/!(*.d).ts`, `/!(*.d).{ts,tsx}`, `**/!(*-dbg).@(js)`.
941 //
942 // Disabling the `fastpaths` option due to a problem with parsing strings as `.ts` in the pattern like `**/!(*.d).ts`.
943 const expression = parse(rest, { ...options, fastpaths: false }).output;
944
945 output = token.close = `)${expression})${extglobStar})`;
946 }
947
948 if (token.prev.type === 'bos') {
949 state.negatedExtglob = true;
950 }
951 }
952
953 push({ type: 'paren', extglob: true, value, output });
954 decrement('parens');
955 };
956
957 /**
958 * Fast paths
959 */
960
961 if (opts.fastpaths !== false && !/(^[*!]|[/()[\]{}"])/.test(input)) {
962 let backslashes = false;
963
964 let output = input.replace(REGEX_SPECIAL_CHARS_BACKREF, (m, esc, chars, first, rest, index) => {
965 if (first === '\\') {
966 backslashes = true;
967 return m;
968 }
969
970 if (first === '?') {
971 if (esc) {
972 return esc + first + (rest ? QMARK.repeat(rest.length) : '');
973 }
974 if (index === 0) {
975 return qmarkNoDot + (rest ? QMARK.repeat(rest.length) : '');
976 }
977 return QMARK.repeat(chars.length);
978 }
979
980 if (first === '.') {
981 return DOT_LITERAL.repeat(chars.length);
982 }
983
984 if (first === '*') {
985 if (esc) {
986 return esc + first + (rest ? star : '');
987 }
988 return star;
989 }
990 return esc ? m : `\\${m}`;
991 });
992
993 if (backslashes === true) {
994 if (opts.unescape === true) {
995 output = output.replace(/\\/g, '');
996 } else {
997 output = output.replace(/\\+/g, m => {
998 return m.length % 2 === 0 ? '\\\\' : (m ? '\\' : '');
999 });
1000 }
1001 }
1002
1003 if (output === input && opts.contains === true) {
1004 state.output = input;
1005 return state;
1006 }
1007
1008 state.output = utils.wrapOutput(output, state, options);
1009 return state;
1010 }
1011
1012 /**
1013 * Tokenize input until we reach end-of-string
1014 */
1015
1016 while (!eos()) {
1017 value = advance();
1018
1019 if (value === '\u0000') {
1020 continue;
1021 }
1022
1023 /**
1024 * Escaped characters
1025 */
1026
1027 if (value === '\\') {
1028 const next = peek();
1029
1030 if (next === '/' && opts.bash !== true) {
1031 continue;
1032 }
1033
1034 if (next === '.' || next === ';') {
1035 continue;
1036 }
1037
1038 if (!next) {
1039 value += '\\';
1040 push({ type: 'text', value });
1041 continue;
1042 }
1043
1044 // collapse slashes to reduce potential for exploits
1045 const match = /^\\+/.exec(remaining());
1046 let slashes = 0;
1047
1048 if (match && match[0].length > 2) {
1049 slashes = match[0].length;
1050 state.index += slashes;
1051 if (slashes % 2 !== 0) {
1052 value += '\\';
1053 }
1054 }
1055
1056 if (opts.unescape === true) {
1057 value = advance();
1058 } else {
1059 value += advance();
1060 }
1061
1062 if (state.brackets === 0) {
1063 push({ type: 'text', value });
1064 continue;
1065 }
1066 }
1067
1068 /**
1069 * If we're inside a regex character class, continue
1070 * until we reach the closing bracket.
1071 */
1072
1073 if (state.brackets > 0 && (value !== ']' || prev.value === '[' || prev.value === '[^')) {
1074 if (opts.posix !== false && value === ':') {
1075 const inner = prev.value.slice(1);
1076 if (inner.includes('[')) {
1077 prev.posix = true;
1078
1079 if (inner.includes(':')) {
1080 const idx = prev.value.lastIndexOf('[');
1081 const pre = prev.value.slice(0, idx);
1082 const rest = prev.value.slice(idx + 2);
1083 const posix = POSIX_REGEX_SOURCE[rest];
1084 if (posix) {
1085 prev.value = pre + posix;
1086 state.backtrack = true;
1087 advance();
1088
1089 if (!bos.output && tokens.indexOf(prev) === 1) {
1090 bos.output = ONE_CHAR;
1091 }
1092 continue;
1093 }
1094 }
1095 }
1096 }
1097
1098 if ((value === '[' && peek() !== ':') || (value === '-' && peek() === ']')) {
1099 value = `\\${value}`;
1100 }
1101
1102 if (value === ']' && (prev.value === '[' || prev.value === '[^')) {
1103 value = `\\${value}`;
1104 }
1105
1106 if (opts.posix === true && value === '!' && prev.value === '[') {
1107 value = '^';
1108 }
1109
1110 prev.value += value;
1111 append({ value });
1112 continue;
1113 }
1114
1115 /**
1116 * If we're inside a quoted string, continue
1117 * until we reach the closing double quote.
1118 */
1119
1120 if (state.quotes === 1 && value !== '"') {
1121 value = utils.escapeRegex(value);
1122 prev.value += value;
1123 append({ value });
1124 continue;
1125 }
1126
1127 /**
1128 * Double quotes
1129 */
1130
1131 if (value === '"') {
1132 state.quotes = state.quotes === 1 ? 0 : 1;
1133 if (opts.keepQuotes === true) {
1134 push({ type: 'text', value });
1135 }
1136 continue;
1137 }
1138
1139 /**
1140 * Parentheses
1141 */
1142
1143 if (value === '(') {
1144 increment('parens');
1145 push({ type: 'paren', value });
1146 continue;
1147 }
1148
1149 if (value === ')') {
1150 if (state.parens === 0 && opts.strictBrackets === true) {
1151 throw new SyntaxError(syntaxError('opening', '('));
1152 }
1153
1154 const extglob = extglobs[extglobs.length - 1];
1155 if (extglob && state.parens === extglob.parens + 1) {
1156 extglobClose(extglobs.pop());
1157 continue;
1158 }
1159
1160 push({ type: 'paren', value, output: state.parens ? ')' : '\\)' });
1161 decrement('parens');
1162 continue;
1163 }
1164
1165 /**
1166 * Square brackets
1167 */
1168
1169 if (value === '[') {
1170 if (opts.nobracket === true || !remaining().includes(']')) {
1171 if (opts.nobracket !== true && opts.strictBrackets === true) {
1172 throw new SyntaxError(syntaxError('closing', ']'));
1173 }
1174
1175 value = `\\${value}`;
1176 } else {
1177 increment('brackets');
1178 }
1179
1180 push({ type: 'bracket', value });
1181 continue;
1182 }
1183
1184 if (value === ']') {
1185 if (opts.nobracket === true || (prev && prev.type === 'bracket' && prev.value.length === 1)) {
1186 push({ type: 'text', value, output: `\\${value}` });
1187 continue;
1188 }
1189
1190 if (state.brackets === 0) {
1191 if (opts.strictBrackets === true) {
1192 throw new SyntaxError(syntaxError('opening', '['));
1193 }
1194
1195 push({ type: 'text', value, output: `\\${value}` });
1196 continue;
1197 }
1198
1199 decrement('brackets');
1200
1201 const prevValue = prev.value.slice(1);
1202 if (prev.posix !== true && prevValue[0] === '^' && !prevValue.includes('/')) {
1203 value = `/${value}`;
1204 }
1205
1206 prev.value += value;
1207 append({ value });
1208
1209 // when literal brackets are explicitly disabled
1210 // assume we should match with a regex character class
1211 if (opts.literalBrackets === false || utils.hasRegexChars(prevValue)) {
1212 continue;
1213 }
1214
1215 const escaped = utils.escapeRegex(prev.value);
1216 state.output = state.output.slice(0, -prev.value.length);
1217
1218 // when literal brackets are explicitly enabled
1219 // assume we should escape the brackets to match literal characters
1220 if (opts.literalBrackets === true) {
1221 state.output += escaped;
1222 prev.value = escaped;
1223 continue;
1224 }
1225
1226 // when the user specifies nothing, try to match both
1227 prev.value = `(${capture}${escaped}|${prev.value})`;
1228 state.output += prev.value;
1229 continue;
1230 }
1231
1232 /**
1233 * Braces
1234 */
1235
1236 if (value === '{' && opts.nobrace !== true) {
1237 increment('braces');
1238
1239 const open = {
1240 type: 'brace',
1241 value,
1242 output: '(',
1243 outputIndex: state.output.length,
1244 tokensIndex: state.tokens.length
1245 };
1246
1247 braces.push(open);
1248 push(open);
1249 continue;
1250 }
1251
1252 if (value === '}') {
1253 const brace = braces[braces.length - 1];
1254
1255 if (opts.nobrace === true || !brace) {
1256 push({ type: 'text', value, output: value });
1257 continue;
1258 }
1259
1260 let output = ')';
1261
1262 if (brace.dots === true) {
1263 const arr = tokens.slice();
1264 const range = [];
1265
1266 for (let i = arr.length - 1; i >= 0; i--) {
1267 tokens.pop();
1268 if (arr[i].type === 'brace') {
1269 break;
1270 }
1271 if (arr[i].type !== 'dots') {
1272 range.unshift(arr[i].value);
1273 }
1274 }
1275
1276 output = expandRange(range, opts);
1277 state.backtrack = true;
1278 }
1279
1280 if (brace.comma !== true && brace.dots !== true) {
1281 const out = state.output.slice(0, brace.outputIndex);
1282 const toks = state.tokens.slice(brace.tokensIndex);
1283 brace.value = brace.output = '\\{';
1284 value = output = '\\}';
1285 state.output = out;
1286 for (const t of toks) {
1287 state.output += (t.output || t.value);
1288 }
1289 }
1290
1291 push({ type: 'brace', value, output });
1292 decrement('braces');
1293 braces.pop();
1294 continue;
1295 }
1296
1297 /**
1298 * Pipes
1299 */
1300
1301 if (value === '|') {
1302 if (extglobs.length > 0) {
1303 extglobs[extglobs.length - 1].conditions++;
1304 }
1305 push({ type: 'text', value });
1306 continue;
1307 }
1308
1309 /**
1310 * Commas
1311 */
1312
1313 if (value === ',') {
1314 let output = value;
1315
1316 const brace = braces[braces.length - 1];
1317 if (brace && stack[stack.length - 1] === 'braces') {
1318 brace.comma = true;
1319 output = '|';
1320 }
1321
1322 push({ type: 'comma', value, output });
1323 continue;
1324 }
1325
1326 /**
1327 * Slashes
1328 */
1329
1330 if (value === '/') {
1331 // if the beginning of the glob is "./", advance the start
1332 // to the current index, and don't add the "./" characters
1333 // to the state. This greatly simplifies lookbehinds when
1334 // checking for BOS characters like "!" and "." (not "./")
1335 if (prev.type === 'dot' && state.index === state.start + 1) {
1336 state.start = state.index + 1;
1337 state.consumed = '';
1338 state.output = '';
1339 tokens.pop();
1340 prev = bos; // reset "prev" to the first token
1341 continue;
1342 }
1343
1344 push({ type: 'slash', value, output: SLASH_LITERAL });
1345 continue;
1346 }
1347
1348 /**
1349 * Dots
1350 */
1351
1352 if (value === '.') {
1353 if (state.braces > 0 && prev.type === 'dot') {
1354 if (prev.value === '.') prev.output = DOT_LITERAL;
1355 const brace = braces[braces.length - 1];
1356 prev.type = 'dots';
1357 prev.output += value;
1358 prev.value += value;
1359 brace.dots = true;
1360 continue;
1361 }
1362
1363 if ((state.braces + state.parens) === 0 && prev.type !== 'bos' && prev.type !== 'slash') {
1364 push({ type: 'text', value, output: DOT_LITERAL });
1365 continue;
1366 }
1367
1368 push({ type: 'dot', value, output: DOT_LITERAL });
1369 continue;
1370 }
1371
1372 /**
1373 * Question marks
1374 */
1375
1376 if (value === '?') {
1377 const isGroup = prev && prev.value === '(';
1378 if (!isGroup && opts.noextglob !== true && peek() === '(' && peek(2) !== '?') {
1379 extglobOpen('qmark', value);
1380 continue;
1381 }
1382
1383 if (prev && prev.type === 'paren') {
1384 const next = peek();
1385 let output = value;
1386
1387 if (next === '<' && !utils.supportsLookbehinds()) {
1388 throw new Error('Node.js v10 or higher is required for regex lookbehinds');
1389 }
1390
1391 if ((prev.value === '(' && !/[!=<:]/.test(next)) || (next === '<' && !/<([!=]|\w+>)/.test(remaining()))) {
1392 output = `\\${value}`;
1393 }
1394
1395 push({ type: 'text', value, output });
1396 continue;
1397 }
1398
1399 if (opts.dot !== true && (prev.type === 'slash' || prev.type === 'bos')) {
1400 push({ type: 'qmark', value, output: QMARK_NO_DOT });
1401 continue;
1402 }
1403
1404 push({ type: 'qmark', value, output: QMARK });
1405 continue;
1406 }
1407
1408 /**
1409 * Exclamation
1410 */
1411
1412 if (value === '!') {
1413 if (opts.noextglob !== true && peek() === '(') {
1414 if (peek(2) !== '?' || !/[!=<:]/.test(peek(3))) {
1415 extglobOpen('negate', value);
1416 continue;
1417 }
1418 }
1419
1420 if (opts.nonegate !== true && state.index === 0) {
1421 negate();
1422 continue;
1423 }
1424 }
1425
1426 /**
1427 * Plus
1428 */
1429
1430 if (value === '+') {
1431 if (opts.noextglob !== true && peek() === '(' && peek(2) !== '?') {
1432 extglobOpen('plus', value);
1433 continue;
1434 }
1435
1436 if ((prev && prev.value === '(') || opts.regex === false) {
1437 push({ type: 'plus', value, output: PLUS_LITERAL });
1438 continue;
1439 }
1440
1441 if ((prev && (prev.type === 'bracket' || prev.type === 'paren' || prev.type === 'brace')) || state.parens > 0) {
1442 push({ type: 'plus', value });
1443 continue;
1444 }
1445
1446 push({ type: 'plus', value: PLUS_LITERAL });
1447 continue;
1448 }
1449
1450 /**
1451 * Plain text
1452 */
1453
1454 if (value === '@') {
1455 if (opts.noextglob !== true && peek() === '(' && peek(2) !== '?') {
1456 push({ type: 'at', extglob: true, value, output: '' });
1457 continue;
1458 }
1459
1460 push({ type: 'text', value });
1461 continue;
1462 }
1463
1464 /**
1465 * Plain text
1466 */
1467
1468 if (value !== '*') {
1469 if (value === '$' || value === '^') {
1470 value = `\\${value}`;
1471 }
1472
1473 const match = REGEX_NON_SPECIAL_CHARS.exec(remaining());
1474 if (match) {
1475 value += match[0];
1476 state.index += match[0].length;
1477 }
1478
1479 push({ type: 'text', value });
1480 continue;
1481 }
1482
1483 /**
1484 * Stars
1485 */
1486
1487 if (prev && (prev.type === 'globstar' || prev.star === true)) {
1488 prev.type = 'star';
1489 prev.star = true;
1490 prev.value += value;
1491 prev.output = star;
1492 state.backtrack = true;
1493 state.globstar = true;
1494 consume(value);
1495 continue;
1496 }
1497
1498 let rest = remaining();
1499 if (opts.noextglob !== true && /^\([^?]/.test(rest)) {
1500 extglobOpen('star', value);
1501 continue;
1502 }
1503
1504 if (prev.type === 'star') {
1505 if (opts.noglobstar === true) {
1506 consume(value);
1507 continue;
1508 }
1509
1510 const prior = prev.prev;
1511 const before = prior.prev;
1512 const isStart = prior.type === 'slash' || prior.type === 'bos';
1513 const afterStar = before && (before.type === 'star' || before.type === 'globstar');
1514
1515 if (opts.bash === true && (!isStart || (rest[0] && rest[0] !== '/'))) {
1516 push({ type: 'star', value, output: '' });
1517 continue;
1518 }
1519
1520 const isBrace = state.braces > 0 && (prior.type === 'comma' || prior.type === 'brace');
1521 const isExtglob = extglobs.length && (prior.type === 'pipe' || prior.type === 'paren');
1522 if (!isStart && prior.type !== 'paren' && !isBrace && !isExtglob) {
1523 push({ type: 'star', value, output: '' });
1524 continue;
1525 }
1526
1527 // strip consecutive `/**/`
1528 while (rest.slice(0, 3) === '/**') {
1529 const after = input[state.index + 4];
1530 if (after && after !== '/') {
1531 break;
1532 }
1533 rest = rest.slice(3);
1534 consume('/**', 3);
1535 }
1536
1537 if (prior.type === 'bos' && eos()) {
1538 prev.type = 'globstar';
1539 prev.value += value;
1540 prev.output = globstar(opts);
1541 state.output = prev.output;
1542 state.globstar = true;
1543 consume(value);
1544 continue;
1545 }
1546
1547 if (prior.type === 'slash' && prior.prev.type !== 'bos' && !afterStar && eos()) {
1548 state.output = state.output.slice(0, -(prior.output + prev.output).length);
1549 prior.output = `(?:${prior.output}`;
1550
1551 prev.type = 'globstar';
1552 prev.output = globstar(opts) + (opts.strictSlashes ? ')' : '|$)');
1553 prev.value += value;
1554 state.globstar = true;
1555 state.output += prior.output + prev.output;
1556 consume(value);
1557 continue;
1558 }
1559
1560 if (prior.type === 'slash' && prior.prev.type !== 'bos' && rest[0] === '/') {
1561 const end = rest[1] !== undefined ? '|$' : '';
1562
1563 state.output = state.output.slice(0, -(prior.output + prev.output).length);
1564 prior.output = `(?:${prior.output}`;
1565
1566 prev.type = 'globstar';
1567 prev.output = `${globstar(opts)}${SLASH_LITERAL}|${SLASH_LITERAL}${end})`;
1568 prev.value += value;
1569
1570 state.output += prior.output + prev.output;
1571 state.globstar = true;
1572
1573 consume(value + advance());
1574
1575 push({ type: 'slash', value: '/', output: '' });
1576 continue;
1577 }
1578
1579 if (prior.type === 'bos' && rest[0] === '/') {
1580 prev.type = 'globstar';
1581 prev.value += value;
1582 prev.output = `(?:^|${SLASH_LITERAL}|${globstar(opts)}${SLASH_LITERAL})`;
1583 state.output = prev.output;
1584 state.globstar = true;
1585 consume(value + advance());
1586 push({ type: 'slash', value: '/', output: '' });
1587 continue;
1588 }
1589
1590 // remove single star from output
1591 state.output = state.output.slice(0, -prev.output.length);
1592
1593 // reset previous token to globstar
1594 prev.type = 'globstar';
1595 prev.output = globstar(opts);
1596 prev.value += value;
1597
1598 // reset output with globstar
1599 state.output += prev.output;
1600 state.globstar = true;
1601 consume(value);
1602 continue;
1603 }
1604
1605 const token = { type: 'star', value, output: star };
1606
1607 if (opts.bash === true) {
1608 token.output = '.*?';
1609 if (prev.type === 'bos' || prev.type === 'slash') {
1610 token.output = nodot + token.output;
1611 }
1612 push(token);
1613 continue;
1614 }
1615
1616 if (prev && (prev.type === 'bracket' || prev.type === 'paren') && opts.regex === true) {
1617 token.output = value;
1618 push(token);
1619 continue;
1620 }
1621
1622 if (state.index === state.start || prev.type === 'slash' || prev.type === 'dot') {
1623 if (prev.type === 'dot') {
1624 state.output += NO_DOT_SLASH;
1625 prev.output += NO_DOT_SLASH;
1626
1627 } else if (opts.dot === true) {
1628 state.output += NO_DOTS_SLASH;
1629 prev.output += NO_DOTS_SLASH;
1630
1631 } else {
1632 state.output += nodot;
1633 prev.output += nodot;
1634 }
1635
1636 if (peek() !== '*') {
1637 state.output += ONE_CHAR;
1638 prev.output += ONE_CHAR;
1639 }
1640 }
1641
1642 push(token);
1643 }
1644
1645 while (state.brackets > 0) {
1646 if (opts.strictBrackets === true) throw new SyntaxError(syntaxError('closing', ']'));
1647 state.output = utils.escapeLast(state.output, '[');
1648 decrement('brackets');
1649 }
1650
1651 while (state.parens > 0) {
1652 if (opts.strictBrackets === true) throw new SyntaxError(syntaxError('closing', ')'));
1653 state.output = utils.escapeLast(state.output, '(');
1654 decrement('parens');
1655 }
1656
1657 while (state.braces > 0) {
1658 if (opts.strictBrackets === true) throw new SyntaxError(syntaxError('closing', '}'));
1659 state.output = utils.escapeLast(state.output, '{');
1660 decrement('braces');
1661 }
1662
1663 if (opts.strictSlashes !== true && (prev.type === 'star' || prev.type === 'bracket')) {
1664 push({ type: 'maybe_slash', value: '', output: `${SLASH_LITERAL}?` });
1665 }
1666
1667 // rebuild the output if we had to backtrack at any point
1668 if (state.backtrack === true) {
1669 state.output = '';
1670
1671 for (const token of state.tokens) {
1672 state.output += token.output != null ? token.output : token.value;
1673
1674 if (token.suffix) {
1675 state.output += token.suffix;
1676 }
1677 }
1678 }
1679
1680 return state;
1681 };
1682
1683 /**
1684 * Fast paths for creating regular expressions for common glob patterns.
1685 * This can significantly speed up processing and has very little downside
1686 * impact when none of the fast paths match.
1687 */
1688
1689 parse.fastpaths = (input, options) => {
1690 const opts = { ...options };
1691 const max = typeof opts.maxLength === 'number' ? Math.min(MAX_LENGTH, opts.maxLength) : MAX_LENGTH;
1692 const len = input.length;
1693 if (len > max) {
1694 throw new SyntaxError(`Input length: ${len}, exceeds maximum allowed length: ${max}`);
1695 }
1696
1697 input = REPLACEMENTS[input] || input;
1698 const win32 = utils.isWindows(options);
1699
1700 // create constants based on platform, for windows or posix
1701 const {
1702 DOT_LITERAL,
1703 SLASH_LITERAL,
1704 ONE_CHAR,
1705 DOTS_SLASH,
1706 NO_DOT,
1707 NO_DOTS,
1708 NO_DOTS_SLASH,
1709 STAR,
1710 START_ANCHOR
1711 } = constants.globChars(win32);
1712
1713 const nodot = opts.dot ? NO_DOTS : NO_DOT;
1714 const slashDot = opts.dot ? NO_DOTS_SLASH : NO_DOT;
1715 const capture = opts.capture ? '' : '?:';
1716 const state = { negated: false, prefix: '' };
1717 let star = opts.bash === true ? '.*?' : STAR;
1718
1719 if (opts.capture) {
1720 star = `(${star})`;
1721 }
1722
1723 const globstar = opts => {
1724 if (opts.noglobstar === true) return star;
1725 return `(${capture}(?:(?!${START_ANCHOR}${opts.dot ? DOTS_SLASH : DOT_LITERAL}).)*?)`;
1726 };
1727
1728 const create = str => {
1729 switch (str) {
1730 case '*':
1731 return `${nodot}${ONE_CHAR}${star}`;
1732
1733 case '.*':
1734 return `${DOT_LITERAL}${ONE_CHAR}${star}`;
1735
1736 case '*.*':
1737 return `${nodot}${star}${DOT_LITERAL}${ONE_CHAR}${star}`;
1738
1739 case '*/*':
1740 return `${nodot}${star}${SLASH_LITERAL}${ONE_CHAR}${slashDot}${star}`;
1741
1742 case '**':
1743 return nodot + globstar(opts);
1744
1745 case '**/*':
1746 return `(?:${nodot}${globstar(opts)}${SLASH_LITERAL})?${slashDot}${ONE_CHAR}${star}`;
1747
1748 case '**/*.*':
1749 return `(?:${nodot}${globstar(opts)}${SLASH_LITERAL})?${slashDot}${star}${DOT_LITERAL}${ONE_CHAR}${star}`;
1750
1751 case '**/.*':
1752 return `(?:${nodot}${globstar(opts)}${SLASH_LITERAL})?${DOT_LITERAL}${ONE_CHAR}${star}`;
1753
1754 default: {
1755 const match = /^(.*?)\.(\w+)$/.exec(str);
1756 if (!match) return;
1757
1758 const source = create(match[1]);
1759 if (!source) return;
1760
1761 return source + DOT_LITERAL + match[2];
1762 }
1763 }
1764 };
1765
1766 const output = utils.removePrefix(input, state);
1767 let source = create(output);
1768
1769 if (source && opts.strictSlashes !== true) {
1770 source += `${SLASH_LITERAL}?`;
1771 }
1772
1773 return source;
1774 };
1775
1776 parse_1$2 = parse;
1777 return parse_1$2;
1778}
1779
1780var picomatch_1$1;
1781var hasRequiredPicomatch$3;
1782
1783function requirePicomatch$3 () {
1784 if (hasRequiredPicomatch$3) return picomatch_1$1;
1785 hasRequiredPicomatch$3 = 1;
1786
1787 const path = require$$0$1;
1788 const scan = /*@__PURE__*/ requireScan$1();
1789 const parse = /*@__PURE__*/ requireParse$2();
1790 const utils = /*@__PURE__*/ requireUtils$2();
1791 const constants = /*@__PURE__*/ requireConstants$3();
1792 const isObject = val => val && typeof val === 'object' && !Array.isArray(val);
1793
1794 /**
1795 * Creates a matcher function from one or more glob patterns. The
1796 * returned function takes a string to match as its first argument,
1797 * and returns true if the string is a match. The returned matcher
1798 * function also takes a boolean as the second argument that, when true,
1799 * returns an object with additional information.
1800 *
1801 * ```js
1802 * const picomatch = require('picomatch');
1803 * // picomatch(glob[, options]);
1804 *
1805 * const isMatch = picomatch('*.!(*a)');
1806 * console.log(isMatch('a.a')); //=> false
1807 * console.log(isMatch('a.b')); //=> true
1808 * ```
1809 * @name picomatch
1810 * @param {String|Array} `globs` One or more glob patterns.
1811 * @param {Object=} `options`
1812 * @return {Function=} Returns a matcher function.
1813 * @api public
1814 */
1815
1816 const picomatch = (glob, options, returnState = false) => {
1817 if (Array.isArray(glob)) {
1818 const fns = glob.map(input => picomatch(input, options, returnState));
1819 const arrayMatcher = str => {
1820 for (const isMatch of fns) {
1821 const state = isMatch(str);
1822 if (state) return state;
1823 }
1824 return false;
1825 };
1826 return arrayMatcher;
1827 }
1828
1829 const isState = isObject(glob) && glob.tokens && glob.input;
1830
1831 if (glob === '' || (typeof glob !== 'string' && !isState)) {
1832 throw new TypeError('Expected pattern to be a non-empty string');
1833 }
1834
1835 const opts = options || {};
1836 const posix = utils.isWindows(options);
1837 const regex = isState
1838 ? picomatch.compileRe(glob, options)
1839 : picomatch.makeRe(glob, options, false, true);
1840
1841 const state = regex.state;
1842 delete regex.state;
1843
1844 let isIgnored = () => false;
1845 if (opts.ignore) {
1846 const ignoreOpts = { ...options, ignore: null, onMatch: null, onResult: null };
1847 isIgnored = picomatch(opts.ignore, ignoreOpts, returnState);
1848 }
1849
1850 const matcher = (input, returnObject = false) => {
1851 const { isMatch, match, output } = picomatch.test(input, regex, options, { glob, posix });
1852 const result = { glob, state, regex, posix, input, output, match, isMatch };
1853
1854 if (typeof opts.onResult === 'function') {
1855 opts.onResult(result);
1856 }
1857
1858 if (isMatch === false) {
1859 result.isMatch = false;
1860 return returnObject ? result : false;
1861 }
1862
1863 if (isIgnored(input)) {
1864 if (typeof opts.onIgnore === 'function') {
1865 opts.onIgnore(result);
1866 }
1867 result.isMatch = false;
1868 return returnObject ? result : false;
1869 }
1870
1871 if (typeof opts.onMatch === 'function') {
1872 opts.onMatch(result);
1873 }
1874 return returnObject ? result : true;
1875 };
1876
1877 if (returnState) {
1878 matcher.state = state;
1879 }
1880
1881 return matcher;
1882 };
1883
1884 /**
1885 * Test `input` with the given `regex`. This is used by the main
1886 * `picomatch()` function to test the input string.
1887 *
1888 * ```js
1889 * const picomatch = require('picomatch');
1890 * // picomatch.test(input, regex[, options]);
1891 *
1892 * console.log(picomatch.test('foo/bar', /^(?:([^/]*?)\/([^/]*?))$/));
1893 * // { isMatch: true, match: [ 'foo/', 'foo', 'bar' ], output: 'foo/bar' }
1894 * ```
1895 * @param {String} `input` String to test.
1896 * @param {RegExp} `regex`
1897 * @return {Object} Returns an object with matching info.
1898 * @api public
1899 */
1900
1901 picomatch.test = (input, regex, options, { glob, posix } = {}) => {
1902 if (typeof input !== 'string') {
1903 throw new TypeError('Expected input to be a string');
1904 }
1905
1906 if (input === '') {
1907 return { isMatch: false, output: '' };
1908 }
1909
1910 const opts = options || {};
1911 const format = opts.format || (posix ? utils.toPosixSlashes : null);
1912 let match = input === glob;
1913 let output = (match && format) ? format(input) : input;
1914
1915 if (match === false) {
1916 output = format ? format(input) : input;
1917 match = output === glob;
1918 }
1919
1920 if (match === false || opts.capture === true) {
1921 if (opts.matchBase === true || opts.basename === true) {
1922 match = picomatch.matchBase(input, regex, options, posix);
1923 } else {
1924 match = regex.exec(output);
1925 }
1926 }
1927
1928 return { isMatch: Boolean(match), match, output };
1929 };
1930
1931 /**
1932 * Match the basename of a filepath.
1933 *
1934 * ```js
1935 * const picomatch = require('picomatch');
1936 * // picomatch.matchBase(input, glob[, options]);
1937 * console.log(picomatch.matchBase('foo/bar.js', '*.js'); // true
1938 * ```
1939 * @param {String} `input` String to test.
1940 * @param {RegExp|String} `glob` Glob pattern or regex created by [.makeRe](#makeRe).
1941 * @return {Boolean}
1942 * @api public
1943 */
1944
1945 picomatch.matchBase = (input, glob, options, posix = utils.isWindows(options)) => {
1946 const regex = glob instanceof RegExp ? glob : picomatch.makeRe(glob, options);
1947 return regex.test(path.basename(input));
1948 };
1949
1950 /**
1951 * Returns true if **any** of the given glob `patterns` match the specified `string`.
1952 *
1953 * ```js
1954 * const picomatch = require('picomatch');
1955 * // picomatch.isMatch(string, patterns[, options]);
1956 *
1957 * console.log(picomatch.isMatch('a.a', ['b.*', '*.a'])); //=> true
1958 * console.log(picomatch.isMatch('a.a', 'b.*')); //=> false
1959 * ```
1960 * @param {String|Array} str The string to test.
1961 * @param {String|Array} patterns One or more glob patterns to use for matching.
1962 * @param {Object} [options] See available [options](#options).
1963 * @return {Boolean} Returns true if any patterns match `str`
1964 * @api public
1965 */
1966
1967 picomatch.isMatch = (str, patterns, options) => picomatch(patterns, options)(str);
1968
1969 /**
1970 * Parse a glob pattern to create the source string for a regular
1971 * expression.
1972 *
1973 * ```js
1974 * const picomatch = require('picomatch');
1975 * const result = picomatch.parse(pattern[, options]);
1976 * ```
1977 * @param {String} `pattern`
1978 * @param {Object} `options`
1979 * @return {Object} Returns an object with useful properties and output to be used as a regex source string.
1980 * @api public
1981 */
1982
1983 picomatch.parse = (pattern, options) => {
1984 if (Array.isArray(pattern)) return pattern.map(p => picomatch.parse(p, options));
1985 return parse(pattern, { ...options, fastpaths: false });
1986 };
1987
1988 /**
1989 * Scan a glob pattern to separate the pattern into segments.
1990 *
1991 * ```js
1992 * const picomatch = require('picomatch');
1993 * // picomatch.scan(input[, options]);
1994 *
1995 * const result = picomatch.scan('!./foo/*.js');
1996 * console.log(result);
1997 * { prefix: '!./',
1998 * input: '!./foo/*.js',
1999 * start: 3,
2000 * base: 'foo',
2001 * glob: '*.js',
2002 * isBrace: false,
2003 * isBracket: false,
2004 * isGlob: true,
2005 * isExtglob: false,
2006 * isGlobstar: false,
2007 * negated: true }
2008 * ```
2009 * @param {String} `input` Glob pattern to scan.
2010 * @param {Object} `options`
2011 * @return {Object} Returns an object with
2012 * @api public
2013 */
2014
2015 picomatch.scan = (input, options) => scan(input, options);
2016
2017 /**
2018 * Compile a regular expression from the `state` object returned by the
2019 * [parse()](#parse) method.
2020 *
2021 * @param {Object} `state`
2022 * @param {Object} `options`
2023 * @param {Boolean} `returnOutput` Intended for implementors, this argument allows you to return the raw output from the parser.
2024 * @param {Boolean} `returnState` Adds the state to a `state` property on the returned regex. Useful for implementors and debugging.
2025 * @return {RegExp}
2026 * @api public
2027 */
2028
2029 picomatch.compileRe = (state, options, returnOutput = false, returnState = false) => {
2030 if (returnOutput === true) {
2031 return state.output;
2032 }
2033
2034 const opts = options || {};
2035 const prepend = opts.contains ? '' : '^';
2036 const append = opts.contains ? '' : '$';
2037
2038 let source = `${prepend}(?:${state.output})${append}`;
2039 if (state && state.negated === true) {
2040 source = `^(?!${source}).*$`;
2041 }
2042
2043 const regex = picomatch.toRegex(source, options);
2044 if (returnState === true) {
2045 regex.state = state;
2046 }
2047
2048 return regex;
2049 };
2050
2051 /**
2052 * Create a regular expression from a parsed glob pattern.
2053 *
2054 * ```js
2055 * const picomatch = require('picomatch');
2056 * const state = picomatch.parse('*.js');
2057 * // picomatch.compileRe(state[, options]);
2058 *
2059 * console.log(picomatch.compileRe(state));
2060 * //=> /^(?:(?!\.)(?=.)[^/]*?\.js)$/
2061 * ```
2062 * @param {String} `state` The object returned from the `.parse` method.
2063 * @param {Object} `options`
2064 * @param {Boolean} `returnOutput` 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.
2065 * @param {Boolean} `returnState` Implementors may use this argument to return the state from the parsed glob with the returned regular expression.
2066 * @return {RegExp} Returns a regex created from the given pattern.
2067 * @api public
2068 */
2069
2070 picomatch.makeRe = (input, options = {}, returnOutput = false, returnState = false) => {
2071 if (!input || typeof input !== 'string') {
2072 throw new TypeError('Expected a non-empty string');
2073 }
2074
2075 let parsed = { negated: false, fastpaths: true };
2076
2077 if (options.fastpaths !== false && (input[0] === '.' || input[0] === '*')) {
2078 parsed.output = parse.fastpaths(input, options);
2079 }
2080
2081 if (!parsed.output) {
2082 parsed = parse(input, options);
2083 }
2084
2085 return picomatch.compileRe(parsed, options, returnOutput, returnState);
2086 };
2087
2088 /**
2089 * Create a regular expression from the given regex source string.
2090 *
2091 * ```js
2092 * const picomatch = require('picomatch');
2093 * // picomatch.toRegex(source[, options]);
2094 *
2095 * const { output } = picomatch.parse('*.js');
2096 * console.log(picomatch.toRegex(output));
2097 * //=> /^(?:(?!\.)(?=.)[^/]*?\.js)$/
2098 * ```
2099 * @param {String} `source` Regular expression source string.
2100 * @param {Object} `options`
2101 * @return {RegExp}
2102 * @api public
2103 */
2104
2105 picomatch.toRegex = (source, options) => {
2106 try {
2107 const opts = options || {};
2108 return new RegExp(source, opts.flags || (opts.nocase ? 'i' : ''));
2109 } catch (err) {
2110 if (options && options.debug === true) throw err;
2111 return /$^/;
2112 }
2113 };
2114
2115 /**
2116 * Picomatch constants.
2117 * @return {Object}
2118 */
2119
2120 picomatch.constants = constants;
2121
2122 /**
2123 * Expose "picomatch"
2124 */
2125
2126 picomatch_1$1 = picomatch;
2127 return picomatch_1$1;
2128}
2129
2130var picomatch$1;
2131var hasRequiredPicomatch$2;
2132
2133function requirePicomatch$2 () {
2134 if (hasRequiredPicomatch$2) return picomatch$1;
2135 hasRequiredPicomatch$2 = 1;
2136
2137 picomatch$1 = /*@__PURE__*/ requirePicomatch$3();
2138 return picomatch$1;
2139}
2140
2141var readdirp_1;
2142var hasRequiredReaddirp;
2143
2144function requireReaddirp () {
2145 if (hasRequiredReaddirp) return readdirp_1;
2146 hasRequiredReaddirp = 1;
2147
2148 const fs = require$$0$2;
2149 const { Readable } = require$$1;
2150 const sysPath = require$$0$1;
2151 const { promisify } = require$$2;
2152 const picomatch = /*@__PURE__*/ requirePicomatch$2();
2153
2154 const readdir = promisify(fs.readdir);
2155 const stat = promisify(fs.stat);
2156 const lstat = promisify(fs.lstat);
2157 const realpath = promisify(fs.realpath);
2158
2159 /**
2160 * @typedef {Object} EntryInfo
2161 * @property {String} path
2162 * @property {String} fullPath
2163 * @property {fs.Stats=} stats
2164 * @property {fs.Dirent=} dirent
2165 * @property {String} basename
2166 */
2167
2168 const BANG = '!';
2169 const RECURSIVE_ERROR_CODE = 'READDIRP_RECURSIVE_ERROR';
2170 const NORMAL_FLOW_ERRORS = new Set(['ENOENT', 'EPERM', 'EACCES', 'ELOOP', RECURSIVE_ERROR_CODE]);
2171 const FILE_TYPE = 'files';
2172 const DIR_TYPE = 'directories';
2173 const FILE_DIR_TYPE = 'files_directories';
2174 const EVERYTHING_TYPE = 'all';
2175 const ALL_TYPES = [FILE_TYPE, DIR_TYPE, FILE_DIR_TYPE, EVERYTHING_TYPE];
2176
2177 const isNormalFlowError = error => NORMAL_FLOW_ERRORS.has(error.code);
2178 const [maj, min] = process.versions.node.split('.').slice(0, 2).map(n => Number.parseInt(n, 10));
2179 const wantBigintFsStats = process.platform === 'win32' && (maj > 10 || (maj === 10 && min >= 5));
2180
2181 const normalizeFilter = filter => {
2182 if (filter === undefined) return;
2183 if (typeof filter === 'function') return filter;
2184
2185 if (typeof filter === 'string') {
2186 const glob = picomatch(filter.trim());
2187 return entry => glob(entry.basename);
2188 }
2189
2190 if (Array.isArray(filter)) {
2191 const positive = [];
2192 const negative = [];
2193 for (const item of filter) {
2194 const trimmed = item.trim();
2195 if (trimmed.charAt(0) === BANG) {
2196 negative.push(picomatch(trimmed.slice(1)));
2197 } else {
2198 positive.push(picomatch(trimmed));
2199 }
2200 }
2201
2202 if (negative.length > 0) {
2203 if (positive.length > 0) {
2204 return entry =>
2205 positive.some(f => f(entry.basename)) && !negative.some(f => f(entry.basename));
2206 }
2207 return entry => !negative.some(f => f(entry.basename));
2208 }
2209 return entry => positive.some(f => f(entry.basename));
2210 }
2211 };
2212
2213 class ReaddirpStream extends Readable {
2214 static get defaultOptions() {
2215 return {
2216 root: '.',
2217 /* eslint-disable no-unused-vars */
2218 fileFilter: (path) => true,
2219 directoryFilter: (path) => true,
2220 /* eslint-enable no-unused-vars */
2221 type: FILE_TYPE,
2222 lstat: false,
2223 depth: 2147483648,
2224 alwaysStat: false
2225 };
2226 }
2227
2228 constructor(options = {}) {
2229 super({
2230 objectMode: true,
2231 autoDestroy: true,
2232 highWaterMark: options.highWaterMark || 4096
2233 });
2234 const opts = { ...ReaddirpStream.defaultOptions, ...options };
2235 const { root, type } = opts;
2236
2237 this._fileFilter = normalizeFilter(opts.fileFilter);
2238 this._directoryFilter = normalizeFilter(opts.directoryFilter);
2239
2240 const statMethod = opts.lstat ? lstat : stat;
2241 // Use bigint stats if it's windows and stat() supports options (node 10+).
2242 if (wantBigintFsStats) {
2243 this._stat = path => statMethod(path, { bigint: true });
2244 } else {
2245 this._stat = statMethod;
2246 }
2247
2248 this._maxDepth = opts.depth;
2249 this._wantsDir = [DIR_TYPE, FILE_DIR_TYPE, EVERYTHING_TYPE].includes(type);
2250 this._wantsFile = [FILE_TYPE, FILE_DIR_TYPE, EVERYTHING_TYPE].includes(type);
2251 this._wantsEverything = type === EVERYTHING_TYPE;
2252 this._root = sysPath.resolve(root);
2253 this._isDirent = ('Dirent' in fs) && !opts.alwaysStat;
2254 this._statsProp = this._isDirent ? 'dirent' : 'stats';
2255 this._rdOptions = { encoding: 'utf8', withFileTypes: this._isDirent };
2256
2257 // Launch stream with one parent, the root dir.
2258 this.parents = [this._exploreDir(root, 1)];
2259 this.reading = false;
2260 this.parent = undefined;
2261 }
2262
2263 async _read(batch) {
2264 if (this.reading) return;
2265 this.reading = true;
2266
2267 try {
2268 while (!this.destroyed && batch > 0) {
2269 const { path, depth, files = [] } = this.parent || {};
2270
2271 if (files.length > 0) {
2272 const slice = files.splice(0, batch).map(dirent => this._formatEntry(dirent, path));
2273 for (const entry of await Promise.all(slice)) {
2274 if (this.destroyed) return;
2275
2276 const entryType = await this._getEntryType(entry);
2277 if (entryType === 'directory' && this._directoryFilter(entry)) {
2278 if (depth <= this._maxDepth) {
2279 this.parents.push(this._exploreDir(entry.fullPath, depth + 1));
2280 }
2281
2282 if (this._wantsDir) {
2283 this.push(entry);
2284 batch--;
2285 }
2286 } else if ((entryType === 'file' || this._includeAsFile(entry)) && this._fileFilter(entry)) {
2287 if (this._wantsFile) {
2288 this.push(entry);
2289 batch--;
2290 }
2291 }
2292 }
2293 } else {
2294 const parent = this.parents.pop();
2295 if (!parent) {
2296 this.push(null);
2297 break;
2298 }
2299 this.parent = await parent;
2300 if (this.destroyed) return;
2301 }
2302 }
2303 } catch (error) {
2304 this.destroy(error);
2305 } finally {
2306 this.reading = false;
2307 }
2308 }
2309
2310 async _exploreDir(path, depth) {
2311 let files;
2312 try {
2313 files = await readdir(path, this._rdOptions);
2314 } catch (error) {
2315 this._onError(error);
2316 }
2317 return { files, depth, path };
2318 }
2319
2320 async _formatEntry(dirent, path) {
2321 let entry;
2322 try {
2323 const basename = this._isDirent ? dirent.name : dirent;
2324 const fullPath = sysPath.resolve(sysPath.join(path, basename));
2325 entry = { path: sysPath.relative(this._root, fullPath), fullPath, basename };
2326 entry[this._statsProp] = this._isDirent ? dirent : await this._stat(fullPath);
2327 } catch (err) {
2328 this._onError(err);
2329 }
2330 return entry;
2331 }
2332
2333 _onError(err) {
2334 if (isNormalFlowError(err) && !this.destroyed) {
2335 this.emit('warn', err);
2336 } else {
2337 this.destroy(err);
2338 }
2339 }
2340
2341 async _getEntryType(entry) {
2342 // entry may be undefined, because a warning or an error were emitted
2343 // and the statsProp is undefined
2344 const stats = entry && entry[this._statsProp];
2345 if (!stats) {
2346 return;
2347 }
2348 if (stats.isFile()) {
2349 return 'file';
2350 }
2351 if (stats.isDirectory()) {
2352 return 'directory';
2353 }
2354 if (stats && stats.isSymbolicLink()) {
2355 const full = entry.fullPath;
2356 try {
2357 const entryRealPath = await realpath(full);
2358 const entryRealPathStats = await lstat(entryRealPath);
2359 if (entryRealPathStats.isFile()) {
2360 return 'file';
2361 }
2362 if (entryRealPathStats.isDirectory()) {
2363 const len = entryRealPath.length;
2364 if (full.startsWith(entryRealPath) && full.substr(len, 1) === sysPath.sep) {
2365 const recursiveError = new Error(
2366 `Circular symlink detected: "${full}" points to "${entryRealPath}"`
2367 );
2368 recursiveError.code = RECURSIVE_ERROR_CODE;
2369 return this._onError(recursiveError);
2370 }
2371 return 'directory';
2372 }
2373 } catch (error) {
2374 this._onError(error);
2375 }
2376 }
2377 }
2378
2379 _includeAsFile(entry) {
2380 const stats = entry && entry[this._statsProp];
2381
2382 return stats && this._wantsEverything && !stats.isDirectory();
2383 }
2384 }
2385
2386 /**
2387 * @typedef {Object} ReaddirpArguments
2388 * @property {Function=} fileFilter
2389 * @property {Function=} directoryFilter
2390 * @property {String=} type
2391 * @property {Number=} depth
2392 * @property {String=} root
2393 * @property {Boolean=} lstat
2394 * @property {Boolean=} bigint
2395 */
2396
2397 /**
2398 * Main function which ends up calling readdirRec and reads all files and directories in given root recursively.
2399 * @param {String} root Root directory
2400 * @param {ReaddirpArguments=} options Options to specify root (start directory), filters and recursion depth
2401 */
2402 const readdirp = (root, options = {}) => {
2403 let type = options.entryType || options.type;
2404 if (type === 'both') type = FILE_DIR_TYPE; // backwards-compatibility
2405 if (type) options.type = type;
2406 if (!root) {
2407 throw new Error('readdirp: root argument is required. Usage: readdirp(root, options)');
2408 } else if (typeof root !== 'string') {
2409 throw new TypeError('readdirp: root argument must be a string. Usage: readdirp(root, options)');
2410 } else if (type && !ALL_TYPES.includes(type)) {
2411 throw new Error(`readdirp: Invalid type passed. Use one of ${ALL_TYPES.join(', ')}`);
2412 }
2413
2414 options.root = root;
2415 return new ReaddirpStream(options);
2416 };
2417
2418 const readdirpPromise = (root, options = {}) => {
2419 return new Promise((resolve, reject) => {
2420 const files = [];
2421 readdirp(root, options)
2422 .on('data', entry => files.push(entry))
2423 .on('end', () => resolve(files))
2424 .on('error', error => reject(error));
2425 });
2426 };
2427
2428 readdirp.promise = readdirpPromise;
2429 readdirp.ReaddirpStream = ReaddirpStream;
2430 readdirp.default = readdirp;
2431
2432 readdirp_1 = readdirp;
2433 return readdirp_1;
2434}
2435
2436var anymatch = {exports: {}};
2437
2438var utils$1 = {};
2439
2440var constants$2;
2441var hasRequiredConstants$2;
2442
2443function requireConstants$2 () {
2444 if (hasRequiredConstants$2) return constants$2;
2445 hasRequiredConstants$2 = 1;
2446
2447 const path = require$$0$1;
2448 const WIN_SLASH = '\\\\/';
2449 const WIN_NO_SLASH = `[^${WIN_SLASH}]`;
2450
2451 /**
2452 * Posix glob regex
2453 */
2454
2455 const DOT_LITERAL = '\\.';
2456 const PLUS_LITERAL = '\\+';
2457 const QMARK_LITERAL = '\\?';
2458 const SLASH_LITERAL = '\\/';
2459 const ONE_CHAR = '(?=.)';
2460 const QMARK = '[^/]';
2461 const END_ANCHOR = `(?:${SLASH_LITERAL}|$)`;
2462 const START_ANCHOR = `(?:^|${SLASH_LITERAL})`;
2463 const DOTS_SLASH = `${DOT_LITERAL}{1,2}${END_ANCHOR}`;
2464 const NO_DOT = `(?!${DOT_LITERAL})`;
2465 const NO_DOTS = `(?!${START_ANCHOR}${DOTS_SLASH})`;
2466 const NO_DOT_SLASH = `(?!${DOT_LITERAL}{0,1}${END_ANCHOR})`;
2467 const NO_DOTS_SLASH = `(?!${DOTS_SLASH})`;
2468 const QMARK_NO_DOT = `[^.${SLASH_LITERAL}]`;
2469 const STAR = `${QMARK}*?`;
2470
2471 const POSIX_CHARS = {
2472 DOT_LITERAL,
2473 PLUS_LITERAL,
2474 QMARK_LITERAL,
2475 SLASH_LITERAL,
2476 ONE_CHAR,
2477 QMARK,
2478 END_ANCHOR,
2479 DOTS_SLASH,
2480 NO_DOT,
2481 NO_DOTS,
2482 NO_DOT_SLASH,
2483 NO_DOTS_SLASH,
2484 QMARK_NO_DOT,
2485 STAR,
2486 START_ANCHOR
2487 };
2488
2489 /**
2490 * Windows glob regex
2491 */
2492
2493 const WINDOWS_CHARS = {
2494 ...POSIX_CHARS,
2495
2496 SLASH_LITERAL: `[${WIN_SLASH}]`,
2497 QMARK: WIN_NO_SLASH,
2498 STAR: `${WIN_NO_SLASH}*?`,
2499 DOTS_SLASH: `${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$)`,
2500 NO_DOT: `(?!${DOT_LITERAL})`,
2501 NO_DOTS: `(?!(?:^|[${WIN_SLASH}])${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$))`,
2502 NO_DOT_SLASH: `(?!${DOT_LITERAL}{0,1}(?:[${WIN_SLASH}]|$))`,
2503 NO_DOTS_SLASH: `(?!${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$))`,
2504 QMARK_NO_DOT: `[^.${WIN_SLASH}]`,
2505 START_ANCHOR: `(?:^|[${WIN_SLASH}])`,
2506 END_ANCHOR: `(?:[${WIN_SLASH}]|$)`
2507 };
2508
2509 /**
2510 * POSIX Bracket Regex
2511 */
2512
2513 const POSIX_REGEX_SOURCE = {
2514 alnum: 'a-zA-Z0-9',
2515 alpha: 'a-zA-Z',
2516 ascii: '\\x00-\\x7F',
2517 blank: ' \\t',
2518 cntrl: '\\x00-\\x1F\\x7F',
2519 digit: '0-9',
2520 graph: '\\x21-\\x7E',
2521 lower: 'a-z',
2522 print: '\\x20-\\x7E ',
2523 punct: '\\-!"#$%&\'()\\*+,./:;<=>?@[\\]^_`{|}~',
2524 space: ' \\t\\r\\n\\v\\f',
2525 upper: 'A-Z',
2526 word: 'A-Za-z0-9_',
2527 xdigit: 'A-Fa-f0-9'
2528 };
2529
2530 constants$2 = {
2531 MAX_LENGTH: 1024 * 64,
2532 POSIX_REGEX_SOURCE,
2533
2534 // regular expressions
2535 REGEX_BACKSLASH: /\\(?![*+?^${}(|)[\]])/g,
2536 REGEX_NON_SPECIAL_CHARS: /^[^@![\].,$*+?^{}()|\\/]+/,
2537 REGEX_SPECIAL_CHARS: /[-*+?.^${}(|)[\]]/,
2538 REGEX_SPECIAL_CHARS_BACKREF: /(\\?)((\W)(\3*))/g,
2539 REGEX_SPECIAL_CHARS_GLOBAL: /([-*+?.^${}(|)[\]])/g,
2540 REGEX_REMOVE_BACKSLASH: /(?:\[.*?[^\\]\]|\\(?=.))/g,
2541
2542 // Replace globs with equivalent patterns to reduce parsing time.
2543 REPLACEMENTS: {
2544 '***': '*',
2545 '**/**': '**',
2546 '**/**/**': '**'
2547 },
2548
2549 // Digits
2550 CHAR_0: 48, /* 0 */
2551 CHAR_9: 57, /* 9 */
2552
2553 // Alphabet chars.
2554 CHAR_UPPERCASE_A: 65, /* A */
2555 CHAR_LOWERCASE_A: 97, /* a */
2556 CHAR_UPPERCASE_Z: 90, /* Z */
2557 CHAR_LOWERCASE_Z: 122, /* z */
2558
2559 CHAR_LEFT_PARENTHESES: 40, /* ( */
2560 CHAR_RIGHT_PARENTHESES: 41, /* ) */
2561
2562 CHAR_ASTERISK: 42, /* * */
2563
2564 // Non-alphabetic chars.
2565 CHAR_AMPERSAND: 38, /* & */
2566 CHAR_AT: 64, /* @ */
2567 CHAR_BACKWARD_SLASH: 92, /* \ */
2568 CHAR_CARRIAGE_RETURN: 13, /* \r */
2569 CHAR_CIRCUMFLEX_ACCENT: 94, /* ^ */
2570 CHAR_COLON: 58, /* : */
2571 CHAR_COMMA: 44, /* , */
2572 CHAR_DOT: 46, /* . */
2573 CHAR_DOUBLE_QUOTE: 34, /* " */
2574 CHAR_EQUAL: 61, /* = */
2575 CHAR_EXCLAMATION_MARK: 33, /* ! */
2576 CHAR_FORM_FEED: 12, /* \f */
2577 CHAR_FORWARD_SLASH: 47, /* / */
2578 CHAR_GRAVE_ACCENT: 96, /* ` */
2579 CHAR_HASH: 35, /* # */
2580 CHAR_HYPHEN_MINUS: 45, /* - */
2581 CHAR_LEFT_ANGLE_BRACKET: 60, /* < */
2582 CHAR_LEFT_CURLY_BRACE: 123, /* { */
2583 CHAR_LEFT_SQUARE_BRACKET: 91, /* [ */
2584 CHAR_LINE_FEED: 10, /* \n */
2585 CHAR_NO_BREAK_SPACE: 160, /* \u00A0 */
2586 CHAR_PERCENT: 37, /* % */
2587 CHAR_PLUS: 43, /* + */
2588 CHAR_QUESTION_MARK: 63, /* ? */
2589 CHAR_RIGHT_ANGLE_BRACKET: 62, /* > */
2590 CHAR_RIGHT_CURLY_BRACE: 125, /* } */
2591 CHAR_RIGHT_SQUARE_BRACKET: 93, /* ] */
2592 CHAR_SEMICOLON: 59, /* ; */
2593 CHAR_SINGLE_QUOTE: 39, /* ' */
2594 CHAR_SPACE: 32, /* */
2595 CHAR_TAB: 9, /* \t */
2596 CHAR_UNDERSCORE: 95, /* _ */
2597 CHAR_VERTICAL_LINE: 124, /* | */
2598 CHAR_ZERO_WIDTH_NOBREAK_SPACE: 65279, /* \uFEFF */
2599
2600 SEP: path.sep,
2601
2602 /**
2603 * Create EXTGLOB_CHARS
2604 */
2605
2606 extglobChars(chars) {
2607 return {
2608 '!': { type: 'negate', open: '(?:(?!(?:', close: `))${chars.STAR})` },
2609 '?': { type: 'qmark', open: '(?:', close: ')?' },
2610 '+': { type: 'plus', open: '(?:', close: ')+' },
2611 '*': { type: 'star', open: '(?:', close: ')*' },
2612 '@': { type: 'at', open: '(?:', close: ')' }
2613 };
2614 },
2615
2616 /**
2617 * Create GLOB_CHARS
2618 */
2619
2620 globChars(win32) {
2621 return win32 === true ? WINDOWS_CHARS : POSIX_CHARS;
2622 }
2623 };
2624 return constants$2;
2625}
2626
2627var hasRequiredUtils$1;
2628
2629function requireUtils$1 () {
2630 if (hasRequiredUtils$1) return utils$1;
2631 hasRequiredUtils$1 = 1;
2632 (function (exports) {
2633
2634 const path = require$$0$1;
2635 const win32 = process.platform === 'win32';
2636 const {
2637 REGEX_BACKSLASH,
2638 REGEX_REMOVE_BACKSLASH,
2639 REGEX_SPECIAL_CHARS,
2640 REGEX_SPECIAL_CHARS_GLOBAL
2641 } = /*@__PURE__*/ requireConstants$2();
2642
2643 exports.isObject = val => val !== null && typeof val === 'object' && !Array.isArray(val);
2644 exports.hasRegexChars = str => REGEX_SPECIAL_CHARS.test(str);
2645 exports.isRegexChar = str => str.length === 1 && exports.hasRegexChars(str);
2646 exports.escapeRegex = str => str.replace(REGEX_SPECIAL_CHARS_GLOBAL, '\\$1');
2647 exports.toPosixSlashes = str => str.replace(REGEX_BACKSLASH, '/');
2648
2649 exports.removeBackslashes = str => {
2650 return str.replace(REGEX_REMOVE_BACKSLASH, match => {
2651 return match === '\\' ? '' : match;
2652 });
2653 };
2654
2655 exports.supportsLookbehinds = () => {
2656 const segs = process.version.slice(1).split('.').map(Number);
2657 if (segs.length === 3 && segs[0] >= 9 || (segs[0] === 8 && segs[1] >= 10)) {
2658 return true;
2659 }
2660 return false;
2661 };
2662
2663 exports.isWindows = options => {
2664 if (options && typeof options.windows === 'boolean') {
2665 return options.windows;
2666 }
2667 return win32 === true || path.sep === '\\';
2668 };
2669
2670 exports.escapeLast = (input, char, lastIdx) => {
2671 const idx = input.lastIndexOf(char, lastIdx);
2672 if (idx === -1) return input;
2673 if (input[idx - 1] === '\\') return exports.escapeLast(input, char, idx - 1);
2674 return `${input.slice(0, idx)}\\${input.slice(idx)}`;
2675 };
2676
2677 exports.removePrefix = (input, state = {}) => {
2678 let output = input;
2679 if (output.startsWith('./')) {
2680 output = output.slice(2);
2681 state.prefix = './';
2682 }
2683 return output;
2684 };
2685
2686 exports.wrapOutput = (input, state = {}, options = {}) => {
2687 const prepend = options.contains ? '' : '^';
2688 const append = options.contains ? '' : '$';
2689
2690 let output = `${prepend}(?:${input})${append}`;
2691 if (state.negated === true) {
2692 output = `(?:^(?!${output}).*$)`;
2693 }
2694 return output;
2695 };
2696 } (utils$1));
2697 return utils$1;
2698}
2699
2700var scan_1;
2701var hasRequiredScan;
2702
2703function requireScan () {
2704 if (hasRequiredScan) return scan_1;
2705 hasRequiredScan = 1;
2706
2707 const utils = /*@__PURE__*/ requireUtils$1();
2708 const {
2709 CHAR_ASTERISK, /* * */
2710 CHAR_AT, /* @ */
2711 CHAR_BACKWARD_SLASH, /* \ */
2712 CHAR_COMMA, /* , */
2713 CHAR_DOT, /* . */
2714 CHAR_EXCLAMATION_MARK, /* ! */
2715 CHAR_FORWARD_SLASH, /* / */
2716 CHAR_LEFT_CURLY_BRACE, /* { */
2717 CHAR_LEFT_PARENTHESES, /* ( */
2718 CHAR_LEFT_SQUARE_BRACKET, /* [ */
2719 CHAR_PLUS, /* + */
2720 CHAR_QUESTION_MARK, /* ? */
2721 CHAR_RIGHT_CURLY_BRACE, /* } */
2722 CHAR_RIGHT_PARENTHESES, /* ) */
2723 CHAR_RIGHT_SQUARE_BRACKET /* ] */
2724 } = /*@__PURE__*/ requireConstants$2();
2725
2726 const isPathSeparator = code => {
2727 return code === CHAR_FORWARD_SLASH || code === CHAR_BACKWARD_SLASH;
2728 };
2729
2730 const depth = token => {
2731 if (token.isPrefix !== true) {
2732 token.depth = token.isGlobstar ? Infinity : 1;
2733 }
2734 };
2735
2736 /**
2737 * Quickly scans a glob pattern and returns an object with a handful of
2738 * useful properties, like `isGlob`, `path` (the leading non-glob, if it exists),
2739 * `glob` (the actual pattern), `negated` (true if the path starts with `!` but not
2740 * with `!(`) and `negatedExtglob` (true if the path starts with `!(`).
2741 *
2742 * ```js
2743 * const pm = require('picomatch');
2744 * console.log(pm.scan('foo/bar/*.js'));
2745 * { isGlob: true, input: 'foo/bar/*.js', base: 'foo/bar', glob: '*.js' }
2746 * ```
2747 * @param {String} `str`
2748 * @param {Object} `options`
2749 * @return {Object} Returns an object with tokens and regex source string.
2750 * @api public
2751 */
2752
2753 const scan = (input, options) => {
2754 const opts = options || {};
2755
2756 const length = input.length - 1;
2757 const scanToEnd = opts.parts === true || opts.scanToEnd === true;
2758 const slashes = [];
2759 const tokens = [];
2760 const parts = [];
2761
2762 let str = input;
2763 let index = -1;
2764 let start = 0;
2765 let lastIndex = 0;
2766 let isBrace = false;
2767 let isBracket = false;
2768 let isGlob = false;
2769 let isExtglob = false;
2770 let isGlobstar = false;
2771 let braceEscaped = false;
2772 let backslashes = false;
2773 let negated = false;
2774 let negatedExtglob = false;
2775 let finished = false;
2776 let braces = 0;
2777 let prev;
2778 let code;
2779 let token = { value: '', depth: 0, isGlob: false };
2780
2781 const eos = () => index >= length;
2782 const peek = () => str.charCodeAt(index + 1);
2783 const advance = () => {
2784 prev = code;
2785 return str.charCodeAt(++index);
2786 };
2787
2788 while (index < length) {
2789 code = advance();
2790 let next;
2791
2792 if (code === CHAR_BACKWARD_SLASH) {
2793 backslashes = token.backslashes = true;
2794 code = advance();
2795
2796 if (code === CHAR_LEFT_CURLY_BRACE) {
2797 braceEscaped = true;
2798 }
2799 continue;
2800 }
2801
2802 if (braceEscaped === true || code === CHAR_LEFT_CURLY_BRACE) {
2803 braces++;
2804
2805 while (eos() !== true && (code = advance())) {
2806 if (code === CHAR_BACKWARD_SLASH) {
2807 backslashes = token.backslashes = true;
2808 advance();
2809 continue;
2810 }
2811
2812 if (code === CHAR_LEFT_CURLY_BRACE) {
2813 braces++;
2814 continue;
2815 }
2816
2817 if (braceEscaped !== true && code === CHAR_DOT && (code = advance()) === CHAR_DOT) {
2818 isBrace = token.isBrace = true;
2819 isGlob = token.isGlob = true;
2820 finished = true;
2821
2822 if (scanToEnd === true) {
2823 continue;
2824 }
2825
2826 break;
2827 }
2828
2829 if (braceEscaped !== true && code === CHAR_COMMA) {
2830 isBrace = token.isBrace = true;
2831 isGlob = token.isGlob = true;
2832 finished = true;
2833
2834 if (scanToEnd === true) {
2835 continue;
2836 }
2837
2838 break;
2839 }
2840
2841 if (code === CHAR_RIGHT_CURLY_BRACE) {
2842 braces--;
2843
2844 if (braces === 0) {
2845 braceEscaped = false;
2846 isBrace = token.isBrace = true;
2847 finished = true;
2848 break;
2849 }
2850 }
2851 }
2852
2853 if (scanToEnd === true) {
2854 continue;
2855 }
2856
2857 break;
2858 }
2859
2860 if (code === CHAR_FORWARD_SLASH) {
2861 slashes.push(index);
2862 tokens.push(token);
2863 token = { value: '', depth: 0, isGlob: false };
2864
2865 if (finished === true) continue;
2866 if (prev === CHAR_DOT && index === (start + 1)) {
2867 start += 2;
2868 continue;
2869 }
2870
2871 lastIndex = index + 1;
2872 continue;
2873 }
2874
2875 if (opts.noext !== true) {
2876 const isExtglobChar = code === CHAR_PLUS
2877 || code === CHAR_AT
2878 || code === CHAR_ASTERISK
2879 || code === CHAR_QUESTION_MARK
2880 || code === CHAR_EXCLAMATION_MARK;
2881
2882 if (isExtglobChar === true && peek() === CHAR_LEFT_PARENTHESES) {
2883 isGlob = token.isGlob = true;
2884 isExtglob = token.isExtglob = true;
2885 finished = true;
2886 if (code === CHAR_EXCLAMATION_MARK && index === start) {
2887 negatedExtglob = true;
2888 }
2889
2890 if (scanToEnd === true) {
2891 while (eos() !== true && (code = advance())) {
2892 if (code === CHAR_BACKWARD_SLASH) {
2893 backslashes = token.backslashes = true;
2894 code = advance();
2895 continue;
2896 }
2897
2898 if (code === CHAR_RIGHT_PARENTHESES) {
2899 isGlob = token.isGlob = true;
2900 finished = true;
2901 break;
2902 }
2903 }
2904 continue;
2905 }
2906 break;
2907 }
2908 }
2909
2910 if (code === CHAR_ASTERISK) {
2911 if (prev === CHAR_ASTERISK) isGlobstar = token.isGlobstar = true;
2912 isGlob = token.isGlob = true;
2913 finished = true;
2914
2915 if (scanToEnd === true) {
2916 continue;
2917 }
2918 break;
2919 }
2920
2921 if (code === CHAR_QUESTION_MARK) {
2922 isGlob = token.isGlob = true;
2923 finished = true;
2924
2925 if (scanToEnd === true) {
2926 continue;
2927 }
2928 break;
2929 }
2930
2931 if (code === CHAR_LEFT_SQUARE_BRACKET) {
2932 while (eos() !== true && (next = advance())) {
2933 if (next === CHAR_BACKWARD_SLASH) {
2934 backslashes = token.backslashes = true;
2935 advance();
2936 continue;
2937 }
2938
2939 if (next === CHAR_RIGHT_SQUARE_BRACKET) {
2940 isBracket = token.isBracket = true;
2941 isGlob = token.isGlob = true;
2942 finished = true;
2943 break;
2944 }
2945 }
2946
2947 if (scanToEnd === true) {
2948 continue;
2949 }
2950
2951 break;
2952 }
2953
2954 if (opts.nonegate !== true && code === CHAR_EXCLAMATION_MARK && index === start) {
2955 negated = token.negated = true;
2956 start++;
2957 continue;
2958 }
2959
2960 if (opts.noparen !== true && code === CHAR_LEFT_PARENTHESES) {
2961 isGlob = token.isGlob = true;
2962
2963 if (scanToEnd === true) {
2964 while (eos() !== true && (code = advance())) {
2965 if (code === CHAR_LEFT_PARENTHESES) {
2966 backslashes = token.backslashes = true;
2967 code = advance();
2968 continue;
2969 }
2970
2971 if (code === CHAR_RIGHT_PARENTHESES) {
2972 finished = true;
2973 break;
2974 }
2975 }
2976 continue;
2977 }
2978 break;
2979 }
2980
2981 if (isGlob === true) {
2982 finished = true;
2983
2984 if (scanToEnd === true) {
2985 continue;
2986 }
2987
2988 break;
2989 }
2990 }
2991
2992 if (opts.noext === true) {
2993 isExtglob = false;
2994 isGlob = false;
2995 }
2996
2997 let base = str;
2998 let prefix = '';
2999 let glob = '';
3000
3001 if (start > 0) {
3002 prefix = str.slice(0, start);
3003 str = str.slice(start);
3004 lastIndex -= start;
3005 }
3006
3007 if (base && isGlob === true && lastIndex > 0) {
3008 base = str.slice(0, lastIndex);
3009 glob = str.slice(lastIndex);
3010 } else if (isGlob === true) {
3011 base = '';
3012 glob = str;
3013 } else {
3014 base = str;
3015 }
3016
3017 if (base && base !== '' && base !== '/' && base !== str) {
3018 if (isPathSeparator(base.charCodeAt(base.length - 1))) {
3019 base = base.slice(0, -1);
3020 }
3021 }
3022
3023 if (opts.unescape === true) {
3024 if (glob) glob = utils.removeBackslashes(glob);
3025
3026 if (base && backslashes === true) {
3027 base = utils.removeBackslashes(base);
3028 }
3029 }
3030
3031 const state = {
3032 prefix,
3033 input,
3034 start,
3035 base,
3036 glob,
3037 isBrace,
3038 isBracket,
3039 isGlob,
3040 isExtglob,
3041 isGlobstar,
3042 negated,
3043 negatedExtglob
3044 };
3045
3046 if (opts.tokens === true) {
3047 state.maxDepth = 0;
3048 if (!isPathSeparator(code)) {
3049 tokens.push(token);
3050 }
3051 state.tokens = tokens;
3052 }
3053
3054 if (opts.parts === true || opts.tokens === true) {
3055 let prevIndex;
3056
3057 for (let idx = 0; idx < slashes.length; idx++) {
3058 const n = prevIndex ? prevIndex + 1 : start;
3059 const i = slashes[idx];
3060 const value = input.slice(n, i);
3061 if (opts.tokens) {
3062 if (idx === 0 && start !== 0) {
3063 tokens[idx].isPrefix = true;
3064 tokens[idx].value = prefix;
3065 } else {
3066 tokens[idx].value = value;
3067 }
3068 depth(tokens[idx]);
3069 state.maxDepth += tokens[idx].depth;
3070 }
3071 if (idx !== 0 || value !== '') {
3072 parts.push(value);
3073 }
3074 prevIndex = i;
3075 }
3076
3077 if (prevIndex && prevIndex + 1 < input.length) {
3078 const value = input.slice(prevIndex + 1);
3079 parts.push(value);
3080
3081 if (opts.tokens) {
3082 tokens[tokens.length - 1].value = value;
3083 depth(tokens[tokens.length - 1]);
3084 state.maxDepth += tokens[tokens.length - 1].depth;
3085 }
3086 }
3087
3088 state.slashes = slashes;
3089 state.parts = parts;
3090 }
3091
3092 return state;
3093 };
3094
3095 scan_1 = scan;
3096 return scan_1;
3097}
3098
3099var parse_1$1;
3100var hasRequiredParse$1;
3101
3102function requireParse$1 () {
3103 if (hasRequiredParse$1) return parse_1$1;
3104 hasRequiredParse$1 = 1;
3105
3106 const constants = /*@__PURE__*/ requireConstants$2();
3107 const utils = /*@__PURE__*/ requireUtils$1();
3108
3109 /**
3110 * Constants
3111 */
3112
3113 const {
3114 MAX_LENGTH,
3115 POSIX_REGEX_SOURCE,
3116 REGEX_NON_SPECIAL_CHARS,
3117 REGEX_SPECIAL_CHARS_BACKREF,
3118 REPLACEMENTS
3119 } = constants;
3120
3121 /**
3122 * Helpers
3123 */
3124
3125 const expandRange = (args, options) => {
3126 if (typeof options.expandRange === 'function') {
3127 return options.expandRange(...args, options);
3128 }
3129
3130 args.sort();
3131 const value = `[${args.join('-')}]`;
3132
3133 return value;
3134 };
3135
3136 /**
3137 * Create the message for a syntax error
3138 */
3139
3140 const syntaxError = (type, char) => {
3141 return `Missing ${type}: "${char}" - use "\\\\${char}" to match literal characters`;
3142 };
3143
3144 /**
3145 * Parse the given input string.
3146 * @param {String} input
3147 * @param {Object} options
3148 * @return {Object}
3149 */
3150
3151 const parse = (input, options) => {
3152 if (typeof input !== 'string') {
3153 throw new TypeError('Expected a string');
3154 }
3155
3156 input = REPLACEMENTS[input] || input;
3157
3158 const opts = { ...options };
3159 const max = typeof opts.maxLength === 'number' ? Math.min(MAX_LENGTH, opts.maxLength) : MAX_LENGTH;
3160
3161 let len = input.length;
3162 if (len > max) {
3163 throw new SyntaxError(`Input length: ${len}, exceeds maximum allowed length: ${max}`);
3164 }
3165
3166 const bos = { type: 'bos', value: '', output: opts.prepend || '' };
3167 const tokens = [bos];
3168
3169 const capture = opts.capture ? '' : '?:';
3170 const win32 = utils.isWindows(options);
3171
3172 // create constants based on platform, for windows or posix
3173 const PLATFORM_CHARS = constants.globChars(win32);
3174 const EXTGLOB_CHARS = constants.extglobChars(PLATFORM_CHARS);
3175
3176 const {
3177 DOT_LITERAL,
3178 PLUS_LITERAL,
3179 SLASH_LITERAL,
3180 ONE_CHAR,
3181 DOTS_SLASH,
3182 NO_DOT,
3183 NO_DOT_SLASH,
3184 NO_DOTS_SLASH,
3185 QMARK,
3186 QMARK_NO_DOT,
3187 STAR,
3188 START_ANCHOR
3189 } = PLATFORM_CHARS;
3190
3191 const globstar = opts => {
3192 return `(${capture}(?:(?!${START_ANCHOR}${opts.dot ? DOTS_SLASH : DOT_LITERAL}).)*?)`;
3193 };
3194
3195 const nodot = opts.dot ? '' : NO_DOT;
3196 const qmarkNoDot = opts.dot ? QMARK : QMARK_NO_DOT;
3197 let star = opts.bash === true ? globstar(opts) : STAR;
3198
3199 if (opts.capture) {
3200 star = `(${star})`;
3201 }
3202
3203 // minimatch options support
3204 if (typeof opts.noext === 'boolean') {
3205 opts.noextglob = opts.noext;
3206 }
3207
3208 const state = {
3209 input,
3210 index: -1,
3211 start: 0,
3212 dot: opts.dot === true,
3213 consumed: '',
3214 output: '',
3215 prefix: '',
3216 backtrack: false,
3217 negated: false,
3218 brackets: 0,
3219 braces: 0,
3220 parens: 0,
3221 quotes: 0,
3222 globstar: false,
3223 tokens
3224 };
3225
3226 input = utils.removePrefix(input, state);
3227 len = input.length;
3228
3229 const extglobs = [];
3230 const braces = [];
3231 const stack = [];
3232 let prev = bos;
3233 let value;
3234
3235 /**
3236 * Tokenizing helpers
3237 */
3238
3239 const eos = () => state.index === len - 1;
3240 const peek = state.peek = (n = 1) => input[state.index + n];
3241 const advance = state.advance = () => input[++state.index] || '';
3242 const remaining = () => input.slice(state.index + 1);
3243 const consume = (value = '', num = 0) => {
3244 state.consumed += value;
3245 state.index += num;
3246 };
3247
3248 const append = token => {
3249 state.output += token.output != null ? token.output : token.value;
3250 consume(token.value);
3251 };
3252
3253 const negate = () => {
3254 let count = 1;
3255
3256 while (peek() === '!' && (peek(2) !== '(' || peek(3) === '?')) {
3257 advance();
3258 state.start++;
3259 count++;
3260 }
3261
3262 if (count % 2 === 0) {
3263 return false;
3264 }
3265
3266 state.negated = true;
3267 state.start++;
3268 return true;
3269 };
3270
3271 const increment = type => {
3272 state[type]++;
3273 stack.push(type);
3274 };
3275
3276 const decrement = type => {
3277 state[type]--;
3278 stack.pop();
3279 };
3280
3281 /**
3282 * Push tokens onto the tokens array. This helper speeds up
3283 * tokenizing by 1) helping us avoid backtracking as much as possible,
3284 * and 2) helping us avoid creating extra tokens when consecutive
3285 * characters are plain text. This improves performance and simplifies
3286 * lookbehinds.
3287 */
3288
3289 const push = tok => {
3290 if (prev.type === 'globstar') {
3291 const isBrace = state.braces > 0 && (tok.type === 'comma' || tok.type === 'brace');
3292 const isExtglob = tok.extglob === true || (extglobs.length && (tok.type === 'pipe' || tok.type === 'paren'));
3293
3294 if (tok.type !== 'slash' && tok.type !== 'paren' && !isBrace && !isExtglob) {
3295 state.output = state.output.slice(0, -prev.output.length);
3296 prev.type = 'star';
3297 prev.value = '*';
3298 prev.output = star;
3299 state.output += prev.output;
3300 }
3301 }
3302
3303 if (extglobs.length && tok.type !== 'paren') {
3304 extglobs[extglobs.length - 1].inner += tok.value;
3305 }
3306
3307 if (tok.value || tok.output) append(tok);
3308 if (prev && prev.type === 'text' && tok.type === 'text') {
3309 prev.value += tok.value;
3310 prev.output = (prev.output || '') + tok.value;
3311 return;
3312 }
3313
3314 tok.prev = prev;
3315 tokens.push(tok);
3316 prev = tok;
3317 };
3318
3319 const extglobOpen = (type, value) => {
3320 const token = { ...EXTGLOB_CHARS[value], conditions: 1, inner: '' };
3321
3322 token.prev = prev;
3323 token.parens = state.parens;
3324 token.output = state.output;
3325 const output = (opts.capture ? '(' : '') + token.open;
3326
3327 increment('parens');
3328 push({ type, value, output: state.output ? '' : ONE_CHAR });
3329 push({ type: 'paren', extglob: true, value: advance(), output });
3330 extglobs.push(token);
3331 };
3332
3333 const extglobClose = token => {
3334 let output = token.close + (opts.capture ? ')' : '');
3335 let rest;
3336
3337 if (token.type === 'negate') {
3338 let extglobStar = star;
3339
3340 if (token.inner && token.inner.length > 1 && token.inner.includes('/')) {
3341 extglobStar = globstar(opts);
3342 }
3343
3344 if (extglobStar !== star || eos() || /^\)+$/.test(remaining())) {
3345 output = token.close = `)$))${extglobStar}`;
3346 }
3347
3348 if (token.inner.includes('*') && (rest = remaining()) && /^\.[^\\/.]+$/.test(rest)) {
3349 // Any non-magical string (`.ts`) or even nested expression (`.{ts,tsx}`) can follow after the closing parenthesis.
3350 // In this case, we need to parse the string and use it in the output of the original pattern.
3351 // Suitable patterns: `/!(*.d).ts`, `/!(*.d).{ts,tsx}`, `**/!(*-dbg).@(js)`.
3352 //
3353 // Disabling the `fastpaths` option due to a problem with parsing strings as `.ts` in the pattern like `**/!(*.d).ts`.
3354 const expression = parse(rest, { ...options, fastpaths: false }).output;
3355
3356 output = token.close = `)${expression})${extglobStar})`;
3357 }
3358
3359 if (token.prev.type === 'bos') {
3360 state.negatedExtglob = true;
3361 }
3362 }
3363
3364 push({ type: 'paren', extglob: true, value, output });
3365 decrement('parens');
3366 };
3367
3368 /**
3369 * Fast paths
3370 */
3371
3372 if (opts.fastpaths !== false && !/(^[*!]|[/()[\]{}"])/.test(input)) {
3373 let backslashes = false;
3374
3375 let output = input.replace(REGEX_SPECIAL_CHARS_BACKREF, (m, esc, chars, first, rest, index) => {
3376 if (first === '\\') {
3377 backslashes = true;
3378 return m;
3379 }
3380
3381 if (first === '?') {
3382 if (esc) {
3383 return esc + first + (rest ? QMARK.repeat(rest.length) : '');
3384 }
3385 if (index === 0) {
3386 return qmarkNoDot + (rest ? QMARK.repeat(rest.length) : '');
3387 }
3388 return QMARK.repeat(chars.length);
3389 }
3390
3391 if (first === '.') {
3392 return DOT_LITERAL.repeat(chars.length);
3393 }
3394
3395 if (first === '*') {
3396 if (esc) {
3397 return esc + first + (rest ? star : '');
3398 }
3399 return star;
3400 }
3401 return esc ? m : `\\${m}`;
3402 });
3403
3404 if (backslashes === true) {
3405 if (opts.unescape === true) {
3406 output = output.replace(/\\/g, '');
3407 } else {
3408 output = output.replace(/\\+/g, m => {
3409 return m.length % 2 === 0 ? '\\\\' : (m ? '\\' : '');
3410 });
3411 }
3412 }
3413
3414 if (output === input && opts.contains === true) {
3415 state.output = input;
3416 return state;
3417 }
3418
3419 state.output = utils.wrapOutput(output, state, options);
3420 return state;
3421 }
3422
3423 /**
3424 * Tokenize input until we reach end-of-string
3425 */
3426
3427 while (!eos()) {
3428 value = advance();
3429
3430 if (value === '\u0000') {
3431 continue;
3432 }
3433
3434 /**
3435 * Escaped characters
3436 */
3437
3438 if (value === '\\') {
3439 const next = peek();
3440
3441 if (next === '/' && opts.bash !== true) {
3442 continue;
3443 }
3444
3445 if (next === '.' || next === ';') {
3446 continue;
3447 }
3448
3449 if (!next) {
3450 value += '\\';
3451 push({ type: 'text', value });
3452 continue;
3453 }
3454
3455 // collapse slashes to reduce potential for exploits
3456 const match = /^\\+/.exec(remaining());
3457 let slashes = 0;
3458
3459 if (match && match[0].length > 2) {
3460 slashes = match[0].length;
3461 state.index += slashes;
3462 if (slashes % 2 !== 0) {
3463 value += '\\';
3464 }
3465 }
3466
3467 if (opts.unescape === true) {
3468 value = advance();
3469 } else {
3470 value += advance();
3471 }
3472
3473 if (state.brackets === 0) {
3474 push({ type: 'text', value });
3475 continue;
3476 }
3477 }
3478
3479 /**
3480 * If we're inside a regex character class, continue
3481 * until we reach the closing bracket.
3482 */
3483
3484 if (state.brackets > 0 && (value !== ']' || prev.value === '[' || prev.value === '[^')) {
3485 if (opts.posix !== false && value === ':') {
3486 const inner = prev.value.slice(1);
3487 if (inner.includes('[')) {
3488 prev.posix = true;
3489
3490 if (inner.includes(':')) {
3491 const idx = prev.value.lastIndexOf('[');
3492 const pre = prev.value.slice(0, idx);
3493 const rest = prev.value.slice(idx + 2);
3494 const posix = POSIX_REGEX_SOURCE[rest];
3495 if (posix) {
3496 prev.value = pre + posix;
3497 state.backtrack = true;
3498 advance();
3499
3500 if (!bos.output && tokens.indexOf(prev) === 1) {
3501 bos.output = ONE_CHAR;
3502 }
3503 continue;
3504 }
3505 }
3506 }
3507 }
3508
3509 if ((value === '[' && peek() !== ':') || (value === '-' && peek() === ']')) {
3510 value = `\\${value}`;
3511 }
3512
3513 if (value === ']' && (prev.value === '[' || prev.value === '[^')) {
3514 value = `\\${value}`;
3515 }
3516
3517 if (opts.posix === true && value === '!' && prev.value === '[') {
3518 value = '^';
3519 }
3520
3521 prev.value += value;
3522 append({ value });
3523 continue;
3524 }
3525
3526 /**
3527 * If we're inside a quoted string, continue
3528 * until we reach the closing double quote.
3529 */
3530
3531 if (state.quotes === 1 && value !== '"') {
3532 value = utils.escapeRegex(value);
3533 prev.value += value;
3534 append({ value });
3535 continue;
3536 }
3537
3538 /**
3539 * Double quotes
3540 */
3541
3542 if (value === '"') {
3543 state.quotes = state.quotes === 1 ? 0 : 1;
3544 if (opts.keepQuotes === true) {
3545 push({ type: 'text', value });
3546 }
3547 continue;
3548 }
3549
3550 /**
3551 * Parentheses
3552 */
3553
3554 if (value === '(') {
3555 increment('parens');
3556 push({ type: 'paren', value });
3557 continue;
3558 }
3559
3560 if (value === ')') {
3561 if (state.parens === 0 && opts.strictBrackets === true) {
3562 throw new SyntaxError(syntaxError('opening', '('));
3563 }
3564
3565 const extglob = extglobs[extglobs.length - 1];
3566 if (extglob && state.parens === extglob.parens + 1) {
3567 extglobClose(extglobs.pop());
3568 continue;
3569 }
3570
3571 push({ type: 'paren', value, output: state.parens ? ')' : '\\)' });
3572 decrement('parens');
3573 continue;
3574 }
3575
3576 /**
3577 * Square brackets
3578 */
3579
3580 if (value === '[') {
3581 if (opts.nobracket === true || !remaining().includes(']')) {
3582 if (opts.nobracket !== true && opts.strictBrackets === true) {
3583 throw new SyntaxError(syntaxError('closing', ']'));
3584 }
3585
3586 value = `\\${value}`;
3587 } else {
3588 increment('brackets');
3589 }
3590
3591 push({ type: 'bracket', value });
3592 continue;
3593 }
3594
3595 if (value === ']') {
3596 if (opts.nobracket === true || (prev && prev.type === 'bracket' && prev.value.length === 1)) {
3597 push({ type: 'text', value, output: `\\${value}` });
3598 continue;
3599 }
3600
3601 if (state.brackets === 0) {
3602 if (opts.strictBrackets === true) {
3603 throw new SyntaxError(syntaxError('opening', '['));
3604 }
3605
3606 push({ type: 'text', value, output: `\\${value}` });
3607 continue;
3608 }
3609
3610 decrement('brackets');
3611
3612 const prevValue = prev.value.slice(1);
3613 if (prev.posix !== true && prevValue[0] === '^' && !prevValue.includes('/')) {
3614 value = `/${value}`;
3615 }
3616
3617 prev.value += value;
3618 append({ value });
3619
3620 // when literal brackets are explicitly disabled
3621 // assume we should match with a regex character class
3622 if (opts.literalBrackets === false || utils.hasRegexChars(prevValue)) {
3623 continue;
3624 }
3625
3626 const escaped = utils.escapeRegex(prev.value);
3627 state.output = state.output.slice(0, -prev.value.length);
3628
3629 // when literal brackets are explicitly enabled
3630 // assume we should escape the brackets to match literal characters
3631 if (opts.literalBrackets === true) {
3632 state.output += escaped;
3633 prev.value = escaped;
3634 continue;
3635 }
3636
3637 // when the user specifies nothing, try to match both
3638 prev.value = `(${capture}${escaped}|${prev.value})`;
3639 state.output += prev.value;
3640 continue;
3641 }
3642
3643 /**
3644 * Braces
3645 */
3646
3647 if (value === '{' && opts.nobrace !== true) {
3648 increment('braces');
3649
3650 const open = {
3651 type: 'brace',
3652 value,
3653 output: '(',
3654 outputIndex: state.output.length,
3655 tokensIndex: state.tokens.length
3656 };
3657
3658 braces.push(open);
3659 push(open);
3660 continue;
3661 }
3662
3663 if (value === '}') {
3664 const brace = braces[braces.length - 1];
3665
3666 if (opts.nobrace === true || !brace) {
3667 push({ type: 'text', value, output: value });
3668 continue;
3669 }
3670
3671 let output = ')';
3672
3673 if (brace.dots === true) {
3674 const arr = tokens.slice();
3675 const range = [];
3676
3677 for (let i = arr.length - 1; i >= 0; i--) {
3678 tokens.pop();
3679 if (arr[i].type === 'brace') {
3680 break;
3681 }
3682 if (arr[i].type !== 'dots') {
3683 range.unshift(arr[i].value);
3684 }
3685 }
3686
3687 output = expandRange(range, opts);
3688 state.backtrack = true;
3689 }
3690
3691 if (brace.comma !== true && brace.dots !== true) {
3692 const out = state.output.slice(0, brace.outputIndex);
3693 const toks = state.tokens.slice(brace.tokensIndex);
3694 brace.value = brace.output = '\\{';
3695 value = output = '\\}';
3696 state.output = out;
3697 for (const t of toks) {
3698 state.output += (t.output || t.value);
3699 }
3700 }
3701
3702 push({ type: 'brace', value, output });
3703 decrement('braces');
3704 braces.pop();
3705 continue;
3706 }
3707
3708 /**
3709 * Pipes
3710 */
3711
3712 if (value === '|') {
3713 if (extglobs.length > 0) {
3714 extglobs[extglobs.length - 1].conditions++;
3715 }
3716 push({ type: 'text', value });
3717 continue;
3718 }
3719
3720 /**
3721 * Commas
3722 */
3723
3724 if (value === ',') {
3725 let output = value;
3726
3727 const brace = braces[braces.length - 1];
3728 if (brace && stack[stack.length - 1] === 'braces') {
3729 brace.comma = true;
3730 output = '|';
3731 }
3732
3733 push({ type: 'comma', value, output });
3734 continue;
3735 }
3736
3737 /**
3738 * Slashes
3739 */
3740
3741 if (value === '/') {
3742 // if the beginning of the glob is "./", advance the start
3743 // to the current index, and don't add the "./" characters
3744 // to the state. This greatly simplifies lookbehinds when
3745 // checking for BOS characters like "!" and "." (not "./")
3746 if (prev.type === 'dot' && state.index === state.start + 1) {
3747 state.start = state.index + 1;
3748 state.consumed = '';
3749 state.output = '';
3750 tokens.pop();
3751 prev = bos; // reset "prev" to the first token
3752 continue;
3753 }
3754
3755 push({ type: 'slash', value, output: SLASH_LITERAL });
3756 continue;
3757 }
3758
3759 /**
3760 * Dots
3761 */
3762
3763 if (value === '.') {
3764 if (state.braces > 0 && prev.type === 'dot') {
3765 if (prev.value === '.') prev.output = DOT_LITERAL;
3766 const brace = braces[braces.length - 1];
3767 prev.type = 'dots';
3768 prev.output += value;
3769 prev.value += value;
3770 brace.dots = true;
3771 continue;
3772 }
3773
3774 if ((state.braces + state.parens) === 0 && prev.type !== 'bos' && prev.type !== 'slash') {
3775 push({ type: 'text', value, output: DOT_LITERAL });
3776 continue;
3777 }
3778
3779 push({ type: 'dot', value, output: DOT_LITERAL });
3780 continue;
3781 }
3782
3783 /**
3784 * Question marks
3785 */
3786
3787 if (value === '?') {
3788 const isGroup = prev && prev.value === '(';
3789 if (!isGroup && opts.noextglob !== true && peek() === '(' && peek(2) !== '?') {
3790 extglobOpen('qmark', value);
3791 continue;
3792 }
3793
3794 if (prev && prev.type === 'paren') {
3795 const next = peek();
3796 let output = value;
3797
3798 if (next === '<' && !utils.supportsLookbehinds()) {
3799 throw new Error('Node.js v10 or higher is required for regex lookbehinds');
3800 }
3801
3802 if ((prev.value === '(' && !/[!=<:]/.test(next)) || (next === '<' && !/<([!=]|\w+>)/.test(remaining()))) {
3803 output = `\\${value}`;
3804 }
3805
3806 push({ type: 'text', value, output });
3807 continue;
3808 }
3809
3810 if (opts.dot !== true && (prev.type === 'slash' || prev.type === 'bos')) {
3811 push({ type: 'qmark', value, output: QMARK_NO_DOT });
3812 continue;
3813 }
3814
3815 push({ type: 'qmark', value, output: QMARK });
3816 continue;
3817 }
3818
3819 /**
3820 * Exclamation
3821 */
3822
3823 if (value === '!') {
3824 if (opts.noextglob !== true && peek() === '(') {
3825 if (peek(2) !== '?' || !/[!=<:]/.test(peek(3))) {
3826 extglobOpen('negate', value);
3827 continue;
3828 }
3829 }
3830
3831 if (opts.nonegate !== true && state.index === 0) {
3832 negate();
3833 continue;
3834 }
3835 }
3836
3837 /**
3838 * Plus
3839 */
3840
3841 if (value === '+') {
3842 if (opts.noextglob !== true && peek() === '(' && peek(2) !== '?') {
3843 extglobOpen('plus', value);
3844 continue;
3845 }
3846
3847 if ((prev && prev.value === '(') || opts.regex === false) {
3848 push({ type: 'plus', value, output: PLUS_LITERAL });
3849 continue;
3850 }
3851
3852 if ((prev && (prev.type === 'bracket' || prev.type === 'paren' || prev.type === 'brace')) || state.parens > 0) {
3853 push({ type: 'plus', value });
3854 continue;
3855 }
3856
3857 push({ type: 'plus', value: PLUS_LITERAL });
3858 continue;
3859 }
3860
3861 /**
3862 * Plain text
3863 */
3864
3865 if (value === '@') {
3866 if (opts.noextglob !== true && peek() === '(' && peek(2) !== '?') {
3867 push({ type: 'at', extglob: true, value, output: '' });
3868 continue;
3869 }
3870
3871 push({ type: 'text', value });
3872 continue;
3873 }
3874
3875 /**
3876 * Plain text
3877 */
3878
3879 if (value !== '*') {
3880 if (value === '$' || value === '^') {
3881 value = `\\${value}`;
3882 }
3883
3884 const match = REGEX_NON_SPECIAL_CHARS.exec(remaining());
3885 if (match) {
3886 value += match[0];
3887 state.index += match[0].length;
3888 }
3889
3890 push({ type: 'text', value });
3891 continue;
3892 }
3893
3894 /**
3895 * Stars
3896 */
3897
3898 if (prev && (prev.type === 'globstar' || prev.star === true)) {
3899 prev.type = 'star';
3900 prev.star = true;
3901 prev.value += value;
3902 prev.output = star;
3903 state.backtrack = true;
3904 state.globstar = true;
3905 consume(value);
3906 continue;
3907 }
3908
3909 let rest = remaining();
3910 if (opts.noextglob !== true && /^\([^?]/.test(rest)) {
3911 extglobOpen('star', value);
3912 continue;
3913 }
3914
3915 if (prev.type === 'star') {
3916 if (opts.noglobstar === true) {
3917 consume(value);
3918 continue;
3919 }
3920
3921 const prior = prev.prev;
3922 const before = prior.prev;
3923 const isStart = prior.type === 'slash' || prior.type === 'bos';
3924 const afterStar = before && (before.type === 'star' || before.type === 'globstar');
3925
3926 if (opts.bash === true && (!isStart || (rest[0] && rest[0] !== '/'))) {
3927 push({ type: 'star', value, output: '' });
3928 continue;
3929 }
3930
3931 const isBrace = state.braces > 0 && (prior.type === 'comma' || prior.type === 'brace');
3932 const isExtglob = extglobs.length && (prior.type === 'pipe' || prior.type === 'paren');
3933 if (!isStart && prior.type !== 'paren' && !isBrace && !isExtglob) {
3934 push({ type: 'star', value, output: '' });
3935 continue;
3936 }
3937
3938 // strip consecutive `/**/`
3939 while (rest.slice(0, 3) === '/**') {
3940 const after = input[state.index + 4];
3941 if (after && after !== '/') {
3942 break;
3943 }
3944 rest = rest.slice(3);
3945 consume('/**', 3);
3946 }
3947
3948 if (prior.type === 'bos' && eos()) {
3949 prev.type = 'globstar';
3950 prev.value += value;
3951 prev.output = globstar(opts);
3952 state.output = prev.output;
3953 state.globstar = true;
3954 consume(value);
3955 continue;
3956 }
3957
3958 if (prior.type === 'slash' && prior.prev.type !== 'bos' && !afterStar && eos()) {
3959 state.output = state.output.slice(0, -(prior.output + prev.output).length);
3960 prior.output = `(?:${prior.output}`;
3961
3962 prev.type = 'globstar';
3963 prev.output = globstar(opts) + (opts.strictSlashes ? ')' : '|$)');
3964 prev.value += value;
3965 state.globstar = true;
3966 state.output += prior.output + prev.output;
3967 consume(value);
3968 continue;
3969 }
3970
3971 if (prior.type === 'slash' && prior.prev.type !== 'bos' && rest[0] === '/') {
3972 const end = rest[1] !== undefined ? '|$' : '';
3973
3974 state.output = state.output.slice(0, -(prior.output + prev.output).length);
3975 prior.output = `(?:${prior.output}`;
3976
3977 prev.type = 'globstar';
3978 prev.output = `${globstar(opts)}${SLASH_LITERAL}|${SLASH_LITERAL}${end})`;
3979 prev.value += value;
3980
3981 state.output += prior.output + prev.output;
3982 state.globstar = true;
3983
3984 consume(value + advance());
3985
3986 push({ type: 'slash', value: '/', output: '' });
3987 continue;
3988 }
3989
3990 if (prior.type === 'bos' && rest[0] === '/') {
3991 prev.type = 'globstar';
3992 prev.value += value;
3993 prev.output = `(?:^|${SLASH_LITERAL}|${globstar(opts)}${SLASH_LITERAL})`;
3994 state.output = prev.output;
3995 state.globstar = true;
3996 consume(value + advance());
3997 push({ type: 'slash', value: '/', output: '' });
3998 continue;
3999 }
4000
4001 // remove single star from output
4002 state.output = state.output.slice(0, -prev.output.length);
4003
4004 // reset previous token to globstar
4005 prev.type = 'globstar';
4006 prev.output = globstar(opts);
4007 prev.value += value;
4008
4009 // reset output with globstar
4010 state.output += prev.output;
4011 state.globstar = true;
4012 consume(value);
4013 continue;
4014 }
4015
4016 const token = { type: 'star', value, output: star };
4017
4018 if (opts.bash === true) {
4019 token.output = '.*?';
4020 if (prev.type === 'bos' || prev.type === 'slash') {
4021 token.output = nodot + token.output;
4022 }
4023 push(token);
4024 continue;
4025 }
4026
4027 if (prev && (prev.type === 'bracket' || prev.type === 'paren') && opts.regex === true) {
4028 token.output = value;
4029 push(token);
4030 continue;
4031 }
4032
4033 if (state.index === state.start || prev.type === 'slash' || prev.type === 'dot') {
4034 if (prev.type === 'dot') {
4035 state.output += NO_DOT_SLASH;
4036 prev.output += NO_DOT_SLASH;
4037
4038 } else if (opts.dot === true) {
4039 state.output += NO_DOTS_SLASH;
4040 prev.output += NO_DOTS_SLASH;
4041
4042 } else {
4043 state.output += nodot;
4044 prev.output += nodot;
4045 }
4046
4047 if (peek() !== '*') {
4048 state.output += ONE_CHAR;
4049 prev.output += ONE_CHAR;
4050 }
4051 }
4052
4053 push(token);
4054 }
4055
4056 while (state.brackets > 0) {
4057 if (opts.strictBrackets === true) throw new SyntaxError(syntaxError('closing', ']'));
4058 state.output = utils.escapeLast(state.output, '[');
4059 decrement('brackets');
4060 }
4061
4062 while (state.parens > 0) {
4063 if (opts.strictBrackets === true) throw new SyntaxError(syntaxError('closing', ')'));
4064 state.output = utils.escapeLast(state.output, '(');
4065 decrement('parens');
4066 }
4067
4068 while (state.braces > 0) {
4069 if (opts.strictBrackets === true) throw new SyntaxError(syntaxError('closing', '}'));
4070 state.output = utils.escapeLast(state.output, '{');
4071 decrement('braces');
4072 }
4073
4074 if (opts.strictSlashes !== true && (prev.type === 'star' || prev.type === 'bracket')) {
4075 push({ type: 'maybe_slash', value: '', output: `${SLASH_LITERAL}?` });
4076 }
4077
4078 // rebuild the output if we had to backtrack at any point
4079 if (state.backtrack === true) {
4080 state.output = '';
4081
4082 for (const token of state.tokens) {
4083 state.output += token.output != null ? token.output : token.value;
4084
4085 if (token.suffix) {
4086 state.output += token.suffix;
4087 }
4088 }
4089 }
4090
4091 return state;
4092 };
4093
4094 /**
4095 * Fast paths for creating regular expressions for common glob patterns.
4096 * This can significantly speed up processing and has very little downside
4097 * impact when none of the fast paths match.
4098 */
4099
4100 parse.fastpaths = (input, options) => {
4101 const opts = { ...options };
4102 const max = typeof opts.maxLength === 'number' ? Math.min(MAX_LENGTH, opts.maxLength) : MAX_LENGTH;
4103 const len = input.length;
4104 if (len > max) {
4105 throw new SyntaxError(`Input length: ${len}, exceeds maximum allowed length: ${max}`);
4106 }
4107
4108 input = REPLACEMENTS[input] || input;
4109 const win32 = utils.isWindows(options);
4110
4111 // create constants based on platform, for windows or posix
4112 const {
4113 DOT_LITERAL,
4114 SLASH_LITERAL,
4115 ONE_CHAR,
4116 DOTS_SLASH,
4117 NO_DOT,
4118 NO_DOTS,
4119 NO_DOTS_SLASH,
4120 STAR,
4121 START_ANCHOR
4122 } = constants.globChars(win32);
4123
4124 const nodot = opts.dot ? NO_DOTS : NO_DOT;
4125 const slashDot = opts.dot ? NO_DOTS_SLASH : NO_DOT;
4126 const capture = opts.capture ? '' : '?:';
4127 const state = { negated: false, prefix: '' };
4128 let star = opts.bash === true ? '.*?' : STAR;
4129
4130 if (opts.capture) {
4131 star = `(${star})`;
4132 }
4133
4134 const globstar = opts => {
4135 if (opts.noglobstar === true) return star;
4136 return `(${capture}(?:(?!${START_ANCHOR}${opts.dot ? DOTS_SLASH : DOT_LITERAL}).)*?)`;
4137 };
4138
4139 const create = str => {
4140 switch (str) {
4141 case '*':
4142 return `${nodot}${ONE_CHAR}${star}`;
4143
4144 case '.*':
4145 return `${DOT_LITERAL}${ONE_CHAR}${star}`;
4146
4147 case '*.*':
4148 return `${nodot}${star}${DOT_LITERAL}${ONE_CHAR}${star}`;
4149
4150 case '*/*':
4151 return `${nodot}${star}${SLASH_LITERAL}${ONE_CHAR}${slashDot}${star}`;
4152
4153 case '**':
4154 return nodot + globstar(opts);
4155
4156 case '**/*':
4157 return `(?:${nodot}${globstar(opts)}${SLASH_LITERAL})?${slashDot}${ONE_CHAR}${star}`;
4158
4159 case '**/*.*':
4160 return `(?:${nodot}${globstar(opts)}${SLASH_LITERAL})?${slashDot}${star}${DOT_LITERAL}${ONE_CHAR}${star}`;
4161
4162 case '**/.*':
4163 return `(?:${nodot}${globstar(opts)}${SLASH_LITERAL})?${DOT_LITERAL}${ONE_CHAR}${star}`;
4164
4165 default: {
4166 const match = /^(.*?)\.(\w+)$/.exec(str);
4167 if (!match) return;
4168
4169 const source = create(match[1]);
4170 if (!source) return;
4171
4172 return source + DOT_LITERAL + match[2];
4173 }
4174 }
4175 };
4176
4177 const output = utils.removePrefix(input, state);
4178 let source = create(output);
4179
4180 if (source && opts.strictSlashes !== true) {
4181 source += `${SLASH_LITERAL}?`;
4182 }
4183
4184 return source;
4185 };
4186
4187 parse_1$1 = parse;
4188 return parse_1$1;
4189}
4190
4191var picomatch_1;
4192var hasRequiredPicomatch$1;
4193
4194function requirePicomatch$1 () {
4195 if (hasRequiredPicomatch$1) return picomatch_1;
4196 hasRequiredPicomatch$1 = 1;
4197
4198 const path = require$$0$1;
4199 const scan = /*@__PURE__*/ requireScan();
4200 const parse = /*@__PURE__*/ requireParse$1();
4201 const utils = /*@__PURE__*/ requireUtils$1();
4202 const constants = /*@__PURE__*/ requireConstants$2();
4203 const isObject = val => val && typeof val === 'object' && !Array.isArray(val);
4204
4205 /**
4206 * Creates a matcher function from one or more glob patterns. The
4207 * returned function takes a string to match as its first argument,
4208 * and returns true if the string is a match. The returned matcher
4209 * function also takes a boolean as the second argument that, when true,
4210 * returns an object with additional information.
4211 *
4212 * ```js
4213 * const picomatch = require('picomatch');
4214 * // picomatch(glob[, options]);
4215 *
4216 * const isMatch = picomatch('*.!(*a)');
4217 * console.log(isMatch('a.a')); //=> false
4218 * console.log(isMatch('a.b')); //=> true
4219 * ```
4220 * @name picomatch
4221 * @param {String|Array} `globs` One or more glob patterns.
4222 * @param {Object=} `options`
4223 * @return {Function=} Returns a matcher function.
4224 * @api public
4225 */
4226
4227 const picomatch = (glob, options, returnState = false) => {
4228 if (Array.isArray(glob)) {
4229 const fns = glob.map(input => picomatch(input, options, returnState));
4230 const arrayMatcher = str => {
4231 for (const isMatch of fns) {
4232 const state = isMatch(str);
4233 if (state) return state;
4234 }
4235 return false;
4236 };
4237 return arrayMatcher;
4238 }
4239
4240 const isState = isObject(glob) && glob.tokens && glob.input;
4241
4242 if (glob === '' || (typeof glob !== 'string' && !isState)) {
4243 throw new TypeError('Expected pattern to be a non-empty string');
4244 }
4245
4246 const opts = options || {};
4247 const posix = utils.isWindows(options);
4248 const regex = isState
4249 ? picomatch.compileRe(glob, options)
4250 : picomatch.makeRe(glob, options, false, true);
4251
4252 const state = regex.state;
4253 delete regex.state;
4254
4255 let isIgnored = () => false;
4256 if (opts.ignore) {
4257 const ignoreOpts = { ...options, ignore: null, onMatch: null, onResult: null };
4258 isIgnored = picomatch(opts.ignore, ignoreOpts, returnState);
4259 }
4260
4261 const matcher = (input, returnObject = false) => {
4262 const { isMatch, match, output } = picomatch.test(input, regex, options, { glob, posix });
4263 const result = { glob, state, regex, posix, input, output, match, isMatch };
4264
4265 if (typeof opts.onResult === 'function') {
4266 opts.onResult(result);
4267 }
4268
4269 if (isMatch === false) {
4270 result.isMatch = false;
4271 return returnObject ? result : false;
4272 }
4273
4274 if (isIgnored(input)) {
4275 if (typeof opts.onIgnore === 'function') {
4276 opts.onIgnore(result);
4277 }
4278 result.isMatch = false;
4279 return returnObject ? result : false;
4280 }
4281
4282 if (typeof opts.onMatch === 'function') {
4283 opts.onMatch(result);
4284 }
4285 return returnObject ? result : true;
4286 };
4287
4288 if (returnState) {
4289 matcher.state = state;
4290 }
4291
4292 return matcher;
4293 };
4294
4295 /**
4296 * Test `input` with the given `regex`. This is used by the main
4297 * `picomatch()` function to test the input string.
4298 *
4299 * ```js
4300 * const picomatch = require('picomatch');
4301 * // picomatch.test(input, regex[, options]);
4302 *
4303 * console.log(picomatch.test('foo/bar', /^(?:([^/]*?)\/([^/]*?))$/));
4304 * // { isMatch: true, match: [ 'foo/', 'foo', 'bar' ], output: 'foo/bar' }
4305 * ```
4306 * @param {String} `input` String to test.
4307 * @param {RegExp} `regex`
4308 * @return {Object} Returns an object with matching info.
4309 * @api public
4310 */
4311
4312 picomatch.test = (input, regex, options, { glob, posix } = {}) => {
4313 if (typeof input !== 'string') {
4314 throw new TypeError('Expected input to be a string');
4315 }
4316
4317 if (input === '') {
4318 return { isMatch: false, output: '' };
4319 }
4320
4321 const opts = options || {};
4322 const format = opts.format || (posix ? utils.toPosixSlashes : null);
4323 let match = input === glob;
4324 let output = (match && format) ? format(input) : input;
4325
4326 if (match === false) {
4327 output = format ? format(input) : input;
4328 match = output === glob;
4329 }
4330
4331 if (match === false || opts.capture === true) {
4332 if (opts.matchBase === true || opts.basename === true) {
4333 match = picomatch.matchBase(input, regex, options, posix);
4334 } else {
4335 match = regex.exec(output);
4336 }
4337 }
4338
4339 return { isMatch: Boolean(match), match, output };
4340 };
4341
4342 /**
4343 * Match the basename of a filepath.
4344 *
4345 * ```js
4346 * const picomatch = require('picomatch');
4347 * // picomatch.matchBase(input, glob[, options]);
4348 * console.log(picomatch.matchBase('foo/bar.js', '*.js'); // true
4349 * ```
4350 * @param {String} `input` String to test.
4351 * @param {RegExp|String} `glob` Glob pattern or regex created by [.makeRe](#makeRe).
4352 * @return {Boolean}
4353 * @api public
4354 */
4355
4356 picomatch.matchBase = (input, glob, options, posix = utils.isWindows(options)) => {
4357 const regex = glob instanceof RegExp ? glob : picomatch.makeRe(glob, options);
4358 return regex.test(path.basename(input));
4359 };
4360
4361 /**
4362 * Returns true if **any** of the given glob `patterns` match the specified `string`.
4363 *
4364 * ```js
4365 * const picomatch = require('picomatch');
4366 * // picomatch.isMatch(string, patterns[, options]);
4367 *
4368 * console.log(picomatch.isMatch('a.a', ['b.*', '*.a'])); //=> true
4369 * console.log(picomatch.isMatch('a.a', 'b.*')); //=> false
4370 * ```
4371 * @param {String|Array} str The string to test.
4372 * @param {String|Array} patterns One or more glob patterns to use for matching.
4373 * @param {Object} [options] See available [options](#options).
4374 * @return {Boolean} Returns true if any patterns match `str`
4375 * @api public
4376 */
4377
4378 picomatch.isMatch = (str, patterns, options) => picomatch(patterns, options)(str);
4379
4380 /**
4381 * Parse a glob pattern to create the source string for a regular
4382 * expression.
4383 *
4384 * ```js
4385 * const picomatch = require('picomatch');
4386 * const result = picomatch.parse(pattern[, options]);
4387 * ```
4388 * @param {String} `pattern`
4389 * @param {Object} `options`
4390 * @return {Object} Returns an object with useful properties and output to be used as a regex source string.
4391 * @api public
4392 */
4393
4394 picomatch.parse = (pattern, options) => {
4395 if (Array.isArray(pattern)) return pattern.map(p => picomatch.parse(p, options));
4396 return parse(pattern, { ...options, fastpaths: false });
4397 };
4398
4399 /**
4400 * Scan a glob pattern to separate the pattern into segments.
4401 *
4402 * ```js
4403 * const picomatch = require('picomatch');
4404 * // picomatch.scan(input[, options]);
4405 *
4406 * const result = picomatch.scan('!./foo/*.js');
4407 * console.log(result);
4408 * { prefix: '!./',
4409 * input: '!./foo/*.js',
4410 * start: 3,
4411 * base: 'foo',
4412 * glob: '*.js',
4413 * isBrace: false,
4414 * isBracket: false,
4415 * isGlob: true,
4416 * isExtglob: false,
4417 * isGlobstar: false,
4418 * negated: true }
4419 * ```
4420 * @param {String} `input` Glob pattern to scan.
4421 * @param {Object} `options`
4422 * @return {Object} Returns an object with
4423 * @api public
4424 */
4425
4426 picomatch.scan = (input, options) => scan(input, options);
4427
4428 /**
4429 * Compile a regular expression from the `state` object returned by the
4430 * [parse()](#parse) method.
4431 *
4432 * @param {Object} `state`
4433 * @param {Object} `options`
4434 * @param {Boolean} `returnOutput` Intended for implementors, this argument allows you to return the raw output from the parser.
4435 * @param {Boolean} `returnState` Adds the state to a `state` property on the returned regex. Useful for implementors and debugging.
4436 * @return {RegExp}
4437 * @api public
4438 */
4439
4440 picomatch.compileRe = (state, options, returnOutput = false, returnState = false) => {
4441 if (returnOutput === true) {
4442 return state.output;
4443 }
4444
4445 const opts = options || {};
4446 const prepend = opts.contains ? '' : '^';
4447 const append = opts.contains ? '' : '$';
4448
4449 let source = `${prepend}(?:${state.output})${append}`;
4450 if (state && state.negated === true) {
4451 source = `^(?!${source}).*$`;
4452 }
4453
4454 const regex = picomatch.toRegex(source, options);
4455 if (returnState === true) {
4456 regex.state = state;
4457 }
4458
4459 return regex;
4460 };
4461
4462 /**
4463 * Create a regular expression from a parsed glob pattern.
4464 *
4465 * ```js
4466 * const picomatch = require('picomatch');
4467 * const state = picomatch.parse('*.js');
4468 * // picomatch.compileRe(state[, options]);
4469 *
4470 * console.log(picomatch.compileRe(state));
4471 * //=> /^(?:(?!\.)(?=.)[^/]*?\.js)$/
4472 * ```
4473 * @param {String} `state` The object returned from the `.parse` method.
4474 * @param {Object} `options`
4475 * @param {Boolean} `returnOutput` 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.
4476 * @param {Boolean} `returnState` Implementors may use this argument to return the state from the parsed glob with the returned regular expression.
4477 * @return {RegExp} Returns a regex created from the given pattern.
4478 * @api public
4479 */
4480
4481 picomatch.makeRe = (input, options = {}, returnOutput = false, returnState = false) => {
4482 if (!input || typeof input !== 'string') {
4483 throw new TypeError('Expected a non-empty string');
4484 }
4485
4486 let parsed = { negated: false, fastpaths: true };
4487
4488 if (options.fastpaths !== false && (input[0] === '.' || input[0] === '*')) {
4489 parsed.output = parse.fastpaths(input, options);
4490 }
4491
4492 if (!parsed.output) {
4493 parsed = parse(input, options);
4494 }
4495
4496 return picomatch.compileRe(parsed, options, returnOutput, returnState);
4497 };
4498
4499 /**
4500 * Create a regular expression from the given regex source string.
4501 *
4502 * ```js
4503 * const picomatch = require('picomatch');
4504 * // picomatch.toRegex(source[, options]);
4505 *
4506 * const { output } = picomatch.parse('*.js');
4507 * console.log(picomatch.toRegex(output));
4508 * //=> /^(?:(?!\.)(?=.)[^/]*?\.js)$/
4509 * ```
4510 * @param {String} `source` Regular expression source string.
4511 * @param {Object} `options`
4512 * @return {RegExp}
4513 * @api public
4514 */
4515
4516 picomatch.toRegex = (source, options) => {
4517 try {
4518 const opts = options || {};
4519 return new RegExp(source, opts.flags || (opts.nocase ? 'i' : ''));
4520 } catch (err) {
4521 if (options && options.debug === true) throw err;
4522 return /$^/;
4523 }
4524 };
4525
4526 /**
4527 * Picomatch constants.
4528 * @return {Object}
4529 */
4530
4531 picomatch.constants = constants;
4532
4533 /**
4534 * Expose "picomatch"
4535 */
4536
4537 picomatch_1 = picomatch;
4538 return picomatch_1;
4539}
4540
4541var picomatch;
4542var hasRequiredPicomatch;
4543
4544function requirePicomatch () {
4545 if (hasRequiredPicomatch) return picomatch;
4546 hasRequiredPicomatch = 1;
4547
4548 picomatch = /*@__PURE__*/ requirePicomatch$1();
4549 return picomatch;
4550}
4551
4552/*!
4553 * normalize-path <https://github.com/jonschlinkert/normalize-path>
4554 *
4555 * Copyright (c) 2014-2018, Jon Schlinkert.
4556 * Released under the MIT License.
4557 */
4558
4559var normalizePath;
4560var hasRequiredNormalizePath;
4561
4562function requireNormalizePath () {
4563 if (hasRequiredNormalizePath) return normalizePath;
4564 hasRequiredNormalizePath = 1;
4565 normalizePath = function(path, stripTrailing) {
4566 if (typeof path !== 'string') {
4567 throw new TypeError('expected path to be a string');
4568 }
4569
4570 if (path === '\\' || path === '/') return '/';
4571
4572 var len = path.length;
4573 if (len <= 1) return path;
4574
4575 // ensure that win32 namespaces has two leading slashes, so that the path is
4576 // handled properly by the win32 version of path.parse() after being normalized
4577 // https://msdn.microsoft.com/library/windows/desktop/aa365247(v=vs.85).aspx#namespaces
4578 var prefix = '';
4579 if (len > 4 && path[3] === '\\') {
4580 var ch = path[2];
4581 if ((ch === '?' || ch === '.') && path.slice(0, 2) === '\\\\') {
4582 path = path.slice(2);
4583 prefix = '//';
4584 }
4585 }
4586
4587 var segs = path.split(/[/\\]+/);
4588 if (stripTrailing !== false && segs[segs.length - 1] === '') {
4589 segs.pop();
4590 }
4591 return prefix + segs.join('/');
4592 };
4593 return normalizePath;
4594}
4595
4596var anymatch_1 = anymatch.exports;
4597
4598var hasRequiredAnymatch;
4599
4600function requireAnymatch () {
4601 if (hasRequiredAnymatch) return anymatch.exports;
4602 hasRequiredAnymatch = 1;
4603
4604 Object.defineProperty(anymatch_1, "__esModule", { value: true });
4605
4606 const picomatch = /*@__PURE__*/ requirePicomatch();
4607 const normalizePath = /*@__PURE__*/ requireNormalizePath();
4608
4609 /**
4610 * @typedef {(testString: string) => boolean} AnymatchFn
4611 * @typedef {string|RegExp|AnymatchFn} AnymatchPattern
4612 * @typedef {AnymatchPattern|AnymatchPattern[]} AnymatchMatcher
4613 */
4614 const BANG = '!';
4615 const DEFAULT_OPTIONS = {returnIndex: false};
4616 const arrify = (item) => Array.isArray(item) ? item : [item];
4617
4618 /**
4619 * @param {AnymatchPattern} matcher
4620 * @param {object} options
4621 * @returns {AnymatchFn}
4622 */
4623 const createPattern = (matcher, options) => {
4624 if (typeof matcher === 'function') {
4625 return matcher;
4626 }
4627 if (typeof matcher === 'string') {
4628 const glob = picomatch(matcher, options);
4629 return (string) => matcher === string || glob(string);
4630 }
4631 if (matcher instanceof RegExp) {
4632 return (string) => matcher.test(string);
4633 }
4634 return (string) => false;
4635 };
4636
4637 /**
4638 * @param {Array<Function>} patterns
4639 * @param {Array<Function>} negPatterns
4640 * @param {String|Array} args
4641 * @param {Boolean} returnIndex
4642 * @returns {boolean|number}
4643 */
4644 const matchPatterns = (patterns, negPatterns, args, returnIndex) => {
4645 const isList = Array.isArray(args);
4646 const _path = isList ? args[0] : args;
4647 if (!isList && typeof _path !== 'string') {
4648 throw new TypeError('anymatch: second argument must be a string: got ' +
4649 Object.prototype.toString.call(_path))
4650 }
4651 const path = normalizePath(_path, false);
4652
4653 for (let index = 0; index < negPatterns.length; index++) {
4654 const nglob = negPatterns[index];
4655 if (nglob(path)) {
4656 return returnIndex ? -1 : false;
4657 }
4658 }
4659
4660 const applied = isList && [path].concat(args.slice(1));
4661 for (let index = 0; index < patterns.length; index++) {
4662 const pattern = patterns[index];
4663 if (isList ? pattern(...applied) : pattern(path)) {
4664 return returnIndex ? index : true;
4665 }
4666 }
4667
4668 return returnIndex ? -1 : false;
4669 };
4670
4671 /**
4672 * @param {AnymatchMatcher} matchers
4673 * @param {Array|string} testString
4674 * @param {object} options
4675 * @returns {boolean|number|Function}
4676 */
4677 const anymatch$1 = (matchers, testString, options = DEFAULT_OPTIONS) => {
4678 if (matchers == null) {
4679 throw new TypeError('anymatch: specify first argument');
4680 }
4681 const opts = typeof options === 'boolean' ? {returnIndex: options} : options;
4682 const returnIndex = opts.returnIndex || false;
4683
4684 // Early cache for matchers.
4685 const mtchers = arrify(matchers);
4686 const negatedGlobs = mtchers
4687 .filter(item => typeof item === 'string' && item.charAt(0) === BANG)
4688 .map(item => item.slice(1))
4689 .map(item => picomatch(item, opts));
4690 const patterns = mtchers
4691 .filter(item => typeof item !== 'string' || (typeof item === 'string' && item.charAt(0) !== BANG))
4692 .map(matcher => createPattern(matcher, opts));
4693
4694 if (testString == null) {
4695 return (testString, ri = false) => {
4696 const returnIndex = typeof ri === 'boolean' ? ri : false;
4697 return matchPatterns(patterns, negatedGlobs, testString, returnIndex);
4698 }
4699 }
4700
4701 return matchPatterns(patterns, negatedGlobs, testString, returnIndex);
4702 };
4703
4704 anymatch$1.default = anymatch$1;
4705 anymatch.exports = anymatch$1;
4706 return anymatch.exports;
4707}
4708
4709/*!
4710 * is-extglob <https://github.com/jonschlinkert/is-extglob>
4711 *
4712 * Copyright (c) 2014-2016, Jon Schlinkert.
4713 * Licensed under the MIT License.
4714 */
4715
4716var isExtglob;
4717var hasRequiredIsExtglob;
4718
4719function requireIsExtglob () {
4720 if (hasRequiredIsExtglob) return isExtglob;
4721 hasRequiredIsExtglob = 1;
4722 isExtglob = function isExtglob(str) {
4723 if (typeof str !== 'string' || str === '') {
4724 return false;
4725 }
4726
4727 var match;
4728 while ((match = /(\\).|([@?!+*]\(.*\))/g.exec(str))) {
4729 if (match[2]) return true;
4730 str = str.slice(match.index + match[0].length);
4731 }
4732
4733 return false;
4734 };
4735 return isExtglob;
4736}
4737
4738/*!
4739 * is-glob <https://github.com/jonschlinkert/is-glob>
4740 *
4741 * Copyright (c) 2014-2017, Jon Schlinkert.
4742 * Released under the MIT License.
4743 */
4744
4745var isGlob;
4746var hasRequiredIsGlob;
4747
4748function requireIsGlob () {
4749 if (hasRequiredIsGlob) return isGlob;
4750 hasRequiredIsGlob = 1;
4751 var isExtglob = /*@__PURE__*/ requireIsExtglob();
4752 var chars = { '{': '}', '(': ')', '[': ']'};
4753 var strictCheck = function(str) {
4754 if (str[0] === '!') {
4755 return true;
4756 }
4757 var index = 0;
4758 var pipeIndex = -2;
4759 var closeSquareIndex = -2;
4760 var closeCurlyIndex = -2;
4761 var closeParenIndex = -2;
4762 var backSlashIndex = -2;
4763 while (index < str.length) {
4764 if (str[index] === '*') {
4765 return true;
4766 }
4767
4768 if (str[index + 1] === '?' && /[\].+)]/.test(str[index])) {
4769 return true;
4770 }
4771
4772 if (closeSquareIndex !== -1 && str[index] === '[' && str[index + 1] !== ']') {
4773 if (closeSquareIndex < index) {
4774 closeSquareIndex = str.indexOf(']', index);
4775 }
4776 if (closeSquareIndex > index) {
4777 if (backSlashIndex === -1 || backSlashIndex > closeSquareIndex) {
4778 return true;
4779 }
4780 backSlashIndex = str.indexOf('\\', index);
4781 if (backSlashIndex === -1 || backSlashIndex > closeSquareIndex) {
4782 return true;
4783 }
4784 }
4785 }
4786
4787 if (closeCurlyIndex !== -1 && str[index] === '{' && str[index + 1] !== '}') {
4788 closeCurlyIndex = str.indexOf('}', index);
4789 if (closeCurlyIndex > index) {
4790 backSlashIndex = str.indexOf('\\', index);
4791 if (backSlashIndex === -1 || backSlashIndex > closeCurlyIndex) {
4792 return true;
4793 }
4794 }
4795 }
4796
4797 if (closeParenIndex !== -1 && str[index] === '(' && str[index + 1] === '?' && /[:!=]/.test(str[index + 2]) && str[index + 3] !== ')') {
4798 closeParenIndex = str.indexOf(')', index);
4799 if (closeParenIndex > index) {
4800 backSlashIndex = str.indexOf('\\', index);
4801 if (backSlashIndex === -1 || backSlashIndex > closeParenIndex) {
4802 return true;
4803 }
4804 }
4805 }
4806
4807 if (pipeIndex !== -1 && str[index] === '(' && str[index + 1] !== '|') {
4808 if (pipeIndex < index) {
4809 pipeIndex = str.indexOf('|', index);
4810 }
4811 if (pipeIndex !== -1 && str[pipeIndex + 1] !== ')') {
4812 closeParenIndex = str.indexOf(')', pipeIndex);
4813 if (closeParenIndex > pipeIndex) {
4814 backSlashIndex = str.indexOf('\\', pipeIndex);
4815 if (backSlashIndex === -1 || backSlashIndex > closeParenIndex) {
4816 return true;
4817 }
4818 }
4819 }
4820 }
4821
4822 if (str[index] === '\\') {
4823 var open = str[index + 1];
4824 index += 2;
4825 var close = chars[open];
4826
4827 if (close) {
4828 var n = str.indexOf(close, index);
4829 if (n !== -1) {
4830 index = n + 1;
4831 }
4832 }
4833
4834 if (str[index] === '!') {
4835 return true;
4836 }
4837 } else {
4838 index++;
4839 }
4840 }
4841 return false;
4842 };
4843
4844 var relaxedCheck = function(str) {
4845 if (str[0] === '!') {
4846 return true;
4847 }
4848 var index = 0;
4849 while (index < str.length) {
4850 if (/[*?{}()[\]]/.test(str[index])) {
4851 return true;
4852 }
4853
4854 if (str[index] === '\\') {
4855 var open = str[index + 1];
4856 index += 2;
4857 var close = chars[open];
4858
4859 if (close) {
4860 var n = str.indexOf(close, index);
4861 if (n !== -1) {
4862 index = n + 1;
4863 }
4864 }
4865
4866 if (str[index] === '!') {
4867 return true;
4868 }
4869 } else {
4870 index++;
4871 }
4872 }
4873 return false;
4874 };
4875
4876 isGlob = function isGlob(str, options) {
4877 if (typeof str !== 'string' || str === '') {
4878 return false;
4879 }
4880
4881 if (isExtglob(str)) {
4882 return true;
4883 }
4884
4885 var check = strictCheck;
4886
4887 // optionally relax check
4888 if (options && options.strict === false) {
4889 check = relaxedCheck;
4890 }
4891
4892 return check(str);
4893 };
4894 return isGlob;
4895}
4896
4897var globParent;
4898var hasRequiredGlobParent;
4899
4900function requireGlobParent () {
4901 if (hasRequiredGlobParent) return globParent;
4902 hasRequiredGlobParent = 1;
4903
4904 var isGlob = /*@__PURE__*/ requireIsGlob();
4905 var pathPosixDirname = require$$0$1.posix.dirname;
4906 var isWin32 = require$$2$1.platform() === 'win32';
4907
4908 var slash = '/';
4909 var backslash = /\\/g;
4910 var enclosure = /[\{\[].*[\}\]]$/;
4911 var globby = /(^|[^\\])([\{\[]|\([^\)]+$)/;
4912 var escaped = /\\([\!\*\?\|\[\]\(\)\{\}])/g;
4913
4914 /**
4915 * @param {string} str
4916 * @param {Object} opts
4917 * @param {boolean} [opts.flipBackslashes=true]
4918 * @returns {string}
4919 */
4920 globParent = function globParent(str, opts) {
4921 var options = Object.assign({ flipBackslashes: true }, opts);
4922
4923 // flip windows path separators
4924 if (options.flipBackslashes && isWin32 && str.indexOf(slash) < 0) {
4925 str = str.replace(backslash, slash);
4926 }
4927
4928 // special case for strings ending in enclosure containing path separator
4929 if (enclosure.test(str)) {
4930 str += slash;
4931 }
4932
4933 // preserves full path in case of trailing path separator
4934 str += 'a';
4935
4936 // remove path parts that are globby
4937 do {
4938 str = pathPosixDirname(str);
4939 } while (isGlob(str) || globby.test(str));
4940
4941 // remove escape chars and return result
4942 return str.replace(escaped, '$1');
4943 };
4944 return globParent;
4945}
4946
4947var utils = {};
4948
4949var hasRequiredUtils;
4950
4951function requireUtils () {
4952 if (hasRequiredUtils) return utils;
4953 hasRequiredUtils = 1;
4954 (function (exports) {
4955
4956 exports.isInteger = num => {
4957 if (typeof num === 'number') {
4958 return Number.isInteger(num);
4959 }
4960 if (typeof num === 'string' && num.trim() !== '') {
4961 return Number.isInteger(Number(num));
4962 }
4963 return false;
4964 };
4965
4966 /**
4967 * Find a node of the given type
4968 */
4969
4970 exports.find = (node, type) => node.nodes.find(node => node.type === type);
4971
4972 /**
4973 * Find a node of the given type
4974 */
4975
4976 exports.exceedsLimit = (min, max, step = 1, limit) => {
4977 if (limit === false) return false;
4978 if (!exports.isInteger(min) || !exports.isInteger(max)) return false;
4979 return ((Number(max) - Number(min)) / Number(step)) >= limit;
4980 };
4981
4982 /**
4983 * Escape the given node with '\\' before node.value
4984 */
4985
4986 exports.escapeNode = (block, n = 0, type) => {
4987 const node = block.nodes[n];
4988 if (!node) return;
4989
4990 if ((type && node.type === type) || node.type === 'open' || node.type === 'close') {
4991 if (node.escaped !== true) {
4992 node.value = '\\' + node.value;
4993 node.escaped = true;
4994 }
4995 }
4996 };
4997
4998 /**
4999 * Returns true if the given brace node should be enclosed in literal braces
5000 */
5001
5002 exports.encloseBrace = node => {
5003 if (node.type !== 'brace') return false;
5004 if ((node.commas >> 0 + node.ranges >> 0) === 0) {
5005 node.invalid = true;
5006 return true;
5007 }
5008 return false;
5009 };
5010
5011 /**
5012 * Returns true if a brace node is invalid.
5013 */
5014
5015 exports.isInvalidBrace = block => {
5016 if (block.type !== 'brace') return false;
5017 if (block.invalid === true || block.dollar) return true;
5018 if ((block.commas >> 0 + block.ranges >> 0) === 0) {
5019 block.invalid = true;
5020 return true;
5021 }
5022 if (block.open !== true || block.close !== true) {
5023 block.invalid = true;
5024 return true;
5025 }
5026 return false;
5027 };
5028
5029 /**
5030 * Returns true if a node is an open or close node
5031 */
5032
5033 exports.isOpenOrClose = node => {
5034 if (node.type === 'open' || node.type === 'close') {
5035 return true;
5036 }
5037 return node.open === true || node.close === true;
5038 };
5039
5040 /**
5041 * Reduce an array of text nodes.
5042 */
5043
5044 exports.reduce = nodes => nodes.reduce((acc, node) => {
5045 if (node.type === 'text') acc.push(node.value);
5046 if (node.type === 'range') node.type = 'text';
5047 return acc;
5048 }, []);
5049
5050 /**
5051 * Flatten an array
5052 */
5053
5054 exports.flatten = (...args) => {
5055 const result = [];
5056
5057 const flat = arr => {
5058 for (let i = 0; i < arr.length; i++) {
5059 const ele = arr[i];
5060
5061 if (Array.isArray(ele)) {
5062 flat(ele);
5063 continue;
5064 }
5065
5066 if (ele !== undefined) {
5067 result.push(ele);
5068 }
5069 }
5070 return result;
5071 };
5072
5073 flat(args);
5074 return result;
5075 };
5076 } (utils));
5077 return utils;
5078}
5079
5080var stringify;
5081var hasRequiredStringify;
5082
5083function requireStringify () {
5084 if (hasRequiredStringify) return stringify;
5085 hasRequiredStringify = 1;
5086
5087 const utils = /*@__PURE__*/ requireUtils();
5088
5089 stringify = (ast, options = {}) => {
5090 const stringify = (node, parent = {}) => {
5091 const invalidBlock = options.escapeInvalid && utils.isInvalidBrace(parent);
5092 const invalidNode = node.invalid === true && options.escapeInvalid === true;
5093 let output = '';
5094
5095 if (node.value) {
5096 if ((invalidBlock || invalidNode) && utils.isOpenOrClose(node)) {
5097 return '\\' + node.value;
5098 }
5099 return node.value;
5100 }
5101
5102 if (node.value) {
5103 return node.value;
5104 }
5105
5106 if (node.nodes) {
5107 for (const child of node.nodes) {
5108 output += stringify(child);
5109 }
5110 }
5111 return output;
5112 };
5113
5114 return stringify(ast);
5115 };
5116 return stringify;
5117}
5118
5119/*!
5120 * is-number <https://github.com/jonschlinkert/is-number>
5121 *
5122 * Copyright (c) 2014-present, Jon Schlinkert.
5123 * Released under the MIT License.
5124 */
5125
5126var isNumber;
5127var hasRequiredIsNumber;
5128
5129function requireIsNumber () {
5130 if (hasRequiredIsNumber) return isNumber;
5131 hasRequiredIsNumber = 1;
5132
5133 isNumber = function(num) {
5134 if (typeof num === 'number') {
5135 return num - num === 0;
5136 }
5137 if (typeof num === 'string' && num.trim() !== '') {
5138 return Number.isFinite ? Number.isFinite(+num) : isFinite(+num);
5139 }
5140 return false;
5141 };
5142 return isNumber;
5143}
5144
5145/*!
5146 * to-regex-range <https://github.com/micromatch/to-regex-range>
5147 *
5148 * Copyright (c) 2015-present, Jon Schlinkert.
5149 * Released under the MIT License.
5150 */
5151
5152var toRegexRange_1;
5153var hasRequiredToRegexRange;
5154
5155function requireToRegexRange () {
5156 if (hasRequiredToRegexRange) return toRegexRange_1;
5157 hasRequiredToRegexRange = 1;
5158
5159 const isNumber = /*@__PURE__*/ requireIsNumber();
5160
5161 const toRegexRange = (min, max, options) => {
5162 if (isNumber(min) === false) {
5163 throw new TypeError('toRegexRange: expected the first argument to be a number');
5164 }
5165
5166 if (max === undefined || min === max) {
5167 return String(min);
5168 }
5169
5170 if (isNumber(max) === false) {
5171 throw new TypeError('toRegexRange: expected the second argument to be a number.');
5172 }
5173
5174 let opts = { relaxZeros: true, ...options };
5175 if (typeof opts.strictZeros === 'boolean') {
5176 opts.relaxZeros = opts.strictZeros === false;
5177 }
5178
5179 let relax = String(opts.relaxZeros);
5180 let shorthand = String(opts.shorthand);
5181 let capture = String(opts.capture);
5182 let wrap = String(opts.wrap);
5183 let cacheKey = min + ':' + max + '=' + relax + shorthand + capture + wrap;
5184
5185 if (toRegexRange.cache.hasOwnProperty(cacheKey)) {
5186 return toRegexRange.cache[cacheKey].result;
5187 }
5188
5189 let a = Math.min(min, max);
5190 let b = Math.max(min, max);
5191
5192 if (Math.abs(a - b) === 1) {
5193 let result = min + '|' + max;
5194 if (opts.capture) {
5195 return `(${result})`;
5196 }
5197 if (opts.wrap === false) {
5198 return result;
5199 }
5200 return `(?:${result})`;
5201 }
5202
5203 let isPadded = hasPadding(min) || hasPadding(max);
5204 let state = { min, max, a, b };
5205 let positives = [];
5206 let negatives = [];
5207
5208 if (isPadded) {
5209 state.isPadded = isPadded;
5210 state.maxLen = String(state.max).length;
5211 }
5212
5213 if (a < 0) {
5214 let newMin = b < 0 ? Math.abs(b) : 1;
5215 negatives = splitToPatterns(newMin, Math.abs(a), state, opts);
5216 a = state.a = 0;
5217 }
5218
5219 if (b >= 0) {
5220 positives = splitToPatterns(a, b, state, opts);
5221 }
5222
5223 state.negatives = negatives;
5224 state.positives = positives;
5225 state.result = collatePatterns(negatives, positives);
5226
5227 if (opts.capture === true) {
5228 state.result = `(${state.result})`;
5229 } else if (opts.wrap !== false && (positives.length + negatives.length) > 1) {
5230 state.result = `(?:${state.result})`;
5231 }
5232
5233 toRegexRange.cache[cacheKey] = state;
5234 return state.result;
5235 };
5236
5237 function collatePatterns(neg, pos, options) {
5238 let onlyNegative = filterPatterns(neg, pos, '-', false) || [];
5239 let onlyPositive = filterPatterns(pos, neg, '', false) || [];
5240 let intersected = filterPatterns(neg, pos, '-?', true) || [];
5241 let subpatterns = onlyNegative.concat(intersected).concat(onlyPositive);
5242 return subpatterns.join('|');
5243 }
5244
5245 function splitToRanges(min, max) {
5246 let nines = 1;
5247 let zeros = 1;
5248
5249 let stop = countNines(min, nines);
5250 let stops = new Set([max]);
5251
5252 while (min <= stop && stop <= max) {
5253 stops.add(stop);
5254 nines += 1;
5255 stop = countNines(min, nines);
5256 }
5257
5258 stop = countZeros(max + 1, zeros) - 1;
5259
5260 while (min < stop && stop <= max) {
5261 stops.add(stop);
5262 zeros += 1;
5263 stop = countZeros(max + 1, zeros) - 1;
5264 }
5265
5266 stops = [...stops];
5267 stops.sort(compare);
5268 return stops;
5269 }
5270
5271 /**
5272 * Convert a range to a regex pattern
5273 * @param {Number} `start`
5274 * @param {Number} `stop`
5275 * @return {String}
5276 */
5277
5278 function rangeToPattern(start, stop, options) {
5279 if (start === stop) {
5280 return { pattern: start, count: [], digits: 0 };
5281 }
5282
5283 let zipped = zip(start, stop);
5284 let digits = zipped.length;
5285 let pattern = '';
5286 let count = 0;
5287
5288 for (let i = 0; i < digits; i++) {
5289 let [startDigit, stopDigit] = zipped[i];
5290
5291 if (startDigit === stopDigit) {
5292 pattern += startDigit;
5293
5294 } else if (startDigit !== '0' || stopDigit !== '9') {
5295 pattern += toCharacterClass(startDigit, stopDigit);
5296
5297 } else {
5298 count++;
5299 }
5300 }
5301
5302 if (count) {
5303 pattern += options.shorthand === true ? '\\d' : '[0-9]';
5304 }
5305
5306 return { pattern, count: [count], digits };
5307 }
5308
5309 function splitToPatterns(min, max, tok, options) {
5310 let ranges = splitToRanges(min, max);
5311 let tokens = [];
5312 let start = min;
5313 let prev;
5314
5315 for (let i = 0; i < ranges.length; i++) {
5316 let max = ranges[i];
5317 let obj = rangeToPattern(String(start), String(max), options);
5318 let zeros = '';
5319
5320 if (!tok.isPadded && prev && prev.pattern === obj.pattern) {
5321 if (prev.count.length > 1) {
5322 prev.count.pop();
5323 }
5324
5325 prev.count.push(obj.count[0]);
5326 prev.string = prev.pattern + toQuantifier(prev.count);
5327 start = max + 1;
5328 continue;
5329 }
5330
5331 if (tok.isPadded) {
5332 zeros = padZeros(max, tok, options);
5333 }
5334
5335 obj.string = zeros + obj.pattern + toQuantifier(obj.count);
5336 tokens.push(obj);
5337 start = max + 1;
5338 prev = obj;
5339 }
5340
5341 return tokens;
5342 }
5343
5344 function filterPatterns(arr, comparison, prefix, intersection, options) {
5345 let result = [];
5346
5347 for (let ele of arr) {
5348 let { string } = ele;
5349
5350 // only push if _both_ are negative...
5351 if (!intersection && !contains(comparison, 'string', string)) {
5352 result.push(prefix + string);
5353 }
5354
5355 // or _both_ are positive
5356 if (intersection && contains(comparison, 'string', string)) {
5357 result.push(prefix + string);
5358 }
5359 }
5360 return result;
5361 }
5362
5363 /**
5364 * Zip strings
5365 */
5366
5367 function zip(a, b) {
5368 let arr = [];
5369 for (let i = 0; i < a.length; i++) arr.push([a[i], b[i]]);
5370 return arr;
5371 }
5372
5373 function compare(a, b) {
5374 return a > b ? 1 : b > a ? -1 : 0;
5375 }
5376
5377 function contains(arr, key, val) {
5378 return arr.some(ele => ele[key] === val);
5379 }
5380
5381 function countNines(min, len) {
5382 return Number(String(min).slice(0, -len) + '9'.repeat(len));
5383 }
5384
5385 function countZeros(integer, zeros) {
5386 return integer - (integer % Math.pow(10, zeros));
5387 }
5388
5389 function toQuantifier(digits) {
5390 let [start = 0, stop = ''] = digits;
5391 if (stop || start > 1) {
5392 return `{${start + (stop ? ',' + stop : '')}}`;
5393 }
5394 return '';
5395 }
5396
5397 function toCharacterClass(a, b, options) {
5398 return `[${a}${(b - a === 1) ? '' : '-'}${b}]`;
5399 }
5400
5401 function hasPadding(str) {
5402 return /^-?(0+)\d/.test(str);
5403 }
5404
5405 function padZeros(value, tok, options) {
5406 if (!tok.isPadded) {
5407 return value;
5408 }
5409
5410 let diff = Math.abs(tok.maxLen - String(value).length);
5411 let relax = options.relaxZeros !== false;
5412
5413 switch (diff) {
5414 case 0:
5415 return '';
5416 case 1:
5417 return relax ? '0?' : '0';
5418 case 2:
5419 return relax ? '0{0,2}' : '00';
5420 default: {
5421 return relax ? `0{0,${diff}}` : `0{${diff}}`;
5422 }
5423 }
5424 }
5425
5426 /**
5427 * Cache
5428 */
5429
5430 toRegexRange.cache = {};
5431 toRegexRange.clearCache = () => (toRegexRange.cache = {});
5432
5433 /**
5434 * Expose `toRegexRange`
5435 */
5436
5437 toRegexRange_1 = toRegexRange;
5438 return toRegexRange_1;
5439}
5440
5441/*!
5442 * fill-range <https://github.com/jonschlinkert/fill-range>
5443 *
5444 * Copyright (c) 2014-present, Jon Schlinkert.
5445 * Licensed under the MIT License.
5446 */
5447
5448var fillRange;
5449var hasRequiredFillRange;
5450
5451function requireFillRange () {
5452 if (hasRequiredFillRange) return fillRange;
5453 hasRequiredFillRange = 1;
5454
5455 const util = require$$2;
5456 const toRegexRange = /*@__PURE__*/ requireToRegexRange();
5457
5458 const isObject = val => val !== null && typeof val === 'object' && !Array.isArray(val);
5459
5460 const transform = toNumber => {
5461 return value => toNumber === true ? Number(value) : String(value);
5462 };
5463
5464 const isValidValue = value => {
5465 return typeof value === 'number' || (typeof value === 'string' && value !== '');
5466 };
5467
5468 const isNumber = num => Number.isInteger(+num);
5469
5470 const zeros = input => {
5471 let value = `${input}`;
5472 let index = -1;
5473 if (value[0] === '-') value = value.slice(1);
5474 if (value === '0') return false;
5475 while (value[++index] === '0');
5476 return index > 0;
5477 };
5478
5479 const stringify = (start, end, options) => {
5480 if (typeof start === 'string' || typeof end === 'string') {
5481 return true;
5482 }
5483 return options.stringify === true;
5484 };
5485
5486 const pad = (input, maxLength, toNumber) => {
5487 if (maxLength > 0) {
5488 let dash = input[0] === '-' ? '-' : '';
5489 if (dash) input = input.slice(1);
5490 input = (dash + input.padStart(dash ? maxLength - 1 : maxLength, '0'));
5491 }
5492 if (toNumber === false) {
5493 return String(input);
5494 }
5495 return input;
5496 };
5497
5498 const toMaxLen = (input, maxLength) => {
5499 let negative = input[0] === '-' ? '-' : '';
5500 if (negative) {
5501 input = input.slice(1);
5502 maxLength--;
5503 }
5504 while (input.length < maxLength) input = '0' + input;
5505 return negative ? ('-' + input) : input;
5506 };
5507
5508 const toSequence = (parts, options, maxLen) => {
5509 parts.negatives.sort((a, b) => a < b ? -1 : a > b ? 1 : 0);
5510 parts.positives.sort((a, b) => a < b ? -1 : a > b ? 1 : 0);
5511
5512 let prefix = options.capture ? '' : '?:';
5513 let positives = '';
5514 let negatives = '';
5515 let result;
5516
5517 if (parts.positives.length) {
5518 positives = parts.positives.map(v => toMaxLen(String(v), maxLen)).join('|');
5519 }
5520
5521 if (parts.negatives.length) {
5522 negatives = `-(${prefix}${parts.negatives.map(v => toMaxLen(String(v), maxLen)).join('|')})`;
5523 }
5524
5525 if (positives && negatives) {
5526 result = `${positives}|${negatives}`;
5527 } else {
5528 result = positives || negatives;
5529 }
5530
5531 if (options.wrap) {
5532 return `(${prefix}${result})`;
5533 }
5534
5535 return result;
5536 };
5537
5538 const toRange = (a, b, isNumbers, options) => {
5539 if (isNumbers) {
5540 return toRegexRange(a, b, { wrap: false, ...options });
5541 }
5542
5543 let start = String.fromCharCode(a);
5544 if (a === b) return start;
5545
5546 let stop = String.fromCharCode(b);
5547 return `[${start}-${stop}]`;
5548 };
5549
5550 const toRegex = (start, end, options) => {
5551 if (Array.isArray(start)) {
5552 let wrap = options.wrap === true;
5553 let prefix = options.capture ? '' : '?:';
5554 return wrap ? `(${prefix}${start.join('|')})` : start.join('|');
5555 }
5556 return toRegexRange(start, end, options);
5557 };
5558
5559 const rangeError = (...args) => {
5560 return new RangeError('Invalid range arguments: ' + util.inspect(...args));
5561 };
5562
5563 const invalidRange = (start, end, options) => {
5564 if (options.strictRanges === true) throw rangeError([start, end]);
5565 return [];
5566 };
5567
5568 const invalidStep = (step, options) => {
5569 if (options.strictRanges === true) {
5570 throw new TypeError(`Expected step "${step}" to be a number`);
5571 }
5572 return [];
5573 };
5574
5575 const fillNumbers = (start, end, step = 1, options = {}) => {
5576 let a = Number(start);
5577 let b = Number(end);
5578
5579 if (!Number.isInteger(a) || !Number.isInteger(b)) {
5580 if (options.strictRanges === true) throw rangeError([start, end]);
5581 return [];
5582 }
5583
5584 // fix negative zero
5585 if (a === 0) a = 0;
5586 if (b === 0) b = 0;
5587
5588 let descending = a > b;
5589 let startString = String(start);
5590 let endString = String(end);
5591 let stepString = String(step);
5592 step = Math.max(Math.abs(step), 1);
5593
5594 let padded = zeros(startString) || zeros(endString) || zeros(stepString);
5595 let maxLen = padded ? Math.max(startString.length, endString.length, stepString.length) : 0;
5596 let toNumber = padded === false && stringify(start, end, options) === false;
5597 let format = options.transform || transform(toNumber);
5598
5599 if (options.toRegex && step === 1) {
5600 return toRange(toMaxLen(start, maxLen), toMaxLen(end, maxLen), true, options);
5601 }
5602
5603 let parts = { negatives: [], positives: [] };
5604 let push = num => parts[num < 0 ? 'negatives' : 'positives'].push(Math.abs(num));
5605 let range = [];
5606 let index = 0;
5607
5608 while (descending ? a >= b : a <= b) {
5609 if (options.toRegex === true && step > 1) {
5610 push(a);
5611 } else {
5612 range.push(pad(format(a, index), maxLen, toNumber));
5613 }
5614 a = descending ? a - step : a + step;
5615 index++;
5616 }
5617
5618 if (options.toRegex === true) {
5619 return step > 1
5620 ? toSequence(parts, options, maxLen)
5621 : toRegex(range, null, { wrap: false, ...options });
5622 }
5623
5624 return range;
5625 };
5626
5627 const fillLetters = (start, end, step = 1, options = {}) => {
5628 if ((!isNumber(start) && start.length > 1) || (!isNumber(end) && end.length > 1)) {
5629 return invalidRange(start, end, options);
5630 }
5631
5632 let format = options.transform || (val => String.fromCharCode(val));
5633 let a = `${start}`.charCodeAt(0);
5634 let b = `${end}`.charCodeAt(0);
5635
5636 let descending = a > b;
5637 let min = Math.min(a, b);
5638 let max = Math.max(a, b);
5639
5640 if (options.toRegex && step === 1) {
5641 return toRange(min, max, false, options);
5642 }
5643
5644 let range = [];
5645 let index = 0;
5646
5647 while (descending ? a >= b : a <= b) {
5648 range.push(format(a, index));
5649 a = descending ? a - step : a + step;
5650 index++;
5651 }
5652
5653 if (options.toRegex === true) {
5654 return toRegex(range, null, { wrap: false, options });
5655 }
5656
5657 return range;
5658 };
5659
5660 const fill = (start, end, step, options = {}) => {
5661 if (end == null && isValidValue(start)) {
5662 return [start];
5663 }
5664
5665 if (!isValidValue(start) || !isValidValue(end)) {
5666 return invalidRange(start, end, options);
5667 }
5668
5669 if (typeof step === 'function') {
5670 return fill(start, end, 1, { transform: step });
5671 }
5672
5673 if (isObject(step)) {
5674 return fill(start, end, 0, step);
5675 }
5676
5677 let opts = { ...options };
5678 if (opts.capture === true) opts.wrap = true;
5679 step = step || opts.step || 1;
5680
5681 if (!isNumber(step)) {
5682 if (step != null && !isObject(step)) return invalidStep(step, opts);
5683 return fill(start, end, 1, step);
5684 }
5685
5686 if (isNumber(start) && isNumber(end)) {
5687 return fillNumbers(start, end, step, opts);
5688 }
5689
5690 return fillLetters(start, end, Math.max(Math.abs(step), 1), opts);
5691 };
5692
5693 fillRange = fill;
5694 return fillRange;
5695}
5696
5697var compile_1;
5698var hasRequiredCompile;
5699
5700function requireCompile () {
5701 if (hasRequiredCompile) return compile_1;
5702 hasRequiredCompile = 1;
5703
5704 const fill = /*@__PURE__*/ requireFillRange();
5705 const utils = /*@__PURE__*/ requireUtils();
5706
5707 const compile = (ast, options = {}) => {
5708 const walk = (node, parent = {}) => {
5709 const invalidBlock = utils.isInvalidBrace(parent);
5710 const invalidNode = node.invalid === true && options.escapeInvalid === true;
5711 const invalid = invalidBlock === true || invalidNode === true;
5712 const prefix = options.escapeInvalid === true ? '\\' : '';
5713 let output = '';
5714
5715 if (node.isOpen === true) {
5716 return prefix + node.value;
5717 }
5718
5719 if (node.isClose === true) {
5720 console.log('node.isClose', prefix, node.value);
5721 return prefix + node.value;
5722 }
5723
5724 if (node.type === 'open') {
5725 return invalid ? prefix + node.value : '(';
5726 }
5727
5728 if (node.type === 'close') {
5729 return invalid ? prefix + node.value : ')';
5730 }
5731
5732 if (node.type === 'comma') {
5733 return node.prev.type === 'comma' ? '' : invalid ? node.value : '|';
5734 }
5735
5736 if (node.value) {
5737 return node.value;
5738 }
5739
5740 if (node.nodes && node.ranges > 0) {
5741 const args = utils.reduce(node.nodes);
5742 const range = fill(...args, { ...options, wrap: false, toRegex: true, strictZeros: true });
5743
5744 if (range.length !== 0) {
5745 return args.length > 1 && range.length > 1 ? `(${range})` : range;
5746 }
5747 }
5748
5749 if (node.nodes) {
5750 for (const child of node.nodes) {
5751 output += walk(child, node);
5752 }
5753 }
5754
5755 return output;
5756 };
5757
5758 return walk(ast);
5759 };
5760
5761 compile_1 = compile;
5762 return compile_1;
5763}
5764
5765var expand_1;
5766var hasRequiredExpand;
5767
5768function requireExpand () {
5769 if (hasRequiredExpand) return expand_1;
5770 hasRequiredExpand = 1;
5771
5772 const fill = /*@__PURE__*/ requireFillRange();
5773 const stringify = /*@__PURE__*/ requireStringify();
5774 const utils = /*@__PURE__*/ requireUtils();
5775
5776 const append = (queue = '', stash = '', enclose = false) => {
5777 const result = [];
5778
5779 queue = [].concat(queue);
5780 stash = [].concat(stash);
5781
5782 if (!stash.length) return queue;
5783 if (!queue.length) {
5784 return enclose ? utils.flatten(stash).map(ele => `{${ele}}`) : stash;
5785 }
5786
5787 for (const item of queue) {
5788 if (Array.isArray(item)) {
5789 for (const value of item) {
5790 result.push(append(value, stash, enclose));
5791 }
5792 } else {
5793 for (let ele of stash) {
5794 if (enclose === true && typeof ele === 'string') ele = `{${ele}}`;
5795 result.push(Array.isArray(ele) ? append(item, ele, enclose) : item + ele);
5796 }
5797 }
5798 }
5799 return utils.flatten(result);
5800 };
5801
5802 const expand = (ast, options = {}) => {
5803 const rangeLimit = options.rangeLimit === undefined ? 1000 : options.rangeLimit;
5804
5805 const walk = (node, parent = {}) => {
5806 node.queue = [];
5807
5808 let p = parent;
5809 let q = parent.queue;
5810
5811 while (p.type !== 'brace' && p.type !== 'root' && p.parent) {
5812 p = p.parent;
5813 q = p.queue;
5814 }
5815
5816 if (node.invalid || node.dollar) {
5817 q.push(append(q.pop(), stringify(node, options)));
5818 return;
5819 }
5820
5821 if (node.type === 'brace' && node.invalid !== true && node.nodes.length === 2) {
5822 q.push(append(q.pop(), ['{}']));
5823 return;
5824 }
5825
5826 if (node.nodes && node.ranges > 0) {
5827 const args = utils.reduce(node.nodes);
5828
5829 if (utils.exceedsLimit(...args, options.step, rangeLimit)) {
5830 throw new RangeError('expanded array length exceeds range limit. Use options.rangeLimit to increase or disable the limit.');
5831 }
5832
5833 let range = fill(...args, options);
5834 if (range.length === 0) {
5835 range = stringify(node, options);
5836 }
5837
5838 q.push(append(q.pop(), range));
5839 node.nodes = [];
5840 return;
5841 }
5842
5843 const enclose = utils.encloseBrace(node);
5844 let queue = node.queue;
5845 let block = node;
5846
5847 while (block.type !== 'brace' && block.type !== 'root' && block.parent) {
5848 block = block.parent;
5849 queue = block.queue;
5850 }
5851
5852 for (let i = 0; i < node.nodes.length; i++) {
5853 const child = node.nodes[i];
5854
5855 if (child.type === 'comma' && node.type === 'brace') {
5856 if (i === 1) queue.push('');
5857 queue.push('');
5858 continue;
5859 }
5860
5861 if (child.type === 'close') {
5862 q.push(append(q.pop(), queue, enclose));
5863 continue;
5864 }
5865
5866 if (child.value && child.type !== 'open') {
5867 queue.push(append(queue.pop(), child.value));
5868 continue;
5869 }
5870
5871 if (child.nodes) {
5872 walk(child, node);
5873 }
5874 }
5875
5876 return queue;
5877 };
5878
5879 return utils.flatten(walk(ast));
5880 };
5881
5882 expand_1 = expand;
5883 return expand_1;
5884}
5885
5886var constants$1;
5887var hasRequiredConstants$1;
5888
5889function requireConstants$1 () {
5890 if (hasRequiredConstants$1) return constants$1;
5891 hasRequiredConstants$1 = 1;
5892
5893 constants$1 = {
5894 MAX_LENGTH: 10000,
5895
5896 // Digits
5897 CHAR_0: '0', /* 0 */
5898 CHAR_9: '9', /* 9 */
5899
5900 // Alphabet chars.
5901 CHAR_UPPERCASE_A: 'A', /* A */
5902 CHAR_LOWERCASE_A: 'a', /* a */
5903 CHAR_UPPERCASE_Z: 'Z', /* Z */
5904 CHAR_LOWERCASE_Z: 'z', /* z */
5905
5906 CHAR_LEFT_PARENTHESES: '(', /* ( */
5907 CHAR_RIGHT_PARENTHESES: ')', /* ) */
5908
5909 CHAR_ASTERISK: '*', /* * */
5910
5911 // Non-alphabetic chars.
5912 CHAR_AMPERSAND: '&', /* & */
5913 CHAR_AT: '@', /* @ */
5914 CHAR_BACKSLASH: '\\', /* \ */
5915 CHAR_BACKTICK: '`', /* ` */
5916 CHAR_CARRIAGE_RETURN: '\r', /* \r */
5917 CHAR_CIRCUMFLEX_ACCENT: '^', /* ^ */
5918 CHAR_COLON: ':', /* : */
5919 CHAR_COMMA: ',', /* , */
5920 CHAR_DOLLAR: '$', /* . */
5921 CHAR_DOT: '.', /* . */
5922 CHAR_DOUBLE_QUOTE: '"', /* " */
5923 CHAR_EQUAL: '=', /* = */
5924 CHAR_EXCLAMATION_MARK: '!', /* ! */
5925 CHAR_FORM_FEED: '\f', /* \f */
5926 CHAR_FORWARD_SLASH: '/', /* / */
5927 CHAR_HASH: '#', /* # */
5928 CHAR_HYPHEN_MINUS: '-', /* - */
5929 CHAR_LEFT_ANGLE_BRACKET: '<', /* < */
5930 CHAR_LEFT_CURLY_BRACE: '{', /* { */
5931 CHAR_LEFT_SQUARE_BRACKET: '[', /* [ */
5932 CHAR_LINE_FEED: '\n', /* \n */
5933 CHAR_NO_BREAK_SPACE: '\u00A0', /* \u00A0 */
5934 CHAR_PERCENT: '%', /* % */
5935 CHAR_PLUS: '+', /* + */
5936 CHAR_QUESTION_MARK: '?', /* ? */
5937 CHAR_RIGHT_ANGLE_BRACKET: '>', /* > */
5938 CHAR_RIGHT_CURLY_BRACE: '}', /* } */
5939 CHAR_RIGHT_SQUARE_BRACKET: ']', /* ] */
5940 CHAR_SEMICOLON: ';', /* ; */
5941 CHAR_SINGLE_QUOTE: '\'', /* ' */
5942 CHAR_SPACE: ' ', /* */
5943 CHAR_TAB: '\t', /* \t */
5944 CHAR_UNDERSCORE: '_', /* _ */
5945 CHAR_VERTICAL_LINE: '|', /* | */
5946 CHAR_ZERO_WIDTH_NOBREAK_SPACE: '\uFEFF' /* \uFEFF */
5947 };
5948 return constants$1;
5949}
5950
5951var parse_1;
5952var hasRequiredParse;
5953
5954function requireParse () {
5955 if (hasRequiredParse) return parse_1;
5956 hasRequiredParse = 1;
5957
5958 const stringify = /*@__PURE__*/ requireStringify();
5959
5960 /**
5961 * Constants
5962 */
5963
5964 const {
5965 MAX_LENGTH,
5966 CHAR_BACKSLASH, /* \ */
5967 CHAR_BACKTICK, /* ` */
5968 CHAR_COMMA, /* , */
5969 CHAR_DOT, /* . */
5970 CHAR_LEFT_PARENTHESES, /* ( */
5971 CHAR_RIGHT_PARENTHESES, /* ) */
5972 CHAR_LEFT_CURLY_BRACE, /* { */
5973 CHAR_RIGHT_CURLY_BRACE, /* } */
5974 CHAR_LEFT_SQUARE_BRACKET, /* [ */
5975 CHAR_RIGHT_SQUARE_BRACKET, /* ] */
5976 CHAR_DOUBLE_QUOTE, /* " */
5977 CHAR_SINGLE_QUOTE, /* ' */
5978 CHAR_NO_BREAK_SPACE,
5979 CHAR_ZERO_WIDTH_NOBREAK_SPACE
5980 } = /*@__PURE__*/ requireConstants$1();
5981
5982 /**
5983 * parse
5984 */
5985
5986 const parse = (input, options = {}) => {
5987 if (typeof input !== 'string') {
5988 throw new TypeError('Expected a string');
5989 }
5990
5991 const opts = options || {};
5992 const max = typeof opts.maxLength === 'number' ? Math.min(MAX_LENGTH, opts.maxLength) : MAX_LENGTH;
5993 if (input.length > max) {
5994 throw new SyntaxError(`Input length (${input.length}), exceeds max characters (${max})`);
5995 }
5996
5997 const ast = { type: 'root', input, nodes: [] };
5998 const stack = [ast];
5999 let block = ast;
6000 let prev = ast;
6001 let brackets = 0;
6002 const length = input.length;
6003 let index = 0;
6004 let depth = 0;
6005 let value;
6006
6007 /**
6008 * Helpers
6009 */
6010
6011 const advance = () => input[index++];
6012 const push = node => {
6013 if (node.type === 'text' && prev.type === 'dot') {
6014 prev.type = 'text';
6015 }
6016
6017 if (prev && prev.type === 'text' && node.type === 'text') {
6018 prev.value += node.value;
6019 return;
6020 }
6021
6022 block.nodes.push(node);
6023 node.parent = block;
6024 node.prev = prev;
6025 prev = node;
6026 return node;
6027 };
6028
6029 push({ type: 'bos' });
6030
6031 while (index < length) {
6032 block = stack[stack.length - 1];
6033 value = advance();
6034
6035 /**
6036 * Invalid chars
6037 */
6038
6039 if (value === CHAR_ZERO_WIDTH_NOBREAK_SPACE || value === CHAR_NO_BREAK_SPACE) {
6040 continue;
6041 }
6042
6043 /**
6044 * Escaped chars
6045 */
6046
6047 if (value === CHAR_BACKSLASH) {
6048 push({ type: 'text', value: (options.keepEscaping ? value : '') + advance() });
6049 continue;
6050 }
6051
6052 /**
6053 * Right square bracket (literal): ']'
6054 */
6055
6056 if (value === CHAR_RIGHT_SQUARE_BRACKET) {
6057 push({ type: 'text', value: '\\' + value });
6058 continue;
6059 }
6060
6061 /**
6062 * Left square bracket: '['
6063 */
6064
6065 if (value === CHAR_LEFT_SQUARE_BRACKET) {
6066 brackets++;
6067
6068 let next;
6069
6070 while (index < length && (next = advance())) {
6071 value += next;
6072
6073 if (next === CHAR_LEFT_SQUARE_BRACKET) {
6074 brackets++;
6075 continue;
6076 }
6077
6078 if (next === CHAR_BACKSLASH) {
6079 value += advance();
6080 continue;
6081 }
6082
6083 if (next === CHAR_RIGHT_SQUARE_BRACKET) {
6084 brackets--;
6085
6086 if (brackets === 0) {
6087 break;
6088 }
6089 }
6090 }
6091
6092 push({ type: 'text', value });
6093 continue;
6094 }
6095
6096 /**
6097 * Parentheses
6098 */
6099
6100 if (value === CHAR_LEFT_PARENTHESES) {
6101 block = push({ type: 'paren', nodes: [] });
6102 stack.push(block);
6103 push({ type: 'text', value });
6104 continue;
6105 }
6106
6107 if (value === CHAR_RIGHT_PARENTHESES) {
6108 if (block.type !== 'paren') {
6109 push({ type: 'text', value });
6110 continue;
6111 }
6112 block = stack.pop();
6113 push({ type: 'text', value });
6114 block = stack[stack.length - 1];
6115 continue;
6116 }
6117
6118 /**
6119 * Quotes: '|"|`
6120 */
6121
6122 if (value === CHAR_DOUBLE_QUOTE || value === CHAR_SINGLE_QUOTE || value === CHAR_BACKTICK) {
6123 const open = value;
6124 let next;
6125
6126 if (options.keepQuotes !== true) {
6127 value = '';
6128 }
6129
6130 while (index < length && (next = advance())) {
6131 if (next === CHAR_BACKSLASH) {
6132 value += next + advance();
6133 continue;
6134 }
6135
6136 if (next === open) {
6137 if (options.keepQuotes === true) value += next;
6138 break;
6139 }
6140
6141 value += next;
6142 }
6143
6144 push({ type: 'text', value });
6145 continue;
6146 }
6147
6148 /**
6149 * Left curly brace: '{'
6150 */
6151
6152 if (value === CHAR_LEFT_CURLY_BRACE) {
6153 depth++;
6154
6155 const dollar = prev.value && prev.value.slice(-1) === '$' || block.dollar === true;
6156 const brace = {
6157 type: 'brace',
6158 open: true,
6159 close: false,
6160 dollar,
6161 depth,
6162 commas: 0,
6163 ranges: 0,
6164 nodes: []
6165 };
6166
6167 block = push(brace);
6168 stack.push(block);
6169 push({ type: 'open', value });
6170 continue;
6171 }
6172
6173 /**
6174 * Right curly brace: '}'
6175 */
6176
6177 if (value === CHAR_RIGHT_CURLY_BRACE) {
6178 if (block.type !== 'brace') {
6179 push({ type: 'text', value });
6180 continue;
6181 }
6182
6183 const type = 'close';
6184 block = stack.pop();
6185 block.close = true;
6186
6187 push({ type, value });
6188 depth--;
6189
6190 block = stack[stack.length - 1];
6191 continue;
6192 }
6193
6194 /**
6195 * Comma: ','
6196 */
6197
6198 if (value === CHAR_COMMA && depth > 0) {
6199 if (block.ranges > 0) {
6200 block.ranges = 0;
6201 const open = block.nodes.shift();
6202 block.nodes = [open, { type: 'text', value: stringify(block) }];
6203 }
6204
6205 push({ type: 'comma', value });
6206 block.commas++;
6207 continue;
6208 }
6209
6210 /**
6211 * Dot: '.'
6212 */
6213
6214 if (value === CHAR_DOT && depth > 0 && block.commas === 0) {
6215 const siblings = block.nodes;
6216
6217 if (depth === 0 || siblings.length === 0) {
6218 push({ type: 'text', value });
6219 continue;
6220 }
6221
6222 if (prev.type === 'dot') {
6223 block.range = [];
6224 prev.value += value;
6225 prev.type = 'range';
6226
6227 if (block.nodes.length !== 3 && block.nodes.length !== 5) {
6228 block.invalid = true;
6229 block.ranges = 0;
6230 prev.type = 'text';
6231 continue;
6232 }
6233
6234 block.ranges++;
6235 block.args = [];
6236 continue;
6237 }
6238
6239 if (prev.type === 'range') {
6240 siblings.pop();
6241
6242 const before = siblings[siblings.length - 1];
6243 before.value += prev.value + value;
6244 prev = before;
6245 block.ranges--;
6246 continue;
6247 }
6248
6249 push({ type: 'dot', value });
6250 continue;
6251 }
6252
6253 /**
6254 * Text
6255 */
6256
6257 push({ type: 'text', value });
6258 }
6259
6260 // Mark imbalanced braces and brackets as invalid
6261 do {
6262 block = stack.pop();
6263
6264 if (block.type !== 'root') {
6265 block.nodes.forEach(node => {
6266 if (!node.nodes) {
6267 if (node.type === 'open') node.isOpen = true;
6268 if (node.type === 'close') node.isClose = true;
6269 if (!node.nodes) node.type = 'text';
6270 node.invalid = true;
6271 }
6272 });
6273
6274 // get the location of the block on parent.nodes (block's siblings)
6275 const parent = stack[stack.length - 1];
6276 const index = parent.nodes.indexOf(block);
6277 // replace the (invalid) block with it's nodes
6278 parent.nodes.splice(index, 1, ...block.nodes);
6279 }
6280 } while (stack.length > 0);
6281
6282 push({ type: 'eos' });
6283 return ast;
6284 };
6285
6286 parse_1 = parse;
6287 return parse_1;
6288}
6289
6290var braces_1;
6291var hasRequiredBraces;
6292
6293function requireBraces () {
6294 if (hasRequiredBraces) return braces_1;
6295 hasRequiredBraces = 1;
6296
6297 const stringify = /*@__PURE__*/ requireStringify();
6298 const compile = /*@__PURE__*/ requireCompile();
6299 const expand = /*@__PURE__*/ requireExpand();
6300 const parse = /*@__PURE__*/ requireParse();
6301
6302 /**
6303 * Expand the given pattern or create a regex-compatible string.
6304 *
6305 * ```js
6306 * const braces = require('braces');
6307 * console.log(braces('{a,b,c}', { compile: true })); //=> ['(a|b|c)']
6308 * console.log(braces('{a,b,c}')); //=> ['a', 'b', 'c']
6309 * ```
6310 * @param {String} `str`
6311 * @param {Object} `options`
6312 * @return {String}
6313 * @api public
6314 */
6315
6316 const braces = (input, options = {}) => {
6317 let output = [];
6318
6319 if (Array.isArray(input)) {
6320 for (const pattern of input) {
6321 const result = braces.create(pattern, options);
6322 if (Array.isArray(result)) {
6323 output.push(...result);
6324 } else {
6325 output.push(result);
6326 }
6327 }
6328 } else {
6329 output = [].concat(braces.create(input, options));
6330 }
6331
6332 if (options && options.expand === true && options.nodupes === true) {
6333 output = [...new Set(output)];
6334 }
6335 return output;
6336 };
6337
6338 /**
6339 * Parse the given `str` with the given `options`.
6340 *
6341 * ```js
6342 * // braces.parse(pattern, [, options]);
6343 * const ast = braces.parse('a/{b,c}/d');
6344 * console.log(ast);
6345 * ```
6346 * @param {String} pattern Brace pattern to parse
6347 * @param {Object} options
6348 * @return {Object} Returns an AST
6349 * @api public
6350 */
6351
6352 braces.parse = (input, options = {}) => parse(input, options);
6353
6354 /**
6355 * Creates a braces string from an AST, or an AST node.
6356 *
6357 * ```js
6358 * const braces = require('braces');
6359 * let ast = braces.parse('foo/{a,b}/bar');
6360 * console.log(stringify(ast.nodes[2])); //=> '{a,b}'
6361 * ```
6362 * @param {String} `input` Brace pattern or AST.
6363 * @param {Object} `options`
6364 * @return {Array} Returns an array of expanded values.
6365 * @api public
6366 */
6367
6368 braces.stringify = (input, options = {}) => {
6369 if (typeof input === 'string') {
6370 return stringify(braces.parse(input, options), options);
6371 }
6372 return stringify(input, options);
6373 };
6374
6375 /**
6376 * Compiles a brace pattern into a regex-compatible, optimized string.
6377 * This method is called by the main [braces](#braces) function by default.
6378 *
6379 * ```js
6380 * const braces = require('braces');
6381 * console.log(braces.compile('a/{b,c}/d'));
6382 * //=> ['a/(b|c)/d']
6383 * ```
6384 * @param {String} `input` Brace pattern or AST.
6385 * @param {Object} `options`
6386 * @return {Array} Returns an array of expanded values.
6387 * @api public
6388 */
6389
6390 braces.compile = (input, options = {}) => {
6391 if (typeof input === 'string') {
6392 input = braces.parse(input, options);
6393 }
6394 return compile(input, options);
6395 };
6396
6397 /**
6398 * Expands a brace pattern into an array. This method is called by the
6399 * main [braces](#braces) function when `options.expand` is true. Before
6400 * using this method it's recommended that you read the [performance notes](#performance))
6401 * and advantages of using [.compile](#compile) instead.
6402 *
6403 * ```js
6404 * const braces = require('braces');
6405 * console.log(braces.expand('a/{b,c}/d'));
6406 * //=> ['a/b/d', 'a/c/d'];
6407 * ```
6408 * @param {String} `pattern` Brace pattern
6409 * @param {Object} `options`
6410 * @return {Array} Returns an array of expanded values.
6411 * @api public
6412 */
6413
6414 braces.expand = (input, options = {}) => {
6415 if (typeof input === 'string') {
6416 input = braces.parse(input, options);
6417 }
6418
6419 let result = expand(input, options);
6420
6421 // filter out empty strings if specified
6422 if (options.noempty === true) {
6423 result = result.filter(Boolean);
6424 }
6425
6426 // filter out duplicates if specified
6427 if (options.nodupes === true) {
6428 result = [...new Set(result)];
6429 }
6430
6431 return result;
6432 };
6433
6434 /**
6435 * Processes a brace pattern and returns either an expanded array
6436 * (if `options.expand` is true), a highly optimized regex-compatible string.
6437 * This method is called by the main [braces](#braces) function.
6438 *
6439 * ```js
6440 * const braces = require('braces');
6441 * console.log(braces.create('user-{200..300}/project-{a,b,c}-{1..10}'))
6442 * //=> 'user-(20[0-9]|2[1-9][0-9]|300)/project-(a|b|c)-([1-9]|10)'
6443 * ```
6444 * @param {String} `pattern` Brace pattern
6445 * @param {Object} `options`
6446 * @return {Array} Returns an array of expanded values.
6447 * @api public
6448 */
6449
6450 braces.create = (input, options = {}) => {
6451 if (input === '' || input.length < 3) {
6452 return [input];
6453 }
6454
6455 return options.expand !== true
6456 ? braces.compile(input, options)
6457 : braces.expand(input, options);
6458 };
6459
6460 /**
6461 * Expose "braces"
6462 */
6463
6464 braces_1 = braces;
6465 return braces_1;
6466}
6467
6468const require$$0 = [
6469 "3dm",
6470 "3ds",
6471 "3g2",
6472 "3gp",
6473 "7z",
6474 "a",
6475 "aac",
6476 "adp",
6477 "afdesign",
6478 "afphoto",
6479 "afpub",
6480 "ai",
6481 "aif",
6482 "aiff",
6483 "alz",
6484 "ape",
6485 "apk",
6486 "appimage",
6487 "ar",
6488 "arj",
6489 "asf",
6490 "au",
6491 "avi",
6492 "bak",
6493 "baml",
6494 "bh",
6495 "bin",
6496 "bk",
6497 "bmp",
6498 "btif",
6499 "bz2",
6500 "bzip2",
6501 "cab",
6502 "caf",
6503 "cgm",
6504 "class",
6505 "cmx",
6506 "cpio",
6507 "cr2",
6508 "cur",
6509 "dat",
6510 "dcm",
6511 "deb",
6512 "dex",
6513 "djvu",
6514 "dll",
6515 "dmg",
6516 "dng",
6517 "doc",
6518 "docm",
6519 "docx",
6520 "dot",
6521 "dotm",
6522 "dra",
6523 "DS_Store",
6524 "dsk",
6525 "dts",
6526 "dtshd",
6527 "dvb",
6528 "dwg",
6529 "dxf",
6530 "ecelp4800",
6531 "ecelp7470",
6532 "ecelp9600",
6533 "egg",
6534 "eol",
6535 "eot",
6536 "epub",
6537 "exe",
6538 "f4v",
6539 "fbs",
6540 "fh",
6541 "fla",
6542 "flac",
6543 "flatpak",
6544 "fli",
6545 "flv",
6546 "fpx",
6547 "fst",
6548 "fvt",
6549 "g3",
6550 "gh",
6551 "gif",
6552 "graffle",
6553 "gz",
6554 "gzip",
6555 "h261",
6556 "h263",
6557 "h264",
6558 "icns",
6559 "ico",
6560 "ief",
6561 "img",
6562 "ipa",
6563 "iso",
6564 "jar",
6565 "jpeg",
6566 "jpg",
6567 "jpgv",
6568 "jpm",
6569 "jxr",
6570 "key",
6571 "ktx",
6572 "lha",
6573 "lib",
6574 "lvp",
6575 "lz",
6576 "lzh",
6577 "lzma",
6578 "lzo",
6579 "m3u",
6580 "m4a",
6581 "m4v",
6582 "mar",
6583 "mdi",
6584 "mht",
6585 "mid",
6586 "midi",
6587 "mj2",
6588 "mka",
6589 "mkv",
6590 "mmr",
6591 "mng",
6592 "mobi",
6593 "mov",
6594 "movie",
6595 "mp3",
6596 "mp4",
6597 "mp4a",
6598 "mpeg",
6599 "mpg",
6600 "mpga",
6601 "mxu",
6602 "nef",
6603 "npx",
6604 "numbers",
6605 "nupkg",
6606 "o",
6607 "odp",
6608 "ods",
6609 "odt",
6610 "oga",
6611 "ogg",
6612 "ogv",
6613 "otf",
6614 "ott",
6615 "pages",
6616 "pbm",
6617 "pcx",
6618 "pdb",
6619 "pdf",
6620 "pea",
6621 "pgm",
6622 "pic",
6623 "png",
6624 "pnm",
6625 "pot",
6626 "potm",
6627 "potx",
6628 "ppa",
6629 "ppam",
6630 "ppm",
6631 "pps",
6632 "ppsm",
6633 "ppsx",
6634 "ppt",
6635 "pptm",
6636 "pptx",
6637 "psd",
6638 "pya",
6639 "pyc",
6640 "pyo",
6641 "pyv",
6642 "qt",
6643 "rar",
6644 "ras",
6645 "raw",
6646 "resources",
6647 "rgb",
6648 "rip",
6649 "rlc",
6650 "rmf",
6651 "rmvb",
6652 "rpm",
6653 "rtf",
6654 "rz",
6655 "s3m",
6656 "s7z",
6657 "scpt",
6658 "sgi",
6659 "shar",
6660 "snap",
6661 "sil",
6662 "sketch",
6663 "slk",
6664 "smv",
6665 "snk",
6666 "so",
6667 "stl",
6668 "suo",
6669 "sub",
6670 "swf",
6671 "tar",
6672 "tbz",
6673 "tbz2",
6674 "tga",
6675 "tgz",
6676 "thmx",
6677 "tif",
6678 "tiff",
6679 "tlz",
6680 "ttc",
6681 "ttf",
6682 "txz",
6683 "udf",
6684 "uvh",
6685 "uvi",
6686 "uvm",
6687 "uvp",
6688 "uvs",
6689 "uvu",
6690 "viv",
6691 "vob",
6692 "war",
6693 "wav",
6694 "wax",
6695 "wbmp",
6696 "wdp",
6697 "weba",
6698 "webm",
6699 "webp",
6700 "whl",
6701 "wim",
6702 "wm",
6703 "wma",
6704 "wmv",
6705 "wmx",
6706 "woff",
6707 "woff2",
6708 "wrm",
6709 "wvx",
6710 "xbm",
6711 "xif",
6712 "xla",
6713 "xlam",
6714 "xls",
6715 "xlsb",
6716 "xlsm",
6717 "xlsx",
6718 "xlt",
6719 "xltm",
6720 "xltx",
6721 "xm",
6722 "xmind",
6723 "xpi",
6724 "xpm",
6725 "xwd",
6726 "xz",
6727 "z",
6728 "zip",
6729 "zipx"
6730];
6731
6732var binaryExtensions;
6733var hasRequiredBinaryExtensions;
6734
6735function requireBinaryExtensions () {
6736 if (hasRequiredBinaryExtensions) return binaryExtensions;
6737 hasRequiredBinaryExtensions = 1;
6738 binaryExtensions = require$$0;
6739 return binaryExtensions;
6740}
6741
6742var isBinaryPath;
6743var hasRequiredIsBinaryPath;
6744
6745function requireIsBinaryPath () {
6746 if (hasRequiredIsBinaryPath) return isBinaryPath;
6747 hasRequiredIsBinaryPath = 1;
6748 const path = require$$0$1;
6749 const binaryExtensions = /*@__PURE__*/ requireBinaryExtensions();
6750
6751 const extensions = new Set(binaryExtensions);
6752
6753 isBinaryPath = filePath => extensions.has(path.extname(filePath).slice(1).toLowerCase());
6754 return isBinaryPath;
6755}
6756
6757var constants = {};
6758
6759var hasRequiredConstants;
6760
6761function requireConstants () {
6762 if (hasRequiredConstants) return constants;
6763 hasRequiredConstants = 1;
6764 (function (exports) {
6765
6766 const {sep} = require$$0$1;
6767 const {platform} = process;
6768 const os = require$$2$1;
6769
6770 exports.EV_ALL = 'all';
6771 exports.EV_READY = 'ready';
6772 exports.EV_ADD = 'add';
6773 exports.EV_CHANGE = 'change';
6774 exports.EV_ADD_DIR = 'addDir';
6775 exports.EV_UNLINK = 'unlink';
6776 exports.EV_UNLINK_DIR = 'unlinkDir';
6777 exports.EV_RAW = 'raw';
6778 exports.EV_ERROR = 'error';
6779
6780 exports.STR_DATA = 'data';
6781 exports.STR_END = 'end';
6782 exports.STR_CLOSE = 'close';
6783
6784 exports.FSEVENT_CREATED = 'created';
6785 exports.FSEVENT_MODIFIED = 'modified';
6786 exports.FSEVENT_DELETED = 'deleted';
6787 exports.FSEVENT_MOVED = 'moved';
6788 exports.FSEVENT_CLONED = 'cloned';
6789 exports.FSEVENT_UNKNOWN = 'unknown';
6790 exports.FSEVENT_FLAG_MUST_SCAN_SUBDIRS = 1;
6791 exports.FSEVENT_TYPE_FILE = 'file';
6792 exports.FSEVENT_TYPE_DIRECTORY = 'directory';
6793 exports.FSEVENT_TYPE_SYMLINK = 'symlink';
6794
6795 exports.KEY_LISTENERS = 'listeners';
6796 exports.KEY_ERR = 'errHandlers';
6797 exports.KEY_RAW = 'rawEmitters';
6798 exports.HANDLER_KEYS = [exports.KEY_LISTENERS, exports.KEY_ERR, exports.KEY_RAW];
6799
6800 exports.DOT_SLASH = `.${sep}`;
6801
6802 exports.BACK_SLASH_RE = /\\/g;
6803 exports.DOUBLE_SLASH_RE = /\/\//;
6804 exports.SLASH_OR_BACK_SLASH_RE = /[/\\]/;
6805 exports.DOT_RE = /\..*\.(sw[px])$|~$|\.subl.*\.tmp/;
6806 exports.REPLACER_RE = /^\.[/\\]/;
6807
6808 exports.SLASH = '/';
6809 exports.SLASH_SLASH = '//';
6810 exports.BRACE_START = '{';
6811 exports.BANG = '!';
6812 exports.ONE_DOT = '.';
6813 exports.TWO_DOTS = '..';
6814 exports.STAR = '*';
6815 exports.GLOBSTAR = '**';
6816 exports.ROOT_GLOBSTAR = '/**/*';
6817 exports.SLASH_GLOBSTAR = '/**';
6818 exports.DIR_SUFFIX = 'Dir';
6819 exports.ANYMATCH_OPTS = {dot: true};
6820 exports.STRING_TYPE = 'string';
6821 exports.FUNCTION_TYPE = 'function';
6822 exports.EMPTY_STR = '';
6823 exports.EMPTY_FN = () => {};
6824 exports.IDENTITY_FN = val => val;
6825
6826 exports.isWindows = platform === 'win32';
6827 exports.isMacos = platform === 'darwin';
6828 exports.isLinux = platform === 'linux';
6829 exports.isIBMi = os.type() === 'OS400';
6830 } (constants));
6831 return constants;
6832}
6833
6834var nodefsHandler;
6835var hasRequiredNodefsHandler;
6836
6837function requireNodefsHandler () {
6838 if (hasRequiredNodefsHandler) return nodefsHandler;
6839 hasRequiredNodefsHandler = 1;
6840
6841 const fs = require$$0$2;
6842 const sysPath = require$$0$1;
6843 const { promisify } = require$$2;
6844 const isBinaryPath = /*@__PURE__*/ requireIsBinaryPath();
6845 const {
6846 isWindows,
6847 isLinux,
6848 EMPTY_FN,
6849 EMPTY_STR,
6850 KEY_LISTENERS,
6851 KEY_ERR,
6852 KEY_RAW,
6853 HANDLER_KEYS,
6854 EV_CHANGE,
6855 EV_ADD,
6856 EV_ADD_DIR,
6857 EV_ERROR,
6858 STR_DATA,
6859 STR_END,
6860 BRACE_START,
6861 STAR
6862 } = /*@__PURE__*/ requireConstants();
6863
6864 const THROTTLE_MODE_WATCH = 'watch';
6865
6866 const open = promisify(fs.open);
6867 const stat = promisify(fs.stat);
6868 const lstat = promisify(fs.lstat);
6869 const close = promisify(fs.close);
6870 const fsrealpath = promisify(fs.realpath);
6871
6872 const statMethods = { lstat, stat };
6873
6874 // TODO: emit errors properly. Example: EMFILE on Macos.
6875 const foreach = (val, fn) => {
6876 if (val instanceof Set) {
6877 val.forEach(fn);
6878 } else {
6879 fn(val);
6880 }
6881 };
6882
6883 const addAndConvert = (main, prop, item) => {
6884 let container = main[prop];
6885 if (!(container instanceof Set)) {
6886 main[prop] = container = new Set([container]);
6887 }
6888 container.add(item);
6889 };
6890
6891 const clearItem = cont => key => {
6892 const set = cont[key];
6893 if (set instanceof Set) {
6894 set.clear();
6895 } else {
6896 delete cont[key];
6897 }
6898 };
6899
6900 const delFromSet = (main, prop, item) => {
6901 const container = main[prop];
6902 if (container instanceof Set) {
6903 container.delete(item);
6904 } else if (container === item) {
6905 delete main[prop];
6906 }
6907 };
6908
6909 const isEmptySet = (val) => val instanceof Set ? val.size === 0 : !val;
6910
6911 /**
6912 * @typedef {String} Path
6913 */
6914
6915 // fs_watch helpers
6916
6917 // object to hold per-process fs_watch instances
6918 // (may be shared across chokidar FSWatcher instances)
6919
6920 /**
6921 * @typedef {Object} FsWatchContainer
6922 * @property {Set} listeners
6923 * @property {Set} errHandlers
6924 * @property {Set} rawEmitters
6925 * @property {fs.FSWatcher=} watcher
6926 * @property {Boolean=} watcherUnusable
6927 */
6928
6929 /**
6930 * @type {Map<String,FsWatchContainer>}
6931 */
6932 const FsWatchInstances = new Map();
6933
6934 /**
6935 * Instantiates the fs_watch interface
6936 * @param {String} path to be watched
6937 * @param {Object} options to be passed to fs_watch
6938 * @param {Function} listener main event handler
6939 * @param {Function} errHandler emits info about errors
6940 * @param {Function} emitRaw emits raw event data
6941 * @returns {fs.FSWatcher} new fsevents instance
6942 */
6943 function createFsWatchInstance(path, options, listener, errHandler, emitRaw) {
6944 const handleEvent = (rawEvent, evPath) => {
6945 listener(path);
6946 emitRaw(rawEvent, evPath, {watchedPath: path});
6947
6948 // emit based on events occurring for files from a directory's watcher in
6949 // case the file's watcher misses it (and rely on throttling to de-dupe)
6950 if (evPath && path !== evPath) {
6951 fsWatchBroadcast(
6952 sysPath.resolve(path, evPath), KEY_LISTENERS, sysPath.join(path, evPath)
6953 );
6954 }
6955 };
6956 try {
6957 return fs.watch(path, options, handleEvent);
6958 } catch (error) {
6959 errHandler(error);
6960 }
6961 }
6962
6963 /**
6964 * Helper for passing fs_watch event data to a collection of listeners
6965 * @param {Path} fullPath absolute path bound to fs_watch instance
6966 * @param {String} type listener type
6967 * @param {*=} val1 arguments to be passed to listeners
6968 * @param {*=} val2
6969 * @param {*=} val3
6970 */
6971 const fsWatchBroadcast = (fullPath, type, val1, val2, val3) => {
6972 const cont = FsWatchInstances.get(fullPath);
6973 if (!cont) return;
6974 foreach(cont[type], (listener) => {
6975 listener(val1, val2, val3);
6976 });
6977 };
6978
6979 /**
6980 * Instantiates the fs_watch interface or binds listeners
6981 * to an existing one covering the same file system entry
6982 * @param {String} path
6983 * @param {String} fullPath absolute path
6984 * @param {Object} options to be passed to fs_watch
6985 * @param {Object} handlers container for event listener functions
6986 */
6987 const setFsWatchListener = (path, fullPath, options, handlers) => {
6988 const {listener, errHandler, rawEmitter} = handlers;
6989 let cont = FsWatchInstances.get(fullPath);
6990
6991 /** @type {fs.FSWatcher=} */
6992 let watcher;
6993 if (!options.persistent) {
6994 watcher = createFsWatchInstance(
6995 path, options, listener, errHandler, rawEmitter
6996 );
6997 return watcher.close.bind(watcher);
6998 }
6999 if (cont) {
7000 addAndConvert(cont, KEY_LISTENERS, listener);
7001 addAndConvert(cont, KEY_ERR, errHandler);
7002 addAndConvert(cont, KEY_RAW, rawEmitter);
7003 } else {
7004 watcher = createFsWatchInstance(
7005 path,
7006 options,
7007 fsWatchBroadcast.bind(null, fullPath, KEY_LISTENERS),
7008 errHandler, // no need to use broadcast here
7009 fsWatchBroadcast.bind(null, fullPath, KEY_RAW)
7010 );
7011 if (!watcher) return;
7012 watcher.on(EV_ERROR, async (error) => {
7013 const broadcastErr = fsWatchBroadcast.bind(null, fullPath, KEY_ERR);
7014 cont.watcherUnusable = true; // documented since Node 10.4.1
7015 // Workaround for https://github.com/joyent/node/issues/4337
7016 if (isWindows && error.code === 'EPERM') {
7017 try {
7018 const fd = await open(path, 'r');
7019 await close(fd);
7020 broadcastErr(error);
7021 } catch (err) {}
7022 } else {
7023 broadcastErr(error);
7024 }
7025 });
7026 cont = {
7027 listeners: listener,
7028 errHandlers: errHandler,
7029 rawEmitters: rawEmitter,
7030 watcher
7031 };
7032 FsWatchInstances.set(fullPath, cont);
7033 }
7034 // const index = cont.listeners.indexOf(listener);
7035
7036 // removes this instance's listeners and closes the underlying fs_watch
7037 // instance if there are no more listeners left
7038 return () => {
7039 delFromSet(cont, KEY_LISTENERS, listener);
7040 delFromSet(cont, KEY_ERR, errHandler);
7041 delFromSet(cont, KEY_RAW, rawEmitter);
7042 if (isEmptySet(cont.listeners)) {
7043 // Check to protect against issue gh-730.
7044 // if (cont.watcherUnusable) {
7045 cont.watcher.close();
7046 // }
7047 FsWatchInstances.delete(fullPath);
7048 HANDLER_KEYS.forEach(clearItem(cont));
7049 cont.watcher = undefined;
7050 Object.freeze(cont);
7051 }
7052 };
7053 };
7054
7055 // fs_watchFile helpers
7056
7057 // object to hold per-process fs_watchFile instances
7058 // (may be shared across chokidar FSWatcher instances)
7059 const FsWatchFileInstances = new Map();
7060
7061 /**
7062 * Instantiates the fs_watchFile interface or binds listeners
7063 * to an existing one covering the same file system entry
7064 * @param {String} path to be watched
7065 * @param {String} fullPath absolute path
7066 * @param {Object} options options to be passed to fs_watchFile
7067 * @param {Object} handlers container for event listener functions
7068 * @returns {Function} closer
7069 */
7070 const setFsWatchFileListener = (path, fullPath, options, handlers) => {
7071 const {listener, rawEmitter} = handlers;
7072 let cont = FsWatchFileInstances.get(fullPath);
7073
7074 const copts = cont && cont.options;
7075 if (copts && (copts.persistent < options.persistent || copts.interval > options.interval)) {
7076 fs.unwatchFile(fullPath);
7077 cont = undefined;
7078 }
7079
7080 /* eslint-enable no-unused-vars, prefer-destructuring */
7081
7082 if (cont) {
7083 addAndConvert(cont, KEY_LISTENERS, listener);
7084 addAndConvert(cont, KEY_RAW, rawEmitter);
7085 } else {
7086 // TODO
7087 // listeners.add(listener);
7088 // rawEmitters.add(rawEmitter);
7089 cont = {
7090 listeners: listener,
7091 rawEmitters: rawEmitter,
7092 options,
7093 watcher: fs.watchFile(fullPath, options, (curr, prev) => {
7094 foreach(cont.rawEmitters, (rawEmitter) => {
7095 rawEmitter(EV_CHANGE, fullPath, {curr, prev});
7096 });
7097 const currmtime = curr.mtimeMs;
7098 if (curr.size !== prev.size || currmtime > prev.mtimeMs || currmtime === 0) {
7099 foreach(cont.listeners, (listener) => listener(path, curr));
7100 }
7101 })
7102 };
7103 FsWatchFileInstances.set(fullPath, cont);
7104 }
7105 // const index = cont.listeners.indexOf(listener);
7106
7107 // Removes this instance's listeners and closes the underlying fs_watchFile
7108 // instance if there are no more listeners left.
7109 return () => {
7110 delFromSet(cont, KEY_LISTENERS, listener);
7111 delFromSet(cont, KEY_RAW, rawEmitter);
7112 if (isEmptySet(cont.listeners)) {
7113 FsWatchFileInstances.delete(fullPath);
7114 fs.unwatchFile(fullPath);
7115 cont.options = cont.watcher = undefined;
7116 Object.freeze(cont);
7117 }
7118 };
7119 };
7120
7121 /**
7122 * @mixin
7123 */
7124 class NodeFsHandler {
7125
7126 /**
7127 * @param {import("../index").FSWatcher} fsW
7128 */
7129 constructor(fsW) {
7130 this.fsw = fsW;
7131 this._boundHandleError = (error) => fsW._handleError(error);
7132 }
7133
7134 /**
7135 * Watch file for changes with fs_watchFile or fs_watch.
7136 * @param {String} path to file or dir
7137 * @param {Function} listener on fs change
7138 * @returns {Function} closer for the watcher instance
7139 */
7140 _watchWithNodeFs(path, listener) {
7141 const opts = this.fsw.options;
7142 const directory = sysPath.dirname(path);
7143 const basename = sysPath.basename(path);
7144 const parent = this.fsw._getWatchedDir(directory);
7145 parent.add(basename);
7146 const absolutePath = sysPath.resolve(path);
7147 const options = {persistent: opts.persistent};
7148 if (!listener) listener = EMPTY_FN;
7149
7150 let closer;
7151 if (opts.usePolling) {
7152 options.interval = opts.enableBinaryInterval && isBinaryPath(basename) ?
7153 opts.binaryInterval : opts.interval;
7154 closer = setFsWatchFileListener(path, absolutePath, options, {
7155 listener,
7156 rawEmitter: this.fsw._emitRaw
7157 });
7158 } else {
7159 closer = setFsWatchListener(path, absolutePath, options, {
7160 listener,
7161 errHandler: this._boundHandleError,
7162 rawEmitter: this.fsw._emitRaw
7163 });
7164 }
7165 return closer;
7166 }
7167
7168 /**
7169 * Watch a file and emit add event if warranted.
7170 * @param {Path} file Path
7171 * @param {fs.Stats} stats result of fs_stat
7172 * @param {Boolean} initialAdd was the file added at watch instantiation?
7173 * @returns {Function} closer for the watcher instance
7174 */
7175 _handleFile(file, stats, initialAdd) {
7176 if (this.fsw.closed) {
7177 return;
7178 }
7179 const dirname = sysPath.dirname(file);
7180 const basename = sysPath.basename(file);
7181 const parent = this.fsw._getWatchedDir(dirname);
7182 // stats is always present
7183 let prevStats = stats;
7184
7185 // if the file is already being watched, do nothing
7186 if (parent.has(basename)) return;
7187
7188 const listener = async (path, newStats) => {
7189 if (!this.fsw._throttle(THROTTLE_MODE_WATCH, file, 5)) return;
7190 if (!newStats || newStats.mtimeMs === 0) {
7191 try {
7192 const newStats = await stat(file);
7193 if (this.fsw.closed) return;
7194 // Check that change event was not fired because of changed only accessTime.
7195 const at = newStats.atimeMs;
7196 const mt = newStats.mtimeMs;
7197 if (!at || at <= mt || mt !== prevStats.mtimeMs) {
7198 this.fsw._emit(EV_CHANGE, file, newStats);
7199 }
7200 if (isLinux && prevStats.ino !== newStats.ino) {
7201 this.fsw._closeFile(path);
7202 prevStats = newStats;
7203 this.fsw._addPathCloser(path, this._watchWithNodeFs(file, listener));
7204 } else {
7205 prevStats = newStats;
7206 }
7207 } catch (error) {
7208 // Fix issues where mtime is null but file is still present
7209 this.fsw._remove(dirname, basename);
7210 }
7211 // add is about to be emitted if file not already tracked in parent
7212 } else if (parent.has(basename)) {
7213 // Check that change event was not fired because of changed only accessTime.
7214 const at = newStats.atimeMs;
7215 const mt = newStats.mtimeMs;
7216 if (!at || at <= mt || mt !== prevStats.mtimeMs) {
7217 this.fsw._emit(EV_CHANGE, file, newStats);
7218 }
7219 prevStats = newStats;
7220 }
7221 };
7222 // kick off the watcher
7223 const closer = this._watchWithNodeFs(file, listener);
7224
7225 // emit an add event if we're supposed to
7226 if (!(initialAdd && this.fsw.options.ignoreInitial) && this.fsw._isntIgnored(file)) {
7227 if (!this.fsw._throttle(EV_ADD, file, 0)) return;
7228 this.fsw._emit(EV_ADD, file, stats);
7229 }
7230
7231 return closer;
7232 }
7233
7234 /**
7235 * Handle symlinks encountered while reading a dir.
7236 * @param {Object} entry returned by readdirp
7237 * @param {String} directory path of dir being read
7238 * @param {String} path of this item
7239 * @param {String} item basename of this item
7240 * @returns {Promise<Boolean>} true if no more processing is needed for this entry.
7241 */
7242 async _handleSymlink(entry, directory, path, item) {
7243 if (this.fsw.closed) {
7244 return;
7245 }
7246 const full = entry.fullPath;
7247 const dir = this.fsw._getWatchedDir(directory);
7248
7249 if (!this.fsw.options.followSymlinks) {
7250 // watch symlink directly (don't follow) and detect changes
7251 this.fsw._incrReadyCount();
7252
7253 let linkPath;
7254 try {
7255 linkPath = await fsrealpath(path);
7256 } catch (e) {
7257 this.fsw._emitReady();
7258 return true;
7259 }
7260
7261 if (this.fsw.closed) return;
7262 if (dir.has(item)) {
7263 if (this.fsw._symlinkPaths.get(full) !== linkPath) {
7264 this.fsw._symlinkPaths.set(full, linkPath);
7265 this.fsw._emit(EV_CHANGE, path, entry.stats);
7266 }
7267 } else {
7268 dir.add(item);
7269 this.fsw._symlinkPaths.set(full, linkPath);
7270 this.fsw._emit(EV_ADD, path, entry.stats);
7271 }
7272 this.fsw._emitReady();
7273 return true;
7274 }
7275
7276 // don't follow the same symlink more than once
7277 if (this.fsw._symlinkPaths.has(full)) {
7278 return true;
7279 }
7280
7281 this.fsw._symlinkPaths.set(full, true);
7282 }
7283
7284 _handleRead(directory, initialAdd, wh, target, dir, depth, throttler) {
7285 // Normalize the directory name on Windows
7286 directory = sysPath.join(directory, EMPTY_STR);
7287
7288 if (!wh.hasGlob) {
7289 throttler = this.fsw._throttle('readdir', directory, 1000);
7290 if (!throttler) return;
7291 }
7292
7293 const previous = this.fsw._getWatchedDir(wh.path);
7294 const current = new Set();
7295
7296 let stream = this.fsw._readdirp(directory, {
7297 fileFilter: entry => wh.filterPath(entry),
7298 directoryFilter: entry => wh.filterDir(entry),
7299 depth: 0
7300 }).on(STR_DATA, async (entry) => {
7301 if (this.fsw.closed) {
7302 stream = undefined;
7303 return;
7304 }
7305 const item = entry.path;
7306 let path = sysPath.join(directory, item);
7307 current.add(item);
7308
7309 if (entry.stats.isSymbolicLink() && await this._handleSymlink(entry, directory, path, item)) {
7310 return;
7311 }
7312
7313 if (this.fsw.closed) {
7314 stream = undefined;
7315 return;
7316 }
7317 // Files that present in current directory snapshot
7318 // but absent in previous are added to watch list and
7319 // emit `add` event.
7320 if (item === target || !target && !previous.has(item)) {
7321 this.fsw._incrReadyCount();
7322
7323 // ensure relativeness of path is preserved in case of watcher reuse
7324 path = sysPath.join(dir, sysPath.relative(dir, path));
7325
7326 this._addToNodeFs(path, initialAdd, wh, depth + 1);
7327 }
7328 }).on(EV_ERROR, this._boundHandleError);
7329
7330 return new Promise(resolve =>
7331 stream.once(STR_END, () => {
7332 if (this.fsw.closed) {
7333 stream = undefined;
7334 return;
7335 }
7336 const wasThrottled = throttler ? throttler.clear() : false;
7337
7338 resolve();
7339
7340 // Files that absent in current directory snapshot
7341 // but present in previous emit `remove` event
7342 // and are removed from @watched[directory].
7343 previous.getChildren().filter((item) => {
7344 return item !== directory &&
7345 !current.has(item) &&
7346 // in case of intersecting globs;
7347 // a path may have been filtered out of this readdir, but
7348 // shouldn't be removed because it matches a different glob
7349 (!wh.hasGlob || wh.filterPath({
7350 fullPath: sysPath.resolve(directory, item)
7351 }));
7352 }).forEach((item) => {
7353 this.fsw._remove(directory, item);
7354 });
7355
7356 stream = undefined;
7357
7358 // one more time for any missed in case changes came in extremely quickly
7359 if (wasThrottled) this._handleRead(directory, false, wh, target, dir, depth, throttler);
7360 })
7361 );
7362 }
7363
7364 /**
7365 * Read directory to add / remove files from `@watched` list and re-read it on change.
7366 * @param {String} dir fs path
7367 * @param {fs.Stats} stats
7368 * @param {Boolean} initialAdd
7369 * @param {Number} depth relative to user-supplied path
7370 * @param {String} target child path targeted for watch
7371 * @param {Object} wh Common watch helpers for this path
7372 * @param {String} realpath
7373 * @returns {Promise<Function>} closer for the watcher instance.
7374 */
7375 async _handleDir(dir, stats, initialAdd, depth, target, wh, realpath) {
7376 const parentDir = this.fsw._getWatchedDir(sysPath.dirname(dir));
7377 const tracked = parentDir.has(sysPath.basename(dir));
7378 if (!(initialAdd && this.fsw.options.ignoreInitial) && !target && !tracked) {
7379 if (!wh.hasGlob || wh.globFilter(dir)) this.fsw._emit(EV_ADD_DIR, dir, stats);
7380 }
7381
7382 // ensure dir is tracked (harmless if redundant)
7383 parentDir.add(sysPath.basename(dir));
7384 this.fsw._getWatchedDir(dir);
7385 let throttler;
7386 let closer;
7387
7388 const oDepth = this.fsw.options.depth;
7389 if ((oDepth == null || depth <= oDepth) && !this.fsw._symlinkPaths.has(realpath)) {
7390 if (!target) {
7391 await this._handleRead(dir, initialAdd, wh, target, dir, depth, throttler);
7392 if (this.fsw.closed) return;
7393 }
7394
7395 closer = this._watchWithNodeFs(dir, (dirPath, stats) => {
7396 // if current directory is removed, do nothing
7397 if (stats && stats.mtimeMs === 0) return;
7398
7399 this._handleRead(dirPath, false, wh, target, dir, depth, throttler);
7400 });
7401 }
7402 return closer;
7403 }
7404
7405 /**
7406 * Handle added file, directory, or glob pattern.
7407 * Delegates call to _handleFile / _handleDir after checks.
7408 * @param {String} path to file or ir
7409 * @param {Boolean} initialAdd was the file added at watch instantiation?
7410 * @param {Object} priorWh depth relative to user-supplied path
7411 * @param {Number} depth Child path actually targeted for watch
7412 * @param {String=} target Child path actually targeted for watch
7413 * @returns {Promise}
7414 */
7415 async _addToNodeFs(path, initialAdd, priorWh, depth, target) {
7416 const ready = this.fsw._emitReady;
7417 if (this.fsw._isIgnored(path) || this.fsw.closed) {
7418 ready();
7419 return false;
7420 }
7421
7422 const wh = this.fsw._getWatchHelpers(path, depth);
7423 if (!wh.hasGlob && priorWh) {
7424 wh.hasGlob = priorWh.hasGlob;
7425 wh.globFilter = priorWh.globFilter;
7426 wh.filterPath = entry => priorWh.filterPath(entry);
7427 wh.filterDir = entry => priorWh.filterDir(entry);
7428 }
7429
7430 // evaluate what is at the path we're being asked to watch
7431 try {
7432 const stats = await statMethods[wh.statMethod](wh.watchPath);
7433 if (this.fsw.closed) return;
7434 if (this.fsw._isIgnored(wh.watchPath, stats)) {
7435 ready();
7436 return false;
7437 }
7438
7439 const follow = this.fsw.options.followSymlinks && !path.includes(STAR) && !path.includes(BRACE_START);
7440 let closer;
7441 if (stats.isDirectory()) {
7442 const absPath = sysPath.resolve(path);
7443 const targetPath = follow ? await fsrealpath(path) : path;
7444 if (this.fsw.closed) return;
7445 closer = await this._handleDir(wh.watchPath, stats, initialAdd, depth, target, wh, targetPath);
7446 if (this.fsw.closed) return;
7447 // preserve this symlink's target path
7448 if (absPath !== targetPath && targetPath !== undefined) {
7449 this.fsw._symlinkPaths.set(absPath, targetPath);
7450 }
7451 } else if (stats.isSymbolicLink()) {
7452 const targetPath = follow ? await fsrealpath(path) : path;
7453 if (this.fsw.closed) return;
7454 const parent = sysPath.dirname(wh.watchPath);
7455 this.fsw._getWatchedDir(parent).add(wh.watchPath);
7456 this.fsw._emit(EV_ADD, wh.watchPath, stats);
7457 closer = await this._handleDir(parent, stats, initialAdd, depth, path, wh, targetPath);
7458 if (this.fsw.closed) return;
7459
7460 // preserve this symlink's target path
7461 if (targetPath !== undefined) {
7462 this.fsw._symlinkPaths.set(sysPath.resolve(path), targetPath);
7463 }
7464 } else {
7465 closer = this._handleFile(wh.watchPath, stats, initialAdd);
7466 }
7467 ready();
7468
7469 this.fsw._addPathCloser(path, closer);
7470 return false;
7471
7472 } catch (error) {
7473 if (this.fsw._handleError(error)) {
7474 ready();
7475 return path;
7476 }
7477 }
7478 }
7479
7480 }
7481
7482 nodefsHandler = NodeFsHandler;
7483 return nodefsHandler;
7484}
7485
7486var fseventsHandler = {exports: {}};
7487
7488const require$$3 = /*@__PURE__*/getAugmentedNamespace(fseventsImporter);
7489
7490var hasRequiredFseventsHandler;
7491
7492function requireFseventsHandler () {
7493 if (hasRequiredFseventsHandler) return fseventsHandler.exports;
7494 hasRequiredFseventsHandler = 1;
7495
7496 const fs = require$$0$2;
7497 const sysPath = require$$0$1;
7498 const { promisify } = require$$2;
7499
7500 let fsevents;
7501 try {
7502 fsevents = require$$3.getFsEvents();
7503 } catch (error) {
7504 if (process.env.CHOKIDAR_PRINT_FSEVENTS_REQUIRE_ERROR) console.error(error);
7505 }
7506
7507 if (fsevents) {
7508 // TODO: real check
7509 const mtch = process.version.match(/v(\d+)\.(\d+)/);
7510 if (mtch && mtch[1] && mtch[2]) {
7511 const maj = Number.parseInt(mtch[1], 10);
7512 const min = Number.parseInt(mtch[2], 10);
7513 if (maj === 8 && min < 16) {
7514 fsevents = undefined;
7515 }
7516 }
7517 }
7518
7519 const {
7520 EV_ADD,
7521 EV_CHANGE,
7522 EV_ADD_DIR,
7523 EV_UNLINK,
7524 EV_ERROR,
7525 STR_DATA,
7526 STR_END,
7527 FSEVENT_CREATED,
7528 FSEVENT_MODIFIED,
7529 FSEVENT_DELETED,
7530 FSEVENT_MOVED,
7531 // FSEVENT_CLONED,
7532 FSEVENT_UNKNOWN,
7533 FSEVENT_FLAG_MUST_SCAN_SUBDIRS,
7534 FSEVENT_TYPE_FILE,
7535 FSEVENT_TYPE_DIRECTORY,
7536 FSEVENT_TYPE_SYMLINK,
7537
7538 ROOT_GLOBSTAR,
7539 DIR_SUFFIX,
7540 DOT_SLASH,
7541 FUNCTION_TYPE,
7542 EMPTY_FN,
7543 IDENTITY_FN
7544 } = /*@__PURE__*/ requireConstants();
7545
7546 const Depth = (value) => isNaN(value) ? {} : {depth: value};
7547
7548 const stat = promisify(fs.stat);
7549 const lstat = promisify(fs.lstat);
7550 const realpath = promisify(fs.realpath);
7551
7552 const statMethods = { stat, lstat };
7553
7554 /**
7555 * @typedef {String} Path
7556 */
7557
7558 /**
7559 * @typedef {Object} FsEventsWatchContainer
7560 * @property {Set<Function>} listeners
7561 * @property {Function} rawEmitter
7562 * @property {{stop: Function}} watcher
7563 */
7564
7565 // fsevents instance helper functions
7566 /**
7567 * Object to hold per-process fsevents instances (may be shared across chokidar FSWatcher instances)
7568 * @type {Map<Path,FsEventsWatchContainer>}
7569 */
7570 const FSEventsWatchers = new Map();
7571
7572 // Threshold of duplicate path prefixes at which to start
7573 // consolidating going forward
7574 const consolidateThreshhold = 10;
7575
7576 const wrongEventFlags = new Set([
7577 69888, 70400, 71424, 72704, 73472, 131328, 131840, 262912
7578 ]);
7579
7580 /**
7581 * Instantiates the fsevents interface
7582 * @param {Path} path path to be watched
7583 * @param {Function} callback called when fsevents is bound and ready
7584 * @returns {{stop: Function}} new fsevents instance
7585 */
7586 const createFSEventsInstance = (path, callback) => {
7587 const stop = fsevents.watch(path, callback);
7588 return {stop};
7589 };
7590
7591 /**
7592 * Instantiates the fsevents interface or binds listeners to an existing one covering
7593 * the same file tree.
7594 * @param {Path} path - to be watched
7595 * @param {Path} realPath - real path for symlinks
7596 * @param {Function} listener - called when fsevents emits events
7597 * @param {Function} rawEmitter - passes data to listeners of the 'raw' event
7598 * @returns {Function} closer
7599 */
7600 function setFSEventsListener(path, realPath, listener, rawEmitter) {
7601 let watchPath = sysPath.extname(realPath) ? sysPath.dirname(realPath) : realPath;
7602
7603 const parentPath = sysPath.dirname(watchPath);
7604 let cont = FSEventsWatchers.get(watchPath);
7605
7606 // If we've accumulated a substantial number of paths that
7607 // could have been consolidated by watching one directory
7608 // above the current one, create a watcher on the parent
7609 // path instead, so that we do consolidate going forward.
7610 if (couldConsolidate(parentPath)) {
7611 watchPath = parentPath;
7612 }
7613
7614 const resolvedPath = sysPath.resolve(path);
7615 const hasSymlink = resolvedPath !== realPath;
7616
7617 const filteredListener = (fullPath, flags, info) => {
7618 if (hasSymlink) fullPath = fullPath.replace(realPath, resolvedPath);
7619 if (
7620 fullPath === resolvedPath ||
7621 !fullPath.indexOf(resolvedPath + sysPath.sep)
7622 ) listener(fullPath, flags, info);
7623 };
7624
7625 // check if there is already a watcher on a parent path
7626 // modifies `watchPath` to the parent path when it finds a match
7627 let watchedParent = false;
7628 for (const watchedPath of FSEventsWatchers.keys()) {
7629 if (realPath.indexOf(sysPath.resolve(watchedPath) + sysPath.sep) === 0) {
7630 watchPath = watchedPath;
7631 cont = FSEventsWatchers.get(watchPath);
7632 watchedParent = true;
7633 break;
7634 }
7635 }
7636
7637 if (cont || watchedParent) {
7638 cont.listeners.add(filteredListener);
7639 } else {
7640 cont = {
7641 listeners: new Set([filteredListener]),
7642 rawEmitter,
7643 watcher: createFSEventsInstance(watchPath, (fullPath, flags) => {
7644 if (!cont.listeners.size) return;
7645 if (flags & FSEVENT_FLAG_MUST_SCAN_SUBDIRS) return;
7646 const info = fsevents.getInfo(fullPath, flags);
7647 cont.listeners.forEach(list => {
7648 list(fullPath, flags, info);
7649 });
7650
7651 cont.rawEmitter(info.event, fullPath, info);
7652 })
7653 };
7654 FSEventsWatchers.set(watchPath, cont);
7655 }
7656
7657 // removes this instance's listeners and closes the underlying fsevents
7658 // instance if there are no more listeners left
7659 return () => {
7660 const lst = cont.listeners;
7661
7662 lst.delete(filteredListener);
7663 if (!lst.size) {
7664 FSEventsWatchers.delete(watchPath);
7665 if (cont.watcher) return cont.watcher.stop().then(() => {
7666 cont.rawEmitter = cont.watcher = undefined;
7667 Object.freeze(cont);
7668 });
7669 }
7670 };
7671 }
7672
7673 // Decide whether or not we should start a new higher-level
7674 // parent watcher
7675 const couldConsolidate = (path) => {
7676 let count = 0;
7677 for (const watchPath of FSEventsWatchers.keys()) {
7678 if (watchPath.indexOf(path) === 0) {
7679 count++;
7680 if (count >= consolidateThreshhold) {
7681 return true;
7682 }
7683 }
7684 }
7685
7686 return false;
7687 };
7688
7689 // returns boolean indicating whether fsevents can be used
7690 const canUse = () => fsevents && FSEventsWatchers.size < 128;
7691
7692 // determines subdirectory traversal levels from root to path
7693 const calcDepth = (path, root) => {
7694 let i = 0;
7695 while (!path.indexOf(root) && (path = sysPath.dirname(path)) !== root) i++;
7696 return i;
7697 };
7698
7699 // returns boolean indicating whether the fsevents' event info has the same type
7700 // as the one returned by fs.stat
7701 const sameTypes = (info, stats) => (
7702 info.type === FSEVENT_TYPE_DIRECTORY && stats.isDirectory() ||
7703 info.type === FSEVENT_TYPE_SYMLINK && stats.isSymbolicLink() ||
7704 info.type === FSEVENT_TYPE_FILE && stats.isFile()
7705 );
7706
7707 /**
7708 * @mixin
7709 */
7710 class FsEventsHandler {
7711
7712 /**
7713 * @param {import('../index').FSWatcher} fsw
7714 */
7715 constructor(fsw) {
7716 this.fsw = fsw;
7717 }
7718 checkIgnored(path, stats) {
7719 const ipaths = this.fsw._ignoredPaths;
7720 if (this.fsw._isIgnored(path, stats)) {
7721 ipaths.add(path);
7722 if (stats && stats.isDirectory()) {
7723 ipaths.add(path + ROOT_GLOBSTAR);
7724 }
7725 return true;
7726 }
7727
7728 ipaths.delete(path);
7729 ipaths.delete(path + ROOT_GLOBSTAR);
7730 }
7731
7732 addOrChange(path, fullPath, realPath, parent, watchedDir, item, info, opts) {
7733 const event = watchedDir.has(item) ? EV_CHANGE : EV_ADD;
7734 this.handleEvent(event, path, fullPath, realPath, parent, watchedDir, item, info, opts);
7735 }
7736
7737 async checkExists(path, fullPath, realPath, parent, watchedDir, item, info, opts) {
7738 try {
7739 const stats = await stat(path);
7740 if (this.fsw.closed) return;
7741 if (sameTypes(info, stats)) {
7742 this.addOrChange(path, fullPath, realPath, parent, watchedDir, item, info, opts);
7743 } else {
7744 this.handleEvent(EV_UNLINK, path, fullPath, realPath, parent, watchedDir, item, info, opts);
7745 }
7746 } catch (error) {
7747 if (error.code === 'EACCES') {
7748 this.addOrChange(path, fullPath, realPath, parent, watchedDir, item, info, opts);
7749 } else {
7750 this.handleEvent(EV_UNLINK, path, fullPath, realPath, parent, watchedDir, item, info, opts);
7751 }
7752 }
7753 }
7754
7755 handleEvent(event, path, fullPath, realPath, parent, watchedDir, item, info, opts) {
7756 if (this.fsw.closed || this.checkIgnored(path)) return;
7757
7758 if (event === EV_UNLINK) {
7759 const isDirectory = info.type === FSEVENT_TYPE_DIRECTORY;
7760 // suppress unlink events on never before seen files
7761 if (isDirectory || watchedDir.has(item)) {
7762 this.fsw._remove(parent, item, isDirectory);
7763 }
7764 } else {
7765 if (event === EV_ADD) {
7766 // track new directories
7767 if (info.type === FSEVENT_TYPE_DIRECTORY) this.fsw._getWatchedDir(path);
7768
7769 if (info.type === FSEVENT_TYPE_SYMLINK && opts.followSymlinks) {
7770 // push symlinks back to the top of the stack to get handled
7771 const curDepth = opts.depth === undefined ?
7772 undefined : calcDepth(fullPath, realPath) + 1;
7773 return this._addToFsEvents(path, false, true, curDepth);
7774 }
7775
7776 // track new paths
7777 // (other than symlinks being followed, which will be tracked soon)
7778 this.fsw._getWatchedDir(parent).add(item);
7779 }
7780 /**
7781 * @type {'add'|'addDir'|'unlink'|'unlinkDir'}
7782 */
7783 const eventName = info.type === FSEVENT_TYPE_DIRECTORY ? event + DIR_SUFFIX : event;
7784 this.fsw._emit(eventName, path);
7785 if (eventName === EV_ADD_DIR) this._addToFsEvents(path, false, true);
7786 }
7787 }
7788
7789 /**
7790 * Handle symlinks encountered during directory scan
7791 * @param {String} watchPath - file/dir path to be watched with fsevents
7792 * @param {String} realPath - real path (in case of symlinks)
7793 * @param {Function} transform - path transformer
7794 * @param {Function} globFilter - path filter in case a glob pattern was provided
7795 * @returns {Function} closer for the watcher instance
7796 */
7797 _watchWithFsEvents(watchPath, realPath, transform, globFilter) {
7798 if (this.fsw.closed || this.fsw._isIgnored(watchPath)) return;
7799 const opts = this.fsw.options;
7800 const watchCallback = async (fullPath, flags, info) => {
7801 if (this.fsw.closed) return;
7802 if (
7803 opts.depth !== undefined &&
7804 calcDepth(fullPath, realPath) > opts.depth
7805 ) return;
7806 const path = transform(sysPath.join(
7807 watchPath, sysPath.relative(watchPath, fullPath)
7808 ));
7809 if (globFilter && !globFilter(path)) return;
7810 // ensure directories are tracked
7811 const parent = sysPath.dirname(path);
7812 const item = sysPath.basename(path);
7813 const watchedDir = this.fsw._getWatchedDir(
7814 info.type === FSEVENT_TYPE_DIRECTORY ? path : parent
7815 );
7816
7817 // correct for wrong events emitted
7818 if (wrongEventFlags.has(flags) || info.event === FSEVENT_UNKNOWN) {
7819 if (typeof opts.ignored === FUNCTION_TYPE) {
7820 let stats;
7821 try {
7822 stats = await stat(path);
7823 } catch (error) {}
7824 if (this.fsw.closed) return;
7825 if (this.checkIgnored(path, stats)) return;
7826 if (sameTypes(info, stats)) {
7827 this.addOrChange(path, fullPath, realPath, parent, watchedDir, item, info, opts);
7828 } else {
7829 this.handleEvent(EV_UNLINK, path, fullPath, realPath, parent, watchedDir, item, info, opts);
7830 }
7831 } else {
7832 this.checkExists(path, fullPath, realPath, parent, watchedDir, item, info, opts);
7833 }
7834 } else {
7835 switch (info.event) {
7836 case FSEVENT_CREATED:
7837 case FSEVENT_MODIFIED:
7838 return this.addOrChange(path, fullPath, realPath, parent, watchedDir, item, info, opts);
7839 case FSEVENT_DELETED:
7840 case FSEVENT_MOVED:
7841 return this.checkExists(path, fullPath, realPath, parent, watchedDir, item, info, opts);
7842 }
7843 }
7844 };
7845
7846 const closer = setFSEventsListener(
7847 watchPath,
7848 realPath,
7849 watchCallback,
7850 this.fsw._emitRaw
7851 );
7852
7853 this.fsw._emitReady();
7854 return closer;
7855 }
7856
7857 /**
7858 * Handle symlinks encountered during directory scan
7859 * @param {String} linkPath path to symlink
7860 * @param {String} fullPath absolute path to the symlink
7861 * @param {Function} transform pre-existing path transformer
7862 * @param {Number} curDepth level of subdirectories traversed to where symlink is
7863 * @returns {Promise<void>}
7864 */
7865 async _handleFsEventsSymlink(linkPath, fullPath, transform, curDepth) {
7866 // don't follow the same symlink more than once
7867 if (this.fsw.closed || this.fsw._symlinkPaths.has(fullPath)) return;
7868
7869 this.fsw._symlinkPaths.set(fullPath, true);
7870 this.fsw._incrReadyCount();
7871
7872 try {
7873 const linkTarget = await realpath(linkPath);
7874 if (this.fsw.closed) return;
7875 if (this.fsw._isIgnored(linkTarget)) {
7876 return this.fsw._emitReady();
7877 }
7878
7879 this.fsw._incrReadyCount();
7880
7881 // add the linkTarget for watching with a wrapper for transform
7882 // that causes emitted paths to incorporate the link's path
7883 this._addToFsEvents(linkTarget || linkPath, (path) => {
7884 let aliasedPath = linkPath;
7885 if (linkTarget && linkTarget !== DOT_SLASH) {
7886 aliasedPath = path.replace(linkTarget, linkPath);
7887 } else if (path !== DOT_SLASH) {
7888 aliasedPath = sysPath.join(linkPath, path);
7889 }
7890 return transform(aliasedPath);
7891 }, false, curDepth);
7892 } catch(error) {
7893 if (this.fsw._handleError(error)) {
7894 return this.fsw._emitReady();
7895 }
7896 }
7897 }
7898
7899 /**
7900 *
7901 * @param {Path} newPath
7902 * @param {fs.Stats} stats
7903 */
7904 emitAdd(newPath, stats, processPath, opts, forceAdd) {
7905 const pp = processPath(newPath);
7906 const isDir = stats.isDirectory();
7907 const dirObj = this.fsw._getWatchedDir(sysPath.dirname(pp));
7908 const base = sysPath.basename(pp);
7909
7910 // ensure empty dirs get tracked
7911 if (isDir) this.fsw._getWatchedDir(pp);
7912 if (dirObj.has(base)) return;
7913 dirObj.add(base);
7914
7915 if (!opts.ignoreInitial || forceAdd === true) {
7916 this.fsw._emit(isDir ? EV_ADD_DIR : EV_ADD, pp, stats);
7917 }
7918 }
7919
7920 initWatch(realPath, path, wh, processPath) {
7921 if (this.fsw.closed) return;
7922 const closer = this._watchWithFsEvents(
7923 wh.watchPath,
7924 sysPath.resolve(realPath || wh.watchPath),
7925 processPath,
7926 wh.globFilter
7927 );
7928 this.fsw._addPathCloser(path, closer);
7929 }
7930
7931 /**
7932 * Handle added path with fsevents
7933 * @param {String} path file/dir path or glob pattern
7934 * @param {Function|Boolean=} transform converts working path to what the user expects
7935 * @param {Boolean=} forceAdd ensure add is emitted
7936 * @param {Number=} priorDepth Level of subdirectories already traversed.
7937 * @returns {Promise<void>}
7938 */
7939 async _addToFsEvents(path, transform, forceAdd, priorDepth) {
7940 if (this.fsw.closed) {
7941 return;
7942 }
7943 const opts = this.fsw.options;
7944 const processPath = typeof transform === FUNCTION_TYPE ? transform : IDENTITY_FN;
7945
7946 const wh = this.fsw._getWatchHelpers(path);
7947
7948 // evaluate what is at the path we're being asked to watch
7949 try {
7950 const stats = await statMethods[wh.statMethod](wh.watchPath);
7951 if (this.fsw.closed) return;
7952 if (this.fsw._isIgnored(wh.watchPath, stats)) {
7953 throw null;
7954 }
7955 if (stats.isDirectory()) {
7956 // emit addDir unless this is a glob parent
7957 if (!wh.globFilter) this.emitAdd(processPath(path), stats, processPath, opts, forceAdd);
7958
7959 // don't recurse further if it would exceed depth setting
7960 if (priorDepth && priorDepth > opts.depth) return;
7961
7962 // scan the contents of the dir
7963 this.fsw._readdirp(wh.watchPath, {
7964 fileFilter: entry => wh.filterPath(entry),
7965 directoryFilter: entry => wh.filterDir(entry),
7966 ...Depth(opts.depth - (priorDepth || 0))
7967 }).on(STR_DATA, (entry) => {
7968 // need to check filterPath on dirs b/c filterDir is less restrictive
7969 if (this.fsw.closed) {
7970 return;
7971 }
7972 if (entry.stats.isDirectory() && !wh.filterPath(entry)) return;
7973
7974 const joinedPath = sysPath.join(wh.watchPath, entry.path);
7975 const {fullPath} = entry;
7976
7977 if (wh.followSymlinks && entry.stats.isSymbolicLink()) {
7978 // preserve the current depth here since it can't be derived from
7979 // real paths past the symlink
7980 const curDepth = opts.depth === undefined ?
7981 undefined : calcDepth(joinedPath, sysPath.resolve(wh.watchPath)) + 1;
7982
7983 this._handleFsEventsSymlink(joinedPath, fullPath, processPath, curDepth);
7984 } else {
7985 this.emitAdd(joinedPath, entry.stats, processPath, opts, forceAdd);
7986 }
7987 }).on(EV_ERROR, EMPTY_FN).on(STR_END, () => {
7988 this.fsw._emitReady();
7989 });
7990 } else {
7991 this.emitAdd(wh.watchPath, stats, processPath, opts, forceAdd);
7992 this.fsw._emitReady();
7993 }
7994 } catch (error) {
7995 if (!error || this.fsw._handleError(error)) {
7996 // TODO: Strange thing: "should not choke on an ignored watch path" will be failed without 2 ready calls -__-
7997 this.fsw._emitReady();
7998 this.fsw._emitReady();
7999 }
8000 }
8001
8002 if (opts.persistent && forceAdd !== true) {
8003 if (typeof transform === FUNCTION_TYPE) {
8004 // realpath has already been resolved
8005 this.initWatch(undefined, path, wh, processPath);
8006 } else {
8007 let realPath;
8008 try {
8009 realPath = await realpath(wh.watchPath);
8010 } catch (e) {}
8011 this.initWatch(realPath, path, wh, processPath);
8012 }
8013 }
8014 }
8015
8016 }
8017
8018 fseventsHandler.exports = FsEventsHandler;
8019 fseventsHandler.exports.canUse = canUse;
8020 return fseventsHandler.exports;
8021}
8022
8023var hasRequiredChokidar;
8024
8025function requireChokidar () {
8026 if (hasRequiredChokidar) return chokidar$1;
8027 hasRequiredChokidar = 1;
8028
8029 const { EventEmitter } = require$$0$3;
8030 const fs = require$$0$2;
8031 const sysPath = require$$0$1;
8032 const { promisify } = require$$2;
8033 const readdirp = /*@__PURE__*/ requireReaddirp();
8034 const anymatch = /*@__PURE__*/ requireAnymatch().default;
8035 const globParent = /*@__PURE__*/ requireGlobParent();
8036 const isGlob = /*@__PURE__*/ requireIsGlob();
8037 const braces = /*@__PURE__*/ requireBraces();
8038 const normalizePath = /*@__PURE__*/ requireNormalizePath();
8039
8040 const NodeFsHandler = /*@__PURE__*/ requireNodefsHandler();
8041 const FsEventsHandler = /*@__PURE__*/ requireFseventsHandler();
8042 const {
8043 EV_ALL,
8044 EV_READY,
8045 EV_ADD,
8046 EV_CHANGE,
8047 EV_UNLINK,
8048 EV_ADD_DIR,
8049 EV_UNLINK_DIR,
8050 EV_RAW,
8051 EV_ERROR,
8052
8053 STR_CLOSE,
8054 STR_END,
8055
8056 BACK_SLASH_RE,
8057 DOUBLE_SLASH_RE,
8058 SLASH_OR_BACK_SLASH_RE,
8059 DOT_RE,
8060 REPLACER_RE,
8061
8062 SLASH,
8063 SLASH_SLASH,
8064 BRACE_START,
8065 BANG,
8066 ONE_DOT,
8067 TWO_DOTS,
8068 GLOBSTAR,
8069 SLASH_GLOBSTAR,
8070 ANYMATCH_OPTS,
8071 STRING_TYPE,
8072 FUNCTION_TYPE,
8073 EMPTY_STR,
8074 EMPTY_FN,
8075
8076 isWindows,
8077 isMacos,
8078 isIBMi
8079 } = /*@__PURE__*/ requireConstants();
8080
8081 const stat = promisify(fs.stat);
8082 const readdir = promisify(fs.readdir);
8083
8084 /**
8085 * @typedef {String} Path
8086 * @typedef {'all'|'add'|'addDir'|'change'|'unlink'|'unlinkDir'|'raw'|'error'|'ready'} EventName
8087 * @typedef {'readdir'|'watch'|'add'|'remove'|'change'} ThrottleType
8088 */
8089
8090 /**
8091 *
8092 * @typedef {Object} WatchHelpers
8093 * @property {Boolean} followSymlinks
8094 * @property {'stat'|'lstat'} statMethod
8095 * @property {Path} path
8096 * @property {Path} watchPath
8097 * @property {Function} entryPath
8098 * @property {Boolean} hasGlob
8099 * @property {Object} globFilter
8100 * @property {Function} filterPath
8101 * @property {Function} filterDir
8102 */
8103
8104 const arrify = (value = []) => Array.isArray(value) ? value : [value];
8105 const flatten = (list, result = []) => {
8106 list.forEach(item => {
8107 if (Array.isArray(item)) {
8108 flatten(item, result);
8109 } else {
8110 result.push(item);
8111 }
8112 });
8113 return result;
8114 };
8115
8116 const unifyPaths = (paths_) => {
8117 /**
8118 * @type {Array<String>}
8119 */
8120 const paths = flatten(arrify(paths_));
8121 if (!paths.every(p => typeof p === STRING_TYPE)) {
8122 throw new TypeError(`Non-string provided as watch path: ${paths}`);
8123 }
8124 return paths.map(normalizePathToUnix);
8125 };
8126
8127 // If SLASH_SLASH occurs at the beginning of path, it is not replaced
8128 // because "//StoragePC/DrivePool/Movies" is a valid network path
8129 const toUnix = (string) => {
8130 let str = string.replace(BACK_SLASH_RE, SLASH);
8131 let prepend = false;
8132 if (str.startsWith(SLASH_SLASH)) {
8133 prepend = true;
8134 }
8135 while (str.match(DOUBLE_SLASH_RE)) {
8136 str = str.replace(DOUBLE_SLASH_RE, SLASH);
8137 }
8138 if (prepend) {
8139 str = SLASH + str;
8140 }
8141 return str;
8142 };
8143
8144 // Our version of upath.normalize
8145 // TODO: this is not equal to path-normalize module - investigate why
8146 const normalizePathToUnix = (path) => toUnix(sysPath.normalize(toUnix(path)));
8147
8148 const normalizeIgnored = (cwd = EMPTY_STR) => (path) => {
8149 if (typeof path !== STRING_TYPE) return path;
8150 return normalizePathToUnix(sysPath.isAbsolute(path) ? path : sysPath.join(cwd, path));
8151 };
8152
8153 const getAbsolutePath = (path, cwd) => {
8154 if (sysPath.isAbsolute(path)) {
8155 return path;
8156 }
8157 if (path.startsWith(BANG)) {
8158 return BANG + sysPath.join(cwd, path.slice(1));
8159 }
8160 return sysPath.join(cwd, path);
8161 };
8162
8163 const undef = (opts, key) => opts[key] === undefined;
8164
8165 /**
8166 * Directory entry.
8167 * @property {Path} path
8168 * @property {Set<Path>} items
8169 */
8170 class DirEntry {
8171 /**
8172 * @param {Path} dir
8173 * @param {Function} removeWatcher
8174 */
8175 constructor(dir, removeWatcher) {
8176 this.path = dir;
8177 this._removeWatcher = removeWatcher;
8178 /** @type {Set<Path>} */
8179 this.items = new Set();
8180 }
8181
8182 add(item) {
8183 const {items} = this;
8184 if (!items) return;
8185 if (item !== ONE_DOT && item !== TWO_DOTS) items.add(item);
8186 }
8187
8188 async remove(item) {
8189 const {items} = this;
8190 if (!items) return;
8191 items.delete(item);
8192 if (items.size > 0) return;
8193
8194 const dir = this.path;
8195 try {
8196 await readdir(dir);
8197 } catch (err) {
8198 if (this._removeWatcher) {
8199 this._removeWatcher(sysPath.dirname(dir), sysPath.basename(dir));
8200 }
8201 }
8202 }
8203
8204 has(item) {
8205 const {items} = this;
8206 if (!items) return;
8207 return items.has(item);
8208 }
8209
8210 /**
8211 * @returns {Array<String>}
8212 */
8213 getChildren() {
8214 const {items} = this;
8215 if (!items) return;
8216 return [...items.values()];
8217 }
8218
8219 dispose() {
8220 this.items.clear();
8221 delete this.path;
8222 delete this._removeWatcher;
8223 delete this.items;
8224 Object.freeze(this);
8225 }
8226 }
8227
8228 const STAT_METHOD_F = 'stat';
8229 const STAT_METHOD_L = 'lstat';
8230 class WatchHelper {
8231 constructor(path, watchPath, follow, fsw) {
8232 this.fsw = fsw;
8233 this.path = path = path.replace(REPLACER_RE, EMPTY_STR);
8234 this.watchPath = watchPath;
8235 this.fullWatchPath = sysPath.resolve(watchPath);
8236 this.hasGlob = watchPath !== path;
8237 /** @type {object|boolean} */
8238 if (path === EMPTY_STR) this.hasGlob = false;
8239 this.globSymlink = this.hasGlob && follow ? undefined : false;
8240 this.globFilter = this.hasGlob ? anymatch(path, undefined, ANYMATCH_OPTS) : false;
8241 this.dirParts = this.getDirParts(path);
8242 this.dirParts.forEach((parts) => {
8243 if (parts.length > 1) parts.pop();
8244 });
8245 this.followSymlinks = follow;
8246 this.statMethod = follow ? STAT_METHOD_F : STAT_METHOD_L;
8247 }
8248
8249 checkGlobSymlink(entry) {
8250 // only need to resolve once
8251 // first entry should always have entry.parentDir === EMPTY_STR
8252 if (this.globSymlink === undefined) {
8253 this.globSymlink = entry.fullParentDir === this.fullWatchPath ?
8254 false : {realPath: entry.fullParentDir, linkPath: this.fullWatchPath};
8255 }
8256
8257 if (this.globSymlink) {
8258 return entry.fullPath.replace(this.globSymlink.realPath, this.globSymlink.linkPath);
8259 }
8260
8261 return entry.fullPath;
8262 }
8263
8264 entryPath(entry) {
8265 return sysPath.join(this.watchPath,
8266 sysPath.relative(this.watchPath, this.checkGlobSymlink(entry))
8267 );
8268 }
8269
8270 filterPath(entry) {
8271 const {stats} = entry;
8272 if (stats && stats.isSymbolicLink()) return this.filterDir(entry);
8273 const resolvedPath = this.entryPath(entry);
8274 const matchesGlob = this.hasGlob && typeof this.globFilter === FUNCTION_TYPE ?
8275 this.globFilter(resolvedPath) : true;
8276 return matchesGlob &&
8277 this.fsw._isntIgnored(resolvedPath, stats) &&
8278 this.fsw._hasReadPermissions(stats);
8279 }
8280
8281 getDirParts(path) {
8282 if (!this.hasGlob) return [];
8283 const parts = [];
8284 const expandedPath = path.includes(BRACE_START) ? braces.expand(path) : [path];
8285 expandedPath.forEach((path) => {
8286 parts.push(sysPath.relative(this.watchPath, path).split(SLASH_OR_BACK_SLASH_RE));
8287 });
8288 return parts;
8289 }
8290
8291 filterDir(entry) {
8292 if (this.hasGlob) {
8293 const entryParts = this.getDirParts(this.checkGlobSymlink(entry));
8294 let globstar = false;
8295 this.unmatchedGlob = !this.dirParts.some((parts) => {
8296 return parts.every((part, i) => {
8297 if (part === GLOBSTAR) globstar = true;
8298 return globstar || !entryParts[0][i] || anymatch(part, entryParts[0][i], ANYMATCH_OPTS);
8299 });
8300 });
8301 }
8302 return !this.unmatchedGlob && this.fsw._isntIgnored(this.entryPath(entry), entry.stats);
8303 }
8304 }
8305
8306 /**
8307 * Watches files & directories for changes. Emitted events:
8308 * `add`, `addDir`, `change`, `unlink`, `unlinkDir`, `all`, `error`
8309 *
8310 * new FSWatcher()
8311 * .add(directories)
8312 * .on('add', path => log('File', path, 'was added'))
8313 */
8314 class FSWatcher extends EventEmitter {
8315 // Not indenting methods for history sake; for now.
8316 constructor(_opts) {
8317 super();
8318
8319 const opts = {};
8320 if (_opts) Object.assign(opts, _opts); // for frozen objects
8321
8322 /** @type {Map<String, DirEntry>} */
8323 this._watched = new Map();
8324 /** @type {Map<String, Array>} */
8325 this._closers = new Map();
8326 /** @type {Set<String>} */
8327 this._ignoredPaths = new Set();
8328
8329 /** @type {Map<ThrottleType, Map>} */
8330 this._throttled = new Map();
8331
8332 /** @type {Map<Path, String|Boolean>} */
8333 this._symlinkPaths = new Map();
8334
8335 this._streams = new Set();
8336 this.closed = false;
8337
8338 // Set up default options.
8339 if (undef(opts, 'persistent')) opts.persistent = true;
8340 if (undef(opts, 'ignoreInitial')) opts.ignoreInitial = false;
8341 if (undef(opts, 'ignorePermissionErrors')) opts.ignorePermissionErrors = false;
8342 if (undef(opts, 'interval')) opts.interval = 100;
8343 if (undef(opts, 'binaryInterval')) opts.binaryInterval = 300;
8344 if (undef(opts, 'disableGlobbing')) opts.disableGlobbing = false;
8345 opts.enableBinaryInterval = opts.binaryInterval !== opts.interval;
8346
8347 // Enable fsevents on OS X when polling isn't explicitly enabled.
8348 if (undef(opts, 'useFsEvents')) opts.useFsEvents = !opts.usePolling;
8349
8350 // If we can't use fsevents, ensure the options reflect it's disabled.
8351 const canUseFsEvents = FsEventsHandler.canUse();
8352 if (!canUseFsEvents) opts.useFsEvents = false;
8353
8354 // Use polling on Mac if not using fsevents.
8355 // Other platforms use non-polling fs_watch.
8356 if (undef(opts, 'usePolling') && !opts.useFsEvents) {
8357 opts.usePolling = isMacos;
8358 }
8359
8360 // Always default to polling on IBM i because fs.watch() is not available on IBM i.
8361 if(isIBMi) {
8362 opts.usePolling = true;
8363 }
8364
8365 // Global override (useful for end-developers that need to force polling for all
8366 // instances of chokidar, regardless of usage/dependency depth)
8367 const envPoll = process.env.CHOKIDAR_USEPOLLING;
8368 if (envPoll !== undefined) {
8369 const envLower = envPoll.toLowerCase();
8370
8371 if (envLower === 'false' || envLower === '0') {
8372 opts.usePolling = false;
8373 } else if (envLower === 'true' || envLower === '1') {
8374 opts.usePolling = true;
8375 } else {
8376 opts.usePolling = !!envLower;
8377 }
8378 }
8379 const envInterval = process.env.CHOKIDAR_INTERVAL;
8380 if (envInterval) {
8381 opts.interval = Number.parseInt(envInterval, 10);
8382 }
8383
8384 // Editor atomic write normalization enabled by default with fs.watch
8385 if (undef(opts, 'atomic')) opts.atomic = !opts.usePolling && !opts.useFsEvents;
8386 if (opts.atomic) this._pendingUnlinks = new Map();
8387
8388 if (undef(opts, 'followSymlinks')) opts.followSymlinks = true;
8389
8390 if (undef(opts, 'awaitWriteFinish')) opts.awaitWriteFinish = false;
8391 if (opts.awaitWriteFinish === true) opts.awaitWriteFinish = {};
8392 const awf = opts.awaitWriteFinish;
8393 if (awf) {
8394 if (!awf.stabilityThreshold) awf.stabilityThreshold = 2000;
8395 if (!awf.pollInterval) awf.pollInterval = 100;
8396 this._pendingWrites = new Map();
8397 }
8398 if (opts.ignored) opts.ignored = arrify(opts.ignored);
8399
8400 let readyCalls = 0;
8401 this._emitReady = () => {
8402 readyCalls++;
8403 if (readyCalls >= this._readyCount) {
8404 this._emitReady = EMPTY_FN;
8405 this._readyEmitted = true;
8406 // use process.nextTick to allow time for listener to be bound
8407 process.nextTick(() => this.emit(EV_READY));
8408 }
8409 };
8410 this._emitRaw = (...args) => this.emit(EV_RAW, ...args);
8411 this._readyEmitted = false;
8412 this.options = opts;
8413
8414 // Initialize with proper watcher.
8415 if (opts.useFsEvents) {
8416 this._fsEventsHandler = new FsEventsHandler(this);
8417 } else {
8418 this._nodeFsHandler = new NodeFsHandler(this);
8419 }
8420
8421 // You’re frozen when your heart’s not open.
8422 Object.freeze(opts);
8423 }
8424
8425 // Public methods
8426
8427 /**
8428 * Adds paths to be watched on an existing FSWatcher instance
8429 * @param {Path|Array<Path>} paths_
8430 * @param {String=} _origAdd private; for handling non-existent paths to be watched
8431 * @param {Boolean=} _internal private; indicates a non-user add
8432 * @returns {FSWatcher} for chaining
8433 */
8434 add(paths_, _origAdd, _internal) {
8435 const {cwd, disableGlobbing} = this.options;
8436 this.closed = false;
8437 let paths = unifyPaths(paths_);
8438 if (cwd) {
8439 paths = paths.map((path) => {
8440 const absPath = getAbsolutePath(path, cwd);
8441
8442 // Check `path` instead of `absPath` because the cwd portion can't be a glob
8443 if (disableGlobbing || !isGlob(path)) {
8444 return absPath;
8445 }
8446 return normalizePath(absPath);
8447 });
8448 }
8449
8450 // set aside negated glob strings
8451 paths = paths.filter((path) => {
8452 if (path.startsWith(BANG)) {
8453 this._ignoredPaths.add(path.slice(1));
8454 return false;
8455 }
8456
8457 // if a path is being added that was previously ignored, stop ignoring it
8458 this._ignoredPaths.delete(path);
8459 this._ignoredPaths.delete(path + SLASH_GLOBSTAR);
8460
8461 // reset the cached userIgnored anymatch fn
8462 // to make ignoredPaths changes effective
8463 this._userIgnored = undefined;
8464
8465 return true;
8466 });
8467
8468 if (this.options.useFsEvents && this._fsEventsHandler) {
8469 if (!this._readyCount) this._readyCount = paths.length;
8470 if (this.options.persistent) this._readyCount += paths.length;
8471 paths.forEach((path) => this._fsEventsHandler._addToFsEvents(path));
8472 } else {
8473 if (!this._readyCount) this._readyCount = 0;
8474 this._readyCount += paths.length;
8475 Promise.all(
8476 paths.map(async path => {
8477 const res = await this._nodeFsHandler._addToNodeFs(path, !_internal, 0, 0, _origAdd);
8478 if (res) this._emitReady();
8479 return res;
8480 })
8481 ).then(results => {
8482 if (this.closed) return;
8483 results.filter(item => item).forEach(item => {
8484 this.add(sysPath.dirname(item), sysPath.basename(_origAdd || item));
8485 });
8486 });
8487 }
8488
8489 return this;
8490 }
8491
8492 /**
8493 * Close watchers or start ignoring events from specified paths.
8494 * @param {Path|Array<Path>} paths_ - string or array of strings, file/directory paths and/or globs
8495 * @returns {FSWatcher} for chaining
8496 */
8497 unwatch(paths_) {
8498 if (this.closed) return this;
8499 const paths = unifyPaths(paths_);
8500 const {cwd} = this.options;
8501
8502 paths.forEach((path) => {
8503 // convert to absolute path unless relative path already matches
8504 if (!sysPath.isAbsolute(path) && !this._closers.has(path)) {
8505 if (cwd) path = sysPath.join(cwd, path);
8506 path = sysPath.resolve(path);
8507 }
8508
8509 this._closePath(path);
8510
8511 this._ignoredPaths.add(path);
8512 if (this._watched.has(path)) {
8513 this._ignoredPaths.add(path + SLASH_GLOBSTAR);
8514 }
8515
8516 // reset the cached userIgnored anymatch fn
8517 // to make ignoredPaths changes effective
8518 this._userIgnored = undefined;
8519 });
8520
8521 return this;
8522 }
8523
8524 /**
8525 * Close watchers and remove all listeners from watched paths.
8526 * @returns {Promise<void>}.
8527 */
8528 close() {
8529 if (this.closed) return this._closePromise;
8530 this.closed = true;
8531
8532 // Memory management.
8533 this.removeAllListeners();
8534 const closers = [];
8535 this._closers.forEach(closerList => closerList.forEach(closer => {
8536 const promise = closer();
8537 if (promise instanceof Promise) closers.push(promise);
8538 }));
8539 this._streams.forEach(stream => stream.destroy());
8540 this._userIgnored = undefined;
8541 this._readyCount = 0;
8542 this._readyEmitted = false;
8543 this._watched.forEach(dirent => dirent.dispose());
8544 ['closers', 'watched', 'streams', 'symlinkPaths', 'throttled'].forEach(key => {
8545 this[`_${key}`].clear();
8546 });
8547
8548 this._closePromise = closers.length ? Promise.all(closers).then(() => undefined) : Promise.resolve();
8549 return this._closePromise;
8550 }
8551
8552 /**
8553 * Expose list of watched paths
8554 * @returns {Object} for chaining
8555 */
8556 getWatched() {
8557 const watchList = {};
8558 this._watched.forEach((entry, dir) => {
8559 const key = this.options.cwd ? sysPath.relative(this.options.cwd, dir) : dir;
8560 watchList[key || ONE_DOT] = entry.getChildren().sort();
8561 });
8562 return watchList;
8563 }
8564
8565 emitWithAll(event, args) {
8566 this.emit(...args);
8567 if (event !== EV_ERROR) this.emit(EV_ALL, ...args);
8568 }
8569
8570 // Common helpers
8571 // --------------
8572
8573 /**
8574 * Normalize and emit events.
8575 * Calling _emit DOES NOT MEAN emit() would be called!
8576 * @param {EventName} event Type of event
8577 * @param {Path} path File or directory path
8578 * @param {*=} val1 arguments to be passed with event
8579 * @param {*=} val2
8580 * @param {*=} val3
8581 * @returns the error if defined, otherwise the value of the FSWatcher instance's `closed` flag
8582 */
8583 async _emit(event, path, val1, val2, val3) {
8584 if (this.closed) return;
8585
8586 const opts = this.options;
8587 if (isWindows) path = sysPath.normalize(path);
8588 if (opts.cwd) path = sysPath.relative(opts.cwd, path);
8589 /** @type Array<any> */
8590 const args = [event, path];
8591 if (val3 !== undefined) args.push(val1, val2, val3);
8592 else if (val2 !== undefined) args.push(val1, val2);
8593 else if (val1 !== undefined) args.push(val1);
8594
8595 const awf = opts.awaitWriteFinish;
8596 let pw;
8597 if (awf && (pw = this._pendingWrites.get(path))) {
8598 pw.lastChange = new Date();
8599 return this;
8600 }
8601
8602 if (opts.atomic) {
8603 if (event === EV_UNLINK) {
8604 this._pendingUnlinks.set(path, args);
8605 setTimeout(() => {
8606 this._pendingUnlinks.forEach((entry, path) => {
8607 this.emit(...entry);
8608 this.emit(EV_ALL, ...entry);
8609 this._pendingUnlinks.delete(path);
8610 });
8611 }, typeof opts.atomic === 'number' ? opts.atomic : 100);
8612 return this;
8613 }
8614 if (event === EV_ADD && this._pendingUnlinks.has(path)) {
8615 event = args[0] = EV_CHANGE;
8616 this._pendingUnlinks.delete(path);
8617 }
8618 }
8619
8620 if (awf && (event === EV_ADD || event === EV_CHANGE) && this._readyEmitted) {
8621 const awfEmit = (err, stats) => {
8622 if (err) {
8623 event = args[0] = EV_ERROR;
8624 args[1] = err;
8625 this.emitWithAll(event, args);
8626 } else if (stats) {
8627 // if stats doesn't exist the file must have been deleted
8628 if (args.length > 2) {
8629 args[2] = stats;
8630 } else {
8631 args.push(stats);
8632 }
8633 this.emitWithAll(event, args);
8634 }
8635 };
8636
8637 this._awaitWriteFinish(path, awf.stabilityThreshold, event, awfEmit);
8638 return this;
8639 }
8640
8641 if (event === EV_CHANGE) {
8642 const isThrottled = !this._throttle(EV_CHANGE, path, 50);
8643 if (isThrottled) return this;
8644 }
8645
8646 if (opts.alwaysStat && val1 === undefined &&
8647 (event === EV_ADD || event === EV_ADD_DIR || event === EV_CHANGE)
8648 ) {
8649 const fullPath = opts.cwd ? sysPath.join(opts.cwd, path) : path;
8650 let stats;
8651 try {
8652 stats = await stat(fullPath);
8653 } catch (err) {}
8654 // Suppress event when fs_stat fails, to avoid sending undefined 'stat'
8655 if (!stats || this.closed) return;
8656 args.push(stats);
8657 }
8658 this.emitWithAll(event, args);
8659
8660 return this;
8661 }
8662
8663 /**
8664 * Common handler for errors
8665 * @param {Error} error
8666 * @returns {Error|Boolean} The error if defined, otherwise the value of the FSWatcher instance's `closed` flag
8667 */
8668 _handleError(error) {
8669 const code = error && error.code;
8670 if (error && code !== 'ENOENT' && code !== 'ENOTDIR' &&
8671 (!this.options.ignorePermissionErrors || (code !== 'EPERM' && code !== 'EACCES'))
8672 ) {
8673 this.emit(EV_ERROR, error);
8674 }
8675 return error || this.closed;
8676 }
8677
8678 /**
8679 * Helper utility for throttling
8680 * @param {ThrottleType} actionType type being throttled
8681 * @param {Path} path being acted upon
8682 * @param {Number} timeout duration of time to suppress duplicate actions
8683 * @returns {Object|false} tracking object or false if action should be suppressed
8684 */
8685 _throttle(actionType, path, timeout) {
8686 if (!this._throttled.has(actionType)) {
8687 this._throttled.set(actionType, new Map());
8688 }
8689
8690 /** @type {Map<Path, Object>} */
8691 const action = this._throttled.get(actionType);
8692 /** @type {Object} */
8693 const actionPath = action.get(path);
8694
8695 if (actionPath) {
8696 actionPath.count++;
8697 return false;
8698 }
8699
8700 let timeoutObject;
8701 const clear = () => {
8702 const item = action.get(path);
8703 const count = item ? item.count : 0;
8704 action.delete(path);
8705 clearTimeout(timeoutObject);
8706 if (item) clearTimeout(item.timeoutObject);
8707 return count;
8708 };
8709 timeoutObject = setTimeout(clear, timeout);
8710 const thr = {timeoutObject, clear, count: 0};
8711 action.set(path, thr);
8712 return thr;
8713 }
8714
8715 _incrReadyCount() {
8716 return this._readyCount++;
8717 }
8718
8719 /**
8720 * Awaits write operation to finish.
8721 * Polls a newly created file for size variations. When files size does not change for 'threshold' milliseconds calls callback.
8722 * @param {Path} path being acted upon
8723 * @param {Number} threshold Time in milliseconds a file size must be fixed before acknowledging write OP is finished
8724 * @param {EventName} event
8725 * @param {Function} awfEmit Callback to be called when ready for event to be emitted.
8726 */
8727 _awaitWriteFinish(path, threshold, event, awfEmit) {
8728 let timeoutHandler;
8729
8730 let fullPath = path;
8731 if (this.options.cwd && !sysPath.isAbsolute(path)) {
8732 fullPath = sysPath.join(this.options.cwd, path);
8733 }
8734
8735 const now = new Date();
8736
8737 const awaitWriteFinish = (prevStat) => {
8738 fs.stat(fullPath, (err, curStat) => {
8739 if (err || !this._pendingWrites.has(path)) {
8740 if (err && err.code !== 'ENOENT') awfEmit(err);
8741 return;
8742 }
8743
8744 const now = Number(new Date());
8745
8746 if (prevStat && curStat.size !== prevStat.size) {
8747 this._pendingWrites.get(path).lastChange = now;
8748 }
8749 const pw = this._pendingWrites.get(path);
8750 const df = now - pw.lastChange;
8751
8752 if (df >= threshold) {
8753 this._pendingWrites.delete(path);
8754 awfEmit(undefined, curStat);
8755 } else {
8756 timeoutHandler = setTimeout(
8757 awaitWriteFinish,
8758 this.options.awaitWriteFinish.pollInterval,
8759 curStat
8760 );
8761 }
8762 });
8763 };
8764
8765 if (!this._pendingWrites.has(path)) {
8766 this._pendingWrites.set(path, {
8767 lastChange: now,
8768 cancelWait: () => {
8769 this._pendingWrites.delete(path);
8770 clearTimeout(timeoutHandler);
8771 return event;
8772 }
8773 });
8774 timeoutHandler = setTimeout(
8775 awaitWriteFinish,
8776 this.options.awaitWriteFinish.pollInterval
8777 );
8778 }
8779 }
8780
8781 _getGlobIgnored() {
8782 return [...this._ignoredPaths.values()];
8783 }
8784
8785 /**
8786 * Determines whether user has asked to ignore this path.
8787 * @param {Path} path filepath or dir
8788 * @param {fs.Stats=} stats result of fs.stat
8789 * @returns {Boolean}
8790 */
8791 _isIgnored(path, stats) {
8792 if (this.options.atomic && DOT_RE.test(path)) return true;
8793 if (!this._userIgnored) {
8794 const {cwd} = this.options;
8795 const ign = this.options.ignored;
8796
8797 const ignored = ign && ign.map(normalizeIgnored(cwd));
8798 const paths = arrify(ignored)
8799 .filter((path) => typeof path === STRING_TYPE && !isGlob(path))
8800 .map((path) => path + SLASH_GLOBSTAR);
8801 const list = this._getGlobIgnored().map(normalizeIgnored(cwd)).concat(ignored, paths);
8802 this._userIgnored = anymatch(list, undefined, ANYMATCH_OPTS);
8803 }
8804
8805 return this._userIgnored([path, stats]);
8806 }
8807
8808 _isntIgnored(path, stat) {
8809 return !this._isIgnored(path, stat);
8810 }
8811
8812 /**
8813 * Provides a set of common helpers and properties relating to symlink and glob handling.
8814 * @param {Path} path file, directory, or glob pattern being watched
8815 * @param {Number=} depth at any depth > 0, this isn't a glob
8816 * @returns {WatchHelper} object containing helpers for this path
8817 */
8818 _getWatchHelpers(path, depth) {
8819 const watchPath = depth || this.options.disableGlobbing || !isGlob(path) ? path : globParent(path);
8820 const follow = this.options.followSymlinks;
8821
8822 return new WatchHelper(path, watchPath, follow, this);
8823 }
8824
8825 // Directory helpers
8826 // -----------------
8827
8828 /**
8829 * Provides directory tracking objects
8830 * @param {String} directory path of the directory
8831 * @returns {DirEntry} the directory's tracking object
8832 */
8833 _getWatchedDir(directory) {
8834 if (!this._boundRemove) this._boundRemove = this._remove.bind(this);
8835 const dir = sysPath.resolve(directory);
8836 if (!this._watched.has(dir)) this._watched.set(dir, new DirEntry(dir, this._boundRemove));
8837 return this._watched.get(dir);
8838 }
8839
8840 // File helpers
8841 // ------------
8842
8843 /**
8844 * Check for read permissions.
8845 * Based on this answer on SO: https://stackoverflow.com/a/11781404/1358405
8846 * @param {fs.Stats} stats - object, result of fs_stat
8847 * @returns {Boolean} indicates whether the file can be read
8848 */
8849 _hasReadPermissions(stats) {
8850 if (this.options.ignorePermissionErrors) return true;
8851
8852 // stats.mode may be bigint
8853 const md = stats && Number.parseInt(stats.mode, 10);
8854 const st = md & 0o777;
8855 const it = Number.parseInt(st.toString(8)[0], 10);
8856 return Boolean(4 & it);
8857 }
8858
8859 /**
8860 * Handles emitting unlink events for
8861 * files and directories, and via recursion, for
8862 * files and directories within directories that are unlinked
8863 * @param {String} directory within which the following item is located
8864 * @param {String} item base path of item/directory
8865 * @returns {void}
8866 */
8867 _remove(directory, item, isDirectory) {
8868 // if what is being deleted is a directory, get that directory's paths
8869 // for recursive deleting and cleaning of watched object
8870 // if it is not a directory, nestedDirectoryChildren will be empty array
8871 const path = sysPath.join(directory, item);
8872 const fullPath = sysPath.resolve(path);
8873 isDirectory = isDirectory != null
8874 ? isDirectory
8875 : this._watched.has(path) || this._watched.has(fullPath);
8876
8877 // prevent duplicate handling in case of arriving here nearly simultaneously
8878 // via multiple paths (such as _handleFile and _handleDir)
8879 if (!this._throttle('remove', path, 100)) return;
8880
8881 // if the only watched file is removed, watch for its return
8882 if (!isDirectory && !this.options.useFsEvents && this._watched.size === 1) {
8883 this.add(directory, item, true);
8884 }
8885
8886 // This will create a new entry in the watched object in either case
8887 // so we got to do the directory check beforehand
8888 const wp = this._getWatchedDir(path);
8889 const nestedDirectoryChildren = wp.getChildren();
8890
8891 // Recursively remove children directories / files.
8892 nestedDirectoryChildren.forEach(nested => this._remove(path, nested));
8893
8894 // Check if item was on the watched list and remove it
8895 const parent = this._getWatchedDir(directory);
8896 const wasTracked = parent.has(item);
8897 parent.remove(item);
8898
8899 // Fixes issue #1042 -> Relative paths were detected and added as symlinks
8900 // (https://github.com/paulmillr/chokidar/blob/e1753ddbc9571bdc33b4a4af172d52cb6e611c10/lib/nodefs-handler.js#L612),
8901 // but never removed from the map in case the path was deleted.
8902 // This leads to an incorrect state if the path was recreated:
8903 // https://github.com/paulmillr/chokidar/blob/e1753ddbc9571bdc33b4a4af172d52cb6e611c10/lib/nodefs-handler.js#L553
8904 if (this._symlinkPaths.has(fullPath)) {
8905 this._symlinkPaths.delete(fullPath);
8906 }
8907
8908 // If we wait for this file to be fully written, cancel the wait.
8909 let relPath = path;
8910 if (this.options.cwd) relPath = sysPath.relative(this.options.cwd, path);
8911 if (this.options.awaitWriteFinish && this._pendingWrites.has(relPath)) {
8912 const event = this._pendingWrites.get(relPath).cancelWait();
8913 if (event === EV_ADD) return;
8914 }
8915
8916 // The Entry will either be a directory that just got removed
8917 // or a bogus entry to a file, in either case we have to remove it
8918 this._watched.delete(path);
8919 this._watched.delete(fullPath);
8920 const eventName = isDirectory ? EV_UNLINK_DIR : EV_UNLINK;
8921 if (wasTracked && !this._isIgnored(path)) this._emit(eventName, path);
8922
8923 // Avoid conflicts if we later create another file with the same name
8924 if (!this.options.useFsEvents) {
8925 this._closePath(path);
8926 }
8927 }
8928
8929 /**
8930 * Closes all watchers for a path
8931 * @param {Path} path
8932 */
8933 _closePath(path) {
8934 this._closeFile(path);
8935 const dir = sysPath.dirname(path);
8936 this._getWatchedDir(dir).remove(sysPath.basename(path));
8937 }
8938
8939 /**
8940 * Closes only file-specific watchers
8941 * @param {Path} path
8942 */
8943 _closeFile(path) {
8944 const closers = this._closers.get(path);
8945 if (!closers) return;
8946 closers.forEach(closer => closer());
8947 this._closers.delete(path);
8948 }
8949
8950 /**
8951 *
8952 * @param {Path} path
8953 * @param {Function} closer
8954 */
8955 _addPathCloser(path, closer) {
8956 if (!closer) return;
8957 let list = this._closers.get(path);
8958 if (!list) {
8959 list = [];
8960 this._closers.set(path, list);
8961 }
8962 list.push(closer);
8963 }
8964
8965 _readdirp(root, opts) {
8966 if (this.closed) return;
8967 const options = {type: EV_ALL, alwaysStat: true, lstat: true, ...opts};
8968 let stream = readdirp(root, options);
8969 this._streams.add(stream);
8970 stream.once(STR_CLOSE, () => {
8971 stream = undefined;
8972 });
8973 stream.once(STR_END, () => {
8974 if (stream) {
8975 this._streams.delete(stream);
8976 stream = undefined;
8977 }
8978 });
8979 return stream;
8980 }
8981
8982 }
8983
8984 // Export FSWatcher class
8985 chokidar$1.FSWatcher = FSWatcher;
8986
8987 /**
8988 * Instantiates watcher with paths to be tracked.
8989 * @param {String|Array<String>} paths file/directory paths and/or globs
8990 * @param {Object=} options chokidar opts
8991 * @returns an instance of FSWatcher for chaining.
8992 */
8993 const watch = (paths, options) => {
8994 const watcher = new FSWatcher(options);
8995 watcher.add(paths);
8996 return watcher;
8997 };
8998
8999 chokidar$1.watch = watch;
9000 return chokidar$1;
9001}
9002
9003var chokidarExports = /*@__PURE__*/ requireChokidar();
9004const chokidar = /*@__PURE__*/getDefaultExportFromCjs(chokidarExports);
9005
9006class FileWatcher {
9007 constructor(task, chokidarOptions) {
9008 this.transformWatchers = new Map();
9009 this.chokidarOptions = chokidarOptions;
9010 this.task = task;
9011 this.watcher = this.createWatcher(null);
9012 }
9013 close() {
9014 this.watcher.close();
9015 for (const watcher of this.transformWatchers.values()) {
9016 watcher.close();
9017 }
9018 }
9019 unwatch(id) {
9020 this.watcher.unwatch(id);
9021 const transformWatcher = this.transformWatchers.get(id);
9022 if (transformWatcher) {
9023 this.transformWatchers.delete(id);
9024 transformWatcher.close();
9025 }
9026 }
9027 watch(id, isTransformDependency) {
9028 if (isTransformDependency) {
9029 const watcher = this.transformWatchers.get(id) ?? this.createWatcher(id);
9030 watcher.add(id);
9031 this.transformWatchers.set(id, watcher);
9032 }
9033 else {
9034 this.watcher.add(id);
9035 }
9036 }
9037 createWatcher(transformWatcherId) {
9038 const task = this.task;
9039 const isLinux = platform() === 'linux';
9040 const isFreeBSD = platform() === 'freebsd';
9041 const isTransformDependency = transformWatcherId !== null;
9042 const handleChange = (id, event) => {
9043 const changedId = transformWatcherId || id;
9044 if (isLinux || isFreeBSD) {
9045 // unwatching and watching fixes an issue with chokidar where on certain systems,
9046 // a file that was unlinked and immediately recreated would create a change event
9047 // but then no longer any further events
9048 watcher.unwatch(changedId);
9049 watcher.add(changedId);
9050 }
9051 task.invalidate(changedId, { event, isTransformDependency });
9052 };
9053 const watcher = chokidar
9054 .watch([], this.chokidarOptions)
9055 .on('add', id => handleChange(id, 'create'))
9056 .on('change', id => handleChange(id, 'update'))
9057 .on('unlink', id => handleChange(id, 'delete'));
9058 return watcher;
9059 }
9060}
9061
9062const eventsRewrites = {
9063 create: {
9064 create: 'buggy',
9065 delete: null, //delete file from map
9066 update: 'create'
9067 },
9068 delete: {
9069 create: 'update',
9070 delete: 'buggy',
9071 update: 'buggy'
9072 },
9073 update: {
9074 create: 'buggy',
9075 delete: 'delete',
9076 update: 'update'
9077 }
9078};
9079class Watcher {
9080 constructor(optionsList, emitter) {
9081 this.buildDelay = 0;
9082 this.buildTimeout = null;
9083 this.closed = false;
9084 this.invalidatedIds = new Map();
9085 this.rerun = false;
9086 this.running = true;
9087 this.emitter = emitter;
9088 emitter.close = this.close.bind(this);
9089 this.tasks = optionsList.map(options => new Task(this, options));
9090 for (const { watch } of optionsList) {
9091 if (watch && typeof watch.buildDelay === 'number') {
9092 this.buildDelay = Math.max(this.buildDelay, watch.buildDelay);
9093 }
9094 }
9095 process$1.nextTick(() => this.run());
9096 }
9097 async close() {
9098 if (this.closed)
9099 return;
9100 this.closed = true;
9101 if (this.buildTimeout)
9102 clearTimeout(this.buildTimeout);
9103 for (const task of this.tasks) {
9104 task.close();
9105 }
9106 await this.emitter.emit('close');
9107 this.emitter.removeAllListeners();
9108 }
9109 invalidate(file) {
9110 if (file) {
9111 const previousEvent = this.invalidatedIds.get(file.id);
9112 const event = previousEvent ? eventsRewrites[previousEvent][file.event] : file.event;
9113 if (event === 'buggy') {
9114 //TODO: throws or warn? Currently just ignore, uses new event
9115 this.invalidatedIds.set(file.id, file.event);
9116 }
9117 else if (event === null) {
9118 this.invalidatedIds.delete(file.id);
9119 }
9120 else {
9121 this.invalidatedIds.set(file.id, event);
9122 }
9123 }
9124 if (this.running) {
9125 this.rerun = true;
9126 return;
9127 }
9128 if (this.buildTimeout)
9129 clearTimeout(this.buildTimeout);
9130 this.buildTimeout = setTimeout(async () => {
9131 this.buildTimeout = null;
9132 try {
9133 await Promise.all([...this.invalidatedIds].map(([id, event]) => this.emitter.emit('change', id, { event })));
9134 this.invalidatedIds.clear();
9135 await this.emitter.emit('restart');
9136 this.emitter.removeListenersForCurrentRun();
9137 this.run();
9138 }
9139 catch (error) {
9140 this.invalidatedIds.clear();
9141 await this.emitter.emit('event', {
9142 code: 'ERROR',
9143 error,
9144 result: null
9145 });
9146 await this.emitter.emit('event', {
9147 code: 'END'
9148 });
9149 }
9150 }, this.buildDelay);
9151 }
9152 async run() {
9153 this.running = true;
9154 await this.emitter.emit('event', {
9155 code: 'START'
9156 });
9157 for (const task of this.tasks) {
9158 await task.run();
9159 }
9160 this.running = false;
9161 await this.emitter.emit('event', {
9162 code: 'END'
9163 });
9164 if (this.rerun) {
9165 this.rerun = false;
9166 this.invalidate();
9167 }
9168 }
9169}
9170class Task {
9171 constructor(watcher, options) {
9172 this.cache = { modules: [] };
9173 this.watchFiles = [];
9174 this.closed = false;
9175 this.invalidated = true;
9176 this.watched = new Set();
9177 this.watcher = watcher;
9178 this.options = options;
9179 this.skipWrite = Boolean(options.watch && options.watch.skipWrite);
9180 this.outputs = this.options.output;
9181 this.outputFiles = this.outputs.map(output => {
9182 if (output.file || output.dir)
9183 return path.resolve(output.file || output.dir);
9184 return undefined;
9185 });
9186 this.watchOptions = this.options.watch || {};
9187 this.filter = createFilter(this.watchOptions.include, this.watchOptions.exclude);
9188 this.fileWatcher = new FileWatcher(this, {
9189 ...this.watchOptions.chokidar,
9190 disableGlobbing: true,
9191 ignoreInitial: true
9192 });
9193 }
9194 close() {
9195 this.closed = true;
9196 this.fileWatcher.close();
9197 }
9198 invalidate(id, details) {
9199 this.invalidated = true;
9200 if (details.isTransformDependency) {
9201 for (const module of this.cache.modules) {
9202 if (!module.transformDependencies.includes(id))
9203 continue;
9204 // effective invalidation
9205 module.originalCode = null;
9206 }
9207 }
9208 this.watcher.invalidate({ event: details.event, id });
9209 this.watchOptions.onInvalidate?.(id);
9210 }
9211 async run() {
9212 if (!this.invalidated)
9213 return;
9214 this.invalidated = false;
9215 const options = {
9216 ...this.options,
9217 cache: this.cache
9218 };
9219 const start = Date.now();
9220 await this.watcher.emitter.emit('event', {
9221 code: 'BUNDLE_START',
9222 input: this.options.input,
9223 output: this.outputFiles
9224 });
9225 let result = null;
9226 try {
9227 result = await rollupInternal(options, this.watcher.emitter);
9228 if (this.closed) {
9229 return;
9230 }
9231 this.updateWatchedFiles(result);
9232 if (!this.skipWrite) {
9233 await Promise.all(this.outputs.map(output => result.write(output)));
9234 if (this.closed) {
9235 return;
9236 }
9237 this.updateWatchedFiles(result);
9238 }
9239 await this.watcher.emitter.emit('event', {
9240 code: 'BUNDLE_END',
9241 duration: Date.now() - start,
9242 input: this.options.input,
9243 output: this.outputFiles,
9244 result
9245 });
9246 }
9247 catch (error) {
9248 if (!this.closed) {
9249 if (Array.isArray(error.watchFiles)) {
9250 for (const id of error.watchFiles) {
9251 this.watchFile(id);
9252 }
9253 }
9254 if (error.id) {
9255 this.cache.modules = this.cache.modules.filter(module => module.id !== error.id);
9256 }
9257 }
9258 await this.watcher.emitter.emit('event', {
9259 code: 'ERROR',
9260 error,
9261 result
9262 });
9263 }
9264 }
9265 updateWatchedFiles(result) {
9266 const previouslyWatched = this.watched;
9267 this.watched = new Set();
9268 this.watchFiles = result.watchFiles;
9269 this.cache = result.cache;
9270 for (const id of this.watchFiles) {
9271 this.watchFile(id);
9272 }
9273 for (const module of this.cache.modules) {
9274 for (const depId of module.transformDependencies) {
9275 this.watchFile(depId, true);
9276 }
9277 }
9278 for (const id of previouslyWatched) {
9279 if (!this.watched.has(id)) {
9280 this.fileWatcher.unwatch(id);
9281 }
9282 }
9283 }
9284 watchFile(id, isTransformDependency = false) {
9285 if (!this.filter(id))
9286 return;
9287 this.watched.add(id);
9288 if (this.outputFiles.includes(id)) {
9289 throw new Error('Cannot import the generated bundle');
9290 }
9291 // this is necessary to ensure that any 'renamed' files
9292 // continue to be watched following an error
9293 this.fileWatcher.watch(id, isTransformDependency);
9294 }
9295}
9296
9297export { Task, Watcher };
Note: See TracBrowser for help on using the repository browser.