<commit_before>'use strict'
//
// TrainerRed - subreddit submission analysis bot
// ---
// @copyright (c) 2014 Damian Bushong <katana@odios.us>
// @license MIT license
// @url <https://github.com/damianb/>
// @reddit <https://reddit.com/u/katana__>
// @twitter <https://twitter.com/blazingcrimson>
//

module.exports = function(options) {
	var output = !!options.quiet ? function() {} || console.log,
		trainerred = require('./../lib')(options.config, options.db),
		db = trainerred.db,
		when = trainerred.when,
		util = require('util')

	// sanity enforcement. options.days has to be (1 <= days <= 14)
	if(!options.days || (options.days < 1 || options.days > 14)) {
		options.days = 7
	}

	trainerred.auth()
		.then(function() {
			output('authenticated, querying...')
		})
		.then(function() {
			if(!options.local) {
				return trainerred.queryListing('/r/$subreddit/about/$location', {
					$location: 'spam',
					$subreddit: trainerred.subreddit,
					only: 'links',
					show: 'all'
				})
			}
		})
		.then(function() {
			if(!options.local) {
				return trainerred.queryListing('/r/$subreddit/new', {
					$subreddit: trainerred.subreddit,
					only: 'links',
					show: 'all'
				})
			}
		})
		.then(function() {
			// *ominous hand waving during $earliestTime conjuration*
			var params = { $earliestTime: (Math.round(Date.now() / 1000) - (1 * 60 * 60 * 24 * options.days)) }

			var userPromise = when.promise(function(resolve, reject) {
				db.all('SELECT author FROM posts WHERE _removed = 1 AND created_utc > $earliestTime'
					+ ' GROUP BY author ORDER BY COUNT(author) DESC LIMIT 10', params, function(err, rows) {
					if(err) {
						return reject(err)
					}

					resolve(rows)
				})
			})

			var domainPromise = when.promise(function(resolve, reject) {
				db.all('SELECT domain FROM posts WHERE _removed = 1 AND created_utc > $earliestTime'
					+ ' GROUP BY domain ORDER BY COUNT(domain) DESC LIMIT 10', params, function(err, rows) {
					if(err) {
						return reject(err)
					}

					resolve(rows)
				})
			})

			return when.join(
				// total posts submitted within the last week
				when.promise(function(resolve, reject) {
					db.get('SELECT COUNT(id) as count FROM posts WHERE created_utc > $earliestTime', params, function(err, row) {
						if(err) {
							return reject(err)
						}

						resolve(row.count)
					})
				}),
				// total posts REMOVED within the last week
				when.promise(function(resolve, reject) {
					db.get('SELECT COUNT(id) as count FROM posts WHERE _removed = 1 AND created_utc > $earliestTime', params, function(err, row) {
						if(err) {
							return reject(err)
						}

						resolve(row.count)
					})
				}),
				// users to review
				when.map(userPromise, function(rows) {
					var user = rows.author
					return trainerred.queryUser(user).then(function() {
						return when.join(
							when.promise(function(resolve, reject) {
								db.get('SELECT COUNT(id) as tCount FROM posts WHERE author = $user', { $user: user }, function(err, row) {
									if(err) {
										return reject(err)
									}

									resolve(row.tCount)
								})
							}),
							when.promise(function(resolve, reject) {
								db.get('SELECT COUNT(id) as rCount FROM posts WHERE author = $user AND _removed = 1', { $user: user }, function(err, row) {
									if(err) {
										return reject(err)
									}

									resolve(row.rCount)
								})
							}),
							when.promise(function(resolve, reject) {
								db.get('SELECT COUNT(id) as rec_tCount FROM posts WHERE author = $user'
									+ ' AND created_utc > $earliestTime', { $user: user, $earliestTime: params.$earliestTime }, function(err, row) {
									if(err) {
										return reject(err)
									}

									resolve(row.rec_tCount)
								})
							}),
							when.promise(function(resolve, reject) {
								db.get('SELECT COUNT(id) as rec_rCount FROM posts WHERE author = $user AND _removed = 1'
									+ ' AND created_utc > $earliestTime', { $user: user, $earliestTime: params.$earliestTime }, function(err, row) {
									if(err) {
										return reject(err)
									}

									resolve(row.rec_rCount)
								})
							})
						).then(function(val) {
							return {
								user: user,
								all: {
									total: val[0],
									removed: val[1]
								},
								recent: {
									total: val[2],
									removed: val[3]
								}
							}
						})
					})
				}),
				// domains to review
				// users to review
				when.map(domainPromise, function(rows) {
					var domain = rows.domain
					return trainerred.queryDomain(domain).then(function() {
						return when.join(
							when.promise(function(resolve, reject) {
								db.get('SELECT COUNT(id) as tCount FROM posts WHERE domain = $domain', { $domain: domain }, function(err, row) {
									if(err) {
										return reject(err)
									}

									resolve(row.tCount)
								})
							}),
							when.promise(function(resolve, reject) {
								db.get('SELECT COUNT(id) as rCount FROM posts WHERE domain = $domain AND _removed = 1', { $domain: domain }, function(err, row) {
									if(err) {
										return reject(err)
									}

									resolve(row.rCount)
								})
							}),
							when.promise(function(resolve, reject) {
								db.get('SELECT COUNT(id) as rec_tCount FROM posts WHERE domain = $domain'
									+ ' AND created_utc > $earliestTime', { $domain: domain, $earliestTime: params.$earliestTime }, function(err, row) {
									if(err) {
										return reject(err)
									}

									resolve(row.rec_tCount)
								})
							}),
							when.promise(function(resolve, reject) {
								db.get('SELECT COUNT(id) as rec_rCount FROM posts WHERE domain = $domain AND _removed = 1'
									+ ' AND created_utc > $earliestTime', { $domain: domain, $earliestTime: params.$earliestTime }, function(err, row) {
									if(err) {
										return reject(err)
									}

									resolve(row.rec_rCount)
								})
							})
						).then(function(val) {
							return {
								domain: domain,
								all: {
									total: val[0],
									removed: val[1]
								},
								recent: {
									total: val[2],
									removed: val[3]
								}
							}
						})
					})
				})
			)
		})
		.then(function(res) {
			// sigh, why does when.join have to be stupid...
			var total = res[0], removed = res[1], users = res[2], domains = res[3]
			output('done grabbing db entries, sending modmail')

			// todo stdout output formatting
			// we need to move the math out of the msg concat lines if we want to do this though...
			// note: this removal rate is only for recent submissions
			var removalRate = trainerred.removalRate(removed, total)
			if(options.mail) {
				var msg = '## TrainerRed initial database population complete.'
				msg += '\n\nTrainerRed has identified ' + total + ' entries (' + removed + ' removals; ' + trainerred.removalRate(removed, total) + '% removal rate) within the last 7 days for analysis.'
				msg += '\n\n---\n### users to review'
				msg += '\n\nsubmitter | overall subs | recent subs\n---|:---:|:---:'
				users.forEach(function(user) {
					if(user.all.removed === 1) {
						return // pass on this one, we don't need to care about first-struck users (we don't do the same for domains though)
					}
					msg += util.format('\n/u/%s | %d% (%d of %d rem) | %d% (%d of %d rem)',
						user.user, trainerred.removalRate(user.all.removed, user.all.total), user.all.removed, user.all.total,
						trainerred.removalRate(user.recent.removed, user.recent.total), user.recent.removed, user.recent.total)
				})
				msg += '\n\n---\n### domains to review'
				msg += '\n\ndomain | overall subs | recent subs\n---|:---:|:---:'
				domains.forEach(function(domain) {
					msg += util.format('\n[%s](https://www.reddit.com/domain/%s/) | %d% (%d of %d rem) | %d% (%d of %d rem)',
						domain.domain, domain.domain, trainerred.removalRate(domain.all.removed, domain.all.total), domain.all.removed, domain.all.total,
						trainerred.removalRate(domain.recent.removed, domain.recent.total), domain.recent.removed, domain.recent.total)
				})
				trainerred.modmail('TrainerRed Database updated', msg).then(function() {
					output('modmail sent!')
				})
			}

			// do we want to format the report and print it over stdout?
			// todo: other formatting options for stdout (csv?)
			// we're ignoring output() here and using console.log straight
			var stdoutExport = ''
			if(!options.export) {
				switch(options.export) {
					case 'json':
						stdoutExport = {
							overview: {
								total: total,
								removals: removed,
								removalRate: removalRate
							},
							users: [],
							domains: []
						}
						users.forEach(function(user) {
							if(user.all.removed === 1) {
								return
							}

							stdoutExport.users.push({
								user: '/u/' + user.user,
								recent: {
									total: user.recent.total,
									removed: user.recent.removed,
									rate: trainerred.removalRate(user.recent.removed, user.recent.total)
								}
								all: {
									total: user.all.total,
									removed: user.all.removed,
									rate: trainerred.removalRate(user.all.removed, user.all.total)
								}
							})
						})
						domains.forEach(function(domain) {
							stdoutExport.domains.push({
								domain: domain.domain,
								domainPage: 'https://www.reddit.com/domain/' + domain.domain,
								recent: {
									total: domain.recent.total,
									removed: domain.recent.removed,
									rate: trainerred.removalRate(domain.recent.removed, domain.recent.total)
								}
								all: {
									total: domain.all.total,
									removed: domain.all.removed,
									rate: trainerred.removalRate(domain.all.removed, domain.all.total)
								}
							})
						})
						stdoutExport = JSON.stringify(stdoutExport)
					break
					case 'standard':
					default:
						// todo - stdout formatting
					break
				}
				console.log(stdoutExport)
			}
			output('terminating...')
			return
		})
		.catch(trainerred.onError)
}
<commit_msg>minor comment changes<commit_after>'use strict'
//
// TrainerRed - subreddit submission analysis bot
// ---
// @copyright (c) 2014 Damian Bushong <katana@odios.us>
// @license MIT license
// @url <https://github.com/damianb/>
// @reddit <https://reddit.com/u/katana__>
// @twitter <https://twitter.com/blazingcrimson>
//

