<commit_before>(typeof $ !== 'undefined' ? $ : jQuery)(document).ready(function($){
	var template = '
 \

 \
				 \

 \
					ISBN #{{isbn}} \
					Title:  \
					Author:  \

 \

 \

 \

 \

 ';

	var notFoundTemplate = '
Could not find book with ISBN {{isbn}}
 ';

	var config = {
		isbnInput: $('input#isbn'),
		welcomePrompt: $('.app-welcome-prompt'),
		donationPrompt: $('.donation-prompt'),
		conditionInput: $('#condition'),
		isbnHelper: $('.isbn-helper'),
		donationSearchThreshold: 5,
		serverUrl: '//libbie.azurewebsites.net',
		welcomePromptShown: false,
		donationPromptShown: false,
		notFoundCssProperties: { backgroundColor: '#333333' },
		maxVisibleBooks: 30,
		animateSpeed: 700,
	};

	var account = null;
	var numSearches = 0;
	var numVisibleSearches = 0;
	var helperVisible = true;
	var smartScanRunning = false, smartScanInterval = null;

	config.isbnInput.focus();

	var socket = io(config.serverUrl);
	socket.emit('getClientInfo');

	socket.on('error', function (data) {
		console.log("Server sent error: ", data);
	});

	socket.on('apperror', function (data) {
		console.error("Application error: ", data);

		if (typeof data.searchIsbn !== 'undefined') {
			$('.addedIsbn.searching.' + data.searchIsbn).replaceWith(notFoundTemplate.replace(/\{\{isbn\}\}/g, data.searchIsbn));
			$('.addedIsbn.notFound.' + data.searchIsbn).animate(config.notFoundCssProperties, config.animateSpeed);
		}
	});

	socket.on('isbnIdentified', function isbnIdentified(data) {
		console.log("ISBN Identified: ", data);

		var book = data.books[0];

		var authors = [];
		for (var author in book.authors) {
			authors.push(book.authors[author].author.name);
		}

		// TODO: Should use handlebars
		$('.addedIsbn.' + data.isbn + ' .title').text(book.title);
		$('.addedIsbn.' + data.isbn + ' .author').text(authors.join(', '));
		$('.addedIsbn.' + data.isbn + ' img.cover').attr('src', book.image_url);
		$('.addedIsbn.' + data.isbn + ' a.goodreads').attr('href', book.link);

		var img = new Image();
		img.src = book.image_url;
		img.onload = function () {
			$('.addedIsbn.searching.' + data.isbn).removeClass('searching').removeClass('loading');
			$('.addedIsbn.loading.' + data.isbn).removeClass('loading');
			$('.addedIsbn.' + data.isbn + ' img.cover').animate({opacity: 1});
			$('.addedIsbn.' + data.isbn + ' a.goodreads').animate({opacity: 1});
		}
	});

	socket.on('bookAdded', function (data) {
		console.log('Book added: ', data);
		var condition = false;

		if ($('#condition option[value=' + data.request.condition + ']').length > 0) {
			condition = $('#condition option[value=' + data.request.condition + ']').html();
		}

		var baseText = 'Added to owned books';
		if (condition) {
			$('.addedIsbn.' + data.isbn + ' .addresult:not(.added)').html(baseText + ' in ' + condition + ' condition');
		} else {
			$('.addedIsbn.' + data.isbn + ' .addresult:not(.added)').html(baseText);
		}

		$('.addedIsbn.' + data.isbn + ' .addresult:not(.added)').fadeIn(config.animateSpeed, function() {
			$('.addedIsbn.' + data.isbn + ' .addresult').addClass('added');
		});
	});

	socket.on('userNotifications', function (data) {
		console.log('User notifications: ', data);
	});

	socket.on('clientInfo', function getClientInfo(data) {
		if (typeof data !== 'object') {
			console.error("Client info not object.");
			return;
		}
		console.log('Account info: ', data);
		account = data;

		if (!config.welcomePromptShown) {
			// Show the welcome prompt if not hidden
			runIfUserPropertyEquals('showWelcomePrompt', true, wrapFuncCB(showWelcomePrompt, true));
		}
	});

	$(document.body).on('keydown', function(e) {
		if(document.activeElement.id !== config.isbnInput.id && !e.metaKey && !e.shiftKey && !e.ctrlKey && !$(document.activeElement).is('input, select')) {
			config.isbnInput.focus();
		}
	});

	$('.donate').click(function () {
		showDonationPrompt(true);
	});

	$('.close, .continue', config.donationPrompt).click(function () {
		showDonationPrompt(false);
	});

	$('.close, .continue', config.welcomePrompt).click(function () {
		if ($('.dont-show-me', config.welcomePrompt).is(':checked')) {
			account.welcomePromptShown = true;
			socket.emit('userHideWelcomePrompt', true);
		}

		showWelcomePrompt(false);
	});

	$('.smartscan').click(function () {
		if (smartScanRunning) {
			endSmartScan();
		} else {
			startSmartScan();
		}
	});

	function startSmartScan() {
		smartScanRunning = true;
		config.isbnInput.val('');

		$('#application').addClass('smartScanRunning');
		config.isbnInput.attr('data-old-placeholder', config.isbnInput.attr('placeholder'));
		config.isbnInput.attr('placeholder', 'Smart scan running... Re-scan barcode.');

		smartScanInterval = setInterval(function(){
			var newText = config.isbnInput.attr('placeholder') + '.';

			if (newText[newText.length - 6] === '.') {
				newText = 'Smart scan running... Re-scan barcode.';
			}

			config.isbnInput.attr('placeholder', newText);
		}, 1000);
	}

	function endSmartScan() {
		smartScanRunning = false;
		clearInterval(smartScanInterval);
		smartScanInterval = null;
		config.isbnInput.attr('placeholder', config.isbnInput.attr('data-old-placeholder'));
		$('#application').removeClass('smartScanRunning');
	}

	config.isbnInput.keypress(function keypressHandler(event) {
		var entryKey = 'Enter';
		if (account !== null && typeof account.entryKey !== 'undefined') {
			entryKey = account.entryKey;
		}

		var isbn = parseIsbn(config.isbnInput.val());
		var eventKeyString = buildEventKeyString(event);
		console.log('Event key string: ', eventKeyString, validateIsbn)
		if (smartScanRunning && validateIsbn(isbn)) {
			console.log('Smart scan identified key combo: ', eventKeyString);
			endSmartScan();
			entryKey = account.entryKey = eventKeyString;
			socket.emit('setUserEntryKey', eventKeyString);
		}

		if (eventKeyString === entryKey && (!smartScanRunning || validateIsbn(isbn))) {
			config.isbnInput.focus();

			if (!validateIsbn(isbn)) {
				alert("Invalid isbn!");
				return;
			}

			if (++numSearches >= config.donationSearchThreshold && !config.donationPromptShown) {
				runIfUserPropertyEquals('hasDonated', false, wrapFuncCB(showDonationPrompt, true));
			}

			if (++numVisibleSearches >= config.maxVisibleBooks) {
				--numVisibleSearches;
				$('#searchList .addedIsbn:last-child').fadeOut(config.animateSpeed, function () {
					$(this).remove();
				});
			}

			config.isbnInput.val('');

			var condition = parseInt(config.conditionInput.val());

			socket.emit('addIsbn', {
				condition: condition,
				isbn: isbn,
			});

			$('#searchList').prepend(template.replace(/\{\{isbn\}\}/g, isbn));

			if (helperVisible) {
				config.isbnHelper.fadeOut(config.animateSpeed);
				helperVisible = false;
			}
		}
	});

	function buildEventKeyString(e) {
		var keys = [ e.key ];

		if (e.metaKey) {
			keys.push('Meta');
		}

		if (e.shiftKey) {
			keys.push('Shift');
		}

		if (e.ctrlKey) {
			keys.push('Control');
		}

		keys.sort();
		return keys.join('+');
	}

	function validateIsbn(isbn) {
		if (typeof isbn !== 'string') {
			return false;
		}

		return null !== isbn.match(/^([0-9]{10}|[0-9]{13})$/);
	}

	function parseIsbn(isbn) {
		if (typeof isbn !== 'string') {
			return '';
		}

		isbn = isbn.replace(/-/g, '').trim();

		if (isbn.length === 9) {
			return '0' + isbn;
		}

		return isbn;
	}

	var promptBg = '

'
	function showPrompt(prompt, show) {
		if (show) {
			if ($('#prompt-cover').length === 0) {
				$('body').append(promptBg);
			}

			$(prompt).show();
		} else {
			$('#prompt-cover').remove();
			$(prompt).hide();
		}
	}

	function hideAllPrompts() {
		$('.prompt').hide();
	}

	function showWelcomePrompt(show) {
		hideAllPrompts();
		config.welcomePromptShown |= show;
		showPrompt(config.welcomePrompt, show);
	}

	function showDonationPrompt(show) {
		hideAllPrompts();
		config.donationPromptShown |= show;
		showPrompt(config.donationPrompt, show);

		if (show) {
			window.location.hash = '#donate';
		} else {
			window.location.hash = '';
		}
	}

	function wrapFuncCB(func) {
		var $this = this;
		var args = Array.prototype.slice.call(arguments);
		args.splice(0, 1);
		return function() {
			return func.apply($this, args);
		}
	}

	function runIfUserPropertyEquals(property, desiredValue, callback) {
		if (account !== null && typeof account[property] !== 'undefined' && account[property] === desiredValue) {
			callback();
		}
	}

	switch (window.location.hash) {
		case '':
			break;
		case '#welcome':
			showWelcomePrompt(true);
			break;
		case '#donate':
			showDonationPrompt(true);
			break;
	}
});<commit_msg>Fix undefined js variable<commit_after>(typeof $ !== 'undefined' ? $ : jQuery)(document).ready(function($){
	var template = '
 \

 \
				 \

 \
					ISBN #{{isbn}} \
					Title:  \
					Author:  \

 \

 \

 \

 \

 ';

	var notFoundTemplate = '
Could not find book with ISBN {{isbn}}
 ';

	var config = {
		isbnInput: $('input#isbn'),
		welcomePrompt: $('.app-welcome-prompt'),
		donationPrompt: $('.donation-prompt'),
		conditionInput: $('#condition'),
		isbnHelper: $('.isbn-helper'),
		donationSearchThreshold: 5,
		serverUrl: '//libbie.azurewebsites.net',
		welcomePromptShown: false,
		donationPromptShown: false,
		notFoundCssProperties: { backgroundColor: '#333333' },
		maxVisibleBooks: 30,
		animateSpeed: 700,
	};

	var account = null;
	var numSearches = 0;
	var numVisibleSearches = 0;
	var helperVisible = true;
	var smartScanRunning = false, smartScanInterval = null;

	config.isbnInput.focus();

	var socket = io(config.serverUrl);
	socket.emit('getClientInfo');

	socket.on('error', function (data) {
		console.log("Server sent error: ", data);
	});

	socket.on('apperror', function (data) {
		console.error("Application error: ", data);

		if (typeof data.searchIsbn !== 'undefined') {
			$('.addedIsbn.searching.' + data.searchIsbn).replaceWith(notFoundTemplate.replace(/\{\{isbn\}\}/g, data.searchIsbn));
			$('.addedIsbn.notFound.' + data.searchIsbn).animate(config.notFoundCssProperties, config.animateSpeed);
		}
	});

	socket.on('isbnIdentified', function isbnIdentified(data) {
		console.log("ISBN Identified: ", data);

		var book = data.books[0];

		var authors = [];
		for (var author in book.authors) {
			authors.push(book.authors[author].author.name);
		}

		// TODO: Should use handlebars
		$('.addedIsbn.' + data.isbn + ' .title').text(book.title);
		$('.addedIsbn.' + data.isbn + ' .author').text(authors.join(', '));
		$('.addedIsbn.' + data.isbn + ' img.cover').attr('src', book.image_url);
		$('.addedIsbn.' + data.isbn + ' a.goodreads').attr('href', book.link);

		var img = new Image();
		img.src = book.image_url;
		img.onload = function () {
			$('.addedIsbn.searching.' + data.isbn).removeClass('searching').removeClass('loading');
			$('.addedIsbn.loading.' + data.isbn).removeClass('loading');
			$('.addedIsbn.' + data.isbn + ' img.cover').animate({opacity: 1});
			$('.addedIsbn.' + data.isbn + ' a.goodreads').animate({opacity: 1});
		}
	});

	socket.on('bookAdded', function (data) {
		console.log('Book added: ', data);
		var condition = false;

		if ($('#condition option[value=' + data.request.condition + ']').length > 0) {
			condition = $('#condition option[value=' + data.request.condition + ']').html();
		}

		var baseText = 'Added to owned books';
		if (condition) {
			$('.addedIsbn.' + data.isbn + ' .addresult:not(.added)').html(baseText + ' in ' + condition + ' condition');
		} else {
			$('.addedIsbn.' + data.isbn + ' .addresult:not(.added)').html(baseText);
		}

		$('.addedIsbn.' + data.isbn + ' .addresult:not(.added)').fadeIn(config.animateSpeed, function() {
			$('.addedIsbn.' + data.isbn + ' .addresult').addClass('added');
		});
	});

	socket.on('userNotifications', function (data) {
		console.log('User notifications: ', data);
	});

	socket.on('clientInfo', function getClientInfo(data) {
		if (typeof data !== 'object') {
			console.error("Client info not object.");
			return;
		}
		console.log('Account info: ', data);
		account = data;

		if (!config.welcomePromptShown) {
			// Show the welcome prompt if not hidden
			runIfUserPropertyEquals('showWelcomePrompt', true, wrapFuncCB(showWelcomePrompt, true));
		}
	});

	$(document.body).on('keydown', function(e) {
		if(document.activeElement.id !== config.isbnInput.id && !e.metaKey && !e.shiftKey && !e.ctrlKey && !$(document.activeElement).is('input, select')) {
			config.isbnInput.focus();
		}
	});

	$('.donate').click(function () {
		showDonationPrompt(true);
	});

	$('.close, .continue', config.donationPrompt).click(function () {
		showDonationPrompt(false);
	});

	$('.close, .continue', config.welcomePrompt).click(function () {
		if ($('.dont-show-me', config.welcomePrompt).is(':checked')) {
			account.welcomePromptShown = true;
			socket.emit('userHideWelcomePrompt', true);
		}

		showWelcomePrompt(false);
	});

	$('.smartscan').click(function () {
		if (smartScanRunning) {
			endSmartScan();
		} else {
			startSmartScan();
		}
	});

	function startSmartScan() {
		smartScanRunning = true;
		config.isbnInput.val('');

		$('#application').addClass('smartScanRunning');
		config.isbnInput.attr('data-old-placeholder', config.isbnInput.attr('placeholder'));
		config.isbnInput.attr('placeholder', 'Smart scan running... Re-scan barcode.');

		smartScanInterval = setInterval(function(){
			var newText = config.isbnInput.attr('placeholder') + '.';

			if (newText[newText.length - 6] === '.') {
				newText = 'Smart scan running... Re-scan barcode.';
			}

			config.isbnInput.attr('placeholder', newText);
		}, 1000);
	}

	function endSmartScan() {
		smartScanRunning = false;
		clearInterval(smartScanInterval);
		smartScanInterval = null;
		config.isbnInput.attr('placeholder', config.isbnInput.attr('data-old-placeholder'));
		$('#application').removeClass('smartScanRunning');
	}

	config.isbnInput.keypress(function keypressHandler(event) {
		var entryKey = 'Enter';
		if (account !== null && typeof account.entryKey !== 'undefined') {
			entryKey = account.entryKey;
		}

		var isbn = parseIsbn(config.isbnInput.val());
		var eventKeyString = buildEventKeyString(event);
		console.log('Event key string: ', eventKeyString, validateIsbn(isbn))
		if (smartScanRunning && validateIsbn(isbn)) {
			console.log('Smart scan identified key combo: ', eventKeyString);
			endSmartScan();
			entryKey = account.entryKey = eventKeyString;
			socket.emit('setUserEntryKey', eventKeyString);
		}

		if (eventKeyString === entryKey && (!smartScanRunning || validateIsbn(isbn))) {
			config.isbnInput.focus();

			if (!validateIsbn(isbn)) {
				alert("Invalid isbn!");
				return;
			}

			if (++numSearches >= config.donationSearchThreshold && !config.donationPromptShown) {
				runIfUserPropertyEquals('hasDonated', false, wrapFuncCB(showDonationPrompt, true));
			}

			if (++numVisibleSearches >= config.maxVisibleBooks) {
				--numVisibleSearches;
				$('#searchList .addedIsbn:last-child').fadeOut(config.animateSpeed, function () {
					$(this).remove();
				});
			}

			config.isbnInput.val('');

			var condition = parseInt(config.conditionInput.val());

			socket.emit('addIsbn', {
				condition: condition,
				isbn: isbn,
			});

			$('#searchList').prepend(template.replace(/\{\{isbn\}\}/g, isbn));

			if (helperVisible) {
				config.isbnHelper.fadeOut(config.animateSpeed);
				helperVisible = false;
			}
		}
	});

	function buildEventKeyString(e) {
		var keys = [ e.key ];

		if (e.metaKey) {
			keys.push('Meta');
		}

		if (e.shiftKey) {
			keys.push('Shift');
		}

		if (e.ctrlKey) {
			keys.push('Control');
		}

		keys.sort();
		return keys.join('+');
	}

	function validateIsbn(isbn) {
		if (typeof isbn !== 'string') {
			return false;
		}

		return null !== isbn.match(/^([0-9]{10}|[0-9]{13})$/);
	}

	function parseIsbn(isbn) {
		if (typeof isbn !== 'string') {
			return '';
		}

		isbn = isbn.replace(/-/g, '').trim();

		if (isbn.length === 9) {
			return '0' + isbn;
		}

		return isbn;
	}

	var promptBg = '

'
	function showPrompt(prompt, show) {
		if (show) {
			if ($('#prompt-cover').length === 0) {
				$('body').append(promptBg);
			}

			$(prompt).show();
		} else {
			$('#prompt-cover').remove();
			$(prompt).hide();
		}
	}

	function hideAllPrompts() {
		$('.prompt').hide();
	}

	function showWelcomePrompt(show) {
		hideAllPrompts();
		config.welcomePromptShown |= show;
		showPrompt(config.welcomePrompt, show);
	}

	function showDonationPrompt(show) {
		hideAllPrompts();
		config.donationPromptShown |= show;
		showPrompt(config.donationPrompt, show);

		if (show) {
			window.location.hash = '#donate';
		} else {
			window.location.hash = '';
		}
	}

	function wrapFuncCB(func) {
		var $this = this;
		var args = Array.prototype.slice.call(arguments);
		args.splice(0, 1);
		return function() {
			return func.apply($this, args);
		}
	}

	function runIfUserPropertyEquals(property, desiredValue, callback) {
		if (account !== null && typeof account[property] !== 'undefined' && account[property] === desiredValue) {
			callback();
		}
	}

	switch (window.location.hash) {
		case '':
			break;
		case '#welcome':
			showWelcomePrompt(true);
			break;
		case '#donate':
			showDonationPrompt(true);
			break;
	}
});<|endoftext|>


