(function (global, factory) {
    typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('d3-scale'), require('d3-shape')) :
    typeof define === 'function' && define.amd ? define(['exports', 'd3-scale', 'd3-shape'], factory) :
    (global = global || self, factory(global.fc = global.fc || {}, global.d3, global.d3));
}(this, function (exports, d3Scale, d3Shape) { 'use strict';

    d3Scale = d3Scale && d3Scale.hasOwnProperty('default') ? d3Scale['default'] : d3Scale;
    d3Shape = d3Shape && d3Shape.hasOwnProperty('default') ? d3Shape['default'] : d3Shape;

    var bufferBuilder = (function () {
      var attributes = {};
      var uniforms = {};

      var build = function build(gl, program, verticesPerElement, count) {
        Object.keys(attributes).forEach(function (key) {
          attributes[key](gl, program, key, verticesPerElement, count);
        });
        Object.keys(uniforms).forEach(function (key) {
          uniforms[key](gl, program, key);
        });
      };

      build.attribute = function () {
        for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
          args[_key] = arguments[_key];
        }

        if (args.length === 1) {
          return attributes[args[0]];
        }

        attributes[args[0]] = args[1];
        return build;
      };

      build.uniform = function () {
        for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
          args[_key2] = arguments[_key2];
        }

        if (args.length === 1) {
          return uniforms[args[0]];
        }

        uniforms[args[0]] = args[1];
        return build;
      };

      return build;
    });

    var types = {
      FLOAT: 5126
    };

    var baseAttributeBuilder = (function () {
      var buffer = null;
      var size = 1; // per vertex

      var type = types.FLOAT;
      var normalized = false;
      var stride = 0;
      var offset = 0;
      var validSize = 0;

      var base = function base(gl, program, name) {
        if (buffer == null || !gl.isBuffer(buffer)) {
          buffer = gl.createBuffer();
          validSize = 0;
        }

        gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
        var location = gl.getAttribLocation(program, name);
        gl.vertexAttribPointer(location, base.size(), base.type(), base.normalized(), base.stride(), base.offset());
        gl.enableVertexAttribArray(location);
      };

      base.validSize = function () {
        if (!arguments.length) {
          return validSize;
        }

        validSize = arguments.length <= 0 ? undefined : arguments[0];
        return base;
      };

      base.buffer = function () {
        if (!arguments.length) {
          return buffer;
        }

        buffer = arguments.length <= 0 ? undefined : arguments[0];
        validSize = 0;
        return base;
      };

      base.size = function () {
        if (!arguments.length) {
          return size;
        }

        size = arguments.length <= 0 ? undefined : arguments[0];
        validSize = 0;
        return base;
      };

      base.type = function () {
        if (!arguments.length) {
          return type;
        }

        type = arguments.length <= 0 ? undefined : arguments[0];
        validSize = 0;
        return base;
      };

      base.normalized = function () {
        if (!arguments.length) {
          return normalized;
        }

        normalized = arguments.length <= 0 ? undefined : arguments[0];
        validSize = 0;
        return base;
      };

      base.stride = function () {
        if (!arguments.length) {
          return stride;
        }

        stride = arguments.length <= 0 ? undefined : arguments[0];
        validSize = 0;
        return base;
      };

      base.offset = function () {
        if (!arguments.length) {
          return offset;
        }

        offset = arguments.length <= 0 ? undefined : arguments[0];
        validSize = 0;
        return base;
      };

      return base;
    });

    var uniformBuilder = (function (_data) {
      var data = _data;
      var changed = true;

      var bind = function bind(gl, program, name) {
        var loc = gl.getUniformLocation(program, name); // provide a way of setting which of the uniform functions to use?

        if (data instanceof Array) {
          switch (data.length) {
            case 1:
              gl.uniform1fv(loc, data);
              break;

            case 2:
              gl.uniform2fv(loc, data);
              break;

            case 3:
              gl.uniform3fv(loc, data);
              break;

            case 4:
              gl.uniform4fv(loc, data);
              break;

            default:
              throw new Error("Uniform supports up to 4 elements. ".concat(data.length, " provided."));
          }
        } else {
          gl.uniform1f(loc, data);
        }
      };

      var build = function build(gl, program, name) {
        if (changed) {
          changed = false;
          bind(gl, program, name);
        }
      };

      build.bind = function () {
        if (!arguments.length) {
          return bind;
        }

        bind = arguments.length <= 0 ? undefined : arguments[0];
        return build;
      };

      build.data = function () {
        if (!arguments.length) {
          return data;
        }

        data = arguments.length <= 0 ? undefined : arguments[0];
        changed = true;
        return build;
      };

      return build;
    });

    var shaderBuilder = (function (base) {
      var shaderHeaders = [];
      var shaderBodies = [];

      var build = function build() {
        return base(shaderHeaders.join('\n'), shaderBodies.join('\n'));
      };

      function append(array, element) {
        array.push(element);
      }

      function insert(array, element, before) {
        var beforeIndex = array.indexOf(before);
        array.splice(beforeIndex >= 0 ? beforeIndex : array.length, 0, element);
      }

      function appendIfNotExists(array, element) {
        var elementIndex = array.indexOf(element);

        if (elementIndex === -1) {
          array.push(element);
        }
      }

      build.appendHeader = function (header) {
        append(shaderHeaders, header);
        return build;
      };

      build.insertHeader = function (header, before) {
        insert(shaderHeaders, header, before);
        return build;
      };

      build.appendHeaderIfNotExists = function (header) {
        appendIfNotExists(shaderHeaders, header);
        return build;
      };

      build.appendBody = function (body) {
        append(shaderBodies, body);
        return build;
      };

      build.insertBody = function (body, before) {
        insert(shaderBodies, body, before);
        return build;
      };

      build.appendBodyIfNotExists = function (body) {
        appendIfNotExists(shaderBodies, body);
        return build;
      };

      return build;
    }); // inf is precalculated here for use in some functions (e.g. log scale calculations)

    var vertexShaderBase = function vertexShaderBase(header, body) {
      return "\nprecision mediump float;\nfloat inf = 1.0 / 0.0;\n".concat(header, "\nvoid main() {\n    ").concat(body, "\n}");
    };
    var fragmentShaderBase = function fragmentShaderBase(header, body) {
      return "\nprecision mediump float;\n".concat(header, "\nvoid main() {\n    gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);\n    ").concat(body, "\n}");
    };

    var drawModes = {
      POINTS: 0,
      LINES: 1,
      LINE_LOOP: 2,
      LINE_STRIP: 3,
      TRIANGLES: 4,
      TRIANGLE_STRIP: 5,
      TRIANGLE_FAN: 6
    };

    var programBuilder = (function () {
      var context = null;
      var program = null;
      var vertexShader = null;
      var fragmentShader = null;
      var mode = drawModes.TRIANGLES;
      var buffers = bufferBuilder();
      var verticesPerElement = 1;

      var build = function build(count) {
        var vertexShaderSource = vertexShader();
        var fragmentShaderSource = fragmentShader();

        if (newProgram(program, vertexShaderSource, fragmentShaderSource)) {
          context.isProgram(program) && context.deleteProgram(program);
          program = createProgram(vertexShaderSource, fragmentShaderSource);
        }

        context.useProgram(program);
        buffers.uniform('uScreen', uniformBuilder([context.canvas.width, context.canvas.height]));
        buffers(context, program, verticesPerElement, count);
        context.drawArrays(mode, 0, count * verticesPerElement);
      };

      build.context = function () {
        if (!arguments.length) {
          return context;
        }

        context = arguments.length <= 0 ? undefined : arguments[0];
        return build;
      };

      build.buffers = function () {
        if (!arguments.length) {
          return buffers;
        }

        buffers = arguments.length <= 0 ? undefined : arguments[0];
        return build;
      };

      build.vertexShader = function () {
        if (!arguments.length) {
          return vertexShader;
        }

        vertexShader = arguments.length <= 0 ? undefined : arguments[0];
        return build;
      };

      build.fragmentShader = function () {
        if (!arguments.length) {
          return fragmentShader;
        }

        fragmentShader = arguments.length <= 0 ? undefined : arguments[0];
        return build;
      };

      build.mode = function () {
        if (!arguments.length) {
          return mode;
        }

        mode = arguments.length <= 0 ? undefined : arguments[0];
        return build;
      };

      build.verticesPerElement = function () {
        if (!arguments.length) {
          return verticesPerElement;
        }

        verticesPerElement = arguments.length <= 0 ? undefined : arguments[0];
        return build;
      };

      return build;

      function newProgram(program, vertexShader, fragmentShader) {
        if (!program) {
          return true;
        }

        var shaders = context.getAttachedShaders(program);
        var vertexShaderSource = context.getShaderSource(shaders[0]);
        var fragmentShaderSource = context.getShaderSource(shaders[1]);
        return vertexShader !== vertexShaderSource || fragmentShader !== fragmentShaderSource;
      }

      function createProgram(vertexShaderSource, fragmentShaderSource) {
        var vertexShader = loadShader(vertexShaderSource, context.VERTEX_SHADER);
        var fragmentShader = loadShader(fragmentShaderSource, context.FRAGMENT_SHADER);
        var program = context.createProgram();
        context.attachShader(program, vertexShader);
        context.attachShader(program, fragmentShader);
        context.linkProgram(program);

        if (!context.getProgramParameter(program, context.LINK_STATUS)) {
          var message = context.getProgramInfoLog(program);
          context.deleteProgram(program);
          throw new Error("Failed to link program : ".concat(message, "\n            Vertex Shader : ").concat(vertexShaderSource, "\n            Fragment Shader : ").concat(fragmentShaderSource));
        }

        return program;
      }

      function loadShader(source, type) {
        var shader = context.createShader(type);
        context.shaderSource(shader, source);
        context.compileShader(shader);

        if (!context.getShaderParameter(shader, context.COMPILE_STATUS)) {
          var message = context.getShaderInfoLog(shader);
          context.deleteShader(shader);
          throw new Error("Failed to compile shader : ".concat(message, "\n            Shader : ").concat(source));
        }

        return shader;
      }
    });

    var glScaleBase = (function () {
      var domain = [0, 1];
      var range = [-1, 1];
      var coordinate = 0;

      var base = function base() {};

      base.domain = function () {
        if (!arguments.length) {
          return domain;
        }

        domain = arguments.length <= 0 ? undefined : arguments[0];
        return base;
      };

      base.range = function () {
        if (!arguments.length) {
          return range;
        }

        range = arguments.length <= 0 ? undefined : arguments[0];
        return base;
      };

      base.coordinate = function () {
        if (!arguments.length) {
          return coordinate;
        }

        coordinate = arguments.length <= 0 ? undefined : arguments[0];
        return base;
      };

      return base;
    });

    var createReboundMethod = ((target, source, name) => {
      const method = source[name];

      if (typeof method !== 'function') {
        throw new Error(`Attempt to rebind ${name} which isn't a function on the source object`);
      }

      return (...args) => {
        var value = method.apply(source, args);
        return value === source ? target : value;
      };
    });

    var rebind = ((target, source, ...names) => {
      for (const name of names) {
        target[name] = createReboundMethod(target, source, name);
      }

      return target;
    });

    const createTransform = transforms => name => transforms.reduce((name, fn) => name && fn(name), name);

    var rebindAll = ((target, source, ...transforms) => {
      const transform = createTransform(transforms);

      for (const name of Object.keys(source)) {
        const result = transform(name);

        if (result) {
          target[result] = createReboundMethod(target, source, name);
        }
      }

      return target;
    });

    var regexify = (strsOrRegexes => strsOrRegexes.map(strOrRegex => typeof strOrRegex === 'string' ? new RegExp(`^${strOrRegex}$`) : strOrRegex));

    var exclude = ((...exclusions) => {
      exclusions = regexify(exclusions);
      return name => exclusions.every(exclusion => !exclusion.test(name)) && name;
    });

    var glScaleLinear = (function () {
      var base = glScaleBase();

      var prefix = function prefix() {
        return "linear".concat(base.coordinate());
      };

      var apply = function apply(program) {
        updateProgram(program);
        var domainSize = base.domain()[1] - base.domain()[0];
        var rangeSize = base.range()[1] - base.range()[0];
        var translate = base.range()[0] * (domainSize / rangeSize) - base.domain()[0];
        var scaleFactor = rangeSize / domainSize;
        var offset = [0, 0, 0, 0];
        var scale = [1, 1, 1, 1];
        offset[base.coordinate()] = translate;
        scale[base.coordinate()] = scaleFactor;
        program.buffers().uniform("".concat(prefix(), "Offset"), uniformBuilder(offset)).uniform("".concat(prefix(), "Scale"), uniformBuilder(scale));
      };

      function updateProgram(program) {
        program.vertexShader().appendHeader("uniform vec4 ".concat(prefix(), "Offset;")).appendHeader("uniform vec4 ".concat(prefix(), "Scale;"));
        apply.scaleComponent(program, 'gl_Position');
      }

      apply.scaleComponent = function (program, component) {
        program.vertexShader().appendBody("".concat(component, " = ").concat(component, " + ").concat(prefix(), "Offset;")).appendBody("".concat(component, " = ").concat(component, " * ").concat(prefix(), "Scale;"));
        return apply;
      };

      rebindAll(apply, base);
      return apply;
    });

    var glScaleLog = (function () {
      var glBase = glScaleBase();
      var base = 10;

      function log(v, base) {
        return Math.log10(v) / Math.log10(base);
      }

      var prefix = function prefix() {
        return "log".concat(glBase.coordinate());
      };

      var apply = function apply(program) {
        updateProgram(program);
        var domainSize = log(glBase.domain()[1], base) - log(glBase.domain()[0], base);
        var rangeSize = glBase.range()[1] - glBase.range()[0];
        var scaleFactor = rangeSize / domainSize;
        var translate = glBase.range()[0] - scaleFactor * log(glBase.domain()[0], base);
        var offset = [0, 0, 0, 0];
        var scale = [0, 0, 0, 0];
        var include = [0, 0, 0, 0];
        offset[glBase.coordinate()] = translate;
        scale[glBase.coordinate()] = scaleFactor;
        include[glBase.coordinate()] = 1;
        program.buffers().uniform("".concat(prefix(), "Offset"), uniformBuilder(offset)).uniform("".concat(prefix(), "Scale"), uniformBuilder(scale)).uniform("".concat(prefix(), "Include"), uniformBuilder(include)).uniform("".concat(prefix(), "Base"), uniformBuilder(base));
      };

      function updateProgram(program) {
        program.vertexShader().appendHeader("uniform vec4 ".concat(prefix(), "Offset;")).appendHeader("uniform vec4 ".concat(prefix(), "Scale;")).appendHeader("uniform vec4 ".concat(prefix(), "Include;")).appendHeader("uniform float ".concat(prefix(), "Base;"));
        apply.scaleComponent(program, 'gl_Position');
      }

      apply.scaleComponent = function (program, component) {
        var logPart = "".concat(prefix(), "Offset + (").concat(prefix(), "Scale * clamp(log(").concat(component, ") / log(").concat(prefix(), "Base), -inf, inf))");
        program.vertexShader().appendBody("".concat(component, " = (").concat(prefix(), "Include * (").concat(logPart, ")) + ((1.0 - ").concat(prefix(), "Include) * ").concat(component, ");"));
        return apply;
      };

      apply.base = function () {
        if (!arguments.length) {
          return base;
        }

        base = arguments.length <= 0 ? undefined : arguments[0];
        return apply;
      };

      rebindAll(apply, glBase);
      return apply;
    });

    var glScalePow = (function () {
      var base = glScaleBase();
      var exponent = 1;

      function pow(b, e) {
        return Math.sign(b) * Math.pow(Math.abs(b), e);
      }

      var prefix = function prefix() {
        return "pow".concat(base.coordinate());
      };

      var apply = function apply(program) {
        updateProgram(program);
        var domainSize = pow(base.domain()[1], exponent) - pow(base.domain()[0], exponent);
        var rangeSize = base.range()[1] - base.range()[0];
        var scaleFactor = rangeSize / domainSize;
        var translate = base.range()[0] - scaleFactor * pow(base.domain()[0], exponent);
        var offset = [0, 0, 0, 0];
        var scale = [0, 0, 0, 0];
        var include = [0, 0, 0, 0];
        offset[base.coordinate()] = translate;
        scale[base.coordinate()] = scaleFactor;
        include[base.coordinate()] = 1;
        program.buffers().uniform("".concat(prefix(), "Offset"), uniformBuilder(offset)).uniform("".concat(prefix(), "Scale"), uniformBuilder(scale)).uniform("".concat(prefix(), "Include"), uniformBuilder(include)).uniform("".concat(prefix(), "Exp"), uniformBuilder(exponent));
      };

      function updateProgram(program) {
        program.vertexShader().appendHeader("uniform vec4 ".concat(prefix(), "Offset;")).appendHeader("uniform vec4 ".concat(prefix(), "Scale;")).appendHeader("uniform vec4 ".concat(prefix(), "Include;")).appendHeader("uniform float ".concat(prefix(), "Exp;"));
        apply.scaleComponent(program, 'gl_Position');
      }

      apply.scaleComponent = function (program, component) {
        var powPart = "".concat(prefix(), "Offset + (").concat(prefix(), "Scale * sign(").concat(component, ") * pow(abs(gl_Position), vec4(").concat(prefix(), "Exp)))");
        program.vertexShader().appendBody("".concat(component, " = (").concat(prefix(), "Include * (").concat(powPart, ")) + ((1.0 - ").concat(prefix(), "Include) * ").concat(component, ");"));
        return apply;
      };

      apply.exponent = function () {
        if (!arguments.length) {
          return exponent;
        }

        exponent = arguments.length <= 0 ? undefined : arguments[0];
        return apply;
      };

      rebindAll(apply, base);
      return apply;
    });

    var scaleMapper = (function (scale) {
      var outScale = d3Scale.scaleIdentity();
      var glScale = null;
      var scaleCopyString = scale.copy.toString(); // compare the stringified 'copy' function of the scale to
      // determine the scale type.

      if (scaleCopyString === d3Scale.scaleLinear().copy.toString()) {
        glScale = glScaleLinear().domain(scale.domain());
      } else if (scaleCopyString === d3Scale.scaleLog().copy.toString()) {
        glScale = glScaleLog().domain(scale.domain()).base(scale.base());
      } else if (scaleCopyString === d3Scale.scalePow().copy.toString()) {
        glScale = glScalePow().domain(scale.domain()).exponent(scale.exponent());
      } else if (scaleCopyString === d3Scale.scaleTime().copy.toString()) {
        glScale = glScaleLinear().domain(scale.domain());
      } else {
        glScale = glScaleLinear().domain(scale.range());
        outScale = scale;
      }

      return {
        scale: outScale,
        glScale: glScale
      };
    });

    var scale = {
      header: "uniform vec2 uScale;",
      body: "gl_Position.xy = gl_Position.xy * uScale;"
    };
    var translate = {
      header: "uniform vec2 uTranslate;",
      body: "gl_Position.xy = gl_Position.xy + uTranslate;"
    };
    var multiColor = {
      header: "attribute vec4 aColor;\n             varying vec4 vColor;",
      body: "vColor = aColor;"
    };
    var circle = {
      header: "attribute float aXValue;\n             attribute float aYValue;\n             attribute float aSize;\n             uniform float uLineWidth;\n             varying float vSize;",
      body: "vSize = 2.0 * sqrt(aSize / 3.14159);\n           gl_PointSize = vSize + uLineWidth + 1.0;\n           gl_Position = vec4(aXValue, aYValue, 0, 1);"
    };
    var square = {
      header: "attribute float aXValue;\n        attribute float aYValue;\n        attribute float aSize;\n        uniform float uLineWidth;\n        varying float vSize;",
      body: "vSize = sqrt(aSize);\n        gl_PointSize = vSize + uLineWidth + 1.0;\n        gl_Position = vec4(aXValue, aYValue, 0, 1);"
    };
    var triangle = {
      header: "attribute float aXValue;\n        attribute float aYValue;\n        attribute float aSize;\n        uniform float uLineWidth;\n        varying float vSize;",
      body: "vSize = sqrt((16.0 * aSize) / (3.0 * sqrt(3.0)));\n        gl_PointSize = vSize + uLineWidth + 1.0;\n        gl_Position = vec4(aXValue, aYValue, 0, 1);"
    };
    var cross = {
      header: "attribute float aXValue;\n        attribute float aYValue;\n        attribute float aSize;\n        uniform float uStrokeWidth;\n        varying float vSize;\n        varying float vStrokeWidthRatio;",
      body: "vSize = 3.0 * sqrt(aSize / 5.0);\n        vStrokeWidthRatio = uStrokeWidth / (vSize + uStrokeWidth + 1.0);\n        gl_PointSize = vSize + uStrokeWidth + 1.0;\n        gl_Position = vec4(aXValue, aYValue, 0, 1);"
    };
    var candlestick = {
      header: "\n        attribute float aXValue;\n        attribute float aHigh;\n        attribute float aOpen;\n        attribute float aClose;\n        attribute float aLow;\n        attribute float aBandwidth;\n        attribute vec3 aCorner;\n    \n        varying float vColorIndicator;\n        uniform vec2 uScreen;\n        uniform float uLineWidth;",
      body: "\n        vColorIndicator = sign(aClose - aOpen);\n\n        float isPositiveY = (sign(aCorner.y) + 1.0) / 2.0;\n        float isNotPositiveY = 1.0 - isPositiveY;\n        float isExtremeY = abs(aCorner.y) - 1.0;\n        float isNotExtremeY = 1.0 - isExtremeY;\n        float yValue = (isPositiveY * isExtremeY * aLow) + (isPositiveY * isNotExtremeY * aClose) + (isNotPositiveY * isNotExtremeY * aOpen) + (isNotPositiveY * isExtremeY * aHigh);\n\n        float xDirection = (isNotExtremeY * aCorner.x) + (isExtremeY * aCorner.z);\n        float yDirection = isNotExtremeY * sign(aClose - aOpen) * aCorner.y;\n\n        float bandwidthModifier = aBandwidth * aCorner.x / 2.0;\n\n        float xModifier = (uLineWidth * xDirection / 2.0) + bandwidthModifier;\n        float yModifier = uLineWidth * yDirection / 2.0;\n\n        gl_Position = vec4(aXValue, yValue, 0, 1);"
    };
    var ohlc = {
      header: "\n      attribute float aXValue;\n      attribute float aHigh;\n      attribute float aOpen;\n      attribute float aClose;\n      attribute float aLow;\n      attribute float aBandwidth;\n      attribute vec3 aCorner;\n  \n      varying float vColorIndicator;\n      uniform vec2 uScreen;\n      uniform float uLineWidth;",
      body: "\n      vColorIndicator = sign(aClose - aOpen);\n\n      float isPositiveY = (sign(aCorner.y) + 1.0) / 2.0;\n      float isNotPositiveY = 1.0 - isPositiveY;\n      float isExtremeY = abs(aCorner.y) - 1.0;\n      float isNotExtremeY = 1.0 - isExtremeY;\n      float yValue = (isPositiveY * isExtremeY * aLow) + (isPositiveY * isNotExtremeY * aClose) + (isNotPositiveY * isNotExtremeY * aOpen) + (isNotPositiveY * isExtremeY * aHigh);\n\n      float xDirection = isExtremeY * aCorner.z;\n      float yDirection = isNotExtremeY * aCorner.z;\n\n      float bandwidthModifier = isNotExtremeY * aCorner.x * aBandwidth / 2.0;\n\n      float xModifier = (uLineWidth * xDirection / 2.0) + bandwidthModifier;\n      float yModifier = uLineWidth * yDirection / 2.0;\n\n      gl_Position = vec4(aXValue, yValue, 0, 1);"
    };
    var bar = {
      header: "attribute float aXValue;\n        attribute float aY0Value;\n        attribute float aYValue;\n        attribute float aWidthValue;\n        attribute vec2 aCorner;\n        \n        uniform vec2 uScreen;\n        uniform float uLineWidth;",
      body: "\n        float isBaseline = (1.0 - aCorner.y) / 2.0;\n        float yValue = (isBaseline * aY0Value) + ((1.0 - isBaseline) * aYValue);\n\n        float xModifier = aCorner.x * (aWidthValue) / 2.0;\n\n        gl_Position = vec4(aXValue, yValue, 0, 1);\n        "
    };
    var preScaleLine = {
      header: "uniform float uLineWidth; // defines the width of the line\n        uniform vec2 uScreen; // the screen space canvas size (for normalizing vectors)\n        attribute vec2 aCorner; // defines which vertex in the line join we are considering\n        attribute float aXValue; attribute float aYValue; // the current vertex positions\n        attribute float aNextXValue; attribute float aNextYValue; // the next vertex positions\n        attribute float aPrevXValue; attribute float aPrevYValue; // the previous vertex positions\n        attribute float aDefined;\n        varying float vDefined;",
      body: "vDefined = aDefined;\n        vec4 curr = vec4(aXValue, aYValue, 0, 1);\n        gl_Position = curr;\n        vec4 next = vec4(aNextXValue, aNextYValue, 0, 0);\n        vec4 prev = vec4(aPrevXValue, aPrevYValue, 0, 0);"
    };
    var postScaleLine = {
      body: "if (all(equal(gl_Position.xy, prev.xy))) {\n            prev.xy = gl_Position.xy + normalize(gl_Position.xy - next.xy);\n        }\n        if (all(equal(gl_Position.xy, next.xy))) {\n            next.xy = gl_Position.xy + normalize(gl_Position.xy - prev.xy);\n        }\n        vec2 A = normalize(normalize(gl_Position.xy - prev.xy) * uScreen);\n        vec2 B = normalize(normalize(next.xy - gl_Position.xy) * uScreen);\n        vec2 tangent = normalize(A + B);\n        vec2 miter = vec2(-tangent.y, tangent.x);\n        vec2 normalA = vec2(-A.y, A.x);\n        float miterLength = 1.0 / dot(miter, normalA);\n        vec2 point = normalize(A - B);\n        if (miterLength > 10.0 && sign(aCorner.x * dot(miter, point)) > 0.0) {\n            gl_Position.xy = gl_Position.xy - (aCorner.x * aCorner.y * uLineWidth * normalA) / uScreen.xy;\n        } else {\n            gl_Position.xy = gl_Position.xy + (aCorner.x * miter * uLineWidth * miterLength) / uScreen.xy;\n        }"
    };
    var errorBar = {
      header: "attribute float aXValue;\n        attribute float aHighValue;\n        attribute float aLowValue;\n        attribute float aBandwidth;\n        attribute vec3 aCorner;\n        uniform vec2 uScreen;\n        uniform float uLineWidth;",
      body: "\n        float isLow = (aCorner.y + 1.0) / 2.0;\n        float yValue = isLow * aLowValue + (1.0 - isLow) * aHighValue;\n\n        float isEdgeCorner = abs(aCorner.x);\n        float lineWidthXDirection = (1.0 - isEdgeCorner) * aCorner.z;\n        float lineWidthYDirection = isEdgeCorner * aCorner.z;\n        \n        gl_Position = vec4(aXValue, yValue, 0, 1);\n        \n        float xModifier = ((uLineWidth * lineWidthXDirection) + (aBandwidth * aCorner.x / 2.0));\n        float yModifier = (uLineWidth * lineWidthYDirection);\n    "
    };
    var area = {
      header: "attribute float aXValue;\n        attribute float aYValue;\n        attribute float aXPrevValue;\n        attribute float aYPrevValue;\n        attribute float aY0Value;\n        attribute float aY0PrevValue;\n        attribute vec3 aCorner;\n        attribute float aDefined;\n        varying float vDefined;\n        \n        float when_lt(float a, float b) {\n            return max(sign(b - a), 0.0);\n        }\n        \n        float and(float a, float b) {\n            return a * b;\n        }",
      body: "vDefined = aDefined;\n        gl_Position = vec4(0, 0, 0, 1);\n\n        float hasIntercepted = when_lt((aYValue - aY0Value) * (aYPrevValue - aY0PrevValue), 0.0);\n        float useIntercept = and(aCorner.z, hasIntercepted);\n        \n        float yGradient = (aYValue - aYPrevValue) / (aXValue - aXPrevValue);\n        float yConstant = aYValue - (yGradient * aXValue);\n\n        float y0Gradient = (aY0Value - aY0PrevValue) / (aXValue - aXPrevValue);\n        float y0Constant = aY0Value - (y0Gradient * aXValue);\n\n        float denominator = (yGradient - y0Gradient) + step(abs(yGradient - y0Gradient), 0.0);\n        float interceptXValue = (y0Constant - yConstant) / denominator;\n        float interceptYValue = (yGradient * interceptXValue) + yConstant;\n\n        gl_Position = vec4(interceptXValue * useIntercept, interceptYValue * useIntercept, 0, 1);\n        \n        gl_Position.x += (1.0 - useIntercept) * ((aCorner.x * aXValue) + ((1.0 - aCorner.x) * aXPrevValue));\n        gl_Position.y += (1.0 - useIntercept) * (1.0 - aCorner.y) * ((aCorner.x * aYValue) + ((1.0 - aCorner.x) * aYPrevValue));\n        gl_Position.y += (1.0 - useIntercept) * aCorner.y * ((aCorner.x * aY0Value) + ((1.0 - aCorner.x) * aY0PrevValue));"
    };
    var boxPlot = {
      header: "\n        attribute float aXValue;\n        attribute float aHigh;\n        attribute float aUpperQuartile;\n        attribute float aMedian;\n        attribute float aLowerQuartile;\n        attribute float aLow;\n        attribute float aBandwidth;\n        attribute float aCapWidth;\n        attribute vec4 aCorner;\n        uniform vec2 uScreen;\n        uniform float uLineWidth;",
      body: "   \n        float isExtremeY = sign(abs(aCorner.y) - 2.0) + 1.0;\n        float isNotExtremeY = 1.0 - isExtremeY;\n\n        float isNonZeroY = abs(sign(aCorner.y));\n        float isZeroY = 1.0 - isNonZeroY;\n\n        float isQuartileY = isNotExtremeY * isNonZeroY;\n\n        float isPositiveY = (sign(aCorner.y + 0.5) + 1.0) / 2.0;\n        float isNegativeY = 1.0 - isPositiveY;\n\n        float yValue =\n          (isExtremeY * isNegativeY) * aHigh +\n          (isQuartileY * isNegativeY) * aUpperQuartile +\n          isZeroY * aMedian +\n          (isQuartileY * isPositiveY) * aLowerQuartile +\n          (isExtremeY * isPositiveY) * aLow;\n\n        gl_Position = vec4(aXValue, yValue, 0, 1);\n\n        float isHorizontal = aCorner.w;\n        float isVertical = 1.0 - isHorizontal;\n\n        float xDisplacement = aCorner.x * (isExtremeY * aCapWidth + isNotExtremeY * aBandwidth) / 2.0;\n        \n        float xModifier = (isVertical * uLineWidth * aCorner.z / 2.0) + xDisplacement;\n        float yModifier = isHorizontal * uLineWidth * aCorner.z / 2.0;\n        "
    };

    var vertexShaderSnippets = /*#__PURE__*/Object.freeze({
        scale: scale,
        translate: translate,
        multiColor: multiColor,
        circle: circle,
        square: square,
        triangle: triangle,
        cross: cross,
        candlestick: candlestick,
        ohlc: ohlc,
        bar: bar,
        preScaleLine: preScaleLine,
        postScaleLine: postScaleLine,
        errorBar: errorBar,
        area: area,
        boxPlot: boxPlot
    });

    var circle$1 = {
      header: "varying float vSize;",
      body: "float distance = length(2.0 * gl_PointCoord - 1.0);\n    if (distance > 1.0) {\n        discard;\n        return;\n    }"
    };
    var square$1 = {
      header: "varying float vSize;",
      body: "vec2 pointCoordTransform = 2.0 * gl_PointCoord - 1.0;\n        float distance = max(abs(pointCoordTransform.x), abs(pointCoordTransform.y));"
    };
    var triangle$1 = {
      header: "varying float vSize;",
      body: "vec2 pointCoordTransform = 2.0 * gl_PointCoord - 1.0;\n    float topEdgesDistance = abs(pointCoordTransform.x) - ((pointCoordTransform.y - 0.6) / sqrt(3.0));\n    float bottomEdgeDistance = pointCoordTransform.y + 0.5;\n    float distance = max(topEdgesDistance, bottomEdgeDistance);\n    if (distance > 1.0) {\n        discard;\n    }"
    };
    var cross$1 = {
      header: "varying float vSize;\n            varying float vStrokeWidthRatio;",
      body: "vec2 pointCoordTransform = 2.0 * gl_PointCoord - 1.0;\n    float innerCornerDistance = min(abs(pointCoordTransform.x), abs(pointCoordTransform.y)) + 0.66 - vStrokeWidthRatio;\n    float outerEdgeDistance = max(abs(pointCoordTransform.x), abs(pointCoordTransform.y));\n    float distance = max(innerCornerDistance, outerEdgeDistance);\n    if (distance > 1.0) {\n        discard;\n    }"
    };
    var candlestick$1 = {
      header: "varying float vColorIndicator;",
      body: "gl_FragColor = vec4(0.4, 0.8, 0, 1);\n    if (vColorIndicator < 0.0) {\n        gl_FragColor = vec4(0.8, 0.4, 0, 1);\n    }"
    };
    var ohlc$1 = {
      header: "varying float vColorIndicator;",
      body: "gl_FragColor = vec4(0.4, 0.8, 0, 1);\n    if (vColorIndicator < 0.0) {\n        gl_FragColor = vec4(0.8, 0.4, 0, 1);\n    }"
    };
    var area$1 = {
      header: "varying float vDefined;",
      body: "if (vDefined < 0.5) {\n            discard;\n        }\n        gl_FragColor = vec4(0.86, 0.86, 0.86, 1);"
    };
    var pointAlias = {
      body: "gl_FragColor.a = gl_FragColor.a * (1.0 - smoothstep(vSize - 2.0, vSize, distance * vSize));"
    };
    var multiColor$1 = {
      header: "varying vec4 vColor;",
      body: "gl_FragColor = vColor;"
    };
    var seriesColor = {
      header: "uniform vec4 uColor;",
      body: "gl_FragColor = uColor;"
    };
    var pointEdge = {
      header: "uniform vec4 uEdgeColor;\n             uniform float uLineWidth;",
      body: "float sEdge = smoothstep(vSize - uLineWidth - 2.0, vSize - uLineWidth, distance * (vSize + uLineWidth));\n           gl_FragColor = (uEdgeColor * sEdge) + ((1.0 - sEdge) * gl_FragColor);"
    };
    var line = {
      header: "varying float vDefined;",
      body: "if (vDefined < 0.5) {\n        discard;\n    }"
    };

    var fragmentShaderSnippets = /*#__PURE__*/Object.freeze({
        circle: circle$1,
        square: square$1,
        triangle: triangle$1,
        cross: cross$1,
        candlestick: candlestick$1,
        ohlc: ohlc$1,
        area: area$1,
        pointAlias: pointAlias,
        multiColor: multiColor$1,
        seriesColor: seriesColor,
        pointEdge: pointEdge,
        line: line
    });

    var circlePointShader = (function () {
      var vertexShader = shaderBuilder(vertexShaderBase);
      var fragmentShader = shaderBuilder(fragmentShaderBase);
      vertexShader.appendHeader(circle.header).appendBody(circle.body);
      fragmentShader.appendHeader(circle$1.header).appendBody(circle$1.body);
      return {
        vertex: function vertex() {
          return vertexShader;
        },
        fragment: function fragment() {
          return fragmentShader;
        }
      };
    });

    var squarePointShader = (function () {
      var vertexShader = shaderBuilder(vertexShaderBase);
      var fragmentShader = shaderBuilder(fragmentShaderBase);
      vertexShader.appendHeader(square.header).appendBody(square.body);
      fragmentShader.appendHeader(square$1.header).appendBody(square$1.body);
      return {
        vertex: function vertex() {
          return vertexShader;
        },
        fragment: function fragment() {
          return fragmentShader;
        }
      };
    });

    var trianglePointShader = (function () {
      var vertexShader = shaderBuilder(vertexShaderBase);
      var fragmentShader = shaderBuilder(fragmentShaderBase);
      vertexShader.appendHeader(triangle.header).appendBody(triangle.body);
      fragmentShader.appendHeader(triangle$1.header).appendBody(triangle$1.body);
      return {
        vertex: function vertex() {
          return vertexShader;
        },
        fragment: function fragment() {
          return fragmentShader;
        }
      };
    });

    var crossPointShader = (function () {
      var vertexShader = shaderBuilder(vertexShaderBase);
      var fragmentShader = shaderBuilder(fragmentShaderBase);
      vertexShader.appendHeader(cross.header).appendBody(cross.body);
      fragmentShader.appendHeader(cross$1.header).appendBody(cross$1.body);
      return {
        vertex: function vertex() {
          return vertexShader;
        },
        fragment: function fragment() {
          return fragmentShader;
        }
      };
    });

    var symbolMapper = (function (symbol) {
      switch (symbol) {
        case d3Shape.symbolCircle:
          return circlePointShader();

        case d3Shape.symbolSquare:
          return squarePointShader();

        case d3Shape.symbolTriangle:
          return trianglePointShader();

        case d3Shape.symbolCross:
          return crossPointShader();

        default:
          throw new Error("Unrecognised symbol: ".concat(symbol));
      }
    });

    var fill = (function () {
      var color = [0.86, 0.86, 0.86, 1.0];

      var fill = function fill(program) {
        program.fragmentShader().appendHeaderIfNotExists(seriesColor.header).appendBodyIfNotExists(seriesColor.body);
        program.buffers().uniform('uColor', uniformBuilder(color));
      };

      fill.color = function () {
        if (!arguments.length) {
          return color;
        }

        color = arguments.length <= 0 ? undefined : arguments[0];
        return fill;
      };

      return fill;
    });

    var stroke = (function () {
      var color = [0.0, 0.0, 0.0, 1.0];
      var width = 1.0;

      var stroke = function stroke(program) {
        program.fragmentShader().appendHeaderIfNotExists(pointEdge.header).appendBodyIfNotExists(pointEdge.body);
        program.buffers().uniform('uEdgeColor', uniformBuilder(color));
        program.buffers().uniform('uLineWidth', uniformBuilder(width));
      };

      stroke.color = function () {
        if (!arguments.length) {
          return color;
        }

        color = arguments.length <= 0 ? undefined : arguments[0];
        return stroke;
      };

      stroke.width = function () {
        if (!arguments.length) {
          return width;
        }

        width = arguments.length <= 0 ? undefined : arguments[0];
        return stroke;
      };

      return stroke;
    });

    var antiAlias = (function () {
      var antiAlias = function antiAlias(program) {
        program.fragmentShader().appendBodyIfNotExists(pointAlias.body);
      };

      return antiAlias;
    });

    var lineWidthShader = (function () {
      var width = 1;

      var lineWidth = function lineWidth(program) {
        program.buffers().uniform('uLineWidth', uniformBuilder(width));
      };

      lineWidth.lineWidth = function () {
        if (!arguments.length) {
          return width;
        }

        width = arguments.length <= 0 ? undefined : arguments[0];
        return lineWidth;
      };

      return lineWidth;
    });

    var fill$1 = (function () {
      var color = [0.86, 0.86, 0.86, 1.0];

      var fill = function fill(program) {
        program.vertexShader().appendHeaderIfNotExists(multiColor.header).appendBodyIfNotExists(multiColor.body);
        program.fragmentShader().appendHeaderIfNotExists(multiColor$1.header).appendBodyIfNotExists(multiColor$1.body);
        program.buffers().uniform('uColor', uniformBuilder(color));
      };

      fill.color = function () {
        if (!arguments.length) {
          return color;
        }

        var hex = arguments.length <= 0 ? undefined : arguments[0];
        var r = '0x' + hex[1] + hex[2];
        var g = '0x' + hex[3] + hex[4];
        var b = '0x' + hex[5] + hex[6];
        color = [+(r / 255), +(g / 255), +(b / 255), 1.0];
        return fill;
      };

      return fill;
    });

    var elementConstantAttributeBuilder = (function () {
      var base = baseAttributeBuilder();

      var value = function value(data, element, vertex, component, index) {
        return data[element];
      };

      var data = null;

      var project = function project(elementCount, verticesPerElement) {
        var components = base.size();
        var offset = base.offset();
        var projectedData = new Float32Array(offset + elementCount * verticesPerElement * components);
        var element = 0;

        for (var index = offset; index <= projectedData.length; index += verticesPerElement * components) {
          projectedData.fill(value(data, element), index, index + verticesPerElement * components);
          element++;
        }

        return projectedData;
      };

      var build = function build(gl, program, name, verticesPerElement, count) {
        base(gl, program, name);

        if (base.validSize() >= count) {
          return;
        }

        if (typeof value === 'function') {
          var projectedData = project(count, verticesPerElement);
          gl.bindBuffer(gl.ARRAY_BUFFER, base.buffer());
          gl.bufferData(gl.ARRAY_BUFFER, projectedData, gl.DYNAMIC_DRAW);
        } else if (Array.isArray(value)) {
          if (value.length === base.size()) {
            var location = gl.getAttribLocation(program, name);
            gl["vertexAttrib".concat(value.length, "fv")](location, value);
            gl.disableVertexAttribArray(location);
          } else {
            throw new Error("Expected array of length: ".concat(base.size(), ", recieved array of length: ").concat(value.length));
          }
        } else {
          throw new Error("Expected function or array, received: ".concat(value));
        }

        base.validSize(count);
      };

      build.value = function () {
        if (!arguments.length) {
          return value;
        }

        value = arguments.length <= 0 ? undefined : arguments[0];
        base.validSize(0);
        return build;
      };

      build.data = function () {
        if (!arguments.length) {
          return data;
        }

        data = arguments.length <= 0 ? undefined : arguments[0];
        base.validSize(0);
        return build;
      };

      rebindAll(build, base, exclude('buffer'));
      return build;
    });

    var glPoint = (function () {
      var xScale = glScaleBase();
      var yScale = glScaleBase();
      var type = circlePointShader();

      var decorate = function decorate() {};

      var xValueAttribute = elementConstantAttributeBuilder();
      var yValueAttribute = elementConstantAttributeBuilder();
      var sizeAttribute = elementConstantAttributeBuilder();
      var program = programBuilder().mode(drawModes.POINTS);
      program.buffers().attribute('aXValue', xValueAttribute).attribute('aYValue', yValueAttribute).attribute('aSize', sizeAttribute);

      var draw = function draw(numElements) {
        program.vertexShader(type.vertex()).fragmentShader(type.fragment());
        xScale.coordinate(0);
        xScale(program);
        yScale.coordinate(1);
        yScale(program);
        decorate(program);
        program(numElements);
      };

      draw.xValues = function (data) {
        xValueAttribute.data(data);
        return draw;
      };

      draw.yValues = function (data) {
        yValueAttribute.data(data);
        return draw;
      };

      draw.sizes = function (data) {
        sizeAttribute.data(data);
        return draw;
      };

      draw.decorate = function () {
        if (!arguments.length) {
          return decorate;
        }

        decorate = arguments.length <= 0 ? undefined : arguments[0];
        return draw;
      };

      draw.xScale = function () {
        if (!arguments.length) {
          return xScale;
        }

        xScale = arguments.length <= 0 ? undefined : arguments[0];
        return draw;
      };

      draw.yScale = function () {
        if (!arguments.length) {
          return yScale;
        }

        yScale = arguments.length <= 0 ? undefined : arguments[0];
        return draw;
      };

      draw.type = function () {
        if (!arguments.length) {
          return type;
        }

        type = arguments.length <= 0 ? undefined : arguments[0];
        return draw;
      };

      rebind(draw, program, 'context');
      return draw;
    });

    var lineShader = (function () {
      var vertexShader = shaderBuilder(vertexShaderBase);
      var fragmentShader = shaderBuilder(fragmentShaderBase);
      vertexShader.appendHeader(preScaleLine.header).appendBody(preScaleLine.body);
      fragmentShader.appendHeader(line.header).appendBody(line.body);
      return {
        vertex: function vertex() {
          return vertexShader;
        },
        fragment: function fragment() {
          return fragmentShader;
        }
      };
    });

    var vertexConstantAttributeBuilder = (function () {
      var base = baseAttributeBuilder();
      var data = null;
      var validSize = 0;

      var project = function project(elementCount, verticesPerElement) {
        var components = base.size();
        var offset = base.offset();
        var componentsPerElement = verticesPerElement * components;
        var projectedData = new Float32Array(offset + elementCount * componentsPerElement);

        if (data.length !== verticesPerElement) {
          throw new Error("Expected vertices array of size ".concat(verticesPerElement, ", recieved array with length ").concat(data.length, "."));
        }

        var target = 0;

        for (var vertex = 0; vertex < verticesPerElement; vertex++) {
          if (data[vertex].length !== components) {
            throw new Error("Expected components array of size ".concat(components, ", recieved array with length ").concat(data[vertex].length, "."));
          }

          for (var component = 0; component < components; component++) {
            projectedData[offset + target] = data[vertex][component];
            target++;
          }
        }

        for (var index = componentsPerElement; index < projectedData.length; index += componentsPerElement) {
          projectedData.copyWithin(offset + index, offset, offset + componentsPerElement);
        }

        return projectedData;
      };

      var build = function build(gl, program, name, verticesPerElement, count) {
        base(gl, program, name);

        if (validSize >= count) {
          return;
        }

        var projectedData = project(count, verticesPerElement);
        gl.bindBuffer(gl.ARRAY_BUFFER, base.buffer());
        gl.bufferData(gl.ARRAY_BUFFER, projectedData, gl.DYNAMIC_DRAW);
        validSize = count;
      };

      build.data = function () {
        if (!arguments.length) {
          return data;
        }

        data = arguments.length <= 0 ? undefined : arguments[0];
        validSize = 0;
        return build;
      };

      rebindAll(build, base, exclude('buffer'));
      return build;
    });

    var glLine = (function () {
      var xScale = glScaleBase();
      var yScale = glScaleBase();

      var decorate = function decorate() {};

      var lineWidth = lineWidthShader();
      var xValueAttribute = elementConstantAttributeBuilder();
      var xNextValueAttribute = elementConstantAttributeBuilder().value(function (data, element) {
        return data[Math.min(element + 1, data.length - 1)];
      });
      var xPreviousValueAttribute = elementConstantAttributeBuilder().value(function (data, element) {
        return data[Math.max(element - 1, 0)];
      });
      var yValueAttribute = elementConstantAttributeBuilder();
      var yNextValueAttribute = elementConstantAttributeBuilder().value(function (data, element) {
        return data[Math.min(element + 1, data.length - 1)];
      });
      var yPreviousValueAttribute = elementConstantAttributeBuilder().value(function (data, element) {
        return data[Math.max(element - 1, 0)];
      });
      var cornerAttribute = vertexConstantAttributeBuilder().size(2).data([[-1, -1], [1, -1], [-1, 1], [1, 1]]);
      var definedAttribute = elementConstantAttributeBuilder().value(function (data, element, vertex, component) {
        var value = data[element];

        if (vertex <= 1) {
          var previousValue = element === 0 ? value : data[element - 1];
          return value ? previousValue : value;
        } else {
          var nextValue = element === data.length - 1 ? value : data[element + 1];
          return value ? nextValue : value;
        }
      });
      var program = programBuilder().mode(drawModes.TRIANGLE_STRIP).verticesPerElement(4);
      program.buffers().attribute('aXValue', xValueAttribute).attribute('aNextXValue', xNextValueAttribute).attribute('aPrevXValue', xPreviousValueAttribute).attribute('aYValue', yValueAttribute).attribute('aNextYValue', yNextValueAttribute).attribute('aPrevYValue', yPreviousValueAttribute).attribute('aCorner', cornerAttribute).attribute('aDefined', definedAttribute);

      var draw = function draw(numElements) {
        var shaderBuilder = lineShader();
        program.vertexShader(shaderBuilder.vertex()).fragmentShader(shaderBuilder.fragment());
        xScale.coordinate(0);
        xScale(program);
        yScale.coordinate(1);
        yScale(program);
        xScale.scaleComponent(program, 'next');
        yScale.scaleComponent(program, 'next');
        xScale.scaleComponent(program, 'prev');
        yScale.scaleComponent(program, 'prev');
        program.vertexShader().appendBody(postScaleLine.body);
        lineWidth(program);
        decorate(program);
        program(numElements);
      };

      draw.xValues = function (data) {
        xValueAttribute.data(data);
        xNextValueAttribute.data(data);
        xPreviousValueAttribute.data(data);
        return draw;
      };

      draw.yValues = function (data) {
        yValueAttribute.data(data);
        yNextValueAttribute.data(data);
        yPreviousValueAttribute.data(data);
        return draw;
      };

      draw.defined = function (data) {
        definedAttribute.data(data);
        return draw;
      };

      draw.decorate = function () {
        if (!arguments.length) {
          return decorate;
        }

        decorate = arguments.length <= 0 ? undefined : arguments[0];
        return draw;
      };

      draw.xScale = function () {
        if (!arguments.length) {
          return xScale;
        }

        xScale = arguments.length <= 0 ? undefined : arguments[0];
        return draw;
      };

      draw.yScale = function () {
        if (!arguments.length) {
          return yScale;
        }

        yScale = arguments.length <= 0 ? undefined : arguments[0];
        return draw;
      };

      rebind(draw, program, 'context');
      rebind(draw, lineWidth, 'lineWidth');
      return draw;
    });

    var ohlcShader = (function () {
      var vertexShader = shaderBuilder(vertexShaderBase);
      var fragmentShader = shaderBuilder(fragmentShaderBase);
      vertexShader.appendHeader(ohlc.header).appendBody(ohlc.body);
      fragmentShader.appendHeader(ohlc$1.header).appendBody(ohlc$1.body);
      return {
        vertex: function vertex() {
          return vertexShader;
        },
        fragment: function fragment() {
          return fragmentShader;
        }
      };
    });

    var glOhlc = (function () {
      var program = programBuilder().verticesPerElement(18);
      var xScale = glScaleBase();
      var yScale = glScaleBase();
      var lineWidth = lineWidthShader();

      var decorate = function decorate() {};

      var xValueAttribute = elementConstantAttributeBuilder();
      var highAttribute = elementConstantAttributeBuilder();
      var openAttribute = elementConstantAttributeBuilder();
      var closeAttribute = elementConstantAttributeBuilder();
      var lowAttribute = elementConstantAttributeBuilder();
      var bandwidthAttribute = elementConstantAttributeBuilder();
      /*
       * x-y coordinate to locate the "corners" of the element.
       * X: -1: LEFT, 0: MIDDLE, 1: RIGHT
       * Y: -2: HIGH, -1: OPEN, 1: CLOSE, 2: LOW
       * Z - Follows convention for X/Y (appropriate direction will be selected by the shader): -1: LEFT/TOP, 1: RIGHT/BOTTOM
       */

      var cornerAttribute = vertexConstantAttributeBuilder().size(3).data([[0, -2, -1], [0, -2, 1], [0, 2, 1], [0, -2, -1], [0, 2, -1], [0, 2, 1], [-1, -1, -1], [-1, -1, 1], [0, -1, 1], [-1, -1, -1], [0, -1, -1], [0, -1, 1], [1, 1, 1], [0, 1, 1], [0, 1, -1], [0, 1, -1], [1, 1, -1], [1, 1, 1]]);

      var draw = function draw(numElements) {
        var shaderBuilder = ohlcShader();
        program.vertexShader(shaderBuilder.vertex()).fragmentShader(shaderBuilder.fragment()).mode(drawModes.TRIANGLES);
        program.buffers().attribute('aXValue', xValueAttribute).attribute('aHigh', highAttribute).attribute('aOpen', openAttribute).attribute('aClose', closeAttribute).attribute('aLow', lowAttribute).attribute('aBandwidth', bandwidthAttribute).attribute('aCorner', cornerAttribute);
        xScale.coordinate(0);
        xScale(program);
        yScale.coordinate(1);
        yScale(program);
        lineWidth(program);
        program.vertexShader().appendBody("\n          gl_Position.x += xModifier / uScreen.x;\n          gl_Position.y += yModifier / uScreen.y;\n        ");
        decorate(program);
        program(numElements);
      };

      draw.xValues = function (data) {
        xValueAttribute.data(data);
        return draw;
      };

      draw.openValues = function (data) {
        openAttribute.data(data);
        return draw;
      };

      draw.highValues = function (data) {
        highAttribute.data(data);
        return draw;
      };

      draw.lowValues = function (data) {
        lowAttribute.data(data);
        return draw;
      };

      draw.closeValues = function (data) {
        closeAttribute.data(data);
        return draw;
      };

      draw.bandwidth = function (data) {
        bandwidthAttribute.data(data);
        return draw;
      };

      draw.decorate = function () {
        if (!arguments.length) {
          return decorate;
        }

        decorate = arguments.length <= 0 ? undefined : arguments[0];
        return draw;
      };

      draw.xScale = function () {
        if (!arguments.length) {
          return xScale;
        }

        xScale = arguments.length <= 0 ? undefined : arguments[0];
        return draw;
      };

      draw.yScale = function () {
        if (!arguments.length) {
          return yScale;
        }

        yScale = arguments.length <= 0 ? undefined : arguments[0];
        return draw;
      };

      rebind(draw, program, 'context');
      rebind(draw, lineWidth, 'lineWidth');
      return draw;
    });

    var barShader = (function () {
      var vertexShader = shaderBuilder(vertexShaderBase);
      var fragmentShader = shaderBuilder(fragmentShaderBase);
      vertexShader.appendHeader(bar.header).appendBody(bar.body);
      return {
        vertex: function vertex() {
          return vertexShader;
        },
        fragment: function fragment() {
          return fragmentShader;
        }
      };
    });

    //     .-------------.------------.
    // (x-w/2, y1)    (x, y1)   (x+w/2, y1)
    //     |     \                    |
    //     |        \                 |
    //     |           \              |
    //     |              \           |
    //     |                 \        |
    //     |                    \     |
    //     |                       \  |
    //     αL            α            αR
    //     .-------------.------------.
    // (x-w/2, y0)     (x, y0)   (x+w/2, y0)
    // Drawing order
    // Triangle βL, αL, αR. (bottom)
    // β -> βL.
    // α -> αL.
    // α -> αR.
    // Triangle βL, αR, βR. (top)
    // β -> βL.
    // α -> αR.
    // β -> βR.

    var glBar = (function () {
      var program = programBuilder().verticesPerElement(6);
      var xScale = glScaleBase();
      var yScale = glScaleBase();

      var decorate = function decorate() {};

      var xValueAttribute = elementConstantAttributeBuilder();
      var yValueAttribute = elementConstantAttributeBuilder();
      var y0ValueAttribute = elementConstantAttributeBuilder();
      var widthValueAttribute = elementConstantAttributeBuilder();
      var cornerAttribute = vertexConstantAttributeBuilder().size(2).data([[-1, -1], [1, 1], [-1, 1], [-1, -1], [1, 1], [1, -1]]);

      var draw = function draw(numElements) {
        var shader = barShader();
        program.vertexShader(shader.vertex()).fragmentShader(shader.fragment()).mode(drawModes.TRIANGLES);
        program.buffers().attribute('aXValue', xValueAttribute).attribute('aYValue', yValueAttribute).attribute('aY0Value', y0ValueAttribute).attribute('aWidthValue', widthValueAttribute).attribute('aCorner', cornerAttribute);
        xScale.coordinate(0);
        xScale(program);
        yScale.coordinate(1);
        yScale(program);
        program.vertexShader().appendBody("\n            gl_Position.x += xModifier / uScreen.x * 2.0;\n        ");
        decorate(program);
        program(numElements);
      };

      draw.xValues = function (data) {
        xValueAttribute.data(data);
        return draw;
      };

      draw.y0Values = function (data) {
        y0ValueAttribute.data(data);
        return draw;
      };

      draw.yValues = function (data) {
        yValueAttribute.data(data);
        return draw;
      };

      draw.widths = function (data) {
        widthValueAttribute.data(data);
        return draw;
      };

      draw.xScale = function () {
        if (!arguments.length) {
          return xScale;
        }

        xScale = arguments.length <= 0 ? undefined : arguments[0];
        return draw;
      };

      draw.yScale = function () {
        if (!arguments.length) {
          return yScale;
        }

        yScale = arguments.length <= 0 ? undefined : arguments[0];
        return draw;
      };

      draw.decorate = function () {
        if (!arguments.length) {
          return decorate;
        }

        decorate = arguments.length <= 0 ? undefined : arguments[0];
        return draw;
      };

      rebind(draw, program, 'context');
      return draw;
    });

    var errorBarShader = (function () {
      var vertexShader = shaderBuilder(vertexShaderBase);
      var fragmentShader = shaderBuilder(fragmentShaderBase);
      vertexShader.appendHeader(errorBar.header).appendBody(errorBar.body);
      return {
        vertex: function vertex() {
          return vertexShader;
        },
        fragment: function fragment() {
          return fragmentShader;
        }
      };
    });

    var glErrorBar = (function () {
      var program = programBuilder().verticesPerElement(18);
      var xScale = glScaleBase();
      var yScale = glScaleBase();

      var lineWidth = lineWidthShader();
      var xValueAttribute = elementConstantAttributeBuilder();
      var highValueAttribute = elementConstantAttributeBuilder();
      var lowValueAttribute = elementConstantAttributeBuilder();
      var bandwidthAttribute = elementConstantAttributeBuilder();
      /*
       * x-y coordinate to locate the "corners" of the element (ie errorbar). The `z` coordinate locates the corner relative to the line (this takes line width into account).
       * X: -1: LEFT, 0: MIDDLE, 1: RIGHT
       * Y: -1: HIGH, 1: LOW
       * Z: Follows X or Y convention, depending on the orientation of the line that the vertex is part of.
       */

      var cornerAttribute = vertexConstantAttributeBuilder().size(3).data([[0, 1, 1], [0, 1, -1], [0, -1, -1], [0, 1, 1], [0, -1, 1], [0, -1, -1], [1, -1, 1], [1, -1, -1], [-1, -1, -1], [1, -1, 1], [-1, -1, 1], [-1, -1, -1], [-1, 1, -1], [-1, 1, 1], [1, 1, 1], [-1, 1, -1], [1, 1, -1], [1, 1, 1]]);

      var draw = function draw(numElements) {
        var shader = errorBarShader();
        program.vertexShader(shader.vertex()).fragmentShader(shader.fragment()).mode(drawModes.TRIANGLES);
        program.buffers().attribute('aXValue', xValueAttribute).attribute('aHighValue', highValueAttribute).attribute('aLowValue', lowValueAttribute).attribute('aBandwidth', bandwidthAttribute).attribute('aCorner', cornerAttribute);
        xScale.coordinate(0);
        xScale(program);
        yScale.coordinate(1);
        yScale(program);
        lineWidth(program);
        program.vertexShader().appendBody("\n                gl_Position.x += xModifier / uScreen.x * 2.0;\n                gl_Position.y += yModifier / uScreen.y * 2.0;\n            ");
        program(numElements);
      };

      draw.xValues = function (data) {
        xValueAttribute.data(data);
        return draw;
      };

      draw.highValues = function (data) {
        highValueAttribute.data(data);
        return draw;
      };

      draw.lowValues = function (data) {
        lowValueAttribute.data(data);
        return draw;
      };

      draw.bandwidth = function (data) {
        bandwidthAttribute.data(data);
        return draw;
      };

      draw.xScale = function () {
        if (!arguments.length) {
          return xScale;
        }

        xScale = arguments.length <= 0 ? undefined : arguments[0];
        return draw;
      };

      draw.yScale = function () {
        if (!arguments.length) {
          return yScale;
        }

        yScale = arguments.length <= 0 ? undefined : arguments[0];
        return draw;
      };

      rebind(draw, program, 'context');
      rebind(draw, lineWidth, 'lineWidth');
      return draw;
    });

    var areaShader = (function () {
      var vertexShader = shaderBuilder(vertexShaderBase);
      var fragmentShader = shaderBuilder(fragmentShaderBase);
      vertexShader.appendHeader(area.header).appendBody(area.body);
      fragmentShader.appendHeader(area$1.header).appendBody(area$1.body);
      return {
        vertex: function vertex() {
          return vertexShader;
        },
        fragment: function fragment() {
          return fragmentShader;
        }
      };
    });

    var glArea = (function () {
      var xScale = glScaleBase();
      var yScale = glScaleBase();

      var decorate = function decorate() {};

      var xValueAttribute = elementConstantAttributeBuilder().value(function (data, element) {
        return data[Math.min(element + 1, data.length - 1)];
      });
      var xPreviousValueAttribute = elementConstantAttributeBuilder();
      var yValueAttribute = elementConstantAttributeBuilder().value(function (data, element) {
        return data[Math.min(element + 1, data.length - 1)];
      });
      var yPreviousValueAttribute = elementConstantAttributeBuilder();
      var y0ValueAttribute = elementConstantAttributeBuilder().value(function (data, element) {
        return data[Math.min(element + 1, data.length - 1)];
      });
      var y0PreviousValueAttribute = elementConstantAttributeBuilder();
      var cornerAttribute = vertexConstantAttributeBuilder().size(3).data([[0, 0, 0], [0, 1, 0], [1, 1, 1], [0, 0, 1], [1, 0, 0], [1, 1, 0]]);
      var definedAttribute = elementConstantAttributeBuilder().value(function (data, element, vertex, component) {
        var value = data[element];
        var nextValue = element === data.length - 1 ? 0 : data[element + 1];
        return value ? nextValue : value;
      });
      var program = programBuilder().mode(drawModes.TRIANGLES).verticesPerElement(6);
      program.buffers().attribute('aXValue', xValueAttribute).attribute('aXPrevValue', xPreviousValueAttribute).attribute('aYValue', yValueAttribute).attribute('aYPrevValue', yPreviousValueAttribute).attribute('aY0Value', y0ValueAttribute).attribute('aY0PrevValue', y0PreviousValueAttribute).attribute('aCorner', cornerAttribute).attribute('aDefined', definedAttribute);

      var draw = function draw(numElements) {
        var shaderBuilder = areaShader();
        program.vertexShader(shaderBuilder.vertex()).fragmentShader(shaderBuilder.fragment());
        xScale.coordinate(0);
        xScale(program);
        yScale.coordinate(1);
        yScale(program);
        decorate(program);
        program(numElements - 1);
      };

      draw.xValues = function (data) {
        xValueAttribute.data(data);
        xPreviousValueAttribute.data(data);
        return draw;
      };

      draw.yValues = function (data) {
        yValueAttribute.data(data);
        yPreviousValueAttribute.data(data);
        return draw;
      };

      draw.y0Values = function (data) {
        y0ValueAttribute.data(data);
        y0PreviousValueAttribute.data(data);
        return draw;
      };

      draw.defined = function (data) {
        definedAttribute.data(data);
        return draw;
      };

      draw.decorate = function () {
        if (!arguments.length) {
          return decorate;
        }

        decorate = arguments.length <= 0 ? undefined : arguments[0];
        return draw;
      };

      draw.xScale = function () {
        if (!arguments.length) {
          return xScale;
        }

        xScale = arguments.length <= 0 ? undefined : arguments[0];
        return draw;
      };

      draw.yScale = function () {
        if (!arguments.length) {
          return yScale;
        }

        yScale = arguments.length <= 0 ? undefined : arguments[0];
        return draw;
      };

      rebind(draw, program, 'context');
      return draw;
    });

    var candlestickShader = (function () {
      var vertexShader = shaderBuilder(vertexShaderBase);
      var fragmentShader = shaderBuilder(fragmentShaderBase);
      vertexShader.appendHeader(candlestick.header).appendBody(candlestick.body);
      fragmentShader.appendHeader(candlestick$1.header).appendBody(candlestick$1.body);
      return {
        vertex: function vertex() {
          return vertexShader;
        },
        fragment: function fragment() {
          return fragmentShader;
        }
      };
    });

    var glCandlestick = (function () {
      var program = programBuilder().verticesPerElement(12);
      var xScale = glScaleBase();
      var yScale = glScaleBase();
      var lineWidth = lineWidthShader();

      var decorate = function decorate() {};

      var xValueAttribute = elementConstantAttributeBuilder();
      var highAttribute = elementConstantAttributeBuilder();
      var openAttribute = elementConstantAttributeBuilder();
      var closeAttribute = elementConstantAttributeBuilder();
      var lowAttribute = elementConstantAttributeBuilder();
      var bandwidthAttribute = elementConstantAttributeBuilder();
      /*
       * x-y coordinate to locate the "corners" of the element.
       * X: -1: LEFT, 0: MIDDLE, 1: RIGHT
       * Y: -2: HIGH, -1: OPEN, 1: CLOSE, 2: LOW
       * Z: -1: LEFT, 1: RIGHT (only valid for HIGH/LOW corners)
       */

      var cornerAttribute = vertexConstantAttributeBuilder().size(3).data([[0, 2, 1], [0, 2, -1], [0, -2, -1], [0, 2, 1], [0, -2, 1], [0, -2, -1], [1, -1, 0], [-1, -1, 0], [-1, 1, 0], [1, -1, 0], [1, 1, 0], [-1, 1, 0]]);

      var draw = function draw(numElements) {
        var shaderBuilder = candlestickShader();
        program.vertexShader(shaderBuilder.vertex()).fragmentShader(shaderBuilder.fragment()).mode(drawModes.TRIANGLES);
        program.buffers().attribute('aXValue', xValueAttribute).attribute('aHigh', highAttribute).attribute('aOpen', openAttribute).attribute('aClose', closeAttribute).attribute('aLow', lowAttribute).attribute('aBandwidth', bandwidthAttribute).attribute('aCorner', cornerAttribute);
        xScale.coordinate(0);
        xScale(program);
        yScale.coordinate(1);
        yScale(program);
        lineWidth(program);
        program.vertexShader().appendBody("\n          gl_Position.x += xModifier / uScreen.x;\n          gl_Position.y += yModifier / uScreen.y;\n        ");
        decorate(program);
        program(numElements);
      };

      draw.xValues = function (data) {
        xValueAttribute.data(data);
        return draw;
      };

      draw.openValues = function (data) {
        openAttribute.data(data);
        return draw;
      };

      draw.highValues = function (data) {
        highAttribute.data(data);
        return draw;
      };

      draw.lowValues = function (data) {
        lowAttribute.data(data);
        return draw;
      };

      draw.closeValues = function (data) {
        closeAttribute.data(data);
        return draw;
      };

      draw.bandwidth = function (data) {
        bandwidthAttribute.data(data);
        return draw;
      };

      draw.decorate = function () {
        if (!arguments.length) {
          return decorate;
        }

        decorate = arguments.length <= 0 ? undefined : arguments[0];
        return draw;
      };

      draw.xScale = function () {
        if (!arguments.length) {
          return xScale;
        }

        xScale = arguments.length <= 0 ? undefined : arguments[0];
        return draw;
      };

      draw.yScale = function () {
        if (!arguments.length) {
          return yScale;
        }

        yScale = arguments.length <= 0 ? undefined : arguments[0];
        return draw;
      };

      rebind(draw, program, 'context');
      rebind(draw, lineWidth, 'lineWidth');
      return draw;
    });

    var boxPlotShader = (function () {
      var vertexShader = shaderBuilder(vertexShaderBase);
      var fragmentShader = shaderBuilder(fragmentShaderBase);
      vertexShader.appendHeader(boxPlot.header).appendBody(boxPlot.body);
      return {
        vertex: function vertex() {
          return vertexShader;
        },
        fragment: function fragment() {
          return fragmentShader;
        }
      };
    });

    //            .------.------.
    //                   |
    //                   |
    //                   |
    //    βL2            β           βR2
    //     .-------------.------------.
    //     |                          |
    //     |                          |
    //     |                          |
    //     γL2            γ           γR2
    //     .-------------.------------.
    //     |                          |
    //     |                          |
    //     |                          |
    //    δL2            δ           δR2
    //     .-------------.------------.
    //                   |
    //                   |
    //                   |
    //           εL1     ε     εR1
    //            .------.------.
    // Line drawing order
    // αL1 -> αR1
    // α -> β
    // βL2 -> βR2
    // γL2 -> γR2
    // δL2 -> δR2
    // βL2 -> δL2
    // βR2 -> δR2
    // δ -> ε
    // εL1 -> εR1

    var glBoxPlot = (function () {
      var verticesPerElement = 54;
      var program = programBuilder().verticesPerElement(verticesPerElement);
      var xScale = glScaleBase();
      var yScale = glScaleBase();

      var decorate = function decorate() {};

      var lineWidth = lineWidthShader();
      var xValueAttribute = elementConstantAttributeBuilder();
      var highAttribute = elementConstantAttributeBuilder();
      var upperQuartileAttribute = elementConstantAttributeBuilder();
      var medianAttribute = elementConstantAttributeBuilder();
      var lowerQuartileAttribute = elementConstantAttributeBuilder();
      var lowAttribute = elementConstantAttributeBuilder();
      var bandwidthAttribute = elementConstantAttributeBuilder();
      var capWidthAttribute = elementConstantAttributeBuilder();
      /*
       * x-y coordinate to locate the "corners" of the element (ie errorbar). The `z` coordinate locates the corner relative to the line (this takes line width into account).
       * X: -1: LEFT, 0: MIDDLE, 1: RIGHT
       * Y: -2: HIGH, -1: UPPER QUARTILE, 0: MEDIAN, 1: LOWER QUARTILE, 2: LOW
       * Z: Follows X or Y convention, depending on the orientation of the line that the vertex is part of.
       * W: Indicator to determine line orientation (needed because some corners are part of two lines). - 0: VERTICAL, 1: HORIZONTAL
       */

      var cornerAttribute = vertexConstantAttributeBuilder().size(4).data([// Top cap line
      [-1, -2, -1, 1], [1, -2, -1, 1], [1, -2, 1, 1], [-1, -2, -1, 1], [1, -2, 1, 1], [-1, -2, 1, 1], // Top whisker line
      [0, -2, -1, 0], [0, -2, 1, 0], [0, -1, 1, 0], [0, -2, -1, 0], [0, -1, 1, 0], [0, -1, -1, 0], // Upper quartile line
      [-1, -1, -1, 1], [1, -1, -1, 1], [1, -1, 1, 1], [-1, -1, -1, 1], [1, -1, 1, 1], [-1, -1, 1, 1], // Median line
      [-1, 0, -1, 1], [1, 0, -1, 1], [1, 0, 1, 1], [-1, 0, -1, 1], [1, 0, 1, 1], [-1, 0, 1, 1], // Lower quartile line
      [-1, 1, -1, 1], [1, 1, -1, 1], [1, 1, 1, 1], [-1, 1, -1, 1], [1, 1, 1, 1], [-1, 1, 1, 1], // Left box vertical line
      [-1, -1, -1, 0], [-1, -1, 1, 0], [-1, 1, 1, 0], [-1, -1, -1, 0], [-1, 1, 1, 0], [-1, 1, -1, 0], // Right box vertical line
      [1, -1, -1, 0], [1, -1, 1, 0], [1, 1, 1, 0], [1, -1, -1, 0], [1, 1, 1, 0], [1, 1, -1, 0], // Bottom whisker line
      [0, 2, -1, 0], [0, 2, 1, 0], [0, 1, 1, 0], [0, 2, -1, 0], [0, 1, 1, 0], [0, 1, -1, 0], // Bottom cap line
      [-1, 2, -1, 1], [1, 2, -1, 1], [1, 2, 1, 1], [-1, 2, -1, 1], [1, 2, 1, 1], [-1, 2, 1, 1]]);

      var draw = function draw(numElements) {
        var shader = boxPlotShader();
        program.vertexShader(shader.vertex()).fragmentShader(shader.fragment()).mode(drawModes.TRIANGLES);
        program.buffers().attribute('aXValue', xValueAttribute).attribute('aHigh', highAttribute).attribute('aUpperQuartile', upperQuartileAttribute).attribute('aMedian', medianAttribute).attribute('aLowerQuartile', lowerQuartileAttribute).attribute('aLow', lowAttribute).attribute('aBandwidth', bandwidthAttribute).attribute('aCapWidth', capWidthAttribute).attribute('aCorner', cornerAttribute);
        xScale.coordinate(0);
        xScale(program);
        yScale.coordinate(1);
        yScale(program);
        lineWidth(program);
        program.vertexShader().appendBody("\n            gl_Position.x += xModifier / uScreen.x * 2.0;\n            gl_Position.y += yModifier / uScreen.y * 2.0;\n        ");
        decorate(program);
        program(numElements);
      };

      draw.xValues = function (data) {
        xValueAttribute.data(data);
        return draw;
      };

      draw.highValues = function (data) {
        highAttribute.data(data);
        return draw;
      };

      draw.upperQuartileValues = function (data) {
        upperQuartileAttribute.data(data);
        return draw;
      };

      draw.medianValues = function (data) {
        medianAttribute.data(data);
        return draw;
      };

      draw.lowerQuartileValues = function (data) {
        lowerQuartileAttribute.data(data);
        return draw;
      };

      draw.lowValues = function (data) {
        lowAttribute.data(data);
        return draw;
      };

      draw.bandwidth = function (data) {
        bandwidthAttribute.data(data);
        return draw;
      };

      draw.capWidth = function (data) {
        capWidthAttribute.data(data);
        return draw;
      };

      draw.xScale = function () {
        if (!arguments.length) {
          return xScale;
        }

        xScale = arguments.length <= 0 ? undefined : arguments[0];
        return draw;
      };

      draw.yScale = function () {
        if (!arguments.length) {
          return yScale;
        }

        yScale = arguments.length <= 0 ? undefined : arguments[0];
        return draw;
      };

      draw.decorate = function () {
        if (!arguments.length) {
          return decorate;
        }

        decorate = arguments.length <= 0 ? undefined : arguments[0];
        return draw;
      };

      rebind(draw, program, 'context');
      rebind(draw, lineWidth, 'lineWidth');
      return draw;
    });

    exports.barFill = fill$1;
    exports.baseAttributeBuilder = baseAttributeBuilder;
    exports.bufferBuilder = bufferBuilder;
    exports.circlePointShader = circlePointShader;
    exports.fragmentShaderSnippets = fragmentShaderSnippets;
    exports.glArea = glArea;
    exports.glBar = glBar;
    exports.glBoxPlot = glBoxPlot;
    exports.glCandlestick = glCandlestick;
    exports.glErrorBar = glErrorBar;
    exports.glLine = glLine;
    exports.glOhlc = glOhlc;
    exports.glPoint = glPoint;
    exports.glScaleLinear = glScaleLinear;
    exports.glScaleLog = glScaleLog;
    exports.glScalePow = glScalePow;
    exports.lineWidth = lineWidthShader;
    exports.pointAntiAlias = antiAlias;
    exports.pointFill = fill;
    exports.pointStroke = stroke;
    exports.programBuilder = programBuilder;
    exports.scaleMapper = scaleMapper;
    exports.shaderBuilder = shaderBuilder;
    exports.squarePointShader = squarePointShader;
    exports.symbolMapper = symbolMapper;
    exports.uniformBuilder = uniformBuilder;
    exports.vertexShaderSnippets = vertexShaderSnippets;

    Object.defineProperty(exports, '__esModule', { value: true });

}));
