Added keydown handler.
Some refactoring.
Cleaned up debug configuration.
Links now clipped to edges of node rectangles.
Updated ONOS icon (just a placeholder for now)
diff --git a/web/gui/src/main/webapp/img/onos-logo.png b/web/gui/src/main/webapp/img/onos-logo.png
index afd87e1..5e0e5a8 100644
--- a/web/gui/src/main/webapp/img/onos-logo.png
+++ b/web/gui/src/main/webapp/img/onos-logo.png
Binary files differ
diff --git a/web/gui/src/main/webapp/network.js b/web/gui/src/main/webapp/network.js
index 7c80616..65e84f0 100644
--- a/web/gui/src/main/webapp/network.js
+++ b/web/gui/src/main/webapp/network.js
@@ -26,13 +26,19 @@
 (function (onos) {
     'use strict';
 
+    // reference to the framework api
     var api = onos.api;
 
+    // configuration data
     var config = {
+            debugOn: false,
+            debug: {
+                showNodeXY: true,
+                showKeyHandler: false
+            },
             options: {
                 layering: true,
-                collisionPrevention: true,
-                showNodeXY: true
+                collisionPrevention: true
             },
             XjsonUrl: 'rs/topology/graph',
             jsonUrl: 'network.json',
@@ -88,20 +94,28 @@
             },
             hostLinkWidth: 1.0,
             mouseOutTimerDelayMs: 120
-        },
-        view = {},
+        };
+
+    // state variables
+    var view = {},
         network = {},
         selected = {},
         highlighted = null,
         viewMode = 'showAll';
 
 
+    function debug(what) {
+        return config.debugOn && config.debug[what];
+    }
+
+    // load the topology view of the network
     function loadNetworkView() {
         // Hey, here I am, calling something on the ONOS api:
         api.printTime();
 
         resize();
 
+        // go get our network data from the server...
         d3.json(config.jsonUrl, function (err, data) {
             if (err) {
                 alert('Oops! Error reading JSON...\n\n' +
@@ -109,14 +123,23 @@
                     'Error: ' + err.message);
                 return;
             }
-            console.log("here is the JSON data...");
-            console.log(data);
+//            console.log("here is the JSON data...");
+//            console.log(data);
 
             network.data = data;
             drawNetwork();
         });
 
-        $(document).on('click', '.select-object', function() {
+        // while we wait for the data, set up the handlers...
+        setUpClickHandler();
+        setUpRadioButtonHandler();
+        setUpKeyHandler();
+        $(window).on('resize', resize);
+    }
+
+    function setUpClickHandler() {
+        // click handler for "selectable" objects
+        $(document).on('click', '.select-object', function () {
             // when any object of class "select-object" is clicked...
             // TODO: get a reference to the object via lookup...
             var obj = network.lookup[$(this).data('id')];
@@ -126,25 +149,67 @@
             // stop propagation of event (I think) ...
             return false;
         });
+    }
 
-        $(window).on('resize', resize);
-
-        // set up radio button behavior
-        d3.selectAll("#displayModes .radio").on('click', function() {
-            var id = d3.select(this).attr("id");
+    function setUpRadioButtonHandler() {
+        d3.selectAll('#displayModes .radio').on('click', function () {
+            var id = d3.select(this).attr('id');
             if (id !== viewMode) {
                 radioButton('displayModes', id);
                 viewMode = id;
-                alert("action: " + id);
+                alert('action: ' + id);
             }
         });
     }
 
+    function setUpKeyHandler() {
+        d3.select('body')
+            .on('keydown', function () {
+                processKeyEvent();
+                if (debug('showKeyHandler')) {
+                    network.svg.append('text')
+                        .attr('x', 5)
+                        .attr('y', 15)
+                        .style('font-size', '20pt')
+                        .text('keyCode: ' + d3.event.keyCode +
+                            ' applied to : ' + contextLabel())
+                        .transition().duration(2000)
+                        .style('font-size', '2pt')
+                        .style('fill-opacity', 0.01)
+                        .remove();
+                }
+            });
+    }
+
     function radioButton(group, id) {
         d3.selectAll("#" + group + " .radio").classed("active", false);
         d3.select("#" + group + " #" + id).classed("active", true);
     }
 
+    function contextLabel() {
+        return highlighted === null ? "(nothing)" : highlighted.id;
+    }
+
+    function processKeyEvent() {
+        var code = d3.event.keyCode;
+        switch (code) {
+            case 76:    // L
+                cycleLabels();
+                break;
+            case 80:    // P
+                togglePorts();
+        }
+
+    }
+
+    function cycleLabels() {
+        alert('Cycle Labels - context = ' + contextLabel());
+    }
+
+    function togglePorts() {
+        alert('Toggle Ports - context = ' + contextLabel());
+    }
+
 
     // ========================================================
 
@@ -430,8 +495,9 @@
                 // adjusted the bounds of the rectangle...
             }
 
-            // for debugging...
-            if (config.options.showNodeXY) {
+            // debug function to show the modelled x,y coordinates of nodes...
+            if (debug('showNodeXY')) {
+                node.select('rect').attr('fill-opacity', 0.5);
                 node.append('circle')
                     .attr({
                         class: 'debug',
@@ -599,34 +665,41 @@
             preventCollisions();
         }
 
-        // TODO: use intersection technique for source end of link also
-        network.link
-            .attr('x1', function(d) {
-                return d.source.x;
-            })
-            .attr('y1', function(d) {
-                return d.source.y;
-            })
-            .each(function(d) {
-                var x = d.target.x,
-                    y = d.target.y,
-                    line = new geo.LineSegment(d.source.x, d.source.y, x, y);
+        // clip visualization of links at bounds of nodes...
+        network.link.each(function(d) {
+                var xs = d.source.x,
+                    ys = d.source.y,
+                    xt = d.target.x,
+                    yt = d.target.y,
+                    line = new geo.LineSegment(xs, ys, xt, yt),
+                    e, ix;
 
-                for (var e in d.target.edge) {
-                    var ix = line.intersect(d.target.edge[e].offset(x,y));
+                for (e in d.source.edge) {
+                    ix = line.intersect(d.source.edge[e].offset(xs, ys));
                     if (ix.in1 && ix.in2) {
-                        x = ix.x;
-                        y = ix.y;
+                        xs = ix.x;
+                        ys = ix.y;
+                        break;
+                    }
+                }
+
+                for (e in d.target.edge) {
+                    ix = line.intersect(d.target.edge[e].offset(xt, yt));
+                    if (ix.in1 && ix.in2) {
+                        xt = ix.x;
+                        yt = ix.y;
                         break;
                     }
                 }
 
                 d3.select(this)
-                    .attr('x2', x)
-                    .attr('y2', y);
-
+                    .attr('x1', xs)
+                    .attr('y1', ys)
+                    .attr('x2', xt)
+                    .attr('y2', yt);
             });
 
+        // position each node by translating the node (group) by x,y
         network.node
             .attr('transform', function(d) {
                 return translate(d.x, d.y);
diff --git a/web/gui/src/main/webapp/onos.css b/web/gui/src/main/webapp/onos.css
index eea7d9d..1b3becb 100644
--- a/web/gui/src/main/webapp/onos.css
+++ b/web/gui/src/main/webapp/onos.css
@@ -82,7 +82,7 @@
 svg .link {
     fill: none;
     stroke: #666;
-    stroke-width: 1.5px;
+    stroke-width: 2.0px;
     opacity: .7;
     /*marker-end: url(#end);*/