function(opt_losslessOnly) {
    if (pendingActions.length <= 1) return;

    // Lossless compression: drop inconsequential moveTos.
    for (var i = pendingActions.length - 1; i > 0; i--) {
      var action = pendingActions[i];
      if (action[0] == MOVE_TO) {
        var prevAction = pendingActions[i - 1];
        if (prevAction[1] == action[1] && prevAction[2] == action[2]) {
          pendingActions.splice(i, 1);
        }
      }
    }

    // Lossless compression: ... drop consecutive moveTos ...
    for (var i = 0; i < pendingActions.length - 1; /* incremented internally */) {
      var action = pendingActions[i];
      if (action[0] == MOVE_TO && pendingActions[i + 1][0] == MOVE_TO) {
        pendingActions.splice(i, 1);
      } else {
        i++;
      }
    }

    // Lossy compression: ... drop all but the extreme y-values ...
    if (pendingActions.length > 2 && !opt_losslessOnly) {
      // keep an initial moveTo, but drop all others.
      var startIdx = 0;
      if (pendingActions[0][0] == MOVE_TO) startIdx++;
      var minIdx = null, maxIdx = null;
      for (var i = startIdx; i < pendingActions.length; i++) {
        var action = pendingActions[i];
        if (action[0] != LINE_TO) continue;
        if (minIdx === null && maxIdx === null) {
          minIdx = i;
          maxIdx = i;
        } else {
          var y = action[2];
          if (y < pendingActions[minIdx][2]) {
            minIdx = i;
          } else if (y > pendingActions[maxIdx][2]) {
            maxIdx = i;
          }
        }
      }
      var minAction = pendingActions[minIdx],
          maxAction = pendingActions[maxIdx];
      pendingActions.splice(startIdx, pendingActions.length - startIdx);
      if (minIdx < maxIdx) {
        pendingActions.push(minAction);
        pendingActions.push(maxAction);
      } else if (minIdx > maxIdx) {
        pendingActions.push(maxAction);
        pendingActions.push(minAction);
      } else {
        pendingActions.push(minAction);
      }
    }
  }
function(opt_losslessOnly) {
    if (pendingActions.length <= 1) return;

    
    for (var i = pendingActions.length - 1; i > 0; i--) {
      var action = pendingActions[i];
      if (action[0] == MOVE_TO) {
        var prevAction = pendingActions[i - 1];
        if (prevAction[1] == action[1] && prevAction[2] == action[2]) {
          pendingActions.splice(i, 1);
        }
      }
    }

    
    for (var i = 0; i < pendingActions.length - 1; ) {
      var action = pendingActions[i];
      if (action[0] == MOVE_TO && pendingActions[i + 1][0] == MOVE_TO) {
        pendingActions.splice(i, 1);
      } else {
        i++;
      }
    }

    
    if (pendingActions.length > 2 && !opt_losslessOnly) {
      
      var startIdx = 0;
      if (pendingActions[0][0] == MOVE_TO) startIdx++;
      var minIdx = null, maxIdx = null;
      for (var i = startIdx; i < pendingActions.length; i++) {
        var action = pendingActions[i];
        if (action[0] != LINE_TO) continue;
        if (minIdx === null && maxIdx === null) {
          minIdx = i;
          maxIdx = i;
        } else {
          var y = action[2];
          if (y < pendingActions[minIdx][2]) {
            minIdx = i;
          } else if (y > pendingActions[maxIdx][2]) {
            maxIdx = i;
          }
        }
      }
      var minAction = pendingActions[minIdx],
          maxAction = pendingActions[maxIdx];
      pendingActions.splice(startIdx, pendingActions.length - startIdx);
      if (minIdx < maxIdx) {
        pendingActions.push(minAction);
        pendingActions.push(maxAction);
      } else if (minIdx > maxIdx) {
        pendingActions.push(maxAction);
        pendingActions.push(minAction);
      } else {
        pendingActions.push(minAction);
      }
    }
  }
function ( opt_losslessOnly ) { if ( pendingActions . length <= 1 ) return ; // Lossless compression: drop inconsequential moveTos. for ( var i = pendingActions . length - 1 ; i > 0 ; i -- ) { var action = pendingActions [ i ] ; if ( action [ 0 ] == MOVE_TO ) { var prevAction = pendingActions [ i - 1 ] ; if ( prevAction [ 1 ] == action [ 1 ] && prevAction [ 2 ] == action [ 2 ] ) { pendingActions . splice ( i , 1 ) ; } } } // Lossless compression: ... drop consecutive moveTos ... for ( var i = 0 ; i < pendingActions . length - 1 ; /* incremented internally */ ) { var action = pendingActions [ i ] ; if ( action [ 0 ] == MOVE_TO && pendingActions [ i + 1 ] [ 0 ] == MOVE_TO ) { pendingActions . splice ( i , 1 ) ; } else { i ++ ; } } // Lossy compression: ... drop all but the extreme y-values ... if ( pendingActions . length > 2 && ! opt_losslessOnly ) { // keep an initial moveTo, but drop all others. var startIdx = 0 ; if ( pendingActions [ 0 ] [ 0 ] == MOVE_TO ) startIdx ++ ; var minIdx = null , maxIdx = null ; for ( var i = startIdx ; i < pendingActions . length ; i ++ ) { var action = pendingActions [ i ] ; if ( action [ 0 ] != LINE_TO ) continue ; if ( minIdx === null && maxIdx === null ) { minIdx = i ; maxIdx = i ; } else { var y = action [ 2 ] ; if ( y < pendingActions [ minIdx ] [ 2 ] ) { minIdx = i ; } else if ( y > pendingActions [ maxIdx ] [ 2 ] ) { maxIdx = i ; } } } var minAction = pendingActions [ minIdx ] , maxAction = pendingActions [ maxIdx ] ; pendingActions . splice ( startIdx , pendingActions . length - startIdx ) ; if ( minIdx < maxIdx ) { pendingActions . push ( minAction ) ; pendingActions . push ( maxAction ) ; } else if ( minIdx > maxIdx ) { pendingActions . push ( maxAction ) ; pendingActions . push ( minAction ) ; } else { pendingActions . push ( minAction ) ; } } }
Drop superfluous motions Assumes all pendingActions have the same (rounded) x-value.
Drop superfluous motions Assumes all pendingActions have the same ( rounded ) x - value .