Initial Commit

This commit is contained in:
Wu
2020-12-19 17:14:40 +00:00
commit 62d68374e1
29 changed files with 2681 additions and 0 deletions

View File

@@ -0,0 +1,129 @@
body {
overflow-x: hidden;
font-size: 18px;
position: relative;
min-height: 100vh;
}
html, body {
height: 100%;
width: 100%;
background-color: #FFF;
}
body {
position: relative;
min-height: 100vh;
}
body::after {
content: '';
display: block;
height: 220px;
/* Set same as footer's height */
}
/*-------- Navbar --------*/
.navbar .nav-link {
font-size: 20px;
background-color: #04021c;
padding-left: 1rem !important;
padding-right: 1rem !important;
}
.bg-dark {
background-color: #04021c!important;
}
.navbar-nav > li > a:hover {
transition: all 0.3s;
color: #FFF;
}
.navbar .active {
background: #FFF !important;
color: #000 !important;
}
.navbar-nav > li > a:hover {
cursor:pointer;
background-color: #FFF;
color: #000 !important;
}
#console-box {
height: 50%;
}
#console {
list-style: none;
-webkit-padding-start: 0;
-webkit-margin-after: 0;
-webkit-margin-before: 1em;
border: 1px solid #000;
overflow-y: auto;
width: 100%;
background: #333;
color: #fff;
height: 200px;
max-height: 200px;
}
.box-shadow {
box-shadow: 0px 10px 50px rgba(0, 0, 0, 0.6);
}
.subfooter {
position: absolute;
bottom: 60px;
width: 100%;
height: 160px;
background-color: #04021c/*#2d3436*/;
color: white;
}
#sub-footer li {
font-size: .8125rem;
font-weight: 300;
}
#sub-footer a {
color: #15abe2;
}
#sub-footer a:visited {
border-bottom: #D7D7D7;
}
#sub-footer a, a:link {
transition: all .4s;
}
.exeter {
margin-top: 10%;
margin-left: 40%;
width: 80%;
content:url("/static/img/exeter.png");
}
.russell {
margin-top: 5%;
margin-left: 40%;
width: 80%;
content:url("/static/img/russell.png");
}
#main-footer {
background: #000;
color: #636e72;
}
.footer {
position: absolute;
bottom: 0;
width: 100%;
height: 60px;
line-height: 60px;
background-color: #f5f5f5;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -0,0 +1,98 @@
body{
margin: 0;
padding: 0;
overflow:hidden;
}
p{
text-align: center;
overflow: overlay;
position: relative;
}
body{
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
background-color: rgb(248, 248, 248)
}
#toolbox{
position: absolute;
bottom: 0;
left: 0;
margin-bottom: 0.5em;
margin-left: 1em;
border: 2px solid #EEEEEE;
border-radius: 5px;
padding: 1em;
z-index: 5;
}
#toolbox input{
width: 30px;
opacity: 0.4;
}
#toolbox input:hover{
opacity: 1;
cursor: pointer;
}
#hidden-file-upload{
display: none;
}
#download-input{
margin: 0 0.5em;
}
.conceptG text{
pointer-events: none;
}
marker{
fill: #333;
}
g.conceptG circle{
fill: #F6FBFF;
stroke: #333;
stroke-width: 2px;
}
g.conceptG:hover circle{
fill: rgb(200, 238, 241);
}
g.selected circle{
fill: rgb(250, 232, 255);
}
g.selected:hover circle{
fill: rgb(250, 232, 255);
}
path.link {
fill: none;
stroke: #333;
stroke-width: 6px;
cursor: default;
}
path.link:hover{
stroke: rgb(94, 196, 204);
}
g.connect-node circle{
fill: #BEFFFF;
}
path.link.hidden{
stroke-width: 0;
}
path.link.selected {
stroke: rgb(229, 172, 247);
}

View File