module.exports = function(options) {
	var output = !!options.quiet ? function() {} || console.log,
		trainerred = require('./../lib')(options.config, options.db),
		db = trainerred.db,
		when = trainerred.when,
		util = require('util')

	// sanity enforcement. options.days has to be (1 <= days <= 14)
	if(!options.days || (options.days < 1 || options.days > 14)) {
		options.days = 7
	}

	trainerred.auth()
		.then(function() {
			output('authenticated, querying...')
		})
		.then(function() {
			if(!options.local) {
				return trainerred.queryListing('/r/$subreddit/about/$location', {
					$location: 'spam',
					$subreddit: trainerred.subreddit,
					only: 'links',
					show: 'all'
				})
			}
		})
		.then(function() {
			if(!options.local) {
				return trainerred.queryListing('/r/$subreddit/new', {
					$subreddit: trainerred.subreddit,
					only: 'links',
					show: 'all'
				})
			}
		})
		.then(function() {
			// *ominous hand waving during $earliestTime conjuration*
			var params = { $earliestTime: (Math.round(Date.now() / 1000) - (1 * 60 * 60 * 24 * options.days)) }

			var userPromise = when.promise(function(resolve, reject) {
				db.all('SELECT author FROM posts WHERE _removed = 1 AND created_utc > $earliestTime'
					+ ' GROUP BY author ORDER BY COUNT(author) DESC LIMIT 10', params, function(err, rows) {
					if(err) {
						return reject(err)
					}

					resolve(rows)
				})
			})

			var domainPromise = when.promise(function(resolve, reject) {
				db.all('SELECT domain FROM posts WHERE _removed = 1 AND created_utc > $earliestTime'
					+ ' GROUP BY domain ORDER BY COUNT(domain) DESC LIMIT 10', params, function(err, rows) {
					if(err) {
						return reject(err)
					}

					resolve(rows)
				})
			})

			return when.join(
				// total posts submitted within the last week
				when.promise(function(resolve, reject) {
					db.get('SELECT COUNT(id) as count FROM posts WHERE created_utc > $earliestTime', params, function(err, row) {
						if(err) {
							return reject(err)
						}

						resolve(row.count)
					})
				}),
				// total posts REMOVED within the last week
				when.promise(function(resolve, reject) {
					db.get('SELECT COUNT(id) as count FROM posts WHERE _removed = 1 AND created_utc > $earliestTime', params, function(err, row) {
						if(err) {
							return reject(err)
						}

						resolve(row.count)
					})
				}),
				// users to review
				when.map(userPromise, function(rows) {
					var user = rows.author
					return trainerred.queryUser(user).then(function() {
						return when.join(
							when.promise(function(resolve, reject) {
								db.get('SELECT COUNT(id) as tCount FROM posts WHERE author = $user', { $user: user }, function(err, row) {
									if(err) {
										return reject(err)
									}

									resolve(row.tCount)
								})
							}),
							when.promise(function(resolve, reject) {
								db.get('SELECT COUNT(id) as rCount FROM posts WHERE author = $user AND _removed = 1', { $user: user }, function(err, row) {
									if(err) {
										return reject(err)
									}

									resolve(row.rCount)
								})
							}),
							when.promise(function(resolve, reject) {
								db.get('SELECT COUNT(id) as rec_tCount FROM posts WHERE author = $user'
									+ ' AND created_utc > $earliestTime', { $user: user, $earliestTime: params.$earliestTime }, function(err, row) {
									if(err) {
										return reject(err)
									}

									resolve(row.rec_tCount)
								})
							}),
							when.promise(function(resolve, reject) {
								db.get('SELECT COUNT(id) as rec_rCount FROM posts WHERE author = $user AND _removed = 1'
									+ ' AND created_utc > $earliestTime', { $user: user, $earliestTime: params.$earliestTime }, function(err, row) {
									if(err) {
										return reject(err)
									}

									resolve(row.rec_rCount)
								})
							})
						).then(function(val) {
							return {
								user: user,
								all: {
									total: val[0],
									removed: val[1]
								},
								recent: {
									total: val[2],
									removed: val[3]
								}
							}
						})
					})
				}),
				// domains to review
				// users to review
				when.map(domainPromise, function(rows) {
					var domain = rows.domain
					return trainerred.queryDomain(domain).then(function() {
						return when.join(
							when.promise(function(resolve, reject) {
								db.get('SELECT COUNT(id) as tCount FROM posts WHERE domain = $domain', { $domain: domain }, function(err, row) {
									if(err) {
										return reject(err)
									}

									resolve(row.tCount)
								})
							}),
							when.promise(function(resolve, reject) {
								db.get('SELECT COUNT(id) as rCount FROM posts WHERE domain = $domain AND _removed = 1', { $domain: domain }, function(err, row) {
									if(err) {
										return reject(err)
									}

									resolve(row.rCount)
								})
							}),
							when.promise(function(resolve, reject) {
								db.get('SELECT COUNT(id) as rec_tCount FROM posts WHERE domain = $domain'
									+ ' AND created_utc > $earliestTime', { $domain: domain, $earliestTime: params.$earliestTime }, function(err, row) {
									if(err) {
										return reject(err)
									}

									resolve(row.rec_tCount)
								})
							}),
							when.promise(function(resolve, reject) {
								db.get('SELECT COUNT(id) as rec_rCount FROM posts WHERE domain = $domain AND _removed = 1'
									+ ' AND created_utc > $earliestTime', { $domain: domain, $earliestTime: params.$earliestTime }, function(err, row) {
									if(err) {
										return reject(err)
									}

									resolve(row.rec_rCount)
								})
							})
						).then(function(val) {
							return {
								domain: domain,
								all: {
									total: val[0],
									removed: val[1]
								},
								recent: {
									total: val[2],
									removed: val[3]
								}
							}
						})
					})
				})
			)
		})
		.then(function(res) {
			// sigh, why does when.join have to be stupid...
			var total = res[0], removed = res[1], users = res[2], domains = res[3]
			output('done grabbing db entries, sending modmail')

			// note: this removal rate is only for recent submissions
			var removalRate = trainerred.removalRate(removed, total)
			if(options.mail) {
				var msg = '## TrainerRed initial database population complete.'
				msg += '\n\nTrainerRed has identified ' + total + ' entries (' + removed + ' removals; ' + trainerred.removalRate(removed, total) + '% removal rate) within the last 7 days for analysis.'
				msg += '\n\n---\n### users to review'
				msg += '\n\nsubmitter | overall subs | recent subs\n---|:---:|:---:'
				users.forEach(function(user) {
					if(user.all.removed === 1) {
						return // pass on this one, we don't need to care about first-struck users (we don't do the same for domains though)
					}
					msg += util.format('\n/u/%s | %d% (%d of %d rem) | %d% (%d of %d rem)',
						user.user, trainerred.removalRate(user.all.removed, user.all.total), user.all.removed, user.all.total,
						trainerred.removalRate(user.recent.removed, user.recent.total), user.recent.removed, user.recent.total)
				})
				msg += '\n\n---\n### domains to review'
				msg += '\n\ndomain | overall subs | recent subs\n---|:---:|:---:'
				domains.forEach(function(domain) {
					msg += util.format('\n[%s](https://www.reddit.com/domain/%s/) | %d% (%d of %d rem) | %d% (%d of %d rem)',
						domain.domain, domain.domain, trainerred.removalRate(domain.all.removed, domain.all.total), domain.all.removed, domain.all.total,
						trainerred.removalRate(domain.recent.removed, domain.recent.total), domain.recent.removed, domain.recent.total)
				})
				trainerred.modmail('TrainerRed Database updated', msg).then(function() {
					output('modmail sent!')
				})
			}

			// do we want to format the report and print it over stdout?
			// todo: other formatting options for stdout (csv?)
			// note: we're ignoring output() here and using console.log straight
			var stdoutExport = ''
			if(!options.export) {
				switch(options.export) {
					case 'json':
						stdoutExport = {
							overview: {
								total: total,
								removals: removed,
								removalRate: removalRate
							},
							users: [],
							domains: []
						}
						users.forEach(function(user) {
							if(user.all.removed === 1) {
								return
							}

							stdoutExport.users.push({
								user: '/u/' + user.user,
								recent: {
									total: user.recent.total,
									removed: user.recent.removed,
									rate: trainerred.removalRate(user.recent.removed, user.recent.total)
								}
								all: {
									total: user.all.total,
									removed: user.all.removed,
									rate: trainerred.removalRate(user.all.removed, user.all.total)
								}
							})
						})
						domains.forEach(function(domain) {
							stdoutExport.domains.push({
								domain: domain.domain,
								domainPage: 'https://www.reddit.com/domain/' + domain.domain,
								recent: {
									total: domain.recent.total,
									removed: domain.recent.removed,
									rate: trainerred.removalRate(domain.recent.removed, domain.recent.total)
								}
								all: {
									total: domain.all.total,
									removed: domain.all.removed,
									rate: trainerred.removalRate(domain.all.removed, domain.all.total)
								}
							})
						})
						stdoutExport = JSON.stringify(stdoutExport)
					break
					case 'standard':
					default:
						// todo - stdout formatting
					break
				}
				console.log(stdoutExport)
			}
			output('terminating...')
			return
		})
		.catch(trainerred.onError)
}
<|endoftext|>


<commit_before>$(document).ready(function(){

	$('#admin_page_controller').hide();
	$('#text_event_name').text("Error: Invalid event name ");
	var eventName = getURLParameter("q");
	if (eventName != null && eventName !== '' ) {
		$('#text_event_name').text("Event name: " + eventName);

	}

});

angular.module('teamform-admin-app', ['firebase'])
.controller('AdminCtrl', ['$scope', '$firebaseObject', '$firebaseArray', function($scope, $firebaseObject, $firebaseArray) {

	// TODO: implementation of AdminCtrl

	// Initialize $scope.param as an empty JSON object
	$scope.param = {};

	// Call Firebase initialization code defined in site.js
	initalizeFirebase();

	var ref = new Firebase("comp3111-1b643.firebaseio.com");
  // create an instance of the authentication service
  var auth = $firebaseAuth(ref);
  // login with Facebook
  auth.$authWithOAuthPopup("facebook").then(function(authData) {
    console.log("Logged in as:", authData.uid);
  }).catch(function(error) {
    console.log("Authentication failed:", error);
  });

	var refPath, ref, eventName;

	eventName = getURLParameter("q");
	refPath = eventName + "/admin/param";
	ref = firebase.database().ref(refPath);

	// Link and sync a firebase object

	$scope.param = $firebaseObject(ref);
	$scope.param.$loaded()
		.then( function(data) {

			// Fill in some initial values when the DB entry doesn't exist
			if(typeof $scope.param.maxTeamSize == "undefined"){
				$scope.param.maxTeamSize = 10;
			}
			if(typeof $scope.param.minTeamSize == "undefined"){
				$scope.param.minTeamSize = 1;
			}

			// Enable the UI when the data is successfully loaded and synchornized
			$('#admin_page_controller').show();
		})
		.catch(function(error) {
			// Database connection error handling...
			//console.error("Error:", error);
		});

	refPath = eventName + "/team";
	$scope.team = [];
	$scope.team = $firebaseArray(firebase.database().ref(refPath));

	refPath = eventName + "/member";
	$scope.member = [];
	$scope.member = $firebaseArray(firebase.database().ref(refPath));

	$scope.changeMinTeamSize = function(delta) {
		var newVal = $scope.param.minTeamSize + delta;
		if (newVal >=1 && newVal <= $scope.param.maxTeamSize ) {
			$scope.param.minTeamSize = newVal;
		}

		$scope.param.$save();

	}

	$scope.changeMaxTeamSize = function(delta) {
		var newVal = $scope.param.maxTeamSize + delta;
		if (newVal >=1 && newVal >= $scope.param.minTeamSize ) {
			$scope.param.maxTeamSize = newVal;
		}

		$scope.param.$save();

	}

	$scope.saveFunc = function() {

		$scope.param.$save();

		// Finally, go back to the front-end
		window.location.href= "index.html";
	}

}]);<commit_msg>firebase testing<commit_after>$(document).ready(function(){

	$('#admin_page_controller').hide();
	$('#text_event_name').text("Error: Invalid event name ");
	var eventName = getURLParameter("q");
	if (eventName != null && eventName !== '' ) {
		$('#text_event_name').text("Event name: " + eventName);

	}

});

