<commit_before>// Load modules

var Crypto = require('crypto');

// Declare internals

var internals = {};

exports = module.exports = function (options) {

    return {
        protocol: 'oauth2',
        useParamsAuth: true,
        auth: 'https://www.facebook.com/v2.3/dialog/oauth',
        token: 'https://graph.facebook.com/oauth/access_token',
        scope: ['email'],
        scopeSeparator: ',',
        profile: function (credentials, params, get, callback) {

            var query = {
                appsecret_proof: Crypto.createHmac('sha256', this.clientSecret).update(credentials.token).digest('hex')
            };

            get('https://graph.facebook.com/v2.3/me', query, function (profile) {

                credentials.profile = {
                    id: profile.id,
                    username: profile.username,
                    displayName: profile.name,
                    name: {
                        first: profile.first_name,
                        last: profile.last_name,
                        middle: profile.middle_name
                    },
                    email: profile.email,
                    raw: profile
                };

                return callback();
            });
        }
    };
};
<commit_msg>Add fields to the query<commit_after>// Load modules

var Crypto = require('crypto');

// Declare internals

var internals = {};

exports = module.exports = function (options) {

    return {
        protocol: 'oauth2',
        useParamsAuth: true,
        auth: 'https://www.facebook.com/v2.3/dialog/oauth',
        token: 'https://graph.facebook.com/oauth/access_token',
        scope: ['email'],
        scopeSeparator: ',',
        profile: function (credentials, params, get, callback) {

            var query = {
                appsecret_proof: Crypto.createHmac('sha256', this.clientSecret).update(credentials.token).digest('hex'),
                fields: 'id,name,email,first_name,last_name,middle_name'
            };

            get('https://graph.facebook.com/v2.3/me', query, function (profile) {

                credentials.profile = {
                    id: profile.id,
                    username: profile.username,
                    displayName: profile.name,
                    name: {
                        first: profile.first_name,
                        last: profile.last_name,
                        middle: profile.middle_name
                    },
                    email: profile.email,
                    raw: profile
                };

                return callback();
            });
        }
    };
};
<|endoftext|>


<commit_before>/**
 *                        WHITEBOPHIR
 *********************************************************
 * @licstart  The following is the entire license notice for the
 *  JavaScript code in this page.
 *
 * Copyright (C) 2013  Ophir LOJKINE
 *
 *
 * The JavaScript code in this page is free software: you can
 * redistribute it and/or modify it under the terms of the GNU
 * General Public License (GNU GPL) as published by the Free Software
 * Foundation, either version 3 of the License, or (at your option)
 * any later version.  The code is distributed WITHOUT ANY WARRANTY;
 * without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE.  See the GNU GPL for more details.
 *
 * As additional permission under GNU GPL version 3 section 7, you
 * may distribute non-source (e.g., minimized or compacted) forms of
 * that code without the copy of the GNU GPL normally required by
 * section 4, provided you include this license notice and a URL
 * through which recipients can access the Corresponding Source.
 *
 * @licend
 */

var Tools = {};

Tools.board = document.getElementById("board");
Tools.svg = document.getElementById("canvas");
Tools.socket = io.connect('', {
	"reconnection delay" : 1, //Make the xhr connections as fast as possible
});
Tools.curTool = null;
Tools.boardName = (function(){
	var path = window.location.pathname.split("/");
	return path[path.length-1];
})();

//Get the board as soon as the page is loaded
Tools.socket.emit("getboard", Tools.boardName);

Tools.HTML = {
	template : new Minitpl("#tools > .tool"),
	addTool : function(toolName, toolIcon) {
		var callback = function () {
			Tools.change(toolName);
		};
		return this.template.add(function (elem) {
				elem.addEventListener("click", callback);
				elem.id = "toolID-"+toolName;
				elem.getElementsByClassName("tool-name")[0].textContent = toolName;
				elem.getElementsByClassName("tool-icon")[0].textContent = toolIcon;
			}
		);
	},
	changeTool : function(oldToolName, newToolName) {
		var oldTool = document.getElementById("toolID-"+oldToolName);
		var newTool = document.getElementById("toolID-"+newToolName);
		if (oldTool) oldTool.classList.remove("curTool");
		if (newTool) newTool.classList.add("curTool");
	},
	addStylesheet : function(href) {
		//Adds a css stylesheet to the html or svg document
		var link = document.createElement("link");
		link.href = href;
		link.rel = "stylesheet";
		link.type = "text/css";
		document.head.appendChild(link);
	}
};

Tools.list = {}; // An array of all known tools. {"toolName" : {toolObject}}

Tools.add = function (newTool) {
	if (newTool.name in Tools.list) {
		console.log("Tools.add: The tool '"+newTool.name+"' is already" +
		"in the list. Updating it...");
	}

	//Format the new tool correctly
	Tools.applyHooks(Tools.toolHooks, newTool);

	//Add the tool to the list
	Tools.list[newTool.name] = newTool;

	if (newTool.stylesheet) {
		Tools.HTML.addStylesheet(newTool.stylesheet);
	}

	//Add the tool to the GUI
	Tools.HTML.addTool(newTool.name, newTool.icon);

	//There may be pending messages for the tool
	var pending = Tools.pendingMessages[newTool.name];
	if (pending) {
		console.log("Drawing pending messages for '%s'.", newTool.name);
		var msg;
		while (msg = pending.shift()) {
			//Transmit the message to the tool (precising that it comes from the network)
			newTool.draw(msg, false);
		}
	}
};

Tools.change = function (toolName){
	if (! (toolName in Tools.list)) {
		throw "Trying to select a tool that has never been added!";
	}

	var newtool = Tools.list[toolName];

	//Update the GUI
	var curToolName = (Tools.curTool) ? Tools.curTool.name : "";
	try {
		Tools.HTML.changeTool(curToolName, toolName);
	} catch (e) {
		console.error("Unable to update the GUI with the new tool. "+e);
	}
	Tools.svg.style.cursor = newtool.mouseCursor || "auto";

	//There is not necessarily already a curTool
	if (Tools.curTool !== null) {
		//It's useless to do anything if the new tool is already selected
		if (newtool === Tools.curTool) return;

		//Remove the old event listeners
		for (var event in Tools.curTool.compiledListeners) {
			var listener = Tools.curTool.compiledListeners[event];
			Tools.board.removeEventListener(event, listener);
		}

		//Call the callbacks of the old tool
		Tools.curTool.onquit(newtool);
	}

	//Add the new event listeners
	for (var event in newtool.compiledListeners) {
		var listener = newtool.compiledListeners[event];
		Tools.board.addEventListener(event, listener);
	}

	//Call the start callback of the new tool
	newtool.onstart(Tools.curTool);
	Tools.curTool = newtool;
};

Tools.send = function(data, toolName){
	toolName = toolName || Tools.curTool.name;
	var d = data;
	d.tool = toolName;
	Tools.applyHooks(Tools.messageHooks, d);
	var message = {
		"board" : Tools.boardName,
		"data" : d
	}
	Tools.socket.emit('broadcast', message);
};

Tools.drawAndSend = function (data) {
	Tools.curTool.draw(data, true);
	Tools.send(data);
};

//Object containing the messages that have been received before the corresponding tool
//is loaded. keys : the name of the tool, values : array of messages for this tool
Tools.pendingMessages = {};

//Receive draw instructions from the server
Tools.socket.on("broadcast", function (message){
	//Check if the message is in the expected format
	if (message.tool) {
		var tool = Tools.list[message.tool];
		if (tool) {
			Tools.applyHooks(Tools.messageHooks, message);
			tool.draw(message, false); //draw the received data
			if (message._children) {
				for (var i=0; i<message._children.length; i++) {
					//Apply hooks on children too
					Tools.applyHooks(Tools.messageHooks, message._children[i]);
					tool.draw(message._children[i]);
				}
			}
		} else {
			//We received a message destinated to a tool that we don't have
			//So we add it to the pending messages
			if (Tools.pendingMessages[message.tool] === undefined) {
				Tools.pendingMessages[message.tool] = [];
			}
			Tools.pendingMessages[message.tool].push(message);
		}
	} else {
		console.error("Received a badly formatted message (no tool). ", message);
	}
});

//List of hook functions that will be applied to messages before sending or drawing them
Tools.messageHooks = [
	function resizeCanvas (m) {
		//Enlarge the canvas is something is drawn near its border
		if (m.x && m.y) {
			var svg = Tools.svg, x=m.x, y=m.y;
			if (x > svg.width.baseVal.value - 1000) {
				svg.width.baseVal.value = x + 2000;
			}
			if (y > svg.height.baseVal.value - 500) {
				svg.height.baseVal.value = y + 2000;
			}
		}
	}
];

//List of hook functions that will be applied to tools before adding them
Tools.toolHooks = [
	function checkToolAttributes(tool) {
		if (typeof(tool.name)!=="string") throw "A tool must have a name";
		if (typeof(tool.listeners)!=="object") {
			tool.listeners = {};
		}
		if (typeof(tool.onstart)!=="function") {
			tool.onstart = function(){};
		}
		if (typeof(tool.onquit)!=="function") {
			tool.onquit = function(){};
		}
	},
	function compileListeners (tool) {
		//compile listeners into compiledListeners
		var listeners = tool.listeners;

		//A tool may provide precompiled listeners
		var compiled = tool.compiledListeners || {};
		tool.compiledListeners = compiled;

		function compile (listener) { //closure
			return (function listen (evt){
					var x = evt.pageX,
						y = evt.pageY;
					return listener(x,y,evt,false);
			});
		}

		function compileTouch (listener) { //closure
			return (function touchListen (evt) {
				//Currently, we don't handle multitouch
				if (evt.changedTouches.length === 1) {
					//evt.preventDefault();
					var touch = evt.changedTouches[0];
					var x = touch.pageX,
						y = touch.pageY;
					return listener(x,y,evt,true);
				}
				return true;
			});
		}

		if (listeners.press) {
			compiled["mousedown"] = compile(listeners.press);
			compiled["touchstart"] = compileTouch(listeners.press);
		}
		if (listeners.move) {
			compiled["mousemove"] = compile(listeners.move);
			compiled["touchmove"] = compileTouch(listeners.move);
		}
		if (listeners.release) {
			var release = compile(listeners.release),
				releaseTouch = compileTouch(listeners.release);
			compiled["mouseup"] = release;
			compiled["mouseleave"] = release;
			compiled["touchleave"] = releaseTouch;
			compiled["touchend"] = releaseTouch;
			compiled["touchcancel"] = releaseTouch;
		}
	}
];

Tools.applyHooks = function(hooks, object) {
	//Apply every hooks on the object
	hooks.forEach(function(hook) {
		hook(object);
	});
};

// Utility functions

Tools.generateUID = function (prefix, suffix) {
	var uid = Date.now().toString(36); //Create the uids in chronological order
	uid += (Math.round(Math.random()*36)).toString(36); //Add a random character at the end
	if (prefix) uid = prefix + uid;
	if (suffix) uid = uid + suffix;
	return uid;
};

Tools.createSVGElement = function (name) {
	return document.createElementNS(Tools.svg.namespaceURI, name);
};

Tools.positionElement = function (elem, x, y) {
	elem.style.top = y+"px";
	elem.style.left = x+"px";
};

(function color (){
	var chooser = document.getElementById("chooseColor");
	Tools.getColor = function(){
		return chooser.value;
	};
})();

(function size (){
	var chooser = document.getElementById("chooseSize");

	function update (){
		if (chooser.value<1 || chooser.value > 50) {
			chooser.value=3;
		}
	}
	update();

	chooser.onchange = update;
	Tools.getSize = function(){
		return chooser.value;
	};
})();

