diff --git a/README.md b/README.md
index ceb924783971193323fe7e75a1abbabd5aea2db3..8f5252e1c1436815c8d426f7e7a53202fcdcb39f 100644
--- a/README.md
+++ b/README.md
@@ -115,6 +115,41 @@ Messages:
 
 In my dreams, this is a way of key-parsing messages as well. I.E. I don't really want to write down a list of keys / values for manager messages - these should be locally defined by the unit that will respond to them. I am fond of that 'replyHello' implementation, and would like to extend it to all aspects of manager-ness, and think that this may be an especially helpful idea in the world of purely-serialized data and micros.
 
+# Serialization, Links
+
+I'm up to this, now. To test, debug, run faster, I'm going to focus on bringing about serialization truths to cuttlefish / nautilus, before deep diving into ponyo.
+
+Basically, I want to get rid of message-passing-by-json because string-parsing everything would be a bigtime slowdown. Quizically, I'm going to keep string-parsing inside of managers, but not inside of links.
+
+To wake up, I've a small list:
+ - type-name inputs, especially at the link
+ - same for comm/
+ - rebuild / use scrape.js (with //HEADER and //ENDHEADER flags)
+
+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.
+
+My links, and state-loading, aren't really well enough developed yet to do what I would like to. A generic 'link' can't be limited to some # / type of inputs / outputs. The interface needs to be developable.
+
+I know I'm going to implement some state-object loading on startup, and have init functions. I could use two state objects (inputList and outputList), those being inputs / outputs typed: like "charArray, uint32, float, floatArray" - on init, or on change, we can match this array to internal operation. And can put messages on them via first-byte drop-in (with type checking!).
+
+First order would be re-building links to have non-static wakeup states.
+
+Messages to 254 port are debug, should just be printed. Messages to 253 are to the link itself? Otherwise 0-ordered, and 0th port go to the manager, by convention.
+
+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. 
+
+## A List of Types
+
+Since serialization is pretty bound up with types, and I'm going through standardizing that now, here's a list:
+
+Type Name | Length | Byte Structure
+--- | --- | ---
+byteArray | n | 250,n,b1,...,bn
+
 # Videos to Take / Demos
 
  - loading with view relaxation
diff --git a/bztools.js b/bztools.js
index 7e9f24ca82ae87863e86daa13374bb8bad077d42..9272c80647486b0bbe76ee0beda55e881e4726c1 100644
--- a/bztools.js
+++ b/bztools.js
@@ -73,4 +73,4 @@ export {
     getLeftHandle,
     getFloaterHandle,
     writeBezier
-}
\ No newline at end of file
+}
diff --git a/hunks/comm/websocketclient.js b/hunks/comm/websocketclient.js
index 1fafe9c799d78ceeed77c799c332e9d797f04d10..ba9e87cf0f5a0c5b734168fc24b5ffbca7d6b425 100644
--- a/hunks/comm/websocketclient.js
+++ b/hunks/comm/websocketclient.js
@@ -4,114 +4,136 @@ line input
 
 */
 
