· 6 years ago · Nov 08, 2019, 04:42 PM
1// modules are defined as an array
2// [ module function, map of requires ]
3//
4// map of requires is short require name -> numeric require
5//
6// anything defined in a previous bundle is accessed via the
7// orig method which is the require for previous bundles
8parcelRequire = (function (modules, cache, entry, globalName) {
9 // Save the require from previous bundle to this closure if any
10 var previousRequire = typeof parcelRequire === 'function' && parcelRequire;
11 var nodeRequire = typeof require === 'function' && require;
12
13 function newRequire(name, jumped) {
14 if (!cache[name]) {
15 if (!modules[name]) {
16 // if we cannot find the module within our internal map or
17 // cache jump to the current global require ie. the last bundle
18 // that was added to the page.
19 var currentRequire = typeof parcelRequire === 'function' && parcelRequire;
20 if (!jumped && currentRequire) {
21 return currentRequire(name, true);
22 }
23
24 // If there are other bundles on this page the require from the
25 // previous one is saved to 'previousRequire'. Repeat this as
26 // many times as there are bundles until the module is found or
27 // we exhaust the require chain.
28 if (previousRequire) {
29 return previousRequire(name, true);
30 }
31
32 // Try the node require function if it exists.
33 if (nodeRequire && typeof name === 'string') {
34 return nodeRequire(name);
35 }
36
37 var err = new Error('Cannot find module \'' + name + '\'');
38 err.code = 'MODULE_NOT_FOUND';
39 throw err;
40 }
41
42 localRequire.resolve = resolve;
43 localRequire.cache = {};
44
45 var module = cache[name] = new newRequire.Module(name);
46
47 modules[name][0].call(module.exports, localRequire, module, module.exports, this);
48 }
49
50 return cache[name].exports;
51
52 function localRequire(x){
53 return newRequire(localRequire.resolve(x));
54 }
55
56 function resolve(x){
57 return modules[name][1][x] || x;
58 }
59 }
60
61 function Module(moduleName) {
62 this.id = moduleName;
63 this.bundle = newRequire;
64 this.exports = {};
65 }
66
67 newRequire.isParcelRequire = true;
68 newRequire.Module = Module;
69 newRequire.modules = modules;
70 newRequire.cache = cache;
71 newRequire.parent = previousRequire;
72 newRequire.register = function (id, exports) {
73 modules[id] = [function (require, module) {
74 module.exports = exports;
75 }, {}];
76 };
77
78 var error;
79 for (var i = 0; i < entry.length; i++) {
80 try {
81 newRequire(entry[i]);
82 } catch (e) {
83 // Save first error but execute all entries
84 if (!error) {
85 error = e;
86 }
87 }
88 }
89
90 if (entry.length) {
91 // Expose entry point to Node, AMD or browser globals
92 // Based on https://github.com/ForbesLindesay/umd/blob/master/template.js
93 var mainExports = newRequire(entry[entry.length - 1]);
94
95 // CommonJS
96 if (typeof exports === "object" && typeof module !== "undefined") {
97 module.exports = mainExports;
98
99 // RequireJS
100 } else if (typeof define === "function" && define.amd) {
101 define(function () {
102 return mainExports;
103 });
104
105 // <script>
106 } else if (globalName) {
107 this[globalName] = mainExports;
108 }
109 }
110
111 // Override the current require with this new one
112 parcelRequire = newRequire;
113
114 if (error) {
115 // throw error from earlier, _after updating parcelRequire_
116 throw error;
117 }
118
119 return newRequire;
120})({"RSRz":[function(require,module,exports) {
121var global = arguments[3];
122
123/**
124 * Lodash (Custom Build) <https://lodash.com/>
125 * Build: `lodash modularize exports="npm" -o ./`
126 * Copyright JS Foundation and other contributors <https://js.foundation/>
127 * Released under MIT license <https://lodash.com/license>
128 * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
129 * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
130 */
131
132/** Used as the size to enable large array optimizations. */
133var LARGE_ARRAY_SIZE = 200;
134
135/** Used to stand-in for `undefined` hash values. */
136var HASH_UNDEFINED = '__lodash_hash_undefined__';
137
138/** Used to compose bitmasks for value comparisons. */
139var COMPARE_PARTIAL_FLAG = 1,
140 COMPARE_UNORDERED_FLAG = 2;
141
142/** Used as references for various `Number` constants. */
143var MAX_SAFE_INTEGER = 9007199254740991;
144
145/** `Object#toString` result references. */
146var argsTag = '[object Arguments]',
147 arrayTag = '[object Array]',
148 asyncTag = '[object AsyncFunction]',
149 boolTag = '[object Boolean]',
150 dateTag = '[object Date]',
151 errorTag = '[object Error]',
152 funcTag = '[object Function]',
153 genTag = '[object GeneratorFunction]',
154 mapTag = '[object Map]',
155 numberTag = '[object Number]',
156 nullTag = '[object Null]',
157 objectTag = '[object Object]',
158 promiseTag = '[object Promise]',
159 proxyTag = '[object Proxy]',
160 regexpTag = '[object RegExp]',
161 setTag = '[object Set]',
162 stringTag = '[object String]',
163 symbolTag = '[object Symbol]',
164 undefinedTag = '[object Undefined]',
165 weakMapTag = '[object WeakMap]';
166
167var arrayBufferTag = '[object ArrayBuffer]',
168 dataViewTag = '[object DataView]',
169 float32Tag = '[object Float32Array]',
170 float64Tag = '[object Float64Array]',
171 int8Tag = '[object Int8Array]',
172 int16Tag = '[object Int16Array]',
173 int32Tag = '[object Int32Array]',
174 uint8Tag = '[object Uint8Array]',
175 uint8ClampedTag = '[object Uint8ClampedArray]',
176 uint16Tag = '[object Uint16Array]',
177 uint32Tag = '[object Uint32Array]';
178
179/**
180 * Used to match `RegExp`
181 * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns).
182 */
183var reRegExpChar = /[\\^$.*+?()[\]{}|]/g;
184
185/** Used to detect host constructors (Safari). */
186var reIsHostCtor = /^\[object .+?Constructor\]$/;
187
188/** Used to detect unsigned integer values. */
189var reIsUint = /^(?:0|[1-9]\d*)$/;
190
191/** Used to identify `toStringTag` values of typed arrays. */
192var typedArrayTags = {};
193typedArrayTags[float32Tag] = typedArrayTags[float64Tag] =
194typedArrayTags[int8Tag] = typedArrayTags[int16Tag] =
195typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] =
196typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] =
197typedArrayTags[uint32Tag] = true;
198typedArrayTags[argsTag] = typedArrayTags[arrayTag] =
199typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] =
200typedArrayTags[dataViewTag] = typedArrayTags[dateTag] =
201typedArrayTags[errorTag] = typedArrayTags[funcTag] =
202typedArrayTags[mapTag] = typedArrayTags[numberTag] =
203typedArrayTags[objectTag] = typedArrayTags[regexpTag] =
204typedArrayTags[setTag] = typedArrayTags[stringTag] =
205typedArrayTags[weakMapTag] = false;
206
207/** Detect free variable `global` from Node.js. */
208var freeGlobal = typeof global == 'object' && global && global.Object === Object && global;
209
210/** Detect free variable `self`. */
211var freeSelf = typeof self == 'object' && self && self.Object === Object && self;
212
213/** Used as a reference to the global object. */
214var root = freeGlobal || freeSelf || Function('return this')();
215
216/** Detect free variable `exports`. */
217var freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports;
218
219/** Detect free variable `module`. */
220var freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module;
221
222/** Detect the popular CommonJS extension `module.exports`. */
223var moduleExports = freeModule && freeModule.exports === freeExports;
224
225/** Detect free variable `process` from Node.js. */
226var freeProcess = moduleExports && freeGlobal.process;
227
228/** Used to access faster Node.js helpers. */
229var nodeUtil = (function() {
230 try {
231 return freeProcess && freeProcess.binding && freeProcess.binding('util');
232 } catch (e) {}
233}());
234
235/* Node.js helper references. */
236var nodeIsTypedArray = nodeUtil && nodeUtil.isTypedArray;
237
238/**
239 * A specialized version of `_.filter` for arrays without support for
240 * iteratee shorthands.
241 *
242 * @private
243 * @param {Array} [array] The array to iterate over.
244 * @param {Function} predicate The function invoked per iteration.
245 * @returns {Array} Returns the new filtered array.
246 */
247function arrayFilter(array, predicate) {
248 var index = -1,
249 length = array == null ? 0 : array.length,
250 resIndex = 0,
251 result = [];
252
253 while (++index < length) {
254 var value = array[index];
255 if (predicate(value, index, array)) {
256 result[resIndex++] = value;
257 }
258 }
259 return result;
260}
261
262/**
263 * Appends the elements of `values` to `array`.
264 *
265 * @private
266 * @param {Array} array The array to modify.
267 * @param {Array} values The values to append.
268 * @returns {Array} Returns `array`.
269 */
270function arrayPush(array, values) {
271 var index = -1,
272 length = values.length,
273 offset = array.length;
274
275 while (++index < length) {
276 array[offset + index] = values[index];
277 }
278 return array;
279}
280
281/**
282 * A specialized version of `_.some` for arrays without support for iteratee
283 * shorthands.
284 *
285 * @private
286 * @param {Array} [array] The array to iterate over.
287 * @param {Function} predicate The function invoked per iteration.
288 * @returns {boolean} Returns `true` if any element passes the predicate check,
289 * else `false`.
290 */
291function arraySome(array, predicate) {
292 var index = -1,
293 length = array == null ? 0 : array.length;
294
295 while (++index < length) {
296 if (predicate(array[index], index, array)) {
297 return true;
298 }
299 }
300 return false;
301}
302
303/**
304 * The base implementation of `_.times` without support for iteratee shorthands
305 * or max array length checks.
306 *
307 * @private
308 * @param {number} n The number of times to invoke `iteratee`.
309 * @param {Function} iteratee The function invoked per iteration.
310 * @returns {Array} Returns the array of results.
311 */
312function baseTimes(n, iteratee) {
313 var index = -1,
314 result = Array(n);
315
316 while (++index < n) {
317 result[index] = iteratee(index);
318 }
319 return result;
320}
321
322/**
323 * The base implementation of `_.unary` without support for storing metadata.
324 *
325 * @private
326 * @param {Function} func The function to cap arguments for.
327 * @returns {Function} Returns the new capped function.
328 */
329function baseUnary(func) {
330 return function(value) {
331 return func(value);
332 };
333}
334
335/**
336 * Checks if a `cache` value for `key` exists.
337 *
338 * @private
339 * @param {Object} cache The cache to query.
340 * @param {string} key The key of the entry to check.
341 * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
342 */
343function cacheHas(cache, key) {
344 return cache.has(key);
345}
346
347/**
348 * Gets the value at `key` of `object`.
349 *
350 * @private
351 * @param {Object} [object] The object to query.
352 * @param {string} key The key of the property to get.
353 * @returns {*} Returns the property value.
354 */
355function getValue(object, key) {
356 return object == null ? undefined : object[key];
357}
358
359/**
360 * Converts `map` to its key-value pairs.
361 *
362 * @private
363 * @param {Object} map The map to convert.
364 * @returns {Array} Returns the key-value pairs.
365 */
366function mapToArray(map) {
367 var index = -1,
368 result = Array(map.size);
369
370 map.forEach(function(value, key) {
371 result[++index] = [key, value];
372 });
373 return result;
374}
375
376/**
377 * Creates a unary function that invokes `func` with its argument transformed.
378 *
379 * @private
380 * @param {Function} func The function to wrap.
381 * @param {Function} transform The argument transform.
382 * @returns {Function} Returns the new function.
383 */
384function overArg(func, transform) {
385 return function(arg) {
386 return func(transform(arg));
387 };
388}
389
390/**
391 * Converts `set` to an array of its values.
392 *
393 * @private
394 * @param {Object} set The set to convert.
395 * @returns {Array} Returns the values.
396 */
397function setToArray(set) {
398 var index = -1,
399 result = Array(set.size);
400
401 set.forEach(function(value) {
402 result[++index] = value;
403 });
404 return result;
405}
406
407/** Used for built-in method references. */
408var arrayProto = Array.prototype,
409 funcProto = Function.prototype,
410 objectProto = Object.prototype;
411
412/** Used to detect overreaching core-js shims. */
413var coreJsData = root['__core-js_shared__'];
414
415/** Used to resolve the decompiled source of functions. */
416var funcToString = funcProto.toString;
417
418/** Used to check objects for own properties. */
419var hasOwnProperty = objectProto.hasOwnProperty;
420
421/** Used to detect methods masquerading as native. */
422var maskSrcKey = (function() {
423 var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || '');
424 return uid ? ('Symbol(src)_1.' + uid) : '';
425}());
426
427/**
428 * Used to resolve the
429 * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
430 * of values.
431 */
432var nativeObjectToString = objectProto.toString;
433
434/** Used to detect if a method is native. */
435var reIsNative = RegExp('^' +
436 funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&')
437 .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'
438);
439
440/** Built-in value references. */
441var Buffer = moduleExports ? root.Buffer : undefined,
442 Symbol = root.Symbol,
443 Uint8Array = root.Uint8Array,
444 propertyIsEnumerable = objectProto.propertyIsEnumerable,
445 splice = arrayProto.splice,
446 symToStringTag = Symbol ? Symbol.toStringTag : undefined;
447
448/* Built-in method references for those with the same name as other `lodash` methods. */
449var nativeGetSymbols = Object.getOwnPropertySymbols,
450 nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined,
451 nativeKeys = overArg(Object.keys, Object);
452
453/* Built-in method references that are verified to be native. */
454var DataView = getNative(root, 'DataView'),
455 Map = getNative(root, 'Map'),
456 Promise = getNative(root, 'Promise'),
457 Set = getNative(root, 'Set'),
458 WeakMap = getNative(root, 'WeakMap'),
459 nativeCreate = getNative(Object, 'create');
460
461/** Used to detect maps, sets, and weakmaps. */
462var dataViewCtorString = toSource(DataView),
463 mapCtorString = toSource(Map),
464 promiseCtorString = toSource(Promise),
465 setCtorString = toSource(Set),
466 weakMapCtorString = toSource(WeakMap);
467
468/** Used to convert symbols to primitives and strings. */
469var symbolProto = Symbol ? Symbol.prototype : undefined,
470 symbolValueOf = symbolProto ? symbolProto.valueOf : undefined;
471
472/**
473 * Creates a hash object.
474 *
475 * @private
476 * @constructor
477 * @param {Array} [entries] The key-value pairs to cache.
478 */
479function Hash(entries) {
480 var index = -1,
481 length = entries == null ? 0 : entries.length;
482
483 this.clear();
484 while (++index < length) {
485 var entry = entries[index];
486 this.set(entry[0], entry[1]);
487 }
488}
489
490/**
491 * Removes all key-value entries from the hash.
492 *
493 * @private
494 * @name clear
495 * @memberOf Hash
496 */
497function hashClear() {
498 this.__data__ = nativeCreate ? nativeCreate(null) : {};
499 this.size = 0;
500}
501
502/**
503 * Removes `key` and its value from the hash.
504 *
505 * @private
506 * @name delete
507 * @memberOf Hash
508 * @param {Object} hash The hash to modify.
509 * @param {string} key The key of the value to remove.
510 * @returns {boolean} Returns `true` if the entry was removed, else `false`.
511 */
512function hashDelete(key) {
513 var result = this.has(key) && delete this.__data__[key];
514 this.size -= result ? 1 : 0;
515 return result;
516}
517
518/**
519 * Gets the hash value for `key`.
520 *
521 * @private
522 * @name get
523 * @memberOf Hash
524 * @param {string} key The key of the value to get.
525 * @returns {*} Returns the entry value.
526 */
527function hashGet(key) {
528 var data = this.__data__;
529 if (nativeCreate) {
530 var result = data[key];
531 return result === HASH_UNDEFINED ? undefined : result;
532 }
533 return hasOwnProperty.call(data, key) ? data[key] : undefined;
534}
535
536/**
537 * Checks if a hash value for `key` exists.
538 *
539 * @private
540 * @name has
541 * @memberOf Hash
542 * @param {string} key The key of the entry to check.
543 * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
544 */
545function hashHas(key) {
546 var data = this.__data__;
547 return nativeCreate ? (data[key] !== undefined) : hasOwnProperty.call(data, key);
548}
549
550/**
551 * Sets the hash `key` to `value`.
552 *
553 * @private
554 * @name set
555 * @memberOf Hash
556 * @param {string} key The key of the value to set.
557 * @param {*} value The value to set.
558 * @returns {Object} Returns the hash instance.
559 */
560function hashSet(key, value) {
561 var data = this.__data__;
562 this.size += this.has(key) ? 0 : 1;
563 data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value;
564 return this;
565}
566
567// Add methods to `Hash`.
568Hash.prototype.clear = hashClear;
569Hash.prototype['delete'] = hashDelete;
570Hash.prototype.get = hashGet;
571Hash.prototype.has = hashHas;
572Hash.prototype.set = hashSet;
573
574/**
575 * Creates an list cache object.
576 *
577 * @private
578 * @constructor
579 * @param {Array} [entries] The key-value pairs to cache.
580 */
581function ListCache(entries) {
582 var index = -1,
583 length = entries == null ? 0 : entries.length;
584
585 this.clear();
586 while (++index < length) {
587 var entry = entries[index];
588 this.set(entry[0], entry[1]);
589 }
590}
591
592/**
593 * Removes all key-value entries from the list cache.
594 *
595 * @private
596 * @name clear
597 * @memberOf ListCache
598 */
599function listCacheClear() {
600 this.__data__ = [];
601 this.size = 0;
602}
603
604/**
605 * Removes `key` and its value from the list cache.
606 *
607 * @private
608 * @name delete
609 * @memberOf ListCache
610 * @param {string} key The key of the value to remove.
611 * @returns {boolean} Returns `true` if the entry was removed, else `false`.
612 */
613function listCacheDelete(key) {
614 var data = this.__data__,
615 index = assocIndexOf(data, key);
616
617 if (index < 0) {
618 return false;
619 }
620 var lastIndex = data.length - 1;
621 if (index == lastIndex) {
622 data.pop();
623 } else {
624 splice.call(data, index, 1);
625 }
626 --this.size;
627 return true;
628}
629
630/**
631 * Gets the list cache value for `key`.
632 *
633 * @private
634 * @name get
635 * @memberOf ListCache
636 * @param {string} key The key of the value to get.
637 * @returns {*} Returns the entry value.
638 */
639function listCacheGet(key) {
640 var data = this.__data__,
641 index = assocIndexOf(data, key);
642
643 return index < 0 ? undefined : data[index][1];
644}
645
646/**
647 * Checks if a list cache value for `key` exists.
648 *
649 * @private
650 * @name has
651 * @memberOf ListCache
652 * @param {string} key The key of the entry to check.
653 * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
654 */
655function listCacheHas(key) {
656 return assocIndexOf(this.__data__, key) > -1;
657}
658
659/**
660 * Sets the list cache `key` to `value`.
661 *
662 * @private
663 * @name set
664 * @memberOf ListCache
665 * @param {string} key The key of the value to set.
666 * @param {*} value The value to set.
667 * @returns {Object} Returns the list cache instance.
668 */
669function listCacheSet(key, value) {
670 var data = this.__data__,
671 index = assocIndexOf(data, key);
672
673 if (index < 0) {
674 ++this.size;
675 data.push([key, value]);
676 } else {
677 data[index][1] = value;
678 }
679 return this;
680}
681
682// Add methods to `ListCache`.
683ListCache.prototype.clear = listCacheClear;
684ListCache.prototype['delete'] = listCacheDelete;
685ListCache.prototype.get = listCacheGet;
686ListCache.prototype.has = listCacheHas;
687ListCache.prototype.set = listCacheSet;
688
689/**
690 * Creates a map cache object to store key-value pairs.
691 *
692 * @private
693 * @constructor
694 * @param {Array} [entries] The key-value pairs to cache.
695 */
696function MapCache(entries) {
697 var index = -1,
698 length = entries == null ? 0 : entries.length;
699
700 this.clear();
701 while (++index < length) {
702 var entry = entries[index];
703 this.set(entry[0], entry[1]);
704 }
705}
706
707/**
708 * Removes all key-value entries from the map.
709 *
710 * @private
711 * @name clear
712 * @memberOf MapCache
713 */
714function mapCacheClear() {
715 this.size = 0;
716 this.__data__ = {
717 'hash': new Hash,
718 'map': new (Map || ListCache),
719 'string': new Hash
720 };
721}
722
723/**
724 * Removes `key` and its value from the map.
725 *
726 * @private
727 * @name delete
728 * @memberOf MapCache
729 * @param {string} key The key of the value to remove.
730 * @returns {boolean} Returns `true` if the entry was removed, else `false`.
731 */
732function mapCacheDelete(key) {
733 var result = getMapData(this, key)['delete'](key);
734 this.size -= result ? 1 : 0;
735 return result;
736}
737
738/**
739 * Gets the map value for `key`.
740 *
741 * @private
742 * @name get
743 * @memberOf MapCache
744 * @param {string} key The key of the value to get.
745 * @returns {*} Returns the entry value.
746 */
747function mapCacheGet(key) {
748 return getMapData(this, key).get(key);
749}
750
751/**
752 * Checks if a map value for `key` exists.
753 *
754 * @private
755 * @name has
756 * @memberOf MapCache
757 * @param {string} key The key of the entry to check.
758 * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
759 */
760function mapCacheHas(key) {
761 return getMapData(this, key).has(key);
762}
763
764/**
765 * Sets the map `key` to `value`.
766 *
767 * @private
768 * @name set
769 * @memberOf MapCache
770 * @param {string} key The key of the value to set.
771 * @param {*} value The value to set.
772 * @returns {Object} Returns the map cache instance.
773 */
774function mapCacheSet(key, value) {
775 var data = getMapData(this, key),
776 size = data.size;
777
778 data.set(key, value);
779 this.size += data.size == size ? 0 : 1;
780 return this;
781}
782
783// Add methods to `MapCache`.
784MapCache.prototype.clear = mapCacheClear;
785MapCache.prototype['delete'] = mapCacheDelete;
786MapCache.prototype.get = mapCacheGet;
787MapCache.prototype.has = mapCacheHas;
788MapCache.prototype.set = mapCacheSet;
789
790/**
791 *
792 * Creates an array cache object to store unique values.
793 *
794 * @private
795 * @constructor
796 * @param {Array} [values] The values to cache.
797 */
798function SetCache(values) {
799 var index = -1,
800 length = values == null ? 0 : values.length;
801
802 this.__data__ = new MapCache;
803 while (++index < length) {
804 this.add(values[index]);
805 }
806}
807
808/**
809 * Adds `value` to the array cache.
810 *
811 * @private
812 * @name add
813 * @memberOf SetCache
814 * @alias push
815 * @param {*} value The value to cache.
816 * @returns {Object} Returns the cache instance.
817 */
818function setCacheAdd(value) {
819 this.__data__.set(value, HASH_UNDEFINED);
820 return this;
821}
822
823/**
824 * Checks if `value` is in the array cache.
825 *
826 * @private
827 * @name has
828 * @memberOf SetCache
829 * @param {*} value The value to search for.
830 * @returns {number} Returns `true` if `value` is found, else `false`.
831 */
832function setCacheHas(value) {
833 return this.__data__.has(value);
834}
835
836// Add methods to `SetCache`.
837SetCache.prototype.add = SetCache.prototype.push = setCacheAdd;
838SetCache.prototype.has = setCacheHas;
839
840/**
841 * Creates a stack cache object to store key-value pairs.
842 *
843 * @private
844 * @constructor
845 * @param {Array} [entries] The key-value pairs to cache.
846 */
847function Stack(entries) {
848 var data = this.__data__ = new ListCache(entries);
849 this.size = data.size;
850}
851
852/**
853 * Removes all key-value entries from the stack.
854 *
855 * @private
856 * @name clear
857 * @memberOf Stack
858 */
859function stackClear() {
860 this.__data__ = new ListCache;
861 this.size = 0;
862}
863
864/**
865 * Removes `key` and its value from the stack.
866 *
867 * @private
868 * @name delete
869 * @memberOf Stack
870 * @param {string} key The key of the value to remove.
871 * @returns {boolean} Returns `true` if the entry was removed, else `false`.
872 */
873function stackDelete(key) {
874 var data = this.__data__,
875 result = data['delete'](key);
876
877 this.size = data.size;
878 return result;
879}
880
881/**
882 * Gets the stack value for `key`.
883 *
884 * @private
885 * @name get
886 * @memberOf Stack
887 * @param {string} key The key of the value to get.
888 * @returns {*} Returns the entry value.
889 */
890function stackGet(key) {
891 return this.__data__.get(key);
892}
893
894/**
895 * Checks if a stack value for `key` exists.
896 *
897 * @private
898 * @name has
899 * @memberOf Stack
900 * @param {string} key The key of the entry to check.
901 * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
902 */
903function stackHas(key) {
904 return this.__data__.has(key);
905}
906
907/**
908 * Sets the stack `key` to `value`.
909 *
910 * @private
911 * @name set
912 * @memberOf Stack
913 * @param {string} key The key of the value to set.
914 * @param {*} value The value to set.
915 * @returns {Object} Returns the stack cache instance.
916 */
917function stackSet(key, value) {
918 var data = this.__data__;
919 if (data instanceof ListCache) {
920 var pairs = data.__data__;
921 if (!Map || (pairs.length < LARGE_ARRAY_SIZE - 1)) {
922 pairs.push([key, value]);
923 this.size = ++data.size;
924 return this;
925 }
926 data = this.__data__ = new MapCache(pairs);
927 }
928 data.set(key, value);
929 this.size = data.size;
930 return this;
931}
932
933// Add methods to `Stack`.
934Stack.prototype.clear = stackClear;
935Stack.prototype['delete'] = stackDelete;
936Stack.prototype.get = stackGet;
937Stack.prototype.has = stackHas;
938Stack.prototype.set = stackSet;
939
940/**
941 * Creates an array of the enumerable property names of the array-like `value`.
942 *
943 * @private
944 * @param {*} value The value to query.
945 * @param {boolean} inherited Specify returning inherited property names.
946 * @returns {Array} Returns the array of property names.
947 */
948function arrayLikeKeys(value, inherited) {
949 var isArr = isArray(value),
950 isArg = !isArr && isArguments(value),
951 isBuff = !isArr && !isArg && isBuffer(value),
952 isType = !isArr && !isArg && !isBuff && isTypedArray(value),
953 skipIndexes = isArr || isArg || isBuff || isType,
954 result = skipIndexes ? baseTimes(value.length, String) : [],
955 length = result.length;
956
957 for (var key in value) {
958 if ((inherited || hasOwnProperty.call(value, key)) &&
959 !(skipIndexes && (
960 // Safari 9 has enumerable `arguments.length` in strict mode.
961 key == 'length' ||
962 // Node.js 0.10 has enumerable non-index properties on buffers.
963 (isBuff && (key == 'offset' || key == 'parent')) ||
964 // PhantomJS 2 has enumerable non-index properties on typed arrays.
965 (isType && (key == 'buffer' || key == 'byteLength' || key == 'byteOffset')) ||
966 // Skip index properties.
967 isIndex(key, length)
968 ))) {
969 result.push(key);
970 }
971 }
972 return result;
973}
974
975/**
976 * Gets the index at which the `key` is found in `array` of key-value pairs.
977 *
978 * @private
979 * @param {Array} array The array to inspect.
980 * @param {*} key The key to search for.
981 * @returns {number} Returns the index of the matched value, else `-1`.
982 */
983function assocIndexOf(array, key) {
984 var length = array.length;
985 while (length--) {
986 if (eq(array[length][0], key)) {
987 return length;
988 }
989 }
990 return -1;
991}
992
993/**
994 * The base implementation of `getAllKeys` and `getAllKeysIn` which uses
995 * `keysFunc` and `symbolsFunc` to get the enumerable property names and
996 * symbols of `object`.
997 *
998 * @private
999 * @param {Object} object The object to query.
1000 * @param {Function} keysFunc The function to get the keys of `object`.
1001 * @param {Function} symbolsFunc The function to get the symbols of `object`.
1002 * @returns {Array} Returns the array of property names and symbols.
1003 */
1004function baseGetAllKeys(object, keysFunc, symbolsFunc) {
1005 var result = keysFunc(object);
1006 return isArray(object) ? result : arrayPush(result, symbolsFunc(object));
1007}
1008
1009/**
1010 * The base implementation of `getTag` without fallbacks for buggy environments.
1011 *
1012 * @private
1013 * @param {*} value The value to query.
1014 * @returns {string} Returns the `toStringTag`.
1015 */
1016function baseGetTag(value) {
1017 if (value == null) {
1018 return value === undefined ? undefinedTag : nullTag;
1019 }
1020 return (symToStringTag && symToStringTag in Object(value))
1021 ? getRawTag(value)
1022 : objectToString(value);
1023}
1024
1025/**
1026 * The base implementation of `_.isArguments`.
1027 *
1028 * @private
1029 * @param {*} value The value to check.
1030 * @returns {boolean} Returns `true` if `value` is an `arguments` object,
1031 */
1032function baseIsArguments(value) {
1033 return isObjectLike(value) && baseGetTag(value) == argsTag;
1034}
1035
1036/**
1037 * The base implementation of `_.isEqual` which supports partial comparisons
1038 * and tracks traversed objects.
1039 *
1040 * @private
1041 * @param {*} value The value to compare.
1042 * @param {*} other The other value to compare.
1043 * @param {boolean} bitmask The bitmask flags.
1044 * 1 - Unordered comparison
1045 * 2 - Partial comparison
1046 * @param {Function} [customizer] The function to customize comparisons.
1047 * @param {Object} [stack] Tracks traversed `value` and `other` objects.
1048 * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
1049 */
1050function baseIsEqual(value, other, bitmask, customizer, stack) {
1051 if (value === other) {
1052 return true;
1053 }
1054 if (value == null || other == null || (!isObjectLike(value) && !isObjectLike(other))) {
1055 return value !== value && other !== other;
1056 }
1057 return baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack);
1058}
1059
1060/**
1061 * A specialized version of `baseIsEqual` for arrays and objects which performs
1062 * deep comparisons and tracks traversed objects enabling objects with circular
1063 * references to be compared.
1064 *
1065 * @private
1066 * @param {Object} object The object to compare.
1067 * @param {Object} other The other object to compare.
1068 * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
1069 * @param {Function} customizer The function to customize comparisons.
1070 * @param {Function} equalFunc The function to determine equivalents of values.
1071 * @param {Object} [stack] Tracks traversed `object` and `other` objects.
1072 * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
1073 */
1074function baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) {
1075 var objIsArr = isArray(object),
1076 othIsArr = isArray(other),
1077 objTag = objIsArr ? arrayTag : getTag(object),
1078 othTag = othIsArr ? arrayTag : getTag(other);
1079
1080 objTag = objTag == argsTag ? objectTag : objTag;
1081 othTag = othTag == argsTag ? objectTag : othTag;
1082
1083 var objIsObj = objTag == objectTag,
1084 othIsObj = othTag == objectTag,
1085 isSameTag = objTag == othTag;
1086
1087 if (isSameTag && isBuffer(object)) {
1088 if (!isBuffer(other)) {
1089 return false;
1090 }
1091 objIsArr = true;
1092 objIsObj = false;
1093 }
1094 if (isSameTag && !objIsObj) {
1095 stack || (stack = new Stack);
1096 return (objIsArr || isTypedArray(object))
1097 ? equalArrays(object, other, bitmask, customizer, equalFunc, stack)
1098 : equalByTag(object, other, objTag, bitmask, customizer, equalFunc, stack);
1099 }
1100 if (!(bitmask & COMPARE_PARTIAL_FLAG)) {
1101 var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'),
1102 othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__');
1103
1104 if (objIsWrapped || othIsWrapped) {
1105 var objUnwrapped = objIsWrapped ? object.value() : object,
1106 othUnwrapped = othIsWrapped ? other.value() : other;
1107
1108 stack || (stack = new Stack);
1109 return equalFunc(objUnwrapped, othUnwrapped, bitmask, customizer, stack);
1110 }
1111 }
1112 if (!isSameTag) {
1113 return false;
1114 }
1115 stack || (stack = new Stack);
1116 return equalObjects(object, other, bitmask, customizer, equalFunc, stack);
1117}
1118
1119/**
1120 * The base implementation of `_.isNative` without bad shim checks.
1121 *
1122 * @private
1123 * @param {*} value The value to check.
1124 * @returns {boolean} Returns `true` if `value` is a native function,
1125 * else `false`.
1126 */
1127function baseIsNative(value) {
1128 if (!isObject(value) || isMasked(value)) {
1129 return false;
1130 }
1131 var pattern = isFunction(value) ? reIsNative : reIsHostCtor;
1132 return pattern.test(toSource(value));
1133}
1134
1135/**
1136 * The base implementation of `_.isTypedArray` without Node.js optimizations.
1137 *
1138 * @private
1139 * @param {*} value The value to check.
1140 * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.
1141 */
1142function baseIsTypedArray(value) {
1143 return isObjectLike(value) &&
1144 isLength(value.length) && !!typedArrayTags[baseGetTag(value)];
1145}
1146
1147/**
1148 * The base implementation of `_.keys` which doesn't treat sparse arrays as dense.
1149 *
1150 * @private
1151 * @param {Object} object The object to query.
1152 * @returns {Array} Returns the array of property names.
1153 */
1154function baseKeys(object) {
1155 if (!isPrototype(object)) {
1156 return nativeKeys(object);
1157 }
1158 var result = [];
1159 for (var key in Object(object)) {
1160 if (hasOwnProperty.call(object, key) && key != 'constructor') {
1161 result.push(key);
1162 }
1163 }
1164 return result;
1165}
1166
1167/**
1168 * A specialized version of `baseIsEqualDeep` for arrays with support for
1169 * partial deep comparisons.
1170 *
1171 * @private
1172 * @param {Array} array The array to compare.
1173 * @param {Array} other The other array to compare.
1174 * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
1175 * @param {Function} customizer The function to customize comparisons.
1176 * @param {Function} equalFunc The function to determine equivalents of values.
1177 * @param {Object} stack Tracks traversed `array` and `other` objects.
1178 * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`.
1179 */
1180function equalArrays(array, other, bitmask, customizer, equalFunc, stack) {
1181 var isPartial = bitmask & COMPARE_PARTIAL_FLAG,
1182 arrLength = array.length,
1183 othLength = other.length;
1184
1185 if (arrLength != othLength && !(isPartial && othLength > arrLength)) {
1186 return false;
1187 }
1188 // Assume cyclic values are equal.
1189 var stacked = stack.get(array);
1190 if (stacked && stack.get(other)) {
1191 return stacked == other;
1192 }
1193 var index = -1,
1194 result = true,
1195 seen = (bitmask & COMPARE_UNORDERED_FLAG) ? new SetCache : undefined;
1196
1197 stack.set(array, other);
1198 stack.set(other, array);
1199
1200 // Ignore non-index properties.
1201 while (++index < arrLength) {
1202 var arrValue = array[index],
1203 othValue = other[index];
1204
1205 if (customizer) {
1206 var compared = isPartial
1207 ? customizer(othValue, arrValue, index, other, array, stack)
1208 : customizer(arrValue, othValue, index, array, other, stack);
1209 }
1210 if (compared !== undefined) {
1211 if (compared) {
1212 continue;
1213 }
1214 result = false;
1215 break;
1216 }
1217 // Recursively compare arrays (susceptible to call stack limits).
1218 if (seen) {
1219 if (!arraySome(other, function(othValue, othIndex) {
1220 if (!cacheHas(seen, othIndex) &&
1221 (arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack))) {
1222 return seen.push(othIndex);
1223 }
1224 })) {
1225 result = false;
1226 break;
1227 }
1228 } else if (!(
1229 arrValue === othValue ||
1230 equalFunc(arrValue, othValue, bitmask, customizer, stack)
1231 )) {
1232 result = false;
1233 break;
1234 }
1235 }
1236 stack['delete'](array);
1237 stack['delete'](other);
1238 return result;
1239}
1240
1241/**
1242 * A specialized version of `baseIsEqualDeep` for comparing objects of
1243 * the same `toStringTag`.
1244 *
1245 * **Note:** This function only supports comparing values with tags of
1246 * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.
1247 *
1248 * @private
1249 * @param {Object} object The object to compare.
1250 * @param {Object} other The other object to compare.
1251 * @param {string} tag The `toStringTag` of the objects to compare.
1252 * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
1253 * @param {Function} customizer The function to customize comparisons.
1254 * @param {Function} equalFunc The function to determine equivalents of values.
1255 * @param {Object} stack Tracks traversed `object` and `other` objects.
1256 * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
1257 */
1258function equalByTag(object, other, tag, bitmask, customizer, equalFunc, stack) {
1259 switch (tag) {
1260 case dataViewTag:
1261 if ((object.byteLength != other.byteLength) ||
1262 (object.byteOffset != other.byteOffset)) {
1263 return false;
1264 }
1265 object = object.buffer;
1266 other = other.buffer;
1267
1268 case arrayBufferTag:
1269 if ((object.byteLength != other.byteLength) ||
1270 !equalFunc(new Uint8Array(object), new Uint8Array(other))) {
1271 return false;
1272 }
1273 return true;
1274
1275 case boolTag:
1276 case dateTag:
1277 case numberTag:
1278 // Coerce booleans to `1` or `0` and dates to milliseconds.
1279 // Invalid dates are coerced to `NaN`.
1280 return eq(+object, +other);
1281
1282 case errorTag:
1283 return object.name == other.name && object.message == other.message;
1284
1285 case regexpTag:
1286 case stringTag:
1287 // Coerce regexes to strings and treat strings, primitives and objects,
1288 // as equal. See http://www.ecma-international.org/ecma-262/7.0/#sec-regexp.prototype.tostring
1289 // for more details.
1290 return object == (other + '');
1291
1292 case mapTag:
1293 var convert = mapToArray;
1294
1295 case setTag:
1296 var isPartial = bitmask & COMPARE_PARTIAL_FLAG;
1297 convert || (convert = setToArray);
1298
1299 if (object.size != other.size && !isPartial) {
1300 return false;
1301 }
1302 // Assume cyclic values are equal.
1303 var stacked = stack.get(object);
1304 if (stacked) {
1305 return stacked == other;
1306 }
1307 bitmask |= COMPARE_UNORDERED_FLAG;
1308
1309 // Recursively compare objects (susceptible to call stack limits).
1310 stack.set(object, other);
1311 var result = equalArrays(convert(object), convert(other), bitmask, customizer, equalFunc, stack);
1312 stack['delete'](object);
1313 return result;
1314
1315 case symbolTag:
1316 if (symbolValueOf) {
1317 return symbolValueOf.call(object) == symbolValueOf.call(other);
1318 }
1319 }
1320 return false;
1321}
1322
1323/**
1324 * A specialized version of `baseIsEqualDeep` for objects with support for
1325 * partial deep comparisons.
1326 *
1327 * @private
1328 * @param {Object} object The object to compare.
1329 * @param {Object} other The other object to compare.
1330 * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
1331 * @param {Function} customizer The function to customize comparisons.
1332 * @param {Function} equalFunc The function to determine equivalents of values.
1333 * @param {Object} stack Tracks traversed `object` and `other` objects.
1334 * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
1335 */
1336function equalObjects(object, other, bitmask, customizer, equalFunc, stack) {
1337 var isPartial = bitmask & COMPARE_PARTIAL_FLAG,
1338 objProps = getAllKeys(object),
1339 objLength = objProps.length,
1340 othProps = getAllKeys(other),
1341 othLength = othProps.length;
1342
1343 if (objLength != othLength && !isPartial) {
1344 return false;
1345 }
1346 var index = objLength;
1347 while (index--) {
1348 var key = objProps[index];
1349 if (!(isPartial ? key in other : hasOwnProperty.call(other, key))) {
1350 return false;
1351 }
1352 }
1353 // Assume cyclic values are equal.
1354 var stacked = stack.get(object);
1355 if (stacked && stack.get(other)) {
1356 return stacked == other;
1357 }
1358 var result = true;
1359 stack.set(object, other);
1360 stack.set(other, object);
1361
1362 var skipCtor = isPartial;
1363 while (++index < objLength) {
1364 key = objProps[index];
1365 var objValue = object[key],
1366 othValue = other[key];
1367
1368 if (customizer) {
1369 var compared = isPartial
1370 ? customizer(othValue, objValue, key, other, object, stack)
1371 : customizer(objValue, othValue, key, object, other, stack);
1372 }
1373 // Recursively compare objects (susceptible to call stack limits).
1374 if (!(compared === undefined
1375 ? (objValue === othValue || equalFunc(objValue, othValue, bitmask, customizer, stack))
1376 : compared
1377 )) {
1378 result = false;
1379 break;
1380 }
1381 skipCtor || (skipCtor = key == 'constructor');
1382 }
1383 if (result && !skipCtor) {
1384 var objCtor = object.constructor,
1385 othCtor = other.constructor;
1386
1387 // Non `Object` object instances with different constructors are not equal.
1388 if (objCtor != othCtor &&
1389 ('constructor' in object && 'constructor' in other) &&
1390 !(typeof objCtor == 'function' && objCtor instanceof objCtor &&
1391 typeof othCtor == 'function' && othCtor instanceof othCtor)) {
1392 result = false;
1393 }
1394 }
1395 stack['delete'](object);
1396 stack['delete'](other);
1397 return result;
1398}
1399
1400/**
1401 * Creates an array of own enumerable property names and symbols of `object`.
1402 *
1403 * @private
1404 * @param {Object} object The object to query.
1405 * @returns {Array} Returns the array of property names and symbols.
1406 */
1407function getAllKeys(object) {
1408 return baseGetAllKeys(object, keys, getSymbols);
1409}
1410
1411/**
1412 * Gets the data for `map`.
1413 *
1414 * @private
1415 * @param {Object} map The map to query.
1416 * @param {string} key The reference key.
1417 * @returns {*} Returns the map data.
1418 */
1419function getMapData(map, key) {
1420 var data = map.__data__;
1421 return isKeyable(key)
1422 ? data[typeof key == 'string' ? 'string' : 'hash']
1423 : data.map;
1424}
1425
1426/**
1427 * Gets the native function at `key` of `object`.
1428 *
1429 * @private
1430 * @param {Object} object The object to query.
1431 * @param {string} key The key of the method to get.
1432 * @returns {*} Returns the function if it's native, else `undefined`.
1433 */
1434function getNative(object, key) {
1435 var value = getValue(object, key);
1436 return baseIsNative(value) ? value : undefined;
1437}
1438
1439/**
1440 * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values.
1441 *
1442 * @private
1443 * @param {*} value The value to query.
1444 * @returns {string} Returns the raw `toStringTag`.
1445 */
1446function getRawTag(value) {
1447 var isOwn = hasOwnProperty.call(value, symToStringTag),
1448 tag = value[symToStringTag];
1449
1450 try {
1451 value[symToStringTag] = undefined;
1452 var unmasked = true;
1453 } catch (e) {}
1454
1455 var result = nativeObjectToString.call(value);
1456 if (unmasked) {
1457 if (isOwn) {
1458 value[symToStringTag] = tag;
1459 } else {
1460 delete value[symToStringTag];
1461 }
1462 }
1463 return result;
1464}
1465
1466/**
1467 * Creates an array of the own enumerable symbols of `object`.
1468 *
1469 * @private
1470 * @param {Object} object The object to query.
1471 * @returns {Array} Returns the array of symbols.
1472 */
1473var getSymbols = !nativeGetSymbols ? stubArray : function(object) {
1474 if (object == null) {
1475 return [];
1476 }
1477 object = Object(object);
1478 return arrayFilter(nativeGetSymbols(object), function(symbol) {
1479 return propertyIsEnumerable.call(object, symbol);
1480 });
1481};
1482
1483/**
1484 * Gets the `toStringTag` of `value`.
1485 *
1486 * @private
1487 * @param {*} value The value to query.
1488 * @returns {string} Returns the `toStringTag`.
1489 */
1490var getTag = baseGetTag;
1491
1492// Fallback for data views, maps, sets, and weak maps in IE 11 and promises in Node.js < 6.
1493if ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag) ||
1494 (Map && getTag(new Map) != mapTag) ||
1495 (Promise && getTag(Promise.resolve()) != promiseTag) ||
1496 (Set && getTag(new Set) != setTag) ||
1497 (WeakMap && getTag(new WeakMap) != weakMapTag)) {
1498 getTag = function(value) {
1499 var result = baseGetTag(value),
1500 Ctor = result == objectTag ? value.constructor : undefined,
1501 ctorString = Ctor ? toSource(Ctor) : '';
1502
1503 if (ctorString) {
1504 switch (ctorString) {
1505 case dataViewCtorString: return dataViewTag;
1506 case mapCtorString: return mapTag;
1507 case promiseCtorString: return promiseTag;
1508 case setCtorString: return setTag;
1509 case weakMapCtorString: return weakMapTag;
1510 }
1511 }
1512 return result;
1513 };
1514}
1515
1516/**
1517 * Checks if `value` is a valid array-like index.
1518 *
1519 * @private
1520 * @param {*} value The value to check.
1521 * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.
1522 * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.
1523 */
1524function isIndex(value, length) {
1525 length = length == null ? MAX_SAFE_INTEGER : length;
1526 return !!length &&
1527 (typeof value == 'number' || reIsUint.test(value)) &&
1528 (value > -1 && value % 1 == 0 && value < length);
1529}
1530
1531/**
1532 * Checks if `value` is suitable for use as unique object key.
1533 *
1534 * @private
1535 * @param {*} value The value to check.
1536 * @returns {boolean} Returns `true` if `value` is suitable, else `false`.
1537 */
1538function isKeyable(value) {
1539 var type = typeof value;
1540 return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean')
1541 ? (value !== '__proto__')
1542 : (value === null);
1543}
1544
1545/**
1546 * Checks if `func` has its source masked.
1547 *
1548 * @private
1549 * @param {Function} func The function to check.
1550 * @returns {boolean} Returns `true` if `func` is masked, else `false`.
1551 */
1552function isMasked(func) {
1553 return !!maskSrcKey && (maskSrcKey in func);
1554}
1555
1556/**
1557 * Checks if `value` is likely a prototype object.
1558 *
1559 * @private
1560 * @param {*} value The value to check.
1561 * @returns {boolean} Returns `true` if `value` is a prototype, else `false`.
1562 */
1563function isPrototype(value) {
1564 var Ctor = value && value.constructor,
1565 proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto;
1566
1567 return value === proto;
1568}
1569
1570/**
1571 * Converts `value` to a string using `Object.prototype.toString`.
1572 *
1573 * @private
1574 * @param {*} value The value to convert.
1575 * @returns {string} Returns the converted string.
1576 */
1577function objectToString(value) {
1578 return nativeObjectToString.call(value);
1579}
1580
1581/**
1582 * Converts `func` to its source code.
1583 *
1584 * @private
1585 * @param {Function} func The function to convert.
1586 * @returns {string} Returns the source code.
1587 */
1588function toSource(func) {
1589 if (func != null) {
1590 try {
1591 return funcToString.call(func);
1592 } catch (e) {}
1593 try {
1594 return (func + '');
1595 } catch (e) {}
1596 }
1597 return '';
1598}
1599
1600/**
1601 * Performs a
1602 * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
1603 * comparison between two values to determine if they are equivalent.
1604 *
1605 * @static
1606 * @memberOf _
1607 * @since 4.0.0
1608 * @category Lang
1609 * @param {*} value The value to compare.
1610 * @param {*} other The other value to compare.
1611 * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
1612 * @example
1613 *
1614 * var object = { 'a': 1 };
1615 * var other = { 'a': 1 };
1616 *
1617 * _.eq(object, object);
1618 * // => true
1619 *
1620 * _.eq(object, other);
1621 * // => false
1622 *
1623 * _.eq('a', 'a');
1624 * // => true
1625 *
1626 * _.eq('a', Object('a'));
1627 * // => false
1628 *
1629 * _.eq(NaN, NaN);
1630 * // => true
1631 */
1632function eq(value, other) {
1633 return value === other || (value !== value && other !== other);
1634}
1635
1636/**
1637 * Checks if `value` is likely an `arguments` object.
1638 *
1639 * @static
1640 * @memberOf _
1641 * @since 0.1.0
1642 * @category Lang
1643 * @param {*} value The value to check.
1644 * @returns {boolean} Returns `true` if `value` is an `arguments` object,
1645 * else `false`.
1646 * @example
1647 *
1648 * _.isArguments(function() { return arguments; }());
1649 * // => true
1650 *
1651 * _.isArguments([1, 2, 3]);
1652 * // => false
1653 */
1654var isArguments = baseIsArguments(function() { return arguments; }()) ? baseIsArguments : function(value) {
1655 return isObjectLike(value) && hasOwnProperty.call(value, 'callee') &&
1656 !propertyIsEnumerable.call(value, 'callee');
1657};
1658
1659/**
1660 * Checks if `value` is classified as an `Array` object.
1661 *
1662 * @static
1663 * @memberOf _
1664 * @since 0.1.0
1665 * @category Lang
1666 * @param {*} value The value to check.
1667 * @returns {boolean} Returns `true` if `value` is an array, else `false`.
1668 * @example
1669 *
1670 * _.isArray([1, 2, 3]);
1671 * // => true
1672 *
1673 * _.isArray(document.body.children);
1674 * // => false
1675 *
1676 * _.isArray('abc');
1677 * // => false
1678 *
1679 * _.isArray(_.noop);
1680 * // => false
1681 */
1682var isArray = Array.isArray;
1683
1684/**
1685 * Checks if `value` is array-like. A value is considered array-like if it's
1686 * not a function and has a `value.length` that's an integer greater than or
1687 * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.
1688 *
1689 * @static
1690 * @memberOf _
1691 * @since 4.0.0
1692 * @category Lang
1693 * @param {*} value The value to check.
1694 * @returns {boolean} Returns `true` if `value` is array-like, else `false`.
1695 * @example
1696 *
1697 * _.isArrayLike([1, 2, 3]);
1698 * // => true
1699 *
1700 * _.isArrayLike(document.body.children);
1701 * // => true
1702 *
1703 * _.isArrayLike('abc');
1704 * // => true
1705 *
1706 * _.isArrayLike(_.noop);
1707 * // => false
1708 */
1709function isArrayLike(value) {
1710 return value != null && isLength(value.length) && !isFunction(value);
1711}
1712
1713/**
1714 * Checks if `value` is a buffer.
1715 *
1716 * @static
1717 * @memberOf _
1718 * @since 4.3.0
1719 * @category Lang
1720 * @param {*} value The value to check.
1721 * @returns {boolean} Returns `true` if `value` is a buffer, else `false`.
1722 * @example
1723 *
1724 * _.isBuffer(new Buffer(2));
1725 * // => true
1726 *
1727 * _.isBuffer(new Uint8Array(2));
1728 * // => false
1729 */
1730var isBuffer = nativeIsBuffer || stubFalse;
1731
1732/**
1733 * Performs a deep comparison between two values to determine if they are
1734 * equivalent.
1735 *
1736 * **Note:** This method supports comparing arrays, array buffers, booleans,
1737 * date objects, error objects, maps, numbers, `Object` objects, regexes,
1738 * sets, strings, symbols, and typed arrays. `Object` objects are compared
1739 * by their own, not inherited, enumerable properties. Functions and DOM
1740 * nodes are compared by strict equality, i.e. `===`.
1741 *
1742 * @static
1743 * @memberOf _
1744 * @since 0.1.0
1745 * @category Lang
1746 * @param {*} value The value to compare.
1747 * @param {*} other The other value to compare.
1748 * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
1749 * @example
1750 *
1751 * var object = { 'a': 1 };
1752 * var other = { 'a': 1 };
1753 *
1754 * _.isEqual(object, other);
1755 * // => true
1756 *
1757 * object === other;
1758 * // => false
1759 */
1760function isEqual(value, other) {
1761 return baseIsEqual(value, other);
1762}
1763
1764/**
1765 * Checks if `value` is classified as a `Function` object.
1766 *
1767 * @static
1768 * @memberOf _
1769 * @since 0.1.0
1770 * @category Lang
1771 * @param {*} value The value to check.
1772 * @returns {boolean} Returns `true` if `value` is a function, else `false`.
1773 * @example
1774 *
1775 * _.isFunction(_);
1776 * // => true
1777 *
1778 * _.isFunction(/abc/);
1779 * // => false
1780 */
1781function isFunction(value) {
1782 if (!isObject(value)) {
1783 return false;
1784 }
1785 // The use of `Object#toString` avoids issues with the `typeof` operator
1786 // in Safari 9 which returns 'object' for typed arrays and other constructors.
1787 var tag = baseGetTag(value);
1788 return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag;
1789}
1790
1791/**
1792 * Checks if `value` is a valid array-like length.
1793 *
1794 * **Note:** This method is loosely based on
1795 * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).
1796 *
1797 * @static
1798 * @memberOf _
1799 * @since 4.0.0
1800 * @category Lang
1801 * @param {*} value The value to check.
1802 * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
1803 * @example
1804 *
1805 * _.isLength(3);
1806 * // => true
1807 *
1808 * _.isLength(Number.MIN_VALUE);
1809 * // => false
1810 *
1811 * _.isLength(Infinity);
1812 * // => false
1813 *
1814 * _.isLength('3');
1815 * // => false
1816 */
1817function isLength(value) {
1818 return typeof value == 'number' &&
1819 value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
1820}
1821
1822/**
1823 * Checks if `value` is the
1824 * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
1825 * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
1826 *
1827 * @static
1828 * @memberOf _
1829 * @since 0.1.0
1830 * @category Lang
1831 * @param {*} value The value to check.
1832 * @returns {boolean} Returns `true` if `value` is an object, else `false`.
1833 * @example
1834 *
1835 * _.isObject({});
1836 * // => true
1837 *
1838 * _.isObject([1, 2, 3]);
1839 * // => true
1840 *
1841 * _.isObject(_.noop);
1842 * // => true
1843 *
1844 * _.isObject(null);
1845 * // => false
1846 */
1847function isObject(value) {
1848 var type = typeof value;
1849 return value != null && (type == 'object' || type == 'function');
1850}
1851
1852/**
1853 * Checks if `value` is object-like. A value is object-like if it's not `null`
1854 * and has a `typeof` result of "object".
1855 *
1856 * @static
1857 * @memberOf _
1858 * @since 4.0.0
1859 * @category Lang
1860 * @param {*} value The value to check.
1861 * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
1862 * @example
1863 *
1864 * _.isObjectLike({});
1865 * // => true
1866 *
1867 * _.isObjectLike([1, 2, 3]);
1868 * // => true
1869 *
1870 * _.isObjectLike(_.noop);
1871 * // => false
1872 *
1873 * _.isObjectLike(null);
1874 * // => false
1875 */
1876function isObjectLike(value) {
1877 return value != null && typeof value == 'object';
1878}
1879
1880/**
1881 * Checks if `value` is classified as a typed array.
1882 *
1883 * @static
1884 * @memberOf _
1885 * @since 3.0.0
1886 * @category Lang
1887 * @param {*} value The value to check.
1888 * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.
1889 * @example
1890 *
1891 * _.isTypedArray(new Uint8Array);
1892 * // => true
1893 *
1894 * _.isTypedArray([]);
1895 * // => false
1896 */
1897var isTypedArray = nodeIsTypedArray ? baseUnary(nodeIsTypedArray) : baseIsTypedArray;
1898
1899/**
1900 * Creates an array of the own enumerable property names of `object`.
1901 *
1902 * **Note:** Non-object values are coerced to objects. See the
1903 * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)
1904 * for more details.
1905 *
1906 * @static
1907 * @since 0.1.0
1908 * @memberOf _
1909 * @category Object
1910 * @param {Object} object The object to query.
1911 * @returns {Array} Returns the array of property names.
1912 * @example
1913 *
1914 * function Foo() {
1915 * this.a = 1;
1916 * this.b = 2;
1917 * }
1918 *
1919 * Foo.prototype.c = 3;
1920 *
1921 * _.keys(new Foo);
1922 * // => ['a', 'b'] (iteration order is not guaranteed)
1923 *
1924 * _.keys('hi');
1925 * // => ['0', '1']
1926 */
1927function keys(object) {
1928 return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object);
1929}
1930
1931/**
1932 * This method returns a new empty array.
1933 *
1934 * @static
1935 * @memberOf _
1936 * @since 4.13.0
1937 * @category Util
1938 * @returns {Array} Returns the new empty array.
1939 * @example
1940 *
1941 * var arrays = _.times(2, _.stubArray);
1942 *
1943 * console.log(arrays);
1944 * // => [[], []]
1945 *
1946 * console.log(arrays[0] === arrays[1]);
1947 * // => false
1948 */
1949function stubArray() {
1950 return [];
1951}
1952
1953/**
1954 * This method returns `false`.
1955 *
1956 * @static
1957 * @memberOf _
1958 * @since 4.13.0
1959 * @category Util
1960 * @returns {boolean} Returns `false`.
1961 * @example
1962 *
1963 * _.times(2, _.stubFalse);
1964 * // => [false, false]
1965 */
1966function stubFalse() {
1967 return false;
1968}
1969
1970module.exports = isEqual;
1971
1972},{}],"a3Jd":[function(require,module,exports) {
1973"use strict";
1974
1975Object.defineProperty(exports, "__esModule", {
1976 value: true
1977});
1978exports.default = void 0;
1979
1980var _lodash = _interopRequireDefault(require("lodash.isequal"));
1981
1982function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
1983
1984function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
1985
1986/**
1987 * ***********************
1988 * PRIVATE STATIC METHODS:
1989 * ***********************
1990 */
1991var __defaultSolver = /:([^\/:]*)/g;
1992/**
1993 * This function compares two arrays (usually two paths for Baobab), and returns
1994 * true if they have the same length and equals elements in the same order.
1995 *
1996 * @param {array} a1 The first array.
1997 * @param {array} a2 The second array.
1998 * @return {boolean} True if the values are equals, false else.
1999 */
2000
2001function __compareArrays(a1, a2) {
2002 var l = a1.length;
2003
2004 if (!Array.isArray(a1) || !Array.isArray(a2) || l !== a2.length) {
2005 return false;
2006 }
2007
2008 for (var i = 0; i < l; i++) {
2009 if (a1[i] !== a2[i]) {
2010 return false;
2011 }
2012 }
2013
2014 return true;
2015}
2016/**
2017 * This function takes a well formed URL from any BaobabRouter instance's route,
2018 * with potentially dynamic and query attributes to resolve, and an object with
2019 * the related values, and returns the URL with the query, and with the values
2020 * inserted instead of the dynamics.
2021 *
2022 * Examples:
2023 * *********
2024 * > __resolveURL('a/b/c'); // same as __resolveURL('a/b/c', {});
2025 * > // 'a/b/c' (nothing to solve)
2026 *
2027 * > __resolveURL('a/:b/c/:d', { ':b': 'B', ':d': 'D' });
2028 * > // 'a/B/c/D'
2029 *
2030 * > __resolveURL('a/:b/:b', { ':b': 'B' });
2031 * > // 'a/B/B'
2032 *
2033 * > __resolveURL('a/:b/:c', { ':c': 'C', ':d': 'D' });
2034 * > // 'a/:b/C'
2035 *
2036 * > __resolveURL('a/:b/:c', { ':c': 'C', ':d': 'D' }, { e: 'E', f: 'F' });
2037 * > // 'a/:b/C?e=E&f=F'
2038 *
2039 * @param {string} url The URL to resolve.
2040 * @param {?object} dyn An optional object with the dynamic values to insert.
2041 * @param {?object} qry An optional object with the query values to insert.
2042 * @return {string} The resolved URL.
2043 */
2044
2045
2046function __resolveURL(url) {
2047 var dyn = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
2048 var qry = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
2049 var hash = url.split("/").map(function (s) {
2050 return dyn.hasOwnProperty(s) ? escape(dyn[s]) : s;
2051 }).join("/");
2052 var query = Object.keys(qry).filter(function (k) {
2053 return qry[k] !== null && qry[k] !== undefined;
2054 }).map(function (k) {
2055 return escape(k) + "=" + escape(qry[k]);
2056 }).join("&");
2057 return query ? hash + "?" + query : hash;
2058}
2059/**
2060 * This function builds a proper path from a route's path and its parents paths.
2061 *
2062 * Examples:
2063 * *********
2064 * > __concatenatePaths('a'); // '/a'
2065 * > __concatenatePaths('/a'); // '/a'
2066 * > __concatenatePaths('a', ''); // '/a'
2067 * > __concatenatePaths('', 'b'); // '/b'
2068 *
2069 * > __concatenatePaths('a', 'b'); // '/a/b'
2070 * > __concatenatePaths('a', '/b'); // '/a/b'
2071 * > __concatenatePaths('a/', '/b'); // '/a/b'
2072 * > __concatenatePaths('a/', 'b'); // '/a/b'
2073 * > __concatenatePaths('/a', '/b'); // '/a/b'
2074 *
2075 * @param {string+} paths the different paths to concatenate.
2076 * @return {string} The cleaned path.
2077 */
2078
2079
2080function __concatenatePaths() {
2081 for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
2082 args[_key] = arguments[_key];
2083 }
2084
2085 return ("/" + args.map(function (str) {
2086 return str || "";
2087 }).join("/")).replace(/\/+/g, "/").replace(/\/+$/g, "");
2088}
2089/**
2090 * This function will merge multiple objects into one. Each object will
2091 * overrides the previous ones. Also, this function will return an object with
2092 * two keys: "value" contains the new object, and "conflicts" is a flag
2093 * specifying wether some paths contain different values in different objects.
2094 *
2095 * Examples:
2096 * *********
2097 * > var a = { key: 'value' },
2098 * > b = __deepMerge(a);
2099 * > a === b; // false
2100 * > b.key; // 'value'
2101 *
2102 * > __deepMerge(
2103 * > { a: 1 },
2104 * > { b: 1 },
2105 * > { c: 1 }
2106 * > );
2107 * > // { a: 1, b: 1, c: 1 }
2108 *
2109 * > __deepMerge(
2110 * > { a: 1 },
2111 * > { a: 2 },
2112 * > { a: 3 }
2113 * > );
2114 * > // { a: 3 }
2115 *
2116 * @param {object*} objects The objects to merge.
2117 * @return {object} An object containing the merged object under the
2118 * key "value", and a flag specifying if some keys
2119 * where having different values in the different
2120 * arguments, under the key "conflicts".
2121 */
2122
2123
2124function __deepMerge() {
2125 var res;
2126 var merged;
2127 var conflicts = false;
2128
2129 for (var i = 0, l = arguments.length; i < l; i++) {
2130 var obj = arguments[i];
2131
2132 if (obj && _typeof(obj) === "object") {
2133 if (!res) {
2134 res = Array.isArray(obj) ? [] : {};
2135 }
2136
2137 for (var k in obj) {
2138 if (obj.hasOwnProperty(k)) {
2139 merged = __deepMerge(res[k], obj[k]);
2140 conflicts = conflicts || merged.conflicts;
2141 res[k] = merged.value;
2142 }
2143 }
2144 } else {
2145 if (res !== undefined && res !== obj) {
2146 conflicts = true;
2147 }
2148
2149 res = obj;
2150 }
2151 }
2152
2153 return {
2154 conflicts: conflicts,
2155 value: res
2156 };
2157}
2158/**
2159 * This function takes a route's hash (that might have some expression to solve,
2160 * such as /toto/:tutu/tata or so), and an actual hash. It will then compare
2161 * them to find if the hash does match.
2162 *
2163 * Examples:
2164 * *********
2165 * > __doesHashMatch('/a/b/c', '/a/b/c'); // returns true
2166 * > __doesHashMatch('/a/b/c', '/a/c/b'); // returns false
2167 *
2168 * > __doesHashMatch('/a/b', '/a/b/c'); // returns true
2169 * > __doesHashMatch('/a/:b/c', '/a/b/c'); // returns true
2170 * > __doesHashMatch('/a/:b', '/a/b/c'); // returns true
2171 *
2172 * > __doesHashMatch('/a/:b', '/a/b/c', /:([^\/:]*)/g); // returns true
2173 * > __doesHashMatch('/a/{b}', '/a/b/c', /\{([^\/\}]*)\}/g); // returns true
2174 * > __doesHashMatch('/a/:b', '/a/b/c', /\{([^\/\}]*)\}/g); // returns false
2175 *
2176 * @param {string} routeHash The route's hash.
2177 * @param {string} hash The current hash.
2178 * @param {?RegExp} solver The dynamic values solver. If not specified, the
2179 * default solver will be used instead.
2180 * @return {boolean} Returns true if the hash does match the path, and
2181 * false else.
2182 */
2183
2184
2185function __doesHashMatch(routeHash, hash, solver) {
2186 var routeArray = routeHash.split("/");
2187 var hashArray = hash.replace(/\?.*$/, "").split("/"); // Check lengths:
2188
2189 if (routeArray.length > hashArray.length) {
2190 return false;
2191 }
2192
2193 for (var i = 0, l = routeArray.length; i < l; i++) {
2194 var match = routeArray[i].match(solver || __defaultSolver);
2195
2196 if (!match && routeArray[i] !== hashArray[i] || match && !hashArray[i]) {
2197 return false;
2198 }
2199 }
2200
2201 return true;
2202}
2203/**
2204 * This function takes a route's state constraints (that might have some dynamic
2205 * values, such as ":tutu" or so), and the actual app state. It will then
2206 * compare them to find if the hash does match, and return an object with the
2207 * dynamic strings current values. It returns false if the state does not match.
2208 *
2209 * Scalars are compared with the "===" operator, but another test checks if both
2210 * values to treat them as the same value.
2211 *
2212 * The difference between the query and the dynamic values is that null dynamic
2213 * values are not allowed, while null query parameters are valid.
2214 *
2215 * @param {object} routeState The route's state constraints.
2216 * @param {object} hash The current state.
2217 * @param {array} dynamics The array of the dynamic values.
2218 * @param {array} query The array of the query values.
2219 * @return {?object} Returns an object with the dynamic values if the
2220 * state does match the constraints, and null else.
2221 */
2222
2223
2224function __doesStateMatch(routeState, state, dynamics, query) {
2225 var results = {};
2226
2227 function searchRoutes(val, i) {
2228 var localResults = __doesStateMatch(val, state[i], dynamics, query);
2229
2230 if (localResults) {
2231 results = __deepMerge(results, localResults);
2232 return true;
2233 }
2234 } // Arrays:
2235
2236
2237 if (Array.isArray(routeState)) {
2238 if (!Array.isArray(state) || routeState.length !== state.length) {
2239 return null;
2240 }
2241
2242 if (routeState.every(searchRoutes)) {
2243 return results;
2244 }
2245
2246 return null; // Objects:
2247 } else if (routeState && _typeof(routeState) === "object") {
2248 if (!state || _typeof(state) !== "object") {
2249 return null;
2250 }
2251
2252 for (var k in routeState) {
2253 if (routeState.hasOwnProperty(k)) {
2254 var localResults = __doesStateMatch(routeState[k], state[k], dynamics, query);
2255
2256 if (localResults) {
2257 results = __deepMerge(results, localResults).value;
2258 } else {
2259 return null;
2260 }
2261 }
2262 }
2263
2264 return results; // Dynamics:
2265 } else if (~(dynamics || []).indexOf(routeState) && state) {
2266 results[routeState] = state;
2267 return results; // Query:
2268 } else if (~(query || []).indexOf(routeState) && !~(dynamics || []).indexOf(routeState)) {
2269 results[routeState] = state;
2270 return results; // Null / undefined cases:
2271 } else if ((routeState === undefined || routeState === null) && (state === undefined || state === null)) {
2272 return results; // Other scalars:
2273 } else if (routeState === state) {
2274 return results;
2275 }
2276
2277 return null;
2278}
2279/**
2280 * This function will extract from a state constraints object and a list of
2281 * dynamic value names a list of paths, with the related values. The goal is to
2282 * transform state contraints object into baobab compliant paths for later
2283 * updates.
2284 *
2285 * @param {route} state The state constraints to extract the paths from.
2286 * @param {?array} dynamics The array of the dynamic values names (like ":toto"
2287 * for instance).
2288 * @param {?array} results The results array to push the newly found paths
2289 * into. Only used in the recursion.
2290 * @param {?array} path The current path to use as paths prefix. Only used
2291 * in the recursion.
2292 * @return {array} The array of every paths found, with the related
2293 * found values and a flag specifying wether the paths
2294 * are related to a dynamic value or not.
2295 */
2296
2297
2298function __extractPaths(state) {
2299 var dynamics = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
2300 var results = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];
2301 var path = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : [];
2302
2303 for (var i in state) {
2304 if (state.hasOwnProperty(i) && state[i] && _typeof(state[i]) === "object" && Object.keys(state[i]).length) {
2305 __extractPaths(state[i], dynamics, results, path.concat(i));
2306 } else {
2307 results.push({
2308 path: path.concat(i),
2309 value: state[i],
2310 dynamic: !!~dynamics.indexOf(state[i])
2311 });
2312 }
2313 }
2314
2315 return results;
2316}
2317/**
2318 * This function will build the routes tree, formed for BaobabRouter. It will do
2319 * the following things, and then execute recursively on the children routes:
2320 *
2321 * - Check default routes validity (must match a child's path)
2322 * - Retrieve for each route the list of related paths
2323 * - Detect sub-routes overriding a parent's state
2324 * - Detect dynamic patterns in routes
2325 *
2326 * The function identifies the tree's root when no baseState and no basePath are
2327 * given.
2328 *
2329 * @param {object} route The input route object.
2330 * @param {regexp} solver The solver to use.
2331 * @param {?object} baseTree The optional base state, ie the recursively
2332 * merged state of the route's ancestors.
2333 * @param {?object} baseQuery The optional base query, ie the recursively
2334 * merged query of the route's ancestors.
2335 * @param {?string} basePath The optional base path, ie the recursively
2336 * concatenated path of the route's ancestors.
2337 * @return {route} The well-formed route object.
2338 */
2339
2340
2341function __makeRoutes(route, solver, baseTree, baseQuery) {
2342 var basePath = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : "";
2343
2344 var _deepMerge = __deepMerge(baseTree || {}, route.state ? {
2345 state: route.state
2346 } : {}),
2347 value = _deepMerge.value,
2348 conflicts = _deepMerge.conflicts;
2349
2350 route.fullPath = __concatenatePaths(basePath, route.path);
2351 route.fullTree = value;
2352 route.overrides = conflicts;
2353 route.dynamics = route.fullPath.match(solver) || [];
2354 route.fullQuery = __deepMerge(baseQuery || {}, route.query || {}).value;
2355 route.fullQueryValues = [];
2356
2357 for (var k in route.fullQuery || {}) {
2358 if (route.fullQuery.hasOwnProperty(k)) {
2359 if (typeof route.fullQuery[k] === "string") {
2360 route.fullQuery[k] = {
2361 match: route.fullQuery[k]
2362 };
2363 }
2364
2365 route.fullQueryValues.push(route.fullQuery[k].match);
2366 }
2367 }
2368
2369 route.updates = __extractPaths(route.fullTree, route.dynamics.concat(route.fullQueryValues));
2370
2371 if (route.defaultRoute) {
2372 route.fullDefaultPath = __concatenatePaths(route.fullPath, route.defaultRoute);
2373 }
2374
2375 if (route.routes) {
2376 route.routes = route.routes.map(function (child) {
2377 return __makeRoutes(child, solver, route.fullTree, route.fullQuery, route.fullPath);
2378 });
2379 }
2380
2381 route.overrides = route.overrides || (route.routes || []).some(function (child) {
2382 return child.overrides;
2383 }); // Some root-specific verifications:
2384
2385 if (arguments.length <= 2) {
2386 // Check read-only paths:
2387 route.readOnly = (route.readOnly || []).map(function (path) {
2388 return ["state"].concat(path);
2389 }); // The root must have a default route:
2390
2391 if (!route.defaultRoute) {
2392 throw new Error("BaobabRouter.__makeRoutes: " + "The root must have a default route.");
2393 }
2394 } // Check that default route is valid:
2395
2396
2397 if (route.defaultRoute && !(route.routes || []).some(function (child) {
2398 return __doesHashMatch(child.path, route.defaultRoute);
2399 })) {
2400 throw new Error("BaobabRouter.__makeRoutes: " + 'The default route "' + route.defaultRoute + '" does not match any ' + "registered route.");
2401 }
2402
2403 if (!("path" in route) && !route.defaultRoute) {
2404 throw new Error("BaobabRouter.__makeRoutes: " + "A route must have either a path or a default route.");
2405 } // Each route must have some state restriction (except for the root):
2406
2407
2408 if (arguments.length > 2 && !route.updates.length) {
2409 throw new Error("BaobabRouter.__makeRoutes: " + "Each route should have some state restrictions.");
2410 }
2411
2412 return route;
2413}
2414/**
2415 * The baobab-router constructor. In its current state, the baobab-router does
2416 * not expose anything to its public API.
2417 *
2418 * Recognized settings:
2419 * ********************
2420 * - {?RegExp} solver A custom solver to identify dynamic values in paths.
2421 *
2422 * @param {Baobab} baobab The Baobab instance to connect the router to.
2423 * @param {Object} routes The routes tree. It must have a defaultRoute string
2424 * and a routes array.
2425 * @param {?Object} settings An optional object of settings. The list of
2426 * recognized settings is described up here.
2427 */
2428
2429
2430var BaobabRouter = function BaobabRouterConstr(baobab, routes, settings) {
2431 /* *******************
2432 * PRIVATE ATTRIBUTES:
2433 * *******************
2434 */
2435 var _tree = baobab;
2436
2437 var _settings = settings || {};
2438
2439 var _solver = _settings.solver || __defaultSolver;
2440
2441 var _routesTree = __makeRoutes(__deepMerge(routes).value, _solver);
2442
2443 var _watcher;
2444
2445 var _hashInterval;
2446
2447 var _hashListener;
2448
2449 var _watcherListener;
2450
2451 var _stored = window.location.hash.replace(/^#/, "");
2452 /* ****************
2453 * PRIVATE METHODS:
2454 * ****************
2455 */
2456
2457 /**
2458 * This function will recursively check the hash to find a route that matches.
2459 * If none is found, then the default route will be used instead.
2460 *
2461 * Then, the state will be updated to match the selected route's state
2462 * constraints.
2463 */
2464
2465
2466 function _checkHash(baseHash, basePath, baseRoute) {
2467 var route = baseRoute || _routesTree;
2468
2469 var match = __doesHashMatch(route.fullPath, baseHash);
2470
2471 var hash = baseHash.replace(/\?.*$/, "").split("/");
2472 var query = baseHash.replace(/^[^\?]*\??/, "");
2473 var doCommit;
2474 var doForceCommit;
2475 var path = basePath || "";
2476
2477 if (!match) {
2478 return false;
2479 } // Check if a child does match (without using default values):
2480
2481
2482 if (route.routes && route.routes.some(function (child) {
2483 return _checkHash(baseHash, route.fullPath, child);
2484 })) {
2485 return true;
2486 } // If there is a default route, check which route it does match:
2487
2488
2489 if (match && route.defaultRoute) {
2490 path = route.fullDefaultPath.split("/").map(function (str, i) {
2491 return str.match(_solver) ? unescape(hash[i]) || str : str;
2492 }).join("/"); // The following line is no more linted, because of some circular deps on
2493 // the two functions:
2494
2495 _updateHash(path);
2496
2497 return true;
2498 } // If the route matched and has no default route:
2499
2500
2501 if (match && !route.defaultRoute) {
2502 var queryValues = query.split("&").reduce(function (res, str) {
2503 var arr = str.split("=");
2504 var queryObj = (route.fullQuery || {})[unescape(arr[0])] || {};
2505 var value = unescape(arr[1]);
2506
2507 switch (queryObj.cast) {
2508 case "number":
2509 value = +value;
2510 break;
2511
2512 case "boolean":
2513 value = value === "true" ? true : false;
2514 break;
2515
2516 case "base64":
2517 try {
2518 value = value ? JSON.parse(atob(value)) : null;
2519 } catch (e) {
2520 value = null;
2521 }
2522
2523 break;
2524
2525 case "json":
2526 try {
2527 value = value ? JSON.parse(value) : null;
2528 } catch (e) {
2529 value = null;
2530 }
2531
2532 break;
2533
2534 default: // Nothing actually...
2535
2536 }
2537
2538 if (queryObj.match) {
2539 res[queryObj.match] = value;
2540 }
2541
2542 return res;
2543 }, {}); // Apply updates:
2544
2545 route.updates.map(function (obj) {
2546 var update = {
2547 path: obj.path,
2548 value: obj.value
2549 };
2550
2551 if (obj.dynamic) {
2552 update.value = hash[route.fullPath.split("/").indexOf(update.value)] || queryValues[update.value];
2553 }
2554
2555 if (_routesTree.readOnly.every(function (str) {
2556 return !__compareArrays(update.path, str);
2557 }) && update.path.length > 1) {
2558 if (!(0, _lodash.default)(_tree.get(update.path.slice(1)), update.value)) {
2559 _tree.set(update.path.slice(1), update.value);
2560
2561 doCommit = true;
2562 } else {
2563 doForceCommit = true;
2564 }
2565 }
2566 }); // Commit only if something has actually been updated:
2567
2568 if (doCommit) {
2569 _tree.commit();
2570 } else if (doForceCommit) {
2571 _checkState();
2572 }
2573
2574 return true;
2575 }
2576 }
2577 /**
2578 * This function will update the hash, and execute the _checkHash method
2579 * if the new hash is different from the stored one. You can force the
2580 * _checkHash call by giving `true` as second parameter.
2581 *
2582 * @param {string} hash The new hash.
2583 * @param {boolean} force Will force the call if set to `true`.
2584 */
2585
2586
2587 function _updateHash(hash) {
2588 var force = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
2589
2590 if (_stored !== hash || force) {
2591 window.location.hash = hash;
2592 _stored = hash;
2593
2594 _checkHash(_stored);
2595 }
2596 }
2597 /**
2598 * This function will recursively check the state to find a route with
2599 * matching state constraints. If none is found, then the default route will
2600 * be used instead.
2601 *
2602 * Then, the hash will be updated to match the selected route's one.
2603 */
2604
2605
2606 function _checkState(basePath, baseRoute, baseTree) {
2607 var tree = baseTree || {
2608 state: _tree.get()
2609 };
2610 var route = baseRoute || _routesTree; // Check if route match:
2611
2612 var match = baseTree ? __doesStateMatch(tree, route.fullTree, route.dynamics, route.fullQueryValues) : __doesStateMatch(route.fullTree, tree, route.dynamics, route.fullQueryValues);
2613
2614 if (!match && arguments.length > 0 && !route.overrides) {
2615 return false;
2616 } // Check if a child does match:
2617
2618
2619 if (route.routes && route.routes.some(function (child) {
2620 return _checkState(route.fullPath, child);
2621 })) {
2622 return true;
2623 } // If the root route did not find any match, let's compare the tree with
2624 // only the read-only restrictions:
2625
2626
2627 if (!arguments.length) {
2628 _stored = null;
2629
2630 var restrictedTree = __extractPaths(tree).filter(function (obj) {
2631 return _routesTree.readOnly.some(function (path) {
2632 return __compareArrays(obj.path, path);
2633 });
2634 }).reduce(function (res, obj) {
2635 obj.path.reduce(function (localTree, string, i) {
2636 if (i === obj.path.length - 1) {
2637 localTree[string] = obj.value;
2638 } else {
2639 localTree[string] = localTree[string] || (typeof obj.path[i + 1] === "number" ? [] : {});
2640 }
2641
2642 return localTree[string];
2643 }, res);
2644 return res;
2645 }, {});
2646
2647 if (route.routes.some(function (child) {
2648 return _checkState(route.fullPath, child, restrictedTree);
2649 })) {
2650 return true;
2651 }
2652 }
2653
2654 if (match) {
2655 var query = {};
2656
2657 for (var k in route.fullQuery) {
2658 if (route.fullQuery.hasOwnProperty(k)) {
2659 var queryObj = route.fullQuery[k];
2660 var value = match[route.fullQuery[k].match];
2661
2662 switch (queryObj.cast) {
2663 case "json":
2664 if (value) {
2665 value = JSON.stringify(value);
2666 }
2667
2668 break;
2669
2670 case "base64":
2671 if (value) {
2672 value = btoa(JSON.stringify(value));
2673 }
2674
2675 break;
2676
2677 default: // Nothing actually...
2678
2679 }
2680
2681 if (value !== undefined && value !== null) {
2682 query[k] = value;
2683 }
2684 }
2685 }
2686
2687 _updateHash(__resolveURL(route.defaultRoute ? route.fullDefaultPath : route.fullPath, match, query), // If updating to a default route, then it might come from an invalid
2688 // state. And if the same route is already set, then forcing the hash
2689 // update is necessary to trigger the _checkHash to go back to a valid
2690 // state:
2691 !!route.defaultRoute);
2692
2693 return true;
2694 }
2695 }
2696 /* ***************
2697 * PUBLIC METHODS:
2698 * ***************
2699 */
2700
2701
2702 function kill() {
2703 // Hash update capture:
2704 if (_hashListener) {
2705 window.removeEventListener("hashchange", _hashListener, false);
2706 } else if (_hashInterval) {
2707 window.clearInterval(_hashInterval);
2708 } // Unbind the tree:
2709
2710
2711 _watcher.release();
2712
2713 _tree.router = null;
2714 }
2715 /* ***************
2716 * INITIALIZATION:
2717 * ***************
2718 */
2719 // Check that there is no router already bound to this tree:
2720
2721
2722 if (_tree.router) {
2723 throw new Error("BaobabRouter (constructor): " + "A router has already been bound to this tree.");
2724 }
2725
2726 _tree.router = this; // Listen to the hash changes:
2727
2728 if ("onhashchange" in window) {
2729 _hashListener = function _hashListener() {
2730 var hash = window.location.hash.replace(/^#/, "");
2731
2732 if (hash !== _stored) {
2733 _stored = hash;
2734
2735 _checkHash(_stored);
2736 }
2737 };
2738
2739 window.addEventListener("hashchange", _hashListener, false);
2740 } else {
2741 _stored = window.location.hash;
2742 _hashInterval = window.setInterval(function () {
2743 var hash = window.location.hash.replace(/^#/, "");
2744
2745 if (hash !== _stored) {
2746 _stored = hash;
2747
2748 _checkHash(_stored);
2749 }
2750 }, 100);
2751 } // Listen to the state changes:
2752
2753
2754 _watcherListener = function _watcherListener() {
2755 return _checkState();
2756 };
2757
2758 _watcher = _tree.watch(__extractPaths(_routesTree.routes.reduce(function _extract(arr, child) {
2759 return (child.routes || []).reduce(_extract, arr.concat(child.updates.map(function (obj) {
2760 return obj.path.slice(1);
2761 })));
2762 }, []).filter(function (path) {
2763 return path && path.length;
2764 }).reduce(function (context, path) {
2765 path.reduce(function (localContext, key) {
2766 return key in localContext ? localContext[key] : localContext[key] = {};
2767 }, context);
2768 return context;
2769 }, {}), []).reduce(function (result, obj, i) {
2770 result["path_" + i] = obj.path;
2771 return result;
2772 }, {}));
2773
2774 _watcher.on("update", _watcherListener); // Export publics:
2775
2776
2777 this.kill = kill; // Read the current hash:
2778
2779 _checkHash(_stored);
2780}; // Baobab-Router version:
2781
2782
2783BaobabRouter.version = "2.3.0"; // Expose private methods for unit testing:
2784
2785BaobabRouter.__doesHashMatch = __doesHashMatch;
2786BaobabRouter.__doesStateMatch = __doesStateMatch;
2787BaobabRouter.__extractPaths = __extractPaths;
2788BaobabRouter.__makeRoutes = __makeRoutes;
2789BaobabRouter.__deepMerge = __deepMerge;
2790BaobabRouter.__compareArrays = __compareArrays;
2791BaobabRouter.__resolveURL = __resolveURL;
2792BaobabRouter.__concatenatePaths = __concatenatePaths; // Expose private attributes for unit testing:
2793
2794BaobabRouter.__defaultSolver = __defaultSolver;
2795/* **************
2796 * EXPORT MODULE:
2797 * **************
2798 */
2799
2800var _default = BaobabRouter;
2801exports.default = _default;
2802},{"lodash.isequal":"RSRz"}]},{},["a3Jd"], null)