@@ -0,0 +1,648 @@
var docEl = document.documentElement,
bodyEl = document.getElementsByTagName('body')[0];
var width = window.innerWidth || docEl.clientWidth || bodyEl.clientWidth,
height = window.innerHeight || docEl.clientHeight || bodyEl.clientHeight;
function fitscreen(nodes, width, height) {
var minX = nodes[0].x;
var maxX = nodes[0].x;
var minY = nodes[0].y;
var maxY = nodes[0].y;
var offsetX = 0, offsetY = 0;
nodes.forEach(function (e, i) {
if (e.x > maxX) {
maxX = e.x
}
if (e.x < minX) {
minX = e.x
}
if (e.y < minY) {
minY = e.y
}
if (e.y < minY) {
minY = e.y
}
});
if (minX < 0) {
offsetX = - minX;
minX += offsetX;
maxX += offsetX;
}
if (minY < 0) {
offsetY = -minY;
minY += offsetY
maxY += offsetY;
}
nodes.forEach(function (e, i) {
e.x += offsetX;
e.y += offsetY;
e.x = (e.x - minX) * width * 0.8 / (maxX - minX) + 0.25 * width;
e.y = (e.y - minY) * height * 0.8 / (maxY - minY) + 0.25 * height;
});
return nodes;
}
document.onload = (function (d3, saveAs, Blob, undefined) {
// define graphcreator object
var GraphCreator = function (svg, nodes, edges) {
var thisGraph = this;
thisGraph.idct = 0;
thisGraph.nodes = nodes || [];
thisGraph.edges = edges || [];
thisGraph.state = {
selectedNode: null,
selectedEdge: null,
mouseDownNode: null,
mouseDownLink: null,
justDragged: false,
justScaleTransGraph: false,
lastKeyDown: -1,
shiftNodeDrag: false,
selectedText: null
};
// define arrow markers for graph links
var defs = svg.append('svg:defs');
defs.append('svg:marker')
.attr('id', 'end-arrow')
.attr('viewBox', '0 -5 10 10')
.attr('refX', "20")
.attr('markerWidth', 3.5)
.attr('markerHeight', 3.5)
.attr('orient', 'auto')
.append('svg:path')
.attr('d', 'M0,-5L10,0L0,5');
// define arrow markers for leading arrow
defs.append('svg:marker')
.attr('id', 'mark-end-arrow')
.attr('viewBox', '0 -5 10 10')
.attr('refX', 7)
.attr('markerWidth', 3.5)
.attr('markerHeight', 3.5)
.attr('orient', 'auto')
.append('svg:path')
.attr('d', 'M0,-5L10,0L0,5');
thisGraph.svg = svg;
thisGraph.svgG = svg.append("g")
.classed(thisGraph.consts.graphClass, true);
var svgG = thisGraph.svgG;
// displayed when dragging between nodes
thisGraph.dragLine = svgG.append('svg:path')
.attr('class', 'link dragline hidden')
.attr('d', 'M0,0L0,0')
.style('marker-end', 'url(#mark-end-arrow)');
// svg nodes and edges
thisGraph.paths = svgG.append("g").selectAll("g");
thisGraph.circles = svgG.append("g").selectAll("g");
thisGraph.drag = d3.behavior.drag()
.origin(function (d) {
return { x: d.x, y: d.y };
})
.on("drag", function (args) {
thisGraph.state.justDragged = true;
thisGraph.dragmove.call(thisGraph, args);
})
.on("dragend", function () {
// todo check if edge-mode is selected
});
// listen for key events
d3.select(window).on("keydown", function () {
thisGraph.svgKeyDown.call(thisGraph);
})
.on("keyup", function () {
thisGraph.svgKeyUp.call(thisGraph);
});
svg.on("mousedown", function (d) { thisGraph.svgMouseDown.call(thisGraph, d); });
svg.on("mouseup", function (d) { thisGraph.svgMouseUp.call(thisGraph, d); });
// listen for dragging
var dragSvg = d3.behavior.zoom()
.on("zoom", function () {
if (d3.event.sourceEvent.shiftKey) {
// TODO the internal d3 state is still changing
return false;
} else {
thisGraph.zoomed.call(thisGraph);
}
return true;
})
.on("zoomstart", function () {
var ael = d3.select("#" + thisGraph.consts.activeEditId).node();
if (ael) {
ael.blur();
}
if (!d3.event.sourceEvent.shiftKey) d3.select('body').style("cursor", "move");
})
.on("zoomend", function () {
d3.select('body').style("cursor", "auto");
});
svg.call(dragSvg).on("dblclick.zoom", null);
// listen for resize
window.onresize = function () { thisGraph.updateWindow(svg); };
// handle download data
d3.select("#download-input").on("click", function () {
var saveEdges = [];
thisGraph.edges.forEach(function (val, i) {
saveEdges.push({ source: val.source.id, target: val.target.id });
});
var blob = new Blob([window.JSON.stringify({ "nodes": thisGraph.nodes, "edges": saveEdges })], { type: "text/plain;charset=utf-8" });
saveAs(blob, "mydag.json");
});
// handle uploaded data
d3.select("#upload-input").on("click", function () {
document.getElementById("hidden-file-upload").click();
});
d3.select("#hidden-file-upload").on("change", function () {
if (window.File && window.FileReader && window.FileList && window.Blob) {
var uploadFile = this.files[0];
var filereader = new window.FileReader();
filereader.onload = function () {
var txtRes = filereader.result;
// TODO better error handling
try {
var jsonObj = JSON.parse(txtRes);
jsonObj.nodes = fitscreen(jsonObj.nodes, width, height)
thisGraph.deleteGraph(true);
thisGraph.nodes = jsonObj.nodes;
thisGraph.setIdCt(jsonObj.nodes.length);
var newEdges = jsonObj.edges;
newEdges.forEach(function (e, i) {
newEdges[i] = {
source: thisGraph.nodes.filter(function (n) { return n.id == e.source; })[0],
target: thisGraph.nodes.filter(function (n) { return n.id == e.target; })[0]
};
});
thisGraph.edges = newEdges;
thisGraph.updateGraph();
} catch (err) {
window.alert("Error parsing uploaded file\nerror message: " + err.message);
return;
}
};
filereader.readAsText(uploadFile);
} else {
alert("Your browser won't let you save this graph -- try upgrading your browser to IE 10+ or Chrome or Firefox.");
}
});
// handle delete graph
d3.select("#delete-graph").on("click", function () {
thisGraph.deleteGraph(false);
});
};
GraphCreator.prototype.setIdCt = function (idct) {
this.idct = idct;
};
GraphCreator.prototype.consts = {
selectedClass: "selected",
connectClass: "connect-node",
circleGClass: "conceptG",
graphClass: "graph",
activeEditId: "active-editing",
BACKSPACE_KEY: 8,
DELETE_KEY: 46,
ENTER_KEY: 13,
nodeRadius: 25
};
/* PROTOTYPE FUNCTIONS */
GraphCreator.prototype.dragmove = function (d) {
var thisGraph = this;
if (thisGraph.state.shiftNodeDrag) {
thisGraph.dragLine.attr('d', 'M' + d.x + ',' + d.y + 'L' + d3.mouse(thisGraph.svgG.node())[0] + ',' + d3.mouse(this.svgG.node())[1]);
} else {
d.x += d3.event.dx;
d.y += d3.event.dy;
thisGraph.updateGraph();
}
};
GraphCreator.prototype.deleteGraph = function (skipPrompt) {
var thisGraph = this,
doDelete = true;
if (!skipPrompt) {
doDelete = window.confirm("Press OK to delete this graph");
}
if (doDelete) {
thisGraph.nodes = [];
thisGraph.edges = [];
thisGraph.updateGraph();
}
};
/* select all text in element: taken from http://stackoverflow.com/questions/6139107/programatically-select-text-in-a-contenteditable-html-element */
GraphCreator.prototype.selectElementContents = function (el) {
var range = document.createRange();
range.selectNodeContents(el);
var sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(range);
};
/* insert svg line breaks: taken from http://stackoverflow.com/questions/13241475/how-do-i-include-newlines-in-labels-in-d3-charts */
GraphCreator.prototype.insertTitleLinebreaks = function (gEl, title) {
var words = title.split(/\s+/g),
nwords = words.length;
var el = gEl.append("text")
.attr("text-anchor", "middle")
.attr("dy", "-" + (nwords - 1) * 7.5);
for (var i = 0; i < words.length; i++) {
var tspan = el.append('tspan').text(words[i]);
if (i > 0)
tspan.attr('x', 0).attr('dy', '15');
}
};
// remove edges associated with a node
GraphCreator.prototype.spliceLinksForNode = function (node) {
var thisGraph = this,
toSplice = thisGraph.edges.filter(function (l) {
return (l.source === node || l.target === node);
});
toSplice.map(function (l) {
thisGraph.edges.splice(thisGraph.edges.indexOf(l), 1);
});
};
GraphCreator.prototype.replaceSelectEdge = function (d3Path, edgeData) {
var thisGraph = this;
d3Path.classed(thisGraph.consts.selectedClass, true);
if (thisGraph.state.selectedEdge) {
thisGraph.removeSelectFromEdge();
}
thisGraph.state.selectedEdge = edgeData;
};
GraphCreator.prototype.replaceSelectNode = function (d3Node, nodeData) {
var thisGraph = this;
d3Node.classed(this.consts.selectedClass, true);
if (thisGraph.state.selectedNode) {
thisGraph.removeSelectFromNode();
}
thisGraph.state.selectedNode = nodeData;
};
GraphCreator.prototype.removeSelectFromNode = function () {
var thisGraph = this;
thisGraph.circles.filter(function (cd) {
return cd.id === thisGraph.state.selectedNode.id;
}).classed(thisGraph.consts.selectedClass, false);
thisGraph.state.selectedNode = null;
};
GraphCreator.prototype.removeSelectFromEdge = function () {
var thisGraph = this;
thisGraph.paths.filter(function (cd) {
return cd === thisGraph.state.selectedEdge;
}).classed(thisGraph.consts.selectedClass, false);
thisGraph.state.selectedEdge = null;
};
GraphCreator.prototype.pathMouseDown = function (d3path, d) {
var thisGraph = this,
state = thisGraph.state;
d3.event.stopPropagation();
state.mouseDownLink = d;
if (state.selectedNode) {
thisGraph.removeSelectFromNode();
}
var prevEdge = state.selectedEdge;
if (!prevEdge || prevEdge !== d) {
thisGraph.replaceSelectEdge(d3path, d);
} else {
thisGraph.removeSelectFromEdge();
}
};
// mousedown on node
GraphCreator.prototype.circleMouseDown = function (d3node, d) {
var thisGraph = this,
state = thisGraph.state;
d3.event.stopPropagation();
state.mouseDownNode = d;
if (d3.event.shiftKey) {
state.shiftNodeDrag = d3.event.shiftKey;
// reposition dragged directed edge
thisGraph.dragLine.classed('hidden', false)
.attr('d', 'M' + d.x + ',' + d.y + 'L' + d.x + ',' + d.y);
return;
}
};
/* place editable text on node in place of svg text */
GraphCreator.prototype.changeTextOfNode = function (d3node, d) {
var thisGraph = this,
consts = thisGraph.consts,
htmlEl = d3node.node();
d3node.selectAll("text").remove();
var nodeBCR = htmlEl.getBoundingClientRect(),
curScale = nodeBCR.width / consts.nodeRadius,
placePad = 5 * curScale,
useHW = curScale > 1 ? nodeBCR.width * 0.71 : consts.nodeRadius * 1.42;
// replace with editableconent text
var d3txt = thisGraph.svg.selectAll("foreignObject")
.data([d])
.enter()
.append("foreignObject")
.attr("x", nodeBCR.left + placePad)
.attr("y", nodeBCR.top + placePad)
.attr("height", 2 * useHW)
.attr("width", useHW)
.append("xhtml:p")
.attr("id", consts.activeEditId)
.attr("contentEditable", "true")
.text(d.title)
.on("mousedown", function (d) {
d3.event.stopPropagation();
})
.on("keydown", function (d) {
d3.event.stopPropagation();
if (d3.event.keyCode == consts.ENTER_KEY && !d3.event.shiftKey) {
this.blur();
}
})
.on("blur", function (d) {
d.title = this.textContent;
thisGraph.insertTitleLinebreaks(d3node, d.title);
d3.select(this.parentElement).remove();
});
return d3txt;
};
// mouseup on nodes
GraphCreator.prototype.circleMouseUp = function (d3node, d) {
var thisGraph = this,
state = thisGraph.state,
consts = thisGraph.consts;
// reset the states
state.shiftNodeDrag = false;
d3node.classed(consts.connectClass, false);
var mouseDownNode = state.mouseDownNode;
if (!mouseDownNode) return;
thisGraph.dragLine.classed("hidden", true);
if (mouseDownNode !== d) {
// we're in a different node: create new edge for mousedown edge and add to graph
var newEdge = { source: mouseDownNode, target: d };
var filtRes = thisGraph.paths.filter(function (d) {
if (d.source === newEdge.target && d.target === newEdge.source) {
thisGraph.edges.splice(thisGraph.edges.indexOf(d), 1);
}
return d.source === newEdge.source && d.target === newEdge.target;
});
if (!filtRes[0].length) {
thisGraph.edges.push(newEdge);
thisGraph.updateGraph();
}
} else {
// we're in the same node
if (state.justDragged) {
// dragged, not clicked
state.justDragged = false;
} else {
// clicked, not dragged
if (d3.event.shiftKey) {
// shift-clicked node: edit text content
var d3txt = thisGraph.changeTextOfNode(d3node, d);
var txtNode = d3txt.node();
thisGraph.selectElementContents(txtNode);
txtNode.focus();
} else {
if (state.selectedEdge) {
thisGraph.removeSelectFromEdge();
}
var prevNode = state.selectedNode;
if (!prevNode || prevNode.id !== d.id) {
thisGraph.replaceSelectNode(d3node, d);
} else {
thisGraph.removeSelectFromNode();
}
}
}
}
state.mouseDownNode = null;
return;
}; // end of circles mouseup
// mousedown on main svg
GraphCreator.prototype.svgMouseDown = function () {
this.state.graphMouseDown = true;
};
// mouseup on main svg
GraphCreator.prototype.svgMouseUp = function () {
var thisGraph = this,
state = thisGraph.state;
if (state.justScaleTransGraph) {
// dragged not clicked
state.justScaleTransGraph = false;
} else if (state.graphMouseDown && d3.event.shiftKey) {
// clicked not dragged from svg
var xycoords = d3.mouse(thisGraph.svgG.node()),
d = { id: thisGraph.idct, title: (this.idct).toString(), x: xycoords[0], y: xycoords[1] };
thisGraph.idct++;
thisGraph.nodes.push(d);
thisGraph.updateGraph();
// make title of text immediently editable
var d3txt = thisGraph.changeTextOfNode(thisGraph.circles.filter(function (dval) {
return dval.id === d.id;
}), d),
txtNode = d3txt.node();
thisGraph.selectElementContents(txtNode);
txtNode.focus();
} else if (state.shiftNodeDrag) {
// dragged from node
state.shiftNodeDrag = false;
thisGraph.dragLine.classed("hidden", true);
}
state.graphMouseDown = false;
};
// keydown on main svg
GraphCreator.prototype.svgKeyDown = function () {
var thisGraph = this,
state = thisGraph.state,
consts = thisGraph.consts;
// make sure repeated key presses don't register for each keydown
if (state.lastKeyDown !== -1) return;
state.lastKeyDown = d3.event.keyCode;
var selectedNode = state.selectedNode,
selectedEdge = state.selectedEdge;
switch (d3.event.keyCode) {
case consts.BACKSPACE_KEY:
case consts.DELETE_KEY:
d3.event.preventDefault();
if (selectedNode) {
thisGraph.nodes.splice(thisGraph.nodes.indexOf(selectedNode), 1);
thisGraph.spliceLinksForNode(selectedNode);
state.selectedNode = null;
thisGraph.updateGraph();
} else if (selectedEdge) {
thisGraph.edges.splice(thisGraph.edges.indexOf(selectedEdge), 1);
state.selectedEdge = null;
thisGraph.updateGraph();
}
break;
}
};
GraphCreator.prototype.svgKeyUp = function () {
this.state.lastKeyDown = -1;
};
// call to propagate changes to graph
GraphCreator.prototype.updateGraph = function () {
var thisGraph = this,
consts = thisGraph.consts,
state = thisGraph.state;
thisGraph.paths = thisGraph.paths.data(thisGraph.edges, function (d) {
return String(d.source.id) + "+" + String(d.target.id);
});
var paths = thisGraph.paths;
// update existing paths
paths.style('marker-end', 'url(#end-arrow)')
.classed(consts.selectedClass, function (d) {
return d === state.selectedEdge;
})
.attr("d", function (d) {
return "M" + d.source.x + "," + d.source.y + "L" + d.target.x + "," + d.target.y;
});
// add new paths
paths.enter()
.append("path")
.style('marker-end', 'url(#end-arrow)')
.classed("link", true)
.attr("d", function (d) {
return "M" + d.source.x + "," + d.source.y + "L" + d.target.x + "," + d.target.y;
})
.on("mousedown", function (d) {
thisGraph.pathMouseDown.call(thisGraph, d3.select(this), d);
}
)
.on("mouseup", function (d) {
state.mouseDownLink = null;
});
// remove old links
paths.exit().remove();
// update existing nodes
thisGraph.circles = thisGraph.circles.data(thisGraph.nodes, function (d) { return d.id; });
thisGraph.circles.attr("transform", function (d) { return "translate(" + d.x + "," + d.y + ")"; });
// add new nodes
var newGs = thisGraph.circles.enter()
.append("g");
newGs.classed(consts.circleGClass, true)
.attr("transform", function (d) { return "translate(" + d.x + "," + d.y + ")"; })
.on("mouseover", function (d) {
if (state.shiftNodeDrag) {
d3.select(this).classed(consts.connectClass, true);
}
})
.on("mouseout", function (d) {
d3.select(this).classed(consts.connectClass, false);
})
.on("mousedown", function (d) {
thisGraph.circleMouseDown.call(thisGraph, d3.select(this), d);
})
.on("mouseup", function (d) {
thisGraph.circleMouseUp.call(thisGraph, d3.select(this), d);
})
.call(thisGraph.drag);
newGs.append("circle")
.attr("r", String(consts.nodeRadius));
newGs.each(function (d) {
thisGraph.insertTitleLinebreaks(d3.select(this), d.title);
});
// remove old nodes
thisGraph.circles.exit().remove();
};
GraphCreator.prototype.zoomed = function () {
this.state.justScaleTransGraph = true;
d3.select("." + this.consts.graphClass)
.attr("transform", "translate(" + d3.event.translate + ") scale(" + d3.event.scale + ")");
};
GraphCreator.prototype.updateWindow = function (svg) {
var docEl = document.documentElement,
bodyEl = document.getElementsByTagName('body')[0];
var x = window.innerWidth || docEl.clientWidth || bodyEl.clientWidth;
var y = window.innerHeight || docEl.clientHeight || bodyEl.clientHeight;
svg.attr("width", x).attr("height", y);
};
/**** MAIN ****/
// warn the user when leaving
// window.onbeforeunload = function(){
// return "Make sure to save your graph locally before leaving";
// };
// initial node data
var obj = JSON.parse('{"nodes": [{"title": "0", "id": 0, "x": 38, "y": 20}, {"title": "1", "id": 1, "x": 39, "y": 26}, {"title": "2", "id": 2, "x": 40, "y": 25}, {"title": "3", "id": 3, "x": 36, "y": 23}, {"title": "4", "id": 4, "x": 33, "y": 10}, {"title": "5", "id": 5, "x": 37, "y": 12}, {"title": "6", "id": 6, "x": 38, "y": 13}, {"title": "7", "id": 7, "x": 37, "y": 20}, {"title": "8", "id": 8, "x": 41, "y": 9}, {"title": "9", "id": 9, "x": 41, "y": 13}, {"title": "10", "id": 10, "x": 36, "y": -5}, {"title": "11", "id": 11, "x": 38, "y": 15}, {"title": "12", "id": 12, "x": 38, "y": 15}, {"title": "13", "id": 13, "x": 37, "y": 15}, {"title": "14", "id": 14, "x": 35, "y": 14}, {"title": "15", "id": 15, "x": 39, "y": 19}], "edges": [{"source": 8, "target": 10}, {"source": 10, "target": 4}, {"source": 4, "target": 14}, {"source": 14, "target": 0}, {"source": 0, "target": 7}, {"source": 7, "target": 3}, {"source": 3, "target": 1}, {"source": 1, "target": 2}, {"source": 2, "target": 15}, {"source": 15, "target": 11}, {"source": 11, "target": 12}, {"source": 12, "target": 13}, {"source": 13, "target": 5}, {"source": 5, "target": 6}, {"source": 6, "target": 9}, {"source": 9, "target": 8}]}')
obj.nodes = fitscreen(obj.nodes, width, height);
var newEdges = obj.edges;
newEdges.forEach(function (e, i) {
newEdges[i] = {
source: obj.nodes.filter(function (n) { return n.id == e.source; })[0],
target: obj.nodes.filter(function (n) { return n.id == e.target; })[0]
};
});
obj.edges = newEdges;
/** MAIN SVG **/
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);
var graph = new GraphCreator(svg, obj.nodes, obj.edges);
graph.setIdCt(obj.nodes.length);
graph.updateGraph();
})(window.d3, window.saveAs, window.Blob);

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

