Use next line in your code var AgarioClient = require('agario-client'); //Use this in your code We will need to create new agent for every new connection so we will make function
329451
function createAgent() {
    return new Socks.Agent({
            proxy: {
                ipaddress: process.argv[3],
                port: parseInt(process.argv[4]),
                type: parseInt(process.argv[2])
            }}
    );
}
962732
function startAllConnections() {
  try {
    myUtils.validateConfig();
  }
  catch(e) {
    console.error(e.message);
    process.exit(2);
  }

  // redefine keys method before connections are started
  if (config.get('redis.useScan')) {
    console.log('Using scan instead of keys');
    Object.defineProperty(Redis.prototype, 'keys', {
      value: function(pattern, cb) {
        let keys = [];
        let that = this;
        let scanCB = function(err, res) {
          if (err) {
            if (typeof cb === 'function') cb(err);
            else {
              console.log('ERROR in redefined "keys" function to use "scan" instead without callback: ' + JSON.stringify(err));
            }
          }
          else {
            let count = res[0], curKeys = res[1];
            console.log("scanning: " + count + ": " + curKeys.length);
            keys = keys.concat(curKeys);
            if (Number(count) === 0) {
              if (typeof cb === 'function') cb(null, keys);
              else {
                console.log('ERROR in redefined "keys" function to use "scan" instead - no callback given!');
              }
            }
            else {
              that.scan(count, 'MATCH', pattern, 'COUNT', config.get('redis.scanCount'), scanCB);
            }
          }
        };
        return this.scan(0, 'MATCH', pattern, 'COUNT', config.get('redis.scanCount'), scanCB);
      }
    });
  }

  // first default connections from config object
  // second connection from cli params (redis-host, redis-port, ...)
  startDefaultConnections(config.connections, function (err) {
    if (err) {
      console.log(err);
      process.exit();
    }
    let db = parseInt(args['redis-db']);
    if (isNaN(db)) {
        db = 0;
    }

    let client;
    if (args['sentinel-host'] || args['sentinels'] || args['redis-host'] || args['redis-port'] || args['redis-socket'] || args['redis-password']) {
      let newDefault = {
        "label": config.get('redis.defaultLabel'),
        "dbIndex": db,
        "password": args['redis-password'] || '',
        "connectionName": config.get('redis.connectionName')
      };

      if (args['redis-socket']) {
        newDefault.path = args['redis-socket'];
      }
      else {
        newDefault.host = args['redis-host'] || "localhost";
        newDefault.port = args['redis-port'] || "6379";
        newDefault.sentinel_name = args['sentinel-name'];
        if (args['sentinels']) {
          newDefault.sentinels = myUtils.parseRedisSentinel('--sentinels', args['sentinels']);
        }
        else if (args['sentinel-host']) {
          newDefault.sentinels = myUtils.parseRedisSentinel( '--sentinel-host or --sentinel-port',
            args['sentinel-host'] + ':' + args['sentinel-port']);
        }
      }

      if (args['redis-tls']) {
        newDefault.tls = {};
      }

      if (!myUtils.containsConnection(config.connections, newDefault)) {
        client = myUtils.createRedisClient(newDefault);
        redisConnections.push(client);
        config.connections.push(newDefault);
        if (!config.get('noSave')) {
          myUtils.saveConnections(config,function (err) {
            if (err) {
              console.log("Problem saving connection config.");
              console.error(err);
            }
          });
        }
        setUpConnection(client, db);
      }
    } else if (config.connections.length === 0) {
      // fallback to localhost if nothing else configured
      client = myUtils.createRedisClient({label: config.get('redis.defaultLabel')});
      redisConnections.push(client);
      setUpConnection(client, db);
    }

    return startWebApp();
  });

  // wait a bit before starting browser to let http server start
  if (args['open']) {
    setTimeout(function() {
      let address = '127.0.0.1';
      if (config.get('server.address') !== '0.0.0.0' && config.get('server.address') !== '::') {
        address = config.get('server.address');
      }
      require('opener')('http://' + address + ':' + config.get('server.port'));
    }, 1000);
  }
}
1141023
async function connectToServer(client, config) {
  return new Promise((resolve, reject) => {
    client
      .on('ready', error => (error ? reject(error) : resolve(client)))
      .on('error', error => reject(error))
      .connect(config);
  });
}
393691
function createClientType() {
    log.info("create client");
    // [ -Events- ]
    // error - when there's a problem with a received message
    // open - when the connection is open
    // close - when the connection is closed
    // message - when there's a message from the hub
    // [ -Constructor- ]
    function Client() {
        log.info("instantiate client");
        // get non-ambiguous this
        var self = this;
        // Call parent constructor
        Client.super_.call(self);
        // Internal structures
        self._transport = undefined;
        self._txRegistry = {};
        self._lastTxId = 0;
        self._txLimit = 1000;
        self._state = "NOT_OPENED";
        self._messageDispatch = {
            distribution: self._handleDistribution.bind(self),
            published: self._handlePublication.bind(self),
            subscribed: self._handleSubscription.bind(self),
            unsubscribed: self._handleUnsubscription.bind(self),
        };
        // state listeners
        self.once("open", function handleOpened() {
            self._state = "OPEN";
        }).once("close", function handleClosed() {
            self._state = "CLOSED";
        });
        // constructor - return undefined
        return undefined;
    }
    // [ -Inheritance- ]
    util.inherits(Client, events.EventEmitter);
    // [ -Private API- ]
    // check state for OPEN
    Client.prototype._checkState = function clientCheckState() {
        if (this._state !== "OPEN") {
            throw new VError("Nonsensical to call before 'open' or after 'close' events");
        }
        return this;
    };
    // get a transaction ID
    Client.prototype._getTxID = function clientGetTxID() {
        var txid;
        // try the last txid + 1 first
        var candidate = this._lastTxId + 1;
        // try to get a txid until we get one, or we've failed _txLimit times
        // (this means we have _txLimit txid's already assigned)
        var tries = 0;
        while (txid === undefined && tries < this._txLimit) {
            tries++;
            candidate %= this._txLimit;
            if (this._txRegistry[candidate] === undefined) {
                txid = candidate;
            } else {
                candidate++;
            }
        }
        // catch the error exit
        if (txid === undefined) {
            throw new VError("Cannot issue a transaction ID - too many outstanding transactions (%d)", this._txLimit);
        }
        // set the last txid and return it to the caller
        this._lastTxId = txid;
        return txid;
    };
    // register a transaction ID
    Client.prototype._registerTxID = function clientRegisterTxID(txid, cb) {
        this._txRegistry[txid] = cb;
        // allow chaining
        return this;
    };
    // retire a transaction ID
    Client.prototype._retireTxID = function clientRetireTxID(txid) {
        delete this._txRegistry[txid];
        // allow chaining
        return this;
    };
    // handle publication message
    Client.prototype._handlePublication = function clientHandlePublication(messageObj) {
        log.info("client handle publication");
        // validate message
        var error = validateProperties(
            messageObj,
           "published message from transport layer",
           ['type', 'message', 'channel', 'number', 'transactionID'],
           []
        );
        // FIXME - message should be JSON
        // FIXME - channel should be string
        // FIXME - number should be a number
        // FIXME - txid should be number
        // FIXME - need a test for no tx callback (on purpose)
        if (error) { this.emit('error', error); return null; }
        var transactionCallback = this._txRegistry[messageObj.transactionID];
        if (transactionCallback) {
            transactionCallback(null, messageObj.message, messageObj.channel, messageObj.number);
            this._retireTxID(messageObj.transactionID);
        } else {
            this.emit('error', new VError("received a message with an unrecognized transaction ID: %j", messageObj));
        }
        // allow chaining
        return this;
    };
    // handle subscription message
    Client.prototype._handleSubscription = function clientHandleSubscription(messageObj) {
        log.info("client on subscribed");
        var error = validateProperties(
            messageObj,
           "subscribed message from transport layer",
           ['type', 'pattern', 'number', 'transactionID'],
           []
        );
        // FIXME - pattern should be regex
        // FIXME - number should be a number
        if (error) { this.emit('error', error); return null; }
        var transactionCallback = this._txRegistry[messageObj.transactionID];
        if (transactionCallback) {
            log.debug("calling tx callback with", messageObj.pattern, messageObj.number);
            transactionCallback(null, messageObj.pattern, messageObj.number);
            this._retireTxID(messageObj.transactionID);
        } else {
            this.emit('error', new VError("received a message with an unrecognized transaction ID: %j", messageObj));
        }
        // allow chaining
        return this;
    };
    // handle unsubscription message
    Client.prototype._handleUnsubscription = function clientHandleUnsubscription(messageObj) {
        log.info("client on unsubscribed");
        var error = validateProperties(
            messageObj,
           "unsubscribed message from transport layer",
           ['type', 'pattern', 'number', 'transactionID'],
           []
        );
        // FIXME - pattern should be regex
        // FIXME - number should be a number
        if (error) { this.emit('error', error); return null; }
        var transactionCallback = this._txRegistry[messageObj.transactionID];
        if (transactionCallback) {
            transactionCallback(null, messageObj.pattern, messageObj.number);
            this._retireTxID(messageObj.transactionID);
        } else {
            this.emit('error', new VError("received a message with an unrecognized transaction ID: %j", messageObj));
        }
        // allow chaining
        return this;
    };
    // handle distributions
    Client.prototype._handleDistribution = function clientDistribute(messageObj) {
        log.info("client on distribution");
        var error = validateProperties(
            messageObj,
           "distribution message from transport layer",
           ['type', 'message', 'channel', 'match'],
           []
        );
        // FIXME - message should be JSON
        // FIXME - channel should be string
        // FIXME - match should be a regex
        if (error) { this.emit('error', error); return null; }
        this.emit('message', messageObj.message, messageObj.channel, messageObj.match);
        // allow chaining
        return this;
    };
    // handle messages from the transport layer
    Client.prototype._handleMessage = function clientHandleMessage(messageObj) {
        log.info("client handle message", this._id, messageObj);
        // parse the message type and respond accordingly
        var handler = this._messageDispatch[messageObj.type];
        if (handler === undefined) {
            this.emit('error', new VError("No dispatcher found for message type (%s) (%j)", messageObj.type, messageObj));
        } else {
            handler(messageObj);
        }
        // allow chaining
        return this;
    };
    // [ -Public API- ]
    // get/set the limit for the max number of client-initiated
    // transactions in flight simultaneously
    Client.prototype.txLimit = function clientTxLimit(limit) {
        if (limit) {
            this._txLimit = limit;
        }
        return this._txLimit;
    };
    // subscribe a subscriber
    Client.prototype.subscribe = function clientSubscribe(pattern, cb) {
        log.info("client subscribe", this._transport._id, pattern);
        // get a non-ambiguous "this"
        var self = this;
        // check state
        this._checkState();
        // get a transaction id
        var txid;
        try {
            txid = self._getTxID();
        } catch (e) {
            callback(cb)(new VError(e, "cannot subscribe - no transaction ID available."));
            // early return because we don't want to execute anything else,
            // and js has no try/catch/else
            return self;
        }
        self._registerTxID(txid, callback(cb));
        // send subscription request
        self._transport.send({
            type: 'subscription',
            'pattern': pattern,
            transactionID: txid,
        }, function handleCompletion(error) {
            // if there's an error, need to retire the TXID early.
            // assumes a send error means the message was not sent,
            // and there's not going to be a corresponding response.
            if (error) {
                self._retireTxID(txid);
                cb(error);
            }
            return null;
        });
        // allow chaining of calls
        return self;
    };
    // unsubscribe a pattern
    Client.prototype.unsubscribe = function clientUnsubscribe(pattern, cb) {
        log.info("client unsubscribe", this._transport._id, pattern);
        // get a non-ambiguous "this"
        var self = this;
        // check state
        this._checkState();
        // get a transaction id
        var txid;
        try {
            txid = self._getTxID();
        } catch (e) {
            callback(cb)(new VError(e, "cannot unsubscribe - no transaction ID available."));
            return self;
        }
        self._registerTxID(txid, callback(cb));
        // send unsubscription request
        self._transport.send({
            type: 'unsubscription',
            'pattern': pattern,
            transactionID: txid,
        }, function handleCompletion(error) {
            // if there's an error, need to retire the TXID early.
            // assumes a send error means the message was not sent,
            // and there's not going to be a corresponding response.
            if (error) {
                self._retireTxID(txid);
                callback(cb)(error);
            }
            return null;
        });
        // allow chaining
        return self;
    };
    // publish to subscribers
    Client.prototype.publish = function clientPublish(message, channel, cb) {
        log.info("client publish", this._transport._id, message);
        var self = this;
        // check state
        this._checkState();
        // get a transaction id
        var txid;
        try {
            txid = self._getTxID();
        } catch (e) {
            callback(cb)(new VError(e, "cannot publish - no transaction ID available."));
            return self;
        }
        self._registerTxID(txid, callback(cb));
        // send publication request
        self._transport.send({
            type: 'publication',
            'message': message,
            'channel': channel,
            transactionID: txid,
        }, function handleCompletion(error) {
            // if there's an error, need to retire the TXID early.
            // assumes a send error means the message was not sent,
            // and there's not going to be a corresponding response.
            if (error) {
                self._retireTxID(txid);
                callback(cb)(new VError(error, "Error sending to hub"));
            }
            return null;
        });
        // allow chaining
        return self;
    };
    // close a transport object
    Client.prototype.close = function clientClose() {
        log.info("client close");
        if (this._state !== "OPEN") {
            throw new VError("Cannot close a client which is not open");
        }
        this._transport.close();
        // it doesn't make sense to do anything with the object after this,
        // so return null
        return null;
    };
    // connect to listening client
    Client.prototype.connect = function clientConnect(url, cb) {
        log.info("client connect");
        // only allow this to be called once on the object
        if (this._transport) {
            // throw immediately - this is programmer error
            throw new VError("'connect' has already been called on this client.");
        }
        // add cb to listeners
        if (cb) {
            this.on('open', cb);
        }
        // open a new transport connection
        this._transport = new ActualTransportClient();
        this._transport.connect(url);
        // proxy some events
        this._transport.on('open', this.emit.bind(this, 'open'));
        this._transport.on('close', this.emit.bind(this, 'close'));
        // handle messages from transport
        this._transport.on('message', this._handleMessage.bind(this));
        // it doesn't make sense to do anything with the object until connect
        // calls back, so return null
        return null;
    };
    // return a new Client
    return Client;
}
414657
function () {
            var ret = new Promise(), conn;
            if (this.count > this.__maxObjects) {
                this.__deferredQueue.enqueue(ret);
            } else {
                //todo override getObject to make async so creating a connetion can execute setup sql
                conn = this.getObject();
                if (!conn) {
                    //we need to deffer it
                    this.__deferredQueue.enqueue(ret);
                } else {
                    ret.callback(conn);
                }
            }
            if (this.count > this.__maxObjects && !conn) {
                ret.errback(new Error("Unexpected ConnectionPool error"));
            }
            return ret.promise();
        }
