// Generated by CoffeeScript 2.5.1
(function() {
  // This file's name is set up in such a way that it will always show up first in
  // the list of files given to coffee --join, so that the other files can assume
  // that XMLHttpRequestEventTarget was already defined.

  // The DOM EventTarget subclass used by XMLHttpRequest.

  // @see http://xhr.spec.whatwg.org/#interface-xmlhttprequest
  var InvalidStateError, NetworkError, ProgressEvent, SecurityError, SyntaxError, XMLHttpRequest, XMLHttpRequestEventTarget, XMLHttpRequestUpload, http, https, os, url;

  XMLHttpRequestEventTarget = (function() {
    class XMLHttpRequestEventTarget {
      // @private
      // This is an abstract class and should not be instantiated directly.
      constructor() {
        this.onloadstart = null;
        this.onprogress = null;
        this.onabort = null;
        this.onerror = null;
        this.onload = null;
        this.ontimeout = null;
        this.onloadend = null;
        this._listeners = {};
      }

      // Adds a new-style listener for one of the XHR events.

      // @see http://www.w3.org/TR/XMLHttpRequest/#events

      // @param {String} eventType an XHR event type, such as 'readystatechange'
      // @param {function(ProgressEvent)} listener function that will be called when
      //   the event fires
      // @return {undefined} undefined
      addEventListener(eventType, listener) {
        var base;
        eventType = eventType.toLowerCase();
        (base = this._listeners)[eventType] || (base[eventType] = []);
        this._listeners[eventType].push(listener);
        return void 0;
      }

      // Removes an event listener added by calling addEventListener.

      // @param {String} eventType an XHR event type, such as 'readystatechange'
      // @param {function(ProgressEvent)} listener the value passed in a previous
      //   call to addEventListener.
      // @return {undefined} undefined
      removeEventListener(eventType, listener) {
        var index;
        eventType = eventType.toLowerCase();
        if (this._listeners[eventType]) {
          index = this._listeners[eventType].indexOf(listener);
          if (index !== -1) {
            this._listeners[eventType].splice(index, 1);
          }
        }
        return void 0;
      }

      // Calls all the listeners for an event.

      // @param {ProgressEvent} event the event to be dispatched
      // @return {undefined} undefined
      dispatchEvent(event) {
        var eventType, j, len, listener, listeners;
        event.currentTarget = event.target = this;
        eventType = event.type;
        if (listeners = this._listeners[eventType]) {
          for (j = 0, len = listeners.length; j < len; j++) {
            listener = listeners[j];
            listener.call(this, event);
          }
        }
        if (listener = this[`on${eventType}`]) {
          listener.call(this, event);
        }
        return void 0;
      }

    };

    // @property {function(ProgressEvent)} DOM level 0-style handler
    //   for the 'loadstart' event
    XMLHttpRequestEventTarget.prototype.onloadstart = null;

    // @property {function(ProgressEvent)} DOM level 0-style handler
    //   for the 'progress' event
    XMLHttpRequestEventTarget.prototype.onprogress = null;

    // @property {function(ProgressEvent)} DOM level 0-style handler
    //   for the 'abort' event
    XMLHttpRequestEventTarget.prototype.onabort = null;

    // @property {function(ProgressEvent)} DOM level 0-style handler
    //   for the 'error' event
    XMLHttpRequestEventTarget.prototype.onerror = null;

    // @property {function(ProgressEvent)} DOM level 0-style handler
    //   for the 'load' event
    XMLHttpRequestEventTarget.prototype.onload = null;

    // @property {function(ProgressEvent)} DOM level 0-style handler
    //   for the 'timeout' event
    XMLHttpRequestEventTarget.prototype.ontimeout = null;

    // @property {function(ProgressEvent)} DOM level 0-style handler
    //   for the 'loadend' event
    XMLHttpRequestEventTarget.prototype.onloadend = null;

    return XMLHttpRequestEventTarget;

  }).call(this);

  // This file's name is set up in such a way that it will always show up second
  // in the list of files given to coffee --join, so it can use the
  // XMLHttpRequestEventTarget definition and so that the other files can assume
  // that XMLHttpRequest was already defined.
  http = require('http');

  https = require('https');

  os = require('os');

  url = require('url');

  XMLHttpRequest = (function() {
    // The ECMAScript HTTP API.

    // @see http://www.w3.org/TR/XMLHttpRequest/#introduction
    class XMLHttpRequest extends XMLHttpRequestEventTarget {
      // Creates a new request.

      // @param {Object} options one or more of the options below
      // @option options {Boolean} anon if true, the request's anonymous flag
      //   will be set
      // @see http://www.w3.org/TR/XMLHttpRequest/#constructors
      // @see http://www.w3.org/TR/XMLHttpRequest/#anonymous-flag
      constructor(options) {
        super();
        this.onreadystatechange = null;
        this._anonymous = options && options.anon;
        this.readyState = XMLHttpRequest.UNSENT;
        this.response = null;
        this.responseText = '';
        this.responseType = '';
        this.responseURL = '';
        this.status = 0;
        this.statusText = '';
        this.timeout = 0;
        this.upload = new XMLHttpRequestUpload(this);
        this._method = null; // String
        this._url = null; // Return value of url.parse()
        this._sync = false;
        this._headers = null; // Object<String, String>
        this._loweredHeaders = null; // Object<lowercase String, String>
        this._mimeOverride = null;
        this._request = null; // http.ClientRequest
        this._response = null; // http.ClientResponse
        this._responseParts = null; // Array<Buffer, String>
        this._responseHeaders = null; // Object<lowercase String, String>
        this._aborting = null;
        this._error = null;
        this._loadedBytes = 0;
        this._totalBytes = 0;
        this._lengthComputable = false;
      }

      // Sets the XHR's method, URL, synchronous flag, and authentication params.

      // @param {String} method the HTTP method to be used
      // @param {String} url the URL that the request will be made to
      // @param {?Boolean} async if false, the XHR should be processed
      //   synchronously; true by default
      // @param {?String} user the user credential to be used in HTTP basic
      //   authentication
      // @param {?String} password the password credential to be used in HTTP basic
      //   authentication
      // @return {undefined} undefined
      // @throw {SecurityError} method is not one of the allowed methods
      // @throw {SyntaxError} urlString is not a valid URL
      // @throw {Error} the URL contains an unsupported protocol; the supported
      //   protocols are file, http and https
      // @see http://www.w3.org/TR/XMLHttpRequest/#the-open()-method
      open(method, url, async, user, password) {
        var xhrUrl;
        method = method.toUpperCase();
        if (method in this._restrictedMethods) {
          throw new SecurityError(`HTTP method ${method} is not allowed in XHR`);
        }
        xhrUrl = this._parseUrl(url);
        if (async === void 0) {
          async = true;
        }
        switch (this.readyState) {
          case XMLHttpRequest.UNSENT:
          case XMLHttpRequest.OPENED:
          case XMLHttpRequest.DONE:
            // Nothing to do here.
            null;
            break;
          case XMLHttpRequest.HEADERS_RECEIVED:
          case XMLHttpRequest.LOADING:
            // TODO(pwnall): terminate abort(), terminate send()
            null;
        }
        this._method = method;
        this._url = xhrUrl;
        this._sync = !async;
        this._headers = {};
        this._loweredHeaders = {};
        this._mimeOverride = null;
        this._setReadyState(XMLHttpRequest.OPENED);
        this._request = null;
        this._response = null;
        this.status = 0;
        this.statusText = '';
        this._responseParts = [];
        this._responseHeaders = null;
        this._loadedBytes = 0;
        this._totalBytes = 0;
        this._lengthComputable = false;
        return void 0;
      }

      // Appends a header to the list of author request headers.

      // @param {String} name the HTTP header name
      // @param {String} value the HTTP header value
      // @return {undefined} undefined
      // @throw {InvalidStateError} readyState is not OPENED
      // @throw {SyntaxError} name is not a valid HTTP header name or value is not
      //   a valid HTTP header value
      // @see http://www.w3.org/TR/XMLHttpRequest/#the-setrequestheader()-method
      setRequestHeader(name, value) {
        var loweredName;
        if (this.readyState !== XMLHttpRequest.OPENED) {
          throw new InvalidStateError("XHR readyState must be OPENED");
        }
        loweredName = name.toLowerCase();
        if (this._restrictedHeaders[loweredName] || /^sec\-/.test(loweredName) || /^proxy-/.test(loweredName)) {
          console.warn(`Refused to set unsafe header \"${name}\"`);
          return void 0;
        }
        value = value.toString();
        if (loweredName in this._loweredHeaders) {
          // Combine value with the existing header value.
          name = this._loweredHeaders[loweredName];
          this._headers[name] = this._headers[name] + ', ' + value;
        } else {
          // New header.
          this._loweredHeaders[loweredName] = name;
          this._headers[name] = value;
        }
        return void 0;
      }

      // Initiates the request.

      // @param {?String, ?ArrayBufferView} data the data to be sent; ignored for
      //   GET and HEAD requests
      // @return {undefined} undefined
      // @throw {InvalidStateError} readyState is not OPENED
      // @see http://www.w3.org/TR/XMLHttpRequest/#the-send()-method
      send(data) {
        if (this.readyState !== XMLHttpRequest.OPENED) {
          throw new InvalidStateError("XHR readyState must be OPENED");
        }
        if (this._request) {
          throw new InvalidStateError("send() already called");
        }
        switch (this._url.protocol) {
          case 'file:':
            this._sendFile(data);
            break;
          case 'http:':
          case 'https:':
            this._sendHttp(data);
            break;
          default:
            throw new NetworkError(`Unsupported protocol ${this._url.protocol}`);
        }
        return void 0;
      }

      // Cancels the network activity performed by this request.

      // @return {undefined} undefined
      // @see http://www.w3.org/TR/XMLHttpRequest/#the-abort()-method
      abort() {
        if (!this._request) {
          return;
        }
        this._request.abort();
        this._setError();
        this._dispatchProgress('abort');
        this._dispatchProgress('loadend');
        return void 0;
      }

      // Returns a header value in the HTTP response for this XHR.

      // @param {String} name case-insensitive HTTP header name
      // @return {?String} value the value of the header whose name matches the
      //   given name, or null if there is no such header
      // @see http://www.w3.org/TR/XMLHttpRequest/#the-getresponseheader()-method
      getResponseHeader(name) {
        var loweredName;
        if (!this._responseHeaders) {
          return null;
        }
        loweredName = name.toLowerCase();
        if (loweredName in this._responseHeaders) {
          return this._responseHeaders[loweredName];
        } else {
          return null;
        }
      }

      // Returns all the HTTP headers in this XHR's response.

      // @return {String} header lines separated by CR LF, where each header line
      //   has the name and value separated by a ": " (colon, space); the empty
      //   string is returned if the headers are not available
      // @see http://www.w3.org/TR/XMLHttpRequest/#the-getallresponseheaders()-method
      getAllResponseHeaders() {
        var lines, name, value;
        if (!this._responseHeaders) {
          return '';
        }
        lines = (function() {
          var ref, results;
          ref = this._responseHeaders;
          results = [];
          for (name in ref) {
            value = ref[name];
            results.push(`${name}: ${value}`);
          }
          return results;
        }).call(this);
        return lines.join("\r\n");
      }

      // Overrides the Content-Type

      // @return {undefined} undefined
      // @see http://www.w3.org/TR/XMLHttpRequest/#the-overridemimetype()-method
      overrideMimeType(newMimeType) {
        if (this.readyState === XMLHttpRequest.LOADING || this.readyState === XMLHttpRequest.DONE) {
          throw new InvalidStateError("overrideMimeType() not allowed in LOADING or DONE");
        }
        this._mimeOverride = newMimeType.toLowerCase();
        return void 0;
      }

      // Network configuration not exposed in the XHR API.

      // Although the XMLHttpRequest specification calls itself "ECMAScript HTTP",
      // it assumes that requests are always performed in the context of a browser
      // application, where some network parameters are set by the browser user and
      // should not be modified by Web applications. This API provides access to
      // these network parameters.

      // NOTE: this is not in the XMLHttpRequest API, and will not work in
      // browsers.  It is a stable node-xhr2 API.

      // @param {Object} options one or more of the options below
      // @option options {?http.Agent} httpAgent the value for the nodejsHttpAgent
      //   property (the agent used for HTTP requests)
      // @option options {?https.Agent} httpsAgent the value for the
      //   nodejsHttpsAgent property (the agent used for HTTPS requests)
      // @return {undefined} undefined
      nodejsSet(options) {
        var baseUrl, parsedUrl;
        if ('httpAgent' in options) {
          this.nodejsHttpAgent = options.httpAgent;
        }
        if ('httpsAgent' in options) {
          this.nodejsHttpsAgent = options.httpsAgent;
        }
        if ('baseUrl' in options) {
          baseUrl = options.baseUrl;
          if (baseUrl !== null) {
            parsedUrl = url.parse(baseUrl, false, true);
            if (!parsedUrl.protocol) {
              throw new SyntaxError("baseUrl must be an absolute URL");
            }
          }
          this.nodejsBaseUrl = baseUrl;
        }
        return void 0;
      }

      // Default settings for the network configuration not exposed in the XHR API.

      // NOTE: this is not in the XMLHttpRequest API, and will not work in
      // browsers.  It is a stable node-xhr2 API.

      // @param {Object} options one or more of the options below
      // @option options {?http.Agent} httpAgent the default value for the
      //   nodejsHttpAgent property (the agent used for HTTP requests)
      // @option options {https.Agent} httpsAgent the default value for the
      //   nodejsHttpsAgent property (the agent used for HTTPS requests)
      // @return {undefined} undefined
      // @see XMLHttpRequest.nodejsSet
      static nodejsSet(options) {
        // "this" will be set to XMLHttpRequest.prototype, so the instance nodejsSet
        // operates on default property values.
        XMLHttpRequest.prototype.nodejsSet(options);
        return void 0;
      }

      // Sets the readyState property and fires the readystatechange event.

      // @private
      // @param {Number} newReadyState the new value of readyState
      // @return {undefined} undefined
      _setReadyState(newReadyState) {
        var event;
        this.readyState = newReadyState;
        event = new ProgressEvent('readystatechange');
        this.dispatchEvent(event);
        return void 0;
      }

      // XMLHttpRequest#send() implementation for the file: protocol.

      // @private
      _sendFile() {
        if (this._url.method !== 'GET') {
          throw new NetworkError('The file protocol only supports GET');
        }
        throw new Error("Protocol file: not implemented");
      }

      // XMLHttpRequest#send() implementation for the http: and https: protocols.

      // @private
      // This method sets the instance variables and calls _sendHxxpRequest(), which
      // is responsible for building a node.js request and firing it off. The code
      // in _sendHxxpRequest() is separated off so it can be reused when handling
      // redirects.

      // @see http://www.w3.org/TR/XMLHttpRequest/#infrastructure-for-the-send()-method
      _sendHttp(data) {
        if (this._sync) {
          throw new Error("Synchronous XHR processing not implemented");
        }
        if ((data != null) && (this._method === 'GET' || this._method === 'HEAD')) {
          console.warn(`Discarding entity body for ${this._method} requests`);
          data = null;
        } else {
          // Send Content-Length: 0
          data || (data = '');
        }
        // NOTE: this is called before finalizeHeaders so that the uploader can
        //       figure out Content-Length and Content-Type.
        this.upload._setData(data);
        this._finalizeHeaders();
        this._sendHxxpRequest();
        return void 0;
      }

      // Sets up and fires off a HTTP/HTTPS request using the node.js API.

      // @private
      // This method contains the bulk of the XMLHttpRequest#send() implementation,
      // and is also used to issue new HTTP requests when handling HTTP redirects.

      // @see http://www.w3.org/TR/XMLHttpRequest/#infrastructure-for-the-send()-method
      _sendHxxpRequest() {
        var agent, hxxp, request;
        if (this._url.protocol === 'http:') {
          hxxp = http;
          agent = this.nodejsHttpAgent;
        } else {
          hxxp = https;
          agent = this.nodejsHttpsAgent;
        }
        request = hxxp.request({
          hostname: this._url.hostname,
          port: this._url.port,
          path: this._url.path,
          auth: this._url.auth,
          method: this._method,
          headers: this._headers,
          agent: agent
        });
        this._request = request;
        if (this.timeout) {
          request.setTimeout(this.timeout, () => {
            return this._onHttpTimeout(request);
          });
        }
        request.on('response', (response) => {
          return this._onHttpResponse(request, response);
        });
        request.on('error', (error) => {
          return this._onHttpRequestError(request, error);
        });
        this.upload._startUpload(request);
        if (this._request === request) { // An http error might have already fired.
          this._dispatchProgress('loadstart');
        }
        return void 0;
      }

      // Fills in the restricted HTTP headers with default values.

      // This is called right before the HTTP request is sent off.

      // @private
      // @return {undefined} undefined
      _finalizeHeaders() {
        var base;
        this._headers['Connection'] = 'keep-alive';
        this._headers['Host'] = this._url.host;
        if (this._anonymous) {
          this._headers['Referer'] = 'about:blank';
        }
        (base = this._headers)['User-Agent'] || (base['User-Agent'] = this._userAgent);
        this.upload._finalizeHeaders(this._headers, this._loweredHeaders);
        return void 0;
      }

      // Called when the headers of an HTTP response have been received.

      // @private
      // @param {http.ClientRequest} request the node.js ClientRequest instance that
      //   produced this response
      // @param {http.ClientResponse} response the node.js ClientResponse instance
      //   passed to
      _onHttpResponse(request, response) {
        var lengthString;
        if (this._request !== request) {
          return;
        }
        // Transparent redirection handling.
        switch (response.statusCode) {
          case 301:
          case 302:
          case 303:
          case 307:
          case 308:
            this._url = this._parseUrl(response.headers['location']);
            this._method = 'GET';
            if ('content-type' in this._loweredHeaders) {
              delete this._headers[this._loweredHeaders['content-type']];
              delete this._loweredHeaders['content-type'];
            }
            // XMLHttpRequestUpload#_finalizeHeaders() sets Content-Type directly.
            if ('Content-Type' in this._headers) {
              delete this._headers['Content-Type'];
            }
            // Restricted headers can't be set by the user, no need to check
            // loweredHeaders.
            delete this._headers['Content-Length'];
            this.upload._reset();
            this._finalizeHeaders();
            this._sendHxxpRequest();
            return;
        }
        this._response = response;
        this._response.on('data', (data) => {
          return this._onHttpResponseData(response, data);
        });
        this._response.on('end', () => {
          return this._onHttpResponseEnd(response);
        });
        this._response.on('close', () => {
          return this._onHttpResponseClose(response);
        });
        this.responseURL = this._url.href.split('#')[0];
        this.status = this._response.statusCode;
        this.statusText = http.STATUS_CODES[this.status];
        this._parseResponseHeaders(response);
        if (lengthString = this._responseHeaders['content-length']) {
          this._totalBytes = parseInt(lengthString);
          this._lengthComputable = true;
        } else {
          this._lengthComputable = false;
        }
        return this._setReadyState(XMLHttpRequest.HEADERS_RECEIVED);
      }

      // Called when some data has been received on a HTTP connection.

      // @private
      // @param {http.ClientResponse} response the node.js ClientResponse instance
      //   that fired this event
      // @param {String, Buffer} data the data that has been received
      _onHttpResponseData(response, data) {
        if (this._response !== response) {
          return;
        }
        this._responseParts.push(data);
        this._loadedBytes += data.length;
        if (this.readyState !== XMLHttpRequest.LOADING) {
          this._setReadyState(XMLHttpRequest.LOADING);
        }
        return this._dispatchProgress('progress');
      }

      // Called when the HTTP request finished processing.

      // @private
      // @param {http.ClientResponse} response the node.js ClientResponse instance
      //   that fired this event
      _onHttpResponseEnd(response) {
        if (this._response !== response) {
          return;
        }
        this._parseResponse();
        this._request = null;
        this._response = null;
        this._setReadyState(XMLHttpRequest.DONE);
        this._dispatchProgress('load');
        return this._dispatchProgress('loadend');
      }

      // Called when the underlying HTTP connection was closed prematurely.

      // If this method is called, it will be called after or instead of
      // onHttpResponseEnd.

      // @private
      // @param {http.ClientResponse} response the node.js ClientResponse instance
      //   that fired this event
      _onHttpResponseClose(response) {
        var request;
        if (this._response !== response) {
          return;
        }
        request = this._request;
        this._setError();
        request.abort();
        this._setReadyState(XMLHttpRequest.DONE);
        this._dispatchProgress('error');
        return this._dispatchProgress('loadend');
      }

      // Called when the timeout set on the HTTP socket expires.

      // @private
      // @param {http.ClientRequest} request the node.js ClientRequest instance that
      //   fired this event
      _onHttpTimeout(request) {
        if (this._request !== request) {
          return;
        }
        this._setError();
        request.abort();
        this._setReadyState(XMLHttpRequest.DONE);
        this._dispatchProgress('timeout');
        return this._dispatchProgress('loadend');
      }

      // Called when something wrong happens on the HTTP socket

      // @private
      // @param {http.ClientRequest} request the node.js ClientRequest instance that
      //   fired this event
      // @param {Error} error emitted exception
      _onHttpRequestError(request, error) {
        if (this._request !== request) {
          return;
        }
        this._setError();
        request.abort();
        this._setReadyState(XMLHttpRequest.DONE);
        this._dispatchProgress('error');
        return this._dispatchProgress('loadend');
      }

      // Fires an XHR progress event.

      // @private
      // @param {String} eventType one of the XHR progress event types, such as
      //   'load' and 'progress'
      _dispatchProgress(eventType) {
        var event;
        event = new ProgressEvent(eventType);
        event.lengthComputable = this._lengthComputable;
        event.loaded = this._loadedBytes;
        event.total = this._totalBytes;
        this.dispatchEvent(event);
        return void 0;
      }

      // Sets up the XHR to reflect the fact that an error has occurred.

      // The possible errors are a network error, a timeout, or an abort.

      // @private
      _setError() {
        this._request = null;
        this._response = null;
        this._responseHeaders = null;
        this._responseParts = null;
        return void 0;
      }

      // Parses a request URL string.

      // @private
      // This method is a thin wrapper around url.parse() that normalizes HTTP
      // user/password credentials. It is used to parse the URL string passed to
      // XMLHttpRequest#open() and the URLs in the Location headers of HTTP redirect
      // responses.

      // @param {String} urlString the URL to be parsed
      // @return {Object} parsed URL
      _parseUrl(urlString) {
        var absoluteUrlString, index, password, user, xhrUrl;
        if (this.nodejsBaseUrl === null) {
          absoluteUrlString = urlString;
        } else {
          absoluteUrlString = url.resolve(this.nodejsBaseUrl, urlString);
        }
        xhrUrl = url.parse(absoluteUrlString, false, true);
        xhrUrl.hash = null;
        if (xhrUrl.auth && ((typeof user !== "undefined" && user !== null) || (typeof password !== "undefined" && password !== null))) {
          index = xhrUrl.auth.indexOf(':');
          if (index === -1) {
            if (!user) {
              user = xhrUrl.auth;
            }
          } else {
            if (!user) {
              user = xhrUrl.substring(0, index);
            }
            if (!password) {
              password = xhrUrl.substring(index + 1);
            }
          }
        }
        if (user || password) {
          xhrUrl.auth = `${user}:${password}`;
        }
        return xhrUrl;
      }

      // Reads the headers from a node.js ClientResponse instance.

      // @private
      // @param {http.ClientResponse} response the response whose headers will be
      //   imported into this XMLHttpRequest's state
      // @return {undefined} undefined
      // @see http://www.w3.org/TR/XMLHttpRequest/#the-getresponseheader()-method
      // @see http://www.w3.org/TR/XMLHttpRequest/#the-getallresponseheaders()-method
      _parseResponseHeaders(response) {
        var loweredName, name, ref, value;
        this._responseHeaders = {};
        ref = response.headers;
        for (name in ref) {
          value = ref[name];
          loweredName = name.toLowerCase();
          if (this._privateHeaders[loweredName]) {
            continue;
          }
          if (this._mimeOverride !== null && loweredName === 'content-type') {
            value = this._mimeOverride;
          }
          this._responseHeaders[loweredName] = value;
        }
        if (this._mimeOverride !== null && !('content-type' in this._responseHeaders)) {
          this._responseHeaders['content-type'] = this._mimeOverride;
        }
        return void 0;
      }

      // Sets the response and responseText properties when an XHR completes.

      // @private
      // @return {undefined} undefined
      _parseResponse() {
        var arrayBuffer, buffer, i, j, jsonError, ref, view;
        if (Buffer.concat) {
          buffer = Buffer.concat(this._responseParts);
        } else {
          // node 0.6
          buffer = this._concatBuffers(this._responseParts);
        }
        this._responseParts = null;
        switch (this.responseType) {
          case 'text':
            this._parseTextResponse(buffer);
            break;
          case 'json':
            this.responseText = null;
            try {
              this.response = JSON.parse(buffer.toString('utf-8'));
            } catch (error1) {
              jsonError = error1;
              this.response = null;
            }
            break;
          case 'buffer':
            this.responseText = null;
            this.response = buffer;
            break;
          case 'arraybuffer':
            this.responseText = null;
            arrayBuffer = new ArrayBuffer(buffer.length);
            view = new Uint8Array(arrayBuffer);
            for (i = j = 0, ref = buffer.length; (0 <= ref ? j < ref : j > ref); i = 0 <= ref ? ++j : --j) {
              view[i] = buffer[i];
            }
            this.response = arrayBuffer;
            break;
          default:
            // TODO(pwnall): content-base detection
            this._parseTextResponse(buffer);
        }
        return void 0;
      }

      // Sets response and responseText for a 'text' response type.

      // @private
      // @param {Buffer} buffer the node.js Buffer containing the binary response
      // @return {undefined} undefined
      _parseTextResponse(buffer) {
        var e;
        try {
          this.responseText = buffer.toString(this._parseResponseEncoding());
        } catch (error1) {
          e = error1;
          // Unknown encoding.
          this.responseText = buffer.toString('binary');
        }
        this.response = this.responseText;
        return void 0;
      }

      // Figures out the string encoding of the XHR's response.

      // This is called to determine the encoding when responseText is set.

      // @private
      // @return {String} a string encoding, e.g. 'utf-8'
      _parseResponseEncoding() {
        var contentType, encoding, match;
        encoding = null;
        if (contentType = this._responseHeaders['content-type']) {
          if (match = /\;\s*charset\=(.*)$/.exec(contentType)) {
            return match[1];
          }
        }
        return 'utf-8';
      }

      // Buffer.concat implementation for node 0.6.

      // @private
      // @param {Array<Buffer>} buffers the buffers whose contents will be merged
      // @return {Buffer} same as Buffer.concat(buffers) in node 0.8 and above
      _concatBuffers(buffers) {
        var buffer, j, k, len, len1, length, target;
        if (buffers.length === 0) {
          return Buffer.alloc(0);
        }
        if (buffers.length === 1) {
          return buffers[0];
        }
        length = 0;
        for (j = 0, len = buffers.length; j < len; j++) {
          buffer = buffers[j];
          length += buffer.length;
        }
        target = Buffer.alloc(length);
        length = 0;
        for (k = 0, len1 = buffers.length; k < len1; k++) {
          buffer = buffers[k];
          buffer.copy(target, length);
          length += buffer.length;
        }
        return target;
      }

    };

    // @property {function(ProgressEvent)} DOM level 0-style handler for the
    //   'readystatechange' event
    XMLHttpRequest.prototype.onreadystatechange = null;

    // @property {Number} the current state of the XHR object
    // @see http://www.w3.org/TR/XMLHttpRequest/#states
    XMLHttpRequest.prototype.readyState = null;

    // @property {String, ArrayBuffer, Buffer, Object} processed XHR response
    // @see http://www.w3.org/TR/XMLHttpRequest/#the-response-attribute
    XMLHttpRequest.prototype.response = null;

    // @property {String} response string, if responseType is '' or 'text'
    // @see http://www.w3.org/TR/XMLHttpRequest/#the-responsetext-attribute
    XMLHttpRequest.prototype.responseText = null;

    // @property {String} sets the parsing method for the XHR response
    // @see http://www.w3.org/TR/XMLHttpRequest/#the-responsetype-attribute
    XMLHttpRequest.prototype.responseType = null;

    // @property {Number} the HTTP
    // @see http://www.w3.org/TR/XMLHttpRequest/#the-status-attribute
    XMLHttpRequest.prototype.status = null;

    // @property {Number} milliseconds to wait for the request to complete
    // @see http://www.w3.org/TR/XMLHttpRequest/#the-timeout-attribute
    XMLHttpRequest.prototype.timeout = null;

    // @property {XMLHttpRequestUpload} the associated upload information
    // @see http://www.w3.org/TR/XMLHttpRequest/#the-upload-attribute
    XMLHttpRequest.prototype.upload = null;

    // readyState value before XMLHttpRequest#open() is called
    XMLHttpRequest.prototype.UNSENT = 0;

    // readyState value before XMLHttpRequest#open() is called
    XMLHttpRequest.UNSENT = 0;

    // readyState value after XMLHttpRequest#open() is called, and before
    //   XMLHttpRequest#send() is called; XMLHttpRequest#setRequestHeader() can be
    //   called in this state
    XMLHttpRequest.prototype.OPENED = 1;

    // readyState value after XMLHttpRequest#open() is called, and before
    //   XMLHttpRequest#send() is called; XMLHttpRequest#setRequestHeader() can be
    //   called in this state
    XMLHttpRequest.OPENED = 1;

    // readyState value after redirects have been followed and the HTTP headers of
    //   the final response have been received
    XMLHttpRequest.prototype.HEADERS_RECEIVED = 2;

    // readyState value after redirects have been followed and the HTTP headers of
    //   the final response have been received
    XMLHttpRequest.HEADERS_RECEIVED = 2;

    // readyState value when the response entity body is being received
    XMLHttpRequest.prototype.LOADING = 3;

    // readyState value when the response entity body is being received
    XMLHttpRequest.LOADING = 3;

    // readyState value after the request has been completely processed
    XMLHttpRequest.prototype.DONE = 4;

    // readyState value after the request has been completely processed
    XMLHttpRequest.DONE = 4;

    // @property {http.Agent} the agent option passed to HTTP requests

    // NOTE: this is not in the XMLHttpRequest API, and will not work in browsers.
    // It is a stable node-xhr2 API that is useful for testing & going through
    // web-proxies.
    XMLHttpRequest.prototype.nodejsHttpAgent = http.globalAgent;

    // @property {https.Agent} the agent option passed to HTTPS requests

    // NOTE: this is not in the XMLHttpRequest API, and will not work in browsers.
    // It is a stable node-xhr2 API that is useful for testing & going through
    // web-proxies.
    XMLHttpRequest.prototype.nodejsHttpsAgent = https.globalAgent;

    // @property {String} the base URL that relative URLs get resolved to

    // NOTE: this is not in the XMLHttpRequest API, and will not work in browsers.
    // Its browser equivalent is the base URL of the document associated with the
    // Window object. It is a stable node-xhr2 API provided for libraries such as
    // Angular Universal.
    XMLHttpRequest.prototype.nodejsBaseUrl = null;

    // HTTP methods that are disallowed in the XHR spec.

    // @private
    // @see Step 6 in http://www.w3.org/TR/XMLHttpRequest/#the-open()-method
    XMLHttpRequest.prototype._restrictedMethods = {
      CONNECT: true,
      TRACE: true,
      TRACK: true
    };

    // HTTP request headers that are disallowed in the XHR spec.

    // @private
    // @see Step 5 in
    //   http://www.w3.org/TR/XMLHttpRequest/#the-setrequestheader()-method
    XMLHttpRequest.prototype._restrictedHeaders = {
      'accept-charset': true,
      'accept-encoding': true,
      'access-control-request-headers': true,
      'access-control-request-method': true,
      connection: true,
      'content-length': true,
      cookie: true,
      cookie2: true,
      date: true,
      dnt: true,
      expect: true,
      host: true,
      'keep-alive': true,
      origin: true,
      referer: true,
      te: true,
      trailer: true,
      'transfer-encoding': true,
      upgrade: true,
      via: true
    };

    // HTTP response headers that should not be exposed according to the XHR spec.

    // @private
    // @see Step 3 in
    //     http://www.w3.org/TR/XMLHttpRequest/#the-getresponseheader()-method
    XMLHttpRequest.prototype._privateHeaders = {
      'set-cookie': true,
      'set-cookie2': true
    };

    // The default value of the User-Agent header.
    XMLHttpRequest.prototype._userAgent = `Mozilla/5.0 (${os.type()} ${os.arch()}) ` + `node.js/${process.versions.node} v8/${process.versions.v8}`;

    return XMLHttpRequest;

  }).call(this);

  // XMLHttpRequest is the result of require('node-xhr2').
  module.exports = XMLHttpRequest;

  // Make node-xhr2 work as a drop-in replacement for libraries that promote the
  // following usage pattern:
  //     var XMLHttpRequest = require('xhr-library-name').XMLHttpRequest
  XMLHttpRequest.XMLHttpRequest = XMLHttpRequest;

  // This file defines the custom errors used in the XMLHttpRequest specification.

    // Thrown if the XHR security policy is violated.
  SecurityError = class SecurityError extends Error {
    // @private
    constructor() {
      super();
    }

  };

  // Thrown if the XHR security policy is violated.
  XMLHttpRequest.SecurityError = SecurityError;

  // Usually thrown if the XHR is in the wrong readyState for an operation.
  InvalidStateError = class InvalidStateError extends Error {
    // @private
    constructor() {
      super();
    }

  };

  // Usually thrown if the XHR is in the wrong readyState for an operation.
  InvalidStateError = class InvalidStateError extends Error {};

  XMLHttpRequest.InvalidStateError = InvalidStateError;

  // Thrown if there is a problem with the URL passed to the XHR.
  NetworkError = class NetworkError extends Error {
    // @private
    constructor() {
      super();
    }

  };

  // Thrown if parsing URLs errors out.
  XMLHttpRequest.SyntaxError = SyntaxError;

  SyntaxError = class SyntaxError extends Error {
    // @private:
    constructor() {
      super();
    }

  };

  ProgressEvent = (function() {
    // http://xhr.spec.whatwg.org/#interface-progressevent
    class ProgressEvent {
      // Creates a new event.

      // @param {String} type the event type, e.g. 'readystatechange'; must be
      //   lowercased
      constructor(type) {
        this.type = type;
        this.target = null;
        this.currentTarget = null;
        this.lengthComputable = false;
        this.loaded = 0;
        this.total = 0;
      }

    };

    // Getting the time from the OS is expensive, skip on that for now.
    // @timeStamp = Date.now()

    // @property {Boolean} for compatibility with DOM events
    ProgressEvent.prototype.bubbles = false;

    // @property {Boolean} for fompatibility with DOM events
    ProgressEvent.prototype.cancelable = false;

    // @property {XMLHttpRequest} the request that caused this event
    ProgressEvent.prototype.target = null;

    // @property {Number} number of bytes that have already been downloaded or
    //   uploaded
    ProgressEvent.prototype.loaded = null;

    // @property {Boolean} true if the Content-Length response header is available
    //   and the value of the event's total property is meaningful
    ProgressEvent.prototype.lengthComputable = null;

    // @property {Number} number of bytes that will be downloaded or uploaded by
    //   the request that fired the event
    ProgressEvent.prototype.total = null;

    return ProgressEvent;

  }).call(this);

  // The XHR spec exports the ProgressEvent constructor.
  XMLHttpRequest.ProgressEvent = ProgressEvent;

  // @see http://xhr.spec.whatwg.org/#interface-xmlhttprequest
  XMLHttpRequestUpload = class XMLHttpRequestUpload extends XMLHttpRequestEventTarget {
    // @private
    // @param {XMLHttpRequest} the XMLHttpRequest that this upload object is
    //   associated with
    constructor(request) {
      super();
      this._request = request;
      this._reset();
    }

    // Sets up this Upload to handle a new request.

    // @private
    // @return {undefined} undefined
    _reset() {
      this._contentType = null;
      this._body = null;
      return void 0;
    }

    // Implements the upload-related part of the send() XHR specification.

    // @private
    // @param {?String, ?Buffer, ?ArrayBufferView} data the argument passed to
    //   XMLHttpRequest#send()
    // @return {undefined} undefined
    // @see step 4 of http://www.w3.org/TR/XMLHttpRequest/#the-send()-method
    _setData(data) {
      var body, i, j, k, offset, ref, ref1, view;
      if (typeof data === 'undefined' || data === null) {
        return;
      }
      if (typeof data === 'string') {
        // DOMString
        if (data.length !== 0) {
          this._contentType = 'text/plain;charset=UTF-8';
        }
        this._body = Buffer.from(data, 'utf8');
      } else if (Buffer.isBuffer(data)) {
        // node.js Buffer
        this._body = data;
      } else if (data instanceof ArrayBuffer) {
        // ArrayBuffer arguments were supported in an old revision of the spec.
        body = Buffer.alloc(data.byteLength);
        view = new Uint8Array(data);
        for (i = j = 0, ref = data.byteLength; (0 <= ref ? j < ref : j > ref); i = 0 <= ref ? ++j : --j) {
          body[i] = view[i];
        }
        this._body = body;
      } else if (data.buffer && data.buffer instanceof ArrayBuffer) {
        // ArrayBufferView
        body = Buffer.alloc(data.byteLength);
        offset = data.byteOffset;
        view = new Uint8Array(data.buffer);
        for (i = k = 0, ref1 = data.byteLength; (0 <= ref1 ? k < ref1 : k > ref1); i = 0 <= ref1 ? ++k : --k) {
          body[i] = view[i + offset];
        }
        this._body = body;
      } else {
        // NOTE: diverging from the XHR specification of coercing everything else
        //       to Strings via toString() because that behavior masks bugs and is
        //       rarely useful
        throw new Error(`Unsupported send() data ${data}`);
      }
      return void 0;
    }

    // Updates the HTTP headers right before the request is sent.

    // This is used to set data-dependent headers such as Content-Length and
    // Content-Type.

    // @private
    // @param {Object<String, String>} headers the HTTP headers to be sent
    // @param {Object<String, String>} loweredHeaders maps lowercased HTTP header
    //   names (e.g., 'content-type') to the actual names used in the headers
    //   parameter (e.g., 'Content-Type')
    // @return {undefined} undefined
    _finalizeHeaders(headers, loweredHeaders) {
      if (this._contentType) {
        if (!('content-type' in loweredHeaders)) {
          headers['Content-Type'] = this._contentType;
        }
      }
      if (this._body) {
        // Restricted headers can't be set by the user, no need to check
        // loweredHeaders.
        headers['Content-Length'] = this._body.length.toString();
      }
      return void 0;
    }

    // Starts sending the HTTP request data.

    // @private
    // @param {http.ClientRequest} request the HTTP request
    // @return {undefined} undefined
    _startUpload(request) {
      if (this._body) {
        request.write(this._body);
      }
      request.end();
      return void 0;
    }

  };

  // Export the XMLHttpRequestUpload constructor.
  XMLHttpRequest.XMLHttpRequestUpload = XMLHttpRequestUpload;

}).call(this);
