<commit_before>function afterMkdir(data) {
    if (data['success'].length > 0) {
        for (var i = 0, len = data['success'].length; i < len; i++) {
            var dir_name = data['success'][i]['name'];
            var dir_id = data['success'][i]['id'];
            var field = ""
                        + "Enter a description for folder \"" + dir_name + "\":"
                        + "(View folder)"
                        + "<input type='text' class='form-control' id='desc-" + dir_id + "'>";
            $('#descriptions .modal-body .form-group').append(field);
        }
        $('#descriptions input').focusout(function() {
            var this_id = $(this).attr('id').substr($(this).attr('id').indexOf("-") + 1)
            $.ajax({
                type: "POST",
                url: "/api/dir/describe/" + this_id,
                data: {
                    description: $('input[id="desc-' + this_id + '"]').val()
                }
            });
        });
        $('#descriptions').modal('show');
    }
}

// Create a new directory
function createDirectory() {
    $.ajax({
        type: "POST",
        url: "/api/mkdir",
        data: {
            dir_name: $('input[name="gallery_dir_name"]').val(),
            parent_id: $('input[name="gallery_dir_id"]').val()
        },
        success: afterMkdir
    });
}

function afterUpload(file, response) {
    console.log("Uploaded file:");
    console.log(file);
    console.log("Response:");
    console.log(response);
    if (response['success'].length > 0) {
        for (var i = 0, len = response['success'].length; i < len; i++) {
            var file_name = response['success'][i]['name'];
            var file_id = response['success'][i]['id'];
            var field = ""
                        + "'"
                        + "Enter a description for file \"" + file_name + "\": "
                        + "(View file)"
                        + "<input type='text' class='form-control' id='desc-" + file_id + "'>";
            $('#descriptions .modal-body .form-group').append(field);
        }
        $('#descriptions input').focusout(function() {
            var this_id = $(this).attr('id').substr($(this).attr('id').indexOf("-") + 1)
            $.ajax({
                type: "POST",
                url: "/api/file/describe/" + this_id,
                data: {
                    caption: $('input[id="desc-' + this_id + '"]').val()
                }
            });
        });
        $('#descriptions').modal('show');
    }
}

// Rebuild the directory tree
function populateDirTree() {
    $.get("/api/get_dir_tree", function(data) {
        $('#fileList').tree({
            data: [data],
            autoOpen: 0
        });
        $('#fileList').bind(
            'tree.click',
            function(event) {
                // The clicked node is 'event.node'
                var node = event.node;
                $('input[name="gallery_dir_id"]').val(node.id);
            }
        );
    });
}

function editFileDescription() {
    $('#edit-description').modal('show');
    $('#edit-description button').click(function() {
        var this_id = $('#edit-description input').attr('id').substr($('#edit-description input').attr('id').indexOf("-") + 1);
        $.ajax({
            type: "POST",
            url: "/api/file/describe/" + this_id,
            data: {
                caption: $('input[id="desc-' + this_id + '"]').val()
            }
        });
    });
}

function editDirDescription() {
    $('#edit-description').modal('show');
    $('#edit-description button').click(function() {
        var this_id = $('#edit-description input').attr('id').substr($('#edit-description input').attr('id').indexOf("-") + 1);
        $.ajax({
            type: "POST",
            url: "/api/dir/describe/" + this_id,
            data: {
                description: $('input[id="desc-' + this_id + '"]').val()
            }
        });
    });
}

function deleteDir() {
    $('#delete').modal('show');
    $('#delete button[id^="confirm"]').click(function(e) {
        e.preventDefault();
        var this_id = $('#delete button[id^="confirm"]').attr('id').substr($('#delete button[id^="confirm"]').attr('id').indexOf("-") + 1);
        $.post("/api/dir/delete/" + this_id);
        location.reload();
    });
}

function deleteFile() {
    $('#delete').modal('show');
    $('#delete button[id^="confirm"]').click(function(e) {
        e.preventDefault();
        var this_id = $('#delete button[id^="confirm"]').attr('id').substr($('#delete button[id^="confirm"]').attr('id').indexOf("-") + 1);
        $.post("/api/file/delete/<DIR_ID>" + this_id);
        location.reload();
    });
}
<commit_msg>Display thumbnail of uploaded file, not file itself<commit_after>function afterMkdir(data) {
    if (data['success'].length > 0) {
        for (var i = 0, len = data['success'].length; i < len; i++) {
            var dir_name = data['success'][i]['name'];
            var dir_id = data['success'][i]['id'];
            var field = ""
                        + "Enter a description for folder \"" + dir_name + "\":"
                        + "(View folder)"
                        + "<input type='text' class='form-control' id='desc-" + dir_id + "'>";
            $('#descriptions .modal-body .form-group').append(field);
        }
        $('#descriptions input').focusout(function() {
            var this_id = $(this).attr('id').substr($(this).attr('id').indexOf("-") + 1)
            $.ajax({
                type: "POST",
                url: "/api/dir/describe/" + this_id,
                data: {
                    description: $('input[id="desc-' + this_id + '"]').val()
                }
            });
        });
        $('#descriptions').modal('show');
    }
}

// Create a new directory
function createDirectory() {
    $.ajax({
        type: "POST",
        url: "/api/mkdir",
        data: {
            dir_name: $('input[name="gallery_dir_name"]').val(),
            parent_id: $('input[name="gallery_dir_id"]').val()
        },
        success: afterMkdir
    });
}

function afterUpload(file, response) {
    console.log("Uploaded file:");
    console.log(file);
    console.log("Response:");
    console.log(response);
    if (response['success'].length > 0) {
        for (var i = 0, len = response['success'].length; i < len; i++) {
            var file_name = response['success'][i]['name'];
            var file_id = response['success'][i]['id'];
            var field = ""
                        + "'"
                        + "Enter a description for file \"" + file_name + "\": "
                        + "(View file)"
                        + "<input type='text' class='form-control' id='desc-" + file_id + "'>";
            $('#descriptions .modal-body .form-group').append(field);
        }
        $('#descriptions input').focusout(function() {
            var this_id = $(this).attr('id').substr($(this).attr('id').indexOf("-") + 1)
            $.ajax({
                type: "POST",
                url: "/api/file/describe/" + this_id,
                data: {
                    caption: $('input[id="desc-' + this_id + '"]').val()
                }
            });
        });
        $('#descriptions').modal('show');
    }
}

// Rebuild the directory tree
function populateDirTree() {
    $.get("/api/get_dir_tree", function(data) {
        $('#fileList').tree({
            data: [data],
            autoOpen: 0
        });
        $('#fileList').bind(
            'tree.click',
            function(event) {
                // The clicked node is 'event.node'
                var node = event.node;
                $('input[name="gallery_dir_id"]').val(node.id);
            }
        );
    });
}

function editFileDescription() {
    $('#edit-description').modal('show');
    $('#edit-description button').click(function() {
        var this_id = $('#edit-description input').attr('id').substr($('#edit-description input').attr('id').indexOf("-") + 1);
        $.ajax({
            type: "POST",
            url: "/api/file/describe/" + this_id,
            data: {
                caption: $('input[id="desc-' + this_id + '"]').val()
            }
        });
    });
}

function editDirDescription() {
    $('#edit-description').modal('show');
    $('#edit-description button').click(function() {
        var this_id = $('#edit-description input').attr('id').substr($('#edit-description input').attr('id').indexOf("-") + 1);
        $.ajax({
            type: "POST",
            url: "/api/dir/describe/" + this_id,
            data: {
                description: $('input[id="desc-' + this_id + '"]').val()
            }
        });
    });
}

function deleteDir() {
    $('#delete').modal('show');
    $('#delete button[id^="confirm"]').click(function(e) {
        e.preventDefault();
        var this_id = $('#delete button[id^="confirm"]').attr('id').substr($('#delete button[id^="confirm"]').attr('id').indexOf("-") + 1);
        $.post("/api/dir/delete/" + this_id);
        location.reload();
    });
}

function deleteFile() {
    $('#delete').modal('show');
    $('#delete button[id^="confirm"]').click(function(e) {
        e.preventDefault();
        var this_id = $('#delete button[id^="confirm"]').attr('id').substr($('#delete button[id^="confirm"]').attr('id').indexOf("-") + 1);
        $.post("/api/file/delete/<DIR_ID>" + this_id);
        location.reload();
    });
}
<|endoftext|>


<commit_before>/**
 * This overrides existing contact code, and builds proper contacts
 * @constructor
 */

var Contact = function() {
  this.givenNames = [];
  this.familyName = "";
  this.phones = [];
  this.category = "";
  this.companyName = "";
  this.isCompany = false;
  this.email = [];
  this.addresses = [];
  this.uri = [];
  this.prefix = "";
  this.jobTitle = "";
  this.birthday = "";
  this.phoneticName = "";
}

var Address = function() {
  this.street = "";
  this.postalCode = "";
  this.city = "";
  this.region = "";
  this.countryCode = "";
  this.country = "";
  this.building = "";
  this.floor = "";
  this.accessCode = "";
}

var PhoneNumber = function() {
  this.number = "";
  this.type = "";
}

var Email = function() {
  this.address = "";
  this.type = "";
}

var ImHandle = function()
{
  this.address = "";
  this.type = "";
  this.network = "";
}

var Uri = function() {
  this.addr = "";
  this.rel = "";
}

var AddressBook = function() {
  this.name = "";
  this.resultSet = [];
}

AddressBook.prototype.addContact = function(newContact, win, fail)
{

}

AddressBook.prototype.removeContact = function(target, win, fail)
{

}

AddressBook.prototype.findContacts = function(filter,win, fail)
{
}

PhoneGap.addConstructor(function() {
  if (typeof navigator.AddressBook == "undefined")
    navigator.AddressBook = new AddressBook(); });
AddressBook.prototype.addContact = function(newContact, win, fail)
{

}

AddressBook.prototype.removeContact = function(target, win, fail)
{

}

AddressBook.prototype.findContacts = function(filter,win, fail)
{
  this.win = win;
  this.fail = fail;
  // Zero out the result set for the query
  this.resultSet = [];
  var name = "";
  var phone = "";
  var email = "";

  if (filter.givenName)
    name = filter.givenName;
  if (filter.familyName)
    name += filter.familyName;
  if (filter.phone)
    var phone = filter.phone;
  if (filter.email)
    var email = filter.email;
  ContactHook.search(name, phone, email);
}

AddressBook.prototype.droidFoundContact = function(name, npa, email)
{
  names = name.split(' ');
  personContact = new Contact();
  personContact.givenNames.push(names[0]);
  // This is technically wrong, but we can't distinguish right now
  if(names.length > 1)
  {
    personContact.familyName = name[name.length -1];
  }

  telNumber = new PhoneNumber();
  telNumber.number = npa;
  personContact.phones.push(telNumber);

  email_addr = new Email();
  email_addr.address = email;

  personContact.email.push(email_addr);

  this.resultSet.push(personContact);

}

AddressBook.prototype.droidDoneContacts = function()
{
  if(resultSet.length > 0)
    this.win(resultSet);
  else
    this.fail();
}
<commit_msg>Removing AddressBook<commit_after><|endoftext|>


<commit_before>
App = Ember.Application.create({
	ApplicationController: Ember.Controller.extend({
		routeChanged: function() {
			// Scroll top top of new page
			window.scrollTo(0, 0);

			//Initialise popovers for all elements that include the relevant attribute
			//Needs to be repeated each time the DOM changes
			Ember.run.scheduleOnce('afterRender', this, afterRender);
		}.observes('currentPath')
	})
});

