diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d68eacc --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +**/.idea +*.iml +node_modules +bower_components +npm-debug.log +mongo-backup* +env.config.prod diff --git a/Procfile b/Procfile new file mode 100644 index 0000000..489b270 --- /dev/null +++ b/Procfile @@ -0,0 +1 @@ +web: node server.js diff --git a/README.md b/README.md new file mode 100644 index 0000000..f7487fd --- /dev/null +++ b/README.md @@ -0,0 +1,27 @@ +# fifa.tournament + +## Setup + +### Requirements +- Latest MongoDb. +- Latest npm version +- Latest nodejs version + +### Configuration +Configure the [env.config](env.config) file properly + +### Set up the database +```Shell +tar -xf backup/prod.backup_.tar.gz +mongorestore --drop -d fifa prod.backup_/heroku_/ +``` +Replace the tag by the actual latest backup filename + +## Running +```Shell +> mongod +> npm install +> node server.js +``` + +Developer information: ezequielbergamaschi@gmail.com diff --git a/app.css b/app.css deleted file mode 100644 index 30152be..0000000 --- a/app.css +++ /dev/null @@ -1,239 +0,0 @@ -.filterLabel { - margin-right:5px; -} - -.nav-justified > .active > a { - background-color:#ddd; -} - -.points { - background-color:#D9D9F1; -} -.won { - color:green; -} -.lost { - color:red; -} -.tie { - color:black; -} - -.img-circle { - cursor:pointer; - height:48px; - width:48px; - vertical-align:middle!important; -} - -ul { - margin-top:10px; -} - -.middleData td { - vertical-align:middle!important; -} - -td { - font-size:24px; -} - -.player { - background-image: url(players.png); - background-repeat: no-repeat; -} - -.Ariel { - width: 48px; - height: 48px; - background-position: -5px -5px; -} - -.Charly { - width: 48px; - height: 48px; - background-position: -63px -5px; -} - -.Cristian { - width: 48px; - height: 48px; - background-position: -121px -5px; -} - -.DaniG { - width: 48px; - height: 48px; - background-position: -179px -5px; -} - -.Ezequiel { - width: 48px; - height: 48px; - background-position: -5px -63px; -} - -.FerO { - width: 48px; - height: 48px; - background-position: -63px -63px; -} - -.FerP { - width: 48px; - height: 48px; - background-position: -121px -63px; -} - -.Gaby { - width: 48px; - height: 48px; - background-position: -179px -63px; -} - -.Gamba { - width: 48px; - height: 48px; - background-position: -5px -121px; -} - -.Hernan { - width: 48px; - height: 48px; - background-position: -63px -121px; -} - -.Juan { - width: 48px; - height: 48px; - background-position: -121px -121px; -} - -.Leandro { - width: 48px; - height: 48px; - background-position: -179px -121px; -} - -.Leo { - width: 48px; - height: 48px; - background-position: -5px -179px; -} - -.Malcolm { - width: 48px; - height: 48px; - background-position: -63px -179px; -} - -.Martin { - width: 48px; - height: 48px; - background-position: -121px -179px; -} - -.Mauri { - width: 48px; - height: 48px; - background-position: -179px -179px; -} - -.Michu { - width: 48px; - height: 48px; - background-position: -237px -5px; -} - -.NicoL { - width: 48px; - height: 48px; - background-position: -237px -63px; -} - -.NicoR { - width: 48px; - height: 48px; - background-position: -237px -121px; -} - -.PabloC { - width: 48px; - height: 48px; - background-position: -237px -179px; -} - -.Santi { - width: 48px; - height: 48px; - background-position: -5px -237px; -} - -.Sebastian { - width: 48px; - height: 48px; - background-position: -63px -237px; -} - -.team { - width:57px; - height:50px; - display:inline-block; - vertical-align:middle!important; -} - -.Argentina { -background-image:url(http://www.fifa.com/imgml/flags/reflected/m/arg.png); -} - -.Alemania { -background-image:url(http://www.fifa.com/imgml/flags/reflected/m/ger.png); -} - -.Brasil { -background-image:url(http://www.fifa.com/imgml/flags/reflected/m/bra.png); -} - -.Espana { -background-image:url(http://www.fifa.com/imgml/flags/reflected/m/esp.png); -} - -.Francia { -background-image:url(http://www.fifa.com/imgml/flags/reflected/m/fra.png); -} - -.Holanda { -background-image:url(http://www.fifa.com/imgml/flags/reflected/m/ned.png); -} - -.Inglaterra { -background-image:url(http://www.fifa.com/imgml/flags/reflected/m/eng.png); -} - -.Italia { -background-image:url(http://www.fifa.com/imgml/flags/reflected/m/ita.png); -} - -.Mexico { -background-image:url(http://www.fifa.com/imgml/flags/reflected/m/mex.png); -} - -.Uruguay { -background-image:url(http://www.fifa.com/imgml/flags/reflected/m/uru.png); -} - -.Colombia { -background-image:url(http://www.fifa.com/imgml/flags/reflected/m/col.png); -} - -.CdMarfil { -background-image:url(http://www.fifa.com/imgml/flags/reflected/m/civ.png); -} - -.EEUU { -background-image:url(http://www.fifa.com/imgml/flags/reflected/m/usa.png); -} - -.Portugal { -background-image:url(http://www.fifa.com/imgml/flags/reflected/m/por.png); -} \ No newline at end of file diff --git a/app.js b/app.js deleted file mode 100644 index 961565a..0000000 --- a/app.js +++ /dev/null @@ -1,2638 +0,0 @@ -angular.module('fifa', []) - .filter('matchFilter', function() { - return function(matches, filter) { - var out = []; - var index; - if (filter.length == 0) { - return matches; - } - for (index = 0; index < matches.length; ++index) { - var match = matches[index]; - var hasAllPlayers = true; - for (j = 0; j < filter.length && hasAllPlayers; ++j) { - hasAllPlayers = match.home.players.indexOf(filter[j]) != -1 - || match.away.players.indexOf(filter[j]) != -1; - } - if (hasAllPlayers) { - out.push(match); - } - } - return out; - } - }) - .filter('tagFilter', function() { - return function(matches, tagFilter) { - var out = []; - var index; - var index = tagFilter.indexOf("Historico"); - if (index != -1) { - tagFilter.splice("Historico", 1); - } - if (tagFilter.length == 0 || (tagFilter.length == 1 && tagFilter[0] == "")) { - return matches; - } - - for (index = 0; index < matches.length; ++index) { - var match = matches[index]; - var hasAllTags = true; - for (j = 0; j < tagFilter.length && hasAllTags; ++j) { - hasAllTags = match.tags.indexOf(tagFilter[j]) != -1; - } - if (hasAllTags) { - out.push(match); - } - } - return out; - } - }) - .service('dataService',['$http', function ($http) { - this.t = $http.get('matches.json'); - }]) -.controller('MainCtrl', ['$scope','dataService', function($scope, dataService){ - $scope.addPlayer = function(player) { - if ($scope.players.indexOf(player) == -1) { - $scope.players.push(player); - } - }; - $scope.removePlayer = function(player) { - var index = $scope.players.indexOf(player); - if (index != -1) { - $scope.players.splice(index, 1); - } - } - $scope.addTagFilter = function(tag) { - if ($scope.tagFilters.indexOf(tag) == -1) { - $scope.tagFilters.push(tag); - } - } - $scope.removeTagFilter = function(tag) { - var index = $scope.tagFilters.indexOf(tag); - if (index != -1) { - $scope.tagFilters.splice(tag, 1); - } - } - $scope.selectTournament = function(tournament) { - $scope.theTournament = tournament; - var phase = $scope.tournamentsConfig[tournament].defaultPhase; - if (!phase) { - phase = ''; - } - $scope.selectPhase(phase); - } - $scope.selectPhase = function(phase) { - $scope.tagFilters = []; - $scope.players = []; - $scope.thePhase = phase; - $scope.addTagFilter(phase); - }; - $scope.initPosition = function(players) { - return { - players: players, - matchesPlayed:0, - matchesWon:0, - matchesTied:0, - matchesLost:0, - goalsScored:0, - goalsReceived:0, - goalsDiff: 0, - points:0, - }; - } - - $scope.processMatchTeam = function(standings, team, goalsReceived) { - var position = standings[team.team + team.players]; - if (!position) { - position = $scope.initPosition(team.players); - position["team"] = team.team; - standings[team.team + team.players] = position; - } - - $scope.updatePosition(position, team.goals, goalsReceived); - } - - $scope.processMatchIndividualWithSupport = function(standings, team, goalsReceived) { - var position = $scope.processIndividual(standings, team.players[0], team.goals, goalsReceived); - position["team"] = team.team; - } - - $scope.processMatchIndividual = function(standings, team, goalsReceived) { - $scope.processIndividual(standings, team.players[0], team.goals, goalsReceived); - $scope.processIndividual(standings, team.players[1], team.goals, goalsReceived); - } - - $scope.processIndividual = function(standings, player, goalsScored, goalsReceived) { - var position = standings[player]; - if (!position) { - position = $scope.initPosition([player]); - standings[player] = position; - } - return $scope.updatePosition(position, goalsScored, goalsReceived); - } - - $scope.updatePosition = function(position, goalsScored, goalsReceived) { - position.matchesPlayed = position.matchesPlayed + 1; - - var won = goalsScored > goalsReceived ? 1 : 0; - position.matchesWon = position.matchesWon + won; - - var tied = goalsScored == goalsReceived ? 1 : 0; - position.matchesTied = position.matchesTied + tied; - - var lost = goalsScored < goalsReceived ? 1 : 0; - position.matchesLost = position.matchesLost + lost; - - position.goalsScored = position.goalsScored + goalsScored; - position.goalsReceived = position.goalsReceived + goalsReceived; - position.goalsDiff = position.goalsScored - position.goalsReceived; - - position.points = position.points + (won * 3) + tied; - return position; - } - - $scope.comparePositions = function(aPosition, anotherPosition) { - var order = anotherPosition.points - aPosition.points; - if (order == 0) { - order = anotherPosition.goalsDiff - aPosition.goalsDiff; - if (order == 0) { - order = anotherPosition.goalsScored - aPosition.goalsScored; - } - } - return order; - } - $scope.standingsCache = {}; - - $scope.calculateStandings = function(tournament, phase, matches) { - if (!$scope.hasStandings(tournament, phase)) { - return []; - } - - var positions = $scope.standingsCache[tournament + phase]; - if (positions) { - return positions; - } - - var standingCalcFunction = $scope.standingsModel(tournament, phase); - var standings = {}; - for (var i = matches.length - 1; i >= 0; i--) { - var match = matches[i]; - standingCalcFunction(standings, match.home, match.away.goals); - standingCalcFunction(standings, match.away, match.home.goals); - } - positions = new Array(); - - for (var key in standings) { - positions.push(standings[key]); - } - positions.sort($scope.comparePositions); - $scope.standingsCache[tournament + phase] = positions; - return positions; - }; - - $scope.standingsModel = function(theTournament, thePhase) { - var model = $scope.tournamentsConfig[theTournament].standingsModel; - var standingCalcFunction; - switch(model) { - case "Team": - standingCalcFunction = $scope.processMatchTeam; - break; - case "Individual": - standingCalcFunction = $scope.processMatchIndividual; - break; - case "IndividualWithSupport": - standingCalcFunction = $scope.processMatchIndividualWithSupport; - break; - default: - standingCalcFunction = function(){}; - } - return standingCalcFunction; - }; - - $scope.hasStandings = function(theTournament, thePhase) { - return $scope.tournamentsConfig[theTournament].phasesWithStandings.indexOf(thePhase) != -1; - }; - - //Data - $scope.tournaments =["Mundial 2", "Torneo 4", "Torneo 3", "Mundial 1", "Torneo 2", "Torneo 1", "Torneo 0", "Historico"]; - $scope.tournamentsConfig = { - "Mundial 2" : { - "phases" : ["Grupo A", "Grupo B", "Semifinales", "Final"], - "defaultPhase" : "Grupo A", - "phasesWithStandings" : ["Grupo A", "Grupo B"], - "standingsModel" : "Team" - }, - "Torneo 4" : { - "phases" : ["Primera", "Segunda", "Tercera"], - "defaultPhase" : "Primera", - "phasesWithStandings" : ["Primera", "Segunda", "Tercera"], - "standingsModel" : "Individual" - }, - "Torneo 3" : { - "phases" : ["Primera", "Segunda"], - "defaultPhase" : "Primera", - "phasesWithStandings" : ["Primera", "Segunda"], - "standingsModel" : "Individual" - }, - "Mundial 1" : { - "phases" : ["Grupo A", "Grupo B", "Grupo C", "Grupo D", "Cuartos de final", "Semifinal", "Tercer Puesto", "Final"], - "defaultPhase" : "Grupo A", - "phasesWithStandings" : ["Grupo A", "Grupo B", "Grupo C", "Grupo D"], - "standingsModel" : "IndividualWithSupport" - }, - "Torneo 2" : { - "phases" : ["Primera", "Segunda"], - "defaultPhase" : "Primera", - "phasesWithStandings" : ["Primera", "Segunda"], - "standingsModel" : "Individual" - }, - "Torneo 1" : { - "phases" : ["Primera", "Segunda"], - "defaultPhase" : "Primera", - "phasesWithStandings" : ["Primera", "Segunda"], - "standingsModel" : "Individual" - }, - "Torneo 0" : { - "phases" : ["Primera"], - "defaultPhase" : "Primera", - "phasesWithStandings" : ["Primera"], - "standingsModel" : "Team" - }, - "Historico" : { - "phases" : [], - "defaultPhase" : "", - "phasesWithStandings" : [], - }, - }; - - $scope.players = []; - $scope.tagFilters = []; - $scope.selectTournament("Mundial 2"); - $scope.loadMatches = function () { - return dataService.t; - }; - - $scope.homeResulsClass = function(match) { - if (match.home.goals > match.away.goals) { - return "won"; - } else if (match.home.goals < match.away.goals) { - return "lost" - } else { - return "tie"; - } - }; - $scope.awayResulsClass = function(match) { - if (match.away.goals > match.home.goals) { - return "won"; - } else if (match.away.goals < match.home.goals) { - return "lost" - } else { - return "tie"; - } - }; - $scope.matches = [ - { - date:'', - home: { - players: ["Charly", "Juan"], - team:"Inglaterra", - goals: -1 - }, - away: { - players: ["Hernan", "Gaby"], - team:"Argentina", - goals: -1 - }, - tags:["Mundial 2", "Grupo A"], - }, - { - date:'', - home: { - players: ["Charly", "Juan"], - team:"Inglaterra", - goals: 0 - }, - away: { - players: ["FerO", "Mauri"], - team:"Francia", - goals: 0 - }, - tags:["Mundial 2", "Grupo A"], - }, - { - date:'', - home: { - players: ["Charly", "Juan"], - team:"Inglaterra", - goals: 0 - }, - away: { - players: ["Leandro", "Santi"], - team:"Brasil", - goals: 1 - }, - tags:["Mundial 2", "Grupo A"], - }, - { - date:'', - home: { - players: ["Leandro", "Santi"], - team:"Brasil", - goals: 5 - }, - away: { - players: ["FerO", "Mauri"], - team:"Francia", - goals: 2 - }, - tags:["Mundial 2", "Grupo A"], - }, - { - date:'', - home: { - players: ["Leandro", "Santi"], - team:"Brasil", - goals: 2 - }, - away: { - players: ["Hernan", "Gaby"], - team:"Argentina", - goals: 2 - }, - tags:["Mundial 2", "Grupo A"], - }, - { - date:'', - home: { - players: ["FerO", "Mauri"], - team:"Francia", - goals: 1 - }, - away: { - players: ["Hernan", "Gaby"], - team:"Argentina", - goals: 0 - }, - tags:["Mundial 2", "Grupo A"], - }, - { - date:'2014-10-06T18:00:00.000Z', - home: { - players: ["NicoR", "NicoL"], - team:"Alemania", - goals: 4 - }, - away: { - players: ["Ariel", "Leo"], - team:"Espana", - goals: 1 - }, - tags:["Mundial 2", "Grupo B"], - }, - { - date:'2014-10-03T20:00:00.000Z', - home: { - players: ["NicoR", "NicoL"], - team:"Alemania", - goals: 4 - }, - away: { - players: ["DaniG", "Malcom"], - team:"Italia", - goals: 0 - }, - tags:["Mundial 2", "Grupo B"] - }, - { - date:'2014-10-03T20:00:00.000Z', - home: { - players: ["NicoR", "NicoL"], - team:"Alemania", - goals: 2 - }, - away: { - players: ["Michu", "FerP"], - team:"Holanda", - goals: 0 - }, - tags:["Mundial 2", "Grupo B"], - }, - { - date:'2014-10-03T20:00:00.000Z', - home: { - players: ["Ariel", "Leo"], - team:"Espana", - goals: 1 - }, - away: { - players: ["DaniG", "Malcom"], - team:"Italia", - goals: 1 - }, - tags:["Mundial 2", "Grupo B"] - }, - { - date:'2014-10-03T20:00:00.000Z', - home: { - players: ["Ariel", "Leo"], - team:"Espana", - goals: 2 - }, - away: { - players: ["Michu", "FerP"], - team:"Holanda", - goals: 0 - }, - tags:["Mundial 2", "Grupo B"] - }, - { - date:'2014-10-03T20:00:00.000Z', - home: { - players: ["DaniG", "Malcom"], - team:"Italia", - goals: 2 - }, - away: { - players: ["Michu", "FerP"], - team:"Holanda", - goals: 1 - }, - tags:["Mundial 2", "Grupo B"] - }, - { - date:'', - home: { - players: ["Leandro", "Santi"], - team:"Brasil", - goals: 3 - }, - away: { - players: ["Leo", "Ariel"], - team:"Espana", - goals: 1 - }, - tags:["Mundial 2", "Semifinales"], - }, - { - date:'', - home: { - players: ["Mauri", "Martin"], - team:"Francia", - goals: 2 - }, - away: { - players: ["NicoR", "NicoL"], - team:"Alemania", - goals: 1 - }, - tags:["Mundial 2", "Semifinales"], - }, - { - date:'', - home: { - players: ["Leandro", "Santi"], - team:"Brasil", - goals: 2 - }, - away: { - players: ["Mauri", "Martin"], - team:"Francia", - goals: 0 - }, - tags:["Mundial 2", "Final"], - }, - { - date:'', - home: { - players: ["NicoR", "DaniG"], - team:"", - goals: 1 - }, - away: { - players: ["Mauri", "FerO"], - team:"", - goals: 1 - }, - tags:["Torneo 0", "Primera"], - }, - { - date:'', - home: { - players: ["Michu", "Charly"], - team:"", - goals: 0 - }, - away: { - players: ["Leo", "Gaby"], - team:"", - goals: 3 - }, - tags:["Torneo 0", "Primera"], - }, - { - date:'', - home: { - players: ["NicoR", "DaniG"], - team:"", - goals: 3 - }, - away: { - players: ["Michu", "Charly"], - team:"", - goals: 0 - }, - tags:["Torneo 0", "Primera"], - }, - { - date:'', - home: { - players: ["Mauri", "FerO"], - team:"", - goals: 1 - }, - away: { - players: ["Leo", "Gaby"], - team:"", - goals: 1 - }, - tags:["Torneo 0", "Primera"], - }, - { - date:'', - home: { - players: ["NicoR", "DaniG"], - team:"", - goals: 0 - }, - away: { - players: ["Leo", "Gaby"], - team:"", - goals: 1 - }, - tags:["Torneo 0", "Primera"], - }, - { - date:'', - home: { - players: ["Mauri", "FerO"], - team:"", - goals: 2 - }, - away: { - players: ["Michu", "Charly"], - team:"", - goals: 1 - }, - tags:["Torneo 0", "Primera"], - }, - { - date:'', - home: { - players: ["NicoR", "DaniG"], - team:"", - goals: 1 - }, - away: { - players: ["Malcom", "Gamba"], - team:"", - goals: 1 - }, - tags:["Torneo 0", "Primera"], - }, - { - date:'', - home: { - players: ["Mauri", "FerO"], - team:"", - goals: 0 - }, - away: { - players: ["Malcom", "Gamba"], - team:"", - goals: 0 - }, - tags:["Torneo 0", "Primera"], - }, - { - date:'', - home: { - players: ["Michu", "Charly"], - team:"", - goals: 0 - }, - away: { - players: ["Malcom", "Gamba"], - team:"", - goals: 0 - }, - tags:["Torneo 0", "Primera"], - }, - { - date:'', - home: { - players: ["Leo", "Gaby"], - team:"", - goals: 2 - }, - away: { - players: ["Malcom", "Gamba"], - team:"", - goals: 1 - }, - tags:["Torneo 0", "Primera"], - }, - { - date:'', - home: { - players: ["NicoR", "Gaby"], - team:"", - goals: 1 - }, - away: { - players: ["Michu", "Mauri"], - team:"", - goals: 1 - }, - tags:["Torneo 1", "Primera"], - }, - { - date:'', - home: { - players: ["Leo", "Michu"], - team:"", - goals: 0 - }, - away: { - players: ["Gaby", "Mauri"], - team:"", - goals: 1 - }, - tags:["Torneo 1", "Primera"], - }, - { - date:'', - home: { - players: ["Leo", "Mauri"], - team:"", - goals: 2 - }, - away: { - players: ["NicoR", "Michu"], - team:"", - goals: 4 - }, - tags:["Torneo 1", "Primera"], - }, - { - date:'', - home: { - players: ["Leo", "Gaby"], - team:"", - goals: 1 - }, - away: { - players: ["NicoR", "Mauri"], - team:"", - goals: 4 - }, - tags:["Torneo 1", "Primera"], - }, - { - date:'', - home: { - players: ["Leo", "NicoR"], - team:"", - goals: 2 - }, - away: { - players: ["Gaby", "Michu"], - team:"", - goals: 1 - }, - tags:["Torneo 1", "Primera"], - }, - { - date:'', - home: { - players: ["Juan", "DaniG"], - team:"", - goals: 5 - }, - away: { - players: ["FerO", "Gamba"], - team:"", - goals: 0 - }, - tags:["Torneo 1", "Segunda"], - }, - { - date:'', - home: { - players: ["Juan", "DaniG"], - team:"", - goals: 0 - }, - away: { - players: ["Charly", "Malcom"], - team:"", - goals: 0 - }, - tags:["Torneo 1", "Segunda"], - }, - { - date:'', - home: { - players: ["FerO", "Gamba"], - team:"", - goals: 0 - }, - away: { - players: ["Charly", "Malcom"], - team:"", - goals: 1 - }, - tags:["Torneo 1", "Segunda"], - }, - { - date:'2014-03-10T00:00:00.000Z', - home:{ - players:["Mauri", "Michu"], - team:"", - goals: 4 - }, - away:{ - players:["Juan", "Charly"], - team:"", - goals: 0 - }, - tags: ["Torneo 2", "Primera"], - }, - { - date:'2014-03-11T00:00:00.000Z', - home:{ - players:["Mauri", "Juan"], - team:"", - goals: 4 - }, - away:{ - players:["Michu", "Charly"], - team:"", - goals: 0 - }, - tags: ["Torneo 2", "Primera"], - }, - { - date:'2014-03-07T00:00:00.000Z', - home:{ - players:["Mauri", "Charly"], - team:"", - goals: 1 - }, - away:{ - players:["Michu", "Juan"], - team:"", - goals: 3 - }, - tags: ["Torneo 2", "Primera"], - }, - { - date:'2014-03-11T00:00:00.000Z', - home:{ - players:["NicoR", "Mauri"], - team:"", - goals: 1 - }, - away:{ - players:["Juan", "Charly"], - team:"", - goals: 0 - }, - tags: ["Torneo 2", "Primera"], - }, - { - date:'2014-03-06T00:00:00.000Z', - home:{ - players:["NicoR", "Juan"], - team:"", - goals: 4 - }, - away:{ - players:["Mauri", "Charly"], - team:"", - goals: 0 - }, - tags: ["Torneo 2", "Primera"], - }, - { - date:'2014-03-14T00:00:00.000Z', - home:{ - players:["NicoR", "Charly"], - team:"", - goals: 0 - }, - away:{ - players:["Mauri", "Juan"], - team:"", - goals: 5 - }, - tags: ["Torneo 2", "Primera"], - }, - { - date:'2014-03-12T00:00:00.000Z', - home:{ - players:["NicoR", "Mauri"], - team:"", - goals: 3 - }, - away:{ - players:["Michu", "Juan"], - team:"", - goals: 0 - }, - tags: ["Torneo 2", "Primera"], - }, - { - date:'2014-02-28T00:00:00.000Z', - home:{ - players:["NicoR", "Michu"], - team:"", - goals: 3 - }, - away:{ - players:["Mauri", "Juan"], - team:"", - goals: 3 - }, - tags: ["Torneo 2", "Primera"], - }, - { - date:'2014-02-26T00:00:00.000Z', - home:{ - players:["NicoR", "Juan"], - team:"", - goals: 4 - }, - away:{ - players:["Mauri", "Michu"], - team:"", - goals: 3 - }, - tags: ["Torneo 2", "Primera"], - }, - { - date:'2014-02-24T00:00:00.000Z', - home:{ - players:["NicoR", "Michu"], - team:"", - goals: 2 - }, - away:{ - players:["Juan", "Charly"], - team:"", - goals: 0 - }, - tags: ["Torneo 2", "Primera"], - }, - { - date:'2014-03-14T00:00:00.000Z', - home:{ - players:["NicoR", "Juan"], - team:"", - goals: 2 - }, - away:{ - players:["Michu", "Charly"], - team:"", - goals: 0 - }, - tags: ["Torneo 2", "Primera"], - }, - { - date:'2014-03-14T00:00:00.000Z', - home:{ - players:["NicoR", "Charly"], - team:"", - goals: 0 - }, - away:{ - players:["Michu", "Juan"], - team:"", - goals: 1 - }, - tags: ["Torneo 2", "Primera"], - }, - { - date:'2014-03-05T00:00:00.000Z', - home:{ - players:["NicoR", "Mauri"], - team:"", - goals: 3 - }, - away:{ - players:["Michu", "Charly"], - team:"", - goals: 0 - }, - tags: ["Torneo 2", "Primera"], - }, - { - date:'2014-03-05T00:00:00.000Z', - home:{ - players:["NicoR", "Michu"], - team:"", - goals: 4 - }, - away:{ - players:["Mauri", "Charly"], - team:"", - goals: 2 - }, - tags: ["Torneo 2", "Primera"], - }, - { - date:'2014-03-12T00:00:00.000Z', - home:{ - players:["NicoR", "Charly"], - team:"", - goals: 1 - }, - away:{ - players:["Mauri", "Michu"], - team:"", - goals: 2 - }, - tags: ["Torneo 2", "Primera"], - }, - { - date:'2014-03-11T00:00:00.000Z', - home:{ - players:["Malcom", "Gamba"], - team:"", - goals: 2 - }, - away:{ - players:["DaniG", "FerO"], - team:"", - goals: 0 - }, - tags: ["Torneo 2", "Segunda"], - }, - { - date:'2014-03-07T00:00:00.000Z', - home:{ - players:["Malcom", "Gamba"], - team:"", - goals: 0 - }, - away:{ - players:["Gaby", "Leo"], - team:"", - goals: 3 - }, - tags: ["Torneo 2", "Segunda"], - }, - { - date:'2014-03-07T00:00:00.000Z', - home:{ - players:["DaniG", "FerO"], - team:"", - goals: 1 - }, - away:{ - players:["Gaby", "Leo"], - team:"", - goals: 3 - }, - tags: ["Torneo 2", "Segunda"], - }, - { - date:'2014-03-07T00:00:00.000Z', - home:{ - players:["Malcom", "Gamba"], - team:"", - goals: -1 - }, - away:{ - players:["DaniG", "Gaby"], - team:"", - goals: -1 - }, - tags: ["Torneo 2", "Segunda"], - }, - { - date:'2014-03-11T00:00:00.000Z', - home:{ - players:["Malcom", "Gamba"], - team:"", - goals: 1 - }, - away:{ - players:["DaniG", "Leo"], - team:"", - goals: 2 - }, - tags: ["Torneo 2", "Segunda"], - }, - { - date:'2014-02-28T00:00:00.000Z', - home:{ - players:["Malcom", "Gamba"], - team:"", - goals: 2 - }, - away:{ - players:["Gaby", "FerO"], - team:"", - goals: 1 - }, - tags: ["Torneo 2", "Segunda"], - }, - { - date:'2014-03-14T00:00:00.000Z', - home:{ - players:["Malcom", "Gamba"], - team:"", - goals: 0 - }, - away:{ - players:["Leo", "FerO"], - team:"", - goals: 4 - }, - tags: ["Torneo 2", "Segunda"], - }, - { - date:'2014-02-24T00:00:00.000Z', - home:{ - players:["DaniG", "FerO"], - team:"", - goals: 1 - }, - away:{ - players:["Malcom", "Gaby"], - team:"", - goals: 1 - }, - tags: ["Torneo 2", "Segunda"], - }, - { - date:'2014-03-13T00:00:00.000Z', - home:{ - players:["DaniG", "FerO"], - team:"", - goals: -1 - }, - away:{ - players:["Malcom", "Leo"], - team:"", - goals: -1 - }, - tags: ["Torneo 2", "Segunda"], - }, - { - date:'2014-03-06T00:00:00.000Z', - home:{ - players:["DaniG", "FerO"], - team:"", - goals: 2 - }, - away:{ - players:["Gaby", "Gamba"], - team:"", - goals: 4 - }, - tags: ["Torneo 2", "Segunda"], - }, - { - date:'2014-03-13T00:00:00.000Z', - home:{ - players:["DaniG", "FerO"], - team:"", - goals: 1 - }, - away:{ - players:["Leo", "Gamba"], - team:"", - goals: 2 - }, - tags: ["Torneo 2", "Segunda"], - }, - { - date:'2014-02-26T00:00:00.000Z', - home:{ - players:["Gaby", "Leo"], - team:"", - goals: 2 - }, - away:{ - players:["Malcom", "DaniG"], - team:"", - goals: 0 - }, - tags: ["Torneo 2", "Segunda"], - }, - { - date:'2014-02-27T00:00:00.000Z', - home:{ - players:["Gaby", "Leo"], - team:"", - goals: 2 - }, - away:{ - players:["Malcom", "FerO"], - team:"", - goals: 2 - }, - tags: ["Torneo 2", "Segunda"], - }, - { - date:'2014-02-25T00:00:00.000Z', - home:{ - players:["Gaby", "Leo"], - team:"", - goals: 4 - }, - away:{ - players:["DaniG", "Gamba"], - team:"", - goals: 0 - }, - tags: ["Torneo 2", "Segunda"], - }, - { - date:'2014-02-27T00:00:00.000Z', - home:{ - players:["Gaby", "Leo"], - team:"", - goals: 4 - }, - away:{ - players:["FerO", "Gamba"], - team:"", - goals: 0 - }, - tags: ["Torneo 2", "Segunda"], - }, - { - date:'', - home:{ - players:["Mauri", "Juan"], - team:"", - goals: 2 - }, - away:{ - players:["Leo", "Gaby"], - team:"", - goals: 1 - }, - tags: ["Torneo 3", "Primera"], - }, - { - date:'', - home:{ - players:["Mauri", "Leo"], - team:"", - goals: 0 - }, - away:{ - players:["Juan", "Gaby"], - team:"", - goals: 1 - }, - tags: ["Torneo 3", "Primera"], - }, - { - date:'', - home:{ - players:["Mauri", "Gaby"], - team:"", - goals: 1 - }, - away:{ - players:["Juan", "Leo"], - team:"", - goals: 3 - }, - tags: ["Torneo 3", "Primera"], - }, - { - date:'', - home:{ - players:["NicoR", "Mauri"], - team:"", - goals: 0 - }, - away:{ - players:["Leo", "Gaby"], - team:"", - goals: 2 - }, - tags: ["Torneo 3", "Primera"], - }, - { - date:'', - home:{ - players:["NicoR", "Leo"], - team:"", - goals: 1 - }, - away:{ - players:["Mauri", "Gaby"], - team:"", - goals: 6 - }, - tags: ["Torneo 3", "Primera"], - }, - { - date:'', - home:{ - players:["NicoR", "Gaby"], - team:"", - goals: 3 - }, - away:{ - players:["Mauri", "Leo"], - team:"", - goals: 1 - }, - tags: ["Torneo 3", "Primera"], - }, - { - date:'', - home:{ - players:["NicoR", "Mauri"], - team:"", - goals: 0 - }, - away:{ - players:["Juan", "Leo"], - team:"", - goals: 0 - }, - tags: ["Torneo 3", "Primera"], - }, - { - date:'', - home:{ - players:["NicoR", "Juan"], - team:"", - goals: 1 - }, - away:{ - players:["Mauri", "Leo"], - team:"", - goals: 0 - }, - tags: ["Torneo 3", "Primera"], - }, - { - date:'', - home:{ - players:["NicoR", "Leo"], - team:"", - goals: 1 - }, - away:{ - players:["Mauri", "Juan"], - team:"", - goals: 4 - }, - tags: ["Torneo 3", "Primera"], - }, - { - date:'', - home:{ - players:["NicoR", "Juan"], - team:"", - goals: 0 - }, - away:{ - players:["Leo", "Gaby"], - team:"", - goals: 3 - }, - tags: ["Torneo 3", "Primera"], - }, - { - date:'', - home:{ - players:["NicoR", "Leo"], - team:"", - goals: 3 - }, - away:{ - players:["Juan", "Gaby"], - team:"", - goals: 1 - }, - tags: ["Torneo 3", "Primera"], - }, - { - date:'', - home:{ - players:["NicoR", "Gaby"], - team:"", - goals: 1 - }, - away:{ - players:["Juan", "Leo"], - team:"", - goals: 2 - }, - tags: ["Torneo 3", "Primera"], - }, - { - date:'', - home:{ - players:["NicoR", "Mauri"], - team:"", - goals: 3 - }, - away:{ - players:["Juan", "Gaby"], - team:"", - goals: 1 - }, - tags: ["Torneo 3", "Primera"], - }, - { - date:'', - home:{ - players:["NicoR", "Juan"], - team:"", - goals: 1 - }, - away:{ - players:["Mauri", "Gaby"], - team:"", - goals: 2 - }, - tags: ["Torneo 3", "Primera"], - }, - { - date:'', - home:{ - players:["NicoR", "Gaby"], - team:"", - goals: 3 - }, - away:{ - players:["Mauri", "Juan"], - team:"", - goals: 3 - }, - tags: ["Torneo 3", "Primera"], - }, - { - date:'2014-07-31T00:00:00.000Z', - home:{ - players:["Malcom", "Santi"], - team:"", - goals: 1 - }, - away:{ - players:["Michu", "FerO"], - team:"", - goals: 2 - }, - tags: ["Torneo 3", "Segunda"], - }, - { - date:'2014-08-01T00:00:00.000Z', - home:{ - players:["Malcom", "Santi"], - team:"", - goals: 2 - }, - away:{ - players:["Charly", "Hernan"], - team:"", - goals: 1 - }, - tags: ["Torneo 3", "Segunda"], - }, - { - date:'2014-07-30T00:00:00.000Z', - home:{ - players:["Michu", "FerO"], - team:"", - goals: 0 - }, - away:{ - players:["Charly", "Hernan"], - team:"", - goals: 1 - }, - tags: ["Torneo 3", "Segunda"], - }, - { - date:'2014-07-28T00:00:00.000Z', - home:{ - players:["Malcom", "Santi"], - team:"", - goals: 2 - }, - away:{ - players:["Michu", "Charly"], - team:"", - goals: 0 - }, - tags: ["Torneo 3", "Segunda"], - }, - { - date:'2014-07-23T00:00:00.000Z', - home:{ - players:["Malcom", "Santi"], - team:"", - goals: 1 - }, - away:{ - players:["Michu", "Hernan"], - team:"", - goals: 1 - }, - tags: ["Torneo 3", "Segunda"], - }, - { - date:'2014-07-21T00:00:00.000Z', - home:{ - players:["Malcom", "Santi"], - team:"", - goals: 3 - }, - away:{ - players:["Charly", "FerO"], - team:"", - goals: 0 - }, - tags: ["Torneo 3", "Segunda"], - }, - { - date:'2014-07-03T00:00:00.000Z', - home:{ - players:["Malcom", "Santi"], - team:"", - goals: 1 - }, - away:{ - players:["Hernan", "FerO"], - team:"", - goals: 1 - }, - tags: ["Torneo 3", "Segunda"], - }, - { - date:'2014-07-07T00:00:00.000Z', - home:{ - players:["Michu", "FerO"], - team:"", - goals: 1 - }, - away:{ - players:["Malcom", "Charly"], - team:"", - goals: 0 - }, - tags: ["Torneo 3", "Segunda"], - }, - { - date:'2014-07-24T00:00:00.000Z', - home:{ - players:["Michu", "FerO"], - team:"", - goals: 0 - }, - away:{ - players:["Malcom", "Hernan"], - team:"", - goals: 0 - }, - tags: ["Torneo 3", "Segunda"], - }, - { - date:'2014-07-22T00:00:00.000Z', - home:{ - players:["Michu", "FerO"], - team:"", - goals: 1 - }, - away:{ - players:["Charly", "Santi"], - team:"", - goals: 0 - }, - tags: ["Torneo 3", "Segunda"], - }, - { - date:'2014-07-10T00:00:00.000Z', - home:{ - players:["Michu", "FerO"], - team:"", - goals: 2 - }, - away:{ - players:["Hernan", "Santi"], - team:"", - goals: 2 - }, - tags: ["Torneo 3", "Segunda"], - }, - { - date:'2014-07-08T00:00:00.000Z', - home:{ - players:["Charly", "Hernan"], - team:"", - goals: 0 - }, - away:{ - players:["Malcom", "Michu"], - team:"", - goals: 0 - }, - tags: ["Torneo 3", "Segunda"], - }, - { - date:'2014-07-11T00:00:00.000Z', - home:{ - players:["Charly", "Hernan"], - team:"", - goals: 1 - }, - away:{ - players:["Malcom", "FerO"], - team:"", - goals: 3 - }, - tags: ["Torneo 3", "Segunda"], - }, - { - date:'2014-07-25T00:00:00.000Z', - home:{ - players:["Charly", "Hernan"], - team:"", - goals: 0 - }, - away:{ - players:["Michu", "Santi"], - team:"", - goals: 7 - }, - tags: ["Torneo 3", "Segunda"], - }, - { - date:'2014-07-25T00:00:00.000Z', - home:{ - players:["Charly", "Hernan"], - team:"", - goals: 1 - }, - away:{ - players:["FerO", "Santi"], - team:"", - goals: 0 - }, - tags: ["Torneo 3", "Segunda"], - }, - { - date:'2014-09-02T00:00:00.000Z', - home:{ - players:["Gaby", "Mauri"], - team:"", - goals: 6 - }, - away:{ - players:["Leo", "Malcom"], - team:"", - goals: 0 - }, - tags: ["Torneo 4", "Primera"], - }, - { - date:'2014-09-02T00:00:00.000Z', - home:{ - players:["Gaby", "Leo"], - team:"", - goals: 1 - }, - away:{ - players:["Mauri", "Malcom"], - team:"", - goals: 1 - }, - tags: ["Torneo 4", "Primera"], - }, - { - date:'2014-08-26T00:00:00.000Z', - home:{ - players:["Gaby", "Malcom"], - team:"", - goals: 0 - }, - away:{ - players:["Mauri", "Leo"], - team:"", - goals: 1 - }, - tags: ["Torneo 4", "Primera"], - }, - { - date:'2014-09-03T00:00:00.000Z', - home:{ - players:["Juan", "Gaby"], - team:"", - goals: 2 - }, - away:{ - players:["Leo", "Malcom"], - team:"", - goals: 3 - }, - tags: ["Torneo 4", "Primera"], - }, - { - date:'2014-09-01T00:00:00.000Z', - home:{ - players:["Juan", "Leo"], - team:"", - goals: 3 - }, - away:{ - players:["Gaby", "Malcom"], - team:"", - goals: 1 - }, - tags: ["Torneo 4", "Primera"], - }, - { - date:'2014-08-26T00:00:00.000Z', - home:{ - players:["Juan", "Malcom"], - team:"", - goals: 1 - }, - away:{ - players:["Gaby", "Leo"], - team:"", - goals: 4 - }, - tags: ["Torneo 4", "Primera"], - }, - { - date:'2014-08-25T00:00:00.000Z', - home:{ - players:["Juan", "Gaby"], - team:"", - goals: 1 - }, - away:{ - players:["Mauri", "Leo"], - team:"", - goals: 2 - }, - tags: ["Torneo 4", "Primera"], - }, - { - date:'2014-09-05T00:00:00.000Z', - home:{ - players:["Juan", "Mauri"], - team:"", - goals: 1 - }, - away:{ - players:["Gaby", "Leo"], - team:"", - goals: 1 - }, - tags: ["Torneo 4", "Primera"], - }, - { - date:'2014-08-27T00:00:00.000Z', - home:{ - players:["Juan", "Leo"], - team:"", - goals: 1 - }, - away:{ - players:["Gaby", "Mauri"], - team:"", - goals: 2 - }, - tags: ["Torneo 4", "Primera"], - }, - { - date:'2014-08-22T00:00:00.000Z', - home:{ - players:["Juan", "Mauri"], - team:"", - goals: 3 - }, - away:{ - players:["Leo", "Malcom"], - team:"", - goals: 2 - }, - tags: ["Torneo 4", "Primera"], - }, - { - date:'2014-08-29T00:00:00.000Z', - home:{ - players:["Juan", "Leo"], - team:"", - goals: 3 - }, - away:{ - players:["Mauri", "Malcom"], - team:"", - goals: 2 - }, - tags: ["Torneo 4", "Primera"], - }, - { - date:'2014-09-04T00:00:00.000Z', - home:{ - players:["Juan", "Malcom"], - team:"", - goals: 3 - }, - away:{ - players:["Mauri", "Leo"], - team:"", - goals: 1 - }, - tags: ["Torneo 4", "Primera"], - }, - { - date:'2014-08-21T00:00:00.000Z', - home:{ - players:["Juan", "Gaby"], - team:"", - goals: 1 - }, - away:{ - players:["Mauri", "Malcom"], - team:"", - goals: 3 - }, - tags: ["Torneo 4", "Primera"], - }, - { - date:'2014-08-29T00:00:00.000Z', - home:{ - players:["Juan", "Mauri"], - team:"", - goals: 1 - }, - away:{ - players:["Gaby", "Malcom"], - team:"", - goals: 2 - }, - tags: ["Torneo 4", "Primera"], - }, - { - date:'2014-09-01T00:00:00.000Z', - home:{ - players:["Juan", "Malcom"], - team:"", - goals: 4 - }, - away:{ - players:["Gaby", "Mauri"], - team:"", - goals: 2 - }, - tags: ["Torneo 4", "Primera"], - }, - { - date:'2014-08-21T00:00:00.000Z', - home:{ - players:["Michu", "NicoR"], - team:"", - goals: 7 - }, - away:{ - players:["FerO", "DaniG"], - team:"", - goals: 1 - }, - tags: ["Torneo 4", "Segunda"], - }, - { - date:'2014-08-27T00:00:00.000Z', - home:{ - players:["Michu", "FerO"], - team:"", - goals: 1 - }, - away:{ - players:["NicoR", "DaniG"], - team:"", - goals: 1 - }, - tags: ["Torneo 4", "Segunda"], - }, - { - date:'2014-08-27T00:00:00.000Z', - home:{ - players:["Michu", "DaniG"], - team:"", - goals: 0 - }, - away:{ - players:["NicoR", "FerO"], - team:"", - goals: 2 - }, - tags: ["Torneo 4", "Segunda"], - }, - { - date:'2014-08-28T00:00:00.000Z', - home:{ - players:["Santi", "Michu"], - team:"", - goals: 3 - }, - away:{ - players:["FerO", "DaniG"], - team:"", - goals: 2 - }, - tags: ["Torneo 4", "Segunda"], - }, - { - date:'2014-08-25T00:00:00.000Z', - home:{ - players:["Santi", "FerO"], - team:"", - goals: 0 - }, - away:{ - players:["Michu", "DaniG"], - team:"", - goals: 0 - }, - tags: ["Torneo 4", "Segunda"], - }, - { - date:'2014-08-28T00:00:00.000Z', - home:{ - players:["Santi", "DaniG"], - team:"", - goals: 3 - }, - away:{ - players:["Michu", "FerO"], - team:"", - goals: 0 - }, - tags: ["Torneo 4", "Segunda"], - }, - { - date:'2014-08-29T00:00:00.000Z', - home:{ - players:["Santi", "Michu"], - team:"", - goals: 2 - }, - away:{ - players:["NicoR", "FerO"], - team:"", - goals: 1 - }, - tags: ["Torneo 4", "Segunda"], - }, - { - date:'2014-08-29T00:00:00.000Z', - home:{ - players:["Santi", "NicoR"], - team:"", - goals: 5 - }, - away:{ - players:["Michu", "FerO"], - team:"", - goals: 0 - }, - tags: ["Torneo 4", "Segunda"], - }, - { - date:'2014-08-26T00:00:00.000Z', - home:{ - players:["Santi", "FerO"], - team:"", - goals: 2 - }, - away:{ - players:["Michu", "NicoR"], - team:"", - goals: 2 - }, - tags: ["Torneo 4", "Segunda"], - }, - { - date:'2014-09-01T00:00:00.000Z', - home:{ - players:["Santi", "NicoR"], - team:"", - goals: 1 - }, - away:{ - players:["FerO", "DaniG"], - team:"", - goals: 1 - }, - tags: ["Torneo 4", "Segunda"], - }, - { - date:'2014-08-29T00:00:00.000Z', - home:{ - players:["Santi", "FerO"], - team:"", - goals: 4 - }, - away:{ - players:["NicoR", "DaniG"], - team:"", - goals: 0 - }, - tags: ["Torneo 4", "Segunda"], - }, - { - date:'2014-09-01T00:00:00.000Z', - home:{ - players:["Santi", "DaniG"], - team:"", - goals: 2 - }, - away:{ - players:["NicoR", "FerO"], - team:"", - goals: 0 - }, - tags: ["Torneo 4", "Segunda"], - }, - { - date:'2014-09-02T00:00:00.000Z', - home:{ - players:["Santi", "Michu"], - team:"", - goals: 4 - }, - away:{ - players:["NicoR", "DaniG"], - team:"", - goals: 2 - }, - tags: ["Torneo 4", "Segunda"], - }, - { - date:'2014-09-03T00:00:00.000Z', - home:{ - players:["Santi", "NicoR"], - team:"", - goals: 5 - }, - away:{ - players:["Michu", "DaniG"], - team:"", - goals: 1 - }, - tags: ["Torneo 4", "Segunda"], - }, - { - date:'2014-09-02T00:00:00.000Z', - home:{ - players:["Santi", "DaniG"], - team:"", - goals: 2 - }, - away:{ - players:["Michu", "NicoR"], - team:"", - goals: 0 - }, - tags: ["Torneo 4", "Segunda"], - }, - { - date:'2014-08-20T00:00:00.000Z', - home:{ - players:["Hernan", "Ariel"], - team:"", - goals: 2 - }, - away:{ - players:["Leandro", "NicoL"], - team:"", - goals: 0 - }, - tags: ["Torneo 4", "Tercera"], - }, - { - date:'2014-08-20T00:00:00.000Z', - home:{ - players:["Hernan", "Ariel"], - team:"", - goals: 2 - }, - away:{ - players:["Charly", "FerP"], - team:"", - goals: 0 - }, - tags: ["Torneo 4", "Tercera"], - }, - { - date:'2014-08-20T00:00:00.000Z', - home:{ - players:["Leandro", "NicoL"], - team:"", - goals: 1 - }, - away:{ - players:["Charly", "FerP"], - team:"", - goals: 3 - }, - tags: ["Torneo 4", "Tercera"], - }, - { - date:'2014-08-21T00:00:00.000Z', - home:{ - players:["Hernan", "NicoL"], - team:"", - goals: 0 - }, - away:{ - players:["Leandro", "FerP"], - team:"", - goals: 0 - }, - tags: ["Torneo 4", "Tercera"], - }, - { - date:'2014-08-22T00:00:00.000Z', - home:{ - players:["Hernan", "NicoL"], - team:"", - goals: 4 - }, - away:{ - players:["Charly", "Ariel"], - team:"", - goals: 0 - }, - tags: ["Torneo 4", "Tercera"], - }, - { - date:'2014-08-22T00:00:00.000Z', - home:{ - players:["Leandro", "FerP"], - team:"", - goals: 4 - }, - away:{ - players:["Charly", "Ariel"], - team:"", - goals: 0 - }, - tags: ["Torneo 4", "Tercera"], - }, - { - date:'2014-08-25T00:00:00.000Z', - home:{ - players:["Hernan", "FerP"], - team:"", - goals: 3 - }, - away:{ - players:["Charly", "NicoL"], - team:"", - goals: 0 - }, - tags: ["Torneo 4", "Tercera"], - }, - { - date:'2014-08-25T00:00:00.000Z', - home:{ - players:["Hernan", "FerP"], - team:"", - goals: 2 - }, - away:{ - players:["Leandro", "Ariel"], - team:"", - goals: 0 - }, - tags: ["Torneo 4", "Tercera"], - }, - { - date:'2014-08-25T00:00:00.000Z', - home:{ - players:["Charly", "NicoL"], - team:"", - goals: 1 - }, - away:{ - players:["Leandro", "Ariel"], - team:"", - goals: 2 - }, - tags: ["Torneo 4", "Tercera"], - }, - { - date:'2014-08-26T00:00:00.000Z', - home:{ - players:["Hernan", "Ariel"], - team:"", - goals: 1 - }, - away:{ - players:["Leandro", "FerP"], - team:"", - goals: 1 - }, - tags: ["Torneo 4", "Tercera"], - }, - { - date:'2014-08-27T00:00:00.000Z', - home:{ - players:["Hernan", "Ariel"], - team:"", - goals: 2 - }, - away:{ - players:["Charly", "NicoL"], - team:"", - goals: 0 - }, - tags: ["Torneo 4", "Tercera"], - }, - { - date:'2014-08-27T00:00:00.000Z', - home:{ - players:["Leandro", "FerP"], - team:"", - goals: 0 - }, - away:{ - players:["Charly", "NicoL"], - team:"", - goals: 0 - }, - tags: ["Torneo 4", "Tercera"], - }, - { - date:'2014-08-29T00:00:00.000Z', - home:{ - players:["Hernan", "FerP"], - team:"", - goals: 0 - }, - away:{ - players:["Leandro", "NicoL"], - team:"", - goals: 2 - }, - tags: ["Torneo 4", "Tercera"], - }, - { - date:'2014-09-01T00:00:00.000Z', - home:{ - players:["Hernan", "FerP"], - team:"", - goals: 8 - }, - away:{ - players:["Charly", "Ariel"], - team:"", - goals: 0 - }, - tags: ["Torneo 4", "Tercera"], - }, - { - date:'2014-09-01T00:00:00.000Z', - home:{ - players:["Leandro", "NicoL"], - team:"", - goals: 3 - }, - away:{ - players:["Charly", "Ariel"], - team:"", - goals: 1 - }, - tags: ["Torneo 4", "Tercera"], - }, - { - date:'2014-09-01T00:00:00.000Z', - home:{ - players:["Hernan", "NicoL"], - team:"", - goals: 0 - }, - away:{ - players:["Charly", "FerP"], - team:"", - goals: 1 - }, - tags: ["Torneo 4", "Tercera"], - }, - { - date:'2014-09-01T00:00:00.000Z', - home:{ - players:["Hernan", "NicoL"], - team:"", - goals: 2 - }, - away:{ - players:["Leandro", "Ariel"], - team:"", - goals: 0 - }, - tags: ["Torneo 4", "Tercera"], - }, - { - date:'2014-09-05T00:00:00.000Z', - home:{ - players:["Charly", "FerP"], - team:"", - goals: 3 - }, - away:{ - players:["Leandro", "Ariel"], - team:"", - goals: 0 - }, - tags: ["Torneo 4", "Tercera"], - }, - { - date:'', - home:{ - players:["NicoR", "Leo"], - team:"Alemania", - goals: 3 - }, - away:{ - players:["Santi", "Gaby"], - team:"Francia", - goals: 3 - }, - tags: ["Mundial 1", "Grupo A"], - }, - { - date:'', - home:{ - players:["NicoR", "Malcom"], - team:"Alemania", - goals: 0 - }, - away:{ - players:["Gamba", "Leo"], - team:"Mexico", - goals: 0 - }, - tags: ["Mundial 1", "Grupo A"], - }, - { - date:'', - home:{ - players:["NicoR", "DaniG"], - team:"Alemania", - goals: 1 - }, - away:{ - players:["Michu", "Juan"], - team:"Inglaterra", - goals: 0 - }, - tags: ["Mundial 1", "Grupo A"], - }, - { - date:'', - home:{ - players:["Michu", "FerO"], - team:"Inglaterra", - goals: 1 - }, - away:{ - players:["Gamba", "Gaby"], - team:"Mexico", - goals: 4 - }, - tags: ["Mundial 1", "Grupo A"], - }, - { - date:'', - home:{ - players:["Michu", "Gaby"], - team:"Inglaterra", - goals: 1 - }, - away:{ - players:["Santi", "DaniG"], - team:"Francia", - goals: 1 - }, - tags: ["Mundial 1", "Grupo A"], - }, - { - date:'', - home:{ - players:["Gamba", "Mauri"], - team:"Mexico", - goals: 1 - }, - away:{ - players:["Santi", "Leo"], - team:"Francia", - goals: 2 - }, - tags: ["Mundial 1", "Grupo A"], - }, - { - date:'', - home:{ - players:["Leo", "Mauri"], - team:"Italia", - goals: 2 - }, - away:{ - players:["Gaby", "Gamba"], - team:"Brasil", - goals: 1 - }, - tags: ["Mundial 1", "Grupo B"], - }, - { - date:'', - home:{ - players:["Leo", "Gamba"], - team:"Italia", - goals: 1 - }, - away:{ - players:["Malcom", "Santi"], - team:"Espana", - goals: 2 - }, - tags: ["Mundial 1", "Grupo B"], - }, - { - date:'', - home:{ - players:["Leo", "Santi"], - team:"Italia", - goals: 0 - }, - away:{ - players:["FerO", "Mauri"], - team:"Uruguay", - goals: 0 - }, - tags: ["Mundial 1", "Grupo B"], - }, - { - date:'', - home:{ - players:["Gaby", "Mauri"], - team:"Brasil", - goals: 7 - }, - away:{ - players:["Malcom", "Charly"], - team:"Espana", - goals: 1 - }, - tags: ["Mundial 1", "Grupo B"], - }, - { - date:'', - home:{ - players:["Gaby", "Charly"], - team:"Brasil", - goals: 2 - }, - away:{ - players:["FerO", "NicoR"], - team:"Uruguay", - goals: 1 - }, - tags: ["Mundial 1", "Grupo B"], - }, - { - date:'', - home:{ - players:["Malcom", "Mauri"], - team:"Espana", - goals: 2 - }, - away:{ - players:["FerO", "Santi"], - team:"Uruguay", - goals: 2 - }, - tags: ["Mundial 1", "Grupo B"], - }, - - { - date:'', - home:{ - players:["Mauri", "Gamba"], - team:"Holanda", - goals: 1 - }, - away:{ - players:["Juan", "Michu"], - team:"CdMarfil", - goals: 1 - }, - tags: ["Mundial 1", "Grupo C"], - }, - { - date:'', - home:{ - players:["Mauri", "Leo"], - team:"Holanda", - goals: 4 - }, - away:{ - players:["DaniG", "NicoR"], - team:"Colombia", - goals: 0 - }, - tags: ["Mundial 1", "Grupo C"], - }, - { - date:'', - home:{ - players:["Juan", "Malcom"], - team:"CdMarfil", - goals: 4 - }, - away:{ - players:["DaniG", "Leo"], - team:"Colombia", - goals: 0 - }, - tags: ["Mundial 1", "Grupo C"], - }, - - { - date:'', - home:{ - players:["Charly", "Santi"], - team:"EEUU", - goals: 0 - }, - away:{ - players:["Cristian", "NicoR"], - team:"Argentina", - goals: 1 - }, - tags: ["Mundial 1", "Grupo D"], - }, - { - date:'', - home:{ - players:["Charly", "NicoR"], - team:"EEUU", - goals: 2 - }, - away:{ - players:["Sebas", "Leo"], - team:"Portugal", - goals: 1 - }, - tags: ["Mundial 1", "Grupo D"], - }, - { - date:'', - home:{ - players:["Cristian", "Leo"], - team:"Argentina", - goals: 0 - }, - away:{ - players:["Sebas", "Malcom"], - team:"Portugal", - goals: 0 - }, - tags: ["Mundial 1", "Grupo D"], - }, - { - date:'', - home:{ - players:["Santi", "Leo"], - team:"Francia", - goals: 1 - }, - away:{ - players:["Juan", "Gaby"], - team:"CdMarfil", - goals: 4 - }, - tags: ["Mundial 1", "Cuartos de final"], - }, - { - date:'', - home:{ - players:["Cristian", "NicoR"], - team:"Argentina", - goals: 0 - }, - away:{ - players:["Leo", "Juan"], - team:"Italia", - goals: 3 - }, - tags: ["Mundial 1", "Cuartos de final"], - }, - { - date:'', - home:{ - players:["Mauri", "Leo"], - team:"Holanda", - goals: 2 - }, - away:{ - players:["NicoR", "Gaby"], - team:"Alemania", - goals: 5 - }, - tags: ["Mundial 1", "Cuartos de final"], - }, - { - date:'', - home:{ - players:["Gaby", "NicoR"], - team:"Brasil", - goals: 3 - }, - away:{ - players:["Charly", "Mauri"], - team:"EEUU", - goals: 1 - }, - tags: ["Mundial 1", "Cuartos de final"], - }, - { - date:'', - home:{ - players:["Juan", "Santi"], - team:"CdMarfil", - goals: 3, - penalties: 4, - }, - away:{ - players:["Leo", "NicoR"], - team:"Italia", - goals: 3, - penalties: 5, - }, - tags: ["Mundial 1", "Semifinal"], - }, - { - date:'', - home:{ - players:["NicoR", "Santi"], - team:"Alemania", - goals: 3 - }, - away:{ - players:["Gaby", "Juan"], - team:"Brasil", - goals: 0 - }, - tags: ["Mundial 1", "Semifinal"], - }, - - { - date:'', - home:{ - players:["Juan", "Leo"], - team:"CdMarfil", - goals: 1 - }, - away:{ - players:["Gaby", "Mauri"], - team:"Brasil", - goals: 4 - }, - tags: ["Mundial 1", "Tercer Puesto"], - }, - { - date:'', - home:{ - players:["NicoR", "Malcom"], - team:"Alemania", - goals: 2 - }, - away:{ - players:["Leo", "Mauri"], - team:"Italia", - goals: 0 - }, - tags: ["Mundial 1", "Final"], - }, - ]; -}]) -; - diff --git a/app/api/match.js b/app/api/match.js new file mode 100644 index 0000000..1cea89b --- /dev/null +++ b/app/api/match.js @@ -0,0 +1,77 @@ +var schemas = require("../model/schemas"); +var stats = require("../service/statistic"); +var ranking = require("../service/ranking"); +var validation = require("./validation"); +var email = require('../service/email'); + +module.exports = function(app) { + app.post("/api/match", validation.authenticateUser, function(req, res) { + var body = req.body; + body.createdBy = req.user.alias; + var tournamentName = body.tournament.name ? body.tournament.name : body.tournament; + schemas.Tournament.findOne({"name": tournamentName}, "_id", function(err, tournamentId) { + if (err) res.send(err); + body.tournament = tournamentId._id; + var match = new schemas.Match(body); + match.save(function(err, match) { + if (err) res.send(err); + stats.updateForPlayer([match.home.player, match.home.partner, match.away.player, match.away.partner]); + ranking.calculateGeneralRanking(function() { + email.sendMatchEmail(match, tournamentName); + res.send("created"); + }); + }) + }) + }); + app.put("/api/match/", validation.authenticateAdmin, function(req, res) { + var body = req.body; + schemas.Tournament.findOne(body.tournament, function(err, tournament2) { + if (err) res.send(err); + body.tournament = tournament2; + schemas.Match.update({"_id": body._id}, {$set: body}, function(err, result) { + if (err) res.send(err); + stats.updateForPlayer([body.home.player, body.home.partner, body.away.player, body.away.partner]); + ranking.calculateGeneralRanking(function() { + res.json(result); + }); + }) + }) + }); + app.get("/api/match/tournament/:tournament", function(req, res) { + var tournamentName = req.params.tournament; + if (tournamentName == "current") { + //FIXME: create a module for commons operations in the db. + schemas.Tournament.findOne({current: true}, "name", function(err, tournament) { + if (err) res.send(err); + tournamentName = tournament.name; + }).sort({creationDate: -1}) + } + var filter = function(match) { + return match.tournament.name == tournamentName; + }; + schemas.Match.find({}, "-__v").populate({ + path: "tournament"/*, FIXME: this should work but I don't know why not... + match: { name: "Torneo 0"}, + select: "-_id -__v"*/ + }).exec(function(err, matches) { + if (err) res.send(err); + matches = matches.filter(function(match) { + return filter(match); + }); + res.json(matches); + }); + }); + app.get("/api/match/player/:alias", function(req, res) { + var alias = req.params.alias; + schemas.Match.find({ $or: [{"home.player": alias}, {"away.player": alias}, {"home.partner": alias}, {"away.partner": alias}]}, "-__v").populate("tournament", "-_id -__v").exec(function(err, matches) { + if (err) res.send(err); + res.json(matches); + }) + }); + app.get("/api/match", function(req, res) { + schemas.Match.find({}, "-_id -__v").populate("tournament", "-_id -__v").exec(function(err, matches) { + if (err) res.send(err); + res.json(matches); + }) + }) +}; diff --git a/app/api/player.js b/app/api/player.js new file mode 100644 index 0000000..1e17080 --- /dev/null +++ b/app/api/player.js @@ -0,0 +1,40 @@ +var schemas = require("../model/schemas"); +var ranking = require("../service/ranking"); +var stats = require("../service/statistic"); +var validation = require("./validation"); +var _ = require("underscore"); + +module.exports = function(app) { + app.get("/api/player", function(req, res) { + schemas.Player.find(function(err, players) { + if (err) res.send(err); + + res.json(players); + }).sort({"ranking": -1}) + }); + app.get("/api/player/:alias", function(req, res) { + schemas.Player.findOne({"alias": req.params.alias}, function(err, player) { + if (err) res.send(err); + res.json(player); + }) + }); + app.post("/api/player", function(req, res) { + var body = req.body; + new schemas.Player(body).save(function(err, created) { + if (err) res.send(err); + res.send("created"); + }) + }); + app.post("/api/player/ranking", validation.authenticateUser, function(req, res) { + ranking.calculateGeneralRanking(function(glickoPlayers) { + res.send("Finished successfully") + }) + }); + app.get("/api/player/stats/all", function(req, res) { + res.json(stats.allPlayerStatistics()); + }); + app.get("/api/player/stats/:alias", function(req, res) { + res.json(stats.playerStatistics(req.params.alias)); + }); + +}; \ No newline at end of file diff --git a/app/api/randomize.js b/app/api/randomize.js new file mode 100644 index 0000000..96753be --- /dev/null +++ b/app/api/randomize.js @@ -0,0 +1,23 @@ +var _ = require("underscore"); + +module.exports = function(app) { + app.post('/api/random/group', function(req, res) { + var groups = []; + _.each(req.body.groups, function(group, groupIdx) { + if (!_.isArray(group)) { + res.send("invalid"); + } else { + _.each(_.shuffle(group), function(item, i) { + if (!groups[i]) { + groups[i] = {} + } + groups[i]['key' + groupIdx] = item; + }); + } + }); + res.json(groups); + }); + app.post("/api/random/value", function(req, res) { + res.send(_.sample(req.body.data)); + }) +}; \ No newline at end of file diff --git a/app/api/routes.js b/app/api/routes.js new file mode 100644 index 0000000..e04b0a1 --- /dev/null +++ b/app/api/routes.js @@ -0,0 +1,45 @@ +module.exports = function(app, passport) { + var index = function (req, res) { + res.render('index', {user: req.user}); + }; + app.get('/', index); + app.get('/templates/:name', function (req, res) { + res.render(req.params.name, { user: req.user }); + }); + + app.get('/auth/google', + passport.authenticate('google', { scope: + [ 'https://www.googleapis.com/auth/plus.me', 'https://www.googleapis.com/auth/userinfo.email' ] })); + + app.get( '/auth/google/callback', + passport.authenticate( 'google', { + successRedirect: '/', + failureRedirect: '/login' + })); + + app.get('/login', function(req, res){ + res.render('login', { user: req.user }); + }); + + app.get('/account', ensureAuthenticated, function(req, res){ + res.render('account', { user: req.user }); + }); + + app.get('/account/logout', function(req, res){ + req.logout(); + res.redirect('/'); + }); + + app.get('/:whatever', index); + app.get('/:whatever/:whatever2', index); + + // Simple route middleware to ensure user is authenticated. +// Use this route middleware on any resource that needs to be protected. If +// the request is authenticated (typically via a persistent login session), +// the request will proceed. Otherwise, the user will be redirected to the +// login page. + function ensureAuthenticated(req, res, next) { + if (req.isAuthenticated()) { return next(); } + res.redirect('/login'); + } +}; \ No newline at end of file diff --git a/app/api/tournament.js b/app/api/tournament.js new file mode 100644 index 0000000..04cba7f --- /dev/null +++ b/app/api/tournament.js @@ -0,0 +1,57 @@ +var schemas = require("../model/schemas"); +var validation = require("./validation"); +var generator = require('../service/tournamentGenerator'); + +module.exports = function(app) { + app.post("/api/tournament", validation.authenticateUser, function(req, res) { + var body = req.body; + var tournament = new schemas.Tournament(body); + tournament.save(function(err) { + if (err) res.send(err); + res.send("created"); + }) + + }); + app.get("/api/tournament", function(req, res) { + schemas.Tournament.find({}, "-_id -__v").sort({creationDate: 'desc'}).exec(function(err, tournaments) { + if (err) res.send(err); + res.json(tournaments); + }); + }); + app.get("/api/tournament/:name", function(req, res) { + var name = req.params.name; + var condition = {}; + name == "current" ? condition.current = true : condition.name = name; + schemas.Tournament.findOne(condition, "-_id -__v", function(err, tournament) { + if (err) res.send(err); + res.json(tournament); + }).sort({creationDate: -1}) + }); + app.delete("/api/tournament/:name", validation.authenticateUser, function(req, res) { + schemas.Tournament.findOneAndRemove({"name": req.params.name}, function(err, tournament) { + if (err) res.send(err); + res.json(tournament); + }) + }); + app.put("/api/tournament/:name", validation.authenticateUser, function(req, res) { + var body = req.body; + schemas.Tournament.update({"name": req.params.name}, { $set: body }, function(err, updated) { + if (err) res.send(err); + res.json(updated); + }) + }); + app.post('/api/tournament/generate', validation.authenticateUser, function(req, res) { + generator.generate(req.body, req.body.secondRound); + res.send("Received, generating tournament..."); + }); + app.post('/api/tournament/csvGenerate', validation.authenticateUser, function(req, res) { + generator.createMatchFromCSV(req.body.data); + res.send("Received, generating matches..."); + }); + app.get("/api/tournament/randomSelect", validation.authenticateUser, function(req, res) { + generator.randomSelect(req.body.players, req.body.teams, function(selections) { + res.json(selections); + }); + }); +}; + diff --git a/app/api/validation.js b/app/api/validation.js new file mode 100644 index 0000000..4a4eff5 --- /dev/null +++ b/app/api/validation.js @@ -0,0 +1,35 @@ +var schemas = require("../model/schemas"); + +var accessDenied = function(res) { + res.status(401).send("You have no access to perform the operation"); +}; + +module.exports = { + authenticateAdmin: function(req, res, next) { + if (!req.user || !req.user.admin) { + accessDenied(res); + } else { + schemas.Player.findOne({_id: req.user.id}, function(err, user) { + if (!err & user.admin) { + next(); + } else { + accessDenied(res); + } + }) + } + }, + authenticateUser: function(req, res, next) { + if (!req.user) { + accessDenied(res); + } else { + schemas.Player.findOne({_id: req.user.id}, function(err, user) { + if (!err && user) { + next(); + } else { + accessDenied(res); + } + }) + } + + } +}; \ No newline at end of file diff --git a/app/config/google.js b/app/config/google.js new file mode 100644 index 0000000..ad71bd3 --- /dev/null +++ b/app/config/google.js @@ -0,0 +1,22 @@ +var GoogleStrategy = require('passport-google-oauth2').Strategy; +var playerManager = require("../model/playerManager"); + +module.exports = function(passport) { + passport.use(new GoogleStrategy({ + clientID: process.env.GOOGLE_CLIENT_ID, + clientSecret: process.env.GOOGLE_CLIENT_SECRET, + callbackURL: (process.env.HEROKU_URL || process.env.LOCAL_URL + ":" + process.env.PORT) + "/auth/google/callback", + passReqToCallback : true + + }, + function(request, accessToken, refreshToken, profile, done) { + // asynchronous verification, for effect... + playerManager.createNewPlayer(profile, function(player) { + process.nextTick(function () { + return done(null, player); + }) + }) + ; + } + )); +}; \ No newline at end of file diff --git a/app/constants.js b/app/constants.js new file mode 100644 index 0000000..670d102 --- /dev/null +++ b/app/constants.js @@ -0,0 +1,11 @@ +function define(name, value) { + Object.defineProperty(exports, name, { + value: value, + enumerable: true + }); +} + +define("HOME", "home"); +define("AWAY", "away"); +define("PLAYER", "player"); +define("PARTNER", "partner"); \ No newline at end of file diff --git a/app/model/playerManager.js b/app/model/playerManager.js new file mode 100644 index 0000000..50a2194 --- /dev/null +++ b/app/model/playerManager.js @@ -0,0 +1,36 @@ +var schemas = require("./schemas"); +var parser = require("./playerParser"); + +function PlayerManager() { + this._players = []; +} + +PlayerManager.prototype.addPlayer = function(player) { + this._players.push(player); +}; + +PlayerManager.prototype.createNewPlayer = function(jsonPlayer, callback) { + var schemaPlayer = parser.parse(jsonPlayer); + if (schemaPlayer) { + var me = this; + schemas.Player.findOne({googleId: schemaPlayer.googleId}, function(err, player) { + if (err) console.error(err); + else if (player) { + console.info("Player already created. " + schemaPlayer.username); + callback.call(this, player); + } else { + schemaPlayer.save(function(err, saved) { + if (err) console.error("cannot save player"); + else { + console.info("Player saved"); + me.addPlayer(saved); + callback.call(this, schemaPlayer); + } + }); + } + }); + } +}; +var playerManager = new PlayerManager(); + +module.exports = playerManager; diff --git a/app/model/playerParser.js b/app/model/playerParser.js new file mode 100644 index 0000000..a36cf28 --- /dev/null +++ b/app/model/playerParser.js @@ -0,0 +1,39 @@ +var schemas = require("../model/schemas"); +/* + { provider: 'google', + id: '110890234919138773163', + displayName: 'Ezequiel Bergamaschi', + name: { familyName: 'Bergamaschi', givenName: 'Ezequiel' }, + isPerson: true, + isPlusUser: true, + language: 'en', + emails: [ { value: 'ebergamaschi@medallia.com', type: 'account' } ], + email: 'ebergamaschi@medallia.com', + gender: 'male', + photos: [ { value: 'https://lh3.googleusercontent.com/-iSWoErT7a24/AAAAAAAAAAI/AAAAAAAAACA/qgBbFeWXFv4/photo.jpg?sz=50' } ] + } + */ + +function parse(jsonPlayer) { + //console.log(jsonPlayer); + var player = new schemas.Player(); + var medalliaDomain = "medallia.com"; + var email = jsonPlayer.email; + var domain = jsonPlayer.domain || email.split("@")[1]; + if (domain != medalliaDomain) { + console.error("invalid domain: " + domain); + return; + } + player.firstName = jsonPlayer.name.givenName; + player.lastName = jsonPlayer.name.familyName; + player.username = email.replace("@" + medalliaDomain, ""); + player.email = jsonPlayer.email; + player.alias = player.username; + player.image = jsonPlayer.photos[0].value; + player.googleId = jsonPlayer.id; + return player; +} + +module.exports = { + parse: parse +}; \ No newline at end of file diff --git a/app/model/schemas.js b/app/model/schemas.js new file mode 100644 index 0000000..76177e8 --- /dev/null +++ b/app/model/schemas.js @@ -0,0 +1,62 @@ +var mongoose = require('mongoose'); +var Schema = mongoose.Schema; + +var playerSchema = new Schema({ + username: String, + firstName: String, + lastName: String, + alias: String, + email: String, + image: String, + lastAccess: { type: Date, default: Date.now }, + ranking: {type: Number, default: 1500}, + previousRanking: Number, + rankingHistory: {type: Array}, + googleId: {type: String, required: true}, + admin: {type: Boolean, default: false} +}); + +var matchSchema = new Schema({ + date: Date, + createdBy: {type: String, required: false}, + home: { + player: {type: String, required: true}, + partner: {type: String, required: false}, + goals: {type: Number, default: -1}, + penalties: {type: Number, default: 0}, + redCards: {type: Number, default: -1}, + yellowCards: {type: Number, default: -1}, + team: String + }, + away: { + player: {type: String, required: true}, + partner: {type: String, required: false}, + goals: {type: Number, default: -1}, + penalties: {type: Number, default: 0}, + redCards: {type: Number, default: -1}, + yellowCards: {type: Number, default: -1}, + team: String + }, + tournament: {type: Schema.Types.ObjectId, ref: "Tournament"}, + phase: {type: String, required: true} +}); + +var tournamentSchema = new Schema({ + name: {type: String, required: true}, + creationDate: { type: Date, default: Date.now }, + current: {type: Boolean, default: false}, + config: { + phases: [String], + defaultPhase: String, + phasesWithStandings: [String], + standingsModel: String + }, + winner: {type: Schema.Types.ObjectId, ref: 'User', default: null}, + second: {type: Schema.Types.ObjectId, ref: 'User', default: null}, + third: {type: Schema.Types.ObjectId, ref: 'User', default: null} +}); + +exports.Player = mongoose.model("Player", playerSchema); +exports.Match = mongoose.model("Match", matchSchema); +exports.Tournament = mongoose.model("Tournament", tournamentSchema); + diff --git a/app/service/email.js b/app/service/email.js new file mode 100644 index 0000000..9c8531e --- /dev/null +++ b/app/service/email.js @@ -0,0 +1,100 @@ +var nodemailer = require('nodemailer'); +var _ = require("underscore"); +var constants = require("../constants"); +var schemas = require("../model/schemas"); + +var config = { + service: 'gmail', + auth: { + user: process.env.FIFA_EMAIL, + pass: process.env.FIFA_EMAIL_PASS + } +}; + + +var validateCredentials = function() { + if (!config.auth.user || !config.auth.pass) { + console.warn("Email account settings not set, skipping email send."); + return; + } +}; + +validateCredentials(); + +var transporter = nodemailer.createTransport(config); +var sendEmail = function(to, subject, body) { + transporter.sendMail({ + from: config.auth.user, + to: to, + subject: subject, + text: body, + bcc: 'ezequiel@medallia.com,santiago@medallia.com,nicolas@medallia.com' + }); +}; + +var findUsersForMatchEmail = function(match) { + var findIn = function (match, homeOrAway, alias) { + return (match[homeOrAway][constants.PLAYER] == alias || match[homeOrAway][constants.PARTNER] == alias); + }; + var getPlayersFor = function(match, homeOrAway) { + return [match[homeOrAway][constants.PLAYER], match[homeOrAway][constants.PARTNER]] + }; + var createdByAlias = match.createdBy; + var homePlayers = getPlayersFor(match, constants.HOME); + var awayPlayers = getPlayersFor(match, constants.AWAY); + + if (findIn(match, constants.HOME, createdByAlias)) { + return awayPlayers; + } else if (findIn(match, constants.AWAY, createdByAlias)) { + return homePlayers; + } else { + return _.union(homePlayers, awayPlayers); + } +}; + +var formatTeam = function(match, homeOrAway) { + var team = match[homeOrAway]; + var player = team[constants.PLAYER]; + var partner = team[constants.PARTNER]; + var suffix = ''; + if (partner) { + suffix = " & " + partner; + } + return "\t" + player + suffix + + "\n\tGoals: "+ team.goals + ", Yellow cards: " + team.yellowCards + ", Red cards: " + team.redCards; +}; + +var sendMatchEmail = function(match, tournamentName) { + validateCredentials(); + var creator = match.createdBy; + var body = "Match highlights: \n\n" + + "Tournament: " + tournamentName + ", Phase: " + match.phase + "\n\n" + + "Home Team: \n" + + formatTeam(match, constants.HOME) + "\n" + + "----\n" + + "Away Team: \n" + + formatTeam(match, constants.AWAY) + "\n\n" + + "Cheers, The Fifa Medallia Team\n " + (process.env.HEROKU_URL) ; + var aliases = findUsersForMatchEmail(match); + var condition = {"$or": []}; + _.each(aliases, function(alias) { + condition["$or"].push({"alias": alias}) + }); + schemas.Player.find(condition, "email", function(err, values) { + if (err) { + console.error(err); + } else { + var textValues = []; + _.each(values, function(object) { + textValues.push(object.email); + }); + sendEmail(textValues.join(), creator + ' added a match in which you played', body) + } + }); + + +}; + +module.exports = { + sendMatchEmail: sendMatchEmail +}; \ No newline at end of file diff --git a/app/service/ranking.js b/app/service/ranking.js new file mode 100644 index 0000000..3a80cb8 --- /dev/null +++ b/app/service/ranking.js @@ -0,0 +1,172 @@ +var glicko2 = require("glicko2"); +var _ = require("underscore"); +var schemas = require("../model/schemas"); + +/** + * A tuple is a Json object which contains glicko and model keys for glicko players and db players respectively. + * Init the tuple, at the beginning of the ranking calculation each player will have the same ranking. + * @param players + * @private + */ +var __initPlayersTuple = function (players) { + var playersTuple = {}; + _.each(players, function (player) { + // reset the ranking history + player.rankingHistory = []; + playersTuple[player.alias] = { + glicko: ranking.makePlayer(), + model: player + }; + }); + return playersTuple; +}; + +var __updateRankingDb = function(tuple) { + if (tuple) { + var glickoPlayer = tuple.glicko; + var model = tuple.model; + var newRankingValue = glickoPlayer.getRating().toFixed(2); + model.previousRanking = model.ranking; + model.ranking = newRankingValue; + model.save(); + } + +}; + +var __updatePlayerRating = function(player, ratingBefore, ratingAfter) { + if (player) { + var rating = (ratingAfter.getRating() - ratingBefore.getRating()) / 2; + player.setRating(player.getRating() + rating ); + } +}; + +var __getPlayer = function(playersTuple, alias) { + var player = playersTuple[alias]; + return player ? player["glicko"] : null; +}; + +var __buildGlickoMatch = function(playersTuple, match) { + return [ + __getPlayer(playersTuple, match.home.player), __getPlayer(playersTuple, match.home.partner), + __getPlayer(playersTuple, match.away.player), __getPlayer(playersTuple, match.away.partner), + match.home.goals > match.away.goals ? 1 : match.home.goals < match.away.goals ? 0 : 0.5 + ]; +}; + +/** + * Overriding the glicko2 updateRatings method, basically is a copy with some extra functionality that + * fits better for 2 vs 2 matches + * @param match + */ +glicko2.Glicko2.prototype.updateRatings = function(match){ + var initialPlayersLength = this.players.length; + var avg = function(val1, val2) { + return (val1 + val2)/2; + }; + //clean matches... + this.cleanPreviousMatches(); + //obtain players... + var homePlayer = match[0], homePartner = match[1], awayPlayer = match[2], awayPartner = match[3]; + var matchResult = match[4]; + var virtualHomePlayer, virtualAwayPlayer; + // single player or multiplayer? + if (!homePartner && !awayPartner) { + // creating virtual players since, if we use the players directly the deviation is higher. + virtualHomePlayer = this.makePlayer(homePlayer.getRating()); + virtualAwayPlayer = this.makePlayer(awayPlayer.getRating()); + } else if (!homePartner || !awayPartner){ + console.error("something wrong happened, one of the partners is null"); + return; + } else { + //multiplayer, lets build a virtual player with rankings avg + virtualHomePlayer = this.makePlayer(avg(homePlayer.getRating(), homePartner.getRating())); + virtualAwayPlayer = this.makePlayer(avg(awayPlayer.getRating(), awayPartner.getRating())); + } + + this.addResult(virtualHomePlayer, virtualAwayPlayer, matchResult); + //save original players for future calculations... + var oldVirtualHomePlayer = _.clone(virtualHomePlayer); + var oldVirtualAwayPlayer = _.clone(virtualAwayPlayer); + + this.calculatePlayersRatings(); + console.log("Team 1 delta: " + (virtualHomePlayer.getRating() - oldVirtualHomePlayer.getRating())); + console.log("Team 2 delta: " + (virtualAwayPlayer.getRating() - oldVirtualAwayPlayer.getRating())); + //update all players involved... + __updatePlayerRating(homePlayer, oldVirtualHomePlayer, virtualHomePlayer); + __updatePlayerRating(homePartner, oldVirtualHomePlayer, virtualHomePlayer); + __updatePlayerRating(awayPlayer, oldVirtualAwayPlayer, virtualAwayPlayer); + __updatePlayerRating(awayPartner, oldVirtualAwayPlayer, virtualAwayPlayer); + if (this.players.length != initialPlayersLength) { + this.players.slice(0, initialPlayersLength -2); + } +}; + +var settings = { + // tau : "Reasonable choices are between 0.3 and 1.2, though the system should + // be tested to decide which value results in greatest predictive accuracy." + tau : 0.5, + // rating : default rating + rating : 1500, + //rd : Default rating deviation + // small number = good confidence on the rating accuracy + rd : 10, + //vol : Default volatility (expected fluctation on the player rating) + vol : 0.6 +}; + +var ranking = new glicko2.Glicko2(settings); + +/*** + * This method should be used to perform the initial ranking calculation based on the whole match history * + * @param callback + */ +var calculateGeneralRanking = function(callback) { + console.time("ranking calculation"); + + schemas.Player.find(function(err, players) { + if (err) { + console.log(err); + } else { + var playersTuple = __initPlayersTuple(players); + schemas.Match.find({$and: [{"home.goals": {$gt: -1}}, {"away.goals": {$gt: -1}}]}, function(err, matches) { + _.each(matches, function(match) { + var homePlayer = match.home.player, homePartner = match.home.partner; + console.log("team 1 : " + homePlayer + " " + homePartner); + var awayPlayer = match.away.player, awayPartner = match.away.partner; + console.log("team 2 : " + awayPlayer + " " + awayPartner); + ranking.updateRatings(__buildGlickoMatch(playersTuple, match)); + _.each([playersTuple[homePlayer], playersTuple[homePartner], playersTuple[awayPlayer], playersTuple[awayPartner]], function (tuple) { + if (tuple) { + var player = tuple.glicko; + var model = tuple.model; + var rankingHistory = model.rankingHistory; + var newRanking = player.getRating().toFixed(2); + var lastRanking = rankingHistory[rankingHistory.length-1]; + lastRanking = lastRanking == null ? null : lastRanking.ranking; + console.log(model.alias + ": " + lastRanking + " > " + newRanking); + if (newRanking != lastRanking) { + rankingHistory.push({ + date: match.date, + match: match._id, + ranking: newRanking, + delta: newRanking - lastRanking + }); + } + } + }); + }); + console.timeEnd("ranking calculation"); + //save ranking... + _.each(playersTuple, function(tuple) { + __updateRankingDb(tuple); + }); + callback.call(this, playersTuple); + }).sort({"date": 1}) + } + + }); +}; + +module.exports = { + calculateGeneralRanking: calculateGeneralRanking +}; diff --git a/app/service/statistic.js b/app/service/statistic.js new file mode 100644 index 0000000..9040699 --- /dev/null +++ b/app/service/statistic.js @@ -0,0 +1,147 @@ +var schemas = require("../model/schemas"); +var _ = require("underscore"); +var players = {}; + +var playerStatistics = function(alias) { + return players[alias]; +}; + +var allPlayerStatistics = function() { + return players; +}; + +var updateForPlayer = function(playersArray) { + _.each(playersArray, function(alias) { + players[alias] = __createBasicModel(); //force recalculation + }); + getAllMatches(function(matches) { + _.each(matches, function(match) { + if (match.home.goals == -1 ) return; //FIXME: filter -1 -1 + __collectBasicStat(match, function(alias) { + return playersArray.indexOf(alias) != -1; + }); + }) + }) +}; + +var getAllMatches = function (callback) { + schemas.Match.find({}, function(err, matches) { + if (err) { + console.log(err); + } else { + callback.call(this, matches); + } + }); +}; + +// initialize +getAllMatches(function(matches) { + _.each(matches, function(match) { + if (match.home.goals == -1 ) return; //FIXME: filter -1 -1 + __collectBasicStat(match); + }); +}); + +var __createBasicModel = function(){ + return { + matches: { played:0, won: 0, lost: 0, tied: 0 }, + goals: { received: 0, scored: 0 }, + cards: { + red: { matches: 0, count: 0 }, + yellow: { matches: 0, count: 0 } + } + }; +}; + + +var __getGoals = function(match) { + return { + home: match.home.goals, + away: match.away.goals + } +}; + +var __getCards = function(match) { + var homeYellow = match.home.yellowCards; + var awayYellow = match.away.yellowCards; + var homeRed = match.home.redCards; + var awayRed = match.away.redCards; + if (homeYellow != -1 && awayYellow != -1 && homeRed != -1 && awayRed != -1) { + return { + "home": {"yellow": homeYellow, "red": homeRed}, + "away": {"yellow": awayYellow, "red": awayRed} + } + } + return null; +}; + +var __verify = function(alias) { + if (alias && !players[alias]) { + players[alias] = __createBasicModel(); + } +}; + +var __addPlayerMatch = function(alias, won, lost, tied) { + var matchesStat = players[alias].matches; + matchesStat.played += 1; + matchesStat.won += won; + matchesStat.lost += lost; + matchesStat.tied += tied; +}; + +var __addPlayerGoals = function(alias, scored, received) { + players[alias].goals.scored += scored; + players[alias].goals.received += received; +}; + +var __addPlayerCards = function(alias, yellowCards, redCards) { + players[alias].cards.red.count += redCards; + players[alias].cards.red.matches += 1; + players[alias].cards.yellow.count += yellowCards; + players[alias].cards.yellow.matches += 1; +}; + +var __collectBasicStat = function(match, playerFilter) { + + if (!playerFilter) playerFilter = function() {return true}; + + var matchPlayers = {"home": [match.home.player, match.home.partner], "away": [match.away.player, match.away.partner]}; + + var cards = __getCards(match); + + var goals = __getGoals(match); + var homeWon = goals.home > goals.away ? 1 : 0; + var homeLost = goals.home < goals.away ? 1 : 0; + var homeTied = goals.home == goals.away ? 1 : 0; + + + + _.each(matchPlayers, function(matchTeam, index) { + _.each(matchTeam, function(player) { + if (playerFilter(player) && player) { + __verify(player); + switch (index){ + case "home": + __addPlayerMatch(player, homeWon, homeLost, homeTied); + __addPlayerGoals(player, goals.home, goals.away); + + break; + case "away": + __addPlayerMatch(player, homeLost, homeWon, homeTied); + __addPlayerGoals(player, goals.away, goals.home); + break; + default: throw new Error("invalid state"); + } + if (cards) { + __addPlayerCards(player, cards[index].yellow, cards[index].red); + } + } + }); + }); +}; + +module.exports = { + playerStatistics: playerStatistics, + allPlayerStatistics: allPlayerStatistics, + updateForPlayer: updateForPlayer +}; diff --git a/app/service/tournamentGenerator.js b/app/service/tournamentGenerator.js new file mode 100644 index 0000000..68a4c07 --- /dev/null +++ b/app/service/tournamentGenerator.js @@ -0,0 +1,89 @@ +var schemas = require("../model/schemas"); +var _ = require("underscore"); +var cons = require("../constants"); + +var createMatchFromCSV = function(matchesCSV) { + var array = matchesCSV.split("\n").map(function(line) { return line.split(",").map(function(cell) { return cell.trim() }); }); + return createMatchFromArray(array) +}; + +var createMatchFromArray = function(matchesArray) { + _.each(matchesArray, function(matchArray) { + if (matchArray.length != 11) { + throw new Error("invalid array length"); + } + var match = new schemas.Match(); + match.home.player = matchArray[0]; + match.home.partner = matchArray[1]; + match.home.team = matchArray[2]; + match.away.player = matchArray[3]; + match.away.partner = matchArray[4]; + match.away.team = matchArray[5]; + match.home.goals = parseInt(matchArray[6]); + match.away.goals = parseInt(matchArray[7]); + match.date = new Date(matchArray[8]); + var tournamentName = matchArray[9]; + match.phase = matchArray[10]; + schemas.Tournament.findOne({"name": tournamentName}, "_id", function(err, tournament) { + if (err) { + console.error(err); + return; + } + match.tournament = tournament._id; + saveMatch(match); + }); + }); +}; + +var generateMatches = function(model, secondRound) { + var tournamentName = model.tournamentName; + schemas.Tournament.findOne({"name": tournamentName}, "_id", function(err, tournamentId) { + if (err) { + console.error(err); + return; + } + _.each(model.groups, function(group) { + var createMatches = function(home, away) { + var length = group.teams.length; + var matches = []; + for (var i = length-1; i >= 0; i--) { + for (var j = 1; j < i+1; j++) { + var match = new schemas.Match(); + match.tournament = tournamentId._id; + match.phase = group.name; + match[home].player = group.teams[i].player; + match[home].partner = group.teams[i].partner; + match[home].team = group.teams[i].team; + match[away].player = group.teams[i - j].player; + match[away].partner = group.teams[i - j].partner; + match[away].team = group.teams[i - j].team; + console.log(match.home.player + " & " + match.home.partner + " vs " + match.away.player + " & " + match.away.partner); + matches.push(match); + } + } + _.each(matches, function(match) { + saveMatch(match); + }) + }; + createMatches(cons.HOME, cons.AWAY); + if (secondRound) { + createMatches( cons.AWAY, cons.HOME); + } + }); + }); +}; + +var saveMatch = function(match) { + match.save(function(err, match) { + if (err) { + console.error(err); + throw new Error(); + } + console.log("created"); + }); +}; + +module.exports = { + createMatchFromCSV: createMatchFromCSV, + generate: generateMatches +}; \ No newline at end of file diff --git a/backup/prod.backup_2015-09-09.tar.gz b/backup/prod.backup_2015-09-09.tar.gz new file mode 100644 index 0000000..18da465 Binary files /dev/null and b/backup/prod.backup_2015-09-09.tar.gz differ diff --git a/backup/prod.backup_2015-09-10.tar.gz b/backup/prod.backup_2015-09-10.tar.gz new file mode 100644 index 0000000..8ad91b3 Binary files /dev/null and b/backup/prod.backup_2015-09-10.tar.gz differ diff --git a/backup/prod.backup_2015-09-11.tar.gz b/backup/prod.backup_2015-09-11.tar.gz new file mode 100644 index 0000000..ce7ebd3 Binary files /dev/null and b/backup/prod.backup_2015-09-11.tar.gz differ diff --git a/backup/prod.backup_2015-09-12.tar.gz b/backup/prod.backup_2015-09-12.tar.gz new file mode 100644 index 0000000..e819dbf Binary files /dev/null and b/backup/prod.backup_2015-09-12.tar.gz differ diff --git a/backup/prod.backup_2015-09-13.tar.gz b/backup/prod.backup_2015-09-13.tar.gz new file mode 100644 index 0000000..a0b14f2 Binary files /dev/null and b/backup/prod.backup_2015-09-13.tar.gz differ diff --git a/backup/prod.backup_2015-09-14.tar.gz b/backup/prod.backup_2015-09-14.tar.gz new file mode 100644 index 0000000..5a03746 Binary files /dev/null and b/backup/prod.backup_2015-09-14.tar.gz differ diff --git a/backup/prod.backup_2015-09-16.tar.gz b/backup/prod.backup_2015-09-16.tar.gz new file mode 100644 index 0000000..9fb1c16 Binary files /dev/null and b/backup/prod.backup_2015-09-16.tar.gz differ diff --git a/backup/prod.backup_2015-09-17.tar.gz b/backup/prod.backup_2015-09-17.tar.gz new file mode 100644 index 0000000..bdc796f Binary files /dev/null and b/backup/prod.backup_2015-09-17.tar.gz differ diff --git a/bower.json b/bower.json new file mode 100644 index 0000000..487efd1 --- /dev/null +++ b/bower.json @@ -0,0 +1,28 @@ +{ + "name": "fifa.tournament", + "version": "0.0.0", + "homepage": "https://github.com/ebergama/fifa.tournament", + "authors": [ + "Ezequiel Bergamaschi " + ], + "main": "server.js", + "license": "MIT", + "ignore": [ + "**/.*", + "node_modules", + "bower_components", + "test", + "tests" + ], + "dependencies": { + "angular-bootstrap": "~0.13.0", + "bootstrap": "~3.3.5", + "font-awesome": "~4.3.0", + "metisMenu": "~2.0.2", + "jquery": "~2.1.4", + "angular-route": "~1.4.1", + "jquery.countdown": "~2.0.4", + "underscore": "1.8.3", + "angular": "~1.4.5" + } +} diff --git a/env.config b/env.config new file mode 100644 index 0000000..17b39f5 --- /dev/null +++ b/env.config @@ -0,0 +1,15 @@ +### Environmental variables + +## Gmail smtp account setup +#FIFA_EMAIL= +#FIFA_EMAIL_PASS= + +## Mongo Database Url +LOCAL_DB_URL=mongodb://localhost/fifa +## Local url & port +LOCAL_URL=http://localhost +PORT=8080 + +## Google client id and client secret for authentication +GOOGLE_CLIENT_ID=1 +GOOGLE_CLIENT_SECRET=1 diff --git a/index.html b/index.html deleted file mode 100644 index 6b78067..0000000 --- a/index.html +++ /dev/null @@ -1,114 +0,0 @@ - - - MArge Fifa - - - - - - - - - - -
- - - - - - -
- {{player}} - {{tagFilter}} - - - - - - - - - - - - - - - - - - - - - - - -
DateHomeAway
- {{match.date | date:'yyyy-MM-dd'}} - - - - -
-
- {{match.home.goals}} - ({{match.home.penalties}}) - - {{match.away.goals}} - ({{match.away.penalties}}) - -
-
- - -
Nada por aqui!
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PosicionEquipoPJPGPEPPGFGCDGPuntos
{{$index + 1}} -
- - -
{{position.matchesPlayed}}{{position.matchesWon}}{{position.matchesTied}}{{position.matchesLost}}{{position.goalsScored}}{{position.goalsReceived}}{{position.goalsDiff}}{{position.points}}
-
- - \ No newline at end of file diff --git a/matches.json b/matches.json deleted file mode 100644 index a7837ca..0000000 --- a/matches.json +++ /dev/null @@ -1,2345 +0,0 @@ -[ - { - date:'', - home: { - players: ["Charly", "Juan"], - team:"Inglaterra", - goals: -1 - }, - away: { - players: ["Hernan", "Gaby"], - team:"Argentina", - goals: -1 - }, - tags:["Mundial 2", "Grupo A"], - }, - { - date:'', - home: { - players: ["Charly", "Juan"], - team:"Inglaterra", - goals: 0 - }, - away: { - players: ["FerO", "Mauri"], - team:"Francia", - goals: 0 - }, - tags:["Mundial 2", "Grupo A"], - }, - { - date:'', - home: { - players: ["Charly", "Juan"], - team:"Inglaterra", - goals: 0 - }, - away: { - players: ["Leandro", "Santi"], - team:"Brasil", - goals: 1 - }, - tags:["Mundial 2", "Grupo A"], - }, - { - date:'', - home: { - players: ["Leandro", "Santi"], - team:"Brasil", - goals: 5 - }, - away: { - players: ["FerO", "Mauri"], - team:"Francia", - goals: 2 - }, - tags:["Mundial 2", "Grupo A"], - }, - { - date:'', - home: { - players: ["Leandro", "Santi"], - team:"Brasil", - goals: 2 - }, - away: { - players: ["Hernan", "Gaby"], - team:"Argentina", - goals: 2 - }, - tags:["Mundial 2", "Grupo A"], - }, - { - date:'', - home: { - players: ["FerO", "Mauri"], - team:"Francia", - goals: 1 - }, - away: { - players: ["Hernan", "Gaby"], - team:"Argentina", - goals: 0 - }, - tags:["Mundial 2", "Grupo A"], - }, - { - date:'2014-10-06T18:00:00.000Z', - home: { - players: ["NicoR", "NicoL"], - team:"Alemania", - goals: 4 - }, - away: { - players: ["Ariel", "Leo"], - team:"Espana", - goals: 1 - }, - tags:["Mundial 2", "Grupo B"], - }, - { - date:'2014-10-03T20:00:00.000Z', - home: { - players: ["NicoR", "NicoL"], - team:"Alemania", - goals: 4 - }, - away: { - players: ["DaniG", "Malcom"], - team:"Italia", - goals: 0 - }, - tags:["Mundial 2", "Grupo B"] - }, - { - date:'2014-10-03T20:00:00.000Z', - home: { - players: ["NicoR", "NicoL"], - team:"Alemania", - goals: 2 - }, - away: { - players: ["Michu", "FerP"], - team:"Holanda", - goals: 0 - }, - tags:["Mundial 2", "Grupo B"], - }, - { - date:'2014-10-03T20:00:00.000Z', - home: { - players: ["Ariel", "Leo"], - team:"Espana", - goals: 1 - }, - away: { - players: ["DaniG", "Malcom"], - team:"Italia", - goals: 1 - }, - tags:["Mundial 2", "Grupo B"] - }, - { - date:'2014-10-03T20:00:00.000Z', - home: { - players: ["Ariel", "Leo"], - team:"Espana", - goals: 2 - }, - away: { - players: ["Michu", "FerP"], - team:"Holanda", - goals: 0 - }, - tags:["Mundial 2", "Grupo B"] - }, - { - date:'2014-10-03T20:00:00.000Z', - home: { - players: ["DaniG", "Malcom"], - team:"Italia", - goals: 2 - }, - away: { - players: ["Michu", "FerP"], - team:"Holanda", - goals: 1 - }, - tags:["Mundial 2", "Grupo B"] - }, - { - date:'', - home: { - players: ["Leandro", "Santi"], - team:"Brasil", - goals: 3 - }, - away: { - players: ["Leo", "Ariel"], - team:"Espana", - goals: 1 - }, - tags:["Mundial 2", "Semifinales"], - }, - { - date:'', - home: { - players: ["Mauri", "Martin"], - team:"Francia", - goals: 2 - }, - away: { - players: ["NicoR", "NicoL"], - team:"Alemania", - goals: 1 - }, - tags:["Mundial 2", "Semifinales"], - }, - { - date:'', - home: { - players: ["Leandro", "Santi"], - team:"Brasil", - goals: 2 - }, - away: { - players: ["Mauri", "Martin"], - team:"Francia", - goals: 0 - }, - tags:["Mundial 2", "Final"], - }, - { - date:'', - home: { - players: ["NicoR", "DaniG"], - team:"", - goals: 1 - }, - away: { - players: ["Mauri", "FerO"], - team:"", - goals: 1 - }, - tags:["Torneo 0", "Primera"], - }, - { - date:'', - home: { - players: ["Michu", "Charly"], - team:"", - goals: 0 - }, - away: { - players: ["Leo", "Gaby"], - team:"", - goals: 3 - }, - tags:["Torneo 0", "Primera"], - }, - { - date:'', - home: { - players: ["NicoR", "DaniG"], - team:"", - goals: 3 - }, - away: { - players: ["Michu", "Charly"], - team:"", - goals: 0 - }, - tags:["Torneo 0", "Primera"], - }, - { - date:'', - home: { - players: ["Mauri", "FerO"], - team:"", - goals: 1 - }, - away: { - players: ["Leo", "Gaby"], - team:"", - goals: 1 - }, - tags:["Torneo 0", "Primera"], - }, - { - date:'', - home: { - players: ["NicoR", "DaniG"], - team:"", - goals: 0 - }, - away: { - players: ["Leo", "Gaby"], - team:"", - goals: 1 - }, - tags:["Torneo 0", "Primera"], - }, - { - date:'', - home: { - players: ["Mauri", "FerO"], - team:"", - goals: 2 - }, - away: { - players: ["Michu", "Charly"], - team:"", - goals: 1 - }, - tags:["Torneo 0", "Primera"], - }, - { - date:'', - home: { - players: ["NicoR", "DaniG"], - team:"", - goals: 1 - }, - away: { - players: ["Malcom", "Gamba"], - team:"", - goals: 1 - }, - tags:["Torneo 0", "Primera"], - }, - { - date:'', - home: { - players: ["Mauri", "FerO"], - team:"", - goals: 0 - }, - away: { - players: ["Malcom", "Gamba"], - team:"", - goals: 0 - }, - tags:["Torneo 0", "Primera"], - }, - { - date:'', - home: { - players: ["Michu", "Charly"], - team:"", - goals: 0 - }, - away: { - players: ["Malcom", "Gamba"], - team:"", - goals: 0 - }, - tags:["Torneo 0", "Primera"], - }, - { - date:'', - home: { - players: ["Leo", "Gaby"], - team:"", - goals: 2 - }, - away: { - players: ["Malcom", "Gamba"], - team:"", - goals: 1 - }, - tags:["Torneo 0", "Primera"], - }, - { - date:'', - home: { - players: ["NicoR", "Gaby"], - team:"", - goals: 1 - }, - away: { - players: ["Michu", "Mauri"], - team:"", - goals: 1 - }, - tags:["Torneo 1", "Primera"], - }, - { - date:'', - home: { - players: ["Leo", "Michu"], - team:"", - goals: 0 - }, - away: { - players: ["Gaby", "Mauri"], - team:"", - goals: 1 - }, - tags:["Torneo 1", "Primera"], - }, - { - date:'', - home: { - players: ["Leo", "Mauri"], - team:"", - goals: 2 - }, - away: { - players: ["NicoR", "Michu"], - team:"", - goals: 4 - }, - tags:["Torneo 1", "Primera"], - }, - { - date:'', - home: { - players: ["Leo", "Gaby"], - team:"", - goals: 1 - }, - away: { - players: ["NicoR", "Mauri"], - team:"", - goals: 4 - }, - tags:["Torneo 1", "Primera"], - }, - { - date:'', - home: { - players: ["Leo", "NicoR"], - team:"", - goals: 2 - }, - away: { - players: ["Gaby", "Michu"], - team:"", - goals: 1 - }, - tags:["Torneo 1", "Primera"], - }, - { - date:'', - home: { - players: ["Juan", "DaniG"], - team:"", - goals: 5 - }, - away: { - players: ["FerO", "Gamba"], - team:"", - goals: 0 - }, - tags:["Torneo 1", "Segunda"], - }, - { - date:'', - home: { - players: ["Juan", "DaniG"], - team:"", - goals: 0 - }, - away: { - players: ["Charly", "Malcom"], - team:"", - goals: 0 - }, - tags:["Torneo 1", "Segunda"], - }, - { - date:'', - home: { - players: ["FerO", "Gamba"], - team:"", - goals: 0 - }, - away: { - players: ["Charly", "Malcom"], - team:"", - goals: 1 - }, - tags:["Torneo 1", "Segunda"], - }, - { - date:'2014-03-10T00:00:00.000Z', - home:{ - players:["Mauri", "Michu"], - team:"", - goals: 4 - }, - away:{ - players:["Juan", "Charly"], - team:"", - goals: 0 - }, - tags: ["Torneo 2", "Primera"], - }, - { - date:'2014-03-11T00:00:00.000Z', - home:{ - players:["Mauri", "Juan"], - team:"", - goals: 4 - }, - away:{ - players:["Michu", "Charly"], - team:"", - goals: 0 - }, - tags: ["Torneo 2", "Primera"], - }, - { - date:'2014-03-07T00:00:00.000Z', - home:{ - players:["Mauri", "Charly"], - team:"", - goals: 1 - }, - away:{ - players:["Michu", "Juan"], - team:"", - goals: 3 - }, - tags: ["Torneo 2", "Primera"], - }, - { - date:'2014-03-11T00:00:00.000Z', - home:{ - players:["NicoR", "Mauri"], - team:"", - goals: 1 - }, - away:{ - players:["Juan", "Charly"], - team:"", - goals: 0 - }, - tags: ["Torneo 2", "Primera"], - }, - { - date:'2014-03-06T00:00:00.000Z', - home:{ - players:["NicoR", "Juan"], - team:"", - goals: 4 - }, - away:{ - players:["Mauri", "Charly"], - team:"", - goals: 0 - }, - tags: ["Torneo 2", "Primera"], - }, - { - date:'2014-03-14T00:00:00.000Z', - home:{ - players:["NicoR", "Charly"], - team:"", - goals: 0 - }, - away:{ - players:["Mauri", "Juan"], - team:"", - goals: 5 - }, - tags: ["Torneo 2", "Primera"], - }, - { - date:'2014-03-12T00:00:00.000Z', - home:{ - players:["NicoR", "Mauri"], - team:"", - goals: 3 - }, - away:{ - players:["Michu", "Juan"], - team:"", - goals: 0 - }, - tags: ["Torneo 2", "Primera"], - }, - { - date:'2014-02-28T00:00:00.000Z', - home:{ - players:["NicoR", "Michu"], - team:"", - goals: 3 - }, - away:{ - players:["Mauri", "Juan"], - team:"", - goals: 3 - }, - tags: ["Torneo 2", "Primera"], - }, - { - date:'2014-02-26T00:00:00.000Z', - home:{ - players:["NicoR", "Juan"], - team:"", - goals: 4 - }, - away:{ - players:["Mauri", "Michu"], - team:"", - goals: 3 - }, - tags: ["Torneo 2", "Primera"], - }, - { - date:'2014-02-24T00:00:00.000Z', - home:{ - players:["NicoR", "Michu"], - team:"", - goals: 2 - }, - away:{ - players:["Juan", "Charly"], - team:"", - goals: 0 - }, - tags: ["Torneo 2", "Primera"], - }, - { - date:'2014-03-14T00:00:00.000Z', - home:{ - players:["NicoR", "Juan"], - team:"", - goals: 2 - }, - away:{ - players:["Michu", "Charly"], - team:"", - goals: 0 - }, - tags: ["Torneo 2", "Primera"], - }, - { - date:'2014-03-14T00:00:00.000Z', - home:{ - players:["NicoR", "Charly"], - team:"", - goals: 0 - }, - away:{ - players:["Michu", "Juan"], - team:"", - goals: 1 - }, - tags: ["Torneo 2", "Primera"], - }, - { - date:'2014-03-05T00:00:00.000Z', - home:{ - players:["NicoR", "Mauri"], - team:"", - goals: 3 - }, - away:{ - players:["Michu", "Charly"], - team:"", - goals: 0 - }, - tags: ["Torneo 2", "Primera"], - }, - { - date:'2014-03-05T00:00:00.000Z', - home:{ - players:["NicoR", "Michu"], - team:"", - goals: 4 - }, - away:{ - players:["Mauri", "Charly"], - team:"", - goals: 2 - }, - tags: ["Torneo 2", "Primera"], - }, - { - date:'2014-03-12T00:00:00.000Z', - home:{ - players:["NicoR", "Charly"], - team:"", - goals: 1 - }, - away:{ - players:["Mauri", "Michu"], - team:"", - goals: 2 - }, - tags: ["Torneo 2", "Primera"], - }, - { - date:'2014-03-11T00:00:00.000Z', - home:{ - players:["Malcom", "Gamba"], - team:"", - goals: 2 - }, - away:{ - players:["DaniG", "FerO"], - team:"", - goals: 0 - }, - tags: ["Torneo 2", "Segunda"], - }, - { - date:'2014-03-07T00:00:00.000Z', - home:{ - players:["Malcom", "Gamba"], - team:"", - goals: 0 - }, - away:{ - players:["Gaby", "Leo"], - team:"", - goals: 3 - }, - tags: ["Torneo 2", "Segunda"], - }, - { - date:'2014-03-07T00:00:00.000Z', - home:{ - players:["DaniG", "FerO"], - team:"", - goals: 1 - }, - away:{ - players:["Gaby", "Leo"], - team:"", - goals: 3 - }, - tags: ["Torneo 2", "Segunda"], - }, - { - date:'2014-03-07T00:00:00.000Z', - home:{ - players:["Malcom", "Gamba"], - team:"", - goals: -1 - }, - away:{ - players:["DaniG", "Gaby"], - team:"", - goals: -1 - }, - tags: ["Torneo 2", "Segunda"], - }, - { - date:'2014-03-11T00:00:00.000Z', - home:{ - players:["Malcom", "Gamba"], - team:"", - goals: 1 - }, - away:{ - players:["DaniG", "Leo"], - team:"", - goals: 2 - }, - tags: ["Torneo 2", "Segunda"], - }, - { - date:'2014-02-28T00:00:00.000Z', - home:{ - players:["Malcom", "Gamba"], - team:"", - goals: 2 - }, - away:{ - players:["Gaby", "FerO"], - team:"", - goals: 1 - }, - tags: ["Torneo 2", "Segunda"], - }, - { - date:'2014-03-14T00:00:00.000Z', - home:{ - players:["Malcom", "Gamba"], - team:"", - goals: 0 - }, - away:{ - players:["Leo", "FerO"], - team:"", - goals: 4 - }, - tags: ["Torneo 2", "Segunda"], - }, - { - date:'2014-02-24T00:00:00.000Z', - home:{ - players:["DaniG", "FerO"], - team:"", - goals: 1 - }, - away:{ - players:["Malcom", "Gaby"], - team:"", - goals: 1 - }, - tags: ["Torneo 2", "Segunda"], - }, - { - date:'2014-03-13T00:00:00.000Z', - home:{ - players:["DaniG", "FerO"], - team:"", - goals: -1 - }, - away:{ - players:["Malcom", "Leo"], - team:"", - goals: -1 - }, - tags: ["Torneo 2", "Segunda"], - }, - { - date:'2014-03-06T00:00:00.000Z', - home:{ - players:["DaniG", "FerO"], - team:"", - goals: 2 - }, - away:{ - players:["Gaby", "Gamba"], - team:"", - goals: 4 - }, - tags: ["Torneo 2", "Segunda"], - }, - { - date:'2014-03-13T00:00:00.000Z', - home:{ - players:["DaniG", "FerO"], - team:"", - goals: 1 - }, - away:{ - players:["Leo", "Gamba"], - team:"", - goals: 2 - }, - tags: ["Torneo 2", "Segunda"], - }, - { - date:'2014-02-26T00:00:00.000Z', - home:{ - players:["Gaby", "Leo"], - team:"", - goals: 2 - }, - away:{ - players:["Malcom", "DaniG"], - team:"", - goals: 0 - }, - tags: ["Torneo 2", "Segunda"], - }, - { - date:'2014-02-27T00:00:00.000Z', - home:{ - players:["Gaby", "Leo"], - team:"", - goals: 2 - }, - away:{ - players:["Malcom", "FerO"], - team:"", - goals: 2 - }, - tags: ["Torneo 2", "Segunda"], - }, - { - date:'2014-02-25T00:00:00.000Z', - home:{ - players:["Gaby", "Leo"], - team:"", - goals: 4 - }, - away:{ - players:["DaniG", "Gamba"], - team:"", - goals: 0 - }, - tags: ["Torneo 2", "Segunda"], - }, - { - date:'2014-02-27T00:00:00.000Z', - home:{ - players:["Gaby", "Leo"], - team:"", - goals: 4 - }, - away:{ - players:["FerO", "Gamba"], - team:"", - goals: 0 - }, - tags: ["Torneo 2", "Segunda"], - }, - { - date:'', - home:{ - players:["Mauri", "Juan"], - team:"", - goals: 2 - }, - away:{ - players:["Leo", "Gaby"], - team:"", - goals: 1 - }, - tags: ["Torneo 3", "Primera"], - }, - { - date:'', - home:{ - players:["Mauri", "Leo"], - team:"", - goals: 0 - }, - away:{ - players:["Juan", "Gaby"], - team:"", - goals: 1 - }, - tags: ["Torneo 3", "Primera"], - }, - { - date:'', - home:{ - players:["Mauri", "Gaby"], - team:"", - goals: 1 - }, - away:{ - players:["Juan", "Leo"], - team:"", - goals: 3 - }, - tags: ["Torneo 3", "Primera"], - }, - { - date:'', - home:{ - players:["NicoR", "Mauri"], - team:"", - goals: 0 - }, - away:{ - players:["Leo", "Gaby"], - team:"", - goals: 2 - }, - tags: ["Torneo 3", "Primera"], - }, - { - date:'', - home:{ - players:["NicoR", "Leo"], - team:"", - goals: 1 - }, - away:{ - players:["Mauri", "Gaby"], - team:"", - goals: 6 - }, - tags: ["Torneo 3", "Primera"], - }, - { - date:'', - home:{ - players:["NicoR", "Gaby"], - team:"", - goals: 3 - }, - away:{ - players:["Mauri", "Leo"], - team:"", - goals: 1 - }, - tags: ["Torneo 3", "Primera"], - }, - { - date:'', - home:{ - players:["NicoR", "Mauri"], - team:"", - goals: 0 - }, - away:{ - players:["Juan", "Leo"], - team:"", - goals: 0 - }, - tags: ["Torneo 3", "Primera"], - }, - { - date:'', - home:{ - players:["NicoR", "Juan"], - team:"", - goals: 1 - }, - away:{ - players:["Mauri", "Leo"], - team:"", - goals: 0 - }, - tags: ["Torneo 3", "Primera"], - }, - { - date:'', - home:{ - players:["NicoR", "Leo"], - team:"", - goals: 1 - }, - away:{ - players:["Mauri", "Juan"], - team:"", - goals: 4 - }, - tags: ["Torneo 3", "Primera"], - }, - { - date:'', - home:{ - players:["NicoR", "Juan"], - team:"", - goals: 0 - }, - away:{ - players:["Leo", "Gaby"], - team:"", - goals: 3 - }, - tags: ["Torneo 3", "Primera"], - }, - { - date:'', - home:{ - players:["NicoR", "Leo"], - team:"", - goals: 3 - }, - away:{ - players:["Juan", "Gaby"], - team:"", - goals: 1 - }, - tags: ["Torneo 3", "Primera"], - }, - { - date:'', - home:{ - players:["NicoR", "Gaby"], - team:"", - goals: 1 - }, - away:{ - players:["Juan", "Leo"], - team:"", - goals: 2 - }, - tags: ["Torneo 3", "Primera"], - }, - { - date:'', - home:{ - players:["NicoR", "Mauri"], - team:"", - goals: 3 - }, - away:{ - players:["Juan", "Gaby"], - team:"", - goals: 1 - }, - tags: ["Torneo 3", "Primera"], - }, - { - date:'', - home:{ - players:["NicoR", "Juan"], - team:"", - goals: 1 - }, - away:{ - players:["Mauri", "Gaby"], - team:"", - goals: 2 - }, - tags: ["Torneo 3", "Primera"], - }, - { - date:'', - home:{ - players:["NicoR", "Gaby"], - team:"", - goals: 3 - }, - away:{ - players:["Mauri", "Juan"], - team:"", - goals: 3 - }, - tags: ["Torneo 3", "Primera"], - }, - { - date:'2014-07-31T00:00:00.000Z', - home:{ - players:["Malcom", "Santi"], - team:"", - goals: 1 - }, - away:{ - players:["Michu", "FerO"], - team:"", - goals: 2 - }, - tags: ["Torneo 3", "Segunda"], - }, - { - date:'2014-08-01T00:00:00.000Z', - home:{ - players:["Malcom", "Santi"], - team:"", - goals: 2 - }, - away:{ - players:["Charly", "Hernan"], - team:"", - goals: 1 - }, - tags: ["Torneo 3", "Segunda"], - }, - { - date:'2014-07-30T00:00:00.000Z', - home:{ - players:["Michu", "FerO"], - team:"", - goals: 0 - }, - away:{ - players:["Charly", "Hernan"], - team:"", - goals: 1 - }, - tags: ["Torneo 3", "Segunda"], - }, - { - date:'2014-07-28T00:00:00.000Z', - home:{ - players:["Malcom", "Santi"], - team:"", - goals: 2 - }, - away:{ - players:["Michu", "Charly"], - team:"", - goals: 0 - }, - tags: ["Torneo 3", "Segunda"], - }, - { - date:'2014-07-23T00:00:00.000Z', - home:{ - players:["Malcom", "Santi"], - team:"", - goals: 1 - }, - away:{ - players:["Michu", "Hernan"], - team:"", - goals: 1 - }, - tags: ["Torneo 3", "Segunda"], - }, - { - date:'2014-07-21T00:00:00.000Z', - home:{ - players:["Malcom", "Santi"], - team:"", - goals: 3 - }, - away:{ - players:["Charly", "FerO"], - team:"", - goals: 0 - }, - tags: ["Torneo 3", "Segunda"], - }, - { - date:'2014-07-03T00:00:00.000Z', - home:{ - players:["Malcom", "Santi"], - team:"", - goals: 1 - }, - away:{ - players:["Hernan", "FerO"], - team:"", - goals: 1 - }, - tags: ["Torneo 3", "Segunda"], - }, - { - date:'2014-07-07T00:00:00.000Z', - home:{ - players:["Michu", "FerO"], - team:"", - goals: 1 - }, - away:{ - players:["Malcom", "Charly"], - team:"", - goals: 0 - }, - tags: ["Torneo 3", "Segunda"], - }, - { - date:'2014-07-24T00:00:00.000Z', - home:{ - players:["Michu", "FerO"], - team:"", - goals: 0 - }, - away:{ - players:["Malcom", "Hernan"], - team:"", - goals: 0 - }, - tags: ["Torneo 3", "Segunda"], - }, - { - date:'2014-07-22T00:00:00.000Z', - home:{ - players:["Michu", "FerO"], - team:"", - goals: 1 - }, - away:{ - players:["Charly", "Santi"], - team:"", - goals: 0 - }, - tags: ["Torneo 3", "Segunda"], - }, - { - date:'2014-07-10T00:00:00.000Z', - home:{ - players:["Michu", "FerO"], - team:"", - goals: 2 - }, - away:{ - players:["Hernan", "Santi"], - team:"", - goals: 2 - }, - tags: ["Torneo 3", "Segunda"], - }, - { - date:'2014-07-08T00:00:00.000Z', - home:{ - players:["Charly", "Hernan"], - team:"", - goals: 0 - }, - away:{ - players:["Malcom", "Michu"], - team:"", - goals: 0 - }, - tags: ["Torneo 3", "Segunda"], - }, - { - date:'2014-07-11T00:00:00.000Z', - home:{ - players:["Charly", "Hernan"], - team:"", - goals: 1 - }, - away:{ - players:["Malcom", "FerO"], - team:"", - goals: 3 - }, - tags: ["Torneo 3", "Segunda"], - }, - { - date:'2014-07-25T00:00:00.000Z', - home:{ - players:["Charly", "Hernan"], - team:"", - goals: 0 - }, - away:{ - players:["Michu", "Santi"], - team:"", - goals: 7 - }, - tags: ["Torneo 3", "Segunda"], - }, - { - date:'2014-07-25T00:00:00.000Z', - home:{ - players:["Charly", "Hernan"], - team:"", - goals: 1 - }, - away:{ - players:["FerO", "Santi"], - team:"", - goals: 0 - }, - tags: ["Torneo 3", "Segunda"], - }, - { - date:'2014-09-02T00:00:00.000Z', - home:{ - players:["Gaby", "Mauri"], - team:"", - goals: 6 - }, - away:{ - players:["Leo", "Malcom"], - team:"", - goals: 0 - }, - tags: ["Torneo 4", "Primera"], - }, - { - date:'2014-09-02T00:00:00.000Z', - home:{ - players:["Gaby", "Leo"], - team:"", - goals: 1 - }, - away:{ - players:["Mauri", "Malcom"], - team:"", - goals: 1 - }, - tags: ["Torneo 4", "Primera"], - }, - { - date:'2014-08-26T00:00:00.000Z', - home:{ - players:["Gaby", "Malcom"], - team:"", - goals: 0 - }, - away:{ - players:["Mauri", "Leo"], - team:"", - goals: 1 - }, - tags: ["Torneo 4", "Primera"], - }, - { - date:'2014-09-03T00:00:00.000Z', - home:{ - players:["Juan", "Gaby"], - team:"", - goals: 2 - }, - away:{ - players:["Leo", "Malcom"], - team:"", - goals: 3 - }, - tags: ["Torneo 4", "Primera"], - }, - { - date:'2014-09-01T00:00:00.000Z', - home:{ - players:["Juan", "Leo"], - team:"", - goals: 3 - }, - away:{ - players:["Gaby", "Malcom"], - team:"", - goals: 1 - }, - tags: ["Torneo 4", "Primera"], - }, - { - date:'2014-08-26T00:00:00.000Z', - home:{ - players:["Juan", "Malcom"], - team:"", - goals: 1 - }, - away:{ - players:["Gaby", "Leo"], - team:"", - goals: 4 - }, - tags: ["Torneo 4", "Primera"], - }, - { - date:'2014-08-25T00:00:00.000Z', - home:{ - players:["Juan", "Gaby"], - team:"", - goals: 1 - }, - away:{ - players:["Mauri", "Leo"], - team:"", - goals: 2 - }, - tags: ["Torneo 4", "Primera"], - }, - { - date:'2014-09-05T00:00:00.000Z', - home:{ - players:["Juan", "Mauri"], - team:"", - goals: 1 - }, - away:{ - players:["Gaby", "Leo"], - team:"", - goals: 1 - }, - tags: ["Torneo 4", "Primera"], - }, - { - date:'2014-08-27T00:00:00.000Z', - home:{ - players:["Juan", "Leo"], - team:"", - goals: 1 - }, - away:{ - players:["Gaby", "Mauri"], - team:"", - goals: 2 - }, - tags: ["Torneo 4", "Primera"], - }, - { - date:'2014-08-22T00:00:00.000Z', - home:{ - players:["Juan", "Mauri"], - team:"", - goals: 3 - }, - away:{ - players:["Leo", "Malcom"], - team:"", - goals: 2 - }, - tags: ["Torneo 4", "Primera"], - }, - { - date:'2014-08-29T00:00:00.000Z', - home:{ - players:["Juan", "Leo"], - team:"", - goals: 3 - }, - away:{ - players:["Mauri", "Malcom"], - team:"", - goals: 2 - }, - tags: ["Torneo 4", "Primera"], - }, - { - date:'2014-09-04T00:00:00.000Z', - home:{ - players:["Juan", "Malcom"], - team:"", - goals: 3 - }, - away:{ - players:["Mauri", "Leo"], - team:"", - goals: 1 - }, - tags: ["Torneo 4", "Primera"], - }, - { - date:'2014-08-21T00:00:00.000Z', - home:{ - players:["Juan", "Gaby"], - team:"", - goals: 1 - }, - away:{ - players:["Mauri", "Malcom"], - team:"", - goals: 3 - }, - tags: ["Torneo 4", "Primera"], - }, - { - date:'2014-08-29T00:00:00.000Z', - home:{ - players:["Juan", "Mauri"], - team:"", - goals: 1 - }, - away:{ - players:["Gaby", "Malcom"], - team:"", - goals: 2 - }, - tags: ["Torneo 4", "Primera"], - }, - { - date:'2014-09-01T00:00:00.000Z', - home:{ - players:["Juan", "Malcom"], - team:"", - goals: 4 - }, - away:{ - players:["Gaby", "Mauri"], - team:"", - goals: 2 - }, - tags: ["Torneo 4", "Primera"], - }, - { - date:'2014-08-21T00:00:00.000Z', - home:{ - players:["Michu", "NicoR"], - team:"", - goals: 7 - }, - away:{ - players:["FerO", "DaniG"], - team:"", - goals: 1 - }, - tags: ["Torneo 4", "Segunda"], - }, - { - date:'2014-08-27T00:00:00.000Z', - home:{ - players:["Michu", "FerO"], - team:"", - goals: 1 - }, - away:{ - players:["NicoR", "DaniG"], - team:"", - goals: 1 - }, - tags: ["Torneo 4", "Segunda"], - }, - { - date:'2014-08-27T00:00:00.000Z', - home:{ - players:["Michu", "DaniG"], - team:"", - goals: 0 - }, - away:{ - players:["NicoR", "FerO"], - team:"", - goals: 2 - }, - tags: ["Torneo 4", "Segunda"], - }, - { - date:'2014-08-28T00:00:00.000Z', - home:{ - players:["Santi", "Michu"], - team:"", - goals: 3 - }, - away:{ - players:["FerO", "DaniG"], - team:"", - goals: 2 - }, - tags: ["Torneo 4", "Segunda"], - }, - { - date:'2014-08-25T00:00:00.000Z', - home:{ - players:["Santi", "FerO"], - team:"", - goals: 0 - }, - away:{ - players:["Michu", "DaniG"], - team:"", - goals: 0 - }, - tags: ["Torneo 4", "Segunda"], - }, - { - date:'2014-08-28T00:00:00.000Z', - home:{ - players:["Santi", "DaniG"], - team:"", - goals: 3 - }, - away:{ - players:["Michu", "FerO"], - team:"", - goals: 0 - }, - tags: ["Torneo 4", "Segunda"], - }, - { - date:'2014-08-29T00:00:00.000Z', - home:{ - players:["Santi", "Michu"], - team:"", - goals: 2 - }, - away:{ - players:["NicoR", "FerO"], - team:"", - goals: 1 - }, - tags: ["Torneo 4", "Segunda"], - }, - { - date:'2014-08-29T00:00:00.000Z', - home:{ - players:["Santi", "NicoR"], - team:"", - goals: 5 - }, - away:{ - players:["Michu", "FerO"], - team:"", - goals: 0 - }, - tags: ["Torneo 4", "Segunda"], - }, - { - date:'2014-08-26T00:00:00.000Z', - home:{ - players:["Santi", "FerO"], - team:"", - goals: 2 - }, - away:{ - players:["Michu", "NicoR"], - team:"", - goals: 2 - }, - tags: ["Torneo 4", "Segunda"], - }, - { - date:'2014-09-01T00:00:00.000Z', - home:{ - players:["Santi", "NicoR"], - team:"", - goals: 1 - }, - away:{ - players:["FerO", "DaniG"], - team:"", - goals: 1 - }, - tags: ["Torneo 4", "Segunda"], - }, - { - date:'2014-08-29T00:00:00.000Z', - home:{ - players:["Santi", "FerO"], - team:"", - goals: 4 - }, - away:{ - players:["NicoR", "DaniG"], - team:"", - goals: 0 - }, - tags: ["Torneo 4", "Segunda"], - }, - { - date:'2014-09-01T00:00:00.000Z', - home:{ - players:["Santi", "DaniG"], - team:"", - goals: 2 - }, - away:{ - players:["NicoR", "FerO"], - team:"", - goals: 0 - }, - tags: ["Torneo 4", "Segunda"], - }, - { - date:'2014-09-02T00:00:00.000Z', - home:{ - players:["Santi", "Michu"], - team:"", - goals: 4 - }, - away:{ - players:["NicoR", "DaniG"], - team:"", - goals: 2 - }, - tags: ["Torneo 4", "Segunda"], - }, - { - date:'2014-09-03T00:00:00.000Z', - home:{ - players:["Santi", "NicoR"], - team:"", - goals: 5 - }, - away:{ - players:["Michu", "DaniG"], - team:"", - goals: 1 - }, - tags: ["Torneo 4", "Segunda"], - }, - { - date:'2014-09-02T00:00:00.000Z', - home:{ - players:["Santi", "DaniG"], - team:"", - goals: 2 - }, - away:{ - players:["Michu", "NicoR"], - team:"", - goals: 0 - }, - tags: ["Torneo 4", "Segunda"], - }, - { - date:'2014-08-20T00:00:00.000Z', - home:{ - players:["Hernan", "Ariel"], - team:"", - goals: 2 - }, - away:{ - players:["Leandro", "NicoL"], - team:"", - goals: 0 - }, - tags: ["Torneo 4", "Tercera"], - }, - { - date:'2014-08-20T00:00:00.000Z', - home:{ - players:["Hernan", "Ariel"], - team:"", - goals: 2 - }, - away:{ - players:["Charly", "FerP"], - team:"", - goals: 0 - }, - tags: ["Torneo 4", "Tercera"], - }, - { - date:'2014-08-20T00:00:00.000Z', - home:{ - players:["Leandro", "NicoL"], - team:"", - goals: 1 - }, - away:{ - players:["Charly", "FerP"], - team:"", - goals: 3 - }, - tags: ["Torneo 4", "Tercera"], - }, - { - date:'2014-08-21T00:00:00.000Z', - home:{ - players:["Hernan", "NicoL"], - team:"", - goals: 0 - }, - away:{ - players:["Leandro", "FerP"], - team:"", - goals: 0 - }, - tags: ["Torneo 4", "Tercera"], - }, - { - date:'2014-08-22T00:00:00.000Z', - home:{ - players:["Hernan", "NicoL"], - team:"", - goals: 4 - }, - away:{ - players:["Charly", "Ariel"], - team:"", - goals: 0 - }, - tags: ["Torneo 4", "Tercera"], - }, - { - date:'2014-08-22T00:00:00.000Z', - home:{ - players:["Leandro", "FerP"], - team:"", - goals: 4 - }, - away:{ - players:["Charly", "Ariel"], - team:"", - goals: 0 - }, - tags: ["Torneo 4", "Tercera"], - }, - { - date:'2014-08-25T00:00:00.000Z', - home:{ - players:["Hernan", "FerP"], - team:"", - goals: 3 - }, - away:{ - players:["Charly", "NicoL"], - team:"", - goals: 0 - }, - tags: ["Torneo 4", "Tercera"], - }, - { - date:'2014-08-25T00:00:00.000Z', - home:{ - players:["Hernan", "FerP"], - team:"", - goals: 2 - }, - away:{ - players:["Leandro", "Ariel"], - team:"", - goals: 0 - }, - tags: ["Torneo 4", "Tercera"], - }, - { - date:'2014-08-25T00:00:00.000Z', - home:{ - players:["Charly", "NicoL"], - team:"", - goals: 1 - }, - away:{ - players:["Leandro", "Ariel"], - team:"", - goals: 2 - }, - tags: ["Torneo 4", "Tercera"], - }, - { - date:'2014-08-26T00:00:00.000Z', - home:{ - players:["Hernan", "Ariel"], - team:"", - goals: 1 - }, - away:{ - players:["Leandro", "FerP"], - team:"", - goals: 1 - }, - tags: ["Torneo 4", "Tercera"], - }, - { - date:'2014-08-27T00:00:00.000Z', - home:{ - players:["Hernan", "Ariel"], - team:"", - goals: 2 - }, - away:{ - players:["Charly", "NicoL"], - team:"", - goals: 0 - }, - tags: ["Torneo 4", "Tercera"], - }, - { - date:'2014-08-27T00:00:00.000Z', - home:{ - players:["Leandro", "FerP"], - team:"", - goals: 0 - }, - away:{ - players:["Charly", "NicoL"], - team:"", - goals: 0 - }, - tags: ["Torneo 4", "Tercera"], - }, - { - date:'2014-08-29T00:00:00.000Z', - home:{ - players:["Hernan", "FerP"], - team:"", - goals: 0 - }, - away:{ - players:["Leandro", "NicoL"], - team:"", - goals: 2 - }, - tags: ["Torneo 4", "Tercera"], - }, - { - date:'2014-09-01T00:00:00.000Z', - home:{ - players:["Hernan", "FerP"], - team:"", - goals: 8 - }, - away:{ - players:["Charly", "Ariel"], - team:"", - goals: 0 - }, - tags: ["Torneo 4", "Tercera"], - }, - { - date:'2014-09-01T00:00:00.000Z', - home:{ - players:["Leandro", "NicoL"], - team:"", - goals: 3 - }, - away:{ - players:["Charly", "Ariel"], - team:"", - goals: 1 - }, - tags: ["Torneo 4", "Tercera"], - }, - { - date:'2014-09-01T00:00:00.000Z', - home:{ - players:["Hernan", "NicoL"], - team:"", - goals: 0 - }, - away:{ - players:["Charly", "FerP"], - team:"", - goals: 1 - }, - tags: ["Torneo 4", "Tercera"], - }, - { - date:'2014-09-01T00:00:00.000Z', - home:{ - players:["Hernan", "NicoL"], - team:"", - goals: 2 - }, - away:{ - players:["Leandro", "Ariel"], - team:"", - goals: 0 - }, - tags: ["Torneo 4", "Tercera"], - }, - { - date:'2014-09-05T00:00:00.000Z', - home:{ - players:["Charly", "FerP"], - team:"", - goals: 3 - }, - away:{ - players:["Leandro", "Ariel"], - team:"", - goals: 0 - }, - tags: ["Torneo 4", "Tercera"], - }, - { - date:'', - home:{ - players:["NicoR", "Leo"], - team:"Alemania", - goals: 3 - }, - away:{ - players:["Santi", "Gaby"], - team:"Francia", - goals: 3 - }, - tags: ["Mundial 1", "Grupo A"], - }, - { - date:'', - home:{ - players:["NicoR", "Malcom"], - team:"Alemania", - goals: 0 - }, - away:{ - players:["Gamba", "Leo"], - team:"Mexico", - goals: 0 - }, - tags: ["Mundial 1", "Grupo A"], - }, - { - date:'', - home:{ - players:["NicoR", "DaniG"], - team:"Alemania", - goals: 1 - }, - away:{ - players:["Michu", "Juan"], - team:"Inglaterra", - goals: 0 - }, - tags: ["Mundial 1", "Grupo A"], - }, - { - date:'', - home:{ - players:["Michu", "FerO"], - team:"Inglaterra", - goals: 1 - }, - away:{ - players:["Gamba", "Gaby"], - team:"Mexico", - goals: 4 - }, - tags: ["Mundial 1", "Grupo A"], - }, - { - date:'', - home:{ - players:["Michu", "Gaby"], - team:"Inglaterra", - goals: 1 - }, - away:{ - players:["Santi", "DaniG"], - team:"Francia", - goals: 1 - }, - tags: ["Mundial 1", "Grupo A"], - }, - { - date:'', - home:{ - players:["Gamba", "Mauri"], - team:"Mexico", - goals: 1 - }, - away:{ - players:["Santi", "Leo"], - team:"Francia", - goals: 2 - }, - tags: ["Mundial 1", "Grupo A"], - }, - { - date:'', - home:{ - players:["Leo", "Mauri"], - team:"Italia", - goals: 2 - }, - away:{ - players:["Gaby", "Gamba"], - team:"Brasil", - goals: 1 - }, - tags: ["Mundial 1", "Grupo B"], - }, - { - date:'', - home:{ - players:["Leo", "Gamba"], - team:"Italia", - goals: 1 - }, - away:{ - players:["Malcom", "Santi"], - team:"Espana", - goals: 2 - }, - tags: ["Mundial 1", "Grupo B"], - }, - { - date:'', - home:{ - players:["Leo", "Santi"], - team:"Italia", - goals: 0 - }, - away:{ - players:["FerO", "Mauri"], - team:"Uruguay", - goals: 0 - }, - tags: ["Mundial 1", "Grupo B"], - }, - { - date:'', - home:{ - players:["Gaby", "Mauri"], - team:"Brasil", - goals: 7 - }, - away:{ - players:["Malcom", "Charly"], - team:"Espana", - goals: 1 - }, - tags: ["Mundial 1", "Grupo B"], - }, - { - date:'', - home:{ - players:["Gaby", "Charly"], - team:"Brasil", - goals: 2 - }, - away:{ - players:["FerO", "NicoR"], - team:"Uruguay", - goals: 1 - }, - tags: ["Mundial 1", "Grupo B"], - }, - { - date:'', - home:{ - players:["Malcom", "Mauri"], - team:"Espana", - goals: 2 - }, - away:{ - players:["FerO", "Santi"], - team:"Uruguay", - goals: 2 - }, - tags: ["Mundial 1", "Grupo B"], - }, - - { - date:'', - home:{ - players:["Mauri", "Gamba"], - team:"Holanda", - goals: 1 - }, - away:{ - players:["Juan", "Michu"], - team:"CdMarfil", - goals: 1 - }, - tags: ["Mundial 1", "Grupo C"], - }, - { - date:'', - home:{ - players:["Mauri", "Leo"], - team:"Holanda", - goals: 4 - }, - away:{ - players:["DaniG", "NicoR"], - team:"Colombia", - goals: 0 - }, - tags: ["Mundial 1", "Grupo C"], - }, - { - date:'', - home:{ - players:["Juan", "Malcom"], - team:"CdMarfil", - goals: 4 - }, - away:{ - players:["DaniG", "Leo"], - team:"Colombia", - goals: 0 - }, - tags: ["Mundial 1", "Grupo C"], - }, - - { - date:'', - home:{ - players:["Charly", "Santi"], - team:"EEUU", - goals: 0 - }, - away:{ - players:["Cristian", "NicoR"], - team:"Argentina", - goals: 1 - }, - tags: ["Mundial 1", "Grupo D"], - }, - { - date:'', - home:{ - players:["Charly", "NicoR"], - team:"EEUU", - goals: 2 - }, - away:{ - players:["Sebas", "Leo"], - team:"Portugal", - goals: 1 - }, - tags: ["Mundial 1", "Grupo D"], - }, - { - date:'', - home:{ - players:["Cristian", "Leo"], - team:"Argentina", - goals: 0 - }, - away:{ - players:["Sebas", "Malcom"], - team:"Portugal", - goals: 0 - }, - tags: ["Mundial 1", "Grupo D"], - }, - { - date:'', - home:{ - players:["Santi", "Leo"], - team:"Francia", - goals: 1 - }, - away:{ - players:["Juan", "Gaby"], - team:"CdMarfil", - goals: 4 - }, - tags: ["Mundial 1", "Cuartos de final"], - }, - { - date:'', - home:{ - players:["Cristian", "NicoR"], - team:"Argentina", - goals: 0 - }, - away:{ - players:["Leo", "Juan"], - team:"Italia", - goals: 3 - }, - tags: ["Mundial 1", "Cuartos de final"], - }, - { - date:'', - home:{ - players:["Mauri", "Leo"], - team:"Holanda", - goals: 2 - }, - away:{ - players:["NicoR", "Gaby"], - team:"Alemania", - goals: 5 - }, - tags: ["Mundial 1", "Cuartos de final"], - }, - { - date:'', - home:{ - players:["Gaby", "NicoR"], - team:"Brasil", - goals: 3 - }, - away:{ - players:["Charly", "Mauri"], - team:"EEUU", - goals: 1 - }, - tags: ["Mundial 1", "Cuartos de final"], - }, - { - date:'', - home:{ - players:["Juan", "Santi"], - team:"CdMarfil", - goals: 3, - penalties: 4, - }, - away:{ - players:["Leo", "NicoR"], - team:"Italia", - goals: 3, - penalties: 5, - }, - tags: ["Mundial 1", "Semifinal"], - }, - { - date:'', - home:{ - players:["NicoR", "Santi"], - team:"Alemania", - goals: 3 - }, - away:{ - players:["Gaby", "Juan"], - team:"Brasil", - goals: 0 - }, - tags: ["Mundial 1", "Semifinal"], - }, - - { - date:'', - home:{ - players:["Juan", "Leo"], - team:"CdMarfil", - goals: 1 - }, - away:{ - players:["Gaby", "Mauri"], - team:"Brasil", - goals: 4 - }, - tags: ["Mundial 1", "Tercer Puesto"], - }, - { - date:'', - home:{ - players:["NicoR", "Malcom"], - team:"Alemania", - goals: 2 - }, - away:{ - players:["Leo", "Mauri"], - team:"Italia", - goals: 0 - }, - tags: ["Mundial 1", "Final"], - }, - ] \ No newline at end of file diff --git a/newrelic.js b/newrelic.js new file mode 100644 index 0000000..3be5dd2 --- /dev/null +++ b/newrelic.js @@ -0,0 +1,24 @@ +/** + * New Relic agent configuration. + * + * See lib/config.defaults.js in the agent distribution for a more complete + * description of configuration variables and their potential values. + */ +exports.config = { + /** + * Array of application names. + */ + app_name: ['Fifa Medallia'], + /** + * Your New Relic license key. + */ + license_key: process.env.NEW_RELIC_LICENSE_KEY || '', + logging: { + /** + * Level at which to log. 'trace' is most useful to New Relic when diagnosing + * issues with the agent, 'info' and higher will impose the least overhead on + * production applications. + */ + level: process.env.NEW_RELIC_LOG + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..09c0cad --- /dev/null +++ b/package.json @@ -0,0 +1,47 @@ +{ + "name": "fifa", + "version": "1.0.0", + "main": "server.js", + "dependencies": { + "angular": "^1.3.16", + "body-parser": "^1.12.4", + "bootstrap": "^3.3.4", + "bower": "^1.4.1", + "connect-redis": "^2.3.0", + "cookie-parser": "^1.3.5", + "cookie-session": "^1.1.0", + "debug": "^2.2.0", + "ejs": "^2.3.1", + "express": "^4.12.4", + "express-session": "^1.11.3", + "glicko2": "^0.8.4", + "googleapis": "^2.0.5", + "jquery": "^2.1.4", + "method-override": "~2.1.1", + "mongodb": "^2.0.33", + "mongoose": "^4.0.5", + "morgan": "~1.2.2", + "newrelic": "^1.22.0", + "node-env-file": "^0.1.7", + "nodemailer": "^1.4.0", + "nodemon": "^1.3.7", + "passport": "^0.2.2", + "passport-google-oauth2": "^0.1.6", + "serve-favicon": "^2.2.1", + "underscore": "^1.8.3" + }, + "devDependencies": {}, + "scripts": { + "postinstall": "./node_modules/bower/bin/bower install" + }, + "author": "", + "license": "ISC", + "repository": { + "type": "git", + "url": "https://github.com/ebergama/fifa.git" + }, + "bugs": { + "url": "https://github.com/ebergama/fifa/issues" + }, + "homepage": "https://github.com/ebergama/fifa" +} diff --git a/pics/Martin.jpg b/pics/Martin.jpg deleted file mode 100644 index 4f73924..0000000 Binary files a/pics/Martin.jpg and /dev/null differ diff --git a/pics/Michu.jpg b/pics/Michu.jpg deleted file mode 100644 index afaa4bc..0000000 Binary files a/pics/Michu.jpg and /dev/null differ diff --git a/pics/Sebastian.jpg b/pics/Sebastian.jpg deleted file mode 100644 index b2ef180..0000000 Binary files a/pics/Sebastian.jpg and /dev/null differ diff --git a/public/css/app.css b/public/css/app.css new file mode 100644 index 0000000..b636496 --- /dev/null +++ b/public/css/app.css @@ -0,0 +1,230 @@ +body { padding-top: 2em; } +@media screen and (max-width: 768px) { + body { padding-top: 6em; } +} + +.filterLabel { + margin-right:5px; +} + +.nav-justified > .active > a { + background-color:#ddd; +} + +.points { + background-color:#D9D9F1; +} +.won { + background-color: #C9F2D7; + color: green; +} +.lost { + background-color: #F4BDBC; + color: red; +} +.tie { + background-color: #fffbc0; +} + +.rankPositive { + color: green; +} + +.rankNegative { + color: red; +} + +.notPlayed { + opacity: 0.2; +} + +.matchGoals { + font-weight: bold; + font-size: x-large; +} +.img-circle { + cursor:pointer; + height:48px; + width:48px; + vertical-align:middle!important; +} + +.img-circle-small { + cursor:pointer; + height:40px; + width:40px; + vertical-align:middle!important; +} + + +.img-circle-large { + cursor:pointer; + height:248px; + width:248px; + vertical-align:middle!important; +} + +ul { + margin-top:10px; +} + +.middleData td { + vertical-align:middle!important; +} +table tr th { + vertical-align:middle!important; + text-align: center; +} + +.table input { + width: 4em; +} + +.team { + min-width:50px; + height:50px; + background-size: 43px; + background-repeat: no-repeat; + display:inline-block; + vertical-align:middle!important; +} + +.Argentina { +background-image:url(http://www.fifa.com/imgml/flags/reflected/m/arg.png); +} + +.Alemania { +background-image:url(http://www.fifa.com/imgml/flags/reflected/m/ger.png); +} + +.Brasil { +background-image:url(http://www.fifa.com/imgml/flags/reflected/m/bra.png); +} + +.Espana { +background-image:url(http://www.fifa.com/imgml/flags/reflected/m/esp.png); +} + +.Francia { +background-image:url(http://www.fifa.com/imgml/flags/reflected/m/fra.png); +} + +.Holanda { +background-image:url(http://www.fifa.com/imgml/flags/reflected/m/ned.png); +} + +.Inglaterra { +background-image:url(http://www.fifa.com/imgml/flags/reflected/m/eng.png); +} + +.Italia { +background-image:url(http://www.fifa.com/imgml/flags/reflected/m/ita.png); +} + +.Mexico { +background-image:url(http://www.fifa.com/imgml/flags/reflected/m/mex.png); +} + +.Uruguay { +background-image:url(http://www.fifa.com/imgml/flags/reflected/m/uru.png); +} + +.Colombia { +background-image:url(http://www.fifa.com/imgml/flags/reflected/m/col.png); +} + +.CdMarfil { +background-image:url(http://www.fifa.com/imgml/flags/reflected/m/civ.png); +} + +.EEUU { +background-image:url(http://www.fifa.com/imgml/flags/reflected/m/usa.png); +} + +.Portugal { +background-image:url(http://www.fifa.com/imgml/flags/reflected/m/por.png); +} + +.Peru { + background-image:url(http://www.fifa.com/imgml/flags/reflected/m/per.png); +} + +.Ecuador { + background-image:url(http://www.fifa.com/imgml/flags/reflected/m/ecu.png); +} + +.Chile { + background-image:url(http://www.fifa.com/imgml/flags/reflected/m/chi.png); +} + +.Venezuela { + background-image:url(http://www.fifa.com/imgml/flags/reflected/m/ven.png); +} + +.Paraguay { + background-image:url(http://www.fifa.com/imgml/flags/reflected/m/par.png); +} + +.Bolivia { + background-image:url(http://www.fifa.com/imgml/flags/reflected/m/bol.png); +} + +.Gales { + background-image:url(http://www.fifa.com/imgml/flags/reflected/m/wal.png); +} + +.Australia { + background-image:url(http://www.fifa.com/imgml/flags/reflected/m/aus.png); +} + +.Korea { + background-image:url(http://www.fifa.com/imgml/flags/reflected/m/kor.png); +} + +.Barcelona { + background-image:url(http://img.fifa.com/mm/teams/1903416/1903416x3.png); +} + +.RealMadrid { + background-image:url(http://www.fifa.com/mm/teams/30504/30504x3.png); +} + +.Juventus { + background-image:url(http://img.fifa.com/mm/teams/31085/31085x3.png); +} + +.Chelsea { + background-image:url(http://img.fifa.com/mm/teams/1935290/1935290x3.png); +} + +.ManCity { + background-image:url(http://img.fifa.com/mm/teams/33337/33337x3.png); +} + +.ManUtd { + background-image:url(http://img.fifa.com/mm/teams/33161/33161x3.png); +} + +.PSG { + background-image:url(http://img.fifa.com/mm/teams/33191/33191x3.png); +} + +.Borussia{ + background-image:url(http://img.fifa.com/mm/teams/33199/33199x3.png); +} + +.Bayern { + background-image:url(http://img.fifa.com/mm/teams/1914810/1914810x3.png); +} + +.Atletico { + background-image:url(http://img.fifa.com/mm/teams/1914808/1914808x3.png); +} +.btn-google { + color: #fff; + background-color: #dd4b39; + border-color: rgba(0,0,0,0.2); +} +.btn-google span { + margin-left: 0.5em; +} diff --git a/public/css/login.css b/public/css/login.css new file mode 100644 index 0000000..0c70391 --- /dev/null +++ b/public/css/login.css @@ -0,0 +1,55 @@ +/*! + * Start Bootstrap - Stylish Portfolio Bootstrap Theme (http://startbootstrap.com) + * Code licensed under the Apache License v2.0. + * For details, see http://www.apache.org/licenses/LICENSE-2.0. + */ + +/* Global Styles */ + +html, +body { + width: 100%; + height: 100%; +} + +body { + font-family: "Source Sans Pro","Helvetica Neue",Helvetica,Arial,sans-serif; +} + +.text-vertical-bottom { + display: table-cell; + text-align: center; + position: absolute; + bottom: 4em; + left: 0; + right: 0; +} + + +/* Header */ + +.header { + display: table; + position: relative; + width: 100%; + height: 100%; + background: url(/images/fifa_15_game-wide.jpg) no-repeat center center scroll; + -webkit-background-size: cover; + -moz-background-size: cover; + background-size: cover; + -o-background-size: cover; +} + +.btn-google { + color: #fff; + background-color: #dd4b39; + border-color: rgba(0,0,0,0.2); +} +.btn-xl { + padding: 18px 28px; + font-size: 22px; + border-radius: 8px; +} +.btn-google span { + margin-left: 0.5em; +} \ No newline at end of file diff --git a/public/css/sb-admin-2.css b/public/css/sb-admin-2.css new file mode 100755 index 0000000..e8be396 --- /dev/null +++ b/public/css/sb-admin-2.css @@ -0,0 +1,354 @@ +/*! + * Start Bootstrap - SB Admin 2 Bootstrap Admin Theme (http://startbootstrap.com) + * Code licensed under the Apache License v2.0. + * For details, see http://www.apache.org/licenses/LICENSE-2.0. + */ + +body { + background-color: #f8f8f8; +} + +#wrapper { + width: 100%; +} + +#page-wrapper { + padding: 0 15px; + min-height: 568px; + background-color: #fff; +} + +@media(min-width:768px) { + #page-wrapper { + position: inherit; + margin: 0 0 0 250px; + padding: 0 30px; + border-left: 1px solid #e7e7e7; + } +} + +.navbar-top-links { + margin-right: 0; +} + +.navbar-top-links li { + display: inline-block; +} + +.navbar-top-links li:last-child { + margin-right: 15px; +} + +.navbar-top-links li a { + padding: 15px; + min-height: 50px; +} + +.navbar-top-links .dropdown-menu li { + display: block; +} + +.navbar-top-links .dropdown-menu li:last-child { + margin-right: 0; +} + +.navbar-top-links .dropdown-menu li a { + padding: 3px 20px; + min-height: 0; +} + +.navbar-top-links .dropdown-menu li a div { + white-space: normal; +} + +.navbar-top-links .dropdown-messages, +.navbar-top-links .dropdown-tasks, +.navbar-top-links .dropdown-alerts { + width: 310px; + min-width: 0; +} + +.navbar-top-links .dropdown-messages { + margin-left: 5px; +} + +.navbar-top-links .dropdown-tasks { + margin-left: -59px; +} + +.navbar-top-links .dropdown-alerts { + margin-left: -123px; +} + +.navbar-top-links .dropdown-user { + right: 0; + left: auto; +} + +.sidebar .sidebar-nav.navbar-collapse { + padding-right: 0; + padding-left: 0; +} + +.sidebar .sidebar-search { + padding: 15px; +} + +.sidebar ul li { + border-bottom: 1px solid #e7e7e7; +} + +.sidebar ul li a.active { + background-color: #eee; +} + +.sidebar .arrow { + float: right; +} + +.sidebar .fa.arrow:before { + content: "\f104"; +} + +.sidebar .active>a>.fa.arrow:before { + content: "\f107"; +} + +.sidebar .nav-second-level li, +.sidebar .nav-third-level li { + border-bottom: 0!important; +} + +.sidebar .nav-second-level li a { + padding-left: 37px; +} + +.sidebar .nav-third-level li a { + padding-left: 52px; +} + +@media(min-width:768px) { + .sidebar { + z-index: 1; + position: absolute; + width: 250px; + margin-top: 51px; + } + + .navbar-top-links .dropdown-messages, + .navbar-top-links .dropdown-tasks, + .navbar-top-links .dropdown-alerts { + margin-left: auto; + } +} + +.btn-outline { + color: inherit; + background-color: transparent; + transition: all .5s; +} + +.btn-primary.btn-outline { + color: #428bca; +} + +.btn-success.btn-outline { + color: #5cb85c; +} + +.btn-info.btn-outline { + color: #5bc0de; +} + +.btn-warning.btn-outline { + color: #f0ad4e; +} + +.btn-danger.btn-outline { + color: #d9534f; +} + +.btn-primary.btn-outline:hover, +.btn-success.btn-outline:hover, +.btn-info.btn-outline:hover, +.btn-warning.btn-outline:hover, +.btn-danger.btn-outline:hover { + color: #fff; +} + +.chat { + margin: 0; + padding: 0; + list-style: none; +} + +.chat li { + margin-bottom: 10px; + padding-bottom: 5px; + border-bottom: 1px dotted #999; +} + +.chat li.left .chat-body { + margin-left: 60px; +} + +.chat li.right .chat-body { + margin-right: 60px; +} + +.chat li .chat-body p { + margin: 0; +} + +.panel .slidedown .glyphicon, +.chat .glyphicon { + margin-right: 5px; +} + +.chat-panel .panel-body { + height: 350px; + overflow-y: scroll; +} + +.login-panel { + margin-top: 25%; +} + +.flot-chart { + display: block; + height: 400px; +} + +.flot-chart-content { + width: 100%; + height: 100%; +} + +.dataTables_wrapper { + position: relative; + clear: both; +} + +table.dataTable thead .sorting, +table.dataTable thead .sorting_asc, +table.dataTable thead .sorting_desc, +table.dataTable thead .sorting_asc_disabled, +table.dataTable thead .sorting_desc_disabled { + background: 0 0; +} + +table.dataTable thead .sorting_asc:after { + content: "\f0de"; + float: right; + font-family: fontawesome; +} + +table.dataTable thead .sorting_desc:after { + content: "\f0dd"; + float: right; + font-family: fontawesome; +} + +table.dataTable thead .sorting:after { + content: "\f0dc"; + float: right; + font-family: fontawesome; + color: rgba(50,50,50,.5); +} + +.btn-circle { + width: 30px; + height: 30px; + padding: 6px 0; + border-radius: 15px; + text-align: center; + font-size: 12px; + line-height: 1.428571429; +} + +.btn-circle.btn-lg { + width: 50px; + height: 50px; + padding: 10px 16px; + border-radius: 25px; + font-size: 18px; + line-height: 1.33; +} + +.btn-circle.btn-xl { + width: 70px; + height: 70px; + padding: 10px 16px; + border-radius: 35px; + font-size: 24px; + line-height: 1.33; +} + +.show-grid [class^=col-] { + padding-top: 10px; + padding-bottom: 10px; + border: 1px solid #ddd; + background-color: #eee!important; +} + +.show-grid { + margin: 15px 0; +} + +.huge { + font-size: 40px; +} + +.panel-green { + border-color: #5cb85c; +} + +.panel-green .panel-heading { + border-color: #5cb85c; + color: #fff; + background-color: #5cb85c; +} + +.panel-green a { + color: #5cb85c; +} + +.panel-green a:hover { + color: #3d8b3d; +} + +.panel-red { + border-color: #d9534f; +} + +.panel-red .panel-heading { + border-color: #d9534f; + color: #fff; + background-color: #d9534f; +} + +.panel-red a { + color: #d9534f; +} + +.panel-red a:hover { + color: #b52b27; +} + +.panel-yellow { + border-color: #f0ad4e; +} + +.panel-yellow .panel-heading { + border-color: #f0ad4e; + color: #fff; + background-color: #f0ad4e; +} + +.panel-yellow a { + color: #f0ad4e; +} + +.panel-yellow a:hover { + color: #df8a13; +} \ No newline at end of file diff --git a/public/favicon.ico b/public/favicon.ico new file mode 100644 index 0000000..d259e24 Binary files /dev/null and b/public/favicon.ico differ diff --git a/public/images/fifa15.png b/public/images/fifa15.png new file mode 100644 index 0000000..ecf7dd2 Binary files /dev/null and b/public/images/fifa15.png differ diff --git a/public/images/fifa_15_game-wide.jpg b/public/images/fifa_15_game-wide.jpg new file mode 100644 index 0000000..e0a5233 Binary files /dev/null and b/public/images/fifa_15_game-wide.jpg differ diff --git a/public/images/icon.question.png b/public/images/icon.question.png new file mode 100644 index 0000000..a8cb478 Binary files /dev/null and b/public/images/icon.question.png differ diff --git a/public/images/medallia-large.png b/public/images/medallia-large.png new file mode 100644 index 0000000..58aa139 Binary files /dev/null and b/public/images/medallia-large.png differ diff --git a/pics/Ariel.jpg b/public/images/pics/Ariel.jpg similarity index 100% rename from pics/Ariel.jpg rename to public/images/pics/Ariel.jpg diff --git a/pics/Charly.jpg b/public/images/pics/Charly.jpg similarity index 100% rename from pics/Charly.jpg rename to public/images/pics/Charly.jpg diff --git a/pics/Cristian.jpg b/public/images/pics/Cristian.jpg similarity index 100% rename from pics/Cristian.jpg rename to public/images/pics/Cristian.jpg diff --git a/pics/DaniG.jpg b/public/images/pics/DaniG.jpg similarity index 100% rename from pics/DaniG.jpg rename to public/images/pics/DaniG.jpg diff --git a/pics/Ezequiel.jpg b/public/images/pics/Ezequiel.jpg similarity index 100% rename from pics/Ezequiel.jpg rename to public/images/pics/Ezequiel.jpg diff --git a/pics/FerO.jpg b/public/images/pics/FerO.jpg similarity index 100% rename from pics/FerO.jpg rename to public/images/pics/FerO.jpg diff --git a/pics/FerP.jpg b/public/images/pics/FerP.jpg similarity index 100% rename from pics/FerP.jpg rename to public/images/pics/FerP.jpg diff --git a/pics/Gaby.jpg b/public/images/pics/Gaby.jpg similarity index 100% rename from pics/Gaby.jpg rename to public/images/pics/Gaby.jpg diff --git a/pics/Gamba.jpg b/public/images/pics/Gamba.jpg similarity index 100% rename from pics/Gamba.jpg rename to public/images/pics/Gamba.jpg diff --git a/pics/Hernan.jpg b/public/images/pics/Hernan.jpg similarity index 100% rename from pics/Hernan.jpg rename to public/images/pics/Hernan.jpg diff --git a/pics/Juan.jpg b/public/images/pics/Juan.jpg similarity index 100% rename from pics/Juan.jpg rename to public/images/pics/Juan.jpg diff --git a/pics/Leandro.jpg b/public/images/pics/Leandro.jpg similarity index 100% rename from pics/Leandro.jpg rename to public/images/pics/Leandro.jpg diff --git a/pics/Leo.jpg b/public/images/pics/Leo.jpg similarity index 100% rename from pics/Leo.jpg rename to public/images/pics/Leo.jpg diff --git a/pics/Malcolm.jpg b/public/images/pics/Malcolm.jpg similarity index 100% rename from pics/Malcolm.jpg rename to public/images/pics/Malcolm.jpg diff --git a/pics/Mauri.jpg b/public/images/pics/Mauri.jpg similarity index 100% rename from pics/Mauri.jpg rename to public/images/pics/Mauri.jpg diff --git a/pics/NicoL.jpg b/public/images/pics/NicoL.jpg similarity index 100% rename from pics/NicoL.jpg rename to public/images/pics/NicoL.jpg diff --git a/pics/NicoR.jpg b/public/images/pics/NicoR.jpg similarity index 100% rename from pics/NicoR.jpg rename to public/images/pics/NicoR.jpg diff --git a/pics/PabloC.jpg b/public/images/pics/PabloC.jpg similarity index 100% rename from pics/PabloC.jpg rename to public/images/pics/PabloC.jpg diff --git a/pics/Santi.jpg b/public/images/pics/Santi.jpg similarity index 100% rename from pics/Santi.jpg rename to public/images/pics/Santi.jpg diff --git a/pics/leo.png b/public/images/pics/leo.png similarity index 100% rename from pics/leo.png rename to public/images/pics/leo.png diff --git a/pics/martin.jpg b/public/images/pics/martin.jpg similarity index 100% rename from pics/martin.jpg rename to public/images/pics/martin.jpg diff --git a/pics/michu.jpg b/public/images/pics/michu.jpg similarity index 100% rename from pics/michu.jpg rename to public/images/pics/michu.jpg diff --git a/pics/sebastian.jpg b/public/images/pics/sebastian.jpg similarity index 100% rename from pics/sebastian.jpg rename to public/images/pics/sebastian.jpg diff --git a/players.png b/public/images/players.png similarity index 100% rename from players.png rename to public/images/players.png diff --git a/public/js/app.js b/public/js/app.js new file mode 100644 index 0000000..d5b82ad --- /dev/null +++ b/public/js/app.js @@ -0,0 +1,71 @@ +var app = angular.module('fifa', ['ngRoute', 'ui.bootstrap', 'fifaControllers']) + +.config(['$routeProvider', "$locationProvider", + function($routeProvider, $locationProvider) { + $routeProvider. + when('/ranking', { + templateUrl: 'templates/ranking', + controller: 'rankingController', + resolve: { + players: function(playerService) { + return playerService.getPlayers(); + }, + allPlayerStats: function(playerService) { + return playerService.getAllPlayerStats(); + } + } + }). + when('/tournament/:tournamentName', { + templateUrl: 'templates/tournament', + controller: 'tournamentController', + resolve: { + playersData: function(playerService) { + return playerService.getPlayers(); + }, + matches: function($route, matchService) { + return matchService.getMatches($route.current.params.tournamentName); + }, + tournament: function($route, tournamentService) { + return tournamentService.getTournament($route.current.params.tournamentName); + } + } + }). + when("/stats", { + templateUrl: 'templates/stats', + controller: 'statsController', + resolve: { + allPlayerStats: function(playerService) { + return playerService.getAllPlayerStats(); + }, + playersData: function(playerService) { + return playerService.getPlayers(); + } + + } + }). + when("/profile/:alias",{ + templateUrl: 'templates/profile', + controller: 'profileController', + resolve: { + matchesForPlayer: function($route, matchService) { + return matchService.getMatchesForPlayer($route.current.params.alias); + }, + playerStats: function($route, playerService) { + return playerService.getPlayerStats($route.current.params.alias) + }, + playersData: function(playerService) { + return playerService.getPlayers(); + }, + player: function($route, playerService) { + return playerService.getPlayer($route.current.params.alias); + } + } + }). + when('/rules', { + templateUrl: 'templates/rules' + }). + otherwise({ + redirectTo: '/tournament/current' + }); + $locationProvider.html5Mode(true); +}]); diff --git a/public/js/controller/mainController.js b/public/js/controller/mainController.js new file mode 100644 index 0000000..b12c0b7 --- /dev/null +++ b/public/js/controller/mainController.js @@ -0,0 +1,41 @@ +controllers = angular.module('fifaControllers', []); + +controllers.factory('Data', function() { + var currentTournament; + var currentPhase; + return { + getCurrentTournament : function() {return currentTournament;}, + setCurrentTournament : function(tournament) {return currentTournament = tournament;}, + getCurrentPhase : function() {return currentPhase;}, + setCurrentPhase : function(phase) {return currentPhase = phase;} + } + +}); + +controllers.controller('mainController', ['$scope', 'tournamentService', 'Data', function($scope, tournamentService, Data) { + + $scope.mainPage = function() { + Data.setCurrentTournament(undefined); + }; + + $scope.logout = function() { + window.location = '/account/logout'; + }; + + $scope.signIn = function() { + window.location = "/login"; + }; + + tournamentService.getTournaments().then(function(response) { + $scope.tournaments = response.data; + }); + + $scope.$watch(function () { return Data.getCurrentTournament(); }, function (newValue, oldValue) { + if (newValue !== oldValue) $scope.theTournament = newValue; + }); + + $scope.selectPhase = function(phase) { + Data.setCurrentPhase(phase); + $scope.thePhase = phase; + } +}]); \ No newline at end of file diff --git a/public/js/controller/matchModalController.js b/public/js/controller/matchModalController.js new file mode 100644 index 0000000..1a829dc --- /dev/null +++ b/public/js/controller/matchModalController.js @@ -0,0 +1,149 @@ +controllers.controller('modalController', ["$scope", "$modal", "$log", "playerService", function ($scope, $modal, $log, playerService) { + + $scope.animationsEnabled = true; + + $scope.open = function (match) { + + var modalInstance = $modal.open({ + animation: $scope.animationsEnabled, + templateUrl: 'resultsEditor', + controller: 'modalInstanceController', + resolve: { + match: function () { + return match; + }, + players: function() { + return playerService.getPlayers(); + } + } + }); + + modalInstance.result.then(function () { + $scope.calculateStandings(); + match.clazz = ""; + }, function () { + $log.info('Modal dismissed at: ' + new Date()); + }); + }; + + $scope.toggleAnimation = function () { + $scope.animationsEnabled = !$scope.animationsEnabled; + }; + +}]); + +angular.module('fifa').controller('modalInstanceController', function ($scope, $modalInstance, match, players, $http) { + + $scope.match = match; + if (!match.home) { + match.home = {}; + match.home.goals = match.home.redCards = match.home.yellowCards = 0; + } + if (!match.away){ + match.away = {}; + match.away.goals = match.away.redCards = match.away.yellowCards = 0; + } + + + match.date = match.date ? new Date(match.date) : new Date(); + + $scope.players = players; + $scope.playeropts = _.pluck(players, 'alias'); + var playersMap = {}; + $.each(players, function(index, player) { + playersMap[player.alias] = player; + }); + + $scope.ok = function () { + + //FIXME: use select2 and angular properly + match.home.player = $("#homePlayer").val().replace("string:",""); + var homePartner = $("#homePartner").val().replace("string:", ""); + match.home.partner = homePartner != '?' ? homePartner : undefined;; + match.away.player = $("#awayPlayer").val().replace("string:",""); + var awayPartner = $("#awayPartner").val().replace("string:", ""); + match.away.partner = awayPartner != '?' ? awayPartner : undefined; + + match.home.team = $("#homeTeam").val(); + match.away.team = $("#awayTeam").val(); + + if (match._id) { + $http.put("/api/match", match).success(function(response) { + $modalInstance.close(); + }).error(function() { + $modalInstance.dismiss("error") + }) + } else { + $http.post("/api/match", match).success(function(response) { + $modalInstance.close(); + }).error(function() { + $modalInstance.dismiss("error") + }) + } + }; + + $scope.cancel = function () { + $modalInstance.dismiss('cancel'); + }; +}).directive('initPlayerSelect', function() { + return function(scope, element, attrs) { + // FIXME use angular properly + _.delay(function() { + $(element).select2({placeholder: "Select a player"}) + }); + } + +}).directive('initTeamSelect', function() { + //FIXME: remove this directive, we should have the teams in the db + return function($scope, element, attrs) { + var data = [ + {id: "RealMadrid", text: "Real Madrid"}, + {id: "Barcelona", text: "Barcelona"}, + {id: "Chelsea", text:"Chelsea"}, + {id: "PSG", text:"PSG"}, + {id: "Bayern", text:"Bayern Munich"}, + {id: "Borussia", text:"Borussia Dortmund"}, + {id: "ManUtd", text:"Manchester United"}, + {id: "ManCity", text:"Manchester City"}, + {id: "Juventus", text:"Juventus"}, + {id: "Argentina", text:"Argentina"}, + {id: "Alemania", text:"Alemania"}, + {id: "Brasil", text:"Brasil"}, + {id: "Espana", text:"Espana"}, + {id: "Francia", text:"Francia"}, + {id: "Holanda", text:"Holanda"}, + {id: "Inglaterra", text:"Inglaterra"}, + {id: "Italia", text:"Italia"}, + {id: "Mexico", text:"Mexico"}, + {id: "Uruguay", text:"Inglaterra"}, + {id: "Colombia", text:"Colombia"}, + {id: "CDMarfil", text:"Costa de Marfil"}, + {id: "EEUU", text:"EEUU"}, + {id: "Portugal", text:"Portugal"}, + {id: "Peru", text:"Peru"}, + {id: "Ecuador", text:"Ecuador"}, + {id: "Chile", text:"Chile"}, + {id: "Venezuela", text:"Venezuela"}, + {id: "Paraguay", text:"Paraguay"}, + {id: "Bolivia", text:"Bolivia"}, + {id: "Gales", text:"Gales"}, + {id: "Australia", text:"Australia"}, + {id: "Korea", text:"Corea del sur"} + ]; + $(element).select2({ + placeholder: "Select a team", + data: data, + allowClear: true + }); + var homeOrAway = $(element).attr('ng-model').split(".")[1]; + var team = $scope.match[homeOrAway].team; + _.delay(function() { + // Don't ask why with just one doesn't work + $(element).select2().val(team); + $(element).select2().val(team); + }); + + + + } +}); \ No newline at end of file diff --git a/public/js/controller/profileController.js b/public/js/controller/profileController.js new file mode 100644 index 0000000..78f2d2d --- /dev/null +++ b/public/js/controller/profileController.js @@ -0,0 +1,28 @@ +controllers.controller("profileController", ["$scope", "$location", "player", "matchesForPlayer", "playerStats", "playersData", function($scope, $location, player, matchesForPlayer, playerStats, playersData) { + player.image = player.image.substring(0, player.image.lastIndexOf('?')); + $scope.thePlayer = player; + $scope.matchesForPlayer = matchesForPlayer; + var indexedMatches = _.indexBy(matchesForPlayer, '_id'); + $scope.stats = playerStats; + $scope.history = _.map(player.rankingHistory || [], function(h) { + h.match = indexedMatches[h.match]; + return h; + }); + + $scope.getPicture = function(alias) { + var player = $scope.playersMap[alias]; + return player ? player.image : "images/icon.question.png"; + }; + + $scope.playersMap = {}; + + $.each(playersData, function (index, player) { + $scope.playersMap[player.alias] = player; + }); + + $scope.goTo = function(player) { + $location.path('/profile/' + player); + }; + + +}]); diff --git a/public/js/controller/rankingController.js b/public/js/controller/rankingController.js new file mode 100644 index 0000000..1b9ae6b --- /dev/null +++ b/public/js/controller/rankingController.js @@ -0,0 +1,28 @@ +controllers.controller("rankingController", ["$scope", "$location", "$http", "Data", "players", "allPlayerStats", function($scope, $location, $http, Data, players, allPlayerStats) { + Data.setCurrentTournament(undefined); + + $scope.updateRanking = function() { + if(confirm("Estas seguro?")) { + $http.post("/api/player/ranking").success(function() { + $location.path("/"); + }); + } + }; + + $scope.goTo = function(player) { + $location.path('/profile/' + player.alias); + }; + + $scope.players = players; + + $.each(players, function(index, player) { + var allPlayerStat = allPlayerStats[player.alias]; + player.matchesPlayed = allPlayerStat ? allPlayerStat.matches.played : 0; + player.wonAvg = allPlayerStat ? (100 * (allPlayerStat.matches.won / allPlayerStat.matches.played)).toFixed(2) : 0; + player.tiedAvg = allPlayerStat ? (100 * (allPlayerStat.matches.tied / allPlayerStat.matches.played)).toFixed(2) : 0; + player.lostAvg = allPlayerStat ? (100 * (allPlayerStat.matches.lost / allPlayerStat.matches.played)).toFixed(2) : 0; + var previous = player.rankingHistory[player.rankingHistory.length - 2] || {}; + player.delta = (player.ranking || 0) - (previous.ranking || 0) + }) + +}]); diff --git a/public/js/controller/statsController.js b/public/js/controller/statsController.js new file mode 100644 index 0000000..b80def3 --- /dev/null +++ b/public/js/controller/statsController.js @@ -0,0 +1,66 @@ +controllers.controller("statsController", ['$scope', 'allPlayerStats', 'playersData', function($scope, allPlayerStats, playersData) { + + var playersMap = {}; + $.each(playersData, function (index, player) { + playersMap[player.alias] = player; + }); + + $scope.stats = []; + var createStatTemplate = function(name, description) { + return { + name: name, + description: description, + list: [], + pushValue: function(name, value) { + if (!isNaN(value) && value !== Infinity) { + this.list.push({name: name, value: value}); + } + } + } + }; + + var scoredGoals = createStatTemplate("Pichichi", "Promedio de goles a favor"); + var receivedGoals = createStatTemplate("El goleado", "Promedio de goles en contra (desc)"); + var lessReceivedGoals = createStatTemplate("Valla menos vencida", "Promedio de goles en contra (asc)"); + var redCards = createStatTemplate("Premio chenemigo", "Promedio de tarjetas rojas"); + var yellowCards = createStatTemplate("Premio chenemiguito", "Promedio de tarjetas amarillas"); + var terminator = createStatTemplate("Terminator", "Promedio de: rojas + amarillas/2"); + var fairPlay = createStatTemplate("Fair Play", "Promedio de: rojas + amarillas/2 (asc)"); + var mostPlayed = createStatTemplate("Vicio yo?", "El que mas partidos jugo"); + var tiedMatches = createStatTemplate("Deportivo empate", "Promedio de partidos empatados"); + var wonMatches = createStatTemplate("Victorias", "Promedio de victorias"); + + + $.each(allPlayerStats, function(playerName, stat) { + var playerAttributes = playersMap[playerName]; + if (playerAttributes && playerAttributes.active !== false) { + scoredGoals.pushValue(playerName, stat.goals.scored / stat.matches.played); + receivedGoals.pushValue(playerName, stat.goals.received / stat.matches.played); + lessReceivedGoals.pushValue(playerName, stat.goals.received / stat.matches.played); + redCards.pushValue(playerName, stat.cards.red.count / stat.cards.red.matches); + yellowCards.pushValue(playerName, stat.cards.yellow.count / stat.cards.yellow.matches); + terminator.pushValue(playerName, (stat.cards.red.count / stat.cards.red.matches) + (0.5*stat.cards.yellow.count / stat.cards.yellow.matches) ); + fairPlay.pushValue(playerName, (stat.cards.red.count / stat.cards.red.matches) + (0.5*stat.cards.yellow.count / stat.cards.yellow.matches) ); + mostPlayed.pushValue(playerName, stat.matches.played); + tiedMatches.pushValue(playerName, stat.matches.tied / stat.matches.played); + wonMatches.pushValue(playerName, stat.matches.won / stat.matches.played); + } + }); + + function sortAndPush(stat, order) { + order = order >=0 ? 1 : -1; + stat.list = _.sortBy(stat.list, function (player) { + return player.value ? order * player.value : 0; + }); + $scope.stats.push(stat); + } + + _.each([scoredGoals, receivedGoals, redCards, yellowCards, terminator, mostPlayed, tiedMatches, wonMatches], function(stat) { + sortAndPush(stat, -1); + }); + + _.each([lessReceivedGoals, fairPlay], function(stat) { + sortAndPush(stat, 1); + }); + +}]); diff --git a/public/js/controller/tournamentController.js b/public/js/controller/tournamentController.js new file mode 100644 index 0000000..6b4ebca --- /dev/null +++ b/public/js/controller/tournamentController.js @@ -0,0 +1,246 @@ +controllers.controller('tournamentController', ['$scope', 'Data', "playersData", "matches", "tournament", function($scope, Data, playersData, matches, tournament){ + + var addTagFilter = function(tag) { + if ($scope.tagFilters.indexOf(tag) == -1) { + $scope.tagFilters.push(tag); + } + }; + + var selectPhase = function(phase) { + $scope.tagFilters = []; + $scope.players = []; + $scope.thePhase = phase; + addTagFilter(phase); + $scope.calculateStandings(); + }; + + $scope.calculateStandings = function() { + var tournament = $scope.theTournament; + var phase = $scope.thePhase; + var matches = $scope.matches; + if (!$scope.hasStandings(tournament, phase)) { + return []; + } + + var standingCalcFunction = getStandingsModel(tournament, phase); + var standings = {}; + for (var i = matches.length - 1; i >= 0; i--) { + var match = matches[i]; + if (match.phase == phase) { + standingCalcFunction(standings, match.home, match.away.goals); + standingCalcFunction(standings, match.away, match.home.goals); + } + + } + var positions = []; + + for (var key in standings) { + positions.push(standings[key]); + } + positions.sort(comparePositions); + $scope.positions = positions; + }; + + var initPosition = function(player, partner) { + return {player: player, partner: partner, + matchesPlayed:0, matchesWon:0, matchesTied:0, matchesLost:0, + goalsScored:0, goalsReceived:0, goalsDiff: 0, + points:0}; + }; + + var processIndividualMatch = function(standings, player, goalsScored, goalsReceived) { + var position = standings[player]; + if (!position) { + position = initPosition(player); + standings[player] = position; + } + return updatePosition(position, goalsScored, goalsReceived); + }; + + + var updatePosition = function(position, goalsScored, goalsReceived) { + if (goalsReceived != -1 && goalsScored != -1) { + var won = goalsScored > goalsReceived ? 1 : 0; + var lost = goalsScored < goalsReceived ? 1 : 0; + var tied = goalsScored == goalsReceived ? 1 : 0; + + position.matchesPlayed += 1; + position.matchesWon += won; + position.matchesLost += lost; + position.matchesTied += tied; + + position.goalsScored += goalsScored; + position.goalsReceived += goalsReceived; + position.goalsDiff = position.goalsScored - position.goalsReceived; + + position.points = position.points + (won * 3) + tied; + } + + return position; + }; + + var comparePositions = function(aPosition, anotherPosition) { + var order = anotherPosition.points - aPosition.points; + if (order == 0) { + order = anotherPosition.goalsDiff - aPosition.goalsDiff; + if (order == 0) { + order = anotherPosition.goalsScored - aPosition.goalsScored; + } + } + return order; + }; + + var getStandingsModel = function(theTournament) { + var model = theTournament.config.standingsModel; + var standingCalcFunction; + switch(model) { + case "Team": + standingCalcFunction = function(standings, team, goalsReceived) { + var position = standings[team.player + team.partner]; + if (!position) { + position = initPosition(team.player, team.partner); + standings[team.player + team.partner] = position; + } + + updatePosition(position, team.goals, goalsReceived); + }; + break; + case "Individual": + standingCalcFunction = function(standings, team, goalsReceived) { + processIndividualMatch(standings, team.player, team.goals, goalsReceived); + if (team.partner) { + processIndividualMatch(standings, team.partner, team.goals, goalsReceived); + } + }; + break; + case "IndividualWithSupport": + standingCalcFunction = function(standings, team, goalsReceived) { + var position = processIndividualMatch(standings, team.player, team.goals, goalsReceived); + position["team"] = team.team; + }; + break; + default: + standingCalcFunction = function(){}; + } + return standingCalcFunction; + }; + + $scope.hasStandings = function(theTournament, thePhase) { + return theTournament ? theTournament.config.phasesWithStandings.indexOf(thePhase) != -1 : false; + }; + + $scope.getPicture = function(alias) { + var player = $scope.playersMap[alias]; + return player ? player.image : ""; + }; + + $scope.$watch(function () { return Data.getCurrentPhase(); }, function (newValue, oldValue) { + if (newValue !== oldValue) selectPhase(newValue); + }); + + $scope.addPlayerTag = function(player) { + if ($scope.players.indexOf(player) == -1) { + $scope.players.push(player); + } + }; + $scope.removePlayerTag = function(player) { + var index = $scope.players.indexOf(player); + if (index != -1) { + $scope.players.splice(index, 1); + } + }; + + $scope.orderByDateFn = function(match) { + return match.date instanceof Date ? match.date.toISOString() : match.date; + }; + + $scope.generateRandomTeams = function() { + // Todo get valid teams from the tournament + $scope.randomTeams = _.sample(["Barcelona", "RealMadrid", "Juventus", "Bayern", "Borussia", "Chelsea", "ManCity", "ManUtd", "PSG"],2); + }; + + //Data + $scope.players = []; + $scope.playersArray = playersData; + $scope.tagFilters = []; + $scope.playersMap = {}; + + $.each(playersData, function (index, player) { + $scope.playersMap[player.alias] = player; + }); + $scope.matches = matches; + $scope.filteredMatches = {}; + $scope.theTournament = tournament; + Data.setCurrentTournament(tournament); + if (tournament && tournament.config.defaultPhase) { + selectPhase(tournament.config.defaultPhase); + } + $(".navbar-collapse").collapse('hide'); +}]) + .filter('matchFilter', function() { + return function(matches, filter) { + var out = []; + var index; + if (filter.length == 0) { + return matches; + } + for (index = 0; index < matches.length; ++index) { + var match = matches[index]; + var hasAllPlayers = true; + for (j = 0; j < filter.length && hasAllPlayers; ++j) { + hasAllPlayers = match.home.player == filter[j] || match.home.partner ==filter[j] || + match.away.player == filter[j] || match.away.partner ==filter[j]; + } + if (hasAllPlayers) { + out.push(match); + } + } + return out; + } + }) + .filter('tagFilter', function() { + var setResultsClass = function(match) { + if (match.home.goals == -1 && match.away.goals == -1) { + match.clazz = "notPlayed"; + } else { + var homeGoals = match.home.goals; + var awayGoals = match.away.goals; + if (homeGoals == awayGoals) { + homeGoals += (match.home.penalties || 0); + awayGoals += (match.away.penalties || 0); + } else { + delete match.home.penalties; + delete match.away.penalties; + } + if (homeGoals > awayGoals) { + match.home.clazz = "won"; + match.away.clazz = ""; + } else if (homeGoals < awayGoals) { + match.home.clazz = ""; + match.away.clazz = "won"; + } else { + match.home.clazz = ""; + match.away.clazz = ""; + } + } + }; + return function(matches, tagFilter) { + var out = []; + if (tagFilter.length == 0 || (tagFilter.length == 1 && !tagFilter[0])) { + return matches; + } + + for (var index = 0; index < matches.length; ++index) { + var match = matches[index]; + var hasAllTags = true; + for (var j = 0; j < tagFilter.length && hasAllTags; ++j) { + hasAllTags = tagFilter[j] == match.tournament.name || tagFilter[j] == match.phase; + } + if (hasAllTags) { + setResultsClass(match); + out.push(match); + } + } + return out; + } + }); \ No newline at end of file diff --git a/public/js/plugins/sb-admin-2.js b/public/js/plugins/sb-admin-2.js new file mode 100755 index 0000000..5be2c88 --- /dev/null +++ b/public/js/plugins/sb-admin-2.js @@ -0,0 +1,36 @@ +$(function() { + + $('#side-menu').metisMenu(); + +}); + +//Loads the correct sidebar on window load, +//collapses the sidebar on window resize. +// Sets the min-height of #page-wrapper to window size +$(function() { + $(window).bind("load resize", function() { + topOffset = 50; + width = (this.window.innerWidth > 0) ? this.window.innerWidth : this.screen.width; + if (width < 768) { + $('div.navbar-collapse').addClass('collapse'); + topOffset = 100; // 2-row-menu + } else { + $('div.navbar-collapse').removeClass('collapse'); + } + + height = ((this.window.innerHeight > 0) ? this.window.innerHeight : this.screen.height) - 1; + height = height - topOffset; + if (height < 1) height = 1; + if (height > topOffset) { + $("#page-wrapper").css("min-height", (height) + "px"); + } + }); + + var url = window.location; + var element = $('ul.nav a').filter(function() { + return this.href == url || url.href.indexOf(this.href) == 0; + }).addClass('active').parent().parent().addClass('in').parent(); + if (element.is('li')) { + element.addClass('active'); + } +}); diff --git a/public/js/service/appService.js b/public/js/service/appService.js new file mode 100644 index 0000000..ce99fa0 --- /dev/null +++ b/public/js/service/appService.js @@ -0,0 +1,47 @@ +angular.module("fifa").service("tournamentService", ["$http", function($http) { + this.getTournaments = function() { + return $http.get("/api/tournament").then(function(data) { + return data; + }); + }; + this.getTournament = function(tournamentName) { + return $http.get("/api/tournament/" + tournamentName).then(function(response) { + return response.data; + }); + } +}]) + .service("playerService", ["$http", function($http) { + this.getPlayers = function() { + return $http.get("/api/player").then(function(response) { + return response.data; + }); + }; + this.getPlayer = function(alias) { + return $http.get("/api/player/" + alias).then(function(response) { + return response.data; + }); + }; + this.getPlayerStats = function(alias) { + return $http.get("/api/player/stats/" + alias).then(function(response) { + return response.data; + }); + }; + this.getAllPlayerStats = function() { + return $http.get("/api/player/stats/all").then(function(response) { + return response.data; + }); + } + }]) + .service("matchService", ["$http", function($http) { + this.getMatches = function(tournamentName) { + return $http.get("/api/match/tournament/" + tournamentName).then(function(response) { + return response.data; + }); + + }; + this.getMatchesForPlayer = function(alias) { + return $http.get("/api/match/player/" + alias).then(function(response) { + return response.data; + }); + } + }]); \ No newline at end of file diff --git a/server.js b/server.js new file mode 100644 index 0000000..50102b0 --- /dev/null +++ b/server.js @@ -0,0 +1,87 @@ +// server.js + +// set up ======================== +require('newrelic'); +var express = require('express'); +var app = express(); // create our app w/ express +var mongoose = require('mongoose'); // mongoose for mongodb +var morgan = require('morgan'); // log requests to the console (express4) +var bodyParser = require('body-parser'); // pull information from HTML POST (express4) +var methodOverride = require('method-override'); // simulate DELETE and PUT (express4) +var favicon = require('serve-favicon'); +var passport = require('passport'); +var session = require('express-session'); +var RedisStore = require( 'connect-redis' )( session ); +var cookieSession = require('cookie-session'); +var env = require('node-env-file'); + +env(__dirname + "/" + (process.env.ENV_FILE || '/env.config')); +app.use(cookieSession({ + keys: ['key1', 'key2'] +})); + +// Passport session setup. +// To support persistent login sessions, Passport needs to be able to +// serialize users into and deserialize users out of the session. Typically, +// this will be as simple as storing the user ID when serializing, and finding +// the user by ID when deserializing. However, since this example does not +// have a database of user records, the complete Google profile is +// serialized and deserialized. +passport.serializeUser(function(user, done) { + done(null, user._id.valueOf()); +}); + +var schemas = require("./app/model/schemas"); +passport.deserializeUser(function(obj, done) { + if (typeof obj !== 'string') { + obj = obj._id; + } + schemas.Player.findOne({_id: mongoose.Types.ObjectId(obj)}, done); +}); + + +require("./app/config/google")(passport); +// configuration ================= + +var mongoUri = process.env.MONGOLAB_URI || + process.env.MONGOHQ_URL || + process.env.LOCAL_DB_URL; + +mongoose.connect(mongoUri); + + +app.use( session({ + secret: 'cookie_secret', + name: 'kaas', + store: new RedisStore({ + host: 'localhost', + port: 6379 + }), + proxy: true, + resave: true, + saveUninitialized: true +})); +app.use( passport.initialize()); +app.use( passport.session()); + +app.set('views', __dirname + '/views'); +app.set('view engine', 'ejs'); +app.use(express.static(__dirname + '/public')); +app.use(favicon(__dirname + '/public/favicon.ico')); +app.use('/bower_components', express.static(__dirname + '/bower_components')); +app.use(morgan('dev')); // log every request to the console +app.use(bodyParser.urlencoded({'extended':'true'})); // parse application/x-www-form-urlencoded +app.use(bodyParser.json()); // parse application/json +app.use(methodOverride()); + +require('./app/api/player.js')(app); +require('./app/api/tournament.js')(app); +require('./app/api/match.js')(app); +require('./app/api/randomize.js')(app); +require('./app/api/routes.js')(app, passport); + +// listen (start app with node server.js) ====================================== +app.set('port', (process.env.PORT)); +app.listen(app.get('port'), function() { + console.log('Node app is running on port', app.get('port')); +}); diff --git a/tags/bootstrap-tags-master.zip b/tags/bootstrap-tags-master.zip deleted file mode 100644 index 0bf8a83..0000000 Binary files a/tags/bootstrap-tags-master.zip and /dev/null differ diff --git a/tags/bootstrap-tags.css b/tags/bootstrap-tags.css deleted file mode 100644 index c3269b6..0000000 --- a/tags/bootstrap-tags.css +++ /dev/null @@ -1,78 +0,0 @@ -/* bootstrap-tags styles */ -.bootstrap-tags.bootstrap-3 .tag a { - margin: 0 0 0 .3em; } -.bootstrap-tags.bootstrap-3 .glyphicon-white { - color: #fff; } - -.bootstrap-tags.bootstrap-2 .tag.md { - padding: .3em .4em .4em; } -.bootstrap-tags.bootstrap-2 .tag.lg { - padding: .4em .4em .5em; } - -.bootstrap-tags { - position: relative; } - .bootstrap-tags .tags { - width: inherit; - height: 0; - position: absolute; - padding: 0; - margin: 0; } - .bootstrap-tags .tag-data { - display: none; } - .bootstrap-tags .tags-input { - width: 100%; - margin: 0; - padding: 0; - height: 1.7em; - box-sizing: content-box; - -webkit-box-sizing: content-box; - -moz-box-sizing: content-box; } - .bootstrap-tags .tag-list { - width: 280px; - height: auto; - min-height: 26px; - left: 2px; - top: 2px; - position: relative; } - .bootstrap-tags .tag { - padding: .4em .4em .4em; - margin: 0 .1em; - float: left; } - .bootstrap-tags .tag.sm { - padding: .4em .4em .5em; - font-size: 12px; } - .bootstrap-tags .tag.md { - font-size: 14px; } - .bootstrap-tags .tag.lg { - font-size: 18px; - padding: .4em .4em .4em; - margin: 0 .2em .2em 0; } - .bootstrap-tags .tag a { - color: #bbb; - cursor: pointer; - opacity: .5; } - .bootstrap-tags .tag .remove { - vertical-align: bottom; - top: 0; } - .bootstrap-tags ul.tags-suggestion-list { - width: 300px; - height: auto; - list-style: none; - margin: 0; - z-index: 2; - max-height: 160px; - overflow: scroll; } - .bootstrap-tags ul.tags-suggestion-list li.tags-suggestion { - padding: 3px 20px; - height: auto; } - .bootstrap-tags ul.tags-suggestion-list li.tags-suggestion-highlighted { - color: white; - text-decoration: none; - background-color: #0081C2; - background-image: -moz-linear-gradient(top, #0088cc, #0077b3); - background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0077b3)); - background-image: -webkit-linear-gradient(top, #0088cc, #0077b3); - background-image: -o-linear-gradient(top, #0088cc, #0077b3); - background-image: linear-gradient(to bottom, #0088cc, #0077b3); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0077b3', GradientType=0); } diff --git a/tags/bootstrap-tags.min.js b/tags/bootstrap-tags.min.js deleted file mode 100644 index 05c5927..0000000 --- a/tags/bootstrap-tags.min.js +++ /dev/null @@ -1,7 +0,0 @@ -/*! - * bootstrap-tags 1.1.5 - * https://github.com/maxwells/bootstrap-tags - * Copyright 2013 Max Lahey; Licensed MIT - */ - -!function(a){!function(){window.Tags||(window.Tags={}),jQuery(function(){return a.tags=function(b,c){var d,e,f,g,h,i,j,k=this;null==c&&(c={});for(d in c)g=c[d],this[d]=g;if(this.bootstrapVersion||(this.bootstrapVersion="3"),this.readOnly||(this.readOnly=!1),this.suggestOnClick||(this.suggestOnClick=!1),this.suggestions||(this.suggestions=[]),this.restrictTo=null!=c.restrictTo?c.restrictTo.concat(this.suggestions):!1,this.exclude||(this.exclude=!1),this.displayPopovers=null!=c.popovers?!0:null!=c.popoverData,this.popoverTrigger||(this.popoverTrigger="hover"),this.tagClass||(this.tagClass="btn-info"),this.tagSize||(this.tagSize="md"),this.promptText||(this.promptText="Enter tags..."),this.caseInsensitive||(this.caseInsensitive=!1),this.readOnlyEmptyMessage||(this.readOnlyEmptyMessage="No tags to display..."),this.maxNumTags||(this.maxNumTags=-1),this.beforeAddingTag||(this.beforeAddingTag=function(){}),this.afterAddingTag||(this.afterAddingTag=function(){}),this.beforeDeletingTag||(this.beforeDeletingTag=function(){}),this.afterDeletingTag||(this.afterDeletingTag=function(){}),this.definePopover||(this.definePopover=function(a){return'associated content for "'+a+'"'}),this.excludes||(this.excludes=function(){return!1}),this.tagRemoved||(this.tagRemoved=function(){}),this.pressedReturn||(this.pressedReturn=function(){}),this.pressedDelete||(this.pressedDelete=function(){}),this.pressedDown||(this.pressedDown=function(){}),this.pressedUp||(this.pressedUp=function(){}),this.$element=a(b),null!=c.tagData?this.tagsArray=c.tagData:(f=a(".tag-data",this.$element).html(),this.tagsArray=null!=f?f.split(","):[]),c.popoverData)this.popoverArray=c.popoverData;else for(this.popoverArray=[],j=this.tagsArray,h=0,i=j.length;i>h;h++)e=j[h],this.popoverArray.push(null);return this.getTags=function(){return k.tagsArray},this.getTagsContent=function(){return k.popoverArray},this.getTagsWithContent=function(){var a,b,c,d;for(a=[],b=c=0,d=k.tagsArray.length-1;d>=0?d>=c:c>=d;b=d>=0?++c:--c)a.push({tag:k.tagsArray[b],content:k.popoverArray[b]});return a},this.getTag=function(a){var b;return b=k.tagsArray.indexOf(a),b>-1?k.tagsArray[b]:null},this.getTagWithContent=function(a){var b;return b=k.tagsArray.indexOf(a),{tag:k.tagsArray[b],content:k.popoverArray[b]}},this.hasTag=function(a){return k.tagsArray.indexOf(a)>-1},this.removeTagClicked=function(b){return"A"===b.currentTarget.tagName&&(k.removeTag(a("span",b.currentTarget.parentElement).html()),a(b.currentTarget.parentNode).remove()),k},this.removeLastTag=function(){return k.tagsArray.length>0&&(k.removeTag(k.tagsArray[k.tagsArray.length-1]),k.canAddByMaxNum()&&k.enableInput()),k},this.removeTag=function(a){if(k.tagsArray.indexOf(a)>-1){if(k.beforeDeletingTag(a)===!1)return;k.popoverArray.splice(k.tagsArray.indexOf(a),1),k.tagsArray.splice(k.tagsArray.indexOf(a),1),k.renderTags(),k.afterDeletingTag(a),k.canAddByMaxNum()&&k.enableInput()}return k},this.canAddByRestriction=function(a){return this.restrictTo===!1||-1!==this.restrictTo.indexOf(a)},this.canAddByExclusion=function(a){return(this.exclude===!1||-1===this.exclude.indexOf(a))&&!this.excludes(a)},this.canAddByMaxNum=function(){return-1===this.maxNumTags||this.tagsArray.length0&&k.canAddByExclusion(a)&&k.canAddByMaxNum()){if(k.beforeAddingTag(a)===!1)return;b=k.definePopover(a),k.popoverArray.push(b||null),k.tagsArray.push(a),k.afterAddingTag(a),k.renderTags(),k.canAddByMaxNum()||k.disableInput()}return k},this.addTagWithContent=function(a,b){if(k.canAddByRestriction(a)&&!k.hasTag(a)&&a.length>0){if(k.beforeAddingTag(a)===!1)return;k.tagsArray.push(a),k.popoverArray.push(b),k.afterAddingTag(a),k.renderTags()}return k},this.renameTag=function(a,b){return k.tagsArray[k.tagsArray.indexOf(a)]=b,k.renderTags(),k},this.setPopover=function(a,b){return k.popoverArray[k.tagsArray.indexOf(a)]=b,k.renderTags(),k},this.clickHandler=function(a){return k.makeSuggestions(a,!0)},this.keyDownHandler=function(a){var b,c;switch(b=null!=a.keyCode?a.keyCode:a.which){case 13:return a.preventDefault(),k.pressedReturn(a),e=a.target.value,-1!==k.suggestedIndex&&(e=k.suggestionList[k.suggestedIndex]),k.addTag(e),a.target.value="",k.renderTags(),k.hideSuggestions();case 46:case 8:if(k.pressedDelete(a),""===a.target.value&&k.removeLastTag(),1===a.target.value.length)return k.hideSuggestions();break;case 40:if(k.pressedDown(a),""!==k.input.val()||-1!==k.suggestedIndex&&null!=k.suggestedIndex||k.makeSuggestions(a,!0),c=k.suggestionList.length,k.suggestedIndex=k.suggestedIndex=0)return k.scrollSuggested(k.suggestedIndex);break;case 38:if(k.pressedUp(a),k.suggestedIndex=k.suggestedIndex>0?k.suggestedIndex-1:0,k.selectSuggested(k.suggestedIndex),k.suggestedIndex>=0)return k.scrollSuggested(k.suggestedIndex);break;case 9:case 27:return k.hideSuggestions(),k.suggestedIndex=-1}},this.keyUpHandler=function(a){var b;return b=null!=a.keyCode?a.keyCode:a.which,40!==b&&38!==b&&27!==b?k.makeSuggestions(a,!1):void 0},this.getSuggestions=function(b,c){var d=this;return this.suggestionList=[],this.caseInsensitive&&(b=b.toLowerCase()),a.each(this.suggestions,function(a,e){var f;return f=d.caseInsensitive?e.substring(0,b.length).toLowerCase():e.substring(0,b.length),d.tagsArray.indexOf(e)<0&&f===b&&(b.length>0||c)?d.suggestionList.push(e):void 0}),this.suggestionList},this.makeSuggestions=function(b,c,d){return null==d&&(d=null!=b.target.value?b.target.value:b.target.textContent),k.suggestedIndex=-1,k.$suggestionList.html(""),a.each(k.getSuggestions(d,c),function(a,b){return k.$suggestionList.append(k.template("tags_suggestion",{suggestion:b}))}),k.$(".tags-suggestion").mouseover(k.selectSuggestedMouseOver),k.$(".tags-suggestion").click(k.suggestedClicked),k.suggestionList.length>0?k.showSuggestions():k.hideSuggestions()},this.suggestedClicked=function(a){return e=a.target.textContent,-1!==k.suggestedIndex&&(e=k.suggestionList[k.suggestedIndex]),k.addTag(e),k.input.val(""),k.makeSuggestions(a,!1,""),k.input.focus(),k.hideSuggestions()},this.hideSuggestions=function(){return k.$(".tags-suggestion-list").css({display:"none"})},this.showSuggestions=function(){return k.$(".tags-suggestion-list").css({display:"block"})},this.selectSuggestedMouseOver=function(b){return a(".tags-suggestion").removeClass("tags-suggestion-highlighted"),a(b.target).addClass("tags-suggestion-highlighted"),a(b.target).mouseout(k.selectSuggestedMousedOut),k.suggestedIndex=k.$(".tags-suggestion").index(a(b.target))},this.selectSuggestedMousedOut=function(b){return a(b.target).removeClass("tags-suggestion-highlighted")},this.selectSuggested=function(b){var c;return a(".tags-suggestion").removeClass("tags-suggestion-highlighted"),c=k.$(".tags-suggestion").eq(b),c.addClass("tags-suggestion-highlighted")},this.scrollSuggested=function(a){var b,c,d,e;return c=k.$(".tags-suggestion").eq(a),d=k.$(".tags-suggestion").eq(0),b=c.position(),e=d.position(),null!=b?k.$(".tags-suggestion-list").scrollTop(b.top-e.top):void 0},this.adjustInputPosition=function(){var b,c,d,e,f,g;return f=k.$(".tag").last(),g=f.position(),c=null!=g?g.left+f.outerWidth(!0):0,d=null!=g?g.top:0,e=k.$element.width()-c,a(".tags-input",k.$element).css({paddingLeft:Math.max(c,0),paddingTop:Math.max(d,0),width:e}),b=null!=g?g.top+f.outerHeight(!0):22,k.$element.css({paddingBottom:b-k.$element.height()})},this.renderTags=function(){var b;return b=k.$(".tags"),b.html(""),k.input.attr("placeholder",0===k.tagsArray.length?k.promptText:""),a.each(k.tagsArray,function(c,d){return d=a(k.formatTag(c,d)),a("a",d).click(k.removeTagClicked),a("a",d).mouseover(k.toggleCloseColor),a("a",d).mouseout(k.toggleCloseColor),k.displayPopovers&&k.initializePopoverFor(d,k.tagsArray[c],k.popoverArray[c]),b.append(d)}),k.adjustInputPosition()},this.renderReadOnly=function(){var b;return b=k.$(".tags"),b.html(0===k.tagsArray.length?k.readOnlyEmptyMessage:""),a.each(k.tagsArray,function(c,d){return d=a(k.formatTag(c,d,!0)),k.displayPopovers&&k.initializePopoverFor(d,k.tagsArray[c],k.popoverArray[c]),b.append(d)})},this.disableInput=function(){return this.$("input").prop("disabled",!0)},this.enableInput=function(){return this.$("input").prop("disabled",!1)},this.initializePopoverFor=function(b,d,e){return c={title:d,content:e,placement:"bottom"},"hoverShowClickHide"===k.popoverTrigger?(a(b).mouseover(function(){return a(b).popover("show"),a(".tag").not(b).popover("hide")}),a(document).click(function(){return a(b).popover("hide")})):c.trigger=k.popoverTrigger,a(b).popover(c)},this.toggleCloseColor=function(b){var c,d;return d=a(b.currentTarget),c=d.css("opacity"),c=.8>c?1:.6,d.css({opacity:c})},this.formatTag=function(a,b,c){var d;return null==c&&(c=!1),d=b.replace("<","<").replace(">",">"),k.template("tag",{tag:d,tagClass:k.tagClass,isPopover:k.displayPopovers,isReadOnly:c,tagSize:k.tagSize})},this.addDocumentListeners=function(){return a(document).mouseup(function(a){var b;return b=k.$(".tags-suggestion-list"),0===b.has(a.target).length?k.hideSuggestions():void 0})},this.template=function(a,b){return Tags.Templates.Template(this.getBootstrapVersion(),a,b)},this.$=function(b){return a(b,this.$element)},this.getBootstrapVersion=function(){return Tags.bootstrapVersion||this.bootstrapVersion},this.initializeDom=function(){return this.$element.append(this.template("tags_container"))},this.init=function(){return this.$element.addClass("bootstrap-tags").addClass("bootstrap-"+this.getBootstrapVersion()),this.initializeDom(),this.readOnly?(this.renderReadOnly(),this.removeTag=function(){},this.removeTagClicked=function(){},this.removeLastTag=function(){},this.addTag=function(){},this.addTagWithContent=function(){},this.renameTag=function(){},this.setPopover=function(){}):(this.input=a(this.template("input",{tagSize:this.tagSize})),this.suggestOnClick&&this.input.click(this.clickHandler),this.input.keydown(this.keyDownHandler),this.input.keyup(this.keyUpHandler),this.$element.append(this.input),this.$suggestionList=a(this.template("suggestion_list")),this.$element.append(this.$suggestionList),this.renderTags(),this.canAddByMaxNum()||this.disableInput(),this.addDocumentListeners())},this.init(),this},a.fn.tags=function(b){var c,d;return d={},c="number"==typeof b?b:-1,this.each(function(e,f){var g;return g=a(f),null==g.data("tags")&&g.data("tags",new a.tags(this,b)),c===e||0===e?d=g.data("tags"):void 0}),d}})}.call(this),function(){window.Tags||(window.Tags={}),Tags.Helpers||(Tags.Helpers={}),Tags.Helpers.addPadding=function(a,b,c){return null==b&&(b=1),null==c&&(c=!0),c?0===b?a:Tags.Helpers.addPadding(" "+a+" ",b-1):a}}.call(this),function(){var a;window.Tags||(window.Tags={}),Tags.Templates||(Tags.Templates={}),(a=Tags.Templates)["2"]||(a["2"]={}),Tags.Templates["2"].input=function(a){var b;return null==a&&(a={}),b=function(){switch(a.tagSize){case"sm":return"small";case"md":return"medium";case"lg":return"large"}}(),""}}.call(this),function(){var a;window.Tags||(window.Tags={}),Tags.Templates||(Tags.Templates={}),(a=Tags.Templates)["2"]||(a["2"]={}),Tags.Templates["2"].tag=function(a){return null==a&&(a={}),"
"+Tags.Helpers.addPadding(a.tag,2,a.isReadOnly)+" "+(a.isReadOnly?"":"")+"
"}}.call(this),function(){var a;window.Tags||(window.Tags={}),Tags.Templates||(Tags.Templates={}),(a=Tags.Templates)["3"]||(a["3"]={}),Tags.Templates["3"].input=function(a){return null==a&&(a={}),""}}.call(this),function(){var a;window.Tags||(window.Tags={}),Tags.Templates||(Tags.Templates={}),(a=Tags.Templates)["3"]||(a["3"]={}),Tags.Templates["3"].tag=function(a){return null==a&&(a={}),"
"+Tags.Helpers.addPadding(a.tag,2,a.isReadOnly)+" "+(a.isReadOnly?"":"")+"
"}}.call(this),function(){var a;window.Tags||(window.Tags={}),Tags.Templates||(Tags.Templates={}),(a=Tags.Templates).shared||(a.shared={}),Tags.Templates.shared.suggestion_list=function(a){return null==a&&(a={}),''}}.call(this),function(){var a;window.Tags||(window.Tags={}),Tags.Templates||(Tags.Templates={}),(a=Tags.Templates).shared||(a.shared={}),Tags.Templates.shared.tags_container=function(a){return null==a&&(a={}),'
'}}.call(this),function(){var a;window.Tags||(window.Tags={}),Tags.Templates||(Tags.Templates={}),(a=Tags.Templates).shared||(a.shared={}),Tags.Templates.shared.tags_suggestion=function(a){return null==a&&(a={}),"
  • "+a.suggestion+"
  • "}}.call(this),function(){window.Tags||(window.Tags={}),Tags.Templates||(Tags.Templates={}),Tags.Templates.Template=function(a,b,c){return null!=Tags.Templates[a]&&null!=Tags.Templates[a][b]?Tags.Templates[a][b](c):Tags.Templates.shared[b](c)}}.call(this)}(window.jQuery); \ No newline at end of file diff --git a/views/index.ejs b/views/index.ejs new file mode 100755 index 0000000..2fed025 --- /dev/null +++ b/views/index.ejs @@ -0,0 +1,206 @@ + + + + + + + + + + + + + MArge Fifa + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + + + +
    +
    +
    +
    +
    +
    +
    +
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/views/login.ejs b/views/login.ejs new file mode 100644 index 0000000..4233074 --- /dev/null +++ b/views/login.ejs @@ -0,0 +1,21 @@ + + + + + + + + + + + + +
    +
    + + +
    +
    + + \ No newline at end of file diff --git a/views/profile.ejs b/views/profile.ejs new file mode 100644 index 0000000..374d6bb --- /dev/null +++ b/views/profile.ejs @@ -0,0 +1,95 @@ +

    {{thePlayer.alias}}

    +
    + +
    +

    Estadísticas

    +
    +
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + +
    Partidos jugados{{stats.matches.played}}
    Partidos ganados{{stats.matches.won}}
    Partidos empatados{{stats.matches.tied}}
    Partidos perdidos{{stats.matches.lost}}
    Goles a favor{{stats.goals.scored}}
    Goles en contra{{stats.goals.received}}
    Goles por partido{{stats.goals.scored / stats.matches.played | number:2}}
    Goles por partido (recibidos){{stats.goals.received / stats.matches.played | number:2}}
    Diferencia de gol + {{stats.goals.scored - stats.goals.received}} +
    Amarillas (Partidos){{stats.cards.yellow.count}} ( {{stats.cards.yellow.matches}} )
    Rojas (Partidos){{stats.cards.red.count}} ( {{stats.cards.red.matches}} )
    +
    +
    + +
    +

    Historial ranking

    +
    +
    +
    + + + + + + + + + + + + + + + + + + +
    + {{entry.date | date:'dd-MM-yyyy'}} + {{entry.ranking}} + {{entry.delta | number:2}} + + + + + + {{entry.match.home.player}} + + + {{entry.match.home.partner}} + +
    +
    + {{entry.match.home.goals}} + ({{entry.match.home.penalties}}) + vs + {{entry.match.away.goals}} + ({{entry.match.away.penalties}}) + +
    +
    + + {{entry.match.away.player}} + + + {{entry.match.away.partner}} +
    +
    +
    + +
    diff --git a/views/ranking.ejs b/views/ranking.ejs new file mode 100644 index 0000000..d795da0 --- /dev/null +++ b/views/ranking.ejs @@ -0,0 +1,54 @@ +

    Ranking

    +
    +
    + <% if (user.admin) { %> + + <% } %> +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    PosJugadorRankingPJPG %PE %PP %Diff
    {{$index + 1}} + + + {{player.alias}} + {{player.ranking}}{{player.matchesPlayed}}{{player.wonAvg}}{{player.tiedAvg}}{{player.lostAvg}} + {{diff | number:2}} + + + +
    +
    + +
    + +
    +
    \ No newline at end of file diff --git a/views/rules.ejs b/views/rules.ejs new file mode 100644 index 0000000..9cf80f8 --- /dev/null +++ b/views/rules.ejs @@ -0,0 +1,81 @@ +

    Reglamento

    +
    + +
    + +

    Reglas generales

    +

    Registro de partidos

    +
      +
    • Mencionar en hipchat incluyendo a todos los integrantes del partido, y como estan conformados los equipos
    • +
    • Mencionar tambien a NicoR o Eze
    • +
    • Mencionar el resultado, e idealmente, tarjetas amarillas y rojas (para futuras estadisticas)
    • +
    + +

    Partidos

    +
      +
    • 6 Minutos
    • +
    • Modo normal
    • +
    • Dia despejado (sin lluvia, nieve, etc) en horario nocturno (para evitar las sombras de las lamparas)
    • +
    • sin extension de tiempo en fase de grupos o liga
    • +
    • 3 Cambios de jugadores por partido
    • +
    • el equipo de la izquierda es el local, el de la derecha es el visitante.
    • +
    + +

    Empates

    +

    Empates en zona de grupos o liga

    +
      +
    • En caso de empate en puntos se define por diferencia de gol.
    • +
    • En caso de empate en diferencia de goles por goles a favor.
    • +
    • En caso de empate en goles a favor, se define por partido entre si
    • +
    • Si persiste el empate, se tira la moneda
    • +
    + +

    Empates en eliminacion directa

    +
      +
    • Extension de tiempo (no golden o silver goal), si persiste el empate, penales
    • +
    + +

    Torneo 7

    + +

    Modalidad

    +
      +
    • Liga, 2 vs 2 compañeros fijos, ida y vuelta, equipos random dentro de un subset
    • +
    • Cada jugador debera sortear el equipo con el que disputa ese partido
    • +
    • Equipos elegidos: Barcelona, Real Madrid, Juventus, Bayern Munich, Borussia Dortmund, Chelsea, Man. City, Man. Utd, PSG
    • +
    • Para obtener un equipo random: + curl -X POST -H "Content-Type: application/json" localhost:8080/api/random/value --data '{"data": ["Barcelona", "Real Madrid", "Juventus", "Bayer Munich", "Borussia Dortmund", "Chelsea", "Man. City", "Man. Utd", "PSG"]} ' +
    • +
    + +

    Copa America 1

    + +

    Modalidad

    +
      +
    • 4 jugadores en cada grupo (A, B, C, D), clasifican los dos primeros de cada zona, luego eliminacion directa
    • +
    • Cada jugador tiene un pais fijo previamente sorteado de modo random
    • +
    • Cada partido el jugador debe elegir un compañero para los partidos de la fase de grupos
    • +
    • No se puede repetir compañero dentro de una misma fase
    • +
    + +

    Eliminacion directa

    +
      +
    • Los cruces se sortearan de manera aleatoria, en cuartos de final, se cruzaran todos los segundos contra todos los primeros, luego, es indistinto
    • +
    • Los compañeros de cada jugador tambien sera por sorteo (ver siguiente seccion)
    • +
    • La localia, tambien sera por sorteo en cada ronda
    • +
    + +

    Eleccion de compañero

    +
      +
    • Alguien que no este en su mismo grupo en fase de grupos
    • +
    • La prioridad para la eleccion la tiene el visitante
    • +
    • Para la fase de eliminacion directa, la eleccion del compañero sera por sorteo para todas las fases (cuartos, semis, final) entre los jugadores que hayan sido eliminados
    • +
    + +

    Inclusion invalida del compañero

    +
      +
    • Se dara el partido por perdido 3-0
    • +
    • En caso de que ambos participantes esten en falta, el partido queda invalidado por lo cual debera repetirse
    • +
    + +
    +
    \ No newline at end of file diff --git a/views/stats.ejs b/views/stats.ejs new file mode 100644 index 0000000..d583176 --- /dev/null +++ b/views/stats.ejs @@ -0,0 +1,29 @@ +

    Estadisticas

    +
    +
    +
    +
    +

    {{stat.name}}

    +
    {{stat.description}}
    + + + + + + + + + + + + + +
    JugadorValor
    {{item.name}}{{item.value | number:2}}
    + +
    + +
    + + +
    +
    \ No newline at end of file diff --git a/views/tournament.ejs b/views/tournament.ejs new file mode 100644 index 0000000..10746e4 --- /dev/null +++ b/views/tournament.ejs @@ -0,0 +1,218 @@ +

    {{theTournament.name}}

    +
    +
    + + Fecha: {{theTournament.creationDate | date:'dd-MM-yyyy'}}
    + Sorteo de equipos (no selecciones) +
    + {{$index == 1 ? 'vs' : ''}} +
    +
    +
    +
    + + + +
    + Tags: + +

    {{thePhase}}

    +

    Partidos

    + + <% if (user) { %> +
    + <% } %> +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <% if (user && user.admin) { %> + + <% } %> + + + + + + + +
    LV
    + + {{match.home.player}} + + {{match.home.goals}} + ({{match.home.penalties}}) + vs + {{match.away.goals}} + ({{match.away.penalties}}) + + + {{match.away.player}} +
    + + {{match.home.partner}} + + + {{match.away.partner}} +
    Nada por aqui!
    +
    +

    Posiciones

    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    #EquipoPtsPJPGPEPPGFGCDG
    {{$index + 1}} +
    + + {{position.player}} + + {{position.partner}} +
    {{position.points}}{{position.matchesPlayed}}{{position.matchesWon}}{{position.matchesTied}}{{position.matchesLost}}{{position.goalsScored}}{{position.goalsReceived}}{{position.goalsDiff}}
    +
    +
    +
    + + +
    + +