| var traverse = require('../../'); | 
|   | 
| module.exports = function (a, b) { | 
|     if (arguments.length !== 2) { | 
|         throw new Error( | 
|             'deepEqual requires exactly two objects to compare against' | 
|         ); | 
|     } | 
|      | 
|     var equal = true; | 
|     var node = b; | 
|      | 
|     traverse(a).forEach(function (y) { | 
|         var notEqual = (function () { | 
|             equal = false; | 
|             //this.stop(); | 
|             return undefined; | 
|         }).bind(this); | 
|          | 
|         //if (node === undefined || node === null) return notEqual(); | 
|          | 
|         if (!this.isRoot) { | 
|         /* | 
|             if (!Object.hasOwnProperty.call(node, this.key)) { | 
|                 return notEqual(); | 
|             } | 
|         */ | 
|             if (typeof node !== 'object') return notEqual(); | 
|             node = node[this.key]; | 
|         } | 
|          | 
|         var x = node; | 
|          | 
|         this.post(function () { | 
|             node = x; | 
|         }); | 
|          | 
|         var toS = function (o) { | 
|             return Object.prototype.toString.call(o); | 
|         }; | 
|          | 
|         if (this.circular) { | 
|             if (traverse(b).get(this.circular.path) !== x) notEqual(); | 
|         } | 
|         else if (typeof x !== typeof y) { | 
|             notEqual(); | 
|         } | 
|         else if (x === null || y === null || x === undefined || y === undefined) { | 
|             if (x !== y) notEqual(); | 
|         } | 
|         else if (x.__proto__ !== y.__proto__) { | 
|             notEqual(); | 
|         } | 
|         else if (x === y) { | 
|             // nop | 
|         } | 
|         else if (typeof x === 'function') { | 
|             if (x instanceof RegExp) { | 
|                 // both regexps on account of the __proto__ check | 
|                 if (x.toString() != y.toString()) notEqual(); | 
|             } | 
|             else if (x !== y) notEqual(); | 
|         } | 
|         else if (typeof x === 'object') { | 
|             if (toS(y) === '[object Arguments]' | 
|             || toS(x) === '[object Arguments]') { | 
|                 if (toS(x) !== toS(y)) { | 
|                     notEqual(); | 
|                 } | 
|             } | 
|             else if (toS(y) === '[object RegExp]' | 
|             || toS(x) === '[object RegExp]') { | 
|                 if (!x || !y || x.toString() !== y.toString()) notEqual(); | 
|             } | 
|             else if (x instanceof Date || y instanceof Date) { | 
|                 if (!(x instanceof Date) || !(y instanceof Date) | 
|                 || x.getTime() !== y.getTime()) { | 
|                     notEqual(); | 
|                 } | 
|             } | 
|             else { | 
|                 var kx = Object.keys(x); | 
|                 var ky = Object.keys(y); | 
|                 if (kx.length !== ky.length) return notEqual(); | 
|                 for (var i = 0; i < kx.length; i++) { | 
|                     var k = kx[i]; | 
|                     if (!Object.hasOwnProperty.call(y, k)) { | 
|                         notEqual(); | 
|                     } | 
|                 } | 
|             } | 
|         } | 
|     }); | 
|      | 
|     return equal; | 
| }; |