-import { Hunkify, Input, Output, State } from '../hunks.js'
+import {
+  Hunkify,
+  Input,
+  Output,
+  State
+} from '../hunks.js'
 
 function WebSocketClient() {
-    Hunkify(this, 'WebSocketClient')
-
-    this.inputs.bytes = new Input('type', 'bytes')
-    this.outputs.bytes = new Output('type', 'bytes')
-
-    // TODO is tackling state sets / updates / onupdate fn's 
-    // this is hunk -> manager commune ... 
-    this.state.status = new State('string', 'status', 'closed')
-    this.state.address = new State('string', 'address', '127.0.0.1')
-    this.state.port = new State('string', 'port', '2042')
-
-    // this ws is a client, 
-    let ws = {}
-    let url = 'ws://127.0.0.1:2020'
-    this.outbuffer = new Array()
-
-    this.init = () => {
-        startWs()
+  Hunkify(this, 'WebSocketClient')
+
+  this.inputs.data = new Input('byteArray', 'data')
+  this.outputs.data = new Output('byteArray', 'data')
+
+  // TODO is tackling state sets / updates / onupdate fn's
+  // this is hunk -> manager commune ...
+  this.state.status = new State('string', 'status', 'closed')
+  this.state.retrycount = new State('number', 'retrycount', 3)
+  this.state.address = new State('string', 'address', '127.0.0.1')
+  this.state.port = new State('string', 'port', '2042')
+
+  // this ws is a client,
+  let ws = {}
+  let url = 'ws://127.0.0.1:2020'
+  this.outbuffer = new Array()
+
+  this.init = () => {
+    startWs()
+  }
+
+  let startWs = () => {
+    // manager calls this once
+    // it is loaded and state is updated (from program)
+    url = 'ws://' + this.state.address.value + ':' + this.state.port.value
+    console.log('INIT WS', url)
+    ws = new WebSocket(url)
+    ws.onopen = (evt) => {
+      this.log('ws opened')
+      this.log('the ws object', ws)
+      this.log(evt)
+      this.state.status.set('opened')
     }
-
-    let startWs = () => {
-        // manager calls this once 
-        // it is loaded and state is updated (from program)
-        url = 'ws://' + this.state.address.value + ':' + this.state.port.value
-        console.log('INIT WS', url)
-        ws = new WebSocket(url)
-        ws.onopen = (evt) => {
-            this.log('ws opened')
-            this.log('the ws object', ws)
-            this.log(evt)
-            this.state.status.set('opened')
-        }
-        ws.onerror = (evt) => {
-            this.log('ws error, will reset to check')
-            console.log(evt)
-            this.state.status.set('error')
-            setCheck(500)
-        }
-        ws.onclose = (evt) => {
-            this.log('ws close')
-            setCheck(500)
-        }
-        ws.onmessage = (msg) => {
-            console.log("WS RX:", msg.data)
-            if (this.outputs.bytes.ie && this.outbuffer.length === 0) {
-                this.outputs.bytes.put(JSON.parse(msg.data))
-            } else {
-                this.outbuffer.push(msg.data)
-            }
-        }
-        this.state.status.set('connecting ...')
+    ws.onerror = (evt) => {
+      this.log('ws error, will reset to check')
+      console.log(evt)
+      this.state.status.set('error')
+      setCheck(500)
+    }
+    ws.onclose = (evt) => {
+      this.log('ws close')
+      setCheck(500)
     }
+    ws.onmessage = (msg) => {
+      console.log("WS RX:", msg.data)
+      if (this.outputs.data.ie && this.outbuffer.length === 0) {
+        this.outputs.data.put(JSON.parse(msg.data))
+      } else {
+        this.outbuffer.push(msg.data)
+      }
+    }
+    this.state.status.set('connecting ...')
+  }
 
-    let checking = false 
+  let checking = false
 
-    let setCheck = (ms) => {
-        if(checking){
-            // noop
-        } else {
-            setTimeout(checkWsStatus, ms)
-            checking = true 
-        }
+  let setCheck = (ms) => {
+    if (checking) {
+      // noop
+    } else {
+      setTimeout(checkWsStatus, ms)
+      checking = true
     }
-
-    let checkWsStatus = () => {
-        checking = false 
-        this.log('CHECKING STATUS')
-        switch (ws.readyState) {
-            case WebSocket.CONNECTING:
-                this.log('is connecting')
-                break
-            case WebSocket.OPEN:
-                this.log('is open')
-                break
-            case WebSocket.CLOSING:
-                this.log('is closing')
-                break
-            case WebSocket.CLOSED:
-                this.log('is closed, retrying ...')
-                startWs()
-                break
-            default:
-                throw new Error('nonsensical result at ws readystate check for ws')
-                break 
-        }
+  }
+
+  let checkWsStatus = () => {
+    let retrycount = this.state.retrycount.value - 1
+    if (retrycount < 1) {
+      // give up
+      this.state.status.set('not connected')
+      this.state.retrycount.set(retrycount)
+      checking = false 
+    } else {
+      this.state.retrycount.set(retrycount)
+      checking = false
+      this.log('CHECKING STATUS')
+      switch (ws.readyState) {
+        case WebSocket.CONNECTING:
+          this.log('is connecting')
+          break
+        case WebSocket.OPEN:
+          this.log('is open')
+          break
+        case WebSocket.CLOSING:
+          this.log('is closing')
+          break
+        case WebSocket.CLOSED:
+          this.log('is closed, retrying ...')
+          startWs()
+          break
+        default:
+          throw new Error('nonsensical result at ws readystate check for ws')
+          break
+      }
+    }
+  }
+
+  // override default change f'n
+  this.state.retrycount.change = (value) => {
+    this.log('retrycount reset')
+    this.state.retrycount.set(value)
+    setCheck(10)
+  }
+
+  this.loop = () => {
+    // something like if(ws !== null && ws.isopen)
+    // if we have an open port, and have bytes to send downstream,
+    if (ws !== null && ws.readyState === 1) {
+      // no buffering
+      if (this.inputs.data.io) {
+        let message = this.inputs.data.get()
+        console.log("WS SENDING", message)
+        ws.send(JSON.stringify(message))
+      }
     }
 
-    this.loop = () => {
-        // something like if(ws !== null && ws.isopen)
-        // if we have an open port, and have bytes to send downstream, 
-        if (ws !== null && ws.readyState === 1) {
-            // no buffering 
-            if (this.inputs.bytes.io) {
-                let message = this.inputs.bytes.get()
-                console.log("WS SENDING", message)
-                ws.send(JSON.stringify(message))
-            }
-        }
-
-        // check if we have outgoing to pass along 
-        if (this.outbuffer.length > 0 && this.outputs.bytes.ie) {
-            this.outputs.bytes.put(this.outbuffer.shift())
-        }
-
+    // check if we have outgoing to pass along
+    if (this.outbuffer.length > 0 && this.outputs.data.ie) {
+      this.outputs.data.put(this.outbuffer.shift())
     }
+
+  }
 }
 
-export default WebSocketClient
\ No newline at end of file
+export default WebSocketClient
diff --git a/hunks/hunks.js b/hunks/hunks.js
index dc6a3096d150bf93745e757a462e203136a45a31..9134a88ad982f74b2910e03876cac7ec4d11e8a4 100644
--- a/hunks/hunks.js
+++ b/hunks/hunks.js
@@ -1,144 +1,156 @@
 /*
 
-tha hunks 
+tha hunks
 
 */
 
 function Hunkify(hunk, name) {
-    // scripting languages should name hunks by their script location and filename 
-    // compiled languages will assign a string 
-    hunk.id = null
-    hunk.name = null
-
-    hunk.log = function(msg) {
-        for (let i = 0; i < arguments.length; i++) {
-            console.log('LG:', hunk.id, ':', arguments[i])
-        }
+  // scripting languages should name hunks by their script location and filename
+  // compiled languages will assign a string
+  hunk.id = null
+  hunk.name = null
+
+  hunk.log = function(msg) {
+    for (let i = 0; i < arguments.length; i++) {
+      console.log('LG:', hunk.id, ':', arguments[i])
     }
+  }
 
-    hunk.inputs = {}
-    hunk.outputs = {}
-    hunk.state = {}
+  hunk.inputs = {}
+  hunk.outputs = {}
+  hunk.state = {}
 }
 
 function Input(type, name) {
-    this.name = name
-    this.type = type
-    this.data = null
-    this.io = false
-    this.ie = true
-
-    this.put = (data) => {
-        // used when MGR does transport 
-        if (data === undefined || data === null) {
-            console.log("THROWING PUT OF UNDEF OR NULL")
-            console.log('to', this)
-            throw new Error('UNDEF OR NULL PUT TO LINK')
-        } else {
-            this.data = data
-            this.io = true
-            this.ie = false
-        }
+  this.name = name
+  this.type = type
+  this.data = null
+  this.io = false
+  this.ie = true
+
+  this.put = (data) => {
+    // used when MGR does transport
+    if (data === undefined || data === null) {
+      console.log("THROWING PUT OF UNDEF OR NULL")
+      console.log('to', this)
+      throw new Error('UNDEF OR NULL PUT TO LINK')
+    } else {
+      this.data = data
+      this.io = true
+      this.ie = false
     }
-
-    this.get = () => {
-        // used internal to hunk to pull data from link 
-        if (this.io) {
-            // TODO: BIG: deep copy here 
-            let dc = JSON.parse(JSON.stringify(this.data))
-            this.data = null
-            this.io = false
-            this.ie = true
-            return dc
-        } else {
-            return null
-        }
+  }
+
+  this.get = () => {
+    // used internal to hunk to pull data from link
+    if (this.io) {
+      // TODO: BIG: deep copy here
+      let dc = JSON.parse(JSON.stringify(this.data))
+      this.data = null
+      this.io = false
+      this.ie = true
+      return dc
+    } else {
+      return null
     }
+  }
 }
 
 function Output(type, name) {
-    this.name = name
-    this.type = type
+  this.name = name
+  this.type = type
+  this.data = null
+  this.posted = false
+  this.io = false
+  this.ie = true
+  this.connections = new Array()
+
+  this.put = (data) => {
+    if (this.ie) {
+      this.data = data
+      this.io = true
+      this.ie = false
+      this.posted = false
+      return true
+    } else {
+      // TODO: throw error here? these should not be allowed
+      return false
+    }
+  }
+
+  this.clear = () => {
     this.data = null
-    this.posted = false
     this.io = false
     this.ie = true
-    this.connections = new Array()
-
-    this.put = (data) => {
-        if (this.ie) {
-            this.data = data
-            this.io = true
-            this.ie = false
-            this.posted = false
-            return true
-        } else {
-            // TODO: throw error here? these should not be allowed 
-            return false
-        }
-    }
-
-    this.clear = () => {
-        this.data = null
-        this.io = false
-        this.ie = true
+  }
+
+  this.attach = (input, pid) => {
+    this.connections.push({
+      input: input,
+      parentid: pid
+    })
+  }
+
+  this.remove = (input, pid) => {
+    // find by names pls
+    let recip = {
+      input: input,
+      parentid: pid
     }
-
-    this.attach = (input, pid) => {
-        this.connections.push({ input: input, parentid: pid })
-    }
-
-    this.remove = (input, pid) => {
-        // find by names pls 
-        let recip = { input: input, parentid: pid }
-        let pos = -1
-        let conn = this.connections.find((cn, i) => {
-            pos = i
-            return ((cn.parentid === recip.parentid) && (cn.input.name === recip.input.name))
-        })
-        if (conn !== undefined | conn !== null) {
-            this.connections.splice(pos, 1)
-            return true
-        } else {
-            console.log('was looking for ', recip, 'in', this.connections)
-            return false
-        }
+    let pos = -1
+    let conn = this.connections.find((cn, i) => {
+      pos = i
+      return ((cn.parentid === recip.parentid) && (cn.input.name === recip.input.name))
+    })
+    if (conn !== undefined | conn !== null) {
+      this.connections.splice(pos, 1)
+      return true
+    } else {
+      console.log('was looking for ', recip, 'in', this.connections)
+      return false
     }
+  }
 
-    this.unhook = (pid) => {
-        for (let conn of this.connections) {
-            if (conn.parentid === pid) {
-                this.remove(conn)
-            }
-        }
+  this.unhook = (pid) => {
+    for (let conn of this.connections) {
+      if (conn.parentid === pid) {
+        this.remove(conn)
+      }
     }
+  }
 }
 
 function State(type, name, startup) {
-    this.name = name
-    this.type = type
-    this.value = startup
-    // this is still something of a hack
-    // during load, the manager gets in here and dishes a function 2 us 
-    this.hookup = (newval) => {
-        console.log('@ state change request, no manager hookup')
-    }
-    // could be getters / setters ? worth it? 
-
-    // from within a hunk, we typically call this
-    // to update the value and ship it out to any views
-    this.set = (value) => {
-        this.value = value
-        this.hookup(this.value)
-    }
-
-    // a view change calls this function, which we can
-    // also manually overwrite (say, to set a change handler / checker)
-    this.change = (value) => {
-        // correct, this will by default ring back to 
-        // the view, to confirm 
-        this.set(value)
-    }
+  this.name = name
+  this.type = type
+  this.value = startup
+  // this is still something of a hack
+  // during load, the manager gets in here and dishes a function 2 us
+  this.hookup = (newval) => {
+    console.log('@ state change request, no manager hookup')
+  }
+  // could be getters / setters ? worth it?
+
+  // from within a hunk, we typically call this
+  // to update the value and ship it out to any views
+  this.set = (value) => {
+    this.value = value
+    this.hookup(this.value)
+  }
+
+  // a view change calls this function, which we can
+  // also manually overwrite (say, to set a change handler / checker)
+  this.change = (value) => {
+    // correct, this will by default ring back to
+    // the view, to confirm
+    console.log('default state change')
+    this.set(value)
+  }
 }
 
-export { Hunkify, Input, Output, State }
\ No newline at end of file
+export {
+  Hunkify,
+  Input,
+  Output,
+  State
+}
diff --git a/hunks/link.js b/hunks/link.js
index 61f196c43f9d94281a5b3cff284643a8c0bae53a..c17f88e24305dbb91919cb0eb80566c11ccf07e2 100644
--- a/hunks/link.js
+++ b/hunks/link.js
@@ -4,164 +4,173 @@ line input
 
 */
 
-import { Hunkify, Input, Output, State } from './hunks.js'
+// HEADER
+import {
+  Hunkify,
+  Input,
+  Output,
+  State
+} from './hunks.js'
+// END HEADER
 
 function Link() {
-    Hunkify(this, 'Link')
-
-    // data in/out
-    // assumed that whatever is on the other end of bytes
-    // does byte / packet level flowcontrol 
-    this.inputs.bytes = new Input('bytes', 'bytes')
-    this.outputs.bytes = new Output('bytes', 'bytes')
-
-    // these are *special link inputs* keeping track of downstream status
-    this.inputs.zero = new Input('any', 'zero')
-    this.inputs.zero.dss = 'open'
-
-    this.inputs.one = new Input('any', 'one')
-    this.inputs.zero.dss = 'open'
-
-    this.inputs.two = new Input('any', 'two')
-    this.inputs.two.dss = 'open'
-
-
-    // special outputs having upstream buffers 
-    this.outputs.zero = new Output('any', 'zero')
-    this.outputs.zero.hold = {}
-    this.outputs.zero.hold.status = 'open'
-    this.outputs.zero.hold.msg = {}
-
-    this.outputs.one = new Output('any', 'one')
-    this.outputs.one.hold = {}
-    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')
+  Hunkify(this, 'Link')
+
+  // data in/out
+  // assumed that whatever is on the other end of bytes
+  // does byte / packet level flowcontrol
+  this.inputs.data = new Input('byteArray', 'data')
+  this.outputs.data = new Output('byteArray', 'data')
+
+  // these are *special link inputs* keeping track of downstream status
+  this.inputs.zero = new Input('any', 'zero')
+  this.inputs.zero.dss = 'open'
+
+  this.inputs.one = new Input('any', 'one')
+  this.inputs.zero.dss = 'open'
+
+  this.inputs.two = new Input('any', 'two')
+  this.inputs.two.dss = 'open'
+
+
+  // special outputs having upstream buffers
+  this.outputs.zero = new Output('any', 'zero')
+  this.outputs.zero.hold = {}
+  this.outputs.zero.hold.status = 'open'
+  this.outputs.zero.hold.msg = {}
+
+  this.outputs.one = new Output('any', 'one')
+  this.outputs.one.hold = {}
+  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')
+  }
+
+  // so far we won't ack at the link layer,
+  // i.e. we will assume that we can send all ports across,
+  // without getting an ack back from the 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()
+
+  // I think we just need to buffer
+  // the outputs that we pull but can't send
+
+  /*
+  let msg = {
+      msg: content,
+      port: portnum,
+      isAck: false
+  }
+  // or
+  let msg = {
+      port: portnum,
+      isAck: true
+  }
+  */
+
+  // the link level will flow control across bytes,
+  // so we just flow control across ports
+
+  this.loop = () => {
+
+    // for everything we're holding, check our outputs
+    for (let i in outports) {
+      if (outports[i].hold.status === 'occupied' && outports[i].ie) {
+        // gr8 news, we can ship it
+        outports[i].put(outports.hold.msg)
+        outports[i].hold.status = 'clear'
+        let ack = {
+          isAck: true,
+          port: i
+        }
+        outbuffer.push(ack)
+      } else {
+        // we can't do anything, waiting for outside world
+      }
     }
 
-    // so far we won't ack at the link layer, 
-    // i.e. we will assume that we can send all ports across, 
-    // without getting an ack back from the 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()
-
-    // I think we just need to buffer 
-    // the outputs that we pull but can't send
-
-    /*
-    let msg = {
-        msg: content,
-        port: portnum, 
-        isAck: false
-    }
-    // or 
-    let msg = {
-        port: portnum,
-        isAck: true 
-    }
-    */
-
-    // the link level will flow control across bytes, 
-    // so we just flow control across ports 
-
-    this.loop = () => {
-
-        // for everything we're holding, check our outputs 
-        for (let i in outports) {
-            if (outports[i].hold.status === 'occupied' && outports[i].ie) {
-                // gr8 news, we can ship it 
-                outports[i].put(outports.hold.msg)
-                outports[i].hold.status = 'clear'
-                let ack = {
-                    isAck: true,
-                    port: i
-                }
-                outbuffer.push(ack)
-            } else {
-                // we can't do anything, waiting for outside world 
-            }
+    // then check for messages from the data link
+    if (this.inputs.data.io) {
+      // we pull every time
+      let msg = this.inputs.data.get()
+      // if it's an ack, we can clear an input
+      if (msg.isAck) {
+        if (inports[msg.port].dss !== 'await ack') {
+          console.log("LINK ERROR: ACK FROM NON WAIT")
+          throw new Error('link panic', msg)
+        } else {
+          inports[msg.port].dss = 'open'
         }
-
-        // then check for messages from the data link 
-        if (this.inputs.bytes.io) {
-            // we pull every time 
-            let msg = this.inputs.bytes.get()
-            // if it's an ack, we can clear an input 
-            if (msg.isAck) {
-                if (inports[msg.port].dss !== 'await ack') {
-                    console.log("LINK ERROR: ACK FROM NON WAIT")
-                    throw new Error('link panic', msg)
-                } else {
-                    inports[msg.port].dss = 'open'
-                }
-            } else {
-                // otherwise we have a message for one of our outputs 
-                let dsport = outports[msg.port]
-                // if we have one
-                if (dsport !== null && dsport !== undefined) {
-                    if (dsport.hold.status === 'occupied') {
-                        // bad news, we are already waiting to send
-                        // but we have this new thing, so
-                        console.log('LINK ERROR: 2ND MSG TO NON ACKED PORT')
-                        throw new Error('link panic', msg)
-                    } else if (dsport.ie){
-                        // this is easy, we can just ship it 
-                        dsport.put(msg.msg)
-                        let ack = {
-                            isAck: true,
-                            port: msg.port
-                        }
-                        outbuffer.push(ack)
-                    } else {
-                        // well, we already pulled it off stream, so 
-                        dsport.hold.status = 'occupied'
-                        dsport.hold.msg = msg.msg
-                        // store it locally, but don't ack
-                        // so we should not get another message on this port until we ack ... 
-                        // if we do, the 1st if statement in this block will be triggered
-                    }
-                } else {
-                    console.log('LINK ERROR: RECEIVES MESSAGE FOR PORT IT DOTH NOT HAVE')
-                    console.log(msg.port, typeof msg.port)
-                    // TODO: make one, and report to manager that we have done so 
-                }
-            } // end message-not-ack 
-        } // end if input has bytes 
-
-        // now let's run over our inputs,
-        for (let i in inports) {
-            // if there's a message on the input, and the downstream is clear,
-            if (inports[i].io && inports[i].dss === 'open') {
-                // we can send it, and reset to await an ack
-                this.log('i', typeof i)
-                let dsmsg = {
-                    msg: inports[i].get(),
-                    port: parseInt(i),
-                    isAck: false,
-                }
-                this.log('LNK MSG OUT', dsmsg)
-                inports[i].dss = 'await ack'
-                outbuffer.push(dsmsg)
-            } else {
-                // otherwise, there's nothing we can do but let it sit there 
+      } else {
+        // otherwise we have a message for one of our outputs
+        let dsport = outports[msg.port]
+        // if we have one
+        if (dsport !== null && dsport !== undefined) {
+          if (dsport.hold.status === 'occupied') {
+            // bad news, we are already waiting to send
+            // but we have this new thing, so
+            console.log('LINK ERROR: 2ND MSG TO NON ACKED PORT')
+            throw new Error('link panic', msg)
+          } else if (dsport.ie) {
+            // this is easy, we can just ship it
+            dsport.put(msg.msg)
+            let ack = {
+              isAck: true,
+              port: msg.port
             }
+            outbuffer.push(ack)
+          } else {
+            // well, we already pulled it off stream, so
+            dsport.hold.status = 'occupied'
+            dsport.hold.msg = msg.msg
+            // store it locally, but don't ack
+            // so we should not get another message on this port until we ack ...
+            // if we do, the 1st if statement in this block will be triggered
+          }
+        } else {
+          console.log('LINK ERROR: RECEIVES MESSAGE FOR PORT IT DOTH NOT HAVE')
+          console.log(msg.port, typeof msg.port)
+          // TODO: make one, and report to manager that we have done so
         }
-
-        // flow control outgoing messages 
-        // one per loop ! 
-        if (this.outputs.bytes.ie && outbuffer.length > 0) {
-            this.outputs.bytes.put(outbuffer.shift())
+      } // end message-not-ack
+    } // end if input has bytes
+
+    // now let's run over our inputs,
+    for (let i in inports) {
+      // if there's a message on the input, and the downstream is clear,
+      if (inports[i].io && inports[i].dss === 'open') {
+        // we can send it, and reset to await an ack
+        this.log('i', typeof i)
+        let dsmsg = {
+          msg: inports[i].get(),
+          port: parseInt(i),
+          isAck: false,
         }
-    } // end loop 
+        this.log('LNK MSG OUT', dsmsg)
+        inports[i].dss = 'await ack'
+        outbuffer.push(dsmsg)
+      } else {
+        // otherwise, there's nothing we can do but let it sit there
+      }
+    }
+
+    // flow control outgoing messages
+    // one per loop !
+    if (this.outputs.data.ie && outbuffer.length > 0) {
+      this.outputs.data.put(outbuffer.shift())
+    }
+  } // end loop
 }
 
-export default Link
\ No newline at end of file
+// FOOTER
+export default Link
+// END FOOTER
diff --git a/hunks/view.js b/hunks/view.js
index e9af913c72b9c188d206b714cfd3cacd049cb487..de7e6b7e0f1dc455535c26a677e1f46aed340ab8 100644
--- a/hunks/view.js
+++ b/hunks/view.js
@@ -1,795 +1,840 @@
-/* 
+/*
 
 VIEW
 
- - scrape to manager, 
- - manager gogetter ... and then, hello click 
- - and then, nicely: 
- - also - link for flowcontrol when downstream non-conn ? the init-over-link question? a few states ... 
- - div structure ... ? open something up just barely, to test node and scraper 
- - beer 2 celly 
- - div structure: the div(div) scaling unfuckery 
+ - scrape to manager,
+ - manager gogetter ... and then, hello click
+ - and then, nicely:
+ - also - link for flowcontrol when downstream non-conn ? the init-over-link question? a few states ...
+ - div structure ... ? open something up just barely, to test node and scraper
+ - beer 2 celly
+ - div structure: the div(div) scaling unfuckery
 
 */
 
-import { Hunkify, Input, Output, State } from './hunks.js'
+import {
+  Hunkify,
+  Input,
+  Output,
+  State
+} from './hunks.js'
+
 import * as BZ from '../bztools.js'
 
 function View() {
-    Hunkify(this, 'View')
-
-    // view of a manager, has route to that manager (via a link?) 
-
-    this.inputs.msgs = new Input('message', 'msgs')
-    this.outputs.msgs = new Output('message', 'msgs')
-
-    // das UI globals
-    // our dom is the space we're allotted,
-    this.dom = {}
-    // the plane, one layer beneath, is where divs live 
-    this.plane = {}
-
-    /* ---------------------------    ---------------------------- */
-    /* -------------------- INIT, LISTENERS ---------------------- */
-    /* ---------------------------    ---------------------------- */
-
-    this.init = () => {
-        // in the case of UIs, we have the dom before init runs,
-        // so this is kind of like the 'window.onload' function
-        this.log('hello ui')
-        this.dom = $('<div>').addClass('view').get(0)
-        // for nested dom elements,
-        this.plane = $('<div>').addClass('plane').get(0)
-
-        // init transform
-        let dft = { s: 1, x: 0, y: 0, ox: 0, oy: 0 }
-        writeTransform(this.plane, dft)
-        writeBackgroundTransform(this.dom, dft)
-
-        // zoom the context 
-        this.dom.addEventListener('wheel', mouseWheelListener)
-
-        // pan the context 
-        this.dom.addEventListener('mousedown', (evt) => {
-            if ($(evt.target).is('.view')) {
-                evt.preventDefault()
-                evt.stopPropagation()
-                window.addEventListener('mousemove', canvasDragListener)
-                window.addEventListener('mouseup', canvasUpListener)
-            } else if ($(evt.target).is('input')) {
-                // no op 
-            } else {
-                // prevents bubbling up outside of the view, potentially a bug farm ? 
-                // evt.preventDefault()
-                // evt.stopPropagation()
-            }
-        })
-
-        // get the context menu on righ click 
-        this.dom.addEventListener('contextmenu', onContextMenu)
-        this.plane.subscale = 1
-
-        // append
-        $(this.dom).append(this.plane)
+  Hunkify(this, 'View')
+
+  // view of a manager, has route to that manager (via a link?)
+
+  this.inputs.msgs = new Input('message', 'msgs')
+  this.outputs.msgs = new Output('message', 'msgs')
+
+  // das UI globals
+  // our dom is the space we're allotted,
+  this.dom = {}
+  // the plane, one layer beneath, is where divs live
+  this.plane = {}
+
+  /* ---------------------------    ---------------------------- */
+  /* -------------------- INIT, LISTENERS ---------------------- */
+  /* ---------------------------    ---------------------------- */
+
+  this.init = () => {
+    // in the case of UIs, we have the dom before init runs,
+    // so this is kind of like the 'window.onload' function
+    this.log('hello ui')
+    this.dom = $('<div>').addClass('view').get(0)
+    // for nested dom elements,
+    this.plane = $('<div>').addClass('plane').get(0)
+
+    // init transform
+    let dft = {
+      s: 1,
+      x: 0,
+      y: 0,
+      ox: 0,
+      oy: 0
     }
+    writeTransform(this.plane, dft)
+    writeBackgroundTransform(this.dom, dft)
 
-    let mouseWheelListener = (evt) => {
-        if (!$(evt.target).is('.view')) {
-            return false
-        }
+    // zoom the context
+    this.dom.addEventListener('wheel', mouseWheelListener)
+
+    // pan the context
+    this.dom.addEventListener('mousedown', (evt) => {
+      if ($(evt.target).is('.view')) {
         evt.preventDefault()
         evt.stopPropagation()
+        window.addEventListener('mousemove', canvasDragListener)
+        window.addEventListener('mouseup', canvasUpListener)
+      } else if ($(evt.target).is('input')) {
+        // no op
+      } else {
+        // prevents bubbling up outside of the view, potentially a bug farm ?
+        // evt.preventDefault()
+        // evt.stopPropagation()
+      }
+    })
+
+    // get the context menu on righ click
+    this.dom.addEventListener('contextmenu', onContextMenu)
+    this.plane.subscale = 1
+
+    // append
+    $(this.dom).append(this.plane)
+  }
+
+  let mouseWheelListener = (evt) => {
+    if (!$(evt.target).is('.view')) {
+      return false
+    }
+    evt.preventDefault()
+    evt.stopPropagation()
 
-        let ox = evt.layerX
-        let oy = evt.layerY
+    let ox = evt.layerX
+    let oy = evt.layerY
 
-        let ds
-        if (evt.deltaY > 0) {
-            ds = 0.025
-        } else {
-            ds = -0.025
-        }
+    let ds
+    if (evt.deltaY > 0) {
+      ds = 0.025
+    } else {
+      ds = -0.025
+    }
 
-        let ct = readTransform(this.plane)
+    let ct = readTransform(this.plane)
 
-        ct.s *= 1 + ds
+    ct.s *= 1 + ds
 
-        ct.x += (ct.x - ox) * ds
-        ct.y += (ct.y - oy) * ds
+    ct.x += (ct.x - ox) * ds
+    ct.y += (ct.y - oy) * ds
 
-        writeTransform(this.plane, ct)
-        writeBackgroundTransform(this.dom, ct)
+    writeTransform(this.plane, ct)
+    writeBackgroundTransform(this.dom, ct)
 
-        // now redraw links
-    }
+    // now redraw links
+  }
 
-    let canvasDragListener = (evt) => {
-        evt.preventDefault()
-        evt.stopPropagation()
-        let ct = readTransform(this.plane)
-        ct.x += evt.movementX
-        ct.y += evt.movementY
-        writeTransform(this.plane, ct)
-        writeBackgroundTransform(this.dom, ct)
-
-        /*
-        this.pan.x += evt.movementX
-        this.pan.y += evt.movementY
-        this.plane.style.backgroundPosition = `${this.pan.x}px ${this.pan.y}px`
-        $(this.plane).children().each((index, div) => {
-            let tf = readTransform(div)
-            tf.x += evt.movementX
-            tf.y += evt.movementY
-            writeTransform(div, tf)
+  let canvasDragListener = (evt) => {
+    evt.preventDefault()
+    evt.stopPropagation()
+    let ct = readTransform(this.plane)
+    ct.x += evt.movementX
+    ct.y += evt.movementY
+    writeTransform(this.plane, ct)
+    writeBackgroundTransform(this.dom, ct)
+
+    /*
+    this.pan.x += evt.movementX
+    this.pan.y += evt.movementY
+    this.plane.style.backgroundPosition = `${this.pan.x}px ${this.pan.y}px`
+    $(this.plane).children().each((index, div) => {
+        let tf = readTransform(div)
+        tf.x += evt.movementX
+        tf.y += evt.movementY
+        writeTransform(div, tf)
+    })
+    */
+  }
+
+  let canvasUpListener = (evt) => {
+    window.removeEventListener('mousemove', canvasDragListener)
+    window.removeEventListener('mouseup', canvasUpListener)
+  }
+
+  // CONTEXT MENU
+  let onContextMenu = (evt) => {
+    //console.log(evt)
+    evt.preventDefault()
+    evt.stopPropagation()
+    // TRANSFORM here to write menu in the right spot on click
+    let menu = $('<div>').addClass('contextmenu')
+      .append('<ul> hello -> </ul>').get(0)
+    let ct = readTransform(this.plane)
+    console.log('write to ', ct)
+    writeTransform(menu, {
+      s: 1,
+      x: evt.layerX - ct.x * ct.s,
+      y: evt.layerY - ct.y * ct.s
+    })
+    $(this.plane).append(menu)
+    // an output
+    this.writemessage('hello', ' ')
+  }
+
+  let menuNextItem = (text) => {
+    $(this.plane).children('.contextmenu').children().not('ul').remove()
+    $(this.plane).children('.contextmenu').append('<ul>' + text + '</ul>')
+  }
+
+  let addContextOptions = (list) => {
+    let menu = $(this.plane).children('.contextmenu').get(0)
+    for (let index in list) {
+      $(menu).append(writeContextOption(list[index].text, list[index].header, list[index].content))
+    }
+  }
+
+  let writeContextOption = (text, header, content) => {
+    let item = $('<li>' + text + '</li>').get(0)
+    item.addEventListener('click', (evt) => {
+      this.writemessage(header, content)
+      menuNextItem(header + ' ' + content + ' ->')
+    })
+    return item
+  }
+
+
+  /* ---------------------------    ---------------------------- */
+  /* ---------------------- FORCE LAYOUT ----------------------- */
+  /* ---------------------------    ---------------------------- */
+
+  // ok, my thoughts on this
+  /*
+
+  I obviously need to think carefully about it for a minute
+  I'm going to make it sortof-work before I go forwards with the link
+
+  - should restart on adding a new hunk with existing positions
+  - should be able to stop it when we mousedown
+
+  */
+
+  let blocks = new Array()
+  let flsimrun = false
+  let flsim = {}
+  let flnodes = []
+
+  let finAlpha = 0.5
+
+  let updateForceLoop = () => {
+    // init and/or update
+    if (!flsimrun && blocks.length > 1) {
+      // Case for starting sim
+      console.log('starting force sim')
+      flsimrun = true
+      // start with two nodes
+      let positions = this.getAllHunkPositions()
+      for (let i in positions) {
+        flnodes.push({
+          index: i,
+          x: positions[i].x,
+          y: positions[i].y,
+          vx: 0,
+          vy: 0
         })
-        */
+      }
+      flsim = d3.forceSimulation(flnodes)
+        .force('charge', d3.forceManyBody().strength(-20))
+        .force('center', d3.forceCenter(600, 600))
+        .force('collide', d3.forceCollide(150))
+        .alphaMin(finAlpha)
+        .on('tick', flTick)
+        .on('end', flEnd)
+    } else if (blocks.length <= 1) {
+      // donot
+    } else {
+      // case for adding / rming from sim
+      this.log('UPD8 Force Sim')
+      let positions = this.getAllHunkPositions()
+      if (positions.length > flnodes.length) {
+        let last = positions.length - 1
+        //console.log('to add new node like', positions[last])
+        let newNode = {
+          index: last,
+          x: positions[last].x,
+          y: positions[last].y,
+          vx: 0,
+          vy: 0
+        }
+        flnodes.push(newNode)
+        // console.log('SIM adds now this', newNode.x, newNode.y)
+      } else {
+        console.log("SIM DELETE CASE NOT WRITTEN")
+      }
+      flsim.nodes(flnodes)
+      flsim.alpha(1)
+        .alphaMin(finAlpha)
+        .restart()
     }
-
-    let canvasUpListener = (evt) => {
-        window.removeEventListener('mousemove', canvasDragListener)
-        window.removeEventListener('mouseup', canvasUpListener)
+  }
+
+  let flTick = () => {
+    // called on sim update
+    let blks = $(this.plane).children('.block')
+    if (blks.length !== flnodes.length) {
+      console.log('FLOOP NODES MISMATCH', blks.length, flnodes.length)
+    } else {
+      for (let i = 0; i < blks.length; i++) {
+        blks[i].style.left = flnodes[i].x + 'px'
+        blks[i].style.top = flnodes[i].y + 'px'
+      }
     }
-
-    // CONTEXT MENU 
-    let onContextMenu = (evt) => {
-        //console.log(evt)
-        evt.preventDefault()
-        evt.stopPropagation()
-        // TRANSFORM here to write menu in the right spot on click 
-        let menu = $('<div>').addClass('contextmenu')
-            .append('<ul> hello -> </ul>').get(0)
-        let ct = readTransform(this.plane)
-        console.log('write to ', ct)
-        writeTransform(menu, { s: 1, x: evt.layerX - ct.x * ct.s, y: evt.layerY - ct.y * ct.s })
-        $(this.plane).append(menu)
-        // an output 
-        this.writemessage('hello', ' ')
+    drawLinks()
+  }
+
+  let flEnd = () => {
+    console.log('FIN DU SIM')
+  }
+
+  this.getAllHunkPositions = () => {
+    let nds = $(this.plane).children('.block')
+    let positions = new Array()
+    for (let nd of nds) {
+      let ps = readXY(nd)
+      ps.id = nd.id
+      positions.push(ps)
     }
-
-    let menuNextItem = (text) => {
-        $(this.plane).children('.contextmenu').children().not('ul').remove()
-        $(this.plane).children('.contextmenu').append('<ul>' + text + '</ul>')
+    return positions
+    // should do transform here ?
+  }
+
+  /* ---------------------------    ---------------------------- */
+  /* -------------------- DRAWING & MOVING --------------------- */
+  /* ---------------------------    ---------------------------- */
+
+  let writeTransform = (div, tf) => {
+    div.style.transform = `scale(${tf.s})`
+    //div.style.transformOrigin = `${tf.ox}px ${tf.oy}px`
+    div.style.left = `${tf.x}px`
+    div.style.top = `${tf.y}px`
+  }
+
+  let writeBackgroundTransform = (div, tf) => {
+    div.style.backgroundSize = `${tf.s * 100}px ${tf.s * 100}px`
+    div.style.backgroundPosition = `${tf.x}px ${tf.y}px `
+  }
+
+  let readTransform = (div) => {
+    // transform, for scale
+    let transform = div.style.transform
+    let index = transform.indexOf('scale')
+    let left = transform.indexOf('(', index)
+    let right = transform.indexOf(')', index)
+    let s = parseFloat(transform.slice(left + 1, right))
+
+    // left and right, position
+    let x = parseFloat(div.style.left)
+    let y = parseFloat(div.style.top)
+
+    return ({
+      s: s,
+      x: x,
+      y: y
+    })
+  }
+
+  let reposition = (div) => {
+    div.style.left = div.x + 'px'
+    div.style.top = div.y + 'px'
+  }
+
+  let readXY = (div) => {
+    //console.log('READXY left', div.style.left, 'top', div.style.top)
+    return {
+      x: div.style.left,
+      y: div.style.top
     }
-
-    let addContextOptions = (list) => {
-        let menu = $(this.plane).children('.contextmenu').get(0)
-        for (let index in list) {
-            $(menu).append(writeContextOption(list[index].text, list[index].header, list[index].content))
+  }
+
+  let drawLinks = () => {
+    // from within the div
+    let outputs = $(this.plane).children('.block').children('.outputs').children('.output')
+    // clear all links
+    BZ.clear(this.plane)
+    // and draw new ones
+    for (let output of outputs) {
+      // finding the children to hookup to
+      for (let conn of output.connectedTo) {
+        // find looks down *all* branches of the dom tree
+        // with children().children() we can reduce that tree
+        let hookup = $(this.plane).find(conn)
+        if (hookup.length !== 1) {
+          // this can happen when a dependent is not loaded yet
+          console.log('mismatched connection', hookup.length, conn)
+        } else {
+          let hk = hookup.get(0)
+          let head = BZ.getRightHandle(output, this.plane.subscale)
+          let tail
+          if (hk.id === 'floater') {
+            tail = BZ.getFloaterHandle(hk, this.plane.subscale)
+          } else {
+            tail = BZ.getLeftHandle(hk, this.plane.subscale)
+          }
+          let bz = BZ.writeBezier(head, tail, output.id + hk.id, this.plane)
+          bz.addEventListener('mouseenter', (evt) => {
+            bz.style.stroke = '#2889af'
+          })
+          bz.addEventListener('mouseout', (evt) => {
+            bz.style.stroke = '#1a1a1a'
+          })
+          bz.addEventListener('contextmenu', (evt) => {
+            evt.preventDefault()
+            evt.stopPropagation()
+            // nice
+            let outId = output.id.substring(0, output.id.indexOf('_output_'))
+            let outName = output.id.substring(output.id.indexOf('_output_') + 8)
+            let inId = conn.substring(1, conn.indexOf('_input_'))
+            let inName = conn.substring(conn.indexOf('_input_') + 7)
+            this.writemessage('removelink', {
+              outId: outId,
+              outName: outName,
+              inId: inId,
+              inName: inName
+            })
+            console.log('cntextlink', '#' + output.id, conn)
+            // write those up as a message ...
+          })
         }
+      }
     }
-
-    let writeContextOption = (text, header, content) => {
-        let item = $('<li>' + text + '</li>').get(0)
-        item.addEventListener('click', (evt) => {
-            this.writemessage(header, content)
-            menuNextItem(header + ' ' + content + ' ->')
-        })
-        return item
+  }
+
+  /* ---------------------------    ---------------------------- */
+  /* -------------------- DEFS in the DOM ---------------------- */
+  /* ---------------------------    ---------------------------- */
+
+  // ADD A DEF
+  // TODO HERE big def walk and update ...
+  // this will make updating things more straightforward?
+  // until we have a def that has a view ... ...
+  let putDef = (def) => {
+    if (false) console.log('ready write', def)
+    // get a position
+    // TODO if/ for case where no menu before load
+    let menu = $(this.plane).children('.contextmenu').get(0)
+    // TRANSFORM for scale here, position to where-added ?
+    let mt
+    if (menu === undefined) {
+      // we need a position, let's pick random
+      mt = {
+        s: 1,
+        x: Math.random() * 1000,
+        y: Math.random() * 800
+      }
+    } else {
+      mt = readTransform(menu)
     }
 
-
-    /* ---------------------------    ---------------------------- */
-    /* ---------------------- FORCE LAYOUT ----------------------- */
-    /* ---------------------------    ---------------------------- */
-
-    // ok, my thoughts on this
-    /*
-
-    I obviously need to think carefully about it for a minute 
-    I'm going to make it sortof-work before I go forwards with the link 
-
-    - should restart on adding a new hunk with existing positions 
-    - should be able to stop it when we mousedown 
-
-    */
-
-    let blocks = new Array()
-    let flsimrun = false
-    let flsim = {}
-    let flnodes = []
-
-    let finAlpha = 0.5
-
-    let updateForceLoop = () => {
-        // init and/or update 
-        if (!flsimrun && blocks.length > 1) {
-            // Case for starting sim 
-            console.log('starting force sim')
-            flsimrun = true
-            // start with two nodes 
-            let positions = this.getAllHunkPositions()
-            for (let i in positions) {
-                flnodes.push({
-                    index: i,
-                    x: positions[i].x,
-                    y: positions[i].y,
-                    vx: 0,
-                    vy: 0
-                })
-            }
-            flsim = d3.forceSimulation(flnodes)
-                .force('charge', d3.forceManyBody().strength(-20))
-                .force('center', d3.forceCenter(600, 600))
-                .force('collide', d3.forceCollide(150))
-                .alphaMin(finAlpha)
-                .on('tick', flTick)
-                .on('end', flEnd)
-        } else if (blocks.length <= 1) {
-            // donot
-        } else {
-            // case for adding / rming from sim 
-            this.log('UPD8 Force Sim')
-            let positions = this.getAllHunkPositions()
-            if (positions.length > flnodes.length) {
-                let last = positions.length - 1
-                //console.log('to add new node like', positions[last])
-                let newNode = {
-                    index: last,
-                    x: positions[last].x,
-                    y: positions[last].y,
-                    vx: 0,
-                    vy: 0
-                }
-                flnodes.push(newNode)
-                // console.log('SIM adds now this', newNode.x, newNode.y)
-            } else {
-                console.log("SIM DELETE CASE NOT WRITTEN")
-            }
-            flsim.nodes(flnodes)
-            flsim.alpha(1)
-                .alphaMin(finAlpha)
-                .restart()
+    // write the def dom
+    let de = writeDefDom(def, false)
+    // not interested in adding the top level's view to itself
+    // TODO probably this is a bugfarm when we go to nest views
+    if (def.dom !== null && def.dom !== undefined && def.id !== 'TLView') {
+      this.log(`${def.id} UI DOM appears...`, def.dom)
+      try {
+        $(de).append($(def.dom).addClass('cuttlefishhunkdom'))
+        if ($(def.dom).is('.view')) {
+          de.style.height = '800px'
+          de.style.width = '1200px'
+          // start of a handle attempt ...
+          $(de).append($('<div>').addClass('rsHandle').on('mousedown', (evt) => {
+            console.log('rshandle down')
+          }))
         }
+      } catch (err) {
+        console.log('error while appending cfhnk to dom', err)
+      }
     }
-
-    let flTick = () => {
-        // called on sim update 
-        let blks = $(this.plane).children('.block')
-        if (blks.length !== flnodes.length) {
-            console.log('FLOOP NODES MISMATCH', blks.length, flnodes.length)
-        } else {
-            for (let i = 0; i < blks.length; i++) {
-                blks[i].style.left = flnodes[i].x + 'px'
-                blks[i].style.top = flnodes[i].y + 'px'
-            }
+    writeTransform(de, mt)
+    // rm menu if it's around
+    if (menu !== undefined) $(menu).remove()
+
+    // add the def to the view
+    $(this.plane).append(de)
+
+    // for the sim, add an x and y
+    // and we keep a list, but maybe don't need to?
+    blocks.push(de)
+
+    // AS Policy, since this thing *is* a stateful view,
+    // we keep state in the view. no mirror, def is a throwaway
+    // i.e. we won't return it: it contains everything we need
+    drawLinks()
+
+    // here is an OK place to do the sorting ...
+    // TODO: add to D3
+    updateForceLoop()
+  }
+
+  let removeDef = (id) => {
+    // get the inputs that we'll have to watch removal for
+    let inpts = $(this.plane).children('#' + id).children('.inputs').children('.input')
+    // remove the def / block
+    $(this.plane).children('#' + id).remove()
+    // we have to walk over the other outputs and disconnect them,
+    let otps = $(this.plane).find('.output')
+    for (let otp of otps) {
+      for (let inp of inpts) {
+        if (otp.connectedTo.includes('#' + inp.id)) {
+          otp.connectedTo.splice(otp.connectedTo.indexOf('#' + inp.id))
         }
-        drawLinks()
+      }
     }
-
-    let flEnd = () => {
-        console.log('FIN DU SIM')
+    drawLinks()
+  }
+
+  let putLink = (outId, outName, inId, inName) => {
+    try {
+      let outp = $(this.plane).children('.block').children('.outputs').children('#' + outId + '_output_' + outName).get(0)
+      outp.connectedTo.push('#' + inId + '_input_' + inName)
+      drawLinks()
+    } catch (err) {
+      console.log('ERR at putlink', err)
+      return false
     }
-
-    this.getAllHunkPositions = () => {
-        let nds = $(this.plane).children('.block')
-        let positions = new Array()
-        for (let nd of nds) {
-            let ps = readXY(nd)
-            ps.id = nd.id
-            positions.push(ps)
-        }
-        return positions
-        // should do transform here ? 
+    return true
+  }
+
+  let removeLink = (outId, outName, inId, inName) => {
+    try {
+      let outp = $(this.plane).children('.block').children('.outputs').children('#' + outId + '_output_' + outName).get(0)
+      outp.connectedTo.splice(outp.connectedTo.indexOf('#' + inId + '_input_' + inName), 1)
+      drawLinks()
+    } catch (err) {
+      console.log('ERR at rmlink', err)
+      return true
+    }
+    return false
+  }
+
+  /* ---------------------------    ---------------------------- */
+  /* ---------------------- WRITING DEFS ----------------------- */
+  /* ---------------------------    ---------------------------- */
+
+  let writeDefDom = (def, debug) => {
+    // debug
+    if (debug) console.log('writing for def', def)
+    // a div to locate it
+    let de = document.createElement('div')
+    $(de).addClass('block').attr('id', def.id)
+
+    // more html: the title
+    $(de).append($('<div>' + de.id + '</div>').addClass('blockid').append('<span style="float:right;"> (' + def.name + ')</span>'))
+
+    let title = $(de).children('.blockid').get(0)
+
+    title.oncontextmenu = (evt) => {
+      evt.preventDefault()
+      evt.stopPropagation()
+      // write menu for requesting delete and copy
+      let menu = $('<div>').addClass('contextmenu').get(0)
+      // title.offsetWidth is 400
+      // de.style.left, de.style.top, de.clientWidth,
+      let ct = readTransform(de)
+      let x = ct.x + 400 + 10 + 'px'
+      writeTransform(menu, {
+        s: 1,
+        x: ct.x + ((400 + 10)),
+        y: ct.y
+      })
+      $(this.plane).append(menu)
+      $(menu).append($('<li>remove hunk</li>').on('click', (evt) => {
+        this.writemessage('removehunk', {
+          id: def.id,
+          name: def.name
+        })
+        $(menu).remove()
+      }))
+      $(menu).append($('<li>copy hunk</li>').on('click', (evt) => {
+        this.writemessage('addhunk', def.name)
+        $(menu).remove()
+      }))
     }
 
-    /* ---------------------------    ---------------------------- */
-    /* -------------------- DRAWING & MOVING --------------------- */
-    /* ---------------------------    ---------------------------- */
+    title.onmousedown = function(evt) {
+      evt.preventDefault()
+      evt.stopPropagation()
 
-    let writeTransform = (div, tf) => {
-        div.style.transform = `scale(${tf.s})`
-        //div.style.transformOrigin = `${tf.ox}px ${tf.oy}px`
-        div.style.left = `${tf.x}px`
-        div.style.top = `${tf.y}px`
-    }
+      function domElemMouseMove(evt) {
+        // TRANSFORMS here to move div about on drag
+        evt.preventDefault()
+        evt.stopPropagation()
+        let ct = readTransform(de)
+        let pt = readTransform(de.parentElement)
+        ct.x += evt.movementX / pt.s
+        ct.y += evt.movementY / pt.s
+        writeTransform(de, ct)
+        drawLinks()
+      }
 
-    let writeBackgroundTransform = (div, tf) => {
-        div.style.backgroundSize = `${tf.s * 100}px ${tf.s * 100}px`
-        div.style.backgroundPosition = `${tf.x}px ${tf.y}px `
-    }
+      function rmOnMouseUp(evt) {
+        // would do save of position state here
+        // TODO /\
+        document.removeEventListener('mousemove', domElemMouseMove)
+        document.removeEventListener('mouseup', rmOnMouseUp)
+      }
 
-    let readTransform = (div) => {
-        // transform, for scale
-        let transform = div.style.transform
-        let index = transform.indexOf('scale')
-        let left = transform.indexOf('(', index)
-        let right = transform.indexOf(')', index)
-        let s = parseFloat(transform.slice(left + 1, right))
-
-        // left and right, position
-        let x = parseFloat(div.style.left)
-        let y = parseFloat(div.style.top)
-
-        return ({
-            s: s,
-            x: x,
-            y: y
-        })
+      document.addEventListener('mousemove', domElemMouseMove)
+      document.addEventListener('mouseup', rmOnMouseUp)
     }
 
-    let reposition = (div) => {
-        div.style.left = div.x + 'px'
-        div.style.top = div.y + 'px'
+    if (Object.keys(def.inputs).length > 0) {
+      let idom = $('<div>').addClass('inputs')
+      for (let key in def.inputs) {
+        if (debug) console.log('def.inputs[key]', def.inputs[key])
+        $(idom).append(writePortDom(def.inputs[key], def, 'input', debug))
+      }
+      $(de).append(idom)
     }
 
-    let readXY = (div) => {
-        //console.log('READXY left', div.style.left, 'top', div.style.top)
-        return { x: div.style.left, y: div.style.top }
+    if (Object.keys(def.inputs).length > 0) {
+      let odom = $('<div>').addClass('outputs')
+      for (let key in def.outputs) {
+        if (debug) console.log('def.outputs[key]', def.outputs[key])
+        $(odom).append(writePortDom(def.outputs[key], def, 'output', debug))
+      }
+      $(de).append(odom)
     }
 
-    let drawLinks = () => {
-        // from within the div
-        let outputs = $(this.plane).children('.block').children('.outputs').children('.output')
-        // clear all links 
-        BZ.clear(this.plane)
-        // and draw new ones
-        for (let output of outputs) {
-            // finding the children to hookup to 
-            for (let conn of output.connectedTo) {
-                // find looks down *all* branches of the dom tree
-                // with children().children() we can reduce that tree
-                let hookup = $(this.plane).find(conn)
-                if (hookup.length !== 1) {
-                    // this can happen when a dependent is not loaded yet 
-                    console.log('mismatched connection', hookup.length, conn)
-                } else {
-                    let hk = hookup.get(0)
-                    let head = BZ.getRightHandle(output, this.plane.subscale)
-                    let tail
-                    if (hk.id === 'floater') {
-                        tail = BZ.getFloaterHandle(hk, this.plane.subscale)
-                    } else {
-                        tail = BZ.getLeftHandle(hk, this.plane.subscale)
-                    }
-                    let bz = BZ.writeBezier(head, tail, output.id + hk.id, this.plane)
-                    bz.addEventListener('mouseenter', (evt) => {
-                        bz.style.stroke = '#2889af'
-                    })
-                    bz.addEventListener('mouseout', (evt) => {
-                        bz.style.stroke = '#1a1a1a'
-                    })
-                    bz.addEventListener('contextmenu', (evt) => {
-                        evt.preventDefault()
-                        evt.stopPropagation()
-                        // nice 
-                        let outId = output.id.substring(0, output.id.indexOf('_output_'))
-                        let outName = output.id.substring(output.id.indexOf('_output_') + 8)
-                        let inId = conn.substring(1, conn.indexOf('_input_'))
-                        let inName = conn.substring(conn.indexOf('_input_') + 7)
-                        this.writemessage('removelink', { outId: outId, outName: outName, inId: inId, inName: inName })
-                        console.log('cntextlink', '#' + output.id, conn)
-                        // write those up as a message ... 
-                    })
-                }
-            }
-        }
+    if (Object.keys(def.inputs).length > 0) {
+      let sdom = $('<div>').addClass('state')
+      for (let key in def.state) {
+        if (debug) console.log('state dom', sdom)
+        if (debug) console.log('def.state[key]', def.state[key])
+        $(sdom).append(writeStateDom(def.state[key], def, debug))
+      }
+      $(de).append(sdom)
     }
-
-    /* ---------------------------    ---------------------------- */
-    /* -------------------- DEFS in the DOM ---------------------- */
-    /* ---------------------------    ---------------------------- */
-
-    // ADD A DEF 
-    // TODO HERE big def walk and update ...
-    // this will make updating things more straightforward?
-    // until we have a def that has a view ... ... 
-    let putDef = (def) => {
-        if (false) console.log('ready write', def)
-        // get a position
-        // TODO if/ for case where no menu before load 
-        let menu = $(this.plane).children('.contextmenu').get(0)
-        // TRANSFORM for scale here, position to where-added ? 
-        let mt
-        if (menu === undefined) {
-            // we need a position, let's pick random 
-            mt = { s: 1, x: Math.random() * 1000, y: Math.random() * 800 }
-        } else {
-            mt = readTransform(menu)
-        }
-
-        // write the def dom 
-        let de = writeDefDom(def, false)
-        // not interested in adding the top level's view to itself
-        // TODO probably this is a bugfarm when we go to nest views 
-        if (def.dom !== null && def.dom !== undefined && def.id !== 'TLView') {
-            this.log(`${def.id} UI DOM appears...`, def.dom)
-            try {
-                $(de).append($(def.dom).addClass('cuttlefishhunkdom'))
-                if ($(def.dom).is('.view')) {
-                    de.style.height = '800px'
-                    de.style.width = '1200px'
-                    // start of a handle attempt ... 
-                    $(de).append($('<div>').addClass('rsHandle').on('mousedown', (evt) =>{
-                        console.log('rshandle down')
-                    }))
-                }
-            } catch (err) {
-                console.log('error while appending cfhnk to dom', err)
-            }
-        }
-        writeTransform(de, mt)
-        // rm menu if it's around 
-        if (menu !== undefined) $(menu).remove()
-
-        // add the def to the view 
-        $(this.plane).append(de)
-
-        // for the sim, add an x and y 
-        // and we keep a list, but maybe don't need to?
-        blocks.push(de)
-
-        // AS Policy, since this thing *is* a stateful view,
-        // we keep state in the view. no mirror, def is a throwaway 
-        // i.e. we won't return it: it contains everything we need 
-        drawLinks()
-
-        // here is an OK place to do the sorting ... 
-        // TODO: add to D3 
-        updateForceLoop()
+    return de
+  }
+
+  let writePortDom = (port, def, inout, debug) => {
+    if (debug) console.log('port dom', port, def.id, inout)
+    let id = def.id + '_' + inout + '_' + port.name
+    if ($(this.plane).children(id).length > 0) {
+      console.log("VIEW UNTESTED RECEIPT OF DEF FOR EXISTING DEF")
+      $(this.plane).children(id).remove()
     }
-
-    let removeDef = (id) => {
-        // get the inputs that we'll have to watch removal for 
-        let inpts = $(this.plane).children('#' + id).children('.inputs').children('.input')
-        // remove the def / block
-        $(this.plane).children('#' + id).remove()
-        // we have to walk over the other outputs and disconnect them, 
-        let otps = $(this.plane).find('.output')
-        for (let otp of otps) {
-            for (let inp of inpts) {
-                if (otp.connectedTo.includes('#' + inp.id)) {
-                    otp.connectedTo.splice(otp.connectedTo.indexOf('#' + inp.id))
-                }
-            }
-        }
-        drawLinks()
+    let dom = {}
+    if(inout === "input"){
+      dom = $('<li>' + port.name + " (" + port.type + ")" + '</li>').addClass(inout).get(0)
+    } else {
+      dom = $('<li>' + "(" + port.type + ") " + port.name + '</li>').addClass(inout).get(0)
     }
-
-    let putLink = (outId, outName, inId, inName) => {
-        try {
-            let outp = $(this.plane).children('.block').children('.outputs').children('#' + outId + '_output_' + outName).get(0)
-            outp.connectedTo.push('#' + inId + '_input_' + inName)
-            drawLinks()
-        } catch (err) {
-            console.log('ERR at putlink', err)
-            return false
-        }
-        return true
+    dom.id = id
+    // this goes in so that we can handily draw links
+    dom.connectedTo = new Array()
+    // let ... in is OK for zero-length arrays, but for ... of throws errors
+    for (let conn in port.connections) {
+      let cn = port.connections[conn]
+      // HERE is the missing link (haha) ... defid , what is
+      // has undefined in title ...
+      dom.connectedTo.push('#' + cn.parentid + '_input_' + cn.input)
     }
-
-    let removeLink = (outId, outName, inId, inName) => {
-        try {
-            let outp = $(this.plane).children('.block').children('.outputs').children('#' + outId + '_output_' + outName).get(0)
-            outp.connectedTo.splice(outp.connectedTo.indexOf('#' + inId + '_input_' + inName), 1)
-            drawLinks()
-        } catch (err) {
-            console.log('ERR at rmlink', err)
-            return true
-        }
-        return false
+    // messy global for the potential floater
+    let floater = {}
+
+    // the events
+    let evtDrag = (drag) => {
+      let cp = readTransform(floater)
+      cp.x += drag.movementX
+      cp.y += drag.movementY
+      writeTransform(floater, cp)
+      drawLinks()
     }
 
-    /* ---------------------------    ---------------------------- */
-    /* ---------------------- WRITING DEFS ----------------------- */
-    /* ---------------------------    ---------------------------- */
-
-    let writeDefDom = (def, debug) => {
-        // debug
-        if (debug) console.log('writing for def', def)
-        // a div to locate it 
-        let de = document.createElement('div')
-        $(de).addClass('block').attr('id', def.id)
-
-        // more html: the title
-        $(de).append($('<div>' + de.id + '</div>').addClass('blockid').append('<span style="float:right;"> (' + def.name + ')</span>'))
-
-        let title = $(de).children('.blockid').get(0)
-
-        title.oncontextmenu = (evt) => {
-            evt.preventDefault()
-            evt.stopPropagation()
-            // write menu for requesting delete and copy 
-            let menu = $('<div>').addClass('contextmenu').get(0)
-            // title.offsetWidth is 400
-            // de.style.left, de.style.top, de.clientWidth, 
-            let ct = readTransform(de)
-            let x = ct.x + 400 + 10 + 'px'
-            writeTransform(menu, { s: 1, x: ct.x + ((400 + 10)), y: ct.y })
-            $(this.plane).append(menu)
-            $(menu).append($('<li>remove hunk</li>').on('click', (evt) => {
-                this.writemessage('removehunk', { id: def.id, name: def.name })
-                $(menu).remove()
-            }))
-            $(menu).append($('<li>copy hunk</li>').on('click', (evt) => {
-                this.writemessage('addhunk', def.name)
-                $(menu).remove()
-            }))
-        }
-
-        title.onmousedown = function(evt) {
-            evt.preventDefault()
-            evt.stopPropagation()
-
-            function domElemMouseMove(evt) {
-                // TRANSFORMS here to move div about on drag 
-                evt.preventDefault()
-                evt.stopPropagation()
-                let ct = readTransform(de)
-                let pt = readTransform(de.parentElement)
-                ct.x += evt.movementX / pt.s
-                ct.y += evt.movementY / pt.s
-                writeTransform(de, ct)
-                drawLinks()
-            }
-
-            function rmOnMouseUp(evt) {
-                // would do save of position state here 
-                // TODO /\
-                document.removeEventListener('mousemove', domElemMouseMove)
-                document.removeEventListener('mouseup', rmOnMouseUp)
-            }
-
-            document.addEventListener('mousemove', domElemMouseMove)
-            document.addEventListener('mouseup', rmOnMouseUp)
-        }
-
-        if (Object.keys(def.inputs).length > 0) {
-            let idom = $('<div>').addClass('inputs')
-            for (let key in def.inputs) {
-                if (debug) console.log('def.inputs[key]', def.inputs[key])
-                $(idom).append(writePortDom(def.inputs[key], def, 'input', debug))
-            }
-            $(de).append(idom)
-        }
-
-        if (Object.keys(def.inputs).length > 0) {
-            let odom = $('<div>').addClass('outputs')
-            for (let key in def.outputs) {
-                if (debug) console.log('def.outputs[key]', def.outputs[key])
-                $(odom).append(writePortDom(def.outputs[key], def, 'output', debug))
-            }
-            $(de).append(odom)
-        }
-
-        if (Object.keys(def.inputs).length > 0) {
-            let sdom = $('<div>').addClass('state')
-            for (let key in def.state) {
-                if (debug) console.log('state dom', sdom)
-                if (debug) console.log('def.state[key]', def.state[key])
-                $(sdom).append(writeStateDom(def.state[key], def, debug))
-            }
-            $(de).append(sdom)
-        }
-        return de
+    let dragMouseUp = (evt) => {
+      console.log('MOUSEUP ON', evt.target.id)
+      // recall name and def id from id
+      let str = evt.target.id
+      let last = str.lastIndexOf('_')
+      let name = str.substring(last + 1)
+      console.log('with name', name)
+      let first = str.indexOf('_')
+      let next = str.indexOf('_', first + 1)
+      let id = str.substring(0, next)
+      console.log('and id', id)
+      // HERE this is current stifle, an awkward message, I think ?
+      this.writemessage('addlink', {
+        outId: def.id,
+        outName: port.name,
+        inId: id,
+        inName: name
+      })
+      // do things to conn, then
+      // cleanup
+      this.plane.removeEventListener('mouseup', dragMouseUp)
+      this.plane.removeEventListener('mousemove', evtDrag)
+      dom.connectedTo.splice(dom.connectedTo.indexOf('#floater'), 1)
+      $('#floater').remove()
+      drawLinks()
     }
 
-    let writePortDom = (port, def, inout, debug) => {
-        if (debug) console.log('port dom', port, def.id, inout)
-        let id = def.id + '_' + inout + '_' + port.name
-        if ($(this.plane).children(id).length > 0) {
-            console.log("VIEW UNTESTED RECEIPT OF DEF FOR EXISTING DEF")
-            $(this.plane).children(id).remove()
-        }
-        let dom = $('<li>' + port.name + '</li>').addClass(inout).get(0)
-        dom.id = id
-        // this goes in so that we can handily draw links
-        dom.connectedTo = new Array()
-        // let ... in is OK for zero-length arrays, but for ... of throws errors 
-        for (let conn in port.connections) {
-            let cn = port.connections[conn]
-            // HERE is the missing link (haha) ... defid , what is 
-            // has undefined in title ... 
-            dom.connectedTo.push('#' + cn.parentid + '_input_' + cn.input)
-        }
-        // messy global for the potential floater 
-        let floater = {}
-
-        // the events
-        let evtDrag = (drag) => {
-            let cp = readTransform(floater)
-            cp.x += drag.movementX
-            cp.y += drag.movementY
-            writeTransform(floater, cp)
-            drawLinks()
-        }
-
-        let dragMouseUp = (evt) => {
-            console.log('MOUSEUP ON', evt.target.id)
-            // recall name and def id from id
-            let str = evt.target.id
-            let last = str.lastIndexOf('_')
-            let name = str.substring(last + 1)
-            console.log('with name', name)
-            let first = str.indexOf('_')
-            let next = str.indexOf('_', first + 1)
-            let id = str.substring(0, next)
-            console.log('and id', id)
-            // HERE this is current stifle, an awkward message, I think ? 
-            this.writemessage('addlink', { outId: def.id, outName: port.name, inId: id, inName: name })
-            // do things to conn, then
-            // cleanup 
-            this.plane.removeEventListener('mouseup', dragMouseUp)
-            this.plane.removeEventListener('mousemove', evtDrag)
-            dom.connectedTo.splice(dom.connectedTo.indexOf('#floater'), 1)
-            $('#floater').remove()
-            drawLinks()
-        }
-
-        // startup the floater 
-        dom.addEventListener('mousedown', (down) => {
-            console.log('MOUSEDOWN for', port.type, port.name, down)
-            // get the location to make the floater, 
-            let cp = BZ.getRightHandle(dom, this.plane.subscale)
-            floater = $('<div>').attr('id', 'floater').append(port.type).get(0)
-            floater.style.zIndex = '1'
-            this.plane.appendChild(floater)
-            // 'hookup' our floater and its berth
-            dom.connectedTo.push('#floater')
-            // init out floater position, and put it in the dom 
-            writeTransform(floater, {
-                s: this.plane.subscale,
-                x: cp.x - 80 * this.plane.subscale,
-                y: cp.y - (floater.clientHeight / 2) * this.plane.subscale
-            })
-            // do relative moves 
-            this.plane.addEventListener('mousemove', evtDrag)
-            // and delete / act when mouse comes up 
-            this.plane.addEventListener('mouseup', dragMouseUp)
+    // startup the floater
+    dom.addEventListener('mousedown', (down) => {
+      console.log('MOUSEDOWN for', port.type, port.name, down)
+      // get the location to make the floater,
+      let cp = BZ.getRightHandle(dom, this.plane.subscale)
+      floater = $('<div>').attr('id', 'floater').append(port.type).get(0)
+      floater.style.zIndex = '1'
+      this.plane.appendChild(floater)
+      // 'hookup' our floater and its berth
+      dom.connectedTo.push('#floater')
+      // init out floater position, and put it in the dom
+      writeTransform(floater, {
+        s: this.plane.subscale,
+        x: cp.x - 80 * this.plane.subscale,
+        y: cp.y - (floater.clientHeight / 2) * this.plane.subscale
+      })
+      // do relative moves
+      this.plane.addEventListener('mousemove', evtDrag)
+      // and delete / act when mouse comes up
+      this.plane.addEventListener('mouseup', dragMouseUp)
+    })
+
+    if (debug) console.log('port', dom)
+    return dom
+  }
+
+  let writeStateDom = (state, def) => {
+    let dom = $('<li>' + state.name + '</li>').get(0)
+    dom.id = def.id + '_state_' + state.name
+    switch (typeof state.value) {
+      case 'string':
+        let strinput = $('<input>').attr('type', 'text').attr('size', 24).attr('value', state.value).get(0)
+        strinput.addEventListener('change', (evt) => {
+          // ask for a change,
+          // TODO HERE NOW: this is the state change request you want to write
+          // do it like writemessage() instead
+          // requestStateChange(def.id, state, strinput.value)
+          // but assert that we don't change the definition unless
+          requestStateChange(def.id, state, strinput.value)
+          strinput.value = state.value
         })
+        state.dom = strinput
+        $(dom).append(strinput)
+        break
+
+      case 'number':
+        let ninput = $('<input>').attr('type', 'text').attr('size', 24).attr('value', state.value.toString()).get(0)
+        ninput.addEventListener('change', (evt) => {
+          // ask for a change,
+          requestStateChange(def.id, state, parseFloat(ninput.value))
+          // but assert that we don't change the definition unless
+          ninput.value = state.value
+        })
+        state.dom = ninput
+        $(dom).append(ninput)
+        break
+
+      case 'boolean':
+        $(dom).append('<span style="float:right;">' + state.value.toString() + '</span>')
+        dom.addEventListener('click', (evt) => {
+          // read the current 'state' (as written) and send the opposite
+          let txt = $(dom).children('span').text()
+          if (txt === 'true') {
+            requestStateChange(def.id, state, false)
+          } else {
+            requestStateChange(def.id, state, true)
+          }
+        })
+        break
 
-        if (debug) console.log('port', dom)
-        return dom
-    }
-
-    let writeStateDom = (state, def) => {
-        let dom = $('<li>' + state.name + '</li>').get(0)
-        dom.id = def.id + '_state_' + state.name
-        switch (typeof state.value) {
-            case 'string':
-                let strinput = $('<input>').attr('type', 'text').attr('size', 24).attr('value', state.value).get(0)
-                strinput.addEventListener('change', (evt) => {
-                    // ask for a change,
-                    // TODO HERE NOW: this is the state change request you want to write
-                    // do it like writemessage() instead 
-                    // requestStateChange(def.id, state, strinput.value)
-                    // but assert that we don't change the definition unless
-                    requestStateChange(def.id, state, strinput.value)
-                    strinput.value = state.value
-                })
-                state.dom = strinput
-                $(dom).append(strinput)
-                break
-
-            case 'number':
-                let ninput = $('<input>').attr('type', 'text').attr('size', 24).attr('value', state.value.toString()).get(0)
-                ninput.addEventListener('change', (evt) => {
-                    // ask for a change,
-                    requestStateChange(def.id, state, parseFloat(ninput.value))
-                    // but assert that we don't change the definition unless
-                    ninput.value = state.value
-                })
-                state.dom = ninput
-                $(dom).append(ninput)
-                break
-
-            case 'boolean':
-                $(dom).append('<span style="float:right;">' + state.value.toString() + '</span>')
-                dom.addEventListener('click', (evt) => {
-                    // read the current 'state' (as written) and send the opposite 
-                    let txt = $(dom).children('span').text()
-                    if (txt === 'true') {
-                        requestStateChange(def.id, state, false)
-                    } else {
-                        requestStateChange(def.id, state, true)
-                    }
-                })
-                break
-
-            default:
-
-                // + note on nonrec type 
-                break
-        }
-        return dom
-    }
+      default:
 
-    let requestStateChange = (parentid, state, value) => {
-        this.writemessage('statechange', {
-            id: parentid,
-            name: state.name,
-            value: value
-        })
+        // + note on nonrec type
+        break
     }
-
-    // responses (change state / add link)
-
-    let receiveStateChange = (parentid, name, value) => {
-        let blkstate = $(this.plane).find('#' + parentid + '_state_' + name)
-        if (blkstate !== null && blkstate !== undefined) {
-            // find value / etc 
-            let inp = $(blkstate).children('input').get(0)
-            if (inp !== null && inp !== undefined) {
-                inp.value = value
-            } else {
-                if (typeof value !== 'boolean') {
-                    console.log('ERR State Change for non Boolean on Boolean Type')
-                } else {
-                    $(blkstate).children('span').text(value)
-                }
-            }
+    return dom
+  }
+
+  let requestStateChange = (parentid, state, value) => {
+    this.writemessage('statechange', {
+      id: parentid,
+      name: state.name,
+      value: value
+    })
+  }
+
+  // responses (change state / add link)
+
+  let receiveStateChange = (parentid, name, value) => {
+    let blkstate = $(this.plane).find('#' + parentid + '_state_' + name)
+    if (blkstate !== null && blkstate !== undefined) {
+      // find value / etc
+      let inp = $(blkstate).children('input').get(0)
+      if (inp !== null && inp !== undefined) {
+        inp.value = value
+      } else {
+        if (typeof value !== 'boolean') {
+          console.log('ERR State Change for non Boolean on Boolean Type')
+        } else {
+          $(blkstate).children('span').text(value)
         }
+      }
     }
+  }
 
-    /* ---------------------------    ---------------------------- */
-    /* --------------------- 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', msg.header)
-            console.log(msg.content)
-            this.outputs.msgs.put(msg)
-        } else {
-            // gotta buffer
-            this.outmsgbuffer.push(msg)
-            this.log('MGR OUTBUFFER LEN', this.outmsgbuffer.length)
-        }
+  this.writemessage = (header, content) => {
+    // guaranteed consumption here
+    let msg = {
+      header: header,
+      content: content
     }
-
-    /* ---------------------------    ---------------------------- */
-    /* ------------------ MESSAGES INPUT, LOOP ------------------- */
-    /* ---------------------------    ---------------------------- */
-
-    // still looking for clear function naming / message naming 
-
-    this.loop = () => {
-        // THE Q: is it trees or is it inputs / outputs ? ports ... 
-        if (this.inputs.msgs.io) {
-            // HERE: this hack gets the data without a deep copy, so we want this 
-            // for bringing the dom element over *which is specific to a native manager* 
-            // so TODO: add switch for native / nonative managers 
-            let data = this.inputs.msgs.data
-            let pult = this.inputs.msgs.get()
-            let header = data.header
-            let content = data.content
-            this.log(`gets msg ${header}`)
-            switch (header) {
-                case 'putcontextoptions':
-                    addContextOptions(content)
-                    break
-                case 'putdef':
-                    putDef(content)
-                    break
-                case 'removedef':
-                    removeDef(content)
-                    break
-                case 'putlink':
-                    putLink(content.outId, content.outName, content.inId, content.inName)
-                    break
-                case 'removelink':
-                    removeLink(content.outId, content.outName, content.inId, content.inName)
-                    break
-                case 'putstate':
-                    receiveStateChange(content.id, content.name, content.value)
-                    break
-                case 'error':
-                    console.log('RECV MANAGER ERROR')
-                    console.log(content)
-                    break
-                default:
-                    console.log('VIEW: msg with no switch')
-                    break
-            }
-        }
+    if (this.outputs.msgs.ie && this.outmsgbuffer.length < 1) {
+      // str8 shooters
+      this.log('msg out', msg.header)
+      console.log(msg.content)
+      this.outputs.msgs.put(msg)
+    } else {
+      // gotta buffer
+      this.outmsgbuffer.push(msg)
+      this.log('MGR OUTBUFFER LEN', this.outmsgbuffer.length)
+    }
+  }
+
+  /* ---------------------------    ---------------------------- */
+  /* ------------------ MESSAGES INPUT, LOOP ------------------- */
+  /* ---------------------------    ---------------------------- */
+
+  // still looking for clear function naming / message naming
+
+  this.loop = () => {
+    // THE Q: is it trees or is it inputs / outputs ? ports ...
+    if (this.inputs.msgs.io) {
+      // HERE: this hack gets the data without a deep copy, so we want this
+      // for bringing the dom element over *which is specific to a native manager*
+      // so TODO: add switch for native / nonative managers
+      let data = this.inputs.msgs.data
+      let pult = this.inputs.msgs.get()
+      let header = data.header
+      let content = data.content
+      this.log(`gets msg ${header}`)
+      switch (header) {
+        case 'putcontextoptions':
+          addContextOptions(content)
+          break
+        case 'putdef':
+          putDef(content)
+          break
+        case 'removedef':
+          removeDef(content)
+          break
+        case 'putlink':
+          putLink(content.outId, content.outName, content.inId, content.inName)
+          break
+        case 'removelink':
+          removeLink(content.outId, content.outName, content.inId, content.inName)
+          break
+        case 'putstate':
+          receiveStateChange(content.id, content.name, content.value)
+          break
+        case 'error':
+          console.log('RECV MANAGER ERROR')
+          console.log(content)
+          break
+        default:
+          console.log('VIEW: msg with no switch')
+          break
+      }
     }
+  }
 }
 
-export default View
\ No newline at end of file
+export default View
diff --git a/programs/mvnv.json b/programs/mvnv.json
index 7d04021fdf7d9679bb834b6d4973aaf9c221cbb7..e9ed8a26233761ada04dd9994a1f398484447461 100644
--- a/programs/mvnv.json
+++ b/programs/mvnv.json
@@ -34,15 +34,15 @@
     },
     {
         "outhunk": "lnkone",
-        "outname": "bytes",
+        "outname": "data",
         "inhunk": "wsclient",
-        "inname": "bytes"
+        "inname": "data"
     },
     {
         "outhunk": "wsclient",
-        "outname": "bytes",
+        "outname": "data",
         "inhunk": "lnkone",
-        "inname": "bytes"
+        "inname": "data"
     },
     {
         "outhunk": "nautilusview",
@@ -68,4 +68,4 @@
         "inhunk": "Logger_Duo",
         "inname": "tolog"
     }]
-}
\ No newline at end of file
+}
diff --git a/style.css b/style.css
index f191ce416e8d7c80430a44b5d9c817b65f790332..ab603aae98261fe1b01fb647f072219443dfa1ab 100644
--- a/style.css
+++ b/style.css
@@ -48,8 +48,8 @@ body {
 	background: #d6d6d6;
 	/*background-image:url("background.png");*/
 	/*background-origin: content-box;*/
-  	background-image: 
-  		linear-gradient(rgba(255, 255, 255, .2) 2px, transparent 2px), 
+  	background-image:
+  		linear-gradient(rgba(255, 255, 255, .2) 2px, transparent 2px),
   		linear-gradient(90deg, rgba(255, 255, 255, .2) 2px, transparent 2px);
   	background-size: 100px 100px;
 }
@@ -58,8 +58,8 @@ body {
 	position: absolute;
 	width: 100px;
 	height: 100px;
-	/*background-image: 
-  		linear-gradient(rgba(255, 255, 255, .2) 2px, transparent 2px), 
+	/*background-image:
+  		linear-gradient(rgba(255, 255, 255, .2) 2px, transparent 2px),
   		linear-gradient(90deg, rgba(255, 255, 255, .2) 2px, transparent 2px);
   	background-size: 100px 100px;*/
 	background: url("bg.png");
@@ -113,7 +113,7 @@ body {
 }
 
 .block {
-	width: 400px;
+	width: 500px;
 	overflow: hidden;
 	position: absolute;
 	padding: 0px;
@@ -141,7 +141,7 @@ body {
 }
 
 .inputs {
-	width: 77px;
+	width: 117px;
 	float: left;
 	margin-left: 2px;
 	font-size: 11px;
@@ -154,7 +154,7 @@ body {
 }
 
 .outputs {
-	width: 77px;
+	width: 117px;
 	float: right;
 	margin-right: 2px;
 	text-align: right;
@@ -164,11 +164,11 @@ body {
 }
 
 .output {
-	/* TODO OUTPUT */ 
+	/* TODO OUTPUT */
 }
 
 .state {
-	padding: 0 83px 0 83px;
+	padding: 0 123px 0 123px;
 	color: #eee;
 }
 
@@ -267,4 +267,4 @@ li:active{
 	padding: 10px;
 	width: 100%;
 	border: none;
-}
\ No newline at end of file
+}