314 lines
		
	
	
		
			7.9 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
		
		
			
		
	
	
			314 lines
		
	
	
		
			7.9 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
|  | 'use strict'; | ||
|  | 
 | ||
|  | Object.defineProperty(exports, '__esModule', { | ||
|  |   value: true | ||
|  | }); | ||
|  | exports.equals = equals; | ||
|  | exports.isA = isA; | ||
|  | exports.fnNameFor = fnNameFor; | ||
|  | exports.isUndefined = isUndefined; | ||
|  | exports.hasProperty = hasProperty; | ||
|  | exports.isImmutableUnorderedKeyed = isImmutableUnorderedKeyed; | ||
|  | exports.isImmutableUnorderedSet = isImmutableUnorderedSet; | ||
|  | 
 | ||
|  | /* | ||
|  | Copyright (c) 2008-2016 Pivotal Labs | ||
|  | 
 | ||
|  | Permission is hereby granted, free of charge, to any person obtaining | ||
|  | a copy of this software and associated documentation files (the | ||
|  | "Software"), to deal in the Software without restriction, including | ||
|  | without limitation the rights to use, copy, modify, merge, publish, | ||
|  | distribute, sublicense, and/or sell copies of the Software, and to | ||
|  | permit persons to whom the Software is furnished to do so, subject to | ||
|  | the following conditions: | ||
|  | 
 | ||
|  | The above copyright notice and this permission notice shall be | ||
|  | included in all copies or substantial portions of the Software. | ||
|  | 
 | ||
|  | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
|  | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
|  | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
|  | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE | ||
|  | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | ||
|  | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | ||
|  | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
|  | 
 | ||
|  | */ | ||
|  | 
 | ||
|  | /* eslint-disable */ | ||
|  | // Extracted out of jasmine 2.5.2
 | ||
|  | function equals(a, b, customTesters, strictCheck) { | ||
|  |   customTesters = customTesters || []; | ||
|  |   return eq(a, b, [], [], customTesters, strictCheck ? hasKey : hasDefinedKey); | ||
|  | } | ||
|  | 
 | ||
|  | const functionToString = Function.prototype.toString; | ||
|  | 
 | ||
|  | function isAsymmetric(obj) { | ||
|  |   return !!obj && isA('Function', obj.asymmetricMatch); | ||
|  | } | ||
|  | 
 | ||
|  | function asymmetricMatch(a, b) { | ||
|  |   var asymmetricA = isAsymmetric(a), | ||
|  |     asymmetricB = isAsymmetric(b); | ||
|  | 
 | ||
|  |   if (asymmetricA && asymmetricB) { | ||
|  |     return undefined; | ||
|  |   } | ||
|  | 
 | ||
|  |   if (asymmetricA) { | ||
|  |     return a.asymmetricMatch(b); | ||
|  |   } | ||
|  | 
 | ||
|  |   if (asymmetricB) { | ||
|  |     return b.asymmetricMatch(a); | ||
|  |   } | ||
|  | } // Equality function lovingly adapted from isEqual in
 | ||
|  | //   [Underscore](http://underscorejs.org)
 | ||
|  | 
 | ||
