function Roundabout(opts) {
  if (!(this instanceof Roundabout)) return new Roundabout(opts);
  Duplex.call(this, opts);

  // roundabout proxy state
  var state = {};
  state.streams = [];
  state.finished = false;
  state.input = new PassThrough();
  state.output = new PassThrough();
  state.input.pipe(state.output);

  // set state
  this._roundaboutState = state;

  // adapt options
  setInputState(this, this);
  setOutputState(this, this);

  var self = this;
  this.on('finish', function() {
    var ws = this._writableState;
    var input = this._roundaboutState.input;
    var iws = input._writableState;
    if (!ws.buffer.length && !iws.buffer.length && !iws.ending) {
      debug('(finish) input.end()');
      input.end();
    }
  });

  // nudge reader
  state.output.on('readable', function() {
    debug('(output) readable: emit _nudge');
    self.emit('_nudge');
  });

  // listen for output end
  state.output.on('end', function() {
    debug('(output) end: emit _nudge');
    state.finished = true;
    self.emit('_nudge');
  });
}
/**
 * Roundabout streams start as passthrough streams
 * with the options given. Every subsequent streams
 * added will alter the readable and writable state
 * of the roundabout stream and the internal passthrough
 * streams.
 *
 * @param {Object} Duplex options
 * @return {Roundabout)
 */
Roundabout streams start as passthrough streams
with the options given. Every subsequent streams
added will alter the readable and writable state
of the roundabout stream and the internal passthrough
streams.

@param {Object} Duplex options
@return {Roundabout)
Roundabout streams start as passthrough streams with the options given . Every subsequent streams added will alter the readable and writable state of the roundabout stream and the internal passthrough streams . @param { Object } Duplex options @return { Roundabout )
function Roundabout(opts) {
  if (!(this instanceof Roundabout)) return new Roundabout(opts);
  Duplex.call(this, opts);
  var state = {};
  state.streams = [];
  state.finished = false;
  state.input = new PassThrough();
  state.output = new PassThrough();
  state.input.pipe(state.output);
  this._roundaboutState = state;
  setInputState(this, this);
  setOutputState(this, this);
  var self = this;
  this.on('finish', function() {
    var ws = this._writableState;
    var input = this._roundaboutState.input;
    var iws = input._writableState;
    if (!ws.buffer.length && !iws.buffer.length && !iws.ending) {
      debug('(finish) input.end()');
      input.end();
    }
  });
  state.output.on('readable', function() {
    debug('(output) readable: emit _nudge');
    self.emit('_nudge');
  });
  state.output.on('end', function() {
    debug('(output) end: emit _nudge');
    state.finished = true;
    self.emit('_nudge');
  });
}
function Roundabout ( opts ) { if ( ! ( this instanceof Roundabout ) ) return new Roundabout ( opts ) ; Duplex . call ( this , opts ) ; var state = { } ; state . streams = [ ] ; state . finished = false ; state . input = new PassThrough ( ) ; state . output = new PassThrough ( ) ; state . input . pipe ( state . output ) ; this . _roundaboutState = state ; setInputState ( this , this ) ; setOutputState ( this , this ) ; var self = this ; this . on ( 'finish' , function ( ) { var ws = this . _writableState ; var input = this . _roundaboutState . input ; var iws = input . _writableState ; if ( ! ws . buffer . length && ! iws . buffer . length && ! iws . ending ) { debug ( '(finish) input.end()' ) ; input . end ( ) ; } } ) ; state . output . on ( 'readable' , function ( ) { debug ( '(output) readable: emit _nudge' ) ; self . emit ( '_nudge' ) ; } ) ; state . output . on ( 'end' , function ( ) { debug ( '(output) end: emit _nudge' ) ; state . finished = true ; self . emit ( '_nudge' ) ; } ) ; }
Roundabout streams start as passthrough streams
 with the options given.
Roundabout streams start as passthrough streams with the options given .
// roundabout proxy state // set state // adapt options // nudge reader // listen for output end