<commit_before>$( document ).ready(function() {

    // url
    var url = window.location.pathname;

    // Fix back button cache problem
    window.onunload = function(){};

    // Set theme
    var theme = localStorage.getItem('theme');
    if (theme === null) { theme = 'light'; }

    set_theme(theme);

    // Syntax highlighting Configuration
    hljs.configure({
        tabReplace: '    ', // 4 spaces
        languages: [],      // Languages used for auto-detection
    });

    $('code').each(function(i, block) {
        hljs.highlightBlock(block);
    });

    // Adding the hljs class gives code blocks the color css
    // even if highlighting doesn't apply
    $('code').addClass('hljs');

    var KEY_CODES = {
        PREVIOUS_KEY: 37,
        NEXT_KEY: 39
    };

    $(document).on('keydown', function (e) {
        if (e.altKey || e.ctrlKey || e.metaKey || e.shiftKey) { return; }
        switch (e.keyCode) {
            case KEY_CODES.NEXT_KEY:
                e.preventDefault();
                if($('.nav-chapters.next').length) {
                    window.location.href = $('.nav-chapters.next').attr('href');
                }
                break;
            case KEY_CODES.PREVIOUS_KEY:
                e.preventDefault();
                if($('.nav-chapters.previous').length) {
                    window.location.href = $('.nav-chapters.previous').attr('href');
                }
                break;
        }
    });

    // Interesting DOM Elements
    var html = $("html");
    var sidebar = $("#sidebar");
    var page_wrapper = $("#page-wrapper");
    var content = $("#content");

    // Toggle sidebar
    $("#sidebar-toggle").click(function(event){
        if ( html.hasClass("sidebar-hidden") ) {
            html.removeClass("sidebar-hidden").addClass("sidebar-visible");
            localStorage.setItem('sidebar', 'visible');
        } else if ( html.hasClass("sidebar-visible") ) {
            html.removeClass("sidebar-visible").addClass("sidebar-hidden");
            localStorage.setItem('sidebar', 'hidden');
        } else {
            if(sidebar.position().left === 0){
                html.addClass("sidebar-hidden");
                localStorage.setItem('sidebar', 'hidden');
            } else {
                html.addClass("sidebar-visible");
                localStorage.setItem('sidebar', 'visible');
            }
        }
    });

    // Scroll sidebar to current active section
    var activeSection = sidebar.find(".active");
    if(activeSection.length) {
        sidebar.scrollTop(activeSection.offset().top);
    }

    // Print button
    $("#print-button").click(function(){
        var printWindow = window.open("print.html");
    });

    if( url.substring(url.lastIndexOf('/')+1) == "print.html" ) {
        window.print();
    }

    // Theme button
    $("#theme-toggle").click(function(){
        if($('.theme-popup').length) {
            $('.theme-popup').remove();
        } else {
            var popup = $('

')
                .append($('
Light (default)
'))
                .append($('
Rust
'))
                .append($('
Coal
'))
                .append($('
Navy
'));

            popup.insertAfter(this);

            $('.theme').click(function(){
                var theme = $(this).attr('id');

                set_theme(theme);
            });
        }

    });

    function set_theme(theme) {
        if (theme == 'coal' || theme == 'navy') {
            $("[href='tomorrow-night.css']").prop('disabled', false);
            $("[href='highlight.css']").prop('disabled', true);
        } else {
            $("[href='tomorrow-night.css']").prop('disabled', true);
            $("[href='highlight.css']").prop('disabled', false);
        }

        localStorage.setItem('theme', theme);

        $('body').removeClass().addClass(theme);
    }

    // Hide Rust code lines prepended with a specific character
    var hiding_character = "#";

    $("code.language-rust").each(function(i, block){

        var code_block = $(this);
        var pre_block = $(this).parent();
        // hide lines
        var lines = code_block.html().split("\n");
        var first_non_hidden_line = false;
        var lines_hidden = false;

        for(var n = 0; n < lines.length; n++){
            if($.trim(lines[n])[0] == hiding_character){
                if(first_non_hidden_line){
                    lines[n] = "" + "\n" + lines[n].replace(/(\s*)# ?/, "$1") + "";
                }
                else {
                    lines[n] = "" + lines[n].replace(/(\s*)# ?/, "$1") + "\n"  +  "";
                }
                lines_hidden = true;
            }
            else if(first_non_hidden_line) {
                lines[n] = "\n" + lines[n];
            }
            else {
                first_non_hidden_line = true;
            }
        }
        code_block.html(lines.join(""));

        // If no lines were hidden, return
        if(!lines_hidden) { return; }

        // add expand button
        pre_block.prepend("

");

        pre_block.find("i").click(function(e){
            if( $(this).hasClass("fa-expand") ) {
                $(this).removeClass("fa-expand").addClass("fa-compress");
                pre_block.find("span.hidden").removeClass("hidden").addClass("unhidden");
            }
            else {
                $(this).removeClass("fa-compress").addClass("fa-expand");
                pre_block.find("span.unhidden").removeClass("unhidden").addClass("hidden");
            }
        });
    });

    // Process playpen code blocks
    $(".playpen").each(function(block){
        var pre_block = $(this);
        // Add play button
        var buttons = pre_block.find(".buttons");
        if( buttons.length === 0 ) {
            pre_block.prepend("

");
            buttons = pre_block.find(".buttons");
        }
        buttons.prepend("");
        buttons.prepend("");

        buttons.find(".play-button").click(function(e){
            run_rust_code(pre_block);
        });
        buttons.find(".clip-button").mouseout(function(e){
            hideTooltip(e.currentTarget);
        });
    });

    var clipboardSnippets = new Clipboard('.clip-button', {
        text: function(trigger) {
            hideTooltip(trigger);
            return trigger.parentElement.parentElement.textContent;
        }
    });
    clipboardSnippets.on('success', function(e) {
            e.clearSelection();
            showTooltip(e.trigger, "Copied!");
    });
    clipboardSnippets.on('error', function(e) {
            showTooltip(e.trigger, "Clipboard error!");
    });

});

function hideTooltip(elem) {
    elem.firstChild.innerText="";
    elem.setAttribute('class', 'fa fa-copy clip-button');
}

function showTooltip(elem, msg) {
    elem.firstChild.innerText=msg;
    elem.setAttribute('class', 'fa fa-copy tooltipped');
}

function run_rust_code(code_block) {
    var result_block = code_block.find(".result");
    if(result_block.length === 0) {
        code_block.append("");
        result_block = code_block.find(".result");
    }

    var text = code_block.find(".language-rust").text();

    var params = {
        version: "stable",
        optimize: "0",
        code: text,
    };

    if(text.includes("#![feature")) {
        params.version = "nightly";
    }

    result_block.text("Running...");

    $.ajax({
        url: "https://play.rust-lang.org/evaluate.json",
        method: "POST",
        crossDomain: true,
        dataType: "json",
        contentType: "application/json",
        data: JSON.stringify(params),
        success: function(response){
            result_block.text(response.result);
        }
    });
}
<commit_msg>One more ES5 fix.<commit_after>$( document ).ready(function() {

    // url
    var url = window.location.pathname;

    // Fix back button cache problem
    window.onunload = function(){};

    // Set theme
    var theme = localStorage.getItem('theme');
    if (theme === null) { theme = 'light'; }

    set_theme(theme);

    // Syntax highlighting Configuration
    hljs.configure({
        tabReplace: '    ', // 4 spaces
        languages: [],      // Languages used for auto-detection
    });

    $('code').each(function(i, block) {
        hljs.highlightBlock(block);
    });

    // Adding the hljs class gives code blocks the color css
    // even if highlighting doesn't apply
    $('code').addClass('hljs');

    var KEY_CODES = {
        PREVIOUS_KEY: 37,
        NEXT_KEY: 39
    };

    $(document).on('keydown', function (e) {
        if (e.altKey || e.ctrlKey || e.metaKey || e.shiftKey) { return; }
        switch (e.keyCode) {
            case KEY_CODES.NEXT_KEY:
                e.preventDefault();
                if($('.nav-chapters.next').length) {
                    window.location.href = $('.nav-chapters.next').attr('href');
                }
                break;
            case KEY_CODES.PREVIOUS_KEY:
                e.preventDefault();
                if($('.nav-chapters.previous').length) {
                    window.location.href = $('.nav-chapters.previous').attr('href');
                }
                break;
        }
    });

    // Interesting DOM Elements
    var html = $("html");
    var sidebar = $("#sidebar");
    var page_wrapper = $("#page-wrapper");
    var content = $("#content");

    // Toggle sidebar
    $("#sidebar-toggle").click(function(event){
        if ( html.hasClass("sidebar-hidden") ) {
            html.removeClass("sidebar-hidden").addClass("sidebar-visible");
            localStorage.setItem('sidebar', 'visible');
        } else if ( html.hasClass("sidebar-visible") ) {
            html.removeClass("sidebar-visible").addClass("sidebar-hidden");
            localStorage.setItem('sidebar', 'hidden');
        } else {
            if(sidebar.position().left === 0){
                html.addClass("sidebar-hidden");
                localStorage.setItem('sidebar', 'hidden');
            } else {
                html.addClass("sidebar-visible");
                localStorage.setItem('sidebar', 'visible');
            }
        }
    });

    // Scroll sidebar to current active section
    var activeSection = sidebar.find(".active");
    if(activeSection.length) {
        sidebar.scrollTop(activeSection.offset().top);
    }

    // Print button
    $("#print-button").click(function(){
        var printWindow = window.open("print.html");
    });

    if( url.substring(url.lastIndexOf('/')+1) == "print.html" ) {
        window.print();
    }

    // Theme button
    $("#theme-toggle").click(function(){
        if($('.theme-popup').length) {
            $('.theme-popup').remove();
        } else {
            var popup = $('

')
                .append($('
Light (default)
'))
                .append($('
Rust
'))
                .append($('
Coal
'))
                .append($('
Navy
'));

            popup.insertAfter(this);

            $('.theme').click(function(){
                var theme = $(this).attr('id');

                set_theme(theme);
            });
        }

    });

    function set_theme(theme) {
        if (theme == 'coal' || theme == 'navy') {
            $("[href='tomorrow-night.css']").prop('disabled', false);
            $("[href='highlight.css']").prop('disabled', true);
        } else {
            $("[href='tomorrow-night.css']").prop('disabled', true);
            $("[href='highlight.css']").prop('disabled', false);
        }

        localStorage.setItem('theme', theme);

        $('body').removeClass().addClass(theme);
    }

    // Hide Rust code lines prepended with a specific character
    var hiding_character = "#";

    $("code.language-rust").each(function(i, block){

        var code_block = $(this);
        var pre_block = $(this).parent();
        // hide lines
        var lines = code_block.html().split("\n");
        var first_non_hidden_line = false;
        var lines_hidden = false;

        for(var n = 0; n < lines.length; n++){
            if($.trim(lines[n])[0] == hiding_character){
                if(first_non_hidden_line){
                    lines[n] = "" + "\n" + lines[n].replace(/(\s*)# ?/, "$1") + "";
                }
                else {
                    lines[n] = "" + lines[n].replace(/(\s*)# ?/, "$1") + "\n"  +  "";
                }
                lines_hidden = true;
            }
            else if(first_non_hidden_line) {
                lines[n] = "\n" + lines[n];
            }
            else {
                first_non_hidden_line = true;
            }
        }
        code_block.html(lines.join(""));

        // If no lines were hidden, return
        if(!lines_hidden) { return; }

        // add expand button
        pre_block.prepend("

");

        pre_block.find("i").click(function(e){
            if( $(this).hasClass("fa-expand") ) {
                $(this).removeClass("fa-expand").addClass("fa-compress");
                pre_block.find("span.hidden").removeClass("hidden").addClass("unhidden");
            }
            else {
                $(this).removeClass("fa-compress").addClass("fa-expand");
                pre_block.find("span.unhidden").removeClass("unhidden").addClass("hidden");
            }
        });
    });

    // Process playpen code blocks
    $(".playpen").each(function(block){
        var pre_block = $(this);
        // Add play button
        var buttons = pre_block.find(".buttons");
        if( buttons.length === 0 ) {
            pre_block.prepend("

");
            buttons = pre_block.find(".buttons");
        }
        buttons.prepend("");
        buttons.prepend("");

        buttons.find(".play-button").click(function(e){
            run_rust_code(pre_block);
        });
        buttons.find(".clip-button").mouseout(function(e){
            hideTooltip(e.currentTarget);
        });
    });

    var clipboardSnippets = new Clipboard('.clip-button', {
        text: function(trigger) {
            hideTooltip(trigger);
            return trigger.parentElement.parentElement.textContent;
        }
    });
    clipboardSnippets.on('success', function(e) {
            e.clearSelection();
            showTooltip(e.trigger, "Copied!");
    });
    clipboardSnippets.on('error', function(e) {
            showTooltip(e.trigger, "Clipboard error!");
    });

});

function hideTooltip(elem) {
    elem.firstChild.innerText="";
    elem.setAttribute('class', 'fa fa-copy clip-button');
}

function showTooltip(elem, msg) {
    elem.firstChild.innerText=msg;
    elem.setAttribute('class', 'fa fa-copy tooltipped');
}

function run_rust_code(code_block) {
    var result_block = code_block.find(".result");
    if(result_block.length === 0) {
        code_block.append("");
        result_block = code_block.find(".result");
    }

    var text = code_block.find(".language-rust").text();

    var params = {
        version: "stable",
        optimize: "0",
        code: text,
    };

    if(text.indexOf("#![feature") !== -1) {
        params.version = "nightly";
    }

    result_block.text("Running...");

    $.ajax({
        url: "https://play.rust-lang.org/evaluate.json",
        method: "POST",
        crossDomain: true,
        dataType: "json",
        contentType: "application/json",
        data: JSON.stringify(params),
        success: function(response){
            result_block.text(response.result);
        }
    });
}
<|endoftext|>


<commit_before>/* jshint node: true */

module.exports = function (environment) {
    var ENV = {
        modulePrefix: 'liquid-windows-store',
        environment: environment,
        baseURL: '/',
        locationType: 'auto',
        EmberENV: {
            FEATURES: {
                // Here you can enable experimental features on an ember canary build
                // e.g. 'with-controller': true
            }
        },

        APP: {
            // Here you can pass flags/options to your application instance
            // when it is created
        }
    };

    if (environment === 'development') {
        // ENV.APP.LOG_RESOLVER = true;
        // ENV.APP.LOG_ACTIVE_GENERATION = true;
        // ENV.APP.LOG_TRANSITIONS = true;
        // ENV.APP.LOG_TRANSITIONS_INTERNAL = true;
        // ENV.APP.LOG_VIEW_LOOKUPS = true;
        // config/environment.js
        ENV.contentSecurityPolicy = {
            'default-src': "'none'",
            'script-src': "'self' https://cdn.mxpnl.com", // Allow scripts from https://cdn.mxpnl.com
            'font-src': "'self' http://fonts.gstatic.com http://i.s-microsoft.com", // Allow fonts to be loaded from http://fonts.gstatic.com
            'connect-src': "'self' https://api.mixpanel.com http://custom-api.local", // Allow data (ajax/websocket) from api.mixpanel.com and custom-api.local
            'img-src': "'self' http://store-images.microsoft.com",
            'style-src': "'self' 'unsafe-inline' http://fonts.googleapis.com", // Allow inline styles and loaded CSS from http://fonts.googleapis.com
            'media-src': "'self'"
        };

        ENV.FIXTURES = {
            enabled: true
        };
    }

    if (environment === 'test') {
        // Testem prefers this...
        ENV.baseURL = '/';
        ENV.locationType = 'none';

        // keep test console output quieter
        ENV.APP.LOG_ACTIVE_GENERATION = false;
        ENV.APP.LOG_VIEW_LOOKUPS = false;

        ENV.APP.rootElement = '#ember-testing';
    }

    if (environment === 'production') {

    }

    return ENV;
};<commit_msg>Allow Fixtures in Production Mode<commit_after>/* jshint node: true */

module.exports = function (environment) {
    var ENV = {
        modulePrefix: 'liquid-windows-store',
        environment: environment,
        baseURL: '/',
        locationType: 'auto',
        EmberENV: {
            FEATURES: {
                // Here you can enable experimental features on an ember canary build
                // e.g. 'with-controller': true
            }
        },

        APP: {
            // Here you can pass flags/options to your application instance
            // when it is created
        }
    };

    if (environment === 'development') {
        // ENV.APP.LOG_RESOLVER = true;
        // ENV.APP.LOG_ACTIVE_GENERATION = true;
        // ENV.APP.LOG_TRANSITIONS = true;
        // ENV.APP.LOG_TRANSITIONS_INTERNAL = true;
        // ENV.APP.LOG_VIEW_LOOKUPS = true;
        // config/environment.js
    }

    if (environment === 'test') {
        // Testem prefers this...
        ENV.baseURL = '/';
        ENV.locationType = 'none';

        // keep test console output quieter
        ENV.APP.LOG_ACTIVE_GENERATION = false;
        ENV.APP.LOG_VIEW_LOOKUPS = false;

        ENV.APP.rootElement = '#ember-testing';
    }

    if (environment === 'production') {

    }

    ENV.contentSecurityPolicy = {
        'default-src': "'none'",
        'script-src': "'self' https://cdn.mxpnl.com", // Allow scripts from https://cdn.mxpnl.com
        'font-src': "'self' http://fonts.gstatic.com http://i.s-microsoft.com", // Allow fonts to be loaded from http://fonts.gstatic.com
        'connect-src': "'self' https://api.mixpanel.com http://custom-api.local", // Allow data (ajax/websocket) from api.mixpanel.com and custom-api.local
        'img-src': "'self' http://placehold.it http://store-images.microsoft.com",
        'style-src': "'self' 'unsafe-inline' http://fonts.googleapis.com", // Allow inline styles and loaded CSS from http://fonts.googleapis.com
        'media-src': "'self'"
    };

    ENV.FIXTURES = {
        enabled: true
    };

    return ENV;
};<|endoftext|>


<commit_before>/*
cmd - what the user types, sans prefix
description - meaningful description, for use with help
action - what the command does
*/

var commands = {};
var client;
var config;
var connection;

exports.get = function(cmd) {
	return commands[cmd];
};

exports.setUp = function(cl, co, con) {
	client = cl;
	config = co;
	connection = con;
};

function Command(cmd, descr, action, hidden = false) {
	this.cmd = cmd;
	this.description = descr;
	this.action = action;
	this.hidden = hidden;
	commands[cmd]=this;
}

function getParams(content) {
	var params = content.split(" ");
	params.shift();
	return params;
}

new Command("ping",
	"It's like ping-pong, but with words.",
	function(message) {
		client.reply(message, "pong");
	}
);

new Command("blame",
	"Assigns blame appropriately",
	function(message) {
		var params = getParams(message.content);
		if(params.length > 0) {
			client.sendMessage(message.channel, "I blame " + params.join(" "));
		}
		else {
			client.sendMessage(message.channel, "I blame Yury");
		}
		client.deleteMessage(message);
	}
);

new Command("ge",
	"Search the RuneScape Grand Exchange for an item",
	function(message) {
		var p = getParams(message.content);
		var item = p.join("+");
		client.sendMessage(message.channel, "http://services.runescape.com/m=itemdb_rs/results?query=" + item);
	}
);

new Command("hs",
	"Search the RuneScape High Scores for a player",
	function(message) {
		var p = getParams(message.content);
		var player = p.join("_");
		client.sendMessage(message.channel, "http://services.runescape.com/m=hiscore/compare?user1=" + player);
	}
);

function listSoundboard(cb) {
	connection.query("SELECT alias, description FROM soundboard", function(err, rows) {
		if(err) {
			return console.error(err);
		}
		var sbList = "```";
		for(var i = 0; i < rows.length; i++) {
			sbList = sbList.concat(rows[i].alias + ": " + rows[i].description + "\n");
		}
		sbList = sbList.concat("```");
		cb(sbList);
	});
}

function playSoundboard(voiceConnection, filePath, iterations = 1) {
	voiceConnection.playFile(filePath, {volume: config.vol}, function(err, intent) {
		if(err){
			console.error(err);
		}
		intent.on("error", function(err) {
			console.error(err);
		});
		intent.once("end", function() {
			if(iterations <= 1) {
				client.leaveVoiceChannel(voiceConnection);
			}
			else {
				playSoundboard(voiceConnection, filePath, iterations-1);
			}
		});
	});
}

new Command("sb",
	"Play something from the soundboard",
	function(message) {
		var voiceChannel = message.author.voiceChannel;
		var params = getParams(message.content);
		if(params.length == 0 || (params.length > 0 && params[0] == "list")) {
			listSoundboard(function(sbList){
				client.sendMessage(message.channel, sbList);
			});
		}
		else if(voiceChannel != null) {
			connection.query("SELECT path FROM soundboard WHERE alias = ?", [params[0]], function(err, rows) {
				if(err) {
					console.error(err);
				}
				if(rows.length == 0) {
					client.sendMessage(message.channel, "I have no idea what that is, " + message.author);
					listSoundboard(function(sbList) {
						client.sendMessage(message.channel, sbList);
					});
				}
				else if (rows.length > 1) {
					console.warn("Soundboard alias " + params[0] + "returned multiple paths");
				}
				else {
					var filePath = rows[0].path;
					client.joinVoiceChannel(voiceChannel, function(err, voiceConnection) {
						if(err) {
							console.error(err);
						}
						params.length == 2 ? playSoundboard(voiceConnection, filePath) : playSoundboard(voiceConnection, filePath, parseInt(params[1]));
					});
				}
			});
		}
		else {
			client.sendMessage(message.channel, "*starts humming*");
		}
	}
);

// new Command("bh",
// 	"Hilarity ensues",
// 	function(message) {
// 		var voiceChannel = message.author.voiceChannel;
// 		if(voiceChannel != null) {
// 			client.joinVoiceChannel(voiceChannel, function(error, voiceConnection){
// 				if(error) {
// 					return console.error(error);
// 				}
// 				voiceConnection.playFile(config.bennyHill, {volume: config.bhvol}, function(error, intent) {
// 					if(error) {
// 						return console.error(error);
// 					}
// 					intent.on("error", function(error) {
// 						return console.error(error);
// 					});
// 					intent.once("end", function() {
// 						voiceConnection.playFile(/*config.bennyHill*/"./bennyHill.mp3", {volume: config.vol}, function(error, intent) {
// 							if(error) {
// 								return console.error(error);
// 							}
// 							intent.on("error", function(error) {
// 								return console.error(error);
// 							});
// 							intent.once("end", function() {
// 								client.leaveVoiceChannel(voiceConnection);
// 							});
// 						});
// 					});
// 				});
// 			});
// 		}
// 		else {
// 			client.sendMessage(message.channel, "*starts humming*");
// 		}
// 		client.deleteMessage(message);
// 	},
// 	true
// );

new Command("config",
	"Admin can configure bot settings.",
	function(message) {
		if(message.channel.permissionsOf(message.author).hasPermission("administrator")) {
			var params = getParams(message.content);
			config[params[0]] = params[1];
			message.reply("Updated config");
		}
		else {
			message.reply("*sticks fingers in ears* lalala I'm not listening!");
		}
	},
	true
);

new Command("botissues",
	"Got an idea or found a bug? Here's the link to submit them.",
	function(message) {
		client.sendMessage(message.channel, "https://github.com/Deixel/DeixBot/issues");
	}
);

new Command("gtadown",
	"Rockstar sucks.",
	function(message) {
		client.sendMessage(message.channel, "http://downdetector.co.uk/problems/gta5");
	}
);

new Command("report",
	"Report them hax0rz",
	function(message) {
		var params = getParams(message.content);
		if(params.length > 1) {
			var hax0r = params.shift();
			var reason =  params.join(" ");
			var report = message.author + " has reported " + hax0r + ". Reason: " + reason;
			client.sendMessage(message.channel, report);
			client.deleteMessage(message);
		}
		else {
			client.sendMessage(message.channel, message.author + " doesn't know how reporting works!");
			client.deleteMessage(message);
		}
	}
);

new Command("say",
	"Words and words and words",
	function(message) {
		var params = getParams(message.content);
		client.sendMessage(message.channel, params.join(" "));
		client.deleteMessage(message);
	},
	true
);

new Command("help",
	"Lists all the commands.",
	function(message) {
		var helpStr = "```";
		for(var cmd in commands) {
			if(!commands[cmd].hidden) {
				helpStr = helpStr.concat(config.cmdprefix, commands[cmd].cmd, ": ", commands[cmd].description, "\n");
			}
		}
		helpStr = helpStr.concat("```");
		client.sendMessage(message.channel, helpStr);
	}
);
<commit_msg>Added some playing debug<commit_after>/*
cmd - what the user types, sans prefix
description - meaningful description, for use with help
action - what the command does
*/

var commands = {};
var client;
var config;
var connection;

exports.get = function(cmd) {
	return commands[cmd];
};

exports.setUp = function(cl, co, con) {
	client = cl;
	config = co;
	connection = con;
};

function Command(cmd, descr, action, hidden = false) {
	this.cmd = cmd;
	this.description = descr;
	this.action = action;
	this.hidden = hidden;
	commands[cmd]=this;
}

function getParams(content) {
	var params = content.split(" ");
	params.shift();
	return params;
}

new Command("ping",
	"It's like ping-pong, but with words.",
	function(message) {
		client.reply(message, "pong");
	}
);

new Command("blame",
	"Assigns blame appropriately",
	function(message) {
		var params = getParams(message.content);
		if(params.length > 0) {
			client.sendMessage(message.channel, "I blame " + params.join(" "));
		}
		else {
			client.sendMessage(message.channel, "I blame Yury");
		}
		client.deleteMessage(message);
	}
);

new Command("ge",
	"Search the RuneScape Grand Exchange for an item",
	function(message) {
		var p = getParams(message.content);
		var item = p.join("+");
		client.sendMessage(message.channel, "http://services.runescape.com/m=itemdb_rs/results?query=" + item);
	}
);

new Command("hs",
	"Search the RuneScape High Scores for a player",
	function(message) {
		var p = getParams(message.content);
		var player = p.join("_");
		client.sendMessage(message.channel, "http://services.runescape.com/m=hiscore/compare?user1=" + player);
	}
);

function listSoundboard(cb) {
	connection.query("SELECT alias, description FROM soundboard", function(err, rows) {
		if(err) {
			return console.error(err);
		}
		var sbList = "```";
		for(var i = 0; i < rows.length; i++) {
			sbList = sbList.concat(rows[i].alias + ": " + rows[i].description + "\n");
		}
		sbList = sbList.concat("```");
		cb(sbList);
	});
}

function playSoundboard(voiceConnection, filePath, iterations = 1) {
	console.log("Playing " + filePath + " for " + iterations + " runs.");
	voiceConnection.playFile(filePath, {volume: config.vol}, function(err, intent) {
		if(err){
			console.error(err);
		}
		intent.on("error", function(err) {
			console.error(err);
		});
		intent.once("end", function() {
			if(iterations <= 1) {
				client.leaveVoiceChannel(voiceConnection);
			}
			else {
				playSoundboard(voiceConnection, filePath, iterations-1);
			}
		});
	});
}

new Command("sb",
	"Play something from the soundboard",
	function(message) {
		var voiceChannel = message.author.voiceChannel;
		var params = getParams(message.content);
		if(params.length == 0 || (params.length > 0 && params[0] == "list")) {
			listSoundboard(function(sbList){
				client.sendMessage(message.channel, sbList);
			});
		}
		else if(voiceChannel != null) {
			connection.query("SELECT path FROM soundboard WHERE alias = ?", [params[0]], function(err, rows) {
				if(err) {
					console.error(err);
				}
				if(rows.length == 0) {
					client.sendMessage(message.channel, "I have no idea what that is, " + message.author);
					listSoundboard(function(sbList) {
						client.sendMessage(message.channel, sbList);
					});
				}
				else if (rows.length > 1) {
					console.warn("Soundboard alias " + params[0] + "returned multiple paths");
				}
				else {
					var filePath = rows[0].path;
					client.joinVoiceChannel(voiceChannel, function(err, voiceConnection) {
						if(err) {
							console.error(err);
						}
						params.length == 2 ? playSoundboard(voiceConnection, filePath) : playSoundboard(voiceConnection, filePath, parseInt(params[1]));
					});
				}
			});
		}
		else {
			client.sendMessage(message.channel, "*starts humming*");
		}
	}
);

// new Command("bh",
// 	"Hilarity ensues",
// 	function(message) {
// 		var voiceChannel = message.author.voiceChannel;
// 		if(voiceChannel != null) {
// 			client.joinVoiceChannel(voiceChannel, function(error, voiceConnection){
// 				if(error) {
// 					return console.error(error);
// 				}
// 				voiceConnection.playFile(config.bennyHill, {volume: config.bhvol}, function(error, intent) {
// 					if(error) {
// 						return console.error(error);
// 					}
// 					intent.on("error", function(error) {
// 						return console.error(error);
// 					});
// 					intent.once("end", function() {
// 						voiceConnection.playFile(/*config.bennyHill*/"./bennyHill.mp3", {volume: config.vol}, function(error, intent) {
// 							if(error) {
// 								return console.error(error);
// 							}
// 							intent.on("error", function(error) {
// 								return console.error(error);
// 							});
// 							intent.once("end", function() {
// 								client.leaveVoiceChannel(voiceConnection);
// 							});
// 						});
// 					});
// 				});
// 			});
// 		}
// 		else {
// 			client.sendMessage(message.channel, "*starts humming*");
// 		}
// 		client.deleteMessage(message);
// 	},
// 	true
// );

new Command("config",
	"Admin can configure bot settings.",
	function(message) {
		if(message.channel.permissionsOf(message.author).hasPermission("administrator")) {
			var params = getParams(message.content);
			config[params[0]] = params[1];
			message.reply("Updated config");
		}
		else {
			message.reply("*sticks fingers in ears* lalala I'm not listening!");
		}
	},
	true
);

new Command("botissues",
	"Got an idea or found a bug? Here's the link to submit them.",
	function(message) {
		client.sendMessage(message.channel, "https://github.com/Deixel/DeixBot/issues");
	}
);

new Command("gtadown",
	"Rockstar sucks.",
	function(message) {
		client.sendMessage(message.channel, "http://downdetector.co.uk/problems/gta5");
	}
);

new Command("report",
	"Report them hax0rz",
	function(message) {
		var params = getParams(message.content);
		if(params.length > 1) {
			var hax0r = params.shift();
			var reason =  params.join(" ");
			var report = message.author + " has reported " + hax0r + ". Reason: " + reason;
			client.sendMessage(message.channel, report);
			client.deleteMessage(message);
		}
		else {
			client.sendMessage(message.channel, message.author + " doesn't know how reporting works!");
			client.deleteMessage(message);
		}
	}
);

new Command("say",
	"Words and words and words",
	function(message) {
		var params = getParams(message.content);
		client.sendMessage(message.channel, params.join(" "));
		client.deleteMessage(message);
	},
	true
);

new Command("help",
	"Lists all the commands.",
	function(message) {
		var helpStr = "```";
		for(var cmd in commands) {
			if(!commands[cmd].hidden) {
				helpStr = helpStr.concat(config.cmdprefix, commands[cmd].cmd, ": ", commands[cmd].description, "\n");
			}
		}
		helpStr = helpStr.concat("```");
		client.sendMessage(message.channel, helpStr);
	}
);
<|endoftext|>


<commit_before>import React from 'react';
import PropTypes from 'prop-types';
import {StyleSheet, Text, View} from 'react-native';
import {colors} from '../../constants/colors';

export class SectionHeader extends React.Component {
  static propTypes = {
    title: PropTypes.string.isRequired
  };

  render() {
    return (
      <View style={styles.container}>
        <Text style={styles.text}>{this.props.title}</Text>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    backgroundColor: colors.headerColor
  },

  text: {
    fontFamily: 'AvenirNext-Medium',
    fontSize: 16,
    color: 'white',
    paddingLeft: 10
  }
});
<commit_msg>fix(Section Header): Use default font on android as AvenirNext-Medium is only supported by iOS"<commit_after>import React from 'react';
import PropTypes from 'prop-types';
import {StyleSheet, Text, View, Platform} from 'react-native';
import {colors} from '../../constants/colors';

export class SectionHeader extends React.Component {
  static propTypes = {
    title: PropTypes.string.isRequired
  };

  render() {
    return (
      <View style={styles.container}>
        <Text style={styles.text}>{this.props.title}</Text>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    backgroundColor: colors.headerColor
  },

  text: {
    fontFamily: Platform.OS === 'ios' ? 'AvenirNext-Medium' : 'normal',
    fontSize: 16,
    color: 'white',
    paddingLeft: 10
  }
});
<|endoftext|>


<commit_before>import * as firebase from 'firebase/app';

import authUtils from '../AuthUtils';
import { getUserUidArrFromUserEmailArr } from './temp-auth-utils.js'
import { getTimestampFromDateString } from './time.js'
import * as DB from '../../constants/database.js';

/**
 * Return a string containing the cleaned text input.
 *
 * @param {string} rawInput String containing raw form input.
 * @return {string} Cleaned string.
 */
export function getCleanedTextInput(rawInput, defaultValue) {
  return rawInput === '' ? defaultValue : rawInput;
}

/**
 * Return an array of collaborator uids given the emails provided in the
 * add trip form.
 *
 * TODO(#72 & #67): Remove 'remove empty fields' once there is better way to
 * remove collaborators (#72) and there is email validation (#67).
 *
 * @param {!Array{string}} collaboratorEmailsArr Array of emails corresponding
 *     to the  collaborators of the trip (not including the trip creator email).
 * @return {!Array{string}} Array of all collaborator uids (including trip
 *     creator uid).
 */
export function getCollaboratorUidArray(collaboratorEmailArr) {
  collaboratorEmailArr = [authUtils.getCurUserEmail()]
                          .concat(collaboratorEmailArr);

  // Removes empty fields (temporary until fix #67 & #72).
  while (collaboratorEmailArr.includes('')) {
    const emptyStrIdx = collaboratorEmailArr.indexOf('');
    collaboratorEmailArr.splice(emptyStrIdx, 1);
  }
  return getUserUidArrFromUserEmailArr(collaboratorEmailArr);
}

/**
 * Returns a formatted and cleaned trip object that will be used as the data
 * for the created Trip document.
 *
 * We know that rawTripObj will contain all of the necessary fields because each
 * key-value pair is explicitly included. This means, only the value
 * corresponding to each key needs to be checked.
 * For text element inputs, React has built in protections against injection/XSS
 * attacks. Thus, no sanitization is needed for text inputs besides providing a
 * default value in a Trip field where applicable.
 *
 * @param {!Object} rawTripObj A JS Object containing the raw form data from the
 *     add trip form.
 * @return {!Object} Formatted/cleaned version of `rawTripObj` holding the data
 *     for the new Trip document that is to be created.
 */
export function formatTripData(rawTripObj) {
  const defaultName = "Untitled Trip";
  const defaultDestination = "No Destination"

  const tripObj = {};
  tripObj[DB.TRIPS_UPDATE_TIMESTAMP] = firebase.firestore.Timestamp.now();
  tripObj[DB.TRIPS_TITLE] =
      getCleanedTextInput(rawTripObj[DB.TRIPS_TITLE], defaultName);
  tripObj[DB.TRIPS_DESCRIPTION] = rawTripObj[DB.TRIPS_DESCRIPTION];
  tripObj[DB.TRIPS_DESTINATION] =
      getCleanedTextInput(rawTripObj[DB.TRIPS_DESTINATION], defaultDestination);
  tripObj[DB.TRIPS_START_DATE] =
      getTimestampFromDateString(rawTripObj[DB.TRIPS_START_DATE]);
  tripObj[DB.TRIPS_END_DATE] =
      getTimestampFromDateString(rawTripObj[DB.TRIPS_END_DATE]);
  tripObj[DB.TRIPS_COLLABORATORS] =
      getCollaboratorUidArray(rawTripObj[DB.TRIPS_COLLABORATORS]);

  return tripObj;
}
<commit_msg>Update JSDoc in filter-input.<commit_after>import * as firebase from 'firebase/app';

import authUtils from '../AuthUtils';
import { getUserUidArrFromUserEmailArr } from './temp-auth-utils.js'
import { getTimestampFromDateString } from './time.js'
import * as DB from '../../constants/database.js';

/**
 * An object containing the raw input data from a SaveTripModal form.
 * @typedef {Object} rawTripData
 * @property {string} title The trips's title.
 * @property {string} description A description of the trip.
 * @property {string} destination The general destination of the trip.
 * @property {string} start_date Start date string in the form 'YYYY-MM-DD'.
 * @property {string} end_date End date string in the form 'YYYY-MM-DD'.
 * @property {!string[]} collaborators An array of collaborator emails.
 */

/**
 * A trip object containing the data stored in a trip document in Firestore.
 * @typedef {Object} tripData
 * @property {string} title The trips's title.
 * @property {string} description A description of the trip.
 * @property {string} destination The general destination of the trip.
 * @property {firebase.firestore.Timestamp} start_date Start date Firestore
 *     timestamp object.
 * @property {firebase.firestore.Timestamp} end_date End date Firestore
 *     timestamp object
 * @property {!string[]} collaborators An array of collaborator uids.
 */

/**
 * Return a string containing the cleaned text input.
 *
 * @param {string} rawInput String containing raw form input.
 * @param {string} defaultValue The default value of the text input in case the
 *     rawInput is empty.
 * @return {string} Cleaned string.
 */
export function getCleanedTextInput(rawInput, defaultValue) {
  return rawInput === '' ? defaultValue : rawInput;
}

/**
 * Return an array of collaborator uids given the emails provided in the
 * add trip form.
 *
 * TODO(#72 & #67): Remove 'remove empty fields' once there is better way to
 * remove collaborators (#72) and there is email validation (#67).
 *
 * @param {!string[]} collaboratorEmailsArr Array of emails corresponding
 *     to the  collaborators of the trip (not including the trip creator email).
 * @return {!string[]} Array of all collaborator uids (including trip
 *     creator uid).
 */
export function getCollaboratorUidArray(collaboratorEmailArr) {
  collaboratorEmailArr = [authUtils.getCurUserEmail()]
                          .concat(collaboratorEmailArr);

  // Removes empty fields (temporary until fix #67 & #72).
  while (collaboratorEmailArr.includes('')) {
    const emptyStrIdx = collaboratorEmailArr.indexOf('');
    collaboratorEmailArr.splice(emptyStrIdx, 1);
  }
  return getUserUidArrFromUserEmailArr(collaboratorEmailArr);
}

/**
 * Returns a formatted and cleaned trip object that will be used as the data
 * for the created trip document.
 *
 * We know that `rawTripData` will contain all of the necessary fields for a
 * trip document (except timestamp) because each key-value pair is explicitly
 * included. This means, only the value corresponding to each key needs to be
 * checked.
 *
 * For text element inputs, React has built in protections against injection/XSS
 * attacks. Thus, no sanitization is needed for text inputs besides providing a
 * default value in a trip field where applicable.
 *
 * @param {!rawTripData} rawTripData A JS Object containing the raw form data
 *     from the add trip form.
 * @return {!tripData} Formatted/cleaned version of `rawTripData` holding the data
 *     for the new Trip document that is to be created.
 */
export function formatTripData(rawTripData) {
  const defaultName = "Untitled Trip";
  const defaultDestination = "No Destination"

  const tripData = {};
  tripData[DB.TRIPS_UPDATE_TIMESTAMP] = firebase.firestore.Timestamp.now();
  tripData[DB.TRIPS_TITLE] =
      getCleanedTextInput(rawTripData[DB.TRIPS_TITLE], defaultName);
  tripData[DB.TRIPS_DESCRIPTION] = rawTripData[DB.TRIPS_DESCRIPTION];
  tripData[DB.TRIPS_DESTINATION] =
     getCleanedTextInput(rawTripData[DB.TRIPS_DESTINATION], defaultDestination);
  tripData[DB.TRIPS_START_DATE] =
      getTimestampFromDateString(rawTripData[DB.TRIPS_START_DATE]);
  tripData[DB.TRIPS_END_DATE] =
      getTimestampFromDateString(rawTripData[DB.TRIPS_END_DATE]);
  tripData[DB.TRIPS_COLLABORATORS] =
      getCollaboratorUidArray(rawTripData[DB.TRIPS_COLLABORATORS]);

  return tripData;
}
<|endoftext|>


<commit_before>const HEXAGON_WIDTH = 70;
const HEXAGON_HEIGHT = 26;//26//80
const GRID_SIZE_X = 14;
const GRID_SIZE_Y = 36;

var game;
var minRow = 0;
var marker;
var hexagonGroup;
var hexagonArray = [];
var cursors;
var playerCol = 2;
var playerRow = 0;
var playerMove = true;
var columns = [Math.ceil(GRID_SIZE_X/2),Math.floor(GRID_SIZE_X/2)];
var moveIndex;
var sectorWidth = HEXAGON_WIDTH;
var sectorHeight = HEXAGON_HEIGHT/4*3;
var gradient = (HEXAGON_HEIGHT/4)/(HEXAGON_WIDTH/2);

window.onload = function() {
	game = new Phaser.Game(1200, 1200);
     game.state.add("PlayGame", playGame);
     game.state.start("PlayGame");
}

var playGame = function(game){}
playGame.prototype = {
     preload: function(){
     	game.load.image("grassTile", "assets/grass.png");
		game.load.image("fireTile", "assets/fire.png");
		game.load.image("wallTile", "assets/wall.png");
		game.load.image("resourceTile", "assets/resource.png");
		game.load.image("emptyTile", "assets/empty.png");
		game.load.image("marker", "assets/marker.png");
     },
     create: function(){
          hexagonGroup = game.add.group();
          game.stage.backgroundColor = "#ffffff";
          cursors = game.input.keyboard.createCursorKeys();
          for(var i = 0; i < GRID_SIZE_Y; i ++){
               addHexagonRow(i);
          }
          hexagonGroup.x = (game.width - HEXAGON_WIDTH * GRID_SIZE_X) / 2;
          hexagonGroup.y = 20;

          marker = game.add.sprite(0,0,"marker");
		marker.anchor.setTo(0.5);
		marker.visible=false;
		hexagonGroup.add(marker);
          moveIndex = game.input.addMoveCallback(checkHex, this);
     },
     update: function(){
          var destroyedRow = false;
          for(var i = minRow; i < GRID_SIZE_Y; i ++){
			for(var j = 0; j < GRID_SIZE_X; j ++){
				if((i % 2 == 0 || j < GRID_SIZE_X - 1) && hexagonArray[i][j].world.y < 0){
                         var destroyTween = game.add.tween(hexagonArray[i][j]).to({
                              alpha:0,
                              y: hexagonArray[i][j].y + HEXAGON_HEIGHT / 2
                         }, 200,  Phaser.Easing.Quadratic.Out, true);
                         destroyTween.onComplete.add(function(e){
                              e.destroy();
                         })
                         destroyedRow = true;
				}
			}
		}
        if(destroyedRow){
             minRow ++;
        }
     }
}

function checkHex(){
      var candidateX = Math.floor((game.input.worldX-hexagonGroup.x)/sectorWidth);
      var candidateY = Math.floor((game.input.worldY-hexagonGroup.y)/sectorHeight);
      var deltaX = (game.input.worldX-hexagonGroup.x)%sectorWidth;
      var deltaY = (game.input.worldY-hexagonGroup.y)%sectorHeight;
      if(candidateY%2==0){
           if(deltaY<((HEXAGON_HEIGHT/4)-deltaX*gradient)){
                candidateX--;
                candidateY--;
           }
           if(deltaY<((-HEXAGON_HEIGHT/4)+deltaX*gradient)){
                candidateY--;
           }
      }
      else{
           if(deltaX>=HEXAGON_WIDTH/2){
                if(deltaY<(HEXAGON_HEIGHT/2-deltaX*gradient)){
                     candidateY--;
                }
           }
           else{
                if(deltaY<deltaX*gradient){
                     candidateY--;
                }
                else{
                     candidateX--;
                }
           }
      }
      placeMarker(candidateX,candidateY);
 }

function placeMarker(posX,posY){
 	 for(var i = 0; i < GRID_SIZE_Y; i ++){
		for(var j = 0; j < GRID_SIZE_X; j ++){
			if(GRID_SIZE_Y%2==0 || i+1<GRID_SIZE_Y || j%2==0){
				if (hexagonArray[i][j] != null) {
					//hexagonArray[i][j].tint = 0xffffff;
				}
			}
		}
	}
	console.log(posX + " ___ " + GRID_SIZE_X);
	if(posX<0 || posY<0 || posY>=GRID_SIZE_Y || posX>=GRID_SIZE_X - posY%2){
		marker.visible=false;
	}
	else{
		//marker.visible=true;
		marker.x = HEXAGON_WIDTH*posX;
		marker.y = HEXAGON_HEIGHT/4*3*posY+HEXAGON_HEIGHT/2;

		//for the halfway point
		if(posY%2==0){
			marker.x += HEXAGON_WIDTH/2;
		}
		else{
			marker.x += HEXAGON_WIDTH;
		}

		if (hexagonArray[posY][posX] != null) {
			//hexagonArray[posY][posX].tint = 0x999900;
		}
	}
}

function addHexagonRow(i){
     var rand;
     hexagonArray[i] = [];
	for(var j = 0; j < GRID_SIZE_X - i % 2; j ++){
          var hexagonX = HEXAGON_WIDTH * j + (HEXAGON_WIDTH / 2) * (i % 2);
          var hexagonY = HEXAGON_HEIGHT * i / 4 * 3;
          rand = Math.floor(Math.random() * 50);
          if (rand == 0) {
               constructTile(hexagonX, hexagonY, i, j, "wallTile");
          } else if(rand >= 1 && rand <= 2)  {
               constructTile(hexagonX, hexagonY, i, j, "grassTile");
               //constructTile(hexagonX, hexagonY, i, j, "emptyTile");
          } else if(rand == 3)  {
               constructTile(hexagonX, hexagonY, i, j, "resourceTile");
          }else {
               constructTile(hexagonX, hexagonY, i, j, "grassTile");
          }
	}
}

function constructTile(hexagonX, hexagonY, i, j, tileType) {
     var tweenTile;
     var tile;
     tile = game.add.sprite(hexagonX, hexagonY, tileType);
     hexagonGroup.add(tile);
     hexagonArray[i][j] = tile;
     tile.inputEnabled = true;
     tile.events.onInputOver.add(over, this);
     tile.events.onInputOut.add(up, this);
     tile.events.onInputDown.add(onClick, this, hexagonX, hexagonY);
     tile.input.pixelPerfectOver = true;
     tile.input.pixelPerfectClick = true;
     tile.input.priorityID = i;
     if (tileType == "wallTile") {
          tweenTile = game.add.tween(tile);
          tweenTile.to({ alpha:1, y: hexagonY - HEXAGON_HEIGHT * 0.8}, 3000,  Phaser.Easing.Bounce.Out, true);
     }
     if (tileType == "resourceTile") {
		tweenTile = game.add.tween(tile);
		tweenTile.to({ alpha:1, y: hexagonY - HEXAGON_HEIGHT * 0.8}, 3000,  Phaser.Easing.Bounce.Out, true);
          //tweenTile.to({ alpha:1, y: hexagonY - HEXAGON_HEIGHT * 2}, 400,  Phaser.Easing.Quadratic.Out, true);
          // tweenTile.onComplete.add(function() {
          //      tweenTile.to({ alpha:1, y: hexagonY - HEXAGON_HEIGHT * 0.5}, 2000,  Phaser.Easing.Quadratic.In, true);
          //      tweenTile.start;
          // });
     }
}

function onClick(tile, hexagonX, hexagonY) {
	var tweenTile;
	tweenTile = game.add.tween(tile);
	tweenTile.to({ alpha:1, y: /*hexagonY*/ - HEXAGON_HEIGHT * 5}, 400,  Phaser.Easing.Quadratic.Out, true);
}
function over(tile) {
     tile.tint = 0x999900;
}
function up(tile) {
     tile.tint = 0xffffff;
}
function over1() {
     //tile.tint = 0x999900;
}

/*var hexagonText = game.add.text(0 + HEXAGON_WIDTH / 3 + 5, 0 + 15, i + "," + j);
hexagonText.font = "arial";
hexagonText.align = "center";
hexagonText.fontSize = 10;
grassTile.addChild(hexagonText);  */ <commit_msg>Calling a callback with parameters using a nested lambda.<commit_after>const HEXAGON_WIDTH = 70;
const HEXAGON_HEIGHT = 26;//26//80
const GRID_SIZE_X = 140;
const GRID_SIZE_Y = 360;

var game;
var minRow = 0;
var marker;
var hexagonGroup;
var hexagonArray = [];
var cursors;
var playerCol = 2;
var playerRow = 0;
var playerMove = true;
var columns = [Math.ceil(GRID_SIZE_X/2),Math.floor(GRID_SIZE_X/2)];
var moveIndex;
var sectorWidth = HEXAGON_WIDTH;
var sectorHeight = HEXAGON_HEIGHT/4*3;
var gradient = (HEXAGON_HEIGHT/4)/(HEXAGON_WIDTH/2);

window.onload = function() {
	game = new Phaser.Game(1200, 1200);
     game.state.add("PlayGame", playGame);
     game.state.start("PlayGame");
};

var playGame = function(game){}
playGame.prototype = {
     preload: function(){
     	game.load.image("grassTile", "assets/grass.png");
		game.load.image("fireTile", "assets/fire.png");
		game.load.image("wallTile", "assets/wall.png");
		game.load.image("resourceTile", "assets/resource.png");
		game.load.image("emptyTile", "assets/empty.png");
		game.load.image("marker", "assets/marker.png");
     },
     create: function(){
          hexagonGroup = game.add.group();
          game.stage.backgroundColor = "#ffffff";
          cursors = game.input.keyboard.createCursorKeys();
          for(var i = 0; i < GRID_SIZE_Y; i ++){
               addHexagonRow(i);
          }
          hexagonGroup.x = (game.width - HEXAGON_WIDTH * GRID_SIZE_X) / 2;
          hexagonGroup.y = 20;

          marker = game.add.sprite(0,0,"marker");
		marker.anchor.setTo(0.5);
		marker.visible=false;
		hexagonGroup.add(marker);
          moveIndex = game.input.addMoveCallback(checkHex, this);
     },
     update: function(){
          var destroyedRow = false;
          for(var i = minRow; i < GRID_SIZE_Y; i ++){
			for(var j = 0; j < GRID_SIZE_X; j ++){
				if((i % 2 == 0 || j < GRID_SIZE_X - 1) && hexagonArray[i][j].world.y < 0){
                         var destroyTween = game.add.tween(hexagonArray[i][j]).to({
                              alpha:0,
                              y: hexagonArray[i][j].y + HEXAGON_HEIGHT / 2
                         }, 200,  Phaser.Easing.Quadratic.Out, true);
                         destroyTween.onComplete.add(function(e){
                              e.destroy();
                         })
                         destroyedRow = true;
				}
			}
		}
        if(destroyedRow){
             minRow ++;
        }
     }
}

function checkHex(){
      var candidateX = Math.floor((game.input.worldX-hexagonGroup.x)/sectorWidth);
      var candidateY = Math.floor((game.input.worldY-hexagonGroup.y)/sectorHeight);
      var deltaX = (game.input.worldX-hexagonGroup.x)%sectorWidth;
      var deltaY = (game.input.worldY-hexagonGroup.y)%sectorHeight;
      if(candidateY%2==0){
           if(deltaY<((HEXAGON_HEIGHT/4)-deltaX*gradient)){
                candidateX--;
                candidateY--;
           }
           if(deltaY<((-HEXAGON_HEIGHT/4)+deltaX*gradient)){
                candidateY--;
           }
      }
      else{
           if(deltaX>=HEXAGON_WIDTH/2){
                if(deltaY<(HEXAGON_HEIGHT/2-deltaX*gradient)){
                     candidateY--;
                }
           }
           else{
                if(deltaY<deltaX*gradient){
                     candidateY--;
                }
                else{
                     candidateX--;
                }
           }
      }
      placeMarker(candidateX,candidateY);
 }

function placeMarker(posX,posY){
 	 for(var i = 0; i < GRID_SIZE_Y; i ++){
		for(var j = 0; j < GRID_SIZE_X; j ++){
			if(GRID_SIZE_Y%2==0 || i+1<GRID_SIZE_Y || j%2==0){
				if (hexagonArray[i][j] != null) {
					//hexagonArray[i][j].tint = 0xffffff;
				}
			}
		}
	}
	//console.log(posX + " ___ " + GRID_SIZE_X);
	if(posX<0 || posY<0 || posY>=GRID_SIZE_Y || posX>=GRID_SIZE_X - posY%2){
		marker.visible=false;
	}
	else{
		//marker.visible=true;
		marker.x = HEXAGON_WIDTH*posX;
		marker.y = HEXAGON_HEIGHT/4*3*posY+HEXAGON_HEIGHT/2;

		//for the halfway point
		if(posY%2==0){
			marker.x += HEXAGON_WIDTH/2;
		}
		else{
			marker.x += HEXAGON_WIDTH;
		}

		if (hexagonArray[posY][posX] != null) {
			//hexagonArray[posY][posX].tint = 0x999900;
		}
	}
}

function addHexagonRow(i){
     var rand;
     hexagonArray[i] = [];
	for(var j = 0; j < GRID_SIZE_X - i % 2; j ++){
          var hexagonX = HEXAGON_WIDTH * j + (HEXAGON_WIDTH / 2) * (i % 2);
          var hexagonY = HEXAGON_HEIGHT * i / 4 * 3;
          rand = Math.floor(Math.random() * 50);
          if (rand == 0) {
               constructTile(hexagonX, hexagonY, i, j, "wallTile");
          } else if(rand >= 1 && rand <= 2)  {
               constructTile(hexagonX, hexagonY, i, j, "grassTile");
               //constructTile(hexagonX, hexagonY, i, j, "emptyTile");
          } else if(rand == 3)  {
               constructTile(hexagonX, hexagonY, i, j, "resourceTile");
          }else {
               constructTile(hexagonX, hexagonY, i, j, "grassTile");
          }
	}
}

function constructTile(hexagonX, hexagonY, i, j, tileType) {
     var tweenTile;
     var tile;

     tile = game.add.sprite(hexagonX, hexagonY, tileType);
     hexagonGroup.add(tile);
     hexagonArray[i][j] = tile;

     tile.inputEnabled = true;
     tile.events.onInputOver.add(over, this);
     tile.events.onInputOut.add(up, this);

     tile.events.onInputDown.add(function () {
          onClick(tile, i, j);
     }, this);

     tile.input.pixelPerfectOver = true;
     tile.input.pixelPerfectClick = true;
     tile.input.priorityID = i;
     tile.autoCull = true;
     tile.z = i;

     if (tileType == "wallTile") {
          tweenTile = game.add.tween(tile);
          tweenTile.to({ alpha:1, y: hexagonY - HEXAGON_HEIGHT * 0.8}, 3000,  Phaser.Easing.Bounce.Out, true);
     }
     if (tileType == "resourceTile") {
		tweenTile = game.add.tween(tile);
		tweenTile.to({ alpha:1, y: hexagonY - HEXAGON_HEIGHT * 0.8}, 3000,  Phaser.Easing.Bounce.Out, true);
          //tweenTile.to({ alpha:1, y: hexagonY - HEXAGON_HEIGHT * 2}, 400,  Phaser.Easing.Quadratic.Out, true);
          // tweenTile.onComplete.add(function() {
          //      tweenTile.to({ alpha:1, y: hexagonY - HEXAGON_HEIGHT * 0.5}, 2000,  Phaser.Easing.Quadratic.In, true);
          //      tweenTile.start;
          // });
     }
}

function onClick(tile, i, j) {
	var destroyTween = game.add.tween(tile).to({
          alpha:0,
          y: tile.y - HEXAGON_HEIGHT * 3
     }, 400,  Phaser.Easing.Quadratic.Out, true);
     destroyTween.onComplete.add(function(e){
          e.destroy();
     })

     console.log("i = " + i + "; j = " + j);
     constructTile(tile.x, tile.y, i, j, "grassTile");
}
function over(tile) {
     tile.tint = 0x999900;
}
function up(tile) {
     tile.tint = 0xffffff;
}
function over1() {
     //tile.tint = 0x999900;
}

/*var hexagonText = game.add.text(0 + HEXAGON_WIDTH / 3 + 5, 0 + 15, i + "," + j);
hexagonText.font = "arial";
hexagonText.align = "center";
hexagonText.fontSize = 10;
grassTile.addChild(hexagonText);  */ <|endoftext|>


<commit_before>var builder = require('./lib/ipa-build.js');

module.exports = function (xcodeproj_path, ipa_path, build_path ,project_name, app_path) {
	builder.xcodebuild(xcodeproj_path, project_name, build_path);
	builder.xcrun(app_path, ipa_path);
}

<commit_msg>Update index.js<commit_after>var builder = require('./lib/ipa-build.js');

module.exports = function (xcodeproj_path, ipa_path, build_path ,project_name, app_path) {
	builder.xcodebuild(xcodeproj_path, project_name, build_path);
	builder.xcrun(app_path, ipa_path);
}
<|endoftext|>


<commit_before>/**
 * Created by zizhouzhai on 3/1/16.
 */

exports.getEmployeeDashboard = function(req, res) {
    if (!req.user) {

        return res.redirect('/login');
    }
    res.render('dashboard_employee',{user : req.user});
};

exports.getBusinessOwnerDashboard = function(req, res) {
    if (!req.user) {
        return res.redirect('/login');
    }
    res.render('dashboard_admin', {user : req.user});
};
<commit_msg>Update dashboard.js<commit_after>/**
 * Created by zizhouzhai on 3/1/16.
 */

exports.getEmployeeDashboard = function(req, res) {
    if (!req.user) {

        return res.redirect('/login_employee');
    }
    res.render('dashboard_employee',{user : req.user});
};

exports.getBusinessOwnerDashboard = function(req, res) {
    if (!req.user) {
        return res.redirect('/login');
    }
    res.render('dashboard_admin', {user : req.user});
};
<|endoftext|>


<commit_before>// Same as native, with that difference that uses Object.is for equality
// check. Makes it reliable for NaN or -0, +0 values

'use strict';

var indexOf = Array.prototype.indexOf
  , isNaN   = require('../../Number/is-nan')
  , is      = require('../../Object/is')
  , value   = require('../../Object/valid-value');

module.exports = function (searchElement, fromIndex) {
	var i, index, self;
	if (!isNaN(searchElement) && (searchElement !== 0)) {
		return indexOf.apply(this, arguments);
	}

	self = Object(value(this));
	for (i = (fromIndex >>> 0); i < (self.length >>> 0); ++i) {
		if (self.hasOwnProperty(i) && is(searchElement, self[i])) {
			return i;
		}
	}
	return -1;
};
<commit_msg>Remove documentation from code<commit_after>'use strict';

var indexOf = Array.prototype.indexOf
  , isNaN   = require('../../Number/is-nan')
  , is      = require('../../Object/is')
  , value   = require('../../Object/valid-value');

module.exports = function (searchElement, fromIndex) {
	var i, index, self;
	if (!isNaN(searchElement) && (searchElement !== 0)) {
		return indexOf.apply(this, arguments);
	}

	self = Object(value(this));
	for (i = (fromIndex >>> 0); i < (self.length >>> 0); ++i) {
		if (self.hasOwnProperty(i) && is(searchElement, self[i])) {
			return i;
		}
	}
	return -1;
};
<|endoftext|>


<commit_before>frappe.ui.FilterGroup = class {
	constructor(opts) {
		$.extend(this, opts);
		this.wrapper = this.parent;
		this.filters = [];
		this.make();
		window.fltr = this;
	}

	make() {
		this.wrapper.append(this.get_container_template());
		this.set_events();
	}

	toggle_clear_filter() {
		let clear_filter_button = this.wrapper.find('.clear-filters');

		if (this.filters.length == 0) {
			clear_filter_button.hide();
		} else {
			clear_filter_button.show();
		}
	}
	set_events() {
		this.wrapper.find('.add-filter').on('click', () => {
			this.add_filter(this.doctype, 'name')
				.then(this.toggle_clear_filter());

		});
		this.wrapper.find('.clear-filters').on('click', () => {
			this.clear_filters();
		});
	}

	add_filters(filters) {
		let promises = [];

		for (const filter of filters) {
			promises.push(() => this.add_filter(...filter));
		}

		promises.push(() => this.toggle_clear_filter())

		return frappe.run_serially(promises);
	}

	add_filter(doctype, fieldname, condition, value, hidden) {
		if (!fieldname) return Promise.resolve();
		// adds a new filter, returns true if filter has been added

		// {}: Add in page filter by fieldname if exists ('=' => 'like')

		if(!this.validate_args(doctype, fieldname)) return false;
		const is_new_filter = arguments.length < 2;
		if (is_new_filter && this.wrapper.find(".new-filter:visible").length) {
			// only allow 1 new filter at a time!
			return Promise.resolve();
		} else {
			let args = [doctype, fieldname, condition, value, hidden];
			const promise = this.push_new_filter(args, is_new_filter);
			return (promise && promise.then) ? promise : Promise.resolve();
		}
	}

	validate_args(doctype, fieldname) {
		if(doctype && fieldname
			&& !frappe.meta.has_field(doctype, fieldname)
			&& !frappe.model.std_fields_list.includes(fieldname)) {

			frappe.throw(__(`Invalid filter: "${[fieldname.bold()]}"`));
			return false;
		}
		return true;
	}

	push_new_filter(args, is_new_filter=false) {
		// args: [doctype, fieldname, condition, value]
		if(this.filter_exists(args)) return;

		// {}: Clear page filter fieldname field

		let filter = this._push_new_filter(...args);

		if (filter && filter.value) {
			filter.setup_state(is_new_filter);
			return filter._filter_value_set; // internal promise
		}
	}

	_push_new_filter(doctype, fieldname, condition, value, hidden = false) {
		let args = {
			parent: this.wrapper,
			parent_doctype: this.doctype,
			doctype: doctype,
			fieldname: fieldname,
			condition: condition,
			value: value,
			hidden: hidden,
			on_change: (update) => {
				if(update) this.update_filters();
				this.on_change();
			},
			filter_items: (doctype, fieldname) => {
				return !this.filter_exists([doctype, fieldname]);
			}
		};
		let filter = new frappe.ui.Filter(args);
		this.filters.push(filter);
		return filter;
	}

	filter_exists(filter_value) {
		// filter_value of form: [doctype, fieldname, condition, value]
		let exists = false;
		this.filters.filter(f => f.field).map(f => {
			let f_value = f.get_value();
			if (filter_value.length === 2) {
				exists = filter_value[0] === f_value[0] && filter_value[1] === f_value[1];
				return;
			}

			let value = filter_value[3];
			let equal = frappe.utils.arrays_equal;

			if(equal(f_value.slice(0, 4), filter_value.slice(0, 4)) || (Array.isArray(value) && equal(value, f_value[3]))) {
				exists = true;
			}
		});
		return exists;
	}

	get_filters() {
		return this.filters.filter(f => f.field).map(f => {
			f.freeze();
			return f.get_value();
		});
		// {}: this.list.update_standard_filters(values);
	}

	update_filters() {
		this.filters = this.filters.filter(f => f.field); // remove hidden filters
		this.toggle_clear_filter();
	}

	clear_filters() {
		this.filters.map(f => f.remove(true));
		// {}: Clear page filters, .date-range-picker (called list run())
		this.filters = [];
	}

	get_filter(fieldname) {
		return this.filters.filter(f => {
			return (f.field && f.field.df.fieldname==fieldname);
		})[0];
	}

	get_container_template() {
		return $(`

				<button class="btn btn-default btn-xs filter-button text-muted add-filter">
					${__("Add Filter")}
				</button><button class="btn btn-default btn-xs filter-button text-muted clear-filters">
					${__("Clear Filters")}
				</button>

`);
	}
};
<commit_msg>style (codacy): added semi-colon<commit_after>frappe.ui.FilterGroup = class {
	constructor(opts) {
		$.extend(this, opts);
		this.wrapper = this.parent;
		this.filters = [];
		this.make();
		window.fltr = this;
	}

	make() {
		this.wrapper.append(this.get_container_template());
		this.set_events();
	}

	toggle_clear_filter() {
		let clear_filter_button = this.wrapper.find('.clear-filters');

		if (this.filters.length == 0) {
			clear_filter_button.hide();
		} else {
			clear_filter_button.show();
		}
	}
	set_events() {
		this.wrapper.find('.add-filter').on('click', () => {
			this.add_filter(this.doctype, 'name')
				.then(this.toggle_clear_filter());

		});
		this.wrapper.find('.clear-filters').on('click', () => {
			this.clear_filters();
		});
	}

	add_filters(filters) {
		let promises = [];

		for (const filter of filters) {
			promises.push(() => this.add_filter(...filter));
		}

		promises.push(() => this.toggle_clear_filter());

		return frappe.run_serially(promises);
	}

	add_filter(doctype, fieldname, condition, value, hidden) {
		if (!fieldname) return Promise.resolve();
		// adds a new filter, returns true if filter has been added

		// {}: Add in page filter by fieldname if exists ('=' => 'like')

		if(!this.validate_args(doctype, fieldname)) return false;
		const is_new_filter = arguments.length < 2;
		if (is_new_filter && this.wrapper.find(".new-filter:visible").length) {
			// only allow 1 new filter at a time!
			return Promise.resolve();
		} else {
			let args = [doctype, fieldname, condition, value, hidden];
			const promise = this.push_new_filter(args, is_new_filter);
			return (promise && promise.then) ? promise : Promise.resolve();
		}
	}

	validate_args(doctype, fieldname) {
		if(doctype && fieldname
			&& !frappe.meta.has_field(doctype, fieldname)
			&& !frappe.model.std_fields_list.includes(fieldname)) {

			frappe.throw(__(`Invalid filter: "${[fieldname.bold()]}"`));
			return false;
		}
		return true;
	}

	push_new_filter(args, is_new_filter=false) {
		// args: [doctype, fieldname, condition, value]
		if(this.filter_exists(args)) return;

		// {}: Clear page filter fieldname field

		let filter = this._push_new_filter(...args);

		if (filter && filter.value) {
			filter.setup_state(is_new_filter);
			return filter._filter_value_set; // internal promise
		}
	}

	_push_new_filter(doctype, fieldname, condition, value, hidden = false) {
		let args = {
			parent: this.wrapper,
			parent_doctype: this.doctype,
			doctype: doctype,
			fieldname: fieldname,
			condition: condition,
			value: value,
			hidden: hidden,
			on_change: (update) => {
				if(update) this.update_filters();
				this.on_change();
			},
			filter_items: (doctype, fieldname) => {
				return !this.filter_exists([doctype, fieldname]);
			}
		};
		let filter = new frappe.ui.Filter(args);
		this.filters.push(filter);
		return filter;
	}

	filter_exists(filter_value) {
		// filter_value of form: [doctype, fieldname, condition, value]
		let exists = false;
		this.filters.filter(f => f.field).map(f => {
			let f_value = f.get_value();
			if (filter_value.length === 2) {
				exists = filter_value[0] === f_value[0] && filter_value[1] === f_value[1];
				return;
			}

			let value = filter_value[3];
			let equal = frappe.utils.arrays_equal;

			if(equal(f_value.slice(0, 4), filter_value.slice(0, 4)) || (Array.isArray(value) && equal(value, f_value[3]))) {
				exists = true;
			}
		});
		return exists;
	}

	get_filters() {
		return this.filters.filter(f => f.field).map(f => {
			f.freeze();
			return f.get_value();
		});
		// {}: this.list.update_standard_filters(values);
	}

	update_filters() {
		this.filters = this.filters.filter(f => f.field); // remove hidden filters
		this.toggle_clear_filter();
	}

	clear_filters() {
		this.filters.map(f => f.remove(true));
		// {}: Clear page filters, .date-range-picker (called list run())
		this.filters = [];
	}

	get_filter(fieldname) {
		return this.filters.filter(f => {
			return (f.field && f.field.df.fieldname==fieldname);
		})[0];
	}

	get_container_template() {
		return $(`

				<button class="btn btn-default btn-xs filter-button text-muted add-filter">
					${__("Add Filter")}
				</button><button class="btn btn-default btn-xs filter-button text-muted clear-filters">
					${__("Clear Filters")}
				</button>

`);
	}
};
<|endoftext|>


<commit_before>import electron from 'electron';
import path from 'path';
import { Curl } from 'node-libcurl';
import fs from 'fs';
import LocalStorage from './local-storage';
import {
  changelogUrl,
  getAppLongName,
  getAppName,
  getAppVersion,
  isDevelopment,
  isMac,
  MNEMONIC_SYM,
} from '../common/constants';
import * as misc from '../common/misc';
import { docsBase } from '../common/documentation';

const { app, Menu, BrowserWindow, shell, dialog } = electron;

const DEFAULT_WIDTH = 1280;
const DEFAULT_HEIGHT = 700;
const MINIMUM_WIDTH = 500;
const MINIMUM_HEIGHT = 400;

let mainWindow = null;
let localStorage = null;

export function init() {
  initLocalStorage();
  initContextMenus();
}

export function createWindow() {
  const zoomFactor = getZoomFactor();
  const { bounds, fullscreen, maximize } = getBounds();
  const { x, y, width, height } = bounds;

  let isVisibleOnAnyDisplay = true;
  for (const d of electron.screen.getAllDisplays()) {
    const isVisibleOnDisplay =
      x >= d.bounds.x &&
      y >= d.bounds.y &&
      x + width <= d.bounds.x + d.bounds.width &&
      y + height <= d.bounds.y + d.bounds.height;

    if (!isVisibleOnDisplay) {
      isVisibleOnAnyDisplay = false;
    }
  }

  mainWindow = new BrowserWindow({
    // Make sure we don't initialize the window outside the bounds
    x: isVisibleOnAnyDisplay ? x : undefined,
    y: isVisibleOnAnyDisplay ? y : undefined,

    // Other options
    fullscreen: fullscreen,
    fullscreenable: true,
    title: getAppName(),
    width: width || DEFAULT_WIDTH,
    height: height || DEFAULT_HEIGHT,
    minHeight: MINIMUM_HEIGHT,
    minWidth: MINIMUM_WIDTH,
    acceptFirstMouse: true,
    icon: path.resolve(__dirname, 'static/icon.png'),
    webPreferences: {
      zoomFactor: zoomFactor,
    },
  });

  // BrowserWindow doesn't have an option for this, so we have to do it manually :(
  if (maximize) {
    mainWindow.maximize();
  }

  mainWindow.on('resize', e => saveBounds());

  mainWindow.on('maximize', e => saveBounds());

  mainWindow.on('unmaximize', e => saveBounds());

  mainWindow.on('move', e => saveBounds());

  mainWindow.on('unresponsive', e => {
    showUnresponsiveModal();
  });

  // Open generic links (<a .../>) in default browser
  mainWindow.webContents.on('will-navigate', (e, url) => {
    if (url === appUrl) {
      return;
    }

    console.log('[app] Navigate to ' + url);
    e.preventDefault();
    electron.shell.openExternal(url);
  });

  // Load the html of the app.
  const url = process.env.APP_RENDER_URL;
  const appUrl = url || `file://${app.getAppPath()}/renderer.html`;
  console.log(`[main] Loading ${appUrl}`);
  mainWindow.loadURL(appUrl);

  // Emitted when the window is closed.
  mainWindow.on('closed', () => {
    // Dereference the window object, usually you would store windows
    // in an array if your app supports multi windows, this is the time
    // when you should delete the corresponding element.
    mainWindow = null;
  });

  const applicationMenu = {
    label: `${MNEMONIC_SYM}Application`,
    submenu: [
      ...(isMac()
        ? [{ label: `A${MNEMONIC_SYM}bout ${getAppName()}`, role: 'about' }, { type: 'separator' }]
        : []),
      {
        label: `${MNEMONIC_SYM}Preferences`,
        click: function(menuItem, window, e) {
          if (!window || !window.webContents) {
            return;
          }
          window.webContents.send('toggle-preferences');
        },
      },
      {
        label: `${MNEMONIC_SYM}Changelog`,
        click: function(menuItem, window, e) {
          if (!window || !window.webContents) {
            return;
          }
          misc.clickLink(changelogUrl());
        },
      },
      { type: 'separator' },
      { role: 'hide' },
      { role: 'hideothers' },
      { type: 'separator' },
      { label: `${MNEMONIC_SYM}Quit`, accelerator: 'CmdOrCtrl+Q', click: () => app.quit() },
    ],
  };

  const editMenu = {
    label: `${MNEMONIC_SYM}Edit`,
    submenu: [
      { label: `${MNEMONIC_SYM}Undo`, accelerator: 'CmdOrCtrl+Z', selector: 'undo:' },
      { label: `${MNEMONIC_SYM}Redo`, accelerator: 'Shift+CmdOrCtrl+Z', selector: 'redo:' },
      { type: 'separator' },
      { label: `Cu${MNEMONIC_SYM}t`, accelerator: 'CmdOrCtrl+X', selector: 'cut:' },
      { label: `${MNEMONIC_SYM}Copy`, accelerator: 'CmdOrCtrl+C', selector: 'copy:' },
      { label: `${MNEMONIC_SYM}Paste`, accelerator: 'CmdOrCtrl+V', selector: 'paste:' },
      {
        label: `Select ${MNEMONIC_SYM}All`,
        accelerator: 'CmdOrCtrl+A',
        selector: 'selectAll:',
      },
    ],
  };

  const viewMenu = {
    label: `${MNEMONIC_SYM}View`,
    submenu: [
      { label: `Toggle ${MNEMONIC_SYM}Full Screen`, role: 'togglefullscreen' },
      {
        label: `${MNEMONIC_SYM}Actual Size`,
        accelerator: 'CmdOrCtrl+0',
        click: () => {
          const w = BrowserWindow.getFocusedWindow();
          if (!w || !w.webContents) {
            return;
          }

          const zoomFactor = 1;
          w.webContents.setZoomFactor(zoomFactor);
          saveZoomFactor(zoomFactor);
        },
      },
      {
        label: `Zoom ${MNEMONIC_SYM}In`,
        accelerator: 'CmdOrCtrl+=',
        click: () => {
          const w = BrowserWindow.getFocusedWindow();
          if (!w || !w.webContents) {
            return;
          }

          const zoomFactor = Math.min(1.8, getZoomFactor() + 0.05);
          w.webContents.setZoomFactor(zoomFactor);

          saveZoomFactor(zoomFactor);
        },
      },
      {
        label: `Zoom ${MNEMONIC_SYM}Out`,
        accelerator: 'CmdOrCtrl+-',
        click: () => {
          const w = BrowserWindow.getFocusedWindow();
          if (!w || !w.webContents) {
            return;
          }

          const zoomFactor = Math.max(0.5, getZoomFactor() - 0.05);
          w.webContents.setZoomFactor(zoomFactor);
          saveZoomFactor(zoomFactor);
        },
      },
      {
        label: 'Toggle Sidebar',
        click: () => {
          const w = BrowserWindow.getFocusedWindow();
          if (!w || !w.webContents) {
            return;
          }

          w.webContents.send('toggle-sidebar');
        },
      },
      {
        label: `Toggle ${MNEMONIC_SYM}DevTools`,
        click: () => mainWindow.toggleDevTools(),
      },
    ],
  };

  const windowMenu = {
    label: `${MNEMONIC_SYM}Window`,
    role: 'window',
    submenu: [
      { label: `${MNEMONIC_SYM}Minimize`, role: 'minimize' },
      ...(isMac() ? [{ label: `${MNEMONIC_SYM}Close`, role: 'close' }] : []),
    ],
  };

  const helpMenu = {
    label: `${MNEMONIC_SYM}Help`,
    role: 'help',
    id: 'help',
    submenu: [
      {
        label: `${MNEMONIC_SYM}Help and Support`,
        accelerator: !isMac() ? 'F1' : null,
        click: () => {
          shell.openExternal(docsBase);
        },
      },
      {
        label: `${MNEMONIC_SYM}Keyboard Shortcuts`,
        accelerator: 'CmdOrCtrl+Shift+?',
        click: (menuItem, w, e) => {
          if (!w || !w.webContents) {
            return;
          }
          w.webContents.send('toggle-preferences-shortcuts');
        },
      },
      {
        label: `Show App ${MNEMONIC_SYM}Data Folder`,
        click: (menuItem, w, e) => {
          const directory = misc.getDataDirectory();
          shell.showItemInFolder(directory);
        },
      },
      {
        label: 'Show Open Source Licenses',
        click: (menuItem, w, e) => {
          const licensePath = path.resolve(app.getAppPath(), '../opensource-licenses.txt');
          shell.openItem(licensePath);
        },
      },
      {
        label: 'Show Software License',
        click: () => {
          shell.openExternal('https://insomnia.rest/license');
        },
      },
      {
        label: `Insomnia ${MNEMONIC_SYM}Help`,
        accelerator: !isMac() ? 'F1' : null,
        click: () => {
          shell.openExternal('https://support.insomnia.rest');
        },
      },
    ],
  };

  if (!isMac()) {
    helpMenu.submenu.unshift({
      label: `${MNEMONIC_SYM}About`,
      click: () => {
        dialog.showMessageBox({
          type: 'info',
          title: getAppName(),
          message: getAppLongName(),
          detail: [
            'Version ' + getAppVersion(),
            'Shell ' + process.versions.electron,
            'Node ' + process.versions.node,
            'V8 ' + process.versions.v8,
            'Architecture ' + process.arch,
            '', // Blank line before libcurl
            Curl.getVersion(),
          ].join('\n'),
        });
      },
    });
  }

  const developerMenu = {
    label: `${MNEMONIC_SYM}Developer`,
    position: 'before=help',
    submenu: [
      {
        label: `${MNEMONIC_SYM}Reload`,
        accelerator: 'Shift+F5',
        click: () => mainWindow.reload(),
      },
      {
        label: `Toggle ${MNEMONIC_SYM}DevTools`,
        accelerator: 'Alt+CmdOrCtrl+I',
        click: () => mainWindow.toggleDevTools(),
      },
      {
        label: `Resize to Defaul${MNEMONIC_SYM}t`,
        click: () =>
          mainWindow.setBounds({
            x: 100,
            y: 100,
            width: DEFAULT_WIDTH,
            height: DEFAULT_HEIGHT,
          }),
      },
      {
        label: `Take ${MNEMONIC_SYM}Screenshot`,
        click: function() {
          mainWindow.capturePage(image => {
            const buffer = image.toPNG();
            const dir = app.getPath('desktop');
            fs.writeFileSync(path.join(dir, `Screenshot-${new Date()}.png`), buffer);
          });
        },
      },
      {
        label: `${MNEMONIC_SYM}Toggle Insomnia`,
        click: () => {
          const w = BrowserWindow.getFocusedWindow();
          if (!w || !w.webContents) {
            return;
          }

          w.webContents.send('toggle-insomnia');
        },
      },
    ],
  };

  const toolsMenu = {
    label: `${MNEMONIC_SYM}Tools`,
    submenu: [
      {
        label: `${MNEMONIC_SYM}Reload Plugins`,
        click: () => {
          const w = BrowserWindow.getFocusedWindow();
          if (!w || !w.webContents) {
            return;
          }

          w.webContents.send('reload-plugins');
        },
      },
    ],
  };

  const template = [];

  template.push(applicationMenu);
  template.push(editMenu);
  template.push(viewMenu);
  template.push(windowMenu);
  template.push(toolsMenu);
  template.push(helpMenu);

  if (isDevelopment() || process.env.INSOMNIA_FORCE_DEBUG) {
    template.push(developerMenu);
  }

  Menu.setApplicationMenu(Menu.buildFromTemplate(template));

  return mainWindow;
}

function showUnresponsiveModal() {
  dialog.showMessageBox(
    {
      type: 'info',
      buttons: ['Cancel', 'Reload'],
      defaultId: 1,
      cancelId: 0,
      title: 'Unresponsive',
      message: 'Insomnia has become unresponsive. Do you want to reload?',
    },
    id => {
      if (id === 1) {
        mainWindow.destroy();
        createWindow();
      }
    },
  );
}

function saveBounds() {
  if (!mainWindow) {
    return;
  }

  const fullscreen = mainWindow.isFullScreen();

  // Only save the size if we're not in fullscreen
  if (!fullscreen) {
    localStorage.setItem('bounds', mainWindow.getBounds());
    localStorage.setItem('maximize', mainWindow.isMaximized());
    localStorage.setItem('fullscreen', false);
  } else {
    localStorage.setItem('fullscreen', true);
  }
}

function getBounds() {
  let bounds = {};
  let fullscreen = false;
  let maximize = false;
  try {
    bounds = localStorage.getItem('bounds', {});
    fullscreen = localStorage.getItem('fullscreen', false);
    maximize = localStorage.getItem('maximize', false);
  } catch (e) {
    // This should never happen, but if it does...!
    console.error('Failed to parse window bounds', e);
  }

  return { bounds, fullscreen, maximize };
}

function saveZoomFactor(zoomFactor) {
  localStorage.setItem('zoomFactor', zoomFactor);
}

function getZoomFactor() {
  let zoomFactor = 1;
  try {
    zoomFactor = localStorage.getItem('zoomFactor', 1);
  } catch (e) {
    // This should never happen, but if it does...!
    console.error('Failed to parse zoomFactor', e);
  }

  return zoomFactor;
}

function initLocalStorage() {
  const localStoragePath = path.join(misc.getDataDirectory(), 'localStorage');
  localStorage = new LocalStorage(localStoragePath);
}

function initContextMenus() {
  require('electron-context-menu')({});
}
<commit_msg>Feature: Show Dev Tools with hotkeys (#2309)<commit_after>import electron from 'electron';
import path from 'path';
import { Curl } from 'node-libcurl';
import fs from 'fs';
import LocalStorage from './local-storage';
import {
  changelogUrl,
  getAppLongName,
  getAppName,
  getAppVersion,
  isDevelopment,
  isMac,
  MNEMONIC_SYM,
} from '../common/constants';
import * as misc from '../common/misc';
import { docsBase } from '../common/documentation';

const { app, Menu, BrowserWindow, shell, dialog } = electron;

const DEFAULT_WIDTH = 1280;
const DEFAULT_HEIGHT = 700;
const MINIMUM_WIDTH = 500;
const MINIMUM_HEIGHT = 400;

let mainWindow = null;
let localStorage = null;

export function init() {
  initLocalStorage();
  initContextMenus();
}

export function createWindow() {
  const zoomFactor = getZoomFactor();
  const { bounds, fullscreen, maximize } = getBounds();
  const { x, y, width, height } = bounds;

  let isVisibleOnAnyDisplay = true;
  for (const d of electron.screen.getAllDisplays()) {
    const isVisibleOnDisplay =
      x >= d.bounds.x &&
      y >= d.bounds.y &&
      x + width <= d.bounds.x + d.bounds.width &&
      y + height <= d.bounds.y + d.bounds.height;

    if (!isVisibleOnDisplay) {
      isVisibleOnAnyDisplay = false;
    }
  }

  mainWindow = new BrowserWindow({
    // Make sure we don't initialize the window outside the bounds
    x: isVisibleOnAnyDisplay ? x : undefined,
    y: isVisibleOnAnyDisplay ? y : undefined,

    // Other options
    fullscreen: fullscreen,
    fullscreenable: true,
    title: getAppName(),
    width: width || DEFAULT_WIDTH,
    height: height || DEFAULT_HEIGHT,
    minHeight: MINIMUM_HEIGHT,
    minWidth: MINIMUM_WIDTH,
    acceptFirstMouse: true,
    icon: path.resolve(__dirname, 'static/icon.png'),
    webPreferences: {
      zoomFactor: zoomFactor,
    },
  });

  // BrowserWindow doesn't have an option for this, so we have to do it manually :(
  if (maximize) {
    mainWindow.maximize();
  }

  mainWindow.on('resize', e => saveBounds());

  mainWindow.on('maximize', e => saveBounds());

  mainWindow.on('unmaximize', e => saveBounds());

  mainWindow.on('move', e => saveBounds());

  mainWindow.on('unresponsive', e => {
    showUnresponsiveModal();
  });

  // Open generic links (<a .../>) in default browser
  mainWindow.webContents.on('will-navigate', (e, url) => {
    if (url === appUrl) {
      return;
    }

    console.log('[app] Navigate to ' + url);
    e.preventDefault();
    electron.shell.openExternal(url);
  });

  // Load the html of the app.
  const url = process.env.APP_RENDER_URL;
  const appUrl = url || `file://${app.getAppPath()}/renderer.html`;
  console.log(`[main] Loading ${appUrl}`);
  mainWindow.loadURL(appUrl);

  // Emitted when the window is closed.
  mainWindow.on('closed', () => {
    // Dereference the window object, usually you would store windows
    // in an array if your app supports multi windows, this is the time
    // when you should delete the corresponding element.
    mainWindow = null;
  });

  const applicationMenu = {
    label: `${MNEMONIC_SYM}Application`,
    submenu: [
      ...(isMac()
        ? [{ label: `A${MNEMONIC_SYM}bout ${getAppName()}`, role: 'about' }, { type: 'separator' }]
        : []),
      {
        label: `${MNEMONIC_SYM}Preferences`,
        click: function(menuItem, window, e) {
          if (!window || !window.webContents) {
            return;
          }
          window.webContents.send('toggle-preferences');
        },
      },
      {
        label: `${MNEMONIC_SYM}Changelog`,
        click: function(menuItem, window, e) {
          if (!window || !window.webContents) {
            return;
          }
          misc.clickLink(changelogUrl());
        },
      },
      { type: 'separator' },
      { role: 'hide' },
      { role: 'hideothers' },
      { type: 'separator' },
      { label: `${MNEMONIC_SYM}Quit`, accelerator: 'CmdOrCtrl+Q', click: () => app.quit() },
    ],
  };

  const editMenu = {
    label: `${MNEMONIC_SYM}Edit`,
    submenu: [
      { label: `${MNEMONIC_SYM}Undo`, accelerator: 'CmdOrCtrl+Z', selector: 'undo:' },
      { label: `${MNEMONIC_SYM}Redo`, accelerator: 'Shift+CmdOrCtrl+Z', selector: 'redo:' },
      { type: 'separator' },
      { label: `Cu${MNEMONIC_SYM}t`, accelerator: 'CmdOrCtrl+X', selector: 'cut:' },
      { label: `${MNEMONIC_SYM}Copy`, accelerator: 'CmdOrCtrl+C', selector: 'copy:' },
      { label: `${MNEMONIC_SYM}Paste`, accelerator: 'CmdOrCtrl+V', selector: 'paste:' },
      {
        label: `Select ${MNEMONIC_SYM}All`,
        accelerator: 'CmdOrCtrl+A',
        selector: 'selectAll:',
      },
    ],
  };

  const viewMenu = {
    label: `${MNEMONIC_SYM}View`,
    submenu: [
      { label: `Toggle ${MNEMONIC_SYM}Full Screen`, role: 'togglefullscreen' },
      {
        label: `${MNEMONIC_SYM}Actual Size`,
        accelerator: 'CmdOrCtrl+0',
        click: () => {
          const w = BrowserWindow.getFocusedWindow();
          if (!w || !w.webContents) {
            return;
          }

          const zoomFactor = 1;
          w.webContents.setZoomFactor(zoomFactor);
          saveZoomFactor(zoomFactor);
        },
      },
      {
        label: `Zoom ${MNEMONIC_SYM}In`,
        accelerator: 'CmdOrCtrl+=',
        click: () => {
          const w = BrowserWindow.getFocusedWindow();
          if (!w || !w.webContents) {
            return;
          }

          const zoomFactor = Math.min(1.8, getZoomFactor() + 0.05);
          w.webContents.setZoomFactor(zoomFactor);

          saveZoomFactor(zoomFactor);
        },
      },
      {
        label: `Zoom ${MNEMONIC_SYM}Out`,
        accelerator: 'CmdOrCtrl+-',
        click: () => {
          const w = BrowserWindow.getFocusedWindow();
          if (!w || !w.webContents) {
            return;
          }

          const zoomFactor = Math.max(0.5, getZoomFactor() - 0.05);
          w.webContents.setZoomFactor(zoomFactor);
          saveZoomFactor(zoomFactor);
        },
      },
      {
        label: 'Toggle Sidebar',
        click: () => {
          const w = BrowserWindow.getFocusedWindow();
          if (!w || !w.webContents) {
            return;
          }

          w.webContents.send('toggle-sidebar');
        },
      },
      {
        label: `Toggle ${MNEMONIC_SYM}DevTools`,
        accelerator: 'AltOrShift+CmdOrCtrl+I',
        click: () => mainWindow.toggleDevTools(),
      },
    ],
  };

  const windowMenu = {
    label: `${MNEMONIC_SYM}Window`,
    role: 'window',
    submenu: [
      { label: `${MNEMONIC_SYM}Minimize`, role: 'minimize' },
      ...(isMac() ? [{ label: `${MNEMONIC_SYM}Close`, role: 'close' }] : []),
    ],
  };

  const helpMenu = {
    label: `${MNEMONIC_SYM}Help`,
    role: 'help',
    id: 'help',
    submenu: [
      {
        label: `${MNEMONIC_SYM}Help and Support`,
        accelerator: !isMac() ? 'F1' : null,
        click: () => {
          shell.openExternal(docsBase);
        },
      },
      {
        label: `${MNEMONIC_SYM}Keyboard Shortcuts`,
        accelerator: 'CmdOrCtrl+Shift+?',
        click: (menuItem, w, e) => {
          if (!w || !w.webContents) {
            return;
          }
          w.webContents.send('toggle-preferences-shortcuts');
        },
      },
      {
        label: `Show App ${MNEMONIC_SYM}Data Folder`,
        click: (menuItem, w, e) => {
          const directory = misc.getDataDirectory();
          shell.showItemInFolder(directory);
        },
      },
      {
        label: 'Show Open Source Licenses',
        click: (menuItem, w, e) => {
          const licensePath = path.resolve(app.getAppPath(), '../opensource-licenses.txt');
          shell.openItem(licensePath);
        },
      },
      {
        label: 'Show Software License',
        click: () => {
          shell.openExternal('https://insomnia.rest/license');
        },
      },
      {
        label: `Insomnia ${MNEMONIC_SYM}Help`,
        accelerator: !isMac() ? 'F1' : null,
        click: () => {
          shell.openExternal('https://support.insomnia.rest');
        },
      },
    ],
  };

  if (!isMac()) {
    helpMenu.submenu.unshift({
      label: `${MNEMONIC_SYM}About`,
      click: () => {
        dialog.showMessageBox({
          type: 'info',
          title: getAppName(),
          message: getAppLongName(),
          detail: [
            'Version ' + getAppVersion(),
            'Shell ' + process.versions.electron,
            'Node ' + process.versions.node,
            'V8 ' + process.versions.v8,
            'Architecture ' + process.arch,
            '', // Blank line before libcurl
            Curl.getVersion(),
          ].join('\n'),
        });
      },
    });
  }

  const developerMenu = {
    label: `${MNEMONIC_SYM}Developer`,
    position: 'before=help',
    submenu: [
      {
        label: `${MNEMONIC_SYM}Reload`,
        accelerator: 'Shift+F5',
        click: () => mainWindow.reload(),
      },
      {
        label: `Resize to Defaul${MNEMONIC_SYM}t`,
        click: () =>
          mainWindow.setBounds({
            x: 100,
            y: 100,
            width: DEFAULT_WIDTH,
            height: DEFAULT_HEIGHT,
          }),
      },
      {
        label: `Take ${MNEMONIC_SYM}Screenshot`,
        click: function() {
          mainWindow.capturePage(image => {
            const buffer = image.toPNG();
            const dir = app.getPath('desktop');
            fs.writeFileSync(path.join(dir, `Screenshot-${new Date()}.png`), buffer);
          });
        },
      },
      {
        label: `${MNEMONIC_SYM}Toggle Insomnia`,
        click: () => {
          const w = BrowserWindow.getFocusedWindow();
          if (!w || !w.webContents) {
            return;
          }

          w.webContents.send('toggle-insomnia');
        },
      },
    ],
  };

  const toolsMenu = {
    label: `${MNEMONIC_SYM}Tools`,
    submenu: [
      {
        label: `${MNEMONIC_SYM}Reload Plugins`,
        click: () => {
          const w = BrowserWindow.getFocusedWindow();
          if (!w || !w.webContents) {
            return;
          }

          w.webContents.send('reload-plugins');
        },
      },
    ],
  };

  const template = [];

  template.push(applicationMenu);
  template.push(editMenu);
  template.push(viewMenu);
  template.push(windowMenu);
  template.push(toolsMenu);
  template.push(helpMenu);

  if (isDevelopment() || process.env.INSOMNIA_FORCE_DEBUG) {
    template.push(developerMenu);
  }

  Menu.setApplicationMenu(Menu.buildFromTemplate(template));

  return mainWindow;
}

function showUnresponsiveModal() {
  dialog.showMessageBox(
    {
      type: 'info',
      buttons: ['Cancel', 'Reload'],
      defaultId: 1,
      cancelId: 0,
      title: 'Unresponsive',
      message: 'Insomnia has become unresponsive. Do you want to reload?',
    },
    id => {
      if (id === 1) {
        mainWindow.destroy();
        createWindow();
      }
    },
  );
}

function saveBounds() {
  if (!mainWindow) {
    return;
  }

  const fullscreen = mainWindow.isFullScreen();

  // Only save the size if we're not in fullscreen
  if (!fullscreen) {
    localStorage.setItem('bounds', mainWindow.getBounds());
    localStorage.setItem('maximize', mainWindow.isMaximized());
    localStorage.setItem('fullscreen', false);
  } else {
    localStorage.setItem('fullscreen', true);
  }
}

function getBounds() {
  let bounds = {};
  let fullscreen = false;
  let maximize = false;
  try {
    bounds = localStorage.getItem('bounds', {});
    fullscreen = localStorage.getItem('fullscreen', false);
    maximize = localStorage.getItem('maximize', false);
  } catch (e) {
    // This should never happen, but if it does...!
    console.error('Failed to parse window bounds', e);
  }

  return { bounds, fullscreen, maximize };
}

function saveZoomFactor(zoomFactor) {
  localStorage.setItem('zoomFactor', zoomFactor);
}

function getZoomFactor() {
  let zoomFactor = 1;
  try {
    zoomFactor = localStorage.getItem('zoomFactor', 1);
  } catch (e) {
    // This should never happen, but if it does...!
    console.error('Failed to parse zoomFactor', e);
  }

  return zoomFactor;
}

function initLocalStorage() {
  const localStoragePath = path.join(misc.getDataDirectory(), 'localStorage');
  localStorage = new LocalStorage(localStoragePath);
}

function initContextMenus() {
  require('electron-context-menu')({});
}
<|endoftext|>