kmap
Version:
Karnagh Map Editor
1,504 lines (1,219 loc) • 1.69 MB
JavaScript
(function webpackUniversalModuleDefinition(root, factory) {
if(typeof exports === 'object' && typeof module === 'object')
module.exports = factory();
else if(typeof define === 'function' && define.amd)
define([], factory);
else if(typeof exports === 'object')
exports["Kmap"] = factory();
else
root["Kmap"] = factory();
})(self, function() {
return /******/ (() => { // webpackBootstrap
/******/ var __webpack_modules__ = ({
/***/ "./index.js":
/*!******************!*\
!*** ./index.js ***!
\******************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (/* reexport safe */ _src_Kmap_Kmap__WEBPACK_IMPORTED_MODULE_3__.Kmap)
/* harmony export */ });
/* harmony import */ var _src_polyfills_all__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./src/polyfills/all */ "./src/polyfills/all.js");
/* harmony import */ var _src_kmap_scss__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./src/kmap.scss */ "./src/kmap.scss");
/* harmony import */ var _src_Kmap_Utility_Ready__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./src/Kmap/Utility/Ready */ "./src/Kmap/Utility/Ready.js");
/* harmony import */ var _src_Kmap_Kmap__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./src/Kmap/Kmap */ "./src/Kmap/Kmap.js");
// The public-path module must be imported first!
// import './src/public-path.js';
//
// Automatically install into div.kmap-cl-install, where the text
// contents of the tag are JSON to configure Kmap
_src_Kmap_Utility_Ready__WEBPACK_IMPORTED_MODULE_2__.Ready.go(function () {
var elements = document.querySelectorAll('div.kmap-cl-install');
for (var i = 0; i < elements.length; i++) {
var element = elements[i];
element.classList.remove('kmap-cl-install');
var json = element.textContent;
element.innerHTML = '';
var kmap = new _src_Kmap_Kmap__WEBPACK_IMPORTED_MODULE_3__.Kmap(element, json);
kmap.startNow();
element.style.display = 'block';
}
});
/***/ }),
/***/ "./src/Kmap/Generator.js":
/*!*******************************!*\
!*** ./src/Kmap/Generator.js ***!
\*******************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "Generator": () => (/* binding */ Generator)
/* harmony export */ });
/* harmony import */ var _Logic_Minterms__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Logic/Minterms */ "./src/Logic/Minterms.js");
/**
* This object manages the practice generator section.
* @param main
* @param element
* @constructor
*/
var Generator = function Generator(main, element) {
var _this = this;
var mintermsSpan;
var options = main.options;
var initialize = function initialize() {
var div = document.createElement('div');
div.classList.add('kmap-cl-generator');
element.appendChild(div); // Heading
var h3 = document.createElement('h3');
h3.innerText = options.fixed ? 'Minterms' : 'Minterm Generator';
div.appendChild(h3);
var form = document.createElement('form');
div.appendChild(form);
var p = document.createElement('p');
p.innerText = 'Size: ';
div.appendChild(p);
if (options.fixed) {
p.appendChild(document.createTextNode('' + options.size + ' Minterms: '));
} else {
//
// The size select control
//
var select = document.createElement('select');
p.appendChild(select);
var options1 = '';
var options2 = '';
for (var s = 2; s <= 4; s++) {
if (s === +main.options.size) {
if (main.options.genDontCare) {
options1 += '<option value="' + s + '">' + s + '</option>';
if (main.options.genDontCareOption) {
options2 += '<option value="' + s + 'd" selected>' + s + " w/don't cares</option>";
}
} else {
options1 += '<option value="' + s + '" selected>' + s + '</option>';
if (main.options.genDontCareOption) {
options2 += '<option value="' + s + 'd">' + s + " w/don't cares</option>";
}
}
} else {
options1 += '<option value="' + s + '">' + s + '</option>';
if (main.options.genDontCareOption) {
options2 += '<option value="' + s + 'd">' + s + " <span>w/don't cares</span></option>";
}
}
}
select.innerHTML = options1 + options2;
select.addEventListener('change', function (event) {
event.preventDefault();
var val = select.value;
var newSize = parseInt(val);
main.options.genDontCare = val.match(/d$/) !== null;
main.newSize(newSize);
}); //
// The Generate button
//
p.appendChild(document.createTextNode(' '));
var button = document.createElement('button');
button.innerText = 'Generate';
p.appendChild(button);
p.appendChild(document.createTextNode(' '));
button.addEventListener('click', function (event) {
event.preventDefault();
main.generate();
});
}
mintermsSpan = document.createElement('span');
p.appendChild(mintermsSpan);
_this.refresh();
};
this.refresh = function () {
if (main.minterms.dontcare.length > 0) {
mintermsSpan.innerHTML = main.minterms.list(true) + "<br>X=" + main.minterms.list_dontcare(true);
} else {
mintermsSpan.innerHTML = main.minterms.list(true);
}
};
initialize();
};
/***/ }),
/***/ "./src/Kmap/Group.js":
/*!***************************!*\
!*** ./src/Kmap/Group.js ***!
\***************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "Group": () => (/* binding */ Group)
/* harmony export */ });
/**
* A single group
* @param groups Kmap.Group object
* @param list List to add this item to
* @param selected Minterms that are selected
* @param color Color to draw item
* @constructor
*/
var Group = function Group(groups, list, selected, color) {
var _this = this;
this.groups = groups;
this.selected = selected;
this.color = color;
if (list === null) {
return;
}
var lst = '';
var first = true;
for (var i = 0; i < selected.length; i++) {
if (!first) {
lst += ',';
} else {
first = false;
}
if (i === 8) {
lst += '<br/>';
}
lst += selected[i];
} // var div = $('<div class="group">' + lst + '</div>');
var div = document.createElement('div');
div.classList.add('group');
div.innerHTML = lst; // var span = $('<span></span>');
// div.append(span);
var span = document.createElement('span');
div.appendChild(span); // var a = $('<a href="javascript:;"></a>');
// span.append(a);
var a = document.createElement('a');
span.appendChild(a);
list.appendChild(div);
a.addEventListener('click', function (event) {
event.preventDefault();
list.removeChild(div);
groups.remove(_this);
});
div.style.backgroundColor = color; // div.css("background-color", color);
};
Group.prototype.draw = function (ctx, wid, hit, insetDepth) {
var inset = 15;
var spacing = 10;
var cols, rows, mapR, mapC, max;
switch (this.groups.main.options.size) {
case 2:
cols = 2;
rows = 2;
mapR = [0, 1, 0, 1];
mapC = [0, 0, 1, 1];
max = 4;
break;
case 3:
cols = 4;
rows = 2;
mapR = [0, 1, 0, 1, 0, 1, 0, 1];
mapC = [0, 0, 1, 1, 3, 3, 2, 2];
max = 8;
break;
case 4:
cols = 4;
rows = 4;
mapR = [0, 1, 3, 2, 0, 1, 3, 2, 0, 1, 3, 2, 0, 1, 3, 2];
mapC = [0, 0, 0, 0, 1, 1, 1, 1, 3, 3, 3, 3, 2, 2, 2, 2];
max = 16;
break;
}
var cnt = this.selected.length;
if (cnt === max) {
// We are wrapping the whole thing
this.drawGroup(ctx, 0, 0, wid, hit, inset + spacing * insetDepth);
return;
}
if (cnt === 1) {
var c1 = mapC[this.selected[0]];
var r1 = mapR[this.selected[0]];
this.drawGroup(ctx, c1 * wid / cols, r1 * hit / rows, wid / cols, hit / rows, inset + spacing * insetDepth);
} else if (cnt == 2) {
var c1 = mapC[this.selected[0]];
var r1 = mapR[this.selected[0]];
var c2 = mapC[this.selected[1]];
var r2 = mapR[this.selected[1]];
if (r1 == r2) {
// Horizontal
if (c2 < c1) {
var t = c1;
c1 = c2;
c2 = t;
}
if (c2 - c1 > 1) {
// Not adjacent!
this.drawGroup(ctx, c2 * wid / cols, r1 * hit / rows, wid * 2 / cols, hit / rows, inset + spacing * insetDepth);
this.drawGroup(ctx, (c1 - 1) * wid / cols, r1 * hit / rows, wid * 2 / cols, hit / rows, inset + spacing * insetDepth);
} else {
this.drawGroup(ctx, c1 * wid / cols, r1 * hit / rows, wid * 2 / cols, hit / rows, inset + spacing * insetDepth);
}
} else {
// Vertical
if (r2 < r1) {
var t = r1;
r1 = r2;
r2 = t;
}
if (r2 - r1 > 1) {
// Not adjacent
this.drawGroup(ctx, c1 * wid / cols, r2 * hit / rows, wid / cols, hit * 2 / rows, inset + spacing * insetDepth);
this.drawGroup(ctx, c1 * wid / cols, (r1 - 1) * hit / rows, wid / cols, hit * 2 / rows, inset + spacing * insetDepth);
} else {
this.drawGroup(ctx, c1 * wid / cols, r1 * hit / rows, wid / cols, hit * 2 / rows, inset + spacing * insetDepth);
}
}
} else if (cnt == 4) {
var c1 = mapC[this.selected[0]];
var r1 = mapR[this.selected[0]];
var c2 = mapC[this.selected[1]];
var r2 = mapR[this.selected[1]];
var c3 = mapC[this.selected[2]];
var r3 = mapR[this.selected[2]];
var c4 = mapC[this.selected[3]];
var r4 = mapR[this.selected[3]]; // Are all in same row?
if (r1 == r2 && r2 == r3 && r3 == r4) {
// Size 4 cover in the same row
this.drawGroup(ctx, c1 * wid / cols, r1 * hit / rows, wid * 4 / cols, hit / rows, inset + spacing * insetDepth);
} else if (c1 == c2 && c2 == c3 && c3 == c4) {
// Size 4 cover in the same column
this.drawGroup(ctx, c1 * wid / cols, r1 * hit / rows, wid / cols, hit * 4 / rows, inset + spacing * insetDepth);
} else {
// This must be square
var wid4 = wid * 2 / cols;
var hit4 = hit * 2 / rows;
if (c1 == 0 && c2 == 0 && c3 == 3 && c4 == 3) {
// This is a left/right side split
if (r1 == 0 && r2 == 3 && r3 == 0 && r4 == 3) {
// Four corner split
this.drawGroup(ctx, -1 * wid / cols, -1 * hit / rows, wid4, hit4, inset + spacing * insetDepth);
this.drawGroup(ctx, -1 * wid / cols, 3 * hit / rows, wid4, hit4, inset + spacing * insetDepth);
this.drawGroup(ctx, 3 * wid / cols, -1 * hit / rows, wid4, hit4, inset + spacing * insetDepth);
this.drawGroup(ctx, 3 * wid / cols, 3 * hit / rows, wid4, hit4, inset + spacing * insetDepth);
} else {
if (r1 > r2) {
var t = r1;
r1 = r2;
r2 = t;
}
this.drawGroup(ctx, -1 * wid / cols, r1 * hit / rows, wid4, hit4, inset + spacing * insetDepth);
this.drawGroup(ctx, 3 * wid / cols, r1 * hit / rows, wid4, hit4, inset + spacing * insetDepth);
}
} else if (r1 == 0 && r2 == 3) {
if (c1 > c3) {
var t = c1;
c1 = c3;
c3 = t;
} // This is a top-bottom split
this.drawGroup(ctx, c1 * wid / cols, -1 * hit / rows, wid4, hit4, inset + spacing * insetDepth);
this.drawGroup(ctx, c1 * wid / cols, 3 * hit / rows, wid4, hit4, inset + spacing * insetDepth);
} else {
// Simple square!
if (c1 > c3) {
var t = c1;
c1 = c3;
c3 = t;
}
if (r1 > r2) {
var t = r1;
r1 = r2;
r2 = t;
}
this.drawGroup(ctx, c1 * wid / cols, r1 * hit / rows, wid4, hit4, inset + spacing * insetDepth);
}
}
} else if (cnt == 8) {
var c1 = mapC[this.selected[0]];
var r1 = mapR[this.selected[0]];
var c2 = mapC[this.selected[1]];
var r2 = mapR[this.selected[1]];
var c3 = mapC[this.selected[2]];
var r3 = mapR[this.selected[2]];
var c4 = mapC[this.selected[3]];
var r4 = mapR[this.selected[3]];
var c5 = mapC[this.selected[4]];
var r5 = mapR[this.selected[4]];
if (c1 == c2 && c2 == c3 && c3 == c4) {
var wid8 = wid * 2 / cols;
var hit8 = hit * 4 / rows; // Vertical layout
if (c1 == 0 && c5 == 3) {
// Left/right split
this.drawGroup(ctx, -1 * wid / cols, 0 * hit / rows, wid8, hit8, inset + spacing * insetDepth);
this.drawGroup(ctx, 3 * wid / cols, 0 * hit / rows, wid8, hit8, inset + spacing * insetDepth);
} else {
if (c1 > c5) {
c1 = c5;
}
this.drawGroup(ctx, c1 * wid / cols, 0 * hit / rows, wid8, hit8, inset + spacing * insetDepth);
}
} else {
//Horizontal layout
var wid8 = wid * 4 / cols;
var hit8 = hit * 2 / rows;
if (r2 - r1 > 1) {
// Split
this.drawGroup(ctx, 0 * wid / cols, -1 * hit / rows, wid8, hit8, inset + spacing * insetDepth);
this.drawGroup(ctx, 0 * wid / cols, 3 * hit / rows, wid8, hit8, inset + spacing * insetDepth);
} else {
if (r1 > r2) {
r1 = r2;
}
this.drawGroup(ctx, 0 * wid / cols, r1 * hit / rows, wid8, hit8, inset + spacing * insetDepth);
}
}
}
};
Group.prototype.drawGroup = function (ctx, x1, y1, wid, hit, inset) {
var x = x1 + inset;
var y = y1 + inset;
var width = wid - inset * 2 - 1;
var height = hit - inset * 2 - 1;
var radius = 30;
ctx.lineWidth = 7;
ctx.strokeStyle = this.color;
ctx.beginPath();
ctx.moveTo(x, y + radius);
ctx.lineTo(x, y + height - radius);
ctx.arcTo(x, y + height, x + radius, y + height, radius);
ctx.lineTo(x + width - radius, y + height);
ctx.arcTo(x + width, y + height, x + width, y + height - radius, radius);
ctx.lineTo(x + width, y + radius);
ctx.arcTo(x + width, y, x + width - radius, y, radius);
ctx.lineTo(x + radius, y);
ctx.arcTo(x, y, x, y + radius, radius);
ctx.stroke();
};
/***/ }),
/***/ "./src/Kmap/Groups.js":
/*!****************************!*\
!*** ./src/Kmap/Groups.js ***!
\****************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "Groups": () => (/* binding */ Groups)
/* harmony export */ });
/* harmony import */ var _MessageDialog__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./MessageDialog */ "./src/Kmap/MessageDialog.js");
/* harmony import */ var _Group__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./Group */ "./src/Kmap/Group.js");
/**
* The groups area of the editor
*/
var Groups = function Groups(main, sel) {
var _this = this;
var that = this;
this.main = main;
var list;
var initialize = function initialize() {
var button = document.createElement('button');
sel.appendChild(button);
button.innerText = 'Cover';
list = document.createElement('div');
list.classList.add('list');
sel.appendChild(list);
_this.groups = [];
_this.colorN = 0;
button.addEventListener('click', function (event) {
event.preventDefault();
var selected = main.work.map.selected;
if (main.options.strict) {
// Determine how many common bits there are
var and1 = Math.pow(2, main.options.size) - 1;
var and2 = and1;
for (var i = 0; i < selected.length; i++) {
var _sel = selected[i];
and1 &= _sel;
and2 &= ~_sel;
}
var or = and1 | and2;
var bits = 0;
var size = main.options.size;
for (var _i = 0; _i < size; _i++) {
if ((or & 1) === 1) {
bits++;
}
or >>= 1;
} // Test for valid
var valid = true;
switch (selected.length) {
case 1:
break;
case 2:
valid = bits == size - 1;
break;
case 4:
valid = bits == size - 2;
break;
case 8:
valid = bits == size - 3;
break;
case 16:
break;
default:
var html = '<p>Grouping must be of some power of two minterms.</p><p>The only ' + 'groupings possible are 1, 2, 4, 8, or 16, depending on the size of the ' + 'Karnaugh map.</p>';
var dlg = new _MessageDialog__WEBPACK_IMPORTED_MODULE_0__.MessageDialog(main, "You can't do that", html);
dlg.open();
return;
}
if (!valid) {
var _html = '<p>Your minterm grouping is invalid.</p><p>Groupings must be such ' + 'that there are bits in common. This means the groupings must be a rectangle ' + 'on the Karnaugh map. This can be a 1 by 4 rectangle or a 2 by 2 rectangle for ' + 'a grouping of 4, for example. Note that the map does <em>wrap around</em> at' + ' the edges, so the right side is adjacent to the left side, for example.</p>';
var _dlg = new _MessageDialog__WEBPACK_IMPORTED_MODULE_0__.MessageDialog(main, "You can't do that", _html);
_dlg.open();
return;
} //
// Ensure this group does not already exist
//
for (var _i2 = 0; _i2 < that.groups.length && valid; _i2++) {
if (that.groups[_i2].selected.length === selected.length) {
var ok = false;
for (var j = 0; j < that.groups[_i2].selected.length; j++) {
if (that.groups[_i2].selected[j] !== selected[j]) {
ok = true;
break;
}
}
if (!ok) {
valid = false;
var _html2 = '<p>This cover already exists.</p>';
var _dlg2 = new _MessageDialog__WEBPACK_IMPORTED_MODULE_0__.MessageDialog(main, "You can't do that", _html2);
_dlg2.open();
return;
}
}
}
}
_this.add_group(selected);
_this.drawGroups();
main.work.map.clear();
});
};
/**
* Add a new group (cover)
* @param minterms Array of minterms in the group
*/
this.add_group = function (minterms) {
var group = new _Group__WEBPACK_IMPORTED_MODULE_1__.Group(this, list, minterms, this.colors[this.colorN]);
this.colorN = (this.colorN + 1) % this.colors.length;
this.groups.push(group);
};
/**
* Draw all of the groups on the canvas
*/
this.drawGroups = function () {
var canvas = main.work.map.get_canvas();
var ctx = canvas.getContext("2d");
var wid = canvas.width;
var hit = canvas.height;
ctx.clearRect(0, 0, wid, hit);
var size = main.options.size;
var counter = [];
for (var i = 0; i < Math.pow(2, size); i++) {
counter.push(0);
}
for (var i = 0; i < this.groups.length; i++) {
var group = this.groups[i];
var max = 1;
for (var j = 0; j < group.selected.length; j++) {
counter[group.selected[j]]++;
if (counter[group.selected[j]] > max) {
max = counter[group.selected[j]];
}
}
group.draw(ctx, wid, hit, max);
}
};
this.clear = function () {
list.innerHTML = '';
this.colorN = 0;
this.groups = [];
this.drawGroups();
};
this.remove = function (group) {
for (var i = 0; i < this.groups.length; i++) {
if (this.groups[i] === group) {
this.groups.splice(i, 1);
}
}
this.drawGroups();
};
initialize();
/*
'<button>Group</button>' +
' <div class="list">' +
' <div class="group">' +
' 0,1,2,3,4,5,6,7,8, 9,10,11,12,13,14,15' +
' <span><a href="javascript:;"></a><img src="images/x.png"></a></span>' +
' </div>' +
' <div class="group">' +
' 0,1,2,3,4,5,6,7,8, 9,10,11,12,13,14,15' +
' <span><a href="javascript:;"></a><img src="images/x.png"></a></span>' +
' </div>' +
' <div class="group">' +
' 0,1,2,3,4,5,6,7,8, 9,10,11,12,13,14,15' +
' <span><a href="javascript:;"></a><img src="images/x.png"></a></span>' +
' </div>' +
' <div class="group">' +
' 0,1,2,3,4,5,6,7,8, 9,10,11,12,13,14,15' +
' <span><a href="javascript:;"></a><img src="images/x.png"></a></span> ' +
' </div>' +
' <div class="group">' +
' 0,1,2,3,4,5,6,7,8, 9,10,11,12,13,14,15' +
' <span><a href="javascript:;"></a><img src="images/x.png"></a></span>' +
' </div>' +
' </div>' +
*/
};
Groups.prototype.colors = ["#0000FF", "#808088", "#FF8800", "#008080", "#BDB76B", "#800000", "#00FF88", "#778899", "#FFA500", "#9ACD32", "#4682B4"];
/***/ }),
/***/ "./src/Kmap/Kmap.js":
/*!**************************!*\
!*** ./src/Kmap/Kmap.js ***!
\**************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "Kmap": () => (/* binding */ Kmap)
/* harmony export */ });
/* harmony import */ var _Options__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Options */ "./src/Kmap/Options.js");
/* harmony import */ var _Utility_Ready__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./Utility/Ready */ "./src/Kmap/Utility/Ready.js");
/* harmony import */ var _Main__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./Main */ "./src/Kmap/Main.js");
/**
* Create an instance of Kmap Karnaugh Map.
* @constructor
*/
var Kmap = function Kmap(sel, options) {
var _this = this;
//
// Master set of the version
//
var PACKAGE = __webpack_require__(/*! ../../package.json */ "./package.json");
this.version = PACKAGE.version; // The Options object that manages user options
this.options = new _Options__WEBPACK_IMPORTED_MODULE_0__.Options(options); // A collection of Main objects.
var mains = [];
this.start = function () {
_Utility_Ready__WEBPACK_IMPORTED_MODULE_1__.Ready.go(function () {
_this.startNow();
});
};
/**
* Start Kmap running now. Does not wait for document ready.
*/
this.startNow = function () {
if (sel instanceof Element) {
var main = new _Main__WEBPACK_IMPORTED_MODULE_2__.Main(_this, sel);
mains.push(main);
} else {
var elements = document.querySelectorAll(sel);
for (var i = 0; i < elements.length; i++) {
var element = elements[i];
var _main = new _Main__WEBPACK_IMPORTED_MODULE_2__.Main(_this, element);
mains.push(_main);
}
}
if (mains.length === 1) {
return mains[0];
}
return null;
};
};
/***/ }),
/***/ "./src/Kmap/Main.js":
/*!**************************!*\
!*** ./src/Kmap/Main.js ***!
\**************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "Main": () => (/* binding */ Main)
/* harmony export */ });
/* harmony import */ var _Work__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Work */ "./src/Kmap/Work.js");
/* harmony import */ var _Generator__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./Generator */ "./src/Kmap/Generator.js");
/* harmony import */ var _Solution__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./Solution */ "./src/Kmap/Solution.js");
/* harmony import */ var _Manual__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./Manual */ "./src/Kmap/Manual.js");
/* harmony import */ var _Logic_Minterms__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../Logic/Minterms */ "./src/Logic/Minterms.js");
/**
* Main window management object
* @param kmap Kmap object (parent)
* @param element The DOM element to use
* @constructor
*/
var Main = function Main(kmap, element) {
var _this = this;
this.options = kmap.options;
this.element = element; // Ensure empty and add the kmap-cl class
element.innerHTML = '';
element.classList.add('kmap-cl'); // The current minterms
this.minterms = new _Logic_Minterms__WEBPACK_IMPORTED_MODULE_4__.Minterms();
this.work = null;
this.generator = null;
this.solution = null;
this.manual = null;
this.initialize = function () {
if (_this.options.generator) {
_this.generator = new _Generator__WEBPACK_IMPORTED_MODULE_1__.Generator(_this, element);
}
if (_this.options.manual) {
_this.manual = new _Manual__WEBPACK_IMPORTED_MODULE_3__.Manual(_this, element);
}
if (_this.options.map) {
_this.work = new _Work__WEBPACK_IMPORTED_MODULE_0__.Work(_this, element);
}
_this.solution = new _Solution__WEBPACK_IMPORTED_MODULE_2__.Solution(_this, element); // Generate initial minterms
if (_this.options.minterms.length === 0) {
_this.generate();
} else {
_this.set(_this.options.minterms, _this.options.dontcare);
}
if (_this.options.solved) {
_this.solution.solve();
}
};
/**
* Generate a new set of minterms with optional don't cares
*/
this.generate = function () {
this.minterms.size = this.options.size;
if (this.options.genDontCare) {
var dcMax = 8;
switch (this.options.size) {
case 2:
dcMax = 2;
break;
case 3:
dcMax = 4;
break;
}
this.minterms.generate_bounded(0.5, 1, Math.pow(2, this.options.size) - 1, 0.2, 1, dcMax);
newMinterms();
} else {
this.minterms.generate_bounded(0.5, 1, Math.pow(2, this.options.size) - 1);
newMinterms();
}
};
this.set = function (minterms, dontcare) {
this.minterms.set_from(minterms, dontcare);
newMinterms();
};
var newMinterms = function newMinterms() {
if (_this.solution !== null) {
_this.solution.clear();
}
_this.options.minterms = _this.minterms.minterms.slice();
_this.options.dontcare = _this.minterms.dontcare.slice();
if (_this.work !== null) {
_this.work.render();
}
if (_this.generator !== null) {
_this.generator.refresh();
}
};
this.newSize = function (size) {
this.options.size = size;
this.generate();
};
this.initialize();
};
/***/ }),
/***/ "./src/Kmap/Manual.js":
/*!****************************!*\
!*** ./src/Kmap/Manual.js ***!
\****************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "Manual": () => (/* binding */ Manual)
/* harmony export */ });
/**
* Manual entry of minterms and don't cares support
* @param main Main object
* @param element Element we are adding this component to
* @constructor
*/
var Manual = function Manual(main, element) {
var that = this;
var labels = main.options.labels;
var manualMinterms, manualDontCares, manualVariables;
var initialize = function initialize() {
var div = document.createElement('div');
div.classList.add('kmap-cl-manual');
element.appendChild(div);
var h3 = document.createElement('h3');
h3.innerHTML = 'Manual Entry';
div.appendChild(h3); // var form = '<form><div class="left">' +
// '<p><label for="manual-minterms">Minterms: </label><br><input type="text" id="manual-minterms" spellcheck="false"></p>' +
// '<p><label for="manual-dontcares">Don\'t cares: </label><br><input type="text" id="manual-dontcares" spellcheck="false"></p>' +
// '<p><button>Take</button></p>' +
// '</div><div class="right">' +
// '<p><label for="manual-variables">Labels: </label><br><input type="text" id="manual-variables" value="' +
// labels + '" spellcheck="false"></p>' +
// '</div></form>';
var form = document.createElement('form');
div.appendChild(form); //
// Left div
//
var left = document.createElement('div');
form.appendChild(left); // <p><label for="manual-minterms">Minterms: </label><br><input type="text" id="manual-minterms" spellcheck="false"></p>
var p = document.createElement('p');
left.appendChild(p);
var label = document.createElement('label');
p.appendChild(label);
label.innerText = 'Minterms: ';
label.appendChild(document.createElement('br'));
manualMinterms = document.createElement('input');
manualMinterms.setAttribute('type', 'text');
manualMinterms.setAttribute('spellcheck', 'false');
label.appendChild(manualMinterms); // <p><label for="manual-dontcares">Don\'t cares: </label><br><input type="text" id="manual-dontcares" spellcheck="false"></p>
p = document.createElement('p');
left.appendChild(p);
label = document.createElement('label');
p.appendChild(label);
label.innerText = 'Don\'t cares: ';
label.appendChild(document.createElement('br'));
manualDontCares = document.createElement('input');
manualDontCares.setAttribute('type', 'text');
manualDontCares.setAttribute('spellcheck', 'false');
label.appendChild(manualDontCares); // <p><button>Take</button></p>
p = document.createElement('p');
left.appendChild(p);
var take = document.createElement('button');
p.appendChild(take);
take.innerText = 'Take'; //
// Right div
//
var right = document.createElement('div');
form.appendChild(right); // <p><label for="manual-variables">Labels: </label><br><input type="text" id="manual-variables" value="' +
// labels + '" spellcheck="false"></p>
p = document.createElement('p');
right.appendChild(p);
label = document.createElement('label');
p.appendChild(label);
label.innerText = 'Labels: ';
label.appendChild(document.createElement('br'));
manualVariables = document.createElement('input');
manualVariables.setAttribute('type', 'text');
manualVariables.setAttribute('spellcheck', 'false');
label.appendChild(manualVariables);
manualVariables.value = labels;
take.addEventListener('click', function (event) {
event.preventDefault();
var mintermslist = parse(manualMinterms.value);
var dontcarelist = parse(manualDontCares.value); // Get the labels, stripping any HTML tags just in case
var labels = manualVariables.value.replace(/(<([^>]+)>)/ig, "");
main.options.labels = labels.split(",");
main.set(mintermslist, dontcarelist);
});
};
function parse(input) {
var reM = /m/g;
var re = /[, ]+/g;
var items = input.replace(reM, '').split(re);
var ret = [];
items.forEach(function (item) {
if (item !== "") {
ret.push(parseInt(item));
}
});
return ret;
}
initialize();
};
/***/ }),
/***/ "./src/Kmap/Map.js":
/*!*************************!*\
!*** ./src/Kmap/Map.js ***!
\*************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "Map": () => (/* binding */ Map)
/* harmony export */ });
/* harmony import */ var _MessageDialog__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./MessageDialog */ "./src/Kmap/MessageDialog.js");
function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it["return"] != null) it["return"](); } finally { if (didErr) throw err; } } }; }
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
/**
* The actual Karnaugh Map
* @param main
* @param element
* @constructor
*/
var Map = function Map(main, element) {
var _this = this;
this.main = main;
this.element = element;
this.selected = [];
var topLeft, botRight, canvas;
var initialize = function initialize() {
var table = document.createElement('table');
table.classList.add('kmap-cl');
element.appendChild(table); // Make a local copy of the labels, converting
// _1 to <sub>1</sub>
var labels = [];
var _iterator = _createForOfIteratorHelper(main.options.labels),
_step;
try {
for (_iterator.s(); !(_step = _iterator.n()).done;) {
var label = _step.value;
labels.push(label.replace(/_([a-zA-Z0-9])*/g, '<sub>$1</sub>'));
}
} catch (err) {
_iterator.e(err);
} finally {
_iterator.f();
}
var left, right, rest, colheads;
if (+main.options.size === 2) {
var A = labels[0];
var B = labels[1];
left = B;
right = A;
rest = "<th>" + A + "'</th><th>" + A + "</th>";
colheads = [B + "'", B];
} else if (+main.options.size === 3) {
var _A = labels[0];
var _B = labels[1];
var C = labels[2];
left = C;
right = _A + _B;
rest = "<th>" + _A + "'" + _B + "'</th><th>" + _A + "'" + _B + "</th><th>" + _A + _B + "</th><th>" + _A + _B + "'</th>";
colheads = [C + "'", C];
} else {
var _A2 = labels[0];
var _B2 = labels[1];
var _C = labels[2];
var D = labels[3];
left = _C + D;
right = _A2 + _B2;
rest = "<th>" + _A2 + "'" + _B2 + "'</th><th>" + _A2 + "'" + _B2 + "</th><th>" + _A2 + _B2 + "</th><th>" + _A2 + _B2 + "'</th>";
colheads = [_C + "'" + D + "'", _C + "'" + D, _C + D, _C + D + "'"];
}
/*
* Top row first
*/
var tr = document.createElement('tr');
tr.innerHTML = '<th><div class="kmap-cl-left">' + left + '</div><div class="kmap-cl-line"></div><div class="kmap-cl-right">' + right + '</div></th>' + rest;
table.appendChild(tr);
/*
* Rest of the table
*/
var rows = +main.options.size === 4 ? 4 : 2;
var cols = +main.options.size === 2 ? 2 : 4;
for (var r = 1; r <= rows; r++) {
tr = document.createElement('tr');
tr.innerHTML = '<th>' + colheads[r - 1] + '</th>';
for (var c = 1; c <= cols; c++) {
var td = make_cell(c, r);
tr.appendChild(td);
if (r === 1 && c === 1) {
topLeft = td;
} else if (r === rows && c === cols) {
botRight = td;
}
}
table.appendChild(tr);
}
canvas = document.createElement('canvas');
canvas.setAttribute('width', '1000');
canvas.setAttribute('height', '1000');
_this.canvas = canvas;
element.appendChild(canvas);
setTimeout(function () {
set_canvas();
}, 0);
window.addEventListener('resize', set_canvas);
};
this.get_canvas = function () {
return this.canvas;
};
this.destroy = function () {
window.removeEventListener('resize', set_canvas);
};
function set_canvas() {
var tl = {
left: topLeft.offsetLeft,
top: topLeft.offsetTop
};
var br = {
left: botRight.offsetLeft,
top: botRight.offsetTop
};
canvas.style.top = tl.top + 'px';
canvas.style.left = tl.left + 'px';
canvas.style.width = br.left - tl.left + botRight.offsetWidth + 'px';
canvas.style.height = br.top - tl.top + botRight.offsetHeight + 'px';
}
var make_cell = function make_cell(c, r) {
var td = document.createElement('td');
var minterm = to_minterm(c, r);
var bit = '0';
for (var i = 0; i < main.options.minterms.length; i++) {
if (minterm === +main.options.minterms[i]) {
bit = '1';
break;
}
}
for (i = 0; i < main.options.dontcare.length; i++) {
if (minterm === +main.options.dontcare[i]) {
bit = 'X';
break;
}
}
if (main.options.labelMinterms) {
td.innerHTML = '<span class="minterm">m' + minterm + '</span>' + bit;
} else {
td.innerHTML = bit;
}
td.addEventListener('click', function (event) {
event.preventDefault();
if (_this.main.options.strict && bit === '0') {
var html = '<p>You are only allowed to select cells that are either true ' + 'or set to don\'t care.</p><p>We are grouping minterms that all are true ' + 'so we can minimize the circuit. So, only true cells can be grouped.</p>';
var dlg = new _MessageDialog__WEBPACK_IMPORTED_MODULE_0__.MessageDialog(main, "You can't do that", html);
dlg.open();
return;
}
if (td.classList.contains("kmap-cl-selected")) {
td.classList.remove("kmap-cl-selected");
var n = _this.selected.indexOf(minterm);
if (n > -1) {
_this.selected.splice(n, 1);
}
} else {
td.classList.add("kmap-cl-selected");
if (!is_selected(minterm)) {
_this.selected.push(minterm);
_this.selected.sort(function (a, b) {
return a - b;
});
}
}
});
return td;
};
var to_minterm = function to_minterm(c, r) {
var map;
if (+_this.main.options.size === 2) {
map = [[0, 2], [1, 3]];
} else if (+_this.main.options.size === 3) {
map = [[0, 2, 6, 4], [1, 3, 7, 5]];
} else {
map = [[0, 4, 12, 8], [1, 5, 13, 9], [3, 7, 15, 11], [2, 6, 14, 10]];
}
return map[r - 1][c - 1];
};
var is_selected = function is_selected(minterm) {
return _this.selected.indexOf(minterm) > -1; //
};
this.clear = function () {
this.selected = [];
var tds = this.element.querySelectorAll('td');
var _iterator2 = _createForOfIteratorHelper(tds),
_step2;
try {
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
var td = _step2.value;
td.classList.remove('kmap-cl-selected');
}
} catch (err) {
_iterator2.e(err);
} finally {
_iterator2.f();
}
};
initialize();
};
/***/ }),
/***/ "./src/Kmap/MessageDialog.js":
/*!***********************************!*\
!*** ./src/Kmap/MessageDialog.js ***!
\***********************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "MessageDialog": () => (/* binding */ MessageDialog)
/* harmony export */ });
/**
* The standard Message dialog box.
*
* Pretty minimalist dialog box
*
* @param main The Main object
* @param title Title for the dialog box
* @param body Body HTML to put in the dialog box
* @constructor
*/
var MessageDialog = function MessageDialog(main, title, body) {
var div = null;
this.open = function () {
// The top level dialog element
div = document.createElement('div');
div.classList.add('kmap-cl-dlg');
main.element.appendChild(div); // The mask
var mask = document.createElement('div');
div.appendChild(mask); // The dialog box itself
var dlg = document.createElement('div');
div.appendChild(dlg); // Title bar
var tb = document.createElement('div');
dlg.appendChild(tb);
tb.innerText = title; // Body
var db = document.createElement('div');
dlg.appendChild(db);
db.innerHTML = body; // Controls
var controls = document.createElement('div');
dlg.appendChild(controls);
var ok = document.createElement('button');
controls.appendChild(ok);
ok.innerText = 'Ok';
ok.addEventListener('click', function (event) {
event.preventDefault();
if (div !== null) {
main.element.removeChild(div);
div = null;
}
});
};
};
/***/ }),
/***/ "./src/Kmap/Options.js":
/*!*****************************!*\
!*** ./src/Kmap/Options.js ***!
\*****************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "Options": () => (/* binding */ Options)
/* harmony export */ });
/**
* User interface options.
*
* Options can be passed as a Javascript Object, JSON, or base64-encoded JSON
*
* @param options User provided options that override the default values.
* @constructor
*/
var Options = function Options(options) {
options = options ? options : {};
if (options !== Object(options)) {
if (options.substr(0, 1) === '{') {
options = JSON.parse(options);
} else {
// Not JSON, must be base64 encoded
options = JSON.parse(atob(options));
}
} /// The input size: 2, 3, or 4
this.size = 4; /// The minterms. Set to integers starting at 0
this.minterms = []; // [1, 2, 7, 8, 9, 14];
/// The don't care minterms
this.dontcare = []; /// Labels for the variables.
this.labels = ['A', 'B', 'C', 'D']; /// Generate don't care maps
this.genDontCare = false; /// Are don't cares an option for the generator?
this.genDontCareOption = true; //
// User interface sections
//
/// Include the generator?
this.generator = true; /// Include the manual data entry section?
this.manual = false; /// Include the map?
this.map = true; /// Include the solution section?
this.solution = true; /// Include the To PNG button
this.toPNG = false; /// If set true, practice generate features are disabled
this.fixed = false; /// Verbose answers on mistakes
this.verbose = true; /// If true, the minterm name appears in each cell.
this.labelMinterms = true; /// If set true, user input is checked for selecting invalid cells
/// such as zeros.
this.strict = true; /// If true, the header Karnaugh Map is included with an option to hide the map
this.mapHeading = true; /// A results selector. Selector that will be set to the success value
/// if the expression successfully checks
this.resultSel = null; /// Value resultsSel will be set to if check is successful ('fail' otherwise)
this.success = 'success'; /// Selector that will be set to the expression each time check is pressed.
this.expressionSel = null; /// Is the solve button provided?
this.solve = false; /// Is the problem solved?
this.solved = false; /// Optional application tag
this.appTag = null; /// Optional name for test result
this.name = null; /// Optional test result API
this.testAPI = null; /// Content type to send (can be json if required)
this.contentType = 'application/x-www-form-urlencoded; charset=UTF-8';
for (var property in options) {
if (options.hasOwnProperty(property)) {
if (!this.hasOwnProperty(property)) {
throw new Error("Invalid option " + property);
}
this[property] = options[property];
}
}
};
/***/ }),
/***/ "./src/Kmap/Solution.js":
/*!******************************!*\
!*** ./src/Kmap/Solution.js ***!
\******************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "Solution": () => (/* binding */ Solution)
/* harmony export */ });
/* harmony import */ var _Logic_Expression__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Logic/Expression */ "./src/Logic/Expression.js");
/* harmony import */ var _Logic_QuineMcCluskeySolver__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Logic/QuineMcCluskeySolver */ "./src/Logic/QuineMcCluskeySolver.js");
/* harmony import */ var _Utility_Ajax__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./Utility/Ajax */ "./src/Kmap/Utility/Ajax.js");
/* harmony import */ var _Utility_JsonAPI__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./Utility/JsonAPI */ "./src/Kmap/Utility/JsonAPI.js");
/* harmony import */ var _Vendor_Blob_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../Vendor/Blob.js */ "./src/Vendor/Blob.js");
/* harmony import */ var _Vendor_Blob_js__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(_Vendor_Blob_js__WEBPACK_IMPORTED_MODULE_4__);
/* harmony import */ var _Vendor_FileSaver_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../Vendor/FileSaver.js */ "./src/Vendor/FileSaver.js");
/* harmony import */ var html2canvas__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! html2canvas */ "../../.yarn/cache/html2canvas-npm-1.0.0-rc.7-8212b6d6fa-c0c6626e6f.zip/node_modules/html2canvas/dist/html2canvas.js");
/* harmony import */ var html2canvas__WEBPACK_IMPORTED_MODULE_6___default = /*#__PURE__*/__webpack_require__.n(html2canvas__WEBPACK_IMPORTED_MODULE_6__);
function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it["return"] != null) it["return"](); } finally { if (didErr) throw err; } } }; }
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
/**
* Practice page solution form
* @param main Main object
* @param element Parent element
* @constructor
*/
var Solution = function Solution(main, element) {
var _this = this;
this.main = main; // The various section elements
var div = null,
expressionInput = null,
result = null;
var initialize = function initialize() {
// We only create the div is the user wants the solution
// interface or is a solution is presented.
if (main.options.solution || main.options.solved) {
div = document.createElement('div');
div.classList.add('kmap-cl-solution');
element.append(div); // If a solution is presented, we don't need the interface
if (main.options.solution && !main.options.solved) {
addDiv();
} // Results div
result = document.createElement('div');
div.appendChild(result);
}
}; // Add the <div> to main
var addDiv = function addDiv() {
// Heading
var h3 = document.createElement('h3');
h3.innerText = 'Solution';
div.appendChild(h3);
var form = document.createElement('form');
div.appendChild(form); //
// Enter expression
// '<p><label>Enter Expression<br><input type="text" spellcheck="false" class="expression"></label></p>'
//
var p = document.createElement('p');
form.appendChild(p);
var label = document.createElement('label');
p.appendChild(label);
label.innerText = 'Enter Expression';
label.appendChild(document.createElement('br'));
expressionInput = document.createElement('input');
expressionInput.setAttribute('type', 'text');
expressionInput.setAttribute('spellch