diff --git a/helpers.js b/helpers.js
new file mode 100644
index 0000000000000000000000000000000000000000..ce5128a8bf42e4f2bac4ed1d1d730d9d00cb32eb
--- /dev/null
+++ b/helpers.js
@@ -0,0 +1,810 @@
+const pipe = (first, ...more) => more.reduce((acc,curr) => (...arguments) => curr(acc(...arguments)) , first);
+
+const offsetHelper = (distances, offset, width, height) => {
+    var w = width;
+    var h = height;
+    var offset = offset;
+    var input = distances;
+    var output = new Uint8ClampedArray(4 * h * w);
+    for (var row = 0; row < h; ++row) {
+    for (var col = 0; col < w; ++col) {
+        if (input[(h - 1 - row) * w + col] <= offset) {
+        output[(h - 1 - row) * w * 4 + col * 4 + 0] = 255;
+        output[(h - 1 - row) * w * 4 + col * 4 + 1] = 255;
+        output[(h - 1 - row) * w * 4 + col * 4 + 2] = 255;
+        output[(h - 1 - row) * w * 4 + col * 4 + 3] = 255;
+        } else {
+        output[(h - 1 - row) * w * 4 + col * 4 + 0] = 0;
+        output[(h - 1 - row) * w * 4 + col * 4 + 1] = 0;
+        output[(h - 1 - row) * w * 4 + col * 4 + 2] = 0;
+        output[(h - 1 - row) * w * 4 + col * 4 + 3] = 255;
+        }
+    }
+    }
+
+    const imgData = new ImageData(output, w, h);
+
+    return imgData;
+};
+
+const edgeDetectHelper = imageRGBA => {
+    var h = imageRGBA.height;
+    var w = imageRGBA.width;
+    var input = imageRGBA.data;
+    var output = new Uint8ClampedArray(h * w * 4);
+    var i00, i0m, i0p, im0, ip0, imm, imp, ipm, ipp, row, col;
+    //
+    // find edges - interior
+    //
+    for (row = 1; row < h - 1; ++row) {
+    for (col = 1; col < w - 1; ++col) {
+        i00 =
+        input[(h - 1 - row) * w * 4 + col * 4 + 0] +
+        input[(h - 1 - row) * w * 4 + col * 4 + 1] +
+        input[(h - 1 - row) * w * 4 + col * 4 + 2];
+        i0p =
+        input[(h - 1 - row) * w * 4 + (col + 1) * 4 + 0] +
+        input[(h - 1 - row) * w * 4 + (col + 1) * 4 + 1] +
+        input[(h - 1 - row) * w * 4 + (col + 1) * 4 + 2];
+        ip0 =
+        input[(h - 2 - row) * w * 4 + col * 4 + 0] +
+        input[(h - 2 - row) * w * 4 + col * 4 + 1] +
+        input[(h - 2 - row) * w * 4 + col * 4 + 2];
+        ipp =
+        input[(h - 2 - row) * w * 4 + (col + 1) * 4 + 0] +
+        input[(h - 2 - row) * w * 4 + (col + 1) * 4 + 1] +
+        input[(h - 2 - row) * w * 4 + (col + 1) * 4 + 2];
+        i0m =
+        input[(h - 1 - row) * w * 4 + (col - 1) * 4 + 0] +
+        input[(h - 1 - row) * w * 4 + (col - 1) * 4 + 1] +
+        input[(h - 1 - row) * w * 4 + (col - 1) * 4 + 2];
+        im0 =
+        input[(h - row) * w * 4 + col * 4 + 0] +
+        input[(h - row) * w * 4 + col * 4 + 1] +
+        input[(h - row) * w * 4 + col * 4 + 2];
+        imm =
+        input[(h - row) * w * 4 + (col - 1) * 4 + 0] +
+        input[(h - row) * w * 4 + (col - 1) * 4 + 1] +
+        input[(h - row) * w * 4 + (col - 1) * 4 + 2];
+        imp =
+        input[(h - row) * w * 4 + (col + 1) * 4 + 0] +
+        input[(h - row) * w * 4 + (col + 1) * 4 + 1] +
+        input[(h - row) * w * 4 + (col + 1) * 4 + 2];
+        ipm =
+        input[(h - 2 - row) * w * 4 + (col - 1) * 4 + 0] +
+        input[(h - 2 - row) * w * 4 + (col - 1) * 4 + 1] +
+        input[(h - 2 - row) * w * 4 + (col - 1) * 4 + 2];
+        if (
+        i00 != i0p ||
+        i00 != ip0 ||
+        i00 != ipp ||
+        i00 != i0m ||
+        i00 != im0 ||
+        i00 != imm ||
+        i00 != imp ||
+        i00 != ipm
+        ) {
+        output[(h - 1 - row) * w * 4 + col * 4 + 0] = 255;
+        output[(h - 1 - row) * w * 4 + col * 4 + 1] = 0;
+        output[(h - 1 - row) * w * 4 + col * 4 + 2] = 0;
+        output[(h - 1 - row) * w * 4 + col * 4 + 3] = 255;
+        } else if (i00 == 0) {
+        output[(h - 1 - row) * w * 4 + col * 4 + 0] = 0;
+        output[(h - 1 - row) * w * 4 + col * 4 + 1] = 0;
+        output[(h - 1 - row) * w * 4 + col * 4 + 2] = 255;
+        output[(h - 1 - row) * w * 4 + col * 4 + 3] = 255;
+        } else {
+        output[(h - 1 - row) * w * 4 + col * 4 + 0] = 0;
+        output[(h - 1 - row) * w * 4 + col * 4 + 1] = 255;
+        output[(h - 1 - row) * w * 4 + col * 4 + 2] = 0;
+        output[(h - 1 - row) * w * 4 + col * 4 + 3] = 255;
+        }
+    }
+    }
+    //
+    // left and right edges
+    //
+    for (row = 1; row < h - 1; ++row) {
+    col = w - 1;
+    i00 =
+        input[(h - 1 - row) * w * 4 + col * 4 + 0] +
+        input[(h - 1 - row) * w * 4 + col * 4 + 1] +
+        input[(h - 1 - row) * w * 4 + col * 4 + 2];
+    i0m =
+        input[(h - 1 - row) * w * 4 + (col - 1) * 4 + 0] +
+        input[(h - 1 - row) * w * 4 + (col - 1) * 4 + 1] +
+        input[(h - 1 - row) * w * 4 + (col - 1) * 4 + 2];
+    imm =
+        input[(h - row) * w * 4 + (col - 1) * 4 + 0] +
+        input[(h - row) * w * 4 + (col - 1) * 4 + 1] +
+        input[(h - row) * w * 4 + (col - 1) * 4 + 2];
+    ipm =
+        input[(h - 2 - row) * w * 4 + (col - 1) * 4 + 0] +
+        input[(h - 2 - row) * w * 4 + (col - 1) * 4 + 1] +
+        input[(h - 2 - row) * w * 4 + (col - 1) * 4 + 2];
+    im0 =
+        input[(h - row) * w * 4 + col * 4 + 0] +
+        input[(h - row) * w * 4 + col * 4 + 1] +
+        input[(h - row) * w * 4 + col * 4 + 2];
+    ip0 =
+        input[(h - 2 - row) * w * 4 + col * 4 + 0] +
+        input[(h - 2 - row) * w * 4 + col * 4 + 1] +
+        input[(h - 2 - row) * w * 4 + col * 4 + 2];
+    if (i00 != i0m || i00 != ip0 || i00 != ipm || i00 != im0 || i00 != imm) {
+        output[(h - 1 - row) * w * 4 + col * 4 + 0] = 255;
+        output[(h - 1 - row) * w * 4 + col * 4 + 1] = 0;
+        output[(h - 1 - row) * w * 4 + col * 4 + 2] = 0;
+        output[(h - 1 - row) * w * 4 + col * 4 + 3] = 255;
+    } else if (i00 == 0) {
+        output[(h - 1 - row) * w * 4 + col * 4 + 0] = 0;
+        output[(h - 1 - row) * w * 4 + col * 4 + 1] = 0;
+        output[(h - 1 - row) * w * 4 + col * 4 + 2] = 255;
+        output[(h - 1 - row) * w * 4 + col * 4 + 3] = 255;
+    } else {
+        output[(h - 1 - row) * w * 4 + col * 4 + 0] = 0;
+        output[(h - 1 - row) * w * 4 + col * 4 + 1] = 255;
+        output[(h - 1 - row) * w * 4 + col * 4 + 2] = 0;
+        output[(h - 1 - row) * w * 4 + col * 4 + 3] = 255;
+    }
+    col = 0;
+    i00 =
+        input[(h - 1 - row) * w * 4 + col * 4 + 0] +
+        input[(h - 1 - row) * w * 4 + col * 4 + 1] +
+        input[(h - 1 - row) * w * 4 + col * 4 + 2];
+    i0p =
+        input[(h - 1 - row) * w * 4 + (col + 1) * 4 + 0] +
+        input[(h - 1 - row) * w * 4 + (col + 1) * 4 + 1] +
+        input[(h - 1 - row) * w * 4 + (col + 1) * 4 + 2];
+    imp =
+        input[(h - row) * w * 4 + (col + 1) * 4 + 0] +
+        input[(h - row) * w * 4 + (col + 1) * 4 + 1] +
+        input[(h - row) * w * 4 + (col + 1) * 4 + 2];
+    ipp =
+        input[(h - 2 - row) * w * 4 + (col + 1) * 4 + 0] +
+        input[(h - 2 - row) * w * 4 + (col + 1) * 4 + 1] +
+        input[(h - 2 - row) * w * 4 + (col + 1) * 4 + 2];
+    im0 =
+        input[(h - row) * w * 4 + col * 4 + 0] +
+        input[(h - row) * w * 4 + col * 4 + 1] +
+        input[(h - row) * w * 4 + col * 4 + 2];
+    ip0 =
+        input[(h - 2 - row) * w * 4 + col * 4 + 0] +
+        input[(h - 2 - row) * w * 4 + col * 4 + 1] +
+        input[(h - 2 - row) * w * 4 + col * 4 + 2];
+    if (i00 != i0p || i00 != ip0 || i00 != ipp || i00 != im0 || i00 != imp) {
+        output[(h - 1 - row) * w * 4 + col * 4 + 0] = 255;
+        output[(h - 1 - row) * w * 4 + col * 4 + 1] = 0;
+        output[(h - 1 - row) * w * 4 + col * 4 + 2] = 0;
+        output[(h - 1 - row) * w * 4 + col * 4 + 3] = 255;
+    } else if (i00 == 0) {
+        output[(h - 1 - row) * w * 4 + col * 4 + 0] = 0;
+        output[(h - 1 - row) * w * 4 + col * 4 + 1] = 0;
+        output[(h - 1 - row) * w * 4 + col * 4 + 2] = 255;
+        output[(h - 1 - row) * w * 4 + col * 4 + 3] = 255;
+    } else {
+        output[(h - 1 - row) * w * 4 + col * 4 + 0] = 0;
+        output[(h - 1 - row) * w * 4 + col * 4 + 1] = 255;
+        output[(h - 1 - row) * w * 4 + col * 4 + 2] = 0;
+        output[(h - 1 - row) * w * 4 + col * 4 + 3] = 255;
+    }
+    }
+    //
+    // top and bottom edges
+    //
+    for (col = 1; col < w - 1; ++col) {
+    row = h - 1;
+    i00 =
+        input[(h - 1 - row) * w * 4 + col * 4 + 0] +
+        input[(h - 1 - row) * w * 4 + col * 4 + 1] +
+        input[(h - 1 - row) * w * 4 + col * 4 + 2];
+    i0m =
+        input[(h - 1 - row) * w * 4 + (col - 1) * 4 + 0] +
+        input[(h - 1 - row) * w * 4 + (col - 1) * 4 + 1] +
+        input[(h - 1 - row) * w * 4 + (col - 1) * 4 + 2];
+    i0p =
+        input[(h - 1 - row) * w * 4 + (col + 1) * 4 + 0] +
+        input[(h - 1 - row) * w * 4 + (col + 1) * 4 + 1] +
+        input[(h - 1 - row) * w * 4 + (col + 1) * 4 + 2];
+    imm =
+        input[(h - row) * w * 4 + (col - 1) * 4 + 0] +
+        input[(h - row) * w * 4 + (col - 1) * 4 + 1] +
+        input[(h - row) * w * 4 + (col - 1) * 4 + 2];
+    im0 =
+        input[(h - row) * w * 4 + col * 4 + 0] +
+        input[(h - row) * w * 4 + col * 4 + 1] +
+        input[(h - row) * w * 4 + col * 4 + 2];
+    imp =
+        input[(h - row) * w * 4 + (col + 1) * 4 + 0] +
+        input[(h - row) * w * 4 + (col + 1) * 4 + 1] +
+        input[(h - row) * w * 4 + (col + 1) * 4 + 2];
+    if (i00 != i0m || i00 != i0p || i00 != imm || i00 != im0 || i00 != imp) {
+        output[(h - 1 - row) * w * 4 + col * 4 + 0] = 255;
+        output[(h - 1 - row) * w * 4 + col * 4 + 1] = 0;
+        output[(h - 1 - row) * w * 4 + col * 4 + 2] = 0;
+        output[(h - 1 - row) * w * 4 + col * 4 + 3] = 255;
+    } else if (i00 == 0) {
+        output[(h - 1 - row) * w * 4 + col * 4 + 0] = 0;
+        output[(h - 1 - row) * w * 4 + col * 4 + 1] = 0;
+        output[(h - 1 - row) * w * 4 + col * 4 + 2] = 255;
+        output[(h - 1 - row) * w * 4 + col * 4 + 3] = 255;
+    } else {
+        output[(h - 1 - row) * w * 4 + col * 4 + 0] = 0;
+        output[(h - 1 - row) * w * 4 + col * 4 + 1] = 255;
+        output[(h - 1 - row) * w * 4 + col * 4 + 2] = 0;
+        output[(h - 1 - row) * w * 4 + col * 4 + 3] = 255;
+    }
+    row = 0;
+    i00 =
+        input[(h - 1 - row) * w * 4 + col * 4 + 0] +
+        input[(h - 1 - row) * w * 4 + col * 4 + 1] +
+        input[(h - 1 - row) * w * 4 + col * 4 + 2];
+    i0m =
+        input[(h - 1 - row) * w * 4 + (col - 1) * 4 + 0] +
+        input[(h - 1 - row) * w * 4 + (col - 1) * 4 + 1] +
+        input[(h - 1 - row) * w * 4 + (col - 1) * 4 + 2];
+    i0p =
+        input[(h - 1 - row) * w * 4 + (col + 1) * 4 + 0] +
+        input[(h - 1 - row) * w * 4 + (col + 1) * 4 + 1] +
+        input[(h - 1 - row) * w * 4 + (col + 1) * 4 + 2];
+    ipm =
+        input[(h - 2 - row) * w * 4 + (col - 1) * 4 + 0] +
+        input[(h - 2 - row) * w * 4 + (col - 1) * 4 + 1] +
+        input[(h - 2 - row) * w * 4 + (col - 1) * 4 + 2];
+    ip0 =
+        input[(h - 2 - row) * w * 4 + col * 4 + 0] +
+        input[(h - 2 - row) * w * 4 + col * 4 + 1] +
+        input[(h - 2 - row) * w * 4 + col * 4 + 2];
+    ipp =
+        input[(h - 2 - row) * w * 4 + (col + 1) * 4 + 0] +
+        input[(h - 2 - row) * w * 4 + (col + 1) * 4 + 1] +
+        input[(h - 2 - row) * w * 4 + (col + 1) * 4 + 2];
+    if (i00 != i0m || i00 != i0p || i00 != ipm || i00 != ip0 || i00 != ipp) {
+        output[(h - 1 - row) * w * 4 + col * 4 + 0] = 255;
+        output[(h - 1 - row) * w * 4 + col * 4 + 1] = 0;
+        output[(h - 1 - row) * w * 4 + col * 4 + 2] = 0;
+        output[(h - 1 - row) * w * 4 + col * 4 + 3] = 255;
+    } else if (i00 == 0) {
+        output[(h - 1 - row) * w * 4 + col * 4 + 0] = 0;
+        output[(h - 1 - row) * w * 4 + col * 4 + 1] = 0;
+        output[(h - 1 - row) * w * 4 + col * 4 + 2] = 255;
+        output[(h - 1 - row) * w * 4 + col * 4 + 3] = 255;
+    } else {
+        output[(h - 1 - row) * w * 4 + col * 4 + 0] = 0;
+        output[(h - 1 - row) * w * 4 + col * 4 + 1] = 255;
+        output[(h - 1 - row) * w * 4 + col * 4 + 2] = 0;
+        output[(h - 1 - row) * w * 4 + col * 4 + 3] = 255;
+    }
+    }
+    //
+    // corners
+    //
+    row = 0;
+    col = 0;
+    i00 =
+    input[(h - 1 - row) * w * 4 + col * 4 + 0] +
+    input[(h - 1 - row) * w * 4 + col * 4 + 1] +
+    input[(h - 1 - row) * w * 4 + col * 4 + 2];
+    i0p =
+    input[(h - 1 - row) * w * 4 + (col + 1) * 4 + 0] +
+    input[(h - 1 - row) * w * 4 + (col + 1) * 4 + 1] +
+    input[(h - 1 - row) * w * 4 + (col + 1) * 4 + 2];
+    ip0 =
+    input[(h - 2 - row) * w * 4 + col * 4 + 0] +
+    input[(h - 2 - row) * w * 4 + col * 4 + 1] +
+    input[(h - 2 - row) * w * 4 + col * 4 + 2];
+    ipp =
+    input[(h - 2 - row) * w * 4 + (col + 1) * 4 + 0] +
+    input[(h - 2 - row) * w * 4 + (col + 1) * 4 + 1] +
+    input[(h - 2 - row) * w * 4 + (col + 1) * 4 + 2];
+    if (i00 != i0p || i00 != ip0 || i00 != ipp) {
+    output[(h - 1 - row) * w * 4 + col * 4 + 0] = 255;
+    output[(h - 1 - row) * w * 4 + col * 4 + 1] = 0;
+    output[(h - 1 - row) * w * 4 + col * 4 + 2] = 0;
+    output[(h - 1 - row) * w * 4 + col * 4 + 3] = 255;
+    } else if (i00 == 0) {
+    output[(h - 1 - row) * w * 4 + col * 4 + 0] = 0;
+    output[(h - 1 - row) * w * 4 + col * 4 + 1] = 0;
+    output[(h - 1 - row) * w * 4 + col * 4 + 2] = 255;
+    output[(h - 1 - row) * w * 4 + col * 4 + 3] = 255;
+    } else {
+    output[(h - 1 - row) * w * 4 + col * 4 + 0] = 0;
+    output[(h - 1 - row) * w * 4 + col * 4 + 1] = 255;
+    output[(h - 1 - row) * w * 4 + col * 4 + 2] = 0;
+    output[(h - 1 - row) * w * 4 + col * 4 + 3] = 255;
+    }
+    row = 0;
+    col = w - 1;
+    i00 =
+    input[(h - 1 - row) * w * 4 + col * 4 + 0] +
+    input[(h - 1 - row) * w * 4 + col * 4 + 1] +
+    input[(h - 1 - row) * w * 4 + col * 4 + 2];
+    i0m =
+    input[(h - 1 - row) * w * 4 + (col - 1) * 4 + 0] +
+    input[(h - 1 - row) * w * 4 + (col - 1) * 4 + 1] +
+    input[(h - 1 - row) * w * 4 + (col - 1) * 4 + 2];
+    ip0 =
+    input[(h - 2 - row) * w * 4 + col * 4 + 0] +
+    input[(h - 2 - row) * w * 4 + col * 4 + 1] +
+    input[(h - 2 - row) * w * 4 + col * 4 + 2];
+    ipm =
+    input[(h - 2 - row) * w * 4 + (col - 1) * 4 + 0] +
+    input[(h - 2 - row) * w * 4 + (col - 1) * 4 + 1] +
+    input[(h - 2 - row) * w * 4 + (col - 1) * 4 + 2];
+    if (i00 != i0m || i00 != ip0 || i00 != ipm) {
+    output[(h - 1 - row) * w * 4 + col * 4 + 0] = 255;
+    output[(h - 1 - row) * w * 4 + col * 4 + 1] = 0;
+    output[(h - 1 - row) * w * 4 + col * 4 + 2] = 0;
+    output[(h - 1 - row) * w * 4 + col * 4 + 3] = 255;
+    } else if (i00 == 0) {
+    output[(h - 1 - row) * w * 4 + col * 4 + 0] = 0;
+    output[(h - 1 - row) * w * 4 + col * 4 + 1] = 0;
+    output[(h - 1 - row) * w * 4 + col * 4 + 2] = 255;
+    output[(h - 1 - row) * w * 4 + col * 4 + 3] = 255;
+    } else {
+    output[(h - 1 - row) * w * 4 + col * 4 + 0] = 0;
+    output[(h - 1 - row) * w * 4 + col * 4 + 1] = 255;
+    output[(h - 1 - row) * w * 4 + col * 4 + 2] = 0;
+    output[(h - 1 - row) * w * 4 + col * 4 + 3] = 255;
+    }
+    row = h - 1;
+    col = 0;
+    i00 =
+    input[(h - 1 - row) * w * 4 + col * 4 + 0] +
+    input[(h - 1 - row) * w * 4 + col * 4 + 1] +
+    input[(h - 1 - row) * w * 4 + col * 4 + 2];
+    i0p =
+    input[(h - 1 - row) * w * 4 + (col + 1) * 4 + 0] +
+    input[(h - 1 - row) * w * 4 + (col + 1) * 4 + 1] +
+    input[(h - 1 - row) * w * 4 + (col + 1) * 4 + 2];
+    im0 =
+    input[(h - row) * w * 4 + col * 4 + 0] +
+    input[(h - row) * w * 4 + col * 4 + 1] +
+    input[(h - row) * w * 4 + col * 4 + 2];
+    imp =
+    input[(h - row) * w * 4 + (col + 1) * 4 + 0] +
+    input[(h - row) * w * 4 + (col + 1) * 4 + 1] +
+    input[(h - row) * w * 4 + (col + 1) * 4 + 2];
+    if (i00 != i0p || i00 != im0 || i00 != imp) {
+    output[(h - 1 - row) * w * 4 + col * 4 + 0] = 255;
+    output[(h - 1 - row) * w * 4 + col * 4 + 1] = 0;
+    output[(h - 1 - row) * w * 4 + col * 4 + 2] = 0;
+    output[(h - 1 - row) * w * 4 + col * 4 + 3] = 255;
+    } else if (i00 == 0) {
+    output[(h - 1 - row) * w * 4 + col * 4 + 0] = 0;
+    output[(h - 1 - row) * w * 4 + col * 4 + 1] = 0;
+    output[(h - 1 - row) * w * 4 + col * 4 + 2] = 255;
+    output[(h - 1 - row) * w * 4 + col * 4 + 3] = 255;
+    } else {
+    output[(h - 1 - row) * w * 4 + col * 4 + 0] = 0;
+    output[(h - 1 - row) * w * 4 + col * 4 + 1] = 255;
+    output[(h - 1 - row) * w * 4 + col * 4 + 2] = 0;
+    output[(h - 1 - row) * w * 4 + col * 4 + 3] = 255;
+    }
+    row = h - 1;
+    col = w - 1;
+    i00 =
+    input[(h - 1 - row) * w * 4 + col * 4 + 0] +
+    input[(h - 1 - row) * w * 4 + col * 4 + 1] +
+    input[(h - 1 - row) * w * 4 + col * 4 + 2];
+    i0m =
+    input[(h - 1 - row) * w * 4 + (col - 1) * 4 + 0] +
+    input[(h - 1 - row) * w * 4 + (col - 1) * 4 + 1] +
+    input[(h - 1 - row) * w * 4 + (col - 1) * 4 + 2];
+    im0 =
+    input[(h - row) * w * 4 + col * 4 + 0] +
+    input[(h - row) * w * 4 + col * 4 + 1] +
+    input[(h - row) * w * 4 + col * 4 + 2];
+    imm =
+    input[(h - row) * w * 4 + (col - 1) * 4 + 0] +
+    input[(h - row) * w * 4 + (col - 1) * 4 + 1] +
+    input[(h - row) * w * 4 + (col - 1) * 4 + 2];
+    if (i00 != i0m || i00 != im0 || i00 != imm) {
+    output[(h - 1 - row) * w * 4 + col * 4 + 0] = 255;
+    output[(h - 1 - row) * w * 4 + col * 4 + 1] = 0;
+    output[(h - 1 - row) * w * 4 + col * 4 + 2] = 0;
+    output[(h - 1 - row) * w * 4 + col * 4 + 3] = 255;
+    } else if (i00 == 0) {
+    output[(h - 1 - row) * w * 4 + col * 4 + 0] = 0;
+    output[(h - 1 - row) * w * 4 + col * 4 + 1] = 0;
+    output[(h - 1 - row) * w * 4 + col * 4 + 2] = 255;
+    output[(h - 1 - row) * w * 4 + col * 4 + 3] = 255;
+    } else {
+    output[(h - 1 - row) * w * 4 + col * 4 + 0] = 0;
+    output[(h - 1 - row) * w * 4 + col * 4 + 1] = 255;
+    output[(h - 1 - row) * w * 4 + col * 4 + 2] = 0;
+    output[(h - 1 - row) * w * 4 + col * 4 + 3] = 255;
+    }
+
+    const imgData = new ImageData(output, w, h);
+
+    return imgData;
+};
+
+const orientEdgesHelper = imageRGBA => {
+    var h = imageRGBA.height;
+    var w = imageRGBA.width;
+    var input = imageRGBA.data;
+    var output = new Uint8ClampedArray(h * w * 4);
+    var row, col;
+    var boundary = 0;
+    var interior = 1;
+    var exterior = 2;
+    var alpha = 3;
+    var northsouth = 0;
+    var north = 128;
+    var south = 64;
+    var eastwest = 1;
+    var east = 128;
+    var west = 64;
+    var startstop = 2;
+    var start = 128;
+    var stop = 64;
+    //
+    // orient body states
+    //
+    for (row = 1; row < h - 1; ++row) {
+    for (col = 1; col < w - 1; ++col) {
+        output[(h - 1 - row) * w * 4 + col * 4 + northsouth] = 0;
+        output[(h - 1 - row) * w * 4 + col * 4 + eastwest] = 0;
+        output[(h - 1 - row) * w * 4 + col * 4 + startstop] = 0;
+        output[(h - 1 - row) * w * 4 + col * 4 + alpha] = 255;
+        if (input[(h - 1 - row) * w * 4 + col * 4 + boundary] != 0) {
+        if (
+            input[(h - 1 - (row + 1)) * w * 4 + col * 4 + boundary] != 0 &&
+            (input[(h - 1 - row) * w * 4 + (col + 1) * 4 + interior] != 0 ||
+            input[(h - 1 - (row + 1)) * w * 4 + (col + 1) * 4 + interior] !=
+                0)
+        )
+            output[(h - 1 - row) * w * 4 + col * 4 + northsouth] |= north;
+        if (
+            input[(h - 1 - (row - 1)) * w * 4 + col * 4 + boundary] != 0 &&
+            (input[(h - 1 - row) * w * 4 + (col - 1) * 4 + interior] != 0 ||
+            input[(h - 1 - (row - 1)) * w * 4 + (col - 1) * 4 + interior] !=
+                0)
+        )
+            output[(h - 1 - row) * w * 4 + col * 4 + northsouth] |= south;
+        if (
+            input[(h - 1 - row) * w * 4 + (col + 1) * 4 + boundary] != 0 &&
+            (input[(h - 1 - (row - 1)) * w * 4 + col * 4 + interior] != 0 ||
+            input[(h - 1 - (row - 1)) * w * 4 + (col + 1) * 4 + interior] !=
+                0)
+        )
+            output[(h - 1 - row) * w * 4 + col * 4 + eastwest] |= east;
+        if (
+            input[(h - 1 - row) * w * 4 + (col - 1) * 4 + boundary] != 0 &&
+            (input[(h - 1 - (row + 1)) * w * 4 + col * 4 + interior] != 0 ||
+            input[(h - 1 - (row + 1)) * w * 4 + (col - 1) * 4 + interior] !=
+                0)
+        )
+            output[(h - 1 - row) * w * 4 + col * 4 + eastwest] |= west;
+        }
+    }
+    }
+    //
+    // orient edge states
+    //
+    for (col = 1; col < w - 1; ++col) {
+    row = 0;
+    output[(h - 1 - row) * w * 4 + col * 4 + northsouth] = 0;
+    output[(h - 1 - row) * w * 4 + col * 4 + eastwest] = 0;
+    output[(h - 1 - row) * w * 4 + col * 4 + startstop] = 0;
+    output[(h - 1 - row) * w * 4 + col * 4 + alpha] = 255;
+    if (input[(h - 1 - row) * w * 4 + col * 4 + boundary] != 0) {
+        if (
+        input[(h - 1 - (row + 1)) * w * 4 + col * 4 + boundary] != 0 &&
+        input[(h - 1 - row) * w * 4 + (col + 1) * 4 + interior] != 0
+        ) {
+        output[(h - 1 - row) * w * 4 + col * 4 + northsouth] |= north;
+        output[(h - 1 - row) * w * 4 + col * 4 + startstop] |= start;
+        }
+        if (input[(h - 1 - row) * w * 4 + (col - 1) * 4 + interior] != 0)
+        output[(h - 1 - row) * w * 4 + col * 4 + startstop] |= stop;
+    }
+    row = h - 1;
+    output[(h - 1 - row) * w * 4 + col * 4 + northsouth] = 0;
+    output[(h - 1 - row) * w * 4 + col * 4 + eastwest] = 0;
+    output[(h - 1 - row) * w * 4 + col * 4 + startstop] = 0;
+    output[(h - 1 - row) * w * 4 + col * 4 + alpha] = 255;
+    if (input[(h - 1 - row) * w * 4 + col * 4 + boundary] != 0) {
+        if (input[(h - 1 - row) * w * 4 + (col + 1) * 4 + interior] != 0)
+        output[(h - 1 - row) * w * 4 + col * 4 + startstop] |= stop;
+        if (
+        input[(h - 1 - (row - 1)) * w * 4 + col * 4 + boundary] != 0 &&
+        input[(h - 1 - row) * w * 4 + (col - 1) * 4 + interior] != 0
+        ) {
+        output[(h - 1 - row) * w * 4 + col * 4 + northsouth] |= south;
+        output[(h - 1 - row) * w * 4 + col * 4 + startstop] |= start;
+        }
+    }
+    }
+    for (row = 1; row < h - 1; ++row) {
+    col = 0;
+    output[(h - 1 - row) * w * 4 + col * 4 + northsouth] = 0;
+    output[(h - 1 - row) * w * 4 + col * 4 + eastwest] = 0;
+    output[(h - 1 - row) * w * 4 + col * 4 + startstop] = 0;
+    output[(h - 1 - row) * w * 4 + col * 4 + alpha] = 255;
+    if (input[(h - 1 - row) * w * 4 + col * 4 + boundary] != 0) {
+        if (
+        input[(h - 1 - row) * w * 4 + (col + 1) * 4 + boundary] != 0 &&
+        input[(h - 1 - (row - 1)) * w * 4 + col * 4 + interior] != 0
+        ) {
+        output[(h - 1 - row) * w * 4 + col * 4 + eastwest] |= east;
+        output[(h - 1 - row) * w * 4 + col * 4 + startstop] |= start;
+        }
+        if (input[(h - 1 - (row + 1)) * w * 4 + col * 4 + interior] != 0)
+        output[(h - 1 - row) * w * 4 + col * 4 + startstop] |= stop;
+    }
+    col = w - 1;
+    output[(h - 1 - row) * w * 4 + col * 4 + northsouth] = 0;
+    output[(h - 1 - row) * w * 4 + col * 4 + eastwest] = 0;
+    output[(h - 1 - row) * w * 4 + col * 4 + startstop] = 0;
+    output[(h - 1 - row) * w * 4 + col * 4 + alpha] = 255;
+    if (input[(h - 1 - row) * w * 4 + col * 4 + boundary] != 0) {
+        if (input[(h - 1 - (row - 1)) * w * 4 + col * 4 + interior] != 0)
+        output[(h - 1 - row) * w * 4 + col * 4 + startstop] |= stop;
+        if (
+        input[(h - 1 - row) * w * 4 + (col - 1) * 4 + boundary] != 0 &&
+        input[(h - 1 - (row + 1)) * w * 4 + col * 4 + interior] != 0
+        ) {
+        output[(h - 1 - row) * w * 4 + col * 4 + eastwest] |= west;
+        output[(h - 1 - row) * w * 4 + col * 4 + startstop] |= start;
+        }
+    }
+    }
+    //
+    // orient corner states (todo)
+    //
+    row = 0;
+    col = 0;
+    output[(h - 1 - row) * w * 4 + col * 4 + northsouth] = 0;
+    output[(h - 1 - row) * w * 4 + col * 4 + eastwest] = 0;
+    output[(h - 1 - row) * w * 4 + col * 4 + startstop] = 0;
+    output[(h - 1 - row) * w * 4 + col * 4 + alpha] = 255;
+    row = h - 1;
+    col = 0;
+    output[(h - 1 - row) * w * 4 + col * 4 + northsouth] = 0;
+    output[(h - 1 - row) * w * 4 + col * 4 + eastwest] = 0;
+    output[(h - 1 - row) * w * 4 + col * 4 + startstop] = 0;
+    output[(h - 1 - row) * w * 4 + col * 4 + alpha] = 255;
+    row = 0;
+    col = w - 1;
+    output[(h - 1 - row) * w * 4 + col * 4 + northsouth] = 0;
+    output[(h - 1 - row) * w * 4 + col * 4 + eastwest] = 0;
+    output[(h - 1 - row) * w * 4 + col * 4 + startstop] = 0;
+    output[(h - 1 - row) * w * 4 + col * 4 + alpha] = 255;
+    row = h - 1;
+    col = w - 1;
+    output[(h - 1 - row) * w * 4 + col * 4 + northsouth] = 0;
+    output[(h - 1 - row) * w * 4 + col * 4 + eastwest] = 0;
+    output[(h - 1 - row) * w * 4 + col * 4 + startstop] = 0;
+    output[(h - 1 - row) * w * 4 + col * 4 + alpha] = 255;
+
+    // var display = new Uint8ClampedArray(h*w*4)
+    // var r,g,b,i
+    // for (row = 0; row < h; ++row) {
+    //   for (col = 0; col < w; ++col) {
+    //     r = output[(h-1-row)*w*4+col*4+0]
+    //     g = output[(h-1-row)*w*4+col*4+1]
+    //     b = output[(h-1-row)*w*4+col*4+2]
+    //     i = r+g+b
+    //     if (i != 0) {
+    //        display[(h-1-row)*w*4+col*4+0] = output[(h-1-row)*w*4+col*4+0]
+    //        display[(h-1-row)*w*4+col*4+1] = output[(h-1-row)*w*4+col*4+1]
+    //        display[(h-1-row)*w*4+col*4+2] = output[(h-1-row)*w*4+col*4+2]
+    //        display[(h-1-row)*w*4+col*4+3] = output[(h-1-row)*w*4+col*4+3]
+    //        }
+    //     else {
+    //        display[(h-1-row)*w*4+col*4+0] = 255
+    //        display[(h-1-row)*w*4+col*4+1] = 255
+    //        display[(h-1-row)*w*4+col*4+2] = 255
+    //        display[(h-1-row)*w*4+col*4+3] = 255
+    //        }
+    //     }
+    //  }
+
+    const imgData = new ImageData(output, w, h);
+
+    return imgData;
+};
+
+const vectorizeHelper = (imageRGBA, vectorFit = 1, sort = true) => {
+    var h = imageRGBA.height;
+    var w = imageRGBA.width;
+    var input = imageRGBA.data;
+    var northsouth = 0;
+    var north = 128;
+    var south = 64;
+    var eastwest = 1;
+    var east = 128;
+    var west = 64;
+    var startstop = 2;
+    var start = 128;
+    var stop = 64;
+    var path = [];
+    //
+    // edge follower
+    //
+    function follow_edges(row, col) {
+    if (
+        input[(h - 1 - row) * w * 4 + col * 4 + northsouth] != 0 ||
+        input[(h - 1 - row) * w * 4 + col * 4 + eastwest] != 0
+    ) {
+        path[path.length] = [[col, row]];
+        while (1) {
+        if (
+            input[(h - 1 - row) * w * 4 + col * 4 + northsouth] & north
+        ) {
+            input[(h - 1 - row) * w * 4 + col * 4 + northsouth] =
+            input[(h - 1 - row) * w * 4 + col * 4 + northsouth] &
+            ~north;
+            row += 1;
+            path[path.length - 1][path[path.length - 1].length] = [
+            col,
+            row
+            ];
+        } else if (
+            input[(h - 1 - row) * w * 4 + col * 4 + northsouth] & south
+        ) {
+            input[(h - 1 - row) * w * 4 + col * 4 + northsouth] =
+            input[(h - 1 - row) * w * 4 + col * 4 + northsouth] &
+            ~south;
+            row -= 1;
+            path[path.length - 1][path[path.length - 1].length] = [
+            col,
+            row
+            ];
+        } else if (
+            input[(h - 1 - row) * w * 4 + col * 4 + eastwest] & east
+        ) {
+            input[(h - 1 - row) * w * 4 + col * 4 + eastwest] =
+            input[(h - 1 - row) * w * 4 + col * 4 + eastwest] & ~east;
+            col += 1;
+            path[path.length - 1][path[path.length - 1].length] = [
+            col,
+            row
+            ];
+        } else if (
+            input[(h - 1 - row) * w * 4 + col * 4 + eastwest] & west
+        ) {
+            input[(h - 1 - row) * w * 4 + col * 4 + eastwest] =
+            input[(h - 1 - row) * w * 4 + col * 4 + eastwest] & ~west;
+            col -= 1;
+            path[path.length - 1][path[path.length - 1].length] = [
+            col,
+            row
+            ];
+        } else break;
+        }
+    }
+    }
+    //
+    // follow boundary starts
+    //
+    for (var row = 1; row < h - 1; ++row) {
+    col = 0;
+    follow_edges(row, col);
+    col = w - 1;
+    follow_edges(row, col);
+    }
+    for (var col = 1; col < w - 1; ++col) {
+    row = 0;
+    follow_edges(row, col);
+    row = h - 1;
+    follow_edges(row, col);
+    }
+    //
+    // follow interior paths
+    //
+    for (var row = 1; row < h - 1; ++row) {
+    for (var col = 1; col < w - 1; ++col) {
+        follow_edges(row, col);
+    }
+    }
+    //
+    // vectorize path
+    //
+    var error = vectorFit;
+    var vecpath = [];
+    for (var seg = 0; seg < path.length; ++seg) {
+    var x0 = path[seg][0][0];
+    var y0 = path[seg][0][1];
+    vecpath[vecpath.length] = [[x0, y0]];
+    var xsum = x0;
+    var ysum = y0;
+    var sum = 1;
+    for (var pt = 1; pt < path[seg].length; ++pt) {
+        var xold = x;
+        var yold = y;
+        var x = path[seg][pt][0];
+        var y = path[seg][pt][1];
+        if (sum == 1) {
+        xsum += x;
+        ysum += y;
+        sum += 1;
+        } else {
+        var xmean = xsum / sum;
+        var ymean = ysum / sum;
+        var dx = xmean - x0;
+        var dy = ymean - y0;
+        var d = Math.sqrt(dx * dx + dy * dy);
+        var nx = dy / d;
+        var ny = -dx / d;
+        var l = Math.abs(nx * (x - x0) + ny * (y - y0));
+        if (l < error) {
+            xsum += x;
+            ysum += y;
+            sum += 1;
+        } else {
+            vecpath[vecpath.length - 1][
+            vecpath[vecpath.length - 1].length
+            ] = [xold, yold];
+            x0 = xold;
+            y0 = yold;
+            xsum = xold;
+            ysum = yold;
+            sum = 1;
+        }
+        }
+        if (pt == path[seg].length - 1) {
+        vecpath[vecpath.length - 1][
+            vecpath[vecpath.length - 1].length
+        ] = [x, y];
+        }
+    }
+    }
+    //
+    // sort path
+    //
+    if (vecpath.length > 1 && sort == true) {
+    var dmin = w * w + h * h;
+    var segmin = null;
+    for (var seg = 0; seg < vecpath.length; ++seg) {
+        var x = vecpath[seg][0][0];
+        var y = vecpath[seg][0][0];
+        var d = x * x + y * y;
+        if (d < dmin) {
+        dmin = d;
+        segmin = seg;
+        }
+    }
+    if (segmin != null) {
+        var sortpath = [vecpath[segmin]];
+        vecpath.splice(segmin, 1);
+    }
+    while (vecpath.length > 0) {
+        var dmin = w * w + h * h;
+        var x0 =
+        sortpath[sortpath.length - 1][
+            sortpath[sortpath.length - 1].length - 1
+        ][0];
+        var y0 =
+        sortpath[sortpath.length - 1][
+            sortpath[sortpath.length - 1].length - 1
+        ][1];
+        segmin = null;
+        for (var seg = 0; seg < vecpath.length; ++seg) {
+        var x = vecpath[seg][0][0];
+        var y = vecpath[seg][0][1];
+        var d = (x - x0) * (x - x0) + (y - y0) * (y - y0);
+        if (d < dmin) {
+            dmin = d;
+            segmin = seg;
+        }
+        }
+        if (segmin != null) {
+        sortpath[sortpath.length] = vecpath[segmin];
+        vecpath.splice(segmin, 1);
+        }
+    }
+    } else if (
+    (vecpath.length > 1 && sort == false) ||
+    vecpath.length == 1
+    )
+    sortpath = vecpath;
+    else sortpath = [];
+
+    return sortpath;
+};
+
+const test = () => console.log("import is working");
+
diff --git a/hunks/flowcontrol/while.js b/hunks/flowcontrol/while.js
new file mode 100644
index 0000000000000000000000000000000000000000..6315918a3570ba465a8d6a99dc1cb08c16e0fb19
--- /dev/null
+++ b/hunks/flowcontrol/while.js
@@ -0,0 +1,44 @@
+/*
+
+thou shall ? pass : not
+
+*/
+
+import {
+    Hunkify,
+    Input,
+    Output,
+    State
+  } from '../hunks.js'
+  
+  function While(){
+    Hunkify(this)
+  
+    // also wants to be polymorphic
+    let condition = new Input('boolean', 'thru', this)
+    this.inputs.push(condition)
+  
+    let evtOut = new Output('boolean', 'thru', this)
+    this.outputs.push(evtOut)
+  
+    let runState = new State('boolean', 'run', false)
+    this.states.push(runState)
+  
+    this.init = () => {
+      console.log('hello gate')
+    }
+  
+    this.loop = () => {
+      if(runStateIn.io()){
+        runState.set(runStateIn.get())
+      }
+      if(evtIn.io()){
+        if(runState.value && !evtOut.io()){
+          evtOut.put(evtIn.get())
+        }
+      }
+    }
+  }
+  
+  export default While
+  
\ No newline at end of file
diff --git a/hunks/image/multipleOffsets.js b/hunks/image/multipleOffsets.js
new file mode 100644
index 0000000000000000000000000000000000000000..b4429940b6137b8e3bb20fb4cd51b959a19e8324
--- /dev/null
+++ b/hunks/image/multipleOffsets.js
@@ -0,0 +1,114 @@
+/*
+
+hunk template
+
+*/
+
+// these are ES6 modules
+import { Hunkify, Input, Output, State } from "../hunks.js";
+import { TSET } from "../../typeset.js";
+
+/*
+  import {
+    html,
+    svg,
+    render
+  } from 'https://unpkg.com/lit-html?module';
+  */
+
+export default function MultipleOffsets() {
+  // this fn attaches handles to our function-object,
+  Hunkify(this);
+
+  // inputs
+  let imageIn = new Input("Float32Array", "image", this);
+  this.inputs.push(imageIn);
+
+  // states
+  let totalOffset = new State("number", "totalOffset", 0.5);
+  this.states.push(totalOffset);
+
+  let offsetDiameter = new State("number", "offsetDiameter", 0.5);
+  this.states.push(offsetDiameter);
+
+  let stepover = new State("number", "stepover", 0.5);
+  this.states.push(stepover);
+
+  let width = new State("number", "width", 190);
+  this.states.push(width);
+
+  let height = new State("number", "height", 266);
+  this.states.push(height);
+
+  // outputs
+  let vectors = new Output("array", "Vectors", this);
+  this.outputs.push(vectors);
+
+  // view
+  // this.dom = {}
+  this.init = () => {
+    //this.dom = $('<div>').get(0)
+  };
+
+  /*
+    this.onload = () => {}
+    */
+
+  this.loop = () => {
+    if (imageIn.io() && !vectors.io()) {
+      function work() {
+        self.importScripts("http://localhost:8080/helpers.js");
+
+        self.onmessage = function(e) {
+
+          let vectors = [];
+          let offset = e.data.offsetDiameter;
+
+          let newVectors;
+
+          while (offset <= e.data.totalOffset) {
+
+            newVectors = pipe(
+              x => offsetHelper(x.imageIn, offset, x.width, x.height),
+              edgeDetectHelper,
+              orientEdgesHelper,
+              vectorizeHelper
+            )(e.data);
+
+            vectors = [...vectors, ...newVectors];
+
+            if (offset === e.data.totalOffset) break;
+
+            offset += e.data.stepover;
+
+            if (offset > e.data.totalOffset) {
+              offset = e.data.totalOffset;
+            }
+
+          }
+
+          self.postMessage(vectors);
+        };
+      }
+
+      var blob = new Blob(["(" + work.toString() + "())"]);
+      var url = window.URL.createObjectURL(blob);
+      var worker = new Worker(url);
+
+      worker.onmessage = e => {
+        const message = e.data;
+        vectors.put(message);
+        worker.terminate();
+      };
+
+      worker.postMessage({
+        imageIn: imageIn.get(),
+        width: width.value,
+        height: height.value,
+        totalOffset: totalOffset.value,
+        offsetDiameter: offsetDiameter.value,
+        stepover: stepover.value,
+      });
+    }
+  };
+}
diff --git a/hunks/image/renderVectors.js b/hunks/image/renderVectors.js
index 2e2acfa27512b2143e12f6cad86dd33f229cbcdc..9860fca5932c3d8155a5fc298d9e5fa92c7a4069 100644
--- a/hunks/image/renderVectors.js
+++ b/hunks/image/renderVectors.js
@@ -60,7 +60,7 @@ export default function RenderVectors() {
     $(this.dom).append(target);
 
     const view = html`
-      <svg id="svg" width="300" height="300"></svg>
+      <svg id=${svgUid} width="300" height="300"></svg>
     `;
     render(view, target);
   };