239451
function ConnectionServer(endpoint, options, connectionListener) {
  events.EventEmitter.call(this);

  if (!(endpoint instanceof Endpoint)) {
    endpoint = new Endpoint(endpoint);
  }
  if (typeof options === 'function') {
    connectionListener = options;
    options = undefined;
  }

  this.endpoint = endpoint;
  this.options = options || {};
  if (typeof connectionListener === 'function') {
    this.on('connection', connectionListener);
  }

  listen.call(this);
}
826914
async function connect() {
  
  let esConfig
  let client

  // use local client
  if (!process.env.ES_HOST) {
    client = new elasticsearch.Client({host: 'localhost:9200'})
  } else {
    await new Promise((resolve, reject) => AWS.config.getCredentials((err) => {
      if (err) return reject(err)
      resolve()
    }))

    esConfig = {
      host: process.env.ES_HOST,
      connectionClass: httpAwsEs,
      amazonES: {
        region: process.env.AWS_DEFAULT_REGION || 'us-east-1',
        credentials: AWS.config.credentials
      },
      // Note that this doesn't abort the query.
      requestTimeout: 120000  // milliseconds
    }
    client = new elasticsearch.Client(esConfig)
  }

  await new Promise((resolve, reject) => client.ping({requestTimeout: 1000}, (err) => {
    if (err) {
      console.log('unable to connect to elasticsearch')
      reject('unable to connect to elasticsearch')
    } else {
      resolve()
    }
  }))
  return client
}
1269131
function newClientStub() {
    // First create the appropriate TLS certs with dgraph cert:
    //     $ dgraph cert
    //     $ dgraph cert -n localhost
    //     $ dgraph cert -c user
    const rootCaCert = fs.readFileSync(path.join(__dirname, 'tls', 'ca.crt'));
    const clientCertKey = fs.readFileSync(path.join(__dirname, 'tls', 'client.user.key'));
    const clientCert = fs.readFileSync(path.join(__dirname, 'tls', 'client.user.crt'));
    return new dgraph.DgraphClientStub(
        "localhost:9080",
        grpc.credentials.createSsl(rootCaCert, clientCertKey, clientCert));
}
163494
function Connection(options) {
  //*****************************************************************
  // public API functions
  //*****************************************************************

  /**
   * Connect event
   *
   * @returns {Promise} promise
   */
  this.connect = () => {
    switch (_status) {
      case Status.NOT_CONNECTED:
        _status = Status.CONNECTING;
        return new Promise(function(resolve, reject) {
          _registerHandshakeCmd(resolve, reject);
        });

      case Status.CLOSING:
      case Status.CLOSED:
        return Promise.reject(
          Errors.createError(
            'Connection closed',
            true,
            info,
            '08S01',
            Errors.ER_CONNECTION_ALREADY_CLOSED
          )
        );

      case Status.CONNECTING:
      case Status.AUTHENTICATING:
        return Promise.reject(
          Errors.createError(
            'Connection is already connecting',
            true,
            info,
            '08S01',
            Errors.ER_ALREADY_CONNECTING
          )
        );
    }
    //status Connected
    return Promise.resolve(this);
  };

  /**
   * Permit to change user during connection.
   * All user variables will be reset, Prepare commands will be released.
   * !!! mysql has a bug when CONNECT_ATTRS capability is set, that is default !!!!
   *
   * @param options   connection options
   * @returns {Promise} promise
   */
  this.changeUser = options => {
    if (!info.isMariaDB()) {
      return Promise.reject(
        Errors.createError(
          'method changeUser not available for MySQL server due to Bug #83472',
          false,
          info,
          '0A000',
          Errors.ER_MYSQL_CHANGE_USER_BUG
        )
      );
    }

    return new Promise(function(resolve, reject) {
      _addCommand(
        new ChangeUser(
          options,
          resolve,
          _authFailHandler.bind(this, reject),
          _addCommand.bind(this)
        )
      );
    });
  };

  /**
   * Start transaction
   *
   * @returns {Promise} promise
   */
  this.beginTransaction = () => {
    return this.query('START TRANSACTION');
  };

  /**
   * Commit a transaction.
   *
   * @returns {Promise} command if commit was needed only
   */
  this.commit = () => {
    return _changeTransaction('COMMIT');
  };

  /**
   * Roll back a transaction.
   *
   * @returns {Promise} promise
   */
  this.rollback = () => {
    return _changeTransaction('ROLLBACK');
  };

  /**
   * Execute query using text protocol.
   *
   * @param sql     sql parameter Object can be used to supersede default option.
   *                Object must then have sql property.
   * @param values  object / array of placeholder values (not mandatory)
   * @returns {Promise} promise
   */
  this.query = (sql, values) => {
    let _cmdOpt, _sql;
    if (typeof sql === 'object') {
      _cmdOpt = sql;
      _sql = _cmdOpt.sql;
    } else {
      _sql = sql;
    }

    return new Promise(function(resolve, reject) {
      const cmd = new Query(resolve, reject, _cmdOpt, opts, _sql, values);
      if (opts.trace) Error.captureStackTrace(cmd);
      _addCommand(cmd);
    });
  };

  /**
   * Execute batch using text protocol.
   *
   * @param sql     sql parameter Object can be used to supersede default option.
   *                Object must then have sql property.
   * @param initialValues  object / array of placeholder values (not mandatory)
   * @returns {Promise} promise
   */
  this.batch = (sql, initialValues) => {
    let _options, _sql;
    if (typeof sql === 'object') {
      _options = sql;
      _sql = _options.sql;
    } else {
      _sql = sql;
    }

    return new Promise(function(resolve, reject) {
      let useBulk = canUseBulk(initialValues);

      const cmd = useBulk
        ? new BatchBulk(resolve, reject, _options, opts, _sql, initialValues)
        : new BatchRewrite(
            resolve,
            reject,
            _options,
            opts,
            _sql,
            initialValues
          );
      if (opts.trace) Error.captureStackTrace(cmd);
      _addCommand(cmd);
    });
  };

  /**
   * Execute query returning a Readable Object that will emit columns/data/end/error events
   * to permit streaming big result-set
   *
   * @param sql     sql parameter Object can be used to supersede default option.
   *                Object must then have sql property.
   * @param values  object / array of placeholder values (not mandatory)
   * @returns {Readable}
   */
  this.queryStream = (sql, values) => {
    let _cmdOpt, _sql;
    if (typeof sql === 'object') {
      _cmdOpt = sql;
      _sql = _cmdOpt.sql;
    } else {
      _sql = sql;
    }

    const cmd = new Stream(_cmdOpt, opts, _sql, values, _socket);
    if (opts.trace) Error.captureStackTrace(cmd);
    _addCommand(cmd);
    return cmd.inStream;
  };

  /**
   * Send an empty MySQL packet to ensure connection is active, and reset @@wait_timeout
   *
   * @returns {Promise} promise
   */
  this.ping = () => {
    return new Promise(function(resolve, reject) {
      return _addCommand(new Ping(resolve, reject));
    });
  };

  /**
   * Send a reset command that will
   * - rollback any open transaction
   * - reset transaction isolation level
   * - reset session variables
   * - delete user variables
   * - remove temporary tables
   * - remove all PREPARE statement
   *
   * @returns {Promise} promise
   */
  this.reset = () => {
    if (
      (info.isMariaDB() && info.hasMinVersion(10, 2, 4)) ||
      (!info.isMariaDB() && info.hasMinVersion(5, 7, 3))
    ) {
      return new Promise(function(resolve, reject) {
        return _addCommand(new Reset(resolve, reject));
      });
    }
    return Promise.reject(
      new Error(
        'Reset command not permitted for server ' + this.info.serverVersion
      )
    );
  };

  /**
   * Indicates the state of the connection as the driver knows it
   * @returns {boolean}
   */
  this.isValid = () => {
    return _status === Status.CONNECTED;
  };

  /**
   * Terminate connection gracefully.
   *
   * @returns {Promise} promise
   */
  this.end = () => {
    _addCommand = _addCommandDisabled;
    clearTimeout(_timeout);

    if (
      _status !== Status.CLOSING &&
      _status !== Status.CLOSED &&
      _status !== Status.NOT_CONNECTED
    ) {
      _status = Status.CLOSING;
      return new Promise(function(resolve, reject) {
        const ended = () => {
          _status = Status.CLOSED;
          _socket.destroy();
          _socket.unref();
          _clear();
          _receiveQueue.clear();
          resolve();
        };
        const quitCmd = new Quit(ended, ended);
        _sendQueue.push(quitCmd);
        _receiveQueue.push(quitCmd);
        if (_sendQueue.length === 1) {
          process.nextTick(_nextSendCmd.bind(this));
        }
      });
    }
    return Promise.resolve();
  };

  /**
   * Alias for destroy.
   */
  this.close = function() {
    this.destroy();
  };

  /**
   * Force connection termination by closing the underlying socket and killing server process if any.
   */
  this.destroy = () => {
    _addCommand = _addCommandDisabled;
    clearTimeout(_timeout);
    if (_status !== Status.CLOSING && _status !== Status.CLOSED) {
      _status = Status.CLOSING;
      _sendQueue.clear();
      if (_receiveQueue.length > 0) {
        //socket is closed, but server may still be processing a huge select
        //only possibility is to kill process by another thread
        //TODO reuse a pool connection to avoid connection creation
        const self = this;
        const killCon = new Connection(opts);
        killCon
          .connect()
          .then(() => {
            //*************************************************
            //kill connection
            //*************************************************
            const killResHandler = () => {
              const destroyError = Errors.createError(
                'Connection destroyed, command was killed',
                true,
                info,
                '08S01',
                Errors.ER_CMD_NOT_EXECUTED_DESTROYED
              );
              socketErrorDispatchToQueries(destroyError);
              process.nextTick(() => {
                if (_socket) _socket.destroy();
              });
              _status = Status.CLOSED;
              killCon.end().catch(() => {});
            };

            killCon
              .query('KILL ' + info.threadId)
              .then(killResHandler)
              .catch(killResHandler);
          })
          .catch(err => {
            //*************************************************
            //failing to create a kill connection, end normally
            //*************************************************
            const ended = () => {
              let sock = _socket;
              _clear();
              _status = Status.CLOSED;
              setImmediate(resolve);
              sock.destroy();
              _receiveQueue.clear();
            };
            const quitCmd = new Quit(ended, ended);
            _sendQueue.push(quitCmd);
            _receiveQueue.push(quitCmd);
            if (_sendQueue.length === 1) {
              process.nextTick(_nextSendCmd.bind(self));
            }
          });
      } else {
        _status = Status.CLOSED;
        _socket.destroy();
      }
    }
    _clear();
  };

  this.pause = () => {
    _socket.pause();
  };

  this.resume = () => {
    _socket.resume();
  };

  this.escape = value => {
    throw Errors.createError(
      '"Connection.escape intentionally not implemented. please use Connection.query(sql, values), it will be more secure and faster',
      false,
      info,
      '0A000',
      Errors.ER_NOT_IMPLEMENTED_ESCAPE
    );
  };

  this.escapeId = value => {
    throw Errors.createError(
      '"Connection.escapeId intentionally not implemented. please use Connection.query(sql, values), it will be more secure and faster',
      false,
      info,
      '0A000',
      Errors.ER_NOT_IMPLEMENTED_ESCAPEID
    );
  };

  this.format = (sql, values) => {
    throw Errors.createError(
      '"Connection.format intentionally not implemented. please use Connection.query(sql, values), it will be more secure and faster',
      false,
      info,
      '0A000',
      Errors.ER_NOT_IMPLEMENTED_FORMAT
    );
  };

  //*****************************************************************
  // additional public methods
  //*****************************************************************

  /**
   * return current connected server version information.
   *
   * @returns {*}
   */
  this.serverVersion = () => {
    if (!info.serverVersion)
      throw new Error(
        'cannot know if server information until connection is established'
      );
    return info.serverVersion.raw;
  };

  /**
   * Change option "debug" during connection.
   * @param val   debug value
   */
  this.debug = val => {
    opts.debug = val;
  };

  this.debugCompress = val => {
    opts.debugCompress = val;
  };

  //*****************************************************************
  // internal public testing methods
  //*****************************************************************

  function TestMethods() {}
  TestMethods.prototype.getCollation = () => {
    return opts.collation;
  };

  TestMethods.prototype.getSocket = () => {
    return _socket;
  };

  this.__tests = new TestMethods();

  //*****************************************************************
  // internal methods
  //*****************************************************************

  this._status = () => {
    return _status;
  };

  /**
   * Execute query using text protocol with callback emit columns/data/end/error
   * events to permit streaming big result-set
   *
   * @param sql     sql parameter Object can be used to supersede default option.
   *                Object must then have sql property.
   * @param values  object / array of placeholder values (not mandatory)
   * @param cb      callback
   * @returns {Query} query
   */
  this._queryCallback = (sql, values, cb) => {
    let _cmdOpts, _sql, _values;
    let _cb = cb;
    if (typeof sql === 'object') {
      _cmdOpts = sql;
      _sql = _cmdOpts.sql;
    } else {
      _sql = sql;
    }

    if (typeof values === 'function') {
      _cb = values;
    } else if (values !== undefined) {
      _values = values;
    }

    let cmd;
    if (_cb) {
      const resolve = rows => {
        const meta = rows.meta;
        delete rows.meta;
        _cb(null, rows, meta);
      };
      cmd = new Query(resolve, _cb, _cmdOpts, opts, _sql, _values);
    } else {
      cmd = new Query(() => {}, () => {}, _cmdOpts, opts, _sql, _values);
    }
    cmd.handleNewRows = row => {
      cmd._rows[cmd._responseIndex].push(row);
      cmd.emit('data', row);
    };

    if (opts.trace) Error.captureStackTrace(cmd);
    _addCommand(cmd);
    return cmd;
  };

  /**
   * Execute a batch using text protocol with callback emit columns/data/end/error
   * events to permit streaming big result-set
   *
   * @param sql     sql parameter Object can be used to supersede default option.
   *                Object must then have sql property.
   * @param values  object / array of placeholder values (not mandatory)
   * @param cb      callback
   * @returns {Query} query
   */
  this._batchCallback = (sql, values, cb) => {
    let _cmdOpts, _sql, _values;
    let _cb = cb;
    if (typeof sql === 'object') {
      _cmdOpts = sql;
      _sql = _cmdOpts.sql;
    } else {
      _sql = sql;
    }

    if (typeof values === 'function') {
      _cb = values;
    } else if (values !== undefined) {
      _values = values;
    }

    let cmd;

    let useBulk = canUseBulk(_values);

    const fct = useBulk ? BatchBulk : BatchRewrite;

    if (_cb) {
      const resolve = rows => {
        const meta = rows.meta;
        delete rows.meta;
        _cb(null, rows, meta);
      };
      cmd = new fct(resolve, _cb, _cmdOpts, opts, _sql, _values);
    } else {
      cmd = new fct(() => {}, () => {}, _cmdOpts, opts, _sql, _values);
    }
    cmd.handleNewRows = row => {
      cmd._rows[cmd._responseIndex].push(row);
      cmd.emit('data', row);
    };

    if (opts.trace) Error.captureStackTrace(cmd);
    _addCommand(cmd);
    return cmd;
  };

  /**
   * Use Batch rewrite or MariaDB bulk protocol.
   *
   * @param _values current batch values
   * @return {boolean} indicating if must use rewrite or bulk
   */
  const canUseBulk = _values => {
    let useBulk = info.isMariaDB() && info.hasMinVersion(10, 2, 7) && opts.bulk;
    if (useBulk) {
      //ensure that there is no stream object
      if (_values !== undefined) {
        const values = Array.isArray(_values) ? _values : [_values];
        const paramLen = Array.isArray(values[0]) ? values[0].length : 1;
        if (!opts.namedPlaceholders) {
          for (let r = 0; r < values.length; r++) {
            let row = values[r];
            if (!Array.isArray(row)) row = [row];
            if (paramLen !== row.length) {
              useBulk = false;
              break;
            }
            for (let j = 0; j < paramLen; j++) {
              const val = row[j];
              if (
                val !== null &&
                typeof val === 'object' &&
                typeof val.pipe === 'function' &&
                typeof val.read === 'function'
              ) {
                useBulk = false;
                break;
              }
            }
            if (!useBulk) break;
          }
        } else {
          for (let r = 0; r < values.length; r++) {
            let row = values[r];
            const keys = Object.keys(row);
            for (let j = 0; j < keys.length; j++) {
              const val = row[keys[j]];
              if (
                val !== null &&
                typeof val === 'object' &&
                typeof val.pipe === 'function' &&
                typeof val.read === 'function'
              ) {
                useBulk = false;
                break;
              }
            }
            if (!useBulk) break;
          }
        }
      }
    }
    return useBulk;
  };

  /**
   * Add handshake command to queue.
   *
   * @private
   */
  const _registerHandshakeCmd = (resolve, rejected) => {
    const _authFail = _authFailHandler.bind(this, rejected);
    const _authSucceed = _authSucceedHandler.bind(this, resolve, _authFail);

    const handshake = new Handshake(
      _authSucceed,
      _authFail,
      _createSecureContext.bind(this, _authFail),
      _addCommand.bind(this),
      _getSocket
    );
    Error.captureStackTrace(handshake);

    handshake.once('end', () => {
      process.nextTick(_nextSendCmd);
    });

    _receiveQueue.push(handshake);
    _initSocket(_authFail);
  };

  const _executeSessionVariableQuery = () => {
    if (opts.sessionVariables) {
      const values = [];
      let sessionQuery = 'set ';
      let keys = Object.keys(opts.sessionVariables);
      if (keys.length > 0) {
        return new Promise(function(resolve, reject) {
          for (let k = 0; k < keys.length; ++k) {
            sessionQuery +=
              (k !== 0 ? ',' : '') +
              '@@' +
              keys[k].replace(/[^a-z0-9_]/gi, '') +
              '=?';
            values.push(opts.sessionVariables[keys[k]]);
          }
          const errorHandling = initialErr => {
            reject(
              Errors.createError(
                'Error setting session variable (value ' +
                  JSON.stringify(opts.sessionVariables) +
                  '). Error: ' +
                  initialErr.message,
                true,
                info,
                '08S01',
                Errors.ER_SETTING_SESSION_ERROR,
                null
              )
            );
          };
          const cmd = new Query(
            resolve,
            errorHandling,
            null,
            opts,
            sessionQuery,
            values
          );
          if (opts.trace) Error.captureStackTrace(cmd);
          _addCommand(cmd);
        });
      }
    }
    return Promise.resolve();
  };

  /**
   * Asking server timezone if not set
   * @returns {Promise<void>|Promise<T | never>}
   * @private
   */
  const _checkServerTimezone = () => {
    if (opts.timezone === 'local' || opts.tz) {
      return Promise.resolve();
    }
    return this.query('SELECT @@system_time_zone stz, @@time_zone tz').then(
      res => {
        const serverTimezone = res[0].tz === 'SYSTEM' ? res[0].stz : res[0].tz;
        const serverZone = moment.tz.zone(serverTimezone);
        if (serverZone) {
          if (serverTimezone === moment.tz.guess()) {
            //db server and client use same timezone, avoid any conversion
            opts.tz = null;
          } else {
            opts.tz = moment.tz.setDefault(serverTimezone);
          }
        } else {
          return Promise.reject(
            Errors.createError(
              "Automatic timezone setting fails. Server timezone '" +
                serverTimezone +
                "' does't have a corresponding IANA timezone. Option timezone must be set according to server timezone",
              true,
              info,
              '08S01',
              Errors.ER_WRONG_AUTO_TIMEZONE
            )
          );
        }
        return Promise.resolve();
      }
    );
  };

  const _executeInitQuery = () => {
    if (opts.initSql) {
      const initialArr = Array.isArray(opts.initSql)
        ? opts.initSql
        : [opts.initSql];
      const initialPromises = [];
      initialArr.forEach(sql => {
        initialPromises.push(
          new Promise(function(resolve, reject) {
            const errorHandling = initialErr => {
              reject(
                Errors.createError(
                  'Error executing initial sql command: ' + initialErr.message,
                  true,
                  info,
                  '08S01',
                  Errors.ER_INITIAL_SQL_ERROR,
                  null
                )
              );
            };
            const cmd = new Query(
              resolve,
              errorHandling,
              null,
              opts,
              sql,
              null
            );
            if (opts.trace) Error.captureStackTrace(cmd);
            _addCommand(cmd);
          })
        );
      });
      return Promise.all(initialPromises);
    }
    return Promise.resolve();
  };

  const _getSocket = () => {
    return _socket;
  };

  /**
   * Initialize socket and associate events.
   * @private
   */
  const _initSocket = authFailHandler => {
    if (opts.socketPath) {
      _socket = Net.connect(opts.socketPath);
    } else {
      _socket = Net.connect(opts.port, opts.host);
    }

    if (opts.connectTimeout) {
      _timeout = setTimeout(
        _connectTimeoutReached,
        opts.connectTimeout,
        authFailHandler
      );
    }

    const _socketError = _socketErrorHandler.bind(this, authFailHandler);

    _socket.on('data', _in.onData.bind(_in));
    _socket.on('error', _socketError);
    _socket.on('end', _socketError);
    _socket.on(
      'connect',
      function() {
        clearTimeout(_timeout);
        if (_status === Status.CONNECTING) {
          _status = Status.AUTHENTICATING;
          _socketConnected = true;
          _socket.setTimeout(
            opts.socketTimeout,
            _socketTimeoutReached.bind(this, authFailHandler)
          );
          _socket.setNoDelay(true);
        }
      }.bind(this)
    );

    _socket.writeBuf = _socket.write;
    _socket.flush = () => {};
    _out.setStream(_socket);
  };

  /**
   * Authentication success result handler.
   *
   * @private
   */
  const _authSucceedHandler = (resolve, rejected) => {
    //enable packet compression according to option
    if (opts.logPackets) info.enableLogPacket();
    if (opts.compress) {
      if (info.serverCapabilities & Capabilities.COMPRESS) {
        _out.setStream(new CompressionOutputStream(_socket, opts, info));
        _in = new CompressionInputStream(_in, _receiveQueue, opts, info);
        _socket.removeAllListeners('data');
        _socket.on('data', _in.onData.bind(_in));
      } else {
        console.error(
          "connection is configured to use packet compression, but the server doesn't have this capability"
        );
      }
    }

    if (opts.pipelining) {
      _addCommand = _addCommandEnablePipeline;
      const commands = _receiveQueue.toArray();
      commands.forEach(cmd => {
        const listeners = cmd.listeners('end');
        cmd.removeListener('end', listeners[0]);
        cmd.once('send_end', () => {
          setImmediate(_nextSendCmd);
        });
      });
    }

    const errorInitialQueries = err => {
      if (!err.fatal) this.end().catch(err => {});
      process.nextTick(rejected, err);
    };

    _executeSessionVariableQuery()
      .then(() => {
        return _checkServerTimezone();
      })
      .then(() => {
        return _executeInitQuery();
      })
      .then(() => {
        _status = Status.CONNECTED;
        process.nextTick(resolve, this);
      })
      .catch(errorInitialQueries);
  };

  /**
   * Authentication failed result handler.
   *
   * @private
   */
  const _authFailHandler = (reject, err) => {
    process.nextTick(reject, err);
    //remove handshake command
    _receiveQueue.shift();

    _fatalError(err, true);
  };

  /**
   * Create TLS socket and associate events.
   *
   * @param rejected  rejected function when error
   * @param callback  callback function when done
   * @private
   */
  const _createSecureContext = (rejected, callback) => {
    const _socketError = _socketErrorHandler.bind(this, rejected);
    const sslOption = Object.assign({}, opts.ssl, {
      servername: opts.host,
      socket: _socket
    });

    try {
      const secureSocket = tls.connect(sslOption, callback);

      secureSocket.on('data', _in.onData.bind(_in));
      secureSocket.on('error', _socketError);
      secureSocket.on('end', _socketError);
      secureSocket.writeBuf = secureSocket.write;
      secureSocket.flush = () => {};

      _socket.removeAllListeners('data');
      _socket = secureSocket;

      _out.setStream(secureSocket);
    } catch (err) {
      _socketError(err);
    }
  };

  /**
   * Handle packet when no packet is expected.
   * (there can be an ERROR packet send by server/proxy to inform that connection is ending).
   *
   * @param packet  packet
   * @private
   */
  const _unexpectedPacket = function(packet) {
    if (packet && packet.peek() === 0xff) {
      //can receive unexpected error packet from server/proxy
      //to inform that connection is closed (usually by timeout)
      let err = packet.readError(info);
      if (
        err.fatal &&
        (_status !== Status.CLOSING && _status !== Status.CLOSED)
      ) {
        this.emit('error', err);
        this.end();
      }
    } else if (_status !== Status.CLOSING && _status !== Status.CLOSED) {
      this.emit(
        'error',
        Errors.createError(
          'receiving packet from server without active commands\n' +
            'conn:' +
            (info.threadId ? info.threadId : -1) +
            '(' +
            packet.pos +
            ',' +
            packet.end +
            ')\n' +
            Utils.log(opts, packet.buf, packet.pos, packet.end),
          true,
          info,
          '08S01',
          Errors.ER_UNEXPECTED_PACKET
        )
      );
      this.destroy();
    }
  };

  /**
   * Change transaction state.
   *
   * @param sql sql
   * @returns {Promise} promise
   * @private
   */
  const _changeTransaction = sql => {
    //if command in progress, driver cannot rely on status and must execute query
    if (_status === Status.CLOSING || _status === Status.CLOSED) {
      return Promise.reject(
        Errors.createError(
          'Cannot execute new commands: connection closed\nsql: ' + sql,
          true,
          info,
          '08S01',
          Errors.ER_CMD_CONNECTION_CLOSED
        )
      );
    }

    //Command in progress => must execute query
    //or if no command in progress, can rely on status to know if query is needed
    if (
      _receiveQueue.peekFront() ||
      info.status & ServerStatus.STATUS_IN_TRANS
    ) {
      return new Promise(function(resolve, reject) {
        const cmd = new Query(resolve, reject, null, opts, sql, null);
        if (opts.trace) Error.captureStackTrace(cmd);
        _addCommand(cmd);
      });
    }
    return Promise.resolve();
  };

  /**
   * Handle connection timeout.
   *
   * @private
   */
  const _connectTimeoutReached = function(authFailHandler) {
    _timeout = null;
    const handshake = _receiveQueue.peekFront();
    authFailHandler(
      Errors.createError(
        'Connection timeout',
        true,
        info,
        '08S01',
        Errors.ER_CONNECTION_TIMEOUT,
        handshake ? handshake.stack : null
      )
    );
  };

  /**
   * Handle socket timeout.
   *
   * @private
   */
  const _socketTimeoutReached = function() {
    const err = Errors.createError(
      'socket timeout',
      true,
      info,
      '08S01',
      Errors.ER_SOCKET_TIMEOUT
    );
    const packetMsgs = info.getLastPackets();
    if (packetMsgs !== '') {
      err.message = err.message + '\nlast received packets:\n' + packetMsgs;
    }
    _fatalError(err, true);
  };

  /**
   * Add command to command sending and receiving queue.
   *
   * @param cmd         command
   * @returns {*}       current command
   * @private
   */
  const _addCommandEnable = cmd => {
    cmd.once('end', () => {
      setImmediate(_nextSendCmd);
    });

    //send immediately only if no current active receiver
    if (_sendQueue.isEmpty() && _status === Status.CONNECTED) {
      if (_receiveQueue.peekFront()) {
        _receiveQueue.push(cmd);
        _sendQueue.push(cmd);
        return cmd;
      }

      _receiveQueue.push(cmd);
      cmd.start(_out, opts, info);
    } else {
      _receiveQueue.push(cmd);
      _sendQueue.push(cmd);
    }
    return cmd;
  };

  /**
   * Add command to command sending and receiving queue using pipelining
   *
   * @param cmd         command
   * @returns {*}       current command
   * @private
   */
  const _addCommandEnablePipeline = cmd => {
    cmd.once('send_end', () => {
      setImmediate(_nextSendCmd);
    });

    _receiveQueue.push(cmd);
    if (_sendQueue.isEmpty()) {
      cmd.start(_out, opts, info);
      if (cmd.sending) {
        _sendQueue.push(cmd);
        cmd.prependOnceListener('send_end', () => {
          _sendQueue.shift();
        });
      }
    } else {
      _sendQueue.push(cmd);
    }
    return cmd;
  };

  /**
   * Replacing command when connection is closing or closed to send a proper error message.
   *
   * @param cmd         command
   * @private
   */
  const _addCommandDisabled = cmd => {
    cmd.throwNewError(
      'Cannot execute new commands: connection closed\n' + cmd.displaySql(),
      true,
      info,
      '08S01',
      Errors.ER_CMD_CONNECTION_CLOSED
    );
  };

  /**
   * Handle socket error.
   *
   * @param authFailHandler   authentication handler
   * @param err               socket error
   * @private
   */
  const _socketErrorHandler = function(authFailHandler, err) {
    if (_status === Status.CLOSING || _status === Status.CLOSED) return;

    _socket.writeBuf = () => {};
    _socket.flush = () => {};

    //socket has been ended without error
    if (!err) {
      err = Errors.createError(
        'socket has unexpectedly been closed',
        true,
        info,
        '08S01',
        Errors.ER_SOCKET_UNEXPECTED_CLOSE
      );
    } else {
      err.fatal = true;
      this.sqlState = 'HY000';
    }

    const packetMsgs = info.getLastPackets();
    if (packetMsgs !== '') {
      err.message += '\nlast received packets:\n' + packetMsgs;
    }

    switch (_status) {
      case Status.CONNECTING:
      case Status.AUTHENTICATING:
        const currentCmd = _receiveQueue.peekFront();
        if (currentCmd && currentCmd.stack && err) {
          err.stack +=
            '\n From event:\n' +
            currentCmd.stack.substring(currentCmd.stack.indexOf('\n') + 1);
        }
        authFailHandler(err);
        break;

      default:
        _fatalError(err, false);
    }
  };

  /**
   * Fatal unexpected error : closing connection, and throw exception.
   *
   * @param self    current connection
   * @private
   */
  const _fatalErrorHandler = function(self) {
    return function(err, avoidThrowError) {
      if (_status === Status.CLOSING || _status === Status.CLOSED) {
        socketErrorDispatchToQueries(err);
        return;
      }
      const mustThrowError = _status !== Status.CONNECTING;
      _status = Status.CLOSING;

      //prevent executing new commands
      _addCommand = _addCommandDisabled;

      if (_socket) {
        _socket.removeAllListeners('error');
        _socket.removeAllListeners('timeout');
        _socket.removeAllListeners('close');
        _socket.removeAllListeners('data');
        if (!_socket.destroyed) _socket.destroy();
        _socket = undefined;
      }
      _status = Status.CLOSED;

      const errorThrownByCmd = socketErrorDispatchToQueries(err);
      if (mustThrowError) {
        if (self.listenerCount('error') > 0) {
          self.emit('error', err);
          self.emit('end');
          _clear();
        } else {
          self.emit('end');
          _clear();
          //error will be thrown if no error listener and no command did throw the exception
          if (!avoidThrowError && !errorThrownByCmd) throw err;
        }
      } else {
        _clear();
      }
    };
  };

  /**
   * Dispatch fatal error to current running queries.
   *
   * @param err        the fatal error
   * @return {boolean} return if error has been relayed to queries
   */
  const socketErrorDispatchToQueries = err => {
    let receiveCmd;
    let errorThrownByCmd = false;
    while ((receiveCmd = _receiveQueue.shift())) {
      if (receiveCmd && receiveCmd.onPacketReceive) {
        errorThrownByCmd = true;
        setImmediate(receiveCmd.throwError.bind(receiveCmd), err, info);
      }
    }
    return errorThrownByCmd;
  };

  /**
   * Will send next command in queue if any.
   *
   * @private
   */
  const _nextSendCmd = () => {
    let sendCmd;
    if ((sendCmd = _sendQueue.shift())) {
      if (sendCmd.sending) {
        _sendQueue.unshift(sendCmd);
      } else {
        sendCmd.start(_out, opts, info);
        if (sendCmd.sending) {
          sendCmd.prependOnceListener('send_end', () => {
            _sendQueue.shift();
          });
          _sendQueue.unshift(sendCmd);
        }
      }
    }
  };

  /**
   * Clearing connection variables when ending.
   *
   * @private
   */
  const _clear = () => {
    _sendQueue.clear();
    _out = undefined;
    _socket = undefined;
  };

  //*****************************************************************
  // internal variables
  //*****************************************************************

  EventEmitter.call(this);
  const opts = Object.assign({}, options);
  const info = new ConnectionInformation();
  const _sendQueue = new Queue();
  const _receiveQueue = new Queue();
  let _status = Status.NOT_CONNECTED;
  let _socketConnected = false;
  let _socket = null;
  let _timeout = null;
  let _addCommand = _addCommandEnable;
  const _fatalError = _fatalErrorHandler(this);
  let _out = new PacketOutputStream(opts, info);
  let _in = new PacketInputStream(
    _unexpectedPacket.bind(this),
    _receiveQueue,
    _out,
    opts,
    info
  );

  //add alias threadId for mysql/mysql2 compatibility
  Object.defineProperty(this, 'threadId', {
    get() {
      return info ? info.threadId : undefined;
    }
  });
  Object.defineProperty(this, 'info', {
    get() {
      return info;
    }
  });
}
262464
function Connection(endpoint, options, connectionListener) {
  if (!(this instanceof Connection)) return new Connection(endpoint, options, connectionListener);

  stream.Duplex.call(this);

  if (endpoint && !(endpoint instanceof Endpoint)) {
    endpoint = new Endpoint(endpoint);
  }
  if (typeof options === 'function') {
    connectionListener = options;
    options = undefined;
  }
  this.endpoint = endpoint;
  this.options = options || {};
  if (typeof connectionListener === 'function') {
    this.on('connect', connectionListener);
  }
  this.status = {sent: 0, received: 0};

  this.on('_read_data', function (data) {
    this.push(data);
    this.status.received += data.length;
  });

  if (endpoint) {
    //connect
    connect.call(this);
  }
}
1099280
function connect(options, connectListener)
{
	var socket = net.connect(options, () => {
		if ( connectListener )
		{
			connectListener();
		}
	});
	
	return new Client(socket, options);
}
762310
function add(client) {
  // Auto-remove clients on close
  client.once('closed', function() {
    remove(client);
  });

  clients = clients || [];
  clients.push(client);
  initClient(client);
}
560399
function AsyncClient(client) {
  this.client = client;
  this.query = this.query.bind(this);
  this.end = this.end.bind(this);
}
773029
function request( next ) {
	/* jshint validthis: true */
	var self = this,
		body = '',
		req;

	this.req.opts.agent = agent;

	// TODO: record request headers
	// TODO: record request header length
	// TODO: record request body length

	req = http.request( this.req.opts, onResponse );
	req.on( 'error', onError );

	this.start = Date.now();
	this.timer = process.hrtime();

	if ( this.req.body ) {
		req.write( this.req.body );
	}
	req.end();

	cache[ this.rid ] = req;

	/**
	* FUNCTION: onConnect( response, socket, head )
	*	Callback invoked upon connecting to a server.
	*
	* @private
	* @param {Object} response - HTTP response object
	* @param {Socket} socket - TCP socket
	* @param {Object} head - HTTP response head
	*/
	function onConnect( response, socket, head ) {
		// Do something...
	}

	/**
	* FUNCTION: onResponse( response )
	*	Callback invoked upon receiving an HTTP response.
	*
	* @private
	* @param {Object} response - HTTP response object
	*/
	function onResponse( res ) {
		self.res.status = res.statusCode;
		self.res.headers = res.headers;

		// TODO: record headers length

		res.on( 'data', onData );
		res.on( 'end', onEnd );
	}

	/**
	* FUNCTION: onError( error )
	*	Callback invoked if an error is encountered while making a request.
	*
	* @private
	* @param {Error} error - error object
	*/
	function onError( error ) {
		self.req.error = error;
		if ( process.connected ) {
			// TODO: log (or not; serialize in output message?)
			console.error( process.pid, 'request', error );
		}
	}

	/**
	* FUNCTION: onData( chunk )
	*	Callback invoked after receiving a chunk of response data.
	*
	* @private
	* @param {Buffer} chunk - response data
	*/
	function onData( chunk ) {
		self.res.bytes += chunk.length;
		body += chunk.toString();
	}

	/**
	* FUNCTION: onEnd()
	*	Callback invoked after a response ends.
	*
	* @private
	*/
	function onEnd() {
		self.elapsed = process.hrtime( self.timer );
		self.end = Date.now();
		self.res.body = body;
		delete cache[ self.rid ];
		delete self.req.opts[ 'agent' ];
		next();
	}
}
627576
function init()
    {
        scope._servConn = new ConnectaSocket(scope._url,scope._reconnect,scope._encode);
        scope._servConn.onConnected = function(e)
        {
            scope.id = e;
            scope.dispatchEvent("connected");
        }
        scope._servConn.onError   = function(e)
        {
            scope.dispatchEvent("error",e);
        }
        scope._servConn.onClose = function(e)
        {
            scope.dispatchEvent("close");
            scope.closePeers();
        }

        scope._servConn.onJoinedRoom	   = onJoinedRoom;
        scope._servConn.onClientJoinedRoom = onClientJoinedRoom;
        scope._servConn.onLeftRoom         = onLeftRoom;
        scope._servConn.onClientLeftRoom   = onClientLeftRoom;
        scope._servConn.onSDPDescription   = onSDPDescription;
        scope._servConn.onIceCandidate     = onIceCandidate;
        scope._servConn.onRTCFallback      = onRTCFallback;
        scope._servConn.onMessage          = onServerMessage;
        scope._servConn.onBytesMessage     = onServerByteArray;

        window.addEventListener("beforeunload", function (event) 
        {
            scope.dispose();
        });
    }
