Source: BinaryStorage.js

(function() {
    /**
     * Binary storage
     * @augments Help4.jscore.Base
     */
    Help4.BinaryStorage = class extends Help4.jscore.Base {
        /**
         * @override
         * @param {string[]} keys
         * @param {string} [value = undefined]
         */
        constructor(keys, value = undefined) {
            const {BinaryStorage} = Help4;

            super({
                statics: {
                    _map:   {init: BinaryStorage.createInternalMap(keys), destroy: false},
                    _sum:   {destroy: false},
                    _value: {destroy: false}
                }
            });

            const {_map} = this;
            this._sum = BinaryStorage.calcSum(_map);

            this.set(value);
        }

        /**
         * creates a binary map for all keys, e.g.
         * {
         *     <key1>: 1,
         *     <key2>: 2,
         *     <key3>: 4
         *     <key4>: 8
         *     ...
         * }
         * @param {string[]} keys
         * @returns {Object}
         */
        static createInternalMap(keys) {
            const map = {};
            let val = 1;
            for (const key of keys) {
                map[key] = val;
                val <<= 1;
            }
            return map;
        }

        /**
         * @param {Object} map
         * @returns {number}
         */
        static calcSum(map) {
            return Object.values(map).reduce((sum, number) => sum + number);
        }

        /**
         * @param {string[]} keys
         * @returns {Object}
         */
        static createPublicMap(keys) {
            const map = {};
            for (const key of keys) {
                map[key] = key;
            }
            return map;
        }

        /**
         * @param {string} value
         * @return {Help4.BinaryStorage}
         */
        set(value) {
            this._value = _clamp.call(this, value);
            return this;
        }

        /**
         * @param {string} value
         * @returns {Help4.BinaryStorage}
         */
        add(value) {
            this._value |= _clamp.call(this, value);
            return this;
        }

        /**
         * @param {string} value
         * @returns {Help4.BinaryStorage}
         */
        rem(value) {
            this._value &= this._sum - _clamp.call(this, value);
            return this;
        }

        /**
         * @param {string} value
         * @returns {boolean}
         */
        has(value) {
            return !!(this._value & _clamp.call(this, value));
        }

        /**
         * @param {string[]} values
         * @returns {boolean}
         */
        hasOneOf(values) {
            return !!values.find(value => this.has(value));
        }
    }

    /**
     * @memberof Help4.BinaryStorage#
     * @private
     * @param {string} value
     * @returns {number}
     */
    function _clamp(value) {
        return this._map[value] || 0;
    }
})();