text: 'use strict';
  (function () {
  
    class RandomPushSource {
      constructor(toPush) {
        this.pushed = 0;
        this.toPush = toPush;
        this.started = false;
        this.paused = false;
        this.closed = false;
  
        this._intervalHandle = null;
      }
  
      readStart() {
        if (this.closed) {
          return;
        }
  
        if (!this.started) {
          this._intervalHandle = setInterval(writeChunk, 2);
          this.started = true;
        }
  
        if (this.paused) {
          this._intervalHandle = setInterval(writeChunk, 2);
          this.paused = false;
        }
  
        const source = this;
        function writeChunk() {
          if (source.paused) {
            return;
          }
  
          source.pushed++;
  
          if (source.toPush > 0 && source.pushed > source.toPush) {
            if (source._intervalHandle) {
              clearInterval(source._intervalHandle);
              source._intervalHandle = undefined;
            }
            source.closed = true;
            source.onend();
          } else {
            source.ondata(randomChunk(128));
          }
        }
      }
  
      readStop() {
        if (this.paused) {
          return;
        }
  
        if (this.started) {
          this.paused = true;
          clearInterval(this._intervalHandle);
          this._intervalHandle = undefined;
        } else {
          throw new Error('Can\'t pause reading an unstarted source.');
        }
      }
    }
  
    function randomChunk(size) {
      let chunk = '';
  
      for (let i = 0; i < size; ++i) {
        // Add a random character from the basic printable ASCII set.
        chunk += String.fromCharCode(Math.round(Math.random() * 84) + 32);
      }
  
      return chunk;
    }
  
    function readableStreamToArray(readable, reader) {
      if (reader === undefined) {
        reader = readable.getReader();
      }
  
      const chunks = [];
  
      return pump();
  
      function pump() {
        return reader.read().then(result => {
          if (result.done) {
            return chunks;
          }
  
          chunks.push(result.value);
          return pump();
        });
      }
    }
  
    class SequentialPullSource {
      constructor(limit, options) {
        const async = options && options.async;
  
        this.current = 0;
        this.limit = limit;
        this.opened = false;
        this.closed = false;
  
        this._exec = f => f();
        if (async) {
          this._exec = f => setTimeout(f, 0);
        }
      }
  
      open(cb) {
        this._exec(() => {
          this.opened = true;
          cb();
        });
      }
  
      read(cb) {
        this._exec(() => {
          if (++this.current <= this.limit) {
            cb(null, false, this.current);
          } else {
            cb(null, true, null);
          }
        });
      }
  
      close(cb) {
        this._exec(() => {
          this.closed = true;
          cb();
        });
      }
    }
  
    function sequentialReadableStream(limit, options) {
      const sequentialSource = new SequentialPullSource(limit, options);
  
      const stream = new ReadableStream({
        start() {
          return new Promise((resolve, reject) => {
            sequentialSource.open(err => {
              if (err) {
                reject(err);
              }
              resolve();
            });
          });
        },
  
        pull(c) {
          return new Promise((resolve, reject) => {
            sequentialSource.read((err, done, chunk) => {
              if (err) {
                reject(err);
              } else if (done) {
                sequentialSource.close(err2 => {
                  if (err2) {
                    reject(err2);
                  }
                  c.close();
                  resolve();
                });
              } else {
                c.enqueue(chunk);
                resolve();
              }
            });
          });
        }
      });
  
      stream.source = sequentialSource;
  
      return stream;
    }
  
  
    self.RandomPushSource = RandomPushSource;
    self.readableStreamToArray = readableStreamToArray;
    self.sequentialReadableStream = sequentialReadableStream;
  
  }());
  