<commit_before>/* global jsep */

(function () {
    window.quest = window.quest || {};

    jsep.removeUnaryOp('~');
    jsep.addUnaryOp('not');

    jsep.removeBinaryOp('>>>');
    jsep.removeBinaryOp('<<');
    jsep.removeBinaryOp('>>');

    jsep.removeBinaryOp('==');
    jsep.removeBinaryOp('===');
    jsep.removeBinaryOp('!==');
    jsep.addBinaryOp('=', 6);
    jsep.addBinaryOp('<>');

    jsep.addBinaryOp('^', 10);

    jsep.removeBinaryOp('||');
    jsep.removeBinaryOp('|');
    jsep.addBinaryOp('or', 1);

    jsep.removeBinaryOp('&&');
    jsep.removeBinaryOp('&');
    jsep.addBinaryOp('and', 2);

    window.quest.load = function (data) {
        // TODO: Eventually this will be called with a full .aslx file
        // (Note - only a single file from a .quest, we don't need to worry ever about including
        // external libraries)

        var script = parseScript(data);
        executeScript(script);
    };

    var commands = {
        'msg': {
            parameters: [1],
            execute: function (ctx) {
                evaluateExpression(ctx.parameters[0], function (result) {
                    console.log(result);
                    ctx.complete();
                });
            }
        },
        'if': {
            create: function (line) {
                var parameters = getParameterInternal(line, '(', ')');
                var thenScript = parseScript(parameters.after);

                return {
                    expression: parseExpression(parameters.parameter),
                    then: thenScript
                };
            },
            execute: function (ctx) {
                evaluateExpression(ctx.parameters.expression, function (result) {
                    if (result) {
                        // TODO: Run "then" script (add it to the callstack)
                    }
                    else {
                        // TODO: Run "else" script if it exists
                    }
                    ctx.complete();
                });
            }
        }
    };

    var getScript = function (line) {
        // based on WorldModel.ScriptFactory.GetScriptConstructor

        var command, keyword, parameters;

        for (var candidate in commands) {
            if (line.substring(0, candidate.length) === candidate) {
                // TODO: Must be non-word character afterwards, see original function
                keyword = candidate;
                command = commands[candidate];
            }
        }

        if (!command) return null;

        if (command.create) {
            parameters = command.create(line);
        }
        else {
            parameters = parseParameters(splitParameters(line));
            if (command.parameters.indexOf(parameters.length) === -1) {
                throw 'Expected ' + command.parameters.join(',') + ' parameters in command: ' + line;
            }
        }

        return {
            keyword: keyword,
            command: command,
            line: line,
            parameters: parameters
        };
    };

    var parseScript = function (text) {
        text = removeSurroundingBraces(text);

        var result = [];
        while (true) {
            var scriptLine = getScriptLine(text);

            if (!scriptLine) break;
            if (scriptLine.line.length !== 0) {
                var script = getScript(scriptLine.line);

                if (!script) {
                    console.log('Unrecognised script command: ' + scriptLine.line);
                }
                else {
                    result.push(script);
                }
            }

            if (!scriptLine.after) break;
            text = scriptLine.after;
        }

        return result;
    };

    var removeSurroundingBraces = function (text) {
        // based on WorldModel.Utility.RemoveSurroundingBraces

        text = text.trim();
        if (text.substring(0, 1) === '{' && text.substring(text.length - 1, text.length) === '}') {
            return text.substring(1, text.length - 1);
        }
        return text;
    };

    var getScriptLine = function (text) {
        // based on WorldModel.Utility.GetScript
        // return one line of the script, and the remaining script

        var result;
        var obscuredScript = obscureStrings(text);
        var bracePos = obscuredScript.indexOf('{');
        var crlfPos = obscuredScript.indexOf('\n');
        var commentPos = obscuredScript.indexOf('//');
        if (crlfPos === -1) return {
            line: text.trim()
        };

        if (bracePos === - 1 || crlfPos < bracePos || (commentPos !== -1 && commentPos < bracePos && commentPos < crlfPos)) {
            return {
                line: text.substring(0, crlfPos).trim(),
                after: text.substring(crlfPos + 1)
            };
        }

        var beforeBrace = text.substring(0, bracePos);
        var parameterResult = getParameterInternal(text, '{', '}');
        var insideBraces = parameterResult.parameter;

        if (insideBraces.indexOf('\n') !== -1) {
            result = beforeBrace + '{' + insideBraces + '}';
        }
        else {
            result = beforeBrace + insideBraces;
        }

        return {
            line: result.trim(),
            after: parameterResult.after
        };
    };

    var splitParameters = function (text) {
        var parameter = getParameter(text);
        if (!parameter) return [];

        // based on WorldModel.Utility.SplitParameter
        var result = [];
        var inQuote = false;
        var processNextCharacter = true;
        var bracketCount = 0;
        var curParam = [];

        for (var i = 0; i < parameter.length; i++) {
            var c = parameter.charAt(i);
            var processThisCharacter = processNextCharacter;
            processNextCharacter = true;

            if (processThisCharacter) {
                if (c === '\\') {
                    // Don't process the character after a backslash
                    processNextCharacter = false;
                }
                else if (c === '"') {
                    inQuote = !inQuote;
                }
                else {
                    if (!inQuote) {
                        if (c === '(') bracketCount++;
                        if (c === ')') bracketCount--;
                        if (bracketCount === 0 && c === ',') {
                            result.push(curParam.join(''));
                            curParam = [];
                            continue;
                        }
                    }
                }
            }

            curParam.push(c);
        }

        result.push(curParam.join('').trim());
        return result;
    };

    var getParameter = function (text) {
        var result = getParameterInternal(text, '(', ')');
        if (!result) return null;
        return result.parameter;
    };

    var getParameterInternal = function (text, open, close) {
        // based on WorldModel.Utility.GetParameterInt

        var obscuredText = obscureStrings(text);
        var start = obscuredText.indexOf(open);
        if (start === -1) return null;

        var finished = false;
        var braceCount = 1;
        var pos = start;

        while (!finished) {
            pos++;
            var curChar = obscuredText.charAt(pos);
            if (curChar === open) braceCount++;
            if (curChar === close) braceCount--;
            if (braceCount === 0 || pos === obscuredText.length - 1) finished = true;
        }

        if (braceCount !== 0) {
            throw 'Missing ' + close;
        }

        return {
            parameter: text.substring(start + 1, pos),
            after: text.substring(pos + 1)
        };
    };

    var obscureStrings = function (input) {
        // based on WorldModel.Utility.ObscureStrings

        var sections = splitQuotes(input);
        var result = [];

        var insideQuote = false;
        for (var i = 0; i < sections.length; i++) {
            var section = sections[i];
            if (insideQuote) {
                result.push(Array(section.length + 1).join('-'));
            }
            else {
                result.push(section);
            }
            if (i < sections.length - 1) {
                result.push('"');
            }
            insideQuote = !insideQuote;
        }
        return result.join('');
    };

    var splitQuotes = function (text) {
        // based on WorldModel.Utility.SplitQuotes

        var result = [];
        var processNextCharacter = true;
        var curParam = [];
        var gotCloseQuote = true;

        for (var i = 0; i < text.length; i++) {
            var curChar = text.charAt(i);

            var processThisCharacter = processNextCharacter;
            processNextCharacter = true;

            if (processThisCharacter) {
                if (curChar === '\\') {
                    // Don't process the character after a backslash
                    processNextCharacter = false;
                }
                else if (curChar === '"') {
                    result.push(curParam.join(''));
                    gotCloseQuote = !gotCloseQuote;
                    curParam = [];
                    continue;
                }
            }

            curParam.push(curChar);
        }

        if (!gotCloseQuote) {
            throw 'Missing quote character in ' + text;
        }

        result.push(curParam.join(''));
        return result;
    };

    var parseExpression = function (expr) {
        return {
            expr: expr,
            tree: jsep(expr)
        };
    };

    var parseParameters = function (parameters) {
        return parameters.map(parseExpression);
    };

    var callstack = [];

    var executeScript = function (script) {
        if (callstack.length !== 0) {
            throw 'Existing callstack is not empty';
        }

        callstack = [{
            script: script,
            index: 0,
            locals: {},
        }];

        executeNext();
    };

    var executeNext = function () {
        if (callstack.length === 0) return;

        var frame = callstack[callstack.length - 1];
        var script = frame.script[frame.index++];

        script.command.execute({
            parameters: script.parameters,
            locals: frame.locals,
            complete: function () {
                if (frame.index === frame.script.length) {
                    callstack.pop();
                }

                executeNext();
            }
        });
    };

    var evaluateExpression = function (expr, complete) {
        //console.log(expr);
        var result = "TODO!";
        complete(result);
    };
})();<commit_msg>Adding expression evaluation<commit_after>/* global jsep */

