/**
 *  @license
 *    Copyright 2016 Brigham Young University
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 **/
'use strict';

/**
 * Toggle the case of a string based on the number value passed in.
 * @param {string} string
 * @param {number} number
 * @param {object} [options={allowOverflow: true}]
 * @returns {string|boolean}
 */
module.exports = binaryCase;

function binaryCase(string, number, options) {
    const binary = (number >>> 0).toString(2);

    if (!options || typeof options !== 'object') options = {};
    if (!options.hasOwnProperty('allowOverflow')) options.allowOverflow = true;

    if (binary.length > string.match(/[a-z]/ig).length && !options.allowOverflow) return false;

    var bin;
    var ch;
    var i;
    var j = binary.length - 1;
    var offset;
    var result = '';
    for (i = 0; i < string.length; i++) {
        ch = string.charAt(i);
        if (/[a-z]/ig.test(ch)) {
            bin = binary.charAt(j--);

            if (bin === '1') {
                offset = ch >= 'a' && ch <= 'z' ? -32 : 32;
                result += String.fromCharCode(ch.charCodeAt(0) + offset);
            } else {
                result += ch;
            }

            if (j < 0) {
                result += string.substr(i + 1);
                break;
            }
        } else {
            result += ch;
        }
    }
    return result;
}

/**
 * Get the maximum number that can be used before causing overflow.
 * @param {string} string
 * @returns {number}
 */
binaryCase.maxNumber = function(string) {
    const pow = string.match(/[a-z]/ig).length;
    return Math.pow(2, pow) - 1;
};

/**
 * Get an array of all possible variations.
 * @param {string} string
 * @returns {string[]}
 */
binaryCase.variations = function(string) {
    const results = [];
    const max = binaryCase.maxNumber(string);
    for (var i = 0; i <= max; i++) {
        results.push(binaryCase(string, i));
    }
    return results;
};
@@ -954,290 +954,1642 @@
     
-const binary = (number %3E%3E%3E 0).toString(2);%0A%0A    if (!options %7C%7C typeof options !== 'object') options = %7B%7D;%0A    if (!options.hasOwnProperty('allowOverflow')) options.allowOverflow = true;%0A%0A    if (binary.length %3E string.match(/%5Ba-z%5D/ig).length && !options.allowOverflow) return false
+if (!options %7C%7C typeof options !== 'object') options = %7B%7D;%0A    if (!options.hasOwnProperty('allowOverflow')) options.allowOverflow = true;%0A%0A    if (number %3E binaryCase.maxNumber(string) && !options.allowOverflow) return false;%0A%0A    return getBinaryCase(string, number);%0A%7D%0A%0AbinaryCase.iterator = function(string, options) %7B%0A    const max = binaryCase.maxNumber(string);%0A%0A    if (!options %7C%7C typeof options !== 'object') options = %7B%7D;%0A    if (!options.hasOwnProperty('startIndex')) options.startIndex = 0;%0A    if (typeof options.startIndex !== 'number' %7C%7C !Number.isInteger(options.startIndex) && options.startIndex %3C 0) throw Error('Option startIndex must be a non-negative integer.');%0A%0A    var index = options && typeof options === 'object' ? options.startIndex %7C%7C 0 : 0;%0A    return %7B%0A        next: function() %7B%0A            return index %3E max%0A                ? %7B done: true %7D%0A                : %7B done: false, value: getBinaryCase(string, index++) %7D;%0A        %7D%0A    %7D;%0A%7D;%0A%0A/**%0A * Get the maximum number that can be used before causing overflow.%0A * @param %7Bstring%7D string%0A * @returns %7Bnumber%7D%0A */%0AbinaryCase.maxNumber = function(string) %7B%0A    const pow = string.match(/%5Ba-z%5D/ig).length;%0A    return Math.pow(2, pow) - 1;%0A%7D;%0A%0A/**%0A * Get an array of all possible variations.%0A * @param %7Bstring%7D string%0A * @returns %7Bstring%5B%5D%7D%0A */%0AbinaryCase.variations = function(string) %7B%0A    const results = %5B%5D;%0A    const max = binaryCase.maxNumber(string);%0A    for (var i = 0; i %3C= max; i++) %7B%0A        results.push(binaryCase(string, i));%0A    %7D%0A    return results;%0A%7D;%0A%0A%0Afunction getBinaryCase(string, number) %7B%0A    const binary = (number %3E%3E%3E 0).toString(2)
 ;%0A%0A 
@@ -3261,580 +3261,4 @@
 t;%0A%7D
-%0A%0A/**%0A * Get the maximum number that can be used before causing overflow.%0A * @param %7Bstring%7D string%0A * @returns %7Bnumber%7D%0A */%0AbinaryCase.maxNumber = function(string) %7B%0A    const pow = string.match(/%5Ba-z%5D/ig).length;%0A    return Math.pow(2, pow) - 1;%0A%7D;%0A%0A/**%0A * Get an array of all possible variations.%0A * @param %7Bstring%7D string%0A * @returns %7Bstring%5B%5D%7D%0A */%0AbinaryCase.variations = function(string) %7B%0A    const results = %5B%5D;%0A    const max = binaryCase.maxNumber(string);%0A    for (var i = 0; i %3C= max; i++) %7B%0A        results.push(binaryCase(string, i));%0A    %7D%0A    return results;%0A%7D;

add iterator method