<commit_before>function spaceShip() {
  this.sprite;
  this.position = { width : 60, height: 0};
  this.speed = 10;
  this.init();
};

spaceShip.prototype.init = function () {
  this.sprite = new Image();
  this.sprite.src = 'ship/ship.png';
};

spaceShip.prototype.build = function (context) {
  context.drawImage(this.sprite, this.position.width, this.position.height);
};

function SpaceBackground(imageURL, height, exibitionArea) {
  this.backgroundImage = new Image();
  this.initialHeight = height;
  this.currentHeight = this.initialHeight;
  this.currentWidth = this.initialHeight;
  this.exibitionArea = exibitionArea;
  this.speed = 1;
  this.isReady = false;
  var self = this;
  this.backgroundImage.onload = function () {
	self.isReady = true;
  };
  this.backgroundImage.src = imageURL;
};

SpaceBackground.prototype.build = function (context) {
	if (this.isReady) {
		if (parseInt(this.currentHeight) == this.initialHeight) {
			this.currentHeight = this.backgroundImage.height - this.exibitionArea;
		}
		context.drawImage(this.backgroundImage, 0, -this.currentHeight);
		this.currentHeight -= this.speed;
	} else {
		context.fillStyle = "blue";
		context.font = "bold 23px Arial";
		context.fillText("Loading background...", context.canvasWidth/2.5, context.canvasHeight/2 );
	}
};

var endlessSpace = ({
  background: null,
  canvas: null,
  context: null,

  init: function () {
    this.canvas = document.getElementById('endlessCanvas');
    this.context = this.canvas.getContext("2d");
	this.context.canvasWidth = this.canvas.scrollWidth;
	this.context.canvasHeight = this.canvas.scrollHeight;
    this.background = new SpaceBackground('background/space.jpg', 0, this.canvas.height);
    this.onReady();
    return this;
  },

  isReady: function () {
	return this.background.isReady;
  },

  onReady: function () {
	var self = this;
	var id = setInterval(function () {
			if (self.isReady()) {
				new ClockCounter().startCronometer();
				clearInterval(id);
				self.refreshScreen();
			}
		}, 15);
	},

	refreshScreen: function () {
		var self = this;
		setInterval(function () {
			self.context.clearRect(0 ,0, self.canvas.width, self.canvas.height );
			self.background.build(self.context);
		}, parseInt(1000/60) - 1);
	},
}).init();
<commit_msg>inserting loading message<commit_after>function spaceShip() {
  this.sprite;
  this.position = { width : 60, height: 0};
  this.speed = 10;
  this.init();
};

spaceShip.prototype.init = function () {
  this.sprite = new Image();
  this.sprite.src = 'ship/ship.png';
};

spaceShip.prototype.build = function (context) {
  context.drawImage(this.sprite, this.position.width, this.position.height);
};

function SpaceBackground(imageURL, height, exibitionArea) {
  this.backgroundImage = new Image();
  this.initialHeight = height;
  this.currentHeight = this.initialHeight;
  this.currentWidth = this.initialHeight;
  this.exibitionArea = exibitionArea;
  this.speed = 1;
  this.isReady = false;
  var self = this;
  this.backgroundImage.onload = function () {
	self.isReady = true;
  };
  this.backgroundImage.src = imageURL;
};

SpaceBackground.prototype.build = function (context) {
	if (this.isReady) {
		if (parseInt(this.currentHeight) == this.initialHeight) {
			this.currentHeight = this.backgroundImage.height - this.exibitionArea;
		}
		context.drawImage(this.backgroundImage, 0, -this.currentHeight);
		this.currentHeight -= this.speed;
	}
};

var endlessSpace = ({
  background: null,
  canvas: null,
  context: null,

  init: function () {
    this.canvas = document.getElementById('endlessCanvas');
    this.context = this.canvas.getContext("2d");
	this.context.canvasWidth = this.canvas.scrollWidth;
	this.context.canvasHeight = this.canvas.scrollHeight;
    this.background = new SpaceBackground('background/space.jpg', 0, this.canvas.height);
    this.onReady();
    return this;
  },

  isReady: function () {
	return this.background.isReady;
  },

  onReady: function () {
	var self = this;
	var id = setInterval(function () {
			if (self.isReady()) {
				new ClockCounter().startCronometer();
				clearInterval(id);
				self.refreshScreen();
			} else {
				context.fillStyle = "blue";
				context.font = "bold 23px Arial";
				context.fillText("Loading...", self.context.canvasWidth/2.5, self.context.canvasHeight/2 );
			}
		}, 15);
	},

	refreshScreen: function () {
		var self = this;
		setInterval(function () {
			self.context.clearRect(0 ,0, self.canvas.width, self.canvas.height );
			self.background.build(self.context);
		}, parseInt(1000/60) - 1);
	},
}).init();
<|endoftext|>


<commit_before>module.exports = {
  apps : [
    {
      name      : 'Move TV',
      script    : 'app.js',
      args      : ['-p', '-s', '/mnt/library/Downloads/complete/TV', '-d', '/mnt/library/TV']
    },

    {
      name      : 'Move Movies',
      script    : 'app.js',
      args      : ['-s', '/mnt/library/Downloads/complete/Movies', '-d', '/mnt/library/Movies']
    }
  ],

  deploy : {
    production : {
      user : 'pi',
      host : '10.1.1.15',
      ref  : 'origin/master',
      repo : 'git@github.com:ducas/movie-maid.git',
      path : '/home/pi/movie-maid-deploy',
      'post-deploy' : 'npm install && pm2 reload ecosystem.config.js --env production'
    }
  }
};
<commit_msg>add 5min restart delay<commit_after>module.exports = {
  apps : [
    {
      name      : 'Move TV',
      script    : 'app.js',
      args      : ['-p', '-s', '/mnt/library/Downloads/complete/TV', '-d', '/mnt/library/TV'],
      restart_delay: 300000
    },

    {
      name      : 'Move Movies',
      script    : 'app.js',
      args      : ['-s', '/mnt/library/Downloads/complete/Movies', '-d', '/mnt/library/Movies'],
      restart_delay: 300000
    }
  ],

  deploy : {
    production : {
      user : 'pi',
      host : '10.1.1.15',
      ref  : 'origin/master',
      repo : 'git@github.com:ducas/movie-maid.git',
      path : '/home/pi/movie-maid-deploy',
      'post-deploy' : 'npm install && pm2 reload ecosystem.config.js --env production'
    }
  }
};
<|endoftext|>


<commit_before>/*jshint node:true*/
module.exports = {
  "framework": "qunit",
  "test_page": "tests/index.html?hidepassed",
  "disable_watching": true,
  "launch_in_ci": [
    "Chrome"
  ],
  "launch_in_dev": [
    "Chrome"
  ],
  "browser_args": {
    "Chrome": [
      '--headless',
      '--disable-gpu',
      '--remote-debugging-port=9222',
      '--window-size=1440,900'
    ]
  }
};
<commit_msg>Try fix tests<commit_after>/*jshint node:true*/
module.exports = {
  "framework": "qunit",
  "test_page": "tests/index.html?hidepassed",
  "disable_watching": true,
  "launch_in_ci": [
    "Chrome"
  ],
  "launch_in_dev": [
    "Chrome"
  ],
  "browser_args": {
    "Chrome": [
      '--headless',
      '--disable-gpu',
      '--no-sandbox',
      '--remote-debugging-port=9222',
      '--window-size=1440,900'
    ]
  }
};
<|endoftext|>


<commit_before>define(['shapes/polygon'], function(Polygon){

	var Collision = {
		/**
		 * Check for collision between two circles.
		 * @param {Thruster.Shapes.Circle} circle1
		 * @param {Thruster.Shapes.Point2d} circle1Pos Center position of the first circle.
		 * @param {Thruster.Shapes.Circle} circle2
		 * @param {Thruster.Shapes.Point2d} circle2Pos Center position of the second circle.
		 * @returns {Boolean} True if the circles collide, false if not.
		 */
		circleOnCircle: function(circle1, circle1Pos, circle2, circle2Pos){
			return circle1Pos.distanceTo(circle2Pos) <= circle1.radius + circle2.radius;
		},

		circleOnPolygon: function(circle, circlePosition, polygon, polygonPosition, polygonAngle){
			var vertices = polygon.getVertices(polygonPosition, polygonAngle),
				projectionAxes = polygon.getNormals(polygonAngle);

			// Find closest vertex to circle's center point
			var closestDist = null,
				closestVertex,
				dist;
			for (var i in vertices){
				dist = circlePosition.distanceTo(vertices[i]);
				if (closestDist === null || dist < closestDist){
					closestVertex = vertices[i];
					closestDist = dist;
				}
			}

			// Add vector (from circle centerpoint to closest vertex) to list of projection axes.
			projectionAxes.push(circlePosition.vectorTo(closestVertex));

			// Use modified separating axis theory to detect collisions.
			var collision = true,
				polyLow = null,
				polyHigh = null,
				circleLow = null,
				circleHigh = null,
				projectedVertex,
				projectedCircleCenter,
				axis;
			for (var axisIndex in projectionAxes){
				axis = projectionAxes[axisIndex];

				projectedCircleCenter = circlePosition.toVector().scalarProjection(axis);
				circleLow = projectedCircleCenter - circle.radius;
				circleHigh = projectedCircleCenter + circle.radius;

				for (var vertexIndex in vertices){
					projectedVertex = vertices[vertexIndex].toVector().scalarProjection(axis);

					if (polyLow === null || projectedVertex < polyLow){ polyLow = projectedVertex; }
					if (polyHigh === null || projectedVertex > polyHigh){ polyHigh = projectedVertex; }
				}

				if (circleHigh < polyLow || circleLow > polyHigh){
					collision = false;
					break;
				}
			}

			return collision;
		},

		/**
		 * Check for collision between a point and a circle.
		 * @param {Thruster.Shapes.Point2d} point
		 * @param {Thruster.Shapes.Circle} circle
		 * @param {Thruster.Shapes.Point2d} circlePos Position of the center of the circle.
		 * @returns {Boolean} True if the point and circle collide, false if not.
		 */
		pointOnCircle: function(point, circle, circlePos){
			return point.distanceTo(circlePos) <= circle.radius;
		},

		/**
		 * Check for collision between a point and a convex polygon.
		 * @param {Thruster.Shapes.Point2d} point
		 * @param {Thruster.Shapes.Polygon} polygon
		 * @param {Thruster.Shapes.Point2d} polygonPosition The position of the polygon.
		 * @param {Number} polygonAngle The rotation angle of the polygon.
		 * @returns {Boolean} True if the point and polygon collide, false if not.
		 */
		pointOnPolygon: function(point, polygon, polygonPosition, polygonAngle){
			var vertices = polygon.getVertices(polygonPosition, polygonAngle),
				normals = polygon.getNormals(polygonAngle),
				collision = true,
				polyLow = null,
				polyHigh = null,
				projectedPoint, projectedVertex;

			// Project all points onto the polygon's normals. If the projected point lies outside
			// the projected vertices on any normal, the two aren't in collision.
			for (var nIndex in normals){
				projectedPoint = point.toVector().scalarProjection(normals[nIndex]);

				for (var vIndex in vertices){
					projectedVertex = vertices[vIndex].toVector().scalarProjection(normals[nIndex]);

					if (polyLow === null || projectedVertex < polyLow){ polyLow = projectedVertex; }
					if (polyHigh === null || projectedVertex > polyHigh){ polyHigh = projectedVertex; }
				}

				if (polyLow > projectedPoint || polyHigh < projectedPoint){
					collision = false;
					break;
				}
			}

			return collision;
		},

		/**
		 * Check for collision between two convex polygons.
		 * @param {Thruster.Shapes.Polygon} polygon1 The first shape.
		 * @param {Thruster.Shapes.Point2d} p1Position Position of the first shape.
		 * @param {Number} p1Angle Angle of the first shape, in radians from the positive x axis.
		 * @param {Thruster.Shapes.Polygon} polygon2 The second shape.
		 * @param {Thruster.Shapes.Point2d} p2Position Position of the second shape.
		 * @param {Number} p2Angle Angle of the second shape, in radians from the positive x axis.
		 * @returns {Boolean} True if the shapes collide, false if not.
		 */
		polygonOnPolygon: function(polygon1, p1Position, p1Angle, polygon2, p2Position, p2Angle){
			// Use the separating axis theorem to detect any gaps between the shapes.
			var p1v = polygon1.getVertices(p1Position, p1Angle),
				p1n = polygon1.getNormals(p1Angle),
				p2v = polygon2.getVertices(p2Position, p2Angle),
				p2n = polygon2.getNormals(p2Angle);

			var normals = p1n.concat(p2n),
				normal, projection, p1Low, p1High, p2Low, p2High,
				collision = true;

			for (var nIndex in normals){
				normal = normals[nIndex];
				// Set all thresholds to null.
				p1Low = p1High = p2Low = p2High = null;

				for (var vIndex in p1v){
					projection = p1v[vIndex].toVector().scalarProjection(normal);

					if (p1Low === null || projection < p1Low){ p1Low = projection; }
					if (p1High === null || projection > p1High){ p1High = projection; }
				}

				for (var vIndex in p2v){
					projection = p2v[vIndex].toVector().scalarProjection(normal);

					if (p2Low === null || projection < p2Low){ p2Low = projection; }
					if (p2High === null || projection > p2High){ p2High = projection; }
				}

				if (p1High < p2Low || p1Low > p2High){
					collision = false;
					break;
				}
			}

			return collision;
		}
	};

	return Collision;

});<commit_msg>Added JSDoc documentation for Shapes/Collision.circleOnPolygon().<commit_after>define(['shapes/polygon'], function(Polygon){

	var Collision = {
		/**
		 * Check for collision between two circles.
		 * @param {Thruster.Shapes.Circle} circle1
		 * @param {Thruster.Shapes.Point2d} circle1Pos Center position of the first circle.
		 * @param {Thruster.Shapes.Circle} circle2
		 * @param {Thruster.Shapes.Point2d} circle2Pos Center position of the second circle.
		 * @returns {Boolean} True if the circles collide, false if not.
		 */
		circleOnCircle: function(circle1, circle1Pos, circle2, circle2Pos){
			return circle1Pos.distanceTo(circle2Pos) <= circle1.radius + circle2.radius;
		},

		/**
		 * Check for collision between a circle and a polygon.
		 * @param {Thruster.Shapes.Circle} circle
		 * @param {Thruster.Shapes.Point2d} circlePosition Center position of the circle.
		 * @param {Thruster.Shapes.Polygon} polygon
		 * @param {Thruster.Shapes.Point2d} circlePosition Position of the polygon.
		 * @param {Number} polygonAngle The rotation angle of the polygon.
		 */
		circleOnPolygon: function(circle, circlePosition, polygon, polygonPosition, polygonAngle){
			var vertices = polygon.getVertices(polygonPosition, polygonAngle),
				projectionAxes = polygon.getNormals(polygonAngle);

			// Find closest vertex to circle's center point
			var closestDist = null,
				closestVertex,
				dist;
			for (var i in vertices){
				dist = circlePosition.distanceTo(vertices[i]);
				if (closestDist === null || dist < closestDist){
					closestVertex = vertices[i];
					closestDist = dist;
				}
			}

			// Add vector (from circle centerpoint to closest vertex) to list of projection axes.
			projectionAxes.push(circlePosition.vectorTo(closestVertex));

			// Use modified separating axis theory to detect collisions.
			var collision = true,
				polyLow = null,
				polyHigh = null,
				circleLow = null,
				circleHigh = null,
				projectedVertex,
				projectedCircleCenter,
				axis;
			for (var axisIndex in projectionAxes){
				axis = projectionAxes[axisIndex];

				projectedCircleCenter = circlePosition.toVector().scalarProjection(axis);
				circleLow = projectedCircleCenter - circle.radius;
				circleHigh = projectedCircleCenter + circle.radius;

				for (var vertexIndex in vertices){
					projectedVertex = vertices[vertexIndex].toVector().scalarProjection(axis);

					if (polyLow === null || projectedVertex < polyLow){ polyLow = projectedVertex; }
					if (polyHigh === null || projectedVertex > polyHigh){ polyHigh = projectedVertex; }
				}

				if (circleHigh < polyLow || circleLow > polyHigh){
					collision = false;
					break;
				}
			}

			return collision;
		},

		/**
		 * Check for collision between a point and a circle.
		 * @param {Thruster.Shapes.Point2d} point
		 * @param {Thruster.Shapes.Circle} circle
		 * @param {Thruster.Shapes.Point2d} circlePos Position of the center of the circle.
		 * @returns {Boolean} True if the point and circle collide, false if not.
		 */
		pointOnCircle: function(point, circle, circlePos){
			return point.distanceTo(circlePos) <= circle.radius;
		},

		/**
		 * Check for collision between a point and a convex polygon.
		 * @param {Thruster.Shapes.Point2d} point
		 * @param {Thruster.Shapes.Polygon} polygon
		 * @param {Thruster.Shapes.Point2d} polygonPosition The position of the polygon.
		 * @param {Number} polygonAngle The rotation angle of the polygon.
		 * @returns {Boolean} True if the point and polygon collide, false if not.
		 */
		pointOnPolygon: function(point, polygon, polygonPosition, polygonAngle){
			var vertices = polygon.getVertices(polygonPosition, polygonAngle),
				normals = polygon.getNormals(polygonAngle),
				collision = true,
				polyLow = null,
				polyHigh = null,
				projectedPoint, projectedVertex;

			// Project all points onto the polygon's normals. If the projected point lies outside
			// the projected vertices on any normal, the two aren't in collision.
			for (var nIndex in normals){
				projectedPoint = point.toVector().scalarProjection(normals[nIndex]);

				for (var vIndex in vertices){
					projectedVertex = vertices[vIndex].toVector().scalarProjection(normals[nIndex]);

					if (polyLow === null || projectedVertex < polyLow){ polyLow = projectedVertex; }
					if (polyHigh === null || projectedVertex > polyHigh){ polyHigh = projectedVertex; }
				}

				if (polyLow > projectedPoint || polyHigh < projectedPoint){
					collision = false;
					break;
				}
			}

			return collision;
		},

		/**
		 * Check for collision between two convex polygons.
		 * @param {Thruster.Shapes.Polygon} polygon1 The first shape.
		 * @param {Thruster.Shapes.Point2d} p1Position Position of the first shape.
		 * @param {Number} p1Angle Angle of the first shape, in radians from the positive x axis.
		 * @param {Thruster.Shapes.Polygon} polygon2 The second shape.
		 * @param {Thruster.Shapes.Point2d} p2Position Position of the second shape.
		 * @param {Number} p2Angle Angle of the second shape, in radians from the positive x axis.
		 * @returns {Boolean} True if the shapes collide, false if not.
		 */
		polygonOnPolygon: function(polygon1, p1Position, p1Angle, polygon2, p2Position, p2Angle){
			// Use the separating axis theorem to detect any gaps between the shapes.
			var p1v = polygon1.getVertices(p1Position, p1Angle),
				p1n = polygon1.getNormals(p1Angle),
				p2v = polygon2.getVertices(p2Position, p2Angle),
				p2n = polygon2.getNormals(p2Angle);

			var normals = p1n.concat(p2n),
				normal, projection, p1Low, p1High, p2Low, p2High,
				collision = true;

			for (var nIndex in normals){
				normal = normals[nIndex];
				// Set all thresholds to null.
				p1Low = p1High = p2Low = p2High = null;

				for (var vIndex in p1v){
					projection = p1v[vIndex].toVector().scalarProjection(normal);

					if (p1Low === null || projection < p1Low){ p1Low = projection; }
					if (p1High === null || projection > p1High){ p1High = projection; }
				}

				for (var vIndex in p2v){
					projection = p2v[vIndex].toVector().scalarProjection(normal);

					if (p2Low === null || projection < p2Low){ p2Low = projection; }
					if (p2High === null || projection > p2High){ p2High = projection; }
				}

				if (p1High < p2Low || p1Low > p2High){
					collision = false;
					break;
				}
			}

			return collision;
		}
	};

	return Collision;

});<|endoftext|>