(function () {
    window.quest = window.quest || {};

    jsep.removeUnaryOp('~');
    jsep.addUnaryOp('not');

    jsep.removeBinaryOp('>>>');
    jsep.removeBinaryOp('<<');
    jsep.removeBinaryOp('>>');

    jsep.removeBinaryOp('==');
    jsep.removeBinaryOp('===');
    jsep.removeBinaryOp('!==');
    jsep.addBinaryOp('=', 6);
    jsep.addBinaryOp('<>');

    jsep.addBinaryOp('^', 10);

    jsep.removeBinaryOp('||');
    jsep.removeBinaryOp('|');
    jsep.addBinaryOp('or', 1);

    jsep.removeBinaryOp('&&');
    jsep.removeBinaryOp('&');
    jsep.addBinaryOp('and', 2);

    window.quest.load = function (data) {
        // TODO: Eventually this will be called with a full .aslx file
        // (Note - only a single file from a .quest, we don't need to worry ever about including
        // external libraries)

        var script = parseScript(data);
        executeScript(script);
    };

    var commands = {
        'msg': {
            parameters: [1],
            execute: function (ctx) {
                evaluateExpression(ctx.parameters[0], function (result) {
                    console.log(result);
                    ctx.complete();
                });
            }
        },
        'if': {
            create: function (line) {
                var parameters = getParameterInternal(line, '(', ')');
                var thenScript = parseScript(parameters.after);

                return {
                    expression: parseExpression(parameters.parameter),
                    then: thenScript
                };
            },
            execute: function (ctx) {
                evaluateExpression(ctx.parameters.expression, function (result) {
                    if (result) {
                        // TODO: Run "then" script (add it to the callstack)
                    }
                    else {
                        // TODO: Run "else" script if it exists
                    }
                    ctx.complete();
                });
            }
        }
    };

    var getScript = function (line) {
        // based on WorldModel.ScriptFactory.GetScriptConstructor

        var command, keyword, parameters;

        for (var candidate in commands) {
            if (line.substring(0, candidate.length) === candidate) {
                // TODO: Must be non-word character afterwards, see original function
                keyword = candidate;
                command = commands[candidate];
            }
        }

        if (!command) return null;

        if (command.create) {
            parameters = command.create(line);
        }
        else {
            parameters = parseParameters(splitParameters(line));
            if (command.parameters.indexOf(parameters.length) === -1) {
                throw 'Expected ' + command.parameters.join(',') + ' parameters in command: ' + line;
            }
        }

        return {
            keyword: keyword,
            command: command,
            line: line,
            parameters: parameters
        };
    };

    var parseScript = function (text) {
        text = removeSurroundingBraces(text);

        var result = [];
        while (true) {
            var scriptLine = getScriptLine(text);

            if (!scriptLine) break;
            if (scriptLine.line.length !== 0) {
                var script = getScript(scriptLine.line);

                if (!script) {
                    console.log('Unrecognised script command: ' + scriptLine.line);
                }
                else {
                    result.push(script);
                }
            }

            if (!scriptLine.after) break;
            text = scriptLine.after;
        }

        return result;
    };

    var removeSurroundingBraces = function (text) {
        // based on WorldModel.Utility.RemoveSurroundingBraces

        text = text.trim();
        if (text.substring(0, 1) === '{' && text.substring(text.length - 1, text.length) === '}') {
            return text.substring(1, text.length - 1);
        }
        return text;
    };

    var getScriptLine = function (text) {
        // based on WorldModel.Utility.GetScript
        // return one line of the script, and the remaining script

        var result;
        var obscuredScript = obscureStrings(text);
        var bracePos = obscuredScript.indexOf('{');
        var crlfPos = obscuredScript.indexOf('\n');
        var commentPos = obscuredScript.indexOf('//');
        if (crlfPos === -1) return {
            line: text.trim()
        };

        if (bracePos === - 1 || crlfPos < bracePos || (commentPos !== -1 && commentPos < bracePos && commentPos < crlfPos)) {
            return {
                line: text.substring(0, crlfPos).trim(),
                after: text.substring(crlfPos + 1)
            };
        }

        var beforeBrace = text.substring(0, bracePos);
        var parameterResult = getParameterInternal(text, '{', '}');
        var insideBraces = parameterResult.parameter;

        if (insideBraces.indexOf('\n') !== -1) {
            result = beforeBrace + '{' + insideBraces + '}';
        }
        else {
            result = beforeBrace + insideBraces;
        }

        return {
            line: result.trim(),
            after: parameterResult.after
        };
    };

    var splitParameters = function (text) {
        var parameter = getParameter(text);
        if (!parameter) return [];

        // based on WorldModel.Utility.SplitParameter
        var result = [];
        var inQuote = false;
        var processNextCharacter = true;
        var bracketCount = 0;
        var curParam = [];

        for (var i = 0; i < parameter.length; i++) {
            var c = parameter.charAt(i);
            var processThisCharacter = processNextCharacter;
            processNextCharacter = true;

            if (processThisCharacter) {
                if (c === '\\') {
                    // Don't process the character after a backslash
                    processNextCharacter = false;
                }
                else if (c === '"') {
                    inQuote = !inQuote;
                }
                else {
                    if (!inQuote) {
                        if (c === '(') bracketCount++;
                        if (c === ')') bracketCount--;
                        if (bracketCount === 0 && c === ',') {
                            result.push(curParam.join(''));
                            curParam = [];
                            continue;
                        }
                    }
                }
            }

            curParam.push(c);
        }

        result.push(curParam.join('').trim());
        return result;
    };

    var getParameter = function (text) {
        var result = getParameterInternal(text, '(', ')');
        if (!result) return null;
        return result.parameter;
    };

    var getParameterInternal = function (text, open, close) {
        // based on WorldModel.Utility.GetParameterInt

        var obscuredText = obscureStrings(text);
        var start = obscuredText.indexOf(open);
        if (start === -1) return null;

        var finished = false;
        var braceCount = 1;
        var pos = start;

        while (!finished) {
            pos++;
            var curChar = obscuredText.charAt(pos);
            if (curChar === open) braceCount++;
            if (curChar === close) braceCount--;
            if (braceCount === 0 || pos === obscuredText.length - 1) finished = true;
        }

        if (braceCount !== 0) {
            throw 'Missing ' + close;
        }

        return {
            parameter: text.substring(start + 1, pos),
            after: text.substring(pos + 1)
        };
    };

    var obscureStrings = function (input) {
        // based on WorldModel.Utility.ObscureStrings

        var sections = splitQuotes(input);
        var result = [];

        var insideQuote = false;
        for (var i = 0; i < sections.length; i++) {
            var section = sections[i];
            if (insideQuote) {
                result.push(Array(section.length + 1).join('-'));
            }
            else {
                result.push(section);
            }
            if (i < sections.length - 1) {
                result.push('"');
            }
            insideQuote = !insideQuote;
        }
        return result.join('');
    };

    var splitQuotes = function (text) {
        // based on WorldModel.Utility.SplitQuotes

        var result = [];
        var processNextCharacter = true;
        var curParam = [];
        var gotCloseQuote = true;

        for (var i = 0; i < text.length; i++) {
            var curChar = text.charAt(i);

            var processThisCharacter = processNextCharacter;
            processNextCharacter = true;

            if (processThisCharacter) {
                if (curChar === '\\') {
                    // Don't process the character after a backslash
                    processNextCharacter = false;
                }
                else if (curChar === '"') {
                    result.push(curParam.join(''));
                    gotCloseQuote = !gotCloseQuote;
                    curParam = [];
                    continue;
                }
            }

            curParam.push(curChar);
        }

        if (!gotCloseQuote) {
            throw 'Missing quote character in ' + text;
        }

        result.push(curParam.join(''));
        return result;
    };

    var parseExpression = function (expr) {
        return {
            expr: expr,
            tree: jsep(expr)
        };
    };

    var parseParameters = function (parameters) {
        return parameters.map(parseExpression);
    };

    var callstack = [];

    var executeScript = function (script) {
        if (callstack.length !== 0) {
            throw 'Existing callstack is not empty';
        }

        callstack = [{
            script: script,
            index: 0,
            locals: {},
        }];

        executeNext();
    };

    var executeNext = function () {
        if (callstack.length === 0) return;

        var frame = callstack[callstack.length - 1];
        var script = frame.script[frame.index++];

        script.command.execute({
            parameters: script.parameters,
            locals: frame.locals,
            complete: function () {
                if (frame.index === frame.script.length) {
                    callstack.pop();
                }

                executeNext();
            }
        });
    };

    var currentExpression;

    var evaluateExpression = function (expr, complete) {
        currentExpression = {
            stack: [expr.tree],
            doneLeft: false,
            stackResult: function (result) {
                currentExpression.stack.pop();
                currentExpression.doneLeft = false;
                if (currentExpression.stack.length === 0) {
                    complete(result);
                }
            }
        };

        evaluateNext();
    };

    var evaluateNext = function () {
        var tree = currentExpression.stack[currentExpression.stack.length - 1];
        console.log(tree);
        switch (tree.type) {
            case 'Literal':
                currentExpression.stackResult(tree.value);
                break;
            default:
                throw 'Unknown expression tree type: ' + tree.type;
        }
    };
})();<|endoftext|>


<commit_before>(function ($) {
    "use strict";

    try {
        Object.defineProperties($, {

            // greatest common divisor
            GCD: {
                value: function () {
                    var
                        remains,
                        primeFactor = 2,
                        product = 1,
                        i = 0,
                        numbers = [],
                        count = 0,

                        euclidesAlgorithm = function(a, b) {
                            var
                                rest = b;

                            while(rest !== 0) {
                               rest = a % b;
                               a = b;
                               b = rest;
                            }

                            return a;
                        },

                        everyoneAreMultipleOf = function(remains, primeFactor) {
                            var
                                i = 0;

                            while(i < remains.length) {
                                if (!remains[i++].multipleOf(primeFactor)) {
                                    return false;
                                }
                            }

                            return true;
                        },

                        hasSomeMultipleOf = function(remains, primeFactor) {
                            var
                                i = 0;

                            while(i < remains.length) {
                                if (remains[i++].multipleOf(primeFactor)) {
                                    return true;
                                }
                            }

                            return false;
                        };

                    numbers = Array.from(arguments);
                    numbers = numbers.uniq();
                    if(numbers.length == 1) {
                        return numbers[0];
                    }

                    // properties

                    // se todos os números forem múltiplos entre si, o MDC será menor deles
                    if(numbers.areMultiples()) {return numbers.min();}

                    // o algorítmo de Euclides é mais eficiente para calcular o MDC entre apenas dois números
                    if(numbers.length == 2) {
                        return euclidesAlgorithm(numbers[0], numbers[1]);
                    }

                    // dois números primos não são múltiplos entre si
                    i = 0;
                    while(true) {
                        if((numbers[i]).isPrime()) {count++;}
                        if(count >= 2) {return 1;}
                        if(i == numbers.length -1) {break;}
                        i++;
                    }

                    remains = numbers.clone();

                    while(remains.count(1) != remains.length) {
                        if(everyoneAreMultipleOf(remains, primeFactor)) {
                            product *= primeFactor;
                        }

                        i = 0;
                        while(i < remains.length) {
                            if (remains[i].multipleOf(primeFactor)) {
                                remains[i] /= primeFactor;
                            }
                            i++;
                        }

                        if(!hasSomeMultipleOf(remains, primeFactor)) {
                            primeFactor = primeFactor.nextPrimeFactor();
                        }
                    }

                    return product;
                }
            },

            // TODO: revisar
            // least common multiple
            LCM: {
                value: function () {
                    var
                        numbers = [],
                        primeFactors = [],
                        commonFactors = [],
                        nonCommonfactors = [],
                        biggerFactorsHash = {},
                        i = 0,
                        biggerCommonProduct = 1,
                        noCommonFactors = 1,

                        for2Factors = function(numbers) {
                            var
                                product = 1;

                            numbers.forEach(function (v) {
                                product *= v;
                            });

                            return product/Math.GCD.apply(null, numbers);
                        };

                    numbers = Array.from(arguments);
                    numbers = numbers.uniq();
                    if(numbers.length == 1) {
                        return numbers[0];
                    }

                    if(numbers.areMultiples()) {return numbers.max();}

                    if(numbers.length == 2) {return for2Factors(numbers);}

                    numbers.forEach(function (v) {
                        primeFactors.push(v.primeFactors());
                    });

                    commonFactors = primeFactors.intersection();

                    primeFactors.forEach(function (a) {
                        commonFactors.forEach(function (v) {
                            if(!biggerFactorsHash[v]) {
                                biggerFactorsHash[v] = a.count(v);
                            } else {
                                if(a.count(v) > biggerFactorsHash[v]) {
                                    biggerFactorsHash[v] = a.count(v);
                                }
                            }
                        });
                    });

                    for(i in biggerFactorsHash) {
                        if (biggerFactorsHash.hasOwnProperty(i)) {
                                biggerCommonProduct *= Math
                                    .pow(i, biggerFactorsHash[i]);
                        }
                    }

                    nonCommonfactors = primeFactors.flatten().uniq()
                        .differences(commonFactors);

                    nonCommonfactors.forEach(function (v) {
                        noCommonFactors *= v;
                    });

                    return biggerCommonProduct * noCommonFactors;
                }
            }

        });

    } catch(e) {}

})(Math);

