<commit_before>/**

	Player Object

**/

PAVO.player = new function() {

	var SPIN_RATE = -0.007;
	var NORMAL_SPEED = 10;
	var SPRINT_SPEED = 50;

	var self = this;

	var motion = {
		moveleft: false, moveright: false,
		movefore: false, moveback: false
	};

	var mouse = {
		down: false,
		x: 0,
		y: 0
	};

	var temp = {
		position: new FOAM.Vector()
	};

	FOAM.Camera.prototype = new FOAM.Thing();
	this.camera = new FOAM.Camera();

	this.pitch = new FOAM.Thing();
	this.yaw = new FOAM.Thing();

	this.position = new FOAM.Vector();
	this.velocity = new FOAM.Vector();
	this.sprint = false;
	this.debug = false;

	this.init = function() {
		jQuery(window).bind("keydown", this.onKeyDown);
		jQuery(window).bind("keyup", this.onKeyUp);
		jQuery("#gl").bind("mousedown", this.onMouseDown);
		jQuery("#gl").bind("mouseup", this.onMouseUp);
		jQuery("#gl").bind("mousemove", this.onMouseMove);
		self.camera.nearLimit = 0.01;
		self.camera.farLimit = 1024;

		// orientation vectors will be treated as quaternions
		// and need a w-component for copies to be meaningful
		self.pitch.orientation.right.w = 0;
		self.pitch.orientation.up.w = 0;
		self.pitch.orientation.front.w = 0;
		self.yaw.orientation.right.w = 0;
		self.yaw.orientation.up.w = 0;
		self.yaw.orientation.front.w = 0;
	};

	this.update = function() {
		var dt = FOAM.interval * 0.001;
		var speed = (this.sprint) ? SPRINT_SPEED : NORMAL_SPEED;

		// determine new velocity
		this.velocity.set();
		if (motion.movefore) {
			this.velocity.sub(self.camera.orientation.front);
		}
		if (motion.moveback) {
			this.velocity.add(self.camera.orientation.front);
		}
		if (motion.moveleft) {
			this.velocity.sub(self.camera.orientation.right);
		}
		if (motion.moveright) {
			this.velocity.add(self.camera.orientation.right);
		}
		this.velocity.norm().mul(dt * speed);
		temp.position.copy(this.position).add(this.velocity);

		// test collision
		if (this.debug || !PAVO.space.testCollision(this.position, temp.position)) {
			this.position.copy(temp.position);
		}
		self.camera.position.copy(this.position);
	};

	this.onKeyDown = function(event) {
		switch(event.keyCode) {
			case FOAM.KEY.A:
				motion.moveleft = true;
				break;
			case FOAM.KEY.D:
				motion.moveright = true;
				break;
			case FOAM.KEY.W:
				motion.movefore = true;
				break;
			case FOAM.KEY.S:
				motion.moveback = true;
				break;
			case FOAM.KEY.SHIFT:
				self.sprint = true;
				break;
			case FOAM.KEY.X:
				self.debug = !self.debug;
				break;
			default:
				//window.alert(event.keyCode);
				break;
		}
	};

	this.onKeyUp = function(event) {
		switch(event.keyCode) {

			case FOAM.KEY.A:
				motion.moveleft = false;
				break;
			case FOAM.KEY.D:
				motion.moveright = false;
				break;
			case FOAM.KEY.W:
				motion.movefore = false;
				break;
			case FOAM.KEY.S:
				motion.moveback = false;
				break;
			case FOAM.KEY.SHIFT:
				self.sprint = false;
				break;
			default:
				break;
		}
	};

	this.onMouseDown = function(event) {
		mouse.down = true;
		return false;
	};

	this.onMouseUp = function(event) {
		mouse.down = false;
		return false;
	};

	this.onMouseMove = function(event) {
		var dx, dy;
		if (mouse.down) {
			dx = SPIN_RATE * (event.pageX - mouse.x);
			dy = SPIN_RATE * (event.pageY - mouse.y);

			// clumsy, but it works. rotate the first quaternion by
			// pitch angle, then use its orientation vectors as the
			// basis vectors for the yaw rotation. insures no roll!
			self.pitch.turn(dy, 0, 0);
			self.yaw.unitquat.x.copy(self.pitch.orientation.right);
			self.yaw.unitquat.y.copy(self.pitch.orientation.up);
			self.yaw.unitquat.z.copy(self.pitch.orientation.front);
			self.yaw.turn(0, dx, 0);
			self.camera.unitquat.x.copy(self.yaw.orientation.right);
			self.camera.unitquat.y.copy(self.yaw.orientation.up);
			self.camera.unitquat.z.copy(self.yaw.orientation.front);
			self.camera.turn(0, 0, 0);

		}
		mouse.x = event.pageX;
		mouse.y = event.pageY;
		return false;
	};
};

<commit_msg>Fixed player object to remove redundant quaternion object.<commit_after>/**

	Player Object

**/

PAVO.player = new function() {

	var SPIN_RATE = -0.007;
	var NORMAL_SPEED = 10;
	var SPRINT_SPEED = 50;

	var self = this;

	var motion = {
		moveleft: false, moveright: false,
		movefore: false, moveback: false
	};

	var mouse = {
		down: false,
		x: 0,
		y: 0
	};

	var temp = {
		position: new FOAM.Vector()
	};

	FOAM.Camera.prototype = new FOAM.Thing();
	this.camera = new FOAM.Camera();
	this.pitch = new FOAM.Thing();

	this.position = new FOAM.Vector();
	this.velocity = new FOAM.Vector();
	this.sprint = false;
	this.debug = false;

	this.init = function() {
		jQuery(window).bind("keydown", this.onKeyDown);
		jQuery(window).bind("keyup", this.onKeyUp);
		jQuery("#gl").bind("mousedown", this.onMouseDown);
		jQuery("#gl").bind("mouseup", this.onMouseUp);
		jQuery("#gl").bind("mousemove", this.onMouseMove);
		self.camera.nearLimit = 0.01;
		self.camera.farLimit = 1024;

		// orientation vectors will be treated as quaternions
		// and need a w-component for copies to be meaningful
		self.pitch.orientation.right.w = 0;
		self.pitch.orientation.up.w = 0;
		self.pitch.orientation.front.w = 0;
	};

	this.update = function() {
		var dt = FOAM.interval * 0.001;
		var speed = (this.sprint) ? SPRINT_SPEED : NORMAL_SPEED;

		// determine new velocity
		this.velocity.set();
		if (motion.movefore) {
			this.velocity.sub(self.camera.orientation.front);
		}
		if (motion.moveback) {
			this.velocity.add(self.camera.orientation.front);
		}
		if (motion.moveleft) {
			this.velocity.sub(self.camera.orientation.right);
		}
		if (motion.moveright) {
			this.velocity.add(self.camera.orientation.right);
		}
		this.velocity.norm().mul(dt * speed);
		temp.position.copy(this.position).add(this.velocity);

		// test collision
		if (this.debug || !PAVO.space.testCollision(this.position, temp.position)) {
			this.position.copy(temp.position);
		}
		self.camera.position.copy(this.position);
	};

	this.onKeyDown = function(event) {
		switch(event.keyCode) {
			case FOAM.KEY.A:
				motion.moveleft = true;
				break;
			case FOAM.KEY.D:
				motion.moveright = true;
				break;
			case FOAM.KEY.W:
				motion.movefore = true;
				break;
			case FOAM.KEY.S:
				motion.moveback = true;
				break;
			case FOAM.KEY.SHIFT:
				self.sprint = true;
				break;
			case FOAM.KEY.X:
				self.debug = !self.debug;
				break;
			default:
				//window.alert(event.keyCode);
				break;
		}
	};

	this.onKeyUp = function(event) {
		switch(event.keyCode) {

			case FOAM.KEY.A:
				motion.moveleft = false;
				break;
			case FOAM.KEY.D:
				motion.moveright = false;
				break;
			case FOAM.KEY.W:
				motion.movefore = false;
				break;
			case FOAM.KEY.S:
				motion.moveback = false;
				break;
			case FOAM.KEY.SHIFT:
				self.sprint = false;
				break;
			default:
				break;
		}
	};

	this.onMouseDown = function(event) {
		mouse.down = true;
		return false;
	};

	this.onMouseUp = function(event) {
		mouse.down = false;
		return false;
	};

	this.onMouseMove = function(event) {
		var dx, dy;
		if (mouse.down) {
			dx = SPIN_RATE * (event.pageX - mouse.x);
			dy = SPIN_RATE * (event.pageY - mouse.y);

			// clumsy, but it works. rotate the first quaternion by
			// pitch angle, then use its orientation vectors as the
			// basis vectors for the yaw rotation. insures no roll!
			self.pitch.turn(dy, 0, 0);
			self.camera.unitquat.x.copy(self.pitch.orientation.right);
			self.camera.unitquat.y.copy(self.pitch.orientation.up);
			self.camera.unitquat.z.copy(self.pitch.orientation.front);
			self.camera.turn(0, dx, 0);

		}
		mouse.x = event.pageX;
		mouse.y = event.pageY;
		return false;
	};
};

<|endoftext|>


<commit_before>
module.exports = {

  VERSION: "Default JavaScript folding player",

  bet_request: function(game_state, bet) {

   try
{

    var cards =  getMyCards(game_state),
        player = getMyPlayer(game_state),
        myBet = 0,
        trans = {
            "1": 1,
            "2": 2,
            "3": 3,
            "4": 4,
            "5": 5,
            "6": 6,
            "7": 7,
            "8": 8,
            "9": 9,
            "10": 10,
            "J": 11,
            "Q": 12,
            "K": 13,
            "A": 14
        },
        x = trans(cards[0].rank),
        y = trans(cards[1].rank);

    // OPENING HAND
    // The cards are equal
    if (x === y) {
        myBet = game_state.pot * 2;
      if ( x >== 10) {
        myBet = player.stack;
      }
    }

    console.log(cards[0]);
    console.log(cards[1]);
    console.log("My bet is : " + myBet);
    bet(myBet);

}
catch (ex)
{
    console.log("Caught exception: " + ex);
}

  function getMyCards(game_state) {

      var cards_down = game_state.community_cards;
      var players = game_state.players;

     var nrOfPlayers = players.length;
        for (var i=0; i<nrOfPlayers;i++) {
            if (players[i].name == 'Comfortable Pugs') {
                return players[i].hole_cards;
            }
        }

   };
 function getAllCards(game_state) {
        var myCards = getMyCards(game_state);
        var cards_down = game_state.community_cards;

        cards.push(myCards[0]);
        cards.push(myCards[1]);

        var cards = [];
        var cardsDownSize = cards_down.length;
         for (var i=0; i<cardsDownSize;i++) {
            cards.push(cards_down[i]);
        }
        return cards;
    };
    function getMyPlayer(game_state) {
              var players = game_state.players;

     var nrOfPlayers = players.length;
        for (var i=0; i<nrOfPlayers;i++) {
            if (players[i].name == 'Comfortable Pugs') {
                return players[i];
            }
        }
    }

  },

  showdown: function(game_state) {

  },

};
<commit_msg>Revert "Initial hand logic"<commit_after>
module.exports = {

  VERSION: "Default JavaScript folding player",

  bet_request: function(game_state, bet) {

   try
{

    var cards =  getMyCards(game_state),
        player = getMyPlayer(game_state),
        myBet = game_state.current_buy_in;
   /* if (cards[0].rank === cards[1].rank) {
       bet(game_state.pot);
    } else {
       bet(game_state.current_buy_in);
    }*/

    console.log(cards[0]);
    console.log(cards[1]);
    if (cards[1].rank === cards[1].rank) {
        myBet = game_state.current_buy_in * 2;
    }
    bet(myBet);

}
catch (ex)
{
    console.log("Caught exception: " + ex);
}

  function getMyCards(game_state) {

      var cards_down = game_state.community_cards;
      var players = game_state.players;

     var nrOfPlayers = players.length;
        for (var i=0; i<nrOfPlayers;i++) {
            if (players[i].name == 'Comfortable Pugs') {
                return players[i].hole_cards;
            }
        }

   };
 function getAllCards(game_state) {
        var myCards = getMyCards(game_state);
        var cards_down = game_state.community_cards;

        cards.push(myCards[0]);
        cards.push(myCards[1]);

        var cards = [];
        var cardsDownSize = cards_down.length;
         for (var i=0; i<cardsDownSize;i++) {
            cards.push(cards_down[i]);
        }
        return cards;
    };
    function getMyPlayer(game_state) {
              var players = game_state.players;

     var nrOfPlayers = players.length;
        for (var i=0; i<nrOfPlayers;i++) {
            if (players[i].name == 'Comfortable Pugs') {
                return players[i];
            }
        }
    }

  },

  showdown: function(game_state) {

  },

};
<|endoftext|>