1032501
function _send(method, signature, varargs) {
        if (!_socket) {
            console.log("You must connect to the WebSocket before sending messages.");

            // FUTURE: Our current implementation closes and re-opens an inspector connection whenever
            // a new HTML file is selected. If done quickly enough, pending requests from the previous
            // connection could come in before the new socket connection is established. For now we
            // simply ignore this condition.
            // This race condition will go away once we support multiple inspector connections and turn
            // off auto re-opening when a new HTML file is selected.
            return (new $.Deferred()).reject().promise();
        }

        var id, callback, args, i, params = {}, promise, msg;

        // extract the parameters, the callback function, and the message id
        args = Array.prototype.slice.call(arguments, 2);
        if (typeof args[args.length - 1] === "function") {
            callback = args.pop();
        } else {
            var deferred = new $.Deferred();
            promise = deferred.promise();
            callback = function (result, error) {
                if (error) {
                    deferred.reject(error);
                } else {
                    deferred.resolve(result);
                }
            };
        }

        id = _messageId++;

        // verify the parameters against the method signature
        // this also constructs the params object of type {name -> value}
        if (signature) {
            for (i in signature) {
                if (_verifySignature(args[i], signature[i])) {
                    params[signature[i].name] = args[i];
                }
            }
        }

        // Store message callback and send message
        msg = { method: method, id: id, params: params };
        _messageCallbacks[id] = { callback: callback, message: msg };
        _socket.send(JSON.stringify(msg));

        return promise;
    }
700648
function () {
    require('ts-node').register({
      project: 'e2e/tsconfig.e2e.json'
    });
    console.log("Connecting local");
    return new Promise(function (resolve, reject) {
      exports.bs_local = new browserstack.Local();
      exports.bs_local.start({'key': exports.config.capabilities['browserstack.key']}, function (error) {
        if (error) return reject(error);
        console.log('Connected. Now testing...');

        resolve();
      });
    });
  }