//Scale the canvas on load
Tools.svg.width.baseVal.value = document.body.clientWidth;
Tools.svg.height.baseVal.value = document.body.clientHeight;

(function menu () {
	var menu = document.getElementById("menu");
		tog = document.getElementById("toggleMenu");

	tog.onclick = function(e){
		menu.classList.toggle("closed");
	};
})();

/***********  Polyfills  ***********/
if (!window.performance || !window.performance.now) {
	window.performance = {
		"now" : Date.now
	}
}
if (!Math.hypot) {
	Math.hypot = function (x,y) {
		//The true Math.hypot accepts any number of parameters
		return Math.sqrt(x*x+y*y);
	}
}

/**
 What does a "tool" object look like?
 newtool = {
 	"name" : "SuperTool",
 	"listeners" : {
 		"press" : function(x,y,evt){...},
 		"move" : function(x,y,evt){...},
  		"release" : function(x,y,evt){...},
 	},
 	"draw" : function(data, isLocal){
 		//Print the data on Tools.svg
 	},
 	"onstart" : function(oldTool){...},
 	"onquit" : function(newTool){...},
 	"stylesheet" : "style.css",
}
*/
<commit_msg>Code style improvement<commit_after>/**
 *                        WHITEBOPHIR
 *********************************************************
 * @licstart  The following is the entire license notice for the
 *  JavaScript code in this page.
 *
 * Copyright (C) 2013  Ophir LOJKINE
 *
 *
 * The JavaScript code in this page is free software: you can
 * redistribute it and/or modify it under the terms of the GNU
 * General Public License (GNU GPL) as published by the Free Software
 * Foundation, either version 3 of the License, or (at your option)
 * any later version.  The code is distributed WITHOUT ANY WARRANTY;
 * without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE.  See the GNU GPL for more details.
 *
 * As additional permission under GNU GPL version 3 section 7, you
 * may distribute non-source (e.g., minimized or compacted) forms of
 * that code without the copy of the GNU GPL normally required by
 * section 4, provided you include this license notice and a URL
 * through which recipients can access the Corresponding Source.
 *
 * @licend
 */

var Tools = {};

Tools.board = document.getElementById("board");
Tools.svg = document.getElementById("canvas");
Tools.socket = io.connect('', {
	"reconnection delay" : 1, //Make the xhr connections as fast as possible
});
Tools.curTool = null;
Tools.boardName = (function(){
	var path = window.location.pathname.split("/");
	return path[path.length-1];
})();

//Get the board as soon as the page is loaded
Tools.socket.emit("getboard", Tools.boardName);

Tools.HTML = {
	template : new Minitpl("#tools > .tool"),
	addTool : function(toolName, toolIcon) {
		var callback = function () {
			Tools.change(toolName);
		};
		return this.template.add(function (elem) {
				elem.addEventListener("click", callback);
				elem.id = "toolID-"+toolName;
				elem.getElementsByClassName("tool-name")[0].textContent = toolName;
				elem.getElementsByClassName("tool-icon")[0].textContent = toolIcon;
			}
		);
	},
	changeTool : function(oldToolName, newToolName) {
		var oldTool = document.getElementById("toolID-"+oldToolName);
		var newTool = document.getElementById("toolID-"+newToolName);
		if (oldTool) oldTool.classList.remove("curTool");
		if (newTool) newTool.classList.add("curTool");
	},
	addStylesheet : function(href) {
		//Adds a css stylesheet to the html or svg document
		var link = document.createElement("link");
		link.href = href;
		link.rel = "stylesheet";
		link.type = "text/css";
		document.head.appendChild(link);
	}
};

Tools.list = {}; // An array of all known tools. {"toolName" : {toolObject}}

Tools.add = function (newTool) {
	if (newTool.name in Tools.list) {
		console.log("Tools.add: The tool '"+newTool.name+"' is already" +
		"in the list. Updating it...");
	}

	//Format the new tool correctly
	Tools.applyHooks(Tools.toolHooks, newTool);

	//Add the tool to the list
	Tools.list[newTool.name] = newTool;

	if (newTool.stylesheet) {
		Tools.HTML.addStylesheet(newTool.stylesheet);
	}

	//Add the tool to the GUI
	Tools.HTML.addTool(newTool.name, newTool.icon);

	//There may be pending messages for the tool
	var pending = Tools.pendingMessages[newTool.name];
	if (pending) {
		console.log("Drawing pending messages for '%s'.", newTool.name);
		var msg;
		while (msg = pending.shift()) {
			//Transmit the message to the tool (precising that it comes from the network)
			newTool.draw(msg, false);
		}
	}
};

Tools.change = function (toolName){
	if (! (toolName in Tools.list)) {
		throw "Trying to select a tool that has never been added!";
	}

	var newtool = Tools.list[toolName];

	//Update the GUI
	var curToolName = (Tools.curTool) ? Tools.curTool.name : "";
	try {
		Tools.HTML.changeTool(curToolName, toolName);
	} catch (e) {
		console.error("Unable to update the GUI with the new tool. "+e);
	}
	Tools.svg.style.cursor = newtool.mouseCursor || "auto";

	//There is not necessarily already a curTool
	if (Tools.curTool !== null) {
		//It's useless to do anything if the new tool is already selected
		if (newtool === Tools.curTool) return;

		//Remove the old event listeners
		for (var event in Tools.curTool.compiledListeners) {
			var listener = Tools.curTool.compiledListeners[event];
			Tools.board.removeEventListener(event, listener);
		}

		//Call the callbacks of the old tool
		Tools.curTool.onquit(newtool);
	}

	//Add the new event listeners
	for (var event in newtool.compiledListeners) {
		var listener = newtool.compiledListeners[event];
		Tools.board.addEventListener(event, listener);
	}

	//Call the start callback of the new tool
	newtool.onstart(Tools.curTool);
	Tools.curTool = newtool;
};

Tools.send = function(data, toolName){
	toolName = toolName || Tools.curTool.name;
	var d = data;
	d.tool = toolName;
	Tools.applyHooks(Tools.messageHooks, d);
	var message = {
		"board" : Tools.boardName,
		"data" : d
	}
	Tools.socket.emit('broadcast', message);
};

Tools.drawAndSend = function (data) {
	Tools.curTool.draw(data, true);
	Tools.send(data);
};

//Object containing the messages that have been received before the corresponding tool
//is loaded. keys : the name of the tool, values : array of messages for this tool
Tools.pendingMessages = {};

//Receive draw instructions from the server
Tools.socket.on("broadcast", function (message){
	//Check if the message is in the expected format
	if (message.tool) {
		var tool = Tools.list[message.tool];
		if (tool) {
			Tools.applyHooks(Tools.messageHooks, message);
			tool.draw(message, false); //draw the received data
			if (message._children) {
				for (var i=0; i<message._children.length; i++) {
					//Apply hooks on children too
					Tools.applyHooks(Tools.messageHooks, message._children[i]);
					tool.draw(message._children[i]);
				}
			}
		} else {
			//We received a message destinated to a tool that we don't have
			//So we add it to the pending messages
			if (Tools.pendingMessages[message.tool] === undefined) {
				Tools.pendingMessages[message.tool] = [];
			}
			Tools.pendingMessages[message.tool].push(message);
		}
	} else {
		console.error("Received a badly formatted message (no tool). ", message);
	}
});

//List of hook functions that will be applied to messages before sending or drawing them
Tools.messageHooks = [
	function resizeCanvas (m) {
		//Enlarge the canvas is something is drawn near its border
		if (m.x && m.y) {
			var svg = Tools.svg, x=m.x, y=m.y;
			if (x > svg.width.baseVal.value - 1000) {
				svg.width.baseVal.value = x + 2000;
			}
			if (y > svg.height.baseVal.value - 500) {
				svg.height.baseVal.value = y + 2000;
			}
		}
	}
];

//List of hook functions that will be applied to tools before adding them
Tools.toolHooks = [
	function checkToolAttributes(tool) {
		if (typeof(tool.name)!=="string") throw "A tool must have a name";
		if (typeof(tool.listeners)!=="object") {
			tool.listeners = {};
		}
		if (typeof(tool.onstart)!=="function") {
			tool.onstart = function(){};
		}
		if (typeof(tool.onquit)!=="function") {
			tool.onquit = function(){};
		}
	},
	function compileListeners (tool) {
		//compile listeners into compiledListeners
		var listeners = tool.listeners;

		//A tool may provide precompiled listeners
		var compiled = tool.compiledListeners || {};
		tool.compiledListeners = compiled;

		function compile (listener) { //closure
			return (function listen (evt){
					var x = evt.pageX,
						y = evt.pageY;
					return listener(x,y,evt,false);
			});
		}

		function compileTouch (listener) { //closure
			return (function touchListen (evt) {
				//Currently, we don't handle multitouch
				if (evt.changedTouches.length === 1) {
					//evt.preventDefault();
					var touch = evt.changedTouches[0];
					var x = touch.pageX,
						y = touch.pageY;
					return listener(x,y,evt,true);
				}
				return true;
			});
		}

		if (listeners.press) {
			compiled["mousedown"] = compile(listeners.press);
			compiled["touchstart"] = compileTouch(listeners.press);
		}
		if (listeners.move) {
			compiled["mousemove"] = compile(listeners.move);
			compiled["touchmove"] = compileTouch(listeners.move);
		}
		if (listeners.release) {
			var release = compile(listeners.release),
				releaseTouch = compileTouch(listeners.release);
			compiled["mouseup"] = release;
			compiled["mouseleave"] = release;
			compiled["touchleave"] = releaseTouch;
			compiled["touchend"] = releaseTouch;
			compiled["touchcancel"] = releaseTouch;
		}
	}
];

Tools.applyHooks = function(hooks, object) {
	//Apply every hooks on the object
	hooks.forEach(function(hook) {
		hook(object);
	});
};

// Utility functions

Tools.generateUID = function (prefix, suffix) {
	var uid = Date.now().toString(36); //Create the uids in chronological order
	uid += (Math.round(Math.random()*36)).toString(36); //Add a random character at the end
	if (prefix) uid = prefix + uid;
	if (suffix) uid = uid + suffix;
	return uid;
};

Tools.createSVGElement = function (name) {
	return document.createElementNS(Tools.svg.namespaceURI, name);
};

Tools.positionElement = function (elem, x, y) {
	elem.style.top = y+"px";
	elem.style.left = x+"px";
};

Tools.getColor = (function color (){
	var chooser = document.getElementById("chooseColor");
	return function(){return chooser.value;};
})();

Tools.getSize = (function size (){
	var chooser = document.getElementById("chooseSize");

	function update (){
		if (chooser.value<1 || chooser.value > 50) {
			chooser.value=3;
		}
	}
	update();

	chooser.onchange = update;
	return function(){return chooser.value;};
})();

//Scale the canvas on load
Tools.svg.width.baseVal.value = document.body.clientWidth;
Tools.svg.height.baseVal.value = document.body.clientHeight;

(function menu () {
	var menu = document.getElementById("menu");
		tog = document.getElementById("toggleMenu");

	tog.onclick = function(e){
		menu.classList.toggle("closed");
	};
})();

/***********  Polyfills  ***********/
if (!window.performance || !window.performance.now) {
	window.performance = {
		"now" : Date.now
	}
}
if (!Math.hypot) {
	Math.hypot = function (x,y) {
		//The true Math.hypot accepts any number of parameters
		return Math.sqrt(x*x+y*y);
	}
}

