<commit_before>/*
 Copyright 2017 Paul Zuehlcke - paul.zuehlcke.de

 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.
 */

/**
 * Stores command properties + logic and provides method to query them
 * @param lwConsole reference to console-object, required by some commands
 * @param config reference to configuration object used to store command-states
 * @constructor
 */
function CommandList(lwConsole, config) {
    "use strict";
    //this.getCommandHandler = getCommandHandler; //Currently unused
    this.getCommand = getCommand;

    function getCommandHandler(commandName) {
        let result = getCommand(commandName);
        if (result) {
            return result.handler;
        }
        else {
            //No matching command found
            return function () {
                return "Unknown command"; //No error, unknown-cmd is success. Feels weird, doesn't it?
            }
        }
    }

    function getCommand(commandName) {
        commandName = commandName.toLowerCase();
        for (let i = 0; i < commands.length; i++) {
            if (commands[i].name === commandName) {
                return commands[i]
            }
        }
    }

    let commands = [
        // {
        //     // ======= Example command to explain cmd implementation
        //     //Identifier of cmd (first arg of user input)
        //     name: "example",
        //     //Description for help-cmd
        //     description: "This is an example cmd to explain how commands are implemented",
        //     //Usage description of command to be printed on UsageError// d
        //     usage: "example <param1> <param2>",
        //     //Should this cmd be visible in the help page? "help example" will always work.
        //     visible: true,
        //     /**
        //      * Handler of command to be executed when cmd.name matches first keyword of user-input
        //      * @param args string-array containing additional arguments provided by user. Example: ["apple", "potato"]
        //      * @returns {string} result message of command to be printed to the console
        //      */
        //     handler: function (args) {
        //         if (args.length !== 2) {
        //             throw new UsageError("Invalid command usage! This message is optional");
        //         }
        //         if (args[0] === "bananas") {
        //             //Commands can also throw other errors, which will be shown in the console
        //             throw new Error("No bananas allowed!");
        //         }
        //
        //         //Commands can store options in the config object. They are preserved across calls.
        //         // If the user has cookies enabled they are also preserved across sessions
        //         // In the future cmds will have their own config-scope so you won't have to mind key-conflicts with
        //         // other cmds anymore.
        //         if (config.get("cakeSetting")) {
        //             lwConsole.print("Cake for you!");
        //         }
        //         else {
        //             lwConsole.print("Maybe next time");
        //             config.store("cakeSetting", true);
        //         }
        //
        //
        //         lwConsole.print("If you have an async cmd you can also print messages yourself like this.");
        //
        //         return "This is the result of the cmd, this message will be displayed in the console"
        //             + "\nAlso, new lines are supported";
        //     }
        // },
        {
            name: "help",
            description: "Shows a list of commands",
            usage: "help [command]",
            visible: true,
            handler: function (args) {
                // let result = new CMDResult();
                if (args.length > 1) {
                    return getCommandHandler("help")(["help"]);
                }
                if (args.length === 0) { //Show list of commands without usage
                    let msg = "Available commands:";
                    for (let i = 0; i < commands.length; i++) {
                        if (commands[i].visible) {
                            msg += "\n" + commands[i].name + ": " + commands[i].description;
                        }
                    }
                    return msg;
                }
                //Show usage for single cmd
                let cmd = getCommand(args[0]);
                if (!cmd) {
                    return "No help page available: Unknown command.";
                }
                return cmd.name +
                    (cmd.description && cmd.description !== "" ? ":\nDescription: " + cmd.description : "") +
                    (cmd.usage && cmd.description !== "" ? "\nUsage: " + cmd.usage : "") +
                    (cmd.author && cmd.author !== "" ? "\nAuthor: " + cmd.author : "");
            }
        },
        {
            name: "motd",
            description: "Shows the message of the day",
            usage: "motd",
            visible: true,
            handler: function () {
                return lwConsole.motd;
            }
        },
        {
            name: "open",
            description: "Opens page from main navigation",
            usage: "open [keybase/github/twitter/email/source]",
            visible: true, //Visible in help page?
            handler: function (args) {
                if (args.length !== 1) {
                    throw new UsageError();
                }
                let urls = {
                    "keybase": "//keybase.io/pbz",
                    "github": "//github.com/Trikolon",
                    "twitter": "//twitter.com/deppaws",
                    "email": "mailto:paul@zuehlcke.de",
                    "source": "//github.com/Trikolon/pbz-uber"
                };
                args[0] = args[0].toLowerCase(); //Ignore case

                if (!urls.hasOwnProperty(args[0])) {
                    throw new UsageError("Sorry, I don't know this service");
                }
                window.open(urls[args[0]]);
                return args[0] + " opened.";
            }
        },
        {
            name: "echo",
            description: "Displays message on console - no pipes yet :-(",
            usage: "echo <message>",
            visible: true,
            handler: function (args) {
                if (!args || args.length === 0) {
                    throw new UsageError();
                }
                return args.join(" ");
            }
        },
        {
            name: "ip",
            description: "Lookup an IP (queries your IP if no argument is provided)",
            usage: "ip [ip]",
            visible: true,
            handler: function (args) {
                let queryUrl = "https://ipinfo.io/";
                if (args.length > 1) {
                    throw new UsageError();
                }

                if (args.length === 1) { //one arg => query arg ip
                    queryUrl += args[0] + "/"
                }

                queryUrl += "json";

                let request = new XMLHttpRequest();
                request.onload = function () {
                    if (request.status !== 200) {
                        lwConsole.print("\nError: ipinfo.io returned code " + request.status);
                    }
                    lwConsole.print(request.responseText);
                };
                request.onerror = function (e) {
                    console.error(e);
                    lwConsole.print("Error: Could not send request to ipinfo.io. Check your internet connection.");
                };
                request.open("GET", queryUrl, true);
                request.send();
                return "Getting data ...";
            }
        },
        {
            name: "calc",
            description: "Calculates a the result of a simple math expression",
            usage: "calc <expression>",
            author: "TheBiochemic",
            visible: true,
            handler: function (args) {
                let expression = args.join("");

                if (args.length > 0) {
                    let expResult = parseExpression(expression);
                    if (expResult === undefined || isNaN(expResult))
                        throw new UsageError("This is not a valid expression!");
                    return expResult.toString();
                }
                else
                    throw new UsageError();

                function parseExpression(expression) {
                    let firstNumber = parseFloat(expression);
                    let iter = 0;

                    //If the expression starts with a legit number -123...
                    if (!isNaN(firstNumber)) {
                        iter++;
                        while (iter < expression.length) {

                            //check until there is an operand -123+...
                            if (isOperand(expression[iter])) {
                                let secondNumber = parseExpression(expression.substring(iter + 1, expression.length));
                                return operate(firstNumber, secondNumber, expression[iter]);

                            }
                            iter++;
                        }
                        return firstNumber;
                    }

                    //if the expression starts with (...
                    if (isNaN(firstNumber) && expression[iter] === "(") {
                        let level = 0;
                        iter++;
                        while (iter < expression.length) {
                            //if it finds another ( -> (123+(...
                            if (expression[iter] === "(") {
                                level++;
                            }
                            if (expression[iter] === ")") {
                                if (level === 0) {
                                    return parseExpression(expression.substring(1, iter));
                                }
                                level--
                            }
                            iter++;
                        }
                    }
                }

                function isOperand(character) {
                    return character === "+" ||
                        character === "-" ||
                        character === "*" ||
                        character === "/" ||
                        character === "^";
                }

                function operate(firstNumber, secondNumber, operator) {
                    switch (operator) {
                        case "+":
                            return firstNumber + secondNumber;
                        case "-":
                            return firstNumber - secondNumber;
                        case "*":
                            return firstNumber * secondNumber;
                        case "/":
                            return firstNumber / secondNumber;
                        case "^":
                            return Math.pow(firstNumber, secondNumber);
                    }
                }
            }
        },
        {
            name: "time",
            description: "Show time in different formats",
            usage: "time <utc/local/unix>",
            visible: true,
            handler: function (args) {
                let date = new Date();
                let found = true;

                if (args && args.length === 1) {
                    switch (args[0].toLowerCase()) {
                        case "utc":
                            date = date.toUTCString();
                            break;
                        case "local":
                            date = date.toLocaleString();
                            break;
                        case "unix":
                            date = Math.floor(date / 1000);
                            break;
                        default:
                            found = false;
                    }
                }
                else {
                    found = false;
                }
                if (!found) {
                    throw new UsageError();
                }
                return date;
            }
        },
        {
            name: "effect",
            description: "Toggle effects, such as invert and flicker",
            usage: "effect <flicker|invert> [true|false]",
            visible: true,
            handler: function (args) {
                function setEffect(effect, state) {
                    switch (effect) {
                        case "invert": {
                            let invertStr;
                            if (state) {
                                invertStr = "100%";
                            }
                            else {
                                invertStr = "0%";
                            }
                            document.getElementById("content").style.filter = "invert(" + invertStr + ")";
                            break;
                        }
                        case "flicker": {
                            let contentDom = document.getElementById("content");
                            let containsClass = contentDom.className.indexOf("monitor") !== -1;
                            if (state) {
                                if (!containsClass) {
                                    contentDom.className += "monitor";
                                }
                            }
                            else {
                                if (containsClass) {
                                    contentDom.className =
                                        contentDom.className.replace(/(?:^|\s)monitor(?!\S)/g, '');
                                }
                            }
                            break;
                        }
                        default: {
                            throw new UsageError();
                        }
                    }
                }

                let state; // boolean state to change effect to
                if (!args || args.length === 0 || args.length > 2) {
                    throw new UsageError();
                }
                args[0] = args[0].toLowerCase();

                if (args.length === 1) { //Toggle
                    state = config.get(args[0]);
                    state = !state;
                }
                else { // State overwrite
                    state = args[1] === "true";
                }
                setEffect(args[0], state); //this can throw usage-error (caught by execution handler)

                config.store(args[0], state);
                return "Effect " + args[0] + " turned " + (state ? "ON" : "OFF");
            }
        },
        {
            name: "clear",
            description: "Clears the console",
            usage: "clear",
            visible: true, //Visible in help page?
            handler: function () {
                lwConsole.clear();
            }
        },
        {
            name: "exit",
            description: "Exit console",
            usage: "exit",
            visible: true,
            handler: function () {
                util.toggleConsole();
            }
        },
        {
            name: "kleinhase",
            description: "Secret message",
            usage: "kleinhase",
            visible: false,
            handler: function () {
                return "<3";
            }
        },
        {
            name: "shutdown",
            description: "",
            usage: "shutdown",
            visible: false,
            handler: function () {
                return "You're not my master!";
            }
        },
        {
            name: "make_me_a_sandwich",
            description: "<3 xkcd",
            usage: "make_me_a_sandwich",
            visible: false,
            handler: function () {
                return "Make it yourself!";
            }
        },
        {
            name: "rm",
            description: "",
            usage: "rm",
            visible: false,
            handler: function () {
                return "Please don't delete anything. We don't have backups.";
            }
        },
        {
            name: "ls",
            description: "",
            usage: "ls",
            visible: false,
            handler: function () {
                return "cia_secrets, cute_cat_gifs, videos, passwords.txt";
            }
        },
        {
            name: "ridb",
            description: "A simple command that confirms that Robert is the best.",
            usage: "ridb [response]",
            author: "Endebert",
            visible: false,
            handler: function (args) {
                let output = "Paul:\t'Robert ist der Beste!'";
                if (args.length > 0)
                    output += "\nRobert:\t'" + args.join(" ") + "'";
                else {
                    output += "\nThere was no response...";
                }
                return output;
            }
        }
    ];
}
<commit_msg>minor formatting fix<commit_after>/*
 Copyright 2017 Paul Zuehlcke - paul.zuehlcke.de

 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.
 */