angular.module('teamform-admin-app', ['firebase'])
.controller('AdminCtrl', ['$scope', '$firebaseObject', '$firebaseArray', function($scope, $firebaseObject, $firebaseArray) {

	// TODO: implementation of AdminCtrl

	// Initialize $scope.param as an empty JSON object
	$scope.param = {};

	// Call Firebase initialization code defined in site.js
	initalizeFirebase();

  // create an instance of the authentication service
  var auth = $firebaseAuth(firebase);
  // login with Facebook
  auth.$authWithOAuthPopup("facebook").then(function(authData) {
    console.log("Logged in as:", authData.uid);
  }).catch(function(error) {
    console.log("Authentication failed:", error);
  });

	var refPath, ref, eventName;

	eventName = getURLParameter("q");
	refPath = eventName + "/admin/param";
	ref = firebase.database().ref(refPath);

	// Link and sync a firebase object

	$scope.param = $firebaseObject(ref);
	$scope.param.$loaded()
		.then( function(data) {

			// Fill in some initial values when the DB entry doesn't exist
			if(typeof $scope.param.maxTeamSize == "undefined"){
				$scope.param.maxTeamSize = 10;
			}
			if(typeof $scope.param.minTeamSize == "undefined"){
				$scope.param.minTeamSize = 1;
			}

			// Enable the UI when the data is successfully loaded and synchornized
			$('#admin_page_controller').show();
		})
		.catch(function(error) {
			// Database connection error handling...
			//console.error("Error:", error);
		});

	refPath = eventName + "/team";
	$scope.team = [];
	$scope.team = $firebaseArray(firebase.database().ref(refPath));

	refPath = eventName + "/member";
	$scope.member = [];
	$scope.member = $firebaseArray(firebase.database().ref(refPath));

	$scope.changeMinTeamSize = function(delta) {
		var newVal = $scope.param.minTeamSize + delta;
		if (newVal >=1 && newVal <= $scope.param.maxTeamSize ) {
			$scope.param.minTeamSize = newVal;
		}

		$scope.param.$save();

	}

	$scope.changeMaxTeamSize = function(delta) {
		var newVal = $scope.param.maxTeamSize + delta;
		if (newVal >=1 && newVal >= $scope.param.minTeamSize ) {
			$scope.param.maxTeamSize = newVal;
		}

		$scope.param.$save();

	}

	$scope.saveFunc = function() {

		$scope.param.$save();

		// Finally, go back to the front-end
		window.location.href= "index.html";
	}

}]);<|endoftext|>


<commit_before>var contextPath = null;

//console log ================================
var PRD_MODE = false; //change = true if on production
if(typeof(console) === 'undefined') {
   console = {};
}

if(!PRD_MODE || typeof(console.log) === 'undefined') {
//   console.log = console.error = console.info = console.debug = console.warn = console.trace = console.dir = console.dirxml = console.group = console.groupEnd = console.time = console.timeEnd = console.assert = console.profile = function() {};
}
// console log ================================

function getContextPath() {
	if (contextPath == null) {
		contextPath = $('#contextPath').val();
	}
	return contextPath;
}

function getURL(url) {
	if (url.indexOf('/') == 0) {
		return getContextPath() + url;
	} else {
		return getContextPath() + '/' + url;
	}
}

function getValueById(id) {
	return $('#' + id).val();
}

function isNotEmptyValueById(id) {
	return isEmptyValueById(id);
}

function isEmptyValueById(id) {
	var value = getValueById(id);
	if (value == null || value == undefined || value == '') {
		return true;
	}
}

function isEmpty(value) {
	if (value == null || value == undefined || value == '') {
		return true;
	} else {
		return false;
	}
}

function trimToEmpty(value) {
	if (isEmpty(value)) {
		return '';
	}
	return value;
}

function redirect(url) {
	try {
		window.location.href = url;
	} catch (e) {
		window.location = url;
	}
}

//secondAuthURL///////////////////////////////
var secondAuthURL = null;
var secondAuthenURLConfig = {
	dev : 'https://sso-devt.true.th:11443/',
	uat : 'https://xxo-uat.true.th:11443/SSORESTFul/',
	prdIntra : 'https://xxo.true.th/SSORESTFul/',
	prdInter : 'https://wxxo.truecorp.co.th/SSORESTFul/'
};

function isUATEnv(host){
	return host.indexOf("uat") > 0;
}

function isDEVEnv(host){
	return host.indexOf("dev") > 0;
}

function isPRDEnv(host){
	if(isDEVEnv(host) === true) {
		return false;
    } else if(isUATEnv(host) === true){
    	return false;
    } else {
        if (host.indexOf("truecorp.co.th") > 0 || host.indexOf("true.th") > 0) {
        	return true;
        }
		return false;
    }
}

function getSecondAuthenURL(){
	if(secondAuthURL == null) {
		var hostname = window.location.hostname;
		if(isPRDEnv(hostname)) {
			var isInter = hostname.indexOf("truecorp.co.th") > 0;
			if(isInter) {
				secondAuthURL = secondAuthenURLConfig.prdInter;
			} else {
				secondAuthURL = secondAuthenURLConfig.prdIntra;
			}
		} else if(isUATEnv(hostname)) {
			secondAuthURL = secondAuthenURLConfig.uat;
		} else if(isDEVEnv(hostname)) {
			secondAuthURL = secondAuthenURLConfig.dev;
		} else {
			secondAuthURL = secondAuthenURLConfig.dev;
		}
	}
	console.log("hostname : " + hostname);
	console.log("secondAuthURL : " + secondAuthURL);
	return secondAuthURL;
}
//secondAuthURL///////////////////////////////<commit_msg>update util.js<commit_after>var contextPath = null;

//console log ================================
var PRD_MODE = false; //change = true if on production
if(typeof(console) === 'undefined') {
   console = {};
}

if(!PRD_MODE || typeof(console.log) === 'undefined') {
   console.log = console.error = console.info = console.debug = console.warn = console.trace = console.dir = console.dirxml = console.group = console.groupEnd = console.time = console.timeEnd = console.assert = console.profile = function() {};
}
// console log ================================

function getContextPath() {
	if (contextPath == null) {
		contextPath = $('#contextPath').val();
	}
	return contextPath;
}

function getURL(url) {
	if (url.indexOf('/') == 0) {
		return getContextPath() + url;
	} else {
		return getContextPath() + '/' + url;
	}
}

function getValueById(id) {
	return $('#' + id).val();
}

function isNotEmptyValueById(id) {
	return isEmptyValueById(id);
}

function isEmptyValueById(id) {
	var value = getValueById(id);
	if (value == null || value == undefined || value == '') {
		return true;
	}
}

function isEmpty(value) {
	if (value == null || value == undefined || value == '') {
		return true;
	} else {
		return false;
	}
}

function trimToEmpty(value) {
	if (isEmpty(value)) {
		return '';
	}
	return value;
}

function redirect(url) {
	try {
		window.location.href = url;
	} catch (e) {
		window.location = url;
	}
}

//secondAuthURL///////////////////////////////
var secondAuthURL = null;
var secondAuthenURLConfig = {
	dev : 'https://sso-devt.true.th:11443/',
	uat : 'https://xxo-uat.true.th:11443/SSORESTFul/',
	prdIntra : 'https://xxo.true.th/SSORESTFul/',
	prdInter : 'https://wxxo.truecorp.co.th/SSORESTFul/'
};

function isUATEnv(host){
	return host.indexOf("uat") > 0;
}

function isDEVEnv(host){
	return host.indexOf("dev") > 0;
}

function isPRDEnv(host){
	if(isDEVEnv(host) === true) {
		return false;
    } else if(isUATEnv(host) === true){
    	return false;
    } else {
        if (host.indexOf("truecorp.co.th") > 0 || host.indexOf("true.th") > 0) {
        	return true;
        }
		return false;
    }
}

function getSecondAuthenURL(){
	if(secondAuthURL == null) {
		var hostname = window.location.hostname;
		if(isPRDEnv(hostname)) {
			var isInter = hostname.indexOf("truecorp.co.th") > 0;
			if(isInter) {
				secondAuthURL = secondAuthenURLConfig.prdInter;
			} else {
				secondAuthURL = secondAuthenURLConfig.prdIntra;
			}
		} else if(isUATEnv(hostname)) {
			secondAuthURL = secondAuthenURLConfig.uat;
		} else if(isDEVEnv(hostname)) {
			secondAuthURL = secondAuthenURLConfig.dev;
		} else {
			secondAuthURL = secondAuthenURLConfig.dev;
		}
	}
	console.log("hostname : " + hostname);
	console.log("secondAuthURL : " + secondAuthURL);
	return secondAuthURL;
}
//secondAuthURL///////////////////////////////<|endoftext|>


<commit_before>import { config, Q, defer, async, log } from 'azk';
import { app }   from 'azk/agent/app';
import { VM  }   from 'azk/agent/vm';
import { Unfsd } from 'azk/agent/unfsd';
import { Balancer } from 'azk/agent/balancer';

var Server = {
  server: null,

  // TODO: log start machine steps
  start() {
    var self = this;
    return async(function* () {
      log.info_t("commands.agent.starting");

      // Virtual machine is required?
      if (config('agent:requires_vm')) {
        yield self.installShare();
        yield self.installVM(true);
      }

      // Load balancer
      yield self.installBalancer();

      // Start web api
      var socket  = config('paths:agent_socket');
      self.server = app.listen(socket);
      log.info_t("commands.agent.started", socket);
    })
  },

  stop() {
    var self = this;
    return Q.async(function* () {
      yield self.removeBalancer();
      yield self.stopVM();
      yield self.removeShare();

      if (self.server) {
        // Stop service
        yield Q.ninvoke(self.server, "close");
      } else {
        return Q.reject("Server not running");
      }
    })();
  },

  installBalancer() {
    return Balancer.start();
  },

  removeBalancer() {
    return Balancer.stop();
  },

  installShare() {
    return Unfsd.start();
  },

  removeShare() {
    return Unfsd.stop();
  },

  installVM(start = false, progress = () => {}) {
    var self = this;
    var vm_name = config("agent:vm:name");
    return Q.async(function* () {
      var installed = yield VM.isInstalled(vm_name);
      var running   = (installed) ? yield VM.isRunnig(vm_name) : false;

      if (!installed) {
        var opts = {
          name: vm_name,
          ip  : config("agent:vm:ip"),
          boot: config("agent:vm:boot_disk"),
          data: config("agent:vm:data_disk"),
        }

        yield VM.init(opts);
      }

      if (!running && start) {
        yield VM.start(vm_name);
        yield VM.configureIp(vm_name, config("agent:vm:ip")).progress(progress);
        yield Unfsd.mount(vm_name).progress(progress);
      };
    })();
  },

  stopVM(running) {
    var vm_name = config("agent:vm:name");
    return async(function* () {
      running = (running == null) ? (yield VM.isRunnig(vm_name)) : false;
      if (running) {
        yield VM.stop(vm_name);
      }
    });
  },
}

export { Server };

<commit_msg>Removing http server in agent.<commit_after>import { config, Q, defer, async, log } from 'azk';
import { app }   from 'azk/agent/app';
import { VM  }   from 'azk/agent/vm';
import { Unfsd } from 'azk/agent/unfsd';
import { Balancer } from 'azk/agent/balancer';

var Server = {
  server: null,

  // TODO: log start machine steps
  start() {
    var self = this;
    return async(function* () {
      log.info_t("commands.agent.starting");

      // Virtual machine is required?
      if (config('agent:requires_vm')) {
        yield self.installShare();
        yield self.installVM(true);
      }

      // Load balancer
      yield self.installBalancer();

      log.info_t("commands.agent.started");
    })
  },

  stop() {
    var self = this;
    return Q.async(function* () {
      yield self.removeBalancer();
      yield self.stopVM();
      yield self.removeShare();
    })();
  },

  installBalancer() {
    return Balancer.start();
  },

  removeBalancer() {
    return Balancer.stop();
  },

  installShare() {
    return Unfsd.start();
  },

  removeShare() {
    return Unfsd.stop();
  },

  installVM(start = false, progress = () => {}) {
    var self = this;
    var vm_name = config("agent:vm:name");
    return Q.async(function* () {
      var installed = yield VM.isInstalled(vm_name);
      var running   = (installed) ? yield VM.isRunnig(vm_name) : false;

      if (!installed) {
        var opts = {
          name: vm_name,
          ip  : config("agent:vm:ip"),
          boot: config("agent:vm:boot_disk"),
          data: config("agent:vm:data_disk"),
        }

        yield VM.init(opts);
      }

      if (!running && start) {
        yield VM.start(vm_name);
        yield VM.configureIp(vm_name, config("agent:vm:ip")).progress(progress);
        yield Unfsd.mount(vm_name).progress(progress);
      };
    })();
  },

  stopVM(running) {
    var vm_name = config("agent:vm:name");
    return async(function* () {
      running = (running == null) ? (yield VM.isRunnig(vm_name)) : false;
      if (running) {
        yield VM.stop(vm_name);
      }
    });
  },
}

export { Server };

<|endoftext|>


<commit_before>(function() {

  const path = require('path');
  const jetpack = require('fs-jetpack');
  const log = require('./log');
  const i18nDir = path.join(__dirname, '..', 'common', 'i18n');

  const loadStrings = function(lang, filename) {
    return new Promise(function(resolve, reject) {

      const msgDir = path.join(i18nDir, lang);
      if (!jetpack.exists(msgDir)) {
        return reject('Unknown language');
      }
      const file = path.join(msgDir, filename + '.json');
      if (!jetpack.exists(file)) {
        return reject('File not found');
      }

      let strings = {};
      strings = jetpack.read(
        path.join(msgDir, 'common.json'),
        'json'
      );
      const content = JSON.parse(
        jetpack.read(file)
      );
      Object.assign(strings, content);

      resolve(strings);

    });
  };

  module.exports = {
    loadStrings: loadStrings,
  };

})();
<commit_msg>Fallback to default lang if string is missing<commit_after>(function() {

  const path = require('path');
  const jetpack = require('fs-jetpack');
  const env = require('./env');
  const i18nDir = path.join(__dirname, '..', 'common', 'i18n');

  const loadStrings = function(lang, filename) {
    return new Promise(function(resolve, reject) {

      let strings = {};
      const defaultMsgDir = path.join(i18nDir, env.defaultLanguage);
      const defaultFile = path.join(defaultMsgDir, filename + '.json');
      strings = jetpack.read(
        path.join(defaultMsgDir, 'common.json'),
        'json'
      );
      Object.assign(
        strings,
        jetpack.read(defaultFile, 'json')
      );

      const msgDir = path.join(i18nDir, lang);
      const file = path.join(msgDir, filename + '.json');
      const commonFile = path.join(msgDir, 'common.json');
      Object.assign(
        strings,
        jetpack.read(commonFile, 'json')
      );
      Object.assign(
        strings,
        jetpack.read(file, 'json')
      );

      resolve(strings);

    });
  };

  module.exports = {
    loadStrings: loadStrings,
  };

})();
<|endoftext|>


<commit_before>import io from 'socket.io-client';
import THREE from 'three';
import './component.css!';

var socket = io.connect('http://localhost:9000');

// create a scene, that will hold all our elements such as objects, cameras and lights.
var scene = new THREE.Scene();

// create a camera, which defines where we're looking at.
var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);

// create a render and set the size
var webGLRenderer = new THREE.WebGLRenderer();
webGLRenderer.setClearColor(new THREE.Color(0x000000, 1.0));
webGLRenderer.setSize(window.innerWidth, window.innerHeight);

// position and point the camera to the center of the scene
camera.position.x = 0;
camera.position.y = 0;
camera.position.z = 150;

// add the output of the renderer to the html element
document.body.appendChild(webGLRenderer.domElement);

createParticles();
render();

function createParticles() {
	var geom = new THREE.Geometry();
	var material = new THREE.PointsMaterial({size: 1, color: 0xffffff});
	var particle = new THREE.Vector3(1, 1, 0);
	geom.vertices.push(particle);
	var system = new THREE.Points(geom, material);
	socket.on('state', (data) => {
		var positions = JSON.parse(data).particles[0].position;
		console.log(positions);
		particle.setX(positions.y * 10);
		particle.setY(positions.x * 10);
		particle.setZ(positions.z * 10);
		geom.verticesNeedUpdate = true;
	});
	scene.add(system);
}

function render() {
	requestAnimationFrame(render);
	webGLRenderer.render(scene, camera);
}

<commit_msg>Remove hardcoded socket client connection host + port<commit_after>import io from 'socket.io-client';
import THREE from 'three';
import './component.css!';

var socket = io.connect();

// create a scene, that will hold all our elements such as objects, cameras and lights.
var scene = new THREE.Scene();

// create a camera, which defines where we're looking at.
var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);

// create a render and set the size
var webGLRenderer = new THREE.WebGLRenderer();
webGLRenderer.setClearColor(new THREE.Color(0x000000, 1.0));
webGLRenderer.setSize(window.innerWidth, window.innerHeight);

// position and point the camera to the center of the scene
camera.position.x = 0;
camera.position.y = 0;
camera.position.z = 150;

// add the output of the renderer to the html element
document.body.appendChild(webGLRenderer.domElement);

createParticles();
render();

function createParticles() {
	var geom = new THREE.Geometry();
	var material = new THREE.PointsMaterial({size: 1, color: 0xffffff});
	var particle = new THREE.Vector3(1, 1, 0);
	geom.vertices.push(particle);
	var system = new THREE.Points(geom, material);
	socket.on('state', (data) => {
		var positions = JSON.parse(data).particles[0].position;
		console.log(positions);
		particle.setX(positions.y * 10);
		particle.setY(positions.x * 10);
		particle.setZ(positions.z * 10);
		geom.verticesNeedUpdate = true;
	});
	scene.add(system);
}

function render() {
	requestAnimationFrame(render);
	webGLRenderer.render(scene, camera);
}

<|endoftext|>


<commit_before>'use strict';

/**
 * @ngdoc module
 * @name vxWamp
 * @description
 *
 * # vxWamp
 *
 * The `vxWamp` module provides seamless WAMPv2 integration, by wrapping AutobahnJS, for angular apps.
 *
 * ## Example
 * See {@link $wamp#example $wamp} for an example of configuring and using `vxWamp`.
 *
 *
 *

 */
/* global -vxWampModule */
var vxWampModule = angular.module('vxWamp', []).provider('$wamp', $WampProvider);

/**
 * @ngdoc provider
 * @name $wampProvider
 *
 * @description
 *
 * Used for accessing a WAMP resource.
 *
 * ## Example
 * See {@link $wamp#example $wamp} for an example of configuring and using `vxWamp`.
 *
 * ## Dependencies
 * Requires the {@link vxWamp `vxWamp`} module to be installed.
 */
function $WampProvider() {
    var options;

    /**
     * @ngdoc method
     * @name $wampProvider#init
     *
     * @param {Object} initOptions autobahnJS connection options
     *
     *    Object properties:
     *
     *      Required options:
     *
     *    - `url`: `{string=}` - the WebSocket URL of the WAMP router to connect to, e.g. ws://myserver.com:8080/ws
     *    - `realm`: `{string=}` - The WAMP realm to join, e.g. realm1
     *
     *    Optional options:
     *
     *      Options that control what kind of Deferreds to use:
     *
     *      - `use_es6_promises`: `{boolean=}` - use deferreds based on ES6 promises
     *      - `use_deferred`: `{callable=}` - if provided, use this deferred constructor, e.g. jQuery.Deferred or Q.defer
     *
     *      Options that control automatic reconnection:
     *
     *      - `max_retries`: `{integer=}` - Maximum number of reconnection attempts (default: 15)
     *      - `initial_retry_delay`: `{float=}` - Initial delay for reconnection attempt in seconds (default: 1.5).
     *      - `max_retry_delay`: `{float=}` - Maximum delay for reconnection attempts in seconds (default: 300).
     *      - `retry_delay_growth`: `{float=}` - The growth factor applied to the retry delay between reconnection attempts (default: 1.5).
     *      - `retry_delay_jitter`: `{float=}` - The standard deviation of a Gaussian to jitter the delay on each retry cycle as a fraction of the mean (default: 0.1).
     *
     * @description
     * Configures the AutobhanJS Service
     */
    this.init = function (initOptions) {
        options = initOptions || {};
    };

    this.$get = function ($rootScope, $q, $log) {

        /**
         * @ngdoc service
         * @name $wamp
         *
         * @description
         * `$wamp` give you access to the autobahnJS methods, call, register, subscribe, unsubscribe and publish.
         *
         * Requires the {@link vxWamp `vxWamp`} module to be installed.
         *
         * You can configure the WAMP connection through {@link vxWamp.$wampProvider $wampProvider}'s API.
         *
         * @example
         *
         * app.config(function ($wampProvider) {
         *      $wampProvider.init({
         *          url: 'ws://127.0.0.1:9000/',
         *          realm: 'realm1'
         *      });
         * })
         *
         *  app.controller("MyCtrl", function($scope, $wamp) {
         *
         *      // 1) subscribe to a topic
         *      function onevent(args) {
         *          $scope.hello = args[0];
         *      }
         *      $wamp.subscribe('com.myapp.hello', onevent);
         *
         *      // 2) publish an event
         *      $wamp.publish('com.myapp.hello', ['Hello, world!']);
         *
         *      // 3) register a procedure for remoting
         *      function add2(args) {
         *          return args[0] + args[1];
         *      }
         *      $wamp.register('com.myapp.add2', add2);
         *
         *      // 4) call a remote procedure
         *      $wamp.call('com.myapp.add2', [2, 3]).then(
         *          function (res) {
         *          $scope.add2 = res;
         *      });
         * });
         *
         *
         * @todo write more docs
         */

        var callbackQueue = [], connection;
        var onChallengeDeferred = $q.defer();

        /**
         * @param session
         * @param method
         * @param extra
         * @returns {*}
         *
         * @description
         * Gets called when a Challenge Message is sent by the router
         */
        var onchallenge = function (session, method, extra) {

            $rootScope.$broadcast("$wamp.onchallenge", {
                promise: onChallengeDeferred,
                session: session,
                method: method,
                extra: extra
            });

            return onChallengeDeferred.promise;
        };

        /**
         * @param func
         * @returns {Function}
         *
         * @description
         * Wraps a callback with a function that calls scope.$apply(), so that the callback is added to the digest
         */
        function digestWrapper(func) {
            return function () {
                var cb = func.apply(this, arguments);
                $rootScope.$apply();
                return cb;
            };
        }

        options = angular.extend({onchallenge: digestWrapper(onchallenge)}, options);

        connection = new autobahn.Connection(options);
        connection.onopen = digestWrapper(function (session) {
            $log.debug("Congrats!  You're connected to the WAMP server!");
            $rootScope.$broadcast("$wamp.open", session);

            //Call any callbacks that were queued up before the connection was established
            var call, resultPromise;

            while (callbackQueue.length > 0) {
                call = callbackQueue.shift();
                resultPromise = session[call.method].apply(session, call.args);
                call.promise.resolve(resultPromise);
                $log.debug("processed queued " + call.method);
            }
        });

        connection.onclose = digestWrapper(function (reason, details) {
            $log.debug("Connection Closed: ", reason);
            $rootScope.$broadcast("$wamp.close", {reason: reason, details: details});

        });

        /**
         * Subscription object which self manages reconnections
         * @param topic
         * @param handler
         * @param options
         * @param subscribedCallback
         * @returns {{}}
         * @constructor
         */
        var Subscription = function (topic, handler, options, subscribedCallback) {

            var subscription = {}, unregister, onOpen, deferred = $q.defer();

            handler = digestWrapper(handler);

            onOpen = function () {
                var p = connection.session.subscribe(topic, handler, options).then(
                    function (s) {
                        subscription = angular.extend(s, subscription);
                        deferred.resolve(subscription);
                        return s;
                    }
                );
                if (subscribedCallback) {
                    subscribedCallback($q.when(p));
                }

            };

            if (connection.isOpen) {
                onOpen();
            }

            unregister = $rootScope.$on("$wamp.open", onOpen);

            subscription.promise = deferred.promise;
            subscription.unsubscribe = function () {
                unregister(); //Remove the event listener, so this object can get cleaned up by gc
                return $q.when(connection.session.unsubscribe(subscription));
            };

            return subscription;
        };

        return {
            connection: connection,
            session: connection.session,
            open: function () {
                connection.open();
            },
            close: function () {
                connection.close();
            },
            subscribe: function (topic, handler, options, subscribedCallback) {
                return Subscription(topic, handler, options, subscribedCallback).promise;
            },
            unsubscribe: function (subscription) {
                return subscription.unsubscribe();
            },
            publish: function (topic, args, kwargs, options) {

                if (!connection.isOpen) {
                    var deferred = $q.defer();
                    callbackQueue.push({method: 'publish', args: arguments, promise: deferred});
                    $log.debug("connection not open, queuing publish");
                    return deferred.promise;
                }

                return $q.when(connection.session.publish(topic, args, kwargs, options));
            },
            register: function (procedure, endpoint, options) {

                endpoint = digestWrapper(endpoint);
                if (!connection.isOpen) {
                    var deferred = $q.defer();
                    callbackQueue.push({
                        method: 'register',
                        args: [procedure, endpoint, options],
                        promise: deferred
                    });
                    $log.debug("connection not open, queuing register");
                    return deferred.promise;
                }

                return $q.when(connection.session.register(procedure, endpoint, options));
            },
            call: function (procedure, args, kwargs, options) {

                if (!connection.isOpen) {
                    var deferred = $q.defer();
                    callbackQueue.push({method: 'call', args: arguments, promise: deferred});
                    $log.debug("connection not open, queuing call");
                    return deferred.promise;
                }

                return $q.when(connection.session.call(procedure, args, kwargs, options));
            }
        };
    };

    return this;

}
<commit_msg>Autobahn now uses the $q promise with the ``use_deferred`` option.  #3<commit_after>'use strict';

