├── .gitignore
├── .jshintignore
├── .jshintrc
├── .stickler.yml
├── LICENSE
├── README.md
├── config.json
├── javascripts
├── DOMdefinitions.js
├── classes
│ ├── action.js
│ ├── bus.js
│ ├── busGroup.js
│ ├── busInput.js
│ ├── busUnwrapper.js
│ ├── busWrapper.js
│ ├── clickBox.js
│ ├── conpoint.js
│ ├── customSketch.js
│ ├── decoder.js
│ ├── diode.js
│ ├── group.js
│ ├── input.js
│ ├── label.js
│ ├── logicGate.js
│ ├── output.js
│ ├── segmentDisplay.js
│ ├── transformation.js
│ └── wire.js
├── constants.js
├── cpdiodes.js
├── customDialog.js
├── dialogs.js
├── loadsave.js
├── modifierMenu.js
├── mouse.js
├── parsing.js
├── previews.js
├── selectionHandling.js
├── sketch.js
└── undoredo.js
├── libraries
├── bootstrap.min.js
├── jquery.min.js
├── lodash.js
├── p5.dom.js
├── p5.js
├── p5.min.js
└── stickUp.min.js
├── package-lock.json
├── package.json
├── public.key
├── site_scripts
├── create_account.js
├── dashboard.js
├── eduSignup.js
├── edu_tutorial.js
├── education.js
├── edulogin.js
├── getstarted.js
├── index.js
├── index_page.js
├── jwt_module.js
├── lib_front.js
├── login.js
├── migrations
│ ├── 20190916195158_create_user_table.js
│ └── 20190916204924_encrypt_user_password.js
├── store.js
├── survicate.js
├── tos_legal.js
└── user_data.js
├── views
├── css
│ ├── ArcaMajora3-Bold.otf
│ ├── bootstrap.css
│ └── index_style.css
├── dashboard.pug
├── eduLogin.pug
├── eduSignup.pug
├── education.pug
├── getstarted.pug
├── hosting-tutorial.pug
├── images
│ ├── alt_logo.png
│ ├── alt_logo_dark.png
│ ├── alt_logo_small.png
│ ├── and-gate.png
│ ├── buffer.png
│ ├── businput.png
│ ├── button.png
│ ├── carousel_1_new.png
│ ├── carousel_1_new_dark.png
│ ├── carousel_2_new.png
│ ├── carousel_2_new_dark.png
│ ├── carousel_3_new.png
│ ├── carousel_3_new_dark.png
│ ├── clock.png
│ ├── counter.png
│ ├── custom_frontpage.png
│ ├── d-flipflop.png
│ ├── decoder.png
│ ├── demux.png
│ ├── favi.png
│ ├── front_teaser.png
│ ├── front_teaser_white.png
│ ├── fulladd.png
│ ├── fulladd_old.png
│ ├── github_dark.png
│ ├── halfadd.png
│ ├── jk-flipflop.png
│ ├── label.png
│ ├── label_white.png
│ ├── logo_index_new.png
│ ├── logo_index_new_white.png
│ ├── mux.png
│ ├── not-gate.png
│ ├── or-gate.png
│ ├── output.png
│ ├── register.png
│ ├── rs-clocked.png
│ ├── rs-flipflop.png
│ ├── segments.png
│ ├── switch.png
│ ├── t-flipflop.png
│ ├── twitter.png
│ ├── uni-hl-demo.jpg
│ ├── unwrapper.png
│ ├── wrapper.png
│ └── xor-gate.png
├── index.pug
├── legal.pug
├── librarySketches
│ ├── library__0gates.json
│ ├── library__0gates.png
│ ├── library__0gates.txt
│ ├── library__0gates_frame.png
│ ├── library__1halfadder.json
│ ├── library__1halfadder.png
│ ├── library__1halfadder.txt
│ ├── library__1halfadder_frame.png
│ ├── library__2fulladder.json
│ ├── library__2fulladder.png
│ ├── library__2fulladder.txt
│ ├── library__2fulladder_frame.png
│ ├── library__3traffic.json
│ ├── library__3traffic.png
│ ├── library__3traffic.txt
│ ├── library__3traffic_frame.png
│ ├── library__44BitCounter.json
│ ├── library__44BitCounter.png
│ ├── library__44BitCounter.txt
│ ├── library__44BitCounter_frame.png
│ ├── library__5tour.json
│ └── library__hover.png
├── logijs.pug
├── login.pug
├── profile.pug
├── robots.txt
├── signup.pug
├── sketches
│ ├── 1-buffer.json
│ ├── 1-demux.json
│ ├── 1-mux.json
│ ├── 2-counter.json
│ ├── 2-decoder.json
│ ├── 2-demux.json
│ ├── 2-mux.json
│ ├── 3-buffer.json
│ ├── 3-counter.json
│ ├── 3-decoder.json
│ ├── 3-demux.json
│ ├── 3-mux.json
│ ├── 4-counter.json
│ ├── 4-decoder.json
│ ├── 4-register.json
│ ├── 5-counter.json
│ ├── 5-decoder.json
│ ├── d-flipflop.json
│ ├── full_add.json
│ ├── half_add.json
│ ├── inverter.json
│ ├── jk-flipflop.json
│ ├── not-gate.json
│ ├── rs-clocked.json
│ ├── rs-flipflop.json
│ └── t-flipflop.json
└── tos.pug
└── webapp_style.css
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | userSketches/
3 | views/previews
4 | views/sharedSketches
5 | .DS_Store
6 | private.key
7 | public.key
8 | nodemon.json
9 | google76e7434874552abc.html
10 | site_scripts/knexfile.js
11 | views/images/legacy/
--------------------------------------------------------------------------------
/.jshintignore:
--------------------------------------------------------------------------------
1 | libraries/*
--------------------------------------------------------------------------------
/.jshintrc:
--------------------------------------------------------------------------------
1 | {
2 | "maxerr" : 50,
3 | "bitwise" : true,
4 | "camelcase" : false,
5 | "curly" : true,
6 | "eqeqeq" : true,
7 | "forin" : true,
8 | "freeze" : true,
9 | "immed" : false,
10 | "latedef" : false,
11 | "newcap" : false,
12 | "noarg" : true,
13 | "noempty" : true,
14 | "nonbsp" : true,
15 | "nonew" : false,
16 | "plusplus" : false,
17 | "quotmark" : false,
18 | "undef" : false,
19 | "unused" : false,
20 | "strict" : false,
21 | "maxparams" : false,
22 | "maxdepth" : false,
23 | "maxstatements" : false,
24 | "maxcomplexity" : false,
25 | "maxlen" : false,
26 | "varstmt" : false,
27 | "asi" : false,
28 | "boss" : false,
29 | "debug" : false,
30 | "eqnull" : false,
31 | "esversion" : 6,
32 | "moz" : false,
33 | "evil" : false,
34 | "expr" : false,
35 | "funcscope" : false,
36 | "globalstrict" : false,
37 | "iterator" : false,
38 | "lastsemic" : false,
39 | "laxbreak" : false,
40 | "laxcomma" : false,
41 | "loopfunc" : false,
42 | "multistr" : false,
43 | "noyield" : false,
44 | "notypeof" : false,
45 | "proto" : false,
46 | "scripturl" : false,
47 | "shadow" : false,
48 | "sub" : false,
49 | "supernew" : false,
50 | "validthis" : false,
51 | "browser" : true,
52 | "browserify" : false,
53 | "couch" : false,
54 | "devel" : true,
55 | "dojo" : false,
56 | "jasmine" : false,
57 | "jquery" : false,
58 | "mocha" : true,
59 | "mootools" : false,
60 | "node" : false,
61 | "nonstandard" : false,
62 | "phantom" : false,
63 | "prototypejs" : false,
64 | "qunit" : false,
65 | "rhino" : false,
66 | "shelljs" : false,
67 | "typed" : false,
68 | "worker" : false,
69 | "wsh" : false,
70 | "yui" : false,
71 | "globals" : {}
72 | }
--------------------------------------------------------------------------------
/.stickler.yml:
--------------------------------------------------------------------------------
1 | linters:
2 | jshint:
3 | config: './.jshintrc'
4 | files:
5 | ignore:
6 | - 'bower_components/*'
7 | - 'node_modules/*'
8 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ### Please note:
2 |
3 | LogiJS development is currently in an indefinite hold in favor of its spiritual successor [Linkuit Studio](https://github.com/SimonBuxx/Linkuit-Studio). Linkuit Studio is a logic circuit simulator comparable to LogiJS but running as a native Windows application.
4 |
5 | While it still misses some features present in LogiJS, Linkuit Studio is much more stable and maintainable than LogiJS. If you like LogiJS, give [Linkuit Studio](https://github.com/SimonBuxx/Linkuit-Studio) a try.
6 |
7 | Issues in this project won't be fixed by me at the moment. But thank you to everyone who is sharing their ideas and creating bug reports.
8 |
9 | [](https://linkuit.com/)
10 |
11 | # LogiJS - Logic Circuit Simulation
12 | 
13 |
14 | LogiJS is an open source logic ciruit simulation webapp.
15 | Focused on educational purposes, its applications range from experiments with basic logic circuits to complex CPU design.
16 |
17 | My goal is to make LogiJS as user-friendly and performant as possible while providing all features expected by educational facilities.
18 | For the near future, please excuse minor bugs, performance issues or rapid changes in design and functionality.
19 | The software is still under development and I'm trying to improve it every day.
20 |
21 | To try it out, visit https://logijs.com/.
22 |
--------------------------------------------------------------------------------
/config.json:
--------------------------------------------------------------------------------
1 | {
2 | "organization": {
3 | "name": "Universität zu Lübeck",
4 | "first_line": "Universität",
5 | "second_line": "zu Lübeck"
6 | },
7 | "accounts": {
8 | "allow_signups": "true",
9 | "enable_login": "true",
10 | "user_identificator": "email",
11 | "require_verification": "false",
12 | "limit_email_hosts": "false",
13 | "allowed_hosts": ["student.uni-luebeck.de", "uni-luebeck.de"]
14 | },
15 | "custom_index_page": {
16 | "use_custom_page": "false",
17 | "background_image": "https://cdn.prod.www.spiegel.de/images/880f3df9-0001-0004-0000-000000092544_w1528_r1.2514619883040936_fpx35.93_fpy54.98.jpg",
18 | "show_organization_name": "true",
19 | "refer_to_logijs_com": "true",
20 | "background_text": "Universität zu Lübeck",
21 | "allow_entering_without_login": "true",
22 | "show_made_in_luebeck": "true"
23 | },
24 | "localization": {
25 | "login": "Login",
26 | "register": "Konto erstellen",
27 | "email": "E-Mail",
28 | "username": "Nutzername",
29 | "password": "Passwort",
30 | "switch_to_logijs_com": "Zu LogiJS.com wechseln",
31 | "continue_without_login": "Ohne Anmeldung fortfahren",
32 | "toggle_dark_mode": "Dunklen Modus an-/ausschalten",
33 | "login_failed": "Anmeldung fehlgeschlagen",
34 | "signup_successful": "Registrierung erfolgreich",
35 | "already_signed_up": "Du hast schon ein Konto?",
36 | "username_invalid": "Nutzername ungültig",
37 | "email_invalid": "E-Mail-Adresse ungültig",
38 | "password_invalid": "Passwort ungültig",
39 | "password_rules": "Bitte gebe zwischen 6 und 50 klein- UND großgeschriebene Zeichen ein, inklusive mindestens einer Zahl",
40 | "username_taken": "Nutzername schon vergeben"
41 | }
42 | }
--------------------------------------------------------------------------------
/javascripts/classes/action.js:
--------------------------------------------------------------------------------
1 | // File: action.js
2 |
3 | function Action(actionType, actionIndizes, actionObject) {
4 | this.actionType = actionType;
5 | this.actionIndizes = actionIndizes;
6 | this.actionObject = actionObject;
7 | }
--------------------------------------------------------------------------------
/javascripts/classes/bus.js:
--------------------------------------------------------------------------------
1 | // File: bus.js
2 |
3 | function Bus(dir, startX, startY) {
4 | this.highColor = color(HRED, HGREEN, HBLUE); // Color for high
5 | this.lowColor = color(LRED, LGREEN, LBLUE); // Color for low
6 | this.markedColor = color(MRED, MGREEN, MBLUE); // Color for marked
7 |
8 | this.direction = dir; // 0 or 1, meaning horizontal or vertical
9 |
10 | this.startX = 0; // Start point of the segment
11 | this.startY = 0;
12 |
13 | this.endX = 0;
14 | this.endY = 0;
15 |
16 | this.busWidth = 0; // number of wires contained
17 | this.busWidthSet = false;
18 | this.showBusMarker = false; // Show the diagonal line and bus width
19 |
20 | this.textDistance = 12; // Distance of the bus width label to the bus
21 | this.textSize = 15;
22 |
23 | this.marked = false;
24 |
25 | this.group = -1;
26 |
27 | this.id = 'bb' + Date.now() + Math.random();
28 |
29 | this.changePosition(startX, startY); // Initialize the start point
30 |
31 | this.states = Array(this.busWidth).fill(false); // create an array for the wire states
32 | }
33 |
34 | Bus.prototype.getData = function () {
35 | var data = {};
36 | data.x1 = JSON.stringify(this.startX);
37 | data.y1 = JSON.stringify(this.startY);
38 | if (this.startX !== this.endX) {
39 | data.x2 = JSON.stringify(this.endX);
40 | } else {
41 | data.y2 = JSON.stringify(this.endY);
42 | }
43 | return data;
44 | };
45 |
46 | Bus.prototype.alterPosition = function (x1, y1) {
47 | this.endX += x1;
48 | this.endY += y1;
49 | this.startX += x1;
50 | this.startY += y1;
51 | };
52 |
53 | Bus.prototype.changePosition = function (newX, newY) {
54 | this.startX = Math.round(newX / GRIDSIZE) * GRIDSIZE;
55 | this.startY = Math.round(newY / GRIDSIZE) * GRIDSIZE;
56 | switch (this.direction) {
57 | case 0:
58 | this.endX = this.startX + GRIDSIZE;
59 | this.endY = this.startY;
60 | break;
61 | case 1:
62 | this.endY = this.startY + GRIDSIZE;
63 | this.endX = this.startX;
64 | break;
65 | default:
66 | console.log('No valid direction given!');
67 | }
68 | };
69 |
70 | Bus.prototype.setStates = function (s) {
71 | this.states = s;
72 | };
73 |
74 | Bus.prototype.setBusWidth = function (newWidth) {
75 | this.busWidth = newWidth;
76 | this.busWidthSet = true;
77 | }
78 |
79 | Bus.prototype.setGroup = function (g) {
80 | this.group = g;
81 | };
82 |
83 | Bus.prototype.getOutput = function () {
84 | return this.states;
85 | };
86 |
87 | Bus.prototype.show = function (del = false, num='') {
88 | strokeWeight(6);
89 | if (this.marked || del) {
90 | stroke(this.markedColor);
91 | } else {
92 | stroke(this.lowColor);
93 | }
94 |
95 | line(this.startX, this.startY, this.endX, this.endY); // Draw the bus line
96 |
97 | if (this.showBusMarker) {
98 | strokeWeight(3);
99 | if (this.direction === 0) {
100 | line(this.startX + Math.abs((this.endX - this.startX) / 2) - 10, this.startY + 10, this.startX + Math.abs((this.endX - this.startX) / 2) + 10, this.endY - 10);
101 | } else {
102 | line(this.startX - 10, this.startY + Math.abs((this.endY - this.startY) / 2) + 10, this.endX + 10, this.startY + Math.abs((this.endY - this.startY) / 2) - 10);
103 | }
104 | if (this.busWidthSet) {
105 | noStroke();
106 | fill(0);
107 | textSize(this.textSize);
108 | textAlign(CENTER, CENTER);
109 | if (this.direction === 0) {
110 | text(this.busWidth, this.startX + Math.abs((this.endX - this.startX) / 2) - 5, this.startY - this.textDistance);
111 | } else {
112 | text(this.busWidth, this.startX + this.textDistance + 2, this.startY + Math.abs((this.endY - this.startY) / 2) + 5);
113 | }
114 | }
115 | }
116 |
117 | /*noStroke();
118 | fill(0);
119 | if (this.direction === 0) {
120 | text(num, Math.min(this.startX, this.endX) + 10, this.startY - 15);
121 | } else {
122 | text(num, this.startX + 10, Math.min(this.startY, this.endY) + 15);
123 | }*/
124 | };
--------------------------------------------------------------------------------
/javascripts/classes/busGroup.js:
--------------------------------------------------------------------------------
1 | // File: busGroup.js
2 |
3 | function BusGroup() {
4 | this.inputGates = [];
5 | this.outputGates = [];
6 | this.inputPorts = [];
7 | this.outputPorts = [];
8 |
9 | this.busses = [];
10 | this.busWidth = 0;
11 |
12 | this.states = Array(this.busWidth).fill(false);
13 | }
14 |
15 | BusGroup.prototype.addBus = function (s) {
16 | this.busses.push(s);
17 | };
18 |
19 | /*
20 | Add a module input to the bus group
21 | module: the module containing the input
22 | port: the module's input bus port
23 | */
24 | BusGroup.prototype.addInput = function (gate, port) {
25 | this.inputGates.push(gate);
26 | this.inputPorts.push(port);
27 | };
28 |
29 | /*
30 | Add a module output to the bus group
31 | module: the module containing the output
32 | port: the module's output bus port
33 | */
34 | BusGroup.prototype.addOutput = function (gate, port) {
35 | this.outputGates.push(gate);
36 | this.outputPorts.push(port);
37 | };
38 |
39 | /*
40 | Sets this group's bus width to the given width
41 | */
42 | BusGroup.prototype.updateBusWidth = function(newWidth=this.busWidth) {
43 | this.busWidth = newWidth;
44 | this.states = Array(this.busWidth).fill(false); // Reinitialize the states array
45 |
46 | // Determine the longest bus and only show the bus markers on that bus
47 | let longest = 0;
48 | let longestLength = 0;
49 | for (let i = 0; i < this.busses.length; i++) {
50 | if (this.busses[i].direction === 0) {
51 | let busLength = Math.abs(this.busses[i].endX - this.busses[i].startX);
52 | if (busLength > longestLength) {
53 | longest = i;
54 | longestLength = busLength;
55 | }
56 | } else {
57 | let busLength = Math.abs(this.busses[i].endY - this.busses[i].startY);
58 | if (busLength > longestLength) {
59 | longest = i;
60 | longestLength = busLength;
61 | }
62 | }
63 | this.busses[i].setBusWidth(this.busWidth);
64 | this.busses[i].showBusMarker = false;
65 | }
66 | if (this.busses.length > 0) {
67 | this.busses[longest].showBusMarker = true;
68 | }
69 | }
70 |
71 | BusGroup.prototype.updateAll = function () {
72 | let allOutputs = [];
73 | for (let j = 0; j < this.outputGates.length; j++) { // For all connected elements
74 | let output = this.outputGates[j].getOutput(this.outputPorts[j]);
75 | allOutputs.push(Array(this.busWidth - output.length).fill(false).concat(output)); // get the output vector
76 | }
77 |
78 | for (let i = 0; i < this.busWidth; i++) { // For every signal, OR it with the current bus state
79 | let bitState = false;
80 | for (let j = 0; j < allOutputs.length; j++) {
81 | if (allOutputs[j].length > i) {
82 | bitState = bitState || allOutputs[j][i];
83 | }
84 | }
85 | this.states[i] = bitState;
86 | }
87 |
88 | // Propagate the state to all inputs
89 | for (let j = 0; j < this.inputGates.length; j++) {
90 | this.inputGates[j].setInput(this.inputPorts[j], this.states);
91 | }
92 |
93 | if (this.busses[0].states !== this.states) {
94 | this.propagateState();
95 | }
96 | };
97 |
98 | BusGroup.prototype.show = function () {
99 | for (let i = 0; i < this.busses.length; i++) {
100 | this.busses[i].show(false);
101 | }
102 | };
103 |
104 | BusGroup.prototype.propagateState = function () {
105 | for (let i = 0; i < this.busses.length; i++) {
106 | this.busses[i].states = this.states;
107 | }
108 | };
--------------------------------------------------------------------------------
/javascripts/classes/busInput.js:
--------------------------------------------------------------------------------
1 | // File: busInput.js
2 |
3 | function BusInput(x, y, busWidth, custPos = 0) {
4 | this.x = x; // X-Position (translated)
5 | this.y = y; // Y-Position
6 |
7 | this.busWidth = busWidth;
8 |
9 | this.w = GRIDSIZE;
10 | this.h = GRIDSIZE;
11 |
12 | this.highColor = color(HRED, HGREEN, HBLUE);
13 | this.lowColor = color(50, 50, 50); // Color for low inputs (dark grey)
14 |
15 | this.outputs = []; // Vector of the output state
16 |
17 | this.custPosition = custPos; // Designated bus position on a custom element
18 |
19 | //this.id = '_' + Math.random().toString(36).substr(2, 9);
20 | this.id = 'bi' + Date.now() + Math.random() + 'b';
21 |
22 | this.isTop = false;
23 | this.lbl = '';
24 | this.marked = false;
25 |
26 | // Initialize the outputs
27 | for (let i = 0; i < this.busWidth; i++) {
28 | this.outputs.push(false); // Set all outputs to low
29 | }
30 |
31 | this.clickBox = new ClickBox(this.x - GRIDSIZE / 2, this.y - GRIDSIZE / 2, this.w, this.h, transform);
32 | this.updateClickBox();
33 | }
34 |
35 | BusInput.prototype.alterPosition = function (x1, y1) {
36 | this.x += x1;
37 | this.y += y1;
38 | this.updateClickBox();
39 | };
40 |
41 | BusInput.prototype.getData = function () {
42 | var data = {};
43 | data.x = JSON.stringify(this.x);
44 | data.y = JSON.stringify(this.y);
45 | if (this.isTop) {
46 | data.istop = JSON.stringify(true);
47 | }
48 | if (this.lbl !== '') {
49 | data.lbl = this.lbl;
50 | }
51 | data.busWidth = this.busWidth;
52 | data.pos = this.custPosition;
53 | return data;
54 | };
55 |
56 | /*
57 | Sets the input state
58 | */
59 | BusInput.prototype.setState = function (s) {
60 | this.setFalse();
61 | s = Array(Math.max(0, this.busWidth - s.length)).fill(false).concat(s).slice(0, this.busWidth);
62 | for (let i = 0; i < this.busWidth; i++) {
63 | this.outputs[i] = s[i];
64 | }
65 | };
66 |
67 | BusInput.prototype.setIsTop = function (b) {
68 | this.isTop = b;
69 | };
70 |
71 |
72 | BusInput.prototype.getOutput = function () {
73 | return this.outputs;
74 | };
75 |
76 | BusInput.prototype.mark = function (b) {
77 | this.marked = b;
78 | };
79 |
80 | BusInput.prototype.setFalse = function () {
81 | this.outputs = Array(this.busWidth).fill(false);
82 | };
83 |
84 | /*
85 | Sets the coordinates of the output, rounded to grid size
86 | */
87 | BusInput.prototype.setCoordinates = function (nx, ny) {
88 | this.x = Math.round(nx / GRIDSIZE) * GRIDSIZE - GRIDSIZE / 2;
89 | this.y = Math.round(ny / GRIDSIZE) * GRIDSIZE - GRIDSIZE / 2;
90 | };
91 |
92 | BusInput.prototype.updateClickBox = function () {
93 | this.clickBox.updatePosition(this.x + GRIDSIZE / 2, this.y + GRIDSIZE / 2);
94 | this.clickBox.setTransform(transform);
95 | };
96 |
97 | /*
98 | Checks if the mouse is inside the clickBox
99 | */
100 | BusInput.prototype.mouseOver = function () {
101 | return this.clickBox.mouseOver();
102 | };
103 |
104 | /*
105 | Checks if a certain point is in the output
106 | */
107 | BusInput.prototype.pointInOutput = function (dummy, px, py) {
108 | return this.clickBox.checkPoint(px, py);
109 | };
110 |
111 | /*
112 | Displays the input on the screen
113 | */
114 | BusInput.prototype.show = function (order = 0) {
115 | stroke(0);
116 | strokeWeight(3);
117 | if (this.marked) {
118 | stroke(MRED, MGREEN, MBLUE);
119 | fill(150);
120 | } else {
121 | fill(this.lowColor);
122 | }
123 | // Draw the rectangle that represents the input
124 | rect(this.x, this.y, this.w, this.h);
125 | noStroke();
126 | if (this.marked) {
127 | fill(170);
128 | } else {
129 | fill(LARED, LAGREEN, LABLUE);
130 | }
131 | triangle(this.x + 2, this.y + 2, this.x + GRIDSIZE - 2, this.y + 2, this.x + 2, this.y + GRIDSIZE - 2);
132 |
133 | if (this.marked) {
134 | fill(MRED, MGREEN, MBLUE);
135 | } else {
136 | fill(0);
137 | }
138 | textFont('Arial');
139 | textSize(10);
140 | textAlign(LEFT, TOP);
141 | text(this.busWidth, this.x + 4, this.y + 4);
142 |
143 | noFill();
144 | if (this.marked) {
145 | stroke(MRED, MGREEN, MBLUE);
146 | } else {
147 | stroke(0);
148 | }
149 | rect(this.x, this.y, this.w, this.h);
150 |
151 | if (this.marked) {
152 | stroke(MRED, MGREEN, MBLUE);
153 | } else {
154 | stroke(0);
155 | }
156 | strokeWeight(3);
157 | line(this.x + 8, this.y + 22, this.x + 22, this.y + 8);
158 |
159 | if (order > 0) {
160 | noStroke();
161 | fill(255);
162 | textSize(20);
163 | textFont('ArcaMajora3');
164 | //textAlign(LEFT, TOP);
165 | if (order.toString().length === 1) {
166 | text(order, this.x + 10, this.y + 7);
167 | } else {
168 | text(order, this.x + 4, this.y + 7);
169 | }
170 | }
171 |
172 | //this.clickBox.markClickBox();
173 | };
174 |
--------------------------------------------------------------------------------
/javascripts/classes/clickBox.js:
--------------------------------------------------------------------------------
1 | // File: clickBox.js
2 |
3 | function ClickBox(x, y, w, h, transform) {
4 | this.x = x;
5 | this.y = y;
6 |
7 | this.w = w;
8 | this.h = h;
9 | this.transform = transform;
10 |
11 | /*
12 | Sets the transformation of the clickBox
13 | */
14 | this.setTransform = function (transform) {
15 | this.transform = transform;
16 | };
17 |
18 | /*
19 | Swaps width and height
20 | */
21 | this.turn = function () {
22 | this.temp = this.h;
23 | this.h = this.w;
24 | this.w = this.temp;
25 | };
26 |
27 | /*
28 | Updates the position of the clickBox
29 | */
30 | this.updatePosition = function (nx, ny) {
31 | this.x = nx;
32 | this.y = ny;
33 | };
34 |
35 | this.updateSize = function (nw, nh) {
36 | this.w = nw;
37 | this.h = nh;
38 | };
39 |
40 | /*
41 | Draws a rect around the clickBox (debugging purposes)
42 | */
43 | this.markClickBox = function (select = false) {
44 | if (select) {
45 | noStroke();
46 | if (currentTheme === 'dark') {
47 | fill(50);
48 | stroke(50);
49 | } else {
50 | fill(255);
51 | stroke(255);
52 | }
53 | strokeWeight(3);
54 | rect(this.x + this.w / 2 - (200 / this.transform.zoom), this.y - this.h / 2 - (50 / this.transform.zoom), 200 / this.transform.zoom, 50 / this.transform.zoom);
55 | }
56 | stroke(50);
57 | fill(0, 30);
58 | rect(this.x - this.w / 2, this.y - this.h / 2, this.w, this.h);
59 | };
60 |
61 | // Returns if the mouse is in a gridSize sized area around x, y
62 | this.mouseOver = function (selectOffset = false) {
63 | if (!selectOffset) {
64 | return (((mouseX / this.transform.zoom - this.transform.dx) >= (this.x - this.w / 2)) &&
65 | ((mouseX / this.transform.zoom - this.transform.dx) <= (this.x + this.w / 2)) &&
66 | ((mouseY / this.transform.zoom - this.transform.dy) >= (this.y - this.h / 2)) &&
67 | ((mouseY / this.transform.zoom - this.transform.dy) <= (this.y + this.h / 2)));
68 | } else {
69 | return (((mouseX / this.transform.zoom - this.transform.dx) >= Math.min((this.x - this.w / 2), this.x + this.w / 2 - (200 / this.transform.zoom))) &&
70 | ((mouseX / this.transform.zoom - this.transform.dx) <= (this.x + this.w / 2)) &&
71 | ((mouseY / this.transform.zoom - this.transform.dy) >= (this.y - this.h / 2 - (50 / this.transform.zoom))) &&
72 | ((mouseY / this.transform.zoom - this.transform.dy) <= (this.y + this.h / 2)));
73 | }
74 | };
75 |
76 | /*
77 | Checks if one point (possibly != mouseX/Y) is inside the ClickBox
78 | */
79 | this.checkPoint = function(px, py) {
80 | return ((px >= (this.x - this.w / 2)) && (px <= (this.x + this.w / 2)) &&
81 | (py >= (this.y - this.h / 2)) && (py <= (this.y + this.h / 2)));
82 | };
83 | }
--------------------------------------------------------------------------------
/javascripts/classes/conpoint.js:
--------------------------------------------------------------------------------
1 | // File: conpoint.js
2 |
3 | function ConPoint(x, y, state, g, isBusConpoint = false) {
4 | this.x = x;
5 | this.y = y;
6 | this.state = state;
7 | this.group = g;
8 | this.isBusConpoint = isBusConpoint;
9 |
10 | this.highColor = color(HRED, HGREEN, HBLUE); // Color for high
11 | this.lowColor = color(LRED, LGREEN, LBLUE); // Color for low
12 |
13 | this.marked = false;
14 | this.markColor = color(MRED, MGREEN, MBLUE);
15 |
16 | this.id = 'p' + Date.now() + Math.random();
17 | }
18 |
19 | ConPoint.prototype.getData = function () {
20 | let data = {};
21 | data.x = JSON.stringify(this.x);
22 | data.y = JSON.stringify(this.y);
23 | return data;
24 | };
25 |
26 | ConPoint.prototype.alterPosition = function (x1, y1) {
27 | this.x += x1;
28 | this.y += y1;
29 | };
30 |
31 | ConPoint.prototype.setGroup = function (ng) {
32 | this.group = ng;
33 | };
34 |
35 | ConPoint.prototype.show = function () {
36 | strokeWeight(0);
37 | if (this.marked) {
38 | fill(this.markColor);
39 | } else if (this.state) {
40 | fill(this.highColor);
41 | } else {
42 | fill(this.lowColor);
43 | }
44 | if (!this.isBusConpoint) {
45 | rect(this.x - 3, this.y - 3, 7, 7);
46 | } else {
47 | rect(this.x - 5, this.y - 5, 10, 10);
48 | }
49 | };
50 |
--------------------------------------------------------------------------------
/javascripts/classes/diode.js:
--------------------------------------------------------------------------------
1 | // File: diode.js
2 |
3 | function Diode(x, y, state) {
4 | this.x = x; // X position
5 | this.y = y; // Y position
6 | this.state = state; // State of the diode
7 |
8 | this.highColor = color(HRED, HGREEN, HBLUE); // Color for high
9 | this.lowColor = color(LRED, LGREEN, LBLUE); // Color for low
10 |
11 | this.groupA = -1; // Group A (Horizontal crossing)
12 | this.groupB = -1; // Group B (Vertical Crossing)
13 |
14 | this.clickBox = new ClickBox(this.x, this.y, 20, 20, transform);
15 |
16 | this.marked = false;
17 |
18 | this.id = 'd' + Date.now() + Math.random();
19 |
20 | this.getData = function () {
21 | var data = {};
22 | data.x = JSON.stringify(this.x);
23 | data.y = JSON.stringify(this.y);
24 | return data;
25 | };
26 |
27 | this.alterPosition = function (x1, y1) {
28 | this.x += x1;
29 | this.y += y1;
30 | this.updateClickBox();
31 | };
32 |
33 | /*
34 | Sets the state of the diode
35 | */
36 | this.setState = function (s) {
37 | this.state = s;
38 | };
39 |
40 | this.setGroups = function (a, b) {
41 | this.groupA = a;
42 | this.groupB = b;
43 | };
44 |
45 | /*
46 | Sets the coordinates of the diode, rounded to grid size
47 | */
48 | this.setCoordinates = function (nx, ny) {
49 | this.x = Math.round(nx / GRIDSIZE) * GRIDSIZE;
50 | this.y = Math.round(ny / GRIDSIZE) * GRIDSIZE;
51 | };
52 |
53 | this.updateClickBox = function () {
54 | this.clickBox.updatePosition(this.x, this.y);
55 | this.clickBox.setTransform(transform);
56 | };
57 |
58 | this.updateClickBox();
59 |
60 | /*
61 | Checks if the mouse is inside the clickBox
62 | */
63 | this.mouseOver = function () {
64 | return this.clickBox.mouseOver();
65 | };
66 |
67 | this.show = function () {
68 | noStroke();
69 | if (this.marked) {
70 | fill(MRED, MGREEN, MBLUE);
71 | } else if (this.state) {
72 | fill(this.highColor);
73 | } else {
74 | fill(this.lowColor);
75 | }
76 | triangle(this.x, this.y + 11, this.x - 11, this.y, this.x + 11, this.y);
77 | //this.clickBox.markClickBox();
78 | };
79 | }
80 |
--------------------------------------------------------------------------------
/javascripts/classes/group.js:
--------------------------------------------------------------------------------
1 | // File: group.js
2 |
3 | function Group() {
4 | this.inputGates = [];
5 | this.outputGates = [];
6 | this.inputPorts = [];
7 | this.outputPorts = [];
8 |
9 | this.wires = [];
10 |
11 | this.state = false;
12 | this.diodeState = false;
13 | this.dstateset = false;
14 | }
15 |
16 | Group.prototype.addWire = function (s) {
17 | this.wires.push(s);
18 | };
19 |
20 | Group.prototype.addInput = function (gate, port) {
21 | this.inputGates.push(gate);
22 | this.inputPorts.push(port);
23 | };
24 |
25 | Group.prototype.addOutput = function (gate, port) {
26 | this.outputGates.push(gate);
27 | this.outputPorts.push(port);
28 | };
29 |
30 | /*
31 | This is evoked when a diode associated with this group is high
32 | */
33 | Group.prototype.diodeHigh = function () {
34 | this.diodeState = true;
35 | this.dstateset = true;
36 | };
37 |
38 | Group.prototype.updateAll = function () {
39 | this.state = false;
40 | // Get all states of the gate outputs
41 | for (let j = 0; j < this.outputGates.length; j++) {
42 | if (this.outputGates[j].getOutput(this.outputPorts[j])) {
43 | this.state = true;
44 | for (let j = 0; j < this.outputGates.length; j++) {
45 | this.outputGates[j].outputs[this.outputPorts[j]] = true;
46 | }
47 | break;
48 | }
49 | }
50 |
51 | // If no input is true, take diodeState as state
52 | if (!this.state && this.dstateset) {
53 | this.state = this.diodeState;
54 | this.dstateset = false;
55 | } else if (!this.dstateset) {
56 | this.diodeState = false;
57 | }
58 |
59 | // Propagate the state to all inputs
60 | for (let j = 0; j < this.inputGates.length; j++) {
61 | this.inputGates[j].setInput(this.inputPorts[j], this.state);
62 | }
63 |
64 | if (this.wires[0].state !== this.state) {
65 | this.propagateState(); // Propagate the state to all wires
66 | }
67 | };
68 |
69 | Group.prototype.show = function () {
70 | for (let i = 0; i < this.wires.length; i++) {
71 | this.wires[i].show(false);
72 | }
73 | };
74 |
75 | Group.prototype.propagateState = function () {
76 | for (let i = 0; i < this.wires.length; i++) {
77 | this.wires[i].state = this.state;
78 | }
79 | };
--------------------------------------------------------------------------------
/javascripts/classes/input.js:
--------------------------------------------------------------------------------
1 | // File: input.js
2 |
3 | function Input(x, y, custPos = 0) {
4 | this.x = x; // X-Position
5 | this.y = y; // Y-Position
6 |
7 | this.w = GRIDSIZE; // Width of the putput
8 | this.h = GRIDSIZE; // Height of the output
9 |
10 | this.state = false; // Input state
11 | this.outputs = false; // equal to state
12 |
13 | this.framecount = -1;
14 | this.clock = false;
15 | this.speed = 30;
16 |
17 | this.custPosition = custPos; // Designated position on a custom element
18 |
19 | this.highColor = color(HRED, HGREEN, HBLUE); // Color for high inputs
20 | this.lowColor = color(50, 50, 50); // Color for low inputs (dark grey)
21 |
22 | this.isTop = false;
23 | this.lbl = '';
24 | this.marked = false;
25 |
26 | this.id = 'i' + Date.now() + Math.random();
27 |
28 | // ClickBox is used for output and global
29 | this.clickBox = new ClickBox(this.x - GRIDSIZE / 2, this.y - GRIDSIZE / 2, this.w, this.h, transform);
30 | this.updateClickBox();
31 | }
32 |
33 | Input.prototype.alterPosition = function (x1, y1) {
34 | this.x += x1;
35 | this.y += y1;
36 | this.updateClickBox();
37 | };
38 |
39 | Input.prototype.getData = function () {
40 | var data = {};
41 | data.x = JSON.stringify(this.x);
42 | data.y = JSON.stringify(this.y);
43 | if (this.isTop) {
44 | data.istop = JSON.stringify(true);
45 | }
46 | if (this.lbl !== '') {
47 | data.lbl = this.lbl;
48 | }
49 | if (this.framecount === -1) {
50 | data.framecount = JSON.stringify(-1);
51 | } else {
52 | data.framecount = JSON.stringify(0);
53 | }
54 | data.clock = JSON.stringify(this.clock);
55 | if (this.clock) {
56 | data.speed = JSON.stringify(this.speed);
57 | }
58 | data.pos = this.custPosition;
59 | return data;
60 | };
61 |
62 | Input.prototype.getIsClock = function () {
63 | return this.clock;
64 | };
65 |
66 | Input.prototype.setClock = function (clk) {
67 | this.clock = Boolean(clk);
68 | };
69 |
70 | /*
71 | Sets the input state
72 | */
73 | Input.prototype.setState = function (s) {
74 | this.state = s;
75 | this.outputs = s;
76 | };
77 |
78 | Input.prototype.setIsTop = function (b) {
79 | this.isTop = b;
80 | };
81 |
82 | Input.prototype.setSpeed = function (s) {
83 | this.speed = s;
84 | };
85 |
86 | Input.prototype.resetFramecount = function () {
87 | this.framecount = this.speed;
88 | this.clock = true;
89 | };
90 |
91 | /*
92 | Toggles the state
93 | */
94 | Input.prototype.toggle = function () {
95 | this.setState(!this.state);
96 | };
97 |
98 | Input.prototype.getOutput = function () {
99 | return this.state;
100 | };
101 |
102 | Input.prototype.mark = function (b) {
103 | this.marked = b;
104 | };
105 |
106 | /*
107 | Sets the coordinates of the output, rounded to grid size
108 | */
109 | Input.prototype.setCoordinates = function (nx, ny) {
110 | this.x = Math.round(nx / GRIDSIZE) * GRIDSIZE - GRIDSIZE / 2;
111 | this.y = Math.round(ny / GRIDSIZE) * GRIDSIZE - GRIDSIZE / 2;
112 | // Check bounds
113 | /*if (this.x < 15) {
114 | this.x = 15;
115 | }
116 | if (this.y < 15) {
117 | this.y = 15;
118 | }*/
119 | };
120 |
121 | Input.prototype.updateClickBox = function () {
122 | this.clickBox.updatePosition(this.x + GRIDSIZE / 2, this.y + GRIDSIZE / 2);
123 | this.clickBox.setTransform(transform);
124 | };
125 |
126 | /*
127 | Checks if the mouse is inside the clickBox
128 | */
129 | Input.prototype.mouseOver = function () {
130 | return this.clickBox.mouseOver();
131 | };
132 |
133 | /*
134 | Checks if a certain point is in the output
135 | */
136 | Input.prototype.pointInOutput = function (dummy, px, py) {
137 | return this.clickBox.checkPoint(px, py);
138 | };
139 |
140 | /*
141 | Displays the input on the screen
142 | */
143 | Input.prototype.show = function (order = 0) {
144 | stroke(0);
145 | strokeWeight(3);
146 | if (this.state) {
147 | fill(this.highColor);
148 | } else if (this.marked) {
149 | stroke(MRED, MGREEN, MBLUE);
150 | fill(150);
151 | } else {
152 | fill(this.lowColor);
153 | }
154 | // Draw the rectangle that represents the input
155 | rect(this.x, this.y, this.w, this.h);
156 | noStroke();
157 | if (this.state) {
158 | fill(HARED, HAGREEN, HABLUE);
159 | } else if (this.marked) {
160 | fill(170);
161 | } else {
162 | fill(LARED, LAGREEN, LABLUE);
163 | }
164 | triangle(this.x + 2, this.y + 2, this.x + GRIDSIZE - 2, this.y + 2, this.x + 2, this.y + GRIDSIZE - 2);
165 | noFill();
166 | if (this.marked) {
167 | stroke(MRED, MGREEN, MBLUE);
168 | } else {
169 | stroke(0);
170 | }
171 | rect(this.x, this.y, this.w, this.h);
172 | if (this.framecount >= 0 && !this.clock) {
173 | if (this.marked) {
174 | fill(MRED, MGREEN, MBLUE);
175 | } else {
176 | fill(0);
177 | }
178 | if (this.state) {
179 | strokeWeight(7);
180 | }
181 | rect(this.x + 10, this.y + 10, this.w / 3, this.h / 3);
182 | }
183 |
184 | if (this.clock) {
185 | if (this.marked) {
186 | stroke(MRED, MGREEN, MBLUE);
187 | } else {
188 | stroke(0);
189 | }
190 | strokeWeight(3);
191 | line(this.x + 15, this.y + 6, this.x + 15, this.y + 15);
192 | line(this.x + 15, this.y + 15, this.x + 22, this.y + 20);
193 | }
194 |
195 | if (order > 0) {
196 | noStroke();
197 | fill(255);
198 | textSize(20);
199 | textFont('ArcaMajora3');
200 | textAlign(LEFT, TOP);
201 | if (order.toString().length === 1) {
202 | text(order, this.x + 10, this.y + 7);
203 | } else {
204 | text(order, this.x + 4, this.y + 7);
205 | }
206 | }
207 |
208 | //this.clickBox.markClickBox();
209 | };
210 |
--------------------------------------------------------------------------------
/javascripts/classes/label.js:
--------------------------------------------------------------------------------
1 | // File: label.js
2 |
3 | function Label(x, y, txt) {
4 | this.x = x; // X position
5 | this.y = y; // Y position
6 | this.h = 20;
7 | this.w = 0;
8 | this.txt = txt; // Label text
9 | this.lines = [];
10 | this.marked = false;
11 |
12 | this.id = 'l' + Date.now() + Math.random();
13 |
14 | this.clickBox = new ClickBox(this.x, this.y, this.w, this.h, transform);
15 |
16 | this.getData = function () {
17 | var data = {};
18 | data.x = JSON.stringify(this.x);
19 | data.y = JSON.stringify(this.y);
20 | data.txt = this.txt;
21 | return data;
22 | };
23 |
24 | /*
25 | Sets the coordinates of the label, rounded to grid size
26 | */
27 | this.setCoordinates = function (nx, ny) {
28 | this.x = Math.round(nx / GRIDSIZE) * GRIDSIZE;
29 | this.y = Math.round(ny / GRIDSIZE) * GRIDSIZE;
30 | };
31 |
32 | this.setCoordinates(x, y);
33 |
34 | this.mark = function (marked) {
35 | this.marked = marked;
36 | };
37 |
38 | this.alterPosition = function (x1, y1) {
39 | this.x += x1;
40 | this.y += y1;
41 | this.updateClickBox();
42 | };
43 |
44 | this.updateClickBox = function () {
45 | this.clickBox.updatePosition(this.x + this.w / 2 - 15, this.y + this.h / 2 - 10);
46 | this.clickBox.updateSize(this.w, this.h + 10);
47 | this.clickBox.setTransform(transform);
48 | };
49 |
50 | this.alterText = function (txt) {
51 | this.txt = txt;
52 | this.lines = txt.split('\n').filter(e => e !== '');
53 | if (this.lines.length === 0) {
54 | this.lines = ['New Label'];
55 | }
56 | this.w = Math.ceil((textWidth(this.lines.reduce(function (a, b) { return a.length > b.length ? a : b; })) + 20) / 30) * 30;
57 | this.h = 30 * this.lines.length - 10;
58 | this.updateClickBox();
59 | };
60 |
61 | textFont('Gudea');
62 | textSize(20);
63 | this.alterText(txt);
64 |
65 | /*
66 | Checks if the mouse is inside the clickBox
67 | */
68 | this.mouseOver = function () {
69 | return this.clickBox.mouseOver();
70 | };
71 |
72 | this.show = function () {
73 | strokeWeight(3);
74 | stroke(140);
75 | noStroke();
76 | fill(150, 200);
77 | rect(this.x, this.y - 15, this.w, this.h + 10);
78 | if (this.marked) {
79 | fill(MRED, MGREEN, MBLUE);
80 | } else {
81 | fill(50);
82 | }
83 | for (let i = 0; i < this.lines.length; i++) {
84 | rect(this.x, this.y - 15 + i * 30, 3, 30);
85 | }
86 | if (this.marked) {
87 | fill(255);
88 | } else {
89 | fill(0);
90 | }
91 | for (let i = 0; i < this.lines.length; i++) {
92 | text(this.lines[i], this.x + 15, this.y - 9 + i * 30, this.w, this.h);
93 | }
94 | //this.clickBox.markClickBox();
95 | };
96 | }
97 |
--------------------------------------------------------------------------------
/javascripts/classes/output.js:
--------------------------------------------------------------------------------
1 | // File: output.js
2 |
3 | function Output(x, y, colr) {
4 | this.x = x; // X-Position
5 | this.y = y; // Y-Position
6 | this.w = GRIDSIZE; // Width of the putput
7 | this.h = GRIDSIZE; // Height of the output
8 | this.state = false; // Output state
9 | this.lbl = '';
10 | this.colr = colr; // 0 = red, 1 = yellow, 2 = green, 3 = blue
11 | this.marked = false;
12 | this.highColor = color(HRED, HGREEN, HBLUE); // Color for high outputs
13 | this.accentColor = color(HARED, HAGREEN, HABLUE);
14 | //this.lowColor = color(LRED, LGREEN, LBLUE); // Color for low outputs
15 | //this.markColor = color(MRED, MGREEN, MBLUE); // Color for marked outputs
16 |
17 | this.id = 'o' + Date.now() + Math.random();
18 |
19 | // ClickBox is used for input and global
20 | this.clickBox = new ClickBox(this.x, this.y, this.w, this.h, transform);
21 |
22 | this.updateColor();
23 | this.updateClickBox();
24 | }
25 |
26 | /*
27 | Manually sets the output state
28 | */
29 | Output.prototype.setInput = function (dummy, s) {
30 | this.state = s;
31 | };
32 |
33 | Output.prototype.getData = function () {
34 | var data = {};
35 | data.x = JSON.stringify(this.x);
36 | data.y = JSON.stringify(this.y);
37 | data.colr = JSON.stringify(this.colr);
38 | if (this.lbl !== '') {
39 | data.lbl = this.lbl;
40 | }
41 | return data;
42 | };
43 |
44 | /*
45 | Sets the coordinates of the output, rounded to grid size
46 | */
47 | Output.prototype.setCoordinates = function (nx, ny) {
48 | this.x = Math.round(nx / GRIDSIZE) * GRIDSIZE;
49 | this.y = Math.round(ny / GRIDSIZE) * GRIDSIZE;
50 | };
51 |
52 | Output.prototype.updateClickBox = function () {
53 | this.clickBox.updatePosition(this.x, this.y);
54 | this.clickBox.setTransform(transform);
55 | };
56 |
57 | Output.prototype.alterPosition = function (x1, y1) {
58 | this.x += x1;
59 | this.y += y1;
60 | this.updateClickBox();
61 | };
62 |
63 | /*
64 | Checks if the mouse is inside the clickBox
65 | */
66 | Output.prototype.mouseOver = function () {
67 | return this.clickBox.mouseOver();
68 | };
69 |
70 | Output.prototype.pointInInput = function (dummy, px, py) {
71 | return this.clickBox.checkPoint(px, py);
72 | };
73 |
74 | Output.prototype.mark = function (b) {
75 | this.marked = b;
76 | };
77 |
78 | Output.prototype.updateColor = function () {
79 | switch (this.colr) {
80 | case 0:
81 | this.highColor = color(HRED, HGREEN, HBLUE);
82 | this.accentColor = color(HARED, HAGREEN, HABLUE);
83 | break;
84 | case 1:
85 | this.highColor = color(YRED, YGREEN, YBLUE);
86 | this.accentColor = color(YARED, YAGREEN, YABLUE);
87 | break;
88 | case 2:
89 | this.highColor = color(GRED, GGREEN, GBLUE);
90 | this.accentColor = color(GARED, GAGREEN, GABLUE);
91 | break;
92 | case 3:
93 | this.highColor = color(BRED, BGREEN, BBLUE);
94 | this.accentColor = color(BARED, BAGREEN, BABLUE);
95 | break;
96 | default:
97 | this.highColor = color(HRED, HGREEN, HBLUE);
98 | this.accentColor = color(HARED, HAGREEN, HABLUE);
99 | console.log('Notice: Output color is invalid, setting to red');
100 | break;
101 | }
102 | };
103 |
104 | /*
105 | Displays the output on the screen
106 | */
107 | Output.prototype.show = function (order = 0) {
108 | stroke(0);
109 | strokeWeight(3);
110 | if (this.state) {
111 | fill(this.highColor);
112 | } else if (this.marked) {
113 | stroke(MRED, MGREEN, MBLUE);
114 | fill(150);
115 | } else {
116 | fill(50);
117 | }
118 | // Draw the circle that represents the output
119 | ellipse(this.x, this.y, this.w, this.h);
120 | if (this.state) {
121 | fill(this.accentColor);
122 | } else if (this.marked) {
123 | fill(170);
124 | } else {
125 | fill(LARED, LAGREEN, LABLUE);
126 | }
127 | arc(this.x, this.y, GRIDSIZE, GRIDSIZE, HALF_PI + QUARTER_PI, PI + HALF_PI + QUARTER_PI, OPEN);
128 |
129 | if (order > 0) {
130 | noStroke();
131 | fill(255);
132 | textSize(20);
133 | textFont('ArcaMajora3');
134 | textAlign(LEFT, TOP);
135 | if (order.toString().length === 1) {
136 | text(order, this.x - 6, this.y - 8);
137 | } else {
138 | text(order, this.x - 12, this.y - 8);
139 | }
140 | }
141 | /*if (!this.state) {
142 | stroke(200);
143 | } else {
144 | stroke(255);
145 | }*/
146 | //strokeWeight(3);
147 | //noFill();
148 | //arc(this.x, this.y, 20, 20, PI, PI + HALF_PI);
149 | //this.clickBox.markClickBox();
150 | };
151 |
--------------------------------------------------------------------------------
/javascripts/classes/transformation.js:
--------------------------------------------------------------------------------
1 | // File: transformation.js
2 |
3 | function Transformation(dx, dy, zoom) {
4 | this.dx = dx;
5 | this.dy = dy;
6 | this.zoom = zoom;
7 | }
--------------------------------------------------------------------------------
/javascripts/classes/wire.js:
--------------------------------------------------------------------------------
1 | // File: wire.js
2 |
3 | function Wire(dir, startX, startY, mimicBus = false) {
4 | this.highColor = color(HRED, HGREEN, HBLUE); // Color for high
5 | this.lowColor = color(LRED, LGREEN, LBLUE); // Color for low
6 | this.markedColor = color(MRED, MGREEN, MBLUE); // Color for marked
7 |
8 | this.state = false; // Wire state (false low, true high);
9 |
10 | this.direction = dir; // 0 or 1, meaning horizontal or vertical
11 |
12 | this.startX = 0; // Start point of the segment
13 | this.startY = 0;
14 |
15 | this.endX = 0;
16 | this.endY = 0;
17 |
18 | this.mimicBus = mimicBus;
19 |
20 | this.marked = false;
21 |
22 | this.group = -1;
23 |
24 | this.id = 'w' + Date.now() + Math.random();
25 |
26 | this.changePosition(startX, startY); // Initialize the start point
27 | }
28 |
29 | Wire.prototype.getData = function () {
30 | var data = {};
31 | data.x1 = JSON.stringify(this.startX);
32 | data.y1 = JSON.stringify(this.startY);
33 | if (this.startX !== this.endX) {
34 | data.x2 = JSON.stringify(this.endX);
35 | } else {
36 | data.y2 = JSON.stringify(this.endY);
37 | }
38 | return data;
39 | };
40 |
41 | Wire.prototype.alterPosition = function (x1, y1) {
42 | this.endX += x1;
43 | this.endY += y1;
44 | this.startX += x1;
45 | this.startY += y1;
46 | };
47 |
48 | Wire.prototype.changePosition = function (newX, newY) {
49 | this.startX = Math.round(newX / GRIDSIZE) * GRIDSIZE;
50 | this.startY = Math.round(newY / GRIDSIZE) * GRIDSIZE;
51 | switch (this.direction) {
52 | case 0:
53 | this.endX = this.startX + GRIDSIZE;
54 | this.endY = this.startY;
55 | break;
56 | case 1:
57 | this.endY = this.startY + GRIDSIZE;
58 | this.endX = this.startX;
59 | break;
60 | default:
61 | console.log('No valid direction given!');
62 | }
63 | };
64 |
65 | Wire.prototype.setState = function (s) {
66 | this.state = s;
67 | };
68 |
69 | Wire.prototype.setGroup = function (g) {
70 | this.group = g;
71 | };
72 |
73 | Wire.prototype.getOutput = function () {
74 | return this.state;
75 | };
76 |
77 | Wire.prototype.show = function (del = false, num='') {
78 | if (this.state || del) {
79 | strokeWeight(5);
80 | } else {
81 | strokeWeight(3);
82 | }
83 | if (this.mimicBus) {
84 | strokeWeight(6);
85 | }
86 | if (this.state) {
87 | stroke(this.highColor);
88 | } else if (this.marked || del) {
89 | stroke(this.markedColor);
90 | } else {
91 | stroke(this.lowColor);
92 | }
93 | line(this.startX, this.startY, this.endX, this.endY);
94 | /*if (this.mimicBus) {
95 | strokeWeight(3);
96 | if (this.direction === 0) {
97 | line(this.startX + Math.abs((this.endX - this.startX) / 2) - 10, this.startY + 10, this.startX + Math.abs((this.endX - this.startX) / 2) + 10, this.endY - 10);
98 | } else {
99 | line(this.startX - 10, this.startY + Math.abs((this.endY - this.startY) / 2) + 10, this.endX + 10, this.startY + Math.abs((this.endY - this.startY) / 2) - 10);
100 | }
101 | }*/
102 | /*noStroke();
103 | fill(0);
104 | if (this.direction === 0) {
105 | text(num, Math.min(this.startX, this.endX) + 10, this.startY - 15);
106 | } else {
107 | text(num, this.startX + 10, Math.min(this.startY, this.endY) + 15);
108 | }*/
109 | };
--------------------------------------------------------------------------------
/javascripts/constants.js:
--------------------------------------------------------------------------------
1 | // File: constants.js
2 |
3 | const GRIDSIZE = 30; // Standard grid size (plz don't change)
4 | const WIRECBSIZE = 20; // Size of the wire ClickBoxes
5 | const IOCBSIZE = 20; // Size of the in-/outputs ClickBoxes
6 |
7 | const HRED = 200, HGREEN = 50, HBLUE = 50; // Color for high wires, in- and outputs (red)
8 | const LRED = 0, LGREEN = 0, LBLUE = 0; // Color for low wires (black)
9 | const MRED = 169, MGREEN = 8, MBLUE = 28; // Color for marked elements (darker red)
10 | const YRED = 240, YGREEN = 240, YBLUE = 50; // Color for yellow outputs
11 | const GRED = 40, GGREEN = 180, GBLUE = 40; // Color for green outputs
12 | const BRED = 10, BGREEN = 100, BBLUE = 190; // Color for blue outputs
13 | const HARED = 209, HAGREEN = 71, HABLUE = 71; // Accent color for high in- and outputs (red)
14 | const LARED = 70, LAGREEN = 70, LABLUE = 70; // Accent color for low elements (dark grey)
15 | const MARED = 200, MAGREEN = 50, MABLUE = 50; // Accent color for marked elements (red)
16 | const YARED = 255, YAGREEN = 255, YABLUE = 83; // Accent color for yellow outputs
17 | const GARED = 78, GAGREEN = 208, GABLUE = 69; // Accent color for green outputs
18 | const BARED = 63, BAGREEN = 125, BABLUE = 218; // Accent color for blue outputs
19 |
20 | // Array indizees for the param array
21 | const GATENUM = 0; // Index of the gates
22 | const OUTPNUM = 1; // Index of the outputs
23 | const INPNUM = 2; // Index of the inputs
24 | const WIRENUM = 3; // Index of the wires
25 | const CPNUM = 4; // Index of the conPoints
26 | const CUSTNUM = 5; // Index of the customs
27 | const DINUM = 6; // Index of the diodes
28 | const DECNUM = 7;
29 | const BUSNUM = 8;
30 | const BUSINNUM = 9;
31 | const UNWRAPNUM = 10;
32 | const WRAPNUM = 11;
33 |
34 | const BUTCOUNT = 10; // Number of frames the button should be high
35 |
36 | const HIST_LENGTH = 20; // Max number of undos possible
--------------------------------------------------------------------------------
/javascripts/modifierMenu.js:
--------------------------------------------------------------------------------
1 | // File: modifierMenu.js
2 | // Contains functions for the modifier mode
3 |
4 | function enterModifierMode() {
5 | customDialog.hide();
6 | closeSaveDialog();
7 | screenshotDialog = false;
8 | closeModifierMenu();
9 | justClosedMenu = false;
10 | hideModuleOptions();
11 | hideAllOptions();
12 | setUnactive();
13 | setControlMode('modify');
14 | setSelectMode('none');
15 | editButton.classList.add('active');
16 | configureButtons('edit');
17 | document.getElementById('select-tools').style.display = 'none';
18 | document.getElementById('screenshot-dialog').style.display = 'none';
19 | mainCanvas.elt.classList.remove('dark-canvas');
20 | addType = 0;
21 | }
22 |
23 | function closeModifierMenu() {
24 | hideElementMenus(); // Hide all element menus
25 | unmarkPropTargets(); // Unmark all outputs, clocks, etc.
26 | mainCanvas.elt.classList.remove('dark-canvas'); // Lighten up the canvas
27 | }
28 |
29 | /*
30 | Unmarks all objects that can be marked in the modifier mode
31 | */
32 | function unmarkPropTargets() {
33 | for (const elem of inputs) {
34 | elem.mark(false);
35 | }
36 | for (const elem of outputs) {
37 | elem.mark(false);
38 | }
39 | for (const elem of busInputs) {
40 | elem.mark(false);
41 | }
42 | for (const elem of labels) {
43 | elem.mark(false);
44 | }
45 | inputToModify = -1;
46 | outputToModify = -1;
47 | labelToModify = -1;
48 | }
49 |
50 | /*
51 | Unmarks all markable objects, for example after dragging a selection
52 | */
53 | function unmarkAll() {
54 | for (const elem of inputs) {
55 | elem.mark(false);
56 | }
57 | for (const elem of outputs) {
58 | elem.mark(false);
59 | }
60 | for (const elem of labels) {
61 | elem.mark(false);
62 | }
63 | for (const elem of gates) {
64 | elem.marked = false;
65 | }
66 | for (const elem of customs) {
67 | elem.marked = false;
68 | }
69 | for (const elem of conpoints) {
70 | elem.marked = false;
71 | }
72 | for (const elem of diodes) {
73 | elem.marked = false;
74 | }
75 | for (const elem of wires) {
76 | elem.marked = false;
77 | }
78 | for (const elem of busses) {
79 | elem.marked = false;
80 | }
81 | for (const elem of busWrappers) {
82 | elem.marked = false;
83 | }
84 | for (const elem of busUnwrappers) {
85 | elem.marked = false;
86 | }
87 | for (const elem of busInputs) {
88 | elem.marked = false;
89 | }
90 | for (const elem of decoders) {
91 | elem.marked = false;
92 | }
93 | for (const elem of segDisplays) {
94 | elem.marked = false;
95 | }
96 | }
97 |
98 | /*
99 | Shows the DOM elements for the input options and unmarks all other
100 | objects that can be marked in modifier mode
101 | */
102 | function showClockPropMenu() {
103 | hideElementMenus();
104 | setClockModifierVisibility(true);
105 | clockspeedSlider.value = 61 - inputs[inputToModify].speed;
106 | if (inputs[inputToModify].speed !== 1) {
107 | document.getElementById('cs-label').innerHTML = inputs[inputToModify].speed + ' ticks/toggle';
108 | } else {
109 | document.getElementById('cs-label').innerHTML = inputs[inputToModify].speed + ' tick/toggle';
110 | }
111 | }
112 |
113 | /*
114 | Shows the DOM elements for the output options and unmarks all other
115 | objects that can be marked in modifier mode
116 | */
117 | function showOutputPropMenu() {
118 | hideElementMenus();
119 | setOutputModifierVisibility(true);
120 | setOutputColor(outputs[outputToModify].colr);
121 | }
122 |
123 | /*
124 | Shows the DOM elements for the label options and unmarks all other
125 | objects that can be marked in modifier mode
126 | */
127 | function showLabelPropMenu() {
128 | hideElementMenus();
129 | setLabelModifierVisibility(true);
130 | labelTextBox.value = labels[labelToModify].txt;
131 | }
132 |
133 | function updateModifierMenuPosition() {
134 | mainCanvas.elt.classList.add('dark-canvas');
135 | if (inputToModify >= 0) {
136 | modifierMenuX = (inputs[inputToModify].x + transform.dx - 1) * transform.zoom;
137 | modifierMenuY = (inputs[inputToModify].y + transform.dy + GRIDSIZE + 2) * transform.zoom;
138 | } else if (outputToModify >= 0) {
139 | modifierMenuX = (outputs[outputToModify].x + transform.dx - GRIDSIZE / 2 - 1) * transform.zoom;
140 | modifierMenuY = (outputs[outputToModify].y + transform.dy + GRIDSIZE / 2 + 2) * transform.zoom;
141 | } else if (labelToModify >= 0) {
142 | modifierMenuX = (labels[labelToModify].x + transform.dx) * transform.zoom;
143 | modifierMenuY = (labels[labelToModify].y + transform.dy + GRIDSIZE / 2 + GRIDSIZE * (labels[labelToModify].lines.length - 1)) * transform.zoom;
144 | }
145 | }
146 |
147 | function positionModifierElements() {
148 | document.getElementById('clock-modifier').style.left = modifierMenuX + 240 + 'px';
149 | document.getElementById('clock-modifier').style.top = modifierMenuY + 'px';
150 |
151 | document.getElementById('output-modifier').style.left = modifierMenuX + 240 + 'px';
152 | document.getElementById('output-modifier').style.top = modifierMenuY + 'px';
153 |
154 | document.getElementById('label-modifier').style.left = modifierMenuX + 240 + 'px';
155 | document.getElementById('label-modifier').style.top = modifierMenuY + 'px';
156 | }
157 |
158 | function swapOutputs(a, b) {
159 | outputs[a] = outputs.splice(b, 1, outputs[a])[0];
160 | }
161 |
162 | /*
163 | Updates the color of the marked output according to the
164 | selected color in the select box
165 | */
166 | function newOutputColor(code) {
167 | setOutputColor(code);
168 | outputs[outputToModify].colr = code;
169 | outputs[outputToModify].updateColor();
170 | }
171 |
172 | function setOutputColor(code) {
173 | setColorButtonsUnactive();
174 | switch (code) {
175 | case 0:
176 | redButton.classList.add('active');
177 | break;
178 | case 1:
179 | yellowButton.classList.add('active');
180 | break;
181 | case 2:
182 | greenButton.classList.add('active');
183 | break;
184 | case 3:
185 | blueButton.classList.add('active');
186 | break;
187 | default:
188 | }
189 | hideAllOptions();
190 | }
191 |
192 | function setOutputModifierVisibility(show) {
193 | if (show) {
194 | document.getElementById('output-modifier').style.display = 'block';
195 | } else {
196 | document.getElementById('output-modifier').style.display = 'none';
197 | }
198 | }
199 |
200 | function setClockModifierVisibility(show) {
201 | if (show) {
202 | document.getElementById('clock-modifier').style.display = 'block';
203 | } else {
204 | document.getElementById('clock-modifier').style.display = 'none';
205 | }
206 | }
207 |
208 | function setLabelModifierVisibility(show) {
209 | if (show) {
210 | document.getElementById('label-modifier').style.display = 'block';
211 | } else {
212 | document.getElementById('label-modifier').style.display = 'none';
213 | }
214 | }
215 |
216 | function hideElementMenus() {
217 | document.getElementById('output-modifier').style.display = 'none';
218 | document.getElementById('clock-modifier').style.display = 'none';
219 | document.getElementById('label-modifier').style.display = 'none';
220 | }
221 |
222 | function elementMenuShown() {
223 | return (controlMode === 'modify' && (inputToModify + outputToModify + labelToModify >= -2));
224 | }
225 |
226 | function setColorButtonsUnactive() {
227 | redButton.classList.remove('active');
228 | yellowButton.classList.remove('active');
229 | greenButton.classList.remove('active');
230 | blueButton.classList.remove('active');
231 | }
--------------------------------------------------------------------------------
/libraries/stickUp.min.js:
--------------------------------------------------------------------------------
1 | // jshint ignore: start
2 | jQuery(function($){$(document).ready(function(){var contentButton = [];var contentTop = [];var content = [];var lastScrollTop = 0;var scrollDir = '';var itemClass = '';var itemHover = '';var menuSize = null;var stickyHeight = 0;var stickyMarginB = 0;var currentMarginT = 0;var topMargin = 0;$(window).scroll(function(event){var st = $(this).scrollTop();if (st > lastScrollTop){scrollDir = 'down';} else {scrollDir = 'up';}lastScrollTop = st;});$.fn.stickUp = function( options ) {$(this).addClass('stuckMenu');var objn = 0;if(options != null) {for(var o in options.parts) {if (options.parts.hasOwnProperty(o)){content[objn] = options.parts[objn];objn++;}}if(objn == 0) {console.log('error:needs arguments');}itemClass = options.itemClass;itemHover = options.itemHover;if(options.topMargin != null) {if(options.topMargin == 'auto') {topMargin = parseInt($('.stuckMenu').css('margin-top'));} else {if(isNaN(options.topMargin) && options.topMargin.search("px") > 0){topMargin = parseInt(options.topMargin.replace("px",""));} else if(!isNaN(parseInt(options.topMargin))) {topMargin = parseInt(options.topMargin);} else {console.log("incorrect argument, ignored.");topMargin = 0;} }} else {topMargin = 0;}menuSize = $('.'+itemClass).size();}stickyHeight = parseInt($(this).height());stickyMarginB = parseInt($(this).css('margin-bottom'));currentMarginT = parseInt($(this).next().closest('div').css('margin-top'));vartop = parseInt($(this).offset().top);};$(document).on('scroll', function() {varscroll = parseInt($(document).scrollTop());if(menuSize != null){for(var i=0;i < menuSize;i++){contentTop[i] = $('#'+content[i]+'').offset().top;function bottomView(i) {contentView = $('#'+content[i]+'').height()*.4;testView = contentTop[i] - contentView;if(varscroll > testView){$('.'+itemClass).removeClass(itemHover);$('.'+itemClass+':eq('+i+')').addClass(itemHover);} else if(varscroll < 50){$('.'+itemClass).removeClass(itemHover);$('.'+itemClass+':eq(0)').addClass(itemHover);}}if(scrollDir == 'down' && varscroll > contentTop[i]-50 && varscroll < contentTop[i]+50) {$('.'+itemClass).removeClass(itemHover);$('.'+itemClass+':eq('+i+')').addClass(itemHover);}if(scrollDir == 'up') {bottomView(i);}}}if(vartop < varscroll + topMargin){$('.stuckMenu').addClass('isStuck');$('.stuckMenu').next().closest('div').css({'margin-top': stickyHeight + stickyMarginB + currentMarginT + 'px'}, 10);$('.stuckMenu').css("position","fixed");$('.isStuck').css({top: '0px'}, 10, function(){});};if(varscroll + topMargin < vartop){$('.stuckMenu').removeClass('isStuck');$('.stuckMenu').next().closest('div').css({'margin-top': currentMarginT + 'px'}, 10);$('.stuckMenu').css("position","relative");};});});});
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "logijs",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "site_scripts/index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "author": "Simon Buchholz",
10 | "license": "gpl-3.0",
11 | "dependencies": {
12 | "base64url": "^3.0.1",
13 | "body-parser": "^1.19.0",
14 | "config": "^3.2.2",
15 | "cookie-parser": "^1.4.4",
16 | "crypto": "^1.0.1",
17 | "dot-prop": "^5.3.0",
18 | "email-validator": "^2.0.4",
19 | "express": "^4.17.1",
20 | "express-fileupload": "^1.1.9",
21 | "express-session": "^1.16.2",
22 | "fs": "0.0.1-security",
23 | "glob": "^7.1.4",
24 | "joi": "^14.3.1",
25 | "jsonwebtoken": "^8.5.1",
26 | "knex": "^0.19.5",
27 | "mysql": "^2.17.1",
28 | "nodemon": "^2.0.5",
29 | "password-validator": "^5.0.2",
30 | "pug": "^3.0.1",
31 | "sharp": "^0.23.0",
32 | "socket.io": "^2.4.0"
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/public.key:
--------------------------------------------------------------------------------
1 | -----BEGIN PUBLIC KEY-----
2 | MFswDQYJKoZIhvcNAQEBBQADSgAwRwJAfJ+DXfA7nCBIDcxpNbTBICYSvpLB7MZ3
3 | NqsoBuebNOoZQ8n1zdCJt5wCm4+uX7Ca3we1YXwnvPUsxYmFf14RQwIDAQAB
4 | -----END PUBLIC KEY-----
--------------------------------------------------------------------------------
/site_scripts/create_account.js:
--------------------------------------------------------------------------------
1 | const CreateUser = document.querySelector('.SignUp');
2 | CreateUser.addEventListener('submit', (e) => {
3 | e.preventDefault();
4 | const username = CreateUser.querySelector('.username').value;
5 | const email = CreateUser.querySelector('.email').value;
6 | const password = CreateUser.querySelector('.password').value;
7 | post('/createUser', {
8 | username: username,
9 | email: email,
10 | password: password
11 | }).then(function (data) {
12 | if (data.error_code === 0) {
13 | window.location = '/login?signup_success=true';
14 | } else {
15 | window.location = '/signup?error_code=' + data.error_code;
16 | }
17 | });
18 | });
19 |
20 | function post(path, data) {
21 | return window.fetch(path, {
22 | method: 'POST',
23 | headers: {
24 | 'Accept': 'application/json',
25 | 'Content-Type': 'application/json'
26 | },
27 | body: JSON.stringify(data)
28 | })
29 | .then(function (res) { console.log(res.ok); return res.json(); })
30 | .then(function (data) { return data; });
31 | }
32 |
33 | const currentTheme = localStorage.getItem('theme');
34 |
35 | if (currentTheme === 'dark') {
36 | document.documentElement.classList.toggle('dark-theme');
37 | document.getElementById('top_logo').src = 'images/logo_index_new_white.png';
38 | document.getElementById('mode-button').innerHTML = '';
39 | }
40 |
41 | document.getElementById('mode-button').addEventListener('click', function () {
42 | let theme = 'light';
43 | document.documentElement.classList.toggle('dark-theme');
44 | if (document.documentElement.classList.contains('dark-theme')) {
45 | theme = 'dark';
46 | document.getElementById('top_logo').src = 'images/logo_index_new_white.png';
47 | document.getElementById('mode-button').innerHTML = '';
48 | } else {
49 | theme = 'light';
50 | document.getElementById('top_logo').src = 'images/logo_index_new.png';
51 | document.getElementById('mode-button').innerHTML = '';
52 | }
53 | localStorage.setItem('theme', theme);
54 | });
--------------------------------------------------------------------------------
/site_scripts/dashboard.js:
--------------------------------------------------------------------------------
1 | let confButton = '';
2 |
3 | const Logout = document.querySelectorAll('.Logout');
4 | for (const button of Logout) {
5 | button.addEventListener('click', (e) => { //jshint ignore:line
6 | e.preventDefault();
7 | setCookie('access_token', '', -1);
8 | window.location = '/';
9 | });
10 | }
11 |
12 | const openButtons = document.querySelectorAll(".btn.open");
13 | for (const button of openButtons) {
14 | button.addEventListener('click', function (event) { //jshint ignore:line
15 | window.location = '/editor?sketch=' + event.target.id;
16 | });
17 | }
18 |
19 | const deleteButtons = document.querySelectorAll(".delete");
20 | for (const button of deleteButtons) {
21 | button.addEventListener('click', function (event) { //jshint ignore:line
22 | if (confButton !== event.target.id) {
23 | button.innerHTML = ' SURE?';
24 | confButton = event.target.id;
25 | } else {
26 | confButton = '';
27 | post('/delete', {
28 | sketch: event.currentTarget.id
29 | });
30 | location.reload();
31 | }
32 | });
33 | }
34 |
35 | const downloadButtons = document.querySelectorAll(".download");
36 | for (const button of downloadButtons) {
37 | button.addEventListener('click', function (event) { //jshint ignore:line
38 | event.preventDefault();
39 | window.location = '/download?file=' + event.currentTarget.id.substring(2);
40 | });
41 | }
42 |
43 | function post(path, data) {
44 | return window.fetch(path, {
45 | method: 'POST',
46 | headers: {
47 | 'Accept': 'application/json',
48 | 'Content-Type': 'application/json'
49 | },
50 | body: JSON.stringify(data)
51 | });
52 | }
53 |
54 | function setCookie(name, value, days) {
55 | var d = new Date();
56 | d.setTime(d.getTime() + 24 * 60 * 60 * 1000 * days);
57 | document.cookie = name + "=" + value + ";path=/;expires=" + d.toGMTString();
58 |
59 | }
60 |
61 | const currentTheme = localStorage.getItem('theme');
62 |
63 | if (currentTheme === 'dark') {
64 | document.documentElement.classList.toggle('dark-theme');
65 | document.getElementById('top_logo').src = 'images/logo_index_new_white.png';
66 | document.getElementById('mode-button').innerHTML = '';
67 | }
68 |
69 | document.getElementById('mode-button').addEventListener('click', function () {
70 | let theme = 'light';
71 | document.documentElement.classList.toggle('dark-theme');
72 | if (document.documentElement.classList.contains('dark-theme')) {
73 | theme = 'dark';
74 | document.getElementById('top_logo').src = 'images/logo_index_new_white.png';
75 | document.getElementById('mode-button').innerHTML = '';
76 | } else {
77 | theme = 'light';
78 | document.getElementById('top_logo').src = 'images/logo_index_new.png';
79 | document.getElementById('mode-button').innerHTML = '';
80 | }
81 | localStorage.setItem('theme', theme);
82 | });
83 |
--------------------------------------------------------------------------------
/site_scripts/eduSignup.js:
--------------------------------------------------------------------------------
1 | const CreateUser = document.querySelector('.SignUp');
2 | CreateUser.addEventListener('submit', (e) => {
3 | e.preventDefault();
4 | const username = CreateUser.querySelector('.username').value;
5 | const email = CreateUser.querySelector('.email').value;
6 | const password = CreateUser.querySelector('.password').value;
7 | post('/createUser', {
8 | username: username,
9 | email: email,
10 | password: password
11 | }).then(function (data) {
12 | if (data.error_code === 0) {
13 | window.location = '/?signup_success=true';
14 | } else {
15 | window.location = '/signup?error_code=' + data.error_code;
16 | }
17 | });
18 | });
19 |
20 | function post(path, data) {
21 | return window.fetch(path, {
22 | method: 'POST',
23 | headers: {
24 | 'Accept': 'application/json',
25 | 'Content-Type': 'application/json'
26 | },
27 | body: JSON.stringify(data)
28 | })
29 | .then(function (res) { console.log(res.ok); return res.json(); })
30 | .then(function (data) { return data; });
31 | }
32 |
33 | const currentTheme = localStorage.getItem('theme');
34 |
35 | if (currentTheme === 'dark') {
36 | document.documentElement.classList.toggle('dark-theme');
37 | document.getElementById('top_logo').src = 'images/logo_index_new_white.png';
38 | document.getElementById('mode-button').innerHTML = '';
39 | }
40 |
41 | document.getElementById('mode-button').addEventListener('click', function () {
42 | let theme = 'light';
43 | document.documentElement.classList.toggle('dark-theme');
44 | if (document.documentElement.classList.contains('dark-theme')) {
45 | theme = 'dark';
46 | document.getElementById('top_logo').src = 'images/logo_index_new_white.png';
47 | document.getElementById('mode-button').innerHTML = '';
48 | } else {
49 | theme = 'light';
50 | document.getElementById('top_logo').src = 'images/logo_index_new.png';
51 | document.getElementById('mode-button').innerHTML = '';
52 | }
53 | localStorage.setItem('theme', theme);
54 | });
--------------------------------------------------------------------------------
/site_scripts/edu_tutorial.js:
--------------------------------------------------------------------------------
1 | const Logout = document.querySelectorAll('.Logout');
2 | for (const button of Logout) {
3 | button.addEventListener('click', (e) => { //jshint ignore:line
4 | e.preventDefault();
5 | setCookie('access_token', '', -1);
6 | window.location = '/';
7 | });
8 | }
9 |
10 | function setCookie(name, value, days) {
11 | var d = new Date();
12 | d.setTime(d.getTime() + 24 * 60 * 60 * 1000 * days);
13 | document.cookie = name + "=" + value + ";path=/;expires=" + d.toGMTString();
14 | }
15 |
16 | window.onscroll = function () { scrollFunction(); };
17 | function scrollFunction() {
18 | if (document.body.scrollTop > 50 || document.documentElement.scrollTop > 50) {
19 | document.getElementsByClassName("navbar-brand")[0].style.setProperty("transform", "scale(0.6)");
20 | document.getElementsByClassName("navbar-header")[0].style.setProperty("top", "-20px");
21 | document.getElementById("front_teaser").style.opacity = "0";
22 | document.getElementById("main-carousel").style.opacity = "1";
23 | } else {
24 | document.getElementsByClassName("navbar-brand")[0].style.setProperty("transform", "scale(1.0)");
25 | document.getElementsByClassName("navbar-header")[0].style.setProperty("top", "10px");
26 | document.getElementById("front_teaser").style.opacity = "1";
27 | document.getElementById("main-carousel").style.opacity = "0";
28 | }
29 | }
30 |
31 | const currentTheme = localStorage.getItem('theme');
32 |
33 | if (currentTheme === 'light') {
34 | document.documentElement.classList.toggle('dark-theme');
35 | document.getElementById('top_logo').src = 'images/logo_index_new.png';
36 | document.getElementById('mode-button').innerHTML = '';
37 | }
38 |
39 | document.getElementById('mode-button').addEventListener('click', function () {
40 | let theme = 'light';
41 | document.documentElement.classList.toggle('dark-theme');
42 | if (document.documentElement.classList.contains('dark-theme')) {
43 | theme = 'dark';
44 | document.getElementById('top_logo').src = 'images/logo_index_new_white.png';
45 | document.getElementById('mode-button').innerHTML = '';
46 | } else {
47 | theme = 'light';
48 | document.getElementById('top_logo').src = 'images/logo_index_new.png';
49 | document.getElementById('mode-button').innerHTML = '';
50 | }
51 | localStorage.setItem('theme', theme);
52 | });
--------------------------------------------------------------------------------
/site_scripts/education.js:
--------------------------------------------------------------------------------
1 | window.onscroll = function () { scrollFunction(); };
2 | function scrollFunction() {
3 | if (document.body.scrollTop > 50 || document.documentElement.scrollTop > 50) {
4 | document.getElementsByClassName("navbar-brand")[0].style.setProperty("transform", "scale(0.6)");
5 | document.getElementsByClassName("navbar-header")[0].style.setProperty("top", "-20px");
6 | } else {
7 | document.getElementsByClassName("navbar-brand")[0].style.setProperty("transform", "scale(1.0)");
8 | document.getElementsByClassName("navbar-header")[0].style.setProperty("top", "10px");
9 | }
10 | }
11 |
12 | const Logout = document.querySelectorAll('.Logout');
13 | for (const button of Logout) {
14 | button.addEventListener('click', (e) => { //jshint ignore:line
15 | e.preventDefault();
16 | setCookie('access_token', '', -1);
17 | window.location = '/';
18 | });
19 | }
20 |
21 | let currentTheme = localStorage.getItem('theme');
22 |
23 | if (currentTheme !== 'light') {
24 | currentTheme = 'dark';
25 | localStorage.setItem('theme', currentTheme);
26 | }
27 |
28 | if (currentTheme === 'dark') {
29 | document.documentElement.classList.toggle('dark-theme');
30 | document.getElementById('top_logo').src = 'images/logo_index_new_white.png';
31 | document.getElementById('mode-button').innerHTML = '';
32 | }
33 |
34 | document.getElementById('mode-button').addEventListener('click', function () {
35 | let theme = 'light';
36 | document.documentElement.classList.toggle('dark-theme');
37 | if (document.documentElement.classList.contains('dark-theme')) {
38 | theme = 'dark';
39 | document.getElementById('top_logo').src = 'images/logo_index_new_white.png';
40 | document.getElementById('mode-button').innerHTML = '';
41 | } else {
42 | theme = 'light';
43 | document.getElementById('top_logo').src = 'images/logo_index_new.png';
44 | document.getElementById('mode-button').innerHTML = '';
45 | }
46 | localStorage.setItem('theme', theme);
47 | });
48 |
49 | function setCookie(name, value, days) {
50 | var d = new Date();
51 | d.setTime(d.getTime() + 24 * 60 * 60 * 1000 * days);
52 | document.cookie = name + "=" + value + ";path=/;expires=" + d.toGMTString();
53 | }
--------------------------------------------------------------------------------
/site_scripts/edulogin.js:
--------------------------------------------------------------------------------
1 | const Login = document.querySelector('.Login');
2 | if (Login !== null) {
3 | Login.addEventListener('submit', (e) => {
4 | e.preventDefault();
5 | const username = Login.querySelector('.username').value;
6 | const password = Login.querySelector('.password').value;
7 | post('/login', { username, password })
8 | .then(function (response) {
9 | if (response.status === 200) {
10 | window.location = '/dashboard';
11 | } else {
12 | window.location = '/?failed=true';
13 | }
14 | });
15 | });
16 | }
17 |
18 | function post(path, data) {
19 | return window.fetch(path, {
20 | method: 'POST',
21 | headers: {
22 | 'Accept': 'application/json',
23 | 'Content-Type': 'application/json'
24 | },
25 | body: JSON.stringify(data)
26 | });
27 | }
28 |
29 | const currentTheme = localStorage.getItem('theme');
30 |
31 | if (currentTheme === 'dark') {
32 | document.documentElement.classList.toggle('dark-theme');
33 | document.getElementById('top_logo').src = 'images/logo_index_new_white.png';
34 | document.getElementById('mode-button').innerHTML = '';
35 | }
36 |
37 | document.getElementById('mode-button').addEventListener('click', function () {
38 | let theme = 'light';
39 | document.documentElement.classList.toggle('dark-theme');
40 | if (document.documentElement.classList.contains('dark-theme')) {
41 | theme = 'dark';
42 | document.getElementById('top_logo').src = 'images/logo_index_new_white.png';
43 | document.getElementById('mode-button').innerHTML = '';
44 | } else {
45 | theme = 'light';
46 | document.getElementById('top_logo').src = 'images/logo_index_new.png';
47 | document.getElementById('mode-button').innerHTML = '';
48 | }
49 | localStorage.setItem('theme', theme);
50 | });
--------------------------------------------------------------------------------
/site_scripts/getstarted.js:
--------------------------------------------------------------------------------
1 | const Logout = document.querySelectorAll('.Logout');
2 | for (const button of Logout) {
3 | button.addEventListener('click', (e) => { //jshint ignore:line
4 | e.preventDefault();
5 | setCookie('access_token', '', -1);
6 | window.location = '/';
7 | });
8 | }
9 |
10 | const currentTheme = localStorage.getItem('theme');
11 |
12 | if (currentTheme === 'dark') {
13 | document.documentElement.classList.toggle('dark-theme');
14 | document.getElementById('top_logo').src = 'images/logo_index_new_white.png';
15 | document.getElementById('mode-button').innerHTML = '';
16 | document.getElementById('getstarted_teaser').src = 'images/front_teaser.png';
17 | }
18 |
19 | document.getElementById('mode-button').addEventListener('click', function () {
20 | let theme = 'light';
21 | document.documentElement.classList.toggle('dark-theme');
22 | if (document.documentElement.classList.contains('dark-theme')) {
23 | theme = 'dark';
24 | document.getElementById('top_logo').src = 'images/logo_index_new_white.png';
25 | document.getElementById('mode-button').innerHTML = '';
26 | document.getElementById('getstarted_teaser').src = 'images/front_teaser.png';
27 | } else {
28 | theme = 'light';
29 | document.getElementById('top_logo').src = 'images/logo_index_new.png';
30 | document.getElementById('mode-button').innerHTML = '';
31 | document.getElementById('getstarted_teaser').src = 'images/front_teaser_white.png';
32 | }
33 | localStorage.setItem('theme', theme);
34 | });
35 |
36 | function setCookie(name, value, days) {
37 | var d = new Date();
38 | d.setTime(d.getTime() + 24 * 60 * 60 * 1000 * days);
39 | document.cookie = name + "=" + value + ";path=/;expires=" + d.toGMTString();
40 | }
--------------------------------------------------------------------------------
/site_scripts/index_page.js:
--------------------------------------------------------------------------------
1 | window.onscroll = function () { scrollFunction(); };
2 | function scrollFunction() {
3 | if (document.body.scrollTop > 50 || document.documentElement.scrollTop > 50) {
4 | document.getElementsByClassName("navbar-brand")[0].style.setProperty("transform", "scale(0.6)");
5 | document.getElementsByClassName("navbar-header")[0].style.setProperty("top", "-20px");
6 | document.getElementById("front_teaser").style.opacity = "0";
7 | document.getElementById("main-carousel").style.opacity = "1";
8 | } else {
9 | document.getElementsByClassName("navbar-brand")[0].style.setProperty("transform", "scale(1.0)");
10 | document.getElementsByClassName("navbar-header")[0].style.setProperty("top", "10px");
11 | document.getElementById("front_teaser").style.opacity = "1";
12 | if (document.body.clientWidth >= 1024) {
13 | document.getElementById("main-carousel").style.opacity = "0";
14 | }
15 | }
16 | }
17 |
18 | let button = document.getElementsByClassName("all-samples-button")[0];
19 | button.addEventListener("click", function () {
20 | let coll = document.getElementsByClassName("collapsible")[0];
21 | coll.classList.toggle("active");
22 | if (coll.style.maxHeight) {
23 | coll.style.maxHeight = null;
24 | button.innerHTML = " Show All";
25 | } else {
26 | coll.style.maxHeight = coll.scrollHeight + "px";
27 | button.innerHTML = " Show Less";
28 | }
29 | });
30 |
31 | const Logout = document.querySelectorAll('.Logout');
32 | for (const button of Logout) {
33 | button.addEventListener('click', (e) => { //jshint ignore:line
34 | e.preventDefault();
35 | setCookie('access_token', '', -1);
36 | window.location = '/';
37 | });
38 | }
39 |
40 | let currentTheme = localStorage.getItem('theme');
41 |
42 | if (currentTheme !== 'light') {
43 | currentTheme = 'dark';
44 | localStorage.setItem('theme', currentTheme);
45 | }
46 |
47 | if (currentTheme === 'dark') {
48 | document.documentElement.classList.toggle('dark-theme');
49 | document.getElementById('top_logo').src = 'images/logo_index_new_white.png';
50 | document.getElementById('mode-button').innerHTML = '';
51 | document.getElementById('front_teaser').src = 'images/front_teaser.png';
52 | document.getElementById('carousel-1').src = 'images/carousel_1_new_dark.png';
53 | document.getElementById('carousel-2').src = 'images/carousel_2_new_dark.png';
54 | document.getElementById('carousel-3').src = 'images/carousel_3_new_dark.png';
55 | }
56 |
57 | document.getElementById('mode-button').addEventListener('click', function () {
58 | let theme = 'light';
59 | document.documentElement.classList.toggle('dark-theme');
60 | if (document.documentElement.classList.contains('dark-theme')) {
61 | theme = 'dark';
62 | document.getElementById('top_logo').src = 'images/logo_index_new_white.png';
63 | document.getElementById('mode-button').innerHTML = '';
64 | document.getElementById('front_teaser').src = 'images/front_teaser.png';
65 | document.getElementById('carousel-1').src = 'images/carousel_1_new_dark.png';
66 | document.getElementById('carousel-2').src = 'images/carousel_2_new_dark.png';
67 | document.getElementById('carousel-3').src = 'images/carousel_3_new_dark.png';
68 | } else {
69 | theme = 'light';
70 | document.getElementById('top_logo').src = 'images/logo_index_new.png';
71 | document.getElementById('mode-button').innerHTML = '';
72 | document.getElementById('front_teaser').src = 'images/front_teaser_white.png';
73 | document.getElementById('carousel-1').src = 'images/carousel_1_new.png';
74 | document.getElementById('carousel-2').src = 'images/carousel_2_new.png';
75 | document.getElementById('carousel-3').src = 'images/carousel_3_new.png';
76 | }
77 | localStorage.setItem('theme', theme);
78 | });
79 |
80 | function setCookie(name, value, days) {
81 | var d = new Date();
82 | d.setTime(d.getTime() + 24 * 60 * 60 * 1000 * days);
83 | document.cookie = name + "=" + value + ";path=/;expires=" + d.toGMTString();
84 | }
--------------------------------------------------------------------------------
/site_scripts/jwt_module.js:
--------------------------------------------------------------------------------
1 | const fs = require('fs');
2 | const jwt = require('jsonwebtoken');
3 |
4 | // use 'utf8' to get string instead of byte array (512 bit key)
5 | var privateKEY = fs.readFileSync('./private.key', 'utf8');
6 | var publicKEY = fs.readFileSync('./public.key', 'utf8');
7 |
8 | module.exports = {
9 | sign: (payload, $Options) => {
10 | /*
11 | sOptions = {
12 | issuer: "Authorization/Resource/This server",
13 | subject: "iam@user.me",
14 | audience: "Client_Identity" // this should be provided by client
15 | }
16 | */
17 | var signOptions = {
18 | issuer: $Options.issuer,
19 | subject: $Options.subject,
20 | audience: $Options.audience,
21 | expiresIn: "30d",
22 | algorithm: "RS256"
23 | };
24 | return jwt.sign(payload, privateKEY, signOptions);
25 | },
26 | verify: (token, $Option) => {
27 | /*
28 | vOption = {
29 | issuer: "Authorization/Resource/This server",
30 | subject: "iam@user.me",
31 | audience: "Client_Identity" // this should be provided by client
32 | }
33 | */
34 | var verifyOptions = {
35 | issuer: $Option.issuer,
36 | subject: $Option.subject,
37 | audience: $Option.audience,
38 | expiresIn: "30d",
39 | algorithm: ["RS256"]
40 | };
41 | try {
42 | return jwt.verify(token, publicKEY, verifyOptions);
43 | } catch (err) {
44 | return false;
45 | }
46 | },
47 | decode: (token) => {
48 | return jwt.decode(token, { complete: true });
49 | }
50 | };
51 |
--------------------------------------------------------------------------------
/site_scripts/lib_front.js:
--------------------------------------------------------------------------------
1 | const downloadButtons = document.querySelectorAll(".btn.download");
2 | for (const button of downloadButtons) {
3 | button.addEventListener('click', function (event) { //jshint ignore:line
4 | event.preventDefault();
5 | window.location = '/libDownload?file=' + event.currentTarget.id.substring(2);
6 | });
7 | }
--------------------------------------------------------------------------------
/site_scripts/login.js:
--------------------------------------------------------------------------------
1 | const Login = document.querySelector('.Login');
2 | Login.addEventListener('submit', (e) => {
3 | e.preventDefault();
4 | const username = Login.querySelector('.username').value;
5 | const password = Login.querySelector('.password').value;
6 | post('/login', { username, password })
7 | .then(function (response) {
8 | if (response.status === 200) {
9 | window.location = '/dashboard';
10 | } else {
11 | window.location = '/login?failed=true';
12 | }
13 | });
14 | });
15 |
16 | function post(path, data) {
17 | return window.fetch(path, {
18 | method: 'POST',
19 | headers: {
20 | 'Accept': 'application/json',
21 | 'Content-Type': 'application/json'
22 | },
23 | body: JSON.stringify(data)
24 | });
25 | }
26 |
27 | const currentTheme = localStorage.getItem('theme');
28 |
29 | if (currentTheme === 'dark') {
30 | document.documentElement.classList.toggle('dark-theme');
31 | document.getElementById('top_logo').src = 'images/logo_index_new_white.png';
32 | document.getElementById('mode-button').innerHTML = '';
33 | }
34 |
35 | document.getElementById('mode-button').addEventListener('click', function () {
36 | let theme = 'light';
37 | document.documentElement.classList.toggle('dark-theme');
38 | if (document.documentElement.classList.contains('dark-theme')) {
39 | theme = 'dark';
40 | document.getElementById('top_logo').src = 'images/logo_index_new_white.png';
41 | document.getElementById('mode-button').innerHTML = '';
42 | } else {
43 | theme = 'light';
44 | document.getElementById('top_logo').src = 'images/logo_index_new.png';
45 | document.getElementById('mode-button').innerHTML = '';
46 | }
47 | localStorage.setItem('theme', theme);
48 | });
--------------------------------------------------------------------------------
/site_scripts/migrations/20190916195158_create_user_table.js:
--------------------------------------------------------------------------------
1 | exports.up = function (knex) {
2 | return knex.schema.createTable('user', function (t) {
3 | t.increments('id').primary();
4 | t.string('username').notNullable();
5 | t.string('password').notNullable();
6 | t.timestamps(false, false);
7 | });
8 | };
9 |
10 | exports.down = function (knex) {
11 | return knex.schema.dropTableIfExists('user');
12 | };
--------------------------------------------------------------------------------
/site_scripts/migrations/20190916204924_encrypt_user_password.js:
--------------------------------------------------------------------------------
1 | const { saltHashPassword } = require('../store');
2 |
3 | exports.up = function up(knex) {
4 | return knex.schema
5 | .table('user', t => {
6 | t.string('salt').notNullable();
7 | t.string('encrypted_password').notNullable();
8 | })
9 | .then(() => knex('user'))
10 | .then(users => Promise.all(users.map(convertPassword)))
11 | .then(() => {
12 | return knex.schema.table('user', t => {
13 | t.dropColumn('password');
14 | });
15 | });
16 | function convertPassword(user) {
17 | const { salt, hash } = saltHashPassword(user.password);
18 | return knex('user')
19 | .where({ id: user.id })
20 | .update({
21 | salt,
22 | encrypted_password: hash
23 | });
24 | }
25 | };
26 |
27 | exports.down = function down(knex) {
28 | return knex.schema.table('user', t => {
29 | t.dropColumn('salt');
30 | t.dropColumn('encrypted_password');
31 | t.string('password').notNullable();
32 | });
33 | };
--------------------------------------------------------------------------------
/site_scripts/store.js:
--------------------------------------------------------------------------------
1 | const crypto = require('crypto');
2 | const knex = require('knex')(require('./knexfile'));
3 |
4 | module.exports = {
5 | createUser({ username, email, password }) {
6 | console.log(`Add user ${username} with email ${email}`);
7 | const { salt, hash } = saltHashPassword({ password });
8 | return knex('user').where({ username })
9 | .then(([user]) => {
10 | if (user) {
11 | return { success: false, reason: 'username' };
12 | } else {
13 | return knex('user').insert({
14 | salt,
15 | encrypted_password: hash,
16 | username,
17 | email
18 | }).then(function () {
19 | console.log('Success');
20 | return { success: true, reason: '' };
21 | });
22 | }
23 | });
24 | },
25 | authenticate({ username, password }) {
26 | console.log(`Authenticating user ${username}`);
27 | return knex('user').where({ username })
28 | .then(([user]) => {
29 | if (!user || user.username !== username) {
30 | return { success: false };
31 | }
32 | const { hash } = saltHashPassword({
33 | password,
34 | salt: user.salt
35 | });
36 | if (hash === user.encrypted_password) {
37 | return knex('user').where({ username }).update({ updated_at: knex.fn.now() })
38 | .then(function () { return { success: hash === user.encrypted_password }; });
39 | }
40 | return { success: false };
41 | });
42 | },
43 | getEmail(user) {
44 | return knex('user').where({ 'username': user }).select('email')
45 | .then(data => {
46 | return data[0].email;
47 | });
48 | }
49 | };
50 |
51 | function saltHashPassword({
52 | password,
53 | salt = randomString()
54 | }) {
55 | const hash = crypto
56 | .createHmac('sha512', salt)
57 | .update(password);
58 | return {
59 | salt,
60 | hash: hash.digest('hex')
61 | };
62 | }
63 |
64 | function randomString() {
65 | return crypto.randomBytes(4).toString('hex');
66 | }
67 |
--------------------------------------------------------------------------------
/site_scripts/survicate.js:
--------------------------------------------------------------------------------
1 | // Start of Survicate (www.survicate.com) code
2 | if (window.location.href.includes('.com')) {
3 | console.log('Loading Survicate script');
4 | (function (w) {
5 | var s = document.createElement('script');
6 | s.src = 'https://survey.survicate.com/workspaces/01d22f9eb05bc4fcdd73eb6342cb3480/web_surveys.js';
7 | s.async = true;
8 | var e = document.getElementsByTagName('script')[0];
9 | e.parentNode.insertBefore(s, e);
10 | })(window);
11 | }
12 | // End of Survicate code
--------------------------------------------------------------------------------
/site_scripts/tos_legal.js:
--------------------------------------------------------------------------------
1 | const Logout = document.querySelectorAll('.Logout');
2 | for (const button of Logout) {
3 | button.addEventListener('click', (e) => { //jshint ignore:line
4 | e.preventDefault();
5 | setCookie('access_token', '', -1);
6 | window.location = '/';
7 | });
8 | }
9 |
10 | function setCookie(name, value, days) {
11 | var d = new Date();
12 | d.setTime(d.getTime() + 24 * 60 * 60 * 1000 * days);
13 | document.cookie = name + "=" + value + ";path=/;expires=" + d.toGMTString();
14 | }
15 |
16 | window.onscroll = function () { scrollFunction(); };
17 | function scrollFunction() {
18 | if (document.body.scrollTop > 50 || document.documentElement.scrollTop > 50) {
19 | document.getElementsByClassName("navbar-brand")[0].style.setProperty("transform", "scale(0.6)");
20 | document.getElementsByClassName("navbar-header")[0].style.setProperty("top", "-20px");
21 | } else {
22 | document.getElementsByClassName("navbar-brand")[0].style.setProperty("transform", "scale(1.0)");
23 | document.getElementsByClassName("navbar-header")[0].style.setProperty("top", "10px");
24 | }
25 | }
26 |
27 | const currentTheme = localStorage.getItem('theme');
28 |
29 | if (currentTheme === 'dark') {
30 | document.documentElement.classList.toggle('dark-theme');
31 | document.getElementById('top_logo').src = 'images/logo_index_new_white.png';
32 | document.getElementById('mode-button').innerHTML = '';
33 | }
34 |
35 | document.getElementById('mode-button').addEventListener('click', function () {
36 | let theme = 'light';
37 | document.documentElement.classList.toggle('dark-theme');
38 | if (document.documentElement.classList.contains('dark-theme')) {
39 | theme = 'dark';
40 | document.getElementById('top_logo').src = 'images/logo_index_new_white.png';
41 | document.getElementById('mode-button').innerHTML = '';
42 | } else {
43 | theme = 'light';
44 | document.getElementById('top_logo').src = 'images/logo_index_new.png';
45 | document.getElementById('mode-button').innerHTML = '';
46 | }
47 | localStorage.setItem('theme', theme);
48 | });
--------------------------------------------------------------------------------
/site_scripts/user_data.js:
--------------------------------------------------------------------------------
1 | const glob = require('glob');
2 | const path = require('path');
3 | const fs = require('fs');
4 |
5 | module.exports = {
6 | getSketches: (user, callback) => {
7 | glob('./userSketches/' + user + '/*.json', { nodir: true }, function (err, files) {
8 | let sketches = [];
9 | let sketchSizes = [];
10 | let sketchBirthtimes = [];
11 | let sketchModified = [];
12 | let images = [];
13 | let descriptions = [];
14 | for (let i = 0; i < files.length; i++) {
15 | sketches.push(path.basename(files[i], '.json'));
16 | sketchSizes.push(getFilesize(files[i]));
17 | sketchBirthtimes.push(getBirthtime(files[i]));
18 | sketchModified.push(getModifiedDate(files[i]));
19 | if (fs.existsSync('./userSketches/' + user + '/' + path.basename(files[i], '.json') + '.png')) {
20 | images.push(fs.readFileSync('./userSketches/' + user + '/' + path.basename(files[i], '.json') + '.png'));
21 | images[i] = new Buffer(images[i], "binary").toString("base64");
22 | } else {
23 | images.push('');
24 | }
25 | if (fs.existsSync('./userSketches/' + user + '/' + path.basename(files[i], '.json') + '.txt')) {
26 | try {
27 | let description = fs.readFileSync('./userSketches/' + user + '/' + path.basename(files[i], '.json') + '.txt');
28 | try {
29 | description = JSON.parse(description);
30 | if (description.hasOwnProperty('desc')) {
31 | if (description.desc !== '') {
32 | descriptions.push(description.desc);
33 | } else {
34 | descriptions.push('No description available.');
35 | }
36 | } else {
37 | descriptions.push('No description available.');
38 | }
39 | } catch (e) {
40 | descriptions.push(fs.readFileSync('./userSketches/' + user + '/' + path.basename(files[i], '.json') + '.txt'));
41 | }
42 | } catch (e) {
43 |
44 | }
45 | } else {
46 | descriptions.push('No description available.');
47 | }
48 | }
49 | callback({
50 | sketches: {
51 | sketches: sketches,
52 | sizes: sketchSizes,
53 | birthtimes: sketchBirthtimes,
54 | modified: sketchModified
55 | },
56 | images: images,
57 | descriptions: descriptions
58 | });
59 | });
60 | }
61 | };
62 |
63 | function getFilesize(filename) {
64 | const stats = fs.statSync(filename);
65 | return Math.round(stats.size / 1000);
66 | }
67 |
68 | function getBirthtime(filename) {
69 | const stats = fs.statSync(filename);
70 | let millis = stats.birthtimeMs;
71 | let newDate = new Date(millis);
72 | return newDate.toLocaleDateString("en-US") + ' ' + newDate.toLocaleTimeString("en-US");
73 | }
74 |
75 | function getModifiedDate(filename) {
76 | const stats = fs.statSync(filename);
77 | let millis = stats.mtime;
78 | let newDate = new Date(millis);
79 | return newDate.toLocaleDateString("en-US") /*+ ' ' + newDate.toLocaleTimeString("de-DE")*/;
80 | }
81 |
--------------------------------------------------------------------------------
/views/css/ArcaMajora3-Bold.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SimonBuxx/LogiJS/87a03cba7f0443603f538af7653f65ea7f4a219b/views/css/ArcaMajora3-Bold.otf
--------------------------------------------------------------------------------
/views/eduLogin.pug:
--------------------------------------------------------------------------------
1 | doctype html
2 |
3 | head
4 | |
5 | |
10 | |
11 | title LogiJS: #{organization}
12 | meta(name='keywords', content='LogiJS, logic, circuit, simulation, simulator, editor, free, open, source, gate, input, output, sketch, electronics, physics, informatics, it, \
13 | computer, chip, pcb, design, creator, creation, processor, cpu, logi, js, javascript')
14 | meta(name='description', content='LogiJS is a web-based logic circuit simulator for educational use. Discover the world of logic circuits.')
15 | meta(charset='UTF-8')
16 | meta(name='viewport', content='width=device-width, initial-scale=1.0')
17 | link(rel='shortcut icon', href='images/favi.png')
18 | style
19 | include css/bootstrap.css
20 | include css/index_style.css
21 | link(href='https://fonts.googleapis.com/css?family=Open+Sans:400,600,300', rel='stylesheet', type='text/css')
22 | link(rel='stylesheet', type='text/css', href='https://cdnjs.cloudflare.com/ajax/libs/cookieconsent2/3.1.0/cookieconsent.min.css')
23 | link(rel="stylesheet", type='text/css', href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.11.2/css/all.min.css")
24 | script(src='https://cdnjs.cloudflare.com/ajax/libs/cookieconsent2/3.1.0/cookieconsent.min.js')
25 | script.
26 | window.addEventListener("load", function () {
27 | window.cookieconsent.initialise({
28 | "position": "bottom-right",
29 | "content": {
30 | "dismiss": "Allow Cookies"
31 | },
32 | "palette": {
33 | "popup": {
34 | "background": "#323232",
35 | "text": "#fff",
36 | "link": "#c83232"
37 | },
38 | "button": {
39 | "background": "#c83232",
40 | "text": "#ffffff"
41 | }
42 | }
43 | })
44 | });
45 | body
46 | |
47 | |
49 | |
50 | .edu-bg(style='background-image: url(\'' + background + '\');')
51 | .top-menu#top
52 | .container
53 | .navbar.navbar-default.navbar-fixed-top(role='navigation', style='background: none;')
54 | .container
55 | .navbar-header
56 | a.navbar-brand(href='#', style="transition: 0.2s;")
57 | img#top_logo(src='images/logo_index_new.png', alt='LogiJS logo', title='LogiJS', style='float: left;')
58 | if show_org_name
59 | div#logo-div(style="float: right; margin: 0; padding: 0; border-left: 5px solid #c83232; padding-left: 20px;")
60 | p#logo-text #{org_first_line}
61 | br
62 | | #{org_second_line}
63 | span(style="color: #c83232;") .
64 | .navbar-collapse.collapse
65 | ul.nav.navbar-nav.navbar-right
66 | li
67 | a.internal-link(rel='nofollow', href='#', target='_parent') #{localization.login}
68 | if show_registration
69 | li
70 | a.internal-link(rel='nofollow', href='/signup', target='_parent') #{localization.register}
71 | li
72 | a#mode-button.internal-link(rel='nofollow', href='javascript:;', target='_parent' title=localization.toggle_dark_mode)
73 | .slogan-container(style="margin-top: 150px;")
74 | h1.background-text #{background_text}
75 | .login_container
76 | form.Login.login-background
77 | if failed
78 | p.login-message #{localization.login_failed}
79 | span(style="color: #c83232;") .
80 | else if signup_success
81 | p.login-message #{localization.signup_successful}
82 | span(style="color: #c83232;") .
83 | else
84 | h1.login_title #{localization.login}
85 | span(style="color: #c83232;") .
86 | p
87 | input.username(type='text', placeholder=localization.username)
88 | br
89 | input.password(type='password', placeholder=localization.password)
90 | br
91 | input.btn.btn-lg.btn-orange.login-confirm-button(type='submit', value=localization.login, role='button')
92 | p.login-redirect-text
93 | if allow_enter
94 | a.login-redirect-text(href='/editor') #{localization.continue_without_login}
95 | br
96 | .footer_bottom.footer_bottom_absolute
97 | .footer_bottom_content
98 | .footer_box.footer_box_outer
99 | if refer_to_logijs_com
100 | a(rel='nofollow', href='https://logijs.com/', target='_blank') #{localization.switch_to_logijs_com}
101 | .footer_box.footer_box_inner
102 | .footer_box.footer_box_outer.footer_right
103 | if made_in_luebeck
104 | p(style="text-align: right;") Made with in Lübeck
105 | span(style="color: #c83232;") .
106 | script
107 | include ../libraries/jquery.min.js
108 | include ../libraries/bootstrap.min.js
109 | include ../site_scripts/edulogin.js
110 |
111 |
--------------------------------------------------------------------------------
/views/eduSignup.pug:
--------------------------------------------------------------------------------
1 | doctype html
2 |
3 | head
4 | |
5 | |
10 | |
11 | title LogiJS: #{organization}
12 | meta(name='keywords', content='LogiJS, logic, circuit, simulation, simulator, editor, free, open, source, gate, input, output, sketch, electronics, physics, informatics, it, \
13 | computer, chip, pcb, design, creator, creation, processor, cpu, logi, js, javascript')
14 | meta(name='description', content='LogiJS is a web-based logic circuit simulator for educational use. Discover the world of logic circuits.')
15 | meta(charset='UTF-8')
16 | meta(name='viewport', content='width=device-width, initial-scale=1.0')
17 | link(rel='shortcut icon', href='images/favi.png')
18 | style
19 | include css/bootstrap.css
20 | include css/index_style.css
21 | link(href='https://fonts.googleapis.com/css?family=Open+Sans:400,600,300', rel='stylesheet', type='text/css')
22 | link(rel='stylesheet', type='text/css', href='https://cdnjs.cloudflare.com/ajax/libs/cookieconsent2/3.1.0/cookieconsent.min.css')
23 | link(rel="stylesheet", type='text/css', href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.11.2/css/all.min.css")
24 | script(src='https://cdnjs.cloudflare.com/ajax/libs/cookieconsent2/3.1.0/cookieconsent.min.js')
25 | script.
26 | window.addEventListener("load", function () {
27 | window.cookieconsent.initialise({
28 | "position": "bottom-right",
29 | "content": {
30 | "dismiss": "Allow Cookies"
31 | },
32 | "palette": {
33 | "popup": {
34 | "background": "#323232",
35 | "text": "#fff",
36 | "link": "#c83232"
37 | },
38 | "button": {
39 | "background": "#c83232",
40 | "text": "#ffffff"
41 | }
42 | }
43 | })
44 | });
45 | body
46 | |
47 | |
49 | |
50 | .edu-bg(style='background-image: url(\'' + background + '\');')
51 | .top-menu#top
52 | .container
53 | .navbar.navbar-default.navbar-fixed-top(role='navigation', style='background: none;')
54 | .container
55 | .navbar-header
56 | button.navbar-toggle(type='button', data-toggle='collapse', data-target='.navbar-collapse')
57 | span.sr-only Toggle navigation
58 | span.icon-bar
59 | span.icon-bar
60 | span.icon-bar
61 | a.navbar-brand(href='/', style="transition: 0.2s;")
62 | img#top_logo(src='images/logo_index_new.png', alt='LogiJS logo', title='LogiJS', style='float: left;')
63 | if show_org_name
64 | div#logo-div(style="float: right; margin: 0; padding: 0; border-left: 5px solid #c83232; padding-left: 20px;")
65 | p#logo-text(style="font-size: 45px; margin-top: 10px; line-height: 1.1; transition: 0.2s; letter-spacing: 2px;") #{org_first_line}
66 | br
67 | | #{org_second_line}
68 | span(style="color: #c83232;") .
69 | .navbar-collapse.collapse
70 | ul.nav.navbar-nav.navbar-right
71 | li
72 | a.internal-link(rel='nofollow', href='/', target='_parent') #{localization.login}
73 | li
74 | a.internal-link(rel='nofollow', href='#', target='_parent') #{localization.register}
75 | li
76 | a#mode-button.internal-link(rel='nofollow', href='javascript:;', target='_parent' title=localization.toggle_dark_mode)
77 | .slogan-container(style="margin-top: 150px;")
78 | h1.background-text #{background_text}
79 | .login_container
80 | - var error = parseInt(error_code);
81 | form.SignUp.login-background
82 | case error
83 | when 1: p.login-message #{localization.username_invalid}
84 | span(style="color: #c83232;") .
85 | when 2: p.login-message #{localization.email_invalid}
86 | span(style="color: #c83232;") .
87 | when 3
88 | p.login-message #{localization.password_invalid}
89 | span(style="color: #c83232;") .
90 | p.login-message.password-tipps #{localization.password_rules}
91 | span(style="color: #c83232;") .
92 | when 4: p.login-message #{localization.username_taken}
93 | span(style="color: #c83232;") .
94 | default: h1.login_title #{localization.register}
95 | span(style="color: #c83232;") .
96 | p
97 | input.username(type='text', placeholder=localization.username)
98 | br
99 | input.email(type='text', placeholder=localization.email)
100 | br
101 | input.password(type='password', placeholder=localization.password)
102 | br
103 | input.btn.btn-lg.btn-orange.login-confirm-button(type='submit', value=localization.register, role='button')
104 | p.login-redirect-text
105 | | #{localization.already_signed_up}
106 | a.login-redirect-text(href='/') #{localization.login}
107 | br
108 | .footer_bottom.footer_bottom_absolute
109 | .footer_bottom_content
110 | .footer_box.footer_box_outer
111 | if refer_to_logijs_com
112 | a(rel='nofollow', href='https://logijs.com/', target='_blank') #{localization.switch_to_logijs_com}
113 | .footer_box.footer_box_inner
114 | .footer_box.footer_box_outer.footer_right
115 | if made_in_luebeck
116 | p(style="text-align: right;") Made with in Lübeck
117 | span(style="color: #c83232;") .
118 | script
119 | include ../libraries/jquery.min.js
120 | include ../libraries/bootstrap.min.js
121 | include ../site_scripts/eduSignup.js
122 |
123 |
--------------------------------------------------------------------------------
/views/getstarted.pug:
--------------------------------------------------------------------------------
1 | doctype html
2 |
3 | head
4 | |
5 | |
10 | |
11 | title LogiJS: Get Started
12 | meta(name='keywords', content='LogiJS, logic, circuit, simulation, simulator, editor, free, open, source, gate, input, output, sketch, electronics, physics, informatics, it, \
13 | computer, chip, pcb, design, creator, creation, processor, cpu, logi, js, javascript')
14 | meta(name='description', content='LogiJS is a web-based logic circuit simulator for educational use. Discover the world of logic circuits.')
15 | meta(charset='UTF-8')
16 | meta(name='viewport', content='width=device-width, initial-scale=1.0')
17 | link(rel='shortcut icon', href='images/favi.png')
18 | link(href='https://fonts.googleapis.com/css?family=Open+Sans:400,600,300', rel='stylesheet', type='text/css')
19 | style
20 | include css/bootstrap.css
21 | include css/index_style.css
22 | link(rel='stylesheet', type='text/css', href='https://cdnjs.cloudflare.com/ajax/libs/cookieconsent2/3.1.0/cookieconsent.min.css')
23 | link(rel="stylesheet", type='text/css', href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.11.2/css/all.min.css")
24 | script(src='https://cdnjs.cloudflare.com/ajax/libs/cookieconsent2/3.1.0/cookieconsent.min.js')
25 | script.
26 | window.addEventListener("load", function () {
27 | window.cookieconsent.initialise({
28 | "position": "bottom-right",
29 | "content": {
30 | "dismiss": "Allow Cookies"
31 | },
32 | "palette": {
33 | "popup": {
34 | "background": "#323232",
35 | "text": "#fff",
36 | "link": "#c83232"
37 | },
38 | "button": {
39 | "background": "#c83232",
40 | "text": "#ffffff"
41 | }
42 | }
43 | })
44 | });
45 | body
46 | |
47 | |
49 | |
50 | .top-menu#top
51 | .container
52 | .navbar.navbar-default.navbar-fixed-top(role='navigation')
53 | .container
54 | ul.nav.navbar-nav.navbar-left
55 | li
56 | a.internal-link(rel='nofollow', href='/#features', target='_parent') Features
57 | li
58 | a.internal-link(rel='nofollow', href='/#samples', target='_parent') Samples
59 | li
60 | a.internal-link(rel='nofollow', href='/#about', target='_parent') About
61 | .navbar-header
62 | button.navbar-toggle(type='button', data-toggle='collapse', data-target='.navbar-collapse')
63 | span.sr-only Toggle navigation
64 | span.icon-bar
65 | span.icon-bar
66 | span.icon-bar
67 | a.navbar-brand(href='/')
68 | img#top_logo(src='images/logo_index_new.png', alt='LogiJS logo', title='LogiJS')
69 | .navbar-collapse.collapse
70 | ul.nav.navbar-nav.navbar-right
71 | if user !== ''
72 | li
73 | a.user-button.internal-link(rel='nofollow', href='/dashboard', target='_parent') #{user}
74 | li
75 | a.Logout.internal-link(rel='nofollow', href='#', target='_parent') Logout
76 | else
77 | li
78 | a.login-button.internal-link(rel='nofollow', href='/login', target='_parent') Login
79 | li
80 | a.internal-link(rel='nofollow', href='/signup', target='_parent') Register
81 | li
82 | a#mode-button.internal-link(rel='nofollow', href='javascript:;', target='_parent' title='Toggle Dark Mode')
83 | .getstarted-container
84 | h1.background-text(style='top: 90px; left: -300px;') Discover the world
85 | h1.getstarted-title
86 | | Welcome to LogiJS
87 | span.red .
88 | h2.getstarted-subtitle
89 | | Let us show you around or just start with a blank sketch
90 | span.red .
91 | a.btn.btn-lg.btn-orange(href='/editor', rel="nofollow", role='button')
92 | New Sketch
93 | a.btn.btn-lg.btn-orange(href='/editor?tour=true&?sketch=library__5tour', rel="nofollow", role='button')
94 | Start the Tour
95 | .red_square(style="position: absolute; top: 0; right: max(17vw, 320px); height: 20vw; background: #c83232; width: 20vw; z-index: 10000;")
96 | .grey_square
97 | img#getstarted_teaser(src='images/front_teaser_white.png', alt='LogiJS Editor', title='LogiJS Editor')
98 |
99 | .footer_bottom.footer_bottom_absolute
100 | .footer_bottom_content
101 | .footer_box
102 | a.internal-link(rel='nofollow', href='/terms-of-service', target='_parent') Terms of Service
103 | a.internal-link(rel='nofollow', href='/legal', target='_parent') Legal Notice
104 | .footer_box
105 | p(style="text-align: center; display: inline-block; width: 100%;")
106 | a(href='https://twitter.com/logi_js', target='_blank', style="margin-right: 5px;")
107 | img(src="images/twitter.png" style="width: 40px; margin-top: -20px;")
108 | a(href='https://github.com/SimonBuxx/logijs', target='_blank', style="margin-left: 5px;")
109 | img(src="images/github_dark.png" style="width: 40px; margin-top: -20px;")
110 | .footer_box
111 | p(style="text-align: right;") Made with in Lübeck
112 | span.red .
113 | script
114 | include ../libraries/jquery.min.js
115 | include ../libraries/bootstrap.min.js
116 | include ../site_scripts/getstarted.js
117 | script.
118 | if (window.innerHeight > 800) {
119 | document.getElementById("top_logo").style.width = "350px";
120 | } else {
121 | document.getElementById("top_logo").style.width = "200px";
122 | }
--------------------------------------------------------------------------------
/views/images/alt_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SimonBuxx/LogiJS/87a03cba7f0443603f538af7653f65ea7f4a219b/views/images/alt_logo.png
--------------------------------------------------------------------------------
/views/images/alt_logo_dark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SimonBuxx/LogiJS/87a03cba7f0443603f538af7653f65ea7f4a219b/views/images/alt_logo_dark.png
--------------------------------------------------------------------------------
/views/images/alt_logo_small.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SimonBuxx/LogiJS/87a03cba7f0443603f538af7653f65ea7f4a219b/views/images/alt_logo_small.png
--------------------------------------------------------------------------------
/views/images/and-gate.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SimonBuxx/LogiJS/87a03cba7f0443603f538af7653f65ea7f4a219b/views/images/and-gate.png
--------------------------------------------------------------------------------
/views/images/buffer.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SimonBuxx/LogiJS/87a03cba7f0443603f538af7653f65ea7f4a219b/views/images/buffer.png
--------------------------------------------------------------------------------
/views/images/businput.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SimonBuxx/LogiJS/87a03cba7f0443603f538af7653f65ea7f4a219b/views/images/businput.png
--------------------------------------------------------------------------------
/views/images/button.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SimonBuxx/LogiJS/87a03cba7f0443603f538af7653f65ea7f4a219b/views/images/button.png
--------------------------------------------------------------------------------
/views/images/carousel_1_new.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SimonBuxx/LogiJS/87a03cba7f0443603f538af7653f65ea7f4a219b/views/images/carousel_1_new.png
--------------------------------------------------------------------------------
/views/images/carousel_1_new_dark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SimonBuxx/LogiJS/87a03cba7f0443603f538af7653f65ea7f4a219b/views/images/carousel_1_new_dark.png
--------------------------------------------------------------------------------
/views/images/carousel_2_new.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SimonBuxx/LogiJS/87a03cba7f0443603f538af7653f65ea7f4a219b/views/images/carousel_2_new.png
--------------------------------------------------------------------------------
/views/images/carousel_2_new_dark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SimonBuxx/LogiJS/87a03cba7f0443603f538af7653f65ea7f4a219b/views/images/carousel_2_new_dark.png
--------------------------------------------------------------------------------
/views/images/carousel_3_new.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SimonBuxx/LogiJS/87a03cba7f0443603f538af7653f65ea7f4a219b/views/images/carousel_3_new.png
--------------------------------------------------------------------------------
/views/images/carousel_3_new_dark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SimonBuxx/LogiJS/87a03cba7f0443603f538af7653f65ea7f4a219b/views/images/carousel_3_new_dark.png
--------------------------------------------------------------------------------
/views/images/clock.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SimonBuxx/LogiJS/87a03cba7f0443603f538af7653f65ea7f4a219b/views/images/clock.png
--------------------------------------------------------------------------------
/views/images/counter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SimonBuxx/LogiJS/87a03cba7f0443603f538af7653f65ea7f4a219b/views/images/counter.png
--------------------------------------------------------------------------------
/views/images/custom_frontpage.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SimonBuxx/LogiJS/87a03cba7f0443603f538af7653f65ea7f4a219b/views/images/custom_frontpage.png
--------------------------------------------------------------------------------
/views/images/d-flipflop.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SimonBuxx/LogiJS/87a03cba7f0443603f538af7653f65ea7f4a219b/views/images/d-flipflop.png
--------------------------------------------------------------------------------
/views/images/decoder.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SimonBuxx/LogiJS/87a03cba7f0443603f538af7653f65ea7f4a219b/views/images/decoder.png
--------------------------------------------------------------------------------
/views/images/demux.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SimonBuxx/LogiJS/87a03cba7f0443603f538af7653f65ea7f4a219b/views/images/demux.png
--------------------------------------------------------------------------------
/views/images/favi.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SimonBuxx/LogiJS/87a03cba7f0443603f538af7653f65ea7f4a219b/views/images/favi.png
--------------------------------------------------------------------------------
/views/images/front_teaser.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SimonBuxx/LogiJS/87a03cba7f0443603f538af7653f65ea7f4a219b/views/images/front_teaser.png
--------------------------------------------------------------------------------
/views/images/front_teaser_white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SimonBuxx/LogiJS/87a03cba7f0443603f538af7653f65ea7f4a219b/views/images/front_teaser_white.png
--------------------------------------------------------------------------------
/views/images/fulladd.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SimonBuxx/LogiJS/87a03cba7f0443603f538af7653f65ea7f4a219b/views/images/fulladd.png
--------------------------------------------------------------------------------
/views/images/fulladd_old.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SimonBuxx/LogiJS/87a03cba7f0443603f538af7653f65ea7f4a219b/views/images/fulladd_old.png
--------------------------------------------------------------------------------
/views/images/github_dark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SimonBuxx/LogiJS/87a03cba7f0443603f538af7653f65ea7f4a219b/views/images/github_dark.png
--------------------------------------------------------------------------------
/views/images/halfadd.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SimonBuxx/LogiJS/87a03cba7f0443603f538af7653f65ea7f4a219b/views/images/halfadd.png
--------------------------------------------------------------------------------
/views/images/jk-flipflop.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SimonBuxx/LogiJS/87a03cba7f0443603f538af7653f65ea7f4a219b/views/images/jk-flipflop.png
--------------------------------------------------------------------------------
/views/images/label.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SimonBuxx/LogiJS/87a03cba7f0443603f538af7653f65ea7f4a219b/views/images/label.png
--------------------------------------------------------------------------------
/views/images/label_white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SimonBuxx/LogiJS/87a03cba7f0443603f538af7653f65ea7f4a219b/views/images/label_white.png
--------------------------------------------------------------------------------
/views/images/logo_index_new.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SimonBuxx/LogiJS/87a03cba7f0443603f538af7653f65ea7f4a219b/views/images/logo_index_new.png
--------------------------------------------------------------------------------
/views/images/logo_index_new_white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SimonBuxx/LogiJS/87a03cba7f0443603f538af7653f65ea7f4a219b/views/images/logo_index_new_white.png
--------------------------------------------------------------------------------
/views/images/mux.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SimonBuxx/LogiJS/87a03cba7f0443603f538af7653f65ea7f4a219b/views/images/mux.png
--------------------------------------------------------------------------------
/views/images/not-gate.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SimonBuxx/LogiJS/87a03cba7f0443603f538af7653f65ea7f4a219b/views/images/not-gate.png
--------------------------------------------------------------------------------
/views/images/or-gate.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SimonBuxx/LogiJS/87a03cba7f0443603f538af7653f65ea7f4a219b/views/images/or-gate.png
--------------------------------------------------------------------------------
/views/images/output.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SimonBuxx/LogiJS/87a03cba7f0443603f538af7653f65ea7f4a219b/views/images/output.png
--------------------------------------------------------------------------------
/views/images/register.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SimonBuxx/LogiJS/87a03cba7f0443603f538af7653f65ea7f4a219b/views/images/register.png
--------------------------------------------------------------------------------
/views/images/rs-clocked.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SimonBuxx/LogiJS/87a03cba7f0443603f538af7653f65ea7f4a219b/views/images/rs-clocked.png
--------------------------------------------------------------------------------
/views/images/rs-flipflop.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SimonBuxx/LogiJS/87a03cba7f0443603f538af7653f65ea7f4a219b/views/images/rs-flipflop.png
--------------------------------------------------------------------------------
/views/images/segments.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SimonBuxx/LogiJS/87a03cba7f0443603f538af7653f65ea7f4a219b/views/images/segments.png
--------------------------------------------------------------------------------
/views/images/switch.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SimonBuxx/LogiJS/87a03cba7f0443603f538af7653f65ea7f4a219b/views/images/switch.png
--------------------------------------------------------------------------------
/views/images/t-flipflop.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SimonBuxx/LogiJS/87a03cba7f0443603f538af7653f65ea7f4a219b/views/images/t-flipflop.png
--------------------------------------------------------------------------------
/views/images/twitter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SimonBuxx/LogiJS/87a03cba7f0443603f538af7653f65ea7f4a219b/views/images/twitter.png
--------------------------------------------------------------------------------
/views/images/uni-hl-demo.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SimonBuxx/LogiJS/87a03cba7f0443603f538af7653f65ea7f4a219b/views/images/uni-hl-demo.jpg
--------------------------------------------------------------------------------
/views/images/unwrapper.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SimonBuxx/LogiJS/87a03cba7f0443603f538af7653f65ea7f4a219b/views/images/unwrapper.png
--------------------------------------------------------------------------------
/views/images/wrapper.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SimonBuxx/LogiJS/87a03cba7f0443603f538af7653f65ea7f4a219b/views/images/wrapper.png
--------------------------------------------------------------------------------
/views/images/xor-gate.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SimonBuxx/LogiJS/87a03cba7f0443603f538af7653f65ea7f4a219b/views/images/xor-gate.png
--------------------------------------------------------------------------------
/views/librarySketches/library__0gates.json:
--------------------------------------------------------------------------------
1 | {"caption":"Gates","gates":[{"x":"510","y":"210","direction":"0","inputCount":"2","outputCount":"1","logicFunction":"\"and\"","outputsInv":"[false]","inputsInv":"[false,false]"},{"x":"510","y":"360","direction":"0","inputCount":"2","outputCount":"1","logicFunction":"\"or\"","outputsInv":"[false]","inputsInv":"[false,false]"},{"x":"510","y":"510","direction":"0","inputCount":"2","outputCount":"1","logicFunction":"\"xor\"","outputsInv":"[false]","inputsInv":"[false,false]"}],"outputs":[{"x":"630","y":"240","colr":"0"},{"x":"630","y":"390","colr":"0"},{"x":"630","y":"540","colr":"0"}],"inputs":[{"x":"405","y":"165","framecount":"-1","clock":"false"},{"x":"465","y":"165","framecount":"-1","clock":"false"}],"wires":[{"x1":"420","y1":"240","x2":"510"},{"x1":"420","y1":"390","x2":"510"},{"x1":"420","y1":"540","x2":"510"},{"x1":"480","y1":"570","x2":"510"},{"x1":"480","y1":"180","y2":"570"},{"x1":"480","y1":"270","x2":"510"},{"x1":"480","y1":"420","x2":"510"},{"x1":"420","y1":"180","y2":"540"},{"x1":"570","y1":"540","x2":"630"},{"x1":"570","y1":"390","x2":"630"},{"x1":"570","y1":"240","x2":"630"}],"conpoints":[{"x":"480","y":"270"},{"x":"480","y":"420"},{"x":"420","y":"240"},{"x":"420","y":"390"}],"diodes":[],"customs":[],"labels":[{"x":"720","y":"240","txt":"AND"},{"x":"720","y":"390","txt":"OR"},{"x":"720","y":"540","txt":"XOR"},{"x":"420","y":"60","txt":"This sketch demonstrates the three basic logic gates,\nas well as input and output elements.\nClick on \"Start\" to start the simulation."}],"segDisplays":[]}
--------------------------------------------------------------------------------
/views/librarySketches/library__0gates.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SimonBuxx/LogiJS/87a03cba7f0443603f538af7653f65ea7f4a219b/views/librarySketches/library__0gates.png
--------------------------------------------------------------------------------
/views/librarySketches/library__0gates.txt:
--------------------------------------------------------------------------------
1 | {"tops":[],"inputLabels":["",""],"outputLabels":["","",""],"caption":"Basic Gates","inputs":2,"outputs":3,"desc":"This sketch demonstrates the three basic logic gates, AND, OR and XOR. It also shows the usage of input and output elements. Logic gates are the fundamentals of every logic circuit."}
--------------------------------------------------------------------------------
/views/librarySketches/library__0gates_frame.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SimonBuxx/LogiJS/87a03cba7f0443603f538af7653f65ea7f4a219b/views/librarySketches/library__0gates_frame.png
--------------------------------------------------------------------------------
/views/librarySketches/library__1halfadder.json:
--------------------------------------------------------------------------------
1 | {"caption":"Half Adder","gates":[{"x":"210","y":"90","direction":"0","inputCount":"2","outputCount":"1","logicFunction":"\"and\"","outputsInv":"[false]","inputsInv":"[false,false]"},{"x":"210","y":"210","direction":"0","inputCount":"2","outputCount":"1","logicFunction":"\"xor\"","outputsInv":"[false]","inputsInv":"[false,false]"}],"outputs":[{"x":"390","y":"120","colr":"0"},{"x":"390","y":"240","colr":"0"},{"x":"390","y":"420","colr":"0"},{"x":"390","y":"450","colr":"0"}],"inputs":[{"x":"75","y":"105","framecount":"-1","clock":"false"},{"x":"75","y":"135","framecount":"-1","clock":"false"},{"x":"75","y":"405","framecount":"-1","clock":"false"},{"x":"75","y":"435","framecount":"-1","clock":"false"}],"wires":[{"x1":"90","y1":"120","x2":"210"},{"x1":"180","y1":"240","x2":"210"},{"x1":"180","y1":"120","y2":"240"},{"x1":"90","y1":"150","x2":"210"},{"x1":"150","y1":"270","x2":"210"},{"x1":"150","y1":"150","y2":"270"},{"x1":"270","y1":"240","x2":"390"},{"x1":"270","y1":"120","x2":"390"},{"x1":"90","y1":"420","x2":"210"},{"x1":"90","y1":"450","x2":"210"},{"x1":"270","y1":"420","x2":"390"},{"x1":"270","y1":"450","x2":"390"}],"conpoints":[{"x":"180","y":"120"},{"x":"150","y":"150"}],"diodes":[],"customs":[{"x":"210","y":"390","direction":"0","filename":"\"half_add.json\"","outputsInv":"[]","inputsInv":"[]"}],"labels":[{"x":"450","y":"120","txt":"Carry bit"},{"x":"450","y":"240","txt":"Sum"},{"x":"90","y":"60","txt":"Half adder, adds two single binary digits"},{"x":"90","y":"360","txt":"Half adder as a pre-built element"},{"x":"450","y":"420","txt":"Carry bit"},{"x":"450","y":"450","txt":"Sum"}],"segDisplays":[]}
--------------------------------------------------------------------------------
/views/librarySketches/library__1halfadder.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SimonBuxx/LogiJS/87a03cba7f0443603f538af7653f65ea7f4a219b/views/librarySketches/library__1halfadder.png
--------------------------------------------------------------------------------
/views/librarySketches/library__1halfadder.txt:
--------------------------------------------------------------------------------
1 | {"tops":[],"inputLabels":["","","",""],"outputLabels":["","","",""],"caption":"Half Adder","inputs":4,"outputs":4,"desc":"This sketch implements a half adder that is used to add two single binary digits. Half adders can be combined to form full adders, used to add binary numbers."}
--------------------------------------------------------------------------------
/views/librarySketches/library__1halfadder_frame.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SimonBuxx/LogiJS/87a03cba7f0443603f538af7653f65ea7f4a219b/views/librarySketches/library__1halfadder_frame.png
--------------------------------------------------------------------------------
/views/librarySketches/library__2fulladder.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SimonBuxx/LogiJS/87a03cba7f0443603f538af7653f65ea7f4a219b/views/librarySketches/library__2fulladder.png
--------------------------------------------------------------------------------
/views/librarySketches/library__2fulladder.txt:
--------------------------------------------------------------------------------
1 | {"tops":[],"inputLabels":["","","","","","","","",""],"outputLabels":["","","","","",""],"caption":"Full Adder","inputs":9,"outputs":6,"desc":"This sketch implements a full adder that is used to add two single binary digits. Full adders constist of two half adders, taking two binary digits and a carry bit as inputs. Full adders can be combined to build integer adders of any size."}
--------------------------------------------------------------------------------
/views/librarySketches/library__2fulladder_frame.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SimonBuxx/LogiJS/87a03cba7f0443603f538af7653f65ea7f4a219b/views/librarySketches/library__2fulladder_frame.png
--------------------------------------------------------------------------------
/views/librarySketches/library__3traffic.json:
--------------------------------------------------------------------------------
1 | {"caption":"Traffic","gates":[],"outputs":[{"x":"990","y":"120","colr":"0"},{"x":"990","y":"150","colr":"1"},{"x":"990","y":"180","colr":"2"},{"x":"990","y":"300","colr":"0"},{"x":"990","y":"330","colr":"2"}],"inputs":[{"x":"165","y":"135","framecount":"0","clock":"true","speed":"30","lbl":">"}],"wires":[{"x1":"300","y1":"150","x2":"330"},{"x1":"300","y1":"180","x2":"330"},{"x1":"960","y1":"300","x2":"990"},{"x1":"180","y1":"150","x2":"240"},{"x1":"930","y1":"330","y2":"390"},{"x1":"930","y1":"330","x2":"990"},{"x1":"870","y1":"180","y2":"300"},{"x1":"870","y1":"180","x2":"990"},{"x1":"960","y1":"300","y2":"420"},{"x1":"510","y1":"120","y2":"300"},{"x1":"480","y1":"120","y2":"330"},{"x1":"450","y1":"120","y2":"360"},{"x1":"810","y1":"120","x2":"990"},{"x1":"810","y1":"120","y2":"360"},{"x1":"840","y1":"150","y2":"330"},{"x1":"840","y1":"150","x2":"990"},{"x1":"390","y1":"150","x2":"660"},{"x1":"390","y1":"180","x2":"660"},{"x1":"390","y1":"210","x2":"660"},{"x1":"390","y1":"240","x2":"660"},{"x1":"630","y1":"120","y2":"390"},{"x1":"600","y1":"120","y2":"420"},{"x1":"450","y1":"360","x2":"810"},{"x1":"480","y1":"330","x2":"840"},{"x1":"510","y1":"300","x2":"870"},{"x1":"630","y1":"390","x2":"930"},{"x1":"600","y1":"420","x2":"960"}],"conpoints":[],"diodes":[{"x":"450","y":"150"},{"x":"630","y":"150"},{"x":"450","y":"180"},{"x":"480","y":"180"},{"x":"600","y":"180"},{"x":"510","y":"210"},{"x":"600","y":"210"},{"x":"480","y":"240"},{"x":"600","y":"240"}],"customs":[{"x":"330","y":"120","direction":"0","filename":"\"2-decoder.json\"","outputsInv":"[false,false,false,false]","inputsInv":"[false,false]"},{"x":"240","y":"120","direction":"0","filename":"\"2-counter.json\"","outputsInv":"[false,false]","inputsInv":"[false]"}],"labels":[{"x":"60","y":"60","txt":"This sketch simulates a traffic light\nusing a diode matrix"},{"x":"1050","y":"120","txt":"Road traffic"},{"x":"1050","y":"300","txt":"Pedestrians"},{"x":"60","y":"150","txt":"Clock"}],"segDisplays":[]}
--------------------------------------------------------------------------------
/views/librarySketches/library__3traffic.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SimonBuxx/LogiJS/87a03cba7f0443603f538af7653f65ea7f4a219b/views/librarySketches/library__3traffic.png
--------------------------------------------------------------------------------
/views/librarySketches/library__3traffic.txt:
--------------------------------------------------------------------------------
1 | {"tops":[],"inputLabels":[">"],"outputLabels":["","","","",""],"caption":"Traffic Lights","inputs":1,"outputs":5,"desc":"This sketch simulates traffic lights using a 4-bit counter (see example #5) and a diode matrix. There are lights for road traffic and for crossing pedestrians. This example shows the usage of diodes, elements that connect wires in one direction only. They are especially helpful for building control units that can be programmed by setting diodes in a matrix. That way, instructions can be fetched and executed successively."}
--------------------------------------------------------------------------------
/views/librarySketches/library__3traffic_frame.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SimonBuxx/LogiJS/87a03cba7f0443603f538af7653f65ea7f4a219b/views/librarySketches/library__3traffic_frame.png
--------------------------------------------------------------------------------
/views/librarySketches/library__44BitCounter.json:
--------------------------------------------------------------------------------
1 | {"caption":"Counter","gates":[{"x":"750","y":"270","direction":"0","inputCount":"2","outputCount":"1","logicFunction":"\"xor\"","outputsInv":"[false]","inputsInv":"[false,false]"},{"x":"1020","y":"300","direction":"0","inputCount":"2","outputCount":"1","logicFunction":"\"and\"","outputsInv":"[false]","inputsInv":"[false,false]"},{"x":"1380","y":"300","direction":"0","inputCount":"3","outputCount":"1","logicFunction":"\"and\"","outputsInv":"[false]","inputsInv":"[false,false,false]"},{"x":"1470","y":"270","direction":"0","inputCount":"2","outputCount":"1","logicFunction":"\"xor\"","outputsInv":"[false]","inputsInv":"[false,false]"},{"x":"1110","y":"270","direction":"0","inputCount":"2","outputCount":"1","logicFunction":"\"xor\"","outputsInv":"[false]","inputsInv":"[false,false]"}],"outputs":[{"x":"1710","y":"150","colr":"0"},{"x":"1320","y":"150","colr":"0"},{"x":"960","y":"150","colr":"0"},{"x":"690","y":"150","colr":"0"}],"inputs":[{"x":"495","y":"405","lbl":">","framecount":"0","clock":"true","speed":"30"}],"wires":[{"x1":"660","y1":"360","x2":"690"},{"x1":"570","y1":"300","y2":"330"},{"x1":"570","y1":"330","x2":"600"},{"x1":"1560","y1":"360","x2":"1590"},{"x1":"840","y1":"360","x2":"870"},{"x1":"570","y1":"360","x2":"600"},{"x1":"1200","y1":"360","x2":"1230"},{"x1":"810","y1":"300","x2":"840"},{"x1":"840","y1":"300","y2":"330"},{"x1":"840","y1":"330","x2":"870"},{"x1":"930","y1":"330","x2":"960"},{"x1":"720","y1":"300","x2":"750"},{"x1":"1350","y1":"330","x2":"1380"},{"x1":"1350","y1":"390","x2":"1380"},{"x1":"1080","y1":"270","y2":"300"},{"x1":"1080","y1":"300","x2":"1110"},{"x1":"1080","y1":"330","x2":"1110"},{"x1":"990","y1":"330","x2":"1020"},{"x1":"1170","y1":"300","x2":"1200"},{"x1":"1200","y1":"300","y2":"330"},{"x1":"1200","y1":"330","x2":"1230"},{"x1":"1290","y1":"330","x2":"1320"},{"x1":"1440","y1":"270","y2":"300"},{"x1":"1440","y1":"300","x2":"1470"},{"x1":"1440","y1":"330","x2":"1470"},{"x1":"1530","y1":"300","x2":"1560"},{"x1":"1560","y1":"300","y2":"330"},{"x1":"1560","y1":"330","x2":"1590"},{"x1":"1560","y1":"360","y2":"420"},{"x1":"840","y1":"360","y2":"420"},{"x1":"570","y1":"360","y2":"420"},{"x1":"1200","y1":"360","y2":"420"},{"x1":"960","y1":"360","x2":"1020"},{"x1":"1350","y1":"390","y2":"450"},{"x1":"1320","y1":"360","x2":"1380"},{"x1":"1650","y1":"330","x2":"1710"},{"x1":"1680","y1":"270","y2":"330"},{"x1":"690","y1":"300","y2":"360"},{"x1":"720","y1":"330","y2":"390"},{"x1":"660","y1":"330","x2":"750"},{"x1":"570","y1":"300","x2":"690"},{"x1":"720","y1":"210","y2":"300"},{"x1":"1350","y1":"210","y2":"330"},{"x1":"690","y1":"150","y2":"270"},{"x1":"540","y1":"270","y2":"390"},{"x1":"960","y1":"150","y2":"360"},{"x1":"1320","y1":"150","y2":"360"},{"x1":"1080","y1":"270","x2":"1320"},{"x1":"990","y1":"180","y2":"330"},{"x1":"540","y1":"270","x2":"690"},{"x1":"1710","y1":"150","y2":"330"},{"x1":"1440","y1":"270","x2":"1680"},{"x1":"540","y1":"390","x2":"720"},{"x1":"1740","y1":"180","y2":"450"},{"x1":"1350","y1":"450","x2":"1740"},{"x1":"720","y1":"210","x2":"1350"},{"x1":"510","y1":"420","x2":"1560"},{"x1":"690","y1":"180","x2":"1740"}],"conpoints":[{"x":"840","y":"420"},{"x":"570","y":"420"},{"x":"1200","y":"420"},{"x":"960","y":"330"},{"x":"960","y":"210"},{"x":"1320","y":"270"},{"x":"990","y":"180"},{"x":"690","y":"180"},{"x":"1320","y":"330"},{"x":"1680","y":"330"},{"x":"720","y":"330"}],"diodes":[],"customs":[{"x":"600","y":"300","direction":"0","filename":"\"d-flipflop.json\"","outputsInv":"[false,false,false,false,false,false]","inputsInv":"[false,false,false,false,false,false]"},{"x":"870","y":"300","direction":"0","filename":"\"d-flipflop.json\"","outputsInv":"[false,false,false,false,false,false]","inputsInv":"[false,false,false,false,false,false]"},{"x":"1230","y":"300","direction":"0","filename":"\"d-flipflop.json\"","outputsInv":"[false,false,false,false,false,false,false,false]","inputsInv":"[false,false,false,false,false,false,false,false]"},{"x":"1590","y":"300","direction":"0","filename":"\"d-flipflop.json\"","outputsInv":"[false,false,false,false,false,false]","inputsInv":"[false,false,false,false,false,false]"}],"labels":[{"x":"390","y":"420","txt":"Clock"},{"x":"690","y":"90","txt":"LSB (least significant bit)"},{"x":"1710","y":"90","txt":"MSB (most significant bit)"}],"segDisplays":[]}
--------------------------------------------------------------------------------
/views/librarySketches/library__44BitCounter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SimonBuxx/LogiJS/87a03cba7f0443603f538af7653f65ea7f4a219b/views/librarySketches/library__44BitCounter.png
--------------------------------------------------------------------------------
/views/librarySketches/library__44BitCounter.txt:
--------------------------------------------------------------------------------
1 | {"tops":[],"inputLabels":[">"],"outputLabels":["","","",""],"caption":"4-Bit Counter","inputs":1,"outputs":4,"desc":"This sketch implements a simple counter made using D gates. It is connected to a clock, permanently increasing the binary output value. When the value passes the biggest possible value (fifteen in this case), the counter restarts from zero."}
--------------------------------------------------------------------------------
/views/librarySketches/library__44BitCounter_frame.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SimonBuxx/LogiJS/87a03cba7f0443603f538af7653f65ea7f4a219b/views/librarySketches/library__44BitCounter_frame.png
--------------------------------------------------------------------------------
/views/librarySketches/library__5tour.json:
--------------------------------------------------------------------------------
1 | {"caption":"Tour","gates":[{"x":"210","y":"210","direction":"0","inputCount":"2","outputCount":"1","logicFunction":"\"and\"","outputsInv":"[false]","inputsInv":"[false,false]"},{"x":"210","y":"360","direction":"0","inputCount":"2","outputCount":"1","logicFunction":"\"or\"","outputsInv":"[false]","inputsInv":"[false,false]"},{"x":"210","y":"510","direction":"0","inputCount":"2","outputCount":"1","logicFunction":"\"xor\"","outputsInv":"[false]","inputsInv":"[false,false]"},{"x":"1380","y":"240","direction":"0","inputCount":"2","outputCount":"1","logicFunction":"\"or\"","outputsInv":"[true]","inputsInv":"[false,false]"},{"x":"1380","y":"360","direction":"0","inputCount":"2","outputCount":"1","logicFunction":"\"or\"","outputsInv":"[true]","inputsInv":"[false,false]"},{"x":"1080","y":"600","direction":"0","inputCount":"2","outputCount":"1","logicFunction":"\"and\"","outputsInv":"[false]","inputsInv":"[false,false]"},{"x":"1080","y":"720","direction":"0","inputCount":"2","outputCount":"1","logicFunction":"\"xor\"","outputsInv":"[false]","inputsInv":"[false,false]"}],"outputs":[{"x":"330","y":"240","colr":"0"},{"x":"330","y":"390","colr":"0"},{"x":"330","y":"540","colr":"0"},{"x":"1560","y":"270","colr":"0"},{"x":"1560","y":"390","colr":"0"},{"x":"1260","y":"630","colr":"0"},{"x":"1260","y":"750","colr":"0"},{"x":"690","y":"60","colr":"0"},{"x":"690","y":"90","colr":"1"},{"x":"690","y":"120","colr":"2"},{"x":"690","y":"150","colr":"3"},{"x":"1200","y":"90","colr":"0"}],"inputs":[{"x":"105","y":"165","framecount":"-1","clock":"false"},{"x":"165","y":"165","framecount":"-1","clock":"false"},{"x":"1275","y":"255","framecount":"-1","clock":"false"},{"x":"1275","y":"405","framecount":"-1","clock":"false"},{"x":"315","y":"705","framecount":"0","clock":"true","speed":"30"},{"x":"945","y":"615","framecount":"-1","clock":"false"},{"x":"945","y":"645","framecount":"-1","clock":"false"},{"x":"315","y":"45","framecount":"0","clock":"true","speed":"15"},{"x":"945","y":"75","framecount":"0","clock":"false"}],"wires":[{"x1":"180","y1":"570","x2":"210"},{"x1":"180","y1":"180","y2":"570"},{"x1":"180","y1":"270","x2":"210"},{"x1":"180","y1":"420","x2":"210"},{"x1":"120","y1":"540","x2":"210"},{"x1":"120","y1":"180","y2":"540"},{"x1":"120","y1":"390","x2":"210"},{"x1":"120","y1":"240","x2":"210"},{"x1":"270","y1":"240","x2":"330"},{"x1":"270","y1":"390","x2":"330"},{"x1":"270","y1":"540","x2":"330"},{"x1":"1350","y1":"360","x2":"1470"},{"x1":"1440","y1":"390","x2":"1560"},{"x1":"1470","y1":"360","y2":"390"},{"x1":"1350","y1":"300","x2":"1380"},{"x1":"1350","y1":"300","y2":"360"},{"x1":"1440","y1":"270","x2":"1560"},{"x1":"1500","y1":"270","y2":"330"},{"x1":"1320","y1":"330","x2":"1500"},{"x1":"1320","y1":"330","y2":"390"},{"x1":"1320","y1":"390","x2":"1380"},{"x1":"1290","y1":"270","x2":"1380"},{"x1":"1290","y1":"420","x2":"1380"},{"x1":"480","y1":"720","x2":"510"},{"x1":"510","y1":"690","y2":"720"},{"x1":"480","y1":"750","x2":"540"},{"x1":"540","y1":"690","y2":"750"},{"x1":"480","y1":"780","x2":"570"},{"x1":"570","y1":"690","y2":"780"},{"x1":"480","y1":"810","x2":"600"},{"x1":"600","y1":"690","y2":"810"},{"x1":"330","y1":"720","x2":"420"},{"x1":"960","y1":"630","x2":"1080"},{"x1":"960","y1":"660","x2":"1080"},{"x1":"1050","y1":"750","x2":"1080"},{"x1":"1050","y1":"630","y2":"750"},{"x1":"1020","y1":"780","x2":"1080"},{"x1":"1020","y1":"660","y2":"780"},{"x1":"1140","y1":"630","x2":"1260"},{"x1":"1140","y1":"750","x2":"1260"},{"x1":"480","y1":"90","x2":"570"},{"x1":"480","y1":"60","x2":"570"},{"x1":"330","y1":"60","x2":"420"},{"x1":"630","y1":"60","x2":"690"},{"x1":"630","y1":"90","x2":"690"},{"x1":"630","y1":"120","x2":"690"},{"x1":"630","y1":"150","x2":"690"},{"x1":"960","y1":"90","x2":"1050"},{"x1":"1110","y1":"90","x2":"1200"}],"conpoints":[{"x":"180","y":"270"},{"x":"180","y":"420"},{"x":"120","y":"390"},{"x":"120","y":"240"},{"x":"1500","y":"270"},{"x":"1470","y":"390"},{"x":"1050","y":"630"},{"x":"1020","y":"660"}],"diodes":[],"customs":[{"x":"420","y":"690","direction":"0","filename":"\"4-counter.json\"","outputsInv":"[]","inputsInv":"[]"},{"x":"570","y":"30","direction":"0","filename":"\"2-decoder.json\"","outputsInv":"[]","inputsInv":"[]"},{"x":"420","y":"30","direction":"0","filename":"\"2-counter.json\"","outputsInv":"[]","inputsInv":"[]"},{"x":"1050","y":"60","direction":"0","filename":"\"not-gate.json\"","outputsInv":"[]","inputsInv":"[]"}],"labels":[],"segDisplays":[{"x":"480","y":"600","inputCount":"4","inputsInv":"[false,false,false,false]"}]}
--------------------------------------------------------------------------------
/views/librarySketches/library__hover.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SimonBuxx/LogiJS/87a03cba7f0443603f538af7653f65ea7f4a219b/views/librarySketches/library__hover.png
--------------------------------------------------------------------------------
/views/login.pug:
--------------------------------------------------------------------------------
1 | doctype html
2 |
3 | head
4 | |
5 | |
10 | |
11 | title LogiJS: Login
12 | meta(name='keywords', content='LogiJS, logic, circuit, simulation, simulator, editor, free, open, source, gate, input, output, sketch, electronics, physics, informatics, it, \
13 | computer, chip, pcb, design, creator, creation, processor, cpu, logi, js, javascript')
14 | meta(name='description', content='LogiJS is a web-based logic circuit simulator for educational use. Discover the world of logic circuits.')
15 | meta(charset='UTF-8')
16 | meta(name='viewport', content='width=device-width, initial-scale=1.0')
17 | link(rel='shortcut icon', href='images/favi.png')
18 | style
19 | include css/bootstrap.css
20 | include css/index_style.css
21 | link(href='https://fonts.googleapis.com/css?family=Open+Sans:400,600,300', rel='stylesheet', type='text/css')
22 | link(rel='stylesheet', type='text/css', href='https://cdnjs.cloudflare.com/ajax/libs/cookieconsent2/3.1.0/cookieconsent.min.css')
23 | link(rel="stylesheet", type='text/css', href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.11.2/css/all.min.css")
24 | script(src='https://cdnjs.cloudflare.com/ajax/libs/cookieconsent2/3.1.0/cookieconsent.min.js')
25 | script.
26 | window.addEventListener("load", function () {
27 | window.cookieconsent.initialise({
28 | "position": "bottom-right",
29 | "content": {
30 | "dismiss": "Allow Cookies"
31 | },
32 | "palette": {
33 | "popup": {
34 | "background": "#323232",
35 | "text": "#fff",
36 | "link": "#c83232"
37 | },
38 | "button": {
39 | "background": "#c83232",
40 | "text": "#ffffff"
41 | }
42 | }
43 | })
44 | });
45 | body
46 | |
47 | |
49 | |
50 | .top-menu#top
51 | .container
52 | .navbar.navbar-default.navbar-fixed-top(role='navigation')
53 | .container
54 | ul.nav.navbar-nav.navbar-left
55 | li
56 | a.internal-link(rel='nofollow', href='/#features', target='_parent') Features
57 | li
58 | a.internal-link(rel='nofollow', href='/#samples', target='_parent') Samples
59 | li
60 | a.internal-link(rel='nofollow', href='/#about', target='_parent') About
61 | .navbar-header
62 | a.navbar-brand(href='/#top', style="transition: 0.2s;")
63 | img#top_logo(src='images/logo_index_new.png', alt='LogiJS logo', title='LogiJS', style='float: left;')
64 | div#logo-div
65 | p#logo-text Logic Circuit
66 | br
67 | | Simulation
68 | span(style="color: #c83232;") .
69 | .navbar-collapse.collapse
70 | ul.nav.navbar-nav.navbar-right
71 | li
72 | a.login-button.internal-link(rel='nofollow', href='#', target='_parent') Login
73 | li
74 | a.internal-link(rel='nofollow', href='/signup', target='_parent') Register
75 | li
76 | a#mode-button.internal-link(rel='nofollow', href='javascript:;', target='_parent' title='Toggle Dark Mode')
77 | .slogan-container(style="margin-top: 150px;")
78 | h1.background-text Discover the world
79 | .login_container
80 | form.Login.login-background
81 | if failed
82 | p.login-message Login failed
83 | span(style="color: #c83232;") .
84 | else if signup_success
85 | p.login-message Registration successful
86 | span(style="color: #c83232;") .
87 | else
88 | h1.login_title Login
89 | span(style="color: #c83232;") .
90 | p
91 | input.username(type='text', placeholder='Username')
92 | br
93 | input.password(type='password', placeholder='Password')
94 | br
95 | input.btn.btn-lg.btn-orange.login-confirm-button(type='submit', value='Login', role='button')
96 | p.login-redirect-text
97 | | Don't have an account?
98 | a.login-redirect-text(href='/signup') Register
99 | br
100 | .footer_bottom.footer_bottom_absolute
101 | .footer_bottom_content
102 | .footer_box.footer_box_outer
103 | a.internal-link(rel='nofollow', href='/terms-of-service', target='_parent') Terms of Service
104 | a.internal-link(rel='nofollow', href='/legal', target='_parent') Legal Notice
105 | .footer_box.footer_box_inner
106 | p(style="text-align: center; display: inline-block; width: 100%;")
107 | a(href='https://twitter.com/logi_js', target='_blank', style="margin-right: 5px;")
108 | img(src="images/twitter.png" style="width: 40px; margin-top: -20px;")
109 | a(href='https://github.com/SimonBuxx/logijs', target='_blank', style="margin-left: 5px;")
110 | img(src="images/github_dark.png" style="width: 40px; margin-top: -20px;")
111 | .footer_box.footer_box_outer.footer_right
112 | p(style="text-align: right;") Made with in Lübeck
113 | span(style="color: #c83232;") .
114 | script
115 | include ../libraries/jquery.min.js
116 | include ../libraries/bootstrap.min.js
117 | include ../site_scripts/login.js
--------------------------------------------------------------------------------
/views/profile.pug:
--------------------------------------------------------------------------------
1 | doctype html
2 |
3 | head
4 | |
5 | |
10 | |
11 | title LogiJS: Profile
12 | meta(name='keywords', content='LogiJS, logic, circuit, simulation, simulator, editor, free, open, source, gate, input, output, sketch, electronics, physics, informatics, it, \
13 | computer, chip, pcb, design, creator, creation, processor, cpu, logi, js, javascript')
14 | meta(name='description', content='LogiJS is a web-based logic circuit simulator for educational use. Discover the world of logic circuits.')
15 | meta(charset='UTF-8')
16 | meta(name='viewport', content='width=device-width, initial-scale=1.0')
17 | link(rel='shortcut icon', href='images/favicon.ico')
18 | style
19 | include css/bootstrap.css
20 | include css/index_style.css
21 | link(href='https://fonts.googleapis.com/css?family=Open+Sans:400,600,300', rel='stylesheet', type='text/css')
22 | link(rel='stylesheet', type='text/css', href='https://cdnjs.cloudflare.com/ajax/libs/cookieconsent2/3.1.0/cookieconsent.min.css')
23 | link(rel="stylesheet", type='text/css', href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.11.2/css/all.min.css")
24 | script(src='https://cdnjs.cloudflare.com/ajax/libs/cookieconsent2/3.1.0/cookieconsent.min.js')
25 | script.
26 | window.addEventListener("load", function () {
27 | window.cookieconsent.initialise({
28 | "palette": {
29 | "popup": {
30 | "background": "#323232",
31 | "text": "#ffffff"
32 | },
33 | "button": {
34 | "background": "#c83232",
35 | "text": "#ffffff"
36 | }
37 | }
38 | })
39 | });
40 | body
41 | |
42 | |
44 | |
45 | .top-menu
46 | .container
47 | .navbar.navbar-default.navbar-fixed-top(role='navigation')
48 | .container
49 | .navbar-header
50 | button.navbar-toggle(type='button', data-toggle='collapse', data-target='.navbar-collapse')
51 | span.sr-only Toggle navigation
52 | span.icon-bar
53 | span.icon-bar
54 | span.icon-bar
55 | a.navbar-brand(href='/')
56 | img(src='images/logo_index.png', alt='LogiJS logo', title='LogiJS')
57 | .navbar-collapse.collapse
58 | ul.nav.navbar-nav.navbar-right
59 | li
60 | a.internal-link(rel='nofollow', href='/', target='_parent') HOME
61 | li
62 | a.internal-link(rel='nofollow', href='/samples', target='_parent') SAMPLES
63 | li
64 | a.external-link(rel='nofollow', href='https://www.github.com/SimonBuxx/LogiJS', target='_parent') GITHUB
65 | li
66 | a.user-button(href='/dashboard') #{user.toUpperCase()}
67 | #blurred-background
68 | .profile-mobile-bar.show-in-mobile
69 | form#import-button.Import(title="Coming soon!")
70 | button.btn.btn-lg.btn-orange(disabled="true", type='submit', role='button')
71 | IMPORT FILE
72 | button#profile-button.btn.btn-lg.btn-orange(type='submit', role='button', onclick="window.location.href='#'")
73 | PROFILE
74 | form#logout-button.Logout
75 | button.btn.btn-lg.btn-orange(type='submit', role='button')
76 | LOGOUT
77 | #info-card.card.profile_card
78 | img.profile-pic(src="images/default-profile.svg", alt="Profile picture")
79 | .profile-data
80 | h2 #{user}
81 | h3 #{email}
82 | h3 Maybe a member since date
83 | #password-card.profile_card
84 | .profile-data
85 | h2 Change Password
86 | h3 Here should be two password inputs and one button to change the password.
87 | .sidebar.profile-sidebar.hide-in-mobile
88 | .sticky-bar
89 | button#editor-button.btn.btn-lg.btn-orange(type='submit', rel="nofollow", onclick="window.location.href='/editor'", role='button')
90 | NEW SKETCH
91 | form#import-button.Import(title="Coming soon!")
92 | button.btn.btn-lg.btn-orange(disabled="true", type='submit', role='button')
93 | IMPORT FILE
94 | button#profile-button.btn.btn-lg.btn-orange(type='submit', role='button', onclick="window.location.href='#'")
95 | PROFILE
96 | form#logout-button.Logout
97 | button.btn.btn-lg.btn-orange(type='submit', role='button')
98 | LOGOUT
99 | .footer_bottom
100 | .text-center
101 | .footer_bottom_content
102 | span#footer-line
103 | a.internal-link(rel='nofollow', href='/terms-of-service', target='_parent') Terms of Service
104 | | |
105 | a.internal-link(rel='nofollow', href='/legal', target='_parent') Legal Notice
106 |
107 | script
108 | include ../libraries/jquery.min.js
109 | include ../libraries/bootstrap.min.js
110 | include ../site_scripts/dashboard.js
--------------------------------------------------------------------------------
/views/robots.txt:
--------------------------------------------------------------------------------
1 | User-Agent: *
2 | Allow: /
3 |
4 |
--------------------------------------------------------------------------------
/views/signup.pug:
--------------------------------------------------------------------------------
1 | doctype html
2 |
3 | head
4 | |
5 | |
10 | |
11 | title LogiJS: Register
12 | meta(name='keywords', content='LogiJS, logic, circuit, simulation, simulator, editor, free, open, source, gate, input, output, sketch, electronics, physics, informatics, it, \
13 | computer, chip, pcb, design, creator, creation, processor, cpu, logi, js, javascript')
14 | meta(name='description', content='LogiJS is a web-based logic circuit simulator for educational use. Discover the world of logic circuits.')
15 | meta(charset='UTF-8')
16 | meta(name='viewport', content='width=device-width, initial-scale=1.0')
17 | link(rel='shortcut icon', href='images/favi.png')
18 | style
19 | include css/bootstrap.css
20 | include css/index_style.css
21 | link(href='https://fonts.googleapis.com/css?family=Open+Sans:400,600,300', rel='stylesheet', type='text/css')
22 | link(rel='stylesheet', type='text/css', href='https://cdnjs.cloudflare.com/ajax/libs/cookieconsent2/3.1.0/cookieconsent.min.css')
23 | link(rel="stylesheet", type='text/css', href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.11.2/css/all.min.css")
24 | script(src='https://cdnjs.cloudflare.com/ajax/libs/cookieconsent2/3.1.0/cookieconsent.min.js')
25 | script.
26 | window.addEventListener("load", function () {
27 | window.cookieconsent.initialise({
28 | "position": "bottom-right",
29 | "content": {
30 | "dismiss": "Allow Cookies"
31 | },
32 | "palette": {
33 | "popup": {
34 | "background": "#323232",
35 | "text": "#fff",
36 | "link": "#c83232"
37 | },
38 | "button": {
39 | "background": "#c83232",
40 | "text": "#ffffff"
41 | }
42 | }
43 | })
44 | });
45 | body
46 | |
47 | |
49 | |
50 | .top-menu#top
51 | .container
52 | .navbar.navbar-default.navbar-fixed-top(role='navigation')
53 | .container
54 | ul.nav.navbar-nav.navbar-left
55 | li
56 | a.internal-link(rel='nofollow', href='/#features', target='_parent') Features
57 | li
58 | a.internal-link(rel='nofollow', href='/#samples', target='_parent') Samples
59 | li
60 | a.internal-link(rel='nofollow', href='/#about', target='_parent') About
61 | .navbar-header
62 | a.navbar-brand(href='/#top', style="transition: 0.2s;")
63 | img#top_logo(src='images/logo_index_new.png', alt='LogiJS logo', title='LogiJS', style='float: left;')
64 | div#logo-div
65 | p#logo-text Logic Circuit
66 | br
67 | | Simulation
68 | span(style="color: #c83232;") .
69 | .navbar-collapse.collapse
70 | ul.nav.navbar-nav.navbar-right
71 | li
72 | a.login-button.internal-link(rel='nofollow', href='/login', target='_parent') Login
73 | li
74 | a.internal-link(rel='nofollow', href='#', target='_parent') Register
75 | li
76 | a#mode-button.internal-link(rel='nofollow', href='javascript:;', target='_parent' title='Toggle Dark Mode')
77 | .slogan-container(style="margin-top: 150px;")
78 | h1.background-text Discover the world
79 | .login_container
80 | - var error = parseInt(error_code);
81 | form.SignUp.login-background
82 | case error
83 | when 1: p.login-message Username invalid
84 | span(style="color: #c83232;") .
85 | when 2: p.login-message Email address invalid
86 | span(style="color: #c83232;") .
87 | when 3
88 | p.login-message Password invalid
89 | span(style="color: #c83232;") .
90 | p.login-message.password-tipps Please enter 6 to 50 upper- AND lowercase characters, containing at least one digit
91 | span(style="color: #c83232;") .
92 | when 4: p.login-message Username already taken
93 | span(style="color: #c83232;") .
94 | default: h1.login_title Register
95 | span(style="color: #c83232;") .
96 | p
97 | input.username(type='text', placeholder='Username')
98 | br
99 | input.email(type='text', placeholder='E-Mail')
100 | br
101 | input.password(type='password', placeholder='Password')
102 | br
103 | input.btn.btn-lg.btn-orange.login-confirm-button(type='submit', value='Register', role='button')
104 | p.login-redirect-text
105 | | By continuing, you are accepting our
106 | a.login-redirect-text(href='/terms-of-service') Terms of Service
107 | | .
108 | p.login-redirect-text
109 | | Already have an account?
110 | a.login-redirect-text(href='/login') Login
111 | br
112 | .footer_bottom.footer_bottom_absolute
113 | .footer_bottom_content
114 | .footer_box.footer_box_outer
115 | a.internal-link(rel='nofollow', href='/terms-of-service', target='_parent') Terms of Service
116 | a.internal-link(rel='nofollow', href='/legal', target='_parent') Legal Notice
117 | .footer_box.footer_box_inner
118 | p(style="text-align: center; display: inline-block; width: 100%;")
119 | a(href='https://twitter.com/logi_js', target='_blank', style="margin-right: 5px;")
120 | img(src="images/twitter.png" style="width: 40px; margin-top: -20px;")
121 | a(href='https://github.com/SimonBuxx/logijs', target='_blank', style="margin-left: 5px;")
122 | img(src="images/github_dark.png" style="width: 40px; margin-top: -20px;")
123 | .footer_box.footer_box_outer.footer_right
124 | p(style="text-align: right;") Made with in Lübeck
125 | span(style="color: #c83232;") .
126 | script
127 | include ../libraries/jquery.min.js
128 | include ../libraries/bootstrap.min.js
129 | include ../site_scripts/create_account.js
--------------------------------------------------------------------------------
/views/sketches/1-buffer.json:
--------------------------------------------------------------------------------
1 | {"caption":"","gates":[{"x":"540","y":"210","direction":"0","inputCount":"2","outputCount":"1","logicFunction":"\"and\"","outputsInv":"[false]","inputsInv":"[false,false]"}],"outputs":[{"x":"690","y":"240","colr":"0","lbl":"1"}],"inputs":[{"x":"435","y":"225","framecount":"-1","clock":"false"}],"wires":[{"x1":"450","y1":"240","x2":"540"},{"x1":"480","y1":"270","x2":"540"},{"x1":"480","y1":"240","y2":"270"},{"x1":"600","y1":"240","x2":"690"}],"conpoints":[{"x":"480","y":"240"}],"diodes":[],"customs":[],"labels":[],"segDisplays":[]}
--------------------------------------------------------------------------------
/views/sketches/1-demux.json:
--------------------------------------------------------------------------------
1 | {
2 | "caption": "DEMUX",
3 | "gates": [
4 | {
5 | "x": "990",
6 | "y": "360",
7 | "direction": "0",
8 | "inputCount": "2",
9 | "outputCount": "1",
10 | "logicFunction": "\"and\"",
11 | "outputsInv": "[false]",
12 | "inputsInv": "[false,true]"
13 | },
14 | {
15 | "x": "990",
16 | "y": "450",
17 | "direction": "0",
18 | "inputCount": "2",
19 | "outputCount": "1",
20 | "logicFunction": "\"and\"",
21 | "outputsInv": "[false]",
22 | "inputsInv": "[false,false]"
23 | }
24 | ],
25 | "outputs": [
26 | {
27 | "x": "1080",
28 | "y": "390",
29 | "colr": "0",
30 | "lbl": "0"
31 | },
32 | {
33 | "x": "1080",
34 | "y": "480",
35 | "colr": "0",
36 | "lbl": "1"
37 | }
38 | ],
39 | "inputs": [
40 | {
41 | "x": "855",
42 | "y": "375",
43 | "framecount": "-1",
44 | "clock": "false"
45 | },
46 | {
47 | "x": "915",
48 | "y": "345",
49 | "istop": "true",
50 | "lbl": "2º",
51 | "framecount": "-1",
52 | "clock": "false"
53 | }
54 | ],
55 | "segments": [],
56 | "wires": [
57 | {
58 | "x1": "960",
59 | "y1": "480",
60 | "x2": "990"
61 | },
62 | {
63 | "x1": "1050",
64 | "y1": "390",
65 | "x2": "1080"
66 | },
67 | {
68 | "x1": "1050",
69 | "y1": "480",
70 | "x2": "1080"
71 | },
72 | {
73 | "x1": "930",
74 | "y1": "420",
75 | "x2": "990"
76 | },
77 | {
78 | "x1": "930",
79 | "y1": "510",
80 | "x2": "990"
81 | },
82 | {
83 | "x1": "960",
84 | "y1": "390",
85 | "y2": "480"
86 | },
87 | {
88 | "x1": "870",
89 | "y1": "390",
90 | "x2": "990"
91 | },
92 | {
93 | "x1": "930",
94 | "y1": "360",
95 | "y2": "510"
96 | }
97 | ],
98 | "conpoints": [
99 | {
100 | "x": "960",
101 | "y": "390"
102 | },
103 | {
104 | "x": "930",
105 | "y": "420"
106 | }
107 | ],
108 | "diodes": [],
109 | "customs": [],
110 | "labels": [],
111 | "segDisplays": []
112 | }
113 |
--------------------------------------------------------------------------------
/views/sketches/1-mux.json:
--------------------------------------------------------------------------------
1 | {
2 | "caption": "MUX",
3 | "gates": [
4 | {
5 | "x": "870",
6 | "y": "270",
7 | "direction": "0",
8 | "inputCount": "2",
9 | "outputCount": "1",
10 | "logicFunction": "\"and\"",
11 | "outputsInv": "[false]",
12 | "inputsInv": "[true,false]"
13 | },
14 | {
15 | "x": "870",
16 | "y": "330",
17 | "direction": "0",
18 | "inputCount": "2",
19 | "outputCount": "1",
20 | "logicFunction": "\"and\"",
21 | "outputsInv": "[false]",
22 | "inputsInv": "[false,false]"
23 | },
24 | {
25 | "x": "990",
26 | "y": "270",
27 | "direction": "0",
28 | "inputCount": "2",
29 | "outputCount": "1",
30 | "logicFunction": "\"or\"",
31 | "outputsInv": "[false]",
32 | "inputsInv": "[false,false]"
33 | }
34 | ],
35 | "outputs": [
36 | {
37 | "x": "1080",
38 | "y": "300",
39 | "colr": "0"
40 | }
41 | ],
42 | "inputs": [
43 | {
44 | "x": "825",
45 | "y": "255",
46 | "istop": "true",
47 | "lbl": "2º",
48 | "framecount": "-1",
49 | "clock": "false"
50 | },
51 | {
52 | "x": "795",
53 | "y": "315",
54 | "lbl": "0",
55 | "framecount": "-1",
56 | "clock": "false"
57 | },
58 | {
59 | "x": "795",
60 | "y": "345",
61 | "lbl": "1",
62 | "framecount": "-1",
63 | "clock": "false"
64 | }
65 | ],
66 | "segments": [],
67 | "wires": [
68 | {
69 | "x1": "840",
70 | "y1": "300",
71 | "x2": "870"
72 | },
73 | {
74 | "x1": "840",
75 | "y1": "390",
76 | "x2": "870"
77 | },
78 | {
79 | "x1": "930",
80 | "y1": "360",
81 | "x2": "960"
82 | },
83 | {
84 | "x1": "960",
85 | "y1": "330",
86 | "y2": "360"
87 | },
88 | {
89 | "x1": "960",
90 | "y1": "330",
91 | "x2": "990"
92 | },
93 | {
94 | "x1": "1050",
95 | "y1": "300",
96 | "x2": "1080"
97 | },
98 | {
99 | "x1": "810",
100 | "y1": "330",
101 | "x2": "870"
102 | },
103 | {
104 | "x1": "810",
105 | "y1": "360",
106 | "x2": "870"
107 | },
108 | {
109 | "x1": "930",
110 | "y1": "300",
111 | "x2": "990"
112 | },
113 | {
114 | "x1": "840",
115 | "y1": "270",
116 | "y2": "390"
117 | }
118 | ],
119 | "conpoints": [
120 | {
121 | "x": "840",
122 | "y": "300"
123 | }
124 | ],
125 | "diodes": [],
126 | "customs": [],
127 | "labels": [],
128 | "segDisplays": []
129 | }
130 |
--------------------------------------------------------------------------------
/views/sketches/2-counter.json:
--------------------------------------------------------------------------------
1 | {
2 | "caption": "Counter",
3 | "gates": [
4 | {
5 | "x": "750",
6 | "y": "270",
7 | "direction": "0",
8 | "inputCount": "2",
9 | "outputCount": "1",
10 | "logicFunction": "\"xor\"",
11 | "outputsInv": "[false]",
12 | "inputsInv": "[false,false]"
13 | }
14 | ],
15 | "outputs": [
16 | {
17 | "x": "960",
18 | "y": "150",
19 | "colr": "0",
20 | "lbl": "2¹"
21 | },
22 | {
23 | "x": "690",
24 | "y": "150",
25 | "colr": "0",
26 | "lbl": "2º"
27 | }
28 | ],
29 | "inputs": [
30 | {
31 | "x": "495",
32 | "y": "405",
33 | "lbl": ">",
34 | "framecount": "-1",
35 | "clock": "false"
36 | }
37 | ],
38 | "segments": [],
39 | "wires": [
40 | {
41 | "x1": "660",
42 | "y1": "360",
43 | "x2": "690"
44 | },
45 | {
46 | "x1": "570",
47 | "y1": "300",
48 | "y2": "330"
49 | },
50 | {
51 | "x1": "570",
52 | "y1": "330",
53 | "x2": "600"
54 | },
55 | {
56 | "x1": "840",
57 | "y1": "360",
58 | "x2": "870"
59 | },
60 | {
61 | "x1": "570",
62 | "y1": "360",
63 | "x2": "600"
64 | },
65 | {
66 | "x1": "810",
67 | "y1": "300",
68 | "x2": "840"
69 | },
70 | {
71 | "x1": "840",
72 | "y1": "300",
73 | "y2": "330"
74 | },
75 | {
76 | "x1": "840",
77 | "y1": "330",
78 | "x2": "870"
79 | },
80 | {
81 | "x1": "930",
82 | "y1": "330",
83 | "x2": "960"
84 | },
85 | {
86 | "x1": "720",
87 | "y1": "300",
88 | "x2": "750"
89 | },
90 | {
91 | "x1": "840",
92 | "y1": "360",
93 | "y2": "420"
94 | },
95 | {
96 | "x1": "570",
97 | "y1": "360",
98 | "y2": "420"
99 | },
100 | {
101 | "x1": "690",
102 | "y1": "300",
103 | "y2": "360"
104 | },
105 | {
106 | "x1": "720",
107 | "y1": "330",
108 | "y2": "390"
109 | },
110 | {
111 | "x1": "660",
112 | "y1": "330",
113 | "x2": "750"
114 | },
115 | {
116 | "x1": "570",
117 | "y1": "300",
118 | "x2": "690"
119 | },
120 | {
121 | "x1": "720",
122 | "y1": "210",
123 | "y2": "300"
124 | },
125 | {
126 | "x1": "690",
127 | "y1": "150",
128 | "y2": "270"
129 | },
130 | {
131 | "x1": "540",
132 | "y1": "270",
133 | "y2": "390"
134 | },
135 | {
136 | "x1": "960",
137 | "y1": "150",
138 | "y2": "330"
139 | },
140 | {
141 | "x1": "720",
142 | "y1": "210",
143 | "x2": "960"
144 | },
145 | {
146 | "x1": "540",
147 | "y1": "270",
148 | "x2": "690"
149 | },
150 | {
151 | "x1": "540",
152 | "y1": "390",
153 | "x2": "720"
154 | },
155 | {
156 | "x1": "510",
157 | "y1": "420",
158 | "x2": "840"
159 | }
160 | ],
161 | "conpoints": [
162 | {
163 | "x": "570",
164 | "y": "420"
165 | },
166 | {
167 | "x": "960",
168 | "y": "210"
169 | },
170 | {
171 | "x": "720",
172 | "y": "330"
173 | }
174 | ],
175 | "diodes": [],
176 | "customs": [
177 | {
178 | "x": "600",
179 | "y": "300",
180 | "direction": "0",
181 | "filename": "\"d-flipflop.json\"",
182 | "outputsInv": "[false,false,false,false,false,false,false,false]",
183 | "inputsInv": "[false,false,false,false,false,false,false,false]"
184 | },
185 | {
186 | "x": "870",
187 | "y": "300",
188 | "direction": "0",
189 | "filename": "\"d-flipflop.json\"",
190 | "outputsInv": "[false,false,false,false,false,false,false,false]",
191 | "inputsInv": "[false,false,false,false,false,false,false,false]"
192 | }
193 | ],
194 | "labels": [],
195 | "segDisplays": []
196 | }
197 |
--------------------------------------------------------------------------------
/views/sketches/2-decoder.json:
--------------------------------------------------------------------------------
1 | {
2 | "caption": "DecoderOld",
3 | "gates": [
4 | {
5 | "x": "990",
6 | "y": "270",
7 | "direction": "0",
8 | "inputCount": "2",
9 | "outputCount": "1",
10 | "logicFunction": "\"and\"",
11 | "outputsInv": "[false]",
12 | "inputsInv": "[true,true]"
13 | },
14 | {
15 | "x": "990",
16 | "y": "330",
17 | "direction": "0",
18 | "inputCount": "2",
19 | "outputCount": "1",
20 | "logicFunction": "\"and\"",
21 | "outputsInv": "[false]",
22 | "inputsInv": "[false,true]"
23 | },
24 | {
25 | "x": "990",
26 | "y": "390",
27 | "direction": "0",
28 | "inputCount": "2",
29 | "outputCount": "1",
30 | "logicFunction": "\"and\"",
31 | "outputsInv": "[false]",
32 | "inputsInv": "[true,false]"
33 | },
34 | {
35 | "x": "990",
36 | "y": "450",
37 | "direction": "0",
38 | "inputCount": "2",
39 | "outputCount": "1",
40 | "logicFunction": "\"and\"",
41 | "outputsInv": "[false]",
42 | "inputsInv": "[false,false]"
43 | }
44 | ],
45 | "outputs": [
46 | {
47 | "x": "1110",
48 | "y": "300",
49 | "colr": "0",
50 | "lbl": "0"
51 | },
52 | {
53 | "x": "1110",
54 | "y": "360",
55 | "colr": "0",
56 | "lbl": "1"
57 | },
58 | {
59 | "x": "1110",
60 | "y": "420",
61 | "colr": "0",
62 | "lbl": "2"
63 | },
64 | {
65 | "x": "1110",
66 | "y": "480",
67 | "colr": "0",
68 | "lbl": "3"
69 | }
70 | ],
71 | "inputs": [
72 | {
73 | "x": "915",
74 | "y": "255",
75 | "framecount": "-1",
76 | "clock": "false",
77 | "lbl": "2¹"
78 | },
79 | {
80 | "x": "945",
81 | "y": "255",
82 | "framecount": "-1",
83 | "clock": "false",
84 | "lbl": "2º"
85 | }
86 | ],
87 | "segments": [],
88 | "wires": [
89 | {
90 | "x1": "960",
91 | "y1": "480",
92 | "x2": "990"
93 | },
94 | {
95 | "x1": "960",
96 | "y1": "300",
97 | "x2": "990"
98 | },
99 | {
100 | "x1": "960",
101 | "y1": "360",
102 | "x2": "990"
103 | },
104 | {
105 | "x1": "960",
106 | "y1": "420",
107 | "x2": "990"
108 | },
109 | {
110 | "x1": "930",
111 | "y1": "510",
112 | "x2": "990"
113 | },
114 | {
115 | "x1": "930",
116 | "y1": "450",
117 | "x2": "990"
118 | },
119 | {
120 | "x1": "930",
121 | "y1": "390",
122 | "x2": "990"
123 | },
124 | {
125 | "x1": "930",
126 | "y1": "330",
127 | "x2": "990"
128 | },
129 | {
130 | "x1": "1050",
131 | "y1": "300",
132 | "x2": "1110"
133 | },
134 | {
135 | "x1": "1050",
136 | "y1": "360",
137 | "x2": "1110"
138 | },
139 | {
140 | "x1": "1050",
141 | "y1": "420",
142 | "x2": "1110"
143 | },
144 | {
145 | "x1": "1050",
146 | "y1": "480",
147 | "x2": "1110"
148 | },
149 | {
150 | "x1": "930",
151 | "y1": "270",
152 | "y2": "510"
153 | },
154 | {
155 | "x1": "960",
156 | "y1": "270",
157 | "y2": "480"
158 | }
159 | ],
160 | "conpoints": [
161 | {
162 | "x": "930",
163 | "y": "450"
164 | },
165 | {
166 | "x": "930",
167 | "y": "390"
168 | },
169 | {
170 | "x": "930",
171 | "y": "330"
172 | },
173 | {
174 | "x": "960",
175 | "y": "300"
176 | },
177 | {
178 | "x": "960",
179 | "y": "360"
180 | },
181 | {
182 | "x": "960",
183 | "y": "420"
184 | }
185 | ],
186 | "diodes": [],
187 | "customs": [],
188 | "labels": [],
189 | "segDisplays": []
190 | }
191 |
--------------------------------------------------------------------------------
/views/sketches/2-demux.json:
--------------------------------------------------------------------------------
1 | {
2 | "caption": "DEMUX",
3 | "gates": [
4 | {
5 | "x": "870",
6 | "y": "270",
7 | "direction": "0",
8 | "inputCount": "3",
9 | "outputCount": "1",
10 | "logicFunction": "\"and\"",
11 | "outputsInv": "[false]",
12 | "inputsInv": "[true,true,false]"
13 | },
14 | {
15 | "x": "870",
16 | "y": "390",
17 | "direction": "0",
18 | "inputCount": "3",
19 | "outputCount": "1",
20 | "logicFunction": "\"and\"",
21 | "outputsInv": "[false]",
22 | "inputsInv": "[false,true,false]"
23 | },
24 | {
25 | "x": "870",
26 | "y": "510",
27 | "direction": "0",
28 | "inputCount": "3",
29 | "outputCount": "1",
30 | "logicFunction": "\"and\"",
31 | "outputsInv": "[false]",
32 | "inputsInv": "[true,false,false]"
33 | },
34 | {
35 | "x": "870",
36 | "y": "630",
37 | "direction": "0",
38 | "inputCount": "3",
39 | "outputCount": "1",
40 | "logicFunction": "\"and\"",
41 | "outputsInv": "[false]",
42 | "inputsInv": "[false,false,false]"
43 | }
44 | ],
45 | "outputs": [
46 | {
47 | "x": "990",
48 | "y": "300",
49 | "colr": "0",
50 | "lbl": "0"
51 | },
52 | {
53 | "x": "990",
54 | "y": "420",
55 | "colr": "0",
56 | "lbl": "1"
57 | },
58 | {
59 | "x": "990",
60 | "y": "540",
61 | "colr": "0",
62 | "lbl": "2"
63 | },
64 | {
65 | "x": "990",
66 | "y": "660",
67 | "colr": "0",
68 | "lbl": "3"
69 | }
70 | ],
71 | "inputs": [
72 | {
73 | "x": "795",
74 | "y": "225",
75 | "istop": "true",
76 | "lbl": "2¹",
77 | "framecount": "-1",
78 | "clock": "false"
79 | },
80 | {
81 | "x": "825",
82 | "y": "225",
83 | "istop": "true",
84 | "lbl": "2º",
85 | "framecount": "-1",
86 | "clock": "false"
87 | },
88 | {
89 | "x": "765",
90 | "y": "225",
91 | "framecount": "-1",
92 | "clock": "false"
93 | }
94 | ],
95 | "segments": [],
96 | "wires": [
97 | {
98 | "x1": "840",
99 | "y1": "300",
100 | "x2": "870"
101 | },
102 | {
103 | "x1": "840",
104 | "y1": "420",
105 | "x2": "870"
106 | },
107 | {
108 | "x1": "840",
109 | "y1": "540",
110 | "x2": "870"
111 | },
112 | {
113 | "x1": "840",
114 | "y1": "660",
115 | "x2": "870"
116 | },
117 | {
118 | "x1": "810",
119 | "y1": "690",
120 | "x2": "870"
121 | },
122 | {
123 | "x1": "810",
124 | "y1": "330",
125 | "x2": "870"
126 | },
127 | {
128 | "x1": "810",
129 | "y1": "450",
130 | "x2": "870"
131 | },
132 | {
133 | "x1": "810",
134 | "y1": "570",
135 | "x2": "870"
136 | },
137 | {
138 | "x1": "930",
139 | "y1": "300",
140 | "x2": "990"
141 | },
142 | {
143 | "x1": "930",
144 | "y1": "420",
145 | "x2": "990"
146 | },
147 | {
148 | "x1": "930",
149 | "y1": "540",
150 | "x2": "990"
151 | },
152 | {
153 | "x1": "930",
154 | "y1": "660",
155 | "x2": "990"
156 | },
157 | {
158 | "x1": "780",
159 | "y1": "360",
160 | "x2": "870"
161 | },
162 | {
163 | "x1": "780",
164 | "y1": "480",
165 | "x2": "870"
166 | },
167 | {
168 | "x1": "780",
169 | "y1": "600",
170 | "x2": "870"
171 | },
172 | {
173 | "x1": "780",
174 | "y1": "720",
175 | "x2": "870"
176 | },
177 | {
178 | "x1": "840",
179 | "y1": "240",
180 | "y2": "660"
181 | },
182 | {
183 | "x1": "810",
184 | "y1": "240",
185 | "y2": "690"
186 | },
187 | {
188 | "x1": "780",
189 | "y1": "240",
190 | "y2": "720"
191 | }
192 | ],
193 | "conpoints": [
194 | {
195 | "x": "840",
196 | "y": "300"
197 | },
198 | {
199 | "x": "840",
200 | "y": "420"
201 | },
202 | {
203 | "x": "840",
204 | "y": "540"
205 | },
206 | {
207 | "x": "810",
208 | "y": "330"
209 | },
210 | {
211 | "x": "810",
212 | "y": "450"
213 | },
214 | {
215 | "x": "810",
216 | "y": "570"
217 | },
218 | {
219 | "x": "780",
220 | "y": "360"
221 | },
222 | {
223 | "x": "780",
224 | "y": "480"
225 | },
226 | {
227 | "x": "780",
228 | "y": "600"
229 | }
230 | ],
231 | "diodes": [],
232 | "customs": [],
233 | "labels": [],
234 | "segDisplays": []
235 | }
236 |
--------------------------------------------------------------------------------
/views/sketches/2-mux.json:
--------------------------------------------------------------------------------
1 | {
2 | "caption": "MUX",
3 | "gates": [
4 | {
5 | "x": "780",
6 | "y": "300",
7 | "direction": "0",
8 | "inputCount": "3",
9 | "outputCount": "1",
10 | "logicFunction": "\"and\"",
11 | "outputsInv": "[false]",
12 | "inputsInv": "[true,true,false]"
13 | },
14 | {
15 | "x": "780",
16 | "y": "390",
17 | "direction": "0",
18 | "inputCount": "3",
19 | "outputCount": "1",
20 | "logicFunction": "\"and\"",
21 | "outputsInv": "[false]",
22 | "inputsInv": "[false,true,false]"
23 | },
24 | {
25 | "x": "780",
26 | "y": "480",
27 | "direction": "0",
28 | "inputCount": "3",
29 | "outputCount": "1",
30 | "logicFunction": "\"and\"",
31 | "outputsInv": "[false]",
32 | "inputsInv": "[true,false,false]"
33 | },
34 | {
35 | "x": "780",
36 | "y": "570",
37 | "direction": "0",
38 | "inputCount": "3",
39 | "outputCount": "1",
40 | "logicFunction": "\"and\"",
41 | "outputsInv": "[false]",
42 | "inputsInv": "[false,false,false]"
43 | },
44 | {
45 | "x": "960",
46 | "y": "390",
47 | "direction": "0",
48 | "inputCount": "4",
49 | "outputCount": "1",
50 | "logicFunction": "\"or\"",
51 | "outputsInv": "[false]",
52 | "inputsInv": "[false,false,false,false]"
53 | }
54 | ],
55 | "outputs": [
56 | {
57 | "x": "1080",
58 | "y": "420",
59 | "colr": "0"
60 | }
61 | ],
62 | "inputs": [
63 | {
64 | "x": "705",
65 | "y": "255",
66 | "istop": "true",
67 | "lbl": "2¹",
68 | "framecount": "-1",
69 | "clock": "false"
70 | },
71 | {
72 | "x": "735",
73 | "y": "255",
74 | "istop": "true",
75 | "lbl": "2º",
76 | "framecount": "-1",
77 | "clock": "false"
78 | },
79 | {
80 | "x": "675",
81 | "y": "375",
82 | "lbl": "0",
83 | "framecount": "-1",
84 | "clock": "false"
85 | },
86 | {
87 | "x": "675",
88 | "y": "465",
89 | "lbl": "1",
90 | "framecount": "-1",
91 | "clock": "false"
92 | },
93 | {
94 | "x": "675",
95 | "y": "555",
96 | "lbl": "2",
97 | "framecount": "-1",
98 | "clock": "false"
99 | },
100 | {
101 | "x": "675",
102 | "y": "645",
103 | "lbl": "3",
104 | "framecount": "-1",
105 | "clock": "false"
106 | }
107 | ],
108 | "segments": [],
109 | "wires": [
110 | {
111 | "x1": "750",
112 | "y1": "330",
113 | "x2": "780"
114 | },
115 | {
116 | "x1": "750",
117 | "y1": "420",
118 | "x2": "780"
119 | },
120 | {
121 | "x1": "750",
122 | "y1": "510",
123 | "x2": "780"
124 | },
125 | {
126 | "x1": "750",
127 | "y1": "600",
128 | "x2": "780"
129 | },
130 | {
131 | "x1": "930",
132 | "y1": "420",
133 | "x2": "960"
134 | },
135 | {
136 | "x1": "900",
137 | "y1": "420",
138 | "y2": "450"
139 | },
140 | {
141 | "x1": "840",
142 | "y1": "510",
143 | "x2": "870"
144 | },
145 | {
146 | "x1": "870",
147 | "y1": "480",
148 | "y2": "510"
149 | },
150 | {
151 | "x1": "720",
152 | "y1": "360",
153 | "x2": "780"
154 | },
155 | {
156 | "x1": "720",
157 | "y1": "450",
158 | "x2": "780"
159 | },
160 | {
161 | "x1": "720",
162 | "y1": "540",
163 | "x2": "780"
164 | },
165 | {
166 | "x1": "720",
167 | "y1": "630",
168 | "x2": "780"
169 | },
170 | {
171 | "x1": "840",
172 | "y1": "420",
173 | "x2": "900"
174 | },
175 | {
176 | "x1": "900",
177 | "y1": "450",
178 | "x2": "960"
179 | },
180 | {
181 | "x1": "840",
182 | "y1": "600",
183 | "x2": "900"
184 | },
185 | {
186 | "x1": "900",
187 | "y1": "510",
188 | "x2": "960"
189 | },
190 | {
191 | "x1": "1020",
192 | "y1": "420",
193 | "x2": "1080"
194 | },
195 | {
196 | "x1": "690",
197 | "y1": "390",
198 | "x2": "780"
199 | },
200 | {
201 | "x1": "690",
202 | "y1": "480",
203 | "x2": "780"
204 | },
205 | {
206 | "x1": "690",
207 | "y1": "570",
208 | "x2": "780"
209 | },
210 | {
211 | "x1": "690",
212 | "y1": "660",
213 | "x2": "780"
214 | },
215 | {
216 | "x1": "930",
217 | "y1": "330",
218 | "y2": "420"
219 | },
220 | {
221 | "x1": "840",
222 | "y1": "330",
223 | "x2": "930"
224 | },
225 | {
226 | "x1": "870",
227 | "y1": "480",
228 | "x2": "960"
229 | },
230 | {
231 | "x1": "900",
232 | "y1": "510",
233 | "y2": "600"
234 | },
235 | {
236 | "x1": "750",
237 | "y1": "270",
238 | "y2": "690"
239 | },
240 | {
241 | "x1": "720",
242 | "y1": "270",
243 | "y2": "690"
244 | }
245 | ],
246 | "conpoints": [
247 | {
248 | "x": "750",
249 | "y": "330"
250 | },
251 | {
252 | "x": "720",
253 | "y": "360"
254 | },
255 | {
256 | "x": "750",
257 | "y": "420"
258 | },
259 | {
260 | "x": "720",
261 | "y": "450"
262 | },
263 | {
264 | "x": "750",
265 | "y": "510"
266 | },
267 | {
268 | "x": "720",
269 | "y": "540"
270 | },
271 | {
272 | "x": "750",
273 | "y": "600"
274 | },
275 | {
276 | "x": "720",
277 | "y": "630"
278 | }
279 | ],
280 | "diodes": [],
281 | "customs": [],
282 | "labels": [],
283 | "segDisplays": []
284 | }
285 |
--------------------------------------------------------------------------------
/views/sketches/3-buffer.json:
--------------------------------------------------------------------------------
1 | {
2 | "caption": "3-Buffer",
3 | "gates": [
4 | {
5 | "x": "180",
6 | "y": "60",
7 | "direction": "0",
8 | "inputCount": "1",
9 | "outputCount": "1",
10 | "logicFunction": "\"and\"",
11 | "caption": "\"&\"",
12 | "outputsInv": "[false]",
13 | "inputsInv": "[false]"
14 | },
15 | {
16 | "x": "270",
17 | "y": "60",
18 | "direction": "0",
19 | "inputCount": "1",
20 | "outputCount": "1",
21 | "logicFunction": "\"and\"",
22 | "caption": "\"&\"",
23 | "outputsInv": "[false]",
24 | "inputsInv": "[false]"
25 | },
26 | {
27 | "x": "360",
28 | "y": "60",
29 | "direction": "0",
30 | "inputCount": "1",
31 | "outputCount": "1",
32 | "logicFunction": "\"and\"",
33 | "caption": "\"&\"",
34 | "outputsInv": "[false]",
35 | "inputsInv": "[false]"
36 | }
37 | ],
38 | "outputs": [
39 | {
40 | "x": "450",
41 | "y": "90",
42 | "colr": "0"
43 | }
44 | ],
45 | "inputs": [
46 | {
47 | "x": "135",
48 | "y": "75",
49 | "framecount": "-1",
50 | "clock": "false"
51 | }
52 | ],
53 | "segments": [],
54 | "wires": [
55 | {
56 | "x1": "240",
57 | "y1": "90",
58 | "x2": "270",
59 | "y2": "90"
60 | },
61 | {
62 | "x1": "330",
63 | "y1": "90",
64 | "x2": "360",
65 | "y2": "90"
66 | },
67 | {
68 | "x1": "420",
69 | "y1": "90",
70 | "x2": "450",
71 | "y2": "90"
72 | },
73 | {
74 | "x1": "150",
75 | "y1": "90",
76 | "x2": "180",
77 | "y2": "90"
78 | }
79 | ],
80 | "conpoints": [],
81 | "diodes": [],
82 | "customs": [],
83 | "labels": []
84 | }
85 |
--------------------------------------------------------------------------------
/views/sketches/3-counter.json:
--------------------------------------------------------------------------------
1 | {
2 | "caption": "Counter",
3 | "gates": [
4 | {
5 | "x": "750",
6 | "y": "270",
7 | "direction": "0",
8 | "inputCount": "2",
9 | "outputCount": "1",
10 | "logicFunction": "\"xor\"",
11 | "outputsInv": "[false]",
12 | "inputsInv": "[false,false]"
13 | },
14 | {
15 | "x": "1020",
16 | "y": "300",
17 | "direction": "0",
18 | "inputCount": "2",
19 | "outputCount": "1",
20 | "logicFunction": "\"and\"",
21 | "outputsInv": "[false]",
22 | "inputsInv": "[false,false]"
23 | },
24 | {
25 | "x": "1110",
26 | "y": "270",
27 | "direction": "0",
28 | "inputCount": "2",
29 | "outputCount": "1",
30 | "logicFunction": "\"xor\"",
31 | "outputsInv": "[false]",
32 | "inputsInv": "[false,false]"
33 | }
34 | ],
35 | "outputs": [
36 | {
37 | "x": "1320",
38 | "y": "150",
39 | "colr": "0",
40 | "lbl": "2²"
41 | },
42 | {
43 | "x": "960",
44 | "y": "150",
45 | "colr": "0",
46 | "lbl": "2¹"
47 | },
48 | {
49 | "x": "690",
50 | "y": "150",
51 | "colr": "0",
52 | "lbl": "2º"
53 | }
54 | ],
55 | "inputs": [
56 | {
57 | "x": "495",
58 | "y": "405",
59 | "lbl": ">",
60 | "framecount": "-1",
61 | "clock": "false"
62 | }
63 | ],
64 | "segments": [],
65 | "wires": [
66 | {
67 | "x1": "660",
68 | "y1": "360",
69 | "x2": "690"
70 | },
71 | {
72 | "x1": "570",
73 | "y1": "300",
74 | "y2": "330"
75 | },
76 | {
77 | "x1": "570",
78 | "y1": "330",
79 | "x2": "600"
80 | },
81 | {
82 | "x1": "840",
83 | "y1": "360",
84 | "x2": "870"
85 | },
86 | {
87 | "x1": "570",
88 | "y1": "360",
89 | "x2": "600"
90 | },
91 | {
92 | "x1": "1200",
93 | "y1": "360",
94 | "x2": "1230"
95 | },
96 | {
97 | "x1": "810",
98 | "y1": "300",
99 | "x2": "840"
100 | },
101 | {
102 | "x1": "840",
103 | "y1": "300",
104 | "y2": "330"
105 | },
106 | {
107 | "x1": "840",
108 | "y1": "330",
109 | "x2": "870"
110 | },
111 | {
112 | "x1": "930",
113 | "y1": "330",
114 | "x2": "960"
115 | },
116 | {
117 | "x1": "720",
118 | "y1": "300",
119 | "x2": "750"
120 | },
121 | {
122 | "x1": "1080",
123 | "y1": "270",
124 | "y2": "300"
125 | },
126 | {
127 | "x1": "1080",
128 | "y1": "300",
129 | "x2": "1110"
130 | },
131 | {
132 | "x1": "1080",
133 | "y1": "330",
134 | "x2": "1110"
135 | },
136 | {
137 | "x1": "990",
138 | "y1": "330",
139 | "x2": "1020"
140 | },
141 | {
142 | "x1": "1170",
143 | "y1": "300",
144 | "x2": "1200"
145 | },
146 | {
147 | "x1": "1200",
148 | "y1": "300",
149 | "y2": "330"
150 | },
151 | {
152 | "x1": "1200",
153 | "y1": "330",
154 | "x2": "1230"
155 | },
156 | {
157 | "x1": "1290",
158 | "y1": "330",
159 | "x2": "1320"
160 | },
161 | {
162 | "x1": "840",
163 | "y1": "360",
164 | "y2": "420"
165 | },
166 | {
167 | "x1": "570",
168 | "y1": "360",
169 | "y2": "420"
170 | },
171 | {
172 | "x1": "1200",
173 | "y1": "360",
174 | "y2": "420"
175 | },
176 | {
177 | "x1": "960",
178 | "y1": "360",
179 | "x2": "1020"
180 | },
181 | {
182 | "x1": "690",
183 | "y1": "300",
184 | "y2": "360"
185 | },
186 | {
187 | "x1": "720",
188 | "y1": "330",
189 | "y2": "390"
190 | },
191 | {
192 | "x1": "660",
193 | "y1": "330",
194 | "x2": "750"
195 | },
196 | {
197 | "x1": "570",
198 | "y1": "300",
199 | "x2": "690"
200 | },
201 | {
202 | "x1": "720",
203 | "y1": "210",
204 | "y2": "300"
205 | },
206 | {
207 | "x1": "690",
208 | "y1": "150",
209 | "y2": "270"
210 | },
211 | {
212 | "x1": "540",
213 | "y1": "270",
214 | "y2": "390"
215 | },
216 | {
217 | "x1": "960",
218 | "y1": "150",
219 | "y2": "360"
220 | },
221 | {
222 | "x1": "1320",
223 | "y1": "150",
224 | "y2": "330"
225 | },
226 | {
227 | "x1": "1080",
228 | "y1": "270",
229 | "x2": "1320"
230 | },
231 | {
232 | "x1": "990",
233 | "y1": "180",
234 | "y2": "330"
235 | },
236 | {
237 | "x1": "540",
238 | "y1": "270",
239 | "x2": "690"
240 | },
241 | {
242 | "x1": "540",
243 | "y1": "390",
244 | "x2": "720"
245 | },
246 | {
247 | "x1": "720",
248 | "y1": "210",
249 | "x2": "960"
250 | },
251 | {
252 | "x1": "690",
253 | "y1": "180",
254 | "x2": "990"
255 | },
256 | {
257 | "x1": "510",
258 | "y1": "420",
259 | "x2": "1200"
260 | }
261 | ],
262 | "conpoints": [
263 | {
264 | "x": "840",
265 | "y": "420"
266 | },
267 | {
268 | "x": "570",
269 | "y": "420"
270 | },
271 | {
272 | "x": "960",
273 | "y": "330"
274 | },
275 | {
276 | "x": "960",
277 | "y": "210"
278 | },
279 | {
280 | "x": "1320",
281 | "y": "270"
282 | },
283 | {
284 | "x": "690",
285 | "y": "180"
286 | },
287 | {
288 | "x": "720",
289 | "y": "330"
290 | }
291 | ],
292 | "diodes": [],
293 | "customs": [
294 | {
295 | "x": "600",
296 | "y": "300",
297 | "direction": "0",
298 | "filename": "\"d-flipflop.json\"",
299 | "outputsInv": "[false,false,false,false,false,false]",
300 | "inputsInv": "[false,false,false,false,false,false]"
301 | },
302 | {
303 | "x": "870",
304 | "y": "300",
305 | "direction": "0",
306 | "filename": "\"d-flipflop.json\"",
307 | "outputsInv": "[false,false,false,false,false,false]",
308 | "inputsInv": "[false,false,false,false,false,false]"
309 | },
310 | {
311 | "x": "1230",
312 | "y": "300",
313 | "direction": "0",
314 | "filename": "\"d-flipflop.json\"",
315 | "outputsInv": "[false,false,false,false,false,false,false,false]",
316 | "inputsInv": "[false,false,false,false,false,false,false,false]"
317 | }
318 | ],
319 | "labels": [],
320 | "segDisplays": []
321 | }
322 |
--------------------------------------------------------------------------------
/views/sketches/d-flipflop.json:
--------------------------------------------------------------------------------
1 | {
2 | "caption": "D-FF",
3 | "gates": [
4 | {
5 | "x": "390",
6 | "y": "90",
7 | "direction": "0",
8 | "inputCount": "2",
9 | "outputCount": "1",
10 | "logicFunction": "\"and\"",
11 | "outputsInv": "[false]",
12 | "inputsInv": "[false,false]"
13 | },
14 | {
15 | "x": "390",
16 | "y": "150",
17 | "direction": "0",
18 | "inputCount": "2",
19 | "outputCount": "1",
20 | "logicFunction": "\"and\"",
21 | "outputsInv": "[false]",
22 | "inputsInv": "[true,false]"
23 | },
24 | {
25 | "x": "240",
26 | "y": "120",
27 | "direction": "0",
28 | "inputCount": "2",
29 | "outputCount": "1",
30 | "logicFunction": "\"and\"",
31 | "outputsInv": "[false]",
32 | "inputsInv": "[true,false]"
33 | }
34 | ],
35 | "outputs": [
36 | {
37 | "x": "600",
38 | "y": "150",
39 | "colr": "0",
40 | "lbl": "Q"
41 | },
42 | {
43 | "x": "600",
44 | "y": "180",
45 | "colr": "0",
46 | "lbl": "Q̅"
47 | }
48 | ],
49 | "inputs": [
50 | {
51 | "x": "345",
52 | "y": "75",
53 | "lbl": "D",
54 | "framecount": "-1",
55 | "clock": "false"
56 | },
57 | {
58 | "x": "75",
59 | "y": "135",
60 | "lbl": ">",
61 | "framecount": "-1",
62 | "clock": "false"
63 | }
64 | ],
65 | "segments": [],
66 | "wires": [
67 | {
68 | "x1": "570",
69 | "y1": "150",
70 | "x2": "600"
71 | },
72 | {
73 | "x1": "570",
74 | "y1": "180",
75 | "x2": "600"
76 | },
77 | {
78 | "x1": "480",
79 | "y1": "150",
80 | "x2": "510"
81 | },
82 | {
83 | "x1": "480",
84 | "y1": "120",
85 | "y2": "150"
86 | },
87 | {
88 | "x1": "450",
89 | "y1": "120",
90 | "x2": "480"
91 | },
92 | {
93 | "x1": "360",
94 | "y1": "120",
95 | "x2": "390"
96 | },
97 | {
98 | "x1": "360",
99 | "y1": "180",
100 | "x2": "390"
101 | },
102 | {
103 | "x1": "210",
104 | "y1": "150",
105 | "x2": "240"
106 | },
107 | {
108 | "x1": "120",
109 | "y1": "150",
110 | "y2": "180"
111 | },
112 | {
113 | "x1": "450",
114 | "y1": "180",
115 | "x2": "510"
116 | },
117 | {
118 | "x1": "330",
119 | "y1": "210",
120 | "x2": "390"
121 | },
122 | {
123 | "x1": "330",
124 | "y1": "150",
125 | "y2": "210"
126 | },
127 | {
128 | "x1": "90",
129 | "y1": "150",
130 | "x2": "150"
131 | },
132 | {
133 | "x1": "300",
134 | "y1": "150",
135 | "x2": "390"
136 | },
137 | {
138 | "x1": "360",
139 | "y1": "90",
140 | "y2": "180"
141 | },
142 | {
143 | "x1": "120",
144 | "y1": "180",
145 | "x2": "240"
146 | }
147 | ],
148 | "conpoints": [
149 | {
150 | "x": "360",
151 | "y": "120"
152 | },
153 | {
154 | "x": "330",
155 | "y": "150"
156 | },
157 | {
158 | "x": "120",
159 | "y": "150"
160 | }
161 | ],
162 | "diodes": [],
163 | "customs": [
164 | {
165 | "x": "510",
166 | "y": "120",
167 | "direction": "0",
168 | "filename": "\"rs-flipflop.json\"",
169 | "outputsInv": "[]",
170 | "inputsInv": "[]"
171 | },
172 | {
173 | "x": "150",
174 | "y": "120",
175 | "direction": "0",
176 | "filename": "\"3-buffer.json\"",
177 | "outputsInv": "[]",
178 | "inputsInv": "[]"
179 | }
180 | ],
181 | "labels": [
182 | {
183 | "x": "90",
184 | "y": "270",
185 | "txt": "Three delays are required"
186 | },
187 | {
188 | "x": "90",
189 | "y": "300",
190 | "txt": "for the flipflop to permanently toggle"
191 | },
192 | {
193 | "x": "90",
194 | "y": "30",
195 | "txt": "Implementation of a D-Flipflop"
196 | }
197 | ],
198 | "segDisplays": []
199 | }
200 |
--------------------------------------------------------------------------------
/views/sketches/full_add.json:
--------------------------------------------------------------------------------
1 | {
2 | "caption": "FA",
3 | "gates": [
4 | {
5 | "x": "1080",
6 | "y": "270",
7 | "direction": "0",
8 | "inputCount": "2",
9 | "outputCount": "1",
10 | "logicFunction": "\"or\"",
11 | "outputsInv": "[false]",
12 | "inputsInv": "[false,false]"
13 | }
14 | ],
15 | "outputs": [
16 | {
17 | "x": "1170",
18 | "y": "300",
19 | "colr": "0",
20 | "lbl": "C"
21 | },
22 | {
23 | "x": "1170",
24 | "y": "360",
25 | "colr": "0",
26 | "lbl": "S"
27 | }
28 | ],
29 | "inputs": [
30 | {
31 | "x": "855",
32 | "y": "345",
33 | "framecount": "0",
34 | "clock": "false",
35 | "lbl": "A"
36 | },
37 | {
38 | "x": "855",
39 | "y": "315",
40 | "framecount": "0",
41 | "clock": "false",
42 | "lbl": "B"
43 | },
44 | {
45 | "x": "855",
46 | "y": "285",
47 | "framecount": "0",
48 | "clock": "false",
49 | "lbl": "C"
50 | }
51 | ],
52 | "segments": [],
53 | "wires": [
54 | {
55 | "x1": "1050",
56 | "y1": "330",
57 | "x2": "1080"
58 | },
59 | {
60 | "x1": "960",
61 | "y1": "330",
62 | "x2": "990"
63 | },
64 | {
65 | "x1": "870",
66 | "y1": "330",
67 | "x2": "900"
68 | },
69 | {
70 | "x1": "870",
71 | "y1": "300",
72 | "x2": "900"
73 | },
74 | {
75 | "x1": "1140",
76 | "y1": "300",
77 | "x2": "1170"
78 | },
79 | {
80 | "x1": "960",
81 | "y1": "300",
82 | "x2": "1080"
83 | },
84 | {
85 | "x1": "870",
86 | "y1": "360",
87 | "x2": "990"
88 | },
89 | {
90 | "x1": "1050",
91 | "y1": "360",
92 | "x2": "1170"
93 | }
94 | ],
95 | "conpoints": [],
96 | "diodes": [],
97 | "customs": [
98 | {
99 | "x": "900",
100 | "y": "270",
101 | "direction": "0",
102 | "filename": "\"half_add.json\"",
103 | "outputsInv": "[false,false]",
104 | "inputsInv": "[false,false]"
105 | },
106 | {
107 | "x": "990",
108 | "y": "300",
109 | "direction": "0",
110 | "filename": "\"half_add.json\"",
111 | "outputsInv": "[false,false]",
112 | "inputsInv": "[false,false]"
113 | }
114 | ],
115 | "labels": [],
116 | "segDisplays": []
117 | }
118 |
--------------------------------------------------------------------------------
/views/sketches/half_add.json:
--------------------------------------------------------------------------------
1 | {
2 | "caption": "HA",
3 | "gates": [
4 | {
5 | "x": "810",
6 | "y": "240",
7 | "direction": "0",
8 | "inputCount": "2",
9 | "outputCount": "1",
10 | "logicFunction": "\"and\"",
11 | "outputsInv": "[false]",
12 | "inputsInv": "[false,false]"
13 | },
14 | {
15 | "x": "810",
16 | "y": "300",
17 | "direction": "0",
18 | "inputCount": "2",
19 | "outputCount": "1",
20 | "logicFunction": "\"xor\"",
21 | "outputsInv": "[false]",
22 | "inputsInv": "[false,false]"
23 | }
24 | ],
25 | "outputs": [
26 | {
27 | "x": "930",
28 | "y": "270",
29 | "colr": "0",
30 | "lbl": "C"
31 | },
32 | {
33 | "x": "930",
34 | "y": "330",
35 | "colr": "0",
36 | "lbl": "S"
37 | }
38 | ],
39 | "inputs": [
40 | {
41 | "x": "705",
42 | "y": "255",
43 | "framecount": "0",
44 | "clock": "false",
45 | "lbl": "A"
46 | },
47 | {
48 | "x": "705",
49 | "y": "285",
50 | "framecount": "0",
51 | "clock": "false",
52 | "lbl": "B"
53 | }
54 | ],
55 | "segments": [],
56 | "wires": [
57 | {
58 | "x1": "780",
59 | "y1": "330",
60 | "x2": "810"
61 | },
62 | {
63 | "x1": "780",
64 | "y1": "270",
65 | "y2": "330"
66 | },
67 | {
68 | "x1": "750",
69 | "y1": "300",
70 | "y2": "360"
71 | },
72 | {
73 | "x1": "750",
74 | "y1": "360",
75 | "x2": "810"
76 | },
77 | {
78 | "x1": "870",
79 | "y1": "330",
80 | "x2": "930"
81 | },
82 | {
83 | "x1": "870",
84 | "y1": "270",
85 | "x2": "930"
86 | },
87 | {
88 | "x1": "720",
89 | "y1": "270",
90 | "x2": "810"
91 | },
92 | {
93 | "x1": "720",
94 | "y1": "300",
95 | "x2": "810"
96 | }
97 | ],
98 | "conpoints": [
99 | {
100 | "x": "780",
101 | "y": "270"
102 | },
103 | {
104 | "x": "750",
105 | "y": "300"
106 | }
107 | ],
108 | "diodes": [],
109 | "customs": [],
110 | "labels": [],
111 | "segDisplays": []
112 | }
113 |
--------------------------------------------------------------------------------
/views/sketches/inverter.json:
--------------------------------------------------------------------------------
1 | {
2 | "caption": "NOT",
3 | "gates": [
4 | {
5 | "x": "690",
6 | "y": "300",
7 | "direction": "0",
8 | "inputCount": "2",
9 | "outputCount": "1",
10 | "logicFunction": "\"and\"",
11 | "caption": "\"&\"",
12 | "outputsInv": "[true]",
13 | "inputsInv": "[false,false]"
14 | }
15 | ],
16 | "outputs": [
17 | {
18 | "x": "840",
19 | "y": "330",
20 | "colr": "0"
21 | }
22 | ],
23 | "inputs": [
24 | {
25 | "x": "525",
26 | "y": "315",
27 | "framecount": "-1",
28 | "clock": "false"
29 | }
30 | ],
31 | "segments": [],
32 | "wires": [
33 | {
34 | "x1": "630",
35 | "y1": "330",
36 | "x2": "630",
37 | "y2": "360"
38 | },
39 | {
40 | "x1": "630",
41 | "y1": "360",
42 | "x2": "690",
43 | "y2": "360"
44 | },
45 | {
46 | "x1": "750",
47 | "y1": "330",
48 | "x2": "840",
49 | "y2": "330"
50 | },
51 | {
52 | "x1": "540",
53 | "y1": "330",
54 | "x2": "690",
55 | "y2": "330"
56 | }
57 | ],
58 | "conpoints": [
59 | {
60 | "x": "630",
61 | "y": "330"
62 | }
63 | ],
64 | "diodes": [],
65 | "customs": []
66 | }
67 |
--------------------------------------------------------------------------------
/views/sketches/jk-flipflop.json:
--------------------------------------------------------------------------------
1 | {"caption":"JK-FF","gates":[{"x":"480","y":"180","direction":"0","inputCount":"3","outputCount":"1","logicFunction":"\"and\"","outputsInv":"[false]","inputsInv":"[false,false,false]"},{"x":"480","y":"300","direction":"0","inputCount":"3","outputCount":"1","logicFunction":"\"and\"","outputsInv":"[false]","inputsInv":"[false,false,false]"},{"x":"330","y":"270","direction":"0","inputCount":"2","outputCount":"1","logicFunction":"\"and\"","outputsInv":"[false]","inputsInv":"[true,false]"}],"outputs":[{"x":"930","y":"210","colr":"0","lbl":"Q"},{"x":"930","y":"330","colr":"0","lbl":"Q̅"}],"inputs":[{"x":"255","y":"195","lbl":"J","framecount":"-1","clock":"false"},{"x":"75","y":"285","lbl":">","framecount":"0","clock":"true","speed":"30"},{"x":"255","y":"375","lbl":"K","framecount":"-1","clock":"false"}],"wires":[{"x1":"780","y1":"330","x2":"930"},{"x1":"780","y1":"300","y2":"330"},{"x1":"810","y1":"210","x2":"930"},{"x1":"420","y1":"180","x2":"750"},{"x1":"540","y1":"210","x2":"570"},{"x1":"540","y1":"330","x2":"570"},{"x1":"570","y1":"300","y2":"330"},{"x1":"450","y1":"240","x2":"480"},{"x1":"450","y1":"240","y2":"330"},{"x1":"450","y1":"330","x2":"480"},{"x1":"270","y1":"390","x2":"480"},{"x1":"270","y1":"210","x2":"480"},{"x1":"450","y1":"420","x2":"810"},{"x1":"420","y1":"180","y2":"270"},{"x1":"810","y1":"210","y2":"420"},{"x1":"420","y1":"270","x2":"480"},{"x1":"450","y1":"360","y2":"420"},{"x1":"450","y1":"360","x2":"480"},{"x1":"570","y1":"270","x2":"660"},{"x1":"570","y1":"210","y2":"270"},{"x1":"570","y1":"300","x2":"660"},{"x1":"720","y1":"270","x2":"810"},{"x1":"720","y1":"300","x2":"780"},{"x1":"750","y1":"180","y2":"300"},{"x1":"210","y1":"300","x2":"240"},{"x1":"300","y1":"300","x2":"330"},{"x1":"120","y1":"330","x2":"330"},{"x1":"390","y1":"300","x2":"450"},{"x1":"120","y1":"300","y2":"330"},{"x1":"90","y1":"300","x2":"150"}],"conpoints":[{"x":"750","y":"300"},{"x":"810","y":"270"},{"x":"450","y":"300"},{"x":"120","y":"300"}],"diodes":[],"customs":[{"x":"660","y":"240","direction":"0","filename":"\"rs-flipflop.json\"","outputsInv":"[]","inputsInv":"[]"},{"x":"240","y":"270","direction":"0","filename":"\"1-buffer.json\"","outputsInv":"[]","inputsInv":"[]"},{"x":"150","y":"270","direction":"0","filename":"\"1-buffer.json\"","outputsInv":"[]","inputsInv":"[]"}],"labels":[{"x":"990","y":"210","txt":"Q"},{"x":"990","y":"330","txt":"not Q"},{"x":"180","y":"210","txt":"J"},{"x":"180","y":"390","txt":"K"},{"x":"0","y":"300","txt":"Clk"}],"segDisplays":[]}
--------------------------------------------------------------------------------
/views/sketches/not-gate.json:
--------------------------------------------------------------------------------
1 | {"caption":"NOT","gates":[{"x":"510","y":"150","direction":"0","inputCount":"2","outputCount":"1","logicFunction":"\"and\"","outputsInv":"[true]","inputsInv":"[false,false]"}],"outputs":[{"x":"660","y":"180","colr":"0","lbl":"1"}],"inputs":[{"x":"405","y":"165","framecount":"-1","clock":"false"}],"wires":[{"x1":"420","y1":"180","x2":"510"},{"x1":"450","y1":"210","x2":"510"},{"x1":"450","y1":"180","y2":"210"},{"x1":"570","y1":"180","x2":"660"}],"conpoints":[{"x":"450","y":"180"}],"diodes":[],"customs":[],"labels":[],"segDisplays":[]}
--------------------------------------------------------------------------------
/views/sketches/rs-clocked.json:
--------------------------------------------------------------------------------
1 | {"caption":"RS-FF","gates":[{"x":"510","y":"270","direction":"0","inputCount":"2","outputCount":"1","logicFunction":"\"and\"","outputsInv":"[false]","inputsInv":"[false,false]"},{"x":"510","y":"360","direction":"0","inputCount":"2","outputCount":"1","logicFunction":"\"and\"","outputsInv":"[false]","inputsInv":"[false,false]"}],"outputs":[{"x":"870","y":"330","colr":"0","lbl":"Q"},{"x":"870","y":"360","colr":"0","lbl":"Q̅"}],"inputs":[{"x":"375","y":"285","lbl":"S","framecount":"-1","clock":"false"},{"x":"375","y":"345","lbl":">","framecount":"0","clock":"true","speed":"30"},{"x":"375","y":"405","lbl":"R","framecount":"-1","clock":"false"}],"wires":[{"x1":"570","y1":"390","x2":"660"},{"x1":"660","y1":"360","y2":"390"},{"x1":"660","y1":"360","x2":"720"},{"x1":"660","y1":"330","x2":"720"},{"x1":"660","y1":"300","y2":"330"},{"x1":"570","y1":"300","x2":"660"},{"x1":"480","y1":"330","x2":"510"},{"x1":"480","y1":"330","y2":"390"},{"x1":"480","y1":"390","x2":"510"},{"x1":"390","y1":"360","x2":"480"},{"x1":"390","y1":"420","x2":"510"},{"x1":"390","y1":"300","x2":"510"},{"x1":"780","y1":"330","x2":"870"},{"x1":"780","y1":"360","x2":"870"}],"conpoints":[{"x":"480","y":"360"}],"diodes":[],"customs":[{"x":"720","y":"300","direction":"0","filename":"\"rs-flipflop.json\"","outputsInv":"[]","inputsInv":"[]"}],"labels":[{"x":"300","y":"300","txt":"R"},{"x":"300","y":"420","txt":"S"},{"x":"930","y":"330","txt":"Q"},{"x":"930","y":"360","txt":"not Q"}],"segDisplays":[]}
--------------------------------------------------------------------------------
/views/sketches/rs-flipflop.json:
--------------------------------------------------------------------------------
1 | {
2 | "caption": "RS-FF",
3 | "gates": [
4 | {
5 | "x": "300",
6 | "y": "210",
7 | "direction": "0",
8 | "inputCount": "3",
9 | "outputCount": "1",
10 | "logicFunction": "\"and\"",
11 | "outputsInv": "[true]",
12 | "inputsInv": "[false,true,false]"
13 | },
14 | {
15 | "x": "300",
16 | "y": "90",
17 | "direction": "0",
18 | "inputCount": "2",
19 | "outputCount": "1",
20 | "logicFunction": "\"and\"",
21 | "outputsInv": "[true]",
22 | "inputsInv": "[true,false]"
23 | },
24 | {
25 | "x": "210",
26 | "y": "270",
27 | "direction": "0",
28 | "inputCount": "1",
29 | "outputCount": "1",
30 | "logicFunction": "\"and\"",
31 | "outputsInv": "[false]",
32 | "inputsInv": "[false]"
33 | },
34 | {
35 | "x": "420",
36 | "y": "90",
37 | "direction": "0",
38 | "inputCount": "1",
39 | "outputCount": "1",
40 | "logicFunction": "\"and\"",
41 | "outputsInv": "[false]",
42 | "inputsInv": "[false]"
43 | },
44 | {
45 | "x": "510",
46 | "y": "90",
47 | "direction": "0",
48 | "inputCount": "2",
49 | "outputCount": "1",
50 | "logicFunction": "\"and\"",
51 | "outputsInv": "[false]",
52 | "inputsInv": "[false,false]"
53 | }
54 | ],
55 | "outputs": [
56 | {
57 | "x": "630",
58 | "y": "120",
59 | "colr": "0",
60 | "lbl": "Q"
61 | },
62 | {
63 | "x": "630",
64 | "y": "240",
65 | "colr": "0",
66 | "lbl": "Q̅"
67 | }
68 | ],
69 | "inputs": [
70 | {
71 | "x": "135",
72 | "y": "105",
73 | "lbl": "S",
74 | "framecount": "-1",
75 | "clock": "false"
76 | },
77 | {
78 | "x": "135",
79 | "y": "255",
80 | "lbl": "R",
81 | "framecount": "-1",
82 | "clock": "false"
83 | }
84 | ],
85 | "segments": [],
86 | "wires": [
87 | {
88 | "x1": "270",
89 | "y1": "300",
90 | "x2": "300"
91 | },
92 | {
93 | "x1": "270",
94 | "y1": "240",
95 | "x2": "300"
96 | },
97 | {
98 | "x1": "270",
99 | "y1": "210",
100 | "y2": "240"
101 | },
102 | {
103 | "x1": "180",
104 | "y1": "300",
105 | "x2": "210"
106 | },
107 | {
108 | "x1": "390",
109 | "y1": "120",
110 | "y2": "150"
111 | },
112 | {
113 | "x1": "480",
114 | "y1": "120",
115 | "x2": "510"
116 | },
117 | {
118 | "x1": "270",
119 | "y1": "150",
120 | "x2": "300"
121 | },
122 | {
123 | "x1": "270",
124 | "y1": "150",
125 | "y2": "180"
126 | },
127 | {
128 | "x1": "420",
129 | "y1": "150",
130 | "y2": "210"
131 | },
132 | {
133 | "x1": "360",
134 | "y1": "120",
135 | "x2": "420"
136 | },
137 | {
138 | "x1": "570",
139 | "y1": "120",
140 | "x2": "630"
141 | },
142 | {
143 | "x1": "480",
144 | "y1": "180",
145 | "y2": "240"
146 | },
147 | {
148 | "x1": "180",
149 | "y1": "210",
150 | "y2": "300"
151 | },
152 | {
153 | "x1": "390",
154 | "y1": "150",
155 | "x2": "510"
156 | },
157 | {
158 | "x1": "150",
159 | "y1": "270",
160 | "x2": "300"
161 | },
162 | {
163 | "x1": "180",
164 | "y1": "210",
165 | "x2": "420"
166 | },
167 | {
168 | "x1": "150",
169 | "y1": "120",
170 | "x2": "300"
171 | },
172 | {
173 | "x1": "270",
174 | "y1": "180",
175 | "x2": "480"
176 | },
177 | {
178 | "x1": "360",
179 | "y1": "240",
180 | "x2": "630"
181 | }
182 | ],
183 | "conpoints": [
184 | {
185 | "x": "270",
186 | "y": "210"
187 | },
188 | {
189 | "x": "390",
190 | "y": "120"
191 | },
192 | {
193 | "x": "420",
194 | "y": "150"
195 | },
196 | {
197 | "x": "480",
198 | "y": "240"
199 | }
200 | ],
201 | "diodes": [],
202 | "customs": [],
203 | "labels": [
204 | {
205 | "x": "60",
206 | "y": "60",
207 | "txt": "Asynchonous RS-Flipflop with no forbidden state"
208 | },
209 | {
210 | "x": "60",
211 | "y": "120",
212 | "txt": "S"
213 | },
214 | {
215 | "x": "60",
216 | "y": "270",
217 | "txt": "R"
218 | },
219 | {
220 | "x": "690",
221 | "y": "120",
222 | "txt": "Q"
223 | },
224 | {
225 | "x": "690",
226 | "y": "240",
227 | "txt": "not Q"
228 | }
229 | ],
230 | "segDisplays": []
231 | }
232 |
--------------------------------------------------------------------------------
/views/sketches/t-flipflop.json:
--------------------------------------------------------------------------------
1 | {"caption":"T-FF","gates":[{"x":"690","y":"180","direction":"0","inputCount":"2","outputCount":"1","logicFunction":"\"and\"","outputsInv":"[false]","inputsInv":"[false,false]"},{"x":"690","y":"300","direction":"0","inputCount":"2","outputCount":"1","logicFunction":"\"and\"","outputsInv":"[false]","inputsInv":"[false,false]"},{"x":"450","y":"240","direction":"0","inputCount":"2","outputCount":"1","logicFunction":"\"and\"","outputsInv":"[false]","inputsInv":"[true,false]"}],"outputs":[{"x":"1080","y":"240","colr":"0","lbl":"Q"},{"x":"1080","y":"270","colr":"0","lbl":"Q̅"}],"inputs":[{"x":"615","y":"225","lbl":"T","framecount":"-1","clock":"false"},{"x":"195","y":"255","lbl":">","framecount":"0","clock":"true","speed":"30"}],"wires":[{"x1":"240","y1":"270","y2":"300"},{"x1":"240","y1":"300","x2":"450"},{"x1":"210","y1":"270","x2":"270"},{"x1":"330","y1":"270","x2":"360"},{"x1":"420","y1":"270","x2":"450"},{"x1":"990","y1":"180","y2":"270"},{"x1":"960","y1":"240","y2":"390"},{"x1":"510","y1":"270","x2":"870"},{"x1":"630","y1":"240","x2":"690"},{"x1":"660","y1":"240","y2":"330"},{"x1":"660","y1":"330","x2":"690"},{"x1":"660","y1":"360","y2":"390"},{"x1":"660","y1":"360","x2":"690"},{"x1":"660","y1":"390","x2":"960"},{"x1":"930","y1":"270","x2":"1080"},{"x1":"660","y1":"210","x2":"690"},{"x1":"660","y1":"180","y2":"210"},{"x1":"660","y1":"180","x2":"990"},{"x1":"930","y1":"240","x2":"1080"},{"x1":"750","y1":"210","x2":"810"},{"x1":"810","y1":"210","y2":"240"},{"x1":"810","y1":"240","x2":"870"},{"x1":"810","y1":"300","x2":"870"},{"x1":"810","y1":"300","y2":"330"},{"x1":"750","y1":"330","x2":"810"}],"conpoints":[{"x":"960","y":"240"},{"x":"990","y":"270"},{"x":"660","y":"240"},{"x":"240","y":"270"}],"diodes":[],"customs":[{"x":"870","y":"210","direction":"0","filename":"\"rs-clocked.json\"","outputsInv":"[false,false]","inputsInv":"[]"},{"x":"360","y":"240","direction":"0","filename":"\"1-buffer.json\"","outputsInv":"[]","inputsInv":"[]"},{"x":"270","y":"240","direction":"0","filename":"\"1-buffer.json\"","outputsInv":"[]","inputsInv":"[]"}],"labels":[{"x":"540","y":"240","txt":"T"},{"x":"120","y":"270","txt":"Clk"}],"segDisplays":[]}
--------------------------------------------------------------------------------