{% extends "user/base-users.html" %} {% block title_ruler %}{% endblock %} {% block title_row %} {% set title = contest.name %} {% include "contest/contest-tabs.html" %} {% endblock %} {% block users_media %} <style> #content-left { overflow-x: auto; } #users-table .username { min-width: 20em; } #users-table td { height: 2.5em; } #users-table a { display: block; } .userinfo a, .user-name a, .user-name form { display: inline !important; } #users-table th a, #users-table th a:link, #users-table th a:visited { color: white; } #users-table th a:hover { color: #0F0; } #users-table td a:hover { text-decoration: underline; } .first-solve { background: #00f9a1; } .rank { min-width: 2.5em } .points { min-width: 2.5em; } .disqualified { background-color: #ffa8a8 !important; } .full-score, .full-score a { font-weight: bold; color: green; } .partial-score, .partial-score a { color: green; } .failed-score, .failed-score a { font-weight: bold; color: red; } .pretest-full-score, .pretest-full-score a { font-weight: bold; color: #2980b9; } .pretest-partial-score, .pretest-partial-score a { color: #2980b9; } .pretest-failed-score, .pretest-failed-score a { font-weight: bold; color: red; } .user-points { font-weight: bold; color: black; } .solving-time { color: gray; font-weight: normal; font-size: 0.75em; padding-bottom: -0.75em; } .point-denominator { border-top: 1px solid gray; font-size: 0.7em; } .start-time { display: none; } .user-name { position: relative; } .organization-column { display: none; text-align: left !important; border-right: none !important; } .organization-column a { color: gray !important; font-weight: 600; } .fullname-column { text-align: right !important; border-right: none !important; } .fullname-column span { color: gray !important; font-weight: 600; } </style> {% if has_rating %} <style>#users-table .rate-box { font-size: 0.85em; float: left; } #users-table td:nth-child(1) .rating { margin-left: 1.25em; display: block; } #users-table td:nth-child(2) a { display: block; } </style> {% endif %} <style> .select2-selection__arrow { display: none; } .select2-selection__rendered { cursor: text; overflow: initial !important } .select2-results__option--highlighted { background-color: #DEDEDE !important; } .select2-results__option { white-space: nowrap; } #search-contest, #search-contest + .select2 { margin-top: 0.5em; } #search-contest { width: 200px; height: 2.3em; } </style> {% endblock %} {% block users_js_media %} {% if can_edit %} <script type="text/javascript"> $(function () { $('a.disqualify-participation').click(function (e) { e.preventDefault(); if (e.ctrlKey || e.metaKey || confirm("{{ _('Are you sure you want to disqualify this participation?') }}")) $(this).closest('form').submit(); }) $('a.un-disqualify-participation').click(function (e) { e.preventDefault(); if (e.ctrlKey || e.metaKey || confirm("{{ _('Are you sure you want to un-disqualify this participation?') }}")) $(this).closest('form').submit(); }) }); </script> {% endif %} {% if perms.judge.change_contestparticipation %} <script type="text/javascript"> $(function () { $('td.user').find('a.user-name').click(function (e) { var data = $(this).siblings('.edit-participation'); if (e.altKey && data.length) { window.open(data.attr('data-link'), '_blank'); return false; } }); }); </script> {% endif %} {% if not contest.ended %} <script type="text/javascript"> $(function () { window.install_tooltips = function () { $('td.user').find('a.user-name').each(function () { var link = $(this); link.mouseenter(function (e) { var start_time = link.siblings('.start-time').text(); link.addClass('tooltipped tooltipped-e').attr('aria-label', start_time); }).mouseleave(function (e) { link.removeClass('tooltipped tooltipped-e').removeAttr('aria-label'); }); }); }; install_tooltips(); }); </script> {% endif %} <script type="text/javascript" src="{{ static('event.js') }}"></script> <script type="text/javascript"> function isFaster(time1, time2) { let arr1 = time1.split(':'); let arr2 = time2.split(':'); for (let i in arr1) { let val1 = parseInt(arr1[i]); let val2 = parseInt(arr2[i]); if (val1 < val2) return true; if (val1 > val2) return false; } return false; } function scoretimeComparison(sub1, sub2) { if (!sub2) return true; return sub1['score'] > sub2['score'] || (sub1['score'] === sub2['score'] && isFaster(sub1['time'], sub2['time'])); } function highlightFirstSolve() { // bucket to store submissions by problems let bestSubmissions = {}; // get information $('td a').each(function() { let td = $(this)[0] let link = td['attributes']['href']['value'] if (link.includes('submissions')) { let scoreAndTime = (td.innerText.split('\n')) let linkElements = link.split('/') // get information let problem = linkElements[linkElements.length - 2]; let score = parseFloat(scoreAndTime[0]); let time = scoreAndTime[1]; if (time) { let curSubmission = { 'td': $(this).parent(), 'score': score, 'time': time } // update best submissions let curBest = bestSubmissions[problem] if (scoretimeComparison(curSubmission, curBest) && score) { bestSubmissions[problem] = curSubmission; } } } }) for (let problem in bestSubmissions) { bestSubmissions[problem]['td'].addClass('first-solve') } } function renew_filter() { var checkboxes = [ '#show-organizations-checkbox', '#show-fullnames-checkbox', '#show-total-score-checkbox', ]; var checkboxes2 = [ '#show-friends-checkbox', '#show-virtual-checkbox' ] for (var i of checkboxes) { var $box = $(i); if ($box.is(':checked')) { $box.prop('checked', false); $box.click(); $box.prop('checked', true); } } var to_update = false; for (var i of checkboxes2) { var $box = $(i); if ($box.is(':checked')) { to_update = true; } } if (to_update) { update_ranking(); } } function get_initial_rank() { var ranks = $('.rank-td').map(function() {return this.innerHTML}).get(); var usernames = $('.user-name .rating a').map(function() {return this.text}).get(); window.user_rank = new Map(); for (var i = 0; i < ranks.length; i++) { window.user_rank[usernames[i]] = ranks[i]; } } function add_initial_friend_rank() { var usernames = $('.user-name .rating a').map(function() {return this.text}).get(); var is_virtual = []; $('.user-name').each(function() { if($(this).children('sup').length) { is_virtual.push(1); } else is_virtual.push(0); }); $('.rank-td').each(function(i) { if (!is_virtual[i]) this.innerHTML += ' (' + window.user_rank[usernames[i]] + ')'; }); } function update_ranking() { var friend = $('#show-friends-checkbox').is(':checked'); var virtual = $('#show-virtual-checkbox').is(':checked'); $('#loading-gif').show(); $.get({ url: `/contest/{{contest.key}}/ranking/ajax?friend=${friend}&virtual=${virtual}`, success: function(HTML) { $('#users-table').html(HTML); highlightFirstSolve(); $('#loading-gif').hide(); if (!virtual && !friend) { get_initial_rank(); } if (friend) { add_initial_friend_rank(); } }, fail: function() { console.log('Fail to update ranking'); } }); } // window.load_dynamic_update = function (last_msg) { // return new EventReceiver( // "{{ EVENT_DAEMON_LOCATION }}", "{{ EVENT_DAEMON_POLL_LOCATION }}", // ['contest_{{contest.id}}'], last_msg, function (message) { // switch (message.type) { // case 'update': // update_ranking(); // break; // } // } // ); // } $(function () { var url = '{{ url('contest_participation', contest.key, '__username__') }}'; var placeholder = $('#search-contest').replaceWith($('<select>').attr({ id: 'search-contest' })).attr('placeholder'); $('#search-contest').select2({ placeholder: placeholder, ajax: { url: '{{ url('contest_user_search_select2_ajax', contest.key) }}' }, minimumInputLength: 1, escapeMarkup: function (markup) { return markup; }, templateResult: function (data, container) { return ('<img class="user-search-image" src="' + data.gravatar_url + '" width="24" height="24">' + '<span class="' + data.display_rank + ' user-search-name">' + data.text + '</span>'); } }).on('change', function () { window.location.href = url.replace('__username__', $(this).val()); }); $('#show-organizations-checkbox').click(function () { $('.organization-column').toggle(); }); $('#show-fullnames-checkbox').click(function () { $('.fullname-column').toggle(); }); {% if request.user.is_authenticated %} $('#show-friends-checkbox').click(function() { update_ranking(); }) {% endif %} $('#show-virtual-checkbox').click(function() { update_ranking(); }) $('#show-total-score-checkbox').click(function() { $('.problem-score-col').toggle(); }) highlightFirstSolve(); renew_filter(); get_initial_rank(); {% if participation_tab %} $('#show-virtual-checkbox').hide(); $('#show-virtual-label').hide(); {% else %} {% if request.in_contest %} setInterval(update_ranking, 60 * 1000); {% endif %} {% endif %} }); </script> {% include "contest/media-js.html" %} {% endblock %} {% block users_table %} <div style="margin-bottom: 0.5em"> {% if tab == 'participation' %} {% if contest.can_see_full_scoreboard(request.user) %} <input id="search-contest" type="text" placeholder="{{ _('View user participation') }}"> {% endif %} {% endif %} <input id="show-organizations-checkbox" type="checkbox" style="vertical-align: bottom"> <label for="show-organizations-checkbox" style="vertical-align: bottom; margin-right: 1em;">{{ _('Show organizations') }}</label> <input id="show-fullnames-checkbox" type="checkbox" style="vertical-align: bottom"> <label for="show-fullnames-checkbox" style="vertical-align: bottom; margin-right: 1em;">{{ _('Show full name') }}</label> {% if request.user.is_authenticated %} <input id="show-friends-checkbox" type="checkbox" style="vertical-align: bottom;"> <label for="show-friends-checkbox" style="vertical-align: bottom; margin-right: 1em;">{{ _('Show friends only') }}</label> {% endif %} <input id="show-total-score-checkbox" type="checkbox" style="vertical-align: bottom; "> <label for="show-total-score-checkbox" style="vertical-align: bottom; margin-right: 1em;">{{ _('Total score only') }}</label> <input id="show-virtual-checkbox" type="checkbox" style="vertical-align: bottom;"> <label id="show-virtual-label" for="show-virtual-checkbox" style="vertical-align: bottom; margin-right: 1em;">{{ _('Show virtual participation') }}</label> <img src="{{static('loading.gif')}}" style="height: 1em; display:none;" id="loading-gif"></img> </div> {% include "contest/ranking-table.html" %} {% endblock %}