<commit_before>/* --------------- JQUERY --------------- */
var shelfConfig = {
			active: false,
			collapsible: true,
			autoHeight: false,
			animated: "swing",
			heightStyle: "content"
	};
var shelfSectionConfig = {
			active: false,
			collapsible: true,
			autoHeight: false,
			animated: "swing"
	};

var currentShelfNumber = 0;
var currentShelfSectionNumber = 0;
var shelves = [];

var $parentAccordion;
var $accordionTemplate;

var $addSection;
var $addShelf;

$(document).ready(function () {

	$parentAccordion = $("#parentAccordion");
	$parentAccordion.accordion(shelfConfig);
	$accordionTemplate = $(".accordion").children();

	$addSection = $("#addSection");
	$addShelf = $("#addShelf");

	$addSection.hide();

	// Add Shelf Button
	$addShelf.on("click", function (e) {
		e.preventDefault();

		// Create a shelf and append it to the parent accordion
		addShelfToArray( shelves );
		var $shelfElement = generateAccordion( currentShelfNumber, "shelf" );
		$parentAccordion.append($shelfElement);
		$parentAccordion.accordion("refresh");

		// Apply name to shelf
		var header = "#ui-accordion-parentAccordion-header-" + currentShelfNumber;
		var shelfDisplayNumber = currentShelfNumber + 1;
		$(header).text("Shelf " + shelfDisplayNumber);

		// Create an accordion element to hold shelf attributes
		var $attributesElement = generateAccordion(currentShelfNumber + 1, "section");
		var panel = "#ui-accordion-parentAccordion-panel-" + currentShelfNumber;
		$(panel).append($attributesElement);
		$(panel).accordion("refresh");

		// Apply content to shelf attribute accordion element
		var $attributesContent = generateAccordionContent(currentShelfNumber, "shelf", shelves);
		var attrHeader = "#ui-accordion-ui-accordion-parentAccordion-panel-" + currentShelfNumber + "-header-0";
		$(attrHeader).text("Shelf attributes");
		var attrContent = "#ui-accordion-ui-accordion-parentAccordion-panel-" + currentShelfNumber + "-panel-0";
		$(attrContent).append($attributesContent);

		addEditable( shelves, "shelf" );
		drawShelves( shelves, scale );

		manageSectionButton();
		currentShelfNumber++;
	});

	// Add section button
	$addSection.on("click", function (e) {
			e.preventDefault();

			var activeShelfNumber = $parentAccordion.accordion("option", "active");
			shelves[activeShelfNumber].sections.push( new sections() );
			var newSectionNumber = shelves[activeShelfNumber].sections.length;

			// Create a section and append it to a shelf
			var $shelfSectionElement = generateAccordion(activeShelfNumber + 1, "section");
			var panel = "#ui-accordion-parentAccordion-panel-" + activeShelfNumber;
			$(panel).append($shelfSectionElement);
			$(panel).accordion("refresh");

			// Apply a name to the section
			var innerHeader = "#ui-accordion-ui-accordion-parentAccordion-panel-" + activeShelfNumber + "-header-" + newSectionNumber;
			$(innerHeader).text("Section " + newSectionNumber);

			// Apply content to the section
			var $contents = generateAccordionContent( activeShelfNumber, "section", shelves );
			var innerPanel = "#ui-accordion-ui-accordion-parentAccordion-panel-" + activeShelfNumber + "-panel-" + newSectionNumber;
			$(innerPanel).append($contents);

			addEditable( shelves, "section" );
			drawSections( activeShelfNumber, shelves, scale );
	});

});

function addEditable( shelves, type ) {
	if( type == "shelf" ){

		$(".notes").editable( function(value, settings) {
			var shelfIndex = $parentAccordion.accordion("option", "active");
			shelves[shelfIndex].notes = value;
			return value;
		});

		$(".uuid").editable( function(value, settings) {
			var shelfIndex = $parentAccordion.accordion("option", "active");
			shelves[shelfIndex].rpUUID = value;
			return value;
		});

	} else {

		$(".id").editable( function(value, settings) {
			var shelfIndex = $parentAccordion.accordion("option", "active");
			var panel = "#ui-accordion-parentAccordion-panel-" + shelfIndex;
			var sectionIndex = $(panel).accordion("option", "active");
			shelves[shelfIndex].sections[sectionIndex - 1].displayID = value;
			return value;
		});

		$(".color").editable( function(value, settings) {
			var shelfIndex = $parentAccordion.accordion("option", "active");
			var panel = "#ui-accordion-parentAccordion-panel-" + shelfIndex;
			var sectionIndex = $(panel).accordion("option", "active");
			shelves[shelfIndex].sections[sectionIndex - 1].displayColor = value;
			return value;
		});

		$(".motion").editable( function(value, settings) {
			var shelfIndex = $parentAccordion.accordion("option", "active");
			var panel = "#ui-accordion-parentAccordion-panel-" + shelfIndex;
			var sectionIndex = $(panel).accordion("option", "active");
			shelves[shelfIndex].sections[sectionIndex - 1].pirURL = value;
			return value;
		});

		$(".stock").editable( function(value, settings) {
			var shelfIndex = $parentAccordion.accordion("option", "active");
			var panel = "#ui-accordion-parentAccordion-panel-" + shelfIndex;
			var sectionIndex = $(panel).accordion("option", "active");
			shelves[shelfIndex].sections[sectionIndex - 1].pintURL = value;
			return value;
		});

	}
}

function shelf() {
	this.shelfName;
	this.notes;
	this.rpUUID;
	this.sections = [];
	return;
}

function sections() {
	this.sectionName = "Default Section name";
	this.displayId;
	this.displayColor;
	this.pirURL;
	this.pintURL;
	return;
}

function getAccordionTemplate() {
		 return $accordionTemplate.clone();
}

function generateAccordion( number, accordionType ) {
		var $accordion = getAccordionTemplate();
		var $accordionWithEvents = attachAccordionEvents( $accordion, accordionType );
		return $accordionWithEvents;
}

function generateAccordionContent( shelfIndex, accordionType, shelvesArray ) {
		var $accordionContent = $(document.createElement("ul"));
		if ( accordionType == "shelf" ) {
			$accordionContent.append($("
").append("Notes: <span class=\"input notes\"" + shelvesArray[shelfIndex].notes + ""));
			$accordionContent.append($("
").append("RasPi UUID: <span class=\"input uuid\"" + shelvesArray[shelfIndex].rpUUID + ""));
		}else {
			var sectionIndex = shelvesArray[shelfIndex].sections.length - 1;
			$accordionContent.append($("
").append("ID: <span class=\"input id\"" + shelvesArray[shelfIndex].sections[sectionIndex].displayId + ""));
			$accordionContent.append($("
").append("Color: <span class=\"input color\"" + shelvesArray[shelfIndex].sections[sectionIndex].displayColor + ""));
			$accordionContent.append($("
").append("Motion sensor: <span class=\"input motion\"" + shelvesArray[shelfIndex].sections[sectionIndex].pirURL + ""));
			$accordionContent.append($("
").append("Stock sensor: <span class=\"input stock\"" + shelvesArray[shelfIndex].sections[sectionIndex].pintURL + ""));
		}

		return $accordionContent;
}

function attachAccordionEvents( $accordionElement, accordionType ) {
		if (accordionType == "shelf") {
				$accordionElement.accordion(shelfConfig);
		} else {
				$accordionElement.accordion(shelfSectionConfig);
		}

		return $accordionElement;
}

// change
function manageSectionButton() {
		if ( $parentAccordion.children().length > 0 ) {
				$addSection.show();
		} else {
				$addSection.hide();
		}
}

function addShelfToArray( shelvesArray ) {
	shelvesArray.push( new shelf );
	return;
}

/* --------------- D3 --------------- */
var svg;
// look at viewbox example here: http://jsfiddle.net/NKRPe/60/
var w = 808;
var h = w*2/3;
var strokePadding = 1;
var domainSize = 1;

/* Scale needs its domain to size the current of shelves + blank aisles, so update
the scale domain anytime a shelf is added */
var scale = d3.scale.linear()
	.domain([0,1])
	.rangeRound([0,w]);

$(document).ready( function() {
	svg = d3.select('#d3').append("svg")
		.attr("width", w)
		.attr("height", h);
});

function drawShelves(shelves, scale){
	domainSize++;
	scale.domain([0,domainSize])
	// Move exisiting shelves and sections
	svg.transition().selectAll(".shelf")
			.duration(500)
			.attr("x", function(d,i) {
				return scale(i+1);
			});
	for(var i=0; i<shelves.length; i++){
		var selector = ".s" + i;
		svg.transition().selectAll(selector)
		.duration(500)
		.attr("x", function() {
			return scale(i+1) + 5;
		});
	}

	// Add the newest shelf
	svg.selectAll(".shelf").data(shelves).enter().append("rect")
		.attr("x", w+100) // initialize out of frame, then slide in
		.attr("y", strokePadding)
		.attr("rx", 5)
		.attr("ry", 5)
		.attr("width", 50)
		.attr("height", 500)
		.attr("fill", "#E1EFF5")
		.attr("stroke",  "#2E6E9E")
		.attr("stroke-width", strokePadding)
		.attr("class", "shelf")
		.transition()
		.duration(500)
		.attr("x", function(d,i) {
			return scale(i+1);
		});
}

function drawSections(shelfIndex, shelves, scale){

	var selector = ".s" + shelfIndex;

	var sectionScale = d3.scale.linear()
		.domain([0, shelves[shelfIndex].sections.length])
		.range([0,495]);

	svg.transition().selectAll(selector)
		.duration(500)
		.attr("y", function(d,i) {
			return sectionScale(i) + 5;
		})
		.attr("height", function(d,i) {
			return 495/shelves[shelfIndex].sections.length - 5;
		});

	// Add new sections
	svg.selectAll(selector).data(shelves[shelfIndex].sections).enter().append("rect")
		.attr("x", function() {
			return scale(shelfIndex+1) + 5;
		})
		.attr("y", function(d,i) {
			return sectionScale(i) + 5;
		})
		.attr("width", 40) // probably need to change the sizes
		.attr("height", function(d,i) {
			return 495/shelves[shelfIndex].sections.length - 5;
		})
		.attr("rx", 5)
		.attr("ry", 5)
		.attr("fill", "#2E6E9E")
		.attr("class", "section s" + shelfIndex)
		.attr("opacity", 0)
		// Open accordion associated with this element when clicked
		.on("click", function(d, i) {
			$parentAccordion.accordion('option', 'active', shelfIndex);
			var panel = "#ui-accordion-parentAccordion-panel-" + shelfIndex;
			var sectionIndex = $(panel).accordion("option", "active", i + 1);
		})
		.transition()
		.attr("opacity", 1)
		.duration(500);
}<commit_msg>Changed cursor to pointer when you hover over a selectable section<commit_after>/* --------------- JQUERY --------------- */
var shelfConfig = {
			active: false,
			collapsible: true,
			autoHeight: false,
			animated: "swing",
			heightStyle: "content"
	};
var shelfSectionConfig = {
			active: false,
			collapsible: true,
			autoHeight: false,
			animated: "swing"
	};

var currentShelfNumber = 0;
var currentShelfSectionNumber = 0;
var shelves = [];

var $parentAccordion;
var $accordionTemplate;

var $addSection;
var $addShelf;

$(document).ready(function () {

	$parentAccordion = $("#parentAccordion");
	$parentAccordion.accordion(shelfConfig);
	$accordionTemplate = $(".accordion").children();

	$addSection = $("#addSection");
	$addShelf = $("#addShelf");

	$addSection.hide();

	// Add Shelf Button
	$addShelf.on("click", function (e) {
		e.preventDefault();

		// Create a shelf and append it to the parent accordion
		addShelfToArray( shelves );
		var $shelfElement = generateAccordion( currentShelfNumber, "shelf" );
		$parentAccordion.append($shelfElement);
		$parentAccordion.accordion("refresh");

		// Apply name to shelf
		var header = "#ui-accordion-parentAccordion-header-" + currentShelfNumber;
		var shelfDisplayNumber = currentShelfNumber + 1;
		$(header).text("Shelf " + shelfDisplayNumber);

		// Create an accordion element to hold shelf attributes
		var $attributesElement = generateAccordion(currentShelfNumber + 1, "section");
		var panel = "#ui-accordion-parentAccordion-panel-" + currentShelfNumber;
		$(panel).append($attributesElement);
		$(panel).accordion("refresh");

		// Apply content to shelf attribute accordion element
		var $attributesContent = generateAccordionContent(currentShelfNumber, "shelf", shelves);
		var attrHeader = "#ui-accordion-ui-accordion-parentAccordion-panel-" + currentShelfNumber + "-header-0";
		$(attrHeader).text("Shelf attributes");
		var attrContent = "#ui-accordion-ui-accordion-parentAccordion-panel-" + currentShelfNumber + "-panel-0";
		$(attrContent).append($attributesContent);

		addEditable( shelves, "shelf" );
		drawShelves( shelves, scale );

		manageSectionButton();
		currentShelfNumber++;
	});

	// Add section button
	$addSection.on("click", function (e) {
			e.preventDefault();

			var activeShelfNumber = $parentAccordion.accordion("option", "active");
			shelves[activeShelfNumber].sections.push( new sections() );
			var newSectionNumber = shelves[activeShelfNumber].sections.length;

			// Create a section and append it to a shelf
			var $shelfSectionElement = generateAccordion(activeShelfNumber + 1, "section");
			var panel = "#ui-accordion-parentAccordion-panel-" + activeShelfNumber;
			$(panel).append($shelfSectionElement);
			$(panel).accordion("refresh");

			// Apply a name to the section
			var innerHeader = "#ui-accordion-ui-accordion-parentAccordion-panel-" + activeShelfNumber + "-header-" + newSectionNumber;
			$(innerHeader).text("Section " + newSectionNumber);

			// Apply content to the section
			var $contents = generateAccordionContent( activeShelfNumber, "section", shelves );
			var innerPanel = "#ui-accordion-ui-accordion-parentAccordion-panel-" + activeShelfNumber + "-panel-" + newSectionNumber;
			$(innerPanel).append($contents);

			addEditable( shelves, "section" );
			drawSections( activeShelfNumber, shelves, scale );
	});

});

function addEditable( shelves, type ) {
	if( type == "shelf" ){

		$(".notes").editable( function(value, settings) {
			var shelfIndex = $parentAccordion.accordion("option", "active");
			shelves[shelfIndex].notes = value;
			return value;
		});

		$(".uuid").editable( function(value, settings) {
			var shelfIndex = $parentAccordion.accordion("option", "active");
			shelves[shelfIndex].rpUUID = value;
			return value;
		});

	} else {

		$(".id").editable( function(value, settings) {
			var shelfIndex = $parentAccordion.accordion("option", "active");
			var panel = "#ui-accordion-parentAccordion-panel-" + shelfIndex;
			var sectionIndex = $(panel).accordion("option", "active");
			shelves[shelfIndex].sections[sectionIndex - 1].displayID = value;
			return value;
		});

		$(".color").editable( function(value, settings) {
			var shelfIndex = $parentAccordion.accordion("option", "active");
			var panel = "#ui-accordion-parentAccordion-panel-" + shelfIndex;
			var sectionIndex = $(panel).accordion("option", "active");
			shelves[shelfIndex].sections[sectionIndex - 1].displayColor = value;
			return value;
		});

		$(".motion").editable( function(value, settings) {
			var shelfIndex = $parentAccordion.accordion("option", "active");
			var panel = "#ui-accordion-parentAccordion-panel-" + shelfIndex;
			var sectionIndex = $(panel).accordion("option", "active");
			shelves[shelfIndex].sections[sectionIndex - 1].pirURL = value;
			return value;
		});

		$(".stock").editable( function(value, settings) {
			var shelfIndex = $parentAccordion.accordion("option", "active");
			var panel = "#ui-accordion-parentAccordion-panel-" + shelfIndex;
			var sectionIndex = $(panel).accordion("option", "active");
			shelves[shelfIndex].sections[sectionIndex - 1].pintURL = value;
			return value;
		});

	}
}

function shelf() {
	this.shelfName;
	this.notes;
	this.rpUUID;
	this.sections = [];
	return;
}

function sections() {
	this.sectionName = "Default Section name";
	this.displayId;
	this.displayColor;
	this.pirURL;
	this.pintURL;
	return;
}

function getAccordionTemplate() {
		 return $accordionTemplate.clone();
}

function generateAccordion( number, accordionType ) {
		var $accordion = getAccordionTemplate();
		var $accordionWithEvents = attachAccordionEvents( $accordion, accordionType );
		return $accordionWithEvents;
}

function generateAccordionContent( shelfIndex, accordionType, shelvesArray ) {
		var $accordionContent = $(document.createElement("ul"));
		if ( accordionType == "shelf" ) {
			$accordionContent.append($("
").append("Notes: <span class=\"input notes\"" + shelvesArray[shelfIndex].notes + ""));
			$accordionContent.append($("
").append("RasPi UUID: <span class=\"input uuid\"" + shelvesArray[shelfIndex].rpUUID + ""));
		}else {
			var sectionIndex = shelvesArray[shelfIndex].sections.length - 1;
			$accordionContent.append($("
").append("ID: <span class=\"input id\"" + shelvesArray[shelfIndex].sections[sectionIndex].displayId + ""));
			$accordionContent.append($("
").append("Color: <span class=\"input color\"" + shelvesArray[shelfIndex].sections[sectionIndex].displayColor + ""));
			$accordionContent.append($("
").append("Motion sensor: <span class=\"input motion\"" + shelvesArray[shelfIndex].sections[sectionIndex].pirURL + ""));
			$accordionContent.append($("
").append("Stock sensor: <span class=\"input stock\"" + shelvesArray[shelfIndex].sections[sectionIndex].pintURL + ""));
		}

		return $accordionContent;
}

function attachAccordionEvents( $accordionElement, accordionType ) {
		if (accordionType == "shelf") {
				$accordionElement.accordion(shelfConfig);
		} else {
				$accordionElement.accordion(shelfSectionConfig);
		}

		return $accordionElement;
}

// change
function manageSectionButton() {
		if ( $parentAccordion.children().length > 0 ) {
				$addSection.show();
		} else {
				$addSection.hide();
		}
}

function addShelfToArray( shelvesArray ) {
	shelvesArray.push( new shelf );
	return;
}

/* --------------- D3 --------------- */
var svg;
// look at viewbox example here: http://jsfiddle.net/NKRPe/60/
var w = 808;
var h = w*2/3;
var strokePadding = 1;
var domainSize = 1;

/* Scale needs its domain to size the current of shelves + blank aisles, so update
the scale domain anytime a shelf is added */
var scale = d3.scale.linear()
	.domain([0,1])
	.rangeRound([0,w]);

$(document).ready( function() {
	svg = d3.select('#d3').append("svg")
		.attr("width", w)
		.attr("height", h);
});

function drawShelves(shelves, scale){
	domainSize++;
	scale.domain([0,domainSize])
	// Move exisiting shelves and sections
	svg.transition().selectAll(".shelf")
			.duration(500)
			.attr("x", function(d,i) {
				return scale(i+1);
			});
	for(var i=0; i<shelves.length; i++){
		var selector = ".s" + i;
		svg.transition().selectAll(selector)
		.duration(500)
		.attr("x", function() {
			return scale(i+1) + 5;
		});
	}

	// Add the newest shelf
	svg.selectAll(".shelf").data(shelves).enter().append("rect")
		.attr("x", w+100) // initialize out of frame, then slide in
		.attr("y", strokePadding)
		.attr("rx", 5)
		.attr("ry", 5)
		.attr("width", 50)
		.attr("height", 500)
		.attr("fill", "#E1EFF5")
		.attr("stroke",  "#2E6E9E")
		.attr("stroke-width", strokePadding)
		.attr("class", "shelf")
		.transition()
		.duration(500)
		.attr("x", function(d,i) {
			return scale(i+1);
		});
}

function drawSections(shelfIndex, shelves, scale){

	var selector = ".s" + shelfIndex;

	var sectionScale = d3.scale.linear()
		.domain([0, shelves[shelfIndex].sections.length])
		.range([0,495]);

	svg.transition().selectAll(selector)
		.duration(500)
		.attr("y", function(d,i) {
			return sectionScale(i) + 5;
		})
		.attr("height", function(d,i) {
			return 495/shelves[shelfIndex].sections.length - 5;
		});

	// Add new sections
	svg.selectAll(selector).data(shelves[shelfIndex].sections).enter().append("rect")
		.attr("x", function() {
			return scale(shelfIndex+1) + 5;
		})
		.attr("y", function(d,i) {
			return sectionScale(i) + 5;
		})
		.attr("width", 40) // probably need to change the sizes
		.attr("height", function(d,i) {
			return 495/shelves[shelfIndex].sections.length - 5;
		})
		.attr("rx", 5)
		.attr("ry", 5)
		.attr("fill", "#2E6E9E")
		.attr("class", "section s" + shelfIndex)
		.attr("opacity", 0)
		// Open accordion associated with this element when clicked
		.attr("cursor", "pointer")
		.on("click", function(d, i) {
			$parentAccordion.accordion('option', 'active', shelfIndex);
			var panel = "#ui-accordion-parentAccordion-panel-" + shelfIndex;
			var sectionIndex = $(panel).accordion("option", "active", i + 1);
		})
		.transition()
		.attr("opacity", 1)
		.duration(500);
}<|endoftext|>


<commit_before>/*

	tdapp_controller_auth.js

*/
var tdapp = require('./tdapp');
var firebase = require('./tdapp_firebase');