@@ -69,7 +69,12 @@ export default function RenderVectors() {
   this.loop = () => {
     if (vectors.io()) {
       const newView = renderVectorsHelper(vectors.get());
-      const svgTarget = document.getElementById("svg");
+
+      let svgTarget = $(this.dom)
+        .find("svg")
+        .get(0);
+
+      // const svgTarget = document.getElementById(svgUid);
       render(newView, svgTarget);
     }
   };
diff --git a/save/contexts/cuttlefish/imageTest2.json b/save/contexts/cuttlefish/imageTest2.json
new file mode 100644
index 0000000000000000000000000000000000000000..75cc45cb73fe5cbe4470cff754938edd7ee468d2
--- /dev/null
+++ b/save/contexts/cuttlefish/imageTest2.json
@@ -0,0 +1,253 @@
+{
+  "interpreterName": "cuttlefish",
+  "interpreterVersion": "v0.1",
+  "hunks": [
+    {
+      "type": "manager",
+      "name": "nrol",
+      "inputs": [
+        {
+          "name": "msgs",
+          "type": "byteArray"
+        }
+      ],
+      "outputs": [
+        {
+          "name": "msgs",
+          "type": "byteArray",
+          "connections": [
+            {
+              "inHunkIndex": "1",
+              "inHunkInput": "0"
+            }
+          ]
+        }
+      ]
+    },
+    {
+      "type": "view",
+      "name": "tlview",
+      "inputs": [
+        {
+          "name": "msgs",
+          "type": "byteArray"
+        }
+      ],
+      "outputs": [
+        {
+          "name": "msgs",
+          "type": "byteArray",
+          "connections": [
+            {
+              "inHunkIndex": "0",
+              "inHunkInput": "0"
+            }
+          ]
+        }
+      ]
+    },
+    {
+      "type": "image/thresholdrgba",
+      "name": "image/thresholdrgba_3",
+      "inputs": [
+        {
+          "name": "image",
+          "type": "ImageData"
+        }
+      ],
+      "outputs": [
+        {
+          "name": "image",
+          "type": "ImageData",
+          "connections": [
+            {
+              "inHunkIndex": "5",
+              "inHunkInput": "0"
+            }
+          ]
+        }
+      ],
+      "states": [
+        {
+          "name": "threshold",
+          "type": "number",
+          "value": "0.5"
+        }
+      ]
+    },
+    {
+      "type": "image/readpng",
+      "name": "image/readpng_3",
+      "outputs": [
+        {
+          "name": "image",
+          "type": "ImageData",
+          "connections": [
+            {
+              "inHunkIndex": "2",
+              "inHunkInput": "0"
+            }
+          ]
+        }
+      ],
+      "states": [
+        {
+          "name": "release",
+          "type": "boolean",
+          "value": "false"
+        }
+      ]
+    },
+    {
+      "type": "image/displayimagedata",
+      "name": "image/displayimagedata_4",
+      "inputs": [
+        {
+          "name": "image",
+          "type": "ImageData"
+        }
+      ]
+    },
+    {
+      "type": "image/distanceTransform",
+      "name": "image/distanceTransform_6",
+      "inputs": [
+        {
+          "name": "image",
+          "type": "ImageData"
+        }
+      ],
+      "outputs": [
+        {
+          "name": "image",
+          "type": "Float32Array",
+          "connections": [
+            {
+              "inHunkIndex": "7",
+              "inHunkInput": "0"
+            }
+          ]
+        }
+      ]
+    },
+    {
+      "type": "image/edgeDetect",
+      "name": "image/edgeDetect_7",
+      "inputs": [
+        {
+          "name": "image",
+          "type": "ImageData"
+        }
+      ],
+      "outputs": [
+        {
+          "name": "image",
+          "type": "ImageData",
+          "connections": [
+            {
+              "inHunkIndex": "8",
+              "inHunkInput": "0"
+            }
+          ]
+        }
+      ]
+    },
+    {
+      "type": "image/offset",
+      "name": "image/offset_8",
+      "inputs": [
+        {
+          "name": "image",
+          "type": "Float32Array"
+        }
+      ],
+      "outputs": [
+        {
+          "name": "image",
+          "type": "ImageData",
+          "connections": [
+            {
+              "inHunkIndex": "6",
+              "inHunkInput": "0"
+            }
+          ]
+        }
+      ],
+      "states": [
+        {
+          "name": "offset",
+          "type": "number",
+          "value": "0.5"
+        },
+        {
+          "name": "width",
+          "type": "number",
+          "value": "190"
+        },
+        {
+          "name": "height",
+          "type": "number",
+          "value": "266"
+        }
+      ]
+    },
+    {
+      "type": "image/orientEdges",
+      "name": "image/orientEdges_9",
+      "inputs": [
+        {
+          "name": "image",
+          "type": "ImageData"
+        }
+      ],
+      "outputs": [
+        {
+          "name": "image",
+          "type": "ImageData",
+          "connections": [
+            {
+              "inHunkIndex": "10",
+              "inHunkInput": "0"
+            },
+            {
+              "inHunkIndex": "4",
+              "inHunkInput": "0"
+            }
+          ]
+        }
+      ]
+    },
+    {
+      "type": "image/renderVectors",
+      "name": "image/renderVectors_11",
+      "inputs": [
+        {
+          "name": "Vectors",
+          "type": "array"
+        }
+      ]
+    },
+    {
+      "type": "image/vectorize",
+      "name": "image/vectorize_11",
+      "inputs": [
+        {
+          "name": "image",
+          "type": "ImageData"
+        }
+      ],
+      "outputs": [
+        {
+          "name": "Vectors",
+          "type": "array",
+          "connections": [
+            {
+              "inHunkIndex": "9",
+              "inHunkInput": "0"
+            }
+          ]
+        }
+      ]
+    }
+  ]
+}
\ No newline at end of file