// Simone 2002
// Sem Limite (com Robert De Niro)
<commit_msg>refactor LCM<commit_after>(function ($) {
    "use strict";

    var
        hasSomeMultipleOf = function(remains, primeFactor) {
            var
                i = 0;

            while(i < remains.length) {
                if (remains[i++].multipleOf(primeFactor)) {
                    return true;
                }
            }

            return false;
        };

    try {
        Object.defineProperties($, {

            // greatest common divisor
            GCD: {
                value: function () {
                    var
                        remains = [],
                        primeFactor = 2,
                        product = 1,
                        i = 0,
                        count = 0,

                        euclidesAlgorithm = function(a, b) {
                            var
                                rest = b;

                            while(rest !== 0) {
                               rest = a % b;
                               a = b;
                               b = rest;
                            }

                            return a;
                        },

                        everyoneAreMultipleOf = function(remains, primeFactor) {
                            var
                                i = 0;

                            while(i < remains.length) {
                                if (!remains[i++].multipleOf(primeFactor)) {
                                    return false;
                                }
                            }

                            return true;
                        };

                    remains = Array.from(arguments);
                    remains = remains.uniq();
                    if(remains.length == 1) {
                        return remains[0];
                    }

                    // properties

                    // se todos os números forem múltiplos entre si, o MDC será menor deles
                    if(remains.areMultiples()) {return remains.min();}

                    // o algorítmo de Euclides é mais eficiente para calcular o MDC entre apenas dois números
                    if(remains.length == 2) {
                        return euclidesAlgorithm(remains[0], remains[1]);
                    }

                    // dois números primos não são múltiplos entre si
                    i = 0;
                    while(true) {
                        if((remains[i]).isPrime()) {count++;}
                        if(count >= 2) {return 1;}
                        if(i == remains.length -1) {break;}
                        i++;
                    }

                    while(remains.count(1) != remains.length) {
                        if(everyoneAreMultipleOf(remains, primeFactor)) {
                            product *= primeFactor;
                        }

                        i = 0;
                        while(i < remains.length) {
                            if (remains[i].multipleOf(primeFactor)) {
                                remains[i] /= primeFactor;
                            }
                            i++;
                        }

                        if(!hasSomeMultipleOf(remains, primeFactor)) {
                            primeFactor = primeFactor.nextPrimeFactor();
                        }
                    }

                    return product;
                }
            },

            // least common multiple
            LCM: {
                value: function () {
                    var
                        product = 1,
                        remains = [],
                        primeFactor = 2,
                        i = 0,

                        for2Factors = function(numbers) {
                            var
                                product = 1;

                            numbers.forEach(function (v) {
                                product *= v;
                            });

                            return product/Math.GCD.apply(null, numbers);
                        };

                    remains = Array.from(arguments);
                    remains = remains.uniq();
                    if(remains.length == 1) {
                        return remains[0];
                    }

                    if(remains.areMultiples()) {return remains.max();}

                    if(remains.length == 2) {return for2Factors(remains);}

                    while(remains.count(1) != remains.length) {
                        product *= primeFactor;

                        i = 0;
                        while(i < remains.length) {
                            if (remains[i].multipleOf(primeFactor)) {
                                remains[i] /= primeFactor;
                            }
                            i++;
                        }

                        if(!hasSomeMultipleOf(remains, primeFactor)) {
                            primeFactor = primeFactor.nextPrimeFactor();
                        }
                    }

                    return product;
                }
            }

        });

    } catch(e) {}

})(Math);
<|endoftext|>


<commit_before>import _ from 'lodash';

import React from 'react';

import memoize from 'memoizee';
import emojify from 'emojify.js';
import emojiCharacters from 'emoji-named-characters';

import Markdown from 'utils/Markdown';

const inversedEmojiCharacters = _.invert(_.mapValues(emojiCharacters, (e) => e.character));

emojify.setConfig({
  mode: 'img',
  img_dir: 'assets/img/emoji' // eslint-disable-line
});

const emojiVariants = _.map(Object.keys(inversedEmojiCharacters), function (name) {
  return name.replace(/\+/g, '\\+');
});

const emojiRegexp = new RegExp('(' + emojiVariants.join('|') + ')', 'gi');

