2020-01-21 06:35:58 +00:00
|
|
|
{% extends "base.html" %}
|
|
|
|
|
|
|
|
{% block js_media %}
|
2023-01-27 23:11:10 +00:00
|
|
|
<script type="text/javascript" src="{{ ACE_URL }}/ace.js"></script>
|
|
|
|
{{ form.media.js }}
|
2023-07-25 15:49:50 +00:00
|
|
|
<script type="text/javascript">
|
|
|
|
function update_submit_area(code) {
|
|
|
|
window.previous_template = code;
|
|
|
|
$('textarea#id_source').val(code);
|
|
|
|
window.ace_source.getSession().setValue(code);
|
|
|
|
}
|
|
|
|
|
|
|
|
function update_language_template() {
|
|
|
|
{% if output_only %}
|
|
|
|
window.ace_source.env.editor.setReadOnly(true);
|
|
|
|
{% else %}
|
|
|
|
var source = $('textarea#id_source');
|
|
|
|
if (source.val() == window.previous_template.replace(/\r/g, '') || source.val() == '') {
|
|
|
|
var lang_id = $('#id_language').val();
|
|
|
|
var code = localStorage.getItem('submit:' + $('#id_language').val());
|
|
|
|
|
|
|
|
if (code != null) {
|
|
|
|
update_submit_area(code);
|
|
|
|
} else {
|
|
|
|
$.get('{{ url('language_template_ajax') }}', {
|
|
|
|
id: lang_id,
|
|
|
|
problem: {{problem_id}}
|
|
|
|
}).done(function (template) {
|
|
|
|
update_submit_area(template);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
{% endif %}
|
|
|
|
}
|
2024-03-23 05:26:53 +00:00
|
|
|
|
|
|
|
{% if request.in_contest and next_valid_submit_time and not (submission_limit and submissions_left <= 0) %}
|
|
|
|
$(function () {
|
|
|
|
const $submitButton = $("#submit-button");
|
|
|
|
$submitButton.prop('disabled', true);
|
|
|
|
const nextValidDate = new Date("{{next_valid_submit_time}}");
|
|
|
|
|
|
|
|
function updateCountdown() {
|
|
|
|
var now = new Date();
|
|
|
|
var timeUntilNextValid = nextValidDate - now;
|
|
|
|
|
|
|
|
if (timeUntilNextValid > 0) {
|
|
|
|
var seconds = Math.floor(timeUntilNextValid / 1000);
|
|
|
|
$("#countdown-timer").text("{{_("Wait")}} " + seconds + "s");
|
|
|
|
setTimeout(updateCountdown, 1000);
|
|
|
|
} else {
|
|
|
|
$("#countdown-timer").text("");
|
|
|
|
$submitButton.prop('disabled', false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
updateCountdown();
|
|
|
|
});
|
|
|
|
{% endif %}
|
2023-07-25 15:49:50 +00:00
|
|
|
</script>
|
2024-03-23 05:26:53 +00:00
|
|
|
|
2023-01-27 23:11:10 +00:00
|
|
|
{% compress js %}
|
|
|
|
<script type="text/javascript">
|
|
|
|
$(function () {
|
|
|
|
function format(state) {
|
|
|
|
if (!state.id) return state.text; // optgroup
|
|
|
|
return state.text;
|
|
|
|
}
|
|
|
|
|
|
|
|
window.previous_template = '';
|
|
|
|
|
|
|
|
function makeDisplayData(data) {
|
|
|
|
var site_data = data.attr('data-info');
|
|
|
|
var judge_data = data.attr('data-judge-info');
|
|
|
|
var display_data = site_data || judge_data;
|
|
|
|
return display_data;
|
|
|
|
}
|
|
|
|
|
|
|
|
function formatSelection(state) {
|
|
|
|
if (!state.id) return state.text; // optgroup
|
|
|
|
var data = makeDisplayData($("option[data-id=" + state.id + "]"));
|
|
|
|
return $('<span>').append($('<b>').text(state.text), ' (', data, ')');
|
|
|
|
}
|
|
|
|
|
|
|
|
// Terrible hack, adapted from https://github.com/select2/select2/issues/4436
|
|
|
|
$.fn.select2.amd.define('select2/data/customAdapter', ['select2/results', 'select2/utils'], function (Result, Utils) {
|
|
|
|
RefPresenter = function ($element, options, dataAdapter) {
|
|
|
|
RefPresenter.__super__.constructor.call(this, $element, options, dataAdapter);
|
|
|
|
};
|
|
|
|
Utils.Extend(RefPresenter, Result);
|
|
|
|
RefPresenter.prototype.bind = function (container, $container) {
|
|
|
|
container.on('results:focus', function (params) {
|
|
|
|
var data = makeDisplayData($("option[data-id=" + params.data.id + "]"));
|
|
|
|
$("#result-version-info").text(data);
|
2020-01-21 06:35:58 +00:00
|
|
|
});
|
2023-01-27 23:11:10 +00:00
|
|
|
RefPresenter.__super__.bind.call(this, container, $container);
|
|
|
|
};
|
|
|
|
return RefPresenter;
|
|
|
|
});
|
|
|
|
|
|
|
|
var customAdapter = $.fn.select2.amd.require('select2/data/customAdapter');
|
|
|
|
|
|
|
|
$("#id_language").select2({
|
|
|
|
templateResult: format,
|
|
|
|
templateSelection: formatSelection,
|
|
|
|
resultsAdapter: customAdapter
|
|
|
|
});
|
|
|
|
|
|
|
|
$('#id_language').on('select2:open', function (evt) {
|
|
|
|
var dropdown = $('.select2-dropdown');
|
|
|
|
if (!$('#result-version-info').length)
|
|
|
|
dropdown.append($("<span id=\"result-version-info\">"));
|
|
|
|
dropdown.attr('id', 'language-select2');
|
|
|
|
});
|
|
|
|
|
|
|
|
$('#id_judge').on('select2:open', function (evt) {
|
|
|
|
var dropdown = $('.select2-dropdown');
|
|
|
|
$('#result-version-info').remove();
|
|
|
|
dropdown.attr('id', 'judge-select2');
|
|
|
|
});
|
|
|
|
|
|
|
|
$('#id_language').change(function () {
|
|
|
|
var lang = $("#id_language").find("option:selected").attr('data-ace');
|
|
|
|
window.ace_source.getSession().setMode("ace/mode/" + lang);
|
|
|
|
update_language_template();
|
|
|
|
});
|
|
|
|
|
|
|
|
$('#ace_source').on('ace_load', function (e, editor) {
|
|
|
|
update_language_template();
|
|
|
|
editor.commands.addCommand({
|
|
|
|
name: 'save',
|
|
|
|
bindKey: {win: 'Ctrl-S', mac: 'Command-S'},
|
|
|
|
exec: function () {
|
|
|
|
localStorage.setItem('submit:' + $('#id_language').val(), editor.getSession().getValue());
|
|
|
|
}
|
|
|
|
});
|
|
|
|
editor.getSession().setUseWrapMode(true);
|
2023-03-10 04:31:55 +00:00
|
|
|
editor.setFontSize(15);
|
2023-01-27 23:11:10 +00:00
|
|
|
editor.setShowPrintMargin(false);
|
|
|
|
// editor.setPrintMarginColumn(100);
|
|
|
|
editor.focus();
|
|
|
|
});
|
|
|
|
|
|
|
|
// $(window).resize(function () {
|
|
|
|
// $('#ace_source').height(Math.max($(window).height() - 353, 100));
|
|
|
|
// }).resize();
|
|
|
|
|
|
|
|
$('#problem_submit').submit(function (event) {
|
|
|
|
if ($('#id_source').val().length > 65536) {
|
|
|
|
alert("{{ _('Your source code must contain at most 65536 characters.') }}");
|
|
|
|
event.preventDefault();
|
|
|
|
$('#problem_submit').find(':submit').attr('disabled', false);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
function get_source_default(file) {
|
|
|
|
const reader = new FileReader();
|
|
|
|
reader.readAsText(file);
|
|
|
|
reader.onload = function (evt) {
|
|
|
|
var src = evt.target.result;
|
|
|
|
update_submit_area(src);
|
|
|
|
}
|
|
|
|
reader.onerror = function (evt) {
|
|
|
|
alert("Fail to upload file");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-03-10 04:31:55 +00:00
|
|
|
$('#id_source_file').on('click change', function(e) {
|
2023-01-27 23:11:10 +00:00
|
|
|
var file = $(this)[0].files[0];
|
|
|
|
if (file) {
|
2023-03-10 04:31:55 +00:00
|
|
|
if (file.name.endsWith('zip')) {
|
|
|
|
update_submit_area(file.name);
|
|
|
|
}
|
2023-04-05 03:41:04 +00:00
|
|
|
else if (file.name.endsWith('sb3')) {
|
|
|
|
update_submit_area(file.name);
|
|
|
|
}
|
2023-01-27 23:11:10 +00:00
|
|
|
else {
|
|
|
|
get_source_default(file);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
})
|
|
|
|
});
|
|
|
|
</script>
|
|
|
|
{% endcompress %}
|
2020-01-21 06:35:58 +00:00
|
|
|
{% endblock %}
|
|
|
|
|
|
|
|
{% block media %}
|
2023-01-27 23:11:10 +00:00
|
|
|
{{ form.media.css }}
|
2020-01-21 06:35:58 +00:00
|
|
|
{% endblock %}
|
|
|
|
|
|
|
|
{% block body %}
|
2023-01-27 23:11:10 +00:00
|
|
|
<br>
|
|
|
|
{% if not no_judges %}
|
|
|
|
{% if default_lang not in form.fields.language.queryset %}
|
|
|
|
<div class="alert alert-warning alert-dismissable">
|
|
|
|
<a class="close">x</a>
|
|
|
|
{% trans trimmed default_language=default_lang.name %}
|
|
|
|
<b>Warning!</b> Your default language, <b>{{ default_language }}</b>,
|
|
|
|
is unavailable for this problem and has been deselected.
|
|
|
|
{% endtrans %}
|
|
|
|
</div>
|
2020-01-21 06:35:58 +00:00
|
|
|
{% endif %}
|
|
|
|
|
2023-01-27 23:11:10 +00:00
|
|
|
{% if request.in_contest and submission_limit %}
|
|
|
|
{% if submissions_left > 0 %}
|
|
|
|
<div class="alert alert-warning alert-dismissable">
|
|
|
|
<a class="close">x</a>
|
|
|
|
{% trans left=submissions_left %}
|
|
|
|
You have {{ left }} submission left
|
|
|
|
{% pluralize %}
|
|
|
|
You have {{ left }} submissions left
|
|
|
|
{% endtrans %}
|
2020-01-21 06:35:58 +00:00
|
|
|
</div>
|
2023-01-27 23:11:10 +00:00
|
|
|
{% else %}
|
|
|
|
<div class="alert alert-warning alert-dismissable">
|
|
|
|
<a class="close">x</a>
|
|
|
|
{{ _('You have 0 submissions left') }}
|
|
|
|
</div>
|
|
|
|
{% endif %}
|
|
|
|
{% endif %}
|
|
|
|
{% endif %}
|
|
|
|
|
2023-03-10 04:31:55 +00:00
|
|
|
<form id="problem_submit" action="" method="post" class="form-area" enctype="multipart/form-data">
|
2023-01-27 23:11:10 +00:00
|
|
|
{% csrf_token %}
|
|
|
|
{{ form.non_field_errors() }}
|
|
|
|
<div id="submit-wrapper">
|
|
|
|
<div id="editor">
|
|
|
|
{{ form.source.errors }}
|
|
|
|
{{ form.source }}
|
|
|
|
</div>
|
|
|
|
{% if not no_judges %}
|
|
|
|
<div id="language">
|
|
|
|
{{ form.language.errors }}
|
|
|
|
<div id="language-select">
|
|
|
|
<select id="id_language" name="language">
|
|
|
|
{% for lang in form.fields.language.queryset %}
|
|
|
|
<option value="{{ lang.id }}" data-id="{{ lang.id }}" data-name="{{ lang.name }}"
|
|
|
|
data-info="{{ lang.info }}" data-ace="{{ lang.ace }}"
|
|
|
|
data-judge-info="{{ runtime_versions(lang.runtime_versions()) }}"
|
|
|
|
{% if lang.id == default_lang.id %}selected{% endif %}>{{ lang.name }}</option>
|
|
|
|
{% endfor %}
|
|
|
|
</select>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
{% endif %}
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<hr>
|
|
|
|
|
|
|
|
{% if no_judges %}
|
|
|
|
<span style="color: red">{{ _('No judge is available for this problem.') }}</span>
|
|
|
|
{% else %}
|
2023-03-10 04:31:55 +00:00
|
|
|
{{ form.source_file.errors }}
|
|
|
|
{{ form.source_file }}
|
2023-01-27 23:11:10 +00:00
|
|
|
<div class="submit-bar">
|
|
|
|
{{ form.judge }}
|
2024-03-23 05:26:53 +00:00
|
|
|
<input id="submit-button" type="submit" value="{{ _('Submit!') }}" class="button small"
|
|
|
|
{% if request.in_contest and submission_limit and submissions_left <= 0 %}disabled{% endif %}>
|
|
|
|
<span id="countdown-timer"></span>
|
2023-01-27 23:11:10 +00:00
|
|
|
</div>
|
|
|
|
{% endif %}
|
|
|
|
</form>
|
2020-07-19 21:27:14 +00:00
|
|
|
{% endblock %}
|