<commit_before>module.exports = function(config) {
  var sauceBrowsers = {
    sl_chrome: {
      base: 'SauceLabs',
      browserName: 'chrome',
      platform: 'Windows 10',
      version: '54.0'
    },
    sl_safari: {
      base: 'SauceLabs',
      browserName: 'safari',
      platform: 'OS X 10.11',
      version: '10.0'
    },
    sl_firefox: {
      base: 'SauceLabs',
      browserName: 'firefox',
      platform: 'Windows 10',
      version: '49.0'
    },
    sl_ms_edge: {
      base: 'SauceLabs',
      browserName: 'MicrosoftEdge',
      platform: 'Windows 10',
      version: '14.14393'
    },
    sl_ie_11: {
      base: 'SauceLabs',
      browserName: 'internet explorer',
      platform: 'Windows 10',
      version: '11.103'
    },
    sl_ios: {
      base: 'SauceLabs',
      browserName: 'Safari',
      appiumVersion: '1.6.0',
      deviceName: 'iPhone Simulator',
      deviceOrientation: 'portrait',
      platformName: 'iOS',
      platformVersion: '10.0'
    },
    sl_android: {
      base: 'SauceLabs',
      browserName: 'Browser',
      appiumVersion: '1.6.0',
      deviceName: 'Android Emulator',
      deviceOrientation: 'portrait',
      platformVersion: '5.1',
      platformName: 'Android'
    }
  }
  config.set({

    // base path that will be used to resolve all patterns (eg. files, exclude)
    basePath: '',

    // register browsers
    customLaunchers: sauceBrowsers,
    browsers: process.env.CI ? Object.keys(sauceBrowsers) : ['PhantomJS'],

    // SauceLabs config for CI
    sauceLabs: {
      testName: 'dom-observer suite',
    },

    // frameworks to use
    // available frameworks: https://npmjs.org/browse/keyword/karma-adapter
    frameworks: ['mocha', 'chai', 'sinon'],

    // Registered plugins
    plugins: [
      'karma-phantomjs-launcher',
      'karma-sauce-launcher',
      'karma-sourcemap-loader',
      'karma-mocha',
      'karma-chai',
      'karma-sinon',
      'karma-coverage',
      'karma-webpack'
    ],

    // list of files / patterns to load in the browser
    files: ['tests.webpack.js'],

    // list of files to exclude
    exclude: [],

    // preprocess matching files before serving them to the browser
    // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
    preprocessors: {
      'tests.webpack.js': ['webpack', 'sourcemap']
    },

    // Webpack config
    webpack: {
      devtool: 'inline-source-map',
      module: {
        preLoaders: [
          {
            test: /\.js$/,
            exclude: /(test|node_modules)\//,
            loader: 'isparta-loader'
          }
        ],
        loaders: [
          {
            test: /\.js$/,
            loader: 'babel-loader',
            exclude: /node_modules/
          }
        ]
      }
    },

    webpackServer: {
      noInfo: true
    },

    coverageReporter: {
      reporters: [
        {
          type: 'lcovonly',
          dir: 'coverage/',
          subdir: '.',
          file: 'lcov.info'
        },
        {
          type: 'html',
          dir: 'coverage/',
          file: 'coverage.html'
        },
        {
          type: 'text-summary'
        }
      ]
    },

    // test results reporter to use
    // available reporters: https://npmjs.org/browse/keyword/karma-reporter
    reporters: process.env.CI ? ['progress', 'saucelabs', 'coverage'] : ['progress', 'coverage'],

    // web server port
    port: 9876,

    // enable / disable colors in the output (reporters and logs)
    colors: true,

    // level of logging
    logLevel: config.LOG_INFO

  });
};
<commit_msg>Remove appium based browsers<commit_after>module.exports = function(config) {
  var sauceBrowsers = {
    sl_chrome: {
      base: 'SauceLabs',
      browserName: 'chrome',
      platform: 'Windows 10',
      version: '54.0'
    },
    sl_safari: {
      base: 'SauceLabs',
      browserName: 'safari',
      platform: 'OS X 10.11',
      version: '10.0'
    },
    sl_firefox: {
      base: 'SauceLabs',
      browserName: 'firefox',
      platform: 'Windows 10',
      version: '49.0'
    },
    sl_ms_edge: {
      base: 'SauceLabs',
      browserName: 'MicrosoftEdge',
      platform: 'Windows 10',
      version: '14.14393'
    },
    sl_ie_11: {
      base: 'SauceLabs',
      browserName: 'internet explorer',
      platform: 'Windows 10',
      version: '11.103'
    }
  }
  config.set({

    // base path that will be used to resolve all patterns (eg. files, exclude)
    basePath: '',

    // register browsers
    customLaunchers: sauceBrowsers,
    browsers: process.env.CI ? Object.keys(sauceBrowsers) : ['PhantomJS'],

    // SauceLabs config for CI
    sauceLabs: {
      testName: 'dom-observer suite',
    },

    // frameworks to use
    // available frameworks: https://npmjs.org/browse/keyword/karma-adapter
    frameworks: ['mocha', 'chai', 'sinon'],

    // Registered plugins
    plugins: [
      'karma-phantomjs-launcher',
      'karma-sauce-launcher',
      'karma-sourcemap-loader',
      'karma-mocha',
      'karma-chai',
      'karma-sinon',
      'karma-coverage',
      'karma-webpack'
    ],

    // list of files / patterns to load in the browser
    files: ['tests.webpack.js'],

    // list of files to exclude
    exclude: [],

    // preprocess matching files before serving them to the browser
    // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
    preprocessors: {
      'tests.webpack.js': ['webpack', 'sourcemap']
    },

    // Webpack config
    webpack: {
      devtool: 'inline-source-map',
      module: {
        preLoaders: [
          {
            test: /\.js$/,
            exclude: /(test|node_modules)\//,
            loader: 'isparta-loader'
          }
        ],
        loaders: [
          {
            test: /\.js$/,
            loader: 'babel-loader',
            exclude: /node_modules/
          }
        ]
      }
    },

    webpackServer: {
      noInfo: true
    },

    coverageReporter: {
      reporters: [
        {
          type: 'lcovonly',
          dir: 'coverage/',
          subdir: '.',
          file: 'lcov.info'
        },
        {
          type: 'html',
          dir: 'coverage/',
          file: 'coverage.html'
        },
        {
          type: 'text-summary'
        }
      ]
    },

    // test results reporter to use
    // available reporters: https://npmjs.org/browse/keyword/karma-reporter
    reporters: process.env.CI ? ['progress', 'saucelabs', 'coverage'] : ['progress', 'coverage'],

    // web server port
    port: 9876,

    // enable / disable colors in the output (reporters and logs)
    colors: true,

    // level of logging
    logLevel: config.LOG_INFO

  });
};
<|endoftext|>


