diff --git a/README.md b/README.md
index 8f5252e1c1436815c8d426f7e7a53202fcdcb39f..857af22367ca5c7cc4c0a47fb653e83ef8dbf822 100644
--- a/README.md
+++ b/README.md
@@ -126,6 +126,16 @@ To wake up, I've a small list:
  - same for comm/
  - rebuild / use scrape.js (with //HEADER and //ENDHEADER flags)
 
+There's some UI leftovers in the view.
+ - want to kick around on spreading things out properly using force layout
+ - can't add links, did this actually work before ? drag correct zoom factor, and cancel other moves
+
+- towards using state-load-at-program-load to set retrycount to 0 
+
+- loading is messy,
+ - load in state objects before init (rolling through much old code)
+ - view should have display location for messages you anticipate users needing to see, primarily errors that are responses to view requests: like addlink (type errors) or addhunk (resource not available from cpp) or errors from hunk v8 loading, json program loading, etc.
+
 Once I'm through that, I should be back at happily opening up nautilus-via-cuttlefish. I'll polish my UI, particularly wire views.
 
 I'll explicate the list of messages that I need to send to managers, and to links.
@@ -140,7 +150,17 @@ Messages to 254 port are debug, should just be printed. Messages to 253 are to t
 
 What's stopping me from implementing this? Am I burnt out?
 
-I think this also asks me to reconsider how programs are loaded. Does it? No. It's actually a good test of the existing system. 
+I think this also asks me to reconsider how programs are loaded. Does it? No. It's actually a good test of the existing system.
+
+So, there's a lot to do. It's a good thing I love JavaScript: every language's bastard son, in a King of the North kind of way.
+
+ - state objects are typed,
+ - state objects are written at program load, if they're there.
+  - does this mean that they go into 'add hunk' message ?
+ - reload link verbatim but via state-load
+ - then scrape to nautilus ... and load via ws
+  - maybe then is view cleanup ?
+
 
 ## A List of Types
 
diff --git a/gogetter.js b/gogetter.js
index ed0dae9a7d4156fd16bf6e1c4155a7890fc7c258..6c2dadfe0d97d1ec52a0bc4f0242e76552814423 100644
--- a/gogetter.js
+++ b/gogetter.js
@@ -1,12 +1,12 @@
-// fs abstraction for sys 
+// fs abstraction for sys
 
 function GoGetter() {
     this.findHunks = (debug) => {
         return new Promise((resolve, reject) => {
             let htmlTreeDiver = (response) => {
-                // do we try to pick links out of this plaintext ? like a monkey ? 
-                // I suppose we do 
-                // header, for names 
+                // do we try to pick links out of this plaintext ? like a monkey ?
+                // I suppose we do
+                // header, for names
                 let hfront = response.indexOf('<h1>Index of /hunks') + 14
                 let hback = response.indexOf('</h1>')
                 let header = response.slice(hfront, hback)
@@ -20,7 +20,7 @@ function GoGetter() {
                 // git those paths (these aren't names, are they?)
                 let paths = response.split('<a href="/hunks/')
                 // rm first two, and last ()
-                paths = paths.slice(2) // 
+                paths = paths.slice(2) //
 
                 paths.forEach((path, index) => {
                     let end = path.indexOf('"')
@@ -37,10 +37,10 @@ function GoGetter() {
                         jQuery.get(recurse, htmlTreeDiver)
                     } else if (path.includes('.js')) {
                         //console.log('likely hunk', path)
-                        // secrets are rming .js 
+                        // secrets are rming .js
                         path = path.slice(0, path.indexOf('.'))
                         if (path === 'hunks' || path === 'manager' || path === 'template' || path.includes('hidden/')) {
-                            // don't add these special hunks 
+                            // don't add these special hunks
                         } else {
                             returned.push(path)
                         }
@@ -48,9 +48,9 @@ function GoGetter() {
                 })
 
                 if (unreturned.length === 0) {
-                    // TODO cull hunks and hidden paths ... 
-                    // now, writing menu options for each path 
-                    // sort alphabetically 
+                    // TODO cull hunks and hidden paths ...
+                    // now, writing menu options for each path
+                    // sort alphabetically
                     returned.sort()
                     //console.log('GG returns this', JSON.parse(JSON.stringify(returned)))
                     resolve(returned)
@@ -81,7 +81,7 @@ function GoGetter() {
 
             window[tempGlobal] = function(module) {
                 cleanup()
-                console.log('ADDHUNK (2) import resolves', url)
+                //console.log('ADDHUNK (2) import resolves', url)
                 resolve(module[Object.keys(module)[0]])
             }
 
@@ -101,7 +101,7 @@ function GoGetter() {
         return new Promise((resolve, reject) => {
             $.ajax({
             	url: path,
-            	type: 'GET', 
+            	type: 'GET',
             	success: (data) => {
             		resolve(data)
             	},
@@ -113,4 +113,4 @@ function GoGetter() {
     }
 }
 
-export default GoGetter
\ No newline at end of file
+export default GoGetter
diff --git a/hunks/hunks.js b/hunks/hunks.js
index 9134a88ad982f74b2910e03876cac7ec4d11e8a4..ad8053e6214ced4027d993b11637d1439d67870c 100644
--- a/hunks/hunks.js
+++ b/hunks/hunks.js
@@ -123,6 +123,7 @@ function Output(type, name) {
 function State(type, name, startup) {
   this.name = name
   this.type = type
+  // TODO pls add check for missing startup value ? 
   this.value = startup
   // this is still something of a hack
   // during load, the manager gets in here and dishes a function 2 us
diff --git a/hunks/link.js b/hunks/link.js
index c17f88e24305dbb91919cb0eb80566c11ccf07e2..79994e5d8a14013d4e6e448e996d6417c83ba6ea 100644
--- a/hunks/link.js
+++ b/hunks/link.js
@@ -22,6 +22,14 @@ function Link() {
   this.inputs.data = new Input('byteArray', 'data')
   this.outputs.data = new Output('byteArray', 'data')
 
+  this.state.inputList = new State('string', 'inputList', "msgs (byteArray)")
+  this.state.outputList = new State('string', 'outputList', "msgs (byteArray)")
+
+  let inports = [this.inputs.zero, this.inputs.zero, this.inputs.one]
+  let outports = [this.outputs.zero, this.outputs.zero]
+
+  /*
+
   // these are *special link inputs* keeping track of downstream status
   this.inputs.zero = new Input('any', 'zero')
   this.inputs.zero.dss = 'open'
@@ -44,10 +52,13 @@ function Link() {
   this.outputs.one.hold.status = 'open'
   this.outputs.one.hold.msg = {}
 
+  */
+
   this.init = () => {
     // manager calls this once
     // it is loaded and state is updated (from program)
     this.log('hello Link')
+    // HERE write those inputs via that list
   }
 
   // so far we won't ack at the link layer,
@@ -56,8 +67,6 @@ function Link() {
   // but we will need to do this for the dmarippers
   // perhaps that should live in the layer that 'websocket' is at now
 
-  let inports = [this.inputs.zero, this.inputs.zero, this.inputs.one]
-  let outports = [this.outputs.zero, this.outputs.zero]
 
   let outbuffer = new Array()
 
@@ -82,6 +91,7 @@ function Link() {
 
   this.loop = () => {
 
+    /*
     // for everything we're holding, check our outputs
     for (let i in outports) {
       if (outports[i].hold.status === 'occupied' && outports[i].ie) {
@@ -168,6 +178,7 @@ function Link() {
     if (this.outputs.data.ie && outbuffer.length > 0) {
       this.outputs.data.put(outbuffer.shift())
     }
+    */
   } // end loop
 }
 
diff --git a/hunks/manager.js b/hunks/manager.js
index 6ee48c1d956a87364961525c278c4133dfcb7bc5..3f0700e131752972826c2f4d57c230b19a1ce8b9 100644
--- a/hunks/manager.js
+++ b/hunks/manager.js
@@ -1,617 +1,651 @@
-import { Hunkify, Input, Output, State } from './hunks.js'
+import {
+  Hunkify,
+  Input,
+  Output,
+  State
+} from './hunks.js'
 
 import GoGetter from '../gogetter.js'
 
 function Manager() {
-    Hunkify(this, 'Manager')
-    // need this tool
-    let GG = new GoGetter
-
-    this.inputs.msgs = new Input('message', 'msgs')
-    this.outputs.msgs = new Output('message', 'msgs')
-
-    let hunkCount = 0
-    let hunks = new Array()
-
-    /* ---------------------------    ---------------------------- */
-    /* -------------------- STD MGR INTERFACE -------------------- */
-    /* ---------------------------    ---------------------------- */
-
-    this.getHelloResponses = () => {
-        // writeMessage does buffering on our end
-        return [{
-                text: 'list available hunks',
-                header: 'listhunks',
-                content: ' '
-            },
-            {
-                text: 'describe running program',
-                header: 'listprogram',
-                content: ' '
-            },
-            {
-                text: 'save running program',
-                header: 'saveprogram',
-                content: ' '
-            }
-        ]
-    }
-
-    /* ---------------------------    ---------------------------- */
-    /* ---------------------- BUILDING LIST ---------------------- */
-    /* ---------------------------    ---------------------------- */
-
-    // for now, managers take callback paths to pipe data back through ? 
-    this.getListOfAvailableHunks = () => {
-        return new Promise((resolve, reject) => {
-            GG.findHunks().then((list) => {
-                resolve(list)
-            }).catch((err) => {
-                reject(err)
-            })
-        })
+  Hunkify(this, 'Manager')
+  // need this tool
+  let GG = new GoGetter
+
+  this.inputs.msgs = new Input('message', 'msgs')
+  this.outputs.msgs = new Output('message', 'msgs')
+
+  let hunkCount = 0
+  let hunks = new Array()
+
+  /* ---------------------------    ---------------------------- */
+  /* -------------------- STD MGR INTERFACE -------------------- */
+  /* ---------------------------    ---------------------------- */
+
+  this.getHelloResponses = () => {
+    // writeMessage does buffering on our end
+    return [{
+        text: 'list available hunks',
+        header: 'listhunks',
+        content: ' '
+      },
+      {
+        text: 'describe running program',
+        header: 'listprogram',
+        content: ' '
+      },
+      {
+        text: 'save running program',
+        header: 'saveprogram',
+        content: ' '
+      }
+    ]
+  }
+
+  let errmsg = (message) => {
+    this.writemessage('error', message)
+  }
+
+  /* ---------------------------    ---------------------------- */
+  /* ---------------------- BUILDING LIST ---------------------- */
+  /* ---------------------------    ---------------------------- */
+
+  // for now, managers take callback paths to pipe data back through ?
+  this.getListOfAvailableHunks = () => {
+    return new Promise((resolve, reject) => {
+      GG.findHunks().then((list) => {
+        resolve(list)
+      }).catch((err) => {
+        reject(err)
+      })
+    })
+  }
+
+  /* ---------------------------    ---------------------------- */
+  /* ----------------- REPLY WITH DESCRIPTIONS ----------------- */
+  /* ---------------------------    ---------------------------- */
+
+  this.describeRunningProgram = () => {
+    for (let hnk in hunks) {
+      this.sendHunkAsDef(hunks[hnk])
     }
+  }
 
-    /* ---------------------------    ---------------------------- */
-    /* ----------------- REPLY WITH DESCRIPTIONS ----------------- */
-    /* ---------------------------    ---------------------------- */
+  this.sendHunkAsDef = (hunk) => {
+    let def = writeDefinition(hunk)
+    this.writemessage('putdef', def)
+  }
 
-    this.describeRunningProgram = () => {
-        for (let hnk in hunks) {
-            this.sendHunkAsDef(hunks[hnk])
-        }
+  // bit confusing this / but is functional code node oo
+  let writeDefinition = (hunk) => {
+    if (hunk.id === null) {
+      throw new Error('hunk with no id in writeHunkDefinition')
     }
-
-    this.sendHunkAsDef = (hunk) => {
-        let def = writeDefinition(hunk)
-        this.writemessage('putdef', def)
+    // ok
+    // write tree
+    let def = {
+      name: hunk.name,
+      id: hunk.id,
+      inputs: {},
+      outputs: {},
+      state: {}
     }
 
-    // bit confusing this / but is functional code node oo 
-    let writeDefinition = (hunk) => {
-        if (hunk.id === null) {
-            throw new Error('hunk with no id in writeHunkDefinition')
-        }
-        // ok 
-        // write tree 
-        let def = {
-            name: hunk.name,
-            id: hunk.id,
-            inputs: {},
-            outputs: {},
-            state: {}
-        }
-
-        // add inputs
-        if (Object.keys(hunk.inputs).length > 0) {
-            for (let key in hunk.inputs) {
-                let input = hunk.inputs[key]
-                def.inputs[input.name] = {
-                    name: input.name,
-                    type: input.type
-                }
-            }
+    // add inputs
+    if (Object.keys(hunk.inputs).length > 0) {
+      for (let key in hunk.inputs) {
+        let input = hunk.inputs[key]
+        def.inputs[input.name] = {
+          name: input.name,
+          type: input.type
         }
+      }
+    }
 
-        // add outputs
-        if (Object.keys(hunk.outputs).length > 0) {
-            for (let key in hunk.outputs) {
-                let output = hunk.outputs[key]
-                def.outputs[output.name] = {
-                    name: output.name,
-                    type: output.type,
-                    connections: new Array()
-                }
-                if (output.connections.length > 0) {
-                    for (let conn in output.connections) {
-                        let crep = {
-                            input: output.connections[conn].input.name,
-                            parentid: output.connections[conn].parentid
-                        }
-                        def.outputs[output.name].connections.push(crep)
-                    }
-                }
-            }
+    // add outputs
+    if (Object.keys(hunk.outputs).length > 0) {
+      for (let key in hunk.outputs) {
+        let output = hunk.outputs[key]
+        def.outputs[output.name] = {
+          name: output.name,
+          type: output.type,
+          connections: new Array()
         }
-
-        // add outputs
-        if (Object.keys(hunk.state).length > 0) {
-            for (let key in hunk.state) {
-                let state = hunk.state[key]
-                def.state[state.name] = {
-                    name: state.name,
-                    type: state.type,
-                    value: state.value
-                }
+        if (output.connections.length > 0) {
+          for (let conn in output.connections) {
+            let crep = {
+              input: output.connections[conn].input.name,
+              parentid: output.connections[conn].parentid
             }
+            def.outputs[output.name].connections.push(crep)
+          }
         }
-
-        if (hunk.dom !== null) {
-            //console.log('WHD has dom', hunk.dom)
-            def.dom = hunk.dom
-        }
-
-        return def
+      }
     }
 
-    this.findHunkById = (id) => {
-        let theHunk = hunks.find((hunk) => {
-            return hunk.id === id
-        })
-        if (theHunk !== undefined) {
-            return theHunk
-        } else {
-            return undefined
+    // add outputs
+    if (Object.keys(hunk.state).length > 0) {
+      for (let key in hunk.state) {
+        let state = hunk.state[key]
+        def.state[state.name] = {
+          name: state.name,
+          type: state.type,
+          value: state.value
         }
+      }
     }
 
-    /* ---------------------------    ---------------------------- */
-    /* ------------------- ADD / REMOVE A HUNK ------------------- */
-    /* ---------------------------    ---------------------------- */
-
-    this.addHunk = (hunkName, id) => {
-        // hunks are named by path in js 
-        // so that we can add
-        // so that we can link 
-        // so that we can go to links, websockets, node 
-        let path = './hunks/' + hunkName + '.js'
-
-        return new Promise((resolve, reject) => {
-            GG.importSource(path).then((src) => {
-                try {
-                    let hunk = sourceToHunk(src, hunkName, id)
-                    hunks.push(hunk)
-                    this.sendHunkAsDef(hunk)
-                    resolve(hunk)
-                } catch (err) {
-                    reject(err)
-                }
-            }).catch((err) => {
-                reject(err)
-            })
-        })
+    if (hunk.dom !== null) {
+      //console.log('WHD has dom', hunk.dom)
+      def.dom = hunk.dom
     }
 
-    let sourceToHunk = (src, name, id) => {
-        // make the instance from the constructor
-        let hunk = new src()
-        // name it (this is just the path)
-        hunk.name = name
-
-        // id it, with a new ID if it doesn't have one, or 
-        // with the ID from its program (occasionally provided) s
-        if (id !== undefined && id !== null) {
-            // TODO: BIGBOI: also check for duplicate ids ?? totally possible, very likely 
-            hunk.id = id
-        } else {
-            // TODO: probably there is a better id, and what of program loads?
-            hunk.id = 'hnk_' + hunkCount
-        }
-        hunkCount++
-
-        // now we open our doors to state changes
-        if (Object.keys(hunk.state).length > 0) {
-            for (let st in hunk.state) {
-                hunk.state[st].hookup = (value) => {
-                    console.log('MGR -> VIEW STATECHANGE')
-                    this.writemessage('putstate', {
-                        id: hunk.id,
-                        name: hunk.state[st].name,
-                        value: value
-                    })
-                }
-            }
-        }
-
-        // startup code if it exists 
-        if (hunk.init != null) {
-            try {
-                hunk.init()
-            } catch (err) {
-                throw err
-            }
+    return def
+  }
+
+  this.findHunkById = (id) => {
+    let theHunk = hunks.find((hunk) => {
+      return hunk.id === id
+    })
+    if (theHunk !== undefined) {
+      return theHunk
+    } else {
+      return undefined
+    }
+  }
+
+  /* ---------------------------    ---------------------------- */
+  /* ------------------- ADD / REMOVE A HUNK ------------------- */
+  /* ---------------------------    ---------------------------- */
+
+  this.addHunk = (hunkName, id, state) => {
+    // hunks are named by path in js
+    // so that we can add
+    // so that we can link
+    // so that we can go to links, websockets, node
+    let path = './hunks/' + hunkName + '.js'
+
+    return new Promise((resolve, reject) => {
+      GG.importSource(path).then((src) => {
+        try {
+          let hunk = sourceToHunk(src, hunkName, id, state)
+          hunks.push(hunk)
+          this.sendHunkAsDef(hunk)
+          resolve(hunk)
+        } catch (err) {
+          reject(err)
         }
-
-        return hunk
+      }).catch((err) => {
+        reject(err)
+      })
+    })
+  }
+
+  let sourceToHunk = (src, name, id, state) => {
+    // make the instance from the constructor
+    let hunk = new src()
+    // name it (this is just the path)
+    hunk.name = name
+
+    // id it, with a new ID if it doesn't have one, or
+    // with the ID from its program (occasionally provided) s
+    if (id !== undefined && id !== null) {
+      // TODO: BIGBOI: also check for duplicate ids ?? totally possible, very likely
+      hunk.id = id
+    } else {
+      // TODO: probably there is a better id, and what of program loads?
+      hunk.id = 'hnk_' + hunkCount
     }
-
-    this.removeHunk = (req) => {
-        let id = req.id
-        let name = req.name
-        if (name == 'manager' || name == 'hidden/view') {
-            throw new Error("I can't let you do that, Dave")
-            return false
-        } else {
-            let hnk = hunks.find((element) => {
-                return id === element.id
-            })
-            if (hnk !== undefined) {
-                // rm then 
-                hunks.splice(hunks.indexOf(hnk), 1)
-                for (let hks of hunks) {
-                    for (let otp of Object.keys(hks.outputs)) {
-                        hks.outputs[otp].unhook(id)
-                    }
-                }
-                return true
-            } else {
-                return false
-            }
+    hunkCount++
+
+    // now we open our doors to state changes
+    if (Object.keys(hunk.state).length > 0) {
+      for (let st in hunk.state) {
+        hunk.state[st].hookup = (value) => {
+          // console.log('MGR -> VIEW STATECHANGE')
+          this.writemessage('putstate', {
+            id: hunk.id,
+            name: hunk.state[st].name,
+            value: value
+          })
         }
+      }
     }
 
-    /* ---------------------------    ---------------------------- */
-    /* ----------------- LINKS HELLO / GOODBYTE ------------------ */
-    /* ---------------------------    ---------------------------- */
-
-    this.addLink = (outHunkId, outputName, inHunkId, inputName) => {
-        // sync, doesn't need to be a promise
-        let outHunk = hunks.find((hunk) => {
-            return hunk.id == outHunkId
-        })
-        let inHunk = hunks.find((hunk) => {
-            return hunk.id == inHunkId
-        })
-        // console.log('found hunks', outHunk, inHunk)
-        if (outHunk === undefined) {
-            console.log("MGR on ADDLINK: outHunk is undefined", outHunkId)
-            return false
-        }
-        if (inHunk === undefined) {
-            console.log("MGR on ADDLINK: inHunk is undefined", inHunkId)
-            return false
-        }
-        if (outHunk.outputs[outputName] === null || outHunk.outputs[outputName] === undefined) {
-            console.log('MGR on ADDLINK: output hunk is null or undefined:', outHunk.name, outputName)
-            return false
-        } else if (inHunk.inputs[inputName] === null || inHunk.inputs[inputName] === undefined) {
-            console.log('MGR on ADDLINK: input hunk is null or undefined:', inHunk.name, inputName)
-            return false
+    // now we update it's state if we have any of *that* to do
+    if(state !== undefined && state !== null){
+      for(let ro in state){
+        // ro is the key
+        if(hunk.state[ro] !== undefined){
+          console.log('types', typeof hunk.state[ro].value, typeof state[ro])
+          if(typeof hunk.state[ro].value == typeof state[ro]){
+            hunk.state[ro].value = state[ro]
+          } else {
+            this.writemessage('error', 'problematic state content in program, not same type')
+          }
         } else {
-            this.log(`hooking ${outHunk.id} to ${inHunk.id}`)
-            outHunk.outputs[outputName].attach(inHunk.inputs[inputName], inHunk.id)
-            this.writemessage('putlink', {
-                outId: outHunkId,
-                outName: outputName,
-                inId: inHunkId,
-                inName: inputName
-            })
-            return true
+          this.writemessage('error', 'problematic state content in program, object not found')
         }
+      }
     }
 
-    this.addLinkByObject = (fromHunk, outputName, toHunk, inputName) => {
-        // TODO: not throwing errors when outputname does not exist 
-        // I.E. addLink doesn't actually use 'name' property, it uses [key]
-        this.addLink(fromHunk.id, outputName, toHunk.id, inputName)
+    // startup code if it exists
+    if (hunk.init != null) {
+      try {
+        hunk.init()
+      } catch (err) {
+        throw err
+      }
     }
 
-    this.removeLink = (outHunkId, outputName, inHunkId, inputName) => {
-        // console.log('REMOVELINK looking for hunk, with name, and in, with name', outHunkId, outputName, inHunkId, inputName)
-        let outHunk = hunks.find((hunk) => {
-            return hunk.id == outHunkId
-        })
-        let inHunk = hunks.find((hunk) => {
-            return hunk.id == inHunkId
-        }) // console.log('found hunks', outHunk, inHunk)
-        if (outHunk === undefined || inHunk === undefined) {
-            console.log("MGR on REMOVELINK: output or input hunks are undefined")
-            return false
-        }
-        if (outHunk.outputs[outputName] === null || outHunk.outputs[outputName] === undefined) {
-            console.log('MGR on REMOVELINK: output hunk is null or undefined:', outHunk.name, outputName)
-            return false
-        } else if (inHunk.inputs[inputName] === null || inHunk.inputs[inputName] === undefined) {
-            console.log('MGR on REMOVELINK: input hunk is null or undefined:', inHunk.name, inputName)
-            return false
-        } else {
-            this.log(`unhooking ${outHunk.id} to ${inHunk.id}`)
-            if (outHunk.outputs[outputName].remove(inHunk.inputs[inputName], inHunk.id)) {
-                this.writemessage('removelink', {
-                    outId: outHunkId,
-                    outName: outputName,
-                    inId: inHunkId,
-                    inName: inputName
-                })
-                return true
-            } else {
-                return false
-            }
+    return hunk
+  }
+
+  this.removeHunk = (req) => {
+    let id = req.id
+    let name = req.name
+    if (name == 'manager' || name == 'hidden/view') {
+      throw new Error("I can't let you do that, Dave")
+      return false
+    } else {
+      let hnk = hunks.find((element) => {
+        return id === element.id
+      })
+      if (hnk !== undefined) {
+        // rm then
+        hunks.splice(hunks.indexOf(hnk), 1)
+        for (let hks of hunks) {
+          for (let otp of Object.keys(hks.outputs)) {
+            hks.outputs[otp].unhook(id)
+          }
         }
+        return true
+      } else {
+        return false
+      }
     }
-
-    /* ---------------------------    ---------------------------- */
-    /* ---------------------- STATE CHANGES ---------------------- */
-    /* ---------------------------    ---------------------------- */
-
-    this.stateChange = (hunkId, stateName, newValue) => {
-        return new Promise((resolve, reject) => {
-            this.log(`to change ${stateName} to ${newValue} in ${hunkId}`)
-            let theHunk = hunks.find((hunk) => {
-                return hunk.id == hunkId
-            })
-            if (theHunk !== undefined) {
-                let theState = theHunk.state[stateName]
-                if (theState !== null && theState !== undefined) {
-                    theState.change(newValue)
-                    resolve()
-                } else {
-                    reject(new Error('@ statechange theState is undefined'))
-                }
-            } else {
-                reject(new Error('@ statechange theHunk is undefined'))
-            }
-        })
+  }
+
+  /* ---------------------------    ---------------------------- */
+  /* ----------------- LINKS HELLO / GOODBYTE ------------------ */
+  /* ---------------------------    ---------------------------- */
+
+  this.addLink = (outHunkId, outputName, inHunkId, inputName) => {
+    // sync, doesn't need to be a promise
+    let outHunk = hunks.find((hunk) => {
+      return hunk.id == outHunkId
+    })
+    let inHunk = hunks.find((hunk) => {
+      return hunk.id == inHunkId
+    })
+    // console.log('found hunks', outHunk, inHunk)
+    if (outHunk === undefined) {
+      errmsg("MGR on ADDLINK: outHunk is undefined: " + outHunkId)
+      return false
     }
-
-    /* ---------------------------    ---------------------------- */
-    /* --------------------- PROGRAM LOADING --------------------- */
-    /* ---------------------------    ---------------------------- */
-
-    this.addProgram = (prgname) => {
-        return new Promise((resolve, reject) => {
-            let unloaded = new Array()
-            let loaded = new Array()
-            // first, we should get the program 
-            // HERE consider this,
-            // probably re-write addlink to auto-complete as well 
-            // and then: the view init ... the stuffy message buffer ... the flush ? 
-            GG.getJson('programs/' + prgname + '.json').then((obj) => {
-                if (obj.programname !== null && obj.programname !== undefined) {
-                    this.log(`opening program with name: ${obj.programname}`)
-                    addHunkList(obj.hunks).then((newHunks) => {
-                        this.log(`finished adding hunks from: ${obj.programname}, now links`)
-                        for (let lnk of obj.links) {
-                            if (this.addLink(lnk.outhunk, lnk.outname, lnk.inhunk, lnk.inname)) {
-                                // success! continue 
-                            } else {
-                                reject('err in program load, at links', lnk)
-                            }
-                        }
-                        resolve(newHunks)
-                    }).catch((err) => {
-                        reject(err)
-                    })
-                } else {
-                    reject(new Error('program loads, not named'))
-                }
-            }).catch((err) => {
-                reject(err)
-            })
+    if (inHunk === undefined) {
+      errmsg("MGR on ADDLINK: inHunk is undefined: " + inHunkId)
+      return false
+    }
+    if (outHunk.outputs[outputName] === null || outHunk.outputs[outputName] === undefined) {
+      errmsg('MGR on ADDLINK: output is null or undefined. for hunk: ' + outHunk.id + " and output: " + outputName)
+      return false
+    } else if (inHunk.inputs[inputName] === null || inHunk.inputs[inputName] === undefined) {
+      errmsg('MGR on ADDLINK: input is null or undefined. for hunk: ' + inHunk.id + " and output: " + inputName)
+      return false
+    } else {
+      this.log(`hooking ${outHunk.id} to ${inHunk.id}`)
+      outHunk.outputs[outputName].attach(inHunk.inputs[inputName], inHunk.id)
+      this.writemessage('putlink', {
+        outId: outHunkId,
+        outName: outputName,
+        inId: inHunkId,
+        inName: inputName
+      })
+      return true
+    }
+  }
+
+  this.addLinkByObject = (fromHunk, outputName, toHunk, inputName) => {
+    // TODO: not throwing errors when outputname does not exist
+    // I.E. addLink doesn't actually use 'name' property, it uses [key]
+    this.addLink(fromHunk.id, outputName, toHunk.id, inputName)
+  }
+
+  this.removeLink = (outHunkId, outputName, inHunkId, inputName) => {
+    // console.log('REMOVELINK looking for hunk, with name, and in, with name', outHunkId, outputName, inHunkId, inputName)
+    let outHunk = hunks.find((hunk) => {
+      return hunk.id == outHunkId
+    })
+    let inHunk = hunks.find((hunk) => {
+      return hunk.id == inHunkId
+    }) // console.log('found hunks', outHunk, inHunk)
+    if (outHunk === undefined || inHunk === undefined) {
+      errmsg("MGR on REMOVELINK: output or input hunks are undefined")
+      return false
+    }
+    if (outHunk.outputs[outputName] === null || outHunk.outputs[outputName] === undefined) {
+      errmsg('MGR on REMOVELINK: output is null or undefined: ' + outHunk.name + " output: " + outputName)
+      return false
+    } else if (inHunk.inputs[inputName] === null || inHunk.inputs[inputName] === undefined) {
+      errmsg('MGR on REMOVELINK: input is null or undefined: ' + inHunk.name + "input: " + inputName)
+      return false
+    } else {
+      this.log(`unhooking ${outHunk.id} to ${inHunk.id}`)
+      if (outHunk.outputs[outputName].remove(inHunk.inputs[inputName], inHunk.id)) {
+        this.writemessage('removelink', {
+          outId: outHunkId,
+          outName: outputName,
+          inId: inHunkId,
+          inName: inputName
         })
+        return true
+      } else {
+        return false
+      }
     }
-
-    let addHunkList = (list) => {
-        return new Promise((resolve, reject) => {
-            let unloaded = new Array()
-            let loaded = new Array()
-            // first, we should get the program 
-            for (let hnk in list) {
-                let name = list[hnk].name
-                let id = list[hnk].id
-                unloaded.push(id)
-                this.addHunk(name, id).then((hunk) => {
-                    if (unloaded.includes(hunk.id)) {
-                        unloaded.splice(unloaded.indexOf(hunk.id), 1)
-                        loaded.push(hunk)
-                        if (unloaded.length < 1) {
-                            resolve(loaded)
-                        }
-                    } else {
-                        reject(new Error('strange catch when adding a list of hunks'))
-                    }
-                }).catch((err) => {
-                    reject(err)
-                })
+  }
+
+  /* ---------------------------    ---------------------------- */
+  /* ---------------------- STATE CHANGES ---------------------- */
+  /* ---------------------------    ---------------------------- */
+
+  this.stateChange = (hunkId, stateName, newValue) => {
+    return new Promise((resolve, reject) => {
+      this.log(`to change ${stateName} to ${newValue} in ${hunkId}`)
+      let theHunk = hunks.find((hunk) => {
+        return hunk.id == hunkId
+      })
+      if (theHunk !== undefined) {
+        let theState = theHunk.state[stateName]
+        if (theState !== null && theState !== undefined) {
+          theState.change(newValue)
+          resolve()
+        } else {
+          reject(new Error('@ statechange theState is undefined'))
+        }
+      } else {
+        reject(new Error('@ statechange theHunk is undefined'))
+      }
+    })
+  }
+
+  /* ---------------------------    ---------------------------- */
+  /* --------------------- PROGRAM LOADING --------------------- */
+  /* ---------------------------    ---------------------------- */
+
+  this.addProgram = (prgname) => {
+    return new Promise((resolve, reject) => {
+      let unloaded = new Array()
+      let loaded = new Array()
+      // first, we should get the program
+      // HERE consider this,
+      // probably re-write addlink to auto-complete as well
+      // and then: the view init ... the stuffy message buffer ... the flush ?
+      GG.getJson('programs/' + prgname + '.json').then((obj) => {
+        if (obj.programname !== null && obj.programname !== undefined) {
+          this.log(`opening program with name: ${obj.programname}`)
+          addHunkList(obj.hunks).then((newHunks) => {
+            this.log(`finished adding hunks from: ${obj.programname}, now links`)
+            for (let lnk of obj.links) {
+              if (this.addLink(lnk.outhunk, lnk.outname, lnk.inhunk, lnk.inname)) {
+                // success! continue
+              } else {
+                reject('watch err in program load, at links', lnk)
+              }
             }
+            resolve(newHunks)
+          }).catch((err) => {
+            reject(err)
+          })
+        } else {
+          reject(new Error('program loads, not named'))
+        }
+      }).catch((err) => {
+        reject(err)
+      })
+    })
+  }
+
+  let addHunkList = (list) => {
+    // list is str8 json 'hunks' list
+    // objects always have "name" and "id" properties,
+    // sometimes have "state" properties
+    return new Promise((resolve, reject) => {
+      let unloaded = new Array()
+      let loaded = new Array()
+      // first, we should get the program
+      for (let hnk in list) {
+        let name = list[hnk].name
+        let id = list[hnk].id
+        let state = list[hnk].state
+        unloaded.push(id)
+        this.addHunk(name, id, state).then((hunk) => {
+          if (unloaded.includes(hunk.id)) {
+            unloaded.splice(unloaded.indexOf(hunk.id), 1)
+            loaded.push(hunk)
+            if (unloaded.length < 1) {
+              resolve(loaded)
+            }
+          } else {
+            reject(new Error('strange catch when adding a list of hunks'))
+          }
+        }).catch((err) => {
+          reject(err)
         })
-    }
-
-    /* ---------------------------    ---------------------------- */
-    /* ---------------------- STARTUP, LOOP ---------------------- */
-    /* ---------------------------    ---------------------------- */
-
-    this.init = () => {
-        // startup by giving ourselves an ID if we haven't been assigned one?
-        // and then adding ourselves to ourselves ? 
-        hunks.push(this)
-        this.log(`manager hello, id is ${this.id}`)
-    }
-
-    this.loop = () => {
-        if (this.inputs.msgs.io) {
-            let msg = this.inputs.msgs.get()
-            let header = msg.header
-            let content = msg.content
-            this.log(`gets msg ${header}`)
-            switch (header) {
-                case 'hello':
-                    let options = this.getHelloResponses()
-                    this.writemessage('putcontextoptions', options)
-                    break
-                case 'listhunks':
-                    this.getListOfAvailableHunks().then((list) => {
-                        let options = new Array()
-                        // this *probably* needs work 
-                        for (let item of list) {
-                            let option = {
-                                text: item,
-                                header: 'addhunk',
-                                content: item
-                            }
-                            options.push(option)
-                        }
-                        this.writemessage('putcontextoptions', options)
-                    }).catch((err) => {
-                        this.log('ERR while getting list of available', err)
-                        this.writemessage('error', err)
-                    })
-                    break
-                case 'addprogram':
-                    // TODO: try muxed up JSON, returns unhandled promise rejection
-                    // in node? 
-                    this.addProgram(content).then((newHunks) => {
-                        // newhunks are automatically reported on msgs, and so are new links
-                        // so we just want a catch block here
-                    }).catch((err) => {
-                        this.log('ERR while adding program', err)
-                    })
-                    break
-                case 'addhunk':
-                    // TODO same here, addhunk should return automatically
-                    this.log('adding this hunk', content)
-                    this.addHunk(content).then((hunk) => {
-                        this.log('added hunk with id', hunk.id)
-                    }).catch((err) => {
-                        this.log('ERR while adding hunk', err)
-                        this.writemessage('error', err)
-                    })
-                    break
-                case 'removehunk':
-                    if (this.removeHunk(content)) {
-                        this.writemessage('removedef', content.id)
-                    } else {
-                        this.writemessage('error', 'could not remove hunk as requested')
-                    }
-                    break
-                case 'addlink':
-                    if (this.addLink(content.outId, content.outName, content.inId, content.inName)) {
-                        // gr8 success, and addlink automatically updates with a message to the view
-                    } else {
-                        this.writemessage('error', 'could not add link as requested')
-                    }
-                    break
-                case 'removelink':
-                    if (this.removeLink(content.outId, content.outName, content.inId, content.inName)) {
-                        // gr8 success, continue 
-                    } else {
-                        this.writemessage('error', 'cannot remove link as requested')
-                    }
-                    break
-                case 'statechange':
-                    this.stateChange(content.id, content.name, content.value).then(() => {
-                        // no response for this, message should pass from hunk 
-                    }).catch((err) => {
-                        this.log('ERR at statechange', err)
-                        this.writemessage('error', 'could not change state as requested')
-                    })
-                    break
-
-                default:
-                    console.log('MGR: msg with no switch')
-                    break
+      }
+    })
+  }
+
+  /* ---------------------------    ---------------------------- */
+  /* ---------------------- STARTUP, LOOP ---------------------- */
+  /* ---------------------------    ---------------------------- */
+
+  this.init = () => {
+    // startup by giving ourselves an ID if we haven't been assigned one?
+    // and then adding ourselves to ourselves ?
+    hunks.push(this)
+    this.log(`manager hello, id is ${this.id}`)
+  }
+
+  // flag,
+  let msgdebug = false
+
+  this.loop = () => {
+    // getting messages
+    if (this.inputs.msgs.io) {
+      let msg = this.inputs.msgs.get()
+      let header = msg.header
+      let content = msg.content
+      if(msgdebug) this.log(`gets msg ${header}`)
+      switch (header) {
+        case 'hello':
+          let options = this.getHelloResponses()
+          this.writemessage('putcontextoptions', options)
+          break
+        case 'listhunks':
+          this.getListOfAvailableHunks().then((list) => {
+            let options = new Array()
+            // this *probably* needs work
+            for (let item of list) {
+              let option = {
+                text: item,
+                header: 'addhunk',
+                content: item
+              }
+              options.push(option)
             }
-        } // end msgs input 
-
-        if (this.outmsgbuffer.length > 0) {
-            let debug = true
-            if (this.outputs.msgs.ie) {
-                if (debug) {
-                    let msg = this.outmsgbuffer.shift()
-                    this.log(`msg out ${msg.header}`)
-                    //console.log(msg.content)
-                    this.outputs.msgs.put(msg)
+            this.writemessage('putcontextoptions', options)
+          }).catch((err) => {
+            this.writemessage('error', 'ERR while getting list of available' + err)
+          })
+          break
+        case 'addprogram':
+          // TODO: try muxed up JSON, returns unhandled promise rejection
+          // in node?
+          this.addProgram(content).then((newHunks) => {
+            // newhunks are automatically reported on msgs, and so are new links
+            // so we just want a catch block here
+          }).catch((err) => {
+            this.writemessage('error', 'ERR while adding program' + err)
+          })
+          break
+        case 'addhunk':
+          // TODO same here, addhunk should return automatically
+          this.log('adding this hunk', content)
+          this.addHunk(content).then((hunk) => {
+            this.log('added hunk with id', hunk.id)
+          }).catch((err) => {
+            this.log('ERR while adding hunk', err)
+            this.writemessage('error', 'ERR on adding hunk' + err)
+          })
+          break
+        case 'removehunk':
+          if (this.removeHunk(content)) {
+            this.writemessage('removedef', content.id)
+          } else {
+            this.writemessage('error', 'could not remove hunk as requested')
+          }
+          break
+        case 'addlink':
+          if (this.addLink(content.outId, content.outName, content.inId, content.inName)) {
+            // gr8 success, and addlink automatically updates with a message to the view
+          } else {
+            this.writemessage('error', 'could not add link as requested')
+          }
+          break
+        case 'removelink':
+          if (this.removeLink(content.outId, content.outName, content.inId, content.inName)) {
+            // gr8 success, continue
+          } else {
+            this.writemessage('error', 'cannot remove link as requested')
+          }
+          break
+        case 'statechange':
+          this.stateChange(content.id, content.name, content.value).then(() => {
+            // no response for this, message should pass from hunk
+          }).catch((err) => {
+            this.log('ERR at statechange', err)
+            this.writemessage('error', 'could not change state as requested')
+          })
+          break
+
+        default:
+          this.writemessage('error', 'manager receives message with no switch!')
+          this.log('MGR: msg with no switch')
+          break
+      }
+    } // end msgs input
+
+    if (this.outmsgbuffer.length > 0) {
+      let debug = true
+      if (this.outputs.msgs.ie) {
+        if (debug) {
+          let msg = this.outmsgbuffer.shift()
+          if (msgdebug) this.log(`msg out ${msg.header}`)
+          //console.log(msg.content)
+          this.outputs.msgs.put(msg)
+        } else {
+          this.outputs.msgs.put(this.outmsgbuffer.shift())
+        }
+      }
+    } // end msgs output check
+
+    // do checks
+    if (hunks.length > 0) {
+      // STEP ONE: transport outputs (posted on last loop) to inputs
+      hunks.forEach((hunk) => {
+        for (let key of Object.keys(hunk.outputs)) {
+          let output = hunk.outputs[key]
+          if (output.connections.length > 0) {
+            // if we have connections
+            if (output.io) {
+              // and the output is occupied (having data)
+              if (!output.posted) {
+                // if it has not been posted to inputs (it's fresh)
+                // double check that all inputs are clear
+                let clear = true
+                for (let pair of output.connections) {
+                  if (pair.input.io) {
+                    clear = false
+                  }
+                }
+                // if all clear, move the output data to each input
+                if (clear) {
+                  for (let pair of output.connections) {
+                    // TODO: BIG copy per-input (within put function call)
+                    pair.input.put(output.data)
+                  }
+                  output.posted = true
                 } else {
-                    this.outputs.msgs.put(this.outmsgbuffer.shift())
+                  console.log('ERR: Output was put before inputs were clear')
                 }
-            }
-        } // end msgs output check 
-
-        // do checks 
-        if (hunks.length > 0) {
-            // STEP ONE: transport outputs (posted on last loop) to inputs 
-            hunks.forEach((hunk) => {
-                for (let key of Object.keys(hunk.outputs)) {
-                    let output = hunk.outputs[key]
-                    if (output.connections.length > 0) {
-                        // if we have connections 
-                        if (output.io) {
-                            // and the output is occupied (having data) 
-                            if (!output.posted) {
-                                // if it has not been posted to inputs (it's fresh) 
-                                // double check that all inputs are clear 
-                                let clear = true
-                                for (let pair of output.connections) {
-                                    if (pair.input.io) {
-                                        clear = false
-                                    }
-                                }
-                                // if all clear, move the output data to each input 
-                                if (clear) {
-                                    for (let pair of output.connections) {
-                                        // TODO: BIG copy per-input (within put function call)
-                                        pair.input.put(output.data)
-                                    }
-                                    output.posted = true
-                                } else {
-                                    console.log('ERR: Output was put before inputs were clear')
-                                }
-                            } else {
-                                // output has been posted, check if all clear 
-                                let clear = true
-                                for (let pair of output.connections) {
-                                    if (pair.input.io) {
-                                        clear = false
-                                    }
-                                }
-                                if (clear) {
-                                    output.clear()
-                                }
-                            }
-                        } // end if-has-data 
-                    } else {
-                        // and output with no connections is automatically cleared
-                        // into the aether 
-                        if (output.io) {
-                            output.clear()
-                        }
-                    }
+              } else {
+                // output has been posted, check if all clear
+                let clear = true
+                for (let pair of output.connections) {
+                  if (pair.input.io) {
+                    clear = false
+                  }
+                }
+                if (clear) {
+                  output.clear()
                 }
-            }) // end connection passing loop
-            // STEP TWO: give each hunk some time to run
-            // the 0is us, let's not call its loop 
-            for (let i = 1; i < hunks.length; i++) {
-                // TODO: watch for ordered calls ? if one emits ... another catches,
-                // we want cah-chunking ? 
-                hunks[i].loop()
+              }
+            } // end if-has-data
+          } else {
+            // and output with no connections is automatically cleared
+            // into the aether
+            if (output.io) {
+              output.clear()
             }
-        } // end if-have-hunks conditional 
-
-        /*
-        // need this at the bootloop, not here also 
-        // setup to loop return 
-        if (this.isBrowser) {
-            setTimeout(this.loop)
-        } else {
-            setImmediate(this.loop)
+          }
         }
-        */
-    } // end loop 
+      }) // end connection passing loop
+      // STEP TWO: give each hunk some time to run
+      // the 0is us, let's not call its loop
+      for (let i = 1; i < hunks.length; i++) {
+        // TODO: watch for ordered calls ? if one emits ... another catches,
+        // we want cah-chunking ?
+        hunks[i].loop()
+      }
+    } // end if-have-hunks conditional
+
+    /*
+    // need this at the bootloop, not here also
+    // setup to loop return
+    if (this.isBrowser) {
+        setTimeout(this.loop)
+    } else {
+        setImmediate(this.loop)
+    }
+    */
+  } // end loop
 
-    /* ---------------------------    ---------------------------- */
-    /* --------------------- MESSAGES OUTPUT --------------------- */
-    /* ---------------------------    ---------------------------- */
+  /* ---------------------------    ---------------------------- */
+  /* --------------------- MESSAGES OUTPUT --------------------- */
+  /* ---------------------------    ---------------------------- */
 
-    this.outmsgbuffer = new Array()
+  this.outmsgbuffer = new Array()
 
-    this.writemessage = (header, content) => {
-        // guaranteed consumption here
-        let msg = {
-            header: header,
-            content: content
-        }
-        if (this.outputs.msgs.ie && this.outmsgbuffer.length < 1) {
-            // str8 shooters 
-            this.log(`msg out ${header}`)
-            //console.log(content)
-            this.outputs.msgs.put(msg)
-        } else {
-            // gotta buffer
-            this.outmsgbuffer.push(msg)
-            this.log(`MGR OUTBUFFER LEN IS ${this.outmsgbuffer.length}`)
-        }
+  this.writemessage = (header, content) => {
+    // guaranteed consumption here
+    let msg = {
+      header: header,
+      content: content
+    }
+    if (this.outputs.msgs.ie && this.outmsgbuffer.length < 1) {
+      // str8 shooters
+      if(msgdebug) this.log(`msg out ${header}`)
+      //console.log(content)
+      this.outputs.msgs.put(msg)
+    } else {
+      // gotta buffer
+      this.outmsgbuffer.push(msg)
+      this.log(`MGR OUTBUFFER LEN IS ${this.outmsgbuffer.length}`)
     }
+  }
 }
 
 export default Manager
-// file scraped from cuttlefish on Thu Mar 28 2019 10:38:28 GMT-0400 (Eastern Daylight Time)
\ No newline at end of file
+// file scraped from cuttlefish on Thu Mar 28 2019 10:38:28 GMT-0400 (Eastern Daylight Time)
diff --git a/hunks/view.js b/hunks/view.js
index de7e6b7e0f1dc455535c26a677e1f46aed340ab8..7a61b40791e53eca1bf5d46a72d2e12a963f9c7f 100644
--- a/hunks/view.js
+++ b/hunks/view.js
@@ -46,6 +46,8 @@ function View() {
     this.dom = $('<div>').addClass('view').get(0)
     // for nested dom elements,
     this.plane = $('<div>').addClass('plane').get(0)
+    // to log, type, etc
+    this.msgbox = $('<div>').addClass('msgbox').get(0)
 
     // init transform
     let dft = {
@@ -83,6 +85,29 @@ function View() {
 
     // append
     $(this.dom).append(this.plane)
+    $(this.dom).append(this.msgbox)
+  }
+
+  let writeToMessageBox = (data) => {
+    // write the message
+    this.msgbox.append($('<div>' + data + '</div>').addClass('msgboxmsg').get(0))
+    // def check
+    let heightcheck = () => {
+      let height = 0;
+      $(this.msgbox).children().each(function(child){
+        // jquery.each() syntax is a bit odd / different than elsewhere, sorry for inconsistency
+        height += this.clientHeight
+      })
+      return height
+    }
+    // if too tall, remove
+    if(heightcheck() > $(this.msgbox).clientHeight){
+      $(this.msgbox).children().get(0).remove()
+      // two at most, sloppy but fast
+      if(heightcheck() > $(this.msgbox).clientHeight){
+        $(this.msgbox).children().get(0).remove()
+      }
+    }
   }
 
   let mouseWheelListener = (evt) => {
@@ -626,6 +651,8 @@ function View() {
 
     // the events
     let evtDrag = (drag) => {
+      drag.preventDefault()
+      drag.stopPropagation()
       let cp = readTransform(floater)
       cp.x += drag.movementX
       cp.y += drag.movementY
@@ -662,6 +689,8 @@ function View() {
 
     // startup the floater
     dom.addEventListener('mousedown', (down) => {
+      down.stopPropagation()
+      down.preventDefault()
       console.log('MOUSEDOWN for', port.type, port.name, down)
       // get the location to make the floater,
       let cp = BZ.getRightHandle(dom, this.plane.subscale)
@@ -687,7 +716,7 @@ function View() {
   }
 
   let writeStateDom = (state, def) => {
-    let dom = $('<li>' + state.name + '</li>').get(0)
+    let dom = $('<li>' + state.name + "(" + state.type + ")" + '</li>').get(0)
     dom.id = def.id + '_state_' + state.name
     switch (typeof state.value) {
       case 'string':
@@ -753,11 +782,12 @@ function View() {
     if (blkstate !== null && blkstate !== undefined) {
       // find value / etc
       let inp = $(blkstate).children('input').get(0)
+      // huh ?
       if (inp !== null && inp !== undefined) {
         inp.value = value
       } else {
         if (typeof value !== 'boolean') {
-          console.log('ERR State Change for non Boolean on Boolean Type')
+          writeToMessageBox('View ERR: State Change for non Boolean on Boolean Type: ' + parentid + ", state: " + name + ", value: " + value)
         } else {
           $(blkstate).children('span').text(value)
         }
@@ -771,6 +801,8 @@ function View() {
 
   this.outmsgbuffer = new Array()
 
+  let msgdebug = false
+
   this.writemessage = (header, content) => {
     // guaranteed consumption here
     let msg = {
@@ -779,8 +811,8 @@ function View() {
     }
     if (this.outputs.msgs.ie && this.outmsgbuffer.length < 1) {
       // str8 shooters
-      this.log('msg out', msg.header)
-      console.log(msg.content)
+      if(msgdebug) this.log('msg out', msg.header)
+      if(msgdebug) console.log(msg.content)
       this.outputs.msgs.put(msg)
     } else {
       // gotta buffer
@@ -805,7 +837,7 @@ function View() {
       let pult = this.inputs.msgs.get()
       let header = data.header
       let content = data.content
-      this.log(`gets msg ${header}`)
+      if(msgdebug) this.log(`gets msg ${header}`)
       switch (header) {
         case 'putcontextoptions':
           addContextOptions(content)
@@ -826,8 +858,7 @@ function View() {
           receiveStateChange(content.id, content.name, content.value)
           break
         case 'error':
-          console.log('RECV MANAGER ERROR')
-          console.log(content)
+          writeToMessageBox(content)
           break
         default:
           console.log('VIEW: msg with no switch')
diff --git a/programs/mvnv.json b/programs/mvnv.json
index e9ed8a26233761ada04dd9994a1f398484447461..5c610baf8dbb1788230241fa17d3b8c08d3864b0 100644
--- a/programs/mvnv.json
+++ b/programs/mvnv.json
@@ -15,11 +15,18 @@
     },
     {
         "name": "link",
-        "id": "lnkone"
+        "id": "lnkone",
+        "state": {
+          "inputList": "msgs (byteArray), lnkIpOne (uint32)",
+          "outputList": "msgs (byteArray), linkReturnOne (uint32)"
+        }
     },
     {
         "name": "comm/websocketclient",
-        "id": "wsclient"
+        "id": "wsclient",
+        "state": {
+          "retrycount": 0
+        }
     },
     {
         "name": "view",
diff --git a/style.css b/style.css
index ab603aae98261fe1b01fb647f072219443dfa1ab..6a367eaf12f33996211486b0ee2be63c8cf8b7f5 100644
--- a/style.css
+++ b/style.css
@@ -54,6 +54,23 @@ body {
   	background-size: 100px 100px;
 }
 
+.msgbox {
+	width: 300px;
+	height: 500px;
+	padding: 10px;
+	margin: 10px;
+	float: right;
+	background-color: rgb(192, 209, 237, 0.5);
+}
+
+.msgboxmsg{
+	padding: 3px;
+	margin-bottom: 3px;
+	background-color: white;
+	font-family: Courier;
+	font-size: 11px;
+}
+
 .plane {
 	position: absolute;
 	width: 100px;