<commit_before>function $(s) {
    return document.querySelector(s);
}

/**
 * Game of Life simulation and display.
 * @param {HTMLCanvasElement} canvas Render target
 * @param {number} [scale] Size of each cell in pixels (power of 2)
 * @param {number} [p] Starting probability of a cell being alive
 */
function GOL(canvas, scale, p) {
    var gl = this.gl = Igloo.getContext(canvas);
    if (gl == null) {
        alert('Could not initialize WebGL!');
        throw new Error('No WebGL');
    }
    scale = scale || 4;
    var w = canvas.width, h = canvas.height;
    this.viewsize = vec2(w, h);
    this.statesize = vec2(w / scale, h / scale);
    this.lasttick = GOL.now();
    this.fps = 0;

    gl.disable(gl.DEPTH_TEST);
    this.programs = {
        copy: new Igloo.Program(gl, 'glsl/quad.vert', 'glsl/copy.frag'),
        gol: new Igloo.Program(gl, 'glsl/quad.vert', 'glsl/gol.frag')
    };
    this.buffers = {
        quad: new Igloo.Buffer(gl, new Float32Array([
                -1, -1, 1, -1, -1, 1, 1, 1
        ]))
    };
    this.textures = {
        a: this.texture(),
        b: this.texture()
    };
    this.framebuffers = {
        step: gl.createFramebuffer()
    };
    this.state = 'a';
    this.fill(this.state, p == null ? 0.5 : p);
}

/**
 * @returns {number} The epoch in integer seconds
 */
GOL.now = function() {
    return Math.floor(Date.now() / 1000);
};

/**
 * @returns {WebGLTexture} A texture suitable for bearing Life state
 */
GOL.prototype.texture = function() {
    var gl = this.gl;
    var tex = gl.createTexture();
    gl.bindTexture(gl.TEXTURE_2D, tex);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
    gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA,
                  this.statesize.x, this.statesize.y,
                  0, gl.RGBA, gl.UNSIGNED_BYTE, null);
    return tex;
};

/**
 * Set a state texture to random values.
 * @param {string} name Name of the texture to reset (a or b)
 * @param {number} [p] Chance of a cell being alive (0.0 to 1.0)
 * @returns {GOL} this
 */
GOL.prototype.fill = function(name, p) {
    var gl = this.gl, w = this.statesize.x, h = this.statesize.y, fs = 4;
    var rand = new Uint8Array(w * h * fs);
    for (var i = 0; i < rand.length; i += fs) {
        var v = Math.random() < p ? 255 : 0;
        rand[i + 0] = rand[i + 1] = rand[i + 2] = v;
        rand[i + 3] = 255;
    }
    gl.bindTexture(gl.TEXTURE_2D, this.textures[name]);
    gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA,
                  this.statesize.x, this.statesize.y,
                  0, gl.RGBA, gl.UNSIGNED_BYTE, rand);
    gl.bindTexture(gl.TEXTURE_2D, null);
    return this;
};

/**
 * @returns {string} The name of the non-current state texture
 */
GOL.prototype.other = function() {
    return this.state == 'a' ? 'b' : 'a';
};

/**
 * Step the Game of Life state on the GPU without rendering anything.
 * @returns {GOL} this
 */
GOL.prototype.step = function() {
    if (GOL.now() != this.lasttick) {
        $('.fps').innerHTML = this.fps + ' FPS';
        this.lasttick = GOL.now();
        this.fps = 0;
    } else {
        this.fps++;
    }
    var gl = this.gl;
    gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffers.step);
    gl.bindTexture(gl.TEXTURE_2D, this.textures[this.other()]);
    gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0,
                            gl.TEXTURE_2D, this.textures[this.other()], 0);
    gl.activeTexture(gl.TEXTURE0);
    gl.bindTexture(gl.TEXTURE_2D, this.textures[this.state]);
    gl.viewport(0, 0, this.statesize.x, this.statesize.y);
    this.programs.gol.use()
        .attrib('quad', this.buffers.quad, 2)
        .uniform('state', 0, true)
        .uniform('scale', this.statesize)
        .draw(gl.TRIANGLE_STRIP, 4);
    this.state = this.other();
    return this;
};

/**
 * Render the Game of Life state stored on the GPU.
 * @returns {GOL} this
 */
GOL.prototype.draw = function() {
    var gl = this.gl;
    gl.bindFramebuffer(gl.FRAMEBUFFER, null);
    gl.bindTexture(gl.TEXTURE_2D, this.textures[this.state]);
    gl.viewport(0, 0, this.viewsize.x, this.viewsize.y);
    this.programs.copy.use()
        .attrib('quad', this.buffers.quad, 2)
        .uniform('state', 0, true)
        .uniform('scale', this.viewsize)
        .draw(gl.TRIANGLE_STRIP, 4);
    gl.bindTexture(gl.TEXTURE_2D, null);
    return this;
};

/**
 * Iterate the Game of Life state and then draw.
 * @returns {GOL} this
 */
GOL.prototype.all = function() {
    this.step();
    this.draw();
    return this;
};

/**
 * Reset the state to random values.
 * @param {number} [p] Chance of a cell being alive (0.0 to 1.0)
 * @returns {GOL} this
 */
GOL.prototype.reset = function(p) {
    this.fill(this.state, p == null ? 0.5 : p);
    return this;
};

/* Initialize everything. */
var gol = null;
window.addEventListener('load', function() {
    var canvas = $('#life');
    gol = new GOL(canvas).draw();
    setInterval(function(){
        gol.all();
    }, 60);
    canvas.addEventListener('click', function() {
        gol.reset();
    });
});
<commit_msg>Remove unneeded unbinding.<commit_after>function $(s) {
    return document.querySelector(s);
}

/**
 * Game of Life simulation and display.
 * @param {HTMLCanvasElement} canvas Render target
 * @param {number} [scale] Size of each cell in pixels (power of 2)
 * @param {number} [p] Starting probability of a cell being alive
 */
function GOL(canvas, scale, p) {
    var gl = this.gl = Igloo.getContext(canvas);
    if (gl == null) {
        alert('Could not initialize WebGL!');
        throw new Error('No WebGL');
    }
    scale = scale || 4;
    var w = canvas.width, h = canvas.height;
    this.viewsize = vec2(w, h);
    this.statesize = vec2(w / scale, h / scale);
    this.lasttick = GOL.now();
    this.fps = 0;

    gl.disable(gl.DEPTH_TEST);
    this.programs = {
        copy: new Igloo.Program(gl, 'glsl/quad.vert', 'glsl/copy.frag'),
        gol: new Igloo.Program(gl, 'glsl/quad.vert', 'glsl/gol.frag')
    };
    this.buffers = {
        quad: new Igloo.Buffer(gl, new Float32Array([
                -1, -1, 1, -1, -1, 1, 1, 1
        ]))
    };
    this.textures = {
        a: this.texture(),
        b: this.texture()
    };
    this.framebuffers = {
        step: gl.createFramebuffer()
    };
    this.state = 'a';
    this.fill(this.state, p == null ? 0.5 : p);
}

/**
 * @returns {number} The epoch in integer seconds
 */
GOL.now = function() {
    return Math.floor(Date.now() / 1000);
};

/**
 * @returns {WebGLTexture} A texture suitable for bearing Life state
 */
GOL.prototype.texture = function() {
    var gl = this.gl;
    var tex = gl.createTexture();
    gl.bindTexture(gl.TEXTURE_2D, tex);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
    gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA,
                  this.statesize.x, this.statesize.y,
                  0, gl.RGBA, gl.UNSIGNED_BYTE, null);
    return tex;
};

/**
 * Set a state texture to random values.
 * @param {string} name Name of the texture to reset (a or b)
 * @param {number} [p] Chance of a cell being alive (0.0 to 1.0)
 * @returns {GOL} this
 */
GOL.prototype.fill = function(name, p) {
    var gl = this.gl, w = this.statesize.x, h = this.statesize.y, fs = 4;
    var rand = new Uint8Array(w * h * fs);
    for (var i = 0; i < rand.length; i += fs) {
        var v = Math.random() < p ? 255 : 0;
        rand[i + 0] = rand[i + 1] = rand[i + 2] = v;
        rand[i + 3] = 255;
    }
    gl.bindTexture(gl.TEXTURE_2D, this.textures[name]);
    gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA,
                  this.statesize.x, this.statesize.y,
                  0, gl.RGBA, gl.UNSIGNED_BYTE, rand);
    return this;
};

/**
 * @returns {string} The name of the non-current state texture
 */
GOL.prototype.other = function() {
    return this.state == 'a' ? 'b' : 'a';
};

/**
 * Step the Game of Life state on the GPU without rendering anything.
 * @returns {GOL} this
 */
GOL.prototype.step = function() {
    if (GOL.now() != this.lasttick) {
        $('.fps').innerHTML = this.fps + ' FPS';
        this.lasttick = GOL.now();
        this.fps = 0;
    } else {
        this.fps++;
    }
    var gl = this.gl;
    gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffers.step);
    gl.bindTexture(gl.TEXTURE_2D, this.textures[this.other()]);
    gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0,
                            gl.TEXTURE_2D, this.textures[this.other()], 0);
    gl.activeTexture(gl.TEXTURE0);
    gl.bindTexture(gl.TEXTURE_2D, this.textures[this.state]);
    gl.viewport(0, 0, this.statesize.x, this.statesize.y);
    this.programs.gol.use()
        .attrib('quad', this.buffers.quad, 2)
        .uniform('state', 0, true)
        .uniform('scale', this.statesize)
        .draw(gl.TRIANGLE_STRIP, 4);
    this.state = this.other();
    return this;
};

/**
 * Render the Game of Life state stored on the GPU.
 * @returns {GOL} this
 */
GOL.prototype.draw = function() {
    var gl = this.gl;
    gl.bindFramebuffer(gl.FRAMEBUFFER, null);
    gl.bindTexture(gl.TEXTURE_2D, this.textures[this.state]);
    gl.viewport(0, 0, this.viewsize.x, this.viewsize.y);
    this.programs.copy.use()
        .attrib('quad', this.buffers.quad, 2)
        .uniform('state', 0, true)
        .uniform('scale', this.viewsize)
        .draw(gl.TRIANGLE_STRIP, 4);
    return this;
};

/**
 * Iterate the Game of Life state and then draw.
 * @returns {GOL} this
 */
GOL.prototype.all = function() {
    this.step();
    this.draw();
    return this;
};

/**
 * Reset the state to random values.
 * @param {number} [p] Chance of a cell being alive (0.0 to 1.0)
 * @returns {GOL} this
 */
GOL.prototype.reset = function(p) {
    this.fill(this.state, p == null ? 0.5 : p);
    return this;
};

/* Initialize everything. */
var gol = null;
window.addEventListener('load', function() {
    var canvas = $('#life');
    gol = new GOL(canvas).draw();
    setInterval(function(){
        gol.all();
    }, 60);
    canvas.addEventListener('click', function() {
        gol.reset();
    });
});
<|endoftext|>


<commit_before>$("#SetFen").click(function () {
	var fenStr = $("#fenIn").val();
	NewGame(fenStr);
});

$('#TakeButton').click( function () {
	if(GameBoard.hisPly > 0) {
		TakeMove();
		GameBoard.ply = 0;
		SetInitialBoardPieces();
	}
});

$('#NewGameButton').click( function () {
	NewGame(START_FEN);
});

function NewGame(fenStr) {
	ParseFen(fenStr);
	PrintBoard();
	SetInitialBoardPieces();
	CheckAndSet();
}

function ClearAllPieces() {
	$(".Piece").remove();
}

function SetInitialBoardPieces() {

	var sq;
	var sq120;
	var file,rank;
	var rankName;
	var fileName;
	var imageString;
	var pieceFileName;
	var pce;

	ClearAllPieces();

	for(sq = 0; sq < 64; ++sq) {
		sq120 = SQ120(sq);
		pce = GameBoard.pieces[sq120];
		if(pce >= PIECES.wP && pce <= PIECES.bK) {
			AddGUIPiece(sq120, pce);
		}
	}
}

function DeSelectSq(sq) {
	$('.Square').each( function(index) {
		if(PieceIsOnSq(sq, $(this).position().top, $(this).position().left) == BOOL.TRUE) {
				$(this).removeClass('SqSelected');
		}
	} );
}

function SetSqSelected(sq) {
	$('.Square').each( function(index) {
		if(PieceIsOnSq(sq, $(this).position().top, $(this).position().left) == BOOL.TRUE) {
				$(this).addClass('SqSelected');
		}
	} );
}

