diff --git a/web/ons-demo/js/app.js b/web/ons-demo/js/app.js
index 5c92490..f7eb5b4 100644
--- a/web/ons-demo/js/app.js
+++ b/web/ons-demo/js/app.js
@@ -1,1206 +1,9 @@
 /*global d3, document∆*/
 
-d3.selection.prototype.moveToFront = function() {
-  return this.each(function(){
-    this.parentNode.appendChild(this);
-  });
-};
-
-var line = d3.svg.line()
-    .x(function(d) {
-    	return d.x;
-    })
-    .y(function(d) {
-    	return d.y;
-    });
-
-var model;
-var svg;
-var updateTopology;
-var pendingLinks = {};
-var selectedFlows = [];
-
-var pendingTimeout = 30000;
-
-var colors = [
-	'color1',
-	'color2',
-	'color3',
-	'color4',
-	'color7',
-	'color8',
-	'color9',
-//	'color11',
-	'color12'
-];
-colors.reverse();
-
-var controllerColorMap = {};
-
-function setPending(selection) {
-	selection.classed('pending', false);
-	setTimeout(function () {
-		selection.classed('pending', true);
-	})
-}
-
-function createTopologyView() {
-
-	window.addEventListener('resize', function () {
-		// this is too slow. instead detect first resize event and hide the paths that have explicit matrix applied
-		// either that or is it possible to position the paths so they get the automatic transform as well?
-//		updateTopology();
-	});
-
-	var svg = d3.select('#svg-container').append('svg:svg');
-
-	svg.append("svg:defs").append("svg:marker")
-	    .attr("id", "arrow")
-	    .attr("viewBox", "0 -5 10 10")
-	    .attr("refX", -1)
-	    .attr("markerWidth", 5)
-	    .attr("markerHeight", 5)
-	    .attr("orient", "auto")
-	  .append("svg:path")
-	    .attr("d", "M0,-3L10,0L0,3");
-
-	return svg.append('svg:svg').attr('id', 'viewBox').attr('viewBox', '0 0 1000 1000').attr('preserveAspectRatio', 'none').
-			attr('id', 'viewbox').append('svg:g').attr('transform', 'translate(500 500)');
-}
-
-function updateSelectedFlowsTopology() {
-	// DRAW THE FLOWS
-	var topologyFlows = [];
-	selectedFlows.forEach(function (flow) {
-		if (flow) {
-			topologyFlows.push(flow);
-		}
-	});
-
-	var flows = d3.select('svg').selectAll('.flow').data(topologyFlows);
-
-	flows.enter().append("svg:path").attr('class', 'flow')
-		.attr('stroke-dasharray', '4, 10')
-		.append('svg:animate')
-		.attr('attributeName', 'stroke-dashoffset')
-		.attr('attributeType', 'xml')
-		.attr('from', '500')
-		.attr('to', '-500')
-		.attr('dur', '20s')
-		.attr('repeatCount', 'indefinite');
-
-	flows.exit().remove();
-
-	flows.attr('d', function (d) {
-			if (!d) {
-				return;
-			}
-			var pts = [];
-			if (!d.dataPath.flowEntries) {
-				// create a temporary vector to indicate the pending flow
-				var s1 = d3.select(document.getElementById(d.srcDpid));
-				var s2 = d3.select(document.getElementById(d.dstDpid));
-
-				var pt1 = document.querySelector('svg').createSVGPoint();
-				pt1.x = s1.attr('x');
-				pt1.y = s1.attr('y');
-				pt1 = pt1.matrixTransform(s1[0][0].getCTM());
-				pts.push(pt1);
-
-				var pt2 = document.querySelector('svg').createSVGPoint();
-				pt2.x = s2.attr('x');
-				pt2.y = s2.attr('y');
-				pt2 = pt2.matrixTransform(s2[0][0].getCTM());
-				pts.push(pt2);
-
-			} else {
-				d.dataPath.flowEntries.forEach(function (flowEntry) {
-					var s = d3.select(document.getElementById(flowEntry.dpid.value));
-					// s[0] is null if the flow entry refers to a non-existent switch
-					if (s[0][0]) {
-						var pt = document.querySelector('svg').createSVGPoint();
-						pt.x = s.attr('x');
-						pt.y = s.attr('y');
-						pt = pt.matrixTransform(s[0][0].getCTM());
-						pts.push(pt);
-					} else {
-						console.log('flow refers to non-existent switch: ' + flowEntry.dpid.value);
-					}
-				});
-			}
-			if (pts.length) {
-				return line(pts);
-			} else {
-				return "M0,0";
-			}
-		})
-		.attr('id', function (d) {
-			if (d) {
-				return makeFlowKey(d);
-			}
-		})
-		.classed('pending', function (d) {
-			return d && (d.createPending || d.deletePending);
-		});
-
-	// "marching ants"
-	flows.select('animate').attr('from', 500);
-
-}
-
-function updateSelectedFlowsTable() {
-	function rowEnter(d) {
-		var row = d3.select(this);
-		row.append('div').classed('deleteFlow', true);
-		row.append('div').classed('flowId', true);
-		row.append('div').classed('srcDPID', true);
-		row.append('div').classed('dstDPID', true);
-		row.append('div').classed('iperf', true);
-
-		row.select('.iperf')
-			.append('div')
-			.attr('class', 'iperf-container')
-			.append('svg:svg')
-			.attr('viewBox', '0 0 1000 32')
-			.attr('preserveAspectRatio', 'none')
-			.append('svg:g')
-			.append('svg:path')
-			.attr('class', 'iperfdata');
-
-		row.on('mouseover', function (d) {
-			if (d) {
-				var path = document.getElementById(makeFlowKey(d));
-				d3.select(path).classed('highlight', true);
-			}
-		});
-		row.on('mouseout', function (d) {
-			if (d) {
-				var path = document.getElementById(makeFlowKey(d));
-				d3.select(path).classed('highlight', false);
-			}
-		});
-	}
-
-	function rowUpdate(d) {
-		var row = d3.select(this);
-		row.attr('id', function (d) {
-			if (d) {
-				return makeSelectedFlowKey(d);
-			}
-		});
-
-		if (!d || !hasIPerf(d)) {
-			row.select('.iperfdata')
-				.attr('d', 'M0,0');
-		}
-
-		row.select('.deleteFlow').on('click', function () {
-			deselectFlow(d);
-		});
-		row.on('dblclick', function () {
-			if (d) {
-				var prompt = 'Delete flow ' + d.flowId + '?';
-				if (confirm(prompt)) {
-					deleteFlow(d);
-					d.deletePending = true;
-					updateSelectedFlows();
-
-					setTimeout(function () {
-						d.deletePending = false;
-						updateSelectedFlows();
-					}, pendingTimeout)
-				};
-			}
-		});
-
-		row.select('.flowId')
-			.text(function (d) {
-				if (d) {
-					if (d.flowId) {
-						return d.flowId;
-					} else {
-						return '0x--';
-					}
-				}
-			})
-			.classed('pending', function (d) {
-				return d && (d.createPending || d.deletePending);
-			});
-
-		row.select('.srcDPID')
-			.text(function (d) {
-				if (d) {
-					return d.srcDpid;
-				}
-			});
-
-		row.select('.dstDPID')
-			.text(function (d) {
-				if (d) {
-					return d.dstDpid;
-				}
-			});
-	}
-
-	var flows = d3.select('#selectedFlows')
-		.selectAll('.selectedFlow')
-		.data(selectedFlows);
-
-	flows.enter()
-		.append('div')
-		.classed('selectedFlow', true)
-		.each(rowEnter);
-
-	flows.each(rowUpdate);
-
-	flows.exit().remove();
-}
-
-// TODO: cancel the interval when the flow is desel
-function startIPerfForFlow(flow) {
-	var duration = 10000; // seconds
-	var interval = 100; // ms. this is defined by the server
-	var updateRate = 2000; // ms
-	var pointsToDisplay = 1000;
-
-	function makePoints() {
-		var pts = [];
-		var i;
-		for (i=0; i < pointsToDisplay; ++i) {
-			var sample = flow.iperfData.samples[i];
-			var height = 30 * sample/1000000;
-			if (height > 30)
-				height = 30;
-			pts.push({
-				x: i * 1000/(pointsToDisplay-1),
-				y: 32 - height
-			})
-		}
-		return pts;
-	}
-
-	if (flow.flowId) {
-		console.log('starting iperf for: ' + flow.flowId);
-		startIPerf(flow, duration, updateRate/interval);
-		flow.iperfDisplayInterval = setInterval(function () {
-			if (flow.iperfData) {
-				while (flow.iperfData.samples.length < pointsToDisplay) {
-					flow.iperfData.samples.push(0);
-				}
-				var iperfPath = d3.select(document.getElementById(makeSelectedFlowKey(flow))).select('path');
-				iperfPath.attr('d', line(makePoints()));
-				flow.iperfData.samples.shift();
-			}
-
-
-		}, interval);
-		flow.iperfFetchInterval = setInterval(function () {
-			getIPerfData(flow, function (data) {
-				try {
-					if (!flow.iperfData) {
-						flow.iperfData = {
-							samples: []
-						};
-						var i;
-						for (i = 0; i < pointsToDisplay; ++i) {
-							flow.iperfData.samples.push(0);
-						}
-					}
-
-					var iperfData = JSON.parse(data);
-
-//				console.log(iperfData.timestamp);
-
-					// if the data is fresh
-					if (flow.iperfData.timestamp && iperfData.timestamp != flow.iperfData.timestamp) {
-
-						while (flow.iperfData.samples.length > pointsToDisplay + iperfData.samples.length) {
-							flow.iperfData.samples.shift();
-						}
-
-						iperfData.samples.forEach(function (s) {
-							flow.iperfData.samples.push(s);
-						});
-					}
-					flow.iperfData.timestamp = iperfData.timestamp;
-				} catch (e) {
-					console.log('bad iperf data: ' + data);
-				}
-//				console.log(data);
-			});
-		}, updateRate/2); // over sample to avoid gaps
-	}
-}
-
-function updateSelectedFlows() {
-	// make sure that all of the selected flows are either
-	// 1) valid (meaning they are in the latest list of flows)
-	// 2) pending
-	if (model) {
-		var flowMap = {};
-		model.flows.forEach(function (flow) {
-			flowMap[makeFlowKey(flow)] = flow;
-		});
-
-		var newSelectedFlows = [];
-		selectedFlows.forEach(function (flow) {
-			if (flow) {
-				var liveFlow = flowMap[makeFlowKey(flow)];
-				if (liveFlow) {
-					newSelectedFlows.push(liveFlow);
-					liveFlow.deletePending = flow.deletePending;
-					liveFlow.iperfFetchInterval = flow.iperfFetchInterval;
-					liveFlow.iperfDisplayInterval = flow.iperfDisplayInterval;
-				} else if (flow.createPending) {
-					newSelectedFlows.push(flow);
-				} else if (hasIPerf(flow)) {
-					clearIPerf(flow);
-				}
-			}
-		});
-		selectedFlows = newSelectedFlows;
-	}
-	selectedFlows.forEach(function (flow) {
-		if (!hasIPerf(flow)) {
-			startIPerfForFlow(flow);
-		}
-	});
-	while (selectedFlows.length < 3) {
-		selectedFlows.push(null);
-	}
-
-	updateSelectedFlowsTable();
-	updateSelectedFlowsTopology();
-}
-
-function selectFlow(flow) {
-	var flowKey = makeFlowKey(flow);
-	var alreadySelected = false;
-	selectedFlows.forEach(function (f) {
-		if (f && makeFlowKey(f) === flowKey) {
-			alreadySelected = true;
-		}
-	});
-
-	if (!alreadySelected) {
-		selectedFlows.unshift(flow);
-		selectedFlows = selectedFlows.slice(0, 3);
-		updateSelectedFlows();
-	}
-}
-
-function hasIPerf(flow) {
-	return flow && flow.iperfFetchInterval;
-}
-
-function clearIPerf(flow) {
-	console.log('clearing iperf interval for: ' + flow.flowId);
-	clearInterval(flow.iperfFetchInterval);
-	delete flow.iperfFetchInterval;
-	clearInterval(flow.iperfDisplayInterval);
-	delete flow.iperfDisplayInterval;
-	delete flow.iperfData;
-}
-
-function deselectFlow(flow, ifCreatePending) {
-	var flowKey = makeFlowKey(flow);
-	var newSelectedFlows = [];
-	selectedFlows.forEach(function (flow) {
-		if (!flow ||
-				flowKey !== makeFlowKey(flow) ||
-				flowKey === makeFlowKey(flow) && ifCreatePending && !flow.createPending ) {
-			newSelectedFlows.push(flow);
-		} else {
-			if (hasIPerf(flow)) {
-				clearIPerf(flow);
-			}
-		}
-	});
-	selectedFlows = newSelectedFlows;
-	while (selectedFlows.length < 3) {
-		selectedFlows.push(null);
-	}
-
-	updateSelectedFlows();
-}
-
-function deselectFlowIfCreatePending(flow) {
-	deselectFlow(flow, true);
-}
-
-function showFlowChooser() {
-	function rowEnter(d) {
-		var row = d3.select(this);
-
-		row.append('div')
-			.classed('black-eye', true).
-			on('click', function () {
-				selectFlow(d);
-			});
-
-		row.append('div')
-			.classed('flowId', true)
-			.text(function (d) {
-				return d.flowId;
-			});
-
-		row.append('div')
-			.classed('srcDPID', true)
-			.text(function (d) {
-				return d.srcDpid;
-			});
-
-
-		row.append('div')
-			.classed('dstDPID', true)
-			.text(function (d) {
-				return d.dstDpid;
-			});
-
-	}
-
-	var flows = d3.select('#flowChooser')
-		.append('div')
-		.style('pointer-events', 'auto')
-		.selectAll('.selectedFlow')
-		.data(model.flows)
-		.enter()
-		.append('div')
-		.classed('selectedFlow', true)
-		.each(rowEnter);
-
-	setTimeout(function () {
-		d3.select(document.body).on('click', function () {
-			d3.select('#flowChooser').html('');
-			d3.select(document.body).on('click', null);
-		});
-	}, 0);
-}
-
-
-
-function updateHeader(model) {
-	d3.select('#lastUpdate').text(new Date());
-	d3.select('#activeSwitches').text(model.edgeSwitches.length + model.aggregationSwitches.length + model.coreSwitches.length);
-	d3.select('#activeFlows').text(model.flows.length);
-}
-
-function toRadians (angle) {
-  return angle * (Math.PI / 180);
-}
-
-var widths = {
-	edge: 6,
-	aggregation: 12,
-	core: 18
-}
-
-function createRingsFromModel(model) {
-	var rings = [{
-		radius: 3,
-		width: widths.edge,
-		switches: model.edgeSwitches,
-		className: 'edge',
-		angles: []
-	}, {
-		radius: 2.25,
-		width: widths.aggregation,
-		switches: model.aggregationSwitches,
-		className: 'aggregation',
-		angles: []
-	}, {
-		radius: 0.75,
-		width: widths.core,
-		switches: model.coreSwitches,
-		className: 'core',
-		angles: []
-	}];
-
-
-	var aggRanges = {};
-
-	// arrange edge switches at equal increments
-	var k = 360 / rings[0].switches.length;
-	rings[0].switches.forEach(function (s, i) {
-		var angle = k * i;
-
-		rings[0].angles[i] = angle;
-
-		// record the angle for the agg switch layout
-		var dpid = s.dpid.split(':');
-		dpid[7] = '01'; // the last component of the agg switch is always '01'
-		var aggdpid = dpid.join(':');
-		var aggRange = aggRanges[aggdpid];
-		if (!aggRange) {
-			aggRange = aggRanges[aggdpid] = {};
-			aggRange.min = aggRange.max = angle;
-		} else {
-			aggRange.max = angle;
-		}
-	});
-
-	// arrange aggregation switches to "fan out" to edge switches
-	k = 360 / rings[1].switches.length;
-	rings[1].switches.forEach(function (s, i) {
-//		rings[1].angles[i] = k * i;
-		var range = aggRanges[s.dpid];
-
-		rings[1].angles[i] = (range.min + range.max)/2;
-	});
-
-	// find the association between core switches and aggregation switches
-	var aggregationSwitchMap = {};
-	model.aggregationSwitches.forEach(function (s, i) {
-		aggregationSwitchMap[s.dpid] = i;
-	});
-
-	// put core switches next to linked aggregation switches
-	k = 360 / rings[2].switches.length;
-	rings[2].switches.forEach(function (s, i) {
-//		rings[2].angles[i] = k * i;
-		var associatedAggregationSwitches = model.configuration.association[s.dpid];
-		// TODO: go between if there are multiple
-		var index = aggregationSwitchMap[associatedAggregationSwitches[0]];
-
-		rings[2].angles[i] = rings[1].angles[index];
-	});
-
-	// TODO: construct this form initially rather than converting. it works better because
-	// it allows binding by dpid
-	var testRings = [];
-	rings.forEach(function (ring) {
-		var testRing = [];
-		ring.switches.forEach(function (s, i) {
-			var testSwitch = {
-				dpid: s.dpid,
-				state: s.state,
-				radius: ring.radius,
-				width: ring.width,
-				className: ring.className,
-				angle: ring.angles[i],
-				controller: s.controller
-			};
-			testRing.push(testSwitch);
-		});
-
-
-		testRings.push(testRing);
-	});
-
-
-//	return rings;
-	return testRings;
-}
-
-function makeLinkKey(link) {
-	return link['src-switch'] + '=>' + link['dst-switch'];
-}
-
-function makeFlowKey(flow) {
-	return flow.srcDpid + '=>' + flow.dstDpid;
-}
-
-function makeSelectedFlowKey(flow) {
-	return 'S' + makeFlowKey(flow);
-}
-
-function createLinkMap(links) {
-	var linkMap = {};
-	links.forEach(function (link) {
-		var srcDPID = link['src-switch'];
-		var dstDPID = link['dst-switch'];
-
-		var srcMap = linkMap[srcDPID] || {};
-
-		srcMap[dstDPID] = link;
-
-		linkMap[srcDPID]  = srcMap;
-	});
-	return linkMap;
-}
-
-// removes links from the pending list that are now in the model
-function reconcilePendingLinks(model) {
-	var links = [];
-	model.links.forEach(function (link) {
-		links.push(link);
-		delete pendingLinks[makeLinkKey(link)]
-	})
-	var linkId;
-	for (linkId in pendingLinks) {
-		links.push(pendingLinks[linkId]);
-	}
-	return links
-}
-
-updateTopology = function() {
-
-	// DRAW THE SWITCHES
-	var rings = svg.selectAll('.ring').data(createRingsFromModel(model));
-
-	var links = reconcilePendingLinks(model);
-	var linkMap = createLinkMap(links);
-
-	function mouseOverSwitch(data) {
-
-		d3.event.preventDefault();
-
-		d3.select(document.getElementById(data.dpid + '-label')).classed('nolabel', false);
-
-		if (data.highlighted) {
-			return;
-		}
-
-		// only highlight valid link or flow destination by checking for class of existing highlighted circle
-		var highlighted = svg.selectAll('.highlight')[0];
-		if (highlighted.length == 1) {
-			var s = d3.select(highlighted[0]).select('circle');
-			// only allow links
-			// 	edge->edge (flow)
-			//  aggregation->core
-			//	core->core
-			if (data.className == 'edge' && !s.classed('edge') ||
-				data.className == 'core' && !s.classed('core') && !s.classed('aggregation') ||
-				data.className == 'aggregation' && !s.classed('core')) {
-				return;
-			}
-
-			// don't highlight if there's already a link or flow
-			// var map = linkMap[data.dpid];
-			// console.log(map);
-			// console.log(s.data()[0].dpid);
-			// console.log(map[s.data()[0].dpid]);
-			// if (map && map[s.data()[0].dpid]) {
-			// 	return;
-			// }
-
-			// the second highlighted switch is the target for a link or flow
-			data.target = true;
-		}
-
-		var node = d3.select(document.getElementById(data.dpid));
-		node.classed('highlight', true).select('circle').transition().duration(100).attr("r", widths.core);
-		data.highlighted = true;
-		node.moveToFront();
-	}
-
-	function mouseOutSwitch(data) {
-		d3.select(document.getElementById(data.dpid + '-label')).classed('nolabel', true);
-
-		if (data.mouseDown)
-			return;
-
-		var node = d3.select(document.getElementById(data.dpid));
-		node.classed('highlight', false).select('circle').transition().duration(100).attr("r", widths[data.className]);
-		data.highlighted = false;
-		data.target = false;
-	}
-
-	function mouseDownSwitch(data) {
-		mouseOverSwitch(data);
-		data.mouseDown = true;
-		d3.select('#topology').classed('linking', true);
-
-		d3.select('svg')
-			.append('svg:path')
-			.attr('id', 'linkVector')
-			.attr('d', function () {
-				var s = d3.select(document.getElementById(data.dpid));
-
-				var pt = document.querySelector('svg').createSVGPoint();
-				pt.x = s.attr('x');
-				pt.y = s.attr('y');
-				pt = pt.matrixTransform(s[0][0].getCTM());
-
-				return line([pt, pt]);
-			});
-
-
-		if (data.className === 'core') {
-			d3.selectAll('.edge').classed('nodrop', true);
-		}
-		if (data.className === 'edge') {
-			d3.selectAll('.core').classed('nodrop', true);
-			d3.selectAll('.aggregation').classed('nodrop', true);
-		}
-		if (data.className === 'aggregation') {
-			d3.selectAll('.edge').classed('nodrop', true);
-			d3.selectAll('.aggregation').classed('nodrop', true);
-		}
-	}
-
-	function mouseUpSwitch(data) {
-		if (data.mouseDown) {
-			data.mouseDown = false;
-			d3.select('#topology').classed('linking', false);
-			d3.event.stopPropagation();
-			d3.selectAll('.nodrop').classed('nodrop', false);
-		}
-	}
-
-	function doubleClickSwitch(data) {
-		var circle = d3.select(document.getElementById(data.dpid)).select('circle');
-		if (data.state == 'ACTIVE') {
-			var prompt = 'Deactivate ' + data.dpid + '?';
-			if (confirm(prompt)) {
-				switchDown(data);
-				setPending(circle);
-			}
-		} else {
-			var prompt = 'Activate ' + data.dpid + '?';
-			if (confirm(prompt)) {
-				switchUp(data);
-				setPending(circle);
-			}
-		}
-	}
-
-	function ringEnter(data, i) {
-		if (!data.length) {
-			return;
-		}
-
-		// create the nodes
-		var nodes = d3.select(this).selectAll("g")
-			.data(data, function (data) {
-				return data.dpid;
-			})
-			.enter().append("svg:g")
-			.attr("id", function (data, i) {
-				return data.dpid;
-			})
-			.attr("transform", function(data, i) {
-				return "rotate(" + data.angle+ ")translate(" + data.radius * 150 + ")rotate(" + (-data.angle) + ")";
-			});
-
-		// add the cirles representing the switches
-		nodes.append("svg:circle")
-			.attr("transform", function(data, i) {
-				var m = document.querySelector('#viewbox').getTransformToElement().inverse();
-				if (data.scale) {
-					m = m.scale(data.scale);
-				}
-				return "matrix( " + m.a + " " + m.b + " " + m.c + " " + m.d + " " + m.e + " " + m.f + " )";
-			})
-			.attr("x", function (data) {
-				return -data.width / 2;
-			})
-			.attr("y", function (data) {
-				return -data.width / 2;
-			})
-			.attr("r", function (data) {
-				return data.width;
-			});
-
-		// setup the mouseover behaviors
-		nodes.on('mouseover', mouseOverSwitch);
-		nodes.on('mouseout', mouseOutSwitch);
-		nodes.on('mouseup', mouseUpSwitch);
-		nodes.on('mousedown', mouseDownSwitch);
-
-		// only do switch up/down for core switches
-		if (i == 2) {
-			nodes.on('dblclick', doubleClickSwitch);
-		}
-	}
-
-	// append switches
-	rings.enter().append("svg:g")
-		.attr("class", "ring")
-		.each(ringEnter);
-
-
-	function ringUpdate(data, i) {
-		var nodes = d3.select(this).selectAll("g")
-			.data(data, function (data) {
-				return data.dpid;
-			});
-		nodes.select('circle')
-			.each(function (data) {
-				// if there's a pending state changed and then the state changes, clear the pending class
-				var circle = d3.select(this);
-				if (data.state === 'ACTIVE' && circle.classed('inactive') ||
-					data.state === 'INACTIVE' && circle.classed('active')) {
-					circle.classed('pending', false);
-				}
-			})
-			.attr('class', function (data)  {
-				if (data.state === 'ACTIVE' && data.controller) {
-					return data.className + ' active ' + controllerColorMap[data.controller];
-				} else {
-					return data.className + ' inactive ' + 'colorInactive';
-				}
-			});
-	}
-
-	// update  switches
-	rings.each(ringUpdate);
-
-
-	// Now setup the labels
-	// This is done separately because SVG draws in node order and we want the labels
-	// always on top
-	var labelRings = svg.selectAll('.labelRing').data(createRingsFromModel(model));
-
-	d3.select(document.body).on('mousemove', function () {
-		if (!d3.select('#topology').classed('linking')) {
-			return;
-		}
-		var linkVector = document.getElementById('linkVector');
-		if (!linkVector) {
-			return;
-		}
-		linkVector = d3.select(linkVector);
-
-		var highlighted = svg.selectAll('.highlight')[0];
-		var s1 = null, s2 = null;
-		if (highlighted.length > 1) {
-			var s1 = d3.select(highlighted[0]);
-			var s2 = d3.select(highlighted[1]);
-
-		} else if (highlighted.length > 0) {
-			var s1 = d3.select(highlighted[0]);
-		}
-		var src = s1;
-		if (s2 && !s2.data()[0].target) {
-			src = s2;
-		}
-		if (src) {
-			linkVector.attr('d', function () {
-					var srcPt = document.querySelector('svg').createSVGPoint();
-					srcPt.x = src.attr('x');
-					srcPt.y = src.attr('y');
-					srcPt = srcPt.matrixTransform(src[0][0].getCTM());
-
-					var svg = document.getElementById('topology');
-					var mouse = d3.mouse(viewbox);
-					var dstPt = document.querySelector('svg').createSVGPoint();
-					dstPt.x = mouse[0];
-					dstPt.y = mouse[1];
-					dstPt = dstPt.matrixTransform(viewbox.getCTM());
-
-					return line([srcPt, dstPt]);
-				});
-		}
-	});
-
-	d3.select(document.body).on('mouseup', function () {
-		function clearHighlight() {
-			svg.selectAll('circle').each(function (data) {
-				data.mouseDown = false;
-				d3.select('#topology').classed('linking', false);
-				mouseOutSwitch(data);
-			});
-			d3.select('#linkVector').remove();
-		};
-
-		d3.selectAll('.nodrop').classed('nodrop', false);
-
-		function removeLink(link) {
-			var path1 = document.getElementById(link['src-switch'] + '=>' + link['dst-switch']);
-			var path2 = document.getElementById(link['dst-switch'] + '=>' + link['src-switch']);
-
-			if (path1) {
-				setPending(d3.select(path1));
-			}
-			if (path2) {
-				setPending(d3.select(path2));
-			}
-
-			linkDown(link);
-		}
-
-
-		var highlighted = svg.selectAll('.highlight')[0];
-		if (highlighted.length == 2) {
-			var s1Data = highlighted[0].__data__;
-			var s2Data = highlighted[1].__data__;
-
-			var srcData, dstData;
-			if (s1Data.target) {
-				dstData = s1Data;
-				srcData = s2Data;
-			} else {
-				dstData = s2Data;
-				srcData = s1Data;
-			}
-
-			if (s1Data.className == 'edge' && s2Data.className == 'edge') {
-				var prompt = 'Create flow from ' + srcData.dpid + ' to ' + dstData.dpid + '?';
-				if (confirm(prompt)) {
-					addFlow(srcData, dstData);
-
-					var flow = {
-						dataPath: {
-							srcPort: {
-								dpid: {
-									value: srcData.dpid
-								}
-							},
-							dstPort: {
-								dpid: {
-									value: dstData.dpid
-								}
-							}
-						},
-					        srcDpid: srcData.dpid,
-					        dstDpid: dstData.dpid,
-						createPending: true
-					};
-
-					selectFlow(flow);
-
-					setTimeout(function () {
-						deselectFlowIfCreatePending(flow);
-					}, pendingTimeout);
-				}
-			} else {
-				var map = linkMap[srcData.dpid];
-				if (map && map[dstData.dpid]) {
-					var prompt = 'Remove link between ' + srcData.dpid + ' and ' + dstData.dpid + '?';
-					if (confirm(prompt)) {
-						removeLink(map[dstData.dpid]);
-					}
-				} else {
-					map = linkMap[dstData.dpid];
-					if (map && map[srcData.dpid]) {
-						var prompt = 'Remove link between ' + dstData.dpid + ' and ' + srcData.dpid + '?';
-						if (confirm(prompt)) {
-							removeLink(map[srcData.dpid]);
-						}
-					} else {
-						var prompt = 'Create link between ' + srcData.dpid + ' and ' + dstData.dpid + '?';
-						if (confirm(prompt)) {
-							var link1 = {
-								'src-switch': srcData.dpid,
-								'src-port': 1,
-								'dst-switch': dstData.dpid,
-								'dst-port': 1,
-								pending: true
-							};
-							pendingLinks[makeLinkKey(link1)] = link1;
-							var link2 = {
-								'src-switch': dstData.dpid,
-								'src-port': 1,
-								'dst-switch': srcData.dpid,
-								'dst-port': 1,
-								pending: true
-							};
-							pendingLinks[makeLinkKey(link2)] = link2;
-							updateTopology();
-
-							linkUp(link1);
-
-							// remove the pending links after 10s
-							setTimeout(function () {
-								delete pendingLinks[makeLinkKey(link1)];
-								delete pendingLinks[makeLinkKey(link2)];
-
-								updateTopology();
-							}, pendingTimeout);
-						}
-					}
-				}
-			}
-
-			clearHighlight();
-		} else {
-			clearHighlight();
-		}
-
-	});
-
-	function labelRingEnter(data) {
-		if (!data.length) {
-			return;
-		}
-
-		// create the nodes
-		var nodes = d3.select(this).selectAll("g")
-			.data(data, function (data) {
-				return data.dpid;
-			})
-			.enter().append("svg:g")
-			.classed('nolabel', true)
-			.attr("id", function (data) {
-				return data.dpid + '-label';
-			})
-			.attr("transform", function(data, i) {
-				return "rotate(" + data.angle+ ")translate(" + data.radius * 150 + ")rotate(" + (-data.angle) + ")";
-			})
-
-		// add the text nodes which show on mouse over
-		nodes.append("svg:text")
-				.text(function (data) {return data.dpid;})
-				.attr("x", function (data) {
-					if (data.angle <= 90 || data.angle >= 270 && data.angle <= 360) {
-						if (data.className == 'edge') {
-							return - data.width*3 - 4;
-						} else {
-							return - data.width - 4;
-						}
-					} else {
-						if (data.className == 'edge') {
-							return data.width*3 + 4;
-						} else {
-							return data.width + 4;
-						}
-					}
-				})
-				.attr("y", function (data) {
-					var y;
-					if (data.angle <= 90 || data.angle >= 270 && data.angle <= 360) {
-						if (data.className == 'edge') {
-							y = data.width*3/2 + 4;
-						} else {
-							y = data.width/2 + 4;
-						}
-					} else {
-						if (data.className == 'edge') {
-							y = data.width*3/2 + 4;
-						} else {
-							y = data.width/2 + 4;
-						}
-					}
-					return y - 6;
-				})
-				.attr("text-anchor", function (data) {
-					if (data.angle <= 90 || data.angle >= 270 && data.angle <= 360) {
-						return "end";
-					} else {
-						return "start";
-					}
-				})
-				.attr("transform", function(data) {
-					var m = document.querySelector('#viewbox').getTransformToElement().inverse();
-					if (data.scale) {
-						m = m.scale(data.scale);
-					}
-					return "matrix( " + m.a + " " + m.b + " " + m.c + " " + m.d + " " + m.e + " " + m.f + " )";
-				})
-	}
-
-	labelRings.enter().append("svg:g")
-		.attr("class", "textRing")
-		.each(labelRingEnter);
-
-	// switches should not change during operation of the ui so no
-	// rings.exit()
-
-
-	// DRAW THE LINKS
-
-	// key on link dpids since these will come/go during demo
-	var links = d3.select('svg').selectAll('.link').data(links, function (d) {
-			return d['src-switch']+'->'+d['dst-switch'];
-	});
-
-	// add new links
-	links.enter().append("svg:path")
-	.attr("class", "link");
-
-	links.attr('id', function (d) {
-			return makeLinkKey(d);
-		})
-		.attr("d", function (d) {
-			var src = d3.select(document.getElementById(d['src-switch']));
-			var dst = d3.select(document.getElementById(d['dst-switch']));
-
-			var srcPt = document.querySelector('svg').createSVGPoint();
-			srcPt.x = src.attr('x');
-			srcPt.y = src.attr('y');
-			srcPt = srcPt.matrixTransform(src[0][0].getCTM());
-
-			var dstPt = document.querySelector('svg').createSVGPoint();
-			dstPt.x = dst.attr('x');
-			dstPt.y = dst.attr('y');
-			dstPt = dstPt.matrixTransform(dst[0][0].getCTM());
-
-			var midPt = document.querySelector('svg').createSVGPoint();
-			midPt.x = (srcPt.x + dstPt.x)/2;
-			midPt.y = (srcPt.y + dstPt.y)/2;
-
-			return line([srcPt, midPt, dstPt]);
-		})
-		.attr("marker-mid", function(d) { return "url(#arrow)"; })
-		.classed('pending', function (d) {
-			return d.pending;
-		});
-
-
-	// remove old links
-	links.exit().remove();
-}
-
-function updateControllers() {
-	var controllers = d3.select('#controllerList').selectAll('.controller').data(model.controllers);
-	controllers.enter().append('div')
-		.each(function (c) {
-			controllerColorMap[c] = colors.pop();
-			d3.select(document.body).classed(controllerColorMap[c] + '-selected', true);
-		})
-		.text(function (d) {
-			return d;
-		})
-		.append('div')
-		.attr('class', 'black-eye');
-
-	controllers.attr('class', function (d) {
-			var color = 'colorInactive';
-			if (model.activeControllers.indexOf(d) != -1) {
-				color = controllerColorMap[d];
-			}
-			var className = 'controller ' + color;
-			return className;
-		});
-
-	// this should never be needed
-	// controllers.exit().remove();
-
-	controllers.on('dblclick', function (c) {
-		if (model.activeControllers.indexOf(c) != -1) {
-			var prompt = 'Dectivate ' + c + '?';
-			if (confirm(prompt)) {
-				controllerDown(c);
-				setPending(d3.select(this));
-			};
-		} else {
-			var prompt = 'Activate ' + c + '?';
-			if (confirm(prompt)) {
-				controllerUp(c);
-				setPending(d3.select(this));
-			};
-		}
-	});
-
-	controllers.select('.black-eye').on('click', function (c) {
-		var allSelected = true;
-		for (var key in controllerColorMap) {
-			if (!d3.select(document.body).classed(controllerColorMap[key] + '-selected')) {
-				allSelected = false;
-				break;
-			}
-		}
-		if (allSelected) {
-			for (var key in controllerColorMap) {
-				d3.select(document.body).classed(controllerColorMap[key] + '-selected', key == c)
-			}
-		} else {
-			for (var key in controllerColorMap) {
-				d3.select(document.body).classed(controllerColorMap[key] + '-selected', true)
-			}
-		}
-
-		// var selected = d3.select(document.body).classed(controllerColorMap[c] + '-selected');
-		// d3.select(document.body).classed(controllerColorMap[c] + '-selected', !selected);
-	});
-
-
-}
 
-var modelString;
 function sync(svg) {
 	var d = Date.now();
+
 	updateModel(function (newModel) {
 //		console.log('Update time: ' + (Date.now() - d)/1000 + 's');
 
@@ -1222,6 +25,8 @@
 			}
 
 			updateHeader(newModel);
+
+			d3.select('#contents').style('visibility', 'visible');
 		}
 
 		// do it again in 1s
@@ -1231,27 +36,7 @@
 	});
 }
 
-svg = createTopologyView();
-
-
-d3.xml("assets/map.svg", "image/svg+xml", function(xml) {
-  var importedNode = document.importNode(xml.documentElement, true);
-  var paths = importedNode.querySelectorAll('path');
-  var i;
-  for (i=0; i < paths.length; i+=1) {
-  	svg.append('svg:path')
-  		.attr('class', 'state')
-  		.attr('d', d3.select(paths.item(i)).attr('d'))
-  		.attr('transform', 'translate(-500 -500)scale(1 1.7)')
-  }
-});
-
-updateSelectedFlows();
-
-d3.select('#showFlowChooser').on('click', function () {
-	showFlowChooser();
-});
-
+appInit();
 
 // workaround for Chrome v25 bug
 // if executed immediately, the view box transform logic doesn't work properly
