diff --git a/client/dat.gui.css b/client/dat.gui.css
deleted file mode 100644
index 6d63e3528a68acb4e8859675e5377af1e64b2af4..0000000000000000000000000000000000000000
--- a/client/dat.gui.css
+++ /dev/null
@@ -1,413 +0,0 @@
-.dg ul {
-    list-style: none;
-    margin: 0;
-    padding: 0;
-    width: 100%;
-    clear: both
-}
-
-.dg.ac {
-    position: fixed;
-    top: 0;
-    left: 0;
-    right: 0;
-    height: 0;
-    z-index: 0
-}
-
-.dg:not(.ac) .main {
-    overflow: hidden
-}
-
-.dg.main {
-    -webkit-transition: opacity .1s linear;
-    -o-transition: opacity .1s linear;
-    -moz-transition: opacity .1s linear;
-    transition: opacity .1s linear
-}
-
-.dg.main.taller-than-window {
-    overflow-y: auto
-}
-
-.dg.main.taller-than-window .close-button {
-    opacity: 1;
-    margin-top: -1px;
-    border-top: 1px solid #2c2c2c
-}
-
-.dg.main ul.closed .close-button {
-    opacity: 1 !important
-}
-
-.dg.main:hover .close-button,
-.dg.main .close-button.drag {
-    opacity: 1
-}
-
-.dg.main .close-button {
-    -webkit-transition: opacity .1s linear;
-    -o-transition: opacity .1s linear;
-    -moz-transition: opacity .1s linear;
-    transition: opacity .1s linear;
-    border: 0;
-    line-height: 19px;
-    height: 20px;
-    cursor: pointer;
-    text-align: center;
-    background-color: #000
-}
-
-.dg.main .close-button.close-top {
-    position: relative
-}
-
-.dg.main .close-button.close-bottom {
-    position: absolute
-}
-
-.dg.main .close-button:hover {
-    background-color: #111
-}
-
-.dg.a {
-    float: right;
-    margin-right: 15px;
-    overflow-y: visible
-}
-
-.dg.a.has-save>ul.close-top {
-    margin-top: 0
-}
-
-.dg.a.has-save>ul.close-bottom {
-    margin-top: 27px
-}
-
-.dg.a.has-save>ul.closed {
-    margin-top: 0
-}
-
-.dg.a .save-row {
-    top: 0;
-    z-index: 1002
-}
-
-.dg.a .save-row.close-top {
-    position: relative
-}
-
-.dg.a .save-row.close-bottom {
-    position: fixed
-}
-
-.dg li {
-    -webkit-transition: height .1s ease-out;
-    -o-transition: height .1s ease-out;
-    -moz-transition: height .1s ease-out;
-    transition: height .1s ease-out;
-    -webkit-transition: overflow .1s linear;
-    -o-transition: overflow .1s linear;
-    -moz-transition: overflow .1s linear;
-    transition: overflow .1s linear
-}
-
-.dg li:not(.folder) {
-    cursor: auto;
-    height: 27px;
-    line-height: 27px;
-    padding: 0 4px 0 5px
-}
-
-.dg li.folder {
-    padding: 0;
-    border-left: 4px solid rgba(0, 0, 0, 0)
-}
-
-.dg li.title {
-    cursor: pointer;
-    margin-left: -4px
-}
-
-.dg .closed li:not(.title),
-.dg .closed ul li,
-.dg .closed ul li>* {
-    height: 0;
-    overflow: hidden;
-    border: 0
-}
-
-.dg .cr {
-    clear: both;
-    padding-left: 3px;
-    height: 27px;
-    overflow: hidden
-}
-
-.dg .property-name {
-    cursor: default;
-    float: left;
-    clear: left;
-    width: 40%;
-    overflow: hidden;
-    text-overflow: ellipsis
-}
-
-.dg .c {
-    float: left;
-    width: 60%;
-    position: relative
-}
-
-.dg .c input[type=text] {
-    border: 0;
-    margin-top: 4px;
-    padding: 3px;
-    width: 100%;
-    float: right
-}
-
-.dg .has-slider input[type=text] {
-    width: 30%;
-    margin-left: 0
-}
-
-.dg .slider {
-    float: left;
-    width: 66%;
-    margin-left: -5px;
-    margin-right: 0;
-    height: 19px;
-    margin-top: 4px
-}
-
-.dg .slider-fg {
-    height: 100%
-}
-
-.dg .c input[type=checkbox] {
-    margin-top: 7px
-}
-
-.dg .c select {
-    margin-top: 5px
-}
-
-.dg .cr.function,
-.dg .cr.function .property-name,
-.dg .cr.function *,
-.dg .cr.boolean,
-.dg .cr.boolean * {
-    cursor: pointer
-}
-
-.dg .cr.color {
-    overflow: visible
-}
-
-.dg .selector {
-    display: none;
-    position: absolute;
-    margin-left: -9px;
-    margin-top: 23px;
-    z-index: 10
-}
-
-.dg .c:hover .selector,
-.dg .selector.drag {
-    display: block
-}
-
-.dg li.save-row {
-    padding: 0
-}
-
-.dg li.save-row .button {
-    display: inline-block;
-    padding: 0px 6px
-}
-
-.dg.dialogue {
-    background-color: #222;
-    width: 460px;
-    padding: 15px;
-    font-size: 13px;
-    line-height: 15px
-}
-
-#dg-new-constructor {
-    padding: 10px;
-    color: #222;
-    font-family: Monaco, monospace;
-    font-size: 10px;
-    border: 0;
-    resize: none;
-    box-shadow: inset 1px 1px 1px #888;
-    word-wrap: break-word;
-    margin: 12px 0;
-    display: block;
-    width: 440px;
-    overflow-y: scroll;
-    height: 100px;
-    position: relative
-}
-
-#dg-local-explain {
-    display: none;
-    font-size: 11px;
-    line-height: 17px;
-    border-radius: 3px;
-    background-color: #333;
-    padding: 8px;
-    margin-top: 10px
-}
-
-#dg-local-explain code {
-    font-size: 10px
-}
-
-#dat-gui-save-locally {
-    display: none
-}
-
-.dg {
-    color: #eee;
-    font: 11px 'Lucida Grande', sans-serif;
-    text-shadow: 0 -1px 0 #111
-}
-
-.dg.main::-webkit-scrollbar {
-    width: 5px;
-    background: #1a1a1a
-}
-
-.dg.main::-webkit-scrollbar-corner {
-    height: 0;
-    display: none
-}
-
-.dg.main::-webkit-scrollbar-thumb {
-    border-radius: 5px;
-    background: #676767
-}
-
-.dg li:not(.folder) {
-    background: #1a1a1a;
-    border-bottom: 1px solid #2c2c2c
-}
-
-.dg li.save-row {
-    line-height: 25px;
-    background: #dad5cb;
-    border: 0
-}
-
-.dg li.save-row select {
-    margin-left: 5px;
-    width: 108px
-}
-
-.dg li.save-row .button {
-    margin-left: 5px;
-    margin-top: 1px;
-    border-radius: 2px;
-    font-size: 9px;
-    line-height: 7px;
-    padding: 4px 4px 5px 4px;
-    background: #c5bdad;
-    color: #fff;
-    text-shadow: 0 1px 0 #b0a58f;
-    box-shadow: 0 -1px 0 #b0a58f;
-    cursor: pointer
-}
-
-.dg li.save-row .button.gears {
-    background: #c5bdad url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAANCAYAAAB/9ZQ7AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAQJJREFUeNpiYKAU/P//PwGIC/ApCABiBSAW+I8AClAcgKxQ4T9hoMAEUrxx2QSGN6+egDX+/vWT4e7N82AMYoPAx/evwWoYoSYbACX2s7KxCxzcsezDh3evFoDEBYTEEqycggWAzA9AuUSQQgeYPa9fPv6/YWm/Acx5IPb7ty/fw+QZblw67vDs8R0YHyQhgObx+yAJkBqmG5dPPDh1aPOGR/eugW0G4vlIoTIfyFcA+QekhhHJhPdQxbiAIguMBTQZrPD7108M6roWYDFQiIAAv6Aow/1bFwXgis+f2LUAynwoIaNcz8XNx3Dl7MEJUDGQpx9gtQ8YCueB+D26OECAAQDadt7e46D42QAAAABJRU5ErkJggg==) 2px 1px no-repeat;
-    height: 7px;
-    width: 8px
-}
-
-.dg li.save-row .button:hover {
-    background-color: #bab19e;
-    box-shadow: 0 -1px 0 #b0a58f
-}
-
-.dg li.folder {
-    border-bottom: 0
-}
-
-.dg li.title {
-    padding-left: 16px;
-    background: #000 url(data:image/gif;base64,R0lGODlhBQAFAJEAAP////Pz8////////yH5BAEAAAIALAAAAAAFAAUAAAIIlI+hKgFxoCgAOw==) 6px 10px no-repeat;
-    cursor: pointer;
-    border-bottom: 1px solid rgba(255, 255, 255, 0.2)
-}
-
-.dg .closed li.title {
-    background-image: url(data:image/gif;base64,R0lGODlhBQAFAJEAAP////Pz8////////yH5BAEAAAIALAAAAAAFAAUAAAIIlGIWqMCbWAEAOw==)
-}
-
-.dg .cr.boolean {
-    border-left: 3px solid #806787
-}
-
-.dg .cr.color {
-    border-left: 3px solid
-}
-
-.dg .cr.function {
-    border-left: 3px solid #e61d5f
-}
-
-.dg .cr.number {
-    border-left: 3px solid #2FA1D6
-}
-
-.dg .cr.number input[type=text] {
-    color: #2FA1D6
-}
-
-.dg .cr.string {
-    border-left: 3px solid #1ed36f
-}
-
-.dg .cr.string input[type=text] {
-    color: #1ed36f
-}
-
-.dg .cr.function:hover,
-.dg .cr.boolean:hover {
-    background: #111
-}
-
-.dg .c input[type=text] {
-    background: #303030;
-    outline: none
-}
-
-.dg .c input[type=text]:hover {
-    background: #3c3c3c
-}
-
-.dg .c input[type=text]:focus {
-    background: #494949;
-    color: #fff
-}
-
-.dg .c .slider {
-    background: #303030;
-    cursor: ew-resize
-}
-
-.dg .c .slider-fg {
-    background: #2FA1D6;
-    max-width: 100%
-}
-
-.dg .c .slider:hover {
-    background: #3c3c3c
-}
-
-.dg .c .slider:hover .slider-fg {
-    background: #44abda
-}
\ No newline at end of file
diff --git a/client/dat.gui.js b/client/dat.gui.js
deleted file mode 100644
index 039d776dd9bec2fde75a01abd6adad104c5a2ab7..0000000000000000000000000000000000000000
--- a/client/dat.gui.js
+++ /dev/null
@@ -1,2591 +0,0 @@
-/**
- * dat-gui JavaScript Controller Library
- * http://code.google.com/p/dat-gui
- *
- * Copyright 2011 Data Arts Team, Google Creative Lab
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- */
-
-(function(global, factory) {
-    typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
-        typeof define === 'function' && define.amd ? define(['exports'], factory) :
-        (factory((global.dat = {})));
-}(this, (function(exports) {
-    'use strict';
-
-    function ___$insertStyle(css) {
-        if (!css) {
-            return;
-        }
-        if (typeof window === 'undefined') {
-            return;
-        }
-
-        var style = document.createElement('style');
-
-        style.setAttribute('type', 'text/css');
-        style.innerHTML = css;
-        document.head.appendChild(style);
-
-        return css;
-    }
-
-    function colorToString(color, forceCSSHex) {
-        var colorFormat = color.__state.conversionName.toString();
-        var r = Math.round(color.r);
-        var g = Math.round(color.g);
-        var b = Math.round(color.b);
-        var a = color.a;
-        var h = Math.round(color.h);
-        var s = color.s.toFixed(1);
-        var v = color.v.toFixed(1);
-        if (forceCSSHex || colorFormat === 'THREE_CHAR_HEX' || colorFormat === 'SIX_CHAR_HEX') {
-            var str = color.hex.toString(16);
-            while (str.length < 6) {
-                str = '0' + str;
-            }
-            return '#' + str;
-        } else if (colorFormat === 'CSS_RGB') {
-            return 'rgb(' + r + ',' + g + ',' + b + ')';
-        } else if (colorFormat === 'CSS_RGBA') {
-            return 'rgba(' + r + ',' + g + ',' + b + ',' + a + ')';
-        } else if (colorFormat === 'HEX') {
-            return '0x' + color.hex.toString(16);
-        } else if (colorFormat === 'RGB_ARRAY') {
-            return '[' + r + ',' + g + ',' + b + ']';
-        } else if (colorFormat === 'RGBA_ARRAY') {
-            return '[' + r + ',' + g + ',' + b + ',' + a + ']';
-        } else if (colorFormat === 'RGB_OBJ') {
-            return '{r:' + r + ',g:' + g + ',b:' + b + '}';
-        } else if (colorFormat === 'RGBA_OBJ') {
-            return '{r:' + r + ',g:' + g + ',b:' + b + ',a:' + a + '}';
-        } else if (colorFormat === 'HSV_OBJ') {
-            return '{h:' + h + ',s:' + s + ',v:' + v + '}';
-        } else if (colorFormat === 'HSVA_OBJ') {
-            return '{h:' + h + ',s:' + s + ',v:' + v + ',a:' + a + '}';
-        }
-        return 'unknown format';
-    }
-
-    var ARR_EACH = Array.prototype.forEach;
-    var ARR_SLICE = Array.prototype.slice;
-    var Common = {
-        BREAK: {},
-        extend: function extend(target) {
-            this.each(ARR_SLICE.call(arguments, 1), function(obj) {
-                var keys = this.isObject(obj) ? Object.keys(obj) : [];
-                keys.forEach(function(key) {
-                    if (!this.isUndefined(obj[key])) {
-                        target[key] = obj[key];
-                    }
-                }.bind(this));
-            }, this);
-            return target;
-        },
-        defaults: function defaults(target) {
-            this.each(ARR_SLICE.call(arguments, 1), function(obj) {
-                var keys = this.isObject(obj) ? Object.keys(obj) : [];
-                keys.forEach(function(key) {
-                    if (this.isUndefined(target[key])) {
-                        target[key] = obj[key];
-                    }
-                }.bind(this));
-            }, this);
-            return target;
-        },
-        compose: function compose() {
-            var toCall = ARR_SLICE.call(arguments);
-            return function() {
-                var args = ARR_SLICE.call(arguments);
-                for (var i = toCall.length - 1; i >= 0; i--) {
-                    args = [toCall[i].apply(this, args)];
-                }
-                return args[0];
-            };
-        },
-        each: function each(obj, itr, scope) {
-            if (!obj) {
-                return;
-            }
-            if (ARR_EACH && obj.forEach && obj.forEach === ARR_EACH) {
-                obj.forEach(itr, scope);
-            } else if (obj.length === obj.length + 0) {
-                var key = void 0;
-                var l = void 0;
-                for (key = 0, l = obj.length; key < l; key++) {
-                    if (key in obj && itr.call(scope, obj[key], key) === this.BREAK) {
-                        return;
-                    }
-                }
-            } else {
-                for (var _key in obj) {
-                    if (itr.call(scope, obj[_key], _key) === this.BREAK) {
-                        return;
-                    }
-                }
-            }
-        },
-        defer: function defer(fnc) {
-            setTimeout(fnc, 0);
-        },
-        debounce: function debounce(func, threshold, callImmediately) {
-            var timeout = void 0;
-            return function() {
-                var obj = this;
-                var args = arguments;
-
-                function delayed() {
-                    timeout = null;
-                    if (!callImmediately) func.apply(obj, args);
-                }
-                var callNow = callImmediately || !timeout;
-                clearTimeout(timeout);
-                timeout = setTimeout(delayed, threshold);
-                if (callNow) {
-                    func.apply(obj, args);
-                }
-            };
-        },
-        toArray: function toArray(obj) {
-            if (obj.toArray) return obj.toArray();
-            return ARR_SLICE.call(obj);
-        },
-        isUndefined: function isUndefined(obj) {
-            return obj === undefined;
-        },
-        isNull: function isNull(obj) {
-            return obj === null;
-        },
-        isNaN: function(_isNaN) {
-            function isNaN(_x) {
-                return _isNaN.apply(this, arguments);
-            }
-            isNaN.toString = function() {
-                return _isNaN.toString();
-            };
-            return isNaN;
-        }(function(obj) {
-            return isNaN(obj);
-        }),
-        isArray: Array.isArray || function(obj) {
-            return obj.constructor === Array;
-        },
-        isObject: function isObject(obj) {
-            return obj === Object(obj);
-        },
-        isNumber: function isNumber(obj) {
-            return obj === obj + 0;
-        },
-        isString: function isString(obj) {
-            return obj === obj + '';
-        },
-        isBoolean: function isBoolean(obj) {
-            return obj === false || obj === true;
-        },
-        isFunction: function isFunction(obj) {
-            return Object.prototype.toString.call(obj) === '[object Function]';
-        }
-    };
-
-    var INTERPRETATIONS = [{
-            litmus: Common.isString,
-            conversions: {
-                THREE_CHAR_HEX: {
-                    read: function read(original) {
-                        var test = original.match(/^#([A-F0-9])([A-F0-9])([A-F0-9])$/i);
-                        if (test === null) {
-                            return false;
-                        }
-                        return {
-                            space: 'HEX',
-                            hex: parseInt('0x' + test[1].toString() + test[1].toString() + test[2].toString() + test[2].toString() + test[3].toString() + test[3].toString(), 0)
-                        };
-                    },
-                    write: colorToString
-                },
-                SIX_CHAR_HEX: {
-                    read: function read(original) {
-                        var test = original.match(/^#([A-F0-9]{6})$/i);
-                        if (test === null) {
-                            return false;
-                        }
-                        return {
-                            space: 'HEX',
-                            hex: parseInt('0x' + test[1].toString(), 0)
-                        };
-                    },
-                    write: colorToString
-                },
-                CSS_RGB: {
-                    read: function read(original) {
-                        var test = original.match(/^rgb\(\s*(.+)\s*,\s*(.+)\s*,\s*(.+)\s*\)/);
-                        if (test === null) {
-                            return false;
-                        }
-                        return {
-                            space: 'RGB',
-                            r: parseFloat(test[1]),
-                            g: parseFloat(test[2]),
-                            b: parseFloat(test[3])
-                        };
-                    },
-                    write: colorToString
-                },
-                CSS_RGBA: {
-                    read: function read(original) {
-                        var test = original.match(/^rgba\(\s*(.+)\s*,\s*(.+)\s*,\s*(.+)\s*,\s*(.+)\s*\)/);
-                        if (test === null) {
-                            return false;
-                        }
-                        return {
-                            space: 'RGB',
-                            r: parseFloat(test[1]),
-                            g: parseFloat(test[2]),
-                            b: parseFloat(test[3]),
-                            a: parseFloat(test[4])
-                        };
-                    },
-                    write: colorToString
-                }
-            }
-        },
-        {
-            litmus: Common.isNumber,
-            conversions: {
-                HEX: {
-                    read: function read(original) {
-                        return {
-                            space: 'HEX',
-                            hex: original,
-                            conversionName: 'HEX'
-                        };
-                    },
-                    write: function write(color) {
-                        return color.hex;
-                    }
-                }
-            }
-        },
-        {
-            litmus: Common.isArray,
-            conversions: {
-                RGB_ARRAY: {
-                    read: function read(original) {
-                        if (original.length !== 3) {
-                            return false;
-                        }
-                        return {
-                            space: 'RGB',
-                            r: original[0],
-                            g: original[1],
-                            b: original[2]
-                        };
-                    },
-                    write: function write(color) {
-                        return [color.r, color.g, color.b];
-                    }
-                },
-                RGBA_ARRAY: {
-                    read: function read(original) {
-                        if (original.length !== 4) return false;
-                        return {
-                            space: 'RGB',
-                            r: original[0],
-                            g: original[1],
-                            b: original[2],
-                            a: original[3]
-                        };
-                    },
-                    write: function write(color) {
-                        return [color.r, color.g, color.b, color.a];
-                    }
-                }
-            }
-        },
-        {
-            litmus: Common.isObject,
-            conversions: {
-                RGBA_OBJ: {
-                    read: function read(original) {
-                        if (Common.isNumber(original.r) && Common.isNumber(original.g) && Common.isNumber(original.b) && Common.isNumber(original.a)) {
-                            return {
-                                space: 'RGB',
-                                r: original.r,
-                                g: original.g,
-                                b: original.b,
-                                a: original.a
-                            };
-                        }
-                        return false;
-                    },
-                    write: function write(color) {
-                        return {
-                            r: color.r,
-                            g: color.g,
-                            b: color.b,
-                            a: color.a
-                        };
-                    }
-                },
-                RGB_OBJ: {
-                    read: function read(original) {
-                        if (Common.isNumber(original.r) && Common.isNumber(original.g) && Common.isNumber(original.b)) {
-                            return {
-                                space: 'RGB',
-                                r: original.r,
-                                g: original.g,
-                                b: original.b
-                            };
-                        }
-                        return false;
-                    },
-                    write: function write(color) {
-                        return {
-                            r: color.r,
-                            g: color.g,
-                            b: color.b
-                        };
-                    }
-                },
-                HSVA_OBJ: {
-                    read: function read(original) {
-                        if (Common.isNumber(original.h) && Common.isNumber(original.s) && Common.isNumber(original.v) && Common.isNumber(original.a)) {
-                            return {
-                                space: 'HSV',
-                                h: original.h,
-                                s: original.s,
-                                v: original.v,
-                                a: original.a
-                            };
-                        }
-                        return false;
-                    },
-                    write: function write(color) {
-                        return {
-                            h: color.h,
-                            s: color.s,
-                            v: color.v,
-                            a: color.a
-                        };
-                    }
-                },
-                HSV_OBJ: {
-                    read: function read(original) {
-                        if (Common.isNumber(original.h) && Common.isNumber(original.s) && Common.isNumber(original.v)) {
-                            return {
-                                space: 'HSV',
-                                h: original.h,
-                                s: original.s,
-                                v: original.v
-                            };
-                        }
-                        return false;
-                    },
-                    write: function write(color) {
-                        return {
-                            h: color.h,
-                            s: color.s,
-                            v: color.v
-                        };
-                    }
-                }
-            }
-        }
-    ];
-    var result = void 0;
-    var toReturn = void 0;
-    var interpret = function interpret() {
-        toReturn = false;
-        var original = arguments.length > 1 ? Common.toArray(arguments) : arguments[0];
-        Common.each(INTERPRETATIONS, function(family) {
-            if (family.litmus(original)) {
-                Common.each(family.conversions, function(conversion, conversionName) {
-                    result = conversion.read(original);
-                    if (toReturn === false && result !== false) {
-                        toReturn = result;
-                        result.conversionName = conversionName;
-                        result.conversion = conversion;
-                        return Common.BREAK;
-                    }
-                });
-                return Common.BREAK;
-            }
-        });
-        return toReturn;
-    };
-
-    var tmpComponent = void 0;
-    var ColorMath = {
-        hsv_to_rgb: function hsv_to_rgb(h, s, v) {
-            var hi = Math.floor(h / 60) % 6;
-            var f = h / 60 - Math.floor(h / 60);
-            var p = v * (1.0 - s);
-            var q = v * (1.0 - f * s);
-            var t = v * (1.0 - (1.0 - f) * s);
-            var c = [
-                [v, t, p],
-                [q, v, p],
-                [p, v, t],
-                [p, q, v],
-                [t, p, v],
-                [v, p, q]
-            ][hi];
-            return {
-                r: c[0] * 255,
-                g: c[1] * 255,
-                b: c[2] * 255
-            };
-        },
-        rgb_to_hsv: function rgb_to_hsv(r, g, b) {
-            var min = Math.min(r, g, b);
-            var max = Math.max(r, g, b);
-            var delta = max - min;
-            var h = void 0;
-            var s = void 0;
-            if (max !== 0) {
-                s = delta / max;
-            } else {
-                return {
-                    h: NaN,
-                    s: 0,
-                    v: 0
-                };
-            }
-            if (r === max) {
-                h = (g - b) / delta;
-            } else if (g === max) {
-                h = 2 + (b - r) / delta;
-            } else {
-                h = 4 + (r - g) / delta;
-            }
-            h /= 6;
-            if (h < 0) {
-                h += 1;
-            }
-            return {
-                h: h * 360,
-                s: s,
-                v: max / 255
-            };
-        },
-        rgb_to_hex: function rgb_to_hex(r, g, b) {
-            var hex = this.hex_with_component(0, 2, r);
-            hex = this.hex_with_component(hex, 1, g);
-            hex = this.hex_with_component(hex, 0, b);
-            return hex;
-        },
-        component_from_hex: function component_from_hex(hex, componentIndex) {
-            return hex >> componentIndex * 8 & 0xFF;
-        },
-        hex_with_component: function hex_with_component(hex, componentIndex, value) {
-            return value << (tmpComponent = componentIndex * 8) | hex & ~(0xFF << tmpComponent);
-        }
-    };
-
-    var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function(obj) {
-        return typeof obj;
-    } : function(obj) {
-        return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
-    };
-
-
-
-
-
-
-
-
-
-
-
-    var classCallCheck = function(instance, Constructor) {
-        if (!(instance instanceof Constructor)) {
-            throw new TypeError("Cannot call a class as a function");
-        }
-    };
-
-    var createClass = function() {
-        function defineProperties(target, props) {
-            for (var i = 0; i < props.length; i++) {
-                var descriptor = props[i];
-                descriptor.enumerable = descriptor.enumerable || false;
-                descriptor.configurable = true;
-                if ("value" in descriptor) descriptor.writable = true;
-                Object.defineProperty(target, descriptor.key, descriptor);
-            }
-        }
-
-        return function(Constructor, protoProps, staticProps) {
-            if (protoProps) defineProperties(Constructor.prototype, protoProps);
-            if (staticProps) defineProperties(Constructor, staticProps);
-            return Constructor;
-        };
-    }();
-
-
-
-
-
-
-
-    var get = function get(object, property, receiver) {
-        if (object === null) object = Function.prototype;
-        var desc = Object.getOwnPropertyDescriptor(object, property);
-
-        if (desc === undefined) {
-            var parent = Object.getPrototypeOf(object);
-
-            if (parent === null) {
-                return undefined;
-            } else {
-                return get(parent, property, receiver);
-            }
-        } else if ("value" in desc) {
-            return desc.value;
-        } else {
-            var getter = desc.get;
-
-            if (getter === undefined) {
-                return undefined;
-            }
-
-            return getter.call(receiver);
-        }
-    };
-
-    var inherits = function(subClass, superClass) {
-        if (typeof superClass !== "function" && superClass !== null) {
-            throw new TypeError("Super expression must either be null or a function, not " + typeof superClass);
-        }
-
-        subClass.prototype = Object.create(superClass && superClass.prototype, {
-            constructor: {
-                value: subClass,
-                enumerable: false,
-                writable: true,
-                configurable: true
-            }
-        });
-        if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;
-    };
-
-
-
-
-
-
-
-
-
-
-
-    var possibleConstructorReturn = function(self, call) {
-        if (!self) {
-            throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
-        }
-
-        return call && (typeof call === "object" || typeof call === "function") ? call : self;
-    };
-
-    var Color = function() {
-        function Color() {
-            classCallCheck(this, Color);
-            this.__state = interpret.apply(this, arguments);
-            if (this.__state === false) {
-                throw new Error('Failed to interpret color arguments');
-            }
-            this.__state.a = this.__state.a || 1;
-        }
-        createClass(Color, [{
-            key: 'toString',
-            value: function toString() {
-                return colorToString(this);
-            }
-        }, {
-            key: 'toHexString',
-            value: function toHexString() {
-                return colorToString(this, true);
-            }
-        }, {
-            key: 'toOriginal',
-            value: function toOriginal() {
-                return this.__state.conversion.write(this);
-            }
-        }]);
-        return Color;
-    }();
-
-    function defineRGBComponent(target, component, componentHexIndex) {
-        Object.defineProperty(target, component, {
-            get: function get$$1() {
-                if (this.__state.space === 'RGB') {
-                    return this.__state[component];
-                }
-                Color.recalculateRGB(this, component, componentHexIndex);
-                return this.__state[component];
-            },
-            set: function set$$1(v) {
-                if (this.__state.space !== 'RGB') {
-                    Color.recalculateRGB(this, component, componentHexIndex);
-                    this.__state.space = 'RGB';
-                }
-                this.__state[component] = v;
-            }
-        });
-    }
-
-    function defineHSVComponent(target, component) {
-        Object.defineProperty(target, component, {
-            get: function get$$1() {
-                if (this.__state.space === 'HSV') {
-                    return this.__state[component];
-                }
-                Color.recalculateHSV(this);
-                return this.__state[component];
-            },
-            set: function set$$1(v) {
-                if (this.__state.space !== 'HSV') {
-                    Color.recalculateHSV(this);
-                    this.__state.space = 'HSV';
-                }
-                this.__state[component] = v;
-            }
-        });
-    }
-    Color.recalculateRGB = function(color, component, componentHexIndex) {
-        if (color.__state.space === 'HEX') {
-            color.__state[component] = ColorMath.component_from_hex(color.__state.hex, componentHexIndex);
-        } else if (color.__state.space === 'HSV') {
-            Common.extend(color.__state, ColorMath.hsv_to_rgb(color.__state.h, color.__state.s, color.__state.v));
-        } else {
-            throw new Error('Corrupted color state');
-        }
-    };
-    Color.recalculateHSV = function(color) {
-        var result = ColorMath.rgb_to_hsv(color.r, color.g, color.b);
-        Common.extend(color.__state, {
-            s: result.s,
-            v: result.v
-        });
-        if (!Common.isNaN(result.h)) {
-            color.__state.h = result.h;
-        } else if (Common.isUndefined(color.__state.h)) {
-            color.__state.h = 0;
-        }
-    };
-    Color.COMPONENTS = ['r', 'g', 'b', 'h', 's', 'v', 'hex', 'a'];
-    defineRGBComponent(Color.prototype, 'r', 2);
-    defineRGBComponent(Color.prototype, 'g', 1);
-    defineRGBComponent(Color.prototype, 'b', 0);
-    defineHSVComponent(Color.prototype, 'h');
-    defineHSVComponent(Color.prototype, 's');
-    defineHSVComponent(Color.prototype, 'v');
-    Object.defineProperty(Color.prototype, 'a', {
-        get: function get$$1() {
-            return this.__state.a;
-        },
-        set: function set$$1(v) {
-            this.__state.a = v;
-        }
-    });
-    Object.defineProperty(Color.prototype, 'hex', {
-        get: function get$$1() {
-            if (!this.__state.space !== 'HEX') {
-                this.__state.hex = ColorMath.rgb_to_hex(this.r, this.g, this.b);
-            }
-            return this.__state.hex;
-        },
-        set: function set$$1(v) {
-            this.__state.space = 'HEX';
-            this.__state.hex = v;
-        }
-    });
-
-    var Controller = function() {
-        function Controller(object, property) {
-            classCallCheck(this, Controller);
-            this.initialValue = object[property];
-            this.domElement = document.createElement('div');
-            this.object = object;
-            this.property = property;
-            this.__onChange = undefined;
-            this.__onFinishChange = undefined;
-        }
-        createClass(Controller, [{
-            key: 'onChange',
-            value: function onChange(fnc) {
-                this.__onChange = fnc;
-                return this;
-            }
-        }, {
-            key: 'onFinishChange',
-            value: function onFinishChange(fnc) {
-                this.__onFinishChange = fnc;
-                return this;
-            }
-        }, {
-            key: 'setValue',
-            value: function setValue(newValue) {
-                this.object[this.property] = newValue;
-                if (this.__onChange) {
-                    this.__onChange.call(this, newValue);
-                }
-                this.updateDisplay();
-                return this;
-            }
-        }, {
-            key: 'getValue',
-            value: function getValue() {
-                return this.object[this.property];
-            }
-        }, {
-            key: 'updateDisplay',
-            value: function updateDisplay() {
-                return this;
-            }
-        }, {
-            key: 'isModified',
-            value: function isModified() {
-                return this.initialValue !== this.getValue();
-            }
-        }]);
-        return Controller;
-    }();
-
-    var EVENT_MAP = {
-        HTMLEvents: ['change'],
-        MouseEvents: ['click', 'mousemove', 'mousedown', 'mouseup', 'mouseover'],
-        KeyboardEvents: ['keydown']
-    };
-    var EVENT_MAP_INV = {};
-    Common.each(EVENT_MAP, function(v, k) {
-        Common.each(v, function(e) {
-            EVENT_MAP_INV[e] = k;
-        });
-    });
-    var CSS_VALUE_PIXELS = /(\d+(\.\d+)?)px/;
-
-    function cssValueToPixels(val) {
-        if (val === '0' || Common.isUndefined(val)) {
-            return 0;
-        }
-        var match = val.match(CSS_VALUE_PIXELS);
-        if (!Common.isNull(match)) {
-            return parseFloat(match[1]);
-        }
-        return 0;
-    }
-    var dom = {
-        makeSelectable: function makeSelectable(elem, selectable) {
-            if (elem === undefined || elem.style === undefined) return;
-            elem.onselectstart = selectable ? function() {
-                return false;
-            } : function() {};
-            elem.style.MozUserSelect = selectable ? 'auto' : 'none';
-            elem.style.KhtmlUserSelect = selectable ? 'auto' : 'none';
-            elem.unselectable = selectable ? 'on' : 'off';
-        },
-        makeFullscreen: function makeFullscreen(elem, hor, vert) {
-            var vertical = vert;
-            var horizontal = hor;
-            if (Common.isUndefined(horizontal)) {
-                horizontal = true;
-            }
-            if (Common.isUndefined(vertical)) {
-                vertical = true;
-            }
-            elem.style.position = 'absolute';
-            if (horizontal) {
-                elem.style.left = 0;
-                elem.style.right = 0;
-            }
-            if (vertical) {
-                elem.style.top = 0;
-                elem.style.bottom = 0;
-            }
-        },
-        fakeEvent: function fakeEvent(elem, eventType, pars, aux) {
-            var params = pars || {};
-            var className = EVENT_MAP_INV[eventType];
-            if (!className) {
-                throw new Error('Event type ' + eventType + ' not supported.');
-            }
-            var evt = document.createEvent(className);
-            switch (className) {
-                case 'MouseEvents':
-                    {
-                        var clientX = params.x || params.clientX || 0;
-                        var clientY = params.y || params.clientY || 0;
-                        evt.initMouseEvent(eventType, params.bubbles || false, params.cancelable || true, window, params.clickCount || 1, 0,
-                            0,
-                            clientX,
-                            clientY,
-                            false, false, false, false, 0, null);
-                        break;
-                    }
-                case 'KeyboardEvents':
-                    {
-                        var init = evt.initKeyboardEvent || evt.initKeyEvent;
-                        Common.defaults(params, {
-                            cancelable: true,
-                            ctrlKey: false,
-                            altKey: false,
-                            shiftKey: false,
-                            metaKey: false,
-                            keyCode: undefined,
-                            charCode: undefined
-                        });
-                        init(eventType, params.bubbles || false, params.cancelable, window, params.ctrlKey, params.altKey, params.shiftKey, params.metaKey, params.keyCode, params.charCode);
-                        break;
-                    }
-                default:
-                    {
-                        evt.initEvent(eventType, params.bubbles || false, params.cancelable || true);
-                        break;
-                    }
-            }
-            Common.defaults(evt, aux);
-            elem.dispatchEvent(evt);
-        },
-        bind: function bind(elem, event, func, newBool) {
-            var bool = newBool || false;
-            if (elem.addEventListener) {
-                elem.addEventListener(event, func, bool);
-            } else if (elem.attachEvent) {
-                elem.attachEvent('on' + event, func);
-            }
-            return dom;
-        },
-        unbind: function unbind(elem, event, func, newBool) {
-            var bool = newBool || false;
-            if (elem.removeEventListener) {
-                elem.removeEventListener(event, func, bool);
-            } else if (elem.detachEvent) {
-                elem.detachEvent('on' + event, func);
-            }
-            return dom;
-        },
-        addClass: function addClass(elem, className) {
-            if (elem.className === undefined) {
-                elem.className = className;
-            } else if (elem.className !== className) {
-                var classes = elem.className.split(/ +/);
-                if (classes.indexOf(className) === -1) {
-                    classes.push(className);
-                    elem.className = classes.join(' ').replace(/^\s+/, '').replace(/\s+$/, '');
-                }
-            }
-            return dom;
-        },
-        removeClass: function removeClass(elem, className) {
-            if (className) {
-                if (elem.className === className) {
-                    elem.removeAttribute('class');
-                } else {
-                    var classes = elem.className.split(/ +/);
-                    var index = classes.indexOf(className);
-                    if (index !== -1) {
-                        classes.splice(index, 1);
-                        elem.className = classes.join(' ');
-                    }
-                }
-            } else {
-                elem.className = undefined;
-            }
-            return dom;
-        },
-        hasClass: function hasClass(elem, className) {
-            return new RegExp('(?:^|\\s+)' + className + '(?:\\s+|$)').test(elem.className) || false;
-        },
-        getWidth: function getWidth(elem) {
-            var style = getComputedStyle(elem);
-            return cssValueToPixels(style['border-left-width']) + cssValueToPixels(style['border-right-width']) + cssValueToPixels(style['padding-left']) + cssValueToPixels(style['padding-right']) + cssValueToPixels(style.width);
-        },
-        getHeight: function getHeight(elem) {
-            var style = getComputedStyle(elem);
-            return cssValueToPixels(style['border-top-width']) + cssValueToPixels(style['border-bottom-width']) + cssValueToPixels(style['padding-top']) + cssValueToPixels(style['padding-bottom']) + cssValueToPixels(style.height);
-        },
-        getOffset: function getOffset(el) {
-            var elem = el;
-            var offset = { left: 0, top: 0 };
-            if (elem.offsetParent) {
-                do {
-                    offset.left += elem.offsetLeft;
-                    offset.top += elem.offsetTop;
-                    elem = elem.offsetParent;
-                } while (elem);
-            }
-            return offset;
-        },
-        isActive: function isActive(elem) {
-            return elem === document.activeElement && (elem.type || elem.href);
-        }
-    };
-
-    var BooleanController = function(_Controller) {
-        inherits(BooleanController, _Controller);
-
-        function BooleanController(object, property) {
-            classCallCheck(this, BooleanController);
-            var _this2 = possibleConstructorReturn(this, (BooleanController.__proto__ || Object.getPrototypeOf(BooleanController)).call(this, object, property));
-            var _this = _this2;
-            _this2.__prev = _this2.getValue();
-            _this2.__checkbox = document.createElement('input');
-            _this2.__checkbox.setAttribute('type', 'checkbox');
-
-            function onChange() {
-                _this.setValue(!_this.__prev);
-            }
-            dom.bind(_this2.__checkbox, 'change', onChange, false);
-            _this2.domElement.appendChild(_this2.__checkbox);
-            _this2.updateDisplay();
-            return _this2;
-        }
-        createClass(BooleanController, [{
-            key: 'setValue',
-            value: function setValue(v) {
-                var toReturn = get(BooleanController.prototype.__proto__ || Object.getPrototypeOf(BooleanController.prototype), 'setValue', this).call(this, v);
-                if (this.__onFinishChange) {
-                    this.__onFinishChange.call(this, this.getValue());
-                }
-                this.__prev = this.getValue();
-                return toReturn;
-            }
-        }, {
-            key: 'updateDisplay',
-            value: function updateDisplay() {
-                if (this.getValue() === true) {
-                    this.__checkbox.setAttribute('checked', 'checked');
-                    this.__checkbox.checked = true;
-                    this.__prev = true;
-                } else {
-                    this.__checkbox.checked = false;
-                    this.__prev = false;
-                }
-                return get(BooleanController.prototype.__proto__ || Object.getPrototypeOf(BooleanController.prototype), 'updateDisplay', this).call(this);
-            }
-        }]);
-        return BooleanController;
-    }(Controller);
-
-    var OptionController = function(_Controller) {
-        inherits(OptionController, _Controller);
-
-        function OptionController(object, property, opts) {
-            classCallCheck(this, OptionController);
-            var _this2 = possibleConstructorReturn(this, (OptionController.__proto__ || Object.getPrototypeOf(OptionController)).call(this, object, property));
-            var options = opts;
-            var _this = _this2;
-            _this2.__select = document.createElement('select');
-            if (Common.isArray(options)) {
-                var map = {};
-                Common.each(options, function(element) {
-                    map[element] = element;
-                });
-                options = map;
-            }
-            Common.each(options, function(value, key) {
-                var opt = document.createElement('option');
-                opt.innerHTML = key;
-                opt.setAttribute('value', value);
-                _this.__select.appendChild(opt);
-            });
-            _this2.updateDisplay();
-            dom.bind(_this2.__select, 'change', function() {
-                var desiredValue = this.options[this.selectedIndex].value;
-                _this.setValue(desiredValue);
-            });
-            _this2.domElement.appendChild(_this2.__select);
-            return _this2;
-        }
-        createClass(OptionController, [{
-            key: 'setValue',
-            value: function setValue(v) {
-                var toReturn = get(OptionController.prototype.__proto__ || Object.getPrototypeOf(OptionController.prototype), 'setValue', this).call(this, v);
-                if (this.__onFinishChange) {
-                    this.__onFinishChange.call(this, this.getValue());
-                }
-                return toReturn;
-            }
-        }, {
-            key: 'updateDisplay',
-            value: function updateDisplay() {
-                if (dom.isActive(this.__select)) return this;
-                this.__select.value = this.getValue();
-                return get(OptionController.prototype.__proto__ || Object.getPrototypeOf(OptionController.prototype), 'updateDisplay', this).call(this);
-            }
-        }]);
-        return OptionController;
-    }(Controller);
-
-    var StringController = function(_Controller) {
-        inherits(StringController, _Controller);
-
-        function StringController(object, property) {
-            classCallCheck(this, StringController);
-            var _this2 = possibleConstructorReturn(this, (StringController.__proto__ || Object.getPrototypeOf(StringController)).call(this, object, property));
-            var _this = _this2;
-
-            function onChange() {
-                _this.setValue(_this.__input.value);
-            }
-
-            function onBlur() {
-                if (_this.__onFinishChange) {
-                    _this.__onFinishChange.call(_this, _this.getValue());
-                }
-            }
-            _this2.__input = document.createElement('input');
-            _this2.__input.setAttribute('type', 'text');
-            dom.bind(_this2.__input, 'keyup', onChange);
-            dom.bind(_this2.__input, 'change', onChange);
-            dom.bind(_this2.__input, 'blur', onBlur);
-            dom.bind(_this2.__input, 'keydown', function(e) {
-                if (e.keyCode === 13) {
-                    this.blur();
-                }
-            });
-            _this2.updateDisplay();
-            _this2.domElement.appendChild(_this2.__input);
-            return _this2;
-        }
-        createClass(StringController, [{
-            key: 'updateDisplay',
-            value: function updateDisplay() {
-                if (!dom.isActive(this.__input)) {
-                    this.__input.value = this.getValue();
-                }
-                return get(StringController.prototype.__proto__ || Object.getPrototypeOf(StringController.prototype), 'updateDisplay', this).call(this);
-            }
-        }]);
-        return StringController;
-    }(Controller);
-
-    function numDecimals(x) {
-        var _x = x.toString();
-        if (_x.indexOf('.') > -1) {
-            return _x.length - _x.indexOf('.') - 1;
-        }
-        return 0;
-    }
-    var NumberController = function(_Controller) {
-        inherits(NumberController, _Controller);
-
-        function NumberController(object, property, params) {
-            classCallCheck(this, NumberController);
-            var _this = possibleConstructorReturn(this, (NumberController.__proto__ || Object.getPrototypeOf(NumberController)).call(this, object, property));
-            var _params = params || {};
-            _this.__min = _params.min;
-            _this.__max = _params.max;
-            _this.__step = _params.step;
-            if (Common.isUndefined(_this.__step)) {
-                if (_this.initialValue === 0) {
-                    _this.__impliedStep = 1;
-                } else {
-                    _this.__impliedStep = Math.pow(10, Math.floor(Math.log(Math.abs(_this.initialValue)) / Math.LN10)) / 10;
-                }
-            } else {
-                _this.__impliedStep = _this.__step;
-            }
-            _this.__precision = numDecimals(_this.__impliedStep);
-            return _this;
-        }
-        createClass(NumberController, [{
-            key: 'setValue',
-            value: function setValue(v) {
-                var _v = v;
-                if (this.__min !== undefined && _v < this.__min) {
-                    _v = this.__min;
-                } else if (this.__max !== undefined && _v > this.__max) {
-                    _v = this.__max;
-                }
-                if (this.__step !== undefined && _v % this.__step !== 0) {
-                    _v = Math.round(_v / this.__step) * this.__step;
-                }
-                return get(NumberController.prototype.__proto__ || Object.getPrototypeOf(NumberController.prototype), 'setValue', this).call(this, _v);
-            }
-        }, {
-            key: 'min',
-            value: function min(minValue) {
-                this.__min = minValue;
-                return this;
-            }
-        }, {
-            key: 'max',
-            value: function max(maxValue) {
-                this.__max = maxValue;
-                return this;
-            }
-        }, {
-            key: 'step',
-            value: function step(stepValue) {
-                this.__step = stepValue;
-                this.__impliedStep = stepValue;
-                this.__precision = numDecimals(stepValue);
-                return this;
-            }
-        }]);
-        return NumberController;
-    }(Controller);
-
-    function roundToDecimal(value, decimals) {
-        var tenTo = Math.pow(10, decimals);
-        return Math.round(value * tenTo) / tenTo;
-    }
-    var NumberControllerBox = function(_NumberController) {
-        inherits(NumberControllerBox, _NumberController);
-
-        function NumberControllerBox(object, property, params) {
-            classCallCheck(this, NumberControllerBox);
-            var _this2 = possibleConstructorReturn(this, (NumberControllerBox.__proto__ || Object.getPrototypeOf(NumberControllerBox)).call(this, object, property, params));
-            _this2.__truncationSuspended = false;
-            var _this = _this2;
-            var prevY = void 0;
-
-            function onChange() {
-                var attempted = parseFloat(_this.__input.value);
-                if (!Common.isNaN(attempted)) {
-                    _this.setValue(attempted);
-                }
-            }
-
-            function onFinish() {
-                if (_this.__onFinishChange) {
-                    _this.__onFinishChange.call(_this, _this.getValue());
-                }
-            }
-
-            function onBlur() {
-                onFinish();
-            }
-
-            function onMouseDrag(e) {
-                var diff = prevY - e.clientY;
-                _this.setValue(_this.getValue() + diff * _this.__impliedStep);
-                prevY = e.clientY;
-            }
-
-            function onMouseUp() {
-                dom.unbind(window, 'mousemove', onMouseDrag);
-                dom.unbind(window, 'mouseup', onMouseUp);
-                onFinish();
-            }
-
-            function onMouseDown(e) {
-                dom.bind(window, 'mousemove', onMouseDrag);
-                dom.bind(window, 'mouseup', onMouseUp);
-                prevY = e.clientY;
-            }
-            _this2.__input = document.createElement('input');
-            _this2.__input.setAttribute('type', 'text');
-            dom.bind(_this2.__input, 'change', onChange);
-            dom.bind(_this2.__input, 'blur', onBlur);
-            dom.bind(_this2.__input, 'mousedown', onMouseDown);
-            dom.bind(_this2.__input, 'keydown', function(e) {
-                if (e.keyCode === 13) {
-                    _this.__truncationSuspended = true;
-                    this.blur();
-                    _this.__truncationSuspended = false;
-                    onFinish();
-                }
-            });
-            _this2.updateDisplay();
-            _this2.domElement.appendChild(_this2.__input);
-            return _this2;
-        }
-        createClass(NumberControllerBox, [{
-            key: 'updateDisplay',
-            value: function updateDisplay() {
-                this.__input.value = this.__truncationSuspended ? this.getValue() : roundToDecimal(this.getValue(), this.__precision);
-                return get(NumberControllerBox.prototype.__proto__ || Object.getPrototypeOf(NumberControllerBox.prototype), 'updateDisplay', this).call(this);
-            }
-        }]);
-        return NumberControllerBox;
-    }(NumberController);
-
-    function map(v, i1, i2, o1, o2) {
-        return o1 + (o2 - o1) * ((v - i1) / (i2 - i1));
-    }
-    var NumberControllerSlider = function(_NumberController) {
-        inherits(NumberControllerSlider, _NumberController);
-
-        function NumberControllerSlider(object, property, min, max, step) {
-            classCallCheck(this, NumberControllerSlider);
-            var _this2 = possibleConstructorReturn(this, (NumberControllerSlider.__proto__ || Object.getPrototypeOf(NumberControllerSlider)).call(this, object, property, { min: min, max: max, step: step }));
-            var _this = _this2;
-            _this2.__background = document.createElement('div');
-            _this2.__foreground = document.createElement('div');
-            dom.bind(_this2.__background, 'mousedown', onMouseDown);
-            dom.bind(_this2.__background, 'touchstart', onTouchStart);
-            dom.addClass(_this2.__background, 'slider');
-            dom.addClass(_this2.__foreground, 'slider-fg');
-
-            function onMouseDown(e) {
-                document.activeElement.blur();
-                dom.bind(window, 'mousemove', onMouseDrag);
-                dom.bind(window, 'mouseup', onMouseUp);
-                onMouseDrag(e);
-            }
-
-            function onMouseDrag(e) {
-                e.preventDefault();
-                var bgRect = _this.__background.getBoundingClientRect();
-                _this.setValue(map(e.clientX, bgRect.left, bgRect.right, _this.__min, _this.__max));
-                return false;
-            }
-
-            function onMouseUp() {
-                dom.unbind(window, 'mousemove', onMouseDrag);
-                dom.unbind(window, 'mouseup', onMouseUp);
-                if (_this.__onFinishChange) {
-                    _this.__onFinishChange.call(_this, _this.getValue());
-                }
-            }
-
-            function onTouchStart(e) {
-                if (e.touches.length !== 1) {
-                    return;
-                }
-                dom.bind(window, 'touchmove', onTouchMove);
-                dom.bind(window, 'touchend', onTouchEnd);
-                onTouchMove(e);
-            }
-
-            function onTouchMove(e) {
-                var clientX = e.touches[0].clientX;
-                var bgRect = _this.__background.getBoundingClientRect();
-                _this.setValue(map(clientX, bgRect.left, bgRect.right, _this.__min, _this.__max));
-            }
-
-            function onTouchEnd() {
-                dom.unbind(window, 'touchmove', onTouchMove);
-                dom.unbind(window, 'touchend', onTouchEnd);
-                if (_this.__onFinishChange) {
-                    _this.__onFinishChange.call(_this, _this.getValue());
-                }
-            }
-            _this2.updateDisplay();
-            _this2.__background.appendChild(_this2.__foreground);
-            _this2.domElement.appendChild(_this2.__background);
-            return _this2;
-        }
-        createClass(NumberControllerSlider, [{
-            key: 'updateDisplay',
-            value: function updateDisplay() {
-                var pct = (this.getValue() - this.__min) / (this.__max - this.__min);
-                this.__foreground.style.width = pct * 100 + '%';
-                return get(NumberControllerSlider.prototype.__proto__ || Object.getPrototypeOf(NumberControllerSlider.prototype), 'updateDisplay', this).call(this);
-            }
-        }]);
-        return NumberControllerSlider;
-    }(NumberController);
-
-    var FunctionController = function(_Controller) {
-        inherits(FunctionController, _Controller);
-
-        function FunctionController(object, property, text) {
-            classCallCheck(this, FunctionController);
-            var _this2 = possibleConstructorReturn(this, (FunctionController.__proto__ || Object.getPrototypeOf(FunctionController)).call(this, object, property));
-            var _this = _this2;
-            _this2.__button = document.createElement('div');
-            _this2.__button.innerHTML = text === undefined ? 'Fire' : text;
-            dom.bind(_this2.__button, 'click', function(e) {
-                e.preventDefault();
-                _this.fire();
-                return false;
-            });
-            dom.addClass(_this2.__button, 'button');
-            _this2.domElement.appendChild(_this2.__button);
-            return _this2;
-        }
-        createClass(FunctionController, [{
-            key: 'fire',
-            value: function fire() {
-                if (this.__onChange) {
-                    this.__onChange.call(this);
-                }
-                this.getValue().call(this.object);
-                if (this.__onFinishChange) {
-                    this.__onFinishChange.call(this, this.getValue());
-                }
-            }
-        }]);
-        return FunctionController;
-    }(Controller);
-
-    var ColorController = function(_Controller) {
-        inherits(ColorController, _Controller);
-
-        function ColorController(object, property) {
-            classCallCheck(this, ColorController);
-            var _this2 = possibleConstructorReturn(this, (ColorController.__proto__ || Object.getPrototypeOf(ColorController)).call(this, object, property));
-            _this2.__color = new Color(_this2.getValue());
-            _this2.__temp = new Color(0);
-            var _this = _this2;
-            _this2.domElement = document.createElement('div');
-            dom.makeSelectable(_this2.domElement, false);
-            _this2.__selector = document.createElement('div');
-            _this2.__selector.className = 'selector';
-            _this2.__saturation_field = document.createElement('div');
-            _this2.__saturation_field.className = 'saturation-field';
-            _this2.__field_knob = document.createElement('div');
-            _this2.__field_knob.className = 'field-knob';
-            _this2.__field_knob_border = '2px solid ';
-            _this2.__hue_knob = document.createElement('div');
-            _this2.__hue_knob.className = 'hue-knob';
-            _this2.__hue_field = document.createElement('div');
-            _this2.__hue_field.className = 'hue-field';
-            _this2.__input = document.createElement('input');
-            _this2.__input.type = 'text';
-            _this2.__input_textShadow = '0 1px 1px ';
-            dom.bind(_this2.__input, 'keydown', function(e) {
-                if (e.keyCode === 13) {
-                    onBlur.call(this);
-                }
-            });
-            dom.bind(_this2.__input, 'blur', onBlur);
-            dom.bind(_this2.__selector, 'mousedown', function() {
-                dom.addClass(this, 'drag').bind(window, 'mouseup', function() {
-                    dom.removeClass(_this.__selector, 'drag');
-                });
-            });
-            dom.bind(_this2.__selector, 'touchstart', function() {
-                dom.addClass(this, 'drag').bind(window, 'touchend', function() {
-                    dom.removeClass(_this.__selector, 'drag');
-                });
-            });
-            var valueField = document.createElement('div');
-            Common.extend(_this2.__selector.style, {
-                width: '122px',
-                height: '102px',
-                padding: '3px',
-                backgroundColor: '#222',
-                boxShadow: '0px 1px 3px rgba(0,0,0,0.3)'
-            });
-            Common.extend(_this2.__field_knob.style, {
-                position: 'absolute',
-                width: '12px',
-                height: '12px',
-                border: _this2.__field_knob_border + (_this2.__color.v < 0.5 ? '#fff' : '#000'),
-                boxShadow: '0px 1px 3px rgba(0,0,0,0.5)',
-                borderRadius: '12px',
-                zIndex: 1
-            });
-            Common.extend(_this2.__hue_knob.style, {
-                position: 'absolute',
-                width: '15px',
-                height: '2px',
-                borderRight: '4px solid #fff',
-                zIndex: 1
-            });
-            Common.extend(_this2.__saturation_field.style, {
-                width: '100px',
-                height: '100px',
-                border: '1px solid #555',
-                marginRight: '3px',
-                display: 'inline-block',
-                cursor: 'pointer'
-            });
-            Common.extend(valueField.style, {
-                width: '100%',
-                height: '100%',
-                background: 'none'
-            });
-            linearGradient(valueField, 'top', 'rgba(0,0,0,0)', '#000');
-            Common.extend(_this2.__hue_field.style, {
-                width: '15px',
-                height: '100px',
-                border: '1px solid #555',
-                cursor: 'ns-resize',
-                position: 'absolute',
-                top: '3px',
-                right: '3px'
-            });
-            hueGradient(_this2.__hue_field);
-            Common.extend(_this2.__input.style, {
-                outline: 'none',
-                textAlign: 'center',
-                color: '#fff',
-                border: 0,
-                fontWeight: 'bold',
-                textShadow: _this2.__input_textShadow + 'rgba(0,0,0,0.7)'
-            });
-            dom.bind(_this2.__saturation_field, 'mousedown', fieldDown);
-            dom.bind(_this2.__saturation_field, 'touchstart', fieldDown);
-            dom.bind(_this2.__field_knob, 'mousedown', fieldDown);
-            dom.bind(_this2.__field_knob, 'touchstart', fieldDown);
-            dom.bind(_this2.__hue_field, 'mousedown', fieldDownH);
-            dom.bind(_this2.__hue_field, 'touchstart', fieldDownH);
-
-            function fieldDown(e) {
-                setSV(e);
-                dom.bind(window, 'mousemove', setSV);
-                dom.bind(window, 'touchmove', setSV);
-                dom.bind(window, 'mouseup', fieldUpSV);
-                dom.bind(window, 'touchend', fieldUpSV);
-            }
-
-            function fieldDownH(e) {
-                setH(e);
-                dom.bind(window, 'mousemove', setH);
-                dom.bind(window, 'touchmove', setH);
-                dom.bind(window, 'mouseup', fieldUpH);
-                dom.bind(window, 'touchend', fieldUpH);
-            }
-
-            function fieldUpSV() {
-                dom.unbind(window, 'mousemove', setSV);
-                dom.unbind(window, 'touchmove', setSV);
-                dom.unbind(window, 'mouseup', fieldUpSV);
-                dom.unbind(window, 'touchend', fieldUpSV);
-                onFinish();
-            }
-
-            function fieldUpH() {
-                dom.unbind(window, 'mousemove', setH);
-                dom.unbind(window, 'touchmove', setH);
-                dom.unbind(window, 'mouseup', fieldUpH);
-                dom.unbind(window, 'touchend', fieldUpH);
-                onFinish();
-            }
-
-            function onBlur() {
-                var i = interpret(this.value);
-                if (i !== false) {
-                    _this.__color.__state = i;
-                    _this.setValue(_this.__color.toOriginal());
-                } else {
-                    this.value = _this.__color.toString();
-                }
-            }
-
-            function onFinish() {
-                if (_this.__onFinishChange) {
-                    _this.__onFinishChange.call(_this, _this.__color.toOriginal());
-                }
-            }
-            _this2.__saturation_field.appendChild(valueField);
-            _this2.__selector.appendChild(_this2.__field_knob);
-            _this2.__selector.appendChild(_this2.__saturation_field);
-            _this2.__selector.appendChild(_this2.__hue_field);
-            _this2.__hue_field.appendChild(_this2.__hue_knob);
-            _this2.domElement.appendChild(_this2.__input);
-            _this2.domElement.appendChild(_this2.__selector);
-            _this2.updateDisplay();
-
-            function setSV(e) {
-                if (e.type.indexOf('touch') === -1) {
-                    e.preventDefault();
-                }
-                var fieldRect = _this.__saturation_field.getBoundingClientRect();
-                var _ref = e.touches && e.touches[0] || e,
-                    clientX = _ref.clientX,
-                    clientY = _ref.clientY;
-                var s = (clientX - fieldRect.left) / (fieldRect.right - fieldRect.left);
-                var v = 1 - (clientY - fieldRect.top) / (fieldRect.bottom - fieldRect.top);
-                if (v > 1) {
-                    v = 1;
-                } else if (v < 0) {
-                    v = 0;
-                }
-                if (s > 1) {
-                    s = 1;
-                } else if (s < 0) {
-                    s = 0;
-                }
-                _this.__color.v = v;
-                _this.__color.s = s;
-                _this.setValue(_this.__color.toOriginal());
-                return false;
-            }
-
-            function setH(e) {
-                if (e.type.indexOf('touch') === -1) {
-                    e.preventDefault();
-                }
-                var fieldRect = _this.__hue_field.getBoundingClientRect();
-                var _ref2 = e.touches && e.touches[0] || e,
-                    clientY = _ref2.clientY;
-                var h = 1 - (clientY - fieldRect.top) / (fieldRect.bottom - fieldRect.top);
-                if (h > 1) {
-                    h = 1;
-                } else if (h < 0) {
-                    h = 0;
-                }
-                _this.__color.h = h * 360;
-                _this.setValue(_this.__color.toOriginal());
-                return false;
-            }
-            return _this2;
-        }
-        createClass(ColorController, [{
-            key: 'updateDisplay',
-            value: function updateDisplay() {
-                var i = interpret(this.getValue());
-                if (i !== false) {
-                    var mismatch = false;
-                    Common.each(Color.COMPONENTS, function(component) {
-                        if (!Common.isUndefined(i[component]) && !Common.isUndefined(this.__color.__state[component]) && i[component] !== this.__color.__state[component]) {
-                            mismatch = true;
-                            return {};
-                        }
-                    }, this);
-                    if (mismatch) {
-                        Common.extend(this.__color.__state, i);
-                    }
-                }
-                Common.extend(this.__temp.__state, this.__color.__state);
-                this.__temp.a = 1;
-                var flip = this.__color.v < 0.5 || this.__color.s > 0.5 ? 255 : 0;
-                var _flip = 255 - flip;
-                Common.extend(this.__field_knob.style, {
-                    marginLeft: 100 * this.__color.s - 7 + 'px',
-                    marginTop: 100 * (1 - this.__color.v) - 7 + 'px',
-                    backgroundColor: this.__temp.toHexString(),
-                    border: this.__field_knob_border + 'rgb(' + flip + ',' + flip + ',' + flip + ')'
-                });
-                this.__hue_knob.style.marginTop = (1 - this.__color.h / 360) * 100 + 'px';
-                this.__temp.s = 1;
-                this.__temp.v = 1;
-                linearGradient(this.__saturation_field, 'left', '#fff', this.__temp.toHexString());
-                this.__input.value = this.__color.toString();
-                Common.extend(this.__input.style, {
-                    backgroundColor: this.__color.toHexString(),
-                    color: 'rgb(' + flip + ',' + flip + ',' + flip + ')',
-                    textShadow: this.__input_textShadow + 'rgba(' + _flip + ',' + _flip + ',' + _flip + ',.7)'
-                });
-            }
-        }]);
-        return ColorController;
-    }(Controller);
-    var vendors = ['-moz-', '-o-', '-webkit-', '-ms-', ''];
-
-    function linearGradient(elem, x, a, b) {
-        elem.style.background = '';
-        Common.each(vendors, function(vendor) {
-            elem.style.cssText += 'background: ' + vendor + 'linear-gradient(' + x + ', ' + a + ' 0%, ' + b + ' 100%); ';
-        });
-    }
-
-    function hueGradient(elem) {
-        elem.style.background = '';
-        elem.style.cssText += 'background: -moz-linear-gradient(top,  #ff0000 0%, #ff00ff 17%, #0000ff 34%, #00ffff 50%, #00ff00 67%, #ffff00 84%, #ff0000 100%);';
-        elem.style.cssText += 'background: -webkit-linear-gradient(top,  #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);';
-        elem.style.cssText += 'background: -o-linear-gradient(top,  #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);';
-        elem.style.cssText += 'background: -ms-linear-gradient(top,  #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);';
-        elem.style.cssText += 'background: linear-gradient(top,  #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);';
-    }
-
-    var css = {
-        load: function load(url, indoc) {
-            var doc = indoc || document;
-            var link = doc.createElement('link');
-            link.type = 'text/css';
-            link.rel = 'stylesheet';
-            link.href = url;
-            doc.getElementsByTagName('head')[0].appendChild(link);
-        },
-        inject: function inject(cssContent, indoc) {
-            var doc = indoc || document;
-            var injected = document.createElement('style');
-            injected.type = 'text/css';
-            injected.innerHTML = cssContent;
-            var head = doc.getElementsByTagName('head')[0];
-            try {
-                head.appendChild(injected);
-            } catch (e) {}
-        }
-    };
-
-    var saveDialogContents = "<div id=\"dg-save\" class=\"dg dialogue\">\n\n  Here's the new load parameter for your <code>GUI</code>'s constructor:\n\n  <textarea id=\"dg-new-constructor\"></textarea>\n\n  <div id=\"dg-save-locally\">\n\n    <input id=\"dg-local-storage\" type=\"checkbox\"/> Automatically save\n    values to <code>localStorage</code> on exit.\n\n    <div id=\"dg-local-explain\">The values saved to <code>localStorage</code> will\n      override those passed to <code>dat.GUI</code>'s constructor. This makes it\n      easier to work incrementally, but <code>localStorage</code> is fragile,\n      and your friends may not see the same values you do.\n\n    </div>\n\n  </div>\n\n</div>";
-
-    var ControllerFactory = function ControllerFactory(object, property) {
-        var initialValue = object[property];
-        if (Common.isArray(arguments[2]) || Common.isObject(arguments[2])) {
-            return new OptionController(object, property, arguments[2]);
-        }
-        if (Common.isNumber(initialValue)) {
-            if (Common.isNumber(arguments[2]) && Common.isNumber(arguments[3])) {
-                if (Common.isNumber(arguments[4])) {
-                    return new NumberControllerSlider(object, property, arguments[2], arguments[3], arguments[4]);
-                }
-                return new NumberControllerSlider(object, property, arguments[2], arguments[3]);
-            }
-            if (Common.isNumber(arguments[4])) {
-                return new NumberControllerBox(object, property, { min: arguments[2], max: arguments[3], step: arguments[4] });
-            }
-            return new NumberControllerBox(object, property, { min: arguments[2], max: arguments[3] });
-        }
-        if (Common.isString(initialValue)) {
-            return new StringController(object, property);
-        }
-        if (Common.isFunction(initialValue)) {
-            return new FunctionController(object, property, '');
-        }
-        if (Common.isBoolean(initialValue)) {
-            return new BooleanController(object, property);
-        }
-        return null;
-    };
-
-    function requestAnimationFrame(callback) {
-        setTimeout(callback, 1000 / 60);
-    }
-    var requestAnimationFrame$1 = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || requestAnimationFrame;
-
-    var CenteredDiv = function() {
-        function CenteredDiv() {
-            classCallCheck(this, CenteredDiv);
-            this.backgroundElement = document.createElement('div');
-            Common.extend(this.backgroundElement.style, {
-                backgroundColor: 'rgba(0,0,0,0.8)',
-                top: 0,
-                left: 0,
-                display: 'none',
-                zIndex: '1000',
-                opacity: 0,
-                WebkitTransition: 'opacity 0.2s linear',
-                transition: 'opacity 0.2s linear'
-            });
-            dom.makeFullscreen(this.backgroundElement);
-            this.backgroundElement.style.position = 'fixed';
-            this.domElement = document.createElement('div');
-            Common.extend(this.domElement.style, {
-                position: 'fixed',
-                display: 'none',
-                zIndex: '1001',
-                opacity: 0,
-                WebkitTransition: '-webkit-transform 0.2s ease-out, opacity 0.2s linear',
-                transition: 'transform 0.2s ease-out, opacity 0.2s linear'
-            });
-            document.body.appendChild(this.backgroundElement);
-            document.body.appendChild(this.domElement);
-            var _this = this;
-            dom.bind(this.backgroundElement, 'click', function() {
-                _this.hide();
-            });
-        }
-        createClass(CenteredDiv, [{
-            key: 'show',
-            value: function show() {
-                var _this = this;
-                this.backgroundElement.style.display = 'block';
-                this.domElement.style.display = 'block';
-                this.domElement.style.opacity = 0;
-                this.domElement.style.webkitTransform = 'scale(1.1)';
-                this.layout();
-                Common.defer(function() {
-                    _this.backgroundElement.style.opacity = 1;
-                    _this.domElement.style.opacity = 1;
-                    _this.domElement.style.webkitTransform = 'scale(1)';
-                });
-            }
-        }, {
-            key: 'hide',
-            value: function hide() {
-                var _this = this;
-                var hide = function hide() {
-                    _this.domElement.style.display = 'none';
-                    _this.backgroundElement.style.display = 'none';
-                    dom.unbind(_this.domElement, 'webkitTransitionEnd', hide);
-                    dom.unbind(_this.domElement, 'transitionend', hide);
-                    dom.unbind(_this.domElement, 'oTransitionEnd', hide);
-                };
-                dom.bind(this.domElement, 'webkitTransitionEnd', hide);
-                dom.bind(this.domElement, 'transitionend', hide);
-                dom.bind(this.domElement, 'oTransitionEnd', hide);
-                this.backgroundElement.style.opacity = 0;
-                this.domElement.style.opacity = 0;
-                this.domElement.style.webkitTransform = 'scale(1.1)';
-            }
-        }, {
-            key: 'layout',
-            value: function layout() {
-                this.domElement.style.left = window.innerWidth / 2 - dom.getWidth(this.domElement) / 2 + 'px';
-                this.domElement.style.top = window.innerHeight / 2 - dom.getHeight(this.domElement) / 2 + 'px';
-            }
-        }]);
-        return CenteredDiv;
-    }();
-
-    var styleSheet = ___$insertStyle(".dg ul{list-style:none;margin:0;padding:0;width:100%;clear:both}.dg.ac{position:fixed;top:0;left:0;right:0;height:0;z-index:0}.dg:not(.ac) .main{overflow:hidden}.dg.main{-webkit-transition:opacity .1s linear;-o-transition:opacity .1s linear;-moz-transition:opacity .1s linear;transition:opacity .1s linear}.dg.main.taller-than-window{overflow-y:auto}.dg.main.taller-than-window .close-button{opacity:1;margin-top:-1px;border-top:1px solid #2c2c2c}.dg.main ul.closed .close-button{opacity:1 !important}.dg.main:hover .close-button,.dg.main .close-button.drag{opacity:1}.dg.main .close-button{-webkit-transition:opacity .1s linear;-o-transition:opacity .1s linear;-moz-transition:opacity .1s linear;transition:opacity .1s linear;border:0;line-height:19px;height:20px;cursor:pointer;text-align:center;background-color:#000}.dg.main .close-button.close-top{position:relative}.dg.main .close-button.close-bottom{position:absolute}.dg.main .close-button:hover{background-color:#111}.dg.a{float:right;margin-right:15px;overflow-y:visible}.dg.a.has-save>ul.close-top{margin-top:0}.dg.a.has-save>ul.close-bottom{margin-top:27px}.dg.a.has-save>ul.closed{margin-top:0}.dg.a .save-row{top:0;z-index:1002}.dg.a .save-row.close-top{position:relative}.dg.a .save-row.close-bottom{position:fixed}.dg li{-webkit-transition:height .1s ease-out;-o-transition:height .1s ease-out;-moz-transition:height .1s ease-out;transition:height .1s ease-out;-webkit-transition:overflow .1s linear;-o-transition:overflow .1s linear;-moz-transition:overflow .1s linear;transition:overflow .1s linear}.dg li:not(.folder){cursor:auto;height:27px;line-height:27px;padding:0 4px 0 5px}.dg li.folder{padding:0;border-left:4px solid rgba(0,0,0,0)}.dg li.title{cursor:pointer;margin-left:-4px}.dg .closed li:not(.title),.dg .closed ul li,.dg .closed ul li>*{height:0;overflow:hidden;border:0}.dg .cr{clear:both;padding-left:3px;height:27px;overflow:hidden}.dg .property-name{cursor:default;float:left;clear:left;width:40%;overflow:hidden;text-overflow:ellipsis}.dg .c{float:left;width:60%;position:relative}.dg .c input[type=text]{border:0;margin-top:4px;padding:3px;width:100%;float:right}.dg .has-slider input[type=text]{width:30%;margin-left:0}.dg .slider{float:left;width:66%;margin-left:-5px;margin-right:0;height:19px;margin-top:4px}.dg .slider-fg{height:100%}.dg .c input[type=checkbox]{margin-top:7px}.dg .c select{margin-top:5px}.dg .cr.function,.dg .cr.function .property-name,.dg .cr.function *,.dg .cr.boolean,.dg .cr.boolean *{cursor:pointer}.dg .cr.color{overflow:visible}.dg .selector{display:none;position:absolute;margin-left:-9px;margin-top:23px;z-index:10}.dg .c:hover .selector,.dg .selector.drag{display:block}.dg li.save-row{padding:0}.dg li.save-row .button{display:inline-block;padding:0px 6px}.dg.dialogue{background-color:#222;width:460px;padding:15px;font-size:13px;line-height:15px}#dg-new-constructor{padding:10px;color:#222;font-family:Monaco, monospace;font-size:10px;border:0;resize:none;box-shadow:inset 1px 1px 1px #888;word-wrap:break-word;margin:12px 0;display:block;width:440px;overflow-y:scroll;height:100px;position:relative}#dg-local-explain{display:none;font-size:11px;line-height:17px;border-radius:3px;background-color:#333;padding:8px;margin-top:10px}#dg-local-explain code{font-size:10px}#dat-gui-save-locally{display:none}.dg{color:#eee;font:11px 'Lucida Grande', sans-serif;text-shadow:0 -1px 0 #111}.dg.main::-webkit-scrollbar{width:5px;background:#1a1a1a}.dg.main::-webkit-scrollbar-corner{height:0;display:none}.dg.main::-webkit-scrollbar-thumb{border-radius:5px;background:#676767}.dg li:not(.folder){background:#1a1a1a;border-bottom:1px solid #2c2c2c}.dg li.save-row{line-height:25px;background:#dad5cb;border:0}.dg li.save-row select{margin-left:5px;width:108px}.dg li.save-row .button{margin-left:5px;margin-top:1px;border-radius:2px;font-size:9px;line-height:7px;padding:4px 4px 5px 4px;background:#c5bdad;color:#fff;text-shadow:0 1px 0 #b0a58f;box-shadow:0 -1px 0 #b0a58f;cursor:pointer}.dg li.save-row .button.gears{background:#c5bdad url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAANCAYAAAB/9ZQ7AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAQJJREFUeNpiYKAU/P//PwGIC/ApCABiBSAW+I8AClAcgKxQ4T9hoMAEUrxx2QSGN6+egDX+/vWT4e7N82AMYoPAx/evwWoYoSYbACX2s7KxCxzcsezDh3evFoDEBYTEEqycggWAzA9AuUSQQgeYPa9fPv6/YWm/Acx5IPb7ty/fw+QZblw67vDs8R0YHyQhgObx+yAJkBqmG5dPPDh1aPOGR/eugW0G4vlIoTIfyFcA+QekhhHJhPdQxbiAIguMBTQZrPD7108M6roWYDFQiIAAv6Aow/1bFwXgis+f2LUAynwoIaNcz8XNx3Dl7MEJUDGQpx9gtQ8YCueB+D26OECAAQDadt7e46D42QAAAABJRU5ErkJggg==) 2px 1px no-repeat;height:7px;width:8px}.dg li.save-row .button:hover{background-color:#bab19e;box-shadow:0 -1px 0 #b0a58f}.dg li.folder{border-bottom:0}.dg li.title{padding-left:16px;background:#000 url(data:image/gif;base64,R0lGODlhBQAFAJEAAP////Pz8////////yH5BAEAAAIALAAAAAAFAAUAAAIIlI+hKgFxoCgAOw==) 6px 10px no-repeat;cursor:pointer;border-bottom:1px solid rgba(255,255,255,0.2)}.dg .closed li.title{background-image:url(data:image/gif;base64,R0lGODlhBQAFAJEAAP////Pz8////////yH5BAEAAAIALAAAAAAFAAUAAAIIlGIWqMCbWAEAOw==)}.dg .cr.boolean{border-left:3px solid #806787}.dg .cr.color{border-left:3px solid}.dg .cr.function{border-left:3px solid #e61d5f}.dg .cr.number{border-left:3px solid #2FA1D6}.dg .cr.number input[type=text]{color:#2FA1D6}.dg .cr.string{border-left:3px solid #1ed36f}.dg .cr.string input[type=text]{color:#1ed36f}.dg .cr.function:hover,.dg .cr.boolean:hover{background:#111}.dg .c input[type=text]{background:#303030;outline:none}.dg .c input[type=text]:hover{background:#3c3c3c}.dg .c input[type=text]:focus{background:#494949;color:#fff}.dg .c .slider{background:#303030;cursor:ew-resize}.dg .c .slider-fg{background:#2FA1D6;max-width:100%}.dg .c .slider:hover{background:#3c3c3c}.dg .c .slider:hover .slider-fg{background:#44abda}\n");
-
-    css.inject(styleSheet);
-    var CSS_NAMESPACE = 'dg';
-    var HIDE_KEY_CODE = 72;
-    var CLOSE_BUTTON_HEIGHT = 20;
-    var DEFAULT_DEFAULT_PRESET_NAME = 'Default';
-    var SUPPORTS_LOCAL_STORAGE = function() {
-        try {
-            return !!window.localStorage;
-        } catch (e) {
-            return false;
-        }
-    }();
-    var SAVE_DIALOGUE = void 0;
-    var autoPlaceVirgin = true;
-    var autoPlaceContainer = void 0;
-    var hide = false;
-    var hideableGuis = [];
-    var GUI = function GUI(pars) {
-        var _this = this;
-        var params = pars || {};
-        this.domElement = document.createElement('div');
-        this.__ul = document.createElement('ul');
-        this.domElement.appendChild(this.__ul);
-        dom.addClass(this.domElement, CSS_NAMESPACE);
-        this.__folders = {};
-        this.__controllers = [];
-        this.__rememberedObjects = [];
-        this.__rememberedObjectIndecesToControllers = [];
-        this.__listening = [];
-        params = Common.defaults(params, {
-            closeOnTop: false,
-            autoPlace: true,
-            width: GUI.DEFAULT_WIDTH
-        });
-        params = Common.defaults(params, {
-            resizable: params.autoPlace,
-            hideable: params.autoPlace
-        });
-        if (!Common.isUndefined(params.load)) {
-            if (params.preset) {
-                params.load.preset = params.preset;
-            }
-        } else {
-            params.load = { preset: DEFAULT_DEFAULT_PRESET_NAME };
-        }
-        if (Common.isUndefined(params.parent) && params.hideable) {
-            hideableGuis.push(this);
-        }
-        params.resizable = Common.isUndefined(params.parent) && params.resizable;
-        if (params.autoPlace && Common.isUndefined(params.scrollable)) {
-            params.scrollable = true;
-        }
-        var useLocalStorage = SUPPORTS_LOCAL_STORAGE && localStorage.getItem(getLocalStorageHash(this, 'isLocal')) === 'true';
-        var saveToLocalStorage = void 0;
-        Object.defineProperties(this, {
-            parent: {
-                get: function get$$1() {
-                    return params.parent;
-                }
-            },
-            scrollable: {
-                get: function get$$1() {
-                    return params.scrollable;
-                }
-            },
-            autoPlace: {
-                get: function get$$1() {
-                    return params.autoPlace;
-                }
-            },
-            closeOnTop: {
-                get: function get$$1() {
-                    return params.closeOnTop;
-                }
-            },
-            preset: {
-                get: function get$$1() {
-                    if (_this.parent) {
-                        return _this.getRoot().preset;
-                    }
-                    return params.load.preset;
-                },
-                set: function set$$1(v) {
-                    if (_this.parent) {
-                        _this.getRoot().preset = v;
-                    } else {
-                        params.load.preset = v;
-                    }
-                    setPresetSelectIndex(this);
-                    _this.revert();
-                }
-            },
-            width: {
-                get: function get$$1() {
-                    return params.width;
-                },
-                set: function set$$1(v) {
-                    params.width = v;
-                    setWidth(_this, v);
-                }
-            },
-            name: {
-                get: function get$$1() {
-                    return params.name;
-                },
-                set: function set$$1(v) {
-                    params.name = v;
-                    if (titleRowName) {
-                        titleRowName.innerHTML = params.name;
-                    }
-                }
-            },
-            closed: {
-                get: function get$$1() {
-                    return params.closed;
-                },
-                set: function set$$1(v) {
-                    params.closed = v;
-                    if (params.closed) {
-                        dom.addClass(_this.__ul, GUI.CLASS_CLOSED);
-                    } else {
-                        dom.removeClass(_this.__ul, GUI.CLASS_CLOSED);
-                    }
-                    this.onResize();
-                    if (_this.__closeButton) {
-                        _this.__closeButton.innerHTML = v ? GUI.TEXT_OPEN : GUI.TEXT_CLOSED;
-                    }
-                }
-            },
-            load: {
-                get: function get$$1() {
-                    return params.load;
-                }
-            },
-            useLocalStorage: {
-                get: function get$$1() {
-                    return useLocalStorage;
-                },
-                set: function set$$1(bool) {
-                    if (SUPPORTS_LOCAL_STORAGE) {
-                        useLocalStorage = bool;
-                        if (bool) {
-                            dom.bind(window, 'unload', saveToLocalStorage);
-                        } else {
-                            dom.unbind(window, 'unload', saveToLocalStorage);
-                        }
-                        localStorage.setItem(getLocalStorageHash(_this, 'isLocal'), bool);
-                    }
-                }
-            }
-        });
-        if (Common.isUndefined(params.parent)) {
-            params.closed = false;
-            dom.addClass(this.domElement, GUI.CLASS_MAIN);
-            dom.makeSelectable(this.domElement, false);
-            if (SUPPORTS_LOCAL_STORAGE) {
-                if (useLocalStorage) {
-                    _this.useLocalStorage = true;
-                    var savedGui = localStorage.getItem(getLocalStorageHash(this, 'gui'));
-                    if (savedGui) {
-                        params.load = JSON.parse(savedGui);
-                    }
-                }
-            }
-            this.__closeButton = document.createElement('div');
-            this.__closeButton.innerHTML = GUI.TEXT_CLOSED;
-            dom.addClass(this.__closeButton, GUI.CLASS_CLOSE_BUTTON);
-            if (params.closeOnTop) {
-                dom.addClass(this.__closeButton, GUI.CLASS_CLOSE_TOP);
-                this.domElement.insertBefore(this.__closeButton, this.domElement.childNodes[0]);
-            } else {
-                dom.addClass(this.__closeButton, GUI.CLASS_CLOSE_BOTTOM);
-                this.domElement.appendChild(this.__closeButton);
-            }
-            dom.bind(this.__closeButton, 'click', function() {
-                _this.closed = !_this.closed;
-            });
-        } else {
-            if (params.closed === undefined) {
-                params.closed = true;
-            }
-            var _titleRowName = document.createTextNode(params.name);
-            dom.addClass(_titleRowName, 'controller-name');
-            var titleRow = addRow(_this, _titleRowName);
-            var onClickTitle = function onClickTitle(e) {
-                e.preventDefault();
-                _this.closed = !_this.closed;
-                return false;
-            };
-            dom.addClass(this.__ul, GUI.CLASS_CLOSED);
-            dom.addClass(titleRow, 'title');
-            dom.bind(titleRow, 'click', onClickTitle);
-            if (!params.closed) {
-                this.closed = false;
-            }
-        }
-        if (params.autoPlace) {
-            if (Common.isUndefined(params.parent)) {
-                if (autoPlaceVirgin) {
-                    autoPlaceContainer = document.createElement('div');
-                    dom.addClass(autoPlaceContainer, CSS_NAMESPACE);
-                    dom.addClass(autoPlaceContainer, GUI.CLASS_AUTO_PLACE_CONTAINER);
-                    document.body.appendChild(autoPlaceContainer);
-                    autoPlaceVirgin = false;
-                }
-                autoPlaceContainer.appendChild(this.domElement);
-                dom.addClass(this.domElement, GUI.CLASS_AUTO_PLACE);
-            }
-            if (!this.parent) {
-                setWidth(_this, params.width);
-            }
-        }
-        this.__resizeHandler = function() {
-            _this.onResizeDebounced();
-        };
-        dom.bind(window, 'resize', this.__resizeHandler);
-        dom.bind(this.__ul, 'webkitTransitionEnd', this.__resizeHandler);
-        dom.bind(this.__ul, 'transitionend', this.__resizeHandler);
-        dom.bind(this.__ul, 'oTransitionEnd', this.__resizeHandler);
-        this.onResize();
-        if (params.resizable) {
-            addResizeHandle(this);
-        }
-        saveToLocalStorage = function saveToLocalStorage() {
-            if (SUPPORTS_LOCAL_STORAGE && localStorage.getItem(getLocalStorageHash(_this, 'isLocal')) === 'true') {
-                localStorage.setItem(getLocalStorageHash(_this, 'gui'), JSON.stringify(_this.getSaveObject()));
-            }
-        };
-        this.saveToLocalStorageIfPossible = saveToLocalStorage;
-
-        function resetWidth() {
-            var root = _this.getRoot();
-            root.width += 1;
-            Common.defer(function() {
-                root.width -= 1;
-            });
-        }
-        if (!params.parent) {
-            resetWidth();
-        }
-    };
-    GUI.toggleHide = function() {
-        hide = !hide;
-        Common.each(hideableGuis, function(gui) {
-            gui.domElement.style.display = hide ? 'none' : '';
-        });
-    };
-    GUI.CLASS_AUTO_PLACE = 'a';
-    GUI.CLASS_AUTO_PLACE_CONTAINER = 'ac';
-    GUI.CLASS_MAIN = 'main';
-    GUI.CLASS_CONTROLLER_ROW = 'cr';
-    GUI.CLASS_TOO_TALL = 'taller-than-window';
-    GUI.CLASS_CLOSED = 'closed';
-    GUI.CLASS_CLOSE_BUTTON = 'close-button';
-    GUI.CLASS_CLOSE_TOP = 'close-top';
-    GUI.CLASS_CLOSE_BOTTOM = 'close-bottom';
-    GUI.CLASS_DRAG = 'drag';
-    GUI.DEFAULT_WIDTH = 245;
-    GUI.TEXT_CLOSED = 'Close Controls';
-    GUI.TEXT_OPEN = 'Open Controls';
-    GUI._keydownHandler = function(e) {
-        if (document.activeElement.type !== 'text' && (e.which === HIDE_KEY_CODE || e.keyCode === HIDE_KEY_CODE)) {
-            GUI.toggleHide();
-        }
-    };
-    dom.bind(window, 'keydown', GUI._keydownHandler, false);
-    Common.extend(GUI.prototype, {
-        add: function add(object, property) {
-            return _add(this, object, property, {
-                factoryArgs: Array.prototype.slice.call(arguments, 2)
-            });
-        },
-        addColor: function addColor(object, property) {
-            return _add(this, object, property, {
-                color: true
-            });
-        },
-        remove: function remove(controller) {
-            this.__ul.removeChild(controller.__li);
-            this.__controllers.splice(this.__controllers.indexOf(controller), 1);
-            var _this = this;
-            Common.defer(function() {
-                _this.onResize();
-            });
-        },
-        destroy: function destroy() {
-            if (this.parent) {
-                throw new Error('Only the root GUI should be removed with .destroy(). ' + 'For subfolders, use gui.removeFolder(folder) instead.');
-            }
-            if (this.autoPlace) {
-                autoPlaceContainer.removeChild(this.domElement);
-            }
-            var _this = this;
-            Common.each(this.__folders, function(subfolder) {
-                _this.removeFolder(subfolder);
-            });
-            dom.unbind(window, 'keydown', GUI._keydownHandler, false);
-            removeListeners(this);
-        },
-        addFolder: function addFolder(name) {
-            if (this.__folders[name] !== undefined) {
-                throw new Error('You already have a folder in this GUI by the' + ' name "' + name + '"');
-            }
-            var newGuiParams = { name: name, parent: this };
-            newGuiParams.autoPlace = this.autoPlace;
-            if (this.load &&
-                this.load.folders &&
-                this.load.folders[name]) {
-                newGuiParams.closed = this.load.folders[name].closed;
-                newGuiParams.load = this.load.folders[name];
-            }
-            var gui = new GUI(newGuiParams);
-            this.__folders[name] = gui;
-            var li = addRow(this, gui.domElement);
-            dom.addClass(li, 'folder');
-            return gui;
-        },
-        removeFolder: function removeFolder(folder) {
-            this.__ul.removeChild(folder.domElement.parentElement);
-            delete this.__folders[folder.name];
-            if (this.load &&
-                this.load.folders &&
-                this.load.folders[folder.name]) {
-                delete this.load.folders[folder.name];
-            }
-            removeListeners(folder);
-            var _this = this;
-            Common.each(folder.__folders, function(subfolder) {
-                folder.removeFolder(subfolder);
-            });
-            Common.defer(function() {
-                _this.onResize();
-            });
-        },
-        open: function open() {
-            this.closed = false;
-        },
-        close: function close() {
-            this.closed = true;
-        },
-        onResize: function onResize() {
-            var root = this.getRoot();
-            if (root.scrollable) {
-                var top = dom.getOffset(root.__ul).top;
-                var h = 0;
-                Common.each(root.__ul.childNodes, function(node) {
-                    if (!(root.autoPlace && node === root.__save_row)) {
-                        h += dom.getHeight(node);
-                    }
-                });
-                if (window.innerHeight - top - CLOSE_BUTTON_HEIGHT < h) {
-                    dom.addClass(root.domElement, GUI.CLASS_TOO_TALL);
-                    root.__ul.style.height = window.innerHeight - top - CLOSE_BUTTON_HEIGHT + 'px';
-                } else {
-                    dom.removeClass(root.domElement, GUI.CLASS_TOO_TALL);
-                    root.__ul.style.height = 'auto';
-                }
-            }
-            if (root.__resize_handle) {
-                Common.defer(function() {
-                    root.__resize_handle.style.height = root.__ul.offsetHeight + 'px';
-                });
-            }
-            if (root.__closeButton) {
-                root.__closeButton.style.width = root.width + 'px';
-            }
-        },
-        onResizeDebounced: Common.debounce(function() {
-            this.onResize();
-        }, 50),
-        remember: function remember() {
-            if (Common.isUndefined(SAVE_DIALOGUE)) {
-                SAVE_DIALOGUE = new CenteredDiv();
-                SAVE_DIALOGUE.domElement.innerHTML = saveDialogContents;
-            }
-            if (this.parent) {
-                throw new Error('You can only call remember on a top level GUI.');
-            }
-            var _this = this;
-            Common.each(Array.prototype.slice.call(arguments), function(object) {
-                if (_this.__rememberedObjects.length === 0) {
-                    addSaveMenu(_this);
-                }
-                if (_this.__rememberedObjects.indexOf(object) === -1) {
-                    _this.__rememberedObjects.push(object);
-                }
-            });
-            if (this.autoPlace) {
-                setWidth(this, this.width);
-            }
-        },
-        getRoot: function getRoot() {
-            var gui = this;
-            while (gui.parent) {
-                gui = gui.parent;
-            }
-            return gui;
-        },
-        getSaveObject: function getSaveObject() {
-            var toReturn = this.load;
-            toReturn.closed = this.closed;
-            if (this.__rememberedObjects.length > 0) {
-                toReturn.preset = this.preset;
-                if (!toReturn.remembered) {
-                    toReturn.remembered = {};
-                }
-                toReturn.remembered[this.preset] = getCurrentPreset(this);
-            }
-            toReturn.folders = {};
-            Common.each(this.__folders, function(element, key) {
-                toReturn.folders[key] = element.getSaveObject();
-            });
-            return toReturn;
-        },
-        save: function save() {
-            if (!this.load.remembered) {
-                this.load.remembered = {};
-            }
-            this.load.remembered[this.preset] = getCurrentPreset(this);
-            markPresetModified(this, false);
-            this.saveToLocalStorageIfPossible();
-        },
-        saveAs: function saveAs(presetName) {
-            if (!this.load.remembered) {
-                this.load.remembered = {};
-                this.load.remembered[DEFAULT_DEFAULT_PRESET_NAME] = getCurrentPreset(this, true);
-            }
-            this.load.remembered[presetName] = getCurrentPreset(this);
-            this.preset = presetName;
-            addPresetOption(this, presetName, true);
-            this.saveToLocalStorageIfPossible();
-        },
-        revert: function revert(gui) {
-            Common.each(this.__controllers, function(controller) {
-                if (!this.getRoot().load.remembered) {
-                    controller.setValue(controller.initialValue);
-                } else {
-                    recallSavedValue(gui || this.getRoot(), controller);
-                }
-                if (controller.__onFinishChange) {
-                    controller.__onFinishChange.call(controller, controller.getValue());
-                }
-            }, this);
-            Common.each(this.__folders, function(folder) {
-                folder.revert(folder);
-            });
-            if (!gui) {
-                markPresetModified(this.getRoot(), false);
-            }
-        },
-        listen: function listen(controller) {
-            var init = this.__listening.length === 0;
-            this.__listening.push(controller);
-            if (init) {
-                updateDisplays(this.__listening);
-            }
-        },
-        updateDisplay: function updateDisplay() {
-            Common.each(this.__controllers, function(controller) {
-                controller.updateDisplay();
-            });
-            Common.each(this.__folders, function(folder) {
-                folder.updateDisplay();
-            });
-        }
-    });
-
-    function addRow(gui, newDom, liBefore) {
-        var li = document.createElement('li');
-        if (newDom) {
-            li.appendChild(newDom);
-        }
-        if (liBefore) {
-            gui.__ul.insertBefore(li, liBefore);
-        } else {
-            gui.__ul.appendChild(li);
-        }
-        gui.onResize();
-        return li;
-    }
-
-    function removeListeners(gui) {
-        dom.unbind(window, 'resize', gui.__resizeHandler);
-        if (gui.saveToLocalStorageIfPossible) {
-            dom.unbind(window, 'unload', gui.saveToLocalStorageIfPossible);
-        }
-    }
-
-    function markPresetModified(gui, modified) {
-        var opt = gui.__preset_select[gui.__preset_select.selectedIndex];
-        if (modified) {
-            opt.innerHTML = opt.value + '*';
-        } else {
-            opt.innerHTML = opt.value;
-        }
-    }
-
-    function augmentController(gui, li, controller) {
-        controller.__li = li;
-        controller.__gui = gui;
-        Common.extend(controller, {
-            options: function options(_options) {
-                if (arguments.length > 1) {
-                    var nextSibling = controller.__li.nextElementSibling;
-                    controller.remove();
-                    return _add(gui, controller.object, controller.property, {
-                        before: nextSibling,
-                        factoryArgs: [Common.toArray(arguments)]
-                    });
-                }
-                if (Common.isArray(_options) || Common.isObject(_options)) {
-                    var _nextSibling = controller.__li.nextElementSibling;
-                    controller.remove();
-                    return _add(gui, controller.object, controller.property, {
-                        before: _nextSibling,
-                        factoryArgs: [_options]
-                    });
-                }
-            },
-            name: function name(_name) {
-                controller.__li.firstElementChild.firstElementChild.innerHTML = _name;
-                return controller;
-            },
-            listen: function listen() {
-                controller.__gui.listen(controller);
-                return controller;
-            },
-            remove: function remove() {
-                controller.__gui.remove(controller);
-                return controller;
-            }
-        });
-        if (controller instanceof NumberControllerSlider) {
-            var box = new NumberControllerBox(controller.object, controller.property, { min: controller.__min, max: controller.__max, step: controller.__step });
-            Common.each(['updateDisplay', 'onChange', 'onFinishChange', 'step'], function(method) {
-                var pc = controller[method];
-                var pb = box[method];
-                controller[method] = box[method] = function() {
-                    var args = Array.prototype.slice.call(arguments);
-                    pb.apply(box, args);
-                    return pc.apply(controller, args);
-                };
-            });
-            dom.addClass(li, 'has-slider');
-            controller.domElement.insertBefore(box.domElement, controller.domElement.firstElementChild);
-        } else if (controller instanceof NumberControllerBox) {
-            var r = function r(returned) {
-                if (Common.isNumber(controller.__min) && Common.isNumber(controller.__max)) {
-                    var oldName = controller.__li.firstElementChild.firstElementChild.innerHTML;
-                    var wasListening = controller.__gui.__listening.indexOf(controller) > -1;
-                    controller.remove();
-                    var newController = _add(gui, controller.object, controller.property, {
-                        before: controller.__li.nextElementSibling,
-                        factoryArgs: [controller.__min, controller.__max, controller.__step]
-                    });
-                    newController.name(oldName);
-                    if (wasListening) newController.listen();
-                    return newController;
-                }
-                return returned;
-            };
-            controller.min = Common.compose(r, controller.min);
-            controller.max = Common.compose(r, controller.max);
-        } else if (controller instanceof BooleanController) {
-            dom.bind(li, 'click', function() {
-                dom.fakeEvent(controller.__checkbox, 'click');
-            });
-            dom.bind(controller.__checkbox, 'click', function(e) {
-                e.stopPropagation();
-            });
-        } else if (controller instanceof FunctionController) {
-            dom.bind(li, 'click', function() {
-                dom.fakeEvent(controller.__button, 'click');
-            });
-            dom.bind(li, 'mouseover', function() {
-                dom.addClass(controller.__button, 'hover');
-            });
-            dom.bind(li, 'mouseout', function() {
-                dom.removeClass(controller.__button, 'hover');
-            });
-        } else if (controller instanceof ColorController) {
-            dom.addClass(li, 'color');
-            controller.updateDisplay = Common.compose(function(val) {
-                li.style.borderLeftColor = controller.__color.toString();
-                return val;
-            }, controller.updateDisplay);
-            controller.updateDisplay();
-        }
-        controller.setValue = Common.compose(function(val) {
-            if (gui.getRoot().__preset_select && controller.isModified()) {
-                markPresetModified(gui.getRoot(), true);
-            }
-            return val;
-        }, controller.setValue);
-    }
-
-    function recallSavedValue(gui, controller) {
-        var root = gui.getRoot();
-        var matchedIndex = root.__rememberedObjects.indexOf(controller.object);
-        if (matchedIndex !== -1) {
-            var controllerMap = root.__rememberedObjectIndecesToControllers[matchedIndex];
-            if (controllerMap === undefined) {
-                controllerMap = {};
-                root.__rememberedObjectIndecesToControllers[matchedIndex] = controllerMap;
-            }
-            controllerMap[controller.property] = controller;
-            if (root.load && root.load.remembered) {
-                var presetMap = root.load.remembered;
-                var preset = void 0;
-                if (presetMap[gui.preset]) {
-                    preset = presetMap[gui.preset];
-                } else if (presetMap[DEFAULT_DEFAULT_PRESET_NAME]) {
-                    preset = presetMap[DEFAULT_DEFAULT_PRESET_NAME];
-                } else {
-                    return;
-                }
-                if (preset[matchedIndex] && preset[matchedIndex][controller.property] !== undefined) {
-                    var value = preset[matchedIndex][controller.property];
-                    controller.initialValue = value;
-                    controller.setValue(value);
-                }
-            }
-        }
-    }
-
-    function _add(gui, object, property, params) {
-        if (object[property] === undefined) {
-            throw new Error('Object "' + object + '" has no property "' + property + '"');
-        }
-        var controller = void 0;
-        if (params.color) {
-            controller = new ColorController(object, property);
-        } else {
-            var factoryArgs = [object, property].concat(params.factoryArgs);
-            controller = ControllerFactory.apply(gui, factoryArgs);
-        }
-        if (params.before instanceof Controller) {
-            params.before = params.before.__li;
-        }
-        recallSavedValue(gui, controller);
-        dom.addClass(controller.domElement, 'c');
-        var name = document.createElement('span');
-        dom.addClass(name, 'property-name');
-        name.innerHTML = controller.property;
-        var container = document.createElement('div');
-        container.appendChild(name);
-        container.appendChild(controller.domElement);
-        var li = addRow(gui, container, params.before);
-        dom.addClass(li, GUI.CLASS_CONTROLLER_ROW);
-        if (controller instanceof ColorController) {
-            dom.addClass(li, 'color');
-        } else {
-            dom.addClass(li, _typeof(controller.getValue()));
-        }
-        augmentController(gui, li, controller);
-        gui.__controllers.push(controller);
-        return controller;
-    }
-
-    function getLocalStorageHash(gui, key) {
-        return document.location.href + '.' + key;
-    }
-
-    function addPresetOption(gui, name, setSelected) {
-        var opt = document.createElement('option');
-        opt.innerHTML = name;
-        opt.value = name;
-        gui.__preset_select.appendChild(opt);
-        if (setSelected) {
-            gui.__preset_select.selectedIndex = gui.__preset_select.length - 1;
-        }
-    }
-
-    function showHideExplain(gui, explain) {
-        explain.style.display = gui.useLocalStorage ? 'block' : 'none';
-    }
-
-    function addSaveMenu(gui) {
-        var div = gui.__save_row = document.createElement('li');
-        dom.addClass(gui.domElement, 'has-save');
-        gui.__ul.insertBefore(div, gui.__ul.firstChild);
-        dom.addClass(div, 'save-row');
-        var gears = document.createElement('span');
-        gears.innerHTML = '&nbsp;';
-        dom.addClass(gears, 'button gears');
-        var button = document.createElement('span');
-        button.innerHTML = 'Save';
-        dom.addClass(button, 'button');
-        dom.addClass(button, 'save');
-        var button2 = document.createElement('span');
-        button2.innerHTML = 'New';
-        dom.addClass(button2, 'button');
-        dom.addClass(button2, 'save-as');
-        var button3 = document.createElement('span');
-        button3.innerHTML = 'Revert';
-        dom.addClass(button3, 'button');
-        dom.addClass(button3, 'revert');
-        var select = gui.__preset_select = document.createElement('select');
-        if (gui.load && gui.load.remembered) {
-            Common.each(gui.load.remembered, function(value, key) {
-                addPresetOption(gui, key, key === gui.preset);
-            });
-        } else {
-            addPresetOption(gui, DEFAULT_DEFAULT_PRESET_NAME, false);
-        }
-        dom.bind(select, 'change', function() {
-            for (var index = 0; index < gui.__preset_select.length; index++) {
-                gui.__preset_select[index].innerHTML = gui.__preset_select[index].value;
-            }
-            gui.preset = this.value;
-        });
-        div.appendChild(select);
-        div.appendChild(gears);
-        div.appendChild(button);
-        div.appendChild(button2);
-        div.appendChild(button3);
-        if (SUPPORTS_LOCAL_STORAGE) {
-            var explain = document.getElementById('dg-local-explain');
-            var localStorageCheckBox = document.getElementById('dg-local-storage');
-            var saveLocally = document.getElementById('dg-save-locally');
-            saveLocally.style.display = 'block';
-            if (localStorage.getItem(getLocalStorageHash(gui, 'isLocal')) === 'true') {
-                localStorageCheckBox.setAttribute('checked', 'checked');
-            }
-            showHideExplain(gui, explain);
-            dom.bind(localStorageCheckBox, 'change', function() {
-                gui.useLocalStorage = !gui.useLocalStorage;
-                showHideExplain(gui, explain);
-            });
-        }
-        var newConstructorTextArea = document.getElementById('dg-new-constructor');
-        dom.bind(newConstructorTextArea, 'keydown', function(e) {
-            if (e.metaKey && (e.which === 67 || e.keyCode === 67)) {
-                SAVE_DIALOGUE.hide();
-            }
-        });
-        dom.bind(gears, 'click', function() {
-            newConstructorTextArea.innerHTML = JSON.stringify(gui.getSaveObject(), undefined, 2);
-            SAVE_DIALOGUE.show();
-            newConstructorTextArea.focus();
-            newConstructorTextArea.select();
-        });
-        dom.bind(button, 'click', function() {
-            gui.save();
-        });
-        dom.bind(button2, 'click', function() {
-            var presetName = prompt('Enter a new preset name.');
-            if (presetName) {
-                gui.saveAs(presetName);
-            }
-        });
-        dom.bind(button3, 'click', function() {
-            gui.revert();
-        });
-    }
-
-    function addResizeHandle(gui) {
-        var pmouseX = void 0;
-        gui.__resize_handle = document.createElement('div');
-        Common.extend(gui.__resize_handle.style, {
-            width: '6px',
-            marginLeft: '-3px',
-            height: '200px',
-            cursor: 'ew-resize',
-            position: 'absolute'
-        });
-
-        function drag(e) {
-            e.preventDefault();
-            gui.width += pmouseX - e.clientX;
-            gui.onResize();
-            pmouseX = e.clientX;
-            return false;
-        }
-
-        function dragStop() {
-            dom.removeClass(gui.__closeButton, GUI.CLASS_DRAG);
-            dom.unbind(window, 'mousemove', drag);
-            dom.unbind(window, 'mouseup', dragStop);
-        }
-
-        function dragStart(e) {
-            e.preventDefault();
-            pmouseX = e.clientX;
-            dom.addClass(gui.__closeButton, GUI.CLASS_DRAG);
-            dom.bind(window, 'mousemove', drag);
-            dom.bind(window, 'mouseup', dragStop);
-            return false;
-        }
-        dom.bind(gui.__resize_handle, 'mousedown', dragStart);
-        dom.bind(gui.__closeButton, 'mousedown', dragStart);
-        gui.domElement.insertBefore(gui.__resize_handle, gui.domElement.firstElementChild);
-    }
-
-    function setWidth(gui, w) {
-        gui.domElement.style.width = w + 'px';
-        if (gui.__save_row && gui.autoPlace) {
-            gui.__save_row.style.width = w + 'px';
-        }
-        if (gui.__closeButton) {
-            gui.__closeButton.style.width = w + 'px';
-        }
-    }
-
-    function getCurrentPreset(gui, useInitialValues) {
-        var toReturn = {};
-        Common.each(gui.__rememberedObjects, function(val, index) {
-            var savedValues = {};
-            var controllerMap = gui.__rememberedObjectIndecesToControllers[index];
-            Common.each(controllerMap, function(controller, property) {
-                savedValues[property] = useInitialValues ? controller.initialValue : controller.getValue();
-            });
-            toReturn[index] = savedValues;
-        });
-        return toReturn;
-    }
-
-    function setPresetSelectIndex(gui) {
-        for (var index = 0; index < gui.__preset_select.length; index++) {
-            if (gui.__preset_select[index].value === gui.preset) {
-                gui.__preset_select.selectedIndex = index;
-            }
-        }
-    }
-
-    function updateDisplays(controllerArray) {
-        if (controllerArray.length !== 0) {
-            requestAnimationFrame$1.call(window, function() {
-                updateDisplays(controllerArray);
-            });
-        }
-        Common.each(controllerArray, function(c) {
-            c.updateDisplay();
-        });
-    }
-
-    var color = {
-        Color: Color,
-        math: ColorMath,
-        interpret: interpret
-    };
-    var controllers = {
-        Controller: Controller,
-        BooleanController: BooleanController,
-        OptionController: OptionController,
-        StringController: StringController,
-        NumberController: NumberController,
-        NumberControllerBox: NumberControllerBox,
-        NumberControllerSlider: NumberControllerSlider,
-        FunctionController: FunctionController,
-        ColorController: ColorController
-    };
-    var dom$1 = { dom: dom };
-    var gui = { GUI: GUI };
-    var GUI$1 = GUI;
-    var index = {
-        color: color,
-        controllers: controllers,
-        dom: dom$1,
-        gui: gui,
-        GUI: GUI$1
-    };
-
-    exports.color = color;
-    exports.controllers = controllers;
-    exports.dom = dom$1;
-    exports.gui = gui;
-    exports.GUI = GUI$1;
-    exports['default'] = index;
-
-    Object.defineProperty(exports, '__esModule', { value: true });
-
-})));
-//# sourceMappingURL=dat.gui.js.map
\ No newline at end of file
diff --git a/lib/jsunit.js b/lib/jsunit.js
index d12559e759dab01bdb652183381ddb8ff7ccf43e..4f917eaab32088dc5996948e086badc80b184567 100644
--- a/lib/jsunit.js
+++ b/lib/jsunit.js
@@ -59,11 +59,9 @@ function State() {
 
     state.onChange = function(item, fn) {
         this.emitters[item] = fn
-        //console.log('ADD STATE CHANGE EMITTER', this.emitters)
     }
 
     state.emitChange = function(item) {
-        //console.log('EMIT CHANGE FOR', item)
         if (this.emitters[item] != null) {
             this.emitters[item]()
         }
@@ -72,10 +70,10 @@ function State() {
     return state
 }
 
-// within state ... or not ? 
+// a coupl'a fancy UI state hooks 
 function Button(label) {
     var button = {
-        type: 'ui-button',
+        type: 'button',
         isPressed: false,
         label: label
     }
@@ -86,10 +84,10 @@ function Button(label) {
 // now we're definitely writing a UI class 
 function MultiLine(label, rows) {
     var ml = {
-        isMultiLine: true,
+        type: 'multiline',
         label: label,
         rows: rows,
-        value: ' - '
+        value: ': - :'
     }
 
     return ml
diff --git a/main.js b/main.js
index 80b3763386a0ec11235627d19f664d49a0163481..769bb6ce98ff57848ac1b2b972592b6fb3cdde1a 100644
--- a/main.js
+++ b/main.js
@@ -1,5 +1,8 @@
 //
-// nnc.js
+//
+// new node controller
+//
+// main.js
 //
 //
 // Jake Read at the Center for Bits and Atoms
@@ -15,14 +18,6 @@
 
 RULES:
 
-modules have Ouputs() and Inputs() that connect to other software modules running on the same CPU. It's a directed graph.
-
-modules can have ATKPort()s that use a Link() to get to remote hardware, per message-passing network. It's a physical graph of duplex connections.
-
-this is nice because we might have two Link()s to double up on bandwidth. 
-
-alternately, Link()s could be TCP connections to other pieces of hardware, including something like us ! 
-
 */
 
 /*
@@ -41,6 +36,9 @@ const http = require('http').Server(app)
 // websocket, to share program representations with the client (and back)
 const WebSocket = require('ws')
 
+// setup prgmem land first, then load server stuff 
+// break server off into obj ? cumbersome ? probably nice to be able to turn it off 
+
 /*
 
 SERVER AND WS SETUP
@@ -78,7 +76,11 @@ http.listen(8080, () => {
     console.log('listening on 8080 for static files')
 })
 
-// server globals 
+/*
+
+SERVER
+
+*/
 
 var sckt = null
 
@@ -142,242 +144,16 @@ PROGRAM AS API
 // is it a JSON, or a txt .js file ? loadProgram and loadModule ...
 // it wants to be an object that gets 'read' in ... 
 
-var program = {
-    description: {
-        name: 'tstprgmem',
-        counter: 0, 
-    },
-    modules: {}
-}
-
-// add things
-
-var gate = addModuleToProgram(program, './src/util/gate.js')
-var delay = addModuleToProgram(program, './src/util/delay.js')
-var log = addModuleToProgram(program, './src/util/log.js')
-
-// hookup as usual 
-
-gate.outputs.out.attach(delay.inputs.thru)
-delay.outputs.out.attach(log.inputs.thru)
-gate.outputs.out.attach(log.inputs.thru)
-
-console.log('saving onesave.json')
-saveProgram(program, 'save/onesave.json')
+const Reps = require('./reps.js')
+const Programs = require('./programs.js')
 
-program = null 
-delete gate 
-delete delay
-delete log 
+var program = {} 
 
-console.log('opening onesave.json')
-var prgmem = openProgram('save/onesave.json')
+program = Programs.open('save/onesave.json')
 
-saveProgram(prgmem, 'save/twosave.json')
-
-// working through:
-/*
-
- - add load-from-thing-connect-outputs-to-inputs 
- - add new state loading / structure?
- - UI / letters 
-
-*/
+var View = require('./views.js')
 
 
-/*
-------------------------------------------------------
-PROGRAM ASSEMBLY 
-------------------------------------------------------
-*/
-
-function addModuleToProgram(program, path) {
-    // source -> heap
-    // program is an object seeking heirarchy, has program.modules 
-    if (fs.existsSync(path)) {
-        var src = require(path)
-        var mod = new src()
-
-        // wants unique module id's 
-        if(program.description.counter == null){
-            program.description.counter = 0
-        } else {
-            program.description.counter ++ 
-        }
-
-        // make unique name 
-        mod.description.id = mod.description.id = mod.description.name + '-' + program.description.counter
-        mod.description.path = path
-        
-        program.modules[mod.description.id] = mod
-
-        // input need references for later hookup
-        for (key in mod.inputs) {
-            mod.inputs[key].parentId = mod.description.id
-            mod.inputs[key].key = key
-        }
-
-        // state updating, begs for update 
-        for (key in mod.state) {
-            if (key == 'onChange' | key == 'emitChange' | key == 'emitters') {
-                //console.log('rolling past change fn')
-            } else {
-                mod.state['_' + key] = mod.state[key]
-                mod.state[key] = {}
-                writeStateObject(mod, key)
-            }
-        }
-
-        if (program.description.id == null) {
-            if (program.description.name == null) {
-                if (program.description == null) {
-                    program.description = {}
-                }
-                program.description.name = 'unnamed program'
-            }
-            program.description.id = program.description.name + '-' + 0
-        }
-
-        console.log('ADDING', mod.description.id, 'to', program.description.id)
-        // also return it so that we can write programs without the UI 
-        return mod
-    } else {
-        console.log('ERR no module found at ', path)
-    }
-}
-
-function writeStateObject(mod, key) {
-    Object.defineProperty(mod.state, key, {
-        set: function(x) {
-            // update internal value 
-            this['_' + key] = x
-            //console.log('SET', key, this['_' + key])
-            // push to internal state change handler
-            this.emitChange(key)
-            // update server (or in some cases, a confirmation)
-            putState(mod)
-        }
-    })
-    Object.defineProperty(mod.state, key, {
-        get: function() {
-            //console.log('GET', key, this['_' + key])
-            return this['_' + key]
-        }
-    })
-}
-
-function makeRepFromModule(mdl) {
-    var rep = {
-        description: {
-            id: mdl.description.id,
-            name: mdl.description.name,
-            alt: mdl.description.alt,
-            path: mdl.description.path
-        }
-    }
-
-    // TODO: making rep. of input / output should be a f'n of that object ...
-    // input, outputs, state objs should be known /sysobjects 
-    // everything else is free play 
-    rep.inputs = {}
-    for (key in mdl.inputs) {
-        rep.inputs[key] = {}
-        rep.inputs[key].accepts = mdl.inputs[key].accepts
-    }
-
-    rep.outputs = {}
-    for (key in mdl.outputs) {
-        rep.outputs[key] = {}
-        rep.outputs[key].emits = mdl.outputs[key].emits
-        rep.outputs[key].calls = new Array()
-        mdl.outputs[key].calls.forEach(function(inp) {
-            var input = {
-                parentId: inp.parentId,
-                key: inp.key
-            }
-            rep.outputs[key].calls.push(input)
-        })
-    }
-
-    rep.state = {}
-    for(key in mdl.state){
-        if(isStateKey(key)){
-            rep.state[key] = mdl.state[key]
-        }
-    }
-
-    return rep
-}
-
-function saveProgram(prgmem, path) {
-    // ok, and we're interested in just copying the relevant things ... 
-    var svprgmem = {
-        description: {
-            name: prgmem.description.name,
-            counter: prgmem.description.counter
-        },
-        modules: {}
-    }
-
-    var mdls = prgmem.modules
-
-    for(key in mdls){
-        var mdl = mdls[key]
-        var og = makeRepFromModule(mdl)
-        svprgmem.modules[mdl.description.id] = og 
-    }
-
-    fs.writeFileSync(path, JSON.stringify(svprgmem, null, 2), 'utf8')
-}
-
-function openProgram(path){
-    var program = {}
-
-    // get the .json file as an object 
-    var prgRep = JSON.parse(fs.readFileSync(path, 'utf8'))
-    console.log('OPENING THIS PRGRAM REP', prgRep)
-
-    // copy-pasta the program descro, 
-    program.description = {
-        name: prgRep.description.name,
-        counter: 0,
-        id: prgRep.description.name + 1, // in another world, we count
-        path: path
-    }
-
-    // gonna get those modules from source
-    program.modules = {}
-
-    for(key in prgRep.modules){
-        var mdlRep = prgRep.modules[key]
-        addModuleToProgram(program, mdlRep.description.path)
-    }
-
-    // gonna hook 'em up
-    for(modName in prgRep.modules){
-        // keys should be identical for rep and heap
-        var mdlRep = prgRep.modules[modName]
-        var mdl = program.modules[modName]
-
-        for(outName in mdlRep.outputs){
-            var outRep = mdlRep.outputs[outName]
-            // each has some caller ids 
-            for(nestedInputRep in outRep.calls){
-                // conn from tl program -> this hookup 
-                var nIRParent = outRep.calls[nestedInputRep].parentId
-                var nIRKey = outRep.calls[nestedInputRep].key 
-                var nI = program.modules[nIRParent].inputs[nIRKey]
-                console.log("ATTACHING", nI, nIRKey, 'to', mdl.outputs[outName])
-                mdl.outputs[outName].attach(nI)
-            }
-        }
-    }
-
-    // once modules exist, link inputs / outputs / copy state ? 
-
-    return program
-}
-
 /*
 
 PROGRAM REPRESENT 
diff --git a/programs.js b/programs.js
new file mode 100644
index 0000000000000000000000000000000000000000..c29c204f727cc0e881e2615ee7ba28dc20dd3420
--- /dev/null
+++ b/programs.js
@@ -0,0 +1,153 @@
+const fs = require('fs')
+
+function addModuleToProgram(program, path) {
+    // source -> heap
+    if (fs.existsSync(path)) {
+        var src = require(path)
+        var mod = new src()
+
+        // wants unique module id's 
+        if(program.description.counter == null){
+            program.description.counter = 0
+        } else {
+            program.description.counter ++ 
+        }
+
+        // make unique name 
+        mod.description.id = mod.description.id = mod.description.name + '-' + program.description.counter
+        mod.description.path = path
+        
+        // add to program object 
+        program.modules[mod.description.id] = mod
+
+        // input need references for later hookup
+        for (key in mod.inputs) {
+            mod.inputs[key].parentId = mod.description.id
+            mod.inputs[key].key = key
+        }
+
+        // state updating, begs for update 
+        for (key in mod.state) {
+            if (key == 'onChange' | key == 'emitChange' | key == 'emitters') {
+                //console.log('rolling past change fn')
+            } else {
+                mod.state['_' + key] = mod.state[key]
+                mod.state[key] = {}
+                writeStateObject(mod, key)
+            }
+        }
+
+        if (program.description.id == null) {
+            if (program.description.name == null) {
+                if (program.description == null) {
+                    program.description = {}
+                }
+                program.description.name = 'unnamed program'
+            }
+            program.description.id = program.description.name + '-' + 0
+        }
+
+        console.log('ADDING', mod.description.id, 'to', program.description.id)
+        // also return it so that we can write programs without the UI 
+        return mod
+    } else {
+        console.log('ERR no module found at ', path)
+    }
+}
+
+function writeStateObject(mod, key) {
+    Object.defineProperty(mod.state, key, {
+        set: function(x) {
+            // update internal value 
+            this['_' + key] = x
+            //console.log('SET', key, this['_' + key])
+            // push to internal state change handler
+            this.emitChange(key)
+            // update server (or in some cases, a confirmation)
+            putState(mod)
+        }
+    })
+    Object.defineProperty(mod.state, key, {
+        get: function() {
+            //console.log('GET', key, this['_' + key])
+            return this['_' + key]
+        }
+    })
+}
+
+function saveProgram(prgmem, path) {
+    // ok, and we're interested in just copying the relevant things ... 
+    var svprgmem = {
+        description: {
+            name: prgmem.description.name,
+            counter: prgmem.description.counter
+        },
+        modules: {}
+    }
+
+    var mdls = prgmem.modules
+
+    for(key in mdls){
+        var mdl = mdls[key]
+        var og = makeRepFromModule(mdl)
+        svprgmem.modules[mdl.description.id] = og 
+    }
+
+    fs.writeFileSync(path, JSON.stringify(svprgmem, null, 2), 'utf8')
+}
+
+
+function openProgram(path){
+    var program = {}
+
+    // get the .json file as an object 
+    var prgRep = JSON.parse(fs.readFileSync(path, 'utf8'))
+    console.log('OPENING THIS PRGRAM REP', prgRep)
+
+    // copy-pasta the program descro, 
+    program.description = {
+        name: prgRep.description.name,
+        counter: 0,
+        id: prgRep.description.name + 1, // in another world, we count
+        path: path
+    }
+
+    // gonna get those modules from source
+    program.modules = {}
+
+    for(key in prgRep.modules){
+        var mdlRep = prgRep.modules[key]
+        addModuleToProgram(program, mdlRep.description.path)
+    }
+
+    // gonna hook 'em up
+    for(modName in prgRep.modules){
+        // keys should be identical for rep and heap
+        var mdlRep = prgRep.modules[modName]
+        var mdl = program.modules[modName]
+
+        for(outName in mdlRep.outputs){
+            var outRep = mdlRep.outputs[outName]
+            // each has some caller ids 
+            for(nestedInputRep in outRep.calls){
+                // conn from tl program -> this hookup 
+                var nIRParent = outRep.calls[nestedInputRep].parentId
+                var nIRKey = outRep.calls[nestedInputRep].key 
+                var nI = program.modules[nIRParent].inputs[nIRKey]
+                console.log("ATTACHING", nIRKey, 'to', outName)
+                mdl.outputs[outName].attach(nI)
+            }
+        }
+    }
+
+    // once modules exist, link inputs / outputs / copy state ? 
+
+
+    return program
+}
+
+module.exports = {
+    open: openProgram,
+    save: saveProgram,
+    addModule: addModuleToProgram
+}
\ No newline at end of file
diff --git a/programs/tstloadprgmem.js b/programs/tstloadprgmem.js
new file mode 100644
index 0000000000000000000000000000000000000000..8a99f867c06acee36c93f54a8fc9c1b602eb8a4f
--- /dev/null
+++ b/programs/tstloadprgmem.js
@@ -0,0 +1,33 @@
+
+var program = {
+    description: {
+        name: 'tstprgmem',
+        counter: 0, 
+    },
+    modules: {}
+}
+
+// add things
+
+var gate = addModuleToProgram(program, './src/util/gate.js')
+var delay = addModuleToProgram(program, './src/util/delay.js')
+var log = addModuleToProgram(program, './src/util/log.js')
+
+// hookup as usual 
+
+gate.outputs.out.attach(delay.inputs.thru)
+delay.outputs.out.attach(log.inputs.thru)
+gate.outputs.out.attach(log.inputs.thru)
+
+console.log('saving onesave.json')
+saveProgram(program, 'save/onesave.json')
+
+program = null 
+delete gate 
+delete delay
+delete log 
+
+console.log('opening onesave.json')
+var prgmem = openProgram('save/onesave.json')
+
+saveProgram(prgmem, 'save/twosave.json')
\ No newline at end of file
diff --git a/reps.js b/reps.js
new file mode 100644
index 0000000000000000000000000000000000000000..7e0024105b23bd1a452cb63184f9fa2bf9c702e0
--- /dev/null
+++ b/reps.js
@@ -0,0 +1,46 @@
+function makeRepFromModule(mdl) {
+    var rep = {
+        description: {
+            id: mdl.description.id,
+            name: mdl.description.name,
+            alt: mdl.description.alt,
+            path: mdl.description.path
+        }
+    }
+
+    // TODO: making rep. of input / output should be a f'n of that object ...
+    // input, outputs, state objs should be known /sysobjects 
+    // everything else is free play 
+    rep.inputs = {}
+    for (key in mdl.inputs) {
+        rep.inputs[key] = {}
+        rep.inputs[key].accepts = mdl.inputs[key].accepts
+    }
+
+    rep.outputs = {}
+    for (key in mdl.outputs) {
+        rep.outputs[key] = {}
+        rep.outputs[key].emits = mdl.outputs[key].emits
+        rep.outputs[key].calls = new Array()
+        mdl.outputs[key].calls.forEach(function(inp) {
+            var input = {
+                parentId: inp.parentId,
+                key: inp.key
+            }
+            rep.outputs[key].calls.push(input)
+        })
+    }
+
+    rep.state = {}
+    for(key in mdl.state){
+        if(isStateKey(key)){
+            rep.state[key] = mdl.state[key]
+        }
+    }
+
+    return rep
+}
+
+module.exports = {
+    makeFromModule: makeRepFromModule
+}
\ No newline at end of file
diff --git a/save/onesave.json b/save/onesave.json
index 1f5cd7fe83d1b806796374cbb3c7fa3c39ac0d66..97421540da2a85a82027de9155330c52a0a90723 100644
--- a/save/onesave.json
+++ b/save/onesave.json
@@ -33,7 +33,7 @@
       },
       "state": {
         "toggle": {
-          "type": "ui-button",
+          "type": "button",
           "isPressed": false,
           "label": "Open / Close"
         },
diff --git a/save/twosave.json b/save/twosave.json
index 1f5cd7fe83d1b806796374cbb3c7fa3c39ac0d66..97421540da2a85a82027de9155330c52a0a90723 100644
--- a/save/twosave.json
+++ b/save/twosave.json
@@ -33,7 +33,7 @@
       },
       "state": {
         "toggle": {
-          "type": "ui-button",
+          "type": "button",
           "isPressed": false,
           "label": "Open / Close"
         },
diff --git a/src/util/gate.js b/src/util/gate.js
index e9b8fdd93336ad51179ffc3b326e04793faa89b7..100706779262c6b337d5d6056f5a9e3c55557565 100644
--- a/src/util/gate.js
+++ b/src/util/gate.js
@@ -15,9 +15,9 @@ function Gate() {
             alt: 'in ... out'
         }
     }
-
+    
     gate.state = State()
-    // alias !
+    // alias ! 
     var state = gate.state 
 
     state.toggle = Button("Open / Close")
diff --git a/views.js b/views.js
new file mode 100644
index 0000000000000000000000000000000000000000..aab65759f0208faa812ab74a5556bfb5c41c975a
--- /dev/null
+++ b/views.js
@@ -0,0 +1,49 @@
+// file system to load / look at our available modules / edit them 
+const fs = require('fs')
+
+// express serves files, http makes the connection
+const app = require('express')()
+const http = require('http').Server(app)
+
+// websocket, to share program representations with the client (and back)
+const WebSocket = require('ws')
+
+// setup prgmem land first, then load server stuff 
+// break server off into obj ? cumbersome ? probably nice to be able to turn it off 
+
+/*
+
+SERVER AND WS SETUP
+
+*/
+
+// serving this handful of static files
+app.get('/', (req, res) => {
+    console.log('client req /')
+    res.sendFile(__dirname + '/client/index.html')
+})
+
+app.get('/:file', (req, res) => {
+    console.log('client req', req.params.file)
+    res.sendFile(__dirname + '/client/' + req.params.file)
+})
+
+// and listening for requests here
+const wss = new WebSocket.Server({ port: 8081 })
+
+wss.on('connection', (ws) => {
+    sckt = ws
+    // say hello
+    socketSend('console', 'hello client')
+    // send current config as list of all modules
+    putReps()
+    console.log('socket open on 8081')
+    ws.on('message', (evt) => {
+        socketRecv(evt)
+    })
+})
+
+// through this window
+http.listen(8080, () => {
+    console.log('listening on 8080 for static files')
+})