App.Router.map(function() {
	this.resource('pre-login');
	this.resource('release-centre', { path: '/:releaseCentre_id' }, function() {
		this.resource('rule-sets', function() {
//			this.resource('rule-set', { path: '/:ruleSet_id' });
			this.resource('rule-set', { path: '/international-edition-only' });
		});
		this.resource('extension', { path: '/:extension_id' }, function() {
			this.resource('product', { path: '/:product_id' }, function() {
				this.resource('build', { path: '/:build_id' }, function() {
					this.resource('package', { path: '/:package_id' }, function() {
						this.resource('build-input');
						this.resource('pre-conditions');
						this.resource('post-conditions');
						this.resource('build-trigger');
					});
					this.resource('pre-execution');
					this.resource('build-history');
					this.resource('execution', function() {
						this.route('results');
						this.route('debug');
						this.route('output');
						this.route('publish');
					});
				});
			});
		});
	});
	this.resource('admin', function() {
		this.resource('create-release-centre');
	});
});

App.AbstractRoute = Ember.Route.extend({
	init: function() {
		App.set('lastKnownRoute', this);
	}
});

App.AuthorisedRoute = App.AbstractRoute.extend({
	beforeModel: function() {
		// Close any open modals
		if ($('.modal').size() > 0) this.send('closeModal');

		//Redirect user to login page if no authorisation token is stored.
		if (sessionStorage.authorisationToken === undefined){
//			this.transitionTo('pre-login');
		}
	}
});

App.ApplicationRoute = Ember.Route.extend({
	actions: {
		removeEntity: function(model) {
			console.log('removeEntity', model);
			this.send('openModal', 'remove-entity', model);
		},
		openModal: function(modalName, params) {
			console.log('openModal');
			var controller = this.controllerFor(modalName);
			var model = controller.getModel(params);
			controller.set('model', model);
			return this.render(modalName, {
				into: 'application',
				outlet: 'modal',
				controller: controller
			});
		},
		modalInserted: function() {
			var $modal = $('.modal');
			var route = this;
			$modal.on('hidden.bs.modal', function(e) {
				route.disconnectOutlet({
					outlet: 'modal',
					parentView: 'application'
				});
			})
			$modal.modal('show');
		},
		closeModal: function() {
			$('.modal').modal('hide');
		}
	}
});

//Pre-Login
App.PreLoginRoute = App.AbstractRoute.extend();

// Index
App.IndexRoute = App.AuthorisedRoute.extend({
	model: function() {
		return {
			releaseCentres: this.store.filter('centre', {}, function(centre) {
				return !centre.get('removed');
			})
		}
	},
	actions: {
		addProduct: function(extension) {
			this.send('openModal', 'create-product', extension);
		},
		addExtension: function(releaseCentre) {
			this.send('openModal', 'create-extension', releaseCentre);
		}
	}
})

// ReleaseCentre
App.ReleaseCentreRoute = App.AuthorisedRoute.extend({
	model: function(params) {
		return this.store.find('centre', params.releaseCentre_id);
	}
})
App.ReleaseCentreIndexRoute = App.AuthorisedRoute.extend({
	model: function() {
		return this.modelFor('release-centre');
	},
	actions: {
		addExtension: function(releaseCentre) {
			this.send('openModal', 'create-extension', releaseCentre);
		}
	}
})
App.CreateReleaseCentreView = Ember.View.extend({
	templateName: 'admin/create-release-centre',
	didInsertElement: function() {
		this.controller.send('modalInserted');
	}
})
App.CreateReleaseCentreController = Ember.ObjectController.extend({
	getModel: function() {
		return this.store.createRecord('centre');
	},
	actions: {
		submit: function() {
			var model = this.get('model');
			model.save();
			this.send('closeModal');
		}
	}
})

// Rule Set
App.RuleSetsRoute = App.AuthorisedRoute.extend({
	model: function() {
		return this.modelFor('release-centre');
	}
})
App.RuleSetsIndexRoute = App.AuthorisedRoute.extend({
	model: function() {
		return this.modelFor('rule-sets');
	}
})
App.RuleSetRoute = App.AuthorisedRoute.extend({
	model: function() {
		return this.modelFor('rule-sets');
	}
})

// Extension
App.ExtensionRoute = App.AuthorisedRoute.extend({
	model: function(params) {
		var centre = this.modelFor('release-centre');
		return centre.get('extensions').then(function(extensions) {
			var extension = extensions.findBy('id', params.extension_id);
			extension.set('parent', centre);
			return  extension;
		});
	}
})
App.ExtensionIndexRoute = App.AuthorisedRoute.extend({
	model: function() {
		return this.modelFor('extension');
	},
	actions: {
		addProduct: function(extension) {
			this.send('openModal', 'create-product', extension);
		}
	}
})
App.CreateExtensionView = Ember.View.extend({
	templateName: 'extension-maintenance',
	didInsertElement: function() {
		this.controller.send('modalInserted');
	}
})
App.CreateExtensionController = Ember.ObjectController.extend({
	getModel: function(releaseCentre) {
		var extension = this.store.createRecord('extension', {
			parent: releaseCentre
		});
		return  extension;
	},
	actions: {
		submit: function() {
			var extension = this.get('model');
			var releaseCentre = extension.get('parent');
			releaseCentre.get('extensions').pushObject(extension);
			extension.save();
			this.send('closeModal');
		}
	}
})

// Product
App.ProductRoute = App.AuthorisedRoute.extend({
	model: function(params) {
		var extension = this.modelFor('extension');
		return extension.get('products').then(function(products) {
			var product = products.findBy('id', params.product_id);
			product.set('parent', extension);
			return product;
		});
	}
})
App.ProductIndexRoute = App.AuthorisedRoute.extend({
	model: function() {
		return this.modelFor('product');
	},
	actions: {
		addBuild: function(product) {
			this.send('openModal', 'create-build', product);
		}
	}
})
App.ProductIndexController = Ember.ObjectController.extend({
	selectedBuild: function() {
		var controller = this;
		this.get('model.builds').then(function(builds) {
			var lastBuild = null;
			builds.forEach(function(build) {
				lastBuild = build;
			})
			controller.set('selectedBuild', lastBuild);
		});
	}.property('selectedBuild')
})
App.CreateProductView = Ember.View.extend({
	templateName: 'product-maintenance',
	didInsertElement: function() {
		this.controller.send('modalInserted');
	}
})
App.CreateProductController = Ember.ObjectController.extend({
	getModel: function(extension) {
		var product = this.store.createRecord('product', {
			parent: extension
		});
		return  product;
	},
	actions: {
		submit: function() {
			var product = this.get('model');
			var extension = product.get('parent');
			extension.get('products').pushObject(product);
			product.save();
			this.send('closeModal');
		}
	}
})

// Build
App.BuildIndexController = Ember.ObjectController.extend({
	actions: {
		initiateBuild: function (selectedBuild) {
			this.transitionToRoute('pre-execution', selectedBuild);
		},
		addPackage: function(build) {
			this.send('openModal', 'create-package', build);
		}
	}
})

App.BuildRoute = App.AuthorisedRoute.extend({
	model: function(params) {
		var product = this.modelFor('product');
		return product.get('builds').then(function(builds) {
			var build = builds.findBy('id', params.build_id);
			build.set('parent', product);
			return build;
		});
	}
})
App.CreateBuildView = Ember.View.extend({
	templateName: 'build-maintenance',
	didInsertElement: function() {
		this.controller.send('modalInserted');
	}
})
App.CreateBuildController = Ember.ObjectController.extend({
	getModel: function(product) {
		var build = this.store.createRecord('build', {
			parent: product
		});
		return  build;
	},
	actions: {
		submit: function() {
			var build = this.get('model');
			var product = build.get('parent');
			product.get('builds').pushObject(build);
			build.save();
			this.send('closeModal');
		}
	}
})

App.BuildIndexRoute = App.AuthorisedRoute.extend({
	model: function() {
		return this.modelFor('build');
	}
})

App.PreExecutionRoute = App.AuthorisedRoute.extend({
	model: function(params) {
		return this.modelFor('build');
	}
})
App.PreExecutionController = Ember.ObjectController.extend({
	actions: {
		runBuild: function (build) {
			var url = 'api/v1/builds/' + build.id + '/run'
			$.ajax({
				url: url,
				type: 'POST'
			})
		}
	}
});

// Package
App.PackageRoute = App.AuthorisedRoute.extend({
	model: function(params) {
		var build = this.modelFor('build');
		return build.get('packages').then(function(packages) {
			var thePackage = packages.findBy('id', params.package_id);
			thePackage.set('parent', build);
			return thePackage;
		});
	}
})
App.CreatePackageView = Ember.View.extend({
	templateName: 'package-maintenance',
	didInsertElement: function() {
		this.controller.send('modalInserted');
	}
})
App.CreatePackageController = Ember.ObjectController.extend({
	getModel: function(build) {
		var package = this.store.createRecord('package', {
			parent: build
		});
		return  package;
	},
	actions: {
		submit: function() {
			var package = this.get('model');
			var build = package.get('parent');
			build.get('packages').pushObject(package);
			package.save();
			this.send('closeModal');
		}
	}
})

App.BuildInputRoute = App.AuthorisedRoute.extend({
	model: function(params) {
		return this.modelFor('package');
	},
	setupController: function(controller, model) {
		controller.set('model', model);
		controller.set('inputfiles', model.get('inputfiles'));
	}
})
App.BuildInputController = Ember.ObjectController.extend({
	actions: {
		reload: function() {
			var inputfiles = this.get('inputfiles');
			inputfiles.reloadLinks();
		}
	}
})
App.PostConditionsRoute = App.AuthorisedRoute.extend({
	model: function(params) {
		return this.modelFor('package');
	}
})

App.ExecutionRoute = App.AuthorisedRoute.extend({
	model: function() {
		var build = this.modelFor('build');
		var pack = { name: '17 Feb, 2014 01:05:00 (UTC)', parent: build };
		return pack;
	}
})

App.ExecutionIndexRoute = App.AuthorisedRoute.extend({
	beforeModel: function() {
		this.transitionTo('execution.results');
	}
})

App.RemoveEntityView = Ember.View.extend({
	templateName: 'remove-entity',
	didInsertElement: function() {
		this.controller.send('modalInserted');
	}
})
App.RemoveEntityController = Ember.ObjectController.extend({
	getModel: function(entity) {
		return entity;
	},
	actions: {
		submit: function() {
			var model = this.get('model');
			model.set('removed', true);
			model.save();
			this.send('closeModal');
		}
	}
})

function signinCallback(authResult) {
	if (authResult['status']['signed_in']) {
		//Store the token in session storage.  Note we can't store against Ember
		//App or it will be lost on page reload.
		sessionStorage.authorisationToken = authResult['access_token'];

		//And return the user to whatever page there were on when they got booted here
		var currentRoute = App.get('lastKnownRoute');
		currentRoute.transitionTo('index');
	} else {
		debug('Sign-in state: ' + authResult['error']);
		sessionStorage.authorisationToken = "Athentication Failed in Client";
	}
}

function afterRender() {
	$("[data-toggle='popover']").popover();
	$("[data-toggle='tooltip']").tooltip();
	$("[data-toggle='dropdown']").dropdown();
	initBuildInputFileUploadForm();
}

function initBuildInputFileUploadForm() {
	var $button = $('.panel-build-input form .btn');
	$('.panel-build-input form').submit(function () {
		var $form = $(this);
		if ($form.valid()) {
			var actionPath = $('.actionpath', $form).text()
			var shortName = $('input[name="shortName"]', $form).val();
			var action = actionPath + shortName;
			console.log('Upload url = "' + action + '"');
			$form.attr('action', action);
			$button.val('Uploading...');
			$button.prop('disabled', true);
			return true;
		} else {
			return false;
		}
	});
	$('.panel-build-input #buildInputFileUploadIframe').load(function() {
		$button.val('Upload');
		$button.prop('disabled', false);
		$('.panel-build-input form')[0].reset();
		$('.panel-build-input .reloadmodel').click();
	});
	effectPulse($('.build-history .traffic-light-in-progress'));
}

function effectPulse($selection) {
	window.setInterval(function() {

	}, 1000)
	if ($selection && $selection.size() > 0) {
		$selection.animate({
			opacity: 0
		}, 500, function() {
			$selection.animate({
				opacity: 1
			}, 500, function() {
				effectPulse($selection);
			})
		})
	}
}
<commit_msg>Fix for traffic lights - afterRender was being called before API calls had completed.<commit_after>
App = Ember.Application.create({
	ApplicationController: Ember.Controller.extend({
		routeChanged: function() {
			// Scroll top top of new page
			window.scrollTo(0, 0);

			//Initialise popovers for all elements that include the relevant attribute
			//Needs to be repeated each time the DOM changes
			//Ember.run.scheduleOnce('afterRender', this, afterRender);
			Ember.run.later(window, afterRender, 1000);
		}.observes('currentPath')
	})
});

App.Router.map(function() {
	this.resource('pre-login');
	this.resource('release-centre', { path: '/:releaseCentre_id' }, function() {
		this.resource('rule-sets', function() {
//			this.resource('rule-set', { path: '/:ruleSet_id' });
			this.resource('rule-set', { path: '/international-edition-only' });
		});
		this.resource('extension', { path: '/:extension_id' }, function() {
			this.resource('product', { path: '/:product_id' }, function() {
				this.resource('build', { path: '/:build_id' }, function() {
					this.resource('package', { path: '/:package_id' }, function() {
						this.resource('build-input');
						this.resource('pre-conditions');
						this.resource('post-conditions');
						this.resource('build-trigger');
					});
					this.resource('pre-execution');
					this.resource('execution-history');
					this.resource('build-history');
					this.resource('execution', function() {
						this.route('results');
						this.route('debug');
						this.route('output');
						this.route('publish');
					});
				});
			});
		});
	});
	this.resource('admin', function() {
		this.resource('create-release-centre');
	});
});

App.AbstractRoute = Ember.Route.extend({
	init: function() {
		App.set('lastKnownRoute', this);
	}
});

App.AuthorisedRoute = App.AbstractRoute.extend({
	beforeModel: function() {
		// Close any open modals
		if ($('.modal').size() > 0) this.send('closeModal');

		//Redirect user to login page if no authorisation token is stored.
		if (sessionStorage.authorisationToken === undefined){
//			this.transitionTo('pre-login');
		}
	}
});

App.ApplicationRoute = Ember.Route.extend({
	actions: {
		removeEntity: function(model) {
			console.log('removeEntity', model);
			this.send('openModal', 'remove-entity', model);
		},
		openModal: function(modalName, params) {
			console.log('openModal');
			var controller = this.controllerFor(modalName);
			var model = controller.getModel(params);
			controller.set('model', model);
			return this.render(modalName, {
				into: 'application',
				outlet: 'modal',
				controller: controller
			});
		},
		modalInserted: function() {
			var $modal = $('.modal');
			var route = this;
			$modal.on('hidden.bs.modal', function(e) {
				route.disconnectOutlet({
					outlet: 'modal',
					parentView: 'application'
				});
			})
			$modal.modal('show');
		},
		closeModal: function() {
			$('.modal').modal('hide');
		}
	}
});

//Pre-Login
App.PreLoginRoute = App.AbstractRoute.extend();

// Index
App.IndexRoute = App.AuthorisedRoute.extend({
	model: function() {
		return {
			releaseCentres: this.store.filter('centre', {}, function(centre) {
				return !centre.get('removed');
			})
		}
	},
	actions: {
		addProduct: function(extension) {
			this.send('openModal', 'create-product', extension);
		},
		addExtension: function(releaseCentre) {
			this.send('openModal', 'create-extension', releaseCentre);
		}
	}
})

// ReleaseCentre
App.ReleaseCentreRoute = App.AuthorisedRoute.extend({
	model: function(params) {
		return this.store.find('centre', params.releaseCentre_id);
	}
})
App.ReleaseCentreIndexRoute = App.AuthorisedRoute.extend({
	model: function() {
		return this.modelFor('release-centre');
	},
	actions: {
		addExtension: function(releaseCentre) {
			this.send('openModal', 'create-extension', releaseCentre);
		}
	}
})
App.CreateReleaseCentreView = Ember.View.extend({
	templateName: 'admin/create-release-centre',
	didInsertElement: function() {
		this.controller.send('modalInserted');
	}
})
App.CreateReleaseCentreController = Ember.ObjectController.extend({
	getModel: function() {
		return this.store.createRecord('centre');
	},
	actions: {
		submit: function() {
			var model = this.get('model');
			model.save();
			this.send('closeModal');
		}
	}
})

// Rule Set
App.RuleSetsRoute = App.AuthorisedRoute.extend({
	model: function() {
		return this.modelFor('release-centre');
	}
})
App.RuleSetsIndexRoute = App.AuthorisedRoute.extend({
	model: function() {
		return this.modelFor('rule-sets');
	}
})
App.RuleSetRoute = App.AuthorisedRoute.extend({
	model: function() {
		return this.modelFor('rule-sets');
	}
})

// Extension
App.ExtensionRoute = App.AuthorisedRoute.extend({
	model: function(params) {
		var centre = this.modelFor('release-centre');
		return centre.get('extensions').then(function(extensions) {
			var extension = extensions.findBy('id', params.extension_id);
			extension.set('parent', centre);
			return  extension;
		});
	}
})
App.ExtensionIndexRoute = App.AuthorisedRoute.extend({
	model: function() {
		return this.modelFor('extension');
	},
	actions: {
		addProduct: function(extension) {
			this.send('openModal', 'create-product', extension);
		}
	}
})
App.CreateExtensionView = Ember.View.extend({
	templateName: 'extension-maintenance',
	didInsertElement: function() {
		this.controller.send('modalInserted');
	}
})
App.CreateExtensionController = Ember.ObjectController.extend({
	getModel: function(releaseCentre) {
		var extension = this.store.createRecord('extension', {
			parent: releaseCentre
		});
		return  extension;
	},
	actions: {
		submit: function() {
			var extension = this.get('model');
			var releaseCentre = extension.get('parent');
			releaseCentre.get('extensions').pushObject(extension);
			extension.save();
			this.send('closeModal');
		}
	}
})

// Product
App.ProductRoute = App.AuthorisedRoute.extend({
	model: function(params) {
		var extension = this.modelFor('extension');
		return extension.get('products').then(function(products) {
			var product = products.findBy('id', params.product_id);
			product.set('parent', extension);
			return product;
		});
	}
})
App.ProductIndexRoute = App.AuthorisedRoute.extend({
	model: function() {
		return this.modelFor('product');
	},
	actions: {
		addBuild: function(product) {
			this.send('openModal', 'create-build', product);
		}
	}
})
App.ProductIndexController = Ember.ObjectController.extend({
	selectedBuild: function() {
		var controller = this;
		this.get('model.builds').then(function(builds) {
			var lastBuild = null;
			builds.forEach(function(build) {
				lastBuild = build;
			})
			controller.set('selectedBuild', lastBuild);
		});
	}.property('selectedBuild')
})
App.CreateProductView = Ember.View.extend({
	templateName: 'product-maintenance',
	didInsertElement: function() {
		this.controller.send('modalInserted');
	}
})
App.CreateProductController = Ember.ObjectController.extend({
	getModel: function(extension) {
		var product = this.store.createRecord('product', {
			parent: extension
		});
		return  product;
	},
	actions: {
		submit: function() {
			var product = this.get('model');
			var extension = product.get('parent');
			extension.get('products').pushObject(product);
			product.save();
			this.send('closeModal');
		}
	}
})

// Build
App.BuildIndexController = Ember.ObjectController.extend({
	actions: {
		initiateBuild: function (selectedBuild) {
			this.transitionToRoute('pre-execution', selectedBuild);
		},
		addPackage: function(build) {
			this.send('openModal', 'create-package', build);
		}
	}
})

App.BuildRoute = App.AuthorisedRoute.extend({
	model: function(params) {
		var product = this.modelFor('product');
		return product.get('builds').then(function(builds) {
			var build = builds.findBy('id', params.build_id);
			build.set('parent', product);
			return build;
		});
	}
})
App.CreateBuildView = Ember.View.extend({
	templateName: 'build-maintenance',
	didInsertElement: function() {
		this.controller.send('modalInserted');
	}
})
App.CreateBuildController = Ember.ObjectController.extend({
	getModel: function(product) {
		var build = this.store.createRecord('build', {
			parent: product
		});
		return  build;
	},
	actions: {
		submit: function() {
			var build = this.get('model');
			var product = build.get('parent');
			product.get('builds').pushObject(build);
			build.save();
			this.send('closeModal');
		}
	}
})

App.BuildIndexRoute = App.AuthorisedRoute.extend({
	model: function() {
		return this.modelFor('build');
	}
})

App.PreExecutionRoute = App.AuthorisedRoute.extend({
	model: function(params) {
		return this.modelFor('build');
	}
})
App.PreExecutionController = Ember.ObjectController.extend({
	actions: {
		runBuild: function (build) {
			var url = 'api/v1/builds/' + build.id + '/run'
			$.ajax({
				url: url,
				type: 'POST'
			})
		}
	}
});

// Package
App.PackageRoute = App.AuthorisedRoute.extend({
	model: function(params) {
		var build = this.modelFor('build');
		return build.get('packages').then(function(packages) {
			var thePackage = packages.findBy('id', params.package_id);
			thePackage.set('parent', build);
			return thePackage;
		});
	}
})
App.CreatePackageView = Ember.View.extend({
	templateName: 'package-maintenance',
	didInsertElement: function() {
		this.controller.send('modalInserted');
	}
})
App.CreatePackageController = Ember.ObjectController.extend({
	getModel: function(build) {
		var package = this.store.createRecord('package', {
			parent: build
		});
		return  package;
	},
	actions: {
		submit: function() {
			var package = this.get('model');
			var build = package.get('parent');
			build.get('packages').pushObject(package);
			package.save();
			this.send('closeModal');
		}
	}
})

App.BuildInputRoute = App.AuthorisedRoute.extend({
	model: function(params) {
		return this.modelFor('package');
	},
	setupController: function(controller, model) {
		controller.set('model', model);
		controller.set('inputfiles', model.get('inputfiles'));
	}
})
App.BuildInputController = Ember.ObjectController.extend({
	actions: {
		reload: function() {
			var inputfiles = this.get('inputfiles');
			inputfiles.reloadLinks();
		}
	}
})
App.PostConditionsRoute = App.AuthorisedRoute.extend({
	model: function(params) {
		return this.modelFor('package');
	}
})

App.ExecutionRoute = App.AuthorisedRoute.extend({
	model: function() {
		var build = this.modelFor('build');
		var pack = { name: '17 Feb, 2014 01:05:00 (UTC)', parent: build };
		return pack;
	}
})

App.ExecutionIndexRoute = App.AuthorisedRoute.extend({
	beforeModel: function() {
		this.transitionTo('execution.results');
	}
})

App.RemoveEntityView = Ember.View.extend({
	templateName: 'remove-entity',
	didInsertElement: function() {
		this.controller.send('modalInserted');
	}
})
App.RemoveEntityController = Ember.ObjectController.extend({
	getModel: function(entity) {
		return entity;
	},
	actions: {
		submit: function() {
			var model = this.get('model');
			model.set('removed', true);
			model.save();
			this.send('closeModal');
		}
	}
})

function signinCallback(authResult) {
	if (authResult['status']['signed_in']) {
		//Store the token in session storage.  Note we can't store against Ember
		//App or it will be lost on page reload.
		sessionStorage.authorisationToken = authResult['access_token'];

		//And return the user to whatever page there were on when they got booted here
		var currentRoute = App.get('lastKnownRoute');
		currentRoute.transitionTo('index');
	} else {
		debug('Sign-in state: ' + authResult['error']);
		sessionStorage.authorisationToken = "Athentication Failed in Client";
	}
}

function afterRender() {
	//alert ("AfterRender");
	$("[data-toggle='popover']").popover();
	$("[data-toggle='tooltip']").tooltip();
	$("[data-toggle='dropdown']").dropdown();
	effectPulse($('.traffic-light-in-progress'));
	initBuildInputFileUploadForm();
}

function initBuildInputFileUploadForm() {
	var $button = $('.panel-build-input form .btn');
	$('.panel-build-input form').submit(function () {
		var $form = $(this);
		if ($form.valid()) {
			var actionPath = $('.actionpath', $form).text()
			var shortName = $('input[name="shortName"]', $form).val();
			var action = actionPath + shortName;
			console.log('Upload url = "' + action + '"');
			$form.attr('action', action);
			$button.val('Uploading...');
			$button.prop('disabled', true);
			return true;
		} else {
			return false;
		}
	});
	$('.panel-build-input #buildInputFileUploadIframe').load(function() {
		$button.val('Upload');
		$button.prop('disabled', false);
		$('.panel-build-input form')[0].reset();
		$('.panel-build-input .reloadmodel').click();
	});
}

function effectPulse($selection) {

	if ($selection && $selection.size() > 0) {
		$selection.stop();
		$selection.clearQueue();
		$selection.animate({
			opacity: 0
		}, 900, function() {
			$selection.animate({
				opacity: 1
			}, 900, function() {
				effectPulse($('.traffic-light-in-progress'));
			})
		})
	}
}
<|endoftext|>


<commit_before>/*
Copyright 2011, Carnegie Learning

    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
    You may obtain a copy of the License at

         http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.
*/

var cocos = require('cocos2d');
var geom = require('geometry');

var PNode = require('PerspectiveNode').PerspectiveNode;
var RC = require('RaceControl').RaceControl;
var MOT = require('ModifyOverTime').ModifyOverTime;

// Displays the dashboard on the right hand side
// TODO: Add speedometer, race progress, medal tracker, penalty time
var Dashboard = cocos.nodes.Node.extend({
    elapsedTime : -3,   // Time in race elapsed so far
    displayTime : null, // Timer displayed to player
    gaugeRadius : 40,   // Radius of the gauges
    penaltyTime : null, // Displayed penalty time
    pTime       : 0.0,  // Stores numerical penalty time
    speed       : 10,   // Speed for speedometer
    maxSpeed    : 200,  // Maximum possible speed to display/calculate
    init: function(maxSpeed) {
        Dashboard.superclass.init.call(this);

        this.set('maxSpeed', maxSpeed);

        // Create the visible timer
        var opts = Object();
        opts['string'] = '-3.0';
        var disp = cocos.nodes.Label.create(opts);
        disp.set('position', new geom.Point(50, 50));
        this.set('displayTime', disp)
        this.addChild({child: disp});

        // Create visible penalty timer
        opts['string'] = '0.0';
        disp = cocos.nodes.Label.create(opts);
        disp.set('position', new geom.Point(50, 100));
        this.addChild({child: disp});
        this.set('penaltyTime', disp);
    },

    // Starts tracking time and updating the dashboard timer
    start: function () {
        this.scheduleUpdate();
    },

    // Changes the current amount of penalty time accured
    modifyPenaltyTime: function(dt) {
        MOT.create(this.get('pTime'), dt, 1.0).bindTo('value', this, 'pTime');
    },

    // Converts numerical seconds to string, accurate to tenths of a second
    timerToString: function(t) {
        t = Math.round(t*10)
        if(t % 10 == 0) {
            t = t / 10.0 + ".0";
        }
        else {
            t /= 10;
        }

        return t;
    },

    // Updates the time
    update: function(dt) {
        // Update elapsed timer
        var t = this.get('elapsedTime') + dt;
        this.set('elapsedTime', t);

        var d = this.get('displayTime');
        d.set('string', this.timerToString(t));

        // Update penalty timer
        this.get('penaltyTime').set('string', this.timerToString(this.get('pTime')));
    },

    fillArc: function (c, x, y, r, s, e, b) {
        c.beginPath();
        s += Math.PI;
        c.arc(x, y, r, s, s + e, b);
        c.lineTo(x, y);
        c.closePath();
        c.fill();
    },

    // Draws the dash
    draw: function(context) {
        context.lineWidth = "4";
        context.fillStyle = "#8B7765";
        context.beginPath();
        context.moveTo(0,-10);
        context.lineTo(0,610);
        context.lineTo(110,610);
        context.lineTo(110,-10);
        context.closePath();
        context.fill();

        // Speedometer
        var r = this.get('gaugeRadius');

        context.strokeStyle = "#000000";
        context.beginPath();
        context.arc(50, 200, r, 0, Math.PI, true);
        context.lineTo(10, 200);
        context.closePath();
        context.stroke();

        context.fillStyle = '#11CC33';
        this.fillArc(context, 50, 200, r, 0,               Math.PI / 3, false);
        context.fillStyle = '#BBBB22';
        this.fillArc(context, 50, 200, r, Math.PI / 3,     Math.PI / 3, false);
        context.fillStyle = '#CC2222';
        this.fillArc(context, 50, 200, r, Math.PI / 3 * 2, Math.PI / 3, false);

        var s = this.get('speed');
        var maxs = this.get('maxSpeed');

        context.beginPath();
        context.moveTo(50, 200);
        context.lineTo(Math.sin(s*Math.PI/maxs - Math.PI/2)*r + 50, Math.cos(s*Math.PI/maxs - Math.PI/2)*-r + 200)
        context.closePath();
        context.stroke();

        // Medalmeter

        context.strokeStyle = "#000000";
        context.beginPath();
        context.arc(50, 300, r, 0, Math.PI, true);
        context.lineTo(10, 300);
        context.closePath();
        context.stroke();

        context.fillStyle = '#236B8E';
        this.fillArc(context, 50, 300, r, 0,               Math.PI / 4, false);
        context.fillStyle = '#A67D3D';
        this.fillArc(context, 50, 300, r, Math.PI / 4,     Math.PI / 4, false);
        context.fillStyle = '#C0C0C0';
        this.fillArc(context, 50, 300, r, Math.PI / 2,     Math.PI / 4, false);
        context.fillStyle = '#CC9900';
        this.fillArc(context, 50, 300, r, Math.PI / 4 * 3, Math.PI / 4, false);

        if(this.get('elapsedTime') > 0) {
            var p = this.pHelper(s);

            context.beginPath();
            context.moveTo(50, 300);
            context.lineTo(Math.sin(Math.PI*p - Math.PI/2)*r + 50, Math.cos(Math.PI*p - Math.PI/2)*-r + 300)
            context.closePath();
            context.stroke();

            var m = this.pHelper(maxs);

            context.fillStyle = 'rgba(0,0,0,0.4)';
            this.fillArc(context, 50, 300, r, Math.PI, -1 * Math.PI * (1 - m), true);
        }
    },

    pHelper: function (s) {
        // TODO: Add chaseDist back into this, otherwise calculation will be off by part of a meter
        var dc = PNode.cameraZ + 6;
        var dc = 0;
        var tc = this.get('elapsedTime') + this.get('pTime');

        var dr = RC.finishLine - dc;
        var tr = dr / s;
        var te = tr + tc;

        var p;

        for(var i=1; i<5; i+=1) {

            if(te < RC.times[i] || i==4) {
                p = 1 - (te - RC.times[i-1]) / (RC.times[i] - RC.times[i-1]);
                p = Math.min(Math.max(p, 0), 1);

                return p / 4 + (1 - 0.25 * i);
            }
        }
    },
});

exports.Dashboard = Dashboard<commit_msg>Dashboard now has configurable timer precision.  Only works up to 3 places right of the decimal.<commit_after>/*
Copyright 2011, Carnegie Learning

    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
    You may obtain a copy of the License at

         http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.
*/

var cocos = require('cocos2d');
var geom = require('geometry');

var PNode = require('PerspectiveNode').PerspectiveNode;
var RC = require('RaceControl').RaceControl;
var MOT = require('ModifyOverTime').ModifyOverTime;

// Displays the dashboard on the right hand side
// TODO: Add speedometer, race progress, medal tracker, penalty time
var Dashboard = cocos.nodes.Node.extend({
    elapsedTime : -3,   // Time in race elapsed so far
    displayTime : null, // Timer displayed to player
    gaugeRadius : 40,   // Radius of the gauges
    penaltyTime : null, // Displayed penalty time
    pTime       : 0.0,  // Stores numerical penalty time
    speed       : 10,   // Speed for speedometer
    maxSpeed    : 200,  // Maximum possible speed to display/calculate
    timerAcc    : 3,    // Number of digits to the right of the decimal place for timer accuracy
    init: function(maxSpeed) {
        Dashboard.superclass.init.call(this);

        this.set('maxSpeed', maxSpeed);

        // Create the visible timer
        var opts = Object();
        opts['string'] = '-3.0';
        var disp = cocos.nodes.Label.create(opts);
        disp.set('position', new geom.Point(40, 50));
        this.set('displayTime', disp)
        this.addChild({child: disp});

        // Create visible penalty timer
        opts['string'] = '0.0';
        disp = cocos.nodes.Label.create(opts);
        disp.set('position', new geom.Point(40, 100));
        this.addChild({child: disp});
        this.set('penaltyTime', disp);
    },

    // Starts tracking time and updating the dashboard timer
    start: function () {
        this.scheduleUpdate();
    },

    // Changes the current amount of penalty time accured
    modifyPenaltyTime: function(dt) {
        MOT.create(this.get('pTime'), dt, 1.0).bindTo('value', this, 'pTime');
    },

    // Updates the time
    update: function(dt) {
        // Update elapsed timer
        var t = this.get('elapsedTime') + dt;
        this.set('elapsedTime', t);

        var d = this.get('displayTime');
        d.set('string', t.toFixed(this.get('timerAcc')));

        // Update penalty timer
        this.get('penaltyTime').set('string', this.get('pTime').toFixed(this.get('timerAcc')));
    },

    fillArc: function (c, x, y, r, s, e, b) {
        c.beginPath();
        s += Math.PI;
        c.arc(x, y, r, s, s + e, b);
        c.lineTo(x, y);
        c.closePath();
        c.fill();
    },

    // Draws the dash
    draw: function(context) {
        context.lineWidth = "4";
        context.fillStyle = "#8B7765";
        context.beginPath();
        context.moveTo(0,-10);
        context.lineTo(0,610);
        context.lineTo(110,610);
        context.lineTo(110,-10);
        context.closePath();
        context.fill();

        // Speedometer
        var r = this.get('gaugeRadius');

        context.strokeStyle = "#000000";
        context.beginPath();
        context.arc(50, 200, r, 0, Math.PI, true);
        context.lineTo(10, 200);
        context.closePath();
        context.stroke();

        context.fillStyle = '#11CC33';
        this.fillArc(context, 50, 200, r, 0,               Math.PI / 3, false);
        context.fillStyle = '#BBBB22';
        this.fillArc(context, 50, 200, r, Math.PI / 3,     Math.PI / 3, false);
        context.fillStyle = '#CC2222';
        this.fillArc(context, 50, 200, r, Math.PI / 3 * 2, Math.PI / 3, false);

        var s = this.get('speed');
        var maxs = this.get('maxSpeed');

        context.beginPath();
        context.moveTo(50, 200);
        context.lineTo(Math.sin(s*Math.PI/maxs - Math.PI/2)*r + 50, Math.cos(s*Math.PI/maxs - Math.PI/2)*-r + 200)
        context.closePath();
        context.stroke();

        // Medalmeter

        context.strokeStyle = "#000000";
        context.beginPath();
        context.arc(50, 300, r, 0, Math.PI, true);
        context.lineTo(10, 300);
        context.closePath();
        context.stroke();

        context.fillStyle = '#236B8E';
        this.fillArc(context, 50, 300, r, 0,               Math.PI / 4, false);
        context.fillStyle = '#A67D3D';
        this.fillArc(context, 50, 300, r, Math.PI / 4,     Math.PI / 4, false);
        context.fillStyle = '#C0C0C0';
        this.fillArc(context, 50, 300, r, Math.PI / 2,     Math.PI / 4, false);
        context.fillStyle = '#CC9900';
        this.fillArc(context, 50, 300, r, Math.PI / 4 * 3, Math.PI / 4, false);

        if(this.get('elapsedTime') > 0) {
            var p = this.pHelper(s);

            context.beginPath();
            context.moveTo(50, 300);
            context.lineTo(Math.sin(Math.PI*p - Math.PI/2)*r + 50, Math.cos(Math.PI*p - Math.PI/2)*-r + 300)
            context.closePath();
            context.stroke();

            var m = this.pHelper(maxs);

            context.fillStyle = 'rgba(0,0,0,0.4)';
            this.fillArc(context, 50, 300, r, Math.PI, -1 * Math.PI * (1 - m), true);
        }
    },

    pHelper: function (s) {
        // TODO: Add chaseDist back into this, otherwise calculation will be off by part of a meter
        var dc = PNode.cameraZ + 6;
        var dc = 0;
        var tc = this.get('elapsedTime') + this.get('pTime');

        var dr = RC.finishLine - dc;
        var tr = dr / s;
        var te = tr + tc;

        var p;

        for(var i=1; i<5; i+=1) {

            if(te < RC.times[i] || i==4) {
                p = 1 - (te - RC.times[i-1]) / (RC.times[i] - RC.times[i-1]);
                p = Math.min(Math.max(p, 0), 1);

                return p / 4 + (1 - 0.25 * i);
            }
        }
    },
});

exports.Dashboard = Dashboard<|endoftext|>


<commit_before>(function(){

    angular.module('listModule', [])
        .component('myList', { // the tag for using this is <my-example>
            templateUrl: "../angular/templates/list-template.html",
            controller: listController
        });

    function listController(listService, $scope) {
        var self = this;

        // get object from service, create and store items in object.
        self.tabs = listService.tabs;
        self.currentTab = listService.currentTab;
        self.currentList = listService.currentList;

        self.addItem = addItem;
		self.removeItem = removeItem;
		self.editItem = editItem;

        $scope.$on('listUpdated', function () {
            self.currentList = listService.currentList;
            self.currentTab = listService.currentTab;
        });

        function addItem() {
            //generate item id
            var itemsLength = self.currentList.length;
            var chr = String.fromCharCode(97 + itemsLength);

            var itemID = self.currentTab + chr;

            //push to items
            var newItem = {
                'itemName':"New name",
                'itemId': itemID,
                'itemNotes': 'Add notes',
                'itemProgress':'0',
            };
            self.currentList.push(newItem);
            console.log(self.currentList);

        }
        function removeItem(iid) {
			console.log("remove item " + iid);
        }
        function editItem(iid) {
			console.log("edit item " + iid);
        }
        function updateItem() {

        }

    }

}());
<commit_msg>removing item from list<commit_after>(function(){

    angular.module('listModule', [])
        .component('myList', { // the tag for using this is <my-example>
            templateUrl: "../angular/templates/list-template.html",
            controller: listController
        });

    function listController(listService, $scope) {
        var self = this;

        // get object from service, create and store items in object.
        self.tabs = listService.tabs;
        self.currentTab = listService.currentTab;
        self.currentList = listService.currentList;

        self.addItem = addItem;
		self.removeItem = removeItem;
		self.editItem = editItem;

        $scope.$on('listUpdated', function () {
            self.currentList = listService.currentList;
            self.currentTab = listService.currentTab;
        });

        function addItem() {
            //generate item id
            var itemsLength = self.currentList.length;
            var chr = String.fromCharCode(97 + itemsLength);

            var itemID = self.currentTab + chr;

            //push to items
            var newItem = {
                'itemName':"New name",
                'itemId': itemID,
                'itemNotes': 'Add notes',
                'itemProgress':'0',
            };
            self.currentList.push(newItem);
            console.log(self.currentList);

        }
        function removeItem(iid) {
			self.currentList = $.grep(self.currentList, function(e){
                return e.iid != iid;
            });
			console.log("remove item " + iid);
        }
        function editItem(iid) {
			console.log("edit item " + iid);
        }
        function updateItem() {

        }

    }

}());
<|endoftext|>


<commit_before>$(function(){
    var sticky_navigation_offset_top = $('.subnav').offset().top;
    var sticky_navigation = function(){
        var scroll_top = $(window).scrollTop();
        if (scroll_top > sticky_navigation_offset_top) {
            $('.subnav').addClass('subnav-fixed');
        } else {
            $('.subnav').removeClass('subnav-fixed');
        }
    };

    sticky_navigation();
    $(window).scroll(function() {
        sticky_navigation();
    });

    $('.busca').focusin(function(){
        $(".busca").switchClass( "input-small", "input-big", 300 );
        return false;
    });

    $('.busca').focusout(function(){
        $(".busca").switchClass( "input-big", "input-small", 300 );
        return false;
    });

    $('a[href^="#"]').not('.carousel-control').bind('click.smoothscroll',function (e) {
        e.preventDefault();
        var target = this.hash,
        $target = $(target);
        $('html, body').stop().animate({
            'scrollTop': $target.offset().top
        }, 500, 'swing', function () {
            window.location.hash = target;
        });
    });

    $('.clipping').hide();
    $('.publicacoes').hide();

    $('.clip').click(function(){
        $('.equipe').hide();
        $('.publicacoes').hide();
        $('.clipping').fadeIn();
    });

    $('.membros').click(function(){
        $('.clipping').hide();
        $('.publicacoes').hide();
        $('.equipe').fadeIn();
    });

    $('.pub').click(function(){
        $('.clipping').hide();
        $('.equipe').hide();
        $('.publicacoes').fadeIn();
    });

    // $(".scroll").scrollable({ circular: true }).autoscroll({ autoplay: true }).click(function() {
    //     $(this).data("scrollable").next();
    // });

    option = {
        title: '@andrenano',
        content: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin lobortis ultricies nunc ac euismod. Class aptent taciti sociosqu ad volutpat.',
        trigger: 'hover',
        placement: 'right',
    };
    $('.tweets li').popover(option);

    $('#menu').scrollspy()

    $('.on').hide();
    // $('.logado').hide();

    $('.entrar').click(function(){
        $('.off').hide();
        $('.on').fadeIn();
    });

    // $('.form-inline').click(function(){
    //     $('.off').hide();
    //     $('.on').hide();
    //     $('.logado').fadeIn();
    // });

    auth.updateLoginWidget();

    //Executa esta funcionalida depois de 400ms por causa dos scripts dos vídeos se tiver na capa, pois
    //eles demoram um pouco para redimensionar o video, e se não estiver pronto, o masonry nao funciona direito.
    window.setTimeout(function() {
        var $container = $('.thumbnails');
        $container.imagesLoaded( function(){
            $container.masonry({
                itemSelector : '.thumbnails>li',
                columnWidth: function( containerWidth ) {
                    //console.log(containerWidth / 12);
                    return containerWidth / 12;
                }
            });
        });
    }, 1000);

    //Auth functions
    function handleBeforeSubmit(form) {
        $('span#loginmsg').fadeOut();
        return true;
    }

    handleSuccess = function(form, data) {
        var errors = data.msg.data;
        var code = data.code;
        var csrfToken = data.msg.csrf;

        /* It's everything ok, let's get out */
        $('span#loginmsg').html(data.msg);
        if (data.status === 'ok') {
            $('span#loginmsg').addClass('alert-success');
            auth.userAuthenticated(data.msg.user);
            $('span#loginmsg').fadeIn();
        } else {
            $('span#loginmsg').addClass('alert-error');
            $('span#loginmsg').fadeIn();
        }

        window.setTimeout(function(){
            $('span#loginmsg').fadeOut();
        },5000);
    }

    $('#frmLogin').ajaxForm({
        dataType: 'json',
        beforeSubmit: function () { handleBeforeSubmit($('#frmLogin')); },
        success: function (data) { handleSuccess($('#frmLogin'), data); }
    });

    $('#remember_password').ajaxForm({
        dataType: 'json',
        beforeSubmit: function () { handleBeforeSubmit($('#frmLogin')); },
        success: function (data) { handleSuccess($('#frmLogin'), data); }
    });

    $('span#loginmsg').hide();
    $('.passwordReminder').hide();
    $('#signupoverlay').hide();
    $('#tos').hide();

    auth.callback_login = function(action){
        //alert('callback:' + action);
        if( $('#iframevotacao') ){
            var ifr = $('#iframevotacao')[0];
            try{
                if(ifr.contentWindow && ifr.contentWindow.trata_botao_adicionar_ideia){
                    var pode = action == 'login';
                    ifr.contentWindow.trata_botao_adicionar_ideia(pode);
                }
            }catch(erro){ }
        }
    };

    document.domain = "localhost";

    _verifica_pode_adicionar_idea = function(){
        return auth.isAuthenticated();
    }

    _chama_tela_login = function(){
        alert('É necessário estar logado para poder contribuir.');
        scroll(0,0);
        auth.showLoginForm();
    }

});
<commit_msg>Adicionado controle do click do menu via atributo data-link<commit_after>$(function(){
    var sticky_navigation_offset_top = $('.subnav').offset().top;
    var sticky_navigation = function(){
        var scroll_top = $(window).scrollTop();
        if (scroll_top > sticky_navigation_offset_top) {
            $('.subnav').addClass('subnav-fixed');
        } else {
            $('.subnav').removeClass('subnav-fixed');
        }
    };

    sticky_navigation();
    $(window).scroll(function() {
        sticky_navigation();
    });

    $('.busca').focusin(function(){
        $(".busca").switchClass( "input-small", "input-big", 300 );
        return false;
    });

    $('.busca').focusout(function(){
        $(".busca").switchClass( "input-big", "input-small", 300 );
        return false;
    });

    $('a[href^="#"]').not('.carousel-control').bind('click.smoothscroll',function (e) {
        e.preventDefault();
        var target = this.hash,
        $target = $(target);
        $('html, body').stop().animate({
            'scrollTop': $target.offset().top
        }, 500, 'swing', function () {
            window.location.hash = target;
        });
    });

    $('.clipping').hide();
    $('.publicacoes').hide();

    $('.clip').click(function(){
        $('.equipe').hide();
        $('.publicacoes').hide();
        $('.clipping').fadeIn();
    });

    $('.membros').click(function(){
        $('.clipping').hide();
        $('.publicacoes').hide();
        $('.equipe').fadeIn();
    });

    $('.pub').click(function(){
        $('.clipping').hide();
        $('.equipe').hide();
        $('.publicacoes').fadeIn();
    });

    // $(".scroll").scrollable({ circular: true }).autoscroll({ autoplay: true }).click(function() {
    //     $(this).data("scrollable").next();
    // });

    option = {
        title: '@andrenano',
        content: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin lobortis ultricies nunc ac euismod. Class aptent taciti sociosqu ad volutpat.',
        trigger: 'hover',
        placement: 'right',
    };
    $('.tweets li').popover(option);

    $('#menu').scrollspy()

    $('.on').hide();
    // $('.logado').hide();

    $('.entrar').click(function(){
        $('.off').hide();
        $('.on').fadeIn();
    });

    // $('.form-inline').click(function(){
    //     $('.off').hide();
    //     $('.on').hide();
    //     $('.logado').fadeIn();
    // });

    auth.updateLoginWidget();

    //Executa esta funcionalida depois de 400ms por causa dos scripts dos vídeos se tiver na capa, pois
    //eles demoram um pouco para redimensionar o video, e se não estiver pronto, o masonry nao funciona direito.
    window.setTimeout(function() {
        var $container = $('.thumbnails');
        $container.imagesLoaded( function(){
            $container.masonry({
                itemSelector : '.thumbnails>li',
                columnWidth: function( containerWidth ) {
                    //console.log(containerWidth / 12);
                    return containerWidth / 12;
                }
            });
        });
    }, 1000);

    //Auth functions
    function handleBeforeSubmit(form) {
        $('span#loginmsg').fadeOut();
        return true;
    }

    handleSuccess = function(form, data) {
        var errors = data.msg.data;
        var code = data.code;
        var csrfToken = data.msg.csrf;

        /* It's everything ok, let's get out */
        $('span#loginmsg').html(data.msg);
        if (data.status === 'ok') {
            $('span#loginmsg').addClass('alert-success');
            auth.userAuthenticated(data.msg.user);
            $('span#loginmsg').fadeIn();
        } else {
            $('span#loginmsg').addClass('alert-error');
            $('span#loginmsg').fadeIn();
        }

        window.setTimeout(function(){
            $('span#loginmsg').fadeOut();
        },5000);
    }

    $('#frmLogin').ajaxForm({
        dataType: 'json',

        beforeSubmit: function () { handleBeforeSubmit($('#frmLogin')); },
        success: function (data) { handleSuccess($('#frmLogin'), data); }
    });

    $('#remember_password').ajaxForm({
        dataType: 'json',
        beforeSubmit: function () { handleBeforeSubmit($('#frmLogin')); },
        success: function (data) { handleSuccess($('#frmLogin'), data); }
    });

    $('span#loginmsg').hide();
    $('.passwordReminder').hide();
    $('#signupoverlay').hide();
    $('#tos').hide();

    auth.callback_login = function(action){
        //alert('callback:' + action);
        if( $('#iframevotacao') ){
            var ifr = $('#iframevotacao')[0];
            try{
                if(ifr.contentWindow && ifr.contentWindow.trata_botao_adicionar_ideia){
                    var pode = action == 'login';
                    ifr.contentWindow.trata_botao_adicionar_ideia(pode);
                }
            }catch(erro){ }
        }
    };

    document.domain = "localhost";

    _verifica_pode_adicionar_idea = function(){
        return auth.isAuthenticated();
    }

    _chama_tela_login = function(){
        alert('É necessário estar logado para poder contribuir.');
        scroll(0,0);
        auth.showLoginForm();
    }

    //Controle sinistro do menu! Utilizando o atributo data-link.
    $('a[data-link]').unbind("click").click(function(event){
        event.preventDefault();
        document.location = $(this).attr('data-link');
    });

});
<|endoftext|>


<commit_before>const StringUtil = require('../util/string-util');
const log = require('../util/log');

/**
 * Initialize a costume from an asset asynchronously.
 * Do not call this unless there is a renderer attached.
 * @param {!object} costume - the Scratch costume object.
 * @property {int} skinId - the ID of the costume's render skin, once installed.
 * @property {number} rotationCenterX - the X component of the costume's origin.
 * @property {number} rotationCenterY - the Y component of the costume's origin.
 * @property {number} [bitmapResolution] - the resolution scale for a bitmap costume.
 * @param {!Asset} costumeAsset - the asset of the costume loaded from storage.
 * @param {!Runtime} runtime - Scratch runtime, used to access the storage module.
 * @returns {?Promise} - a promise which will resolve after skinId is set, or null on error.
 */
const loadCostumeFromAsset = function (costume, costumeAsset, runtime) {
    costume.assetId = costumeAsset.assetId;
    if (!runtime.renderer) {
        log.error('No rendering module present; cannot load costume: ', costume.name);
        return costume;
    }
    const AssetType = runtime.storage.AssetType;
    const rotationCenter = [
        costume.rotationCenterX / costume.bitmapResolution,
        costume.rotationCenterY / costume.bitmapResolution
    ];
    if (costumeAsset.assetType === AssetType.ImageVector) {
        costume.skinId = runtime.renderer.createSVGSkin(costumeAsset.decodeText(), rotationCenter);
        costume.size = runtime.renderer.getSkinSize(costume.skinId);
        return costume;
    }

    return new Promise((resolve, reject) => {
        const imageElement = new Image();
        const onError = function () {
            // eslint-disable-next-line no-use-before-define
            removeEventListeners();
            reject();
        };
        const onLoad = function () {
            // eslint-disable-next-line no-use-before-define
            removeEventListeners();
            resolve(imageElement);
        };
        const removeEventListeners = function () {
            imageElement.removeEventListener('error', onError);
            imageElement.removeEventListener('load', onLoad);
        };
        imageElement.addEventListener('error', onError);
        imageElement.addEventListener('load', onLoad);
        imageElement.src = costumeAsset.encodeDataURI();
    }).then(imageElement => {
        costume.skinId = runtime.renderer.createBitmapSkin(imageElement, costume.bitmapResolution, rotationCenter);
        costume.size = runtime.renderer.getSkinSize(costume.skinId);
        return costume;
    });
};

/**
 * Load a costume's asset into memory asynchronously.
 * Do not call this unless there is a renderer attached.
 * @param {string} md5ext - the MD5 and extension of the costume to be loaded.
 * @param {!object} costume - the Scratch costume object.
 * @property {int} skinId - the ID of the costume's render skin, once installed.
 * @property {number} rotationCenterX - the X component of the costume's origin.
 * @property {number} rotationCenterY - the Y component of the costume's origin.
 * @property {number} [bitmapResolution] - the resolution scale for a bitmap costume.
 * @param {!Runtime} runtime - Scratch runtime, used to access the storage module.
 * @returns {?Promise} - a promise which will resolve after skinId is set, or null on error.
 */
const loadCostume = function (md5ext, costume, runtime) {
    if (!runtime.storage) {
        log.error('No storage module present; cannot load costume asset: ', md5ext);
        return Promise.resolve(costume);
    }

    const AssetType = runtime.storage.AssetType;
    const idParts = StringUtil.splitFirst(md5ext, '.');
    const md5 = idParts[0];
    const ext = idParts[1].toLowerCase();
    const assetType = (ext === 'svg') ? AssetType.ImageVector : AssetType.ImageBitmap;

    return runtime.storage.load(assetType, md5, ext).then(costumeAsset => {
        costume.dataFormat = ext;
        return loadCostumeFromAsset(costume, costumeAsset, runtime);
    });
};

module.exports = {
    loadCostume,
    loadCostumeFromAsset
};
<commit_msg>Correct what is being passed into scratch-render if some metadata (rotationCenter, bitmapResolution) is missing.<commit_after>const StringUtil = require('../util/string-util');
const log = require('../util/log');

/**
 * Initialize a costume from an asset asynchronously.
 * Do not call this unless there is a renderer attached.
 * @param {!object} costume - the Scratch costume object.
 * @property {int} skinId - the ID of the costume's render skin, once installed.
 * @property {number} rotationCenterX - the X component of the costume's origin.
 * @property {number} rotationCenterY - the Y component of the costume's origin.
 * @property {number} [bitmapResolution] - the resolution scale for a bitmap costume.
 * @param {!Asset} costumeAsset - the asset of the costume loaded from storage.
 * @param {!Runtime} runtime - Scratch runtime, used to access the storage module.
 * @returns {?Promise} - a promise which will resolve after skinId is set, or null on error.
 */
const loadCostumeFromAsset = function (costume, costumeAsset, runtime) {
    costume.assetId = costumeAsset.assetId;
    if (!runtime.renderer) {
        log.error('No rendering module present; cannot load costume: ', costume.name);
        return costume;
    }
    const AssetType = runtime.storage.AssetType;
    let rotationCenter;
    if (costume.rotationCenterX && costume.rotationCenterY && costume.bitmapResolution) {
        rotationCenter = [
            costume.rotationCenterX / costume.bitmapResolution,
            costume.rotationCenterY / costume.bitmapResolution
        ];
    }
    if (costumeAsset.assetType === AssetType.ImageVector) {
        // createSVGSkin does the right thing if rotationCenter isn't provided, so it's okay if it's
        // undefined here
        costume.skinId = runtime.renderer.createSVGSkin(costumeAsset.decodeText(), rotationCenter);
        costume.size = runtime.renderer.getSkinSize(costume.skinId);
        return costume;
    }

    return new Promise((resolve, reject) => {
        const imageElement = new Image();
        const onError = function () {
            // eslint-disable-next-line no-use-before-define
            removeEventListeners();
            reject();
        };
        const onLoad = function () {
            // eslint-disable-next-line no-use-before-define
            removeEventListeners();
            resolve(imageElement);
        };
        const removeEventListeners = function () {
            imageElement.removeEventListener('error', onError);
            imageElement.removeEventListener('load', onLoad);
        };
        imageElement.addEventListener('error', onError);
        imageElement.addEventListener('load', onLoad);
        imageElement.src = costumeAsset.encodeDataURI();
    }).then(imageElement => {
        // createBitmapSkin does the right thing if costume.bitmapResolution or rotationCenter are undefined...
        costume.skinId = runtime.renderer.createBitmapSkin(imageElement, costume.bitmapResolution, rotationCenter);
        costume.size = runtime.renderer.getSkinSize(costume.skinId);
        return costume;
    });
};

/**
 * Load a costume's asset into memory asynchronously.
 * Do not call this unless there is a renderer attached.
 * @param {string} md5ext - the MD5 and extension of the costume to be loaded.
 * @param {!object} costume - the Scratch costume object.
 * @property {int} skinId - the ID of the costume's render skin, once installed.
 * @property {number} rotationCenterX - the X component of the costume's origin.
 * @property {number} rotationCenterY - the Y component of the costume's origin.
 * @property {number} [bitmapResolution] - the resolution scale for a bitmap costume.
 * @param {!Runtime} runtime - Scratch runtime, used to access the storage module.
 * @returns {?Promise} - a promise which will resolve after skinId is set, or null on error.
 */
const loadCostume = function (md5ext, costume, runtime) {
    if (!runtime.storage) {
        log.error('No storage module present; cannot load costume asset: ', md5ext);
        return Promise.resolve(costume);
    }

    const AssetType = runtime.storage.AssetType;
    const idParts = StringUtil.splitFirst(md5ext, '.');
    const md5 = idParts[0];
    const ext = idParts[1].toLowerCase();
    const assetType = (ext === 'svg') ? AssetType.ImageVector : AssetType.ImageBitmap;

    return runtime.storage.load(assetType, md5, ext).then(costumeAsset => {
        costume.dataFormat = ext;
        return loadCostumeFromAsset(costume, costumeAsset, runtime);
    });
};