<commit_before>
module.exports = {

  VERSION: "Preflop stage active",

  /**
   * @returns false - если не префлоп
   *      1000 - если пара или больше или равно 10
   *      0 - если нужно сбросить карты
   */
  preflop_stage: function(game_state) {
    var player = game_state.players[game_state.in_action];

    if ( game_state.community_cards && game_state.community_cards.length == 0 ) {
      return false;
    }

    if ( player.hole_cards.length != 2 ) {
      return false;
    }

    var card1 = player.hole_cards[0], card2 = player.hole_cards[1];

    if (
      card1.rank == card2.rank
    ) {
      return 1000;
    }

    if (
      (
        card1.rank == '10'
        || card1.rank == 'J'
        || card1.rank == 'Q'
        || card1.rank == 'K'
        || card1.rank == 'A'
      ) && (
        card2.rank == '10'
        || card2.rank == 'J'
        || card2.rank == 'Q'
        || card2.rank == 'K'
        || card2.rank == 'A'
      )
    ) {
      return 1000;
    }

    return 10;
  },

  bet_request: function(game_state) {
    console.log("game_state !!!", game_state);
    var preflop = preflop_stage(game_state);
    if (preflop === false) {
      return 1000;
    }
    return preflop;
  },

  // rank2Num: function(rank) {
  //   switch (rank) {
  //     case 'J': return 11;
  //     case 'Q': return 12;
  //     case 'K': return 13;
  //     case 'A': return 14;
  //     default: return rank;
  //   }
  // },

  showdown: function(game_state) {

  },

  should_bet_after_flop: function(cards) {

    return true;
  },

  any_cards_are_equal: function(cards) {
    for (var i = 0; i < cards.length-1; i++) {
      for (var j = i+1; j < cards.length; j++) {
        if (cards[i].rank == cards[j].rank)
          return true;
      }
    }
    return false;
  },

  get_player_cards: function(game_state) {
    var index = game_state.in_action;

    if (game_state.players[index]) {
      return game_state.players[index].hole_cards;
    }

    console.log("player not found", game_state);
  }

};
<commit_msg>bugfix: preflop active<commit_after>
module.exports = {

  VERSION: "Preflop stage active",

  /**
   * @returns false - если не префлоп
   *      1000 - если пара или больше или равно 10
   *      0 - если нужно сбросить карты
   */
  preflop_stage: function(game_state) {
    var player = game_state.players[game_state.in_action];

    if ( game_state.community_cards && game_state.community_cards.length == 0 ) {
      return false;
    }

    if ( player.hole_cards.length != 2 ) {
      return false;
    }

    var card1 = player.hole_cards[0], card2 = player.hole_cards[1];

    if (
      card1.rank == card2.rank
    ) {
      return 1000;
    }

    if (
      (
        card1.rank == '10'
        || card1.rank == 'J'
        || card1.rank == 'Q'
        || card1.rank == 'K'
        || card1.rank == 'A'
      ) && (
        card2.rank == '10'
        || card2.rank == 'J'
        || card2.rank == 'Q'
        || card2.rank == 'K'
        || card2.rank == 'A'
      )
    ) {
      return 1000;
    }

    return 10;
  },

  bet_request: function(game_state) {
    console.log("game_state !!!", game_state);
    var preflop = this.preflop_stage(game_state);
    if (preflop === false) {
      return 1000;
    }
    return preflop;
  },

  // rank2Num: function(rank) {
  //   switch (rank) {
  //     case 'J': return 11;
  //     case 'Q': return 12;
  //     case 'K': return 13;
  //     case 'A': return 14;
  //     default: return rank;
  //   }
  // },

  showdown: function(game_state) {

  },

  should_bet_after_flop: function(cards) {

    return true;
  },

  any_cards_are_equal: function(cards) {
    for (var i = 0; i < cards.length-1; i++) {
      for (var j = i+1; j < cards.length; j++) {
        if (cards[i].rank == cards[j].rank)
          return true;
      }
    }
    return false;
  },

  get_player_cards: function(game_state) {
    var index = game_state.in_action;

    if (game_state.players[index]) {
      return game_state.players[index].hole_cards;
    }

    console.log("player not found", game_state);
  }

};
<|endoftext|>


<commit_before>module.exports = function (matrix) {
    var self = '11011011011111111111111111111111';

    var player = {
        response: function (point) {
            return [point, point, point, self];
        }
    };

    var around = [
        0,      1,      2,
        3,   /* i */    5,
        6,      7,      8
    ];

    var freeIndex = [];
    var selfIndex = [];
    var enemyIndex = [];

    for (var point of around) {
        if (matrix[point] === 0) {
            freeIndex.push(point);
        } else if (matrix[point] === self) {
            selfIndex.push(point);
        } else {
            enemyIndex.push(point);
        }
    }

    if (freeIndex.length === 8) {
        return player.response(5);
    }

    if (enemyIndex.length === 8) {
        return player.response(8);
    }

    if (selfIndex.length === 8) {
        return player.response(0);
    }

    if (enemyIndex.length === 0) {
        var restFree = [];

        for (var point of freeIndex) {
            if (selfIndex.indexOf(point + 4) === -1) {
                restFree.push(point);
            }
        }

        if (restFree.length) {
            return player.response(restFree[0]);
        }

        return player.response(selfIndex[0]);
    }

    var attackPoint = 1;

    if (enemyIndex.indexOf(attackPoint) > -1) {
        return player.response(attackPoint);
    }

    var restEnemy = [];

    for (var point of enemyIndex) {
        if (selfIndex.indexOf(point + 3) === -1) {
            restEnemy.push(point);
        }
    }

    if (restEnemy.length) {
        return player.response(restEnemy[0]);
    }

    if (freeIndex.length) {
        return player.response(freeIndex[0]);
    }

    return player.response(enemyIndex[0]);
};<commit_msg>scrutinizer name<commit_after>module.exports = function (matrix) {
    var self = '11011011011111111111111111111111';

    var player = {
        response: function (point) {
            return [point, point, point, self];
        }
    };

    var around = [
        0,      1,      2,
        3,   /* i */    5,
        6,      7,      8
    ];

    var freeIndex = [];
    var selfIndex = [];
    var enemyIndex = [];

    for (var point of around) {
        if (matrix[point] === 0) {
            freeIndex.push(point);
        } else if (matrix[point] === self) {
            selfIndex.push(point);
        } else {
            enemyIndex.push(point);
        }
    }

    if (freeIndex.length === 8) {
        return player.response(5);
    }

    if (enemyIndex.length === 8) {
        return player.response(8);
    }

    if (selfIndex.length === 8) {
        return player.response(0);
    }

    if (enemyIndex.length === 0) {
        var restFree = [];

        for (var freePoint of freeIndex) {
            if (selfIndex.indexOf(freePoint + 4) === -1) {
                restFree.push(freePoint);
            }
        }

        if (restFree.length) {
            return player.response(restFree[0]);
        }

        return player.response(selfIndex[0]);
    }

    var attackPoint = 1;

    if (enemyIndex.indexOf(attackPoint) > -1) {
        return player.response(attackPoint);
    }

    var restEnemy = [];

    for (var enemyPoint of enemyIndex) {
        if (selfIndex.indexOf(enemyPoint + 3) === -1) {
            restEnemy.push(enemyPoint);
        }
    }

    if (restEnemy.length) {
        return player.response(restEnemy[0]);
    }

    if (freeIndex.length) {
        return player.response(freeIndex[0]);
    }

    return player.response(enemyIndex[0]);
};<|endoftext|>


<commit_before>'use strict';

const getRanking = require('./ranking');

let gameState, myplayer;
module.exports = {
  VERSION: "Kickstarter",
  bet_request: function(game_state, bet) {
    new Promise((resolve, reject) => {
        gameState =  game_state;
        myplayer = game_state.players[game_state.in_action];
        console.log(myplayer.hole_cards);
        console.log(game_state);

        //Check for zero phase

        let promise;
        if(gameState.community_cards.length <= 3){
          promise = Promise.resolve(phase_zero());
        } else {
          promise = Promise.resolve(phase_two());
        }
        promise.then(resolve, reject);
    }).then(value => {
        bet(value);
    }).catch(err => {
        console.log('ERROR', err);
    });
  },
  showdown: function(game_state) {
  }
};

function phase_zero (){

  const rank = evaluate(myplayer.hole_cards);
  console.log("phase zero", rank);
  if(rank >= 3){
    return minimalRaise();
  }else if (rank ===2) {
    return call();
  }
  console.log('neither raise nor call');
  const highCards = myplayer.hole_cards.filter(isHighCard);
  if(highCards.length > 0 && isSmallBlind()) {
    console.log('we have a high card and it is still small blind - call!');
    return callMax(gameState.small_blind * 4);
  }
  return fold();
}

function phase_two (){
  console.log('phase 2!');
  const allCards = gameState.community_cards.map(item => item);
  myplayer.hole_cards.forEach(item => allCards.push(item));
  console.log('allcards', allCards);

  if(isSuited(myplayer.hole_cards)) {
    const suit = myplayer.hole_cards[0].suit;
    const suited = gameState.community_cards.filter(card => {
        return card.suit === suit;
    }).length;

    if(suited === 3) { // FLUSH!
        return allIn();
    } else if(suited == 2) {
        if(gameState.community_cards.length < 5) { // flush still possible
            return minimalRaise();
        } // else use ranking
    }
  }

  // const communityOnly = getRanking(gameState.community_cards);
  const withOurCards = getRanking(allCards);
  return Promise.all([/*communityOnly,*/ withOurCards]).then((rankingData) => {
    // const communityRank = rankingData[0].rank;
    const allCardsRank = rankingData[0].rank;

    // console.log('community and allcards rank:', communityRank, allCardsRank);

    // if(communityRank > allCardsRank) {
    //     console.log('communityRank > allCardsRank', communityRank, allCardsRank);
    //     return Math.random() >= 0.7? call():fold(); // 70% call
    // }

    if(allCardsRank >= 8) {
        return allIn();
    } else if(allCardsRank >= 5) {
        return minimalRaise();
    } else if(allCardsRank >= 3) {
        return call();
    } else if(allCardsRank >= 2) {
        return call();
    } else if(allCardsRank >= 1) {
        return call();
    } else {
        return fold();
    }
  }, err => {
    console.log('ERROR could not get rank', err);
    return call();
  });

  // const rank = evaluate(myplayer.hole_cards);
  // if(rank === 3){
  //   return gameState.minimum_raise;
  // }else if (rank ===2) {
  //   return call();
  // }
  // return fold();
}