/**
 What does a "tool" object look like?
 newtool = {
 	"name" : "SuperTool",
 	"listeners" : {
 		"press" : function(x,y,evt){...},
 		"move" : function(x,y,evt){...},
  		"release" : function(x,y,evt){...},
 	},
 	"draw" : function(data, isLocal){
 		//Print the data on Tools.svg
 	},
 	"onstart" : function(oldTool){...},
 	"onquit" : function(newTool){...},
 	"stylesheet" : "style.css",
}
*/
<|endoftext|>


<commit_before>import axios from 'axios';
import {
  NEW_TASK,
  GET_TASKS,
  DELETE_TASK,
  CLEAR_TASKS,
  RENAME_TASK,
  TOGGLE_DONE,
  ADD_MESSAGE,
} from '../actions/actionTypes';

export function getTasksSuccess(response) {
  return {
    type: GET_TASKS,
    response,
  };
}

export function taskError(response) {
  return {
    type: ADD_MESSAGE,
    response,
  };
}

export function getTasks(id) {
  const error = {
    message: 'Something went wrong. Could not load the tasks. Try reloading.',
    name: 'tasks-get-error',
    type: 'error',
  };
  return dispatch =>
    axios
      .get(`/projects/${id}/getTasks`)
      .then(res => {
        if (res.data.tasksList) {
          dispatch(getTasksSuccess(res.data.tasksList));
        } else {
          dispatch(taskError(error));
        }
      })
      .catch(() => dispatch(taskError(error)));
}

export function newTaskSuccess(task) {
  return {
    type: NEW_TASK,
    task,
  };
}

export function newTask(task) {
  const { name, project } = task;
  const error = {
    message:
      'Something went wrong. Could not create the task. Try again or reload the page',
    name: 'tasks-new-error',
    type: 'error',
  };
  return dispatch =>
    axios
      .post(`/projects/${task.project}/add`, { name, project })
      .then(res => {
        if (res.data.task) {
          dispatch(newTaskSuccess(res.data.task));
        } else {
          dispatch(taskError(error));
        }
      })
      .catch(() => dispatch(taskError(error)));
}

export function deleteTaskSuccess(id) {
  return {
    type: DELETE_TASK,
    id,
  };
}

export function deleteTask(id) {
  const error = {
    message:
      'Something went wrong. Could not delete the task. Try again or reload the page',
    name: 'tasks-delete-error',
    type: 'error',
  };
  return dispatch =>
    axios
      .post(`/projects/${id}/delete`, { id })
      .then(res => {
        if (res.data.deleted) {
          dispatch(deleteTaskSuccess(id));
        } else {
          dispatch(taskError(error));
        }
      })
      .catch(() => dispatch(taskError(error)));
}

export function renameTaskSuccess(id, name) {
  return {
    type: RENAME_TASK,
    id,
    name,
  };
}

export function renameTask(id, name) {
  const error = {
    message:
      'Something went wrong. Could not rename the task. Try again or reload the page',
    name: 'tasks-rename-error',
    type: 'error',
  };
  return dispatch =>
    axios
      .post(`/projects/tasks/${id}/edit`, { id, name })
      .then(res => {
        if (res.data.renamed) {
          dispatch(renameTaskSuccess(id, name));
        } else {
          dispatch(taskError(error));
        }
      })
      .catch(() => dispatch(taskError(error)));
}

export function clearTasks() {
  return {
    type: CLEAR_TASKS,
    response: [],
  };
}

export function toggleDoneSuccess(id, done) {
  return {
    type: TOGGLE_DONE,
    id,
    done,
  };
}

export function toggleDone(id) {
  const error = {
    message:
      'Something went wrong. Could not toggle the task. Try again or reload the page',
    name: 'tasks-toggle-error',
    type: 'error',
  };
  return dispatch =>
    axios
      .post(`/projects/tasks/${id}/done`, { id })
      .then(res => {
        if (res.data.done !== undefined) {
          dispatch(toggleDoneSuccess(id, res.data.done));
        } else {
          dispatch(taskError(error));
        }
      })
      .catch(() => dispatch(taskError(error)));
}
<commit_msg>editing task now supports changing the project<commit_after>import axios from 'axios';
import {
  NEW_TASK,
  GET_TASKS,
  DELETE_TASK,
  CLEAR_TASKS,
  RENAME_TASK,
  TOGGLE_DONE,
  ADD_MESSAGE,
} from '../actions/actionTypes';

export function getTasksSuccess(response) {
  return {
    type: GET_TASKS,
    response,
  };
}

export function taskError(response) {
  return {
    type: ADD_MESSAGE,
    response,
  };
}

export function getTasks(id) {
  const error = {
    message: 'Something went wrong. Could not load the tasks. Try reloading.',
    name: 'tasks-get-error',
    type: 'error',
  };
  return dispatch =>
    axios
      .get(`/projects/${id}/getTasks`)
      .then(res => {
        if (res.data.tasksList) {
          dispatch(getTasksSuccess(res.data.tasksList));
        } else {
          dispatch(taskError(error));
        }
      })
      .catch(() => dispatch(taskError(error)));
}

export function newTaskSuccess(task) {
  return {
    type: NEW_TASK,
    task,
  };
}

export function newTask(task) {
  const { name, project } = task;
  const error = {
    message:
      'Something went wrong. Could not create the task. Try again or reload the page',
    name: 'tasks-new-error',
    type: 'error',
  };
  return dispatch =>
    axios
      .post(`/projects/${task.project}/add`, { name, project })
      .then(res => {
        if (res.data.task) {
          dispatch(newTaskSuccess(res.data.task));
        } else {
          dispatch(taskError(error));
        }
      })
      .catch(() => dispatch(taskError(error)));
}

export function deleteTaskSuccess(id) {
  return {
    type: DELETE_TASK,
    id,
  };
}

export function deleteTask(id) {
  const error = {
    message:
      'Something went wrong. Could not delete the task. Try again or reload the page',
    name: 'tasks-delete-error',
    type: 'error',
  };
  return dispatch =>
    axios
      .post(`/projects/${id}/delete`, { id })
      .then(res => {
        if (res.data.deleted) {
          dispatch(deleteTaskSuccess(id));
        } else {
          dispatch(taskError(error));
        }
      })
      .catch(() => dispatch(taskError(error)));
}

export function renameTaskSuccess(id, name, project) {
  return {
    type: RENAME_TASK,
    id,
    name,
    project
  };
}

export function renameTask(id, name, categoryID) {
  const error = {
    message:
      'Something went wrong. Could not rename the task. Try again or reload the page',
    name: 'tasks-rename-error',
    type: 'error',
  };
  return dispatch =>
    axios
      .post(`/projects/tasks/${id}/edit`, { id, name, project: categoryID })
      .then(res => {
        console.log(res.data);
        if (res.data.renamed) {
          dispatch(renameTaskSuccess(id, name, categoryID));
        } else {
          dispatch(taskError(error));
        }
      })
      .catch(() => dispatch(taskError(error)));
}

export function clearTasks() {
  return {
    type: CLEAR_TASKS,
    response: [],
  };
}

export function toggleDoneSuccess(id, done) {
  return {
    type: TOGGLE_DONE,
    id,
    done,
  };
}

export function toggleDone(id) {
  const error = {
    message:
      'Something went wrong. Could not toggle the task. Try again or reload the page',
    name: 'tasks-toggle-error',
    type: 'error',
  };
  return dispatch =>
    axios
      .post(`/projects/tasks/${id}/done`, { id })
      .then(res => {
        if (res.data.done !== undefined) {
          dispatch(toggleDoneSuccess(id, res.data.done));
        } else {
          dispatch(taskError(error));
        }
      })
      .catch(() => dispatch(taskError(error)));
}
<|endoftext|>


<commit_before>'use strict';

// - store: contains the product list
// - cart: the shopping cart object
function storeController($scope, $routeParams, DataService) {

  // get store and cart from service
  $scope.store = DataService.store;
  $scope.cart = DataService.cart;

  // use routing to pick the selected product
  if ($routeParams.productSku != null) {
      $scope.product = $scope.store.getProduct($routeParams.productSku);
  }

  $scope.user = DataService.user;
}

function userController($scope, DataService) {

  $scope.user = DataService.user;

  function closeLoginDialog() {
    $('#loginDialog').modal('hide');
  }

  $scope.login = function() {

    // todo: add a spinner to the dialog
    var promise = $scope.user.login();
    promise.then(
      function(success) {
        console.log(success);
        closeLoginDialog();
      },
      function(failure) {
        console.log(failure);
        // todo: put the error on the dialog instead
        alert('Login failed: ' + (failure.data.message || failure.data.error_description));
      }
    );
  };

  $scope.oauthLogin = function(provider) {

    $scope.oauthCallback = function(e) {
//      if (e.origin !== "") return; // todo: origin check
      var params = e.data;
      console.log(e);
      if (params.username) {
        console.log('username: ' + params.username);
        console.log('accessToken: ' + params.accessToken);
        $scope.user.setUsername(params.username);
        $scope.user.setAccessToken(params.accessToken);
        $scope.$apply();
        closeLoginDialog();
      }
    };

    var url = 'http://localhost:3000/auth/' + provider;
    var width = 1020;
    var height = 600;
    var left = (screen.availWidth/2)-(width/2);
    var top = (screen.availHeight/2)-(height/2);
    window.addEventListener("message", $scope.oauthCallback, false);
    window.open(url, "SignIn", "left="+left+",top="+top+",width="+width+",height="+height+",toolbar=0,scrollbars=0,status=0,resizable=0,location=0,menuBar=0");
  };

  $scope.logout = function() {
    $scope.user.logout();
  };
}

function oauthCallbackController($location) {

  var queryString = {};
  $location.absUrl().replace(
    new RegExp("([^?=&]+)=(([^&#]*))?", "g"),
    function($0, $1, $2, $3) { queryString[decodeURIComponent($1)] = decodeURIComponent($3); }
  );

  // todo: replace '*' with origin
  window.opener.postMessage(queryString, "*");
  window.close();
}
<commit_msg>do appropriate origin set and check for oauth postMessage<commit_after>'use strict';

// - store: contains the product list
// - cart: the shopping cart object
function storeController($scope, $routeParams, DataService) {

  // get store and cart from service
  $scope.store = DataService.store;
  $scope.cart = DataService.cart;

  // use routing to pick the selected product
  if ($routeParams.productSku != null) {
      $scope.product = $scope.store.getProduct($routeParams.productSku);
  }

  $scope.user = DataService.user;
}

function userController($scope, DataService, config) {

  $scope.user = DataService.user;

  function closeLoginDialog() {
    $('#loginDialog').modal('hide');
  }

  $scope.login = function() {

    // todo: add a spinner to the dialog
    var promise = $scope.user.login();
    promise.then(
      function(success) {
        console.log(success);
        closeLoginDialog();
      },
      function(failure) {
        console.log(failure);
        // todo: put the error on the dialog instead
        alert('Login failed: ' + (failure.data.message || failure.data.error_description));
      }
    );
  };

  $scope.oauthLogin = function(provider) {

    $scope.oauthCallback = function(e) {
      if (e.origin !== config.base) { return; }
      var params = e.data;
      if (params.username) {
        console.log('username: ' + params.username);
        console.log('accessToken: ' + params.accessToken);
        $scope.user.setUsername(params.username);
        $scope.user.setAccessToken(params.accessToken);
        $scope.$apply();
        closeLoginDialog();
      }
    };

    var url = config.base + '/auth/' + provider;
    var width = 1020;
    var height = 600;
    var left = (screen.availWidth/2)-(width/2);
    var top = (screen.availHeight/2)-(height/2);
    window.addEventListener("message", $scope.oauthCallback, false);
    window.open(url, "SignIn", "left="+left+",top="+top+",width="+width+",height="+height+",toolbar=0,scrollbars=0,status=0,resizable=0,location=0,menuBar=0");
  };

  $scope.logout = function() {
    $scope.user.logout();
  };
}