module.exports = {
    loadCostume,
    loadCostumeFromAsset
};
<|endoftext|>


<commit_before>Rooms = new Meteor.Collection('rooms');

Rooms.allow({
    update: Permissions.ownsDocument,
    remove: Permissions.ownsDocument
});

Rooms.deny({
    update: function(userId, room, fieldNames) {
        // may only edit the following fields:
        return (_.without(fieldNames, 'name', 'description', 'tags', 'guests', 'listed', 'public', 'scheduled', 'scheduledTime', 'chat').length > 0);
    }
});

Meteor.methods({
    roomInsert: function(room) {
        validateRoom(room);

        var user = Meteor.user();
        var room = _.extend(room, {
            creatorId: user._id,
            creatorEmail: user.emails[0].address,
            creatorName: user.username,
            submittedTime: new Date()
        });

        var roomId = Rooms.insert(room);

        return {
            _id: roomId
        };
    },
    roomUpdate: function(room) {

        var roomId = room._id;
        delete room._id;

        validateRoom(room);

        Rooms.update({
            _id: roomId
        }, {
            $set: room
        });

        return {
            _id: roomId
        };
    },
    roomAddFeeling: function(data) {
        data.feeling.rating = parseInt(data.feeling.rating, 10);
        var room = Rooms.findOne({
            _id: data.roomId
        });

        if (!room) {
            throw new Meteor.Error(422, 'Room does not exists');
        }

        if (Permissions.ownsDocument(Meteor.userId(), room)) {
            throw new Meteor.Error(422, 'The room owner is not allowed to rate the room');
        }

        var feelingFound = false;

        for (var i in room.feelings) {
            var feeling = room.feelings[i];
            if (feeling.user_id == Meteor.userId()) {
                feelingFound = true;
                break;
            }
        }

        if (feelingFound) {
            Rooms.update({
                _id: room._id,
                'feelings.user_id': Meteor.userId()
            }, {
                $set: {
                    'feelings.$.rating': data.feeling.rating,
                    'feelings.$.comment': data.feeling.comment
                }
            });
        } else {
            Rooms.update({
                _id: room._id
            }, {
                $push: {
                    'feelings': {
                        'user_id': Meteor.userId(),
                        'rating': data.feeling.rating,
                        'comment': data.feeling.comment
                    }
                }
            });
        }
    },
    searchExpert: function(topics) {
        // IA feature : Intelligent recomendation of an expert in a set of topics
        //OK..magic fingers

        for (var i in topics) {
            topics[i] = new RegExp('^' + topics[i] + '$', 'i');
        }

        var pipeline = [{
            $unwind: "$feelings"
        }, {
            $match: {
                tags: {
                    $in: topics
                }
            }
        }, {
            $project: {
                'creatorEmail': 1,
                'feelings': 1,
                'tags': 1,
                'visits': 1
            }
        }, {
            $group: {
                _id: {
                    presenter: "$creatorEmail"
                },
                avg_rating: {
                    $avg: "$feelings.rating"
                },
                cant_visits: {
                    $sum: "$visits"
                },
                all_tags: {
                    $addToSet: "$tags"
                }
            }
        }, {
            $sort: {
                cant_visits: -1,
                avg: -1
            }
        }, {
            $limit: 10
        }];
        var result = Rooms.aggregate(pipeline);

        //  math formula using visits, avg ranking, tags coincidence
        console.log(result);
        //return expert usermail, avg ranking & number of visits in rooms
    }
});

var validateRoom = function(room) {
    check(room, {
        name: String,
        description: String,
        tags: Array,
        guests: Array,
        listed: Boolean,
        public: Boolean,
        scheduled: Boolean,
        scheduledTime: Date,
        chat: Boolean
    });

    //Room Name cannot be empty
    if (!room.name) {
        throw new Meteor.Error(422, 'Please, fill in the room name');
    }

    //If Room is not Public then it has to have an Access Password
    if (!room.public && room.guests.length === 0) {
        throw new Meteor.Error(422, 'Please, provide guests for private room');
    }

    //If Room is not Scheduled then no need for a Time
    if (!room.scheduled) {
        room.scheduledTime = null;
    }
    //If the Room IS Scheduled for a Time, then it cannot be older than right now
    else if (compareDates(room.scheduledTime, new Date()) < 0) {
        throw new Meteor.Error(422, 'The scheduled date must be in the future!!!! Are you a time traveller?');
    }

    //Filter to only keep the valid emails from the guest list
    room.guests = filterEmails(room.guests);
};

/**
 * Compares two dates
 * @param {Date} d1 first date
 * @param {Date} d2 second date
 * @returns {integer} =0 if dates are equal, <0 if first date is earlier than second one
 */
var compareDates = function(d1, d2) {
    if (d1.getYear() != d2.getYear())
        return d1.getYear() - d2.getYear();
    if (d1.getMonth() != d2.getMonth())
        return d1.getMonth() - d2.getMonth();
    if (d1.getDate() != d2.getDate())
        return d1.getDate() - d2.getDate();
    if (d1.getHours() != d2.getHours())
        return d1.getHours() - d2.getHours();
    return d1.getMinutes() - d2.getMinutes()
};

/**
 * Removes invalid emails from an array of them
 * @param {String[]} emails
 * @returns {String[]} only valid emails
 */
var filterEmails = function(emails) {
    var validEmails = [];
    for (var i = 0; i < emails.length; i++) {
        if (isValidEmail(emails[i])) {
            validEmails.push(emails[i]);
        }
    }
    return validEmails;
};

/**
 * Checks if an email is valid
 * @param {String} email
 * @returns {Boolean} true if email format is valid, false otherwise
 */
isValidEmail = function(email) {
    var emailFilter = /^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/;
    return emailFilter.test(email);
};<commit_msg>Update room.js<commit_after>Rooms = new Meteor.Collection('rooms');

Rooms.allow({
    update: Permissions.ownsDocument,
    remove: Permissions.ownsDocument
});

Rooms.deny({
    update: function(userId, room, fieldNames) {
        // may only edit the following fields:
        return (_.without(fieldNames, 'name', 'description', 'tags', 'guests', 'listed', 'public', 'scheduled', 'scheduledTime', 'chat').length > 0);
    }
});

Meteor.methods({
    roomInsert: function(room) {
        validateRoom(room);

        var user = Meteor.user();
        var room = _.extend(room, {
            creatorId: user._id,
            creatorEmail: user.emails[0].address,
            creatorName: user.username,
            submittedTime: new Date()
        });

        var roomId = Rooms.insert(room);

        return {
            _id: roomId
        };
    },
    roomUpdate: function(room) {

        var roomId = room._id;
        delete room._id;

        validateRoom(room);

        Rooms.update({
            _id: roomId
        }, {
            $set: room
        });

        return {
            _id: roomId
        };
    },
    roomAddFeeling: function(data) {
        data.feeling.rating = parseInt(data.feeling.rating, 10);
        var room = Rooms.findOne({
            _id: data.roomId
        });

        if (!room) {
            throw new Meteor.Error(422, 'Room does not exists');
        }

        if (Permissions.ownsDocument(Meteor.userId(), room)) {
            throw new Meteor.Error(422, 'The room owner is not allowed to rate the room');
        }

        var feelingFound = false;

        for (var i in room.feelings) {
            var feeling = room.feelings[i];
            if (feeling.user_id == Meteor.userId()) {
                feelingFound = true;
                break;
            }
        }

        if (feelingFound) {
            Rooms.update({
                _id: room._id,
                'feelings.user_id': Meteor.userId()
            }, {
                $set: {
                    'feelings.$.rating': data.feeling.rating,
                    'feelings.$.comment': data.feeling.comment
                }
            });
        } else {
            Rooms.update({
                _id: room._id
            }, {
                $push: {
                    'feelings': {
                        'user_id': Meteor.userId(),
                        'rating': data.feeling.rating,
                        'comment': data.feeling.comment
                    }
                }
            });
        }
    },
    searchExpert: function(topics) {
        // IA feature : Intelligent recomendation of an expert in a set of topics
        //OK..magic fingers

        for (var i in topics) {
            topics[i] = new RegExp('^' + topics[i] + '$', 'i');
        }

        var pipeline = [{
            $unwind: "$feelings"
        }, {
            $match: {
                tags: {
                    $in: topics
                }
            }
        }, {
            $project: {
                'creatorEmail': 1,
                'feelings': 1,
                'tags': 1,
                'visits': 1
            }
        }, {
            $group: {
                _id: {
                    presenter: "$creatorEmail"
                },
                avg_rating: {
                    $avg: "$feelings.rating"
                },
                cant_visits: {
                    $sum: "$visits"
                },
                all_tags: {
                    $addToSet: "$tags"
                }
            }
        }, {
            $sort: {
                cant_visits: -1,
                avg: -1
            }
        }, {
            $limit: 10
        }];
        var experts = Rooms.aggregate(pipeline);

        for(var expert in experts){
            console.log(experts[expert]);
        }

        //  math formula using visits, avg ranking, tags coincidence
        console.log(experts);
        //return expert usermail, avg ranking & number of visits in rooms
    }
});

var validateRoom = function(room) {
    check(room, {
        name: String,
        description: String,
        tags: Array,
        guests: Array,
        listed: Boolean,
        public: Boolean,
        scheduled: Boolean,
        scheduledTime: Date,
        chat: Boolean
    });

    //Room Name cannot be empty
    if (!room.name) {
        throw new Meteor.Error(422, 'Please, fill in the room name');
    }

    //If Room is not Public then it has to have an Access Password
    if (!room.public && room.guests.length === 0) {
        throw new Meteor.Error(422, 'Please, provide guests for private room');
    }

    //If Room is not Scheduled then no need for a Time
    if (!room.scheduled) {
        room.scheduledTime = null;
    }
    //If the Room IS Scheduled for a Time, then it cannot be older than right now
    else if (compareDates(room.scheduledTime, new Date()) < 0) {
        throw new Meteor.Error(422, 'The scheduled date must be in the future!!!! Are you a time traveller?');
    }

    //Filter to only keep the valid emails from the guest list
    room.guests = filterEmails(room.guests);
};

/**
 * Compares two dates
 * @param {Date} d1 first date
 * @param {Date} d2 second date
 * @returns {integer} =0 if dates are equal, <0 if first date is earlier than second one
 */
var compareDates = function(d1, d2) {
    if (d1.getYear() != d2.getYear())
        return d1.getYear() - d2.getYear();
    if (d1.getMonth() != d2.getMonth())
        return d1.getMonth() - d2.getMonth();
    if (d1.getDate() != d2.getDate())
        return d1.getDate() - d2.getDate();
    if (d1.getHours() != d2.getHours())
        return d1.getHours() - d2.getHours();
    return d1.getMinutes() - d2.getMinutes()
};

/**
 * Removes invalid emails from an array of them
 * @param {String[]} emails
 * @returns {String[]} only valid emails
 */
var filterEmails = function(emails) {
    var validEmails = [];
    for (var i = 0; i < emails.length; i++) {
        if (isValidEmail(emails[i])) {
            validEmails.push(emails[i]);
        }
    }
    return validEmails;
};

/**
 * Checks if an email is valid
 * @param {String} email
 * @returns {Boolean} true if email format is valid, false otherwise
 */
isValidEmail = function(email) {
    var emailFilter = /^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/;
    return emailFilter.test(email);
};<|endoftext|>