View File

@@ -0,0 +1,26 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1" crossorigin="anonymous">
<title>Document</title>
</head>
<body>
<div class="container">
<h1>Hello</h1>
<div class="ratio ratio-16x9">
<iframe src="preview.html" title="YouTube video" allowfullscreen></iframe>
</div>
</div>
<section>
<div class="container">
<div class="row">
<h1>Leader</h1>
<label for="formFileLg" class="form-label">Large file input example</label>
<input class="form-control form-control-lg" id="formFileLg" type="file" />
</div>
</div>
</section>
</body>
</html>

View File

@@ -0,0 +1,92 @@
$( document ).ready( () => {
$('body').scrollspy({ target: '#main-nav', offset: 130 })
$('#fullpage').fullpage({
// anchors: ['underPage', 'gradPage', 'phdPage'],
sectionsColor: ['#ffffff', '#f8f8f8'],
autoScrolling: false,
css3: true,
fitToSection: false,
afterLoad: function(anchorLink, index) {
// history.pushState(null, null, "");
// console.log(anchorLink);
}
});
$("a").on('click', function(event) {
// Make sure this.hash has a value before overriding default behavior
if (this.hash !== "") {
// Prevent default anchor click behavior
event.preventDefault();
// Store hash
var hash = this.hash;
// Using jQuery's animate() method to add smooth page scroll
// The optional number (800) specifies the number of milliseconds it takes to scroll to the specified area
var offset = 0;
if (hash === "#home")
{
offset = -100;
}
else {
offset = -60;
}
$('html, body').animate({
scrollTop: ($(hash).offset().top + offset)
}, 1000, function(){
// Add hash (#) to URL when done scrolling (default click behavior)
// window.location.hash = hash;
});
}
});
// initialize with defaults
// $("#uploadfile").fileinput();
// with plugin options
$("#uploadfile").fileinput({
// theme: "fa",
'theme': 'fas',
showUpload:false,
previewFileType:'py',
maxFileCount: 1,
allowedFileExtensions: ["py"]
});
ConsoleLogHTML.connect(document.getElementById("console")); // Redirect log messages
// ConsoleLogHTML.disconnect(); // Stop redirecting
var url = window.location;
// GET REQUEST
$("#btnGetFiles").click( (event) => {
event.preventDefault();
ajaxGet();
});
// DO GET
function ajaxGet(){
$.ajax({
type : "GET",
url : "/api/files/getall",
success: (data) => {
//clear old data
$("#listFiles").html("");
/*
render list of files
*/
$("#listFiles").append('<ul>');
$.each(data, (index, filename) => {
$("#listFiles").append('<li><a href=' + url + 'api/files/' + filename +'>' + filename + '</a></li>');
});
$("#listFiles").append('</ul>');
},
error : (err) => {
$("#listFiles").html(err.responseText);
}
});
}
})

View File

@@ -0,0 +1,81 @@
// warn the user when leaving
window.onbeforeunload = function(){
return "Make sure to save your graph locally before leaving";
};
var socket = io();
socket.on('connect', () => {
$("#session_id").text(socket.id);
window.id = socket.id
console.log('Session Id: ', socket.id); // an alphanumeric id...
});
socket.on('users_count', (clients) => {
$("#user_counts").text(clients);
});
socket.on('start', () => {
console.log('Building start');
});
$(document).ready( () => {
$("#btnSubmit").click((event) => {
//stop submit the form, we will post it manually.
event.preventDefault();
doAjax();
});
$('#uploadfile').change(function(e){
if(e.target.files[0])
{
var fileName = e.target.files[0].name;
if(fileName !== "my_model.py")
{
alert('Please upload my_model.py');
$('#btnSubmit').prop('disabled', true);
}
else
{
$('#btnSubmit').prop('disabled', false);
}
}
});
});
function doAjax() {
// Get form
var form = $('#fileUploadForm')[0];
var data = new FormData(form);
var file = data.get('uploadfile');
var renameFile =new File([file], window.id + '.py' ,{type:file.type});
var formdata = new FormData();
formdata.append('uploadfile', renameFile);
// console.log(formdata.get('uploadfile'))
if(window.id) {
$.ajax({
type: "POST",
enctype: 'multipart/form-data',
url: "/api/files/upload",
data: formdata,
processData: false, //prevent jQuery from automatically transforming the data into a query string
contentType: false,
cache: false,
success: (data) => {
// $("#listFiles").text(data);
console.log('Emit build request')
socket.emit('build', {});
},
error: (e) => {
$("#listFiles").text(e.responseText);
}
});
}
else
{
alert('Failed to connect to server');
}
}