function oauthCallbackController($location, config) {

  var queryString = {};
  $location.absUrl().replace(
    new RegExp("([^?=&]+)=(([^&#]*))?", "g"),
    function($0, $1, $2, $3) { queryString[decodeURIComponent($1)] = decodeURIComponent($3); }
  );

  window.opener.postMessage(queryString, config.base);
  window.close();
}
<|endoftext|>


<commit_before>/**
 * Adds a date and price as a tuple to a targetSeries
 * @param {HighChart.series} targetSeries reference
 * @param {int} date UTC formatted time
 * @param {int} price currency price
 */
var addDataPointToSeries = function (targetSeries, date, price) {
  targetSeries.addPoint([date, price], false);
};

// Adds a live data point to a series, differs from "addDataPointToSeries"
//    because it defaults to true for redrawing the chart, hence a "live"
//    addPoint functionality
var addLiveDataPointToSeries = function (targetSeries, date, price) {
  targetSeries.addPoint([date, price], true);
};

/**
 * Adds data points to a certain series, given a data set (chartData)
 * @param {HighChart.series} targetSeries reference
 * @param {object} chartData
 */
var addTickerDatasetToSeries = function (targetSeries, tickerData) {
  for (var i = 0; i < tickerData.length; i++) {
    var date = tickerData[i].date * 1000;
    var price = tickerData[i].close;
    console.log('adding point...');
    addDataPointToSeries(targetSeries, date, price);
  }
};

/**
 * Adds data points to a certain series, given a data set (chartData)
 * @param {HighChart.series} targetSeries reference
 * @param {object} chartData
 */
var addBacktestDatasetToSeries = function (targetSeries, tickerData) {
  for (var i = 0; i < tickerData.length; i++) {
    var date = tickerData[i][0] * 1000;
    var price = tickerData[i][1];
    console.log('backtest: adding point...');
    addDataPointToSeries(targetSeries, date, price);
  }
};

/**
 * Adds data points to a certain series, given a data set (chartData)
 * @param {HighChart.series} targetSeries reference
 * @param {object} chartData
 */
var addBenchMarkDatasetToSeries = function (targetSeries, tickerData) {
  for (var i = 0; i < tickerData.length; i++) {
    var date = tickerData[i][0] * 1000;
    var price = tickerData[i][1];
    console.log('benchmark: adding point...');
    addDataPointToSeries(targetSeries, date, price);
  }
};

/**
 * Adds data points to a certain series, given a data set (chartData)
 * @param {HighChart.series} targetSeries reference
 * @param {array[][]} chartData
 */
var addIndicatorDatasetToSeries = function (targetSeries, chartData) {
  for (var i = 0; i < chartData.length; i++) {
    var date = chartData[i][0] * 1000;
    var price = chartData[i][1];
    //console.log('date:', date, 'price:', price);
    addDataPointToSeries(targetSeries, date, price);
  }
};

/**
 * Creates object literal, given paramaters, and adds it to highchart
 * @param {HighChart} highchart self reference
 * @param {object} params parameters to add to series
 */
var createCandlestickSeries = function (highchart, name) {
  var seriesObj = {};
  seriesObj.name = name;
  seriesObj.id = name;
  seriesObj.data = [];
  seriesObj.marker = {
    enabled: true,
    radius: 2
  };
  seriesObj.tooltip = {
    valueDecimals: 5
  };
  highchart.addSeries(seriesObj, true);
};

/**
 * Creates object literal, given paramaters, and adds it to highchart
 * @param {HighChart} highchart self reference
 * @param {object} params parameters to add to series
 */
var createIndicatorSeries = function (highchart, name, spline) {
  var seriesObj = {};
  seriesObj.name = name;
  seriesObj.id = name;
  seriesObj.data = [];
  seriesObj.marker = {
    enabled: false,
    radius: 3
  };
  if (spline == true) {
    seriesObj.type = 'spline';
  }
  seriesObj.tooltip = {
    valueDecimals: 5
  };
  highchart.addSeries(seriesObj, true);
};

var createFlagSeries = function (highchart) {
  var seriesObj = {};
  seriesObj.id = 'flags';
  seriesObj.type = 'flags';
  seriesObj.data = [];
  seriesObj.onSeries = 'Closing Price';
  seriesObj.shape = 'circlepin';
  seriesObj.width = 20;

  highchart.addSeries(seriesObj);
};

/**
 * Every flag consists of x, title and text. The attribute "x" must be set to
 * the point where the flag should appear. The attribute "title" is the text
 * which is displayed inside the flag on the chart. The attribute "text" contains
 * the text which will appear when the mouse hover above the flag.
 */
var addFlagToSeries = function (highchart, timeStamp, order) {
  var flagObj = {};
  console.log('inside addFlagToSeries:', timeStamp, order);
  flagObj.x = timeStamp;
  flagObj.title = order;
  flagObj.text = 'Make a trade here.';

  highchart.get('flags').addPoint(flagObj);
};

/**
 * Connects and listens on two sockets to initialize and then update a chart.
 *     initializedChartData creates a series and adds historical data to it.
 *     updatedChartData listens for live data and adds it to a targetSeries
 * @param {HighChart} highchart self reference
 */
var loadStrategyTrades = function (highchart) {
  var socket = io.connect('http://localhost:3000');
  console.log(socket);
  if ((socket).connected) {     // weird issue where accessing variable switches disconnected and concected
    socket = io.connect('https://powerful-lake-24304.herokuapp.com/');
    console.log('Heroku domain socket selected');
  }

  console.log('CONNECTION RECEIVED. SERVER RUNNING AT http://localhost:3000');
  highchart.showLoading('');

  // INITALIZE CHART WITH HISTORICAL DATA
  socket.on('initializedChartData', function (chartData) {

    console.log('### initializedChartData received...');
    console.log('### creating series...');

    console.log(Object.keys(chartData));

    createCandlestickSeries(highchart, 'Closing Price');
    createIndicatorSeries(highchart, '10-Day Moving Average');
    createIndicatorSeries(highchart, '20-Day Moving Average');

    /* Creating tickerData chart lines */
    var tickerData = chartData.tickerData;
    // console.log(tickerData);
    var targetSeries = highchart.get("Closing Price");
    addTickerDatasetToSeries(targetSeries, tickerData);
    //
    // /* Adding indicators */
    var SMA_A = chartData.indicators[0];
    var targetSMA10 = highchart.get('10-Day Moving Average');
    console.log('### adding SMA10 to chart');
    addIndicatorDatasetToSeries(targetSMA10, SMA_A);

    var SMA_B = chartData.indicators[1];
    var targetSMA20 = highchart.get('20-Day Moving Average');
    console.log('### adding SMA20 to chart');
    addIndicatorDatasetToSeries(targetSMA20, SMA_B);

    // /* Adding order flags */
    createFlagSeries(highchart);
    for (var i = 0; i < chartData.flags.length; i++) {
      console.log('flag added');
      var timeStamp = chartData.flags[i].timestamp * 1000;
      var orderLongShort = chartData.flags[i].longShort;
      addFlagToSeries(highchart, timeStamp, orderLongShort);
    }

    highchart.hideLoading();

  });

  // UPDATE CHART WITH LIVE DATA
  socket.on('updatedChartData', function (chartData) {
    console.log("### CLIENT: Live Data Point Received");
    var date = chartData.time;
    var price = parseFloat(chartData.mostRecentTickerPrice);
    var targetSeries = highchart.get('Closing Price');
    addLiveDataPointToSeries(targetSeries, date, price);
  });
};

/**
 * Connects and listens on two sockets to initialize and then update a chart.
 *     initializedChartData creates a series and adds historical data to it.
 *     updatedChartData listens for live data and adds it to a targetSeries
 * @param {HighChart} highchart self reference
 */
var loadPortfolioPerformance = function (highchart) {

  var socket = io.connect(window.location.href);
  console.log('~~~~~~');
  console.log(socket);
  console.log(socket.connected);
  console.log(socket.disconnected);
  console.log('~~~~~~');

  console.log(window.location.href);

  // if ((socket).connected) {     // weird issue where accessing variable switches disconnected and concected
  //   socket = io.connect('https://powerful-lake-24304.herokuapp.com/');
  //   console.log('Heroku domain socket selected');
  // }

  highchart.showLoading('');

  // INITALIZE CHART WITH HISTORICAL DATA
  socket.on('backtest', function (chartData) {
    console.log(socket);
    console.log(socket.connected);
    console.log(socket.disconnected);    console.log('### <Backtest> received...');
    console.log(Object.keys(chartData));

    /* Creating tickerData benchmark chart lines */
    createIndicatorSeries(highchart, 'Benchmark', false);
    var bm = chartData.benchmark;
    var bmtarget = highchart.get('Benchmark');
    addBenchMarkDatasetToSeries(bmtarget, bm);

    /* Creating tickerData chart lines */
    createIndicatorSeries(highchart, 'Backtest', false);
    var bt = chartData.backtest;
    //console.log(chartData);
    var btarget = highchart.get('Backtest');
    addBacktestDatasetToSeries(btarget, bt);

    /* This line needs to be here for some reason, or else chart won't render properly... */
    createFlagSeries(highchart);

    highchart.hideLoading();
  });
};

$(document).ready(function () {
  $('#hcharts-strategy').highcharts('StockChart', {
    plotOptions: {
      series: {
        dataGrouping: {
          enabled: true,
          groupPixelWidth: 5
        }
      }
    },
    rangeSelector: {
      buttons: [{
        type: 'month',
        count: 1,
        text: '1m'
      }, {
        type: 'month',
        count: 3,
        text: '3m'
      }, {
        type: 'month',
        count: 6,
        text: '6m'
      }, {
        type: 'ytd',
        text: 'YTD'
      }, {
        type: 'year',
        count: 1,
        text: '1y'
      }, {
        type: 'all',
        text: 'All'
      }],
      inputEnabled: false,
      selected: 1
    },

    title: {
      text: 'Moving Avg. Crossover Trades'
    },
    subtitle: {
      text: '+ Indicators (BTC/USD)'
    },
    xAxis: {
      type: 'datetime',
      ordinal: false
    },
    // yAxis:
    //   [{
    //     title: {
    //       text: 'Ticker',
    //     },
    //     opposite: false
    //   }
    // ],
    chart: {
      events: {
        load: function () {
          var self = this;
          // loadStrategyTrades(self);
        }
      },
    },
    series: []
  });

  $('#hcharts-portfolio').highcharts('StockChart', {
    plotOptions: {
      series: {
        dataGrouping: {
          enabled: true,
          groupPixelWidth: 4
        }
      }
    },
    rangeSelector: {
      buttons: [{
        type: 'month',
        count: 1,
        text: '1m'
      }, {
        type: 'month',
        count: 3,
        text: '3m'
      }, {
        type: 'month',
        count: 6,
        text: '6m'
      }, {
        type: 'ytd',
        text: 'YTD'
      }, {
        type: 'year',
        count: 1,
        text: '1y'
      }, {
        type: 'all',
        text: 'All'
      }],
      inputEnabled: false,
      selected: 1
    },

    title: {
      text: 'Portfolio Performance'
    },
    subtitle: {
      text: 'Moving Average Crossover Strategy'
    },
    xAxis: {
      type: 'datetime',
      ordinal: false
    },
    // yAxis:
    //   [{
    //     title: {
    //       text: 'Value',
    //     },
    //     opposite: false
    //   }
    // ],
    chart: {
      events: {
        load: function () {
          var self = this;
          loadPortfolioPerformance(self);
        }
      },
    },
    series: []
  });
});
<commit_msg>socket now connects to URL of page<commit_after>/**
 * Adds a date and price as a tuple to a targetSeries
 * @param {HighChart.series} targetSeries reference
 * @param {int} date UTC formatted time
 * @param {int} price currency price
 */
