'use strict';
+function jsonclone(x)
+{
+ return JSON.parse(JSON.stringify(x));
+}
+
+// Log with deep clone, so that the browser will show the object at time of log,
+// instead of what it looks like at time of view.
+function dlog()
+{
+ let args = [];
+ for (const arg of arguments) {
+ args.push(jsonclone(arg));
+ }
+ console.log(args);
+}
+
function addheading(carousel, colspan, content)
{
let thead = document.createElement("thead");
tr.appendChild(th);
thead.appendChild(tr);
carousel.appendChild(thead);
-};
+}
+
function addtd(tr, className, content) {
let td = document.createElement("td");
td.appendChild(document.createTextNode(content));
td.className = className;
tr.appendChild(td);
-};
+}
+
function addth(tr, className, content) {
let th = document.createElement("th");
th.appendChild(document.createTextNode(content));
th.className = className;
tr.appendChild(th);
-};
+}
function subrank_partitions(games, parts, start_rank, tiebreakers, func) {
let result = [];
function parse_teams_from_spreadsheet(response) {
let teams = [];
- for (let i = 2; response.values[i].length >= 1; ++i) {
+ for (let i = 1; i < response.values.length && response.values[i].length >= 1; ++i) {
teams.push({
"name": response.values[i][0],
"mediumname": response.values[i][1],
"shortname": response.values[i][2],
//"tags": response.values[i][3],
+ "seeding": parseInt(response.values[i][3]),
"ngames": 0,
"nplayed": 0,
"gd": 0,
"score1": parseInt(response.values[i][2]),
"score2": parseInt(response.values[i][3]),
"streamday": response.values[i][7],
- "streamtime": response.values[i][8],
+ "streamtime": response.values[i][8].replace('.', ':'),
"group_name": real_group_name
});
}
return games;
};
-function apply_games_to_teams(games, teams)
+function get_team_code(teams, str) {
+ for (const team of teams) {
+ if (team.name === str || team.mediumname === str || team.shortname === str) {
+ return team.shortname;
+ }
+ }
+ return str;
+}
+
+function get_all_group_games(teams, groups, cb) {
+ get_sheet('Results', function(response) {
+ let games = [];
+ for (const region of ultimateconfig['group_match_scores']) {
+ for (let row = region.first_row; row <= region.last_row; ++row) {
+ let team1 = get_team_code(teams, response.values[row - 1][region.team1_column]);
+ let team2 = get_team_code(teams, response.values[row - 1][region.team2_column]);
+ if (team1 === undefined || team2 === undefined || team1 === '' || team2 === '' || team1 === null || team2 === null) {
+ continue;
+ }
+ let group_name = region.group_name;
+ if (group_name === undefined) {
+ // Infer group from whatever group both teams are in.
+ for (const [group, teams] of Object.entries(groups)) {
+ if (teams.indexOf(team1) != -1 && teams.indexOf(team2) != -1) {
+ group_name = group;
+ break;
+ }
+ }
+ }
+ let game = {
+ "name1": team1,
+ "name2": team2,
+ "score1": parseInt(response.values[row - 1][region.team1_score_column]),
+ "score2": parseInt(response.values[row - 1][region.team2_score_column]),
+ "group_name": group_name
+ };
+ if (region.stream_time_column !== undefined) {
+ game["streamtime"] = response.values[row - 1][region.stream_time_column].replace('.', ':');
+ game["streamday"] = region.stream_day;
+ }
+ games.push(game);
+ }
+ }
+ cb(games);
+ });
+};
+
+function apply_games_to_teams(games, teams, group_name, ignored_teams, ret_ignored_games)
{
let teams_to_idx = make_teams_to_idx(teams);
+ let ignored_teams_idx;
+ if (ignored_teams === undefined) {
+ ignored_teams_idx = [];
+ } else {
+ ignored_teams_idx = make_teams_to_idx(ignored_teams);
+ }
+ for (let i = 0; i < teams.length; ++i) {
+ teams[i].nplayed = 0;
+ teams[i].goals = 0;
+ teams[i].gd = 0;
+ teams[i].pts = 0;
+ }
for (let i = 0; i < games.length; ++i) {
+ if (games[i].group_name !== group_name) {
+ continue;
+ }
let idx1 = teams_to_idx[games[i].name1];
let idx2 = teams_to_idx[games[i].name2];
if (games[i].score1 === undefined || games[i].score2 === undefined ||
games[i].score1 == games[i].score2) {
continue;
}
+
+ let ignored_idx1 = ignored_teams_idx[games[i].name1];
+ let ignored_idx2 = ignored_teams_idx[games[i].name2];
+ if (ignored_idx1 !== undefined || ignored_idx2 !== undefined) {
+ if (ret_ignored_games !== undefined) {
+ // Figure out whether the fifth we're ignoring was only picked out arbitrarily
+ // (ie., there's a tie for 5th); if so, mark it as such.
+ let arbitrary = false;
+ if (ignored_idx1 !== undefined && ignored_teams[ignored_idx1].rank < 5) {
+ arbitrary = true;
+ } else if (ignored_idx2 !== undefined && ignored_teams[ignored_idx2].rank < 5) {
+ arbitrary = true;
+ }
+ ret_ignored_games.push([teams[idx1].shortname, teams[idx2].shortname, arbitrary]);
+ }
+ continue;
+ }
++teams[idx1].nplayed;
++teams[idx2].nplayed;
teams[idx1].goals += games[i].score1;
let idx1 = teams_to_idx[games[i].name1];
let idx2 = teams_to_idx[games[i].name2];
if (idx1 !== undefined) {
- ++teams[idx1].ngames;
+ ++teams[idx1].ngames; // FIXME: shouldn't nplayed be just as good?
}
if (idx2 !== undefined) {
++teams[idx2].ngames;
return teams.filter(function(team) { return team.ngames > 0; });
}
+// So that we can just have one team list, and let membership be defined by the group list.
+function filter_teams_by_group(teams, groups, group)
+{
+ return teams.filter(function(team) {
+ return groups[group].indexOf(team.shortname) != -1 || groups[group].indexOf(team.mediumname) != -1;
+ });
+}
+
function display_group_parsed(teams, games, group_name)
{
document.getElementById('entire-bug').style.display = 'none';
- apply_games_to_teams(games, teams);
+ apply_games_to_teams(games, teams, group_name);
let tiebreakers = [];
teams = rank(games, teams, 1, tiebreakers);
// Stream schedule
let max_list_len = 7;
-function display_stream_schedule(response, group_name) {
- let teams = parse_teams_from_spreadsheet(response);
- let games = parse_games_from_spreadsheet(response, group_name, true);
- display_stream_schedule_parsed(teams, games, 0);
-};
-
function sort_game_list(games) {
games = games.filter(function(game) { return game.streamtime !== undefined && game.streamtime.match(/[0-9]+:[0-9]+/) != null; });
games.sort(function(a, b) {
return Math.ceil((games.length - start_idx) / max_list_len);
}
+function get_mediumname(name, teams, teams_to_idx)
+{
+ if (teams_to_idx[name] === undefined) {
+ return name.replace(/^W /, 'Winner ').replace(/^L /, 'Loser ');
+ } else {
+ return teams[teams_to_idx[name]].mediumname;
+ }
+}
+
function display_stream_schedule_parsed(teams, games, page) {
document.getElementById('entire-bug').style.display = 'none';
for (let i = start_idx; i < games.length && row_num < max_list_len; ++i) {
let tr = document.createElement("tr");
- let name1 = teams[teams_to_idx[games[i].name1]].mediumname;
- let name2 = teams[teams_to_idx[games[i].name2]].mediumname;
+ let name1 = get_mediumname(games[i].name1, teams, teams_to_idx);
+ let name2 = get_mediumname(games[i].name2, teams, teams_to_idx);
addtd(tr, "matchup", name1 + "–" + name2);
addtd(tr, "group", games[i].group_name);
carousel.style.display = 'table';
};
-function get_group(group_name, cb)
+function get_sheet(sheet_name, cb)
{
let req = new XMLHttpRequest();
req.onload = function(e) {
- cb(JSON.parse(req.responseText), group_name);
+ cb(JSON.parse(req.responseText));
};
- req.open('GET', 'https://sheets.googleapis.com/v4/spreadsheets/' + ultimateconfig['score_sheet_id'] + '/values/\'' + group_name + '\'!A1:J50?key=' + ultimateconfig['api_key']);
+ req.open('GET', 'https://sheets.googleapis.com/v4/spreadsheets/' + ultimateconfig['score_sheet_id'] + '/values/\'' + sheet_name + '\'!A1:Z50?key=' + ultimateconfig['api_key']);
req.send();
}
-function showgroup(group_name)
+function get_group(group_name, cb)
{
- get_group(group_name, function(response, group_name) {
- let teams = parse_teams_from_spreadsheet(response);
- let games = parse_games_from_spreadsheet(response, group_name, false);
- teams = filter_teams(teams, response);
- display_group_parsed(teams, games, group_name);
- publish_group_rank(response, group_name); // Update the spreadsheet in the background.
+ get_sheet(group_name, function(response) {
+ cb(response, group_name);
});
}
+function get_teams(cb)
+{
+ get_sheet('Teams', function(response) {
+ cb(parse_teams_from_spreadsheet(response));
+ });
+}
+
+function get_groups(cb)
+{
+ get_sheet('Groups', function(response) {
+ let groups = {};
+ for (let i = 1; i < response.values.length && response.values[i].length >= 1; ++i) {
+ let team = response.values[i][0];
+ let group = response.values[i][1];
+ if (groups[group] === undefined) {
+ groups[group] = [];
+ }
+ groups[group].push(team);
+ }
+ cb(groups);
+ });
+}
+
+function showgroup(group_name)
+{
+ get_teams(function(teams) {
+ get_groups(function(groups) {
+ get_all_group_games(teams, groups, function(games) {
+ teams = filter_teams_by_group(teams, groups, group_name);
+ display_group_parsed(teams, games, group_name);
+ publish_group_rank(response, group_name); // Update the spreadsheet in the background.
+ });
+ });
+ });
+}
function showgroup_from_state()
{
function showschedule(page)
{
- let teams = [];
- let games = [];
- let num_left = 5;
-
- let cb = function(response, group_name) {
- teams = teams.concat(parse_teams_from_spreadsheet(response));
- games = games.concat(parse_games_from_spreadsheet(response, group_name, true));
- if (--num_left == 0) {
- display_stream_schedule_parsed(teams, games, 0);
- }
- };
-
- get_group('Group A', cb);
- get_group('Group B', cb);
- get_group('Group C', cb);
- get_group('Playoffs', cb);
- get_group('Playoffs 9th-13th', cb);
+ get_teams(function(teams) {
+ get_groups(function(groups) {
+ get_all_group_games(teams, groups, function(games) {
+ get_all_playoff_games(teams, groups, games, function(playoff_games) {
+ games = games.concat(playoff_games);
+ games = games.filter(function(game) { return game.streamday !== undefined; });
+ display_stream_schedule_parsed(teams, games, 0);
+ });
+ });
+ });
+ });
};
function do_series(series)
function showcarousel()
{
- let teams_per_group = [];
- let games_per_group = [];
- let combined_teams = [];
- let combined_games = [];
- let num_left = 5;
-
- let cb = function(response, group_name) {
- let teams = parse_teams_from_spreadsheet(response);
- let games = parse_games_from_spreadsheet(response, group_name, true);
- teams_per_group[group_name] = teams;
- games_per_group[group_name] = games;
-
- combined_teams = combined_teams.concat(teams);
- combined_games = combined_games.concat(games);
- if (--num_left == 0) {
- let series = [
- [ 13000, function() { display_group_parsed(teams_per_group['Group A'], games_per_group['Group A'], 'Group A'); } ],
- [ 2000, function() { hidetable(); } ],
- [ 13000, function() { display_group_parsed(teams_per_group['Group B'], games_per_group['Group B'], 'Group B'); } ],
- [ 2000, function() { hidetable(); } ],
- [ 13000, function() { display_group_parsed(teams_per_group['Group C'], games_per_group['Group C'], 'Group C'); } ],
- [ 2000, function() { hidetable(); } ]
- [ 13000, function() { display_group_parsed(teams_per_group['Playoffs 9th-13th'], games_per_group['Playoffs 9th-13th'], 'Playoffs 9th–13th'); } ],
- [ 2000, function() { hidetable(); } ]
- ];
- let num_pages = find_num_pages(combined_games);
- for (let page = 0; page < num_pages; ++page) {
- series.push([ 13000, function() { display_stream_schedule_parsed(combined_teams, combined_games, page); } ]);
- series.push([ 2000, function() { hidetable(); } ]);
- }
-
- do_series(series);
- }
- };
+ let groups_to_get = [
+ 'Group A',
+ 'Group B',
+ 'Group C',
+ 'Playoffs',
+ 'Playoffs 9th–11th',
+ 'Playoffs 12th–14th'
+ ];
+ get_teams(function(teams) {
+ get_groups(function(groups) {
+ get_all_group_games(teams, groups, function(games) {
+ get_all_playoff_games(teams, groups, games, function(playoff_games) {
+ games = games.concat(playoff_games);
+ games = games.filter(function(game) { return game.streamday !== undefined; });
+
+ let series = [
+ [ 13000, function() { display_group_parsed(filter_teams_by_group(teams, groups, 'Group A'), games, 'Group A'); } ],
+ [ 2000, function() { hidetable(); } ],
+ [ 13000, function() { display_group_parsed(filter_teams_by_group(teams, groups, 'Group B'), games, 'Group B'); } ],
+ [ 2000, function() { hidetable(); } ],
+ [ 13000, function() { display_group_parsed(filter_teams_by_group(teams, groups, 'Group C'), games, 'Group C'); } ],
+ [ 2000, function() { hidetable(); } ],
+ // We don't show the playoff groups, since we don't even know whether they have data.
+ ];
+ let num_pages = find_num_pages(games);
+ for (let page = 0; page < num_pages; ++page) {
+ series.push([ 13000, function() { display_stream_schedule_parsed(teams, games, page); } ]);
+ series.push([ 2000, function() { hidetable(); } ]);
+ }
- get_group('Group A', cb);
- get_group('Group B', cb);
- get_group('Group C', cb);
- get_group('Playoffs 9th-13th', cb);
- get_group('Playoffs', cb);
+ do_series(series);
+ });
+ });
+ });
+ });
};
function stopcarousel()