<commit_before>var ServicoParser = function() {
	var xmlDoc;
	var returnObject = {};

	function parseNome(xmlDoc) {
		return $(xmlDoc).find('nome').html();
	}

	function parseArray(xmlDoc, selector) {
		var values = [];

		$(xmlDoc).find(selector).each(function(index, item) {
			values.push($(item).html());
		});

		return values;
	}

	function parseSigla(xmlDoc) {
		return $(xmlDoc).find('sigla').html();
	}

	function parseDescricao(xmlDoc) {
		return $(xmlDoc).find('descricao').html();
	}

	function parseNomesPopulares(xmlDoc) {
		return parseArray(xmlDoc, 'nomes-populares item');
	}

	function parseSegmentos(xmlDoc) {
		return parseArray(xmlDoc, 'segmentos-da-sociedade item');
	}

	function parsePalavrasChave(xmlDoc) {
		return parseArray(xmlDoc, 'palavras-chave item');
	}

	function parseLegislacoes(xmlDoc) {
		return parseArray(xmlDoc, 'legislacoes item');
	}

	function parseAreasDeInteresse(xmlDoc) {
		return parseArray(xmlDoc, 'areas-de-interesse item');
	}

	function parseSolicitantes(xmlDoc) {
		var solicitantes = [];

		$(xmlDoc).find('solicitantes solicitante').each(function(index, item) {
			solicitantes.push({tipo: $(item).find('tipo').html(), requisitos: $(item).find('requisitos').html()});
		});

		return solicitantes;
	}

	function parseTempoTotalEstimado(xmlDoc) {
		return { max: $(xmlDoc).find('tempo-total-estimado ate').attr('max'), unidade: $(xmlDoc).find('tempo-total-estimado ate').attr('unidade'), descricao: $(xmlDoc).find('tempo-total-estimado descricao').html() };
	}

	function parseGratuito(xmlDoc) {
		return $(xmlDoc).find('gratuito').html() !== 'false';
	}

	function parseEtapas(xmlDoc) {
		var etapas = [];

		$(xmlDoc).find('etapa').each(function(index, etapa) {
			etapas.push({'titulo': $(etapa).find('titulo').html(),
				'descricao': $(etapa).find('descricao').html(),
				'documentos': parseDocumentos(etapa),
				'custos': parseCustos(etapa),
				'canaisDePrestacao': parseCanaisDePrestacao(etapa)
			});
		});

		return etapas;
	}

	function parseDocumentos(etapa) {
		var documentos = {};
		documentos.items = [];
		documentos.casos = [];

		$(etapa).find('documentos default item').each(function(index, item) {
			documentos.items.push($(item).html());
		});

		$(etapa).find('documentos caso').each(function(index, caso) {
			var casoObj = { descricao: $(caso).attr('descricao'), items: [] };

			$(caso).find('item').each(function(index, item) {
				casoObj.items.push($(item).html());
			});

			documentos.casos.push(casoObj);
		});

		return documentos;
	}

	function parseCustos(etapa) {
		var custos = {};
		custos.items = [];
		custos.casos = [];

		$(etapa).find('custos default custo').each(function(index, item) {
			var custo = {descricao: $(item).find('descricao').html(), valor: $(item).find('valor').html() };
			custos.items.push(custo);
		});

		$(etapa).find('custos caso').each(function(index, caso) {
			var casoObj = { descricao: $(caso).attr('descricao'), items: [] };

			$(caso).find('custo').each(function(index, item) {
				var custoObj = {descricao: $(item).find('descricao').html(), valor: $(item).find('valor').html() };
				casoObj.items.push(custoObj);
			});

			custos.casos.push(casoObj);
		});

		return custos;
	}

	function parseCanaisDePrestacao(etapa) {
		var canaisDePrestacao = {};
		canaisDePrestacao.items = [];
		canaisDePrestacao.casos = [];

		$(etapa).find('canais-de-prestacao default canal-de-prestacao').each(function(index, item) {
			canaisDePrestacao.items.push({ 'tipo': $(item).attr('tipo'), 'descricao': $(item).find('descricao').html() });
		});

		$(etapa).find('canais-de-prestacao caso').each(function(index, caso) {
			var casoObj = { descricao: $(caso).attr('descricao'), items: [] };

			$(caso).find('canal-de-prestacao').each(function(index, item) {
				var canalDePrestacaoObj = {tipo: $(item).attr('tipo'), descricao: $(item).find('descricao').html() };
				casoObj.items.push(canalDePrestacaoObj);
			});

			canaisDePrestacao.casos.push(casoObj);
		});

		return canaisDePrestacao;
	}

	function parseOrgao(xmlDoc) {
		return { id: $(xmlDoc).find('orgao').attr('id'), contato: $(xmlDoc).find('orgao contato').html() };
	}

	function parseXml(data) {
		xmlDoc = $.parseXML(data);

	  	returnObject.nome = parseNome(xmlDoc);
	  	returnObject.descricao = parseDescricao(xmlDoc);
	  	returnObject.sigla = parseSigla(xmlDoc);
	  	returnObject.gratuito = parseGratuito(xmlDoc);
	  	returnObject.nomesPopulares = parseNomesPopulares(xmlDoc);
	  	returnObject.segmentos = parseSegmentos(xmlDoc);
	  	returnObject.palavrasChave = parsePalavrasChave(xmlDoc);
	  	returnObject.solicitantes = parseSolicitantes(xmlDoc);
	  	returnObject.areasDeInteresse = parseAreasDeInteresse(xmlDoc);
		returnObject.canaisDePrestacao = parseCanaisDePrestacao(xmlDoc);
		returnObject.tempoTotalEstimado = parseTempoTotalEstimado(xmlDoc);
		returnObject.legislacoes = parseLegislacoes(xmlDoc);
		returnObject.etapas = parseEtapas(xmlDoc);
		returnObject.orgao = parseOrgao(xmlDoc);

		return returnObject;
	}

	return {
		parseXml: parseXml,
		parseNome: parseNome,
		parseDescricao: parseDescricao,
		parseSigla: parseSigla,
		parseGratuito: parseGratuito,
		parseNomesPopulares: parseNomesPopulares,
		parseSegmentos: parseSegmentos,
		parsePalavrasChave: parsePalavrasChave,
		parseSolicitantes: parseSolicitantes,
		parseAreasDeInteresse: parseAreasDeInteresse,
		parseCanaisDePrestacao: parseCanaisDePrestacao,
		parseTempoTotalEstimado: parseTempoTotalEstimado,
		parseLegislacoes: parseLegislacoes,
		parseEtapas: parseEtapas,
		parseOrgao: parseOrgao
	};
};
<commit_msg>Refatorado servicoParser<commit_after>function ServicoParser() {
}

ServicoParser.prototype.parseNome = function (xmlDoc) {
	return $(xmlDoc).find('nome').html();
};

ServicoParser.prototype.parseArray = function (xmlDoc, selector) {
	var values = [];

	$(xmlDoc).find(selector).each(function(index, item) {
		values.push($(item).html());
	});

	return values;
};

ServicoParser.prototype.parseSigla = function (xmlDoc) {
	return $(xmlDoc).find('sigla').html();
};

ServicoParser.prototype.parseDescricao = function (xmlDoc) {
	return $(xmlDoc).find('descricao').html();
};

ServicoParser.prototype.parseNomesPopulares = function (xmlDoc) {
	return this.parseArray(xmlDoc, 'nomes-populares item');
};

ServicoParser.prototype.parseSegmentos = function (xmlDoc) {
	return this.parseArray(xmlDoc, 'segmentos-da-sociedade item');
};

ServicoParser.prototype.parsePalavrasChave = function (xmlDoc) {
	return this.parseArray(xmlDoc, 'palavras-chave item');
};

ServicoParser.prototype.parseLegislacoes = function (xmlDoc) {
	return this.parseArray(xmlDoc, 'legislacoes item');
};

ServicoParser.prototype.parseAreasDeInteresse = function (xmlDoc) {
	return this.parseArray(xmlDoc, 'areas-de-interesse item');
};

ServicoParser.prototype.parseSolicitantes = function (xmlDoc) {
	var solicitantes = [];

	$(xmlDoc).find('solicitantes solicitante').each(function(index, item) {
		solicitantes.push({
			tipo: $(item).find('tipo').html(),
			requisitos: $(item).find('requisitos').html()
		});
	});

	return solicitantes;
};

ServicoParser.prototype.parseTempoTotalEstimado = function (xmlDoc) {
	return {
		max: $(xmlDoc).find('tempo-total-estimado ate').attr('max'),
		unidade: $(xmlDoc).find('tempo-total-estimado ate').attr('unidade'),
		descricao: $(xmlDoc).find('tempo-total-estimado descricao').html()
	};
};

ServicoParser.prototype.parseGratuito = function (xmlDoc) {
	return $(xmlDoc).find('gratuito').html() !== 'false';
};

ServicoParser.prototype.parseDocumentos = function (etapa) {
	var documentos = {};
	documentos.items = [];
	documentos.casos = [];

	$(etapa).find('documentos default item').each(function(index, item) {
		documentos.items.push($(item).html());
	});

	$(etapa).find('documentos caso').each(function(index, caso) {
		var casoObj = { descricao: $(caso).attr('descricao'), items: [] };

		$(caso).find('item').each(function(index, item) {
			casoObj.items.push($(item).html());
		});

		documentos.casos.push(casoObj);
	});

	return documentos;
};

ServicoParser.prototype.parseEtapas = function (xmlDoc) {
	var etapas = [],
		parser = this;

	$(xmlDoc).find('etapa').each(function(index, etapa) {
		etapas.push({
			titulo: $(etapa).find('titulo').html(),
			descricao: $(etapa).find('descricao').html(),
			documentos: parser.parseDocumentos(etapa),
			custos: parser.parseCustos(etapa),
			canaisDePrestacao: parser.parseCanaisDePrestacao(etapa)
		});
	});

	return etapas;
};

ServicoParser.prototype.parseCustos = function (etapa) {
	var custos = {};
	custos.items = [];
	custos.casos = [];

	$(etapa).find('custos default custo').each(function(index, item) {
		var custo = {
			descricao: $(item).find('descricao').html(),
			valor: $(item).find('valor').html()
		};
		custos.items.push(custo);
	});

	$(etapa).find('custos caso').each(function(index, caso) {
		var casoObj = { descricao: $(caso).attr('descricao'), items: [] };

		$(caso).find('custo').each(function(index, item) {
			var custoObj = {
				descricao: $(item).find('descricao').html(),
				valor: $(item).find('valor').html()
			};
			casoObj.items.push(custoObj);
		});

		custos.casos.push(casoObj);
	});

	return custos;
};

ServicoParser.prototype.parseCanaisDePrestacao = function (etapa) {
	var canaisDePrestacao = {};
	canaisDePrestacao.items = [];
	canaisDePrestacao.casos = [];

	$(etapa).find('canais-de-prestacao default canal-de-prestacao').each(function(index, item) {
		canaisDePrestacao.items.push({
			tipo: $(item).attr('tipo'),
			descricao: $(item).find('descricao').html()
		});
	});

	$(etapa).find('canais-de-prestacao caso').each(function(index, caso) {
		var casoObj = { descricao: $(caso).attr('descricao'), items: [] };

		$(caso).find('canal-de-prestacao').each(function(index, item) {
			var canalDePrestacaoObj = {
				tipo: $(item).attr('tipo'),
				descricao: $(item).find('descricao').html()
			};
			casoObj.items.push(canalDePrestacaoObj);
		});

		canaisDePrestacao.casos.push(casoObj);
	});

	return canaisDePrestacao;
};

ServicoParser.prototype.parseOrgao = function (xmlDoc) {
	return {
		id: $(xmlDoc).find('orgao').attr('id'),
		contato: $(xmlDoc).find('orgao contato').html()
	};
};

ServicoParser.prototype.parseXml = function (data) {
	var xmlDoc = $.parseXML(data),
		servico = {
	  		nome: this.parseNome(xmlDoc),
	  		descricao: this.parseDescricao(xmlDoc),
		  	sigla: this.parseSigla(xmlDoc),
		  	gratuito: this.parseGratuito(xmlDoc),
		  	nomesPopulares: this.parseNomesPopulares(xmlDoc),
		  	segmentos: this.parseSegmentos(xmlDoc),
		  	palavrasChave: this.parsePalavrasChave(xmlDoc),
		  	solicitantes: this.parseSolicitantes(xmlDoc),
		  	areasDeInteresse: this.parseAreasDeInteresse(xmlDoc),
			canaisDePrestacao: this.parseCanaisDePrestacao(xmlDoc),
			tempoTotalEstimado: this.parseTempoTotalEstimado(xmlDoc),
			legislacoes: this.parseLegislacoes(xmlDoc),
			etapas: this.parseEtapas(xmlDoc),
			orgao: this.parseOrgao(xmlDoc)
		};

	return servico;
};
<|endoftext|>


<commit_before>var _ = require('underscore')._;

var commands = function(dbot) {
    var polls = dbot.db.polls;
    var commands = {
        '~newpoll': function(event) {
            var name = event.input[1],
                options = event.input[2].split(','),
                description = event.input[3];

            if(_.has(polls, name)) {
                event.reply(dbot.t('poll_exists', { 'name': name }));
            } else {
                polls[name] = {
                    'name': name,
                    'description': description,
                    'owner': event.user,
                    'votes': {},
                    'votees': {}
                };
                for(var i=0;i<options.length;i++) {
                    polls[name]['votes'][options[i]] = 0;
                }
                event.reply(dbot.t('poll_created', {
                    'name': name,
                    'description': description,
                    'url': dbot.t('url', {
                        'host': dbot.config.web.webHost,
                        'port': dbot.config.web.webPort,
                        'path': 'polls/' + name
                    })
                }));
            }
        },

        '~addoption': function(event) {
            var name = event.input[1],
                option = event.input[2];

            if(_.has(polls, name)) {
                if(polls[name].owner === event.user) {
                    if(!_.has(polls[name].votes, option)) {
                        polls[name]['votes'][option] = 0;
                        event.reply(dbot.t('option_added', {
                            'user': event.user,
                            'name': name,
                            'option': option
                        }));
                    } else {
                        event.reply(dbot.t('option_exists', {
                            'option': option,
                            'name': name,
                            'user': event.user
                        }));
                    }
                } else {
                    event.reply(dbot.t('not_poll_owner', {
                        'user': event.user,
                        'name': name
                    }));
                }
            } else {
                event.reply(dbot.t('poll_unexistent', {'name': name}));
            }
        },

        '~rmoption': function(event) {
            var name = event.input[1],
                option = event.input[2];

            if(_.has(polls, name)) {
                if(polls[name].owner === event.user) {
                    if(_.has(polls[name].votes, option)) {
                        delete polls[name]['votes'][option];
                        event.reply(dbot.t('option_removed', {
                            'user': event.user,
                            'name': name,
                            'option': option
                        }));
                    } else {
                        event.reply(dbot.t('invalid_vote', { 'vote': option }));
                    }
                } else {
                    event.reply(dbot.t('not_poll_owner', { 'name': name }));
                }
            } else {
                event.reply(dbot.t('poll_unexistent', { 'name': name }));
            }
        },

        '~vote': function(event) {
            var name = event.input[1],
                vote = event.input[2];

            if(_.has(polls, name)) {
                if(_.has(polls[name].votes, vote)) {
                    if(_.has(polls[name].votees, event.user)) {
                        var oldVote = polls[name].votees[event.user];
                        polls[name].votes[oldVote]--;
                        polls[name].votes[vote]++;
                        polls[name].votees[event.user] = vote;

                        event.reply(dbot.t('changed_vote', {
                            'vote': vote,
                            'poll': name,
                            'count': polls[name].votes[vote],
                            'user': event.user
                        }));
                    } else {
                        polls[name].votes[vote]++;
                        polls[name].votees[event.user] = vote;
                        event.reply(dbot.t('voted', {
                            'vote': vote,
                            'poll': name,
                            'count': polls[name].votes[vote],
                            'user': event.user
                        }));
                    }
                } else {
                    event.reply(dbot.t('invalid_vote', { 'vote': vote }));
                }
            } else {
                event.reply(dbot.t('poll_unexistent', { 'name': name }));
            }
        },

        '~pdesc': function(event) {
            var name = event.input[1];

            if(_.has(polls, name)) {
                event.reply(dbot.t('poll_describe', {
                    'name': name,
                    'description': polls[name].description,
                    'url': dbot.t('url', {
                        'host': dbot.config.web.webHost,
                        'port': dbot.config.web.webPort,
                        'path': 'polls/' + name
                    })
                }));
            } else {
                event.reply(dbot.t('poll_unexistent', { 'name': name }));
            }
        },

        '~count': function(event) {
            var name = event.input[1];

            if(_.has(polls, name)) {
                var order;
                var votesArr = [];

                var order = _.chain(polls[name].votes)
                    .pairs()
                    .sortBy(function(option) { return option[1] })
                    .reverse()
                    .value();

                var orderString = "";
                for(var i=0;i<order.length;i++) {
                    orderString += order[i][0] +
                        " (" + order[i][1] + "), ";
                }
                orderString = orderString.slice(0, -2);

                event.reply(dbot.t('count', {
                    'poll': name,
                    'description': polls[name].description,
                    'places': orderString
                }));
            } else {
                event.reply(dbot.t('poll_unexistent', {'name': name}));
            }
        }
    };
    commands['~newpoll'].regex = [/~newpoll ([^ ]+) options=([^ ]+) (.+)/, 4];
    commands['~addoption'].regex = [/~addoption ([^ ]+) ([^ ]+)/, 3];
    commands['~rmoption'].regex = [/~rmoption ([^ ]+) ([^ ]+)/, 3];
    commands['~vote'].regex = [/~vote ([^ ]+) ([^ ]+)/, 3];
    commands['~pdesc'].regex = [/~pdesc ([^ ]+)/, 2];
    commands['~count'].regex = [/~count ([^ ]+)/, 2];

    return commands;
};

