foop
Version:
interfaces that describe their intentions.
267 lines (237 loc) • 22.5 kB
JavaScript
// conditionals
/* eslint complexity: "OFF" */
// debugging
/* eslint max-depth: "OFF" */
var isObjNotNull = require('../is/objNotNull')
var isNullOrUndefined = require('../is/nullOrUndefined')
var isFunction = require('../is/function')
var isRegExp = require('../is/regexp')
var isError = require('../is/error')
var isTrue = require('../is/true')
var isDate = require('../is/date')
var isArray = require('../is/array')
var isObj = require('../is/obj')
var toS = require('../is/toS')
var hasOwnProperty = require('../util/hasOwnProperty')
var ObjectKeys = require('../util/keys')
var ObjectOrArrayKeys = require('../util/keysObjOrArray')
var ENV_DEBUG = require('../env/debug')
// const ENV_DEBUG = true
var isNotRealOrNotEqToString = function (x, y) { return !x || !y || x.toString() !== y.toString(); }
/* prettier-ignore */
/**
* @desc checks value equality, used by eq which compares all types
* @since 4.1.0
* @memberOf Traverse
* @protected
*
* @TODO !!!!!! USE ENUM FLAGS ON LOOSE TO ALLOW MORE CONFIG FOR ==, COMPARATOR, VALUEOF, walk proto (check ownProps...)...
*
* @param {*} x compare to y
* @param {*} y compare to x
* @param {boolean | number} [loose=false] use == checks when typof !=
* @return {boolean}
*
* @example
*
* eqValue(1, 1) //=> true
* eqValue('1', 1) //=> false
* eqValue('1', 1, true) //=> true
* eqValue({}, {}) //=> true
*
*/
module.exports = function eqValue(x, y, loose) {
/* istanbul ignore next: dev */
if (ENV_DEBUG) {
console.log('eqValue', {x: x, y: y, loose: loose})
}
// if (x === y) {
// if (ENV_DEBUG) {
// console.log('===', {x, y})
// }
// // noop
// }
// else
if (isNullOrUndefined(x) || isNullOrUndefined(y)) {
/* istanbul ignore next: dev */
if (ENV_DEBUG) {
console.log('null or undef !=', {x: x, y: y})
}
if (x !== y) {
return false
}
}
else if (typeof x !== typeof y) {
// eslint-disable-next-line
if (isTrue(loose) && x == y) {
// ignore
}
else {
/* istanbul ignore next: dev */
if (ENV_DEBUG) {
console.log('typeof !=', {x: x, y: y})
}
return false
}
}
// @TODO put this up first?
else if (toS(x) !== toS(y)) {
/* istanbul ignore next: dev */
if (ENV_DEBUG) {
console.log('diff str types', {x: toS(x), y: toS(y)})
}
return false
}
else if (isObjNotNull(x)) {
// use .equals if the method exists
if (hasOwnProperty(x, 'equals')) {
return x.equals(y)
}
/* istanbul ignore next: dev */
if (ENV_DEBUG) {
console.log('isObjNotNull', {x: x})
}
// if (isArray(x)) {
// if (x.length !== y.length) {
// return false
// }
// }
// @NOTE .toString will be covered for functions and regexes in objStrict
if (isRegExp(x) || isRegExp(y)) {
/* istanbul ignore next: dev */
if (ENV_DEBUG) {
console.log('regexp', {x: x, y: y})
}
if (isNotRealOrNotEqToString(x, y)) {
/* istanbul ignore next: dev */
if (ENV_DEBUG) {
console.log('regexp !=', {x: x, y: y})
}
return false
}
}
else if (isDate(x) || isDate(y)) {
/* istanbul ignore next: dev */
if (ENV_DEBUG) {
console.log('dates', {x: x, y: y})
}
if (!isDate(x) || !isDate(y) || x.getTime() !== y.getTime()) {
/* istanbul ignore next: dev */
if (ENV_DEBUG) {
console.log('!= dates', {x: x, y: y})
}
return false
}
}
else if (isError(x) || isError(y)) {
/* istanbul ignore next: dev */
if (ENV_DEBUG) {
console.log('isError', {x: x, y: y})
}
if (!isError(x) || !isError(y) || x.stack !== y.stack) {
/* istanbul ignore next: dev */
if (ENV_DEBUG) {
console.log('!= errors', {x: x, y: y})
}
return false
}
}
// @NOTE this is covered by toString != toString
// else if (isArray(x) && !isArray(y)) {
// /* istanbul ignore next: dev */
// if (ENV_DEBUG) {
// console.log('isArray(x) || isArray(y)!')
// }
//
// return false
// }
// else if (!isArray(x) && isArray(y)) {
// /* istanbul ignore next: dev */
// if (ENV_DEBUG) {
// console.log('!isArray(x) && isArray(y):')
// }
//
// return false
// }
// @TODO considering, we already know it is not null & undefined
// if (isPrimitive(x) || isPrimitive(y)) {
// return x.valueOf() === y.valueOf()
// }
else {
// @TODO ObjectOrArrayKeys, but have to have else where they are both array
//
// @NOTE it will traverse through values if they are == here
var xKeys = ObjectKeys(x)
var yKeys = ObjectKeys(y).length
// diff length
if (xKeys.length !== yKeys) {
/* istanbul ignore next: dev */
if (ENV_DEBUG) {
console.log('!= obj key length', {xKeys: xKeys, yKeys: yKeys})
}
return false
}
for (var k = 0; k < xKeys.length; k++) {
if (!hasOwnProperty(y, xKeys[k])) {
/* istanbul ignore next: dev */
if (ENV_DEBUG) {
console.log('!= obj property', {y: y, val: xKeys[k]})
}
return false
}
}
}
}
else if (toS(x) === toS(y) && x !== y) {
// isString(x) || isBoolean(x) || isNumber(x) || isIterator(x)
/* istanbul ignore next: dev */
if (ENV_DEBUG) {
console.log('same str types - diff values', {s: toS(x), x: x, y: y})
}
return false
}
// // @TODO put this up first?
// else if (toS(x) !== toS(y)) {
// /* istanbul ignore next: dev */
// if (ENV_DEBUG) {
// console.log('diff str types', {x: toS(x), y: toS(y)})
// }
//
// return false
// }
// go deeper
else if (isFunction(x) || isFunction(y)) {
/* istanbul ignore next: dev */
if (ENV_DEBUG) {
console.log('isFunction(x) && isFunction(y):')
console.log(x.toString())
console.log(y.toString())
}
if (isNotRealOrNotEqToString(x, y)) {
/* istanbul ignore next: dev */
if (ENV_DEBUG) {
console.log('x.toString() !== y.toString()', x.toString() !== y.toString())
}
return false
}
else {
return true
}
}
// @TODO why?
else if (isObj(x) && isObj(y)) {
/* istanbul ignore next: dev */
if (ENV_DEBUG) {
console.log('isObj(x) && isObj(y):')
}
return false
}
// else {
/* istanbul ignore next: dev */
if (ENV_DEBUG) {
console.log('eqeqeq:', {[toS(x) + 'X']: x, [toS(y) + 'Y']: y})
}
return true
// }
}
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXFWYWx1ZS5qcyIsInNvdXJjZXMiOlsiZXFWYWx1ZS5qcyJdLCJzb3VyY2VzQ29udGVudCI6WyIvLyBjb25kaXRpb25hbHNcbi8qIGVzbGludCBjb21wbGV4aXR5OiBcIk9GRlwiICovXG4vLyBkZWJ1Z2dpbmdcbi8qIGVzbGludCBtYXgtZGVwdGg6IFwiT0ZGXCIgKi9cblxuY29uc3QgaXNPYmpOb3ROdWxsID0gcmVxdWlyZSgnLi4vaXMvb2JqTm90TnVsbCcpXG5jb25zdCBpc051bGxPclVuZGVmaW5lZCA9IHJlcXVpcmUoJy4uL2lzL251bGxPclVuZGVmaW5lZCcpXG5jb25zdCBpc0Z1bmN0aW9uID0gcmVxdWlyZSgnLi4vaXMvZnVuY3Rpb24nKVxuY29uc3QgaXNSZWdFeHAgPSByZXF1aXJlKCcuLi9pcy9yZWdleHAnKVxuY29uc3QgaXNFcnJvciA9IHJlcXVpcmUoJy4uL2lzL2Vycm9yJylcbmNvbnN0IGlzVHJ1ZSA9IHJlcXVpcmUoJy4uL2lzL3RydWUnKVxuY29uc3QgaXNEYXRlID0gcmVxdWlyZSgnLi4vaXMvZGF0ZScpXG5jb25zdCBpc0FycmF5ID0gcmVxdWlyZSgnLi4vaXMvYXJyYXknKVxuY29uc3QgaXNPYmogPSByZXF1aXJlKCcuLi9pcy9vYmonKVxuY29uc3QgdG9TID0gcmVxdWlyZSgnLi4vaXMvdG9TJylcbmNvbnN0IGhhc093blByb3BlcnR5ID0gcmVxdWlyZSgnLi4vdXRpbC9oYXNPd25Qcm9wZXJ0eScpXG5jb25zdCBPYmplY3RLZXlzID0gcmVxdWlyZSgnLi4vdXRpbC9rZXlzJylcbmNvbnN0IE9iamVjdE9yQXJyYXlLZXlzID0gcmVxdWlyZSgnLi4vdXRpbC9rZXlzT2JqT3JBcnJheScpXG5jb25zdCBFTlZfREVCVUcgPSByZXF1aXJlKCcuLi9lbnYvZGVidWcnKVxuXG4vLyBjb25zdCBFTlZfREVCVUcgPSB0cnVlXG5cbmNvbnN0IGlzTm90UmVhbE9yTm90RXFUb1N0cmluZyA9ICh4LCB5KSA9PlxuICAheCB8fCAheSB8fCB4LnRvU3RyaW5nKCkgIT09IHkudG9TdHJpbmcoKVxuXG4vKiBwcmV0dGllci1pZ25vcmUgKi9cbi8qKlxuICogQGRlc2MgY2hlY2tzIHZhbHVlIGVxdWFsaXR5LCB1c2VkIGJ5IGVxIHdoaWNoIGNvbXBhcmVzIGFsbCB0eXBlc1xuICogQHNpbmNlIDQuMS4wXG4gKiBAbWVtYmVyT2YgVHJhdmVyc2VcbiAqIEBwcm90ZWN0ZWRcbiAqXG4gKiBAVE9ETyAhISEhISEgVVNFIEVOVU0gRkxBR1MgT04gTE9PU0UgVE8gQUxMT1cgTU9SRSBDT05GSUcgRk9SID09LCBDT01QQVJBVE9SLCBWQUxVRU9GLCB3YWxrIHByb3RvIChjaGVjayBvd25Qcm9wcy4uLikuLi5cbiAqXG4gKiBAcGFyYW0gIHsqfSB4IGNvbXBhcmUgdG8geVxuICogQHBhcmFtICB7Kn0geSBjb21wYXJlIHRvIHhcbiAqIEBwYXJhbSAge2Jvb2xlYW4gfCBudW1iZXJ9IFtsb29zZT1mYWxzZV0gdXNlID09IGNoZWNrcyB3aGVuIHR5cG9mICE9XG4gKiBAcmV0dXJuIHtib29sZWFufVxuICpcbiAqIEBleGFtcGxlXG4gKlxuICogICAgZXFWYWx1ZSgxLCAxKSAgICAgICAgIC8vPT4gdHJ1ZVxuICogICAgZXFWYWx1ZSgnMScsIDEpICAgICAgIC8vPT4gZmFsc2VcbiAqICAgIGVxVmFsdWUoJzEnLCAxLCB0cnVlKSAvLz0+IHRydWVcbiAqICAgIGVxVmFsdWUoe30sIHt9KSAgICAgICAvLz0+IHRydWVcbiAqXG4gKi9cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gZXFWYWx1ZSh4LCB5LCBsb29zZSkge1xuICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dDogZGV2ICovXG4gIGlmIChFTlZfREVCVUcpIHtcbiAgICBjb25zb2xlLmxvZygnZXFWYWx1ZScsIHt4LCB5LCBsb29zZX0pXG4gIH1cblxuICAvLyBpZiAoeCA9PT0geSkge1xuICAvLyAgIGlmIChFTlZfREVCVUcpIHtcbiAgLy8gICAgIGNvbnNvbGUubG9nKCc9PT0nLCB7eCwgeX0pXG4gIC8vICAgfVxuICAvLyAgIC8vIG5vb3BcbiAgLy8gfVxuICAvLyBlbHNlXG5cbiAgaWYgKGlzTnVsbE9yVW5kZWZpbmVkKHgpIHx8IGlzTnVsbE9yVW5kZWZpbmVkKHkpKSB7XG4gICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQ6IGRldiAqL1xuICAgIGlmIChFTlZfREVCVUcpIHtcbiAgICAgIGNvbnNvbGUubG9nKCdudWxsIG9yIHVuZGVmICE9Jywge3gsIHl9KVxuICAgIH1cblxuICAgIGlmICh4ICE9PSB5KSB7XG4gICAgICByZXR1cm4gZmFsc2VcbiAgICB9XG4gIH1cbiAgZWxzZSBpZiAodHlwZW9mIHggIT09IHR5cGVvZiB5KSB7XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lXG4gICAgaWYgKGlzVHJ1ZShsb29zZSkgJiYgeCA9PSB5KSB7XG4gICAgICAvLyBpZ25vcmVcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dDogZGV2ICovXG4gICAgICBpZiAoRU5WX0RFQlVHKSB7XG4gICAgICAgIGNvbnNvbGUubG9nKCd0eXBlb2YgIT0nLCB7eCwgeX0pXG4gICAgICB9XG5cbiAgICAgIHJldHVybiBmYWxzZVxuICAgIH1cbiAgfVxuICAvLyBAVE9ETyBwdXQgdGhpcyB1cCBmaXJzdD9cbiAgZWxzZSBpZiAodG9TKHgpICE9PSB0b1MoeSkpIHtcbiAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dDogZGV2ICovXG4gICAgaWYgKEVOVl9ERUJVRykge1xuICAgICAgY29uc29sZS5sb2coJ2RpZmYgc3RyIHR5cGVzJywge3g6IHRvUyh4KSwgeTogdG9TKHkpfSlcbiAgICB9XG5cbiAgICByZXR1cm4gZmFsc2VcbiAgfVxuICBlbHNlIGlmIChpc09iak5vdE51bGwoeCkpIHtcbiAgICAvLyB1c2UgLmVxdWFscyBpZiB0aGUgbWV0aG9kIGV4aXN0c1xuICAgIGlmIChoYXNPd25Qcm9wZXJ0eSh4LCAnZXF1YWxzJykpIHtcbiAgICAgIHJldHVybiB4LmVxdWFscyh5KVxuICAgIH1cblxuICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0OiBkZXYgKi9cbiAgICBpZiAoRU5WX0RFQlVHKSB7XG4gICAgICBjb25zb2xlLmxvZygnaXNPYmpOb3ROdWxsJywge3h9KVxuICAgIH1cblxuICAgIC8vIGlmIChpc0FycmF5KHgpKSB7XG4gICAgLy8gICBpZiAoeC5sZW5ndGggIT09IHkubGVuZ3RoKSB7XG4gICAgLy8gICAgIHJldHVybiBmYWxzZVxuICAgIC8vICAgfVxuICAgIC8vIH1cblxuICAgIC8vIEBOT1RFIC50b1N0cmluZyB3aWxsIGJlIGNvdmVyZWQgZm9yIGZ1bmN0aW9ucyBhbmQgcmVnZXhlcyBpbiBvYmpTdHJpY3RcbiAgICBpZiAoaXNSZWdFeHAoeCkgfHwgaXNSZWdFeHAoeSkpIHtcbiAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0OiBkZXYgKi9cbiAgICAgIGlmIChFTlZfREVCVUcpIHtcbiAgICAgICAgY29uc29sZS5sb2coJ3JlZ2V4cCcsIHt4LCB5fSlcbiAgICAgIH1cblxuICAgICAgaWYgKGlzTm90UmVhbE9yTm90RXFUb1N0cmluZyh4LCB5KSkge1xuICAgICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dDogZGV2ICovXG4gICAgICAgIGlmIChFTlZfREVCVUcpIHtcbiAgICAgICAgICBjb25zb2xlLmxvZygncmVnZXhwICE9Jywge3gsIHl9KVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgICB9XG4gICAgfVxuICAgIGVsc2UgaWYgKGlzRGF0ZSh4KSB8fCBpc0RhdGUoeSkpIHtcbiAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0OiBkZXYgKi9cbiAgICAgIGlmIChFTlZfREVCVUcpIHtcbiAgICAgICAgY29uc29sZS5sb2coJ2RhdGVzJywge3gsIHl9KVxuICAgICAgfVxuXG4gICAgICBpZiAoIWlzRGF0ZSh4KSB8fCAhaXNEYXRlKHkpIHx8IHguZ2V0VGltZSgpICE9PSB5LmdldFRpbWUoKSkge1xuICAgICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dDogZGV2ICovXG4gICAgICAgIGlmIChFTlZfREVCVUcpIHtcbiAgICAgICAgICBjb25zb2xlLmxvZygnIT0gZGF0ZXMnLCB7eCwgeX0pXG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gZmFsc2VcbiAgICAgIH1cbiAgICB9XG4gICAgZWxzZSBpZiAoaXNFcnJvcih4KSB8fCBpc0Vycm9yKHkpKSB7XG4gICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dDogZGV2ICovXG4gICAgICBpZiAoRU5WX0RFQlVHKSB7XG4gICAgICAgIGNvbnNvbGUubG9nKCdpc0Vycm9yJywge3gsIHl9KVxuICAgICAgfVxuXG4gICAgICBpZiAoIWlzRXJyb3IoeCkgfHwgIWlzRXJyb3IoeSkgfHwgeC5zdGFjayAhPT0geS5zdGFjaykge1xuICAgICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dDogZGV2ICovXG4gICAgICAgIGlmIChFTlZfREVCVUcpIHtcbiAgICAgICAgICBjb25zb2xlLmxvZygnIT0gZXJyb3JzJywge3gsIHl9KVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gQE5PVEUgdGhpcyBpcyBjb3ZlcmVkIGJ5IHRvU3RyaW5nICE9IHRvU3RyaW5nXG4gICAgLy8gZWxzZSBpZiAoaXNBcnJheSh4KSAmJiAhaXNBcnJheSh5KSkge1xuICAgIC8vICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQ6IGRldiAqL1xuICAgIC8vICAgaWYgKEVOVl9ERUJVRykge1xuICAgIC8vICAgICBjb25zb2xlLmxvZygnaXNBcnJheSh4KSB8fCBpc0FycmF5KHkpIScpXG4gICAgLy8gICB9XG4gICAgLy9cbiAgICAvLyAgIHJldHVybiBmYWxzZVxuICAgIC8vIH1cbiAgICAvLyBlbHNlIGlmICghaXNBcnJheSh4KSAmJiBpc0FycmF5KHkpKSB7XG4gICAgLy8gICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dDogZGV2ICovXG4gICAgLy8gICBpZiAoRU5WX0RFQlVHKSB7XG4gICAgLy8gICAgIGNvbnNvbGUubG9nKCchaXNBcnJheSh4KSAmJiBpc0FycmF5KHkpOicpXG4gICAgLy8gICB9XG4gICAgLy9cbiAgICAvLyAgIHJldHVybiBmYWxzZVxuICAgIC8vIH1cblxuICAgIC8vIEBUT0RPIGNvbnNpZGVyaW5nLCB3ZSBhbHJlYWR5IGtub3cgaXQgaXMgbm90IG51bGwgJiB1bmRlZmluZWRcbiAgICAvLyBpZiAoaXNQcmltaXRpdmUoeCkgfHwgaXNQcmltaXRpdmUoeSkpIHtcbiAgICAvLyAgcmV0dXJuIHgudmFsdWVPZigpID09PSB5LnZhbHVlT2YoKVxuICAgIC8vIH1cblxuICAgIGVsc2Uge1xuICAgICAgLy8gQFRPRE8gT2JqZWN0T3JBcnJheUtleXMsIGJ1dCBoYXZlIHRvIGhhdmUgZWxzZSB3aGVyZSB0aGV5IGFyZSBib3RoIGFycmF5XG4gICAgICAvL1xuICAgICAgLy8gQE5PVEUgaXQgd2lsbCB0cmF2ZXJzZSB0aHJvdWdoIHZhbHVlcyBpZiB0aGV5IGFyZSA9PSBoZXJlXG4gICAgICBjb25zdCB4S2V5cyA9IE9iamVjdEtleXMoeClcbiAgICAgIGNvbnN0IHlLZXlzID0gT2JqZWN0S2V5cyh5KS5sZW5ndGhcblxuICAgICAgLy8gZGlmZiBsZW5ndGhcbiAgICAgIGlmICh4S2V5cy5sZW5ndGggIT09IHlLZXlzKSB7XG4gICAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0OiBkZXYgKi9cbiAgICAgICAgaWYgKEVOVl9ERUJVRykge1xuICAgICAgICAgIGNvbnNvbGUubG9nKCchPSBvYmoga2V5IGxlbmd0aCcsIHt4S2V5cywgeUtleXN9KVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgICB9XG5cbiAgICAgIGZvciAobGV0IGsgPSAwOyBrIDwgeEtleXMubGVuZ3RoOyBrKyspIHtcbiAgICAgICAgaWYgKCFoYXNPd25Qcm9wZXJ0eSh5LCB4S2V5c1trXSkpIHtcbiAgICAgICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dDogZGV2ICovXG4gICAgICAgICAgaWYgKEVOVl9ERUJVRykge1xuICAgICAgICAgICAgY29uc29sZS5sb2coJyE9IG9iaiBwcm9wZXJ0eScsIHt5LCB2YWw6IHhLZXlzW2tdfSlcbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZXR1cm4gZmFsc2VcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuICBlbHNlIGlmICh0b1MoeCkgPT09IHRvUyh5KSAmJiB4ICE9PSB5KSB7XG4gICAgLy8gaXNTdHJpbmcoeCkgfHwgaXNCb29sZWFuKHgpIHx8IGlzTnVtYmVyKHgpIHx8IGlzSXRlcmF0b3IoeClcbiAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dDogZGV2ICovXG4gICAgaWYgKEVOVl9ERUJVRykge1xuICAgICAgY29uc29sZS5sb2coJ3NhbWUgc3RyIHR5cGVzIC0gZGlmZiB2YWx1ZXMnLCB7czogdG9TKHgpLCB4LCB5fSlcbiAgICB9XG5cbiAgICByZXR1cm4gZmFsc2VcbiAgfVxuICAvLyAvLyBAVE9ETyBwdXQgdGhpcyB1cCBmaXJzdD9cbiAgLy8gZWxzZSBpZiAodG9TKHgpICE9PSB0b1MoeSkpIHtcbiAgLy8gICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dDogZGV2ICovXG4gIC8vICAgaWYgKEVOVl9ERUJVRykge1xuICAvLyAgICAgY29uc29sZS5sb2coJ2RpZmYgc3RyIHR5cGVzJywge3g6IHRvUyh4KSwgeTogdG9TKHkpfSlcbiAgLy8gICB9XG4gIC8vXG4gIC8vICAgcmV0dXJuIGZhbHNlXG4gIC8vIH1cblxuICAvLyBnbyBkZWVwZXJcbiAgZWxzZSBpZiAoaXNGdW5jdGlvbih4KSB8fCBpc0Z1bmN0aW9uKHkpKSB7XG4gICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQ6IGRldiAqL1xuICAgIGlmIChFTlZfREVCVUcpIHtcbiAgICAgIGNvbnNvbGUubG9nKCdpc0Z1bmN0aW9uKHgpICYmIGlzRnVuY3Rpb24oeSk6JylcbiAgICAgIGNvbnNvbGUubG9nKHgudG9TdHJpbmcoKSlcbiAgICAgIGNvbnNvbGUubG9nKHkudG9TdHJpbmcoKSlcbiAgICB9XG5cbiAgICBpZiAoaXNOb3RSZWFsT3JOb3RFcVRvU3RyaW5nKHgsIHkpKSB7XG4gICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dDogZGV2ICovXG4gICAgICBpZiAoRU5WX0RFQlVHKSB7XG4gICAgICAgIGNvbnNvbGUubG9nKCd4LnRvU3RyaW5nKCkgIT09IHkudG9TdHJpbmcoKScsIHgudG9TdHJpbmcoKSAhPT0geS50b1N0cmluZygpKVxuICAgICAgfVxuICAgICAgcmV0dXJuIGZhbHNlXG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgcmV0dXJuIHRydWVcbiAgICB9XG4gIH1cbiAgLy8gQFRPRE8gd2h5P1xuICBlbHNlIGlmIChpc09iaih4KSAmJiBpc09iaih5KSkge1xuICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0OiBkZXYgKi9cbiAgICBpZiAoRU5WX0RFQlVHKSB7XG4gICAgICBjb25zb2xlLmxvZygnaXNPYmooeCkgJiYgaXNPYmooeSk6JylcbiAgICB9XG5cbiAgICByZXR1cm4gZmFsc2VcbiAgfVxuICAvLyBlbHNlIHtcbiAgLyogaXN0YW5idWwgaWdub3JlIG5leHQ6IGRldiAqL1xuICBpZiAoRU5WX0RFQlVHKSB7XG4gICAgY29uc29sZS5sb2coJ2VxZXFlcTonLCB7W3RvUyh4KSArICdYJ106IHgsIFt0b1MoeSkgKyAnWSddOiB5fSlcbiAgfVxuICByZXR1cm4gdHJ1ZVxuICAvLyB9XG59XG4iXSwibmFtZXMiOlsiY29uc3QiLCJsZXQiXSwibWFwcGluZ3MiOiJBQUFBOzs7OztBQUtBQSxHQUFLLENBQUMsWUFBWSxHQUFHLE9BQU8sQ0FBQyxrQkFBa0IsQ0FBQztBQUNoREEsR0FBSyxDQUFDLGlCQUFpQixHQUFHLE9BQU8sQ0FBQyx1QkFBdUIsQ0FBQztBQUMxREEsR0FBSyxDQUFDLFVBQVUsR0FBRyxPQUFPLENBQUMsZ0JBQWdCLENBQUM7QUFDNUNBLEdB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