function ClickedSquare(pageX, pageY) {
	console.log('ClickedSquare() at ' + pageX + ',' + pageY);
	var position = $('#Board').position();

	var workedX = Math.floor(position.left);
	var workedY = Math.floor(position.top);

	pageX = Math.floor(pageX);
	pageY = Math.floor(pageY);

	var file = Math.floor((pageX-workedX) / 60);
	var rank = 7 - Math.floor((pageY-workedY) / 60);

	var sq = FR2SQ(file,rank);

	console.log('Clicked sq:' + PrSq(sq));

	SetSqSelected(sq);

	return sq;
}

$(document).on('click','.Piece', function (e) {
	console.log('Piece Click');

	if(UserMove.from == SQUARES.NO_SQ) {
		UserMove.from = ClickedSquare(e.pageX, e.pageY);
	} else {
		UserMove.to = ClickedSquare(e.pageX, e.pageY);
	}

	MakeUserMove();

});

$(document).on('click','.Square', function (e) {
	console.log('Square Click');
	if(UserMove.from != SQUARES.NO_SQ) {
		UserMove.to = ClickedSquare(e.pageX, e.pageY);
		MakeUserMove();
	}

});

function MakeUserMove() {

	if(UserMove.from != SQUARES.NO_SQ && UserMove.to != SQUARES.NO_SQ) {

		console.log("User Move:" + PrSq(UserMove.from) + PrSq(UserMove.to));

		var parsed = ParseMove(UserMove.from,UserMove.to);

		if(parsed != NOMOVE) {
			MakeMove(parsed);
			PrintBoard();
			MoveGUIPiece(parsed);
			CheckAndSet();
			PreSearch();
		}

		DeSelectSq(UserMove.from);
		DeSelectSq(UserMove.to);

		UserMove.from = SQUARES.NO_SQ;
		UserMove.to = SQUARES.NO_SQ;
	}

}

function PieceIsOnSq(sq, top, left) {

	if( (RanksBrd[sq] == 7 - Math.round(top/60) ) &&
		FilesBrd[sq] == Math.round(left/60) ) {
		return BOOL.TRUE;
	}

	return BOOL.FALSE;

}

function RemoveGUIPiece(sq) {

	$('.Piece').each( function(index) {
		if(PieceIsOnSq(sq, $(this).position().top, $(this).position().left) == BOOL.TRUE) {
			$(this).remove();
		}
	} );

}

function AddGUIPiece(sq, pce) {

	var file = FilesBrd[sq];
	var rank = RanksBrd[sq];
	var rankName = "rank" + (rank+1);
	var	fileName = "file" + (file+1);
	var pieceFileName = "images/" + SideChar[PieceCol[pce]] + PceChar[pce].toUpperCase() + ".png";
	var	imageString = "<image src=\"" + pieceFileName + "\" class=\"Piece " + rankName + " " + fileName + "\"/>";
	$("#Board").append(imageString);
}

function MoveGUIPiece(move) {

	var from = FROMSQ(move);
	var to = TOSQ(move);

	if(move & MFLAGEP) {
		var epRemove;
		if(GameBoard.side == COLOURS.BLACK) {
			epRemove = to - 10;
		} else {
			epRemove = to + 10;
		}
		RemoveGUIPiece(epRemove);
	} else if(CAPTURED(move)) {
		RemoveGUIPiece(to);
	}

	var file = FilesBrd[to];
	var rank = RanksBrd[to];
	var rankName = "rank" + (rank+1);
	var	fileName = "file" + (file+1);

	$('.Piece').each( function(index) {
		if(PieceIsOnSq(from, $(this).position().top, $(this).position().left) == BOOL.TRUE) {
			$(this).removeClass();
			$(this).addClass("Piece " + rankName + " " + fileName);
		}
	} );

	if(move & MFLAGCA) {
		switch(to) {
			case SQUARES.G1: RemoveGUIPiece(SQUARES.H1); AddGUIPiece(SQUARES.F1, PIECES.wR); break;
			case SQUARES.C1: RemoveGUIPiece(SQUARES.A1); AddGUIPiece(SQUARES.D1, PIECES.wR); break;
			case SQUARES.G8: RemoveGUIPiece(SQUARES.H8); AddGUIPiece(SQUARES.F8, PIECES.bR); break;
			case SQUARES.C8: RemoveGUIPiece(SQUARES.A8); AddGUIPiece(SQUARES.D8, PIECES.bR); break;
		}
	} else if (PROMOTED(move)) {
		RemoveGUIPiece(to);
		AddGUIPiece(to, PROMOTED(move));
	}

}

function DrawMaterial() {

	if (GameBoard.pceNum[PIECES.wP]!=0 || GameBoard.pceNum[PIECES.bP]!=0) return BOOL.FALSE;
	if (GameBoard.pceNum[PIECES.wQ]!=0 || GameBoard.pceNum[PIECES.bQ]!=0 ||
					GameBoard.pceNum[PIECES.wR]!=0 || GameBoard.pceNum[PIECES.bR]!=0) return BOOL.FALSE;
	if (GameBoard.pceNum[PIECES.wB] > 1 || GameBoard.pceNum[PIECES.bB] > 1) {return BOOL.FALSE;}
    if (GameBoard.pceNum[PIECES.wN] > 1 || GameBoard.pceNum[PIECES.bN] > 1) {return BOOL.FALSE;}

	if (GameBoard.pceNum[PIECES.wN]!=0 && GameBoard.pceNum[PIECES.wB]!=0) {return BOOL.FALSE;}
	if (GameBoard.pceNum[PIECES.bN]!=0 && GameBoard.pceNum[PIECES.bB]!=0) {return BOOL.FALSE;}

	return BOOL.TRUE;
}

function ThreeFoldRep() {
	var i = 0, r = 0;

	for(i = 0; i < GameBoard.hisPly; ++i) {
		if (GameBoard.history[i].posKey == GameBoard.posKey) {
		    r++;
		}
	}
	return r;
}

function CheckResult() {
	if(GameBoard.fiftyMove >= 100) {
		 $("#GameStatus").text("GAME DRAWN {fifty move rule}");
		 return BOOL.TRUE;
	}

	if (ThreeFoldRep() >= 2) {
     	$("#GameStatus").text("GAME DRAWN {3-fold repetition}");
     	return BOOL.TRUE;
    }

	if (DrawMaterial() == BOOL.TRUE) {
     	$("#GameStatus").text("GAME DRAWN {insufficient material to mate}");
     	return BOOL.TRUE;
    }

    GenerateMoves();

    var MoveNum = 0;
	var found = 0;

	for(MoveNum = GameBoard.moveListStart[GameBoard.ply]; MoveNum < GameBoard.moveListStart[GameBoard.ply + 1]; ++MoveNum)  {

        if ( MakeMove(GameBoard.moveList[MoveNum]) == BOOL.FALSE)  {
            continue;
        }
        found++;
		TakeMove();
		break;
    }

	if(found != 0) return BOOL.FALSE;

	var InCheck = SqAttacked(GameBoard.pList[PCEINDEX(Kings[GameBoard.side],0)], GameBoard.side^1);

	if(InCheck == BOOL.TRUE) {
		if(GameBoard.side == COLOURS.WHITE) {
	      $("#GameStatus").text("GAME OVER {black mates}");
	      return BOOL.TRUE;
        } else {
	      $("#GameStatus").text("GAME OVER {white mates}");
	      return BOOL.TRUE;
        }
	} else {
		$("#GameStatus").text("GAME DRAWN {stalemate}");return BOOL.TRUE;
	}

	return BOOL.FALSE;
}

function CheckAndSet() {
	if(CheckResult() == BOOL.TRUE) {
		GameController.GameOver = BOOL.TRUE;
	} else {
		GameController.GameOver = BOOL.FALSE;
		$("#GameStatus").text('');
	}
}

function PreSearch() {
	if(GameController.GameOver == BOOL.FALSE) {
		SearchController.thinking = BOOL.TRUE;
		setTimeout( function() { StartSearch(); }, 200 );
	}
}

$('#SearchButton').click( function () {
	GameController.PlayerSide = GameController.side ^ 1;
	PreSearch();
});

function StartSearch() {

	SearchController.depth = MAXDEPTH;
	var t = $.now();
	var tt = $('#ThinkTimeChoice').val();

	SearchController.time = parseInt(tt) * 1000;
	SearchPosition();

	MakeMove(SearchController.best);
	MoveGUIPiece(SearchController.best);
	CheckAndSet();
}

<commit_msg>Update gui.js<commit_after>$("#SetFen").click(function () {
	var fenStr = $("#fenIn").val();
	NewGame(fenStr);
});

$('#TakeButton').click( function () {
	if(GameBoard.hisPly > 0) {
		for(i=0;i<=1;i++){
			TakeMove();
			GameBoard.ply = 0;
			SetInitialBoardPieces();
		}
	}
});

$('#NewGameButton').click( function () {
	NewGame(START_FEN);
});

function NewGame(fenStr) {
	ParseFen(fenStr);
	PrintBoard();
	SetInitialBoardPieces();
	CheckAndSet();
}

function ClearAllPieces() {
	$(".Piece").remove();
}

function SetInitialBoardPieces() {

	var sq;
	var sq120;
	var file,rank;
	var rankName;
	var fileName;
	var imageString;
	var pieceFileName;
	var pce;

	ClearAllPieces();

	for(sq = 0; sq < 64; ++sq) {
		sq120 = SQ120(sq);
		pce = GameBoard.pieces[sq120];
		if(pce >= PIECES.wP && pce <= PIECES.bK) {
			AddGUIPiece(sq120, pce);
		}
	}
}

function DeSelectSq(sq) {
	$('.Square').each( function(index) {
		if(PieceIsOnSq(sq, $(this).position().top, $(this).position().left) == BOOL.TRUE) {
				$(this).removeClass('SqSelected');
		}
	} );
}

function SetSqSelected(sq) {
	$('.Square').each( function(index) {
		if(PieceIsOnSq(sq, $(this).position().top, $(this).position().left) == BOOL.TRUE) {
				$(this).addClass('SqSelected');
		}
	} );
}

function ClickedSquare(pageX, pageY) {
	console.log('ClickedSquare() at ' + pageX + ',' + pageY);
	var position = $('#Board').position();

	var workedX = Math.floor(position.left);
	var workedY = Math.floor(position.top);

	pageX = Math.floor(pageX);
	pageY = Math.floor(pageY);

	var file = Math.floor((pageX-workedX) / 60);
	var rank = 7 - Math.floor((pageY-workedY) / 60);

	var sq = FR2SQ(file,rank);

	console.log('Clicked sq:' + PrSq(sq));

	SetSqSelected(sq);

	return sq;
}

$(document).on('click','.Piece', function (e) {
	console.log('Piece Click');

	if(UserMove.from == SQUARES.NO_SQ) {
		UserMove.from = ClickedSquare(e.pageX, e.pageY);
	} else {
		UserMove.to = ClickedSquare(e.pageX, e.pageY);
	}

	MakeUserMove();

});

$(document).on('click','.Square', function (e) {
	console.log('Square Click');
	if(UserMove.from != SQUARES.NO_SQ) {
		UserMove.to = ClickedSquare(e.pageX, e.pageY);
		MakeUserMove();
	}

});

function MakeUserMove() {

	if(UserMove.from != SQUARES.NO_SQ && UserMove.to != SQUARES.NO_SQ) {

		console.log("User Move:" + PrSq(UserMove.from) + PrSq(UserMove.to));

		var parsed = ParseMove(UserMove.from,UserMove.to);

		if(parsed != NOMOVE) {
			MakeMove(parsed);
			PrintBoard();
			MoveGUIPiece(parsed);
			CheckAndSet();
			PreSearch();
		}

		DeSelectSq(UserMove.from);
		DeSelectSq(UserMove.to);

		UserMove.from = SQUARES.NO_SQ;
		UserMove.to = SQUARES.NO_SQ;
	}

}

function PieceIsOnSq(sq, top, left) {

	if( (RanksBrd[sq] == 7 - Math.round(top/60) ) &&
		FilesBrd[sq] == Math.round(left/60) ) {
		return BOOL.TRUE;
	}

	return BOOL.FALSE;

}

function RemoveGUIPiece(sq) {

	$('.Piece').each( function(index) {
		if(PieceIsOnSq(sq, $(this).position().top, $(this).position().left) == BOOL.TRUE) {
			$(this).remove();
		}
	} );

}

function AddGUIPiece(sq, pce) {

	var file = FilesBrd[sq];
	var rank = RanksBrd[sq];
	var rankName = "rank" + (rank+1);
	var	fileName = "file" + (file+1);
	var pieceFileName = "images/" + SideChar[PieceCol[pce]] + PceChar[pce].toUpperCase() + ".png";
	var	imageString = "<image src=\"" + pieceFileName + "\" class=\"Piece " + rankName + " " + fileName + "\"/>";
	$("#Board").append(imageString);
}

function MoveGUIPiece(move) {

	var from = FROMSQ(move);
	var to = TOSQ(move);

	if(move & MFLAGEP) {
		var epRemove;
		if(GameBoard.side == COLOURS.BLACK) {
			epRemove = to - 10;
		} else {
			epRemove = to + 10;
		}
		RemoveGUIPiece(epRemove);
	} else if(CAPTURED(move)) {
		RemoveGUIPiece(to);
	}

	var file = FilesBrd[to];
	var rank = RanksBrd[to];
	var rankName = "rank" + (rank+1);
	var	fileName = "file" + (file+1);

	$('.Piece').each( function(index) {
		if(PieceIsOnSq(from, $(this).position().top, $(this).position().left) == BOOL.TRUE) {
			$(this).removeClass();
			$(this).addClass("Piece " + rankName + " " + fileName);
		}
	} );

	if(move & MFLAGCA) {
		switch(to) {
			case SQUARES.G1: RemoveGUIPiece(SQUARES.H1); AddGUIPiece(SQUARES.F1, PIECES.wR); break;
			case SQUARES.C1: RemoveGUIPiece(SQUARES.A1); AddGUIPiece(SQUARES.D1, PIECES.wR); break;
			case SQUARES.G8: RemoveGUIPiece(SQUARES.H8); AddGUIPiece(SQUARES.F8, PIECES.bR); break;
			case SQUARES.C8: RemoveGUIPiece(SQUARES.A8); AddGUIPiece(SQUARES.D8, PIECES.bR); break;
		}
	} else if (PROMOTED(move)) {
		RemoveGUIPiece(to);
		AddGUIPiece(to, PROMOTED(move));
	}

}

function DrawMaterial() {

	if (GameBoard.pceNum[PIECES.wP]!=0 || GameBoard.pceNum[PIECES.bP]!=0) return BOOL.FALSE;
	if (GameBoard.pceNum[PIECES.wQ]!=0 || GameBoard.pceNum[PIECES.bQ]!=0 ||
					GameBoard.pceNum[PIECES.wR]!=0 || GameBoard.pceNum[PIECES.bR]!=0) return BOOL.FALSE;
	if (GameBoard.pceNum[PIECES.wB] > 1 || GameBoard.pceNum[PIECES.bB] > 1) {return BOOL.FALSE;}
    if (GameBoard.pceNum[PIECES.wN] > 1 || GameBoard.pceNum[PIECES.bN] > 1) {return BOOL.FALSE;}

	if (GameBoard.pceNum[PIECES.wN]!=0 && GameBoard.pceNum[PIECES.wB]!=0) {return BOOL.FALSE;}
	if (GameBoard.pceNum[PIECES.bN]!=0 && GameBoard.pceNum[PIECES.bB]!=0) {return BOOL.FALSE;}

	return BOOL.TRUE;
}

function ThreeFoldRep() {
	var i = 0, r = 0;

	for(i = 0; i < GameBoard.hisPly; ++i) {
		if (GameBoard.history[i].posKey == GameBoard.posKey) {
		    r++;
		}
	}
	return r;
}

function CheckResult() {
	if(GameBoard.fiftyMove >= 100) {
		 $("#GameStatus").text("GAME DRAWN {fifty move rule}");
		 return BOOL.TRUE;
	}

	if (ThreeFoldRep() >= 2) {
     	$("#GameStatus").text("GAME DRAWN {3-fold repetition}");
     	return BOOL.TRUE;
    }

	if (DrawMaterial() == BOOL.TRUE) {
     	$("#GameStatus").text("GAME DRAWN {insufficient material to mate}");
     	return BOOL.TRUE;
    }

    GenerateMoves();

    var MoveNum = 0;
	var found = 0;

	for(MoveNum = GameBoard.moveListStart[GameBoard.ply]; MoveNum < GameBoard.moveListStart[GameBoard.ply + 1]; ++MoveNum)  {

        if ( MakeMove(GameBoard.moveList[MoveNum]) == BOOL.FALSE)  {
            continue;
        }
        found++;
		TakeMove();
		break;
    }

	if(found != 0) return BOOL.FALSE;

	var InCheck = SqAttacked(GameBoard.pList[PCEINDEX(Kings[GameBoard.side],0)], GameBoard.side^1);

	if(InCheck == BOOL.TRUE) {
		if(GameBoard.side == COLOURS.WHITE) {
	      $("#GameStatus").text("GAME OVER {black mates}");
	      return BOOL.TRUE;
        } else {
	      $("#GameStatus").text("GAME OVER {white mates}");
	      return BOOL.TRUE;
        }
	} else {
		$("#GameStatus").text("GAME DRAWN {stalemate}");return BOOL.TRUE;
	}

	return BOOL.FALSE;
}

function CheckAndSet() {
	if(CheckResult() == BOOL.TRUE) {
		GameController.GameOver = BOOL.TRUE;
	} else {
		GameController.GameOver = BOOL.FALSE;
		$("#GameStatus").text('');
	}
}

function PreSearch() {
	if(GameController.GameOver == BOOL.FALSE) {
		SearchController.thinking = BOOL.TRUE;
		setTimeout( function() { StartSearch(); }, 200 );
	}
}

$('#SearchButton').click( function () {
	GameController.PlayerSide = GameController.side ^ 1;
	PreSearch();
});

function StartSearch() {

	SearchController.depth = MAXDEPTH;
	var t = $.now();
	var tt = $('#ThinkTimeChoice').val();

	SearchController.time = parseInt(tt) * 1000;
	SearchPosition();

	MakeMove(SearchController.best);
	MoveGUIPiece(SearchController.best);
	CheckAndSet();
}

<|endoftext|>


<commit_before>//ID3 Decision Tree Algorithm

//main algorithm and prediction functions

var id3 = function(_s,target,features){
    var targets = _.unique(_s.pluck(target));
    if (targets.length == 1){
	console.log("end node! "+targets[0]);
	return {type:"result", val: targets[0], name: targets[0],alias:targets[0]+randomTag() };
    }
    if(features.length == 0){
	console.log("returning the most dominate feature!!!");
	return {type:"result", val: targets[0], name: targets[0], alias:targets[0]+randomTag()}; //this needs to be changed!!
    }
    var bestFeature = maxGain(_s,target,features);
    var remainingFeatures = _.without(features,bestFeature);
    var possibleValues = _.unique(_s.pluck(bestFeature));
    console.log("node for "+bestFeature);
    var node = {name: bestFeature,alias: bestFeature+randomTag()};
    node.type = "feature";
    node.vals = _.map(possibleValues,function(v){
	console.log("creating a branch for "+v);
	var _newS = _(_s.filter(function(x) {return x[bestFeature] == v}));
	var child_node = {name:v,alias:v+randomTag(),type: "feature_value"};
	child_node.child =  id3(_newS,target,remainingFeatures);
	return child_node;

    });
    return node;
}

var predict = function(id3Model,sample) {
    root = id3Model;
    while(root.type != "result"){
	var attr = root.name;
	var sampleVal = sample[attr];
	var childNode = _.detect(root.vals,function(x){return x.name == sampleVal});
	root = childNode.child;
    }
    return root.val;
}

//necessary math functions

var entropy = function(vals){
    var uniqueVals = _.unique(vals);
    var probs = uniqueVals.map(function(x){return prob(x,vals)});
    var logVals = probs.map(function(p){return -p*log2(p) });
    return logVals.reduce(function(a,b){return a+b},0);
}

var gain = function(_s,target,feature){
    var attrVals = _.unique(_s.pluck(feature));
    var setEntropy = entropy(_s.pluck(target));
    var setSize = _s.size();
    var entropies = attrVals.map(function(n){
	var subset = _s.filter(function(x){return x[feature] === n});
	return (subset.length/setSize)*entropy(_.pluck(subset,target));
    });
    var sumOfEntropies =  entropies.reduce(function(a,b){return a+b},0);
    return setEntropy - sumOfEntropies;
}

var maxGain = function(_s,target,features){
    return _.max(features,function(e){return gain(_s,target,e)});
}

var prob = function(val,vals){
    var instances = _.filter(vals,function(x) {return x === val}).length;
    var total = vals.length;
    return instances/total;
}

var log2 = function(n){
    return Math.log(n)/Math.log(2);
}

var randomTag = function(){
    return "_r"+Math.round(Math.random()*10000).toString();
}

//Display logic

var drawGraph = function(id3Model,divId){
//    var g = sigma.init(document.getElementById('canvas'));
//    g = addEdges(id3Model,g);
//    g.draw();
    var g = new Array();
    g = addEdges(id3Model,g).reverse();
    window.g = g;
    var data = google.visualization.arrayToDataTable(g.concat(g));
    var chart = new google.visualization.OrgChart(document.getElementById(divId));
    google.visualization.events.addListener(chart, 'ready',function(){
    _.each($('.google-visualization-orgchart-node'),function(x){
	var oldVal = $(x).html();
	console.log(x);
	if(oldVal){
	    var cleanVal = oldVal.replace(/_r[0-9]+/,'');
	    $(x).html(cleanVal);
	}
});
    });
    chart.draw(data, {allowHtml: true});

}

var addEdges = function(node,g){
    if(node.type == 'feature'){
	_.each(node.vals,function(m){
	    g.push([m.alias,node.alias,'']);
	    g = addEdges(m,g);
	});
	return g;
    }
    if(node.type == 'feature_value'){

	g.push([node.child.alias,node.alias,'']);
	if(node.child.type != 'result'){
	    g = addEdges(node.child,g);
	}
	return g;
    }
    return g;
}

var renderSamples = function(samples,$el,model,target,features){
    _.each(samples,function(s){
	var features_for_sample = _.map(features,function(x){return s[x]});
	$el.append("
"+features_for_sample.join('	')+"	"+predict(model,s)+"	actual: "+s[target]+"
");
    })
}

var renderTrainingData = function(_training,$el,target,features){
    _training.each(function(s){
	$el.append("
"+_.map(features,function(x){return s[x]}).join('	')+"	"+s[target]+"
");
    })
}

var calcError = function(samples,model,target){
    var total = 0;
    var correct = 0;
    _.each(samples,function(s){
	total++;
	var pred = predict(model,s);
	var actual = s[target];
	if(pred == actual){
	    correct++;
	}
    });
    return correct/total;
}
<commit_msg>fixed a bug in the case of more than one value at and of branch, and some small ui stuff<commit_after>//ID3 Decision Tree Algorithm

//main algorithm and prediction functions

var id3 = function(_s,target,features){
    var targets = _.unique(_s.pluck(target));
    if (targets.length == 1){
	console.log("end node! "+targets[0]);
	return {type:"result", val: targets[0], name: targets[0],alias:targets[0]+randomTag() };
    }
    if(features.length == 0){
	console.log("returning the most dominate feature!!!");
	var topTarget = mostCommon(targets);
	return {type:"result", val: topTarget, name: topTarget, alias: topTarget+randomTag()};
    }
    var bestFeature = maxGain(_s,target,features);
    var remainingFeatures = _.without(features,bestFeature);
    var possibleValues = _.unique(_s.pluck(bestFeature));
    console.log("node for "+bestFeature);
    var node = {name: bestFeature,alias: bestFeature+randomTag()};
    node.type = "feature";
    node.vals = _.map(possibleValues,function(v){
	console.log("creating a branch for "+v);
	var _newS = _(_s.filter(function(x) {return x[bestFeature] == v}));
	var child_node = {name:v,alias:v+randomTag(),type: "feature_value"};
	child_node.child =  id3(_newS,target,remainingFeatures);
	return child_node;

    });
    return node;
}

var predict = function(id3Model,sample) {
    root = id3Model;
    while(root.type != "result"){
	var attr = root.name;
	var sampleVal = sample[attr];
	var childNode = _.detect(root.vals,function(x){return x.name == sampleVal});
	root = childNode.child;
    }
    return root.val;
}

//necessary math functions

var entropy = function(vals){
    var uniqueVals = _.unique(vals);
    var probs = uniqueVals.map(function(x){return prob(x,vals)});
    var logVals = probs.map(function(p){return -p*log2(p) });
    return logVals.reduce(function(a,b){return a+b},0);
}

var gain = function(_s,target,feature){
    var attrVals = _.unique(_s.pluck(feature));
    var setEntropy = entropy(_s.pluck(target));
    var setSize = _s.size();
    var entropies = attrVals.map(function(n){
	var subset = _s.filter(function(x){return x[feature] === n});
	return (subset.length/setSize)*entropy(_.pluck(subset,target));
    });
    var sumOfEntropies =  entropies.reduce(function(a,b){return a+b},0);
    return setEntropy - sumOfEntropies;
}

var maxGain = function(_s,target,features){
    return _.max(features,function(e){return gain(_s,target,e)});
}

var prob = function(val,vals){
    var instances = _.filter(vals,function(x) {return x === val}).length;
    var total = vals.length;
    return instances/total;
}

var log2 = function(n){
    return Math.log(n)/Math.log(2);
}

var mostCommon = function(l){
   return  _.sortBy(l,function(a){
	return count(a,l);
    }).reverse()[0];
}

var count = function(a,l){
    return _.filter(l,function(b) { return b === a}).length
}

var randomTag = function(){
    return "_r"+Math.round(Math.random()*1000000).toString();
}

//Display logic

var drawGraph = function(id3Model,divId){
    var g = new Array();
    g = addEdges(id3Model,g).reverse();
    window.g = g;
    var data = google.visualization.arrayToDataTable(g.concat(g));
    var chart = new google.visualization.OrgChart(document.getElementById(divId));
    google.visualization.events.addListener(chart, 'ready',function(){
    _.each($('.google-visualization-orgchart-node'),function(x){
	var oldVal = $(x).html();
	if(oldVal){
	    var cleanVal = oldVal.replace(/_r[0-9]+/,'');
	    $(x).html(cleanVal);
	}
});
    });
    chart.draw(data, {allowHtml: true});

}

var addEdges = function(node,g){
    if(node.type == 'feature'){
	_.each(node.vals,function(m){
	    g.push([m.alias,node.alias,'']);
	    g = addEdges(m,g);
	});
	return g;
    }
    if(node.type == 'feature_value'){

	g.push([node.child.alias,node.alias,'']);
	if(node.child.type != 'result'){
	    g = addEdges(node.child,g);
	}
	return g;
    }
    return g;
}

var renderSamples = function(samples,$el,model,target,features){
    _.each(samples,function(s){
	var features_for_sample = _.map(features,function(x){return s[x]});
	$el.append("
"+features_for_sample.join('	')+"	"+predict(model,s)+"	actual: "+s[target]+"
");
    })
}

var renderTrainingData = function(_training,$el,target,features){
    _training.each(function(s){
	$el.append("
"+_.map(features,function(x){return s[x]}).join('	')+"	"+s[target]+"
");
    })
}

var calcError = function(samples,model,target){
    var total = 0;
    var correct = 0;
    _.each(samples,function(s){
	total++;
	var pred = predict(model,s);
	var actual = s[target];
	if(pred == actual){
	    correct++;
	}
    });
    return correct/total;
}
<|endoftext|>


<commit_before>(function() {
  "use strict";
  var states = {
    MAIN: 0,
    VIEW: 1
  };

  var sequenceTypes = {
    ALPHABETICAL: 0,
    NUMERIC: 1
  };

  var casings = {
    LOWERCASE: 0,
    UPPERCASE: 1,
    MIXED: 2
  };

  var state = null;
  var baseUrl = null;
  var sequences = [];

  function byId(input) {
    return document.getElementById(input);
  }

  function byClass(input) {
    return document.getElementsByClassName(input);
  }

  function byTag(input) {
    return document.getElementsByTagName(input);
  }

  Element.prototype.byId = function(input) {
    return this.getElementById(input);
  };

  Element.prototype.byClass = function(input) {
    return this.getElementsByClassName(input);
  };

  Element.prototype.byTag = function(input) {
    return this.getElementsByTagName(input);
  };

  var casingHtml = '<select class="config"><option value="0">Lowercase</option><option value="1">Uppercase</option><option value="1">Mixed</option></select>';
  var paddingHtml = '<input class="config" type="number" value="0">';

  function addSequence(type, padding, casing, start) {
    var element = document.createElement("div");
    element.className = "sequence";
    element.innerHTML = '<select class="type"><option value="0">Alphabetical</option><option value="1">Numeric</option></select>
' +
      ' ' + casingHtml +
      'Start at: <input type="text" class="start" value="a">';
    byId("sequences").appendChild(element);
    element.byClass("type")[0].addEventListener("change", onTypeChange);
  }

  function addNewSequence() {
    addSequence(sequenceTypes.ALPHABETICAL, 0, casings.LOWERCASE, "a");
  }

  function onTypeChange(e) {
      let elem = this.parentElement.byClass("config")[0];
      if (this.selectedIndex === sequenceTypes.ALPHABETICAL) {
        elem.outerHTML = casingHtml;
        this.parentElement.byClass("start")[0].value = "a";
      }
      else if (this.selectedIndex === sequenceTypes.NUMERIC) {
        elem.outerHTML = paddingHtml;
        this.parentElement.byClass("start")[0].value = "1";
      }
  }

  function removeSequence(index) {
    if (index > -1 && index < sequences.length) {
      sequences.splice(index, 1);
    }
  }

  function doNextSequence() {
    doSequence(++seqIndex);
  }

  function doPrevSequence() {
    doSequence(--seqIndex);
  }

  function doSequence() {
    if (sequences.length < 1) {
      alert("Error!");
    }
    if (seqIndex > sequences.length) {
      seqIndex = 0;
    }
    else if (seqIndex < 0) {
      seqIndex = sequences.length - 1;
    }
    var seq = sequences[seqIndex];
    var image = byId("image");
    var src = baseUrl;
    var name = seqIndex.toString();
    while (name.length < seq.padding) {
      name = "0" + name;
    }
    src += name + ".jpg";
    image.src = src;
    image.alt = src;
  }

  function start() {
    state = states.VIEW;
    buildSequences();
    byId("main").classList.add("hidden");
    byId("view").classList.add("hidden");
    document.addEventListener("keydown", keyCheck);
    doSequence();
  }

  function keyCheck(e) {
    if (e.keyCode === 39) {
      doNextSequence();
    }
    else if (e.keyCode === 37) {
      doPrevSequence();
    }
  }

  var seqIndex = 0;

  function buildSequences() {
    baseUrl = byId("base-url").value;
    sequences = [];
    seqIndex = 0;
    var elems = byClass("sequence");
    for (let i = elems.length - 1; i >= 0; i--) {
      let elem = elems[i];
      let seq = { };
      let type = elem.byClass("type")[0].selectedIndex;
      seq.type = type;
      seq.start = elem.byClass("start")[0].value;
      if (type === sequenceTypes.ALPHABETICAL) {
        seq.padding = 0;
        seq.casing = elem.byClass("config")[0].selectedIndex;
      }
      else if (type === sequenceTypes.NUMERIC) {
        seq.padding = elem.byClass("config")[0].value;
        seq.casing = casings.LOWERCASE;
        seq.start = +seq.start;
      }
      sequences.push(seq);
    }
  }

  function setup() {
    document.removeEventListener("DOMContentLoaded", setup);
    state = states.MAIN;
    byId("add-sequence").addEventListener("click", addNewSequence);
    byId("start").addEventListener("click", start);
  }

  document.addEventListener("DOMContentLoaded", setup);
}).call(this);
<commit_msg>Update img.js<commit_after>(function() {
  "use strict";
  var states = {
    MAIN: 0,
    VIEW: 1
  };

  var sequenceTypes = {
    ALPHABETICAL: 0,
    NUMERIC: 1
  };

  var casings = {
    LOWERCASE: 0,
    UPPERCASE: 1,
    MIXED: 2
  };

  var state = null;
  var baseUrl = null;
  var sequences = [];

  function byId(input) {
    return document.getElementById(input);
  }

  function byClass(input) {
    return document.getElementsByClassName(input);
  }

  function byTag(input) {
    return document.getElementsByTagName(input);
  }

  Element.prototype.byId = function(input) {
    return this.getElementById(input);
  };

  Element.prototype.byClass = function(input) {
    return this.getElementsByClassName(input);
  };

  Element.prototype.byTag = function(input) {
    return this.getElementsByTagName(input);
  };

  var casingHtml = '<select class="config"><option value="0">Lowercase</option><option value="1">Uppercase</option><option value="1">Mixed</option></select>';
  var paddingHtml = '<input class="config" type="number" value="0">';

  function addSequence(type, padding, casing, start) {
    var element = document.createElement("div");
    element.className = "sequence";
    element.innerHTML = '<select class="type"><option value="0">Alphabetical</option><option value="1">Numeric</option></select>
' +
      ' ' + casingHtml +
      'Start at: <input type="text" class="start" value="a">';
    byId("sequences").appendChild(element);
    element.byClass("type")[0].addEventListener("change", onTypeChange);
  }

  function addNewSequence() {
    addSequence(sequenceTypes.ALPHABETICAL, 0, casings.LOWERCASE, "a");
  }

  function onTypeChange(e) {
      let elem = this.parentElement.byClass("config")[0];
      if (this.selectedIndex === sequenceTypes.ALPHABETICAL) {
        elem.outerHTML = casingHtml;
        this.parentElement.byClass("start")[0].value = "a";
      }
      else if (this.selectedIndex === sequenceTypes.NUMERIC) {
        elem.outerHTML = paddingHtml;
        this.parentElement.byClass("start")[0].value = "1";
      }
  }

  function removeSequence(index) {
    if (index > -1 && index < sequences.length) {
      sequences.splice(index, 1);
    }
  }

  function doNextSequence() {
    doSequence(++seqIndex);
  }

  function doPrevSequence() {
    doSequence(--seqIndex);
  }

  function doSequence() {
    if (sequences.length < 1) {
      alert("Error!");
    }
    if (seqIndex > sequences.length) {
      seqIndex = 0;
    }
    else if (seqIndex < 0) {
      seqIndex = sequences.length - 1;
    }
    var seq = sequences[0];
    var image = byId("image");
    var src = baseUrl;
    var name = seqIndex.toString();
    while (name.length < seq.padding) {
      name = "0" + name;
    }
    src += name + ".jpg";
    image.src = src;
    image.alt = src;
  }

  function start() {
    state = states.VIEW;
    buildSequences();
    byId("main").classList.add("hidden");
    byId("view").classList.remove("hidden");
    document.addEventListener("keydown", keyCheck);
    doSequence();
  }

  function keyCheck(e) {
    if (e.keyCode === 39) {
      doNextSequence();
    }
    else if (e.keyCode === 37) {
      doPrevSequence();
    }
  }

  var seqIndex = 0;

  function buildSequences() {
    baseUrl = byId("base-url").value;
    sequences = [];
    seqIndex = 0;
    var elems = byClass("sequence");
    for (let i = elems.length - 1; i >= 0; i--) {
      let elem = elems[i];
      let seq = { };
      let type = elem.byClass("type")[0].selectedIndex;
      seq.type = type;
      seq.start = elem.byClass("start")[0].value;
      if (type === sequenceTypes.ALPHABETICAL) {
        seq.padding = 0;
        seq.casing = elem.byClass("config")[0].selectedIndex;
      }
      else if (type === sequenceTypes.NUMERIC) {
        seq.padding = elem.byClass("config")[0].value;
        seq.casing = casings.LOWERCASE;
        seq.start = +seq.start;
      }
      sequences.push(seq);
    }
  }

  function setup() {
    document.removeEventListener("DOMContentLoaded", setup);
    state = states.MAIN;
    byId("add-sequence").addEventListener("click", addNewSequence);
    byId("start").addEventListener("click", start);
  }

  document.addEventListener("DOMContentLoaded", setup);
}).call(this);
<|endoftext|>


<commit_before>/* *********************************************************************
  Threepenny - JavaScript library

  Additional JavaScript functions that are available
  for Threepenny.
********************************************************************* */
window.jquery_scrollToBottom = function(el){
  $(el).scrollTop(el.scrollHeight);
};

function prim_audio_stop(audio){
  audio.pause();
  audio.currentTime = 0;
}

Haskell.map = function (fun, array) {
  var result;
  for (i=0; i<array.length; i++) {
    result[i] = fun(array[i]);
  }
  return result;
};

// Canvas API additions.
// See http://stackoverflow.com/a/9722502/403805 .
CanvasRenderingContext2D.prototype.clear =
  CanvasRenderingContext2D.prototype.clear || function (preserveTransform) {
    if (preserveTransform) {
      this.save();
      this.setTransform(1, 0, 0, 1, 0, 0);
    }
    this.clearRect(0, 0, this.canvas.width, this.canvas.height);
    if (preserveTransform) {
      this.restore();
    }
};

// Sendvalue
$.fn.sendvalue = function(trigger){
  $(this).each(function(){
    var self = this;
    var el = $(self);
    el.keydown(function(e){
      if(e.which == 13) {
        trigger.call(self,el.val());
        return false;
      }
      else
        return true;
    });
  });
};

// Livechange
$.fn.livechange = function(ms,trigger){
  $(this).each(function(){
    var self = this;
    var el = $(self);
    var last_val;
    var check = function(){
      var val = el.val();
      if(val != last_val)
        trigger.call(self);
      last_val = val;
    };
    var checker;
    var restart = function(){
      clearTimeout(checker);
      checker = setInterval(check,ms);
    };
    restart();
    el.keypress(restart).change(restart);
  });
};

<commit_msg>`lib.js` now features working `Haskell.map` function.<commit_after>/* *********************************************************************
  Threepenny - JavaScript library

  Additional JavaScript functions that are available
  for Threepenny.
********************************************************************* */
window.jquery_scrollToBottom = function(el){
  $(el).scrollTop(el.scrollHeight);
};

function prim_audio_stop(audio){
  audio.pause();
  audio.currentTime = 0;
}

Haskell.map = function (fun, array) {
  var result = [];
  for (i=0; i<array.length; i++) {
    result[i] = fun(array[i]);
  }
  return result;
};

// Canvas API additions.
// See http://stackoverflow.com/a/9722502/403805 .
CanvasRenderingContext2D.prototype.clear =
  CanvasRenderingContext2D.prototype.clear || function (preserveTransform) {
    if (preserveTransform) {
      this.save();
      this.setTransform(1, 0, 0, 1, 0, 0);
    }
    this.clearRect(0, 0, this.canvas.width, this.canvas.height);
    if (preserveTransform) {
      this.restore();
    }
};

// Sendvalue
$.fn.sendvalue = function(trigger){
  $(this).each(function(){
    var self = this;
    var el = $(self);
    el.keydown(function(e){
      if(e.which == 13) {
        trigger.call(self,el.val());
        return false;
      }
      else
        return true;
    });
  });
};

// Livechange
$.fn.livechange = function(ms,trigger){
  $(this).each(function(){
    var self = this;
    var el = $(self);
    var last_val;
    var check = function(){
      var val = el.val();
      if(val != last_val)
        trigger.call(self);
      last_val = val;
    };
    var checker;
    var restart = function(){
      clearTimeout(checker);
      checker = setInterval(check,ms);
    };
    restart();
    el.keypress(restart).change(restart);
  });
};

<|endoftext|>


<commit_before>// Copyright (c) 2016 CanalTP
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

var map = {
    DrawSectionOption: {
        DRAWSTART: 2, // 10
        DRAWEND: 1, // 01
        DRAWBOTH: 3, // 11
        DRAWNEITHER: 0 // 00
    },
    _should_draw_section_start: function(option) {
        return option & 2;
    },
    _should_draw_section_end: function(option) {
        return option & 1;
    },
    STARTTEXT : 'Start',
    ENDTEXT : 'End',
    makeFeatures: {
        region: function(context, json) {
            if (json.shape) {
                var geoJsonShape = wkt2geojson(json.shape);
                return map._makePolygon(context, 'region', geoJsonShape, json, {color : '008ACA'});
            }
            return [];
        },
        section: function(context, json, draw_section_option) {
            var color = json.display_informations;
            switch (json.type) {
            case 'street_network':
                switch (json.mode) {
                case 'bike': color = map.bikeColor; break;
                case 'car': color = map.carColor; break;
                case 'walking': color = map.walkingColor; break;
                }
                break;
            case 'transfer':
                switch (json.transfer_type) {
                case 'guaranteed': color = map.carColor; break;
                case 'extension': color = map.bikeColor; break;
                case 'walking': color = map.walkingColor; break;
                }
                break;
            }
            if (draw_section_option === undefined) {
                draw_section_option = map.DrawSectionOption.DRAWBOTH;
            }
            return map._makeString(context, 'section', json, color)
                .concat(map._makeStopTimesMarker(context, json, color, draw_section_option));
        },
        line: function(context, json) {
            return map._makeString(context, 'line', json, json);
        },
        journey: function(context, json) {
            if (! ('sections' in json)) { return []; }
            var bind = function(s, i, array) {
                var draw_section_option = map.DrawSectionOption.DRAWNEITHER;
                if ( i === 0) { draw_section_option |= map.DrawSectionOption.DRAWSTART; }
                if ( i === (array.length -1) ) { draw_section_option |= map.DrawSectionOption.DRAWEND; }
                return map.makeFeatures.section(context, s, draw_section_option);
            };
            return flatMap(json.sections, bind);
        },
        isochrone: function(context, json) {
            if (! ('geojson' in json)) { return []; }
            var draw_section_option = map.DrawSectionOption.DRAWNEITHER;
            draw_section_option |= map.DrawSectionOption.DRAWSTART;
            var color = context.min_duration_color[json.min_duration];
            console.log(color);
            var place;
            if(('from' in json)) {
                place = json.from;
            }
            if(('to' in json)) {
                place = json.to;
            }
            if (color.color == '00ff00') {
                return map._makePolygon(context, 'isochrone', json.geojson, json, color)
                .concat(map._makeMarker(context, 'place', place));
            } else {
                return map._makePolygon(context, 'isochrone', json.geojson, json, color)
            }
        },
        address: function(context, json) {
            return map._makeMarker(context, 'address', json);
        },
        administrative_region: function(context, json) {
            return map._makeMarker('administrative_region', json);
        },
        stop_area: function(context, json) {
            return map._makeMarker(context, 'stop_area', json);
        },
        stop_point: function(context, json) {
            return map._makeMarker(context, 'stop_point', json);
        },
        place: function(context, json) {
            return map._makeMarker(context, 'place', json);
        },
        poi: function(context, json) {
            return map._makeMarker(context, 'poi', json);
        },
        response: function(context, json) {
            var key = responseCollectionName(json);
            if (key === null) {
                return [];
            }
            var type = getType(key);
            if (!(type in map.makeFeatures)) {
                return [];
            }
            var bind = function(s) {
                return map.makeFeatures[type](context, s);
            };
            return flatMap(json[key], bind);
        }
    },

    hasMap: function(context, type, json) {
        return map.getFeatures(context, type, json).length !== 0;
    },

    getFeatures: function(context, type, json) {
        if (! (map.makeFeatures[type] instanceof Function)) { return []; }
        try {
            return map.makeFeatures[type](context, json);
        } catch (e) {
            console.log(sprintf('map.makeFeatures[%s] thows an exception:', type));
            console.log(e);
            return [];
        }
    },

    run: function(context, type, json) {
        var div = $('
');
        // setting for default path of images used by leaflet
        L.Icon.Default.imagePath='lib/img/leaflet/dist/images';
        var features = [];
        if ((features = map.getFeatures(context, type, json)).length) {
            div.addClass('leaflet');
            var m = L.map(div.get(0)).setView([48.843693, 2.373303], 13);
            L.tileLayer('https://{s}.tile.openstreetmap.se/hydda/full/{z}/{x}/{y}.png', {
	        attribution: 'Tiles courtesy of ' +
                    'OpenStreetMap Sweden' +
                    ' — Map data © ' +
                    'OpenStreetMap'
            }).addTo(m);
            var overlay = L.featureGroup(features).addTo(m);
            setTimeout(function() {
                m.invalidateSize();
                m.fitBounds(overlay.getBounds());
            }, 100);
        } else {
            div.addClass('noMap');
            div.append('No map');
        }
        return div;
    },

    _makeMarker: function(context, type, json, colorJson, useCustomMarker, label) {
        var lat, lon;
        var obj = json;
        switch (type){
            case 'stop_date_time':
                obj = json.stop_point;
                lat = obj.coord.lat;
                lon = obj.coord.lon;
                break;
            case 'place':
                lat = json[json.embedded_type].coord.lat;
                lon = json[json.embedded_type].coord.lon;
                break;
            default:
                lat = json.coord.lat;
                lon = json.coord.lon;
        }
        var sum = summary.run(context, type, json);
        var t = type === 'place' ? json.embedded_type : type;
        var marker;
        if (! useCustomMarker) {
            marker = L.marker([lat, lon]);
        } else {
            var color = '#000000';
            if (colorJson  && colorJson instanceof Object && colorJson.color) {
                color = '#' + colorJson.color;
            }
            marker = L.circleMarker([lat, lon], {color: color, opacity: 1, fillColor: 'white', fillOpacity: 1});
            marker.setRadius(5);
        }
        if (label) {
            marker.bindLabel(label, {noHide: true, className: 'map-marker-label'});
        }
        return [marker.bindPopup(map._makeLink(context, t, obj, sum)[0])];
    },

    bikeColor: { color: 'CED480' },
    carColor: { color: 'EFBF8F' },
    walkingColor: { color: '89C6E5' },

    _makeString: function(context, type, json, colorJson) {
        if (! ( "geojson" in json) || ! json.geojson.coordinates.length) {
            return [];
        }
        if (! (colorJson instanceof Object) || ! (colorJson.color)) {
            colorJson = { color: '000000' };
        }
        var sum = summary.run(context, type, json);
        return [
            L.geoJson(json.geojson, {
                style: {
                    color: getTextColor(colorJson),
                    weight: 6,
                    opacity: 1
                }
            }),
            L.geoJson(json.geojson, {
                style: {
                    color: "#" + colorJson.color,
                    weight: 5,
                    opacity: 1
                }
            }).bindPopup(sum)
        ];
    },
    _makeStopTimesMarker: function(context, json, color, draw_section_option) {
        var stopTimes = json['stop_date_times'];
        var markers = [];

        if (stopTimes) {
            // when section is PT
            stopTimes.forEach(function(st, i) {
                var label = null;
                if (i === 0 &&
                    map._should_draw_section_start(draw_section_option)) {
                    label = map.STARTTEXT;
                }else if (i === (stopTimes.length -1 ) &&
                          map._should_draw_section_end(draw_section_option)) {
                    label = map.ENDTEXT;
                }
                markers = markers.concat(map._makeMarker(context, 'stop_date_time', st, color, true, label));
            });
        } else {
            // when section is Walking
            var from = json.from;
            var to = json.to;
            if (! from || ! to) { return markers; }
            var label_from = null;
            var label_to = null;
            if (map._should_draw_section_start(draw_section_option)) {
                label_from = map.STARTTEXT;
            }
            if (map._should_draw_section_end(draw_section_option)) {
                label_to = map.ENDTEXT;
            }
            markers = markers.concat(map._makeMarker(context, 'place', from, color, true, label_from))
                             .concat(map._makeMarker(context, 'place', to, color, true, label_to));
        }
        return markers;
    },
    _makePolygon: function(context, type, geoJsonCoords, json, colorJson) {
        var sum = summary.run(context, type, json);
        // TODO use link when navitia has debugged the ticket NAVITIAII-2133
        var link = map._makeLink(context, type, json, sum)[0];
        return [
            L.geoJson(geoJsonCoords, {
                color:  '#555555',
                opacity: 1,
                weight: 0.5,
                fillColor:  '#' + colorJson.color,
                fillOpacity: 0.25
            }).bindPopup(link)
        ];
    },
    _makeLink: function(context, type, obj, name) {
        return context.makeLink(type, obj, name);
    }
};
<commit_msg>correction<commit_after>// Copyright (c) 2016 CanalTP
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

var map = {
    DrawSectionOption: {
        DRAWSTART: 2, // 10
        DRAWEND: 1, // 01
        DRAWBOTH: 3, // 11
        DRAWNEITHER: 0 // 00
    },
    _should_draw_section_start: function(option) {
        return option & 2;
    },
    _should_draw_section_end: function(option) {
        return option & 1;
    },
    STARTTEXT : 'Start',
    ENDTEXT : 'End',
    makeFeatures: {
        region: function(context, json) {
            if (json.shape) {
                var geoJsonShape = wkt2geojson(json.shape);
                return map._makePolygon(context, 'region', geoJsonShape, json, {color : '008ACA'});
            }
            return [];
        },
        section: function(context, json, draw_section_option) {
            var color = json.display_informations;
            switch (json.type) {
            case 'street_network':
                switch (json.mode) {
                case 'bike': color = map.bikeColor; break;
                case 'car': color = map.carColor; break;
                case 'walking': color = map.walkingColor; break;
                }
                break;
            case 'transfer':
                switch (json.transfer_type) {
                case 'guaranteed': color = map.carColor; break;
                case 'extension': color = map.bikeColor; break;
                case 'walking': color = map.walkingColor; break;
                }
                break;
            }
            if (draw_section_option === undefined) {
                draw_section_option = map.DrawSectionOption.DRAWBOTH;
            }
            return map._makeString(context, 'section', json, color)
                .concat(map._makeStopTimesMarker(context, json, color, draw_section_option));
        },
        line: function(context, json) {
            return map._makeString(context, 'line', json, json);
        },
        journey: function(context, json) {
            if (! ('sections' in json)) { return []; }
            var bind = function(s, i, array) {
                var draw_section_option = map.DrawSectionOption.DRAWNEITHER;
                if ( i === 0) { draw_section_option |= map.DrawSectionOption.DRAWSTART; }
                if ( i === (array.length -1) ) { draw_section_option |= map.DrawSectionOption.DRAWEND; }
                return map.makeFeatures.section(context, s, draw_section_option);
            };
            return flatMap(json.sections, bind);
        },
        isochrone: function(context, json) {
            if (! ('geojson' in json)) { return []; }
            var draw_section_option = map.DrawSectionOption.DRAWNEITHER;
            draw_section_option |= map.DrawSectionOption.DRAWSTART;
            var color = context.min_duration_color[json.min_duration];
            var place;
            if(('from' in json)) {
                place = json.from;
            }
            if(('to' in json)) {
                place = json.to;
            }
            return map._makePolygon(context, 'isochrone', json.geojson, json, color)
            .concat(map._makeMarker(context, 'place', place));
        },
        address: function(context, json) {
            return map._makeMarker(context, 'address', json);
        },
        administrative_region: function(context, json) {
            return map._makeMarker('administrative_region', json);
        },
        stop_area: function(context, json) {
            return map._makeMarker(context, 'stop_area', json);
        },
        stop_point: function(context, json) {
            return map._makeMarker(context, 'stop_point', json);
        },
        place: function(context, json) {
            return map._makeMarker(context, 'place', json);
        },
        poi: function(context, json) {
            return map._makeMarker(context, 'poi', json);
        },
        response: function(context, json) {
            var key = responseCollectionName(json);
            if (key === null) {
                return [];
            }
            var type = getType(key);
            if (!(type in map.makeFeatures)) {
                return [];
            }
            var bind = function(s) {
                return map.makeFeatures[type](context, s);
            };
            return flatMap(json[key], bind);
        }
    },

    hasMap: function(context, type, json) {
        return map.getFeatures(context, type, json).length !== 0;
    },

    getFeatures: function(context, type, json) {
        if (! (map.makeFeatures[type] instanceof Function)) { return []; }
        try {
            return map.makeFeatures[type](context, json);
        } catch (e) {
            console.log(sprintf('map.makeFeatures[%s] thows an exception:', type));
            console.log(e);
            return [];
        }
    },

    run: function(context, type, json) {
        var div = $('
');
        // setting for default path of images used by leaflet
        L.Icon.Default.imagePath='lib/img/leaflet/dist/images';
        var features = [];
        if ((features = map.getFeatures(context, type, json)).length) {
            div.addClass('leaflet');
            var m = L.map(div.get(0)).setView([48.843693, 2.373303], 13);
            L.tileLayer('https://{s}.tile.openstreetmap.se/hydda/full/{z}/{x}/{y}.png', {
	        attribution: 'Tiles courtesy of ' +
                    'OpenStreetMap Sweden' +
                    ' — Map data © ' +
                    'OpenStreetMap'
            }).addTo(m);
            var overlay = L.featureGroup(features).addTo(m);
            setTimeout(function() {
                m.invalidateSize();
                m.fitBounds(overlay.getBounds());
            }, 100);
        } else {
            div.addClass('noMap');
            div.append('No map');
        }
        return div;
    },

    _makeMarker: function(context, type, json, colorJson, useCustomMarker, label) {
        var lat, lon;
        var obj = json;
        switch (type){
            case 'stop_date_time':
                obj = json.stop_point;
                lat = obj.coord.lat;
                lon = obj.coord.lon;
                break;
            case 'place':
                lat = json[json.embedded_type].coord.lat;
                lon = json[json.embedded_type].coord.lon;
                break;
            default:
                lat = json.coord.lat;
                lon = json.coord.lon;
        }
        var sum = summary.run(context, type, json);
        var t = type === 'place' ? json.embedded_type : type;
        var marker;
        if (! useCustomMarker) {
            marker = L.marker([lat, lon]);
        } else {
            var color = '#000000';
            if (colorJson  && colorJson instanceof Object && colorJson.color) {
                color = '#' + colorJson.color;
            }
            marker = L.circleMarker([lat, lon], {color: color, opacity: 1, fillColor: 'white', fillOpacity: 1});
            marker.setRadius(5);
        }
        if (label) {
            marker.bindLabel(label, {noHide: true, className: 'map-marker-label'});
        }
        return [marker.bindPopup(map._makeLink(context, t, obj, sum)[0])];
    },

    bikeColor: { color: 'CED480' },
    carColor: { color: 'EFBF8F' },
    walkingColor: { color: '89C6E5' },

    _makeString: function(context, type, json, colorJson) {
        if (! ( "geojson" in json) || ! json.geojson.coordinates.length) {
            return [];
        }
        if (! (colorJson instanceof Object) || ! (colorJson.color)) {
            colorJson = { color: '000000' };
        }
        var sum = summary.run(context, type, json);
        return [
            L.geoJson(json.geojson, {
                style: {
                    color: getTextColor(colorJson),
                    weight: 6,
                    opacity: 1
                }
            }),
            L.geoJson(json.geojson, {
                style: {
                    color: "#" + colorJson.color,
                    weight: 5,
                    opacity: 1
                }
            }).bindPopup(sum)
        ];
    },
    _makeStopTimesMarker: function(context, json, color, draw_section_option) {
        var stopTimes = json['stop_date_times'];
        var markers = [];

        if (stopTimes) {
            // when section is PT
            stopTimes.forEach(function(st, i) {
                var label = null;
                if (i === 0 &&
                    map._should_draw_section_start(draw_section_option)) {
                    label = map.STARTTEXT;
                }else if (i === (stopTimes.length -1 ) &&
                          map._should_draw_section_end(draw_section_option)) {
                    label = map.ENDTEXT;
                }
                markers = markers.concat(map._makeMarker(context, 'stop_date_time', st, color, true, label));
            });
        } else {
            // when section is Walking
            var from = json.from;
            var to = json.to;
            if (! from || ! to) { return markers; }
            var label_from = null;
            var label_to = null;
            if (map._should_draw_section_start(draw_section_option)) {
                label_from = map.STARTTEXT;
            }
            if (map._should_draw_section_end(draw_section_option)) {
                label_to = map.ENDTEXT;
            }
            markers = markers.concat(map._makeMarker(context, 'place', from, color, true, label_from))
                             .concat(map._makeMarker(context, 'place', to, color, true, label_to));
        }
        return markers;
    },
    _makePolygon: function(context, type, geoJsonCoords, json, colorJson) {
        var sum = summary.run(context, type, json);
        // TODO use link when navitia has debugged the ticket NAVITIAII-2133
        var link = map._makeLink(context, type, json, sum)[0];
        return [
            L.geoJson(geoJsonCoords, {
                color:  '#555555',
                opacity: 1,
                weight: 0.5,
                fillColor:  '#' + colorJson.color,
                fillOpacity: 0.25
            }).bindPopup(link)
        ];
    },
    _makeLink: function(context, type, obj, name) {
        return context.makeLink(type, obj, name);
    }
};
<|endoftext|>


<commit_before>

var Hydda = L.tileLayer('http://{s}.tile.openstreetmap.se/hydda/full/{z}/{x}/{y}.png', {
	attribution: 'Tiles courtesy of OpenStreetMap Sweden — Map data © OpenStreetMap'
});

var OpenStreetMap = L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
	attribution: '© OpenStreetMap contributors, CC-BY-SA'
});

var OpenCycleMap = L.tileLayer('http://{s}.tile.thunderforest.com/cycle/{z}/{x}/{y}.png', {
	attribution: '© OpenCycleMap, © OpenStreetMap contributors, CC-BY-SA'
});

var mypoints = new L.LayerGroup();

var baseMaps = {
	"Hydda": Hydda,
	"OpenStreetMap Carto": OpenStreetMap,
	"OpenCycloMap": OpenCycleMap
};

var overlayMaps = {
	//   "My Points": mypoints,
};

var mymap = new L.Map('mapid', {
	layers: [Hydda],
	center: [49.75, 13.35],
	zoom: 13,
	fullscreenControl: true
});

var layerControl = L.control.layers(baseMaps, overlayMaps).addTo(mymap);

var greenIcon = new L.Icon({
	iconUrl: 'icons/green.png',
	shadowUrl: 'icons/shadow.png',
	iconSize: [25, 41],
	iconAnchor: [12, 41],
	popupAnchor: [1, -34],
	shadowSize: [41, 41]
});

var redIcon = new L.Icon({
	iconUrl: 'icons/red.png',
	shadowUrl: 'icons/shadow.png',
	iconSize: [25, 41],
	iconAnchor: [12, 41],
	popupAnchor: [1, -34],
	shadowSize: [41, 41]
});

var blueIcon = new L.Icon({
	iconUrl: 'icons/blue.png',
	shadowUrl: 'icons/shadow.png',
	iconSize: [25, 41],
	iconAnchor: [12, 41],
	popupAnchor: [1, -34],
	shadowSize: [41, 41]
});

var purpleIcon = new L.Icon({
	iconUrl: 'icons/purple.png',
	shadowUrl: 'icons/shadow.png',
	iconSize: [25, 41],
	iconAnchor: [12, 41],
	popupAnchor: [1, -34],
	shadowSize: [41, 41]
});

var orangeIcon = new L.Icon({
	iconUrl: 'icons/orange.png',
	shadowUrl: 'icons/shadow.png',
	iconSize: [25, 41],
	iconAnchor: [12, 41],
	popupAnchor: [1, -34],
	shadowSize: [41, 41]
});

var yellowIcon = new L.Icon({
	iconUrl: 'icons/yellow.png',
	shadowUrl: 'icons/shadow.png',
	iconSize: [25, 41],
	iconAnchor: [12, 41],
	popupAnchor: [1, -34],
	shadowSize: [41, 41]
});

var greyIcon = new L.Icon({
	iconUrl: 'icons/grey.png',
	shadowUrl: 'icons/shadow.png',
	iconSize: [25, 41],
	iconAnchor: [12, 41],
	popupAnchor: [1, -34],
	shadowSize: [41, 41]
});

var azureIcon = new L.Icon({
	iconUrl: 'icons/azure.png',
	shadowUrl: 'icons/shadow.png',
	iconSize: [25, 41],
	iconAnchor: [12, 41],
	popupAnchor: [1, -34],
	shadowSize: [41, 41]
});

var ochreIcon = new L.Icon({
	iconUrl: 'icons/ochre.png',
	shadowUrl: 'icons/shadow.png',
	iconSize: [25, 41],
	iconAnchor: [12, 41],
	popupAnchor: [1, -34],
	shadowSize: [41, 41]
});

var pinkIcon = new L.Icon({
	iconUrl: 'icons/pink.png',
	shadowUrl: 'icons/shadow.png',
	iconSize: [25, 41],
	iconAnchor: [12, 41],
	popupAnchor: [1, -34],
	shadowSize: [41, 41]
});

var blackIcon = new L.Icon({
	iconUrl: 'icons/black.png',
	shadowUrl: 'icons/shadow.png',
	iconSize: [25, 41],
	iconAnchor: [12, 41],
	popupAnchor: [1, -34],
	shadowSize: [41, 41]
});

var markersCluster = L.markerClusterGroup();

var transportation = new L.LayerGroup().addTo(mymap);
var foodAndDrink = new L.LayerGroup().addTo(mymap);
var carService = new L.LayerGroup().addTo(mymap);
var cultureAndEntertainment = new L.LayerGroup().addTo(mymap);
var lodging = new L.LayerGroup().addTo(mymap);
var naturalFeature = new L.LayerGroup().addTo(mymap);
var other = new L.LayerGroup().addTo(mymap);
var outdoor = new L.LayerGroup().addTo(mymap);
var professionalAndPublic = new L.LayerGroup().addTo(mymap);
var shoppingAndService = new L.LayerGroup().addTo(mymap);

var transportation2 = new L.LayerGroup();
var foodAndDrink2 = new L.LayerGroup();
var carService2 = new L.LayerGroup();
var cultureAndEntertainment2 = new L.LayerGroup();
var lodging2 = new L.LayerGroup();
var naturalFeature2 = new L.LayerGroup();
var other2 = new L.LayerGroup();
var outdoor2 = new L.LayerGroup();
var professionalAndPublic2 = new L.LayerGroup();
var shoppingAndService2 = new L.LayerGroup();

var selectAll = new L.LayerGroup().addTo(mymap);
var bug = new L.LayerGroup().addTo(mymap);

var num1 = 0, num2 = 0, num3 = 0, num4 = 0, num5 = 0, num6 = 0, num7 = 0, num8 = 0, num9 = 0, num10 = 0;

mymap.on('overlayremove', function (eo) {
	if (eo.layer === selectAll) {
		mymap.removeLayer(transportation);
		mymap.removeLayer(foodAndDrink);
		mymap.removeLayer(carService);
		mymap.removeLayer(cultureAndEntertainment);
		mymap.removeLayer(lodging);
		mymap.removeLayer(naturalFeature);
		mymap.removeLayer(other);
		mymap.removeLayer(outdoor);
		mymap.removeLayer(professionalAndPublic);
		mymap.removeLayer(shoppingAndService);
		layerControl.removeLayer(bug);
	} else if (eo.layer === transportation) {
		removeLayer(markersCluster, transportation2);
	} else if (eo.layer === foodAndDrink) {
		removeLayer(markersCluster, foodAndDrink2);
	} else if (eo.layer === carService) {
		removeLayer(markersCluster, carService2);
	} else if (eo.layer === cultureAndEntertainment) {
		removeLayer(markersCluster, cultureAndEntertainment2);
	} else if (eo.layer === lodging) {
		removeLayer(markersCluster, lodging2);
	} else if (eo.layer === naturalFeature) {
		removeLayer(markersCluster, naturalFeature2);
	} else if (eo.layer === other) {
		removeLayer(markersCluster, other2);
	} else if (eo.layer === outdoor) {
		removeLayer(markersCluster, outdoor2);
	} else if (eo.layer === professionalAndPublic) {
		removeLayer(markersCluster, professionalAndPublic2);
	} else if (eo.layer === shoppingAndService) {
		removeLayer(markersCluster, shoppingAndService2);
	}
});

mymap.on('overlayadd', function (eo) {
	if (eo.layer === selectAll) {
		mymap.addLayer(transportation);
		mymap.addLayer(foodAndDrink);
		mymap.addLayer(carService);
		mymap.addLayer(cultureAndEntertainment);
		mymap.addLayer(lodging);
		mymap.addLayer(naturalFeature);
		mymap.addLayer(other);
		mymap.addLayer(outdoor);
		mymap.addLayer(professionalAndPublic);
		mymap.addLayer(shoppingAndService);
		layerControl.removeLayer(bug);
	} else if (eo.layer === transportation) {
		addLayer(markersCluster, transportation2);
	} else if (eo.layer === foodAndDrink) {
		addLayer(markersCluster, foodAndDrink2);
	} else if (eo.layer === carService) {
		addLayer(markersCluster, carService2);
	} else if (eo.layer === cultureAndEntertainment) {
		addLayer(markersCluster, cultureAndEntertainment2);
	} else if (eo.layer === lodging) {
		addLayer(markersCluster, lodging2);
	} else if (eo.layer === naturalFeature) {
		addLayer(markersCluster, naturalFeature2);
	} else if (eo.layer === other) {
		addLayer(markersCluster, other2);
	} else if (eo.layer === outdoor) {
		addLayer(markersCluster, outdoor2);
	} else if (eo.layer === professionalAndPublic) {
		addLayer(markersCluster, professionalAndPublic2);
	} else if (eo.layer === shoppingAndService) {
		addLayer(markersCluster, shoppingAndService2);
	}
});

function removeLayer(cluster, layer) {
	cluster.removeLayer(layer);
}
function addLayer(cluster, layer) {
	cluster.addLayer(layer);
}

function refreshLayer(center) {
	layerControl.removeLayer(selectAll);
	layerControl.removeLayer(transportation);
	layerControl.removeLayer(foodAndDrink);
	layerControl.removeLayer(carService);
	layerControl.removeLayer(cultureAndEntertainment);
	layerControl.removeLayer(lodging);
	layerControl.removeLayer(naturalFeature);
	layerControl.removeLayer(other);
	layerControl.removeLayer(outdoor);
	layerControl.removeLayer(professionalAndPublic);
	layerControl.removeLayer(shoppingAndService);

	layerControl.addOverlay(selectAll, 'Un/check all');
	layerControl.addOverlay(transportation, "Transportation (" + num1 + ")");
	layerControl.addOverlay(foodAndDrink, "Food and Drink (" + num2 + ")");
	layerControl.addOverlay(carService, "Car Service (" + num3 + ")");
	layerControl.addOverlay(cultureAndEntertainment, "Culture and Entertainment (" + num4 + ")");
	layerControl.addOverlay(lodging, "Lodging (" + num5 + ")");
	layerControl.addOverlay(naturalFeature, "Natural Feature (" + num6 + ")");
	layerControl.addOverlay(other, "Other (" + num7 + ")");
	layerControl.addOverlay(outdoor, "Outdoor (" + num8 + ")");
	layerControl.addOverlay(professionalAndPublic, "Professional and Public (" + num9 + ")");
	layerControl.addOverlay(shoppingAndService, "Shopping and Service (" + num10 + ")");

	mymap.addLayer(selectAll);
	mymap.addLayer(transportation);
	mymap.addLayer(foodAndDrink);
	mymap.addLayer(carService);
	mymap.addLayer(cultureAndEntertainment);
	mymap.addLayer(lodging);
	mymap.addLayer(naturalFeature);
	mymap.addLayer(other);
	mymap.addLayer(outdoor);
	mymap.addLayer(professionalAndPublic);
	mymap.addLayer(shoppingAndService);

	mymap.panTo([center[0], center[1]]);
}
<commit_msg>🐛 Set OSM Carto as default tiles<commit_after>

//TODO: Hydda not loading
var Hydda = L.tileLayer('http://{s}.tile.openstreetmap.se/hydda/full/{z}/{x}/{y}.png', {
	attribution: 'Tiles courtesy of OpenStreetMap Sweden — Map data © OpenStreetMap'
});

var OpenStreetMap = L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
	attribution: '© OpenStreetMap contributors, CC-BY-SA'
});

var OpenCycleMap = L.tileLayer('http://{s}.tile.thunderforest.com/cycle/{z}/{x}/{y}.png', {
	attribution: '© OpenCycleMap, © OpenStreetMap contributors, CC-BY-SA'
});

var mypoints = new L.LayerGroup();

var baseMaps = {
	//"Hydda": Hydda,
	"OpenStreetMap Carto": OpenStreetMap,
	"OpenCycleMap": OpenCycleMap
};

var overlayMaps = {
	//   "My Points": mypoints,
};

var mymap = new L.Map('mapid', {
	layers: [OpenStreetMap],
	center: [49.75, 13.35],
	zoom: 13,
	fullscreenControl: true
});

var layerControl = L.control.layers(baseMaps, overlayMaps).addTo(mymap);

var greenIcon = new L.Icon({
	iconUrl: 'icons/green.png',
	shadowUrl: 'icons/shadow.png',
	iconSize: [25, 41],
	iconAnchor: [12, 41],
	popupAnchor: [1, -34],
	shadowSize: [41, 41]
});

var redIcon = new L.Icon({
	iconUrl: 'icons/red.png',
	shadowUrl: 'icons/shadow.png',
	iconSize: [25, 41],
	iconAnchor: [12, 41],
	popupAnchor: [1, -34],
	shadowSize: [41, 41]
});

var blueIcon = new L.Icon({
	iconUrl: 'icons/blue.png',
	shadowUrl: 'icons/shadow.png',
	iconSize: [25, 41],
	iconAnchor: [12, 41],
	popupAnchor: [1, -34],
	shadowSize: [41, 41]
});

var purpleIcon = new L.Icon({
	iconUrl: 'icons/purple.png',
	shadowUrl: 'icons/shadow.png',
	iconSize: [25, 41],
	iconAnchor: [12, 41],
	popupAnchor: [1, -34],
	shadowSize: [41, 41]
});

var orangeIcon = new L.Icon({
	iconUrl: 'icons/orange.png',
	shadowUrl: 'icons/shadow.png',
	iconSize: [25, 41],
	iconAnchor: [12, 41],
	popupAnchor: [1, -34],
	shadowSize: [41, 41]
});

var yellowIcon = new L.Icon({
	iconUrl: 'icons/yellow.png',
	shadowUrl: 'icons/shadow.png',
	iconSize: [25, 41],
	iconAnchor: [12, 41],
	popupAnchor: [1, -34],
	shadowSize: [41, 41]
});

var greyIcon = new L.Icon({
	iconUrl: 'icons/grey.png',
	shadowUrl: 'icons/shadow.png',
	iconSize: [25, 41],
	iconAnchor: [12, 41],
	popupAnchor: [1, -34],
	shadowSize: [41, 41]
});

var azureIcon = new L.Icon({
	iconUrl: 'icons/azure.png',
	shadowUrl: 'icons/shadow.png',
	iconSize: [25, 41],
	iconAnchor: [12, 41],
	popupAnchor: [1, -34],
	shadowSize: [41, 41]
});

var ochreIcon = new L.Icon({
	iconUrl: 'icons/ochre.png',
	shadowUrl: 'icons/shadow.png',
	iconSize: [25, 41],
	iconAnchor: [12, 41],
	popupAnchor: [1, -34],
	shadowSize: [41, 41]
});

var pinkIcon = new L.Icon({
	iconUrl: 'icons/pink.png',
	shadowUrl: 'icons/shadow.png',
	iconSize: [25, 41],
	iconAnchor: [12, 41],
	popupAnchor: [1, -34],
	shadowSize: [41, 41]
});

var blackIcon = new L.Icon({
	iconUrl: 'icons/black.png',
	shadowUrl: 'icons/shadow.png',
	iconSize: [25, 41],
	iconAnchor: [12, 41],
	popupAnchor: [1, -34],
	shadowSize: [41, 41]
});

var markersCluster = L.markerClusterGroup();

var transportation = new L.LayerGroup().addTo(mymap);
var foodAndDrink = new L.LayerGroup().addTo(mymap);
var carService = new L.LayerGroup().addTo(mymap);
var cultureAndEntertainment = new L.LayerGroup().addTo(mymap);
var lodging = new L.LayerGroup().addTo(mymap);
var naturalFeature = new L.LayerGroup().addTo(mymap);
var other = new L.LayerGroup().addTo(mymap);
var outdoor = new L.LayerGroup().addTo(mymap);
var professionalAndPublic = new L.LayerGroup().addTo(mymap);
var shoppingAndService = new L.LayerGroup().addTo(mymap);

var transportation2 = new L.LayerGroup();
var foodAndDrink2 = new L.LayerGroup();
var carService2 = new L.LayerGroup();
var cultureAndEntertainment2 = new L.LayerGroup();
var lodging2 = new L.LayerGroup();
var naturalFeature2 = new L.LayerGroup();
var other2 = new L.LayerGroup();
var outdoor2 = new L.LayerGroup();
var professionalAndPublic2 = new L.LayerGroup();
var shoppingAndService2 = new L.LayerGroup();

var selectAll = new L.LayerGroup().addTo(mymap);
var bug = new L.LayerGroup().addTo(mymap);

var num1 = 0, num2 = 0, num3 = 0, num4 = 0, num5 = 0, num6 = 0, num7 = 0, num8 = 0, num9 = 0, num10 = 0;

mymap.on('overlayremove', function (eo) {
	if (eo.layer === selectAll) {
		mymap.removeLayer(transportation);
		mymap.removeLayer(foodAndDrink);
		mymap.removeLayer(carService);
		mymap.removeLayer(cultureAndEntertainment);
		mymap.removeLayer(lodging);
		mymap.removeLayer(naturalFeature);
		mymap.removeLayer(other);
		mymap.removeLayer(outdoor);
		mymap.removeLayer(professionalAndPublic);
		mymap.removeLayer(shoppingAndService);
		layerControl.removeLayer(bug);
	} else if (eo.layer === transportation) {
		removeLayer(markersCluster, transportation2);
	} else if (eo.layer === foodAndDrink) {
		removeLayer(markersCluster, foodAndDrink2);
	} else if (eo.layer === carService) {
		removeLayer(markersCluster, carService2);
	} else if (eo.layer === cultureAndEntertainment) {
		removeLayer(markersCluster, cultureAndEntertainment2);
	} else if (eo.layer === lodging) {
		removeLayer(markersCluster, lodging2);
	} else if (eo.layer === naturalFeature) {
		removeLayer(markersCluster, naturalFeature2);
	} else if (eo.layer === other) {
		removeLayer(markersCluster, other2);
	} else if (eo.layer === outdoor) {
		removeLayer(markersCluster, outdoor2);
	} else if (eo.layer === professionalAndPublic) {
		removeLayer(markersCluster, professionalAndPublic2);
	} else if (eo.layer === shoppingAndService) {
		removeLayer(markersCluster, shoppingAndService2);
	}
});

mymap.on('overlayadd', function (eo) {
	if (eo.layer === selectAll) {
		mymap.addLayer(transportation);
		mymap.addLayer(foodAndDrink);
		mymap.addLayer(carService);
		mymap.addLayer(cultureAndEntertainment);
		mymap.addLayer(lodging);
		mymap.addLayer(naturalFeature);
		mymap.addLayer(other);
		mymap.addLayer(outdoor);
		mymap.addLayer(professionalAndPublic);
		mymap.addLayer(shoppingAndService);
		layerControl.removeLayer(bug);
	} else if (eo.layer === transportation) {
		addLayer(markersCluster, transportation2);
	} else if (eo.layer === foodAndDrink) {
		addLayer(markersCluster, foodAndDrink2);
	} else if (eo.layer === carService) {
		addLayer(markersCluster, carService2);
	} else if (eo.layer === cultureAndEntertainment) {
		addLayer(markersCluster, cultureAndEntertainment2);
	} else if (eo.layer === lodging) {
		addLayer(markersCluster, lodging2);
	} else if (eo.layer === naturalFeature) {
		addLayer(markersCluster, naturalFeature2);
	} else if (eo.layer === other) {
		addLayer(markersCluster, other2);
	} else if (eo.layer === outdoor) {
		addLayer(markersCluster, outdoor2);
	} else if (eo.layer === professionalAndPublic) {
		addLayer(markersCluster, professionalAndPublic2);
	} else if (eo.layer === shoppingAndService) {
		addLayer(markersCluster, shoppingAndService2);
	}
});

function removeLayer(cluster, layer) {
	cluster.removeLayer(layer);
}
function addLayer(cluster, layer) {
	cluster.addLayer(layer);
}

function refreshLayer(center) {
	layerControl.removeLayer(selectAll);
	layerControl.removeLayer(transportation);
	layerControl.removeLayer(foodAndDrink);
	layerControl.removeLayer(carService);
	layerControl.removeLayer(cultureAndEntertainment);
	layerControl.removeLayer(lodging);
	layerControl.removeLayer(naturalFeature);
	layerControl.removeLayer(other);
	layerControl.removeLayer(outdoor);
	layerControl.removeLayer(professionalAndPublic);
	layerControl.removeLayer(shoppingAndService);

	layerControl.addOverlay(selectAll, 'Un/check all');
	layerControl.addOverlay(transportation, "Transportation (" + num1 + ")");
	layerControl.addOverlay(foodAndDrink, "Food and Drink (" + num2 + ")");
	layerControl.addOverlay(carService, "Car Service (" + num3 + ")");
	layerControl.addOverlay(cultureAndEntertainment, "Culture and Entertainment (" + num4 + ")");
	layerControl.addOverlay(lodging, "Lodging (" + num5 + ")");
	layerControl.addOverlay(naturalFeature, "Natural Feature (" + num6 + ")");
	layerControl.addOverlay(other, "Other (" + num7 + ")");
	layerControl.addOverlay(outdoor, "Outdoor (" + num8 + ")");
	layerControl.addOverlay(professionalAndPublic, "Professional and Public (" + num9 + ")");
	layerControl.addOverlay(shoppingAndService, "Shopping and Service (" + num10 + ")");

	mymap.addLayer(selectAll);
	mymap.addLayer(transportation);
	mymap.addLayer(foodAndDrink);
	mymap.addLayer(carService);
	mymap.addLayer(cultureAndEntertainment);
	mymap.addLayer(lodging);
	mymap.addLayer(naturalFeature);
	mymap.addLayer(other);
	mymap.addLayer(outdoor);
	mymap.addLayer(professionalAndPublic);
	mymap.addLayer(shoppingAndService);

	mymap.panTo([center[0], center[1]]);
}
<|endoftext|>


<commit_before>//
// Setup map
//

// The ractive passed in needs to have at least 'collection' and
// 'filters' defined as properties
function initMap(ractive, view) {
  var collection, filterAttribute, filtersCollection, scale, legend, initialValues, regionStyle, mapDef, map, mapObject;

  if (ractive == undefined) {
    throw 'Need to pass ractive and view to the Map creator'
  }

  collection = ractive.get('collection');

  // Create scale and legend from view
  mapDef = defineMap(ractive, view, collection);

  map = $(".map").vectorMap(mapDef);
  mapObject = map.vectorMap('get', 'mapObject');

  // Create map definition object
  function defineMap(ractive, view, collection) {
    filterAttribute = view.filterAttribute;
    filtersCollection = new Backbone.Collection(ractive.get('filters').getForAttribute(filterAttribute));
    scale = _.object(filtersCollection.pluck('value'), filtersCollection.pluck('colour'));
    legend = _.object(filtersCollection.pluck('value'), filtersCollection.pluck('title'));
    initialValues = _prepareMapData(collection);
    regionStyle = {
      initial: {
        fill: '#E2E2E2'
      },
      selected: {
        stroke: 'green',
        'stroke-width': 1,
        fill: 'pink'
      },
      hover: {
        fill: 'grey'
      }
    }

    return {
      backgroundColor: '#feba2b',
      map: 'world_merc',
      series: {
        regions: [{
          scale: scale,
          normalizeFunction: 'ordinal',
          attribute: 'fill',
          values: initialValues,
        }]
      },
      regionStyle: regionStyle,
      onRegionClick: function(event, regionCode) {
        _regionClick(event, regionCode);
      },
      onRegionTipShow: function(event, label, code) {
        _regionTip(event, label, code);
      }
    };
  }

  function _regionClick(event, regionCode) {
    var party = collection.findWhere({
      iso2: regionCode
    });
    if (party == undefined) {
      return
    }

    if (ractive.get('selectedParty') == party) {
      ractive.set('selectedParty', false);
    } else {
      ractive.set('selectedParty', party);
    }
  }

  function _regionTip(event, label, code) {
    var party = collection.findWhere({
      iso2: code
    })
    if (party) {
      var status = party.get(filterAttribute);
      label.html(
        '' + label.html() + '
' +
        'Status: ' + status
      );
    }
  }

  function _prepareMapData(collection) {
    return collection.prepareMapData(filterAttribute);
  }

  //
  function updateMap() {
    // Update data and re-render map based on current filter state
    if (app.DEBUG) {
      console.debug('updateMap')
    }
    if (!mapObject) {
      return
    };
    mapObject.reset();
    mapObject.series.regions[0].setValues(_prepareMapData(collection));
    return _zoomToFiltered();
  }

  function _zoomToFiltered() {
    if (app.DEBUG) {
      console.debug('_zoomToFiltered')
    }
    var regionCodes = _.compact(collection.pluck('iso2'));
    if (_.isEmpty(regionCodes)) {
      return
    };
    setTimeout(zoomMapTo(regionCodes), 0);
  }

  function zoomMapTo(regionCodes) {
    if (app.DEBUG) {
      console.debug('zoomMapTo', regionCodes)
    }
    if (!mapObject) {
      return
    };

    if (regionCodes == undefined) {
      mapObject.setFocus({
        scale: mapObject.baseScale,
        x: mapObject.baseTransX,
        y: mapObject.baseTransY
      });
    } else {
      mapObject.setFocus({
        regions: regionCodes
      });
    }
  }

  function showMarkerFor(party) {
    if (app.DEBUG) {
      console.debug('showMarkerFor', party)
    }
    var map = ractive.get('map').mapObject;
    map.removeAllMarkers();
    map.addMarker(party.iso2, [party.lat, party.lon]);
  }

  ractive.observe('geoSearch', function(filterId) {
    console.debug('geoSearch observed by map', filterId)
  }, {
    init: false
  });

  return {
    mapObject: mapObject,
    updateMap: updateMap,
    _zoomToFiltered: _zoomToFiltered,
    zoomMapTo: zoomMapTo,
    showMarkerFor: showMarkerFor
  }
}<commit_msg>some map<commit_after>//
// Setup map
//

// The ractive passed in needs to have at least 'collection' and
// 'filters' defined as properties
function initMap(ractive, view) {
  var collection, filterAttribute, filtersCollection, scale, legend, initialValues, regionStyle, mapDef, map, mapObject;

  if (ractive == undefined) {
    throw 'Need to pass ractive and view to the Map creator'
  }

  collection = ractive.get('collection');

  // Create scale and legend from view
  map = $(".map").vectorMap(defineMap());
  mapObject = map.vectorMap('get', 'mapObject');

  // Create map definition object
  function defineMap() {
    filterAttribute = view.filterAttribute;
    filtersCollection = new Backbone.Collection(ractive.get('filters').getForAttribute(filterAttribute));
    scale = _.object(filtersCollection.pluck('value'), filtersCollection.pluck('colour'));
    legend = _.object(filtersCollection.pluck('value'), filtersCollection.pluck('title'));
    initialValues = _prepareMapData(collection);
    regionStyle = {
      initial: {
        fill: '#E2E2E2'
      },
      selected: {
        stroke: 'green',
        'stroke-width': 1,
        fill: 'pink'
      },
      hover: {
        fill: 'grey'
      }
    }

    return {
      backgroundColor: '#feba2b',
      map: 'world_merc',
      series: {
        regions: [{
          scale: scale,
          normalizeFunction: 'ordinal',
          attribute: 'fill',
          values: initialValues,
        }]
      },
      regionStyle: regionStyle,
      onRegionClick: function(event, regionCode) {
        _regionClick(event, regionCode);
      },
      onMarkerClick: function(event, regionCode) {
        _markerClick(event, regionCode);
      },
      onRegionTipShow: function(event, label, code) {
        _regionTip(event, label, code);
      }
    };
  }

  function _regionClick(event, regionCode) {
    var party = collection.findWhere({
      iso2: regionCode
    });
    if (party == undefined) {
      return
    }

    if (ractive.get('selectedParty') == party) {
      ractive.set('selectedParty', false);
    } else {
      ractive.set('selectedParty', party);
    }
  }

  function _markerClick(event, markerCode) {
    var party = collection.findWhere({iso2: markerCode});
    if (party == undefined) {
      throw 'No Party found for ' + markerCode; return
    } else {
      ractive.set('geoSearch', party)
    }
  }

  function _regionTip(event, label, code) {
    var party = collection.findWhere({
      iso2: code
    })
    if (party) {
      var status = party.get(filterAttribute);
      label.html(
        '' + label.html() + '
' +
        'Status: ' + status
      );
    }
  }

  function _prepareMapData() {
    return collection.prepareMapData(filterAttribute);
  }

  //
  function updateMap() {
    // Update data and re-render map based on current filter state
    if (app.DEBUG) {
      console.debug('updateMap')
    }
    if (!mapObject) {
      return
    };
    mapObject.reset();
    mapObject.series.regions[0].setValues(_prepareMapData(collection));
    return _zoomToFiltered();
  }

  function _zoomToFiltered() {
    if (app.DEBUG) {
      console.debug('_zoomToFiltered')
    }
    var regionCodes = _.compact(collection.pluck('iso2'));
    if (_.isEmpty(regionCodes)) {
      return
    };
    setTimeout(zoomMapTo(regionCodes), 0);
  }

  function zoomMapTo(regionCodes) {
    if (app.DEBUG) {
      console.debug('zoomMapTo', regionCodes)
    }
    if (!mapObject) {
      return
    };

    if (regionCodes == undefined) {
      mapObject.setFocus({
        scale: mapObject.baseScale,
        x: mapObject.baseTransX,
        y: mapObject.baseTransY
      });
    } else {
      mapObject.setFocus({
        regions: regionCodes
      });
    }
  }

  function _addMarkerFor(party) {
    if (app.DEBUG) {console.debug('_addMarkerFor', party) }

    var map = ractive.get('map').mapObject;
    map.removeAllMarkers();
    map.addMarker(party.iso2, [party.lat, party.lon]);
  }

  ractive.observe('geoSearch', function(filterId) {
    console.debug('geoSearch observed by map', filterId)
  }, {
    init: false
  });

  return {
    mapObject: mapObject,
    updateMap: updateMap,
    zoomMapTo: zoomMapTo,
    _addMarkerFor: _addMarkerFor
  }
}<|endoftext|>


<commit_before>//Promlem: Nav links don't have animation when clicked
//Solution: Show nested nav smoothly when clicked

//1. When clicked user clicks nav link
	//1.1 Show nested nav with animation
	//1.2 When user clicks nav link again
		//1.2.1 Go to link
//2. When user clicks on another nav link
	//2.1 Hide other nested navs
	//2.2 Show nested nav of nav link clicked<commit_msg>Update plan in nav.js<commit_after>//Promlem: Nav links don't have animation when clicked
//Solution: Show nested nav smoothly when clicked

//1. Disable showing of nav link on hover
//2. When clicked user clicks nav link
	//2.1 Show nested nav with animation
	//2.2 When user clicks nav link again
		//2.2.1 Go to link
//3. When user clicks on another nav link
	//3.1 Hide other nested navs
	//3.2 Show nested nav of nav link clicked<|endoftext|>