//tdapp.controller("AuthCtrl",function($scope,$http,$cookies,$window,$timeout,appdata,TDMgr,Backend,Autologin,$firebaseAuth){
tdapp.controller("AuthCtrl",function($scope,$http,$cookies,$window,$timeout,appdata,TDMgr,Backend,Autologin){

	// Injection

	Autologin.setScope($scope);
	Backend.setScope($scope);

	// Login

	function gomain(){
		$timeout(function(){
			$window.location = "/#/main";
		},1000);
	}

	$scope.dologin = function(){
		$scope.errormsg = "";
		if($window.location.host=="localhost"){
			appdata.server = appdata.localserver;
		}
		if($scope.user==undefined){
			$scope.errormsg = "Login-Error: Enter a valid E-Mail-Adress and a valid password!";
			return;
		}
		firebase.auth().signInWithEmailAndPassword(
			$scope.user.email,
			$scope.user.password
		).then(
			function(data){
				appdata.fblogin = true;
				appdata.currentuser = data.email;
				var now = new Date();
				var exp = new Date(now.getFullYear(), now.getMonth()+1, now.getDate());
				$cookies.put(appdata.usercookie,appdata.currentuser,{expires:exp});
				data.getToken().then(function(token){
					// Create cookie
					var now = new Date();
					var exp = new Date(now.getFullYear(), now.getMonth()+1, now.getDate());
					$cookies.put(appdata.tokencookie,token,{expires:exp});
					// Modifiy headers
					$http.defaults.headers.common['Authorization'] = "Basic " + token;
					$scope.filtertag = 'All'; // set filtertag before calling Backend.getTodos()
					$scope.errormsg = "";
					gomain();
				});
			}
		).catch(function(error){
			$window.location = "/#/login";
			$scope.errormsg = "Login-Error: "+error.message;
			console.log($scope.errormsg);
			$scope.$apply();
		});
	}

	$scope.dologinWithGoogle = function(){
		var provider = new firebase.auth.GoogleAuthProvider();
		firebase.auth().signInWithPopup(provider).then(function(result){
			var token = result.credential.idToken;
			appdata.currentuser = result.user.email;
			appdata.fblogin = false;
			// Create cookie
			var now = new Date();
			var exp = new Date(now.getFullYear(), now.getMonth()+1, now.getDate());
			$cookies.put(appdata.tokencookie,token,{expires:exp});
			$cookies.put(appdata.usercookie,appdata.currentuser,{expires:exp});
			// Modifiy headers
			$http.defaults.headers.common['Authorization'] = "Basic " + token;
			$scope.filtertag = 'All'; // set filtertag before calling Backend.getTodos()
			$scope.errormsg = "";
			gomain();
		}).catch(function(error){
			$scope.errormsg = "Login-Error: "+error.message;
			console.log($scope.errormsg);
			$scope.$apply();
		});
	}

	/* Old
	$scope.dologinWithGoogle = function(){
		var auth = $firebaseAuth();
		auth.$signInWithPopup("google").then(
			function(firebaseUser){
				console.log("Signed in as: ", firebaseUser.user.email);
				console.log("Credentials: ", firebaseUser.credential);
				$scope.email = firebaseUser.user.email;
				firebaseUser.user.getToken(false).then(function(idToken){
					console.log("Token: ", idToken);
					// Create cookie
					var now = new Date();
					var exp = new Date(now.getFullYear(), now.getMonth()+1, now.getDate());
					$cookies.put(appdata.cookiename,idToken,{expires:exp});
					// Modifiy headers
					$http.defaults.headers.common['Authorization'] = "Basic " + idToken;
					$scope.filtertag = 'All'; // set filtertag before calling Backend.getTodos()
					$scope.errormsg = "";
					gomain();
				});
			}
		).catch(function(error){
			$scope.errormsg = "Login-Error."
			console.log("Authentication failed: ", error);
		});
	}
	*/

	// Keyboard

	$scope.loginKeydown = function(e){
		var k = e.keyCode;
		if(k==13){//ret
			e.preventDefault();
			$scope.dologin();
		}
	}

	// Register

	$scope.showRegister = function(){
		$window.location = "/#/register";
	};

	// Finish

	$("#liusername").focus();

	Autologin.check(); // do automatic login if cookie/token is available
});
<commit_msg>Bugfix Google-Login<commit_after>/*

	tdapp_controller_auth.js

*/
var tdapp = require('./tdapp');
var firebase = require('./tdapp_firebase');

//tdapp.controller("AuthCtrl",function($scope,$http,$cookies,$window,$timeout,appdata,TDMgr,Backend,Autologin,$firebaseAuth){
tdapp.controller("AuthCtrl",function($scope,$http,$cookies,$window,$timeout,appdata,TDMgr,Backend,Autologin){

	// Injection

	Autologin.setScope($scope);
	Backend.setScope($scope);

	// Login

	function gomain(){
		$timeout(function(){
			$window.location = "/#/main";
		},1000);
	}

	$scope.dologin = function(){
		$scope.errormsg = "";
		if($window.location.host=="localhost"){
			appdata.server = appdata.localserver;
		}
		if($scope.user==undefined){
			$scope.errormsg = "Login-Error: Enter a valid E-Mail-Adress and a valid password!";
			return;
		}
		firebase.auth().signInWithEmailAndPassword(
			$scope.user.email,
			$scope.user.password
		).then(
			function(data){
				appdata.fblogin = true;
				appdata.currentuser = data.email;
				var now = new Date();
				var exp = new Date(now.getFullYear(), now.getMonth()+1, now.getDate());
				$cookies.put(appdata.usercookie,appdata.currentuser,{expires:exp});
				data.getToken().then(function(token){
					// Create cookie
					var now = new Date();
					var exp = new Date(now.getFullYear(), now.getMonth()+1, now.getDate());
					$cookies.put(appdata.tokencookie,token,{expires:exp});
					// Modifiy headers
					$http.defaults.headers.common['Authorization'] = "Basic " + token;
					$scope.filtertag = 'All'; // set filtertag before calling Backend.getTodos()
					$scope.errormsg = "";
					gomain();
				});
			}
		).catch(function(error){
			$window.location = "/#/login";
			$scope.errormsg = "Login-Error: "+error.message;
			console.log($scope.errormsg);
			$scope.$apply();
		});
	}

	$scope.dologinWithGoogle = function(){
		var provider = new firebase.auth.GoogleAuthProvider();
		firebase.auth().signInWithPopup(provider).then(function(result){
			appdata.currentuser = result.user.email;
			appdata.fblogin = false;
			firebase.auth().onAuthStateChanged(function(user){
				if(user){
					user.getToken().then(function(token){
						// Create cookie
						var now = new Date();
						var exp = new Date(now.getFullYear(), now.getMonth()+1, now.getDate());
						$cookies.put(appdata.tokencookie,token,{expires:exp});
						$cookies.put(appdata.usercookie,appdata.currentuser,{expires:exp});
						// Modifiy headers
						$http.defaults.headers.common['Authorization'] = "Basic " + token;
						$scope.filtertag = 'All'; // set filtertag before calling Backend.getTodos()
						$scope.errormsg = "";
						gomain();
					});
				}
			});
			/*
			var token = result.credential.idToken;
			appdata.currentuser = result.user.email;
			appdata.fblogin = false;
			// Create cookie
			var now = new Date();
			var exp = new Date(now.getFullYear(), now.getMonth()+1, now.getDate());
			$cookies.put(appdata.tokencookie,token,{expires:exp});
			$cookies.put(appdata.usercookie,appdata.currentuser,{expires:exp});
			// Modifiy headers
			$http.defaults.headers.common['Authorization'] = "Basic " + token;
			$scope.filtertag = 'All'; // set filtertag before calling Backend.getTodos()
			$scope.errormsg = "";
			gomain();
			*/
		}).catch(function(error){
			$scope.errormsg = "Login-Error: "+error.message;
			console.log($scope.errormsg);
			$scope.$apply();
		});
	}

	/* Old
	$scope.dologinWithGoogle = function(){
		var auth = $firebaseAuth();
		auth.$signInWithPopup("google").then(
			function(firebaseUser){
				console.log("Signed in as: ", firebaseUser.user.email);
				console.log("Credentials: ", firebaseUser.credential);
				$scope.email = firebaseUser.user.email;
				firebaseUser.user.getToken(false).then(function(idToken){
					console.log("Token: ", idToken);
					// Create cookie
					var now = new Date();
					var exp = new Date(now.getFullYear(), now.getMonth()+1, now.getDate());
					$cookies.put(appdata.cookiename,idToken,{expires:exp});
					// Modifiy headers
					$http.defaults.headers.common['Authorization'] = "Basic " + idToken;
					$scope.filtertag = 'All'; // set filtertag before calling Backend.getTodos()
					$scope.errormsg = "";
					gomain();
				});
			}
		).catch(function(error){
			$scope.errormsg = "Login-Error."
			console.log("Authentication failed: ", error);
		});
	}
	*/

	// Keyboard

	$scope.loginKeydown = function(e){
		var k = e.keyCode;
		if(k==13){//ret
			e.preventDefault();
			$scope.dologin();
		}
	}

	// Register

	$scope.showRegister = function(){
		$window.location = "/#/register";
	};

	// Finish

	$("#liusername").focus();

	Autologin.check(); // do automatic login if cookie/token is available
});
<|endoftext|>


<commit_before>"use strict";

var yeoman = require("yeoman-generator");
var incSay = require("incubator-say");
var util   = require("util");
var path   = require("path");

var IncubatorGenerator = module.exports = function IncubatorGenerator (args) {
	yeoman.generators.Base.apply(this, arguments);

	this.argument("appname", { type : String, required : false });
	this.appname = this.appname || path.basename(process.cwd());
	this.appname = this._.camelize(this._.slugify(this._.humanize(this.appname)));

	this.option("skip-welcome-message", {
		desc     : "Do not print out the welcome message.",
		type     : Boolean,
		defaults : true
	});

	this.option("skip-core", {
		desc     : "Skip core installation.",
		type     : Boolean,
		defaults : true
	});

	if (!this.options["skip-welcome-message"]) {
		this.log(incSay("Welcome to the Incubator Generator!"));
		this.log("By default I will create a Gruntfile and all dotfiles required to work");
		this.log("with the Bandwidth Incubator build pipeline.");
		this.log();
	}

	if (!this.options["skip-core"]) {
		this.invoke("incubator:core", args);
	}
};

util.inherits(IncubatorGenerator, yeoman.generators.Base);<commit_msg>Move greeting and invocation of sub generators to methods<commit_after>"use strict";

var yeoman = require("yeoman-generator");
var incSay = require("incubator-say");
var util   = require("util");
var path   = require("path");

var IncubatorGenerator = module.exports = function IncubatorGenerator () {
	yeoman.generators.Base.apply(this, arguments);

	this.argument("appname", { type : String, required : false });
	this.appname = this.appname || path.basename(process.cwd());
	this.appname = this._.camelize(this._.slugify(this._.humanize(this.appname)));

	this.option("skip-welcome-message", {
		desc : "Do not print out the welcome message.",
		type : Boolean
	});

	this.option("skip-core", {
		desc : "Skip core installation.",
		type : Boolean
	});
};

util.inherits(IncubatorGenerator, yeoman.generators.Base);

IncubatorGenerator.prototype.greeting = function greeting () {
	if (!this.options["skip-welcome-message"]) {
		this.log(incSay("Welcome to the Incubator Generator!"));
		this.log("By default I will create a Gruntfile and all dotfiles required to work");
		this.log("with the Bandwidth Incubator build pipeline.");
		this.log();
	}
};

IncubatorGenerator.prototype.components = function components () {
	if (!this.options["skip-core"]) {
		this.invoke("incubator:core", this.args);
	}
};<|endoftext|>


<commit_before>import { XMLSchema } from 'substance'
import JATS4RData from '../../tmp/JATS4R.data'

const JATS4R = XMLSchema.fromJSON(JATS4RData)

// TODO: this should come from compilation
JATS4R.getName = function() {
  return 'jats4r'
}

JATS4R.getVersion = function() {
  return '1.1'
}

