wrap-pony-code-snippet

Created Diff never expires
9 removals
647 lines
12 additions
650 lines
(function () {
(function () {
"use strict";
"use strict";
const PLAYPEN_URL = "https://playground.ponylang.io";
const PLAYPEN_URL = "https://playground.ponylang.io";


var samples = 2;
var samples = 2;


function optionalLocalStorageGetItem(key) {
function optionalLocalStorageGetItem(key) {
try {
try {
return localStorage.getItem(key);
return localStorage.getItem(key);
} catch (e) {
} catch (e) {
return null;
return null;
}
}
}
}


function optionalLocalStorageSetItem(key, value) {
function optionalLocalStorageSetItem(key, value) {
try {
try {
window.localStorage.setItem(key, value);
window.localStorage.setItem(key, value);
} catch (e) {
} catch (e) {
// ignore
// ignore
}
}
}
}


function build_themes(themelist) {
function build_themes(themelist) {
// Load all ace themes, sorted by their proper name.
// Load all ace themes, sorted by their proper name.
var themes = themelist.themes;
var themes = themelist.themes;
themes.sort(function (a, b) {
themes.sort(function (a, b) {
if (a.caption < b.caption) {
if (a.caption < b.caption) {
return -1;
return -1;
} else if (a.caption > b.caption) {
} else if (a.caption > b.caption) {
return 1;
return 1;
}
}
return 0;
return 0;
});
});


var themeopt,
var themeopt,
themefrag = document.createDocumentFragment();
themefrag = document.createDocumentFragment();
for (var i = 0; i < themes.length; i++) {
for (var i = 0; i < themes.length; i++) {
themeopt = document.createElement("option");
themeopt = document.createElement("option");
themeopt.setAttribute("val", themes[i].theme);
themeopt.setAttribute("val", themes[i].theme);
themeopt.textContent = themes[i].caption;
themeopt.textContent = themes[i].caption;
themefrag.appendChild(themeopt);
themefrag.appendChild(themeopt);
}
}
document.getElementById("themes").appendChild(themefrag);
document.getElementById("themes").appendChild(themefrag);
}
}


function send(path, data, callback, button, message, result) {
function send(path, data, callback, button, message, result) {
button.disabled = true;
button.disabled = true;


set_result(result, "<p class=message>" + message);
set_result(result, "<p class=message>" + message);


var request = new XMLHttpRequest();
var request = new XMLHttpRequest();
request.open("POST", path, true);
request.open("POST", path, true);
request.setRequestHeader("Content-Type", "application/json");
request.setRequestHeader("Content-Type", "application/json");
request.onreadystatechange = function () {
request.onreadystatechange = function () {
button.disabled = false;
button.disabled = false;
if (request.readyState == 4) {
if (request.readyState == 4) {
var json;
var json;


try {
try {
json = JSON.parse(request.response);
json = JSON.parse(request.response);
} catch (e) {
} catch (e) {
console.log("JSON.parse(): " + e);
console.log("JSON.parse(): " + e);
}
}


if (request.status == 200) {
if (request.status == 200) {
callback(json);
callback(json);
} else if (request.status === 0) {
} else if (request.status === 0) {
set_result(result, "<p class=error>Connection failure" +
set_result(result, "<p class=error>Connection failure" +
"<p class=error-explanation>Are you connected to the Internet?");
"<p class=error-explanation>Are you connected to the Internet?");
} else {
} else {
set_result(result, "<p class=error>Something went wrong" +
set_result(result, "<p class=error>Something went wrong" +
"<p class=error-explanation>The HTTP request produced a response with status code " + request.status + ".");
"<p class=error-explanation>The HTTP request produced a response with status code " + request.status + ".");
}
}
}
}
};
};
request.timeout = 20000;
request.timeout = 20000;
request.ontimeout = function () {
request.ontimeout = function () {
set_result(result, "<p class=error>Connection timed out" +
set_result(result, "<p class=error>Connection timed out" +
"<p class=error-explanation>Are you connected to the Internet?");
"<p class=error-explanation>Are you connected to the Internet?");
};
};
request.send(JSON.stringify(data));
request.send(JSON.stringify(data));
}
}


var PYGMENTS_TO_ACE_MAPPINGS = {
var PYGMENTS_TO_ACE_MAPPINGS = {
'asm': {
'asm': {
'c': 'ace_comment', // Comment,
'c': 'ace_comment', // Comment,
'na': 'ace_support ace_function ace_directive', // Name.Attribute,
'na': 'ace_support ace_function ace_directive', // Name.Attribute,
'no': 'ace_constant', // Name.Constant,
'no': 'ace_constant', // Name.Constant,
'nl': 'ace_entity ace_name ace_function', // Name.Label,
'nl': 'ace_entity ace_name ace_function', // Name.Label,
'nv': 'ace_variable ace_parameter ace_register', // Name.Variable,
'nv': 'ace_variable ace_parameter ace_register', // Name.Variable,
'mh': 'ace_constant ace_character ace_hexadecimal', // Number.Hex,
'mh': 'ace_constant ace_character ace_hexadecimal', // Number.Hex,
'mi': 'ace_constant ace_character ace_decimal', // Number.Integer,
'mi': 'ace_constant ace_character ace_decimal', // Number.Integer,
'p': 'ace_punctuation', // Punctuation,
'p': 'ace_punctuation', // Punctuation,
's': 'ace_string', // String,
's': 'ace_string', // String,
'sc': 'ace_string', // String.Char,
'sc': 'ace_string', // String.Char,
'': '', // Text,
'': '', // Text,
},
},
'llvm-ir': {
'llvm-ir': {
'c': 'ace_comment', // Comment
'c': 'ace_comment', // Comment
'k': 'ace_keyword', // Keyword
'k': 'ace_keyword', // Keyword
'kt': 'ace_storage ace_type', // Keyword.Type
'kt': 'ace_storage ace_type', // Keyword.Type
'nl': 'ace_identifier', // Name.Label
'nl': 'ace_identifier', // Name.Label
'nv': 'ace_variable', // Name.Variable
'nv': 'ace_variable', // Name.Variable
'nv-Anonymous': 'ace_support ace_variable', // Name.Variable.Anonymous
'nv-Anonymous': 'ace_support ace_variable', // Name.Variable.Anonymous
'vg': 'ace_variable ace_other', // Name.Variable.Global
'vg': 'ace_variable ace_other', // Name.Variable.Global
'm': 'ace_constant ace_numeric', // Number
'm': 'ace_constant ace_numeric', // Number
'p': 'ace_punctuation', // Punctuation
'p': 'ace_punctuation', // Punctuation
's': 'ace_string', // String
's': 'ace_string', // String
'': '', // Text
'': '', // Text
}
}
};
};


function rehighlight(pygmentized, language) {
function rehighlight(pygmentized, language) {
var mappings = PYGMENTS_TO_ACE_MAPPINGS[language];
var mappings = PYGMENTS_TO_ACE_MAPPINGS[language];
return pygmentized.replace(/<span class="([^"]*)">([^<]*)<\/span>/g, function () {
return pygmentized.replace(/<span class="([^"]*)">([^<]*)<\/span>/g, function () {
var classes = mappings[arguments[1]];
var classes = mappings[arguments[1]];
if (classes) {
if (classes) {
return '<span class="' + classes + '">' + arguments[2] + '</span>';
return '<span class="' + classes + '">' + arguments[2] + '</span>';
} else {
} else {
return arguments[2];
return arguments[2];
}
}
});
});
}
}


