text: import { decode as decodeVlq, encode as encodeVlq } from 'vlq';
  
  function decodeSegments ( encodedSegments ) {
  	let i = encodedSegments.length;
  	let segments = new Array( i );
  
  	while ( i-- ) segments[i] = decodeVlq( encodedSegments[i] );
  	return segments;
  }
  
  export function decode ( mappings ) {
  	let sourceFileIndex = 0;   // second field
  	let sourceCodeLine = 0;    // third field
  	let sourceCodeColumn = 0;  // fourth field
  	let nameIndex = 0;         // fifth field
  
  	let lines = mappings.split( ';' );
  	let numLines = lines.length;
  	let decoded = new Array( numLines );
  
  	let i;
  	let j;
  	let line;
  	let generatedCodeColumn;
  	let decodedLine;
  	let segments;
  	let segment;
  	let result;
  
  	for ( i = 0; i < numLines; i += 1 ) {
  		line = lines[i];
  
  		generatedCodeColumn = 0; // first field - reset each time
  		decodedLine = [];
  
  		segments = decodeSegments( line.split( ',' ) );
  
  		for ( j = 0; j < segments.length; j += 1 ) {
  			segment = segments[j];
  
  			if ( !segment.length ) {
  				break;
  			}
  
  			generatedCodeColumn += segment[0];
  
  			result = [ generatedCodeColumn ];
  			decodedLine.push( result );
  
  			if ( segment.length === 1 ) {
  				// only one field!
  				continue;
  			}
  
  			sourceFileIndex  += segment[1];
  			sourceCodeLine   += segment[2];
  			sourceCodeColumn += segment[3];
  
  			result.push( sourceFileIndex, sourceCodeLine, sourceCodeColumn );
  
  			if ( segment.length === 5 ) {
  				nameIndex += segment[4];
  				result.push( nameIndex );
  			}
  		}
  
  		decoded[i] = decodedLine;
  	}
  
  	return decoded;
  }
  
  export function encode ( decoded ) {
  	let offsets = {
  		generatedCodeColumn: 0,
  		sourceFileIndex: 0,   // second field
  		sourceCodeLine: 0,    // third field
  		sourceCodeColumn: 0,  // fourth field
  		nameIndex: 0          // fifth field
  	};
  
  	return decoded.map( line => {
  		offsets.generatedCodeColumn = 0; // first field - reset each time
  		return line.map( encodeSegment ).join( ',' );
  	}).join( ';' );
  
  	function encodeSegment ( segment ) {
  		if ( !segment.length ) {
  			return segment;
  		}
  
  		let result = new Array( segment.length );
  
  		result[0] = segment[0] - offsets.generatedCodeColumn;
  		offsets.generatedCodeColumn = segment[0];
  
  		if ( segment.length === 1 ) {
  			// only one field!
  			return encodeVlq( result );
  		}
  
  		result[1] = segment[1] - offsets.sourceFileIndex;
  		result[2] = segment[2] - offsets.sourceCodeLine;
  		result[3] = segment[3] - offsets.sourceCodeColumn;
  
  		offsets.sourceFileIndex  = segment[1];
  		offsets.sourceCodeLine   = segment[2];
  		offsets.sourceCodeColumn = segment[3];
  
  		if ( segment.length === 5 ) {
  			result[4] = segment[4] - offsets.nameIndex;
  			offsets.nameIndex = segment[4];
  		}
  
  		return encodeVlq( result );
  	}
  }
  