/**
 * Stores command properties + logic and provides method to query them
 * @param lwConsole reference to console-object, required by some commands
 * @param config reference to configuration object used to store command-states
 * @constructor
 */
function CommandList(lwConsole, config) {
    "use strict";
    //this.getCommandHandler = getCommandHandler; //Currently unused
    this.getCommand = getCommand;

    function getCommandHandler(commandName) {
        let result = getCommand(commandName);
        if (result) {
            return result.handler;
        }
        else {
            //No matching command found
            return function () {
                return "Unknown command"; //No error, unknown-cmd is success. Feels weird, doesn't it?
            }
        }
    }

    function getCommand(commandName) {
        commandName = commandName.toLowerCase();
        for (let i = 0; i < commands.length; i++) {
            if (commands[i].name === commandName) {
                return commands[i]
            }
        }
    }

    let commands = [
        // {
        //     // ======= Example command to explain cmd implementation
        //     //Identifier of cmd (first arg of user input)
        //     name: "example",
        //     //Description for help-cmd
        //     description: "This is an example cmd to explain how commands are implemented",
        //     //Usage description of command to be printed on UsageError// d
        //     usage: "example <param1> <param2>",
        //     //Should this cmd be visible in the help page? "help example" will always work.
        //     visible: true,
        //     /**
        //      * Handler of command to be executed when cmd.name matches first keyword of user-input
        //      * @param args string-array containing additional arguments provided by user. Example: ["apple", "potato"]
        //      * @returns {string} result message of command to be printed to the console
        //      */
        //     handler: function (args) {
        //         if (args.length !== 2) {
        //             throw new UsageError("Invalid command usage! This message is optional");
        //         }
        //         if (args[0] === "bananas") {
        //             //Commands can also throw other errors, which will be shown in the console
        //             throw new Error("No bananas allowed!");
        //         }
        //
        //         //Commands can store options in the config object. They are preserved across calls.
        //         // If the user has cookies enabled they are also preserved across sessions
        //         // In the future cmds will have their own config-scope so you won't have to mind key-conflicts with
        //         // other cmds anymore.
        //         if (config.get("cakeSetting")) {
        //             lwConsole.print("Cake for you!");
        //         }
        //         else {
        //             lwConsole.print("Maybe next time");
        //             config.store("cakeSetting", true);
        //         }
        //
        //
        //         lwConsole.print("If you have an async cmd you can also print messages yourself like this.");
        //
        //         return "This is the result of the cmd, this message will be displayed in the console"
        //             + "\nAlso, new lines are supported";
        //     }
        // },
        {
            name: "help",
            description: "Shows a list of commands",
            usage: "help [command]",
            visible: true,
            handler: function (args) {
                // let result = new CMDResult();
                if (args.length > 1) {
                    return getCommandHandler("help")(["help"]);
                }
                if (args.length === 0) { //Show list of commands without usage
                    let msg = "Available commands:";
                    for (let i = 0; i < commands.length; i++) {
                        if (commands[i].visible) {
                            msg += "\n" + commands[i].name + ": " + commands[i].description;
                        }
                    }
                    return msg;
                }
                //Show usage for single cmd
                let cmd = getCommand(args[0]);
                if (!cmd) {
                    return "No help page available: Unknown command.";
                }
                return cmd.name + ":" +
                    (cmd.description && cmd.description !== "" ? "\nDescription: " + cmd.description : "") +
                    (cmd.usage && cmd.description !== "" ? "\nUsage: " + cmd.usage : "") +
                    (cmd.author && cmd.author !== "" ? "\nAuthor: " + cmd.author : "");
            }
        },
        {
            name: "motd",
            description: "Shows the message of the day",
            usage: "motd",
            visible: true,
            handler: function () {
                return lwConsole.motd;
            }
        },
        {
            name: "open",
            description: "Opens page from main navigation",
            usage: "open [keybase/github/twitter/email/source]",
            visible: true, //Visible in help page?
            handler: function (args) {
                if (args.length !== 1) {
                    throw new UsageError();
                }
                let urls = {
                    "keybase": "//keybase.io/pbz",
                    "github": "//github.com/Trikolon",
                    "twitter": "//twitter.com/deppaws",
                    "email": "mailto:paul@zuehlcke.de",
                    "source": "//github.com/Trikolon/pbz-uber"
                };
                args[0] = args[0].toLowerCase(); //Ignore case

                if (!urls.hasOwnProperty(args[0])) {
                    throw new UsageError("Sorry, I don't know this service");
                }
                window.open(urls[args[0]]);
                return args[0] + " opened.";
            }
        },
        {
            name: "echo",
            description: "Displays message on console - no pipes yet :-(",
            usage: "echo <message>",
            visible: true,
            handler: function (args) {
                if (!args || args.length === 0) {
                    throw new UsageError();
                }
                return args.join(" ");
            }
        },
        {
            name: "ip",
            description: "Lookup an IP (queries your IP if no argument is provided)",
            usage: "ip [ip]",
            visible: true,
            handler: function (args) {
                let queryUrl = "https://ipinfo.io/";
                if (args.length > 1) {
                    throw new UsageError();
                }

                if (args.length === 1) { //one arg => query arg ip
                    queryUrl += args[0] + "/"
                }

                queryUrl += "json";

                let request = new XMLHttpRequest();
                request.onload = function () {
                    if (request.status !== 200) {
                        lwConsole.print("\nError: ipinfo.io returned code " + request.status);
                    }
                    lwConsole.print(request.responseText);
                };
                request.onerror = function (e) {
                    console.error(e);
                    lwConsole.print("Error: Could not send request to ipinfo.io. Check your internet connection.");
                };
                request.open("GET", queryUrl, true);
                request.send();
                return "Getting data ...";
            }
        },
        {
            name: "calc",
            description: "Calculates a the result of a simple math expression",
            usage: "calc <expression>",
            author: "TheBiochemic",
            visible: true,
            handler: function (args) {
                let expression = args.join("");

                if (args.length > 0) {
                    let expResult = parseExpression(expression);
                    if (expResult === undefined || isNaN(expResult))
                        throw new UsageError("This is not a valid expression!");
                    return expResult.toString();
                }
                else
                    throw new UsageError();

                function parseExpression(expression) {
                    let firstNumber = parseFloat(expression);
                    let iter = 0;

                    //If the expression starts with a legit number -123...
                    if (!isNaN(firstNumber)) {
                        iter++;
                        while (iter < expression.length) {

                            //check until there is an operand -123+...
                            if (isOperand(expression[iter])) {
                                let secondNumber = parseExpression(expression.substring(iter + 1, expression.length));
                                return operate(firstNumber, secondNumber, expression[iter]);

                            }
                            iter++;
                        }
                        return firstNumber;
                    }

                    //if the expression starts with (...
                    if (isNaN(firstNumber) && expression[iter] === "(") {
                        let level = 0;
                        iter++;
                        while (iter < expression.length) {
                            //if it finds another ( -> (123+(...
                            if (expression[iter] === "(") {
                                level++;
                            }
                            if (expression[iter] === ")") {
                                if (level === 0) {
                                    return parseExpression(expression.substring(1, iter));
                                }
                                level--
                            }
                            iter++;
                        }
                    }
                }

                function isOperand(character) {
                    return character === "+" ||
                        character === "-" ||
                        character === "*" ||
                        character === "/" ||
                        character === "^";
                }

                function operate(firstNumber, secondNumber, operator) {
                    switch (operator) {
                        case "+":
                            return firstNumber + secondNumber;
                        case "-":
                            return firstNumber - secondNumber;
                        case "*":
                            return firstNumber * secondNumber;
                        case "/":
                            return firstNumber / secondNumber;
                        case "^":
                            return Math.pow(firstNumber, secondNumber);
                    }
                }
            }
        },
        {
            name: "time",
            description: "Show time in different formats",
            usage: "time <utc/local/unix>",
            visible: true,
            handler: function (args) {
                let date = new Date();
                let found = true;

                if (args && args.length === 1) {
                    switch (args[0].toLowerCase()) {
                        case "utc":
                            date = date.toUTCString();
                            break;
                        case "local":
                            date = date.toLocaleString();
                            break;
                        case "unix":
                            date = Math.floor(date / 1000);
                            break;
                        default:
                            found = false;
                    }
                }
                else {
                    found = false;
                }
                if (!found) {
                    throw new UsageError();
                }
                return date;
            }
        },
        {
            name: "effect",
            description: "Toggle effects, such as invert and flicker",
            usage: "effect <flicker|invert> [true|false]",
            visible: true,
            handler: function (args) {
                function setEffect(effect, state) {
                    switch (effect) {
                        case "invert": {
                            let invertStr;
                            if (state) {
                                invertStr = "100%";
                            }
                            else {
                                invertStr = "0%";
                            }
                            document.getElementById("content").style.filter = "invert(" + invertStr + ")";
                            break;
                        }
                        case "flicker": {
                            let contentDom = document.getElementById("content");
                            let containsClass = contentDom.className.indexOf("monitor") !== -1;
                            if (state) {
                                if (!containsClass) {
                                    contentDom.className += "monitor";
                                }
                            }
                            else {
                                if (containsClass) {
                                    contentDom.className =
                                        contentDom.className.replace(/(?:^|\s)monitor(?!\S)/g, '');
                                }
                            }
                            break;
                        }
                        default: {
                            throw new UsageError();
                        }
                    }
                }

                let state; // boolean state to change effect to
                if (!args || args.length === 0 || args.length > 2) {
                    throw new UsageError();
                }
                args[0] = args[0].toLowerCase();

                if (args.length === 1) { //Toggle
                    state = config.get(args[0]);
                    state = !state;
                }
                else { // State overwrite
                    state = args[1] === "true";
                }
                setEffect(args[0], state); //this can throw usage-error (caught by execution handler)

                config.store(args[0], state);
                return "Effect " + args[0] + " turned " + (state ? "ON" : "OFF");
            }
        },
        {
            name: "clear",
            description: "Clears the console",
            usage: "clear",
            visible: true, //Visible in help page?
            handler: function () {
                lwConsole.clear();
            }
        },
        {
            name: "exit",
            description: "Exit console",
            usage: "exit",
            visible: true,
            handler: function () {
                util.toggleConsole();
            }
        },
        {
            name: "kleinhase",
            description: "Secret message",
            usage: "kleinhase",
            visible: false,
            handler: function () {
                return "<3";
            }
        },
        {
            name: "shutdown",
            description: "",
            usage: "shutdown",
            visible: false,
            handler: function () {
                return "You're not my master!";
            }
        },
        {
            name: "make_me_a_sandwich",
            description: "<3 xkcd",
            usage: "make_me_a_sandwich",
            visible: false,
            handler: function () {
                return "Make it yourself!";
            }
        },
        {
            name: "rm",
            description: "",
            usage: "rm",
            visible: false,
            handler: function () {
                return "Please don't delete anything. We don't have backups.";
            }
        },
        {
            name: "ls",
            description: "",
            usage: "ls",
            visible: false,
            handler: function () {
                return "cia_secrets, cute_cat_gifs, videos, passwords.txt";
            }
        },
        {
            name: "ridb",
            description: "A simple command that confirms that Robert is the best.",
            usage: "ridb [response]",
            author: "Endebert",
            visible: false,
            handler: function (args) {
                let output = "Paul:\t'Robert ist der Beste!'";
                if (args.length > 0)
                    output += "\nRobert:\t'" + args.join(" ") + "'";
                else {
                    output += "\nThere was no response...";
                }
                return output;
            }
        }
    ];
}
<|endoftext|>


