first initial working link for ptp and joining back and drawing the edge, also making use of old core icons to provide a basic look and feel, updated coloring to dark mode instead of info, seems to fit better

This commit is contained in:
Blake J. Harnden 2018-05-07 15:04:54 -07:00
parent b10c7fe502
commit 8e99af96a4
18 changed files with 1414 additions and 45 deletions

File diff suppressed because one or more lines are too long

BIN
webapp/static/core-icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

View file

@ -3,8 +3,7 @@
}
.navbar-text {
color: #17a2b8 !important;
background-color: #fff;
color: #fff !important;
font-weight: bold;
}

199
webapp/static/coreip.js Normal file
View file

@ -0,0 +1,199 @@
const AF_INET = 2;
const AF_INET6 = 23;
function ord (string) {
var str = string + '';
var code = str.charCodeAt(0);
if (code >= 0xD800 && code <= 0xDBFF) {
// High surrogate (could change last hex to 0xDB7F to treat
// high private surrogates as single characters)
var hi = code;
if (str.length === 1) {
// This is just a high surrogate with no following low surrogate,
// so we return its value;
return code;
// we could also throw an error as it is not a complete character,
// but someone may want to know
}
var low = str.charCodeAt(1);
return ((hi - 0xD800) * 0x400) + (low - 0xDC00) + 0x10000
}
if (code >= 0xDC00 && code <= 0xDFFF) {
// Low surrogate
// This is just a low surrogate with no preceding high surrogate,
// so we return its value;
return code;
// we could also throw an error as it is not a complete character,
// but someone may want to know
}
return code
}
function inetNtop (a) {
var i = 0;
var m = '';
var c = [];
a += '';
if (a.length === 4) {
// IPv4
return [
a.charCodeAt(0),
a.charCodeAt(1),
a.charCodeAt(2),
a.charCodeAt(3)
].join('.');
} else if (a.length === 16) {
// IPv6
for (i = 0; i < 16; i++) {
c.push(((a.charCodeAt(i++) << 8) + a.charCodeAt(i)).toString(16));
}
return c.join(':')
.replace(/((^|:)0(?=:|$))+:?/g, function (t) {
m = (t.length > m.length) ? t : m;
return t;
})
.replace(m || ' ', '::');
} else {
// Invalid length
return false;
}
}
function inetPton(a) {
var r;
var m;
var x;
var i;
var j;
var f = String.fromCharCode;
// IPv4
m = a.match(/^(?:\d{1,3}(?:\.|$)){4}/);
if (m) {
m = m[0].split('.');
m = f(m[0]) + f(m[1]) + f(m[2]) + f(m[3]);
// Return if 4 bytes, otherwise false.
return m.length === 4 ? m : false;
}
r = /^((?:[\da-f]{1,4}(?::|)){0,8})(::)?((?:[\da-f]{1,4}(?::|)){0,8})$/;
// IPv6
m = a.match(r);
if (m) {
// Translate each hexadecimal value.
for (j = 1; j < 4; j++) {
// Indice 2 is :: and if no length, continue.
if (j === 2 || m[j].length === 0) {
continue;
}
m[j] = m[j].split(':');
for (i = 0; i < m[j].length; i++) {
m[j][i] = parseInt(m[j][i], 16);
// Would be NaN if it was blank, return false.
if (isNaN(m[j][i])) {
// Invalid IP.
return false;
}
m[j][i] = f(m[j][i] >> 8) + f(m[j][i] & 0xFF);
}
m[j] = m[j].join('');
}
x = m[1].length + m[3].length;
if (x === 16) {
return m[1] + m[3];
} else if (x < 16 && m[2].length > 0) {
return m[1] + (new Array(16 - x + 1))
.join('\x00') + m[3];
}
}
// Invalid IP
return false
}
class IpAddress {
constructor(addressFamily, address) {
console.log('ip address: ', addressFamily, address);
this.addressFamily = addressFamily;
this.address = address;
}
str() {
return inetNtop(this.address);
}
}
class IpPrefix {
constructor(addressFamily, prefix) {
this.addressFamily = addressFamily;
if (this.addressFamily === AF_INET) {
this.addressLength = 32;
} else if (this.addressFamily == AF_INET6) {
this.addressLength = 128;
} else {
throw Error(`invalid address family: ${addressFamily}`);
}
const values = prefix.split('/');
console.log(`split prefix: ${values}`);
if (values.length > 2) {
throw Error(`invalid prefix: ${prefix}`);
}
if (values.length === 2) {
this.prefixLength = parseInt(values[1]);
} else {
this.prefixLength = this.addressLength;
}
this.prefix = inetPton(values[0]);
if (this.addressLength > this.prefixLength) {
const addressBits = this.addressLength - this.prefixLength;
let netMask = ((1 << this.prefixLength) - 1) << addressBits;
prefix = '';
//in xrange(-1, -(addrbits >> 3) - 2, -1)
const stopValue = -(addressBits) - 2;
for (let i = -1; i > stopValue; --i) {
prefix = String.fromCharCode(ord(this.prefix[i]) & (netMask & 0xff)) + prefix;
netMask >>= 8;
}
this.prefix = this.prefix.slice(0, stopValue) + prefix;
}
}
getAddress(id) {
if (id in [-1, 0, 1] && this.addressLength === this.prefixLength) {
return new IpAddress(this.addressFamily, this.prefix);
}
const value = (1 << (this.addressLength - this.prefixLength)) - 1;
console.log(`address length(${this.addressLength}) prefix length(${this.prefixLength}) value(${value})`);
if (id === 0 || id > value || (this.addressFamily === AF_INET && id === value)) {
throw Error(`invalid id for prefix ${this.prefix}: ${id}`);
}
let address = '';
let prefixEndpoint = -1;
console.log('stop condition: ', -(this.addressLength >> 3) - 1);
for (let i = -1; i > -(this.addressLength >> 3) - 1; --i) {
console.log('i: ', i);
prefixEndpoint = i;
address = String.fromCharCode(ord(this.prefix[i]) | (id & 0xff)) + address;
console.log('address: ', address);
id >>= 8;
console.log('id: ', id);
if (!id) {
break
}
}
address = this.prefix.slice(0, prefixEndpoint) + address;
return new IpAddress(this.addressFamily, address);
}
}

