// locale
uojLocaleData = {
"username": {
"en": "Username",
"zh-cn": "用户名"
},
"contests::total score": {
"en": "Score",
"zh-cn": "总分"
},
"contests::n participants": {
"en": function(n) {
return n + " participant" + (n <= 1 ? '' : 's');
},
"zh-cn": function(n) {
return "共 " + n + " 名参赛者";
}
},
"click-zan::good": {
"en": "Good",
"zh-cn": "好评"
},
"click-zan::bad": {
"en": "Bad",
"zh-cn": "差评"
},
"editor::use advanced editor": {
"en": "use advanced editor",
"zh-cn": "使用高级编辑器"
},
"editor::language": {
"en": "Language",
"zh-cn": "语言"
},
"editor::browse": {
"en": "Browse",
"zh-cn": "浏览"
},
"editor::upload by editor": {
"en": "Upload by editor",
"zh-cn": "使用编辑器上传"
},
"editor::upload from local": {
"en": "Upload from local",
"zh-cn": "从本地文件上传"
}
};
function uojLocale(name) {
locale = $.cookie('uoj_locale');
if (uojLocaleData[name] === undefined) {
return '';
}
if (uojLocaleData[name][locale] === undefined) {
locale = 'zh-cn';
}
val = uojLocaleData[name][locale];
if (!$.isFunction(val)) {
return val;
} else {
var args = [];
for (var i = 1; i < arguments.length; i++) {
args.push(arguments[i]);
}
return val.apply(this, args);
}
}
// utility
function strToDate(str) {
var a = str.split(/[^0-9]/);
return new Date(
parseInt(a[0]),
parseInt(a[1]) - 1,
parseInt(a[2]),
parseInt(a[3]),
parseInt(a[4]),
parseInt(a[5]),
0);
}
function dateToStr(date) {
return date.getFullYear() + '-' + (date.getMonth() + 1) + '-' + date.getDate() + ' ' + date.getHours() + ':' + date.getMinutes() + ':' + date.getSeconds();
}
function toFilledStr(o, f, l) {
var s = o.toString();
while (s.length < l) {
s = f.toString() + s;
}
return s;
}
function getPenaltyTimeStr(x) {
var ss = toFilledStr(x % 60, '0', 2);
x = Math.floor(x / 60);
var mm = toFilledStr(x % 60, '0', 2);
x = Math.floor(x / 60);
var hh = x.toString();
return hh + ':' + mm + ':' + ss;
}
function htmlspecialchars(str)
{
var s = "";
if (str.length == 0) return "";
s = str.replace(/&/g, "&");
s = s.replace(//g, ">");
s = s.replace(/"/g, """);
return s;
}
function getColOfRating(rating) {
if (rating < 1500) {
var H = 300 - (1500 - 850) * 300 / 1650, S = 30 + (1500 - 850) * 70 / 1650, V = 50 + (1500 - 850) * 50 / 1650;
if (rating < 300) rating = 300;
var k = (rating - 300) / 1200;
return ColorConverter.toStr(ColorConverter.toRGB(new HSV(H + (300 - H) * (1 - k), 30 + (S - 30) * k, 50 + (V - 50) * k)));
}
if (rating > 2500) {
rating = 2500;
}
return ColorConverter.toStr(ColorConverter.toRGB(new HSV(300 - (rating - 850) * 300 / 1650, 30 + (rating - 850) * 70 / 1650, 50 + (rating - 850) * 50 / 1650)));
}
function getColOfScore(score) {
if (score == 0) {
return ColorConverter.toStr(ColorConverter.toRGB(new HSV(0, 100, 80)));
} else if (score == 100) {
return ColorConverter.toStr(ColorConverter.toRGB(new HSV(120, 100, 80)));
} else {
return ColorConverter.toStr(ColorConverter.toRGB(new HSV(30 + score * 60 / 100, 100, 90)));
}
}
function getUserLink(username, rating, addSymbol) {
if (!username) {
return '';
}
if (addSymbol == undefined) {
addSymbol = true;
}
var text = username;
if (username.charAt(0) == '@') {
username = username.substr(1);
}
if (addSymbol) {
if (rating >= 2500) {
text += '';
for (var i = 2500; i <= rating; i += 200) {
text += "ℵ"
}
text += "";
}
}
return '' + text + '';
}
function getUserSpan(username, rating, addSymbol) {
if (!username) {
return '';
}
if (addSymbol == undefined) {
addSymbol = true;
}
var text = username;
if (username.charAt(0) == '@') {
username = username.substr(1);
}
if (addSymbol) {
if (rating >= 2500) {
text += '';
for (var i = 2500; i <= rating; i += 200) {
text += "ℵ"
}
text += "";
}
}
return '' + text + '';
}
function replaceWithHighlightUsername() {
var username = $(this).text();
var rating = $(this).data("rating");
if (isNaN(rating)) {
return;
}
if ($(this).data("link") != 0) {
$(this).replaceWith(getUserLink(username, rating));
} else {
$(this).replaceWith(getUserSpan(username, rating));
}
}
$.fn.uoj_honor = function() {
return this.each(function() {
var honor = $(this).text();
var rating = $(this).data("rating");
if (isNaN(rating)) {
return;
}
if (rating >= 2500) {
honor += '';
for (var i = 2500; i <= rating; i += 200) {
honor += "ℵ"
}
honor += "";
}
$(this).css("color", getColOfRating(rating)).html(honor);
});
}
function showErrorHelp(name, err) {
if (err) {
$('#div-' + name).addClass('has-error');
$('#help-' + name).text(err);
return false;
} else {
$('#div-' + name).removeClass('has-error');
$('#help-' + name).text('');
return true;
}
}
function getFormErrorAndShowHelp(name, val) {
var err = val($('#input-' + name).val());
return showErrorHelp(name, err);
}
function validateSettingPassword(str) {
if (str.length < 6) {
return '密码长度不应小于6。';
} else if (! /^[!-~]+$/.test(str)) {
return '密码应只包含可见ASCII字符。';
} else if (str != $('#input-confirm_password').val()) {
return '两次输入的密码不一致。';
} else {
return '';
}
}
function validatePassword(str) {
if (str.length < 6) {
return '密码长度不应小于6。';
} else if (! /^[!-~]+$/.test(str)) {
return '密码应只包含可见ASCII字符。';
} else {
return '';
}
}
function validateEmail(str) {
if (str.length > 50) {
return '电子邮箱地址太长。';
} else if (! /^(.+)@(.+)$/.test(str)) {
return '电子邮箱地址非法。';
} else {
return '';
}
}
function validateUsername(str) {
if (str.length == 0) {
return '用户名不能为空。';
} else if (! /^[a-zA-Z0-9_]+$/.test(str)) {
return '用户名应只包含大小写英文字母、数字和下划线。';
} else {
return '';
}
}
function validateQQ(str) {
if (str.length < 5) {
return 'QQ的长度不应小于5。';
} else if (str.length > 15) {
return 'QQ的长度不应大于15。';
} else if (/\D/.test(str)) {
return 'QQ应只包含0~9的数字。';
} else {
return '';
}
}
function validateMotto(str) {
if (str.length > 50) {
return '不能超过50字';
} else {
return '';
}
}
// tags
$.fn.uoj_problem_tag = function() {
return this.each(function() {
$(this).attr('href', uojHome + '/problems?tag=' + encodeURIComponent($(this).text()));
});
}
$.fn.uoj_blog_tag = function() {
return this.each(function() {
$(this).attr('href', uojBlogUrl + '/archive?tag=' + encodeURIComponent($(this).text()));
});
}
// click zan
function click_zan(zan_id, zan_type, zan_delta, node) {
var loading_node = $('
loading...
');
$(node).replaceWith(loading_node);
$.post('/click-zan', {
id : zan_id,
delta : zan_delta,
type : zan_type
}, function(ret) {
$(loading_node).replaceWith($(ret).click_zan_block());
}).fail(function() {
$(loading_node).replaceWith('');
var show_help_lang = function() {
if ($(this).val() == 'Java7' || $(this).val() == 'Java8') {
div_help_language.text('注意:Java 程序源代码中不应指定所在的 package。我们会在源代码中找到第一个被定义的类并以它的 main 函数为程序入口点。');
} else {
div_help_language.text('');
}
};
var advanced_editor = null;
var advanced_editor_init = function() {
require_codemirror({}, function() {
var mode = get_codemirror_mode(input_language.val());
require_codemirror_mode(mode, function() {
if (advanced_editor != null) {
return;
}
advanced_editor = CodeMirror.fromTextArea(input_editor[0], {
mode: mode,
lineNumbers: true,
matchBrackets: true,
lineWrapping: true,
styleActiveLine: true,
indentUnit: 4,
indentWithTabs: true,
theme: 'default'
});
advanced_editor.on('change', function() {
advanced_editor.save();
});
$(advanced_editor.getWrapperElement()).css('box-shadow', '0 2px 10px rgba(0,0,0,0.2)');
advanced_editor.focus();
});
});
}
var save_prefer_upload_type = function(type) {
$.cookie('uoj_source_code_form_group_preferred_upload_type', type, { expires: 7, path: '/' });
};
autosave_locally(2000, name, input_editor);
var prefer_upload_type = $.cookie('uoj_source_code_form_group_preferred_upload_type');
if (prefer_upload_type === null) {
prefer_upload_type = 'editor';
}
if (prefer_upload_type == 'file') {
input_upload_type_file[0].checked = true;
div_editor.css('display', 'none');
} else {
input_upload_type_editor[0].checked = true;
div_file.css('display', 'none');
if (prefer_upload_type == 'advanced') {
input_use_advanced_editor[0].checked = true;
}
}
input_language.each(show_help_lang);
input_language.change(show_help_lang);
input_language.change(function() {
if (advanced_editor != null) {
var mode = get_codemirror_mode(input_language.val());
require_codemirror_mode(mode, function() {
if (mode != get_codemirror_mode(input_language.val())) {
return;
}
advanced_editor.setOption('mode', mode);
});
}
})
input_upload_type_editor.click(function() {
div_editor.show('fast');
div_file.hide('fast');
save_prefer_upload_type('editor');
});
input_upload_type_file.click(function() {
div_file.show('fast');
div_editor.hide('fast');
save_prefer_upload_type('file');
});
input_file.change(function() {
input_file_path.val(input_file.val());
});
input_use_advanced_editor.click(function() {
if (this.checked) {
advanced_editor_init();
save_prefer_upload_type('advanced');
} else {
if (advanced_editor != null) {
advanced_editor.toTextArea();
advanced_editor = null;
input_editor.focus();
}
save_prefer_upload_type('editor');
}
});
$(this)
.append($('
'))
.append($('
'))
.append($('
')
.append(input_language)
)
.append($('
')
.append($('
')
.append(input_upload_type_editor)
.append(' '+uojLocale('editor::upload by editor'))
)
)
.append($('
')
.append($('
')
.append(input_upload_type_file)
.append(' '+uojLocale('editor::upload from local'))
)
)
.append(div_help_language)
.append(div_editor)
.append(div_file);
if (prefer_upload_type == 'advanced') {
var check_advanced_init = function() {
if (div_editor.is(':visible')) {
advanced_editor_init();
} else {
setTimeout(check_advanced_init, 1);
}
}
check_advanced_init();
}
});
}
// text file form group
$.fn.text_file_form_group = function(name, text) {
return this.each(function() {
var input_upload_type_name = name + '_upload_type';
var input_editor_id = 'input-' + name + '_editor';
var input_editor_name = name + '_editor';
var input_file_id = 'input-' + name + '_file';
var input_file_name = name + '_file';
var div_editor_id = 'div-' + name + '_editor';
var div_file_id = 'div-' + name + '_file';
var help_file_id = 'help-' + name + '_file';
var input_upload_type_editor = $('
');
var input_upload_type_file = $('
');
var input_file = $('
');
var input_file_path = $('
');
var input_editor = $('
');
var input_use_advanced_editor = $('
');
var div_editor =
$('
')
.append(input_editor)
.append($('
')
.append($('
')
.append(input_use_advanced_editor)
.append(' ' + uojLocale('editor::use advanced editor'))
)
)
var div_file =
$('
')
.append(input_file)
.append($('
')
.append(input_file_path)
.append($('
')
.append($('
')
.css('width', '100px')
.click(function() {
input_file.click();
})
)
)
)
.append($('
'))
var advanced_editor = null;
var advanced_editor_init = function() {
require_codemirror({}, function() {
var mode = get_codemirror_mode('text');
require_codemirror_mode(mode, function() {
if (advanced_editor != null) {
return;
}
advanced_editor = CodeMirror.fromTextArea(input_editor[0], {
mode: mode,
lineNumbers: true,
matchBrackets: true,
lineWrapping: true,
styleActiveLine: true,
indentUnit: 4,
indentWithTabs: true,
theme: 'default'
});
advanced_editor.on('change', function() {
advanced_editor.save();
});
$(advanced_editor.getWrapperElement()).css('box-shadow', '0 2px 10px rgba(0,0,0,0.2)');
advanced_editor.focus();
});
});
}
var save_prefer_upload_type = function(type) {
$.cookie('uoj_text_file_form_group_preferred_upload_type', type, { expires: 7, path: '/' });
};
autosave_locally(2000, name, input_editor);
var prefer_upload_type = $.cookie('uoj_text_file_form_group_preferred_upload_type');
if (prefer_upload_type === null) {
prefer_upload_type = 'editor';
}
if (prefer_upload_type == 'file') {
input_upload_type_file[0].checked = true;
div_editor.css('display', 'none');
} else {
input_upload_type_editor[0].checked = true;
div_file.css('display', 'none');
if (prefer_upload_type == 'advanced') {
input_use_advanced_editor[0].checked = true;
}
}
input_upload_type_editor.click(function() {
div_editor.show('fast');
div_file.hide('fast');
save_prefer_upload_type('editor');
});
input_upload_type_file.click(function() {
div_file.show('fast');
div_editor.hide('fast');
save_prefer_upload_type('file');
});
input_file.change(function() {
input_file_path.val(input_file.val());
});
input_use_advanced_editor.click(function() {
if (this.checked) {
advanced_editor_init();
save_prefer_upload_type('advanced');
} else {
if (advanced_editor != null) {
advanced_editor.toTextArea();
advanced_editor = null;
input_editor.focus();
}
save_prefer_upload_type('editor');
}
});
$(this)
.append($('
'))
.append($('
'))
.append($('
')
.append($('
')
.append(input_upload_type_editor)
.append(' '+uojLocale('editor::upload by editor'))
)
)
.append($('
')
.append($('
')
.append(input_upload_type_file)
.append(' '+uojLocale('editor::upload from local'))
)
)
.append(div_editor)
.append(div_file);
if (prefer_upload_type == 'advanced') {
var check_advanced_init = function() {
if (div_editor.is(':visible')) {
advanced_editor_init();
} else {
setTimeout(check_advanced_init, 1);
}
}
check_advanced_init();
}
});
}
// custom test
function custom_test_onsubmit(response_text, div_result, url) {
if (response_text != '') {
$(div_result).html('
' + response_text + '
');
return;
}
var update = function() {
var can_next = true;
$.get(url,
function(data) {
if (data.judged === undefined) {
$(div_result).html('
error
');
} else {
var judge_status = $('
');
$(div_result).empty();
$(div_result).append(judge_status);
if (data.judged) {
var judge_result = $(data.result);
judge_result.css('display', 'none');
$(div_result).append(judge_result);
judge_status.hide(500);
judge_result.slideDown(500);
can_next = false;
}
}
}, 'json')
.always(function() {
if (can_next) {
setTimeout(update, 500);
}
});
};
setTimeout(update, 500);
}
// comment
function showCommentReplies(id, replies) {
var toggleFormReply = function(from, text) {
if (text == undefined) {
text = '';
}
var p = '#comment-body-' + id;
var q = '#div-form-reply';
var r = '#input-reply_comment';
var t = '#input-reply_id';
if ($(q).data('from') != from) {
$(q).data('from', from);
$(q).hide('fast', function() {
$(this).appendTo(p).show('fast', function() {
$(t).val(id);
$(r).val(text).focus();
});
});
} else if ($(q).css('display') != 'none') {
$(q).appendTo(p).hide('fast');
} else {
$(q).appendTo(p).show('fast', function() {
$(t).val(id);
$(r).val(text).focus();
});
}
}
$('#reply-to-' + id).click(function(e) {
e.preventDefault();
toggleFormReply(id);
});
if (replies.length == 0) {
return;
}
$("#replies-" + id).long_table(
replies,
1,
'
' +
'评论回复 | ' +
'
',
function(reply) {
return $('').append(
$('
| ').append(
$('
' + getUserLink(reply.poster, reply.poster_rating) + ':' + reply.content + '
')
).append(
$('
').append(
'
' + '' + reply.post_time + '' + ''
).append(
$('
').append(
$('
回复').click(function (e) {
e.preventDefault();
toggleFormReply(reply.id, '回复 @' + reply.poster + ':');
})
)
)
)
).uoj_highlight();
}, {
table_classes: ['table', 'table-condensed'],
page_len: 5,
prevent_focus_on_click: true
}
);
}
// standings
function showStandings() {
$("#standings").long_table(
standings,
1,
'
' +
'# | ' +
''+uojLocale('username')+' | ' +
''+uojLocale('contests::total score')+' | ' +
$.map(problems, function(col, idx) {
return '' + '' + String.fromCharCode('A'.charCodeAt(0) + idx) + '' + ' | ';
}).join('') +
'
',
function(row) {
var col_tr = '
';
col_tr += '' + row[3] + ' | ';
col_tr += '' + getUserLink(row[2][0], row[2][1]) + ' | ';
col_tr += '' + ' ' + row[0] + ' ' + '' + getPenaltyTimeStr(row[1]) + ' | ';
for (var i = 0; i < problems.length; i++) {
col_tr += '';
col = score[row[2][0]][i];
if (col != undefined) {
col_tr += '';
if (standings_version < 2) {
col_tr += ' ' + getPenaltyTimeStr(col[1]) + ' ';
} else {
if (col[0] > 0) {
col_tr += '' + getPenaltyTimeStr(col[1]) + ' ';
}
}
}
col_tr += ' | ';
}
col_tr += '
';
return col_tr;
}, {
table_classes: ['table', 'table-bordered', 'table-striped', 'table-text-center', 'table-vertical-middle', 'table-condensed'],
page_len: 100,
print_after_table: function() {
return '
' + uojLocale("contests::n participants", standings.length) + '
';
}
}
);
}