var addDataPointToSeries = function (targetSeries, date, price) {
  targetSeries.addPoint([date, price], false);
};

// Adds a live data point to a series, differs from "addDataPointToSeries"
//    because it defaults to true for redrawing the chart, hence a "live"
//    addPoint functionality
var addLiveDataPointToSeries = function (targetSeries, date, price) {
  targetSeries.addPoint([date, price], true);
};

/**
 * Adds data points to a certain series, given a data set (chartData)
 * @param {HighChart.series} targetSeries reference
 * @param {object} chartData
 */
var addTickerDatasetToSeries = function (targetSeries, tickerData) {
  for (var i = 0; i < tickerData.length; i++) {
    var date = tickerData[i].date * 1000;
    var price = tickerData[i].close;
    console.log('adding point...');
    addDataPointToSeries(targetSeries, date, price);
  }
};

/**
 * Adds data points to a certain series, given a data set (chartData)
 * @param {HighChart.series} targetSeries reference
 * @param {object} chartData
 */
var addBacktestDatasetToSeries = function (targetSeries, tickerData) {
  for (var i = 0; i < tickerData.length; i++) {
    var date = tickerData[i][0] * 1000;
    var price = tickerData[i][1];
    console.log('backtest: adding point...');
    addDataPointToSeries(targetSeries, date, price);
  }
};

/**
 * Adds data points to a certain series, given a data set (chartData)
 * @param {HighChart.series} targetSeries reference
 * @param {object} chartData
 */
var addBenchMarkDatasetToSeries = function (targetSeries, tickerData) {
  for (var i = 0; i < tickerData.length; i++) {
    var date = tickerData[i][0] * 1000;
    var price = tickerData[i][1];
    console.log('benchmark: adding point...');
    addDataPointToSeries(targetSeries, date, price);
  }
};

/**
 * Adds data points to a certain series, given a data set (chartData)
 * @param {HighChart.series} targetSeries reference
 * @param {array[][]} chartData
 */
var addIndicatorDatasetToSeries = function (targetSeries, chartData) {
  for (var i = 0; i < chartData.length; i++) {
    var date = chartData[i][0] * 1000;
    var price = chartData[i][1];
    //console.log('date:', date, 'price:', price);
    addDataPointToSeries(targetSeries, date, price);
  }
};

/**
 * Creates object literal, given paramaters, and adds it to highchart
 * @param {HighChart} highchart self reference
 * @param {object} params parameters to add to series
 */
var createCandlestickSeries = function (highchart, name) {
  var seriesObj = {};
  seriesObj.name = name;
  seriesObj.id = name;
  seriesObj.data = [];
  seriesObj.marker = {
    enabled: true,
    radius: 2
  };
  seriesObj.tooltip = {
    valueDecimals: 5
  };
  highchart.addSeries(seriesObj, true);
};

/**
 * Creates object literal, given paramaters, and adds it to highchart
 * @param {HighChart} highchart self reference
 * @param {object} params parameters to add to series
 */
var createIndicatorSeries = function (highchart, name, spline) {
  var seriesObj = {};
  seriesObj.name = name;
  seriesObj.id = name;
  seriesObj.data = [];
  seriesObj.marker = {
    enabled: false,
    radius: 3
  };
  if (spline == true) {
    seriesObj.type = 'spline';
  }
  seriesObj.tooltip = {
    valueDecimals: 5
  };
  highchart.addSeries(seriesObj, true);
};

var createFlagSeries = function (highchart) {
  var seriesObj = {};
  seriesObj.id = 'flags';
  seriesObj.type = 'flags';
  seriesObj.data = [];
  seriesObj.onSeries = 'Closing Price';
  seriesObj.shape = 'circlepin';
  seriesObj.width = 20;

  highchart.addSeries(seriesObj);
};

/**
 * Every flag consists of x, title and text. The attribute "x" must be set to
 * the point where the flag should appear. The attribute "title" is the text
 * which is displayed inside the flag on the chart. The attribute "text" contains
 * the text which will appear when the mouse hover above the flag.
 */
var addFlagToSeries = function (highchart, timeStamp, order) {
  var flagObj = {};
  console.log('inside addFlagToSeries:', timeStamp, order);
  flagObj.x = timeStamp;
  flagObj.title = order;
  flagObj.text = 'Make a trade here.';

  highchart.get('flags').addPoint(flagObj);
};

/**
 * Connects and listens on two sockets to initialize and then update a chart.
 *     initializedChartData creates a series and adds historical data to it.
 *     updatedChartData listens for live data and adds it to a targetSeries
 * @param {HighChart} highchart self reference
 */
var loadStrategyTrades = function (highchart) {

  var socket = io.connect(window.location.href);

  highchart.showLoading('');

  // INITALIZE CHART WITH HISTORICAL DATA
  socket.on('initializedChartData', function (chartData) {

    console.log('### initializedChartData received...');
    console.log('### creating series...');

    console.log(Object.keys(chartData));

    createCandlestickSeries(highchart, 'Closing Price');
    createIndicatorSeries(highchart, '10-Day Moving Average');
    createIndicatorSeries(highchart, '20-Day Moving Average');

    /* Creating tickerData chart lines */
    var tickerData = chartData.tickerData;
    // console.log(tickerData);
    var targetSeries = highchart.get("Closing Price");
    addTickerDatasetToSeries(targetSeries, tickerData);
    //
    // /* Adding indicators */
    var SMA_A = chartData.indicators[0];
    var targetSMA10 = highchart.get('10-Day Moving Average');
    console.log('### adding SMA10 to chart');
    addIndicatorDatasetToSeries(targetSMA10, SMA_A);

    var SMA_B = chartData.indicators[1];
    var targetSMA20 = highchart.get('20-Day Moving Average');
    console.log('### adding SMA20 to chart');
    addIndicatorDatasetToSeries(targetSMA20, SMA_B);

    // /* Adding order flags */
    createFlagSeries(highchart);
    for (var i = 0; i < chartData.flags.length; i++) {
      console.log('flag added');
      var timeStamp = chartData.flags[i].timestamp * 1000;
      var orderLongShort = chartData.flags[i].longShort;
      addFlagToSeries(highchart, timeStamp, orderLongShort);
    }

    highchart.hideLoading();

  });

  // UPDATE CHART WITH LIVE DATA
  socket.on('updatedChartData', function (chartData) {
    console.log("### CLIENT: Live Data Point Received");
    var date = chartData.time;
    var price = parseFloat(chartData.mostRecentTickerPrice);
    var targetSeries = highchart.get('Closing Price');
    addLiveDataPointToSeries(targetSeries, date, price);
  });
};

/**
 * Connects and listens on two sockets to initialize and then update a chart.
 *     initializedChartData creates a series and adds historical data to it.
 *     updatedChartData listens for live data and adds it to a targetSeries
 * @param {HighChart} highchart self reference
 */
var loadPortfolioPerformance = function (highchart) {

  var socket = io.connect(window.location.href);

  highchart.showLoading('');

  // INITALIZE CHART WITH HISTORICAL DATA
  socket.on('backtest', function (chartData) {
    console.log(socket);
    console.log(socket.connected);
    console.log(socket.disconnected);    console.log('### <Backtest> received...');
    console.log(Object.keys(chartData));

    /* Creating tickerData benchmark chart lines */
    createIndicatorSeries(highchart, 'Benchmark', false);
    var bm = chartData.benchmark;
    var bmtarget = highchart.get('Benchmark');
    addBenchMarkDatasetToSeries(bmtarget, bm);

    /* Creating tickerData chart lines */
    createIndicatorSeries(highchart, 'Backtest', false);
    var bt = chartData.backtest;
    //console.log(chartData);
    var btarget = highchart.get('Backtest');
    addBacktestDatasetToSeries(btarget, bt);

    /* This line needs to be here for some reason, or else chart won't render properly... */
    createFlagSeries(highchart);

    highchart.hideLoading();
  });
};

$(document).ready(function () {
  $('#hcharts-strategy').highcharts('StockChart', {
    plotOptions: {
      series: {
        dataGrouping: {
          enabled: true,
          groupPixelWidth: 5
        }
      }
    },
    rangeSelector: {
      buttons: [{
        type: 'month',
        count: 1,
        text: '1m'
      }, {
        type: 'month',
        count: 3,
        text: '3m'
      }, {
        type: 'month',
        count: 6,
        text: '6m'
      }, {
        type: 'ytd',
        text: 'YTD'
      }, {
        type: 'year',
        count: 1,
        text: '1y'
      }, {
        type: 'all',
        text: 'All'
      }],
      inputEnabled: false,
      selected: 1
    },

    title: {
      text: 'Moving Avg. Crossover Trades'
    },
    subtitle: {
      text: '+ Indicators (BTC/USD)'
    },
    xAxis: {
      type: 'datetime',
      ordinal: false
    },
    // yAxis:
    //   [{
    //     title: {
    //       text: 'Ticker',
    //     },
    //     opposite: false
    //   }
    // ],
    chart: {
      events: {
        load: function () {
          var self = this;
          loadStrategyTrades(self);
        }
      },
    },
    series: []
  });

  $('#hcharts-portfolio').highcharts('StockChart', {
    plotOptions: {
      series: {
        dataGrouping: {
          enabled: true,
          groupPixelWidth: 4
        }
      }
    },
    rangeSelector: {
      buttons: [{
        type: 'month',
        count: 1,
        text: '1m'
      }, {
        type: 'month',
        count: 3,
        text: '3m'
      }, {
        type: 'month',
        count: 6,
        text: '6m'
      }, {
        type: 'ytd',
        text: 'YTD'
      }, {
        type: 'year',
        count: 1,
        text: '1y'
      }, {
        type: 'all',
        text: 'All'
      }],
      inputEnabled: false,
      selected: 1
    },

    title: {
      text: 'Portfolio Performance'
    },
    subtitle: {
      text: 'Moving Average Crossover Strategy'
    },
    xAxis: {
      type: 'datetime',
      ordinal: false
    },
    // yAxis:
    //   [{
    //     title: {
    //       text: 'Value',
    //     },
    //     opposite: false
    //   }
    // ],
    chart: {
      events: {
        load: function () {
          var self = this;
          loadPortfolioPerformance(self);
        }
      },
    },
    series: []
  });
});
<|endoftext|>


<commit_before>/**
 * Main ui constructor
 *
 * @contructor
 *
 */
MartIrcUi = function() {
    if (! (this instanceof arguments.callee)) {
        return new arguments.callee(arguments);
    }

    var self = this;

    self.ircConnection = null;

    self.init();
    self.bindEvents();
};

/**
 * MartIrcUi init
 *
 */
MartIrcUi.prototype.init = function() {
    var self = this;
};

MartIrcUi.prototype.bindEvents = function() {
    var self = this;

    $('#connectButton').click(function() {
        self.connect();
    });

    $('#prompt form').submit(function(event) {
        event.preventDefault();

        self.parseOutgoingMessage();
    });

    $('#chat .current-title img').live('click', function(event) {
        self.removeChat();
    });

    $('#channels a.channel').live('click', function(event) {
        self.focusOnPublicChat($(this));
    });

    $('#channels a.user, #users .list.active a').live('click', function(event) {
        self.focusOnPrivateChat($(this));
    });

    $('#channels a.server').live('click', function(event) {
        self.focusOnServer();
    });

    $('#prompt form input').focus();
};