JATS4R.getDocTypeParams = function() {
  return ['article', 'JATS4R 1.1', 'http://texture.substance.io/JATS4R-1.1.dtd']
}

export default JATS4R
<commit_msg>JATS4R -> JATS4M.<commit_after>import { XMLSchema } from 'substance'
import JATS4RData from '../../tmp/JATS4R.data'

const JATS4R = XMLSchema.fromJSON(JATS4RData)

// TODO: this should come from compilation
JATS4R.getName = function() {
  return 'jats4m'
}

JATS4R.getVersion = function() {
  return '1.1'
}

JATS4R.getDocTypeParams = function() {
  return ['article', 'JATS4M 1.1', 'http://texture.substance.io/JATS4M-1.1.dtd']
}

export default JATS4R
<|endoftext|>


<commit_before>require('ember-runtime/core');
require('ember-metal/expand_properties');

/**
@module ember
@submodule ember-runtime
*/

var a_slice = Array.prototype.slice;

if (Ember.FEATURES.isEnabled('propertyBraceExpansion')) {
  var expandProperties = Ember.expandProperties;
}

if (Ember.EXTEND_PROTOTYPES === true || Ember.EXTEND_PROTOTYPES.Function) {

  /**
    The `property` extension of Javascript's Function prototype is available
    when `Ember.EXTEND_PROTOTYPES` or `Ember.EXTEND_PROTOTYPES.Function` is
    `true`, which is the default.

    Computed properties allow you to treat a function like a property:

    ```javascript
    MyApp.President = Ember.Object.extend({
      firstName: '',
      lastName:  '',

      fullName: function() {
        return this.get('firstName') + ' ' + this.get('lastName');

        // Call this flag to mark the function as a property
      }.property()
    });

    var president = MyApp.President.create({
      firstName: "Barack",
      lastName: "Obama"
    });

    president.get('fullName');    // "Barack Obama"
    ```

    Treating a function like a property is useful because they can work with
    bindings, just like any other property.

    Many computed properties have dependencies on other properties. For
    example, in the above example, the `fullName` property depends on
    `firstName` and `lastName` to determine its value. You can tell Ember
    about these dependencies like this:

    ```javascript
    MyApp.President = Ember.Object.extend({
      firstName: '',
      lastName:  '',

      fullName: function() {
        return this.get('firstName') + ' ' + this.get('lastName');

        // Tell Ember.js that this computed property depends on firstName
        // and lastName
      }.property('firstName', 'lastName')
    });
    ```

    Make sure you list these dependencies so Ember knows when to update
    bindings that connect to a computed property. Changing a dependency
    will not immediately trigger an update of the computed property, but
    will instead clear the cache so that it is updated when the next `get`
    is called on the property.

    See [Ember.ComputedProperty](/api/classes/Ember.ComputedProperty.html), [Ember.computed](/api/#method_computed).

    @method property
    @for Function
  */
  Function.prototype.property = function() {
    var ret = Ember.computed(this);
    // ComputedProperty.prototype.property expands properties; no need for us to
    // do so here.
    return ret.property.apply(ret, arguments);
  };

  /**
    The `observes` extension of Javascript's Function prototype is available
    when `Ember.EXTEND_PROTOTYPES` or `Ember.EXTEND_PROTOTYPES.Function` is
    true, which is the default.

    You can observe property changes simply by adding the `observes`
    call to the end of your method declarations in classes that you write.
    For example:

    ```javascript
    Ember.Object.extend({
      valueObserver: function() {
        // Executes whenever the "value" property changes
      }.observes('value')
    });
    ```

    In the future this method may become asynchronous. If you want to ensure
    synchronous behavior, use `observesImmediately`.

    See `Ember.observer`.

    @method observes
    @for Function
  */
  Function.prototype.observes = function() {
    if (Ember.FEATURES.isEnabled('propertyBraceExpansion')) {
      var addWatchedProperty = function (obs) { watched.push(obs); };
      var watched = [];

      for (var i=0; i<arguments.length; ++i) {
        expandProperties(arguments[i], addWatchedProperty);
      }
    } else {
      this.__ember_observes__ = a_slice.call(arguments);
    }

    return this;
  };

  /**
    The `observesImmediately` extension of Javascript's Function prototype is
    available when `Ember.EXTEND_PROTOTYPES` or
    `Ember.EXTEND_PROTOTYPES.Function` is true, which is the default.

    You can observe property changes simply by adding the `observesImmediately`
    call to the end of your method declarations in classes that you write.
    For example:

    ```javascript
    Ember.Object.extend({
      valueObserver: function() {
        // Executes immediately after the "value" property changes
      }.observesImmediately('value')
    });
    ```

    In the future, `observes` may become asynchronous. In this event,
    `observesImmediately` will maintain the synchronous behavior.

    See `Ember.immediateObserver`.

    @method observesImmediately
    @for Function
  */
  Function.prototype.observesImmediately = function() {
    for (var i=0, l=arguments.length; i<l; i++) {
      var arg = arguments[i];
      Ember.assert("Immediate observers must observe internal properties only, not properties on other objects.", arg.indexOf('.') === -1);
    }

    // observes handles property expansion
    return this.observes.apply(this, arguments);
  };

  /**
    The `observesBefore` extension of Javascript's Function prototype is
    available when `Ember.EXTEND_PROTOTYPES` or
    `Ember.EXTEND_PROTOTYPES.Function` is true, which is the default.

    You can get notified when a property change is about to happen by
    by adding the `observesBefore` call to the end of your method
    declarations in classes that you write. For example:

    ```javascript
    Ember.Object.extend({
      valueObserver: function() {
        // Executes whenever the "value" property is about to change
      }.observesBefore('value')
    });
    ```

    See `Ember.beforeObserver`.

    @method observesBefore
    @for Function
  */
  Function.prototype.observesBefore = function() {
    if (Ember.FEATURES.isEnabled('propertyBraceExpansion')) {
      var addWatchedProperty = function (obs) { watched.push(obs); };
      var watched = [];

      for (var i=0; i<arguments.length; ++i) {
        expandProperties(arguments[i], addWatchedProperty);
      }

      this.__ember_observesBefore__ = watched;
    } else {
      this.__ember_observesBefore__ = a_slice.call(arguments);
    }

    return this;
  };

  /**
    The `on` extension of Javascript's Function prototype is available
    when `Ember.EXTEND_PROTOTYPES` or `Ember.EXTEND_PROTOTYPES.Function` is
    true, which is the default.

    You can listen for events simply by adding the `on` call to the end of
    your method declarations in classes or mixins that you write. For example:

    ```javascript
    Ember.Mixin.create({
      doSomethingWithElement: function() {
        // Executes whenever the "didInsertElement" event fires
      }.on('didInsertElement')
    });
    ```

    See `Ember.on`.

    @method on
    @for Function
  */
  Function.prototype.on = function() {
    var events = a_slice.call(arguments);
    this.__ember_listens__ = events;
    return this;
  };
}

<commit_msg>[FEATURE propertyBraceExpansion] Ensure __ember_observes__ is set properly.<commit_after>require('ember-runtime/core');
require('ember-metal/expand_properties');

/**
@module ember
@submodule ember-runtime
*/

var a_slice = Array.prototype.slice;

if (Ember.FEATURES.isEnabled('propertyBraceExpansion')) {
  var expandProperties = Ember.expandProperties;
}

if (Ember.EXTEND_PROTOTYPES === true || Ember.EXTEND_PROTOTYPES.Function) {

  /**
    The `property` extension of Javascript's Function prototype is available
    when `Ember.EXTEND_PROTOTYPES` or `Ember.EXTEND_PROTOTYPES.Function` is
    `true`, which is the default.

    Computed properties allow you to treat a function like a property:

    ```javascript
    MyApp.President = Ember.Object.extend({
      firstName: '',
      lastName:  '',

      fullName: function() {
        return this.get('firstName') + ' ' + this.get('lastName');

        // Call this flag to mark the function as a property
      }.property()
    });

    var president = MyApp.President.create({
      firstName: "Barack",
      lastName: "Obama"
    });

    president.get('fullName');    // "Barack Obama"
    ```

    Treating a function like a property is useful because they can work with
    bindings, just like any other property.

    Many computed properties have dependencies on other properties. For
    example, in the above example, the `fullName` property depends on
    `firstName` and `lastName` to determine its value. You can tell Ember
    about these dependencies like this:

    ```javascript
    MyApp.President = Ember.Object.extend({
      firstName: '',
      lastName:  '',

      fullName: function() {
        return this.get('firstName') + ' ' + this.get('lastName');

        // Tell Ember.js that this computed property depends on firstName
        // and lastName
      }.property('firstName', 'lastName')
    });
    ```

    Make sure you list these dependencies so Ember knows when to update
    bindings that connect to a computed property. Changing a dependency
    will not immediately trigger an update of the computed property, but
    will instead clear the cache so that it is updated when the next `get`
    is called on the property.

    See [Ember.ComputedProperty](/api/classes/Ember.ComputedProperty.html), [Ember.computed](/api/#method_computed).

    @method property
    @for Function
  */
  Function.prototype.property = function() {
    var ret = Ember.computed(this);
    // ComputedProperty.prototype.property expands properties; no need for us to
    // do so here.
    return ret.property.apply(ret, arguments);
  };

  /**
    The `observes` extension of Javascript's Function prototype is available
    when `Ember.EXTEND_PROTOTYPES` or `Ember.EXTEND_PROTOTYPES.Function` is
    true, which is the default.

    You can observe property changes simply by adding the `observes`
    call to the end of your method declarations in classes that you write.
    For example:

    ```javascript
    Ember.Object.extend({
      valueObserver: function() {
        // Executes whenever the "value" property changes
      }.observes('value')
    });
    ```

    In the future this method may become asynchronous. If you want to ensure
    synchronous behavior, use `observesImmediately`.

    See `Ember.observer`.

    @method observes
    @for Function
  */
  Function.prototype.observes = function() {
    if (Ember.FEATURES.isEnabled('propertyBraceExpansion')) {
      var addWatchedProperty = function (obs) { watched.push(obs); };
      var watched = [];

      for (var i=0; i<arguments.length; ++i) {
        expandProperties(arguments[i], addWatchedProperty);
      }

      this.__ember_observes__ = watched;
    } else {
      this.__ember_observes__ = a_slice.call(arguments);
    }

    return this;
  };

  /**
    The `observesImmediately` extension of Javascript's Function prototype is
    available when `Ember.EXTEND_PROTOTYPES` or
    `Ember.EXTEND_PROTOTYPES.Function` is true, which is the default.

    You can observe property changes simply by adding the `observesImmediately`
    call to the end of your method declarations in classes that you write.
    For example:

    ```javascript
    Ember.Object.extend({
      valueObserver: function() {
        // Executes immediately after the "value" property changes
      }.observesImmediately('value')
    });
    ```

    In the future, `observes` may become asynchronous. In this event,
    `observesImmediately` will maintain the synchronous behavior.

    See `Ember.immediateObserver`.

    @method observesImmediately
    @for Function
  */
  Function.prototype.observesImmediately = function() {
    for (var i=0, l=arguments.length; i<l; i++) {
      var arg = arguments[i];
      Ember.assert("Immediate observers must observe internal properties only, not properties on other objects.", arg.indexOf('.') === -1);
    }

    // observes handles property expansion
    return this.observes.apply(this, arguments);
  };

  /**
    The `observesBefore` extension of Javascript's Function prototype is
    available when `Ember.EXTEND_PROTOTYPES` or
    `Ember.EXTEND_PROTOTYPES.Function` is true, which is the default.

    You can get notified when a property change is about to happen by
    by adding the `observesBefore` call to the end of your method
    declarations in classes that you write. For example:

    ```javascript
    Ember.Object.extend({
      valueObserver: function() {
        // Executes whenever the "value" property is about to change
      }.observesBefore('value')
    });
    ```

    See `Ember.beforeObserver`.

    @method observesBefore
    @for Function
  */
  Function.prototype.observesBefore = function() {
    if (Ember.FEATURES.isEnabled('propertyBraceExpansion')) {
      var addWatchedProperty = function (obs) { watched.push(obs); };
      var watched = [];

      for (var i=0; i<arguments.length; ++i) {
        expandProperties(arguments[i], addWatchedProperty);
      }

      this.__ember_observesBefore__ = watched;
    } else {
      this.__ember_observesBefore__ = a_slice.call(arguments);
    }

    return this;
  };

  /**
    The `on` extension of Javascript's Function prototype is available
    when `Ember.EXTEND_PROTOTYPES` or `Ember.EXTEND_PROTOTYPES.Function` is
    true, which is the default.

    You can listen for events simply by adding the `on` call to the end of
    your method declarations in classes or mixins that you write. For example:

    ```javascript
    Ember.Mixin.create({
      doSomethingWithElement: function() {
        // Executes whenever the "didInsertElement" event fires
      }.on('didInsertElement')
    });
    ```

    See `Ember.on`.

    @method on
    @for Function
  */
  Function.prototype.on = function() {
    var events = a_slice.call(arguments);
    this.__ember_listens__ = events;
    return this;
  };
}

