| 2007 | return obj; |
| 2008 | }; |
| 2009 | var eq = function(a, b, aStack, bStack) { |
| 2010 | if (a === b) return a !== 0 || 1 / a == 1 / b; |
| 2011 | if (a == null || b == null) return a === b; |
| 2012 | if (a instanceof _) a = a._wrapped; |
| 2013 | if (b instanceof _) b = b._wrapped; |
| 2014 | var className = toString.call(a); |
| 2015 | if (className != toString.call(b)) return false; |
| 2016 | switch (className) { |
| 2017 | case '[object String]': |
| 2018 | return a == String(b); |
| 2019 | case '[object Number]': |
| 2020 | return a != +a ? b != +b : (a == 0 ? 1 / a == 1 / b : a == +b); |
| 2021 | case '[object Date]': |
| 2022 | case '[object Boolean]': |
| 2023 | return +a == +b; |
| 2024 | case '[object RegExp]': |
| 2025 | return a.source == b.source && |
| 2026 | a.global == b.global && |
| 2027 | a.multiline == b.multiline && |
| 2028 | a.ignoreCase == b.ignoreCase; |
| 2029 | } |
| 2030 | if (typeof a != 'object' || typeof b != 'object') return false; |
| 2031 | var length = aStack.length; |
| 2032 | while (length--) { |
| 2033 | if (aStack[length] == a) return bStack[length] == b; |
| 2034 | } |
| 2035 | var aCtor = a.constructor, bCtor = b.constructor; |
| 2036 | if (aCtor !== bCtor && !(_.isFunction(aCtor) && (aCtor instanceof aCtor) && |
| 2037 | _.isFunction(bCtor) && (bCtor instanceof bCtor)) |
| 2038 | && ('constructor' in a && 'constructor' in b)) { |
| 2039 | return false; |
| 2040 | } |
| 2041 | aStack.push(a); |
| 2042 | bStack.push(b); |
| 2043 | var size = 0, result = true; |
| 2044 | if (className == '[object Array]') { |
| 2045 | size = a.length; |
| 2046 | result = size == b.length; |
| 2047 | if (result) { |
| 2048 | while (size--) { |
| 2049 | if (!(result = eq(a[size], b[size], aStack, bStack))) break; |
| 2050 | } |
| 2051 | } |
| 2052 | } else { |
| 2053 | for (var key in a) { |
| 2054 | if (_.has(a, key)) { |
| 2055 | size++; |
| 2056 | if (!(result = _.has(b, key) && eq(a[key], b[key], aStack, bStack))) break; |
| 2057 | } |
| 2058 | } |
| 2059 | if (result) { |
| 2060 | for (key in b) { |
| 2061 | if (_.has(b, key) && !(size--)) break; |
| 2062 | } |
| 2063 | result = !size; |
| 2064 | } |
| 2065 | } |
| 2066 | aStack.pop(); |