Files
hustoj/web/template/syzoj/reinfo.php
klarkxy c22c788cfa feat(ui): 判题结果页新增输出对比视图
- 新增 parse_diff_blocks 系列函数,将 runtimeinfo 解析为结构化的测试点对比块,支持 simple 表格和 diff -y 两种格式
- 在判题结果页插入"输出对比"区块,逐测试点并列展示期望输出与用户输出,差异行高亮
- 补充 diff-section 相关样式,移动端切换为单列布局
2026-07-08 21:13:13 +08:00

730 lines
27 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php $show_title=$id." - $MSG_ERROR_INFO - $OJ_NAME"; ?>
<?php include("template/$OJ_TEMPLATE/header.php");?>
<script src="include/vditor-adapter.js"></script>
<script src="template/<?php echo $OJ_TEMPLATE?>/js/textFit.min.js"></script>
<style>
.single-subtask {
box-shadow: none !important;
}
.single-subtask > .title {
display: none;
}
.single-subtask > .content {
padding: 0 !important;
}
.accordion > .content > .accordion {
margin-top: 0;
margin-bottom: 0;
}
.accordion > .content > .accordion > .content {
margin-top: 0;
margin-bottom: 14px;
}
.accordion > .content > .accordion > .content > :last-child {
margin-bottom: -10px !important;
}
/* === reinfo 友好化样式 === */
#result-banner {
margin-bottom: 18px;
border-left: 5px solid;
}
#result-banner.green { border-left-color: #21ba45; }
#result-banner.red { border-left-color: #db2828; }
#result-banner.yellow{ border-left-color: #fbbd08; }
#result-banner.blue { border-left-color: #2185d0; }
#result-banner.grey { border-left-color: #767676; }
#result-banner h2.ui.header {
margin: 0;
}
#result-banner .verdict-stats {
margin-top: 6px;
font-size: 0.95em;
color: rgba(0,0,0,0.6);
}
#result-banner .verdict-stats .stat {
margin-right: 16px;
}
#result-banner .verdict-stats i.icon {
margin-right: 4px;
}
#verdict-tip {
margin-bottom: 18px;
font-size: 1.05em;
padding: 8px 12px;
background: rgba(33,150,243,0.08);
border-radius: 6px;
border-left: 3px solid #2185d0;
}
#raw-info-accordion {
margin-bottom: 18px;
}
#raw-info-accordion > .content {
padding: 8px 14px;
}
#raw-info-accordion pre#errtxt {
margin: 0;
padding: 12px;
background: #f7f7f9;
border-radius: 4px;
font-family: 'Fira Mono', 'Cascadia Code', Consolas, monospace;
font-size: 0.9em;
white-space: pre-wrap;
word-break: break-all;
}
#raw-info-accordion .title .dedup-label {
margin-left: 8px;
}
#raw-info-accordion .empty-notice {
color: #999;
font-style: italic;
}
.quick-actions {
text-align: center;
margin-top: 24px;
margin-bottom: 12px;
}
.quick-actions .ui.buttons {
box-shadow: none;
}
/* AI 点评区 */
#llm-section {
margin-top: 20px;
margin-bottom: 18px;
}
#llm-section .ui.header {
margin-top: 0;
}
#llm-section .llm-section-header {
transition: background-color 0.15s;
padding: 4px 8px;
margin-left: -8px;
margin-right: -8px;
border-radius: 4px;
}
#llm-section .llm-section-header:hover {
background-color: rgba(33,150,243,0.06);
}
#llm-section .llm-toggle-icon {
transition: transform 0.2s;
color: #888;
}
#llm-review-result {
word-break: break-word;
}
/* 错误解释列表(由 JS explain() 填充) - 已弃用,由 AI 点评替代 */
/* 自动刷新状态 */
i.icon.spinning {
animation: spin 1.2s linear infinite;
}
@keyframes spin {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
#auto-refresh-status {
color: #2185d0;
font-weight: 600;
}
/* Diff 对比样式 */
#diff-section {
margin-bottom: 18px;
}
.diff-card {
margin-bottom: 14px;
border-left: 4px solid #fbbd08;
padding: 12px 16px;
}
.diff-header {
display: flex;
align-items: center;
gap: 6px;
margin-bottom: 10px;
padding-bottom: 8px;
border-bottom: 1px solid #eee;
font-weight: 600;
color: #555;
}
.diff-name {
font-family: 'Fira Mono', 'Cascadia Code', Consolas, monospace;
font-size: 0.95em;
}
.diff-table {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 12px;
}
@media (max-width: 768px) {
.diff-table { grid-template-columns: 1fr; }
}
.diff-side {
background: #fafafa;
border-radius: 6px;
overflow: hidden;
border: 1px solid #e0e0e0;
}
.diff-side-header {
padding: 6px 10px;
font-size: 0.85em;
font-weight: 600;
color: #fff;
}
.diff-expected .diff-side-header {
background: #21ba45;
}
.diff-yours .diff-side-header {
background: #db2828;
}
.diff-content {
margin: 0 !important;
padding: 8px 0 !important;
background: #fff !important;
font-family: 'Fira Mono', 'Cascadia Code', Consolas, monospace;
font-size: 0.85em;
line-height: 1.5;
overflow-x: auto;
max-height: 400px;
overflow-y: auto;
}
.diff-line {
display: flex;
align-items: flex-start;
padding: 0;
white-space: pre;
}
.diff-line-mismatch {
background: rgba(255, 230, 100, 0.25);
}
.diff-expected .diff-line-mismatch {
background: rgba(33, 186, 69, 0.12);
}
.diff-yours .diff-line-mismatch {
background: rgba(219, 40, 40, 0.10);
}
.diff-lineno {
display: inline-block;
min-width: 38px;
padding: 0 8px;
text-align: right;
color: #999;
background: #f5f5f5;
border-right: 1px solid #e8e8e8;
user-select: none;
flex-shrink: 0;
}
.diff-text {
padding: 0 10px;
flex: 1;
word-break: break-all;
white-space: pre-wrap;
}
</style>
<div class="padding">
<?php
// 兼容老变量:$row 是 solution 行reinfo.php 已查询过)
$verdict_name = isset($judge_result[$row['result']]) ? $judge_result[$row['result']] : (isset($MSG_UNKNOWN) ? $MSG_UNKNOWN : 'Unknown');
$verdict_lang = isset($language_name[$lang]) ? $language_name[$lang] : '?';
$verdict_memory = isset($row['memory']) ? intval($row['memory']) : 0;
$verdict_time = isset($row['time']) ? intval($row['time']) : 0;
$verdict_mark = isset($mark) ? $mark : (isset($row['pass_rate']) ? round($row['pass_rate']*100, 1) : 0);
// 兜底:防止 PHP notice
$diff_blocks = isset($diff_blocks) && is_array($diff_blocks) ? $diff_blocks : array();
?>
<!-- 1. 顶部判题结果横幅 -->
<div class="ui segment <?php echo isset($verdict_color_class) ? $verdict_color_class : 'blue'; ?>" id="result-banner">
<h2 class="ui header">
<i class="<?php echo isset($result_icon) ? $result_icon : 'info circle' ?> icon" style="color: inherit;"></i>
<div class="content">
<?php echo htmlspecialchars($verdict_name, ENT_QUOTES, 'UTF-8') ?>
<div class="verdict-stats">
<span class="stat"><i class="chart bar icon"></i><?php echo $MSG_MARK ?>: <?php echo $verdict_mark ?>%</span>
<span class="stat"><i class="microchip icon"></i><?php echo $verdict_memory ?> KB</span>
<span class="stat"><i class="clock icon"></i><?php echo $verdict_time ?> ms</span>
<span class="stat"><i class="code icon"></i><?php echo htmlspecialchars($verdict_lang, ENT_QUOTES, 'UTF-8') ?></span>
<span class="stat" id="auto-refresh-status" style="display:none;">
<i class="refresh icon spinning"></i> <span id="auto-refresh-text"></span>
</span>
</div>
</div>
</h2>
</div>
<!-- 2. 判题结果标题提示(仅一句话,具体修复建议交给 AI -->
<div class="ui info message" id="verdict-tip">
<i class="info circle icon"></i>
<?php echo isset($verdict_tip) ? htmlspecialchars($verdict_tip, ENT_QUOTES, 'UTF-8') : ''; ?>
</div>
<!-- 3. AI 点评区(标题可点击折叠/展开) -->
<?php if (isset($OJ_LLM_ENABLED) && $OJ_LLM_ENABLED) { ?>
<div class="ui raised segment" id="llm-section">
<h3 class="ui header llm-section-header" id="llm-toggle" style="cursor: pointer; user-select: none;">
<i class="magic icon"></i>
<div class="content">
AI 智能点评
<div class="sub header"><?php echo isset($MSG_AI_REVIEW_DESC) ? $MSG_AI_REVIEW_DESC : '基于你的代码和判题结果分析'; ?></div>
</div>
<i class="dropdown icon llm-toggle-icon" style="margin-left: auto; font-size: 1em;"></i>
</h3>
<div id="llm-section-body">
<button class="ui labeled icon primary button" id="llm-review-btn" onclick="fetchLLMReview()">
<i class="magic icon"></i> 获取 AI 点评
</button>
<div id="llm-review-loading" class="ui active inline text loader" style="display:none; margin-left: 1em;">
AI 正在分析你的代码,请稍候...
</div>
<div id="llm-review-result" style="display:none; margin-top: 15px;">
<div class="ui existing segment" id="llm-review-content"></div>
</div>
<div id="llm-review-error" style="display:none; margin-top: 15px;">
<div class="ui negative message">
<p id="llm-review-error-msg"></p>
</div>
</div>
</div>
</div>
<script>
// 折叠/展开 AI 点评区
(function(){
var header = document.getElementById('llm-toggle');
var body = document.getElementById('llm-section-body');
var icon = header ? header.querySelector('.llm-toggle-icon') : null;
if (!header || !body) return;
header.addEventListener('click', function(e){
// 如果用户点击的是按钮本身,不要触发展开(按钮事件自己处理)
if (e.target.closest('button')) return;
var collapsed = body.style.display === 'none';
body.style.display = collapsed ? '' : 'none';
if (icon) {
icon.className = collapsed
? 'dropdown icon llm-toggle-icon'
: 'dropdown icon llm-toggle-icon active';
// active class 让 Semantic UI 的箭头自动旋转 90°但我们手写也行
icon.style.transform = collapsed ? 'rotate(0deg)' : 'rotate(-90deg)';
}
});
})();
function fetchLLMReview(){
var btn = $('#llm-review-btn');
btn.prop('disabled', true).addClass('loading');
$('#llm-review-loading').show();
$('#llm-review-error').hide();
$('#llm-review-result').hide();
var fullText = "";
var container = document.getElementById('llm-review-content');
var resultDiv = document.getElementById('llm-review-result');
var reader = null;
var decoder = new TextDecoder();
var sseBuffer = "";
function processSSE(text) {
sseBuffer += text;
var lines = sseBuffer.split('\n');
sseBuffer = lines.pop();
var currentEvent = "";
for (var i = 0; i < lines.length; i++) {
var line = lines[i];
if (line.indexOf('event: ') === 0) {
currentEvent = line.substring(7);
} else if (line.indexOf('data: ') === 0) {
var dataStr = line.substring(6);
try {
var data = JSON.parse(dataStr);
if (currentEvent === 'chunk') {
fullText += data.text;
container.textContent = fullText;
resultDiv.style.display = 'block';
} else if (currentEvent === 'cached') {
fullText = data.text;
container.textContent = fullText;
resultDiv.style.display = 'block';
} else if (currentEvent === 'done') {
finishReview();
} else if (currentEvent === 'error') {
showError(data.message || '未知错误');
}
} catch(e) {}
currentEvent = "";
}
}
}
function finishReview() {
btn.removeClass('loading').hide();
document.getElementById('llm-review-loading').style.display = 'none';
resultDiv.style.display = 'block';
if (fullText && typeof HustOJVditor !== 'undefined' && HustOJVditor.renderMarkdownBlocks) {
HustOJVditor.renderMarkdownBlocks('#llm-review-content', { useTextContent: true });
}
}
function showError(msg) {
btn.removeClass('loading').prop('disabled', false);
document.getElementById('llm-review-loading').style.display = 'none';
document.getElementById('llm-review-error-msg').textContent = msg;
document.getElementById('llm-review-error').style.display = 'block';
}
if (typeof fetch === 'undefined') {
showError('浏览器不支持,请升级浏览器');
return;
}
fetch('llm-review.php?sid=<?php echo intval($id); ?>')
.then(function(response) {
if (!response.ok) {
return response.text().then(function(text) {
try {
var d = JSON.parse(text);
showError(d.error || '请求失败 (HTTP ' + response.status + ')');
} catch(e) {
showError('请求失败 (HTTP ' + response.status + ')');
}
});
}
reader = response.body.getReader();
function read() {
reader.read().then(function(result) {
if (result.done) {
if (fullText) finishReview();
return;
}
var text = decoder.decode(result.value, { stream: true });
processSSE(text);
read();
}).catch(function(err) {
if (fullText) {
finishReview();
} else {
showError('读取响应失败: ' + err.message);
}
});
}
read();
})
.catch(function(err) {
showError('网络请求失败: ' + err.message);
});
}
</script>
<?php } ?>
<!-- 3.5. 对比详情WA/PE 时显示diff 视图) -->
<?php if (!empty($diff_blocks) && is_array($diff_blocks)): ?>
<div id="diff-section">
<h3 class="ui header" style="margin-top: 0;">
<i class="exchange icon"></i>
<div class="content">
输出对比
<div class="sub header">逐测试点对比期望输出和你的输出</div>
</div>
</h3>
<?php foreach ($diff_blocks as $idx => $block): ?>
<div class="ui segment diff-card">
<div class="diff-header">
<i class="file outline icon"></i>
<span class="diff-name"><?php echo htmlspecialchars($block['name'], ENT_QUOTES, 'UTF-8'); ?></span>
</div>
<div class="diff-table">
<div class="diff-side diff-expected">
<div class="diff-side-header">
<i class="check icon"></i> 期望输出
</div>
<pre class="diff-content"><?php
$max = max(count($block['expected']), count($block['yours']));
$lines_html = array();
for ($li = 0; $li < $max; $li++) {
$e = isset($block['expected'][$li]) ? $block['expected'][$li] : '';
$y = isset($block['yours'][$li]) ? $block['yours'][$li] : '';
$diff_class = ($e !== $y) ? ' diff-line-mismatch' : '';
$line_no = $li + 1;
$lines_html[] = '<div class="diff-line' . $diff_class . '" data-line="' . $line_no . '"><span class="diff-lineno">' . $line_no . '</span><span class="diff-text">' . htmlspecialchars($e, ENT_QUOTES, 'UTF-8') . '</span></div>';
}
echo implode('', $lines_html);
?></pre>
</div>
<div class="diff-side diff-yours">
<div class="diff-side-header">
<i class="bug icon"></i> 你的输出
</div>
<pre class="diff-content"><?php
$max = max(count($block['expected']), count($block['yours']));
$lines_html = array();
for ($li = 0; $li < $max; $li++) {
$e = isset($block['expected'][$li]) ? $block['expected'][$li] : '';
$y = isset($block['yours'][$li]) ? $block['yours'][$li] : '';
$diff_class = ($e !== $y) ? ' diff-line-mismatch' : '';
$line_no = $li + 1;
$lines_html[] = '<div class="diff-line' . $diff_class . '" data-line="' . $line_no . '"><span class="diff-lineno">' . $line_no . '</span><span class="diff-text">' . htmlspecialchars($y, ENT_QUOTES, 'UTF-8') . '</span></div>';
}
echo implode('', $lines_html);
?></pre>
</div>
</div>
</div>
<?php endforeach; ?>
</div>
<?php endif; ?>
<!-- 4. 原始错误折叠(默认收起) -->
<div class="ui styled accordion" id="raw-info-accordion">
<div class="title">
<i class="dropdown icon"></i>
<?php echo isset($MSG_RAW_ERROR) ? $MSG_RAW_ERROR : '查看原始错误信息'; ?>
<?php if (!empty($view_reinfo_dedup_count)): ?>
<span class="ui tiny teal label dedup-label">
<?php echo sprintf(isset($MSG_DEDUP_HINT) ? $MSG_DEDUP_HINT : '已折叠 %d 个相同测试点', intval($view_reinfo_dedup_count)); ?>
</span>
<?php endif; ?>
<?php if (trim($view_reinfo) === ''): ?>
<span class="dedup-label empty-notice">(无)</span>
<?php endif; ?>
</div>
<div class="content">
<?php if (trim($view_reinfo) === ''): ?>
<p class="empty-notice">当前判题结果没有原始错误信息(如 TLE/MLE 通常不会写 runtimeinfo。</p>
<?php else: ?>
<pre id="errtxt"><?php
// 普通用户:折叠后;管理员/源浏览者:原文
if (isset($is_admin_session) && $is_admin_session) {
echo htmlspecialchars($view_reinfo_raw, ENT_QUOTES, 'UTF-8');
} elseif (isset($is_source_browser) && $is_source_browser) {
echo htmlspecialchars($view_reinfo_raw, ENT_QUOTES, 'UTF-8');
} else {
echo htmlspecialchars($view_reinfo, ENT_QUOTES, 'UTF-8');
}
?></pre>
<?php endif; ?>
</div>
</div>
<!-- 5. 快捷操作区 -->
<div class="quick-actions">
<div class="ui horizontal divider">
<?php echo isset($MSG_QUICK_ACTIONS) ? $MSG_QUICK_ACTIONS : '快捷操作'; ?>
</div>
<div class="ui buttons">
<a class="ui blue button" href="submitpage.php?id=<?php echo intval($row['problem_id']) ?>">
<i class="edit icon"></i> <?php echo isset($MSG_RESUBMIT) ? $MSG_RESUBMIT : '重新提交'; ?>
</a>
<a class="ui button" href="showsource.php?id=<?php echo intval($id) ?>">
<i class="code icon"></i> <?php echo isset($MSG_VIEW_SOURCE) ? $MSG_VIEW_SOURCE : '查看我的代码'; ?>
</a>
<a class="ui button" href="problem.php?id=<?php echo intval($row['problem_id']) ?>">
<i class="info circle icon"></i> <?php echo isset($MSG_VIEW_PROBLEM) ? $MSG_VIEW_PROBLEM : '查看题目'; ?>
</a>
</div>
</div>
</div>
<?php if(isset($OJ_MARKDOWN) && $OJ_MARKDOWN){ ?>
<script>
$(document).ready(function(){
// 初始化折叠面板
$('#raw-info-accordion').accordion();
// 管理员/superuser 默认展开原始错误
<?php if (isset($is_admin_session) && $is_admin_session) { ?>
$('#raw-info-accordion').accordion('open', 0);
<?php } elseif (isset($is_source_browser) && $is_source_browser) { ?>
$('#raw-info-accordion').accordion('open', 0);
<?php } ?>
HustOJVditor.renderMarkdownBlocks('#errtxt', {
getSource: function (element) {
var pre = element.querySelector ? element.querySelector('pre') : null;
return pre ? pre.textContent : element.textContent || '';
}
}).then(function () {
for(let i=1;i<10;i++){
$(".language-input"+i).parent().before("<div><?php echo $MSG_Input?>"+i+":</div>");
$(".language-output"+i).parent().before("<div><?php echo $MSG_Output?>"+i+":</div>");
}
$("#errtxt table").addClass("ui mini-table cell striped");
$("#errtxt table tr:odd td").css({
"border": "1px solid grey",
"text-align": "center",
"width": "200px",
"background-color": "#8521d022",
"height": "30px"
});
$("#errtxt table tr:even td").css({
"border": "1px solid grey",
"text-align": "center",
"width": "200px",
"background-color": "#2185d022",
"height": "30px"
});
$("#errtxt table th").css({
"border": "1px solid grey",
"width": "200px",
"height": "30px",
"background-color": "#2185d088",
"text-align": "center"
});
<?php
if(isset($OJ_DOWNLOAD) && $OJ_DOWNLOAD){
if(isset($OJ_DL_1ST_WA_ONLY) && $OJ_DL_1ST_WA_ONLY){
?>
let down=$($("#errtxt").find("h2")[0]);
let filename=down.text();
down.html("<a href='download.php?sid=<?php echo $id?>&name=" + filename+ "'>" + filename+ "</a>");
<?php
}else{
?>
$("#errtxt").find("h2").each(function(){
let down=$(this);
let filename=down.text();
console.log(filename);
down.html("<a href='download.php?sid=<?php echo $id?>&name=" + filename+ "'>" + filename+ "</a>");
});
<?php
}
}
?>
$("th").each(function(){
let html=$(this).html();
html=html.replace("Expected","<?php echo $MSG_EXPECTED ?>");
html=html.replace("Yours","<?php echo $MSG_YOURS ?>");
html=html.replace("filename","<?php echo $MSG_FILENAME ?>");
html=html.replace("size","<?php echo $MSG_SIZE ?>");
html=html.replace("result","<?php echo $MSG_RESULT ?>");
html=html.replace("memory","<?php echo $MSG_MEMORY?>");
html=html.replace("time","<?php echo $MSG_TIME ?>");
$(this).html(html);
});
}).catch(function (error) {
console.error('Failed to render reinfo markdown.', error);
});
});
</script>
<?php } else { ?>
<script>
// OJ_MARKDOWN 未开启时也要初始化折叠
$(document).ready(function(){
$('#raw-info-accordion').accordion();
<?php if (isset($is_admin_session) && $is_admin_session) { ?>
$('#raw-info-accordion').accordion('open', 0);
<?php } elseif (isset($is_source_browser) && $is_source_browser) { ?>
$('#raw-info-accordion').accordion('open', 0);
<?php } ?>
});
</script>
<?php } ?>
<!-- 自动刷新判题中result < 4 或 > 14时定时拉取最新状态 -->
<?php
$result_code_js = isset($row['result']) ? intval($row['result']) : 4;
$sid_js = isset($id) ? intval($id) : 0;
// 0=Pending, 1=Pending Rejudging, 2=Compiling, 3=Running/Judging, 14=Manual, 15=Submitting, 16/17=Remote
$is_pending = ($result_code_js < 4) || ($result_code_js > 14);
?>
<?php if ($sid_js > 0 && $is_pending): ?>
<script>
(function(){
var sid = <?php echo $sid_js ?>;
var currentResult = <?php echo $result_code_js ?>;
var interval = 1500; // 初始 1.5s
var maxInterval = 8000; // 最长 8s
var countdown = 0;
var stopped = false;
function showStatus(text){
var el = document.getElementById('auto-refresh-status');
var t = document.getElementById('auto-refresh-text');
if (el && t) {
el.style.display = '';
t.textContent = text;
}
}
function hideStatus(){
var el = document.getElementById('auto-refresh-status');
if (el) el.style.display = 'none';
}
function tick(){
if (stopped) return;
countdown--;
if (countdown > 0) {
showStatus('将在 ' + countdown + ' 秒后自动刷新');
setTimeout(tick, 1000);
return;
}
fetch('status-ajax.php?solution_id=' + sid + '&t=json', {credentials: 'same-origin'})
.then(function(r){ return r.json(); })
.then(function(data){
if (!data || typeof data.result === 'undefined') {
// 解析失败,下次重试
interval = Math.min(interval * 1.5, maxInterval);
countdown = Math.ceil(interval / 1000);
tick();
return;
}
var newResult = parseInt(data.result);
if (newResult >= 4 && newResult <= 14) {
// 判题完成,刷新页面拿到完整错误信息
showStatus('判题完成,正在刷新...');
setTimeout(function(){ location.reload(); }, 400);
stopped = true;
return;
}
// 仍在评判中
interval = Math.min(interval * 1.3, maxInterval);
countdown = Math.ceil(interval / 1000);
showStatus('判题中,将在 ' + countdown + ' 秒后再次查询');
setTimeout(tick, 1000);
})
.catch(function(err){
// 网络错误,重试
console.warn('auto refresh failed:', err);
interval = Math.min(interval * 1.5, maxInterval);
countdown = Math.ceil(interval / 1000);
showStatus('查询失败,' + countdown + ' 秒后重试');
setTimeout(tick, 1000);
});
}
// 用户切到后台标签时停止轮询,避免无意义请求
document.addEventListener('visibilitychange', function(){
if (document.hidden) {
stopped = true;
hideStatus();
} else if (!stopped) {
countdown = 0;
tick();
}
});
// 启动
countdown = Math.ceil(interval / 1000);
showStatus('判题中,将在 ' + countdown + ' 秒后自动刷新');
setTimeout(tick, 1000);
})();
</script>
<?php endif; ?>
<?php include("template/$OJ_TEMPLATE/footer.php");?>