exports.fetch = function(dbot) {
    return commands(dbot);
}
<commit_msg>polls case insensitive [#155]<commit_after>var _ = require('underscore')._;

var commands = function(dbot) {
    var polls = dbot.db.polls;
    var commands = {
        '~newpoll': function(event) {
            var name = event.input[1].toLowerCase(),
                options = event.input[2].toLowerCase().split(','),
                description = event.input[3];

            if(_.has(polls, name)) {
                event.reply(dbot.t('poll_exists', { 'name': name }));
            } else {
                polls[name] = {
                    'name': name,
                    'description': description,
                    'owner': event.user,
                    'votes': {},
                    'votees': {}
                };
                for(var i=0;i<options.length;i++) {
                    polls[name]['votes'][options[i]] = 0;
                }
                event.reply(dbot.t('poll_created', {
                    'name': name,
                    'description': description,
                    'url': dbot.t('url', {
                        'host': dbot.config.web.webHost,
                        'port': dbot.config.web.webPort,
                        'path': 'polls/' + name
                    })
                }));
            }
        },

        '~addoption': function(event) {
            var name = event.input[1].toLowerCase(),
                option = event.input[2].toLowerCase();

            if(_.has(polls, name)) {
                if(polls[name].owner === event.user) {
                    if(!_.has(polls[name].votes, option)) {
                        polls[name]['votes'][option] = 0;
                        event.reply(dbot.t('option_added', {
                            'user': event.user,
                            'name': name,
                            'option': option
                        }));
                    } else {
                        event.reply(dbot.t('option_exists', {
                            'option': option,
                            'name': name,
                            'user': event.user
                        }));
                    }
                } else {
                    event.reply(dbot.t('not_poll_owner', {
                        'user': event.user,
                        'name': name
                    }));
                }
            } else {
                event.reply(dbot.t('poll_unexistent', {'name': name}));
            }
        },

        '~rmoption': function(event) {
            var name = event.input[1].toLowerCase(),
                option = event.input[2].toLowerCase();

            if(_.has(polls, name)) {
                if(polls[name].owner === event.user) {
                    if(_.has(polls[name].votes, option)) {
                        delete polls[name]['votes'][option];
                        event.reply(dbot.t('option_removed', {
                            'user': event.user,
                            'name': name,
                            'option': option
                        }));
                    } else {
                        event.reply(dbot.t('invalid_vote', { 'vote': option }));
                    }
                } else {
                    event.reply(dbot.t('not_poll_owner', { 'name': name }));
                }
            } else {
                event.reply(dbot.t('poll_unexistent', { 'name': name }));
            }
        },

        '~vote': function(event) {
            var name = event.input[1].toLowerCase(),
                vote = event.input[2].toLowerCase();

            if(_.has(polls, name)) {
                if(_.has(polls[name].votes, vote)) {
                    if(_.has(polls[name].votees, event.user)) {
                        var oldVote = polls[name].votees[event.user];
                        polls[name].votes[oldVote]--;
                        polls[name].votes[vote]++;
                        polls[name].votees[event.user] = vote;

                        event.reply(dbot.t('changed_vote', {
                            'vote': vote,
                            'poll': name,
                            'count': polls[name].votes[vote],
                            'user': event.user
                        }));
                    } else {
                        polls[name].votes[vote]++;
                        polls[name].votees[event.user] = vote;
                        event.reply(dbot.t('voted', {
                            'vote': vote,
                            'poll': name,
                            'count': polls[name].votes[vote],
                            'user': event.user
                        }));
                    }
                } else {
                    event.reply(dbot.t('invalid_vote', { 'vote': vote }));
                }
            } else {
                event.reply(dbot.t('poll_unexistent', { 'name': name }));
            }
        },

        '~pdesc': function(event) {
            var name = event.input[1].toLowerCase();

            if(_.has(polls, name)) {
                event.reply(dbot.t('poll_describe', {
                    'name': name,
                    'description': polls[name].description,
                    'url': dbot.t('url', {
                        'host': dbot.config.web.webHost,
                        'port': dbot.config.web.webPort,
                        'path': 'polls/' + name
                    })
                }));
            } else {
                event.reply(dbot.t('poll_unexistent', { 'name': name }));
            }
        },

        '~count': function(event) {
            var name = event.input[1].toLowerCase();

            if(_.has(polls, name)) {
                var order;
                var votesArr = [];

                var order = _.chain(polls[name].votes)
                    .pairs()
                    .sortBy(function(option) { return option[1] })
                    .reverse()
                    .value();

                var orderString = "";
                for(var i=0;i<order.length;i++) {
                    orderString += order[i][0] +
                        " (" + order[i][1] + "), ";
                }
                orderString = orderString.slice(0, -2);

                event.reply(dbot.t('count', {
                    'poll': name,
                    'description': polls[name].description,
                    'places': orderString
                }));
            } else {
                event.reply(dbot.t('poll_unexistent', {'name': name}));
            }
        }
    };
    commands['~newpoll'].regex = [/~newpoll ([^ ]+) options=([^ ]+) (.+)/, 4];
    commands['~addoption'].regex = [/~addoption ([^ ]+) ([^ ]+)/, 3];
    commands['~rmoption'].regex = [/~rmoption ([^ ]+) ([^ ]+)/, 3];
    commands['~vote'].regex = [/~vote ([^ ]+) ([^ ]+)/, 3];
    commands['~pdesc'].regex = [/~pdesc ([^ ]+)/, 2];
    commands['~count'].regex = [/~count ([^ ]+)/, 2];

    return commands;
};

exports.fetch = function(dbot) {
    return commands(dbot);
}
<|endoftext|>


<commit_before>/* global sails, User, Group, Document, Authorship, Citation, ScopusCitation, DocumentOrigins, SourceTypes, DocumentTypes, SourceType */
"use strict";

const _ = require('lodash');
const citation_year_count = 6;
const mainInstituteId = 1;

module.exports = {
    getUserPerformance,
    getUsersPerformance,
    getGroupInstitutePerformance,
    getGroupsInstitutePerformance,
    getUserInstitutePerformance,
    getUsersInstitutePerformance,
    getUserMBOInvitedTalks,
    getUsersMBOInvitedTalks,
    getGroupMBOInvitedTalks,
    getGroupsMBOInvitedTalks
};

async function getUserPerformance(user, year) {
    const y = parseInt(year) || (new Date()).getFullYear();
    const performance = await getResearchEntityPerformance(user.documents, y);
    return formatPerformance({
            email: user.username,
            lastname: user.surname,
            name: user.name
        },
        performance);
}

async function getUsersPerformance(year) {
    return await calculateForAll(User, getUserPerformance, year);
}

async function getGroupInstitutePerformance(group, year) {
    const y = parseInt(year) || (new Date()).getFullYear();
    const docs = group.documents.filter(d => parseInt(d.year, 10) === y || parseInt(d.year, 10) === y + 1);
    const documents = await Document.find({id: docs.map(d => d.id)}).populate('sourceMetrics');
    const performance = await getResearchEntityInstitutePerformance(documents, y);
    return formatInstitutePerformance({
            cdr: group.cdr,
            line: group.name
        },
        performance
    );
}

async function getGroupsInstitutePerformance(year) {
    return await calculateForAll(Group, getGroupInstitutePerformance, year);
}

async function getUserInstitutePerformance(user, year) {
    const y = parseInt(year) || (new Date()).getFullYear();
    const docs = user.documents.filter(d => parseInt(d.year, 10) === y || parseInt(d.year, 10) === y + 1);
    const authorships = await Authorship.find({document: docs.map(d => d.id)}).populate('affiliations');
    const documentIds = authorships.filter(
        a => a.affiliations.map(af => af.id)
            .includes(mainInstituteId))
        .map(a => a.document);
    const documents = await Document.find({id: _.uniq(documentIds)})
        .populate('sourceMetrics');
    const performance = await getResearchEntityInstitutePerformance(documents, y);
    return formatInstitutePerformance({
            email: user.username,
            lastname: user.surname,
            name: user.name
        },
        performance);
}

async function getUsersInstitutePerformance(year) {
    return await calculateForAll(User, getUserInstitutePerformance, year);
}

async function getUserMBOInvitedTalks(user, year) {
    const y = parseInt(year) || (new Date()).getFullYear();
    const res = await getResearchEntityMBOInvitedTalks(user.documents, y);

    return Object.assign({}, {
        email: user.username,
        lastname: user.surname,
        name: user.name,
        year: y
    }, res);
}

async function getUsersMBOInvitedTalks(year) {
    return await calculateForAll(User, getUserMBOInvitedTalks, year);
}

async function getGroupMBOInvitedTalks(group, year) {
    const y = parseInt(year) || (new Date()).getFullYear();
    const res = await getResearchEntityMBOInvitedTalks(group.documents, y);

    return Object.assign({}, {
        cdr: group.cdr,
        line: group.name,
        year: y
    }, res);
}

async function getGroupsMBOInvitedTalks(year) {
    return await calculateForAll(Group, getGroupMBOInvitedTalks, year);
}

async function getResearchEntityMBOInvitedTalks(docs, year) {
    function formatIT(doc) {
        return doc.authorsStr + ' ' + doc.title + ' ' + doc.itSource;
    }
    const invitedTalks = docs.filter(d => parseInt(d.year, 10) === year && d.type === DocumentTypes.INVITED_TALK);

    const sourceTypes = await SourceType.find({type: 'invited_talk'});
    const scientificSourceTypes = sourceTypes.filter(st => st.section === 'Scientific Event').map(st => st.key);
    const disseminationSourceTypes = sourceTypes.filter(st => st.section === 'Dissemination').map(st => st.key);

    return {
        scientific: invitedTalks.filter(d => scientificSourceTypes.includes(d.sourceType)).map(formatIT),
        dissemination: invitedTalks.filter(d => disseminationSourceTypes.includes(d.sourceType)).map(formatIT)
    };

}

async function getResearchEntityPerformance(docs, year) {
    const documents = docs.filter(d => d.year <= year);
    const scopusCitations = await getScopusCitations(documents, year);
    const citations = getCitationTotals(scopusCitations);
    const hIndex = calculateHIndex(citations);
    const totalCitations = citations.reduce((total, c) => total + c, 0);

    const years = _.range(citation_year_count, 0).map(i => i + parseInt(year, 10) - citation_year_count);
    const citationsPerYear = (await getCitationPerYear(scopusCitations, years));

    const source_date = await Citation.findOne({origin: DocumentOrigins.SCOPUS}).sort('updatedAt DESC');
    return {
        hindex: hIndex,
        total_citations: totalCitations,
        citations_years: citationsPerYear,
        source_date: source_date
    };
}

async function getResearchEntityInstitutePerformance(documents, year) {
    const excludedDocumentTypes = [
        DocumentTypes.ERRATUM,
        DocumentTypes.POSTER,
        DocumentTypes.PHD_THESIS,
        DocumentTypes.REPORT,
        DocumentTypes.INVITED_TALK,
        DocumentTypes.ABSTRACT_REPORT
    ];
    const docs = documents.filter(d => !excludedDocumentTypes.includes(d.type));
    const docsCurrentYear = docs.filter(d => parseInt(d.year, 10) === year);
    const docsNextYear = docs.filter(d => parseInt(d.year, 10) === (year + 1));

    const papersStr = {
        total: docsCurrentYear.length,
        journal: docsCurrentYear.filter(d => d.sourceType === SourceTypes.JOURNAL).length,
        conference: docsCurrentYear.filter(d => d.sourceType === SourceTypes.CONFERENCE).length,
        book: docsCurrentYear.filter(d => [SourceTypes.BOOK, SourceTypes.BOOKSERIES].includes(d.sourceType)).length
    };

    const papers_next_yearStr = {
        total: docsNextYear.length,
        journal: docsNextYear.filter(d => d.sourceType === SourceTypes.JOURNAL).length,
        conference: docsNextYear.filter(d => d.sourceType === SourceTypes.CONFERENCE).length,
        book: docsNextYear.filter(d => [SourceTypes.BOOK, SourceTypes.BOOKSERIES].includes(d.sourceType)).length
    };

    const dcyIF = docsCurrentYear.map(d => {
        const metricAllYears = d.sourceMetrics.filter(m => m.name === 'IF');
        const year = Math.max(...metricAllYears.map(m => parseInt(m.year, 10)));
        d.IF = metricAllYears.find(m => m.year === year);
        return d;
    });

    const docsCurrentYearWithIF = dcyIF.filter(d => d.IF);
    const totalIFCurrentYear = docsCurrentYearWithIF.reduce((sum, d) => sum + parseFloat(d.IF.value), 0);

    return {
        papers: papersStr,
        papers_next_year: papers_next_yearStr,
        papers_if: docsCurrentYearWithIF.length,
        total_if: totalIFCurrentYear.toFixed(2),
    };
}

function formatPerformance(researchEntityData, performance) {
    const citationsYearStr = performance.citations_years.map(cpy => cpy.year + ':' + cpy.citations).join(', ');
    const dataUpTo = performance.source_date.updatedAt.getDate() + '/' +
        performance.source_date.updatedAt.getMonth() + '/' +
        performance.source_date.updatedAt.getFullYear();
    return Object.assign({}, researchEntityData, {
        hindex: {
            title: 'h-index',
            value: performance.hindex,
            str: 'h-index: ' + performance.hindex
        },
        total_citations: {
            title: 'Total Citations',
            value: performance.total_citations,
            str: 'Total Citations: ' + performance.total_citations
        },
        citations_years: {
            title: 'Nr. of citations per year',
            value: performance.citations_years,
            str: 'Nr. of citations per year: ' + citationsYearStr,
        },
        source: {
            str: '(Citations from Scopus - data up to ' + dataUpTo + ')'
        }
    });
}

function formatInstitutePerformance(researchEntityData, performance) {
    return Object.assign({}, researchEntityData, {
        papers: {
            title: 'Nr. of papers in current year (Journal, Conference, Book)',
            value: performance.papers,
            str: formatPapers(performance.papers, 'Nr. of papers due current year (Journal, Conference, Book):')
        },
        papers_next_year: {
            title: 'Nr. of papers due next year (Journal, Conference, Book)',
            value: performance.papers_next_year,
            str: formatPapers(performance.papers_next_year, 'Nr. of papers due next year (Journal, Conference, Book):')
        },
        papers_if: {
            title: 'Nr. of papers (in current year) with IF',
            value: performance.papers_if,
            str: 'Nr. of papers (in current year) with IF: ' + performance.papers_if
        },
        total_if: {
            title: 'Total IF (papers in current year)',
            value: performance.total_if,
            str: 'Total IF (papers in current year): ' + performance.total_if
        },
        source: {
            str: '(Publications from SCIENTILLA and Impact Factor from Web of Science)'
        },
    });

    function formatPapers(papers, prefix) {
        return prefix + ' ' +
            papers.total +
            ' ( ' + papers.journal + ' J + ' +
            papers.conference + 'C + ' +
            papers.book + ' B )'
    }
}

async function calculateForAll(ResearchEntityModel, fn, ...params) {
    const researchEntities = await ResearchEntityModel.find().populate('documents');
    const res = [];
    for (const researchEntity of researchEntities)
        if (!_.isEmpty(researchEntity.documents))
            res.push(await fn(researchEntity, params));

    return res;
}

function getCitationTotals(scopusCitations) {
    return scopusCitations
        .reduce((res, sc) => {
            let documentCits = res.find(r => r.document === sc.document);
            if (!documentCits) {
                documentCits = {
                    document: sc.document,
                    citations: 0
                };
                res.push(documentCits);
            }

            documentCits.citations += sc.citations;
            return res;
        }, [])
        .map(c => c.citations)
        .map(c => parseInt(c, 10));
}

async function getCitationPerYear(scopusCitations, years) {
    const citPerYear = scopusCitations.reduce((res, c) => {
        if (_.isEmpty(c) || !c.citations) return res;
        if (!res[c.year]) res[c.year] = 0;
        res[c.year] += parseInt(c.citations, 10);
        return res;
    }, {});

    return years.map(y => ({
        year: y,
        citations: citPerYear[y] || 0
    }));
}

async function getScopusCitations(documents, year) {
    const docIds = documents.map(d => d.id);
    const scopusCitations = await ScopusCitation.find({document: docIds});
    return (await Citation.find({id: scopusCitations.map(sc => sc.citation)}))
        .filter(c => c.year <= year)
        .map(c => ({
            document: scopusCitations.find(sc => sc.citation === c.id).document,
            year: c.year,
            citations: parseInt(c.citations, 10)
        }));
}

function calculateHIndex(citations) {
    if (!Array.isArray(citations))
        return;

    const cits = _.clone(citations);
    const orderedCitations = cits.sort((c1, c2) => c2 - c1);
    let h = 0;
    orderedCitations.every(c => (h >= c) ? false : ++h);
    return h;
}<commit_msg>Changed invited talks mbo api format<commit_after>/* global sails, User, Group, Document, Authorship, Citation, ScopusCitation, DocumentOrigins, SourceTypes, DocumentTypes, SourceType */
"use strict";

const _ = require('lodash');
const citation_year_count = 6;
const mainInstituteId = 1;

module.exports = {
    getUserPerformance,
    getUsersPerformance,
    getGroupInstitutePerformance,
    getGroupsInstitutePerformance,
    getUserInstitutePerformance,
    getUsersInstitutePerformance,
    getUserMBOInvitedTalks,
    getUsersMBOInvitedTalks,
    getGroupMBOInvitedTalks,
    getGroupsMBOInvitedTalks
};

async function getUserPerformance(user, year) {
    const y = parseInt(year) || (new Date()).getFullYear();
    const performance = await getResearchEntityPerformance(user.documents, y);
    return formatPerformance({
            email: user.username,
            lastname: user.surname,
            name: user.name
        },
        performance);
}

async function getUsersPerformance(year) {
    return await calculateForAll(User, getUserPerformance, year);
}

async function getGroupInstitutePerformance(group, year) {
    const y = parseInt(year) || (new Date()).getFullYear();
    const docs = group.documents.filter(d => parseInt(d.year, 10) === y || parseInt(d.year, 10) === y + 1);
    const documents = await Document.find({id: docs.map(d => d.id)}).populate('sourceMetrics');
    const performance = await getResearchEntityInstitutePerformance(documents, y);
    return formatInstitutePerformance({
            cdr: group.cdr,
            line: group.name
        },
        performance
    );
}

async function getGroupsInstitutePerformance(year) {
    return await calculateForAll(Group, getGroupInstitutePerformance, year);
}

async function getUserInstitutePerformance(user, year) {
    const y = parseInt(year) || (new Date()).getFullYear();
    const docs = user.documents.filter(d => parseInt(d.year, 10) === y || parseInt(d.year, 10) === y + 1);
    const authorships = await Authorship.find({document: docs.map(d => d.id)}).populate('affiliations');
    const documentIds = authorships.filter(
        a => a.affiliations.map(af => af.id)
            .includes(mainInstituteId))
        .map(a => a.document);
    const documents = await Document.find({id: _.uniq(documentIds)})
        .populate('sourceMetrics');
    const performance = await getResearchEntityInstitutePerformance(documents, y);
    return formatInstitutePerformance({
            email: user.username,
            lastname: user.surname,
            name: user.name
        },
        performance);
}

async function getUsersInstitutePerformance(year) {
    return await calculateForAll(User, getUserInstitutePerformance, year);
}

async function getUserMBOInvitedTalks(user, year) {
    const y = parseInt(year) || (new Date()).getFullYear();
    const res = await getResearchEntityMBOInvitedTalks(user.documents, y);

    return Object.assign({}, {
        email: user.username,
        lastname: user.surname,
        name: user.name,
        year: y
    }, res);
}

async function getUsersMBOInvitedTalks(year) {
    return await calculateForAll(User, getUserMBOInvitedTalks, year);
}

async function getGroupMBOInvitedTalks(group, year) {
    const y = parseInt(year) || (new Date()).getFullYear();
    const res = await getResearchEntityMBOInvitedTalks(group.documents, y);

    return Object.assign({}, {
        cdr: group.cdr,
        line: group.name,
        year: y
    }, res);
}

async function getGroupsMBOInvitedTalks(year) {
    return await calculateForAll(Group, getGroupMBOInvitedTalks, year);
}

async function getResearchEntityMBOInvitedTalks(docs, year) {
    function formatIT(doc) {
        return doc.itSource;
    }

    function formatOutput(sourceTypes, invitedTalks) {
        return sourceTypes.reduce((res, st) => {
            const filteredIT = invitedTalks.filter(d => d.sourceType === st.key);
            if (filteredIT.length)
                res.push({
                    title: st.label,
                    value: filteredIT.map(formatIT)
                });
            return res;
        }, []);
    }

    const invitedTalks = docs.filter(d => parseInt(d.year, 10) === year && d.type === DocumentTypes.INVITED_TALK);

    const sourceTypes = await SourceType.find({type: 'invited_talk'});
    const scientificSourceTypes = sourceTypes.filter(st => st.section === 'Scientific Event');
    const disseminationSourceTypes = sourceTypes.filter(st => st.section === 'Dissemination');

    const scientific = formatOutput(scientificSourceTypes, invitedTalks);
    const dissemination = formatOutput(disseminationSourceTypes, invitedTalks);

    return {scientific, dissemination};

}

async function getResearchEntityPerformance(docs, year) {
    const documents = docs.filter(d => d.year <= year);
    const scopusCitations = await getScopusCitations(documents, year);
    const citations = getCitationTotals(scopusCitations);
    const hIndex = calculateHIndex(citations);
    const totalCitations = citations.reduce((total, c) => total + c, 0);

    const years = _.range(citation_year_count, 0).map(i => i + parseInt(year, 10) - citation_year_count);
    const citationsPerYear = (await getCitationPerYear(scopusCitations, years));

    const source_date = await Citation.findOne({origin: DocumentOrigins.SCOPUS}).sort('updatedAt DESC');
    return {
        hindex: hIndex,
        total_citations: totalCitations,
        citations_years: citationsPerYear,
        source_date: source_date
    };
}

async function getResearchEntityInstitutePerformance(documents, year) {
    const excludedDocumentTypes = [
        DocumentTypes.ERRATUM,
        DocumentTypes.POSTER,
        DocumentTypes.PHD_THESIS,
        DocumentTypes.REPORT,
        DocumentTypes.INVITED_TALK,
        DocumentTypes.ABSTRACT_REPORT
    ];
    const docs = documents.filter(d => !excludedDocumentTypes.includes(d.type));
    const docsCurrentYear = docs.filter(d => parseInt(d.year, 10) === year);
    const docsNextYear = docs.filter(d => parseInt(d.year, 10) === (year + 1));

    const papersStr = {
        total: docsCurrentYear.length,
        journal: docsCurrentYear.filter(d => d.sourceType === SourceTypes.JOURNAL).length,
        conference: docsCurrentYear.filter(d => d.sourceType === SourceTypes.CONFERENCE).length,
        book: docsCurrentYear.filter(d => [SourceTypes.BOOK, SourceTypes.BOOKSERIES].includes(d.sourceType)).length
    };

    const papers_next_yearStr = {
        total: docsNextYear.length,
        journal: docsNextYear.filter(d => d.sourceType === SourceTypes.JOURNAL).length,
        conference: docsNextYear.filter(d => d.sourceType === SourceTypes.CONFERENCE).length,
        book: docsNextYear.filter(d => [SourceTypes.BOOK, SourceTypes.BOOKSERIES].includes(d.sourceType)).length
    };

    const dcyIF = docsCurrentYear.map(d => {
        const metricAllYears = d.sourceMetrics.filter(m => m.name === 'IF');
        const year = Math.max(...metricAllYears.map(m => parseInt(m.year, 10)));
        d.IF = metricAllYears.find(m => m.year === year);
        return d;
    });

    const docsCurrentYearWithIF = dcyIF.filter(d => d.IF);
    const totalIFCurrentYear = docsCurrentYearWithIF.reduce((sum, d) => sum + parseFloat(d.IF.value), 0);

    return {
        papers: papersStr,
        papers_next_year: papers_next_yearStr,
        papers_if: docsCurrentYearWithIF.length,
        total_if: totalIFCurrentYear.toFixed(2),
    };
}

function formatPerformance(researchEntityData, performance) {
    const citationsYearStr = performance.citations_years.map(cpy => cpy.year + ':' + cpy.citations).join(', ');
    const dataUpTo = performance.source_date.updatedAt.getDate() + '/' +
        performance.source_date.updatedAt.getMonth() + '/' +
        performance.source_date.updatedAt.getFullYear();
    return Object.assign({}, researchEntityData, {
        hindex: {
            title: 'h-index',
            value: performance.hindex,
            str: 'h-index: ' + performance.hindex
        },
        total_citations: {
            title: 'Total Citations',
            value: performance.total_citations,
            str: 'Total Citations: ' + performance.total_citations
        },
        citations_years: {
            title: 'Nr. of citations per year',
            value: performance.citations_years,
            str: 'Nr. of citations per year: ' + citationsYearStr,
        },
        source: {
            str: '(Citations from Scopus - data up to ' + dataUpTo + ')'
        }
    });
}

function formatInstitutePerformance(researchEntityData, performance) {
    return Object.assign({}, researchEntityData, {
        papers: {
            title: 'Nr. of papers in current year (Journal, Conference, Book)',
            value: performance.papers,
            str: formatPapers(performance.papers, 'Nr. of papers due current year (Journal, Conference, Book):')
        },
        papers_next_year: {
            title: 'Nr. of papers due next year (Journal, Conference, Book)',
            value: performance.papers_next_year,
            str: formatPapers(performance.papers_next_year, 'Nr. of papers due next year (Journal, Conference, Book):')
        },
        papers_if: {
            title: 'Nr. of papers (in current year) with IF',
            value: performance.papers_if,
            str: 'Nr. of papers (in current year) with IF: ' + performance.papers_if
        },
        total_if: {
            title: 'Total IF (papers in current year)',
            value: performance.total_if,
            str: 'Total IF (papers in current year): ' + performance.total_if
        },
        source: {
            str: '(Publications from SCIENTILLA and Impact Factor from Web of Science)'
        },
    });

    function formatPapers(papers, prefix) {
        return prefix + ' ' +
            papers.total +
            ' ( ' + papers.journal + ' J + ' +
            papers.conference + 'C + ' +
            papers.book + ' B )'
    }
}

async function calculateForAll(ResearchEntityModel, fn, ...params) {
    const researchEntities = await ResearchEntityModel.find().populate('documents');
    const res = [];
    for (const researchEntity of researchEntities)
        if (!_.isEmpty(researchEntity.documents))
            res.push(await fn(researchEntity, params));

    return res;
}

function getCitationTotals(scopusCitations) {
    return scopusCitations
        .reduce((res, sc) => {
            let documentCits = res.find(r => r.document === sc.document);
            if (!documentCits) {
                documentCits = {
                    document: sc.document,
                    citations: 0
                };
                res.push(documentCits);
            }

            documentCits.citations += sc.citations;
            return res;
        }, [])
        .map(c => c.citations)
        .map(c => parseInt(c, 10));
}

async function getCitationPerYear(scopusCitations, years) {
    const citPerYear = scopusCitations.reduce((res, c) => {
        if (_.isEmpty(c) || !c.citations) return res;
        if (!res[c.year]) res[c.year] = 0;
        res[c.year] += parseInt(c.citations, 10);
        return res;
    }, {});

    return years.map(y => ({
        year: y,
        citations: citPerYear[y] || 0
    }));
}

async function getScopusCitations(documents, year) {
    const docIds = documents.map(d => d.id);
    const scopusCitations = await ScopusCitation.find({document: docIds});
    return (await Citation.find({id: scopusCitations.map(sc => sc.citation)}))
        .filter(c => c.year <= year)
        .map(c => ({
            document: scopusCitations.find(sc => sc.citation === c.id).document,
            year: c.year,
            citations: parseInt(c.citations, 10)
        }));
}

function calculateHIndex(citations) {
    if (!Array.isArray(citations))
        return;

    const cits = _.clone(citations);
    const orderedCitations = cits.sort((c1, c2) => c2 - c1);
    let h = 0;
    orderedCitations.every(c => (h >= c) ? false : ++h);
    return h;
}<|endoftext|>


<commit_before>/*

//--------------------------------------------------------------------------------------------------//
//---------------------------------------- Table Of Contents ---------------------------------------//
//--------------------------------------------------------------------------------------------------//

---------------------------------------------------------------
#                             Config                          #
---------------------------------------------------------------

//

---------------------------------------------------------------
#                            Filters                          #
---------------------------------------------------------------

isLoggedIn
isLoggedOut
isAdmin

canView
canPost
canEditPost
canEditComment

hasCompletedProfile

---------------------------------------------------------------
#                          Controllers                        #
---------------------------------------------------------------

PostsListController
PostPageController

---------------------------------------------------------------
#                             Routes                          #
---------------------------------------------------------------

1) Paginated Lists
----------------------
Top
New
Best
Pending
Categories

2) Digest
--------------------
Digest

3) Posts
--------------------
Post Page
Post Page (scroll to comment)
Post Edit
Post Submit

4) Comments
--------------------
Comment Page
Comment Edit
Comment Submit

5) Users
--------------------
User Profie
User Edit
Forgot Password
Account
All Users
Unsubscribe (from notifications)
Sign Up
Sign In

6) Misc Routes
--------------------
Settings
Categories
Toolbox

*/

//--------------------------------------------------------------------------------------------------//
//--------------------------------------------- Config ---------------------------------------------//
//--------------------------------------------------------------------------------------------------//

Router.configure({
  layoutTemplate: 'layout',
  loadingTemplate: 'loading',
  notFoundTemplate: 'not_found',
});

//--------------------------------------------------------------------------------------------------//
//--------------------------------------------- Filters --------------------------------------------//
//--------------------------------------------------------------------------------------------------//

var filters = {

  nProgressHook: function () {
    if (this.ready()) {
      NProgress.done();
    } else {
      NProgress.start();
      this.stop();
    }
  },

  resetScroll: function () {
    var scrollTo = window.currentScroll || 0;
    $('body').scrollTop(scrollTo);
    $('body').css("min-height", 0);
  },

  isLoggedIn: function() {
    if (!(Meteor.loggingIn() || Meteor.user())) {
      throwError(i18n.t('Please Sign In First.'))
      this.render('signin');
      this.stop();
    }
  },

  isLoggedOut: function() {
    if(Meteor.user()){
      this.render('already_logged_in');
      this.stop();
    }
  },

  isAdmin: function() {
    this.subscribe('currentUser').wait();
    if(!this.ready()) return;
    if(!isAdmin()){
      throwError(i18n.t("Sorry, you  have to be an admin to view this page."))
      this.render('no_rights');
      this.stop();
    }
  },

  canView: function() {
    this.subscribe('currentUser').wait();
    this.subscribe('settings').wait();
    if(!this.ready()) return;
    if(!canView()){
      console.log('cannot view')
      this.render('no_rights');
      this.stop();
    }
  },

  canPost: function () {
    this.subscribe('currentUser').wait();
    this.subscribe('settings').wait();
    if(!this.ready()) return;
    if(!canPost()){
      throwError(i18n.t("Sorry, you don't have permissions to add new items."))
      this.render('no_rights');
      this.stop();
    }
  },

  canEditPost: function() {
    this.subscribe('currentUser').wait();
    if(!this.ready()) return;
    // Already subscribed to this post by route({waitOn: ...})
    var post = Posts.findOne(this.params._id);
    if(!currentUserCanEdit(post)){
      throwError(i18n.t("Sorry, you cannot edit this post."))
      this.render('no_rights');
      this.stop();
    }
  },

  canEditComment: function() {
    this.subscribe('currentUser').wait();
    if(!this.ready()) return;
    // Already subscribed to this commit by CommentPageController
    var comment = Comments.findOne(this.params._id);
    if(!currentUserCanEdit(comment)){
      throwError(i18n.t("Sorry, you cannot edit this comment."))
      this.render('no_rights');
      this.stop();
    }
  },

  hasCompletedProfile: function() {
    this.subscribe('currentUser').wait();
    if(!this.ready()) return;
    var user = Meteor.user();
    if (user && ! userProfileComplete(user)){
      this.render('user_email');
      this.stop();
    }
  }

}

// Load Hooks

Router.load( function () {
  clearSeenErrors(); // set all errors who have already been seen to not show anymore
  Session.set('categorySlug', null);

  // if we're not on the search page itself, clear search query and field
  if(getCurrentRoute().indexOf('search') == -1){
    Session.set('searchQuery', '');
    $('.search-field').val('').blur();
  }

});

// Before Hooks

// Use nProgress on every route that has to load a subscription
Router.before(filters.nProgressHook, {only: [
  'posts_top',
  'posts_new',
  'posts_best',
  'posts_pending',
  'posts_digest',
  'posts_category',
  'search',
  'post_page',
  'post_edit',
  'comment_page',
  'comment_edit',
  'comment_reply',
  'user_edit',
  'user_profile',
  'all-users',
  'logs'
]});

Router.before(filters.canView);
Router.before(filters.hasCompletedProfile);
Router.before(filters.isLoggedIn, {only: ['comment_reply','post_submit']});
Router.before(filters.isLoggedOut, {only: ['signin', 'signup']});
Router.before(filters.canPost, {only: ['posts_pending', 'comment_reply', 'post_submit']});
Router.before(filters.canEditPost, {only: ['post_edit']});
Router.before(filters.canEditComment, {only: ['comment_edit']});
Router.before(filters.isAdmin, {only: ['posts_pending', 'all-users', 'settings', 'categories', 'toolbox', 'logs']});

// After Hooks

Router.after(filters.resetScroll, {except:['posts_top', 'posts_new', 'posts_best', 'posts_pending', 'posts_category', 'all-users']});
Router.after( function () {
  analyticsRequest() // log this request with mixpanel, etc
});

// Unload Hooks

//

//--------------------------------------------------------------------------------------------------//
//------------------------------------------- Controllers ------------------------------------------//
//--------------------------------------------------------------------------------------------------//

// Controller for all posts lists

PostsListController = RouteController.extend({
  template:'posts_list',
  waitOn: function () {
    // take the first segment of the path to get the view, unless it's '/' in which case the view default to 'top'
    // note: most of the time this.params.slug will be empty
    this._terms = {
      view: this.path == '/' ? 'top' : this.path.split('/')[1],
      limit: this.params.limit || getSetting('postsPerPage', 10),
      category: this.params.slug,
      query: Session.get("searchQuery")
    }
    return [
      Meteor.subscribe('postsList', this._terms),
      Meteor.subscribe('postsListUsers', this._terms)
    ]
  },
  data: function () {
    var parameters = getParameters(this._terms),
        posts = Posts.find(parameters.find, parameters.options);
        postsCount = posts.count();

    Session.set('postsLimit', this._terms.limit);

    return {
      postsList: posts,
      postsCount: postsCount
    }
  },
  after: function() {
    var view = this.path == '/' ? 'top' : this.path.split('/')[1];
    Session.set('view', view);
  }
});

// Controller for post digest

PostsDigestController = RouteController.extend({
  template: 'posts_digest',
  waitOn: function() {
    // if day is set, use that. If not default to today
    var currentDate = this.params.day ? new Date(this.params.year, this.params.month-1, this.params.day) : Session.get('today'),
        terms = {
          view: 'digest',
          after: moment(currentDate).startOf('day').valueOf(),
          before: moment(currentDate).endOf('day').valueOf()
        }
    return [
      Meteor.subscribe('postsList', terms),
      Meteor.subscribe('postsListUsers', terms)
    ]
  },
  data: function() {
    var currentDate = this.params.day ? new Date(this.params.year, this.params.month-1, this.params.day) : Session.get('today'),
        terms = {
          view: 'digest',
          after: moment(currentDate).startOf('day').valueOf(),
          before: moment(currentDate).endOf('day').valueOf()
        },
        parameters = getParameters(terms);
    Session.set('currentDate', currentDate);
    return {
      posts: Posts.find(parameters.find, parameters.options)
    }
  }
});

// Controller for post pages

PostPageController = RouteController.extend({
  template: 'post_page',
  waitOn: function () {
    return [
      Meteor.subscribe('singlePost', this.params._id),
      Meteor.subscribe('postComments', this.params._id),
      Meteor.subscribe('postUsers', this.params._id)
    ];
  },
  data: function () {
    return {postId: this.params._id};
  },
  after: function () {
    window.queueComments = false;
    window.openedComments = [];
    // TODO: scroll to comment position
  }
});

// Controller for comment pages

CommentPageController = RouteController.extend({
  waitOn: function() {
    return [
      Meteor.subscribe('singleComment', this.params._id),
      Meteor.subscribe('commentUser', this.params._id),
      Meteor.subscribe('commentPost', this.params._id)
    ]
  },
  data: function() {
    return {
      comment: Comments.findOne(this.params._id)
    }
  },
  after: function () {
    window.queueComments = false;
  }
});

// Controller for user pages

UserPageController = RouteController.extend({
  waitOn: function() {
    return Meteor.subscribe('singleUser', this.params._idOrSlug);
  },
  data: function() {
    var findById = Meteor.users.findOne(this.params._idOrSlug);
    var findBySlug = Meteor.users.findOne({slug: this.params._idOrSlug});
    if(typeof findById !== "undefined"){
      // redirect to slug-based URL
      Router.go(getProfileUrl(findById), {replaceState: true});
    }else{
      return {
        user: (typeof findById == "undefined") ? findBySlug : findById
      }
    }
  }
});

//--------------------------------------------------------------------------------------------------//
//--------------------------------------------- Routes ---------------------------------------------//
//--------------------------------------------------------------------------------------------------//

Router.map(function() {

  // -------------------------------------------- Post Lists -------------------------------------------- //

  // Top

  this.route('posts_top', {
    path: '/',
    controller: PostsListController
  });

  this.route('posts_top', {
    path: '/top/:limit?',
    controller: PostsListController
  });

  // New

  this.route('posts_new', {
    path: '/new/:limit?',
    controller: PostsListController
  });

  // Best

  this.route('posts_best', {
    path: '/best/:limit?',
    controller: PostsListController
  });

  // Pending

  this.route('posts_pending', {
    path: '/pending/:limit?',
    controller: PostsListController
  });

  // Categories

  this.route('posts_category', {
    path: '/category/:slug/:limit?',
    controller: PostsListController,
    after: function() {
      Session.set('categorySlug', this.params.slug);
    }
  });

  // TODO: enable /category/new, /category/best, etc. views

  // Search

  this.route('search', {
    path: '/search/:limit?',
    controller: PostsListController
  });

  // Digest

  this.route('posts_digest', {
    path: '/digest/:year/:month/:day',
    controller: PostsDigestController
  });

  this.route('posts_digest', {
    path: '/digest',
    controller: PostsDigestController
  });

  // -------------------------------------------- Post -------------------------------------------- //

  // Post Page

  this.route('post_page', {
    path: '/posts/:_id',
    controller: PostPageController
  });

  this.route('post_page', {
    path: '/posts/:_id/comment/:commentId',
    controller: PostPageController,
    after: function () {
      // TODO: scroll to comment position
    }
  });

  // Post Edit

  this.route('post_edit', {
    path: '/posts/:_id/edit',
    waitOn: function () {
      return Meteor.subscribe('singlePost', this.params._id);
    },
    data: function() {
      return {postId: this.params._id};
    }
  });

  // Post Submit

  this.route('post_submit', {path: '/submit'});

  // -------------------------------------------- Comment -------------------------------------------- //

  // Comment Page

  this.route('comment_page', {
    path: '/comments/:_id',
    controller: CommentPageController
  });

  // Comment Reply

  this.route('comment_reply', {
    path: '/comments/:_id/reply',
    controller: CommentPageController,
    after: function() {
      window.queueComments = false;
    }
  });

  // Comment Edit

  this.route('comment_edit', {
    path: '/comments/:_id/edit',
    controller: CommentPageController,
    after: function() {
      window.queueComments = false;
    }
  });

  // -------------------------------------------- Users -------------------------------------------- //

  // User Profile

  this.route('user_profile', {
    path: '/users/:_idOrSlug',
    controller: UserPageController
  });

  // User Edit

  this.route('user_edit', {
    path: '/users/:_idOrSlug/edit',
    controller: UserPageController
  });

  // Account

  this.route('account', {
    path: '/account',
    template: 'user_edit',
    data: function() {
      return {
        user: Meteor.user()
      }
    }
  });

  // Forgot Password

  this.route('forgot_password');

  // All Users

  this.route('all-users', {
    path: '/all-users/:limit?',
    template: 'users',
    waitOn: function() {
      var limit = parseInt(this.params.limit) || 20;
      return Meteor.subscribe('allUsers', this.params.filterBy, this.params.sortBy, limit);
    },
    data: function() {
      var limit = parseInt(this.params.limit) || 20,
          parameters = getUsersParameters(this.params.filterBy, this.params.sortBy, limit),
          filterBy = (typeof this.params.filterBy === 'string') ? this.params.filterBy : 'all',
          sortBy = (typeof this.params.sortBy === 'string') ? this.params.sortBy : 'createdAt';
      Session.set('usersLimit', limit);
      return {
        users: Meteor.users.find(parameters.find, parameters.options),
        filterBy: filterBy,
        sortBy: sortBy
      }
    }
  });

  // Unsubscribe (from notifications)

  this.route('unsubscribe', {
    path: '/unsubscribe/:hash',
    data: function() {
      return {
        hash: this.params.hash
      }
    }
  });

  // User Sign-Up

  this.route('signup');

  // User Sign-In

  this.route('signin');

  // -------------------------------------------- Other -------------------------------------------- //

  // Categories

  this.route('categories');

  // Settings

  this.route('settings');

  // Toolbox

  this.route('toolbox');

  // Search Logs

  this.route('logs', {
    path: '/logs/:limit?',
    waitOn: function () {
      var limit = this.params.limit || 100;
      Session.set('logsLimit', limit);
      return Meteor.subscribe('searches', limit);
    },
    data: function () {
      return Searches.find({}, {sort: {timestamp: -1}});
    }
  });
});
<commit_msg>#220: now all pages are waitOn('categories')<commit_after>/*

//--------------------------------------------------------------------------------------------------//
//---------------------------------------- Table Of Contents ---------------------------------------//
//--------------------------------------------------------------------------------------------------//

---------------------------------------------------------------
#                             Config                          #
---------------------------------------------------------------

//

---------------------------------------------------------------
#                            Filters                          #
---------------------------------------------------------------

isLoggedIn
isLoggedOut
isAdmin

canView
canPost
canEditPost
canEditComment

hasCompletedProfile

---------------------------------------------------------------
#                          Controllers                        #
---------------------------------------------------------------

PostsListController
PostPageController

---------------------------------------------------------------
#                             Routes                          #
---------------------------------------------------------------

1) Paginated Lists
----------------------
Top
New
Best
Pending
Categories

