<commit_before>var modal = "";
var ulElement = "";
var selElement = "";
var videoModal = "";
var player = "";
var autoSwitchEpisode = false;
var isFullscreen = 1;

document.addEventListener("fullscreenchange", FShandler);
document.addEventListener("webkitfullscreenchange", FShandler);
document.addEventListener("mozfullscreenchange", FShandler);
document.addEventListener("MSFullscreenChange", FShandler);
document.addEventListener("keydown", function (e) {
	e.preventDefault();
	e.stopPropagation();
    if (e.keyCode === 70) {
        if (isFullscreen % 2 === 0) {
            if (document.exitFullscreen) {
                document.exitFullscreen();
            } else if (document.webkitExitFullscreen) {
                document.webkitExitFullscreen();
            } else if (document.mozCancelFullScreen) {
                document.mozCancelFullScreen();
            } else if (document.msExitFullscreen) {
                document.msExitFullscreen();
            }
        } else {
            if (player.requestFullscreen) {
                player.requestFullscreen();
            } else if (player.msRequestFullscreen) {
                player.msRequestFullscreen();
            } else if (player.mozRequestFullScreen) {
                player.mozRequestFullScreen();
            } else if (player.webkitRequestFullscreen) {
                player.webkitRequestFullscreen();
            }
        }
    } else if (e.keyCode === 37) {
        player.currentTime -= 5;
    } else if (e.keyCode === 39) {
        player.currentTime += 5;
    } else if (e.keyCode === 32) {
        if(player.paused){
        	player.play();
    	} else {
        	player.pause();
    	}
    }
}, false);

function FShandler() {
    isFullscreen++;
}

function changeSeason(elem) {
    ulElement.style.display = "none";
    var e = document.getElementById(elem.id);
    var myVal = e.options[e.selectedIndex].value;
    var tempStr = elem.id.replace("selector", "C");
    tempStr = tempStr.split("C").pop();
    tempStr = "C" + tempStr + String(myVal);
    ulElement = document.getElementById(String(tempStr));
    ulElement.style.display = "block";
}

function showModal(elem) {
    var tempStr = elem.id;
    tempStr = tempStr.replace("A", "B");
    modal = document.getElementById(String(tempStr));
    tempStr = tempStr.replace("B", "selector");
    selElement = document.getElementById(String(tempStr) + String("_"));
    var myVal = selElement.value;
    tempStr = tempStr.replace("selector", "C");
    tempStr = tempStr.split("C").pop();
    tempStr = "C" + tempStr + "_" + String(myVal);
    ulElement = document.getElementById(String(tempStr));
    modal.style.display = "block";
    ulElement.style.display = "block";
}

function showVideoModal(elem) {
    var tempStr = elem.id;
    tempStr = tempStr.replace("D", "E");
    videoModal = document.getElementById(String(tempStr));
    tempStr = tempStr.replace("E", "F");
    player = document.getElementById(String(tempStr));
    videoModal.style.display = "block";
}

function showVideoModalsetSubs(elem, srcStr) {
    var tempStr = elem.id;
    tempStr = tempStr.replace("D", "E");
    videoModal = document.getElementById(String(tempStr));
    tempStr = tempStr.replace("E", "F");
    player = document.getElementById(String(tempStr));
    videoModal.style.display = "block";
    var subNum = parseInt(player.childElementCount) - 1;
    var array = srcStr.split(',');
    for (var i = 1, j = 0; i <= subNum; i++, j++) {
        player.children[i].src = array[j];
    }
}

function hideModal() {
    modal.style.display = "none";
    ulElement.style.display = "none";
}

function hideVideoModal() {
    videoModal.style.display = "none";
    player.pause();
    player = "";
}

function setAlt(elem, altStr) {
    var me = document.getElementById(elem.id);
    me.alt = altStr;
    me.style.display = "inline";
}

function resetPlayer(){
    var myTime = player.currentTime;
	var mySrc = player.children[0].src;
	player.children[0].src="";
    player.load();
	player.children[0].src=mySrc;
    player.currentTime = myTime;
	player.load();
    player.play();
}

function prevEp() {
    var index = videoModal.id.indexOf("_");
    var myID = videoModal.id.substr(0, index + 1);
    var currentNum = parseInt(videoModal.id.substr(index + 1));
    if (currentNum !== 0) {
        videoModal.style.display = "none";
        player.pause();
        player = "";
        currentNum -= 1;
        tempStr = String(myID) + String(currentNum);
        videoModal = document.getElementById(tempStr);
        videoModal.style.display = "block";
        if (isDescendant(ulElement, videoModal) === false && selElement.value !== 1) {
            selElement.selectedIndex = parseInt(parseInt(selElement.value) - 2);
            changeSeason(selElement);
        }
        tempStr = tempStr.replace("E", "F");
        player = document.getElementById(String(tempStr));
        player.play();
    }
}

function nextEp() {
    var index = videoModal.id.indexOf("_");
    var myID = videoModal.id.substr(0, index + 1);
    var currentNum = parseInt(videoModal.id.substr(index + 1));
    currentNum += 1;
    var tempStr = String(myID) + String(currentNum);
	tempStr = tempStr.replace("E", "D");
	var btnElem = document.getElementById(tempStr);
	oldVolume = player.volume;
    if (document.getElementById(tempStr) !== null) {
		hideVideoModal();
		btnElem.click();
        if (isDescendant(ulElement, videoModal) === false) {
            selElement.selectedIndex = parseInt(parseInt(selElement.value));
            changeSeason(selElement);
        }
        if (autoSwitchEpisode === true) {
            player.addEventListener('ended', nextEp);
        }
        if (isFullscreen % 2 === 0) {
            if (document.exitFullscreen) {
                document.exitFullscreen();
            } else if (document.webkitExitFullscreen) {
                document.webkitExitFullscreen();
            } else if (document.mozCancelFullScreen) {
                document.mozCancelFullScreen();
            } else if (document.msExitFullscreen) {
                document.msExitFullscreen();
            }
        }
        player.volume = oldVolume;
        player.play();
    }
}

function autoSwitch() {
    if (autoSwitchEpisode === false) {
        autoSwitchEpisode = true;
        var e = document.getElementsByClassName("autoButton");
        player.addEventListener('ended', nextEp);
        for (var i = 0; i < e.length; i++) {
            e[i].checked = true;
        }
    } else {
        autoSwitchEpisode = false;
        player.removeEventListener('ended', nextEp);
        var e = document.getElementsByClassName("autoButton");
        for (var i = 0; i < e.length; i++) {
            e[i].checked = false;
        }
    }
}

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

window.onclick = function (event) {
    if (event.target === modal) {
        modal.style.display = "none";
    }
    if (event.target === videoModal) {
        videoModal.style.display = "none";
        player.pause();
        player = "";
    }
};

function setPadding(){
	document.getElementById("paddingDiv").style.display="block";
	var wrapper = document.getElementById("wrapper");
    var wDiv = wrapper.offsetWidth;
    var tempArr = document.getElementsByClassName("showDiv");
    var temp1 = tempArr[0];
	var temp2 = tempArr[1];
    var style = getComputedStyle(temp1);
	var extraSpace = Math.abs(parseFloat((temp1.offsetLeft + temp1.getBoundingClientRect().width)-temp2.offsetLeft));
    var sDiv = parseFloat(temp1.getBoundingClientRect().width);
	var currentElHeight=parseInt(style.marginTop)+temp1.offsetHeight;
    var rate = Math.floor(wDiv/(sDiv+(extraSpace/2)));
	var numbEl = (wrapper.childElementCount-1)%rate;
	var realRate = Math.floor(rate-numbEl);
	var extraElementW=sDiv*realRate+extraSpace*(realRate-1)+parseFloat(style.marginLeft);
	if (numbEl <= 0){
        extraElementW=0;
        currentElHeight=0;
		document.getElementById("paddingDiv").style.display="none";
    } else {
		document.getElementById("paddingDiv").style.width=extraElementW.toString()+"px";
		document.getElementById("paddingDiv").style.height=currentElHeight.toString()+"px";
	}
}

window.onload=setPadding;
window.onresize=setPadding;
<commit_msg>Update TVcript.js<commit_after>var modal = "";
var ulElement = "";
var selElement = "";
var videoModal = "";
var player = "";
var autoSwitchEpisode = false;
var isFullscreen = 1;

document.addEventListener("fullscreenchange", FShandler);
document.addEventListener("webkitfullscreenchange", FShandler);
document.addEventListener("mozfullscreenchange", FShandler);
document.addEventListener("MSFullscreenChange", FShandler);
document.addEventListener("keydown", function (e) {
if (e.keyCode === 70) {
	e.preventDefault();
	e.stopPropagation();
	if (isFullscreen % 2 === 0) {
            if (document.exitFullscreen) {
                document.exitFullscreen();
            } else if (document.webkitExitFullscreen) {
                document.webkitExitFullscreen();
            } else if (document.mozCancelFullScreen) {
                document.mozCancelFullScreen();
            } else if (document.msExitFullscreen) {
                document.msExitFullscreen();
            }
        } else {
            if (player.requestFullscreen) {
                player.requestFullscreen();
            } else if (player.msRequestFullscreen) {
                player.msRequestFullscreen();
            } else if (player.mozRequestFullScreen) {
                player.mozRequestFullScreen();
            } else if (player.webkitRequestFullscreen) {
                player.webkitRequestFullscreen();
            }
        }
    } else if (e.keyCode === 37) {
	e.preventDefault();
	e.stopPropagation();
        player.currentTime -= 5;
    } else if (e.keyCode === 39) {
	e.preventDefault();
	e.stopPropagation();
        player.currentTime += 5;
    } else if (e.keyCode === 32) {
	e.preventDefault();
	e.stopPropagation();
        if(player.paused){
        	player.play();
    	} else {
        	player.pause();
    	}
    }
}, false);

function FShandler() {
    isFullscreen++;
}

function changeSeason(elem) {
    ulElement.style.display = "none";
    var e = document.getElementById(elem.id);
    var myVal = e.options[e.selectedIndex].value;
    var tempStr = elem.id.replace("selector", "C");
    tempStr = tempStr.split("C").pop();
    tempStr = "C" + tempStr + String(myVal);
    ulElement = document.getElementById(String(tempStr));
    ulElement.style.display = "block";
}

function showModal(elem) {
    var tempStr = elem.id;
    tempStr = tempStr.replace("A", "B");
    modal = document.getElementById(String(tempStr));
    tempStr = tempStr.replace("B", "selector");
    selElement = document.getElementById(String(tempStr) + String("_"));
    var myVal = selElement.value;
    tempStr = tempStr.replace("selector", "C");
    tempStr = tempStr.split("C").pop();
    tempStr = "C" + tempStr + "_" + String(myVal);
    ulElement = document.getElementById(String(tempStr));
    modal.style.display = "block";
    ulElement.style.display = "block";
}

function showVideoModal(elem) {
    var tempStr = elem.id;
    tempStr = tempStr.replace("D", "E");
    videoModal = document.getElementById(String(tempStr));
    tempStr = tempStr.replace("E", "F");
    player = document.getElementById(String(tempStr));
    videoModal.style.display = "block";
}