<commit_before>var thesaurus = require('moby');
var pluralize = require('pluralize');

var saurus = module.exports;

saurus.maxSaurus = maxSaurus;

function maxSaurus(text, callback) {
    if(typeof text != "string" ) {
        console.error("Input isn't a string?");
    }
    else {
        var words = text.split(/-| /);
        var newText = "";
        for(i in words) {
            var processedWord = "";

            var word = words[i];
            var lowerWord = word.toLowerCase();
            var filteredWord = lowerWord.replace(/[^\w\s]|_/g,"");

            var synonyms = thesaurus.search(filteredWord);
            if (synonyms.length == 0) {
                console.error("No synonyms found for " + filteredWord);
                processedWord = word;
            }
            else {
                synonyms.sort(function(a, b) {
                    return b.length - a.length;
                });
                console.log(lowerWord.indexOf(filteredWord));
                processedWord = lowerWord.replace(filteredWord, synonyms[0]);
            }

            newText = newText + " " + processedWord;
        }
    }
    callback(newText);
}<commit_msg>repluralization<commit_after>var thesaurus = require('moby');
var pluralize = require('pluralize');

var saurus = module.exports;

saurus.maxSaurus = maxSaurus;

function maxSaurus(text, callback) {
    if(typeof text != "string" ) {
        console.error("Input isn't a string?");
    }
    else {
        var words = text.split(/-| /);
        var newText = "";
        for(i in words) {
            var processedWord = "";

            var plural = false;
            var word = words[i];
            var lowerWord = word.toLowerCase();
            var filteredWord = lowerWord.replace(/[^\w\s]|_/g,"");
            var finalWord = filteredWord;

            var singularWord = pluralize(filteredWord, 1);
            if(singularWord != filteredWord) {
                plural = true;
                finalWord = singularWord;
            }

            var synonyms = thesaurus.search(finalWord);
            if(synonyms.length == 0) {
                console.log("No synonyms found for " + finalWord);
                processedWord = word;
            }
            else {
                synonyms.sort(function(a, b) {
                    return b.length - a.length;
                });
                var count = 0;
                while(synonyms[count].indexOf(" ") > 0) {
                    count++;
                }
                var bestSynonym = synonyms[count];
                if(plural == true && bestSynonym.indexOf("-") < 0 && bestSynonym.slice(-1) != "s") {
                    console.log("pluralizing: " + bestSynonym);
                    bestSynonym = pluralize(bestSynonym);
                }
                console.log("Lower word: " + lowerWord + " Final word: " + finalWord + " bestSynonym: " + bestSynonym);
                processedWord = lowerWord.replace(filteredWord, bestSynonym);
            }

            newText = newText + " " + processedWord;
        }
    }
    callback(newText);
}<|endoftext|>


<commit_before>const mongoose = require('mongoose');
const Election = require('../../app/models/election');
const Alternative = require('../../app/models/alternative');
const helpers = require('../../test/helpers');
const server = require('../../server');
const createUsers = helpers.createUsers;
const clearCollections = helpers.clearCollections;
const dropDatabase = helpers.dropDatabase;

module.exports = function () {
  const activeElectionData = {
    title: 'activeElection1',
    description: 'active election 1',
    active: true,
  };

  const testAlternative = {
    description: 'test alternative',
  };
  const testAlternative2 = {
    description: 'another test alternative',
  };
  const testAlternative3 = {
    description: 'last test alternative',
  };

  const alternatives = [testAlternative, testAlternative2, testAlternative3];

  this.Before(async function () {
    await clearCollections();
    const election = await new Election(activeElectionData);
    this.election = election;
    this.alternatives = await Promise.all(
      alternatives.map((alternative) => new Alternative(alternative))
    );

    for (let i = 0; i < alternatives.length; i++) {
      await election.addAlternative(this.alternatives[i]);
    }

    await createUsers().spread((user, adminUser) => {
      this.user = user;
      this.adminUser = adminUser;
    });
  });

  this.registerHandler('BeforeFeatures', (event, callback) => {
    mongoose.connection.on('connected', () => server(callback));
  });

  this.registerHandler('AfterStep', (
    event,
    callback // To make sure all tests run correctly we force
  ) =>
    // waiting for Angular after each step.

    browser.waitForAngular().then(callback, (err) => {
      const message = err.message || err;
      if (message.includes('window.angular')) callback();
      else callback(err);
    })
  );

  this.registerHandler('AfterFeatures', (event, callback) => {
    dropDatabase(callback).nodeify(callback);
  });
};
<commit_msg>Fix E2E tests to support election type<commit_after>const mongoose = require('mongoose');
const Election = require('../../app/models/election');
const ElectionTypes = require('../../app/models/utils');
const Alternative = require('../../app/models/alternative');
const helpers = require('../../test/helpers');
const server = require('../../server');
const createUsers = helpers.createUsers;
const clearCollections = helpers.clearCollections;
const dropDatabase = helpers.dropDatabase;

module.exports = function () {
  const activeElectionData = {
    title: 'activeElection1',
    type: ElectionTypes.STV,
    description: 'active election 1',
    active: true,
  };

  const testAlternative = {
    description: 'test alternative',
  };
  const testAlternative2 = {
    description: 'another test alternative',
  };
  const testAlternative3 = {
    description: 'last test alternative',
  };

  const alternatives = [testAlternative, testAlternative2, testAlternative3];

  this.Before(async function () {
    await clearCollections();
    const election = await new Election(activeElectionData);
    this.election = election;
    this.alternatives = await Promise.all(
      alternatives.map((alternative) => new Alternative(alternative))
    );

    for (let i = 0; i < alternatives.length; i++) {
      await election.addAlternative(this.alternatives[i]);
    }

    await createUsers().spread((user, adminUser) => {
      this.user = user;
      this.adminUser = adminUser;
    });
  });

  this.registerHandler('BeforeFeatures', (event, callback) => {
    mongoose.connection.on('connected', () => server(callback));
  });

  this.registerHandler('AfterStep', (
    event,
    callback // To make sure all tests run correctly we force
  ) =>
    // waiting for Angular after each step.

    browser.waitForAngular().then(callback, (err) => {
      const message = err.message || err;
      if (message.includes('window.angular')) callback();
      else callback(err);
    })
  );

  this.registerHandler('AfterFeatures', (event, callback) => {
    dropDatabase(callback).nodeify(callback);
  });
};
<|endoftext|>


<commit_before>"use strict"

// A simulation of a game i' playing with my kids.

// There are 4 cows, sheeps, cats, and pigs each
const nAnimals = 12,

  // 5 portions of hay
  nHay = 5,

  //Roll a regular dice, return [1..n]
  roll = n => Math.floor(1 + Math.random() * n),

  // The cock will wake up all animals
  stepCock = state => {
    let c = Object.assign({}, state)
    c.awake = nAnimals
    return c
  },

  // Hay will reduce the number of hays by one
  stepHay = state => {
    let c = Object.assign({}, state)
    c.hay = c.hay - 1
    return c
  },

  // One animal falls asleep
  stepMoon = state => {
    let c = Object.assign({}, state)
    c.awake = c.awake - 1
    return c
  },

  // Return step function based on random dice
  stepFn = _ => [
      stepHay,
      stepCock,
      stepMoon, stepMoon, stepMoon, stepMoon
    ][roll(6) - 1],

  // The game is won if all animals are asleep
  isWon = state => state.awake == 0,

  // The game is lost if there is no more hay
  isLost = state => state.hay < 0,

  newGame = {
    // When starting, all animals are awake
    awake: nAnimals,

    // 5 portions of hay
    hay: 5
  },

  // Play one game, return true if won
  oneGame = _ => {
    let state = newGame
    while (true) {
      // A game step
      var fn = stepFn()
      // Apply step to context
      state = fn(state)
      if (isWon(state)) return true
      if (isLost(state)) return false
    }
  },

  total = 100000,
  games = Array.apply(null, Array(total)).map(oneGame),
  wins = games.filter(b => b).length

console.log(`Played ${total} games winning ${wins}`)

// EOF<commit_msg>refactor: Mostly comments<commit_after>"use strict"

// A simulation of a game i' playing with my kids.

// There are 4 cows, sheeps, cats, and pigs each
const nAnimals = 12,

  // 5 portions of hay
  nHay = 5,

  // Roll a regular dice, return [1..n]
  roll = n => Math.floor(1 + Math.random() * n),

  // The cock will wake up all animals
  // Immutable state
  stepCock = state => {
    let c = Object.assign({}, state)
    c.awake = nAnimals
    return c
  },

  // Hay will reduce the number of hays by one
  stepHay = state => {
    let c = Object.assign({}, state)
    c.hay = c.hay - 1
    return c
  },

  // One animal falls asleep
  stepMoon = state => {
    let c = Object.assign({}, state)
    c.awake = c.awake - 1
    return c
  },

  // Return step function based on random dice
  stepFn = _ => [
      stepHay,
      stepCock,
      stepMoon, stepMoon, stepMoon, stepMoon
    ][roll(6) - 1],

  // The game is won if all animals are asleep
  isWon = state => state.awake == 0,

  // The game is lost if there is no more hay
  isLost = state => state.hay < 0,

  newGame = {
    // When starting, all animals are awake
    awake: nAnimals,

    // A couple of hay portions
    hay: nHay
  },

  // Play one game, return true if won
  oneGame = _ => {
    let state = newGame
    while (true) {
      // A game step
      var fn = stepFn()
      // Apply step function state
      state = fn(state)
      if (isWon(state)) return true
      if (isLost(state)) return false
    }
  },

  total = 100000,
  games = Array.apply(null, Array(total)).map(oneGame),
  wins = games.filter(b => b).length

console.log(`Played ${total} games winning ${wins}`)

// EOF<|endoftext|>


<commit_before>import React from 'react';
import PropTypes from 'prop-types';

class Ad extends React.PureComponent {
  static propTypes = {
    style: PropTypes.object,
  };

  componentDidMount() {
    (window.adsbygoogle = window.adsbygoogle || []).push({});
  }

  render() {
    const { style, ...others } = this.props;

    const props = {};
    if (!others['data-ad-slot']) {
      // Default to responsive
      props['data-ad-slot'] = '5976455458';
      props['data-ad-format'] = 'auto';
      props['data-full-width-responsive'] = 'true';
    }

    return (
      <ins
        className="adsbygoogle"
        style={style ? { display: 'block', ...style } : { display: 'block' }}
        data-ad-client="ca-pub-8048055232081854"
        {...props}
        {...others}
      />
    );
  }
}

export default Ad;
<commit_msg>Fix crash caused by google adsense<commit_after>import React from 'react';
import PropTypes from 'prop-types';

class Ad extends React.PureComponent {
  static propTypes = {
    style: PropTypes.object,
  };

  componentDidMount() {
    try {
      (window.adsbygoogle = window.adsbygoogle || []).push({});
    } catch (err) {
      // "adsbygoogle.push() error: No slot size for availableWidth=0" error that I can't explain
      console.error(err);
    }
  }

  render() {
    const { style, ...others } = this.props;

    const props = {};
    if (!others['data-ad-slot']) {
      // Default to responsive
      props['data-ad-slot'] = '5976455458';
      props['data-ad-format'] = 'auto';
      props['data-full-width-responsive'] = 'true';
    }

    return (
      <ins
        className="adsbygoogle"
        style={style ? { display: 'block', ...style } : { display: 'block' }}
        data-ad-client="ca-pub-8048055232081854"
        {...props}
        {...others}
      />
    );
  }
}

export default Ad;
<|endoftext|>