function redrawResult(result) {
function redrawResult(result) {
// Sadly the fun letter-spacing animation can leave artefacts,
// Sadly the fun letter-spacing animation can leave artefacts,
// so we want to manually trigger a redraw. It doesn’t matter
// so we want to manually trigger a redraw. It doesn’t matter
// whether it’s relative or static for now, so we’ll flip that.
// whether it’s relative or static for now, so we’ll flip that.
result.parentNode.style.visibility = "hidden";
result.parentNode.style.visibility = "hidden";
var _ = result.parentNode.offsetHeight; // This empty assignment is intentional
var _ = result.parentNode.offsetHeight; // This empty assignment is intentional
result.parentNode.style.visibility = "";
result.parentNode.style.visibility = "";
}
}


function evaluate(result, code, button) {
function evaluate(result, code, button) {
send("/evaluate.json", {
send("/evaluate.json", {
code: code,
code: code,
separate_output: true,
separate_output: true,
color: true,
color: true,
branch: branch
branch: branch
}, function (object) {
}, function (object) {
var samp, pre, h;
var samp, pre, h;
set_result(result);
set_result(result);
if (object.compiler) {
if (object.compiler) {
h = document.createElement("span");
h = document.createElement("span");
h.className = "output-header";
h.className = "output-header";
h.textContent = "Ponyc Output";
h.textContent = "Ponyc Output";
result.appendChild(h);
result.appendChild(h);


samp = document.createElement("samp");
samp = document.createElement("samp");
samp.innerHTML = formatCompilerOutput(object.compiler);
samp.innerHTML = formatCompilerOutput(object.compiler);
pre = document.createElement("pre");
pre = document.createElement("pre");
pre.classList.add("ponyc-output");
pre.classList.add("ponyc-output");
pre.classList.add("output");
pre.classList.add("output");
pre.appendChild(samp);
pre.appendChild(samp);
result.appendChild(pre);
result.appendChild(pre);
}
}


if (object.stdout) {
if (object.stdout) {
h = document.createElement("span");
h = document.createElement("span");
h.className = "output-header";
h.className = "output-header";
h.textContent = "Standard Output";
h.textContent = "Standard Output";
result.appendChild(h);
result.appendChild(h);


samp = document.createElement("samp");
samp = document.createElement("samp");
samp.className = "output-stdout";
samp.className = "output-stdout";
pre.classList.add("output");
pre.classList.add("output");
samp.innerHTML = formatCompilerOutput(object.stdout);
samp.innerHTML = formatCompilerOutput(object.stdout);
pre = document.createElement("pre");
pre = document.createElement("pre");
pre.appendChild(samp);
pre.appendChild(samp);
result.appendChild(pre);
result.appendChild(pre);
}
}
if (object.stderr) {
if (object.stderr) {
h = document.createElement("span");
h = document.createElement("span");
h.className = "output-header";
h.className = "output-header";
pre.classList.add("output");
pre.classList.add("output");
h.textContent = "Standard Error";
h.textContent = "Standard Error";
result.appendChild(h);
result.appendChild(h);


samp = document.createElement("samp");
samp = document.createElement("samp");
samp.className = "output";
samp.className = "output";
samp.innerHTML = formatCompilerOutput(object.stderr);
samp.innerHTML = formatCompilerOutput(object.stderr);
pre = document.createElement("pre");
pre = document.createElement("pre");
pre.classList.add("output");
pre.classList.add("output");
pre.classList.add("stderr");
pre.classList.add("stderr");
pre.appendChild(samp);
pre.appendChild(samp);
result.appendChild(pre);
result.appendChild(pre);
}
}


var div = document.createElement("p");
var div = document.createElement("p");
div.className = "message";
div.className = "message";
if (object.success) {
if (object.success) {
if (object.stdout || object.stderr) {
if (object.stdout || object.stderr) {
div.textContent = "Program ended.";
div.textContent = "Program ended.";
} else {
} else {
div.textContent = "Program ended with no output.";
div.textContent = "Program ended with no output.";
}
}
} else {
} else {
div.textContent = "Compilation failed.";
div.textContent = "Compilation failed.";
}
}
result.appendChild(div);
result.appendChild(div);
}, button, "Running…", result);
}, button, "Running…", result);
}
}