2) Digest
--------------------
Digest

3) Posts
--------------------
Post Page
Post Page (scroll to comment)
Post Edit
Post Submit

4) Comments
--------------------
Comment Page
Comment Edit
Comment Submit

5) Users
--------------------
User Profie
User Edit
Forgot Password
Account
All Users
Unsubscribe (from notifications)
Sign Up
Sign In

6) Misc Routes
--------------------
Settings
Categories
Toolbox

*/

//--------------------------------------------------------------------------------------------------//
//--------------------------------------------- Config ---------------------------------------------//
//--------------------------------------------------------------------------------------------------//

Router.configure({
  layoutTemplate: 'layout',
  loadingTemplate: 'loading',
  notFoundTemplate: 'not_found',
  waitOn: Meteor.subscribe('categories')
});

//--------------------------------------------------------------------------------------------------//
//--------------------------------------------- Filters --------------------------------------------//
//--------------------------------------------------------------------------------------------------//

var filters = {

  nProgressHook: function () {
    if (this.ready()) {
      NProgress.done();
    } else {
      NProgress.start();
      this.stop();
    }
  },

  resetScroll: function () {
    var scrollTo = window.currentScroll || 0;
    $('body').scrollTop(scrollTo);
    $('body').css("min-height", 0);
  },

  isLoggedIn: function() {
    if (!(Meteor.loggingIn() || Meteor.user())) {
      throwError(i18n.t('Please Sign In First.'))
      this.render('signin');
      this.stop();
    }
  },

  isLoggedOut: function() {
    if(Meteor.user()){
      this.render('already_logged_in');
      this.stop();
    }
  },

  isAdmin: function() {
    this.subscribe('currentUser').wait();
    if(!this.ready()) return;
    if(!isAdmin()){
      throwError(i18n.t("Sorry, you  have to be an admin to view this page."))
      this.render('no_rights');
      this.stop();
    }
  },

  canView: function() {
    this.subscribe('currentUser').wait();
    this.subscribe('settings').wait();
    if(!this.ready()) return;
    if(!canView()){
      console.log('cannot view')
      this.render('no_rights');
      this.stop();
    }
  },

  canPost: function () {
    this.subscribe('currentUser').wait();
    this.subscribe('settings').wait();
    if(!this.ready()) return;
    if(!canPost()){
      throwError(i18n.t("Sorry, you don't have permissions to add new items."))
      this.render('no_rights');
      this.stop();
    }
  },

  canEditPost: function() {
    this.subscribe('currentUser').wait();
    if(!this.ready()) return;
    // Already subscribed to this post by route({waitOn: ...})
    var post = Posts.findOne(this.params._id);
    if(!currentUserCanEdit(post)){
      throwError(i18n.t("Sorry, you cannot edit this post."))
      this.render('no_rights');
      this.stop();
    }
  },

  canEditComment: function() {
    this.subscribe('currentUser').wait();
    if(!this.ready()) return;
    // Already subscribed to this commit by CommentPageController
    var comment = Comments.findOne(this.params._id);
    if(!currentUserCanEdit(comment)){
      throwError(i18n.t("Sorry, you cannot edit this comment."))
      this.render('no_rights');
      this.stop();
    }
  },

  hasCompletedProfile: function() {
    this.subscribe('currentUser').wait();
    if(!this.ready()) return;
    var user = Meteor.user();
    if (user && ! userProfileComplete(user)){
      this.render('user_email');
      this.stop();
    }
  }

}

