<commit_before>//get dom elements buttons and screen
var zero = document.getElementById("zero");
var one = document.getElementById("one");
var two = document.getElementById("two");
var three = document.getElementById("three");
var four = document.getElementById("four");
var five = document.getElementById("five");
var six = document.getElementById("six");
var seven = document.getElementById("seven");
var eight = document.getElementById("eight");
var nine = document.getElementById("nine");
var point = document.getElementById("point");
var equal = document.getElementById("equal");
var plus = document.getElementById("plus");
var minus = document.getElementById("minus");
var mult = document.getElementById("mult");
var divide = document.getElementById("divide");
var percent = document.getElementById("percent");
var reverse = document.getElementById("reverse");
var ac = document.getElementById("ac");
var screen = document.getElementById("screen");

//declare variables for calculations
var val = "0";
var floating = false;
var memVal = 0;
var operator;
var operatorPressed = false;
var firstDigitAfterOperator = false;
var isFirstZero = true;
var isResult = false;

function display() {

  if (val.length < 9) {
    screen.className = "";
    screen.innerHTML = val;
  } else {
    if (val.length < 12) {
      screen.className = "small";
      screen.innerHTML = val;
    } else {
      if (val.length < 17) {
        screen.className = "smaller";
        screen.innerHTML = val;
      } else {
        if (val.length < 25) {
          screen.className = "smallest";
          screen.innerHTML = val;
        } else {
          screen.innerHTML = "Number too large";
          val = "0";
        }
      }
    }
  }

}

function screenFlash() {
  screen.style.display = "none";
  setTimeout(function () {
    screen.style.display = "inherit";
  }, 50);
}

function clear() {
  val = "0";
  memVal = "0";
  firstDigitAfterOperator = false;
  operatorPressed = false;
  isFirstZero = true;
  isResult = false;
  floating = "false";
  screen.className = "";
  display();
}

function reverseNum() {
  if (val != "0") {
    if (val.startsWith("-")) {
      val = val.replace("-", "");
    } else {
      val = "-" + val;
    }
    display();
  }
}

function decimal() {
  if (!floating) {
    val += ".";
    floating = true;
  }
  display();
}

function add() {
  firstDigitAfterOperator = true;

  if (operatorPressed) {
    calculate();
    memVal = parseFloat(val);
  } else {
    memVal = parseFloat(val);
    //css border plus
  }
  screenFlash();
  operator = "plus";
  isResult = false;
}

function substract() {
  firstDigitAfterOperator = true;

  if (operatorPressed) {
    calculate();
    memVal = parseFloat(val);
  } else {
    memVal = parseFloat(val);
    //css border minus
  }
  screenFlash();
  operator = "minus";
  isResult = false;
}

function multiply() {
  memVal = parseFloat(val);
  operator = "times";
  isResult = false;
  clear();
}

function division() {
  memVal = parseFloat(val);
  operator = "division";
  isResult = false;
  clear();
}

function percentage() {
  val = parseFloat(val) / 100;
  val = val.toString();
  display();
}

function calculate() {
  var temp = 0;
  switch (operator) {
    case "plus":
      if (isResult) {
        val = memVal + parseFloat(val);
        val = val.toString();
      } else {
        temp = parseFloat(val);
        val = memVal + temp;
        memVal = temp;
        val = val.toString();
        isResult = true;
      }
      break;
    case "minus":
      if (isResult) {
        val = parseFloat(val) - memVal;
        val = val.toString();
      } else {
        temp = parseFloat(val);
        val = memVal - temp;
        memVal = temp;
        val = val.toString();
        isResult = true;
      }
      break;
    case "times":
      if (isResult) {
        val = memVal * parseFloat(val);
        val = val.toString();
      } else {
        temp = parseFloat(val);
        val = memVal * temp;
        memVal = temp;
        val = val.toString();
        isResult = true;
      }
      break;
    case "division":
      if (isResult) {
        val = parseFloat(val) / memVal;
        val = val.toString();
      } else {
        temp = parseFloat(val);
        val = memVal / temp;
        memVal = temp;
        val = val.toString();
        isResult = true;
      }
      break;
  }
  display();
}

function pressNum(num) {
  if (firstDigitAfterOperator) {
    val = num;
    firstDigitAfterOperator = false;
    operatorPressed = true;
  } else {
    if (isFirstZero) {
      val = num;
      isFirstZero = false;
    } else {
      val += num;
    }
  }

  display();
}

//declare event listeners
ac.addEventListener("click", clear);
reverse.addEventListener("click", reverseNum);
point.addEventListener("click", decimal);
plus.addEventListener("click", add);
minus.addEventListener("click", substract);
mult.addEventListener("click", multiply);
divide.addEventListener("click", division);
percent.addEventListener("click", percentage);
equal.addEventListener("click", calculate);
zero.addEventListener("click", function () {
  pressNum('0')
});
one.addEventListener("click", function () {
  pressNum('1')
});
two.addEventListener("click", function () {
  pressNum('2')
});
three.addEventListener("click", function () {
  pressNum('3')
});
four.addEventListener("click", function () {
  pressNum('4')
});
five.addEventListener("click", function () {
  pressNum('5')
});
six.addEventListener("click", function () {
  pressNum('6')
});
seven.addEventListener("click", function () {
  pressNum('7')
});
eight.addEventListener("click", function () {
  pressNum('8')
});
nine.addEventListener("click", function () {
  pressNum('9')
});

//keyboard event listener using keyCode because replacements are not yet supported
//by all browsers
document.addEventListener("keypress", function (e) {
  console.log(e.keyCode);
  switch (e.keyCode) {
    case 48:
      pressNum('0');
      break;

    case 49:
      pressNum('1');
      break;

    case 50:
      pressNum('2');
      break;

    case 51:
      pressNum('3');
      break;

    case 52:
      pressNum('4');
      break;

    case 53:
      pressNum('5');
      break;

    case 54:
      pressNum('6');
      break;

    case (55):
      pressNum('7');
      break;

    case 56:
      pressNum('8');
      break;

    case 57:
      pressNum('9');
      break;

    case 44:
    case 46:
      decimal();
      break;

    case 61:
    case 13:
      calculate();
      break;

    case 43:
      add();
      break;

    case 45:
      substract();
      break;

    case 42:
      multiply();
      break;

    case 47:
      division();
      break;

    case 37:
      percentage();
      break;

    case 177:
      reverseNum();
      break;

    case 67:
    case 99:
      clear();
      break;
  }
})<commit_msg>Change multiply() to allow operation chaining<commit_after>//get dom elements buttons and screen
var zero = document.getElementById("zero");
var one = document.getElementById("one");
var two = document.getElementById("two");
var three = document.getElementById("three");
var four = document.getElementById("four");
var five = document.getElementById("five");
var six = document.getElementById("six");
var seven = document.getElementById("seven");
var eight = document.getElementById("eight");
var nine = document.getElementById("nine");
var point = document.getElementById("point");
var equal = document.getElementById("equal");
var plus = document.getElementById("plus");
var minus = document.getElementById("minus");
var mult = document.getElementById("mult");
var divide = document.getElementById("divide");
var percent = document.getElementById("percent");
var reverse = document.getElementById("reverse");
var ac = document.getElementById("ac");
var screen = document.getElementById("screen");

//declare variables for calculations
var val = "0";
var floating = false;
var memVal = 0;
var operator;
var operatorPressed = false;
var firstDigitAfterOperator = false;
var isFirstZero = true;
var isResult = false;

function display() {

  if (val.length < 9) {
    screen.className = "";
    screen.innerHTML = val;
  } else {
    if (val.length < 12) {
      screen.className = "small";
      screen.innerHTML = val;
    } else {
      if (val.length < 17) {
        screen.className = "smaller";
        screen.innerHTML = val;
      } else {
        if (val.length < 25) {
          screen.className = "smallest";
          screen.innerHTML = val;
        } else {
          screen.innerHTML = "Number too large";
          val = "0";
        }
      }
    }
  }

}

function screenFlash() {
  screen.style.display = "none";
  setTimeout(function () {
    screen.style.display = "inherit";
  }, 50);
}

function clear() {
  val = "0";
  memVal = "0";
  firstDigitAfterOperator = false;
  operatorPressed = false;
  isFirstZero = true;
  isResult = false;
  floating = "false";
  screen.className = "";
  display();
}

function reverseNum() {
  if (val != "0") {
    if (val.startsWith("-")) {
      val = val.replace("-", "");
    } else {
      val = "-" + val;
    }
    display();
  }
}

function decimal() {
  if (!floating) {
    val += ".";
    floating = true;
  }
  display();
}

function add() {
  firstDigitAfterOperator = true;

  if (operatorPressed) {
    calculate();
    memVal = parseFloat(val);
  } else {
    memVal = parseFloat(val);
    //css border plus
  }
  screenFlash();
  operator = "plus";
  isResult = false;
}

function substract() {
  firstDigitAfterOperator = true;

  if (operatorPressed) {
    calculate();
    memVal = parseFloat(val);
  } else {
    memVal = parseFloat(val);
    //css border minus
  }
  screenFlash();
  operator = "minus";
  isResult = false;
}

function multiply() {
  firstDigitAfterOperator = true;

  if (operatorPressed) {
    calculate();
    memVal = parseFloat(val);
  } else {
    memVal = parseFloat(val);
    //css border times
  }
  screenFlash();
  operator = "times";
  isResult = false;
}

function division() {
  memVal = parseFloat(val);
  operator = "division";
  isResult = false;
  clear();
}

function percentage() {
  val = parseFloat(val) / 100;
  val = val.toString();
  display();
}

function calculate() {
  var temp = 0;
  switch (operator) {
    case "plus":
      if (isResult) {
        val = memVal + parseFloat(val);
        val = val.toString();
      } else {
        temp = parseFloat(val);
        val = memVal + temp;
        memVal = temp;
        val = val.toString();
        isResult = true;
      }
      break;
    case "minus":
      if (isResult) {
        val = parseFloat(val) - memVal;
        val = val.toString();
      } else {
        temp = parseFloat(val);
        val = memVal - temp;
        memVal = temp;
        val = val.toString();
        isResult = true;
      }
      break;
    case "times":
      if (isResult) {
        val = memVal * parseFloat(val);
        val = val.toString();
      } else {
        temp = parseFloat(val);
        val = memVal * temp;
        memVal = temp;
        val = val.toString();
        isResult = true;
      }
      break;
    case "division":
      if (isResult) {
        val = parseFloat(val) / memVal;
        val = val.toString();
      } else {
        temp = parseFloat(val);
        val = memVal / temp;
        memVal = temp;
        val = val.toString();
        isResult = true;
      }
      break;
  }
  display();
}

function pressNum(num) {
  if (firstDigitAfterOperator) {
    val = num;
    firstDigitAfterOperator = false;
    operatorPressed = true;
  } else {
    if (isFirstZero) {
      val = num;
      isFirstZero = false;
    } else {
      val += num;
    }
  }

  display();
}

//declare event listeners
ac.addEventListener("click", clear);
reverse.addEventListener("click", reverseNum);
point.addEventListener("click", decimal);
plus.addEventListener("click", add);
minus.addEventListener("click", substract);
mult.addEventListener("click", multiply);
divide.addEventListener("click", division);
percent.addEventListener("click", percentage);
equal.addEventListener("click", calculate);
zero.addEventListener("click", function () {
  pressNum('0')
});
one.addEventListener("click", function () {
  pressNum('1')
});
two.addEventListener("click", function () {
  pressNum('2')
});
three.addEventListener("click", function () {
  pressNum('3')
});
four.addEventListener("click", function () {
  pressNum('4')
});
five.addEventListener("click", function () {
  pressNum('5')
});
six.addEventListener("click", function () {
  pressNum('6')
});
seven.addEventListener("click", function () {
  pressNum('7')
});
eight.addEventListener("click", function () {
  pressNum('8')
});
nine.addEventListener("click", function () {
  pressNum('9')
});

//keyboard event listener using keyCode because replacements are not yet supported
//by all browsers
document.addEventListener("keypress", function (e) {
  console.log(e.keyCode);
  switch (e.keyCode) {
    case 48:
      pressNum('0');
      break;

    case 49:
      pressNum('1');
      break;

    case 50:
      pressNum('2');
      break;

    case 51:
      pressNum('3');
      break;

    case 52:
      pressNum('4');
      break;

    case 53:
      pressNum('5');
      break;

    case 54:
      pressNum('6');
      break;

    case (55):
      pressNum('7');
      break;

    case 56:
      pressNum('8');
      break;

    case 57:
      pressNum('9');
      break;

    case 44:
    case 46:
      decimal();
      break;

    case 61:
    case 13:
      calculate();
      break;

    case 43:
      add();
      break;

    case 45:
      substract();
      break;

    case 42:
      multiply();
      break;

    case 47:
      division();
      break;

    case 37:
      percentage();
      break;

    case 177:
      reverseNum();
      break;

    case 67:
    case 99:
      clear();
      break;
  }
})<|endoftext|>


<commit_before>var m = require("moment");
var db = require("./db");
var api = require("./api");

/*
 * Function to clone a custom javascript object.
 */
var clone = exports.clone = function(obj){

    if(obj == null || typeof(obj) != 'object')
        return obj;

    var temp = new obj.constructor();
    for(var key in obj)
        temp[key] = clone(obj[key]);

    return temp;
}

exports.get_remote_operations = function(){

	var ops = [];

	for( key in api.remote )
		ops.push(key);

	return ops;
}

/*
 * Function to check db id.
 */
exports.isHex = function( wid ){

	var str = wid.split("");
	for(i in str){

		if(str[i] > "f")
			return false;
	}
	return true;

}

/*
 * Function to check if a user id has access to a document. By now, a user has acces to a document if
 * has the ownership of the document or belongs to the rcpts list of the document.
 */
exports.check_access = function( params, doc ){

	return doc.uid == params.uid || (doc.rcpts != undefined && doc.rcpts.indexOf(params.uid) >= 0);
}

/*
 * gets inner field of the object
 */
var get_field = exports.get_field =  function( obj, fname ){

	if( obj == undefined )
		return undefined;

	var idx = fname.indexOf(".");
	if(  idx != -1 ){

		obj = obj[fname.substr(0,idx)];
		fname = fname.substr(idx+1,fname.length-1);
		return get_field(obj,fname);
	}else
		return obj[fname];

}

/*
 * sets the inner field of the object to the value.
 *  var x = {a:1,b:"kdjfklsdf",c:[5,6,7],d:{e:1,f:"fksdkf",g:[8,9,0]}};
 */
var set_field = exports.set_field = function(obj, fname, value, index ){

	var idx = fname.indexOf(".");

	if(  idx != -1 ){

		var cfield = fname.substr(0,idx);
		if( obj[cfield] == undefined )
			obj[cfield] = {};
		obj = obj[cfield];
		fname = fname.substr(idx+1,fname.length-1);

		set_field(obj,fname,value,index);
	}else{

		if(index != undefined){

			if(typeof obj[fname] == "object")
				obj[fname][index] = value;
			else
				throw new Error("Cannot index");
		}else
			obj[fname] = value;
	}

}

/*
 * deletes inner field of the object.
 */
var del_field = exports.del_field = function(obj, fname, index ){

	if( obj == undefined )
		return;

	var idx = fname.indexOf(".");
	if(  idx != -1 ){

		var cfield = fname.substr(0,idx);
		if( obj[cfield] == undefined )
			obj[cfield] = {};
		obj = obj[cfield];
		fname = fname.substr(idx+1,fname.length-1);

		del_field( obj, fname, index);
	}else{
		if(index != undefined){

			if(typeof obj[fname] == "object")
				obj[fname].splice(index,1);
			else
				throw new Error("Cannot index");
		}else{

			delete obj[fname];
		}

	}

}

/*
 * Change default behaviour of console.log to print timestamp before any message
 * TODO: si se llama mas de una vez los timestamp de van superponiendo a la izquierda del mensaje.
 */
var f = console.log;
exports.add_console_log_printing_format = function(){

	console.tlog = function(){

		var args = Array.prototype.slice.call(arguments);
		args[0] = "[%s] " + args[0];
		args.splice(1,0,m().format("DD/MM/YYYY H:mm:ss"));
		f.apply(this, args);

	}

}

<commit_msg>Added function generate_rstring to generate random string of different length.<commit_after>var m = require("moment");
var db = require("./db");
var api = require("./api");

/*
 * Function to generate a random string of certain length.
 */
exports.generate_rstring = function( length ){

	return Math.random().toString(36).substring(2,2+length);
}

/*
 * Function to clone a custom javascript object.
 */
var clone = exports.clone = function(obj){

    if(obj == null || typeof(obj) != 'object')
        return obj;

    var temp = new obj.constructor();
    for(var key in obj)
        temp[key] = clone(obj[key]);

    return temp;
}

exports.get_remote_operations = function(){

	var ops = [];

	for( key in api.remote )
		ops.push(key);

	return ops;
}

/*
 * Function to check db id.
 */
exports.isHex = function( wid ){

	var str = wid.split("");
	for(i in str){

		if(str[i] > "f")
			return false;
	}
	return true;

}

/*
 * Function to check if a user id has access to a document. By now, a user has acces to a document if
 * has the ownership of the document or belongs to the rcpts list of the document.
 */
exports.check_access = function( params, doc ){

	return doc.uid == params.uid || (doc.rcpts != undefined && doc.rcpts.indexOf(params.uid) >= 0);
}

/*
 * gets inner field of the object
 */
var get_field = exports.get_field =  function( obj, fname ){

	if( obj == undefined )
		return undefined;

	var idx = fname.indexOf(".");
	if(  idx != -1 ){

		obj = obj[fname.substr(0,idx)];
		fname = fname.substr(idx+1,fname.length-1);
		return get_field(obj,fname);
	}else
		return obj[fname];

}

/*
 * sets the inner field of the object to the value.
 *  var x = {a:1,b:"kdjfklsdf",c:[5,6,7],d:{e:1,f:"fksdkf",g:[8,9,0]}};
 */
var set_field = exports.set_field = function(obj, fname, value, index ){

	var idx = fname.indexOf(".");

	if(  idx != -1 ){

		var cfield = fname.substr(0,idx);
		if( obj[cfield] == undefined )
			obj[cfield] = {};
		obj = obj[cfield];
		fname = fname.substr(idx+1,fname.length-1);

		set_field(obj,fname,value,index);
	}else{

		if(index != undefined){

			if(typeof obj[fname] == "object")
				obj[fname][index] = value;
			else
				throw new Error("Cannot index");
		}else
			obj[fname] = value;
	}

}

/*
 * deletes inner field of the object.
 */
var del_field = exports.del_field = function(obj, fname, index ){

	if( obj == undefined )
		return;

	var idx = fname.indexOf(".");
	if(  idx != -1 ){

		var cfield = fname.substr(0,idx);
		if( obj[cfield] == undefined )
			obj[cfield] = {};
		obj = obj[cfield];
		fname = fname.substr(idx+1,fname.length-1);

		del_field( obj, fname, index);
	}else{
		if(index != undefined){

			if(typeof obj[fname] == "object")
				obj[fname].splice(index,1);
			else
				throw new Error("Cannot index");
		}else{

			delete obj[fname];
		}

	}

}

/*
 * Change default behaviour of console.log to print timestamp before any message
 * TODO: si se llama mas de una vez los timestamp de van superponiendo a la izquierda del mensaje.
 */
var f = console.log;
exports.add_console_log_printing_format = function(){

	console.tlog = function(){

		var args = Array.prototype.slice.call(arguments);
		args[0] = "[%s] " + args[0];
		args.splice(1,0,m().format("DD/MM/YYYY H:mm:ss"));
		f.apply(this, args);

	}

}

<|endoftext|>


<commit_before>import React from 'react';

class CreateComment extends React.Component {
  _create() {
    const text = this.refs.text.value;
    const {create, postId} = this.props;
    create(postId, text);
    this.refs.text.value = '';
  }

  _renderError(error) {
    return (

        {error}

    );
  }
  render() {
    const {error} = this.props;
    return (

        {error ? this._renderError(error) : null}
        <textarea ref="text" placeholder="Enter your comment here.">

        </textarea>

        <button onClick={this._create}>Add Comment</button>

    );
  }
}

CreateComment.propTypes = {
  error: React.PropTypes.string,
  create: React.PropTypes.func,
  postId: React.PropTypes.string
};

export default CreateComment;
<commit_msg>Fixing bug in comments.components.create_comment<commit_after>import React from 'react';

class CreateComment extends React.Component {
  _create() {
    const text = this.refs.text.value;
    const {create, postId} = this.props;
    create(postId, text);
    this.refs.text.value = '';
  }

  _renderError(error) {
    return (

        {error}

    );
  }
  render() {
    const {error} = this.props;
    return (

        {error ? this._renderError(error) : null}
        <textarea ref="text" placeholder="Enter your comment here.">

        </textarea>

        <button onClick={this._create.bind(this)}>Add Comment</button>

    );
  }
}

CreateComment.propTypes = {
  error: React.PropTypes.string,
  create: React.PropTypes.func,
  postId: React.PropTypes.string
};

export default CreateComment;
<|endoftext|>