<|endoftext|>


<commit_before>/**
 * @license
 * Copyright 2018 The FOAM Authors. All Rights Reserved.
 * http://www.apache.org/licenses/LICENSE-2.0
 */

foam.CLASS({
  package: 'foam.nanos.dig',
  name: 'DUG',

  documentation: 'Data Update Gateway - DAO subscription notifcation service',

  javaImports: [
    'foam.dao.DAO',
    'foam.dao.HTTPSink',
    'foam.lib.json.Outputter',
    'foam.nanos.logger.Logger',
    'static foam.lib.json.OutputterMode.NETWORK'
  ],

  tableColumns: [
    'id',
    'daoKey',
    'format',
    'owner',
    'url'
  ],

  searchColumns: [],

  properties: [
    {
        class: 'String',
        name: 'id',
        displayWidth: 40
    },
    {
      class: 'String',
      name: 'daoKey',
      label: 'DAO',
      view: function(_, X) {
        var E = foam.mlang.Expressions.create();
        return foam.u2.view.ChoiceView.create({
          dao: X.nSpecDAO
            .where(E.ENDS_WITH(foam.nanos.boot.NSpec.ID, 'DAO'))
            .orderBy(foam.nanos.boot.NSpec.ID),
          objToChoice: function(nspec) {
            return [nspec.id, nspec.id];
          }
        });
      }
    },
    {
      class: 'Enum',
      of: 'foam.nanos.http.Format',
      name: 'format',
      // format hidden until implemented
      hidden: true
    },
    {
      class: 'Reference',
      of: 'foam.nanos.auth.User',
      name: 'owner',
      hidden: true
      // TODO: set tableCellRenderer
    },
    {
      class: 'URL',
      name: 'url',
      label: 'URL',
      displayWidth: 100
    }
  ],

  methods: [
    {
      name: 'execute',
      args: [
        {
          name: 'x',
          type: 'Context'
        }
      ],
      javaCode: `
        try {
          DAO dao = (DAO) x.get(getDaoKey());
          // TODO: choose outputter based on format
          dao.listen(new HTTPSink(getUrl(), foam.nanos.http.Format.JSON), null);
        } catch (Throwable t) {
          ((Logger) x.get("logger")).error("DUG", "error executing DUG", t);
        }
      `
    }
  ]
});
<commit_msg>Remove unserved DAOs from DUG list.<commit_after>/**
 * @license
 * Copyright 2018 The FOAM Authors. All Rights Reserved.
 * http://www.apache.org/licenses/LICENSE-2.0
 */

foam.CLASS({
  package: 'foam.nanos.dig',
  name: 'DUG',

  documentation: 'Data Update Gateway - DAO subscription notifcation service',

  javaImports: [
    'foam.dao.DAO',
    'foam.dao.HTTPSink',
    'foam.lib.json.Outputter',
    'foam.nanos.logger.Logger',
    'static foam.lib.json.OutputterMode.NETWORK'
  ],

  tableColumns: [
    'id',
    'daoKey',
    'format',
    'owner',
    'url'
  ],

  searchColumns: [],

  properties: [
    {
        class: 'String',
        name: 'id',
        displayWidth: 40
    },
    {
      class: 'String',
      name: 'daoKey',
      label: 'DAO',
      view: function(_, X) {
        var E = foam.mlang.Expressions.create();
        return foam.u2.view.ChoiceView.create({
          dao: X.nSpecDAO
            .where(E.ENDS_WITH(foam.nanos.boot.NSpec.ID, 'DAO'))
            .where(E.EQ(foam.nanos.boot.NSpec.SERVE, E.TRUE))
            .orderBy(foam.nanos.boot.NSpec.ID),
          objToChoice: function(nspec) {
            return [nspec.id, nspec.id];
          }
        });
      }
    },
    {
      class: 'Enum',
      of: 'foam.nanos.http.Format',
      name: 'format',
      // format hidden until implemented
      hidden: true
    },
    {
      class: 'Reference',
      of: 'foam.nanos.auth.User',
      name: 'owner',
      hidden: true
      // TODO: set tableCellRenderer
    },
    {
      class: 'URL',
      name: 'url',
      label: 'URL',
      displayWidth: 100
    }
  ],

  methods: [
    {
      name: 'execute',
      args: [
        {
          name: 'x',
          type: 'Context'
        }
      ],
      javaCode: `
        try {
          DAO dao = (DAO) x.get(getDaoKey());
          // TODO: choose outputter based on format
          dao.listen(new HTTPSink(getUrl(), foam.nanos.http.Format.JSON), null);
        } catch (Throwable t) {
          ((Logger) x.get("logger")).error("DUG", "error executing DUG", t);
        }
      `
    }
  ]
});
<|endoftext|>


<commit_before>(function(window, document, $) {
	var canvas = document.getElementById("game"),
		context = canvas.getContext("2d"),
		defaultColour = "#444",
		backgroundColour = "#eee";

	function rand(min, max) {
  		return Math.floor(Math.random() * (max - min)) + min;
	}

	function drawDinosaur(options) {
		var context = options.context,
			x = options.left,
			y = options.bottom;

		// background spacer
		context.fillStyle = backgroundColour;
		context.fillRect(x + 7, y - 14, 22, 18);

		// Dino!
		context.fillStyle = defaultColour;

		// tail
		context.fillRect(x, y - 36, 2, 16);
		context.fillRect(x + 2, y - 32, 2, 16);
		context.fillRect(x + 4, y - 30, 2, 16);
		context.fillRect(x + 6, y - 28, 2, 16);
		context.fillRect(x + 8, y - 28, 2, 18);
		context.fillRect(x + 10, y - 30, 2, 22);
		context.fillRect(x + 12, y - 32, 4, 26);
		context.fillRect(x + 16, y - 34, 4, 26);
		context.fillRect(x + 20, y - 36, 4, 30);
		context.fillRect(x + 24, y - 38, 2, 30);
		context.fillRect(x + 26, y - 38, 2, 28);
		context.fillRect(x + 28, y - 52, 2, 40);

		if (options.wideEyed) {
			context.fillRect(x + 30, y - 54, 6, 2);
			context.fillRect(x + 32, y - 50, 2, 2);
			context.fillRect(x + 30, y - 46, 2, 32);
			context.fillRect(x + 32, y - 46, 2, 30);
			context.fillRect(x + 34, y - 46, 2, 28);
			// context.fillRect(x + 32, y - 54, 2, 4);
			// context.fillRect(x + 32, y - 48, 2, 32);
			// context.fillRect(x + 34, y - 54, 2, 36);
		} else {
			context.fillRect(x + 30, y - 54, 2, 40);
			context.fillRect(x + 32, y - 54, 2, 4);
			context.fillRect(x + 32, y - 48, 2, 32);
			context.fillRect(x + 34, y - 54, 2, 36);
		}

		context.fillRect(x + 36, y - 54, 2, 34);
		context.fillRect(x + 38, y - 54, 2, 20);
		context.fillRect(x + 40, y - 54, 12, 16);
		context.fillRect(x + 52, y - 52, 2, 14);

		if (options.wideEyed) {
			context.fillRect(x + 38, y - 34, 8, 2);
		} else {
			context.fillRect(x + 40, y - 36, 8, 2);
		}

		// arm (singular)
		context.fillRect(x + 36, y - 26, 4, 2);
		context.fillRect(x + 40, y - 26, 2, 4);

		y = options.bottom;
		if (options.backLegUp) {
			y -= 4;
		}
		// back leg
		context.fillRect(x + 12, y, 4, 2);
		context.fillRect(x + 12, y - 6, 2, 8);
		context.fillRect(x + 14, y - 6, 2, 3);
		context.fillRect(x + 16, y - 8, 2, 3);

		y = options.bottom;
		if (options.frontLegUp) {
			y -= 6;
		}

		// front leg
		context.fillRect(x + 22, y, 4, 2);
		context.fillRect(x + 22, y - 6, 2, 8);
	}

	function drawBackground(options) {
		var context = options.context,
			x = options.left,
			y = options.bottom;

		context.fillStyle = defaultColour;

		context.fillRect(x, y - 20, canvas.width, 1);

		for (y = options.bottom - 10; y <= canvas.height; y += 8) {
			for (x = options.left + rand(0, 100); x <= canvas.width; x += rand(100, 200)) {
				context.fillRect(x, y, 4, 1);
			}
		}
	}

	function drawCactus(options) {
		var context = options.context,
			x = options.left,
			y = options.bottom,
			scale = options.scale;

		context.fillStyle = defaultColour;

		// center
		context.fillRect(x + 6 * scale, y - 40 * scale, 6 * scale, 40 * scale);
		context.fillRect(x + 7 * scale, y - 41 * scale, 4 * scale, 1 * scale);

		// left
		context.fillRect(x, y - 30 * scale, 4 * scale, 15 * scale);
		context.fillRect(x + 1 * scale, y - 31 * scale, 2 * scale, 1 * scale);
		context.fillRect(x + 4 * scale, y - 19 * scale, 4 * scale, 4 * scale);

		// right
		context.fillRect(x + 14 * scale, y - 30 * scale, 4 * scale, 15 * scale);
		context.fillRect(x + 15 * scale, y - 31 * scale, 2 * scale, 1 * scale);
		context.fillRect(x + 12 * scale, y - 19 * scale, 4 * scale, 4 * scale);
	}

	drawBackground({
		context: context,
		left: 0,
		bottom: canvas.height,
		frontLegUp: true
	});

	drawDinosaur({
		context: context,
		left: 10,
		bottom: canvas.height - 10
	});

	drawDinosaur({
		context: context,
		left: 110,
		bottom: canvas.height - 10,
		backLegUp: true
	});

	drawDinosaur({
		context: context,
		left: 210,
		bottom: canvas.height - 10,
		frontLegUp: true
	});

	drawDinosaur({
		context: context,
		left: 310,
		bottom: canvas.height - 60,
		backLegUp: true,
		frontLegUp: true
	});

	drawDinosaur({
		context: context,
		left: 510,
		bottom: canvas.height - 10,
		wideEyed: true
	});

	drawCactus({
		context: context,
		left: 410,
		bottom: canvas.height - 10,
		scale: 1
	});

	drawCactus({
		context: context,
		left: 430,
		bottom: canvas.height - 10,
		scale: 1
	});

	drawCactus({
		context: context,
		left: 560,
		bottom: canvas.height - 10,
		scale: 1.2
	});

})(window, document, $);<commit_msg>added basic game loop with stepping<commit_after>(function(window, document, $) {
	var canvas = document.getElementById("game"),
		context = canvas.getContext("2d"),
		defaultColour = "#444",
		backgroundColour = "#eee";

	function rand(min, max) {
  		return Math.floor(Math.random() * (max - min)) + min;
	}

	function drawDinosaur(options) {
		var context = options.context,
			x = options.left,
			y = options.bottom;

		// background spacer
		context.fillStyle = backgroundColour;
		context.fillRect(x + 7, y - 14, 22, 18);

		// Dino!
		context.fillStyle = defaultColour;

		// tail
		context.fillRect(x, y - 36, 2, 16);
		context.fillRect(x + 2, y - 32, 2, 16);
		context.fillRect(x + 4, y - 30, 2, 16);
		context.fillRect(x + 6, y - 28, 2, 16);
		context.fillRect(x + 8, y - 28, 2, 18);
		context.fillRect(x + 10, y - 30, 2, 22);
		context.fillRect(x + 12, y - 32, 4, 26);
		context.fillRect(x + 16, y - 34, 4, 26);
		context.fillRect(x + 20, y - 36, 4, 30);
		context.fillRect(x + 24, y - 38, 2, 30);
		context.fillRect(x + 26, y - 38, 2, 28);
		context.fillRect(x + 28, y - 52, 2, 40);

		if (options.wideEyed) {
			context.fillRect(x + 30, y - 54, 6, 2);
			context.fillRect(x + 32, y - 50, 2, 2);
			context.fillRect(x + 30, y - 46, 2, 32);
			context.fillRect(x + 32, y - 46, 2, 30);
			context.fillRect(x + 34, y - 46, 2, 28);
			// context.fillRect(x + 32, y - 54, 2, 4);
			// context.fillRect(x + 32, y - 48, 2, 32);
			// context.fillRect(x + 34, y - 54, 2, 36);
		} else {
			context.fillRect(x + 30, y - 54, 2, 40);
			context.fillRect(x + 32, y - 54, 2, 4);
			context.fillRect(x + 32, y - 48, 2, 32);
			context.fillRect(x + 34, y - 54, 2, 36);
		}

		context.fillRect(x + 36, y - 54, 2, 34);
		context.fillRect(x + 38, y - 54, 2, 20);
		context.fillRect(x + 40, y - 54, 12, 16);
		context.fillRect(x + 52, y - 52, 2, 14);

		if (options.wideEyed) {
			context.fillRect(x + 38, y - 34, 8, 2);
		} else {
			context.fillRect(x + 40, y - 36, 8, 2);
		}

		// arm (singular)
		context.fillRect(x + 36, y - 26, 4, 2);
		context.fillRect(x + 40, y - 26, 2, 4);

		y = options.bottom;
		if (options.backLegUp) {
			y -= 4;
		}
		// back leg
		context.fillRect(x + 12, y, 4, 2);
		context.fillRect(x + 12, y - 6, 2, 8);
		context.fillRect(x + 14, y - 6, 2, 3);
		context.fillRect(x + 16, y - 8, 2, 3);

		y = options.bottom;
		if (options.frontLegUp) {
			y -= 6;
		}

		// front leg
		context.fillRect(x + 22, y, 4, 2);
		context.fillRect(x + 22, y - 6, 2, 8);
	}

	function drawBackground(options) {
		var context = options.context,
			x = options.left,
			y = options.bottom;

		context.fillStyle = defaultColour;

		context.fillRect(x, y - 20, canvas.width, 1);

		for (y = options.bottom - 10; y <= canvas.height; y += 8) {
			for (x = options.left + rand(0, 100); x <= canvas.width; x += rand(100, 200)) {
				context.fillRect(x, y, 4, 1);
			}
		}
	}

	function drawCactus(options) {
		var context = options.context,
			x = options.left,
			y = options.bottom,
			scale = options.scale;

		context.fillStyle = defaultColour;

		// center
		context.fillRect(x + 6 * scale, y - 40 * scale, 6 * scale, 40 * scale);
		context.fillRect(x + 7 * scale, y - 41 * scale, 4 * scale, 1 * scale);

		// left
		context.fillRect(x, y - 30 * scale, 4 * scale, 15 * scale);
		context.fillRect(x + 1 * scale, y - 31 * scale, 2 * scale, 1 * scale);
		context.fillRect(x + 4 * scale, y - 19 * scale, 4 * scale, 4 * scale);

		// right
		context.fillRect(x + 14 * scale, y - 30 * scale, 4 * scale, 15 * scale);
		context.fillRect(x + 15 * scale, y - 31 * scale, 2 * scale, 1 * scale);
		context.fillRect(x + 12 * scale, y - 19 * scale, 4 * scale, 4 * scale);
	}

	drawBackground({
		context: context,
		left: 0,
		bottom: canvas.height,
		frontLegUp: true
	});

	drawCactus({
		context: context,
		left: 410,
		bottom: canvas.height - 10,
		scale: 1
	});

	drawCactus({
		context: context,
		left: 430,
		bottom: canvas.height - 10,
		scale: 1
	});

	drawCactus({
		context: context,
		left: 560,
		bottom: canvas.height - 10,
		scale: 1.2
	});

	var lastTick = null,
		jumping = false,
		score = 0,
		ground = canvas.height - 10,
		speed = 0.01; // 10 score per second

	function step(timestamp) {
		if (lastTick) {
			score += (timestamp - lastTick) * speed;

			drawDinosaur({
				context: context,
				left: 10,
				bottom: ground,
				backLegUp: Math.floor(score) % 3 === 0,
				frontLegUp: Math.floor(score) % 3 === 1
			});
		}
		lastTick = timestamp;
		window.requestAnimationFrame(step);
	}

	window.requestAnimationFrame(step);

})(window, document, $);<|endoftext|>


<commit_before>export function getDefaults() {
  //return the center and the zoom level
  const data = window.location.hash.substring(1).split(',')
  let stashed
  if(data.length !== 3){
    stashed = {}
  } else {
    stashed = {
      center: [
        parseFloat(data[0]),
        parseFloat(data[1])
      ],
      zoom: parseFloat(data[2]),
      geojson: []
    }
  }

  return Object.assign({
    center: [39.5501, -105.7821],
      zoom: 10,
      geojson: {
        loading: false,
        data: []
      }
    },
    stashed
  )
}<commit_msg>styling<commit_after>export function getDefaults() {
  //return the center and the zoom level
  const data = window.location.hash.substring(1).split(',')
  let stashed
  if(data.length !== 3){
    stashed = {}
  } else {
    stashed = {
      center: [
        parseFloat(data[0]),
        parseFloat(data[1])
      ],
      zoom: parseFloat(data[2]),
      geojson: []
    }
  }

  return Object.assign({
    center: [39.5501, -105.7821],
    zoom: 10,
    geojson: {
      loading: false,
      data: []
    }
  },
  stashed
  )
}<|endoftext|>


<commit_before>import http from '../http';

export default class collections {

    static getAll() {
        return http.get(`/zebedee/collections`)
            .then(response => {
                return response;
            })
    }

    static addDataset() {
        // return http.put(`/zebedee/collections/${collectionID}/dataset/${datasetID}`, body , true)
        //     .then(response => {
        //         return response;
        //     })

        // mocked ok response from Zebedee
        return new Promise(resolve => {
            setTimeout(() => { resolve(); }, 2000);
        })
    }

    static removeDataset() {
        // return http.delete(`/zebedee/collections/${collectionID}/dataset/${datasetID}`, true)
        //     .then(response => {
        //         return response;
        //     })

        // mocked ok response from Zebedee
        return new Promise(resolve => {
            setTimeout(() => { resolve(); }, 1000);
        })
    }

    static addVersion(collectionID, datasetID, edition, version) {
        // return http.put(`/zebedee/collections/${collectionID}/datasetID/${datasetID}/editions/${edition}/versions/${version}`, body , true)
        //     .then(response => {
        //         return response;
        //     })

        // mocked ok response from Zebedee
        return new Promise(resolve => {
            setTimeout(() => { resolve(); }, 2000);
        })
    }

    static removeVersion(collectionID, datasetID, edition, version) {
        // return http.delete(`/zebedee/collections/${collectionID}/datasetID/${datasetID}/editions/${edition}/versions/${version}`, true)
        //     .then(response => {
        //         return response;
        //     })

        // mocked ok response from Zebedee
        return new Promise(resolve => {
            setTimeout(() => { resolve(); }, 1000);
        })
    }

}
<commit_msg>Unstub calls to zebedee and add methods for updating state of content in collection<commit_after>import http from '../http';

export default class collections {

    static getAll() {
        return http.get(`/zebedee/collections`)
            .then(response => {
                return response;
            })
    }

    static addDataset(collectionID, datasetID) {
        const body = {state: "inProgress"};
        return http.put(`/zebedee/collections/${collectionID}/datasets/${datasetID}`, body , true)
            .then(response => {
                return response;
            });
    }

    static setDatasetStatusToComplete(collectionID, datasetID) {
        const body = {state: "complete"};
        return http.put(`/zebedee/collections/${collectionID}/datasets/${datasetID}`, body , true)
            .then(response => {
                return response;
            });
    }

    static setDatasetStatusToReviewed(collectionID, datasetID) {
        const body = {state: "reviewed"};
        return http.put(`/zebedee/collections/${collectionID}/datasets/${datasetID}`, body , true)
            .then(response => {
                return response;
            });
    }

    static removeDataset(collectionID, datasetID) {
        return http.delete(`/zebedee/collections/${collectionID}/datasets/${datasetID}`, true)
            .then(response => {
                return response;
            });
    }

    static addDatasetVersion(collectionID, datasetID, editionID, versionID) {
        const body = {state: "inProgress"};
        return http.put(`/zebedee/collections/${collectionID}/datasets/${datasetID}/editions/${editionID}/versions/${versionID}`, body , true)
            .then(response => {
                return response;
            });
    }

    static setDatasetVersionStatusToComplete(collectionID, datasetID) {
        const body = {state: "complete"};
        return http.put(`/zebedee/collections/${collectionID}/datasets/${datasetID}/editions/${editionID}/versions/${versionID}`, body , true)
            .then(response => {
                return response;
            });
    }