function evaluate (cards){
  const first = cards[0];
  const second = cards[1];
  if(first.rank === second.rank){ // check pair
    return 3;
  }else if(isSuited(cards)){
    return 2;
  } else {
    return 0;
  }
}

function isHighCard(card) {
    const highCards = ['J', 'Q', 'A', 'K', '10'];
    return highCards.indexOf(card.rank.toUpperCase()) >= 0;
}

function isSmallBlind() {
    return gameState.current_buy_in === gameState.small_blind;
}

function callMax(max) {
    const called = call();
    return Math.min(max, called); // if "max" is selected, we fold
}

function isSuited(cards){
  const first = cards[0];
  const second = cards[1];
  if(first.suit === second.suit){
    return true;
  }
  return false;

}

function call (){
  const c = gameState.current_buy_in - gameState.players[gameState.in_action].bet;
  return c;
}

function allIn(){
  const c = myplayer.stack;
  return c;
}

function fold(){
  return 0;
}

function minimalRaise() {
    return call() + gameState.minimum_raise;
}<commit_msg>redo first phase<commit_after>'use strict';

const getRanking = require('./ranking');

let gameState, myplayer;
module.exports = {
  VERSION: "Kickstarter",
  bet_request: function(game_state, bet) {
    new Promise((resolve, reject) => {
        gameState =  game_state;
        myplayer = game_state.players[game_state.in_action];
        console.log(myplayer.hole_cards);
        console.log(game_state);

        //Check for zero phase

        let promise;
        if(gameState.community_cards.length <= 3){
          promise = Promise.resolve(phase_zero());
        } else {
          promise = Promise.resolve(phase_two());
        }
        promise.then(resolve, reject);
    }).then(value => {
        bet(value);
    }).catch(err => {
        console.log('ERROR', err);
    });
  },
  showdown: function(game_state) {
  }
};

function phase_zero (){

  const rank = evaluate(myplayer.hole_cards);
  console.log("phase zero", rank);
  if(rank >= 3){
    return minimalRaise();
  }else if (rank >= 1) {
    return call();
  }
  console.log('neither raise nor call');
  const highCards = myplayer.hole_cards.filter(isHighCard);
  if(highCards.length > 0 && isSmallBlind()) {
    console.log('we have a high card and it is still small blind - call!');
    return callMax(gameState.small_blind * 4);
  }
  return fold();
}

function phase_two (){
  console.log('phase 2!');
  const allCards = gameState.community_cards.map(item => item);
  myplayer.hole_cards.forEach(item => allCards.push(item));
  console.log('allcards', allCards);

  if(isSuited(myplayer.hole_cards)) {
    const suit = myplayer.hole_cards[0].suit;
    const suited = gameState.community_cards.filter(card => {
        return card.suit === suit;
    }).length;

    if(suited === 3) { // FLUSH!
        return allIn();
    } else if(suited == 2) {
        if(gameState.community_cards.length < 5) { // flush still possible
            return minimalRaise();
        } // else use ranking
    }
  }

  // const communityOnly = getRanking(gameState.community_cards);
  const withOurCards = getRanking(allCards);
  return Promise.all([/*communityOnly,*/ withOurCards]).then((rankingData) => {
    // const communityRank = rankingData[0].rank;
    const allCardsRank = rankingData[0].rank;

    // console.log('community and allcards rank:', communityRank, allCardsRank);

    // if(communityRank > allCardsRank) {
    //     console.log('communityRank > allCardsRank', communityRank, allCardsRank);
    //     return Math.random() >= 0.7? call():fold(); // 70% call
    // }

    if(allCardsRank >= 8) {
        return allIn();
    } else if(allCardsRank >= 5) {
        return minimalRaise();
    } else if(allCardsRank >= 3) {
        return call();
    } else if(allCardsRank >= 2) {
        return call();
    } else if(allCardsRank >= 1) {
        return call();
    } else {
        return fold();
    }
  }, err => {
    console.log('ERROR could not get rank', err);
    return call();
  });

  // const rank = evaluate(myplayer.hole_cards);
  // if(rank === 3){
  //   return gameState.minimum_raise;
  // }else if (rank ===2) {
  //   return call();
  // }
  // return fold();
}

function evaluate (cards){
  const first = cards[0];
  const second = cards[1];
  if(first.rank === second.rank){ // check pair
    return 3;
  }else if(isSuited(cards)){
    return 2;
  } else if(isHighCard(first) || isHighCard(second)) {
    return 1;
  }else {
    return 0;
  }
}

function isHighCard(card) {
    const highCards = ['J', 'Q', 'A', 'K', '10'];
    return highCards.indexOf(card.rank.toUpperCase()) >= 0;
}

function isSmallBlind() {
    return gameState.current_buy_in === gameState.small_blind;
}

function callMax(max) {
    const called = call();
    return Math.min(max, called); // if "max" is selected, we fold
}

function isSuited(cards){
  const first = cards[0];
  const second = cards[1];
  if(first.suit === second.suit){
    return true;
  }
  return false;

}

function call (){
  const c = gameState.current_buy_in - gameState.players[gameState.in_action].bet;
  return c;
}

function allIn(){
  const c = myplayer.stack;
  return c;
}

function fold(){
  return 0;
}

function minimalRaise() {
    return call() + gameState.minimum_raise;
}<|endoftext|>


<commit_before>
module.exports = {

  VERSION: "Default JavaScript folding player",

  bet_request: function(game_state, bet) {
    bet(0);
  },

  showdown: function(game_state) {

  }
};
<commit_msg>All in<commit_after>
module.exports = {

  VERSION: "Default JavaScript folding player",

  bet_request: function(game_state, bet) {
    bet(10000);
  },

  showdown: function(game_state) {

  }
};
<|endoftext|>


