<commit_before>"use strict";

var $       = require("jquery");
var Plugin  = require("../modules/Plugin");
var Utils   = require("../modules/Utilities");
var youtube = Object.create(Plugin);

youtube.init("youtube", "YouTube");

youtube.test = function () {
    var domainMatch = (/youtube\.[A-Z\.]{2,}\/watch/i).test(document.location.href);
    var playerFound = $("#eow-title").length > 0;
    return domainMatch && playerFound;
};

youtube.scrape = function () {
    var title       = $.trim($("#eow-title").text());
    var parsedTitle = title.replace(/^(.+)\s*[-–:]+\s*(.+)$/, "$1_,_$2").split("_,_");

    if (parsedTitle.length > 1) {
        return cleanseTrack(parsedTitle[0], parsedTitle[1]);
    }

    if (title.indexOf("by") >= 0) {
        parsedTitle = title.replace(/^(.+)\s*by\s*(.+)$/, "$1_,_$2").split("_,_");

        if (parsedTitle.length > 1) {
            return cleanseTrack(parsedTitle[1], parsedTitle[0]);
        }
    }

    if (title.indexOf("\"") >= 0) {
        parsedTitle = title.replace(/^([^"]+)(".+)$/, "$1_,_$2").split("_,_");

        if (parsedTitle.length > 1) {
            return cleanseTrack(parsedTitle[0], parsedTitle[1]);
        }
    }

    return {
        title:    title,
        elapsed:  Utils.calculateDuration($(".ytp-time-current").text()),
        duration: Utils.calculateDuration($(".ytp-time-duration").text()),
        stopped:  $(".ytp-play-button").attr("aria-label").toLowerCase() === "play"
    };
};

/**
 * Cleanse method inspired by the Chrome Last.fm Scrobbler extension
 * by David Sabata (https://github.com/david-sabata/Chrome-Last.fm-Scrobbler)
 *
 * @param {String} artist
 * @param {String} title
 */
function cleanseTrack(artist, title) {
    title = $.trim(title);
    title = title.replace(/\s*\*+\s?\S+\s?\*+$/, ''); // **NEW**
    title = title.replace(/\s*\[[^\]]+\]$/, ''); // [whatever] succeeding title
    title = title.replace(/^\[[^\]]+\]\s*/, ''); // [whatever] preceding title
    title = title.replace(/\s*\([^\)]*version\)$/i, ''); // (whatever version)
    title = title.replace(/\s*\.(avi|wmv|mpg|mpeg|flv)$/i, ''); // video extensions
    title = title.replace(/\s*(of+icial\s*)?(music\s*)?video/i, ''); // (official)? (music)? video
    title = title.replace(/\s*(ALBUM TRACK\s*)?(album track\s*)/i, ''); // (ALBUM TRACK)
    title = title.replace(/\s*\(\s*of+icial\s*\)/i, ''); // (official)
    title = title.replace(/\s*\(\s*[0-9]{4}\s*\)/i, ''); // (1999)
    title = title.replace(/\s+\(\s*(HD|HQ)\s*\)$/, ''); // HD (HQ)
    title = title.replace(/\s+(HD|HQ)\s*$/, ''); // HD (HQ)
    title = title.replace(/\s*video\s*clip/i, ''); // video clip
    title = title.replace(/\s+\(?live\)?$/i, ''); // live
    title = title.replace(/\(\s*\)/, ''); // Leftovers after e.g. (official video)
    title = title.replace(/\(.*lyrics?\)/i, ''); // (with lyrics)
    title = title.replace(/\s*(with\s+)?lyrics?\s*$/i, ''); // (with)? lyrics
    title = title.replace(/^(|.*\s)"(.*)"(\s.*|)$/, '$2'); // Artist - The new "Track title" featuring someone
    title = title.replace(/^(|.*\s)'(.*)'(\s.*|)$/, '$2'); // 'Track title'
    title = title.replace(/^[\/\s,:;~-\s"]+/, ''); // trim starting white chars and dash
    title = title.replace(/[\/\s,:;~-\s"\s!]+$/, ''); // trim trailing white chars and dash

    return {
        artist:   artist,
        title:    title,
        elapsed:  Utils.calculateDuration($(".ytp-time-current").text()),
        duration: Utils.calculateDuration($(".ytp-time-duration").text()),
        stopped:  $(".ytp-play-button").attr("aria-label").toLowerCase() === "play"
    };
}

module.exports = youtube;
<commit_msg>Fixed youtube scroblling for non-english browsers language fix for #111<commit_after>"use strict";

var $       = require("jquery");
var Plugin  = require("../modules/Plugin");
var Utils   = require("../modules/Utilities");
var youtube = Object.create(Plugin);

youtube.init("youtube", "YouTube");

youtube.test = function () {
    var domainMatch = (/youtube\.[A-Z\.]{2,}\/watch/i).test(document.location.href);
    var playerFound = $("#eow-title").length > 0;
    return domainMatch && playerFound;
};

youtube.scrape = function () {
    var title       = $.trim($("#eow-title").text());
    var parsedTitle = title.replace(/^(.+)\s*[-–:]+\s*(.+)$/, "$1_,_$2").split("_,_");

    if (parsedTitle.length > 1) {
        return cleanseTrack(parsedTitle[0], parsedTitle[1]);
    }

    if (title.indexOf("by") >= 0) {
        parsedTitle = title.replace(/^(.+)\s*by\s*(.+)$/, "$1_,_$2").split("_,_");

        if (parsedTitle.length > 1) {
            return cleanseTrack(parsedTitle[1], parsedTitle[0]);
        }
    }

    if (title.indexOf("\"") >= 0) {
        parsedTitle = title.replace(/^([^"]+)(".+)$/, "$1_,_$2").split("_,_");

        if (parsedTitle.length > 1) {
            return cleanseTrack(parsedTitle[0], parsedTitle[1]);
        }
    }

    return {
        title:    title,
        elapsed:  Utils.calculateDuration($(".ytp-time-current").text()),
        duration: Utils.calculateDuration($(".ytp-time-duration").text()),
        stopped:  $(".ytp-play-button").attr("aria-label").toLowerCase() === "play"
    };
};

/**
 * Cleanse method inspired by the Chrome Last.fm Scrobbler extension
 * by David Sabata (https://github.com/david-sabata/Chrome-Last.fm-Scrobbler)
 *
 * @param {String} artist
 * @param {String} title
 */
function cleanseTrack(artist, title) {
    title = $.trim(title);
    title = title.replace(/\s*\*+\s?\S+\s?\*+$/, ''); // **NEW**
    title = title.replace(/\s*\[[^\]]+\]$/, ''); // [whatever] succeeding title
    title = title.replace(/^\[[^\]]+\]\s*/, ''); // [whatever] preceding title
    title = title.replace(/\s*\([^\)]*version\)$/i, ''); // (whatever version)
    title = title.replace(/\s*\.(avi|wmv|mpg|mpeg|flv)$/i, ''); // video extensions
    title = title.replace(/\s*(of+icial\s*)?(music\s*)?video/i, ''); // (official)? (music)? video
    title = title.replace(/\s*(ALBUM TRACK\s*)?(album track\s*)/i, ''); // (ALBUM TRACK)
    title = title.replace(/\s*\(\s*of+icial\s*\)/i, ''); // (official)
    title = title.replace(/\s*\(\s*[0-9]{4}\s*\)/i, ''); // (1999)
    title = title.replace(/\s+\(\s*(HD|HQ)\s*\)$/, ''); // HD (HQ)
    title = title.replace(/\s+(HD|HQ)\s*$/, ''); // HD (HQ)
    title = title.replace(/\s*video\s*clip/i, ''); // video clip
    title = title.replace(/\s+\(?live\)?$/i, ''); // live
    title = title.replace(/\(\s*\)/, ''); // Leftovers after e.g. (official video)
    title = title.replace(/\(.*lyrics?\)/i, ''); // (with lyrics)
    title = title.replace(/\s*(with\s+)?lyrics?\s*$/i, ''); // (with)? lyrics
    title = title.replace(/^(|.*\s)"(.*)"(\s.*|)$/, '$2'); // Artist - The new "Track title" featuring someone
    title = title.replace(/^(|.*\s)'(.*)'(\s.*|)$/, '$2'); // 'Track title'
    title = title.replace(/^[\/\s,:;~-\s"]+/, ''); // trim starting white chars and dash
    title = title.replace(/[\/\s,:;~-\s"\s!]+$/, ''); // trim trailing white chars and dash

    return {
        artist:   artist,
        title:    title,
        elapsed:  Utils.calculateDuration($(".ytp-time-current").text()),
        duration: Utils.calculateDuration($(".ytp-time-duration").text()),
        stopped:  $(".html5-video-player").hasClass("ended-mode")
    };
}

module.exports = youtube;
<|endoftext|>


<commit_before>'use strict';

/**
takes in string value from move command from message,
converts it to value that can be used for accessing
the board array
**/
function getCoord(val){
	const convert = {
		"a": 0, "b": 1, "c": 2, "d": 3, "e": 4, "f": 5, "g": 6, "h": 7,
		"8": 0, "7": 1, "6": 2, "5": 3, "4": 4, "3": 5, "2": 6, "1": 7
	};

	//check for bad coords
	// tolowercase will not do anything to numbers
	if(convert[val.toLowerCase()] !== undefined){
		return convert[val];
	}else{
		throw new Error('invalid string to convert to coordinate');
	}
}

/*return the first letter of the unit on that board coord
i.e. the color of the piece*/
function getColor(x, y, board){
	if(x > 7 || x < 0 || y > 7 || y < 0){
		throw new Error('trying to get color of something out of bounds');
	}else{
		return board[y][x].charAt(0);
	}
}

function getPiece(x, y, board){
	if(x > 7 || x < 0 || y > 7 || y < 0){
		throw new Error('trying to get piece type of something out of bounds');
	}else{
		return board[y][x].charAt(1);
	}
}

function isInBoard(coord){
	return (coord > 0 && coord < 7) ? true : false;
}

function nothingBetweenDiag(startX, startY, destX, destY, board){
	var upperBoundX;
	var lowerBoundX;
	var lowerBoundY;
	/*don't need to do upperBoundY because we
	use upperBoundX to get the number of spaces that the bishop
	moves vertically*/
	if(destX > startX){
		upperBoundX = destX;
		lowerBoundX = startX;
	}else{
		upperBoundX = startX;
		lowerBoundX = destX;
	}

	if(destY > startY){
		lowerBoundY = startY;
	}else{
		lowerBoundY = destY;
	}

	//chose upperBoundX and lowerBoundX because only displacement amount matters
	//completely arbitrary, could use the other too
	for(var i = 1; i < upperBoundX - lowerBoundX - 1; i++){
		if(board[lowerBoundY + i][lowerBoundX + i]){
			return false;
		}
	}
	return true;
}

function nothingBetweenLateral(start, startX, startY, dest, board, isVertical){
	//check that nothing is inbetween
	var upperBound;
	var lowerBound;
	if(dest > start){
		upperBound = dest;
		lowerBound = start;
	}else{
		upperBound = start;
		lowerBound = dest;
	}

	/* since rook can't jump over piece, return false if trying that
	   lowerBound + 1 since its not looking at either end points
	*/
	for(var i = 1; i < upperBound - lowerBound - 1; i++){
		if((isVertical && (board[lowerBound + i][startX] === 0))
		||(!isVertical && (board[startY][lowerBound + i] === 0))){
			return false;
		}

	}
	return true;
}

function findNextPiece(adjustX, adjustY, startX, startY, board){
	console.log(isInBoard(startY));
	if(!isInBoard(startX) || !isInBoard(startY) || !(Math.abs(adjustX) in [0,1]) || !(Math.abs(adjustY) in [0,1])){
		return 0;
	}else if(board[startY][startX] !== 0){
		return board[startY][startX];
	}else{
		return findNextPiece(adjustX, adjustY, startX+adjustX, startY+adjustY, board);
	}
}

function pawn(color, startX, startY, destX, destY, board){
	if(color === "w"){
		//move forward 1
		if(destY - startY === -1){
			//moving diagonal 1, so killing a piece
			if((Math.abs(destX - startX) === 1)
			||(destX === startX && board[destY][destX] === 0)){
			//or, just moving forward(not diagonal) and empty space there
				return true;
			}
		}else if(Math.abs(destY - startY) === 2 && (startY === 6) && (board[destY][destX] === 0)){
		//first move for pawn, move two, also empty space
			return true;
		}
	/*same thing as white, only Y is reversed and we kill white pieces now
		also, can move two if start at y === 1
	*/
	}else if(color === "b"){
		if(destY - startY === 1){
			if((Math.abs(destX - startX) === 1)
			||(destX === startX && board[destY][destX] === 0)){
				return true;
			}
		}else if(Math.abs(destY - startY) === 2 && (startY === 1) && (board[destY][destX] === 0)){
			return true;
		}
	}
	return false;
}

function rook(startX, startY, destX, destY, board){
	//move vertically
	if(((destX === startX) && nothingBetweenLateral(startY, startX, startY, destY, board, true))
	||((destY === startY) && nothingBetweenLateral(startX, startX, startY, destX, board, false))){
	//move horizontally, destY is now destX, startY is now startX
		return true;
	}
	return false;
}

function knight(startX, startY, destX, destY){
	if((Math.abs(destX - startX) === 2 && Math.abs(destY - startY) === 1)
	||(Math.abs(destX - startX) === 1 && Math.abs(destY - startY) === 2)){
		return true;
	}
	return false;
}

function bishop(startX, startY, destX, destY, board){
	if((Math.abs(destX-startX) === Math.abs(destY-startY)) && nothingBetweenDiag(startX, startY, destX, destY, board)){
		return true;
	}
	return false;
}

function queen(startX, startY, destX, destY, board){
	if(Math.abs(destX - startX) === 0 && nothingBetweenLateral(startY, startX, startY, destY, board, true)){
	//move vertical
		return true;
	}else if(Math.abs(destY - startY) === 0 && nothingBetweenLateral(startX, startX, startY, destY, board, false)){
	//move horizontal
		return true;
	}else if((Math.abs(destY - startY) === Math.abs(destX - startX)) && nothingBetweenDiag(startX, startY, destX, destY, board)){
	//move diagonal
		return true;
	}
	return false;
}

// castling is done elsewhere
function king(startX, startY, destX, destY){
	//since eating its own piece is already checked for, nothing to really check
	console.log(startX, startY, destX, destY);
	if((Math.abs(startX - destX) <= 1) && (Math.abs(startY - destY) <= 1)){
		console.log("king is good")
		return true;
	}
	return false;
}

var self = module.exports = {
	/**
	returns 2d array that represents chess board
	N is knight
	b is black
	w is white
	**/
	/*accessing this board
	will be board[Y coord][X coord] because it is row then term*/
	initBoard: function(){
		var board = [["bR", "bN", "bB", "bQ", "bK", "bB", "bN", "bR"],
				 ["bP", "bP", "bP", "bP", "bP", "bP", "bP", "bP"],
				 [0, 0, 0, 0, 0, 0, 0, 0],
				 [0, 0, 0, 0, 0, 0, 0, 0],
				 [0, 0, 0, 0, 0, 0, 0, 0],
				 [0, 0, 0, 0, 0, 0, 0, 0],
				 ["wP", "wP", "wP", "wP", "wP", "wP", "wP", "wP"],
				 ["wR", "wN", "wB", "wQ", "wK", "wB", "wN", "wR"]];
		return board;
	},

	getMoveInfo: function(movePhrase, board){
		var startX = getCoord(movePhrase.charAt(0));
		var startY = getCoord(movePhrase.charAt(1));
		var destX = getCoord(movePhrase.charAt(2));
		var destY = getCoord(movePhrase.charAt(3));
		console.log(board[startY][startX]);
		var piece = getPiece(startX, startY, board);
		var pieceColor = getColor(startX, startY, board);

		return {"startX": startX,
				"startY": startY,
				"destX": destX,
				"destY": destY,
				"piece": piece,
				"pieceColor": pieceColor
		};
	},

	/**checks if moving side's king is put in check
	but knight case checks if its putitng opponent king into check

	this should really check if a king is put in check from old position(your king is in check)
	and from new position (enemy king is in check)
	**/
	isCheck: function(color, board){
		var king = (() => {
			var kingPhrase = color + "K";
			for(var y = 0; y < 8; y++){
				for(var x = 0; x < 8; x++){
					if(board[y][x] === kingPhrase){
						return {x:x, y:y};
					}
				}
			}
		})();
		var opponentColor = (color == "w") ? "b" : "w";
		const diagKillerRange = [{piece:"Q", range: 8}, {piece:"P", range: 1}, {piece:"K", range: 1}, {piece:"B", range: 8}];
		const horiKillerRange = [{piece:"Q", range: 8}, {piece:"R", range: 8}, {piece:"K", range: 1}];
		const cardinalDirections = {up:[0, 1], down:[0, -1], right:[1, 0], left:[-1, 0],
							se:[1, -1], nw:[-1, 1], ne:[1, 1], sw:[-1, -1]};
		const knightDirections = [[-1, -2], [-1, 2], [1, -2], [1, 2],
								[-2, -1], [-2, 1], [2, -1], [2, 1]];
		for(var i in cardinalDirections){
			var pieceInfo = findPieceWithInfo(cardinalDirections[i], king.x, king.y, board);
			if(isKiller(i, pieceInfo.name, pieceInfo.dist)) {return true};
		}
		for(var i in knightDirections){
			var y = knightDirections[i][1] + king.y;
			var x = knightDirections[i][0] + king.x;
			if (0 <= x && 0 <= y &&
				7 >= x  && 7 >= y ) {
				if (board[y][x] == opponentColor + "N") {
					return true;
				}
			}
		}
		return false;
		function findPieceWithInfo(direction, x, y, board){
			console.log(direction, x, y)
			var dist = 0;
			x = x + direction[0];
			y = y + direction[1];
			dist++;
			while (0 <= x  && 0 <= y &&
				   7 >= x  && 7 >= y ){
				console.log("X: ", x, "Y: ", y);
				if(board[y][x] != 0){
					console.log("Direction: ",direction);
					console.log("Name: ",board[y][x]);
					console.log("Dist: ",dist);
					return {name:board[y][x], dist:dist}
				}
				x = x + direction[0];
				y = y + direction[1];
				dist++;
			}
			return {name:0, dist:0}
		}

		function isKiller(direction, piece, dist){
			if(piece[0] == color){
				return false;
			}
			if (direction in ["up", "down", "left", "right"]){
				console.log("hor killer");
				return (horiKillerRange[direction] > dist);
			}
			if (direction in ["nw", "ne", "se", "sw"]){
				console.log("diag killer");
				return (diagKillerRange[direction] > dist);
			}
			return false;
		}
		//find all cardinal pieces
		//check if any of them are offensive
		//check for jumper
	},

	/* *** need to check if move is out of range of board - done
		check if it puts own king into check
		check if invalid move command(letter and numbers are out of order or something) - done
		check if move is not putting piece in the same place its already in - done
		check if move tries to kill piece of own colour -done
		check if it is indeed moving its own color piece - done
	*/

	//color is taken in as "w" or "b"
	//move phrase is [PIECE][START][DEST]
	isValidMove: function(movePhrase, color, checkStatus, board){
		var isValid = false;
		console.log("hello 1");
		var moveInfo = self.getMoveInfo(movePhrase, board);
		var startX = moveInfo["startX"];
		var startY = moveInfo["startY"];
		var destX = moveInfo["destX"];
		var destY = moveInfo["destY"];
		var piece = moveInfo["piece"];
		var pieceColor = moveInfo["pieceColor"];
		console.log(moveInfo);
		console.log("hello 2");
		//moving to same space
		if(((startX === destX) && (startY === destY))
		//moving piece of not own color
		|| (pieceColor !== color)
		//killing piece of own color
		|| ((board[destY][destX] !== 0) && getColor(destX, destY, board) === color)){
			return false;
		}
		console.log("hello 3");
		switch(piece){
			case "P":
				isValid = pawn(color, startX, startY, destX, destY, board);
				break;
			case "R":
				isValid = rook(startX, startY, destX, destY, board);
				break;
			case "N":
				isValid = knight(startX, startY, destX, destY);
				break;
			case "B":
				isValid = bishop(startX, startY, destX, destY, board);
				break;
			case "Q":
				isValid = queen(startX, startY, destX, destY, board);
				break;
			case "K":
				isValid = king(startX, startY, destX, destY);
				break;
		}
		console.log("hello 4");
		console.log("isValid: " , isValid, "checkStatus: ", checkStatus);
		//if the move is valid but mover's king is in check before move
		if(isValid && checkStatus){
			var afterBoard = board.map(function(arr) {
			    return arr.slice();
			});
			afterBoard[startY][startX] = 0
			afterBoard[destY][destX] = piece;
			if(self.isCheck(color, afterBoard)){
				return false;
			}
		}
		console.log("hello 5");
		return isValid;
	}

}
<commit_msg>small thing<commit_after>'use strict';

/**
takes in string value from move command from message,
converts it to value that can be used for accessing
the board array
**/
function getCoord(val){
	const convert = {
		"a": 0, "b": 1, "c": 2, "d": 3, "e": 4, "f": 5, "g": 6, "h": 7,
		"8": 0, "7": 1, "6": 2, "5": 3, "4": 4, "3": 5, "2": 6, "1": 7
	};

	//check for bad coords
	// tolowercase will not do anything to numbers
	if(convert[val.toLowerCase()] !== undefined){
		return convert[val];
	}else{
		throw new Error('invalid string to convert to coordinate');
	}
}

/*return the first letter of the unit on that board coord
i.e. the color of the piece*/
function getColor(x, y, board){
	if(x > 7 || x < 0 || y > 7 || y < 0){
		throw new Error('trying to get color of something out of bounds');
	}else{
		return board[y][x].charAt(0);
	}
}

function getPiece(x, y, board){
	if(x > 7 || x < 0 || y > 7 || y < 0){
		throw new Error('trying to get piece type of something out of bounds');
	}else{
		return board[y][x].charAt(1);
	}
}

function isInBoard(coord){
	return (coord > 0 && coord < 7) ? true : false;
}

function nothingBetweenDiag(startX, startY, destX, destY, board){
	var upperBoundX;
	var lowerBoundX;
	var lowerBoundY;
	/*don't need to do upperBoundY because we
	use upperBoundX to get the number of spaces that the bishop
	moves vertically*/
	if(destX > startX){
		upperBoundX = destX;
		lowerBoundX = startX;
	}else{
		upperBoundX = startX;
		lowerBoundX = destX;
	}

	if(destY > startY){
		lowerBoundY = startY;
	}else{
		lowerBoundY = destY;
	}

	//chose upperBoundX and lowerBoundX because only displacement amount matters
	//completely arbitrary, could use the other too
	for(var i = 1; i < upperBoundX - lowerBoundX - 1; i++){
		if(board[lowerBoundY + i][lowerBoundX + i]){
			return false;
		}
	}
	return true;
}

function nothingBetweenLateral(start, startX, startY, dest, board, isVertical){
	//check that nothing is inbetween
	var upperBound;
	var lowerBound;
	if(dest > start){
		upperBound = dest;
		lowerBound = start;
	}else{
		upperBound = start;
		lowerBound = dest;
	}

	/* since rook can't jump over piece, return false if trying that
	   lowerBound + 1 since its not looking at either end points
	*/
	for(var i = 1; i < upperBound - lowerBound - 1; i++){
		if((isVertical && (board[lowerBound + i][startX] === 0))
		||(!isVertical && (board[startY][lowerBound + i] === 0))){
			return false;
		}

	}
	return true;
}

function findNextPiece(adjustX, adjustY, startX, startY, board){
	console.log(isInBoard(startY));
	if(!isInBoard(startX) || !isInBoard(startY) || !(Math.abs(adjustX) in [0,1]) || !(Math.abs(adjustY) in [0,1])){
		return 0;
	}else if(board[startY][startX] !== 0){
		return board[startY][startX];
	}else{
		return findNextPiece(adjustX, adjustY, startX+adjustX, startY+adjustY, board);
	}
}

function pawn(color, startX, startY, destX, destY, board){
	if(color === "w"){
		//move forward 1
		if(destY - startY === -1){
			//moving diagonal 1, so killing a piece
			if((Math.abs(destX - startX) === 1)
			||(destX === startX && board[destY][destX] === 0)){
			//or, just moving forward(not diagonal) and empty space there
				return true;
			}
		}else if(Math.abs(destY - startY) === 2 && (startY === 6) && (board[destY][destX] === 0)){
		//first move for pawn, move two, also empty space
			return true;
		}
	/*same thing as white, only Y is reversed and we kill white pieces now
		also, can move two if start at y === 1
	*/
	}else if(color === "b"){
		if(destY - startY === 1){
			if((Math.abs(destX - startX) === 1)
			||(destX === startX && board[destY][destX] === 0)){
				return true;
			}
		}else if(Math.abs(destY - startY) === 2 && (startY === 1) && (board[destY][destX] === 0)){
			return true;
		}
	}
	return false;
}

function rook(startX, startY, destX, destY, board){
	//move vertically
	if(((destX === startX) && nothingBetweenLateral(startY, startX, startY, destY, board, true))
	||((destY === startY) && nothingBetweenLateral(startX, startX, startY, destX, board, false))){
	//move horizontally, destY is now destX, startY is now startX
		return true;
	}
	return false;
}

function knight(startX, startY, destX, destY){
	if((Math.abs(destX - startX) === 2 && Math.abs(destY - startY) === 1)
	||(Math.abs(destX - startX) === 1 && Math.abs(destY - startY) === 2)){
		return true;
	}
	return false;
}

function bishop(startX, startY, destX, destY, board){
	if((Math.abs(destX-startX) === Math.abs(destY-startY)) && nothingBetweenDiag(startX, startY, destX, destY, board)){
		return true;
	}
	return false;
}

function queen(startX, startY, destX, destY, board){
	if(Math.abs(destX - startX) === 0 && nothingBetweenLateral(startY, startX, startY, destY, board, true)){
	//move vertical
		return true;
	}else if(Math.abs(destY - startY) === 0 && nothingBetweenLateral(startX, startX, startY, destY, board, false)){
	//move horizontal
		return true;
	}else if((Math.abs(destY - startY) === Math.abs(destX - startX)) && nothingBetweenDiag(startX, startY, destX, destY, board)){
	//move diagonal
		return true;
	}
	return false;
}

// castling is done elsewhere
function king(startX, startY, destX, destY){
	//since eating its own piece is already checked for, nothing to really check
	console.log(startX, startY, destX, destY);
	if((Math.abs(startX - destX) <= 1) && (Math.abs(startY - destY) <= 1)){
		console.log("king is good")
		return true;
	}
	return false;
}

var self = module.exports = {
	/**
	returns 2d array that represents chess board
	N is knight
	b is black
	w is white
	**/
	/*accessing this board
	will be board[Y coord][X coord] because it is row then term*/
	initBoard: function(){
		var board = [["bR", "bN", "bB", "bQ", "bK", "bB", "bN", "bR"],
				 ["bP", "bP", "bP", "bP", "bP", "bP", "bP", "bP"],
				 [0, 0, 0, 0, 0, 0, 0, 0],
				 [0, 0, 0, 0, 0, 0, 0, 0],
				 [0, 0, 0, 0, 0, 0, 0, 0],
				 [0, 0, 0, 0, 0, 0, 0, 0],
				 ["wP", "wP", "wP", "wP", "wP", "wP", "wP", "wP"],
				 ["wR", "wN", "wB", "wQ", "wK", "wB", "wN", "wR"]];
		return board;
	},

	getMoveInfo: function(movePhrase, board){
		var startX = getCoord(movePhrase.charAt(0));
		var startY = getCoord(movePhrase.charAt(1));
		var destX = getCoord(movePhrase.charAt(2));
		var destY = getCoord(movePhrase.charAt(3));
		console.log(board[startY][startX]);
		var piece = getPiece(startX, startY, board);
		var pieceColor = getColor(startX, startY, board);

		return {"startX": startX,
				"startY": startY,
				"destX": destX,
				"destY": destY,
				"piece": piece,
				"pieceColor": pieceColor
		};
	},

	/**checks if moving side's king is put in check
	but knight case checks if its putitng opponent king into check

	this should really check if a king is put in check from old position(your king is in check)
	and from new position (enemy king is in check)
	**/
	isCheck: function(color, board){
		var king = (() => {
			var kingPhrase = color + "K";
			for(var y = 0; y < 8; y++){
				for(var x = 0; x < 8; x++){
					if(board[y][x] === kingPhrase){
						return {x:x, y:y};
					}
				}
			}
		})();
		var opponentColor = (color == "w") ? "b" : "w";
		const diagKillerRange = {"Q": 8, "P": 1, "K": 1, "B": 8};
		const horiKillerRange = {"Q": 8, "K": 1, "R": 8};
		const cardinalDirections = {up:[0, 1], down:[0, -1], right:[1, 0], left:[-1, 0],
							se:[1, -1], nw:[-1, 1], ne:[1, 1], sw:[-1, -1]};
		const knightDirections = [[-1, -2], [-1, 2], [1, -2], [1, 2],
								[-2, -1], [-2, 1], [2, -1], [2, 1]];
		for(var i in cardinalDirections){
			var pieceInfo = findPieceWithInfo(cardinalDirections[i], king.x, king.y, board);
			if(isKiller(i, pieceInfo.name, pieceInfo.dist)) {return true};
		}
		for(var i in knightDirections){
			var y = knightDirections[i][1] + king.y;
			var x = knightDirections[i][0] + king.x;
			if (0 <= x && 0 <= y &&
				7 >= x  && 7 >= y ) {
				if (board[y][x] == opponentColor + "N") {
					return true;
				}
			}
		}
		return false;
		function findPieceWithInfo(direction, x, y, board){
			console.log(direction, x, y)
			var dist = 0;
			x = x + direction[0];
			y = y + direction[1];
			dist++;
			while (0 <= x  && 0 <= y &&
				   7 >= x  && 7 >= y ){
				console.log("X: ", x, "Y: ", y);
				if(board[y][x] != 0){
					console.log("Direction: ",direction);
					console.log("Name: ",board[y][x]);
					console.log("Dist: ",dist);
					return {name:board[y][x], dist:dist}
				}
				x = x + direction[0];
				y = y + direction[1];
				dist++;
			}
			return {name:0, dist:0}
		}

		function isKiller(direction, piece, dist){
			if(piece[0] == color){
				return false;
			}
			if (direction in ["up", "down", "left", "right"]){
				console.log("hor killer");
				return (horiKillerRange[piece[1]] > dist);
			}
			if (direction in ["nw", "ne", "se", "sw"]){
				console.log("diag killer");
				return (diagKillerRange[piece[1]] > dist);
			}
			return false;
		}
		//find all cardinal pieces
		//check if any of them are offensive
		//check for jumper
	},

	/* *** need to check if move is out of range of board - done
		check if it puts own king into check
		check if invalid move command(letter and numbers are out of order or something) - done
		check if move is not putting piece in the same place its already in - done
		check if move tries to kill piece of own colour -done
		check if it is indeed moving its own color piece - done
	*/

	//color is taken in as "w" or "b"
	//move phrase is [PIECE][START][DEST]
	isValidMove: function(movePhrase, color, checkStatus, board){
		var isValid = false;
		console.log("hello 1");
		var moveInfo = self.getMoveInfo(movePhrase, board);
		var startX = moveInfo["startX"];
		var startY = moveInfo["startY"];
		var destX = moveInfo["destX"];
		var destY = moveInfo["destY"];
		var piece = moveInfo["piece"];
		var pieceColor = moveInfo["pieceColor"];
		console.log(moveInfo);
		console.log("hello 2");
		//moving to same space
		if(((startX === destX) && (startY === destY))
		//moving piece of not own color
		|| (pieceColor !== color)
		//killing piece of own color
		|| ((board[destY][destX] !== 0) && getColor(destX, destY, board) === color)){
			return false;
		}
		console.log("hello 3");
		switch(piece){
			case "P":
				isValid = pawn(color, startX, startY, destX, destY, board);
				break;
			case "R":
				isValid = rook(startX, startY, destX, destY, board);
				break;
			case "N":
				isValid = knight(startX, startY, destX, destY);
				break;
			case "B":
				isValid = bishop(startX, startY, destX, destY, board);
				break;
			case "Q":
				isValid = queen(startX, startY, destX, destY, board);
				break;
			case "K":
				isValid = king(startX, startY, destX, destY);
				break;
		}
		console.log("hello 4");
		console.log("isValid: " , isValid, "checkStatus: ", checkStatus);
		//if the move is valid but mover's king is in check before move
		if(isValid && checkStatus){
			var afterBoard = board.map(function(arr) {
			    return arr.slice();
			});
			afterBoard[startY][startX] = 0
			afterBoard[destY][destX] = piece;
			if(self.isCheck(color, afterBoard)){
				return false;
			}
		}
		console.log("hello 5");
		return isValid;
	}

}
<|endoftext|>


<commit_before>/**
 * Copyright (c) 2017-present, Facebook, Inc.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

// See https://docusaurus.io/docs/site-config.html for all the possible
// site configuration options.

/* List of projects/orgs using your project for the users page */
const users = [
  {
    caption: 'User1',
    // You will need to prepend the image path with your baseUrl
    // if it is not '/', like: '/test-site/img/docusaurus.svg'.
    image: '/img/docusaurus.svg',
    infoLink: 'https://www.facebook.com',
    pinned: true,
  },
];

const siteConfig = {
  title: 'web1992\'s blog' /* title for your website */,
  tagline: 'Read Write Share',
  url: 'https://your-docusaurus-test-site.com' /* your website url */,
  baseUrl: '/' /* base url for your project */,
  // For github.io type URLs, you would set the url and baseUrl like:
  //   url: 'https://facebook.github.io',
  //   baseUrl: '/test-site/',

  // Used for publishing and more
  projectName: 'web1992-blog',
  organizationName: 'web1992',
  // For top-level user or org sites, the organization is still the same.
  // e.g., for the https://JoelMarcey.github.io site, it would be set like...
  //   organizationName: 'JoelMarcey'

  // For no header links in the top nav bar -> headerLinks: [],
  headerLinks: [
    // { doc: 'doc1', label: 'Docs' },
    // { doc: 'doc4', label: 'API' },
    // { page: 'help', label: 'Help' },
    { blog: true, label: 'Blog' },
    // Links to href destination
    { href: "https://github.com/web1992", label: "GitHub" },
    { page: 'about', label: 'About' },
    { search: true }
  ],

  blogSidebarTitle: { default: 'Recent posts', all: 'All' },
  //blogSidebarCount: 'ALL',
  blogSidebarCount:20,
  // If you have users set above, you add it here:
  users,

  /* path to images for header/footer */
  headerIcon: 'img/docusaurus.svg',
  footerIcon: 'img/docusaurus.svg',
  favicon: 'img/favicon.png',

  /* colors for website */
  colors: {
    primaryColor: '#2E8555',
    secondaryColor: '#205C3B',
  },

  /* custom fonts for website */
  /*fonts: {
    myFont: [
      "Times New Roman",
      "Serif"
    ],
    myOtherFont: [
      "-apple-system",
      "system-ui"
    ]
  },*/

  // This copyright info is used in /core/Footer.js and blog rss/atom feeds.
  copyright:
    'Copyright © ' +
    new Date().getFullYear() +
    ' 京ICP备15055486号',

  highlight: {
    // Highlight.js theme to use for syntax highlighting in code blocks
    // theme: 'default',
    theme: 'vs2015',
  },

  // Add custom scripts here that would be placed in <script> tags
  scripts: ['https://buttons.github.io/buttons.js'],

  /* On page navigation for the current documentation page */
  onPageNav: 'separate',

  /* Open Graph and Twitter card images */
  ogImage: 'img/docusaurus.png',
  twitterImage: 'img/docusaurus.png',

  // You may provide arbitrary config keys to be used as needed by your
  // template. For example, if you need your repo's URL...
  //   repoUrl: 'https://github.com/facebook/test-site',
};

module.exports = siteConfig;
<commit_msg>fix color<commit_after>/**
 * Copyright (c) 2017-present, Facebook, Inc.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

// See https://docusaurus.io/docs/site-config.html for all the possible
// site configuration options.

/* List of projects/orgs using your project for the users page */
const users = [
  {
    caption: 'User1',
    // You will need to prepend the image path with your baseUrl
    // if it is not '/', like: '/test-site/img/docusaurus.svg'.
    image: '/img/docusaurus.svg',
    infoLink: 'https://www.facebook.com',
    pinned: true,
  },
];

const siteConfig = {
  title: 'web1992\'s blog' /* title for your website */,
  tagline: 'Read Write Share',
  url: 'https://your-docusaurus-test-site.com' /* your website url */,
  baseUrl: '/' /* base url for your project */,
  // For github.io type URLs, you would set the url and baseUrl like:
  //   url: 'https://facebook.github.io',
  //   baseUrl: '/test-site/',

  // Used for publishing and more
  projectName: 'web1992-blog',
  organizationName: 'web1992',
  // For top-level user or org sites, the organization is still the same.
  // e.g., for the https://JoelMarcey.github.io site, it would be set like...
  //   organizationName: 'JoelMarcey'

  // For no header links in the top nav bar -> headerLinks: [],
  headerLinks: [
    // { doc: 'doc1', label: 'Docs' },
    // { doc: 'doc4', label: 'API' },
    // { page: 'help', label: 'Help' },
    { blog: true, label: 'Blog' },
    // Links to href destination
    { href: "https://github.com/web1992", label: "GitHub" },
    { page: 'about', label: 'About' },
    { search: true }
  ],

  blogSidebarTitle: { default: 'Recent posts', all: 'All' },
  //blogSidebarCount: 'ALL',
  blogSidebarCount:20,
  // If you have users set above, you add it here:
  users,

  /* path to images for header/footer */
  headerIcon: 'img/docusaurus.svg',
  footerIcon: 'img/docusaurus.svg',
  favicon: 'img/favicon.png',

  /* colors for website */
  colors: {
    primaryColor: '#4285f4',
    secondaryColor: '#205C3B',
  },

  /* custom fonts for website */
  /*fonts: {
    myFont: [
      "Times New Roman",
      "Serif"
    ],
    myOtherFont: [
      "-apple-system",
      "system-ui"
    ]
  },*/

  // This copyright info is used in /core/Footer.js and blog rss/atom feeds.
  copyright:
    'Copyright © ' +
    new Date().getFullYear() +
    ' 京ICP备15055486号',

  highlight: {
    // Highlight.js theme to use for syntax highlighting in code blocks
    // theme: 'default',
    theme: 'vs2015',
  },

  // Add custom scripts here that would be placed in <script> tags
  scripts: ['https://buttons.github.io/buttons.js'],

  /* On page navigation for the current documentation page */
  onPageNav: 'separate',

  /* Open Graph and Twitter card images */
  ogImage: 'img/docusaurus.png',
  twitterImage: 'img/docusaurus.png',

  // You may provide arbitrary config keys to be used as needed by your
  // template. For example, if you need your repo's URL...
  //   repoUrl: 'https://github.com/facebook/test-site',
};

module.exports = siteConfig;
<|endoftext|>


<commit_before>
var Q = require("q");
var LruMap = require("collections/lru-map");
var UUID = require("./lib/uuid");
var adapt = require("./adapt");

function debug() {
    //typeof console !== "undefined" && console.log.apply(console, arguments);
}

var rootId = "";

var has = Object.prototype.hasOwnProperty;

/**
 * @param connection
 * @param local
 */
module.exports = Connection;
function Connection(connection, local, options) {
    options = options || {};
    var makeId = options.makeId || function () {
        return UUID.generate();
    };
    var locals = LruMap(null, options.max || Infinity);
    connection = adapt(connection, options.origin);

    var debugKey = Math.random().toString(16).slice(2, 4).toUpperCase() + ":";
    function _debug() {
        debug.apply(null, [debugKey].concat(Array.prototype.slice.call(arguments)));
    }

    // message receiver loop
    Q.when(connection.get(), get).done();
    function get(message) {
        _debug("receive:", message);
        Q.when(connection.get(), get).done();
        receive(message);
    }

    // message receiver
    function receive(message) {
        message = JSON.parse(message);
        _debug("receive: parsed message", message);

        if (!receivers[message.type])
            return; // ignore bad message types
        if (!locals.has(message.to))
            return; // ignore messages to non-existant or forgotten promises
        receivers[message.type](message);
    }

    // message receiver handlers by message type
    var receivers = {
        "resolve": function (message) {
            if (locals.has(message.to)) {
                resolveLocal(message.to, 'resolve', decode(message.resolution));
            }
        },
        "notify": function (message) {
            if (locals.has(message.to)) {
                resolveLocal(message.to, 'notify', decode(message.resolution));
            }
        },
        // a "send" message forwards messages from a remote
        // promise to a local promise.
        "send": function (message) {

            // forward the message to the local promise,
            // which will return a response promise
            var local = locals.get(message.to).promise;
            var response = Q.dispatch(local, message.op, decode(message.args));
            var envelope;

            // connect the local response promise with the
            // remote response promise:

            // if the value is ever resolved, send the
            // fulfilled value across the wire
            Q.when(response, function (resolution) {
                try {
                    resolution = encode(resolution);
                } catch (exception) {
                    try {
                        resolution = {"!": encode(exception)};
                    } catch (exception) {
                        resolution = {"!": null};
                    }
                }
                envelope = JSON.stringify({
                    "type": "resolve",
                    "to": message.from,
                    "resolution": resolution
                });
                connection.put(envelope);
            }, function (reason) {
                try {
                    reason = encode(reason);
                } catch (exception) {
                    try {
                        reason = encode(exception);
                    } catch (exception) {
                        reason = null;
                    }
                }
                envelope = JSON.stringify({
                    "type": "resolve",
                    "to": message.from,
                    "resolution": {"!": reason}
                })
                connection.put(envelope);
            }, function (progress) {
                try {
                    progress = encode(progress);
                    envelope = JSON.stringify({
                        "type": "notify",
                        "to": message.from,
                        "resolution": progress
                    });
                } catch (exception) {
                    try {
                        progress = {"!": encode(exception)};
                    } catch (exception) {
                        progress = {"!": null};
                    }
                    envelope = JSON.stringify({
                        "type": "resolve",
                        "to": message.from,
                        "resolution": progress
                    });
                }
                connection.put(envelope);
            })
            .done();

        }
    }

    // construct a local promise, such that it can
    // be resolved later by a remote message
    function makeLocal(id) {
        if (locals.has(id)) {
            return locals.get(id).promise;
        } else {
            var deferred = Q.defer();
            locals.set(id, deferred);
            return deferred.promise;
        }
    }

    // a utility for resolving the local promise
    // for a given identifier.
    function resolveLocal(id, op, value) {
        _debug(op + ':', "L" + JSON.stringify(id), JSON.stringify(value), typeof value);
        locals.get(id)[op](value);
    }

    // makes a promise that will send all of its events to a
    // remote object.
    function makeRemote(id) {
        return Q.makePromise({
            when: function () {
                return this;
            }
        }, function (op, args) {
            var localId = makeId();
            var response = makeLocal(localId);
             _debug('sending:', "R" + JSON.stringify(id), JSON.stringify(op), JSON.stringify(encode(args)));
            connection.put(JSON.stringify({
                "type": "send",
                "to": id,
                "from": localId,
                "op": op,
                "args": encode(args)
            }));
            return response;
        });
    }

    // serializes an object tree, encoding promises such
    // that JSON.stringify on the result will produce
    // "QSON": serialized promise objects.
    function encode(object) {
        if (object === undefined) {
            return {"%": "undefined"};
        } else if (Object(object) !== object) {
            return object;
        } if (Q.isPromise(object) || typeof object === "function") {
            var id = makeId();
            makeLocal(id);
            resolveLocal(id, 'resolve', object);
            return {"@": id, "type": typeof object};
        } else if (object instanceof Error) {
            return {
                message: object.message,
                stack: object.stack
            };
        } else if (Array.isArray(object)) {
            return object.map(encode);
        } else if (typeof object === "object") {
            var result = {};
            for (var key in object) {
                if (has.call(object, key)) {
                    var newKey = key.replace(/[@!%\\]/, function ($0) {
                        return "\\" + $0;
                    });
                    result[newKey] = encode(object[key]);
                }
            }
            return result;
        } else {
            return object;
        }
    }

    // decodes QSON
    function decode(object) {
        if (Object(object) !== object) {
            return object;
        } else if (object['%']) {
            if (object["%"] === "undefined") {
                return undefined;
            } else {
                return Q.reject(new TypeError("Unrecognized type: " + object["%"]));
            }
        } else if (object['!']) {
            return Q.reject(object['!']);
        } else if (object['@']) {
            var remote = makeRemote(object["@"]);
            if (object.type === "function") {
                return function () {
                    return Q.fapply(remote, Array.prototype.slice.call(arguments));
                };
            } else {
                return remote;
            }
        } else if (Array.isArray(object)) {
            return object.map(decode);
        } else {
            var newObject = {};
            for (var key in object) {
                if (has.call(object, key)) {
                    var newKey = key.replace(/\\([\\!@%])/, function ($0, $1) {
                        return $1;
                    });
                    newObject[newKey] = decode(object[key]);
                }
            }
            return newObject;
        }
    }

    // a peer-to-peer promise connection is symmetric: both
    // the local and remote side have a "root" promise
    // object. On each side, the respective remote object is
    // returned, and the object passed as an argument to
    // Connection is used as the local object.  The identifier of
    // the root object is an empty-string by convention.
    // All other identifiers are numbers.
    makeLocal(rootId);
    resolveLocal(rootId, 'resolve', local);
    return makeRemote(rootId);

}

<commit_msg>Rename resolveLocal to dispatchLocal<commit_after>
var Q = require("q");
var LruMap = require("collections/lru-map");
var UUID = require("./lib/uuid");
var adapt = require("./adapt");

function debug() {
    //typeof console !== "undefined" && console.log.apply(console, arguments);
}

var rootId = "";

var has = Object.prototype.hasOwnProperty;

/**
 * @param connection
 * @param local
 */
module.exports = Connection;
function Connection(connection, local, options) {
    options = options || {};
    var makeId = options.makeId || function () {
        return UUID.generate();
    };
    var locals = LruMap(null, options.max || Infinity);
    connection = adapt(connection, options.origin);

    var debugKey = Math.random().toString(16).slice(2, 4).toUpperCase() + ":";
    function _debug() {
        debug.apply(null, [debugKey].concat(Array.prototype.slice.call(arguments)));
    }

    // message receiver loop
    connection.get().then(get).done();
    function get(message) {
        _debug("receive:", message);
        connection.get().then(get).done();
        receive(message);
    }

    // message receiver
    function receive(message) {
        message = JSON.parse(message);
        _debug("receive: parsed message", message);

        if (!receivers[message.type])
            return; // ignore bad message types
        if (!locals.has(message.to))
            return; // ignore messages to non-existant or forgotten promises
        receivers[message.type](message);
    }

    // message receiver handlers by message type
    var receivers = {
        "resolve": function (message) {
            if (locals.has(message.to)) {
                dispatchLocal(message.to, 'resolve', decode(message.resolution));
            }
        },
        "notify": function (message) {
            if (locals.has(message.to)) {
                dispatchLocal(message.to, 'notify', decode(message.resolution));
            }
        },
        // a "send" message forwards messages from a remote
        // promise to a local promise.
        "send": function (message) {

            // forward the message to the local promise,
            // which will return a response promise
            var local = locals.get(message.to).promise;
            var response = local.dispatch(message.op, decode(message.args));
            var envelope;

            // connect the local response promise with the
            // remote response promise:

            // if the value is ever resolved, send the
            // fulfilled value across the wire
            response.then(function (resolution) {
                try {
                    resolution = encode(resolution);
                } catch (exception) {
                    try {
                        resolution = {"!": encode(exception)};
                    } catch (exception) {
                        resolution = {"!": null};
                    }
                }
                envelope = JSON.stringify({
                    "type": "resolve",
                    "to": message.from,
                    "resolution": resolution
                });
                connection.put(envelope);
            }, function (reason) {
                try {
                    reason = encode(reason);
                } catch (exception) {
                    try {
                        reason = encode(exception);
                    } catch (exception) {
                        reason = null;
                    }
                }
                envelope = JSON.stringify({
                    "type": "resolve",
                    "to": message.from,
                    "resolution": {"!": reason}
                })
                connection.put(envelope);
            }, function (progress) {
                try {
                    progress = encode(progress);
                    envelope = JSON.stringify({
                        "type": "notify",
                        "to": message.from,
                        "resolution": progress
                    });
                } catch (exception) {
                    try {
                        progress = {"!": encode(exception)};
                    } catch (exception) {
                        progress = {"!": null};
                    }
                    envelope = JSON.stringify({
                        "type": "resolve",
                        "to": message.from,
                        "resolution": progress
                    });
                }
                connection.put(envelope);
            })
            .done();

        }
    }

    // construct a local promise, such that it can
    // be resolved later by a remote message
    function makeLocal(id) {
        if (locals.has(id)) {
            return locals.get(id).promise;
        } else {
            var deferred = Q.defer();
            locals.set(id, deferred);
            return deferred.promise;
        }
    }

    // a utility for resolving the local promise
    // for a given identifier.
    function dispatchLocal(id, op, value) {
        _debug(op + ':', "L" + JSON.stringify(id), JSON.stringify(value), typeof value);
        locals.get(id)[op](value);
    }

    // makes a promise that will send all of its events to a
    // remote object.
    function makeRemote(id) {
        return Q.makePromise({
            when: function () {
                return this;
            }
        }, function (op, args) {
            var localId = makeId();
            var response = makeLocal(localId);
             _debug('sending:', "R" + JSON.stringify(id), JSON.stringify(op), JSON.stringify(encode(args)));
            connection.put(JSON.stringify({
                "type": "send",
                "to": id,
                "from": localId,
                "op": op,
                "args": encode(args)
            }));
            return response;
        });
    }

    // serializes an object tree, encoding promises such
    // that JSON.stringify on the result will produce
    // "QSON": serialized promise objects.
    function encode(object) {
        if (object === undefined) {
            return {"%": "undefined"};
        } else if (Object(object) !== object) {
            return object;
        } if (Q.isPromise(object) || typeof object === "function") {
            var id = makeId();
            makeLocal(id);
            dispatchLocal(id, 'resolve', object);
            return {"@": id, "type": typeof object};
        } else if (object instanceof Error) {
            return {
                message: object.message,
                stack: object.stack
            };
        } else if (Array.isArray(object)) {
            return object.map(encode);
        } else if (typeof object === "object") {
            var result = {};
            for (var key in object) {
                if (has.call(object, key)) {
                    var newKey = key.replace(/[@!%\\]/, function ($0) {
                        return "\\" + $0;
                    });
                    result[newKey] = encode(object[key]);
                }
            }
            return result;
        } else {
            return object;
        }
    }

    // decodes QSON
    function decode(object) {
        if (Object(object) !== object) {
            return object;
        } else if (object['%']) {
            if (object["%"] === "undefined") {
                return undefined;
            } else {
                return Q.reject(new TypeError("Unrecognized type: " + object["%"]));
            }
        } else if (object['!']) {
            return Q.reject(object['!']);
        } else if (object['@']) {
            var remote = makeRemote(object["@"]);
            if (object.type === "function") {
                return function () {
                    return Q.fapply(remote, Array.prototype.slice.call(arguments));
                };
            } else {
                return remote;
            }
        } else if (Array.isArray(object)) {
            return object.map(decode);
        } else {
            var newObject = {};
            for (var key in object) {
                if (has.call(object, key)) {
                    var newKey = key.replace(/\\([\\!@%])/, function ($0, $1) {
                        return $1;
                    });
                    newObject[newKey] = decode(object[key]);
                }
            }
            return newObject;
        }
    }

    // a peer-to-peer promise connection is symmetric: both
    // the local and remote side have a "root" promise
    // object. On each side, the respective remote object is
    // returned, and the object passed as an argument to
    // Connection is used as the local object.  The identifier of
    // the root object is an empty-string by convention.
    // All other identifiers are numbers.
    makeLocal(rootId);
    dispatchLocal(rootId, 'resolve', local);
    return makeRemote(rootId);

}

<|endoftext|>


<commit_before>/**
 * Created by desver_f on 24/01/17.
 */

import { observable, computed } from 'mobx';
import autobind from 'autobind-decorator';
import moment from 'moment';
import stores from './index';
import * as Intra from '../api/intra';
import newsParser from '../features/news/newsParser';

@autobind
class Session {
    @observable isLogged = false;
    @observable session = null;
    @observable news = [];
    @observable username = '';

    async login(username = '', password = '') {
        try {

            if (username && password) {
                await this.tryLoginRegular(username, password);
            } else {
                await this.tryLoginFromAutoLogin();
            }
        } catch (e) {
            console.error(e);
            stores.ui.errorState();
            this.isLogged = false;
        }
    }

    async tryLoginFromAutoLogin() {
        const autoLogin = await this.getAutologinFromCache();

        if (autoLogin.link && autoLogin.username) {
            const session = await Intra.autoLog(autoLogin.link);
            this.setSessionFields(session, autoLogin.username);
        }
    }

    async tryLoginRegular(username, password) {
        const session = await Intra.login(username, password);

        this.setSessionFields(session, username);
        await this.saveAutoLoginIfNeeded(username);
    }

    async saveAutoLoginIfNeeded(username) {
        const hasAutoLogin = !!(await this.getAutologinFromCache());

        if (this.isLogged && !hasAutoLogin) {
            const { autologin } = await Intra.fetchAutoLogin();

            await storage.save('autologin', {
                link: autologin,
                username,
            });
        }
    }

    getAutologinFromCache() {
        return storage.get('autologin');
    }

    setSessionFields(session, username) {
        if (session && session.message !== "Veuillez vous connecter") {
            this.isLogged = true;
            this.username = username;
            this.session = {
                board: session.board
            };
            this.news = newsParser(session.history);
        }
    }

    async userInformation() {
        try {
            const information = await Intra.fetchStudent(this.username);

            this.session = {
                ...this.session,
                user: {
                    name: information.title,
                    credits: information.credits,
                    spices: information.spice || '0',
                    gpa: information.gpa[0].gpa,
                    logtime: information.nsstat.active,
                    expectedLogtime: information.nsstat.nslog_norm,
                    promo: `tek${information.studentyear}`,
                    studentyear: information.studentyear,
                    year: information.scolaryear,
                    location: information.location,
                    thumbnail: information.picture,
                    uid: information.uid,
                }
            };

            this.username = information.login;
        } catch (e) {
            console.error(e);
            stores.ui.errorState();
        }
    }

    async logout() {
        try {
            await Intra.logout();
            this.username = '';
            this.isLogged = false;
            await storage.delete('autologin');

        } catch (e) {
            this.isLogged = false;
            console.error(e);
            stores.ui.errorState();
        }
    }

    @computed get tokens() {
        const activities = this.session.board.activites.slice();

        return activities
            .filter((activity) => activity.token)
            .map((activity) => ({
                title: `${activity.module.split(' - ')[0]} - ${activity.title}`,
                date: moment(activity.timeline_start, 'DD/MM/YYYY, HH[h]mm').format('DD.MM.YYYY'),
                tokenLink: activity.token_link,
            }));
    }
}

const sessionStore = new Session();
export default sessionStore;<commit_msg>- Fixed missing import from rn-simple-storage after rebasing<commit_after>/**
 * Created by desver_f on 24/01/17.
 */

import { observable, computed } from 'mobx';
import autobind from 'autobind-decorator';
import moment from 'moment';
import storage from 'react-native-simple-store';

import stores from './index';
import * as Intra from '../api/intra';
import newsParser from '../features/news/newsParser';

@autobind
class Session {
    @observable isLogged = false;
    @observable session = null;
    @observable news = [];
    @observable username = '';

    async login(username = '', password = '') {
        try {

            if (username && password) {
                await this.tryLoginRegular(username, password);
            } else {
                await this.tryLoginFromAutoLogin();
            }
        } catch (e) {
            console.error(e);
            stores.ui.errorState();
            this.isLogged = false;
        }
    }

    async tryLoginFromAutoLogin() {
        const autoLogin = await this.getAutologinFromCache();

        if (autoLogin.link && autoLogin.username) {
            const session = await Intra.autoLog(autoLogin.link);
            this.setSessionFields(session, autoLogin.username);
        }
    }

    async tryLoginRegular(username, password) {
        const session = await Intra.login(username, password);

        this.setSessionFields(session, username);
        await this.saveAutoLoginIfNeeded(username);
    }

    async saveAutoLoginIfNeeded(username) {
        const hasAutoLogin = !!(await this.getAutologinFromCache());

        if (this.isLogged && !hasAutoLogin) {
            const { autologin } = await Intra.fetchAutoLogin();

            await storage.save('autologin', {
                link: autologin,
                username,
            });
        }
    }

    getAutologinFromCache() {
        return storage.get('autologin');
    }

    setSessionFields(session, username) {
        if (session && session.message !== "Veuillez vous connecter") {
            this.isLogged = true;
            this.username = username;
            this.session = {
                board: session.board
            };
            this.news = newsParser(session.history);
        }
    }

    async userInformation() {
        try {
            const information = await Intra.fetchStudent(this.username);

            this.session = {
                ...this.session,
                user: {
                    name: information.title,
                    credits: information.credits,
                    spices: information.spice || '0',
                    gpa: information.gpa[0].gpa,
                    logtime: information.nsstat.active,
                    expectedLogtime: information.nsstat.nslog_norm,
                    promo: `tek${information.studentyear}`,
                    studentyear: information.studentyear,
                    year: information.scolaryear,
                    location: information.location,
                    thumbnail: information.picture,
                    uid: information.uid,
                }
            };

            this.username = information.login;
        } catch (e) {
            console.error(e);
            stores.ui.errorState();
        }
    }

    async logout() {
        try {
            await Intra.logout();
            this.username = '';
            this.isLogged = false;
            await storage.delete('autologin');

        } catch (e) {
            this.isLogged = false;
            console.error(e);
            stores.ui.errorState();
        }
    }

    @computed get tokens() {
        const activities = this.session.board.activites.slice();

        return activities
            .filter((activity) => activity.token)
            .map((activity) => ({
                title: `${activity.module.split(' - ')[0]} - ${activity.title}`,
                date: moment(activity.timeline_start, 'DD/MM/YYYY, HH[h]mm').format('DD.MM.YYYY'),
                tokenLink: activity.token_link,
            }));
    }
}

const sessionStore = new Session();
export default sessionStore;<|endoftext|>


<commit_before>import { Mongo } from 'meteor/mongo';
import { SimpleSchema } from 'meteor/aldeed:simple-schema';
import Wallet from '../users/Wallet';

const Collectives = new Mongo.Collection('collectives');

const Country = new SimpleSchema({
  name: {
    type: String,
  },
  code: {
    type: String,
    regEx: /^[A-Z]{2}$/,
  },
});

const Jurisdiction = new SimpleSchema({
  legal: {
    type: Object,
    optional: true,
  },
  'legal.taxId': {
    type: String,
    optional: true,
  },
  'legal.name': {
    type: String,
    optional: true,
  },
  'legal.type': {
    type: String,
    optional: true,
  },
  location: {
    type: Object,
    optional: true,
  },
  'location.address': {
    type: String,
    optional: true,
  },
  'location.state': {
    type: String,
    optional: true,
  },
  'location.country': {
    type: Country.schema,
    optional: true,
  },
});

const CollectiveProfile = new SimpleSchema({
  website: {
    type: String,
    regEx: SimpleSchema.RegEx.Url,
    optional: true,
  },
  bio: {
    type: String,
    optional: true,
  },
  blockchain: {
    type: Object,
    optional: true,
  },
  'blockchain.address': {
    type: String,
    optional: true,
  },
  logo: {
    type: String,
    optional: true,
  },
  jurisdiction: {
    type: Jurisdiction.schema,
    optional: true,
  },
  foundation: {
    type: Date,
    optional: true,
  },
  goal: {
      type: String,
      allowedValues: ['Profit', 'Free'],
      optional: true
  },
  owners : {
      type: String,
      optional: true
  },
  configured: {
    type: Boolean,
    optional: true
  },
  wallet: {
    type: Wallet,
    optional: true
  }
});

Collectives.schema = new SimpleSchema({
  name: {
    type: String,
  },
  domain: {
    type: String,
  },
  emails: {
    type: Array,
    optional: true,
  },
  'emails.$': {
    type: Object,
  },
  'emails.$.address': {
      type: String,
      regEx: SimpleSchema.RegEx.Email
  },
  'emails.$.verified': {
      type: Boolean
  },
  profile: {
      type: CollectiveProfile.schema,
      optional: true
  },
  goal: {
    type: String,
    allowedValues: ['Business', 'Free', 'Commons'],
    optional: true
  },
  authorities: {
    type: Array,
    optional: true
  },
  'authorities.$': {
    type: Object,
    optional: true
  },
  'authorities.$.userId': {
    type: String,
    optional: true,
  },
});

Collectives.attachSchema(Collectives.schema);
export default Collectives;
<commit_msg>test export schema with attach<commit_after>import { Mongo } from 'meteor/mongo';
import { SimpleSchema } from 'meteor/aldeed:simple-schema';
import Wallet from '../users/Wallet';

const Collectives = new Mongo.Collection('collectives');

export const Country = new SimpleSchema({
  name: {
    type: String,
  },
  code: {
    type: String,
    regEx: /^[A-Z]{2}$/,
  },
});

const Jurisdiction = new SimpleSchema({
  legal: {
    type: Object,
    optional: true,
  },
  'legal.taxId': {
    type: String,
    optional: true,
  },
  'legal.name': {
    type: String,
    optional: true,
  },
  'legal.type': {
    type: String,
    optional: true,
  },
  location: {
    type: Object,
    optional: true,
  },
  'location.address': {
    type: String,
    optional: true,
  },
  'location.state': {
    type: String,
    optional: true,
  },
  'location.country': {
    type: Country.schema,
    optional: true,
  },
});

const CollectiveProfile = new SimpleSchema({
  website: {
    type: String,
    regEx: SimpleSchema.RegEx.Url,
    optional: true,
  },
  bio: {
    type: String,
    optional: true,
  },
  blockchain: {
    type: Object,
    optional: true,
  },
  'blockchain.address': {
    type: String,
    optional: true,
  },
  logo: {
    type: String,
    optional: true,
  },
  jurisdiction: {
    type: Jurisdiction.schema,
    optional: true,
  },
  foundation: {
    type: Date,
    optional: true,
  },
  goal: {
      type: String,
      allowedValues: ['Profit', 'Free'],
      optional: true
  },
  owners : {
      type: String,
      optional: true
  },
  configured: {
    type: Boolean,
    optional: true
  },
  wallet: {
    type: Wallet,
    optional: true
  }
});

Collectives.schema = new SimpleSchema({
  name: {
    type: String,
  },
  domain: {
    type: String,
  },
  emails: {
    type: Array,
    optional: true,
  },
  'emails.$': {
    type: Object,
  },
  'emails.$.address': {
      type: String,
      regEx: SimpleSchema.RegEx.Email
  },
  'emails.$.verified': {
      type: Boolean
  },
  profile: {
      type: CollectiveProfile.schema,
      optional: true
  },
  goal: {
    type: String,
    allowedValues: ['Business', 'Free', 'Commons'],
    optional: true
  },
  authorities: {
    type: Array,
    optional: true
  },
  'authorities.$': {
    type: Object,
    optional: true
  },
  'authorities.$.userId': {
    type: String,
    optional: true,
  },
});

Collectives.attachSchema(Collectives.schema);
// export collectives or .schema???
export default Collectives.schema;
<|endoftext|>


<commit_before>module.exports = {
    rules: {
        'react/display-name': [2],
        'react/forbid-prop-types': [2],
        'react/no-children-prop': [2],
        'react/no-danger': [2],
        'react/no-danger-with-children': [2],
        'react/no-deprecated': [2],
        'react/no-did-mount-set-state': [2],
        'react/no-did-update-set-state': [2],
        'react/no-direct-mutation-state': [2],
        'react/no-find-dom-node': [2],
        'react/no-is-mounted': [2],
        'react/no-multi-comp': [2, {
            ignoreStateless: true
        }],
        'react/no-render-return-value': [2],
        'react/no-set-state': [0],
        'react/no-string-refs': [1],
        'react/no-unescaped-entities': [2],
        'react/no-unknown-property': [2],
        'react/no-unused-prop-types': [2],
        'react/prefer-es6-class': [2],
        'react/prefer-stateless-function': [1],
        'react/prop-types': [2],
        'react/react-in-jsx-scope': [2],
        'react/require-optimization': [0],
        'react/require-render-return': [2],
        'react/self-closing-comp': [2],
        'react/sort-comp': [2],
        'react/sort-prop-types': [2],
        'react/style-prop-object': [2],

        // JSX
        'react/jsx-boolean-value': [2, 'never'],
        'react/jsx-closing-bracket-location': [2, 'line-aligned'],
        'react/jsx-curly-spacing': [2],
        'react/jsx-equals-spacing': [2],
        'react/jsx-filename-extension': [2],
        'react/jsx-first-prop-new-line': [2, 'multiline'],
        'react/jsx-handler-names': [2],
        'react/jsx-indent': [2],
        'react/jsx-indent-props': [2],
        'react/jsx-key': [2],
        'react/jsx-max-props-per-line': [2, {maximum: 1}],
        'react/jsx-no-bind': [1, {
            ignoreRefs: true
        }],
        'react/jsx-no-comment-textnodes': [2],
        'react/jsx-no-duplicate-props': [2],
        'react/jsx-no-target-blank': [2],
        'react/jsx-no-undef': [2],
        'react/jsx-pascal-case': [2, {
            allowAllCaps: true
        }],
        'react/jsx-sort-props': [2, {
            shorthandFirst: true,
            callbacksLast: true
        }],
        'react/jsx-space-before-closing': [2, 'always'],
        'react/jsx-uses-react': [2],
        'react/jsx-uses-vars': [2],
        'react/jsx-wrap-multilines': [2],
    },
    plugins: ['react'],
    extends: ['plugin:react/all']
};
<commit_msg>fix(react): Extend react rules from react/recommended<commit_after>module.exports = {
    rules: {
        'react/display-name': [2],
        'react/forbid-prop-types': [2],
        'react/no-children-prop': [2],
        'react/no-danger': [2],
        'react/no-danger-with-children': [2],
        'react/no-deprecated': [2],
        'react/no-did-mount-set-state': [2],
        'react/no-did-update-set-state': [2],
        'react/no-direct-mutation-state': [2],
        'react/no-find-dom-node': [2],
        'react/no-is-mounted': [2],
        'react/no-multi-comp': [2, {
            ignoreStateless: true
        }],
        'react/no-render-return-value': [2],
        'react/no-set-state': [0],
        'react/no-string-refs': [1],
        'react/no-unescaped-entities': [2],
        'react/no-unknown-property': [2],
        'react/no-unused-prop-types': [2],
        'react/prefer-es6-class': [2],
        'react/prefer-stateless-function': [1],
        'react/prop-types': [2],
        'react/react-in-jsx-scope': [2],
        'react/require-optimization': [0],
        'react/require-render-return': [2],
        'react/self-closing-comp': [2],
        'react/sort-comp': [2],
        'react/sort-prop-types': [2],
        'react/style-prop-object': [2],

        // JSX
        'react/jsx-boolean-value': [2, 'never'],
        'react/jsx-closing-bracket-location': [2, 'line-aligned'],
        'react/jsx-curly-spacing': [2],
        'react/jsx-equals-spacing': [2],
        'react/jsx-filename-extension': [2],
        'react/jsx-first-prop-new-line': [2, 'multiline'],
        'react/jsx-handler-names': [2],
        'react/jsx-indent': [2],
        'react/jsx-indent-props': [2],
        'react/jsx-key': [2],
        'react/jsx-max-props-per-line': [2, {maximum: 1}],
        'react/jsx-no-bind': [1, {
            ignoreRefs: true
        }],
        'react/jsx-no-comment-textnodes': [2],
        'react/jsx-no-duplicate-props': [2],
        'react/jsx-no-target-blank': [2],
        'react/jsx-no-undef': [2],
        'react/jsx-pascal-case': [2, {
            allowAllCaps: true
        }],
        'react/jsx-sort-props': [2, {
            shorthandFirst: true,
            callbacksLast: true
        }],
        'react/jsx-space-before-closing': [2, 'always'],
        'react/jsx-uses-react': [2],
        'react/jsx-uses-vars': [2],
        'react/jsx-wrap-multilines': [2],
    },
    plugins: ['react'],
    extends: ['plugin:react/recommended']
};
<|endoftext|>


<commit_before>import Template from "./template";
import paper from "paper";

export  default class Pump extends Template{
    constructor(){
        super();
    }

    __setupDefinitions() {
        this.__unique = {
            "position": "Point"
        };

        this.__heritable = {
            "rotation": "Float",
            "length": "Float",
            "width": "Float",
            "height": "Float",
            "spacing": "Float",
            "flowChannelWidth":"Float"
        };

        this.__defaults = {
            "rotation": 0,
            "width": 600,
            "length": 300,
            "height": 250,
            "spacing": 1000,
            "flowChannelWidth":300
        };

        this.__units = {
            "rotation": "&deg",
            "length": "μm",
            "width": "μm",
            "height": "μm",
            "spacing": "μm",
            "flowChannelWidth":"μm"
        };

        this.__minimum = {
            "rotation": 0,
            "width": 30,
            "length": 120,
            "height": 10,
            "spacing": 10,
            "flowChannelWidth":1
        };

        this.__maximum = {
            "rotation": 180,
            "width": 6000,
            "length": 24 * 1000,
            "height": 1200,
            "spacing": 10000,
            "flowChannelWidth":10000
        };

        this.__featureParams = {
            position: "position",
            length: "length",
            width: "width",
            rotation: "rotation",
            spacing: "spacing",
            flowChannelWidth: "flowChannelWidth"

        };

        this.__targetParams = {
            length: "length",
            width: "width",
            rotation: "rotation",
            spacing: "spacing",
            flowChannelWidth: "flowChannelWidth"

        };

        this.__placementTool = "componentPositionTool";

        this.__toolParams = {
            position: "position"
        };

        this.__mint = "MUX";
    }

    __drawFlow(params){
        let rec;
        let position = params["position"];
        let px = position[0];
        let py = position[1];
        let l = params["length"];
        let w = params["width"];
        let color = params["color"];
        let rotation = params["rotation"];
        let spacing = params["spacing"];
        let channelwidth = params["flowChannelWidth"];

        let startX = px - w / 2;
        let startY = py - l / 2;
        let endX = px + w / 2;
        let endY = py + l / 2;

        let ret = new paper.CompoundPath();

        let startPoint = new paper.Point(startX, startY);
        let endPoint = new paper.Point(endX, endY);

        rec = paper.Path.Rectangle({
            from: new paper.Point(px - channelwidth/2, py - spacing - l/2),
            to: new paper.Point(px + channelwidth/2, py + spacing + l/2),
        });

        ret.addChild(rec);

        ret.fillColor = color;
        return ret.rotate(rotation, px, py);

    }

    __drawControl(params){
        let rec;
        let position = params["position"];
        let px = position[0];
        let py = position[1];
        let l = params["length"];
        let w = params["width"];
        let color = params["color"];
        let rotation = params["rotation"];
        let spacing = params["spacing"];

        let startX = px - w / 2;
        let startY = py - l / 2;
        let endX = px + w / 2;
        let endY = py + l / 2;

        let ret = new paper.CompoundPath();

        let startPoint = new paper.Point(startX, startY);
        let endPoint = new paper.Point(endX, endY);

        rec = paper.Path.Rectangle({
            from: startPoint,
            to: endPoint,
            radius: 0,
            fillColor: color,
            strokeWidth: 0
        });

        ret.addChild(rec);

        let topcenter = new paper.Point(px, py - spacing);

        rec = paper.Path.Rectangle({
            from: new paper.Point(topcenter.x - w/2, topcenter.y - l/2),
            to: new paper.Point(topcenter.x + w/2, topcenter.y + l/2)
        });

        ret.addChild(rec);

        let bottomcenter = new paper.Point(px, py + spacing);
        rec = paper.Path.Rectangle({
            from: new paper.Point(bottomcenter.x - w/2, bottomcenter.y - l/2),
            to: new paper.Point(bottomcenter.x + w/2, bottomcenter.y + l/2)
        });

        ret.addChild(rec);

        ret.fillColor = color;
        return ret.rotate(rotation, px, py);

    }

    render2D(params, key) {
        if(key == "FLOW"){
            return this.__drawFlow(params);
        }else if (key == "CONTROL"){
            return this.__drawControl(params);
        }
    }

    render2DTarget(key, params){
        let ret = new paper.CompoundPath();
        let flow = this.render2D(params, "FLOW");
        let control = this.render2D(params, "CONTROL");
        ret.addChild(control);
        ret.addChild(flow);
        ret.fillColor = params["color"];
        ret.fillColor.alpha = 0.5;
        return ret;
    }
}<commit_msg>Fixed bug where pump was being incorrectly serialized to MUX<commit_after>import Template from "./template";
import paper from "paper";

export  default class Pump extends Template{
    constructor(){
        super();
    }

    __setupDefinitions() {
        this.__unique = {
            "position": "Point"
        };

        this.__heritable = {
            "rotation": "Float",
            "length": "Float",
            "width": "Float",
            "height": "Float",
            "spacing": "Float",
            "flowChannelWidth":"Float"
        };

        this.__defaults = {
            "rotation": 0,
            "width": 600,
            "length": 300,
            "height": 250,
            "spacing": 1000,
            "flowChannelWidth":300
        };

        this.__units = {
            "rotation": "&deg",
            "length": "μm",
            "width": "μm",
            "height": "μm",
            "spacing": "μm",
            "flowChannelWidth":"μm"
        };

        this.__minimum = {
            "rotation": 0,
            "width": 30,
            "length": 120,
            "height": 10,
            "spacing": 10,
            "flowChannelWidth":1
        };

        this.__maximum = {
            "rotation": 180,
            "width": 6000,
            "length": 24 * 1000,
            "height": 1200,
            "spacing": 10000,
            "flowChannelWidth":10000
        };

        this.__featureParams = {
            position: "position",
            length: "length",
            width: "width",
            rotation: "rotation",
            spacing: "spacing",
            flowChannelWidth: "flowChannelWidth"

        };

        this.__targetParams = {
            length: "length",
            width: "width",
            rotation: "rotation",
            spacing: "spacing",
            flowChannelWidth: "flowChannelWidth"

        };

        this.__placementTool = "componentPositionTool";

        this.__toolParams = {
            position: "position"
        };

        this.__mint = "PUMP";
    }

    __drawFlow(params){
        let rec;
        let position = params["position"];
        let px = position[0];
        let py = position[1];
        let l = params["length"];
        let w = params["width"];
        let color = params["color"];
        let rotation = params["rotation"];
        let spacing = params["spacing"];
        let channelwidth = params["flowChannelWidth"];

        let startX = px - w / 2;
        let startY = py - l / 2;
        let endX = px + w / 2;
        let endY = py + l / 2;

        let ret = new paper.CompoundPath();

        let startPoint = new paper.Point(startX, startY);
        let endPoint = new paper.Point(endX, endY);

        rec = paper.Path.Rectangle({
            from: new paper.Point(px - channelwidth/2, py - spacing - l/2),
            to: new paper.Point(px + channelwidth/2, py + spacing + l/2),
        });

        ret.addChild(rec);

        ret.fillColor = color;
        return ret.rotate(rotation, px, py);

    }

    __drawControl(params){
        let rec;
        let position = params["position"];
        let px = position[0];
        let py = position[1];
        let l = params["length"];
        let w = params["width"];
        let color = params["color"];
        let rotation = params["rotation"];
        let spacing = params["spacing"];

        let startX = px - w / 2;
        let startY = py - l / 2;
        let endX = px + w / 2;
        let endY = py + l / 2;

        let ret = new paper.CompoundPath();

        let startPoint = new paper.Point(startX, startY);
        let endPoint = new paper.Point(endX, endY);

        rec = paper.Path.Rectangle({
            from: startPoint,
            to: endPoint,
            radius: 0,
            fillColor: color,
            strokeWidth: 0
        });

        ret.addChild(rec);

        let topcenter = new paper.Point(px, py - spacing);

        rec = paper.Path.Rectangle({
            from: new paper.Point(topcenter.x - w/2, topcenter.y - l/2),
            to: new paper.Point(topcenter.x + w/2, topcenter.y + l/2)
        });

        ret.addChild(rec);

        let bottomcenter = new paper.Point(px, py + spacing);
        rec = paper.Path.Rectangle({
            from: new paper.Point(bottomcenter.x - w/2, bottomcenter.y - l/2),
            to: new paper.Point(bottomcenter.x + w/2, bottomcenter.y + l/2)
        });

        ret.addChild(rec);

        ret.fillColor = color;
        return ret.rotate(rotation, px, py);

    }

    render2D(params, key) {
        if(key == "FLOW"){
            return this.__drawFlow(params);
        }else if (key == "CONTROL"){
            return this.__drawControl(params);
        }
    }

    render2DTarget(key, params){
        let ret = new paper.CompoundPath();
        let flow = this.render2D(params, "FLOW");
        let control = this.render2D(params, "CONTROL");
        ret.addChild(control);
        ret.addChild(flow);
        ret.fillColor = params["color"];
        ret.fillColor.alpha = 0.5;
        return ret;
    }
}<|endoftext|>


<commit_before>/*
 * ready
 * Watch for when an element becomes available in the DOM
 * @param {String} selector
 * @param {Function} fn
 */

(function(win){
	'use strict';

	var listeners = [],
	doc = win.document,
	MutationObserver = win.MutationObserver || win.WebKitMutationObserver,
	observer;

	function ready(selector, fn){
		// Append the specifics to an array so that it may be monitored
		listeners.push({
			selector: selector,
			fn: fn
		});
		if(!observer){
			// Use `MutationObserver` to watch for changes in the entire document
			observer = new MutationObserver(check);
			observer.observe(doc.documentElement, {
				childList: true,
				subtree: true
			});
			// Disconnect the mutation observer on unload to avoid memory leaks
			win.addEventListener('unload', observer.disconnect.bind(observer), false);
		}
		// Check elements currently in the DOM
		check();
	};

	// Check all listeners to see if they are ready
	function check(){
		var i = 0, len = listeners.length, n = 0, nLen, listener, elements, element;
		for(; i < len; i++){
			listener = listeners[i];
			elements = doc.querySelectorAll(listener.selector);
			nLen = elements.length;
			for(; n < nLen; n++){
				element = elements[n];
				if(!element.ready){
					element.ready = true;
					listener.fn.call(element, element);
				}
			}
		}
	}

	// Expose `ready`
	win.ready = ready;

})(this);<commit_msg>Fix callback not being invoked for every element<commit_after>/*
 * ready
 * Watch for when an element becomes available in the DOM
 * @param {String} selector
 * @param {Function} fn
 */

(function(win){
	'use strict';

	var listeners = [],
	doc = win.document,
	MutationObserver = win.MutationObserver || win.WebKitMutationObserver,
	observer;

	function ready(selector, fn){
		// Append the specifics to an array so that it may be monitored
		listeners.push({
			selector: selector,
			fn: fn
		});
		if(!observer){
			// Use `MutationObserver` to watch for changes in the entire document
			observer = new MutationObserver(check);
			observer.observe(doc.documentElement, {
				childList: true,
				subtree: true
			});
			// Disconnect the mutation observer on unload to avoid memory leaks
			win.addEventListener('unload', observer.disconnect.bind(observer), false);
		}
		// Check elements currently in the DOM
		check();
	};

	// Check if any elements have been added to the DOM
	function check(){
		for(var i = 0, len = listeners.length, listener, elements; i < len; i++){
			listener = listeners[i];
			// Query for elements matching the specified selector
			elements = doc.querySelectorAll(listener.selector);
			for(var j = 0, jLen = elements.length, element; j < jLen; j++){
				element = elements[j];
				// Make sure the callback isn't invoked with the same element
				// more than once
				if(!element.ready){
					element.ready = true;
					// Invoke the callback with the element
					listener.fn.call(element, element);
				}
			}
		}
	}

	// Expose `ready`
	win.ready = ready;

})(this);<|endoftext|>


<commit_before>/* global app */

app.register({
	name: 'ComicRenderer',
	dependencies: ['jquery'],
	factory: function ($) {
		"use strict";

		var AddImage,
			OnImageLoad,
			Render,
			_comic,
			_imagesLoaded = 0,
			_totalImagesToLoad = 0,
			_img_PanelFrame,
			_img_SpeechBubbleLeft,
			_img_SpeechBubbleRight;

		// Adds the image and begins loading it
		AddImage = function (url) {
			_totalImagesToLoad++;

			var _img = new Image();
			_img.onload = OnImageLoad;
			_img.src = url;
			return _img;
		};

		// Once loaded, if it's the final image, begin rendering to canvas
		OnImageLoad = function () {
				if(++_imagesLoaded >= _totalImagesToLoad){
					Render();
			};
		};

		// Render each panel to the canvas
		Render = function () {
			var _canvas = $('canvas.comic')[0];
			var _ctx = _canvas.getContext('2d');

			_ctx.drawImage(_img_PanelFrame, 0, 0);

			for (var _panelCount = 0; _panelCount < _comic.Panels.length; _panelCount++) {
				var _panel = _comic.Panels[_panelCount],
					_panelXOrigin = ((350 + 10) * _panelCount + 10),
					_panelYOrigin = 10,
					_panelWidth = 350,
					_panelHeight = 450;

				// Draw the background. Should always have a 10px padding around it
				_ctx.drawImage(
					_panel.Background,
					_panelXOrigin,
					_panelYOrigin
				);

				// Draw character 1. Should always be anchored to bottom left
				_ctx.drawImage(
					_panel.Character1,
					_panelXOrigin,
					_panelYOrigin + _panelHeight - _panel.Character1.height
				);

				// Draw character 2. Should always be anchored to bottom right
				_ctx.drawImage(
					_panel.Character2,
					_panelXOrigin + _panelWidth - _panel.Character2.width,
					_panelYOrigin + _panelHeight - _panel.Character2.height
				);

				// Depending on the speech bubble owner, draw a different speech bubble
				_ctx.drawImage(
					( _panel.SpeechBubbleOwner == 1 ? _img_SpeechBubbleLeft : _img_SpeechBubbleRight),
					_panelXOrigin + 10,
					_panelYOrigin + 10
				);
			}
		};

		return function (comic) {
			_comic = comic;

			// Load shared resources
			_img_PanelFrame = AddImage('img/PanelFrame.png'),
			_img_SpeechBubbleLeft = AddImage('img/SpeechLeft.png'),
			_img_SpeechBubbleRight = AddImage('img/SpeechRight.png')

			// Convert each panel's resources to new Image()
			for (var _panelCount = 0; _panelCount < _comic.Panels.length; _panelCount++) {
				var _panel = _comic.Panels[_panelCount];
				_panel.Background = AddImage(_panel.Background);
				_panel.Character1 = AddImage(_panel.Character1);
				_panel.Character2 = AddImage(_panel.Character2);
			}
		};
	}
});
<commit_msg>Flips the second character<commit_after>/* global app */

app.register({
	name: 'ComicRenderer',
	dependencies: ['jquery'],
	factory: function ($) {
		"use strict";

		var AddImage,
			OnImageLoad,
			Render,
			_comic,
			_imagesLoaded = 0,
			_totalImagesToLoad = 0,
			_img_PanelFrame,
			_img_SpeechBubbleLeft,
			_img_SpeechBubbleRight;

		// Adds the image and begins loading it
		AddImage = function (url) {
			_totalImagesToLoad++;

			var _img = new Image();
			_img.onload = OnImageLoad;
			_img.src = url;
			return _img;
		};

		// Once loaded, if it's the final image, begin rendering to canvas
		OnImageLoad = function () {
				if(++_imagesLoaded >= _totalImagesToLoad){
					Render();
			};
		};

		// Render each panel to the canvas
		Render = function () {
			var _canvas = $('canvas.comic')[0];
			var _ctx = _canvas.getContext('2d');

			_ctx.drawImage(_img_PanelFrame, 0, 0);

			for (var _panelCount = 0; _panelCount < _comic.Panels.length; _panelCount++) {
				var _panel = _comic.Panels[_panelCount],
					_panelXOrigin = ((350 + 10) * _panelCount + 10),
					_panelYOrigin = 10,
					_panelWidth = 350,
					_panelHeight = 450;

				// Draw the background. Should always have a 10px padding around it
				_ctx.drawImage(
					_panel.Background,
					_panelXOrigin,
					_panelYOrigin
				);

				// Draw character 1. Should always be anchored to bottom left
				_ctx.drawImage(
					_panel.Character1,
					_panelXOrigin,
					_panelYOrigin + _panelHeight - _panel.Character1.height
				);

				// Draw character 2. Should always be anchored to bottom right
				_ctx.save();
				_ctx.scale(-1, 1);
				_ctx.drawImage(
					_panel.Character2,
					-(_panelXOrigin + _panelWidth),
					_panelYOrigin + _panelHeight - _panel.Character2.height
				);
				_ctx.restore();

				// Depending on the speech bubble owner, draw a different speech bubble
				_ctx.drawImage(
					( _panel.SpeechBubbleOwner == 1 ? _img_SpeechBubbleLeft : _img_SpeechBubbleRight),
					_panelXOrigin + 10,
					_panelYOrigin + 10
				);
			}
		};

		return function (comic) {
			_comic = comic;

			// Load shared resources
			_img_PanelFrame = AddImage('img/PanelFrame.png'),
			_img_SpeechBubbleLeft = AddImage('img/SpeechLeft.png'),
			_img_SpeechBubbleRight = AddImage('img/SpeechRight.png')

			// Convert each panel's resources to new Image()
			for (var _panelCount = 0; _panelCount < _comic.Panels.length; _panelCount++) {
				var _panel = _comic.Panels[_panelCount];
				_panel.Background = AddImage(_panel.Background);
				_panel.Character1 = AddImage(_panel.Character1);
				_panel.Character2 = AddImage(_panel.Character2);
			}
		};
	}
});
<|endoftext|>


<commit_before>import React, {Component, PropTypes} from "react";

// actions
import ImageActions from '../../actions/ImageActions';

// stores
import ImageStore from '../../stores/ImageStore';
import UserStore from '../../stores/UserStore';

// components
import AuthorityButtonCreate from '../common/authority/AuthorityButtonCreate.react.js';
import AuthorityButtonDelete from '../common/authority/AuthorityButtonDelete.react.js';

// constatns
import Constants from '../../constants/NoteeConstants';

// utils
import AuthorityUtil from '../../utils/AuthorityUtil';

export default class ImageSection extends Component {

    constructor(props) {
        super(props);
        this.state = {
            images: [],
            upload_file: null,
            tap_image: "",
            now_user: ""
        };

        // imageSection
        this.setImages = this.setImages.bind(this);
        this.clickImage = this.clickImage.bind(this);
        this.uploadImage = this.uploadImage.bind(this);
        this.deleteImage = this.deleteImage.bind(this);

        // eventemit
        this.deleteSuccessed = this.deleteSuccessed.bind(this);

        // ajax
        this.ajaxLoaded = this.ajaxLoaded.bind(this);
        this.ajaxNowUserLoaded = this.ajaxNowUserLoaded.bind(this);

        // handles
        this.handleChangeImage = this.handleChangeImage.bind(this);
    }

    componentDidMount() {
        ImageStore.addChangeListener(Constants.IMAGE_CREATE, this.setImages);
        ImageStore.addChangeListener(Constants.IMAGE_DELETE, this.setImages);
    }

    componentWillMount() {
        ImageStore.loadImages(this.ajaxLoaded);
        UserStore.loadUserByToken(this.ajaxNowUserLoaded);
    }

    ajaxLoaded(content){
        if(!content){return;}
        this.setState({images: content});
    }

    ajaxNowUserLoaded(content) {
        this.setState({now_user: content});
    }

    render() {
        AuthorityUtil.checkAuthority("ImageSection", this.state.now_user);

        var style = {
            image: {
                header: {
                    width: "100%",
                    height: "10%",
                    float: "left",
                    backgroundColor: "rgba(255, 255, 255, 0.9)"
                },
                left: {
                    width: "70%",
                    height: "80%",
                    paddingTop: "30px",
                    float: "left",
                    overflowY: "scroll"
                },
                right: {
                    width: "30%",
                    height: "90%",
                    float: "left"
                },
                image: {
                    width: "200px",
                    height: "auto",
                    float: "left",
                    marginRight: "10px",
                    marginBottom: "10px"
                },
                preview: {
                    width: "90%",
                    height: "auto",
                    marginLeft: "5%",
                    paddingTop: "30px",
                    float: "left"
                }
            }
        }

        return (

                    <input
                        type="file"
                        ref="image"
                        onChange={this.handleChangeImage}
                    />

                        <AuthorityButtonCreate
                            className="mt_15"
                            modelName="Image"
                            now_user={this.state.now_user}
                            createMethod={this.uploadImage}
                        />

                    {this.state.images.map((image)=>{
                        return(

                        );
                    })}

                        <AuthorityButtonDelete
                            modelName="Image"
                            now_user={this.state.now_user}
                            deleteMethod={this.deleteImage}
                        />

        );
    }

    setImages() {
        ImageStore.loadImages(this.ajaxLoaded);
    }

    clickImage(e) {
        this.setState({tap_image: e.target.src});
    }

    uploadImage() {
        ImageActions.create(this.state.upload_file);
    }

    deleteImage() {
        ImageActions.delete(this.state.tap_image);
    }

    deleteSuccessed(){
        ImageStore.loadImages(this.ajaxLoaded);
        this.setState({tap_image: null});
    }

    handleChangeImage(e) {
        var files = e.target.files;
        this.setState({upload_file: files[0]});
    }

};
<commit_msg>integrate eventemitter stores -> EventUtil file & add remove Image EventListener<commit_after>import React, {Component, PropTypes} from "react";

// actions
import ImageActions from '../../actions/ImageActions';

// stores
import ImageStore from '../../stores/ImageStore';
import UserStore from '../../stores/UserStore';

// components
import AuthorityButtonCreate from '../common/authority/AuthorityButtonCreate.react.js';
import AuthorityButtonDelete from '../common/authority/AuthorityButtonDelete.react.js';

// constatns
import Constants from '../../constants/NoteeConstants';

// utils
import AuthorityUtil from '../../utils/AuthorityUtil';
import EventUtil from '../../utils/EventUtil';

export default class ImageSection extends Component {

    constructor(props) {
        super(props);
        this.state = {
            images: [],
            upload_file: null,
            tap_image: "",
            now_user: ""
        };

        // imageSection
        this.setImages = this.setImages.bind(this);
        this.clickImage = this.clickImage.bind(this);
        this.uploadImage = this.uploadImage.bind(this);
        this.deleteImage = this.deleteImage.bind(this);

        // eventemit
        this.deleteSuccessed = this.deleteSuccessed.bind(this);

        // ajax
        this.ajaxLoaded = this.ajaxLoaded.bind(this);
        this.ajaxNowUserLoaded = this.ajaxNowUserLoaded.bind(this);

        // handles
        this.handleChangeImage = this.handleChangeImage.bind(this);
    }

    componentDidMount() {
        EventUtil.addChangeListener(Constants.IMAGE_CREATE, this.setImages);
        EventUtil.addChangeListener(Constants.IMAGE_DELETE, this.setImages);
    }

    componentWillUnmount(){
        EventUtil.removeChangeListener(Constants.IMAGE_CREATE, this.setImages);
        EventUtil.removeChangeListener(Constants.IMAGE_DELETE, this.setImages);
    }

    componentWillMount() {
        ImageStore.loadImages(this.ajaxLoaded);
        UserStore.loadUserByToken(this.ajaxNowUserLoaded);
    }

    ajaxLoaded(content){
        if(!content){return;}
        this.setState({images: content});
    }

    ajaxNowUserLoaded(content) {
        this.setState({now_user: content});
    }

    render() {
        AuthorityUtil.checkAuthority("ImageSection", this.state.now_user);

        var style = {
            image: {
                header: {
                    width: "100%",
                    height: "10%",
                    float: "left",
                    backgroundColor: "rgba(255, 255, 255, 0.9)"
                },
                left: {
                    width: "70%",
                    height: "80%",
                    paddingTop: "30px",
                    float: "left",
                    overflowY: "scroll"
                },
                right: {
                    width: "30%",
                    height: "90%",
                    float: "left"
                },
                image: {
                    width: "200px",
                    height: "auto",
                    float: "left",
                    marginRight: "10px",
                    marginBottom: "10px"
                },
                preview: {
                    width: "90%",
                    height: "auto",
                    marginLeft: "5%",
                    paddingTop: "30px",
                    float: "left"
                }
            }
        }

        return (

                    <input
                        type="file"
                        ref="image"
                        onChange={this.handleChangeImage}
                    />

                        <AuthorityButtonCreate
                            className="mt_15"
                            modelName="Image"
                            now_user={this.state.now_user}
                            createMethod={this.uploadImage}
                        />

                    {this.state.images.map((image)=>{
                        return(

                        );
                    })}

                        <AuthorityButtonDelete
                            modelName="Image"
                            now_user={this.state.now_user}
                            deleteMethod={this.deleteImage}
                        />

        );
    }

    setImages() {
        ImageStore.loadImages(this.ajaxLoaded);
    }

    clickImage(e) {
        this.setState({tap_image: e.target.src});
    }

    uploadImage() {
        ImageActions.create(this.state.upload_file);
    }

    deleteImage() {
        ImageActions.delete(this.state.tap_image);
    }

    deleteSuccessed(){
        ImageStore.loadImages(this.ajaxLoaded);
        this.setState({tap_image: null});
    }

    handleChangeImage(e) {
        var files = e.target.files;
        this.setState({upload_file: files[0]});
    }

};
<|endoftext|>