This app provides monitoring and information features for the common freifunk user and the technical stuff of a freifunk community.
Code base is taken from a TUM Practical Course project and added here to see if Freifunk Altdorf can use it.
https://www.freifunk-altdorf.de
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
106 lines
2.7 KiB
106 lines
2.7 KiB
'use strict'; |
|
|
|
/** |
|
* Copyright (c) 2013-present, Facebook, Inc. |
|
* |
|
* This source code is licensed under the MIT license found in the |
|
* LICENSE file in the root directory of this source tree. |
|
* |
|
* |
|
*/ |
|
|
|
var aStackPool = []; |
|
var bStackPool = []; |
|
|
|
/** |
|
* Checks if two values are equal. Values may be primitives, arrays, or objects. |
|
* Returns true if both arguments have the same keys and values. |
|
* |
|
* @see http://underscorejs.org |
|
* @copyright 2009-2013 Jeremy Ashkenas, DocumentCloud Inc. |
|
* @license MIT |
|
*/ |
|
function areEqual(a, b) { |
|
var aStack = aStackPool.length ? aStackPool.pop() : []; |
|
var bStack = bStackPool.length ? bStackPool.pop() : []; |
|
var result = eq(a, b, aStack, bStack); |
|
aStack.length = 0; |
|
bStack.length = 0; |
|
aStackPool.push(aStack); |
|
bStackPool.push(bStack); |
|
return result; |
|
} |
|
|
|
function eq(a, b, aStack, bStack) { |
|
if (a === b) { |
|
// Identical objects are equal. `0 === -0`, but they aren't identical. |
|
return a !== 0 || 1 / a == 1 / b; |
|
} |
|
if (a == null || b == null) { |
|
// a or b can be `null` or `undefined` |
|
return false; |
|
} |
|
if (typeof a != 'object' || typeof b != 'object') { |
|
return false; |
|
} |
|
var objToStr = Object.prototype.toString; |
|
var className = objToStr.call(a); |
|
if (className != objToStr.call(b)) { |
|
return false; |
|
} |
|
switch (className) { |
|
case '[object String]': |
|
return a == String(b); |
|
case '[object Number]': |
|
return isNaN(a) || isNaN(b) ? false : a == Number(b); |
|
case '[object Date]': |
|
case '[object Boolean]': |
|
return +a == +b; |
|
case '[object RegExp]': |
|
return a.source == b.source && a.global == b.global && a.multiline == b.multiline && a.ignoreCase == b.ignoreCase; |
|
} |
|
// Assume equality for cyclic structures. |
|
var length = aStack.length; |
|
while (length--) { |
|
if (aStack[length] == a) { |
|
return bStack[length] == b; |
|
} |
|
} |
|
aStack.push(a); |
|
bStack.push(b); |
|
var size = 0; |
|
// Recursively compare objects and arrays. |
|
if (className === '[object Array]') { |
|
size = a.length; |
|
if (size !== b.length) { |
|
return false; |
|
} |
|
// Deep compare the contents, ignoring non-numeric properties. |
|
while (size--) { |
|
if (!eq(a[size], b[size], aStack, bStack)) { |
|
return false; |
|
} |
|
} |
|
} else { |
|
if (a.constructor !== b.constructor) { |
|
return false; |
|
} |
|
if (a.hasOwnProperty('valueOf') && b.hasOwnProperty('valueOf')) { |
|
return a.valueOf() == b.valueOf(); |
|
} |
|
var keys = Object.keys(a); |
|
if (keys.length != Object.keys(b).length) { |
|
return false; |
|
} |
|
for (var i = 0; i < keys.length; i++) { |
|
if (!eq(a[keys[i]], b[keys[i]], aStack, bStack)) { |
|
return false; |
|
} |
|
} |
|
} |
|
aStack.pop(); |
|
bStack.pop(); |
|
return true; |
|
} |
|
|
|
module.exports = areEqual; |