function compile(emit, result, code, button) {
function compile(emit, result, code, button) {
send("/compile.json", {
send("/compile.json", {
emit: emit,
emit: emit,
code: code,
code: code,
color: true,
color: true,
highlight: true,
highlight: true,
branch: branch
branch: branch
}, function (object) {
}, function (object) {
if ("error" in object) {
if ("error" in object) {
set_result(result, "<pre class=\"rustc-output rustc-errors\"><samp></samp></pre>");
set_result(result, "<pre class=\"rustc-output rustc-errors\"><samp></samp></pre>");
result.firstElementChild.firstElementChild.innerHTML = formatCompilerOutput(object.error);
result.firstElementChild.firstElementChild.innerHTML = formatCompilerOutput(object.error);
} else {
} else {
set_result(result, "<pre class=highlight><code>" + rehighlight(object.result, emit) + "</code></pre>");
set_result(result, "<pre class=highlight><code>" + rehighlight(object.result, emit) + "</code></pre>");
}
}
}, button, "Compiling…", result);
}, button, "Compiling…", result);
}
}


function shareGist(result, code, button) {
function shareGist(result, code, button) {
send("/gist.json", {
send("/gist.json", {
code: code,
code: code,
base_url: PLAYPEN_URL,
base_url: PLAYPEN_URL,
branch: branch,
branch: branch,
}, function (response) {
}, function (response) {
var gist_id = response.gist_id;
var gist_id = response.gist_id;
var gist_url = response.gist_url;
var gist_url = response.gist_url;


var play_url = PLAYPEN_URL + "/?gist=" + encodeURIComponent(gist_id);
var play_url = PLAYPEN_URL + "/?gist=" + encodeURIComponent(gist_id);


if (branch != "release") {
if (branch != "release") {
play_url += "&branch=" + branch;
play_url += "&branch=" + branch;
}
}


set_result(
set_result(
result,
result,
"<p><a href=" + play_url + ">Permalink to the playground</a></p>" +
"<p><a href=" + play_url + ">Permalink to the playground</a></p>" +
"<p><a href=" + gist_url + ">Direct link to the gist</a></p>"
"<p><a href=" + gist_url + ">Direct link to the gist</a></p>"
);
);
}, button, "Creating Gist…", result);
}, button, "Creating Gist…", result);
}
}


function httpRequest(method, url, data, expect, on_success, on_fail) {
function httpRequest(method, url, data, expect, on_success, on_fail) {
var req = new XMLHttpRequest();
var req = new XMLHttpRequest();


req.open(method, url, true);
req.open(method, url, true);
req.onreadystatechange = function () {
req.onreadystatechange = function () {
if (req.readyState == XMLHttpRequest.DONE) {
if (req.readyState == XMLHttpRequest.DONE) {
if (req.status == expect) {
if (req.status == expect) {
if (on_success) {
if (on_success) {
on_success(req.responseText);
on_success(req.responseText);
}
}
} else {
} else {
if (on_fail) {
if (on_fail) {
on_fail(req.status, req.responseText);
on_fail(req.status, req.responseText);
}
}
}
}
}
}
};
};


if (method === "GET") {
if (method === "GET") {
req.send();
req.send();
} else if (method === "POST") {
} else if (method === "POST") {
req.send(data);
req.send(data);
}
}
}
}