<commit_before>var fs = require('fs'),
    path = require('path'),
    walk = require('./utils').walk;
    log = require('../utils').log;

var logger = new log('READER');

function read(callback){
  var _this = this;

  var content_abspath = path.resolve(this.work_path, this.content_path),
      content_index = path.resolve(content_abspath).split(path.sep).pop();

  walk(content_abspath, function(tree){
    pullTree.call(_this, tree[content_index]);
    _this.raw_content.forEach(function(post_path, index){
      buildPost.call(_this, post_path, index);
    });
    if (callback) {callback();}
    return _this.raw_content;
  });
}

/*===Helpers===*/

function pullTree(tree){
  for (var node in tree){
    if (typeof tree[node] == 'object') { // folder found
        this.folders.push(node);
        arguments.callee.call(this, tree[node]);
    }
    else {
      this.raw_content.push(tree[node]);
    }
  }
}

function buildPost(post_path, index){
  var _this = this;
  var post = {};
  var data = fs.readFileSync(post_path).toString();

  var meta, content;
  var all = data.split('======');
  meta = all[1];
  content = all[2];

  if (meta == undefined || content == undefined) {
    logger.warning('Bad Post :' + post_path);
    return;
  }

  var metas = meta.split('\n');
  for (var key in metas){
    var name = metas[key].split(':')[0],
        value = metas[key].split(':')[1];
    if (name){
      post[name.trim()] = value.trim();
    }else continue;
  }
  post.content = content;

  post.abs_path = post_path;
  post.target_folder = path.join(path.resolve(this.deploy_path), path.relative(this.content_path, path.dirname(post_path)));
  post.folder = path.relative(this.deploy_path, post.target_folder);
  post.basename = path.basename(post_path, path.extname(post_path))
  post.perm_link = this.config.site_config.site_url + path.relative(this.content_path, post_path).replace(path.extname(post_path), '.html');

  post.tags = post.tags.split(',').
    filter(function(ele, index){
      return (ele.trim() != '');
    }).
    map(function(ele){
      return ele.trim();
    });

  _this.raw_content[index] = post;
}

exports.read = read;
<commit_msg>use Post.set() assigning property<commit_after>var fs = require('fs'),
    path = require('path'),

    Post = require('../model/post').Post,

    walk = require('./utils').walk;
    log = require('../utils').log;

var logger = new log('READER');

function read(callback){
  var _this = this;

  var content_abspath = path.resolve(this.work_path, this.content_path),
      content_index = path.resolve(content_abspath).split(path.sep).pop();

  walk(content_abspath, function(tree){
    pullTree.call(_this, tree[content_index]);
    _this.raw_content.forEach(function(post_path, index){
      buildPost.call(_this, post_path, index);
    });
    if (callback) {callback();}
    return _this.raw_content;
  });
}

/*===Helpers===*/

function pullTree(tree){
  for (var node in tree){
    if (typeof tree[node] == 'object') { // folder found
        this.folders.push(node);
        arguments.callee.call(this, tree[node]);
    }
    else {
      this.raw_content.push(tree[node]);
    }
  }
}

function buildPost(post_path, index){
  var _this = this;
  var post = new Post();

  var data = fs.readFileSync(post_path).toString();

  var meta, content;
  var all = data.split('======');
  meta = all[1];
  content = all[2];

  if (meta === undefined || content === undefined) {
    logger.warning('Bad Post :' + post_path);
    return;
  }

  var metas = meta.split('\n');
  for (var key in metas){
    var name = metas[key].split(':')[0],
        value = metas[key].split(':')[1];
    if (name){
      post.set(name.trim(), value.trim());
    }else continue;
  }
  post.set('content', content);

  post.set('abs_path', post_path);
  post.set('target_folder', path.join(path.resolve(this.deploy_path), path.relative(this.content_path, path.dirname(post_path))));
  post.set('folder', path.relative(this.deploy_path, post.target_folder));
  post.set('basename', path.basename(post_path, path.extname(post_path)));
  post.set('perm_link', this.config.site_config.site_url + path.relative(this.content_path, post_path).replace(path.extname(post_path), '.html'));

  post.set('tags', post.tags.split(',').
    filter(function(ele, index){
      return (ele.trim() !== '');
    }).
    map(function(ele){
      return ele.trim();
    }));

  _this.raw_content[index] = post;
}

exports.read = read;
<|endoftext|>


<commit_before>var mongoose = require('mongoose');
var Event = require('../data/event');
var _ = require('underscore');

var router = require('express').Router();
router.route('/:id').post(editEvent).delete(deleteEvent);
router.route('/').get(getEvents).post(addEvent);

// nodemailer
var nodemailer = require('nodemailer');
var smtpConfig = {
	host: 'smtp.gmail.com',
	port: 465,
	secure: true,
	auth: {
		user: 'amr.notify@gmail.com',
		pass: process.env.EMAIL_PASSWORD
	}
};
var transporter = nodemailer.createTransport(smtpConfig);
transporter.verify(function(err, success) {
	if (err) {
		console.log(err);
	} else {
		console.log('Email server ready...');
	}
})

var mailData = {
	from: 'amr.notify@gmail.com',
	to: 'chris.witulski@gmail.com'
}

// App functions
function getEvents(req, res) {
    Event.find(function (err, events) {
        if (err) res.send(err);
        else res.json(events);
    });
}

function addEvent(req, res) {
    var event = new Event(_.extend({}, req.body));

	mailData.subject = '[AMR] Event created';
	mailData.text = event.owner + ' created an event called ' + event.name + '\r\n' +
		'Date: ' + event.date.toLocaleString() + '\r\n' +
		'Location: ' + event.location + '\r\n' +
		'Description: ' + event.description + '\r\n' +
		'Other information may be available on the site.'
	transporter.sendMail(mailData);

    event.save(function (err) {
        if (err) res.send(err);
        else res.json(event);
    });
}

function editEvent(req, res) {
    var id = req.params.id;
    var info = req.body;

	mailData.subject = '[AMR] Event edited';
	mailData.text = event.owner + ' updated an event called ' + event.name + '\r\n' +
		'Date: ' + event.date.toLocaleString() + '\r\n' +
		'Location: ' + event.location + '\r\n' +
		'Description: ' + event.description + '\r\n' +
		'Other information may be available on the site.'
	transporter.sendMail(mailData);

    var query = { _id: id },
        update = { $set: {
            name: info.name,
            location: info.location,
            description: info.description,
            date: new Date(info.date),
            tags: info.tags,
            contactName: info.contactName,
            contactEmail: info.contactEmail,
            edited: info.edited,
            editDate: info.editDate
        }};
    Event.update(query, update, function (err, updated) {
        if (err) res.send(err);
        else res.json(updated);
    });
}

function deleteEvent(req, res) {
    var id = req.params.id;

	mailData.subject = '[AMR] Event deleted';
	mailData.text = info.owner + ' deleted event ID ' + id;
	transporter.sendMail(mailData);

    Event.remove({ _id: id }, function (err, removed) {
        if (err) res.send(err);
        else res.json(removed);
    });
}

module.exports = router;
<commit_msg>update another typo...<commit_after>var mongoose = require('mongoose');
var Event = require('../data/event');
var _ = require('underscore');

var router = require('express').Router();
router.route('/:id').post(editEvent).delete(deleteEvent);
router.route('/').get(getEvents).post(addEvent);

// nodemailer
var nodemailer = require('nodemailer');
var smtpConfig = {
	host: 'smtp.gmail.com',
	port: 465,
	secure: true,
	auth: {
		user: 'amr.notify@gmail.com',
		pass: process.env.EMAIL_PASSWORD
	}
};
var transporter = nodemailer.createTransport(smtpConfig);
transporter.verify(function(err, success) {
	if (err) {
		console.log(err);
	} else {
		console.log('Email server ready...');
	}
})

var mailData = {
	from: 'amr.notify@gmail.com',
	to: 'chris.witulski@gmail.com'
}

// App functions
function getEvents(req, res) {
    Event.find(function (err, events) {
        if (err) res.send(err);
        else res.json(events);
    });
}

function addEvent(req, res) {
    var event = new Event(_.extend({}, req.body));

	mailData.subject = '[AMR] Event created';
	mailData.text = event.owner + ' created an event called ' + event.name + '\r\n' +
		'Date: ' + event.date.toLocaleString() + '\r\n' +
		'Location: ' + event.location + '\r\n' +
		'Description: ' + event.description + '\r\n' +
		'Other information may be available on the site.'
	transporter.sendMail(mailData);

    event.save(function (err) {
        if (err) res.send(err);
        else res.json(event);
    });
}

function editEvent(req, res) {
    var id = req.params.id;
    var info = req.body;

	mailData.subject = '[AMR] Event edited';
	mailData.text = info.owner + ' updated an event called ' + info.name + '\r\n' +
		'Date: ' + info.date.toLocaleString() + '\r\n' +
		'Location: ' + info.location + '\r\n' +
		'Description: ' + info.description + '\r\n' +
		'Other information may be available on the site.'
	transporter.sendMail(mailData);

    var query = { _id: id },
        update = { $set: {
            name: info.name,
            location: info.location,
            description: info.description,
            date: new Date(info.date),
            tags: info.tags,
            contactName: info.contactName,
            contactEmail: info.contactEmail,
            edited: info.edited,
            editDate: info.editDate
        }};
    Event.update(query, update, function (err, updated) {
        if (err) res.send(err);
        else res.json(updated);
    });
}

function deleteEvent(req, res) {
    var id = req.params.id;

	mailData.subject = '[AMR] Event deleted';
	mailData.text = info.owner + ' deleted event ID ' + id;
	transporter.sendMail(mailData);

    Event.remove({ _id: id }, function (err, removed) {
        if (err) res.send(err);
        else res.json(removed);
    });
}

module.exports = router;
<|endoftext|>


<commit_before>//Utility functions
//From http://www.jquerybyexample.net/2012/06/get-url-parameters-using-jquery.html
function getURLParameter(sParam) {
    var sPageURL = window.location.search.substring(1);
    var sURLVariables = sPageURL.split('&');
    for (var i = 0; i < sURLVariables.length; i++) {
        var sParameterName = sURLVariables[i].split('=');
        if (sParameterName[0] === sParam) {
            return sParameterName[1];
        }
    }
}
;

function ampDecode(encoded) {
    var elem = document.createElement('textarea');
    elem.innerHTML = encoded;
    return elem.value;
}

$(function () {
    var gh = null;
    var profile;

    var exerciseParam = getURLParameter("exercise");
    if (exerciseParam) {
        $("#exercise").attr("resource", exerciseParam);
    }

    LD2h.expand().then(function () {

        var sourceUriValue = $("#sourceURI").val();
        if (sourceUriValue && (sourceUriValue.trim().length > 0)) {
            setRdfSourceType("uri");
        }

        var codeEditorValue = ampDecode($("#codeEditor").html());
        $("#codeEditor").html("");
        var codeEditorCM = CodeMirror($("#codeEditor")[0], {
            mode: "javascript"
        });
        if (codeEditorValue) {
            codeEditorCM.setValue(codeEditorValue);
        }
        var matchersEditorValue = ampDecode($("#matchersEditor").html());
        $("#matchersEditor").html("")
        var matchersEditorCM = CodeMirror($("#matchersEditor")[0], {
            mode: "turtle"
        });
        if (matchersEditorValue) {
            matchersEditorCM.setValue(matchersEditorValue);
        }
        var run = function () {
            if ($("#sourceURI").val() !== "") {
                var sourceURI = $("#sourceURI").val();
            } else {
                var sourceURI = $("#endpointURL").val() + "?query=" + encodeURIComponent($("#queryForEndpoint").val()) + "&format=auto";
            }
            var turtleParser = LdpStore.parsers.findParsers("text/turtle")[0];
            var store = new LdpStore({
                parsers: new LdpStore.ParserUtil({
                    'text/turtle': turtleParser,
                    //'application/ld+json': LdpStore.parsers.findParsers("application/ld+json")[0],
                    'application/rdf+xml': LdpStore.parsers.findParsers("application/rdf+xml")[0]
                })
            });
            var getData = function () {
                if ($('#rdfSource-uri').is(":visible") || $('#rdfSource-endpoint').is(":visible")) {
                    return store.match(
                            null,
                            null,
                            null,
                            sourceURI).catch(
                            function (error) {
                                console.warn("Couldn't get any triple from " + sourceURI + ". reason: " + error);
                            });

                } else {
                    var turtle = rdfDataEditorCM.getValue();
                    return turtleParser.parse(turtle, undefined, "http://example.org/").catch(function (e) {
                        console.log(e);
                        alert("Could not parse Turtle: " + e.constructor.name);
                        throw "Parsing failed";
                    });
                }
            };
            getData().then(function (g) {
                var code = codeEditorCM.getValue();
                var runCode = new Promise(function (resolve, reject) {
                    try {
                        var result = eval(code);
                    } catch (e) {
                        if ((e instanceof ReferenceError) ||
                                (e instanceof SyntaxError) ||
                                (e instanceof TypeError)) {
                            alert(e.constructor.name +
                                    (e.lineNumber ? " on line " + e.lineNumber : "") +
                                    ": " + e.message);
                        } else {
                            throw(e);
                        }
                    }
                    //if code result in undefined it will immediately be resolves
                    //if it returns a promise it will follow that promise
                    resolve(result);
                });
                runCode.then(function () {
                    var resource = rdf.createNamedNode($("#rendering-resource").val());
                    var matchersTurtle = matchersEditorCM.getValue();
                    if (matchersTurtle.length > 0) {
                        turtleParser.parse(matchersTurtle).then(function (matchers) {
                            var renderingResult = new RDF2h(matchers).render(
                                    g, resource);
                            $("#result").html(renderingResult);
                        });
                    }
                });
            });
        };
        $("#run").on("click", run);

        $(".source-solution-button").on("click", function () {
            if ($("#sourceURI-solution").length > 0) {
                if (confirm("Confirm that you are you too lazy to copy and paste that URI.")) {
                    $("#sourceURI").val($("#sourceURI-solution").text().trim());
                    setRdfSourceType("uri")
                }
            } else {
                setRdfSourceType("directInput");
                rdfDataEditorCM.setValue($("#sourceEditor-solution").text().trim());
            }
        });
        $("#codeEditor-solution-button").on("click", function () {
            var message = "Confirm that you would like to see the solution.";
            if (codeEditorCM.getValue().trim().length > 0) {
                message += "\nWARNING: The code that you've already entered will be gone forever.";
            }
            if (confirm(message)) {
                codeEditorCM.setValue($("#codeEditor-solution").text().trim());
            }
        });
        $("#rendering-solution-button").on("click", function () {
            var message = "Confirm that you would like to see the solution.";
            if (matchersEditorCM.getValue().trim().length > 0) {
                message += "\nWARNING: That code that you've already entered will be forever lost.";
            }
            if (confirm(message)) {
                $("#rendering-resource").val($("#rendering-resource-solution").text().trim());
                matchersEditorCM.setValue($("#matchersEditor-solution").text().trim());
            }
        });

        updateLogginStatus();

        function updateLogginStatus() {
            if (profile) {
                $('.authenticatedOnly').show();
                $('#login-div').html('Logged in as ' + profile.login + ' (Logout)');
                $('#logout-link').click(function () {
                    profile = null;
                    updateLogginStatus();
                    return false;
                });
                var repo = gh.getRepo(profile.login, 'lodide-saved-contents');
                repo.getTree("master").then(function (r) {
                    var tree = r.data.tree
                    //for (var i = 0; i < tree.length;i++) {
                    //    var e = tree[i];
                    tree.forEach(function (e) {
                        console.log(e);
                        repo.getContents('master', e.path, 'raw').then(function (response) {
                            console.log("Contents of: " + e.path);
                            console.log(response.data);
                        });
                    });
                }).catch(function (e) {
                    alert("e: " + e);
                });
            } else {
                $('.authenticatedOnly').hide();
                $('#login-div').html('Login with GitHub');
                $('#login-link').click(function () {
                    $('#login-dialog').modal("show");
                    return false;
                });
            }
        }

        var loginButtonAction = function (auth) {
            gh = new GitHub(auth);
            var user = gh.getUser();
            console.log(user);
            user.getProfile().then(function (response) {
                profile = response.data;
                console.log(profile);
                updateLogginStatus();
                $('#login-dialog').modal('hide');
            });

        }

        $('#personalAccessTokenLoginButton').click(function () {
            if ($('#saveCredentialForLater').prop("checked")) {
                localStorage.setItem("personalAccessToken", $('#personalAccessToken').val());
            } else {
                localStorage.removeItem("personalAccessToken");
            }
            loginButtonAction({
                token: $('#personalAccessToken').val(),
            });
        });

        $('#passwordLoginButton').click(function () {
            loginButtonAction({
                'username': $('#userName').val(),
                'password': $('#password').val()
            });
        });

        $("#saveButton").click(function () {
            $("#fileNameDialog").modal("show");
        });

        $("#saveButton2").click(function () {
            var fileName = $("#fileName").val();
            if (!fileName.endsWith(".ttl")) {
                fileName = fileName + ".ttl";
            }
            var repo = gh.getRepo(profile.login, 'lodide-saved-contents');
            repo.listBranches().then(writeFile).catch(function (e) {
                console.log("failed to write file, will attempt to create repo");
                console.log(e);
                //create new repository
                gh.getUser().createRepo({
                    "name": "lodide-saved-contents",
                    "description": "A repository for saving http://lodide.io/ projects.",
                    "homepage": "http://lodide.io/",
                    "private": false,
                    "has_issues": false,
                    "has_wiki": false,
                    "has_downloads": false
                }).then(writeFile)
                        .catch(function (a) {
                            alert("error: " + a)
                        });
            });
            function writeFile() {
                serializeCurrentState().then(function (fileContent) {
                    repo.writeFile('master', fileName, fileContent,
                            "Run it on http://lodide.io/?exercise=https://raw.githubusercontent.com/" + profile.login + "/lodide-saved-contents/master/" + fileName, {}).then(function (r) {
                        alert("saved file: " + fileName);
                        console.log(r);
                    });
                }).catch(function (e) {
                    console.log("Error serializing:");
                    console.log(e);
                    alert("Serialization failed, see log");
                });
            }
            function serializeCurrentState() {
                var g = new rdf.Graph();
                var exercise = rdf.createNamedNode(""); //rdf-ext supports relative IRIs
                g.add(rdf.createTriple(exercise, rdfNs("type"), lodIdeNs("Exercise")));
                g.add(rdf.createTriple(exercise, lodIdeNs("intro"), rdf.createLiteral($("#intro").html())));
                g.add(rdf.createTriple(exercise, lodIdeNs("finalWords"),
                        rdf.createLiteral($("#finalWords").html())));
                var dataSource = rdf.createBlankNode();
                g.add(rdf.createTriple(exercise, lodIdeNs("dataSource"), dataSource));
                if ($("#dataSource-taskDescription").length > 0) {
                    g.add(rdf.createTriple(dataSource, lodIdeNs("taskDescription"),
                            rdf.createLiteral($("#dataSource-taskDescription").html())));
                }
                if ($("#sourceURI-solution").html()) {
                    g.add(rdf.createTriple(dataSource, lodIdeNs("taskSolutionResource"),
                            rdf.createNamedNode($("#sourceURI-solution").html())));
                }
                if ($('#rdfSource-uri').is(":visible")) {
                    g.add(rdf.createTriple(dataSource, lodIdeNs("taskSolutionResourceCurrent"),
                            rdf.createLiteral($("#sourceURI").val())));
                }
                if ($('#rdfSource-directInput').is(":visible")) {
                    g.add(rdf.createTriple(dataSource, lodIdeNs("taskSolutionCodeCurrent"),
                            rdf.createLiteral(rdfDataEditorCM.getValue())));
                }
                var dataProcessing = rdf.createBlankNode();
                g.add(rdf.createTriple(exercise, lodIdeNs("dataProcessing"), dataProcessing));
                if ($("#dataProcessing-taskDescription").length > 0) {
                    g.add(rdf.createTriple(dataProcessing, lodIdeNs("taskDescription"),
                            rdf.createLiteral($("#dataProcessing-taskDescription").html())));
                }
                g.add(rdf.createTriple(dataProcessing, lodIdeNs("taskSolutionCode"),
                        rdf.createLiteral($("#codeEditor-solution").html())));
                g.add(rdf.createTriple(dataProcessing, lodIdeNs("taskSolutionCodeCurrent"),
                        rdf.createLiteral(codeEditorCM.getValue())));
                if ($("#dataRenderingTitle").length > 0) {
                    var dataRendering = rdf.createBlankNode();
                    g.add(rdf.createTriple(exercise, lodIdeNs("dataRendering"), dataRendering));
                    if ($("#dataRendering-taskDescription").length > 0) {
                        g.add(rdf.createTriple(dataRendering, lodIdeNs("taskDescription"),
                                rdf.createLiteral($("#dataRendering-taskDescription").html())));
                    }
                    g.add(rdf.createTriple(dataRendering, lodIdeNs("taskSolutionCode"),
                            rdf.createLiteral($("#matchersEditor-solution").html())));
                    g.add(rdf.createTriple(dataRendering, lodIdeNs("taskSolutionCodeCurrent"),
                            rdf.createLiteral(matchersEditorCM.getValue())));
                    g.add(rdf.createTriple(dataRendering, lodIdeNs("taskSolutionResource"),
                            rdf.createNamedNode($("#rendering-resource-solution").html())));
                    g.add(rdf.createTriple(dataRendering, lodIdeNs("taskSolutionResourceCurrent"),
                            rdf.createLiteral($("#rendering-resource").val())));
                }
                return rdf.serializers["text/turtle"].serialize(g).then(function (turtle) {
                    return turtle;
                });
            }
            function lodIdeNs(localName) {
                return rdf.createNamedNode("http://ontology.lodide.io/" + localName);
            }
            function rdfNs(localName) {
                return rdf.createNamedNode("http://www.w3.org/1999/02/22-rdf-syntax-ns#" + localName);
            }
        });

        $(".exerciseIndexLink").click(function (e) {
            var exerciseArea = $("#exercise");
            exerciseArea.hide();
            var exerciseIndexArea = $("#exerciseIndex");

            if (exerciseIndexArea.is(":visible")) {
                exerciseIndexArea.addClass("fetch");
                exerciseIndexArea.attr("resource", "index.ttl");
                LD2h.expand();
            } else {
                exerciseIndexArea.show();
            }
            window.previousLocation = window.location.toString();
            window.history.pushState({}, "", "exercise-index.html");
            $("#lodIDEMenu").removeClass("active");
            $("#exerciseIndexMenu").addClass("active");
            e.preventDefault();
        });

        $(".lodIDELink").click(function () {
            var exerciseArea = $("#exercise");
            exerciseArea.show();
            var exerciseIndexArea = $("#exerciseIndex");
            exerciseIndexArea.hide();
            window.history.pushState({}, "", window.previousLocation);
            $("#lodIDEMenu").addClass("active");
            $("#exerciseIndexMenu").removeClass("active");
        });

    });

});
<commit_msg>improved github repository creation workflow<commit_after>//Utility functions
//From http://www.jquerybyexample.net/2012/06/get-url-parameters-using-jquery.html
function getURLParameter(sParam) {
    var sPageURL = window.location.search.substring(1);
    var sURLVariables = sPageURL.split('&');
    for (var i = 0; i < sURLVariables.length; i++) {
        var sParameterName = sURLVariables[i].split('=');
        if (sParameterName[0] === sParam) {
            return sParameterName[1];
        }
    }
}
;

function ampDecode(encoded) {
    var elem = document.createElement('textarea');
    elem.innerHTML = encoded;
    return elem.value;
}

$(function () {
    var gh = null;
    var profile;

    var exerciseParam = getURLParameter("exercise");
    if (exerciseParam) {
        $("#exercise").attr("resource", exerciseParam);
    }

    LD2h.expand().then(function () {

        var sourceUriValue = $("#sourceURI").val();
        if (sourceUriValue && (sourceUriValue.trim().length > 0)) {
            setRdfSourceType("uri");
        }

        var codeEditorValue = ampDecode($("#codeEditor").html());
        $("#codeEditor").html("");
        var codeEditorCM = CodeMirror($("#codeEditor")[0], {
            mode: "javascript"
        });
        if (codeEditorValue) {
            codeEditorCM.setValue(codeEditorValue);
        }
        var matchersEditorValue = ampDecode($("#matchersEditor").html());
        $("#matchersEditor").html("")
        var matchersEditorCM = CodeMirror($("#matchersEditor")[0], {
            mode: "turtle"
        });
        if (matchersEditorValue) {
            matchersEditorCM.setValue(matchersEditorValue);
        }
        var run = function () {
            if ($("#sourceURI").val() !== "") {
                var sourceURI = $("#sourceURI").val();
            } else {
                var sourceURI = $("#endpointURL").val() + "?query=" + encodeURIComponent($("#queryForEndpoint").val()) + "&format=auto";
            }
            var turtleParser = LdpStore.parsers.findParsers("text/turtle")[0];
            var store = new LdpStore({
                parsers: new LdpStore.ParserUtil({
                    'text/turtle': turtleParser,
                    //'application/ld+json': LdpStore.parsers.findParsers("application/ld+json")[0],
                    'application/rdf+xml': LdpStore.parsers.findParsers("application/rdf+xml")[0]
                })
            });
            var getData = function () {
                if ($('#rdfSource-uri').is(":visible") || $('#rdfSource-endpoint').is(":visible")) {
                    return store.match(
                            null,
                            null,
                            null,
                            sourceURI).catch(
                            function (error) {
                                console.warn("Couldn't get any triple from " + sourceURI + ". reason: " + error);
                            });

                } else {
                    var turtle = rdfDataEditorCM.getValue();
                    return turtleParser.parse(turtle, undefined, "http://example.org/").catch(function (e) {
                        console.log(e);
                        alert("Could not parse Turtle: " + e.constructor.name);
                        throw "Parsing failed";
                    });
                }
            };
            getData().then(function (g) {
                var code = codeEditorCM.getValue();
                var runCode = new Promise(function (resolve, reject) {
                    try {
                        var result = eval(code);
                    } catch (e) {
                        if ((e instanceof ReferenceError) ||
                                (e instanceof SyntaxError) ||
                                (e instanceof TypeError)) {
                            alert(e.constructor.name +
                                    (e.lineNumber ? " on line " + e.lineNumber : "") +
                                    ": " + e.message);
                        } else {
                            throw(e);
                        }
                    }
                    //if code result in undefined it will immediately be resolves
                    //if it returns a promise it will follow that promise
                    resolve(result);
                });
                runCode.then(function () {
                    var resource = rdf.createNamedNode($("#rendering-resource").val());
                    var matchersTurtle = matchersEditorCM.getValue();
                    if (matchersTurtle.length > 0) {
                        turtleParser.parse(matchersTurtle).then(function (matchers) {
                            var renderingResult = new RDF2h(matchers).render(
                                    g, resource);
                            $("#result").html(renderingResult);
                        });
                    }
                });
            });
        };
        $("#run").on("click", run);

        $(".source-solution-button").on("click", function () {
            if ($("#sourceURI-solution").length > 0) {
                if (confirm("Confirm that you are you too lazy to copy and paste that URI.")) {
                    $("#sourceURI").val($("#sourceURI-solution").text().trim());
                    setRdfSourceType("uri")
                }
            } else {
                setRdfSourceType("directInput");
                rdfDataEditorCM.setValue($("#sourceEditor-solution").text().trim());
            }
        });
        $("#codeEditor-solution-button").on("click", function () {
            var message = "Confirm that you would like to see the solution.";
            if (codeEditorCM.getValue().trim().length > 0) {
                message += "\nWARNING: The code that you've already entered will be gone forever.";
            }
            if (confirm(message)) {
                codeEditorCM.setValue($("#codeEditor-solution").text().trim());
            }
        });
        $("#rendering-solution-button").on("click", function () {
            var message = "Confirm that you would like to see the solution.";
            if (matchersEditorCM.getValue().trim().length > 0) {
                message += "\nWARNING: That code that you've already entered will be forever lost.";
            }
            if (confirm(message)) {
                $("#rendering-resource").val($("#rendering-resource-solution").text().trim());
                matchersEditorCM.setValue($("#matchersEditor-solution").text().trim());
            }
        });

        updateLogginStatus();

        function updateLogginStatus() {
            if (profile) {
                $('.authenticatedOnly').show();
                $('#login-div').html('Logged in as ' + profile.login + ' (Logout)');
                $('#logout-link').click(function () {
                    profile = null;
                    updateLogginStatus();
                    return false;
                });
                var repo = gh.getRepo(profile.login, 'lodide-saved-contents');
                repo.getTree("master").then(function (r) {
                    console.log("successful access to your repo");
                }).catch(function (e) {
                    console.log("failed to access repo contents, will attempt to create repo");
                    console.log(e);
                    //create new repository
                    gh.getUser().createRepo({
                        "name": "lodide-saved-contents",
                        "description": "A repository for saving http://lodide.io/ projects.",
                        "homepage": "http://lodide.io/",
                        "private": false,
                        "has_issues": false,
                        "has_wiki": false,
                        "has_downloads": false
                    }).then(writeReadme)
                        .catch(function (a) {
                            alert("error: " + a)
                        });
                    function writeReadme() {
                        repo.writeFile('master', "README.md", "# LodIDE\nThis repository collects all your saved work from [LodIDE](http://lodide.io).",
                                "Autogenerated README", {}).then(function (r) {
                            console.log(r);
                        });
                    }
                });
            } else {
                $('.authenticatedOnly').hide();
                $('#login-div').html('Login with GitHub');
                $('#login-link').click(function () {
                    $('#login-dialog').modal("show");
                    return false;
                });
            }
        }

        var loginButtonAction = function (auth) {
            gh = new GitHub(auth);
            var user = gh.getUser();
            console.log(user);
            user.getProfile().then(function (response) {
                profile = response.data;
                console.log(profile);
                updateLogginStatus();
                $('#login-dialog').modal('hide');
            });

        }

        $('#personalAccessTokenLoginButton').click(function () {
            if ($('#saveCredentialForLater').prop("checked")) {
                localStorage.setItem("personalAccessToken", $('#personalAccessToken').val());
            } else {
                localStorage.removeItem("personalAccessToken");
            }
            loginButtonAction({
                token: $('#personalAccessToken').val(),
            });
        });

        $('#passwordLoginButton').click(function () {
            loginButtonAction({
                'username': $('#userName').val(),
                'password': $('#password').val()
            });
        });

        $("#saveButton").click(function () {
            $("#fileNameDialog").modal("show");
        });

        $("#saveButton2").click(function () {
            var fileName = $("#fileName").val();
            if (!fileName.endsWith(".ttl")) {
                fileName = fileName + ".ttl";
            }
            var repo = gh.getRepo(profile.login, 'lodide-saved-contents');
            repo.listBranches().then(writeFile).catch(function (e) {
                alert("failed to write file, did you delete the repo? Will attempt to create repo.");
                console.log(e);
                //create new repository
                gh.getUser().createRepo({
                    "name": "lodide-saved-contents",
                    "description": "A repository for saving http://lodide.io/ projects.",
                    "homepage": "http://lodide.io/",
                    "private": false,
                    "has_issues": false,
                    "has_wiki": false,
                    "has_downloads": false
                }).then(writeFile)
                        .catch(function (a) {
                            alert("error: " + a)
                        });
            });
            function writeFile() {
                serializeCurrentState().then(function (fileContent) {
                    repo.writeFile('master', fileName, fileContent,
                            "Run it on http://lodide.io/?exercise=https://raw.githubusercontent.com/" + profile.login + "/lodide-saved-contents/master/" + fileName, {}).then(function (r) {
                        alert("saved file: " + fileName);
                        console.log(r);
                    });
                }).catch(function (e) {
                    console.log("Error serializing:");
                    console.log(e);
                    alert("Serialization failed, see log");
                });
            }
            function serializeCurrentState() {
                var g = new rdf.Graph();
                var exercise = rdf.createNamedNode(""); //rdf-ext supports relative IRIs
                g.add(rdf.createTriple(exercise, rdfNs("type"), lodIdeNs("Exercise")));
                g.add(rdf.createTriple(exercise, lodIdeNs("intro"), rdf.createLiteral($("#intro").html())));
                g.add(rdf.createTriple(exercise, lodIdeNs("finalWords"),
                        rdf.createLiteral($("#finalWords").html())));
                var dataSource = rdf.createBlankNode();
                g.add(rdf.createTriple(exercise, lodIdeNs("dataSource"), dataSource));
                if ($("#dataSource-taskDescription").length > 0) {
                    g.add(rdf.createTriple(dataSource, lodIdeNs("taskDescription"),
                            rdf.createLiteral($("#dataSource-taskDescription").html())));
                }
                if ($("#sourceURI-solution").html()) {
                    g.add(rdf.createTriple(dataSource, lodIdeNs("taskSolutionResource"),
                            rdf.createNamedNode($("#sourceURI-solution").html())));
                }
                if ($('#rdfSource-uri').is(":visible")) {
                    g.add(rdf.createTriple(dataSource, lodIdeNs("taskSolutionResourceCurrent"),
                            rdf.createLiteral($("#sourceURI").val())));
                }
                if ($('#rdfSource-directInput').is(":visible")) {
                    g.add(rdf.createTriple(dataSource, lodIdeNs("taskSolutionCodeCurrent"),
                            rdf.createLiteral(rdfDataEditorCM.getValue())));
                }
                var dataProcessing = rdf.createBlankNode();
                g.add(rdf.createTriple(exercise, lodIdeNs("dataProcessing"), dataProcessing));
                if ($("#dataProcessing-taskDescription").length > 0) {
                    g.add(rdf.createTriple(dataProcessing, lodIdeNs("taskDescription"),
                            rdf.createLiteral($("#dataProcessing-taskDescription").html())));
                }
                g.add(rdf.createTriple(dataProcessing, lodIdeNs("taskSolutionCode"),
                        rdf.createLiteral($("#codeEditor-solution").html())));
                g.add(rdf.createTriple(dataProcessing, lodIdeNs("taskSolutionCodeCurrent"),
                        rdf.createLiteral(codeEditorCM.getValue())));
                if ($("#dataRenderingTitle").length > 0) {
                    var dataRendering = rdf.createBlankNode();
                    g.add(rdf.createTriple(exercise, lodIdeNs("dataRendering"), dataRendering));
                    if ($("#dataRendering-taskDescription").length > 0) {
                        g.add(rdf.createTriple(dataRendering, lodIdeNs("taskDescription"),
                                rdf.createLiteral($("#dataRendering-taskDescription").html())));
                    }
                    g.add(rdf.createTriple(dataRendering, lodIdeNs("taskSolutionCode"),
                            rdf.createLiteral($("#matchersEditor-solution").html())));
                    g.add(rdf.createTriple(dataRendering, lodIdeNs("taskSolutionCodeCurrent"),
                            rdf.createLiteral(matchersEditorCM.getValue())));
                    g.add(rdf.createTriple(dataRendering, lodIdeNs("taskSolutionResource"),
                            rdf.createNamedNode($("#rendering-resource-solution").html())));
                    g.add(rdf.createTriple(dataRendering, lodIdeNs("taskSolutionResourceCurrent"),
                            rdf.createLiteral($("#rendering-resource").val())));
                }
                return rdf.serializers["text/turtle"].serialize(g).then(function (turtle) {
                    return turtle;
                });
            }
            function lodIdeNs(localName) {
                return rdf.createNamedNode("http://ontology.lodide.io/" + localName);
            }
            function rdfNs(localName) {
                return rdf.createNamedNode("http://www.w3.org/1999/02/22-rdf-syntax-ns#" + localName);
            }
        });

        $(".exerciseIndexLink").click(function (e) {
            var exerciseArea = $("#exercise");
            exerciseArea.hide();
            var exerciseIndexArea = $("#exerciseIndex");

            if (exerciseIndexArea.is(":visible")) {
                exerciseIndexArea.addClass("fetch");
                exerciseIndexArea.attr("resource", "index.ttl");
                LD2h.expand();
            } else {
                exerciseIndexArea.show();
            }
            window.previousLocation = window.location.toString();
            window.history.pushState({}, "", "exercise-index.html");
            $("#lodIDEMenu").removeClass("active");
            $("#exerciseIndexMenu").addClass("active");
            e.preventDefault();
        });

        $(".lodIDELink").click(function () {
            var exerciseArea = $("#exercise");
            exerciseArea.show();
            var exerciseIndexArea = $("#exerciseIndex");
            exerciseIndexArea.hide();
            window.history.pushState({}, "", window.previousLocation);
            $("#lodIDEMenu").addClass("active");
            $("#exerciseIndexMenu").removeClass("active");
        });

    });

});
<|endoftext|>


<commit_before>#!/usr/bin/env node
/*
  Copyright (C) 2012 Ariya Hidayat <ariya.hidayat@gmail.com>
  Copyright (C) 2011 Ariya Hidayat <ariya.hidayat@gmail.com>

  Redistribution and use in source and binary forms, with or without
  modification, are permitted provided that the following conditions are met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in the
      documentation and/or other materials provided with the distribution.

  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

/*jslint sloppy:true node:true */

var fs = require('fs'),
    esprima = require('esprima'),
    fname,
    content,
    options,
    syntax;

if (process.argv.length <= 2) {
    console.log('Usage:');
    console.log('   esparse [options] file.js');
    console.log();
    console.log('Available options:');
    console.log();
    console.log('  --comment      Gather all line and block comments in an array');
    console.log('  --loc          Include line-column location info for each syntax node');
    console.log('  --range        Include index-based range for each syntax node');
    console.log('  --raw          Display the raw value of literals');
    console.log('  --tolerant     Tolerate errors on a best-effort basis (WIP)');
    console.log('  -v, --version  Shows program version');
    console.log();
    process.exit(1);
}

options = {};

process.argv.splice(2).forEach(function (entry) {

    if (entry === '-v' || entry === '--version') {
        console.log('ECMAScript Parser (using Esprima version', esprima.version, ')');
        console.log();
        process.exit(0);
    } else if (entry === '--comment') {
        options.comment = true;
    } else if (entry === '--loc') {
        options.loc = true;
    } else if (entry === '--range') {
        options.range = true;
    } else if (entry === '--raw') {
        options.raw = true;
    } else if (entry === '--tolerant') {
        options.tolerant = true;
    } else if (entry.slice(0, 2) === '--') {
        console.log('Error: unknown option ' + entry + '.');
        process.exit(1);
    } else if (typeof fname === 'string') {
        console.log('Error: more than one input file.');
        process.exit(1);
    } else {
        fname = entry;
    }
});

if (typeof fname !== 'string') {
    console.log('Error: no input file.');
    process.exit(1);
}

try {
    content = fs.readFileSync(fname, 'utf-8');
    syntax = esprima.parse(content, options);
    console.log(JSON.stringify(syntax, null, 4));
} catch (e) {
    console.log('Error: ' + e.message);
    process.exit(1);
}
<commit_msg>esparse: Call the tolerant mode as experimental rather than WIP.<commit_after>#!/usr/bin/env node
/*
  Copyright (C) 2012 Ariya Hidayat <ariya.hidayat@gmail.com>
  Copyright (C) 2011 Ariya Hidayat <ariya.hidayat@gmail.com>

  Redistribution and use in source and binary forms, with or without
  modification, are permitted provided that the following conditions are met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in the
      documentation and/or other materials provided with the distribution.

  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

/*jslint sloppy:true node:true */

var fs = require('fs'),
    esprima = require('esprima'),
    fname,
    content,
    options,
    syntax;

if (process.argv.length <= 2) {
    console.log('Usage:');
    console.log('   esparse [options] file.js');
    console.log();
    console.log('Available options:');
    console.log();
    console.log('  --comment      Gather all line and block comments in an array');
    console.log('  --loc          Include line-column location info for each syntax node');
    console.log('  --range        Include index-based range for each syntax node');
    console.log('  --raw          Display the raw value of literals');
    console.log('  --tolerant     Tolerate errors on a best-effort basis (experimental)');
    console.log('  -v, --version  Shows program version');
    console.log();
    process.exit(1);
}

options = {};

process.argv.splice(2).forEach(function (entry) {

    if (entry === '-v' || entry === '--version') {
        console.log('ECMAScript Parser (using Esprima version', esprima.version, ')');
        console.log();
        process.exit(0);
    } else if (entry === '--comment') {
        options.comment = true;
    } else if (entry === '--loc') {
        options.loc = true;
    } else if (entry === '--range') {
        options.range = true;
    } else if (entry === '--raw') {
        options.raw = true;
    } else if (entry === '--tolerant') {
        options.tolerant = true;
    } else if (entry.slice(0, 2) === '--') {
        console.log('Error: unknown option ' + entry + '.');
        process.exit(1);
    } else if (typeof fname === 'string') {
        console.log('Error: more than one input file.');
        process.exit(1);
    } else {
        fname = entry;
    }
});

if (typeof fname !== 'string') {
    console.log('Error: no input file.');
    process.exit(1);
}

try {
    content = fs.readFileSync(fname, 'utf-8');
    syntax = esprima.parse(content, options);
    console.log(JSON.stringify(syntax, null, 4));
} catch (e) {
    console.log('Error: ' + e.message);
    process.exit(1);
}
<|endoftext|>


<commit_before>module.exports = {
  /**
   * Application configuration section
   * http://pm2.keymetrics.io/docs/usage/application-declaration/
   */
  apps: [{
    name: "Trials Statistic Dashboard",
    script: "./dist/server.js",
    watch: true,
    env: {
      NODE_ENV: "production"
    },
    env_production: {
      NODE_ENV: "production"
    },
    instances: "max",
    exec_mode: "cluster"
  }]
}<commit_msg>Watch config pm2 changed<commit_after>module.exports = {
  /**
   * Application configuration section
   * http://pm2.keymetrics.io/docs/usage/application-declaration/
   */
  apps: [{
    name: "Trials Statistic Dashboard",
    script: "./dist/server.js",
    watch: ['public', 'dist'],
    env: {
      NODE_ENV: "production"
    },
    env_production: {
      NODE_ENV: "production"
    },
    instances: "max",
    exec_mode: "cluster"
  }]
}<|endoftext|>