diff --git a/README.md b/README.md
index a039fb36eeef9ca910520c399bba2610ade75867..07dcdda1640cebe9bf5f49c3948efdf16fb211bd 100644
--- a/README.md
+++ b/README.md
@@ -15,6 +15,16 @@ This project serves the developement environment / api we use to write and repre
 
 ## For MW
 
+ - top menu bar instructions 
+ - rick click on menu bar to delete module 
+
+ - upd8ts to modules:
+  - rename inout to jsunit
+  - buttons get onClick evt 
+
+ - as you test, to track, 
+  - weird state types solution: arrays, numbers, buttons, etc ?
+
  - GIFS
   - load a program
   - drag around
@@ -25,12 +35,6 @@ This project serves the developement environment / api we use to write and repre
   - rm modules
   - change settings 
 
- - right now
-  - push state down & up 
-   - note below : 
-   - not actually setting, do node main, change ms, watch console 
-  - some wholistic test ... 
-
  - *don't forget*
   - onload, load state... 
   - when hooking back to server, server.emitChange(key) ... from writeStateObject 
diff --git a/client/client.js b/client/client.js
index 69c0c79a6afcb4ad9ed70f6a67b9de19c6d216c0..84d0f845f5ef15076597fc85900393ece6328b83 100644
--- a/client/client.js
+++ b/client/client.js
@@ -66,6 +66,8 @@ window.onload = function() {
         }
         // others
         this.onerror = (err) => {
+            alert('link to server is broken')
+            location.reload()
             console.log('socket error', err)
         }
         this.onclose = (evt) => {
@@ -138,73 +140,6 @@ MISC ---------------------------------------------------
 
 */
 
-// 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'
-    for (key in tree) {
-        var ul = document.createElement('ul')
-        ul.innerHTML = key.toString()
-        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('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)
-    }
-
-    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)
-    }
-    wrapper.append(menuDom) 
-
-    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)
-    }
-
-    document.addEventListener('click', rmListener)
-}
 
 /*
 
@@ -215,7 +150,6 @@ HEAP -> SERVER ---------------------------------------------------
 // always a rep, tho
 var program = {}
 
-
 // re-writes the program, adds a description,
 // and loads multiple representations of modules to the view 
 
@@ -248,112 +182,6 @@ function heapSendsNewModule(mdl) {
 // and appends to the rep object a .ui object 
 // containing references to those DOM objects 
 
-function addRepToView(rep) {
-    // a div to locate it 
-    var domElem = document.createElement('div')
-    // dif. color for hardwares ?
-    domElem.className = 'block'
-    if (rep.description.isHardware) {
-        domElem.classList.add('hardware')
-    }
-    domElem.style.left = lastPos.x + 'px'
-    domElem.style.top = lastPos.y + 'px'
-
-    // more html: the title
-    var title = document.createElement('div')
-    title.className = 'modname'
-    title.innerHTML = rep.description.id
-    title.alt = rep.description.alt
-    domElem.appendChild(title)
-
-    var uiSetFlag
-    // place in pos if info present 
-    // the rep.ui object will store references to the module's related DOM elements
-    if (rep.description.position != null) {
-        uiSetFlag = false
-        if (rep.description.position.left != null) {
-            domElem.style.left = rep.description.position.left + 'px'
-        }
-        if (rep.description.position.top != null) {
-            domElem.style.top = rep.description.position.top + 'px'
-        }
-    } else {
-        uiSetFlag = true
-        rep.description.position = {}
-        rep.description.position.left = lastPos.x
-        rep.description.position.top = lastPos.y
-    }
-
-    if(rep.ui == null){
-        rep.ui = {}
-    }
-
-    rep.ui.domElem = domElem
-
-    // WRITE UI STATE ELEMENTS 
-    var stateElem = document.createElement('div')
-    stateElem.className = 'state'
-    rep.ui.state = {}
-    for (st in rep.state) {
-        var inputItem = writeStateRep(stateElem, rep, st)
-        rep.ui.state[st] = inputItem
-    }
-
-    // WRITE INPUTS 
-    var inElem = document.createElement('div')
-    inElem.className = 'inputs'
-    rep.ui.inputs = {}
-    for (ip in rep.inputs) {
-        var li = writeEventRep(rep, 'input', ip)
-        inElem.appendChild(li)
-        rep.ui.inputs[ip] = li
-    }
-
-    // WRITE OUTPUTS 
-    var outElem = document.createElement('div')
-    outElem.className = 'outputs'
-    rep.ui.outputs = {}
-    for (op in rep.outputs) {
-        var li = writeEventRep(rep, 'output', op)
-        outElem.appendChild(li)
-        rep.ui.outputs[op] = li
-    }
-
-    // APPEND TO CONTAINER
-    domElem.appendChild(inElem)
-    domElem.appendChild(outElem)
-    domElem.appendChild(stateElem)
-    var clearElem = document.createElement('div')
-    clearElem.className = 'clear'
-    domElem.appendChild(clearElem)
-
-    // MOVEABOUT CODE 
-    title.onmousedown = function(evt) {
-        offsetX = evt.clientX - domElem.getBoundingClientRect().left
-        offsetY = evt.clientY - domElem.getBoundingClientRect().top
-
-        function domElemMouseMove(mv) {
-            domElem.style.left = mv.pageX - offsetX + 'px'
-            domElem.style.top = mv.pageY - offsetY + 'px'
-            redrawLinks()
-        }
-
-        document.addEventListener('mousemove', domElemMouseMove)
-
-        title.onmouseup = function() {
-            rep.description.position.left = parseInt(domElem.style.left, 10)
-            rep.description.position.top = parseInt(domElem.style.top, 10)
-            putUi(rep)
-            document.removeEventListener('mousemove', domElemMouseMove)
-            title.onmouseup = null
-        }
-    }
-
-    wrapper.appendChild(rep.ui.domElem)
-    if(uiSetFlag){
-        putUi(rep)
-    }
-}
 
 function heapSendsModuleChange(data){
     console.log(data)
@@ -383,7 +211,9 @@ function heapSendsModuleChange(data){
 // update state from server to UI
 function heapSendsStateChange(data) {
     console.log('HEAP SENDS CHANGE STATE IN MODULE', data)
-    heapSendsModuleChange(data)
+    var rep = program.modules[data.id] 
+    rep.state[data.key] = data.val 
+    rep.ui.state[data.key].value = data.val 
 }
 
 /*
@@ -394,17 +224,12 @@ UI -> HEAP ---------------------------------------------------
 
 // push new state from UI to server 
 function putState(rep, key) {
-    // ship it all home: not perfect, but hey 
     var data = {
-        description: {
-            id: rep.description.id
-        },
-        state: {
-            key: key,
-            val: rep.state[key]
-        }
+        id: rep.description.id,
+        key: key, 
+        val: rep.state[key]
     }
-    socketSend('put state', data)
+    socketSend('put state change', data)
 }
 
 // save ui position to server for reload
@@ -419,12 +244,47 @@ function putUi(rep) {
         }
     }
 
-    socketSend('put ui', 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)
+        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)
+    }
 }
 
 /*
 
-UTILITIES? ---------------------------------------------------
+UTILITIES ---------------------------------------------------
 
 */
 