function showVideoModalsetSubs(elem, srcStr) {
    var tempStr = elem.id;
    tempStr = tempStr.replace("D", "E");
    videoModal = document.getElementById(String(tempStr));
    tempStr = tempStr.replace("E", "F");
    player = document.getElementById(String(tempStr));
    videoModal.style.display = "block";
    var subNum = parseInt(player.childElementCount) - 1;
    var array = srcStr.split(',');
    for (var i = 1, j = 0; i <= subNum; i++, j++) {
        player.children[i].src = array[j];
    }
}

function hideModal() {
    modal.style.display = "none";
    ulElement.style.display = "none";
}

function hideVideoModal() {
    videoModal.style.display = "none";
    player.pause();
    player = "";
}

function setAlt(elem, altStr) {
    var me = document.getElementById(elem.id);
    me.alt = altStr;
    me.style.display = "inline";
}

function resetPlayer(){
    var myTime = player.currentTime;
	var mySrc = player.children[0].src;
	player.children[0].src="";
    player.load();
	player.children[0].src=mySrc;
    player.currentTime = myTime;
	player.load();
    player.play();
}

function prevEp() {
    var index = videoModal.id.indexOf("_");
    var myID = videoModal.id.substr(0, index + 1);
    var currentNum = parseInt(videoModal.id.substr(index + 1));
    if (currentNum !== 0) {
        videoModal.style.display = "none";
        player.pause();
        player = "";
        currentNum -= 1;
        tempStr = String(myID) + String(currentNum);
        videoModal = document.getElementById(tempStr);
        videoModal.style.display = "block";
        if (isDescendant(ulElement, videoModal) === false && selElement.value !== 1) {
            selElement.selectedIndex = parseInt(parseInt(selElement.value) - 2);
            changeSeason(selElement);
        }
        tempStr = tempStr.replace("E", "F");
        player = document.getElementById(String(tempStr));
        player.play();
    }
}

function nextEp() {
    var index = videoModal.id.indexOf("_");
    var myID = videoModal.id.substr(0, index + 1);
    var currentNum = parseInt(videoModal.id.substr(index + 1));
    currentNum += 1;
    var tempStr = String(myID) + String(currentNum);
	tempStr = tempStr.replace("E", "D");
	var btnElem = document.getElementById(tempStr);
	oldVolume = player.volume;
    if (document.getElementById(tempStr) !== null) {
		hideVideoModal();
		btnElem.click();
        if (isDescendant(ulElement, videoModal) === false) {
            selElement.selectedIndex = parseInt(parseInt(selElement.value));
            changeSeason(selElement);
        }
        if (autoSwitchEpisode === true) {
            player.addEventListener('ended', nextEp);
        }
        if (isFullscreen % 2 === 0) {
            if (document.exitFullscreen) {
                document.exitFullscreen();
            } else if (document.webkitExitFullscreen) {
                document.webkitExitFullscreen();
            } else if (document.mozCancelFullScreen) {
                document.mozCancelFullScreen();
            } else if (document.msExitFullscreen) {
                document.msExitFullscreen();
            }
        }
        player.volume = oldVolume;
        player.play();
    }
}

function autoSwitch() {
    if (autoSwitchEpisode === false) {
        autoSwitchEpisode = true;
        var e = document.getElementsByClassName("autoButton");
        player.addEventListener('ended', nextEp);
        for (var i = 0; i < e.length; i++) {
            e[i].checked = true;
        }
    } else {
        autoSwitchEpisode = false;
        player.removeEventListener('ended', nextEp);
        var e = document.getElementsByClassName("autoButton");
        for (var i = 0; i < e.length; i++) {
            e[i].checked = false;
        }
    }
}

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

window.onclick = function (event) {
    if (event.target === modal) {
        modal.style.display = "none";
    }
    if (event.target === videoModal) {
        videoModal.style.display = "none";
        player.pause();
        player = "";
    }
};

function setPadding(){
	document.getElementById("paddingDiv").style.display="block";
	var wrapper = document.getElementById("wrapper");
    var wDiv = wrapper.offsetWidth;
    var tempArr = document.getElementsByClassName("showDiv");
    var temp1 = tempArr[0];
	var temp2 = tempArr[1];
    var style = getComputedStyle(temp1);
	var extraSpace = Math.abs(parseFloat((temp1.offsetLeft + temp1.getBoundingClientRect().width)-temp2.offsetLeft));
    var sDiv = parseFloat(temp1.getBoundingClientRect().width);
	var currentElHeight=parseInt(style.marginTop)+temp1.offsetHeight;
    var rate = Math.floor(wDiv/(sDiv+(extraSpace/2)));
	var numbEl = (wrapper.childElementCount-1)%rate;
	var realRate = Math.floor(rate-numbEl);
	var extraElementW=sDiv*realRate+extraSpace*(realRate-1)+parseFloat(style.marginLeft);
	if (numbEl <= 0){
        extraElementW=0;
        currentElHeight=0;
		document.getElementById("paddingDiv").style.display="none";
    } else {
		document.getElementById("paddingDiv").style.width=extraElementW.toString()+"px";
		document.getElementById("paddingDiv").style.height=currentElHeight.toString()+"px";
	}
}

window.onload=setPadding;
window.onresize=setPadding;
<|endoftext|>


<commit_before>/**
 * Tooltip.js
 * A basic script that applies a mouseover tooltip functionality to all elements of a page that have a data-tooltip attribute
 * Matthias Schuetz, http://matthiasschuetz.com
 *
 * Copyright (C) Matthias Schuetz
 * Free to use under the MIT license
 */