/**
 * @ngdoc module
 * @name vxWamp
 * @description
 *
 * # vxWamp
 *
 * The `vxWamp` module provides seamless WAMPv2 integration, by wrapping AutobahnJS, for angular apps.
 *
 * ## Example
 * See {@link $wamp#example $wamp} for an example of configuring and using `vxWamp`.
 *
 *
 *

 */
/* global -vxWampModule */
var vxWampModule = angular.module('vxWamp', []).provider('$wamp', $WampProvider);

/**
 * @ngdoc provider
 * @name $wampProvider
 *
 * @description
 *
 * Used for accessing a WAMP resource.
 *
 * ## Example
 * See {@link $wamp#example $wamp} for an example of configuring and using `vxWamp`.
 *
 * ## Dependencies
 * Requires the {@link vxWamp `vxWamp`} module to be installed.
 */
function $WampProvider() {
    var options;

    /**
     * @ngdoc method
     * @name $wampProvider#init
     *
     * @param {Object} initOptions autobahnJS connection options
     *
     *    Object properties:
     *
     *      Required options:
     *
     *    - `url`: `{string=}` - the WebSocket URL of the WAMP router to connect to, e.g. ws://myserver.com:8080/ws
     *    - `realm`: `{string=}` - The WAMP realm to join, e.g. realm1
     *
     *    Optional options:
     *
     *      Options that control what kind of Deferreds to use:
     *
     *      - `use_es6_promises`: `{boolean=}` - use deferreds based on ES6 promises
     *      - `use_deferred`: `{callable=}` - if provided, use this deferred constructor, e.g. jQuery.Deferred or Q.defer
     *
     *      Options that control automatic reconnection:
     *
     *      - `max_retries`: `{integer=}` - Maximum number of reconnection attempts (default: 15)
     *      - `initial_retry_delay`: `{float=}` - Initial delay for reconnection attempt in seconds (default: 1.5).
     *      - `max_retry_delay`: `{float=}` - Maximum delay for reconnection attempts in seconds (default: 300).
     *      - `retry_delay_growth`: `{float=}` - The growth factor applied to the retry delay between reconnection attempts (default: 1.5).
     *      - `retry_delay_jitter`: `{float=}` - The standard deviation of a Gaussian to jitter the delay on each retry cycle as a fraction of the mean (default: 0.1).
     *
     * @description
     * Configures the AutobhanJS Service
     */
    this.init = function (initOptions) {
        options = initOptions || {};
    };

    this.$get = function ($rootScope, $q, $log) {

        /**
         * @ngdoc service
         * @name $wamp
         *
         * @description
         * `$wamp` give you access to the autobahnJS methods, call, register, subscribe, unsubscribe and publish.
         *
         * Requires the {@link vxWamp `vxWamp`} module to be installed.
         *
         * You can configure the WAMP connection through {@link vxWamp.$wampProvider $wampProvider}'s API.
         *
         * @example
         *
         * app.config(function ($wampProvider) {
         *      $wampProvider.init({
         *          url: 'ws://127.0.0.1:9000/',
         *          realm: 'realm1'
         *      });
         * })
         *
         *  app.controller("MyCtrl", function($scope, $wamp) {
         *
         *      // 1) subscribe to a topic
         *      function onevent(args) {
         *          $scope.hello = args[0];
         *      }
         *      $wamp.subscribe('com.myapp.hello', onevent);
         *
         *      // 2) publish an event
         *      $wamp.publish('com.myapp.hello', ['Hello, world!']);
         *
         *      // 3) register a procedure for remoting
         *      function add2(args) {
         *          return args[0] + args[1];
         *      }
         *      $wamp.register('com.myapp.add2', add2);
         *
         *      // 4) call a remote procedure
         *      $wamp.call('com.myapp.add2', [2, 3]).then(
         *          function (res) {
         *          $scope.add2 = res;
         *      });
         * });
         *
         *
         * @todo write more docs
         */

        var callbackQueue = [], connection;
        var onChallengeDeferred = $q.defer();

        /**
         * @param session
         * @param method
         * @param extra
         * @returns {*}
         *
         * @description
         * Gets called when a Challenge Message is sent by the router
         */
        var onchallenge = function (session, method, extra) {

            $rootScope.$broadcast("$wamp.onchallenge", {
                promise: onChallengeDeferred,
                session: session,
                method: method,
                extra: extra
            });

            return onChallengeDeferred.promise;
        };

        /**
         * @param func
         * @returns {Function}
         *
         * @description
         * Wraps a callback with a function that calls scope.$apply(), so that the callback is added to the digest
         */
        function digestWrapper(func) {
            return function () {
                var cb = func.apply(this, arguments);
                $rootScope.$apply();
                return cb;
            };
        }

        options = angular.extend({onchallenge: digestWrapper(onchallenge), use_deferred: $q.defer}, options);

        connection = new autobahn.Connection(options);
        connection.onopen = digestWrapper(function (session) {
            $log.debug("Congrats!  You're connected to the WAMP server!");
            $rootScope.$broadcast("$wamp.open", session);

            //Call any callbacks that were queued up before the connection was established
            var call, resultPromise;

            while (callbackQueue.length > 0) {
                call = callbackQueue.shift();
                resultPromise = session[call.method].apply(session, call.args);
                call.promise.resolve(resultPromise);
                $log.debug("processed queued " + call.method);
            }
        });

        connection.onclose = digestWrapper(function (reason, details) {
            $log.debug("Connection Closed: ", reason);
            $rootScope.$broadcast("$wamp.close", {reason: reason, details: details});

        });

        /**
         * Subscription object which self manages reconnections
         * @param topic
         * @param handler
         * @param options
         * @param subscribedCallback
         * @returns {{}}
         * @constructor
         */
        var Subscription = function (topic, handler, options, subscribedCallback) {

            var subscription = {}, unregister, onOpen, deferred = $q.defer();

            handler = digestWrapper(handler);

            onOpen = function () {
                var p = connection.session.subscribe(topic, handler, options).then(
                    function (s) {
                        subscription = angular.extend(s, subscription);
                        deferred.resolve(subscription);
                        return s;
                    }
                );
                if (subscribedCallback) {
                    subscribedCallback(p);
                }

            };

            if (connection.isOpen) {
                onOpen();
            }

            unregister = $rootScope.$on("$wamp.open", onOpen);

            subscription.promise = deferred.promise;
            subscription.unsubscribe = function () {
                unregister(); //Remove the event listener, so this object can get cleaned up by gc
                return connection.session.unsubscribe(subscription);
            };

            return subscription;
        };

        return {
            connection: connection,
            session: connection.session,
            open: function () {
                connection.open();
            },
            close: function () {
                connection.close();
            },
            subscribe: function (topic, handler, options, subscribedCallback) {
                return Subscription(topic, handler, options, subscribedCallback).promise;
            },
            unsubscribe: function (subscription) {
                return subscription.unsubscribe();
            },
            publish: function (topic, args, kwargs, options) {

                if (!connection.isOpen) {
                    var deferred = $q.defer();
                    callbackQueue.push({method: 'publish', args: arguments, promise: deferred});
                    $log.debug("connection not open, queuing publish");
                    return deferred.promise;
                }

                return connection.session.publish(topic, args, kwargs, options);
            },
            register: function (procedure, endpoint, options) {

                endpoint = digestWrapper(endpoint);
                if (!connection.isOpen) {
                    var deferred = $q.defer();
                    callbackQueue.push({
                        method: 'register',
                        args: [procedure, endpoint, options],
                        promise: deferred
                    });
                    $log.debug("connection not open, queuing register");
                    return deferred.promise;
                }

                return connection.session.register(procedure, endpoint, options);
            },
            call: function (procedure, args, kwargs, options) {

                if (!connection.isOpen) {
                    var deferred = $q.defer();
                    callbackQueue.push({method: 'call', args: arguments, promise: deferred});
                    $log.debug("connection not open, queuing call");
                    return deferred.promise;
                }

                return connection.session.call(procedure, args, kwargs, options);
            }
        };
    };

    return this;

}
<|endoftext|>


<commit_before>import assignSafe from '../util/assign-safe';
import dashCase from '../util/dash-case';
import data from '../util/data';
import emit from './emit';

/* jshint expr: true */
function notify (elem, notifyName, propName, detail = {}) {
  // Notifications must *always* have:
  // - name
  // - newValue
  // - oldValue
  // but may contain other information.
  detail.name = propName;
  detail.newValue === undefined && (detail.newValue = elem[propName]);
  detail.oldValue === undefined && (detail.oldValue = elem[propName]);

  emit(elem, notifyName, {
    bubbles: true,
    cancelable: false,
    detail: detail
  });
}