    static setDatasetVersionStatusToReviewed(collectionID, datasetID) {
        const body = {state: "reviewed"};
        return http.put(`/zebedee/collections/${collectionID}/datasets/${datasetID}/editions/${editionID}/versions/${versionID}`, body , true)
            .then(response => {
                return response;
            });
    }

    static removeDatasetVersion(collectionID, datasetID, editionID, versionID) {
        return http.delete(`/zebedee/collections/${collectionID}/datasets/${datasetID}/editions/${editionID}/versions/${versionID}`, true)
            .then(response => {
                return response;
            });
    }

}
<|endoftext|>


<commit_before>/* LanguageTool WebExtension
 * Copyright (C) 2015 Daniel Naber (http://www.danielnaber.de)
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301
 * USA
 */
"use strict";

const trackingBaseUrl = "https://openthesaurus.stats.mysnip-hosting.de/piwik.php";
const trackingSiteId = "12";
const THROTTLE_REQUESTS = 5;
const MAX_TIME = 1 * 60 * 1000; // 1 minute
// chrome.google.com: see http://stackoverflow.com/questions/11613371/
// docs.google.com: Google Docs has a too complicated DOM (but its own add-on framework)
// addons.mozilla.org: see http://stackoverflow.com/questions/42147966/
const unsupportedSitesRegex = /^https?:\/\/(docs.google.com|chrome.google.com|addons.mozilla.org).*/;
const notSupportMarkerSitesRegex = /^https?:\/\/(www.facebook.com|facebook.com|docs.google.com|chrome.google.com|addons.mozilla.org|.*wikipedia.org.*&veaction=edit).*/;

// turn off some rules by default because they are not that useful in a typical web context:
const ruleIdsIgnoredByDefault = [
    // English:
    {id: 'EN_QUOTES', language: 'en'},
    {id: 'DASH_RULE', language: 'en'},
    // German:
    {id: 'TYPOGRAFISCHE_ANFUEHRUNGSZEICHEN', language: 'de'},
    {id: 'FALSCHE_VERWENDUNG_DES_BINDESTRICHS', language: 'de'},
    {id: 'BISSTRICH', language: 'de'},
    {id: 'AUSLASSUNGSPUNKTE', language: 'de'},
];

const errorsText = ['error', 'exception', 'problem'];
const lastTrackingError = {};

class Tools {

    constructor() {
    }

    static getApiServerUrl(callback) {
        const storage = Tools.getStorage();
        storage.get({
            apiServerUrl: 'https://api.languagetool.org/v2',
            havePremiumAccount: false
        }, function(items) {
            let serverUrl = items.apiServerUrl;
            if (items.havePremiumAccount) {
                serverUrl = 'https://languagetoolplus.com/api/v2';
            }
            callback(serverUrl);
        });
    }

    static track(pageUrl, actionName, optionalTrackDetails) {
        if (!Tools.isChrome()) {
            // version with tracking not deployed yet for Firefox, so make it explicit that tracking on FF won't work:
            return;
        }
        try {
            // throttle request for error tracking
            const foundErrorTracking = errorsText.find(item => actionName.toLowerCase().indexOf(item) !== -1);
            if (foundErrorTracking) {
                if(!lastTrackingError[actionName]) {
                    lastTrackingError[actionName] = [Date.now()];
                } else {
                    if (lastTrackingError[actionName].length < THROTTLE_REQUESTS) {
                        lastTrackingError[actionName].push(Date.now());
                    } else {
                        // compare the first item, make sure only max THROTTLE_REQUESTS per min
                        const now = Date.now();
                        const distanceRunTime = now - lastTrackingError[actionName][0];
                        if (distanceRunTime >= MAX_TIME) {
                            lastTrackingError[actionName].push(now);
                            lastTrackingError[actionName].splice(0,1);
                        } else {
                            // console.warn(`LT add-on ignore tracking for ${actionName} - ${new Date(now)}`, lastTrackingError);
                            return null; // break, ignore this action name
                        }
                    }
                }
            }
            const storage = Tools.getStorage();
            storage.get({
                uid: null
            }, function(items) {
                // needed to tell visits from  unique visitors:
                let uid;
                if (items.uid) {
                    uid = items.uid;
                } else {
                    uid = Tools.getRandomToken();
                    storage.set({uid: uid}, function() {});
                }
                let shortenedUrl = pageUrl ? pageUrl.replace(/^(.*?:\/\/.+?)[?\/].*/, "$1") : '';  // for privacy reasons, only log host
                if (shortenedUrl.indexOf("http:") !== 0 && shortenedUrl.indexOf("https:") !== 0) {
                    shortenedUrl = "http://"  + shortenedUrl;  // Piwik needs URL, it will not log otherwise
                }
                const url = encodeURIComponent(shortenedUrl);
                const manifest = chrome.runtime.getManifest();
                const version = manifest && manifest.version ? manifest.version : "unknown";
                const trackingUrl = trackingBaseUrl +
                    "?idsite=" + trackingSiteId +
                    "&_cvar={\"1\":[\"version\",\"" + encodeURIComponent(version) + "\"]}" +
                    "&rec=1" +
                    "&url=" + url +
                    "&action_name=" + encodeURIComponent(actionName) +
                    "&rand=" + Date.now() +
                    "&apiv=1" +
                    "&_id=" + uid +
                    "&e_c=Action" +
                    "&e_a=" + encodeURIComponent(actionName) +
                    (optionalTrackDetails ? "&e_n=" + encodeURIComponent(optionalTrackDetails) : "");
                //console.log("trackingUrl: " + trackingUrl);
                const trackReq = new XMLHttpRequest();
                trackReq.open('POST', trackingUrl);
                trackReq.onerror = function() {
                    console.log("LT add-on tracking failed");
                };
                trackReq.ontimeout = function() {
                    console.log("LT add-on tracking failed with timeout");
                };
                trackReq.send();
                console.log(`LanguageTool tracking: ${shortenedUrl}, ${actionName}, ${optionalTrackDetails}`);
            });
        } catch(e) {
            console.log(`LanguageTool add-on tracking failed: ${e.message}`);
        }
    }

    static getStorage() {
        // special case for Firefox as long as chrome.storage.sync is defined, but
        // not yet activated by default: https://github.com/languagetool-org/languagetool-browser-addon/issues/97
        return chrome.storage.sync && !Tools.isFirefox() ? chrome.storage.sync : chrome.storage.local;
    }

    static doNotSupportOnUrl(url) {
        return url.match(unsupportedSitesRegex);
    }

    static doNotShowMarkerOnUrl(url) {
        return url.match(notSupportMarkerSitesRegex);
    }

    static getRandomToken() {
        const randomPool = new Uint8Array(8);
        crypto.getRandomValues(randomPool);
        let hex = '';
        for (let i = 0; i < randomPool.length; ++i) {
            hex += randomPool[i].toString(16);
        }
        return hex;
    }

    // NOTE: the number of logs that can be sent is limited by the same limit
    // that limits the check requests per minute, so prefer Tools.track()
    static logOnServer(message, serverUrl = 'https://api.languagetool.org/v2') {
        if (serverUrl.indexOf("https://languagetool.org") === -1) {
            // these logging messages are only useful for the LT dev team
            // to improve the add-on, so don't send anywhere else:
            return;
        }
        const req = new XMLHttpRequest();
        req.timeout = 60 * 1000; // milliseconds
        const url = serverUrl + (serverUrl.endsWith("/") ? "log" : "/log");
        req.open('POST', url);
        req.onload = function() {
            // do nothing (also ignore timeout and errors)
        };
        //console.log("Posting to " + url + ": " + message);
        req.send("message=" + encodeURIComponent(message));
    }

    static isFirefox() {
        return navigator.userAgent.indexOf("Firefox/") !== -1;
    }

    static isChrome() {
        return navigator.userAgent.indexOf("Chrome/") !== -1 || navigator.userAgent.indexOf("Chromium/") !== -1;
    }

    static escapeHtml(s) {
        return s.replace(/&/g, '&')
                .replace(/>/g, '>')
                .replace(/</g, '<')
                .replace(/"/g, '"')
                .replace(/'/g, ''');
    }

    static startWithLowercase(str) {
        const firstCh = str.charAt(0);
        return firstCh == firstCh.toLowerCase() && firstCh != firstCh.toUpperCase();
    }

    static startWithUppercase(str) {
        const firstCh = str.charAt(0);
        return firstCh == firstCh.toUpperCase() && firstCh != firstCh.toLowerCase();
    }

    static lowerCaseFirstChar(str) {
        const firstCh = str.charAt(0);
        return firstCh.toLowerCase() + str.substr(1);
    }

    static setIgnoreRules(callback) {
        const storage = Tools.getStorage();
        storage.get({ ignoredRules: ruleIdsIgnoredByDefault }, callback);
    }

    static getUserSettingsForRender(callback) {
        const storage = Tools.getStorage();
        storage.get({
            dictionary: [],
            disabledDomains: [],
            autoCheckOnDomains: [],
            ignoreCheckOnDomains: [],
            ignoredRules: ruleIdsIgnoredByDefault,
            havePremiumAccount: false,
            autoCheck: false,
            usageCounter: 0,
        }, callback);
    }

    // Due to Transifex limited support for Android i18n files, we already have
    // a very complicated i18n setup (see injectTranslations.py) and it seems
    // we're better off just hard-coding the English language names here instead of
    // making the process even more complicated:
    static getLangName(langCode) {
        switch (langCode) {
            case "ast-ES": return "Asturian";
            case "be-BY": return "Belarusian";
            case "br-FR": return "Breton";
            case "ca-ES": return "Catalan";
            case "ca-ES-valencia": return "Catalan (Valencian)";
            case "zh-CN": return "Chinese";
            case "da-DK": return "Danish";
            case "nl": return "Dutch";
            case "en-US": return "English (American)";
            case "en-GB": return "English (British)";
            case "en-AU": return "English (Australia)";
            case "en-CA": return "English (Canada)";
            case "en-NZ": return "English (New Zealand)";
            case "en-ZA": return "English (South Africa)";
            case "eo": return "Esperanto";
            case "fr": return "French";
            case "gl-ES": return "Galician";
            case "de-DE": return "German (German)";
            case "de-AT": return "German (Austria)";
            case "de-CH": return "German (Switzerland)";
            case "el-GR": return "Greek";
            case "is-IS": return "Icelandic";
            case "it": return "Italian";
            case "ja-JP": return "Japanese";
            case "km-KH": return "Khmer";
            case "lt-LT": return "Lithuanian";
            case "ml-IN": return "Malayalam";
            case "fa": return "Persian";
            case "pl-PL": return "Polish";
            case "pt-PT": return "Portuguese (Portugal)";
            case "pt-BR": return "Portuguese (Brazil)";
            case "ro-RO": return "Romanian";
            case "ru-RU": return "Russian";
            case "sk-SK": return "Slovak";
            case "sl-SI": return "Slovenian";
            case "es": return "Spanish";
            case "sv": return "Swedish";
            case "tl-PH": return "Tagalog";
            case "ta-IN": return "Tamil";
            case "uk-UA": return "Ukrainian";
            default: return langCode;
        }
    }

}

if (typeof module !== 'undefined') {
    module.exports = Tools;
}
<commit_msg>fix logOnServer (currently not used anyway)<commit_after>/* LanguageTool WebExtension
 * Copyright (C) 2015 Daniel Naber (http://www.danielnaber.de)
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301
 * USA
 */
"use strict";

const trackingBaseUrl = "https://openthesaurus.stats.mysnip-hosting.de/piwik.php";
const trackingSiteId = "12";
const THROTTLE_REQUESTS = 5;
const MAX_TIME = 1 * 60 * 1000; // 1 minute
// chrome.google.com: see http://stackoverflow.com/questions/11613371/
// docs.google.com: Google Docs has a too complicated DOM (but its own add-on framework)
// addons.mozilla.org: see http://stackoverflow.com/questions/42147966/
const unsupportedSitesRegex = /^https?:\/\/(docs.google.com|chrome.google.com|addons.mozilla.org).*/;
const notSupportMarkerSitesRegex = /^https?:\/\/(www.facebook.com|facebook.com|docs.google.com|chrome.google.com|addons.mozilla.org|.*wikipedia.org.*&veaction=edit).*/;

// turn off some rules by default because they are not that useful in a typical web context:
const ruleIdsIgnoredByDefault = [
    // English:
    {id: 'EN_QUOTES', language: 'en'},
    {id: 'DASH_RULE', language: 'en'},
    // German:
    {id: 'TYPOGRAFISCHE_ANFUEHRUNGSZEICHEN', language: 'de'},
    {id: 'FALSCHE_VERWENDUNG_DES_BINDESTRICHS', language: 'de'},
    {id: 'BISSTRICH', language: 'de'},
    {id: 'AUSLASSUNGSPUNKTE', language: 'de'},
];

const errorsText = ['error', 'exception', 'problem'];
const lastTrackingError = {};

class Tools {

