diff --git a/dmoj/urls.py b/dmoj/urls.py index ecc17b9..1fad04d 100644 --- a/dmoj/urls.py +++ b/dmoj/urls.py @@ -18,7 +18,7 @@ from judge.feed import AtomBlogFeed, AtomCommentFeed, AtomProblemFeed, BlogFeed, from judge.forms import CustomAuthenticationForm from judge.sitemap import BlogPostSitemap, ContestSitemap, HomePageSitemap, OrganizationSitemap, ProblemSitemap, \ SolutionSitemap, UrlSitemap, UserSitemap -from judge.views import TitledTemplateView, about, api, blog, comment, contests, language, license, mailgun, \ +from judge.views import TitledTemplateView, about, api, blog, comment, contests, ide, language, license, mailgun, \ notification, organization, preview, problem, problem_manage, ranked_submission, register, stats, status, submission, tasks, \ ticket, totp, user, widgets from judge.views.problem_data import ProblemDataView, ProblemSubmissionDiff, \ @@ -399,6 +399,11 @@ urlpatterns = [ url(r'submit/$', user.import_users_submit, name='import_users_submit'), url(r'sample/$', user.sample_import_users, name='import_users_sample') ])), + + url(r'^ide/', include([ + url(r'^$', login_required(TitledTemplateView.as_view(template_name='ide.html', title=_('IDE'))), name='ide'), + url(r'api', ide.api, name='ide_api'), + ])), ] favicon_paths = ['apple-touch-icon-180x180.png', 'apple-touch-icon-114x114.png', 'android-chrome-72x72.png', diff --git a/judge/views/ide.py b/judge/views/ide.py new file mode 100644 index 0000000..cbdba47 --- /dev/null +++ b/judge/views/ide.py @@ -0,0 +1,29 @@ +from django.utils.translation import gettext as _ +from django.contrib.auth.decorators import login_required +from django.http import HttpResponse, Http404, JsonResponse +from django.views.decorators.csrf import csrf_exempt + +import requests, json, http + +PREFIX_URL = 'ide/api' + +@login_required +@csrf_exempt +def api(request): + url = 'http://localhost:2358' + request.get_full_path()[len(PREFIX_URL) + 1:] + headers = {'X-Judge0-Token': 'cuom1999'} + r = None + if request.method == 'POST': + r = requests.post(url, data=json.loads(request.body.decode('utf-8')), headers=headers) + elif request.method == 'GET': + r = requests.get(url, headers=headers) + else: + return Http404() + + res = r.content.decode('utf-8') + try: + res = json.loads(r.content.decode('utf-8')) + return JsonResponse(res, status=r.status_code, safe=False) + except Exception: + return HttpResponse(res) + \ No newline at end of file diff --git a/resources/download.js b/resources/download.js new file mode 100644 index 0000000..9312aec --- /dev/null +++ b/resources/download.js @@ -0,0 +1,132 @@ +//download.js v3.0, by dandavis; 2008-2014. [CCBY2] see http://danml.com/download.html for tests/usage +// v1 landed a FF+Chrome compat way of downloading strings to local un-named files, upgraded to use a hidden frame and optional mime +// v2 added named files via a[download], msSaveBlob, IE (10+) support, and window.URL support for larger+faster saves than dataURLs +// v3 added dataURL and Blob Input, bind-toggle arity, and legacy dataURL fallback was improved with force-download mime and base64 support + +// data can be a string, Blob, File, or dataURL + + + + +function download(data, strFileName, strMimeType) { + + var self = window, // this script is only for browsers anyway... + u = "application/octet-stream", // this default mime also triggers iframe downloads + m = strMimeType || u, + x = data, + D = document, + a = D.createElement("a"), + z = function(a){return String(a);}, + + + B = self.Blob || self.MozBlob || self.WebKitBlob || z, + BB = self.MSBlobBuilder || self.WebKitBlobBuilder || self.BlobBuilder, + fn = strFileName || "download", + blob, + b, + ua, + fr; + + //if(typeof B.bind === 'function' ){ B=B.bind(self); } + + if(String(this)==="true"){ //reverse arguments, allowing download.bind(true, "text/xml", "export.xml") to act as a callback + x=[x, m]; + m=x[0]; + x=x[1]; + } + + + + //go ahead and download dataURLs right away + if(String(x).match(/^data\:[\w+\-]+\/[\w+\-]+[,;]/)){ + return navigator.msSaveBlob ? // IE10 can't do a[download], only Blobs: + navigator.msSaveBlob(d2b(x), fn) : + saver(x) ; // everyone else can save dataURLs un-processed + }//end if dataURL passed? + + try{ + + blob = x instanceof B ? + x : + new B([x], {type: m}) ; + }catch(y){ + if(BB){ + b = new BB(); + b.append([x]); + blob = b.getBlob(m); // the blob + } + + } + + + + function d2b(u) { + var p= u.split(/[:;,]/), + t= p[1], + dec= p[2] == "base64" ? atob : decodeURIComponent, + bin= dec(p.pop()), + mx= bin.length, + i= 0, + uia= new Uint8Array(mx); + + for(i;i.dropdown { + border-radius: 0 .28571429rem .28571429rem 0; +} + +.ui.selection.dropdown { + width: 205px; +} + +.lm_header .lm_tab { + padding-bottom: 3px; + height: 16px; + font-family: "Droid Sans Mono", monospace, monospace, "Droid Sans Fallback"; + font-size: 14px; +} + +.lm_header .lm_tab.lm_active { + box-shadow: none; + padding-bottom: 3px; +} + +#site-navigation { + border-radius: 0; + margin: 0; + background: #1e1e1e; + border-bottom: 1px solid rgba(255, 255, 255, 0.08); + height: 45px; +} + +#navigation-message { + font-size: 1.2em; + white-space: nowrap; + overflow: hidden; +} + +@keyframes slide { + 0% { transform: translateX(570px); } + 100% { transform: translateX(-100%); } +} +@-webkit-keyframes slide { + 0% { transform: translateX(570px); } + 100% { transform: translateX(-100%); } +} + +.navigation-message-text { + white-space: nowrap; + -moz-animation: slide 60s linear infinite; + -webkit-animation: slide 60s linear infinite; + animation: slide 60s linear infinite; +} + +.navigation-message-text:hover { + -moz-animation-play-state: paused; + -webkit-animation-play-state: paused; + animation-play-state: paused; +} + +#navigation-message a { + color: #41a5f1; + font-weight: bold; +} + +#site-icon { + height: 40px; + vertical-align: middle; +} + +#site-header { + padding-top: 0; + padding-bottom: 0; +} + +#site-header h2 { + display: inline; + vertical-align: middle; + font-family: 'Exo 2', sans-serif; +} + +#site-content { + height: calc(100% - 45px - 19px); +} + +#site-modal .header { + color: #db2828; +} + +#site-footer { + background-color: darkslategrey; + bottom: 0; + font-family: monospace, monospace, "Droid Sans Fallback"; + font-size: 13px; + height: 19px; + padding-left: 16px; + padding-right: 16px; + position: fixed; +} + +#site-footer { + color: gray; + left: 0; + width: 100%; +} + +#editor-status-line { + background: transparent; + color: #fff; + font-family: monospace; + height: 19px; + padding: 0px 16px; + width: inherit; +} + +#editor-status-line input[type=text] { + background: transparent; + border: none; + color: #fff; + font-family: monospace; + outline: none; +} + +#editor-status-line input[type=text]::selection { + background-color: #cce2ff; + color: #fff; +} + +.blink { + animation: blinker 1s linear infinite; +} + +@keyframes blinker { + 50% { + background: #FFD700; + } +} + +.dot { + background: #0E6EB8; + position: absolute; + border-radius: 50px; + width: 5px; + height: 5px; + right: 7.5px; + top: 7.5px; +} + +.no-left-padding { + padding-left: 0 !important; +} + +input[type="text"] { + width: 205px !important; +} \ No newline at end of file diff --git a/resources/ide.js b/resources/ide.js new file mode 100644 index 0000000..08020c9 --- /dev/null +++ b/resources/ide.js @@ -0,0 +1,868 @@ +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 \n\ +\n\ +int main(void) {\n\ + printf(\"Hello Judge0!\\n\");\n\ + return 0;\n\ +}\n\ +"; + +var csharpSource = "\ +public class Hello {\n\ + public static void Main() {\n\ + System.Console.WriteLine(\"hello, world\");\n\ + }\n\ +}\n\ +"; + +var cppSource = "\ +#include \n\ +\n\ +int main() {\n\ + std::cout << \"hello, world\" << std::endl;\n\ + return 0;\n\ +}\n\ +"; + +var clojureSource = "(println \"hello, world\")\n"; + +var cobolSource = "\ +IDENTIFICATION DIVISION.\n\ +PROGRAM-ID. MAIN.\n\ +PROCEDURE DIVISION.\n\ +DISPLAY \"hello, world\".\n\ +STOP RUN.\n\ +"; + +var lispSource = "(write-line \"hello, world\")"; + +var dSource = "\ +import std.stdio;\n\ +\n\ +void main()\n\ +{\n\ + writeln(\"hello, world\");\n\ +}\n\ +"; + +var elixirSource = "IO.puts \"hello, world\""; + +var erlangSource = "\ +main(_) ->\n\ + io:fwrite(\"hello, world\\n\").\n\ +"; + +var executableSource = "\ +Judge0 IDE assumes that content of executable is Base64 encoded.\n\ +\n\ +This means that you should Base64 encode content of your binary,\n\ +paste it here and click \"Run\".\n\ +\n\ +Here is an example of compiled \"hello, world\" NASM program.\n\ +Content of compiled binary is Base64 encoded and used as source code.\n\ +\n\ +https://ide.judge0.com/?kS_f\n\ +"; + +var fsharpSource = "printfn \"hello, world\"\n"; + +var fortranSource = "\ +program main\n\ + print *, \"hello, world\"\n\ +end\n\ +"; + +var goSource = "\ +package main\n\ +\n\ +import \"fmt\"\n\ +\n\ +func main() {\n\ + fmt.Println(\"hello, world\")\n\ +}\n\ +"; + +var groovySource = "println \"hello, world\"\n"; + +var haskellSource = "main = putStrLn \"hello, world\""; + +var javaSource = "\ +public class Main {\n\ + public static void main(String[] args) {\n\ + System.out.println(\"hello, world\");\n\ + }\n\ +}\n\ +"; + +var javaScriptSource = "console.log(\"hello, world\");"; + +var kotlinSource = "\ +fun main() {\n\ + println(\"hello, world\")\n\ +}\n\ +"; + +var luaSource = "print(\"hello, world\")"; + +var objectiveCSource = "\ +#import \n\ +\n\ +int main() {\n\ + @autoreleasepool {\n\ + char name[10];\n\ + scanf(\"%s\", name);\n\ + NSString *message = [NSString stringWithFormat:@\"hello, %s\\n\", name];\n\ + printf(\"%s\", message.UTF8String);\n\ + }\n\ + return 0;\n\ +}\n\ +"; + +var ocamlSource = "print_endline \"hello, world\""; + +var octaveSource = "printf(\"hello, world\\n\");"; + +var pascalSource = "\ +program Hello;\n\ +begin\n\ + writeln ('hello, world')\n\ +end.\n\ +"; + +var perlSource = "\ +my $name = ;\n\ +print \"hello, $name\";\n\ +"; + +var phpSource = "\ +\n\ +"; + +var plainTextSource = "hello, world\n"; + +var prologSource = "\ +:- initialization(main).\n\ +main :- write('hello, world\\n').\n\ +"; + +var pythonSource = "print(\"hello, world\")"; + +var rSource = "cat(\"hello, world\\n\")"; + +var rubySource = "puts \"hello, world\""; + +var rustSource = "\ +fn main() {\n\ + println!(\"hello, world\");\n\ +}\n\ +"; + +var scalaSource = "\ +object Main {\n\ + def main(args: Array[String]) = {\n\ + val name = scala.io.StdIn.readLine()\n\ + println(\"hello, \"+ name)\n\ + }\n\ +}\n\ +"; + +var swiftSource = "\ +import Foundation\n\ +let name = readLine()\n\ +print(\"hello, \\(name!)\")\n\ +"; + +var typescriptSource = "console.log(\"hello, world\");"; + +var vbSource = "\ +Public Module Program\n\ + Public Sub Main()\n\ + Console.WriteLine(\"hello, world\")\n\ + End Sub\n\ +End Module\n\ +"; + +var sources = { + 45: assemblySource, + 46: bashSource, + 47: basicSource, + 48: cSource, + 49: cSource, + 50: cSource, + 51: csharpSource, + 52: cppSource, + 53: cppSource, + 54: cppSource, + 55: lispSource, + 56: dSource, + 57: elixirSource, + 58: erlangSource, + 44: executableSource, + 59: fortranSource, + 60: goSource, + 61: haskellSource, + 62: javaSource, + 63: javaScriptSource, + 64: luaSource, + 65: ocamlSource, + 66: octaveSource, + 67: pascalSource, + 68: phpSource, + 43: plainTextSource, + 69: prologSource, + 70: pythonSource, + 71: pythonSource, + 72: rubySource, + 73: rustSource, + 74: typescriptSource, + 75: cSource, + 76: cppSource, + 77: cobolSource, + 78: kotlinSource, + 79: objectiveCSource, + 80: rSource, + 81: scalaSource, + 83: swiftSource, + 84: vbSource, + 85: perlSource, + 86: clojureSource, + 87: fsharpSource, + 88: groovySource, +}; + +var fileNames = { + 45: "main.asm", + 46: "script.sh", + 47: "main.bas", + 48: "main.c", + 49: "main.c", + 50: "main.c", + 51: "Main.cs", + 52: "main.cpp", + 53: "main.cpp", + 54: "main.cpp", + 55: "script.lisp", + 56: "main.d", + 57: "script.exs", + 58: "main.erl", + 44: "a.out", + 59: "main.f90", + 60: "main.go", + 61: "main.hs", + 62: "Main.java", + 63: "script.js", + 64: "script.lua", + 65: "main.ml", + 66: "script.m", + 67: "main.pas", + 68: "script.php", + 43: "text.txt", + 69: "main.pro", + 70: "script.py", + 71: "script.py", + 72: "script.rb", + 73: "main.rs", + 74: "script.ts", + 75: "main.c", + 76: "main.cpp", + 77: "main.cob", + 78: "Main.kt", + 79: "main.m", + 80: "script.r", + 81: "Main.scala", + 83: "Main.swift", + 84: "Main.vb", + 85: "script.pl", + 86: "main.clj", + 87: "script.fsx", + 88: "script.groovy", +}; \ No newline at end of file diff --git a/templates/ide.html b/templates/ide.html new file mode 100644 index 0000000..81f8460 --- /dev/null +++ b/templates/ide.html @@ -0,0 +1,227 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + {# Chrome 39 for Android colour #} + + {% if og_image %} + + {% endif %} + {% block og_title %}{% endblock %} + + + {% if meta_description %} + + {% endif %} + + + + + + + + + + + + + + + + + + + + + + + + + + IDE + + + + + + + + + +
+ + + + + + + + +