View file

@ -1,25 +1,52 @@
const Ip4Prefix = '10.0.0.1/24';
const Ip6Prefix = '2001::/64';
const PtpNode = 12;
const NodeTypes = {
// default router
0: {
name: 'node'
name: 'node',
display: 'Default'
},
// switch
4: {
name: 'switch'
name: 'switch',
display: 'Switch'
},
// hub
5: {
name: 'hub'
name: 'hub',
display: 'Hub'
},
// wlan
6: {
name: 'wlan'
name: 'wlan',
display: 'WLAN'
},
12: {
name: 'ptp',
display: 'PTP'
}
};
function getNodeType(nodeType) {
return NodeTypes[nodeType];
}
const NodeIcons = {
router: 'static/router.svg',
host: 'static/host.gif',
PC: 'static/pc.gif',
mdr: 'static/mdr.svg',
switch: 'static/lanswitch.svg',
hub: 'static/hub.svg',
wlan: 'static/wlan.gif'
};
class CoreNode {
constructor(id, name, x, y) {
constructor(id, type, name, x, y) {
this.id = id;
this.type = type;
this.name = name;
this.model = null;
this.canvas = null;
@ -32,35 +59,54 @@ class CoreNode {
this.lon = null;
this.alt = null;
this.emulation_id = null;
this.emulation_server = null;
this.emulation_server = null
this.interfaces = {};
}
getNetworkNode() {
let iconName = getNodeType(this.type).name;
if (this.type === 0) {
iconName = this.model;
}
const icon = NodeIcons[iconName];
return {
id: this.id,
x: this.x,
y: this.y,
label: this.name,
node: this
coreNode: this,
//color: '#FFF',
//shape: 'image',
//shapeProperties: {
// useBorderWithImage: true
//},
//image: nodeMode.image,
//type: nodeMode.nodeType
shape: 'image',
image: icon
};
}
json() {
return {
id: this.id,
type: this.type,
name: this.name,
model: this.model,
x: this.x,
y: this.y,
lat: this.lat,
lon: this.lon,
alt: this.alt
}
}
}
class CoreNetwork {
constructor(elementId) {
this.nodeType = NodeTypes['0'];
this.nodeModel = null;
constructor(elementId, coreRest) {
this.coreRest = coreRest;
this.nodeType = 0;
this.nodeModel = 'router';
this.nodeId = 0;
this.container = document.getElementById(elementId);
this.nodes = new vis.DataSet();
this.edges = new vis.DataSet();
this.links = {};
this.networkData = {
nodes: this.nodes,
edges: this.edges
@ -88,18 +134,120 @@ class CoreNetwork {
this.edges.on('add', this.addEdge.bind(this));
}
getCoreNodes() {
const coreNodes = [];
for (let node of this.nodes.get()) {
coreNodes.push(node.coreNode.json());
}
return coreNodes;
}
addCoreNode(node) {
const position = node.position;
const coreNode = new CoreNode(node.id, node.type, node.name, position.x, position.y);
coreNode.model = node.model;
this.nodes.add(coreNode.getNetworkNode());
}
nextNodeId() {
this.nodeId += 1;
return this.nodeId;
}
joinedSessions(nodes) {
const self = this;
for (let node of nodes) {
if (node.type === PtpNode) {
continue;
}
this.addCoreNode(node);
}
for (let node of nodes) {
if (![4, 5, 6, 12].includes(node.type)) {
continue;
}
this.coreRest.getLinks(node.id)
.then(function(response) {
console.log('link response: ', response);
for (let linkData of response.links) {
self.createEdgeFromLink(linkData);
}
})
.catch(function(err) {
console.log('get link error: ', err);
});
}
if (nodes.length) {
this.nodeId = Math.max.apply(Math, nodes.map(function (node) {
return node.id
}));
} else {
this.nodeId = 0;
}
}
createEdgeFromLink(linkData) {
const fromNode = this.nodes.get(linkData.node1_id).coreNode;
const toNode = this.nodes.get(linkData.node2_id).coreNode;
const linkId = `${fromNode.id}-${toNode.id}`;
const interfaceOne = {
id: linkData.interface1_id,
ip4: linkData.interface1_ip4,
ip4mask: linkData.interface1_ip4_mask,
ip6: linkData.interface1_ip6,
ip6mask: linkData.interface1_ip6_mask
};
fromNode.interfaces[linkData.interface1_id] = interfaceOne;
const interfaceTwo = {
id: linkData.interface2_id,
ip4: linkData.interface2_ip4,
ip4mask: linkData.interface2_ip4_mask,
ip6: linkData.interface2_ip6,
ip6mask: linkData.interface2_ip6_mask
};
toNode.interfaces[linkData.interface2_id] = interfaceTwo;
this.links[linkId] = {
node_one: fromNode.id,
node_two: toNode.id,
interface_one: interfaceOne,
interface_two: interfaceTwo
};
const edge = {from: fromNode.id, to: toNode.id};
this.edges.add(edge);
}
async start() {
const nodes = coreNetwork.getCoreNodes();
for (let node of nodes) {
const response = await coreRest.createNode(node);
console.log('created node: ', response);
}
for (let linkId in this.links) {
const link = this.links[linkId];
const response = await coreRest.createLink(link);
console.log('created link: ', response);
}
return await coreRest.setSessionState(SessionStates.instantiation);
}
addNode(properties) {
console.log('add node event: ', properties);
if (properties.nodes.length === 0) {
const {x, y} = properties.pointer.canvas;
const nodeId = this.nextNodeId();
const name = `${this.nodeType.name}${nodeId}`;
const coreNode = new CoreNode(nodeId, name, x, y);
const nodeTypeData = getNodeType(this.nodeType);
const name = `${nodeTypeData.name}${nodeId}`;
const coreNode = new CoreNode(nodeId, this.nodeType, name, x, y);
coreNode.model = this.nodeModel;
this.nodes.add(coreNode.getNetworkNode());
console.log('added node: ', coreNode.getNetworkNode());
@ -115,10 +263,55 @@ class CoreNetwork {
this.edges.remove(edge.id);
}
const fromNode = this.nodes.get(edge.from).coreNode;
const toNode = this.nodes.get(edge.to).coreNode;
this.addEdgeLink(edge, fromNode, toNode)
.then(function() {
console.log('create edge link success!');
})
.catch(function(err) {
console.log('create link error: ', err);
});
// keep edge mode enabled
setTimeout(() => this.network.addEdgeMode(), 250);
}
async addEdgeLink(edge, fromNode, toNode) {
const fromIps = await this.coreRest.getNodeIps(fromNode.id, Ip4Prefix, Ip6Prefix);
const toIps = await this.coreRest.getNodeIps(toNode.id, Ip4Prefix, Ip6Prefix);
console.log('link ips: ', fromIps, toIps);
const linkId = `${fromNode.id}-${toNode.id}`;
const interfaceOneId =Object.keys(fromNode.interfaces).length;
const interfaceOne = {
id: interfaceOneId,
ip4: fromIps.ip4,
ip4mask: fromIps.ip4mask,
ip6: fromIps.ip6,
ip6mask: fromIps.ip6mask
};
fromNode.interfaces[interfaceOneId] = interfaceOne;
const interfaceTwoId = Object.keys(toNode.interfaces).length;
const interfaceTwo = {
id: interfaceTwoId,
ip4: toIps.ip4,
ip4mask: toIps.ip4mask,
ip6: toIps.ip6,
ip6mask: toIps.ip6mask
};
toNode.interfaces[interfaceTwoId] = interfaceTwo;
this.links[linkId] = {
node_one: fromNode.id,
node_two: toNode.id,
interface_one: interfaceOne,
interface_two: interfaceTwo
};
}
linkMode(enabled) {
console.log('link mode:', enabled);
if (enabled) {
@ -129,7 +322,7 @@ class CoreNetwork {
}
setNodeMode(nodeType, model) {
this.nodeType = NodeTypes[nodeType];
this.nodeType = nodeType;
this.nodeModel = model || null;
}
}

View file

@ -1,9 +1,106 @@
const SessionStates = {
definition: 1,
configuration: 2,
instantiation: 3,
runtime: 4,
dataCollect: 5,
shutdown: 6
};
const SessionStateDisplay = {
1: 'Definition',
2: 'Configuration',
3: 'Instantiation',
4: 'Runtime',
5: 'Data Collect',
6: 'Shutdown'
};
async function sendJson(url, data, type) {
return await $.ajax({
url,
type,
data: JSON.stringify(data),
contentType: 'application/json',
dataType: 'json'
});
}
async function postJson(url, data) {
console.log('POST: ', url);
return await sendJson(url, data, 'POST');
}
async function putJson(url, data) {
console.log('PUT: ', url);
return await sendJson(url, data, 'PUT');
}
class CoreRest {
constructor() {
this.currentSession = null;
}
async sessions(callback) {
const response = await $.getJSON('/sessions');
callback(response);
getStateName(state) {
return SessionStateDisplay[state];
}
async getSession() {
return await $.getJSON(`/sessions/${this.currentSession}`);
}
async getSessions() {
return await $.getJSON('/sessions');
}
async createSession() {
return await postJson('/sessions');
}
async shutdownSession() {
return await this.setSessionState(SessionStates.shutdown);
}
async setSessionState(state) {
return await putJson(`/sessions/${this.currentSession}/state`, {state})
}
async createNode(node) {
return await postJson(`/sessions/${this.currentSession}/nodes`, node);
}
async createLink(link) {
return await postJson(`/sessions/${this.currentSession}/links`, link);
}
async getLinks(nodeId) {
return await $.getJSON(`/sessions/${this.currentSession}/nodes/${nodeId}/links`)
}
async getNodeIps(nodeId, ip4Prefix, ip6Prefix) {
return await postJson('/ips', {
id: nodeId,
ip4: ip4Prefix,
ip6: ip6Prefix
});
}
async retrieveSession() {
let response = await this.getSessions();
const sessions = response.sessions;
console.log('current sessions: ', sessions);
const session = {id: 0, state: 0};
if (sessions.length) {
this.currentSession = sessions[0].id;
session.state = sessions[0].state;
} else {
response = await this.createSession();
this.currentSession = response.id;
session.state = response.state;
}
session.id = this.currentSession;
return session;
}
}

BIN
webapp/static/host.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

197
webapp/static/hub.svg Normal file
View file

@ -0,0 +1,197 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="146"
height="100"
id="svg3868"
version="1.1"
inkscape:version="0.47 r22583"
sodipodi:docname="hub.svg">
<defs
id="defs3870">
<linearGradient
id="linearGradient5149">
<stop
id="stop5151"
offset="0"
style="stop-color:#5dacd1;stop-opacity:1;" />
<stop
id="stop5153"
offset="1"
style="stop-color:#1b4a78;stop-opacity:1;" />
</linearGradient>
<linearGradient
id="linearGradient4902">
<stop
style="stop-color:#484848;stop-opacity:1;"
offset="0"
id="stop4904" />
<stop
style="stop-color:#8f8f90;stop-opacity:0;"
offset="1"
id="stop4906" />
</linearGradient>
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 526.18109 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="744.09448 : 526.18109 : 1"
inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
id="perspective3876" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient12001"
id="linearGradient4908"
x1="5.8083773"
y1="68.180191"
x2="84.600281"
y2="68.180191"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.269166,0,0,1.2912385,-2.3717949,931.82545)" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient12001"
id="linearGradient5039"
x1="105"
y1="55"
x2="140"
y2="55"
gradientUnits="userSpaceOnUse" />
<inkscape:perspective
id="perspective5049"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient12001"
id="linearGradient3844"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.471308,0,0,0.471308,9.3066001,-238.48173)"
x1="175.71875"
y1="737.01562"
x2="470.00089"
y2="737.01562" />
<linearGradient
id="linearGradient12001">
<stop
style="stop-color:#1b4a78;stop-opacity:1;"
offset="0"
id="stop12003" />
<stop
style="stop-color:#5dacd1;stop-opacity:1;"
offset="1"
id="stop12005" />
</linearGradient>
<inkscape:perspective
id="perspective5135"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<inkscape:perspective
id="perspective5165"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="1"
inkscape:cx="91.162404"
inkscape:cy="35.126778"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="914"
inkscape:window-height="668"
inkscape:window-x="2157"
inkscape:window-y="214"
inkscape:window-maximized="0">
<inkscape:grid
type="xygrid"
id="grid4935"
empspacing="5"
visible="true"
enabled="true"
snapvisiblegridlinesonly="true"
spacingx="0.5px"
spacingy="0.5px" />
</sodipodi:namedview>
<metadata
id="metadata3873">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(0,-952.36218)">
<rect
style="fill:url(#linearGradient4908);fill-opacity:1.0;stroke-width:0;stroke-miterlimit:4;stroke-dasharray:none"
id="rect4390"
width="100"
height="45"
x="5"
y="997.36218" />
<path
style="fill:url(#linearGradient5039);stroke:#000000;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none;fill-opacity:1.0"
d="m 105,45 35,-40 0,45 -35,40 0,-45 z"
id="path5031"
transform="translate(0,952.36218)"
sodipodi:nodetypes="ccccc" />
<path
style="fill:#3a78a0;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;fill-opacity:1"
d="M 105,45 5,45 40,5 140,5 105,45 z"
id="path5079"
transform="translate(0,952.36218)" />
<path
style="fill:#f2fdff;fill-opacity:0.70980392000000003;stroke:none;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
d="m 32.5,979.86218 7.5,-7.5 77.5,0 -7.5,7.5 -77.5,0 z"
id="path5255" />
<path
style="fill:#f2fdff;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;fill-opacity:0.70980394"
d="m 45,27.5 -7.5,7.5 10,0 7.5,-7.5 -10,0 z"
id="path5259"
transform="translate(0,952.36218)" />
<path
id="path5261"
d="m 77.5,979.86218 -7.5,7.5 10,0 7.5,-7.5 -10,0 z"
style="fill:#f2fdff;fill-opacity:0.70980392;stroke:none" />
<path
style="fill:#f2fdff;fill-opacity:0.70980392;stroke:none"
d="m 70,964.86218 -7.5,7.5 10,0 7.5,-7.5 -10,0 z"
id="path5263" />
<path
id="path5265"
d="m 102.5,964.86218 -7.5,7.5 10,0 7.5,-7.5 -10,0 z"
style="fill:#f2fdff;fill-opacity:0.70980392;stroke:none" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 6.4 KiB

190
webapp/static/lanswitch.svg Normal file
View file

@ -0,0 +1,190 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="146"
height="100"
id="svg3868"
version="1.1"
inkscape:version="0.47 r22583"
sodipodi:docname="switch.svg">
<defs
id="defs3870">
<linearGradient
id="linearGradient5149">
<stop
id="stop5151"
offset="0"
style="stop-color:#5dacd1;stop-opacity:1;" />
<stop
id="stop5153"
offset="1"
style="stop-color:#1b4a78;stop-opacity:1;" />
</linearGradient>
<linearGradient
id="linearGradient4902">
<stop
style="stop-color:#484848;stop-opacity:1;"
offset="0"
id="stop4904" />
<stop
style="stop-color:#8f8f90;stop-opacity:0;"
offset="1"
id="stop4906" />
</linearGradient>
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 526.18109 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="744.09448 : 526.18109 : 1"
inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
id="perspective3876" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient12001"
id="linearGradient4908"
x1="5.8083773"
y1="68.180191"
x2="84.600281"
y2="68.180191"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.269166,0,0,1.2912385,-2.3717949,931.82545)" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient12001"
id="linearGradient5039"
x1="105"
y1="55"
x2="140"
y2="55"
gradientUnits="userSpaceOnUse" />
<inkscape:perspective
id="perspective5049"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient12001"
id="linearGradient3844"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.471308,0,0,0.471308,9.3066001,-238.48173)"
x1="175.71875"
y1="737.01562"
x2="470.00089"
y2="737.01562" />
<linearGradient
id="linearGradient12001">
<stop
style="stop-color:#1b4a78;stop-opacity:1;"
offset="0"
id="stop12003" />
<stop
style="stop-color:#5dacd1;stop-opacity:1;"
offset="1"
id="stop12005" />
</linearGradient>
<inkscape:perspective
id="perspective5135"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<inkscape:perspective
id="perspective5165"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="2.8284271"
inkscape:cx="91.162404"
inkscape:cy="35.126778"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="809"
inkscape:window-height="852"
inkscape:window-x="605"
inkscape:window-y="185"
inkscape:window-maximized="0">
<inkscape:grid
type="xygrid"
id="grid4935"
empspacing="5"
visible="true"
enabled="true"
snapvisiblegridlinesonly="true" />
</sodipodi:namedview>
<metadata
id="metadata3873">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(0,-952.36218)">
<rect
style="fill:url(#linearGradient4908);fill-opacity:1.0;stroke-width:0;stroke-miterlimit:4;stroke-dasharray:none"
id="rect4390"
width="100"
height="45"
x="5"
y="997.36218" />
<path
style="fill:url(#linearGradient5039);stroke:#000000;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none;fill-opacity:1.0"
d="m 105,45 35,-40 0,45 -35,40 0,-45 z"
id="path5031"
transform="translate(0,952.36218)"
sodipodi:nodetypes="ccccc" />
<path
style="fill:#3a78a0;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;fill-opacity:1"
d="M 105,45 5,45 40,5 140,5 105,45 z"
id="path5079"
transform="translate(0,952.36218)" />
<path
style="fill:#f2fdff;fill-opacity:0.71171169;stroke:none"
d="m 63.720704,982.3378 12.656877,-3.10116 12.656905,-3.10105 -3.523923,3.28427 18.978167,0.15164 -6.571234,6.1243 -18.978156,-0.15164 -3.523925,3.28426 -5.843452,-3.24896 -5.851259,-3.24166 z"
id="path13511" />
<path
style="fill:#f2fdff;fill-opacity:0.71171169;stroke:none"
d="M 80.174263,970.7443 74.367199,967.43074 68.560125,964.11719 65,967.36218 46.024691,967.0001 l -6.638732,6.05106 18.975309,0.36208 -3.560123,3.24499 12.690524,-2.96052 12.682595,-2.95341 z"
id="path13513" />
<path
id="path5195"
d="M 65.174263,985.7443 59.367199,982.43074 53.560125,979.11719 50,982.36218 31.024691,982.0001 l -6.638732,6.05106 18.975309,0.36208 -3.560123,3.24499 12.690524,-2.96052 12.682595,-2.95341 z"
style="fill:#f2fdff;fill-opacity:0.71171169;stroke:none" />
<path
id="path5209"
d="m 78.9675,967.75499 12.656877,-3.10116 12.656903,-3.10105 -3.52392,3.28427 18.97816,0.15164 -6.57123,6.1243 -18.978154,-0.15164 -3.523925,3.28426 -5.843452,-3.24896 -5.851259,-3.24166 z"
style="fill:#f2fdff;fill-opacity:0.71171169;stroke:none" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 6.5 KiB

178
webapp/static/mdr.svg Normal file
View file

@ -0,0 +1,178 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="146"
height="100"
id="svg13653"
sodipodi:version="0.32"
inkscape:version="0.47 r22583"
sodipodi:docname="router.svg"
version="1.0">
<defs
id="defs13655">
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 99.931252 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="199.10001 : 99.931252 : 1"
inkscape:persp3d-origin="99.550003 : 66.620834 : 1"
id="perspective3835" />
<linearGradient
id="linearGradient12828">
<stop
id="stop12830"
offset="0"
style="stop-color:#484849;stop-opacity:1;" />
<stop
style="stop-color:#434344;stop-opacity:1;"
offset="0"
id="stop12862" />
<stop
id="stop12832"
offset="1.0000000"
style="stop-color:#8f8f90;stop-opacity:0.0000000;" />
</linearGradient>
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient12828"
id="radialGradient13651"
cx="328.57144"
cy="602.7193"
fx="328.57144"
fy="602.7193"
r="147.14285"
gradientTransform="matrix(1,0,0,0.177184,0,495.9268)"
gradientUnits="userSpaceOnUse" />
<linearGradient
id="linearGradient12001">
<stop
style="stop-color:#1b4a78;stop-opacity:1;"
offset="0"
id="stop12003" />
<stop
style="stop-color:#5dacd1;stop-opacity:1;"
offset="1"
id="stop12005" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient12001"
id="linearGradient13633"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.471308,0,0,0.471308,118.8781,123.5182)"
x1="175.71875"
y1="737.01562"
x2="470.00089"
y2="737.01562" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient12001"
id="linearGradient3844"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.471308,0,0,0.471308,-45.6934,-239.9103)"
x1="175.71875"
y1="737.01562"
x2="470.00089"
y2="737.01562" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="1"
inkscape:cx="118.57814"
inkscape:cy="50.488033"
inkscape:document-units="px"
inkscape:current-layer="layer1"
inkscape:window-width="1280"
inkscape:window-height="949"
inkscape:window-x="1631"
inkscape:window-y="29"
showgrid="false"
inkscape:window-maximized="0" />
<metadata
id="metadata13658">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Capa 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-33.124945,-44.636248)">
<path
style="fill:url(#linearGradient3844);fill-opacity:1;stroke:none"
d="m 37.14136,72.27878 0,0.29457 c 0.006,-0.0975 0.0206,-0.19729 0.0295,-0.29457 l -0.0295,0 z m 138.62351,0 c 0.0302,0.33044 0.0589,0.66821 0.0589,1.00153 l 0,-1.00153 -0.0589,0 z m 0.0589,1.00153 c -1e-5,15.05224 -31.07495,27.26223 -69.35594,27.26223 -37.68286,1e-5 -68.3765,-11.82771 -69.32649,-26.55527 l 0,40.67979 c -0.0151,0.23376 -0.0147,0.45704 -0.0147,0.69223 0,0.22546 8.7e-4,0.45335 0.0147,0.67751 0.91151,14.74102 31.61889,26.59945 69.32649,26.59945 37.7076,0 68.41498,-11.85843 69.32648,-26.59945 l 0.0295,0 0,-0.50077 c 9.5e-4,-0.0587 0,-0.11794 0,-0.17674 0,-0.0588 9.4e-4,-0.11803 0,-0.17674 l 0,-41.90224 z"
id="path13626" />
<path
sodipodi:type="arc"
style="fill:#3a78a0;fill-opacity:1;stroke:none"
id="path11090"
sodipodi:cx="328.57144"
sodipodi:cy="602.7193"
sodipodi:rx="147.14285"
sodipodi:ry="26.071428"
d="m 475.71429,602.7193 c 0,14.39885 -65.87809,26.07143 -147.14285,26.07143 -81.26475,0 -147.14285,-11.67258 -147.14285,-26.07143 0,-14.39885 65.8781,-26.07143 147.14285,-26.07143 81.26476,0 147.14285,11.67258 147.14285,26.07143 z"
transform="matrix(0.471308,0,0,1.045917,-48.3838,-554.9944)" />
<g
id="g13565"
style="fill:#f2fdff;fill-opacity:0.71171169"
transform="matrix(0.84958,0.276715,-0.703617,0.334119,278.6313,-230.2001)">
<path
id="path13507"
d="m 328.66945,592.8253 -5.97867,10.35298 -5.97867,10.35297 6.18436,0 0,21.24074 11.53226,0 0,-21.24074 6.18435,0 -5.97867,-10.35297 -5.96496,-10.35298 z"
style="fill:#f2fdff;fill-opacity:0.71171169;stroke:none" />
<path
id="path13509"
d="m 328.66945,687.10951 -5.97867,-10.35298 -5.97867,-10.35297 6.18436,0 0,-21.24074 11.53226,0 0,21.24074 6.18435,0 -5.97867,10.35297 -5.96496,10.35298 z"
style="fill:#f2fdff;fill-opacity:0.71171169;stroke:none" />
<path
id="path13511"
d="m 333.74751,639.82449 10.35297,-5.97867 10.35297,-5.97867 0,6.18436 21.24074,0 0,11.53225 -21.24074,0 0,6.18436 -10.35297,-5.97867 -10.35297,-5.96496 z"
style="fill:#f2fdff;fill-opacity:0.71171169;stroke:none" />
<path
id="path13513"
d="m 323.35667,639.82449 -10.35297,-5.97867 -10.35298,-5.97867 0,6.18436 -21.24073,0 0,11.53225 21.24073,0 0,6.18436 10.35298,-5.97867 10.35297,-5.96496 z"
style="fill:#f2fdff;fill-opacity:0.71171169;stroke:none" />
</g>
<rect
style="fill:#f2fdff;fill-opacity:0.70980394;stroke:#000000;stroke-opacity:1"
id="rect6161"
width="91.923882"
height="37.476658"
x="52.679455"
y="60.048466"
transform="translate(33.124945,44.636248)"
rx="5.454824"
ry="5.454824" />
<text
xml:space="preserve"
style="font-size:32px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:DejaVu Sans;-inkscape-font-specification:Bitstream Charter Bold"
x="91.107697"
y="135.0903"
id="text6673"><tspan
sodipodi:role="line"
id="tspan6675"
x="91.107697"
y="135.0903">MDR</tspan></text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 6.8 KiB

BIN
webapp/static/pc.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

158
webapp/static/router.svg Normal file
View file

@ -0,0 +1,158 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="146"
height="100"
id="svg13653"
sodipodi:version="0.32"
inkscape:version="0.47 r22583"
sodipodi:docname="router.svg"
version="1.0">
<defs
id="defs13655">
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 99.931252 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="199.10001 : 99.931252 : 1"
inkscape:persp3d-origin="99.550003 : 66.620834 : 1"
id="perspective3835" />
<linearGradient
id="linearGradient12828">
<stop
id="stop12830"
offset="0"
style="stop-color:#484849;stop-opacity:1;" />
<stop
style="stop-color:#434344;stop-opacity:1;"
offset="0"
id="stop12862" />
<stop
id="stop12832"
offset="1.0000000"
style="stop-color:#8f8f90;stop-opacity:0.0000000;" />
</linearGradient>
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient12828"
id="radialGradient13651"
cx="328.57144"
cy="602.7193"
fx="328.57144"
fy="602.7193"
r="147.14285"
gradientTransform="matrix(1,0,0,0.177184,0,495.9268)"
gradientUnits="userSpaceOnUse" />
<linearGradient
id="linearGradient12001">
<stop
style="stop-color:#1b4a78;stop-opacity:1;"
offset="0"
id="stop12003" />
<stop
style="stop-color:#5dacd1;stop-opacity:1;"
offset="1"
id="stop12005" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient12001"
id="linearGradient13633"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.471308,0,0,0.471308,118.8781,123.5182)"
x1="175.71875"
y1="737.01562"
x2="470.00089"
y2="737.01562" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient12001"
id="linearGradient3844"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.471308,0,0,0.471308,-45.6934,-239.9103)"
x1="175.71875"
y1="737.01562"
x2="470.00089"
y2="737.01562" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="2.8"
inkscape:cx="118.57814"
inkscape:cy="50.488033"
inkscape:document-units="px"
inkscape:current-layer="layer1"
inkscape:window-width="1280"
inkscape:window-height="949"
inkscape:window-x="289"
inkscape:window-y="87"
showgrid="false"
inkscape:window-maximized="0" />
<metadata
id="metadata13658">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Capa 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-33.124945,-44.636248)">
<path
style="fill:url(#linearGradient3844);fill-opacity:1;stroke:none"
d="m 37.14136,72.27878 0,0.29457 c 0.006,-0.0975 0.0206,-0.19729 0.0295,-0.29457 l -0.0295,0 z m 138.62351,0 c 0.0302,0.33044 0.0589,0.66821 0.0589,1.00153 l 0,-1.00153 -0.0589,0 z m 0.0589,1.00153 c -1e-5,15.05224 -31.07495,27.26223 -69.35594,27.26223 -37.68286,1e-5 -68.3765,-11.82771 -69.32649,-26.55527 l 0,40.67979 c -0.0151,0.23376 -0.0147,0.45704 -0.0147,0.69223 0,0.22546 8.7e-4,0.45335 0.0147,0.67751 0.91151,14.74102 31.61889,26.59945 69.32649,26.59945 37.7076,0 68.41498,-11.85843 69.32648,-26.59945 l 0.0295,0 0,-0.50077 c 9.5e-4,-0.0587 0,-0.11794 0,-0.17674 0,-0.0588 9.4e-4,-0.11803 0,-0.17674 l 0,-41.90224 z"
id="path13626" />
<path
sodipodi:type="arc"
style="fill:#3a78a0;fill-opacity:1;stroke:none"
id="path11090"
sodipodi:cx="328.57144"
sodipodi:cy="602.7193"
sodipodi:rx="147.14285"
sodipodi:ry="26.071428"
d="m 475.71429,602.7193 c 0,14.39885 -65.87809,26.07143 -147.14285,26.07143 -81.26475,0 -147.14285,-11.67258 -147.14285,-26.07143 0,-14.39885 65.8781,-26.07143 147.14285,-26.07143 81.26476,0 147.14285,11.67258 147.14285,26.07143 z"
transform="matrix(0.471308,0,0,1.045917,-48.3838,-554.9944)" />
<g
id="g13565"
style="fill:#f2fdff;fill-opacity:0.71171169"
transform="matrix(0.84958,0.276715,-0.703617,0.334119,278.6313,-230.2001)">
<path
id="path13507"
d="m 328.66945,592.8253 -5.97867,10.35298 -5.97867,10.35297 6.18436,0 0,21.24074 11.53226,0 0,-21.24074 6.18435,0 -5.97867,-10.35297 -5.96496,-10.35298 z"
style="fill:#f2fdff;fill-opacity:0.71171169;stroke:none" />
<path
id="path13509"
d="m 328.66945,687.10951 -5.97867,-10.35298 -5.97867,-10.35297 6.18436,0 0,-21.24074 11.53226,0 0,21.24074 6.18435,0 -5.97867,10.35297 -5.96496,10.35298 z"
style="fill:#f2fdff;fill-opacity:0.71171169;stroke:none" />
<path
id="path13511"
d="m 333.74751,639.82449 10.35297,-5.97867 10.35297,-5.97867 0,6.18436 21.24074,0 0,11.53225 -21.24074,0 0,6.18436 -10.35297,-5.97867 -10.35297,-5.96496 z"
style="fill:#f2fdff;fill-opacity:0.71171169;stroke:none" />
<path
id="path13513"
d="m 323.35667,639.82449 -10.35297,-5.97867 -10.35298,-5.97867 0,6.18436 -21.24073,0 0,11.53225 21.24073,0 0,6.18436 10.35298,-5.97867 10.35297,-5.96496 z"
style="fill:#f2fdff;fill-opacity:0.71171169;stroke:none" />
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 6.1 KiB

File diff suppressed because one or more lines are too long

BIN
webapp/static/wlan.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 259 B