<commit_before>// This will eventually have much more information, including movement costs and such
function Cell(spriteName, type, x, y) {
    this.position = {x: x, y: y};
    this.spriteName = spriteName;
    this.type = type;
}

// Units may deserve their own file eventually, as they will have to track
// attack and defense information for the various weapon types
function Unit(id, player, spriteName, pos, distance, movementType, movement,
              health, maxHealth, nation, name, canMove, attacks, armor) {
    this.id = id;
    this.player = player;
    this.spriteName = spriteName;
    this.pos = pos;
    // The total distance the unit can move
    this.distance = distance;
    // treads, feet, wheels, that sort of thing
    this.movementType = movementType;
    // map of cell types to movement costs, ie plains -> 1.0
    this.movement = movement;
    this.health = health;
    this.maxHealth = maxHealth;
    this.nation = nation;
    this.name = name;
    this.canMove = canMove;
    this.attacks = attacks;
    this.armor = armor;

    this.resetState = function() {
        this.canMove = true;
    }
}

function Player(id, nation, team) {
    this.id = id;
    this.nation = nation;
    this.team = team;
}

var myPlayer;

function addWizard(player, pos) {
    var mtype = "feet";
    var movement = {
        0: 1.0, // Plains
    };
    var distance = 4;
    game.world.addUnit(player, "wizard", pos, distance, mtype, movement);
}

function World(width, height) {

    function getWidth() {
        return w;
    }

    function getHeight() {
        return h;
    }

    function getCell(x, y) {
        return cells[x][y];
    }

    function setCell(x, y, cell) {
        cells[x][y] = cell;
    }

    function withinWorld(x, y) {
        return x >= 0 && x < w && y >= 0 && y < h;
    }

    function initialize(entryCells) {
        if (entryCells.length == w && entryCells[0].length == h)
        {
            for (var x = 0; x < w; x++) {
                for (var y = 0; y < h; y++) {
                    cells[x][y] = entryCells[x][y];
                }
            }
        } else {
            console.log("World.initialize called with incorrect size");
        }
    }

    function addOrUpdatePlayer(id, nation, team) {
        var player = new Player(id, nation, team);
        players[id] = player;
        if (id === playerId) {
            myPlayer = player;
        }
    }

    function getPlayer(id) {
        return players[id];
    }

    function getPlayerFromNation(nation) {
        for (var id in players) {
            if (players[id].nation === nation) {
                return players[id];
            }
        }
        return undefined;
    }

    // unit sprite's have to be cloned, so we have to wrap their creation
    function addUnit(uid, player, srcSpriteName, pos, distance, movementType,
                     movement, health, maxHealth, nation, name, canMove,
                     attacks, armor) {
        var newSpriteName = player + srcSpriteName + unitCounter;
        unitCounter += 1;
        var spritePos = jQuery.extend(true, {}, pos);
        assets.spriteManager.cloneSprite(srcSpriteName, newSpriteName, spritePos);
        var newUnit = new Unit(uid, player, newSpriteName, pos, distance,
                               movementType, movement, health, maxHealth,
                               nation, name, canMove, attacks, armor);
        units[uid] = newUnit;
    }

    function moveUnit(srcPos, destPos) {
        var unit = findUnit(srcPos.x, srcPos.y);
        if (!unit) {
            console.log("No unit found at", srcPos);
            return;
        }
        if (findUnit(destPos.x, destPos.y) !== undefined) {
            console.log("A unit exists at", destPos, "already");
            return;
        }
        unit.pos = destPos;
    }

    function getUnits() {
        var output = [];
        for (var id in units) {
            output.push(units[id]);
        }
        return output;
    }

    function findUnit(wx, wy) {
        for (var id in units) {
            if (units[id].pos.x === wx && units[id].pos.y === wy) {
                return units[id];
            }
        }
        return undefined;
    }

    function getUnit(id) {
        return units[id];
    }

    function resetUnits(playerId) {
        var playerNation = getPlayer(playerId).nation;
        var allUnits = getUnits();
        for (var i = allUnits.length - 1; i >= 0; i--) {
            if (allUnits[i].nation === playerNation) {
                allUnits[i].resetState();
            }
        };
    }

    function findAvailableMoves(unit) {
        if (unit.canMove) {
            var moves = findAvailableCells(unit);
            game.movesAvailableCallback(moves);
            return moves;
        } else {
            console.log("That unit moved already");
        }
    }

    function findAvailableAttacks(unit) {
        // need to go through a different process for melee/range units
        // ranged units need to get their attack range from somewhere, min and max
        var moves = findAvailableCells(unit);
        var attacks = processMeleeAttack(unit, moves);
        game.attacksAvailableCallback(attacks);
        return attacks;
    }

    function findAvailableCells(unit) {
        function cellEqual(cell1, cell2) {
            return cell1.cell.position.x == cell2.cell.position.x &&
                   cell1.cell.position.y == cell2.cell.position.y;
        }

        var visited = new BinaryHeap(function() { return 1; }, cellEqual);
        var source = cells[unit.pos.x][unit.pos.y];

        function processCell(cell, remainingmoves) {
            visited.push({cell: cell, remainingmoves: remainingmoves});
            if (remainingmoves > 0) {
                var neighbors = getMatrixNeighbors(cells, cell.position);
                for (var i = neighbors.length - 1; i >= 0; i--) {
                    var neighbor = {cell: neighbors[i],
                                    remainingmoves: neighbors[i].remainingmoves};
                    var neighborUnit = game.world.findUnit(neighbors[i].position.x,
                                                           neighbors[i].position.y);
                    if (visited.contains(neighbor)) {
                        neighbor.remainingmoves = visited.get(neighbor).remainingmoves;
                    } else {
                        neighbor.remainingmoves = 0;
                    }
                    if (!visited.contains(neighbor) ||
                        remainingmoves > neighbor.remainingmoves) {
                        var moveCost = unit.movement[neighbor.cell.type];
                        if (moveCost > 0 && neighborUnit === undefined &&
                            remainingmoves - moveCost > 0) {
                            processCell(neighbors[i], remainingmoves - moveCost);
                        }
                    }
                }
            }
        }

        processCell(source, unit.distance);

        var moves = new BinaryHeap(function() { return 1; }, cellEqual);
        for (var i = visited.content.length - 1; i >= 0; i--) {
            if (!moves.contains(visited.content[i])) {
                moves.push(visited.content[i]);
            }
        }

        return moves.content;
    }

    // Rule is the shape of the neighbors you want. "plus" means just
    // the above, below, left, and right neighbors. "square" means
    // the full 3x3 grid of neighbors
    function getNeighbors(wx, wy, rule) {
        function initializeNeighbors(size) {
            var neighbors = new Array(size);
            for (var i = 0; i < size; i++) {
                neighbors[i] = new Array(size);
            }
            return neighbors;
        }

        rule = rule === undefined ? "plus" : rule;
        var neighbors = initializeNeighbors(3);
        for (var x = -1; x <= 1; x++) {
            for (var y = -1; y <= 1; y++) {
                if (withinWorld(wx + x, wy + y)) {
                    neighbors[x + 1][y + 1] = cells[wx + x][wy + y];
                }
            }
        }
        if (rule === "plus") {
            set2DCorners(neighbors, 3, {});
        }
        objectifyUndefined(neighbors);

        return neighbors;
    }

    function processRangeAttack(unit, moves) {
        // TODO this is all wrong
        var attacks = [];
        for (var i = moves.length - 1; i >= 0; i--) {
            if (ManhattanDistance(moves[i].cell.position, unit.pos) >= unit.minRange) {
                attacks.push(moves[i]);
            }
        }

        return attacks;
    }

    function processMeleeAttack(unit, moves) {
        // sorry!
        function cellEqual(cell1, cell2) {
            return cell1.cell.position.x == cell2.cell.position.x &&
                   cell1.cell.position.y == cell2.cell.position.y;
        }

        var attacks = new BinaryHeap(function() { return 1; }, cellEqual);
        for (var i = moves.length - 1; i >= 0; i--) {
            var neighbors = getMatrixNeighbors(cells, moves[i].cell.position);
            for (var j = neighbors.length - 1; j >= 0; j--) {
                var neighbor = {cell: neighbors[j]};
                if (!attacks.contains(neighbor)) {
                    attacks.push(neighbor);
                }
            }
        }

        return attacks.content;
    }

    function serialize() {
        var outUnits = serializeUnits();
        var terrain = serializeTerrain();

        var serialObject = {"units": outUnits,
                            "terrain": terrain};

        return JSON.stringify(serialObject);
    }

    function serializeTerrain() {
        var terrain = new Array(w);
        for (var x = 0; x < w; x++) {
            terrain[x] = new Array(h);
            for (var y = 0; y < h; y++) {
                terrain[x][y] = cells[x][y].type;
            }
        }

        return terrain;
    }

    function serializeUnits() {
        var outUnits = {};
        for (var player in units) {
            if (units.hasOwnProperty(player)) {
                outUnits[player] = [];
                for (var i = 0; i < units[player].length; i++) {
                    var unit = jQuery.extend(true, {}, units[player][i]);
                    unit.loc = unit.pos;
                    delete unit.pos;
                    outUnits[player].push(unit);
                }
            }
        }

        return outUnits;
    }

    var w = width;
    var h = height;

    var cells = new Array(width);

    var players = {};
    var unitCounter = 0;
    var units = {};

    for (var x = 0; x < width; x++) {
        cells[x] = new Array(height);
    }

    this.getWidth = function() {
        return getWidth();
    };

    this.getHeight = function() {
        return getHeight();
    };

    this.getCell = function(x, y) {
        return getCell(x, y);
    };

    this.setCell = function(x, y, cell) {
        setCell(x, y, cell);
    };

    this.initialize = function(entryCells) {
        initialize(entryCells);
    };

    this.addUnit = function(uid, player, srcSpriteName, pos, distance, movementType,
                            movement, health, maxHealth, nation, name, canMove,
                            attacks, armor) {
        addUnit(uid, player, srcSpriteName, pos, distance, movementType, movement,
                health, maxHealth, nation, name, canMove, attacks, armor);
    };

    this.getUnits = function() {
        return getUnits();
    };

    this.findUnit = function(wx, wy) {
        return findUnit(wx, wy);
    };

    this.getUnit = function(id) {
        return getUnit(id);
    };

    this.withinWorld = function(x, y) {
        return withinWorld(x, y);
    };

    this.findAvailableMoves = function(unit) {
        return findAvailableMoves(unit);
    };

    this.findAvailableAttacks = function(unit) {
        return findAvailableAttacks(unit);
    };

    this.serialize = function() {
        return serialize();
    };

    this.moveUnit = function(srcPos, destPos) {
        moveUnit(srcPos, destPos);
    }

    this.resetUnits = function(playerId) {
        resetUnits(playerId);
    }

    this.addOrUpdatePlayer = function(id, nation, team) {
        addOrUpdatePlayer(id, nation, team);
    }

    this.getPlayer = function(id) {
        return getPlayer(id);
    }

    this.getPlayerFromNation = function(nation) {
        return getPlayerFromNation(nation);
    }

    this.getNeighbors = function(wx, wy, rule) {
        return getNeighbors(wx, wy, rule);
    }

    this.currentPlayerId = null;
}

function plainsWorld(width, height) {
    var terrain = new Array(width);

    for (var x = 0; x < width; x++) {
        terrain[x] = new Array(height);
        for (var y = 0; y < height; y++) {
            terrain[x][y] = terrainTable[terrainTypes.plains](x, y);
        }
    }

    var w = new World(width, height);
    w.initialize(terrain);

    return w;
}

function routePath(unit, goal) {
    var moves = game.world.findAvailableMoves(unit);
    var pathworld = convertWorldToPathNodes(game.world, unit, moves);
    var pathfinder = new PathFinder(pathworld, pathworld[unit.pos.x][unit.pos.y]);
    var path = pathfinder.findPath(pathworld[goal.x][goal.y]);
    if (path) {
        game.pathCallback(path);
    } else {
        console.log("You can't get there!");
    }
    return path;
}

var terrainTable;
var terrainTypes = {};

function cellEqual(cell1, cell2) {
    return cell1.cell.position.x == cell2.position.x &&
           cell1.cell.position.y == cell2.position.y;
}

function convertWorldToPathNodes(world, unit, moves) {
    var pathworld = new Array(world.getWidth());
    for (var x = 0; x < world.getWidth(); x++) {
        pathworld[x] = new Array(world.getHeight());
        for (var y = 0; y < world.getHeight(); y++) {
            // The cost modifier could/should come from a combination of
            // the cell type and the unit's movement modifiers. Likewise for
            // passable
            var cost = unit.movement[world.getCell(x, y).type];
            var passable = false;
            if (cost > 0 && arrayContains(moves, world.getCell(x, y), cellEqual)) {
                passable = true;
            }
            pathworld[x][y] = new pathNode({x: x, y: y}, cost, passable);
        }
    }
    return pathworld;
}
<commit_msg>null !== undefined<commit_after>// This will eventually have much more information, including movement costs and such
function Cell(spriteName, type, x, y) {
    this.position = {x: x, y: y};
    this.spriteName = spriteName;
    this.type = type;
}

// Units may deserve their own file eventually, as they will have to track
// attack and defense information for the various weapon types
function Unit(id, player, spriteName, pos, distance, movementType, movement,
              health, maxHealth, nation, name, canMove, attacks, armor) {
    this.id = id;
    this.player = player;
    this.spriteName = spriteName;
    this.pos = pos;
    // The total distance the unit can move
    this.distance = distance;
    // treads, feet, wheels, that sort of thing
    this.movementType = movementType;
    // map of cell types to movement costs, ie plains -> 1.0
    this.movement = movement;
    this.health = health;
    this.maxHealth = maxHealth;
    this.nation = nation;
    this.name = name;
    this.canMove = canMove;
    this.attacks = attacks;
    this.armor = armor;

    this.resetState = function() {
        this.canMove = true;
    }
}

function Player(id, nation, team) {
    this.id = id;
    this.nation = nation;
    this.team = team;
}

var myPlayer;

function addWizard(player, pos) {
    var mtype = "feet";
    var movement = {
        0: 1.0, // Plains
    };
    var distance = 4;
    game.world.addUnit(player, "wizard", pos, distance, mtype, movement);
}

function World(width, height) {

    function getWidth() {
        return w;
    }

    function getHeight() {
        return h;
    }

    function getCell(x, y) {
        return cells[x][y];
    }

    function setCell(x, y, cell) {
        cells[x][y] = cell;
    }

    function withinWorld(x, y) {
        return x >= 0 && x < w && y >= 0 && y < h;
    }

    function initialize(entryCells) {
        if (entryCells.length == w && entryCells[0].length == h)
        {
            for (var x = 0; x < w; x++) {
                for (var y = 0; y < h; y++) {
                    cells[x][y] = entryCells[x][y];
                }
            }
        } else {
            console.log("World.initialize called with incorrect size");
        }
    }

    function addOrUpdatePlayer(id, nation, team) {
        var player = new Player(id, nation, team);
        players[id] = player;
        if (id === playerId) {
            myPlayer = player;
        }
    }

    function getPlayer(id) {
        return players[id];
    }

    function getPlayerFromNation(nation) {
        for (var id in players) {
            if (players[id].nation === nation) {
                return players[id];
            }
        }
        return null;
    }

    // unit sprite's have to be cloned, so we have to wrap their creation
    function addUnit(uid, player, srcSpriteName, pos, distance, movementType,
                     movement, health, maxHealth, nation, name, canMove,
                     attacks, armor) {
        var newSpriteName = player + srcSpriteName + unitCounter;
        unitCounter += 1;
        var spritePos = jQuery.extend(true, {}, pos);
        assets.spriteManager.cloneSprite(srcSpriteName, newSpriteName, spritePos);
        var newUnit = new Unit(uid, player, newSpriteName, pos, distance,
                               movementType, movement, health, maxHealth,
                               nation, name, canMove, attacks, armor);
        units[uid] = newUnit;
    }

    function moveUnit(srcPos, destPos) {
        var unit = findUnit(srcPos.x, srcPos.y);
        if (!unit) {
            console.log("No unit found at", srcPos);
            return;
        }
        if (findUnit(destPos.x, destPos.y) !== undefined) {
            console.log("A unit exists at", destPos, "already");
            return;
        }
        unit.pos = destPos;
    }

    function getUnits() {
        var output = [];
        for (var id in units) {
            output.push(units[id]);
        }
        return output;
    }

    function findUnit(wx, wy) {
        for (var id in units) {
            if (units[id].pos.x === wx && units[id].pos.y === wy) {
                return units[id];
            }
        }
        return undefined;
    }

    function getUnit(id) {
        return units[id];
    }

    function resetUnits(playerId) {
        var playerNation = getPlayer(playerId).nation;
        var allUnits = getUnits();
        for (var i = allUnits.length - 1; i >= 0; i--) {
            if (allUnits[i].nation === playerNation) {
                allUnits[i].resetState();
            }
        };
    }

    function findAvailableMoves(unit) {
        if (unit.canMove) {
            var moves = findAvailableCells(unit);
            game.movesAvailableCallback(moves);
            return moves;
        } else {
            console.log("That unit moved already");
        }
    }

    function findAvailableAttacks(unit) {
        // need to go through a different process for melee/range units
        // ranged units need to get their attack range from somewhere, min and max
        var moves = findAvailableCells(unit);
        var attacks = processMeleeAttack(unit, moves);
        game.attacksAvailableCallback(attacks);
        return attacks;
    }

    function findAvailableCells(unit) {
        function cellEqual(cell1, cell2) {
            return cell1.cell.position.x == cell2.cell.position.x &&
                   cell1.cell.position.y == cell2.cell.position.y;
        }

        var visited = new BinaryHeap(function() { return 1; }, cellEqual);
        var source = cells[unit.pos.x][unit.pos.y];

        function processCell(cell, remainingmoves) {
            visited.push({cell: cell, remainingmoves: remainingmoves});
            if (remainingmoves > 0) {
                var neighbors = getMatrixNeighbors(cells, cell.position);
                for (var i = neighbors.length - 1; i >= 0; i--) {
                    var neighbor = {cell: neighbors[i],
                                    remainingmoves: neighbors[i].remainingmoves};
                    var neighborUnit = game.world.findUnit(neighbors[i].position.x,
                                                           neighbors[i].position.y);
                    if (visited.contains(neighbor)) {
                        neighbor.remainingmoves = visited.get(neighbor).remainingmoves;
                    } else {
                        neighbor.remainingmoves = 0;
                    }
                    if (!visited.contains(neighbor) ||
                        remainingmoves > neighbor.remainingmoves) {
                        var moveCost = unit.movement[neighbor.cell.type];
                        if (moveCost > 0 && neighborUnit === undefined &&
                            remainingmoves - moveCost > 0) {
                            processCell(neighbors[i], remainingmoves - moveCost);
                        }
                    }
                }
            }
        }

        processCell(source, unit.distance);

        var moves = new BinaryHeap(function() { return 1; }, cellEqual);
        for (var i = visited.content.length - 1; i >= 0; i--) {
            if (!moves.contains(visited.content[i])) {
                moves.push(visited.content[i]);
            }
        }

        return moves.content;
    }

    // Rule is the shape of the neighbors you want. "plus" means just
    // the above, below, left, and right neighbors. "square" means
    // the full 3x3 grid of neighbors
    function getNeighbors(wx, wy, rule) {
        function initializeNeighbors(size) {
            var neighbors = new Array(size);
            for (var i = 0; i < size; i++) {
                neighbors[i] = new Array(size);
            }
            return neighbors;
        }

        rule = rule === undefined ? "plus" : rule;
        var neighbors = initializeNeighbors(3);
        for (var x = -1; x <= 1; x++) {
            for (var y = -1; y <= 1; y++) {
                if (withinWorld(wx + x, wy + y)) {
                    neighbors[x + 1][y + 1] = cells[wx + x][wy + y];
                }
            }
        }
        if (rule === "plus") {
            set2DCorners(neighbors, 3, {});
        }
        objectifyUndefined(neighbors);

        return neighbors;
    }

    function processRangeAttack(unit, moves) {
        // TODO this is all wrong
        var attacks = [];
        for (var i = moves.length - 1; i >= 0; i--) {
            if (ManhattanDistance(moves[i].cell.position, unit.pos) >= unit.minRange) {
                attacks.push(moves[i]);
            }
        }

        return attacks;
    }

    function processMeleeAttack(unit, moves) {
        // sorry!
        function cellEqual(cell1, cell2) {
            return cell1.cell.position.x == cell2.cell.position.x &&
                   cell1.cell.position.y == cell2.cell.position.y;
        }

        var attacks = new BinaryHeap(function() { return 1; }, cellEqual);
        for (var i = moves.length - 1; i >= 0; i--) {
            var neighbors = getMatrixNeighbors(cells, moves[i].cell.position);
            for (var j = neighbors.length - 1; j >= 0; j--) {
                var neighbor = {cell: neighbors[j]};
                if (!attacks.contains(neighbor)) {
                    attacks.push(neighbor);
                }
            }
        }

        return attacks.content;
    }

    function serialize() {
        var outUnits = serializeUnits();
        var terrain = serializeTerrain();

        var serialObject = {"units": outUnits,
                            "terrain": terrain};

        return JSON.stringify(serialObject);
    }

    function serializeTerrain() {
        var terrain = new Array(w);
        for (var x = 0; x < w; x++) {
            terrain[x] = new Array(h);
            for (var y = 0; y < h; y++) {
                terrain[x][y] = cells[x][y].type;
            }
        }

        return terrain;
    }

    function serializeUnits() {
        var outUnits = {};
        for (var player in units) {
            if (units.hasOwnProperty(player)) {
                outUnits[player] = [];
                for (var i = 0; i < units[player].length; i++) {
                    var unit = jQuery.extend(true, {}, units[player][i]);
                    unit.loc = unit.pos;
                    delete unit.pos;
                    outUnits[player].push(unit);
                }
            }
        }

        return outUnits;
    }

    var w = width;
    var h = height;

    var cells = new Array(width);

    var players = {};
    var unitCounter = 0;
    var units = {};

    for (var x = 0; x < width; x++) {
        cells[x] = new Array(height);
    }

    this.getWidth = function() {
        return getWidth();
    };

    this.getHeight = function() {
        return getHeight();
    };

    this.getCell = function(x, y) {
        return getCell(x, y);
    };

    this.setCell = function(x, y, cell) {
        setCell(x, y, cell);
    };

    this.initialize = function(entryCells) {
        initialize(entryCells);
    };

    this.addUnit = function(uid, player, srcSpriteName, pos, distance, movementType,
                            movement, health, maxHealth, nation, name, canMove,
                            attacks, armor) {
        addUnit(uid, player, srcSpriteName, pos, distance, movementType, movement,
                health, maxHealth, nation, name, canMove, attacks, armor);
    };

    this.getUnits = function() {
        return getUnits();
    };

    this.findUnit = function(wx, wy) {
        return findUnit(wx, wy);
    };

    this.getUnit = function(id) {
        return getUnit(id);
    };

    this.withinWorld = function(x, y) {
        return withinWorld(x, y);
    };

    this.findAvailableMoves = function(unit) {
        return findAvailableMoves(unit);
    };

    this.findAvailableAttacks = function(unit) {
        return findAvailableAttacks(unit);
    };

    this.serialize = function() {
        return serialize();
    };

    this.moveUnit = function(srcPos, destPos) {
        moveUnit(srcPos, destPos);
    }

    this.resetUnits = function(playerId) {
        resetUnits(playerId);
    }

    this.addOrUpdatePlayer = function(id, nation, team) {
        addOrUpdatePlayer(id, nation, team);
    }

    this.getPlayer = function(id) {
        return getPlayer(id);
    }

    this.getPlayerFromNation = function(nation) {
        return getPlayerFromNation(nation);
    }

    this.getNeighbors = function(wx, wy, rule) {
        return getNeighbors(wx, wy, rule);
    }

    this.currentPlayerId = null;
}

function plainsWorld(width, height) {
    var terrain = new Array(width);

    for (var x = 0; x < width; x++) {
        terrain[x] = new Array(height);
        for (var y = 0; y < height; y++) {
            terrain[x][y] = terrainTable[terrainTypes.plains](x, y);
        }
    }

    var w = new World(width, height);
    w.initialize(terrain);

    return w;
}

function routePath(unit, goal) {
    var moves = game.world.findAvailableMoves(unit);
    var pathworld = convertWorldToPathNodes(game.world, unit, moves);
    var pathfinder = new PathFinder(pathworld, pathworld[unit.pos.x][unit.pos.y]);
    var path = pathfinder.findPath(pathworld[goal.x][goal.y]);
    if (path) {
        game.pathCallback(path);
    } else {
        console.log("You can't get there!");
    }
    return path;
}

var terrainTable;
var terrainTypes = {};

function cellEqual(cell1, cell2) {
    return cell1.cell.position.x == cell2.position.x &&
           cell1.cell.position.y == cell2.position.y;
}

function convertWorldToPathNodes(world, unit, moves) {
    var pathworld = new Array(world.getWidth());
    for (var x = 0; x < world.getWidth(); x++) {
        pathworld[x] = new Array(world.getHeight());
        for (var y = 0; y < world.getHeight(); y++) {
            // The cost modifier could/should come from a combination of
            // the cell type and the unit's movement modifiers. Likewise for
            // passable
            var cost = unit.movement[world.getCell(x, y).type];
            var passable = false;
            if (cost > 0 && arrayContains(moves, world.getCell(x, y), cellEqual)) {
                passable = true;
            }
            pathworld[x][y] = new pathNode({x: x, y: y}, cost, passable);
        }
    }
    return pathworld;
}
<|endoftext|>


<commit_before>// Copyright (c) 2013 Matt Runkle. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

var SITES = [
	"play.google.com/music",
	"pandora.com"
];

function checkForSupportedSite(tabId, changeInfo, tab) {
	SITES.forEach(function(element, index, array) {
		if (tab.url.indexOf(element) > -1) {
			chrome.pageAction.show(tabId);
			return false; // break
		}
	});
}

function injectConnector(tabid, callback) {
	// TODO lookup correct script

	chrome.tabs.executeScript(tabid, {file: "connectors/googlemusic.js"}, callback);
}

// Listen for any changes to the URL of any tab
chrome.tabs.onUpdated.addListener(checkForSupportedSite);
<commit_msg>Inject the correct script based on URL.<commit_after>// Copyright (c) 2013 Matt Runkle. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

var CONNECTORS = [
	{
		name: "Google Music",
		script: "googlemusic.js",
		site: "play.google.com"
	},
	{
		name: "Pandora",
		script: "pandora.js",
		site: "www.pandora.com"
	}
];

function getHostname(url) {
	// Dirty trick to get hostname of URL without library
	var a = document.createElement('a');
	a.href = url;
	return a.hostname;
}

function checkForSupportedSite(tabId, changeInfo, tab) {
	var hostname = getHostname(tab.url);

	var match = !CONNECTORS.every(function(connector) {
		console.log(connector.site);
		if (hostname == connector.site) {
			chrome.pageAction.show(tabId);
			return false; // break
		}

		return true;
	});

	if (!match)
		chrome.pageAction.hide(tabId);
}

function injectConnector(tabid, callback) {
	chrome.tabs.get(tabid, function(tab) {
		var hostname = getHostname(tab.url);

		CONNECTORS.every(function(connector) {
			if (hostname == connector.site) {
				console.log("Injecting " + connector.name + " script");
				chrome.tabs.executeScript(tabid, {file: "connectors/" + connector.script}, callback);
				return false; // break
			}

			return true;
		});
	});
}

// Listen for any changes to the URL of any tab
chrome.tabs.onUpdated.addListener(checkForSupportedSite);
<|endoftext|>


<commit_before>module.exports = function(value1, value2) {

if (value1.format) value1 = value1.format('YYYY-MM-DD');
if (value2.format) value2 = value2.format('YYYY-MM-DD');

  if (typeof value1!='object' && typeof value2!='object')
    return value1==value2;

var what = Object.prototype.toString;

if (what.call(value1)=='[object Array]') { // multiple list
    return arraysEqual(value1, value2);
}

if (value1.start && value2.start) {

 var value1start = value1.start.format?value1.start.format('YYYY-MM-DD'):value1.start;
 var value1end = value1.end.format?value1.end.format('YYYY-MM-DD'):value1.end;
 var value2start = value2.start.format?value2.start.format('YYYY-MM-DD'):value2.start;
 var value2end = value2.end.format?value2.end.format('YYYY-MM-DD'):value2.end;

  return (value1start==value2start) && (value1end==value2end);
}

return false;

}

function arraysEqual(arr1, arr2) {

  var equal = true;

  if (arr1.length!=arr2.length) return false;

  arr1.forEach(function(item) {
    if (typeof item!='object' && arr2.indexOf(item)==-1)
      equal = false;
  });

  return equal;
}
<commit_msg>bug fix'<commit_after>module.exports = function(value1, value2) {

if (value1 && value1.format) value1 = value1.format('YYYY-MM-DD');
if (value2 && value2.format) value2 = value2.format('YYYY-MM-DD');

  if (typeof value1!='object' && typeof value2!='object')
    return value1==value2;

var what = Object.prototype.toString;

if (what.call(value1)=='[object Array]') { // multiple list
    return arraysEqual(value1, value2);
}

if (value1.start && value2.start) {

 var value1start = value1.start.format?value1.start.format('YYYY-MM-DD'):value1.start;
 var value1end = value1.end.format?value1.end.format('YYYY-MM-DD'):value1.end;
 var value2start = value2.start.format?value2.start.format('YYYY-MM-DD'):value2.start;
 var value2end = value2.end.format?value2.end.format('YYYY-MM-DD'):value2.end;

  return (value1start==value2start) && (value1end==value2end);
}

return false;

}

function arraysEqual(arr1, arr2) {

  var equal = true;

  if (arr1.length!=arr2.length) return false;

  arr1.forEach(function(item) {
    if (typeof item!='object' && arr2.indexOf(item)==-1)
      equal = false;
  });

  return equal;
}
<|endoftext|>