// Load Hooks

Router.load( function () {
  clearSeenErrors(); // set all errors who have already been seen to not show anymore
  Session.set('categorySlug', null);

  // if we're not on the search page itself, clear search query and field
  if(getCurrentRoute().indexOf('search') == -1){
    Session.set('searchQuery', '');
    $('.search-field').val('').blur();
  }

});

// Before Hooks

// Use nProgress on every route that has to load a subscription
Router.before(filters.nProgressHook, {only: [
  'posts_top',
  'posts_new',
  'posts_best',
  'posts_pending',
  'posts_digest',
  'posts_category',
  'search',
  'post_page',
  'post_edit',
  'comment_page',
  'comment_edit',
  'comment_reply',
  'user_edit',
  'user_profile',
  'all-users',
  'logs'
]});

Router.before(filters.canView);
Router.before(filters.hasCompletedProfile);
Router.before(filters.isLoggedIn, {only: ['comment_reply','post_submit']});
Router.before(filters.isLoggedOut, {only: ['signin', 'signup']});
Router.before(filters.canPost, {only: ['posts_pending', 'comment_reply', 'post_submit']});
Router.before(filters.canEditPost, {only: ['post_edit']});
Router.before(filters.canEditComment, {only: ['comment_edit']});
Router.before(filters.isAdmin, {only: ['posts_pending', 'all-users', 'settings', 'categories', 'toolbox', 'logs']});

// After Hooks

Router.after(filters.resetScroll, {except:['posts_top', 'posts_new', 'posts_best', 'posts_pending', 'posts_category', 'all-users']});
Router.after( function () {
  analyticsRequest() // log this request with mixpanel, etc
});

// Unload Hooks

//

//--------------------------------------------------------------------------------------------------//
//------------------------------------------- Controllers ------------------------------------------//
//--------------------------------------------------------------------------------------------------//

// Controller for all posts lists

PostsListController = RouteController.extend({
  template:'posts_list',
  waitOn: function () {
    // take the first segment of the path to get the view, unless it's '/' in which case the view default to 'top'
    // note: most of the time this.params.slug will be empty
    this._terms = {
      view: this.path == '/' ? 'top' : this.path.split('/')[1],
      limit: this.params.limit || getSetting('postsPerPage', 10),
      category: this.params.slug,
      query: Session.get("searchQuery")
    }
    return [
      Meteor.subscribe('postsList', this._terms),
      Meteor.subscribe('postsListUsers', this._terms)
    ]
  },
  data: function () {
    var parameters = getParameters(this._terms),
        posts = Posts.find(parameters.find, parameters.options);
        postsCount = posts.count();

    Session.set('postsLimit', this._terms.limit);

    return {
      postsList: posts,
      postsCount: postsCount
    }
  },
  after: function() {
    var view = this.path == '/' ? 'top' : this.path.split('/')[1];
    Session.set('view', view);
  }
});

// Controller for post digest

PostsDigestController = RouteController.extend({
  template: 'posts_digest',
  waitOn: function() {
    // if day is set, use that. If not default to today
    var currentDate = this.params.day ? new Date(this.params.year, this.params.month-1, this.params.day) : Session.get('today'),
        terms = {
          view: 'digest',
          after: moment(currentDate).startOf('day').valueOf(),
          before: moment(currentDate).endOf('day').valueOf()
        }
    return [
      Meteor.subscribe('postsList', terms),
      Meteor.subscribe('postsListUsers', terms)
    ]
  },
  data: function() {
    var currentDate = this.params.day ? new Date(this.params.year, this.params.month-1, this.params.day) : Session.get('today'),
        terms = {
          view: 'digest',
          after: moment(currentDate).startOf('day').valueOf(),
          before: moment(currentDate).endOf('day').valueOf()
        },
        parameters = getParameters(terms);
    Session.set('currentDate', currentDate);
    return {
      posts: Posts.find(parameters.find, parameters.options)
    }
  }
});

// Controller for post pages

PostPageController = RouteController.extend({
  template: 'post_page',
  waitOn: function () {
    return [
      Meteor.subscribe('singlePost', this.params._id),
      Meteor.subscribe('postComments', this.params._id),
      Meteor.subscribe('postUsers', this.params._id)
    ];
  },
  data: function () {
    return {postId: this.params._id};
  },
  after: function () {
    window.queueComments = false;
    window.openedComments = [];
    // TODO: scroll to comment position
  }
});

// Controller for comment pages

CommentPageController = RouteController.extend({
  waitOn: function() {
    return [
      Meteor.subscribe('singleComment', this.params._id),
      Meteor.subscribe('commentUser', this.params._id),
      Meteor.subscribe('commentPost', this.params._id)
    ]
  },
  data: function() {
    return {
      comment: Comments.findOne(this.params._id)
    }
  },
  after: function () {
    window.queueComments = false;
  }
});

// Controller for user pages

UserPageController = RouteController.extend({
  waitOn: function() {
    return Meteor.subscribe('singleUser', this.params._idOrSlug);
  },
  data: function() {
    var findById = Meteor.users.findOne(this.params._idOrSlug);
    var findBySlug = Meteor.users.findOne({slug: this.params._idOrSlug});
    if(typeof findById !== "undefined"){
      // redirect to slug-based URL
      Router.go(getProfileUrl(findById), {replaceState: true});
    }else{
      return {
        user: (typeof findById == "undefined") ? findBySlug : findById
      }
    }
  }
});

//--------------------------------------------------------------------------------------------------//
//--------------------------------------------- Routes ---------------------------------------------//
//--------------------------------------------------------------------------------------------------//