|  | function eq(a, b, aStack, bStack, customTesters, hasKey) { | ||
|  |   var result = true; | ||
|  |   var asymmetricResult = asymmetricMatch(a, b); | ||
|  | 
 | ||
|  |   if (asymmetricResult !== undefined) { | ||
|  |     return asymmetricResult; | ||
|  |   } | ||
|  | 
 | ||
|  |   for (var i = 0; i < customTesters.length; i++) { | ||
|  |     var customTesterResult = customTesters[i](a, b); | ||
|  | 
 | ||
|  |     if (customTesterResult !== undefined) { | ||
|  |       return customTesterResult; | ||
|  |     } | ||
|  |   } | ||
|  | 
 | ||
|  |   if (a instanceof Error && b instanceof Error) { | ||
|  |     return a.message == b.message; | ||
|  |   } | ||
|  | 
 | ||
|  |   if (Object.is(a, b)) { | ||
|  |     return true; | ||
|  |   } // A strict comparison is necessary because `null == undefined`.
 | ||
|  | 
 | ||
|  |   if (a === null || b === null) { | ||
|  |     return a === b; | ||
|  |   } | ||
|  | 
 | ||
|  |   var className = Object.prototype.toString.call(a); | ||
|  | 
 | ||
|  |   if (className != Object.prototype.toString.call(b)) { | ||
|  |     return false; | ||
|  |   } | ||
|  | 
 | ||
|  |   switch (className) { | ||
|  |     // Strings, numbers, dates, and booleans are compared by value.
 | ||
|  |     case '[object String]': | ||
|  |       // Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is
 | ||
|  |       // equivalent to `new String("5")`.
 | ||
|  |       return a == String(b); | ||
|  | 
 | ||
|  |     case '[object Number]': | ||
|  |       return Object.is(Number(a), Number(b)); | ||
|  | 
 | ||
|  |     case '[object Date]': | ||
|  |     case '[object Boolean]': | ||
|  |       // Coerce dates and booleans to numeric primitive values. Dates are compared by their
 | ||
|  |       // millisecond representations. Note that invalid dates with millisecond representations
 | ||
|  |       // of `NaN` are not equivalent.
 | ||
|  |       return +a == +b; | ||
|  |     // RegExps are compared by their source patterns and flags.
 | ||
|  | 
 | ||
|  |     case '[object RegExp]': | ||
|  |       return ( | ||
|  |         a.source == b.source && | ||
|  |         a.global == b.global && | ||
|  |         a.multiline == b.multiline && | ||
|  |         a.ignoreCase == b.ignoreCase | ||
|  |       ); | ||
|  |   } | ||
|  | 
 | ||
|  |   if (typeof a != 'object' || typeof b != 'object') { | ||
|  |     return false; | ||
|  |   } // Use DOM3 method isEqualNode (IE>=9)
 | ||
|  | 
 | ||
|  |   if (isDomNode(a) && isDomNode(b)) { | ||
|  |     return a.isEqualNode(b); | ||
|  |   } // Used to detect circular references.
 | ||
|  | 
 | ||
|  |   var length = aStack.length; | ||
|  | 
 | ||
|  |   while (length--) { | ||
|  |     // Linear search. Performance is inversely proportional to the number of
 | ||
|  |     // unique nested structures.
 | ||
|  |     // circular references at same depth are equal
 | ||
|  |     // circular reference is not equal to non-circular one
 | ||
|  |     if (aStack[length] === a) { | ||
|  |       return bStack[length] === b; | ||
|  |     } else if (bStack[length] === b) { | ||
|  |       return false; | ||
|  |     } | ||
|  |   } // Add the first object to the stack of traversed objects.
 | ||
|  | 
 | ||
|  |   aStack.push(a); | ||
|  |   bStack.push(b); | ||
|  |   var size = 0; // Recursively compare objects and arrays.
 | ||
|  |   // Compare array lengths to determine if a deep comparison is necessary.
 | ||
|  | 
 | ||
|  |   if (className == '[object Array]') { | ||
|  |     size = a.length; | ||
|  | 
 | ||
|  |     if (size !== b.length) { | ||
|  |       return false; | ||
|  |     } | ||
|  | 
 | ||
|  |     while (size--) { | ||
|  |       result = eq(a[size], b[size], aStack, bStack, customTesters, hasKey); | ||
|  | 
 | ||
|  |       if (!result) { | ||
|  |         return false; | ||
|  |       } | ||
|  |     } | ||
|  |   } // Deep compare objects.
 | ||
|  | 
 | ||
|  |   var aKeys = keys(a, className == '[object Array]', hasKey), | ||
|  |     key; | ||
|  |   size = aKeys.length; // Ensure that both objects contain the same number of properties before comparing deep equality.
 | ||
|  | 
 | ||
|  |   if (keys(b, className == '[object Array]', hasKey).length !== size) { | ||
|  |     return false; | ||
|  |   } | ||
|  | 
 | ||
|  |   while (size--) { | ||
|  |     key = aKeys[size]; // Deep compare each member
 | ||
|  | 
 | ||
|  |     result = | ||
|  |       hasKey(b, key) && | ||
|  |       eq(a[key], b[key], aStack, bStack, customTesters, hasKey); | ||
|  | 
 | ||
|  |     if (!result) { | ||
|  |       return false; | ||
|  |     } | ||
|  |   } // Remove the first object from the stack of traversed objects.
 | ||
|  | 
 | ||
|  |   aStack.pop(); | ||
|  |   bStack.pop(); | ||
|  |   return result; | ||
|  | } | ||
|  | 
 | ||
|  | function keys(obj, isArray, hasKey) { | ||
|  |   var allKeys = (function(o) { | ||
|  |     var keys = []; | ||
|  | 
 | ||
|  |     for (var key in o) { | ||
|  |       if (hasKey(o, key)) { | ||
|  |         keys.push(key); | ||
|  |       } | ||
|  |     } | ||
|  | 
 | ||
|  |     return keys.concat( | ||
|  |       Object.getOwnPropertySymbols(o).filter( | ||
|  |         symbol => Object.getOwnPropertyDescriptor(o, symbol).enumerable | ||
|  |       ) | ||
|  |     ); | ||
|  |   })(obj); | ||
|  | 
 | ||
|  |   if (!isArray) { | ||
|  |     return allKeys; | ||
|  |   } | ||
|  | 
 | ||
|  |   var extraKeys = []; | ||
|  | 
 | ||
|  |   if (allKeys.length === 0) { | ||
|  |     return allKeys; | ||
|  |   } | ||
|  | 
 | ||
|  |   for (var x = 0; x < allKeys.length; x++) { | ||
|  |     if (typeof allKeys[x] === 'symbol' || !allKeys[x].match(/^[0-9]+$/)) { | ||
|  |       extraKeys.push(allKeys[x]); | ||
|  |     } | ||
|  |   } | ||
|  | 
 | ||
|  |   return extraKeys; | ||
|  | } | ||
|  | 
 | ||
|  | function hasDefinedKey(obj, key) { | ||
|  |   return hasKey(obj, key) && obj[key] !== undefined; | ||
|  | } | ||
|  | 
 | ||
|  | function hasKey(obj, key) { | ||
|  |   return Object.prototype.hasOwnProperty.call(obj, key); | ||
|  | } | ||
|  | 
 | ||
|  | function isA(typeName, value) { | ||
|  |   return Object.prototype.toString.apply(value) === '[object ' + typeName + ']'; | ||
|  | } | ||
|  | 
 | ||
|  | function isDomNode(obj) { | ||
|  |   return ( | ||
|  |     obj !== null && | ||
|  |     typeof obj === 'object' && | ||
|  |     typeof obj.nodeType === 'number' && | ||
|  |     typeof obj.nodeName === 'string' && | ||
|  |     typeof obj.isEqualNode === 'function' | ||
|  |   ); | ||
|  | } | ||
|  | 
 | ||
|  | function fnNameFor(func) { | ||
|  |   if (func.name) { | ||
|  |     return func.name; | ||
|  |   } | ||
|  | 
 | ||
|  |   const matches = functionToString | ||
|  |     .call(func) | ||
|  |     .match(/^(?:async)?\s*function\s*\*?\s*([\w$]+)\s*\(/); | ||
|  |   return matches ? matches[1] : '<anonymous>'; | ||
|  | } | ||
|  | 
 | ||
|  | function isUndefined(obj) { | ||
|  |   return obj === void 0; | ||
|  | } | ||
|  | 
 | ||
|  | function getPrototype(obj) { | ||
|  |   if (Object.getPrototypeOf) { | ||
|  |     return Object.getPrototypeOf(obj); | ||
|  |   } | ||
|  | 
 | ||
|  |   if (obj.constructor.prototype == obj) { | ||
|  |     return null; | ||
|  |   } | ||
|  | 
 | ||
|  |   return obj.constructor.prototype; | ||
|  | } | ||
|  | 
 | ||
|  | function hasProperty(obj, property) { | ||
|  |   if (!obj) { | ||
|  |     return false; | ||
|  |   } | ||
|  | 
 | ||
|  |   if (Object.prototype.hasOwnProperty.call(obj, property)) { | ||
|  |     return true; | ||
|  |   } | ||
|  | 
 | ||
|  |   return hasProperty(getPrototype(obj), property); | ||
|  | } // SENTINEL constants are from https://github.com/facebook/immutable-js
 | ||
|  | 
 | ||
|  | const IS_KEYED_SENTINEL = '@@__IMMUTABLE_KEYED__@@'; | ||
|  | const IS_SET_SENTINEL = '@@__IMMUTABLE_SET__@@'; | ||
|  | const IS_ORDERED_SENTINEL = '@@__IMMUTABLE_ORDERED__@@'; | ||
|  | 
 | ||
|  | function isImmutableUnorderedKeyed(maybeKeyed) { | ||
|  |   return !!( | ||
|  |     maybeKeyed && | ||
|  |     maybeKeyed[IS_KEYED_SENTINEL] && | ||
|  |     !maybeKeyed[IS_ORDERED_SENTINEL] | ||
|  |   ); | ||
|  | } | ||
|  | 
 | ||
|  | function isImmutableUnorderedSet(maybeSet) { | ||
|  |   return !!( | ||
|  |     maybeSet && | ||
|  |     maybeSet[IS_SET_SENTINEL] && | ||
|  |     !maybeSet[IS_ORDERED_SENTINEL] | ||
|  |   ); | ||
|  | } |