function minExtend(obj1, obj2, opt) {
    var objOut = {};
    if(typeof obj2 !== 'object') obj2 = {};

    var arrayLen = opt === 'pieLike' ? -1 : 3;

    var keys = Object.keys(obj1);
    var i, k, v;

    for(i = 0; i < keys.length; i++) {
        k = keys[i];
        v = obj1[k];
        if(k.charAt(0) === '_' || typeof v === 'function') continue;
        else if(k === 'module') objOut[k] = v;
        else if(Array.isArray(v)) {
            if(k === 'colorscale' || arrayLen === -1) {
                objOut[k] = v.slice();
            } else {
                objOut[k] = v.slice(0, arrayLen);
            }
        } else if(lib.isTypedArray(v)) {
            if(arrayLen === -1) {
                objOut[k] = v.subarray();
            } else {
                objOut[k] = v.subarray(0, arrayLen);
            }
        } else if(v && (typeof v === 'object')) objOut[k] = minExtend(obj1[k], obj2[k], opt);
        else objOut[k] = v;
    }

    keys = Object.keys(obj2);
    for(i = 0; i < keys.length; i++) {
        k = keys[i];
        v = obj2[k];
        if(typeof v !== 'object' || !(k in objOut) || typeof objOut[k] !== 'object') {
            objOut[k] = v;
        }
    }

    return objOut;
}
modified version of jQuery's extend to strip out private objs and functions,
and cut arrays down to first <arraylen> or 1 elements
because extend-like algorithms are hella slow
obj2 is assumed to already be clean of these things (including no arrays)