<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Lilly's DNA thing</title>
<link rel="icon" type="image/png" href="/images/favicon.png" />
<link rel="stylesheet" type="text/css" href="/css" />
<style type="text/css">
html, body { height: 100%; }
body * { font-size: 1.45em; color: #fff; background: #000; }
div { text-align: center; }
textarea { display: block; width: 100%; border: 2px inset; height: 90%; }
button { font-size: 1em; border: 2px outset; margin: 5px 0px; padding: 0px 5px; }
</style>
<script type="text/javascript">
var textarea, complement, transcribe, translate, sequence, reverse, data;
var codons = [
"uuu", "uuc", "uua", "uug", "cuu", "cuc", "cua", "cug",
"auu", "auc", "aua", "aug", "guu", "guc", "gua", "gug",
"ucu", "ucc", "uca", "ucg", "ccu", "ccc", "cca", "ccg",
"acu", "acc", "aca", "acg", "gcu", "gcc", "gca", "gcg",
"uau", "uac", "uaa", "uag", "uga", "cau", "cac", "caa",
"cag", "aau", "aac", "aaa", "aag", "gau", "gac", "gaa",
"gag", "ugu", "ugc", "ugg", "cgu", "cgc", "cga", "cgg",
"aga", "agg", "agu", "agc", "ggu", "ggc", "gga", "ggg"
];
var aminos = [
"Phe", "Phe", "Leu", "Leu", "Leu", "Leu", "Leu", "Leu",
"Ile", "Ile", "Ile", "Met", "Val", "Val", "Val", "Val",
"Ser", "Ser", "Ser", "Ser", "Pro", "Pro", "Pro", "Pro",
"Thr", "Thr", "Thr", "Thr", "Ala", "Ala", "Ala", "Ala",
"Tyr", "Tyr", "Stp", "Stp", "Stp", "His", "His", "Gln",
"Gln", "Asn", "Asn", "Lys", "Lys", "Asp", "Asp", "Glu",
"Glu", "Cys", "Cys", "Trp", "Arg", "Arg", "Arg", "Arg",
"Arg", "Arg", "Ser", "Ser", "Gly", "Gly", "Gly", "Gly"
];
var isAminos = _ => -1 < aminos.indexOf(
textarea.value.replaceAll(/[ 0-9]/g, "").match(/.../)[0]
);
var formatBasePairs = input => {
input = input.match(/(.{0,9})/g).join(" ").match(/(.{0,70} ?)/g).filter(l => l.length);
var output = [];
for (var i = 0; i < input.length; i++)
output.push(((63 * i + 1) + " ").padStart(10, " ") + input[i]);
return output.join("\n");
};
var deformatBasePairs = input => input.replaceAll(/[^TGUACtguac]/g, "");
var convert = q => {
// bool q = true = convert from DNA to RNA (or RNA to DNA)
// bool q = false = just complement DNA or RNA, do not convert
if (isAminos()) return;
textarea.value = (s => q ^ !!s.match(/[uU]/)
? s
.replaceAll(/t/g, 'a').replaceAll(/T/g, 'A')
.replaceAll(/u/g, 'a').replaceAll(/U/g, 'A')
.replaceAll(/x/g, 'u').replaceAll(/X/g, 'U')
: s
.replaceAll(/t/g, 'a').replaceAll(/T/g, 'A')
.replaceAll(/u/g, 'a').replaceAll(/U/g, 'A')
.replaceAll(/x/g, 't').replaceAll(/X/g, 'T')
)(textarea.value
.replaceAll(/g/g, 'x').replaceAll(/G/g, 'X')
.replaceAll(/c/g, 'g').replaceAll(/C/g, 'G')
.replaceAll(/x/g, 'c').replaceAll(/X/g, 'C')
.replaceAll(/a/g, 'x').replaceAll(/A/g, 'X')
);
textarea.oninput();
};
onload = _ => {
data = document.querySelector("#data");
textarea = document.querySelector("textarea");
complement = document.querySelector("#complement");
transcribe = document.querySelector("#transcribe");
translate = document.querySelector("#translate");
sequence = document.querySelector("#sequence");
reverse = document.querySelector("#reverse");
complement.onclick = _ => { convert(false); };
transcribe.onclick = _ => { convert(true); };
translate.onclick = _ => {
if (isAminos()) return;
textarea.value = textarea.value.toLowerCase().replaceAll(/t/g, 'u')
.replaceAll(/[^gcau]/g, "").match(/(...)/g)
.map(c => aminos[codons.indexOf(c)]).join("");
textarea.oninput();
};
sequence.onclick = _ => {
if (!isAminos()) return;
var input = textarea.value.replaceAll(/[0-9 ]/g, "").match(/(...)/g)
.map(a => codons[Math.floor(Math.random()
* (aminos.lastIndexOf(a) - aminos.indexOf(a)))
+ aminos.indexOf(a)]).join("").match(/(.{0,10})/g)
.join(" ").match(/(.{0,66} ?)/g);
var output = [];
for (var i = 0; i < input.length; i++) {
output.push(((60 * i + 1) + " ").padStart(10, " ") + input[i]);
}
textarea.value = output.join("\n");
textarea.oninput();
};
reverse.onclick = _ => {
if (isAminos()) return;
textarea.value = formatBasePairs(
textarea.value.replaceAll(/[^GCAUTgcaut]/g, "")
.split("").reverse().join("")
);
textarea.oninput();
};
textarea.oninput = _ => {
var w = textarea.value.replaceAll(/[^a-zA-Z]/g, "").length
data.innerHTML = w + " base pairs, " + Math.floor(w / 3)
+ " codons (" + (w % 3) + " trailing base pairs)";
textarea.value = formatBasePairs(isAminos()
? textarea.value.replaceAll(/[\W\d]/g, "")
: deformatBasePairs(textarea.value));
};
textarea.oninput();
};
</script>
</head>
<body>
<div id="data"></div>
<textarea>
ctggtctggccggcgacgcgcgtgccctgtggccaaacactgcctggagtgagagcaaac
taccagcgcagtggggccggcgcgagtgtgcgtgtgtgtgcgtgtgtgtgtgcgagcgcg
gtggaggggggggaccaactgcttcacactttcaacactgcactgaagagggagagcgag
agagagactggagacgcacagatccccccaaggtctcccaagcctaccgtcccacagatt
attgtacagagccccaaaaatcgaaacagaggaaacgaacagcagttgaacatggacgaa
ggaattcctcatttgcaagagagacagttactggaacatagagattttataggactggac
tattcctctttgtatatgtgtaaacccaaaaggagcatgaaacgagacgacaccaaggat
acctacaaattaccgcacagattaatagaaaagaaaagaagagaccgaattaatgaatgc
attgctcagctgaaagatttactgcctgaacatctgaaattgacaactctgggacatctg
gagaaagctgtagtcttggaattaactttgaaacacttaaaagctttaaccgccttaacc
gagcaacagcatcagaagataattgctttacagaatggggagcgatctctgaaatcgccc
attcagtccgacttggatgcgttccactcgggatttcaaacatgcgccaaagaagtcttg
caatacctctcccggtttgagagctggacacccagggagccgcggtgtgtccagctgatc
aaccacttgcacgccgtggccacccagttcttgcccaccccgcagctgttgactcaacag
gtccctctgagcaaaggcaccggcgctccctcggccgccgggtccgcggccgccccctgc
ctggagcgcgcggggcagaagctggagcccctcgcctactgcgtgcccgtcatccagcgg
actcagcccagcgccgagctcgccgccgagaacgacacggacaccgacagcggctacggc
ggcgaagccgaggcccggccggaccgcgagaaaggcaaaggcgcgggggcgagccgcgtc
accatcaagcaggagcctcccggggaggactcgccggcgcccaagaggatgaagctggat
tcccgcggcggcggcagcggcggcggcccggggggcggcgcggtggcggcggcagccgcg
cttctggggcccgaccctgccgccgcggccgcgctgctgagacccgacgccgccctgctc
agctcgctggtggcgttcggcggaggcggaggcgcgcccttcccgcagcccgcggccgcc
gcggcccccttctgcctgcccttctgcttcctctcgccttctgcagctgccgcctacgtg
cagcccttcctggacaagagcggcctggagaagtatctgtacccggcggcggctgccgcc
ccgttcccgctgctataccccggcatccccgccccggcggcagccgcggcagccgccgcc
gccgctgccgccgccgccgccgcgttcccctgcctgtcctcggtgttgtcgccccctccc
gagaaggcgggcgccgccgccgcgaccctcctgccgcacgaggtggcgccccttggggcg
ccgcacccccagcacccgcacggccgcacccacctgcccttcgccgggccccgcgagccg
gggaacccggagagctctgctcaggaagatccctcgcagccaggaaaggaagctccctga
atccttgcgtcccgaaggacggaggttcaagcagagtgagaagttaaaatacccttaagg
aggttcaagcagagtgagaagttaaaatacccttaaggtctttaagggaggaagtgtaat
agatgcacgacaggcataaacaagaacaacaaaacaggtgttatgtgtacattcggagtt
cctgttttgctcatcccgcaccaccccaccctccacacactaacatccctttcttccccc
caccagctgtaaaagatcctatgcgaaagacactggctcttttttttaatcccccaaata
aattttgcccccttttaggccatgttccattatctcttaaaattggaacctaattcgaga
ggaagtaagaagggtctgttctgtggctgagctaggtgaaccccggggtaggggaaagat
gttaacacctttgacgtctttggagttgacatggaacagcaggtagttgttatgtagagc
tagttctcaaagctgccctgcctgttttaggaggcgttccacaaacagattgaggctctt
ttagaattgaatttactcttcagtattttctaatgttcagctttctaaaaggcatatatt
tttcaaagaagtgaggatgcagtttctcacgttgcaacctattctgaagtggtttaaatg
gtatctcttagtaacttgcactcgttaaagaaacacggagctgggccatcgtcagaacta
agtcagggaaggagatggatgagaaggccagaatcattcctagtacatttgctaacactt
tattgagaaattgaccatgaattaatggactcatcttaatttcttctaagtccatatata
gatagatatctatctgtacagatttctatttatccatagataggtatctatacatacaca
tctcaagtgcatctattcccactctcattaatccatcatgttcctaaatttttgtaatct
tactgtaaaaaaaagtgcactgaacttcaaaacaaaacaaaaaacaacaacaacaaaaaa
caagtccaaactgatatatcctatattctgttaaaattcaaaagtgaacgaaagcattta
actggccagttttgattgcaaatgctgtaaagatatagaatgaagtcctgtgaggccttc
ctatctccaagtctatgtattttctggagaccaaaccagataccagataatcacaaagaa
agcttttttaataaggcttaaaccaagaccttgtctagatatttttagtttgttgccaag
gtagcactgtgagaaatctcacttggatgttatgtaaggggtgagacacaacagtctgac
tatgagtgaggaaaatatctgggtcttttcgtcagtttggtgcatttgctgctgctgttg
ctactgtttgcctcaaacgctgtgtttaaacaacgttaaactcttagcctacaaggtggc
tcttatgtacatagttgttaatacatccaattaatgatgtctgacatgctatttttgtag
ggagaaaatatgtgctaatgatattttgagttaaaatatcttttggggaggatttgctga
aaagttgcacttttgttacaatgcttatgcttggtacaagcttatgctgtcttaaattat
tttaaaaaaataaatactgtctgtgagaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaa
</textarea>
<div>
<button id="complement" title="Convert from GCTA to CGAT (or GCUA to CGAU)">Complement</button>
<button id="transcribe" title="Convert from GCTA to CGAU (or GCUA to CGAT)">Transcribe</button>
<button id="translate" title="Decode codons into amino acids (WARNING: Discards trailing base pairs!)">Translate</button>
<button id="sequence" title="Encode amino acids into codons">Sequence</button>
<button id="reverse" title="Reverse textarea">Reverse</button>
</div>
</body>
</html>