    constructor() {
    }

    static getApiServerUrl(callback) {
        const storage = Tools.getStorage();
        storage.get({
            apiServerUrl: 'https://api.languagetool.org/v2',
            havePremiumAccount: false
        }, function(items) {
            let serverUrl = items.apiServerUrl;
            if (items.havePremiumAccount) {
                serverUrl = 'https://languagetoolplus.com/api/v2';
            }
            callback(serverUrl);
        });
    }

    static track(pageUrl, actionName, optionalTrackDetails) {
        if (!Tools.isChrome()) {
            // version with tracking not deployed yet for Firefox, so make it explicit that tracking on FF won't work:
            return;
        }
        try {
            // throttle request for error tracking
            const foundErrorTracking = errorsText.find(item => actionName.toLowerCase().indexOf(item) !== -1);
            if (foundErrorTracking) {
                if(!lastTrackingError[actionName]) {
                    lastTrackingError[actionName] = [Date.now()];
                } else {
                    if (lastTrackingError[actionName].length < THROTTLE_REQUESTS) {
                        lastTrackingError[actionName].push(Date.now());
                    } else {
                        // compare the first item, make sure only max THROTTLE_REQUESTS per min
                        const now = Date.now();
                        const distanceRunTime = now - lastTrackingError[actionName][0];
                        if (distanceRunTime >= MAX_TIME) {
                            lastTrackingError[actionName].push(now);
                            lastTrackingError[actionName].splice(0,1);
                        } else {
                            // console.warn(`LT add-on ignore tracking for ${actionName} - ${new Date(now)}`, lastTrackingError);
                            return null; // break, ignore this action name
                        }
                    }
                }
            }
            const storage = Tools.getStorage();
            storage.get({
                uid: null
            }, function(items) {
                // needed to tell visits from  unique visitors:
                let uid;
                if (items.uid) {
                    uid = items.uid;
                } else {
                    uid = Tools.getRandomToken();
                    storage.set({uid: uid}, function() {});
                }
                let shortenedUrl = pageUrl ? pageUrl.replace(/^(.*?:\/\/.+?)[?\/].*/, "$1") : '';  // for privacy reasons, only log host
                if (shortenedUrl.indexOf("http:") !== 0 && shortenedUrl.indexOf("https:") !== 0) {
                    shortenedUrl = "http://"  + shortenedUrl;  // Piwik needs URL, it will not log otherwise
                }
                const url = encodeURIComponent(shortenedUrl);
                const manifest = chrome.runtime.getManifest();
                const version = manifest && manifest.version ? manifest.version : "unknown";
                const trackingUrl = trackingBaseUrl +
                    "?idsite=" + trackingSiteId +
                    "&_cvar={\"1\":[\"version\",\"" + encodeURIComponent(version) + "\"]}" +
                    "&rec=1" +
                    "&url=" + url +
                    "&action_name=" + encodeURIComponent(actionName) +
                    "&rand=" + Date.now() +
                    "&apiv=1" +
                    "&_id=" + uid +
                    "&e_c=Action" +
                    "&e_a=" + encodeURIComponent(actionName) +
                    (optionalTrackDetails ? "&e_n=" + encodeURIComponent(optionalTrackDetails) : "");
                //console.log("trackingUrl: " + trackingUrl);
                const trackReq = new XMLHttpRequest();
                trackReq.open('POST', trackingUrl);
                trackReq.onerror = function() {
                    console.log("LT add-on tracking failed");
                };
                trackReq.ontimeout = function() {
                    console.log("LT add-on tracking failed with timeout");
                };
                trackReq.send();
                console.log(`LanguageTool tracking: ${shortenedUrl}, ${actionName}, ${optionalTrackDetails}`);
            });
        } catch(e) {
            console.log(`LanguageTool add-on tracking failed: ${e.message}`);
        }
    }

    static getStorage() {
        // special case for Firefox as long as chrome.storage.sync is defined, but
        // not yet activated by default: https://github.com/languagetool-org/languagetool-browser-addon/issues/97
        return chrome.storage.sync && !Tools.isFirefox() ? chrome.storage.sync : chrome.storage.local;
    }

    static doNotSupportOnUrl(url) {
        return url.match(unsupportedSitesRegex);
    }

    static doNotShowMarkerOnUrl(url) {
        return url.match(notSupportMarkerSitesRegex);
    }

    static getRandomToken() {
        const randomPool = new Uint8Array(8);
        crypto.getRandomValues(randomPool);
        let hex = '';
        for (let i = 0; i < randomPool.length; ++i) {
            hex += randomPool[i].toString(16);
        }
        return hex;
    }

    // NOTE: the number of logs that can be sent is limited by the same limit
    // that limits the check requests per minute, so prefer Tools.track()
    static logOnServer(message, serverUrl = 'https://api.languagetool.org/v2') {
        if (serverUrl.indexOf("https://languagetool.org") === -1 && serverUrl.indexOf("https://api.languagetool.org") === -1) {
            // these logging messages are only useful for the LT dev team
            // to improve the add-on, so don't send anywhere else:
            return;
        }
        const req = new XMLHttpRequest();
        req.timeout = 60 * 1000; // milliseconds
        const url = serverUrl + (serverUrl.endsWith("/") ? "log" : "/log");
        req.open('POST', url);
        req.onload = function() {
            // do nothing (also ignore timeout and errors)
        };
        //console.log("Posting to " + url + ": " + message);
        req.send("message=" + encodeURIComponent(message));
    }

    static isFirefox() {
        return navigator.userAgent.indexOf("Firefox/") !== -1;
    }

    static isChrome() {
        return navigator.userAgent.indexOf("Chrome/") !== -1 || navigator.userAgent.indexOf("Chromium/") !== -1;
    }

    static escapeHtml(s) {
        return s.replace(/&/g, '&')
                .replace(/>/g, '>')
                .replace(/</g, '<')
                .replace(/"/g, '"')
                .replace(/'/g, ''');
    }

    static startWithLowercase(str) {
        const firstCh = str.charAt(0);
        return firstCh == firstCh.toLowerCase() && firstCh != firstCh.toUpperCase();
    }

    static startWithUppercase(str) {
        const firstCh = str.charAt(0);
        return firstCh == firstCh.toUpperCase() && firstCh != firstCh.toLowerCase();
    }

    static lowerCaseFirstChar(str) {
        const firstCh = str.charAt(0);
        return firstCh.toLowerCase() + str.substr(1);
    }

    static setIgnoreRules(callback) {
        const storage = Tools.getStorage();
        storage.get({ ignoredRules: ruleIdsIgnoredByDefault }, callback);
    }

    static getUserSettingsForRender(callback) {
        const storage = Tools.getStorage();
        storage.get({
            dictionary: [],
            disabledDomains: [],
            autoCheckOnDomains: [],
            ignoreCheckOnDomains: [],
            ignoredRules: ruleIdsIgnoredByDefault,
            havePremiumAccount: false,
            autoCheck: false,
            usageCounter: 0,
        }, callback);
    }

    // Due to Transifex limited support for Android i18n files, we already have
    // a very complicated i18n setup (see injectTranslations.py) and it seems
    // we're better off just hard-coding the English language names here instead of
    // making the process even more complicated:
    static getLangName(langCode) {
        switch (langCode) {
            case "ast-ES": return "Asturian";
            case "be-BY": return "Belarusian";
            case "br-FR": return "Breton";
            case "ca-ES": return "Catalan";
            case "ca-ES-valencia": return "Catalan (Valencian)";
            case "zh-CN": return "Chinese";
            case "da-DK": return "Danish";
            case "nl": return "Dutch";
            case "en-US": return "English (American)";
            case "en-GB": return "English (British)";
            case "en-AU": return "English (Australia)";
            case "en-CA": return "English (Canada)";
            case "en-NZ": return "English (New Zealand)";
            case "en-ZA": return "English (South Africa)";
            case "eo": return "Esperanto";
            case "fr": return "French";
            case "gl-ES": return "Galician";
            case "de-DE": return "German (German)";
            case "de-AT": return "German (Austria)";
            case "de-CH": return "German (Switzerland)";
            case "el-GR": return "Greek";
            case "is-IS": return "Icelandic";
            case "it": return "Italian";
            case "ja-JP": return "Japanese";
            case "km-KH": return "Khmer";
            case "lt-LT": return "Lithuanian";
            case "ml-IN": return "Malayalam";
            case "fa": return "Persian";
            case "pl-PL": return "Polish";
            case "pt-PT": return "Portuguese (Portugal)";
            case "pt-BR": return "Portuguese (Brazil)";
            case "ro-RO": return "Romanian";
            case "ru-RU": return "Russian";
            case "sk-SK": return "Slovak";
            case "sl-SI": return "Slovenian";
            case "es": return "Spanish";
            case "sv": return "Swedish";
            case "tl-PH": return "Tagalog";
            case "ta-IN": return "Tamil";
            case "uk-UA": return "Ukrainian";
            default: return langCode;
        }
    }

}

if (typeof module !== 'undefined') {
    module.exports = Tools;
}
<|endoftext|>


<commit_before>'use strict';

const HAProxyModule = require('./module').HAProxyModule;
const logger = require('../core').logger;

module.exports = (worker, options) => {
    let module = new HAProxyModule(worker, options);

    logger.info(`Init "${module.name.toUpperCase()}" module. Version - ${module.version}`);

    return {
        module: module
    };
};<commit_msg>update<commit_after>'use strict';

const HAProxyModule = require('./module').HAProxyModule;
const logger = require('../core').logger;

module.exports = (worker, options) => {
    let module = new HAProxyModule(worker, options);

    logger.info(`Init "${module.name.toUpperCase()}" module. Version - ${module.version}`);

    return {
        module: module,
        middlewares: require('./middlewares')()
    };
};<|endoftext|>