function property (name, prop) {
  var internalGetter, internalSetter, internalValue, isBoolean;

  if (typeof prop === 'object') {
    prop = assignSafe({}, prop);
  } else {
    prop = { type: prop };
  }

  if (prop.attr === true) {
    prop.attr = dashCase(name);
  }

  if (typeof prop.deps === 'string') {
    prop.deps = prop.deps.split(' ');
  }

  if (!Array.isArray(prop.deps)) {
    prop.deps = [];
  }

  if (prop.notify === undefined) {
    prop.notify = true;
  }

  if (prop.notify === true) {
    prop.notify = 'skate.property';
  }

  if (typeof prop.type !== 'function') {
    prop.type = val => val;
  }

  internalGetter = prop.get;
  internalSetter = prop.set;
  isBoolean = prop.type && prop.type === Boolean;
  delete prop.value;

  prop.get = function () {
    return internalGetter ? internalGetter.apply(this) : internalValue;
  };

  prop.set = function (value) {
    var info = data(this);

    // If the property is being updated and it is a boolean we must just check
    // if the attribute exists because "" is true for a boolean attribute.
    if (info.updatingProperty && isBoolean) {
      value = this.hasAttribute(prop.attr);
    }

    // We report both new and old values;
    var newValue = prop.type(value);
    var oldValue = this[name];

    // Regardless of any options, we store the value internally.
    internalValue = newValue;

    // We check first to see if we're already updating the property from
    // the attribute. If we are, then there's no need to update the attribute
    // especially because it would invoke an infinite loop.
    if (prop.attr && !info.updatingProperty) {
      info.updatingAttribute = true;

      if (isBoolean && internalValue) {
        this.setAttribute(prop.attr, '');
      } else if (isBoolean && !internalValue) {
        this.removeAttribute(prop.attr, '');
      } else {
        this.setAttribute(prop.attr, internalValue);
      }

      info.updatingAttribute = false;
    }

    // A setter is responsible for setting its own value. We still store the
    // value internally because the default getter may still be used to return
    // that value. Even if it's not, we use it to reference the old value which
    // is useful information for the setter.
    if (internalSetter) {
      internalSetter.call(this, newValue, oldValue);
    }

    if (prop.notify) {
      notify(this, prop.notify, name, {
        newValue: newValue,
        oldValue: oldValue
      });
    }
  };

  return prop;
}

function makePropertyHandler (elem, name, depPath, depName) {
  return function (e) {
    if (depName !== e.detail.name) {
      return;
    }

    var target = elem;

    // Resolve the dependency element from the dependecy path. If no path
    // exists, this will continue to be the main element. If the path
    // points to a non-element, then it's a no-op.
    depPath.forEach(function (part) {
      target = elem && elem[part];
    });

    // If the event bubbled, ensure that it doesn't call any handlers for
    // the same property on main element.
    if (elem !== e.target) {
      e.stopImmediatePropagation();
    }

    // Only notify of changes if the main element, or the element matched by
    // the dependency path, matches the target that triggered the event.
    if (target === e.target) {
      // We get and set the property so that logic in the getter and setter
      // get invoked. When the setter is invoked, it automatically notifies
      // any dependencies.
      elem[name] = elem[name];
    }
  };
}

function defineProperty (elem, name, prop) {
  // We don't need to scope the data to the component ID be cause if multiple
  // bindings on the same component define the same attribute, then they'd
  // conflict anyways.
  var info = data(elem);
  var value = prop && prop.value || undefined;

  if (!info.attributeToPropertyMap) {
    info.attributeToPropertyMap = {};
  }

  prop = property(name, prop);
  Object.defineProperty(elem, name, prop);

  // Initialise the value if a initial value was provided. Attributes that exist
  // on the element should trump any default values that are provided.
  if (value !== undefined && (!prop.attr || !elem.hasAttribute(prop.attr))) {
    elem[name] = typeof value === 'function' ? value.call(elem) : value;
  }

  // This ensures that the corresponding attribute will know to update this
  // property when it is set.
  if (prop.attr) {
    info.attributeToPropertyMap[prop.attr] = name;
  }

  // If you aren't notifying of property changes, then dependencies aren't
  // listened to.
  if (prop.notify) {
    prop.deps.forEach(function (dep) {
      var depPath = dep.split('.');
      var depName = depPath.pop();
      elem.addEventListener(prop.notify, makePropertyHandler(elem, name, depPath, depName));
    });
  }
}

function defineProperties (elem, props) {
  Object.keys(props).forEach(function (name) {
    defineProperty(elem, name, props[name]);
  });
}

export default function (elem, props = {}, prop = {}) {
  if (typeof props === 'string') {
    defineProperty(elem, props, prop);
  } else {
    defineProperties(elem, props);
  }
}
<commit_msg>Fix issue causing the value to not get initialised.<commit_after>import assignSafe from '../util/assign-safe';
import dashCase from '../util/dash-case';
import data from '../util/data';
import emit from './emit';

/* jshint expr: true */
function notify (elem, notifyName, propName, detail = {}) {
  // Notifications must *always* have:
  // - name
  // - newValue
  // - oldValue
  // but may contain other information.
  detail.name = propName;
  detail.newValue === undefined && (detail.newValue = elem[propName]);
  detail.oldValue === undefined && (detail.oldValue = elem[propName]);

  emit(elem, notifyName, {
    bubbles: true,
    cancelable: false,
    detail: detail
  });
}

function property (name, prop) {
  var internalGetter, internalSetter, internalValue, isBoolean;

  if (typeof prop === 'object') {
    prop = assignSafe({}, prop);
  } else {
    prop = { type: prop };
  }

  if (prop.attr === true) {
    prop.attr = dashCase(name);
  }

  if (typeof prop.deps === 'string') {
    prop.deps = prop.deps.split(' ');
  }

  if (!Array.isArray(prop.deps)) {
    prop.deps = [];
  }

  if (prop.notify === undefined) {
    prop.notify = true;
  }

  if (prop.notify === true) {
    prop.notify = 'skate.property';
  }

  if (typeof prop.type !== 'function') {
    prop.type = val => val;
  }

  internalGetter = prop.get;
  internalSetter = prop.set;
  isBoolean = prop.type && prop.type === Boolean;
  delete prop.value;

  prop.get = function () {
    return internalGetter ? internalGetter.apply(this) : internalValue;
  };

  prop.set = function (value) {
    var info = data(this);

    // If the property is being updated and it is a boolean we must just check
    // if the attribute exists because "" is true for a boolean attribute.
    if (info.updatingProperty && isBoolean) {
      value = this.hasAttribute(prop.attr);
    }

    // We report both new and old values;
    var newValue = prop.type(value);
    var oldValue = this[name];

    // Regardless of any options, we store the value internally.
    internalValue = newValue;

    // We check first to see if we're already updating the property from
    // the attribute. If we are, then there's no need to update the attribute
    // especially because it would invoke an infinite loop.
    if (prop.attr && !info.updatingProperty) {
      info.updatingAttribute = true;

      if (isBoolean && internalValue) {
        this.setAttribute(prop.attr, '');
      } else if (isBoolean && !internalValue) {
        this.removeAttribute(prop.attr, '');
      } else {
        this.setAttribute(prop.attr, internalValue);
      }

      info.updatingAttribute = false;
    }

    // A setter is responsible for setting its own value. We still store the
    // value internally because the default getter may still be used to return
    // that value. Even if it's not, we use it to reference the old value which
    // is useful information for the setter.
    if (internalSetter) {
      internalSetter.call(this, newValue, oldValue);
    }

    if (prop.notify) {
      notify(this, prop.notify, name, {
        newValue: newValue,
        oldValue: oldValue
      });
    }
  };

  return prop;
}

function makePropertyHandler (elem, name, depPath, depName) {
  return function (e) {
    if (depName !== e.detail.name) {
      return;
    }

    var target = elem;

    // Resolve the dependency element from the dependecy path. If no path
    // exists, this will continue to be the main element. If the path
    // points to a non-element, then it's a no-op.
    depPath.forEach(function (part) {
      target = elem && elem[part];
    });

    // If the event bubbled, ensure that it doesn't call any handlers for
    // the same property on main element.
    if (elem !== e.target) {
      e.stopImmediatePropagation();
    }

    // Only notify of changes if the main element, or the element matched by
    // the dependency path, matches the target that triggered the event.
    if (target === e.target) {
      // We get and set the property so that logic in the getter and setter
      // get invoked. When the setter is invoked, it automatically notifies
      // any dependencies.
      elem[name] = elem[name];
    }
  };
}

function defineProperty (elem, name, prop) {
  // We don't need to scope the data to the component ID be cause if multiple
  // bindings on the same component define the same attribute, then they'd
  // conflict anyways.
  var info = data(elem);
  var value = prop && prop.value !== 'undefined' ? prop.value : undefined;

  if (!info.attributeToPropertyMap) {
    info.attributeToPropertyMap = {};
  }

  prop = property(name, prop);
  Object.defineProperty(elem, name, prop);

  // Initialise the value if a initial value was provided. Attributes that exist
  // on the element should trump any default values that are provided.
  if (value !== undefined && (!prop.attr || !elem.hasAttribute(prop.attr))) {
    elem[name] = typeof value === 'function' ? value.call(elem) : value;
  }

  // This ensures that the corresponding attribute will know to update this
  // property when it is set.
  if (prop.attr) {
    info.attributeToPropertyMap[prop.attr] = name;
  }

  // If you aren't notifying of property changes, then dependencies aren't
  // listened to.
  if (prop.notify) {
    prop.deps.forEach(function (dep) {
      var depPath = dep.split('.');
      var depName = depPath.pop();
      elem.addEventListener(prop.notify, makePropertyHandler(elem, name, depPath, depName));
    });
  }
}

function defineProperties (elem, props) {
  Object.keys(props).forEach(function (name) {
    defineProperty(elem, name, props[name]);
  });
}

export default function (elem, props = {}, prop = {}) {
  if (typeof props === 'string') {
    defineProperty(elem, props, prop);
  } else {
    defineProperties(elem, props);
  }
}
<|endoftext|>


<commit_before>function getResult(callback, json) {

    var res = 'yolo';

    json.index = json.index+1;
    if(json.step[json.index].end){
         callback(res);
     }else{
         var action_module = require('./'+ json.step[json.index].call_id + '.js');
         action_module.getResult(function(result) {
             console.log(json.step[json.index].call_id + " : " + result);
             callback(result);

         },json);
     }
}

exports.getResult = getResult;
<commit_msg>Update api_2_call_2.js<commit_after>function getResult(callback, json) {

    console.log("Call made : api_2_call_2");

    var res = 'yolo';

    json.index = json.index+1;
    if(json.step[json.index].end){
         callback(res);
     }else{
         var action_module = require('./'+ json.step[json.index].call_id + '.js');
         action_module.getResult(function(result) {
             console.log(json.step[json.index].call_id + " : " + result);
             callback(result);

         },json);
     }
}

exports.getResult = getResult;
<|endoftext|>


<commit_before>import React, {Component} from 'react';
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider';
import ListItem from 'material-ui/List/ListItem';
import Drawer from 'material-ui/Drawer';
import RaisedButton from 'material-ui/RaisedButton';
import Subheader from 'material-ui/Subheader';
import Avatar from 'material-ui/Avatar';
import {muiTheme} from './ColorScheme';

const styles = {
    container: {
        textAlign: 'center',
        paddingTop: 20,
    },
    list: {
        textAlign: 'left',
        margin: 40
    },
    img: {
        maxHeight: 150,
        paddingRight: 16
    },
    beerName: {
        fontSize: 'larger',
        fontWeight: 'bold'
    },
    abv: {
        fontSize: 'larger',
        fontStyle: 'italic'
    }

};

class BeerList extends Component {
    constructor(props, context) {
        super(props, context);

        let swapId = this.props.params['swapId'];

        this.state = {
            swapId: swapId,
            userBeerList: [],
            open: false
        };
    }

    handleToggle = () => this.setState({open: !this.state.open});

    componentWillMount() {
        // get the beers for this swap
        let swapId = this.state.swapId,
            // url = `http://beerswap.enservio.lan/BeerWS/api/Beer/Swap/List/V1/${swapId}`,
            url = `http://beerswap.enservio.lan/BeerWS/api/Beer/Swap/attendees/V1/${swapId}`,
            me = this;

        fetch(url, {
            headers: new Headers({
                'Content-Type': 'application/json'
            }),
            mode: 'cors',
            method: 'get'
        }).then(function (response) {
            return response.json();
        }).then(setBeerList);

        function setBeerList (beerList) {
            if (beerList && beerList instanceof Object && beerList.UserSelections && Array.isArray(beerList.UserSelections)) {
                me.setState({
                    userBeerList: beerList.UserSelections
                });
            }
        }
    }