(function (root, factory) {
	if (typeof define === "function" && define.amd) {
		// AMD. Register as an anonymous module.
		define(factory);
	} else if (!root.tooltip) {
		// Browser globals
		root.tooltip = factory(root);
	}
}(this, function() {
	var _options = {
		tooltipId: "tooltip",
		offsetDefault: 15
	};

	var _tooltips = [];
	var _tooltipsTemp = null;

	function _bindTooltips(resetTooltips) {
		if (resetTooltips) {
			_tooltipsTemp = _tooltips.concat();
			_tooltips = [];
		}

		Array.prototype.forEach.call(document.querySelectorAll("[data-tooltip]"), function(elm, idx) {
			var tooltipText = elm.getAttribute("title").trim();
			var options;

			if (resetTooltips && _tooltipsTemp.length && _tooltipsTemp[idx] && _tooltipsTemp[idx].text) {
				if (tooltipText.length === 0) {
					elm.setAttribute("title", _tooltipsTemp[idx].text);
					tooltipText = _tooltipsTemp[idx].text;
				}

				elm.removeEventListener("mousemove", _onElementMouseMove);
				elm.removeEventListener("mouseout", _onElementMouseOut);
				elm.removeEventListener("mouseover", _onElementMouseOver);
			}

			if (tooltipText) {
				elm.setAttribute("title", "");
				elm.setAttribute("data-tooltip-id", idx);
				options = _parseOptions(elm.getAttribute("data-tooltip"));

				_tooltips[idx] = {
					text: tooltipText,
					options: options
				};

				elm.addEventListener("mousemove", _onElementMouseMove);
				elm.addEventListener("mouseout", _onElementMouseOut);
				elm.addEventListener("mouseover", _onElementMouseOver);
			}
		});

		if (resetTooltips) {
			_tooltipsTemp = null;
		}
	}

	function _createTooltip(text, tooltipId) {
		var tooltipElm = document.createElement("div");
		var tooltipText = document.createTextNode(text);
		var options = tooltipId && _tooltips[tooltipId] && _tooltips[tooltipId].options;

		if (options && options["class"]) {
			tooltipElm.setAttribute("class", options["class"]);
		}

		tooltipElm.setAttribute("id", _options.tooltipId);
		tooltipElm.appendChild(tooltipText);

		document.querySelector("body").appendChild(tooltipElm);
	}

	function _getTooltipElm() {
		return document.querySelector("#" + _options.tooltipId);
	}

	function _onElementMouseMove(evt) {
		var tooltipId = this.getAttribute("data-tooltip-id");
		var tooltipElm = _getTooltipElm();
		var options = tooltipId && _tooltips[tooltipId] && _tooltips[tooltipId].options;
		var offset = options && options.offset || _options.offsetDefault;
		var scrollY = window.scrollY || window.pageYOffset;
		var scrollX = window.scrollX || window.pageXOffset;
		var tooltipTop = evt.pageY + offset;
		var tooltipLeft = evt.pageX + offset;

		if (tooltipElm) {
			tooltipTop = (tooltipTop - scrollY + tooltipElm.offsetHeight + 20 >= window.innerHeight ? (tooltipTop - tooltipElm.offsetHeight - 20) : tooltipTop);
			tooltipLeft = (tooltipLeft - scrollX + tooltipElm.offsetWidth + 20 >= window.innerWidth ? (tooltipLeft - tooltipElm.offsetWidth - 20) : tooltipLeft);

			tooltipElm.style.top = tooltipTop + "px";
			tooltipElm.style.left = tooltipLeft + "px";
		}
	}

	function _onElementMouseOut(evt) {
		var tooltipElm = _getTooltipElm();

		if (tooltipElm) {
			document.querySelector("body").removeChild(tooltipElm);
		}
	}

	function _onElementMouseOver(evt) {
		var tooltipId = this.getAttribute("data-tooltip-id");
		var tooltipText = tooltipId && _tooltips[tooltipId] && _tooltips[tooltipId].text;

		if (tooltipText) {
			_createTooltip(tooltipText, tooltipId);
		}
	}

	function _parseOptions(options) {
		var optionsObj;

		if (options.length) {
			try {
				optionsObj = JSON.parse(options.replace(/'/ig, "\""));
			} catch(err) {
				console.log(err);
			}
		}

		return optionsObj;
	}

	function _init() {
		window.addEventListener("load", _bindTooltips);
	}

	_init();

	return {
		setOptions: function(options) {
			for (var option in options) {
				if (_options.hasOwnProperty(option)) {
					_options[option] = options[option];
				}
			}
		},
		refresh: function() {
			_bindTooltips(true);
		}
	};
}));
<commit_msg>Fixed trim issue<commit_after>/**
 * Tooltip.js
 * A basic script that applies a mouseover tooltip functionality to all elements of a page that have a data-tooltip attribute
 * Matthias Schuetz, http://matthiasschuetz.com
 *
 * Copyright (C) Matthias Schuetz
 * Free to use under the MIT license
 */

(function (root, factory) {
	if (typeof define === "function" && define.amd) {
		// AMD. Register as an anonymous module.
		define(factory);
	} else if (!root.tooltip) {
		// Browser globals
		root.tooltip = factory(root);
	}
}(this, function() {
	var _options = {
		tooltipId: "tooltip",
		offsetDefault: 15
	};

	var _tooltips = [];
	var _tooltipsTemp = null;

	function _bindTooltips(resetTooltips) {
		if (resetTooltips) {
			_tooltipsTemp = _tooltips.concat();
			_tooltips = [];
		}

		Array.prototype.forEach.call(document.querySelectorAll("[data-tooltip]"), function(elm, idx) {
			var tooltipText = (elm.getAttribute("title") || "").trim();
			var options;

			if (resetTooltips && _tooltipsTemp.length && _tooltipsTemp[idx] && _tooltipsTemp[idx].text) {
				if (tooltipText.length === 0) {
					elm.setAttribute("title", _tooltipsTemp[idx].text);
					tooltipText = _tooltipsTemp[idx].text;
				}

				elm.removeEventListener("mousemove", _onElementMouseMove);
				elm.removeEventListener("mouseout", _onElementMouseOut);
				elm.removeEventListener("mouseover", _onElementMouseOver);
			}

			if (tooltipText) {
				elm.setAttribute("title", "");
				elm.setAttribute("data-tooltip-id", idx);
				options = _parseOptions(elm.getAttribute("data-tooltip"));

				_tooltips[idx] = {
					text: tooltipText,
					options: options
				};

				elm.addEventListener("mousemove", _onElementMouseMove);
				elm.addEventListener("mouseout", _onElementMouseOut);
				elm.addEventListener("mouseover", _onElementMouseOver);
			}
		});

		if (resetTooltips) {
			_tooltipsTemp = null;
		}
	}

	function _createTooltip(text, tooltipId) {
		var tooltipElm = document.createElement("div");
		var tooltipText = document.createTextNode(text);
		var options = tooltipId && _tooltips[tooltipId] && _tooltips[tooltipId].options;

		if (options && options["class"]) {
			tooltipElm.setAttribute("class", options["class"]);
		}

		tooltipElm.setAttribute("id", _options.tooltipId);
		tooltipElm.appendChild(tooltipText);

		document.querySelector("body").appendChild(tooltipElm);
	}

	function _getTooltipElm() {
		return document.querySelector("#" + _options.tooltipId);
	}

	function _onElementMouseMove(evt) {
		var tooltipId = this.getAttribute("data-tooltip-id");
		var tooltipElm = _getTooltipElm();
		var options = tooltipId && _tooltips[tooltipId] && _tooltips[tooltipId].options;
		var offset = options && options.offset || _options.offsetDefault;
		var scrollY = window.scrollY || window.pageYOffset;
		var scrollX = window.scrollX || window.pageXOffset;
		var tooltipTop = evt.pageY + offset;
		var tooltipLeft = evt.pageX + offset;

		if (tooltipElm) {
			tooltipTop = (tooltipTop - scrollY + tooltipElm.offsetHeight + 20 >= window.innerHeight ? (tooltipTop - tooltipElm.offsetHeight - 20) : tooltipTop);
			tooltipLeft = (tooltipLeft - scrollX + tooltipElm.offsetWidth + 20 >= window.innerWidth ? (tooltipLeft - tooltipElm.offsetWidth - 20) : tooltipLeft);

			tooltipElm.style.top = tooltipTop + "px";
			tooltipElm.style.left = tooltipLeft + "px";
		}
	}

	function _onElementMouseOut(evt) {
		var tooltipElm = _getTooltipElm();

		if (tooltipElm) {
			document.querySelector("body").removeChild(tooltipElm);
		}
	}

	function _onElementMouseOver(evt) {
		var tooltipId = this.getAttribute("data-tooltip-id");
		var tooltipText = tooltipId && _tooltips[tooltipId] && _tooltips[tooltipId].text;

		if (tooltipText) {
			_createTooltip(tooltipText, tooltipId);
		}
	}

	function _parseOptions(options) {
		var optionsObj;

		if (options.length) {
			try {
				optionsObj = JSON.parse(options.replace(/'/ig, "\""));
			} catch(err) {
				console.log(err);
			}
		}

		return optionsObj;
	}

	function _init() {
		window.addEventListener("load", _bindTooltips);
	}

	_init();

	return {
		setOptions: function(options) {
			for (var option in options) {
				if (_options.hasOwnProperty(option)) {
					_options[option] = options[option];
				}
			}
		},
		refresh: function() {
			_bindTooltips(true);
		}
	};
}));
<|endoftext|>


<commit_before>'use strict';

const helper = require('./database/helper');

return helper.connectToDatabase()
  .then((db) => db.createCollection('users_duplications'))
  .then((collection) => collection.drop())
  .then((result) => {
    console.log('Got result from drop users_duplications:', result);
    return helper.connectToDatabase()
      .then((db) => db.createCollection('users_migrated'))
      .then((collection) => collection.drop())
      .then(() => {
        console.log('Got result from drop users_migrated:', result);
        return helper.connectToDatabase()
          .then((db) => db.collection('users'))
          .then((coll) => coll.mapReduce(function() {
            emit(this.username.toLowerCase().replace(/[|\s&;$%&§\{\[\]\}@"<>()+,!?\-._~\=\*\+\#\;\\/]/g, ''), this);
          },
            function(key, values) {
              if (values.length === undefined || values.length === null || values.length < 1)
                values = [values];
              let o = {
                count: 1,
                username: key,
                users: values.reduce(function(prev, curr) {
                  if (curr.count === undefined || curr.count === null || curr.count < 1)
                    prev.push(curr.value);
                  else
                    prev.concat(curr.users);
                  return prev;
                }, [])
              };
              o.count = o.users.length;
              return o;
            },
            {out: 'users_duplications'}
          ))
          .then((collection) => collection.count())
          .then((result) => {
            console.log('Got result from first mapReduce:', result);
            return helper.connectToDatabase()
              .then((db) => db.collection('users_duplications'))
              .then((coll) => coll.mapReduce(function() {
                if (this.value.count === undefined || this.value.count === null || this.value.count < 1) {
                  this.value.username = this.value.username.replace(/[|\s&;$%&§\{\[\]\}@"<>()+,!?\=\*\+\#\;\\/]/g,'_');
                  emit(this.value._id, this.value);
                }
                else {
                  let i = 0;
                  this.value.users.forEach(function(user) {
                    let username = user.username.replace(/[|\s&;$%&§\{\[\]\}@"<>()+,!?\=\*\+\#\;\\/]/g,'_');
                    for (let j = 0; j < i; j++) {
                      username = username+'_';
                    }
                    i++;
                    user.username = username;
                    emit(user._id, user);
                  });
                }
              },
                function(key, values) {
                  console.log('value slength: ', values.length);
                  return values[0];
                },
                {out: 'users_migrated'}
              ))
              .then((collection) => collection.count())
              .then((result) => {
                console.log('Got result from second mapReduce:', result);
                return helper.connectToDatabase()
                  .then((db) => db.collection('users_migrated'))
                  .then((coll) => coll.aggregate([{ $replaceRoot: { newRoot: '$value' } },{ $out: 'users' }]))
                  .then((collection) => collection.toArray())
                  .then((result) => {
                    console.log('Finished!!! Got results from aggregate:', result.length);
                    process.exit(0);
                    return true;
                  });
              });
          });
      });
  })
  .catch((error) => {
    console.log('Error:', error);
    process.exit(0);
    return;
  });
<commit_msg>[SWIK-1280_username_case_insensitive] Merge code seems to work now<commit_after>'use strict';

const helper = require('./database/helper');

return helper.connectToDatabase()
  .then((db) => db.createCollection('users_duplications'))
  .then((collection) => collection.drop())
  .then((result) => {
    console.log('Got result from drop users_duplications:', result);
    return helper.connectToDatabase()
      .then((db) => db.createCollection('users_migrated'))
      .then((collection) => collection.drop())
      .then(() => {
        console.log('Got result from drop users_migrated:', result);
        return helper.connectToDatabase()
          .then((db) => db.collection('users'))
          .then((coll) => coll.mapReduce(function() {
            emit(this.username.toLowerCase().replace(/[|\s&;$%&§\{\[\]\}@"<>()+,!?\-._~\=\*\+\#\;\\/]/g, ''), this);
          },
            function(key, values) {
              if (values.length === undefined || values.length === null || values.length < 1)
                values = [values];
              let o = {
                count: 1,
                username: key,
                users: values.reduce(function(prev, curr) {
                  if (curr.count === undefined || curr.count === null || curr.count < 1)
                    prev.push(curr);
                  else {
                    let result = [];
                    prev.forEach((e) => {
                      result.push(e);
                    });
                    curr.users.forEach((e) => {
                      result.push(e);
                    });
                    prev = result;
                  }
                  return prev;
                }, [])
              };
              o.count = o.users.length;
              return o;
            },
            {out: 'users_duplications'}
          ))
          .then((collection) => collection.count())
          .then((result) => {
            console.log('Got result from first mapReduce:', result);
            return helper.connectToDatabase()
              .then((db) => db.collection('users_duplications'))
              .then((coll) => coll.mapReduce(function() {
                if (this.value.count === undefined || this.value.count === null || this.value.count < 1) {
                  this.value.username = this.value.username.replace(/[|\s&;$%&§\{\[\]\}@"<>()+,!?\=\*\+\#\;\\/]/g,'_');
                  emit(this.value._id, this.value);
                }
                else {
                  let i = 0;
                  this.value.users.forEach(function(user) {
                    if (user !== undefined) {
                      let username = user.username.replace(/[|\s&;$%&§\{\[\]\}@"<>()+,!?\=\*\+\#\;\\/]/g,'_');
                      while (username.charAt(username.length-1) === '_') {
                        username = username.substr(0, username.length-1);
                      }
                      for (let j = 0; j < i; j++) {
                        username = username+'_';
                      }
                      i++;
                      user.username = username;
                      emit(user._id, user);
                    }
                  });
                }
              },
                function(key, values) {
                  return values[0];
                },
                {out: 'users_migrated'}
              ))
              .then((collection) => collection.count())
              .then((result) => {
                console.log('Got result from second mapReduce:', result);
                return helper.connectToDatabase()
                  .then((db) => db.collection('users_migrated'))
                  .then((coll) => coll.aggregate([{ $replaceRoot: { newRoot: '$value' } },{ $out: 'users' }]))
                  .then((collection) => collection.toArray())
                  .then((result) => {
                    console.log('Finished!!! Got results from aggregate:', result.length);
                    process.exit(0);
                    return true;
                  });
              });
          });
      });
  })
  .catch((error) => {
    console.log('Error:', error);
    process.exit(0);
    return;
  });
<|endoftext|>


<commit_before>$(function(){

    $.ajax({
        url: "README.symlink.md",
        dataType: 'text',
        cache: false,
        success: function(text){
            $('#notes .loading').remove();
            var converter = new Showdown.converter();
            var html = converter.makeHtml(text);
            $('#notes').append('
' + html + '
');
        }, error: function(jqXHR, textStatus, errorThrown){
            $('#notes .loading').remove();
            $('
').addClass('alert').html('<button type="button" class="close" data-dismiss="alert">×</button> Sorry! We couldn’t find your project’s README.md file. Are you sure it exists?').appendTo('#notes');
        }
    });

    $.ajax({
        url: "scraperwiki.symlink.json",
        dataType: 'json',
        cache: false,
        success: function(data){
            console.log(data);
            if('project-name' in data && 'customer-name' in data){
                $('#info h1').html(data['project-name'] + ' ' + data['customer-name'] + '');
            }
            if('status-message' in data){
                $('#info .lead').html('Latest status: ' + data['status-message']);
            }
        }, error: function(jqXHR, textStatus, errorThrown){
            $('
').addClass('alert').html('<button type="button" class="close" data-dismiss="alert">×</button> Something went wrong! We couldn’t find your project’s scraperwiki.json file. Are you sure it exists?').prependTo('#info');
            $('#info .lead').hide();
            $('#info h1 small').hide();
        }
    });

    $.ajax({
        url: "../../sqlite",
        data: {
            q: "SELECT name FROM sqlite_master WHERE type='table'"
        },
        dataType: 'json',
        cache: false,
        success: function(data){
            var $ul = $('
').addClass('nav nav-tabs');
            var $tables = $('
').addClass('tables');
            $.each(data, function(i,table){
                var $li = $('
').bind('click', function(){
                    $(this).addClass('active').siblings('.active').removeClass('active');
                    $('.tables .table').eq($(this).prevAll().length).show().siblings('.table').hide();
                });
                $('' + table['name'] + '').appendTo($li);
                var $table = $('
').addClass('table').css('height', 300);
                $.ajax({
                    url: "../../sqlite",
                    data: {
                        q: "SELECT * FROM `" + table['name'] + "`"
                    },
                    dataType: 'json',
                    cache: false,
                    success: function(data){
                        var grid = new recline.View.SlickGrid({
                            model: new recline.Model.Dataset({ records: data }),
                            el: $table
                        });
                        grid.visible = true;
                        grid.render();
                    }
                });
                if(i==0){
                    $li.addClass('active');
                } else {
                    $table.hide();
                }
                $li.appendTo($ul);
                $table.appendTo($tables);
            });
            $ul.appendTo('#data');
            $tables.appendTo('#data');
        }, error: function(jqXHR, textStatus, errorThrown){
            $('
').addClass('alert').html('<button type="button" class="close" data-dismiss="alert">×</button> Something went wrong! We couldn’t select data from your project’s SQLite API.').appendTo('#data');
            $('#datagrid').hide();
        }
    });

    var $hds = $('').addClass('drop-shadow').appendTo('.page-header');
    $(window).scroll(function(){
        var st = $(window).scrollTop();
        var op = 0;
        if(st > 0){
            op = Math.min(1, st/30);
        }
        $hds.css('opacity', op);
    });

});
<commit_msg>default limit on datastore preview table length<commit_after>$(function(){

    $.ajax({
        url: "README.symlink.md",
        dataType: 'text',
        cache: false,
        success: function(text){
            $('#notes .loading').remove();
            var converter = new Showdown.converter();
            var html = converter.makeHtml(text);
            $('#notes').append('
' + html + '
');
        }, error: function(jqXHR, textStatus, errorThrown){
            $('#notes .loading').remove();
            $('
').addClass('alert').html('<button type="button" class="close" data-dismiss="alert">×</button> Sorry! We couldn’t find your project’s README.md file. Are you sure it exists?').appendTo('#notes');
        }
    });

    $.ajax({
        url: "scraperwiki.symlink.json",
        dataType: 'json',
        cache: false,
        success: function(data){
            console.log(data);
            if('project-name' in data && 'customer-name' in data){
                $('#info h1').html(data['project-name'] + ' ' + data['customer-name'] + '');
            }
            if('status-message' in data){
                $('#info .lead').html('Latest status: ' + data['status-message']);
            }
        }, error: function(jqXHR, textStatus, errorThrown){
            $('
').addClass('alert').html('<button type="button" class="close" data-dismiss="alert">×</button> Something went wrong! We couldn’t find your project’s scraperwiki.json file. Are you sure it exists?').prependTo('#info');
            $('#info .lead').hide();
            $('#info h1 small').hide();
        }
    });

    $.ajax({
        url: "../../sqlite",
        data: {
            q: "SELECT name FROM sqlite_master WHERE type='table'"
        },
        dataType: 'json',
        cache: false,
        success: function(data){
            var $ul = $('
').addClass('nav nav-tabs');
            var $tables = $('
').addClass('tables');
            $.each(data, function(i,table){
                var $li = $('
').bind('click', function(){
                    $(this).addClass('active').siblings('.active').removeClass('active');
                    $('.tables .table').eq($(this).prevAll().length).show().siblings('.table').hide();
                });
                $('' + table['name'] + '').appendTo($li);
                var $table = $('
').addClass('table').css('height', 300);
                $.ajax({
                    url: "../../sqlite",
                    data: {
                        q: "SELECT * FROM `" + table['name'] + "` LIMIT 500"
                    },
                    dataType: 'json',
                    cache: false,
                    success: function(data){
                        var grid = new recline.View.SlickGrid({
                            model: new recline.Model.Dataset({ records: data }),
                            el: $table
                        });
                        grid.visible = true;
                        grid.render();
                    }
                });
                if(i==0){
                    $li.addClass('active');
                } else {
                    $table.hide();
                }
                $li.appendTo($ul);
                $table.appendTo($tables);
            });
            $ul.appendTo('#data');
            $tables.appendTo('#data');
        }, error: function(jqXHR, textStatus, errorThrown){
            $('
').addClass('alert').html('<button type="button" class="close" data-dismiss="alert">×</button> Something went wrong! We couldn’t select data from your project’s SQLite API.').appendTo('#data');
            $('#datagrid').hide();
        }
    });

    var $hds = $('').addClass('drop-shadow').appendTo('.page-header');
    $(window).scroll(function(){
        var st = $(window).scrollTop();
        var op = 0;
        if(st > 0){
            op = Math.min(1, st/30);
        }
        $hds.css('opacity', op);
    });

});
<|endoftext|>


<commit_before>ispy.toggleAnimation = function() {
  ispy.animating = !ispy.animating;

  if ( ispy.animating ) {

    var length = ispy.camera.position.length();
    var xs = [ispy.camera.position.x, 0];
    var ys = [0, 0];
    var zs = [ispy.camera.position.z, length];

    var tw1 = new TWEEN.Tween(ispy.camera.position)
      .to({x:xs, y:ys, z:zs}, 2000)
      .easing(TWEEN.Easing.Sinusoidal.In);

    var r = 2.0;

    var tw2 = new TWEEN.Tween(ispy.camera.position)
      .to({x:0, y:0, z:r}, 2000)
      .easing(TWEEN.Easing.Sinusoidal.In);

    var ns = 24;
    var s = 2*Math.PI/ns;
    var cx = [];
    var cy = [];
    var cz = [];
    for ( var i = 1; i <= ns; i++ ) {
      cx.push(r*Math.sin(s*i));
      cy.push(0.0);
      cz.push(r*Math.cos(s*i));
    }

    var c1x = cx.slice(0,12);
    var c1y = cy.slice(0,12);
    var c1z = cz.slice(0,12);

    var tw3 = new TWEEN.Tween(ispy.camera.position)
      .to({x:c1x, y:c1y, z:c1z}, 2500);

    // Split the rotation in half and
    // turn off tracks and turn on electrons

    var c2x = cx.slice(13,24);
    var c2y = cy.slice(13,24);
    var c2z = cz.slice(13,24);

    var tw4 = new TWEEN.Tween(ispy.camera.position)
      .to({x:c2x, y:c2y, z:c2z}, 2500)
      .onStart(function(){
        ispy.toggle("Tracking", "Tracks_V2");
        ispy.toggle("HCAL", "HBRecHits_V2");
        ispy.toggle("HCAL", "HERecHits_V2");
        ispy.toggle("PhysicsObjects", "GsfElectrons_V1");
      })

    var pgeometry = new THREE.SphereGeometry(0.25,32,32);
    var pmaterial = new THREE.MeshBasicMaterial({color: 0xffff00});

    var proton1 = new THREE.Mesh(pgeometry, pmaterial);
    proton1.position.x = 0.0;
    proton1.position.y = 0.0;
    proton1.position.z = 200.0;

    var proton2 = new THREE.Mesh(pgeometry, pmaterial);
    proton2.position.x = 0.0;
    proton2.position.y = 0.0;
    proton2.position.z = -200.0;

    ispy.scene.add(proton1);
    ispy.scene.add(proton2);

    var c1 = new TWEEN.Tween(proton1.position)
      .to({z:0.0}, 2000)
      .easing(TWEEN.Easing.Back.In);

    var c2 = new TWEEN.Tween(proton2.position)
      .to({z:0.0}, 2000)
      .onComplete(function(){
        tw1.start();

        ispy.toggle("Tracking", "Tracks_V2");
        ispy.toggle("ECAL", "EBRecHits_V2");
        ispy.toggle("ECAL", "EERecHits_V2");
        ispy.toggle("HCAL", "HBRecHits_V2");
        ispy.toggle("HCAL", "HERecHits_V2");
      })
      .easing(TWEEN.Easing.Back.In);

    var c3 = new TWEEN.Tween(proton1.position)
      .to({z:-200.0}, 2000)
      .onComplete(function(){
        ispy.scene.remove(proton1);
      }).easing(TWEEN.Easing.Back.Out);

    var c4 = new TWEEN.Tween(proton2.position)
      .to({z:200.0}, 2000)
      .onComplete(function(){
        ispy.scene.remove(proton2);
      }).easing(TWEEN.Easing.Back.Out);

    c1.chain(c3);
    c2.chain(c4);

    tw1.chain(tw2);
    tw2.chain(tw3);
    tw3.chain(tw4);

    c1.start();
    c2.start();
  }
}
<commit_msg>factor out some of the animation parameters<commit_after>// This is particular to the sequence below:
// - Colliding bunch crossings
// - Zoom into position inside detector
// - Rotate around, turning off tracks halfway through rotation
// It will be nice to generalize all this but it's good-enough for now.

ispy.animation_script = {
    "collision": {
      "proton1": {
        "pi" : {x:0, y:0, z:200.0},
        "pf" : {x:0, y:0, z:-200.0}
      },
      "proton2": {
        "pi": {x:0, y:0, z:-200.0},
        "pf": {x:0, y:0, z:200.0}
      },
      "time": 2500
    },
    "zoom": {
      "time": 2000
    },
    "rotation": {
      "radius": 2.0,
      "angle": 2*Math.PI,
      "nsteps": 24,
      "time": 5000
    }
}

ispy.toggleAnimation = function() {
  ispy.animating = !ispy.animating;

  if ( ispy.animating ) {

    var animation = ispy.animation_script;

    var length = ispy.camera.position.length();
    var xs = [ispy.camera.position.x, 0];
    var ys = [0, 0];
    var zs = [ispy.camera.position.z, length];

    var tw1 = new TWEEN.Tween(ispy.camera.position)
      .to({x:xs, y:ys, z:zs}, animation.zoom.time)
      .easing(TWEEN.Easing.Sinusoidal.In);

    var r = animation.rotation.radius;

    var tw2 = new TWEEN.Tween(ispy.camera.position)
      .to({x:0, y:0, z:r}, animation.zoom.time)
      .easing(TWEEN.Easing.Sinusoidal.In);

    var ns = animation.rotation.nsteps;
    var s = animation.rotation.angle/ns;
    var cx = [];
    var cy = [];
    var cz = [];
    for ( var i = 1; i <= ns; i++ ) {
      cx.push(r*Math.sin(s*i));
      cy.push(0.0);
      cz.push(r*Math.cos(s*i));
    }

    var bs = 0;
    var es = ns/2;

    var c1x = cx.slice(0,es);
    var c1y = cy.slice(0,es);
    var c1z = cz.slice(0,es);

    var tw3 = new TWEEN.Tween(ispy.camera.position)
      .to({x:c1x, y:c1y, z:c1z}, animation.rotation.time);

    // Split the rotation in half and
    // turn off tracks and turn on electrons

    bs = ns/2 + 1;
    es = ns;

    var c2x = cx.slice(bs, es);
    var c2y = cy.slice(bs, es);
    var c2z = cz.slice(bs, es);

    var tw4 = new TWEEN.Tween(ispy.camera.position)
      .to({x:c2x, y:c2y, z:c2z}, animation.rotation.time)
      .onStart(function(){
        ispy.toggle("Tracking", "Tracks_V2");
        ispy.toggle("HCAL", "HBRecHits_V2");
        ispy.toggle("HCAL", "HERecHits_V2");
        ispy.toggle("PhysicsObjects", "GsfElectrons_V1");
      })

    var pgeometry = new THREE.SphereGeometry(0.25,32,32);
    var pmaterial = new THREE.MeshBasicMaterial({color: 0xffff00});

    var proton1 = new THREE.Mesh(pgeometry, pmaterial);
    proton1.position.x = animation.collision.proton1.pi.x;
    proton1.position.y = animation.collision.proton1.pi.y;
    proton1.position.z = animation.collision.proton1.pi.z;

    var proton2 = new THREE.Mesh(pgeometry, pmaterial);
    proton2.position.x = animation.collision.proton2.pi.x;
    proton2.position.y = animation.collision.proton2.pi.y;
    proton2.position.z = animation.collision.proton2.pi.z;

    ispy.scene.add(proton1);
    ispy.scene.add(proton2);

    var c1 = new TWEEN.Tween(proton1.position)
      .to({z:0.0}, animation.collision.time)
      .easing(TWEEN.Easing.Back.In);

    var c2 = new TWEEN.Tween(proton2.position)
      .to({z:0.0}, animation.collision.time)
      .onComplete(function(){
        tw1.start();

        ispy.toggle("Tracking", "Tracks_V2");
        ispy.toggle("ECAL", "EBRecHits_V2");
        ispy.toggle("ECAL", "EERecHits_V2");
        ispy.toggle("HCAL", "HBRecHits_V2");
        ispy.toggle("HCAL", "HERecHits_V2");
      })
      .easing(TWEEN.Easing.Back.In);

    var c3 = new TWEEN.Tween(proton1.position)
      .to({z:animation.collision.proton1.pf.z}, animation.collision.time)
      .onComplete(function(){
        ispy.scene.remove(proton1);
      }).easing(TWEEN.Easing.Back.Out);

    var c4 = new TWEEN.Tween(proton2.position)
      .to({z:animation.collision.proton2.pf.z}, animation.collision.time)
      .onComplete(function(){
        ispy.scene.remove(proton2);
      }).easing(TWEEN.Easing.Back.Out);

    c1.chain(c3);
    c2.chain(c4);

    tw1.chain(tw2);
    tw2.chain(tw3);
    tw3.chain(tw4);

    c1.start();
    c2.start();
  }
}
<|endoftext|>


<commit_before>// WebUI Application
// Michael Thomas, 2014

// Awesome Logging
// Only display console log output in debug mode, else nothing.
// @todo - Send serious logs to server?
var debug = true;

log = function () {
  if (debug && console && typeof console.log === 'function') {
    for (var i = 0, ii = arguments.length; i < ii; i++) {
      console.log(arguments[i]);
    }
  }
}

// Main Application
var WebUI = function() {
	// Login Bits
	// Display the login screen.
	var displayLogin = function(callback) {
		// Hide Header
		$("#app-nav").addClass("hide");
		// Set Title
		document.title = "giv2giv - Login";
		// Show Login Panel
		$("#login-panel").removeClass("hide");

		// Callback
		if(typeof callback === "function") {
    	// Call it, since we have confirmed it is callable
      callback();
    }
	};

	// Hide the login screen
	var hideLogin = function(callback) {
		// Show Header
		$("#app-nav").removeClass("hide");
		// Title is set in Load Page
		// Hide Login Panel
		$("#login-panel").addClass("hide");
		// Clean up form here.
		$("#signin-email").val("");
		$("#signin-password").val("");

		// Callback
		if(typeof callback === "function") {
    	// Call it, since we have confirmed it is callable
      callback();
    }
	};

	// Login Form
	$("#login-frm").on("submit", function(e) {
		// Build Payload
		var payload = JSON.stringify({ "email" : $("#signin-email").val(), "password" : $("#signin-password").val() });
		$.ajax({
			url: "https://api.giv2giv.org/api/sessions/create.json",
			type: "POST",
			data: payload,
			contentType: "application/json",
			dataType:"json",
			success: function (data) {
				$.ajaxSetup({
		 			beforeSend: function(xhr, settings) {
			 			xhr.setRequestHeader("Authorization", "Token token=" + data.session.session.token);
		  		}
		 		});
		 		// Set Cookie
		 		$.cookie('session', data.session.session.token);
			  startApplication();
			},
			error: function(data) {
				var res = JSON.parse(data.responseText);
				if(res.message == "unauthorized") {
					$("#login-message").html("Incorrect Email or Password");
				} else {
					log("WebUI: Login Error - " + res.message);
				}
			}
		});
		e.preventDefault();
	});

	// Application Bits
	// Display Application
	var displayApplication = function(callback) {
		// Show App Panel
		$("#app-panel").removeClass("hide");
		// Show App Nav
		$("#app-nav").removeClass("hide");
		// Callback
		if(typeof callback === "function") {
    	// Call it, since we have confirmed it is callable
      callback();
    }
	};

	// Start Application
	// This is only loaded on full page refresh or first visit
	var startApplication = function(callback) {
		log("WebUI: Started Application");
		if($.cookie('session') == undefined) {
			log("WebUI: No Session Cookie found, displaying Login.");
			displayLogin();
			stopLoad();
		} else {
			// We have a session cookie, set header & see if it's valid
			log("WebUI: Session Cookie found, checking session.");
			// Set Header
			$.ajaxSetup({
 				beforeSend: function(xhr, settings) {
	 				xhr.setRequestHeader("Authorization", "Token token=" + $.cookie('session'));
				}
			});
			// Get Donor Info (and check session as a result)
			$.get("https://api.giv2giv.org/api/donors.json").success(function(data) {
				// Load Dashboard (routing)
				log("WebUI: Valid session, loading application.");
				log("WebUI: Initial Page " + window.location.pathname);
				// Load Current URL
				History.replaceState(null, 'Loading...', window.location.pathname);
				// Set Donor Name
				$("#donor-name").html(data.donor.name);
				hideLogin();
				// Display Application
				displayApplication();
			}).error(function(data) {
				if(data.statusText == "Unauthorized") {
					log("WebUI: Invalid session, resetting cookie & displaying Login.");
					displayLogin();
					stopLoad();
				}
			});
		}
		if(typeof callback === "function") {
    	// Call it, since we have confirmed it is callable
      callback();
    }
	};

	// End Application
	var endApplication = function(message, callback) {
		// @todo - End our session
		// @todo - Fix history bug here
		// Clear existing data in Application Container
		$.removeCookie('session');
		$("#app-panel").html("");
		$('#app-panel').addClass('hide');
		$('#app-nav').addClass('hide');
		$('#login-panel').removeClass('hide');

		// Callback
		if(typeof callback === "function") {
    	// Call it, since we have confirmed it is callable
      callback();
    }
	};

	// Start Loading
  var startLoad = function() {
  	log("WebUI: Start Loader");
    $('#loading').removeClass("hide");
  };

  // Stop Loading
  var stopLoad = function() {
  	log("WebUI: Stop Loader");
    $('#loading').addClass("hide");
  };

  // Setup App Router
  // Note: Sub routing (like /endowments/1) handled in modules.
	var router = function(callback) {
		log("WebUI: Starting router.");
		History.Adapter.bind(window,'statechange',function() {
			crossroads.parse(document.location.pathname);
  	});

		// Handle Logout Button
		$("#logout-btn").on("click", function(e) {
			log("WebUI: Logout.");
			endApplication(function() {
				displayLogin();
			});
			e.preventDefault();
		});

		// Handle Nav Bar Clicks
		$(".nav-link a").on("click", function(e) {
			if(!$(this).parent().hasClass("active")) {
				History.pushState(null, 'Loading...', $(this).attr('href'));
			}
			e.preventDefault();
		});

		// Routes
		// Dashboard Route
		crossroads.addRoute('/', function() {
			startLoad();
			loadPage('/ui/dashboard.html', function() {
				// Remove old active tabs
				$(".nav-link").siblings().removeClass("active");
				History.replaceState(null, 'giv2giv - Dashboard', '/');
				stopLoad();
				// Set Nav Tab
				$("#endowments-nav").addClass("active");
			});
		});

		crossroads.addRoute('/donor', function() {
			startLoad();
			loadPage('/ui/donor.html', function() {
				$(".nav-link").siblings().removeClass("active");
				History.replaceState(null, 'giv2giv - Donor', '/donor');
				stopLoad();
				// Set Nav Tab
				$("#donor-nav").addClass("active");
			});
		});

		crossroads.addRoute('/numbers', function() {
			startLoad();
			loadPage('/ui/numbers.html', function() {
				$(".nav-link").siblings().removeClass("active");
				History.replaceState(null, 'giv2giv - Numbers', '/numbers');
				stopLoad();
				// Set Nav Tab
				$("#numbers-nav").addClass("active");
			});
		});

		// Callbacks
		if(typeof callback === "function") {
    	// Call it, since we have confirmed it is callable
      callback();
    }
	};

	// Load HTML Page
	function loadPage(url, callback) {
		log("WebUI: Loading Page HTML: " + url);
		$.get(url, function (data) {
			log("WebUI: Loaded page.")
			$("#app-panel").html(data);
			reloadUI();
		}).fail(function(data) {
			log("WebUI: Failed to load page.");
		});

		// Callback
		if(typeof callback === "function") {
  		// Call it, since we have confirmed it is callable
    	callback();
  	}
	}

	// Reload UI
	// Some jQuery Selectors can't delegate & need to be applied to dynamic HTML
	function reloadUI() {
		// Initialize tabs
		$('[data-toggle="tabs"] a').click(function (e) { e.preventDefault(); $(this).tab('show'); });
	}

  // Finally expose bits
	return {
		init: function () {
			// History Adapter
			log("WebUI: Init Start");
			router(function() {
				startApplication();
				log("WebUI: Init Complete");
			});
		}, startLoad: function () {
			startLoad();
		}, stopLoad: function () {
			stopLoad();
		}, showAlert: function(type, message, timeout) {
			showAlert(type, message, timeout);
		}
	};
} ();

// DOM Loaded
$(function() {
	WebUI.init();
});<commit_msg>Sort of fix logout bug<commit_after>// WebUI Application
// Michael Thomas, 2014

// Awesome Logging
// Only display console log output in debug mode, else nothing.
// @todo - Send serious logs to server?
var debug = true;

log = function () {
  if (debug && console && typeof console.log === 'function') {
    for (var i = 0, ii = arguments.length; i < ii; i++) {
      console.log(arguments[i]);
    }
  }
}

// Main Application
var WebUI = function() {
	// Login Bits
	// Display the login screen.
	var displayLogin = function(callback) {
		// Hide Header
		$("#app-nav").addClass("hide");
		// Set Title
		document.title = "giv2giv - Login";
		// Show Login Panel
		$("#login-panel").removeClass("hide");

		// Callback
		if(typeof callback === "function") {
    	// Call it, since we have confirmed it is callable
      callback();
    }
	};

	// Hide the login screen
	var hideLogin = function(callback) {
		// Show Header
		$("#app-nav").removeClass("hide");
		// Title is set in Load Page
		// Hide Login Panel
		$("#login-panel").addClass("hide");
		// Clean up form here.
		$("#signin-email").val("");
		$("#signin-password").val("");

		// Callback
		if(typeof callback === "function") {
    	// Call it, since we have confirmed it is callable
      callback();
    }
	};

	// Login Form
	$("#login-frm").on("submit", function(e) {
		// Build Payload
		var payload = JSON.stringify({ "email" : $("#signin-email").val(), "password" : $("#signin-password").val() });
		$.ajax({
			url: "https://api.giv2giv.org/api/sessions/create.json",
			type: "POST",
			data: payload,
			contentType: "application/json",
			dataType:"json",
			success: function (data) {
				$.ajaxSetup({
		 			beforeSend: function(xhr, settings) {
			 			xhr.setRequestHeader("Authorization", "Token token=" + data.session.session.token);
		  		}
		 		});
		 		// Set Cookie
		 		$.cookie('session', data.session.session.token);
			  startApplication();
			},
			error: function(data) {
				var res = JSON.parse(data.responseText);
				if(res.message == "unauthorized") {
					$("#login-message").html("Incorrect Email or Password");
				} else {
					log("WebUI: Login Error - " + res.message);
				}
			}
		});
		e.preventDefault();
	});

	// Application Bits
	// Display Application
	var displayApplication = function(callback) {
		// Show App Panel
		$("#app-panel").removeClass("hide");
		// Show App Nav
		$("#app-nav").removeClass("hide");
		// Callback
		if(typeof callback === "function") {
    	// Call it, since we have confirmed it is callable
      callback();
    }
	};

	// Start Application
	// This is only loaded on full page refresh or first visit
	var startApplication = function(callback) {
		log("WebUI: Started Application");
		if($.cookie('session') == undefined) {
			log("WebUI: No Session Cookie found, displaying Login.");
			displayLogin();
			stopLoad();
		} else {
			// We have a session cookie, set header & see if it's valid
			log("WebUI: Session Cookie found, checking session.");
			// Set Header
			$.ajaxSetup({
 				beforeSend: function(xhr, settings) {
	 				xhr.setRequestHeader("Authorization", "Token token=" + $.cookie('session'));
				}
			});
			// Get Donor Info (and check session as a result)
			$.get("https://api.giv2giv.org/api/donors.json").success(function(data) {
				// Load Dashboard (routing)
				log("WebUI: Valid session, loading application.");
				log("WebUI: Initial Page " + window.location.pathname);
				// Load Current URL
				History.replaceState(null, 'Loading...', window.location.pathname);
				// Set Donor Name
				$("#donor-name").html(data.donor.name);
				hideLogin();
				// Display Application
				displayApplication();
			}).error(function(data) {
				if(data.statusText == "Unauthorized") {
					log("WebUI: Invalid session, resetting cookie & displaying Login.");
					displayLogin();
					stopLoad();
				}
			});
		}
		if(typeof callback === "function") {
    	// Call it, since we have confirmed it is callable
      callback();
    }
	};

	// End Application
	var endApplication = function(message, callback) {
		// @todo - End our session
		// @todo - Fix history bug here
		// Line below "fixs" history bug, but isn't ideal.
		location.reload();
		// Clear existing data in Application Container
		$.removeCookie('session');
		$("#app-panel").html("");
		$('#app-panel').addClass('hide');
		$('#app-nav').addClass('hide');
		$('#login-panel').removeClass('hide');

		// Callback
		if(typeof callback === "function") {
    	// Call it, since we have confirmed it is callable
      callback();
    }
	};

	// Start Loading
  var startLoad = function() {
  	log("WebUI: Start Loader");
    $('#loading').removeClass("hide");
  };

  // Stop Loading
  var stopLoad = function() {
  	log("WebUI: Stop Loader");
    $('#loading').addClass("hide");
  };

  // Setup App Router
  // Note: Sub routing (like /endowments/1) handled in modules.
	var router = function(callback) {
		log("WebUI: Starting router.");
		History.Adapter.bind(window,'statechange',function() {
			crossroads.parse(document.location.pathname);
  	});

		// Handle Logout Button
		$("#logout-btn").on("click", function(e) {
			log("WebUI: Logout.");
			endApplication(function() {
				displayLogin();
			});
			e.preventDefault();
		});

		// Handle Nav Bar Clicks
		$(".nav-link a").on("click", function(e) {
			if(!$(this).parent().hasClass("active")) {
				History.pushState(null, 'Loading...', $(this).attr('href'));
			}
			e.preventDefault();
		});

		// Routes
		// Dashboard Route
		crossroads.addRoute('/', function() {
			startLoad();
			loadPage('/ui/dashboard.html', function() {
				// Remove old active tabs
				$(".nav-link").siblings().removeClass("active");
				History.replaceState(null, 'giv2giv - Dashboard', '/');
				stopLoad();
				// Set Nav Tab
				$("#endowments-nav").addClass("active");
			});
		});

		crossroads.addRoute('/donor', function() {
			startLoad();
			loadPage('/ui/donor.html', function() {
				$(".nav-link").siblings().removeClass("active");
				History.replaceState(null, 'giv2giv - Donor', '/donor');
				stopLoad();
				// Set Nav Tab
				$("#donor-nav").addClass("active");
			});
		});

		crossroads.addRoute('/numbers', function() {
			startLoad();
			loadPage('/ui/numbers.html', function() {
				$(".nav-link").siblings().removeClass("active");
				History.replaceState(null, 'giv2giv - Numbers', '/numbers');
				stopLoad();
				// Set Nav Tab
				$("#numbers-nav").addClass("active");
			});
		});

		// Callbacks
		if(typeof callback === "function") {
    	// Call it, since we have confirmed it is callable
      callback();
    }
	};

	// Load HTML Page
	function loadPage(url, callback) {
		log("WebUI: Loading Page HTML: " + url);
		$.get(url, function (data) {
			log("WebUI: Loaded page.")
			$("#app-panel").html(data);
			reloadUI();
		}).fail(function(data) {
			log("WebUI: Failed to load page.");
		});

		// Callback
		if(typeof callback === "function") {
  		// Call it, since we have confirmed it is callable
    	callback();
  	}
	}

	// Reload UI
	// Some jQuery Selectors can't delegate & need to be applied to dynamic HTML
	function reloadUI() {
		// Initialize tabs
		$('[data-toggle="tabs"] a').click(function (e) { e.preventDefault(); $(this).tab('show'); });
	}

  // Finally expose bits
	return {
		init: function () {
			// History Adapter
			log("WebUI: Init Start");
			router(function() {
				startApplication();
				log("WebUI: Init Complete");
			});
		}, startLoad: function () {
			startLoad();
		}, stopLoad: function () {
			stopLoad();
		}, showAlert: function(type, message, timeout) {
			showAlert(type, message, timeout);
		}
	};
} ();

// DOM Loaded
$(function() {
	WebUI.init();
});<|endoftext|>


<commit_before>var Class = require('../../utils/Class');
var BaseSoundManager = require('../BaseSoundManager');
var HTML5AudioSound = require('./HTML5AudioSound');
var SoundValueEvent = require('../SoundValueEvent');
var HTML5AudioSoundManager = new Class({
    Extends: BaseSoundManager,
    initialize: function HTML5AudioSoundManager(game) {
        /**
         * Flag indicating whether if there are no idle instances of HTML5 Audio tag,
         * for any particular sound, if one of the used tags should be stopped and used
         * for succeeding playback or if succeeding Phaser.Sound.HTML5AudioSound#play
         * call should be ignored.
         *
         * @property {boolean} override
         * @default true
         */
        this.override = true;
        /**
         * Value representing time difference in seconds between calling
         * play method on an audio tag and when it actually starts playing.
         * It is used to achieve more accurate delayed sound playback.
         *
         * You might need to tweak this value to get the desired results
         * since audio play delay varies depending on the browser/platform.
         *
         * @property {number} audioPlayDelay
         * @default 0.1
         */
        this.audioPlayDelay = 0.1;
        /**
         * A value by which we should offset the loop end marker of the looping sound to compensate
         * for lag, caused by changing audio tag position, in order to achieve gapless looping.
         *
         * You might need to tweak this value to get the desired results
         * since loop lag varies depending on the browser/platform.
         *
         * @property {number} loopEndOffset
         * @default 0.05
         */
        this.loopEndOffset = 0.05;
        /**
         * An array for keeping track of all the sounds
         * that were paused when game lost focus.
         *
         * @private
         * @property {Phaser.Sound.HTML5AudioSound[]} onBlurPausedSounds
         * @default []
         */
        this.onBlurPausedSounds = [];
        /**
         * Property that actually holds the value of global mute
         * for HTML5 Audio sound manager implementation.
         *
         * @private
         * @property {boolean} _mute
         * @default false
         */
        this._mute = false;
        /**
         * Property that actually holds the value of global volume
         * for HTML5 Audio sound manager implementation.
         *
         * @private
         * @property {boolean} _volume
         * @default 1
         */
        this._volume = 1;
        BaseSoundManager.call(this, game);
    },
    add: function (key, config) {
        var sound = new HTML5AudioSound(this, key, config);
        this.sounds.push(sound);
        return sound;
    },
    onBlur: function () {
        this.forEachActiveSound(function (sound) {
            if (sound.isPlaying) {
                this.onBlurPausedSounds.push(sound);
                sound.onBlur();
            }
        });
    },
    onFocus: function () {
        this.onBlurPausedSounds.forEach(function (sound) {
            sound.onFocus();
        });
        this.onBlurPausedSounds.length = 0;
    },
    destroy: function () {
        BaseSoundManager.prototype.destroy.call(this);
        this.onBlurPausedSounds.length = 0;
        this.onBlurPausedSounds = null;
    }
});
/**
 * Global mute setting.
 *
 * @name Phaser.Sound.HTML5AudioSoundManager#mute
 * @property {boolean} mute
 */
Object.defineProperty(HTML5AudioSoundManager.prototype, 'mute', {
    get: function () {
        return this._mute;
    },
    set: function (value) {
        this._mute = value;
        this.forEachActiveSound(function (sound) {
            sound.setMute();
        });
        this.events.dispatch(new SoundValueEvent(this, 'SOUND_MUTE', value));
    }
});
/**
 * Global volume setting.
 *
 * @name Phaser.Sound.HTML5AudioSoundManager#volume
 * @property {number} volume
 */
Object.defineProperty(HTML5AudioSoundManager.prototype, 'volume', {
    get: function () {
        return this._volume;
    },
    set: function (value) {
        this._volume = value;
        this.forEachActiveSound(function (sound) {
            sound.setVolume();
        });
        this.events.dispatch(new SoundValueEvent(this, 'SOUND_VOLUME', value));
    }
});
module.exports = HTML5AudioSoundManager;
<commit_msg>Using EventEmitter emit method to dispatch mute update event<commit_after>var Class = require('../../utils/Class');
var BaseSoundManager = require('../BaseSoundManager');
var HTML5AudioSound = require('./HTML5AudioSound');
var HTML5AudioSoundManager = new Class({
    Extends: BaseSoundManager,
    initialize: function HTML5AudioSoundManager(game) {
        /**
         * Flag indicating whether if there are no idle instances of HTML5 Audio tag,
         * for any particular sound, if one of the used tags should be stopped and used
         * for succeeding playback or if succeeding Phaser.Sound.HTML5AudioSound#play
         * call should be ignored.
         *
         * @property {boolean} override
         * @default true
         */
        this.override = true;
        /**
         * Value representing time difference in seconds between calling
         * play method on an audio tag and when it actually starts playing.
         * It is used to achieve more accurate delayed sound playback.
         *
         * You might need to tweak this value to get the desired results
         * since audio play delay varies depending on the browser/platform.
         *
         * @property {number} audioPlayDelay
         * @default 0.1
         */
        this.audioPlayDelay = 0.1;
        /**
         * A value by which we should offset the loop end marker of the looping sound to compensate
         * for lag, caused by changing audio tag position, in order to achieve gapless looping.
         *
         * You might need to tweak this value to get the desired results
         * since loop lag varies depending on the browser/platform.
         *
         * @property {number} loopEndOffset
         * @default 0.05
         */
        this.loopEndOffset = 0.05;
        /**
         * An array for keeping track of all the sounds
         * that were paused when game lost focus.
         *
         * @private
         * @property {Phaser.Sound.HTML5AudioSound[]} onBlurPausedSounds
         * @default []
         */
        this.onBlurPausedSounds = [];
        /**
         * Property that actually holds the value of global mute
         * for HTML5 Audio sound manager implementation.
         *
         * @private
         * @property {boolean} _mute
         * @default false
         */
        this._mute = false;
        /**
         * Property that actually holds the value of global volume
         * for HTML5 Audio sound manager implementation.
         *
         * @private
         * @property {boolean} _volume
         * @default 1
         */
        this._volume = 1;
        BaseSoundManager.call(this, game);
    },
    add: function (key, config) {
        var sound = new HTML5AudioSound(this, key, config);
        this.sounds.push(sound);
        return sound;
    },
    onBlur: function () {
        this.forEachActiveSound(function (sound) {
            if (sound.isPlaying) {
                this.onBlurPausedSounds.push(sound);
                sound.onBlur();
            }
        });
    },
    onFocus: function () {
        this.onBlurPausedSounds.forEach(function (sound) {
            sound.onFocus();
        });
        this.onBlurPausedSounds.length = 0;
    },
    destroy: function () {
        BaseSoundManager.prototype.destroy.call(this);
        this.onBlurPausedSounds.length = 0;
        this.onBlurPausedSounds = null;
    }
});
/**
 * Global mute setting.
 *
 * @name Phaser.Sound.HTML5AudioSoundManager#mute
 * @property {boolean} mute
 */
Object.defineProperty(HTML5AudioSoundManager.prototype, 'mute', {
    get: function () {
        return this._mute;
    },
    set: function (value) {
        this._mute = value;
        this.forEachActiveSound(function (sound) {
            sound.setMute();
        });
        this.emit('mute', this, value);
    }
});
/**
 * Global volume setting.
 *
 * @name Phaser.Sound.HTML5AudioSoundManager#volume
 * @property {number} volume
 */
Object.defineProperty(HTML5AudioSoundManager.prototype, 'volume', {
    get: function () {
        return this._volume;
    },
    set: function (value) {
        this._volume = value;
        this.forEachActiveSound(function (sound) {
            sound.setVolume();
        });
        this.events.dispatch(new SoundValueEvent(this, 'SOUND_VOLUME', value));
    }
});
module.exports = HTML5AudioSoundManager;
<|endoftext|>


<commit_before>'use strict';

/**
 * Global modules
 */
var async = require('async');
var Trello = require('node-trello');
var _ = require('lodash');

/**
 * Custom mixin for lodash
 */
_.mixin({
	'findByValues': function(collection, property, values) {
		return _.filter(collection, function(item) {
			return _.contains(values, item[property]);
		});
	}
});

/**
 * Request the data to Trello to create the newsletter
 * @param {object} configuration Configuration for the job
 * @param {object} paths Paths of the module and executation
 * @param {function} callback Async callback
 */
function init(configuration, paths, callback) {

	//Create a new instance of Trello
	var t = new Trello(configuration.config.trello.key, configuration.config.trello.token);

	//Get all information in parallel
	async.parallel({

		//Get the list information
		lists: function(next) {
			_getLists(t, configuration, next);
		},

		//Get extra infomation to show
		extras: function(next) {
			_getExtras(t, configuration, next);
		}

	}, function(err, data) {

		//Next
		callback(err, data);

	});

}

/**
 * Get the lists information of the board
 * @param  {function}  t  Trello instance
 * @param  {object} configuration Configuration for the job
 * @param  {function}  next  Async callback
 */
function _getLists(t, configuration, next) {

	//Params for the service
	var params = [
		'fields=name,pos',
		'cards=open',
		'card_fields=name,labels,pos,desc,idMembers,idAttachmentCover,url'
	];

	//Get the lists of the board
	t.get('/1/boards/' + configuration.config.trello.board + '/lists?' + params.join('&'), function(err, data) {

		//Check errors
		if (err) {

			next(new Error('There was an error getting the information from Trello: ' + err));

			//Else, read the data
		} else {

			//Check if there are data
			if (!data.length) {

				next(new Error('The Trello board doesn\'t have information to use'));

				//Process the information
			} else {

				//Next!
				next(null, data);

			}

		}

	});

}

/**
 * Get extra information of the cards
 * @param  {function}  t  Trello instance
 * @param  {object} configuration Configuration for the job
 * @param  {function}  next  Async callback
 */
function _getExtras(t, configuration, next) {

	//Params for the service
	var params = [
		'attachments=cover',
		'attachment_fields=previews,url',
		'members=true',
		'member_fields=initials,avatarHash,fullName',
		'fields=name'
	];

	//Get the lists of the board
	t.get('/1/boards/' + configuration.config.trello.board + '/cards?' + params.join('&'), function(err, data) {

		//Check errors
		if (err) {

			next(new Error('There was an error getting the information from Trello: ' + err));

			//Else, read the data
		} else {

			//Check if there are data
			if (!data.length) {

				next(new Error('The Trello board doesn\'t have information to use'));

				//Process the information
			} else {

				//Next!
				next(null, data);

			}

		}

	});

}

/**
 * Public methods exported
 */
module.exports = {
	init: init
};
<commit_msg>Get the username<commit_after>'use strict';

/**
 * Global modules
 */
var async = require('async');
var Trello = require('node-trello');
var _ = require('lodash');

/**
 * Custom mixin for lodash
 */
_.mixin({
	'findByValues': function(collection, property, values) {
		return _.filter(collection, function(item) {
			return _.contains(values, item[property]);
		});
	}
});

/**
 * Request the data to Trello to create the newsletter
 * @param {object} configuration Configuration for the job
 * @param {object} paths Paths of the module and executation
 * @param {function} callback Async callback
 */
function init(configuration, paths, callback) {

	//Create a new instance of Trello
	var t = new Trello(configuration.config.trello.key, configuration.config.trello.token);

	//Get all information in parallel
	async.parallel({

		//Get the list information
		lists: function(next) {
			_getLists(t, configuration, next);
		},

		//Get extra infomation to show
		extras: function(next) {
			_getExtras(t, configuration, next);
		}

	}, function(err, data) {

		//Next
		callback(err, data);

	});

}

/**
 * Get the lists information of the board
 * @param  {function}  t  Trello instance
 * @param  {object} configuration Configuration for the job
 * @param  {function}  next  Async callback
 */
function _getLists(t, configuration, next) {

	//Params for the service
	var params = [
		'fields=name,pos',
		'cards=open',
		'card_fields=name,labels,pos,desc,idMembers,idAttachmentCover,url'
	];

	//Get the lists of the board
	t.get('/1/boards/' + configuration.config.trello.board + '/lists?' + params.join('&'), function(err, data) {

		//Check errors
		if (err) {

			next(new Error('There was an error getting the information from Trello: ' + err));

			//Else, read the data
		} else {

			//Check if there are data
			if (!data.length) {

				next(new Error('The Trello board doesn\'t have information to use'));

				//Process the information
			} else {

				//Next!
				next(null, data);

			}

		}

	});

}

/**
 * Get extra information of the cards
 * @param  {function}  t  Trello instance
 * @param  {object} configuration Configuration for the job
 * @param  {function}  next  Async callback
 */
function _getExtras(t, configuration, next) {

	//Params for the service
	var params = [
		'attachments=cover',
		'attachment_fields=previews,url',
		'members=true',
		'member_fields=initials,avatarHash,fullName,username',
		'fields=name'
	];

	//Get the lists of the board
	t.get('/1/boards/' + configuration.config.trello.board + '/cards?' + params.join('&'), function(err, data) {

		//Check errors
		if (err) {

			next(new Error('There was an error getting the information from Trello: ' + err));

			//Else, read the data
		} else {

			//Check if there are data
			if (!data.length) {

				next(new Error('The Trello board doesn\'t have information to use'));

				//Process the information
			} else {

				//Next!
				next(null, data);

			}

		}

	});

}

/**
 * Public methods exported
 */
module.exports = {
	init: init
};
<|endoftext|>


<commit_before>/*
 * Copyright 2013 The Polymer Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style
 * license that can be found in the LICENSE file.
 */
(function() {

  var log = window.logFlags || {};

  // bind a property in A to a path in B by converting A[property] to a
  // getter/setter pair that accesses B[...path...]
  function bindProperties(inA, inProperty, inB, inPath) {
    log.bind && console.log("[%s]: bindProperties: [%s] to [%s].[%s]",
        inB.localName || 'object', inPath, inA.localName, inProperty);
    // capture A's value if B's value is null or undefined,
    // otherwise use B's value
    var v = PathObserver.getValueAtPath(inB, inPath);
    if (v == null || v === undefined) {
      PathObserver.setValueAtPath(inB, inPath, inA[inProperty]);
    }
    // redefine A's property as an accessor on path in B
    Object.defineProperty(inA, inProperty, {
      get: function() {
        return PathObserver.getValueAtPath(inB, inPath);
      },
      set: function(inValue) {
        PathObserver.setValueAtPath(inB, inPath, inValue);
      },
      configurable: true,
      enumerable: true
    });
  }

  // exports
  Polymer.bindProperties = bindProperties;

})();<commit_msg>to be overwritten, value must be strictly null, not nullish<commit_after>/*
 * Copyright 2013 The Polymer Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style
 * license that can be found in the LICENSE file.
 */
(function() {

  var log = window.logFlags || {};

  // bind a property in A to a path in B by converting A[property] to a
  // getter/setter pair that accesses B[...path...]
  function bindProperties(inA, inProperty, inB, inPath) {
    log.bind && console.log("[%s]: bindProperties: [%s] to [%s].[%s]",
        inB.localName || 'object', inPath, inA.localName, inProperty);
    // capture A's value if B's value is null or undefined,
    // otherwise use B's value
    var v = PathObserver.getValueAtPath(inB, inPath);
    if (v === null || v === undefined) {
      PathObserver.setValueAtPath(inB, inPath, inA[inProperty]);
    }
    // redefine A's property as an accessor on path in B
    Object.defineProperty(inA, inProperty, {
      get: function() {
        return PathObserver.getValueAtPath(inB, inPath);
      },
      set: function(inValue) {
        PathObserver.setValueAtPath(inB, inPath, inValue);
      },
      configurable: true,
      enumerable: true
    });
  }

  // exports
  Polymer.bindProperties = bindProperties;

})();<|endoftext|>


<commit_before>import {
  updateInventory,
  addInventoryItem,
  removeInventoryItem,
  selectItem,
} from '../../../ui';
import { clamp, REALLY_BIG_NUMBER, clone } from '../../../utils';

import PineCone from '../../object/PineCone';

export default class Inventory {
  constructor(game) {
    this.game = game;

    this.money = {
      value: 0,
      max: REALLY_BIG_NUMBER,
    };

    this.items = {
      'wood-axe': {
        value: true,
        sellable: false,
        selected: true,
      },
      bucket: {
        value: false,
        sellable: false,
        selected: false,
      },
      water: {
        value: 0,
        max: 15,
        sellable: false,
        selected: null,
      },
      log: {
        value: 0,
        max: 10,
        sellable: true,
        selected: null,
      },
      'pine-cone': {
        value: 0,
        max: 100,
        sellable: true,
        selected: false,
        place: PineCone,
      },
    };

    setupObj = setupObj.bind(this);

    setupObj(this.items);
    setupObj(this.money, 'money');

    // add items we started with to ui
    for (let itemName in this.items) {
      let value = this.items[itemName].value;

      if (value === false || value <= 0) continue;

      value = typeof value === 'boolean' ? undefined : value;

      const { sellable, selected } = this.items[itemName];

      addInventoryItem.call(this, itemName, value, sellable, selected);
    }

    this.seek = this.seek.bind(this);
  }

  get selected() {
    for (let name in this.items) {
      if (this.items[name].selected) return name;
    }
  }

  select(id) {
    if (this.items[id].selected || this.items[id].selected === null) return; // already selected or not selectable

    for (let name in this.items) {
      let item = this.items[name];

      if (!item.selected) continue;

      item.selected = false;
    }

    this.items[id].selected = true;
  }

  seek(direction) {
    const names = Object.keys(this.items).filter(function(itemName) {
      let item = this.items[itemName];

      return item.selected !== null && (item.value > 0 || item.value === true);
    }.bind(this));

    let i = names.indexOf(this.selected) + (direction === 'next' ? 1 : -1);
    i = wrap(i, names.length);

    const newName = names[i];

    this.select(newName);
  }
}

function wrap(value, length) {
  if (value < 0) return length - 1;
  if (value >= length) return 0;
  return value;
}

// set 'values' prop to read/write (clamped to max if present) and all other props to read only
function setupObj(obj, objName) {
  processObject = processObject.bind(this);

  if (objName === undefined) {
    const itemNames = Object.keys(obj);

    for (let i = 0; i < itemNames.length; i++) {
      processObject(obj[itemNames[i]], itemNames[i]);
    }
  } else {
    processObject(obj, objName);
  }

  function processObject(item, itemName) {
    for (let keyName in item) {
      if (keyName === 'value' || keyName === 'selected') { // TODO make work with selected too
        readWriteKey.call(this, item, itemName, keyName);
      } else {
        readKey(item, keyName);
      }
    }

    Object.defineProperty(item, 'isMax', { get: isMax.bind(item) });
  }
}

function isMax() {
  let maxed = false;

  const { value, max } = this;

  const type = typeof value;

  if (type === 'number') {
    maxed = value >= max;
  } else if (type === 'boolean') {
    maxed = value;
  }

  return maxed;
}

// sets up a getter-setter for 'value' prop, clamping it to obj.max
function readWriteKey(obj, itemName, keyName) {
  const privName = '_' + keyName;

  obj[privName] = obj[keyName];
  delete obj[keyName];

  Object.defineProperty(obj, keyName, {
    get: function() { return this[privName]; }.bind(obj),
    set: function(name, self, value) {
      if (typeof this[privName] !== 'number') {
        this[privName] = value;
      } else {
        this[privName] = clamp(value, 0, this.max || REALLY_BIG_NUMBER);
      }

      switch (keyName) {
        case 'value': {
          if (this[privName] <= 0 || this[privName] === false) {
            removeInventoryItem(name);

            self.select('wood-axe'); // default back to wood-axe
          } else {
            updateInventory.call(self, name, this[privName], this.sellable);
          }
          break;
        }
        case 'selected': {
          selectItem(name, this[privName]);
          break;
        }
      }
    }.bind(obj, itemName, this),
  });
}

// sets up a getter only for 'key' prop, making it read-only
function readKey(obj, keyName) {
  const oldKeyValue = obj[keyName];

  delete obj[keyName];

  Object.defineProperty(obj, keyName, {
    get: function() { return oldKeyValue; },
  });
}
<commit_msg>Add extra inventory if testing<commit_after>import {
  updateInventory,
  addInventoryItem,
  removeInventoryItem,
  selectItem,
} from '../../../ui';
import { clamp, REALLY_BIG_NUMBER, clone } from '../../../utils';
import config from '../../../config';

import PineCone from '../../object/PineCone';

export default class Inventory {
  constructor(game) {
    this.game = game;

    this.money = {
      value: 0,
      max: REALLY_BIG_NUMBER,
    };

    this.items = {
      'wood-axe': {
        value: true,
        sellable: false,
        selected: true,
      },
      bucket: {
        value: false,
        sellable: false,
        selected: false,
      },
      water: {
        value: 0,
        max: 15,
        sellable: false,
        selected: null,
      },
      log: {
        value: 0,
        max: config.test ? 1000 : 10,
        sellable: true,
        selected: null,
      },
      'pine-cone': {
        value: config.test ? 100 : 0,
        max: 100,
        sellable: true,
        selected: false,
        place: PineCone,
      },
    };

    setupObj = setupObj.bind(this);

    setupObj(this.items);
    setupObj(this.money, 'money');

    // add items we started with to ui
    for (let itemName in this.items) {
      let value = this.items[itemName].value;

      if (value === false || value <= 0) continue;

      value = typeof value === 'boolean' ? undefined : value;

      const { sellable, selected } = this.items[itemName];

      addInventoryItem.call(this, itemName, value, sellable, selected);
    }

    this.seek = this.seek.bind(this);
  }

  get selected() {
    for (let name in this.items) {
      if (this.items[name].selected) return name;
    }
  }

  select(id) {
    if (this.items[id].selected || this.items[id].selected === null) return; // already selected or not selectable

    for (let name in this.items) {
      let item = this.items[name];

      if (!item.selected) continue;

      item.selected = false;
    }

    this.items[id].selected = true;
  }

  seek(direction) {
    const names = Object.keys(this.items).filter(function(itemName) {
      let item = this.items[itemName];

      return item.selected !== null && (item.value > 0 || item.value === true);
    }.bind(this));

    let i = names.indexOf(this.selected) + (direction === 'next' ? 1 : -1);
    i = wrap(i, names.length);

    const newName = names[i];

    this.select(newName);
  }
}

function wrap(value, length) {
  if (value < 0) return length - 1;
  if (value >= length) return 0;
  return value;
}

// set 'values' prop to read/write (clamped to max if present) and all other props to read only
function setupObj(obj, objName) {
  processObject = processObject.bind(this);

  if (objName === undefined) {
    const itemNames = Object.keys(obj);

    for (let i = 0; i < itemNames.length; i++) {
      processObject(obj[itemNames[i]], itemNames[i]);
    }
  } else {
    processObject(obj, objName);
  }

  function processObject(item, itemName) {
    for (let keyName in item) {
      if (keyName === 'value' || keyName === 'selected') { // TODO make work with selected too
        readWriteKey.call(this, item, itemName, keyName);
      } else {
        readKey(item, keyName);
      }
    }

    Object.defineProperty(item, 'isMax', { get: isMax.bind(item) });
  }
}

function isMax() {
  let maxed = false;

  const { value, max } = this;

  const type = typeof value;

  if (type === 'number') {
    maxed = value >= max;
  } else if (type === 'boolean') {
    maxed = value;
  }

  return maxed;
}

// sets up a getter-setter for 'value' prop, clamping it to obj.max
function readWriteKey(obj, itemName, keyName) {
  const privName = '_' + keyName;

  obj[privName] = obj[keyName];
  delete obj[keyName];

  Object.defineProperty(obj, keyName, {
    get: function() { return this[privName]; }.bind(obj),
    set: function(name, self, value) {
      if (typeof this[privName] !== 'number') {
        this[privName] = value;
      } else {
        this[privName] = clamp(value, 0, this.max || REALLY_BIG_NUMBER);
      }

      switch (keyName) {
        case 'value': {
          if (this[privName] <= 0 || this[privName] === false) {
            removeInventoryItem(name);

            self.select('wood-axe'); // default back to wood-axe
          } else {
            updateInventory.call(self, name, this[privName], this.sellable);
          }
          break;
        }
        case 'selected': {
          selectItem(name, this[privName]);
          break;
        }
      }
    }.bind(obj, itemName, this),
  });
}

// sets up a getter only for 'key' prop, making it read-only
function readKey(obj, keyName) {
  const oldKeyValue = obj[keyName];

  delete obj[keyName];

  Object.defineProperty(obj, keyName, {
    get: function() { return oldKeyValue; },
  });
}
<|endoftext|>