diff --git a/client/client.js b/client/client.js
index e5e341691daae3d0b25775a633268edb02462896..90e450d46c3c6fbf149c1e7aebf32fd3c5669a6a 100644
--- a/client/client.js
+++ b/client/client.js
@@ -1,619 +1,669 @@
-//
-//
-// new node controller / VIEW 
-// reconfigurable unviersal numeric dataflow machine controller
-// 'RUN DMC'
-// dataflow numeric controller
-// DNC 
-//
-// client.js
-//
-//
-// Jake Read at the Center for Bits and Atoms
-// (c) Massachusetts Institute of Technology 2018
-//
-// This work may be reproduced, modified, distributed, performed, and
-// displayed for any purpose, but must acknowledge the mods
-// project. Copyright is retained and must be preserved. The work is
-// provided as is; no warranty is provided, and users accept all
-// liability.
-
-/*
-
-CLIENT GLOBALS ---------------------------------------------------
-
-*/
-
-var sckt = {}
-var lastPos = { x: 10, y: 30 }
-
-// drawing / div-ing
-var wrapper = {}
-var nav = {}
-
-/*
-
-STARTUP ---------------------------------------------------
-
-*/
-
-window.onload = function() {
-    svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg')
-    svg.style.position = 'absolute'
-    svg.style.left = 0
-    svg.style.top = 0
-    svg.style.zIndex = 0
-    svg.style.overflow = 'visible'
-    svg.setAttribute('width', 2)
-    svg.setAttribute('height', 2)
-    svg.setAttribute('id', 'svg')
-    svg.setAttribute('width', '100%')
-    svg.setAttribute('height', '100%')
-    document.body.appendChild(svg)
-
-    wrapper = document.createElement('div')
-    wrapper.id = 'wrapper'
-    document.body.append(wrapper)
-
-    nav = document.getElementById('nav')
-
-    const socket = new WebSocket('ws://localhost:8081')
-
-    socket.onopen = function(evt) {
-        // pass to global ref 
-        sckt = this
-        // say hello 
-        socketSend('console', 'hello server')
-        console.log('socket open')
-        // ask for the current program 
-        socketSend('get current program', '')
-        // main socket entry point
-        this.onmessage = (evt) => {
-            socketRecv(evt)
-        }
-        // others
-        this.onerror = (err) => {
-            alert('link to server is broken')
-            location.reload()
-            console.log('socket error', err)
-        }
-        this.onclose = (evt) => {
-            console.log('socket closed', evt)
-            sckt = null
+    //
+    //
+    // new node controller / VIEW 
+    // reconfigurable unviersal numeric dataflow machine controller
+    // 'RUN DMC'
+    // dataflow numeric controller
+    // DNC 
+    //
+    // client.js
+    //
+    //
+    // Jake Read at the Center for Bits and Atoms
+    // (c) Massachusetts Institute of Technology 2018
+    //
+    // This work may be reproduced, modified, distributed, performed, and
+    // displayed for any purpose, but must acknowledge the mods
+    // project. Copyright is retained and must be preserved. The work is
+    // provided as is; no warranty is provided, and users accept all
+    // liability.
+
+    /*
+
+    CLIENT GLOBALS ---------------------------------------------------
+
+    */
+
+    var sckt = {}
+    var lastPos = { x: 10, y: 30 }
+
+    // drawing / div-ing
+    var wrapper = {}
+    var nav = {}
+
+    /*
+
+    STARTUP ---------------------------------------------------
+
+    */
+
+    window.onload = function() {
+        svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg')
+        svg.style.position = 'absolute'
+        svg.style.left = 0
+        svg.style.top = 0
+        svg.style.zIndex = 0
+        svg.style.overflow = 'visible'
+        svg.setAttribute('width', 2)
+        svg.setAttribute('height', 2)
+        svg.setAttribute('id', 'svg')
+        svg.setAttribute('width', '100%')
+        svg.setAttribute('height', '100%')
+        document.body.appendChild(svg)
+
+        wrapper = document.createElement('div')
+        wrapper.id = 'wrapper'
+        document.body.append(wrapper)
+
+        nav = document.getElementById('nav')
+
+        const socket = new WebSocket('ws://localhost:8081')
+
+        socket.onopen = function(evt) {
+            // pass to global ref 
+            sckt = this
+            // say hello 
+            socketSend('console', 'hello server')
+            console.log('socket open')
+            // ask for the current program 
+            socketSend('get current program', '')
+            // main socket entry point
+            this.onmessage = (evt) => {
+                socketRecv(evt)
+            }
+            // others
+            this.onerror = (err) => {
+                alert('link to server is broken')
+                location.reload()
+                console.log('socket error', err)
+            }
+            this.onclose = (evt) => {
+                console.log('socket closed', evt)
+                sckt = null
+            }
         }
     }
-}
 
-/*
+    /*
 
-RECV / SEND PORTALS ---------------------------------------------------
+    RECV / SEND PORTALS ---------------------------------------------------
 
-*/
+    */
 
-function socketSend(type, data) {
-    var msg = {
-        type: type,
-        data: data
+    function socketSend(type, data) {
+        var msg = {
+            type: type,
+            data: data
+        }
+        console.log('SEND', msg)
+        sckt.send(JSON.stringify(msg))
     }
-    console.log('SEND', msg)
-    sckt.send(JSON.stringify(msg))
-}
-
-function socketRecv(evt) {
-    var recv = JSON.parse(evt.data)
-    var type = recv.type
-    var data = recv.data
-    console.log('RECV', recv)
-    // tree banger
-    switch (type) {
-        case 'console':
-            console.log('RECV CONSOLE:', data)
-            break
-        case 'put module menu':
-            console.log('RECV MODULE MENU')
-            heapSendsModuleMenu(data)
-            break
-        case 'put program menu':
-            console.log('RECV PRG MENU')
-            heapSendsProgramMenu(data)
-            break
-        case 'put program':
-            console.log('RECV PROGRAM')
-            heapSendsNewProgram(data)
-            break
-        case 'put module':
-            console.log('RECV NEW MODULE')
-            heapSendsNewModule(data)
-            break
-        case 'put module change':
-            console.log('RECV MODULE CHANGE')
-            heapSendsModuleChange(data)
-            break
-        case 'put state change':
-            console.log('RECV STATE CHANGE')
-            heapSendsStateChange(data)
-            break
-        case 'restart':
-            location.reload()
-        default:
-            console.log('ERR recv with non recognized type', recv)
-            break
+
+    function socketRecv(evt) {
+        var recv = JSON.parse(evt.data)
+        var type = recv.type
+        var data = recv.data
+        console.log('RECV', recv)
+        // tree banger
+        switch (type) {
+            case 'console':
+                console.log('RECV CONSOLE:', data)
+                break
+            case 'put module menu':
+                console.log('RECV MODULE MENU')
+                heapSendsModuleMenu(data)
+                break
+            case 'put program menu':
+                console.log('RECV PRG MENU')
+                heapSendsProgramMenu(data)
+                break
+            case 'put program':
+                console.log('RECV PROGRAM')
+                heapSendsNewProgram(data)
+                break
+            case 'put module':
+                console.log('RECV NEW MODULE')
+                heapSendsNewModule(data)
+                break
+            case 'put module change':
+                console.log('RECV MODULE CHANGE')
+                heapSendsModuleChange(data)
+                break
+            case 'put state change':
+                console.log('RECV STATE CHANGE')
+                heapSendsStateChange(data)
+                break
+            case 'restart':
+                location.reload()
+            default:
+                console.log('ERR recv with non recognized type', recv)
+                break
+        }
     }
-}
 
-/*
+    /*
 
-MISC ---------------------------------------------------
+    MISC ---------------------------------------------------
 
-*/
+    */
 
 
-/*
+    /*
 
-HEAP -> SERVER ---------------------------------------------------
+    HEAP -> SERVER ---------------------------------------------------
 
-*/
+    */
 
-// always a rep, tho
-var program = {}
+    // always a rep, tho
+    var program = {}
 
-// re-writes the program, adds a description,
-// and loads multiple representations of modules to the view 
+    // re-writes the program, adds a description,
+    // and loads multiple representations of modules to the view 
 
-function heapSendsNewProgram(prgm) {
-    // whole hearted replace
-    // hello for bugs when we lay this on top of something else 
-    program = prgm
-    // 1st we want to git rm old files ... 
-    // when adding links, we'll have to add all and then draw links
-    console.log(program)
-    for (mdlName in program.modules) {
-        addRepToView(program.modules[mdlName])
+    function heapSendsNewProgram(prgm) {
+        // whole hearted replace
+        // hello for bugs when we lay this on top of something else 
+        program = prgm
+        // 1st we want to git rm old files ... 
+        // when adding links, we'll have to add all and then draw links
+        console.log(program)
+        for (mdlName in program.modules) {
+            addRepToView(program.modules[mdlName])
+        }
+        redrawLinks()
     }
-    redrawLinks()
-}
 
-function heapSendsNewModule(mdl) {
-    if (program.description == null) {
-        program.description.name = 'unnamed program'
-    }
-    if (program.modules == null) {
-        program.modules = {}
-    }
-    addRepToView(mdl)
-    program.modules[mdl.description.id] = mdl
-    redrawLinks()
-}
-
-// writes DOM elements to represent the module, appends to the wrapper
-// and appends to the rep object a .ui object 
-// containing references to those DOM objects 
-
-function heapSendsModuleChange(data) {
-    console.log(data)
-    // data should be rep of changed module 
-    var rep = program.modules[data.description.id]
-    // we want a general case, but for now we know we're looking for 
-    // new event hookups or new state items 
-    for (key in rep.outputs) {
-        var output = rep.outputs[key]
-        if (output.calls.length !== data.outputs[key].calls.length) {
-            rep.outputs = data.outputs
+    function heapSendsNewModule(mdl) {
+        if (program.description == null) {
+            program.description.name = 'unnamed program'
+        }
+        if (program.modules == null) {
+            program.modules = {}
         }
+        addRepToView(mdl)
+        program.modules[mdl.description.id] = mdl
+        redrawLinks()
     }
-    // ok
-    for (key in rep.state) {
-        var stateItem = rep.state[key]
-        if (stateItem != data.state[key]) {
-            stateItem = data.state[key]
-            rep.ui.state[key].value = data.state[key]
+
+    // writes DOM elements to represent the module, appends to the wrapper
+    // and appends to the rep object a .ui object 
+    // containing references to those DOM objects 
+
+    function heapSendsModuleChange(data) {
+        console.log(data)
+        // data should be rep of changed module 
+        var rep = program.modules[data.description.id]
+        // we want a general case, but for now we know we're looking for 
+        // new event hookups or new state items 
+        for (key in rep.outputs) {
+            var output = rep.outputs[key]
+            if (output.calls.length !== data.outputs[key].calls.length) {
+                rep.outputs = data.outputs
+            }
+        }
+        // ok
+        for (key in rep.state) {
+            var stateItem = rep.state[key]
+            if (stateItem != data.state[key]) {
+                stateItem = data.state[key]
+                rep.ui.state[key].value = data.state[key]
+            }
         }
+        // wreckless or wonderful?
+        //clear(rep)
+        redrawLinks()
     }
-    // wreckless or wonderful?
-    //clear(rep)
-    redrawLinks()
-}
-
-// update state from server to UI
-function heapSendsStateChange(data) {
-    console.log('HEAP SENDS CHANGE STATE IN MODULE', data)
-    var rep = program.modules[data.id]
-    rep.state[data.key] = data.val
-    if (rep.state[data.key].type == 'multiline') {
-        rep.ui.state[data.key].value = data.val.value
-    } else {
-        rep.ui.state[data.key].value = data.val
+
+    // update state from server to UI
+    function heapSendsStateChange(data) {
+        console.log('HEAP SENDS CHANGE STATE IN MODULE', data)
+        var rep = program.modules[data.id]
+        rep.state[data.key] = data.val
+        if (rep.state[data.key].type == 'multiline') {
+            rep.ui.state[data.key].value = data.val.value
+        } else {
+            rep.ui.state[data.key].value = data.val
+        }
     }
-}
 
-/*
+    /*
 
-UI -> HEAP ---------------------------------------------------
+    UI -> HEAP ---------------------------------------------------
 
-*/
+    */
+    
 
-// push new state from UI to server 
-function putState(rep, key) {
-    var data = {
-        id: rep.description.id,
-        key: key,
-        val: rep.state[key]
-    }
-    socketSend('put state change', data)
-}
 
-// save ui position to server for reload
-function putUi(rep) {
-    var data = {
-        description: {
+    // push new state from UI to server 
+    function putState(rep, key) {
+        var data = {
             id: rep.description.id,
-            position: {
-                left: rep.description.position.left,
-                top: rep.description.position.top
-            }
+            key: key,
+            val: rep.state[key]
         }
+        socketSend('put state change', data)
     }
 
-    socketSend('put ui change', data)
-}
-
-// input / output click handling 
-var clkState = false
-var oClk = {}
-var tmpBz = {}
-
-function evtConnectHandler(clk) {
-    if (!clkState) {
-        // first click
-        oClk = clk
-        clkState = true
-    } else {
-        // second click
-        var tClk = clk
-        //console.log(oClk, tClk)
-        var x1 = parseInt(oClk.evt.target.offsetParent.style.left, 10) + oClk.evt.target.offsetLeft + oClk.evt.target.clientWidth
-        var y1 = parseInt(oClk.evt.target.offsetParent.style.top, 10) + oClk.evt.target.offsetTop + oClk.evt.target.clientHeight / 2
-        var x2 = parseInt(tClk.evt.target.offsetParent.style.left, 10) + tClk.evt.target.offsetLeft
-        var y2 = parseInt(tClk.evt.target.offsetParent.style.top, 10) + tClk.evt.target.offsetTop + tClk.evt.target.clientHeight / 2
-        //var bz = newBezier(x1, y1, x2, y2)
-        clkState = false
-        //console.log('connect', oClk.rep.description.id, oClk.name, 'to', tClk.rep.description.id, tClk.name)
+    // save ui position to server for reload
+    function putUi(rep) {
         var data = {
-            from: {
-                id: oClk.rep.description.id,
-                output: oClk.name
-            },
-            to: {
-                id: tClk.rep.description.id,
-                input: tClk.name
+            description: {
+                id: rep.description.id,
+                position: {
+                    left: rep.description.position.left,
+                    top: rep.description.position.top
+                }
+            }
+        }
+
+        socketSend('put ui change', data)
+    }
+
+    // input / output click handling 
+    var clkState = false
+    var oClk = {}
+    var tmpBz = {}
+
+    function evtConnectHandler(clk) {
+        if (!clkState) {
+            // first click
+            oClk = clk
+            clkState = true
+        } else {
+            // second click
+            var tClk = clk
+            //console.log(oClk, tClk)
+            var x1 = parseInt(oClk.evt.target.offsetParent.style.left, 10) + oClk.evt.target.offsetLeft + oClk.evt.target.clientWidth
+            var y1 = parseInt(oClk.evt.target.offsetParent.style.top, 10) + oClk.evt.target.offsetTop + oClk.evt.target.clientHeight / 2
+            var x2 = parseInt(tClk.evt.target.offsetParent.style.left, 10) + tClk.evt.target.offsetLeft
+            var y2 = parseInt(tClk.evt.target.offsetParent.style.top, 10) + tClk.evt.target.offsetTop + tClk.evt.target.clientHeight / 2
+            //var bz = newBezier(x1, y1, x2, y2)
+            clkState = false
+            //console.log('connect', oClk.rep.description.id, oClk.name, 'to', tClk.rep.description.id, tClk.name)
+            var data = {
+                from: {
+                    id: oClk.rep.description.id,
+                    output: oClk.name
+                },
+                to: {
+                    id: tClk.rep.description.id,
+                    input: tClk.name
+                }
             }
+            socketSend('put link change', data)
         }
-        socketSend('put link change', data)
     }
-}
 
-/*
+    /*
 
-UTILITIES ---------------------------------------------------
+    UTILITIES ---------------------------------------------------
 
-*/
+    */
 
-function isStateKey(key) {
-    if (key.indexOf('_') == 0 || key == 'emitters' || key == 'onChange' || key == 'emitChange') {
-        return false
-    } else {
-        return true
+    function isStateKey(key) {
+        if (key.indexOf('_') == 0 || key == 'emitters' || key == 'onChange' || key == 'emitChange') {
+            return false
+        } else {
+            return true
+        }
     }
-}
 
-function redrawLinks() {
-    // probably not a great way to do this, we're removing everything
-    // svg -rm -r 
-    while (svg.firstChild) {
-        svg.removeChild(svg.firstChild)
-    }
-    // find that link
-    var lnkPt
-    var nLnk = 0
-    for (mdlName in program.modules) {
-        if (program.modules[mdlName].description.isLink) {
-            lnkPt = getLeftWall(program.modules[mdlName].ui.domElem)
+    function redrawLinks() {
+        // probably not a great way to do this, we're removing everything
+        // svg -rm -r 
+        while (svg.firstChild) {
+            svg.removeChild(svg.firstChild)
         }
-    }
-    // redraw thru all links, just look at reps
-    for (mdlName in program.modules) {
-        var mdlRep = program.modules[mdlName]
-        for (key in mdlRep.outputs) {
-            var output = mdlRep.outputs[key]
-            var outputUi = mdlRep.ui.outputs[key]
-            for (input in output.calls) {
-                var toId = output.calls[input].parentId
-                var toKey = output.calls[input].key
-                var inputUi = program.modules[toId].ui.inputs[toKey]
-                var outPos = getOutputArrow(outputUi)
-                var inPos = getInputArrow(inputUi)
-                if (inputUi.isHovering || outputUi.isHovering) {
-                    var bz = newBezier(outPos.x, outPos.y, inPos.x, inPos.y, true)
-                } else {
-                    var bz = newBezier(outPos.x, outPos.y, inPos.x, inPos.y, false)
-                }
+        // find that link
+        var lnkPt
+        var nLnk = 0
+        for (mdlName in program.modules) {
+            if (program.modules[mdlName].description.isLink) {
+                lnkPt = getLeftWall(program.modules[mdlName].ui.domElem)
             }
         }
-        if (mdlRep.description.isHardware && !mdlRep.description.isLink) {
-            nLnk++
-            var hwPt = getRightWall(mdlRep.ui.domElem)
-            lnkPt.y += 10 * nLnk
-            var ln = newLine(hwPt.x, hwPt.y, lnkPt.x, lnkPt.y)
+        // redraw thru all links, just look at reps
+        for (mdlName in program.modules) {
+            var mdlRep = program.modules[mdlName]
+            for (key in mdlRep.outputs) {
+                var output = mdlRep.outputs[key]
+                var outputUi = mdlRep.ui.outputs[key]
+                for (input in output.calls) {
+                    var toId = output.calls[input].parentId
+                    var toKey = output.calls[input].key
+                    var inputUi = program.modules[toId].ui.inputs[toKey]
+                    var outPos = getOutputArrow(outputUi)
+                    var inPos = getInputArrow(inputUi)
+                    if (inputUi.isHovering || outputUi.isHovering) {
+                        var bz = newBezier(outPos.x, outPos.y, inPos.x, inPos.y, true)
+                    } else {
+                        var bz = newBezier(outPos.x, outPos.y, inPos.x, inPos.y, false)
+                    }
+                }
+            }
+            if (mdlRep.description.isHardware && !mdlRep.description.isLink) {
+                nLnk++
+                var hwPt = getRightWall(mdlRep.ui.domElem)
+                lnkPt.y += 10 * nLnk
+                var ln = newLine(hwPt.x, hwPt.y, lnkPt.x, lnkPt.y)
+            }
         }
     }
-}
-
-/*
-
-UI EVENTS ---------------------------------------------------------------------
-
-*/
-
-// drag / pan etc 
-
-document.body.style.overflow = 'hidden'
-document.body.style.transform = 'scale(1) translate(0px, 0px)'
-document.body.style.transformOrigin = '0px 0px'
-// s/o @ Neil 
-function getCurrentTransform() {
-    // a string 
-    var transform = document.body.style.transform
-
-    var index = transform.indexOf('scale')
-    var left = transform.indexOf('(', index)
-    var right = transform.indexOf(')', index)
-    var s = parseFloat(transform.slice(left + 1, right))
-    var index = transform.indexOf('translate')
-    var left = transform.indexOf('(', index)
-    var right = transform.indexOf('px', left)
-    var tx = parseFloat(transform.slice(left + 1, right))
-    var left = transform.indexOf(',', right)
-    var right = transform.indexOf('px', left)
-    var ty = parseFloat(transform.slice(left + 1, right))
-    var origin = document.body.style.transformOrigin
-    var pxx = origin.indexOf('px')
-    var ox = parseFloat(origin.slice(0, pxx))
-    var pxy = origin.indexOf('px', pxx + 2)
-    var oy = parseFloat(origin.slice(pxx + 2, pxy))
-
-    return ({
-        s: s,
-        tx: tx,
-        ty: ty,
-        ox: ox,
-        oy: oy
-    })
-}
-
-function elementIsNotModule(element) {
-    if ((element.tagName == 'HTML') || (element.tagName == 'BODY') || (element.tagName == 'svg')) {
-        return true
-    } else {
-        return false
+
+    /*
+
+    UI EVENTS ---------------------------------------------------------------------
+
+    */
+
+    // drag / pan etc 
+
+    document.body.style.overflow = 'hidden'
+    document.body.style.transform = 'scale(1) translate(0px, 0px)'
+    document.body.style.transformOrigin = '0px 0px'
+    // s/o @ Neil 
+    function getCurrentTransform() {
+        // a string 
+        var transform = document.body.style.transform
+
+        var index = transform.indexOf('scale')
+        var left = transform.indexOf('(', index)
+        var right = transform.indexOf(')', index)
+        var s = parseFloat(transform.slice(left + 1, right))
+        var index = transform.indexOf('translate')
+        var left = transform.indexOf('(', index)
+        var right = transform.indexOf('px', left)
+        var tx = parseFloat(transform.slice(left + 1, right))
+        var left = transform.indexOf(',', right)
+        var right = transform.indexOf('px', left)
+        var ty = parseFloat(transform.slice(left + 1, right))
+        var origin = document.body.style.transformOrigin
+        var pxx = origin.indexOf('px')
+        var ox = parseFloat(origin.slice(0, pxx))
+        var pxy = origin.indexOf('px', pxx + 2)
+        var oy = parseFloat(origin.slice(pxx + 2, pxy))
+
+        return ({
+            s: s,
+            tx: tx,
+            ty: ty,
+            ox: ox,
+            oy: oy
+        })
     }
-}
 
-onwheel = function(evt) {
-    var el = document.elementFromPoint(evt.pageX, evt.pageY)
-    if (elementIsNotModule(el)) {
-        var cT = getCurrentTransform()
-        evt.preventDefault()
-        evt.stopPropagation()
-        if (evt.deltaY > 0) {
-            var scale = 1.05 * cT.s
+    function elementIsNotModule(element) {
+        if ((element.tagName == 'HTML') || (element.tagName == 'BODY') || (element.tagName == 'svg')) {
+            return true
         } else {
-            var scale = 0.95 * cT.s
+            return false
         }
-        var tx = cT.tx + (evt.pageX - cT.ox) * (1 - 1 / cT.s)
-        var ty = cT.ty + (evt.pageY - cT.oy) * (1 - 1 / cT.s)
+    }
+
+    onwheel = function(evt) {
+        var el = document.elementFromPoint(evt.pageX, evt.pageY)
+        if (elementIsNotModule(el)) {
+            var cT = getCurrentTransform()
+            evt.preventDefault()
+            evt.stopPropagation()
+            if (evt.deltaY > 0) {
+                var scale = 1.05 * cT.s
+            } else {
+                var scale = 0.95 * cT.s
+            }
+            var tx = cT.tx + (evt.pageX - cT.ox) * (1 - 1 / cT.s)
+            var ty = cT.ty + (evt.pageY - cT.oy) * (1 - 1 / cT.s)
 
-        // body
-        document.body.style.transform = `scale(${scale}) translate(${tx}px,${ty}px)`
-        document.body.style.transformOrigin = `${evt.pageX}px ${evt.pageY}px`
+            // body
+            document.body.style.transform = `scale(${scale}) translate(${tx}px,${ty}px)`
+            document.body.style.transformOrigin = `${evt.pageX}px ${evt.pageY}px`
 
-        // opposite for nav 
-        nav.style.transformOrigin = `${evt.pageX}px ${evt.pageY}px`
-        nav.style.transform = `scale(${1/scale}) translate(${-tx*scale}px,${-ty*scale}px)`
+            // opposite for nav 
+            nav.style.transformOrigin = `${evt.pageX}px ${evt.pageY}px`
+            nav.style.transform = `scale(${1/scale}) translate(${-tx*scale}px,${-ty*scale}px)`
+        }
     }
-}
 
-onmousedown = function(evt) {
-    var qr = document.querySelector(':focus')
-    if (qr) {
-        qr.blur()
+    onmousedown = function(evt) {
+        var qr = document.querySelector(':focus')
+        if (qr) {
+            qr.blur()
+        }
+        var el = document.elementFromPoint(evt.pageX, evt.pageY)
+        if (elementIsNotModule(el)) {
+            evt.preventDefault()
+            evt.stopPropagation()
+            window.addEventListener('mousemove', mouseMoveDragListener)
+            window.addEventListener('mouseup', mouseUpDragListener)
+        }
+        // removes any popup descriptions for list items in Module Menu
+         rmDescription()
     }
-    var el = document.elementFromPoint(evt.pageX, evt.pageY)
-    if (elementIsNotModule(el)) {
+
+    function mouseMoveDragListener(evt) {
         evt.preventDefault()
         evt.stopPropagation()
-        window.addEventListener('mousemove', mouseMoveDragListener)
-        window.addEventListener('mouseup', mouseUpDragListener)
+        var cT = getCurrentTransform()
+        var dx = evt.movementX
+        var dy = evt.movementY
+        var tx = cT.tx + dx / cT.s
+        var ty = cT.ty + dy / cT.s
+
+        // for body 
+        document.body.style.transform = `scale(${cT.s}) translate(${tx}px,${ty}px)`
+
+        // opposite for nav 
+        nav.style.transform = `scale(${1/cT.s}) translate(${-tx*cT.s}px,${-ty*cT.s}px)`
     }
-}
-
-function mouseMoveDragListener(evt) {
-    evt.preventDefault()
-    evt.stopPropagation()
-    var cT = getCurrentTransform()
-    var dx = evt.movementX
-    var dy = evt.movementY
-    var tx = cT.tx + dx / cT.s
-    var ty = cT.ty + dy / cT.s
-
-    // for body 
-    document.body.style.transform = `scale(${cT.s}) translate(${tx}px,${ty}px)`
-
-    // opposite for nav 
-    nav.style.transform = `scale(${1/cT.s}) translate(${-tx*cT.s}px,${-ty*cT.s}px)`
-}
-
-function mouseUpDragListener(evt) {
-    window.removeEventListener('mousemove', mouseMoveDragListener)
-    window.removeEventListener('mouseup', mouseUpDragListener)
-}
-
-// get json menu item and render
-// and ask for module at /obj/key
-oncontextmenu = function(evt) {
-    console.log(evt.target)
-    if (evt.target.className == 'modname') {
-        var modRep = program.modules[evt.target.innerHTML]
-        if (modRep) {
-            writeModuleOptionMenu(modRep)
-        }
-    } else {
-        if (sckt) {
-            socketSend('get module menu', '')
+
+    function mouseUpDragListener(evt) {
+        window.removeEventListener('mousemove', mouseMoveDragListener)
+        window.removeEventListener('mouseup', mouseUpDragListener)
+    }
+
+    // get json menu item and render
+    // and ask for module at /obj/key
+    oncontextmenu = function(evt) {
+        console.log(evt.target)
+        if (evt.target.className == 'modname') {
+            var modRep = program.modules[evt.target.innerHTML]
+            if (modRep) {
+                writeModuleOptionMenu(modRep)
+            }
         } else {
-            // socket brkn, reload page 
-            location.reload()
+            if (sckt) {
+                socketSend('get module menu', '')
+            } else {
+                // socket brkn, reload page 
+                location.reload()
+            }
+            // prevents event bubbling 
         }
-        // prevents event bubbling 
+        return false
     }
-    return false
-}
-
-onmousemove = function(evt) {
-    var cT = getCurrentTransform()
-    lastPos.x = cT.ox - cT.tx + (evt.pageX - cT.ox) / cT.s
-    lastPos.y = cT.oy - cT.ty + (evt.pageY - cT.oy) / cT.s
-}
-
-document.onkeydown = function(evt) {
-    switch (evt.key) {
-        case 'Escape':
-            location.reload()
-            break
-        case 's':
-            // get path ? 
-            var path = prompt("path? starting at atkapi/programs/")
-            socketSend('save program', path)
-            break
-        case 'l':
-            socketSend('get program menu', '')
-            break
-        case 'm':
-            socketSend('get module menu', '')
-            break
-        default:
-            break
+    
+
+    onmousemove = function(evt) {
+        var cT = getCurrentTransform()
+        lastPos.x = cT.ox - cT.tx + (evt.pageX - cT.ox) / cT.s
+        lastPos.y = cT.oy - cT.ty + (evt.pageY - cT.oy) / cT.s
     }
-}
-
-function writeModuleOptionMenu(modRep) {
-    var menuDom = document.createElement('div')
-    menuDom.id = 'perModuleMenu'
-    menuDom.style.left = 10 + modRep.ui.domElem.offsetLeft + modRep.ui.domElem.offsetWidth + 'px'
-    menuDom.style.top = modRep.ui.domElem.offsetTop + 'px'
-    // future: rm all inputs, rm all outputs, rename, open (heirarchy)
-    var opts = ['delete', 'copy']
-    for (i in opts) {
-        var li = document.createElement('li')
-        li.innerHTML = opts[i]
-        li.id = opts[i]
-        if (opts[i] == 'delete') {
-            li.addEventListener('click', function(evt) {
-                var data = {
-                    id: modRep.description.id
-                }
-                socketSend('remove module', data)
-                wrapper.removeChild(document.getElementById('perModuleMenu'))
-            })
-        } else if (opts[i] == 'copy') {
-            li.addEventListener('click', function(evt) {
-                var data = modRep.description.path
-                socketSend('put module', data)
-                wrapper.removeChild(document.getElementById('perModuleMenu'))
-            })
+
+    document.onkeydown = function(evt) {
+        switch (evt.key) {
+            case 'Escape':
+                location.reload()
+                break
+            case 's':
+                // get path ? 
+                var path = prompt("path? starting at atkapi/programs/")
+                socketSend('save program', path)
+                break
+            case 'l':
+                socketSend('get program menu', '')
+                break
+            case 'm':
+                socketSend('get module menu', '')
+                break
+            default:
+                break
+        }
+    }
+
+    function writeModuleOptionMenu(modRep) {
+        var menuDom = document.createElement('div')
+        menuDom.id = 'perModuleMenu'
+        menuDom.style.left = 10 + modRep.ui.domElem.offsetLeft + modRep.ui.domElem.offsetWidth + 'px'
+        menuDom.style.top = modRep.ui.domElem.offsetTop + 'px'
+        // future: rm all inputs, rm all outputs, rename, open (heirarchy)
+        var opts = ['delete', 'copy']
+        for (i in opts) {
+            var li = document.createElement('li')
+            li.innerHTML = opts[i]
+            li.id = opts[i]
+            if (opts[i] == 'delete') {
+                li.addEventListener('click', function(evt) {
+                    var data = {
+                        id: modRep.description.id
+                    }
+                    socketSend('remove module', data)
+                    wrapper.removeChild(document.getElementById('perModuleMenu'))
+                })
+            } else if (opts[i] == 'copy') {
+                li.addEventListener('click', function(evt) {
+                    var data = modRep.description.path
+                    socketSend('put module', data)
+                    wrapper.removeChild(document.getElementById('perModuleMenu'))
+                })
+            }
+            menuDom.appendChild(li)
         }
-        menuDom.appendChild(li)
+        wrapper.append(menuDom)
+
+        function rmListener(evt) {
+            var findMenu = document.getElementById('perModuleMenu')
+            if (findMenu != null && findMenu.id == 'perModuleMenu') {
+                wrapper.removeChild(findMenu)
+            }
+            evt.target.removeEventListener(evt.type, arguments.callee)
+        }
+
+        document.addEventListener('click', rmListener)
     }
-    wrapper.append(menuDom)
 
-    function rmListener(evt) {
-        var findMenu = document.getElementById('perModuleMenu')
-        if (findMenu != null && findMenu.id == 'perModuleMenu') {
-            wrapper.removeChild(findMenu)
+
+    // return ul element with name and alt and link? 
+    // TODO: not properly a tree, see note @ reciprocal fn in views.js
+    function heapSendsModuleMenu(tree) {
+        var menuDom = document.createElement('div')
+        menuDom.id = 'moduleMenu'
+        menuDom.style.left = lastPos.x + 'px'
+        menuDom.style.top = lastPos.y + 'px'
+        var title = document.createElement('div')
+        title.className = 'title'
+        title.innerHTML = 'module menu'
+        menuDom.appendChild(title)
+        for (key in tree) {
+            var ul = document.createElement('ul')
+            var header = document.createElement('h4')
+            //ul.innerHTML = key.toString()
+            // create header for ul
+            header.innerHTML = key.toString()
+            ul.append(header)
+            for (subkey in tree[key]) {
+                var li = document.createElement('li')
+                var path = tree[key][subkey].path
+                li.innerHTML = subkey.toString()
+                li.id = path
+                li.addEventListener('mouseover', function(evt){                    
+                    rmDescription()//
+                    writeModuleDescription(evt)//
+                })
+                //////////////////////////////////////////////////////////
+                li.addEventListener('click', function(evt) {
+                    var data = this.id
+                    socketSend('put module', data)
+                    wrapper.removeChild(document.getElementById('moduleMenu'))
+                })
+                ul.appendChild(li)
+            }
+            menuDom.appendChild(ul)
+        }
+        wrapper.append(menuDom)
+
+        function rmListener(evt) {
+            var findMenu = document.getElementById('moduleMenu')
+            if (findMenu !== null && findMenu.id == 'moduleMenu') {
+                wrapper.removeChild(findMenu)
+            }
+            evt.target.removeEventListener(evt.type, arguments.callee)
         }
-        evt.target.removeEventListener(evt.type, arguments.callee)
+
+        document.addEventListener('click', rmListener)
     }
 
-    document.addEventListener('click', rmListener)
-}
-
-// return ul element with name and alt and link? 
-// TODO: not properly a tree, see note @ reciprocal fn in views.js
-function heapSendsModuleMenu(tree) {
-    var menuDom = document.createElement('div')
-    menuDom.id = 'moduleMenu'
-    menuDom.style.left = lastPos.x + 'px'
-    menuDom.style.top = lastPos.y + 'px'
-    var title = document.createElement('div')
-    title.className = 'title'
-    title.innerHTML = 'module menu'
-    menuDom.appendChild(title)
-    for (key in tree) {
-        var ul = document.createElement('ul')
-        ul.innerHTML = key.toString()
-        for (subkey in tree[key]) {
+    function heapSendsProgramMenu(tree) {
+        var menuDom = document.createElement('div')
+        menuDom.id = 'programMenu'
+        menuDom.style.left = lastPos.x + 'px'
+        menuDom.style.top = lastPos.y + 'px'
+        for (key in tree) {
             var li = document.createElement('li')
-            var path = tree[key][subkey].path
-            li.innerHTML = subkey.toString()
+            var path = tree[key].path
+            li.innerHTML = key.toString()
             li.id = path
             li.addEventListener('click', function(evt) {
                 var data = this.id
-                socketSend('put module', data)
-                wrapper.removeChild(document.getElementById('moduleMenu'))
+                socketSend('load program', data)
+                wrapper.removeChild(document.getElementById('programMenu'))
             })
-            ul.appendChild(li)
+            menuDom.appendChild(li)
         }
-        menuDom.appendChild(ul)
-    }
-    wrapper.append(menuDom)
+        wrapper.append(menuDom)
 
-    function rmListener(evt) {
-        var findMenu = document.getElementById('moduleMenu')
-        if (findMenu !== null && findMenu.id == 'moduleMenu') {
-            wrapper.removeChild(findMenu)
+        function rmListener(evt) {
+            var findMenu = document.getElementById('programMenu')
+            if (findMenu !== null && findMenu.id == 'programMenu') {
+                wrapper.removeChild(findMenu)
+            }
+            // rm this listner... 
+            evt.target.removeEventListener(evt.type, arguments.callee)
         }
-        evt.target.removeEventListener(evt.type, arguments.callee)
-    }
 
-    document.addEventListener('click', rmListener)
-}
-
-function heapSendsProgramMenu(tree) {
-    var menuDom = document.createElement('div')
-    menuDom.id = 'programMenu'
-    menuDom.style.left = lastPos.x + 'px'
-    menuDom.style.top = lastPos.y + 'px'
-    for (key in tree) {
-        var li = document.createElement('li')
-        var path = tree[key].path
-        li.innerHTML = key.toString()
-        li.id = path
-        li.addEventListener('click', function(evt) {
-            var data = this.id
-            socketSend('load program', data)
-            wrapper.removeChild(document.getElementById('programMenu'))
-        })
-        menuDom.appendChild(li)
+        document.addEventListener('click', rmListener)
     }
-    wrapper.append(menuDom)
 
-    function rmListener(evt) {
-        var findMenu = document.getElementById('programMenu')
-        if (findMenu !== null && findMenu.id == 'programMenu') {
-            wrapper.removeChild(findMenu)
+
+    // Paloma adds
+
+    // module descriptions
+    const moduleDescriptionsObj = 
+        {
+            and : 'this is the description for and',
+            atkbreadboard: 'this is the description for atkbreadboard',
+            atkseriallink: 'this is the description for atkseriallink',
+            atkstepper: 'this is the description for akstepper',
+            webcam : 'this is description for webcam',
+            planner: 'this is the description for planner',
+            rawmove: 'this is the description for rawmove',
+            gcode: 'this is the descriprion for gcode'  
         }
-        // rm this listner... 
-        evt.target.removeEventListener(evt.type, arguments.callee)
+
+    function writeModuleDescription(evt) {
+        let liRect = evt.target.getBoundingClientRect();
+        let menuDes = document.createElement('div')
+        menuDes.id = 'moduleDescription'
+        menuDes.style.left = 255 + liRect.left + 'px'
+        menuDes.style.top = liRect.top - 18 + 'px'
+        let parentEl = evt.target.parentElement
+        let headerKey = parentEl.firstChild.innerHTML
+        menuDes.innerHTML = moduleDescriptionsObj[evt.target.innerHTML]
+        wrapper.append(menuDes)
     }
 
-    document.addEventListener('click', rmListener)
-}
\ No newline at end of file
+    function rmDescription() {
+        let modDes = document.getElementById('moduleDescription')
+            if (modDes != null) {
+                wrapper.removeChild(modDes)
+            }
+        }
\ No newline at end of file
diff --git a/client/style.css b/client/style.css
index 7ad87f552315c08de4042d0d1e173f90182d32fc..4156d2e14efdac91259f5f0964da2a7290453b7f 100644
--- a/client/style.css
+++ b/client/style.css
@@ -122,6 +122,14 @@ li:active{
     background-color: #303030;
 }
 
+#moduleDescription {
+	position: absolute;
+    width: 245px;
+	padding: 10px;
+    background-color: #303030;
+    color: white;
+}
+
 #programMenu {
 	position: absolute;
 	width: 245px;
diff --git a/package-lock.json b/package-lock.json
index c36b3529307813e28adaeecb7bb29d35fef8edb5..625b7fa709520ae142ad6fae9b426b94371f9207 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -784,6 +784,11 @@
       "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
       "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk="
     },
+    "http": {
+      "version": "0.0.0",
+      "resolved": "https://registry.npmjs.org/http/-/http-0.0.0.tgz",
+      "integrity": "sha1-huYybSnF0Dnen6xYSkVon5KfT3I="
+    },
     "http-errors": {
       "version": "1.6.3",
       "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz",