Moved loads of stuff
This commit is contained in:
41
src/blocks/affineDecrypt.js
Normal file
41
src/blocks/affineDecrypt.js
Normal file
@ -0,0 +1,41 @@
|
||||
module.exports = {
|
||||
name: "Affine Decrypt",
|
||||
inputs: {
|
||||
text: "Text",
|
||||
a: "a",
|
||||
b: "b"
|
||||
},
|
||||
output: true,
|
||||
execute: function({text, a, b}, elem){
|
||||
a = parseInt(a);
|
||||
b = parseInt(b);
|
||||
|
||||
if(isNaN(a)){
|
||||
return "";
|
||||
}
|
||||
if(isNaN(b)){
|
||||
return "";
|
||||
}
|
||||
|
||||
if(!require("./util/coPrime.js")(a, 26)){
|
||||
console.log(a, 26, "not coprime");
|
||||
return "";
|
||||
}
|
||||
|
||||
var reverseLookupTable = [];
|
||||
for(var i = 0; i < 26; i++){
|
||||
reverseLookupTable[((a * i) + b)%26] = i;
|
||||
}
|
||||
|
||||
return text
|
||||
.split("")
|
||||
.map(require("./util/toNum.js"))
|
||||
.map((num)=>(reverseLookupTable[num]))
|
||||
.map(require("./util/toChar.js"))
|
||||
.join("");
|
||||
},
|
||||
pageBlock: {
|
||||
html: "",
|
||||
js: function(){}
|
||||
}
|
||||
}
|
41
src/blocks/affineEncrypt.js
Normal file
41
src/blocks/affineEncrypt.js
Normal file
@ -0,0 +1,41 @@
|
||||
module.exports = {
|
||||
name: "Affine Encrypt",
|
||||
inputs: {
|
||||
text: "Text",
|
||||
a: "a",
|
||||
b: "b"
|
||||
},
|
||||
output: true,
|
||||
execute: function({text, a, b}, elem){
|
||||
a = parseInt(a);
|
||||
b = parseInt(b);
|
||||
|
||||
if(isNaN(a)){
|
||||
return "";
|
||||
}
|
||||
if(isNaN(b)){
|
||||
return "";
|
||||
}
|
||||
|
||||
if(!require("./util/coPrime.js")(a, 26)){
|
||||
return "";
|
||||
console.log(a, 26, "not coprime");
|
||||
}
|
||||
|
||||
var lookupTable = [];
|
||||
for(var i = 0; i < 26; i++){
|
||||
lookupTable[i] = ((a * i) + b)%26;
|
||||
}
|
||||
|
||||
return text
|
||||
.split("")
|
||||
.map(require("./util/toNum.js"))
|
||||
.map((num)=>(lookupTable[num]))
|
||||
.map(require("./util/toChar.js"))
|
||||
.join("");
|
||||
},
|
||||
pageBlock: {
|
||||
html: "",
|
||||
js: function(){}
|
||||
}
|
||||
}
|
18
src/blocks/asciiToHex.js
Normal file
18
src/blocks/asciiToHex.js
Normal file
@ -0,0 +1,18 @@
|
||||
module.exports = {
|
||||
name: "ASCII to Hex",
|
||||
inputs: {
|
||||
text: "Text"
|
||||
},
|
||||
output: true,
|
||||
execute: function({text}, elem){
|
||||
return text
|
||||
.split("")
|
||||
.map((char)=>(char.charCodeAt(0)))
|
||||
.map((int)=>(int.toString(16)))
|
||||
.join("");
|
||||
},
|
||||
pageBlock: {
|
||||
html: "",
|
||||
js: function(){}
|
||||
}
|
||||
}
|
26
src/blocks/atbash.js
Normal file
26
src/blocks/atbash.js
Normal file
@ -0,0 +1,26 @@
|
||||
module.exports = {
|
||||
name: "Atbash",
|
||||
inputs: {
|
||||
text: "Text"
|
||||
},
|
||||
output: true,
|
||||
execute: function({text}, elem){
|
||||
return text
|
||||
.split("")
|
||||
.map(require("./util/toNum.js"))
|
||||
.map((num)=>{
|
||||
if(Number.isInteger(num)){
|
||||
return 25 - num;
|
||||
}
|
||||
else{
|
||||
return num;
|
||||
}
|
||||
})
|
||||
.map(require("./util/toChar.js"))
|
||||
.join("")
|
||||
},
|
||||
pageBlock: {
|
||||
html: "",
|
||||
js: function(){}
|
||||
}
|
||||
}
|
34
src/blocks/caesar.js
Normal file
34
src/blocks/caesar.js
Normal file
@ -0,0 +1,34 @@
|
||||
module.exports = {
|
||||
name: "Caesar",
|
||||
inputs: {
|
||||
text: "Text",
|
||||
shift: "Shift"
|
||||
},
|
||||
output: true,
|
||||
execute: function({text, shift}, elem){
|
||||
if(!isNaN(parseInt(shift))){
|
||||
shift = parseInt(shift);
|
||||
}
|
||||
else{
|
||||
shift = 0;
|
||||
}
|
||||
|
||||
return text
|
||||
.split("")
|
||||
.map(require("./util/toNum.js"))
|
||||
.map((num)=>{
|
||||
if(Number.isInteger(num)){
|
||||
return ((num + shift)%26 + 26)%26;
|
||||
}
|
||||
else{
|
||||
return num;
|
||||
}
|
||||
})
|
||||
.map(require("./util/toChar.js"))
|
||||
.join("");
|
||||
},
|
||||
pageBlock: {
|
||||
html: "",
|
||||
js: function(){}
|
||||
}
|
||||
}
|
15
src/blocks/concat.js
Normal file
15
src/blocks/concat.js
Normal file
@ -0,0 +1,15 @@
|
||||
module.exports = {
|
||||
name: "Concat",
|
||||
inputs: {
|
||||
str1: "String 1",
|
||||
str2: "String 2"
|
||||
},
|
||||
output: true,
|
||||
execute: function({str1, str2}, block){
|
||||
return str1 + str2;
|
||||
},
|
||||
pageBlock: {
|
||||
html: "",
|
||||
js: function(){}
|
||||
}
|
||||
}
|
18
src/blocks/elementsToNumbers.js
Normal file
18
src/blocks/elementsToNumbers.js
Normal file
@ -0,0 +1,18 @@
|
||||
module.exports = {
|
||||
name: "Elements to Numbers",
|
||||
inputs: {
|
||||
elements: "Elements"
|
||||
},
|
||||
output: true,
|
||||
execute: function({elements}, elem){
|
||||
return elements
|
||||
.split(",")
|
||||
.map((element)=>(require("./util/elements.js").indexOf(element.toLowerCase()) + 1))
|
||||
.filter((num)=>(num > 0))
|
||||
.join(",");
|
||||
},
|
||||
pageBlock: {
|
||||
html: "",
|
||||
js: function(){}
|
||||
}
|
||||
}
|
164
src/blocks/frequency.js
Normal file
164
src/blocks/frequency.js
Normal file
@ -0,0 +1,164 @@
|
||||
var events = require("../events.js");
|
||||
|
||||
function getGroups(text, size){
|
||||
return text
|
||||
.toLowerCase()
|
||||
.split(/[^a-z]/)
|
||||
.map((word)=>{
|
||||
groups = []
|
||||
for(var i = 0; i <= (word.length - size); i++){
|
||||
groups.push(word.substr(i, size));
|
||||
}
|
||||
return groups;
|
||||
})
|
||||
.reduce((allGroups, groups)=>(
|
||||
allGroups.concat(groups)
|
||||
), []);
|
||||
}
|
||||
|
||||
function getFirstLetters(text){
|
||||
return text
|
||||
.toLowerCase()
|
||||
.split(/[^a-z]/)
|
||||
.filter((word)=>(word.length > 0))
|
||||
.map((word)=>(word[0]));
|
||||
}
|
||||
|
||||
function getFrequency(groups){
|
||||
return groups
|
||||
.reduce((frequencies, group)=>{
|
||||
if(!frequencies[group]){
|
||||
frequencies[group] = 0;
|
||||
}
|
||||
frequencies[group] += 1;
|
||||
return frequencies;
|
||||
}, {})
|
||||
};
|
||||
|
||||
function topGroupsByFrequency(groups, alreadyPercentage){
|
||||
var output = {};
|
||||
var total = Object.values(groups).reduce((a, b)=>(a + b));
|
||||
output.labels = Object.keys(groups).sort((a, b)=>(groups[b] - groups[a])).slice(0, 26);
|
||||
output.values = output.labels.map((groupName)=>(groups[groupName]));
|
||||
if(!alreadyPercentage){
|
||||
output.values = output.values.map((value)=>(value / total * 100)); //calculates as percentage of whole thing
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
|
||||
module.exports = {
|
||||
name: "Frequency Analysis",
|
||||
inputs: {
|
||||
input: "Input"
|
||||
},
|
||||
output: false,
|
||||
execute: function({input}, block){
|
||||
var topGroups = {};
|
||||
if(!isNaN(parseInt(block.properties.type))){
|
||||
//frequency of group with length type
|
||||
topGroups = topGroupsByFrequency(getFrequency(getGroups(input, parseInt(block.properties.type))));
|
||||
}
|
||||
else if(block.properties.type == "first"){
|
||||
//first letter of each word
|
||||
topGroups = topGroupsByFrequency(getFrequency(getFirstLetters(input, parseInt(block.properties.type))));
|
||||
}
|
||||
$(block.elem).data("chartTop").data.labels = topGroups.labels;
|
||||
$(block.elem).data("chartTop").data.datasets[0] = {
|
||||
data: topGroups.values
|
||||
};
|
||||
$(block.elem).data("chartTop").update();
|
||||
},
|
||||
size: { //update static widths in HTML as well
|
||||
height: 400,
|
||||
width: 400
|
||||
},
|
||||
pageBlock: {
|
||||
html: `
|
||||
<select>
|
||||
<option value="1">Single Letters</option>
|
||||
<option value="2">Digraphs</option>
|
||||
<option value="3">Trigraphs</option>
|
||||
<option value="first">1st Letter</option>
|
||||
</select>
|
||||
<span class="topHidden">
|
||||
<div class="canvasContainer">
|
||||
<canvas class="chart top" width="380" height="150"></canvas>
|
||||
</div>
|
||||
<div class="canvasContainer">
|
||||
<canvas class="chart bottom" width="380" height="150"></canvas>
|
||||
</div>
|
||||
</span>
|
||||
`,
|
||||
js: function(block){
|
||||
var standardFrequencies = {
|
||||
"1": {a: 8.167, b: 1.492, c: 2.782, d: 4.253, e: 12.702, f: 2.228, g: 2.015, h: 6.094, i: 6.966, j: 0.153, k: 0.772, l: 4.025, m: 2.406, n: 6.749, o: 7.507, p: 1.929, q: 0.095, r: 5.987, s: 6.327, t: 9.056, u: 2.758, v: 0.978, w: 2.36, x: 0.15, y: 1.974, z: 0.074},
|
||||
"2": {th: 1.52, he: 1.28, in: 0.94, er: 0.94, an: 0.82, re: 0.68, nd: 0.63, at: 0.59, on: 0.57, nt: 0.56, ha: 0.56, es: 0.56, st: 0.55, en: 0.55, ed: 0.53, to: 0.52, it: 0.5, ou: 0.5, ea: 0.47, hi: 0.46, is: 0.46, or: 0.43, ti: 0.34, as: 0.33, te: 0.27, et: 0.19, ng: 0.18, of: 0.16, al: 0.09, de: 0.09, se: 0.08, le: 0.08, sa: 0.06, si: 0.05, ar: 0.04, ve: 0.04, ra: 0.04, ld: 0.02, ur: 0.02},
|
||||
"3": {the: 1.3636489593493786, ing: 0.7262728609096382, and: 0.7216909325651525, ion: 0.6628250374662927, tio: 0.5432009819877033, ent: 0.5302935539742596, for: 0.4364176465207254, ati: 0.42040977561828335, ter: 0.35934740727926423, ate: 0.3318152376738465, ers: 0.3060779039472102, res: 0.280786679167951, her: 0.2793230868699396, est: 0.2682868458761497, com: 0.2678235657432033, pro: 0.2649545115201913, ere: 0.2542082834806153, all: 0.25378437256592273, int: 0.25335782763051096, men: 0.25312595645961633, you: 0.2493700011137761, ons: 0.24523864706698645, our: 0.24466859192459378, con: 0.23825624560930553, are: 0.23536230733045035, tha: 0.23203135274154815},
|
||||
first: {a: 11.602, b: 4.702, c: 3.511, d: 2.67, e: 2.007, f: 3.779, g: 1.95, h: 7.232, i: 6.286, j: 0.597, k: 0.59, l: 2.705, m: 4.383, n: 2.365, o: 6.264, p: 2.545, q: 0.173, r: 1.653, s: 7.755, t: 16.671, u: 1.487, v: 0.649, w: 6.753, x: 0.017, y: 1.62, z: 0.034}
|
||||
}
|
||||
|
||||
if(block.properties.type){
|
||||
block.elem.find("select").val(block.properties.type);
|
||||
}
|
||||
else{
|
||||
block.properties.type = block.elem.find("select").val();
|
||||
}
|
||||
|
||||
$(block.elem).find("select").change(function(){
|
||||
block.properties.type = block.elem.find("select").val();
|
||||
|
||||
var standardFrequency = standardFrequencies[block.properties.type];
|
||||
var standardGroups = topGroupsByFrequency(standardFrequency, true);
|
||||
|
||||
$(block.elem).data("chartBottom").data.labels = standardGroups.labels;
|
||||
$(block.elem).data("chartBottom").data.datasets[0] = {
|
||||
data: standardGroups.values
|
||||
};
|
||||
$(block.elem).data("chartBottom").update();
|
||||
|
||||
events.emit("inputChanged");
|
||||
});
|
||||
|
||||
var Chart = require("chart.js");
|
||||
$(block.elem).data("chartTop", new Chart(
|
||||
$(block.elem).find(".chart.top"),
|
||||
{
|
||||
type: "bar",
|
||||
options: {
|
||||
title: {
|
||||
display: true,
|
||||
text: "Input Text Frequency"
|
||||
},
|
||||
legend: {
|
||||
display: false
|
||||
}
|
||||
}
|
||||
}
|
||||
));
|
||||
$(block.elem).data("chartBottom", new Chart(
|
||||
$(block.elem).find(".chart.bottom"),
|
||||
{
|
||||
type: "bar",
|
||||
options: {
|
||||
title: {
|
||||
display: true,
|
||||
text: "Standard English Frequency"
|
||||
},
|
||||
legend: {
|
||||
display: false
|
||||
}
|
||||
},
|
||||
data: {
|
||||
labels: ["1", "2", "3"],
|
||||
datasets: [{
|
||||
data: [5,3,10]
|
||||
}]
|
||||
}
|
||||
}
|
||||
));
|
||||
|
||||
$(block.elem).find("select").change();
|
||||
}
|
||||
}
|
||||
}
|
29
src/blocks/hexToAscii.js
Normal file
29
src/blocks/hexToAscii.js
Normal file
@ -0,0 +1,29 @@
|
||||
module.exports = {
|
||||
name: "Hex to ASCII",
|
||||
inputs: {
|
||||
hex: "Hex String"
|
||||
},
|
||||
output: true,
|
||||
execute: function({hex}, elem){
|
||||
return hex
|
||||
.split("")
|
||||
.filter((digit)=>(!isNaN(parseInt(digit, 16))))
|
||||
.reduce((pairs, digit)=>{
|
||||
if(pairs[pairs.length - 1].length < 2){
|
||||
pairs[pairs.length - 1] += digit
|
||||
}
|
||||
else{
|
||||
pairs.push([digit]);
|
||||
}
|
||||
return pairs;
|
||||
}, [""])
|
||||
.filter((pair)=>(pair.length == 2))
|
||||
.map((pair)=>(parseInt(pair, 16)))
|
||||
.map((int)=>(String.fromCharCode(int)))
|
||||
.join("")
|
||||
},
|
||||
pageBlock: {
|
||||
html: "",
|
||||
js: function(){}
|
||||
}
|
||||
}
|
26
src/blocks/index.js
Normal file
26
src/blocks/index.js
Normal file
@ -0,0 +1,26 @@
|
||||
var blocks = [
|
||||
"input",
|
||||
"output",
|
||||
"reverse",
|
||||
"numsToLetters",
|
||||
"lettersToNums",
|
||||
"hexToAscii",
|
||||
"asciiToHex",
|
||||
"vigenereEncode",
|
||||
"vigenereDecode",
|
||||
"caesar",
|
||||
"affineEncrypt",
|
||||
"affineDecrypt",
|
||||
"atbash",
|
||||
"numbersToElements",
|
||||
"elementsToNumbers",
|
||||
"transposition",
|
||||
"transpositionReverse",
|
||||
"substitution",
|
||||
"frequency",
|
||||
];
|
||||
|
||||
module.exports = blocks.reduce((blocks, block)=>{
|
||||
blocks[block] = require("./" + block + ".js");
|
||||
return blocks;
|
||||
}, {});
|
23
src/blocks/input.js
Normal file
23
src/blocks/input.js
Normal file
@ -0,0 +1,23 @@
|
||||
var events = require("../events.js");
|
||||
|
||||
module.exports = {
|
||||
name: "Input",
|
||||
inputs: {
|
||||
},
|
||||
output: true,
|
||||
execute: function({}, block){
|
||||
return block.properties.value;
|
||||
},
|
||||
pageBlock: {
|
||||
html: "<input type='text' name='input'></input>",
|
||||
js: function(block){
|
||||
if(block.properties.value){
|
||||
block.elem.find("input[name='input']").val(block.properties.value);
|
||||
}
|
||||
$(block.elem).find("input[name='input']").keyup(function(){
|
||||
block.properties.value = block.elem.find("input[name='input']").val();
|
||||
events.emit("inputChanged");
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
35
src/blocks/lettersToNums.js
Normal file
35
src/blocks/lettersToNums.js
Normal file
@ -0,0 +1,35 @@
|
||||
module.exports = {
|
||||
name: "Letters to Numbers",
|
||||
inputs: {
|
||||
letters: "Letters",
|
||||
offset: "Offset"
|
||||
},
|
||||
output: true,
|
||||
execute: function({letters, offset}, elem){
|
||||
if(!offset){
|
||||
offset = 0;
|
||||
}
|
||||
else{
|
||||
offset = parseInt(offset);
|
||||
}
|
||||
|
||||
return letters
|
||||
.split("")
|
||||
.map((char)=>(char.charCodeAt(0)))
|
||||
.filter((asciiVal)=>(((asciiVal >= 65) && (asciiVal <= 90)) || ((asciiVal >= 97) && (asciiVal <= 122))))
|
||||
.map((asciiVal)=>{
|
||||
if(asciiVal <= 90){
|
||||
return asciiVal - 65;
|
||||
}
|
||||
else{
|
||||
return asciiVal - 97;
|
||||
}
|
||||
})
|
||||
.map((num)=>(num + offset))
|
||||
.join(",");
|
||||
},
|
||||
pageBlock: {
|
||||
html: "",
|
||||
js: function(){}
|
||||
}
|
||||
}
|
19
src/blocks/numbersToElements.js
Normal file
19
src/blocks/numbersToElements.js
Normal file
@ -0,0 +1,19 @@
|
||||
module.exports = {
|
||||
name: "Numbers to Elements",
|
||||
inputs: {
|
||||
numbers: "Numbers"
|
||||
},
|
||||
output: true,
|
||||
execute: function({numbers}, elem){
|
||||
return numbers
|
||||
.split(",")
|
||||
.map((num)=>(parseInt(num)))
|
||||
.filter((num)=>(!isNaN(num)))
|
||||
.map((num)=>(require("./util/elements.js")[num-1]))
|
||||
.join(",");
|
||||
},
|
||||
pageBlock: {
|
||||
html: "",
|
||||
js: function(){}
|
||||
}
|
||||
}
|
47
src/blocks/numsToLetters.js
Normal file
47
src/blocks/numsToLetters.js
Normal file
@ -0,0 +1,47 @@
|
||||
module.exports = {
|
||||
name: "Numbers to Letters",
|
||||
inputs: {
|
||||
nums: "Numbers",
|
||||
offset: "Offset"
|
||||
},
|
||||
output: true,
|
||||
execute: function({nums, offset}, elem){
|
||||
if(!offset){
|
||||
offset = 0;
|
||||
}
|
||||
else{
|
||||
offset = parseInt(offset);
|
||||
}
|
||||
|
||||
return nums
|
||||
.split(",")
|
||||
.filter((num)=>(num))
|
||||
.map((num)=>(parseInt(num)))
|
||||
.filter((num)=>(!isNaN(num)))
|
||||
.map((num)=>(num - offset))
|
||||
.map((num)=>(num%52))
|
||||
.map((num)=>{
|
||||
if(num < 0){
|
||||
return 52 + num;
|
||||
}
|
||||
else{
|
||||
return num;
|
||||
}
|
||||
})
|
||||
.map((num)=>{
|
||||
if(num < 26){
|
||||
asciiOffset = 97;
|
||||
}
|
||||
else{
|
||||
asciiOffset = 65 - 26;
|
||||
}
|
||||
return num + asciiOffset;
|
||||
})
|
||||
.map((asciiVal)=>(String.fromCharCode(asciiVal)))
|
||||
.join("")
|
||||
},
|
||||
pageBlock: {
|
||||
html: "",
|
||||
js: function(){}
|
||||
}
|
||||
}
|
14
src/blocks/output.js
Normal file
14
src/blocks/output.js
Normal file
@ -0,0 +1,14 @@
|
||||
module.exports = {
|
||||
name: "Output",
|
||||
inputs: {
|
||||
input: "Input"
|
||||
},
|
||||
output: false,
|
||||
execute: function({input}, block){
|
||||
$(block.elem).find("span.output").html(input);
|
||||
},
|
||||
pageBlock: {
|
||||
html: "<span class='output'></span>",
|
||||
js: function(){}
|
||||
}
|
||||
}
|
17
src/blocks/reverse.js
Normal file
17
src/blocks/reverse.js
Normal file
@ -0,0 +1,17 @@
|
||||
module.exports = {
|
||||
name: "Reverse",
|
||||
inputs: {
|
||||
input: "Input"
|
||||
},
|
||||
output: true,
|
||||
execute: function({input}, elem){
|
||||
return input
|
||||
.split("")
|
||||
.reverse()
|
||||
.join("");
|
||||
},
|
||||
pageBlock: {
|
||||
html: "",
|
||||
js: function(){}
|
||||
}
|
||||
}
|
36
src/blocks/substitution.js
Normal file
36
src/blocks/substitution.js
Normal file
@ -0,0 +1,36 @@
|
||||
module.exports = {
|
||||
name: "Substitution",
|
||||
inputs: {
|
||||
text: "Text",
|
||||
mapping: "Mapping"
|
||||
},
|
||||
output: true,
|
||||
execute: function({text, mapping}, elem){
|
||||
mapping = mapping.toLowerCase();
|
||||
var letterMapping = {};
|
||||
for(var i = 0; i < (mapping.length - 1); i++){
|
||||
letterMapping[mapping[i]] = mapping[i+1];
|
||||
}
|
||||
|
||||
return text
|
||||
.split("")
|
||||
.map((char)=>{
|
||||
if(char.toLowerCase() in letterMapping){
|
||||
if(char.toLowerCase() == char){
|
||||
return letterMapping[char];
|
||||
}
|
||||
else{
|
||||
return letterMapping[char.toLowerCase()].toUpperCase();
|
||||
}
|
||||
}
|
||||
else{
|
||||
return char;
|
||||
}
|
||||
})
|
||||
.join("");
|
||||
},
|
||||
pageBlock: {
|
||||
html: "",
|
||||
js: function(){}
|
||||
}
|
||||
}
|
14
src/blocks/template.js
Normal file
14
src/blocks/template.js
Normal file
@ -0,0 +1,14 @@
|
||||
module.exports = {
|
||||
name: "Example Block",
|
||||
inputs: {
|
||||
input: "Input"
|
||||
},
|
||||
output: true,
|
||||
execute: function({input}, elem){
|
||||
return input;
|
||||
},
|
||||
pageBlock: {
|
||||
html: "",
|
||||
js: function(){}
|
||||
}
|
||||
}
|
27
src/blocks/transposition.js
Normal file
27
src/blocks/transposition.js
Normal file
@ -0,0 +1,27 @@
|
||||
module.exports = {
|
||||
name: "Transposition",
|
||||
inputs: {
|
||||
text: "Text",
|
||||
n: "n"
|
||||
},
|
||||
output: true,
|
||||
execute: function({text, n}, elem){
|
||||
var n = parseInt(n);
|
||||
|
||||
text = text.replace(/[ ,.]/g, "");
|
||||
|
||||
var output = "";
|
||||
x = 0;
|
||||
for(var i = 0; i < n; i++){
|
||||
for(var y = i; y < text.length; y += n){
|
||||
output += text[y];
|
||||
}
|
||||
}
|
||||
|
||||
return output;
|
||||
},
|
||||
pageBlock: {
|
||||
html: "",
|
||||
js: function(){}
|
||||
}
|
||||
}
|
29
src/blocks/transpositionReverse.js
Normal file
29
src/blocks/transpositionReverse.js
Normal file
@ -0,0 +1,29 @@
|
||||
module.exports = {
|
||||
name: "Transposition Reverse",
|
||||
inputs: {
|
||||
text: "Text",
|
||||
n: "n"
|
||||
},
|
||||
output: true,
|
||||
execute: function({text, n}, elem){
|
||||
var n = parseInt(n);
|
||||
|
||||
text = text.replace(/[ ,.]/g, "");
|
||||
|
||||
var output = [];
|
||||
x = 0;
|
||||
var z = 0;
|
||||
for(var i = 0; i < n; i++){
|
||||
for(var y = i; y < text.length; y += n){
|
||||
output[y] = text[z];
|
||||
z++;
|
||||
}
|
||||
}
|
||||
|
||||
return output.join("");
|
||||
},
|
||||
pageBlock: {
|
||||
html: "",
|
||||
js: function(){}
|
||||
}
|
||||
}
|
19
src/blocks/util/coPrime.js
Normal file
19
src/blocks/util/coPrime.js
Normal file
@ -0,0 +1,19 @@
|
||||
function getFactors(num){
|
||||
factors = [];
|
||||
for(var i = 2; i <= num; i++){
|
||||
if(num%i == 0){
|
||||
factors.push(i);
|
||||
}
|
||||
}
|
||||
return factors;
|
||||
}
|
||||
|
||||
function coPrime(a, b){
|
||||
aFactors = getFactors(a);
|
||||
bFactors = getFactors(b);
|
||||
common = aFactors.filter((factor)=>(bFactors.indexOf(factor) > -1));
|
||||
|
||||
return (common.length == 0);
|
||||
}
|
||||
|
||||
module.exports = coPrime;
|
120
src/blocks/util/elements.js
Normal file
120
src/blocks/util/elements.js
Normal file
@ -0,0 +1,120 @@
|
||||
module.exports =[
|
||||
"h",
|
||||
"he",
|
||||
"li",
|
||||
"be",
|
||||
"b",
|
||||
"c",
|
||||
"n",
|
||||
"o",
|
||||
"f",
|
||||
"ne",
|
||||
"na",
|
||||
"mg",
|
||||
"al",
|
||||
"si",
|
||||
"p",
|
||||
"s",
|
||||
"cl",
|
||||
"ar",
|
||||
"k",
|
||||
"ca",
|
||||
"sc",
|
||||
"ti",
|
||||
"v",
|
||||
"cr",
|
||||
"mn",
|
||||
"fe",
|
||||
"co",
|
||||
"ni",
|
||||
"cu",
|
||||
"zn",
|
||||
"ga",
|
||||
"ge",
|
||||
"as",
|
||||
"se",
|
||||
"br",
|
||||
"kr",
|
||||
"rb",
|
||||
"sr",
|
||||
"y",
|
||||
"zr",
|
||||
"nb",
|
||||
"mo",
|
||||
"tc",
|
||||
"ru",
|
||||
"rh",
|
||||
"pd",
|
||||
"ag",
|
||||
"cd",
|
||||
"in",
|
||||
"sn",
|
||||
"sb",
|
||||
"te",
|
||||
"i",
|
||||
"xe",
|
||||
"cs",
|
||||
"ba",
|
||||
"la",
|
||||
"ce",
|
||||
"pr",
|
||||
"nd",
|
||||
"pm",
|
||||
"sm",
|
||||
"eu",
|
||||
"gd",
|
||||
"tb",
|
||||
"dy",
|
||||
"ho",
|
||||
"er",
|
||||
"tm",
|
||||
"yb",
|
||||
"lu",
|
||||
"hf",
|
||||
"ta",
|
||||
"w",
|
||||
"re",
|
||||
"os",
|
||||
"ir",
|
||||
"pt",
|
||||
"au",
|
||||
"hg",
|
||||
"tl",
|
||||
"pb",
|
||||
"bi",
|
||||
"po",
|
||||
"at",
|
||||
"rn",
|
||||
"fr",
|
||||
"ra",
|
||||
"ac",
|
||||
"th",
|
||||
"pa",
|
||||
"u",
|
||||
"np",
|
||||
"pu",
|
||||
"am",
|
||||
"cm",
|
||||
"bk",
|
||||
"cf",
|
||||
"es",
|
||||
"fm",
|
||||
"md",
|
||||
"no",
|
||||
"lr",
|
||||
"rf",
|
||||
"db",
|
||||
"sg",
|
||||
"bh",
|
||||
"hs",
|
||||
"mt",
|
||||
"ds",
|
||||
"rg",
|
||||
"cn",
|
||||
"nh",
|
||||
"fl",
|
||||
"mc",
|
||||
"lv",
|
||||
"ts",
|
||||
"og"
|
||||
];
|
8
src/blocks/util/toChar.js
Normal file
8
src/blocks/util/toChar.js
Normal file
@ -0,0 +1,8 @@
|
||||
module.exports = function(num){
|
||||
if(Number.isInteger(num)){
|
||||
return String.fromCharCode(num + 97);
|
||||
}
|
||||
else{
|
||||
return num;
|
||||
}
|
||||
}
|
9
src/blocks/util/toNum.js
Normal file
9
src/blocks/util/toNum.js
Normal file
@ -0,0 +1,9 @@
|
||||
module.exports = function(char){
|
||||
var num = char.toLowerCase().charCodeAt(0) - 97;
|
||||
if((num >= 0) && (num < 26)){
|
||||
return num;
|
||||
}
|
||||
else{
|
||||
return char;
|
||||
}
|
||||
}
|
30
src/blocks/vigenereDecode.js
Normal file
30
src/blocks/vigenereDecode.js
Normal file
@ -0,0 +1,30 @@
|
||||
module.exports = {
|
||||
name: "Vigenere Decode",
|
||||
inputs: {
|
||||
cipherText: "Ciphertext",
|
||||
key: "Key"
|
||||
},
|
||||
output: true,
|
||||
execute: function({cipherText, key}, elem){
|
||||
var keyNums = key.split("").map(require("./util/toNum.js"));
|
||||
|
||||
return cipherText
|
||||
.split("")
|
||||
.map(require("./util/toNum.js"))
|
||||
.map((int, pos, ints)=>{
|
||||
if(Number.isInteger(int)){
|
||||
var realCharsPosition = ints.slice(0, pos).filter((num)=>(Number.isInteger(num))).length;
|
||||
return (int + 26 - keyNums[realCharsPosition%key.length])%26;
|
||||
}
|
||||
else{
|
||||
return int;
|
||||
}
|
||||
})
|
||||
.map(require("./util/toChar.js"))
|
||||
.join("");
|
||||
},
|
||||
pageBlock: {
|
||||
html: "",
|
||||
js: function(){}
|
||||
}
|
||||
}
|
30
src/blocks/vigenereEncode.js
Normal file
30
src/blocks/vigenereEncode.js
Normal file
@ -0,0 +1,30 @@
|
||||
module.exports = {
|
||||
name: "Vigenere Encode",
|
||||
inputs: {
|
||||
plaintext: "Plaintext",
|
||||
key: "Key"
|
||||
},
|
||||
output: true,
|
||||
execute: function({plaintext, key}, elem){
|
||||
var keyNums = key.split("").map(require("./util/toNum.js"));
|
||||
|
||||
return plaintext
|
||||
.split("")
|
||||
.map(require("./util/toNum.js"))
|
||||
.map((int, pos, ints)=>{
|
||||
if(Number.isInteger(int)){
|
||||
var realCharsPosition = ints.slice(0, pos).filter((num)=>(Number.isInteger(num))).length;
|
||||
return (int + keyNums[realCharsPosition % key.length]) % 26;
|
||||
}
|
||||
else{
|
||||
return int;
|
||||
}
|
||||
})
|
||||
.map(require("./util/toChar.js"))
|
||||
.join("");
|
||||
},
|
||||
pageBlock: {
|
||||
html: "",
|
||||
js: function(){}
|
||||
}
|
||||
}
|
9
src/diagram/export.js
Normal file
9
src/diagram/export.js
Normal file
@ -0,0 +1,9 @@
|
||||
module.exports = function(){
|
||||
var diagram = require("./index.js");
|
||||
return JSON.stringify(diagram, function(key, value){
|
||||
if(key == "elem"){
|
||||
return undefined;
|
||||
}
|
||||
return value;
|
||||
});
|
||||
}
|
12
src/diagram/import.js
Normal file
12
src/diagram/import.js
Normal file
@ -0,0 +1,12 @@
|
||||
var diagram = require("./index.js");
|
||||
var events = require("../events.js");
|
||||
var $ = require("jquery");
|
||||
|
||||
module.exports = function(newDiagram){
|
||||
Object.assign(diagram, JSON.parse(newDiagram));
|
||||
$("#workspace>*").remove();
|
||||
for(var block of diagram.state){
|
||||
require("../pageInteraction/addBlockToPage.js")(block);
|
||||
}
|
||||
events.emit("diagramImport");
|
||||
}
|
5
src/diagram/index.js
Normal file
5
src/diagram/index.js
Normal file
@ -0,0 +1,5 @@
|
||||
module.exports = {
|
||||
name: "New Diagram",
|
||||
state: [],
|
||||
snapshots: []
|
||||
};
|
17
src/events.js
Normal file
17
src/events.js
Normal file
@ -0,0 +1,17 @@
|
||||
var subscriptions = {};
|
||||
|
||||
module.exports = {
|
||||
subscribe: function(event, callback){
|
||||
if(!subscriptions[event]){
|
||||
subscriptions[event] = [];
|
||||
}
|
||||
subscriptions[event].push(callback);
|
||||
},
|
||||
emit: function(event, data){
|
||||
if(subscriptions[event]){
|
||||
for(var callback of subscriptions[event]){
|
||||
callback(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
17
src/index.html
Normal file
17
src/index.html
Normal file
@ -0,0 +1,17 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>Cryptography Assistant</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="header">
|
||||
<a href="#" id="projectName">New Diagram</a>
|
||||
<a href="#" id="import">Open File</a>
|
||||
<a href="#" id="export">Save</a>
|
||||
<input type="file" id="importUpload"></input>
|
||||
</div>
|
||||
<div id="blocks">
|
||||
</div>
|
||||
<div id="workspace">
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
10
src/index.js
Normal file
10
src/index.js
Normal file
@ -0,0 +1,10 @@
|
||||
require("./styles.scss");
|
||||
require("./pageInteraction");
|
||||
require("./outputCalculation.js");
|
||||
require("./menu.js");
|
||||
|
||||
//for lazy debugging, remove when done
|
||||
window.diagram = require("./diagram");
|
||||
window.$ = require("jquery");
|
||||
window.exportDiagram = require("./diagram/export.js");
|
||||
window.importDiagram = require("./diagram/import.js");
|
34
src/menu.js
Normal file
34
src/menu.js
Normal file
@ -0,0 +1,34 @@
|
||||
var $ = require("jquery");
|
||||
var events = require("./events.js");
|
||||
var diagram = require("./diagram");
|
||||
|
||||
$("#header>a#export").click(function(){
|
||||
var fileSaver = require("file-saver");
|
||||
var exported = require("./diagram/export.js")();
|
||||
var exportedBlob = new Blob([exported], {type: "text/plain;chartset=utf-8"})
|
||||
fileSaver.saveAs(exportedBlob, diagram.name + ".json");
|
||||
});
|
||||
|
||||
$("#header>a#import").click(function(){
|
||||
$("#header>#importUpload").click();
|
||||
});
|
||||
|
||||
$("#header>#importUpload").change(function(){
|
||||
var reader = new FileReader();
|
||||
reader.onload = function(){
|
||||
require("./diagram/import.js")(reader.result);
|
||||
}
|
||||
reader.readAsText(this.files[0]);
|
||||
});
|
||||
|
||||
$("#header>a#projectName").click(function(){
|
||||
do{
|
||||
diagram.name = prompt("Please enter a name for the diagram", diagram.name);
|
||||
}
|
||||
while(!diagram.name);
|
||||
$("#header>a#projectName").html(diagram.name);
|
||||
});
|
||||
|
||||
events.subscribe("diagramImport", function(){
|
||||
$("#header>a#projectName").html(diagram.name);
|
||||
});
|
38
src/outputCalculation.js
Normal file
38
src/outputCalculation.js
Normal file
@ -0,0 +1,38 @@
|
||||
var diagram = require("./diagram");
|
||||
var events = require("./events.js");
|
||||
var blocks = require("./blocks");
|
||||
|
||||
function resolveOutput(block, cache){
|
||||
var inputValues = {};
|
||||
for(var input in block.inputs){
|
||||
if(block.inputs[input] in cache){
|
||||
inputValues[input] = cache[block.inputs[input]];
|
||||
}
|
||||
else{
|
||||
var inputBlock = diagram.state.filter((diagramBlock)=>(diagramBlock.id == block.inputs[input]))[0];
|
||||
inputValues[input] = resolveOutput(inputBlock, cache);
|
||||
}
|
||||
}
|
||||
|
||||
var output = "";
|
||||
if(Object.keys(blocks[block.type].inputs).length == Object.keys(inputValues).length){ //only execute if all inputs are present
|
||||
output = blocks[block.type].execute(inputValues, block);
|
||||
}
|
||||
cache[block.id] = output;
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
function calculateOutputBlocks(){
|
||||
var cache = {};
|
||||
var outputBlocks = diagram.state.filter((block)=>((block.type == "output") || (block.type == "frequency")));
|
||||
for(var block of outputBlocks){
|
||||
resolveOutput(block, cache);
|
||||
}
|
||||
}
|
||||
|
||||
events.subscribe("inputChanged", calculateOutputBlocks);
|
||||
events.subscribe("newJoin", calculateOutputBlocks);
|
||||
events.subscribe("diagramImport", calculateOutputBlocks);
|
||||
|
||||
window.calculate = calculateOutputBlocks;
|
24
src/pageInteraction/addBlockToPage.js
Normal file
24
src/pageInteraction/addBlockToPage.js
Normal file
@ -0,0 +1,24 @@
|
||||
var blocks = require("../blocks");
|
||||
|
||||
module.exports = function(newBlock){
|
||||
var newBlockElement = $(
|
||||
require("./block.hbs")({
|
||||
block: blocks[newBlock.type],
|
||||
instance: newBlock
|
||||
})
|
||||
).appendTo("#workspace");
|
||||
newBlock.elem = newBlockElement;
|
||||
if(blocks[newBlock.type].size){
|
||||
newBlockElement.css({
|
||||
height: blocks[newBlock.type].size.height,
|
||||
width: blocks[newBlock.type].size.width
|
||||
});
|
||||
}
|
||||
if(newBlock.position){
|
||||
newBlockElement.css({
|
||||
top: newBlock.position.y,
|
||||
left: newBlock.position.x
|
||||
});
|
||||
}
|
||||
blocks[newBlock.type].pageBlock.js(newBlock);
|
||||
}
|
18
src/pageInteraction/block.hbs
Normal file
18
src/pageInteraction/block.hbs
Normal file
@ -0,0 +1,18 @@
|
||||
<div class="block" data-type="{{block.type}}" id="{{instance.id}}">
|
||||
<div class="inputs">
|
||||
{{#each block.inputs as |desc name|}}
|
||||
<div id="{{name}}">{{desc}}</div>
|
||||
{{/each}}
|
||||
</div>
|
||||
<div class="main">
|
||||
<div>
|
||||
<div class="title">{{block.name}}</div>
|
||||
{{{block.pageBlock.html}}}
|
||||
</div>
|
||||
</div>
|
||||
{{#if block.output}}
|
||||
<div class="output">
|
||||
Output
|
||||
</div>
|
||||
{{/if}}
|
||||
</div>
|
86
src/pageInteraction/dragDrop.js
Normal file
86
src/pageInteraction/dragDrop.js
Normal file
@ -0,0 +1,86 @@
|
||||
var blocks = require("../blocks");
|
||||
var diagram = require("../diagram");
|
||||
var events = require("../events.js");
|
||||
var $ = require("jquery");
|
||||
var uuid = require("node-uuid");
|
||||
|
||||
function blockPositionChange(event){
|
||||
var block = diagram.state.filter((block)=>(block.dragging))[0];
|
||||
if(block){
|
||||
block.position.x = event.pageX - $("#workspace").position().left - block.offset.x;
|
||||
block.position.y = event.pageY - $("#workspace").position().top - block.offset.y;
|
||||
|
||||
$("#workspace>.block#" + block.id).css({
|
||||
left: block.position.x,
|
||||
top: block.position.y,
|
||||
});
|
||||
|
||||
events.emit("blockMove");
|
||||
}
|
||||
}
|
||||
|
||||
$("#blocks").on("mousedown", ".block>.main,.block>.inputs", function(event){
|
||||
var newBlock = {
|
||||
id: uuid.v4(),
|
||||
position: {
|
||||
x: 0,
|
||||
y: 0
|
||||
},
|
||||
dragging: true,
|
||||
offset: {
|
||||
x: event.pageX - $(this).parent().offset().left,
|
||||
y: event.pageY - $(this).parent().offset().top
|
||||
},
|
||||
type: $(this).parent().data("type"),
|
||||
inputs: {},
|
||||
properties: {}
|
||||
}
|
||||
diagram.state.push(newBlock);
|
||||
require("./addBlockToPage.js")(newBlock);
|
||||
blockPositionChange(event);
|
||||
});
|
||||
|
||||
$("#workspace").on("mousedown", ".block>.main,.block>.inputs", function(event){
|
||||
if(event.which == 1){ //check left mouse button
|
||||
var block = diagram.state.filter((block)=>(block.id == $(this).parent().attr("id")))[0];
|
||||
block.dragging = true;
|
||||
block.offset.x = event.pageX - $(this).parent().offset().left;
|
||||
block.offset.y = event.pageY - $(this).parent().offset().top;
|
||||
blockPositionChange(event);
|
||||
}
|
||||
});
|
||||
|
||||
$("#workspace").on("mouseup", ".block>.main,.block>.inputs", function(event){
|
||||
diagram.state.filter((block)=>(block.id == $(this).parent().attr("id")))[0].dragging = false;
|
||||
});
|
||||
|
||||
|
||||
$(document).on("mousemove", function(event){
|
||||
event.preventDefault();
|
||||
blockPositionChange(event);
|
||||
});
|
||||
|
||||
$("#workspace").on("mousedown", ".block>.main", function(event){
|
||||
if(event.which == 3){ //right mouse button, delete
|
||||
event.preventDefault();
|
||||
for(var i in diagram.state){
|
||||
if(diagram.state[i].id == $(this).parent().attr("id")){
|
||||
diagram.state.splice(i, 1);
|
||||
}
|
||||
}
|
||||
for(var block of diagram.state){
|
||||
for(var input in block.inputs){
|
||||
if(block.inputs[input] == $(this).parent().attr("id")){
|
||||
delete block.inputs[input];
|
||||
}
|
||||
}
|
||||
}
|
||||
$(this).parent().remove();
|
||||
events.emit("blockDelete");
|
||||
}
|
||||
});
|
||||
|
||||
$(document).on("contextmenu", function(event){
|
||||
event.preventDefault();
|
||||
return false;
|
||||
});
|
3
src/pageInteraction/index.js
Normal file
3
src/pageInteraction/index.js
Normal file
@ -0,0 +1,3 @@
|
||||
require("./setupBlocks.js");
|
||||
require("./dragDrop.js");
|
||||
require("./joining.js");
|
88
src/pageInteraction/joining.js
Normal file
88
src/pageInteraction/joining.js
Normal file
@ -0,0 +1,88 @@
|
||||
var blocks = require("../blocks");
|
||||
var diagram = require("../diagram");
|
||||
var events = require("../events.js");
|
||||
var $ = require("jquery");
|
||||
|
||||
function moveLine(elem, a, b, c, d){
|
||||
[[a, b], [c, d]] = [[a, b], [c, d]].sort((a, b)=>(a[0] - b[0])); //swap coords based on x-value, a will always be smaller than b
|
||||
var l = Math.sqrt(Math.pow(a - c, 2) + Math.pow(d - b, 2));
|
||||
var x = (a + c - l) / 2;
|
||||
var y = (b + d) / 2;
|
||||
var theta = Math.asin(2 * (y - b) / l);
|
||||
$(elem).css({
|
||||
left: x,
|
||||
top: y,
|
||||
width: l,
|
||||
transform: "rotate(" + theta + "rad)"
|
||||
});
|
||||
}
|
||||
|
||||
var lineStart = [0, 0];
|
||||
var lineEnd = [0, 0];
|
||||
var dragging = false;
|
||||
var startBlock = "";
|
||||
var endBlock = "";
|
||||
var endInput = "";
|
||||
|
||||
$("#workspace").on("mousedown", ".block>.output", function(event){
|
||||
dragging = true;
|
||||
$("#workspace").append("<div class='line' id='joiningLine'></div>");
|
||||
startBlock = $(this).parent().attr("id");
|
||||
lineStart = [event.pageX - $("#workspace").offset().left, event.pageY - $("#workspace").offset().top];
|
||||
});
|
||||
|
||||
$(document).on("mousemove", function(event){
|
||||
if(dragging){
|
||||
lineEnd = [event.pageX - $("#workspace").offset().left, event.pageY - $("#workspace").offset().top];
|
||||
moveLine($("#joiningLine"), lineStart[0], lineStart[1], lineEnd[0], lineEnd[1]);
|
||||
}
|
||||
});
|
||||
|
||||
$(document).on("mouseup", function(event){
|
||||
if(dragging){
|
||||
dragging = false;
|
||||
$("#joiningLine").remove();
|
||||
}
|
||||
});
|
||||
|
||||
$("#workspace").on("mouseup", ".block>.inputs>div", function(event){
|
||||
if(dragging){
|
||||
endBlock = $(this).parent().parent().attr("id");
|
||||
endInput = $(this).attr("id");
|
||||
var endBlockInstance = diagram.state.filter((block)=>(block.id == endBlock))[0];
|
||||
endBlockInstance.inputs[endInput] = startBlock;
|
||||
drawJoiningLines();
|
||||
events.emit("newJoin");
|
||||
}
|
||||
});
|
||||
|
||||
events.subscribe("blockMove", drawJoiningLines);
|
||||
events.subscribe("blockDelete", drawJoiningLines);
|
||||
events.subscribe("diagramImport", drawJoiningLines);
|
||||
|
||||
function drawJoiningLines(){
|
||||
$(".line").remove();
|
||||
for(var endBlock of diagram.state){
|
||||
for(var input in endBlock.inputs){
|
||||
startBlockId = endBlock.inputs[input];
|
||||
startBlock = diagram.state.filter((block)=>(block.id == startBlockId))[0];
|
||||
lineId = startBlock.id + "-" + endBlock.id + "-" + input;
|
||||
if($("#" + lineId).length){
|
||||
var line = $("#" + lineId)
|
||||
}
|
||||
else{
|
||||
var line = $("<div class='line' id='" + lineId + "'></div>").appendTo($("#workspace"));
|
||||
}
|
||||
|
||||
outputElem = $("#" + startBlock.id).find(".output").eq(0);
|
||||
inputElem = $("#" + endBlock.id).find(".inputs>#" + input).eq(0);
|
||||
moveLine(
|
||||
line,
|
||||
startBlock.position.x + (outputElem.outerWidth()/2),
|
||||
startBlock.position.y + outputElem.position().top + outputElem.outerHeight(),
|
||||
endBlock.position.x + inputElem.position().left + (inputElem.outerWidth()/2),
|
||||
endBlock.position.y
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
8
src/pageInteraction/setupBlocks.js
Normal file
8
src/pageInteraction/setupBlocks.js
Normal file
@ -0,0 +1,8 @@
|
||||
var $ = require("jquery");
|
||||
var blocks = require("../blocks");
|
||||
for(var block of Object.keys(blocks)){
|
||||
blocks[block].type = block;
|
||||
$("#blocks").append(require("./block.hbs")({
|
||||
block: blocks[block]
|
||||
}));
|
||||
}
|
83
src/styles.scss
Normal file
83
src/styles.scss
Normal file
@ -0,0 +1,83 @@
|
||||
html, body{
|
||||
margin: 0;
|
||||
border: 0;
|
||||
font-family: sans-serif;
|
||||
}
|
||||
|
||||
body{
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
#header{
|
||||
#importUpload{
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
#blocks{
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
overflow-x: scroll;
|
||||
.block{
|
||||
margin: 10px;
|
||||
}
|
||||
.topHidden{
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.block{
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
border: 1px solid black;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex-shrink: 0;
|
||||
background-color: white;
|
||||
.inputs{
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
>div{
|
||||
font-weight: bold;
|
||||
border: 1px solid black;
|
||||
flex-grow: 1;
|
||||
text-align: center;
|
||||
padding-top: 5px;
|
||||
padding-bottom: 5px;
|
||||
}
|
||||
}
|
||||
.main{
|
||||
flex-grow: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
>div{
|
||||
margin: auto;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
>.title{
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
>.output{
|
||||
font-weight: bold;
|
||||
border: 1px solid black;
|
||||
text-align: center;
|
||||
padding-top: 5px;
|
||||
padding-bottom: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
#workspace{
|
||||
position: relative;
|
||||
.block{
|
||||
position: absolute;
|
||||
}
|
||||
.line{
|
||||
border-top: 2px solid black;
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user