function fetchGist(session, result, gist_id, do_evaluate, evaluateButton) {
function fetchGist(session, result, gist_id, do_evaluate, evaluateButton) {
session.setValue("// Loading Gist: https://gist.github.com/" + gist_id + " ...");
session.setValue("// Loading Gist: https://gist.github.com/" + gist_id + " ...");
httpRequest("GET", "https://api.github.com/gists/" + gist_id, null, 200,
httpRequest("GET", "https://api.github.com/gists/" + gist_id, null, 200,
function (response) {
function (response) {
response = JSON.parse(response);
response = JSON.parse(response);
if (response) {
if (response) {
var files = response.files;
var files = response.files;
for (var name in files) {
for (var name in files) {
if (files.hasOwnProperty(name)) {
if (files.hasOwnProperty(name)) {
session.setValue(files[name].content);
session.setValue(files[name].content);


if (do_evaluate) {
if (do_evaluate) {
doEvaluate();
doEvaluate();
}
}
break;
break;
}
}
}
}
}
}
},
},
function (status, response) {
function (status, response) {
set_result(result, "<p class=error>Failed to fetch Gist" +
set_result(result, "<p class=error>Failed to fetch Gist" +
"<p class=error-explanation>Are you connected to the Internet?");
"<p class=error-explanation>Are you connected to the Internet?");
}
}
);
);
}
}


function fetchSnippet(session, result, snippet_file_name, do_evaluate, evaluateButton) {
function fetchSnippet(session, result, snippet_file_name, do_evaluate, evaluateButton, wrap) {
session.setValue("// Loading snippet: https://github.com/ponylang/pony-tutorial/blob/main/code-samples/" + snippet_file_name + " ...");
session.setValue("// Loading snippet: https://github.com/ponylang/pony-tutorial/blob/main/code-samples/" + snippet_file_name + " ...");
httpRequest("GET", "https://raw.githubusercontent.com/ponylang/pony-tutorial/main/code-samples/" + snippet_file_name, null, 200,
httpRequest("GET", "https://raw.githubusercontent.com/ponylang/pony-tutorial/main/code-samples/" + snippet_file_name, null, 200,
function (response) {
function (response) {
session.setValue(response);
if (wrap) {
session.setValue(`
actor Main
new create(env: Env) =>
${response}
`.trim());
} else {
session.setValue(response);
}


if (do_evaluate) {
if (do_evaluate) {
doEvaluate();
doEvaluate();
}
}
},
},
function (status, response) {
function (status, response) {
set_result(result, "<p class=error>Failed to fetch snippet" +
set_result(result, "<p class=error>Failed to fetch snippet" +
"<p class=error-explanation>Are you connected to the Internet?");
"<p class=error-explanation>Are you connected to the Internet?");
}
}
);
);
}
}


function getQueryParameters() {
function getQueryParameters() {
var a = window.location.search.substr(1).split('&');
var a = window.location.search.substr(1).split('&');
if (a === "") return {};
if (a === "") return {};
var b = {};
var b = {};
for (var i = 0; i < a.length; i++) {
for (var i = 0; i < a.length; i++) {
var p = a[i].split('=');
var p = a[i].split('=');
if (p.length != 2) continue;
if (p.length != 2) continue;
b[p[0]] = decodeURIComponent(p[1].replace(/\+/g, " "));
b[p[0]] = decodeURIComponent(p[1].replace(/\+/g, " "));
}
}
return b;
return b;
}
}


function clear_result(result) {
function clear_result(result) {
result.innerHTML = "";
result.innerHTML = "";
result.parentNode.setAttribute("data-empty", "");
result.parentNode.setAttribute("data-empty", "");
set_result.editor.resize();
set_result.editor.resize();
}
}


function set_result(result, contents) {
function set_result(result, contents) {
result.parentNode.removeAttribute("data-empty");
result.parentNode.removeAttribute("data-empty");
if (contents === undefined) {
if (contents === undefined) {
result.textContent = "";
result.textContent = "";
} else if (typeof contents == "string") {
} else if (typeof contents == "string") {
result.innerHTML = contents;
result.innerHTML = contents;
} else {
} else {
result.textContent = "";
result.textContent = "";
result.appendChild(contents);
result.appendChild(contents);
}
}
set_result.editor.resize();
set_result.editor.resize();
}
}


function set_keyboard(editor, mode) {
function set_keyboard(editor, mode) {
if (mode == "Emacs") {
if (mode == "Emacs") {
editor.setKeyboardHandler("ace/keyboard/emacs");
editor.setKeyboardHandler("ace/keyboard/emacs");
} else if (mode == "Vim") {
} else if (mode == "Vim") {
editor.setKeyboardHandler("ace/keyboard/vim");
editor.setKeyboardHandler("ace/keyboard/vim");
if (!set_keyboard.vim_set_up) {
if (!set_keyboard.vim_set_up) {
ace.config.loadModule("ace/keyboard/vim", function (m) {
ace.config.loadModule("ace/keyboard/vim", function (m) {
var Vim = ace.require("ace/keyboard/vim").CodeMirror.Vim;
var Vim = ace.require("ace/keyboard/vim").CodeMirror.Vim;
Vim.defineEx("write", "w", function (cm, input) {
Vim.defineEx("write", "w", function (cm, input) {
cm.ace.execCommand("evaluate");
cm.ace.execCommand("evaluate");
});
});
});
});
}
}
set_keyboard.vim_set_up = true;
set_keyboard.vim_set_up = true;
} else {
} else {
editor.setKeyboardHandler(null);
editor.setKeyboardHandler(null);
}
}
}
}


function set_theme(editor, themelist, theme) {
function set_theme(editor, themelist, theme) {
var themes = document.getElementById("themes");
var themes = document.getElementById("themes");
var themepath = null,
var themepath = null,
i = 0,
i = 0,
themelen = themelist.themes.length,
themelen = themelist.themes.length,
selected = themes.options[themes.selectedIndex];
selected = themes.options[themes.selectedIndex];
if (selected.textContent === theme) {
if (selected.textContent === theme) {
themepath = selected.getAttribute("val");
themepath = selected.getAttribute("val");
} else {
} else {
for (i; i < themelen; i++) {
for (i; i < themelen; i++) {
if (themelist.themes[i].caption == theme) {
if (themelist.themes[i].caption == theme) {
themes.selectedIndex = i;
themes.selectedIndex = i;
themepath = themelist.themes[i].theme;
themepath = themelist.themes[i].theme;
break;
break;
}
}
}
}
}
}
if (themepath !== null) {
if (themepath !== null) {
editor.setTheme(themepath);
editor.setTheme(themepath);
optionalLocalStorageSetItem("theme", theme);
optionalLocalStorageSetItem("theme", theme);
}
}
}
}


function getRadioValue(name) {
function getRadioValue(name) {
var nodes = document.getElementsByName(name);
var nodes = document.getElementsByName(name);
for (var i = 0; i < nodes.length; i++) {
for (var i = 0; i < nodes.length; i++) {
var node = nodes[i];
var node = nodes[i];
if (node.checked) {
if (node.checked) {
return node.value;
return node.value;
}
}
}
}
}
}


var evaluateButton;
var evaluateButton;
var asmButton;
var asmButton;
var irButton;
var irButton;
var formatButton;
var formatButton;
var gistButton;
var gistButton;
var configureEditorButton;
var configureEditorButton;
var result;
var result;
var clearResultButton;
var clearResultButton;
var keyboard;
var keyboard;
var themes;
var themes;
var editor;
var editor;
var session;
var session;
var themelist;
var themelist;
var theme;
var theme;
var mode;
var mode;
var query;
var query;


function doEvaluate() {
function doEvaluate() {
var code = session.getValue();
var code = session.getValue();
evaluate(result, session.getValue(), evaluateButton);
evaluate(result, session.getValue(), evaluateButton);
}
}


var COLOR_CODES = ['black', 'red', 'green', 'yellow', 'blue', 'magenta', 'cyan', 'white'];
var COLOR_CODES = ['black', 'red', 'green', 'yellow', 'blue', 'magenta', 'cyan', 'white'];