const processText = function (text) {
  let markedText = Markdown.default(text);

  // need hack with replace because of https://github.com/Ranks/emojify.js/issues/127
  const noPTag = markedText.replace(/
/g, '
 ');

  let emojifiedText = emojify
    .replace(noPTag.replace(emojiRegexp, (match) => ':' + inversedEmojiCharacters[match] + ':'));

  return emojifiedText;
};

const memoizedProcessText = memoize(processText, {
  length: 1000,
  maxAge: 60 * 60 * 1000,
  max: 10000
});

class Text extends React.Component {
  static propTypes = {
    content: React.PropTypes.object.isRequired,
    className: React.PropTypes.string
  };

  constructor(props) {
    super(props);
  }

  render() {
    const { content, className } = this.props;

    let renderedContent;

    if (content.markdownText !== null) {
      renderedContent =

;
    } else {
      renderedContent =

          {content.text}

;
    }

    return renderedContent;
  }
}

export default Text;
<commit_msg>style(web): fixed warnings<commit_after>import _ from 'lodash';

import React from 'react';

import memoize from 'memoizee';
import emojify from 'emojify.js';
import emojiCharacters from 'emoji-named-characters';

import Markdown from 'utils/Markdown';

const inversedEmojiCharacters = _.invert(_.mapValues(emojiCharacters, (e) => e.character));

emojify.setConfig({
  mode: 'img',
  img_dir: 'assets/img/emoji' // eslint-disable-line
});

const emojiVariants = _.map(Object.keys(inversedEmojiCharacters), function (name) {
  return name.replace(/\+/g, '\\+');
});

const emojiRegexp = new RegExp('(' + emojiVariants.join('|') + ')', 'gi');

const processText = function (text) {
  let markedText = Markdown.default(text);

  // need hack with replace because of https://github.com/Ranks/emojify.js/issues/127
  const noPTag = markedText.replace(/
/g, '
 ');

  let emojifiedText = emojify
    .replace(noPTag.replace(emojiRegexp, (match) => ':' + inversedEmojiCharacters[match] + ':'));

  return emojifiedText;
};

const memoizedProcessText = memoize(processText, {
  length: 1000,
  maxAge: 60 * 60 * 1000,
  max: 10000
});

class Text extends React.Component {
  static propTypes = {
    content: React.PropTypes.object.isRequired,
    className: React.PropTypes.string
  };

  constructor(props) {
    super(props);
  }

  render() {
    const { content, className } = this.props;

    let renderedContent;

    if (content.markdownText !== null) {
      renderedContent = (

      );
    } else {
      renderedContent = (

          {content.text}

      );
    }

    return renderedContent;
  }
}

export default Text;
<|endoftext|>


<commit_before>/**
* Copyright (c) Microsoft.  All rights reserved.
*
* 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';
var util = require('util');

//Fetch the resource group from profile id using regex
exports.getResourceGroupFromProfileId = function (id) {
  var resourceGroupMatchRegexPattern = /(?:^|\/)resourcegroups\/(.*?)(?:\/providers|$)/g;
  var match = resourceGroupMatchRegexPattern.exec(id);
  return match[1];
}

//Create a string of origin names by the list of origins from endpoint
exports.getOriginNamesString = function (originList) {
	var nameArray = [];
	for (var i = 0; i < originList.length; i++) {
		nameArray.push(originList[i].name);
	}
	return nameArray.join("s");
}

//Convert command input boolean string to boolean
exports.getBooleanFromString = function (booleanString) {
	if (booleanString == "true") {
		return true;
	}
	return false;
}<commit_msg>code revise<commit_after>/**
* Copyright (c) Microsoft.  All rights reserved.
*
* 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';
var util = require('util');

//Fetch the resource group from profile id using regex
exports.getResourceGroupFromProfileId = function (id) {
  var resourceGroupMatchRegexPattern = /(?:^|\/)resourcegroups\/(.*?)(?:\/providers|$)/g;
  var match = resourceGroupMatchRegexPattern.exec(id);
  return match[1];
};

//Create a string of origin names by the list of origins from endpoint
exports.getOriginNamesString = function (originList) {
	var nameArray = [];
	for (var i = 0; i < originList.length; i++) {
		nameArray.push(originList[i].name);
	}
	return nameArray.join("s");
};

//Convert command input boolean string to boolean
exports.getBooleanFromString = function (booleanString) {
	if (booleanString == "true") {
		return true;
	}
	return false;
};<|endoftext|>


<commit_before>/**
* @license Apache-2.0
*
* Copyright (c) 2021 The Stdlib Authors.
*
* 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.
*/

/* eslint-disable max-len */

'use strict';

// MODULES //

var isNumber = require( '@stdlib/assert/is-number' ).isPrimitive;
var isComplexLike = require( '@stdlib/assert/is-complex-like' );
var isndarrayLike = require( '@stdlib/assert/is-ndarray-like' );
var isArrayLikeObject = require( '@stdlib/assert/is-array-like-object' );
var isSingleSegmentCompatible = require( '@stdlib/ndarray/base/assert/is-single-segment-compatible' );
var ndarray = require( '@stdlib/ndarray/memoized-ctor' );
var buffer = require( '@stdlib/ndarray/base/buffer' );
var shape2strides = require( '@stdlib/ndarray/base/shape2strides' );
var iterationOrder = require( '@stdlib/ndarray/base/iteration-order' );
var singletonDimensions = require( '@stdlib/ndarray/base/singleton-dimensions' );
var dtype = require( '@stdlib/ndarray/base/buffer-dtype' );
var maxViewBufferIndex = require( '@stdlib/ndarray/base/max-view-buffer-index' );
var minViewBufferIndex = require( '@stdlib/ndarray/base/min-view-buffer-index' );
var resolve = require( './resolve.js' );
var validate = require( './validate.js' );

// MAIN //

/**
* Returns a function which dispatches to specified functions based on input argument types.
*
* @param {Object} table - resolution table object
* @throws {TypeError} must provide an object
* @throws {TypeError} must provide valid table fields
* @throws {Error} table field values must be array-like objects having an even number of elements
* @throws {TypeError} table field values must consist of dtype-function pairs
* @returns {Function} dispatch function
*
* @example
* var nabs = require( '@stdlib/math/base/special/abs' );
* var dabs = require( '@stdlib/math/strided/special/dabs' );
* var sabs = require( '@stdlib/math/strided/special/sabs' );
* var gabs = require( '@stdlib/math/strided/special/abs' );
* var Float64Array = require( '@stdlib/array/float64' );
*
* var table = {
*     'scalar': [
*         'number', nabs
*     ],
*     'array': [
*         'float64', dabs,
*         'float32', sabs,
*         'generic', gabs
*     ],
*     'ndarray': [
*         'float64', dabs.ndarray,
*         'float32', sabs.ndarray,
*         'generic', gabs.ndarray
*     ]
* };
*
* var abs = dispatch( table );
*
* var x = new Float64Array( [ -1.0, -2.0, -3.0 ] );
*
* var y = abs( x );
* // returns <Float64Array>[ 1.0, 2.0, 3.0 ]
*/
function dispatch( table ) {
	var err;
	var t;

	t = {
		'scalar': [],
		'array': [],
		'ndarray': []
	};
	err = validate( t, table );
	if ( err ) {
		throw err;
	}
	return dispatcher;

	/**
	* Function interface which performs dispatch.
	*
	* @private
	* @param {(ndarray|ArrayLikeObject|number|Complex)} x - input value
	* @throws {TypeError} must provide an argument having a supported data type
	* @returns {(ndarray|ArrayLikeObject|number)} results
	*/
	function dispatcher( x ) {
		var strides;
		var offset;
		var order;
		var ndims;
		var shape;
		var data;
		var ctor;
		var buf;
		var dt;
		var N;
		var s;
		var y;
		var f;
		var i;

		if ( isNumber( x ) ) {
			f = resolve( t.scalar, 'number' );
			if ( f ) {
				return f( x );
			}
			throw new TypeError( 'invalid argument. Providing a number is not supported.' );
		}
		if ( isndarrayLike( x ) ) {
			// Cache ndarray properties to avoid repeatedly calling ndarray accessors...
			N = x.length;
			ndims = x.ndims;
			shape = x.shape;
			strides = x.strides;
			offset = x.offset;
			order = x.order;
			data = x.data;
			dt = x.dtype;

			// Attempt to resolve a type-specific implementation...
			f = resolve( t.ndarray, dt );
			if ( f === null ) {
				// Fall back to resolving a "generic" interface:
				f = resolve( t.ndarray, 'generic' );
				if ( f === null ) {
					throw new TypeError( 'invalid argument. Providing an ndarray with data type `' + dt + '` is not supported.' );
				}
			}
			// Create an output ndarray...
			ctor = ndarray( dt, ndims );
			buf = buffer( dt, N );
			y = ctor( buf, shape, shape2strides( shape, order ), 0, order );

			// Determine whether the ndarray is one-dimensional and thus readily translates to a one-dimensional strided array...
			if ( ndims === 1 ) {
				f( N, data, strides[ 0 ], offset, buf, 1, 0 );
				return y;
			}
			// Determine whether the ndarray has only **one** non-singleton dimension (e.g., ndims=4, shape=[10,1,1,1]) so that we can treat the ndarray as being equivalent to a one-dimensional strided array...
			if ( singletonDimensions( shape ) === ndims-1 ) {
				// Get the stride for the non-singleton dimension...
				for ( i = 0; i < ndims; i++ ) {
					if ( shape[ i ] !== 1 ) {
						s = strides[ i ];
						break;
					}
				}
				f( N, data, s, offset, buf, 1, 0 );
				return y;
			}
			// Determine whether we can ignore shape (and strides) and treat `x` as a linear strided array...
			s = iterationOrder( strides ); // +/-1
			if ( s !== 0 && isSingleSegmentCompatible( shape, strides, offset ) ) { // Note: equivalent to @stdlib/ndarray/base/assert/is-contiguous, but in-lined so we can retain iteration order
				if ( s === 1 ) {
					offset = minViewBufferIndex( shape, strides, offset );
				} else {
					offset = maxViewBufferIndex( shape, strides, offset );
				}
				f( N, data, s, offset, buf, 1, 0 );
				return y;
			}
			// At this point, `x` is a non-contiguous n-dimensional array, so we cannot directly use lower-level strided array functionality...

			// TODO: consider cache oblivious iteration, rather than data copy...
			data = buffer( dt, N );
			for ( i = 0; i < N; i++ ) {
				// FIXME: handle complex dtype ndarrays and beware that `iget` is not guaranteed to be on something considered "ndarray-like"
				data[ i ] = x.iget( i );
			}
			// The buffer copy is contiguous so we can now use strided array functionality:
			f( N, data, 1, 0, buf, 1, 0 );

			return y;
		}
		if ( isArrayLikeObject( x ) ) {
			dt = dtype( x ) || 'generic';

			// Attempt to resolve a type-specific implementation...
			f = resolve( t.array, dt );
			if ( f === null ) {
				// Fall back to resolving a "generic" interface:
				f = resolve( t.array, 'generic' );
				if ( f === null ) {
					throw new TypeError( 'invalid argument. Providing an array-like object is not supported.' );
				}
			}
			N = x.length;

			// Create an output array:
			y = buffer( dt, N );

			f( N, x, 1, y, 1 );
			return y;
		}
		// Note: we check for complex numbers last, as assumed that, in general, 1) complex numbers are not likely to be an especially common input argument data type and 2) users may expect that using complex numbers won't be as performant as built-in numbers, so we can leverage that expectation to prioritize other data types
		if ( isComplexLike( x ) ) {
			f = resolve( t.scalar, 'complex' );
			if ( f ) {
				return f( x );
			}
			throw new TypeError( 'invalid argument. Providing a complex number is not supported.' );
		}
		throw new TypeError( 'invalid argument. Must provide an argument having a supported data type. Value: `' + x + '`.' );
	}
}

// EXPORTS //

module.exports = dispatch;
<commit_msg>Document fields<commit_after>/**
* @license Apache-2.0
*
* Copyright (c) 2021 The Stdlib Authors.
*
* 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.
*/

/* eslint-disable max-len */

'use strict';

// MODULES //

var isNumber = require( '@stdlib/assert/is-number' ).isPrimitive;
var isComplexLike = require( '@stdlib/assert/is-complex-like' );
var isndarrayLike = require( '@stdlib/assert/is-ndarray-like' );
var isArrayLikeObject = require( '@stdlib/assert/is-array-like-object' );
var isSingleSegmentCompatible = require( '@stdlib/ndarray/base/assert/is-single-segment-compatible' );
var ndarray = require( '@stdlib/ndarray/memoized-ctor' );
var buffer = require( '@stdlib/ndarray/base/buffer' );
var shape2strides = require( '@stdlib/ndarray/base/shape2strides' );
var iterationOrder = require( '@stdlib/ndarray/base/iteration-order' );
var singletonDimensions = require( '@stdlib/ndarray/base/singleton-dimensions' );
var dtype = require( '@stdlib/ndarray/base/buffer-dtype' );
var maxViewBufferIndex = require( '@stdlib/ndarray/base/max-view-buffer-index' );
var minViewBufferIndex = require( '@stdlib/ndarray/base/min-view-buffer-index' );
var resolve = require( './resolve.js' );
var validate = require( './validate.js' );

// MAIN //

/**
* Returns a function which dispatches to specified functions based on input argument types.
*
* @param {Object} table - resolution table object
* @param {ArrayLikeObject} [table.scalar] - scalar look-up table
* @param {ArrayLikeObject} [table.array] - array look-up table
* @param {ArrayLikeObject} [table.ndarray] - ndarray look-up table
* @throws {TypeError} must provide an object
* @throws {TypeError} must provide valid table fields
* @throws {Error} table field values must be array-like objects having an even number of elements
* @throws {TypeError} table field values must consist of dtype-function pairs
* @returns {Function} dispatch function
*
* @example
* var nabs = require( '@stdlib/math/base/special/abs' );
* var dabs = require( '@stdlib/math/strided/special/dabs' );
* var sabs = require( '@stdlib/math/strided/special/sabs' );
* var gabs = require( '@stdlib/math/strided/special/abs' );
* var Float64Array = require( '@stdlib/array/float64' );
*
* var table = {
*     'scalar': [
*         'number', nabs
*     ],
*     'array': [
*         'float64', dabs,
*         'float32', sabs,
*         'generic', gabs
*     ],
*     'ndarray': [
*         'float64', dabs.ndarray,
*         'float32', sabs.ndarray,
*         'generic', gabs.ndarray
*     ]
* };
*
* var abs = dispatch( table );
*
* var x = new Float64Array( [ -1.0, -2.0, -3.0 ] );
*
* var y = abs( x );
* // returns <Float64Array>[ 1.0, 2.0, 3.0 ]
*/
function dispatch( table ) {
	var err;
	var t;

	t = {
		'scalar': [],
		'array': [],
		'ndarray': []
	};
	err = validate( t, table );
	if ( err ) {
		throw err;
	}
	return dispatcher;

	/**
	* Function interface which performs dispatch.
	*
	* @private
	* @param {(ndarray|ArrayLikeObject|number|Complex)} x - input value
	* @throws {TypeError} must provide an argument having a supported data type
	* @returns {(ndarray|ArrayLikeObject|number)} results
	*/
	function dispatcher( x ) {
		var strides;
		var offset;
		var order;
		var ndims;
		var shape;
		var data;
		var ctor;
		var buf;
		var dt;
		var N;
		var s;
		var y;
		var f;
		var i;

		if ( isNumber( x ) ) {
			f = resolve( t.scalar, 'number' );
			if ( f ) {
				return f( x );
			}
			throw new TypeError( 'invalid argument. Providing a number is not supported.' );
		}
		if ( isndarrayLike( x ) ) {
			// Cache ndarray properties to avoid repeatedly calling ndarray accessors...
			N = x.length;
			ndims = x.ndims;
			shape = x.shape;
			strides = x.strides;
			offset = x.offset;
			order = x.order;
			data = x.data;
			dt = x.dtype;

			// Attempt to resolve a type-specific implementation...
			f = resolve( t.ndarray, dt );
			if ( f === null ) {
				// Fall back to resolving a "generic" interface:
				f = resolve( t.ndarray, 'generic' );
				if ( f === null ) {
					throw new TypeError( 'invalid argument. Providing an ndarray with data type `' + dt + '` is not supported.' );
				}
			}
			// Create an output ndarray...
			ctor = ndarray( dt, ndims );
			buf = buffer( dt, N );
			y = ctor( buf, shape, shape2strides( shape, order ), 0, order );

			// Determine whether the ndarray is one-dimensional and thus readily translates to a one-dimensional strided array...
			if ( ndims === 1 ) {
				f( N, data, strides[ 0 ], offset, buf, 1, 0 );
				return y;
			}
			// Determine whether the ndarray has only **one** non-singleton dimension (e.g., ndims=4, shape=[10,1,1,1]) so that we can treat the ndarray as being equivalent to a one-dimensional strided array...
			if ( singletonDimensions( shape ) === ndims-1 ) {
				// Get the stride for the non-singleton dimension...
				for ( i = 0; i < ndims; i++ ) {
					if ( shape[ i ] !== 1 ) {
						s = strides[ i ];
						break;
					}
				}
				f( N, data, s, offset, buf, 1, 0 );
				return y;
			}
			// Determine whether we can ignore shape (and strides) and treat `x` as a linear strided array...
			s = iterationOrder( strides ); // +/-1
			if ( s !== 0 && isSingleSegmentCompatible( shape, strides, offset ) ) { // Note: equivalent to @stdlib/ndarray/base/assert/is-contiguous, but in-lined so we can retain iteration order
				if ( s === 1 ) {
					offset = minViewBufferIndex( shape, strides, offset );
				} else {
					offset = maxViewBufferIndex( shape, strides, offset );
				}
				f( N, data, s, offset, buf, 1, 0 );
				return y;
			}
			// At this point, `x` is a non-contiguous n-dimensional array, so we cannot directly use lower-level strided array functionality...

			// TODO: consider cache oblivious iteration, rather than data copy...
			data = buffer( dt, N );
			for ( i = 0; i < N; i++ ) {
				// FIXME: handle complex dtype ndarrays and beware that `iget` is not guaranteed to be on something considered "ndarray-like"
				data[ i ] = x.iget( i );
			}
			// The buffer copy is contiguous so we can now use strided array functionality:
			f( N, data, 1, 0, buf, 1, 0 );

			return y;
		}
		if ( isArrayLikeObject( x ) ) {
			dt = dtype( x ) || 'generic';

			// Attempt to resolve a type-specific implementation...
			f = resolve( t.array, dt );
			if ( f === null ) {
				// Fall back to resolving a "generic" interface:
				f = resolve( t.array, 'generic' );
				if ( f === null ) {
					throw new TypeError( 'invalid argument. Providing an array-like object is not supported.' );
				}
			}
			N = x.length;

			// Create an output array:
			y = buffer( dt, N );

			f( N, x, 1, y, 1 );
			return y;
		}
		// Note: we check for complex numbers last, as assumed that, in general, 1) complex numbers are not likely to be an especially common input argument data type and 2) users may expect that using complex numbers won't be as performant as built-in numbers, so we can leverage that expectation to prioritize other data types
		if ( isComplexLike( x ) ) {
			f = resolve( t.scalar, 'complex' );
			if ( f ) {
				return f( x );
			}
			throw new TypeError( 'invalid argument. Providing a complex number is not supported.' );
		}
		throw new TypeError( 'invalid argument. Must provide an argument having a supported data type. Value: `' + x + '`.' );
	}
}

// EXPORTS //

module.exports = dispatch;
<|endoftext|>


<commit_before>'use strict';

// MODULES //

var tape = require( 'tape' );
var http = require( 'http' );
var noop = require( '@stdlib/utils/noop' );
var createServer = require( './fixtures/server.js' );
var httpServer = require( './../lib' );

// TESTS //

tape( 'main export is a function', function test( t ) {
	t.ok( true, __filename );
	t.equal( typeof httpServer, 'function', 'main export is a function' );
	t.end();
});

tape( 'the function will throw an error if provided an invalid option', function test( t ) {
	t.throws( foo, Error, 'throws error' );
	t.throws( bar, Error, 'throws error' );
	t.end();
	function foo() {
		httpServer({
			'port': 3.14
		});
	}
	function bar() {
		httpServer({
			'maxport': 3.14
		}, noop );
	}
});

tape( 'the function will throw an error if provided a request listener which is not a function', function test( t ) {
	var values;
	var i;

	values = [
		'5',
		5,
		NaN,
		true,
		null,
		undefined,
		[],
		{}
	];

	for ( i = 0; i < values.length; i++ ) {
		t.throws( badValue( values[ i ] ), TypeError, 'throws an error when provided '+values[i] );
	}
	t.end();
	function badValue( value ) {
		return function badValue() {
			httpServer( {}, value );
		};
	}
});

tape( 'the function returns a function', function test( t ) {
	t.equal( typeof httpServer(), 'function', 'returns a function' );
	t.end();
});

tape( 'the returned function will throw an error if provided a callback argument which is not a function', function test( t ) {
	var values;
	var create;
	var i;

	values = [
		'5',
		5,
		NaN,
		true,
		null,
		undefined,
		[],
		{}
	];

	create = httpServer( {} );

	for ( i = 0; i < values.length; i++ ) {
		t.throws( badValue( values[ i ] ) , TypeError, 'throws an error when provided '+values[i] );
	}
	t.end();
	function badValue( value ) {
		return function badValue() {
			create( value );
		};
	}
});

tape( 'the created server listens on a specified port', function test( t ) {
	var create;
	var opts;

	opts = {};
	opts.port = 7331;

	create = httpServer( opts );
	create( onServer );

	function onServer( error, server ) {
		if ( error ) {
			t.ok( false, error.message );
		} else {
			t.equal( server.address().port, opts.port, 'listens on port '+opts.port );
		}
		server.close();
		t.end();
	}
});

tape( 'the returned function will throw if the server encounters an error', function test( t ) {
	var create;
	var server;
	var opts;

	opts = {};
	opts.port = 1337;

	create = httpServer( opts );
	create( next );

	function next( error, s ) {
		server = s;
		t.throws( foo, Error, 'throws error' );
		server.close();
		t.end();
	}

	function foo() {
		var err = new Error( 'Server error.' );
		server.emit( 'error', err );
	}
});

tape( 'the returned function will throw if unable to listen on a specified port (default behavior)', function test( t ) {
	var create;
	var server;
	var opts;

	opts = {};
	opts.port = 10000;

	create = httpServer( opts );
	create( next );

	function next( error, s ) {
		server = s;
		t.throws( foo, Error, 'throws an error' );
		server.close();
		t.end();
	}

	function foo() {
		var err = new Error( 'Server address already in use.' );
		err.code = 'EADDRINUSE';

		server.emit( 'error', err );
	}
});

tape( 'the returned function will port hunt', function test( t ) {
	var eServer;
	var server;
	var create;
	var opts;

	opts = {};
	opts.port = 8080;
	opts.maxport = 9999;

	create = httpServer( opts );
	eServer = createServer( opts.port, next );

	function next() {
		var addr = eServer.address();
		t.equal( addr.port, opts.port, 'fixture server bound to port '+opts.port+' and with address '+addr.address );
		create( onServer );
	}

	function onServer( error, s ) {
		var port;
		server = s;
		if ( error ) {
			t.ok( false, error.message );
		} else {
			port = server.address().port;
			t.equal( port > opts.port, true, 'returns a server with a port ('+port+') higher than '+opts.port );
		}
		setTimeout( onTimeout, 0 );
	}

	function onTimeout() {
		server.close();
		eServer.close();
		t.end();
	}
});

tape( 'the server will listen on a specified hostname', function test( t ) {
	var create;
	var opts;

	opts = {};
	opts.hostname = 'localhost';

	create = httpServer( opts );
	create( onServer );

	function onServer( error, server ) {
		if ( error ) {
			t.ok( false, error.message );
		} else {
			t.equal( server.address().address, '127.0.0.1', 'listens on address 127.0.0.1 (localhost)' );
		}
		server.close();
		t.end();
	}
});

tape( 'the server will listen on a specified address', function test( t ) {
	var create;
	var opts;

	opts = {};
	opts.address = '127.0.0.1';

	create = httpServer( opts );
	create( onServer );

	function onServer( error, server ) {
		if ( error ) {
			t.ok( false, error.message );
		} else {
			t.equal( server.address().address, opts.address, 'listens at address '+opts.address );
		}
		server.close();
		t.end();
	}
});

tape( 'the server will use a provided request listener (no options)', function test( t ) {
	var create;
	var server;

	create = httpServer( onRequest );
	create( onServer );

	function onServer( error, s ) {
		var addr;
		if ( error ) {
			t.ok( false, error.message );
		}
		server = s;
		addr = s.address();
		http.get( 'http://'+addr.address+':'+addr.port, noop );
	}
	function onRequest( request, response ) {
		t.ok( true, 'uses request listener' );
		response.end( 'OK' );
		server.close();
		t.end();
	}
});

tape( 'the server will use a provided request listener (options)', function test( t ) {
	var create;
	var server;
	var opts;

	opts = {};
	opts.port = 7000;

	create = httpServer( opts, onRequest );
	create( onServer );

	function onServer( error, s ) {
		if ( error ) {
			t.ok( false, error.message );
		}
		server = s;
		http.get( 'http://127.0.0.1:7000', noop );
	}
	function onRequest( request, response ) {
		t.ok( true, 'uses request listener' );
		response.end( 'OK' );
		server.close();
		t.end();
	}
});
<commit_msg>Forcefully shut down servers in tests<commit_after>'use strict';

// MODULES //

var tape = require( 'tape' );
var http = require( 'http' );
var getKeys = require( 'object-keys' ).shim();
var noop = require( '@stdlib/utils/noop' );
var createServer = require( './fixtures/server.js' );
var httpServer = require( './../lib' );

// TESTS //

tape( 'main export is a function', function test( t ) {
	t.ok( true, __filename );
	t.equal( typeof httpServer, 'function', 'main export is a function' );
	t.end();
});

tape( 'the function will throw an error if provided an invalid option', function test( t ) {
	t.throws( foo, Error, 'throws error' );
	t.throws( bar, Error, 'throws error' );
	t.end();
	function foo() {
		httpServer({
			'port': 3.14
		});
	}
	function bar() {
		httpServer({
			'maxport': 3.14
		}, noop );
	}
});

tape( 'the function will throw an error if provided a request listener which is not a function', function test( t ) {
	var values;
	var i;

	values = [
		'5',
		5,
		NaN,
		true,
		null,
		undefined,
		[],
		{}
	];

	for ( i = 0; i < values.length; i++ ) {
		t.throws( badValue( values[ i ] ), TypeError, 'throws an error when provided '+values[i] );
	}
	t.end();
	function badValue( value ) {
		return function badValue() {
			httpServer( {}, value );
		};
	}
});

tape( 'the function returns a function', function test( t ) {
	t.equal( typeof httpServer(), 'function', 'returns a function' );
	t.end();
});

tape( 'the returned function will throw an error if provided a callback argument which is not a function', function test( t ) {
	var values;
	var create;
	var i;

	values = [
		'5',
		5,
		NaN,
		true,
		null,
		undefined,
		[],
		{}
	];

	create = httpServer( {} );

	for ( i = 0; i < values.length; i++ ) {
		t.throws( badValue( values[ i ] ) , TypeError, 'throws an error when provided '+values[i] );
	}
	t.end();
	function badValue( value ) {
		return function badValue() {
			create( value );
		};
	}
});

tape( 'the created server listens on a specified port', function test( t ) {
	var create;
	var opts;

	opts = {};
	opts.port = 7331;

	create = httpServer( opts );
	create( onServer );

	function onServer( error, server ) {
		if ( error ) {
			t.ok( false, error.message );
		} else {
			t.equal( server.address().port, opts.port, 'listens on port '+opts.port );
		}
		server.close();
		t.end();
	}
});

tape( 'the returned function will throw if the server encounters an error', function test( t ) {
	var create;
	var server;
	var opts;

	opts = {};
	opts.port = 1337;

	create = httpServer( opts );
	create( next );

	function next( error, s ) {
		server = s;
		t.throws( foo, Error, 'throws error' );
		server.close();
		t.end();
	}

	function foo() {
		var err = new Error( 'Server error.' );
		server.emit( 'error', err );
	}
});

tape( 'the returned function will throw if unable to listen on a specified port (default behavior)', function test( t ) {
	var create;
	var server;
	var opts;

	opts = {};
	opts.port = 10000;

	create = httpServer( opts );
	create( next );

	function next( error, s ) {
		server = s;
		t.throws( foo, Error, 'throws an error' );
		server.close();
		t.end();
	}

	function foo() {
		var err = new Error( 'Server address already in use.' );
		err.code = 'EADDRINUSE';

		server.emit( 'error', err );
	}
});

tape( 'the returned function will port hunt', function test( t ) {
	var eServer;
	var server;
	var create;
	var opts;

	opts = {};
	opts.port = 8080;
	opts.maxport = 9999;

	create = httpServer( opts );
	eServer = createServer( opts.port, next );

	function next() {
		var addr = eServer.address();
		t.equal( addr.port, opts.port, 'fixture server bound to port '+opts.port+' and with address '+addr.address );
		create( onServer );
	}

	function onServer( error, s ) {
		var port;
		server = s;
		if ( error ) {
			t.ok( false, error.message );
		} else {
			port = server.address().port;
			t.equal( port > opts.port, true, 'returns a server with a port ('+port+') higher than '+opts.port );
		}
		setTimeout( onTimeout, 0 );
	}

	function onTimeout() {
		server.close();
		eServer.close();
		t.end();
	}
});

tape( 'the server will listen on a specified hostname', function test( t ) {
	var create;
	var opts;

	opts = {};
	opts.hostname = 'localhost';

	create = httpServer( opts );
	create( onServer );

	function onServer( error, server ) {
		if ( error ) {
			t.ok( false, error.message );
		} else {
			t.equal( server.address().address, '127.0.0.1', 'listens on address 127.0.0.1 (localhost)' );
		}
		server.close();
		t.end();
	}
});

tape( 'the server will listen on a specified address', function test( t ) {
	var create;
	var opts;

	opts = {};
	opts.address = '127.0.0.1';

	create = httpServer( opts );
	create( onServer );

	function onServer( error, server ) {
		if ( error ) {
			t.ok( false, error.message );
		} else {
			t.equal( server.address().address, opts.address, 'listens at address '+opts.address );
		}
		server.close();
		t.end();
	}
});

tape( 'the server will use a provided request listener (no options)', function test( t ) {
	var connections;
	var create;
	var server;

	connections = {};

	create = httpServer( onRequest );
	create( onServer );

	function onRequest( request, response ) {
		t.ok( true, 'uses request listener' );
		response.end( 'OK' );
		server.close();
		setTimeout( destroyConnections, 10 );
	}

	function onServer( error, s ) {
		var addr;
		if ( error ) {
			t.ok( false, error.message );
		}
		server = s;

		server.on( 'connection', onConnection );
		server.once( 'close', onClose );

		addr = s.address();
		http.get( 'http://'+addr.address+':'+addr.port, noop );
	}

	function onClose() {
		t.end();
	}

	function onConnection( socket ) {
		var key;

		key = socket.remoteAddress+':'+socket.remotePort;
		connections[ key ] = socket;

		socket.once( 'close', onSocketClose );

		function onSocketClose() {
			delete connections[ key ];
		}
	}

	function destroyConnections() {
		var keys;
		var i;
		keys = getKeys( connections );
		for ( i = 0; i < keys.length; i++ ) {
			connections[ keys[i] ].destroy();
		}
	}
});

tape( 'the server will use a provided request listener (options)', function test( t ) {
	var connections;
	var create;
	var server;
	var opts;

	opts = {};
	opts.port = 7331;

	connections = {};

	create = httpServer( opts, onRequest );
	create( onServer );

	function onRequest( request, response ) {
		t.ok( true, 'uses request listener' );
		response.end( 'OK' );
		server.close();
		setTimeout( destroyConnections, 10 );
	}

	function onServer( error, s ) {
		var addr;
		if ( error ) {
			t.ok( false, error.message );
		}
		server = s;

		server.on( 'connection', onConnection );
		server.once( 'close', onClose );

		addr = s.address();
		http.get( 'http://'+addr.address+':'+addr.port, noop );
	}

	function onClose() {
		t.end();
	}

	function onConnection( socket ) {
		var key;

		key = socket.remoteAddress+':'+socket.remotePort;
		connections[ key ] = socket;

		socket.once( 'close', onSocketClose );

		function onSocketClose() {
			delete connections[ key ];
		}
	}

	function destroyConnections() {
		var keys;
		var i;
		keys = getKeys( connections );
		for ( i = 0; i < keys.length; i++ ) {
			connections[ keys[i] ].destroy();
		}
	}
});
<|endoftext|>


<commit_before>/**
 * Target number of nano-seconds to run tests for.
 * @type {Number}
 *
 * @properties={typeid:35,uuid:"1CEA5B7F-4E92-4087-B0DD-71B9DD9D925D",variableType:8}
 */
var benchTime = 1e9;

/**
 * Local shortcut for high-precision timing.
 * @type {function():Number}
 * @properties={typeid:35,uuid:"56B573D2-D629-4779-8D6A-07AFEC2E834A",variableType:-4}
 */
var nanoTime = java.lang.System.nanoTime;

/**
 * @properties={typeid:35,uuid:"797221B3-A92A-4A75-A0DB-642F2748664E",variableType:-4}
 */
var Bench = function () {
	var b = this;

	//Number of iterations benchmark should be run
	b.N = 0,
	b.start = null;
	b.duration = null;
	b.timerOn = false;

	b.startTimer = function() {
		if (!b.timerOn) {
			b.start = nanoTime();
			b.timerOn = true;
		}
	};

	b.stopTimer = function() {
		if (b.timerOn) {
			b.duration += (nanoTime() - b.start);
			b.timerOn = false;
		}
	};

	b.resetTimer = function() {
		if (b.timerOn) {
			b.start = nanoTime();
		}
		b.duration = 0;
	};

	/**
	 * @return {Number}
	 */
	b.nsPerOp = function() {
		if (b.N <= 0) {
			return 0;
		}
		return b.duration/b.N;
	}
	}
}

/**
 *
 * @properties={typeid:35,uuid:"EB3AF1B5-7570-4549-A876-5CAB3A549F52",variableType:-4}
 */
var BenchmarkResult = function (ops, duration) {
	var b = this;
	b.ops = ops;
	b.duration = duration;

	/** @type {Number} */
	b.nsPerOp = (ops > 0 && (duration/ops)) || 0;
	/** @type {Number} */
	b.opsPerS = (duration > 0 && ops/(duration/1e9))
}

/**
 * @param {String} name
 * @param {BenchmarkResult} r
 *
 * @properties={typeid:35,uuid:"24A46511-1436-4F39-ABC0-7E6FD91B20F9",variableType:-4}
 */
var log = function (name, r) {
	var time = nsToTime(r.nsPerOp);
	application.output(name + ":\t" + pad(r.ops + " ops\t", 20) + pad(time.time.toFixed(3) + " " + time.unit + "/op\t", 20) + pad(r.opsPerS.toFixed(3) +" ops/sec", 20))

	function pad(s, n) {
		if (s.length >= n)
		{
			return s;
		}
		return (new Array(n-s.length+1).join(' ') + s);
	}
};

/**
 * @param {scopes.benchpress.Bench} b
 * @param {function(scopes.benchpress.Bench)} benchmark
 * @param {Number} n
 *
 * @properties={typeid:24,uuid:"65E00C72-991C-4272-A96E-5EF55E673F5A"}
 */
function runNTimes(b, benchmark, n) {
	//Attempt to get consistent results across runs by suggesting
	//to the JVM that it collect garbage from previous runs
	java.lang.System.gc();

	b.N = n;
	b.resetTimer();
	b.startTimer();
	benchmark(b);
	b.stopTimer();
}

/**
 * @param {function(scopes.benchpress.Bench)} benchmark
 *
 * @properties={typeid:24,uuid:"553F5063-96EE-4BA2-A551-C2C240CF1D2C"}
 */
function launch(benchmark) {

	var b = new Bench();

	//Run the benchmark once to start (in case it's expensive)
	var n = 1;
	runNTimes(b,benchmark,n);

	var last;
	while (b.duration < benchTime && n < 1e9) {
		last = n;

		//Predict iterations/sec
		if (b.nsPerOp() == 0) {
			n = 1e9;
		}
		else {
			n = (benchTime / b.nsPerOp())
		}

		// Run more iterations than we think we'll need for a second (1.5x).
        // Don't grow too fast in case we had timing errors previously.
        // Be sure to run at least one more than last time.
        n = Math.max(Math.min(n+n/2, 100*last), last+1);
        // Round up to something easy to read.
        n = roundUp(n);

        runNTimes(b,benchmark,n);
	}

	var result = new BenchmarkResult(n, b.duration);
	return result;

}

/**
 * Rounds a number down to the nearest power of 10.
 * @param n
 * @return {Number}
 * @properties={typeid:24,uuid:"4CAD1EB4-F416-46F4-AD2B-DD1D6B337B26"}
 */
function roundDown10(n) {
	var tens = 0
	// tens = floor(log_10(n))
	while (n >= 10) {
		n = n / 10
		tens++
	}
	// result = 10^tens
	var result = 1
	for (var i = 0; i < tens; i++) {
		result *= 10
	}
	return result
}

/**
 * Rounds x up to a number of the form [1eX, 2eX, 5eX].
 * @param n
 * @return {Number}
 *
 * @properties={typeid:24,uuid:"838FA8B2-A943-4ECB-968E-3C7F490B89C1"}
 */
function roundUp(n) {
	var base = roundDown10(n)
	if ( n <= base ) {
		return base;
	}
	else if (n <= (2 * base)) {
		return 2 * base
	}
	else if (n <= (5 * base)) {
		return 5 * base;
	}
	else {
		return 10 * base
	}
}

/**
 * Search across all scopes for benchmarking methods and run them
 * @properties={typeid:24,uuid:"5D1EFCD0-2C9D-4003-8C66-35F715834A85"}
 */
function runAllBenchmarks() {
	var scopeNames = solutionModel.getScopeNames();
	scopeNames.forEach(function (s) {
		var methods = solutionModel.getGlobalMethods(s).map(function(j) { return j.getName() } );
		var benchmarks = methods.filter(function (name) {
			return name.indexOf('benchmark_') == 0;
		});

		benchmarks.forEach(function (benchmark) {
			var result = launch(scopes[s][benchmark]);
			log([s, benchmark].join('.'), result);
		});
	});
}

/**
 * @param {Number} ns
 * @return {{time:Number, unit:String}}
 * @properties={typeid:24,uuid:"91A1D73E-5E6C-43A6-90B6-E8780ABCC0E7"}
 */
function nsToTime(ns)
{
	var time;

	//Seconds
	time = ns/1e9;
	if (time >= 1) {
		return {
			time : time,
			unit : 's'
		};
	}

	//Milliseconds
	time = ns/1e6;
	if (time > 1) {
		return {
			time : time,
			unit : 'ms'
		};
	}

	//Nanoseconds
	return {
		time : ns,
		unit : 'ns'
	};
}<commit_msg>Add opsPerS<commit_after>/**
 * Target number of nano-seconds to run tests for.
 * @type {Number}
 *
 * @properties={typeid:35,uuid:"1CEA5B7F-4E92-4087-B0DD-71B9DD9D925D",variableType:8}
 */
var benchTime = 1e9;

/**
 * Local shortcut for high-precision timing.
 * @type {function():Number}
 * @properties={typeid:35,uuid:"56B573D2-D629-4779-8D6A-07AFEC2E834A",variableType:-4}
 */
var nanoTime = java.lang.System.nanoTime;

/**
 * @properties={typeid:35,uuid:"797221B3-A92A-4A75-A0DB-642F2748664E",variableType:-4}
 */
var Bench = function () {
	var b = this;

	//Number of iterations benchmark should be run
	b.N = 0,
	b.start = null;
	b.duration = null;
	b.timerOn = false;

	b.startTimer = function() {
		if (!b.timerOn) {
			b.start = nanoTime();
			b.timerOn = true;
		}
	};

	b.stopTimer = function() {
		if (b.timerOn) {
			b.duration += (nanoTime() - b.start);
			b.timerOn = false;
		}
	};

	b.resetTimer = function() {
		if (b.timerOn) {
			b.start = nanoTime();
		}
		b.duration = 0;
	};

	/**
	 * @return {Number}
	 */
	b.nsPerOp = function() {
		if (b.N <= 0) {
			return 0;
		}
		return b.duration/b.N;
	}

	/**
	 * @return {Number}
	 */
	b.opsPerS = function() {
		if (b.duration <= 0)
		{
			return 0;
		}
		return b.N/(b.duration/1e9);
	}

}

/**
 *
 * @properties={typeid:35,uuid:"EB3AF1B5-7570-4549-A876-5CAB3A549F52",variableType:-4}
 */
var BenchmarkResult = function (ops, duration) {
	var b = this;
	b.ops = ops;
	b.duration = duration;

	/** @type {Number} */
	b.nsPerOp = (ops > 0 && (duration/ops)) || 0;
	/** @type {Number} */
	b.opsPerS = (duration > 0 && ops/(duration/1e9))
}

/**
 * @param {String} name
 * @param {BenchmarkResult} r
 *
 * @properties={typeid:35,uuid:"24A46511-1436-4F39-ABC0-7E6FD91B20F9",variableType:-4}
 */
var log = function (name, r) {
	var time = nsToTime(r.nsPerOp);
	application.output(name + ":\t" + pad(r.ops + " ops\t", 20) + pad(time.time.toFixed(3) + " " + time.unit + "/op\t", 20) + pad(r.opsPerS.toFixed(3) +" ops/sec", 20))

	function pad(s, n) {
		if (s.length >= n)
		{
			return s;
		}
		return (new Array(n-s.length+1).join(' ') + s);
	}
};

/**
 * @param {scopes.benchpress.Bench} b
 * @param {function(scopes.benchpress.Bench)} benchmark
 * @param {Number} n
 *
 * @properties={typeid:24,uuid:"65E00C72-991C-4272-A96E-5EF55E673F5A"}
 */
function runNTimes(b, benchmark, n) {
	//Attempt to get consistent results across runs by suggesting
	//to the JVM that it collect garbage from previous runs
	java.lang.System.gc();

	b.N = n;
	b.resetTimer();
	b.startTimer();
	benchmark(b);
	b.stopTimer();
}

/**
 * @param {function(scopes.benchpress.Bench)} benchmark
 *
 * @properties={typeid:24,uuid:"553F5063-96EE-4BA2-A551-C2C240CF1D2C"}
 */
function launch(benchmark) {

	var b = new Bench();

	//Run the benchmark once to start (in case it's expensive)
	var n = 1;
	runNTimes(b,benchmark,n);

	var last;
	while (b.duration < benchTime && n < 1e9) {
		last = n;

		//Predict iterations/sec
		if (b.nsPerOp() == 0) {
			n = 1e9;
		}
		else {
			n = (benchTime / b.nsPerOp())
		}

		// Run more iterations than we think we'll need for a second (1.5x).
        // Don't grow too fast in case we had timing errors previously.
        // Be sure to run at least one more than last time.
        n = Math.max(Math.min(n+n/2, 100*last), last+1);
        // Round up to something easy to read.
        n = roundUp(n);

        runNTimes(b,benchmark,n);
	}

	var result = new BenchmarkResult(n, b.duration);
	return result;

}

/**
 * Rounds a number down to the nearest power of 10.
 * @param n
 * @return {Number}
 * @properties={typeid:24,uuid:"4CAD1EB4-F416-46F4-AD2B-DD1D6B337B26"}
 */
function roundDown10(n) {
	var tens = 0
	// tens = floor(log_10(n))
	while (n >= 10) {
		n = n / 10
		tens++
	}
	// result = 10^tens
	var result = 1
	for (var i = 0; i < tens; i++) {
		result *= 10
	}
	return result
}

/**
 * Rounds x up to a number of the form [1eX, 2eX, 5eX].
 * @param n
 * @return {Number}
 *
 * @properties={typeid:24,uuid:"838FA8B2-A943-4ECB-968E-3C7F490B89C1"}
 */
function roundUp(n) {
	var base = roundDown10(n)
	if ( n <= base ) {
		return base;
	}
	else if (n <= (2 * base)) {
		return 2 * base
	}
	else if (n <= (5 * base)) {
		return 5 * base;
	}
	else {
		return 10 * base
	}
}

/**
 * Search across all scopes for benchmarking methods and run them
 * @properties={typeid:24,uuid:"5D1EFCD0-2C9D-4003-8C66-35F715834A85"}
 */
function runAllBenchmarks() {
	var scopeNames = solutionModel.getScopeNames();
	scopeNames.forEach(function (s) {
		var methods = solutionModel.getGlobalMethods(s).map(function(j) { return j.getName() } );
		var benchmarks = methods.filter(function (name) {
			return name.indexOf('benchmark_') == 0;
		});

		benchmarks.forEach(function (benchmark) {
			var result = launch(scopes[s][benchmark]);
			log([s, benchmark].join('.'), result);
		});
	});
}

/**
 * @param {Number} ns
 * @return {{time:Number, unit:String}}
 * @properties={typeid:24,uuid:"91A1D73E-5E6C-43A6-90B6-E8780ABCC0E7"}
 */
function nsToTime(ns)
{
	var time;

	//Seconds
	time = ns/1e9;
	if (time >= 1) {
		return {
			time : time,
			unit : 's'
		};
	}

	//Milliseconds
	time = ns/1e6;
	if (time > 1) {
		return {
			time : time,
			unit : 'ms'
		};
	}

	//Nanoseconds
	return {
		time : ns,
		unit : 'ns'
	};
}<|endoftext|>


<commit_before>/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.
 */

var App = require('app');
var filters = require('views/common/filter_view');
var sort = require('views/common/sort_view');

App.MainConfigHistoryView = App.TableView.extend(App.TableServerViewMixin, {
  templateName: require('templates/main/dashboard/config_history'),

  controllerBinding: 'App.router.mainConfigHistoryController',

  /**
   * @type {boolean}
   * @default false
   */
  filteringComplete: false,
  isInitialRendering: true,

  /**
   * return filtered number of all content number information displayed on the page footer bar
   * @returns {String}
   */
  filteredContentInfo: function () {
    return this.t('tableView.filters.filteredConfigVersionInfo').format(this.get('filteredCount'), this.get('totalCount'));
  }.property('filteredCount', 'totalCount'),

  didInsertElement: function () {
    this.addObserver('startIndex', this, 'updatePagination');
    this.addObserver('displayLength', this, 'updatePagination');
    this.set('isInitialRendering', true);
    this.refresh();
    this.set('controller.isPolling', true);
    this.get('controller').doPolling();
  },

  /**
   * stop polling after leaving config history page
   */
  willDestroyElement: function () {
    this.set('controller.isPolling', false);
    clearTimeout(this.get('controller.timeoutRef'));
  },

  updateFilter: function (iColumn, value, type) {
    if (!this.get('isInitialRendering')) {
      this._super(iColumn, value, type);
    }
  },

  sortView: sort.serverWrapperView,
  versionSort: sort.fieldView.extend({
    column: 1,
    name: 'serviceVersion',
    displayName: Em.I18n.t('dashboard.configHistory.table.version.title'),
    classNames: ['first']
  }),
  configGroupSort: sort.fieldView.extend({
    column: 2,
    name: 'configGroup',
    displayName: Em.I18n.t('dashboard.configHistory.table.configGroup.title')
  }),
  modifiedSort: sort.fieldView.extend({
    column: 3,
    name: 'createTime',
    status: 'sorting_desc',
    displayName: Em.I18n.t('dashboard.configHistory.table.created.title')
  }),
  authorSort: sort.fieldView.extend({
    column: 4,
    name: 'author',
    displayName: Em.I18n.t('common.author')
  }),
  notesSort: sort.fieldView.extend({
    column: 5,
    name: 'notes',
    displayName: Em.I18n.t('common.notes')
  }),

  serviceFilterView: filters.createSelectView({
    column: 1,
    fieldType: 'filter-input-width',
    content: function () {
      return [
        {
          value: '',
          label: Em.I18n.t('common.all')
        }
      ].concat(App.Service.find().map(function (service) {
        return {
          value: service.get('serviceName'),
          label: service.get('displayName')
        }
      }));
    }.property('App.router.clusterController.isLoaded'),
    onChangeValue: function () {
      this.get('parentView').updateFilter(this.get('column'), this.get('value'), 'select');
    }
  }),

  configGroupFilterView: filters.createSelectView({
    column: 2,
    fieldType: 'filter-input-width',
    content: function () {
      var groupName = App.ServiceConfigVersion.find().mapProperty('groupName').uniq();
      if (groupName.indexOf(null) > -1) {
        groupName.splice(groupName.indexOf(null), 1);
      }
      return [
        {
          value: '',
          label: Em.I18n.t('common.all')
        }
      ].concat(groupName.map(function (item) {
        return {
          value: item,
          label: item
        }
      }));
    }.property('App.router.mainConfigHistoryController.content'),
    onChangeValue: function () {
      this.get('parentView').updateFilter(this.get('column'), this.get('value'), 'select');
    }
  }),

  modifiedFilterView: filters.createSelectView({
    column: 3,
    appliedEmptyValue: ["", ""],
    fieldType: 'filter-input-width,modified-filter',
    emptyValue: 'Any',
    contentBinding: "controller.modifiedFilter.content",
    onChangeValue: function () {
      this.set("controller.modifiedFilter.optionValue", this.get('selected'));
      this.get('parentView').updateFilter(this.get('column'), [this.get('controller.modifiedFilter.actualValues.startTime'), this.get('controller.modifiedFilter.actualValues.endTime')], 'range');
    }
  }),

  authorFilterView: filters.createTextView({
    column: 4,
    fieldType: 'filter-input-width',
    onChangeValue: function () {
      this.get('parentView').updateFilter(this.get('column'), this.get('value'), 'string');
    }
  }),

  notesFilterView: filters.createTextView({
    column: 5,
    fieldType: 'filter-input-width',
    onChangeValue: function () {
      this.get('parentView').updateFilter(this.get('column'), this.get('value'), 'string');
    }
  }),

  ConfigVersionView: Em.View.extend({
    tagName: 'tr',
    showLessNotes: true,
    toggleShowLessStatus: function () {
      this.toggleProperty('showLessNotes');
    },
    didInsertElement: function () {
      App.tooltip(this.$("[rel='Tooltip']"));
    }
  }),

  /**
   * refresh table content
   */
  refresh: function () {
    var self = this;
    this.set('filteringComplete', false);
    this.get('controller').load().done(function () {
      self.refreshDone.apply(self);
    });
  },

  /**
   * callback executed after refresh call done
   * @method refreshDone
   */
  refreshDone: function () {
    this.set('isInitialRendering', false);
    this.set('filteringComplete', true);
    this.propertyDidChange('pageContent');
    this.set('controller.resetStartIndex', false);
  },

  /**
   * associations between host property and column index
   * @type {Array}
   */
  colPropAssoc: function () {
    return this.get('controller.colPropAssoc');
  }.property('controller.colPropAssoc')
});
<commit_msg>AMBARI-9213 Config History - config group shows incorrect filter value. (atkach)<commit_after>/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.
 */

var App = require('app');
var filters = require('views/common/filter_view');
var sort = require('views/common/sort_view');

App.MainConfigHistoryView = App.TableView.extend(App.TableServerViewMixin, {
  templateName: require('templates/main/dashboard/config_history'),

  controllerBinding: 'App.router.mainConfigHistoryController',

  /**
   * @type {boolean}
   * @default false
   */
  filteringComplete: false,
  isInitialRendering: true,

  /**
   * return filtered number of all content number information displayed on the page footer bar
   * @returns {String}
   */
  filteredContentInfo: function () {
    return this.t('tableView.filters.filteredConfigVersionInfo').format(this.get('filteredCount'), this.get('totalCount'));
  }.property('filteredCount', 'totalCount'),

  didInsertElement: function () {
    this.addObserver('startIndex', this, 'updatePagination');
    this.addObserver('displayLength', this, 'updatePagination');
    this.set('isInitialRendering', true);
    this.refresh();
    this.set('controller.isPolling', true);
    this.get('controller').doPolling();
  },

  /**
   * stop polling after leaving config history page
   */
  willDestroyElement: function () {
    this.set('controller.isPolling', false);
    clearTimeout(this.get('controller.timeoutRef'));
  },

  updateFilter: function (iColumn, value, type) {
    if (!this.get('isInitialRendering')) {
      this._super(iColumn, value, type);
    }
  },

  sortView: sort.serverWrapperView,
  versionSort: sort.fieldView.extend({
    column: 1,
    name: 'serviceVersion',
    displayName: Em.I18n.t('dashboard.configHistory.table.version.title'),
    classNames: ['first']
  }),
  configGroupSort: sort.fieldView.extend({
    column: 2,
    name: 'configGroup',
    displayName: Em.I18n.t('dashboard.configHistory.table.configGroup.title')
  }),
  modifiedSort: sort.fieldView.extend({
    column: 3,
    name: 'createTime',
    status: 'sorting_desc',
    displayName: Em.I18n.t('dashboard.configHistory.table.created.title')
  }),
  authorSort: sort.fieldView.extend({
    column: 4,
    name: 'author',
    displayName: Em.I18n.t('common.author')
  }),
  notesSort: sort.fieldView.extend({
    column: 5,
    name: 'notes',
    displayName: Em.I18n.t('common.notes')
  }),

  serviceFilterView: filters.createSelectView({
    column: 1,
    fieldType: 'filter-input-width',
    content: function () {
      return [
        {
          value: '',
          label: Em.I18n.t('common.all')
        }
      ].concat(App.Service.find().map(function (service) {
        return {
          value: service.get('serviceName'),
          label: service.get('displayName')
        }
      }));
    }.property('App.router.clusterController.isLoaded'),
    onChangeValue: function () {
      this.get('parentView').updateFilter(this.get('column'), this.get('value'), 'select');
    }
  }),

  configGroupFilterView: filters.createSelectView({
    column: 2,
    fieldType: 'filter-input-width',
    content: function () {
      var groupName = App.ServiceConfigVersion.find().mapProperty('groupName').uniq();
      if (groupName.indexOf(null) > -1) {
        groupName.splice(groupName.indexOf(null), 1);
      }
      return [
        {
          value: '',
          label: Em.I18n.t('common.all')
        }
      ].concat(groupName.map(function (item) {
        return {
          value: item,
          label: item
        }
      }));
    }.property('parentView.isInitialRendering'),
    onChangeValue: function () {
      this.get('parentView').updateFilter(this.get('column'), this.get('value'), 'select');
    }
  }),

  modifiedFilterView: filters.createSelectView({
    column: 3,
    appliedEmptyValue: ["", ""],
    fieldType: 'filter-input-width,modified-filter',
    emptyValue: 'Any',
    contentBinding: "controller.modifiedFilter.content",
    onChangeValue: function () {
      this.set("controller.modifiedFilter.optionValue", this.get('selected'));
      this.get('parentView').updateFilter(this.get('column'), [this.get('controller.modifiedFilter.actualValues.startTime'), this.get('controller.modifiedFilter.actualValues.endTime')], 'range');
    }
  }),

  authorFilterView: filters.createTextView({
    column: 4,
    fieldType: 'filter-input-width',
    onChangeValue: function () {
      this.get('parentView').updateFilter(this.get('column'), this.get('value'), 'string');
    }
  }),

  notesFilterView: filters.createTextView({
    column: 5,
    fieldType: 'filter-input-width',
    onChangeValue: function () {
      this.get('parentView').updateFilter(this.get('column'), this.get('value'), 'string');
    }
  }),

  ConfigVersionView: Em.View.extend({
    tagName: 'tr',
    showLessNotes: true,
    toggleShowLessStatus: function () {
      this.toggleProperty('showLessNotes');
    },
    didInsertElement: function () {
      App.tooltip(this.$("[rel='Tooltip']"));
    }
  }),

  /**
   * refresh table content
   */
  refresh: function () {
    var self = this;
    this.set('filteringComplete', false);
    this.get('controller').load().done(function () {
      self.refreshDone.apply(self);
    });
  },

  /**
   * callback executed after refresh call done
   * @method refreshDone
   */
  refreshDone: function () {
    this.set('isInitialRendering', false);
    this.set('filteringComplete', true);
    this.propertyDidChange('pageContent');
    this.set('controller.resetStartIndex', false);
  },

  /**
   * associations between host property and column index
   * @type {Array}
   */
  colPropAssoc: function () {
    return this.get('controller.colPropAssoc');
  }.property('controller.colPropAssoc')
});
<|endoftext|>