View File

@@ -0,0 +1,21 @@
<!DOCTYPE HTML>
<html>
<head>
<link rel="stylesheet" href="graph-creator.css" />
<script src="https://d3js.org/d3.v3.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/FileSaver.js/2.0.0/FileSaver.min.js"></script>
</head>
<body>
<div class="container">
<div id="toolbox">
<input type="file" id="hidden-file-upload"><input id="upload-input" type="image" title="upload graph" src="upload-icon.png" alt="upload graph"> &nbsp;
<!-- <input type="image" id="download-input" title="download graph" src="download-icon.png" alt="download graph"> -->
<input type="image" id="delete-graph" title="delete graph" src="trash-icon.png" alt="delete graph">
</div>
</div>
<script src="graph-creator.js"></script>
</body>
</html>

View File

@@ -0,0 +1,156 @@
/*!
* bootstrap-fileinput v5.1.3
* http://plugins.krajee.com/file-input
*
* Krajee Explorer Font Awesome 5.x theme style for bootstrap-fileinput. Load this theme file after loading
* font awesome 5.x CSS and `fileinput.css`.
*
* Author: Kartik Visweswaran
* Copyright: 2014 - 2020, Kartik Visweswaran, Krajee.com
*
* Licensed under the BSD-3-Clause
* https://github.com/kartik-v/bootstrap-fileinput/blob/master/LICENSE.md
*/
.theme-explorer-fas .file-preview-frame {
border: 1px solid #ddd;
margin: 2px 0;
width: 100%;
display: flex;
justify-content: space-between;
align-items: center;
}
.theme-explorer-fas .file-actions,
.theme-explorer-fas .file-upload-indicator, .theme-explorer-fas .file-drag-handle, .theme-explorer-fas .explorer-frame .kv-file-content, .theme-explorer-fas .file-actions, .explorer-frame .file-preview-other {
text-align: center;
}
.theme-explorer-fas .file-upload-indicator, .theme-explorer-fas .file-drag-handle {
position: absolute;
display: inline-block;
bottom: 8px;
right: 4px;
width: 16px;
height: 16px;
font-size: 16px;
}
.theme-explorer-fas .file-thumb-progress .progress, .theme-explorer-fas .explorer-caption {
display: block;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
}
.theme-explorer-fas .file-thumb-progress .progress {
margin-top: 5px;
}
.theme-explorer-fas .explorer-caption,
.theme-explorer-fas .file-footer-buttons {
padding: 5px;
}
.theme-explorer-fas .file-footer-buttons {
text-align: right;
}
.theme-explorer-fas .explorer-caption {
color: #777;
padding-top: 5px;
}
.theme-explorer-fas .kvsortable-ghost {
opacity: 0.6;
background: #e1edf7;
border: 2px solid #a1abff;
}
.theme-explorer-fas .file-preview .table {
margin: 0;
}
.theme-explorer-fas .file-error-message ul {
padding: 5px 0 0 20px;
}
.explorer-frame .file-preview-text {
display: inline-block;
color: #428bca;
border: 1px solid #ddd;
font-family: Menlo, Monaco, Consolas, "Courier New", monospace;
outline: none;
padding: 8px;
resize: none;
}
.explorer-frame .file-preview-html {
display: inline-block;
border: 1px solid #ddd;
padding: 8px;
overflow: auto;
}
.explorer-frame .file-other-icon {
font-size: 2.6em;
}
.explorer-frame:hover {
background-color: #f5f5f5;
}
.theme-explorer-fas .file-preview-frame samp {
font-size: 0.9rem;
}
.theme-explorer-fas .explorer-frame .kv-file-content {
width: 160px;
height: 80px;
padding: 5px;
text-align: left;
}
.theme-explorer-fas .file-details-cell {
width: 60%;
font-size: 0.95rem;
text-align: left;
margin-right: auto;
}
.theme-explorer-fas .file-actions-cell {
position: relative;
height: 80px;
width: 200px;
}
/*noinspection CssOverwrittenProperties*/
.file-zoom-dialog .explorer-frame .file-other-icon {
font-size: 22em;
font-size: 50vmin;
}
@media only screen and (max-width: 1249px) {
.theme-explorer-fas .file-preview-frame .file-details-cell {
width: 40%;
}
}
@media only screen and (max-width: 1023px) {
.theme-explorer-fas .file-preview-frame .file-details-cell {
width: 30%;
}
}
@media only screen and (max-width: 767px) {
.theme-explorer-fas .file-preview-frame .file-details-cell {
width: 200px;
}
}
@media only screen and (max-width: 575px) {
.theme-explorer-fas .file-preview-frame {
flex-direction: column;
}
.theme-explorer-fas .file-preview-frame .kv-file-content {
width: auto;
text-align: center;
}
.theme-explorer-fas .file-details-cell {
width: 100px;
text-align: center;
margin-right: 0;
}
.theme-explorer-fas .file-preview-frame .kv-file-content,
.theme-explorer-fas .file-details-cell,
.theme-explorer-fas .file-actions-cell {
width: 100%;
}
.theme-explorer-fas .file-actions-cell {
height: auto;
}
.theme-explorer-fas .file-footer-buttons {
text-align: left;
}
}

View File

@@ -0,0 +1,71 @@
/*!
* bootstrap-fileinput v5.1.3
* http://plugins.krajee.com/file-input
*
* Krajee Explorer Font Awesome theme configuration for bootstrap-fileinput.
* Load this theme file after loading `fileinput.js`. Ensure that
* font awesome assets and CSS are loaded on the page as well.
*
* Author: Kartik Visweswaran
* Copyright: 2014 - 2020, Kartik Visweswaran, Krajee.com
*
* Licensed under the BSD-3-Clause
* https://github.com/kartik-v/bootstrap-fileinput/blob/master/LICENSE.md
*/
(function ($) {
'use strict';
$.fn.fileinputThemes['explorer-fas'] = {
layoutTemplates: {
footer: '<div class="file-details-cell">' +
'<div class="explorer-caption" title="{caption}">{caption}</div> ' + '{size}{progress}' +
'</div>' +
'<div class="file-actions-cell">{indicator} {actions}</div>',
actions: '{drag}\n' +
'<div class="file-actions">\n' +
' <div class="file-footer-buttons">\n' +
' {upload} {download} {delete} {zoom} {other} ' +
' </div>\n' +
'</div>',
fileIcon: '<i class="fas fa-file kv-caption-icon"></i> '
},
previewSettings: {
html: {width: '100px', height: '60px'},
text: {width: '100px', height: '60px'},
video: {width: 'auto', height: '60px'},
audio: {width: 'auto', height: '60px'},
flash: {width: '100%', height: '60px'},
object: {width: '100%', height: '60px'},
pdf: {width: '100px', height: '60px'},
other: {width: '100%', height: '60px'}
},
frameClass: 'explorer-frame',
fileActionSettings: {
removeIcon: '<i class="fas fa-trash-alt"></i>',
uploadIcon: '<i class="fas fa-upload"></i>',
uploadRetryIcon: '<i class="fas fa-redo-alt"></i>',
downloadIcon: '<i class="fas fa-download"></i>',
zoomIcon: '<i class="fas fa-search-plus"></i>',
dragIcon: '<i class="fas fa-arrows-alt"></i>',
indicatorNew: '<i class="fas fa-plus-circle text-warning"></i>',
indicatorSuccess: '<i class="fas fa-check-circle text-success"></i>',
indicatorError: '<i class="fas fa-exclamation-circle text-danger"></i>',
indicatorLoading: '<i class="fas fa-hourglass text-muted"></i>',
indicatorPaused: '<i class="fa fa-pause text-info"></i>'
},
previewZoomButtonIcons: {
prev: '<i class="fas fa-caret-left fa-lg"></i>',
next: '<i class="fas fa-caret-right fa-lg"></i>',
toggleheader: '<i class="fas fa-fw fa-arrows-alt-v"></i>',
fullscreen: '<i class="fas fa-fw fa-arrows-alt"></i>',
borderless: '<i class="fas fa-fw fa-external-link-alt"></i>',
close: '<i class="fas fa-fw fa-times"></i>'
},
previewFileIcon: '<i class="fas fa-file"></i>',
browseIcon: '<i class="fas fa-folder-open"></i>',
removeIcon: '<i class="fas fa-trash-alt"></i>',
cancelIcon: '<i class="fas fa-ban"></i>',
pauseIcon: '<i class="fas fa-pause"></i>',
uploadIcon: '<i class="fas fa-upload"></i>',
msgValidationErrorIcon: '<i class="fas fa-exclamation-circle"></i> '
};
})(window.jQuery);

View File

@@ -0,0 +1,13 @@
/*!
* bootstrap-fileinput v5.1.3
* http://plugins.krajee.com/file-input
*
* Krajee Explorer Font Awesome 5.x theme style for bootstrap-fileinput. Load this theme file after loading
* font awesome 5.x CSS and `fileinput.css`.
*
* Author: Kartik Visweswaran
* Copyright: 2014 - 2020, Kartik Visweswaran, Krajee.com
*
* Licensed under the BSD-3-Clause
* https://github.com/kartik-v/bootstrap-fileinput/blob/master/LICENSE.md
*/.theme-explorer-fas .file-preview-frame{border:1px solid #ddd;margin:2px 0;width:100%;display:flex;justify-content:space-between;align-items:center}.explorer-frame .file-preview-other,.theme-explorer-fas .explorer-frame .kv-file-content,.theme-explorer-fas .file-actions,.theme-explorer-fas .file-drag-handle,.theme-explorer-fas .file-upload-indicator{text-align:center}.theme-explorer-fas .file-drag-handle,.theme-explorer-fas .file-upload-indicator{position:absolute;display:inline-block;bottom:8px;right:4px;width:16px;height:16px;font-size:16px}.theme-explorer-fas .explorer-caption,.theme-explorer-fas .file-thumb-progress .progress{display:block;white-space:nowrap;text-overflow:ellipsis;overflow:hidden}.theme-explorer-fas .file-thumb-progress .progress{margin-top:5px}.theme-explorer-fas .explorer-caption,.theme-explorer-fas .file-footer-buttons{padding:5px}.theme-explorer-fas .file-footer-buttons{text-align:right}.theme-explorer-fas .explorer-caption{color:#777;padding-top:5px}.theme-explorer-fas .kvsortable-ghost{opacity:.6;background:#e1edf7;border:2px solid #a1abff}.theme-explorer-fas .file-preview .table{margin:0}.theme-explorer-fas .file-error-message ul{padding:5px 0 0 20px}.explorer-frame .file-preview-text{display:inline-block;color:#428bca;border:1px solid #ddd;font-family:Menlo,Monaco,Consolas,"Courier New",monospace;outline:0;padding:8px;resize:none}.explorer-frame .file-preview-html{display:inline-block;border:1px solid #ddd;padding:8px;overflow:auto}.explorer-frame .file-other-icon{font-size:2.6em}.explorer-frame:hover{background-color:#f5f5f5}.theme-explorer-fas .file-preview-frame samp{font-size:.9rem}.theme-explorer-fas .explorer-frame .kv-file-content{width:160px;height:80px;padding:5px;text-align:left}.theme-explorer-fas .file-details-cell{width:60%;font-size:.95rem;text-align:left;margin-right:auto}.theme-explorer-fas .file-actions-cell{position:relative;height:80px;width:200px}.file-zoom-dialog .explorer-frame .file-other-icon{font-size:22em;font-size:50vmin}@media only screen and (max-width:1249px){.theme-explorer-fas .file-preview-frame .file-details-cell{width:40%}}@media only screen and (max-width:1023px){.theme-explorer-fas .file-preview-frame .file-details-cell{width:30%}}@media only screen and (max-width:767px){.theme-explorer-fas .file-preview-frame .file-details-cell{width:200px}}@media only screen and (max-width:575px){.theme-explorer-fas .file-preview-frame{flex-direction:column}.theme-explorer-fas .file-preview-frame .kv-file-content{text-align:center}.theme-explorer-fas .file-details-cell{text-align:center;margin-right:0}.theme-explorer-fas .file-actions-cell,.theme-explorer-fas .file-details-cell,.theme-explorer-fas .file-preview-frame .kv-file-content{width:100%}.theme-explorer-fas .file-actions-cell{height:auto}.theme-explorer-fas .file-footer-buttons{text-align:left}}

View File

@@ -0,0 +1,14 @@
/*!
* bootstrap-fileinput v5.1.3
* http://plugins.krajee.com/file-input
*
* Krajee Explorer Font Awesome theme configuration for bootstrap-fileinput.
* Load this theme file after loading `fileinput.js`. Ensure that
* font awesome assets and CSS are loaded on the page as well.
*
* Author: Kartik Visweswaran
* Copyright: 2014 - 2020, Kartik Visweswaran, Krajee.com
*
* Licensed under the BSD-3-Clause
* https://github.com/kartik-v/bootstrap-fileinput/blob/master/LICENSE.md
*/!function(a){"use strict";a.fn.fileinputThemes["explorer-fas"]={layoutTemplates:{footer:'<div class="file-details-cell"><div class="explorer-caption" title="{caption}">{caption}</div> {size}{progress}</div><div class="file-actions-cell">{indicator} {actions}</div>',actions:'{drag}\n<div class="file-actions">\n <div class="file-footer-buttons">\n {upload} {download} {delete} {zoom} {other} </div>\n</div>',fileIcon:'<i class="fas fa-file kv-caption-icon"></i> '},previewSettings:{html:{width:"100px",height:"60px"},text:{width:"100px",height:"60px"},video:{width:"auto",height:"60px"},audio:{width:"auto",height:"60px"},flash:{width:"100%",height:"60px"},object:{width:"100%",height:"60px"},pdf:{width:"100px",height:"60px"},other:{width:"100%",height:"60px"}},frameClass:"explorer-frame",fileActionSettings:{removeIcon:'<i class="fas fa-trash-alt"></i>',uploadIcon:'<i class="fas fa-upload"></i>',uploadRetryIcon:'<i class="fas fa-redo-alt"></i>',downloadIcon:'<i class="fas fa-download"></i>',zoomIcon:'<i class="fas fa-search-plus"></i>',dragIcon:'<i class="fas fa-arrows-alt"></i>',indicatorNew:'<i class="fas fa-plus-circle text-warning"></i>',indicatorSuccess:'<i class="fas fa-check-circle text-success"></i>',indicatorError:'<i class="fas fa-exclamation-circle text-danger"></i>',indicatorLoading:'<i class="fas fa-hourglass text-muted"></i>',indicatorPaused:'<i class="fa fa-pause text-info"></i>'},previewZoomButtonIcons:{prev:'<i class="fas fa-caret-left fa-lg"></i>',next:'<i class="fas fa-caret-right fa-lg"></i>',toggleheader:'<i class="fas fa-fw fa-arrows-alt-v"></i>',fullscreen:'<i class="fas fa-fw fa-arrows-alt"></i>',borderless:'<i class="fas fa-fw fa-external-link-alt"></i>',close:'<i class="fas fa-fw fa-times"></i>'},previewFileIcon:'<i class="fas fa-file"></i>',browseIcon:'<i class="fas fa-folder-open"></i>',removeIcon:'<i class="fas fa-trash-alt"></i>',cancelIcon:'<i class="fas fa-ban"></i>',pauseIcon:'<i class="fas fa-pause"></i>',uploadIcon:'<i class="fas fa-upload"></i>',msgValidationErrorIcon:'<i class="fas fa-exclamation-circle"></i> '}}(window.jQuery);

View File

@@ -0,0 +1,49 @@
/*!
* bootstrap-fileinput v5.1.3
* http://plugins.krajee.com/file-input
*
* Font Awesome 5 icon theme configuration for bootstrap-fileinput. Requires font awesome 5 assets to be loaded.
*
* Author: Kartik Visweswaran
* Copyright: 2014 - 2020, Kartik Visweswaran, Krajee.com
*
* Licensed under the BSD-3-Clause
* https://github.com/kartik-v/bootstrap-fileinput/blob/master/LICENSE.md
*/
(function ($) {
"use strict";
$.fn.fileinputThemes.fas = {
fileActionSettings: {
removeIcon: '<i class="fas fa-trash-alt"></i>',
uploadIcon: '<i class="fas fa-upload"></i>',
uploadRetryIcon: '<i class="fas fa-redo-alt"></i>',
downloadIcon: '<i class="fas fa-download"></i>',
zoomIcon: '<i class="fas fa-search-plus"></i>',
dragIcon: '<i class="fas fa-arrows-alt"></i>',
indicatorNew: '<i class="fas fa-plus-circle text-warning"></i>',
indicatorSuccess: '<i class="fas fa-check-circle text-success"></i>',
indicatorError: '<i class="fas fa-exclamation-circle text-danger"></i>',
indicatorLoading: '<i class="fas fa-hourglass text-muted"></i>',
indicatorPaused: '<i class="fa fa-pause text-info"></i>'
},
layoutTemplates: {
fileIcon: '<i class="fas fa-file kv-caption-icon"></i> '
},
previewZoomButtonIcons: {
prev: '<i class="fas fa-caret-left fa-lg"></i>',
next: '<i class="fas fa-caret-right fa-lg"></i>',
toggleheader: '<i class="fas fa-fw fa-arrows-alt-v"></i>',
fullscreen: '<i class="fas fa-fw fa-arrows-alt"></i>',
borderless: '<i class="fas fa-fw fa-external-link-alt"></i>',
close: '<i class="fas fa-fw fa-times"></i>'
},
previewFileIcon: '<i class="fas fa-file"></i>',
browseIcon: '<i class="fas fa-folder-open"></i>',
removeIcon: '<i class="fas fa-trash-alt"></i>',
cancelIcon: '<i class="fas fa-ban"></i>',
pauseIcon: '<i class="fas fa-pause"></i>',
uploadIcon: '<i class="fas fa-upload"></i>',
msgValidationErrorIcon: '<i class="fas fa-exclamation-circle"></i> '
};
})(window.jQuery);

View File

@@ -0,0 +1,12 @@
/*!
* bootstrap-fileinput v5.1.3
* http://plugins.krajee.com/file-input
*
* Font Awesome 5 icon theme configuration for bootstrap-fileinput. Requires font awesome 5 assets to be loaded.
*
* Author: Kartik Visweswaran
* Copyright: 2014 - 2020, Kartik Visweswaran, Krajee.com
*
* Licensed under the BSD-3-Clause
* https://github.com/kartik-v/bootstrap-fileinput/blob/master/LICENSE.md
*/!function(a){"use strict";a.fn.fileinputThemes.fas={fileActionSettings:{removeIcon:'<i class="fas fa-trash-alt"></i>',uploadIcon:'<i class="fas fa-upload"></i>',uploadRetryIcon:'<i class="fas fa-redo-alt"></i>',downloadIcon:'<i class="fas fa-download"></i>',zoomIcon:'<i class="fas fa-search-plus"></i>',dragIcon:'<i class="fas fa-arrows-alt"></i>',indicatorNew:'<i class="fas fa-plus-circle text-warning"></i>',indicatorSuccess:'<i class="fas fa-check-circle text-success"></i>',indicatorError:'<i class="fas fa-exclamation-circle text-danger"></i>',indicatorLoading:'<i class="fas fa-hourglass text-muted"></i>',indicatorPaused:'<i class="fa fa-pause text-info"></i>'},layoutTemplates:{fileIcon:'<i class="fas fa-file kv-caption-icon"></i> '},previewZoomButtonIcons:{prev:'<i class="fas fa-caret-left fa-lg"></i>',next:'<i class="fas fa-caret-right fa-lg"></i>',toggleheader:'<i class="fas fa-fw fa-arrows-alt-v"></i>',fullscreen:'<i class="fas fa-fw fa-arrows-alt"></i>',borderless:'<i class="fas fa-fw fa-external-link-alt"></i>',close:'<i class="fas fa-fw fa-times"></i>'},previewFileIcon:'<i class="fas fa-file"></i>',browseIcon:'<i class="fas fa-folder-open"></i>',removeIcon:'<i class="fas fa-trash-alt"></i>',cancelIcon:'<i class="fas fa-ban"></i>',pauseIcon:'<i class="fas fa-pause"></i>',uploadIcon:'<i class="fas fa-upload"></i>',msgValidationErrorIcon:'<i class="fas fa-exclamation-circle"></i> '}}(window.jQuery);

Binary file not shown.

After

Width:  |  Height:  |  Size: 133 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB