Domjudge-UI-for-Codeforces

For ICPC competitors practicing for the DOMjudge UI in codeforces.

You will need to install an extension such as Tampermonkey, Greasemonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Userscripts to install this script.

You will need to install an extension such as Tampermonkey to install this script.

You will need to install a user script manager extension to install this script.

(I already have a user script manager, let me install it!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(I already have a user style manager, let me install it!)

// ==UserScript==
// @name         Domjudge-UI-for-Codeforces
// @namespace    http://tampermonkey.net/
// @version      0.1.0
// @license      MIT
// @description  For ICPC competitors practicing for the DOMjudge UI in codeforces.
// @author       jakao
// @match        https://codeforces.com/gym/*/submit*
// @match        https://codeforces.com/contest/*/submit*
// @icon         https://i.imgur.com/RwGYTmF.png
// @grant        GM_addStyle
// ==/UserScript==

const css = `
.summary-table {
    text-align: center;
}
table {
    width: 100%;
    border-collapse: collapse;
}
.score-penalty-table {
    display: flex;
    align-items: center;
}
.score-penalty-table > div {
    flex: 1;
    padding: 5px;
    border-right: 1px solid #ccc; /* Optional border for visual separation */
}
.score-penalty-table > div:first-child {
    border-right: 1px solid transparent; /* Transparent border between left and right */
}
.badge {
    display: inline-block;
    padding: .25em .4em;
    font-size: 75%;
    font-weight: 700;
    line-height: 1;
    text-align: center;
    white-space: nowrap;
    vertical-align: baseline;
    border-radius: .25rem;
    transition: color .15s ease-in-out, background-color .15s ease-in-out, border-color .15s ease-in-out, box-shadow .15s ease-in-out;
}
.problem-badge {
    font-size: 100%;
}
td.score_cell {
    min-width: 4.2em;
    padding: 2px 1px 2px 1px;
    border-right: none;
}
.summary-table td.score_cell {
    min-width: 4.2em;
    border-right: none;
}
thead {
    display: table-header-group;
    vertical-align: middle;
    unicode-bidi: isolate;
    border-color: inherit;
}
.sortorderswitch {
    border-top: 2px solid black;
}
.summary-table {
    margin-top: 2.5em;
}
.summary-table a {
    display: block;
    padding: 2px 1px 2px 1px;
    text-decoration: none;
    color: black;
}
.scorenc, .scorett, .scorepl {
    text-align: center;
    width: 2ex;
}
.scorenc {
    font-weight: bold;
}
.summary-table .scoreaf { white-space: nowrap; border: 0; text-align: center; }
.summary-table tr {
    border-bottom: 1px solid black;
    border-bottom-width: 1px;
    border-bottom-style: solid;
    border-bottom-color: black;
    height: 42px;
}
.summary-table .scoretn {
    padding: 0px 5px 0px;
    text-align: right;
    font-weight: bold;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.summary-table td, .summary-table th {
    border-right: 1px solid silver;
    padding: 0px;
}
.summary-table-header {
    font-variant: small-caps;
    border-bottom: 2px solid black;
    white-space: nowrap;
}
.summary-table-header th{
    text-align: center;
    box-shadow: -1px 0px 0px 0px silver inset, 0px 2px 0px 0px black;
    border: none;
    background: var(--background-color);
    position: sticky;
    top: 0px;
    z-index: 1;
}
col {
    display: table-column;
    unicode-bidi: isolate;
}
colgroup {
    display: table-column-group;
    unicode-bidi: isolate;
}
.summary-table td {
    font-size: small;
    vertical-align: middle;
    text-align: center;
}
.summary-table td div {
    width: 4em;
    font-size: 120%;
    display: inline-block;
}
.summary-table td div span {
    font-weight: normal;
    font-size: 70%;
    display: block;
}
.summary-table th {
    text-align: center;
    box-shadow: -1px 0px 0px 0px silver inset, 0px 2px 0px 0px black;
    border: none;
    background: var(--background-color);
    position: sticky;
    top: 0px;
    z-index: 1;
}
td.scorenc {
    border-color: silver;
    border-right: 0;
}
*, ::after, ::before {
    box-sizing: border-box;
}
.row {
    display: -ms-flexbox;
    display: flex;
    -ms-flex-wrap: wrap;
    flex-wrap: wrap;
    margin-right: -15px;
    margin-left: -15px;
}
.col {
    -ms-flex-preferred-size: 0;
    flex-basis: 0;
    -ms-flex-positive: 1;
    flex-grow: 1;
    max-width: 100%;
}
.teamoverview {
    border-top: solid 1px darkgray;
    border-bottom: solid 1px darkgray;
    background-color: #c4d8ff;
    margin-top: 2ex;
    padding-left: 1ex;
    font-size: 1.17em;
    text-align: center;
}
.h1, .h2, .h3, .h4, .h5, .h6, h1, h2, h3, h4, h5, h6 {
    margin-bottom: .5rem;
    font-weight: 500 !important;
    line-height: 1.2;
}
h1 {
    display: block !important;
    font-size: 2em;
    margin-block-start: 0.67em !important;
    margin-block-end: 0.67em !important;
    margin-inline-start: 0px !important;
    margin-inline-end: 0px !important;
    font-weight: bold;
    unicode-bidi: isolate !important;
}
.data-table tr {
    border-bottom: 1px solid silver;
}
.table td, .table th {
    padding: .75rem;
    vertical-align: top;
    border-top: 1px solid #dee2e6;
}
.table-sm td, .table-sm th {
    padding: .3rem;
}
.table thead th {
    vertical-align: bottom;
    border-bottom: 2px solid #dee2e6;
}
.table .thead-light th {
    color: #495057;
    background-color: #e9ecef;
    border-color: #dee2e6;
}
table {
    border-collapse: collapse;
}
.table {
    width: 100%;
    margin-bottom: 1rem;
    color: #212529;
}
th {
    display: table-cell;
    vertical-align: inherit;
    font-weight: bold !important;
    text-align: -internal-center;
    unicode-bidi: isolate;
}
.sol {
    font-weight: bold;
    font-variant: small-caps;
}
.sol_queued {
    color: gray;
}
.sol_incorrect, .compile-unsuccessful {
    color: red;
}
.sol_correct, .compile-successful {
    color: green;
}
.probid, .langid {
    font-variant: small-caps;
}
.data-table td a, .data-table td a:hover {
    display: block;
    text-decoration: none;
    color: inherit;
    padding: 3px 5px;
}
.table-striped tbody tr:nth-of-type(odd) {
    background-color: rgba(0, 0, 0, .05);
}
body {
    color: var(--text-color);
    background-color: var(--background-color);
    font-family: Roboto, sans-serif !important;
    padding-bottom: 4em;
    padding-top: 4.5rem;
}

div {
    display: block;
    unicode-bidi: isolate;
}
.navbar-collapse {
    -ms-flex-preferred-size: 100%;
    flex-basis: 100%;
    -ms-flex-positive: 1;
    flex-grow: 1;
    -ms-flex-align: center;
    align-items: center;
}
ul {
    display: block;
    list-style-type: disc;
    margin-block-start: 1em;
    margin-block-end: 1em;
    margin-inline-start: 0px;
    margin-inline-end: 0px;
    padding-inline-start: 40px;
    unicode-bidi: isolate;
}
dl, ol, ul {
    margin-top: 0;
    margin-bottom: 1rem;
}
.mr-auto, .mx-auto {
    margin-right: auto !important;
}
.navbar-nav {
    display: -ms-flexbox;
    display: flex;
    -ms-flex-direction: column;
    flex-direction: row;
    padding-left: 0;
    margin-bottom: 0;
    list-style: none;
}
li {
    display: list-item;
    text-align: -webkit-match-parent;
    unicode-bidi: isolate;
}
#menuDefault ul li.nav-item {
    white-space: nowrap;
    white-space-collapse: collapse;
    text-wrap: nowrap;
}
#menuDefault {
    display: flex;
}
.nav-link {
    display: block;
    padding: .5rem 1rem;
}
.navbar-dark .navbar-nav .active>.nav-link, .navbar-dark .navbar-nav .nav-link.active, .navbar-dark .navbar-nav .nav-link.show, .navbar-dark .navbar-nav .show>.nav-link {
    color: #fff !important;
}
.navbar-dark .navbar-nav .nav-link {
    color: #FFFFFF80 !important;
    font-size: 16px;
}
.fa, .fa-brands, .fa-classic, .fa-regular, .fa-sharp, .fa-solid, .fab, .far, .fas {
    -moz-osx-font-smoothing: grayscale;
    -webkit-font-smoothing: antialiased;
    display: var(--fa-display, inline-block);
    font-style: normal;
    font-variant: normal;
    line-height: 1;
    text-rendering: auto;
}
.fa-classic, .fa-regular, .fa-solid, .far, .fas {
    font-family: "Font Awesome 6 Free";
}
.fa-solid, .fas {
    font-weight: 900;
}
a {
    color: #007bff;
    text-decoration: none;
    background-color: transparent;
}
.navbar-brand {
    display: inline-block;
    padding-top: .3125rem;
    padding-bottom: .3125rem;
    margin-right: 1rem;
    /* font-size: 1.25rem; */
    font-size: 20px !important;
    line-height: inherit;
    white-space: nowrap;
}
.navbar-dark .navbar-brand {
    color: #fff;
}
.navbar-dark .navbar-text {
    color: rgba(255, 255, 255, .5);
    font-size: 16px;
}
.navbar-text {
    display: inline-block;
    padding-top: .5rem;
    padding-bottom: .5rem;
}
nav {
    display: block;
    unicode-bidi: isolate;
}
.navbar {
    position: relative;
    justify-content: space-between;
    -ms-flex-pack: justify;
    -ms-flex-wrap: wrap;
    -ms-flex-align: center;
    align-items: center;
    flex-direction: row;
    display: flex;
    display: -ms-flexbox;
    padding-top: 8px;
    padding-right: 16px;
    padding-bottom: 8px;
    padding-left: 16px;
}
.bg-dark {
    background-color: #343a40 !important;
}
.fixed-top {
    position: fixed;
    top: 0;
    right: 0;
    left: 0;
    z-index: 1030;
}

/* submit button */
.justify-content-center {
    -ms-flex-pack: center !important;
    justify-content: center !important;
}
.btn {
    display: inline-block;
    font-weight: 400;
    color: #212529;
    text-align: center;
    vertical-align: middle;
    -webkit-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
    user-select: none;
    background-color: transparent;
    border: 1px solid transparent;
    padding: 6px 12px;
    font-size: 16px;
    line-height: 1.5;
    border-radius: .25rem;
    transition: color .15s ease-in-out, background-color .15s ease-in-out, border-color .15s ease-in-out, box-shadow .15s ease-in-out;
}
.btn:not(:disabled):not(.disabled) {
    cursor: pointer;
}
.btn-success {
    color: #fff !important;
    background: #0a8927 !important;
}
.btn-info {
    color: #fff !important;
    background-color: #17a2b8  !important;
}
.score_pending {
    background: #6666FF !important;
}
.btn-secondary {
    color: #fff;
    background-color: #6c757d;
    border-color: #6c757d;
}
.modal-footer>* {
    margin: .25rem;
}
.btn-group-sm>.btn, .btn-sm {
    padding: .25rem .5rem;
    font-size: 14px;
    line-height: 1.5;
    border-radius: .2rem;
}
.modal-header {
    display: -ms-flexbox;
    display: flex;
    -ms-flex-align: start;
    align-items: flex-start;
    -ms-flex-pack: justify;
    justify-content: space-between;
    padding: 1rem 1rem;
    border-bottom: 1px solid #dee2e6;
    border-top-left-radius: calc(.3rem - 1px);
    border-top-right-radius: calc(.3rem - 1px);
}
.modal-title {
    margin-bottom: 0;
    line-height: 1.5;
}
.modal-header .close {
    padding: 1rem 1rem;
    margin: -1rem -1rem -1rem auto;
}
button.close {
    padding: 0;
    background-color: transparent;
    border: 0;
}
.close {
    float: right;
    font-size: 1.5rem;
    font-weight: 700;
    line-height: 1;
    color: #000;
    text-shadow: 0 1px 0 #fff;
    opacity: .5;
}
[type=button], [type=reset], [type=submit], button {
    -webkit-appearance: button;
}
button, select {
    text-transform: none;
}

button, input {
    overflow: visible;
}
button, input, optgroup, select, textarea {
    margin: 0;
    font-family: inherit;
    font-size: inherit;
    line-height: inherit;
}
button {
    border-radius: 0;
}

.close {
    color: #aaa;
    float: right;
    font-size: 28px;
    font-weight: bold;
}
.close:hover,
.close:focus {
    color: black;
    text-decoration: none;
    cursor: pointer;
}
.modal-open .modal {
    overflow-x: hidden;
    overflow-y: auto;
}
.modal {
    position: fixed;
    top: 0;
    left: 0;
    z-index: 1050;
    display: none;
    width: 100%;
    height: 100%;
    overflow: hidden;
    outline: 0;
}
.fade {
    transition: opacity .15s linear;
}
.modal-header {
    display: -ms-flexbox;
    display: flex;
    -ms-flex-align: start;
    align-items: flex-start;
    -ms-flex-pack: justify;
    justify-content: space-between;
    padding: 16px 16px;
    border-bottom: 1px solid #dee2e6;
    border-top-left-radius: calc(.3rem - 1px);
    border-top-right-radius: calc(.3rem - 1px);
}
.modal-body {
    position: relative;
    -ms-flex: 1 1 auto;
    flex: 1 1 auto;
    padding: 1rem;
}
form {
    display: block;
    margin-top: 0em;
    unicode-bidi: isolate;
}
.modal-content {
    position: relative;
    display: -ms-flexbox;
    display: flex;
    -ms-flex-direction: column;
    flex-direction: column;
    width: 100%;
    pointer-events: auto;
    background-color: #fff;
    background-clip: padding-box;
    border: 1px solid rgba(0, 0, 0, .2);
    border-radius: 4.8px;
    outline: 0;
}
.modal-footer {
    display: -ms-flexbox;
    display: flex;
    -ms-flex-wrap: wrap;
    flex-wrap: wrap;
    -ms-flex-align: center;
    align-items: center;
    -ms-flex-pack: end;
    justify-content: flex-end;
    padding: .75rem;
    border-top: 1px solid #dee2e6;
    border-bottom-right-radius: calc(.3rem - 1px);
    border-bottom-left-radius: calc(.3rem - 1px);
}
h5 {
    font-size: 20px !important;
}
.modal.fade .modal-dialog {
    transition: -webkit-transform .3s ease-out;
    transition: transform .3s ease-out;
    transition: transform .3s ease-out, -webkit-transform .3s ease-out;
    -webkit-transform: translate(0, -50px);
    transform: translate(0, -50px);
}
.modal.show .modal-dialog {
    -webkit-transform: none;
    transform: none;
}
.modal-dialog {
    position: relative;
    width: auto;
    margin: .5rem;
    pointer-events: none;
}
@media (min-width: 576px) {
    .modal-dialog {
        max-width: 500px;
        margin: 1.75rem auto;
    }
}
@media (min-width: 992px) {
    .modal-lg, .modal-xl {
        max-width: 800px;
    }
}
label {
    display: inline-block;
    margin-bottom: .5rem;
}
label {
    cursor: default;
}
.form-group {
    margin-bottom: 1rem;
}
.custom-file {
    position: relative;
    display: inline-block;
    width: 100%;
    height: calc(1.5em + .75rem + 2px);
    margin-bottom: 0;
}
input:not([type="image" i], [type="range" i], [type="checkbox" i], [type="radio" i]) {
    overflow-clip-margin: 0px !important;
    overflow: clip !important;
}
input[type="file" i] {
    appearance: none;
    background-color: initial;
    cursor: default;
    align-items: baseline;
    color: inherit;
    text-overflow: ellipsis;
    text-align: start !important;
    padding: initial;
    border: initial;
    white-space: pre;
}
input {
    font-style: ;
    font-variant-ligatures: ;
    font-variant-caps: ;
    font-variant-numeric: ;
    font-variant-east-asian: ;
    font-variant-alternates: ;
    font-variant-position: ;
    font-weight: ;
    font-stretch: ;
    font-size: ;
    font-family: ;
    font-optical-sizing: ;
    font-size-adjust: ;
    font-kerning: ;
    font-feature-settings: ;
    font-variation-settings: ;
    text-rendering: auto;
    color: fieldtext;
    letter-spacing: normal;
    word-spacing: normal;
    line-height: normal;
    text-transform: none;
    text-indent: 0px;
    text-shadow: none;
    display: inline-block;
    text-align: start;
    appearance: auto;
    -webkit-rtl-ordering: logical;
    cursor: text;
    background-color: field;
    margin: 0em;
    padding: 1px 0px;
    border-width: 2px;
    border-style: inset;
    border-color: light-dark(rgb(118, 118, 118), rgb(133, 133, 133));
    border-image: initial;
    padding-block: 1px;
    padding-inline: 2px;
}
.text-muted {
    color: #6c757d !important;
}
.text-truncate {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
file-label, .custom-select {
    transition: background-color .15s ease-in-out, border-color .15s ease-in-out, box-shadow .15s ease-in-out;
}
.custom-select {
    display: inline-block;
    width: 100%;
    height: calc(1.5em + .75rem + 2px);
    padding: .375rem 1.75rem .375rem .75rem;
    font-size: 14px;
    font-weight: 400;
    line-height: 1.5;
    color: #495057;
    vertical-align: middle;
    border: 1px solid #ced4da;
    border-radius: .25rem;
    -webkit-appearance: none;
    -moz-appearance: none;
    appearance: none;
}
.form-control {
    display: block;
    width: 100%;
    height: calc(1.5em + .75rem + 2px);
    padding: .375rem .75rem;
    font-size: 14px;
    font-family: Roboto, sans-serif;
    font-weight: 400;
    line-height: 1.5;
    color: #495057;
    background-color: #fff;
    background-clip: padding-box;
    border: 1px solid #ced4da;
    border-radius: .25rem;
    transition: border-color .15s ease-in-out, box-shadow .15s ease-in-out;
}
select {
    word-wrap: normal;
}
.custom-file-label {
    position: absolute;
    top: 0;
    right: 0;
    left: 0;
    z-index: 1;
    height: calc(1.5em + .75rem + 2px);
    padding: .375rem .75rem;
    overflow: hidden;
    font-weight: 400;
    line-height: 1.5;
    color: #495057;
    background-color: #fff;
    border: 1px solid #ced4da;
    border-radius: .25rem;
}
.custom-file-label::after {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    z-index: 3;
    display: block;
    height: calc(1.5em + .75rem);
    padding: .375rem .75rem;
    line-height: 1.5;
    color: #495057;
    content: "Browse";
    background-color: #e9ecef;
    border-left: inherit;
    border-radius: 0 .25rem .25rem 0;
}
.alert-warning {
    color: #856404;
    background-color: #fff3cd;
    border-color: #ffeeba;
}
.alert {
    position: relative;
    padding: .75rem 1.25rem;
    margin-bottom: 1rem;
    border: 1px solid transparent;
    border-radius: .25rem;
}
option {
    font-weight: normal;
    display: block;
    padding-block-start: 0px;
    padding-block-end: 1px;
    min-block-size: 1.2em;
    padding-inline: 2px;
    white-space: nowrap;
}
.modal-backdrop.fade {
    opacity: 0;
}
.modal-backdrop.show {
    opacity: .5;
}
.modal-backdrop {
    position: fixed;
    top: 0;
    left: 0;
    z-index: 1040;
    width: 100vw;
    height: 100vh;
    background-color: #000;
}
`;

GM_addStyle(css);

let contestStartTime = -1;
// let contestStartTime = 1726755078;
let blueLine;
let submissionResult;
let contestProblems, contestProblemName, gymRound;
let teamname, rank, penalty, score;
let problemStatus = {};
let timerInterval;
let submitForm;
let contestLength = 18000;

function getCurrentURL () {
    return window.location.href;
}

function parseLanguage(language){
    if(language.startsWith('C++')){
        return "CPP";
    }
    if(language.startsWith('Py')){
        return "PY3";
    }
    return language;
}

function parseVerdict(verdict){
    if(verdict == "OK") return "CORRECT";
    if(verdict == "WRONG_ANSWER")   return "WRONG-ANSWER";
    if(verdict == "TIME_LIMIT_EXCEEDED") return "TIMELIMIT";
    if(verdict == "RUNTIME_ERROR") return "RUN-ERROR";
    if(verdict == "MEMORY_LIMIT_EXCEEDED") return "RUN-ERROR";
    if(verdict == "COMPILATION_ERROR")  return "COMPILER-ERROR";
    if(verdict == "TESTING")  return "PENDING";
    return "PENDING";
}

function parseSubmission(result){
    submissionResult = [];
    for(let submission of result){
        if(contestStartTime <= submission.creationTimeSeconds && submission.creationTimeSeconds - contestStartTime < contestLength){
            const date = new Date(submission.creationTimeSeconds * 1000);
            submissionResult.push({
                index: submission.problem.index,
                verdict: parseVerdict(submission.verdict),
                time: date.getHours().toString().padStart(2, '0')+":"+date.getMinutes().toString().padStart(2, '0'),
                submitMinute: Math.floor(submission.relativeTimeSeconds/60),
                language: parseLanguage(submission.programmingLanguage)
            });
        }
    }
    const reversedSubmissionResult = submissionResult.slice().reverse();
    for(let submission of reversedSubmissionResult){
        if(submission.index in problemStatus){
            if(submission.verdict == "CORRECT"){
                if(problemStatus[submission.index].passtime == -1)
                    problemStatus[submission.index].passtime = submission.submitMinute;
            }
            else if(submission.verdict == "PENDING"){
                problemStatus[submission.index].pendingNumber = problemStatus[submission.index].pendingNumber+1;
                if(problemStatus[submission.index].pending == -1)
                    problemStatus[submission.index].pending = submission.submitMinute;
            }
            else{
                problemStatus[submission.index].rejected = problemStatus[submission.index].rejected + (submission.verdict == "COMPILER-ERROR" ? 0 : 1);
            }
        }
        else{
            let newStatus;
            if(submission.verdict == "PENDING"){
                newStatus = {
                    rejected: 0,
                    passtime: -1,
                    pending: submission.submitMinute,
                    pendingNumber: 1
                }
            }
            else if(submission.verdict != "CORRECT"){
                newStatus = {
                    rejected: submission.verdict == "COMPILER-ERROR" ? 0 : 1,
                    passtime: -1,
                    pending: -1,
                    pendingNumber: 0
                }
            }
            else{
                newStatus = {
                    rejected: 0,
                    passtime: submission.submitMinute,
                    pending: -1,
                    pendingNumber: 0
                }
            }
            problemStatus[submission.index] = newStatus;
        }
    }
}

async function getApiData () {
    domjudgeView();
    gymRound = getCurrentURL().split('/')[4];
    // console.log(gymRound);

    let links = document.querySelectorAll('a'), username;
    // 取得 username
    for (let link of links) {
        if (link.href.includes('/profile/')) {
            username = link.href.split('/')[4];
            break;
        }
    }

    const SubmissionApiURL = 'https://codeforces.com/api/contest.status?contestId=' + gymRound + '&handle=' + username;
    // console.log(SubmissionApiURL);

    await fetch(SubmissionApiURL)
        .then(response => response.json())  // 將回應轉為 JSON 格式
        .then(data => {
        if (data.result && data.result.length > 0) {
            if("startTimeSeconds" in data.result[0].author)
                contestStartTime = data.result[0].author.startTimeSeconds;
            parseSubmission(data.result);
            // return data.result[0].creationTimeSeconds;
        } else {
            console.log("No result found in Submission API response");
        }
    })
        .then(() => drawHeader())
        .catch(error => {
        console.error("Error fetching API:", error);
    });

    const ContestApiURL = 'https://codeforces.com/api/contest.standings?contestId=' + gymRound + '&from=1&showUnofficial=true';
    // console.log(ContestApiURL);

    await fetch(ContestApiURL)
        .then(response => response.json())  // 將回應轉為 JSON 格式
        .then(data => {
        if (data.result) {
            contestLength = data.result.contest.durationSeconds;

            contestProblems = [];
            for(let problem of data.result.problems){
                contestProblems.push(problem.index);
            }

            contestProblemName = [];
            for(let problem of data.result.problems){
                contestProblemName.push(problem.index + " - " + problem.name);
            }

            for(let team of data.result.rows){
                if(team.party.members.some(item => item.handle === username)){
                    penalty = team.penalty;
                    rank = team.rank;
                    score = team.points;
                    if("teamName" in team.party)
                        teamname = team.party.teamName;
                    else
                        teamname = username;
                    break;
                }
            }
        } else {
            console.log("No result found in Contest API response");
        }
    })
        .then(() => drawTimeLine())
        .then(() => updateTimeLine())
        .then(() => drawTeamsSummary())
        .then(() => drawSubmission())
        .then(() => addSubmitPage())
        .then(() => submitButtomJquery());
    // .catch(error => {
    //     console.error("Error fetching API:", error);
    // });

    timerInterval = setInterval(updateTimer, 1000);
}

function updateTimeLine(){
    if(contestStartTime == -1)  return;
    // console.log((Date.now() / 1000 - contestStartTime), contestLength);
    let contestDuringPrecentage = (Date.now() / 1000 - contestStartTime) / contestLength;
    // contestDuringPrecentage = Math.random();
    if(contestDuringPrecentage > 1) {
        return;
    }
    let pageWidth = window.innerWidth;
    let blueLineWidth = contestDuringPrecentage * pageWidth;
    blueLine.style.width = blueLineWidth + 'px'; // 設定寬度
}

function addFontAwesome(){
    // 獲取頁面中的 <header> 元素
    let header = document.querySelector('head');

    // 創建一個新的 <script> 元素
    let scriptElement = document.createElement('script');

    // 設置 <script> 標籤的屬性
    scriptElement.src = "https://cdnjs.cloudflare.com/ajax/libs/jquery/1.8.3/jquery.min.js"
    scriptElement.type = "text/javascript";

    let linkElement = document.createElement('link');

    // 設置 <link> 標籤的屬性
    linkElement.href = "https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.2.1/css/all.min.css";
    linkElement.rel = "stylesheet";
    linkElement.type = "text/css";
    //linkElement.type = "text/javascript";

    // 將 <link> 標籤添加到 <head> 中


    // 將 <script> 元素添加到 <header> 中
    if (header) {
        header.appendChild(scriptElement);
        header.appendChild(linkElement);
    }
}
function drawTimeLine(){
    if(contestStartTime == -1)  return;
    let contestDuringPrecentage = (Date.now() / 1000 - contestStartTime) / contestLength;
    // contestDuringPrecentage = 0.5;
    if(contestDuringPrecentage > 1) {
        return;
    }
    let pageWidth = window.innerWidth;
    let blueLineWidth = contestDuringPrecentage * pageWidth;

    blueLine = document.createElement('div');
    blueLine.style.position = 'absolute';
    blueLine.style.bottom = '0';
    blueLine.style.left = '0';
    blueLine.style.height = '5.5px'; // 可以調整高度
    blueLine.style.backgroundColor = '#0079ff';
    blueLine.style.zIndex = '9999'; // 保證藍線在最上層
    blueLine.style.width = blueLineWidth + 'px'; // 設定寬度
    document.querySelector('nav').appendChild(blueLine);

}

function drawHeader(){
    document.getElementById('body').style.margin = "0";

    // 選擇所有的 <a> 元素
    let links = document.querySelectorAll('a');
    let LogoutLink;

    // 遍歷每個 <a>,檢查其 innerHTML 是否包含 "Logout"
    links.forEach(link => {
        if (link.innerHTML.includes('Logout')) {
            // console.log(link); // 找到的 <a> 元素會被輸出到控制台
            LogoutLink = link;
        }
    });

    document.getElementById('header').remove();
    document.querySelector('.menu-list-container').remove();
    document.querySelector('.menu-box').remove();
    document.querySelector('.alert-success').remove();

    let baseUrl = getCurrentURL().split('/').slice(0, 5).join('/');

    let navElement = document.createElement('nav');
    navElement.classList.add('navbar','navbar-expand-md','navbar-dark','bg-dark','fixed-top');

    let navHTML = "";

    navHTML = `<a class="navbar-brand hidden-sm-down" href="${baseUrl}/submit">DOMjudge</a>`;

    navHTML += '<div class="collapse navbar-collapse" id="menuDefault">';
    navHTML += '<ul class="navbar-nav mr-auto">';
    navHTML += `<li class="nav-item active"><a class="nav-link" href="${baseUrl}/submit"><i class="fas fa-home"></i> Home </a></li>`;
    navHTML += `<li class="nav-item"><a class="nav-link" href="${baseUrl}"><i class="fas fa-book-open"></i> Problemset </a></li>`;
    navHTML += `<li class="nav-item"><a class="nav-link" href="${baseUrl}/standings"><i class="fas fa-list-ol"></i> Scoreboard </a></li>`;

    navHTML += '</ul>';
    navHTML += '<div id="submitbut"><a id="submitLink" class="nav-link justify-content-center" data-ajax-modal="" data-ajax-modal-after="initSubmitModal" href="#"><span class="btn btn-success btn-sm"><i class="fas fa-cloud-upload-alt"></i> Submit</span></a></div>';
    navHTML += `<a class="btn btn-info btn-sm justify-content-center" href="${LogoutLink}" onclick="return confirmLogout();"><i class="fas fa-sign-out-alt"></i> Logout</a>`;
    navHTML += `<div class="navbar-text" style="white-space:nowrap;"><span style="padding-left: 10px;"><i class="fas fa-clock loading-indicator"></i></span><span id="timeleft"> contest over</span></div>`;
    navHTML += '</div>';

    navElement.innerHTML = navHTML;

    let bodyDiv = document.getElementById('body');
    bodyDiv.insertBefore(navElement, bodyDiv.firstChild);
}

function updateTimer(){
    if(Math.floor(Date.now()/1000) - contestStartTime > contestLength){
        document.getElementById("timeleft").innerHTML = " contest over";
        clearInterval(timerInterval); // 倒數結束時停止計時
    }
    else{
        let leftSecond = contestLength - (Math.floor(Date.now()/1000) - contestStartTime);
        let minutes = (Math.floor((leftSecond%3600)/60));
        let seconds = leftSecond%60;
        let displayMinutes = minutes < 10 ? '0' + minutes : minutes;
        let displaySeconds = seconds < 10 ? '0' + seconds : seconds;
        if(leftSecond > 3600)
            document.getElementById("timeleft").innerHTML = " " + Math.floor(leftSecond/3600).toString() + ":" + displayMinutes + ":" + displaySeconds;
        else
            document.getElementById("timeleft").innerHTML = " " + displayMinutes + ":" + displaySeconds;
    }
}

function drawTeamsSummary(){
    // console.log(contestProblems);

    let tableHTML = '<table class="summary-table center">';

    // Table Header
    tableHTML += '<colgroup><col id="scorerank"><col id="scoreteamname"></colgroup>';
    tableHTML += '<colgroup><col id="scoresolv"><col id="scoretotal"></colgroup>';
    tableHTML += '<colgroup>';
    for(let i = 0; i < contestProblems.length; i++){
        tableHTML += '<col class="scoreprob"';
    }
    tableHTML += '</colgroup>';
    tableHTML += '<thead><tr class="summary-table-header">';
    tableHTML += '<th title="rank" scope="col">rank</th>';
    tableHTML += '<th title="team name" scope="col" colspan="3">team</th>';
    tableHTML += '<th title="# solved / penalty time" colspan="2" scope="col">score</th>';
    // tableHTML += '<th style="text-align: center;">score</th>';
    contestProblems.forEach(problemIndex => {
        const linkURL = `https://codeforces.com/gym/${gymRound}/problem/${problemIndex.toString()}`;
        tableHTML += `<th title="" scope="col"><a href="${linkURL}" target="_blank"><span class="badge problem-badge" style="min-width: 28px; border: 1px solid"><span style="color: #000000;">${problemIndex}</span></span></a></th>`;
    });
    tableHTML += '</tr></thead><tbody>';

    tableHTML += '<tr class="sortorderswitch">';
    tableHTML += `<td class="scorepl">${rank}</td>`;
    tableHTML += `<td class="scoreaf"> </td>`;
    tableHTML += `<td class="scoreaf"> </td>`;
    tableHTML += `<td class="scoretn">${teamname}</td>`;
    // tableHTML += `<td class="score-penalty-table"><div>${score}</div><div>${penalty}</div></td>`;
    tableHTML += `<td class="scorenc">${score}</td>`;
    tableHTML += `<td class="scorett">${penalty}</td>`;

    contestProblems.forEach(problemIndex => {
        if(!(problemIndex in problemStatus))
            tableHTML += `<td class="score_cell"></td>`;
        else if(problemStatus[problemIndex].passtime != -1){
            // console.log(problemIndex, problemStatus[problemIndex].passtime, problemStatus[problemIndex].pending, problemStatus[problemIndex].pendingNumber);
            if(problemStatus[problemIndex].passtime > problemStatus[problemIndex].pending && problemStatus[problemIndex].pendingNumber != 0){
                const tryTime = problemStatus[problemIndex].rejected;
                const tryString = tryTime.toString() + " + " + (problemStatus[problemIndex].pendingNumber).toString() + " tries";
                tableHTML += `<td class="score_cell"><a><div style="background:#6666FF">&nbsp;<span>${tryString}</span></div></a></td>`;
            }
            else{
                const tryTime = problemStatus[problemIndex].rejected+1;
                const tryString = tryTime.toString() + (tryTime > 1 ? " tries" : " try");
                tableHTML += `<td class="score_cell"><a><div style="background:#60e760">${problemStatus[problemIndex].passtime}<span>${tryString}</span></div></a></td>`;
            }
        }
        else if(problemStatus[problemIndex].pendingNumber != 0){
            const tryTime = problemStatus[problemIndex].rejected;
            const tryString = tryTime.toString() + " + " + (problemStatus[problemIndex].pendingNumber).toString() + " tries";
            tableHTML += `<td class="score_cell"><a><div style="background:#6666FF">&nbsp;<span>${tryString}</span></div></a></td>`;
        }
        else{
            const tryTime = problemStatus[problemIndex].rejected;
            const tryString = tryTime.toString() + (tryTime > 1 ? " tries" : " try");
            tableHTML += `<td class="score_cell"><a><div style="background:#e87272">&nbsp;<span>${tryString}</span></div></a></td>`;
        }

    });
    tableHTML += '</tr>';

    tableHTML += '</tbody></table>';

    submitForm = document.getElementById('pageContent').getElementsByTagName('form')[0];

    document.getElementById('pageContent').innerHTML = tableHTML;

}
function drawSubmission(){
    let tableHTML = '<div class="row><div class="col">';

    tableHTML += '<h1 class="teamoverview">Submissions</h1>';
    tableHTML += '<table class="data-table table table-hover table-striped table-sm submissions-table">'

    tableHTML += '<thead class="thead-light"><tr><th scope="col">time</th><th scope="col">problem</th><th scope="col">lang</th><th scope="col">result</th></tr></thead>';

    tableHTML += '<tbody>';

    submissionResult.forEach(Submission =>{
        tableHTML += '<tr class>';
        tableHTML += `<td>${Submission.time}</td>`;
        tableHTML += `<td class="probid"><a><span class="badge problem-badge" style="min-width: 28px;border: 1px solid #7293a8";><span>${Submission.index}</span></span><a></td>`;
        tableHTML += `<td class="langid"><a>${Submission.language}</a></td>`;
        if(Submission.verdict == "CORRECT")
            tableHTML += `<td class="sol sol_correct"><a>${Submission.verdict}</a></td>`;
        else if(Submission.verdict == "PENDING")
            tableHTML += `<td class="sol sol_queued"><a>${Submission.verdict}</a></td>`;
        else
            tableHTML += `<td class="sol sol_incorrect"><a>${Submission.verdict}</a></td>`;
        tableHTML += '</tr>';
    });

    tableHTML += '</tbody></table>';
    tableHTML += '</div></div>';

    document.getElementById('pageContent').innerHTML += tableHTML;
    document.getElementById('sidebar').innerHTML = "";
}

addFontAwesome();
getApiData();

function domjudgeView() {
    // 遍歷所有的文本節點
    let walker = document.createTreeWalker(document.body, NodeFilter.SHOW_TEXT, null, false);
    let node, nextNode;

    while (node = walker.nextNode()) {
        // 檢查節點是否包含 'on test'
        let textContent = node.nodeValue;
        let index = textContent.indexOf(' ON TEST');

        if (index !== -1) {
            // 刪除 'on test' 及其後面的所有內容
            node.nodeValue = textContent.substring(0, index);
            nextNode = walker.nextNode();
            nextNode.nodeValue = "";
        }
        else{
            let pretestIndex = textContent.indexOf(' ON PRETEST');
            if (pretestIndex !== -1) {
                // 刪除 'on pretest' 及其後面的所有內容
                node.nodeValue = textContent.substring(0, pretestIndex);
                nextNode = walker.nextNode();
                nextNode.nodeValue = "";
            }
        }
    }
}

domjudgeView();

// 監聽 DOM 的變化以處理動態更新的內容
const observer = new MutationObserver((mutations) => {
    mutations.forEach((mutation) => {
        // 針對新增的節點,重新執行移除操作
        if (mutation.addedNodes.length) {
            // chrome.storage.sync.get(['featureEnabled'], function (result) {
            //     if (result.featureEnabled) {
            //         domjudgeView();
            //         updateTimeLine();
            //     }
            // });
            domjudgeView();
            updateTimeLine();
        }
    });
});

// 配置監聽器參數
const observerConfig = {
    childList: true,  // 監聽子節點變動
    subtree: true,    // 監聽整個子樹
    characterData: true  // 監聽文字內容變動
};

// 啟動監聽器
observer.observe(document.body, observerConfig);

function humanReadableTimeDiff(seconds) {
    var intervals = [
        ['years', 365 * 24 * 60 * 60],
        ['months', 30 * 24 * 60 * 60],
        ['days', 24 * 60 * 60],
        ['hours', 60 * 60],
        ['minutes', 60],
    ];
    for (let [name, length] of intervals) {
        if (seconds / length >= 2) {
            return Math.floor(seconds/length) + ' ' + name;
        }
    }
    return Math.floor(seconds) + ' seconds';
}

function humanReadableBytes(bytes) {
    var sizes = [
        ['GB', 1024*1024*1024],
        ['MB', 1024*1024],
        ['KB', 1024],
    ];
    for (let [name, length] of sizes) {
        if (bytes / length >= 2) {
            return Math.floor(bytes/length) + name;
        }
    }
    return Math.floor(bytes) + 'B';
}

function addSubmitPage(){
    // 創建模態框的 HTML

    let submitTable = submitForm.querySelector('tbody');
    let rows = submitTable.querySelectorAll('tr');

    submitTable.insertBefore(rows[4], rows[0]);
    submitTable.removeChild(rows[3]);

    submitForm.querySelector('.field-name').innerHTML = "Source files";
    submitForm.querySelector('.programTypeNotice').remove();
    submitForm.querySelector('.outputOnlyProgramTypeIdNotice').remove();
    submitForm.querySelector(".error__submittedProblemIndex").remove();

    let submitButInput = submitTable.querySelector(".submit");
    let buttonElement = document.createElement("button");
    buttonElement.id = submitButInput.id;
    buttonElement.type = submitButInput.type;
    buttonElement.className = submitButInput.className;
    buttonElement.innerHTML = `<i class="fas fa-cloud-upload-alt"></i> Submit `;
    // submitTable.replaceChild(buttonElement, submitButInput);

    buttonElement.classList.add('btn');
    buttonElement.classList.add('btn-success');


    const allowedLanguage = ["43", "89", "87", "31"];
    const languageName = ["C", "CPP", "JAVA", "PYTHON3"];

    const selectElement = submitForm.querySelector('select[name="programTypeId"]');
    Array.from(selectElement.options).forEach(option => {
        if (!allowedLanguage.includes(option.value)) {
            option.remove();
        }
        else{
            for(let i = 0; i < allowedLanguage.length; i++){
                if(allowedLanguage[i] == option.value){
                    option.innerHTML = languageName[i];
                    option.removeAttribute('selected');
                    break;
                }
            }
        }
    });

    const noLanguageOption = document.createElement('option');
    noLanguageOption.value = "0";
    noLanguageOption.text = "Select a language";
    noLanguageOption
    selectElement.insertBefore(noLanguageOption, selectElement.firstChild);

    // console.log(submitForm.outerHTML);

    // <span class="close">&times;</span>

    submitForm.querySelector('select[name="submittedProblemIndex"]').querySelector('option[value=""]').remove();
    let submit_problem_option = submitForm.querySelector('select[name="submittedProblemIndex"]').innerHTML;
    let csrf_token_input = submitForm.querySelector('input[name="csrf_token"]').outerHTML;
    // console.log(submit_problem_option);

    const modalHTML = `<div id="myModal" class="modal fade show" tabindex="-1" role="dialog" aria-modal="true" style="display: none;">
    <div class="modal-dialog modal-lg" role="document"><div class="modal-content"><div class="modal-header"><h5 class="modal-title">Submit</h5><button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button></div>
<form class="submit-form" name="csrf_token" method="post" action="/team/submit" enctype="multipart/form-data">`
    + csrf_token_input +
          `<input type="hidden" name="ftaa" value="">
    <input type="hidden" name="bfaa" value="">
    <input type="hidden" name="action" value="submitSolutionFormSubmitted">
    <div class="modal-body">
    <div class="form-group"><label for="submit_problem_code" class="required">Source files</label><div class="custom-file"><input type="file" id="submit_problem_code" name="sourceFile" required="required" class="custom-file-input custom-file-input"><label class="custom-file-label text-truncate text-muted" for="submit_problem_code">No file selected</label></div></div>
    <div class="alert alert-warning" id="files_not_modified" style="display:none;"></div>
    <div class="form-group"><label class="required" for="submit_problem_problem">Problem</label><select id="submit_problem_problem" name="submittedProblemIndex" required="required" class="form-control custom-select form-control"><option value="" selected="selected">Select a problem</option>` + submit_problem_option + `</select></div>
    <div class="form-group"><label class="required" for="submit_problem_language">Language</label><select id="submit_problem_language" name="programTypeId" required="required" class="form-control custom-select form-control"><option value="" selected="selected">Select a language</option><option value="43">C</option><option value="89">C++</option><option value="87">Java</option><option value="31">Python 3</option></select></div></div>
    <div class="modal-footer"><button id="cancelBtn" type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button><button type="submit" class="btn-success btn"><i class="fas fa-cloud-upload-alt"></i> Submit </button></div><input type="hidden" name="_tta" value="396"></form></div></div>
    </div>`;

    // 插入模態框到頁面中
    document.body.insertAdjacentHTML('beforeend', modalHTML);

    $(function () {
        $('body').on('change', '.custom-file-input', function () {
            var files = this.files;
            var fileNames = [];
            for (var i = 0; i < files.length; i++) {
                fileNames.push(files.item(i).name);
            }
            $(this).next('.custom-file-label').html(fileNames.join(", "));
            $(this).next('.custom-file-label').removeClass('text-muted');
        });
    });

    const fileInput = document.getElementById('submit_problem_code');
    fileInput.addEventListener('change', (event) => {

        const five_minutes_in_ms = 5 * 60 * 1000;
        const now = Date.now();
        const filesNotModified = document.getElementById('files_not_modified');
        filesNotModified.style.display = 'none';

        var atLeastOneFileRecent = false;
        var fileInfoHtml = '';
        const files = event.target.files;
        for (let file of files) {
            const date = new Date(file.lastModified);
            const ago = humanReadableTimeDiff((now - date)/1000) + ' ago';
            if (date > now - five_minutes_in_ms) {
                atLeastOneFileRecent = true;
            }
            let size = humanReadableBytes(file.size);
            fileInfoHtml += `<li><span class="filename">${file.name}</span>, ${size}, last modified ${ago}</li>`;
        }
        if (!atLeastOneFileRecent) {
            filesNotModified.style.display = 'block';
            filesNotModified.innerHTML =
                'None of the selected files has been recently modified:' +
                '<ul>' + fileInfoHtml + '</ul>';
        }
    });

    const modal_backdrop_html = `<div class="modal-backdrop fade show" style="display:none;"></div>`;
    document.body.insertAdjacentHTML('beforeend', modal_backdrop_html);

    // 把 input 按鈕換成 button
    // submitButInput = document.getElementById("singlePageSubmitButton");
    // submitButInput.parentNode.insertBefore(buttonElement, submitButInput);
    // submitButInput.remove();

    // 獲取模態框和觸發連結
    const modal = document.getElementById('myModal');
    const openModal = document.getElementById('submitbut');
    const closeModal = document.querySelector('.close');
    const cancelModal = document.getElementById('cancelBtn');
    const modal_backdrop = document.querySelector('.modal-backdrop');
    const filesNotModified = document.getElementById('files_not_modified');

    // 當用戶點擊連結時,顯示模態框
    openModal.addEventListener('click', function(event) {
        event.preventDefault(); // 防止連結跳轉
        modal.style.display = 'block';
        modal_backdrop.style.display = 'block';
    });

    // 當用戶點擊關閉按鈕時,隱藏模態框
    closeModal.addEventListener('click', function() {
        modal.style.display = 'none';
        modal_backdrop.style.display = 'none';
        filesNotModified.style.display = 'none';
    });

    // 當用戶點擊模態框外部時,隱藏模態框
    window.addEventListener('click', function(event) {
        if (event.target === modal) {
            modal.style.display = 'none';
            modal_backdrop.style.display = 'none';
            filesNotModified.style.display = 'none';
        }
    });

    cancelModal.addEventListener('click', function() {
        modal.style.display = 'none';
        modal_backdrop.style.display = 'none';
        filesNotModified.style.display = 'none';
    });
}


function getMainExtension(ext) {
    switch (ext) {
        case 'c':
            return '43';
        case 'cpp':
            return '89';
        case 'cc':
            return '89';
        case 'cxx':
            return '89';
        case 'c++':
            return '89';
        case 'java':
            return '87';
        case 'py':
            return '31';
        default:
            return '';
    }
}


function submitButtomJquery(){

    $(document).ready(function () {
        {
        }
        var processFile = function () {
            var filename = $('#submit_problem_code').val();
            if (filename !== '' && filename !== undefined) {
                filename = filename.replace(/^.*[\\\/]/, '');
                var parts = filename.split('.').reverse();
                if (parts.length < 2) return;
                var lcParts = [parts[0].toLowerCase(), parts[1].toLowerCase()];

                // language ID

                var language = document.getElementById('submit_problem_language');
                // the "autodetect" option has empty value
                if (language.value !== '') return;

                var langid = getMainExtension(lcParts[0]);
                for (i = 0; i < language.length; i++) {
                    if (language.options[i].value === langid) {
                        language.selectedIndex = i;
                    }
                }

                // Problem ID

                var problem = document.getElementById('submit_problem_problem');
                // the "autodetect" option has empty value
                if (problem.value !== '') {
                    return;
                }

                for (var i = 0; i < problem.length; i++) {
                    if (problem.options[i].text.split(/ - /)[0].toLowerCase() === lcParts[1]) {
                        problem.selectedIndex = i;
                    }
                }
            }
        };
        var $body = $('body');
        $body.on('change', '#submit_problem_code', processFile);
    });

    const form = document.querySelector('.submit-form');

    form.addEventListener('submit', function(event) {
        event.preventDefault();

        const formData = new FormData(document.querySelector('.submit-form'));

        // for (const [key, value] of formData.entries()) {
        //     console.log(key, value);
        // }

        var langelt = document.getElementById("submit_problem_language");
        var language = langelt.options[langelt.selectedIndex].value;
        var languagetxt = langelt.options[langelt.selectedIndex].text;
        var fileelt = document.getElementById("submit_problem_code");
        var filenames = fileelt.files;
        var filename = filenames[0].name;
        var probelt = document.getElementById("submit_problem_problem");
        var problem = probelt.options[probelt.selectedIndex].value;
        var problemtxt = probelt.options[probelt.selectedIndex].text;

        var error = false;
        if (language === "") {
            langelt.focus();
            langelt.className = langelt.className + " errorfield";
            error = true;
        }
        if (problem === "") {
            probelt.focus();
            probelt.className = probelt.className + " errorfield";
            error = true;
        }
        if (filename === "") {
            error = true;
        }
        if (error) return false;

        var auxfileno = 0;
        // start at one; skip maincode file field
        for (var i = 1; i < filenames.length; i++) {
            if (filenames[i].value !== "") {
                auxfileno++;
            }
        }
        var extrafiles = '';
        if (auxfileno > 0) {
            extrafiles = "Additional source files: " + auxfileno + '\n';
        }
        var question =
            'Main source file: ' + filename + '\n' +
            extrafiles + '\n' +
            'Problem: ' + problemtxt + '\n' +
            'Language: ' + languagetxt + '\n' +
            '\nMake submission?';
        if(confirm(question)){
            fetch(getCurrentURL().split('/').slice(0, 5).join('/')+'/submit?csrf_token='+formData.get('csrf_token'), {
                method: form.method,
                body: formData,
            })
                .then(response => {
                if (response.ok) {
                    location.reload();

                } else {
                    console.error('submit fail');
                }
            });
        }
        // .catch(error => {
        //     console.error('error: ', error);
        // });
    });
}