text: // Generated by CoffeeScript 1.10.0
  (function() {
    var Cv;
  
    Cv = (function() {
      function Cv(canvas) {
        this.canvas = canvas;
        this.ctx = this.canvas.getContext('2d');
      }
  
      Cv.prototype.getColorBoundsRect = function(imageData, color, threshold) {
        var i, j, pos, rect, ref, xMax, xMin, yMax, yMin;
        xMin = imageData.width;
        yMin = imageData.height;
        xMax = yMax = 0;
        for (i = j = 0, ref = imageData.length; j <= ref; i = j += 4) {
          if (color === this.getPixelColor(imageData, i)) {
            pos = this.indexToXY(i);
            if (pos.x < xMin) {
              xMin = pos.x;
            }
            if (pos.y < yMin) {
              yMin = pos.y;
            }
            if (pos.x > xMax) {
              xMax = pos.x;
            }
            if (pos.y > yMax) {
              yMax = pos.y;
            }
          }
        }
        if (xMin > xMax || yMin > yMax) {
          return null;
        } else {
          rect = {
            x: xMin,
            y: yMin,
            width: xMax - xMin,
            height: yMax - yMin
          };
          return rect;
        }
      };
  
      Cv.prototype.getPixelColor = function(imageData, pixIndex) {
        var p;
        p = [imageData[pixIndex], imageData[pixIndex + 1], imageData[pixIndex + 2]];
        return "#" + ("000000" + rgbToHex(p[0], p[1], p[2])).slice(-6);
      };
  
      Cv.prototype.getXYPixelColor = function(imageData, x, y) {
        var data, p;
        data = imageData.data;
        p = [data[(y * imageData.width * 4) + x * 4], data[(y * imageData.width * 4) + x * 4 + 1], data[(y * imageData.width * 4) + x * 4 + 2]];
        return "#" + ("000000" + rgbToHex(p[0], p[1], p[2])).slice(-6);
      };
  
      Cv.prototype.copyPixels = function(srcImageData, srcRect, destImageData, destPt) {
        var finalImageData, rectData;
        this.canvas.width = this.canvas.width;
        this.ctx.putImageData(srcImageData, 0, 0);
        rectData = this.ctx.getImageData(srcRect.x, srcRect.y, srcRect.w, srcRect.h);
        this.canvas.width = this.canvas.width;
        this.ctx.putImageData(destImageData, 0, 0);
        this.ctx.putImageData(rectData, destPt.x, destPt.y);
        finalImageData = this.ctx.getImageData(0, 0, destImageData.width, destImageData.height);
        return finalImageData;
      };
  
      Cv.prototype.indexToXY = function(width, index) {
        var x, y;
        index = index / 4;
        y = Math.floor(index / width);
        x = index % width;
        return {
          x: x,
          y: y
        };
      };
  
      Cv.prototype.XYToIndex = function(width, x, y) {
        return (y * width + x) * 4;
      };
  
      Cv.prototype.split = function(img) {
        var blue, green, i, j, red, ref;
        red = blue = green = [];
        for (i = j = 0, ref = imageData.length; j <= ref; i = j += 4) {
          red.push(imageData[i]);
          green.push(imageData[i + 1]);
          blue.push(imageData[i + 2]);
        }
        return [red, blue, green];
      };
  
      Cv.prototype.rgbToHsl = function(r, g, b) {
        var d, h, l, max, min, ref, s, sum;
        r /= 255;
        g /= 255;
        b /= 255;
        max = Math.max(r, g, b);
        min = Math.min(r, g, b);
        sum = max + min;
        l = s = h = sum / 2;
        if (max === min) {
          h = s = 0;
        } else {
          d = max - min;
          if (l > 0.5) {
            s = d / (2 - sum);
          } else {
            s = d / sum;
          }
          switch (max) {
            case r:
              h = (g - b) / d + ((ref = g < b) != null ? ref : {
                6: 0
              });
              break;
            case g:
              h = (b - r) / d + 2;
              break;
            case b:
              h = (r - g) / d + 4;
          }
          h /= 6;
        }
        return [Math.floor(h * 360), Math.floor(s * 100), Math.floor(l * 100)];
      };
  
      Cv.prototype.rgbToHex = function(r, g, b) {
        return "#" + this.componentToHex(r) + this.componentToHex(g) + this.componentToHex(b);
      };
  
      Cv.prototype.componentToHex = function(c) {
        var hex, ret;
        hex = c.toString(16);
        if (hex.length === 1) {
          ret = "0" + hex;
        } else {
          ret = hex;
        }
        return ret;
      };
  
      Cv.prototype.convertBounds = function(bounds, incanvas, outcanvas) {
        var hProportion, newBounds, wProportion, x, y;
        wProportion = outcanvas.width / incanvas.width;
        hProportion = outcanvas.height / incanvas.height;
        x = Math.floor(bounds.x);
        y = Math.floor(bounds.y);
        newBounds = {
          x: x * wProportion,
          y: y * hProportion
        };
        return newBounds;
      };
  
      Cv.prototype.convolute = function(imageData, weights, opaque) {
        var a, alphaFac, b, dst, dstOff, g, h, halfSide, j, k, m, n, output, r, ref, ref1, ref2, ref3, scx, scy, sh, side, src, srcOff, sw, sx, sy, w, wt, wx, wy, x, y;
        side = Math.round(Math.sqrt(weights.length));
        halfSide = Math.floor(side / 2);
        src = imageData.data;
        sw = imageData.width;
        sh = imageData.height;
        w = sw;
        h = sh;
        output = this.ctx.createImageData(w, h);
        dst = output.data;
        alphaFac = opaque != null ? opaque : {
          1: 0
        };
        for (y = j = 0, ref = h - 1; 0 <= ref ? j <= ref : j >= ref; y = 0 <= ref ? ++j : --j) {
          for (x = k = 0, ref1 = w - 1; 0 <= ref1 ? k <= ref1 : k >= ref1; x = 0 <= ref1 ? ++k : --k) {
            sx = x;
            sy = y;
            dstOff = (y * w + x) * 4;
            r = g = b = a = 0;
            for (wy = m = 0, ref2 = side - 1; 0 <= ref2 ? m <= ref2 : m >= ref2; wy = 0 <= ref2 ? ++m : --m) {
              for (wx = n = 0, ref3 = side - 1; 0 <= ref3 ? n <= ref3 : n >= ref3; wx = 0 <= ref3 ? ++n : --n) {
                scy = sy + wy - halfSide;
                scx = sx + wx - halfSide;
                if (scy >= 0 && scy < sh && scx >= 0 && scx < sw) {
                  srcOff = (scy * sw + scx) * 4;
                  wt = weights[wy * side + wx];
                  r += src[srcOff] * wt;
                  g += src[srcOff + 1] * wt;
                  b += src[srcOff + 2] * wt;
                  a += src[srcOff + 3] * wt;
                }
              }
            }
            dst[dstOff] = r;
            dst[dstOff + 1] = g;
            dst[dstOff + 2] = b;
            dst[dstOff + 3] = a + alphaFac * (255 - a);
          }
        }
        return output;
      };
  
      Cv.prototype.blend = function(sourceData1, sourceData2, filter) {
        var average1, average2, blendedData, data1, data2, dataBlend, diff, height, i, j, k, len, len1, len2, m, n, ref, ref1, ref2, ref3, ref4, ref5, ref6, ref7, width;
        width = this.canvas.width;
        height = this.canvas.height;
        data1 = sourceData1.data;
        data2 = sourceData2.data;
        blendedData = this.ctx.createImageData(width, height);
        dataBlend = blendedData.data;
        console.log(data1, data2);
        len1 = sourceData1.data.length - 4;
        len2 = sourceData2.data.length - 4;
        len = Math.min(len1, len2);
        switch (filter) {
          case "add":
            console.log('blend:add');
            for (i = j = 0, ref = len; j <= ref; i = j += 4) {
              dataBlend[i] = (ref1 = data1[i] + data2[i] > 255) != null ? ref1 : {
                255: data1[i] + data2[i]
              };
              dataBlend[i + 1] = (ref2 = data1[i + 1] + data2[i + 1] > 255) != null ? ref2 : {
                255: data1[i + 1] + data2[i + 1]
              };
              dataBlend[i + 2] = (ref3 = data1[i + 2] + data2[i + 2] > 255) != null ? ref3 : {
                255: data1[i + 2] + data2[i + 2]
              };
            }
            break;
          case "multiply":
            console.log('blend:multiply');
            for (i = k = 0, ref4 = len; k <= ref4; i = k += 4) {
              dataBlend[i] = (data1[i] + data2[i]) / 255;
              dataBlend[i + 1] = (data1[i + 1] + data2[i + 1]) / 255;
              dataBlend[i + 2] = (data1[i + 2] + data2[i + 2]) / 255;
            }
            break;
          case "difference":
            console.log('blend:difference');
            for (i = m = 0, ref5 = len; m <= ref5; i = m += 4) {
              dataBlend[i] = this.fastAbs(data1[i] - data2[i]);
              dataBlend[i + 1] = this.fastAbs(data1[i + 1] - data2[i + 1]);
              dataBlend[i + 2] = this.fastAbs(data1[i + 2] - data2[i + 2]);
              dataBlend[i + 3] = this.fastAbs(data1[i + 3] - data2[i + 3]);
            }
            break;
          case "differenceAverage":
            for (i = n = 0, ref6 = len; n <= ref6; i = n += 4) {
              average1 = (data1[i] + data1[i + 1] + data1[i + 2]) / 3;
              average2 = (data2[i] + data2[i + 1] + data2[i + 2]) / 3;
              diff = (ref7 = this.fastAbs(average1 - average2) > 20) != null ? ref7 : {
                255: 0
              };
              target[i] = diff;
              target[i + 1] = diff;
              target[i + 2] = diff;
              target[i + 3] = 255;
            }
        }
        console.log('blended data', blendedData.data);
        return blendedData;
      };
  
      Cv.prototype.fastAbs = function(value) {
        return (value ^ (value >> 31)) - (value >> 31);
      };
  
      Cv.prototype.threshold = function(srcImageData, rule, value, colorOut) {
        var average, data, dataThreshold, height, i, j, k, len, m, n, ref, ref1, ref2, ref3, thresholdImageData, width;
        width = srcImageData.width;
        height = srcImageData.height;
        data = srcImageData.data;
        len = srcImageData.data.length - 4;
        thresholdImageData = this.ctx.createImageData(width, height);
        dataThreshold = thresholdImageData.data;
        switch (rule) {
          case "<":
            for (i = j = 0, ref = len; j <= ref; i = j += 4) {
              average = (data[i] + data[i + 1] + data[i + 2]) / 3;
              if (average < value) {
                dataThreshold[i] = colorOut;
              }
            }
            break;
          case ">":
            for (i = k = 0, ref1 = len; k <= ref1; i = k += 4) {
              average = (data[i] + data[i + 1] + data[i + 2]) / 3;
              if (average > value) {
                dataThreshold[i] = colorOut;
              }
            }
            break;
          case "!":
            for (i = m = 0, ref2 = len; m <= ref2; i = m += 4) {
              average = (data[i] + data[i + 1] + data[i + 2]) / 3;
              if (average !== value) {
                dataThreshold[i] = colorOut;
              }
            }
            break;
          case "===":
            for (i = n = 0, ref3 = len; n <= ref3; i = n += 4) {
              average = (data[i] + data[i + 1] + data[i + 2]) / 3;
              if (average === value) {
                dataThreshold[i] = colorOut;
              }
            }
        }
        return thresholdImageData;
      };
  
      return Cv;
  
    })();
  
    window.Cv = Cv;
  
  }).call(this);
  