// Generated by CoffeeScript 1.6.1
(function() {
  var BASE64_CHARS, LineMapping, MAX_BASE64_VALUE, VLQ_CONTINUATION_BIT, VLQ_SHIFT, VLQ_VALUE_MASK, decodeBase64Char, encodeBase64Char;

  LineMapping = (function() {

    function LineMapping(generatedLine) {
      this.generatedLine = generatedLine;
      this.columnMap = {};
      this.columnMappings = [];
    }

    LineMapping.prototype.addMapping = function(generatedColumn, _arg, options) {
      var sourceColumn, sourceLine;
      sourceLine = _arg[0], sourceColumn = _arg[1];
      if (options == null) {
        options = {};
      }
      if (this.columnMap[generatedColumn] && options.noReplace) {
        return;
      }
      this.columnMap[generatedColumn] = {
        generatedLine: this.generatedLine,
        generatedColumn: generatedColumn,
        sourceLine: sourceLine,
        sourceColumn: sourceColumn
      };
      this.columnMappings.push(this.columnMap[generatedColumn]);
      return this.columnMappings.sort(function(a, b) {
        return a.generatedColumn - b.generatedColumn;
      });
    };

    LineMapping.prototype.getSourcePosition = function(generatedColumn) {
      var answer, columnMapping, lastColumnMapping, _i, _len, _ref;
      answer = null;
      lastColumnMapping = null;
      _ref = this.columnMappings;
      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
        columnMapping = _ref[_i];
        if (columnMapping.generatedColumn > generatedColumn) {
          break;
        } else {
          lastColumnMapping = columnMapping;
        }
      }
      if (lastColumnMapping) {
        return answer = [lastColumnMapping.sourceLine, lastColumnMapping.sourceColumn];
      }
    };

    return LineMapping;

  })();

  exports.SourceMap = (function() {

    function SourceMap() {
      this.generatedLines = [];
    }

    SourceMap.prototype.addMapping = function(sourceLocation, generatedLocation, options) {
      var generatedColumn, generatedLine, lineMapping;
      if (options == null) {
        options = {};
      }
      generatedLine = generatedLocation[0], generatedColumn = generatedLocation[1];
      lineMapping = this.generatedLines[generatedLine];
      if (!lineMapping) {
        lineMapping = this.generatedLines[generatedLine] = new LineMapping(generatedLine);
      }
      return lineMapping.addMapping(generatedColumn, sourceLocation, options);
    };

    SourceMap.prototype.getSourcePosition = function(_arg) {
      var answer, generatedColumn, generatedLine, lineMapping;
      generatedLine = _arg[0], generatedColumn = _arg[1];
      answer = null;
      lineMapping = this.generatedLines[generatedLine];
      if (!lineMapping) {

      } else {
        answer = lineMapping.getSourcePosition(generatedColumn);
      }
      return answer;
    };

    SourceMap.prototype.forEachMapping = function(fn) {
      var columnMapping, generatedLineNumber, lineMapping, _i, _len, _ref, _results;
      _ref = this.generatedLines;
      _results = [];
      for (generatedLineNumber = _i = 0, _len = _ref.length; _i < _len; generatedLineNumber = ++_i) {
        lineMapping = _ref[generatedLineNumber];
        if (lineMapping) {
          _results.push((function() {
            var _j, _len1, _ref1, _results1;
            _ref1 = lineMapping.columnMappings;
            _results1 = [];
            for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
              columnMapping = _ref1[_j];
              _results1.push(fn(columnMapping));
            }
            return _results1;
          })());
        } else {
          _results.push(void 0);
        }
      }
      return _results;
    };

    return SourceMap;

  })();

  exports.generateV3SourceMap = function(sourceMap, sourceFile, generatedFile) {
    var answer, lastGeneratedColumnWritten, lastSourceColumnWritten, lastSourceLineWritten, mappings, needComma, writingGeneratedLine;
    if (sourceFile == null) {
      sourceFile = null;
    }
    if (generatedFile == null) {
      generatedFile = null;
    }
    writingGeneratedLine = 0;
    lastGeneratedColumnWritten = 0;
    lastSourceLineWritten = 0;
    lastSourceColumnWritten = 0;
    needComma = false;
    mappings = "";
    sourceMap.forEachMapping(function(mapping) {
      while (writingGeneratedLine < mapping.generatedLine) {
        lastGeneratedColumnWritten = 0;
        needComma = false;
        mappings += ";";
        writingGeneratedLine++;
      }
      if (needComma) {
        mappings += ",";
        needComma = false;
      }
      mappings += exports.vlqEncodeValue(mapping.generatedColumn - lastGeneratedColumnWritten);
      lastGeneratedColumnWritten = mapping.generatedColumn;
      mappings += exports.vlqEncodeValue(0);
      mappings += exports.vlqEncodeValue(mapping.sourceLine - lastSourceLineWritten);
      lastSourceLineWritten = mapping.sourceLine;
      mappings += exports.vlqEncodeValue(mapping.sourceColumn - lastSourceColumnWritten);
      lastSourceColumnWritten = mapping.sourceColumn;
      return needComma = true;
    });
    answer = {
      version: 3,
      file: generatedFile,
      sourceRoot: "",
      sources: sourceFile ? [sourceFile] : [],
      names: [],
      mappings: mappings
    };
    return JSON.stringify(answer, null, 2);
  };

  exports.loadV3SourceMap = function(sourceMap) {
    return todo();
  };

  BASE64_CHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';

  MAX_BASE64_VALUE = BASE64_CHARS.length - 1;

  encodeBase64Char = function(value) {
    if (value > MAX_BASE64_VALUE) {
      throw new Error("Cannot encode value " + value + " > " + MAX_BASE64_VALUE);
    } else if (value < 0) {
      throw new Error("Cannot encode value " + value + " < 0");
    }
    return BASE64_CHARS[value];
  };

  decodeBase64Char = function(char) {
    var value;
    value = BASE64_CHARS.indexOf(char);
    if (value === -1) {
      throw new Error("Invalid Base 64 character: " + char);
    }
    return value;
  };

  VLQ_SHIFT = 5;

  VLQ_CONTINUATION_BIT = 1 << VLQ_SHIFT;

  VLQ_VALUE_MASK = VLQ_CONTINUATION_BIT - 1;

  exports.vlqEncodeValue = function(value) {
    var answer, nextVlqChunk, signBit, valueToEncode;
    signBit = value < 0 ? 1 : 0;
    valueToEncode = (Math.abs(value) << 1) + signBit;
    answer = "";
    while (valueToEncode || !answer) {
      nextVlqChunk = valueToEncode & VLQ_VALUE_MASK;
      valueToEncode = valueToEncode >> VLQ_SHIFT;
      if (valueToEncode) {
        nextVlqChunk |= VLQ_CONTINUATION_BIT;
      }
      answer += encodeBase64Char(nextVlqChunk);
    }
    return answer;
  };

  exports.vlqDecodeValue = function(str, offset) {
    var consumed, continuationShift, done, nextChunkValue, nextVlqChunk, position, signBit, value;
    if (offset == null) {
      offset = 0;
    }
    position = offset;
    done = false;
    value = 0;
    continuationShift = 0;
    while (!done) {
      nextVlqChunk = decodeBase64Char(str[position]);
      position += 1;
      nextChunkValue = nextVlqChunk & VLQ_VALUE_MASK;
      value += nextChunkValue << continuationShift;
      if (!(nextVlqChunk & VLQ_CONTINUATION_BIT)) {
        done = true;
      }
      continuationShift += VLQ_SHIFT;
    }
    consumed = position - offset;
    signBit = value & 1;
    value = value >> 1;
    if (signBit) {
      value = -value;
    }
    return [value, consumed];
  };

}).call(this);