MartIrcUi.prototype.connect = function() {
    var self = this;

    if (self.ircConnection && self.ircConnection.connected()) {
        self.ircConnection.disconnect();

        self.ircConnection = null;
    }

    self.ircConnection = new IrcConnection({
        nodeServerHost: $('#nodeServerHost').val(),
        nodeServerPort: parseInt($('#nodeServerPort').val()),
        ircServerHost: $('#ircServerHost').val(),
        ircServerPort: parseInt($('#ircServerPort').val()),
        nickname: $('#nickname').val()
    });

    $(self.ircConnection).bind('irc.server', function(event, data) {
        $(self).trigger('irc.server', data);

        self.displayServerMessage(data.raw);

        self.parseIncomingMessage(data);
    });

};

MartIrcUi.prototype.displayServerMessage = function(rawMsg) {
    var self = this;

    var msg = $('').addClass('msg');
    msg.append($('').addClass('server-msg').text('Server : '));
    msg.append($('').addClass('txt').text(rawMsg));

    $("#chat .server").append(msg);

    self.focusOnPrompt();
};

MartIrcUi.prototype.scanMessage = function(rawMsg) {
    var self = this;

    var msg = self.escape(rawMsg);

    var regex = /\b(?:(?:https?|ftp|file):\/\/|www\.|ftp\.)[-A-Z0-9+&@#\/%=~_|$?!:,.]*[A-Z0-9+&@#\/%=~_|$]/i;

    return msg.replace(regex, " $& ");
};

MartIrcUi.prototype.parseIncomingMessage = function(data) {
    var self = this;

    switch (data.command) {
    case 'privmsg':
	self.receiveMessage(data.params[0], data.person.nick, data.params[1]);
	break;
    case 'join':
	    if(data.person.nick != self.ircConnection.settings.nickname){
		self.addUserToChannel(data.params[0], data.person.nick);
	    }
	break;
    case 'part':
	self.removeUserFromChannel(data.params[0], data.person.nick);
	break;
    case '353':
        var users = data.params[3].split(' ');
        for (i in users) {
            self.addUserToChannel(data.params[2], users[i]);
        }
        break;
    }
};

MartIrcUi.prototype.parseOutgoingMessage = function() {
    var self = this;

    var extractCommand = new RegExp("^:(\\w)(?: ([\\S]+))*", "");

    var rawMsg = $('#prompt form input').val();

    $('#prompt form input').val('');

    var matches = rawMsg.match(extractCommand);

    if (!matches) {
        self.sendMessage(rawMsg);

        return;
    }

    switch (matches[1]) {
    case 'c':
        self.connect();
        break;
    case 'j':
        self.ircConnection.join(matches[2]);

        if (matches[2][0] === '#') {

            var id = $('#channels a:contains("' + matches[2] + '")').attr('id');

            if (!id) {
                id = self.createPublicChat(matches[2]);
            }

            self.focusOnPublicChat($('#channels a#' + id));
        } else {
            var id = $('#channels a:contains("' + matches[2] + '")').attr('id');

            if (!id) {
                id = self.createPrivateChat(matches[2]);
            }

            self.displayUsersTab(false);
            self.focusOnPrivateChat($('#channels a#' + id));
        }

        break;
    case 'k':
        if ($('#channels .active').attr('id') !== 'server') {
            self.removeChat();
        }

        break;
    }
};

MartIrcUi.prototype.receiveMessage = function(chat, nickname, rawMsg) {
    var self = this;

    if(chat === self.ircConnection.settings.nickname){
	chat = nickname;
    }

    var id = $('#channels a:contains("'+chat+'")').attr('id');
    var userClass = $('#users .'+id+' a:contains("'+nickname+'")').attr('class');

    var msg = $('').addClass('msg');
    msg.append($('').addClass(userClass+" nick").text(nickname +' : ').css('color', $('#users .'+id+' .'+userClass).css('color')));
    msg.append($('').addClass('txt').append(self.scanMessage(rawMsg)));

    if (!id) {
        id = self.createPrivateChat(chat);

        self.displayUsersTab(false);
        self.focusOnPrivateChat($('#channels a#' + id));
    }

    $('#chat .' + id).append(msg);

    self.focusOnPrompt();
};

MartIrcUi.prototype.sendMessage = function(rawMsg) {
    var self = this;

    var msg = $('').addClass('msg');

    if ($('#chat .active').hasClass('server')) {
        msg.append($('').addClass("command").text('Command : '));
        msg.append($('').addClass('txt').text(rawMsg));
        self.ircConnection.sendMessage(rawMsg);
    } else {
        msg.append($('').addClass("current-user nick").text(self.ircConnection.settings.nickname + ' : '));
        msg.append($('').addClass('txt').append(self.scanMessage(rawMsg)));
        self.ircConnection.privmsg($('#channels .active').text(), rawMsg);
    }

    $('#chat .active').append(msg);

    self.focusOnPrompt();
};

MartIrcUi.prototype.createPublicChat = function(name) {
    var self = this;

    var id = 'channel-' + new Date().getTime();

    $('#channels').append($('').attr('id', id).addClass('channel').text(name));
    $('#chat').append($('
').addClass(id));
    $("#users").append($('
').addClass('list ' + id));

    return id;
};

MartIrcUi.prototype.createPrivateChat = function(name) {
    var self = this;

    var id = 'user-' + new Date().getTime();

    $('#channels').append($('').attr('id', id).addClass('user').text(name));
    $('#chat').append($('
').addClass(id));

    return id;
};

MartIrcUi.prototype.addUserToChannel = function(channel, name) {
    var self = this;

    var id = $('#channels a:contains("'+channel+'")').attr('id');

    var userClass = 'channelUser-'+new Date().getTime();

    $('#users .'+id).append($('').addClass(userClass).text(name));

    $('.'+userClass).css('color', 'rgb('+Math.floor((Math.random()*255))+','+Math.floor((Math.random()*255))+','+Math.floor((Math.random()*255))+')');
};

MartIrcUi.prototype.removeUserFromChannel = function(channel, name) {
    var self = this;

    var id = $('#channels a:contains("'+channel+'")').attr('id');

    $('#users .'+id+' a:contains("'+name+'")').remove();
};

MartIrcUi.prototype.focusOnPrompt = function() {
    var self = this;

    $("#chat .active").attr({
        scrollTop: $("#chat .active").attr("scrollHeight")
    });

    $('#prompt form input').focus();
};

MartIrcUi.prototype.focusOnServer = function() {
    var self = this;

    self.changeActiveChat('server', 'Server');

    self.displayUsersTab(false);
    self.displayCloseIcon(false);

    var chatToEnable = $('#chat .server').addClass('active');
    chatToEnable.show();

    self.focusOnPrompt();
};

MartIrcUi.prototype.focusOnPrivateChat = function(channel) {
    var self = this;
    var id;

    if (channel.attr('id')) {
        id = channel.attr('id');
    } else {
        id = channel.attr('class');
    }

    self.changeActiveChat(id, 'Private : ' + channel.text());

    self.displayUsersTab(false);
    self.displayCloseIcon(true);

    if (!$('#channels a#' + id).get(0)) {
        var user = $('').attr('id', id).attr('class', 'user').text(channel.text());
        $('#channels').append(user);

        var userChat = $('
').attr('class', id);
        $('#chat').append(userChat);
    }

    var chatTitle = 'Private : ' + channel.text();

    var chatToEnable = $('#chat .' + id).addClass('active');
    chatToEnable.show();

    self.focusOnPrompt();
};

MartIrcUi.prototype.focusOnPublicChat = function(channel) {
    var self = this;
    var id = channel.attr('id');

    self.changeActiveChat(id, 'Public : ' + channel.text());

    self.displayUsersTab(true);
    self.displayCloseIcon(true);

    var chatTitle = 'Public : ' + channel.text();

    var chatAndUsersToEnable = $('#chat .' + id + ', #users .list.' + id).addClass('active');
    chatAndUsersToEnable.show();

    self.focusOnPrompt();
};

MartIrcUi.prototype.changeActiveChat = function(id, chatTitle) {
    var self = this;

    var channelToDisable = $('#channels .active');
    var chatAndUsersToDisable = $('#chat .active, #users .list.active');

    chatAndUsersToDisable.hide();
    channelToDisable.removeClass('active');
    chatAndUsersToDisable.removeClass('active');

    $("#chat .current-title span").text(chatTitle);

    $('#' + id).addClass('active');
};

MartIrcUi.prototype.removeChat = function() {
    var self = this;

    var id = $('#channels .active').attr('id');
    var name = $('#channels .active').text();

    if (name[0] === '#') {
        self.ircConnection.part(name);
    }

    $('#channels  #' + id + ', #chat .' + id).remove();

    if ($('#channels .active').hasClass('channel')) {
        $('#users .' + id).remove();
    }

    var lastChannel = $('#channels a').last();

    if (lastChannel.hasClass('channel')) {
        self.focusOnPublicChat(lastChannel);
    } else if (lastChannel.hasClass('user')) {
        self.focusOnPrivateChat(lastChannel);
    } else {
        self.focusOnServer();
    }
};

MartIrcUi.prototype.displayUsersTab = function(display) {
    var self = this;

    if (display) {
        $('#chat, #prompt').removeClass('span-19');
        $('#chat, #prompt').addClass('span-16');
        $('#prompt').removeClass('append-1');
        $('#prompt').addClass('append-4');
        $('#prompt .text').addClass('span-14');
        $('#prompt .text').removeClass('span-17');
        $('#users').removeClass('last');
        $('#chat').addClass('last');
        $('#users').show();
    } else {
        $('#chat, #prompt').removeClass('span-16');
        $('#chat, #prompt').addClass('span-19');
        $('#prompt').removeClass('append-4');
        $('#prompt').addClass('append-1');
        $('#prompt .text').removeClass('span-14');
        $('#prompt .text').addClass('span-17');
        $('#users').addClass('last');
        $('#chat').removeClass('last');
        $('#users').hide();
    }
};

MartIrcUi.prototype.displayCloseIcon = function(display) {
    var self = this;

    if (display) {
        $('#chat .current-title img').css('visibility', 'visible');
    } else {
        $('#chat .current-title img').css('visibility', 'hidden');
    }
};

/**
 * Converts HTML to safe text
 */
MartIrcUi.prototype.escape = function(html) {
    return $('
').text(html).html();
};
<commit_msg>Remove own nickname from channel user list<commit_after>/**
 * Main ui constructor
 *
 * @contructor
 *
 */
MartIrcUi = function() {
    if (! (this instanceof arguments.callee)) {
        return new arguments.callee(arguments);
    }

    var self = this;

    self.ircConnection = null;

    self.init();
    self.bindEvents();
};

/**
 * MartIrcUi init
 *
 */
MartIrcUi.prototype.init = function() {
    var self = this;
};

MartIrcUi.prototype.bindEvents = function() {
    var self = this;

    $('#connectButton').click(function() {
        self.connect();
    });

    $('#prompt form').submit(function(event) {
        event.preventDefault();

        self.parseOutgoingMessage();
    });

    $('#chat .current-title img').live('click', function(event) {
        self.removeChat();
    });

    $('#channels a.channel').live('click', function(event) {
        self.focusOnPublicChat($(this));
    });

    $('#channels a.user, #users .list.active a').live('click', function(event) {
        self.focusOnPrivateChat($(this));
    });

    $('#channels a.server').live('click', function(event) {
        self.focusOnServer();
    });

    $('#prompt form input').focus();
};

MartIrcUi.prototype.connect = function() {
    var self = this;

    if (self.ircConnection && self.ircConnection.connected()) {
        self.ircConnection.disconnect();

        self.ircConnection = null;
    }

    self.ircConnection = new IrcConnection({
        nodeServerHost: $('#nodeServerHost').val(),
        nodeServerPort: parseInt($('#nodeServerPort').val()),
        ircServerHost: $('#ircServerHost').val(),
        ircServerPort: parseInt($('#ircServerPort').val()),
        nickname: $('#nickname').val()
    });

    $(self.ircConnection).bind('irc.server', function(event, data) {
        $(self).trigger('irc.server', data);

        self.displayServerMessage(data.raw);

        self.parseIncomingMessage(data);
    });

};

MartIrcUi.prototype.displayServerMessage = function(rawMsg) {
    var self = this;

    var msg = $('').addClass('msg');
    msg.append($('').addClass('server-msg').text('Server : '));
    msg.append($('').addClass('txt').text(rawMsg));

    $("#chat .server").append(msg);

    self.focusOnPrompt();
};

MartIrcUi.prototype.scanMessage = function(rawMsg) {
    var self = this;

    var msg = self.escape(rawMsg);

    var regex = /\b(?:(?:https?|ftp|file):\/\/|www\.|ftp\.)[-A-Z0-9+&@#\/%=~_|$?!:,.]*[A-Z0-9+&@#\/%=~_|$]/i;

    return msg.replace(regex, " $& ");
};

MartIrcUi.prototype.parseIncomingMessage = function(data) {
    var self = this;

    switch (data.command) {
    case 'privmsg':
	self.receiveMessage(data.params[0], data.person.nick, data.params[1]);
	break;
    case 'join':
	    if(data.person.nick != self.ircConnection.settings.nickname){
		self.addUserToChannel(data.params[0], data.person.nick);
	    }
	break;
    case 'part':
	self.removeUserFromChannel(data.params[0], data.person.nick);
	break;
    case '353':
        var users = data.params[3].split(' ');
        for (i in users) {
	    if(users[i] != self.ircConnection.settings.nickname){
		self.addUserToChannel(data.params[2], users[i]);
	    }
        }
        break;
    }
};

MartIrcUi.prototype.parseOutgoingMessage = function() {
    var self = this;

    var extractCommand = new RegExp("^:(\\w)(?: ([\\S]+))*", "");

    var rawMsg = $('#prompt form input').val();

    $('#prompt form input').val('');

    var matches = rawMsg.match(extractCommand);

    if (!matches) {
        self.sendMessage(rawMsg);

        return;
    }

    switch (matches[1]) {
    case 'c':
        self.connect();
        break;
    case 'j':
        self.ircConnection.join(matches[2]);

        if (matches[2][0] === '#') {

            var id = $('#channels a:contains("' + matches[2] + '")').attr('id');

            if (!id) {
                id = self.createPublicChat(matches[2]);
            }

            self.focusOnPublicChat($('#channels a#' + id));
        } else {
            var id = $('#channels a:contains("' + matches[2] + '")').attr('id');

            if (!id) {
                id = self.createPrivateChat(matches[2]);
            }

            self.displayUsersTab(false);
            self.focusOnPrivateChat($('#channels a#' + id));
        }

        break;
    case 'k':
        if ($('#channels .active').attr('id') !== 'server') {
            self.removeChat();
        }

        break;
    }
};

MartIrcUi.prototype.receiveMessage = function(chat, nickname, rawMsg) {
    var self = this;

    if(chat === self.ircConnection.settings.nickname){
	chat = nickname;
    }

    var id = $('#channels a:contains("'+chat+'")').attr('id');
    var userClass = $('#users .'+id+' a:contains("'+nickname+'")').attr('class');

    var msg = $('').addClass('msg');
    msg.append($('').addClass(userClass+" nick").text(nickname +' : ').css('color', $('#users .'+id+' .'+userClass).css('color')));
    msg.append($('').addClass('txt').append(self.scanMessage(rawMsg)));

    if (!id) {
        id = self.createPrivateChat(chat);

        self.displayUsersTab(false);
        self.focusOnPrivateChat($('#channels a#' + id));
    }

    $('#chat .' + id).append(msg);

    self.focusOnPrompt();
};

MartIrcUi.prototype.sendMessage = function(rawMsg) {
    var self = this;

    var msg = $('').addClass('msg');

    if ($('#chat .active').hasClass('server')) {
        msg.append($('').addClass("command").text('Command : '));
        msg.append($('').addClass('txt').text(rawMsg));
        self.ircConnection.sendMessage(rawMsg);
    } else {
        msg.append($('').addClass("current-user nick").text(self.ircConnection.settings.nickname + ' : '));
        msg.append($('').addClass('txt').append(self.scanMessage(rawMsg)));
        self.ircConnection.privmsg($('#channels .active').text(), rawMsg);
    }

    $('#chat .active').append(msg);

    self.focusOnPrompt();
};

MartIrcUi.prototype.createPublicChat = function(name) {
    var self = this;

    var id = 'channel-' + new Date().getTime();

    $('#channels').append($('').attr('id', id).addClass('channel').text(name));
    $('#chat').append($('
').addClass(id));
    $("#users").append($('
').addClass('list ' + id));

    return id;
};

MartIrcUi.prototype.createPrivateChat = function(name) {
    var self = this;

    var id = 'user-' + new Date().getTime();

    $('#channels').append($('').attr('id', id).addClass('user').text(name));
    $('#chat').append($('
').addClass(id));

    return id;
};

MartIrcUi.prototype.addUserToChannel = function(channel, name) {
    var self = this;

    var id = $('#channels a:contains("'+channel+'")').attr('id');

    var userClass = 'channelUser-'+new Date().getTime();

    $('#users .'+id).append($('').addClass(userClass).text(name));

    $('.'+userClass).css('color', 'rgb('+Math.floor((Math.random()*255))+','+Math.floor((Math.random()*255))+','+Math.floor((Math.random()*255))+')');
};

MartIrcUi.prototype.removeUserFromChannel = function(channel, name) {
    var self = this;

    var id = $('#channels a:contains("'+channel+'")').attr('id');

    $('#users .'+id+' a:contains("'+name+'")').remove();
};

MartIrcUi.prototype.focusOnPrompt = function() {
    var self = this;

    $("#chat .active").attr({
        scrollTop: $("#chat .active").attr("scrollHeight")
    });

    $('#prompt form input').focus();
};

MartIrcUi.prototype.focusOnServer = function() {
    var self = this;

    self.changeActiveChat('server', 'Server');

    self.displayUsersTab(false);
    self.displayCloseIcon(false);

    var chatToEnable = $('#chat .server').addClass('active');
    chatToEnable.show();

    self.focusOnPrompt();
};

MartIrcUi.prototype.focusOnPrivateChat = function(channel) {
    var self = this;
    var id;

    if (channel.attr('id')) {
        id = channel.attr('id');
    } else {
        id = channel.attr('class');
    }

    self.changeActiveChat(id, 'Private : ' + channel.text());

    self.displayUsersTab(false);
    self.displayCloseIcon(true);

    if (!$('#channels a#' + id).get(0)) {
        var user = $('').attr('id', id).attr('class', 'user').text(channel.text());
        $('#channels').append(user);

        var userChat = $('
').attr('class', id);
        $('#chat').append(userChat);
    }

    var chatTitle = 'Private : ' + channel.text();

    var chatToEnable = $('#chat .' + id).addClass('active');
    chatToEnable.show();

    self.focusOnPrompt();
};

MartIrcUi.prototype.focusOnPublicChat = function(channel) {
    var self = this;
    var id = channel.attr('id');

    self.changeActiveChat(id, 'Public : ' + channel.text());

    self.displayUsersTab(true);
    self.displayCloseIcon(true);

    var chatTitle = 'Public : ' + channel.text();

    var chatAndUsersToEnable = $('#chat .' + id + ', #users .list.' + id).addClass('active');
    chatAndUsersToEnable.show();

    self.focusOnPrompt();
};

MartIrcUi.prototype.changeActiveChat = function(id, chatTitle) {
    var self = this;

    var channelToDisable = $('#channels .active');
    var chatAndUsersToDisable = $('#chat .active, #users .list.active');

    chatAndUsersToDisable.hide();
    channelToDisable.removeClass('active');
    chatAndUsersToDisable.removeClass('active');

    $("#chat .current-title span").text(chatTitle);

    $('#' + id).addClass('active');
};

MartIrcUi.prototype.removeChat = function() {
    var self = this;

    var id = $('#channels .active').attr('id');
    var name = $('#channels .active').text();

    if (name[0] === '#') {
        self.ircConnection.part(name);
    }

    $('#channels  #' + id + ', #chat .' + id).remove();

    if ($('#channels .active').hasClass('channel')) {
        $('#users .' + id).remove();
    }

    var lastChannel = $('#channels a').last();

    if (lastChannel.hasClass('channel')) {
        self.focusOnPublicChat(lastChannel);
    } else if (lastChannel.hasClass('user')) {
        self.focusOnPrivateChat(lastChannel);
    } else {
        self.focusOnServer();
    }
};

MartIrcUi.prototype.displayUsersTab = function(display) {
    var self = this;

    if (display) {
        $('#chat, #prompt').removeClass('span-19');
        $('#chat, #prompt').addClass('span-16');
        $('#prompt').removeClass('append-1');
        $('#prompt').addClass('append-4');
        $('#prompt .text').addClass('span-14');
        $('#prompt .text').removeClass('span-17');
        $('#users').removeClass('last');
        $('#chat').addClass('last');
        $('#users').show();
    } else {
        $('#chat, #prompt').removeClass('span-16');
        $('#chat, #prompt').addClass('span-19');
        $('#prompt').removeClass('append-4');
        $('#prompt').addClass('append-1');
        $('#prompt .text').removeClass('span-14');
        $('#prompt .text').addClass('span-17');
        $('#users').addClass('last');
        $('#chat').removeClass('last');
        $('#users').hide();
    }
};

MartIrcUi.prototype.displayCloseIcon = function(display) {
    var self = this;

    if (display) {
        $('#chat .current-title img').css('visibility', 'visible');
    } else {
        $('#chat .current-title img').css('visibility', 'hidden');
    }
};

/**
 * Converts HTML to safe text
 */
MartIrcUi.prototype.escape = function(html) {
    return $('
').text(html).html();
};
<|endoftext|>


<commit_before>// Import
var BinaryWriter = require("./BinaryWriter");

function UpdateLeaderboard(playerTracker, leaderboard, leaderboardType) {
    this.playerTracker = playerTracker;
    this.leaderboard = leaderboard;
    this.leaderboardType = leaderboardType;
    this.leaderboardCount = Math.min(leaderboard.length, playerTracker.gameServer.config.serverMaxLB);
}
module.exports = UpdateLeaderboard;
UpdateLeaderboard.prototype.build = function(protocol) {
    switch (this.leaderboardType) {
        case 48:
            // UserText
            return this.buildUserText(protocol);
        case 49:
            // FFA
            if (protocol < 6) return this.buildFfa5();
            else if (protocol < 11) return this.buildFfa6();
            //else if (protocol == 11)
            //return this.buildFfa11();
            else return this.buildFfa13();
        case 50:
            // Team
            return this.buildTeam();
        default:
            return null;
    }
}
// UserText
UpdateLeaderboard.prototype.buildUserText = function(protocol) {
    var writer = new BinaryWriter();
    writeCount(writer, 0x31, this.leaderboard.length);
    for (var i = 0; i < this.leaderboard.length; i++) {
        var item = this.leaderboard[i] || "";
        if (protocol < 11) writer.writeUInt32(0);
        if (protocol < 6) writer.writeStringZeroUnicode(item);
        else writer.writeStringZeroUtf8(item);
    }
    return writer.toBuffer();
};
// FFA protocol 5
UpdateLeaderboard.prototype.buildFfa5 = function() {
    var writer = new BinaryWriter();
    writeCount(writer, 0x31, this.leaderboardCount);
    for (var i = 0; i < this.leaderboardCount; i++) {
        var item = this.leaderboard[i];
        if (item == null) return null; // bad leaderboardm just don't send it
        var name = item._nameUnicode;
        var id = 0;
        if (item == this.playerTracker && item.cells.length) id = item.cells[0].nodeId ^ this.playerTracker.scrambleId;
        writer.writeUInt32(id >>> 0); // Player cell Id
        if (name) writer.writeBytes(name);
        else writer.writeUInt16(0);
    }
    return writer.toBuffer();
};
// FFA protocol 6
UpdateLeaderboard.prototype.buildFfa6 = function() {
    var writer = new BinaryWriter();
    writeCount(writer, 0x31, this.leaderboardCount);
    for (var i = 0; i < this.leaderboardCount; i++) {
        var item = this.leaderboard[i];
        if (item == null) return null; // bad leaderboardm just don't send it
        var name = item._nameUtf8;
        var id = item == this.playerTracker ? 1 : 0;
        writer.writeUInt32(id >>> 0); // isMe flag
        if (name) writer.writeBytes(name);
        else writer.writeUInt8(0);
    }
    return writer.toBuffer();
};
// FFA protocol 11
UpdateLeaderboard.prototype.buildFfa11 = function() {
    var pos = require('./LeaderboardPosition');
    this.playerTracker.socket.packetHandler.sendPacket(new pos(this.leaderboard.indexOf(this.playerTracker) + 1));
    var writer = new BinaryWriter();
    writeCount(writer, 0x31, this.leaderboardCount);
    for (var i = 0; i < this.leaderboardCount; i++) {
        var item = this.leaderboard[i];
        if (item == null) return null; // bad leaderboardm just don't send it
        var name = item._nameUtf8;
        if (name) writer.writeBytes(name);
        else writer.writeUInt8(0);
    }
    return writer.toBuffer();
};
// FFA protocol 13
UpdateLeaderboard.prototype.buildFfa13 = function() {
    var writer = new BinaryWriter();
    writer.writeUInt8(0x33); // Packet ID
    for (var i = 0; i < this.leaderboardCount; i++) {
        var item = this.leaderboard[i];
        if (item == null) return null; // bad leaderboardm just don't send it
        if (item === this.playerTracker) {
            writer.writeUInt8(0x09);
            writer.writeUInt16(1);
        } else {
            var name = item._name;
            writer.writeUInt8(0x02);
            if (name != null && name.length) writer.writeStringZeroUtf8(name);
            else writer.writeUInt8(0);
        }
    }
    var thing = this.leaderboard.indexOf(this.playerTracker) + 1;
    var place = (thing <= 10) ? null : thing;
    if (this.playerTracker.cells.length && place != null) {
        writer.writeUInt8(0x09);
        writer.writeUInt16(place);
    }
    return writer.toBuffer();
};
// Party
// TODO: Implement the "minimap"
UpdateLeaderboard.prototype.buildParty = function() {
    var protocol13s = 0;
    for (var i in this.playerTracker.gameServer.clients) {
        var client = this.playerTracker.gameServer.clients[i].packetHandler;
        if (client.protocol >= 13) protocol13s++;
    }
    var writer = new BinaryWriter();
    writer.writeUInt8(0x34); // Packet ID
    writer.writeUInt16(protocol13s); // How many friends are in-game
    for (var i = 0; i < this.leaderboardCount; i++) {
        var item = this.leaderboard[i];
        if (item == null) return null; // bad leaderboardm just don't send it
        if (item === this.playerTracker) {
            writer.writeUInt8(0x09);
            writer.writeUInt16(1);
        } else {
            var name = item._name;
            writer.writeUInt8(0x02);
            if (name != null && name.length) writer.writeStringZeroUtf8(name);
            else writer.writeUInt8(0);
        }
    }
    var thing = this.leaderboard.indexOf(this.playerTracker) + 1;
    var place = (thing <= 10) ? null : thing;
    if (this.playerTracker.cells.length && place != null) {
        writer.writeUInt16(place);
    }
    return writer.toBuffer();
};

function writeCount(writer, flag1, flag2) {
    writer.writeUInt8(flag1); // Packet ID
    writer.writeUInt32(flag2 >>> 0); // Number of elements
}
// Team
UpdateLeaderboard.prototype.buildTeam = function() {
    var writer = new BinaryWriter();
    writeCount(writer, 0x32, this.leaderboard.length);
    for (var i = 0; i < this.leaderboard.length; i++) {
        var value = this.leaderboard[i];
        if (value == null) return null; // bad leaderboardm just don't send it
        if (isNaN(value)) value = 0;
        value = value < 0 ? 0 : value;
        value = value > 1 ? 1 : value;
        writer.writeFloat(value); // isMe flag (previously cell ID)
    }
    return writer.toBuffer();
};
<commit_msg>Fixes board command<commit_after>// Import
var BinaryWriter = require("./BinaryWriter");

function UpdateLeaderboard(playerTracker, leaderboard, leaderboardType) {
    this.playerTracker = playerTracker;
    this.leaderboard = leaderboard;
    this.leaderboardType = leaderboardType;
    this.leaderboardCount = Math.min(leaderboard.length, playerTracker.gameServer.config.serverMaxLB);
}
module.exports = UpdateLeaderboard;
UpdateLeaderboard.prototype.build = function(protocol) {
    switch (this.leaderboardType) {
        case 48:
            // UserText
            return protocol < 13 ? this.buildUserText(protocol) : this.buildUserText13();
        case 49:
            // FFA
            if (protocol < 6) return this.buildFfa5();
            else if (protocol < 11) return this.buildFfa6();
            //else if (protocol == 11)
            //return this.buildFfa11();
            else return this.buildFfa13();
        case 50:
            // Team
            return this.buildTeam();
        default:
            return null;
    }
}
// UserText prorocols 5/6/11
UpdateLeaderboard.prototype.buildUserText = function(protocol) {
    var writer = new BinaryWriter();
    writeCount(writer, 0x31, this.leaderboard.length);
    for (var i = 0; i < this.leaderboard.length; i++) {
        var item = this.leaderboard[i] || "";
        if (protocol < 11) writer.writeUInt32(0);
        if (protocol < 6) writer.writeStringZeroUnicode(item);
        else writer.writeStringZeroUtf8(item);
    }
    return writer.toBuffer();
};
// UserText protocol 13
UpdateLeaderboard.prototype.buildUserText13 = function () {
    var writer = new BinaryWriter();
    writer.writeUInt8(0x33);
    for (var i = 0; i < this.leaderboard.length; i++) {
        writer.writeUInt8(0x02);
        writer.writeStringZeroUtf8(this.leaderboard[i]);
    }
    return writer.toBuffer();
};
// FFA protocol 5
UpdateLeaderboard.prototype.buildFfa5 = function() {
    var writer = new BinaryWriter();
    writeCount(writer, 0x31, this.leaderboardCount);
    for (var i = 0; i < this.leaderboardCount; i++) {
        var item = this.leaderboard[i];
        if (item == null) return null; // bad leaderboardm just don't send it
        var name = item._nameUnicode;
        var id = 0;
        if (item == this.playerTracker && item.cells.length) id = item.cells[0].nodeId ^ this.playerTracker.scrambleId;
        writer.writeUInt32(id >>> 0); // Player cell Id
        if (name) writer.writeBytes(name);
        else writer.writeUInt16(0);
    }
    return writer.toBuffer();
};
// FFA protocol 6
UpdateLeaderboard.prototype.buildFfa6 = function() {
    var writer = new BinaryWriter();
    writeCount(writer, 0x31, this.leaderboardCount);
    for (var i = 0; i < this.leaderboardCount; i++) {
        var item = this.leaderboard[i];
        if (item == null) return null; // bad leaderboardm just don't send it
        var name = item._nameUtf8;
        var id = item == this.playerTracker ? 1 : 0;
        writer.writeUInt32(id >>> 0); // isMe flag
        if (name) writer.writeBytes(name);
        else writer.writeUInt8(0);
    }
    return writer.toBuffer();
};
// FFA protocol 11
UpdateLeaderboard.prototype.buildFfa11 = function() {
    var pos = require('./LeaderboardPosition');
    this.playerTracker.socket.packetHandler.sendPacket(new pos(this.leaderboard.indexOf(this.playerTracker) + 1));
    var writer = new BinaryWriter();
    writeCount(writer, 0x31, this.leaderboardCount);
    for (var i = 0; i < this.leaderboardCount; i++) {
        var item = this.leaderboard[i];
        if (item == null) return null; // bad leaderboardm just don't send it
        var name = item._nameUtf8;
        if (name) writer.writeBytes(name);
        else writer.writeUInt8(0);
    }
    return writer.toBuffer();
};
// FFA protocol 13
UpdateLeaderboard.prototype.buildFfa13 = function() {
    var writer = new BinaryWriter();
    writer.writeUInt8(0x33); // Packet ID
    for (var i = 0; i < this.leaderboardCount; i++) {
        var item = this.leaderboard[i];
        if (item == null) return null; // bad leaderboardm just don't send it
        if (item === this.playerTracker) {
            writer.writeUInt8(0x09);
            writer.writeUInt16(1);
        } else {
            var name = item._name;
            writer.writeUInt8(0x02);
            if (name != null && name.length) writer.writeStringZeroUtf8(name);
            else writer.writeUInt8(0);
        }
    }
    var thing = this.leaderboard.indexOf(this.playerTracker) + 1;
    var place = (thing <= 10) ? null : thing;
    if (this.playerTracker.cells.length && place != null) {
        writer.writeUInt8(0x09);
        writer.writeUInt16(place);
    }
    return writer.toBuffer();
};
// Party
// TODO: Implement the "minimap"
UpdateLeaderboard.prototype.buildParty = function() {
    var protocol13s = 0;
    for (var i in this.playerTracker.gameServer.clients) {
        var client = this.playerTracker.gameServer.clients[i].packetHandler;
        if (client.protocol >= 13) protocol13s++;
    }
    var writer = new BinaryWriter();
    writer.writeUInt8(0x34); // Packet ID
    writer.writeUInt16(protocol13s); // How many friends are in-game
    for (var i = 0; i < this.leaderboardCount; i++) {
        var item = this.leaderboard[i];
        if (item == null) return null; // bad leaderboardm just don't send it
        if (item === this.playerTracker) {
            writer.writeUInt8(0x09);
            writer.writeUInt16(1);
        } else {
            var name = item._name;
            writer.writeUInt8(0x02);
            if (name != null && name.length) writer.writeStringZeroUtf8(name);
            else writer.writeUInt8(0);
        }
    }
    var thing = this.leaderboard.indexOf(this.playerTracker) + 1;
    var place = (thing <= 10) ? null : thing;
    if (this.playerTracker.cells.length && place != null) {
        writer.writeUInt16(place);
    }
    return writer.toBuffer();
};

function writeCount(writer, flag1, flag2) {
    writer.writeUInt8(flag1); // Packet ID
    writer.writeUInt32(flag2 >>> 0); // Number of elements
}
// Team
UpdateLeaderboard.prototype.buildTeam = function() {
    var writer = new BinaryWriter();
    writeCount(writer, 0x32, this.leaderboard.length);
    for (var i = 0; i < this.leaderboard.length; i++) {
        var value = this.leaderboard[i];
        if (value == null) return null; // bad leaderboardm just don't send it
        if (isNaN(value)) value = 0;
        value = value < 0 ? 0 : value;
        value = value > 1 ? 1 : value;
        writer.writeFloat(value); // isMe flag (previously cell ID)
    }
    return writer.toBuffer();
};
<|endoftext|>