Router.map(function() {

  // -------------------------------------------- Post Lists -------------------------------------------- //

  // Top

  this.route('posts_top', {
    path: '/',
    controller: PostsListController
  });

  this.route('posts_top', {
    path: '/top/:limit?',
    controller: PostsListController
  });

  // New

  this.route('posts_new', {
    path: '/new/:limit?',
    controller: PostsListController
  });

  // Best

  this.route('posts_best', {
    path: '/best/:limit?',
    controller: PostsListController
  });

  // Pending

  this.route('posts_pending', {
    path: '/pending/:limit?',
    controller: PostsListController
  });

  // Categories

  this.route('posts_category', {
    path: '/category/:slug/:limit?',
    controller: PostsListController,
    after: function() {
      Session.set('categorySlug', this.params.slug);
    }
  });

  // TODO: enable /category/new, /category/best, etc. views

  // Search

  this.route('search', {
    path: '/search/:limit?',
    controller: PostsListController
  });

  // Digest

  this.route('posts_digest', {
    path: '/digest/:year/:month/:day',
    controller: PostsDigestController
  });

  this.route('posts_digest', {
    path: '/digest',
    controller: PostsDigestController
  });

  // -------------------------------------------- Post -------------------------------------------- //

  // Post Page

  this.route('post_page', {
    path: '/posts/:_id',
    controller: PostPageController
  });

  this.route('post_page', {
    path: '/posts/:_id/comment/:commentId',
    controller: PostPageController,
    after: function () {
      // TODO: scroll to comment position
    }
  });

  // Post Edit

  this.route('post_edit', {
    path: '/posts/:_id/edit',
    waitOn: function () {
      return Meteor.subscribe('singlePost', this.params._id);
    },
    data: function() {
      return {postId: this.params._id};
    }
  });

  // Post Submit

  this.route('post_submit', {path: '/submit'});

  // -------------------------------------------- Comment -------------------------------------------- //

  // Comment Page

  this.route('comment_page', {
    path: '/comments/:_id',
    controller: CommentPageController
  });

  // Comment Reply

  this.route('comment_reply', {
    path: '/comments/:_id/reply',
    controller: CommentPageController,
    after: function() {
      window.queueComments = false;
    }
  });

  // Comment Edit

  this.route('comment_edit', {
    path: '/comments/:_id/edit',
    controller: CommentPageController,
    after: function() {
      window.queueComments = false;
    }
  });

  // -------------------------------------------- Users -------------------------------------------- //

  // User Profile

  this.route('user_profile', {
    path: '/users/:_idOrSlug',
    controller: UserPageController
  });

  // User Edit

  this.route('user_edit', {
    path: '/users/:_idOrSlug/edit',
    controller: UserPageController
  });

  // Account

  this.route('account', {
    path: '/account',
    template: 'user_edit',
    data: function() {
      return {
        user: Meteor.user()
      }
    }
  });

  // Forgot Password

  this.route('forgot_password');

  // All Users

  this.route('all-users', {
    path: '/all-users/:limit?',
    template: 'users',
    waitOn: function() {
      var limit = parseInt(this.params.limit) || 20;
      return Meteor.subscribe('allUsers', this.params.filterBy, this.params.sortBy, limit);
    },
    data: function() {
      var limit = parseInt(this.params.limit) || 20,
          parameters = getUsersParameters(this.params.filterBy, this.params.sortBy, limit),
          filterBy = (typeof this.params.filterBy === 'string') ? this.params.filterBy : 'all',
          sortBy = (typeof this.params.sortBy === 'string') ? this.params.sortBy : 'createdAt';
      Session.set('usersLimit', limit);
      return {
        users: Meteor.users.find(parameters.find, parameters.options),
        filterBy: filterBy,
        sortBy: sortBy
      }
    }
  });

  // Unsubscribe (from notifications)

  this.route('unsubscribe', {
    path: '/unsubscribe/:hash',
    data: function() {
      return {
        hash: this.params.hash
      }
    }
  });

  // User Sign-Up

  this.route('signup');

  // User Sign-In

  this.route('signin');

  // -------------------------------------------- Other -------------------------------------------- //

  // Categories

  this.route('categories');

  // Settings

  this.route('settings');

  // Toolbox

  this.route('toolbox');

  // Search Logs

  this.route('logs', {
    path: '/logs/:limit?',
    waitOn: function () {
      var limit = this.params.limit || 100;
      Session.set('logsLimit', limit);
      return Meteor.subscribe('searches', limit);
    },
    data: function () {
      return Searches.find({}, {sort: {timestamp: -1}});
    }
  });
});
<|endoftext|>


<commit_before>'use strict';

/* Controllers */

angular.module('angular-client-side-auth')
.controller('NavCtrl', ['$rootScope', '$scope', '$location', 'Auth', function($rootScope, $scope, $location, Auth) {
    $scope.user = Auth.user;
    $scope.userRoles = Auth.userRoles;
    $scope.accessLevels = Auth.accessLevels;

    $scope.logout = function() {
        Auth.logout(function() {
            $location.path('/login');
        }, function() {
            $rootScope.error = "Failed to logout";
        });
    };
}]);

angular.module('angular-client-side-auth')
.controller('DataCtrl', ['$rootScope', '$scope', '$location', 'Auth', function($rootScope, $scope, $location, Auth) {
    $scope.user = Auth.user;
    $scope.userRoles = Auth.userRoles;
    $scope.accessLevels = Auth.accessLevels;

    Auth.getData(function(res) {
        $scope.data = res;
    }, function() {
        $rootScope.error = "Failed to retrieve data";
    });

    //$scope.data = [{"payer": "bobby", "payee" : "Bob"}, {"payer": "test", "payee" : "test2"}];
    //$rootScope.success = JSON.stringify($scope.data);
}]);

angular.module('angular-client-side-auth')
.controller('TransCtrl', ['$rootScope', '$scope', '$location', 'Auth', function($rootScope, $scope, $location, Auth) {
    $scope.user = Auth.user;
    $scope.userRoles = Auth.userRoles;
    $scope.accessLevels = Auth.accessLevels;

    $scope.newTransaction = function() {
        Auth.newTransaction( {
            payer: $scope.payer,
            payee: $scope.payee,
            amount: $scope.amount,
            reason: $scope.reason
        }, function() { //Success
            $rootScope.success = "Created transaction";
            $location.path('/transactionLog');
        }, function() {
            $rootScope.error = "Failed to create transaction";
        });
    };
}]);

angular.module('angular-client-side-auth')
.controller('LoginCtrl',
['$rootScope', '$scope', '$location', '$window', 'Auth', function($rootScope, $scope, $location, $window, Auth) {

    $scope.rememberme = true;
    $scope.login = function() {
        Auth.login({
                username: $scope.username,
                password: $scope.password,
                rememberme: $scope.rememberme
            },
            function(res) {
                $location.path('/');
            },
            function(err) {
                $rootScope.error = "Failed to login";
            });
    };

    $scope.loginOauth = function(provider) {
        $window.location.href = '/auth/' + provider;
    };
}]);

angular.module('angular-client-side-auth')
.controller('RegisterCtrl',
['$rootScope', '$scope', '$location', 'Auth', function($rootScope, $scope, $location, Auth) {
    $scope.role = Auth.userRoles.user;
    $scope.userRoles = Auth.userRoles;

    $scope.register = function() {
        Auth.register({
                username: $scope.username,
                password: $scope.password,
                role: $scope.role
            },
            function() {
                $location.path('/');
            },
            function(err) {
                $rootScope.error = err;
            });
    };
}]);

angular.module('angular-client-side-auth')
.controller('AdminCtrl',
['$rootScope', '$scope', 'Users', 'Auth', function($rootScope, $scope, Users, Auth) {
    $scope.loading = true;
    $scope.userRoles = Auth.userRoles;

    Users.getAll(function(res) {
        $scope.users = res;
        $scope.loading = false;
    }, function(err) {
        $rootScope.error = "Failed to fetch users.";
        $scope.loading = false;
    });

}]);

<commit_msg>reverted back to test data...<commit_after>'use strict';

/* Controllers */

angular.module('angular-client-side-auth')
.controller('NavCtrl', ['$rootScope', '$scope', '$location', 'Auth', function($rootScope, $scope, $location, Auth) {
    $scope.user = Auth.user;
    $scope.userRoles = Auth.userRoles;
    $scope.accessLevels = Auth.accessLevels;

    $scope.logout = function() {
        Auth.logout(function() {
            $location.path('/login');
        }, function() {
            $rootScope.error = "Failed to logout";
        });
    };
}]);

angular.module('angular-client-side-auth')
.controller('DataCtrl', ['$rootScope', '$scope', '$location', 'Auth', function($rootScope, $scope, $location, Auth) {
    $scope.user = Auth.user;
    $scope.userRoles = Auth.userRoles;
    $scope.accessLevels = Auth.accessLevels;

    /*Auth.getData(function(res) {
        $scope.data = res;
    }, function() {
        $rootScope.error = "Failed to retrieve data";
    });
    */

    $scope.data = [{"payer": "bobby", "payee" : "Bob"}, {"payer": "test", "payee" : "test2"}];
    //$rootScope.success = JSON.stringify($scope.data);
}]);

angular.module('angular-client-side-auth')
.controller('TransCtrl', ['$rootScope', '$scope', '$location', 'Auth', function($rootScope, $scope, $location, Auth) {
    $scope.user = Auth.user;
    $scope.userRoles = Auth.userRoles;
    $scope.accessLevels = Auth.accessLevels;

    $scope.newTransaction = function() {
        Auth.newTransaction( {
            payer: $scope.payer,
            payee: $scope.payee,
            amount: $scope.amount,
            reason: $scope.reason
        }, function() { //Success
            $rootScope.success = "Created transaction";
            $location.path('/transactionLog');
        }, function() {
            $rootScope.error = "Failed to create transaction";
        });
    };
}]);

angular.module('angular-client-side-auth')
.controller('LoginCtrl',
['$rootScope', '$scope', '$location', '$window', 'Auth', function($rootScope, $scope, $location, $window, Auth) {

    $scope.rememberme = true;
    $scope.login = function() {
        Auth.login({
                username: $scope.username,
                password: $scope.password,
                rememberme: $scope.rememberme
            },
            function(res) {
                $location.path('/');
            },
            function(err) {
                $rootScope.error = "Failed to login";
            });
    };

    $scope.loginOauth = function(provider) {
        $window.location.href = '/auth/' + provider;
    };
}]);

angular.module('angular-client-side-auth')
.controller('RegisterCtrl',
['$rootScope', '$scope', '$location', 'Auth', function($rootScope, $scope, $location, Auth) {
    $scope.role = Auth.userRoles.user;
    $scope.userRoles = Auth.userRoles;

    $scope.register = function() {
        Auth.register({
                username: $scope.username,
                password: $scope.password,
                role: $scope.role
            },
            function() {
                $location.path('/');
            },
            function(err) {
                $rootScope.error = err;
            });
    };
}]);

angular.module('angular-client-side-auth')
.controller('AdminCtrl',
['$rootScope', '$scope', 'Users', 'Auth', function($rootScope, $scope, Users, Auth) {
    $scope.loading = true;
    $scope.userRoles = Auth.userRoles;

    Users.getAll(function(res) {
        $scope.users = res;
        $scope.loading = false;
    }, function(err) {
        $rootScope.error = "Failed to fetch users.";
        $scope.loading = false;
    });

}]);

<|endoftext|>


<commit_before>angular.module('starter.controllers', [])

.controller('AppCtrl', function($scope, $location, RegistrationService) {
  $scope.logout = function() {
    RegistrationService.logout();
    $location.path("/home");
  }
  $scope.timeleft = '0 secs';
})

.controller('RegisterCtrl', function($scope, $location, RegistrationService) {
  $scope.user = {
    name: '',
    email: '',
    password: '',
    password2: ''
  };

  $scope.$parent.logout_text = 'Logout';

  $scope.register = function() {
    RegistrationService.register($scope.user).then(function() {
      $location.path("/");
    })
  }
})

.controller('LoginCtrl', function($scope, $location, RegistrationService) {
  $scope.user = {
    email: '',
    password: ''
  };

  $scope.$parent.logout_text = 'Register';

  $scope.login = function() {
    RegistrationService.login($scope.user.email, $scope.user.password).then(function() {
      $location.path("/");
    });
  }

})

.controller('LeadersCtrl', function($scope, SocketIO, Answer) {
  $scope.leaders = Answer.leaders();

  SocketIO.on('answer', function(msg) {
    $scope.leaders = Answer.leaders();
  });

  $scope.$on('$destroy', function(event) {
    SocketIO.removeAllListeners('answer');
  });

})

.controller('HomeCtrl', '$state', function($scope, $location, $state) {
  $http.get('app.json').success(function(data) {
    $scope.rooms = data;
    $scope.whichrooms = $state.params.three;
  }
})

.controller('OneCtrl', function($scope, $location) {
  $scope.$parent.logout_text = 'Home';

  $scope.one = function() {
    (function() {
    $location.path("/");
    });
  }
})

.controller('TwoCtrl', function($scope, $location) {

})

.controller('ThreeCtrl', function($scope, $location) {
  $scope.$state = $state;
})

.controller('AllCtrl', function($scope, $location) {

})

.controller('1B1Ctrl', function($scope, $location) {

})

.controller('1B2Ctrl', function($scope, $location) {

})

.controller('1B3Ctrl', function($scope, $location) {

})

.controller('2B1Ctrl', function($scope, $location) {

})

.controller('2B2Ctrl', function($scope, $location) {

})

.controller('2B3Ctrl', function($scope, $location) {

})
.controller('2B4Ctrl', function($scope, $location) {

})

.controller('2B5Ctrl', function($scope, $location) {

})

.controller('2B6Ctrl', function($scope, $location) {

})

.controller('3B1Ctrl', function($scope, $location) {

})

.controller('3B2Ctrl', function($scope, $location) {

})

.controller('3B3Ctrl', function($scope, $location) {

})
.controller('3B4Ctrl', function($scope, $location) {

})

.controller('3B5Ctrl', function($scope, $location) {

})

.controller('3B6Ctrl', function($scope, $location) {

})

.controller('MainCtrl', function($scope, $state, $ionicSideMenuDelegate) {
        "use strict";

        $scope.enterState = function(stateID) {
          console.log(stateID);
            $state.transitionTo(stateID);
        };

       //$scope.enterState('home');

        $scope.$state = $state;
    })
<commit_msg>Update controllers.js<commit_after>angular.module('starter.controllers', [])

.controller('AppCtrl', function($scope, $location, RegistrationService) {
  $scope.logout = function() {
    RegistrationService.logout();
    $location.path("/home");
  }
  $scope.timeleft = '0 secs';
})

.controller('RegisterCtrl', function($scope, $location, RegistrationService) {
  $scope.user = {
    name: '',
    email: '',
    password: '',
    password2: ''
  };

  $scope.$parent.logout_text = 'Logout';

  $scope.register = function() {
    RegistrationService.register($scope.user).then(function() {
      $location.path("/");
    })
  }
})

.controller('LoginCtrl', function($scope, $location, RegistrationService) {
  $scope.user = {
    email: '',
    password: ''
  };

  $scope.$parent.logout_text = 'Register';

  $scope.login = function() {
    RegistrationService.login($scope.user.email, $scope.user.password).then(function() {
      $location.path("/");
    });
  }

})

.controller('LeadersCtrl', function($scope, SocketIO, Answer) {
  $scope.leaders = Answer.leaders();

  SocketIO.on('answer', function(msg) {
    $scope.leaders = Answer.leaders();
  });

  $scope.$on('$destroy', function(event) {
    SocketIO.removeAllListeners('answer');
  });

})

.controller('ThreeCtrl', function($scope, $location) {

})

.controller('OneCtrl', function($scope, $location) {

})

.controller('TwoCtrl', function($scope, $location) {

})

.controller('HomeCtrl', '$http', '$state', function($scope, $location, $state, $http) {
  $http.get('app.json').success(function(data) {
    $scope.rooms = data;
    $scope.whichrooms = $state.params.three;
  }
})

.controller('AllCtrl', function($scope, $location) {

})

.controller('1B1Ctrl', function($scope, $location) {

})

.controller('1B2Ctrl', function($scope, $location) {

})

.controller('1B3Ctrl', function($scope, $location) {

})

.controller('2B1Ctrl', function($scope, $location) {

})

.controller('2B2Ctrl', function($scope, $location) {

})

.controller('2B3Ctrl', function($scope, $location) {

})
.controller('2B4Ctrl', function($scope, $location) {

})

.controller('2B5Ctrl', function($scope, $location) {

})

.controller('2B6Ctrl', function($scope, $location) {

})

.controller('3B1Ctrl', function($scope, $location) {

})

.controller('3B2Ctrl', function($scope, $location) {

})

.controller('3B3Ctrl', function($scope, $location) {

})
.controller('3B4Ctrl', function($scope, $location) {

})

.controller('3B5Ctrl', function($scope, $location) {

})

.controller('3B6Ctrl', function($scope, $location) {

})

.controller('MainCtrl', function($scope, $state, $ionicSideMenuDelegate) {
        "use strict";

        $scope.enterState = function(stateID) {
          console.log(stateID);
            $state.transitionTo(stateID);
        };

       //$scope.enterState('home');

        $scope.$state = $state;
    })
<|endoftext|>


<commit_before>var ZON = {};

ZON.Zone = function() {
  this.spawns = [];
  this.textures = [];
  this.tiles = [];
};

ZON.SpawnPoint = function() {
};

ZON.Tile = function() {
};

ZON.BLOCK = {
  INFO:         0,
  SPAWN_POINTS: 1,
  TEXTURES:     2,
  TILES:        3,
  ECONOMY:      4
};

ZON.TILE_ROTATION = {
  NONE:                 0,
  FLIP_HORIZONTAL:      2,
  FLIP_VERTICAL:        3,
  FLIP_BOTH:            4,
  CLOCKWISE_90:         5,
  COUNTER_CLOCKWISE_90: 6
};

ZON.Loader = {};
ZON.Loader.load = function(path, callback) {
  ROSELoader.load(path, function(rh) {
    var zone = new ZON.Zone();

    var blocks = rh.readUint32();
    for (var i = 0; i < blocks; ++i) {
      var type   = rh.readUint32();
      var offset = rh.readUint32();
      var pos    = rh.tell();

      switch(type) {
      case ZON.BLOCK.INFO:
        zone.type = rh.readUint32();
        zone.width = rh.readUint32();
        zone.height = rh.readUint32();
        zone.gridCount = rh.readUint32();
        zone.gridSize = rh.readFloat();
        zone.startX = rh.readUint32();
        zone.startY = rh.readUint32();
        // We don't care about the following position data
        break;
      case ZON.BLOCK.SPAWN_POINTS:
        var spawns = rh.readUint32();
        for (var j = 0; j < spawns; ++j) {
          var spawn = new ZON.SpawnPoint();
          spawn.position = rh.readVector3().multiplyScalar(ZZ_SCALE_IN);
          spawn.name = rh.readByteStr();
          zone.spawns.push(spawn);
        }
        break;
      case ZON.BLOCK.TEXTURES:
        var textures = rh.readUint32();
        for (var j = 0; j < textures; ++j) {
          zone.textures.push(rh.readByteStr());
        }
        break;
      case ZON.BLOCK.TILES:
        var tiles = rh.readUint32();
        for (var j = 0; j < tiles; ++j) {
          var tile = new ZON.Tile();
          tile.layer1  = rh.readUint32();
          tile.layer2  = rh.readUint32();
          tile.offset1 = rh.readUint32();
          tile.offset2 = rh.readUint32();
          tile.blend   = !!rh.readUint32();
          tile.rotation = rh.readUint32();
          tile.type = rh.readUint32();
          zone.tiles.push(tile);
        }
        break;
      case ZON.BLOCK.ECONOMY:
        zone.name                  = rh.readByteStr();
        zone.underground           = !!rh.readUint32();
        zone.backgroundMusicPath   = rh.readByteStr();
        zone.skyPath               = rh.readByteStr();
        // We don't care about the following economy data
        break;
      }
      rh.seek(pos);
    }
    callback(zone);
  });
};
<commit_msg>Refactor zon.js<commit_after>/**
 * @constructor
 * @property {String} name
 * @property {Number} type
 * @property {Number} width
 * @property {Number} height
 * @property {Number} gridCount
 * @property {Number} gridSize
 * @property {Number} startX
 * @property {Number} startY
 * @property {Boolean} underground
 * @property {String} backgroundMusicPath
 * @property {String} skyPath
 * @property {Zone.SpawnPoint[]} spawns
 * @property {Zone.Tile[]} tiles
 * @property {String[]} textures
 */
var Zone = function() {
  this.spawns = [];
  this.tiles = [];
  this.textures = [];
};

/**
 * @constructor
 * @property {THREE.Vector3} position
 * @property {String} name
 */
Zone.SpawnPoint = function() {
};

/**
 * @constructor
 * @property {Number} layer1
 * @property {Number} layer2
 * @property {Number} offset1
 * @property {Number} offset2
 * @property {Boolean} blend
 * @property {Zone.TILE_ROTATION} rotation
 * @property {Number} type
 */
Zone.Tile = function() {
};

/**
 * @enum {Number}
 * @readonly
 */
Zone.BLOCK = {
  INFO:         0,
  SPAWN_POINTS: 1,
  TEXTURES:     2,
  TILES:        3,
  ECONOMY:      4
};

/**
 * @enum {Number}
 * @readonly
 */
Zone.TILE_ROTATION = {
  NONE:                 0,
  FLIP_HORIZONTAL:      2,
  FLIP_VERTICAL:        3,
  FLIP_BOTH:            4,
  CLOCKWISE_90:         5,
  COUNTER_CLOCKWISE_90: 6
};

/**
 * @callback Zone~onLoad
 * @param {Zone} zone
 */

/**
 * @param {String} path
 * @param {Zone~onLoad} callback
 */
Zone.load = function(path, callback) {
  ROSELoader.load(path, function(/** BinaryReader */rh) {
    var blocks, i, j, data;
    data = new Zone();

    blocks = rh.readUint32();
    for (i = 0; i < blocks; ++i) {
      var type, offset, pos, count;
      type   = rh.readUint32();
      offset = rh.readUint32();
      pos    = rh.tell();

      rh.seek(offset);
      switch(type) {
      case Zone.BLOCK.INFO:
        data.type      = rh.readUint32();
        data.width     = rh.readUint32();
        data.height    = rh.readUint32();
        data.gridCount = rh.readUint32();
        data.gridSize  = rh.readFloat();
        data.startX    = rh.readUint32();
        data.startY    = rh.readUint32();
        break;
      case Zone.BLOCK.SPAWN_POINTS:
        count = rh.readUint32();
        for (j = 0; j < count; ++j) {
          var spawn = new Zone.SpawnPoint();
          spawn.position = rh.readVector3().multiplyScalar(ZZ_SCALE_IN);
          spawn.name     = rh.readByteStr();
          data.spawns.push(spawn);
        }
        break;
      case Zone.BLOCK.TEXTURES:
        count = rh.readUint32();
        for (j = 0; j < count; ++j) {
          data.textures.push(rh.readByteStr());
        }
        break;
      case Zone.BLOCK.TILES:
        count = rh.readUint32();
        for (j = 0; j < count; ++j) {
          var tile = new Zone.Tile();
          tile.layer1   = rh.readUint32();
          tile.layer2   = rh.readUint32();
          tile.offset1  = rh.readUint32();
          tile.offset2  = rh.readUint32();
          tile.blend    = rh.readUint32() !== 0;
          tile.rotation = rh.readUint32();
          tile.type     = rh.readUint32();
          data.tiles.push(tile);
        }
        break;
      case Zone.BLOCK.ECONOMY:
        data.name                = rh.readByteStr();
        data.underground         = rh.readUint32() !== 0;
        data.backgroundMusicPath = rh.readByteStr();
        data.skyPath             = rh.readByteStr();
        break;
      }
      rh.seek(pos);
    }
    callback(data);
  });
};
<|endoftext|>


<commit_before><commit_msg>Remove duplicated lines on JS application manifest<commit_after><|endoftext|>