<commit_before>(function ( $ ) {
	"use strict";

	//test

	$(function () {

		// Place your administration-specific JavaScript here
		function validateURL(value){
	    	return /^(https?|ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i.test(value);
	    }

		$('#uconn-banner-settings').on('submit', function() {

			var url = $("#department_url").val();
			var title = $("#department_title").val();

		    if (!validateURL(url)) {
		        alert("Please enter a valid URL, remember including http://");
		        return false;
		    } else if (title=="" || title==null) {
		    	alert("Please enter a department title.");
		    	return false;
		    } else {
		    	return true;
		    }

		});

	});

}(jQuery));

<commit_msg>testing<commit_after>(function ( $ ) {
	"use strict";

	$(function () {

		// Place your administration-specific JavaScript here
		function validateURL(value){
	    	return /^(https?|ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i.test(value);
	    }

		$('#uconn-banner-settings').on('submit', function() {

			var url = $("#department_url").val();
			var title = $("#department_title").val();

		    if (!validateURL(url)) {
		        alert("Please enter a valid URL, remember including http://");
		        return false;
		    } else if (title=="" || title==null) {
		    	alert("Please enter a department title.");
		    	return false;
		    } else {
		    	return true;
		    }

		});

	});

}(jQuery));

<|endoftext|>


<commit_before>var senateData;
var houseData;
var congressData;
var perfStart;

function getRegExpString(senator) {
  var title = '(Senator|Sen\\.|Congressman|Congresswoman)';
  var optionalQuote = '(\'|")?';
  var wildCardMiddle = optionalQuote + '(\\w*)(\\.)?' + optionalQuote;
  var upToTwoWildCardMiddles = '\\s*' + wildCardMiddle + '\\s*' + wildCardMiddle + '\\s*';
  var firstLast = '\\b' + senator.firstName + '\\b' + upToTwoWildCardMiddles + '\\b' + senator.lastName + '\\b';
  var lastFirst = '\\b' + senator.lastName + ',\\b' + senator.firstName + '\\b';
  var titleLast = '\\b' + title + '\\s*' + senator.lastName + '\\b';
  var nicknames = '';
  var regExpString = '';

  function getNicknameString (nickname, lastName) {
    return '|\\b' + nickname + '\\b' + upToTwoWildCardMiddles + '\\b' + lastName + '\\b|\\b' + lastName + '\\b,\\b' + nickname + '\\b';
  }

  if (senator.nicknames) {
    if (Array.isArray(senator.nicknames)) {
      for (var i = 0; i < senator.nicknames.length; i++) {
        nicknames += getNicknameString(senator.nicknames[i], senator.lastName);
      }
    } else if (typeof senator.nicknames === 'string') {
      nicknames += getNicknameString(senator.nicknames[i], senator.lastName);
    }
  }

  regExpString += title + '?' + '(' + firstLast + nicknames + ')|' + titleLast + '|' + lastFirst;

  return regExpString;
}

function getLastNamesRegExp() {
  var lastNamesRegExpArr = [];

  for (var i = 0; i < senateData.length; i++) {
    lastNamesRegExpArr.push('\\b' + senateData[i].lastName + '\\b');
  }

  return new RegExp(lastNamesRegExpArr.join('|'), 'ig');
}

function scan(node) {
  if (node.innerText) {
    var lastNamesRegExp = getLastNamesRegExp();
    var lastNames = node.innerText.match(lastNamesRegExp);

    if (lastNames) {
      var foundLastNames = _.uniq(lastNames);
      var foundLastNamesRegExpArr = [];
      var foundLastNamesRegExp;
      var markContext;

      for (var i = 0; i < senateData.length; i++) {
        if (foundLastNames.indexOf(senateData[i].lastName) > -1) {
          var senatorRegEx = '(' + getRegExpString(senateData[i]) + ')';
          foundLastNamesRegExpArr.push(senatorRegEx);
        }
      }

      if (foundLastNamesRegExpArr.length) {
        foundLastNamesRegExp = new RegExp(foundLastNamesRegExpArr.join('|'), 'ig');
        markContext = new Mark(node);

        markContext.markRegExp(foundLastNamesRegExp, {
          element: 'span',
          className: 'dial-congress',
          done: function(x) {
            var perfEnd = performance.now();
            var perfTime = Math.round(perfEnd - perfStart) / 1000;
            console.log('Dial Congress scan of DOM complete: ' + perfTime + ' seconds');
            console.log('Congress critters found: ' + x);
          }
        });

        bindHoverEvents();
      }
    }
  }
}

function bindHoverEvents() {
  $marks = $('.dial-congress');

  $marks.each(function(i, mark) {
    var $mark = $(mark);

    if (!$mark.hasClass('dial-congress-mouseenter')) {
      $mark.addClass('dial-congress-mouseenter');
      $mark.on('mouseenter', matchSenatorToMark);
    }
  });
}

function matchSenatorToMark(e) {
  var $el = $(e.target);
  var text = $el.text();

  for(var i = 0; i < senateData.length; i++) {
    var regExp = new RegExp(getRegExpString(senateData[i]), 'ig');

    if (text.match(regExp)) {
      buildTooltip($el, senateData[i]);
      $el.off('mouseenter', matchSenatorToMark);
      break;
    }
  }
}

function buildTooltip($el, senator) {
  track({
    eventName: 'tooltip-built',
    congressman: senator.firstName + ' ' + senator.lastName,
    text: $el.text()
  });

  $el.attr('title', senator.party + '/' + senator.state + ': ' + senator.phone);

  $el.tooltipster({
    functionReady: function() {
      track({
        eventName: 'tooltip-hover',
        congressman: senator.firstName + ' ' + senator.lastName,
        text: $el.text()
      });
    },
    interactive: true,
    theme: ['tooltipster-noir', 'tooltipster-noir-customized']
  });

  $el.tooltipster('open');
}

function checkIfTooltipster($node) {
  return $node.hasClass('tooltipster-base') || $node.hasClass('tooltipster-ruler');
}

function watchForDOMChanges() {
  var observer = new MutationObserver(function(mutations) {
    mutations.forEach(function(mutation) {
      if (mutation.addedNodes.length) {
        // check nodes that have been added to the DOM
        mutation.addedNodes.forEach(function(node) {
          if (node.nodeType == 1) {
            // node is an Element
            var $node = $(node);

            // make sure it's not a tooltipster and that it has content
            if (!checkIfTooltipster($node) && !$node.is(':empty')) {
              perfStart = performance.now();
              scan(node);
            }
          } else if (node.nodeType == 3 && node.parentNode) {
            // node is Text, send parentNode to scan()
            perfStart = performance.now();
            scan(node.parentNode);
          }
        })
      } else if (mutation.target) {
        // check nodes that have had their attributes or characterData changed
        var tooltipsterRemoved = false;

        // check if tooltipster has been removed
        mutation.removedNodes.forEach(function(node) {
          if (!tooltipsterRemoved && checkIfTooltipster($(node))) {
            tooltipsterRemoved = true;
          }
        });

        if (!tooltipsterRemoved) {
          perfStart = performance.now();
          scan(mutation.target);
        }
      }
    });
  });

  var observerConfig = {
    attributes: true,
    characterData: true,
    childList: true,
    subtree: true
  };

  var targetNode = document.body;
  observer.observe(targetNode, observerConfig);
}

function track(data) {
  chrome.runtime.sendMessage(data, function(response) {
    // console.log('message received', response);
  });
}

$(document).ready(function() {
  $.when(
    $.get(chrome.extension.getURL('js/senate.json'), function(data) {
      senateData = JSON.parse(data);
      senateData.forEach(function(senator) {
        senator.house = 'senate';
      });
    }),

    $.get(chrome.extension.getURL('js/house.json'), function(data) {
      houseData = JSON.parse(data);
      houseData.forEach(function(rep) {
        rep.house = 'house';
      });
    })
  ).then(function() {
    congressData = _.union(senateData, houseData);
    perfStart = performance.now();
    scan(document.body);
    watchForDOMChanges();
  });
});
<commit_msg>Scan for all of congress using combined senate and house data<commit_after>var senateData;
var houseData;
var congressData;
var perfStart;

function getRegExpString(critter) {
  var title = '(Senator|Sen\\.|Congressman|Congresswoman)';

  if (critter.house === 'house') {
    title = '(Representative|Rep\\.|Congressman|Congresswoman)';
  }

  var optionalQuote = '(\'|")?';
  var wildCardMiddle = optionalQuote + '(\\w*)(\\.)?' + optionalQuote;
  var upToTwoWildCardMiddles = '\\s*' + wildCardMiddle + '\\s*' + wildCardMiddle + '\\s*';
  var firstLast = '\\b' + critter.firstName + '\\b' + upToTwoWildCardMiddles + '\\b' + critter.lastName + '\\b';
  var lastFirst = '\\b' + critter.lastName + ',\\b' + critter.firstName + '\\b';
  var titleLast = '\\b' + title + '\\s*' + critter.lastName + '\\b';
  var nicknames = '';
  var regExpString = '';

  function getNicknameString (nickname, lastName) {
    return '|\\b' + nickname + '\\b' + upToTwoWildCardMiddles + '\\b' + lastName + '\\b|\\b' + lastName + '\\b,\\b' + nickname + '\\b';
  }

  if (critter.nicknames) {
    if (Array.isArray(critter.nicknames)) {
      for (var i = 0; i < critter.nicknames.length; i++) {
        nicknames += getNicknameString(critter.nicknames[i], critter.lastName);
      }
    } else if (typeof critter.nicknames === 'string') {
      nicknames += getNicknameString(critter.nicknames[i], critter.lastName);
    }
  }

  regExpString += title + '?' + '(' + firstLast + nicknames + ')|' + titleLast + '|' + lastFirst;

  return regExpString;
}

function getLastNamesRegExp() {
  var lastNamesRegExpArr = [];

  for (var i = 0; i < congressData.length; i++) {
    lastNamesRegExpArr.push('\\b' + congressData[i].lastName + '\\b');
  }

  return new RegExp(lastNamesRegExpArr.join('|'), 'ig');
}

function scan(node) {
  if (node.innerText) {
    var lastNamesRegExp = getLastNamesRegExp();
    var lastNames = node.innerText.match(lastNamesRegExp);

    if (lastNames) {
      var foundLastNames = _.uniq(lastNames);
      var foundLastNamesRegExpArr = [];
      var foundLastNamesRegExp;
      var markContext;

      for (var i = 0; i < congressData.length; i++) {
        if (foundLastNames.indexOf(congressData[i].lastName) > -1) {
          var senatorRegEx = '(' + getRegExpString(congressData[i]) + ')';
          foundLastNamesRegExpArr.push(senatorRegEx);
        }
      }

      if (foundLastNamesRegExpArr.length) {
        foundLastNamesRegExp = new RegExp(foundLastNamesRegExpArr.join('|'), 'ig');
        markContext = new Mark(node);

        markContext.markRegExp(foundLastNamesRegExp, {
          element: 'span',
          className: 'dial-congress',
          done: function(x) {
            var perfEnd = performance.now();
            var perfTime = Math.round(perfEnd - perfStart) / 1000;
            console.log('Dial Congress scan of DOM complete: ' + perfTime + ' seconds');
            console.log('Congress critters found: ' + x);
          }
        });

        bindHoverEvents();
      }
    }
  }
}

function bindHoverEvents() {
  $marks = $('.dial-congress');

  $marks.each(function(i, mark) {
    var $mark = $(mark);

    if (!$mark.hasClass('dial-congress-mouseenter')) {
      $mark.addClass('dial-congress-mouseenter');
      $mark.on('mouseenter', matchSenatorToMark);
    }
  });
}

function matchSenatorToMark(e) {
  var $el = $(e.target);
  var text = $el.text();

  for(var i = 0; i < congressData.length; i++) {
    var regExp = new RegExp(getRegExpString(congressData[i]), 'ig');

    if (text.match(regExp)) {
      buildTooltip($el, congressData[i]);
      $el.off('mouseenter', matchSenatorToMark);
      break;
    }
  }
}

function buildTooltip($el, senator) {
  track({
    eventName: 'tooltip-built',
    congressman: senator.firstName + ' ' + senator.lastName,
    text: $el.text()
  });

  $el.attr('title', senator.party + '/' + senator.state + ': ' + senator.phone);

  $el.tooltipster({
    functionReady: function() {
      track({
        eventName: 'tooltip-hover',
        congressman: senator.firstName + ' ' + senator.lastName,
        text: $el.text()
      });
    },
    interactive: true,
    theme: ['tooltipster-noir', 'tooltipster-noir-customized']
  });

  $el.tooltipster('open');
}

function checkIfTooltipster($node) {
  return $node.hasClass('tooltipster-base') || $node.hasClass('tooltipster-ruler');
}

function watchForDOMChanges() {
  var observer = new MutationObserver(function(mutations) {
    mutations.forEach(function(mutation) {
      if (mutation.addedNodes.length) {
        // check nodes that have been added to the DOM
        mutation.addedNodes.forEach(function(node) {
          if (node.nodeType == 1) {
            // node is an Element
            var $node = $(node);

            // make sure it's not a tooltipster and that it has content
            if (!checkIfTooltipster($node) && !$node.is(':empty')) {
              perfStart = performance.now();
              scan(node);
            }
          } else if (node.nodeType == 3 && node.parentNode) {
            // node is Text, send parentNode to scan()
            perfStart = performance.now();
            scan(node.parentNode);
          }
        })
      } else if (mutation.target) {
        // check nodes that have had their attributes or characterData changed
        var tooltipsterRemoved = false;

        // check if tooltipster has been removed
        mutation.removedNodes.forEach(function(node) {
          if (!tooltipsterRemoved && checkIfTooltipster($(node))) {
            tooltipsterRemoved = true;
          }
        });

        if (!tooltipsterRemoved) {
          perfStart = performance.now();
          scan(mutation.target);
        }
      }
    });
  });

  var observerConfig = {
    attributes: true,
    characterData: true,
    childList: true,
    subtree: true
  };

  var targetNode = document.body;
  // observer.observe(targetNode, observerConfig);
}

function track(data) {
  chrome.runtime.sendMessage(data, function(response) {
    // console.log('message received', response);
  });
}

$(document).ready(function() {
  $.when(
    $.get(chrome.extension.getURL('js/senate.json'), function(data) {
      senateData = JSON.parse(data);
      senateData.forEach(function(senator) {
        senator.house = 'senate';
      });
    }),

    $.get(chrome.extension.getURL('js/house.json'), function(data) {
      houseData = JSON.parse(data);
      houseData.forEach(function(rep) {
        rep.house = 'house';
      });
    })
  ).then(function() {
    congressData = _.union(senateData, houseData);
    perfStart = performance.now();
    scan(document.body);
    watchForDOMChanges();
  });
});
<|endoftext|>


<commit_before>  var modalMap;
  var service;
  var longitude;
  var latitude;
  var totalLocations = new Array();
  var totalLocationNames = new Array();
  var totalLocationDistances = new Array();
  var callCount = 0;
  var currLat;
  var currLong;
  var mapUrl;
  var tableDesc;
  var isDetails = false;
  var userLocation;
  var currOpenPlace;
  var isMobile = {
    Android: function() { return navigator.userAgent.match(/Android/i); },
    BlackBerry: function() { return navigator.userAgent.match(/BlackBerry/i); },
    iOS: function() { return navigator.userAgent.match(/iPhone|iPad|iPod/i); },
    Opera: function() { return navigator.userAgent.match(/Opera Mini/i); },
    Windows: function() { return navigator.userAgent.match(/IEMobile/i); },
    any: function() { return (isMobile.Android() || isMobile.BlackBerry() || isMobile.iOS() || isMobile.Opera() || isMobile.Windows()); } };
  function clickModal(){
    $("#firstData > *, #secondData > *, #thirdData > *").click(function()
    {

      var myservice;
      $('#myModal').modal({
        keyboard: true
      });
      tableDesc = $(this).children();
      //console.log(tableDesc);
      for(var i = 0; i < totalLocations.length; i++)
      {
        if(totalLocations[i].distance == tableDesc[2].innerHTML)
        {
          currLat = totalLocations[i].geometry.location.k;
          currLong = totalLocations[i].geometry.location.D;

          }
        }
    //location from array of total locations to instantiate map.
    var restLocation = new google.maps.LatLng(currLat, currLong);
    //finding average latitutde and longitute for map center
    var centerLocation = new google.maps.LatLng((currLat + latitude)/2, (currLong + longitude)/2);
    modalMap = new google.maps.Map(document.getElementById('rowDesc'),{
          center: centerLocation,
          zoom: 15
        });
    var marker = new google.maps.Marker({
      position: restLocation,
      map: modalMap
    });

     var origMarker = new google.maps.Marker({
      position: userLocation,
      map: modalMap
    });

    document.getElementById("rowName").innerHTML = tableDesc[0].innerHTML;

  function resizeMap() {
   if(typeof modalMap =="undefined") return;
   setTimeout( function(){resizingMap();} , 400);
}

function resizingMap() {

   var center = modalMap.getCenter();
   google.maps.event.trigger(modalMap, "resize");
   modalMap.setCenter(center);
    }
  });

}

/*STARTS here man*/
$(document).ready(function(){

  //instantiation of arrow back to top
  $('.selectpicker').selectpicker();

  $(document).ready(function() {
  $("#dataTable").tablesorter({
    sortList: [[0,0]],
    cssAsc: 'headerSortUp',
    cssDesc: 'headerSortDown',
    cssHeader: 'header',
    widgets : ['stickyHeaders','reflow'],
    widgetOptions : {
    stickyHeaders_attachTo : '.table-responsive',
    reflow_className    : 'ui-table-reflow',
    reflow_dataAttrib : 'data-title'

  }
  });
});

    document.getElementById("name").onclick = function(){
    document.getElementById("click").innerHTML = "Restaurants currently open sorted by name";
  }
    document.getElementById("rating").onclick = function(){
    document.getElementById("click").innerHTML = "Restaurants currently open sorted by rating";
  }
    document.getElementById("distance").onclick = function(){
    document.getElementById("click").innerHTML = "Restaurants currently open sorted by distance";
  }

  if(navigator.geolocation == undefined)
    {
      document.getElementById("click").innerHTML = "Could not retrieve your current location";
      document.getElementById("mobile").innerHTML = "Try enabling geolocation in your browser";
    }
  else
    {

    navigator.geolocation.getCurrentPosition(success, error);
    }
  });

function changeSearch(){

  $('.fa-arrow-up').click(function () {
  $('html,body').animate({scrollTop: 0}, 500);
    return false;
  });
  }
  function success(position)
  {
    /*latitude and longitude contain the users current location. */
    latitude = position.coords.latitude;
    longitude = position.coords.longitude;
    //console.log("my latitude "+ latitude);
    //console.log("my longitude "+ longitude);
    initialize();
  }
  function error()
  {
    document.getElementById("click").innerHTML = "Could not retrieve your current location";
    document.getElementById("mobile").innerHTML = "Try enabling location services on your device.";
  }

  function initialize()
  {
      itemCount = 0;
      userLocation = new google.maps.LatLng(latitude,longitude);
      var request =
        {
          /*don't be a dummy tallahassee is a variable name, but its not that anymore, but you want this to be here forever */
          location: userLocation,
          radius: '12000',
          types: ['restaurant'],
          openNow: true
        };

    service = new google.maps.places.PlacesService(map);
    service.nearbySearch(request,callback);
  }

function callback(results, status, info)
  {

    if(info.hasNextPage === true)
        {
          info.nextPage();
        }
        //~ Use this whenever you want to see what args you're getting.
        //console.log("Got arguments", arguments);

      if (status == google.maps.places.PlacesServiceStatus.OK)
        {
         callCount +=1;
         parseLocations(results,callCount,info);
        }

  }
  function parseReviews()
  {

    var service;
    isDetails = true;
    for(var i = 0; i < totalLocations.length; i++)
    {
      if(tableDesc[2].innerHTML == totalLocations[i].distance)
      {
        //var id = "'"+totalLocations[i].place_id + "'";
        var request =
        {
          placeId: totalLocations[i].place_id
        };
      service = new google.maps.places.PlacesService(map);
      service.getDetails(request,setReviewModal)
      }
  }
}

  function setReviewModal(results,status,info)
  {
    console.log(results);
    $("#headreview").show();
    document.getElementById('bodyreview').innerHTML = "";
    document.getElementById('headreview').innerHTML = "
" + "Author" + "	" + "" + "Experience" + "	" + "" + "Rating / 5" + "	" + "
";
    var allReviews = $.extend(true, [], results);

    for(var i = 0; i < results.reviews.length; i++)
    {
      //console.log("allReviews Before: " + allReviews[i].text);
      if(results.reviews[i].text.length < 5 )break;
      if(results.reviews[i].text.length > 100)
        results.reviews[i].text = results.reviews[i].text.substr(0,100);
      //console.log("allReviews After: " + allReviews[i].text);
      document.getElementById('bodyreview').innerHTML += "
" + "" + results.reviews[i].author_name + "	" +  "" + results.reviews[i].text + "...." + "	"
      + "" + results.reviews[i].rating  + "	" + "
";

    }

    flip(false);
    moreInfo(allReviews);
  }

  function moreInfo(allResults)
  {

    $(".reviewrows").click(function(){

      //clicked results object is the children of the tr, so the author text and rating td's
      var clickedResult = $(this).children();
      for(var i=0; i < allResults.reviews.length; i++)
      {
        if (allResults.reviews[i].author_name == clickedResult[0].innerHTML )
        {
          $("#headreview").hide();
          document.getElementById('bodyreview').innerHTML = allResults.reviews[i].text;

        }
      }
    });
  }

  function parseLocations(locations,callCount,info)
  {
    //this attaches a back to top event when the up arrow is pressed.

    changeSearch();
    var counter = 0;
    if (callCount == 2)
    {
        counter = 20;
    }
    else if (callCount == 3)
    {
      counter = 40;
    }
    //console.log("call count" + counter);
    //~ Use this whenever you want to display object/array arguments.
    //var tBody = ["firstData","secondData","thirdData"];
    var currentDistances = calculateDistance(locations,latitude,longitude);
    for (var i = 0; i < locations.length; i++, counter++)
        {
          var distanceandDescription = undefined;
          totalLocations[counter] = locations[i];
          totalLocationNames[counter] =locations[i].name;
          var x = $.inArray(locations[i].name,totalLocationNames,0);
          if(x > -1 && x != counter)
          {
            //if (locations[x].vicinity.length == 0 && locations[i].vicinity.length == 0) break;
            locations[i].vicinity = locations[i].vicinity.replace(/[0-9#]/g, '');
            locations[i].vicinity = locations[i].vicinity.substr(0,locations[i].vicinity.indexOf(','));
            distanceandDescription = currentDistances[i].toFixed(2) + "(" + locations[i].vicinity + ")";
            totalLocations[counter]["distance"] = distanceandDescription;
          }
        else
        {
          totalLocations[counter]["distance"] = currentDistances[i].toFixed(2);

        }

          //console.log("parseLocations:", locations[i].name);
          if(locations[i].rating == undefined) continue
           if(distanceandDescription == undefined)
           {
            distanceandDescription = currentDistances[i].toFixed(2);
          }
            //document.getElementById(tBody[callCount - 1]).innerHTML += "
" + "" + locations[i].name + "	" + "" + "&nbsp&nbsp&nbsp" + + locations[i].rating + "	" + "" + distanceandDescription+ "	" + "
";
            document.getElementById("firstData").innerHTML += "
" + "" + "
" + locations[i].name + "
" + "	" + "" + "&nbsp&nbsp&nbsp" + locations[i].rating  + "	" + ""  + distanceandDescription + "	" + "
";
        }
        //document.getElementById(tBody[callCount - 1]).innerHTML +="
" + "
";
        progressBar(callCount);
        //fills the progress bar because there are no more locations available
        $("#dataTable").trigger("update");
        if(info.hasNextPage === false)
        {
          progressBar(3);
        }

        clickModal();
  }
   function progressBar(callCount)
  {
    if (callCount == 1)
      {
        document.getElementById('activeBar').style.width = "33.3%";
      }
    else if (callCount == 2)
      {
        document.getElementById('activeBar').style.width = "66.6%";
      }
    else
      {
        document.getElementById('activeBar').style.width = "100%";
        $("#activeBar").delay(1000).fadeOut("slow", function()
          {
            $("#bar").css('visibility','hidden');
        });
      }
  }

  function calculateDistance(locations,latitude,longitude)
   {
      var distanceArray = new Array();
      for (var i=0; i < locations.length; i++)
      {
        distanceArray[i] = getDistanceFromLatLonInKm(latitude, longitude, locations[i].geometry.location.k, locations[i].geometry.location.D)
        //console.log("Distance Value" + distanceArray[i]);
      }
      return distanceArray;
   }

  function getDistanceFromLatLonInKm(lat1,lon1,lat2,lon2)
    {
      //var r = 6378100; //Radius of the earth in m
      var R = 6371; // Radius of the earth in km
      var kmtoMi = 0.621371;
      var dLat = deg2rad(lat2-lat1);  // deg2rad below
      var dLon = deg2rad(lon2-lon1);
      var a =
      Math.sin(dLat/2) * Math.sin(dLat/2) +
      Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2)) *
      Math.sin(dLon/2) * Math.sin(dLon/2);
      var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
      var d = R * c; // Distance in km
      return d * 0.621371;
    }

  function deg2rad(deg)
    {
      return deg * (Math.PI/180)
    }

function navigate()
  {

    var mobileMap = "http://maps.google.com/maps?saddr="+latitude + "," + longitude + "&daddr=" + currLat + "," + currLong;
    var x = document.getElementById('vehicle').value;
    mapUrl = "comgooglemaps://?saddr=" + latitude + "," + longitude + "&daddr=" + currLat + "," + currLong + "&directionsmode=" + x;
    if (isMobile.iOS())
    {
      setTimeout(function () { window.location = mapUrl; }, 25);

      window.location = "http://maps.apple.com/maps?saddr=" + latitude + "," + longitude + "&daddr=" + currLat + "," + currLong;
    }

   if(isMobile.Android())
     window.location = "http://maps.google.com/maps?saddr="+ latitude + "," + longitude+ "&daddr="+currLat+","+currLong;

   window.location = mobileMap;
  }

jQuery(document).ready(function($){

  //how long to wait to make the arrow visible.
  var offset = 300,
    //reduce the opacity of the arrow once we reach this point.
    offset_opacity = 1200,

    scroll_top_duration = 700,
    //back to top arrow.
    $back_to_top = $('.cd-top');

  //show or hide the arrow.
  $(window).scroll(function(){
    ( $(this).scrollTop() > offset ) ? $back_to_top.addClass('cd-is-visible') : $back_to_top.removeClass('cd-is-visible cd-fade-out');
    if( $(this).scrollTop() > offset_opacity ) {
      $back_to_top.addClass('cd-fade-out');
    }
  });

  //smooth scroll to top
  $back_to_top.on('click', function(event){
    event.preventDefault();
    $('body,html').animate({
      scrollTop: 0 ,
      }, scroll_top_duration
    );
  });

});

  function flip(back)
  {
    if (back === true)
    {
      $(".modal").modal('hide');
       setTimeout(function(){$("#myModal").modal('show');},1500);
    }
    //var front = document.getElementById('myModal');

    //var back_content = $('#reviewmodal').html();
    /*var back;
    back = flippant.flip(front, back_content,'card');
    */
    if(back === false)
    {
    $("#myModal").modal('hide');

    setTimeout(function(){
      $('#modaltest').modal({
        keyboard: true
      });
    },500);

    }
}

<commit_msg>added multiple places api calls and combined responses for better results<commit_after>  var modalMap;
  var service;
  var longitude;
  var latitude;
  var totalLocations = new Array();
  var totalLocationNames = new Array();
  var totalLocationDistances = new Array();
  var callCount = 0;
  var currLat;
  var currLong;
  var mapUrl;
  var tableDesc;
  var isDetails = false;
  var userLocation;
  var currOpenPlace;
  var isMobile = {
    Android: function() { return navigator.userAgent.match(/Android/i); },
    BlackBerry: function() { return navigator.userAgent.match(/BlackBerry/i); },
    iOS: function() { return navigator.userAgent.match(/iPhone|iPad|iPod/i); },
    Opera: function() { return navigator.userAgent.match(/Opera Mini/i); },
    Windows: function() { return navigator.userAgent.match(/IEMobile/i); },
    any: function() { return (isMobile.Android() || isMobile.BlackBerry() || isMobile.iOS() || isMobile.Opera() || isMobile.Windows()); } };
  function clickModal(){
    $("#firstData > *").click(function()
    {

      var myservice;
      var combinedDescription;
      var phoneRequest;
      $('#myModal').modal({
        keyboard: true
      });
      tableDesc = $(this).children();

      for(var i = 0; i < totalLocations.length; i++)
      {
        if(tableDesc[2].childNodes[1] == undefined )
          combinedDescription = tableDesc[2].childNodes[0].innerHTML;
        else
        {
          combinedDescription = tableDesc[2].childNodes[0].innerHTML + tableDesc[2].childNodes[1].outerHTML;
        }

        if(totalLocations[i].distance == combinedDescription)
        {

          currLat = totalLocations[i].geometry.location.k;
          currLong = totalLocations[i].geometry.location.D;
          var phoneRequest =
          {
            placeId: totalLocations[i].place_id
          };
          break;
        }
      }
    //location from array of total locations to instantiate map.
    var restLocation = new google.maps.LatLng(currLat, currLong);
    //finding average latitutde and longitute for map center
    var centerLocation = new google.maps.LatLng((currLat + latitude)/2, (currLong + longitude)/2);

    modalMap = new google.maps.Map(document.getElementById('rowDesc'),{
          center: centerLocation,
          zoom: 13
        });

    var targetDistance = getDistanceFromLatLonInKm(latitude,longitude,currLat,currLong);
    if(targetDistance > 4.0)
    {
      zoomLevel = 12;
      modalMap.setZoom(zoomLevel);
    }

     var origMarker = new google.maps.Marker({
      position: userLocation,
      map: modalMap,
      icon:  "../images/mapMarkers/green_MarkerA.png"
    });
     var marker = new google.maps.Marker({
      position: restLocation,
      map: modalMap,
      icon: "../images/mapMarkers/red_MarkerB.png"
    });

      service = new google.maps.places.PlacesService(map);
      service.getDetails(phoneRequest,function(results){

        document.getElementById("phoneNumber").innerHTML = "" + results.international_phone_number + "";

      });

document.getElementById("rowName").innerHTML = tableDesc[0].innerHTML;

});

}

/*STARTS here man*/
$(document).ready(function(){

  //instantiation of arrow back to top
  $('.selectpicker').selectpicker();

  $(document).ready(function() {
  $("#dataTable").tablesorter({
    sortList: [[2,0]],
    cssAsc: 'headerSortUp',
    cssDesc: 'headerSortDown',
    cssHeader: 'header',
    widgets : ['stickyHeaders','reflow'],
    headers: {
      1: {sorter: "digit", string: "zero"}
    },
    widgetOptions : {
    stickyHeaders_attachTo : '.table-responsive',
    reflow_className    : 'ui-table-reflow',
    reflow_dataAttrib : 'data-title'

  }
  });
});

    document.getElementById("name").onclick = function(){
    document.getElementById("mobile").innerHTML = "Arranged by name.";
  }
    document.getElementById("rating").onclick = function(){
    document.getElementById("mobile").innerHTML = "Arranged by rating.";
  }
    document.getElementById("distance").onclick = function(){
    document.getElementById("mobile").innerHTML = "Arranged by distance from your location.";
  }

  if(navigator.geolocation == undefined)
    {
      document.getElementById("click").innerHTML = "Could not retrieve your current location";
      document.getElementById("mobile").innerHTML = "Try enabling geolocation in your browser";
    }
  else
    {

    navigator.geolocation.getCurrentPosition(success, error);
    }
  });

function changeSearch(){

  $('.fa-arrow-up').click(function () {
  $('html,body').animate({scrollTop: 0}, 500);
    return false;
  });
  }
  function success(position)
  {
    /*latitude and longitude contain the users current location. */
    latitude = position.coords.latitude;
    longitude = position.coords.longitude;
    //console.log("my latitude "+ latitude);
    //console.log("my longitude "+ longitude);

    initialize();

  }
  function error()
  {
    document.getElementById("click").innerHTML = "Could not retrieve your current location";
    document.getElementById("mobile").innerHTML = "Try enabling location services on your device.";
  }

function initialize()
  {
      userLocation = new google.maps.LatLng(latitude,longitude);
      itemCount = 0;
      var request =
        {
          /*don't be a dummy tallahassee is a variable name, but its not that anymore, but you want this to be here forever */
          location: userLocation,
          radius: '6000',
          types: ['restaurant'],
          openNow: true
        };

    service = new google.maps.places.PlacesService(map);
    service.nearbySearch(request,callback);
  }

function grabclosePlaces()
{
  var request =
        {
          //don't be a dummy tallahassee is a variable name, but its not that anymore, but you want this to be here forever
          location: userLocation,
          radius: '1200',
          types: ['restaurant'],
          openNow: true
        };

    service = new google.maps.places.PlacesService(map);
    service.nearbySearch(request,callback);
}

  function callback(results, status, info)
  {
    console.log("results" + results + "/n" + "status" + status );

    if(info.hasNextPage === true)
        {
          info.nextPage();
        }
        //~ Use this whenever you want to see what args you're getting.
        //console.log("Got arguments", arguments);

      if (status == google.maps.places.PlacesServiceStatus.OK)
        {
         callCount +=1;

         if(callCount < 7)
         parseLocations(results,callCount,info);
        }

  }
  function parseLocations(locations,callCount,info)
  {
    //this attaches a back to top event when the up arrow is pressed.

   changeSearch();
    var counter = 0;
    if (callCount == 2)
    {
        counter = 20;
    }
    else if (callCount == 3)
    {
      counter = 40;
    }
    //console.log("call count" + counter);
    //~ Use this whenever you want to display object/array arguments.

    for(var i = 0; i < locations.length; i++)
      {
        for (var j = 0; j < totalLocations.length; j++)
          {
            if (locations[i].place_id == totalLocations[j].place_id)
            {
              locations[i]["id"] = "rid";

            }
          }
      }

    var currentDistances = calculateDistance(locations,latitude,longitude);
    for (var i = 0; i < locations.length; i++, counter++)
        {
          console.log("locations:" + locations[i].name + "\n");
          if(locations[i]["id"] == "rid")
          {
            continue;
          }

          var distanceandDescription = undefined;
          totalLocations[counter] = locations[i];
          totalLocationNames[counter] =locations[i].name;
          var x = $.inArray(locations[i].name,totalLocationNames,0);
          if(x > -1 && x != counter)
          {
            //if (locations[x].vicinity.length == 0 && locations[i].vicinity.length == 0) break;
            locations[i].vicinity = locations[i].vicinity.replace(/[0-9#]/g, '');
            locations[i].vicinity = locations[i].vicinity.substr(0,locations[i].vicinity.indexOf(','));
            distanceandDescription = currentDistances[i].toFixed(2) + "
" + "
" + "(" + locations[i].vicinity + ")" + "
";
            totalLocations[counter]["distance"] = distanceandDescription;
          }
        else
        {
          totalLocations[counter]["distance"] = currentDistances[i].toFixed(2);

        }

          if(locations[i].rating == undefined)
            locations[i].rating = "No Reviews Yet";
           if(distanceandDescription == undefined)
           {

            distanceandDescription = currentDistances[i].toFixed(2);

          }
            document.getElementById("firstData").innerHTML += "
" + "" + "
" + locations[i].name + "
" + "	" + "" +  "
" + locations[i].rating + "
" + "	" + ""  +  "
" + distanceandDescription + "
" +  "	" + "
";

        }

        progressBar(callCount);
        //fills the progress bar because there are no more locations available
        $("#dataTable").trigger("update");
        if(info.hasNextPage === false)
        {
          progressBar(3);
        }

        clickModal();
  }
   function progressBar(callCount)
  {
    if (callCount == 1)
      {
        document.getElementById('activeBar').style.width = "33.3%";
      }
    else if (callCount == 2)
      {
        console.log("cheese");
        document.getElementById('activeBar').style.width = "66.6%";
      }
    else
      {
        document.getElementById('activeBar').style.width = "100%";
        $("#activeBar").delay(1000).fadeOut("slow", function()
          {
            $("#bar").css('visibility','hidden');
        });
        //setTimeout(function(){grabclosePlaces();},5000);
      }
  }
  function parseReviews()
  {

    var service;
    isDetails = true;
    for(var i = 0; i < totalLocations.length; i++)
    {
      if(tableDesc[2].innerHTML == totalLocations[i].distance)
      {

        var request =
        {
          placeId: totalLocations[i].place_id
        };
      service = new google.maps.places.PlacesService(map);
      service.getDetails(request,setReviewModal)
      }
  }
}

  function setReviewModal(results,status,info)
  {
    console.log(results);
    $("#headreview").show();
    document.getElementById('bodyreview').innerHTML = "";
    document.getElementById('headreview').innerHTML = "
" + "Author" + "	" + "" + "Experience" + "	" + "" + "Rating / 5" + "	" + "
";
    var allReviews = $.extend(true, [], results);

    for(var i = 0; i < results.reviews.length; i++)
    {
      //console.log("allReviews Before: " + allReviews[i].text);
      if(results.reviews[i].text.length < 5 )break;
      if(results.reviews[i].text.length > 100)
        results.reviews[i].text = results.reviews[i].text.substr(0,100);
      //console.log("allReviews After: " + allReviews[i].text);
      document.getElementById('bodyreview').innerHTML += "
" + "" + results.reviews[i].author_name + "	" +  "" + results.reviews[i].text + "...." + "	"
      + "" + results.reviews[i].rating  + "	" + "
";

    }

    flip(false);
    moreInfo(allReviews);
  }

  function moreInfo(allResults)
  {
    console.log(allResults)
    $(".reviewrows").click(function(){

      //clicked results object is the children of the tr, so the author text and rating td's
      var clickedResult = $(this).children();
      for(var i=0; i < allResults.reviews.length; i++)
      {
        if (allResults.reviews[i].author_name == clickedResult[0].innerHTML )
        {
          $("#headreview").hide();
          document.getElementById('bodyreview').innerHTML = allResults.reviews[i].text;

        }
      }
    });
  }

  function calculateDistance(locations,latitude,longitude)
   {
      var distanceArray = new Array();
      for (var i=0; i < locations.length; i++)
      {
        distanceArray[i] = getDistanceFromLatLonInKm(latitude, longitude, locations[i].geometry.location.k, locations[i].geometry.location.D)
        //console.log("Distance Value" + distanceArray[i]);
      }
      return distanceArray;
   }

  function getDistanceFromLatLonInKm(lat1,lon1,lat2,lon2)
    {
      //var r = 6378100; //Radius of the earth in m
      var R = 6371; // Radius of the earth in km
      var kmtoMi = 0.621371;
      var dLat = deg2rad(lat2-lat1);  // deg2rad below
      var dLon = deg2rad(lon2-lon1);
      var a =
      Math.sin(dLat/2) * Math.sin(dLat/2) +
      Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2)) *
      Math.sin(dLon/2) * Math.sin(dLon/2);
      var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
      var d = R * c; // Distance in km
      return d * 0.621371;
    }

  function deg2rad(deg)
    {
      return deg * (Math.PI/180)
    }

function navigate()
  {

    var mobileMap = "http://maps.google.com/maps?saddr="+latitude + "," + longitude + "&daddr=" + currLat + "," + currLong;
    var x = document.getElementById('vehicle').value;
    mapUrl = "comgooglemaps://?saddr=" + latitude + "," + longitude + "&daddr=" + currLat + "," + currLong + "&directionsmode=" + x;
    if (isMobile.iOS())
    {
      setTimeout(function () { window.location = mapUrl; }, 25);

      window.location = "http://maps.apple.com/maps?saddr=" + latitude + "," + longitude + "&daddr=" + currLat + "," + currLong;
    }

   if(isMobile.Android())
     window.location = "http://maps.google.com/maps?saddr="+ latitude + "," + longitude+ "&daddr="+currLat+","+currLong;

   window.location = mobileMap;
  }

jQuery(document).ready(function($){

  //how long to wait to make the arrow visible.
  var offset = 300,
    //reduce the opacity of the arrow once we reach this point.
    offset_opacity = 1200,

    scroll_top_duration = 700,
    //back to top arrow.
    $back_to_top = $('.cd-top');

  //show or hide the arrow.
  $(window).scroll(function(){
    ( $(this).scrollTop() > offset ) ? $back_to_top.addClass('cd-is-visible') : $back_to_top.removeClass('cd-is-visible cd-fade-out');
    if( $(this).scrollTop() > offset_opacity ) {
      $back_to_top.addClass('cd-fade-out');
    }
  });

  //smooth scroll to top
  $back_to_top.on('click', function(event){
    event.preventDefault();
    $('body,html').animate({
      scrollTop: 0 ,
      }, scroll_top_duration
    );
  });

});

  function flip(back)
  {
    if (back === true)
    {
      $(".modal").modal('hide');
       setTimeout(function(){$("#myModal").modal('show');},1500);
    }
    //var front = document.getElementById('myModal');

    //var back_content = $('#reviewmodal').html();
    /*var back;
    back = flippant.flip(front, back_content,'card');
    */
    if(back === false)
    {
    $("#myModal").modal('hide');

    setTimeout(function(){
      $('#modaltest').modal({
        keyboard: true
      });
    },500);

    }
}

<|endoftext|>