var wait = true; var check_timeout = 300; var editorMode = localStorageGetItem("editorMode") || "normal"; var redirectStderrToStdout = ((localStorageGetItem("redirectStderrToStdout") || "false") === "true"); var editorModeObject = null; var fontSize = 14; var MonacoVim; var MonacoEmacs; var layout; var sourceEditor; var stdinEditor; var stdoutEditor; var stderrEditor; var isEditorDirty = false; var currentLanguageId; var $selectLanguage var $selectTheme var $insertTemplateBtn; var $runBtn; var timeStart; var timeEnd; var layoutConfig = { settings: { showPopoutIcon: false, reorderEnabled: true }, dimensions: { borderWidth: 3, headerHeight: 22 }, content: [{ type: "row", content: [{ type: "component", componentName: "source", title: "SOURCE", isClosable: false, componentState: { readOnly: false }, width: 60 }, { type: "column", content: [{ type: "stack", content: [{ type: "component", componentName: "stdin", title: "STDIN", isClosable: false, componentState: { readOnly: false } }] }, { type: "stack", content: [{ type: "component", componentName: "stdout", title: "STDOUT", isClosable: false, componentState: { readOnly: true } }, { type: "component", componentName: "stderr", title: "STDERR", isClosable: false, componentState: { readOnly: true } }, ] }] }] }] }; function encode(str) { return btoa(unescape(encodeURIComponent(str || ""))); } function decode(bytes) { var escaped = escape(atob(bytes || "")); try { return decodeURIComponent(escaped); } catch { return unescape(escaped); } } function localStorageSetItem(key, value) { try { localStorage.setItem(key, value); } catch (ignorable) { } } function localStorageGetItem(key) { try { return localStorage.getItem(key); } catch (ignorable) { return null; } } function showError(title, content) { $("#site-modal #title").html(title); $("#site-modal .content").html(content); $("#site-modal").modal("show"); } function handleError(jqXHR, textStatus, errorThrown) { showError(`${jqXHR.statusText} (${jqXHR.status})`, `
${JSON.stringify(jqXHR, null, 4)}`); } function handleRunError(jqXHR, textStatus, errorThrown) { handleError(jqXHR, textStatus, errorThrown); $runBtn.removeClass("loading"); } function handleResult(data) { timeEnd = performance.now(); var status = data.status; var stdout = decode(data.stdout); var stderr = decode(data.stderr); var compile_output = decode(data.compile_output); var time = (data.time === null ? "-" : data.time + "s"); var memory = (data.memory === null ? "-" : data.memory + "KB"); stdoutEditor.setValue(compile_output + stdout + `\n[${status.description}, ${time}, ${memory}]`); stderrEditor.setValue(stderr); if (stdout !== "") { var dot = document.getElementById("stdout-dot"); if (!dot.parentElement.classList.contains("lm_active")) { dot.hidden = false; } } if (stderr !== "") { var dot = document.getElementById("stderr-dot"); if (!dot.parentElement.classList.contains("lm_active")) { dot.hidden = false; } } $runBtn.removeClass("loading"); } function getIdFromURI() { var uri = location.search.substr(1).trim(); return uri.split("&")[0]; } function downloadSource() { var value = parseInt($selectLanguage.val()); download(sourceEditor.getValue(), fileNames[value], "text/plain"); } function loadSavedSource() { snippet_id = getIdFromURI(); if (snippet_id.length == 36) { $.ajax({ url: apiUrl + "/submissions/" + snippet_id + "?fields=source_code,language_id,stdin,stdout,stderr,compile_output,message,time,memory,status&base64_encoded=true", type: "GET", success: function(data, textStatus, jqXHR) { sourceEditor.setValue(decode(data["source_code"])); $selectLanguage.dropdown("set selected", data["language_id"]); stdinEditor.setValue(decode(data["stdin"])); stderrEditor.setValue(decode(data["stderr"])); var time = (data.time === null ? "-" : data.time + "s"); var memory = (data.memory === null ? "-" : data.memory + "KB"); stdoutEditor.setValue(decode(data["compile_output"]) + decode(data["stdout"]) + `\n[${data.status.description}, ${time}, ${memory}]`); changeEditorLanguage(); }, error: handleRunError }); } else { loadRandomLanguage(); } } function run() { if (sourceEditor.getValue().trim() === "") { showError("Error", "Source code can't be empty!"); return; } else { $runBtn.addClass("loading"); } document.getElementById("stdout-dot").hidden = true; document.getElementById("stderr-dot").hidden = true; stdoutEditor.setValue(""); stderrEditor.setValue(""); var sourceValue = encode(sourceEditor.getValue()); var stdinValue = encode(stdinEditor.getValue()); var languageId = resolveLanguageId($selectLanguage.val()); if (parseInt(languageId) === 44) { sourceValue = sourceEditor.getValue(); } var data = { source_code: sourceValue, language_id: languageId, stdin: stdinValue, redirect_stderr_to_stdout: redirectStderrToStdout }; var sendRequest = function(data) { timeStart = performance.now(); $.ajax({ url: apiUrl + `/submissions?base64_encoded=true&wait=${wait}`, type: "POST", async: true, contentType: "application/json", data: JSON.stringify(data), xhrFields: { withCredentials: apiUrl.indexOf("/secure") != -1 ? true : false }, success: function (data, textStatus, jqXHR) { console.log(data.token); if (wait == true) { handleResult(data); } else { setTimeout(fetchSubmission.bind(null, data.token), check_timeout); } }, error: handleRunError }); } sendRequest(data); } function fetchSubmission(submission_token) { $.ajax({ url: apiUrl + "/submissions/" + submission_token + "?base64_encoded=true", type: "GET", async: true, success: function (data, textStatus, jqXHR) { if (data.status.id <= 2) { // In Queue or Processing setTimeout(fetchSubmission.bind(null, submission_token), check_timeout); return; } handleResult(data); }, error: handleRunError }); } function changeEditorLanguage() { monaco.editor.setModelLanguage(sourceEditor.getModel(), $selectLanguage.find(":selected").attr("mode")); currentLanguageId = parseInt($selectLanguage.val()); $(".lm_title")[0].innerText = fileNames[currentLanguageId]; apiUrl = resolveApiUrl($selectLanguage.val()); } function insertTemplate() { currentLanguageId = parseInt($selectLanguage.val()); sourceEditor.setValue(sources[currentLanguageId]); changeEditorLanguage(); } function loadRandomLanguage() { var values = []; for (var i = 0; i < $selectLanguage[0].options.length; ++i) { values.push($selectLanguage[0].options[i].value); } // $selectLanguage.dropdown("set selected", values[Math.floor(Math.random() * $selectLanguage[0].length)]); $selectLanguage.dropdown("set selected", values[9]); apiUrl = resolveApiUrl($selectLanguage.val()); insertTemplate(); } function resizeEditor(layoutInfo) { if (editorMode != "normal") { var statusLineHeight = $("#editor-status-line").height(); layoutInfo.height -= statusLineHeight; layoutInfo.contentHeight -= statusLineHeight; } } function disposeEditorModeObject() { try { editorModeObject.dispose(); editorModeObject = null; } catch(ignorable) { } } function changeEditorMode() { disposeEditorModeObject(); if (editorMode == "vim") { editorModeObject = MonacoVim.initVimMode(sourceEditor, $("#editor-status-line")[0]); } else if (editorMode == "emacs") { var statusNode = $("#editor-status-line")[0]; editorModeObject = new MonacoEmacs.EmacsExtension(sourceEditor); editorModeObject.onDidMarkChange(function(e) { statusNode.textContent = e ? "Mark Set!" : "Mark Unset"; }); editorModeObject.onDidChangeKey(function(str) { statusNode.textContent = str; }); editorModeObject.start(); } } function resolveLanguageId(id) { id = parseInt(id); return id; } function resolveApiUrl(id) { id = parseInt(id); return apiUrl; } function editorsUpdateFontSize(fontSize) { sourceEditor.updateOptions({fontSize: fontSize}); stdinEditor.updateOptions({fontSize: fontSize}); stdoutEditor.updateOptions({fontSize: fontSize}); stderrEditor.updateOptions({fontSize: fontSize}); } function getDefaultTheme() { return localStorageGetItem('editor-theme') || 'vs-dark'; } function editorsUpdateTheme(isInit) { var theme = $selectTheme.val(); if (isInit) { theme = getDefaultTheme(); $selectTheme.val(theme).change(); } else localStorageSetItem('editor-theme', theme); var $siteNavigation = $("#site-navigation"); if (theme == 'vs') { $siteNavigation.removeClass('inverted'); $siteNavigation.css('background', 'white'); } else { $("#site-navigation").addClass('inverted'); $siteNavigation.css('background', '#1e1e1e'); } sourceEditor.updateOptions({theme: theme}); stdinEditor.updateOptions({theme: theme}); stdoutEditor.updateOptions({theme: theme}); stderrEditor.updateOptions({theme: theme}); } function updateScreenElements() { var display = window.innerWidth <= 1200 ? "none" : ""; $(".wide.screen.only").each(function(index) { $(this).css("display", display); }); } $(window).resize(function() { layout.updateSize(); updateScreenElements(); }); $(document).ready(function () { updateScreenElements(); $selectLanguage = $("#select-language"); $selectLanguage.change(function (e) { if (!isEditorDirty) { insertTemplate(); } else { changeEditorLanguage(); } }); $selectTheme = $("#select-theme"); $selectTheme.change(function(e) { editorsUpdateTheme(false); }); $insertTemplateBtn = $("#insert-template-btn"); $insertTemplateBtn.click(function (e) { if (isEditorDirty && confirm("Are you sure? Your current changes will be lost.")) { insertTemplate(); } }); $runBtn = $("#run-btn"); $runBtn.click(function (e) { run(); }); $(`input[name="editor-mode"][value="${editorMode}"]`).prop("checked", true); $("input[name=\"editor-mode\"]").on("change", function(e) { editorMode = e.target.value; localStorageSetItem("editorMode", editorMode); resizeEditor(sourceEditor.getLayoutInfo()); changeEditorMode(); sourceEditor.focus(); }); $("input[name=\"redirect-output\"]").prop("checked", redirectStderrToStdout) $("input[name=\"redirect-output\"]").on("change", function(e) { redirectStderrToStdout = e.target.checked; localStorageSetItem("redirectStderrToStdout", redirectStderrToStdout); }); $("body").keydown(function (e) { var keyCode = e.keyCode || e.which; if (keyCode == 120 || (event.ctrlKey && keyCode == 66)) { // F9 || ctrl B e.preventDefault(); run(); } else if (event.ctrlKey && (keyCode == 107 || keyCode == 187)) { // Ctrl++ e.preventDefault(); fontSize += 1; editorsUpdateFontSize(fontSize); } else if (event.ctrlKey && (keyCode == 107 || keyCode == 189)) { // Ctrl+- e.preventDefault(); fontSize -= 1; editorsUpdateFontSize(fontSize); } }); $("select.dropdown").dropdown(); $(".ui.dropdown").dropdown(); $(".ui.dropdown.site-links").dropdown({action: "hide", on: "hover"}); $(".ui.checkbox").checkbox(); $(".message .close").on("click", function () { $(this).closest(".message").transition("fade"); }); require(["vs/editor/editor.main", "monaco-vim", "monaco-emacs"], function (ignorable, MVim, MEmacs) { layout = new GoldenLayout(layoutConfig, $("#site-content")); MonacoVim = MVim; MonacoEmacs = MEmacs; layout.registerComponent("source", function (container, state) { sourceEditor = monaco.editor.create(container.getElement()[0], { automaticLayout: true, theme: getDefaultTheme(), scrollBeyondLastLine: true, readOnly: state.readOnly, language: "cpp", minimap: { enabled: false }, matchBrackets: false, }); changeEditorMode(); sourceEditor.getModel().onDidChangeContent(function (e) { currentLanguageId = parseInt($selectLanguage.val()); isEditorDirty = sourceEditor.getValue() != sources[currentLanguageId]; }); sourceEditor.onDidLayoutChange(resizeEditor); sourceEditor.onDidChangeCursorPosition(function(e) { var line = sourceEditor.getPosition().lineNumber; var col = sourceEditor.getPosition().column; $('#cursor-position').html(`Line ${line}, Column ${col}`) }) }); layout.registerComponent("stdin", function (container, state) { stdinEditor = monaco.editor.create(container.getElement()[0], { automaticLayout: true, theme: getDefaultTheme(), scrollBeyondLastLine: false, readOnly: state.readOnly, language: "plaintext", minimap: { enabled: false }, wordWrap: "on", }); }); layout.registerComponent("stdout", function (container, state) { stdoutEditor = monaco.editor.create(container.getElement()[0], { automaticLayout: true, theme: getDefaultTheme(), scrollBeyondLastLine: false, readOnly: state.readOnly, language: "plaintext", minimap: { enabled: false }, wordWrap: "on", }); container.on("tab", function(tab) { tab.element.append(""); tab.element.on("mousedown", function(e) { e.target.closest(".lm_tab").children[3].hidden = true; }); }); }); layout.registerComponent("stderr", function (container, state) { stderrEditor = monaco.editor.create(container.getElement()[0], { automaticLayout: true, theme: getDefaultTheme(), scrollBeyondLastLine: false, readOnly: state.readOnly, language: "plaintext", minimap: { enabled: false }, wordWrap: "on", }); container.on("tab", function(tab) { tab.element.append(""); tab.element.on("mousedown", function(e) { e.target.closest(".lm_tab").children[3].hidden = true; }); }); }); layout.on("initialised", function () { $(".monaco-editor")[0].appendChild($("#editor-status-line")[0]); if (getIdFromURI()) { loadSavedSource(); } else { loadRandomLanguage(); } $("#site-navigation").css("border-bottom", "1px solid black"); sourceEditor.focus(); editorsUpdateFontSize(fontSize); editorsUpdateTheme(true); }); layout.init(); }); }); // Template Sources var assemblySource = "\ section .text\n\ global _start\n\ \n\ _start:\n\ \n\ xor eax, eax\n\ lea edx, [rax+len]\n\ mov al, 1\n\ mov esi, msg\n\ mov edi, eax\n\ syscall\n\ \n\ xor edi, edi\n\ lea eax, [rdi+60]\n\ syscall\n\ \n\ section .rodata\n\ \n\ msg db 'hello, world', 0xa\n\ len equ $ - msg\n\ "; var bashSource = "echo \"hello, world\""; var basicSource = "PRINT \"hello, world\""; var cSource = "\ // Powered by Judge0\n\ #include