@@ -460,17 +320,6 @@ function redrawLinks() {
     }
 }
 
-
-// need top level rep of program - nice to think of how to handle heirarchy later on? tl rep is internal rep ... is same ? 
-// how to handle movement of rep, incl. svg - goes with moving mouse after 1st click: svg lives 'in' rep ? 
-
-// trying to do this top level from the program config itself, will try sending jsonified modules[] 
-
-// consistency with saved formats, written formats, sent... json objs
-
-var svgns = 'http://www.w3.org/2000/svg'
-var svg = {}
-
 /*
 
 UI EVENTS ---------------------------------------------------------------------
@@ -519,39 +368,70 @@ document.onkeydown = function(evt){
     }
 }
 
-// input / output click hookups 
+// 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'
+    for (key in tree) {
+        var ul = document.createElement('ul')
+        ul.innerHTML = key.toString()
+        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('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)
 
-var clkState = false
-var oClk = {}
-var tmpBz = {}
+    function rmListener(evt) {
+        var findMenu = document.getElementById('moduleMenu')
+        if (findMenu !== null && findMenu.id == 'moduleMenu') {
+            wrapper.removeChild(findMenu)
+        }
+        evt.target.removeEventListener(evt.type, arguments.callee)
+    }
 
-// input / output click handling
-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
-            }
+    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)
+    }
+    wrapper.append(menuDom) 
+
+    function rmListener(evt){
+        var findMenu = document.getElementById('programMenu') 
+        if(findMenu !== null && findMenu.id == 'programMenu'){
+            wrapper.removeChild(findMenu)
         }
-        socketSend('put link', data)
+        // rm this listner... 
+        evt.target.removeEventListener(evt.type, arguments.callee)
     }
-}
\ No newline at end of file
+
+    document.addEventListener('click', rmListener)
+}
diff --git a/client/divtools.js b/client/divtools.js
index ed2866c32d1ddd58cccd84a5a2f0d0a8b3458557..337a85cf5a4257bf169b8816b462f055be446479 100644
--- a/client/divtools.js
+++ b/client/divtools.js
@@ -1,5 +1,130 @@
 // writing representations
 
+
+function addRepToView(rep) {
+    // a div to locate it 
+    var domElem = document.createElement('div')
+    // dif. color for hardwares ?
+    domElem.className = 'block'
+    if (rep.description.isHardware) {
+        domElem.classList.add('hardware')
+    }
+    domElem.style.left = lastPos.x + 'px'
+    domElem.style.top = lastPos.y + 'px'
+
+    // more html: the title
+    var title = document.createElement('div')
+    title.className = 'modname'
+    title.innerHTML = rep.description.id
+    title.alt = rep.description.alt
+    domElem.appendChild(title)
+
+    var uiSetFlag
+    // place in pos if info present 
+    // the rep.ui object will store references to the module's related DOM elements
+    if (rep.description.position != null) {
+        uiSetFlag = false
+        if (rep.description.position.left != null) {
+            domElem.style.left = rep.description.position.left + 'px'
+        }
+        if (rep.description.position.top != null) {
+            domElem.style.top = rep.description.position.top + 'px'
+        }
+    } else {
+        uiSetFlag = true
+        rep.description.position = {}
+        rep.description.position.left = lastPos.x
+        rep.description.position.top = lastPos.y
+    }
+
+    if(rep.ui == null){
+        rep.ui = {}
+    }
+
+    rep.ui.domElem = domElem
+
+    // WRITE UI STATE ELEMENTS 
+    var stateElem = document.createElement('div')
+    stateElem.className = 'state'
+    rep.ui.state = {}
+    for (st in rep.state) {
+        var inputItem = writeStateRep(stateElem, rep, st)
+        rep.ui.state[st] = inputItem
+    }
+
+    // WRITE INPUTS 
+    var inElem = document.createElement('div')
+    inElem.className = 'inputs'
+    rep.ui.inputs = {}
+    for (ip in rep.inputs) {
+        var li = writeEventRep(rep, 'input', ip)
+        inElem.appendChild(li)
+        rep.ui.inputs[ip] = li
+    }
+
+    // WRITE OUTPUTS 
+    var outElem = document.createElement('div')
+    outElem.className = 'outputs'
+    rep.ui.outputs = {}
+    for (op in rep.outputs) {
+        var li = writeEventRep(rep, 'output', op)
+        outElem.appendChild(li)
+        rep.ui.outputs[op] = li
+    }
+
+    // APPEND TO CONTAINER
+    domElem.appendChild(inElem)
+    domElem.appendChild(outElem)
+    domElem.appendChild(stateElem)
+    var clearElem = document.createElement('div')
+    clearElem.className = 'clear'
+    domElem.appendChild(clearElem)
+
+    // MOVEABOUT CODE 
+    title.onmousedown = function(evt) {
+        offsetX = evt.clientX - domElem.getBoundingClientRect().left
+        offsetY = evt.clientY - domElem.getBoundingClientRect().top
+
+        function domElemMouseMove(mv) {
+            domElem.style.left = mv.pageX - offsetX + 'px'
+            domElem.style.top = mv.pageY - offsetY + 'px'
+            redrawLinks()
+        }
+
+        document.addEventListener('mousemove', domElemMouseMove)
+
+        title.onmouseup = function() {
+            rep.description.position.left = parseInt(domElem.style.left, 10)
+            rep.description.position.top = parseInt(domElem.style.top, 10)
+            putUi(rep)
+            document.removeEventListener('mousemove', domElemMouseMove)
+            title.onmouseup = null
+        }
+    }
+
+    wrapper.appendChild(rep.ui.domElem)
+    if(uiSetFlag){
+        putUi(rep)
+    }
+}
+
+function writeEventRep(rep, type, key) {
+    var li = document.createElement('li')
+    li.innerHTML = key.toString()
+    li.id = rep.id + ' ' + type + ' ' + key
+    li.addEventListener('click', (evt) => {
+        var ipclk = {
+            rep: rep,
+            type: type,
+            name: key,
+            evt: evt
+        }
+        console.log('clicked', key)
+        evtConnectHandler(ipclk)
+    })
+    return li
+}
+
 function writeStateRep(container, rep, key) {
     var variable = rep.state[key]
     switch (variable.type) {
@@ -8,12 +133,6 @@ function writeStateRep(container, rep, key) {
             var li = document.createElement('li')
             li.appendChild(document.createTextNode(variable.label))
             li.addEventListener('click', function() {
-                // invert 
-                if (rep.state[key].isPressed) {
-                    rep.state[key].isPressed = false
-                } else {
-                    rep.state[key].isPressed = true
-                }
                 putState(rep, key)
             })
             container.appendChild(li)
@@ -58,7 +177,7 @@ function writeStateRep(container, rep, key) {
                 input.type = 'text'
                 input.size = 24
                 input.value = variable.toString()
-                input.addEventListener('change', function() {
+                input.addEventListener('change', function(evt) {
                     rep.state[key] = parseFloat(input.value)
                     putState(rep, key)
                 })
@@ -92,25 +211,11 @@ function writeStateRep(container, rep, key) {
     }
 }
 
-function writeEventRep(rep, type, key) {
-    var li = document.createElement('li')
-    li.innerHTML = key.toString()
-    li.id = rep.id + ' ' + type + ' ' + key
-    li.addEventListener('click', (evt) => {
-        var ipclk = {
-            rep: rep,
-            type: type,
-            name: key,
-            evt: evt
-        }
-        console.log('clicked', key)
-        evtConnectHandler(ipclk)
-    })
-    return li
-}
 
 // bezier utilities
 
+var svgns = 'http://www.w3.org/2000/svg'
+var svg = {}
 
 function newBezier(x1, y1, x2, y2) {
     var bz = {}
diff --git a/lib/jsunit.js b/lib/jsunit.js
index 071b68d602d3c409561eff213eb88b10d8226673..1bc3075475210c7bddfe250c1a105db7f8f02f8f 100644
--- a/lib/jsunit.js
+++ b/lib/jsunit.js
@@ -66,7 +66,7 @@ function State() {
             this.emitters[item]()
         }
     }
-
+    
     return state
 }
 
diff --git a/main.js b/main.js
index 07ede52c69609cd9ba16c076cf75459e5cff101e..51c6645f7729326e98af4a5d194c5f9044056c70 100644
--- a/main.js
+++ b/main.js
@@ -23,6 +23,7 @@ programs are assemblies of modules
 
 */
 
