UNPKG

122 kBJavaScriptView Raw
1var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
2
3function unwrapExports (x) {
4 return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
5}
6
7function createCommonjsModule(fn, module) {
8 return module = { exports: {} }, fn(module, module.exports), module.exports;
9}
10
11/**
12 * Helpers.
13 */
14
15var s = 1000;
16var m = s * 60;
17var h = m * 60;
18var d = h * 24;
19var w = d * 7;
20var y = d * 365.25;
21
22/**
23 * Parse or format the given `val`.
24 *
25 * Options:
26 *
27 * - `long` verbose formatting [false]
28 *
29 * @param {String|Number} val
30 * @param {Object} [options]
31 * @throws {Error} throw an error if val is not a non-empty string or a number
32 * @return {String|Number}
33 * @api public
34 */
35
36var ms = function(val, options) {
37 options = options || {};
38 var type = typeof val;
39 if (type === 'string' && val.length > 0) {
40 return parse(val);
41 } else if (type === 'number' && isFinite(val)) {
42 return options.long ? fmtLong(val) : fmtShort(val);
43 }
44 throw new Error(
45 'val is not a non-empty string or a valid number. val=' +
46 JSON.stringify(val)
47 );
48};
49
50/**
51 * Parse the given `str` and return milliseconds.
52 *
53 * @param {String} str
54 * @return {Number}
55 * @api private
56 */
57
58function parse(str) {
59 str = String(str);
60 if (str.length > 100) {
61 return;
62 }
63 var match = /^(-?(?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec(
64 str
65 );
66 if (!match) {
67 return;
68 }
69 var n = parseFloat(match[1]);
70 var type = (match[2] || 'ms').toLowerCase();
71 switch (type) {
72 case 'years':
73 case 'year':
74 case 'yrs':
75 case 'yr':
76 case 'y':
77 return n * y;
78 case 'weeks':
79 case 'week':
80 case 'w':
81 return n * w;
82 case 'days':
83 case 'day':
84 case 'd':
85 return n * d;
86 case 'hours':
87 case 'hour':
88 case 'hrs':
89 case 'hr':
90 case 'h':
91 return n * h;
92 case 'minutes':
93 case 'minute':
94 case 'mins':
95 case 'min':
96 case 'm':
97 return n * m;
98 case 'seconds':
99 case 'second':
100 case 'secs':
101 case 'sec':
102 case 's':
103 return n * s;
104 case 'milliseconds':
105 case 'millisecond':
106 case 'msecs':
107 case 'msec':
108 case 'ms':
109 return n;
110 default:
111 return undefined;
112 }
113}
114
115/**
116 * Short format for `ms`.
117 *
118 * @param {Number} ms
119 * @return {String}
120 * @api private
121 */
122
123function fmtShort(ms) {
124 var msAbs = Math.abs(ms);
125 if (msAbs >= d) {
126 return Math.round(ms / d) + 'd';
127 }
128 if (msAbs >= h) {
129 return Math.round(ms / h) + 'h';
130 }
131 if (msAbs >= m) {
132 return Math.round(ms / m) + 'm';
133 }
134 if (msAbs >= s) {
135 return Math.round(ms / s) + 's';
136 }
137 return ms + 'ms';
138}
139
140/**
141 * Long format for `ms`.
142 *
143 * @param {Number} ms
144 * @return {String}
145 * @api private
146 */
147
148function fmtLong(ms) {
149 var msAbs = Math.abs(ms);
150 if (msAbs >= d) {
151 return plural(ms, msAbs, d, 'day');
152 }
153 if (msAbs >= h) {
154 return plural(ms, msAbs, h, 'hour');
155 }
156 if (msAbs >= m) {
157 return plural(ms, msAbs, m, 'minute');
158 }
159 if (msAbs >= s) {
160 return plural(ms, msAbs, s, 'second');
161 }
162 return ms + ' ms';
163}
164
165/**
166 * Pluralization helper.
167 */
168
169function plural(ms, msAbs, n, name) {
170 var isPlural = msAbs >= n * 1.5;
171 return Math.round(ms / n) + ' ' + name + (isPlural ? 's' : '');
172}
173
174/**
175 * This is the common logic for both the Node.js and web browser
176 * implementations of `debug()`.
177 */
178
179function setup(env) {
180 createDebug.debug = createDebug;
181 createDebug.default = createDebug;
182 createDebug.coerce = coerce;
183 createDebug.disable = disable;
184 createDebug.enable = enable;
185 createDebug.enabled = enabled;
186 createDebug.humanize = ms;
187
188 Object.keys(env).forEach(key => {
189 createDebug[key] = env[key];
190 });
191
192 /**
193 * Active `debug` instances.
194 */
195 createDebug.instances = [];
196
197 /**
198 * The currently active debug mode names, and names to skip.
199 */
200
201 createDebug.names = [];
202 createDebug.skips = [];
203
204 /**
205 * Map of special "%n" handling functions, for the debug "format" argument.
206 *
207 * Valid key names are a single, lower or upper-case letter, i.e. "n" and "N".
208 */
209 createDebug.formatters = {};
210
211 /**
212 * Selects a color for a debug namespace
213 * @param {String} namespace The namespace string for the for the debug instance to be colored
214 * @return {Number|String} An ANSI color code for the given namespace
215 * @api private
216 */
217 function selectColor(namespace) {
218 let hash = 0;
219
220 for (let i = 0; i < namespace.length; i++) {
221 hash = ((hash << 5) - hash) + namespace.charCodeAt(i);
222 hash |= 0; // Convert to 32bit integer
223 }
224
225 return createDebug.colors[Math.abs(hash) % createDebug.colors.length];
226 }
227 createDebug.selectColor = selectColor;
228
229 /**
230 * Create a debugger with the given `namespace`.
231 *
232 * @param {String} namespace
233 * @return {Function}
234 * @api public
235 */
236 function createDebug(namespace) {
237 let prevTime;
238
239 function debug(...args) {
240 // Disabled?
241 if (!debug.enabled) {
242 return;
243 }
244
245 const self = debug;
246
247 // Set `diff` timestamp
248 const curr = Number(new Date());
249 const ms = curr - (prevTime || curr);
250 self.diff = ms;
251 self.prev = prevTime;
252 self.curr = curr;
253 prevTime = curr;
254
255 args[0] = createDebug.coerce(args[0]);
256
257 if (typeof args[0] !== 'string') {
258 // Anything else let's inspect with %O
259 args.unshift('%O');
260 }
261
262 // Apply any `formatters` transformations
263 let index = 0;
264 args[0] = args[0].replace(/%([a-zA-Z%])/g, (match, format) => {
265 // If we encounter an escaped % then don't increase the array index
266 if (match === '%%') {
267 return match;
268 }
269 index++;
270 const formatter = createDebug.formatters[format];
271 if (typeof formatter === 'function') {
272 const val = args[index];
273 match = formatter.call(self, val);
274
275 // Now we need to remove `args[index]` since it's inlined in the `format`
276 args.splice(index, 1);
277 index--;
278 }
279 return match;
280 });
281
282 // Apply env-specific formatting (colors, etc.)
283 createDebug.formatArgs.call(self, args);
284
285 const logFn = self.log || createDebug.log;
286 logFn.apply(self, args);
287 }
288
289 debug.namespace = namespace;
290 debug.enabled = createDebug.enabled(namespace);
291 debug.useColors = createDebug.useColors();
292 debug.color = selectColor(namespace);
293 debug.destroy = destroy;
294 debug.extend = extend;
295 // Debug.formatArgs = formatArgs;
296 // debug.rawLog = rawLog;
297
298 // env-specific initialization logic for debug instances
299 if (typeof createDebug.init === 'function') {
300 createDebug.init(debug);
301 }
302
303 createDebug.instances.push(debug);
304
305 return debug;
306 }
307
308 function destroy() {
309 const index = createDebug.instances.indexOf(this);
310 if (index !== -1) {
311 createDebug.instances.splice(index, 1);
312 return true;
313 }
314 return false;
315 }
316
317 function extend(namespace, delimiter) {
318 const newDebug = createDebug(this.namespace + (typeof delimiter === 'undefined' ? ':' : delimiter) + namespace);
319 newDebug.log = this.log;
320 return newDebug;
321 }
322
323 /**
324 * Enables a debug mode by namespaces. This can include modes
325 * separated by a colon and wildcards.
326 *
327 * @param {String} namespaces
328 * @api public
329 */
330 function enable(namespaces) {
331 createDebug.save(namespaces);
332
333 createDebug.names = [];
334 createDebug.skips = [];
335
336 let i;
337 const split = (typeof namespaces === 'string' ? namespaces : '').split(/[\s,]+/);
338 const len = split.length;
339
340 for (i = 0; i < len; i++) {
341 if (!split[i]) {
342 // ignore empty strings
343 continue;
344 }
345
346 namespaces = split[i].replace(/\*/g, '.*?');
347
348 if (namespaces[0] === '-') {
349 createDebug.skips.push(new RegExp('^' + namespaces.substr(1) + '$'));
350 } else {
351 createDebug.names.push(new RegExp('^' + namespaces + '$'));
352 }
353 }
354
355 for (i = 0; i < createDebug.instances.length; i++) {
356 const instance = createDebug.instances[i];
357 instance.enabled = createDebug.enabled(instance.namespace);
358 }
359 }
360
361 /**
362 * Disable debug output.
363 *
364 * @return {String} namespaces
365 * @api public
366 */
367 function disable() {
368 const namespaces = [
369 ...createDebug.names.map(toNamespace),
370 ...createDebug.skips.map(toNamespace).map(namespace => '-' + namespace)
371 ].join(',');
372 createDebug.enable('');
373 return namespaces;
374 }
375
376 /**
377 * Returns true if the given mode name is enabled, false otherwise.
378 *
379 * @param {String} name
380 * @return {Boolean}
381 * @api public
382 */
383 function enabled(name) {
384 if (name[name.length - 1] === '*') {
385 return true;
386 }
387
388 let i;
389 let len;
390
391 for (i = 0, len = createDebug.skips.length; i < len; i++) {
392 if (createDebug.skips[i].test(name)) {
393 return false;
394 }
395 }
396
397 for (i = 0, len = createDebug.names.length; i < len; i++) {
398 if (createDebug.names[i].test(name)) {
399 return true;
400 }
401 }
402
403 return false;
404 }
405
406 /**
407 * Convert regexp to namespace
408 *
409 * @param {RegExp} regxep
410 * @return {String} namespace
411 * @api private
412 */
413 function toNamespace(regexp) {
414 return regexp.toString()
415 .substring(2, regexp.toString().length - 2)
416 .replace(/\.\*\?$/, '*');
417 }
418
419 /**
420 * Coerce `val`.
421 *
422 * @param {Mixed} val
423 * @return {Mixed}
424 * @api private
425 */
426 function coerce(val) {
427 if (val instanceof Error) {
428 return val.stack || val.message;
429 }
430 return val;
431 }
432
433 createDebug.enable(createDebug.load());
434
435 return createDebug;
436}
437
438var common = setup;
439
440var browser = createCommonjsModule(function (module, exports) {
441/* eslint-env browser */
442
443/**
444 * This is the web browser implementation of `debug()`.
445 */
446
447exports.log = log;
448exports.formatArgs = formatArgs;
449exports.save = save;
450exports.load = load;
451exports.useColors = useColors;
452exports.storage = localstorage();
453
454/**
455 * Colors.
456 */
457
458exports.colors = [
459 '#0000CC',
460 '#0000FF',
461 '#0033CC',
462 '#0033FF',
463 '#0066CC',
464 '#0066FF',
465 '#0099CC',
466 '#0099FF',
467 '#00CC00',
468 '#00CC33',
469 '#00CC66',
470 '#00CC99',
471 '#00CCCC',
472 '#00CCFF',
473 '#3300CC',
474 '#3300FF',
475 '#3333CC',
476 '#3333FF',
477 '#3366CC',
478 '#3366FF',
479 '#3399CC',
480 '#3399FF',
481 '#33CC00',
482 '#33CC33',
483 '#33CC66',
484 '#33CC99',
485 '#33CCCC',
486 '#33CCFF',
487 '#6600CC',
488 '#6600FF',
489 '#6633CC',
490 '#6633FF',
491 '#66CC00',
492 '#66CC33',
493 '#9900CC',
494 '#9900FF',
495 '#9933CC',
496 '#9933FF',
497 '#99CC00',
498 '#99CC33',
499 '#CC0000',
500 '#CC0033',
501 '#CC0066',
502 '#CC0099',
503 '#CC00CC',
504 '#CC00FF',
505 '#CC3300',
506 '#CC3333',
507 '#CC3366',
508 '#CC3399',
509 '#CC33CC',
510 '#CC33FF',
511 '#CC6600',
512 '#CC6633',
513 '#CC9900',
514 '#CC9933',
515 '#CCCC00',
516 '#CCCC33',
517 '#FF0000',
518 '#FF0033',
519 '#FF0066',
520 '#FF0099',
521 '#FF00CC',
522 '#FF00FF',
523 '#FF3300',
524 '#FF3333',
525 '#FF3366',
526 '#FF3399',
527 '#FF33CC',
528 '#FF33FF',
529 '#FF6600',
530 '#FF6633',
531 '#FF9900',
532 '#FF9933',
533 '#FFCC00',
534 '#FFCC33'
535];
536
537/**
538 * Currently only WebKit-based Web Inspectors, Firefox >= v31,
539 * and the Firebug extension (any Firefox version) are known
540 * to support "%c" CSS customizations.
541 *
542 * TODO: add a `localStorage` variable to explicitly enable/disable colors
543 */
544
545// eslint-disable-next-line complexity
546function useColors() {
547 // NB: In an Electron preload script, document will be defined but not fully
548 // initialized. Since we know we're in Chrome, we'll just detect this case
549 // explicitly
550 if (typeof window !== 'undefined' && window.process && (window.process.type === 'renderer' || window.process.__nwjs)) {
551 return true;
552 }
553
554 // Internet Explorer and Edge do not support colors.
555 if (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/(edge|trident)\/(\d+)/)) {
556 return false;
557 }
558
559 // Is webkit? http://stackoverflow.com/a/16459606/376773
560 // document is undefined in react-native: https://github.com/facebook/react-native/pull/1632
561 return (typeof document !== 'undefined' && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance) ||
562 // Is firebug? http://stackoverflow.com/a/398120/376773
563 (typeof window !== 'undefined' && window.console && (window.console.firebug || (window.console.exception && window.console.table))) ||
564 // Is firefox >= v31?
565 // https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages
566 (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/) && parseInt(RegExp.$1, 10) >= 31) ||
567 // Double check webkit in userAgent just in case we are in a worker
568 (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/));
569}
570
571/**
572 * Colorize log arguments if enabled.
573 *
574 * @api public
575 */
576
577function formatArgs(args) {
578 args[0] = (this.useColors ? '%c' : '') +
579 this.namespace +
580 (this.useColors ? ' %c' : ' ') +
581 args[0] +
582 (this.useColors ? '%c ' : ' ') +
583 '+' + module.exports.humanize(this.diff);
584
585 if (!this.useColors) {
586 return;
587 }
588
589 const c = 'color: ' + this.color;
590 args.splice(1, 0, c, 'color: inherit');
591
592 // The final "%c" is somewhat tricky, because there could be other
593 // arguments passed either before or after the %c, so we need to
594 // figure out the correct index to insert the CSS into
595 let index = 0;
596 let lastC = 0;
597 args[0].replace(/%[a-zA-Z%]/g, match => {
598 if (match === '%%') {
599 return;
600 }
601 index++;
602 if (match === '%c') {
603 // We only are interested in the *last* %c
604 // (the user may have provided their own)
605 lastC = index;
606 }
607 });
608
609 args.splice(lastC, 0, c);
610}
611
612/**
613 * Invokes `console.log()` when available.
614 * No-op when `console.log` is not a "function".
615 *
616 * @api public
617 */
618function log(...args) {
619 // This hackery is required for IE8/9, where
620 // the `console.log` function doesn't have 'apply'
621 return typeof console === 'object' &&
622 console.log &&
623 console.log(...args);
624}
625
626/**
627 * Save `namespaces`.
628 *
629 * @param {String} namespaces
630 * @api private
631 */
632function save(namespaces) {
633 try {
634 if (namespaces) {
635 exports.storage.setItem('debug', namespaces);
636 } else {
637 exports.storage.removeItem('debug');
638 }
639 } catch (error) {
640 // Swallow
641 // XXX (@Qix-) should we be logging these?
642 }
643}
644
645/**
646 * Load `namespaces`.
647 *
648 * @return {String} returns the previously persisted debug modes
649 * @api private
650 */
651function load() {
652 let r;
653 try {
654 r = exports.storage.getItem('debug');
655 } catch (error) {
656 // Swallow
657 // XXX (@Qix-) should we be logging these?
658 }
659
660 // If debug isn't set in LS, and we're in Electron, try to load $DEBUG
661 if (!r && typeof process !== 'undefined' && 'env' in process) {
662 r = process.env.DEBUG;
663 }
664
665 return r;
666}
667
668/**
669 * Localstorage attempts to return the localstorage.
670 *
671 * This is necessary because safari throws
672 * when a user disables cookies/localstorage
673 * and you attempt to access it.
674 *
675 * @return {LocalStorage}
676 * @api private
677 */
678
679function localstorage() {
680 try {
681 // TVMLKit (Apple TV JS Runtime) does not have a window object, just localStorage in the global context
682 // The Browser also has localStorage in the global context.
683 return localStorage;
684 } catch (error) {
685 // Swallow
686 // XXX (@Qix-) should we be logging these?
687 }
688}
689
690module.exports = common(exports);
691
692const {formatters} = module.exports;
693
694/**
695 * Map %j to `JSON.stringify()`, since no Web Inspectors do that by default.
696 */
697
698formatters.j = function (v) {
699 try {
700 return JSON.stringify(v);
701 } catch (error) {
702 return '[UnexpectedJSONParseError]: ' + error.message;
703 }
704};
705});
706var browser_1 = browser.log;
707var browser_2 = browser.formatArgs;
708var browser_3 = browser.save;
709var browser_4 = browser.load;
710var browser_5 = browser.useColors;
711var browser_6 = browser.storage;
712var browser_7 = browser.colors;
713
714let debugFunc;
715let phase = 'default';
716let namespace = '';
717const newDebug = () => {
718 debugFunc = namespace
719 ? browser(`fetch-mock:${phase}:${namespace}`)
720 : browser(`fetch-mock:${phase}`);
721};
722
723const newDebugSandbox = ns => browser(`fetch-mock:${phase}:${ns}`);
724
725newDebug();
726
727var debug_1 = {
728 debug: (...args) => {
729 debugFunc(...args);
730 },
731 setDebugNamespace: str => {
732 namespace = str;
733 newDebug();
734 },
735 setDebugPhase: str => {
736 phase = str || 'default';
737 newDebug();
738 },
739 getDebug: namespace => newDebugSandbox(namespace)
740};
741
742var globToRegexp = function (glob, opts) {
743 if (typeof glob !== 'string') {
744 throw new TypeError('Expected a string');
745 }
746
747 var str = String(glob);
748
749 // The regexp we are building, as a string.
750 var reStr = "";
751
752 // Whether we are matching so called "extended" globs (like bash) and should
753 // support single character matching, matching ranges of characters, group
754 // matching, etc.
755 var extended = opts ? !!opts.extended : false;
756
757 // When globstar is _false_ (default), '/foo/*' is translated a regexp like
758 // '^\/foo\/.*$' which will match any string beginning with '/foo/'
759 // When globstar is _true_, '/foo/*' is translated to regexp like
760 // '^\/foo\/[^/]*$' which will match any string beginning with '/foo/' BUT
761 // which does not have a '/' to the right of it.
762 // E.g. with '/foo/*' these will match: '/foo/bar', '/foo/bar.txt' but
763 // these will not '/foo/bar/baz', '/foo/bar/baz.txt'
764 // Lastely, when globstar is _true_, '/foo/**' is equivelant to '/foo/*' when
765 // globstar is _false_
766 var globstar = opts ? !!opts.globstar : false;
767
768 // If we are doing extended matching, this boolean is true when we are inside
769 // a group (eg {*.html,*.js}), and false otherwise.
770 var inGroup = false;
771
772 // RegExp flags (eg "i" ) to pass in to RegExp constructor.
773 var flags = opts && typeof( opts.flags ) === "string" ? opts.flags : "";
774
775 var c;
776 for (var i = 0, len = str.length; i < len; i++) {
777 c = str[i];
778
779 switch (c) {
780 case "/":
781 case "$":
782 case "^":
783 case "+":
784 case ".":
785 case "(":
786 case ")":
787 case "=":
788 case "!":
789 case "|":
790 reStr += "\\" + c;
791 break;
792
793 case "?":
794 if (extended) {
795 reStr += ".";
796 break;
797 }
798
799 case "[":
800 case "]":
801 if (extended) {
802 reStr += c;
803 break;
804 }
805
806 case "{":
807 if (extended) {
808 inGroup = true;
809 reStr += "(";
810 break;
811 }
812
813 case "}":
814 if (extended) {
815 inGroup = false;
816 reStr += ")";
817 break;
818 }
819
820 case ",":
821 if (inGroup) {
822 reStr += "|";
823 break;
824 }
825 reStr += "\\" + c;
826 break;
827
828 case "*":
829 // Move over all consecutive "*"'s.
830 // Also store the previous and next characters
831 var prevChar = str[i - 1];
832 var starCount = 1;
833 while(str[i + 1] === "*") {
834 starCount++;
835 i++;
836 }
837 var nextChar = str[i + 1];
838
839 if (!globstar) {
840 // globstar is disabled, so treat any number of "*" as one
841 reStr += ".*";
842 } else {
843 // globstar is enabled, so determine if this is a globstar segment
844 var isGlobstar = starCount > 1 // multiple "*"'s
845 && (prevChar === "/" || prevChar === undefined) // from the start of the segment
846 && (nextChar === "/" || nextChar === undefined); // to the end of the segment
847
848 if (isGlobstar) {
849 // it's a globstar, so match zero or more path segments
850 reStr += "((?:[^/]*(?:\/|$))*)";
851 i++; // move over the "/"
852 } else {
853 // it's not a globstar, so only match one path segment
854 reStr += "([^/]*)";
855 }
856 }
857 break;
858
859 default:
860 reStr += c;
861 }
862 }
863
864 // When regexp 'g' flag is specified don't
865 // constrain the regular expression with ^ & $
866 if (!flags || !~flags.indexOf('g')) {
867 reStr = "^" + reStr + "$";
868 }
869
870 return new RegExp(reStr, flags);
871};
872
873/**
874 * Expose `pathToRegexp`.
875 */
876var pathToRegexp_1 = pathToRegexp;
877var parse_1 = parse$1;
878var compile_1 = compile;
879var tokensToFunction_1 = tokensToFunction;
880var tokensToRegExp_1 = tokensToRegExp;
881
882/**
883 * Default configs.
884 */
885var DEFAULT_DELIMITER = '/';
886var DEFAULT_DELIMITERS = './';
887
888/**
889 * The main path matching regexp utility.
890 *
891 * @type {RegExp}
892 */
893var PATH_REGEXP = new RegExp([
894 // Match escaped characters that would otherwise appear in future matches.
895 // This allows the user to escape special characters that won't transform.
896 '(\\\\.)',
897 // Match Express-style parameters and un-named parameters with a prefix
898 // and optional suffixes. Matches appear as:
899 //
900 // ":test(\\d+)?" => ["test", "\d+", undefined, "?"]
901 // "(\\d+)" => [undefined, undefined, "\d+", undefined]
902 '(?:\\:(\\w+)(?:\\(((?:\\\\.|[^\\\\()])+)\\))?|\\(((?:\\\\.|[^\\\\()])+)\\))([+*?])?'
903].join('|'), 'g');
904
905/**
906 * Parse a string for the raw tokens.
907 *
908 * @param {string} str
909 * @param {Object=} options
910 * @return {!Array}
911 */
912function parse$1 (str, options) {
913 var tokens = [];
914 var key = 0;
915 var index = 0;
916 var path = '';
917 var defaultDelimiter = (options && options.delimiter) || DEFAULT_DELIMITER;
918 var delimiters = (options && options.delimiters) || DEFAULT_DELIMITERS;
919 var pathEscaped = false;
920 var res;
921
922 while ((res = PATH_REGEXP.exec(str)) !== null) {
923 var m = res[0];
924 var escaped = res[1];
925 var offset = res.index;
926 path += str.slice(index, offset);
927 index = offset + m.length;
928
929 // Ignore already escaped sequences.
930 if (escaped) {
931 path += escaped[1];
932 pathEscaped = true;
933 continue
934 }
935
936 var prev = '';
937 var next = str[index];
938 var name = res[2];
939 var capture = res[3];
940 var group = res[4];
941 var modifier = res[5];
942
943 if (!pathEscaped && path.length) {
944 var k = path.length - 1;
945
946 if (delimiters.indexOf(path[k]) > -1) {
947 prev = path[k];
948 path = path.slice(0, k);
949 }
950 }
951
952 // Push the current path onto the tokens.
953 if (path) {
954 tokens.push(path);
955 path = '';
956 pathEscaped = false;
957 }
958
959 var partial = prev !== '' && next !== undefined && next !== prev;
960 var repeat = modifier === '+' || modifier === '*';
961 var optional = modifier === '?' || modifier === '*';
962 var delimiter = prev || defaultDelimiter;
963 var pattern = capture || group;
964
965 tokens.push({
966 name: name || key++,
967 prefix: prev,
968 delimiter: delimiter,
969 optional: optional,
970 repeat: repeat,
971 partial: partial,
972 pattern: pattern ? escapeGroup(pattern) : '[^' + escapeString(delimiter) + ']+?'
973 });
974 }
975
976 // Push any remaining characters.
977 if (path || index < str.length) {
978 tokens.push(path + str.substr(index));
979 }
980
981 return tokens
982}
983
984/**
985 * Compile a string to a template function for the path.
986 *
987 * @param {string} str
988 * @param {Object=} options
989 * @return {!function(Object=, Object=)}
990 */
991function compile (str, options) {
992 return tokensToFunction(parse$1(str, options))
993}
994
995/**
996 * Expose a method for transforming tokens into the path function.
997 */
998function tokensToFunction (tokens) {
999 // Compile all the tokens into regexps.
1000 var matches = new Array(tokens.length);
1001
1002 // Compile all the patterns before compilation.
1003 for (var i = 0; i < tokens.length; i++) {
1004 if (typeof tokens[i] === 'object') {
1005 matches[i] = new RegExp('^(?:' + tokens[i].pattern + ')$');
1006 }
1007 }
1008
1009 return function (data, options) {
1010 var path = '';
1011 var encode = (options && options.encode) || encodeURIComponent;
1012
1013 for (var i = 0; i < tokens.length; i++) {
1014 var token = tokens[i];
1015
1016 if (typeof token === 'string') {
1017 path += token;
1018 continue
1019 }
1020
1021 var value = data ? data[token.name] : undefined;
1022 var segment;
1023
1024 if (Array.isArray(value)) {
1025 if (!token.repeat) {
1026 throw new TypeError('Expected "' + token.name + '" to not repeat, but got array')
1027 }
1028
1029 if (value.length === 0) {
1030 if (token.optional) continue
1031
1032 throw new TypeError('Expected "' + token.name + '" to not be empty')
1033 }
1034
1035 for (var j = 0; j < value.length; j++) {
1036 segment = encode(value[j], token);
1037
1038 if (!matches[i].test(segment)) {
1039 throw new TypeError('Expected all "' + token.name + '" to match "' + token.pattern + '"')
1040 }
1041
1042 path += (j === 0 ? token.prefix : token.delimiter) + segment;
1043 }
1044
1045 continue
1046 }
1047
1048 if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') {
1049 segment = encode(String(value), token);
1050
1051 if (!matches[i].test(segment)) {
1052 throw new TypeError('Expected "' + token.name + '" to match "' + token.pattern + '", but got "' + segment + '"')
1053 }
1054
1055 path += token.prefix + segment;
1056 continue
1057 }
1058
1059 if (token.optional) {
1060 // Prepend partial segment prefixes.
1061 if (token.partial) path += token.prefix;
1062
1063 continue
1064 }
1065
1066 throw new TypeError('Expected "' + token.name + '" to be ' + (token.repeat ? 'an array' : 'a string'))
1067 }
1068
1069 return path
1070 }
1071}
1072
1073/**
1074 * Escape a regular expression string.
1075 *
1076 * @param {string} str
1077 * @return {string}
1078 */
1079function escapeString (str) {
1080 return str.replace(/([.+*?=^!:${}()[\]|/\\])/g, '\\$1')
1081}
1082
1083/**
1084 * Escape the capturing group by escaping special characters and meaning.
1085 *
1086 * @param {string} group
1087 * @return {string}
1088 */
1089function escapeGroup (group) {
1090 return group.replace(/([=!:$/()])/g, '\\$1')
1091}
1092
1093/**
1094 * Get the flags for a regexp from the options.
1095 *
1096 * @param {Object} options
1097 * @return {string}
1098 */
1099function flags (options) {
1100 return options && options.sensitive ? '' : 'i'
1101}
1102
1103/**
1104 * Pull out keys from a regexp.
1105 *
1106 * @param {!RegExp} path
1107 * @param {Array=} keys
1108 * @return {!RegExp}
1109 */
1110function regexpToRegexp (path, keys) {
1111 if (!keys) return path
1112
1113 // Use a negative lookahead to match only capturing groups.
1114 var groups = path.source.match(/\((?!\?)/g);
1115
1116 if (groups) {
1117 for (var i = 0; i < groups.length; i++) {
1118 keys.push({
1119 name: i,
1120 prefix: null,
1121 delimiter: null,
1122 optional: false,
1123 repeat: false,
1124 partial: false,
1125 pattern: null
1126 });
1127 }
1128 }
1129
1130 return path
1131}
1132
1133/**
1134 * Transform an array into a regexp.
1135 *
1136 * @param {!Array} path
1137 * @param {Array=} keys
1138 * @param {Object=} options
1139 * @return {!RegExp}
1140 */
1141function arrayToRegexp (path, keys, options) {
1142 var parts = [];
1143
1144 for (var i = 0; i < path.length; i++) {
1145 parts.push(pathToRegexp(path[i], keys, options).source);
1146 }
1147
1148 return new RegExp('(?:' + parts.join('|') + ')', flags(options))
1149}
1150
1151/**
1152 * Create a path regexp from string input.
1153 *
1154 * @param {string} path
1155 * @param {Array=} keys
1156 * @param {Object=} options
1157 * @return {!RegExp}
1158 */
1159function stringToRegexp (path, keys, options) {
1160 return tokensToRegExp(parse$1(path, options), keys, options)
1161}
1162
1163/**
1164 * Expose a function for taking tokens and returning a RegExp.
1165 *
1166 * @param {!Array} tokens
1167 * @param {Array=} keys
1168 * @param {Object=} options
1169 * @return {!RegExp}
1170 */
1171function tokensToRegExp (tokens, keys, options) {
1172 options = options || {};
1173
1174 var strict = options.strict;
1175 var start = options.start !== false;
1176 var end = options.end !== false;
1177 var delimiter = escapeString(options.delimiter || DEFAULT_DELIMITER);
1178 var delimiters = options.delimiters || DEFAULT_DELIMITERS;
1179 var endsWith = [].concat(options.endsWith || []).map(escapeString).concat('$').join('|');
1180 var route = start ? '^' : '';
1181 var isEndDelimited = tokens.length === 0;
1182
1183 // Iterate over the tokens and create our regexp string.
1184 for (var i = 0; i < tokens.length; i++) {
1185 var token = tokens[i];
1186
1187 if (typeof token === 'string') {
1188 route += escapeString(token);
1189 isEndDelimited = i === tokens.length - 1 && delimiters.indexOf(token[token.length - 1]) > -1;
1190 } else {
1191 var capture = token.repeat
1192 ? '(?:' + token.pattern + ')(?:' + escapeString(token.delimiter) + '(?:' + token.pattern + '))*'
1193 : token.pattern;
1194
1195 if (keys) keys.push(token);
1196
1197 if (token.optional) {
1198 if (token.partial) {
1199 route += escapeString(token.prefix) + '(' + capture + ')?';
1200 } else {
1201 route += '(?:' + escapeString(token.prefix) + '(' + capture + '))?';
1202 }
1203 } else {
1204 route += escapeString(token.prefix) + '(' + capture + ')';
1205 }
1206 }
1207 }
1208
1209 if (end) {
1210 if (!strict) route += '(?:' + delimiter + ')?';
1211
1212 route += endsWith === '$' ? '$' : '(?=' + endsWith + ')';
1213 } else {
1214 if (!strict) route += '(?:' + delimiter + '(?=' + endsWith + '))?';
1215 if (!isEndDelimited) route += '(?=' + delimiter + '|' + endsWith + ')';
1216 }
1217
1218 return new RegExp(route, flags(options))
1219}
1220
1221/**
1222 * Normalize the given path string, returning a regular expression.
1223 *
1224 * An empty array can be passed in for the keys, which will hold the
1225 * placeholder key descriptions. For example, using `/user/:id`, `keys` will
1226 * contain `[{ name: 'id', delimiter: '/', optional: false, repeat: false }]`.
1227 *
1228 * @param {(string|RegExp|Array)} path
1229 * @param {Array=} keys
1230 * @param {Object=} options
1231 * @return {!RegExp}
1232 */
1233function pathToRegexp (path, keys, options) {
1234 if (path instanceof RegExp) {
1235 return regexpToRegexp(path, keys)
1236 }
1237
1238 if (Array.isArray(path)) {
1239 return arrayToRegexp(/** @type {!Array} */ (path), keys, options)
1240 }
1241
1242 return stringToRegexp(/** @type {string} */ (path), keys, options)
1243}
1244pathToRegexp_1.parse = parse_1;
1245pathToRegexp_1.compile = compile_1;
1246pathToRegexp_1.tokensToFunction = tokensToFunction_1;
1247pathToRegexp_1.tokensToRegExp = tokensToRegExp_1;
1248
1249// Copyright Joyent, Inc. and other Node contributors.
1250
1251// If obj.hasOwnProperty has been overridden, then calling
1252// obj.hasOwnProperty(prop) will break.
1253// See: https://github.com/joyent/node/issues/1707
1254function hasOwnProperty(obj, prop) {
1255 return Object.prototype.hasOwnProperty.call(obj, prop);
1256}
1257
1258var decode = function(qs, sep, eq, options) {
1259 sep = sep || '&';
1260 eq = eq || '=';
1261 var obj = {};
1262
1263 if (typeof qs !== 'string' || qs.length === 0) {
1264 return obj;
1265 }
1266
1267 var regexp = /\+/g;
1268 qs = qs.split(sep);
1269
1270 var maxKeys = 1000;
1271 if (options && typeof options.maxKeys === 'number') {
1272 maxKeys = options.maxKeys;
1273 }
1274
1275 var len = qs.length;
1276 // maxKeys <= 0 means that we should not limit keys count
1277 if (maxKeys > 0 && len > maxKeys) {
1278 len = maxKeys;
1279 }
1280
1281 for (var i = 0; i < len; ++i) {
1282 var x = qs[i].replace(regexp, '%20'),
1283 idx = x.indexOf(eq),
1284 kstr, vstr, k, v;
1285
1286 if (idx >= 0) {
1287 kstr = x.substr(0, idx);
1288 vstr = x.substr(idx + 1);
1289 } else {
1290 kstr = x;
1291 vstr = '';
1292 }
1293
1294 k = decodeURIComponent(kstr);
1295 v = decodeURIComponent(vstr);
1296
1297 if (!hasOwnProperty(obj, k)) {
1298 obj[k] = v;
1299 } else if (Array.isArray(obj[k])) {
1300 obj[k].push(v);
1301 } else {
1302 obj[k] = [obj[k], v];
1303 }
1304 }
1305
1306 return obj;
1307};
1308
1309// Copyright Joyent, Inc. and other Node contributors.
1310
1311var stringifyPrimitive = function(v) {
1312 switch (typeof v) {
1313 case 'string':
1314 return v;
1315
1316 case 'boolean':
1317 return v ? 'true' : 'false';
1318
1319 case 'number':
1320 return isFinite(v) ? v : '';
1321
1322 default:
1323 return '';
1324 }
1325};
1326
1327var encode = function(obj, sep, eq, name) {
1328 sep = sep || '&';
1329 eq = eq || '=';
1330 if (obj === null) {
1331 obj = undefined;
1332 }
1333
1334 if (typeof obj === 'object') {
1335 return Object.keys(obj).map(function(k) {
1336 var ks = encodeURIComponent(stringifyPrimitive(k)) + eq;
1337 if (Array.isArray(obj[k])) {
1338 return obj[k].map(function(v) {
1339 return ks + encodeURIComponent(stringifyPrimitive(v));
1340 }).join(sep);
1341 } else {
1342 return ks + encodeURIComponent(stringifyPrimitive(obj[k]));
1343 }
1344 }).join(sep);
1345
1346 }
1347
1348 if (!name) return '';
1349 return encodeURIComponent(stringifyPrimitive(name)) + eq +
1350 encodeURIComponent(stringifyPrimitive(obj));
1351};
1352
1353var querystring = createCommonjsModule(function (module, exports) {
1354
1355exports.decode = exports.parse = decode;
1356exports.encode = exports.stringify = encode;
1357});
1358var querystring_1 = querystring.decode;
1359var querystring_2 = querystring.parse;
1360var querystring_3 = querystring.encode;
1361var querystring_4 = querystring.stringify;
1362
1363var isSubset_1 = createCommonjsModule(function (module, exports) {
1364
1365Object.defineProperty(exports, '__esModule', {
1366 value: true
1367});
1368/**
1369 * Check if an object is contained within another object.
1370 *
1371 * Returns `true` if:
1372 * - all enumerable keys of *subset* are also enumerable in *superset*, and
1373 * - every value assigned to an enumerable key of *subset* strictly equals
1374 * the value assigned to the same key of *superset* – or is a subset of it.
1375 *
1376 * @param {Object} superset
1377 * @param {Object} subset
1378 *
1379 * @returns {Boolean}
1380 *
1381 * @module is-subset
1382 * @function default
1383 * @alias isSubset
1384 */
1385var isSubset = (function (_isSubset) {
1386 function isSubset(_x, _x2) {
1387 return _isSubset.apply(this, arguments);
1388 }
1389
1390 isSubset.toString = function () {
1391 return _isSubset.toString();
1392 };
1393
1394 return isSubset;
1395})(function (superset, subset) {
1396 if (typeof superset !== 'object' || superset === null || (typeof subset !== 'object' || subset === null)) return false;
1397
1398 return Object.keys(subset).every(function (key) {
1399 if (!superset.propertyIsEnumerable(key)) return false;
1400
1401 var subsetItem = subset[key];
1402 var supersetItem = superset[key];
1403 if (typeof subsetItem === 'object' && subsetItem !== null ? !isSubset(supersetItem, subsetItem) : supersetItem !== subsetItem) return false;
1404
1405 return true;
1406 });
1407});
1408
1409exports['default'] = isSubset;
1410module.exports = exports['default'];
1411});
1412
1413unwrapExports(isSubset_1);
1414
1415let URL;
1416// https://stackoverflow.com/a/19709846/308237
1417const absoluteUrlRX = new RegExp('^(?:[a-z]+:)?//', 'i');
1418
1419const headersToArray = headers => {
1420 // node-fetch 1 Headers
1421 if (typeof headers.raw === 'function') {
1422 return Object.entries(headers.raw());
1423 } else if (headers[Symbol.iterator]) {
1424 return [...headers];
1425 } else {
1426 return Object.entries(headers);
1427 }
1428};
1429
1430const zipObject = entries =>
1431 entries.reduce((obj, [key, val]) => Object.assign(obj, { [key]: val }), {});
1432
1433const normalizeUrl = url => {
1434 if (
1435 typeof url === 'function' ||
1436 url instanceof RegExp ||
1437 /^(begin|end|glob|express|path)\:/.test(url)
1438 ) {
1439 return url;
1440 }
1441 if (absoluteUrlRX.test(url)) {
1442 const u = new URL(url);
1443 return u.href;
1444 } else {
1445 const u = new URL(url, 'http://dummy');
1446 return u.pathname + u.search;
1447 }
1448};
1449
1450const extractBody = async request => {
1451 try {
1452 // node-fetch
1453 if ('body' in request) {
1454 return request.body.toString();
1455 }
1456 // fetch
1457 return request.clone().text();
1458 } catch (err) {
1459 return;
1460 }
1461};
1462
1463var requestUtils = {
1464 setUrlImplementation: it => {
1465 URL = it;
1466 },
1467 normalizeRequest: (url, options, Request) => {
1468 if (Request.prototype.isPrototypeOf(url)) {
1469 const derivedOptions = {
1470 method: url.method
1471 };
1472
1473 const body = extractBody(url);
1474
1475 if (typeof body !== 'undefined') {
1476 derivedOptions.body = body;
1477 }
1478
1479 const normalizedRequestObject = {
1480 url: normalizeUrl(url.url),
1481 options: Object.assign(derivedOptions, options),
1482 request: url,
1483 signal: (options && options.signal) || url.signal
1484 };
1485
1486 const headers = headersToArray(url.headers);
1487
1488 if (headers.length) {
1489 normalizedRequestObject.options.headers = zipObject(headers);
1490 }
1491 return normalizedRequestObject;
1492 } else if (
1493 typeof url === 'string' ||
1494 // horrible URL object duck-typing
1495 (typeof url === 'object' && 'href' in url)
1496 ) {
1497 return {
1498 url: normalizeUrl(url),
1499 options: options,
1500 signal: options && options.signal
1501 };
1502 } else if (typeof url === 'object') {
1503 throw new TypeError(
1504 'fetch-mock: Unrecognised Request object. Read the Config and Installation sections of the docs'
1505 );
1506 } else {
1507 throw new TypeError('fetch-mock: Invalid arguments passed to fetch');
1508 }
1509 },
1510 normalizeUrl,
1511 getPath: url => {
1512 const u = absoluteUrlRX.test(url)
1513 ? new URL(url)
1514 : new URL(url, 'http://dummy');
1515 return u.pathname;
1516 },
1517
1518 getQuery: url => {
1519 const u = absoluteUrlRX.test(url)
1520 ? new URL(url)
1521 : new URL(url, 'http://dummy');
1522 return u.search ? u.search.substr(1) : '';
1523 },
1524 headers: {
1525 normalize: headers => zipObject(headersToArray(headers)),
1526 toLowerCase: headers =>
1527 Object.keys(headers).reduce((obj, k) => {
1528 obj[k.toLowerCase()] = headers[k];
1529 return obj;
1530 }, {}),
1531 equal: (actualHeader, expectedHeader) => {
1532 actualHeader = Array.isArray(actualHeader)
1533 ? actualHeader
1534 : [actualHeader];
1535 expectedHeader = Array.isArray(expectedHeader)
1536 ? expectedHeader
1537 : [expectedHeader];
1538
1539 if (actualHeader.length !== expectedHeader.length) {
1540 return false;
1541 }
1542
1543 return actualHeader.every((val, i) => val === expectedHeader[i]);
1544 }
1545 }
1546};
1547
1548var lodash_isequal = createCommonjsModule(function (module, exports) {
1549/**
1550 * Lodash (Custom Build) <https://lodash.com/>
1551 * Build: `lodash modularize exports="npm" -o ./`
1552 * Copyright JS Foundation and other contributors <https://js.foundation/>
1553 * Released under MIT license <https://lodash.com/license>
1554 * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
1555 * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
1556 */
1557
1558/** Used as the size to enable large array optimizations. */
1559var LARGE_ARRAY_SIZE = 200;
1560
1561/** Used to stand-in for `undefined` hash values. */
1562var HASH_UNDEFINED = '__lodash_hash_undefined__';
1563
1564/** Used to compose bitmasks for value comparisons. */
1565var COMPARE_PARTIAL_FLAG = 1,
1566 COMPARE_UNORDERED_FLAG = 2;
1567
1568/** Used as references for various `Number` constants. */
1569var MAX_SAFE_INTEGER = 9007199254740991;
1570
1571/** `Object#toString` result references. */
1572var argsTag = '[object Arguments]',
1573 arrayTag = '[object Array]',
1574 asyncTag = '[object AsyncFunction]',
1575 boolTag = '[object Boolean]',
1576 dateTag = '[object Date]',
1577 errorTag = '[object Error]',
1578 funcTag = '[object Function]',
1579 genTag = '[object GeneratorFunction]',
1580 mapTag = '[object Map]',
1581 numberTag = '[object Number]',
1582 nullTag = '[object Null]',
1583 objectTag = '[object Object]',
1584 promiseTag = '[object Promise]',
1585 proxyTag = '[object Proxy]',
1586 regexpTag = '[object RegExp]',
1587 setTag = '[object Set]',
1588 stringTag = '[object String]',
1589 symbolTag = '[object Symbol]',
1590 undefinedTag = '[object Undefined]',
1591 weakMapTag = '[object WeakMap]';
1592
1593var arrayBufferTag = '[object ArrayBuffer]',
1594 dataViewTag = '[object DataView]',
1595 float32Tag = '[object Float32Array]',
1596 float64Tag = '[object Float64Array]',
1597 int8Tag = '[object Int8Array]',
1598 int16Tag = '[object Int16Array]',
1599 int32Tag = '[object Int32Array]',
1600 uint8Tag = '[object Uint8Array]',
1601 uint8ClampedTag = '[object Uint8ClampedArray]',
1602 uint16Tag = '[object Uint16Array]',
1603 uint32Tag = '[object Uint32Array]';
1604
1605/**
1606 * Used to match `RegExp`
1607 * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns).
1608 */
1609var reRegExpChar = /[\\^$.*+?()[\]{}|]/g;
1610
1611/** Used to detect host constructors (Safari). */
1612var reIsHostCtor = /^\[object .+?Constructor\]$/;
1613
1614/** Used to detect unsigned integer values. */
1615var reIsUint = /^(?:0|[1-9]\d*)$/;
1616
1617/** Used to identify `toStringTag` values of typed arrays. */
1618var typedArrayTags = {};
1619typedArrayTags[float32Tag] = typedArrayTags[float64Tag] =
1620typedArrayTags[int8Tag] = typedArrayTags[int16Tag] =
1621typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] =
1622typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] =
1623typedArrayTags[uint32Tag] = true;
1624typedArrayTags[argsTag] = typedArrayTags[arrayTag] =
1625typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] =
1626typedArrayTags[dataViewTag] = typedArrayTags[dateTag] =
1627typedArrayTags[errorTag] = typedArrayTags[funcTag] =
1628typedArrayTags[mapTag] = typedArrayTags[numberTag] =
1629typedArrayTags[objectTag] = typedArrayTags[regexpTag] =
1630typedArrayTags[setTag] = typedArrayTags[stringTag] =
1631typedArrayTags[weakMapTag] = false;
1632
1633/** Detect free variable `global` from Node.js. */
1634var freeGlobal = typeof commonjsGlobal == 'object' && commonjsGlobal && commonjsGlobal.Object === Object && commonjsGlobal;
1635
1636/** Detect free variable `self`. */
1637var freeSelf = typeof self == 'object' && self && self.Object === Object && self;
1638
1639/** Used as a reference to the global object. */
1640var root = freeGlobal || freeSelf || Function('return this')();
1641
1642/** Detect free variable `exports`. */
1643var freeExports = exports && !exports.nodeType && exports;
1644
1645/** Detect free variable `module`. */
1646var freeModule = freeExports && 'object' == 'object' && module && !module.nodeType && module;
1647
1648/** Detect the popular CommonJS extension `module.exports`. */
1649var moduleExports = freeModule && freeModule.exports === freeExports;
1650
1651/** Detect free variable `process` from Node.js. */
1652var freeProcess = moduleExports && freeGlobal.process;
1653
1654/** Used to access faster Node.js helpers. */
1655var nodeUtil = (function() {
1656 try {
1657 return freeProcess && freeProcess.binding && freeProcess.binding('util');
1658 } catch (e) {}
1659}());
1660
1661/* Node.js helper references. */
1662var nodeIsTypedArray = nodeUtil && nodeUtil.isTypedArray;
1663
1664/**
1665 * A specialized version of `_.filter` for arrays without support for
1666 * iteratee shorthands.
1667 *
1668 * @private
1669 * @param {Array} [array] The array to iterate over.
1670 * @param {Function} predicate The function invoked per iteration.
1671 * @returns {Array} Returns the new filtered array.
1672 */
1673function arrayFilter(array, predicate) {
1674 var index = -1,
1675 length = array == null ? 0 : array.length,
1676 resIndex = 0,
1677 result = [];
1678
1679 while (++index < length) {
1680 var value = array[index];
1681 if (predicate(value, index, array)) {
1682 result[resIndex++] = value;
1683 }
1684 }
1685 return result;
1686}
1687
1688/**
1689 * Appends the elements of `values` to `array`.
1690 *
1691 * @private
1692 * @param {Array} array The array to modify.
1693 * @param {Array} values The values to append.
1694 * @returns {Array} Returns `array`.
1695 */
1696function arrayPush(array, values) {
1697 var index = -1,
1698 length = values.length,
1699 offset = array.length;
1700
1701 while (++index < length) {
1702 array[offset + index] = values[index];
1703 }
1704 return array;
1705}
1706
1707/**
1708 * A specialized version of `_.some` for arrays without support for iteratee
1709 * shorthands.
1710 *
1711 * @private
1712 * @param {Array} [array] The array to iterate over.
1713 * @param {Function} predicate The function invoked per iteration.
1714 * @returns {boolean} Returns `true` if any element passes the predicate check,
1715 * else `false`.
1716 */
1717function arraySome(array, predicate) {
1718 var index = -1,
1719 length = array == null ? 0 : array.length;
1720
1721 while (++index < length) {
1722 if (predicate(array[index], index, array)) {
1723 return true;
1724 }
1725 }
1726 return false;
1727}
1728
1729/**
1730 * The base implementation of `_.times` without support for iteratee shorthands
1731 * or max array length checks.
1732 *
1733 * @private
1734 * @param {number} n The number of times to invoke `iteratee`.
1735 * @param {Function} iteratee The function invoked per iteration.
1736 * @returns {Array} Returns the array of results.
1737 */
1738function baseTimes(n, iteratee) {
1739 var index = -1,
1740 result = Array(n);
1741
1742 while (++index < n) {
1743 result[index] = iteratee(index);
1744 }
1745 return result;
1746}
1747
1748/**
1749 * The base implementation of `_.unary` without support for storing metadata.
1750 *
1751 * @private
1752 * @param {Function} func The function to cap arguments for.
1753 * @returns {Function} Returns the new capped function.
1754 */
1755function baseUnary(func) {
1756 return function(value) {
1757 return func(value);
1758 };
1759}
1760
1761/**
1762 * Checks if a `cache` value for `key` exists.
1763 *
1764 * @private
1765 * @param {Object} cache The cache to query.
1766 * @param {string} key The key of the entry to check.
1767 * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
1768 */
1769function cacheHas(cache, key) {
1770 return cache.has(key);
1771}
1772
1773/**
1774 * Gets the value at `key` of `object`.
1775 *
1776 * @private
1777 * @param {Object} [object] The object to query.
1778 * @param {string} key The key of the property to get.
1779 * @returns {*} Returns the property value.
1780 */
1781function getValue(object, key) {
1782 return object == null ? undefined : object[key];
1783}
1784
1785/**
1786 * Converts `map` to its key-value pairs.
1787 *
1788 * @private
1789 * @param {Object} map The map to convert.
1790 * @returns {Array} Returns the key-value pairs.
1791 */
1792function mapToArray(map) {
1793 var index = -1,
1794 result = Array(map.size);
1795
1796 map.forEach(function(value, key) {
1797 result[++index] = [key, value];
1798 });
1799 return result;
1800}
1801
1802/**
1803 * Creates a unary function that invokes `func` with its argument transformed.
1804 *
1805 * @private
1806 * @param {Function} func The function to wrap.
1807 * @param {Function} transform The argument transform.
1808 * @returns {Function} Returns the new function.
1809 */
1810function overArg(func, transform) {
1811 return function(arg) {
1812 return func(transform(arg));
1813 };
1814}
1815
1816/**
1817 * Converts `set` to an array of its values.
1818 *
1819 * @private
1820 * @param {Object} set The set to convert.
1821 * @returns {Array} Returns the values.
1822 */
1823function setToArray(set) {
1824 var index = -1,
1825 result = Array(set.size);
1826
1827 set.forEach(function(value) {
1828 result[++index] = value;
1829 });
1830 return result;
1831}
1832
1833/** Used for built-in method references. */
1834var arrayProto = Array.prototype,
1835 funcProto = Function.prototype,
1836 objectProto = Object.prototype;
1837
1838/** Used to detect overreaching core-js shims. */
1839var coreJsData = root['__core-js_shared__'];
1840
1841/** Used to resolve the decompiled source of functions. */
1842var funcToString = funcProto.toString;
1843
1844/** Used to check objects for own properties. */
1845var hasOwnProperty = objectProto.hasOwnProperty;
1846
1847/** Used to detect methods masquerading as native. */
1848var maskSrcKey = (function() {
1849 var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || '');
1850 return uid ? ('Symbol(src)_1.' + uid) : '';
1851}());
1852
1853/**
1854 * Used to resolve the
1855 * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
1856 * of values.
1857 */
1858var nativeObjectToString = objectProto.toString;
1859
1860/** Used to detect if a method is native. */
1861var reIsNative = RegExp('^' +
1862 funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&')
1863 .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'
1864);
1865
1866/** Built-in value references. */
1867var Buffer = moduleExports ? root.Buffer : undefined,
1868 Symbol = root.Symbol,
1869 Uint8Array = root.Uint8Array,
1870 propertyIsEnumerable = objectProto.propertyIsEnumerable,
1871 splice = arrayProto.splice,
1872 symToStringTag = Symbol ? Symbol.toStringTag : undefined;
1873
1874/* Built-in method references for those with the same name as other `lodash` methods. */
1875var nativeGetSymbols = Object.getOwnPropertySymbols,
1876 nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined,
1877 nativeKeys = overArg(Object.keys, Object);
1878
1879/* Built-in method references that are verified to be native. */
1880var DataView = getNative(root, 'DataView'),
1881 Map = getNative(root, 'Map'),
1882 Promise = getNative(root, 'Promise'),
1883 Set = getNative(root, 'Set'),
1884 WeakMap = getNative(root, 'WeakMap'),
1885 nativeCreate = getNative(Object, 'create');
1886
1887/** Used to detect maps, sets, and weakmaps. */
1888var dataViewCtorString = toSource(DataView),
1889 mapCtorString = toSource(Map),
1890 promiseCtorString = toSource(Promise),
1891 setCtorString = toSource(Set),
1892 weakMapCtorString = toSource(WeakMap);
1893
1894/** Used to convert symbols to primitives and strings. */
1895var symbolProto = Symbol ? Symbol.prototype : undefined,
1896 symbolValueOf = symbolProto ? symbolProto.valueOf : undefined;
1897
1898/**
1899 * Creates a hash object.
1900 *
1901 * @private
1902 * @constructor
1903 * @param {Array} [entries] The key-value pairs to cache.
1904 */
1905function Hash(entries) {
1906 var index = -1,
1907 length = entries == null ? 0 : entries.length;
1908
1909 this.clear();
1910 while (++index < length) {
1911 var entry = entries[index];
1912 this.set(entry[0], entry[1]);
1913 }
1914}
1915
1916/**
1917 * Removes all key-value entries from the hash.
1918 *
1919 * @private
1920 * @name clear
1921 * @memberOf Hash
1922 */
1923function hashClear() {
1924 this.__data__ = nativeCreate ? nativeCreate(null) : {};
1925 this.size = 0;
1926}
1927
1928/**
1929 * Removes `key` and its value from the hash.
1930 *
1931 * @private
1932 * @name delete
1933 * @memberOf Hash
1934 * @param {Object} hash The hash to modify.
1935 * @param {string} key The key of the value to remove.
1936 * @returns {boolean} Returns `true` if the entry was removed, else `false`.
1937 */
1938function hashDelete(key) {
1939 var result = this.has(key) && delete this.__data__[key];
1940 this.size -= result ? 1 : 0;
1941 return result;
1942}
1943
1944/**
1945 * Gets the hash value for `key`.
1946 *
1947 * @private
1948 * @name get
1949 * @memberOf Hash
1950 * @param {string} key The key of the value to get.
1951 * @returns {*} Returns the entry value.
1952 */
1953function hashGet(key) {
1954 var data = this.__data__;
1955 if (nativeCreate) {
1956 var result = data[key];
1957 return result === HASH_UNDEFINED ? undefined : result;
1958 }
1959 return hasOwnProperty.call(data, key) ? data[key] : undefined;
1960}
1961
1962/**
1963 * Checks if a hash value for `key` exists.
1964 *
1965 * @private
1966 * @name has
1967 * @memberOf Hash
1968 * @param {string} key The key of the entry to check.
1969 * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
1970 */
1971function hashHas(key) {
1972 var data = this.__data__;
1973 return nativeCreate ? (data[key] !== undefined) : hasOwnProperty.call(data, key);
1974}
1975
1976/**
1977 * Sets the hash `key` to `value`.
1978 *
1979 * @private
1980 * @name set
1981 * @memberOf Hash
1982 * @param {string} key The key of the value to set.
1983 * @param {*} value The value to set.
1984 * @returns {Object} Returns the hash instance.
1985 */
1986function hashSet(key, value) {
1987 var data = this.__data__;
1988 this.size += this.has(key) ? 0 : 1;
1989 data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value;
1990 return this;
1991}
1992
1993// Add methods to `Hash`.
1994Hash.prototype.clear = hashClear;
1995Hash.prototype['delete'] = hashDelete;
1996Hash.prototype.get = hashGet;
1997Hash.prototype.has = hashHas;
1998Hash.prototype.set = hashSet;
1999
2000/**
2001 * Creates an list cache object.
2002 *
2003 * @private
2004 * @constructor
2005 * @param {Array} [entries] The key-value pairs to cache.
2006 */
2007function ListCache(entries) {
2008 var index = -1,
2009 length = entries == null ? 0 : entries.length;
2010
2011 this.clear();
2012 while (++index < length) {
2013 var entry = entries[index];
2014 this.set(entry[0], entry[1]);
2015 }
2016}
2017
2018/**
2019 * Removes all key-value entries from the list cache.
2020 *
2021 * @private
2022 * @name clear
2023 * @memberOf ListCache
2024 */
2025function listCacheClear() {
2026 this.__data__ = [];
2027 this.size = 0;
2028}
2029
2030/**
2031 * Removes `key` and its value from the list cache.
2032 *
2033 * @private
2034 * @name delete
2035 * @memberOf ListCache
2036 * @param {string} key The key of the value to remove.
2037 * @returns {boolean} Returns `true` if the entry was removed, else `false`.
2038 */
2039function listCacheDelete(key) {
2040 var data = this.__data__,
2041 index = assocIndexOf(data, key);
2042
2043 if (index < 0) {
2044 return false;
2045 }
2046 var lastIndex = data.length - 1;
2047 if (index == lastIndex) {
2048 data.pop();
2049 } else {
2050 splice.call(data, index, 1);
2051 }
2052 --this.size;
2053 return true;
2054}
2055
2056/**
2057 * Gets the list cache value for `key`.
2058 *
2059 * @private
2060 * @name get
2061 * @memberOf ListCache
2062 * @param {string} key The key of the value to get.
2063 * @returns {*} Returns the entry value.
2064 */
2065function listCacheGet(key) {
2066 var data = this.__data__,
2067 index = assocIndexOf(data, key);
2068
2069 return index < 0 ? undefined : data[index][1];
2070}
2071
2072/**
2073 * Checks if a list cache value for `key` exists.
2074 *
2075 * @private
2076 * @name has
2077 * @memberOf ListCache
2078 * @param {string} key The key of the entry to check.
2079 * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
2080 */
2081function listCacheHas(key) {
2082 return assocIndexOf(this.__data__, key) > -1;
2083}
2084
2085/**
2086 * Sets the list cache `key` to `value`.
2087 *
2088 * @private
2089 * @name set
2090 * @memberOf ListCache
2091 * @param {string} key The key of the value to set.
2092 * @param {*} value The value to set.
2093 * @returns {Object} Returns the list cache instance.
2094 */
2095function listCacheSet(key, value) {
2096 var data = this.__data__,
2097 index = assocIndexOf(data, key);
2098
2099 if (index < 0) {
2100 ++this.size;
2101 data.push([key, value]);
2102 } else {
2103 data[index][1] = value;
2104 }
2105 return this;
2106}
2107
2108// Add methods to `ListCache`.
2109ListCache.prototype.clear = listCacheClear;
2110ListCache.prototype['delete'] = listCacheDelete;
2111ListCache.prototype.get = listCacheGet;
2112ListCache.prototype.has = listCacheHas;
2113ListCache.prototype.set = listCacheSet;
2114
2115/**
2116 * Creates a map cache object to store key-value pairs.
2117 *
2118 * @private
2119 * @constructor
2120 * @param {Array} [entries] The key-value pairs to cache.
2121 */
2122function MapCache(entries) {
2123 var index = -1,
2124 length = entries == null ? 0 : entries.length;
2125
2126 this.clear();
2127 while (++index < length) {
2128 var entry = entries[index];
2129 this.set(entry[0], entry[1]);
2130 }
2131}
2132
2133/**
2134 * Removes all key-value entries from the map.
2135 *
2136 * @private
2137 * @name clear
2138 * @memberOf MapCache
2139 */
2140function mapCacheClear() {
2141 this.size = 0;
2142 this.__data__ = {
2143 'hash': new Hash,
2144 'map': new (Map || ListCache),
2145 'string': new Hash
2146 };
2147}
2148
2149/**
2150 * Removes `key` and its value from the map.
2151 *
2152 * @private
2153 * @name delete
2154 * @memberOf MapCache
2155 * @param {string} key The key of the value to remove.
2156 * @returns {boolean} Returns `true` if the entry was removed, else `false`.
2157 */
2158function mapCacheDelete(key) {
2159 var result = getMapData(this, key)['delete'](key);
2160 this.size -= result ? 1 : 0;
2161 return result;
2162}
2163
2164/**
2165 * Gets the map value for `key`.
2166 *
2167 * @private
2168 * @name get
2169 * @memberOf MapCache
2170 * @param {string} key The key of the value to get.
2171 * @returns {*} Returns the entry value.
2172 */
2173function mapCacheGet(key) {
2174 return getMapData(this, key).get(key);
2175}
2176
2177/**
2178 * Checks if a map value for `key` exists.
2179 *
2180 * @private
2181 * @name has
2182 * @memberOf MapCache
2183 * @param {string} key The key of the entry to check.
2184 * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
2185 */
2186function mapCacheHas(key) {
2187 return getMapData(this, key).has(key);
2188}
2189
2190/**
2191 * Sets the map `key` to `value`.
2192 *
2193 * @private
2194 * @name set
2195 * @memberOf MapCache
2196 * @param {string} key The key of the value to set.
2197 * @param {*} value The value to set.
2198 * @returns {Object} Returns the map cache instance.
2199 */
2200function mapCacheSet(key, value) {
2201 var data = getMapData(this, key),
2202 size = data.size;
2203
2204 data.set(key, value);
2205 this.size += data.size == size ? 0 : 1;
2206 return this;
2207}
2208
2209// Add methods to `MapCache`.
2210MapCache.prototype.clear = mapCacheClear;
2211MapCache.prototype['delete'] = mapCacheDelete;
2212MapCache.prototype.get = mapCacheGet;
2213MapCache.prototype.has = mapCacheHas;
2214MapCache.prototype.set = mapCacheSet;
2215
2216/**
2217 *
2218 * Creates an array cache object to store unique values.
2219 *
2220 * @private
2221 * @constructor
2222 * @param {Array} [values] The values to cache.
2223 */
2224function SetCache(values) {
2225 var index = -1,
2226 length = values == null ? 0 : values.length;
2227
2228 this.__data__ = new MapCache;
2229 while (++index < length) {
2230 this.add(values[index]);
2231 }
2232}
2233
2234/**
2235 * Adds `value` to the array cache.
2236 *
2237 * @private
2238 * @name add
2239 * @memberOf SetCache
2240 * @alias push
2241 * @param {*} value The value to cache.
2242 * @returns {Object} Returns the cache instance.
2243 */
2244function setCacheAdd(value) {
2245 this.__data__.set(value, HASH_UNDEFINED);
2246 return this;
2247}
2248
2249/**
2250 * Checks if `value` is in the array cache.
2251 *
2252 * @private
2253 * @name has
2254 * @memberOf SetCache
2255 * @param {*} value The value to search for.
2256 * @returns {number} Returns `true` if `value` is found, else `false`.
2257 */
2258function setCacheHas(value) {
2259 return this.__data__.has(value);
2260}
2261
2262// Add methods to `SetCache`.
2263SetCache.prototype.add = SetCache.prototype.push = setCacheAdd;
2264SetCache.prototype.has = setCacheHas;
2265
2266/**
2267 * Creates a stack cache object to store key-value pairs.
2268 *
2269 * @private
2270 * @constructor
2271 * @param {Array} [entries] The key-value pairs to cache.
2272 */
2273function Stack(entries) {
2274 var data = this.__data__ = new ListCache(entries);
2275 this.size = data.size;
2276}
2277
2278/**
2279 * Removes all key-value entries from the stack.
2280 *
2281 * @private
2282 * @name clear
2283 * @memberOf Stack
2284 */
2285function stackClear() {
2286 this.__data__ = new ListCache;
2287 this.size = 0;
2288}
2289
2290/**
2291 * Removes `key` and its value from the stack.
2292 *
2293 * @private
2294 * @name delete
2295 * @memberOf Stack
2296 * @param {string} key The key of the value to remove.
2297 * @returns {boolean} Returns `true` if the entry was removed, else `false`.
2298 */
2299function stackDelete(key) {
2300 var data = this.__data__,
2301 result = data['delete'](key);
2302
2303 this.size = data.size;
2304 return result;
2305}
2306
2307/**
2308 * Gets the stack value for `key`.
2309 *
2310 * @private
2311 * @name get
2312 * @memberOf Stack
2313 * @param {string} key The key of the value to get.
2314 * @returns {*} Returns the entry value.
2315 */
2316function stackGet(key) {
2317 return this.__data__.get(key);
2318}
2319
2320/**
2321 * Checks if a stack value for `key` exists.
2322 *
2323 * @private
2324 * @name has
2325 * @memberOf Stack
2326 * @param {string} key The key of the entry to check.
2327 * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
2328 */
2329function stackHas(key) {
2330 return this.__data__.has(key);
2331}
2332
2333/**
2334 * Sets the stack `key` to `value`.
2335 *
2336 * @private
2337 * @name set
2338 * @memberOf Stack
2339 * @param {string} key The key of the value to set.
2340 * @param {*} value The value to set.
2341 * @returns {Object} Returns the stack cache instance.
2342 */
2343function stackSet(key, value) {
2344 var data = this.__data__;
2345 if (data instanceof ListCache) {
2346 var pairs = data.__data__;
2347 if (!Map || (pairs.length < LARGE_ARRAY_SIZE - 1)) {
2348 pairs.push([key, value]);
2349 this.size = ++data.size;
2350 return this;
2351 }
2352 data = this.__data__ = new MapCache(pairs);
2353 }
2354 data.set(key, value);
2355 this.size = data.size;
2356 return this;
2357}
2358
2359// Add methods to `Stack`.
2360Stack.prototype.clear = stackClear;
2361Stack.prototype['delete'] = stackDelete;
2362Stack.prototype.get = stackGet;
2363Stack.prototype.has = stackHas;
2364Stack.prototype.set = stackSet;
2365
2366/**
2367 * Creates an array of the enumerable property names of the array-like `value`.
2368 *
2369 * @private
2370 * @param {*} value The value to query.
2371 * @param {boolean} inherited Specify returning inherited property names.
2372 * @returns {Array} Returns the array of property names.
2373 */
2374function arrayLikeKeys(value, inherited) {
2375 var isArr = isArray(value),
2376 isArg = !isArr && isArguments(value),
2377 isBuff = !isArr && !isArg && isBuffer(value),
2378 isType = !isArr && !isArg && !isBuff && isTypedArray(value),
2379 skipIndexes = isArr || isArg || isBuff || isType,
2380 result = skipIndexes ? baseTimes(value.length, String) : [],
2381 length = result.length;
2382
2383 for (var key in value) {
2384 if ((inherited || hasOwnProperty.call(value, key)) &&
2385 !(skipIndexes && (
2386 // Safari 9 has enumerable `arguments.length` in strict mode.
2387 key == 'length' ||
2388 // Node.js 0.10 has enumerable non-index properties on buffers.
2389 (isBuff && (key == 'offset' || key == 'parent')) ||
2390 // PhantomJS 2 has enumerable non-index properties on typed arrays.
2391 (isType && (key == 'buffer' || key == 'byteLength' || key == 'byteOffset')) ||
2392 // Skip index properties.
2393 isIndex(key, length)
2394 ))) {
2395 result.push(key);
2396 }
2397 }
2398 return result;
2399}
2400
2401/**
2402 * Gets the index at which the `key` is found in `array` of key-value pairs.
2403 *
2404 * @private
2405 * @param {Array} array The array to inspect.
2406 * @param {*} key The key to search for.
2407 * @returns {number} Returns the index of the matched value, else `-1`.
2408 */
2409function assocIndexOf(array, key) {
2410 var length = array.length;
2411 while (length--) {
2412 if (eq(array[length][0], key)) {
2413 return length;
2414 }
2415 }
2416 return -1;
2417}
2418
2419/**
2420 * The base implementation of `getAllKeys` and `getAllKeysIn` which uses
2421 * `keysFunc` and `symbolsFunc` to get the enumerable property names and
2422 * symbols of `object`.
2423 *
2424 * @private
2425 * @param {Object} object The object to query.
2426 * @param {Function} keysFunc The function to get the keys of `object`.
2427 * @param {Function} symbolsFunc The function to get the symbols of `object`.
2428 * @returns {Array} Returns the array of property names and symbols.
2429 */
2430function baseGetAllKeys(object, keysFunc, symbolsFunc) {
2431 var result = keysFunc(object);
2432 return isArray(object) ? result : arrayPush(result, symbolsFunc(object));
2433}
2434
2435/**
2436 * The base implementation of `getTag` without fallbacks for buggy environments.
2437 *
2438 * @private
2439 * @param {*} value The value to query.
2440 * @returns {string} Returns the `toStringTag`.
2441 */
2442function baseGetTag(value) {
2443 if (value == null) {
2444 return value === undefined ? undefinedTag : nullTag;
2445 }
2446 return (symToStringTag && symToStringTag in Object(value))
2447 ? getRawTag(value)
2448 : objectToString(value);
2449}
2450
2451/**
2452 * The base implementation of `_.isArguments`.
2453 *
2454 * @private
2455 * @param {*} value The value to check.
2456 * @returns {boolean} Returns `true` if `value` is an `arguments` object,
2457 */
2458function baseIsArguments(value) {
2459 return isObjectLike(value) && baseGetTag(value) == argsTag;
2460}
2461
2462/**
2463 * The base implementation of `_.isEqual` which supports partial comparisons
2464 * and tracks traversed objects.
2465 *
2466 * @private
2467 * @param {*} value The value to compare.
2468 * @param {*} other The other value to compare.
2469 * @param {boolean} bitmask The bitmask flags.
2470 * 1 - Unordered comparison
2471 * 2 - Partial comparison
2472 * @param {Function} [customizer] The function to customize comparisons.
2473 * @param {Object} [stack] Tracks traversed `value` and `other` objects.
2474 * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
2475 */
2476function baseIsEqual(value, other, bitmask, customizer, stack) {
2477 if (value === other) {
2478 return true;
2479 }
2480 if (value == null || other == null || (!isObjectLike(value) && !isObjectLike(other))) {
2481 return value !== value && other !== other;
2482 }
2483 return baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack);
2484}
2485
2486/**
2487 * A specialized version of `baseIsEqual` for arrays and objects which performs
2488 * deep comparisons and tracks traversed objects enabling objects with circular
2489 * references to be compared.
2490 *
2491 * @private
2492 * @param {Object} object The object to compare.
2493 * @param {Object} other The other object to compare.
2494 * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
2495 * @param {Function} customizer The function to customize comparisons.
2496 * @param {Function} equalFunc The function to determine equivalents of values.
2497 * @param {Object} [stack] Tracks traversed `object` and `other` objects.
2498 * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
2499 */
2500function baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) {
2501 var objIsArr = isArray(object),
2502 othIsArr = isArray(other),
2503 objTag = objIsArr ? arrayTag : getTag(object),
2504 othTag = othIsArr ? arrayTag : getTag(other);
2505
2506 objTag = objTag == argsTag ? objectTag : objTag;
2507 othTag = othTag == argsTag ? objectTag : othTag;
2508
2509 var objIsObj = objTag == objectTag,
2510 othIsObj = othTag == objectTag,
2511 isSameTag = objTag == othTag;
2512
2513 if (isSameTag && isBuffer(object)) {
2514 if (!isBuffer(other)) {
2515 return false;
2516 }
2517 objIsArr = true;
2518 objIsObj = false;
2519 }
2520 if (isSameTag && !objIsObj) {
2521 stack || (stack = new Stack);
2522 return (objIsArr || isTypedArray(object))
2523 ? equalArrays(object, other, bitmask, customizer, equalFunc, stack)
2524 : equalByTag(object, other, objTag, bitmask, customizer, equalFunc, stack);
2525 }
2526 if (!(bitmask & COMPARE_PARTIAL_FLAG)) {
2527 var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'),
2528 othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__');
2529
2530 if (objIsWrapped || othIsWrapped) {
2531 var objUnwrapped = objIsWrapped ? object.value() : object,
2532 othUnwrapped = othIsWrapped ? other.value() : other;
2533
2534 stack || (stack = new Stack);
2535 return equalFunc(objUnwrapped, othUnwrapped, bitmask, customizer, stack);
2536 }
2537 }
2538 if (!isSameTag) {
2539 return false;
2540 }
2541 stack || (stack = new Stack);
2542 return equalObjects(object, other, bitmask, customizer, equalFunc, stack);
2543}
2544
2545/**
2546 * The base implementation of `_.isNative` without bad shim checks.
2547 *
2548 * @private
2549 * @param {*} value The value to check.
2550 * @returns {boolean} Returns `true` if `value` is a native function,
2551 * else `false`.
2552 */
2553function baseIsNative(value) {
2554 if (!isObject(value) || isMasked(value)) {
2555 return false;
2556 }
2557 var pattern = isFunction(value) ? reIsNative : reIsHostCtor;
2558 return pattern.test(toSource(value));
2559}
2560
2561/**
2562 * The base implementation of `_.isTypedArray` without Node.js optimizations.
2563 *
2564 * @private
2565 * @param {*} value The value to check.
2566 * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.
2567 */
2568function baseIsTypedArray(value) {
2569 return isObjectLike(value) &&
2570 isLength(value.length) && !!typedArrayTags[baseGetTag(value)];
2571}
2572
2573/**
2574 * The base implementation of `_.keys` which doesn't treat sparse arrays as dense.
2575 *
2576 * @private
2577 * @param {Object} object The object to query.
2578 * @returns {Array} Returns the array of property names.
2579 */
2580function baseKeys(object) {
2581 if (!isPrototype(object)) {
2582 return nativeKeys(object);
2583 }
2584 var result = [];
2585 for (var key in Object(object)) {
2586 if (hasOwnProperty.call(object, key) && key != 'constructor') {
2587 result.push(key);
2588 }
2589 }
2590 return result;
2591}
2592
2593/**
2594 * A specialized version of `baseIsEqualDeep` for arrays with support for
2595 * partial deep comparisons.
2596 *
2597 * @private
2598 * @param {Array} array The array to compare.
2599 * @param {Array} other The other array to compare.
2600 * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
2601 * @param {Function} customizer The function to customize comparisons.
2602 * @param {Function} equalFunc The function to determine equivalents of values.
2603 * @param {Object} stack Tracks traversed `array` and `other` objects.
2604 * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`.
2605 */
2606function equalArrays(array, other, bitmask, customizer, equalFunc, stack) {
2607 var isPartial = bitmask & COMPARE_PARTIAL_FLAG,
2608 arrLength = array.length,
2609 othLength = other.length;
2610
2611 if (arrLength != othLength && !(isPartial && othLength > arrLength)) {
2612 return false;
2613 }
2614 // Assume cyclic values are equal.
2615 var stacked = stack.get(array);
2616 if (stacked && stack.get(other)) {
2617 return stacked == other;
2618 }
2619 var index = -1,
2620 result = true,
2621 seen = (bitmask & COMPARE_UNORDERED_FLAG) ? new SetCache : undefined;
2622
2623 stack.set(array, other);
2624 stack.set(other, array);
2625
2626 // Ignore non-index properties.
2627 while (++index < arrLength) {
2628 var arrValue = array[index],
2629 othValue = other[index];
2630
2631 if (customizer) {
2632 var compared = isPartial
2633 ? customizer(othValue, arrValue, index, other, array, stack)
2634 : customizer(arrValue, othValue, index, array, other, stack);
2635 }
2636 if (compared !== undefined) {
2637 if (compared) {
2638 continue;
2639 }
2640 result = false;
2641 break;
2642 }
2643 // Recursively compare arrays (susceptible to call stack limits).
2644 if (seen) {
2645 if (!arraySome(other, function(othValue, othIndex) {
2646 if (!cacheHas(seen, othIndex) &&
2647 (arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack))) {
2648 return seen.push(othIndex);
2649 }
2650 })) {
2651 result = false;
2652 break;
2653 }
2654 } else if (!(
2655 arrValue === othValue ||
2656 equalFunc(arrValue, othValue, bitmask, customizer, stack)
2657 )) {
2658 result = false;
2659 break;
2660 }
2661 }
2662 stack['delete'](array);
2663 stack['delete'](other);
2664 return result;
2665}
2666
2667/**
2668 * A specialized version of `baseIsEqualDeep` for comparing objects of
2669 * the same `toStringTag`.
2670 *
2671 * **Note:** This function only supports comparing values with tags of
2672 * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.
2673 *
2674 * @private
2675 * @param {Object} object The object to compare.
2676 * @param {Object} other The other object to compare.
2677 * @param {string} tag The `toStringTag` of the objects to compare.
2678 * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
2679 * @param {Function} customizer The function to customize comparisons.
2680 * @param {Function} equalFunc The function to determine equivalents of values.
2681 * @param {Object} stack Tracks traversed `object` and `other` objects.
2682 * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
2683 */
2684function equalByTag(object, other, tag, bitmask, customizer, equalFunc, stack) {
2685 switch (tag) {
2686 case dataViewTag:
2687 if ((object.byteLength != other.byteLength) ||
2688 (object.byteOffset != other.byteOffset)) {
2689 return false;
2690 }
2691 object = object.buffer;
2692 other = other.buffer;
2693
2694 case arrayBufferTag:
2695 if ((object.byteLength != other.byteLength) ||
2696 !equalFunc(new Uint8Array(object), new Uint8Array(other))) {
2697 return false;
2698 }
2699 return true;
2700
2701 case boolTag:
2702 case dateTag:
2703 case numberTag:
2704 // Coerce booleans to `1` or `0` and dates to milliseconds.
2705 // Invalid dates are coerced to `NaN`.
2706 return eq(+object, +other);
2707
2708 case errorTag:
2709 return object.name == other.name && object.message == other.message;
2710
2711 case regexpTag:
2712 case stringTag:
2713 // Coerce regexes to strings and treat strings, primitives and objects,
2714 // as equal. See http://www.ecma-international.org/ecma-262/7.0/#sec-regexp.prototype.tostring
2715 // for more details.
2716 return object == (other + '');
2717
2718 case mapTag:
2719 var convert = mapToArray;
2720
2721 case setTag:
2722 var isPartial = bitmask & COMPARE_PARTIAL_FLAG;
2723 convert || (convert = setToArray);
2724
2725 if (object.size != other.size && !isPartial) {
2726 return false;
2727 }
2728 // Assume cyclic values are equal.
2729 var stacked = stack.get(object);
2730 if (stacked) {
2731 return stacked == other;
2732 }
2733 bitmask |= COMPARE_UNORDERED_FLAG;
2734
2735 // Recursively compare objects (susceptible to call stack limits).
2736 stack.set(object, other);
2737 var result = equalArrays(convert(object), convert(other), bitmask, customizer, equalFunc, stack);
2738 stack['delete'](object);
2739 return result;
2740
2741 case symbolTag:
2742 if (symbolValueOf) {
2743 return symbolValueOf.call(object) == symbolValueOf.call(other);
2744 }
2745 }
2746 return false;
2747}
2748
2749/**
2750 * A specialized version of `baseIsEqualDeep` for objects with support for
2751 * partial deep comparisons.
2752 *
2753 * @private
2754 * @param {Object} object The object to compare.
2755 * @param {Object} other The other object to compare.
2756 * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
2757 * @param {Function} customizer The function to customize comparisons.
2758 * @param {Function} equalFunc The function to determine equivalents of values.
2759 * @param {Object} stack Tracks traversed `object` and `other` objects.
2760 * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
2761 */
2762function equalObjects(object, other, bitmask, customizer, equalFunc, stack) {
2763 var isPartial = bitmask & COMPARE_PARTIAL_FLAG,
2764 objProps = getAllKeys(object),
2765 objLength = objProps.length,
2766 othProps = getAllKeys(other),
2767 othLength = othProps.length;
2768
2769 if (objLength != othLength && !isPartial) {
2770 return false;
2771 }
2772 var index = objLength;
2773 while (index--) {
2774 var key = objProps[index];
2775 if (!(isPartial ? key in other : hasOwnProperty.call(other, key))) {
2776 return false;
2777 }
2778 }
2779 // Assume cyclic values are equal.
2780 var stacked = stack.get(object);
2781 if (stacked && stack.get(other)) {
2782 return stacked == other;
2783 }
2784 var result = true;
2785 stack.set(object, other);
2786 stack.set(other, object);
2787
2788 var skipCtor = isPartial;
2789 while (++index < objLength) {
2790 key = objProps[index];
2791 var objValue = object[key],
2792 othValue = other[key];
2793
2794 if (customizer) {
2795 var compared = isPartial
2796 ? customizer(othValue, objValue, key, other, object, stack)
2797 : customizer(objValue, othValue, key, object, other, stack);
2798 }
2799 // Recursively compare objects (susceptible to call stack limits).
2800 if (!(compared === undefined
2801 ? (objValue === othValue || equalFunc(objValue, othValue, bitmask, customizer, stack))
2802 : compared
2803 )) {
2804 result = false;
2805 break;
2806 }
2807 skipCtor || (skipCtor = key == 'constructor');
2808 }
2809 if (result && !skipCtor) {
2810 var objCtor = object.constructor,
2811 othCtor = other.constructor;
2812
2813 // Non `Object` object instances with different constructors are not equal.
2814 if (objCtor != othCtor &&
2815 ('constructor' in object && 'constructor' in other) &&
2816 !(typeof objCtor == 'function' && objCtor instanceof objCtor &&
2817 typeof othCtor == 'function' && othCtor instanceof othCtor)) {
2818 result = false;
2819 }
2820 }
2821 stack['delete'](object);
2822 stack['delete'](other);
2823 return result;
2824}
2825
2826/**
2827 * Creates an array of own enumerable property names and symbols of `object`.
2828 *
2829 * @private
2830 * @param {Object} object The object to query.
2831 * @returns {Array} Returns the array of property names and symbols.
2832 */
2833function getAllKeys(object) {
2834 return baseGetAllKeys(object, keys, getSymbols);
2835}
2836
2837/**
2838 * Gets the data for `map`.
2839 *
2840 * @private
2841 * @param {Object} map The map to query.
2842 * @param {string} key The reference key.
2843 * @returns {*} Returns the map data.
2844 */
2845function getMapData(map, key) {
2846 var data = map.__data__;
2847 return isKeyable(key)
2848 ? data[typeof key == 'string' ? 'string' : 'hash']
2849 : data.map;
2850}
2851
2852/**
2853 * Gets the native function at `key` of `object`.
2854 *
2855 * @private
2856 * @param {Object} object The object to query.
2857 * @param {string} key The key of the method to get.
2858 * @returns {*} Returns the function if it's native, else `undefined`.
2859 */
2860function getNative(object, key) {
2861 var value = getValue(object, key);
2862 return baseIsNative(value) ? value : undefined;
2863}
2864
2865/**
2866 * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values.
2867 *
2868 * @private
2869 * @param {*} value The value to query.
2870 * @returns {string} Returns the raw `toStringTag`.
2871 */
2872function getRawTag(value) {
2873 var isOwn = hasOwnProperty.call(value, symToStringTag),
2874 tag = value[symToStringTag];
2875
2876 try {
2877 value[symToStringTag] = undefined;
2878 var unmasked = true;
2879 } catch (e) {}
2880
2881 var result = nativeObjectToString.call(value);
2882 if (unmasked) {
2883 if (isOwn) {
2884 value[symToStringTag] = tag;
2885 } else {
2886 delete value[symToStringTag];
2887 }
2888 }
2889 return result;
2890}
2891
2892/**
2893 * Creates an array of the own enumerable symbols of `object`.
2894 *
2895 * @private
2896 * @param {Object} object The object to query.
2897 * @returns {Array} Returns the array of symbols.
2898 */
2899var getSymbols = !nativeGetSymbols ? stubArray : function(object) {
2900 if (object == null) {
2901 return [];
2902 }
2903 object = Object(object);
2904 return arrayFilter(nativeGetSymbols(object), function(symbol) {
2905 return propertyIsEnumerable.call(object, symbol);
2906 });
2907};
2908
2909/**
2910 * Gets the `toStringTag` of `value`.
2911 *
2912 * @private
2913 * @param {*} value The value to query.
2914 * @returns {string} Returns the `toStringTag`.
2915 */
2916var getTag = baseGetTag;
2917
2918// Fallback for data views, maps, sets, and weak maps in IE 11 and promises in Node.js < 6.
2919if ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag) ||
2920 (Map && getTag(new Map) != mapTag) ||
2921 (Promise && getTag(Promise.resolve()) != promiseTag) ||
2922 (Set && getTag(new Set) != setTag) ||
2923 (WeakMap && getTag(new WeakMap) != weakMapTag)) {
2924 getTag = function(value) {
2925 var result = baseGetTag(value),
2926 Ctor = result == objectTag ? value.constructor : undefined,
2927 ctorString = Ctor ? toSource(Ctor) : '';
2928
2929 if (ctorString) {
2930 switch (ctorString) {
2931 case dataViewCtorString: return dataViewTag;
2932 case mapCtorString: return mapTag;
2933 case promiseCtorString: return promiseTag;
2934 case setCtorString: return setTag;
2935 case weakMapCtorString: return weakMapTag;
2936 }
2937 }
2938 return result;
2939 };
2940}
2941
2942/**
2943 * Checks if `value` is a valid array-like index.
2944 *
2945 * @private
2946 * @param {*} value The value to check.
2947 * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.
2948 * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.
2949 */
2950function isIndex(value, length) {
2951 length = length == null ? MAX_SAFE_INTEGER : length;
2952 return !!length &&
2953 (typeof value == 'number' || reIsUint.test(value)) &&
2954 (value > -1 && value % 1 == 0 && value < length);
2955}
2956
2957/**
2958 * Checks if `value` is suitable for use as unique object key.
2959 *
2960 * @private
2961 * @param {*} value The value to check.
2962 * @returns {boolean} Returns `true` if `value` is suitable, else `false`.
2963 */
2964function isKeyable(value) {
2965 var type = typeof value;
2966 return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean')
2967 ? (value !== '__proto__')
2968 : (value === null);
2969}
2970
2971/**
2972 * Checks if `func` has its source masked.
2973 *
2974 * @private
2975 * @param {Function} func The function to check.
2976 * @returns {boolean} Returns `true` if `func` is masked, else `false`.
2977 */
2978function isMasked(func) {
2979 return !!maskSrcKey && (maskSrcKey in func);
2980}
2981
2982/**
2983 * Checks if `value` is likely a prototype object.
2984 *
2985 * @private
2986 * @param {*} value The value to check.
2987 * @returns {boolean} Returns `true` if `value` is a prototype, else `false`.
2988 */
2989function isPrototype(value) {
2990 var Ctor = value && value.constructor,
2991 proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto;
2992
2993 return value === proto;
2994}
2995
2996/**
2997 * Converts `value` to a string using `Object.prototype.toString`.
2998 *
2999 * @private
3000 * @param {*} value The value to convert.
3001 * @returns {string} Returns the converted string.
3002 */
3003function objectToString(value) {
3004 return nativeObjectToString.call(value);
3005}
3006
3007/**
3008 * Converts `func` to its source code.
3009 *
3010 * @private
3011 * @param {Function} func The function to convert.
3012 * @returns {string} Returns the source code.
3013 */
3014function toSource(func) {
3015 if (func != null) {
3016 try {
3017 return funcToString.call(func);
3018 } catch (e) {}
3019 try {
3020 return (func + '');
3021 } catch (e) {}
3022 }
3023 return '';
3024}
3025
3026/**
3027 * Performs a
3028 * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
3029 * comparison between two values to determine if they are equivalent.
3030 *
3031 * @static
3032 * @memberOf _
3033 * @since 4.0.0
3034 * @category Lang
3035 * @param {*} value The value to compare.
3036 * @param {*} other The other value to compare.
3037 * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
3038 * @example
3039 *
3040 * var object = { 'a': 1 };
3041 * var other = { 'a': 1 };
3042 *
3043 * _.eq(object, object);
3044 * // => true
3045 *
3046 * _.eq(object, other);
3047 * // => false
3048 *
3049 * _.eq('a', 'a');
3050 * // => true
3051 *
3052 * _.eq('a', Object('a'));
3053 * // => false
3054 *
3055 * _.eq(NaN, NaN);
3056 * // => true
3057 */
3058function eq(value, other) {
3059 return value === other || (value !== value && other !== other);
3060}
3061
3062/**
3063 * Checks if `value` is likely an `arguments` object.
3064 *
3065 * @static
3066 * @memberOf _
3067 * @since 0.1.0
3068 * @category Lang
3069 * @param {*} value The value to check.
3070 * @returns {boolean} Returns `true` if `value` is an `arguments` object,
3071 * else `false`.
3072 * @example
3073 *
3074 * _.isArguments(function() { return arguments; }());
3075 * // => true
3076 *
3077 * _.isArguments([1, 2, 3]);
3078 * // => false
3079 */
3080var isArguments = baseIsArguments(function() { return arguments; }()) ? baseIsArguments : function(value) {
3081 return isObjectLike(value) && hasOwnProperty.call(value, 'callee') &&
3082 !propertyIsEnumerable.call(value, 'callee');
3083};
3084
3085/**
3086 * Checks if `value` is classified as an `Array` object.
3087 *
3088 * @static
3089 * @memberOf _
3090 * @since 0.1.0
3091 * @category Lang
3092 * @param {*} value The value to check.
3093 * @returns {boolean} Returns `true` if `value` is an array, else `false`.
3094 * @example
3095 *
3096 * _.isArray([1, 2, 3]);
3097 * // => true
3098 *
3099 * _.isArray(document.body.children);
3100 * // => false
3101 *
3102 * _.isArray('abc');
3103 * // => false
3104 *
3105 * _.isArray(_.noop);
3106 * // => false
3107 */
3108var isArray = Array.isArray;
3109
3110/**
3111 * Checks if `value` is array-like. A value is considered array-like if it's
3112 * not a function and has a `value.length` that's an integer greater than or
3113 * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.
3114 *
3115 * @static
3116 * @memberOf _
3117 * @since 4.0.0
3118 * @category Lang
3119 * @param {*} value The value to check.
3120 * @returns {boolean} Returns `true` if `value` is array-like, else `false`.
3121 * @example
3122 *
3123 * _.isArrayLike([1, 2, 3]);
3124 * // => true
3125 *
3126 * _.isArrayLike(document.body.children);
3127 * // => true
3128 *
3129 * _.isArrayLike('abc');
3130 * // => true
3131 *
3132 * _.isArrayLike(_.noop);
3133 * // => false
3134 */
3135function isArrayLike(value) {
3136 return value != null && isLength(value.length) && !isFunction(value);
3137}
3138
3139/**
3140 * Checks if `value` is a buffer.
3141 *
3142 * @static
3143 * @memberOf _
3144 * @since 4.3.0
3145 * @category Lang
3146 * @param {*} value The value to check.
3147 * @returns {boolean} Returns `true` if `value` is a buffer, else `false`.
3148 * @example
3149 *
3150 * _.isBuffer(new Buffer(2));
3151 * // => true
3152 *
3153 * _.isBuffer(new Uint8Array(2));
3154 * // => false
3155 */
3156var isBuffer = nativeIsBuffer || stubFalse;
3157
3158/**
3159 * Performs a deep comparison between two values to determine if they are
3160 * equivalent.
3161 *
3162 * **Note:** This method supports comparing arrays, array buffers, booleans,
3163 * date objects, error objects, maps, numbers, `Object` objects, regexes,
3164 * sets, strings, symbols, and typed arrays. `Object` objects are compared
3165 * by their own, not inherited, enumerable properties. Functions and DOM
3166 * nodes are compared by strict equality, i.e. `===`.
3167 *
3168 * @static
3169 * @memberOf _
3170 * @since 0.1.0
3171 * @category Lang
3172 * @param {*} value The value to compare.
3173 * @param {*} other The other value to compare.
3174 * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
3175 * @example
3176 *
3177 * var object = { 'a': 1 };
3178 * var other = { 'a': 1 };
3179 *
3180 * _.isEqual(object, other);
3181 * // => true
3182 *
3183 * object === other;
3184 * // => false
3185 */
3186function isEqual(value, other) {
3187 return baseIsEqual(value, other);
3188}
3189
3190/**
3191 * Checks if `value` is classified as a `Function` object.
3192 *
3193 * @static
3194 * @memberOf _
3195 * @since 0.1.0
3196 * @category Lang
3197 * @param {*} value The value to check.
3198 * @returns {boolean} Returns `true` if `value` is a function, else `false`.
3199 * @example
3200 *
3201 * _.isFunction(_);
3202 * // => true
3203 *
3204 * _.isFunction(/abc/);
3205 * // => false
3206 */
3207function isFunction(value) {
3208 if (!isObject(value)) {
3209 return false;
3210 }
3211 // The use of `Object#toString` avoids issues with the `typeof` operator
3212 // in Safari 9 which returns 'object' for typed arrays and other constructors.
3213 var tag = baseGetTag(value);
3214 return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag;
3215}
3216
3217/**
3218 * Checks if `value` is a valid array-like length.
3219 *
3220 * **Note:** This method is loosely based on
3221 * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).
3222 *
3223 * @static
3224 * @memberOf _
3225 * @since 4.0.0
3226 * @category Lang
3227 * @param {*} value The value to check.
3228 * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
3229 * @example
3230 *
3231 * _.isLength(3);
3232 * // => true
3233 *
3234 * _.isLength(Number.MIN_VALUE);
3235 * // => false
3236 *
3237 * _.isLength(Infinity);
3238 * // => false
3239 *
3240 * _.isLength('3');
3241 * // => false
3242 */
3243function isLength(value) {
3244 return typeof value == 'number' &&
3245 value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
3246}
3247
3248/**
3249 * Checks if `value` is the
3250 * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
3251 * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
3252 *
3253 * @static
3254 * @memberOf _
3255 * @since 0.1.0
3256 * @category Lang
3257 * @param {*} value The value to check.
3258 * @returns {boolean} Returns `true` if `value` is an object, else `false`.
3259 * @example
3260 *
3261 * _.isObject({});
3262 * // => true
3263 *
3264 * _.isObject([1, 2, 3]);
3265 * // => true
3266 *
3267 * _.isObject(_.noop);
3268 * // => true
3269 *
3270 * _.isObject(null);
3271 * // => false
3272 */
3273function isObject(value) {
3274 var type = typeof value;
3275 return value != null && (type == 'object' || type == 'function');
3276}
3277
3278/**
3279 * Checks if `value` is object-like. A value is object-like if it's not `null`
3280 * and has a `typeof` result of "object".
3281 *
3282 * @static
3283 * @memberOf _
3284 * @since 4.0.0
3285 * @category Lang
3286 * @param {*} value The value to check.
3287 * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
3288 * @example
3289 *
3290 * _.isObjectLike({});
3291 * // => true
3292 *
3293 * _.isObjectLike([1, 2, 3]);
3294 * // => true
3295 *
3296 * _.isObjectLike(_.noop);
3297 * // => false
3298 *
3299 * _.isObjectLike(null);
3300 * // => false
3301 */
3302function isObjectLike(value) {
3303 return value != null && typeof value == 'object';
3304}
3305
3306/**
3307 * Checks if `value` is classified as a typed array.
3308 *
3309 * @static
3310 * @memberOf _
3311 * @since 3.0.0
3312 * @category Lang
3313 * @param {*} value The value to check.
3314 * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.
3315 * @example
3316 *
3317 * _.isTypedArray(new Uint8Array);
3318 * // => true
3319 *
3320 * _.isTypedArray([]);
3321 * // => false
3322 */
3323var isTypedArray = nodeIsTypedArray ? baseUnary(nodeIsTypedArray) : baseIsTypedArray;
3324
3325/**
3326 * Creates an array of the own enumerable property names of `object`.
3327 *
3328 * **Note:** Non-object values are coerced to objects. See the
3329 * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)
3330 * for more details.
3331 *
3332 * @static
3333 * @since 0.1.0
3334 * @memberOf _
3335 * @category Object
3336 * @param {Object} object The object to query.
3337 * @returns {Array} Returns the array of property names.
3338 * @example
3339 *
3340 * function Foo() {
3341 * this.a = 1;
3342 * this.b = 2;
3343 * }
3344 *
3345 * Foo.prototype.c = 3;
3346 *
3347 * _.keys(new Foo);
3348 * // => ['a', 'b'] (iteration order is not guaranteed)
3349 *
3350 * _.keys('hi');
3351 * // => ['0', '1']
3352 */
3353function keys(object) {
3354 return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object);
3355}
3356
3357/**
3358 * This method returns a new empty array.
3359 *
3360 * @static
3361 * @memberOf _
3362 * @since 4.13.0
3363 * @category Util
3364 * @returns {Array} Returns the new empty array.
3365 * @example
3366 *
3367 * var arrays = _.times(2, _.stubArray);
3368 *
3369 * console.log(arrays);
3370 * // => [[], []]
3371 *
3372 * console.log(arrays[0] === arrays[1]);
3373 * // => false
3374 */
3375function stubArray() {
3376 return [];
3377}
3378
3379/**
3380 * This method returns `false`.
3381 *
3382 * @static
3383 * @memberOf _
3384 * @since 4.13.0
3385 * @category Util
3386 * @returns {boolean} Returns `false`.
3387 * @example
3388 *
3389 * _.times(2, _.stubFalse);
3390 * // => [false, false]
3391 */
3392function stubFalse() {
3393 return false;
3394}
3395
3396module.exports = isEqual;
3397});
3398
3399const { debug, setDebugNamespace } = debug_1;
3400
3401
3402
3403
3404const {
3405 headers: headerUtils,
3406 getPath,
3407 getQuery,
3408 normalizeUrl: normalizeUrl$1
3409} = requestUtils;
3410
3411
3412const debuggableUrlFunc = func => url => {
3413 debug('Actual url:', url);
3414 return func(url);
3415};
3416
3417const stringMatchers = {
3418 begin: targetString =>
3419 debuggableUrlFunc(url => url.indexOf(targetString) === 0),
3420 end: targetString =>
3421 debuggableUrlFunc(url => url.substr(-targetString.length) === targetString),
3422 glob: targetString => {
3423 const urlRX = globToRegexp(targetString);
3424 return debuggableUrlFunc(url => urlRX.test(url));
3425 },
3426 express: targetString => {
3427 const urlRX = pathToRegexp_1(targetString);
3428 return debuggableUrlFunc(url => urlRX.test(getPath(url)));
3429 },
3430 path: targetString => debuggableUrlFunc(url => getPath(url) === targetString)
3431};
3432
3433const getHeaderMatcher = ({ headers: expectedHeaders }) => {
3434 debug('Generating header matcher');
3435 if (!expectedHeaders) {
3436 debug(' No header expectations defined - skipping');
3437 return;
3438 }
3439 const expectation = headerUtils.toLowerCase(expectedHeaders);
3440 debug(' Expected headers:', expectation);
3441 return (url, { headers = {} }) => {
3442 debug('Attempting to match headers');
3443 const lowerCaseHeaders = headerUtils.toLowerCase(
3444 headerUtils.normalize(headers)
3445 );
3446 debug(' Expected headers:', expectation);
3447 debug(' Actual headers:', lowerCaseHeaders);
3448 return Object.keys(expectation).every(headerName =>
3449 headerUtils.equal(lowerCaseHeaders[headerName], expectation[headerName])
3450 );
3451 };
3452};
3453
3454const getMethodMatcher = ({ method: expectedMethod }) => {
3455 debug('Generating method matcher');
3456 if (!expectedMethod) {
3457 debug(' No method expectations defined - skipping');
3458 return;
3459 }
3460 debug(' Expected method:', expectedMethod);
3461 return (url, { method }) => {
3462 debug('Attempting to match method');
3463 const actualMethod = method ? method.toLowerCase() : 'get';
3464 debug(' Expected method:', expectedMethod);
3465 debug(' Actual method:', actualMethod);
3466 return expectedMethod === actualMethod;
3467 };
3468};
3469
3470const getQueryStringMatcher = ({ query: expectedQuery }) => {
3471 debug('Generating query parameters matcher');
3472 if (!expectedQuery) {
3473 debug(' No query parameters expectations defined - skipping');
3474 return;
3475 }
3476 debug(' Expected query parameters:', expectedQuery);
3477 const keys = Object.keys(expectedQuery);
3478 return url => {
3479 debug('Attempting to match query parameters');
3480 const query = querystring.parse(getQuery(url));
3481 debug(' Expected query parameters:', expectedQuery);
3482 debug(' Actual query parameters:', query);
3483 return keys.every(key => query[key] === expectedQuery[key]);
3484 };
3485};
3486
3487const getParamsMatcher = ({ params: expectedParams, url: matcherUrl }) => {
3488 debug('Generating path parameters matcher');
3489 if (!expectedParams) {
3490 debug(' No path parameters expectations defined - skipping');
3491 return;
3492 }
3493 if (!/express:/.test(matcherUrl)) {
3494 throw new Error(
3495 'fetch-mock: matching on params is only possible when using an express: matcher'
3496 );
3497 }
3498 debug(' Expected path parameters:', expectedParams);
3499 const expectedKeys = Object.keys(expectedParams);
3500 const keys = [];
3501 const re = pathToRegexp_1(matcherUrl.replace(/^express:/, ''), keys);
3502 return url => {
3503 debug('Attempting to match path parameters');
3504 const vals = re.exec(getPath(url)) || [];
3505 vals.shift();
3506 const params = keys.reduce(
3507 (map, { name }, i) =>
3508 vals[i] ? Object.assign(map, { [name]: vals[i] }) : map,
3509 {}
3510 );
3511 debug(' Expected path parameters:', expectedParams);
3512 debug(' Actual path parameters:', params);
3513 return expectedKeys.every(key => params[key] === expectedParams[key]);
3514 };
3515};
3516
3517const getBodyMatcher = (route, fetchMock) => {
3518 const matchPartialBody = fetchMock.getOption('matchPartialBody', route);
3519 const { body: expectedBody } = route;
3520
3521 debug('Generating body matcher');
3522 return (url, { body, method = 'get' }) => {
3523 debug('Attempting to match body');
3524 if (method.toLowerCase() === 'get') {
3525 debug(' GET request - skip matching body');
3526 // GET requests don’t send a body so the body matcher should be ignored for them
3527 return true;
3528 }
3529
3530 let sentBody;
3531
3532 try {
3533 debug(' Parsing request body as JSON');
3534 sentBody = JSON.parse(body);
3535 } catch (err) {
3536 debug(' Failed to parse request body as JSON', err);
3537 }
3538 debug('Expected body:', expectedBody);
3539 debug('Actual body:', sentBody);
3540 if (matchPartialBody) {
3541 debug('matchPartialBody is true - checking for partial match only');
3542 }
3543
3544 return (
3545 sentBody &&
3546 (matchPartialBody
3547 ? isSubset_1(sentBody, expectedBody)
3548 : lodash_isequal(sentBody, expectedBody))
3549 );
3550 };
3551};
3552
3553const getFullUrlMatcher = (route, matcherUrl, query) => {
3554 // if none of the special syntaxes apply, it's just a simple string match
3555 // but we have to be careful to normalize the url we check and the name
3556 // of the route to allow for e.g. http://it.at.there being indistinguishable
3557 // from http://it.at.there/ once we start generating Request/Url objects
3558 debug(' Matching using full url', matcherUrl);
3559 const expectedUrl = normalizeUrl$1(matcherUrl);
3560 debug(' Normalised url to:', matcherUrl);
3561 if (route.identifier === matcherUrl) {
3562 debug(' Updating route identifier to match normalized url:', matcherUrl);
3563 route.identifier = expectedUrl;
3564 }
3565
3566 return matcherUrl => {
3567 debug('Expected url:', expectedUrl);
3568 debug('Actual url:', matcherUrl);
3569 if (query && expectedUrl.indexOf('?')) {
3570 debug('Ignoring query string when matching url');
3571 return matcherUrl.indexOf(expectedUrl) === 0;
3572 }
3573 return normalizeUrl$1(matcherUrl) === expectedUrl;
3574 };
3575};
3576
3577const getFunctionMatcher = ({ functionMatcher }) => {
3578 debug('Detected user defined function matcher', functionMatcher);
3579 return (...args) => {
3580 debug('Calling function matcher with arguments', args);
3581 return functionMatcher(...args);
3582 };
3583};
3584
3585const getUrlMatcher = route => {
3586 debug('Generating url matcher');
3587 const { url: matcherUrl, query } = route;
3588
3589 if (matcherUrl === '*') {
3590 debug(' Using universal * rule to match any url');
3591 return () => true;
3592 }
3593
3594 if (matcherUrl instanceof RegExp) {
3595 debug(' Using regular expression to match url:', matcherUrl);
3596 return url => matcherUrl.test(url);
3597 }
3598
3599 if (matcherUrl.href) {
3600 debug(` Using URL object to match url`, matcherUrl);
3601 return getFullUrlMatcher(route, matcherUrl.href, query);
3602 }
3603
3604 for (const shorthand in stringMatchers) {
3605 if (matcherUrl.indexOf(shorthand + ':') === 0) {
3606 debug(` Using ${shorthand}: pattern to match url`, matcherUrl);
3607 const urlFragment = matcherUrl.replace(new RegExp(`^${shorthand}:`), '');
3608 return stringMatchers[shorthand](urlFragment);
3609 }
3610 }
3611
3612 return getFullUrlMatcher(route, matcherUrl, query);
3613};
3614
3615var generateMatcher = (route, fetchMock) => {
3616 setDebugNamespace('generateMatcher()');
3617 debug('Compiling matcher for route');
3618 const matchers = [
3619 route.query && getQueryStringMatcher(route),
3620 route.method && getMethodMatcher(route),
3621 route.headers && getHeaderMatcher(route),
3622 route.params && getParamsMatcher(route),
3623 route.body && getBodyMatcher(route, fetchMock),
3624 route.functionMatcher && getFunctionMatcher(route),
3625 route.url && getUrlMatcher(route)
3626 ].filter(matcher => !!matcher);
3627
3628 debug('Compiled matcher for route');
3629 setDebugNamespace();
3630 return (url, options = {}, request) =>
3631 matchers.every(matcher => matcher(url, options, request));
3632};
3633
3634const { getDebug } = debug_1;
3635
3636
3637const matcherProperties = [
3638 'query',
3639 'method',
3640 'headers',
3641 'params',
3642 'body',
3643 'functionMatcher',
3644 'url'
3645];
3646
3647const isUrlMatcher = matcher =>
3648 matcher instanceof RegExp ||
3649 typeof matcher === 'string' ||
3650 (typeof matcher === 'object' && 'href' in matcher);
3651
3652const isFunctionMatcher = matcher => typeof matcher === 'function';
3653
3654const argsToRoute = args => {
3655 const [matcher, response, options = {}] = args;
3656
3657 const routeConfig = {};
3658
3659 if (isUrlMatcher(matcher) || isFunctionMatcher(matcher)) {
3660 routeConfig.matcher = matcher;
3661 } else {
3662 Object.assign(routeConfig, matcher);
3663 }
3664
3665 if (response) {
3666 routeConfig.response = response;
3667 }
3668
3669 Object.assign(routeConfig, options);
3670 return routeConfig;
3671};
3672
3673const sanitizeRoute = route => {
3674 const debug = getDebug('sanitizeRoute()');
3675 debug('Sanitizing route properties');
3676 route = Object.assign({}, route);
3677
3678 if (route.method) {
3679 debug(`Converting method ${route.method} to lower case`);
3680 route.method = route.method.toLowerCase();
3681 }
3682 if (isUrlMatcher(route.matcher)) {
3683 debug('Mock uses a url matcher', route.matcher);
3684 route.url = route.matcher;
3685 delete route.matcher;
3686 }
3687
3688 route.functionMatcher = route.matcher || route.functionMatcher;
3689
3690 debug('Setting route.identifier...');
3691 debug(` route.name is ${route.name}`);
3692 debug(` route.url is ${route.url}`);
3693 debug(` route.functionMatcher is ${route.functionMatcher}`);
3694 route.identifier = route.name || route.url || route.functionMatcher;
3695 debug(` -> route.identifier set to ${route.identifier}`);
3696 return route;
3697};
3698
3699const validateRoute = route => {
3700 if (!('response' in route)) {
3701 throw new Error('fetch-mock: Each route must define a response');
3702 }
3703
3704 if (!matcherProperties.some(matcherType => matcherType in route)) {
3705 throw new Error(
3706 "fetch-mock: Each route must specify some criteria for matching calls to fetch. To match all calls use '*'"
3707 );
3708 }
3709};
3710
3711const limit = route => {
3712 const debug = getDebug('limit()');
3713 debug('Limiting number of requests to handle by route');
3714 if (!route.repeat) {
3715 debug(
3716 ' No `repeat` value set on route. Will match any number of requests'
3717 );
3718 return;
3719 }
3720
3721 debug(` Route set to repeat ${route.repeat} times`);
3722 const matcher = route.matcher;
3723 let timesLeft = route.repeat;
3724 route.matcher = (url, options) => {
3725 const match = timesLeft && matcher(url, options);
3726 if (match) {
3727 timesLeft--;
3728 return true;
3729 }
3730 };
3731 route.reset = () => (timesLeft = route.repeat);
3732};
3733
3734const delayResponse = route => {
3735 const debug = getDebug('delayResponse()');
3736 debug(`Applying response delay settings`);
3737 const { delay } = route;
3738 if (delay) {
3739 debug(` Wrapping response in delay of ${delay} miliseconds`);
3740 const response = route.response;
3741 route.response = () => {
3742 debug(`Delaying response by ${delay} miliseconds`);
3743 return new Promise(res => setTimeout(() => res(response), delay));
3744 };
3745 } else {
3746 debug(
3747 ` No delay set on route. Will respond 'immediately' (but asynchronously)`
3748 );
3749 }
3750};
3751
3752const compileRoute = function(args) {
3753 const debug = getDebug('compileRoute()');
3754 debug('Compiling route');
3755 const route = sanitizeRoute(argsToRoute(args));
3756 validateRoute(route);
3757 route.matcher = generateMatcher(route, this);
3758 limit(route);
3759 delayResponse(route);
3760 return route;
3761};
3762
3763var compileRoute_1 = {
3764 compileRoute,
3765 sanitizeRoute
3766};
3767
3768const { debug: debug$1, setDebugPhase } = debug_1;
3769const { compileRoute: compileRoute$1 } = compileRoute_1;
3770const FetchMock = {};
3771
3772FetchMock.mock = function(...args) {
3773 setDebugPhase('setup');
3774 if (args.length) {
3775 this.addRoute(args);
3776 }
3777
3778 return this._mock();
3779};
3780
3781FetchMock.addRoute = function(uncompiledRoute) {
3782 debug$1('Adding route', uncompiledRoute);
3783 const route = this.compileRoute(uncompiledRoute);
3784 const clashes = this.routes.filter(
3785 ({ identifier, method }) =>
3786 identifier === route.identifier &&
3787 (!method || !route.method || method === route.method)
3788 );
3789
3790 if (this.getOption('overwriteRoutes', route) === false || !clashes.length) {
3791 this._uncompiledRoutes.push(uncompiledRoute);
3792 return this.routes.push(route);
3793 }
3794
3795 if (this.getOption('overwriteRoutes', route) === true) {
3796 clashes.forEach(clash => {
3797 const index = this.routes.indexOf(clash);
3798 this._uncompiledRoutes.splice(index, 1, uncompiledRoute);
3799 this.routes.splice(index, 1, route);
3800 });
3801 return this.routes;
3802 }
3803
3804 if (clashes.length) {
3805 throw new Error(
3806 'fetch-mock: Adding route with same name or matcher as existing route. See `overwriteRoutes` option.'
3807 );
3808 }
3809
3810 this._uncompiledRoutes.push(uncompiledRoute);
3811 this.routes.push(route);
3812};
3813
3814FetchMock._mock = function() {
3815 if (!this.isSandbox) {
3816 // Do this here rather than in the constructor to ensure it's scoped to the test
3817 this.realFetch = this.realFetch || this.global.fetch;
3818 this.global.fetch = this.fetchHandler;
3819 }
3820 setDebugPhase();
3821 return this;
3822};
3823
3824FetchMock.catch = function(response) {
3825 if (this.fallbackResponse) {
3826 console.warn(
3827 'calling fetchMock.catch() twice - are you sure you want to overwrite the previous fallback response'
3828 ); // eslint-disable-line
3829 }
3830 this.fallbackResponse = response || 'ok';
3831 return this._mock();
3832};
3833
3834FetchMock.spy = function() {
3835 this._mock();
3836 return this.catch(this.getNativeFetch());
3837};
3838
3839FetchMock.compileRoute = compileRoute$1;
3840
3841const defineShorthand = (methodName, underlyingMethod, shorthandOptions) => {
3842 FetchMock[methodName] = function(matcher, response, options) {
3843 return this[underlyingMethod](
3844 matcher,
3845 response,
3846 Object.assign(options || {}, shorthandOptions)
3847 );
3848 };
3849};
3850defineShorthand('once', 'mock', { repeat: 1 });
3851
3852['get', 'post', 'put', 'delete', 'head', 'patch'].forEach(method => {
3853 defineShorthand(method, 'mock', { method });
3854 defineShorthand(`${method}Once`, 'once', { method });
3855});
3856
3857FetchMock.resetBehavior = function() {
3858 if (this.realFetch) {
3859 this.global.fetch = this.realFetch;
3860 this.realFetch = undefined;
3861 }
3862 this.fallbackResponse = undefined;
3863 this.routes = [];
3864 this._uncompiledRoutes = [];
3865 return this;
3866};
3867
3868FetchMock.resetHistory = function() {
3869 this._calls = [];
3870 this._holdingPromises = [];
3871 this.routes.forEach(route => route.reset && route.reset());
3872 return this;
3873};
3874
3875FetchMock.restore = FetchMock.reset = function() {
3876 this.resetBehavior();
3877 this.resetHistory();
3878 return this;
3879};
3880
3881var setUpAndTearDown = FetchMock;
3882
3883const { getDebug: getDebug$1 } = debug_1;
3884const responseConfigProps = [
3885 'body',
3886 'headers',
3887 'throws',
3888 'status',
3889 'redirectUrl'
3890];
3891
3892class ResponseBuilder {
3893 constructor(options) {
3894 this.debug = getDebug$1('ResponseBuilder()');
3895 this.debug('Response builder created with options', options);
3896 Object.assign(this, options);
3897 }
3898
3899 exec() {
3900 this.debug('building response');
3901 this.normalizeResponseConfig();
3902 this.constructFetchOpts();
3903 this.constructResponseBody();
3904 return this.buildObservableResponse(
3905 new this.fetchMock.config.Response(this.body, this.options)
3906 );
3907 }
3908
3909 sendAsObject() {
3910 if (responseConfigProps.some(prop => this.responseConfig[prop])) {
3911 if (
3912 Object.keys(this.responseConfig).every(key =>
3913 responseConfigProps.includes(key)
3914 )
3915 ) {
3916 return false;
3917 } else {
3918 return true;
3919 }
3920 } else {
3921 return true;
3922 }
3923 }
3924
3925 normalizeResponseConfig() {
3926 // If the response config looks like a status, start to generate a simple response
3927 if (typeof this.responseConfig === 'number') {
3928 this.debug('building response using status', this.responseConfig);
3929 this.responseConfig = {
3930 status: this.responseConfig
3931 };
3932 // If the response config is not an object, or is an object that doesn't use
3933 // any reserved properties, assume it is meant to be the body of the response
3934 } else if (typeof this.responseConfig === 'string' || this.sendAsObject()) {
3935 this.debug('building text response from', this.responseConfig);
3936 this.responseConfig = {
3937 body: this.responseConfig
3938 };
3939 }
3940 }
3941
3942 validateStatus(status) {
3943 if (!status) {
3944 this.debug('No status provided. Defaulting to 200');
3945 return 200;
3946 }
3947
3948 if (
3949 (typeof status === 'number' &&
3950 parseInt(status, 10) !== status &&
3951 status >= 200) ||
3952 status < 600
3953 ) {
3954 this.debug('Valid status provided', status);
3955 return status;
3956 }
3957
3958 throw new TypeError(`fetch-mock: Invalid status ${status} passed on response object.
3959To respond with a JSON object that has status as a property assign the object to body
3960e.g. {"body": {"status: "registered"}}`);
3961 }
3962
3963 constructFetchOpts() {
3964 this.options = this.responseConfig.options || {};
3965 this.options.url = this.responseConfig.redirectUrl || this.url;
3966 this.options.status = this.validateStatus(this.responseConfig.status);
3967 this.options.statusText = this.fetchMock.statusTextMap[
3968 '' + this.options.status
3969 ];
3970 // Set up response headers. The empty object is to cope with
3971 // new Headers(undefined) throwing in Chrome
3972 // https://code.google.com/p/chromium/issues/detail?id=335871
3973 this.options.headers = new this.fetchMock.config.Headers(
3974 this.responseConfig.headers || {}
3975 );
3976 }
3977
3978 getOption(name) {
3979 return this.fetchMock.getOption(name, this.route);
3980 }
3981
3982 convertToJson() {
3983 // convert to json if we need to
3984 if (
3985 this.getOption('sendAsJson') &&
3986 this.responseConfig.body != null && //eslint-disable-line
3987 typeof this.body === 'object'
3988 ) {
3989 this.debug('Stringifying JSON response body');
3990 this.body = JSON.stringify(this.body);
3991 if (!this.options.headers.has('Content-Type')) {
3992 this.options.headers.set('Content-Type', 'application/json');
3993 }
3994 }
3995 }
3996
3997 setContentLength() {
3998 // add a Content-Length header if we need to
3999 if (
4000 this.getOption('includeContentLength') &&
4001 typeof this.body === 'string' &&
4002 !this.options.headers.has('Content-Length')
4003 ) {
4004 this.debug('Setting content-length header:', this.body.length.toString());
4005 this.options.headers.set('Content-Length', this.body.length.toString());
4006 }
4007 }
4008
4009 constructResponseBody() {
4010 // start to construct the body
4011 this.body = this.responseConfig.body;
4012 this.convertToJson();
4013 this.setContentLength();
4014
4015 // On the server we need to manually construct the readable stream for the
4016 // Response object (on the client this done automatically)
4017 if (this.Stream) {
4018 this.debug('Creating response stream');
4019 const stream = new this.Stream.Readable();
4020 if (this.body != null) { //eslint-disable-line
4021 stream.push(this.body, 'utf-8');
4022 }
4023 stream.push(null);
4024 this.body = stream;
4025 }
4026 this.body = this.body;
4027 }
4028
4029 buildObservableResponse(response) {
4030 const fetchMock = this.fetchMock;
4031
4032 // Using a proxy means we can set properties that may not be writable on
4033 // the original Response. It also means we can track the resolution of
4034 // promises returned by res.json(), res.text() etc
4035 this.debug('Wrappipng Response in ES proxy for observability');
4036 return new Proxy(response, {
4037 get: (originalResponse, name) => {
4038 if (this.responseConfig.redirectUrl) {
4039 if (name === 'url') {
4040 this.debug(
4041 'Retrieving redirect url',
4042 this.responseConfig.redirectUrl
4043 );
4044 return this.responseConfig.redirectUrl;
4045 }
4046
4047 if (name === 'redirected') {
4048 this.debug('Retrieving redirected status', true);
4049 return true;
4050 }
4051 }
4052
4053 if (typeof originalResponse[name] === 'function') {
4054 this.debug('Wrapping body promises in ES proxies for observability');
4055 return new Proxy(originalResponse[name], {
4056 apply: (func, thisArg, args) => {
4057 this.debug(`Calling res.${name}`);
4058 const result = func.apply(response, args);
4059 if (result.then) {
4060 fetchMock._holdingPromises.push(result.catch(() => null));
4061 }
4062 return result;
4063 }
4064 });
4065 }
4066
4067 return originalResponse[name];
4068 }
4069 });
4070 }
4071}
4072
4073var responseBuilder = options => new ResponseBuilder(options).exec();
4074
4075const { debug: debug$2, setDebugPhase: setDebugPhase$1, getDebug: getDebug$2 } = debug_1;
4076
4077
4078const FetchMock$1 = {};
4079
4080// see https://heycam.github.io/webidl/#aborterror for the standardised interface
4081// Note that this differs slightly from node-fetch
4082class AbortError extends Error {
4083 constructor() {
4084 super(...arguments);
4085 this.name = 'AbortError';
4086 this.message = 'The operation was aborted.';
4087
4088 // Do not include this class in the stacktrace
4089 if (Error.captureStackTrace) {
4090 Error.captureStackTrace(this, this.constructor);
4091 }
4092 }
4093}
4094
4095const resolve = async (
4096 { response, responseIsFetch = false },
4097 url,
4098 options,
4099 request
4100) => {
4101 const debug = getDebug$2('resolve()');
4102 debug('Recursively resolving function and promise responses');
4103 // We want to allow things like
4104 // - function returning a Promise for a response
4105 // - delaying (using a timeout Promise) a function's execution to generate
4106 // a response
4107 // Because of this we can't safely check for function before Promisey-ness,
4108 // or vice versa. So to keep it DRY, and flexible, we keep trying until we
4109 // have something that looks like neither Promise nor function
4110 while (true) {
4111 if (typeof response === 'function') {
4112 debug(' Response is a function');
4113 // in the case of falling back to the network we need to make sure we're using
4114 // the original Request instance, not our normalised url + options
4115 if (responseIsFetch) {
4116 if (request) {
4117 debug(' -> Calling fetch with Request instance');
4118 return response(request);
4119 }
4120 debug(' -> Calling fetch with url and options');
4121 return response(url, options);
4122 } else {
4123 debug(' -> Calling response function');
4124 response = response(url, options, request);
4125 }
4126 } else if (typeof response.then === 'function') {
4127 debug(' Response is a promise');
4128 debug(' -> Resolving promise');
4129 response = await response;
4130 } else {
4131 debug(' Response is not a function or a promise');
4132 debug(' -> Exiting response resolution recursion');
4133 return response;
4134 }
4135 }
4136};
4137
4138FetchMock$1.fetchHandler = function(url, options, request) {
4139 setDebugPhase$1('handle');
4140 const debug = getDebug$2('fetchHandler()');
4141 debug('fetch called with:', url, options);
4142 const normalizedRequest = requestUtils.normalizeRequest(
4143 url,
4144 options,
4145 this.config.Request
4146 );
4147
4148 ({ url, options, request } = normalizedRequest);
4149
4150 const { signal } = normalizedRequest;
4151
4152 debug('Request normalised');
4153 debug(' url', url);
4154 debug(' options', options);
4155 debug(' request', request);
4156 debug(' signal', signal);
4157
4158 if (request && this.routes.some(({ body }) => !!body)) {
4159 debug(
4160 'Need to wait for Body to be streamed before calling router: switching to async mode'
4161 );
4162 return this._asyncFetchHandler(url, options, request, signal);
4163 }
4164 return this._fetchHandler(url, options, request, signal);
4165};
4166
4167FetchMock$1._asyncFetchHandler = async function(url, options, request, signal) {
4168 options.body = await options.body;
4169 return this._fetchHandler(url, options, request, signal);
4170};
4171
4172FetchMock$1._fetchHandler = function(url, options, request, signal) {
4173 const route = this.executeRouter(url, options, request);
4174
4175 // this is used to power the .flush() method
4176 let done;
4177 this._holdingPromises.push(new this.config.Promise(res => (done = res)));
4178
4179 // wrapped in this promise to make sure we respect custom Promise
4180 // constructors defined by the user
4181 return new this.config.Promise((res, rej) => {
4182 if (signal) {
4183 debug$2('signal exists - enabling fetch abort');
4184 const abort = () => {
4185 debug$2('aborting fetch');
4186 // note that DOMException is not available in node.js; even node-fetch uses a custom error class: https://github.com/bitinn/node-fetch/blob/master/src/abort-error.js
4187 rej(
4188 typeof DOMException !== 'undefined'
4189 ? new DOMException('The operation was aborted.', 'AbortError')
4190 : new AbortError()
4191 );
4192 done();
4193 };
4194 if (signal.aborted) {
4195 debug$2('signal is already aborted - aborting the fetch');
4196 abort();
4197 }
4198 signal.addEventListener('abort', abort);
4199 }
4200
4201 this.generateResponse(route, url, options, request)
4202 .then(res, rej)
4203 .then(done, done)
4204 .then(() => {
4205 setDebugPhase$1();
4206 });
4207 });
4208};
4209
4210FetchMock$1.fetchHandler.isMock = true;
4211
4212FetchMock$1.executeRouter = function(url, options, request) {
4213 const debug = getDebug$2('executeRouter()');
4214 debug(`Attempting to match request to a route`);
4215 if (this.getOption('fallbackToNetwork') === 'always') {
4216 debug(
4217 ' Configured with fallbackToNetwork=always - passing through to fetch'
4218 );
4219 return { response: this.getNativeFetch(), responseIsFetch: true };
4220 }
4221
4222 const match = this.router(url, options, request);
4223
4224 if (match) {
4225 debug(' Matching route found');
4226 return match;
4227 }
4228
4229 if (this.getOption('warnOnFallback')) {
4230 console.warn(`Unmatched ${(options && options.method) || 'GET'} to ${url}`); // eslint-disable-line
4231 }
4232
4233 this.push({ url, options, request, isUnmatched: true });
4234
4235 if (this.fallbackResponse) {
4236 debug(' No matching route found - using fallbackResponse');
4237 return { response: this.fallbackResponse };
4238 }
4239
4240 if (!this.getOption('fallbackToNetwork')) {
4241 throw new Error(
4242 `fetch-mock: No fallback response defined for ${(options &&
4243 options.method) ||
4244 'GET'} to ${url}`
4245 );
4246 }
4247
4248 debug(' Configured to fallbackToNetwork - passing through to fetch');
4249 return { response: this.getNativeFetch(), responseIsFetch: true };
4250};
4251
4252FetchMock$1.generateResponse = async function(route, url, options, request) {
4253 const debug = getDebug$2('generateResponse()');
4254 const response = await resolve(route, url, options, request);
4255
4256 // If the response says to throw an error, throw it
4257 // Type checking is to deal with sinon spies having a throws property :-0
4258 if (response.throws && typeof response !== 'function') {
4259 debug('response.throws is defined - throwing an error');
4260 throw response.throws;
4261 }
4262
4263 // If the response is a pre-made Response, respond with it
4264 if (this.config.Response.prototype.isPrototypeOf(response)) {
4265 debug('response is already a Response instance - returning it');
4266 return response;
4267 }
4268
4269 // finally, if we need to convert config into a response, we do it
4270 return responseBuilder({
4271 url,
4272 responseConfig: response,
4273 fetchMock: this,
4274 route
4275 });
4276};
4277
4278FetchMock$1.router = function(url, options, request) {
4279 const route = this.routes.find((route, i) => {
4280 debug$2(`Trying to match route ${i}`);
4281 return route.matcher(url, options, request);
4282 });
4283
4284 if (route) {
4285 this.push({
4286 url,
4287 options,
4288 request,
4289 identifier: route.identifier
4290 });
4291 return route;
4292 }
4293};
4294
4295FetchMock$1.getNativeFetch = function() {
4296 const func = this.realFetch || (this.isSandbox && this.config.fetch);
4297 if (!func) {
4298 throw new Error(
4299 'fetch-mock: Falling back to network only available on global fetch-mock, or by setting config.fetch on sandboxed fetch-mock'
4300 );
4301 }
4302 return func;
4303};
4304
4305FetchMock$1.push = function({ url, options, request, isUnmatched, identifier }) {
4306 debug$2('Recording fetch call', {
4307 url,
4308 options,
4309 request,
4310 isUnmatched,
4311 identifier
4312 });
4313 const args = [url, options];
4314 args.request = request;
4315 args.identifier = identifier;
4316 args.isUnmatched = isUnmatched;
4317 this._calls.push(args);
4318};
4319
4320var fetchHandler = FetchMock$1;
4321
4322const { setDebugPhase: setDebugPhase$2, setDebugNamespace: setDebugNamespace$1, debug: debug$3 } = debug_1;
4323const { normalizeUrl: normalizeUrl$2 } = requestUtils;
4324const FetchMock$2 = {};
4325const { sanitizeRoute: sanitizeRoute$1 } = compileRoute_1;
4326
4327const isName = nameOrMatcher =>
4328 typeof nameOrMatcher === 'string' && /^[\da-zA-Z\-]+$/.test(nameOrMatcher);
4329
4330const filterCallsWithMatcher = function(matcher, options = {}, calls) {
4331 matcher = generateMatcher(
4332 sanitizeRoute$1(Object.assign({ matcher }, options)),
4333 this
4334 );
4335 return calls.filter(([url, options]) => matcher(normalizeUrl$2(url), options));
4336};
4337
4338const formatDebug = func => {
4339 return function(...args) {
4340 setDebugPhase$2('inspect');
4341 const result = func.call(this, ...args);
4342 setDebugPhase$2();
4343 return result;
4344 };
4345};
4346
4347FetchMock$2.filterCalls = function(nameOrMatcher, options) {
4348 debug$3('Filtering fetch calls');
4349 let calls = this._calls;
4350 let matcher = '*';
4351
4352 if ([true, 'matched'].includes(nameOrMatcher)) {
4353 debug$3(`Filter provided is ${nameOrMatcher}. Returning matched calls only`);
4354 calls = calls.filter(({ isUnmatched }) => !isUnmatched);
4355 } else if ([false, 'unmatched'].includes(nameOrMatcher)) {
4356 debug$3(
4357 `Filter provided is ${nameOrMatcher}. Returning unmatched calls only`
4358 );
4359 calls = calls.filter(({ isUnmatched }) => isUnmatched);
4360 } else if (typeof nameOrMatcher === 'undefined') {
4361 debug$3(`Filter provided is undefined. Returning all calls`);
4362 calls = calls;
4363 } else if (isName(nameOrMatcher)) {
4364 debug$3(
4365 `Filter provided, looks like the name of a named route. Returning only calls handled by that route`
4366 );
4367 calls = calls.filter(({ identifier }) => identifier === nameOrMatcher);
4368 } else {
4369 matcher = normalizeUrl$2(nameOrMatcher);
4370 if (this.routes.some(({ identifier }) => identifier === matcher)) {
4371 debug$3(
4372 `Filter provided, ${nameOrMatcher}, identifies a route. Returning only calls handled by that route`
4373 );
4374 calls = calls.filter(call => call.identifier === matcher);
4375 }
4376 }
4377
4378 if ((options || matcher !== '*') && calls.length) {
4379 if (typeof options === 'string') {
4380 options = { method: options };
4381 }
4382 debug$3(
4383 'Compiling filter and options to route in order to filter all calls',
4384 nameOrMatcher
4385 );
4386 calls = filterCallsWithMatcher.call(this, matcher, options, calls);
4387 }
4388 debug$3(`Retrieved ${calls.length} calls`);
4389 return calls;
4390};
4391
4392FetchMock$2.calls = formatDebug(function(nameOrMatcher, options) {
4393 debug$3('retrieving matching calls');
4394 return this.filterCalls(nameOrMatcher, options);
4395});
4396
4397FetchMock$2.lastCall = formatDebug(function(nameOrMatcher, options) {
4398 debug$3('retrieving last matching call');
4399 return [...this.filterCalls(nameOrMatcher, options)].pop();
4400});
4401
4402FetchMock$2.lastUrl = formatDebug(function(nameOrMatcher, options) {
4403 debug$3('retrieving url of last matching call');
4404 return (this.lastCall(nameOrMatcher, options) || [])[0];
4405});
4406
4407FetchMock$2.lastOptions = formatDebug(function(nameOrMatcher, options) {
4408 debug$3('retrieving options of last matching call');
4409 return (this.lastCall(nameOrMatcher, options) || [])[1];
4410});
4411
4412FetchMock$2.called = formatDebug(function(nameOrMatcher, options) {
4413 debug$3('checking if matching call was made');
4414 return !!this.filterCalls(nameOrMatcher, options).length;
4415});
4416
4417FetchMock$2.flush = formatDebug(async function(waitForResponseMethods) {
4418 setDebugNamespace$1('flush');
4419 debug$3(
4420 `flushing all fetch calls. ${
4421 waitForResponseMethods ? '' : 'Not '
4422 }waiting for response bodies to complete download`
4423 );
4424
4425 const queuedPromises = this._holdingPromises;
4426 this._holdingPromises = [];
4427 debug$3(`${queuedPromises.length} fetch calls to be awaited`);
4428
4429 await Promise.all(queuedPromises);
4430 debug$3(`All fetch calls have completed`);
4431 if (waitForResponseMethods && this._holdingPromises.length) {
4432 debug$3(`Awaiting all fetch bodies to download`);
4433 await this.flush(waitForResponseMethods);
4434 debug$3(`All fetch bodies have completed downloading`);
4435 }
4436 setDebugNamespace$1();
4437});
4438
4439FetchMock$2.done = formatDebug(function(nameOrMatcher) {
4440 setDebugPhase$2('inspect');
4441 setDebugNamespace$1('done');
4442 debug$3('Checking to see if expected calls have been made');
4443 let routesToCheck;
4444
4445 if (nameOrMatcher && typeof nameOrMatcher !== 'boolean') {
4446 debug$3(
4447 'Checking to see if expected calls have been made for single route:',
4448 nameOrMatcher
4449 );
4450 routesToCheck = [{ identifier: nameOrMatcher }];
4451 } else {
4452 debug$3('Checking to see if expected calls have been made for all routes');
4453 routesToCheck = this.routes;
4454 }
4455
4456 // Can't use array.every because would exit after first failure, which would
4457 // break the logging
4458 const result = routesToCheck
4459 .map(({ identifier }) => {
4460 if (!this.called(identifier)) {
4461 debug$3('No calls made for route:', identifier);
4462 console.warn(`Warning: ${identifier} not called`); // eslint-disable-line
4463 return false;
4464 }
4465
4466 const expectedTimes = (
4467 this.routes.find(r => r.identifier === identifier) || {}
4468 ).repeat;
4469
4470 if (!expectedTimes) {
4471 debug$3(
4472 'Route has been called at least once, and no expectation of more set:',
4473 identifier
4474 );
4475 return true;
4476 }
4477 const actualTimes = this.filterCalls(identifier).length;
4478
4479 debug$3(`Route called ${actualTimes} times:`, identifier);
4480 if (expectedTimes > actualTimes) {
4481 debug$3(
4482 `Route called ${actualTimes} times, but expected ${expectedTimes}:`,
4483 identifier
4484 );
4485 console.warn(
4486 `Warning: ${identifier} only called ${actualTimes} times, but ${expectedTimes} expected`
4487 ); // eslint-disable-line
4488 return false;
4489 } else {
4490 return true;
4491 }
4492 })
4493 .every(isDone => isDone);
4494
4495 setDebugNamespace$1();
4496 setDebugPhase$2();
4497 return result;
4498});
4499
4500var inspecting = FetchMock$2;
4501
4502const { debug: debug$4 } = debug_1;
4503
4504
4505
4506
4507const FetchMock$3 = Object.assign({}, fetchHandler, setUpAndTearDown, inspecting);
4508
4509FetchMock$3.config = {
4510 fallbackToNetwork: false,
4511 includeContentLength: true,
4512 sendAsJson: true,
4513 warnOnFallback: true,
4514 overwriteRoutes: undefined
4515};
4516
4517FetchMock$3.createInstance = function() {
4518 debug$4('Creating fetch-mock instance');
4519 const instance = Object.create(FetchMock$3);
4520 instance._uncompiledRoutes = (this._uncompiledRoutes || []).slice();
4521 instance.routes = instance._uncompiledRoutes.map(config =>
4522 instance.compileRoute(config)
4523 );
4524 instance.fallbackResponse = this.fallbackResponse || undefined;
4525 instance.config = Object.assign({}, this.config || FetchMock$3.config);
4526 instance._calls = [];
4527 instance._holdingPromises = [];
4528 instance.bindMethods();
4529 return instance;
4530};
4531
4532FetchMock$3.bindMethods = function() {
4533 this.fetchHandler = FetchMock$3.fetchHandler.bind(this);
4534 this.reset = this.restore = FetchMock$3.reset.bind(this);
4535 this.resetHistory = FetchMock$3.resetHistory.bind(this);
4536 this.resetBehavior = FetchMock$3.resetBehavior.bind(this);
4537};
4538
4539FetchMock$3.sandbox = function() {
4540 debug$4('Creating sandboxed fetch-mock instance');
4541 // this construct allows us to create a fetch-mock instance which is also
4542 // a callable function, while circumventing circularity when defining the
4543 // object that this function should be bound to
4544 const proxy = (url, options) => sandbox.fetchHandler(url, options);
4545
4546 const sandbox = Object.assign(
4547 proxy, // Ensures that the entire returned object is a callable function
4548 FetchMock$3, // prototype methods
4549 this.createInstance() // instance data
4550 );
4551
4552 sandbox.bindMethods();
4553 sandbox.isSandbox = true;
4554 return sandbox;
4555};
4556
4557FetchMock$3.getOption = function(name, route = {}) {
4558 return name in route ? route[name] : this.config[name];
4559};
4560
4561var lib = FetchMock$3;
4562
4563const statusTextMap = {
4564 '100': 'Continue',
4565 '101': 'Switching Protocols',
4566 '102': 'Processing',
4567 '200': 'OK',
4568 '201': 'Created',
4569 '202': 'Accepted',
4570 '203': 'Non-Authoritative Information',
4571 '204': 'No Content',
4572 '205': 'Reset Content',
4573 '206': 'Partial Content',
4574 '207': 'Multi-Status',
4575 '208': 'Already Reported',
4576 '226': 'IM Used',
4577 '300': 'Multiple Choices',
4578 '301': 'Moved Permanently',
4579 '302': 'Found',
4580 '303': 'See Other',
4581 '304': 'Not Modified',
4582 '305': 'Use Proxy',
4583 '307': 'Temporary Redirect',
4584 '308': 'Permanent Redirect',
4585 '400': 'Bad Request',
4586 '401': 'Unauthorized',
4587 '402': 'Payment Required',
4588 '403': 'Forbidden',
4589 '404': 'Not Found',
4590 '405': 'Method Not Allowed',
4591 '406': 'Not Acceptable',
4592 '407': 'Proxy Authentication Required',
4593 '408': 'Request Timeout',
4594 '409': 'Conflict',
4595 '410': 'Gone',
4596 '411': 'Length Required',
4597 '412': 'Precondition Failed',
4598 '413': 'Payload Too Large',
4599 '414': 'URI Too Long',
4600 '415': 'Unsupported Media Type',
4601 '416': 'Range Not Satisfiable',
4602 '417': 'Expectation Failed',
4603 '418': "I'm a teapot",
4604 '421': 'Misdirected Request',
4605 '422': 'Unprocessable Entity',
4606 '423': 'Locked',
4607 '424': 'Failed Dependency',
4608 '425': 'Unordered Collection',
4609 '426': 'Upgrade Required',
4610 '428': 'Precondition Required',
4611 '429': 'Too Many Requests',
4612 '431': 'Request Header Fields Too Large',
4613 '451': 'Unavailable For Legal Reasons',
4614 '500': 'Internal Server Error',
4615 '501': 'Not Implemented',
4616 '502': 'Bad Gateway',
4617 '503': 'Service Unavailable',
4618 '504': 'Gateway Timeout',
4619 '505': 'HTTP Version Not Supported',
4620 '506': 'Variant Also Negotiates',
4621 '507': 'Insufficient Storage',
4622 '508': 'Loop Detected',
4623 '509': 'Bandwidth Limit Exceeded',
4624 '510': 'Not Extended',
4625 '511': 'Network Authentication Required'
4626};
4627
4628var statusText = statusTextMap;
4629
4630const theGlobal = typeof window !== 'undefined' ? window : self;
4631const { setUrlImplementation } = requestUtils;
4632setUrlImplementation(theGlobal.URL);
4633
4634lib.global = theGlobal;
4635lib.statusTextMap = statusText;
4636
4637lib.config = Object.assign(lib.config, {
4638 Promise: theGlobal.Promise,
4639 Request: theGlobal.Request,
4640 Response: theGlobal.Response,
4641 Headers: theGlobal.Headers
4642});
4643
4644var client = lib.createInstance();
4645
4646export default client;