Initial IDE
This commit is contained in:
parent
ed6e79fdf0
commit
c4a91ccf0f
6 changed files with 1428 additions and 1 deletions
|
@ -18,7 +18,7 @@ from judge.feed import AtomBlogFeed, AtomCommentFeed, AtomProblemFeed, BlogFeed,
|
||||||
from judge.forms import CustomAuthenticationForm
|
from judge.forms import CustomAuthenticationForm
|
||||||
from judge.sitemap import BlogPostSitemap, ContestSitemap, HomePageSitemap, OrganizationSitemap, ProblemSitemap, \
|
from judge.sitemap import BlogPostSitemap, ContestSitemap, HomePageSitemap, OrganizationSitemap, ProblemSitemap, \
|
||||||
SolutionSitemap, UrlSitemap, UserSitemap
|
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, \
|
notification, organization, preview, problem, problem_manage, ranked_submission, register, stats, status, submission, tasks, \
|
||||||
ticket, totp, user, widgets
|
ticket, totp, user, widgets
|
||||||
from judge.views.problem_data import ProblemDataView, ProblemSubmissionDiff, \
|
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'submit/$', user.import_users_submit, name='import_users_submit'),
|
||||||
url(r'sample/$', user.sample_import_users, name='import_users_sample')
|
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',
|
favicon_paths = ['apple-touch-icon-180x180.png', 'apple-touch-icon-114x114.png', 'android-chrome-72x72.png',
|
||||||
|
|
29
judge/views/ide.py
Normal file
29
judge/views/ide.py
Normal file
|
@ -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)
|
||||||
|
|
132
resources/download.js
Normal file
132
resources/download.js
Normal file
|
@ -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<mx;++i) uia[i]= bin.charCodeAt(i);
|
||||||
|
|
||||||
|
return new B([uia], {type: t});
|
||||||
|
}
|
||||||
|
|
||||||
|
function saver(url, winMode){
|
||||||
|
|
||||||
|
|
||||||
|
if ('download' in a) { //html5 A[download]
|
||||||
|
a.href = url;
|
||||||
|
a.setAttribute("download", fn);
|
||||||
|
a.innerHTML = "downloading...";
|
||||||
|
D.body.appendChild(a);
|
||||||
|
setTimeout(function() {
|
||||||
|
a.click();
|
||||||
|
D.body.removeChild(a);
|
||||||
|
if(winMode===true){setTimeout(function(){ self.URL.revokeObjectURL(a.href);}, 250 );}
|
||||||
|
}, 66);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//do iframe dataURL download (old ch+FF):
|
||||||
|
var f = D.createElement("iframe");
|
||||||
|
D.body.appendChild(f);
|
||||||
|
if(!winMode){ // force a mime that will download:
|
||||||
|
url="data:"+url.replace(/^data:([\w\/\-\+]+)/, u);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
f.src = url;
|
||||||
|
setTimeout(function(){ D.body.removeChild(f); }, 333);
|
||||||
|
|
||||||
|
}//end saver
|
||||||
|
|
||||||
|
|
||||||
|
if (navigator.msSaveBlob) { // IE10+ : (has Blob, but not a[download] or URL)
|
||||||
|
return navigator.msSaveBlob(blob, fn);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(self.URL){ // simple fast and modern way using Blob and URL:
|
||||||
|
saver(self.URL.createObjectURL(blob), true);
|
||||||
|
}else{
|
||||||
|
// handle non-Blob()+non-URL browsers:
|
||||||
|
if(typeof blob === "string" || blob.constructor===z ){
|
||||||
|
try{
|
||||||
|
return saver( "data:" + m + ";base64," + self.btoa(blob) );
|
||||||
|
}catch(y){
|
||||||
|
return saver( "data:" + m + "," + encodeURIComponent(blob) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Blob but not URL:
|
||||||
|
fr=new FileReader();
|
||||||
|
fr.onload=function(e){
|
||||||
|
saver(this.result);
|
||||||
|
};
|
||||||
|
fr.readAsDataURL(blob);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
} /* end download() */
|
||||||
|
|
166
resources/ide.css
Normal file
166
resources/ide.css
Normal file
|
@ -0,0 +1,166 @@
|
||||||
|
html, body {
|
||||||
|
height: 100%;
|
||||||
|
min-height: 100%;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
background: url(/images/judge0_background.png) no-repeat center center fixed;
|
||||||
|
-webkit-background-size: cover;
|
||||||
|
-moz-background-size: cover;
|
||||||
|
-o-background-size: cover;
|
||||||
|
background-size: cover;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ui[class*="left action"].input>.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;
|
||||||
|
}
|
868
resources/ide.js
Normal file
868
resources/ide.js
Normal file
|
@ -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})`, `<pre>${JSON.stringify(jqXHR, null, 4)}</pre>`);
|
||||||
|
}
|
||||||
|
|
||||||
|
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("<span id=\"stdout-dot\" class=\"dot\" hidden></span>");
|
||||||
|
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("<span id=\"stderr-dot\" class=\"dot\" hidden></span>");
|
||||||
|
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 <stdio.h>\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 <iostream>\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 <Foundation/Foundation.h>\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 = <STDIN>;\n\
|
||||||
|
print \"hello, $name\";\n\
|
||||||
|
";
|
||||||
|
|
||||||
|
var phpSource = "\
|
||||||
|
<?php\n\
|
||||||
|
print(\"hello, world\\n\");\n\
|
||||||
|
?>\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",
|
||||||
|
};
|
227
templates/ide.html
Normal file
227
templates/ide.html
Normal file
|
@ -0,0 +1,227 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
|
||||||
|
<!-- Favicons-->
|
||||||
|
<link rel="apple-touch-icon" sizes="57x57" href="/apple-touch-icon-57x57.png">
|
||||||
|
<link rel="apple-touch-icon" sizes="60x60" href="/apple-touch-icon-60x60.png">
|
||||||
|
<link rel="apple-touch-icon" sizes="72x72" href="/apple-touch-icon-72x72.png">
|
||||||
|
<link rel="apple-touch-icon" sizes="76x76" href="/apple-touch-icon-76x76.png">
|
||||||
|
<link rel="apple-touch-icon" sizes="114x114" href="/apple-touch-icon-114x114.png">
|
||||||
|
<link rel="apple-touch-icon" sizes="120x120" href="/apple-touch-icon-120x120.png">
|
||||||
|
<link rel="apple-touch-icon" sizes="144x144" href="/apple-touch-icon-144x144.png">
|
||||||
|
<link rel="apple-touch-icon" sizes="152x152" href="/apple-touch-icon-152x152.png">
|
||||||
|
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon-180x180.png">
|
||||||
|
<link rel="icon" type="image/png" href="/favicon-32x32.png" sizes="32x32">
|
||||||
|
<link rel="icon" type="image/png" href="/android-chrome-192x192.png" sizes="192x192">
|
||||||
|
<link rel="icon" type="image/png" href="/favicon-96x96.png" sizes="96x96">
|
||||||
|
<link rel="icon" type="image/png" href="/favicon-16x16.png" sizes="16x16">
|
||||||
|
<link rel="manifest" href="/manifest.json">
|
||||||
|
<meta name="msapplication-TileColor" content="#FFBB33">
|
||||||
|
<meta name="msapplication-TileImage" content="/mstile-144x144.png">
|
||||||
|
{# Chrome 39 for Android colour #}
|
||||||
|
<meta name="theme-color" content="#FFBB33">
|
||||||
|
{% if og_image %}
|
||||||
|
<meta property="og:image" content="{{ request.build_absolute_uri(og_image) }}">
|
||||||
|
{% endif %}
|
||||||
|
{% block og_title %}{% endblock %}
|
||||||
|
<meta property="og:site_name" content="{{ SITE_LONG_NAME }}">
|
||||||
|
<meta property="og:url"
|
||||||
|
content="{{ DMOJ_SCHEME }}://{{ DMOJ_CANONICAL|default(site.domain) }}{{ request.get_full_path() }}">
|
||||||
|
{% if meta_description %}
|
||||||
|
<meta property="og:description" content="{{ meta_description }}">
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<meta property="og:title" content="IDE">
|
||||||
|
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js" integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo=" crossorigin="anonymous"></script>
|
||||||
|
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/golden-layout/1.5.9/goldenlayout.min.js" integrity="sha256-NhJAZDfGgv4PiB+GVlSrPdh3uc75XXYSM4su8hgTchI=" crossorigin="anonymous"></script>
|
||||||
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/golden-layout/1.5.9/css/goldenlayout-base.css" integrity="sha256-oIDR18yKFZtfjCJfDsJYpTBv1S9QmxYopeqw2dO96xM=" crossorigin="anonymous" />
|
||||||
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/golden-layout/1.5.9/css/goldenlayout-dark-theme.css" integrity="sha256-ygw8PvSDJJUGLf6Q9KIQsYR3mOmiQNlDaxMLDOx9xL0=" crossorigin="anonymous" />
|
||||||
|
|
||||||
|
<script>
|
||||||
|
var require = {
|
||||||
|
paths: {
|
||||||
|
"vs": "https://unpkg.com/monaco-editor/min/vs",
|
||||||
|
"monaco-vim": "https://unpkg.com/monaco-vim/dist/monaco-vim",
|
||||||
|
"monaco-emacs": "https://unpkg.com/monaco-emacs/dist/monaco-emacs"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<script src="https://unpkg.com/monaco-editor/min/vs/loader.js"></script>
|
||||||
|
<script src="https://unpkg.com/monaco-editor@0.23.0/min/vs/editor/editor.main.nls.js"></script>
|
||||||
|
<script src="https://unpkg.com/monaco-editor@0.23.0/min/vs/editor/editor.main.js"></script>
|
||||||
|
|
||||||
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.4.1/semantic.min.css" integrity="sha256-9mbkOfVho3ZPXfM7W8sV2SndrGDuh7wuyLjtsWeTI1Q=" crossorigin="anonymous" />
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.4.1/semantic.min.js" integrity="sha256-t8GepnyPmw9t+foMh3mKNvcorqNHamSKtKRxxpUEgFI=" crossorigin="anonymous"></script>
|
||||||
|
|
||||||
|
<link href="https://fonts.googleapis.com/css?family=Exo+2" rel="stylesheet">
|
||||||
|
|
||||||
|
<script type="text/javascript" src="{{ static('download.js') }}"></script>
|
||||||
|
|
||||||
|
<script type="text/javascript" src="{{ static('ide.js') }}"></script>
|
||||||
|
|
||||||
|
<link type="text/css" rel="stylesheet" href="{{ static('ide.css') }}">
|
||||||
|
|
||||||
|
<title>IDE</title>
|
||||||
|
<link rel="shortcut icon" href="./favicon.ico" type="image/x-icon">
|
||||||
|
<link rel="icon" href="./favicon.ico" type="image/x-icon">
|
||||||
|
|
||||||
|
<script>
|
||||||
|
$(function() {
|
||||||
|
window.apiUrl = "{{ url('ide_api') }}";
|
||||||
|
$(window).on('beforeunload', function(e) {
|
||||||
|
return "T";
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div id="site-navigation" class="ui small inverted menu">
|
||||||
|
<div id="site-header" class="header item">
|
||||||
|
<a href="/">
|
||||||
|
<img id="site-icon" src="{{ static('icons/logo.png') }}">
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div class="left menu">
|
||||||
|
<div class="ui dropdown item site-links on-hover">
|
||||||
|
File <i class="dropdown icon"></i>
|
||||||
|
<div class="menu">
|
||||||
|
<a class="item" target="_blank" href="/"><i class="file code icon"></i>{{ _('New File') }}</a>
|
||||||
|
<div class="item" onclick="downloadSource()"><i class="download icon"></i>{{ _('Download') }}</div>
|
||||||
|
<div id="insert-template-btn" class="item"><i class="file code outline icon"></i>{{ _('Insert template
|
||||||
|
for current language') }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="link item" onclick="$('#site-settings').modal('show')"><i class="cog icon"></i> Settings</div>
|
||||||
|
<div class="item borderless">
|
||||||
|
<select id="select-language" class="ui dropdown">
|
||||||
|
<option value="45" mode="UNKNOWN">Assembly (NASM 2.14.02)</option> <!-- Unknown mode. Help needed. -->
|
||||||
|
<option value="46" mode="shell">Bash (5.0.0)</option>
|
||||||
|
<option value="47" mode="UNKNOWN">Basic (FBC 1.07.1)</option> <!-- Unknown mode. Help needed. -->
|
||||||
|
<option value="75" mode="c">C (Clang 7.0.1)</option>
|
||||||
|
<option value="48" mode="c">C (GCC 7.4.0)</option>
|
||||||
|
<option value="49" mode="c">C (GCC 8.3.0)</option>
|
||||||
|
<option value="50" mode="c">C (GCC 9.2.0)</option>
|
||||||
|
<option value="51" mode="csharp">C# (Mono 6.6.0.161)</option>
|
||||||
|
<option value="76" mode="cpp">C++ (Clang 7.0.1)</option>
|
||||||
|
<option value="52" mode="cpp">C++ (GCC 7.4.0)</option>
|
||||||
|
<option value="53" mode="cpp">C++ (GCC 8.3.0)</option>
|
||||||
|
<option value="54" mode="cpp">C++ (GCC 9.2.0)</option>
|
||||||
|
<option value="86" mode="clojure">Clojure (1.10.1)</option>
|
||||||
|
<option value="77" mode="UNKNOWN">COBOL (GnuCOBOL 2.2)</option> <!-- Unknown mode. Help needed. -->
|
||||||
|
<option value="55" mode="UNKNOWN">Common Lisp (SBCL 2.0.0)</option> <!-- Unknown mode. Help needed. -->
|
||||||
|
<option value="56" mode="UNKNOWN">D (DMD 2.089.1)</option> <!-- Unknown mode. Help needed. -->
|
||||||
|
<option value="57" mode="UNKNOWN">Elixir (1.9.4)</option> <!-- Unknown mode. Help needed. -->
|
||||||
|
<option value="58" mode="UNKNOWN">Erlang (OTP 22.2)</option> <!-- Unknown mode. Help needed. -->
|
||||||
|
<option value="44" mode="plaintext">Executable</option>
|
||||||
|
<option value="87" mode="fsharp">F# (.NET Core SDK 3.1.202)</option>
|
||||||
|
<option value="59" mode="UNKNOWN">Fortran (GFortran 9.2.0)</option> <!-- Unknown mode. Help needed. -->
|
||||||
|
<option value="60" mode="go">Go (1.13.5)</option>
|
||||||
|
<option value="88" mode="UNKNOWN">Groovy (3.0.3)</option> <!-- Unknown mode. Help needed. -->
|
||||||
|
<option value="61" mode="UNKNOWN">Haskell (GHC 8.8.1)</option> <!-- Unknown mode. Help needed. -->
|
||||||
|
<option value="62" mode="java">Java (OpenJDK 13.0.1)</option>
|
||||||
|
<option value="63" mode="javascript">JavaScript (Node.js 12.14.0)</option>
|
||||||
|
<option value="78" mode="kotlin">Kotlin (1.3.70)</option>
|
||||||
|
<option value="64" mode="lua">Lua (5.3.5)</option>
|
||||||
|
<option value="79" mode="objective-c">Objective-C (Clang 7.0.1)</option>
|
||||||
|
<option value="65" mode="UNKNOWN">OCaml (4.09.0)</option> <!-- Unknown mode. Help needed. -->
|
||||||
|
<option value="66" mode="UNKNOWN">Octave (5.1.0)</option> <!-- Unknown mode. Help needed. -->
|
||||||
|
<option value="67" mode="pascal">Pascal (FPC 3.0.4)</option>
|
||||||
|
<option value="85" mode="perl">Perl (5.28.1)</option>
|
||||||
|
<option value="68" mode="php">PHP (7.4.1)</option>
|
||||||
|
<option value="43" mode="plaintext">Plain Text</option>
|
||||||
|
<option value="69" mode="UNKNOWN">Prolog (GNU Prolog 1.4.5)</option> <!-- Unknown mode. Help needed. -->
|
||||||
|
<option value="70" mode="python">Python (2.7.17)</option>
|
||||||
|
<option value="71" mode="python">Python (3.8.1)</option>
|
||||||
|
<option value="80" mode="r">R (4.0.0)</option>
|
||||||
|
<option value="72" mode="ruby">Ruby (2.7.0)</option>
|
||||||
|
<option value="73" mode="rust">Rust (1.40.0)</option>
|
||||||
|
<option value="81" mode="UNKNOWN">Scala (2.13.2)</option> <!-- Unknown mode. Help needed. -->
|
||||||
|
<option value="83" mode="swift">Swift (5.2.3)</option>
|
||||||
|
<option value="74" mode="typescript">TypeScript (3.7.4)</option>
|
||||||
|
<option value="84" mode="vb">Visual Basic.Net (vbnc 0.0.0.5943)</option> <!-- (vbnc 0.0.0.5943) -->
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="item no-left-padding borderless">
|
||||||
|
<button id="run-btn" class="ui primary labeled icon button"><i class="play icon"></i>Run (F9)</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="site-content"></div>
|
||||||
|
|
||||||
|
<div id="site-modal" class="ui modal">
|
||||||
|
<div class="header">
|
||||||
|
<i class="close icon"></i>
|
||||||
|
<span id="title"></span>
|
||||||
|
</div>
|
||||||
|
<div class="scrolling content"></div>
|
||||||
|
<div class="actions">
|
||||||
|
<div class="ui small labeled icon cancel button">
|
||||||
|
<i class="remove icon"></i>
|
||||||
|
Close (ESC)
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="site-settings" class="ui modal">
|
||||||
|
<i class="close icon"></i>
|
||||||
|
<div class="header">
|
||||||
|
<i class="cog icon"></i>
|
||||||
|
Settings
|
||||||
|
</div>
|
||||||
|
<div class="content">
|
||||||
|
<div class="ui form">
|
||||||
|
<div class="inline fields">
|
||||||
|
<label>Editor Mode</label>
|
||||||
|
<div class="field">
|
||||||
|
<div class="ui radio checkbox">
|
||||||
|
<input type="radio" name="editor-mode" value="normal" checked="checked">
|
||||||
|
<label>Normal</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="field">
|
||||||
|
<div class="ui radio checkbox">
|
||||||
|
<input type="radio" name="editor-mode" value="vim">
|
||||||
|
<label>Vim</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="field">
|
||||||
|
<div class="ui radio checkbox">
|
||||||
|
<input type="radio" name="editor-mode" value="emacs">
|
||||||
|
<label>Emacs</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="inline field">
|
||||||
|
<div class="ui checkbox">
|
||||||
|
<input type="checkbox" name="redirect-output">
|
||||||
|
<label>Redirect stderr to stdout</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="inline field">
|
||||||
|
<label>{{ _('Editor Theme') }}</label>
|
||||||
|
<select id="select-theme" class="ui dropdown">
|
||||||
|
<option value="vs">VS Light</option>
|
||||||
|
<option value="vs-dark">VS Dark</option>
|
||||||
|
<option value="hc-black">HC Black</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="site-footer">
|
||||||
|
<div id="editor-status-line"></div>
|
||||||
|
<span id="cursor-position"></span>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
Loading…
Reference in a new issue