// A simple function to decode ANSI escape codes into HTML.
// A simple function to decode ANSI escape codes into HTML.
// This is very basic, with lots of very obvious omissions and holes;
// This is very basic, with lots of very obvious omissions and holes;
// it’s designed purely to cope with rustc output.
// it’s designed purely to cope with rustc output.
//
//
// TERM=xterm rustc uses these:
// TERM=xterm rustc uses these:
//
//
// - bug/fatal/error = red
// - bug/fatal/error = red
// - warning = yellow
// - warning = yellow
// - note = green
// - note = green
// - help = cyan
// - help = cyan
// - error code = magenta
// - error code = magenta
// - bold
// - bold
function ansi2html(text) {
function ansi2html(text) {
return text.replace(/&/g, '&amp;')
return text.replace(/&/g, '&amp;')
.replace(/</g, '&lt;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/>/g, '&gt;')
.replace(/\x1b\[1m\x1b\[3([0-7])m([^\x1b]*)(?:\x1b\(B)?\x1b\[0?m/g, function (original, colorCode, text) {
.replace(/\x1b\[1m\x1b\[3([0-7])m([^\x1b]*)(?:\x1b\(B)?\x1b\[0?m/g, function (original, colorCode, text) {
return '<span class=ansi-' + COLOR_CODES[+colorCode] + '><strong>' + text + '</strong></span>';
return '<span class=ansi-' + COLOR_CODES[+colorCode] + '><strong>' + text + '</strong></span>';
}).replace(/\x1b\[3([0-7])m([^\x1b]*)(?:\x1b\(B)?\x1b\[0?m/g, function (original, colorCode, text) {
}).replace(/\x1b\[3([0-7])m([^\x1b]*)(?:\x1b\(B)?\x1b\[0?m/g, function (original, colorCode, text) {
return '<span class=ansi-' + COLOR_CODES[+colorCode] + '>' + text + '</span>';
return '<span class=ansi-' + COLOR_CODES[+colorCode] + '>' + text + '</span>';
}).replace(/\x1b\[1m([^\x1b]*)(?:\x1b\(B)?\x1b\[0?m/g, function (original, text) {
}).replace(/\x1b\[1m([^\x1b]*)(?:\x1b\(B)?\x1b\[0?m/g, function (original, text) {
return "<strong>" + text + "</strong>";
return "<strong>" + text + "</strong>";
}).replace(/(?:\x1b\(B)?\x1b\[0?m/g, '');
}).replace(/(?:\x1b\(B)?\x1b\[0?m/g, '');
}
}


//This affects how mouse acts on the program output.
//This affects how mouse acts on the program output.
//Screenshots here: https://github.com/rust-lang/rust-playpen/pull/192#issue-145465630
//Screenshots here: https://github.com/rust-lang/rust-playpen/pull/192#issue-145465630
//If mouse hovers on eg. "<anon>:3", temporarily show that line(3) into view by
//If mouse hovers on eg. "<anon>:3", temporarily show that line(3) into view by
//selecting it entirely and move editor's cursor to the beginning of it;
//selecting it entirely and move editor's cursor to the beginning of it;
//Moves back to original view when mouse moved away.
//Moves back to original view when mouse moved away.
//If mouse left click on eg. "<anon>:3" then the editor's cursor is moved
//If mouse left click on eg. "<anon>:3" then the editor's cursor is moved
//to the beginning of that line
//to the beginning of that line
function jumpToLine(text, r1) {
function jumpToLine(text, r1) {
return "<a onclick=\"javascript:editGo(" + r1 + ",1)\"" +
return "<a onclick=\"javascript:editGo(" + r1 + ",1)\"" +
" onmouseover=\"javascript:editShowLine(" + r1 + ")\"" +
" onmouseover=\"javascript:editShowLine(" + r1 + ")\"" +
" onmouseout=\"javascript:editRestore()\"" +
" onmouseout=\"javascript:editRestore()\"" +
" class=\"linejump\">" + text + "</a>";
" class=\"linejump\">" + text + "</a>";
}
}


//Similarly to jumpToLine, except this one acts on eg. "<anon>:2:31: 2:32"
//Similarly to jumpToLine, except this one acts on eg. "<anon>:2:31: 2:32"
//and thus selects a region on mouse hover, or when clicked sets cursor to
//and thus selects a region on mouse hover, or when clicked sets cursor to
//the beginning of region.
//the beginning of region.
function jumpToRegion(text, r1, c1, r2, c2) {
function jumpToRegion(text, r1, c1, r2, c2) {
return "<a onclick=\"javascript:editGo(" + r1 + "," + c1 + ")\"" +
return "<a onclick=\"javascript:editGo(" + r1 + "," + c1 + ")\"" +
" onmouseover=\"javascript:editShowRegion(" + r1 + "," + c1 + ", " + r2 + "," + c2 + ")\"" +
" onmouseover=\"javascript:editShowRegion(" + r1 + "," + c1 + ", " + r2 + "," + c2 + ")\"" +
" onmouseout=\"javascript:editRestore()\"" +
" onmouseout=\"javascript:editRestore()\"" +
" class=\"linejump\">" + text + "</a>";
" class=\"linejump\">" + text + "</a>";
}
}


//Similarly to jumpToLine, except this one acts on eg. "<anon>:2:31"
//Similarly to jumpToLine, except this one acts on eg. "<anon>:2:31"
function jumpToPoint(text, r1, c1) {
function jumpToPoint(text, r1, c1) {
return "<a onclick=\"javascript:editGo(" + r1 + "," + c1 + ")\"" +
return "<a onclick=\"javascript:editGo(" + r1 + "," + c1 + ")\"" +
" onmouseover=\"javascript:editShowPoint(" + r1 + "," + c1 + ")\"" +
" onmouseover=\"javascript:editShowPoint(" + r1 + "," + c1 + ")\"" +
" onmouseout=\"javascript:editRestore()\"" +
" onmouseout=\"javascript:editRestore()\"" +
" class=\"linejump\">" + text + "</a>";
" class=\"linejump\">" + text + "</a>";
}
}


function formatCompilerOutput(text) {
function formatCompilerOutput(text) {
return ansi2html(text)
return ansi2html(text)
.replace(/\/.*\/main.pony/mg, "main.pony")
.replace(/\/.*\/main.pony/mg, "main.pony")
.replace(/\/usr\/local\/lib\/pony\/[^\/]*\//mg, "")
.replace(/\/usr\/local\/lib\/pony\/[^\/]*\//mg, "")
.replace(/main\.pony:(\d+):(\d+)/mg, jumpToPoint);
.replace(/main\.pony:(\d+):(\d+)/mg, jumpToPoint);
}
}


addEventListener("DOMContentLoaded", function () {
addEventListener("DOMContentLoaded", function () {
evaluateButton = document.getElementById("evaluate");
evaluateButton = document.getElementById("evaluate");
asmButton = document.getElementById("asm");
asmButton = document.getElementById("asm");
irButton = document.getElementById("llvm-ir");
irButton = document.getElementById("llvm-ir");
formatButton = document.getElementById("format");
formatButton = document.getElementById("format");
gistButton = document.getElementById("gist");
gistButton = document.getElementById("gist");
configureEditorButton = document.getElementById("configure-editor");
configureEditorButton = document.getElementById("configure-editor");
result = document.getElementById("result").firstElementChild;
result = document.getElementById("result").firstElementChild;
clearResultButton = document.getElementById("clear-result");
clearResultButton = document.getElementById("clear-result");
keyboard = document.getElementById("keyboard");
keyboard = document.getElementById("keyboard");
themes = document.getElementById("themes");
themes = document.getElementById("themes");
editor = ace.edit("editor");
editor = ace.edit("editor");
set_result.editor = editor;
set_result.editor = editor;
editor.$blockScrolling = Infinity;
editor.$blockScrolling = Infinity;
editor.setAnimatedScroll(true);
editor.setAnimatedScroll(true);
session = editor.getSession();
session = editor.getSession();
themelist = ace.require("ace/ext/themelist");
themelist = ace.require("ace/ext/themelist");
window.branch = "release"
window.branch = "release"


editor.focus();
editor.focus();


build_themes(themelist);
build_themes(themelist);


editor.renderer.on('themeChange', function (e) {
editor.renderer.on('themeChange', function (e) {
var path = e.theme;
var path = e.theme;
ace.config.loadModule(['theme', e.theme], function (t) {
ace.config.loadModule(['theme', e.theme], function (t) {
document.getElementById("result").className = t.cssClass + (t.isDark ? " ace_dark" : "");
document.getElementById("result").className = t.cssClass + (t.isDark ? " ace_dark" : "");
});
});
});
});


theme = optionalLocalStorageGetItem("theme");
theme = optionalLocalStorageGetItem("theme");
if (theme === null) {
if (theme === null) {
set_theme(editor, themelist, "GitHub");
set_theme(editor, themelist, "GitHub");
} else {
} else {
set_theme(editor, themelist, theme);
set_theme(editor, themelist, theme);
}
}


session.setMode("ace/mode/pony");
session.setMode("ace/mode/pony");


// Match the tab style of the Pony standard library.
// Match the tab style of the Pony standard library.
session.setTabSize(2);
session.setTabSize(2);
session.setUseSoftTabs(true);
session.setUseSoftTabs(true);


mode = optionalLocalStorageGetItem("keyboard");
mode = optionalLocalStorageGetItem("keyboard");
if (mode !== null) {
if (mode !== null) {
set_keyboard(editor, mode);
set_keyboard(editor, mode);
keyboard.value = mode;
keyboard.value = mode;
}
}


query = getQueryParameters();
query = getQueryParameters();
if ("code" in query) {
if ("code" in query) {
session.setValue(query.code);
session.setValue(query.code);
} else if ("gist" in query) {
} else if ("gist" in query) {
// fetchGist() must defer evaluation until after the content has been loaded
// fetchGist() must defer evaluation until after the content has been loaded
fetchGist(session, result, query.gist, query.run === "1", evaluateButton);
fetchGist(session, result, query.gist, query.run === "1", evaluateButton);
query.run = 0;
query.run = 0;
} else if ("snippet" in query) {
} else if ("snippet" in query) {
// fetchSnippet() must defer evaluation until after the content has been loaded
// fetchSnippet() must defer evaluation until after the content has been loaded
fetchSnippet(session, result, query.snippet, query.run === "1", evaluateButton);
fetchSnippet(session, result, query.snippet, query.run === "1", evaluateButton, query.wrap === '1');
query.run = 0;
query.run = 0;
} else {
} else {
var code = optionalLocalStorageGetItem("code");
var code = optionalLocalStorageGetItem("code");
if (code !== null) {
if (code !== null) {
session.setValue(code);
session.setValue(code);
}
}
}
}


if ("branch" in query) {
if ("branch" in query) {
branch = query.branch
branch = query.branch
}
}


if (query.run === "1") {
if (query.run === "1") {
doEvaluate();
doEvaluate();
}
}


addEventListener("resize", function () {
addEventListener("resize", function () {
editor.resize();
editor.resize();
});
});


//This helps re-focus editor after a Run or any other action that caused
//This helps re-focus editor after a Run or any other action that caused
//editor to lose focus. Just press Enter or Esc key to focus editor.
//editor to lose focus. Just press Enter or Esc key to focus editor.
//Without this, you'd most likely have to LMB somewhere in the editor
//Without this, you'd most likely have to LMB somewhere in the editor
//area which would change the location of its cursor to where you clicked.
//area which would change the location of its cursor to where you clicked.
addEventListener("keyup", function (e) {
addEventListener("keyup", function (e) {
if ((document.body == document.activeElement) && //needed to avoid when editor has focus already
if ((document.body == document.activeElement) && //needed to avoid when editor has focus already
(13 == e.keyCode || 27 == e.keyCode)) { //Enter or Escape keys
(13 == e.keyCode || 27 == e.keyCode)) { //Enter or Escape keys
editor.focus();
editor.focus();
}
}
});
});


session.on("change", function () {
session.on("change", function () {
var code = session.getValue();
var code = session.getValue();
optionalLocalStorageSetItem("code", code);
optionalLocalStorageSetItem("code", code);
});
});


keyboard.onkeyup = keyboard.onchange = function () {
keyboard.onkeyup = keyboard.onchange = function () {
var mode = keyboard.options[keyboard.selectedIndex].value;
var mode = keyboard.options[keyboard.selectedIndex].value;
optionalLocalStorageSetItem("keyboard", mode);
optionalLocalStorageSetItem("keyboard", mode);
set_keyboard(editor, mode);
set_keyboard(editor, mode);
};
};


evaluateButton.onclick = function () {
evaluateButton.onclick = function () {
doEvaluate(true);
doEvaluate(true);
editor.focus();
editor.focus();
};
};


editor.commands.addCommand({
editor.commands.addCommand({
name: "evaluate",
name: "evaluate",
exec: evaluateButton.onclick,
exec: evaluateButton.onclick,
bindKey: { win: "Ctrl-Enter", mac: "Ctrl-Enter" }
bindKey: { win: "Ctrl-Enter", mac: "Ctrl-Enter" }
});
});


// ACE uses the "cstyle" behaviour for all languages by default, which
// ACE uses the "cstyle" behaviour for all languages by default, which
// gives us nice things like quote and paren autopairing. However this
// gives us nice things like quote and paren autopairing. However this
// also autopairs single quotes, which makes writing lifetimes annoying.
// also autopairs single quotes, which makes writing lifetimes annoying.
// To avoid having to duplicate the other functionality provided by the
// To avoid having to duplicate the other functionality provided by the
// cstyle behaviour, we work around this situation by hijacking the
// cstyle behaviour, we work around this situation by hijacking the
// single quote as a hotkey and modifying the document ourselves, which
// single quote as a hotkey and modifying the document ourselves, which
// does not trigger this behaviour.
// does not trigger this behaviour.
editor.commands.addCommand({
editor.commands.addCommand({
name: "rust_no_single_quote_autopairing",
name: "rust_no_single_quote_autopairing",
exec: function (editor, line) {
exec: function (editor, line) {
var sess = editor.getSession();
var sess = editor.getSession();
var doc = sess.getDocument();
var doc = sess.getDocument();
var selection = sess.getSelection();
var selection = sess.getSelection();
var ranges = selection.getAllRanges();
var ranges = selection.getAllRanges();
var prev_range = null;
var prev_range = null;


// no selection = zero width range, so we don't need to handle this case specially
// no selection = zero width range, so we don't need to handle this case specially
// start from the back, so changes to earlier ranges don't invalidate later ranges
// start from the back, so changes to earlier ranges don't invalidate later ranges
for (var i = ranges.length - 1; i >= 0; i--) {
for (var i = ranges.length - 1; i >= 0; i--) {
// sanity check: better to do no modification than to do something wrong
// sanity check: better to do no modification than to do something wrong
// see the compareRange docs:
// see the compareRange docs:
// https://github.com/ajaxorg/ace/blob/v1.2.6/lib/ace/range.js#L106-L120
// https://github.com/ajaxorg/ace/blob/v1.2.6/lib/ace/range.js#L106-L120
if (prev_range && prev_range.compareRange(ranges[i]) != -2) {
if (prev_range && prev_range.compareRange(ranges[i]) != -2) {
console.log("ranges intersect or are not in ascending order, skipping",
console.log("ranges intersect or are not in ascending order, skipping",
ranges[i]);
ranges[i]);
}
}
prev_range = ranges[i];
prev_range = ranges[i];


doc.replace(ranges[i], "'");
doc.replace(ranges[i], "'");
}
}
// the selection contents were replaced, so clear the selection
// the selection contents were replaced, so clear the selection
selection.clearSelection();
selection.clearSelection();
},
},
bindKey: { win: "'", mac: "'" },
bindKey: { win: "'", mac: "'" },
});
});


// We’re all pretty much agreed that such an obscure command as transposing
// We’re all pretty much agreed that such an obscure command as transposing
// letters hogging Ctrl-T, normally “open new tab”, is a bad thing.
// letters hogging Ctrl-T, normally “open new tab”, is a bad thing.
var transposeletters = editor.commands.commands.transposeletters;
var transposeletters = editor.commands.commands.transposeletters;
editor.commands.removeCommand("transposeletters");
editor.commands.removeCommand("transposeletters");
delete transposeletters.bindKey;
delete transposeletters.bindKey;
editor.commands.addCommand(transposeletters);
editor.commands.addCommand(transposeletters);


asmButton.onclick = function () {
asmButton.onclick = function () {
compile("asm", result, session.getValue(), asmButton);
compile("asm", result, session.getValue(), asmButton);
};
};


irButton.onclick = function () {
irButton.onclick = function ()
compile("llvm-ir", result, session.getValue(), irButton);
};

gistButton.onclick = function () {
shareGist(result, sessio