+// business 
 const Reps = require('./reps.js')
 const Programs = require('./programs.js')
 
@@ -30,109 +31,11 @@ var program = {}
 
 program = Programs.open('programs/default.json')
 
+
+// UI 
 const View = require('./views.js')
 View.startHttp() 
 View.startWs() 
 
 Programs.assignSocket(View.uiSocket)
 View.assignProgram(program)
-
-/*
-
-PROGRAM REPRESENT 
-
-*/
-
-/*
-
-// update state from UI to server 
-function changeState(data) {
-    // of one module 
-    // should just recv all state, walk tree for differences
-    var oldState = modules[data.id].state
-    var newState = data.state
-    // rep only holds proper key-values w/o emitters, _values etc
-    for (var key in newState) {
-        if (isStateKey(key)) {
-            if (oldState[key].isButton) {
-                if (oldState[key].isPressed != newState[key].isPressed) {
-                    console.log('CHANGE BUTTON STATE', key, 'to', newState[key], 'in', data.id)
-                    // this will trigger some 'onChange' f'ns
-                    // that might change some state
-                    oldState[key] = newState[key]
-                    // to prevent quickly changing it back, we'll exit now (one state change from UI per trx)
-                    return true
-                }
-            } else if (oldState[key].isMultiLine) {
-                if (oldState[key].value != newState[key].value) {
-                    console.log('CHANGE MULTILINE STATE', key, 'to', newState[key].value, 'in', data.id)
-                    oldState[key].value = newState[key].value
-                    return true
-                }
-            } else if (oldState[key] !== newState[key]) {
-                console.log('CHANGE STATE', key, 'to', newState[key], 'in', data.id)
-                oldState[key] = newState[key]
-                return true
-            }
-        }
-    }
-}
-
-function changeUi(data) {
-    var mod = modules[data.id]
-    if (mod.ui == null) {
-        console.log("NO UI")
-        mod.ui = {}
-    }
-    mod.ui = data.ui
-    console.log('CHANGE UI', mod.id, mod.ui)
-}
-
-function setUiPos(module, left, top) {
-    if (module.ui == null) {
-        module.ui = {}
-    }
-    module.ui.left = left
-    module.ui.top = top
-}
-
-// push new state from server to UI
-function putState(mod) {
-    // push just the state to the individual mod
-    // copy only the keys we want to see 
-    var state = {}
-    for (var key in mod.state) {
-        if (isStateKey(key)) {
-            state[key] = mod.state[key]
-        }
-    }
-    var data = {
-        id: mod.id,
-        state: state
-    }
-    socketSend('change state', data)
-}
-
-function putLink(data) {
-    var fromModule = modules.find((module) => {
-        return module.id === data.from.id
-    })
-
-    var toModule = modules.find((module) => {
-        return module.id === data.to.id
-    })
-
-    if (fromModule.outputs[data.from.output].isLinked(toModule.inputs[data.to.input])) {
-        console.log("HOOKDOWN")
-        fromModule.outputs[data.from.output].remove(toModule.inputs[data.to.input])
-    } else {
-        fromModule.outputs[data.from.output].attach(toModule.inputs[data.to.input])
-    }
-
-    // replace it 
-    changeRep(fromModule)
-}
-
-*/
-
-// put
\ No newline at end of file
diff --git a/programs.js b/programs.js
index 9959f93a988cbe6a749fd6b347672d74ecd3408b..427ce16d1c92f9bba0586a0800613f8a60243222 100644
--- a/programs.js
+++ b/programs.js
@@ -72,7 +72,7 @@ function writeStateObject(mod, key) {
             // when we change it within the module 
             // this.emitChange(key)
             // push to external view
-            if(link){
+            if(socket){
                 pushState(mod, key)
             }
         }
@@ -96,8 +96,12 @@ function assignSocket(sckt){
 }
 
 function pushState(mod, key){
-    console.log("GONNA PUSH IT OOOOOUT")
-    console.log('link', socket)
+    var data = {
+        id: mod.description.id,
+        key: key,
+        val: mod.state[key]
+    }
+    socket.send('put state change', data)
 }
 
 
diff --git a/src/util/delay.js b/src/util/delay.js
index d7f8500fcbf577dcc728e32a8fc76bdfcddbe2e2..abf1b6fa6ce81b7dce81e941ed812151eb40bd86 100644
--- a/src/util/delay.js
+++ b/src/util/delay.js
@@ -21,6 +21,7 @@ function Delay() {
     var state = delay.state
 
     state.ms = 100
+    state.onChange('ms', onMsChange)
 
     delay.inputs = {
         thru: Input('any', onDelayBegin) // makes anything into '1' event
@@ -30,6 +31,11 @@ function Delay() {
         out: Output('any')
     }
 
+    function onMsChange(){
+        console.log("noting state change", state.ms)
+        state.ms = 1200
+    }
+
     function onDelayBegin(input){
         setTimeout(function(){
             delay.outputs.out.emit(input)
diff --git a/src/util/gate.js b/src/util/gate.js
index 100706779262c6b337d5d6056f5a9e3c55557565..cb46f95703784131cdc2e471ea5ea989160d452f 100644
--- a/src/util/gate.js
+++ b/src/util/gate.js
@@ -15,13 +15,12 @@ function Gate() {
             alt: 'in ... out'
         }
     }
-    
+
     gate.state = State()
     // alias ! 
     var state = gate.state 
 
-    state.toggle = Button("Open / Close")
-    state.onChange('toggle', onButtonPress)
+    state.toggle = Button("Open / Close", onButtonPress)
     // yikes 
     gate.isOpen = false
     state.message = 'closed'
@@ -35,6 +34,7 @@ function Gate() {
     }
 
     function onButtonPress(evt){
+        console.log("GATE BUTTON")
         state.toggle.isPressed = false
         if(gate.isOpen){
             gate.isOpen = false
diff --git a/views.js b/views.js
index 44a6514608e94e736dfb8b259153b942fbe1754a..6f7416d1faa08c269edee89fda93913a243f5ea6 100644
--- a/views.js
+++ b/views.js
@@ -99,14 +99,14 @@ function socketRecv(evt) {
         case 'put module':
             uiRequestNewModule(data)
             break
-        case 'put state':
+        case 'put state change':
             uiRequestStateChange(data)
             break
-        case 'put link':
+        case 'put link change':
             uiRequestLinkChange(data)
             // id:output > id:input
             break
-        case 'put ui':
+        case 'put ui change':
             uiRequestUiChange(data)
             break
         default:
@@ -226,36 +226,26 @@ function uiRequestNewModule(data) {
 
 function uiRequestStateChange(data) {
     console.log('UI REQUEST CHANGE STATE IN MODULE', data)
-    // there should only be one ! 
-    var id = data.description.id
-    var key = data.state.key
-    var val = data.state.val
-
-    var mdlState = program.modules[id].state
-    console.log('mdlState', mdlState)
-    var mdlStateItem = program.modules[id].state[key]
-    console.log('mdlStateItem', mdlStateItem)
-
-    if (mdlStateItem) {
-        switch (mdlState.type) {
+
+    var mdlState = program.modules[data.id].state
+
+    if (mdlState[data.key]) {
+        switch (mdlState[data.key].type) {
             case 'button':
-                mdlStateItem.onClick()
+                mdlState[data.key].onClick()
                 break
             case 'multiline':
-                mdlStateItem.value = val
-                mdlState.emitChange(key)
+                mdlState[data.key].value = data.val 
+                mdlState.emitChange(data.key)
                 break
             default:
-                mdlStateItem = val
-                mdlState.emitChange(key)
+                mdlState[data.key] = data.val 
+                mdlState.emitChange(data.key)
                 break
         }
     } else {
         console.log("ERR no state key,", key, "found here", data)
     }
-
-    console.log('mdlStateItem', mdlStateItem)
-    console.log(program.modules[id])
 }
 
 function uiRequestLinkChange(data) {
@@ -265,14 +255,17 @@ function uiRequestLinkChange(data) {
     var toId = data.to.id
     var inputName = data.to.input
 
-    // HERE: check if hooked already 
-
     var fromMdl = program.modules[fromId]
     var toMdl = program.modules[toId]
-    fromMdl.outputs[outputName].attach(toMdl.inputs[inputName])
 
-    var nRep = Reps.makeFromModule(fromMdl)
+    // if it's already attached, we rm
+    if(fromMdl.outputs[outputName].isLinked(toMdl.inputs[inputName])){
+        fromMdl.outputs[outputName].remove(toMdl.inputs[inputName])
+    } else {
+        fromMdl.outputs[outputName].attach(toMdl.inputs[inputName])
+    }
 
+    var nRep = Reps.makeFromModule(fromMdl)
     socketSend('put module change', nRep)
 }