    getBreweryName(brewery) {
        let bName = brewery.Name || '';
        if (brewery.Website) {
            return (
                {bName}
            )
        } else {
            return bName;
        }
    }

    render() {
        const userBeers = this.state.userBeerList.slice();
        const users = userBeers.map((user) => {
            return (
                <ListItem key={user.$id}
                          primaryText={user.FirstName + ' ' + user.LastName}
                          leftAvatar={<Avatar>{user.SelectionOrder > 0 ? user.SelectionOrder : '?'}</Avatar>}
                />
            );
        });

        const userBeerList = userBeers.map((userBeer) => (

                     {userBeer.BeerSelection.BeerName}
                    {userBeer.BeerSelection.Abv}   | {this.getBreweryName(userBeer.BeerSelection.Brewery)}

                    {userBeer.BeerSelection.BeerDescription}

        ));
        return (
            <MuiThemeProvider muiTheme={muiTheme}>

Beer List

                        <RaisedButton
                            label="Show Users"
                            onTouchTap={this.handleToggle}
                        />
                        <Drawer open={this.state.open} openSecondary={true} style={styles.list}>
                            <Subheader style={styles.container}>Users</Subheader>
                            {users}
                        </Drawer>

                        {userBeerList}

            </MuiThemeProvider>
        );
    }
}

export default BeerList;
<commit_msg>Changing button name to draft order.<commit_after>import React, {Component} from 'react';
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider';
import ListItem from 'material-ui/List/ListItem';
import Drawer from 'material-ui/Drawer';
import RaisedButton from 'material-ui/RaisedButton';
import Subheader from 'material-ui/Subheader';
import Avatar from 'material-ui/Avatar';
import {muiTheme} from './ColorScheme';

const styles = {
    container: {
        textAlign: 'center',
        paddingTop: 20,
    },
    list: {
        textAlign: 'left',
        margin: 40
    },
    img: {
        maxHeight: 150,
        paddingRight: 16
    },
    beerName: {
        fontSize: 'larger',
        fontWeight: 'bold'
    },
    abv: {
        fontSize: 'larger',
        fontStyle: 'italic'
    }

};

class BeerList extends Component {
    constructor(props, context) {
        super(props, context);

        let swapId = this.props.params['swapId'];

        this.state = {
            swapId: swapId,
            userBeerList: [],
            open: false
        };
    }

    handleToggle = () => this.setState({open: !this.state.open});

    componentWillMount() {
        // get the beers for this swap
        let swapId = this.state.swapId,
            // url = `http://beerswap.enservio.lan/BeerWS/api/Beer/Swap/List/V1/${swapId}`,
            url = `http://beerswap.enservio.lan/BeerWS/api/Beer/Swap/attendees/V1/${swapId}`,
            me = this;

        fetch(url, {
            headers: new Headers({
                'Content-Type': 'application/json'
            }),
            mode: 'cors',
            method: 'get'
        }).then(function (response) {
            return response.json();
        }).then(setBeerList);

        function setBeerList (beerList) {
            if (beerList && beerList instanceof Object && beerList.UserSelections && Array.isArray(beerList.UserSelections)) {
                me.setState({
                    userBeerList: beerList.UserSelections
                });
            }
        }
    }

    getBreweryName(brewery) {
        let bName = brewery.Name || '';
        if (brewery.Website) {
            return (
                {bName}
            )
        } else {
            return bName;
        }
    }

    render() {
        const userBeers = this.state.userBeerList.slice();
        const users = userBeers.map((user) => {
            return (
                <ListItem key={user.$id}
                          primaryText={user.FirstName + ' ' + user.LastName}
                          leftAvatar={<Avatar>{user.SelectionOrder > 0 ? user.SelectionOrder : '?'}</Avatar>}
                />
            );
        });

        const userBeerList = userBeers.map((userBeer) => (

                     {userBeer.BeerSelection.BeerName}
                    {userBeer.BeerSelection.Abv}   | {this.getBreweryName(userBeer.BeerSelection.Brewery)}

                    {userBeer.BeerSelection.BeerDescription}

        ));
        return (
            <MuiThemeProvider muiTheme={muiTheme}>

Beer List

                        <RaisedButton
                            label="Draft Order"
                            onTouchTap={this.handleToggle}
                        />
                        <Drawer open={this.state.open} openSecondary={true} style={styles.list}>
                            <Subheader style={styles.container}>Users</Subheader>
                            {users}
                        </Drawer>

                        {userBeerList}

            </MuiThemeProvider>
        );
    }
}

export default BeerList;
<|endoftext|>


<commit_before>var domBuilder = require('dombuilder');
var progressParser = require('../lib/progress-parser.js');
var ui = require('./ui.js');

module.exports = function (backend) {
  ui.push(repoList(backend));
};

function repoList(backend) {
  var $ = {};
  var pending;
  var children = {};
  backend.init(onAdd, onRemove, onReady);

  return domBuilder(["section.page$page", {"data-position": "none", css: {opacity: 0.5}},
    ["header",
      ["button", {onclick:onclick(add)}, [".icon-plus"]],
      ["h1", "Git Repositories"]
    ],
    ["ul.content.header$list"]
  ], $);

  function onAdd(repo) {
    var icon = ".icon.left.icon-";
    if (/github\.com/.test(repo.url)) {
      icon += "github";
    }
    else if (/bitbucket\.org/.test(repo.url)) {
      icon += "bitbucket";
    }
    else {
      icon += "git";
    }
    var $$ = {};
    var child = domBuilder(
      ["li$li", { href: "#", onclick: onclick(fetch, repo, icon, $$) },
        [icon],
        ["p", repo.name],
        ["p", repo.description],
        ["p.progress",
          ["progress$progress"], ["span$span", "Working..."]
        ],
      ], $$
    );
    children[repo.name] = child;
    $.list.appendChild(child);
    repo.remove = remove;

    function remove(callback) {
      backend.remove(repo, callback);
    }
  }

  function onRemove(meta) {
    var child = children[meta.name];
    delete children[meta.name];
    $.list.removeChild(child);
  }

  function onReady(err) {
    if (err) return ui.error(err);
    $.page.style.opacity = 1;
  }

  function fetch(repo, icon, $$) {
    var progress = $$.progress;
    var span = $$.span;
    var child = $$.li;
    pending = repo;

    return repo.getHead(function (err, head) {
      if (err) return ui.error(err);
      if (!head) return clone();
      return onFetch();
    });

    function clone() {
      child.classList.add("active");
      repo.fetch(repo.remote, {
        onProgress: progressParser(function (message, num, max) {
          progress.setAttribute("max", max);
          progress.setAttribute("value", num);
          span.textContent = message;
        })
      }, onFetch);

    }

    function onFetch(err) {
      if (err) return ui.error(err);
      var oldChild = child;
      child = domBuilder(
        ["li", { href:"#", onclick: onclick(load, repo) },
          [icon],
          [".icon.right.icon-right-open"],
          ["p", repo.name],
          ["p", repo.description]
        ]
      );
      children[repo.name] = child;
      $$ = null;
      $.list.replaceChild(child, oldChild);
      if (pending === repo) load(repo);
    }

  }

  function load(repo) {
    pending = null;
    repo.logWalk("HEAD", function (err, stream) {
      if (err) return ui.error(err);
      ui.push(historyList(repo, stream));
    });
  }

  function add() {
    ui.push(addPage(backend));
  }

}

function addPage(backend) {
  var $ = {};
  var working = false;
  return domBuilder(["section.page",
    ["header",
      ["button.back", {onclick: ui.pop}, [".icon-left-open"]],
      ["h1", "Add Repository"]
    ],
    ["form.content.header", {onsubmit: submit},
      ["label", {"for": "url"}, "Remote Url"],
      ["input", {
        type: "text",
        name: "url",
        placeholder: "Enter git url here",
        value: "git://github.com/creationix/conquest.git",
        required: true
      }],
      ["label", {"for": "name"}, "Name"],
      ["input", {
        type: "text",
        name: "name",
        placeholder: "Enter custom local name here",
      }],
      ["label", {"for": "description"}, "Description"],
      ["input", {
        type: "text",
        name: "description",
        placeholder: "Enter a short description here",
      }],
      ["input$submit", {
        type: "submit",
        value: "Add Repo"
      }]
    ]
  ], $);
  function submit(evt) {
    evt.preventDefault();
    if (working) return;
    working = true;
    var url = this.url.value;
    var name = this.name.value;
    if (!name) {
      var index = url.lastIndexOf("/");
      name = url.substr(index + 1);
      if (/\.git$/.test(name)) {
        name = name.substr(0, name.length - 4);
      }
    }
    var description = this.description.value;
    return backend.add({
      name: name,
      url: url,
      description: description
    }, onRepo);

    function onRepo(err) {
      working = false;
      if (err) return ui.error(err);
      return ui.pop();
    }
  }
}

function historyList(repo, stream) {
  var $ = {}, ul, end, reading = false;
  var root = domBuilder(["section.page",
    ["header",
      ["button", {onclick:onclick(remove)}, [".icon-minus"]],
      ["button", {onclick:onclick(update)}, [".icon-download"]],
      ["button.back", {onclick: ui.pop}, [".icon-left-open"]],
      ["h1", repo.name]
    ],
    ["ul$ul.content.header",
      ["li$li", {css:{height: "100px"}}, "Loading..."]
    ]
  ], $);
  ul = $.ul;
  end = $.li;
  $ = {};
  ul.addEventListener('scroll', check, false);
  window.addEventListener('resize', check, false);
  setImmediate(function () {
    reading = true;
    stream.read(onRead);
  });
  return root;

  function remove() {
    ui.confirm("Are you sure you want to delete this local repo?", function (res) {
      if (!res) return;
      repo.remove(function (err) {
        if (err) return ui.error(err);
        ui.pop();
      });
    });
  }

  function update() {
    ui.error("TODO: Implement update");
  }

  function load(commit) {
    ui.push(commitPage(repo, commit));
  }

  function onRead(err, commit) {
    reading = false;
    if (err) return ui.error(err);
    if (commit === undefined) {
      ul.removeChild(end);
      end = null;
      ul.removeEventListener('scroll', check, false);
      window.removeEventListener('resize', check, false);
      return;
    }
    var title = truncate(commit.message, 80);
    var item = domBuilder(
      ["li", { href:"#", onclick: onclick(load, commit) },
        [".icon.right.icon-right-open", { title: commit.hash }],
        ["p", title],
        ["p", commit.author.date]
      ]
    );
    ul.insertBefore(item, end);
    check();
  }

  function check() {
    if (reading) return;
    if (end.offsetTop > ul.offsetHeight + ul.scrollTop) return;
    reading = true;
    stream.read(onRead);
  }

}

function commitPage(repo, commit) {
  var details = [];
  var body = ["section.page",
    ["header",
      ["button.back", {onclick: ui.pop}, [".icon-left-open"]],
      ["h1", repo.name]
    ],
    ["form.content.header", {onsubmit: prevent}, details]
  ];
  details.push(
    ["label", "Message"],
    ["p", {css:{whiteSpace:"pre-wrap"}}, commit.message]);
  details.push(
    ["label", "Tree"],
    ["button.recommend", {onclick: enter}, commit.tree]);
  if (commit.parents) {
    details.push(["label",
      "Parent" + (commit.parents.length === 1 ? "" : "s")
    ]);
    commit.parents.forEach(function (parent) {
      details.push(["button", {onclick: ascend(parent)}, parent]);
    });
  }
  details.push(
    ["label", "Author"],
    ["p", commit.author.name + " <" + commit.author.email + "> " + commit.author.date]);
  if (commit.author.email !== commit.committer.email) {
    details.push(
      ["label", "Committer"],
      ["p", commit.committer.name + " <" + commit.committer.email + "> " + commit.committer.date]);
  }
  details.push(
    ["label", "Hash"],
    ["button", {disabled:true}, commit.hash]);

  return domBuilder(body);

  function prevent(evt) {
    evt.preventDefault();
  }

  function enter() {
    repo.loadAs("tree", commit.tree, function (err, tree) {
      if (err) return ui.error(err);
      ui.push(filesList(repo, tree));
    });
  }

  function ascend(parent) {
    return function () {
      repo.loadAs("commit", parent, function (err, commit) {
        if (err) return ui.error(err);
        ui.peer(commitPage(repo, commit));
      });
    };
  }
}

function filesList(repo, tree) {
  return domBuilder(["section.page",
    ["header",
      ["button.back", {onclick: ui.pop}, [".icon-left-open"]],
      ["h1", repo.name]
    ],
    ["ul.content.header", tree.map(function (file) {
      var icon = ".icon.left.icon-";
      if (file.mode === 16384) {
        icon += "folder-empty";
      }
      else {
        icon += "doc";
      }

      return ["li", { href:"#", onclick: onclick(load, file) },
        [icon],
        (file.mode === 16384 ? [".icon.right.icon-right-open"] : []),
        ["p", file.name],
        ["p", file.hash]
      ];
    })]
  ]);
  function load(file) {
    if (file.mode === 16384) {
      return repo.loadAs("tree", file.hash, function (err, tree) {
        if (err) return ui.error(err);
        ui.push(filesList(repo, tree));
      });
    }
    console.log("TODO: load file");
  }
}

function truncate(message, limit) {
  var title = message.split(/[\r\n]/)[0];
  if (title.length > limit) title = title.substr(0, limit - 3) + "...";
  return title;
}

function onclick(handler) {
  var args = Array.prototype.slice.call(arguments, 1);
  return function (evt) {
    evt.preventDefault();
    evt.stopPropagation();
    return handler.apply(this, args);
  };
}

<commit_msg>Kill invalid repos<commit_after>var domBuilder = require('dombuilder');
var progressParser = require('../lib/progress-parser.js');
var ui = require('./ui.js');

module.exports = function (backend) {
  ui.push(repoList(backend));
};

function repoList(backend) {
  var $ = {};
  var pending;
  var children = {};
  backend.init(onAdd, onRemove, onReady);

  return domBuilder(["section.page$page", {"data-position": "none", css: {opacity: 0.5}},
    ["header",
      ["button", {onclick:onclick(add)}, [".icon-plus"]],
      ["h1", "Git Repositories"]
    ],
    ["ul.content.header$list"]
  ], $);

  function onAdd(repo) {
    var icon = ".icon.left.icon-";
    if (/github\.com/.test(repo.url)) {
      icon += "github";
    }
    else if (/bitbucket\.org/.test(repo.url)) {
      icon += "bitbucket";
    }
    else {
      icon += "git";
    }
    var $$ = {};
    var child = domBuilder(
      ["li$li", { href: "#", onclick: onclick(fetch, repo, icon, $$) },
        [icon],
        ["p", repo.name],
        ["p", repo.description],
        ["p.progress",
          ["progress$progress"], ["span$span", "Working..."]
        ],
      ], $$
    );
    children[repo.name] = child;
    $.list.appendChild(child);
    repo.remove = function (callback) {
      backend.remove(repo, callback);
    };
  }

  function onRemove(meta) {
    var child = children[meta.name];
    delete children[meta.name];
    $.list.removeChild(child);
  }

  function onReady(err) {
    if (err) return ui.error(err);
    $.page.style.opacity = 1;
  }

  function fetch(repo, icon, $$) {
    var progress = $$.progress;
    var span = $$.span;
    var child = $$.li;
    pending = repo;

    return repo.getHead(function (err, head) {
      if (err) return ui.error(err);
      if (!head) return clone();
      return onFetch();
    });

    function clone() {
      child.classList.add("active");
      repo.fetch(repo.remote, {
        onProgress: progressParser(function (message, num, max) {
          progress.setAttribute("max", max);
          progress.setAttribute("value", num);
          span.textContent = message;
        })
      }, onFetch);

    }

    function onFetch(err) {
      if (err) {
        return repo.remove(function () {
          return ui.error(err);
        });
      }
      var oldChild = child;
      child = domBuilder(
        ["li", { href:"#", onclick: onclick(load, repo) },
          [icon],
          [".icon.right.icon-right-open"],
          ["p", repo.name],
          ["p", repo.description]
        ]
      );
      children[repo.name] = child;
      $$ = null;
      $.list.replaceChild(child, oldChild);
      if (pending === repo) load(repo);
    }

  }

  function load(repo) {
    pending = null;
    repo.logWalk("HEAD", function (err, stream) {
      if (err) return ui.error(err);
      ui.push(historyList(repo, stream));
    });
  }

  function add() {
    ui.push(addPage(backend));
  }

}

function addPage(backend) {
  var $ = {};
  var working = false;
  return domBuilder(["section.page",
    ["header",
      ["button.back", {onclick: ui.pop}, [".icon-left-open"]],
      ["h1", "Add Repository"]
    ],
    ["form.content.header", {onsubmit: submit},
      ["label", {"for": "url"}, "Remote Url"],
      ["input", {
        type: "text",
        name: "url",
        placeholder: "Enter git url here",
        value: "git://github.com/creationix/conquest.git",
        required: true
      }],
      ["label", {"for": "name"}, "Name"],
      ["input", {
        type: "text",
        name: "name",
        placeholder: "Enter custom local name here",
      }],
      ["label", {"for": "description"}, "Description"],
      ["input", {
        type: "text",
        name: "description",
        placeholder: "Enter a short description here",
      }],
      ["input$submit", {
        type: "submit",
        value: "Add Repo"
      }]
    ]
  ], $);
  function submit(evt) {
    evt.preventDefault();
    if (working) return;
    working = true;
    var url = this.url.value;
    var name = this.name.value;
    if (!name) {
      var index = url.lastIndexOf("/");
      name = url.substr(index + 1);
      if (/\.git$/.test(name)) {
        name = name.substr(0, name.length - 4);
      }
    }
    var description = this.description.value;
    return backend.add({
      name: name,
      url: url,
      description: description
    }, onRepo);

    function onRepo(err) {
      working = false;
      if (err) return ui.error(err);
      return ui.pop();
    }
  }
}

function historyList(repo, stream) {
  var $ = {}, ul, end, reading = false;
  var root = domBuilder(["section.page",
    ["header",
      ["button", {onclick:onclick(remove)}, [".icon-minus"]],
      ["button", {onclick:onclick(update)}, [".icon-download"]],
      ["button.back", {onclick: ui.pop}, [".icon-left-open"]],
      ["h1", repo.name]
    ],
    ["ul$ul.content.header",
      ["li$li", {css:{height: "100px"}}, "Loading..."]
    ]
  ], $);
  ul = $.ul;
  end = $.li;
  $ = {};
  ul.addEventListener('scroll', check, false);
  window.addEventListener('resize', check, false);
  setImmediate(function () {
    reading = true;
    stream.read(onRead);
  });
  return root;

  function remove() {
    ui.confirm("Are you sure you want to delete this local repo?", function (res) {
      if (!res) return;
      repo.remove(function (err) {
        if (err) return ui.error(err);
        ui.pop();
      });
    });
  }

  function update() {
    ui.error("TODO: Implement update");
  }

  function load(commit) {
    ui.push(commitPage(repo, commit));
  }

  function onRead(err, commit) {
    reading = false;
    if (err) return ui.error(err);
    if (commit === undefined) {
      ul.removeChild(end);
      end = null;
      ul.removeEventListener('scroll', check, false);
      window.removeEventListener('resize', check, false);
      return;
    }
    var title = truncate(commit.message, 80);
    var item = domBuilder(
      ["li", { href:"#", onclick: onclick(load, commit) },
        [".icon.right.icon-right-open", { title: commit.hash }],
        ["p", title],
        ["p", commit.author.date]
      ]
    );
    ul.insertBefore(item, end);
    check();
  }

  function check() {
    if (reading) return;
    if (end.offsetTop > ul.offsetHeight + ul.scrollTop) return;
    reading = true;
    stream.read(onRead);
  }

}

function commitPage(repo, commit) {
  var details = [];
  var body = ["section.page",
    ["header",
      ["button.back", {onclick: ui.pop}, [".icon-left-open"]],
      ["h1", repo.name]
    ],
    ["form.content.header", {onsubmit: prevent}, details]
  ];
  details.push(
    ["label", "Message"],
    ["p", {css:{whiteSpace:"pre-wrap"}}, commit.message]);
  details.push(
    ["label", "Tree"],
    ["button.recommend", {onclick: enter}, commit.tree]);
  if (commit.parents) {
    details.push(["label",
      "Parent" + (commit.parents.length === 1 ? "" : "s")
    ]);
    commit.parents.forEach(function (parent) {
      details.push(["button", {onclick: ascend(parent)}, parent]);
    });
  }
  details.push(
    ["label", "Author"],
    ["p", commit.author.name + " <" + commit.author.email + "> " + commit.author.date]);
  if (commit.author.email !== commit.committer.email) {
    details.push(
      ["label", "Committer"],
      ["p", commit.committer.name + " <" + commit.committer.email + "> " + commit.committer.date]);
  }
  details.push(
    ["label", "Hash"],
    ["button", {disabled:true}, commit.hash]);

  return domBuilder(body);

  function prevent(evt) {
    evt.preventDefault();
  }

  function enter() {
    repo.loadAs("tree", commit.tree, function (err, tree) {
      if (err) return ui.error(err);
      ui.push(filesList(repo, tree));
    });
  }

  function ascend(parent) {
    return function () {
      repo.loadAs("commit", parent, function (err, commit) {
        if (err) return ui.error(err);
        ui.peer(commitPage(repo, commit));
      });
    };
  }
}

function filesList(repo, tree) {
  return domBuilder(["section.page",
    ["header",
      ["button.back", {onclick: ui.pop}, [".icon-left-open"]],
      ["h1", repo.name]
    ],
    ["ul.content.header", tree.map(function (file) {
      var icon = ".icon.left.icon-";
      if (file.mode === 16384) {
        icon += "folder-empty";
      }
      else {
        icon += "doc";
      }

      return ["li", { href:"#", onclick: onclick(load, file) },
        [icon],
        (file.mode === 16384 ? [".icon.right.icon-right-open"] : []),
        ["p", file.name],
        ["p", file.hash]
      ];
    })]
  ]);
  function load(file) {
    if (file.mode === 16384) {
      return repo.loadAs("tree", file.hash, function (err, tree) {
        if (err) return ui.error(err);
        ui.push(filesList(repo, tree));
      });
    }
    console.log("TODO: load file");
  }
}

function truncate(message, limit) {
  var title = message.split(/[\r\n]/)[0];
  if (title.length > limit) title = title.substr(0, limit - 3) + "...";
  return title;
}

function onclick(handler) {
  var args = Array.prototype.slice.call(arguments, 1);
  return function (evt) {
    evt.preventDefault();
    evt.stopPropagation();
    return handler.apply(this, args);
  };
}

<|endoftext|>