<commit_before>/*	VCO.DateUtil
	Utilities for parsing time
================================================== */

VCO.DateUtil = {
	get: function (id) {
		return (typeof id === 'string' ? document.getElementById(id) : id);
	},

	sortByDate: function(array) { // only for use with slide data objects
		array.sort(function(a,b){
			if (a.date.data.date_obj < b.date.data.date_obj) return -1;
			if (a.date.data.date_obj > b.date.data.date_obj) return 1;
			return 0;
		});
	},

	/*	Find Best Format
	================================================== */
	findBestFormat: function(data) {
		var eval_array = ["millisecond", "second", "minute", "hour", "day", "month", "year"],
			format = "";

		for (var i = 0; i < eval_array.length; i++) {
			if (data[eval_array[i]]) {
				return VCO.DateUtil.best_dateformat_lookup[eval_array[i]];
			}
		};
		return "";
	},

	best_dateformat_lookup: {
		millisecond: 1,
		second: VCO.Language.dateformats.time_short,
		minute: VCO.Language.dateformats.time_no_seconds_short,
		hour: VCO.Language.dateformats.time_no_seconds_short,
		day: VCO.Language.dateformats.full_short,
		month: VCO.Language.dateformats.month_short,
		year: VCO.Language.dateformats.year,
		decade: VCO.Language.dateformats.year,
		century: VCO.Language.dateformats.year,
		millennium: VCO.Language.dateformats.year,
		age: VCO.Language.dateformats.year,
		epoch: VCO.Language.dateformats.year,
		era: VCO.Language.dateformats.year,
		eon: VCO.Language.dateformats.year,
	}

};<commit_msg>refactor sortByDate to use date comparison (will help with #2)<commit_after>/*	VCO.DateUtil
	Utilities for parsing time
================================================== */

VCO.DateUtil = {
	get: function (id) {
		return (typeof id === 'string' ? document.getElementById(id) : id);
	},

	sortByDate: function(array) { // only for use with slide data objects
		array.sort(function(a,b){
			if (a.date.isBefore(b.date)) return -1;
			if (a.date.isAfter(b.date)) return 1;
			return 0;
		});
	},

	/*	Find Best Format
	================================================== */
	findBestFormat: function(data) {
		var eval_array = ["millisecond", "second", "minute", "hour", "day", "month", "year"],
			format = "";

		for (var i = 0; i < eval_array.length; i++) {
			if (data[eval_array[i]]) {
				return VCO.DateUtil.best_dateformat_lookup[eval_array[i]];
			}
		};
		return "";
	},

	best_dateformat_lookup: {
		millisecond: 1,
		second: VCO.Language.dateformats.time_short,
		minute: VCO.Language.dateformats.time_no_seconds_short,
		hour: VCO.Language.dateformats.time_no_seconds_short,
		day: VCO.Language.dateformats.full_short,
		month: VCO.Language.dateformats.month_short,
		year: VCO.Language.dateformats.year,
		decade: VCO.Language.dateformats.year,
		century: VCO.Language.dateformats.year,
		millennium: VCO.Language.dateformats.year,
		age: VCO.Language.dateformats.year,
		epoch: VCO.Language.dateformats.year,
		era: VCO.Language.dateformats.year,
		eon: VCO.Language.dateformats.year,
	}

};<|endoftext|>


<commit_before>import React, { Component } from 'react';
import {
	ReactiveBase,
	CategorySearch,
	ResultCard,
	MultiDropdownList,
	RangeSlider,
	SingleDropdownRange
} from '@appbaseio/reactivesearch';

import './Base.styl';

class Base extends Component {
	constructor() {
		super();
		this.state = {
			topics: [],
			showNav: false
		};
		this.toggleTopic = this.toggleTopic.bind(this);
		this.resetTopic = this.resetTopic.bind(this);
		this.handleToggleFilters = this.handleToggleFilters.bind(this);
	}

	handleToggleFilters() {
		const showNav = !this.state.showNav;
		this.setState({
			showNav
		});
	}

	toggleTopic(topic) {
		const topics = [ ...this.state.topics ];
		const index = topics.indexOf(topic);
		let nextTopics = [];
		if (index === -1) {
			nextTopics = [ ...topics, topic ];
		} else {
			nextTopics = topics.slice(0, index).concat(topics.slice(index + 1));
		}
		this.setState({
			topics: nextTopics
		});
	}

	resetTopic(topics) {
		this.setState({
			topics
		});
	}

	onData(res, toggleTopic) {
		const result = {
			desc: (

									{res.owner}/{res.owner.length + res.name.length > 27 ?
 : ''}{res.name}

								{res.description}

							{
								res.topics.length > 0 ?

										{res.topics.slice(0, 7).map(topic => <span className="card-tag" key={`${res.name}-${topic}`} onClick={() => toggleTopic(topic)}>#{topic})}

 :
								null
							}

								{res.stars}

								{res.forks}

								{res.watchers}

			)
		};
		return result;
	}

	render() {
		return (
			<ReactiveBase
				app="gitxplore-latest"
				credentials="W7ZomvYgQ:df994896-a25d-4d4e-8724-e26659b93001"
				theme="rbc-green"
			>
				<div className={`${this.state.showNav ? 'full-header' : ''}`}>

GitXplore

								Toggle Filters

								<MultiDropdownList
									componentId="language"
									appbaseField="language.raw"
									title="Language"
									size={100}
								/>
								<MultiDropdownList
									componentId="topics"
									appbaseField="topics.raw"
									title="Repo Topics"
									defaultSelected={this.state.topics}
									size={1000}
									queryFormat="and"
									onValueChange={value => this.resetTopic(value)}
								/>
								<SingleDropdownRange
									componentId="pushed"
									appbaseField="pushed"
									title="Last Active"
									data={[
										{"start": "now-1M", "end": "now", "label": "Last 30 days"},
										{"start": "now-6M", "end": "now", "label": "Last 6 months"},
										{"start": "now-1y", "end": "now", "label": "Last year"}
									]}
								/>
								<SingleDropdownRange
									componentId="created"
									appbaseField="created"
									title="Created"
									data={[
										{"start": "2017-01-01T00:00:00Z", "end": "2017-12-31T23:59:59Z", "label": "2017"},
										{"start": "2016-01-01T00:00:00Z", "end": "2016-12-31T23:59:59Z", "label": "2016"},
										{"start": "2015-01-01T00:00:00Z", "end": "2015-12-31T23:59:59Z", "label": "2015"},
										{"start": "2014-01-01T00:00:00Z", "end": "2014-12-31T23:59:59Z", "label": "2014"},
										{"start": "2013-01-01T00:00:00Z", "end": "2013-12-31T23:59:59Z", "label": "2013"},
										{"start": "2012-01-01T00:00:00Z", "end": "2012-12-31T23:59:59Z", "label": "2012"},
										{"start": "2011-01-01T00:00:00Z", "end": "2011-12-31T23:59:59Z", "label": "2011"},
										{"start": "2010-01-01T00:00:00Z", "end": "2010-12-31T23:59:59Z", "label": "2010"},
										{"start": "2009-01-01T00:00:00Z", "end": "2009-12-31T23:59:59Z", "label": "2009"},
										{"start": "2008-01-01T00:00:00Z", "end": "2008-12-31T23:59:59Z", "label": "2008"},
										{"start": "2007-01-01T00:00:00Z", "end": "2007-12-31T23:59:59Z", "label": "2007"}
									]}
								/>
								<RangeSlider
									componentId="stars"
									appbaseField="stars"
									title="Repo Stars"
									showHistogram={false}
									range={{
										"start": 0,
										"end": 300000
									}}
									defaultSelected={{
										"start": 0,
										"end": 300000
									}}
									rangeLabels={{
										"start": "0 Stars",
										"end": "300K Stars"
									}}
									stepValue={50}
								/>
								<RangeSlider
									componentId="forks"
									appbaseField="forks"
									title="Repo Forks"
									showHistogram={false}
									range={{
										"start": 0,
										"end": 180000
									}}
									defaultSelected={{
										"start": 0,
										"end": 180000
									}}
									rangeLabels={{
										"start": "0 Forks",
										"end": "180K Forks"
									}}
									stepValue={50}
								/>

					<CategorySearch
						componentId="repo"
						appbaseField={["name", "description", "name.raw", "fullname", "owner", "topics"]}
						categoryField="language.raw"
						queryFormat="and"
						placeholder="Search Repos"
						URLParams={true}
					/>
					<ResultCard
						componentId="SearchResult"
						appbaseField="name"
						noResults="No results were found, try clearing all the filters."
						pagination={true}
						size={6}
						onData={(res) => this.onData(res, this.toggleTopic)}
						react={{
							and: ["repo", "topics", "stars", "description", "forks", "pushed", "created", "language"]
						}}
						sortOptions={[
							{
								label: "Best Match",
								appbaseField: "_score",
								sortBy: "desc"
							},
							{
								label: "Most Stars",
								appbaseField: "stars",
								sortBy: "desc"
							},
							{
								label: "Fewest Stars",
								appbaseField: "stars",
								sortBy: "asc"
							},
							{
								label: "Most Forks",
								appbaseField: "forks",
								sortBy: "desc"
							},
							{
								label: "Fewest Forks",
								appbaseField: "forks",
								sortBy: "asc"
							},
							{
								label: "A to Z",
								appbaseField: "owner.raw",
								sortBy: "asc"
							},
							{
								label: "Z to A",
								appbaseField: "owner.raw",
								sortBy: "desc"
							},
							{
								label: "Recently Updated",
								appbaseField: "pushed",
								sortBy: "desc"
							},
							{
								label: "Least Recently Updated",
								appbaseField: "pushed",
								sortBy: "asc"
							}
						]}
					/>

 window.open('https://medium.appbase.io/how-to-build-a-github-search-ui-in-60-minutes-295109211c70')}
					>

							  Read How We Built It!

			</ReactiveBase>
		);
	}
}

export default Base;
<commit_msg>Update filters<commit_after>import React, { Component } from 'react';
import {
	ReactiveBase,
	CategorySearch,
	ResultCard,
	MultiDropdownList,
	RangeSlider,
	SingleDropdownRange
} from '@appbaseio/reactivesearch';

import './Base.styl';

class Base extends Component {
	constructor() {
		super();
		this.state = {
			topics: [],
			showNav: false
		};
		this.toggleTopic = this.toggleTopic.bind(this);
		this.resetTopic = this.resetTopic.bind(this);
		this.handleToggleFilters = this.handleToggleFilters.bind(this);
	}

	handleToggleFilters() {
		const showNav = !this.state.showNav;
		this.setState({
			showNav
		});
	}

	toggleTopic(topic) {
		const topics = [ ...this.state.topics ];
		const index = topics.indexOf(topic);
		let nextTopics = [];
		if (index === -1) {
			nextTopics = [ ...topics, topic ];
		} else {
			nextTopics = topics.slice(0, index).concat(topics.slice(index + 1));
		}
		this.setState({
			topics: nextTopics
		});
	}

	resetTopic(topics) {
		this.setState({
			topics
		});
	}

	onData(res, toggleTopic) {
		const result = {
			desc: (

									{res.owner}/{res.owner.length + res.name.length > 27 ?
 : ''}{res.name}

								{res.description}

							{
								res.topics.length > 0 ?

										{res.topics.slice(0, 7).map(topic => <span className="card-tag" key={`${res.name}-${topic}`} onClick={() => toggleTopic(topic)}>#{topic})}

 :
								null
							}

								{res.stars}

								{res.forks}

								{res.watchers}

			)
		};
		return result;
	}

	render() {
		return (
			<ReactiveBase
				app="gitxplore-latest"
				credentials="W7ZomvYgQ:df994896-a25d-4d4e-8724-e26659b93001"
				theme="rbc-green"
			>
				<div className={`${this.state.showNav ? 'full-header' : ''}`}>

GitXplore

								Toggle Filters

								<MultiDropdownList
									componentId="language"
									appbaseField="language.raw"
									title="Language"
									size={100}
								/>
								<MultiDropdownList
									componentId="topics"
									appbaseField="topics.raw"
									title="Repo Topics"
									defaultSelected={this.state.topics}
									size={1000}
									queryFormat="and"
									onValueChange={value => this.resetTopic(value)}
								/>
								<SingleDropdownRange
									componentId="pushed"
									appbaseField="pushed"
									title="Last Active"
									data={[
										{"start": "now-1M", "end": "now", "label": "Last 30 days"},
										{"start": "now-6M", "end": "now", "label": "Last 6 months"},
										{"start": "now-1y", "end": "now", "label": "Last year"}
									]}
								/>
								<SingleDropdownRange
									componentId="created"
									appbaseField="created"
									title="Created"
									data={[
										{"start": "2017-01-01T00:00:00Z", "end": "2017-12-31T23:59:59Z", "label": "2017"},
										{"start": "2016-01-01T00:00:00Z", "end": "2016-12-31T23:59:59Z", "label": "2016"},
										{"start": "2015-01-01T00:00:00Z", "end": "2015-12-31T23:59:59Z", "label": "2015"},
										{"start": "2014-01-01T00:00:00Z", "end": "2014-12-31T23:59:59Z", "label": "2014"},
										{"start": "2013-01-01T00:00:00Z", "end": "2013-12-31T23:59:59Z", "label": "2013"},
										{"start": "2012-01-01T00:00:00Z", "end": "2012-12-31T23:59:59Z", "label": "2012"},
										{"start": "2011-01-01T00:00:00Z", "end": "2011-12-31T23:59:59Z", "label": "2011"},
										{"start": "2010-01-01T00:00:00Z", "end": "2010-12-31T23:59:59Z", "label": "2010"},
										{"start": "2009-01-01T00:00:00Z", "end": "2009-12-31T23:59:59Z", "label": "2009"},
										{"start": "2008-01-01T00:00:00Z", "end": "2008-12-31T23:59:59Z", "label": "2008"},
										{"start": "2007-01-01T00:00:00Z", "end": "2007-12-31T23:59:59Z", "label": "2007"}
									]}
								/>
								<RangeSlider
									componentId="stars"
									appbaseField="stars"
									title="Repo Stars"
									showHistogram={false}
									range={{
										"start": 0,
										"end": 300000
									}}
									defaultSelected={{
										"start": 0,
										"end": 300000
									}}
									rangeLabels={{
										"start": "0 Stars",
										"end": "300K Stars"
									}}
									stepValue={1}
									URLParams
								/>
								<RangeSlider
									componentId="forks"
									appbaseField="forks"
									title="Repo Forks"
									showHistogram={false}
									range={{
										"start": 0,
										"end": 180000
									}}
									defaultSelected={{
										"start": 0,
										"end": 180000
									}}
									rangeLabels={{
										"start": "0 Forks",
										"end": "180K Forks"
									}}
									stepValue={1}
									URLParams
								/>

					<CategorySearch
						componentId="repo"
						appbaseField={["name", "description", "name.raw", "fullname", "owner", "topics"]}
						categoryField="language.raw"
						queryFormat="and"
						placeholder="Search Repos"
						URLParams={true}
					/>
					<ResultCard
						componentId="SearchResult"
						appbaseField="name"
						noResults="No results were found, try clearing all the filters."
						pagination={true}
						size={6}
						onData={(res) => this.onData(res, this.toggleTopic)}
						react={{
							and: ["repo", "topics", "stars", "description", "forks", "pushed", "created", "language"]
						}}
						sortOptions={[
							{
								label: "Best Match",
								appbaseField: "_score",
								sortBy: "desc"
							},
							{
								label: "Most Stars",
								appbaseField: "stars",
								sortBy: "desc"
							},
							{
								label: "Fewest Stars",
								appbaseField: "stars",
								sortBy: "asc"
							},
							{
								label: "Most Forks",
								appbaseField: "forks",
								sortBy: "desc"
							},
							{
								label: "Fewest Forks",
								appbaseField: "forks",
								sortBy: "asc"
							},
							{
								label: "A to Z",
								appbaseField: "owner.raw",
								sortBy: "asc"
							},
							{
								label: "Z to A",
								appbaseField: "owner.raw",
								sortBy: "desc"
							},
							{
								label: "Recently Updated",
								appbaseField: "pushed",
								sortBy: "desc"
							},
							{
								label: "Least Recently Updated",
								appbaseField: "pushed",
								sortBy: "asc"
							}
						]}
					/>

 window.open('https://medium.appbase.io/how-to-build-a-github-search-ui-in-60-minutes-295109211c70')}
					>

							  Read How We Built It!

			</ReactiveBase>
		);
	}
}

export default Base;
<|endoftext|>


<commit_before>/*
 * grunt-phpunit
 * https://github.com/SaschaGalley/grunt-phpunit
 *
 * Copyright (c) 2013 Sascha Galley
 * http://xash.at
 * Licensed under the MIT license.
 */
'use strict';

// External libs.
var path = require('path');
var exec = require('child_process').exec;

exports.init = function(grunt) {

    var exports  = {},
        defaults = {
            // Default options
            bin: 'phpcs',
            debug: false,
            extensions: false,
            ignore: false,
            severity: false,
            standard: false,
            verbose: false,
            logfile: false
        },
        cmd    = null,
        done   = null,
        config = {};

    /**
     * Builds phpunit command
     *
     * @return string
     */
    var buildCommand = function(dir) {

        var cmd = path.normalize(config.bin);

        if (grunt.option('debug') || config.debug === true) {
            // Display debbuging information during test execution.
            cmd += ' --debug';
        }

        if (grunt.option('extensions') || config.extensions) {
            // A comma separated list of file extensions to check
            cmd += ' --extensions=' + config.extensions;
        }

        if (grunt.option('ignore') || config.ignore) {
            // A comma separated list of patterns to ignore files and directories.
            cmd += ' --ignore=' + config.ignore;
        }

        if (grunt.option('severity') || config.severity) {
            // The minimum severity required to display an error or warning
            cmd += ' --severity=' + config.severity;
        }

        if (grunt.option('verbose') || config.standard) {
            // Define the code sniffer standard.
            cmd += ' --standard=' + config.standard;
        }

        if (grunt.option('report-file') || config.reportFile) {
            // Define the code sniffer standard.
            cmd += ' --report-file=' + config.reportFile;
        }

        if (grunt.option('verbose') || config.verbose === true) {
            // Output more verbose information.
            cmd += ' -v';
        }
        return cmd;
    };

    /**
     * Setup task before running it
     *
     * @param Object runner
     */
    exports.setup = function(runner) {

        var dir = path.normalize(runner.data.dir);
        config  = runner.options(defaults);
        cmd     = buildCommand(dir) + ' ' + dir;

        grunt.log.writeln('Starting phpcs (target: ' + runner.target.cyan + ') in ' + dir.cyan);
        grunt.verbose.writeln('Exec: ' + cmd);

        done    = runner.async();
    };

    /**
     * Runs phpunit command with options
     *
     */
    exports.run = function() {

        exec(cmd, function(err, stdout, stderr) {

            if (stdout) {
                grunt.log.write(stdout);
            }

            if (err) {
                grunt.fatal(err);
            }
            done();
        });
    };

    return exports;
};
<commit_msg>Renaming config value<commit_after>/*
 * grunt-phpunit
 * https://github.com/SaschaGalley/grunt-phpunit
 *
 * Copyright (c) 2013 Sascha Galley
 * http://xash.at
 * Licensed under the MIT license.
 */
'use strict';

// External libs.
var path = require('path');
var exec = require('child_process').exec;

exports.init = function(grunt) {

    var exports  = {},
        defaults = {
            // Default options
            bin: 'phpcs',
            debug: false,
            extensions: false,
            ignore: false,
            severity: false,
            standard: false,
            verbose: false,
            reportFile: false
        },
        cmd    = null,
        done   = null,
        config = {};

    /**
     * Builds phpunit command
     *
     * @return string
     */
    var buildCommand = function(dir) {

        var cmd = path.normalize(config.bin);

        if (grunt.option('debug') || config.debug === true) {
            // Display debbuging information during test execution.
            cmd += ' --debug';
        }

        if (grunt.option('extensions') || config.extensions) {
            // A comma separated list of file extensions to check
            cmd += ' --extensions=' + config.extensions;
        }

        if (grunt.option('ignore') || config.ignore) {
            // A comma separated list of patterns to ignore files and directories.
            cmd += ' --ignore=' + config.ignore;
        }

        if (grunt.option('severity') || config.severity) {
            // The minimum severity required to display an error or warning
            cmd += ' --severity=' + config.severity;
        }

        if (grunt.option('verbose') || config.standard) {
            // Define the code sniffer standard.
            cmd += ' --standard=' + config.standard;
        }

        if (grunt.option('report-file') || config.reportFile) {
            // Define the code sniffer standard.
            cmd += ' --report-file=' + config.reportFile;
        }

        if (grunt.option('verbose') || config.verbose === true) {
            // Output more verbose information.
            cmd += ' -v';
        }
        return cmd;
    };

    /**
     * Setup task before running it
     *
     * @param Object runner
     */
    exports.setup = function(runner) {

        var dir = path.normalize(runner.data.dir);
        config  = runner.options(defaults);
        cmd     = buildCommand(dir) + ' ' + dir;

        grunt.log.writeln('Starting phpcs (target: ' + runner.target.cyan + ') in ' + dir.cyan);
        grunt.verbose.writeln('Exec: ' + cmd);

        done    = runner.async();
    };

    /**
     * Runs phpunit command with options
     *
     */
    exports.run = function() {

        exec(cmd, function(err, stdout, stderr) {

            if (stdout) {
                grunt.log.write(stdout);
            }

            if (err) {
                grunt.fatal(err);
            }
            done();
        });
    };

    return exports;
};
<|endoftext|>


<commit_before>/*
 *
 * Copyright 2015-2016, Google Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */

'use strict';

var BenchmarkClient = require('./benchmark_client');
var BenchmarkServer = require('./benchmark_server');

exports.runClient = function runClient(call) {
  var client;
  call.on('data', function(request) {
    var stats;
    switch (request.argtype) {
      case 'setup':
      var setup = request.setup;
      client = new BenchmarkClient(setup.server_targets,
                                   setup.client_channels,
                                   setup.histogram_params,
                                   setup.security_params);
      client.on('error', function(error) {
        call.emit('error', error);
      });
      switch (setup.load_params.load) {
        case 'closed_loop':
        client.startClosedLoop(setup.outstanding_rpcs_per_channel,
                               setup.rpc_type,
                               setup.payload_config.simple_params.req_size,
                               setup.payload_config.simple_params.resp_size);
        break;
        case 'poisson':
        client.startPoisson(setup.outstanding_rpcs_per_channel,
                            setup.rpc_type, setup.payload_config.req_size,
                            setup.payload_config.resp_size,
                            setup.load_params.poisson.offered_load);
        break;
        default:
        call.emit('error', new Error('Unsupported LoadParams type' +
            setup.load_params.load));
      }
      stats = client.mark();
      call.write({
        stats: stats
      });
      break;
      case 'mark':
      if (client) {
        stats = client.mark(request.mark.reset);
        call.write({
          stats: stats
        });
      } else {
        call.emit('error', new Error('Got Mark before ClientConfig'));
      }
      break;
      default:
      throw new Error('Nonexistent client argtype option: ' + request.argtype);
    }
  });
  call.on('end', function() {
    client.stop(function() {
      call.end();
    });
  });
};

exports.runServer = function runServer(call) {
  var server;
  call.on('data', function(request) {
    var stats;
    switch (request.argtype) {
      case 'setup':
      server = new BenchmarkServer('[::]', request.setup.port,
                                   request.setup.security_params);
      server.start();
      stats = server.mark();
      call.write({
        stats: stats,
        port: server.getPort()
      });
      break;
      case 'mark':
      if (server) {
        stats = server.mark(request.mark.reset);
        call.write({
          stats: stats,
          port: server.getPort(),
          cores: 1
        });
      } else {
        call.emit('error', new Error('Got Mark before ServerConfig'));
      }
      break;
      default:
      throw new Error('Nonexistent server argtype option');
    }
  });
  call.on('end', function() {
    server.stop(function() {
      call.end();
    });
  });
};
<commit_msg>Add quit option to Node.js worker<commit_after>/*
 *
 * Copyright 2015-2016, Google Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */

'use strict';

var BenchmarkClient = require('./benchmark_client');
var BenchmarkServer = require('./benchmark_server');

exports.quitWorker = function quitWorker(call, callback) {
  callback(null, {});
  process.exit(0);
}

exports.runClient = function runClient(call) {
  var client;
  call.on('data', function(request) {
    var stats;
    switch (request.argtype) {
      case 'setup':
      var setup = request.setup;
      client = new BenchmarkClient(setup.server_targets,
                                   setup.client_channels,
                                   setup.histogram_params,
                                   setup.security_params);
      client.on('error', function(error) {
        call.emit('error', error);
      });
      switch (setup.load_params.load) {
        case 'closed_loop':
        client.startClosedLoop(setup.outstanding_rpcs_per_channel,
                               setup.rpc_type,
                               setup.payload_config.simple_params.req_size,
                               setup.payload_config.simple_params.resp_size);
        break;
        case 'poisson':
        client.startPoisson(setup.outstanding_rpcs_per_channel,
                            setup.rpc_type, setup.payload_config.req_size,
                            setup.payload_config.resp_size,
                            setup.load_params.poisson.offered_load);
        break;
        default:
        call.emit('error', new Error('Unsupported LoadParams type' +
            setup.load_params.load));
      }
      stats = client.mark();
      call.write({
        stats: stats
      });
      break;
      case 'mark':
      if (client) {
        stats = client.mark(request.mark.reset);
        call.write({
          stats: stats
        });
      } else {
        call.emit('error', new Error('Got Mark before ClientConfig'));
      }
      break;
      default:
      throw new Error('Nonexistent client argtype option: ' + request.argtype);
    }
  });
  call.on('end', function() {
    client.stop(function() {
      call.end();
    });
  });
};

exports.runServer = function runServer(call) {
  var server;
  call.on('data', function(request) {
    var stats;
    switch (request.argtype) {
      case 'setup':
      server = new BenchmarkServer('[::]', request.setup.port,
                                   request.setup.security_params);
      server.start();
      stats = server.mark();
      call.write({
        stats: stats,
        port: server.getPort()
      });
      break;
      case 'mark':
      if (server) {
        stats = server.mark(request.mark.reset);
        call.write({
          stats: stats,
          port: server.getPort(),
          cores: 1
        });
      } else {
        call.emit('error', new Error('Got Mark before ServerConfig'));
      }
      break;
      default:
      throw new Error('Nonexistent server argtype option');
    }
  });
  call.on('end', function() {
    server.stop(function() {
      call.end();
    });
  });
};
<|endoftext|>


<commit_before>doesItSuck.factory('presentationFactory', presentationFactory);

  function presentationFactory() {

  var COLORCHOICE = {'SUCKS': 'red', 'DOESN\'T SUCK': 'green', 'MEH': 'yellow'};
  var RESULT_TERMS = {'positive': 'DOESN\'T SUCK', 'negative': 'SUCKS', 'neutral': 'MEH'};
  var SNARKY = [
                "Oh well",
                "Who would have thought",
                "Amazing",
                "Who cares",
                "How surprising",
                "Fantastic",
                "How boring"
              ];

  var chart =  {colors: ['#02D606', '#FFC400', '#FF2626'],
               series:  ['Positive', 'Neutral', 'Negative'],
               labels:  ['7 days ago', '4 days ago', 'Yesterday']};

  var service = {
    evaluateSearch: evaluateSearch,
    getFullColorScheme: getFullColorScheme,
    getColorScheme: getColorScheme,
    insertHTML: insertHTML,
    getChart: getChart,
    getFontColor: getFontColor,
    operator: operator,
    getOutcome: getOutcome,
    snarkyComment: snarkyComment
  };

  return service;

  function getChart() {
    return chart;
  }

  function evaluateSearch(search) {
    if( search.positive > 1.5 * search.negative) {
      return RESULT_TERMS.positive;
    } else if( search.negative > 1.5 * search.positive) {
      return RESULT_TERMS.negative;
    } else {
      return RESULT_TERMS.neutral;
    }
  }

  function operator(comparison) {
    if (comparison[0].score > comparison[1].score) {
      return ">";
    } else if (comparison[0].score < comparison[1].score) {
      return "<";
    } else {
      return "=";
    }
  }

  function snarkyComment() {
    var index = Math.floor(Math.random()*SNARKY.length);
    return SNARKY[index];
  }

  function getOutcome(comparison) {
    var winner;
    var loser;
    if (comparison[0].score > comparison[1].score) {
      winner = comparison[0].search_term;
      loser = comparison[1].search_term;
    } else if (comparison[0].score < comparison[1].score) {
      winner = comparison[1].search_term;
      loser = comparison[0].search_term;
    } else {
      return comparison[0] + " and " + comparison[1] + " both suck equally hard.";
    }
    loser = loser.charAt(0).toUpperCase() + loser.slice(1);
    return loser + " sucks worse than " + winner;
  }

  function getFullColorScheme(search) {
    var evaluated = evaluateSearch(search);
    return COLORCHOICE[evaluated];
  }

  function getColorScheme(search){
    return (search.winner) ? COLORCHOICE['DOESN\'T SUCK'] : COLORCHOICE['SUCKS'];
  }

  function getFontColor(score) {
    if(score > 0){return "positive-word";}
    if(score === 0){return "neutral-word";}
    if(score < 0){return "negative-word";}
  }

  function insertHTML(messages){
    messages.forEach(function(msg){
      insertSentimentClass(msg);
      insertKeyWordClass(msg, 'posWords', 'positive');
      insertKeyWordClass(msg, 'negWords', 'negative');
    });
  }

  function insertKeyWordClass(msg, keyWords, sentiment){
    var re;
    msg[keyWords].forEach(function(word){
      re = new RegExp(word, "gi");
      msg.content = msg.content.replace(re,"" + word + "");
    });
  }

  function insertSentimentClass(msg){
    var sentiment = msg.sentiment;
    msg.content = "" + msg.content +"";
  }

}
<commit_msg>fix bug in comparison<commit_after>doesItSuck.factory('presentationFactory', presentationFactory);

  function presentationFactory() {

  var COLORCHOICE = {'SUCKS': 'red', 'DOESN\'T SUCK': 'green', 'MEH': 'yellow'};
  var RESULT_TERMS = {'positive': 'DOESN\'T SUCK', 'negative': 'SUCKS', 'neutral': 'MEH'};
  var SNARKY = [
                "Oh well",
                "Who would have thought",
                "Amazing",
                "Who cares",
                "How surprising",
                "Fantastic",
                "How boring"
              ];

  var chart =  {colors: ['#02D606', '#FFC400', '#FF2626'],
               series:  ['Positive', 'Neutral', 'Negative'],
               labels:  ['7 days ago', '4 days ago', 'Yesterday']};

  var service = {
    evaluateSearch: evaluateSearch,
    getFullColorScheme: getFullColorScheme,
    getColorScheme: getColorScheme,
    insertHTML: insertHTML,
    getChart: getChart,
    getFontColor: getFontColor,
    operator: operator,
    getOutcome: getOutcome,
    snarkyComment: snarkyComment
  };

  return service;

  function getChart() {
    return chart;
  }

  function evaluateSearch(search) {
    if( search.positive > 1.5 * search.negative) {
      return RESULT_TERMS.positive;
    } else if( search.negative > 1.5 * search.positive) {
      return RESULT_TERMS.negative;
    } else {
      return RESULT_TERMS.neutral;
    }
  }

  function operator(comparison) {
    if (comparison[0].score > comparison[1].score) {
      return ">";
    } else if (comparison[0].score < comparison[1].score) {
      return "<";
    } else {
      return "=";
    }
  }

  function snarkyComment() {
    var index = Math.floor(Math.random()*SNARKY.length);
    return SNARKY[index];
  }

  function getOutcome(comparison) {
    var winner;
    var loser;
    if (comparison[0].score > comparison[1].score) {
      winner = comparison[0].search_term;
      loser = comparison[1].search_term;
    } else if (comparison[0].score < comparison[1].score) {
      winner = comparison[1].search_term;
      loser = comparison[0].search_term;
    } else {
      return comparison[0].search_term + " and " + comparison[1].search_term + " both suck equally hard.";
    }
    loser = loser.charAt(0).toUpperCase() + loser.slice(1);
    return loser + " sucks worse than " + winner;
  }

  function getFullColorScheme(search) {
    var evaluated = evaluateSearch(search);
    return COLORCHOICE[evaluated];
  }

  function getColorScheme(search){
    return (search.winner) ? COLORCHOICE['DOESN\'T SUCK'] : COLORCHOICE['SUCKS'];
  }

  function getFontColor(score) {
    if(score > 0){return "positive-word";}
    if(score === 0){return "neutral-word";}
    if(score < 0){return "negative-word";}
  }

  function insertHTML(messages){
    messages.forEach(function(msg){
      insertSentimentClass(msg);
      insertKeyWordClass(msg, 'posWords', 'positive');
      insertKeyWordClass(msg, 'negWords', 'negative');
    });
  }

  function insertKeyWordClass(msg, keyWords, sentiment){
    var re;
    msg[keyWords].forEach(function(word){
      re = new RegExp(word, "gi");
      msg.content = msg.content.replace(re,"" + word + "");
    });
  }

  function insertSentimentClass(msg){
    var sentiment = msg.sentiment;
    msg.content = "" + msg.content +"";
  }

}
<|endoftext|>


<commit_before>const React = require('react')
const e = React.createElement
const Component = React.Component
const bindActionCreators = require('redux').bindActionCreators
const connect = require('react-redux').connect
const LoadingActions = require('../actions/loading')
const nodegit = require('../utils/nodegit').nodegit
const c = require('material-ui/Card')
const Card = c.Card
const CardTitle = c.CardTitle
const status = require('../utils/status')
const t = require('../utils/text')

class Diff extends Component {

	constructor(props) {
		super(props)

		this.state = {
			artifacts: [],
			updating: false,
		}
	}

	setUpdating(updating) {
		this.setState(Object.assign({}, this.state, { updating }))
		if (updating) {
			this.props.actions.loading.IncrementLoadingJobs()
		} else {
			this.props.actions.loading.DecrementLoadingJobs()
		}
	}

	componentDidMount() {
		this.refresh(this.props.shaA, this.props.shaB)
	}

	componentWillReceiveProps(nextProps) {
		if (this.props.shaA !== nextProps.shaA || this.props.shaB !== nextProps.shaB) {
			this.refresh(nextProps.shaA, nextProps.shaB)
		}
	}

	getStatusKeys(patch) {
		const keys = []

		if (patch.isAdded()) { keys.push(status.ADDED) }
		if (patch.isConflicted()) { keys.push(status.CONFLICTED) }
		if (patch.isCopied()) { keys.push(status.COPIED) }
		if (patch.isDeleted()) { keys.push(status.DELETED) }
		if (patch.isIgnored()) { keys.push(status.IGNORED) }
		if (patch.isModified()) { keys.push(status.MODIFIED) }
		if (patch.isRenamed()) { keys.push(status.RENAMED) }
		if (patch.isTypeChange()) { keys.push(status.TYPECHANGE) }
		if (patch.isUnmodified()) { keys.push(status.UNMODIFIED) }
		if (patch.isUnreadable()) { keys.push(status.UNREADABLE) }
		if (patch.isUntracked()) { keys.push(status.UNTRACKED) }

		return keys
	}

	refresh(shaA, shaB) {
		if (!shaA) {
			return
		}
		this.setUpdating(true)
		let repo
		let artifacts = []
		let treeA
		let patches
		let currentPathIndex
		let hunks
		let currentHunkIndex

		const processPatch = () => {
			if (patches.length === currentPathIndex) {
				return Promise.resolve()
			}
			const patch = patches[currentPathIndex++]

			artifacts[currentPathIndex] = {
				oldName: patch.oldFile().path(), // @TODO: check why oldName = newName always
				newName: patch.newFile().path(),
				hunks: [],
				status: this.getStatusKeys(patch),
			}

			return patch.hunks()
				.then((h) => {
					hunks = h
					currentHunkIndex = 0
					return processHunk()
				})
				.then(processPatch)
		}

		const processHunk = () => {
			if (hunks.length === currentHunkIndex) {
				return Promise.resolve()
			}

			const hunk = hunks[currentHunkIndex++]

			return hunk.lines()
				.then((lines) => {
					artifacts[currentPathIndex].hunks.push(lines.map((line) => {
						const originsWithoutNumber = ['>', '<']
						const origin = String.fromCharCode(line.origin())
						const lineNumber = originsWithoutNumber.includes(origin) ? '' : ((line.newLineno() !== -1 ? line.newLineno() : line.oldLineno()) + '.')
						return {
							origin,
							content: line.content(),
							line: lineNumber,
						}
					}))
				})
				.then(processHunk)
		}

		nodegit.Repository.open(this.props.projects.active.path)
			.then((r) => {
				repo = r
				return repo.getCommit(shaA)
			})
			.then((commit) => commit.getTree())
			.then((t) => treeA = t)
			.then(() => shaB && repo.getCommit(shaB))
			.then((commit) => commit && commit.getTree())
			.then((t) => treeA.diff(t))
			.then((diffs) => {
				return diffs.findSimilar({
					flags: nodegit.Diff.FIND.RENAMES,
				})
					.then(() => diffs)
			})
			.then((diffs) => diffs.patches())
			.then((p) => {
				patches = p
				currentPathIndex = 0
				return processPatch()
			})
			.catch((error) => {
				console.error(error)
			})
			.then(() => {
				this.setState(Object.assign({}, this.states, { artifacts }))
				this.setUpdating(false)
			})

	}

	getArtifacts() {
		return this.state.artifacts.map((artifact, i) => {
			const name = artifact.oldName + (artifact.oldName === artifact.newName ? '' : ` > ${artifact.newName}`)
			return (
				e(
					Card,
					{
						key: i,
						className: 'diff-card',
					},
					e(
						CardTitle,
						{
							title: name,
							subtitle: artifact.status.map((k) => t(this.props.settings.language, `status_${k}`)).join(', '),
						}
					),
					e(
						'div',
						{
							className: 'diff-hunks'
						},
						this.getHunks(artifact)
					)
				)
			)
		})
	}

	getHunks(artifact) {
		return artifact.hunks.map((hunk, i) => {
			return (
				e(
					'div',
					{
						key: i,
						className: 'diff-hunk',
					},
					e(
						'div',
						{
							className: 'diff-hunk-in'
						},
						hunk.map((line, l) => {
							const classes = ['diff-line']
							switch (line.origin) {
								case '+':
									classes.push('diff-line-addition')
									break
								case '-':
									classes.push('diff-line-removal')
									break
							}
							return (
								e(
									'div',
									{
										key: l,
										className: classes.join(' '),
									},
									e(
										'div',
										{
											className: 'diff-line-number',
										},
										line.line
									),
									e(
										'div',
										{
											className: 'diff-line-origin',
										},
										line.origin
									),
									e(
										'pre',
										{
											className: 'diff-line-code',
										},
										line.content
									)
								)
							)
						})
					)
				)
			)
		})
	}

	render() {
		const renderArtifacts = () => {
			const artifacts = this.getArtifacts()
			if (artifacts.length) {
				return artifacts
			} else if (this.state.updating || !this.props.shaA) {
				return null
			} else {
				return e('div', null, 'Bez změn.')
			}

		}

		return (
			e(
				'div',
				null,
				renderArtifacts()
			)
		)
	}

}

function mapStateToProps(state) {
	return {
		loading: state.loading,
		projects: state.projects,
		settings: state.settings,
	}
}

function mapDispatchToProps(dispatch) {
	return {
		actions: {
			loading: bindActionCreators(LoadingActions, dispatch),
		}
	}
}

module.exports = connect(mapStateToProps, mapDispatchToProps)(Diff)
<commit_msg>Diff: loading icon<commit_after>const React = require('react')
const e = React.createElement
const Component = React.Component
const bindActionCreators = require('redux').bindActionCreators
const connect = require('react-redux').connect
const LoadingActions = require('../actions/loading')
const nodegit = require('../utils/nodegit').nodegit
const c = require('material-ui/Card')
const Card = c.Card
const CardTitle = c.CardTitle
const status = require('../utils/status')
const t = require('../utils/text')
const CircularProgress = require('material-ui/CircularProgress').default

class Diff extends Component {

	constructor(props) {
		super(props)

		this.state = {
			artifacts: [],
			updating: false,
		}
	}

	setUpdating(updating) {
		this.setState(Object.assign({}, this.state, { updating }))
		if (updating) {
			this.props.actions.loading.IncrementLoadingJobs()
		} else {
			this.props.actions.loading.DecrementLoadingJobs()
		}
	}

	componentDidMount() {
		this.refresh(this.props.shaA, this.props.shaB)
	}

	componentWillReceiveProps(nextProps) {
		if (this.props.shaA !== nextProps.shaA || this.props.shaB !== nextProps.shaB) {
			this.refresh(nextProps.shaA, nextProps.shaB)
		}
	}

	getStatusKeys(patch) {
		const keys = []

		if (patch.isAdded()) { keys.push(status.ADDED) }
		if (patch.isConflicted()) { keys.push(status.CONFLICTED) }
		if (patch.isCopied()) { keys.push(status.COPIED) }
		if (patch.isDeleted()) { keys.push(status.DELETED) }
		if (patch.isIgnored()) { keys.push(status.IGNORED) }
		if (patch.isModified()) { keys.push(status.MODIFIED) }
		if (patch.isRenamed()) { keys.push(status.RENAMED) }
		if (patch.isTypeChange()) { keys.push(status.TYPECHANGE) }
		if (patch.isUnmodified()) { keys.push(status.UNMODIFIED) }
		if (patch.isUnreadable()) { keys.push(status.UNREADABLE) }
		if (patch.isUntracked()) { keys.push(status.UNTRACKED) }

		return keys
	}

	refresh(shaA, shaB) {
		if (!shaA) {
			return
		}
		this.setUpdating(true)
		let repo
		let artifacts = []
		let treeA
		let patches
		let currentPathIndex
		let hunks
		let currentHunkIndex

		const processPatch = () => {
			if (patches.length === currentPathIndex) {
				return Promise.resolve()
			}
			const patch = patches[currentPathIndex++]

			artifacts[currentPathIndex] = {
				oldName: patch.oldFile().path(), // @TODO: check why oldName = newName always
				newName: patch.newFile().path(),
				hunks: [],
				status: this.getStatusKeys(patch),
			}

			return patch.hunks()
				.then((h) => {
					hunks = h
					currentHunkIndex = 0
					return processHunk()
				})
				.then(processPatch)
		}

		const processHunk = () => {
			if (hunks.length === currentHunkIndex) {
				return Promise.resolve()
			}

			const hunk = hunks[currentHunkIndex++]

			return hunk.lines()
				.then((lines) => {
					artifacts[currentPathIndex].hunks.push(lines.map((line) => {
						const originsWithoutNumber = ['>', '<']
						const origin = String.fromCharCode(line.origin())
						const lineNumber = originsWithoutNumber.includes(origin) ? '' : ((line.newLineno() !== -1 ? line.newLineno() : line.oldLineno()) + '.')
						return {
							origin,
							content: line.content(),
							line: lineNumber,
						}
					}))
				})
				.then(processHunk)
		}

		nodegit.Repository.open(this.props.projects.active.path)
			.then((r) => {
				repo = r
				return repo.getCommit(shaA)
			})
			.then((commit) => commit.getTree())
			.then((t) => treeA = t)
			.then(() => shaB && repo.getCommit(shaB))
			.then((commit) => commit && commit.getTree())
			.then((t) => treeA.diff(t))
			.then((diffs) => {
				return diffs.findSimilar({
					flags: nodegit.Diff.FIND.RENAMES,
				})
					.then(() => diffs)
			})
			.then((diffs) => diffs.patches())
			.then((p) => {
				patches = p
				currentPathIndex = 0
				return processPatch()
			})
			.catch((error) => {
				console.error(error)
			})
			.then(() => {
				this.setState(Object.assign({}, this.states, { artifacts }))
				this.setUpdating(false)
			})

	}

	getArtifacts() {
		return this.state.artifacts.map((artifact, i) => {
			const name = artifact.oldName + (artifact.oldName === artifact.newName ? '' : ` > ${artifact.newName}`)
			return (
				e(
					Card,
					{
						key: i,
						className: 'diff-card',
					},
					e(
						CardTitle,
						{
							title: name,
							subtitle: artifact.status.map((k) => t(this.props.settings.language, `status_${k}`)).join(', '),
						}
					),
					e(
						'div',
						{
							className: 'diff-hunks'
						},
						this.getHunks(artifact)
					)
				)
			)
		})
	}

	getHunks(artifact) {
		return artifact.hunks.map((hunk, i) => {
			return (
				e(
					'div',
					{
						key: i,
						className: 'diff-hunk',
					},
					e(
						'div',
						{
							className: 'diff-hunk-in'
						},
						hunk.map((line, l) => {
							const classes = ['diff-line']
							switch (line.origin) {
								case '+':
									classes.push('diff-line-addition')
									break
								case '-':
									classes.push('diff-line-removal')
									break
							}
							return (
								e(
									'div',
									{
										key: l,
										className: classes.join(' '),
									},
									e(
										'div',
										{
											className: 'diff-line-number',
										},
										line.line
									),
									e(
										'div',
										{
											className: 'diff-line-origin',
										},
										line.origin
									),
									e(
										'pre',
										{
											className: 'diff-line-code',
										},
										line.content
									)
								)
							)
						})
					)
				)
			)
		})
	}

	render() {
		const renderArtifacts = () => {
			const artifacts = this.getArtifacts()
			if (artifacts.length) {
				return artifacts
			} else if (this.state.updating) {
				return e(CircularProgress)
			} else if (!this.props.shaA) {
				return null
			} else {
				return e('div', null, 'Bez změn.')
			}

		}

		return (
			e(
				'div',
				null,
				renderArtifacts()
			)
		)
	}

}

function mapStateToProps(state) {
	return {
		loading: state.loading,
		projects: state.projects,
		settings: state.settings,
	}
}

function mapDispatchToProps(dispatch) {
	return {
		actions: {
			loading: bindActionCreators(LoadingActions, dispatch),
		}
	}
}

module.exports = connect(mapStateToProps, mapDispatchToProps)(Diff)
<|endoftext|>