<commit_before>(function ($) {
    function Person(data) {
        _.extend(this, data);
    }
    _.extend(Person.prototype, {

        age: function (date) {
            var birth = this.birth_date;
            if (typeof birth == 'number' || /^c/.test(birth)) {
                birth += '-07-01';
                birth = birth.replace(/^c\s+/, '');
            }
            return moment(date).diff(moment(birth, 'YYYY-MM-DD'), 'd') / 365.2425;
        },

        experience: function (date, pattern) {
            var ymd = moment(date).format('YYYY-MM-DD'),
                regexp = new RegExp(pattern),
                days = 0;
            this.positions.forEach(function (p) {
                if (p.start <= ymd && regexp.test(p.office)) {
                    var end = p.end <= ymd ? moment(p.end, 'YYYY-MM-DD') : moment(date);
                    days += end.diff(moment(p.start, 'YYYY-MM-DD'), 'd');
                }
            });
            return days / 365.2425;
        },

        councilExperience: function (date) {
            return this.experience(date, 'Council');
        },

        mayoralExperience: function (date) {
            return this.experience(date, 'Mayor');
        }
    });

    function Council() {
        _.extend(this, {
            members: [],
            add: [],
            remove: []
        });
    }
    _.extend(Council.prototype, {

        genderCount: function (gender) {
            return this.members.reduce(function (previousValue, currentPerson) {
                if (currentPerson.gender == gender) {
                    previousValue++;
                }
                return previousValue;
            }, 0);
        },

        women: function () {
            return this.genderCount('F');
        },

        men: function () {
            return this.genderCount('M');
        },

        ages: function (date) {
            return this.members.map(function (person) {
                return person.age(date);
            });
        },

        averageAge: function (date) {
            return this.ages(date).reduce(function (previous, current) {
                    return previous + current;
                }, 0) / this.members.length;
        },

        minAge: function (date) {
            return _.min(this.ages(date));
        },

        maxAge: function (date) {
            return _.max(this.ages(date));
        },

        totalCouncilExperience: function (date) {
            return this.members.reduce(function (previousValue, currentPerson) {
                return previousValue + currentPerson.councilExperience(date);
            }, 0);
        },

        totalMayoralExperience: function (date) {
            return this.members.reduce(function (previousValue, currentPerson) {
                return previousValue + currentPerson.mayoralExperience(date);
            }, 0);
        },

        changes: function () {
            var texts = [];
            if (this.remove.length) {
                texts.push('Lost ' + _.pluck(this.remove, 'name').join(', ') + '.');
            }
            if (this.add.length) {
                texts.push('Gained ' + _.pluck(this.add, 'name').join(', ') + '.');
            }
            return texts.join('
');
        }
    });

    $.getJSON('data/person.json', process);

    function process(personData) {
        var councils = {},
            members = [];
        _.each(personData, function (data) {
            var person = new Person(data);
            person.positions.forEach(function (p) {
                if (!/Council/.test(p.office)) {
                    return;
                }
                if (p.start) {
                    if (!councils[p.start]) {
                        councils[p.start] = new Council();
                        councils[p.start].date = p.start;
                    }
                    councils[p.start].add.push(person);
                }
                else {
                    throw 'Missing start in ' + person.code;
                }
                if (p.end) {
                    if (!councils[p.end]) {
                        councils[p.end] = new Council();
                        councils[p.end].date = p.end;
                    }
                    councils[p.end].remove.push(person);
                }
            });
        });
        councils = _.pick(councils, _.keys(councils).sort());
        _.each(councils, function (c, date) {
            members = _.union(_.difference(members, c.remove), c.add);
            c.members = members.slice();
        });
        draw(councils);
    }

    function dataRow(council, date) {
        return {
            date: date,
            men: council.men(),
            women: council.women(),
            councilExperience: council.totalCouncilExperience(date),
            mayoralExperience: council.totalMayoralExperience(date),
            averageAge: council.averageAge(date),
            minAge: council.minAge(date),
            maxAge: council.maxAge(date),
            changes: council.changes()
        };
    }

    function millisToYmd(millis) {
        return moment(millis).utc().format('YYYY-MM-DD');
    }

    function draw(councils) {
        var data = [],
            prevCouncil;
        _.each(councils, function (council, ymd) {
            if (prevCouncil) {
                data.push(dataRow(prevCouncil, ymd));
            }
            data.push(dataRow(council, ymd));
            prevCouncil = council;
        });
        /*
        now = new Date();
        date = moment(prevCouncil.date).add(180, 'd').toDate();
        if (now.getTime() > date.getTime()) {
            date = now;
        }
        */
        data.push(dataRow(prevCouncil, moment().format('YYYY-MM-DD')));
        var xConfig = {
                type : 'timeseries',
                tick: {
                    format: '%Y',
                    values: _.range(1975, 2021, 2).map(function (y) { return y + '-01-01'; })
                },
                padding: 0
            },
            tooltipConfig = {
                format: {
                    title: function (x) {
                        return moment(x).format('D MMM YYYY');
                    },
                    value: function (value) {
                        return Array.isArray(value) ? _.uniq(value).map(function (item) { return item % 1 ? item.toFixed(2) : item; }).join(' ⮕ ') : value;
                    }
                },
                contents: function (d, defaultTitleFormat, defaultValueFormat, color) {
                    var newD = [],
                        ymd = moment(d[0].x).format('YYYY-MM-DD'),
                        $div;
                    d.forEach(function (item) {
                        var last = newD.length && newD[newD.length - 1];
                        if (last && last.id === item.id) {
                            last.value.push(item.value);
                        }
                        else {
                            newD.push(_.extend({}, item, {value: [item.value]}));
                        }
                    });
                    $div = $('
').append(c3.chart.internal.fn.getTooltipContent.call(this, newD, defaultTitleFormat, defaultValueFormat, color));
                    $div.find('table').append('
' + councils[ymd].changes() + '
');
                    return $div.html();
                }
            };
        var charts = [
        c3.generate({
            bindto: '#women-graph',
            data: {
                x: 'date',
                type: 'area',
                groups: [['women', 'men']],
                colors: {
                    women: '#018571',
                    men: '#80cdc1'
                },
                columns: [
                    ['date'].concat(_.pluck(data, 'date')),
                    ['women'].concat(_.pluck(data, 'women')),
                    ['men'].concat(_.pluck(data, 'men'))
                ]
            },
            axis: {
                x: xConfig,
                y: {
                    max: 13,
                    tick: {
                        values: _.range(0, 14, 2)
                    },
                    padding: 0
                }
            },
            point: {
                show: false
            },
            padding: {right: 10},
            tooltip: tooltipConfig
        }),
        c3.generate({
            bindto: '#experience-graph',
            data: {
                x: 'date',
                type: 'area',
                groups: [['councilExperience', 'mayoralExperience']],
                order: null,
                colors: {
                    councilExperience: '#a6611a',
                    mayoralExperience: '#dfc27d'
                },
                columns: [
                    ['date'].concat(_.pluck(data, 'date')),
                    ['councilExperience'].concat(_.pluck(data, 'councilExperience')),
                    ['mayoralExperience'].concat(_.pluck(data, 'mayoralExperience'))
                ]
            },
            axis: {
                x: xConfig,
                y: {
                    padding: 0
                }
            },
            point: {
                show: false
            },
            padding: {right: 10},
            tooltip: tooltipConfig
        }),
        c3.generate({
            bindto: '#age-graph',
            data: {
                x: 'date',
                type: 'line',
                columns: [
                    ['date'].concat(_.pluck(data, 'date')),
                    ['averageAge'].concat(_.pluck(data, 'averageAge')),
                    ['minAge'].concat(_.pluck(data, 'minAge')),
                    ['maxAge'].concat(_.pluck(data, 'maxAge'))
                ]
            },
            axis: {
                x: xConfig,
                y: {
                    padding: 0
                }
            },
            point: {
                show: false
            },
            padding: {right: 10},
            tooltip: tooltipConfig
        })
        ];
        // Flush (redraw) is needed for some reason to get widths right
        charts.forEach(function (chart) { chart.flush(); });
    }
})(jQuery);
<commit_msg>fix error from mousing over last point; extend sensitivity radius of points<commit_after>(function ($) {
    function Person(data) {
        _.extend(this, data);
    }
    _.extend(Person.prototype, {

        age: function (date) {
            var birth = this.birth_date;
            if (typeof birth == 'number' || /^c/.test(birth)) {
                birth += '-07-01';
                birth = birth.replace(/^c\s+/, '');
            }
            return moment(date).diff(moment(birth, 'YYYY-MM-DD'), 'd') / 365.2425;
        },

        experience: function (date, pattern) {
            var ymd = moment(date).format('YYYY-MM-DD'),
                regexp = new RegExp(pattern),
                days = 0;
            this.positions.forEach(function (p) {
                if (p.start <= ymd && regexp.test(p.office)) {
                    var end = p.end <= ymd ? moment(p.end, 'YYYY-MM-DD') : moment(date);
                    days += end.diff(moment(p.start, 'YYYY-MM-DD'), 'd');
                }
            });
            return days / 365.2425;
        },

        councilExperience: function (date) {
            return this.experience(date, 'Council');
        },

        mayoralExperience: function (date) {
            return this.experience(date, 'Mayor');
        }
    });

    function Council() {
        _.extend(this, {
            members: [],
            add: [],
            remove: []
        });
    }
    _.extend(Council.prototype, {

        genderCount: function (gender) {
            return this.members.reduce(function (previousValue, currentPerson) {
                if (currentPerson.gender == gender) {
                    previousValue++;
                }
                return previousValue;
            }, 0);
        },

        women: function () {
            return this.genderCount('F');
        },

        men: function () {
            return this.genderCount('M');
        },

        ages: function (date) {
            return this.members.map(function (person) {
                return person.age(date);
            });
        },

        averageAge: function (date) {
            return this.ages(date).reduce(function (previous, current) {
                    return previous + current;
                }, 0) / this.members.length;
        },

        minAge: function (date) {
            return _.min(this.ages(date));
        },

        maxAge: function (date) {
            return _.max(this.ages(date));
        },

        totalCouncilExperience: function (date) {
            return this.members.reduce(function (previousValue, currentPerson) {
                return previousValue + currentPerson.councilExperience(date);
            }, 0);
        },

        totalMayoralExperience: function (date) {
            return this.members.reduce(function (previousValue, currentPerson) {
                return previousValue + currentPerson.mayoralExperience(date);
            }, 0);
        },

        changes: function () {
            var texts = [];
            if (this.remove.length) {
                texts.push('Lost ' + _.pluck(this.remove, 'name').join(', ') + '.');
            }
            if (this.add.length) {
                texts.push('Gained ' + _.pluck(this.add, 'name').join(', ') + '.');
            }
            return texts.join('
');
        }
    });

    $.getJSON('data/person.json', process);

    function process(personData) {
        var councils = {},
            members = [];
        _.each(personData, function (data) {
            var person = new Person(data);
            person.positions.forEach(function (p) {
                if (!/Council/.test(p.office)) {
                    return;
                }
                if (p.start) {
                    if (!councils[p.start]) {
                        councils[p.start] = new Council();
                        councils[p.start].date = p.start;
                    }
                    councils[p.start].add.push(person);
                }
                else {
                    throw 'Missing start in ' + person.code;
                }
                if (p.end) {
                    if (!councils[p.end]) {
                        councils[p.end] = new Council();
                        councils[p.end].date = p.end;
                    }
                    councils[p.end].remove.push(person);
                }
            });
        });
        councils = _.pick(councils, _.keys(councils).sort());
        _.each(councils, function (c, date) {
            members = _.union(_.difference(members, c.remove), c.add);
            c.members = members.slice();
        });
        draw(councils);
    }

    function dataRow(council, date) {
        return {
            date: date,
            men: council.men(),
            women: council.women(),
            councilExperience: council.totalCouncilExperience(date),
            mayoralExperience: council.totalMayoralExperience(date),
            averageAge: council.averageAge(date),
            minAge: council.minAge(date),
            maxAge: council.maxAge(date),
            changes: council.changes()
        };
    }

    function millisToYmd(millis) {
        return moment(millis).utc().format('YYYY-MM-DD');
    }

    function draw(councils) {
        var data = [],
            prevCouncil;
        _.each(councils, function (council, ymd) {
            if (prevCouncil) {
                data.push(dataRow(prevCouncil, ymd));
            }
            data.push(dataRow(council, ymd));
            prevCouncil = council;
        });
        /*
        now = new Date();
        date = moment(prevCouncil.date).add(180, 'd').toDate();
        if (now.getTime() > date.getTime()) {
            date = now;
        }
        */
        data.push(dataRow(prevCouncil, moment().format('YYYY-MM-DD')));
        var xConfig = {
                type : 'timeseries',
                tick: {
                    format: '%Y',
                    values: _.range(1975, 2021, 2).map(function (y) { return y + '-01-01'; })
                },
                padding: 0
            },
            tooltipConfig = {
                format: {
                    title: function (x) {
                        return moment(x).format('D MMM YYYY');
                    },
                    value: function (value) {
                        return Array.isArray(value) ? _.uniq(value).map(function (item) { return item % 1 ? item.toFixed(2) : item; }).join(' ⮕ ') : value;
                    }
                },
                contents: function (d, defaultTitleFormat, defaultValueFormat, color) {
                    var newD = [],
                        ymd = moment(d[0].x).format('YYYY-MM-DD'),
                        $div;
                    d.forEach(function (item) {
                        var last = newD.length && newD[newD.length - 1];
                        if (last && last.id === item.id) {
                            last.value.push(item.value);
                        }
                        else {
                            newD.push(_.extend({}, item, {value: [item.value]}));
                        }
                    });
                    $div = $('
').append(c3.chart.internal.fn.getTooltipContent.call(this, newD, defaultTitleFormat, defaultValueFormat, color));
                    if (councils[ymd]) {
                        $div.find('table').append('
' + councils[ymd].changes() + '
');
                    }
                    return $div.html();
                }
            };
        var charts = [
        c3.generate({
            bindto: '#women-graph',
            data: {
                x: 'date',
                type: 'area',
                groups: [['women', 'men']],
                colors: {
                    women: '#018571',
                    men: '#80cdc1'
                },
                columns: [
                    ['date'].concat(_.pluck(data, 'date')),
                    ['women'].concat(_.pluck(data, 'women')),
                    ['men'].concat(_.pluck(data, 'men'))
                ]
            },
            axis: {
                x: xConfig,
                y: {
                    max: 13,
                    tick: {
                        values: _.range(0, 14, 2)
                    },
                    padding: 0
                }
            },
            point: {
                show: false,
                sensitivity: 100
            },
            padding: {right: 10},
            tooltip: tooltipConfig
        }),
        c3.generate({
            bindto: '#experience-graph',
            data: {
                x: 'date',
                type: 'area',
                groups: [['councilExperience', 'mayoralExperience']],
                order: null,
                colors: {
                    councilExperience: '#a6611a',
                    mayoralExperience: '#dfc27d'
                },
                columns: [
                    ['date'].concat(_.pluck(data, 'date')),
                    ['councilExperience'].concat(_.pluck(data, 'councilExperience')),
                    ['mayoralExperience'].concat(_.pluck(data, 'mayoralExperience'))
                ]
            },
            axis: {
                x: xConfig,
                y: {
                    padding: 0
                }
            },
            point: {
                show: false,
                sensitivity: 100
            },
            padding: {right: 10},
            tooltip: tooltipConfig
        }),
        c3.generate({
            bindto: '#age-graph',
            data: {
                x: 'date',
                type: 'line',
                columns: [
                    ['date'].concat(_.pluck(data, 'date')),
                    ['averageAge'].concat(_.pluck(data, 'averageAge')),
                    ['minAge'].concat(_.pluck(data, 'minAge')),
                    ['maxAge'].concat(_.pluck(data, 'maxAge'))
                ]
            },
            axis: {
                x: xConfig,
                y: {
                    padding: 0
                }
            },
            point: {
                show: false,
                sensitivity: 100
            },
            padding: {right: 10},
            tooltip: tooltipConfig
        })
        ];
        // Flush (redraw) is needed for some reason to get widths right
        charts.forEach(function (chart) { chart.flush(); });
    }
})(jQuery);
<|endoftext|>


<commit_before>var fs = require('fs-extra');
var path = require('path');
var schemes = require('./schemes.js');
var semver = require('semver');

module.exports = {
  extractDependencies: function(dependencies) {
    var pkgs = [];
    Object.keys(dependencies || {}).forEach(function(k) {
      var expression = dependencies[k];
      var name = k, scheme, pos = expression.indexOf(':');
      if( ~pos ) {
        scheme = expression.substring(0, pos);
        expression = expression.substring(pos + 1);
      }

      scheme = scheme || schemes.default();

      // is version
      if( ~['*', 'latest'].indexOf(expression) ) {
        pkgs.push(scheme + ':' + k);
      } else if( semver.validRange(expression) ) {
        pkgs.push(scheme + ':' + k + '@' + expression);
      } else {
        pkgs.push(scheme + ':' + name + '[' + expression + ']');
      }
    });
    return pkgs;
  },
  parseExpression: function(expression) {
    var alias = (function() {
      var pos = expression.indexOf('[');
      if( ~pos ) return expression.substring(0, pos);
    })();

    if( alias ) {
      expression = (function() {
        expression = expression.substring(expression.indexOf('[') + 1)
        expression = expression.substring(0, expression.lastIndexOf(']'));
        return expression;
      })();
    }

    var scheme = (function() {
      if( alias && ~alias.indexOf(':') ) return alias.substring(0, alias.indexOf(':'));
      if( expression && ~expression.indexOf(':') ) return expression.substring(0, expression.indexOf(':'));
    })();

    if( alias && ~alias.indexOf(':') ) alias = alias.substring(alias.indexOf(':') + 1);
    if( expression && ~expression.indexOf(':') ) expression = expression.substring(expression.indexOf(':') + 1);

    return {
      scheme: scheme || schemes.default(),
      alias: alias,
      expression: expression
    }
  },
  extractPaths: (function() {
    var ignores = ['.', '..', 'npm-debug.log', '.DS_Store', '.git', '.gitignore', '.lock-wscript', '.hg', '.svn', 'CVS'];

    return function(basedir, excludes) {
      var dirs = [], files = [], excludes = excludes || [];

      function visit(dir, nomore) {
        var list = fs.readdirSync(dir);
        list.forEach(function(filename) {
          if( ~ignores.indexOf(filename) ) return;
          if( ~excludes.indexOf(filename) ) return;
          if( filename.startsWith('._') || filename.endsWith('.swp') || filename.endsWith('.log') || filename.startsWith('.wafpickle') ) return;

          var file = path.join(dir, filename);
          var stat = fs.statSync(file);
          if( stat.isDirectory() ) dirs.push(file.substring(basedir.length)), !nomore && visit(file, ~['node_modules', 'web_modules'].indexOf(filename));
          else if( stat.isFile() ) files.push(file.substring(basedir.length));
        });
      }

      visit(basedir);

      return {
        basedir: basedir,
        directories: dirs,
        files: files
      }
    }
  })(),
  visitSubPackages: function(basedir, listener) {
    var founds = [];

    function visit(dir) {
      function visitpkgs(subpkgdir) {
        if( fs.existsSync(subpkgdir) ) {
          var list = fs.readdirSync(subpkgdir);
          list.forEach(function(filename) {
            var pkgdir = path.join(subpkgdir, filename);
            var stat = fs.statSync(pkgdir);
            if( filename[0] === '.' || !stat.isDirectory() ) return;

            if( filename[0] === '@' ) {  // private npm
              fs.readdirSync(pkgdir).forEach(function(_filename) {
                var _pkgdir = path.join(pkgdir, _filename);
                founds.push(_pkgdir);
                listener && listener({
                  name: '@' + filename + '/' + _filename,
                  directory: _pkgdir,
                  parent: dir
                });
                visit(_pkgdir);
              });
            } else {
              founds.push(pkgdir);
              listener && listener({
                name: filename,
                directory: pkgdir,
                parent: dir
              });
              visit(pkgdir);
            }
          });
        }
      }

      visitpkgs(path.join(dir, 'node_modules'));
      visitpkgs(path.join(dir, 'web_modules'));
    }

    visit(basedir);
    return founds;
  }
};<commit_msg>Fix supports old nodejs versions<commit_after>var fs = require('fs-extra');
var path = require('path');
var schemes = require('./schemes.js');
var semver = require('semver');

function endsWith(str, word) {
  if( !str || !word ) return false;
  if( str === word ) return true;
  var i = str.lastIndexOf(word);
  return i > 0 && i === str.length - word.length;
}

function startsWith(str, word) {
  if( !str || !word ) return false;
  if( str === word ) return true;
  return str.indexOf(word) === 0 ? true : false;
}

module.exports = {
  extractDependencies: function(dependencies) {
    var pkgs = [];
    Object.keys(dependencies || {}).forEach(function(k) {
      var expression = dependencies[k];
      var name = k, scheme, pos = expression.indexOf(':');
      if( ~pos ) {
        scheme = expression.substring(0, pos);
        expression = expression.substring(pos + 1);
      }

      scheme = scheme || schemes.default();

      // is version
      if( ~['*', 'latest'].indexOf(expression) ) {
        pkgs.push(scheme + ':' + k);
      } else if( semver.validRange(expression) ) {
        pkgs.push(scheme + ':' + k + '@' + expression);
      } else {
        pkgs.push(scheme + ':' + name + '[' + expression + ']');
      }
    });
    return pkgs;
  },
  parseExpression: function(expression) {
    var alias = (function() {
      var pos = expression.indexOf('[');
      if( ~pos ) return expression.substring(0, pos);
    })();

    if( alias ) {
      expression = (function() {
        expression = expression.substring(expression.indexOf('[') + 1)
        expression = expression.substring(0, expression.lastIndexOf(']'));
        return expression;
      })();
    }

    var scheme = (function() {
      if( alias && ~alias.indexOf(':') ) return alias.substring(0, alias.indexOf(':'));
      if( expression && ~expression.indexOf(':') ) return expression.substring(0, expression.indexOf(':'));
    })();

    if( alias && ~alias.indexOf(':') ) alias = alias.substring(alias.indexOf(':') + 1);
    if( expression && ~expression.indexOf(':') ) expression = expression.substring(expression.indexOf(':') + 1);

    return {
      scheme: scheme || schemes.default(),
      alias: alias,
      expression: expression
    }
  },
  extractPaths: (function() {
    var ignores = ['.', '..', 'npm-debug.log', '.DS_Store', '.git', '.gitignore', '.lock-wscript', '.hg', '.svn', 'CVS'];

    return function(basedir, excludes) {
      var dirs = [], files = [], excludes = excludes || [];

      function visit(dir, nomore) {
        var list = fs.readdirSync(dir);
        list.forEach(function(filename) {
          if( ~ignores.indexOf(filename) ) return;
          if( ~excludes.indexOf(filename) ) return;
          if( startsWith(filename, '._') || endsWith(filename, '.swp') || endsWith(filename, '.log') || startsWith(filename, '.wafpickle') ) return;

          var file = path.join(dir, filename);
          var stat = fs.statSync(file);
          if( stat.isDirectory() ) dirs.push(file.substring(basedir.length)), !nomore && visit(file, ~['node_modules', 'web_modules'].indexOf(filename));
          else if( stat.isFile() ) files.push(file.substring(basedir.length));
        });
      }

      visit(basedir);

      return {
        basedir: basedir,
        directories: dirs,
        files: files
      }
    }
  })(),
  visitSubPackages: function(basedir, listener) {
    var founds = [];

    function visit(dir) {
      function visitpkgs(subpkgdir) {
        if( fs.existsSync(subpkgdir) ) {
          var list = fs.readdirSync(subpkgdir);
          list.forEach(function(filename) {
            var pkgdir = path.join(subpkgdir, filename);
            var stat = fs.statSync(pkgdir);
            if( filename[0] === '.' || !stat.isDirectory() ) return;

            if( filename[0] === '@' ) {  // private npm
              fs.readdirSync(pkgdir).forEach(function(_filename) {
                var _pkgdir = path.join(pkgdir, _filename);
                founds.push(_pkgdir);
                listener && listener({
                  name: '@' + filename + '/' + _filename,
                  directory: _pkgdir,
                  parent: dir
                });
                visit(_pkgdir);
              });
            } else {
              founds.push(pkgdir);
              listener && listener({
                name: filename,
                directory: pkgdir,
                parent: dir
              });
              visit(pkgdir);
            }
          });
        }
      }

      visitpkgs(path.join(dir, 'node_modules'));
      visitpkgs(path.join(dir, 'web_modules'));
    }

    visit(basedir);
    return founds;
  }
};<|endoftext|>


<commit_before>/*
* Copyright 2014 Space Dynamics Laboratory - Utah State University Research Foundation.
*
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an 'AS IS' BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
'use strict';

/*global setUpDropdown*/

app.controller('NavCtrl', ['$scope', '$location', '$rootScope', 'business', '$route', '$timeout', 'auth', function ($scope, $location, $rootScope, Business, $route, $timeout, Auth) { /*jshint unused: false*/

  /*******************************************************************************
  * This Controller gives us a place to add functionality to the navbar
  *******************************************************************************/
  //////////////////////////////////////////////////////////////////////////////
  // Variables
  //////////////////////////////////////////////////////////////////////////////
  $scope._scopename   = 'nav';
  $scope.navLocation  = 'views/nav/nav.html';
  $scope.searchKey    = $rootScope.searchKey;
  $scope.user         = {};
  $scope.beforeLogin  = null;
  $scope.typeahead    = null;

  /***************************************************************
  * Set up typeahead, and then watch for selection made
  ***************************************************************/
  Business.componentservice.getComponentDetails().then(function(result) {
    Business.typeahead(result, 'name').then(function(value){
      $scope.typeahead = value;
    });
  });

  //////////////////////////////////////////////////////////////////////////////
  // Event Watches
  //////////////////////////////////////////////////////////////////////////////
  $scope.$on('$beforeLogin', function(event, path, search){
    $scope.beforeLogin = {};
    $scope.beforeLogin.path = path;
    $scope.beforeLogin.search = search;
    Auth.login($scope.user).then(function () {
    }, function (error) {
      $scope.error = error.toString();
    });

    // $location.path('/login');
  });

  /***************************************************************
  * This function watches for the content loaded event and then checks
  * to see if they're logged in.
  ***************************************************************/
  $scope.$on('$includeContentLoaded', function(event){
    $scope.user.isLoggedIn = Auth.signedIn();
  });

  /***************************************************************
  * This function watches for the login event in order to adjust
  * the navigation and possibly redirect the page back to where they were.
  ***************************************************************/
  $scope.$on('$login', function(event, user){
    $scope.user.info = user;
    $scope.user.isLoggedIn = Auth.signedIn();
    if ($scope.beforeLogin && $scope.beforeLogin.path !== '/login') {
      var temp = $scope.beforeLogin.path;
      var temp2 = $scope.beforeLogin.search;
      $scope.beforeLogin = null;
      $location.search(temp2);
      $location.path(temp);
    } else {
      $scope.beforeLogin = null;
      $location.search({});
      $location.path('/');
    }
  });

  /***************************************************************
  * Catch the enter/select event here
  ***************************************************************/
  $scope.$on('$typeahead.select', function(event, value, index) {
    $scope.searchKey = value;
    if (value !== undefined) {
      $scope.goToSearch();
      $scope.$apply();
    } else {
      $scope.goToSearch();
      $scope.$apply();
    }
  });

  /***************************************************************
  * Catch the navigation location change event here
  ***************************************************************/
  $scope.$on('$changenav', function(event, value, index) {
    $scope.navLocation = value;
  });

  //////////////////////////////////////////////////////////////////////////////
  // Functions
  //////////////////////////////////////////////////////////////////////////////

  /***************************************************************
  * This function sends the routing to the results page with a specified
  * search key saved in the localCache
  ***************************************************************/
  $scope.goToSearch = function(){ /*jshint unused:false*/
    $scope.closeNavbarItem('searchNavButton');
    var key = 'All';
    if ($scope.searchKey) {
      key = $scope.searchKey;
      $rootScope.searchKey = $scope.searchKey;
    }
    $location.search({
      'type': 'search',
      'code': key
    });
    Business.componentservice.search('search', key, true).then(function (key) {
      if($location.path() === '/results') {
        $rootScope.$broadcast('$callSearch');
      } else {
        $location.path('/results');
      }
    });
  };

  /***************************************************************
  * This function sends the routing to the results page with a specified
  * search key saved in the localCache
  ***************************************************************/
  $scope.goToLogin = function(){ /*jshint unused:false*/

    $location.search({});
    $location.path('/login');
  };

  /***************************************************************
  * This function sends the person home
  ***************************************************************/
  $scope.sendHome = function(){ /*jshint unused:false*/
    Business.componentservice.search('search', $scope.searchKey);
    $location.path('/');
  };

  /***************************************************************
  * This function sends the navigation to a specified route.
  ***************************************************************/
  $scope.send = function(route) {
    $location.path(route);
  };

  /***************************************************************
  * Log out the user
  ***************************************************************/
  $scope.logout = function () {
    Auth.logout();
    $scope.user.isLoggedIn = false;
    $route.reload();
  };

  //////////////////////////////////////////////////////////////////////////////
  // Scope Watches
  //////////////////////////////////////////////////////////////////////////////

  /*******************************************************************************
  * This function sets the rootScope's search key so that if you did it in the
  * controller search, it is still preserved across the page.
  * params: param name -- param description
  * returns: Return name -- return description
  *******************************************************************************/
  $rootScope.$watch('searchKey', function() {
    $scope.searchKey = $rootScope.searchKey;
  });
  $scope.$watch('searchKey', function() {
    $rootScope.searchKey = $scope.searchKey;
  });

  // We have to manually connect the list item to the dropdown toggle because the
  // routing and nav load somehow delays it which makes the dropdown not work
  // until the second click. This makes it work on first click.
  $scope.$watch('navLocation', function() {
    $timeout(function() {
      setUpDropdown('dropTheMenu');
    }, 500);
  });

  /***************************************************************
  * Automatically login the user for the demo... DELETE THIS LATER
  ***************************************************************/

  $scope.$emit('$TRIGGEREVENT','$beforeLogin', $location.path(), $location.search());

}]);
<commit_msg>Fixed a bug with opening windows that is caused by the navigation login sequence.<commit_after>/*
* Copyright 2014 Space Dynamics Laboratory - Utah State University Research Foundation.
*
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an 'AS IS' BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
'use strict';

/*global setUpDropdown*/

app.controller('NavCtrl', ['$scope', '$location', '$rootScope', 'business', '$route', '$timeout', 'auth', function ($scope, $location, $rootScope, Business, $route, $timeout, Auth) { /*jshint unused: false*/

  /*******************************************************************************
  * This Controller gives us a place to add functionality to the navbar
  *******************************************************************************/
  //////////////////////////////////////////////////////////////////////////////
  // Variables
  //////////////////////////////////////////////////////////////////////////////
  $scope._scopename   = 'nav';
  $scope.navLocation  = 'views/nav/nav.html';
  $scope.searchKey    = $rootScope.searchKey;
  $scope.user         = {};
  $scope.beforeLogin  = null;
  $scope.typeahead    = null;

  /***************************************************************
  * Set up typeahead, and then watch for selection made
  ***************************************************************/
  Business.componentservice.getComponentDetails().then(function(result) {
    Business.typeahead(result, 'name').then(function(value){
      $scope.typeahead = value;
    });
  });

  //////////////////////////////////////////////////////////////////////////////
  // Event Watches
  //////////////////////////////////////////////////////////////////////////////
  $scope.$on('$beforeLogin', function(event, path, search){
    $scope.beforeLogin = {};
    $scope.beforeLogin.path = path;
    $scope.beforeLogin.search = search;
    Auth.login($scope.user).then(function () {
    }, function (error) {
      $scope.error = error.toString();
    });

    // $location.path('/login');
  });

  /***************************************************************
  * This function watches for the content loaded event and then checks
  * to see if they're logged in.
  ***************************************************************/
  $scope.$on('$includeContentLoaded', function(event){
    $scope.user.isLoggedIn = Auth.signedIn();
  });

  /***************************************************************
  * This function watches for the login event in order to adjust
  * the navigation and possibly redirect the page back to where they were.
  ***************************************************************/
  $scope.$on('$login', function(event, user){
    $scope.user.info = user;
    $scope.user.isLoggedIn = Auth.signedIn();
    if ($scope.beforeLogin && $scope.beforeLogin.path !== '/login') {
      var temp = $scope.beforeLogin.path;
      var temp2 = $scope.beforeLogin.search;
      $scope.beforeLogin = null;
      $location.search(temp2);
      $location.path(temp);
    } else {
      $scope.beforeLogin = null;
      // $location.search({});
      // $location.path('/');
    }
  });

  /***************************************************************
  * Catch the enter/select event here
  ***************************************************************/
  $scope.$on('$typeahead.select', function(event, value, index) {
    $scope.searchKey = value;
    if (value !== undefined) {
      $scope.goToSearch();
      $scope.$apply();
    } else {
      $scope.goToSearch();
      $scope.$apply();
    }
  });

  /***************************************************************
  * Catch the navigation location change event here
  ***************************************************************/
  $scope.$on('$changenav', function(event, value, index) {
    $scope.navLocation = value;
  });

  //////////////////////////////////////////////////////////////////////////////
  // Functions
  //////////////////////////////////////////////////////////////////////////////

  /***************************************************************
  * This function sends the routing to the results page with a specified
  * search key saved in the localCache
  ***************************************************************/
  $scope.goToSearch = function(){ /*jshint unused:false*/
    $scope.closeNavbarItem('searchNavButton');
    var key = 'All';
    if ($scope.searchKey) {
      key = $scope.searchKey;
      $rootScope.searchKey = $scope.searchKey;
    }
    $location.search({
      'type': 'search',
      'code': key
    });
    Business.componentservice.search('search', key, true).then(function (key) {
      if($location.path() === '/results') {
        $rootScope.$broadcast('$callSearch');
      } else {
        $location.path('/results');
      }
    });
  };

  /***************************************************************
  * This function sends the routing to the results page with a specified
  * search key saved in the localCache
  ***************************************************************/
  $scope.goToLogin = function(){ /*jshint unused:false*/

    $location.search({});
    $location.path('/login');
  };

  /***************************************************************
  * This function sends the person home
  ***************************************************************/
  $scope.sendHome = function(){ /*jshint unused:false*/
    Business.componentservice.search('search', $scope.searchKey);
    $location.path('/');
  };

  /***************************************************************
  * This function sends the navigation to a specified route.
  ***************************************************************/
  $scope.send = function(route) {
    $location.path(route);
  };

  /***************************************************************
  * Log out the user
  ***************************************************************/
  $scope.logout = function () {
    Auth.logout();
    $scope.user.isLoggedIn = false;
    $route.reload();
  };

  //////////////////////////////////////////////////////////////////////////////
  // Scope Watches
  //////////////////////////////////////////////////////////////////////////////

  /*******************************************************************************
  * This function sets the rootScope's search key so that if you did it in the
  * controller search, it is still preserved across the page.
  * params: param name -- param description
  * returns: Return name -- return description
  *******************************************************************************/
  $rootScope.$watch('searchKey', function() {
    $scope.searchKey = $rootScope.searchKey;
  });
  $scope.$watch('searchKey', function() {
    $rootScope.searchKey = $scope.searchKey;
  });

  // We have to manually connect the list item to the dropdown toggle because the
  // routing and nav load somehow delays it which makes the dropdown not work
  // until the second click. This makes it work on first click.
  $scope.$watch('navLocation', function() {
    $timeout(function() {
      setUpDropdown('dropTheMenu');
    }, 500);
  });

  /***************************************************************
  * Automatically login the user for the demo... DELETE THIS LATER
  ***************************************************************/

  $scope.$emit('$TRIGGEREVENT','$beforeLogin', $location.path(), $location.search());

}]);
<|endoftext|>


<commit_before>/*
Notes:
'data' is lazily imported from the html
'seedrandom' is also imported from html. it gives deterministic random #s based on a seed set in fire()
*/

var wordsSelected = [];
var teams = [];
var NUMBER_OF_WORDS = 6;
var spyMasterMode = false;
var sessionData = [];
var customData = [];

var COLOR_RED = "#ff0000";
var COLOR_YELLOW = "#ffff00";
var COLOR_BLUE = "#00eeee";
var COLOR_BLACK = "#808080";
var COLOR_GREEN = "#009000";

//init
$("#seed").keyup(function() {
	fire();
});

$("#gameMode").change(function() {
	fire();
});

$("#seed").val(Math.floor(Math.random() * 1000));
fire();

function fire() {
	//get seed and set the seed for randomizer
	var seed = document.getElementById("seed").value;
	Math.seedrandom(seed.toLowerCase());

	var option = $('#gameMode :selected').val();
	switch (option) {
		case '2knouns':
			sessionData = data.slice(0);
			break;
		case 'movies':
			sessionData = movieData.slice(0);
			break;
		case 'custom':
			if (customData.length === 0) {
				var customWordList = prompt("Please enter custom word list. The list will be saved until your refresh your browser. (The words MUST be delimanted by spaces). eg: cat dog mouse", "Enter words here");
				customData = customWordList.split(' ');
			}
			sessionData = customData.slice(0);
			break;
		default:
			sessionData = defaultData.slice(0);
	}

	wordsSelected = [];
	teams = [];
	spyMasterMode = false;
	document.getElementById("board").innerHTML = "";

	//fire new board
	updateScore();
	createNewGame();
}

// Trying to get the new word bank to work

function NewWords() {
	document.getElementById("seed").value = 12344;
	document.getElementById("seed").focus();
	document.getElementById("reset").submit();
	}

/////

//not used, but probably useful at some point
function removeItem(array, index) {
	if (index > -1) {
		// console.log("index: " + index + ", word: " + array[index] + " removed.");
		array.splice(index, 1);
	}
}

function createNewGame() {
	var trs = [];
	for (var i = 0; i < NUMBER_OF_WORDS; i++) {
		if (!trs[i % 6]) {
			trs[i % 6] = "";
		}
		var randomNumber = Math.floor(Math.random() * sessionData.length);
		var word = sessionData[randomNumber];
		removeItem(sessionData, randomNumber);
		wordsSelected.push(word);
		trs[i % 6] += "

" + word + "

";
	}
	//Washington stimulates economic growth Read me
	for (var i = 0; i < trs.length; i++) {
		document.getElementById("board").innerHTML += '
' + trs[i] + '
'
	}

	//create teams
	for (var i = 0; i < 8; i++) {
		teams.push(COLOR_RED);
		teams.push(COLOR_BLUE);
	}

	// one extra for one of the teams
	if (Math.floor(Math.random() * data.length) % 2 === 0) {
		teams.push(COLOR_RED);
		// document.getElementById("team").style.color = COLOR_RED;
		// document.getElementById("team").innerHTML = "RED";
		$('#board').addClass('redStarts').removeClass('blueStarts');

	} else {
		teams.push(COLOR_BLUE);
		// document.getElementById("team").style.color = COLOR_BLUE;
		// document.getElementById("team").innerHTML = "BLUE";
		$('#board').addClass('blueStarts').removeClass('redStarts');
	}

	// add neturals
	for (var i = 0; i < 7; i++) {
		teams.push(COLOR_YELLOW);
	}

	// push the assasin
	teams.push(COLOR_BLACK)

	//shuffle teams
	shuffle(teams);

	updateScore();
}

function clicked(value) {
	if (spyMasterMode) {
		//spymaster mode
		document.getElementById(value).style.backgroundColor = COLOR_GREEN;
	} else {
		//guessers mode
		var word = wordsSelected[value];
		if (document.getElementById("confirm").checked) {
			if (window.confirm("Are sure you want to select '" + word + "'?")) {
				document.getElementById(value).style.backgroundColor = teams[value];
				if (teams[value] == "black") {
					document.getElementById(value).style.color = "white";
				}
			}
		} else {
			document.getElementById(value).style.backgroundColor = teams[value];
			if (teams[value] == "black") {
				document.getElementById(value).style.color = "white";
			}
		}
	}
	updateScore();
}

function updateScore() {
	var blueScore = 9;
	var redScore = 9;
	if (spyMasterMode) {
		blueScore = 0;
		redScore = 0;
		$('div.word').each(function() {
			var color = $(this).css('background-color');
			if (color === 'rgb(0, 238, 238)') {
				blueScore++;
			}
			if (color === 'rgb(255, 0, 0)') {
				redScore++;
			}
		});
	} else {
		$('div.word').each(function() {
			var color = $(this).css('background-color');
			if (color === 'rgb(0, 238, 238)') {
				blueScore--;
			}
			if (color === 'rgb(255, 0, 0)') {
				redScore--;
			}
		});

		if ($('.redStarts').length === 1) {
			blueScore--;
		} else {
			redScore--;
		}
	}
	$('#redScore').text(redScore);
	$('#blueScore').text(blueScore);
	if(redScore === 0){
		$('#redScore').text('Winner!');
	}
	if(blueScore === 0){
		$('#blueScore').text('Winner!');
	}
}

function spyMaster() {
	//TODO: randomize or organize tiles for easier comparing
	spyMasterMode = true;
	for (var i = 0; i < NUMBER_OF_WORDS; i++) {
		document.getElementById(i).style.backgroundColor = teams[i];
		if (teams[i] == "black") {
			document.getElementById(i).style.color = "white";
		}
	}
}

function shuffle(array) {
	var currentIndex = array.length,
		temporaryValue, randomIndex;

	// While there remain elements to shuffle...
	while (0 !== currentIndex) {

		// Pick a remaining element...
		randomIndex = Math.floor(Math.random() * currentIndex);
		currentIndex -= 1;

		// And swap it with the current element.
		temporaryValue = array[currentIndex];
		array[currentIndex] = array[randomIndex];
		array[randomIndex] = temporaryValue;
	}

	return array;
}

//enable pressing 'Enter' on seed field
document.getElementById('seed').onkeypress = function(e) {
	if (!e) e = window.event;
	var keyCode = e.keyCode || e.which;
	if (keyCode == '13') {
		// Enter pressed
		fire();
		return false;
	}
}
<commit_msg>Update index.js<commit_after>/*
Notes:
'data' is lazily imported from the html
'seedrandom' is also imported from html. it gives deterministic random #s based on a seed set in fire()
*/

var wordsSelected = [];
var teams = [];
var NUMBER_OF_WORDS = 6;
var spyMasterMode = false;
var sessionData = [];
var customData = [];

var COLOR_RED = "#ff0000";
var COLOR_YELLOW = "#ffff00";
var COLOR_BLUE = "#00eeee";
var COLOR_BLACK = "#808080";
var COLOR_GREEN = "#009000";

//init
$("#seed").keyup(function() {
	fire();
});

$("#gameMode").change(function() {
	fire();
});

$("#seed").val(Math.floor(Math.random() * 1000));
fire();

function fire() {
	//get seed and set the seed for randomizer
	var seed = document.getElementById("seed").value;
	Math.seedrandom(seed.toLowerCase());

	var option = $('#gameMode :selected').val();
	switch (option) {
		case '2knouns':
			sessionData = data.slice(0);
			break;
		case 'movies':
			sessionData = movieData.slice(0);
			break;
		case 'custom':
			if (customData.length === 0) {
				var customWordList = prompt("Please enter custom word list. The list will be saved until your refresh your browser. (The words MUST be delimanted by spaces). eg: cat dog mouse", "Enter words here");
				customData = customWordList.split(' ');
			}
			sessionData = customData.slice(0);
			break;
		default:
			sessionData = defaultData.slice(0);
	}

	wordsSelected = [];
	teams = [];
	spyMasterMode = false;
	document.getElementById("board").innerHTML = "";

	//fire new board
	updateScore();
	createNewGame();
}

// Trying to get the new word bank to work

function NewWords() {
	document.getElementById("seed").value = 12344;
//	document.getElementById("seed").focus();
	document.getElementById("reset").submit();
	}

/////

//not used, but probably useful at some point
function removeItem(array, index) {
	if (index > -1) {
		// console.log("index: " + index + ", word: " + array[index] + " removed.");
		array.splice(index, 1);
	}
}

function createNewGame() {
	var trs = [];
	for (var i = 0; i < NUMBER_OF_WORDS; i++) {
		if (!trs[i % 6]) {
			trs[i % 6] = "";
		}
		var randomNumber = Math.floor(Math.random() * sessionData.length);
		var word = sessionData[randomNumber];
		removeItem(sessionData, randomNumber);
		wordsSelected.push(word);
		trs[i % 6] += "

" + word + "

";
	}
	//Washington stimulates economic growth Read me
	for (var i = 0; i < trs.length; i++) {
		document.getElementById("board").innerHTML += '
' + trs[i] + '
'
	}

	//create teams
	for (var i = 0; i < 8; i++) {
		teams.push(COLOR_RED);
		teams.push(COLOR_BLUE);
	}

	// one extra for one of the teams
	if (Math.floor(Math.random() * data.length) % 2 === 0) {
		teams.push(COLOR_RED);
		// document.getElementById("team").style.color = COLOR_RED;
		// document.getElementById("team").innerHTML = "RED";
		$('#board').addClass('redStarts').removeClass('blueStarts');

	} else {
		teams.push(COLOR_BLUE);
		// document.getElementById("team").style.color = COLOR_BLUE;
		// document.getElementById("team").innerHTML = "BLUE";
		$('#board').addClass('blueStarts').removeClass('redStarts');
	}

	// add neturals
	for (var i = 0; i < 7; i++) {
		teams.push(COLOR_YELLOW);
	}

	// push the assasin
	teams.push(COLOR_BLACK)

	//shuffle teams
	shuffle(teams);

	updateScore();
}

function clicked(value) {
	if (spyMasterMode) {
		//spymaster mode
		document.getElementById(value).style.backgroundColor = COLOR_GREEN;
	} else {
		//guessers mode
		var word = wordsSelected[value];
		if (document.getElementById("confirm").checked) {
			if (window.confirm("Are sure you want to select '" + word + "'?")) {
				document.getElementById(value).style.backgroundColor = teams[value];
				if (teams[value] == "black") {
					document.getElementById(value).style.color = "white";
				}
			}
		} else {
			document.getElementById(value).style.backgroundColor = teams[value];
			if (teams[value] == "black") {
				document.getElementById(value).style.color = "white";
			}
		}
	}
	updateScore();
}

function updateScore() {
	var blueScore = 9;
	var redScore = 9;
	if (spyMasterMode) {
		blueScore = 0;
		redScore = 0;
		$('div.word').each(function() {
			var color = $(this).css('background-color');
			if (color === 'rgb(0, 238, 238)') {
				blueScore++;
			}
			if (color === 'rgb(255, 0, 0)') {
				redScore++;
			}
		});
	} else {
		$('div.word').each(function() {
			var color = $(this).css('background-color');
			if (color === 'rgb(0, 238, 238)') {
				blueScore--;
			}
			if (color === 'rgb(255, 0, 0)') {
				redScore--;
			}
		});

		if ($('.redStarts').length === 1) {
			blueScore--;
		} else {
			redScore--;
		}
	}
	$('#redScore').text(redScore);
	$('#blueScore').text(blueScore);
	if(redScore === 0){
		$('#redScore').text('Winner!');
	}
	if(blueScore === 0){
		$('#blueScore').text('Winner!');
	}
}

function spyMaster() {
	//TODO: randomize or organize tiles for easier comparing
	spyMasterMode = true;
	for (var i = 0; i < NUMBER_OF_WORDS; i++) {
		document.getElementById(i).style.backgroundColor = teams[i];
		if (teams[i] == "black") {
			document.getElementById(i).style.color = "white";
		}
	}
}

function shuffle(array) {
	var currentIndex = array.length,
		temporaryValue, randomIndex;

	// While there remain elements to shuffle...
	while (0 !== currentIndex) {

		// Pick a remaining element...
		randomIndex = Math.floor(Math.random() * currentIndex);
		currentIndex -= 1;

		// And swap it with the current element.
		temporaryValue = array[currentIndex];
		array[currentIndex] = array[randomIndex];
		array[randomIndex] = temporaryValue;
	}

	return array;
}

//enable pressing 'Enter' on seed field
document.getElementById('seed').onkeypress = function(e) {
	if (!e) e = window.event;
	var keyCode = e.keyCode || e.which;
	if (keyCode == '13') {
		// Enter pressed
		fire();
		return false;
	}
}
<|endoftext|>


<commit_before>(function () {
  var _ = function (element, o) {
    var me = this;

    if (typeof element === 'string' && $$(element).length > 1) {
      var object = [];
      $$(element).forEach(function (element) {
        object.push(new _(element, o));
      });
      return object;
    }

    // Setup.
    me.element = $(element);
    me.options = {};

    // Return an empty object if the element does not exist.
    if (!me.element) {
      return {};
    }

    o = o || {};

    // @TODO: remove unused class names?!
    configure(me, {
      disableHistory: false,
      classNames: {
        main: 'perfundo',
        link: 'perfundo__link',
        overlay: 'perfundo__overlay',
        content: 'perfundo__content',
        html: 'perfundo__html',
        figcaption: 'perfundo__figcaption',
        control: 'perfundo__control',
        close: 'perfundo__close',
        prev: 'perfundo__prev',
        next: 'perfundo__next',
        untarget: 'perfundo__untarget',
        active: 'is-active'
      }
    }, o);

    // Add ".is-active" functionality.
    var style = $('style', me.element);
    if (style) {
      var isActiveStyle = style.cloneNode(true);
      isActiveStyle.innerHTML = isActiveStyle.innerHTML.replace(
        /:target/gi,
        '.' + me.options.classNames.active
      );
      me.element.insertBefore(isActiveStyle, style);
    }

    $.bind($$('.' + me.options.classNames.link, me.element), {
      'click': function (e) {
        var overlay = $(this.getAttribute('href'));
        if (me.options.disableHistory) {
          e.preventDefault();
        }
        me.closeOverlay();
        overlay.classList.add(me.options.classNames.active); // @TODO: use openOverlay prototype
      }
    });

    $.bind($$('.' + me.options.classNames.close, me.element), {
      'click': function (e) {
        if (me.options.disableHistory) {
          e.preventDefault();
        }
        me.closeOverlay();
      }
    });

    // $.bind($$('.' + me.options.classNames.link, me.element), {
    //   'focus': function (e) {
    //     var trigger = e.target;
    //     var subMenu = trigger.nextElementSibling;
    //     // Close open sub menus that are not part of the triggered menu tree.
    //     var openSubMenus = $$('.' + me.options.classNames.open, me.element);
    //     openSubMenus.forEach(function (openSubMenu) {
    //       if (!isDescendant(openSubMenu, trigger)) {
    //         me.closeSubMenu(openSubMenu);
    //       }
    //     });
    //     // Open the sub menu.
    //     if (me.options.focusopen == 'enabled' && subMenu && subMenu.classList.contains(me.options.classNames.sub)) {
    //       me.openSubMenu(subMenu);
    //     }
    //   },
    //   'blur': function (e) {
    //     // Close all open sub menus if the menu loses focus.
    //     setTimeout(function() {
    //       var trigger = document.activeElement;
    //       if (!isDescendant(me.element, trigger)) {
    //         var openSubMenus = $$('.' + me.options.classNames.open, me.element);
    //         openSubMenus.forEach(function (openSubMenu) {
    //           me.closeSubMenu(openSubMenu);
    //         });
    //       }
    //     }, 1);
    //   }
    // });

    // if (me.options.spaceopen == 'enabled') {
    //   $.bind($$('.' + me.options.classNames.link, me.element), {
    //     'keydown': function (e) {
    //       if (e.keyCode == 32) {
    //         var trigger = e.target;
    //         var subMenu = trigger.nextElementSibling;

    //         if (subMenu && subMenu.classList.contains(me.options.classNames.sub)) {
    //           e.preventDefault();
    //           me.toggleSubMenu(subMenu);
    //         }
    //       }
    //     }
    //   });
    // }

    // if (me.options.clickopen == 'enabled') {
    //   $$('.' + me.options.classNames.sub, me.element).forEach(function (subMenu) {
    //     subMenu.classList.add(me.options.classNames.nohover)
    //   });
    //   $.bind($$('.' + me.options.classNames.link, me.element), {
    //     'click': function (e) {
    //       var subMenu = e.target.nextElementSibling;

    //       if (subMenu && subMenu.classList.contains(me.options.classNames.sub)) {
    //         e.preventDefault();
    //         me.openSubMenu(subMenu);
    //       }
    //     }
    //   });
    // }
  };

  _.prototype = {
    closeOverlay: function () {
      var me = this;
      $$('.' + me.options.classNames.overlay + '.' + me.options.classNames.active, me.element).forEach(function (overlay) {
        overlay.classList.remove(me.options.classNames.active);
      });
    }
    // openSubMenu: function (subMenu) {
    //   subMenu = $(subMenu, this.element);
    //   // Add open class and aria rule to the sub menu.
    //   subMenu.previousElementSibling.setAttribute('aria-expanded', true);
    //   subMenu.classList.add(this.options.classNames.open);
    // },
    // closeSubMenu: function (subMenu) {
    //   subMenu = $(subMenu, this.element);
    //   // Remove open class and aria rule from not targeted sub menus.
    //   subMenu.previousElementSibling.setAttribute('aria-expanded', false);
    //   subMenu.classList.remove(this.options.classNames.open);
    // },
    // toggleSubMenu: function (subMenu) {
    //   subMenu = $(subMenu, this.element);
    //   if (subMenu.classList.contains(this.options.classNames.open)) {
    //     this.closeSubMenu(subMenu);
    //   }
    //   else {
    //     this.openSubMenu(subMenu);
    //   }
    // }
  };

  // Private functions.
  function configure(instance, properties, o) {
    for (var i in properties) {
      var initial = properties[i];
      var attrValue = instance.element.getAttribute('data-' + i.toLowerCase());

      if (typeof initial === 'number') {
        instance.options[i] = parseInt(attrValue);
      }
      else if (initial === false) {
        instance.options[i] = attrValue !== null;
      }
      else if (initial instanceof Function) {
        instance.options[i] = null;
      }
      else {
        instance.options[i] = attrValue;
      }

      if (!instance.options[i] && instance.options[i] !== 0) {
        instance.options[i] = (i in o) ? o[i] : initial;
      }
    }
  }

  // Helpers.
  var slice = Array.prototype.slice;

  function $(expr, con) {
    return typeof expr === 'string' ? (con || document).querySelector(expr) : expr || null;
  }

  function $$(expr, con) {
    return slice.call((con || document).querySelectorAll(expr));
  }

  // function isDescendant(parent, child) {
  //   var node = child.parentNode;
  //   while (node != null) {
  //     if (node == parent) {
  //       return true;
  //     }
  //     node = node.parentNode;
  //   }
  //   return false;
  // }

  $.bind = function(elements, o) {
    if (elements) {
      elements = elements.length ? elements : [elements];
      elements.forEach(function (element) {
        for (var event in o) {
          var callback = o[event];
          event.split(/\s+/).forEach(function (event) {
            element.addEventListener(event, callback);
          });
        }
      });
    }
  };

  _.$ = $;
  _.$$ = $$;

  // Make sure to export perfundo on self when in a browser.
  if (typeof self !== 'undefined') {
    self.perfundo = _;
  }

  // Expose componentNav as a CJS module.
  if (typeof module === 'object' && module.exports) {
    module.exports = _;
  }

  return _;
}());
<commit_msg>add a "openOverlay" prototype function<commit_after>(function () {
  var _ = function (element, o) {
    var me = this;

    if (typeof element === 'string' && $$(element).length > 1) {
      var object = [];
      $$(element).forEach(function (element) {
        object.push(new _(element, o));
      });
      return object;
    }

    // Setup.
    me.element = $(element);
    me.options = {};

    // Return an empty object if the element does not exist.
    if (!me.element) {
      return {};
    }

    o = o || {};

    // @TODO: remove unused class names?!
    configure(me, {
      disableHistory: false,
      classNames: {
        main: 'perfundo',
        link: 'perfundo__link',
        overlay: 'perfundo__overlay',
        content: 'perfundo__content',
        html: 'perfundo__html',
        figcaption: 'perfundo__figcaption',
        control: 'perfundo__control',
        close: 'perfundo__close',
        prev: 'perfundo__prev',
        next: 'perfundo__next',
        untarget: 'perfundo__untarget',
        active: 'is-active'
      }
    }, o);

    // Add ".is-active" functionality.
    var style = $('style', me.element);
    if (style) {
      var isActiveStyle = style.cloneNode(true);
      isActiveStyle.innerHTML = isActiveStyle.innerHTML.replace(
        /:target/gi,
        '.' + me.options.classNames.active
      );
      me.element.insertBefore(isActiveStyle, style);
    }

    $.bind($$('.' + me.options.classNames.link, me.element), {
      'click': function (e) {
        if (me.options.disableHistory) {
          e.preventDefault();
        }
        me.openOverlay(this.getAttribute('href'));
      }
    });

    $.bind($$('.' + me.options.classNames.close, me.element), {
      'click': function (e) {
        if (me.options.disableHistory) {
          e.preventDefault();
        }
        me.closeOverlay();
      }
    });

    // $.bind($$('.' + me.options.classNames.link, me.element), {
    //   'focus': function (e) {
    //     var trigger = e.target;
    //     var subMenu = trigger.nextElementSibling;
    //     // Close open sub menus that are not part of the triggered menu tree.
    //     var openSubMenus = $$('.' + me.options.classNames.open, me.element);
    //     openSubMenus.forEach(function (openSubMenu) {
    //       if (!isDescendant(openSubMenu, trigger)) {
    //         me.closeSubMenu(openSubMenu);
    //       }
    //     });
    //     // Open the sub menu.
    //     if (me.options.focusopen == 'enabled' && subMenu && subMenu.classList.contains(me.options.classNames.sub)) {
    //       me.openSubMenu(subMenu);
    //     }
    //   },
    //   'blur': function (e) {
    //     // Close all open sub menus if the menu loses focus.
    //     setTimeout(function() {
    //       var trigger = document.activeElement;
    //       if (!isDescendant(me.element, trigger)) {
    //         var openSubMenus = $$('.' + me.options.classNames.open, me.element);
    //         openSubMenus.forEach(function (openSubMenu) {
    //           me.closeSubMenu(openSubMenu);
    //         });
    //       }
    //     }, 1);
    //   }
    // });

    // if (me.options.spaceopen == 'enabled') {
    //   $.bind($$('.' + me.options.classNames.link, me.element), {
    //     'keydown': function (e) {
    //       if (e.keyCode == 32) {
    //         var trigger = e.target;
    //         var subMenu = trigger.nextElementSibling;

    //         if (subMenu && subMenu.classList.contains(me.options.classNames.sub)) {
    //           e.preventDefault();
    //           me.toggleSubMenu(subMenu);
    //         }
    //       }
    //     }
    //   });
    // }

    // if (me.options.clickopen == 'enabled') {
    //   $$('.' + me.options.classNames.sub, me.element).forEach(function (subMenu) {
    //     subMenu.classList.add(me.options.classNames.nohover)
    //   });
    //   $.bind($$('.' + me.options.classNames.link, me.element), {
    //     'click': function (e) {
    //       var subMenu = e.target.nextElementSibling;

    //       if (subMenu && subMenu.classList.contains(me.options.classNames.sub)) {
    //         e.preventDefault();
    //         me.openSubMenu(subMenu);
    //       }
    //     }
    //   });
    // }
  };

  _.prototype = {
    openOverlay: function (overlay) {
      var me = this;
      var overlay = $(overlay);
      me.closeOverlay();
      overlay.classList.add(me.options.classNames.active); // @TODO: use openOverlay prototype
    },
    closeOverlay: function () {
      var me = this;
      $$('.' + me.options.classNames.overlay + '.' + me.options.classNames.active, me.element).forEach(function (overlay) {
        overlay.classList.remove(me.options.classNames.active);
      });
    }
    // openSubMenu: function (subMenu) {
    //   subMenu = $(subMenu, this.element);
    //   // Add open class and aria rule to the sub menu.
    //   subMenu.previousElementSibling.setAttribute('aria-expanded', true);
    //   subMenu.classList.add(this.options.classNames.open);
    // },
    // closeSubMenu: function (subMenu) {
    //   subMenu = $(subMenu, this.element);
    //   // Remove open class and aria rule from not targeted sub menus.
    //   subMenu.previousElementSibling.setAttribute('aria-expanded', false);
    //   subMenu.classList.remove(this.options.classNames.open);
    // },
    // toggleSubMenu: function (subMenu) {
    //   subMenu = $(subMenu, this.element);
    //   if (subMenu.classList.contains(this.options.classNames.open)) {
    //     this.closeSubMenu(subMenu);
    //   }
    //   else {
    //     this.openSubMenu(subMenu);
    //   }
    // }
  };

  // Private functions.
  function configure(instance, properties, o) {
    for (var i in properties) {
      var initial = properties[i];
      var attrValue = instance.element.getAttribute('data-' + i.toLowerCase());

      if (typeof initial === 'number') {
        instance.options[i] = parseInt(attrValue);
      }
      else if (initial === false) {
        instance.options[i] = attrValue !== null;
      }
      else if (initial instanceof Function) {
        instance.options[i] = null;
      }
      else {
        instance.options[i] = attrValue;
      }

      if (!instance.options[i] && instance.options[i] !== 0) {
        instance.options[i] = (i in o) ? o[i] : initial;
      }
    }
  }

  // Helpers.
  var slice = Array.prototype.slice;

  function $(expr, con) {
    return typeof expr === 'string' ? (con || document).querySelector(expr) : expr || null;
  }

  function $$(expr, con) {
    return slice.call((con || document).querySelectorAll(expr));
  }

  // function isDescendant(parent, child) {
  //   var node = child.parentNode;
  //   while (node != null) {
  //     if (node == parent) {
  //       return true;
  //     }
  //     node = node.parentNode;
  //   }
  //   return false;
  // }

  $.bind = function(elements, o) {
    if (elements) {
      elements = elements.length ? elements : [elements];
      elements.forEach(function (element) {
        for (var event in o) {
          var callback = o[event];
          event.split(/\s+/).forEach(function (event) {
            element.addEventListener(event, callback);
          });
        }
      });
    }
  };

  _.$ = $;
  _.$$ = $$;

  // Make sure to export perfundo on self when in a browser.
  if (typeof self !== 'undefined') {
    self.perfundo = _;
  }

  // Expose componentNav as a CJS module.
  if (typeof module === 'object' && module.exports) {
    module.exports = _;
  }

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


<commit_before>var map;

// Utility features for the map
// This is the center of Tennessee
var latlng = {lat: 35.5046, lng: -86.2331};
var zoom = 7;
var mapTypeId = 'hybrid';
var API_CALL_LIMIT = 60;

function initMap() {
  map = new google.maps.Map(document.getElementById('map'), {
    zoom: zoom,
    center: new google.maps.LatLng(latlng['lat'], latlng['lng']),
    mapTypeId: mapTypeId
  });

  // Get JSON Data from scraped web data on github for Tennessee.
  var requestDataURL = 'https://raw.githubusercontent.com/Rhendz/TWeather/master/data/use_this_data.json';
  var cityData = {};
  var weatherData = {};
  getJSONData(requestDataURL, function(data) {
    cityData = data;

    // Get JSON Data from OpenWeatherAPI for Tennessee.
    var requestWeatherURL = 'http://api.openweathermap.org/data/2.5/&APPID=f9a99216f25450f101c2194df8e56eb0';
    getJSONData(requestWeatherURL, function(data) {
      weatherData = data;
      // Need to add population based weather calling because of API_CALL_LIMIT / zooming
    });
  });

}

// Loads in JSON Data from OpenWeatherAPI and Github
function xhrSuccess() {
  console.log("JSON File retrieval success!");
  this.callback(this.response);
}

function xhrError() {
  console.log("JSON File retrieval failed!");
  console.error(this.statusText);
}

function loadJSONFile(requestURL, fCallback) {
  var req = new XMLHttpRequest();
  req.callback = fCallback;
  req.onload = xhrSuccess;
  req.onerror = xhrError;
  req.responseType = 'json';
  req.open('get', requestURL, true);
  req.send(null);
}

function getJSONData(requestURL, fCallback) {
  loadJSONFile(requestURL, function(jsonObj) {
    fCallback(jsonObj);
  });
}

function addMarker(jsonObj) {
  // Adds a city name for each city position
  for (var i = 0; i < jsonObj.cities.length; i++) {
    var cityName = jsonObj.cities[i].cityName;

    var coords = jsonObj.cities[i].coords;
    var latlng = new google.maps.LatLng(coords.lat, coords.lng);

    var marker = new google.maps.Marker({
      position: latlng,
      title: cityName,
      map: map
    });
    console.log("Marker for " + cityName + " has been added!");
  }
}
<commit_msg>Working Map!<commit_after>var map;

// Settings for the map
// This is the center of Tennessee
var latlng = {
  lat: 35.5046,
  lng: -86.2331
};
var zoom = 8;
var mapTypeId = 'terrain';
var API_CALL_LIMIT = 60;
var BASE_MAP_LOCATIONS = 50;
var ADD_MAP_LOCATIONS = 5;

function initMap() {
  map = new google.maps.Map(document.getElementById('map'), {
    zoom: zoom,
    center: new google.maps.LatLng(latlng['lat'], latlng['lng']),
    mapTypeId: mapTypeId
  });

  // Get JSON Data from scraped web data on github for Tennessee.
  var requestDataURL = 'https://raw.githubusercontent.com/Rhendz/TWeather/master/data/use_this_data.json';
  var cityData = {};
  var weatherData = {};
  getJSONData(requestDataURL, function(data) {
    cityData = data;

    // Population based weather calling because of API_CALL_LIMIT
    cityDataLength = Object.keys(cityData).length;

    dataByPopulation = getByPopulation(data);

    for (i = 0; i < BASE_MAP_LOCATIONS; i++) {
      cityName = Object.keys(dataByPopulation)[i];
      coords = dataByPopulation[cityName].coords;
      var requestWeatherURL = 'http://api.openweathermap.org/data/2.5/weather' + '?lat=' + coords.lat + '&lon=' + coords.lng + '&APPID=f9a99216f25450f101c2194df8e56eb0';

      // Because getJSONData() is an async function,
      // it will not operate along with the for loop;
      // therefore, the cityName for each iteration
      // must be preserved by changing the scope.

      // getJSONData() will hold onto the cityName
      // even after the execution of re_scope()
      // has been completed. This is called closure.
      ! function re_scope(markerCityName) {
        getJSONData(requestWeatherURL, function(data) {
          weatherData = data;
          addMarker(weatherData, markerCityName);
        });
      }(cityName)
    }

  });
}

function getByPopulation(data) {
  var dataByPopulation = {};
  var tempPop = parseInt(data[Object.keys(data)[0]].population);

  // data key val of large city pop.
  var dataVal = 0;

  for (i = 0; i < BASE_MAP_LOCATIONS; i++) {
    for (j = 0; j < Object.keys(data).length; j++) {
      data_pop = parseInt(data[Object.keys(data)[j]].population);
      if (tempPop < data_pop) {
        tempPop = data_pop;
        dataVal = j;
      }
    }
    // Add population based city
    dataByPopulation[Object.keys(data)[dataVal]] = data[Object.keys(data)[dataVal]];

    tempPop = parseInt(data[Object.keys(data)[0]].population);
    delete data[Object.keys(data)[dataVal]];
  }
  return dataByPopulation;
}

// Loads in JSON Data from OpenWeatherAPI and Github
function xhrSuccess() {
  // console.log("JSON File retrieval success!");
  this.callback(this.response);
}

function xhrError() {
  console.log("JSON File retrieval failed!");
  console.error(this.statusText);
}

function loadJSONFile(requestURL, fCallback) {
  var req = new XMLHttpRequest();
  req.callback = fCallback;
  req.onload = xhrSuccess;
  req.onerror = xhrError;
  req.responseType = 'json';
  req.open('get', requestURL, true);
  req.send(null);
}

function getJSONData(requestURL, fCallback) {
  loadJSONFile(requestURL, function(jsonObj) {
    fCallback(jsonObj);
  });
}

function addMarker(jsonObj, cityName) {

  var latlng = {
    lat: jsonObj.coord.lat,
    lng: jsonObj.coord.lon
  };

  var image = {
    url: 'http://openweathermap.org/img/w/' + jsonObj.weather[0].icon + '.png',
    size: new google.maps.Size(125, 125),
    origin: new google.maps.Point(0, 0),
    anchor: new google.maps.Point(0, 32)
  };

  var marker = new google.maps.Marker({
    icon: image,
    position: latlng,
    title: cityName,
    map: map
  });
  marker.addListener('click', function() {
    map.setCenter(marker.getPosition());
    map.setZoom(11);
  });
  // console.log("Marker for " + cityName + " has been added!");
}
<|endoftext|>