| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191 | 'use strict';const Ref = require('./ref');const internals = {};internals.extendedCheckForValue = function (value, insensitive) {    const valueType = typeof value;    if (valueType === 'object') {        if (value instanceof Date) {            return (item) => {                return item instanceof Date && value.getTime() === item.getTime();            };        }        if (Buffer.isBuffer(value)) {            return (item) => {                return Buffer.isBuffer(item) && value.length === item.length && value.toString('binary') === item.toString('binary');            };        }    }    else if (insensitive && valueType === 'string') {        const lowercaseValue = value.toLowerCase();        return (item) => {            return typeof item === 'string' && lowercaseValue === item.toLowerCase();        };    }    return null;};module.exports = class InternalSet {    constructor(from) {        this._set = new Set(from);        this._hasRef = false;    }    add(value, refs) {        const isRef = Ref.isRef(value);        if (!isRef && this.has(value, null, null, false)) {            return this;        }        if (refs !== undefined) { // If it's a merge, we don't have any refs            Ref.push(refs, value);        }        this._set.add(value);        this._hasRef |= isRef;        return this;    }    merge(add, remove) {        for (const item of add._set) {            this.add(item);        }        for (const item of remove._set) {            this.remove(item);        }        return this;    }    remove(value) {        this._set.delete(value);        return this;    }    has(value, state, options, insensitive) {        return !!this.get(value, state, options, insensitive);    }    get(value, state, options, insensitive) {        if (!this._set.size) {            return false;        }        const hasValue = this._set.has(value);        if (hasValue) {            return { value };        }        const extendedCheck = internals.extendedCheckForValue(value, insensitive);        if (!extendedCheck) {            if (state && this._hasRef) {                for (let item of this._set) {                    if (Ref.isRef(item)) {                        item = [].concat(item(state.reference || state.parent, options));                        const found = item.indexOf(value);                        if (found >= 0) {                            return { value: item[found] };                        }                    }                }            }            return false;        }        return this._has(value, state, options, extendedCheck);    }    _has(value, state, options, check) {        const checkRef = !!(state && this._hasRef);        const isReallyEqual = function (item) {            if (value === item) {                return true;            }            return check(item);        };        for (let item of this._set) {            if (checkRef && Ref.isRef(item)) { // Only resolve references if there is a state, otherwise it's a merge                item = item(state.reference || state.parent, options);                if (Array.isArray(item)) {                    const found = item.findIndex(isReallyEqual);                    if (found >= 0) {                        return {                            value: item[found]                        };                    }                    continue;                }            }            if (isReallyEqual(item)) {                return {                    value: item                };            }        }        return false;    }    values(options) {        if (options && options.stripUndefined) {            const values = [];            for (const item of this._set) {                if (item !== undefined) {                    values.push(item);                }            }            return values;        }        return Array.from(this._set);    }    slice() {        const set = new InternalSet(this._set);        set._hasRef = this._hasRef;        return set;    }    concat(source) {        const set = new InternalSet([...this._set, ...source._set]);        set._hasRef = !!(this._hasRef | source._hasRef);        return set;    }};
 |