<commit_before>"use strict";
/*global alert: true, ODSA */
(function ($) {
  var jsav;
  var graph;
  var mst;   //A graph representing the resulted MST
  var tree;  //Union/Find Tree
  var gnodes = [];
  var mstnodes = [];
  var treeNodes = [];
  var labels;
  var weights;
  var parents;
  var treeLabels;
  var arr;     //Used to initialize the distance and labels arrays.

  function runit() {
    var i;
    ODSA.AV.reset(true);
    jsav = new JSAV($('.avcontainer'));
    graph = jsav.ds.graph({width: 600, height: 400, layout: "manual", directed: false});
    mst = jsav.ds.graph({width: 600, height: 400, layout: "manual", directed: false});
	mst.hide();
    initGraph();
    initTree();
    graph.layout();
	tree.layout();
    arr = new Array(graph.edges().length);
    for (i = 0; i < arr.length; i++) {
      arr[i] = "("+graph.edges()[i].start().value()+","+graph.edges()[i].end().value()+")";
    }
    labels = jsav.ds.array(arr, {layout: "vertical", left: 673, top: -120});
    for (i = 0; i < arr.length; i++) {
      arr[i] = graph.edges()[i].weight();
    }
    weights = jsav.ds.array(arr, {layout: "vertical", left: 720, top: -120});

	arr = new Array(gnodes.length);
    //Initializing the labels
    for (i = 0; i < arr.length; i++) {
      arr[i] = String.fromCharCode(i + 65);
    }
	treeLabels = jsav.ds.array(arr, {left: 0, top: 40, indexed: true});
    //Initializing the parent pointer
    for (i = 0; i < arr.length; i++) {
      arr[i] = "/";
    }
    parents = jsav.ds.array(arr, {left: 0, top: -7});
    jsav.displayInit();
    kruskal();
    displayMST();
    jsav.recorded();
  }
  function findMinimumEdge() {
    var minEdge;
    var i;
    for (i = 0; i < graph.edges().length; i++) {
      if (!graph.edges()[i].hasClass('visited')) {
        minEdge = graph.edges()[i];
        break;
      }
    }
    for (i = 0; i < graph.edges().length; i++) {
      if ((graph.edges()[i].weight() <= minEdge.weight()) && !graph.edges()[i].hasClass('visited')) {
        minEdge = graph.edges()[i];
      }
    }
    return minEdge;
  }
  function displayMST() {
    graph.hide();
	tree.hide();
	treeLabels.hide();
	parents.hide();
	mst.show();
    mst.layout();
    jsav.umsg("Complete minimum spanning tree");
  }

  // Mark a node in the graph.
  function markIt(node) {
    node.addClass("visited");
    //jsav.umsg("Add node " + node.value() + " to the MST");
    node.highlight();
    //jsav.step();
  }

  function kruskal() {
    var i;
    var minEdge;
    var startNode;
    var endNode;
    var startTreeNode;
    var endTreeNode;
    var alreadyUnioned;
    var msg;
    var mstedge;
    for (i = 0; i < graph.edges().length; i++) {
      msg = "";
      minEdge = findMinimumEdge();
      startNode = minEdge.start();
      endNode = minEdge.end();
      startTreeNode = treeNodes[gnodes.indexOf(startNode)];
      endTreeNode = treeNodes[gnodes.indexOf(endNode)];
	  jsav.umsg("Processing Edge ("+startNode.value()+","+endNode.value()+"):");
	  jsav.step();
      alreadyUnioned = union(startTreeNode, endTreeNode);
      if (alreadyUnioned === false) {
        //Add to MST
        jsav.umsg("
Add edge to the MST", {'preserve': true});
        minEdge.css({"stroke-width": "4", "stroke": "red"});
        weights.css(graph.edges().indexOf(minEdge), {'background-color':'red'});
        labels.css(graph.edges().indexOf(minEdge), {'background-color':'red'});
        markIt(startNode);
        markIt(endNode);
        mstedge = mst.addEdge(mstnodes[gnodes.indexOf(startNode)], mstnodes[gnodes.indexOf(endNode)], {"weight": minEdge.weight()});
        mstedge.css({"stroke-width": "2", "stroke": "red"});
      }
      else {
        jsav.umsg("
Dismiss edge", {'preserve': true});
        minEdge.css({"stroke-width": "4", "stroke": "orange"});
        weights.css(graph.edges().indexOf(minEdge), {'background-color':'orange'});
        labels.css(graph.edges().indexOf(minEdge), {'background-color':'orange'});
      }
      minEdge.addClass('visited');
      jsav.step();
      //End Algorithm when all Nodes are added to MST
      if (mst.edges().length === gnodes.length-1) {
        break;
      }
    }
  }
  function find(treeNode) {
    if (treeNode.parent() === tree.root()) {
      return treeNode;
    }
    else {
      var currentNode = treeNode;
      while (currentNode.parent() !== tree.root()) {
        currentNode = currentNode.parent();
      }
      return currentNode;
    }
  }
  function union(node1, node2) {
    //First we have to find which one has the least size
    var parent1 = find(node1);
    var parent2 = find(node2);
	var index1 = treeNodes.indexOf(parent1);
    var index2 = treeNodes.indexOf(parent2);
	jsav.umsg('
Parent Of Node ('+node1.value()+') is ('+parent1.value()+')', {'preserve': true});
	parent1.highlight();
	treeLabels.highlight(index1);
	jsav.step();
	jsav.umsg('
Parent Of Node ('+node2.value()+') is ('+parent2.value()+')', {'preserve': true});
	parent2.highlight();
	treeLabels.highlight(index2);
	jsav.step();
    if (parent1 === parent2) {
	  jsav.umsg('
Nodes are already Unioned', {'preserve': true});
      parent1.unhighlight();
      treeLabels.unhighlight(index1);
      parent2.unhighlight();
      treeLabels.unhighlight(index2);
	  jsav.step();
      return true;
    }
    else if (parent1.size === parent2.size) {
      if (parent1.value().charCodeAt(0) < parent2.value().charCodeAt(0)) {
        parent1.addChild(parent2);
        parent1.size++;
		parents.value(index2, index1);
      }
      else {
        parent2.addChild(parent1);
        parent2.size++;
		parents.value(index1, index2);
      }
    }
    else if (parent1.size > parent2.size) {
      parent1.addChild(parent2);
      parent1.size++;
	  parents.value(index2, index1);
    }
    else {
      parent2.addChild(parent1);
      parent2.size++;
	  parents.value(index1, index2);
    }
	jsav.umsg('
Union Nodes', {'preserve': true});
	parent1.unhighlight();
	treeLabels.unhighlight(index1);
	parent2.unhighlight();
	treeLabels.unhighlight(index2);
	tree.layout();
	jsav.step();
    return false;
  }
  function initTree() {
    var newNode;
    tree = jsav.ds.tree({left: 0, top: 90, nodegap: 20});
    var root = tree.newNode("X");
    tree.root(root);
    root.id("root");
    for (var i = 0; i < gnodes.length; i++) {
      newNode = tree.newNode(gnodes[i].value());
      newNode.size = 1;   //To maintain the size of each connected component
      root.addChild(newNode);
    }
    treeNodes = new Array(gnodes.length);
    for (i = 0; i < treeNodes.length; i++) {
      treeNodes[i] = tree.root().child(i);
    }
  }
  function about() {
    var mystring = "Kruskal's Algorithm Visualization\nWritten by Mohammed Fawzi and Cliff Shaffer\nCreated as part of the OpenDSA hypertextbook project.\nFor more information, see http://algoviz.org/OpenDSA\nWritten during Spring, 2013\nLast update: March, 2013\nJSAV library version " + JSAV.version();
    alert(mystring);
  }

  // Initialize the graph.
  function initGraph() {
    //Nodes of the original graph
    var a = graph.addNode("A", {"left": 240, "top": -15});
    var b = graph.addNode("B", {"left": 540, "top": -15});
    var c = graph.addNode("C", {"left": 360, "top": 10});
    var d = graph.addNode("D", {"left": 360, "top": 125});
    var e = graph.addNode("E", {"left": 215, "top": 225});
    var f = graph.addNode("F", {"left": 540, "top": 175});
    //Nodes of the MST
    mst.addNode("A", {"left": 25, "top": -15});
    mst.addNode("B", {"left": 325, "top": -15});
    mst.addNode("C", {"left": 145, "top": 10});
    mst.addNode("D", {"left": 145, "top": 125});
    mst.addNode("E", {"left": 0, "top": 225});
    mst.addNode("F", {"left": 325, "top": 175});
    //Original graph edges
    graph.addEdge(a, c, {"weight": 7});
    graph.addEdge(a, e, {"weight": 9});
    graph.addEdge(c, b, {"weight": 5});
    graph.addEdge(c, d, {"weight": 1});
    graph.addEdge(c, f, {"weight": 2});
    graph.addEdge(f, b, {"weight": 6});
    graph.addEdge(d, f, {"weight": 2});
    graph.addEdge(e, f, {"weight": 1});
    gnodes = graph.nodes();
    mstnodes = mst.nodes();
    for (var i = 0; i < mstnodes.length; i++) {
      gnodes[i].index = i;
    }
  }
  // Connect action callbacks to the HTML entities
  $('#about').click(about);
  $('#runit').click(runit);
  //$('#help').click(help);
  $('#reset').click(ODSA.AV.reset);
}(jQuery));
<commit_msg>Fixing layout problems<commit_after>"use strict";
/*global alert: true, ODSA */
(function ($) {
  var jsav;
  var graph;
  var mst;   //A graph representing the resulted MST
  var tree;  //Union/Find Tree
  var gnodes = [];
  var mstnodes = [];
  var treeNodes = [];
  var labels;
  var weights;
  var parents;
  var treeLabels;
  var arr;     //Used to initialize the distance and labels arrays.

  function runit() {
    var i;
    ODSA.AV.reset(true);
    jsav = new JSAV($('.avcontainer'));
    graph = jsav.ds.graph({width: 600, height: 400, layout: "manual", directed: false});
    mst = jsav.ds.graph({width: 600, height: 400, layout: "manual", directed: false});
	mst.hide();
    initGraph();
    initTree();
    graph.layout();
	tree.layout();
    arr = new Array(graph.edges().length);
    for (i = 0; i < arr.length; i++) {
      arr[i] = "("+graph.edges()[i].start().value()+","+graph.edges()[i].end().value()+")";
    }
    labels = jsav.ds.array(arr, {layout: "vertical", left: 673, top: -120});
    for (i = 0; i < arr.length; i++) {
      arr[i] = graph.edges()[i].weight();
    }
    weights = jsav.ds.array(arr, {layout: "vertical", left: 720, top: -120});

	arr = new Array(gnodes.length);
    //Initializing the labels
    for (i = 0; i < arr.length; i++) {
      arr[i] = String.fromCharCode(i + 65);
    }
	treeLabels = jsav.ds.array(arr, {left: 0, top: 40, indexed: true});
    //Initializing the parent pointer
    for (i = 0; i < arr.length; i++) {
      arr[i] = "/";
    }
    parents = jsav.ds.array(arr, {left: 0, top: -7});
    jsav.displayInit();
    kruskal();
    displayMST();
    jsav.recorded();
  }
  function findMinimumEdge() {
    var minEdge;
    var i;
    for (i = 0; i < graph.edges().length; i++) {
      if (!graph.edges()[i].hasClass('visited')) {
        minEdge = graph.edges()[i];
        break;
      }
    }
    for (i = 0; i < graph.edges().length; i++) {
      if ((graph.edges()[i].weight() <= minEdge.weight()) && !graph.edges()[i].hasClass('visited')) {
        minEdge = graph.edges()[i];
      }
    }
    return minEdge;
  }
  function displayMST() {
    graph.hide();
	tree.hide();
	treeLabels.hide();
	parents.hide();
	mst.show();
    mst.layout();
    jsav.umsg("Complete minimum spanning tree");
  }

  // Mark a node in the graph.
  function markIt(node) {
    node.addClass("visited");
    //jsav.umsg("Add node " + node.value() + " to the MST");
    node.highlight();
    //jsav.step();
  }

  function kruskal() {
    var i;
    var minEdge;
    var startNode;
    var endNode;
    var startTreeNode;
    var endTreeNode;
    var alreadyUnioned;
    var msg;
    var mstedge;
    for (i = 0; i < graph.edges().length; i++) {
      msg = "";
      minEdge = findMinimumEdge();
      startNode = minEdge.start();
      endNode = minEdge.end();
      startTreeNode = treeNodes[gnodes.indexOf(startNode)];
      endTreeNode = treeNodes[gnodes.indexOf(endNode)];
	  jsav.umsg("Processing Edge ("+startNode.value()+","+endNode.value()+"):");
	  jsav.step();
      alreadyUnioned = union(startTreeNode, endTreeNode);
      if (alreadyUnioned === false) {
        //Add to MST
        jsav.umsg("
Add edge to the MST", {'preserve': true});
        minEdge.css({"stroke-width": "4", "stroke": "red"});
        weights.css(graph.edges().indexOf(minEdge), {'background-color':'red'});
        labels.css(graph.edges().indexOf(minEdge), {'background-color':'red'});
        markIt(startNode);
        markIt(endNode);
        mstedge = mst.addEdge(mstnodes[gnodes.indexOf(startNode)], mstnodes[gnodes.indexOf(endNode)], {"weight": minEdge.weight()});
        mstedge.css({"stroke-width": "2", "stroke": "red"});
      }
      else {
        jsav.umsg("
Dismiss edge", {'preserve': true});
        minEdge.css({"stroke-width": "4", "stroke": "orange"});
        weights.css(graph.edges().indexOf(minEdge), {'background-color':'orange'});
        labels.css(graph.edges().indexOf(minEdge), {'background-color':'orange'});
      }
      minEdge.addClass('visited');
      jsav.step();
      //End Algorithm when all Nodes are added to MST
      if (mst.edges().length === gnodes.length-1) {
        break;
      }
    }
  }
  function find(treeNode) {
    if (treeNode.parent() === tree.root()) {
      return treeNode;
    }
    else {
      var currentNode = treeNode;
      while (currentNode.parent() !== tree.root()) {
        currentNode = currentNode.parent();
      }
      return currentNode;
    }
  }
  function union(node1, node2) {
    //First we have to find which one has the least size
    var parent1 = find(node1);
    var parent2 = find(node2);
	var index1 = treeNodes.indexOf(parent1);
    var index2 = treeNodes.indexOf(parent2);
	jsav.umsg('
Parent Of Node ('+node1.value()+') is ('+parent1.value()+')', {'preserve': true});
	parent1.highlight();
	treeLabels.highlight(index1);
	jsav.step();
	jsav.umsg('
Parent Of Node ('+node2.value()+') is ('+parent2.value()+')', {'preserve': true});
	parent2.highlight();
	treeLabels.highlight(index2);
	jsav.step();
    if (parent1 === parent2) {
	  jsav.umsg('
Nodes are already Unioned', {'preserve': true});
      parent1.unhighlight();
      treeLabels.unhighlight(index1);
      parent2.unhighlight();
      treeLabels.unhighlight(index2);
	  jsav.step();
      return true;
    }
    else if (parent1.size === parent2.size) {
      if (parent1.value().charCodeAt(0) < parent2.value().charCodeAt(0)) {
        parent1.addChild(parent2);
        parent1.size++;
		parents.value(index2, index1);
      }
      else {
        parent2.addChild(parent1);
        parent2.size++;
		parents.value(index1, index2);
      }
    }
    else if (parent1.size > parent2.size) {
      parent1.addChild(parent2);
      parent1.size++;
	  parents.value(index2, index1);
    }
    else {
      parent2.addChild(parent1);
      parent2.size++;
	  parents.value(index1, index2);
    }
	jsav.umsg('
Union Nodes', {'preserve': true});
	parent1.unhighlight();
	treeLabels.unhighlight(index1);
	parent2.unhighlight();
	treeLabels.unhighlight(index2);
	tree.layout();
	jsav.step();
    return false;
  }
  function initTree() {
    var newNode;
    tree = jsav.ds.tree({left: 0, top: 90, nodegap: 20});
    var root = tree.newNode("X");
    tree.root(root);
    root.id("root");
    for (var i = 0; i < gnodes.length; i++) {
      newNode = tree.newNode(gnodes[i].value());
      newNode.size = 1;   //To maintain the size of each connected component
      root.addChild(newNode);
    }
    treeNodes = new Array(gnodes.length);
    for (i = 0; i < treeNodes.length; i++) {
      treeNodes[i] = tree.root().child(i);
    }
  }
  function about() {
    var mystring = "Kruskal's Algorithm Visualization\nWritten by Mohammed Fawzi and Cliff Shaffer\nCreated as part of the OpenDSA hypertextbook project.\nFor more information, see http://algoviz.org/OpenDSA\nWritten during Spring, 2013\nLast update: March, 2013\nJSAV library version " + JSAV.version();
    alert(mystring);
  }

  // Initialize the graph.
  function initGraph() {
    //Nodes of the original graph
    var a = graph.addNode("A", {"left": 50, "top": -15});
    var b = graph.addNode("B", {"left": 350, "top": -15});
    var c = graph.addNode("C", {"left": 190, "top": 10});
    var d = graph.addNode("D", {"left": 190, "top": 125});
    var e = graph.addNode("E", {"left": 50, "top": 225});
    var f = graph.addNode("F", {"left": 350, "top": 175});
    //Nodes of the MST
    mst.addNode("A", {"left": 25, "top": -15});
    mst.addNode("B", {"left": 325, "top": -15});
    mst.addNode("C", {"left": 145, "top": 10});
    mst.addNode("D", {"left": 145, "top": 125});
    mst.addNode("E", {"left": 0, "top": 225});
    mst.addNode("F", {"left": 325, "top": 175});
    //Original graph edges
    graph.addEdge(a, c, {"weight": 7});
    graph.addEdge(a, e, {"weight": 9});
    graph.addEdge(c, b, {"weight": 5});
    graph.addEdge(c, d, {"weight": 1});
    graph.addEdge(c, f, {"weight": 2});
    graph.addEdge(f, b, {"weight": 6});
    graph.addEdge(d, f, {"weight": 2});
    graph.addEdge(e, f, {"weight": 1});
    gnodes = graph.nodes();
    mstnodes = mst.nodes();
    for (var i = 0; i < mstnodes.length; i++) {
      gnodes[i].index = i;
    }
  }
  // Connect action callbacks to the HTML entities
  $('#about').click(about);
  $('#runit').click(runit);
  //$('#help').click(help);
  $('#reset').click(ODSA.AV.reset);
}(jQuery));
<|endoftext|>


<commit_before>var sass = require('node-sass');

module.exports = {
    generateScopedName: '[name]_[local]__[hash:base64:5]'
};
<commit_msg>Removed dependency on node-sass<commit_after>module.exports = {
    generateScopedName: '[name]_[local]__[hash:base64:5]'
};
<|endoftext|>


<commit_before>/**
 * @module Animatronics
 */

import React from 'react'
import PropTypes from 'prop-types'

import withAnimatronics from './withAnimatronics'

class Animatronics extends React.Component {
  render() {
    const { createAnimationSequences, children } = this.props;
    const enhance = withAnimatronics(createAnimationSequences);
    class BaseComponent extends React.Component {
      render() {
        const { ...props } = this.props;
        return React.cloneElement(children, props);
      }
    }
    const AnimatronicsComponent = enhance(BaseComponent);
    return <AnimatronicsComponent/>;
  }
}

Animatronics.propTypes = {
  createAnimationSequences: PropTypes.func.isRequired,
};

export default Animatronics;
<commit_msg>:art: [Animatronics] Added flow types<commit_after>// @flow
/**
 * @module Animatronics
 */

import React from 'react'
import PropTypes from 'prop-types'

import type { Element } from 'react'

import withAnimatronics from './withAnimatronics'

type Props = {
  createAnimationSequences: Function,
  children: Element<any>,
};

class Animatronics extends React.Component<Props> {
  render() {
    const { createAnimationSequences, children } = this.props;
    const enhance = withAnimatronics(createAnimationSequences);
    class BaseComponent extends React.Component<{}> {
      render() {
        const { ...props } = this.props;
        return React.cloneElement(children, props);
      }
    }
    const AnimatronicsComponent = enhance(BaseComponent);
    return <AnimatronicsComponent/>;
  }
}

export default Animatronics;
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2015 peeracle contributors
 *
 * 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.
 */

'use strict';

/**
 * @class
 * @memberof Peeracle
 * @param {!Uint8Array} buffer
 * @constructor
 */

function BinaryStream(buffer) {
  /**
   * @member {Uint8Array}
   */
  this.bytes = buffer;

  /**
   * @member {number}
   * @private
   */
  this.length_ = buffer.length;

  /**
   * @member {number}
   * @private
   */
  this.offset_ = 0;
}

BinaryStream.ERR_INVALID_ARGUMENT = 'Invalid argument';
BinaryStream.ERR_INDEX_OUT_OF_BOUNDS = 'Index out of bounds';
BinaryStream.ERR_VALUE_OUT_OF_BOUNDS = 'Value out of bounds';

/**
 * @returns {number}
 */
BinaryStream.prototype.readByte = function readByte() {
  if (this.offset_ + 1 >= this.length_) {
    throw new RangeError(BinaryStream.ERR_INDEX_OUT_OF_BOUNDS);
  }
  return this.bytes[this.offset_++];
};

/**
 * @param value
 */
BinaryStream.prototype.writeByte = function writeByte(value) {
  if (typeof value !== 'number') {
    throw new Error(BinaryStream.ERR_INVALID_ARGUMENT);
  }
  if (value < 0 || value > 255) {
    throw new Error(BinaryStream.ERR_VALUE_OUT_OF_BOUNDS);
  }
  this.bytes.set(new Uint8Array([value]), this.offset_++);
};

/**
 * @param length
 * @returns {Uint8Array}
 */
BinaryStream.prototype.readBytes = function readBytes(length) {
  var bytes;

  if (typeof length !== 'number' || length < 1) {
    throw new Error(BinaryStream.ERR_INVALID_ARGUMENT);
  }

  if (length > this.length_ ||
    this.offset_ + length > this.length_) {
    throw new RangeError(BinaryStream.ERR_INDEX_OUT_OF_BOUNDS);
  }
  bytes = this.bytes.subarray(this.offset_, this.offset_ + length);
  this.offset_ += length;
  return bytes;
};

/**
 * @param {Uint8Array} bytes
 */
BinaryStream.prototype.writeBytes = function writeBytes(bytes) {
  var length = bytes.length;
  try {
    this.bytes.set(bytes, this.offset_);
    this.offset_ += length;
  } catch (err) {
    throw err;
  if (!(bytes instanceof Uint8Array)) {
    throw new TypeError(BinaryStream.ERR_INVALID_ARGUMENT);
  }

};

/**
 * @returns {number}
 */
BinaryStream.prototype.readFloat8 = function readFloat8() {
  var number = this.readBytes(8);
  var sign = (number[0] >> 7) & 0x1;
  var exponent = (((number[0] & 0x7f) << 4) |
    ((number[1] >> 4) & 0xf)) - 1023;

  var i;
  var significand = 0;
  var shift = Math.pow(2, 6 * 8);
  significand += (number[1] & 0xf) * shift;
  for (i = 2; i < 8; ++i) {
    shift = Math.pow(2, (8 - i - 1) * 8);
    significand += (number[i] & 0xff) * shift;
  }

  if (exponent > -1023) {
    if (exponent === 1024) {
      if (significand === 0) {
        if (sign === 0) {
          return Number.POSITIVE_INFINITY;
        }
        return Number.NEGATIVE_INFINITY;
      }
      return NaN;
    }
    significand += 0x10000000000000;
  } else {
    if (significand === 0) {
      return 0;
    }
    exponent = -1022;
  }

  return Math.pow(-1, sign) * (significand * Math.pow(2, -52)) *
    Math.pow(2, exponent);
};

/**
 * @param {number} value
 */
BinaryStream.prototype.writeFloat8 = function writeFloat8(value) {
  var hiWord = 0;
  var loWord = 0;
  var exponent;
  var significand;
  var val = value;

  switch (val) {
    case Number.POSITIVE_INFINITY:
      hiWord = 0x7FF00000;
      break;
    case Number.NEGATIVE_INFINITY:
      hiWord = 0xFFF00000;
      break;
    case +0.0:
      hiWord = 0x40000000;
      break;
    case -0.0:
      hiWord = 0xC0000000;
      break;
    default:
      if (Number.isNaN(value)) {
        hiWord = 0x7FF80000;
        break;
      }

      if (val <= -0.0) {
        hiWord = 0x80000000;
        val = -val;
      }

      exponent = Math.floor(Math.log(val) / Math.log(2));
      significand = Math.floor((val / Math.pow(2, exponent)) * Math.pow(2, 52));

      loWord = significand & 0xFFFFFFFF;
      significand /= Math.pow(2, 32);

      exponent += 1023;
      if (exponent >= 0x7FF) {
        exponent = 0x7FF;
        significand = 0;
      } else if (exponent < 0) {
        exponent = 0;
      }

      hiWord = hiWord | (exponent << 20);
      hiWord = hiWord | (significand & ~(-1 << 20));
      break;
  if (typeof value !== 'number') {
    throw new TypeError(BinaryStream.ERR_INVALID_ARGUMENT);
  }

  this.writeUInt32(hiWord);
  this.writeUInt32(loWord);
};

/**
 * @param {boolean?} unsigned
 * @returns {number}
 */
BinaryStream.prototype.readInt32 = function readInt32(unsigned) {
  var number = this.readBytes(4);
  var value = (number[0] << 24) +
    (number[1] << 16) +
    (number[2] << 8);

  if (unsigned) {
    return value + number[3] >>> 0;
  }

  return value + number[3];
};

/**
 * @param {number} value
 * @param {boolean?} unsigned
 */
BinaryStream.prototype.writeInt32 = function writeInt32(value, unsigned) {
  var l = 0;
  var bytes = [];
  var val = value;

  if (typeof val !== 'number') {
    throw new TypeError(BinaryStream.ERR_INVALID_ARGUMENT);
  }

  if (unsigned) {
    val = val >>> 0;
  }

  while (l < 4) {
    bytes[l] = (val & 0xFF);
    val = val >> 8;
    ++l;
  }

  this.writeBytes(new Uint8Array(bytes.reverse()));
};

/**
 * @returns {number}
 */
BinaryStream.prototype.readUInt32 = function readUInt32() {
  return this.readInt32(true);
};

/**
 * @param {number} value
 */
BinaryStream.prototype.writeUInt32 = function writeUInt32(value) {
  if (typeof value !== 'number') {
    throw new TypeError(BinaryStream.ERR_INVALID_ARGUMENT);
  }
  this.writeInt32(value, true);
};

/**
 * @param length
 * @returns {string}
 */
BinaryStream.prototype.readString = function readString(length) {
  var str = '';
  var bytes;
  var i;

  if (length) {
    bytes = this.readBytes(length);
    for (i = 0; i < length; ++i) {
      str += String.fromCharCode(bytes[i]);
    }
    return str;
  }

  i = this.readByte();
  while (i) {
    str += String.fromCharCode(i);
    i = this.readByte();
  }
  return str;
};

/**
 * @param {string} value
 */
BinaryStream.prototype.writeString = function writeString(value) {
  var i;
  var length;
  var bytes;

  if (typeof value !== 'string') {
    this.writeByte(0);
    return;
  }

  length = value.length;
  bytes = new Uint8Array(length + 1);

  for (i = 0; i < length; ++i) {
    bytes[i] = value.charCodeAt(i);
  }
  bytes[length] = 0;

  this.writeBytes(bytes);
};

/**
 *
 * @param value
 */
BinaryStream.prototype.seek = function seek(value) {
  if (typeof value !== 'number') {
    throw new TypeError(BinaryStream.ERR_INVALID_ARGUMENT);
  }
  if (value < 0 || value >= this.length_) {
    throw new RangeError(BinaryStream.ERR_INDEX_OUT_OF_BOUNDS);
  }
  this.offset_ = value;
};

module.exports = BinaryStream;
<commit_msg>Check type of length argument<commit_after>/*
 * Copyright (c) 2015 peeracle contributors
 *
 * 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.
 */

'use strict';

/**
 * @class
 * @memberof Peeracle
 * @param {!Uint8Array} buffer
 * @constructor
 */

function BinaryStream(buffer) {
  /**
   * @member {Uint8Array}
   */
  this.bytes = buffer;

  /**
   * @member {number}
   * @private
   */
  this.length_ = buffer.length;

  /**
   * @member {number}
   * @private
   */
  this.offset_ = 0;
}

BinaryStream.ERR_INVALID_ARGUMENT = 'Invalid argument';
BinaryStream.ERR_INDEX_OUT_OF_BOUNDS = 'Index out of bounds';
BinaryStream.ERR_VALUE_OUT_OF_BOUNDS = 'Value out of bounds';

/**
 * @returns {number}
 */
BinaryStream.prototype.readByte = function readByte() {
  if (this.offset_ + 1 >= this.length_) {
    throw new RangeError(BinaryStream.ERR_INDEX_OUT_OF_BOUNDS);
  }
  return this.bytes[this.offset_++];
};

/**
 * @param value
 */
BinaryStream.prototype.writeByte = function writeByte(value) {
  if (typeof value !== 'number') {
    throw new Error(BinaryStream.ERR_INVALID_ARGUMENT);
  }
  if (value < 0 || value > 255) {
    throw new Error(BinaryStream.ERR_VALUE_OUT_OF_BOUNDS);
  }
  this.bytes.set(new Uint8Array([value]), this.offset_++);
};

/**
 * @param length
 * @returns {Uint8Array}
 */
BinaryStream.prototype.readBytes = function readBytes(length) {
  var bytes;

  if (typeof length !== 'number' || length < 1) {
    throw new Error(BinaryStream.ERR_INVALID_ARGUMENT);
  }

  if (length > this.length_ ||
    this.offset_ + length > this.length_) {
    throw new RangeError(BinaryStream.ERR_INDEX_OUT_OF_BOUNDS);
  }
  bytes = this.bytes.subarray(this.offset_, this.offset_ + length);
  this.offset_ += length;
  return bytes;
};

/**
 * @param {Uint8Array} bytes
 */
BinaryStream.prototype.writeBytes = function writeBytes(bytes) {
  var length = bytes.length;
  try {
    this.bytes.set(bytes, this.offset_);
    this.offset_ += length;
  } catch (err) {
    throw err;
  if (!(bytes instanceof Uint8Array)) {
    throw new TypeError(BinaryStream.ERR_INVALID_ARGUMENT);
  }

};

/**
 * @returns {number}
 */
BinaryStream.prototype.readFloat8 = function readFloat8() {
  var number = this.readBytes(8);
  var sign = (number[0] >> 7) & 0x1;
  var exponent = (((number[0] & 0x7f) << 4) |
    ((number[1] >> 4) & 0xf)) - 1023;

  var i;
  var significand = 0;
  var shift = Math.pow(2, 6 * 8);
  significand += (number[1] & 0xf) * shift;
  for (i = 2; i < 8; ++i) {
    shift = Math.pow(2, (8 - i - 1) * 8);
    significand += (number[i] & 0xff) * shift;
  }

  if (exponent > -1023) {
    if (exponent === 1024) {
      if (significand === 0) {
        if (sign === 0) {
          return Number.POSITIVE_INFINITY;
        }
        return Number.NEGATIVE_INFINITY;
      }
      return NaN;
    }
    significand += 0x10000000000000;
  } else {
    if (significand === 0) {
      return 0;
    }
    exponent = -1022;
  }

  return Math.pow(-1, sign) * (significand * Math.pow(2, -52)) *
    Math.pow(2, exponent);
};

/**
 * @param {number} value
 */
BinaryStream.prototype.writeFloat8 = function writeFloat8(value) {
  var hiWord = 0;
  var loWord = 0;
  var exponent;
  var significand;
  var val = value;

  switch (val) {
    case Number.POSITIVE_INFINITY:
      hiWord = 0x7FF00000;
      break;
    case Number.NEGATIVE_INFINITY:
      hiWord = 0xFFF00000;
      break;
    case +0.0:
      hiWord = 0x40000000;
      break;
    case -0.0:
      hiWord = 0xC0000000;
      break;
    default:
      if (Number.isNaN(value)) {
        hiWord = 0x7FF80000;
        break;
      }

      if (val <= -0.0) {
        hiWord = 0x80000000;
        val = -val;
      }

      exponent = Math.floor(Math.log(val) / Math.log(2));
      significand = Math.floor((val / Math.pow(2, exponent)) * Math.pow(2, 52));

      loWord = significand & 0xFFFFFFFF;
      significand /= Math.pow(2, 32);

      exponent += 1023;
      if (exponent >= 0x7FF) {
        exponent = 0x7FF;
        significand = 0;
      } else if (exponent < 0) {
        exponent = 0;
      }

      hiWord = hiWord | (exponent << 20);
      hiWord = hiWord | (significand & ~(-1 << 20));
      break;
  if (typeof value !== 'number') {
    throw new TypeError(BinaryStream.ERR_INVALID_ARGUMENT);
  }

  this.writeUInt32(hiWord);
  this.writeUInt32(loWord);
};

/**
 * @param {boolean?} unsigned
 * @returns {number}
 */
BinaryStream.prototype.readInt32 = function readInt32(unsigned) {
  var number = this.readBytes(4);
  var value = (number[0] << 24) +
    (number[1] << 16) +
    (number[2] << 8);

  if (unsigned) {
    return value + number[3] >>> 0;
  }

  return value + number[3];
};

/**
 * @param {number} value
 * @param {boolean?} unsigned
 */
BinaryStream.prototype.writeInt32 = function writeInt32(value, unsigned) {
  var l = 0;
  var bytes = [];
  var val = value;

  if (typeof val !== 'number') {
    throw new TypeError(BinaryStream.ERR_INVALID_ARGUMENT);
  }

  if (unsigned) {
    val = val >>> 0;
  }

  while (l < 4) {
    bytes[l] = (val & 0xFF);
    val = val >> 8;
    ++l;
  }

  this.writeBytes(new Uint8Array(bytes.reverse()));
};

/**
 * @returns {number}
 */
BinaryStream.prototype.readUInt32 = function readUInt32() {
  return this.readInt32(true);
};

/**
 * @param {number} value
 */
BinaryStream.prototype.writeUInt32 = function writeUInt32(value) {
  if (typeof value !== 'number') {
    throw new TypeError(BinaryStream.ERR_INVALID_ARGUMENT);
  }
  this.writeInt32(value, true);
};

/**
 * @param length
 * @returns {string}
 */
BinaryStream.prototype.readString = function readString(length) {
  var str = '';
  var bytes;
  var i;

  if (typeof length === 'number') {
    bytes = this.readBytes(length);
    for (i = 0; i < length; ++i) {
      str += String.fromCharCode(bytes[i]);
    }
    return str;
  }

  i = this.readByte();
  while (i) {
    str += String.fromCharCode(i);
    i = this.readByte();
  }
  return str;
};

/**
 * @param {string} value
 */
BinaryStream.prototype.writeString = function writeString(value) {
  var i;
  var length;
  var bytes;

  if (typeof value !== 'string') {
    this.writeByte(0);
    return;
  }

  length = value.length;
  bytes = new Uint8Array(length + 1);

  for (i = 0; i < length; ++i) {
    bytes[i] = value.charCodeAt(i);
  }
  bytes[length] = 0;

  this.writeBytes(bytes);
};

/**
 *
 * @param value
 */
BinaryStream.prototype.seek = function seek(value) {
  if (typeof value !== 'number') {
    throw new TypeError(BinaryStream.ERR_INVALID_ARGUMENT);
  }
  if (value < 0 || value >= this.length_) {
    throw new RangeError(BinaryStream.ERR_INDEX_OUT_OF_BOUNDS);
  }
  this.offset_ = value;
};

module.exports = BinaryStream;
<|endoftext|>


<commit_before>// Require libraries.
var Leaflet = require('leaflet');
var APDateTime = require('../../../common/js/APDateTime.js');

// Convenience variables.
var master = $('.igraphic-graphic.map');
var $map = $('.content .map', master);

// Create the Leaflet map.
var map = L.map($map.get(0), {
	attributionControl: false,
	scrollWheelZoom: false,
	maxBounds: [
		[24, -93],
		[51, -60]
	]
}).setView([42.25841962, -71.81532837], 6);

// Add the MapBox baselayer to our map.
L.tileLayer('http://{s}.tiles.mapbox.com/v3/gabriel-florit.36cf07a4/{z}/{x}/{y}.png', {
	minZoom: 6,
	maxZoom: 10
}).addTo(map);

// Define the snowfall image bounds.
var customBounds = [[30.8, -85.7], [47.58, -67]]; // we came up with these after much tweaking
// var sourceBounds = [[31, -85.5, ], [47.5, -67]]; // this is what the National Weather Service uses

// Add the snowfall image to the map.
var imageLayer = L.imageOverlay('http://amzncache.boston.com/partners/maps/snowfall.png', customBounds).addTo(map);

// Create a Leaflet control for the legend.
var MyControl = L.Control.extend({

	options: {
		position: 'topright'
	},

	onAdd: function (map) {

		var container = L.DomUtil.create('div', 'legend leaflet-bar');

		// Insert the legend contents.
		container.innerHTML = $('.legend', master).html();

		return container;
	}
});

// Only add the control if we're not on touch screens.
if (!Modernizr.touch) {
	map.addControl(new MyControl());
}

function intersectRect(r1, r2) {
	return !(r2.left > r1.right ||
	r2.right < r1.left ||
	r2.top > r1.bottom ||
	r2.bottom < r1.top);
}

function populateUpdatedAt(date) {

	// Populate the 'updated' element.
	$('.updated-timestamp').html('Updated ' + [APDateTime.time(date), APDateTime.date(date)].join(', '));
}

function getIconDimensions(zoom) {

	return {
		6: {
			width: 36,
			height: 21
		},
		7: {
			width: 36,
			height: 21
		},
		8: {
			width: 48,
			height: 27
		},
		9: {
			width: 48,
			height: 27
		},
		10: {
			width: 64,
			height: 36
		}
	}[zoom];
}

var markersLayer;
var allPoints;

function addMarkersToMap(zoom) {

	var iconDimensions = getIconDimensions(zoom);

	var ICON_WIDTH = iconDimensions.width;
	var ICON_HEIGHT = iconDimensions.height;

	var markers = [];

	// for each point,
	// find the absolute pixel coordinates for the given zoom level
	// assuming we're center aligning the point,
	// find the point's bounding box in pixel coordinates
	_.chain(allPoints)
	.sortBy(function(v, i) {
		return -(+v.latitude);
	})
	.sortBy(function(v, i) {
		return (+v.longitude);
	})
	.forEach(function(point, index) {

		var pointCoords = map.project([point.latitude, point.longitude]);

		var pointBBox = {
			left: pointCoords.x - ICON_WIDTH/2,
			right: pointCoords.x + ICON_WIDTH/2,
			bottom: pointCoords.y + ICON_HEIGHT/2,
			top: pointCoords.y - ICON_HEIGHT/2
		};

		// make sure this bbox doesn't overlap with any existing markers
		var overlaps = _.some(markers, function(marker) {

			var markerCoords = map.project(marker._latlng);

			var markerBBox = {
				left: markerCoords.x - ICON_WIDTH/2,
				right: markerCoords.x + ICON_WIDTH/2,
				bottom: markerCoords.y + ICON_HEIGHT/2,
				top: markerCoords.y - ICON_HEIGHT/2
			};

			return intersectRect(pointBBox, markerBBox);
		});

		// if it doesn't overlap, add to markers layer
		if (!overlaps) {

			var icon = L.divIcon({
				html: '●' + point.snowfall + '”',
				className: 'snowfall'
			});

			var marker = L.marker([point.latitude, point.longitude], {
				icon: icon,
				clickable: false
			});
			markers.push(marker);

		}
	});

	if (markersLayer) {
		map.removeLayer(markersLayer);
	}

	markersLayer = L.layerGroup(markers);

	markersLayer.addTo(map);
}

map.on('zoomend', function(e) {
	addMarkersToMap(map.getZoom());
});

window.snowfall_scraper = function(json) {

	var ts = json.timestamp;

	var date = new Date(`${ts.month} ${ts.day}, ${ts.year}, ${ts.hour}:${ts.minutes} ${ts.mode}`);
	populateUpdatedAt(date);

	allPoints = json.snowfall_points;
	addMarkersToMap(map.getZoom());
};

$.ajax({
	url: 'http://cache.boston.com/partners/snowfallscraper/snowfall_scraper.json',
	dataType: 'jsonp',
	jsonpCallback: 'snowfall_scraper'
});<commit_msg>tweak label sizes<commit_after>// Require libraries.
var Leaflet = require('leaflet');
var APDateTime = require('../../../common/js/APDateTime.js');

// Convenience variables.
var master = $('.igraphic-graphic.map');
var $map = $('.content .map', master);

// Create the Leaflet map.
var map = L.map($map.get(0), {
	attributionControl: false,
	scrollWheelZoom: false,
	maxBounds: [
		[24, -93],
		[51, -60]
	]
}).setView([42.25841962, -71.81532837], 6);

// Add the MapBox baselayer to our map.
L.tileLayer('http://{s}.tiles.mapbox.com/v3/gabriel-florit.36cf07a4/{z}/{x}/{y}.png', {
	minZoom: 6,
	maxZoom: 10
}).addTo(map);

// Define the snowfall image bounds.
var customBounds = [[30.8, -85.7], [47.58, -67]]; // we came up with these after much tweaking
// var sourceBounds = [[31, -85.5, ], [47.5, -67]]; // this is what the National Weather Service uses

// Add the snowfall image to the map.
var imageLayer = L.imageOverlay('http://amzncache.boston.com/partners/maps/snowfall.png', customBounds).addTo(map);

// Create a Leaflet control for the legend.
var MyControl = L.Control.extend({

	options: {
		position: 'topright'
	},

	onAdd: function (map) {

		var container = L.DomUtil.create('div', 'legend leaflet-bar');

		// Insert the legend contents.
		container.innerHTML = $('.legend', master).html();

		return container;
	}
});

// Only add the control if we're not on touch screens.
if (!Modernizr.touch) {
	map.addControl(new MyControl());
}

function intersectRect(r1, r2) {
	return !(r2.left > r1.right ||
	r2.right < r1.left ||
	r2.top > r1.bottom ||
	r2.bottom < r1.top);
}

function populateUpdatedAt(date) {

	// Populate the 'updated' element.
	$('.updated-timestamp').html('Updated ' + [APDateTime.time(date), APDateTime.date(date)].join(', '));
}

function getIconDimensions(zoom) {

	return {
		6: {
			width: 42,
			height: 21
		},
		7: {
			width: 42,
			height: 21
		},
		8: {
			width: 55,
			height: 27
		},
		9: {
			width: 55,
			height: 27
		},
		10: {
			width: 73,
			height: 36
		}
	}[zoom];
}

var markersLayer;
var allPoints;

function addMarkersToMap(zoom) {

	var iconDimensions = getIconDimensions(zoom);

	var ICON_WIDTH = iconDimensions.width;
	var ICON_HEIGHT = iconDimensions.height;

	var markers = [];

	// for each point,
	// find the absolute pixel coordinates for the given zoom level
	// assuming we're center aligning the point,
	// find the point's bounding box in pixel coordinates
	_.chain(allPoints)
	.sortBy(function(v, i) {
		return -(+v.latitude);
	})
	.sortBy(function(v, i) {
		return (+v.longitude);
	})
	.forEach(function(point, index) {

		var pointCoords = map.project([point.latitude, point.longitude]);

		var pointBBox = {
			left: pointCoords.x - ICON_WIDTH/2,
			right: pointCoords.x + ICON_WIDTH/2,
			bottom: pointCoords.y + ICON_HEIGHT/2,
			top: pointCoords.y - ICON_HEIGHT/2
		};

		// make sure this bbox doesn't overlap with any existing markers
		var overlaps = _.some(markers, function(marker) {

			var markerCoords = map.project(marker._latlng);

			var markerBBox = {
				left: markerCoords.x - ICON_WIDTH/2,
				right: markerCoords.x + ICON_WIDTH/2,
				bottom: markerCoords.y + ICON_HEIGHT/2,
				top: markerCoords.y - ICON_HEIGHT/2
			};

			return intersectRect(pointBBox, markerBBox);
		});

		// if it doesn't overlap, add to markers layer
		if (!overlaps) {

			var icon = L.divIcon({
				html: '●' + point.snowfall + '”',
				className: 'snowfall'
			});

			var marker = L.marker([point.latitude, point.longitude], {
				icon: icon,
				clickable: false
			});
			markers.push(marker);

		}
	});

	if (markersLayer) {
		map.removeLayer(markersLayer);
	}

	markersLayer = L.layerGroup(markers);

	markersLayer.addTo(map);
}

map.on('zoomend', function(e) {
	addMarkersToMap(map.getZoom());
});

window.snowfall_scraper = function(json) {

	var ts = json.timestamp;

	var date = new Date(`${ts.month} ${ts.day}, ${ts.year}, ${ts.hour}:${ts.minutes} ${ts.mode}`);
	populateUpdatedAt(date);

	allPoints = json.snowfall_points;
	addMarkersToMap(map.getZoom());
};

$.ajax({
	url: 'http://cache.boston.com/partners/snowfallscraper/snowfall_scraper.json',
	dataType: 'jsonp',
	jsonpCallback: 'snowfall_scraper'
});<|endoftext|>


<commit_before>// Require libraries.
var Leaflet = require('leaflet');
var APDateTime = require('../../../common/js/APDateTime.js');

// Convenience variables.
var master = $('.igraphic-graphic.map');
var $map = $('.content .map', master);

// Create the Leaflet map.
var map = L.map($map.get(0), {attributionControl: false}).setView([42.25841962, -71.81532837], 6);

// Add the MapBox baselayer to our map.
L.tileLayer('http://{s}.tiles.mapbox.com/v3/gabriel-florit.baselayer_land/{z}/{x}/{y}.png', {
	minZoom: 5,
	maxZoom: 10
}).addTo(map);

// Define the snowfall image bounds.
var southWest = new L.LatLng(30.8, -85.7),
	northEast = new L.LatLng(47.58, -67),
	bounds = new L.LatLngBounds(southWest, northEast);

// Add the snowfall image to the map.
var imageLayer = L.imageOverlay('http://amzncache.boston.com/partners/maps/snowfall.png', bounds).addTo(map);

// Create a Leaflet control for the legend.
var MyControl = L.Control.extend({

	options: {
		position: 'topright'
	},

	onAdd: function (map) {

		var container = L.DomUtil.create('div', 'legend leaflet-bar');

		// Insert the legend contents.
		container.innerHTML = $('.legend', master).html();

		return container;
	}
});

// Only add the control if we're not on touch screens.
if (!Modernizr.touch) {
	map.addControl(new MyControl());
}

// Get the time right now.
var date = new Date();

// Construct a new date with no minutes or seconds.
var hourDate = new Date(date.getFullYear(), date.getMonth(), date.getDate(), date.getHours());

// Populate the 'updated' element.
$('.updated-timestamp').html('Updated ' + [APDateTime.time(hourDate), APDateTime.date(hourDate)].join(', '));<commit_msg>no zoom on scrollwheel<commit_after>// Require libraries.
var Leaflet = require('leaflet');
var APDateTime = require('../../../common/js/APDateTime.js');

// Convenience variables.
var master = $('.igraphic-graphic.map');
var $map = $('.content .map', master);

// Create the Leaflet map.
var map = L.map($map.get(0), {
	attributionControl: false,
	scrollWheelZoom: false
}).setView([42.25841962, -71.81532837], 6);

// Add the MapBox baselayer to our map.
L.tileLayer('http://{s}.tiles.mapbox.com/v3/gabriel-florit.baselayer_land/{z}/{x}/{y}.png', {
	minZoom: 5,
	maxZoom: 10
}).addTo(map);

// Define the snowfall image bounds.
var southWest = new L.LatLng(30.8, -85.7),
	northEast = new L.LatLng(47.58, -67),
	bounds = new L.LatLngBounds(southWest, northEast);

// Add the snowfall image to the map.
var imageLayer = L.imageOverlay('http://amzncache.boston.com/partners/maps/snowfall.png', bounds).addTo(map);

// Create a Leaflet control for the legend.
var MyControl = L.Control.extend({

	options: {
		position: 'topright'
	},

	onAdd: function (map) {

		var container = L.DomUtil.create('div', 'legend leaflet-bar');

		// Insert the legend contents.
		container.innerHTML = $('.legend', master).html();

		return container;
	}
});

// Only add the control if we're not on touch screens.
if (!Modernizr.touch) {
	map.addControl(new MyControl());
}

// Get the time right now.
var date = new Date();

// Construct a new date with no minutes or seconds.
var hourDate = new Date(date.getFullYear(), date.getMonth(), date.getDate(), date.getHours());

// Populate the 'updated' element.
$('.updated-timestamp').html('Updated ' + [APDateTime.time(hourDate), APDateTime.date(hourDate)].join(', '));<|endoftext|>


<commit_before>/**
	_moon.ExpandableIntegerPicker_, which extends
	moon.ExpandableListItem, is a drop-down
	picker menu that prompts the user to make a selection from a range of
	integer-based options.

	The value of the currently selected item is available in the picker's _value_
	property, while the content of the item is available in _content_.

	When the picker is minimized, the content of the currently selected item is
	displayed as subtext below the picker label.
*/
enyo.kind({
	name: "moon.ExpandableIntegerPicker",
	kind: "moon.ExpandableListItem",
	classes: "moon-expandable-integer-picker",
	events: {
		/**
			Fires when the currently selected item changes.
			_inEvent.value_ contains the value of the currently selected item.
			_inEvent.content_ contains the content of the currently selected item.
		*/
		onChange: ""
	},
	published: {
		//* Text to be displayed in the _currentValue_ control if no item is currently selected
		noneText: "",
		//* Initial value
		value: -1,
		//* Minimum value
		min: 0,
		//* Maximum value
		max: 9,
		//* Amount to increment/decrement by
		step: 1,
		//* Unit/label to be appended to the end of the number
		unit: "sec"
	},
	lockBottom: true,

	//* @protected

	handlers: {
		requestScrollIntoView: "requestScrollIntoView"
	},
	componentOverrides: {
		headerWrapper: {components: [
			{name: "header", kind: "moon.Item", spotlight: false, classes: "moon-expandable-list-item-header moon-expandable-picker-header"},
			{name: "currentValue", kind: "moon.Item", spotlight: false, classes: "moon-expandable-picker-current-value"}
		]},
		client: {components: [
			{name: "picker", kind: "moon.SimpleIntegerPicker", onSelect: "toggleActive", onActivate: "activated"}
		]}
	},
	bindings: [
		{from: ".min", to: ".$.picker.min"},
		{from: ".max", to: ".$.picker.max"},
		{from: ".unit", to: ".$.picker.unit"},
		{from: ".value", to: ".$.picker.value"},
		{from: ".showCurrentValue", to: ".$.currentValue.showing"},
		{from: ".currentValueText", to: ".$.currentValue.content"}
	],
	computed: {
		"showCurrentValue": ["open"],
		"currentValueText": ["value", "noneText"]
	},

	// Change handlers
	valueChanged: function() {
		this.fireChangeEvent();
	},
	openChanged: function() {
		this.inherited(arguments);

		if (!this.getOpen()) {
			this.updateValue();
		}

		this.preventResize = false;
	},
	activeChanged: function() {
		var active = this.getActive();
		if (active) {
			// enyo.Group's highlander logic actually prevents an item from being
			// de-activated once it's been activated; that's not exactly the logic
			// we want for ExpandablePicker, so we only notify the group when an
			// item is activated, not when it's de-activated.
			this.bubble("onActivate");
		}
		this.setOpen(active);
	},

	// Computed props
	showCurrentValue: function() {
		return !this.open;
	},
	currentValueText: function() {
		return (this.value === "") ? this.noneText : this.value + " " + this.unit;
	},

	//* Set _this.value_ to _this.$.clientInput.value_
	updateValue: function() {
		this.setValue(this.$.picker.getValue());
	},
	//* If open, close and spot header. If closed, open and unspot.
	toggleActive: function() {
		if (this.getOpen()) {
			this.setActive(false);
			enyo.Spotlight.spot(this.$.headerWrapper);
		} else {
			this.setActive(true);
			enyo.Spotlight.unspot();
		}
	},
	//* Kill any onActivate events coming from buttons in the SimplePicker
	activated: function(inSender, inEvent) {
		return true;
	},
	//* Fires an _onChange_ event.
	fireChangeEvent: function() {
		this.doChange({value: this.value, content: this.content});
	},
	//* Resize _this.$.picker_
	resized: function() {
		if (!this.preventResize) {
			this.$.picker.resized();
			this.preventResize = true;
		}
	}
});
<commit_msg>Fixed GF-33276 - openChanged() event of expandableIntegerPicker was squashing initial value.<commit_after>/**
	_moon.ExpandableIntegerPicker_, which extends
	moon.ExpandableListItem, is a drop-down
	picker menu that prompts the user to make a selection from a range of
	integer-based options.

	The value of the currently selected item is available in the picker's _value_
	property, while the content of the item is available in _content_.

	When the picker is minimized, the content of the currently selected item is
	displayed as subtext below the picker label.
*/
enyo.kind({
	name: "moon.ExpandableIntegerPicker",
	kind: "moon.ExpandableListItem",
	classes: "moon-expandable-integer-picker",
	events: {
		/**
			Fires when the currently selected item changes.
			_inEvent.value_ contains the value of the currently selected item.
			_inEvent.content_ contains the content of the currently selected item.
		*/
		onChange: ""
	},
	published: {
		//* Text to be displayed in the _currentValue_ control if no item is currently selected
		noneText: "",
		//* Initial value
		value: -1,
		//* Minimum value
		min: 0,
		//* Maximum value
		max: 9,
		//* Amount to increment/decrement by
		step: 1,
		//* Unit/label to be appended to the end of the number
		unit: "sec"
	},
	lockBottom: true,

	//* @protected

	handlers: {
		requestScrollIntoView: "requestScrollIntoView"
	},
	componentOverrides: {
		headerWrapper: {components: [
			{name: "header", kind: "moon.Item", spotlight: false, classes: "moon-expandable-list-item-header moon-expandable-picker-header"},
			{name: "currentValue", kind: "moon.Item", spotlight: false, classes: "moon-expandable-picker-current-value"}
		]},
		client: {components: [
			{name: "picker", kind: "moon.SimpleIntegerPicker", onSelect: "toggleActive", onActivate: "activated"}
		]}
	},
	bindings: [
		{from: ".min", to: ".$.picker.min"},
		{from: ".max", to: ".$.picker.max"},
		{from: ".unit", to: ".$.picker.unit"},
		{from: ".value", to: ".$.picker.value"},
		{from: ".showCurrentValue", to: ".$.currentValue.showing"},
		{from: ".currentValueText", to: ".$.currentValue.content"}
	],
	computed: {
		"showCurrentValue": ["open"],
		"currentValueText": ["value", "noneText"]
	},

	// Change handlers
	valueChanged: function() {
		this.fireChangeEvent();
	},
	openChanged: function() {
		this.inherited(arguments);

		if (!this.getOpen() && this.hasNode()) {
			this.updateValue();
		}

		this.preventResize = false;
	},
	activeChanged: function() {
		var active = this.getActive();
		if (active) {
			// enyo.Group's highlander logic actually prevents an item from being
			// de-activated once it's been activated; that's not exactly the logic
			// we want for ExpandablePicker, so we only notify the group when an
			// item is activated, not when it's de-activated.
			this.bubble("onActivate");
		}
		this.setOpen(active);
	},

	// Computed props
	showCurrentValue: function() {
		return !this.open;
	},
	currentValueText: function() {
		return (this.value === "") ? this.noneText : this.value + " " + this.unit;
	},

	//* Set _this.value_ to _this.$.clientInput.value_
	updateValue: function() {
		this.setValue(this.$.picker.getValue());
	},
	//* If open, close and spot header. If closed, open and unspot.
	toggleActive: function() {
		if (this.getOpen()) {
			this.setActive(false);
			enyo.Spotlight.spot(this.$.headerWrapper);
		} else {
			this.setActive(true);
			enyo.Spotlight.unspot();
		}
	},
	//* Kill any onActivate events coming from buttons in the SimplePicker
	activated: function(inSender, inEvent) {
		return true;
	},
	//* Fires an _onChange_ event.
	fireChangeEvent: function() {
		this.doChange({value: this.value, content: this.content});
	},
	//* Resize _this.$.picker_
	resized: function() {
		if (!this.preventResize) {
			this.$.picker.resized();
			this.preventResize = true;
		}
	}
});
<|endoftext|>


<commit_before>import path from 'path';

import urlQuery from '../utils/url-query';

const getPatternDemo = require('patternplate-server/library/get-pattern-demo');
const getPatternFile = require('patternplate-server/library/get-pattern-file');

function withErrorHandling(fn) {
	return async function(...args) {
		const [, id] = args;
		try {
			const result = await fn(...args);
			if (!result) {
				const error = new Error(`Could not find pattern with id ${id}`);
				error.fileName = id;
				error.file = id;
				error.status = 404;
				throw error;
			}
			return [null, result];
		} catch (error) {
			return [error];
		}
	};
}

function getPatternId(raw) {
	const parsed = path.parse(raw);
	const extension = getPatternExtension(raw);
	const base = path.basename(raw, path.extname(raw));

	if (base === 'index' && extension !== 'json') {
		return path.dirname(raw);
	}

	return `${path.dirname(raw)}/${path.basename(parsed.base, path.extname(parsed.base))}`;
}

function getPatternExtension(raw) {
	return path.extname(raw).slice(1) || 'html';
}

const getPatternDemoOrError = withErrorHandling(getPatternDemo);
const getPatternFileOrError = withErrorHandling(getPatternFile);

export default function patternRouteFactory(application) {
	return async function patternRoute() {
		const parsed = urlQuery.parse(this.params.id);
		const id = getPatternId(parsed.pathname);
		const extension = getPatternExtension(parsed.pathname);
		const type = this.accepts('text', 'html', 'json') || extension;
		const {environment = 'index'} = parsed.query;

		const filters = {
			outFormats: [extension],
			environments: [environment].filter(Boolean)
		};

		if (type === 'html' && extension === 'html') {
			const [error, demo] = await getPatternDemoOrError(application.parent.server, id, filters, environment);

			if (error) {
				console.log(error.message);
				if (error.stack) {
					console.trace(error.stack);
				}
				this.throw(error);
			}

			this.type = 'html';
			this.body = demo;
			return;
		}

		const [error, file] = await getPatternFileOrError(application.parent.server, id, filters, extension, environment);

		if (error) {
			this.throw(error);
		}

		this.type = extension;
		this.body = file;
	};
}
<commit_msg>style: do not fail when pattern-demo result is falsy<commit_after>import path from 'path';

import urlQuery from '../utils/url-query';

const getPatternDemo = require('patternplate-server/library/get-pattern-demo');
const getPatternFile = require('patternplate-server/library/get-pattern-file');

function withErrorHandling(fn) {
	return async function(...args) {
		try {
			const result = await fn(...args);
			return [null, result || ''];
		} catch (error) {
			return [error];
		}
	};
}

function getPatternId(raw) {
	const parsed = path.parse(raw);
	const extension = getPatternExtension(raw);
	const base = path.basename(raw, path.extname(raw));

	if (base === 'index' && extension !== 'json') {
		return path.dirname(raw);
	}

	return `${path.dirname(raw)}/${path.basename(parsed.base, path.extname(parsed.base))}`;
}

function getPatternExtension(raw) {
	return path.extname(raw).slice(1) || 'html';
}

const getPatternDemoOrError = withErrorHandling(getPatternDemo);
const getPatternFileOrError = withErrorHandling(getPatternFile);

export default function patternRouteFactory(application) {
	return async function patternRoute() {
		const parsed = urlQuery.parse(this.params.id);
		const id = getPatternId(parsed.pathname);
		const extension = getPatternExtension(parsed.pathname);
		const type = this.accepts('text', 'html', 'json') || extension;
		const {environment = 'index'} = parsed.query;

		const filters = {
			outFormats: [extension],
			environments: [environment].filter(Boolean)
		};

		if (type === 'html' && extension === 'html') {
			const [error, demo] = await getPatternDemoOrError(application.parent.server, id, filters, environment);

			if (error) {
				console.log(error.message);
				if (error.stack) {
					console.trace(error.stack);
				}
				this.throw(error);
			}

			this.type = 'html';
			this.body = demo;
			return;
		}

		const [error, file] = await getPatternFileOrError(application.parent.server, id, filters, extension, environment);

		if (error) {
			this.throw(error);
		}

		this.type = extension;
		this.body = file;
	};
}
<|endoftext|>