text: (function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.bts = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
  // MIT License:
  //
  // Copyright (c) 2010-2012, Joe Walnes
  //
  // Permission is hereby granted, free of charge, to any person obtaining a copy
  // of this software and associated documentation files (the "Software"), to deal
  // in the Software without restriction, including without limitation the rights
  // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  // copies of the Software, and to permit persons to whom the Software is
  // furnished to do so, subject to the following conditions:
  //
  // The above copyright notice and this permission notice shall be included in
  // all copies or substantial portions of the Software.
  //
  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  // THE SOFTWARE.
  
  /**
   * This behaves like a WebSocket in every way, except if it fails to connect,
   * or it gets disconnected, it will repeatedly poll until it successfully connects
   * again.
   *
   * It is API compatible, so when you have:
   *   ws = new WebSocket('ws://....');
   * you can replace with:
   *   ws = new ReconnectingWebSocket('ws://....');
   *
   * The event stream will typically look like:
   *  onconnecting
   *  onopen
   *  onmessage
   *  onmessage
   *  onclose // lost connection
   *  onconnecting
   *  onopen  // sometime later...
   *  onmessage
   *  onmessage
   *  etc...
   *
   * It is API compatible with the standard WebSocket API, apart from the following members:
   *
   * - `bufferedAmount`
   * - `extensions`
   * - `binaryType`
   *
   * Latest version: https://github.com/joewalnes/reconnecting-websocket/
   * - Joe Walnes
   *
   * Syntax
   * ======
   * var socket = new ReconnectingWebSocket(url, protocols, options);
   *
   * Parameters
   * ==========
   * url - The url you are connecting to.
   * protocols - Optional string or array of protocols.
   * options - See below
   *
   * Options
   * =======
   * Options can either be passed upon instantiation or set after instantiation:
   *
   * var socket = new ReconnectingWebSocket(url, null, { debug: true, reconnectInterval: 4000 });
   *
   * or
   *
   * var socket = new ReconnectingWebSocket(url);
   * socket.debug = true;
   * socket.reconnectInterval = 4000;
   *
   * debug
   * - Whether this instance should log debug messages. Accepts true or false. Default: false.
   *
   * automaticOpen
   * - Whether or not the websocket should attempt to connect immediately upon instantiation. The socket can be manually opened or closed at any time using ws.open() and ws.close().
   *
   * reconnectInterval
   * - The number of milliseconds to delay before attempting to reconnect. Accepts integer. Default: 1000.
   *
   * maxReconnectInterval
   * - The maximum number of milliseconds to delay a reconnection attempt. Accepts integer. Default: 30000.
   *
   * reconnectDecay
   * - The rate of increase of the reconnect delay. Allows reconnect attempts to back off when problems persist. Accepts integer or float. Default: 1.5.
   *
   * timeoutInterval
   * - The maximum time in milliseconds to wait for a connection to succeed before closing and retrying. Accepts integer. Default: 2000.
   *
   */
  (function (global, factory) {
      if (typeof define === 'function' && define.amd) {
          define([], factory);
      } else if (typeof module !== 'undefined' && module.exports){
          module.exports = factory();
      } else {
          global.ReconnectingWebSocket = factory();
      }
  })(this, function () {
  
      if (typeof window === "undefined" || !('WebSocket' in window)) {
          return;
      }
  
      function ReconnectingWebSocket(url, protocols, options) {
  
          // Default settings
          var settings = {
  
              /** Whether this instance should log debug messages. */
              debug: false,
  
              /** Whether or not the websocket should attempt to connect immediately upon instantiation. */
              automaticOpen: true,
  
              /** The number of milliseconds to delay before attempting to reconnect. */
              reconnectInterval: 1000,
              /** The maximum number of milliseconds to delay a reconnection attempt. */
              maxReconnectInterval: 30000,
              /** The rate of increase of the reconnect delay. Allows reconnect attempts to back off when problems persist. */
              reconnectDecay: 1.5,
  
              /** The maximum time in milliseconds to wait for a connection to succeed before closing and retrying. */
              timeoutInterval: 2000,
  
              /** The maximum number of reconnection attempts to make. Unlimited if null. */
              maxReconnectAttempts: null,
  
              /** The binary type, possible values 'blob' or 'arraybuffer', default 'blob'. */
              binaryType: 'blob'
          }
          if (!options) { options = {}; }
  
          // Overwrite and define settings with options if they exist.
          for (var key in settings) {
              if (typeof options[key] !== 'undefined') {
                  this[key] = options[key];
              } else {
                  this[key] = settings[key];
              }
          }
  
          // These should be treated as read-only properties
  
          /** The URL as resolved by the constructor. This is always an absolute URL. Read only. */
          this.url = url;
  
          /** The number of attempted reconnects since starting, or the last successful connection. Read only. */
          this.reconnectAttempts = 0;
  
          /**
           * The current state of the connection.
           * Can be one of: WebSocket.CONNECTING, WebSocket.OPEN, WebSocket.CLOSING, WebSocket.CLOSED
           * Read only.
           */
          this.readyState = WebSocket.CONNECTING;
  
          /**
           * A string indicating the name of the sub-protocol the server selected; this will be one of
           * the strings specified in the protocols parameter when creating the WebSocket object.
           * Read only.
           */
          this.protocol = null;
  
          // Private state variables
  
          var self = this;
          var ws;
          var forcedClose = false;
          var timedOut = false;
          var t = null;
          var eventTarget = document.createElement('div');
  
          // Wire up "on*" properties as event handlers
  
          eventTarget.addEventListener('open',       function(event) { self.onopen(event); });
          eventTarget.addEventListener('close',      function(event) { self.onclose(event); });
          eventTarget.addEventListener('connecting', function(event) { self.onconnecting(event); });
          eventTarget.addEventListener('message',    function(event) { self.onmessage(event); });
          eventTarget.addEventListener('error',      function(event) { self.onerror(event); });
  
          // Expose the API required by EventTarget
  
          this.addEventListener = eventTarget.addEventListener.bind(eventTarget);
          this.removeEventListener = eventTarget.removeEventListener.bind(eventTarget);
          this.dispatchEvent = eventTarget.dispatchEvent.bind(eventTarget);
  
          /**
           * This function generates an event that is compatible with standard
           * compliant browsers and IE9 - IE11
           *
           * This will prevent the error:
           * Object doesn't support this action
           *
           * http://stackoverflow.com/questions/19345392/why-arent-my-parameters-getting-passed-through-to-a-dispatched-event/19345563#19345563
           * @param s String The name that the event should use
           * @param args Object an optional object that the event will use
           */
          function generateEvent(s, args) {
          	var evt = document.createEvent("CustomEvent");
          	evt.initCustomEvent(s, false, false, args);
          	return evt;
          };
  
          this.open = function (reconnectAttempt) {
              ws = new WebSocket(self.url, protocols || []);
              ws.binaryType = this.binaryType;
  
              if (reconnectAttempt) {
                  if (this.maxReconnectAttempts && this.reconnectAttempts > this.maxReconnectAttempts) {
                      return;
                  }
              } else {
                  eventTarget.dispatchEvent(generateEvent('connecting'));
                  this.reconnectAttempts = 0;
              }
  
              if (self.debug || ReconnectingWebSocket.debugAll) {
                  console.debug('ReconnectingWebSocket', 'attempt-connect', self.url);
              }
  
              var localWs = ws;
              var timeout = setTimeout(function() {
                  if (self.debug || ReconnectingWebSocket.debugAll) {
                      console.debug('ReconnectingWebSocket', 'connection-timeout', self.url);
                  }
                  timedOut = true;
                  localWs.close();
                  timedOut = false;
              }, self.timeoutInterval);
  
              ws.onopen = function(event) {
                  clearTimeout(timeout);
                  if (self.debug || ReconnectingWebSocket.debugAll) {
                      console.debug('ReconnectingWebSocket', 'onopen', self.url);
                  }
                  self.protocol = ws.protocol;
                  self.readyState = WebSocket.OPEN;
                  self.reconnectAttempts = 0;
                  var e = generateEvent('open');
                  e.isReconnect = reconnectAttempt;
                  reconnectAttempt = false;
                  eventTarget.dispatchEvent(e);
              };
  
              ws.onclose = function(event) {
                  clearTimeout(timeout);
                  ws = null;
                  if (forcedClose) {
                      self.readyState = WebSocket.CLOSED;
                      eventTarget.dispatchEvent(generateEvent('close'));
                  } else {
                      self.readyState = WebSocket.CONNECTING;
                      var e = generateEvent('connecting');
                      e.code = event.code;
                      e.reason = event.reason;
                      e.wasClean = event.wasClean;
                      eventTarget.dispatchEvent(e);
                      if (!reconnectAttempt && !timedOut) {
                          if (self.debug || ReconnectingWebSocket.debugAll) {
                              console.debug('ReconnectingWebSocket', 'onclose', self.url);
                          }
                          eventTarget.dispatchEvent(generateEvent('close'));
                      }
  
                      var timeout = self.reconnectInterval * Math.pow(self.reconnectDecay, self.reconnectAttempts);
                      t = setTimeout(function() {
                          self.reconnectAttempts++;
                          self.open(true);
                      }, timeout > self.maxReconnectInterval ? self.maxReconnectInterval : timeout);
                  }
              };
              ws.onmessage = function(event) {
                  if (self.debug || ReconnectingWebSocket.debugAll) {
                      console.debug('ReconnectingWebSocket', 'onmessage', self.url, event.data);
                  }
                  var e = generateEvent('message');
                  e.data = event.data;
                  eventTarget.dispatchEvent(e);
              };
              ws.onerror = function(event) {
                  if (self.debug || ReconnectingWebSocket.debugAll) {
                      console.debug('ReconnectingWebSocket', 'onerror', self.url, event);
                  }
                  eventTarget.dispatchEvent(generateEvent('error'));
              };
          }
  
          // Whether or not to create a websocket upon instantiation
          if (this.automaticOpen == true) {
              this.open(false);
          }
  
          /**
           * Transmits data to the server over the WebSocket connection.
           *
           * @param data a text string, ArrayBuffer or Blob to send to the server.
           */
          this.send = function(data) {
              if (ws) {
                  if (self.debug || ReconnectingWebSocket.debugAll) {
                      console.debug('ReconnectingWebSocket', 'send', self.url, data);
                  }
                  return ws.send(data);
              } else {
                  throw 'INVALID_STATE_ERR : Pausing to reconnect websocket';
              }
          };
  
          /**
           * Closes the WebSocket connection or connection attempt, if any.
           * If the connection is already CLOSED, this method does nothing.
           */
          this.close = function(code, reason) {
              // Default CLOSE_NORMAL code
              if (typeof code == 'undefined') {
                  code = 1000;
              }
              forcedClose = true;
              if (ws) {
                  ws.close(code, reason);
              }
              if (t) {
                  clearTimeout(t);
                  t = null;
              }
          };
  
          /**
           * Additional public API method to refresh the connection if still open (close, re-open).
           * For example, if the app suspects bad data / missed heart beats, it can try to refresh.
           */
          this.refresh = function() {
              if (ws) {
                  ws.close();
              }
          };
      }
  
      /**
       * An event listener to be called when the WebSocket connection's readyState changes to OPEN;
       * this indicates that the connection is ready to send and receive data.
       */
      ReconnectingWebSocket.prototype.onopen = function(event) {};
      /** An event listener to be called when the WebSocket connection's readyState changes to CLOSED. */
      ReconnectingWebSocket.prototype.onclose = function(event) {};
      /** An event listener to be called when a connection begins being attempted. */
      ReconnectingWebSocket.prototype.onconnecting = function(event) {};
      /** An event listener to be called when a message is received from the server. */
      ReconnectingWebSocket.prototype.onmessage = function(event) {};
      /** An event listener to be called when an error occurs. */
      ReconnectingWebSocket.prototype.onerror = function(event) {};
  
      /**
       * Whether all instances of ReconnectingWebSocket should log debug messages.
       * Setting this to true is the equivalent of setting all instances of ReconnectingWebSocket.debug to true.
       */
      ReconnectingWebSocket.debugAll = false;
  
      ReconnectingWebSocket.CONNECTING = WebSocket.CONNECTING;
      ReconnectingWebSocket.OPEN = WebSocket.OPEN;
      ReconnectingWebSocket.CLOSING = WebSocket.CLOSING;
      ReconnectingWebSocket.CLOSED = WebSocket.CLOSED;
  
      return ReconnectingWebSocket;
  });
  
  },{}],2:[function(require,module,exports){
  // base-x encoding
  // Forked from https://github.com/cryptocoinjs/bs58
  // Originally written by Mike Hearn for BitcoinJ
  // Copyright (c) 2011 Google Inc
  // Ported to JavaScript by Stefan Thomas
  // Merged Buffer refactorings from base58-native by Stephen Pair
  // Copyright (c) 2013 BitPay Inc
  
  module.exports = function base (ALPHABET) {
    var ALPHABET_MAP = {}
    var BASE = ALPHABET.length
    var LEADER = ALPHABET.charAt(0)
  
    // pre-compute lookup table
    for (var i = 0; i < ALPHABET.length; i++) {
      ALPHABET_MAP[ALPHABET.charAt(i)] = i
    }
  
    function encode (source) {
      if (source.length === 0) return ''
  
      var digits = [0]
      for (var i = 0; i < source.length; ++i) {
        for (var j = 0, carry = source[i]; j < digits.length; ++j) {
          carry += digits[j] << 8
          digits[j] = carry % BASE
          carry = (carry / BASE) | 0
        }
  
        while (carry > 0) {
          digits.push(carry % BASE)
          carry = (carry / BASE) | 0
        }
      }
  
      var string = ''
  
      // deal with leading zeros
      for (var k = 0; source[k] === 0 && k < source.length - 1; ++k) string += ALPHABET[0]
      // convert digits to a string
      for (var q = digits.length - 1; q >= 0; --q) string += ALPHABET[digits[q]]
  
      return string
    }
  
    function decodeUnsafe (string) {
      if (string.length === 0) return []
  
      var bytes = [0]
      for (var i = 0; i < string.length; i++) {
        var value = ALPHABET_MAP[string[i]]
        if (value === undefined) return
  
        for (var j = 0, carry = value; j < bytes.length; ++j) {
          carry += bytes[j] * BASE
          bytes[j] = carry & 0xff
          carry >>= 8
        }
  
        while (carry > 0) {
          bytes.push(carry & 0xff)
          carry >>= 8
        }
      }
  
      // deal with leading zeros
      for (var k = 0; string[k] === LEADER && k < string.length - 1; ++k) {
        bytes.push(0)
      }
  
      return bytes.reverse()
    }
  
    function decode (string) {
      var array = decodeUnsafe(string)
      if (array) return array
  
      throw new Error('Non-base' + BASE + ' character')
    }
  
    return {
      encode: encode,
      decodeUnsafe: decodeUnsafe,
      decode: decode
    }
  }
  
  },{}],3:[function(require,module,exports){
  // (public) Constructor
  function BigInteger(a, b, c) {
    if (!(this instanceof BigInteger))
      return new BigInteger(a, b, c)
  
    if (a != null) {
      if ("number" == typeof a) this.fromNumber(a, b, c)
      else if (b == null && "string" != typeof a) this.fromString(a, 256)
      else this.fromString(a, b)
    }
  }
  
  var proto = BigInteger.prototype
  
  // duck-typed isBigInteger
  proto.__bigi = require('../package.json').version
  BigInteger.isBigInteger = function (obj, check_ver) {
    return obj && obj.__bigi && (!check_ver || obj.__bigi === proto.__bigi)
  }
  
  // Bits per digit
  var dbits
  
  // am: Compute w_j += (x*this_i), propagate carries,
  // c is initial carry, returns final carry.
  // c < 3*dvalue, x < 2*dvalue, this_i < dvalue
  // We need to select the fastest one that works in this environment.
  
  // am1: use a single mult and divide to get the high bits,
  // max digit bits should be 26 because
  // max internal value = 2*dvalue^2-2*dvalue (< 2^53)
  function am1(i, x, w, j, c, n) {
    while (--n >= 0) {
      var v = x * this[i++] + w[j] + c
      c = Math.floor(v / 0x4000000)
      w[j++] = v & 0x3ffffff
    }
    return c
  }
  // am2 avoids a big mult-and-extract completely.
  // Max digit bits should be <= 30 because we do bitwise ops
  // on values up to 2*hdvalue^2-hdvalue-1 (< 2^31)
  function am2(i, x, w, j, c, n) {
    var xl = x & 0x7fff,
      xh = x >> 15
    while (--n >= 0) {
      var l = this[i] & 0x7fff
      var h = this[i++] >> 15
      var m = xh * l + h * xl
      l = xl * l + ((m & 0x7fff) << 15) + w[j] + (c & 0x3fffffff)
      c = (l >>> 30) + (m >>> 15) + xh * h + (c >>> 30)
      w[j++] = l & 0x3fffffff
    }
    return c
  }
  // Alternately, set max digit bits to 28 since some
  // browsers slow down when dealing with 32-bit numbers.
  function am3(i, x, w, j, c, n) {
    var xl = x & 0x3fff,
      xh = x >> 14
    while (--n >= 0) {
      var l = this[i] & 0x3fff
      var h = this[i++] >> 14
      var m = xh * l + h * xl
      l = xl * l + ((m & 0x3fff) << 14) + w[j] + c
      c = (l >> 28) + (m >> 14) + xh * h
      w[j++] = l & 0xfffffff
    }
    return c
  }
  
  // wtf?
  BigInteger.prototype.am = am1
  dbits = 26
  
  BigInteger.prototype.DB = dbits
  BigInteger.prototype.DM = ((1 << dbits) - 1)
  var DV = BigInteger.prototype.DV = (1 << dbits)
  
  var BI_FP = 52
  BigInteger.prototype.FV = Math.pow(2, BI_FP)
  BigInteger.prototype.F1 = BI_FP - dbits
  BigInteger.prototype.F2 = 2 * dbits - BI_FP
  
  // Digit conversions
  var BI_RM = "0123456789abcdefghijklmnopqrstuvwxyz"
  var BI_RC = new Array()
  var rr, vv
  rr = "0".charCodeAt(0)
  for (vv = 0; vv <= 9; ++vv) BI_RC[rr++] = vv
  rr = "a".charCodeAt(0)
  for (vv = 10; vv < 36; ++vv) BI_RC[rr++] = vv
  rr = "A".charCodeAt(0)
  for (vv = 10; vv < 36; ++vv) BI_RC[rr++] = vv
  
  function int2char(n) {
    return BI_RM.charAt(n)
  }
  
  function intAt(s, i) {
    var c = BI_RC[s.charCodeAt(i)]
    return (c == null) ? -1 : c
  }
  
  // (protected) copy this to r
  function bnpCopyTo(r) {
    for (var i = this.t - 1; i >= 0; --i) r[i] = this[i]
    r.t = this.t
    r.s = this.s
  }
  
  // (protected) set from integer value x, -DV <= x < DV
  function bnpFromInt(x) {
    this.t = 1
    this.s = (x < 0) ? -1 : 0
    if (x > 0) this[0] = x
    else if (x < -1) this[0] = x + DV
    else this.t = 0
  }
  
  // return bigint initialized to value
  function nbv(i) {
    var r = new BigInteger()
    r.fromInt(i)
    return r
  }
  
  // (protected) set from string and radix
  function bnpFromString(s, b) {
    var self = this
  
    var k
    if (b == 16) k = 4
    else if (b == 8) k = 3
    else if (b == 256) k = 8; // byte array
    else if (b == 2) k = 1
    else if (b == 32) k = 5
    else if (b == 4) k = 2
    else {
      self.fromRadix(s, b)
      return
    }
    self.t = 0
    self.s = 0
    var i = s.length,
      mi = false,
      sh = 0
    while (--i >= 0) {
      var x = (k == 8) ? s[i] & 0xff : intAt(s, i)
      if (x < 0) {
        if (s.charAt(i) == "-") mi = true
        continue
      }
      mi = false
      if (sh == 0)
        self[self.t++] = x
      else if (sh + k > self.DB) {
        self[self.t - 1] |= (x & ((1 << (self.DB - sh)) - 1)) << sh
        self[self.t++] = (x >> (self.DB - sh))
      } else
        self[self.t - 1] |= x << sh
      sh += k
      if (sh >= self.DB) sh -= self.DB
    }
    if (k == 8 && (s[0] & 0x80) != 0) {
      self.s = -1
      if (sh > 0) self[self.t - 1] |= ((1 << (self.DB - sh)) - 1) << sh
    }
    self.clamp()
    if (mi) BigInteger.ZERO.subTo(self, self)
  }
  
  // (protected) clamp off excess high words
  function bnpClamp() {
    var c = this.s & this.DM
    while (this.t > 0 && this[this.t - 1] == c)--this.t
  }
  
  // (public) return string representation in given radix
  function bnToString(b) {
    var self = this
    if (self.s < 0) return "-" + self.negate()
      .toString(b)
    var k
    if (b == 16) k = 4
    else if (b == 8) k = 3
    else if (b == 2) k = 1
    else if (b == 32) k = 5
    else if (b == 4) k = 2
    else return self.toRadix(b)
    var km = (1 << k) - 1,
      d, m = false,
      r = "",
      i = self.t
    var p = self.DB - (i * self.DB) % k
    if (i-- > 0) {
      if (p < self.DB && (d = self[i] >> p) > 0) {
        m = true
        r = int2char(d)
      }
      while (i >= 0) {
        if (p < k) {
          d = (self[i] & ((1 << p) - 1)) << (k - p)
          d |= self[--i] >> (p += self.DB - k)
        } else {
          d = (self[i] >> (p -= k)) & km
          if (p <= 0) {
            p += self.DB
            --i
          }
        }
        if (d > 0) m = true
        if (m) r += int2char(d)
      }
    }
    return m ? r : "0"
  }
  
  // (public) -this
  function bnNegate() {
    var r = new BigInteger()
    BigInteger.ZERO.subTo(this, r)
    return r
  }
  
  // (public) |this|
  function bnAbs() {
    return (this.s < 0) ? this.negate() : this
  }
  
  // (public) return + if this > a, - if this < a, 0 if equal
  function bnCompareTo(a) {
    var r = this.s - a.s
    if (r != 0) return r
    var i = this.t
    r = i - a.t
    if (r != 0) return (this.s < 0) ? -r : r
    while (--i >= 0)
      if ((r = this[i] - a[i]) != 0) return r
    return 0
  }
  
  // returns bit length of the integer x
  function nbits(x) {
    var r = 1,
      t
    if ((t = x >>> 16) != 0) {
      x = t
      r += 16
    }
    if ((t = x >> 8) != 0) {
      x = t
      r += 8
    }
    if ((t = x >> 4) != 0) {
      x = t
      r += 4
    }
    if ((t = x >> 2) != 0) {
      x = t
      r += 2
    }
    if ((t = x >> 1) != 0) {
      x = t
      r += 1
    }
    return r
  }
  
  // (public) return the number of bits in "this"
  function bnBitLength() {
    if (this.t <= 0) return 0
    return this.DB * (this.t - 1) + nbits(this[this.t - 1] ^ (this.s & this.DM))
  }
  
  // (public) return the number of bytes in "this"
  function bnByteLength() {
    return this.bitLength() >> 3
  }
  
  // (protected) r = this << n*DB
  function bnpDLShiftTo(n, r) {
    var i
    for (i = this.t - 1; i >= 0; --i) r[i + n] = this[i]
    for (i = n - 1; i >= 0; --i) r[i] = 0
    r.t = this.t + n
    r.s = this.s
  }
  
  // (protected) r = this >> n*DB
  function bnpDRShiftTo(n, r) {
    for (var i = n; i < this.t; ++i) r[i - n] = this[i]
    r.t = Math.max(this.t - n, 0)
    r.s = this.s
  }
  
  // (protected) r = this << n
  function bnpLShiftTo(n, r) {
    var self = this
    var bs = n % self.DB
    var cbs = self.DB - bs
    var bm = (1 << cbs) - 1
    var ds = Math.floor(n / self.DB),
      c = (self.s << bs) & self.DM,
      i
    for (i = self.t - 1; i >= 0; --i) {
      r[i + ds + 1] = (self[i] >> cbs) | c
      c = (self[i] & bm) << bs
    }
    for (i = ds - 1; i >= 0; --i) r[i] = 0
    r[ds] = c
    r.t = self.t + ds + 1
    r.s = self.s
    r.clamp()
  }
  
  // (protected) r = this >> n
  function bnpRShiftTo(n, r) {
    var self = this
    r.s = self.s
    var ds = Math.floor(n / self.DB)
    if (ds >= self.t) {
      r.t = 0
      return
    }
    var bs = n % self.DB
    var cbs = self.DB - bs
    var bm = (1 << bs) - 1
    r[0] = self[ds] >> bs
    for (var i = ds + 1; i < self.t; ++i) {
      r[i - ds - 1] |= (self[i] & bm) << cbs
      r[i - ds] = self[i] >> bs
    }
    if (bs > 0) r[self.t - ds - 1] |= (self.s & bm) << cbs
    r.t = self.t - ds
    r.clamp()
  }
  
  // (protected) r = this - a
  function bnpSubTo(a, r) {
    var self = this
    var i = 0,
      c = 0,
      m = Math.min(a.t, self.t)
    while (i < m) {
      c += self[i] - a[i]
      r[i++] = c & self.DM
      c >>= self.DB
    }
    if (a.t < self.t) {
      c -= a.s
      while (i < self.t) {
        c += self[i]
        r[i++] = c & self.DM
        c >>= self.DB
      }
      c += self.s
    } else {
      c += self.s
      while (i < a.t) {
        c -= a[i]
        r[i++] = c & self.DM
        c >>= self.DB
      }
      c -= a.s
    }
    r.s = (c < 0) ? -1 : 0
    if (c < -1) r[i++] = self.DV + c
    else if (c > 0) r[i++] = c
    r.t = i
    r.clamp()
  }
  
  // (protected) r = this * a, r != this,a (HAC 14.12)
  // "this" should be the larger one if appropriate.
  function bnpMultiplyTo(a, r) {
    var x = this.abs(),
      y = a.abs()
    var i = x.t
    r.t = i + y.t
    while (--i >= 0) r[i] = 0
    for (i = 0; i < y.t; ++i) r[i + x.t] = x.am(0, y[i], r, i, 0, x.t)
    r.s = 0
    r.clamp()
    if (this.s != a.s) BigInteger.ZERO.subTo(r, r)
  }
  
  // (protected) r = this^2, r != this (HAC 14.16)
  function bnpSquareTo(r) {
    var x = this.abs()
    var i = r.t = 2 * x.t
    while (--i >= 0) r[i] = 0
    for (i = 0; i < x.t - 1; ++i) {
      var c = x.am(i, x[i], r, 2 * i, 0, 1)
      if ((r[i + x.t] += x.am(i + 1, 2 * x[i], r, 2 * i + 1, c, x.t - i - 1)) >= x.DV) {
        r[i + x.t] -= x.DV
        r[i + x.t + 1] = 1
      }
    }
    if (r.t > 0) r[r.t - 1] += x.am(i, x[i], r, 2 * i, 0, 1)
    r.s = 0
    r.clamp()
  }
  
  // (protected) divide this by m, quotient and remainder to q, r (HAC 14.20)
  // r != q, this != m.  q or r may be null.
  function bnpDivRemTo(m, q, r) {
    var self = this
    var pm = m.abs()
    if (pm.t <= 0) return
    var pt = self.abs()
    if (pt.t < pm.t) {
      if (q != null) q.fromInt(0)
      if (r != null) self.copyTo(r)
      return
    }
    if (r == null) r = new BigInteger()
    var y = new BigInteger(),
      ts = self.s,
      ms = m.s
    var nsh = self.DB - nbits(pm[pm.t - 1]); // normalize modulus
    if (nsh > 0) {
      pm.lShiftTo(nsh, y)
      pt.lShiftTo(nsh, r)
    } else {
      pm.copyTo(y)
      pt.copyTo(r)
    }
    var ys = y.t
    var y0 = y[ys - 1]
    if (y0 == 0) return
    var yt = y0 * (1 << self.F1) + ((ys > 1) ? y[ys - 2] >> self.F2 : 0)
    var d1 = self.FV / yt,
      d2 = (1 << self.F1) / yt,
      e = 1 << self.F2
    var i = r.t,
      j = i - ys,
      t = (q == null) ? new BigInteger() : q
    y.dlShiftTo(j, t)
    if (r.compareTo(t) >= 0) {
      r[r.t++] = 1
      r.subTo(t, r)
    }
    BigInteger.ONE.dlShiftTo(ys, t)
    t.subTo(y, y); // "negative" y so we can replace sub with am later
    while (y.t < ys) y[y.t++] = 0
    while (--j >= 0) {
      // Estimate quotient digit
      var qd = (r[--i] == y0) ? self.DM : Math.floor(r[i] * d1 + (r[i - 1] + e) * d2)
      if ((r[i] += y.am(0, qd, r, j, 0, ys)) < qd) { // Try it out
        y.dlShiftTo(j, t)
        r.subTo(t, r)
        while (r[i] < --qd) r.subTo(t, r)
      }
    }
    if (q != null) {
      r.drShiftTo(ys, q)
      if (ts != ms) BigInteger.ZERO.subTo(q, q)
    }
    r.t = ys
    r.clamp()
    if (nsh > 0) r.rShiftTo(nsh, r); // Denormalize remainder
    if (ts < 0) BigInteger.ZERO.subTo(r, r)
  }
  
  // (public) this mod a
  function bnMod(a) {
    var r = new BigInteger()
    this.abs()
      .divRemTo(a, null, r)
    if (this.s < 0 && r.compareTo(BigInteger.ZERO) > 0) a.subTo(r, r)
    return r
  }
  
  // Modular reduction using "classic" algorithm
  function Classic(m) {
    this.m = m
  }
  
  function cConvert(x) {
    if (x.s < 0 || x.compareTo(this.m) >= 0) return x.mod(this.m)
    else return x
  }
  
  function cRevert(x) {
    return x
  }
  
  function cReduce(x) {
    x.divRemTo(this.m, null, x)
  }
  
  function cMulTo(x, y, r) {
    x.multiplyTo(y, r)
    this.reduce(r)
  }
  
  function cSqrTo(x, r) {
    x.squareTo(r)
    this.reduce(r)
  }
  
  Classic.prototype.convert = cConvert
  Classic.prototype.revert = cRevert
  Classic.prototype.reduce = cReduce
  Classic.prototype.mulTo = cMulTo
  Classic.prototype.sqrTo = cSqrTo
  
  // (protected) return "-1/this % 2^DB"; useful for Mont. reduction
  // justification:
  //         xy == 1 (mod m)
  //         xy =  1+km
  //   xy(2-xy) = (1+km)(1-km)
  // x[y(2-xy)] = 1-k^2m^2
  // x[y(2-xy)] == 1 (mod m^2)
  // if y is 1/x mod m, then y(2-xy) is 1/x mod m^2
  // should reduce x and y(2-xy) by m^2 at each step to keep size bounded.
  // JS multiply "overflows" differently from C/C++, so care is needed here.
  function bnpInvDigit() {
    if (this.t < 1) return 0
    var x = this[0]
    if ((x & 1) == 0) return 0
    var y = x & 3; // y == 1/x mod 2^2
    y = (y * (2 - (x & 0xf) * y)) & 0xf; // y == 1/x mod 2^4
    y = (y * (2 - (x & 0xff) * y)) & 0xff; // y == 1/x mod 2^8
    y = (y * (2 - (((x & 0xffff) * y) & 0xffff))) & 0xffff; // y == 1/x mod 2^16
    // last step - calculate inverse mod DV directly
    // assumes 16 < DB <= 32 and assumes ability to handle 48-bit ints
    y = (y * (2 - x * y % this.DV)) % this.DV; // y == 1/x mod 2^dbits
    // we really want the negative inverse, and -DV < y < DV
    return (y > 0) ? this.DV - y : -y
  }
  
  // Montgomery reduction
  function Montgomery(m) {
    this.m = m
    this.mp = m.invDigit()
    this.mpl = this.mp & 0x7fff
    this.mph = this.mp >> 15
    this.um = (1 << (m.DB - 15)) - 1
    this.mt2 = 2 * m.t
  }
  
  // xR mod m
  function montConvert(x) {
    var r = new BigInteger()
    x.abs()
      .dlShiftTo(this.m.t, r)
    r.divRemTo(this.m, null, r)
    if (x.s < 0 && r.compareTo(BigInteger.ZERO) > 0) this.m.subTo(r, r)
    return r
  }
  
  // x/R mod m
  function montRevert(x) {
    var r = new BigInteger()
    x.copyTo(r)
    this.reduce(r)
    return r
  }
  
  // x = x/R mod m (HAC 14.32)
  function montReduce(x) {
    while (x.t <= this.mt2) // pad x so am has enough room later
      x[x.t++] = 0
    for (var i = 0; i < this.m.t; ++i) {
      // faster way of calculating u0 = x[i]*mp mod DV
      var j = x[i] & 0x7fff
      var u0 = (j * this.mpl + (((j * this.mph + (x[i] >> 15) * this.mpl) & this.um) << 15)) & x.DM
      // use am to combine the multiply-shift-add into one call
      j = i + this.m.t
      x[j] += this.m.am(0, u0, x, i, 0, this.m.t)
      // propagate carry
      while (x[j] >= x.DV) {
        x[j] -= x.DV
        x[++j]++
      }
    }
    x.clamp()
    x.drShiftTo(this.m.t, x)
    if (x.compareTo(this.m) >= 0) x.subTo(this.m, x)
  }
  
  // r = "x^2/R mod m"; x != r
  function montSqrTo(x, r) {
    x.squareTo(r)
    this.reduce(r)
  }
  
  // r = "xy/R mod m"; x,y != r
  function montMulTo(x, y, r) {
    x.multiplyTo(y, r)
    this.reduce(r)
  }
  
  Montgomery.prototype.convert = montConvert
  Montgomery.prototype.revert = montRevert
  Montgomery.prototype.reduce = montReduce
  Montgomery.prototype.mulTo = montMulTo
  Montgomery.prototype.sqrTo = montSqrTo
  
  // (protected) true iff this is even
  function bnpIsEven() {
    return ((this.t > 0) ? (this[0] & 1) : this.s) == 0
  }
  
  // (protected) this^e, e < 2^32, doing sqr and mul with "r" (HAC 14.79)
  function bnpExp(e, z) {
    if (e > 0xffffffff || e < 1) return BigInteger.ONE
    var r = new BigInteger(),
      r2 = new BigInteger(),
      g = z.convert(this),
      i = nbits(e) - 1
    g.copyTo(r)
    while (--i >= 0) {
      z.sqrTo(r, r2)
      if ((e & (1 << i)) > 0) z.mulTo(r2, g, r)
      else {
        var t = r
        r = r2
        r2 = t
      }
    }
    return z.revert(r)
  }
  
  // (public) this^e % m, 0 <= e < 2^32
  function bnModPowInt(e, m) {
    var z
    if (e < 256 || m.isEven()) z = new Classic(m)
    else z = new Montgomery(m)
    return this.exp(e, z)
  }
  
  // protected
  proto.copyTo = bnpCopyTo
  proto.fromInt = bnpFromInt
  proto.fromString = bnpFromString
  proto.clamp = bnpClamp
  proto.dlShiftTo = bnpDLShiftTo
  proto.drShiftTo = bnpDRShiftTo
  proto.lShiftTo = bnpLShiftTo
  proto.rShiftTo = bnpRShiftTo
  proto.subTo = bnpSubTo
  proto.multiplyTo = bnpMultiplyTo
  proto.squareTo = bnpSquareTo
  proto.divRemTo = bnpDivRemTo
  proto.invDigit = bnpInvDigit
  proto.isEven = bnpIsEven
  proto.exp = bnpExp
  
  // public
  proto.toString = bnToString
  proto.negate = bnNegate
  proto.abs = bnAbs
  proto.compareTo = bnCompareTo
  proto.bitLength = bnBitLength
  proto.byteLength = bnByteLength
  proto.mod = bnMod
  proto.modPowInt = bnModPowInt
  
  // (public)
  function bnClone() {
    var r = new BigInteger()
    this.copyTo(r)
    return r
  }
  
  // (public) return value as integer
  function bnIntValue() {
    if (this.s < 0) {
      if (this.t == 1) return this[0] - this.DV
      else if (this.t == 0) return -1
    } else if (this.t == 1) return this[0]
    else if (this.t == 0) return 0
    // assumes 16 < DB < 32
    return ((this[1] & ((1 << (32 - this.DB)) - 1)) << this.DB) | this[0]
  }
  
  // (public) return value as byte
  function bnByteValue() {
    return (this.t == 0) ? this.s : (this[0] << 24) >> 24
  }
  
  // (public) return value as short (assumes DB>=16)
  function bnShortValue() {
    return (this.t == 0) ? this.s : (this[0] << 16) >> 16
  }
  
  // (protected) return x s.t. r^x < DV
  function bnpChunkSize(r) {
    return Math.floor(Math.LN2 * this.DB / Math.log(r))
  }
  
  // (public) 0 if this == 0, 1 if this > 0
  function bnSigNum() {
    if (this.s < 0) return -1
    else if (this.t <= 0 || (this.t == 1 && this[0] <= 0)) return 0
    else return 1
  }
  
  // (protected) convert to radix string
  function bnpToRadix(b) {
    if (b == null) b = 10
    if (this.signum() == 0 || b < 2 || b > 36) return "0"
    var cs = this.chunkSize(b)
    var a = Math.pow(b, cs)
    var d = nbv(a),
      y = new BigInteger(),
      z = new BigInteger(),
      r = ""
    this.divRemTo(d, y, z)
    while (y.signum() > 0) {
      r = (a + z.intValue())
        .toString(b)
        .substr(1) + r
      y.divRemTo(d, y, z)
    }
    return z.intValue()
      .toString(b) + r
  }
  
  // (protected) convert from radix string
  function bnpFromRadix(s, b) {
    var self = this
    self.fromInt(0)
    if (b == null) b = 10
    var cs = self.chunkSize(b)
    var d = Math.pow(b, cs),
      mi = false,
      j = 0,
      w = 0
    for (var i = 0; i < s.length; ++i) {
      var x = intAt(s, i)
      if (x < 0) {
        if (s.charAt(i) == "-" && self.signum() == 0) mi = true
        continue
      }
      w = b * w + x
      if (++j >= cs) {
        self.dMultiply(d)
        self.dAddOffset(w, 0)
        j = 0
        w = 0
      }
    }
    if (j > 0) {
      self.dMultiply(Math.pow(b, j))
      self.dAddOffset(w, 0)
    }
    if (mi) BigInteger.ZERO.subTo(self, self)
  }
  
  // (protected) alternate constructor
  function bnpFromNumber(a, b, c) {
    var self = this
    if ("number" == typeof b) {
      // new BigInteger(int,int,RNG)
      if (a < 2) self.fromInt(1)
      else {
        self.fromNumber(a, c)
        if (!self.testBit(a - 1)) // force MSB set
          self.bitwiseTo(BigInteger.ONE.shiftLeft(a - 1), op_or, self)
        if (self.isEven()) self.dAddOffset(1, 0); // force odd
        while (!self.isProbablePrime(b)) {
          self.dAddOffset(2, 0)
          if (self.bitLength() > a) self.subTo(BigInteger.ONE.shiftLeft(a - 1), self)
        }
      }
    } else {
      // new BigInteger(int,RNG)
      var x = new Array(),
        t = a & 7
      x.length = (a >> 3) + 1
      b.nextBytes(x)
      if (t > 0) x[0] &= ((1 << t) - 1)
      else x[0] = 0
      self.fromString(x, 256)
    }
  }
  
  // (public) convert to bigendian byte array
  function bnToByteArray() {
    var self = this
    var i = self.t,
      r = new Array()
    r[0] = self.s
    var p = self.DB - (i * self.DB) % 8,
      d, k = 0
    if (i-- > 0) {
      if (p < self.DB && (d = self[i] >> p) != (self.s & self.DM) >> p)
        r[k++] = d | (self.s << (self.DB - p))
      while (i >= 0) {
        if (p < 8) {
          d = (self[i] & ((1 << p) - 1)) << (8 - p)
          d |= self[--i] >> (p += self.DB - 8)
        } else {
          d = (self[i] >> (p -= 8)) & 0xff
          if (p <= 0) {
            p += self.DB
            --i
          }
        }
        if ((d & 0x80) != 0) d |= -256
        if (k === 0 && (self.s & 0x80) != (d & 0x80))++k
        if (k > 0 || d != self.s) r[k++] = d
      }
    }
    return r
  }
  
  function bnEquals(a) {
    return (this.compareTo(a) == 0)
  }
  
  function bnMin(a) {
    return (this.compareTo(a) < 0) ? this : a
  }
  
  function bnMax(a) {
    return (this.compareTo(a) > 0) ? this : a
  }
  
  // (protected) r = this op a (bitwise)
  function bnpBitwiseTo(a, op, r) {
    var self = this
    var i, f, m = Math.min(a.t, self.t)
    for (i = 0; i < m; ++i) r[i] = op(self[i], a[i])
    if (a.t < self.t) {
      f = a.s & self.DM
      for (i = m; i < self.t; ++i) r[i] = op(self[i], f)
      r.t = self.t
    } else {
      f = self.s & self.DM
      for (i = m; i < a.t; ++i) r[i] = op(f, a[i])
      r.t = a.t
    }
    r.s = op(self.s, a.s)
    r.clamp()
  }
  
  // (public) this & a
  function op_and(x, y) {
    return x & y
  }
  
  function bnAnd(a) {
    var r = new BigInteger()
    this.bitwiseTo(a, op_and, r)
    return r
  }
  
  // (public) this | a
  function op_or(x, y) {
    return x | y
  }
  
  function bnOr(a) {
    var r = new BigInteger()
    this.bitwiseTo(a, op_or, r)
    return r
  }
  
  // (public) this ^ a
  function op_xor(x, y) {
    return x ^ y
  }
  
  function bnXor(a) {
    var r = new BigInteger()
    this.bitwiseTo(a, op_xor, r)
    return r
  }
  
  // (public) this & ~a
  function op_andnot(x, y) {
    return x & ~y
  }
  
  function bnAndNot(a) {
    var r = new BigInteger()
    this.bitwiseTo(a, op_andnot, r)
    return r
  }
  
  // (public) ~this
  function bnNot() {
    var r = new BigInteger()
    for (var i = 0; i < this.t; ++i) r[i] = this.DM & ~this[i]
    r.t = this.t
    r.s = ~this.s
    return r
  }
  
  // (public) this << n
  function bnShiftLeft(n) {
    var r = new BigInteger()
    if (n < 0) this.rShiftTo(-n, r)
    else this.lShiftTo(n, r)
    return r
  }
  
  // (public) this >> n
  function bnShiftRight(n) {
    var r = new BigInteger()
    if (n < 0) this.lShiftTo(-n, r)
    else this.rShiftTo(n, r)
    return r
  }
  
  // return index of lowest 1-bit in x, x < 2^31
  function lbit(x) {
    if (x == 0) return -1
    var r = 0
    if ((x & 0xffff) == 0) {
      x >>= 16
      r += 16
    }
    if ((x & 0xff) == 0) {
      x >>= 8
      r += 8
    }
    if ((x & 0xf) == 0) {
      x >>= 4
      r += 4
    }
    if ((x & 3) == 0) {
      x >>= 2
      r += 2
    }
    if ((x & 1) == 0)++r
    return r
  }
  
  // (public) returns index of lowest 1-bit (or -1 if none)
  function bnGetLowestSetBit() {
    for (var i = 0; i < this.t; ++i)
      if (this[i] != 0) return i * this.DB + lbit(this[i])
    if (this.s < 0) return this.t * this.DB
    return -1
  }
  
  // return number of 1 bits in x
  function cbit(x) {
    var r = 0
    while (x != 0) {
      x &= x - 1
      ++r
    }
    return r
  }
  
  // (public) return number of set bits
  function bnBitCount() {
    var r = 0,
      x = this.s & this.DM
    for (var i = 0; i < this.t; ++i) r += cbit(this[i] ^ x)
    return r
  }
  
  // (public) true iff nth bit is set
  function bnTestBit(n) {
    var j = Math.floor(n / this.DB)
    if (j >= this.t) return (this.s != 0)
    return ((this[j] & (1 << (n % this.DB))) != 0)
  }
  
  // (protected) this op (1<<n)
  function bnpChangeBit(n, op) {
    var r = BigInteger.ONE.shiftLeft(n)
    this.bitwiseTo(r, op, r)
    return r
  }
  
  // (public) this | (1<<n)
  function bnSetBit(n) {
    return this.changeBit(n, op_or)
  }
  
  // (public) this & ~(1<<n)
  function bnClearBit(n) {
    return this.changeBit(n, op_andnot)
  }
  
  // (public) this ^ (1<<n)
  function bnFlipBit(n) {
    return this.changeBit(n, op_xor)
  }
  
  // (protected) r = this + a
  function bnpAddTo(a, r) {
    var self = this
  
    var i = 0,
      c = 0,
      m = Math.min(a.t, self.t)
    while (i < m) {
      c += self[i] + a[i]
      r[i++] = c & self.DM
      c >>= self.DB
    }
    if (a.t < self.t) {
      c += a.s
      while (i < self.t) {
        c += self[i]
        r[i++] = c & self.DM
        c >>= self.DB
      }
      c += self.s
    } else {
      c += self.s
      while (i < a.t) {
        c += a[i]
        r[i++] = c & self.DM
        c >>= self.DB
      }
      c += a.s
    }
    r.s = (c < 0) ? -1 : 0
    if (c > 0) r[i++] = c
    else if (c < -1) r[i++] = self.DV + c
    r.t = i
    r.clamp()
  }
  
  // (public) this + a
  function bnAdd(a) {
    var r = new BigInteger()
    this.addTo(a, r)
    return r
  }
  
  // (public) this - a
  function bnSubtract(a) {
    var r = new BigInteger()
    this.subTo(a, r)
    return r
  }
  
  // (public) this * a
  function bnMultiply(a) {
    var r = new BigInteger()
    this.multiplyTo(a, r)
    return r
  }
  
  // (public) this^2
  function bnSquare() {
    var r = new BigInteger()
    this.squareTo(r)
    return r
  }
  
  // (public) this / a
  function bnDivide(a) {
    var r = new BigInteger()
    this.divRemTo(a, r, null)
    return r
  }
  
  // (public) this % a
  function bnRemainder(a) {
    var r = new BigInteger()
    this.divRemTo(a, null, r)
    return r
  }
  
  // (public) [this/a,this%a]
  function bnDivideAndRemainder(a) {
    var q = new BigInteger(),
      r = new BigInteger()
    this.divRemTo(a, q, r)
    return new Array(q, r)
  }
  
  // (protected) this *= n, this >= 0, 1 < n < DV
  function bnpDMultiply(n) {
    this[this.t] = this.am(0, n - 1, this, 0, 0, this.t)
    ++this.t
    this.clamp()
  }
  
  // (protected) this += n << w words, this >= 0
  function bnpDAddOffset(n, w) {
    if (n == 0) return
    while (this.t <= w) this[this.t++] = 0
    this[w] += n
    while (this[w] >= this.DV) {
      this[w] -= this.DV
      if (++w >= this.t) this[this.t++] = 0
      ++this[w]
    }
  }
  
  // A "null" reducer
  function NullExp() {}
  
  function nNop(x) {
    return x
  }
  
  function nMulTo(x, y, r) {
    x.multiplyTo(y, r)
  }
  
  function nSqrTo(x, r) {
    x.squareTo(r)
  }
  
  NullExp.prototype.convert = nNop
  NullExp.prototype.revert = nNop
  NullExp.prototype.mulTo = nMulTo
  NullExp.prototype.sqrTo = nSqrTo
  
  // (public) this^e
  function bnPow(e) {
    return this.exp(e, new NullExp())
  }
  
  // (protected) r = lower n words of "this * a", a.t <= n
  // "this" should be the larger one if appropriate.
  function bnpMultiplyLowerTo(a, n, r) {
    var i = Math.min(this.t + a.t, n)
    r.s = 0; // assumes a,this >= 0
    r.t = i
    while (i > 0) r[--i] = 0
    var j
    for (j = r.t - this.t; i < j; ++i) r[i + this.t] = this.am(0, a[i], r, i, 0, this.t)
    for (j = Math.min(a.t, n); i < j; ++i) this.am(0, a[i], r, i, 0, n - i)
    r.clamp()
  }
  
  // (protected) r = "this * a" without lower n words, n > 0
  // "this" should be the larger one if appropriate.
  function bnpMultiplyUpperTo(a, n, r) {
    --n
    var i = r.t = this.t + a.t - n
    r.s = 0; // assumes a,this >= 0
    while (--i >= 0) r[i] = 0
    for (i = Math.max(n - this.t, 0); i < a.t; ++i)
      r[this.t + i - n] = this.am(n - i, a[i], r, 0, 0, this.t + i - n)
    r.clamp()
    r.drShiftTo(1, r)
  }
  
  // Barrett modular reduction
  function Barrett(m) {
    // setup Barrett
    this.r2 = new BigInteger()
    this.q3 = new BigInteger()
    BigInteger.ONE.dlShiftTo(2 * m.t, this.r2)
    this.mu = this.r2.divide(m)
    this.m = m
  }
  
  function barrettConvert(x) {
    if (x.s < 0 || x.t > 2 * this.m.t) return x.mod(this.m)
    else if (x.compareTo(this.m) < 0) return x
    else {
      var r = new BigInteger()
      x.copyTo(r)
      this.reduce(r)
      return r
    }
  }
  
  function barrettRevert(x) {
    return x
  }
  
  // x = x mod m (HAC 14.42)
  function barrettReduce(x) {
    var self = this
    x.drShiftTo(self.m.t - 1, self.r2)
    if (x.t > self.m.t + 1) {
      x.t = self.m.t + 1
      x.clamp()
    }
    self.mu.multiplyUpperTo(self.r2, self.m.t + 1, self.q3)
    self.m.multiplyLowerTo(self.q3, self.m.t + 1, self.r2)
    while (x.compareTo(self.r2) < 0) x.dAddOffset(1, self.m.t + 1)
    x.subTo(self.r2, x)
    while (x.compareTo(self.m) >= 0) x.subTo(self.m, x)
  }
  
  // r = x^2 mod m; x != r
  function barrettSqrTo(x, r) {
    x.squareTo(r)
    this.reduce(r)
  }
  
  // r = x*y mod m; x,y != r
  function barrettMulTo(x, y, r) {
    x.multiplyTo(y, r)
    this.reduce(r)
  }
  
  Barrett.prototype.convert = barrettConvert
  Barrett.prototype.revert = barrettRevert
  Barrett.prototype.reduce = barrettReduce
  Barrett.prototype.mulTo = barrettMulTo
  Barrett.prototype.sqrTo = barrettSqrTo
  
  // (public) this^e % m (HAC 14.85)
  function bnModPow(e, m) {
    var i = e.bitLength(),
      k, r = nbv(1),
      z
    if (i <= 0) return r
    else if (i < 18) k = 1
    else if (i < 48) k = 3
    else if (i < 144) k = 4
    else if (i < 768) k = 5
    else k = 6
    if (i < 8)
      z = new Classic(m)
    else if (m.isEven())
      z = new Barrett(m)
    else
      z = new Montgomery(m)
  
    // precomputation
    var g = new Array(),
      n = 3,
      k1 = k - 1,
      km = (1 << k) - 1
    g[1] = z.convert(this)
    if (k > 1) {
      var g2 = new BigInteger()
      z.sqrTo(g[1], g2)
      while (n <= km) {
        g[n] = new BigInteger()
        z.mulTo(g2, g[n - 2], g[n])
        n += 2
      }
    }
  
    var j = e.t - 1,
      w, is1 = true,
      r2 = new BigInteger(),
      t
    i = nbits(e[j]) - 1
    while (j >= 0) {
      if (i >= k1) w = (e[j] >> (i - k1)) & km
      else {
        w = (e[j] & ((1 << (i + 1)) - 1)) << (k1 - i)
        if (j > 0) w |= e[j - 1] >> (this.DB + i - k1)
      }
  
      n = k
      while ((w & 1) == 0) {
        w >>= 1
        --n
      }
      if ((i -= n) < 0) {
        i += this.DB
        --j
      }
      if (is1) { // ret == 1, don't bother squaring or multiplying it
        g[w].copyTo(r)
        is1 = false
      } else {
        while (n > 1) {
          z.sqrTo(r, r2)
          z.sqrTo(r2, r)
          n -= 2
        }
        if (n > 0) z.sqrTo(r, r2)
        else {
          t = r
          r = r2
          r2 = t
        }
        z.mulTo(r2, g[w], r)
      }
  
      while (j >= 0 && (e[j] & (1 << i)) == 0) {
        z.sqrTo(r, r2)
        t = r
        r = r2
        r2 = t
        if (--i < 0) {
          i = this.DB - 1
          --j
        }
      }
    }
    return z.revert(r)
  }
  
  // (public) gcd(this,a) (HAC 14.54)
  function bnGCD(a) {
    var x = (this.s < 0) ? this.negate() : this.clone()
    var y = (a.s < 0) ? a.negate() : a.clone()
    if (x.compareTo(y) < 0) {
      var t = x
      x = y
      y = t
    }
    var i = x.getLowestSetBit(),
      g = y.getLowestSetBit()
    if (g < 0) return x
    if (i < g) g = i
    if (g > 0) {
      x.rShiftTo(g, x)
      y.rShiftTo(g, y)
    }
    while (x.signum() > 0) {
      if ((i = x.getLowestSetBit()) > 0) x.rShiftTo(i, x)
      if ((i = y.getLowestSetBit()) > 0) y.rShiftTo(i, y)
      if (x.compareTo(y) >= 0) {
        x.subTo(y, x)
        x.rShiftTo(1, x)
      } else {
        y.subTo(x, y)
        y.rShiftTo(1, y)
      }
    }
    if (g > 0) y.lShiftTo(g, y)
    return y
  }
  
  // (protected) this % n, n < 2^26
  function bnpModInt(n) {
    if (n <= 0) return 0
    var d = this.DV % n,
      r = (this.s < 0) ? n - 1 : 0
    if (this.t > 0)
      if (d == 0) r = this[0] % n
      else
        for (var i = this.t - 1; i >= 0; --i) r = (d * r + this[i]) % n
    return r
  }
  
  // (public) 1/this % m (HAC 14.61)
  function bnModInverse(m) {
    var ac = m.isEven()
    if (this.signum() === 0) throw new Error('division by zero')
    if ((this.isEven() && ac) || m.signum() == 0) return BigInteger.ZERO
    var u = m.clone(),
      v = this.clone()
    var a = nbv(1),
      b = nbv(0),
      c = nbv(0),
      d = nbv(1)
    while (u.signum() != 0) {
      while (u.isEven()) {
        u.rShiftTo(1, u)
        if (ac) {
          if (!a.isEven() || !b.isEven()) {
            a.addTo(this, a)
            b.subTo(m, b)
          }
          a.rShiftTo(1, a)
        } else if (!b.isEven()) b.subTo(m, b)
        b.rShiftTo(1, b)
      }
      while (v.isEven()) {
        v.rShiftTo(1, v)
        if (ac) {
          if (!c.isEven() || !d.isEven()) {
            c.addTo(this, c)
            d.subTo(m, d)
          }
          c.rShiftTo(1, c)
        } else if (!d.isEven()) d.subTo(m, d)
        d.rShiftTo(1, d)
      }
      if (u.compareTo(v) >= 0) {
        u.subTo(v, u)
        if (ac) a.subTo(c, a)
        b.subTo(d, b)
      } else {
        v.subTo(u, v)
        if (ac) c.subTo(a, c)
        d.subTo(b, d)
      }
    }
    if (v.compareTo(BigInteger.ONE) != 0) return BigInteger.ZERO
    while (d.compareTo(m) >= 0) d.subTo(m, d)
    while (d.signum() < 0) d.addTo(m, d)
    return d
  }
  
  var lowprimes = [
    2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71,
    73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151,
    157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233,
    239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317,
    331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419,
    421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503,
    509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607,
    613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701,
    709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811,
    821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911,
    919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997
  ]
  
  var lplim = (1 << 26) / lowprimes[lowprimes.length - 1]
  
  // (public) test primality with certainty >= 1-.5^t
  function bnIsProbablePrime(t) {
    var i, x = this.abs()
    if (x.t == 1 && x[0] <= lowprimes[lowprimes.length - 1]) {
      for (i = 0; i < lowprimes.length; ++i)
        if (x[0] == lowprimes[i]) return true
      return false
    }
    if (x.isEven()) return false
    i = 1
    while (i < lowprimes.length) {
      var m = lowprimes[i],
        j = i + 1
      while (j < lowprimes.length && m < lplim) m *= lowprimes[j++]
      m = x.modInt(m)
      while (i < j) if (m % lowprimes[i++] == 0) return false
    }
    return x.millerRabin(t)
  }
  
  // (protected) true if probably prime (HAC 4.24, Miller-Rabin)
  function bnpMillerRabin(t) {
    var n1 = this.subtract(BigInteger.ONE)
    var k = n1.getLowestSetBit()
    if (k <= 0) return false
    var r = n1.shiftRight(k)
    t = (t + 1) >> 1
    if (t > lowprimes.length) t = lowprimes.length
    var a = new BigInteger(null)
    var j, bases = []
    for (var i = 0; i < t; ++i) {
      for (;;) {
        j = lowprimes[Math.floor(Math.random() * lowprimes.length)]
        if (bases.indexOf(j) == -1) break
      }
      bases.push(j)
      a.fromInt(j)
      var y = a.modPow(r, this)
      if (y.compareTo(BigInteger.ONE) != 0 && y.compareTo(n1) != 0) {
        var j = 1
        while (j++ < k && y.compareTo(n1) != 0) {
          y = y.modPowInt(2, this)
          if (y.compareTo(BigInteger.ONE) == 0) return false
        }
        if (y.compareTo(n1) != 0) return false
      }
    }
    return true
  }
  
  // protected
  proto.chunkSize = bnpChunkSize
  proto.toRadix = bnpToRadix
  proto.fromRadix = bnpFromRadix
  proto.fromNumber = bnpFromNumber
  proto.bitwiseTo = bnpBitwiseTo
  proto.changeBit = bnpChangeBit
  proto.addTo = bnpAddTo
  proto.dMultiply = bnpDMultiply
  proto.dAddOffset = bnpDAddOffset
  proto.multiplyLowerTo = bnpMultiplyLowerTo
  proto.multiplyUpperTo = bnpMultiplyUpperTo
  proto.modInt = bnpModInt
  proto.millerRabin = bnpMillerRabin
  
  // public
  proto.clone = bnClone
  proto.intValue = bnIntValue
  proto.byteValue = bnByteValue
  proto.shortValue = bnShortValue
  proto.signum = bnSigNum
  proto.toByteArray = bnToByteArray
  proto.equals = bnEquals
  proto.min = bnMin
  proto.max = bnMax
  proto.and = bnAnd
  proto.or = bnOr
  proto.xor = bnXor
  proto.andNot = bnAndNot
  proto.not = bnNot
  proto.shiftLeft = bnShiftLeft
  proto.shiftRight = bnShiftRight
  proto.getLowestSetBit = bnGetLowestSetBit
  proto.bitCount = bnBitCount
  proto.testBit = bnTestBit
  proto.setBit = bnSetBit
  proto.clearBit = bnClearBit
  proto.flipBit = bnFlipBit
  proto.add = bnAdd
  proto.subtract = bnSubtract
  proto.multiply = bnMultiply
  proto.divide = bnDivide
  proto.remainder = bnRemainder
  proto.divideAndRemainder = bnDivideAndRemainder
  proto.modPow = bnModPow
  proto.modInverse = bnModInverse
  proto.pow = bnPow
  proto.gcd = bnGCD
  proto.isProbablePrime = bnIsProbablePrime
  
  // JSBN-specific extension
  proto.square = bnSquare
  
  // constants
  BigInteger.ZERO = nbv(0)
  BigInteger.ONE = nbv(1)
  BigInteger.valueOf = nbv
  
  module.exports = BigInteger
  
  },{"../package.json":6}],4:[function(require,module,exports){
  (function (Buffer){
  // FIXME: Kind of a weird way to throw exceptions, consider removing
  var assert = require('assert')
  var BigInteger = require('./bigi')
  
  /**
   * Turns a byte array into a big integer.
   *
   * This function will interpret a byte array as a big integer in big
   * endian notation.
   */
  BigInteger.fromByteArrayUnsigned = function(byteArray) {
    // BigInteger expects a DER integer conformant byte array
    if (byteArray[0] & 0x80) {
      return new BigInteger([0].concat(byteArray))
    }
  
    return new BigInteger(byteArray)
  }
  
  /**
   * Returns a byte array representation of the big integer.
   *
   * This returns the absolute of the contained value in big endian
   * form. A value of zero results in an empty array.
   */
  BigInteger.prototype.toByteArrayUnsigned = function() {
    var byteArray = this.toByteArray()
    return byteArray[0] === 0 ? byteArray.slice(1) : byteArray
  }
  
  BigInteger.fromDERInteger = function(byteArray) {
    return new BigInteger(byteArray)
  }
  
  /*
   * Converts BigInteger to a DER integer representation.
   *
   * The format for this value uses the most significant bit as a sign
   * bit.  If the most significant bit is already set and the integer is
   * positive, a 0x00 is prepended.
   *
   * Examples:
   *
   *      0 =>     0x00
   *      1 =>     0x01
   *     -1 =>     0xff
   *    127 =>     0x7f
   *   -127 =>     0x81
   *    128 =>   0x0080
   *   -128 =>     0x80
   *    255 =>   0x00ff
   *   -255 =>   0xff01
   *  16300 =>   0x3fac
   * -16300 =>   0xc054
   *  62300 => 0x00f35c
   * -62300 => 0xff0ca4
  */
  BigInteger.prototype.toDERInteger = BigInteger.prototype.toByteArray
  
  BigInteger.fromBuffer = function(buffer) {
    // BigInteger expects a DER integer conformant byte array
    if (buffer[0] & 0x80) {
      var byteArray = Array.prototype.slice.call(buffer)
  
      return new BigInteger([0].concat(byteArray))
    }
  
    return new BigInteger(buffer)
  }
  
  BigInteger.fromHex = function(hex) {
    if (hex === '') return BigInteger.ZERO
  
    assert.equal(hex, hex.match(/^[A-Fa-f0-9]+/), 'Invalid hex string')
    assert.equal(hex.length % 2, 0, 'Incomplete hex')
    return new BigInteger(hex, 16)
  }
  
  BigInteger.prototype.toBuffer = function(size) {
    var byteArray = this.toByteArrayUnsigned()
    var zeros = []
  
    var padding = size - byteArray.length
    while (zeros.length < padding) zeros.push(0)
  
    return new Buffer(zeros.concat(byteArray))
  }
  
  BigInteger.prototype.toHex = function(size) {
    return this.toBuffer(size).toString('hex')
  }
  
  }).call(this,require("buffer").Buffer)
  },{"./bigi":3,"assert":75,"buffer":79}],5:[function(require,module,exports){
  var BigInteger = require('./bigi')
  
  //addons
  require('./convert')
  
  module.exports = BigInteger
  },{"./bigi":3,"./convert":4}],6:[function(require,module,exports){
  module.exports={
    "_args": [
      [
        {
          "raw": "bigi@^1.4.1",
          "scope": null,
          "escapedName": "bigi",
          "name": "bigi",
          "rawSpec": "^1.4.1",
          "spec": ">=1.4.1 <2.0.0",
          "type": "range"
        },
        "/Users/luisan00/Desktop/ws/node_modules/bitsharesjs"
      ]
    ],
    "_from": "bigi@>=1.4.1 <2.0.0",
    "_id": "bigi@1.4.2",
    "_inCache": true,
    "_location": "/bigi",
    "_nodeVersion": "6.1.0",
    "_npmOperationalInternal": {
      "host": "packages-12-west.internal.npmjs.com",
      "tmp": "tmp/bigi-1.4.2.tgz_1469584192413_0.6801238611806184"
    },
    "_npmUser": {
      "name": "jprichardson",
      "email": "jprichardson@gmail.com"
    },
    "_npmVersion": "3.8.6",
    "_phantomChildren": {},
    "_requested": {
      "raw": "bigi@^1.4.1",
      "scope": null,
      "escapedName": "bigi",
      "name": "bigi",
      "rawSpec": "^1.4.1",
      "spec": ">=1.4.1 <2.0.0",
      "type": "range"
    },
    "_requiredBy": [
      "/bitsharesjs",
      "/ecurve"
    ],
    "_resolved": "https://registry.npmjs.org/bigi/-/bigi-1.4.2.tgz",
    "_shasum": "9c665a95f88b8b08fc05cfd731f561859d725825",
    "_shrinkwrap": null,
    "_spec": "bigi@^1.4.1",
    "_where": "/Users/luisan00/Desktop/ws/node_modules/bitsharesjs",
    "bugs": {
      "url": "https://github.com/cryptocoinjs/bigi/issues"
    },
    "dependencies": {},
    "description": "Big integers.",
    "devDependencies": {
      "coveralls": "^2.11.2",
      "istanbul": "^0.3.5",
      "jshint": "^2.5.1",
      "mocha": "^2.1.0",
      "mochify": "^2.1.0"
    },
    "directories": {},
    "dist": {
      "shasum": "9c665a95f88b8b08fc05cfd731f561859d725825",
      "tarball": "https://registry.npmjs.org/bigi/-/bigi-1.4.2.tgz"
    },
    "gitHead": "c25308081c896ff84702303722bf5ecd8b3f78e3",
    "homepage": "https://github.com/cryptocoinjs/bigi#readme",
    "keywords": [
      "cryptography",
      "math",
      "bitcoin",
      "arbitrary",
      "precision",
      "arithmetic",
      "big",
      "integer",
      "int",
      "number",
      "biginteger",
      "bigint",
      "bignumber",
      "decimal",
      "float"
    ],
    "main": "./lib/index.js",
    "maintainers": [
      {
        "name": "midnightlightning",
        "email": "boydb@midnightdesign.ws"
      },
      {
        "name": "sidazhang",
        "email": "sidazhang89@gmail.com"
      },
      {
        "name": "nadav",
        "email": "npm@shesek.info"
      },
      {
        "name": "jprichardson",
        "email": "jprichardson@gmail.com"
      }
    ],
    "name": "bigi",
    "optionalDependencies": {},
    "readme": "ERROR: No README data found!",
    "repository": {
      "url": "git+https://github.com/cryptocoinjs/bigi.git",
      "type": "git"
    },
    "scripts": {
      "browser-test": "mochify --wd -R spec",
      "coverage": "istanbul cover ./node_modules/.bin/_mocha -- --reporter list test/*.js",
      "coveralls": "npm run-script coverage && node ./node_modules/.bin/coveralls < coverage/lcov.info",
      "jshint": "jshint --config jshint.json lib/*.js ; true",
      "test": "_mocha -- test/*.js",
      "unit": "mocha"
    },
    "testling": {
      "files": "test/*.js",
      "harness": "mocha",
      "browsers": [
        "ie/9..latest",
        "firefox/latest",
        "chrome/latest",
        "safari/6.0..latest",
        "iphone/6.0..latest",
        "android-browser/4.2..latest"
      ]
    },
    "version": "1.4.2"
  }
  
  },{}],7:[function(require,module,exports){
  "use strict";
  
  exports.__esModule = true;
  exports.Manager = exports.ChainConfig = exports.Apis = undefined;
  
  var _ApiInstances = require("./src/ApiInstances");
  
  var _ApiInstances2 = _interopRequireDefault(_ApiInstances);
  
  var _ConnectionManager = require("./src/ConnectionManager");
  
  var _ConnectionManager2 = _interopRequireDefault(_ConnectionManager);
  
  var _ChainConfig = require("./src/ChainConfig");
  
  var _ChainConfig2 = _interopRequireDefault(_ChainConfig);
  
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  
  exports.Apis = _ApiInstances2.default;
  exports.ChainConfig = _ChainConfig2.default;
  exports.Manager = _ConnectionManager2.default;
  },{"./src/ApiInstances":8,"./src/ChainConfig":9,"./src/ConnectionManager":11}],8:[function(require,module,exports){
  "use strict";
  
  exports.__esModule = true;
  
  var _ChainWebSocket = require("./ChainWebSocket");
  
  var _ChainWebSocket2 = _interopRequireDefault(_ChainWebSocket);
  
  var _GrapheneApi = require("./GrapheneApi");
  
  var _GrapheneApi2 = _interopRequireDefault(_GrapheneApi);
  
  var _ChainConfig = require("./ChainConfig");
  
  var _ChainConfig2 = _interopRequireDefault(_ChainConfig);
  
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  
  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } // var { List } = require("immutable");
  
  
  var inst = void 0;
  
  /**
      Configure: configure as follows `Apis.instance("ws://localhost:8090").init_promise`.  This returns a promise, once resolved the connection is ready.
  
      Import: import { Apis } from "@graphene/chain"
  
      Short-hand: Apis.db("method", "parm1", 2, 3, ...).  Returns a promise with results.
  
      Additional usage: Apis.instance().db_api().exec("method", ["method", "parm1", 2, 3, ...]).  Returns a promise with results.
  */
  
  exports.default = {
  
      setRpcConnectionStatusCallback: function setRpcConnectionStatusCallback(callback) {
          this.statusCb = callback;
          if (inst) inst.setRpcConnectionStatusCallback(callback);
      },
  
      /**
          @arg {string} cs is only provided in the first call
          @return {Apis} singleton .. Check Apis.instance().init_promise to know when the connection is established
      */
      reset: function reset() {
          var cs = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : "ws://localhost:8090";
          var connect = arguments[1];
          var connectTimeout = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 4000;
  
          if (inst) {
              inst.close();
              inst = null;
          }
          inst = new ApisInstance();
          inst.setRpcConnectionStatusCallback(this.statusCb);
  
          if (inst && connect) {
              inst.connect(cs, connectTimeout);
          }
  
          return inst;
      },
      instance: function instance() {
          var cs = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : "ws://localhost:8090";
          var connect = arguments[1];
          var connectTimeout = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 4000;
  
          if (!inst) {
              inst = new ApisInstance();
              inst.setRpcConnectionStatusCallback(this.statusCb);
          }
  
          if (inst && connect) {
              inst.connect(cs, connectTimeout);
          }
  
          return inst;
      },
      chainId: function chainId() {
          return Apis.instance().chain_id;
      },
  
      close: function close() {
          if (inst) {
              inst.close();
              inst = null;
          }
      }
      // db: (method, ...args) => Apis.instance().db_api().exec(method, toStrings(args)),
      // network: (method, ...args) => Apis.instance().network_api().exec(method, toStrings(args)),
      // history: (method, ...args) => Apis.instance().history_api().exec(method, toStrings(args)),
      // crypto: (method, ...args) => Apis.instance().crypto_api().exec(method, toStrings(args))
  };
  
  var ApisInstance = function () {
      function ApisInstance() {
          _classCallCheck(this, ApisInstance);
      }
  
      /** @arg {string} connection .. */
      ApisInstance.prototype.connect = function connect(cs, connectTimeout) {
          var _this = this;
  
          // console.log("INFO\tApiInstances\tconnect\t", cs);
  
          var rpc_user = "",
              rpc_password = "";
          if (typeof window !== "undefined" && window.location && window.location.protocol === "https:" && cs.indexOf("wss://") < 0) {
              throw new Error("Secure domains require wss connection");
          }
  
          this.ws_rpc = new _ChainWebSocket2.default(cs, this.statusCb, connectTimeout);
  
          this.init_promise = this.ws_rpc.login(rpc_user, rpc_password).then(function () {
              console.log("Connected to API node:", cs);
              _this._db = new _GrapheneApi2.default(_this.ws_rpc, "database");
              _this._net = new _GrapheneApi2.default(_this.ws_rpc, "network_broadcast");
              _this._hist = new _GrapheneApi2.default(_this.ws_rpc, "history");
              _this._crypt = new _GrapheneApi2.default(_this.ws_rpc, "crypto");
              var db_promise = _this._db.init().then(function () {
                  //https://github.com/cryptonomex/graphene/wiki/chain-locked-tx
                  return _this._db.exec("get_chain_id", []).then(function (_chain_id) {
                      _this.chain_id = _chain_id;
                      return _ChainConfig2.default.setChainId(_chain_id);
                      //DEBUG console.log("chain_id1",this.chain_id)
                  });
              });
              _this.ws_rpc.on_reconnect = function () {
                  _this.ws_rpc.login("", "").then(function () {
                      _this._db.init().then(function () {
                          if (_this.statusCb) _this.statusCb("reconnect");
                      });
                      _this._net.init();
                      _this._hist.init();
                      _this._crypt.init();
                  });
              };
              return Promise.all([db_promise, _this._net.init(), _this._hist.init(), _this._crypt.init()
              // Temporary squash crypto API error until the API is upgraded everywhere
              .catch(function (e) {
                  return console.error("ApiInstance\tCrypto API Error", e);
              })]);
          });
      };
  
      ApisInstance.prototype.close = function close() {
          if (this.ws_rpc) this.ws_rpc.close();
          this.ws_rpc = null;
      };
  
      ApisInstance.prototype.db_api = function db_api() {
          return this._db;
      };
  
      ApisInstance.prototype.network_api = function network_api() {
          return this._net;
      };
  
      ApisInstance.prototype.history_api = function history_api() {
          return this._hist;
      };
  
      ApisInstance.prototype.crypto_api = function crypto_api() {
          return this._crypt;
      };
  
      ApisInstance.prototype.setRpcConnectionStatusCallback = function setRpcConnectionStatusCallback(callback) {
          this.statusCb = callback;
      };
  
      return ApisInstance;
  }();
  
  module.exports = exports["default"];
  },{"./ChainConfig":9,"./ChainWebSocket":10,"./GrapheneApi":12}],9:[function(require,module,exports){
  (function (process){
  "use strict";
  
  exports.__esModule = true;
  var _this = void 0;
  
  var ecc_config = {
      address_prefix: process.env.npm_config__graphene_ecc_default_address_prefix || "GPH"
  };
  
  _this = {
      core_asset: "CORE",
      address_prefix: "GPH",
      expire_in_secs: 15,
      expire_in_secs_proposal: 24 * 60 * 60,
      review_in_secs_committee: 24 * 60 * 60,
      networks: {
          BitShares: {
              core_asset: "BTS",
              address_prefix: "BTS",
              chain_id: "4018d7844c78f6a6c41c6a552b898022310fc5dec06da467ee7905a8dad512c8"
          },
          Muse: {
              core_asset: "MUSE",
              address_prefix: "MUSE",
              chain_id: "45ad2d3f9ef92a49b55c2227eb06123f613bb35dd08bd876f2aea21925a67a67"
          },
          Test: {
              core_asset: "TEST",
              address_prefix: "TEST",
              chain_id: "39f5e2ede1f8bc1a3a54a7914414e3779e33193f1f5693510e73cb7a87617447"
          },
          Obelisk: {
              core_asset: "GOV",
              address_prefix: "FEW",
              chain_id: "1cfde7c388b9e8ac06462d68aadbd966b58f88797637d9af805b4560b0e9661e"
          }
      },
  
      /** Set a few properties for known chain IDs. */
      setChainId: function setChainId(chain_id) {
  
          var i = void 0,
              len = void 0,
              network = void 0,
              network_name = void 0,
              ref = void 0;
          ref = Object.keys(_this.networks);
  
          for (i = 0, len = ref.length; i < len; i++) {
  
              network_name = ref[i];
              network = _this.networks[network_name];
  
              if (network.chain_id === chain_id) {
  
                  _this.network_name = network_name;
  
                  if (network.address_prefix) {
                      _this.address_prefix = network.address_prefix;
                      ecc_config.address_prefix = network.address_prefix;
                  }
  
                  // console.log("INFO    Configured for", network_name, ":", network.core_asset, "\n");
  
                  return {
                      network_name: network_name,
                      network: network
                  };
              }
          }
  
          if (!_this.network_name) {
              console.log("Unknown chain id (this may be a testnet)", chain_id);
          }
      },
  
      reset: function reset() {
          _this.core_asset = "CORE";
          _this.address_prefix = "GPH";
          ecc_config.address_prefix = "GPH";
          _this.expire_in_secs = 15;
          _this.expire_in_secs_proposal = 24 * 60 * 60;
  
          console.log("Chain config reset");
      },
  
      setPrefix: function setPrefix() {
          var prefix = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : "GPH";
  
          _this.address_prefix = prefix;
          ecc_config.address_prefix = prefix;
      }
  };
  
  exports.default = _this;
  module.exports = exports["default"];
  }).call(this,require('_process'))
  },{"_process":87}],10:[function(require,module,exports){
  (function (process){
  "use strict";
  
  exports.__esModule = true;
  
  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  
  var WebSocketClient = void 0;
  if (typeof WebSocket === "undefined" && !process.env.browser) {
      WebSocketClient = require("ws");
  } else if (typeof WebSocket !== "undefined" && typeof document !== "undefined") {
      WebSocketClient = require("ReconnectingWebSocket");
  } else {
      WebSocketClient = WebSocket;
  }
  
  var SOCKET_DEBUG = false;
  
  var ChainWebSocket = function () {
      function ChainWebSocket(ws_server, statusCb) {
          var _this = this;
  
          var connectTimeout = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 4000;
  
          _classCallCheck(this, ChainWebSocket);
  
          this.statusCb = statusCb;
          this.connectionTimeout = setTimeout(function () {
              if (_this.current_reject) _this.current_reject(new Error("Connection attempt timed out: " + ws_server));
          }, connectTimeout);
          try {
              this.ws = new WebSocketClient(ws_server);
          } catch (error) {
              console.error("invalid websocket URL:", error, ws_server);
              this.ws = new WebSocketClient("wss://127.0.0.1:8090");
          }
          this.ws.timeoutInterval = 5000;
          this.current_reject = null;
          this.on_reconnect = null;
          this.connect_promise = new Promise(function (resolve, reject) {
              _this.current_reject = reject;
              _this.ws.onopen = function () {
                  clearTimeout(_this.connectionTimeout);
                  if (_this.statusCb) _this.statusCb("open");
                  if (_this.on_reconnect) _this.on_reconnect();
                  resolve();
              };
              _this.ws.onerror = function (error) {
                  clearTimeout(_this.connectionTimeout);
                  if (_this.statusCb) _this.statusCb("error");
  
                  if (_this.current_reject) {
                      _this.current_reject(error);
                  }
              };
              _this.ws.onmessage = function (message) {
                  return _this.listener(JSON.parse(message.data));
              };
              _this.ws.onclose = function () {
                  if (_this.statusCb) _this.statusCb("closed");
              };
          });
          this.cbId = 0;
          this.cbs = {};
          this.subs = {};
          this.unsub = {};
      }
  
      ChainWebSocket.prototype.call = function call(params) {
          var _this2 = this;
  
          var method = params[1];
          if (SOCKET_DEBUG) console.log("[ChainWebSocket] >---- call ----->  \"id\":" + (this.cbId + 1), JSON.stringify(params));
  
          this.cbId += 1;
  
          if (method === "set_subscribe_callback" || method === "subscribe_to_market" || method === "broadcast_transaction_with_callback" || method === "set_pending_transaction_callback") {
              // Store callback in subs map
              this.subs[this.cbId] = {
                  callback: params[2][0]
              };
  
              // Replace callback with the callback id
              params[2][0] = this.cbId;
          }
  
          if (method === "unsubscribe_from_market" || method === "unsubscribe_from_accounts") {
              if (typeof params[2][0] !== "function") {
                  throw new Error("First parameter of unsub must be the original callback");
              }
  
              var unSubCb = params[2].splice(0, 1)[0];
  
              // Find the corresponding subscription
              for (var id in this.subs) {
                  if (this.subs[id].callback === unSubCb) {
                      this.unsub[this.cbId] = id;
                      break;
                  }
              }
          }
  
          var request = {
              method: "call",
              params: params
          };
          request.id = this.cbId;
  
          return new Promise(function (resolve, reject) {
              _this2.cbs[_this2.cbId] = {
                  time: new Date(),
                  resolve: resolve,
                  reject: reject
              };
              _this2.ws.onerror = function (error) {
                  console.log("!!! ChainWebSocket Error ", error);
                  reject(error);
              };
              _this2.ws.send(JSON.stringify(request));
          });
      };
  
      ChainWebSocket.prototype.listener = function listener(response) {
          if (SOCKET_DEBUG) console.log("[ChainWebSocket] <---- reply ----<", JSON.stringify(response));
  
          var sub = false,
              callback = null;
  
          if (response.method === "notice") {
              sub = true;
              response.id = response.params[0];
          }
  
          if (!sub) {
              callback = this.cbs[response.id];
          } else {
              callback = this.subs[response.id].callback;
          }
  
          if (callback && !sub) {
              if (response.error) {
                  callback.reject(response.error);
              } else {
                  callback.resolve(response.result);
              }
              delete this.cbs[response.id];
  
              if (this.unsub[response.id]) {
                  delete this.subs[this.unsub[response.id]];
                  delete this.unsub[response.id];
              }
          } else if (callback && sub) {
              callback(response.params[1]);
          } else {
              console.log("Warning: unknown websocket response: ", response);
          }
      };
  
      ChainWebSocket.prototype.login = function login(user, password) {
          var _this3 = this;
  
          return this.connect_promise.then(function () {
              return _this3.call([1, "login", [user, password]]);
          });
      };
  
      ChainWebSocket.prototype.close = function close() {
          this.ws.close();
      };
  
      return ChainWebSocket;
  }();
  
  exports.default = ChainWebSocket;
  module.exports = exports["default"];
  }).call(this,require('_process'))
  },{"ReconnectingWebSocket":1,"_process":87,"ws":77}],11:[function(require,module,exports){
  "use strict";
  
  exports.__esModule = true;
  
  var _ApiInstances = require("./ApiInstances");
  
  var _ApiInstances2 = _interopRequireDefault(_ApiInstances);
  
  var _ChainWebSocket = require("./ChainWebSocket");
  
  var _ChainWebSocket2 = _interopRequireDefault(_ChainWebSocket);
  
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  
  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  
  var Manager = function () {
      function Manager(_ref) {
          var url = _ref.url,
              urls = _ref.urls;
  
          _classCallCheck(this, Manager);
  
          this.url = url;
          this.urls = urls.filter(function (a) {
              return a !== url;
          });
      }
  
      Manager.prototype.logFailure = function logFailure(url) {
          console.error("Unable to connect to", url + ", skipping to next full node API server");
      };
  
      Manager.prototype.connect = function connect() {
          var _connect = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
  
          var url = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.url;
  
          return new Promise(function (resolve, reject) {
              _ApiInstances2.default.instance(url, _connect).init_promise.then(resolve).catch(function () {
                  _ApiInstances2.default.instance().close();
                  reject();
              });
          });
      };
  
      Manager.prototype.connectWithFallback = function connectWithFallback() {
          var connect = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
          var url = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.url;
          var index = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;
  
          var _this = this;
  
          var resolve = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
          var reject = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : null;
  
          if (reject && index > this.urls.length - 1) return reject(new Error("Tried " + (index + 1) + " connections, none of which worked: " + JSON.stringify(this.urls.concat(this.url))));
          var fallback = function fallback(resolve, reject) {
              _this.logFailure(url);
              return _this.connectWithFallback(connect, _this.urls[index], index + 1, resolve, reject);
          };
          if (resolve && reject) {
              return this.connect(connect, url).then(resolve).catch(function () {
                  fallback(resolve, reject);
              });
          } else {
              return new Promise(function (resolve, reject) {
                  _this.connect(connect).then(resolve).catch(function () {
                      fallback(resolve, reject);
                  });
              });
          }
      };
  
      Manager.prototype.checkConnections = function checkConnections() {
          var rpc_user = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : "";
          var rpc_password = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : "";
  
          var _this2 = this;
  
          var resolve = arguments[2];
          var reject = arguments[3];
  
          var connectionStartTimes = {};
          var checkFunction = function checkFunction(resolve, reject) {
              var fullList = _this2.urls.concat(_this2.url);
              var connectionPromises = [];
  
              fullList.forEach(function (url) {
                  var conn = new _ChainWebSocket2.default(url, function () {});
                  connectionStartTimes[url] = new Date().getTime();
                  connectionPromises.push(function () {
                      return conn.login(rpc_user, rpc_password).then(function (data) {
                          var _ref2;
  
                          conn.close();
                          return _ref2 = {}, _ref2[url] = new Date().getTime() - connectionStartTimes[url], _ref2;
                      }).catch(function (err) {
                          if (url === _this2.url) {
                              _this2.url = _this2.urls[0];
                          } else {
                              _this2.urls = _this2.urls.filter(function (a) {
                                  return a !== url;
                              });
                          }
                          conn.close();
                          return null;
                      });
                  });
              });
  
              Promise.all(connectionPromises.map(function (a) {
                  return a();
              })).then(function (res) {
                  resolve(res.filter(function (a) {
                      return !!a;
                  }).reduce(function (f, a) {
                      var key = Object.keys(a)[0];
                      f[key] = a[key];
                      return f;
                  }, {}));
              }).catch(function () {
                  return _this2.checkConnections(rpc_user, rpc_password, resolve, reject);
              });
          };
  
          if (resolve && reject) {
              checkFunction(resolve, reject);
          } else {
              return new Promise(checkFunction);
          }
      };
  
      return Manager;
  }();
  
  exports.default = Manager;
  module.exports = exports["default"];
  },{"./ApiInstances":8,"./ChainWebSocket":10}],12:[function(require,module,exports){
  "use strict";
  
  exports.__esModule = true;
  
  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  
  var GrapheneApi = function () {
      function GrapheneApi(ws_rpc, api_name) {
          _classCallCheck(this, GrapheneApi);
  
          this.ws_rpc = ws_rpc;
          this.api_name = api_name;
      }
  
      GrapheneApi.prototype.init = function init() {
          var self = this;
          return this.ws_rpc.call([1, this.api_name, []]).then(function (response) {
              //console.log("[GrapheneApi.js:11] ----- GrapheneApi.init ----->", this.api_name, response);
              self.api_id = response;
              return self;
          });
      };
  
      GrapheneApi.prototype.exec = function exec(method, params) {
          return this.ws_rpc.call([this.api_id, method, params]).catch(function (error) {
              console.log("!!! GrapheneApi error: ", method, params, error, JSON.stringify(error));
              throw error;
          });
      };
  
      return GrapheneApi;
  }();
  
  exports.default = GrapheneApi;
  module.exports = exports["default"];
  },{}],13:[function(require,module,exports){
  "use strict";
  
  module.exports = {
      PrivateKey: require("./ecc/src/PrivateKey"),
      PublicKey: require("./ecc/src/PublicKey"),
      Signature: require("./ecc/src/signature"),
      key: require("./ecc/src/KeyUtils"),
      TransactionBuilder: require("./chain/src/TransactionBuilder"),
      Login: require("./chain/src/AccountLogin"),
      bitshares_ws: require("bitsharesjs-ws")
  };
  },{"./chain/src/AccountLogin":14,"./chain/src/TransactionBuilder":17,"./ecc/src/KeyUtils":21,"./ecc/src/PrivateKey":22,"./ecc/src/PublicKey":23,"./ecc/src/signature":30,"bitsharesjs-ws":7}],14:[function(require,module,exports){
  "use strict";
  
  exports.__esModule = true;
  
  var _PrivateKey = require("../../ecc/src/PrivateKey");
  
  var _PrivateKey2 = _interopRequireDefault(_PrivateKey);
  
  var _KeyUtils = require("../../ecc/src/KeyUtils");
  
  var _KeyUtils2 = _interopRequireDefault(_KeyUtils);
  
  var _state = require("./state");
  
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  
  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  
  var _keyCachePriv = {};
  var _keyCachePub = {};
  
  var AccountLogin = function () {
      function AccountLogin() {
          _classCallCheck(this, AccountLogin);
  
          var state = { loggedIn: false, roles: ["active", "owner", "memo"] };
          this.get = (0, _state.get)(state);
          this.set = (0, _state.set)(state);
  
          this.subs = {};
      }
  
      AccountLogin.prototype.addSubscription = function addSubscription(cb) {
          this.subs[cb] = cb;
      };
  
      AccountLogin.prototype.setRoles = function setRoles(roles) {
          this.set("roles", roles);
      };
  
      AccountLogin.prototype.generateKeys = function generateKeys(accountName, password, roles, prefix) {
          var start = new Date().getTime();
          if (!accountName || !password) {
              throw new Error("Account name or password required");
          }
          if (password.length < 12) {
              throw new Error("Password must have at least 12 characters");
          }
  
          var privKeys = {};
          var pubKeys = {};
  
          (roles || this.get("roles")).forEach(function (role) {
              var seed = accountName + role + password;
              var pkey = _keyCachePriv[seed] ? _keyCachePriv[seed] : _PrivateKey2.default.fromSeed(_KeyUtils2.default.normalize_brainKey(seed));
              _keyCachePriv[seed] = pkey;
  
              privKeys[role] = pkey;
              pubKeys[role] = _keyCachePub[seed] ? _keyCachePub[seed] : pkey.toPublicKey().toString(prefix);
  
              _keyCachePub[seed] = pubKeys[role];
          });
  
          return { privKeys: privKeys, pubKeys: pubKeys };
      };
  
      AccountLogin.prototype.checkKeys = function checkKeys(_ref) {
          var _this = this;
  
          var accountName = _ref.accountName,
              password = _ref.password,
              auths = _ref.auths;
  
          if (!accountName || !password || !auths) {
              throw new Error("checkKeys: Missing inputs");
          }
          var hasKey = false;
  
          var _loop = function _loop(role) {
              var _generateKeys = _this.generateKeys(accountName, password, [role]),
                  privKeys = _generateKeys.privKeys,
                  pubKeys = _generateKeys.pubKeys;
  
              auths[role].forEach(function (key) {
                  if (key[0] === pubKeys[role]) {
                      hasKey = true;
                      _this.set(role, { priv: privKeys[role], pub: pubKeys[role] });
                  }
              });
          };
  
          for (var role in auths) {
              _loop(role);
          };
  
          if (hasKey) {
              this.set("name", accountName);
          }
  
          this.set("loggedIn", hasKey);
  
          return hasKey;
      };
  
      AccountLogin.prototype.signTransaction = function signTransaction(tr) {
          var _this2 = this;
  
          var myKeys = {};
          var hasKey = false;
  
          this.get("roles").forEach(function (role) {
              var myKey = _this2.get(role);
              if (myKey) {
                  hasKey = true;
                  console.log("adding signer:", myKey.pub);
                  tr.add_signer(myKey.priv, myKey.pub);
              }
          });
  
          if (!hasKey) {
              throw new Error("You do not have any private keys to sign this transaction");
          }
      };
  
      return AccountLogin;
  }();
  
  var accountLogin = new AccountLogin();
  
  exports.default = accountLogin;
  module.exports = exports["default"];
  },{"../../ecc/src/KeyUtils":21,"../../ecc/src/PrivateKey":22,"./state":18}],15:[function(require,module,exports){
  "use strict";
  
  exports.__esModule = true;
  var ChainTypes = {};
  
  ChainTypes.reserved_spaces = {
      relative_protocol_ids: 0,
      protocol_ids: 1,
      implementation_ids: 2
  };
  
  ChainTypes.object_type = {
      "null": 0,
      base: 1,
      account: 2,
      asset: 3,
      force_settlement: 4,
      committee_member: 5,
      witness: 6,
      limit_order: 7,
      call_order: 8,
      custom: 9,
      proposal: 10,
      operation_history: 11,
      withdraw_permission: 12,
      vesting_balance: 13,
      worker: 14,
      balance: 15
  };
  
  ChainTypes.impl_object_type = {
      global_property: 0,
      dynamic_global_property: 1,
      index_meta: 2,
      asset_dynamic_data: 3,
      asset_bitasset_data: 4,
      account_balance: 5,
      account_statistics: 6,
      transaction: 7,
      block_summary: 8,
      account_transaction_history: 9,
      blinded_balance: 10,
      chain_property: 11,
      witness_schedule: 12,
      budget_record: 13
  };
  
  ChainTypes.vote_type = {
      committee: 0,
      witness: 1,
      worker: 2
  };
  
  ChainTypes.operations = {
      transfer: 0,
      limit_order_create: 1,
      limit_order_cancel: 2,
      call_order_update: 3,
      fill_order: 4,
      account_create: 5,
      account_update: 6,
      account_whitelist: 7,
      account_upgrade: 8,
      account_transfer: 9,
      asset_create: 10,
      asset_update: 11,
      asset_update_bitasset: 12,
      asset_update_feed_producers: 13,
      asset_issue: 14,
      asset_reserve: 15,
      asset_fund_fee_pool: 16,
      asset_settle: 17,
      asset_global_settle: 18,
      asset_publish_feed: 19,
      witness_create: 20,
      witness_update: 21,
      proposal_create: 22,
      proposal_update: 23,
      proposal_delete: 24,
      withdraw_permission_create: 25,
      withdraw_permission_update: 26,
      withdraw_permission_claim: 27,
      withdraw_permission_delete: 28,
      committee_member_create: 29,
      committee_member_update: 30,
      committee_member_update_global_parameters: 31,
      vesting_balance_create: 32,
      vesting_balance_withdraw: 33,
      worker_create: 34,
      custom: 35,
      assert: 36,
      balance_claim: 37,
      override_transfer: 38,
      transfer_to_blind: 39,
      blind_transfer: 40,
      transfer_from_blind: 41,
      asset_settle_cancel: 42,
      asset_claim_fees: 43
  };
  
  exports.default = ChainTypes;
  module.exports = exports["default"];
  },{}],16:[function(require,module,exports){
  'use strict';
  
  exports.__esModule = true;
  
  var _bytebuffer = require('bytebuffer');
  
  var _SerializerValidation = require('../../serializer/src/SerializerValidation');
  
  var _SerializerValidation2 = _interopRequireDefault(_SerializerValidation);
  
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  
  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  
  var DB_MAX_INSTANCE_ID = _bytebuffer.Long.fromNumber(Math.pow(2, 48) - 1);
  
  var ObjectId = function () {
      function ObjectId(space, type, instance) {
          _classCallCheck(this, ObjectId);
  
          this.space = space;
          this.type = type;
          this.instance = instance;
          var instance_string = this.instance.toString();
          var _ObjectId = this.space + '.' + this.type + '.' + instance_string;
          if (!_SerializerValidation2.default.is_digits(instance_string)) {
              throw new ('Invalid object id ' + _ObjectId)();
          }
      }
  
      ObjectId.fromString = function fromString(value) {
          if (value.space !== undefined && value.type !== undefined && value.instance !== undefined) {
              return value;
          }
  
          var params = _SerializerValidation2.default.require_match(/^([0-9]+)\.([0-9]+)\.([0-9]+)$/, _SerializerValidation2.default.required(value, "ObjectId"), "ObjectId");
          return new ObjectId(parseInt(params[1]), parseInt(params[2]), _bytebuffer.Long.fromString(params[3]));
      };
  
      ObjectId.fromLong = function fromLong(long) {
          var space = long.shiftRight(56).toInt();
          var type = long.shiftRight(48).toInt() & 0x00ff;
          var instance = long.and(DB_MAX_INSTANCE_ID);
          return new ObjectId(space, type, instance);
      };
  
      ObjectId.fromByteBuffer = function fromByteBuffer(b) {
          return ObjectId.fromLong(b.readUint64());
      };
  
      ObjectId.prototype.toLong = function toLong() {
          return _bytebuffer.Long.fromNumber(this.space).shiftLeft(56).or(_bytebuffer.Long.fromNumber(this.type).shiftLeft(48).or(this.instance));
      };
  
      ObjectId.prototype.appendByteBuffer = function appendByteBuffer(b) {
          return b.writeUint64(this.toLong());
      };
  
      ObjectId.prototype.toString = function toString() {
          return this.space + '.' + this.type + '.' + this.instance.toString();
      };
  
      return ObjectId;
  }();
  
  exports.default = ObjectId;
  module.exports = exports['default'];
  },{"../../serializer/src/SerializerValidation":33,"bytebuffer":40}],17:[function(require,module,exports){
  (function (Buffer){
  "use strict";
  
  exports.__esModule = true;
  
  var _assert = require("assert");
  
  var _assert2 = _interopRequireDefault(_assert);
  
  var _ecc = require("../../ecc");
  
  var _serializer = require("../../serializer");
  
  var _bitsharesjsWs = require("bitsharesjs-ws");
  
  var _ChainTypes = require("./ChainTypes");
  
  var _ChainTypes2 = _interopRequireDefault(_ChainTypes);
  
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  
  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  
  var head_block_time_string, committee_min_review;
  
  var TransactionBuilder = function () {
      function TransactionBuilder() {
          _classCallCheck(this, TransactionBuilder);
  
          this.ref_block_num = 0;
          this.ref_block_prefix = 0;
          this.expiration = 0;
          this.operations = [];
          this.signatures = [];
          this.signer_private_keys = [];
  
          // semi-private method bindings
          this._broadcast = _broadcast.bind(this);
      }
  
      /**
          @arg {string} name - like "transfer"
          @arg {object} operation - JSON matchching the operation's format
      */
  
  
      TransactionBuilder.prototype.add_type_operation = function add_type_operation(name, operation) {
          this.add_operation(this.get_type_operation(name, operation));
          return;
      };
  
      /**
          This does it all: set fees, finalize, sign, and broadcast (if wanted).
           @arg {ConfidentialWallet} cwallet - must be unlocked, used to gather signing keys
           @arg {array<string>} [signer_pubkeys = null] - Optional ["GPHAbc9Def0...", ...].  These are additional signing keys.  Some balance claims require propritary address formats, the witness node can't tell us which ones are needed so they must be passed in.  If the witness node can figure out a signing key (mostly all other transactions), it should not be passed in here.
           @arg {boolean} [broadcast = false]
      */
  
  
      TransactionBuilder.prototype.process_transaction = function process_transaction(cwallet) {
          var _this = this;
  
          var signer_pubkeys = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
          var broadcast = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
  
  
          var wallet_object = cwallet.wallet.wallet_object;
          if (_bitsharesjsWs.Apis.instance().chain_id !== wallet_object.get("chain_id")) return Promise.reject("Mismatched chain_id; expecting " + wallet_object.get("chain_id") + ", but got " + _bitsharesjsWs.Apis.instance().chain_id);
  
          return this.set_required_fees().then(function () {
              var signer_pubkeys_added = {};
              if (signer_pubkeys) {
  
                  // Balance claims are by address, only the private
                  // key holder can know about these additional
                  // potential keys.
                  var pubkeys = cwallet.getPubkeys_having_PrivateKey(signer_pubkeys);
                  if (!pubkeys.length) throw new Error("Missing signing key");
  
                  for (var _iterator = pubkeys, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {
                      var _ref;
  
                      if (_isArray) {
                          if (_i >= _iterator.length) break;
                          _ref = _iterator[_i++];
                      } else {
                          _i = _iterator.next();
                          if (_i.done) break;
                          _ref = _i.value;
                      }
  
                      var pubkey_string = _ref;
  
                      var private_key = cwallet.getPrivateKey(pubkey_string);
                      _this.add_signer(private_key, pubkey_string);
                      signer_pubkeys_added[pubkey_string] = true;
                  }
              }
  
              return _this.get_potential_signatures().then(function (_ref2) {
                  var pubkeys = _ref2.pubkeys,
                      addys = _ref2.addys;
  
                  var my_pubkeys = cwallet.getPubkeys_having_PrivateKey(pubkeys, addys);
  
                  //{//Testing only, don't send All public keys!
                  //    var pubkeys_all = PrivateKeyStore.getPubkeys() // All public keys
                  //    this.get_required_signatures(pubkeys_all).then( required_pubkey_strings =>
                  //        console.log('get_required_signatures all\t',required_pubkey_strings.sort(), pubkeys_all))
                  //    this.get_required_signatures(my_pubkeys).then( required_pubkey_strings =>
                  //        console.log('get_required_signatures normal\t',required_pubkey_strings.sort(), pubkeys))
                  //}
  
                  return _this.get_required_signatures(my_pubkeys).then(function (required_pubkeys) {
                      for (var _iterator2 = required_pubkeys, _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) {
                          var _ref3;
  
                          if (_isArray2) {
                              if (_i2 >= _iterator2.length) break;
                              _ref3 = _iterator2[_i2++];
                          } else {
                              _i2 = _iterator2.next();
                              if (_i2.done) break;
                              _ref3 = _i2.value;
                          }
  
                          var _pubkey_string = _ref3;
  
                          if (signer_pubkeys_added[_pubkey_string]) continue;
                          var private_key = cwallet.getPrivateKey(_pubkey_string);
                          if (!private_key)
                              // This should not happen, get_required_signatures will only
                              // returned keys from my_pubkeys
                              throw new Error("Missing signing key for " + _pubkey_string);
                          _this.add_signer(private_key, _pubkey_string);
                      }
                  });
              }).then(function () {
                  return broadcast ? _this.broadcast() : _this.serialize();
              });
          });
      };
  
      /** Typically this is called automatically just prior to signing.  Once finalized this transaction can not be changed. */
  
  
      TransactionBuilder.prototype.finalize = function finalize() {
          var _this2 = this;
  
          return new Promise(function (resolve, reject) {
  
              if (_this2.tr_buffer) {
                  throw new Error("already finalized");
              }
  
              resolve(_bitsharesjsWs.Apis.instance().db_api().exec("get_objects", [["2.1.0"]]).then(function (r) {
                  head_block_time_string = r[0].time;
                  if (_this2.expiration === 0) _this2.expiration = base_expiration_sec() + _bitsharesjsWs.ChainConfig.expire_in_secs;
                  _this2.ref_block_num = r[0].head_block_number & 0xFFFF;
                  _this2.ref_block_prefix = new Buffer(r[0].head_block_id, 'hex').readUInt32LE(4);
                  //DEBUG console.log("ref_block",@ref_block_num,@ref_block_prefix,r)
  
                  var iterable = _this2.operations;
                  for (var i = 0, op; i < iterable.length; i++) {
                      op = iterable[i];
                      if (op[1]["finalize"]) {
                          op[1].finalize();
                      }
                  }
                  _this2.tr_buffer = _serializer.ops.transaction.toBuffer(_this2);
              }));
          });
      };
  
      /** @return {string} hex transaction ID */
  
  
      TransactionBuilder.prototype.id = function id() {
          if (!this.tr_buffer) {
              throw new Error("not finalized");
          }
          return _ecc.hash.sha256(this.tr_buffer).toString('hex').substring(0, 40);
      };
  
      /**
          Typically one will use {@link this.add_type_operation} instead.
          @arg {array} operation - [operation_id, operation]
      */
  
  
      TransactionBuilder.prototype.add_operation = function add_operation(operation) {
          if (this.tr_buffer) {
              throw new Error("already finalized");
          }
          (0, _assert2.default)(operation, "operation");
          if (!Array.isArray(operation)) {
              throw new Error("Expecting array [operation_id, operation]");
          }
          this.operations.push(operation);
          return;
      };
  
      TransactionBuilder.prototype.get_type_operation = function get_type_operation(name, operation) {
          if (this.tr_buffer) {
              throw new Error("already finalized");
          }
          (0, _assert2.default)(name, "name");
          (0, _assert2.default)(operation, "operation");
          var _type = _serializer.ops[name];
          (0, _assert2.default)(_type, "Unknown operation " + name);
          var operation_id = _ChainTypes2.default.operations[_type.operation_name];
          if (operation_id === undefined) {
              throw new Error("unknown operation: " + _type.operation_name);
          }
          if (!operation.fee) {
              operation.fee = { amount: 0, asset_id: 0 };
          }
          if (name === 'proposal_create') {
              /*
              * Proposals involving the committee account require a review
              * period to be set, look for them here
              */
              var requiresReview = false,
                  extraReview = 0;
              operation.proposed_ops.forEach(function (op) {
                  var COMMITTE_ACCOUNT = 0;
                  var key = void 0;
  
                  switch (op.op[0]) {
                      case 0:
                          // transfer
                          key = "from";
                          break;
  
                      case 6: //account_update
                      case 17:
                          // asset_settle
                          key = "account";
                          break;
  
                      case 10: // asset_create
                      case 11: // asset_update
                      case 12: // asset_update_bitasset
                      case 13: // asset_update_feed_producers
                      case 14: // asset_issue
                      case 18: // asset_global_settle
                      case 43:
                          // asset_claim_fees
                          key = "issuer";
                          break;
  
                      case 15:
                          // asset_reserve
                          key = "payer";
                          break;
  
                      case 16:
                          // asset_fund_fee_pool
                          key = "from_account";
                          break;
  
                      case 22: // proposal_create
                      case 23: // proposal_update
                      case 24:
                          // proposal_delete
                          key = "fee_paying_account";
                          break;
  
                      case 31:
                          // committee_member_update_global_parameters
                          requiresReview = true;
                          extraReview = 60 * 60 * 24 * 13; // Make the review period 2 weeks total
                          break;
                  }
                  if (key in op.op[1] && op.op[1][key] === COMMITTE_ACCOUNT) {
                      requiresReview = true;
                  }
              });
              operation.expiration_time || (operation.expiration_time = base_expiration_sec() + _bitsharesjsWs.ChainConfig.expire_in_secs_proposal);
              if (requiresReview) {
                  operation.review_period_seconds = extraReview + Math.max(committee_min_review, 24 * 60 * 60 || _bitsharesjsWs.ChainConfig.review_in_secs_committee);
                  /*
                  * Expiration time must be at least equal to
                  * now + review_period_seconds, so we add one hour to make sure
                  */
                  operation.expiration_time += 60 * 60 + extraReview;
              }
          }
          var operation_instance = _type.fromObject(operation);
          return [operation_id, operation_instance];
      };
  
      /* optional: fetch the current head block */
  
      TransactionBuilder.prototype.update_head_block = function update_head_block() {
          return Promise.all([_bitsharesjsWs.Apis.instance().db_api().exec("get_objects", [["2.0.0"]]), _bitsharesjsWs.Apis.instance().db_api().exec("get_objects", [["2.1.0"]])]).then(function (res) {
              var g = res[0],
                  r = res[1];
  
              head_block_time_string = r[0].time;
              committee_min_review = g[0].parameters.committee_proposal_review_period;
          });
      };
  
      /** optional: there is a deafult expiration */
  
  
      TransactionBuilder.prototype.set_expire_seconds = function set_expire_seconds(sec) {
          if (this.tr_buffer) {
              throw new Error("already finalized");
          }
          return this.expiration = base_expiration_sec() + sec;
      };
  
      /* Wraps this transaction in a proposal_create transaction */
  
  
      TransactionBuilder.prototype.propose = function propose(proposal_create_options) {
          if (this.tr_buffer) {
              throw new Error("already finalized");
          }
          if (!this.operations.length) {
              throw new Error("add operation first");
          }
  
          (0, _assert2.default)(proposal_create_options, "proposal_create_options");
          (0, _assert2.default)(proposal_create_options.fee_paying_account, "proposal_create_options.fee_paying_account");
  
          var proposed_ops = this.operations.map(function (op) {
              return { op: op };
          });
  
          this.operations = [];
          this.signatures = [];
          this.signer_private_keys = [];
          proposal_create_options.proposed_ops = proposed_ops;
          this.add_type_operation("proposal_create", proposal_create_options);
          return this;
      };
  
      TransactionBuilder.prototype.has_proposed_operation = function has_proposed_operation() {
          var hasProposed = false;
          for (var i = 0; i < this.operations.length; i++) {
              if ("proposed_ops" in this.operations[i][1]) {
                  hasProposed = true;
                  break;
              }
          }
  
          return hasProposed;
      };
  
      /** optional: the fees can be obtained from the witness node */
  
  
      TransactionBuilder.prototype.set_required_fees = function set_required_fees(asset_id) {
          var _this3 = this;
  
          var fee_pool;
          if (this.tr_buffer) {
              throw new Error("already finalized");
          }
          if (!this.operations.length) {
              throw new Error("add operations first");
          }
          var operations = [];
          for (var i = 0, op; i < this.operations.length; i++) {
              op = this.operations[i];
              operations.push(_serializer.ops.operation.toObject(op));
          }
  
          if (!asset_id) {
              var op1_fee = operations[0][1].fee;
              if (op1_fee && op1_fee.asset_id !== null) {
                  asset_id = op1_fee.asset_id;
              } else {
                  asset_id = "1.3.0";
              }
          }
  
          var promises = [_bitsharesjsWs.Apis.instance().db_api().exec("get_required_fees", [operations, asset_id])];
  
          var feeAssetPromise = null;
          if (asset_id !== "1.3.0") {
              // This handles the fallback to paying fees in BTS if the fee pool is empty.
              promises.push(_bitsharesjsWs.Apis.instance().db_api().exec("get_required_fees", [operations, "1.3.0"]));
              promises.push(_bitsharesjsWs.Apis.instance().db_api().exec("get_objects", [[asset_id]]));
          }
  
          return Promise.all(promises).then(function (results) {
              var fees = results[0],
                  coreFees = results[1],
                  asset = results[2];
  
              asset = asset ? asset[0] : null;
  
              var dynamicPromise = asset_id !== "1.3.0" && asset ? _bitsharesjsWs.Apis.instance().db_api().exec("get_objects", [[asset.dynamic_asset_data_id]]) : new Promise(function (resolve, reject) {
                  resolve();
              });
  
              dynamicPromise.then(function (dynamicObject) {
                  if (asset_id !== "1.3.0") {
                      fee_pool = dynamicObject ? dynamicObject[0].fee_pool : 0;
                      var totalFees = 0;
                      for (var j = 0, fee; j < coreFees.length; j++) {
                          fee = coreFees[j];
                          totalFees += fee.amount;
                      }
  
                      if (totalFees > parseInt(fee_pool, 10)) {
                          fees = coreFees;
                          asset_id = "1.3.0";
                      }
                  }
  
                  // Proposed transactions need to be flattened
                  var flat_assets = [];
                  var flatten = function flatten(obj) {
                      if (Array.isArray(obj)) {
                          for (var k = 0, item; k < obj.length; k++) {
                              item = obj[k];
                              flatten(item);
                          }
                      } else {
                          flat_assets.push(obj);
                      }
                      return;
                  };
                  flatten(fees);
  
                  var asset_index = 0;
  
                  var set_fee = function set_fee(operation) {
                      if (!operation.fee || operation.fee.amount === 0 || operation.fee.amount.toString && operation.fee.amount.toString() === "0" // Long
                      ) {
                              operation.fee = flat_assets[asset_index];
                              // console.log("new operation.fee", operation.fee)
                          } else {
                              // console.log("old operation.fee", operation.fee)
                          }
                      asset_index++;
                      if (operation.proposed_ops) {
                          var result = [];
                          for (var y = 0; y < operation.proposed_ops.length; y++) {
                              result.push(set_fee(operation.proposed_ops[y].op[1]));
                          }return result;
                      }
                  };
                  for (var _i3 = 0; _i3 < _this3.operations.length; _i3++) {
                      set_fee(_this3.operations[_i3][1]);
                  }
              });
              //DEBUG console.log('... get_required_fees',operations,asset_id,flat_assets)
          });
      };
  
      TransactionBuilder.prototype.get_potential_signatures = function get_potential_signatures() {
          var tr_object = _serializer.ops.signed_transaction.toObject(this);
          return Promise.all([_bitsharesjsWs.Apis.instance().db_api().exec("get_potential_signatures", [tr_object]), _bitsharesjsWs.Apis.instance().db_api().exec("get_potential_address_signatures", [tr_object])]).then(function (results) {
              return { pubkeys: results[0], addys: results[1] };
          });
      };
  
      TransactionBuilder.prototype.get_required_signatures = function get_required_signatures(available_keys) {
          if (!available_keys.length) {
              return Promise.resolve([]);
          }
          var tr_object = _serializer.ops.signed_transaction.toObject(this);
          //DEBUG console.log('... tr_object',tr_object)
          return _bitsharesjsWs.Apis.instance().db_api().exec("get_required_signatures", [tr_object, available_keys]).then(function (required_public_keys) {
              //DEBUG console.log('... get_required_signatures',required_public_keys)
              return required_public_keys;
          });
      };
  
      TransactionBuilder.prototype.add_signer = function add_signer(private_key) {
          var public_key = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : private_key.toPublicKey();
  
  
          (0, _assert2.default)(private_key.d, "required PrivateKey object");
  
          if (this.signed) {
              throw new Error("already signed");
          }
          if (!public_key.Q) {
              public_key = _ecc.PublicKey.fromPublicKeyString(public_key);
          }
          // prevent duplicates
          var spHex = private_key.toHex();
          for (var _iterator3 = this.signer_private_keys, _isArray3 = Array.isArray(_iterator3), _i4 = 0, _iterator3 = _isArray3 ? _iterator3 : _iterator3[Symbol.iterator]();;) {
              var _ref4;
  
              if (_isArray3) {
                  if (_i4 >= _iterator3.length) break;
                  _ref4 = _iterator3[_i4++];
              } else {
                  _i4 = _iterator3.next();
                  if (_i4.done) break;
                  _ref4 = _i4.value;
              }
  
              var sp = _ref4;
  
              if (sp[0].toHex() === spHex) return;
          }
          this.signer_private_keys.push([private_key, public_key]);
      };
  
      TransactionBuilder.prototype.sign = function sign() {
          var chain_id = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : _bitsharesjsWs.Apis.instance().chain_id;
  
          if (!this.tr_buffer) {
              throw new Error("not finalized");
          }
          if (this.signed) {
              throw new Error("already signed");
          }
          if (!this.signer_private_keys.length) {
              throw new Error("Transaction was not signed. Do you have a private key? [no_signers]");
          }
          var end = this.signer_private_keys.length;
          for (var i = 0; 0 < end ? i < end : i > end; 0 < end ? i++ : i++) {
              var _signer_private_keys$ = this.signer_private_keys[i],
                  private_key = _signer_private_keys$[0],
                  public_key = _signer_private_keys$[1];
  
              var sig = _ecc.Signature.signBuffer(Buffer.concat([new Buffer(chain_id, 'hex'), this.tr_buffer]), private_key, public_key);
              this.signatures.push(sig.toBuffer());
          }
          this.signer_private_keys = [];
          this.signed = true;
          return;
      };
  
      TransactionBuilder.prototype.serialize = function serialize() {
          return _serializer.ops.signed_transaction.toObject(this);
      };
  
      TransactionBuilder.prototype.toObject = function toObject() {
          return _serializer.ops.signed_transaction.toObject(this);
      };
  
      TransactionBuilder.prototype.broadcast = function broadcast(was_broadcast_callback) {
          var _this4 = this;
  
          if (this.tr_buffer) {
              return this._broadcast(was_broadcast_callback);
          } else {
              return this.finalize().then(function () {
                  return _this4._broadcast(was_broadcast_callback);
              });
          }
      };
  
      return TransactionBuilder;
  }();
  
  var base_expiration_sec = function base_expiration_sec() {
      var head_block_sec = Math.ceil(getHeadBlockDate().getTime() / 1000);
      var now_sec = Math.ceil(Date.now() / 1000);
      // The head block time should be updated every 3 seconds.  If it isn't
      // then help the transaction to expire (use head_block_sec)
      if (now_sec - head_block_sec > 30) {
          return head_block_sec;
      }
      // If the user's clock is very far behind, use the head block time.
      return Math.max(now_sec, head_block_sec);
  };
  
  function _broadcast(was_broadcast_callback) {
      var _this5 = this;
  
      return new Promise(function (resolve, reject) {
  
          if (!_this5.signed) {
              _this5.sign();
          }
          if (!_this5.tr_buffer) {
              throw new Error("not finalized");
          }
          if (!_this5.signatures.length) {
              throw new Error("not signed");
          }
          if (!_this5.operations.length) {
              throw new Error("no operations");
          }
  
          var tr_object = _serializer.ops.signed_transaction.toObject(_this5);
          // console.log('... broadcast_transaction_with_callback !!!')
          _bitsharesjsWs.Apis.instance().network_api().exec("broadcast_transaction_with_callback", [function (res) {
              return resolve(res);
          }, tr_object]).then(function () {
              //console.log('... broadcast success, waiting for callback')
              if (was_broadcast_callback) was_broadcast_callback();
              return;
          }).catch(function (error) {
              // console.log may be redundant for network errors, other errors could occur
              console.log(error);
              var message = error.message;
              if (!message) {
                  message = "";
              }
              reject(new Error(message + "\n" + 'bitshares-crypto ' + ' digest ' + _ecc.hash.sha256(_this5.tr_buffer).toString('hex') + ' transaction ' + _this5.tr_buffer.toString('hex') + ' ' + JSON.stringify(tr_object)));
              return;
          });
          return;
      });
  }
  
  function getHeadBlockDate() {
      return timeStringToDate(head_block_time_string);
  }
  
  function timeStringToDate(time_string) {
      if (!time_string) return new Date("1970-01-01T00:00:00.000Z");
      if (!/Z$/.test(time_string)) //does not end in Z
          // https://github.com/cryptonomex/graphene/issues/368
          time_string = time_string + "Z";
      return new Date(time_string);
  }
  
  exports.default = TransactionBuilder;
  module.exports = exports["default"];
  }).call(this,require("buffer").Buffer)
  },{"../../ecc":19,"../../serializer":31,"./ChainTypes":15,"assert":75,"bitsharesjs-ws":7,"buffer":79}],18:[function(require,module,exports){
  "use strict";
  
  exports.__esModule = true;
  function get(state) {
      return function (key) {
          return state[key] || "";
      };
  }
  
  function set(state) {
      return function (key, value) {
          state[key] = value;
          return this;
      };
  }
  
  exports.get = get;
  exports.set = set;
  },{}],19:[function(require,module,exports){
  "use strict";
  
  exports.__esModule = true;
  exports.key = exports.hash = exports.brainKey = exports.Signature = exports.PublicKey = exports.PrivateKey = exports.Aes = exports.Address = undefined;
  
  var _address = require("./src/address");
  
  var _address2 = _interopRequireDefault(_address);
  
  var _aes = require("./src/aes");
  
  var _aes2 = _interopRequireDefault(_aes);
  
  var _PrivateKey = require("./src/PrivateKey");
  
  var _PrivateKey2 = _interopRequireDefault(_PrivateKey);
  
  var _PublicKey = require("./src/PublicKey");
  
  var _PublicKey2 = _interopRequireDefault(_PublicKey);
  
  var _signature = require("./src/signature");
  
  var _signature2 = _interopRequireDefault(_signature);
  
  var _BrainKey = require("./src/BrainKey");
  
  var _BrainKey2 = _interopRequireDefault(_BrainKey);
  
  var _hash = require("./src/hash");
  
  var hash = _interopRequireWildcard(_hash);
  
  var _KeyUtils = require("./src/KeyUtils");
  
  var _KeyUtils2 = _interopRequireDefault(_KeyUtils);
  
  function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
  
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  
  exports.Address = _address2.default;
  exports.Aes = _aes2.default;
  exports.PrivateKey = _PrivateKey2.default;
  exports.PublicKey = _PublicKey2.default;
  exports.Signature = _signature2.default;
  exports.brainKey = _BrainKey2.default;
  exports.hash = hash;
  exports.key = _KeyUtils2.default;
  },{"./src/BrainKey":20,"./src/KeyUtils":21,"./src/PrivateKey":22,"./src/PublicKey":23,"./src/address":24,"./src/aes":25,"./src/hash":29,"./src/signature":30}],20:[function(require,module,exports){
  'use strict';
  
  exports.__esModule = true;
  exports.default = normalize;
  function normalize(brainKey) {
      if (typeof brainKey !== 'string') {
          throw new Error("string required for brainKey");
      }
      brainKey = brainKey.trim();
      return brainKey.split(/[\t\n\v\f\r ]+/).join(' ');
  }
  module.exports = exports['default'];
  },{}],21:[function(require,module,exports){
  (function (Buffer){
  'use strict';
  
  exports.__esModule = true;
  
  var _PrivateKey = require('./PrivateKey');
  
  var _PrivateKey2 = _interopRequireDefault(_PrivateKey);
  
  var _PublicKey = require('./PublicKey');
  
  var _PublicKey2 = _interopRequireDefault(_PublicKey);
  
  var _address = require('./address');
  
  var _address2 = _interopRequireDefault(_address);
  
  var _aes = require('./aes');
  
  var _aes2 = _interopRequireDefault(_aes);
  
  var _hash = require('./hash');
  
  var _secureRandom = require('secure-random');
  
  var _secureRandom2 = _interopRequireDefault(_secureRandom);
  
  var _bitsharesjsWs = require('bitsharesjs-ws');
  
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  
  // hash for .25 second
  
  // import dictionary from './dictionary_en';
  var HASH_POWER_MILLS = 250;
  
  var key = {
  
      /** Uses 1 second of hashing power to create a key/password checksum.  An
      implementation can re-call this method with the same password to re-match
      the strength of the CPU (either after moving from a desktop to a mobile,
      mobile to desktop, or N years from now when CPUs are presumably stronger).
       A salt is used for all the normal reasons...
       @return object {
          aes_private: Aes,
          checksum: "{hash_iteration_count},{salt},{checksum}"
      }
      */
      aes_checksum: function aes_checksum(password) {
          if (!(typeof password === "string")) {
              throw new "password string required"();
          }
          var salt = _secureRandom2.default.randomBuffer(4).toString('hex');
          var iterations = 0;
          var secret = salt + password;
          // hash for .1 second
          var start_t = Date.now();
          while (Date.now() - start_t < HASH_POWER_MILLS) {
              secret = (0, _hash.sha256)(secret);
              iterations += 1;
          }
  
          var checksum = (0, _hash.sha256)(secret);
          var checksum_string = [iterations, salt.toString('hex'), checksum.slice(0, 4).toString('hex')].join(',');
  
          return { aes_private: _aes2.default.fromSeed(secret),
              checksum: checksum_string
          };
      },
  
  
      /** Provide a matching password and key_checksum.  A "wrong password"
      error is thrown if the password does not match.  If this method takes
      much more or less than 1 second to return, one should consider updating
      all encyrpted fields using a new key.key_checksum.
      */
      aes_private: function aes_private(password, key_checksum) {
          var _key_checksum$split = key_checksum.split(','),
              iterations = _key_checksum$split[0],
              salt = _key_checksum$split[1],
              checksum = _key_checksum$split[2];
  
          var secret = salt + password;
          for (var i = 0; 0 < iterations ? i < iterations : i > iterations; 0 < iterations ? i++ : i++) {
              secret = (0, _hash.sha256)(secret);
          }
          var new_checksum = (0, _hash.sha256)(secret);
          if (!(new_checksum.slice(0, 4).toString('hex') === checksum)) {
              throw new Error("wrong password");
          }
          return _aes2.default.fromSeed(secret);
      },
  
  
      /**
          A week random number generator can run out of entropy.  This should ensure even the worst random number implementation will be reasonably safe.
           @param1 string entropy of at least 32 bytes
      */
      random32ByteBuffer: function random32ByteBuffer() {
          var entropy = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.browserEntropy();
  
  
          if (!(typeof entropy === 'string')) {
              throw new Error("string required for entropy");
          }
  
          if (entropy.length < 32) {
              throw new Error("expecting at least 32 bytes of entropy");
          }
  
          var start_t = Date.now();
  
          while (Date.now() - start_t < HASH_POWER_MILLS) {
              entropy = (0, _hash.sha256)(entropy);
          }var hash_array = [];
          hash_array.push(entropy);
  
          // Hashing for 1 second may helps the computer is not low on entropy (this method may be called back-to-back).
          hash_array.push(_secureRandom2.default.randomBuffer(32));
  
          return (0, _hash.sha256)(Buffer.concat(hash_array));
      },
  
  
      suggest_brain_key: function suggest_brain_key() {
          var dictionary = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ",";
          var entropy = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.browserEntropy();
  
  
          var randomBuffer = this.random32ByteBuffer(entropy);
  
          var word_count = 16;
          var dictionary_lines = dictionary.split(',');
  
          if (!(dictionary_lines.length === 49744)) {
              throw new Error('expecting ' + 49744 + ' but got ' + dictionary_lines.length + ' dictionary words');
          }
  
          var brainkey = [];
          var end = word_count * 2;
  
          for (var i = 0; i < end; i += 2) {
  
              // randomBuffer has 256 bits / 16 bits per word == 16 words
              var num = (randomBuffer[i] << 8) + randomBuffer[i + 1];
  
              // convert into a number between 0 and 1 (inclusive)
              var rndMultiplier = num / Math.pow(2, 16);
              var wordIndex = Math.round(dictionary_lines.length * rndMultiplier);
  
              brainkey.push(dictionary_lines[wordIndex]);
          }
          return this.normalize_brainKey(brainkey.join(' '));
      },
  
      get_random_key: function get_random_key(entropy) {
          return _PrivateKey2.default.fromBuffer(this.random32ByteBuffer(entropy));
      },
      get_brainPrivateKey: function get_brainPrivateKey(brainKey) {
          var sequence = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
  
          if (sequence < 0) {
              throw new Error("invalid sequence");
          }
          brainKey = key.normalize_brainKey(brainKey);
          return _PrivateKey2.default.fromBuffer((0, _hash.sha256)((0, _hash.sha512)(brainKey + " " + sequence)));
      },
  
  
      // Turn invisible space like characters into a single space
      normalize_brainKey: function normalize_brainKey(brainKey) {
          if (!(typeof brainKey === 'string')) {
              throw new Error("string required for brainKey");
          }
  
          brainKey = brainKey.trim();
          return brainKey.split(/[\t\n\v\f\r ]+/).join(' ');
      },
      browserEntropy: function browserEntropy() {
  
          var entropyStr = "";
          try {
              entropyStr = new Date().toString() + " " + window.screen.height + " " + window.screen.width + " " + window.screen.colorDepth + " " + " " + window.screen.availHeight + " " + window.screen.availWidth + " " + window.screen.pixelDepth + navigator.language + " " + window.location + " " + window.history.length;
  
              for (var i = 0, mimeType; i < navigator.mimeTypes.length; i++) {
                  mimeType = navigator.mimeTypes[i];
                  entropyStr += mimeType.description + " " + mimeType.type + " " + mimeType.suffixes + " ";
              }
              console.log("INFO\tbrowserEntropy gathered");
          } catch (error) {
              //nodejs:ReferenceError: window is not defined
              entropyStr = (0, _hash.sha256)(new Date().toString());
          }
  
          var b = new Buffer(entropyStr);
          entropyStr += b.toString('binary') + " " + new Date().toString();
          return entropyStr;
      },
  
  
      // @return array of 5 legacy addresses for a pubkey string parameter.
      addresses: function addresses(pubkey) {
          var address_prefix = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : _bitsharesjsWs.ChainConfig.address_prefix;
  
          var public_key = _PublicKey2.default.fromPublicKeyString(pubkey, address_prefix);
          // S L O W
          var address_string = [_address2.default.fromPublic(public_key, false, 0).toString(address_prefix), // btc_uncompressed
          _address2.default.fromPublic(public_key, true, 0).toString(address_prefix), // btc_compressed
          _address2.default.fromPublic(public_key, false, 56).toString(address_prefix), // pts_uncompressed
          _address2.default.fromPublic(public_key, true, 56).toString(address_prefix), // pts_compressed
          public_key.toAddressString(address_prefix) // bts_short, most recent format
          ];
          return address_string;
      }
  };
  
  exports.default = key;
  module.exports = exports['default'];
  }).call(this,require("buffer").Buffer)
  },{"./PrivateKey":22,"./PublicKey":23,"./address":24,"./aes":25,"./hash":29,"bitsharesjs-ws":7,"buffer":79,"secure-random":66}],22:[function(require,module,exports){
  (function (Buffer){
  'use strict';
  
  exports.__esModule = true;
  
  var _ecurve = require('ecurve');
  
  var _ecurve2 = _interopRequireDefault(_ecurve);
  
  var _bigi = require('bigi');
  
  var _bigi2 = _interopRequireDefault(_bigi);
  
  var _bs = require('bs58');
  
  var _hash = require('./hash');
  
  var _PublicKey = require('./PublicKey');
  
  var _PublicKey2 = _interopRequireDefault(_PublicKey);
  
  var _deepEqual = require('deep-equal');
  
  var _deepEqual2 = _interopRequireDefault(_deepEqual);
  
  var _assert = require('assert');
  
  var _assert2 = _interopRequireDefault(_assert);
  
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  
  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  
  var secp256k1 = (0, _ecurve.getCurveByName)('secp256k1');
  var G = secp256k1.G,
      n = secp256k1.n;
  
  var PrivateKey = function () {
  
      /**
          @private see static functions
          @param {BigInteger}
      */
      function PrivateKey(d) {
          _classCallCheck(this, PrivateKey);
  
          this.d = d;
      }
  
      PrivateKey.fromBuffer = function fromBuffer(buf) {
          if (!Buffer.isBuffer(buf)) {
              throw new Error("Expecting paramter to be a Buffer type");
          }
          if (32 !== buf.length) {
              console.log('WARN: Expecting 32 bytes, instead got ' + buf.length + ', stack trace:', new Error().stack);
          }
          if (buf.length === 0) {
              throw new Error("Empty buffer");
          }
          return new PrivateKey(_bigi2.default.fromBuffer(buf));
      };
  
      /** @arg {string} seed - any length string.  This is private, the same seed produces the same private key every time.  */
  
  
      PrivateKey.fromSeed = function fromSeed(seed) {
          // generate_private_key
          if (!(typeof seed === 'string')) {
              throw new Error('seed must be of type string');
          }
          return PrivateKey.fromBuffer((0, _hash.sha256)(seed));
      };
  
      /** @return {string} Wallet Import Format (still a secret, Not encrypted) */
  
  
      PrivateKey.fromWif = function fromWif(_private_wif) {
          var private_wif = new Buffer((0, _bs.decode)(_private_wif));
          var version = private_wif.readUInt8(0);
          _assert2.default.equal(0x80, version, 'Expected version ' + 0x80 + ', instead got ' + version);
          // checksum includes the version
          var private_key = private_wif.slice(0, -4);
          var checksum = private_wif.slice(-4);
          var new_checksum = (0, _hash.sha256)(private_key);
          new_checksum = (0, _hash.sha256)(new_checksum);
          new_checksum = new_checksum.slice(0, 4);
          var isEqual = (0, _deepEqual2.default)(checksum, new_checksum); //, 'Invalid checksum'
          if (!isEqual) {
              throw new Error("Checksum did not match");
          }
          private_key = private_key.slice(1);
          return PrivateKey.fromBuffer(private_key);
      };
  
      PrivateKey.prototype.toWif = function toWif() {
          var private_key = this.toBuffer();
          // checksum includes the version
          private_key = Buffer.concat([new Buffer([0x80]), private_key]);
          var checksum = (0, _hash.sha256)(private_key);
          checksum = (0, _hash.sha256)(checksum);
          checksum = checksum.slice(0, 4);
          var private_wif = Buffer.concat([private_key, checksum]);
          return (0, _bs.encode)(private_wif);
      };
  
      /**
          @return {Point}
      */
  
  
      PrivateKey.prototype.toPublicKeyPoint = function toPublicKeyPoint() {
          var Q;
          return Q = secp256k1.G.multiply(this.d);
      };
  
      PrivateKey.prototype.toPublicKey = function toPublicKey() {
          if (this.public_key) {
              return this.public_key;
          }
          return this.public_key = _PublicKey2.default.fromPoint(this.toPublicKeyPoint());
      };
  
      PrivateKey.prototype.toBuffer = function toBuffer() {
          return this.d.toBuffer(32);
      };
  
      /** ECIES */
  
  
      PrivateKey.prototype.get_shared_secret = function get_shared_secret(public_key) {
          var legacy = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
  
          public_key = toPublic(public_key);
          var KB = public_key.toUncompressed().toBuffer();
          var KBP = _ecurve.Point.fromAffine(secp256k1, _bigi2.default.fromBuffer(KB.slice(1, 33)), // x
          _bigi2.default.fromBuffer(KB.slice(33, 65)) // y
          );
          var r = this.toBuffer();
          var P = KBP.multiply(_bigi2.default.fromBuffer(r));
          var S = P.affineX.toBuffer({ size: 32 });
          /*
          the input to sha512 must be exactly 32-bytes, to match the c++ implementation
          of get_shared_secret.  Right now S will be shorter if the most significant
          byte(s) is zero.  Pad it back to the full 32-bytes
          */
          if (!legacy && S.length < 32) {
              var pad = new Buffer(32 - S.length).fill(0);
              S = Buffer.concat([pad, S]);
          }
  
          // SHA512 used in ECIES
          return (0, _hash.sha512)(S);
      };
  
      // /** ECIES (does not always match the Point.fromAffine version above) */
      // get_shared_secret(public_key){
      //     public_key = toPublic(public_key)
      //     var P = public_key.Q.multiply( this.d );
      //     var S = P.affineX.toBuffer({size: 32});
      //     // ECIES, adds an extra sha512
      //     return sha512(S);
      // }
  
      /** @throws {Error} - overflow of the key could not be derived */
  
  
      PrivateKey.prototype.child = function child(offset) {
          offset = Buffer.concat([this.toPublicKey().toBuffer(), offset]);
          offset = (0, _hash.sha256)(offset);
          var c = _bigi2.default.fromBuffer(offset);
  
          if (c.compareTo(n) >= 0) throw new Error("Child offset went out of bounds, try again");
  
          var derived = this.d.add(c); //.mod(n)
  
          if (derived.signum() === 0) throw new Error("Child offset derived to an invalid key, try again");
  
          return new PrivateKey(derived);
      };
  
      /* <helper_functions> */
  
      PrivateKey.prototype.toByteBuffer = function toByteBuffer() {
          var b = new ByteBuffer(ByteBuffer.DEFAULT_CAPACITY, ByteBuffer.LITTLE_ENDIAN);
          this.appendByteBuffer(b);
          return b.copy(0, b.offset);
      };
  
      PrivateKey.fromHex = function fromHex(hex) {
          return PrivateKey.fromBuffer(new Buffer(hex, 'hex'));
      };
  
      PrivateKey.prototype.toHex = function toHex() {
          return this.toBuffer().toString('hex');
      };
  
      /* </helper_functions> */
  
  
      return PrivateKey;
  }();
  
  exports.default = PrivateKey;
  
  
  var toPublic = function toPublic(data) {
      return data == null ? data : data.Q ? data : _PublicKey2.default.fromStringOrThrow(data);
  };
  module.exports = exports['default'];
  }).call(this,require("buffer").Buffer)
  },{"./PublicKey":23,"./hash":29,"assert":75,"bigi":5,"bs58":39,"buffer":79,"deep-equal":55,"ecurve":60}],23:[function(require,module,exports){
  (function (Buffer){
  'use strict';
  
  exports.__esModule = true;
  
  var _bigi = require('bigi');
  
  var _bigi2 = _interopRequireDefault(_bigi);
  
  var _ecurve = require('ecurve');
  
  var _bs = require('bs58');
  
  var _hash = require('./hash');
  
  var _bitsharesjsWs = require('bitsharesjs-ws');
  
  var _assert = require('assert');
  
  var _assert2 = _interopRequireDefault(_assert);
  
  var _deepEqual = require('deep-equal');
  
  var _deepEqual2 = _interopRequireDefault(_deepEqual);
  
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  
  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  
  var secp256k1 = (0, _ecurve.getCurveByName)('secp256k1');
  var G = secp256k1.G,
      n = secp256k1.n;
  
  var PublicKey = function () {
  
      /** @param {Point} public key */
      function PublicKey(Q) {
          _classCallCheck(this, PublicKey);
  
          this.Q = Q;
      }
  
      PublicKey.fromBinary = function fromBinary(bin) {
          return PublicKey.fromBuffer(new Buffer(bin, 'binary'));
      };
  
      PublicKey.fromBuffer = function fromBuffer(buffer) {
          if (buffer.toString('hex') === '000000000000000000000000000000000000000000000000000000000000000000') return new PublicKey(null);
          return new PublicKey(_ecurve.Point.decodeFrom(secp256k1, buffer));
      };
  
      PublicKey.prototype.toBuffer = function toBuffer() {
          var compressed = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.Q ? this.Q.compressed : null;
  
          if (this.Q === null) return new Buffer('000000000000000000000000000000000000000000000000000000000000000000', 'hex');
          return this.Q.getEncoded(compressed);
      };
  
      PublicKey.fromPoint = function fromPoint(point) {
          return new PublicKey(point);
      };
  
      PublicKey.prototype.toUncompressed = function toUncompressed() {
          var buf = this.Q.getEncoded(false);
          var point = _ecurve.Point.decodeFrom(secp256k1, buf);
          return PublicKey.fromPoint(point);
      };
  
      /** bts::blockchain::address (unique but not a full public key) */
  
  
      PublicKey.prototype.toBlockchainAddress = function toBlockchainAddress() {
          var pub_buf = this.toBuffer();
          var pub_sha = (0, _hash.sha512)(pub_buf);
          return (0, _hash.ripemd160)(pub_sha);
      };
  
      /** Alias for {@link toPublicKeyString} */
  
  
      PublicKey.prototype.toString = function toString() {
          var address_prefix = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : _bitsharesjsWs.ChainConfig.address_prefix;
  
          return this.toPublicKeyString(address_prefix);
      };
  
      /**
          Full public key
          {return} string
      */
  
  
      PublicKey.prototype.toPublicKeyString = function toPublicKeyString() {
          var address_prefix = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : _bitsharesjsWs.ChainConfig.address_prefix;
  
          var pub_buf = this.toBuffer();
          var checksum = (0, _hash.ripemd160)(pub_buf);
          var addy = Buffer.concat([pub_buf, checksum.slice(0, 4)]);
          return address_prefix + (0, _bs.encode)(addy);
      };
  
      /**
          @arg {string} public_key - like GPHXyz...
          @arg {string} address_prefix - like GPH
          @return PublicKey or `null` (if the public_key string is invalid)
      */
  
  
      PublicKey.fromPublicKeyString = function fromPublicKeyString(public_key) {
          var address_prefix = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : _bitsharesjsWs.ChainConfig.address_prefix;
  
          try {
              return PublicKey.fromStringOrThrow(public_key, address_prefix);
          } catch (e) {
              return null;
          }
      };
  
      /**
          @arg {string} public_key - like GPHXyz...
          @arg {string} address_prefix - like GPH
          @throws {Error} if public key is invalid
          @return PublicKey
      */
  
  
      PublicKey.fromStringOrThrow = function fromStringOrThrow(public_key) {
          var address_prefix = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : _bitsharesjsWs.ChainConfig.address_prefix;
  
          var prefix = public_key.slice(0, address_prefix.length);
          _assert2.default.equal(address_prefix, prefix, 'Expecting key to begin with ' + address_prefix + ', instead got ' + prefix);
          public_key = public_key.slice(address_prefix.length);
  
          public_key = new Buffer((0, _bs.decode)(public_key), 'binary');
          var checksum = public_key.slice(-4);
          public_key = public_key.slice(0, -4);
          var new_checksum = (0, _hash.ripemd160)(public_key);
          new_checksum = new_checksum.slice(0, 4);
          var isEqual = (0, _deepEqual2.default)(checksum, new_checksum); //, 'Invalid checksum'
          if (!isEqual) {
              throw new Error("Checksum did not match");
          }
          return PublicKey.fromBuffer(public_key);
      };
  
      PublicKey.prototype.toAddressString = function toAddressString() {
          var address_prefix = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : _bitsharesjsWs.ChainConfig.address_prefix;
  
          var pub_buf = this.toBuffer();
          var pub_sha = (0, _hash.sha512)(pub_buf);
          var addy = (0, _hash.ripemd160)(pub_sha);
          var checksum = (0, _hash.ripemd160)(addy);
          addy = Buffer.concat([addy, checksum.slice(0, 4)]);
          return address_prefix + (0, _bs.encode)(addy);
      };
  
      PublicKey.prototype.toPtsAddy = function toPtsAddy() {
          var pub_buf = this.toBuffer();
          var pub_sha = (0, _hash.sha256)(pub_buf);
          var addy = (0, _hash.ripemd160)(pub_sha);
          addy = Buffer.concat([new Buffer([0x38]), addy]); //version 56(decimal)
  
          var checksum = (0, _hash.sha256)(addy);
          checksum = (0, _hash.sha256)(checksum);
  
          addy = Buffer.concat([addy, checksum.slice(0, 4)]);
          return (0, _bs.encode)(addy);
      };
  
      PublicKey.prototype.child = function child(offset) {
  
          (0, _assert2.default)(Buffer.isBuffer(offset), "Buffer required: offset");
          _assert2.default.equal(offset.length, 32, "offset length");
  
          offset = Buffer.concat([this.toBuffer(), offset]);
          offset = (0, _hash.sha256)(offset);
  
          var c = _bigi2.default.fromBuffer(offset);
  
          if (c.compareTo(n) >= 0) throw new Error("Child offset went out of bounds, try again");
  
          var cG = G.multiply(c);
          var Qprime = this.Q.add(cG);
  
          if (secp256k1.isInfinity(Qprime)) throw new Error("Child offset derived to an invalid key, try again");
  
          return PublicKey.fromPoint(Qprime);
      };
  
      /* <HEX> */
  
      PublicKey.prototype.toByteBuffer = function toByteBuffer() {
          var b = new ByteBuffer(ByteBuffer.DEFAULT_CAPACITY, ByteBuffer.LITTLE_ENDIAN);
          this.appendByteBuffer(b);
          return b.copy(0, b.offset);
      };
  
      PublicKey.fromHex = function fromHex(hex) {
          return PublicKey.fromBuffer(new Buffer(hex, 'hex'));
      };
  
      PublicKey.prototype.toHex = function toHex() {
          return this.toBuffer().toString('hex');
      };
  
      PublicKey.fromPublicKeyStringHex = function fromPublicKeyStringHex(hex) {
          return PublicKey.fromPublicKeyString(new Buffer(hex, 'hex'));
      };
  
      /* </HEX> */
  
  
      return PublicKey;
  }();
  
  exports.default = PublicKey;
  module.exports = exports['default'];
  }).call(this,require("buffer").Buffer)
  },{"./hash":29,"assert":75,"bigi":5,"bitsharesjs-ws":7,"bs58":39,"buffer":79,"deep-equal":55,"ecurve":60}],24:[function(require,module,exports){
  (function (Buffer){
  'use strict';
  
  exports.__esModule = true;
  
  var _assert = require('assert');
  
  var _assert2 = _interopRequireDefault(_assert);
  
  var _bitsharesjsWs = require('bitsharesjs-ws');
  
  var _hash2 = require('./hash');
  
  var _bs = require('bs58');
  
  var _deepEqual = require('deep-equal');
  
  var _deepEqual2 = _interopRequireDefault(_deepEqual);
  
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  
  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  
  /** Addresses are shortened non-reversable hashes of a public key.  The full PublicKey is preferred.
      @deprecated
  */
  var Address = function () {
      function Address(addy) {
          _classCallCheck(this, Address);
  
          this.addy = addy;
      }
  
      Address.fromBuffer = function fromBuffer(buffer) {
          var _hash = (0, _hash2.sha512)(buffer);
          var addy = (0, _hash2.ripemd160)(_hash);
          return new Address(addy);
      };
  
      Address.fromString = function fromString(string) {
          var address_prefix = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : _bitsharesjsWs.ChainConfig.address_prefix;
  
          var prefix = string.slice(0, address_prefix.length);
          _assert2.default.equal(address_prefix, prefix, 'Expecting key to begin with ' + address_prefix + ', instead got ' + prefix);
          var addy = string.slice(address_prefix.length);
          addy = new Buffer((0, _bs.decode)(addy), 'binary');
          var checksum = addy.slice(-4);
          addy = addy.slice(0, -4);
          var new_checksum = (0, _hash2.ripemd160)(addy);
          new_checksum = new_checksum.slice(0, 4);
          var isEqual = (0, _deepEqual2.default)(checksum, new_checksum); //, 'Invalid checksum'
          if (!isEqual) {
              throw new Error("Checksum did not match");
          }
          return new Address(addy);
      };
  
      /** @return Address - Compressed PTS format (by default) */
      Address.fromPublic = function fromPublic(public_key) {
          var compressed = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
          var version = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 56;
  
          var sha2 = (0, _hash2.sha256)(public_key.toBuffer(compressed));
          var rep = (0, _hash2.ripemd160)(sha2);
          var versionBuffer = new Buffer(1);
          versionBuffer.writeUInt8(0xFF & version, 0);
          var addr = Buffer.concat([versionBuffer, rep]);
          var check = (0, _hash2.sha256)(addr);
          check = (0, _hash2.sha256)(check);
          var buffer = Buffer.concat([addr, check.slice(0, 4)]);
          return new Address((0, _hash2.ripemd160)(buffer));
      };
  
      Address.prototype.toBuffer = function toBuffer() {
          return this.addy;
      };
  
      Address.prototype.toString = function toString() {
          var address_prefix = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : _bitsharesjsWs.ChainConfig.address_prefix;
  
          var checksum = (0, _hash2.ripemd160)(this.addy);
          var addy = Buffer.concat([this.addy, checksum.slice(0, 4)]);
          return address_prefix + (0, _bs.encode)(addy);
      };
  
      return Address;
  }();
  
  exports.default = Address;
  module.exports = exports['default'];
  }).call(this,require("buffer").Buffer)
  },{"./hash":29,"assert":75,"bitsharesjs-ws":7,"bs58":39,"buffer":79,"deep-equal":55}],25:[function(require,module,exports){
  (function (Buffer){
  "use strict";
  
  exports.__esModule = true;
  
  var _aes = require("crypto-js/aes");
  
  var _aes2 = _interopRequireDefault(_aes);
  
  var _encHex = require("crypto-js/enc-hex");
  
  var _encHex2 = _interopRequireDefault(_encHex);
  
  var _encBase = require("crypto-js/enc-base64");
  
  var _encBase2 = _interopRequireDefault(_encBase);
  
  var _assert = require("assert");
  
  var _assert2 = _interopRequireDefault(_assert);
  
  var _bytebuffer = require("bytebuffer");
  
  var _hash2 = require("./hash");
  
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  
  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } // https://code.google.com/p/crypto-js
  
  
  /** Provides symetric encrypt and decrypt via AES. */
  var Aes = function () {
  
      /** @private */
      function Aes(iv, key) {
          _classCallCheck(this, Aes);
  
          this.iv = iv, this.key = key;
      }
  
      /** This is an excellent way to ensure that all references to Aes can not operate anymore (example: a wallet becomes locked).  An application should ensure there is only one Aes object instance for a given secret `seed`. */
  
  
      Aes.prototype.clear = function clear() {
          return this.iv = this.key = undefined;
      };
  
      /** @arg {string} seed - secret seed may be used to encrypt or decrypt. */
  
  
      Aes.fromSeed = function fromSeed(seed) {
          if (seed === undefined) {
              throw new Error("seed is required");
          }
          var _hash = (0, _hash2.sha512)(seed);
          _hash = _hash.toString('hex');
          // DEBUG console.log('... fromSeed _hash',_hash)
          return Aes.fromSha512(_hash);
      };
  
      /** @arg {string} hash - A 128 byte hex string, typically one would call {@link fromSeed} instead. */
      Aes.fromSha512 = function fromSha512(hash) {
          _assert2.default.equal(hash.length, 128, "A Sha512 in HEX should be 128 characters long, instead got " + hash.length);
          var iv = _encHex2.default.parse(hash.substring(64, 96));
          var key = _encHex2.default.parse(hash.substring(0, 64));
          return new Aes(iv, key);
      };
  
      Aes.fromBuffer = function fromBuffer(buf) {
          (0, _assert2.default)(Buffer.isBuffer(buf), "Expecting Buffer");
          _assert2.default.equal(buf.length, 64, "A Sha512 Buffer should be 64 characters long, instead got " + buf.length);
          return Aes.fromSha512(buf.toString("hex"));
      };
      /**
          @throws {Error} - "Invalid Key, ..."
          @arg {PrivateKey} private_key - required and used for decryption
          @arg {PublicKey} public_key - required and used to calcualte the shared secret
          @arg {string} [nonce = ""] optional but should always be provided and be unique when re-using the same private/public keys more than once.  This nonce is not a secret.
          @arg {string|Buffer} message - Encrypted message containing a checksum
          @return {Buffer}
      */
  
  
      Aes.decrypt_with_checksum = function decrypt_with_checksum(private_key, public_key, nonce, message) {
          var legacy = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false;
  
  
          // Warning: Do not put `nonce = ""` in the arguments, in es6 this will not convert "null" into an emtpy string
          if (nonce == null) // null or undefined
              nonce = "";
  
          if (!Buffer.isBuffer(message)) {
              message = new Buffer(message, 'hex');
          }
  
          var S = private_key.get_shared_secret(public_key, legacy);
          // D E B U G
          // console.log('decrypt_with_checksum', {
          //     priv_to_pub: private_key.toPublicKey().toString(),
          //     pub: public_key.toPublicKeyString(),
          //     nonce: nonce,
          //     message: message.length,
          //     S: S.toString('hex')
          // })
  
          var aes = Aes.fromSeed(Buffer.concat([
          // A null or empty string nonce will not effect the hash
          new Buffer("" + nonce), new Buffer(S.toString('hex'))]));
  
          var planebuffer = aes.decrypt(message);
          if (!(planebuffer.length >= 4)) {
              throw new Error("Invalid key, could not decrypt message(1)");
          }
  
          // DEBUG console.log('... planebuffer',planebuffer)
          var checksum = planebuffer.slice(0, 4);
          var plaintext = planebuffer.slice(4);
  
          // console.log('... checksum',checksum.toString('hex'))
          // console.log('... plaintext',plaintext.toString())
  
          var new_checksum = (0, _hash2.sha256)(plaintext);
          new_checksum = new_checksum.slice(0, 4);
          new_checksum = new_checksum.toString('hex');
  
          if (!(checksum.toString('hex') === new_checksum)) {
              throw new Error("Invalid key, could not decrypt message(2)");
          }
  
          return plaintext;
      };
  
      /** Identical to {@link decrypt_with_checksum} but used to encrypt.  Should not throw an error.
          @return {Buffer} message - Encrypted message which includes a checksum
      */
      Aes.encrypt_with_checksum = function encrypt_with_checksum(private_key, public_key, nonce, message) {
  
          // Warning: Do not put `nonce = ""` in the arguments, in es6 this will not convert "null" into an emtpy string
  
          if (nonce == null) // null or undefined
              nonce = "";
  
          if (!Buffer.isBuffer(message)) {
              message = new Buffer(message, 'binary');
          }
  
          var S = private_key.get_shared_secret(public_key);
  
          // D E B U G
          // console.log('encrypt_with_checksum', {
          //     priv_to_pub: private_key.toPublicKey().toString()
          //     pub: public_key.toPublicKeyString()
          //     nonce: nonce
          //     message: message.length
          //     S: S.toString('hex')
          // })
  
          var aes = Aes.fromSeed(Buffer.concat([
          // A null or empty string nonce will not effect the hash
          new Buffer("" + nonce), new Buffer(S.toString('hex'))]));
          // DEBUG console.log('... S',S.toString('hex'))
          var checksum = (0, _hash2.sha256)(message).slice(0, 4);
          var payload = Buffer.concat([checksum, message]);
          // DEBUG console.log('... payload',payload.toString())
          return aes.encrypt(payload);
      };
  
      /** @private */
      Aes.prototype._decrypt_word_array = function _decrypt_word_array(cipher) {
          // https://code.google.com/p/crypto-js/#Custom_Key_and_IV
          // see wallet_records.cpp master_key::decrypt_key
          return _aes2.default.decrypt({ ciphertext: cipher, salt: null }, this.key, { iv: this.iv });
      };
  
      /** @private */
  
  
      Aes.prototype._encrypt_word_array = function _encrypt_word_array(plaintext) {
          //https://code.google.com/p/crypto-js/issues/detail?id=85
          var cipher = _aes2.default.encrypt(plaintext, this.key, { iv: this.iv });
          return _encBase2.default.parse(cipher.toString());
      };
  
      /** This method does not use a checksum, the returned data must be validated some other way.
          @arg {string} ciphertext
          @return {Buffer} binary
      */
  
  
      Aes.prototype.decrypt = function decrypt(ciphertext) {
          if (typeof ciphertext === "string") {
              ciphertext = new Buffer(ciphertext, 'binary');
          }
          if (!Buffer.isBuffer(ciphertext)) {
              throw new Error("buffer required");
          }
          (0, _assert2.default)(ciphertext, "Missing cipher text");
          // hex is the only common format
          var hex = this.decryptHex(ciphertext.toString('hex'));
          return new Buffer(hex, 'hex');
      };
  
      /** This method does not use a checksum, the returned data must be validated some other way.
          @arg {string} plaintext
          @return {Buffer} binary
      */
  
  
      Aes.prototype.encrypt = function encrypt(plaintext) {
          if (typeof plaintext === "string") {
              plaintext = new Buffer(plaintext, 'binary');
          }
          if (!Buffer.isBuffer(plaintext)) {
              throw new Error("buffer required");
          }
          //assert plaintext, "Missing plain text"
          // hex is the only common format
          var hex = this.encryptHex(plaintext.toString('hex'));
          return new Buffer(hex, 'hex');
      };
  
      /** This method does not use a checksum, the returned data must be validated some other way.
          @arg {string|Buffer} plaintext
          @return {string} hex
      */
  
  
      Aes.prototype.encryptToHex = function encryptToHex(plaintext) {
          if (typeof plaintext === "string") {
              plaintext = new Buffer(plaintext, 'binary');
          }
          if (!Buffer.isBuffer(plaintext)) {
              throw new Error("buffer required");
          }
          //assert plaintext, "Missing plain text"
          // hex is the only common format
          return this.encryptHex(plaintext.toString('hex'));
      };
  
      /** This method does not use a checksum, the returned data must be validated some other way.
          @arg {string} cipher - hex
          @return {string} binary (could easily be readable text)
      */
  
  
      Aes.prototype.decryptHex = function decryptHex(cipher) {
          (0, _assert2.default)(cipher, "Missing cipher text");
          // Convert data into word arrays (used by Crypto)
          var cipher_array = _encHex2.default.parse(cipher);
          var plainwords = this._decrypt_word_array(cipher_array);
          return _encHex2.default.stringify(plainwords);
      };
  
      /** This method does not use a checksum, the returned data must be validated some other way.
          @arg {string} cipher - hex
          @return {Buffer} encoded as specified by the parameter
      */
  
  
      Aes.prototype.decryptHexToBuffer = function decryptHexToBuffer(cipher) {
          (0, _assert2.default)(cipher, "Missing cipher text");
          // Convert data into word arrays (used by Crypto)
          var cipher_array = _encHex2.default.parse(cipher);
          var plainwords = this._decrypt_word_array(cipher_array);
          var plainhex = _encHex2.default.stringify(plainwords);
          return new Buffer(plainhex, 'hex');
      };
  
      /** This method does not use a checksum, the returned data must be validated some other way.
          @arg {string} cipher - hex
          @arg {string} [encoding = 'binary'] - a valid Buffer encoding
          @return {String} encoded as specified by the parameter
      */
  
  
      Aes.prototype.decryptHexToText = function decryptHexToText(cipher) {
          var encoding = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'binary';
  
          return this.decryptHexToBuffer(cipher).toString(encoding);
      };
  
      /** This method does not use a checksum, the returned data must be validated some other way.
          @arg {string} plainhex - hex format
          @return {String} hex
      */
  
  
      Aes.prototype.encryptHex = function encryptHex(plainhex) {
          var plain_array = _encHex2.default.parse(plainhex);
          var cipher_array = this._encrypt_word_array(plain_array);
          return _encHex2.default.stringify(cipher_array);
      };
  
      return Aes;
  }();
  
  exports.default = Aes;
  module.exports = exports["default"];
  }).call(this,require("buffer").Buffer)
  },{"./hash":29,"assert":75,"buffer":79,"bytebuffer":40,"crypto-js/aes":46,"crypto-js/enc-base64":49,"crypto-js/enc-hex":50}],26:[function(require,module,exports){
  (function (Buffer){
  'use strict';
  
  exports.__esModule = true;
  exports.verifyRaw = exports.verify = exports.sign = exports.recoverPubKey = exports.deterministicGenerateK = exports.calcPubKeyRecoveryParam = undefined;
  
  var _assert = require('assert');
  
  var _assert2 = _interopRequireDefault(_assert);
  
  var _hash = require('./hash');
  
  var _enforce_types = require('./enforce_types');
  
  var _enforce_types2 = _interopRequireDefault(_enforce_types);
  
  var _bigi = require('bigi');
  
  var _bigi2 = _interopRequireDefault(_bigi);
  
  var _ecsignature = require('./ecsignature');
  
  var _ecsignature2 = _interopRequireDefault(_ecsignature);
  
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  
  // https://tools.ietf.org/html/rfc6979#section-3.2
  // from github.com/bitcoinjs/bitcoinjs-lib from github.com/cryptocoinjs/ecdsa
  function deterministicGenerateK(curve, hash, d, checkSig, nonce) {
  
    (0, _enforce_types2.default)('Buffer', hash);
    (0, _enforce_types2.default)(_bigi2.default, d);
  
    if (nonce) {
      hash = (0, _hash.sha256)(Buffer.concat([hash, new Buffer(nonce)]));
    }
  
    // sanity check
    _assert2.default.equal(hash.length, 32, 'Hash must be 256 bit');
  
    var x = d.toBuffer(32);
    var k = new Buffer(32);
    var v = new Buffer(32);
  
    // Step B
    v.fill(1);
  
    // Step C
    k.fill(0);
  
    // Step D
    k = (0, _hash.HmacSHA256)(Buffer.concat([v, new Buffer([0]), x, hash]), k);
  
    // Step E
    v = (0, _hash.HmacSHA256)(v, k);
  
    // Step F
    k = (0, _hash.HmacSHA256)(Buffer.concat([v, new Buffer([1]), x, hash]), k);
  
    // Step G
    v = (0, _hash.HmacSHA256)(v, k);
  
    // Step H1/H2a, ignored as tlen === qlen (256 bit)
    // Step H2b
    v = (0, _hash.HmacSHA256)(v, k);
  
    var T = _bigi2.default.fromBuffer(v);
  
    // Step H3, repeat until T is within the interval [1, n - 1]
    while (T.signum() <= 0 || T.compareTo(curve.n) >= 0 || !checkSig(T)) {
      k = (0, _hash.HmacSHA256)(Buffer.concat([v, new Buffer([0])]), k);
      v = (0, _hash.HmacSHA256)(v, k);
  
      // Step H1/H2a, again, ignored as tlen === qlen (256 bit)
      // Step H2b again
      v = (0, _hash.HmacSHA256)(v, k);
  
      T = _bigi2.default.fromBuffer(v);
    }
  
    return T;
  }
  
  function sign(curve, hash, d, nonce) {
  
    var e = _bigi2.default.fromBuffer(hash);
    var n = curve.n;
    var G = curve.G;
  
    var r, s;
    var k = deterministicGenerateK(curve, hash, d, function (k) {
      // find canonically valid signature
      var Q = G.multiply(k);
  
      if (curve.isInfinity(Q)) return false;
  
      r = Q.affineX.mod(n);
      if (r.signum() === 0) return false;
  
      s = k.modInverse(n).multiply(e.add(d.multiply(r))).mod(n);
      if (s.signum() === 0) return false;
  
      return true;
    }, nonce);
  
    var N_OVER_TWO = n.shiftRight(1);
  
    // enforce low S values, see bip62: 'low s values in signatures'
    if (s.compareTo(N_OVER_TWO) > 0) {
      s = n.subtract(s);
    }
  
    return new _ecsignature2.default(r, s);
  }
  
  function verifyRaw(curve, e, signature, Q) {
    var n = curve.n;
    var G = curve.G;
  
    var r = signature.r;
    var s = signature.s;
  
    // 1.4.1 Enforce r and s are both integers in the interval [1, n − 1]
    if (r.signum() <= 0 || r.compareTo(n) >= 0) return false;
    if (s.signum() <= 0 || s.compareTo(n) >= 0) return false;
  
    // c = s^-1 mod n
    var c = s.modInverse(n);
  
    // 1.4.4 Compute u1 = es^−1 mod n
    //               u2 = rs^−1 mod n
    var u1 = e.multiply(c).mod(n);
    var u2 = r.multiply(c).mod(n);
  
    // 1.4.5 Compute R = (xR, yR) = u1G + u2Q
    var R = G.multiplyTwo(u1, Q, u2);
  
    // 1.4.5 (cont.) Enforce R is not at infinity
    if (curve.isInfinity(R)) return false;
  
    // 1.4.6 Convert the field element R.x to an integer
    var xR = R.affineX;
  
    // 1.4.7 Set v = xR mod n
    var v = xR.mod(n);
  
    // 1.4.8 If v = r, output "valid", and if v != r, output "invalid"
    return v.equals(r);
  }
  
  function verify(curve, hash, signature, Q) {
    // 1.4.2 H = Hash(M), already done by the user
    // 1.4.3 e = H
    var e = _bigi2.default.fromBuffer(hash);
    return verifyRaw(curve, e, signature, Q);
  }
  
  /**
    * Recover a public key from a signature.
    *
    * See SEC 1: Elliptic Curve Cryptography, section 4.1.6, "Public
    * Key Recovery Operation".
    *
    * http://www.secg.org/download/aid-780/sec1-v2.pdf
    */
  function recoverPubKey(curve, e, signature, i) {
    _assert2.default.strictEqual(i & 3, i, 'Recovery param is more than two bits');
  
    var n = curve.n;
    var G = curve.G;
  
    var r = signature.r;
    var s = signature.s;
  
    (0, _assert2.default)(r.signum() > 0 && r.compareTo(n) < 0, 'Invalid r value');
    (0, _assert2.default)(s.signum() > 0 && s.compareTo(n) < 0, 'Invalid s value');
  
    // A set LSB signifies that the y-coordinate is odd
    var isYOdd = i & 1;
  
    // The more significant bit specifies whether we should use the
    // first or second candidate key.
    var isSecondKey = i >> 1;
  
    // 1.1 Let x = r + jn
    var x = isSecondKey ? r.add(n) : r;
    var R = curve.pointFromX(isYOdd, x);
  
    // 1.4 Check that nR is at infinity
    var nR = R.multiply(n);
    (0, _assert2.default)(curve.isInfinity(nR), 'nR is not a valid curve point');
  
    // Compute -e from e
    var eNeg = e.negate().mod(n);
  
    // 1.6.1 Compute Q = r^-1 (sR -  eG)
    //               Q = r^-1 (sR + -eG)
    var rInv = r.modInverse(n);
  
    var Q = R.multiplyTwo(s, G, eNeg).multiply(rInv);
    curve.validate(Q);
  
    return Q;
  }
  
  /**
    * Calculate pubkey extraction parameter.
    *
    * When extracting a pubkey from a signature, we have to
    * distinguish four different cases. Rather than putting this
    * burden on the verifier, Bitcoin includes a 2-bit value with the
    * signature.
    *
    * This function simply tries all four cases and returns the value
    * that resulted in a successful pubkey recovery.
    */
  function calcPubKeyRecoveryParam(curve, e, signature, Q) {
    for (var i = 0; i < 4; i++) {
      var Qprime = recoverPubKey(curve, e, signature, i);
  
      // 1.6.2 Verify Q
      if (Qprime.equals(Q)) {
        return i;
      }
    }
  
    throw new Error('Unable to find valid recovery factor');
  }
  
  exports.calcPubKeyRecoveryParam = calcPubKeyRecoveryParam;
  exports.deterministicGenerateK = deterministicGenerateK;
  exports.recoverPubKey = recoverPubKey;
  exports.sign = sign;
  exports.verify = verify;
  exports.verifyRaw = verifyRaw;
  }).call(this,require("buffer").Buffer)
  },{"./ecsignature":27,"./enforce_types":28,"./hash":29,"assert":75,"bigi":5,"buffer":79}],27:[function(require,module,exports){
  (function (Buffer){
  'use strict';
  
  exports.__esModule = true;
  
  var _assert = require('assert');
  
  var _assert2 = _interopRequireDefault(_assert);
  
  var _enforce_types = require('./enforce_types');
  
  var _enforce_types2 = _interopRequireDefault(_enforce_types);
  
  var _bigi = require('bigi');
  
  var _bigi2 = _interopRequireDefault(_bigi);
  
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  
  // from https://github.com/bitcoinjs/bitcoinjs-lib
  function ECSignature(r, s) {
    (0, _enforce_types2.default)(_bigi2.default, r);
    (0, _enforce_types2.default)(_bigi2.default, s);
  
    this.r = r;
    this.s = s;
  }
  
  // Import operations
  ECSignature.parseCompact = function (buffer) {
    _assert2.default.equal(buffer.length, 65, 'Invalid signature length');
    var i = buffer.readUInt8(0) - 27;
  
    // At most 3 bits
    _assert2.default.equal(i, i & 7, 'Invalid signature parameter');
    var compressed = !!(i & 4);
  
    // Recovery param only
    i = i & 3;
  
    var r = _bigi2.default.fromBuffer(buffer.slice(1, 33));
    var s = _bigi2.default.fromBuffer(buffer.slice(33));
  
    return {
      compressed: compressed,
      i: i,
      signature: new ECSignature(r, s)
    };
  };
  
  ECSignature.fromDER = function (buffer) {
    _assert2.default.equal(buffer.readUInt8(0), 0x30, 'Not a DER sequence');
    _assert2.default.equal(buffer.readUInt8(1), buffer.length - 2, 'Invalid sequence length');
    _assert2.default.equal(buffer.readUInt8(2), 0x02, 'Expected a DER integer');
  
    var rLen = buffer.readUInt8(3);
    (0, _assert2.default)(rLen > 0, 'R length is zero');
  
    var offset = 4 + rLen;
    _assert2.default.equal(buffer.readUInt8(offset), 0x02, 'Expected a DER integer (2)');
  
    var sLen = buffer.readUInt8(offset + 1);
    (0, _assert2.default)(sLen > 0, 'S length is zero');
  
    var rB = buffer.slice(4, offset);
    var sB = buffer.slice(offset + 2);
    offset += 2 + sLen;
  
    if (rLen > 1 && rB.readUInt8(0) === 0x00) {
      (0, _assert2.default)(rB.readUInt8(1) & 0x80, 'R value excessively padded');
    }
  
    if (sLen > 1 && sB.readUInt8(0) === 0x00) {
      (0, _assert2.default)(sB.readUInt8(1) & 0x80, 'S value excessively padded');
    }
  
    _assert2.default.equal(offset, buffer.length, 'Invalid DER encoding');
    var r = _bigi2.default.fromDERInteger(rB);
    var s = _bigi2.default.fromDERInteger(sB);
  
    (0, _assert2.default)(r.signum() >= 0, 'R value is negative');
    (0, _assert2.default)(s.signum() >= 0, 'S value is negative');
  
    return new ECSignature(r, s);
  };
  
  // FIXME: 0x00, 0x04, 0x80 are SIGHASH_* boundary constants, importing Transaction causes a circular dependency
  ECSignature.parseScriptSignature = function (buffer) {
    var hashType = buffer.readUInt8(buffer.length - 1);
    var hashTypeMod = hashType & ~0x80;
  
    (0, _assert2.default)(hashTypeMod > 0x00 && hashTypeMod < 0x04, 'Invalid hashType');
  
    return {
      signature: ECSignature.fromDER(buffer.slice(0, -1)),
      hashType: hashType
    };
  };
  
  // Export operations
  ECSignature.prototype.toCompact = function (i, compressed) {
    if (compressed) i += 4;
    i += 27;
  
    var buffer = new Buffer(65);
    buffer.writeUInt8(i, 0);
  
    this.r.toBuffer(32).copy(buffer, 1);
    this.s.toBuffer(32).copy(buffer, 33);
  
    return buffer;
  };
  
  ECSignature.prototype.toDER = function () {
    var rBa = this.r.toDERInteger();
    var sBa = this.s.toDERInteger();
  
    var sequence = [];
  
    // INTEGER
    sequence.push(0x02, rBa.length);
    sequence = sequence.concat(rBa);
  
    // INTEGER
    sequence.push(0x02, sBa.length);
    sequence = sequence.concat(sBa);
  
    // SEQUENCE
    sequence.unshift(0x30, sequence.length);
  
    return new Buffer(sequence);
  };
  
  ECSignature.prototype.toScriptSignature = function (hashType) {
    var hashTypeBuffer = new Buffer(1);
    hashTypeBuffer.writeUInt8(hashType, 0);
  
    return Buffer.concat([this.toDER(), hashTypeBuffer]);
  };
  
  exports.default = ECSignature;
  module.exports = exports['default'];
  }).call(this,require("buffer").Buffer)
  },{"./enforce_types":28,"assert":75,"bigi":5,"buffer":79}],28:[function(require,module,exports){
  (function (Buffer){
  'use strict';
  
  exports.__esModule = true;
  exports.default = enforce;
  function enforce(type, value) {
    // Copied from https://github.com/bitcoinjs/bitcoinjs-lib
    switch (type) {
      case 'Array':
        {
          if (Array.isArray(value)) return;
          break;
        }
  
      case 'Boolean':
        {
          if (typeof value === 'boolean') return;
          break;
        }
  
      case 'Buffer':
        {
          if (Buffer.isBuffer(value)) return;
          break;
        }
  
      case 'Number':
        {
          if (typeof value === 'number') return;
          break;
        }
  
      case 'String':
        {
          if (typeof value === 'string') return;
          break;
        }
  
      default:
        {
          if (getName(value.constructor) === getName(type)) return;
        }
    }
  
    throw new TypeError('Expected ' + (getName(type) || type) + ', got ' + value);
  }
  
  function getName(fn) {
    // Why not fn.name: https://kangax.github.io/compat-table/es6/#function_name_property
    var match = fn.toString().match(/function (.*?)\(/);
    return match ? match[1] : null;
  }
  module.exports = exports['default'];
  }).call(this,{"isBuffer":require("../../../../../../../../../usr/local/lib/node_modules/browserify/node_modules/is-buffer/index.js")})
  },{"../../../../../../../../../usr/local/lib/node_modules/browserify/node_modules/is-buffer/index.js":84}],29:[function(require,module,exports){
  "use strict";
  
  exports.__esModule = true;
  exports.ripemd160 = exports.HmacSHA256 = exports.sha512 = exports.sha256 = exports.sha1 = undefined;
  
  var _createHash = require("create-hash");
  
  var _createHash2 = _interopRequireDefault(_createHash);
  
  var _createHmac = require("create-hmac");
  
  var _createHmac2 = _interopRequireDefault(_createHmac);
  
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  
  /** @arg {string|Buffer} data
      @arg {string} [digest = null] - 'hex', 'binary' or 'base64'
      @return {string|Buffer} - Buffer when digest is null, or string
  */
  function sha1(data, encoding) {
      return (0, _createHash2.default)('sha1').update(data).digest(encoding);
  }
  
  /** @arg {string|Buffer} data
      @arg {string} [digest = null] - 'hex', 'binary' or 'base64'
      @return {string|Buffer} - Buffer when digest is null, or string
  */
  function sha256(data, encoding) {
      return (0, _createHash2.default)('sha256').update(data).digest(encoding);
  }
  
  /** @arg {string|Buffer} data
      @arg {string} [digest = null] - 'hex', 'binary' or 'base64'
      @return {string|Buffer} - Buffer when digest is null, or string
  */
  function sha512(data, encoding) {
      return (0, _createHash2.default)('sha512').update(data).digest(encoding);
  }
  
  function HmacSHA256(buffer, secret) {
      return (0, _createHmac2.default)('sha256', secret).update(buffer).digest();
  }
  
  function ripemd160(data) {
      return (0, _createHash2.default)('rmd160').update(data).digest();
  }
  
  // function hash160(buffer) {
  //   return ripemd160(sha256(buffer))
  // }
  //
  // function hash256(buffer) {
  //   return sha256(sha256(buffer))
  // }
  
  //
  // function HmacSHA512(buffer, secret) {
  //   return crypto.createHmac('sha512', secret).update(buffer).digest()
  // }
  
  exports.sha1 = sha1;
  exports.sha256 = sha256;
  exports.sha512 = sha512;
  exports.HmacSHA256 = HmacSHA256;
  exports.ripemd160 = ripemd160;
  },{"create-hash":42,"create-hmac":45}],30:[function(require,module,exports){
  (function (Buffer){
  'use strict';
  
  exports.__esModule = true;
  
  var _ecdsa = require('./ecdsa');
  
  var _hash2 = require('./hash');
  
  var _ecurve = require('ecurve');
  
  var _assert = require('assert');
  
  var _assert2 = _interopRequireDefault(_assert);
  
  var _bigi = require('bigi');
  
  var _bigi2 = _interopRequireDefault(_bigi);
  
  var _PublicKey = require('./PublicKey');
  
  var _PublicKey2 = _interopRequireDefault(_PublicKey);
  
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  
  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  
  var secp256k1 = (0, _ecurve.getCurveByName)('secp256k1');
  
  var Signature = function () {
      function Signature(r1, s1, i1) {
          _classCallCheck(this, Signature);
  
          this.r = r1;
          this.s = s1;
          this.i = i1;
          _assert2.default.equal(this.r != null, true, 'Missing parameter');
          _assert2.default.equal(this.s != null, true, 'Missing parameter');
          _assert2.default.equal(this.i != null, true, 'Missing parameter');
      }
  
      Signature.fromBuffer = function fromBuffer(buf) {
          var i, r, s;
          _assert2.default.equal(buf.length, 65, 'Invalid signature length');
          i = buf.readUInt8(0);
          _assert2.default.equal(i - 27, i - 27 & 7, 'Invalid signature parameter');
          r = _bigi2.default.fromBuffer(buf.slice(1, 33));
          s = _bigi2.default.fromBuffer(buf.slice(33));
          return new Signature(r, s, i);
      };
  
      Signature.prototype.toBuffer = function toBuffer() {
          var buf;
          buf = new Buffer(65);
          buf.writeUInt8(this.i, 0);
          this.r.toBuffer(32).copy(buf, 1);
          this.s.toBuffer(32).copy(buf, 33);
          return buf;
      };
  
      Signature.prototype.recoverPublicKeyFromBuffer = function recoverPublicKeyFromBuffer(buffer) {
          return this.recoverPublicKey((0, _hash2.sha256)(buffer));
      };
  
      /**
          @return {PublicKey}
      */
      Signature.prototype.recoverPublicKey = function recoverPublicKey(sha256_buffer) {
          var Q = void 0,
              e = void 0,
              i = void 0;
          e = _bigi2.default.fromBuffer(sha256_buffer);
          i = this.i;
          i -= 27;
          i = i & 3;
          Q = (0, _ecdsa.recoverPubKey)(secp256k1, e, this, i);
          return _PublicKey2.default.fromPoint(Q);
      };
  
      /**
          @param {Buffer} buf
          @param {PrivateKey} private_key
          @return {Signature}
      */
      Signature.signBuffer = function signBuffer(buf, private_key) {
          var _hash = (0, _hash2.sha256)(buf);
          return Signature.signBufferSha256(_hash, private_key);
      };
  
      /** Sign a buffer of exactally 32 bytes in size (sha256(text))
          @param {Buffer} buf - 32 bytes binary
          @param {PrivateKey} private_key
          @return {Signature}
      */
  
  
      Signature.signBufferSha256 = function signBufferSha256(buf_sha256, private_key) {
          if (buf_sha256.length !== 32 || !Buffer.isBuffer(buf_sha256)) throw new Error("buf_sha256: 32 byte buffer requred");
          var der, e, ecsignature, i, lenR, lenS, nonce;
          i = null;
          nonce = 0;
          e = _bigi2.default.fromBuffer(buf_sha256);
          while (true) {
              ecsignature = (0, _ecdsa.sign)(secp256k1, buf_sha256, private_key.d, nonce++);
              der = ecsignature.toDER();
              lenR = der[3];
              lenS = der[5 + lenR];
              if (lenR === 32 && lenS === 32) {
                  i = (0, _ecdsa.calcPubKeyRecoveryParam)(secp256k1, e, ecsignature, private_key.toPublicKey().Q);
                  i += 4; // compressed
                  i += 27; // compact  //  24 or 27 :( forcing odd-y 2nd key candidate)
                  break;
              }
              if (nonce % 10 === 0) {
                  console.log("WARN: " + nonce + " attempts to find canonical signature");
              }
          }
          return new Signature(ecsignature.r, ecsignature.s, i);
      };
  
      Signature.sign = function sign(string, private_key) {
          return Signature.signBuffer(new Buffer(string), private_key);
      };
  
      /**
          @param {Buffer} un-hashed
          @param {./PublicKey}
          @return {boolean}
      */
      Signature.prototype.verifyBuffer = function verifyBuffer(buf, public_key) {
          var _hash = (0, _hash2.sha256)(buf);
          return this.verifyHash(_hash, public_key);
      };
  
      Signature.prototype.verifyHash = function verifyHash(hash, public_key) {
          _assert2.default.equal(hash.length, 32, "A SHA 256 should be 32 bytes long, instead got " + hash.length);
          return (0, _ecdsa.verify)(secp256k1, hash, {
              r: this.r,
              s: this.s
          }, public_key.Q);
      };
  
      /* <HEX> */
  
      Signature.prototype.toByteBuffer = function toByteBuffer() {
          var b;
          b = new ByteBuffer(ByteBuffer.DEFAULT_CAPACITY, ByteBuffer.LITTLE_ENDIAN);
          this.appendByteBuffer(b);
          return b.copy(0, b.offset);
      };
  
      Signature.fromHex = function fromHex(hex) {
          return Signature.fromBuffer(new Buffer(hex, "hex"));
      };
  
      Signature.prototype.toHex = function toHex() {
          return this.toBuffer().toString("hex");
      };
  
      Signature.signHex = function signHex(hex, private_key) {
          var buf;
          buf = new Buffer(hex, 'hex');
          return Signature.signBuffer(buf, private_key);
      };
  
      Signature.prototype.verifyHex = function verifyHex(hex, public_key) {
          var buf;
          buf = new Buffer(hex, 'hex');
          return this.verifyBuffer(buf, public_key);
      };
  
      return Signature;
  }();
  
  exports.default = Signature;
  module.exports = exports['default'];
  }).call(this,require("buffer").Buffer)
  },{"./PublicKey":23,"./ecdsa":26,"./hash":29,"assert":75,"bigi":5,"buffer":79,"ecurve":60}],31:[function(require,module,exports){
  "use strict";
  
  exports.__esModule = true;
  exports.SerializerValidation = exports.template = exports.ops = exports.types = exports.fp = exports.Serializer = undefined;
  
  var _serializer = require("./src/serializer");
  
  var _serializer2 = _interopRequireDefault(_serializer);
  
  var _FastParser = require("./src/FastParser");
  
  var _FastParser2 = _interopRequireDefault(_FastParser);
  
  var _types = require("./src/types");
  
  var _types2 = _interopRequireDefault(_types);
  
  var _operations = require("./src/operations");
  
  var ops = _interopRequireWildcard(_operations);
  
  var _template = require("./src/template");
  
  var _template2 = _interopRequireDefault(_template);
  
  var _SerializerValidation = require("./src/SerializerValidation");
  
  var _SerializerValidation2 = _interopRequireDefault(_SerializerValidation);
  
  function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
  
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  
  exports.Serializer = _serializer2.default;
  exports.fp = _FastParser2.default;
  exports.types = _types2.default;
  exports.ops = ops;
  exports.template = _template2.default;
  exports.SerializerValidation = _SerializerValidation2.default;
  },{"./src/FastParser":32,"./src/SerializerValidation":33,"./src/operations":35,"./src/serializer":36,"./src/template":37,"./src/types":38}],32:[function(require,module,exports){
  (function (Buffer){
  'use strict';
  
  exports.__esModule = true;
  
  var _PublicKey = require('../../ecc/src/PublicKey');
  
  var _PublicKey2 = _interopRequireDefault(_PublicKey);
  
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  
  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  
  var FastParser = function () {
      function FastParser() {
          _classCallCheck(this, FastParser);
      }
  
      FastParser.fixed_data = function fixed_data(b, len, buffer) {
          if (!b) {
              return;
          }
          if (buffer) {
              var data = buffer.slice(0, len).toString('binary');
              b.append(data, 'binary');
              while (len-- > data.length) {
                  b.writeUint8(0);
              }
          } else {
              var b_copy = b.copy(b.offset, b.offset + len);
              b.skip(len);
              return new Buffer(b_copy.toBinary(), 'binary');
          }
      };
  
      FastParser.public_key = function public_key(b, _public_key) {
          if (!b) {
              return;
          }
          if (_public_key) {
              var buffer = _public_key.toBuffer();
              b.append(buffer.toString('binary'), 'binary');
              return;
          } else {
              buffer = FastParser.fixed_data(b, 33);
              return _PublicKey2.default.fromBuffer(buffer);
          }
      };
  
      FastParser.ripemd160 = function ripemd160(b, _ripemd) {
          if (!b) {
              return;
          }
          if (_ripemd) {
              FastParser.fixed_data(b, 20, _ripemd);
              return;
          } else {
              return FastParser.fixed_data(b, 20);
          }
      };
  
      FastParser.time_point_sec = function time_point_sec(b, epoch) {
          if (epoch) {
              epoch = Math.ceil(epoch / 1000);
              b.writeInt32(epoch);
              return;
          } else {
              epoch = b.readInt32(); // fc::time_point_sec
              return new Date(epoch * 1000);
          }
      };
  
      return FastParser;
  }();
  
  exports.default = FastParser;
  module.exports = exports['default'];
  }).call(this,require("buffer").Buffer)
  },{"../../ecc/src/PublicKey":23,"buffer":79}],33:[function(require,module,exports){
  'use strict';
  
  exports.__esModule = true;
  
  var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
  
  var _bytebuffer = require('bytebuffer');
  
  var _ChainTypes = require('../../chain/src/ChainTypes');
  
  var _ChainTypes2 = _interopRequireDefault(_ChainTypes);
  
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  
  var MAX_SAFE_INT = 9007199254740991;
  var MIN_SAFE_INT = -9007199254740991;
  
  /**
      Most validations are skipped and the value returned unchanged when an empty string, null, or undefined is encountered (except "required").
  
      Validations support a string format for dealing with large numbers.
  */
  var _my = {
  
      is_empty: function is_empty(value) {
          return value === null || value === undefined;
      },
  
      required: function required(value) {
          var field_name = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : "";
  
          if (this.is_empty(value)) {
              throw new Error('value required ' + field_name + ' ' + value);
          }
          return value;
      },
      require_long: function require_long(value) {
          var field_name = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : "";
  
          if (!_bytebuffer.Long.isLong(value)) {
              throw new Error('Long value required ' + field_name + ' ' + value);
          }
          return value;
      },
      string: function string(value) {
          if (this.is_empty(value)) {
              return value;
          }
          if (typeof value !== "string") {
              throw new Error('string required: ' + value);
          }
          return value;
      },
      number: function number(value) {
          if (this.is_empty(value)) {
              return value;
          }
          if (typeof value !== "number") {
              throw new Error('number required: ' + value);
          }
          return value;
      },
      whole_number: function whole_number(value) {
          var field_name = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : "";
  
          if (this.is_empty(value)) {
              return value;
          }
          if (/\./.test(value)) {
              throw new Error('whole number required ' + field_name + ' ' + value);
          }
          return value;
      },
      unsigned: function unsigned(value) {
          var field_name = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : "";
  
          if (this.is_empty(value)) {
              return value;
          }
          if (/-/.test(value)) {
              throw new Error('unsigned required ' + field_name + ' ' + value);
          }
          return value;
      },
  
  
      is_digits: function is_digits(value) {
          if (typeof value === "numeric") {
              return true;
          }
          return (/^[0-9]+$/.test(value)
          );
      },
  
      to_number: function to_number(value) {
          var field_name = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : "";
  
          if (this.is_empty(value)) {
              return value;
          }
          this.no_overflow53(value, field_name);
          var int_value = function () {
              if (typeof value === "number") {
                  return value;
              } else {
                  return parseInt(value);
              }
          }();
          return int_value;
      },
  
      to_long: function to_long(value) {
          var field_name = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : "";
  
          if (this.is_empty(value)) {
              return value;
          }
          if (_bytebuffer.Long.isLong(value)) {
              return value;
          }
  
          this.no_overflow64(value, field_name);
          if (typeof value === "number") {
              value = "" + value;
          }
          return _bytebuffer.Long.fromString(value);
      },
      to_string: function to_string(value) {
          var field_name = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : "";
  
          if (this.is_empty(value)) {
              return value;
          }
          if (typeof value === "string") {
              return value;
          }
          if (typeof value === "number") {
              this.no_overflow53(value, field_name);
              return "" + value;
          }
          if (_bytebuffer.Long.isLong(value)) {
              return value.toString();
          }
          throw 'unsupported type ' + field_name + ': (' + (typeof value === 'undefined' ? 'undefined' : _typeof(value)) + ') ' + value;
      },
      require_test: function require_test(regex, value) {
          var field_name = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : "";
  
          if (this.is_empty(value)) {
              return value;
          }
          if (!regex.test(value)) {
              throw new Error('unmatched ' + regex + ' ' + field_name + ' ' + value);
          }
          return value;
      },
  
  
      require_match: function require_match(regex, value) {
          var field_name = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : "";
  
          if (this.is_empty(value)) {
              return value;
          }
          var match = value.match(regex);
          if (match === null) {
              throw new Error('unmatched ' + regex + ' ' + field_name + ' ' + value);
          }
          return match;
      },
  
      require_object_id: function require_object_id(value, field_name) {
          return require_match(/^([0-9]+)\.([0-9]+)\.([0-9]+)$/, value, field_name);
      },
  
      // Does not support over 53 bits
      require_range: function require_range(min, max, value) {
          var field_name = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : "";
  
          if (this.is_empty(value)) {
              return value;
          }
          var number = this.to_number(value);
          if (value < min || value > max) {
              throw new Error('out of range ' + value + ' ' + field_name + ' ' + value);
          }
          return value;
      },
  
  
      require_object_type: function require_object_type() {
          var reserved_spaces = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 1;
          var type = arguments[1];
          var value = arguments[2];
          var field_name = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : "";
  
          if (this.is_empty(value)) {
              return value;
          }
          var object_type = _ChainTypes2.default.object_type[type];
          if (!object_type) {
              throw new Error('Unknown object type ' + type + ' ' + field_name + ' ' + value);
          }
          var re = new RegExp(reserved_spaces + '.' + object_type + '.[0-9]+$');
          if (!re.test(value)) {
              throw new Error('Expecting ' + type + ' in format ' + (reserved_spaces + '.' + object_type + '.[0-9]+ ') + ('instead of ' + value + ' ' + field_name + ' ' + value));
          }
          return value;
      },
  
      get_instance: function get_instance(reserve_spaces, type, value, field_name) {
          if (this.is_empty(value)) {
              return value;
          }
          this.require_object_type(reserve_spaces, type, value, field_name);
          return this.to_number(value.split('.')[2]);
      },
  
      require_relative_type: function require_relative_type(type, value, field_name) {
          this.require_object_type(0, type, value, field_name);
          return value;
      },
  
      get_relative_instance: function get_relative_instance(type, value, field_name) {
          if (this.is_empty(value)) {
              return value;
          }
          this.require_object_type(0, type, value, field_name);
          return this.to_number(value.split('.')[2]);
      },
  
      require_protocol_type: function require_protocol_type(type, value, field_name) {
          this.require_object_type(1, type, value, field_name);
          return value;
      },
  
      get_protocol_instance: function get_protocol_instance(type, value, field_name) {
          if (this.is_empty(value)) {
              return value;
          }
          this.require_object_type(1, type, value, field_name);
          return this.to_number(value.split('.')[2]);
      },
  
      get_protocol_type: function get_protocol_type(value, field_name) {
          if (this.is_empty(value)) {
              return value;
          }
          this.require_object_id(value, field_name);
          var values = value.split('.');
          return this.to_number(values[1]);
      },
  
      get_protocol_type_name: function get_protocol_type_name(value, field_name) {
          if (this.is_empty(value)) {
              return value;
          }
          var type_id = this.get_protocol_type(value, field_name);
          return Object.keys(_ChainTypes2.default.object_type)[type_id];
      },
  
  
      require_implementation_type: function require_implementation_type(type, value, field_name) {
          this.require_object_type(2, type, value, field_name);
          return value;
      },
  
      get_implementation_instance: function get_implementation_instance(type, value, field_name) {
          if (this.is_empty(value)) {
              return value;
          }
          this.require_object_type(2, type, value, field_name);
          return this.to_number(value.split('.')[2]);
      },
  
      // signed / unsigned decimal
      no_overflow53: function no_overflow53(value) {
          var field_name = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : "";
  
          if (typeof value === "number") {
              if (value > MAX_SAFE_INT || value < MIN_SAFE_INT) {
                  throw new Error('overflow ' + field_name + ' ' + value);
              }
              return;
          }
          if (typeof value === "string") {
              var int = parseInt(value);
              if (value > MAX_SAFE_INT || value < MIN_SAFE_INT) {
                  throw new Error('overflow ' + field_name + ' ' + value);
              }
              return;
          }
          if (_bytebuffer.Long.isLong(value)) {
              // typeof value.toInt() is 'number'
              this.no_overflow53(value.toInt(), field_name);
              return;
          }
          throw 'unsupported type ' + field_name + ': (' + (typeof value === 'undefined' ? 'undefined' : _typeof(value)) + ') ' + value;
      },
  
  
      // signed / unsigned whole numbers only
      no_overflow64: function no_overflow64(value) {
          var field_name = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : "";
  
          // https://github.com/dcodeIO/Long.js/issues/20
          if (_bytebuffer.Long.isLong(value)) {
              return;
          }
  
          // BigInteger#isBigInteger https://github.com/cryptocoinjs/bigi/issues/20
          if (value.t !== undefined && value.s !== undefined) {
              this.no_overflow64(value.toString(), field_name);
              return;
          }
  
          if (typeof value === "string") {
              // remove leading zeros, will cause a false positive
              value = value.replace(/^0+/, '');
              // remove trailing zeros
              while (/0$/.test(value)) {
                  value = value.substring(0, value.length - 1);
              }
              if (/\.$/.test(value)) {
                  // remove trailing dot
                  value = value.substring(0, value.length - 1);
              }
              if (value === "") {
                  value = "0";
              }
              var long_string = _bytebuffer.Long.fromString(value).toString();
              if (long_string !== value.trim()) {
                  throw new Error('overflow ' + field_name + ' ' + value);
              }
              return;
          }
          if (typeof value === "number") {
              if (value > MAX_SAFE_INT || value < MIN_SAFE_INT) {
                  throw new Error('overflow ' + field_name + ' ' + value);
              }
              return;
          }
  
          throw 'unsupported type ' + field_name + ': (' + (typeof value === 'undefined' ? 'undefined' : _typeof(value)) + ') ' + value;
      }
  };
  
  exports.default = _my;
  module.exports = exports['default'];
  },{"../../chain/src/ChainTypes":15,"bytebuffer":40}],34:[function(require,module,exports){
  "use strict";
  
  exports.__esModule = true;
  
  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  
  /** Exception nesting.  */
  var ErrorWithCause = function () {
      function ErrorWithCause(message, cause) {
          _classCallCheck(this, ErrorWithCause);
  
          this.message = message;
          if (typeof cause !== "undefined" && cause !== null ? cause.message : undefined) {
              this.message = "cause\t" + cause.message + "\t" + this.message;
          }
  
          var stack = ""; //(new Error).stack
          if (typeof cause !== "undefined" && cause !== null ? cause.stack : undefined) {
              stack = "caused by\n\t" + cause.stack + "\t" + stack;
          }
  
          this.stack = this.message + "\n" + stack;
      }
  
      ErrorWithCause.throw = function _throw(message, cause) {
          var msg = message;
          if (typeof cause !== "undefined" && cause !== null ? cause.message : undefined) {
              msg += "\t cause: " + cause.message + " ";
          }
          if (typeof cause !== "undefined" && cause !== null ? cause.stack : undefined) {
              msg += "\n stack: " + cause.stack + " ";
          }
          throw new Error(msg);
      };
  
      return ErrorWithCause;
  }();
  
  exports.default = ErrorWithCause;
  module.exports = exports["default"];
  },{}],35:[function(require,module,exports){
  "use strict";
  
  exports.__esModule = true;
  exports.stealth_memo_data = exports.signed_transaction = exports.transaction = exports.asset_claim_fees = exports.asset_settle_cancel = exports.transfer_from_blind = exports.blind_transfer = exports.blind_input = exports.transfer_to_blind = exports.blind_output = exports.stealth_confirmation = exports.override_transfer = exports.balance_claim = exports.assert = exports.block_id_predicate = exports.asset_symbol_eq_lit_predicate = exports.account_name_eq_lit_predicate = exports.custom = exports.worker_create = exports.burn_worker_initializer = exports.vesting_balance_worker_initializer = exports.refund_worker_initializer = exports.vesting_balance_withdraw = exports.vesting_balance_create = exports.cdd_vesting_policy_initializer = exports.linear_vesting_policy_initializer = exports.committee_member_update_global_parameters = exports.chain_parameters = exports.committee_member_update = exports.committee_member_create = exports.withdraw_permission_delete = exports.withdraw_permission_claim = exports.withdraw_permission_update = exports.withdraw_permission_create = exports.proposal_delete = exports.proposal_update = exports.proposal_create = exports.op_wrapper = exports.witness_update = exports.witness_create = exports.asset_publish_feed = exports.price_feed = exports.asset_global_settle = exports.asset_settle = exports.asset_fund_fee_pool = exports.asset_reserve = exports.asset_issue = exports.asset_update_feed_producers = exports.asset_update_bitasset = exports.asset_update = exports.asset_create = exports.bitasset_options = exports.asset_options = exports.price = exports.account_transfer = exports.account_upgrade = exports.account_whitelist = exports.account_update = exports.account_create = exports.account_options = exports.authority = exports.fill_order = exports.call_order_update = exports.limit_order_cancel = exports.limit_order_create = exports.transfer = exports.memo_data = exports.signed_block_header = exports.block_header = exports.signed_block = exports.processed_transaction = exports.asset = exports.void_result = exports.fee_schedule = exports.asset_claim_fees_operation_fee_parameters = exports.asset_settle_cancel_operation_fee_parameters = exports.transfer_from_blind_operation_fee_parameters = exports.blind_transfer_operation_fee_parameters = exports.transfer_to_blind_operation_fee_parameters = exports.override_transfer_operation_fee_parameters = exports.balance_claim_operation_fee_parameters = exports.assert_operation_fee_parameters = exports.custom_operation_fee_parameters = exports.worker_create_operation_fee_parameters = exports.vesting_balance_withdraw_operation_fee_parameters = exports.vesting_balance_create_operation_fee_parameters = exports.committee_member_update_global_parameters_operation_fee_parameters = exports.committee_member_update_operation_fee_parameters = exports.committee_member_create_operation_fee_parameters = exports.withdraw_permission_delete_operation_fee_parameters = exports.withdraw_permission_claim_operation_fee_parameters = exports.withdraw_permission_update_operation_fee_parameters = exports.withdraw_permission_create_operation_fee_parameters = exports.proposal_delete_operation_fee_parameters = exports.proposal_update_operation_fee_parameters = exports.proposal_create_operation_fee_parameters = exports.witness_update_operation_fee_parameters = exports.witness_create_operation_fee_parameters = exports.asset_publish_feed_operation_fee_parameters = exports.asset_global_settle_operation_fee_parameters = exports.asset_settle_operation_fee_parameters = exports.asset_fund_fee_pool_operation_fee_parameters = exports.asset_reserve_operation_fee_parameters = exports.asset_issue_operation_fee_parameters = exports.asset_update_feed_producers_operation_fee_parameters = exports.asset_update_bitasset_operation_fee_parameters = exports.asset_update_operation_fee_parameters = exports.asset_create_operation_fee_parameters = exports.account_transfer_operation_fee_parameters = exports.account_upgrade_operation_fee_parameters = exports.account_whitelist_operation_fee_parameters = exports.account_update_operation_fee_parameters = exports.account_create_operation_fee_parameters = exports.fill_order_operation_fee_parameters = exports.call_order_update_operation_fee_parameters = exports.limit_order_cancel_operation_fee_parameters = exports.limit_order_create_operation_fee_parameters = exports.transfer_operation_fee_parameters = exports.operation = undefined;
  
  var _types = require("./types");
  
  var _types2 = _interopRequireDefault(_types);
  
  var _serializer = require("./serializer");
  
  var _serializer2 = _interopRequireDefault(_serializer);
  
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  
  var uint8 = _types2.default.uint8,
      uint16 = _types2.default.uint16,
      uint32 = _types2.default.uint32,
      int64 = _types2.default.int64,
      uint64 = _types2.default.uint64,
      string = _types2.default.string,
      bytes = _types2.default.bytes,
      bool = _types2.default.bool,
      array = _types2.default.array,
      fixed_array = _types2.default.fixed_array,
      protocol_id_type = _types2.default.protocol_id_type,
      object_id_type = _types2.default.object_id_type,
      vote_id = _types2.default.vote_id,
      future_extensions = _types2.default.future_extensions,
      static_variant = _types2.default.static_variant,
      map = _types2.default.map,
      set = _types2.default.set,
      public_key = _types2.default.public_key,
      address = _types2.default.address,
      time_point_sec = _types2.default.time_point_sec,
      optional = _types2.default.optional;
  
  
  future_extensions = _types2.default.void;
  
  /*
  When updating generated code
  Replace:  operation = static_variant [
  with:     operation.st_operations = [
  
  Delete:
  public_key = new Serializer(
      "public_key"
      key_data: bytes 33
  )
  
  */
  // Place-holder, their are dependencies on "operation" .. The final list of
  // operations is not avialble until the very end of the generated code.
  // See: operation.st_operations = ...
  var operation = static_variant();
  // module.exports["operation"] = operation;
  
  exports.operation = operation;
  // For module.exports
  
  var Serializer = function Serializer(operation_name, serilization_types_object) {
      return new _serializer2.default(operation_name, serilization_types_object);
      // return module.exports[operation_name] = s;
  };
  
  // Custom-types follow Generated code:
  
  // ##  Generated code follows
  // # programs/js_operation_serializer > npm i -g decaffeinate
  // ## -------------------------------
  var transfer_operation_fee_parameters = exports.transfer_operation_fee_parameters = new Serializer("transfer_operation_fee_parameters", { fee: uint64,
      price_per_kbyte: uint32 });
  
  var limit_order_create_operation_fee_parameters = exports.limit_order_create_operation_fee_parameters = new Serializer("limit_order_create_operation_fee_parameters", { fee: uint64 });
  
  var limit_order_cancel_operation_fee_parameters = exports.limit_order_cancel_operation_fee_parameters = new Serializer("limit_order_cancel_operation_fee_parameters", { fee: uint64 });
  
  var call_order_update_operation_fee_parameters = exports.call_order_update_operation_fee_parameters = new Serializer("call_order_update_operation_fee_parameters", { fee: uint64 });
  
  var fill_order_operation_fee_parameters = exports.fill_order_operation_fee_parameters = new Serializer("fill_order_operation_fee_parameters");
  
  var account_create_operation_fee_parameters = exports.account_create_operation_fee_parameters = new Serializer("account_create_operation_fee_parameters", { basic_fee: uint64,
      premium_fee: uint64,
      price_per_kbyte: uint32 });
  
  var account_update_operation_fee_parameters = exports.account_update_operation_fee_parameters = new Serializer("account_update_operation_fee_parameters", { fee: int64,
      price_per_kbyte: uint32 });
  
  var account_whitelist_operation_fee_parameters = exports.account_whitelist_operation_fee_parameters = new Serializer("account_whitelist_operation_fee_parameters", { fee: int64 });
  
  var account_upgrade_operation_fee_parameters = exports.account_upgrade_operation_fee_parameters = new Serializer("account_upgrade_operation_fee_parameters", { membership_annual_fee: uint64,
      membership_lifetime_fee: uint64 });
  
  var account_transfer_operation_fee_parameters = exports.account_transfer_operation_fee_parameters = new Serializer("account_transfer_operation_fee_parameters", { fee: uint64 });
  
  var asset_create_operation_fee_parameters = exports.asset_create_operation_fee_parameters = new Serializer("asset_create_operation_fee_parameters", { symbol3: uint64,
      symbol4: uint64,
      long_symbol: uint64,
      price_per_kbyte: uint32 });
  
  var asset_update_operation_fee_parameters = exports.asset_update_operation_fee_parameters = new Serializer("asset_update_operation_fee_parameters", { fee: uint64,
      price_per_kbyte: uint32 });
  
  var asset_update_bitasset_operation_fee_parameters = exports.asset_update_bitasset_operation_fee_parameters = new Serializer("asset_update_bitasset_operation_fee_parameters", { fee: uint64 });
  
  var asset_update_feed_producers_operation_fee_parameters = exports.asset_update_feed_producers_operation_fee_parameters = new Serializer("asset_update_feed_producers_operation_fee_parameters", { fee: uint64 });
  
  var asset_issue_operation_fee_parameters = exports.asset_issue_operation_fee_parameters = new Serializer("asset_issue_operation_fee_parameters", { fee: uint64,
      price_per_kbyte: uint32 });
  
  var asset_reserve_operation_fee_parameters = exports.asset_reserve_operation_fee_parameters = new Serializer("asset_reserve_operation_fee_parameters", { fee: uint64 });
  
  var asset_fund_fee_pool_operation_fee_parameters = exports.asset_fund_fee_pool_operation_fee_parameters = new Serializer("asset_fund_fee_pool_operation_fee_parameters", { fee: uint64 });
  
  var asset_settle_operation_fee_parameters = exports.asset_settle_operation_fee_parameters = new Serializer("asset_settle_operation_fee_parameters", { fee: uint64 });
  
  var asset_global_settle_operation_fee_parameters = exports.asset_global_settle_operation_fee_parameters = new Serializer("asset_global_settle_operation_fee_parameters", { fee: uint64 });
  
  var asset_publish_feed_operation_fee_parameters = exports.asset_publish_feed_operation_fee_parameters = new Serializer("asset_publish_feed_operation_fee_parameters", { fee: uint64 });
  
  var witness_create_operation_fee_parameters = exports.witness_create_operation_fee_parameters = new Serializer("witness_create_operation_fee_parameters", { fee: uint64 });
  
  var witness_update_operation_fee_parameters = exports.witness_update_operation_fee_parameters = new Serializer("witness_update_operation_fee_parameters", { fee: int64 });
  
  var proposal_create_operation_fee_parameters = exports.proposal_create_operation_fee_parameters = new Serializer("proposal_create_operation_fee_parameters", { fee: uint64,
      price_per_kbyte: uint32 });
  
  var proposal_update_operation_fee_parameters = exports.proposal_update_operation_fee_parameters = new Serializer("proposal_update_operation_fee_parameters", { fee: uint64,
      price_per_kbyte: uint32 });
  
  var proposal_delete_operation_fee_parameters = exports.proposal_delete_operation_fee_parameters = new Serializer("proposal_delete_operation_fee_parameters", { fee: uint64 });
  
  var withdraw_permission_create_operation_fee_parameters = exports.withdraw_permission_create_operation_fee_parameters = new Serializer("withdraw_permission_create_operation_fee_parameters", { fee: uint64 });
  
  var withdraw_permission_update_operation_fee_parameters = exports.withdraw_permission_update_operation_fee_parameters = new Serializer("withdraw_permission_update_operation_fee_parameters", { fee: uint64 });
  
  var withdraw_permission_claim_operation_fee_parameters = exports.withdraw_permission_claim_operation_fee_parameters = new Serializer("withdraw_permission_claim_operation_fee_parameters", { fee: uint64,
      price_per_kbyte: uint32 });
  
  var withdraw_permission_delete_operation_fee_parameters = exports.withdraw_permission_delete_operation_fee_parameters = new Serializer("withdraw_permission_delete_operation_fee_parameters", { fee: uint64 });
  
  var committee_member_create_operation_fee_parameters = exports.committee_member_create_operation_fee_parameters = new Serializer("committee_member_create_operation_fee_parameters", { fee: uint64 });
  
  var committee_member_update_operation_fee_parameters = exports.committee_member_update_operation_fee_parameters = new Serializer("committee_member_update_operation_fee_parameters", { fee: uint64 });
  
  var committee_member_update_global_parameters_operation_fee_parameters = exports.committee_member_update_global_parameters_operation_fee_parameters = new Serializer("committee_member_update_global_parameters_operation_fee_parameters", { fee: uint64 });
  
  var vesting_balance_create_operation_fee_parameters = exports.vesting_balance_create_operation_fee_parameters = new Serializer("vesting_balance_create_operation_fee_parameters", { fee: uint64 });
  
  var vesting_balance_withdraw_operation_fee_parameters = exports.vesting_balance_withdraw_operation_fee_parameters = new Serializer("vesting_balance_withdraw_operation_fee_parameters", { fee: uint64 });
  
  var worker_create_operation_fee_parameters = exports.worker_create_operation_fee_parameters = new Serializer("worker_create_operation_fee_parameters", { fee: uint64 });
  
  var custom_operation_fee_parameters = exports.custom_operation_fee_parameters = new Serializer("custom_operation_fee_parameters", { fee: uint64,
      price_per_kbyte: uint32 });
  
  var assert_operation_fee_parameters = exports.assert_operation_fee_parameters = new Serializer("assert_operation_fee_parameters", { fee: uint64 });
  
  var balance_claim_operation_fee_parameters = exports.balance_claim_operation_fee_parameters = new Serializer("balance_claim_operation_fee_parameters");
  
  var override_transfer_operation_fee_parameters = exports.override_transfer_operation_fee_parameters = new Serializer("override_transfer_operation_fee_parameters", { fee: uint64,
      price_per_kbyte: uint32 });
  
  var transfer_to_blind_operation_fee_parameters = exports.transfer_to_blind_operation_fee_parameters = new Serializer("transfer_to_blind_operation_fee_parameters", { fee: uint64,
      price_per_output: uint32 });
  
  var blind_transfer_operation_fee_parameters = exports.blind_transfer_operation_fee_parameters = new Serializer("blind_transfer_operation_fee_parameters", { fee: uint64,
      price_per_output: uint32 });
  
  var transfer_from_blind_operation_fee_parameters = exports.transfer_from_blind_operation_fee_parameters = new Serializer("transfer_from_blind_operation_fee_parameters", { fee: uint64 });
  
  var asset_settle_cancel_operation_fee_parameters = exports.asset_settle_cancel_operation_fee_parameters = new Serializer("asset_settle_cancel_operation_fee_parameters");
  
  var asset_claim_fees_operation_fee_parameters = exports.asset_claim_fees_operation_fee_parameters = new Serializer("asset_claim_fees_operation_fee_parameters", { fee: uint64 });
  
  var fee_parameters = static_variant([transfer_operation_fee_parameters, limit_order_create_operation_fee_parameters, limit_order_cancel_operation_fee_parameters, call_order_update_operation_fee_parameters, fill_order_operation_fee_parameters, account_create_operation_fee_parameters, account_update_operation_fee_parameters, account_whitelist_operation_fee_parameters, account_upgrade_operation_fee_parameters, account_transfer_operation_fee_parameters, asset_create_operation_fee_parameters, asset_update_operation_fee_parameters, asset_update_bitasset_operation_fee_parameters, asset_update_feed_producers_operation_fee_parameters, asset_issue_operation_fee_parameters, asset_reserve_operation_fee_parameters, asset_fund_fee_pool_operation_fee_parameters, asset_settle_operation_fee_parameters, asset_global_settle_operation_fee_parameters, asset_publish_feed_operation_fee_parameters, witness_create_operation_fee_parameters, witness_update_operation_fee_parameters, proposal_create_operation_fee_parameters, proposal_update_operation_fee_parameters, proposal_delete_operation_fee_parameters, withdraw_permission_create_operation_fee_parameters, withdraw_permission_update_operation_fee_parameters, withdraw_permission_claim_operation_fee_parameters, withdraw_permission_delete_operation_fee_parameters, committee_member_create_operation_fee_parameters, committee_member_update_operation_fee_parameters, committee_member_update_global_parameters_operation_fee_parameters, vesting_balance_create_operation_fee_parameters, vesting_balance_withdraw_operation_fee_parameters, worker_create_operation_fee_parameters, custom_operation_fee_parameters, assert_operation_fee_parameters, balance_claim_operation_fee_parameters, override_transfer_operation_fee_parameters, transfer_to_blind_operation_fee_parameters, blind_transfer_operation_fee_parameters, transfer_from_blind_operation_fee_parameters, asset_settle_cancel_operation_fee_parameters, asset_claim_fees_operation_fee_parameters]);
  
  var fee_schedule = exports.fee_schedule = new Serializer("fee_schedule", { parameters: set(fee_parameters),
      scale: uint32 });
  
  var void_result = exports.void_result = new Serializer("void_result");
  
  var asset = exports.asset = new Serializer("asset", { amount: int64,
      asset_id: protocol_id_type("asset") });
  
  var operation_result = static_variant([void_result, object_id_type, asset]);
  
  var processed_transaction = exports.processed_transaction = new Serializer("processed_transaction", { ref_block_num: uint16,
      ref_block_prefix: uint32,
      expiration: time_point_sec,
      operations: array(operation),
      extensions: set(future_extensions),
      signatures: array(bytes(65)),
      operation_results: array(operation_result) });
  
  var signed_block = exports.signed_block = new Serializer("signed_block", { previous: bytes(20),
      timestamp: time_point_sec,
      witness: protocol_id_type("witness"),
      transaction_merkle_root: bytes(20),
      extensions: set(future_extensions),
      witness_signature: bytes(65),
      transactions: array(processed_transaction) });
  
  var block_header = exports.block_header = new Serializer("block_header", { previous: bytes(20),
      timestamp: time_point_sec,
      witness: protocol_id_type("witness"),
      transaction_merkle_root: bytes(20),
      extensions: set(future_extensions) });
  
  var signed_block_header = exports.signed_block_header = new Serializer("signed_block_header", { previous: bytes(20),
      timestamp: time_point_sec,
      witness: protocol_id_type("witness"),
      transaction_merkle_root: bytes(20),
      extensions: set(future_extensions),
      witness_signature: bytes(65) });
  
  var memo_data = exports.memo_data = new Serializer("memo_data", { from: public_key,
      to: public_key,
      nonce: uint64,
      message: bytes() });
  
  var transfer = exports.transfer = new Serializer("transfer", { fee: asset,
      from: protocol_id_type("account"),
      to: protocol_id_type("account"),
      amount: asset,
      memo: optional(memo_data),
      extensions: set(future_extensions) });
  
  var limit_order_create = exports.limit_order_create = new Serializer("limit_order_create", { fee: asset,
      seller: protocol_id_type("account"),
      amount_to_sell: asset,
      min_to_receive: asset,
      expiration: time_point_sec,
      fill_or_kill: bool,
      extensions: set(future_extensions) });
  
  var limit_order_cancel = exports.limit_order_cancel = new Serializer("limit_order_cancel", { fee: asset,
      fee_paying_account: protocol_id_type("account"),
      order: protocol_id_type("limit_order"),
      extensions: set(future_extensions) });
  
  var call_order_update = exports.call_order_update = new Serializer("call_order_update", { fee: asset,
      funding_account: protocol_id_type("account"),
      delta_collateral: asset,
      delta_debt: asset,
      extensions: set(future_extensions) });
  
  var fill_order = exports.fill_order = new Serializer("fill_order", { fee: asset,
      order_id: object_id_type,
      account_id: protocol_id_type("account"),
      pays: asset,
      receives: asset });
  
  var authority = exports.authority = new Serializer("authority", { weight_threshold: uint32,
      account_auths: map(protocol_id_type("account"), uint16),
      key_auths: map(public_key, uint16),
      address_auths: map(address, uint16) });
  
  var account_options = exports.account_options = new Serializer("account_options", { memo_key: public_key,
      voting_account: protocol_id_type("account"),
      num_witness: uint16,
      num_committee: uint16,
      votes: set(vote_id),
      extensions: set(future_extensions) });
  
  var account_create = exports.account_create = new Serializer("account_create", { fee: asset,
      registrar: protocol_id_type("account"),
      referrer: protocol_id_type("account"),
      referrer_percent: uint16,
      name: string,
      owner: authority,
      active: authority,
      options: account_options,
      extensions: set(future_extensions) });
  
  var account_update = exports.account_update = new Serializer("account_update", { fee: asset,
      account: protocol_id_type("account"),
      owner: optional(authority),
      active: optional(authority),
      new_options: optional(account_options),
      extensions: set(future_extensions) });
  
  var account_whitelist = exports.account_whitelist = new Serializer("account_whitelist", { fee: asset,
      authorizing_account: protocol_id_type("account"),
      account_to_list: protocol_id_type("account"),
      new_listing: uint8,
      extensions: set(future_extensions) });
  
  var account_upgrade = exports.account_upgrade = new Serializer("account_upgrade", { fee: asset,
      account_to_upgrade: protocol_id_type("account"),
      upgrade_to_lifetime_member: bool,
      extensions: set(future_extensions) });
  
  var account_transfer = exports.account_transfer = new Serializer("account_transfer", { fee: asset,
      account_id: protocol_id_type("account"),
      new_owner: protocol_id_type("account"),
      extensions: set(future_extensions) });
  
  var price = exports.price = new Serializer("price", { base: asset,
      quote: asset });
  
  var asset_options = exports.asset_options = new Serializer("asset_options", { max_supply: int64,
      market_fee_percent: uint16,
      max_market_fee: int64,
      issuer_permissions: uint16,
      flags: uint16,
      core_exchange_rate: price,
      whitelist_authorities: set(protocol_id_type("account")),
      blacklist_authorities: set(protocol_id_type("account")),
      whitelist_markets: set(protocol_id_type("asset")),
      blacklist_markets: set(protocol_id_type("asset")),
      description: string,
      extensions: set(future_extensions) });
  
  var bitasset_options = exports.bitasset_options = new Serializer("bitasset_options", { feed_lifetime_sec: uint32,
      minimum_feeds: uint8,
      force_settlement_delay_sec: uint32,
      force_settlement_offset_percent: uint16,
      maximum_force_settlement_volume: uint16,
      short_backing_asset: protocol_id_type("asset"),
      extensions: set(future_extensions) });
  
  var asset_create = exports.asset_create = new Serializer("asset_create", { fee: asset,
      issuer: protocol_id_type("account"),
      symbol: string,
      precision: uint8,
      common_options: asset_options,
      bitasset_opts: optional(bitasset_options),
      is_prediction_market: bool,
      extensions: set(future_extensions) });
  
  var asset_update = exports.asset_update = new Serializer("asset_update", { fee: asset,
      issuer: protocol_id_type("account"),
      asset_to_update: protocol_id_type("asset"),
      new_issuer: optional(protocol_id_type("account")),
      new_options: asset_options,
      extensions: set(future_extensions) });
  
  var asset_update_bitasset = exports.asset_update_bitasset = new Serializer("asset_update_bitasset", { fee: asset,
      issuer: protocol_id_type("account"),
      asset_to_update: protocol_id_type("asset"),
      new_options: bitasset_options,
      extensions: set(future_extensions) });
  
  var asset_update_feed_producers = exports.asset_update_feed_producers = new Serializer("asset_update_feed_producers", { fee: asset,
      issuer: protocol_id_type("account"),
      asset_to_update: protocol_id_type("asset"),
      new_feed_producers: set(protocol_id_type("account")),
      extensions: set(future_extensions) });
  
  var asset_issue = exports.asset_issue = new Serializer("asset_issue", { fee: asset,
      issuer: protocol_id_type("account"),
      asset_to_issue: asset,
      issue_to_account: protocol_id_type("account"),
      memo: optional(memo_data),
      extensions: set(future_extensions) });
  
  var asset_reserve = exports.asset_reserve = new Serializer("asset_reserve", { fee: asset,
      payer: protocol_id_type("account"),
      amount_to_reserve: asset,
      extensions: set(future_extensions) });
  
  var asset_fund_fee_pool = exports.asset_fund_fee_pool = new Serializer("asset_fund_fee_pool", { fee: asset,
      from_account: protocol_id_type("account"),
      asset_id: protocol_id_type("asset"),
      amount: int64,
      extensions: set(future_extensions) });
  
  var asset_settle = exports.asset_settle = new Serializer("asset_settle", { fee: asset,
      account: protocol_id_type("account"),
      amount: asset,
      extensions: set(future_extensions) });
  
  var asset_global_settle = exports.asset_global_settle = new Serializer("asset_global_settle", { fee: asset,
      issuer: protocol_id_type("account"),
      asset_to_settle: protocol_id_type("asset"),
      settle_price: price,
      extensions: set(future_extensions) });
  
  var price_feed = exports.price_feed = new Serializer("price_feed", { settlement_price: price,
      maintenance_collateral_ratio: uint16,
      maximum_short_squeeze_ratio: uint16,
      core_exchange_rate: price });
  
  var asset_publish_feed = exports.asset_publish_feed = new Serializer("asset_publish_feed", { fee: asset,
      publisher: protocol_id_type("account"),
      asset_id: protocol_id_type("asset"),
      feed: price_feed,
      extensions: set(future_extensions) });
  
  var witness_create = exports.witness_create = new Serializer("witness_create", { fee: asset,
      witness_account: protocol_id_type("account"),
      url: string,
      block_signing_key: public_key });
  
  var witness_update = exports.witness_update = new Serializer("witness_update", { fee: asset,
      witness: protocol_id_type("witness"),
      witness_account: protocol_id_type("account"),
      new_url: optional(string),
      new_signing_key: optional(public_key) });
  
  var op_wrapper = exports.op_wrapper = new Serializer("op_wrapper", { op: operation });
  
  var proposal_create = exports.proposal_create = new Serializer("proposal_create", { fee: asset,
      fee_paying_account: protocol_id_type("account"),
      expiration_time: time_point_sec,
      proposed_ops: array(op_wrapper),
      review_period_seconds: optional(uint32),
      extensions: set(future_extensions) });
  
  var proposal_update = exports.proposal_update = new Serializer("proposal_update", { fee: asset,
      fee_paying_account: protocol_id_type("account"),
      proposal: protocol_id_type("proposal"),
      active_approvals_to_add: set(protocol_id_type("account")),
      active_approvals_to_remove: set(protocol_id_type("account")),
      owner_approvals_to_add: set(protocol_id_type("account")),
      owner_approvals_to_remove: set(protocol_id_type("account")),
      key_approvals_to_add: set(public_key),
      key_approvals_to_remove: set(public_key),
      extensions: set(future_extensions) });
  
  var proposal_delete = exports.proposal_delete = new Serializer("proposal_delete", { fee: asset,
      fee_paying_account: protocol_id_type("account"),
      using_owner_authority: bool,
      proposal: protocol_id_type("proposal"),
      extensions: set(future_extensions) });
  
  var withdraw_permission_create = exports.withdraw_permission_create = new Serializer("withdraw_permission_create", { fee: asset,
      withdraw_from_account: protocol_id_type("account"),
      authorized_account: protocol_id_type("account"),
      withdrawal_limit: asset,
      withdrawal_period_sec: uint32,
      periods_until_expiration: uint32,
      period_start_time: time_point_sec });
  
  var withdraw_permission_update = exports.withdraw_permission_update = new Serializer("withdraw_permission_update", { fee: asset,
      withdraw_from_account: protocol_id_type("account"),
      authorized_account: protocol_id_type("account"),
      permission_to_update: protocol_id_type("withdraw_permission"),
      withdrawal_limit: asset,
      withdrawal_period_sec: uint32,
      period_start_time: time_point_sec,
      periods_until_expiration: uint32 });
  
  var withdraw_permission_claim = exports.withdraw_permission_claim = new Serializer("withdraw_permission_claim", { fee: asset,
      withdraw_permission: protocol_id_type("withdraw_permission"),
      withdraw_from_account: protocol_id_type("account"),
      withdraw_to_account: protocol_id_type("account"),
      amount_to_withdraw: asset,
      memo: optional(memo_data) });
  
  var withdraw_permission_delete = exports.withdraw_permission_delete = new Serializer("withdraw_permission_delete", { fee: asset,
      withdraw_from_account: protocol_id_type("account"),
      authorized_account: protocol_id_type("account"),
      withdrawal_permission: protocol_id_type("withdraw_permission") });
  
  var committee_member_create = exports.committee_member_create = new Serializer("committee_member_create", { fee: asset,
      committee_member_account: protocol_id_type("account"),
      url: string });
  
  var committee_member_update = exports.committee_member_update = new Serializer("committee_member_update", { fee: asset,
      committee_member: protocol_id_type("committee_member"),
      committee_member_account: protocol_id_type("account"),
      new_url: optional(string) });
  
  var chain_parameters = exports.chain_parameters = new Serializer("chain_parameters", { current_fees: fee_schedule,
      block_interval: uint8,
      maintenance_interval: uint32,
      maintenance_skip_slots: uint8,
      committee_proposal_review_period: uint32,
      maximum_transaction_size: uint32,
      maximum_block_size: uint32,
      maximum_time_until_expiration: uint32,
      maximum_proposal_lifetime: uint32,
      maximum_asset_whitelist_authorities: uint8,
      maximum_asset_feed_publishers: uint8,
      maximum_witness_count: uint16,
      maximum_committee_count: uint16,
      maximum_authority_membership: uint16,
      reserve_percent_of_fee: uint16,
      network_percent_of_fee: uint16,
      lifetime_referrer_percent_of_fee: uint16,
      cashback_vesting_period_seconds: uint32,
      cashback_vesting_threshold: int64,
      count_non_member_votes: bool,
      allow_non_member_whitelists: bool,
      witness_pay_per_block: int64,
      worker_budget_per_day: int64,
      max_predicate_opcode: uint16,
      fee_liquidation_threshold: int64,
      accounts_per_fee_scale: uint16,
      account_fee_scale_bitshifts: uint8,
      max_authority_depth: uint8,
      extensions: set(future_extensions) });
  
  var committee_member_update_global_parameters = exports.committee_member_update_global_parameters = new Serializer("committee_member_update_global_parameters", { fee: asset,
      new_parameters: chain_parameters });
  
  var linear_vesting_policy_initializer = exports.linear_vesting_policy_initializer = new Serializer("linear_vesting_policy_initializer", { begin_timestamp: time_point_sec,
      vesting_cliff_seconds: uint32,
      vesting_duration_seconds: uint32 });
  
  var cdd_vesting_policy_initializer = exports.cdd_vesting_policy_initializer = new Serializer("cdd_vesting_policy_initializer", { start_claim: time_point_sec,
      vesting_seconds: uint32 });
  
  var vesting_policy_initializer = static_variant([linear_vesting_policy_initializer, cdd_vesting_policy_initializer]);
  
  var vesting_balance_create = exports.vesting_balance_create = new Serializer("vesting_balance_create", { fee: asset,
      creator: protocol_id_type("account"),
      owner: protocol_id_type("account"),
      amount: asset,
      policy: vesting_policy_initializer });
  
  var vesting_balance_withdraw = exports.vesting_balance_withdraw = new Serializer("vesting_balance_withdraw", { fee: asset,
      vesting_balance: protocol_id_type("vesting_balance"),
      owner: protocol_id_type("account"),
      amount: asset });
  
  var refund_worker_initializer = exports.refund_worker_initializer = new Serializer("refund_worker_initializer");
  
  var vesting_balance_worker_initializer = exports.vesting_balance_worker_initializer = new Serializer("vesting_balance_worker_initializer", { pay_vesting_period_days: uint16 });
  
  var burn_worker_initializer = exports.burn_worker_initializer = new Serializer("burn_worker_initializer");
  
  var worker_initializer = static_variant([refund_worker_initializer, vesting_balance_worker_initializer, burn_worker_initializer]);
  
  var worker_create = exports.worker_create = new Serializer("worker_create", { fee: asset,
      owner: protocol_id_type("account"),
      work_begin_date: time_point_sec,
      work_end_date: time_point_sec,
      daily_pay: int64,
      name: string,
      url: string,
      initializer: worker_initializer });
  
  var custom = exports.custom = new Serializer("custom", { fee: asset,
      payer: protocol_id_type("account"),
      required_auths: set(protocol_id_type("account")),
      id: uint16,
      data: bytes() });
  
  var account_name_eq_lit_predicate = exports.account_name_eq_lit_predicate = new Serializer("account_name_eq_lit_predicate", { account_id: protocol_id_type("account"),
      name: string });
  
  var asset_symbol_eq_lit_predicate = exports.asset_symbol_eq_lit_predicate = new Serializer("asset_symbol_eq_lit_predicate", { asset_id: protocol_id_type("asset"),
      symbol: string });
  
  var block_id_predicate = exports.block_id_predicate = new Serializer("block_id_predicate", { id: bytes(20) });
  
  var predicate = static_variant([account_name_eq_lit_predicate, asset_symbol_eq_lit_predicate, block_id_predicate]);
  
  var assert = exports.assert = new Serializer("assert", { fee: asset,
      fee_paying_account: protocol_id_type("account"),
      predicates: array(predicate),
      required_auths: set(protocol_id_type("account")),
      extensions: set(future_extensions) });
  
  var balance_claim = exports.balance_claim = new Serializer("balance_claim", { fee: asset,
      deposit_to_account: protocol_id_type("account"),
      balance_to_claim: protocol_id_type("balance"),
      balance_owner_key: public_key,
      total_claimed: asset });
  
  var override_transfer = exports.override_transfer = new Serializer("override_transfer", { fee: asset,
      issuer: protocol_id_type("account"),
      from: protocol_id_type("account"),
      to: protocol_id_type("account"),
      amount: asset,
      memo: optional(memo_data),
      extensions: set(future_extensions) });
  
  var stealth_confirmation = exports.stealth_confirmation = new Serializer("stealth_confirmation", { one_time_key: public_key,
      to: optional(public_key),
      encrypted_memo: bytes() });
  
  var blind_output = exports.blind_output = new Serializer("blind_output", { commitment: bytes(33),
      range_proof: bytes(),
      owner: authority,
      stealth_memo: optional(stealth_confirmation) });
  
  var transfer_to_blind = exports.transfer_to_blind = new Serializer("transfer_to_blind", { fee: asset,
      amount: asset,
      from: protocol_id_type("account"),
      blinding_factor: bytes(32),
      outputs: array(blind_output) });
  
  var blind_input = exports.blind_input = new Serializer("blind_input", { commitment: bytes(33),
      owner: authority });
  
  var blind_transfer = exports.blind_transfer = new Serializer("blind_transfer", { fee: asset,
      inputs: array(blind_input),
      outputs: array(blind_output) });
  
  var transfer_from_blind = exports.transfer_from_blind = new Serializer("transfer_from_blind", { fee: asset,
      amount: asset,
      to: protocol_id_type("account"),
      blinding_factor: bytes(32),
      inputs: array(blind_input) });
  
  var asset_settle_cancel = exports.asset_settle_cancel = new Serializer("asset_settle_cancel", { fee: asset,
      settlement: protocol_id_type("force_settlement"),
      account: protocol_id_type("account"),
      amount: asset,
      extensions: set(future_extensions) });
  
  var asset_claim_fees = exports.asset_claim_fees = new Serializer("asset_claim_fees", { fee: asset,
      issuer: protocol_id_type("account"),
      amount_to_claim: asset,
      extensions: set(future_extensions) });
  
  operation.st_operations = [transfer, limit_order_create, limit_order_cancel, call_order_update, fill_order, account_create, account_update, account_whitelist, account_upgrade, account_transfer, asset_create, asset_update, asset_update_bitasset, asset_update_feed_producers, asset_issue, asset_reserve, asset_fund_fee_pool, asset_settle, asset_global_settle, asset_publish_feed, witness_create, witness_update, proposal_create, proposal_update, proposal_delete, withdraw_permission_create, withdraw_permission_update, withdraw_permission_claim, withdraw_permission_delete, committee_member_create, committee_member_update, committee_member_update_global_parameters, vesting_balance_create, vesting_balance_withdraw, worker_create, custom, assert, balance_claim, override_transfer, transfer_to_blind, blind_transfer, transfer_from_blind, asset_settle_cancel, asset_claim_fees];
  
  var transaction = exports.transaction = new Serializer("transaction", { ref_block_num: uint16,
      ref_block_prefix: uint32,
      expiration: time_point_sec,
      operations: array(operation),
      extensions: set(future_extensions) });
  
  var signed_transaction = exports.signed_transaction = new Serializer("signed_transaction", { ref_block_num: uint16,
      ref_block_prefix: uint32,
      expiration: time_point_sec,
      operations: array(operation),
      extensions: set(future_extensions),
      signatures: array(bytes(65)) });
  //# -------------------------------
  //#  Generated code end
  //# -------------------------------
  
  // Custom Types
  
  var stealth_memo_data = exports.stealth_memo_data = new Serializer("stealth_memo_data", {
      from: optional(public_key),
      amount: asset,
      blinding_factor: bytes(32),
      commitment: bytes(33),
      check: uint32
  });
  // var stealth_confirmation = new Serializer(
  //     "stealth_confirmation", {
  //     one_time_key: public_key,
  //     to: optional( public_key ),
  //     encrypted_memo: stealth_memo_data
  // })
  },{"./serializer":36,"./types":38}],36:[function(require,module,exports){
  (function (process,Buffer){
  'use strict';
  
  exports.__esModule = true;
  
  var _bytebuffer = require('bytebuffer');
  
  var _bytebuffer2 = _interopRequireDefault(_bytebuffer);
  
  var _error_with_cause = require('./error_with_cause');
  
  var _error_with_cause2 = _interopRequireDefault(_error_with_cause);
  
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  
  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  
  var HEX_DUMP = process.env.npm_config__graphene_serializer_hex_dump;
  
  var Serializer = function () {
      function Serializer(operation_name, types) {
          _classCallCheck(this, Serializer);
  
          this.operation_name = operation_name;
          this.types = types;
          if (this.types) this.keys = Object.keys(this.types);
  
          Serializer.printDebug = true;
      }
  
      Serializer.prototype.fromByteBuffer = function fromByteBuffer(b) {
          var object = {};
          var field = null;
          try {
              var iterable = this.keys;
              for (var i = 0, field; i < iterable.length; i++) {
                  field = iterable[i];
                  var type = this.types[field];
                  try {
                      if (HEX_DUMP) {
                          if (type.operation_name) {
                              console.error(type.operation_name);
                          } else {
                              var o1 = b.offset;
                              type.fromByteBuffer(b);
                              var o2 = b.offset;
                              b.offset = o1;
                              //b.reset()
                              var _b = b.copy(o1, o2);
                              console.error(this.operation_name + '.' + field + '\t', _b.toHex());
                          }
                      }
                      object[field] = type.fromByteBuffer(b);
                  } catch (e) {
                      if (Serializer.printDebug) {
                          console.error('Error reading ' + this.operation_name + '.' + field + ' in data:');
                          b.printDebug();
                      }
                      throw e;
                  }
              }
          } catch (error) {
              _error_with_cause2.default.throw(this.operation_name + '.' + field, error);
          }
  
          return object;
      };
  
      Serializer.prototype.appendByteBuffer = function appendByteBuffer(b, object) {
          var field = null;
          try {
              var iterable = this.keys;
              for (var i = 0, field; i < iterable.length; i++) {
                  field = iterable[i];
                  var type = this.types[field];
                  type.appendByteBuffer(b, object[field]);
              }
          } catch (error) {
              try {
                  _error_with_cause2.default.throw(this.operation_name + '.' + field + " = " + JSON.stringify(object[field]), error);
              } catch (e) {
                  // circular ref
                  _error_with_cause2.default.throw(this.operation_name + '.' + field + " = " + object[field], error);
              }
          }
          return;
      };
  
      Serializer.prototype.fromObject = function fromObject(serialized_object) {
          var result = {};
          var field = null;
          try {
              var iterable = this.keys;
              for (var i = 0, field; i < iterable.length; i++) {
                  field = iterable[i];
                  var type = this.types[field];
                  var value = serialized_object[field];
                  //DEBUG value = value.resolve if value.resolve
                  //DEBUG console.log('... value',field,value)
                  var object = type.fromObject(value);
                  result[field] = object;
              }
          } catch (error) {
              _error_with_cause2.default.throw(this.operation_name + '.' + field, error);
          }
  
          return result;
      };
  
      /**
          @arg {boolean} [debug.use_default = false] - more template friendly
          @arg {boolean} [debug.annotate = false] - add user-friendly information
      */
  
  
      Serializer.prototype.toObject = function toObject() {
          var serialized_object = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
          var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : { use_default: false, annotate: false };
  
          var result = {};
          var field = null;
          try {
              if (!this.types) return result;
  
              var iterable = this.keys;
              for (var i = 0, field; i < iterable.length; i++) {
                  field = iterable[i];
                  var type = this.types[field];
                  var object = type.toObject(typeof serialized_object !== "undefined" && serialized_object !== null ? serialized_object[field] : undefined, debug);
                  result[field] = object;
                  if (HEX_DUMP) {
                      var b = new _bytebuffer2.default(_bytebuffer2.default.DEFAULT_CAPACITY, _bytebuffer2.default.LITTLE_ENDIAN);
                      type.appendByteBuffer(b, typeof serialized_object !== "undefined" && serialized_object !== null ? serialized_object[field] : undefined);
                      b = b.copy(0, b.offset);
                      console.error(this.operation_name + '.' + field, b.toHex());
                  }
              }
          } catch (error) {
              _error_with_cause2.default.throw(this.operation_name + '.' + field, error);
          }
  
          return result;
      };
  
      /** Sort by the first element in a operation */
  
  
      Serializer.prototype.compare = function compare(a, b) {
  
          var first_key = this.keys[0];
          var first_type = this.types[first_key];
  
          var valA = a[first_key];
          var valB = b[first_key];
  
          if (first_type.compare) return first_type.compare(valA, valB);
  
          if (typeof valA === "number" && typeof valB === "number") return valA - valB;
  
          var encoding = void 0;
          if (Buffer.isBuffer(valA) && Buffer.isBuffer(valB)) {
              // A binary string compare does not work.  If localeCompare is well supported that could replace HEX.  Performanance is very good so comparing HEX works.
              encoding = "hex";
          }
  
          var strA = valA.toString(encoding);
          var strB = valB.toString(encoding);
          return strA > strB ? 1 : strA < strB ? -1 : 0;
      };
  
      // <helper_functions>
  
      Serializer.prototype.fromHex = function fromHex(hex) {
          var b = _bytebuffer2.default.fromHex(hex, _bytebuffer2.default.LITTLE_ENDIAN);
          return this.fromByteBuffer(b);
      };
  
      Serializer.prototype.fromBuffer = function fromBuffer(buffer) {
          var b = _bytebuffer2.default.fromBinary(buffer.toString("binary"), _bytebuffer2.default.LITTLE_ENDIAN);
          return this.fromByteBuffer(b);
      };
  
      Serializer.prototype.toHex = function toHex(object) {
          // return this.toBuffer(object).toString("hex")
          var b = this.toByteBuffer(object);
          return b.toHex();
      };
  
      Serializer.prototype.toByteBuffer = function toByteBuffer(object) {
          var b = new _bytebuffer2.default(_bytebuffer2.default.DEFAULT_CAPACITY, _bytebuffer2.default.LITTLE_ENDIAN);
          this.appendByteBuffer(b, object);
          return b.copy(0, b.offset);
      };
  
      Serializer.prototype.toBuffer = function toBuffer(object) {
          return new Buffer(this.toByteBuffer(object).toBinary(), 'binary');
      };
  
      return Serializer;
  }();
  
  exports.default = Serializer;
  module.exports = exports['default'];
  }).call(this,require('_process'),require("buffer").Buffer)
  },{"./error_with_cause":34,"_process":87,"buffer":79,"bytebuffer":40}],37:[function(require,module,exports){
  "use strict";
  
  exports.__esModule = true;
  exports.default = template;
  
  /** Console print any transaction object with zero default values. */
  function template(op) {
  
      var object = op.toObject(void 0, { use_default: true, annotate: true });
  
      // visual (with descriptions)
      console.error(JSON.stringify(object, null, 4));
  
      // usable in a copy-paste
  
      object = op.toObject(void 0, { use_default: true, annotate: false });
  
      // copy-paste one-lineer
      console.error(JSON.stringify(object));
  }
  module.exports = exports["default"];
  },{}],38:[function(require,module,exports){
  (function (process,Buffer){
  'use strict';
  
  exports.__esModule = true;
  
  var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
  
  // Low-level types that make up operations
  
  var _SerializerValidation = require('./SerializerValidation');
  
  var _SerializerValidation2 = _interopRequireDefault(_SerializerValidation);
  
  var _FastParser = require('./FastParser');
  
  var _FastParser2 = _interopRequireDefault(_FastParser);
  
  var _ChainTypes = require('../../chain/src/ChainTypes');
  
  var _ChainTypes2 = _interopRequireDefault(_ChainTypes);
  
  var _ObjectId = require('../../chain/src/ObjectId');
  
  var _ObjectId2 = _interopRequireDefault(_ObjectId);
  
  var _ecc = require('../../ecc');
  
  var _bitsharesjsWs = require('bitsharesjs-ws');
  
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  
  var Types = {};
  
  var HEX_DUMP = process.env.npm_config__graphene_serializer_hex_dump;
  
  Types.uint8 = {
      fromByteBuffer: function fromByteBuffer(b) {
          return b.readUint8();
      },
      appendByteBuffer: function appendByteBuffer(b, object) {
          _SerializerValidation2.default.require_range(0, 0xFF, object, 'uint8 ' + object);
          b.writeUint8(object);
          return;
      },
      fromObject: function fromObject(object) {
          _SerializerValidation2.default.require_range(0, 0xFF, object, 'uint8 ' + object);
          return object;
      },
      toObject: function toObject(object) {
          var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  
          if (debug.use_default && object === undefined) {
              return 0;
          }
          _SerializerValidation2.default.require_range(0, 0xFF, object, 'uint8 ' + object);
          return parseInt(object);
      }
  };
  
  Types.uint16 = {
      fromByteBuffer: function fromByteBuffer(b) {
          return b.readUint16();
      },
      appendByteBuffer: function appendByteBuffer(b, object) {
          _SerializerValidation2.default.require_range(0, 0xFFFF, object, 'uint16 ' + object);
          b.writeUint16(object);
          return;
      },
      fromObject: function fromObject(object) {
          _SerializerValidation2.default.require_range(0, 0xFFFF, object, 'uint16 ' + object);
          return object;
      },
      toObject: function toObject(object) {
          var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  
          if (debug.use_default && object === undefined) {
              return 0;
          }
          _SerializerValidation2.default.require_range(0, 0xFFFF, object, 'uint16 ' + object);
          return parseInt(object);
      }
  };
  
  Types.uint32 = {
      fromByteBuffer: function fromByteBuffer(b) {
          return b.readUint32();
      },
      appendByteBuffer: function appendByteBuffer(b, object) {
          _SerializerValidation2.default.require_range(0, 0xFFFFFFFF, object, 'uint32 ' + object);
          b.writeUint32(object);
          return;
      },
      fromObject: function fromObject(object) {
          _SerializerValidation2.default.require_range(0, 0xFFFFFFFF, object, 'uint32 ' + object);
          return object;
      },
      toObject: function toObject(object) {
          var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  
          if (debug.use_default && object === undefined) {
              return 0;
          }
          _SerializerValidation2.default.require_range(0, 0xFFFFFFFF, object, 'uint32 ' + object);
          return parseInt(object);
      }
  };
  
  var MIN_SIGNED_32 = -1 * Math.pow(2, 31);
  var MAX_SIGNED_32 = Math.pow(2, 31) - 1;
  
  Types.varint32 = {
      fromByteBuffer: function fromByteBuffer(b) {
          return b.readVarint32();
      },
      appendByteBuffer: function appendByteBuffer(b, object) {
          _SerializerValidation2.default.require_range(MIN_SIGNED_32, MAX_SIGNED_32, object, 'uint32 ' + object);
          b.writeVarint32(object);
          return;
      },
      fromObject: function fromObject(object) {
          _SerializerValidation2.default.require_range(MIN_SIGNED_32, MAX_SIGNED_32, object, 'uint32 ' + object);
          return object;
      },
      toObject: function toObject(object) {
          var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  
          if (debug.use_default && object === undefined) {
              return 0;
          }
          _SerializerValidation2.default.require_range(MIN_SIGNED_32, MAX_SIGNED_32, object, 'uint32 ' + object);
          return parseInt(object);
      }
  };
  
  Types.int64 = {
      fromByteBuffer: function fromByteBuffer(b) {
          return b.readInt64();
      },
      appendByteBuffer: function appendByteBuffer(b, object) {
          _SerializerValidation2.default.required(object);
          b.writeInt64(_SerializerValidation2.default.to_long(object));
          return;
      },
      fromObject: function fromObject(object) {
          _SerializerValidation2.default.required(object);
          return _SerializerValidation2.default.to_long(object);
      },
      toObject: function toObject(object) {
          var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  
          if (debug.use_default && object === undefined) {
              return "0";
          }
          _SerializerValidation2.default.required(object);
          return _SerializerValidation2.default.to_long(object).toString();
      }
  };
  
  Types.uint64 = {
      fromByteBuffer: function fromByteBuffer(b) {
          return b.readUint64();
      },
      appendByteBuffer: function appendByteBuffer(b, object) {
          b.writeUint64(_SerializerValidation2.default.to_long(_SerializerValidation2.default.unsigned(object)));
          return;
      },
      fromObject: function fromObject(object) {
          return _SerializerValidation2.default.to_long(_SerializerValidation2.default.unsigned(object));
      },
      toObject: function toObject(object) {
          var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  
          if (debug.use_default && object === undefined) {
              return "0";
          }
          return _SerializerValidation2.default.to_long(object).toString();
      }
  };
  
  Types.string = {
      fromByteBuffer: function fromByteBuffer(b) {
          var b_copy;
          var len = b.readVarint32();
          b_copy = b.copy(b.offset, b.offset + len), b.skip(len);
          return new Buffer(b_copy.toBinary(), 'binary');
      },
      appendByteBuffer: function appendByteBuffer(b, object) {
          _SerializerValidation2.default.required(object);
          b.writeVarint32(object.length);
          b.append(object.toString('binary'), 'binary');
          return;
      },
      fromObject: function fromObject(object) {
          _SerializerValidation2.default.required(object);
          return new Buffer(object);
      },
      toObject: function toObject(object) {
          var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  
          if (debug.use_default && object === undefined) {
              return "";
          }
          return object.toString();
      }
  };
  
  Types.bytes = function (size) {
      return {
          fromByteBuffer: function fromByteBuffer(b) {
              if (size === undefined) {
                  var b_copy;
                  var len = b.readVarint32();
                  b_copy = b.copy(b.offset, b.offset + len), b.skip(len);
                  return new Buffer(b_copy.toBinary(), 'binary');
              } else {
                  b_copy = b.copy(b.offset, b.offset + size), b.skip(size);
                  return new Buffer(b_copy.toBinary(), 'binary');
              }
          },
          appendByteBuffer: function appendByteBuffer(b, object) {
              _SerializerValidation2.default.required(object);
              if (typeof object === "string") object = new Buffer(object, "hex");
  
              if (size === undefined) {
                  b.writeVarint32(object.length);
              }
              b.append(object.toString('binary'), 'binary');
              return;
          },
          fromObject: function fromObject(object) {
              _SerializerValidation2.default.required(object);
              if (Buffer.isBuffer(object)) return object;
  
              return new Buffer(object, 'hex');
          },
          toObject: function toObject(object) {
              var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  
              if (debug.use_default && object === undefined) {
                  var zeros = function zeros(num) {
                      return new Array(num).join("00");
                  };
                  return zeros(size);
              }
              _SerializerValidation2.default.required(object);
              return object.toString('hex');
          }
      };
  };
  
  Types.bool = {
      fromByteBuffer: function fromByteBuffer(b) {
          return b.readUint8() === 1;
      },
      appendByteBuffer: function appendByteBuffer(b, object) {
          // supports boolean or integer
          b.writeUint8(JSON.parse(object) ? 1 : 0);
          return;
      },
      fromObject: function fromObject(object) {
          return JSON.parse(object) ? true : false;
      },
      toObject: function toObject(object) {
          var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  
          if (debug.use_default && object === undefined) {
              return false;
          }
          return JSON.parse(object) ? true : false;
      }
  };
  
  Types.void = {
      fromByteBuffer: function fromByteBuffer(b) {
          throw new Error("(void) undefined type");
      },
      appendByteBuffer: function appendByteBuffer(b, object) {
          throw new Error("(void) undefined type");
      },
      fromObject: function fromObject(object) {
          throw new Error("(void) undefined type");
      },
      toObject: function toObject(object) {
          var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  
          if (debug.use_default && object === undefined) {
              return undefined;
          }
          throw new Error("(void) undefined type");
      }
  };
  
  Types.array = function (st_operation) {
      return {
          fromByteBuffer: function fromByteBuffer(b) {
              var size = b.readVarint32();
              if (HEX_DUMP) {
                  console.log("varint32 size = " + size.toString(16));
              }
              var result = [];
              for (var i = 0; 0 < size ? i < size : i > size; 0 < size ? i++ : i++) {
                  result.push(st_operation.fromByteBuffer(b));
              }
              return sortOperation(result, st_operation);
          },
          appendByteBuffer: function appendByteBuffer(b, object) {
              _SerializerValidation2.default.required(object);
              object = sortOperation(object, st_operation);
              b.writeVarint32(object.length);
              for (var i = 0, o; i < object.length; i++) {
                  o = object[i];
                  st_operation.appendByteBuffer(b, o);
              }
          },
          fromObject: function fromObject(object) {
              _SerializerValidation2.default.required(object);
              object = sortOperation(object, st_operation);
              var result = [];
              for (var i = 0, o; i < object.length; i++) {
                  o = object[i];
                  result.push(st_operation.fromObject(o));
              }
              return result;
          },
          toObject: function toObject(object) {
              var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  
              if (debug.use_default && object === undefined) {
                  return [st_operation.toObject(object, debug)];
              }
              _SerializerValidation2.default.required(object);
              object = sortOperation(object, st_operation);
  
              var result = [];
              for (var i = 0, o; i < object.length; i++) {
                  o = object[i];
                  result.push(st_operation.toObject(o, debug));
              }
              return result;
          }
      };
  };
  
  Types.time_point_sec = {
      fromByteBuffer: function fromByteBuffer(b) {
          return b.readUint32();
      },
      appendByteBuffer: function appendByteBuffer(b, object) {
          if (typeof object !== "number") object = Types.time_point_sec.fromObject(object);
  
          b.writeUint32(object);
          return;
      },
      fromObject: function fromObject(object) {
          _SerializerValidation2.default.required(object);
  
          if (typeof object === "number") return object;
  
          if (object.getTime) return Math.floor(object.getTime() / 1000);
  
          if (typeof object !== "string") throw new Error("Unknown date type: " + object);
  
          // if(typeof object === "string" && !/Z$/.test(object))
          //     object = object + "Z"
  
          return Math.floor(new Date(object).getTime() / 1000);
      },
      toObject: function toObject(object) {
          var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  
          if (debug.use_default && object === undefined) return new Date(0).toISOString().split('.')[0];
  
          _SerializerValidation2.default.required(object);
  
          if (typeof object === "string") return object;
  
          if (object.getTime) return object.toISOString().split('.')[0];
  
          var int = parseInt(object);
          _SerializerValidation2.default.require_range(0, 0xFFFFFFFF, int, 'uint32 ' + object);
          return new Date(int * 1000).toISOString().split('.')[0];
      }
  };
  
  Types.set = function (st_operation) {
      return {
          validate: function validate(array) {
              var dup_map = {};
              for (var i = 0, o; i < array.length; i++) {
                  o = array[i];
                  var ref;
                  if (ref = typeof o === 'undefined' ? 'undefined' : _typeof(o), ['string', 'number'].indexOf(ref) >= 0) {
                      if (dup_map[o] !== undefined) {
                          throw new Error("duplicate (set)");
                      }
                      dup_map[o] = true;
                  }
              }
              return sortOperation(array, st_operation);
          },
          fromByteBuffer: function fromByteBuffer(b) {
              var size = b.readVarint32();
              if (HEX_DUMP) {
                  console.log("varint32 size = " + size.toString(16));
              }
              return this.validate(function () {
                  var result = [];
                  for (var i = 0; 0 < size ? i < size : i > size; 0 < size ? i++ : i++) {
                      result.push(st_operation.fromByteBuffer(b));
                  }
                  return result;
              }());
          },
          appendByteBuffer: function appendByteBuffer(b, object) {
              if (!object) {
                  object = [];
              }
              b.writeVarint32(object.length);
              var iterable = this.validate(object);
              for (var i = 0, o; i < iterable.length; i++) {
                  o = iterable[i];
                  st_operation.appendByteBuffer(b, o);
              }
              return;
          },
          fromObject: function fromObject(object) {
              if (!object) {
                  object = [];
              }
              return this.validate(function () {
                  var result = [];
                  for (var i = 0, o; i < object.length; i++) {
                      o = object[i];
                      result.push(st_operation.fromObject(o));
                  }
                  return result;
              }());
          },
          toObject: function toObject(object) {
              var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  
              if (debug.use_default && object === undefined) {
                  return [st_operation.toObject(object, debug)];
              }
              if (!object) {
                  object = [];
              }
              return this.validate(function () {
                  var result = [];
                  for (var i = 0, o; i < object.length; i++) {
                      o = object[i];
                      result.push(st_operation.toObject(o, debug));
                  }
                  return result;
              }());
          }
      };
  };
  
  // global_parameters_update_operation current_fees
  Types.fixed_array = function (count, st_operation) {
      return {
          fromByteBuffer: function fromByteBuffer(b) {
              var i, j, ref, results;
              results = [];
              for (i = j = 0, ref = count; j < ref; i = j += 1) {
                  results.push(st_operation.fromByteBuffer(b));
              }
              return sortOperation(results, st_operation);
          },
          appendByteBuffer: function appendByteBuffer(b, object) {
              var i, j, ref;
              if (count !== 0) {
                  _SerializerValidation2.default.required(object);
                  object = sortOperation(object, st_operation);
              }
              for (i = j = 0, ref = count; j < ref; i = j += 1) {
                  st_operation.appendByteBuffer(b, object[i]);
              }
          },
          fromObject: function fromObject(object) {
              var i, j, ref, results;
              if (count !== 0) {
                  _SerializerValidation2.default.required(object);
              }
              results = [];
              for (i = j = 0, ref = count; j < ref; i = j += 1) {
                  results.push(st_operation.fromObject(object[i]));
              }
              return results;
          },
          toObject: function toObject(object, debug) {
              var i, j, k, ref, ref1, results, results1;
              if (debug == null) {
                  debug = {};
              }
              if (debug.use_default && object === void 0) {
                  results = [];
                  for (i = j = 0, ref = count; j < ref; i = j += 1) {
                      results.push(st_operation.toObject(void 0, debug));
                  }
                  return results;
              }
              if (count !== 0) {
                  _SerializerValidation2.default.required(object);
              }
              results1 = [];
              for (i = k = 0, ref1 = count; k < ref1; i = k += 1) {
                  results1.push(st_operation.toObject(object[i], debug));
              }
              return results1;
          }
      };
  };
  
  /* Supports instance numbers (11) or object types (1.2.11).  Object type
  Validation is enforced when an object type is used. */
  var id_type = function id_type(reserved_spaces, object_type) {
      _SerializerValidation2.default.required(reserved_spaces, "reserved_spaces");
      _SerializerValidation2.default.required(object_type, "object_type");
      return {
          fromByteBuffer: function fromByteBuffer(b) {
              return b.readVarint32();
          },
          appendByteBuffer: function appendByteBuffer(b, object) {
              _SerializerValidation2.default.required(object);
              if (object.resolve !== undefined) {
                  object = object.resolve;
              }
              // convert 1.2.n into just n
              if (/^[0-9]+\.[0-9]+\.[0-9]+$/.test(object)) {
                  object = _SerializerValidation2.default.get_instance(reserved_spaces, object_type, object);
              }
              b.writeVarint32(_SerializerValidation2.default.to_number(object));
              return;
          },
          fromObject: function fromObject(object) {
              _SerializerValidation2.default.required(object);
              if (object.resolve !== undefined) {
                  object = object.resolve;
              }
              if (_SerializerValidation2.default.is_digits(object)) {
                  return _SerializerValidation2.default.to_number(object);
              }
              return _SerializerValidation2.default.get_instance(reserved_spaces, object_type, object);
          },
          toObject: function toObject(object) {
              var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  
              var object_type_id = _ChainTypes2.default.object_type[object_type];
              if (debug.use_default && object === undefined) {
                  return reserved_spaces + '.' + object_type_id + '.0';
              }
              _SerializerValidation2.default.required(object);
              if (object.resolve !== undefined) {
                  object = object.resolve;
              }
              if (/^[0-9]+\.[0-9]+\.[0-9]+$/.test(object)) {
                  object = _SerializerValidation2.default.get_instance(reserved_spaces, object_type, object);
              }
  
              return reserved_spaces + '.' + object_type_id + '.' + object;
          }
      };
  };
  
  Types.protocol_id_type = function (name) {
      _SerializerValidation2.default.required(name, "name");
      return id_type(_ChainTypes2.default.reserved_spaces.protocol_ids, name);
  };
  
  Types.object_id_type = {
      fromByteBuffer: function fromByteBuffer(b) {
          return _ObjectId2.default.fromByteBuffer(b);
      },
      appendByteBuffer: function appendByteBuffer(b, object) {
          _SerializerValidation2.default.required(object);
          if (object.resolve !== undefined) {
              object = object.resolve;
          }
          object = _ObjectId2.default.fromString(object);
          object.appendByteBuffer(b);
          return;
      },
      fromObject: function fromObject(object) {
          _SerializerValidation2.default.required(object);
          if (object.resolve !== undefined) {
              object = object.resolve;
          }
          return _ObjectId2.default.fromString(object);
      },
      toObject: function toObject(object) {
          var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  
          if (debug.use_default && object === undefined) {
              return "0.0.0";
          }
          _SerializerValidation2.default.required(object);
          if (object.resolve !== undefined) {
              object = object.resolve;
          }
          object = _ObjectId2.default.fromString(object);
          return object.toString();
      }
  };
  
  Types.vote_id = { TYPE: 0x000000FF,
      ID: 0xFFFFFF00,
      fromByteBuffer: function fromByteBuffer(b) {
          var value = b.readUint32();
          return {
              type: value & this.TYPE,
              id: value & this.ID
          };
      },
      appendByteBuffer: function appendByteBuffer(b, object) {
          _SerializerValidation2.default.required(object);
          if (object === "string") object = Types.vote_id.fromObject(object);
  
          var value = object.id << 8 | object.type;
          b.writeUint32(value);
          return;
      },
      fromObject: function fromObject(object) {
          _SerializerValidation2.default.required(object, "(type vote_id)");
          if ((typeof object === 'undefined' ? 'undefined' : _typeof(object)) === "object") {
              _SerializerValidation2.default.required(object.type, "type");
              _SerializerValidation2.default.required(object.id, "id");
              return object;
          }
          _SerializerValidation2.default.require_test(/^[0-9]+:[0-9]+$/, object, 'vote_id format ' + object);
  
          var _object$split = object.split(':'),
              type = _object$split[0],
              id = _object$split[1];
  
          _SerializerValidation2.default.require_range(0, 0xff, type, 'vote type ' + object);
          _SerializerValidation2.default.require_range(0, 0xffffff, id, 'vote id ' + object);
          return { type: type, id: id };
      },
      toObject: function toObject(object) {
          var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  
          if (debug.use_default && object === undefined) {
              return "0:0";
          }
          _SerializerValidation2.default.required(object);
          if (typeof object === "string") object = Types.vote_id.fromObject(object);
  
          return object.type + ":" + object.id;
      },
      compare: function compare(a, b) {
          if ((typeof a === 'undefined' ? 'undefined' : _typeof(a)) !== "object") a = Types.vote_id.fromObject(a);
          if ((typeof b === 'undefined' ? 'undefined' : _typeof(b)) !== "object") b = Types.vote_id.fromObject(b);
          return parseInt(a.id) - parseInt(b.id);
      }
  };
  
  Types.optional = function (st_operation) {
      _SerializerValidation2.default.required(st_operation, "st_operation");
      return {
          fromByteBuffer: function fromByteBuffer(b) {
              if (!(b.readUint8() === 1)) {
                  return undefined;
              }
              return st_operation.fromByteBuffer(b);
          },
          appendByteBuffer: function appendByteBuffer(b, object) {
              if (object !== null && object !== undefined) {
                  b.writeUint8(1);
                  st_operation.appendByteBuffer(b, object);
              } else {
                  b.writeUint8(0);
              }
              return;
          },
          fromObject: function fromObject(object) {
              if (object === undefined) {
                  return undefined;
              }
              return st_operation.fromObject(object);
          },
          toObject: function toObject(object) {
              var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  
              // toObject is only null save if use_default is true
              var result_object = function () {
                  if (!debug.use_default && object === undefined) {
                      return undefined;
                  } else {
                      return st_operation.toObject(object, debug);
                  }
              }();
  
              if (debug.annotate) {
                  if ((typeof result_object === 'undefined' ? 'undefined' : _typeof(result_object)) === "object") {
                      result_object.__optional = "parent is optional";
                  } else {
                      result_object = { __optional: result_object };
                  }
              }
              return result_object;
          }
      };
  };
  
  Types.static_variant = function (_st_operations) {
      return {
          nosort: true,
          st_operations: _st_operations,
          fromByteBuffer: function fromByteBuffer(b) {
              var type_id = b.readVarint32();
              var st_operation = this.st_operations[type_id];
              if (HEX_DUMP) {
                  console.error('static_variant id 0x' + type_id.toString(16) + ' (' + type_id + ')');
              }
              _SerializerValidation2.default.required(st_operation, 'operation ' + type_id);
              return [type_id, st_operation.fromByteBuffer(b)];
          },
          appendByteBuffer: function appendByteBuffer(b, object) {
              _SerializerValidation2.default.required(object);
              var type_id = object[0];
              var st_operation = this.st_operations[type_id];
              _SerializerValidation2.default.required(st_operation, 'operation ' + type_id);
              b.writeVarint32(type_id);
              st_operation.appendByteBuffer(b, object[1]);
              return;
          },
          fromObject: function fromObject(object) {
              _SerializerValidation2.default.required(object);
              var type_id = object[0];
              var st_operation = this.st_operations[type_id];
              _SerializerValidation2.default.required(st_operation, 'operation ' + type_id);
              return [type_id, st_operation.fromObject(object[1])];
          },
          toObject: function toObject(object) {
              var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  
              if (debug.use_default && object === undefined) {
                  return [0, this.st_operations[0].toObject(undefined, debug)];
              }
              _SerializerValidation2.default.required(object);
              var type_id = object[0];
              var st_operation = this.st_operations[type_id];
              _SerializerValidation2.default.required(st_operation, 'operation ' + type_id);
              return [type_id, st_operation.toObject(object[1], debug)];
          }
      };
  };
  
  Types.map = function (key_st_operation, value_st_operation) {
      return {
          validate: function validate(array) {
              if (!Array.isArray(array)) {
                  throw new Error("expecting array");
              }
              var dup_map = {};
              for (var i = 0, o; i < array.length; i++) {
                  o = array[i];
                  var ref;
                  if (!(o.length === 2)) {
                      throw new Error("expecting two elements");
                  }
                  if (ref = _typeof(o[0]), ['number', 'string'].indexOf(ref) >= 0) {
                      if (dup_map[o[0]] !== undefined) {
                          throw new Error("duplicate (map)");
                      }
                      dup_map[o[0]] = true;
                  }
              }
              return sortOperation(array, key_st_operation);
          },
          fromByteBuffer: function fromByteBuffer(b) {
              var result = [];
              var end = b.readVarint32();
              for (var i = 0; 0 < end ? i < end : i > end; 0 < end ? i++ : i++) {
                  result.push([key_st_operation.fromByteBuffer(b), value_st_operation.fromByteBuffer(b)]);
              }
              return this.validate(result);
          },
          appendByteBuffer: function appendByteBuffer(b, object) {
              this.validate(object);
              b.writeVarint32(object.length);
              for (var i = 0, o; i < object.length; i++) {
                  o = object[i];
                  key_st_operation.appendByteBuffer(b, o[0]);
                  value_st_operation.appendByteBuffer(b, o[1]);
              }
              return;
          },
          fromObject: function fromObject(object) {
              _SerializerValidation2.default.required(object);
              var result = [];
              for (var i = 0, o; i < object.length; i++) {
                  o = object[i];
                  result.push([key_st_operation.fromObject(o[0]), value_st_operation.fromObject(o[1])]);
              }
              return this.validate(result);
          },
          toObject: function toObject(object) {
              var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  
              if (debug.use_default && object === undefined) {
                  return [[key_st_operation.toObject(undefined, debug), value_st_operation.toObject(undefined, debug)]];
              }
              _SerializerValidation2.default.required(object);
              object = this.validate(object);
              var result = [];
              for (var i = 0, o; i < object.length; i++) {
                  o = object[i];
                  result.push([key_st_operation.toObject(o[0], debug), value_st_operation.toObject(o[1], debug)]);
              }
              return result;
          }
      };
  };
  
  Types.public_key = {
      toPublic: function toPublic(object) {
          if (object.resolve !== undefined) {
              object = object.resolve;
          }
          return object == null ? object : object.Q ? object : _ecc.PublicKey.fromStringOrThrow(object);
      },
      fromByteBuffer: function fromByteBuffer(b) {
          return _FastParser2.default.public_key(b);
      },
      appendByteBuffer: function appendByteBuffer(b, object) {
          _SerializerValidation2.default.required(object);
          _FastParser2.default.public_key(b, Types.public_key.toPublic(object));
          return;
      },
      fromObject: function fromObject(object) {
          _SerializerValidation2.default.required(object);
          if (object.Q) {
              return object;
          }
          return Types.public_key.toPublic(object);
      },
      toObject: function toObject(object) {
          var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  
          if (debug.use_default && object === undefined) {
              return _bitsharesjsWs.ChainConfig.address_prefix + "859gxfnXyUriMgUeThh1fWv3oqcpLFyHa3TfFYC4PK2HqhToVM";
          }
          _SerializerValidation2.default.required(object);
          return object.toString();
      },
      compare: function compare(a, b) {
          return strCmp(a.toAddressString(), b.toAddressString());
      }
  };
  
  Types.address = {
      _to_address: function _to_address(object) {
          _SerializerValidation2.default.required(object);
          if (object.addy) {
              return object;
          }
          return _ecc.Address.fromString(object);
      },
      fromByteBuffer: function fromByteBuffer(b) {
          return new _ecc.Address(_FastParser2.default.ripemd160(b));
      },
      appendByteBuffer: function appendByteBuffer(b, object) {
          _FastParser2.default.ripemd160(b, Types.address._to_address(object).toBuffer());
          return;
      },
      fromObject: function fromObject(object) {
          return Types.address._to_address(object);
      },
      toObject: function toObject(object) {
          var debug = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  
          if (debug.use_default && object === undefined) {
              return _bitsharesjsWs.ChainConfig.address_prefix + "664KmHxSuQyDsfwo4WEJvWpzg1QKdg67S";
          }
          return Types.address._to_address(object).toString();
      },
      compare: function compare(a, b) {
          return strCmp(a.toString(), b.toString());
      }
  };
  
  var strCmp = function strCmp(a, b) {
      return a > b ? 1 : a < b ? -1 : 0;
  };
  var firstEl = function firstEl(el) {
      return Array.isArray(el) ? el[0] : el;
  };
  var sortOperation = function sortOperation(array, st_operation) {
      return st_operation.nosort ? array : st_operation.compare ? array.sort(function (a, b) {
          return st_operation.compare(firstEl(a), firstEl(b));
      }) : // custom compare operation
      array.sort(function (a, b) {
          return typeof firstEl(a) === "number" && typeof firstEl(b) === "number" ? firstEl(a) - firstEl(b) :
          // A binary string compare does not work. Performanance is very good so HEX is used..  localeCompare is another option.
          Buffer.isBuffer(firstEl(a)) && Buffer.isBuffer(firstEl(b)) ? strCmp(firstEl(a).toString("hex"), firstEl(b).toString("hex")) : strCmp(firstEl(a).toString(), firstEl(b).toString());
      });
  };
  
  exports.default = Types;
  module.exports = exports['default'];
  }).call(this,require('_process'),require("buffer").Buffer)
  },{"../../chain/src/ChainTypes":15,"../../chain/src/ObjectId":16,"../../ecc":19,"./FastParser":32,"./SerializerValidation":33,"_process":87,"bitsharesjs-ws":7,"buffer":79}],39:[function(require,module,exports){
  var basex = require('base-x')
  var ALPHABET = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
  
  module.exports = basex(ALPHABET)
  
  },{"base-x":2}],40:[function(require,module,exports){
  /*
   Copyright 2013-2014 Daniel Wirtz <dcode@dcode.io>
  
   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at
  
   http://www.apache.org/licenses/LICENSE-2.0
  
   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
   */
  
  /**
   * @license bytebuffer.js (c) 2015 Daniel Wirtz <dcode@dcode.io>
   * Backing buffer: ArrayBuffer, Accessor: Uint8Array
   * Released under the Apache License, Version 2.0
   * see: https://github.com/dcodeIO/bytebuffer.js for details
   */
  (function(global, factory) {
  
      /* AMD */ if (typeof define === 'function' && define["amd"])
          define(["long"], factory);
      /* CommonJS */ else if (typeof require === 'function' && typeof module === "object" && module && module["exports"])
          module['exports'] = (function() {
              var Long; try { Long = require("long"); } catch (e) {}
              return factory(Long);
          })();
      /* Global */ else
          (global["dcodeIO"] = global["dcodeIO"] || {})["ByteBuffer"] = factory(global["dcodeIO"]["Long"]);
  
  })(this, function(Long) {
      "use strict";
  
      /**
       * Constructs a new ByteBuffer.
       * @class The swiss army knife for binary data in JavaScript.
       * @exports ByteBuffer
       * @constructor
       * @param {number=} capacity Initial capacity. Defaults to {@link ByteBuffer.DEFAULT_CAPACITY}.
       * @param {boolean=} littleEndian Whether to use little or big endian byte order. Defaults to
       *  {@link ByteBuffer.DEFAULT_ENDIAN}.
       * @param {boolean=} noAssert Whether to skip assertions of offsets and values. Defaults to
       *  {@link ByteBuffer.DEFAULT_NOASSERT}.
       * @expose
       */
      var ByteBuffer = function(capacity, littleEndian, noAssert) {
          if (typeof capacity === 'undefined')
              capacity = ByteBuffer.DEFAULT_CAPACITY;
          if (typeof littleEndian === 'undefined')
              littleEndian = ByteBuffer.DEFAULT_ENDIAN;
          if (typeof noAssert === 'undefined')
              noAssert = ByteBuffer.DEFAULT_NOASSERT;
          if (!noAssert) {
              capacity = capacity | 0;
              if (capacity < 0)
                  throw RangeError("Illegal capacity");
              littleEndian = !!littleEndian;
              noAssert = !!noAssert;
          }
  
          /**
           * Backing ArrayBuffer.
           * @type {!ArrayBuffer}
           * @expose
           */
          this.buffer = capacity === 0 ? EMPTY_BUFFER : new ArrayBuffer(capacity);
  
          /**
           * Uint8Array utilized to manipulate the backing buffer. Becomes `null` if the backing buffer has a capacity of `0`.
           * @type {?Uint8Array}
           * @expose
           */
          this.view = capacity === 0 ? null : new Uint8Array(this.buffer);
  
          /**
           * Absolute read/write offset.
           * @type {number}
           * @expose
           * @see ByteBuffer#flip
           * @see ByteBuffer#clear
           */
          this.offset = 0;
  
          /**
           * Marked offset.
           * @type {number}
           * @expose
           * @see ByteBuffer#mark
           * @see ByteBuffer#reset
           */
          this.markedOffset = -1;
  
          /**
           * Absolute limit of the contained data. Set to the backing buffer's capacity upon allocation.
           * @type {number}
           * @expose
           * @see ByteBuffer#flip
           * @see ByteBuffer#clear
           */
          this.limit = capacity;
  
          /**
           * Whether to use little endian byte order, defaults to `false` for big endian.
           * @type {boolean}
           * @expose
           */
          this.littleEndian = littleEndian;
  
          /**
           * Whether to skip assertions of offsets and values, defaults to `false`.
           * @type {boolean}
           * @expose
           */
          this.noAssert = noAssert;
      };
  
      /**
       * ByteBuffer version.
       * @type {string}
       * @const
       * @expose
       */
      ByteBuffer.VERSION = "5.0.1";
  
      /**
       * Little endian constant that can be used instead of its boolean value. Evaluates to `true`.
       * @type {boolean}
       * @const
       * @expose
       */
      ByteBuffer.LITTLE_ENDIAN = true;
  
      /**
       * Big endian constant that can be used instead of its boolean value. Evaluates to `false`.
       * @type {boolean}
       * @const
       * @expose
       */
      ByteBuffer.BIG_ENDIAN = false;
  
      /**
       * Default initial capacity of `16`.
       * @type {number}
       * @expose
       */
      ByteBuffer.DEFAULT_CAPACITY = 16;
  
      /**
       * Default endianess of `false` for big endian.
       * @type {boolean}
       * @expose
       */
      ByteBuffer.DEFAULT_ENDIAN = ByteBuffer.BIG_ENDIAN;
  
      /**
       * Default no assertions flag of `false`.
       * @type {boolean}
       * @expose
       */
      ByteBuffer.DEFAULT_NOASSERT = false;
  
      /**
       * A `Long` class for representing a 64-bit two's-complement integer value. May be `null` if Long.js has not been loaded
       *  and int64 support is not available.
       * @type {?Long}
       * @const
       * @see https://github.com/dcodeIO/long.js
       * @expose
       */
      ByteBuffer.Long = Long || null;
  
      /**
       * @alias ByteBuffer.prototype
       * @inner
       */
      var ByteBufferPrototype = ByteBuffer.prototype;
  
      /**
       * An indicator used to reliably determine if an object is a ByteBuffer or not.
       * @type {boolean}
       * @const
       * @expose
       * @private
       */
      ByteBufferPrototype.__isByteBuffer__;
  
      Object.defineProperty(ByteBufferPrototype, "__isByteBuffer__", {
          value: true,
          enumerable: false,
          configurable: false
      });
  
      // helpers
  
      /**
       * @type {!ArrayBuffer}
       * @inner
       */
      var EMPTY_BUFFER = new ArrayBuffer(0);
  
      /**
       * String.fromCharCode reference for compile-time renaming.
       * @type {function(...number):string}
       * @inner
       */
      var stringFromCharCode = String.fromCharCode;
  
      /**
       * Creates a source function for a string.
       * @param {string} s String to read from
       * @returns {function():number|null} Source function returning the next char code respectively `null` if there are
       *  no more characters left.
       * @throws {TypeError} If the argument is invalid
       * @inner
       */
      function stringSource(s) {
          var i=0; return function() {
              return i < s.length ? s.charCodeAt(i++) : null;
          };
      }
  
      /**
       * Creates a destination function for a string.
       * @returns {function(number=):undefined|string} Destination function successively called with the next char code.
       *  Returns the final string when called without arguments.
       * @inner
       */
      function stringDestination() {
          var cs = [], ps = []; return function() {
              if (arguments.length === 0)
                  return ps.join('')+stringFromCharCode.apply(String, cs);
              if (cs.length + arguments.length > 1024)
                  ps.push(stringFromCharCode.apply(String, cs)),
                      cs.length = 0;
              Array.prototype.push.apply(cs, arguments);
          };
      }
  
      /**
       * Gets the accessor type.
       * @returns {Function} `Buffer` under node.js, `Uint8Array` respectively `DataView` in the browser (classes)
       * @expose
       */
      ByteBuffer.accessor = function() {
          return Uint8Array;
      };
      /**
       * Allocates a new ByteBuffer backed by a buffer of the specified capacity.
       * @param {number=} capacity Initial capacity. Defaults to {@link ByteBuffer.DEFAULT_CAPACITY}.
       * @param {boolean=} littleEndian Whether to use little or big endian byte order. Defaults to
       *  {@link ByteBuffer.DEFAULT_ENDIAN}.
       * @param {boolean=} noAssert Whether to skip assertions of offsets and values. Defaults to
       *  {@link ByteBuffer.DEFAULT_NOASSERT}.
       * @returns {!ByteBuffer}
       * @expose
       */
      ByteBuffer.allocate = function(capacity, littleEndian, noAssert) {
          return new ByteBuffer(capacity, littleEndian, noAssert);
      };
  
      /**
       * Concatenates multiple ByteBuffers into one.
       * @param {!Array.<!ByteBuffer|!ArrayBuffer|!Uint8Array|string>} buffers Buffers to concatenate
       * @param {(string|boolean)=} encoding String encoding if `buffers` contains a string ("base64", "hex", "binary",
       *  defaults to "utf8")
       * @param {boolean=} littleEndian Whether to use little or big endian byte order for the resulting ByteBuffer. Defaults
       *  to {@link ByteBuffer.DEFAULT_ENDIAN}.
       * @param {boolean=} noAssert Whether to skip assertions of offsets and values for the resulting ByteBuffer. Defaults to
       *  {@link ByteBuffer.DEFAULT_NOASSERT}.
       * @returns {!ByteBuffer} Concatenated ByteBuffer
       * @expose
       */
      ByteBuffer.concat = function(buffers, encoding, littleEndian, noAssert) {
          if (typeof encoding === 'boolean' || typeof encoding !== 'string') {
              noAssert = littleEndian;
              littleEndian = encoding;
              encoding = undefined;
          }
          var capacity = 0;
          for (var i=0, k=buffers.length, length; i<k; ++i) {
              if (!ByteBuffer.isByteBuffer(buffers[i]))
                  buffers[i] = ByteBuffer.wrap(buffers[i], encoding);
              length = buffers[i].limit - buffers[i].offset;
              if (length > 0) capacity += length;
          }
          if (capacity === 0)
              return new ByteBuffer(0, littleEndian, noAssert);
          var bb = new ByteBuffer(capacity, littleEndian, noAssert),
              bi;
          i=0; while (i<k) {
              bi = buffers[i++];
              length = bi.limit - bi.offset;
              if (length <= 0) continue;
              bb.view.set(bi.view.subarray(bi.offset, bi.limit), bb.offset);
              bb.offset += length;
          }
          bb.limit = bb.offset;
          bb.offset = 0;
          return bb;
      };
  
      /**
       * Tests if the specified type is a ByteBuffer.
       * @param {*} bb ByteBuffer to test
       * @returns {boolean} `true` if it is a ByteBuffer, otherwise `false`
       * @expose
       */
      ByteBuffer.isByteBuffer = function(bb) {
          return (bb && bb["__isByteBuffer__"]) === true;
      };
      /**
       * Gets the backing buffer type.
       * @returns {Function} `Buffer` under node.js, `ArrayBuffer` in the browser (classes)
       * @expose
       */
      ByteBuffer.type = function() {
          return ArrayBuffer;
      };
      /**
       * Wraps a buffer or a string. Sets the allocated ByteBuffer's {@link ByteBuffer#offset} to `0` and its
       *  {@link ByteBuffer#limit} to the length of the wrapped data.
       * @param {!ByteBuffer|!ArrayBuffer|!Uint8Array|string|!Array.<number>} buffer Anything that can be wrapped
       * @param {(string|boolean)=} encoding String encoding if `buffer` is a string ("base64", "hex", "binary", defaults to
       *  "utf8")
       * @param {boolean=} littleEndian Whether to use little or big endian byte order. Defaults to
       *  {@link ByteBuffer.DEFAULT_ENDIAN}.
       * @param {boolean=} noAssert Whether to skip assertions of offsets and values. Defaults to
       *  {@link ByteBuffer.DEFAULT_NOASSERT}.
       * @returns {!ByteBuffer} A ByteBuffer wrapping `buffer`
       * @expose
       */
      ByteBuffer.wrap = function(buffer, encoding, littleEndian, noAssert) {
          if (typeof encoding !== 'string') {
              noAssert = littleEndian;
              littleEndian = encoding;
              encoding = undefined;
          }
          if (typeof buffer === 'string') {
              if (typeof encoding === 'undefined')
                  encoding = "utf8";
              switch (encoding) {
                  case "base64":
                      return ByteBuffer.fromBase64(buffer, littleEndian);
                  case "hex":
                      return ByteBuffer.fromHex(buffer, littleEndian);
                  case "binary":
                      return ByteBuffer.fromBinary(buffer, littleEndian);
                  case "utf8":
                      return ByteBuffer.fromUTF8(buffer, littleEndian);
                  case "debug":
                      return ByteBuffer.fromDebug(buffer, littleEndian);
                  default:
                      throw Error("Unsupported encoding: "+encoding);
              }
          }
          if (buffer === null || typeof buffer !== 'object')
              throw TypeError("Illegal buffer");
          var bb;
          if (ByteBuffer.isByteBuffer(buffer)) {
              bb = ByteBufferPrototype.clone.call(buffer);
              bb.markedOffset = -1;
              return bb;
          }
          if (buffer instanceof Uint8Array) { // Extract ArrayBuffer from Uint8Array
              bb = new ByteBuffer(0, littleEndian, noAssert);
              if (buffer.length > 0) { // Avoid references to more than one EMPTY_BUFFER
                  bb.buffer = buffer.buffer;
                  bb.offset = buffer.byteOffset;
                  bb.limit = buffer.byteOffset + buffer.byteLength;
                  bb.view = new Uint8Array(buffer.buffer);
              }
          } else if (buffer instanceof ArrayBuffer) { // Reuse ArrayBuffer
              bb = new ByteBuffer(0, littleEndian, noAssert);
              if (buffer.byteLength > 0) {
                  bb.buffer = buffer;
                  bb.offset = 0;
                  bb.limit = buffer.byteLength;
                  bb.view = buffer.byteLength > 0 ? new Uint8Array(buffer) : null;
              }
          } else if (Object.prototype.toString.call(buffer) === "[object Array]") { // Create from octets
              bb = new ByteBuffer(buffer.length, littleEndian, noAssert);
              bb.limit = buffer.length;
              for (var i=0; i<buffer.length; ++i)
                  bb.view[i] = buffer[i];
          } else
              throw TypeError("Illegal buffer"); // Otherwise fail
          return bb;
      };
  
      /**
       * Writes the array as a bitset.
       * @param {Array<boolean>} value Array of booleans to write
       * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `length` if omitted.
       * @returns {!ByteBuffer}
       * @expose
       */
      ByteBufferPrototype.writeBitSet = function(value, offset) {
        var relative = typeof offset === 'undefined';
        if (relative) offset = this.offset;
        if (!this.noAssert) {
          if (!(value instanceof Array))
            throw TypeError("Illegal BitSet: Not an array");
          if (typeof offset !== 'number' || offset % 1 !== 0)
              throw TypeError("Illegal offset: "+offset+" (not an integer)");
          offset >>>= 0;
          if (offset < 0 || offset + 0 > this.buffer.byteLength)
              throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
        }
  
        var start = offset,
            bits = value.length,
            bytes = (bits >> 3),
            bit = 0,
            k;
  
        offset += this.writeVarint32(bits,offset);
  
        while(bytes--) {
          k = (!!value[bit++] & 1) |
              ((!!value[bit++] & 1) << 1) |
              ((!!value[bit++] & 1) << 2) |
              ((!!value[bit++] & 1) << 3) |
              ((!!value[bit++] & 1) << 4) |
              ((!!value[bit++] & 1) << 5) |
              ((!!value[bit++] & 1) << 6) |
              ((!!value[bit++] & 1) << 7);
          this.writeByte(k,offset++);
        }
  
        if(bit < bits) {
          var m = 0; k = 0;
          while(bit < bits) k = k | ((!!value[bit++] & 1) << (m++));
          this.writeByte(k,offset++);
        }
  
        if (relative) {
          this.offset = offset;
          return this;
        }
        return offset - start;
      }
  
      /**
       * Reads a BitSet as an array of booleans.
       * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `length` if omitted.
       * @returns {Array<boolean>
       * @expose
       */
      ByteBufferPrototype.readBitSet = function(offset) {
        var relative = typeof offset === 'undefined';
        if (relative) offset = this.offset;
  
        var ret = this.readVarint32(offset),
            bits = ret.value,
            bytes = (bits >> 3),
            bit = 0,
            value = [],
            k;
  
        offset += ret.length;
  
        while(bytes--) {
          k = this.readByte(offset++);
          value[bit++] = !!(k & 0x01);
          value[bit++] = !!(k & 0x02);
          value[bit++] = !!(k & 0x04);
          value[bit++] = !!(k & 0x08);
          value[bit++] = !!(k & 0x10);
          value[bit++] = !!(k & 0x20);
          value[bit++] = !!(k & 0x40);
          value[bit++] = !!(k & 0x80);
        }
  
        if(bit < bits) {
          var m = 0;
          k = this.readByte(offset++);
          while(bit < bits) value[bit++] = !!((k >> (m++)) & 1);
        }
  
        if (relative) {
          this.offset = offset;
        }
        return value;
      }
      /**
       * Reads the specified number of bytes.
       * @param {number} length Number of bytes to read
       * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `length` if omitted.
       * @returns {!ByteBuffer}
       * @expose
       */
      ByteBufferPrototype.readBytes = function(length, offset) {
          var relative = typeof offset === 'undefined';
          if (relative) offset = this.offset;
          if (!this.noAssert) {
              if (typeof offset !== 'number' || offset % 1 !== 0)
                  throw TypeError("Illegal offset: "+offset+" (not an integer)");
              offset >>>= 0;
              if (offset < 0 || offset + length > this.buffer.byteLength)
                  throw RangeError("Illegal offset: 0 <= "+offset+" (+"+length+") <= "+this.buffer.byteLength);
          }
          var slice = this.slice(offset, offset + length);
          if (relative) this.offset += length;
          return slice;
      };
  
      /**
       * Writes a payload of bytes. This is an alias of {@link ByteBuffer#append}.
       * @function
       * @param {!ByteBuffer|!ArrayBuffer|!Uint8Array|string} source Data to write. If `source` is a ByteBuffer, its offsets
       *  will be modified according to the performed read operation.
       * @param {(string|number)=} encoding Encoding if `data` is a string ("base64", "hex", "binary", defaults to "utf8")
       * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by the number of bytes
       *  written if omitted.
       * @returns {!ByteBuffer} this
       * @expose
       */
      ByteBufferPrototype.writeBytes = ByteBufferPrototype.append;
  
      // types/ints/int8
  
      /**
       * Writes an 8bit signed integer.
       * @param {number} value Value to write
       * @param {number=} offset Offset to write to. Will use and advance {@link ByteBuffer#offset} by `1` if omitted.
       * @returns {!ByteBuffer} this
       * @expose
       */
      ByteBufferPrototype.writeInt8 = function(value, offset) {
          var relative = typeof offset === 'undefined';
          if (relative) offset = this.offset;
          if (!this.noAssert) {
              if (typeof value !== 'number' || value % 1 !== 0)
                  throw TypeError("Illegal value: "+value+" (not an integer)");
              value |= 0;
              if (typeof offset !== 'number' || offset % 1 !== 0)
                  throw TypeError("Illegal offset: "+offset+" (not an integer)");
              offset >>>= 0;
              if (offset < 0 || offset + 0 > this.buffer.byteLength)
                  throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
          }
          offset += 1;
          var capacity0 = this.buffer.byteLength;
          if (offset > capacity0)
              this.resize((capacity0 *= 2) > offset ? capacity0 : offset);
          offset -= 1;
          this.view[offset] = value;
          if (relative) this.offset += 1;
          return this;
      };
  
      /**
       * Writes an 8bit signed integer. This is an alias of {@link ByteBuffer#writeInt8}.
       * @function
       * @param {number} value Value to write
       * @param {number=} offset Offset to write to. Will use and advance {@link ByteBuffer#offset} by `1` if omitted.
       * @returns {!ByteBuffer} this
       * @expose
       */
      ByteBufferPrototype.writeByte = ByteBufferPrototype.writeInt8;
  
      /**
       * Reads an 8bit signed integer.
       * @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `1` if omitted.
       * @returns {number} Value read
       * @expose
       */
      ByteBufferPrototype.readInt8 = function(offset) {
          var relative = typeof offset === 'undefined';
          if (relative) offset = this.offset;
          if (!this.noAssert) {
              if (typeof offset !== 'number' || offset % 1 !== 0)
                  throw TypeError("Illegal offset: "+offset+" (not an integer)");
              offset >>>= 0;
              if (offset < 0 || offset + 1 > this.buffer.byteLength)
                  throw RangeError("Illegal offset: 0 <= "+offset+" (+"+1+") <= "+this.buffer.byteLength);
          }
          var value = this.view[offset];
          if ((value & 0x80) === 0x80) value = -(0xFF - value + 1); // Cast to signed
          if (relative) this.offset += 1;
          return value;
      };
  
      /**
       * Reads an 8bit signed integer. This is an alias of {@link ByteBuffer#readInt8}.
       * @function
       * @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `1` if omitted.
       * @returns {number} Value read
       * @expose
       */
      ByteBufferPrototype.readByte = ByteBufferPrototype.readInt8;
  
      /**
       * Writes an 8bit unsigned integer.
       * @param {number} value Value to write
       * @param {number=} offset Offset to write to. Will use and advance {@link ByteBuffer#offset} by `1` if omitted.
       * @returns {!ByteBuffer} this
       * @expose
       */
      ByteBufferPrototype.writeUint8 = function(value, offset) {
          var relative = typeof offset === 'undefined';
          if (relative) offset = this.offset;
          if (!this.noAssert) {
              if (typeof value !== 'number' || value % 1 !== 0)
                  throw TypeError("Illegal value: "+value+" (not an integer)");
              value >>>= 0;
              if (typeof offset !== 'number' || offset % 1 !== 0)
                  throw TypeError("Illegal offset: "+offset+" (not an integer)");
              offset >>>= 0;
              if (offset < 0 || offset + 0 > this.buffer.byteLength)
                  throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
          }
          offset += 1;
          var capacity1 = this.buffer.byteLength;
          if (offset > capacity1)
              this.resize((capacity1 *= 2) > offset ? capacity1 : offset);
          offset -= 1;
          this.view[offset] = value;
          if (relative) this.offset += 1;
          return this;
      };
  
      /**
       * Writes an 8bit unsigned integer. This is an alias of {@link ByteBuffer#writeUint8}.
       * @function
       * @param {number} value Value to write
       * @param {number=} offset Offset to write to. Will use and advance {@link ByteBuffer#offset} by `1` if omitted.
       * @returns {!ByteBuffer} this
       * @expose
       */
      ByteBufferPrototype.writeUInt8 = ByteBufferPrototype.writeUint8;
  
      /**
       * Reads an 8bit unsigned integer.
       * @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `1` if omitted.
       * @returns {number} Value read
       * @expose
       */
      ByteBufferPrototype.readUint8 = function(offset) {
          var relative = typeof offset === 'undefined';
          if (relative) offset = this.offset;
          if (!this.noAssert) {
              if (typeof offset !== 'number' || offset % 1 !== 0)
                  throw TypeError("Illegal offset: "+offset+" (not an integer)");
              offset >>>= 0;
              if (offset < 0 || offset + 1 > this.buffer.byteLength)
                  throw RangeError("Illegal offset: 0 <= "+offset+" (+"+1+") <= "+this.buffer.byteLength);
          }
          var value = this.view[offset];
          if (relative) this.offset += 1;
          return value;
      };
  
      /**
       * Reads an 8bit unsigned integer. This is an alias of {@link ByteBuffer#readUint8}.
       * @function
       * @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `1` if omitted.
       * @returns {number} Value read
       * @expose
       */
      ByteBufferPrototype.readUInt8 = ByteBufferPrototype.readUint8;
  
      // types/ints/int16
  
      /**
       * Writes a 16bit signed integer.
       * @param {number} value Value to write
       * @param {number=} offset Offset to write to. Will use and advance {@link ByteBuffer#offset} by `2` if omitted.
       * @throws {TypeError} If `offset` or `value` is not a valid number
       * @throws {RangeError} If `offset` is out of bounds
       * @expose
       */
      ByteBufferPrototype.writeInt16 = function(value, offset) {
          var relative = typeof offset === 'undefined';
          if (relative) offset = this.offset;
          if (!this.noAssert) {
              if (typeof value !== 'number' || value % 1 !== 0)
                  throw TypeError("Illegal value: "+value+" (not an integer)");
              value |= 0;
              if (typeof offset !== 'number' || offset % 1 !== 0)
                  throw TypeError("Illegal offset: "+offset+" (not an integer)");
              offset >>>= 0;
              if (offset < 0 || offset + 0 > this.buffer.byteLength)
                  throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
          }
          offset += 2;
          var capacity2 = this.buffer.byteLength;
          if (offset > capacity2)
              this.resize((capacity2 *= 2) > offset ? capacity2 : offset);
          offset -= 2;
          if (this.littleEndian) {
              this.view[offset+1] = (value & 0xFF00) >>> 8;
              this.view[offset  ] =  value & 0x00FF;
          } else {
              this.view[offset]   = (value & 0xFF00) >>> 8;
              this.view[offset+1] =  value & 0x00FF;
          }
          if (relative) this.offset += 2;
          return this;
      };
  
      /**
       * Writes a 16bit signed integer. This is an alias of {@link ByteBuffer#writeInt16}.
       * @function
       * @param {number} value Value to write
       * @param {number=} offset Offset to write to. Will use and advance {@link ByteBuffer#offset} by `2` if omitted.
       * @throws {TypeError} If `offset` or `value` is not a valid number
       * @throws {RangeError} If `offset` is out of bounds
       * @expose
       */
      ByteBufferPrototype.writeShort = ByteBufferPrototype.writeInt16;
  
      /**
       * Reads a 16bit signed integer.
       * @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `2` if omitted.
       * @returns {number} Value read
       * @throws {TypeError} If `offset` is not a valid number
       * @throws {RangeError} If `offset` is out of bounds
       * @expose
       */
      ByteBufferPrototype.readInt16 = function(offset) {
          var relative = typeof offset === 'undefined';
          if (relative) offset = this.offset;
          if (!this.noAssert) {
              if (typeof offset !== 'number' || offset % 1 !== 0)
                  throw TypeError("Illegal offset: "+offset+" (not an integer)");
              offset >>>= 0;
              if (offset < 0 || offset + 2 > this.buffer.byteLength)
                  throw RangeError("Illegal offset: 0 <= "+offset+" (+"+2+") <= "+this.buffer.byteLength);
          }
          var value = 0;
          if (this.littleEndian) {
              value  = this.view[offset  ];
              value |= this.view[offset+1] << 8;
          } else {
              value  = this.view[offset  ] << 8;
              value |= this.view[offset+1];
          }
          if ((value & 0x8000) === 0x8000) value = -(0xFFFF - value + 1); // Cast to signed
          if (relative) this.offset += 2;
          return value;
      };
  
      /**
       * Reads a 16bit signed integer. This is an alias of {@link ByteBuffer#readInt16}.
       * @function
       * @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `2` if omitted.
       * @returns {number} Value read
       * @throws {TypeError} If `offset` is not a valid number
       * @throws {RangeError} If `offset` is out of bounds
       * @expose
       */
      ByteBufferPrototype.readShort = ByteBufferPrototype.readInt16;
  
      /**
       * Writes a 16bit unsigned integer.
       * @param {number} value Value to write
       * @param {number=} offset Offset to write to. Will use and advance {@link ByteBuffer#offset} by `2` if omitted.
       * @throws {TypeError} If `offset` or `value` is not a valid number
       * @throws {RangeError} If `offset` is out of bounds
       * @expose
       */
      ByteBufferPrototype.writeUint16 = function(value, offset) {
          var relative = typeof offset === 'undefined';
          if (relative) offset = this.offset;
          if (!this.noAssert) {
              if (typeof value !== 'number' || value % 1 !== 0)
                  throw TypeError("Illegal value: "+value+" (not an integer)");
              value >>>= 0;
              if (typeof offset !== 'number' || offset % 1 !== 0)
                  throw TypeError("Illegal offset: "+offset+" (not an integer)");
              offset >>>= 0;
              if (offset < 0 || offset + 0 > this.buffer.byteLength)
                  throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
          }
          offset += 2;
          var capacity3 = this.buffer.byteLength;
          if (offset > capacity3)
              this.resize((capacity3 *= 2) > offset ? capacity3 : offset);
          offset -= 2;
          if (this.littleEndian) {
              this.view[offset+1] = (value & 0xFF00) >>> 8;
              this.view[offset  ] =  value & 0x00FF;
          } else {
              this.view[offset]   = (value & 0xFF00) >>> 8;
              this.view[offset+1] =  value & 0x00FF;
          }
          if (relative) this.offset += 2;
          return this;
      };
  
      /**
       * Writes a 16bit unsigned integer. This is an alias of {@link ByteBuffer#writeUint16}.
       * @function
       * @param {number} value Value to write
       * @param {number=} offset Offset to write to. Will use and advance {@link ByteBuffer#offset} by `2` if omitted.
       * @throws {TypeError} If `offset` or `value` is not a valid number
       * @throws {RangeError} If `offset` is out of bounds
       * @expose
       */
      ByteBufferPrototype.writeUInt16 = ByteBufferPrototype.writeUint16;
  
      /**
       * Reads a 16bit unsigned integer.
       * @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `2` if omitted.
       * @returns {number} Value read
       * @throws {TypeError} If `offset` is not a valid number
       * @throws {RangeError} If `offset` is out of bounds
       * @expose
       */
      ByteBufferPrototype.readUint16 = function(offset) {
          var relative = typeof offset === 'undefined';
          if (relative) offset = this.offset;
          if (!this.noAssert) {
              if (typeof offset !== 'number' || offset % 1 !== 0)
                  throw TypeError("Illegal offset: "+offset+" (not an integer)");
              offset >>>= 0;
              if (offset < 0 || offset + 2 > this.buffer.byteLength)
                  throw RangeError("Illegal offset: 0 <= "+offset+" (+"+2+") <= "+this.buffer.byteLength);
          }
          var value = 0;
          if (this.littleEndian) {
              value  = this.view[offset  ];
              value |= this.view[offset+1] << 8;
          } else {
              value  = this.view[offset  ] << 8;
              value |= this.view[offset+1];
          }
          if (relative) this.offset += 2;
          return value;
      };
  
      /**
       * Reads a 16bit unsigned integer. This is an alias of {@link ByteBuffer#readUint16}.
       * @function
       * @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `2` if omitted.
       * @returns {number} Value read
       * @throws {TypeError} If `offset` is not a valid number
       * @throws {RangeError} If `offset` is out of bounds
       * @expose
       */
      ByteBufferPrototype.readUInt16 = ByteBufferPrototype.readUint16;
  
      // types/ints/int32
  
      /**
       * Writes a 32bit signed integer.
       * @param {number} value Value to write
       * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `4` if omitted.
       * @expose
       */
      ByteBufferPrototype.writeInt32 = function(value, offset) {
          var relative = typeof offset === 'undefined';
          if (relative) offset = this.offset;
          if (!this.noAssert) {
              if (typeof value !== 'number' || value % 1 !== 0)
                  throw TypeError("Illegal value: "+value+" (not an integer)");
              value |= 0;
              if (typeof offset !== 'number' || offset % 1 !== 0)
                  throw TypeError("Illegal offset: "+offset+" (not an integer)");
              offset >>>= 0;
              if (offset < 0 || offset + 0 > this.buffer.byteLength)
                  throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
          }
          offset += 4;
          var capacity4 = this.buffer.byteLength;
          if (offset > capacity4)
              this.resize((capacity4 *= 2) > offset ? capacity4 : offset);
          offset -= 4;
          if (this.littleEndian) {
              this.view[offset+3] = (value >>> 24) & 0xFF;
              this.view[offset+2] = (value >>> 16) & 0xFF;
              this.view[offset+1] = (value >>>  8) & 0xFF;
              this.view[offset  ] =  value         & 0xFF;
          } else {
              this.view[offset  ] = (value >>> 24) & 0xFF;
              this.view[offset+1] = (value >>> 16) & 0xFF;
              this.view[offset+2] = (value >>>  8) & 0xFF;
              this.view[offset+3] =  value         & 0xFF;
          }
          if (relative) this.offset += 4;
          return this;
      };
  
      /**
       * Writes a 32bit signed integer. This is an alias of {@link ByteBuffer#writeInt32}.
       * @param {number} value Value to write
       * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `4` if omitted.
       * @expose
       */
      ByteBufferPrototype.writeInt = ByteBufferPrototype.writeInt32;
  
      /**
       * Reads a 32bit signed integer.
       * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `4` if omitted.
       * @returns {number} Value read
       * @expose
       */
      ByteBufferPrototype.readInt32 = function(offset) {
          var relative = typeof offset === 'undefined';
          if (relative) offset = this.offset;
          if (!this.noAssert) {
              if (typeof offset !== 'number' || offset % 1 !== 0)
                  throw TypeError("Illegal offset: "+offset+" (not an integer)");
              offset >>>= 0;
              if (offset < 0 || offset + 4 > this.buffer.byteLength)
                  throw RangeError("Illegal offset: 0 <= "+offset+" (+"+4+") <= "+this.buffer.byteLength);
          }
          var value = 0;
          if (this.littleEndian) {
              value  = this.view[offset+2] << 16;
              value |= this.view[offset+1] <<  8;
              value |= this.view[offset  ];
              value += this.view[offset+3] << 24 >>> 0;
          } else {
              value  = this.view[offset+1] << 16;
              value |= this.view[offset+2] <<  8;
              value |= this.view[offset+3];
              value += this.view[offset  ] << 24 >>> 0;
          }
          value |= 0; // Cast to signed
          if (relative) this.offset += 4;
          return value;
      };
  
      /**
       * Reads a 32bit signed integer. This is an alias of {@link ByteBuffer#readInt32}.
       * @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `4` if omitted.
       * @returns {number} Value read
       * @expose
       */
      ByteBufferPrototype.readInt = ByteBufferPrototype.readInt32;
  
      /**
       * Writes a 32bit unsigned integer.
       * @param {number} value Value to write
       * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `4` if omitted.
       * @expose
       */
      ByteBufferPrototype.writeUint32 = function(value, offset) {
          var relative = typeof offset === 'undefined';
          if (relative) offset = this.offset;
          if (!this.noAssert) {
              if (typeof value !== 'number' || value % 1 !== 0)
                  throw TypeError("Illegal value: "+value+" (not an integer)");
              value >>>= 0;
              if (typeof offset !== 'number' || offset % 1 !== 0)
                  throw TypeError("Illegal offset: "+offset+" (not an integer)");
              offset >>>= 0;
              if (offset < 0 || offset + 0 > this.buffer.byteLength)
                  throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
          }
          offset += 4;
          var capacity5 = this.buffer.byteLength;
          if (offset > capacity5)
              this.resize((capacity5 *= 2) > offset ? capacity5 : offset);
          offset -= 4;
          if (this.littleEndian) {
              this.view[offset+3] = (value >>> 24) & 0xFF;
              this.view[offset+2] = (value >>> 16) & 0xFF;
              this.view[offset+1] = (value >>>  8) & 0xFF;
              this.view[offset  ] =  value         & 0xFF;
          } else {
              this.view[offset  ] = (value >>> 24) & 0xFF;
              this.view[offset+1] = (value >>> 16) & 0xFF;
              this.view[offset+2] = (value >>>  8) & 0xFF;
              this.view[offset+3] =  value         & 0xFF;
          }
          if (relative) this.offset += 4;
          return this;
      };
  
      /**
       * Writes a 32bit unsigned integer. This is an alias of {@link ByteBuffer#writeUint32}.
       * @function
       * @param {number} value Value to write
       * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `4` if omitted.
       * @expose
       */
      ByteBufferPrototype.writeUInt32 = ByteBufferPrototype.writeUint32;
  
      /**
       * Reads a 32bit unsigned integer.
       * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `4` if omitted.
       * @returns {number} Value read
       * @expose
       */
      ByteBufferPrototype.readUint32 = function(offset) {
          var relative = typeof offset === 'undefined';
          if (relative) offset = this.offset;
          if (!this.noAssert) {
              if (typeof offset !== 'number' || offset % 1 !== 0)
                  throw TypeError("Illegal offset: "+offset+" (not an integer)");
              offset >>>= 0;
              if (offset < 0 || offset + 4 > this.buffer.byteLength)
                  throw RangeError("Illegal offset: 0 <= "+offset+" (+"+4+") <= "+this.buffer.byteLength);
          }
          var value = 0;
          if (this.littleEndian) {
              value  = this.view[offset+2] << 16;
              value |= this.view[offset+1] <<  8;
              value |= this.view[offset  ];
              value += this.view[offset+3] << 24 >>> 0;
          } else {
              value  = this.view[offset+1] << 16;
              value |= this.view[offset+2] <<  8;
              value |= this.view[offset+3];
              value += this.view[offset  ] << 24 >>> 0;
          }
          if (relative) this.offset += 4;
          return value;
      };
  
      /**
       * Reads a 32bit unsigned integer. This is an alias of {@link ByteBuffer#readUint32}.
       * @function
       * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `4` if omitted.
       * @returns {number} Value read
       * @expose
       */
      ByteBufferPrototype.readUInt32 = ByteBufferPrototype.readUint32;
  
      // types/ints/int64
  
      if (Long) {
  
          /**
           * Writes a 64bit signed integer.
           * @param {number|!Long} value Value to write
           * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `8` if omitted.
           * @returns {!ByteBuffer} this
           * @expose
           */
          ByteBufferPrototype.writeInt64 = function(value, offset) {
              var relative = typeof offset === 'undefined';
              if (relative) offset = this.offset;
              if (!this.noAssert) {
                  if (typeof value === 'number')
                      value = Long.fromNumber(value);
                  else if (typeof value === 'string')
                      value = Long.fromString(value);
                  else if (!(value && value instanceof Long))
                      throw TypeError("Illegal value: "+value+" (not an integer or Long)");
                  if (typeof offset !== 'number' || offset % 1 !== 0)
                      throw TypeError("Illegal offset: "+offset+" (not an integer)");
                  offset >>>= 0;
                  if (offset < 0 || offset + 0 > this.buffer.byteLength)
                      throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
              }
              if (typeof value === 'number')
                  value = Long.fromNumber(value);
              else if (typeof value === 'string')
                  value = Long.fromString(value);
              offset += 8;
              var capacity6 = this.buffer.byteLength;
              if (offset > capacity6)
                  this.resize((capacity6 *= 2) > offset ? capacity6 : offset);
              offset -= 8;
              var lo = value.low,
                  hi = value.high;
              if (this.littleEndian) {
                  this.view[offset+3] = (lo >>> 24) & 0xFF;
                  this.view[offset+2] = (lo >>> 16) & 0xFF;
                  this.view[offset+1] = (lo >>>  8) & 0xFF;
                  this.view[offset  ] =  lo         & 0xFF;
                  offset += 4;
                  this.view[offset+3] = (hi >>> 24) & 0xFF;
                  this.view[offset+2] = (hi >>> 16) & 0xFF;
                  this.view[offset+1] = (hi >>>  8) & 0xFF;
                  this.view[offset  ] =  hi         & 0xFF;
              } else {
                  this.view[offset  ] = (hi >>> 24) & 0xFF;
                  this.view[offset+1] = (hi >>> 16) & 0xFF;
                  this.view[offset+2] = (hi >>>  8) & 0xFF;
                  this.view[offset+3] =  hi         & 0xFF;
                  offset += 4;
                  this.view[offset  ] = (lo >>> 24) & 0xFF;
                  this.view[offset+1] = (lo >>> 16) & 0xFF;
                  this.view[offset+2] = (lo >>>  8) & 0xFF;
                  this.view[offset+3] =  lo         & 0xFF;
              }
              if (relative) this.offset += 8;
              return this;
          };
  
          /**
           * Writes a 64bit signed integer. This is an alias of {@link ByteBuffer#writeInt64}.
           * @param {number|!Long} value Value to write
           * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `8` if omitted.
           * @returns {!ByteBuffer} this
           * @expose
           */
          ByteBufferPrototype.writeLong = ByteBufferPrototype.writeInt64;
  
          /**
           * Reads a 64bit signed integer.
           * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `8` if omitted.
           * @returns {!Long}
           * @expose
           */
          ByteBufferPrototype.readInt64 = function(offset) {
              var relative = typeof offset === 'undefined';
              if (relative) offset = this.offset;
              if (!this.noAssert) {
                  if (typeof offset !== 'number' || offset % 1 !== 0)
                      throw TypeError("Illegal offset: "+offset+" (not an integer)");
                  offset >>>= 0;
                  if (offset < 0 || offset + 8 > this.buffer.byteLength)
                      throw RangeError("Illegal offset: 0 <= "+offset+" (+"+8+") <= "+this.buffer.byteLength);
              }
              var lo = 0,
                  hi = 0;
              if (this.littleEndian) {
                  lo  = this.view[offset+2] << 16;
                  lo |= this.view[offset+1] <<  8;
                  lo |= this.view[offset  ];
                  lo += this.view[offset+3] << 24 >>> 0;
                  offset += 4;
                  hi  = this.view[offset+2] << 16;
                  hi |= this.view[offset+1] <<  8;
                  hi |= this.view[offset  ];
                  hi += this.view[offset+3] << 24 >>> 0;
              } else {
                  hi  = this.view[offset+1] << 16;
                  hi |= this.view[offset+2] <<  8;
                  hi |= this.view[offset+3];
                  hi += this.view[offset  ] << 24 >>> 0;
                  offset += 4;
                  lo  = this.view[offset+1] << 16;
                  lo |= this.view[offset+2] <<  8;
                  lo |= this.view[offset+3];
                  lo += this.view[offset  ] << 24 >>> 0;
              }
              var value = new Long(lo, hi, false);
              if (relative) this.offset += 8;
              return value;
          };
  
          /**
           * Reads a 64bit signed integer. This is an alias of {@link ByteBuffer#readInt64}.
           * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `8` if omitted.
           * @returns {!Long}
           * @expose
           */
          ByteBufferPrototype.readLong = ByteBufferPrototype.readInt64;
  
          /**
           * Writes a 64bit unsigned integer.
           * @param {number|!Long} value Value to write
           * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `8` if omitted.
           * @returns {!ByteBuffer} this
           * @expose
           */
          ByteBufferPrototype.writeUint64 = function(value, offset) {
              var relative = typeof offset === 'undefined';
              if (relative) offset = this.offset;
              if (!this.noAssert) {
                  if (typeof value === 'number')
                      value = Long.fromNumber(value);
                  else if (typeof value === 'string')
                      value = Long.fromString(value);
                  else if (!(value && value instanceof Long))
                      throw TypeError("Illegal value: "+value+" (not an integer or Long)");
                  if (typeof offset !== 'number' || offset % 1 !== 0)
                      throw TypeError("Illegal offset: "+offset+" (not an integer)");
                  offset >>>= 0;
                  if (offset < 0 || offset + 0 > this.buffer.byteLength)
                      throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
              }
              if (typeof value === 'number')
                  value = Long.fromNumber(value);
              else if (typeof value === 'string')
                  value = Long.fromString(value);
              offset += 8;
              var capacity7 = this.buffer.byteLength;
              if (offset > capacity7)
                  this.resize((capacity7 *= 2) > offset ? capacity7 : offset);
              offset -= 8;
              var lo = value.low,
                  hi = value.high;
              if (this.littleEndian) {
                  this.view[offset+3] = (lo >>> 24) & 0xFF;
                  this.view[offset+2] = (lo >>> 16) & 0xFF;
                  this.view[offset+1] = (lo >>>  8) & 0xFF;
                  this.view[offset  ] =  lo         & 0xFF;
                  offset += 4;
                  this.view[offset+3] = (hi >>> 24) & 0xFF;
                  this.view[offset+2] = (hi >>> 16) & 0xFF;
                  this.view[offset+1] = (hi >>>  8) & 0xFF;
                  this.view[offset  ] =  hi         & 0xFF;
              } else {
                  this.view[offset  ] = (hi >>> 24) & 0xFF;
                  this.view[offset+1] = (hi >>> 16) & 0xFF;
                  this.view[offset+2] = (hi >>>  8) & 0xFF;
                  this.view[offset+3] =  hi         & 0xFF;
                  offset += 4;
                  this.view[offset  ] = (lo >>> 24) & 0xFF;
                  this.view[offset+1] = (lo >>> 16) & 0xFF;
                  this.view[offset+2] = (lo >>>  8) & 0xFF;
                  this.view[offset+3] =  lo         & 0xFF;
              }
              if (relative) this.offset += 8;
              return this;
          };
  
          /**
           * Writes a 64bit unsigned integer. This is an alias of {@link ByteBuffer#writeUint64}.
           * @function
           * @param {number|!Long} value Value to write
           * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `8` if omitted.
           * @returns {!ByteBuffer} this
           * @expose
           */
          ByteBufferPrototype.writeUInt64 = ByteBufferPrototype.writeUint64;
  
          /**
           * Reads a 64bit unsigned integer.
           * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `8` if omitted.
           * @returns {!Long}
           * @expose
           */
          ByteBufferPrototype.readUint64 = function(offset) {
              var relative = typeof offset === 'undefined';
              if (relative) offset = this.offset;
              if (!this.noAssert) {
                  if (typeof offset !== 'number' || offset % 1 !== 0)
                      throw TypeError("Illegal offset: "+offset+" (not an integer)");
                  offset >>>= 0;
                  if (offset < 0 || offset + 8 > this.buffer.byteLength)
                      throw RangeError("Illegal offset: 0 <= "+offset+" (+"+8+") <= "+this.buffer.byteLength);
              }
              var lo = 0,
                  hi = 0;
              if (this.littleEndian) {
                  lo  = this.view[offset+2] << 16;
                  lo |= this.view[offset+1] <<  8;
                  lo |= this.view[offset  ];
                  lo += this.view[offset+3] << 24 >>> 0;
                  offset += 4;
                  hi  = this.view[offset+2] << 16;
                  hi |= this.view[offset+1] <<  8;
                  hi |= this.view[offset  ];
                  hi += this.view[offset+3] << 24 >>> 0;
              } else {
                  hi  = this.view[offset+1] << 16;
                  hi |= this.view[offset+2] <<  8;
                  hi |= this.view[offset+3];
                  hi += this.view[offset  ] << 24 >>> 0;
                  offset += 4;
                  lo  = this.view[offset+1] << 16;
                  lo |= this.view[offset+2] <<  8;
                  lo |= this.view[offset+3];
                  lo += this.view[offset  ] << 24 >>> 0;
              }
              var value = new Long(lo, hi, true);
              if (relative) this.offset += 8;
              return value;
          };
  
          /**
           * Reads a 64bit unsigned integer. This is an alias of {@link ByteBuffer#readUint64}.
           * @function
           * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `8` if omitted.
           * @returns {!Long}
           * @expose
           */
          ByteBufferPrototype.readUInt64 = ByteBufferPrototype.readUint64;
  
      } // Long
  
  
      // types/floats/float32
  
      /*
       ieee754 - https://github.com/feross/ieee754
  
       The MIT License (MIT)
  
       Copyright (c) Feross Aboukhadijeh
  
       Permission is hereby granted, free of charge, to any person obtaining a copy
       of this software and associated documentation files (the "Software"), to deal
       in the Software without restriction, including without limitation the rights
       to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
       copies of the Software, and to permit persons to whom the Software is
       furnished to do so, subject to the following conditions:
  
       The above copyright notice and this permission notice shall be included in
       all copies or substantial portions of the Software.
  
       THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
       IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
       FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
       AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
       LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
       OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
       THE SOFTWARE.
      */
  
      /**
       * Reads an IEEE754 float from a byte array.
       * @param {!Array} buffer
       * @param {number} offset
       * @param {boolean} isLE
       * @param {number} mLen
       * @param {number} nBytes
       * @returns {number}
       * @inner
       */
      function ieee754_read(buffer, offset, isLE, mLen, nBytes) {
          var e, m,
              eLen = nBytes * 8 - mLen - 1,
              eMax = (1 << eLen) - 1,
              eBias = eMax >> 1,
              nBits = -7,
              i = isLE ? (nBytes - 1) : 0,
              d = isLE ? -1 : 1,
              s = buffer[offset + i];
  
          i += d;
  
          e = s & ((1 << (-nBits)) - 1);
          s >>= (-nBits);
          nBits += eLen;
          for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8) {}
  
          m = e & ((1 << (-nBits)) - 1);
          e >>= (-nBits);
          nBits += mLen;
          for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8) {}
  
          if (e === 0) {
              e = 1 - eBias;
          } else if (e === eMax) {
              return m ? NaN : ((s ? -1 : 1) * Infinity);
          } else {
              m = m + Math.pow(2, mLen);
              e = e - eBias;
          }
          return (s ? -1 : 1) * m * Math.pow(2, e - mLen);
      }
  
      /**
       * Writes an IEEE754 float to a byte array.
       * @param {!Array} buffer
       * @param {number} value
       * @param {number} offset
       * @param {boolean} isLE
       * @param {number} mLen
       * @param {number} nBytes
       * @inner
       */
      function ieee754_write(buffer, value, offset, isLE, mLen, nBytes) {
          var e, m, c,
              eLen = nBytes * 8 - mLen - 1,
              eMax = (1 << eLen) - 1,
              eBias = eMax >> 1,
              rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0),
              i = isLE ? 0 : (nBytes - 1),
              d = isLE ? 1 : -1,
              s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0;
  
          value = Math.abs(value);
  
          if (isNaN(value) || value === Infinity) {
              m = isNaN(value) ? 1 : 0;
              e = eMax;
          } else {
              e = Math.floor(Math.log(value) / Math.LN2);
              if (value * (c = Math.pow(2, -e)) < 1) {
                  e--;
                  c *= 2;
              }
              if (e + eBias >= 1) {
                  value += rt / c;
              } else {
                  value += rt * Math.pow(2, 1 - eBias);
              }
              if (value * c >= 2) {
                  e++;
                  c /= 2;
              }
  
              if (e + eBias >= eMax) {
                  m = 0;
                  e = eMax;
              } else if (e + eBias >= 1) {
                  m = (value * c - 1) * Math.pow(2, mLen);
                  e = e + eBias;
              } else {
                  m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen);
                  e = 0;
              }
          }
  
          for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {}
  
          e = (e << mLen) | m;
          eLen += mLen;
          for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {}
  
          buffer[offset + i - d] |= s * 128;
      }
  
      /**
       * Writes a 32bit float.
       * @param {number} value Value to write
       * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `4` if omitted.
       * @returns {!ByteBuffer} this
       * @expose
       */
      ByteBufferPrototype.writeFloat32 = function(value, offset) {
          var relative = typeof offset === 'undefined';
          if (relative) offset = this.offset;
          if (!this.noAssert) {
              if (typeof value !== 'number')
                  throw TypeError("Illegal value: "+value+" (not a number)");
              if (typeof offset !== 'number' || offset % 1 !== 0)
                  throw TypeError("Illegal offset: "+offset+" (not an integer)");
              offset >>>= 0;
              if (offset < 0 || offset + 0 > this.buffer.byteLength)
                  throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
          }
          offset += 4;
          var capacity8 = this.buffer.byteLength;
          if (offset > capacity8)
              this.resize((capacity8 *= 2) > offset ? capacity8 : offset);
          offset -= 4;
          ieee754_write(this.view, value, offset, this.littleEndian, 23, 4);
          if (relative) this.offset += 4;
          return this;
      };
  
      /**
       * Writes a 32bit float. This is an alias of {@link ByteBuffer#writeFloat32}.
       * @function
       * @param {number} value Value to write
       * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `4` if omitted.
       * @returns {!ByteBuffer} this
       * @expose
       */
      ByteBufferPrototype.writeFloat = ByteBufferPrototype.writeFloat32;
  
      /**
       * Reads a 32bit float.
       * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `4` if omitted.
       * @returns {number}
       * @expose
       */
      ByteBufferPrototype.readFloat32 = function(offset) {
          var relative = typeof offset === 'undefined';
          if (relative) offset = this.offset;
          if (!this.noAssert) {
              if (typeof offset !== 'number' || offset % 1 !== 0)
                  throw TypeError("Illegal offset: "+offset+" (not an integer)");
              offset >>>= 0;
              if (offset < 0 || offset + 4 > this.buffer.byteLength)
                  throw RangeError("Illegal offset: 0 <= "+offset+" (+"+4+") <= "+this.buffer.byteLength);
          }
          var value = ieee754_read(this.view, offset, this.littleEndian, 23, 4);
          if (relative) this.offset += 4;
          return value;
      };
  
      /**
       * Reads a 32bit float. This is an alias of {@link ByteBuffer#readFloat32}.
       * @function
       * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `4` if omitted.
       * @returns {number}
       * @expose
       */
      ByteBufferPrototype.readFloat = ByteBufferPrototype.readFloat32;
  
      // types/floats/float64
  
      /**
       * Writes a 64bit float.
       * @param {number} value Value to write
       * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `8` if omitted.
       * @returns {!ByteBuffer} this
       * @expose
       */
      ByteBufferPrototype.writeFloat64 = function(value, offset) {
          var relative = typeof offset === 'undefined';
          if (relative) offset = this.offset;
          if (!this.noAssert) {
              if (typeof value !== 'number')
                  throw TypeError("Illegal value: "+value+" (not a number)");
              if (typeof offset !== 'number' || offset % 1 !== 0)
                  throw TypeError("Illegal offset: "+offset+" (not an integer)");
              offset >>>= 0;
              if (offset < 0 || offset + 0 > this.buffer.byteLength)
                  throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
          }
          offset += 8;
          var capacity9 = this.buffer.byteLength;
          if (offset > capacity9)
              this.resize((capacity9 *= 2) > offset ? capacity9 : offset);
          offset -= 8;
          ieee754_write(this.view, value, offset, this.littleEndian, 52, 8);
          if (relative) this.offset += 8;
          return this;
      };
  
      /**
       * Writes a 64bit float. This is an alias of {@link ByteBuffer#writeFloat64}.
       * @function
       * @param {number} value Value to write
       * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `8` if omitted.
       * @returns {!ByteBuffer} this
       * @expose
       */
      ByteBufferPrototype.writeDouble = ByteBufferPrototype.writeFloat64;
  
      /**
       * Reads a 64bit float.
       * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `8` if omitted.
       * @returns {number}
       * @expose
       */
      ByteBufferPrototype.readFloat64 = function(offset) {
          var relative = typeof offset === 'undefined';
          if (relative) offset = this.offset;
          if (!this.noAssert) {
              if (typeof offset !== 'number' || offset % 1 !== 0)
                  throw TypeError("Illegal offset: "+offset+" (not an integer)");
              offset >>>= 0;
              if (offset < 0 || offset + 8 > this.buffer.byteLength)
                  throw RangeError("Illegal offset: 0 <= "+offset+" (+"+8+") <= "+this.buffer.byteLength);
          }
          var value = ieee754_read(this.view, offset, this.littleEndian, 52, 8);
          if (relative) this.offset += 8;
          return value;
      };
  
      /**
       * Reads a 64bit float. This is an alias of {@link ByteBuffer#readFloat64}.
       * @function
       * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `8` if omitted.
       * @returns {number}
       * @expose
       */
      ByteBufferPrototype.readDouble = ByteBufferPrototype.readFloat64;
  
  
      // types/varints/varint32
  
      /**
       * Maximum number of bytes required to store a 32bit base 128 variable-length integer.
       * @type {number}
       * @const
       * @expose
       */
      ByteBuffer.MAX_VARINT32_BYTES = 5;
  
      /**
       * Calculates the actual number of bytes required to store a 32bit base 128 variable-length integer.
       * @param {number} value Value to encode
       * @returns {number} Number of bytes required. Capped to {@link ByteBuffer.MAX_VARINT32_BYTES}
       * @expose
       */
      ByteBuffer.calculateVarint32 = function(value) {
          // ref: src/google/protobuf/io/coded_stream.cc
          value = value >>> 0;
               if (value < 1 << 7 ) return 1;
          else if (value < 1 << 14) return 2;
          else if (value < 1 << 21) return 3;
          else if (value < 1 << 28) return 4;
          else                      return 5;
      };
  
      /**
       * Zigzag encodes a signed 32bit integer so that it can be effectively used with varint encoding.
       * @param {number} n Signed 32bit integer
       * @returns {number} Unsigned zigzag encoded 32bit integer
       * @expose
       */
      ByteBuffer.zigZagEncode32 = function(n) {
          return (((n |= 0) << 1) ^ (n >> 31)) >>> 0; // ref: src/google/protobuf/wire_format_lite.h
      };
  
      /**
       * Decodes a zigzag encoded signed 32bit integer.
       * @param {number} n Unsigned zigzag encoded 32bit integer
       * @returns {number} Signed 32bit integer
       * @expose
       */
      ByteBuffer.zigZagDecode32 = function(n) {
          return ((n >>> 1) ^ -(n & 1)) | 0; // // ref: src/google/protobuf/wire_format_lite.h
      };
  
      /**
       * Writes a 32bit base 128 variable-length integer.
       * @param {number} value Value to write
       * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by the number of bytes
       *  written if omitted.
       * @returns {!ByteBuffer|number} this if `offset` is omitted, else the actual number of bytes written
       * @expose
       */
      ByteBufferPrototype.writeVarint32 = function(value, offset) {
          var relative = typeof offset === 'undefined';
          if (relative) offset = this.offset;
          if (!this.noAssert) {
              if (typeof value !== 'number' || value % 1 !== 0)
                  throw TypeError("Illegal value: "+value+" (not an integer)");
              value |= 0;
              if (typeof offset !== 'number' || offset % 1 !== 0)
                  throw TypeError("Illegal offset: "+offset+" (not an integer)");
              offset >>>= 0;
              if (offset < 0 || offset + 0 > this.buffer.byteLength)
                  throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
          }
          var size = ByteBuffer.calculateVarint32(value),
              b;
          offset += size;
          var capacity10 = this.buffer.byteLength;
          if (offset > capacity10)
              this.resize((capacity10 *= 2) > offset ? capacity10 : offset);
          offset -= size;
          value >>>= 0;
          while (value >= 0x80) {
              b = (value & 0x7f) | 0x80;
              this.view[offset++] = b;
              value >>>= 7;
          }
          this.view[offset++] = value;
          if (relative) {
              this.offset = offset;
              return this;
          }
          return size;
      };
  
      /**
       * Writes a zig-zag encoded (signed) 32bit base 128 variable-length integer.
       * @param {number} value Value to write
       * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by the number of bytes
       *  written if omitted.
       * @returns {!ByteBuffer|number} this if `offset` is omitted, else the actual number of bytes written
       * @expose
       */
      ByteBufferPrototype.writeVarint32ZigZag = function(value, offset) {
          return this.writeVarint32(ByteBuffer.zigZagEncode32(value), offset);
      };
  
      /**
       * Reads a 32bit base 128 variable-length integer.
       * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by the number of bytes
       *  written if omitted.
       * @returns {number|!{value: number, length: number}} The value read if offset is omitted, else the value read
       *  and the actual number of bytes read.
       * @throws {Error} If it's not a valid varint. Has a property `truncated = true` if there is not enough data available
       *  to fully decode the varint.
       * @expose
       */
      ByteBufferPrototype.readVarint32 = function(offset) {
          var relative = typeof offset === 'undefined';
          if (relative) offset = this.offset;
          if (!this.noAssert) {
              if (typeof offset !== 'number' || offset % 1 !== 0)
                  throw TypeError("Illegal offset: "+offset+" (not an integer)");
              offset >>>= 0;
              if (offset < 0 || offset + 1 > this.buffer.byteLength)
                  throw RangeError("Illegal offset: 0 <= "+offset+" (+"+1+") <= "+this.buffer.byteLength);
          }
          var c = 0,
              value = 0 >>> 0,
              b;
          do {
              if (!this.noAssert && offset > this.limit) {
                  var err = Error("Truncated");
                  err['truncated'] = true;
                  throw err;
              }
              b = this.view[offset++];
              if (c < 5)
                  value |= (b & 0x7f) << (7*c);
              ++c;
          } while ((b & 0x80) !== 0);
          value |= 0;
          if (relative) {
              this.offset = offset;
              return value;
          }
          return {
              "value": value,
              "length": c
          };
      };
  
      /**
       * Reads a zig-zag encoded (signed) 32bit base 128 variable-length integer.
       * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by the number of bytes
       *  written if omitted.
       * @returns {number|!{value: number, length: number}} The value read if offset is omitted, else the value read
       *  and the actual number of bytes read.
       * @throws {Error} If it's not a valid varint
       * @expose
       */
      ByteBufferPrototype.readVarint32ZigZag = function(offset) {
          var val = this.readVarint32(offset);
          if (typeof val === 'object')
              val["value"] = ByteBuffer.zigZagDecode32(val["value"]);
          else
              val = ByteBuffer.zigZagDecode32(val);
          return val;
      };
  
      // types/varints/varint64
  
      if (Long) {
  
          /**
           * Maximum number of bytes required to store a 64bit base 128 variable-length integer.
           * @type {number}
           * @const
           * @expose
           */
          ByteBuffer.MAX_VARINT64_BYTES = 10;
  
          /**
           * Calculates the actual number of bytes required to store a 64bit base 128 variable-length integer.
           * @param {number|!Long} value Value to encode
           * @returns {number} Number of bytes required. Capped to {@link ByteBuffer.MAX_VARINT64_BYTES}
           * @expose
           */
          ByteBuffer.calculateVarint64 = function(value) {
              if (typeof value === 'number')
                  value = Long.fromNumber(value);
              else if (typeof value === 'string')
                  value = Long.fromString(value);
              // ref: src/google/protobuf/io/coded_stream.cc
              var part0 = value.toInt() >>> 0,
                  part1 = value.shiftRightUnsigned(28).toInt() >>> 0,
                  part2 = value.shiftRightUnsigned(56).toInt() >>> 0;
              if (part2 == 0) {
                  if (part1 == 0) {
                      if (part0 < 1 << 14)
                          return part0 < 1 << 7 ? 1 : 2;
                      else
                          return part0 < 1 << 21 ? 3 : 4;
                  } else {
                      if (part1 < 1 << 14)
                          return part1 < 1 << 7 ? 5 : 6;
                      else
                          return part1 < 1 << 21 ? 7 : 8;
                  }
              } else
                  return part2 < 1 << 7 ? 9 : 10;
          };
  
          /**
           * Zigzag encodes a signed 64bit integer so that it can be effectively used with varint encoding.
           * @param {number|!Long} value Signed long
           * @returns {!Long} Unsigned zigzag encoded long
           * @expose
           */
          ByteBuffer.zigZagEncode64 = function(value) {
              if (typeof value === 'number')
                  value = Long.fromNumber(value, false);
              else if (typeof value === 'string')
                  value = Long.fromString(value, false);
              else if (value.unsigned !== false) value = value.toSigned();
              // ref: src/google/protobuf/wire_format_lite.h
              return value.shiftLeft(1).xor(value.shiftRight(63)).toUnsigned();
          };
  
          /**
           * Decodes a zigzag encoded signed 64bit integer.
           * @param {!Long|number} value Unsigned zigzag encoded long or JavaScript number
           * @returns {!Long} Signed long
           * @expose
           */
          ByteBuffer.zigZagDecode64 = function(value) {
              if (typeof value === 'number')
                  value = Long.fromNumber(value, false);
              else if (typeof value === 'string')
                  value = Long.fromString(value, false);
              else if (value.unsigned !== false) value = value.toSigned();
              // ref: src/google/protobuf/wire_format_lite.h
              return value.shiftRightUnsigned(1).xor(value.and(Long.ONE).toSigned().negate()).toSigned();
          };
  
          /**
           * Writes a 64bit base 128 variable-length integer.
           * @param {number|Long} value Value to write
           * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by the number of bytes
           *  written if omitted.
           * @returns {!ByteBuffer|number} `this` if offset is omitted, else the actual number of bytes written.
           * @expose
           */
          ByteBufferPrototype.writeVarint64 = function(value, offset) {
              var relative = typeof offset === 'undefined';
              if (relative) offset = this.offset;
              if (!this.noAssert) {
                  if (typeof value === 'number')
                      value = Long.fromNumber(value);
                  else if (typeof value === 'string')
                      value = Long.fromString(value);
                  else if (!(value && value instanceof Long))
                      throw TypeError("Illegal value: "+value+" (not an integer or Long)");
                  if (typeof offset !== 'number' || offset % 1 !== 0)
                      throw TypeError("Illegal offset: "+offset+" (not an integer)");
                  offset >>>= 0;
                  if (offset < 0 || offset + 0 > this.buffer.byteLength)
                      throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
              }
              if (typeof value === 'number')
                  value = Long.fromNumber(value, false);
              else if (typeof value === 'string')
                  value = Long.fromString(value, false);
              else if (value.unsigned !== false) value = value.toSigned();
              var size = ByteBuffer.calculateVarint64(value),
                  part0 = value.toInt() >>> 0,
                  part1 = value.shiftRightUnsigned(28).toInt() >>> 0,
                  part2 = value.shiftRightUnsigned(56).toInt() >>> 0;
              offset += size;
              var capacity11 = this.buffer.byteLength;
              if (offset > capacity11)
                  this.resize((capacity11 *= 2) > offset ? capacity11 : offset);
              offset -= size;
              switch (size) {
                  case 10: this.view[offset+9] = (part2 >>>  7) & 0x01;
                  case 9 : this.view[offset+8] = size !== 9 ? (part2       ) | 0x80 : (part2       ) & 0x7F;
                  case 8 : this.view[offset+7] = size !== 8 ? (part1 >>> 21) | 0x80 : (part1 >>> 21) & 0x7F;
                  case 7 : this.view[offset+6] = size !== 7 ? (part1 >>> 14) | 0x80 : (part1 >>> 14) & 0x7F;
                  case 6 : this.view[offset+5] = size !== 6 ? (part1 >>>  7) | 0x80 : (part1 >>>  7) & 0x7F;
                  case 5 : this.view[offset+4] = size !== 5 ? (part1       ) | 0x80 : (part1       ) & 0x7F;
                  case 4 : this.view[offset+3] = size !== 4 ? (part0 >>> 21) | 0x80 : (part0 >>> 21) & 0x7F;
                  case 3 : this.view[offset+2] = size !== 3 ? (part0 >>> 14) | 0x80 : (part0 >>> 14) & 0x7F;
                  case 2 : this.view[offset+1] = size !== 2 ? (part0 >>>  7) | 0x80 : (part0 >>>  7) & 0x7F;
                  case 1 : this.view[offset  ] = size !== 1 ? (part0       ) | 0x80 : (part0       ) & 0x7F;
              }
              if (relative) {
                  this.offset += size;
                  return this;
              } else {
                  return size;
              }
          };
  
          /**
           * Writes a zig-zag encoded 64bit base 128 variable-length integer.
           * @param {number|Long} value Value to write
           * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by the number of bytes
           *  written if omitted.
           * @returns {!ByteBuffer|number} `this` if offset is omitted, else the actual number of bytes written.
           * @expose
           */
          ByteBufferPrototype.writeVarint64ZigZag = function(value, offset) {
              return this.writeVarint64(ByteBuffer.zigZagEncode64(value), offset);
          };
  
          /**
           * Reads a 64bit base 128 variable-length integer. Requires Long.js.
           * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by the number of bytes
           *  read if omitted.
           * @returns {!Long|!{value: Long, length: number}} The value read if offset is omitted, else the value read and
           *  the actual number of bytes read.
           * @throws {Error} If it's not a valid varint
           * @expose
           */
          ByteBufferPrototype.readVarint64 = function(offset) {
              var relative = typeof offset === 'undefined';
              if (relative) offset = this.offset;
              if (!this.noAssert) {
                  if (typeof offset !== 'number' || offset % 1 !== 0)
                      throw TypeError("Illegal offset: "+offset+" (not an integer)");
                  offset >>>= 0;
                  if (offset < 0 || offset + 1 > this.buffer.byteLength)
                      throw RangeError("Illegal offset: 0 <= "+offset+" (+"+1+") <= "+this.buffer.byteLength);
              }
              // ref: src/google/protobuf/io/coded_stream.cc
              var start = offset,
                  part0 = 0,
                  part1 = 0,
                  part2 = 0,
                  b  = 0;
              b = this.view[offset++]; part0  = (b & 0x7F)      ; if ( b & 0x80                                                   ) {
              b = this.view[offset++]; part0 |= (b & 0x7F) <<  7; if ((b & 0x80) || (this.noAssert && typeof b === 'undefined')) {
              b = this.view[offset++]; part0 |= (b & 0x7F) << 14; if ((b & 0x80) || (this.noAssert && typeof b === 'undefined')) {
              b = this.view[offset++]; part0 |= (b & 0x7F) << 21; if ((b & 0x80) || (this.noAssert && typeof b === 'undefined')) {
              b = this.view[offset++]; part1  = (b & 0x7F)      ; if ((b & 0x80) || (this.noAssert && typeof b === 'undefined')) {
              b = this.view[offset++]; part1 |= (b & 0x7F) <<  7; if ((b & 0x80) || (this.noAssert && typeof b === 'undefined')) {
              b = this.view[offset++]; part1 |= (b & 0x7F) << 14; if ((b & 0x80) || (this.noAssert && typeof b === 'undefined')) {
              b = this.view[offset++]; part1 |= (b & 0x7F) << 21; if ((b & 0x80) || (this.noAssert && typeof b === 'undefined')) {
              b = this.view[offset++]; part2  = (b & 0x7F)      ; if ((b & 0x80) || (this.noAssert && typeof b === 'undefined')) {
              b = this.view[offset++]; part2 |= (b & 0x7F) <<  7; if ((b & 0x80) || (this.noAssert && typeof b === 'undefined')) {
              throw Error("Buffer overrun"); }}}}}}}}}}
              var value = Long.fromBits(part0 | (part1 << 28), (part1 >>> 4) | (part2) << 24, false);
              if (relative) {
                  this.offset = offset;
                  return value;
              } else {
                  return {
                      'value': value,
                      'length': offset-start
                  };
              }
          };
  
          /**
           * Reads a zig-zag encoded 64bit base 128 variable-length integer. Requires Long.js.
           * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by the number of bytes
           *  read if omitted.
           * @returns {!Long|!{value: Long, length: number}} The value read if offset is omitted, else the value read and
           *  the actual number of bytes read.
           * @throws {Error} If it's not a valid varint
           * @expose
           */
          ByteBufferPrototype.readVarint64ZigZag = function(offset) {
              var val = this.readVarint64(offset);
              if (val && val['value'] instanceof Long)
                  val["value"] = ByteBuffer.zigZagDecode64(val["value"]);
              else
                  val = ByteBuffer.zigZagDecode64(val);
              return val;
          };
  
      } // Long
  
  
      // types/strings/cstring
  
      /**
       * Writes a NULL-terminated UTF8 encoded string. For this to work the specified string must not contain any NULL
       *  characters itself.
       * @param {string} str String to write
       * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by the number of bytes
       *  contained in `str` + 1 if omitted.
       * @returns {!ByteBuffer|number} this if offset is omitted, else the actual number of bytes written
       * @expose
       */
      ByteBufferPrototype.writeCString = function(str, offset) {
          var relative = typeof offset === 'undefined';
          if (relative) offset = this.offset;
          var i,
              k = str.length;
          if (!this.noAssert) {
              if (typeof str !== 'string')
                  throw TypeError("Illegal str: Not a string");
              for (i=0; i<k; ++i) {
                  if (str.charCodeAt(i) === 0)
                      throw RangeError("Illegal str: Contains NULL-characters");
              }
              if (typeof offset !== 'number' || offset % 1 !== 0)
                  throw TypeError("Illegal offset: "+offset+" (not an integer)");
              offset >>>= 0;
              if (offset < 0 || offset + 0 > this.buffer.byteLength)
                  throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
          }
          // UTF8 strings do not contain zero bytes in between except for the zero character, so:
          k = utfx.calculateUTF16asUTF8(stringSource(str))[1];
          offset += k+1;
          var capacity12 = this.buffer.byteLength;
          if (offset > capacity12)
              this.resize((capacity12 *= 2) > offset ? capacity12 : offset);
          offset -= k+1;
          utfx.encodeUTF16toUTF8(stringSource(str), function(b) {
              this.view[offset++] = b;
          }.bind(this));
          this.view[offset++] = 0;
          if (relative) {
              this.offset = offset;
              return this;
          }
          return k;
      };
  
      /**
       * Reads a NULL-terminated UTF8 encoded string. For this to work the string read must not contain any NULL characters
       *  itself.
       * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by the number of bytes
       *  read if omitted.
       * @returns {string|!{string: string, length: number}} The string read if offset is omitted, else the string
       *  read and the actual number of bytes read.
       * @expose
       */
      ByteBufferPrototype.readCString = function(offset) {
          var relative = typeof offset === 'undefined';
          if (relative) offset = this.offset;
          if (!this.noAssert) {
              if (typeof offset !== 'number' || offset % 1 !== 0)
                  throw TypeError("Illegal offset: "+offset+" (not an integer)");
              offset >>>= 0;
              if (offset < 0 || offset + 1 > this.buffer.byteLength)
                  throw RangeError("Illegal offset: 0 <= "+offset+" (+"+1+") <= "+this.buffer.byteLength);
          }
          var start = offset,
              temp;
          // UTF8 strings do not contain zero bytes in between except for the zero character itself, so:
          var sd, b = -1;
          utfx.decodeUTF8toUTF16(function() {
              if (b === 0) return null;
              if (offset >= this.limit)
                  throw RangeError("Illegal range: Truncated data, "+offset+" < "+this.limit);
              b = this.view[offset++];
              return b === 0 ? null : b;
          }.bind(this), sd = stringDestination(), true);
          if (relative) {
              this.offset = offset;
              return sd();
          } else {
              return {
                  "string": sd(),
                  "length": offset - start
              };
          }
      };
  
      // types/strings/istring
  
      /**
       * Writes a length as uint32 prefixed UTF8 encoded string.
       * @param {string} str String to write
       * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by the number of bytes
       *  written if omitted.
       * @returns {!ByteBuffer|number} `this` if `offset` is omitted, else the actual number of bytes written
       * @expose
       * @see ByteBuffer#writeVarint32
       */
      ByteBufferPrototype.writeIString = function(str, offset) {
          var relative = typeof offset === 'undefined';
          if (relative) offset = this.offset;
          if (!this.noAssert) {
              if (typeof str !== 'string')
                  throw TypeError("Illegal str: Not a string");
              if (typeof offset !== 'number' || offset % 1 !== 0)
                  throw TypeError("Illegal offset: "+offset+" (not an integer)");
              offset >>>= 0;
              if (offset < 0 || offset + 0 > this.buffer.byteLength)
                  throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
          }
          var start = offset,
              k;
          k = utfx.calculateUTF16asUTF8(stringSource(str), this.noAssert)[1];
          offset += 4+k;
          var capacity13 = this.buffer.byteLength;
          if (offset > capacity13)
              this.resize((capacity13 *= 2) > offset ? capacity13 : offset);
          offset -= 4+k;
          if (this.littleEndian) {
              this.view[offset+3] = (k >>> 24) & 0xFF;
              this.view[offset+2] = (k >>> 16) & 0xFF;
              this.view[offset+1] = (k >>>  8) & 0xFF;
              this.view[offset  ] =  k         & 0xFF;
          } else {
              this.view[offset  ] = (k >>> 24) & 0xFF;
              this.view[offset+1] = (k >>> 16) & 0xFF;
              this.view[offset+2] = (k >>>  8) & 0xFF;
              this.view[offset+3] =  k         & 0xFF;
          }
          offset += 4;
          utfx.encodeUTF16toUTF8(stringSource(str), function(b) {
              this.view[offset++] = b;
          }.bind(this));
          if (offset !== start + 4 + k)
              throw RangeError("Illegal range: Truncated data, "+offset+" == "+(offset+4+k));
          if (relative) {
              this.offset = offset;
              return this;
          }
          return offset - start;
      };
  
      /**
       * Reads a length as uint32 prefixed UTF8 encoded string.
       * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by the number of bytes
       *  read if omitted.
       * @returns {string|!{string: string, length: number}} The string read if offset is omitted, else the string
       *  read and the actual number of bytes read.
       * @expose
       * @see ByteBuffer#readVarint32
       */
      ByteBufferPrototype.readIString = function(offset) {
          var relative = typeof offset === 'undefined';
          if (relative) offset = this.offset;
          if (!this.noAssert) {
              if (typeof offset !== 'number' || offset % 1 !== 0)
                  throw TypeError("Illegal offset: "+offset+" (not an integer)");
              offset >>>= 0;
              if (offset < 0 || offset + 4 > this.buffer.byteLength)
                  throw RangeError("Illegal offset: 0 <= "+offset+" (+"+4+") <= "+this.buffer.byteLength);
          }
          var start = offset;
          var len = this.readUint32(offset);
          var str = this.readUTF8String(len, ByteBuffer.METRICS_BYTES, offset += 4);
          offset += str['length'];
          if (relative) {
              this.offset = offset;
              return str['string'];
          } else {
              return {
                  'string': str['string'],
                  'length': offset - start
              };
          }
      };
  
      // types/strings/utf8string
  
      /**
       * Metrics representing number of UTF8 characters. Evaluates to `c`.
       * @type {string}
       * @const
       * @expose
       */
      ByteBuffer.METRICS_CHARS = 'c';
  
      /**
       * Metrics representing number of bytes. Evaluates to `b`.
       * @type {string}
       * @const
       * @expose
       */
      ByteBuffer.METRICS_BYTES = 'b';
  
      /**
       * Writes an UTF8 encoded string.
       * @param {string} str String to write
       * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} if omitted.
       * @returns {!ByteBuffer|number} this if offset is omitted, else the actual number of bytes written.
       * @expose
       */
      ByteBufferPrototype.writeUTF8String = function(str, offset) {
          var relative = typeof offset === 'undefined';
          if (relative) offset = this.offset;
          if (!this.noAssert) {
              if (typeof offset !== 'number' || offset % 1 !== 0)
                  throw TypeError("Illegal offset: "+offset+" (not an integer)");
              offset >>>= 0;
              if (offset < 0 || offset + 0 > this.buffer.byteLength)
                  throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
          }
          var k;
          var start = offset;
          k = utfx.calculateUTF16asUTF8(stringSource(str))[1];
          offset += k;
          var capacity14 = this.buffer.byteLength;
          if (offset > capacity14)
              this.resize((capacity14 *= 2) > offset ? capacity14 : offset);
          offset -= k;
          utfx.encodeUTF16toUTF8(stringSource(str), function(b) {
              this.view[offset++] = b;
          }.bind(this));
          if (relative) {
              this.offset = offset;
              return this;
          }
          return offset - start;
      };
  
      /**
       * Writes an UTF8 encoded string. This is an alias of {@link ByteBuffer#writeUTF8String}.
       * @function
       * @param {string} str String to write
       * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} if omitted.
       * @returns {!ByteBuffer|number} this if offset is omitted, else the actual number of bytes written.
       * @expose
       */
      ByteBufferPrototype.writeString = ByteBufferPrototype.writeUTF8String;
  
      /**
       * Calculates the number of UTF8 characters of a string. JavaScript itself uses UTF-16, so that a string's
       *  `length` property does not reflect its actual UTF8 size if it contains code points larger than 0xFFFF.
       * @param {string} str String to calculate
       * @returns {number} Number of UTF8 characters
       * @expose
       */
      ByteBuffer.calculateUTF8Chars = function(str) {
          return utfx.calculateUTF16asUTF8(stringSource(str))[0];
      };
  
      /**
       * Calculates the number of UTF8 bytes of a string.
       * @param {string} str String to calculate
       * @returns {number} Number of UTF8 bytes
       * @expose
       */
      ByteBuffer.calculateUTF8Bytes = function(str) {
          return utfx.calculateUTF16asUTF8(stringSource(str))[1];
      };
  
      /**
       * Calculates the number of UTF8 bytes of a string. This is an alias of {@link ByteBuffer.calculateUTF8Bytes}.
       * @function
       * @param {string} str String to calculate
       * @returns {number} Number of UTF8 bytes
       * @expose
       */
      ByteBuffer.calculateString = ByteBuffer.calculateUTF8Bytes;
  
      /**
       * Reads an UTF8 encoded string.
       * @param {number} length Number of characters or bytes to read.
       * @param {string=} metrics Metrics specifying what `length` is meant to count. Defaults to
       *  {@link ByteBuffer.METRICS_CHARS}.
       * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by the number of bytes
       *  read if omitted.
       * @returns {string|!{string: string, length: number}} The string read if offset is omitted, else the string
       *  read and the actual number of bytes read.
       * @expose
       */
      ByteBufferPrototype.readUTF8String = function(length, metrics, offset) {
          if (typeof metrics === 'number') {
              offset = metrics;
              metrics = undefined;
          }
          var relative = typeof offset === 'undefined';
          if (relative) offset = this.offset;
          if (typeof metrics === 'undefined') metrics = ByteBuffer.METRICS_CHARS;
          if (!this.noAssert) {
              if (typeof length !== 'number' || length % 1 !== 0)
                  throw TypeError("Illegal length: "+length+" (not an integer)");
              length |= 0;
              if (typeof offset !== 'number' || offset % 1 !== 0)
                  throw TypeError("Illegal offset: "+offset+" (not an integer)");
              offset >>>= 0;
              if (offset < 0 || offset + 0 > this.buffer.byteLength)
                  throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
          }
          var i = 0,
              start = offset,
              sd;
          if (metrics === ByteBuffer.METRICS_CHARS) { // The same for node and the browser
              sd = stringDestination();
              utfx.decodeUTF8(function() {
                  return i < length && offset < this.limit ? this.view[offset++] : null;
              }.bind(this), function(cp) {
                  ++i; utfx.UTF8toUTF16(cp, sd);
              });
              if (i !== length)
                  throw RangeError("Illegal range: Truncated data, "+i+" == "+length);
              if (relative) {
                  this.offset = offset;
                  return sd();
              } else {
                  return {
                      "string": sd(),
                      "length": offset - start
                  };
              }
          } else if (metrics === ByteBuffer.METRICS_BYTES) {
              if (!this.noAssert) {
                  if (typeof offset !== 'number' || offset % 1 !== 0)
                      throw TypeError("Illegal offset: "+offset+" (not an integer)");
                  offset >>>= 0;
                  if (offset < 0 || offset + length > this.buffer.byteLength)
                      throw RangeError("Illegal offset: 0 <= "+offset+" (+"+length+") <= "+this.buffer.byteLength);
              }
              var k = offset + length;
              utfx.decodeUTF8toUTF16(function() {
                  return offset < k ? this.view[offset++] : null;
              }.bind(this), sd = stringDestination(), this.noAssert);
              if (offset !== k)
                  throw RangeError("Illegal range: Truncated data, "+offset+" == "+k);
              if (relative) {
                  this.offset = offset;
                  return sd();
              } else {
                  return {
                      'string': sd(),
                      'length': offset - start
                  };
              }
          } else
              throw TypeError("Unsupported metrics: "+metrics);
      };
  
      /**
       * Reads an UTF8 encoded string. This is an alias of {@link ByteBuffer#readUTF8String}.
       * @function
       * @param {number} length Number of characters or bytes to read
       * @param {number=} metrics Metrics specifying what `n` is meant to count. Defaults to
       *  {@link ByteBuffer.METRICS_CHARS}.
       * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by the number of bytes
       *  read if omitted.
       * @returns {string|!{string: string, length: number}} The string read if offset is omitted, else the string
       *  read and the actual number of bytes read.
       * @expose
       */
      ByteBufferPrototype.readString = ByteBufferPrototype.readUTF8String;
  
      // types/strings/vstring
  
      /**
       * Writes a length as varint32 prefixed UTF8 encoded string.
       * @param {string} str String to write
       * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by the number of bytes
       *  written if omitted.
       * @returns {!ByteBuffer|number} `this` if `offset` is omitted, else the actual number of bytes written
       * @expose
       * @see ByteBuffer#writeVarint32
       */
      ByteBufferPrototype.writeVString = function(str, offset) {
          var relative = typeof offset === 'undefined';
          if (relative) offset = this.offset;
          if (!this.noAssert) {
              if (typeof str !== 'string')
                  throw TypeError("Illegal str: Not a string");
              if (typeof offset !== 'number' || offset % 1 !== 0)
                  throw TypeError("Illegal offset: "+offset+" (not an integer)");
              offset >>>= 0;
              if (offset < 0 || offset + 0 > this.buffer.byteLength)
                  throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
          }
          var start = offset,
              k, l;
          k = utfx.calculateUTF16asUTF8(stringSource(str), this.noAssert)[1];
          l = ByteBuffer.calculateVarint32(k);
          offset += l+k;
          var capacity15 = this.buffer.byteLength;
          if (offset > capacity15)
              this.resize((capacity15 *= 2) > offset ? capacity15 : offset);
          offset -= l+k;
          offset += this.writeVarint32(k, offset);
          utfx.encodeUTF16toUTF8(stringSource(str), function(b) {
              this.view[offset++] = b;
          }.bind(this));
          if (offset !== start+k+l)
              throw RangeError("Illegal range: Truncated data, "+offset+" == "+(offset+k+l));
          if (relative) {
              this.offset = offset;
              return this;
          }
          return offset - start;
      };
  
      /**
       * Reads a length as varint32 prefixed UTF8 encoded string.
       * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by the number of bytes
       *  read if omitted.
       * @returns {string|!{string: string, length: number}} The string read if offset is omitted, else the string
       *  read and the actual number of bytes read.
       * @expose
       * @see ByteBuffer#readVarint32
       */
      ByteBufferPrototype.readVString = function(offset) {
          var relative = typeof offset === 'undefined';
          if (relative) offset = this.offset;
          if (!this.noAssert) {
              if (typeof offset !== 'number' || offset % 1 !== 0)
                  throw TypeError("Illegal offset: "+offset+" (not an integer)");
              offset >>>= 0;
              if (offset < 0 || offset + 1 > this.buffer.byteLength)
                  throw RangeError("Illegal offset: 0 <= "+offset+" (+"+1+") <= "+this.buffer.byteLength);
          }
          var start = offset;
          var len = this.readVarint32(offset);
          var str = this.readUTF8String(len['value'], ByteBuffer.METRICS_BYTES, offset += len['length']);
          offset += str['length'];
          if (relative) {
              this.offset = offset;
              return str['string'];
          } else {
              return {
                  'string': str['string'],
                  'length': offset - start
              };
          }
      };
  
  
      /**
       * Appends some data to this ByteBuffer. This will overwrite any contents behind the specified offset up to the appended
       *  data's length.
       * @param {!ByteBuffer|!ArrayBuffer|!Uint8Array|string} source Data to append. If `source` is a ByteBuffer, its offsets
       *  will be modified according to the performed read operation.
       * @param {(string|number)=} encoding Encoding if `data` is a string ("base64", "hex", "binary", defaults to "utf8")
       * @param {number=} offset Offset to append at. Will use and increase {@link ByteBuffer#offset} by the number of bytes
       *  written if omitted.
       * @returns {!ByteBuffer} this
       * @expose
       * @example A relative `<01 02>03.append(<04 05>)` will result in `<01 02 04 05>, 04 05|`
       * @example An absolute `<01 02>03.append(04 05>, 1)` will result in `<01 04>05, 04 05|`
       */
      ByteBufferPrototype.append = function(source, encoding, offset) {
          if (typeof encoding === 'number' || typeof encoding !== 'string') {
              offset = encoding;
              encoding = undefined;
          }
          var relative = typeof offset === 'undefined';
          if (relative) offset = this.offset;
          if (!this.noAssert) {
              if (typeof offset !== 'number' || offset % 1 !== 0)
                  throw TypeError("Illegal offset: "+offset+" (not an integer)");
              offset >>>= 0;
              if (offset < 0 || offset + 0 > this.buffer.byteLength)
                  throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
          }
          if (!(source instanceof ByteBuffer))
              source = ByteBuffer.wrap(source, encoding);
          var length = source.limit - source.offset;
          if (length <= 0) return this; // Nothing to append
          offset += length;
          var capacity16 = this.buffer.byteLength;
          if (offset > capacity16)
              this.resize((capacity16 *= 2) > offset ? capacity16 : offset);
          offset -= length;
          this.view.set(source.view.subarray(source.offset, source.limit), offset);
          source.offset += length;
          if (relative) this.offset += length;
          return this;
      };
  
      /**
       * Appends this ByteBuffer's contents to another ByteBuffer. This will overwrite any contents at and after the
          specified offset up to the length of this ByteBuffer's data.
       * @param {!ByteBuffer} target Target ByteBuffer
       * @param {number=} offset Offset to append to. Will use and increase {@link ByteBuffer#offset} by the number of bytes
       *  read if omitted.
       * @returns {!ByteBuffer} this
       * @expose
       * @see ByteBuffer#append
       */
      ByteBufferPrototype.appendTo = function(target, offset) {
          target.append(this, offset);
          return this;
      };
  
      /**
       * Enables or disables assertions of argument types and offsets. Assertions are enabled by default but you can opt to
       *  disable them if your code already makes sure that everything is valid.
       * @param {boolean} assert `true` to enable assertions, otherwise `false`
       * @returns {!ByteBuffer} this
       * @expose
       */
      ByteBufferPrototype.assert = function(assert) {
          this.noAssert = !assert;
          return this;
      };
  
      /**
       * Gets the capacity of this ByteBuffer's backing buffer.
       * @returns {number} Capacity of the backing buffer
       * @expose
       */
      ByteBufferPrototype.capacity = function() {
          return this.buffer.byteLength;
      };
      /**
       * Clears this ByteBuffer's offsets by setting {@link ByteBuffer#offset} to `0` and {@link ByteBuffer#limit} to the
       *  backing buffer's capacity. Discards {@link ByteBuffer#markedOffset}.
       * @returns {!ByteBuffer} this
       * @expose
       */
      ByteBufferPrototype.clear = function() {
          this.offset = 0;
          this.limit = this.buffer.byteLength;
          this.markedOffset = -1;
          return this;
      };
  
      /**
       * Creates a cloned instance of this ByteBuffer, preset with this ByteBuffer's values for {@link ByteBuffer#offset},
       *  {@link ByteBuffer#markedOffset} and {@link ByteBuffer#limit}.
       * @param {boolean=} copy Whether to copy the backing buffer or to return another view on the same, defaults to `false`
       * @returns {!ByteBuffer} Cloned instance
       * @expose
       */
      ByteBufferPrototype.clone = function(copy) {
          var bb = new ByteBuffer(0, this.littleEndian, this.noAssert);
          if (copy) {
              bb.buffer = new ArrayBuffer(this.buffer.byteLength);
              bb.view = new Uint8Array(bb.buffer);
          } else {
              bb.buffer = this.buffer;
              bb.view = this.view;
          }
          bb.offset = this.offset;
          bb.markedOffset = this.markedOffset;
          bb.limit = this.limit;
          return bb;
      };
  
      /**
       * Compacts this ByteBuffer to be backed by a {@link ByteBuffer#buffer} of its contents' length. Contents are the bytes
       *  between {@link ByteBuffer#offset} and {@link ByteBuffer#limit}. Will set `offset = 0` and `limit = capacity` and
       *  adapt {@link ByteBuffer#markedOffset} to the same relative position if set.
       * @param {number=} begin Offset to start at, defaults to {@link ByteBuffer#offset}
       * @param {number=} end Offset to end at, defaults to {@link ByteBuffer#limit}
       * @returns {!ByteBuffer} this
       * @expose
       */
      ByteBufferPrototype.compact = function(begin, end) {
          if (typeof begin === 'undefined') begin = this.offset;
          if (typeof end === 'undefined') end = this.limit;
          if (!this.noAssert) {
              if (typeof begin !== 'number' || begin % 1 !== 0)
                  throw TypeError("Illegal begin: Not an integer");
              begin >>>= 0;
              if (typeof end !== 'number' || end % 1 !== 0)
                  throw TypeError("Illegal end: Not an integer");
              end >>>= 0;
              if (begin < 0 || begin > end || end > this.buffer.byteLength)
                  throw RangeError("Illegal range: 0 <= "+begin+" <= "+end+" <= "+this.buffer.byteLength);
          }
          if (begin === 0 && end === this.buffer.byteLength)
              return this; // Already compacted
          var len = end - begin;
          if (len === 0) {
              this.buffer = EMPTY_BUFFER;
              this.view = null;
              if (this.markedOffset >= 0) this.markedOffset -= begin;
              this.offset = 0;
              this.limit = 0;
              return this;
          }
          var buffer = new ArrayBuffer(len);
          var view = new Uint8Array(buffer);
          view.set(this.view.subarray(begin, end));
          this.buffer = buffer;
          this.view = view;
          if (this.markedOffset >= 0) this.markedOffset -= begin;
          this.offset = 0;
          this.limit = len;
          return this;
      };
  
      /**
       * Creates a copy of this ByteBuffer's contents. Contents are the bytes between {@link ByteBuffer#offset} and
       *  {@link ByteBuffer#limit}.
       * @param {number=} begin Begin offset, defaults to {@link ByteBuffer#offset}.
       * @param {number=} end End offset, defaults to {@link ByteBuffer#limit}.
       * @returns {!ByteBuffer} Copy
       * @expose
       */
      ByteBufferPrototype.copy = function(begin, end) {
          if (typeof begin === 'undefined') begin = this.offset;
          if (typeof end === 'undefined') end = this.limit;
          if (!this.noAssert) {
              if (typeof begin !== 'number' || begin % 1 !== 0)
                  throw TypeError("Illegal begin: Not an integer");
              begin >>>= 0;
              if (typeof end !== 'number' || end % 1 !== 0)
                  throw TypeError("Illegal end: Not an integer");
              end >>>= 0;
              if (begin < 0 || begin > end || end > this.buffer.byteLength)
                  throw RangeError("Illegal range: 0 <= "+begin+" <= "+end+" <= "+this.buffer.byteLength);
          }
          if (begin === end)
              return new ByteBuffer(0, this.littleEndian, this.noAssert);
          var capacity = end - begin,
              bb = new ByteBuffer(capacity, this.littleEndian, this.noAssert);
          bb.offset = 0;
          bb.limit = capacity;
          if (bb.markedOffset >= 0) bb.markedOffset -= begin;
          this.copyTo(bb, 0, begin, end);
          return bb;
      };
  
      /**
       * Copies this ByteBuffer's contents to another ByteBuffer. Contents are the bytes between {@link ByteBuffer#offset} and
       *  {@link ByteBuffer#limit}.
       * @param {!ByteBuffer} target Target ByteBuffer
       * @param {number=} targetOffset Offset to copy to. Will use and increase the target's {@link ByteBuffer#offset}
       *  by the number of bytes copied if omitted.
       * @param {number=} sourceOffset Offset to start copying from. Will use and increase {@link ByteBuffer#offset} by the
       *  number of bytes copied if omitted.
       * @param {number=} sourceLimit Offset to end copying from, defaults to {@link ByteBuffer#limit}
       * @returns {!ByteBuffer} this
       * @expose
       */
      ByteBufferPrototype.copyTo = function(target, targetOffset, sourceOffset, sourceLimit) {
          var relative,
              targetRelative;
          if (!this.noAssert) {
              if (!ByteBuffer.isByteBuffer(target))
                  throw TypeError("Illegal target: Not a ByteBuffer");
          }
          targetOffset = (targetRelative = typeof targetOffset === 'undefined') ? target.offset : targetOffset | 0;
          sourceOffset = (relative = typeof sourceOffset === 'undefined') ? this.offset : sourceOffset | 0;
          sourceLimit = typeof sourceLimit === 'undefined' ? this.limit : sourceLimit | 0;
  
          if (targetOffset < 0 || targetOffset > target.buffer.byteLength)
              throw RangeError("Illegal target range: 0 <= "+targetOffset+" <= "+target.buffer.byteLength);
          if (sourceOffset < 0 || sourceLimit > this.buffer.byteLength)
              throw RangeError("Illegal source range: 0 <= "+sourceOffset+" <= "+this.buffer.byteLength);
  
          var len = sourceLimit - sourceOffset;
          if (len === 0)
              return target; // Nothing to copy
  
          target.ensureCapacity(targetOffset + len);
  
          target.view.set(this.view.subarray(sourceOffset, sourceLimit), targetOffset);
  
          if (relative) this.offset += len;
          if (targetRelative) target.offset += len;
  
          return this;
      };
  
      /**
       * Makes sure that this ByteBuffer is backed by a {@link ByteBuffer#buffer} of at least the specified capacity. If the
       *  current capacity is exceeded, it will be doubled. If double the current capacity is less than the required capacity,
       *  the required capacity will be used instead.
       * @param {number} capacity Required capacity
       * @returns {!ByteBuffer} this
       * @expose
       */
      ByteBufferPrototype.ensureCapacity = function(capacity) {
          var current = this.buffer.byteLength;
          if (current < capacity)
              return this.resize((current *= 2) > capacity ? current : capacity);
          return this;
      };
  
      /**
       * Overwrites this ByteBuffer's contents with the specified value. Contents are the bytes between
       *  {@link ByteBuffer#offset} and {@link ByteBuffer#limit}.
       * @param {number|string} value Byte value to fill with. If given as a string, the first character is used.
       * @param {number=} begin Begin offset. Will use and increase {@link ByteBuffer#offset} by the number of bytes
       *  written if omitted. defaults to {@link ByteBuffer#offset}.
       * @param {number=} end End offset, defaults to {@link ByteBuffer#limit}.
       * @returns {!ByteBuffer} this
       * @expose
       * @example `someByteBuffer.clear().fill(0)` fills the entire backing buffer with zeroes
       */
      ByteBufferPrototype.fill = function(value, begin, end) {
          var relative = typeof begin === 'undefined';
          if (relative) begin = this.offset;
          if (typeof value === 'string' && value.length > 0)
              value = value.charCodeAt(0);
          if (typeof begin === 'undefined') begin = this.offset;
          if (typeof end === 'undefined') end = this.limit;
          if (!this.noAssert) {
              if (typeof value !== 'number' || value % 1 !== 0)
                  throw TypeError("Illegal value: "+value+" (not an integer)");
              value |= 0;
              if (typeof begin !== 'number' || begin % 1 !== 0)
                  throw TypeError("Illegal begin: Not an integer");
              begin >>>= 0;
              if (typeof end !== 'number' || end % 1 !== 0)
                  throw TypeError("Illegal end: Not an integer");
              end >>>= 0;
              if (begin < 0 || begin > end || end > this.buffer.byteLength)
                  throw RangeError("Illegal range: 0 <= "+begin+" <= "+end+" <= "+this.buffer.byteLength);
          }
          if (begin >= end)
              return this; // Nothing to fill
          while (begin < end) this.view[begin++] = value;
          if (relative) this.offset = begin;
          return this;
      };
  
      /**
       * Makes this ByteBuffer ready for a new sequence of write or relative read operations. Sets `limit = offset` and
       *  `offset = 0`. Make sure always to flip a ByteBuffer when all relative read or write operations are complete.
       * @returns {!ByteBuffer} this
       * @expose
       */
      ByteBufferPrototype.flip = function() {
          this.limit = this.offset;
          this.offset = 0;
          return this;
      };
      /**
       * Marks an offset on this ByteBuffer to be used later.
       * @param {number=} offset Offset to mark. Defaults to {@link ByteBuffer#offset}.
       * @returns {!ByteBuffer} this
       * @throws {TypeError} If `offset` is not a valid number
       * @throws {RangeError} If `offset` is out of bounds
       * @see ByteBuffer#reset
       * @expose
       */
      ByteBufferPrototype.mark = function(offset) {
          offset = typeof offset === 'undefined' ? this.offset : offset;
          if (!this.noAssert) {
              if (typeof offset !== 'number' || offset % 1 !== 0)
                  throw TypeError("Illegal offset: "+offset+" (not an integer)");
              offset >>>= 0;
              if (offset < 0 || offset + 0 > this.buffer.byteLength)
                  throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
          }
          this.markedOffset = offset;
          return this;
      };
      /**
       * Sets the byte order.
       * @param {boolean} littleEndian `true` for little endian byte order, `false` for big endian
       * @returns {!ByteBuffer} this
       * @expose
       */
      ByteBufferPrototype.order = function(littleEndian) {
          if (!this.noAssert) {
              if (typeof littleEndian !== 'boolean')
                  throw TypeError("Illegal littleEndian: Not a boolean");
          }
          this.littleEndian = !!littleEndian;
          return this;
      };
  
      /**
       * Switches (to) little endian byte order.
       * @param {boolean=} littleEndian Defaults to `true`, otherwise uses big endian
       * @returns {!ByteBuffer} this
       * @expose
       */
      ByteBufferPrototype.LE = function(littleEndian) {
          this.littleEndian = typeof littleEndian !== 'undefined' ? !!littleEndian : true;
          return this;
      };
  
      /**
       * Switches (to) big endian byte order.
       * @param {boolean=} bigEndian Defaults to `true`, otherwise uses little endian
       * @returns {!ByteBuffer} this
       * @expose
       */
      ByteBufferPrototype.BE = function(bigEndian) {
          this.littleEndian = typeof bigEndian !== 'undefined' ? !bigEndian : false;
          return this;
      };
      /**
       * Prepends some data to this ByteBuffer. This will overwrite any contents before the specified offset up to the
       *  prepended data's length. If there is not enough space available before the specified `offset`, the backing buffer
       *  will be resized and its contents moved accordingly.
       * @param {!ByteBuffer|string|!ArrayBuffer} source Data to prepend. If `source` is a ByteBuffer, its offset will be
       *  modified according to the performed read operation.
       * @param {(string|number)=} encoding Encoding if `data` is a string ("base64", "hex", "binary", defaults to "utf8")
       * @param {number=} offset Offset to prepend at. Will use and decrease {@link ByteBuffer#offset} by the number of bytes
       *  prepended if omitted.
       * @returns {!ByteBuffer} this
       * @expose
       * @example A relative `00<01 02 03>.prepend(<04 05>)` results in `<04 05 01 02 03>, 04 05|`
       * @example An absolute `00<01 02 03>.prepend(<04 05>, 2)` results in `04<05 02 03>, 04 05|`
       */
      ByteBufferPrototype.prepend = function(source, encoding, offset) {
          if (typeof encoding === 'number' || typeof encoding !== 'string') {
              offset = encoding;
              encoding = undefined;
          }
          var relative = typeof offset === 'undefined';
          if (relative) offset = this.offset;
          if (!this.noAssert) {
              if (typeof offset !== 'number' || offset % 1 !== 0)
                  throw TypeError("Illegal offset: "+offset+" (not an integer)");
              offset >>>= 0;
              if (offset < 0 || offset + 0 > this.buffer.byteLength)
                  throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
          }
          if (!(source instanceof ByteBuffer))
              source = ByteBuffer.wrap(source, encoding);
          var len = source.limit - source.offset;
          if (len <= 0) return this; // Nothing to prepend
          var diff = len - offset;
          if (diff > 0) { // Not enough space before offset, so resize + move
              var buffer = new ArrayBuffer(this.buffer.byteLength + diff);
              var view = new Uint8Array(buffer);
              view.set(this.view.subarray(offset, this.buffer.byteLength), len);
              this.buffer = buffer;
              this.view = view;
              this.offset += diff;
              if (this.markedOffset >= 0) this.markedOffset += diff;
              this.limit += diff;
              offset += diff;
          } else {
              var arrayView = new Uint8Array(this.buffer);
          }
          this.view.set(source.view.subarray(source.offset, source.limit), offset - len);
  
          source.offset = source.limit;
          if (relative)
              this.offset -= len;
          return this;
      };
  
      /**
       * Prepends this ByteBuffer to another ByteBuffer. This will overwrite any contents before the specified offset up to the
       *  prepended data's length. If there is not enough space available before the specified `offset`, the backing buffer
       *  will be resized and its contents moved accordingly.
       * @param {!ByteBuffer} target Target ByteBuffer
       * @param {number=} offset Offset to prepend at. Will use and decrease {@link ByteBuffer#offset} by the number of bytes
       *  prepended if omitted.
       * @returns {!ByteBuffer} this
       * @expose
       * @see ByteBuffer#prepend
       */
      ByteBufferPrototype.prependTo = function(target, offset) {
          target.prepend(this, offset);
          return this;
      };
      /**
       * Prints debug information about this ByteBuffer's contents.
       * @param {function(string)=} out Output function to call, defaults to console.log
       * @expose
       */
      ByteBufferPrototype.printDebug = function(out) {
          if (typeof out !== 'function') out = console.log.bind(console);
          out(
              this.toString()+"\n"+
              "-------------------------------------------------------------------\n"+
              this.toDebug(/* columns */ true)
          );
      };
  
      /**
       * Gets the number of remaining readable bytes. Contents are the bytes between {@link ByteBuffer#offset} and
       *  {@link ByteBuffer#limit}, so this returns `limit - offset`.
       * @returns {number} Remaining readable bytes. May be negative if `offset > limit`.
       * @expose
       */
      ByteBufferPrototype.remaining = function() {
          return this.limit - this.offset;
      };
      /**
       * Resets this ByteBuffer's {@link ByteBuffer#offset}. If an offset has been marked through {@link ByteBuffer#mark}
       *  before, `offset` will be set to {@link ByteBuffer#markedOffset}, which will then be discarded. If no offset has been
       *  marked, sets `offset = 0`.
       * @returns {!ByteBuffer} this
       * @see ByteBuffer#mark
       * @expose
       */
      ByteBufferPrototype.reset = function() {
          if (this.markedOffset >= 0) {
              this.offset = this.markedOffset;
              this.markedOffset = -1;
          } else {
              this.offset = 0;
          }
          return this;
      };
      /**
       * Resizes this ByteBuffer to be backed by a buffer of at least the given capacity. Will do nothing if already that
       *  large or larger.
       * @param {number} capacity Capacity required
       * @returns {!ByteBuffer} this
       * @throws {TypeError} If `capacity` is not a number
       * @throws {RangeError} If `capacity < 0`
       * @expose
       */
      ByteBufferPrototype.resize = function(capacity) {
          if (!this.noAssert) {
              if (typeof capacity !== 'number' || capacity % 1 !== 0)
                  throw TypeError("Illegal capacity: "+capacity+" (not an integer)");
              capacity |= 0;
              if (capacity < 0)
                  throw RangeError("Illegal capacity: 0 <= "+capacity);
          }
          if (this.buffer.byteLength < capacity) {
              var buffer = new ArrayBuffer(capacity);
              var view = new Uint8Array(buffer);
              view.set(this.view);
              this.buffer = buffer;
              this.view = view;
          }
          return this;
      };
      /**
       * Reverses this ByteBuffer's contents.
       * @param {number=} begin Offset to start at, defaults to {@link ByteBuffer#offset}
       * @param {number=} end Offset to end at, defaults to {@link ByteBuffer#limit}
       * @returns {!ByteBuffer} this
       * @expose
       */
      ByteBufferPrototype.reverse = function(begin, end) {
          if (typeof begin === 'undefined') begin = this.offset;
          if (typeof end === 'undefined') end = this.limit;
          if (!this.noAssert) {
              if (typeof begin !== 'number' || begin % 1 !== 0)
                  throw TypeError("Illegal begin: Not an integer");
              begin >>>= 0;
              if (typeof end !== 'number' || end % 1 !== 0)
                  throw TypeError("Illegal end: Not an integer");
              end >>>= 0;
              if (begin < 0 || begin > end || end > this.buffer.byteLength)
                  throw RangeError("Illegal range: 0 <= "+begin+" <= "+end+" <= "+this.buffer.byteLength);
          }
          if (begin === end)
              return this; // Nothing to reverse
          Array.prototype.reverse.call(this.view.subarray(begin, end));
          return this;
      };
      /**
       * Skips the next `length` bytes. This will just advance
       * @param {number} length Number of bytes to skip. May also be negative to move the offset back.
       * @returns {!ByteBuffer} this
       * @expose
       */
      ByteBufferPrototype.skip = function(length) {
          if (!this.noAssert) {
              if (typeof length !== 'number' || length % 1 !== 0)
                  throw TypeError("Illegal length: "+length+" (not an integer)");
              length |= 0;
          }
          var offset = this.offset + length;
          if (!this.noAssert) {
              if (offset < 0 || offset > this.buffer.byteLength)
                  throw RangeError("Illegal length: 0 <= "+this.offset+" + "+length+" <= "+this.buffer.byteLength);
          }
          this.offset = offset;
          return this;
      };
  
      /**
       * Slices this ByteBuffer by creating a cloned instance with `offset = begin` and `limit = end`.
       * @param {number=} begin Begin offset, defaults to {@link ByteBuffer#offset}.
       * @param {number=} end End offset, defaults to {@link ByteBuffer#limit}.
       * @returns {!ByteBuffer} Clone of this ByteBuffer with slicing applied, backed by the same {@link ByteBuffer#buffer}
       * @expose
       */
      ByteBufferPrototype.slice = function(begin, end) {
          if (typeof begin === 'undefined') begin = this.offset;
          if (typeof end === 'undefined') end = this.limit;
          if (!this.noAssert) {
              if (typeof begin !== 'number' || begin % 1 !== 0)
                  throw TypeError("Illegal begin: Not an integer");
              begin >>>= 0;
              if (typeof end !== 'number' || end % 1 !== 0)
                  throw TypeError("Illegal end: Not an integer");
              end >>>= 0;
              if (begin < 0 || begin > end || end > this.buffer.byteLength)
                  throw RangeError("Illegal range: 0 <= "+begin+" <= "+end+" <= "+this.buffer.byteLength);
          }
          var bb = this.clone();
          bb.offset = begin;
          bb.limit = end;
          return bb;
      };
      /**
       * Returns a copy of the backing buffer that contains this ByteBuffer's contents. Contents are the bytes between
       *  {@link ByteBuffer#offset} and {@link ByteBuffer#limit}.
       * @param {boolean=} forceCopy If `true` returns a copy, otherwise returns a view referencing the same memory if
       *  possible. Defaults to `false`
       * @returns {!ArrayBuffer} Contents as an ArrayBuffer
       * @expose
       */
      ByteBufferPrototype.toBuffer = function(forceCopy) {
          var offset = this.offset,
              limit = this.limit;
          if (!this.noAssert) {
              if (typeof offset !== 'number' || offset % 1 !== 0)
                  throw TypeError("Illegal offset: Not an integer");
              offset >>>= 0;
              if (typeof limit !== 'number' || limit % 1 !== 0)
                  throw TypeError("Illegal limit: Not an integer");
              limit >>>= 0;
              if (offset < 0 || offset > limit || limit > this.buffer.byteLength)
                  throw RangeError("Illegal range: 0 <= "+offset+" <= "+limit+" <= "+this.buffer.byteLength);
          }
          // NOTE: It's not possible to have another ArrayBuffer reference the same memory as the backing buffer. This is
          // possible with Uint8Array#subarray only, but we have to return an ArrayBuffer by contract. So:
          if (!forceCopy && offset === 0 && limit === this.buffer.byteLength)
              return this.buffer;
          if (offset === limit)
              return EMPTY_BUFFER;
          var buffer = new ArrayBuffer(limit - offset);
          new Uint8Array(buffer).set(new Uint8Array(this.buffer).subarray(offset, limit), 0);
          return buffer;
      };
  
      /**
       * Returns a raw buffer compacted to contain this ByteBuffer's contents. Contents are the bytes between
       *  {@link ByteBuffer#offset} and {@link ByteBuffer#limit}. This is an alias of {@link ByteBuffer#toBuffer}.
       * @function
       * @param {boolean=} forceCopy If `true` returns a copy, otherwise returns a view referencing the same memory.
       *  Defaults to `false`
       * @returns {!ArrayBuffer} Contents as an ArrayBuffer
       * @expose
       */
      ByteBufferPrototype.toArrayBuffer = ByteBufferPrototype.toBuffer;
  
      /**
       * Converts the ByteBuffer's contents to a string.
       * @param {string=} encoding Output encoding. Returns an informative string representation if omitted but also allows
       *  direct conversion to "utf8", "hex", "base64" and "binary" encoding. "debug" returns a hex representation with
       *  highlighted offsets.
       * @param {number=} begin Offset to begin at, defaults to {@link ByteBuffer#offset}
       * @param {number=} end Offset to end at, defaults to {@link ByteBuffer#limit}
       * @returns {string} String representation
       * @throws {Error} If `encoding` is invalid
       * @expose
       */
      ByteBufferPrototype.toString = function(encoding, begin, end) {
          if (typeof encoding === 'undefined')
              return "ByteBufferAB(offset="+this.offset+",markedOffset="+this.markedOffset+",limit="+this.limit+",capacity="+this.capacity()+")";
          if (typeof encoding === 'number')
              encoding = "utf8",
              begin = encoding,
              end = begin;
          switch (encoding) {
              case "utf8":
                  return this.toUTF8(begin, end);
              case "base64":
                  return this.toBase64(begin, end);
              case "hex":
                  return this.toHex(begin, end);
              case "binary":
                  return this.toBinary(begin, end);
              case "debug":
                  return this.toDebug();
              case "columns":
                  return this.toColumns();
              default:
                  throw Error("Unsupported encoding: "+encoding);
          }
      };
  
      // lxiv-embeddable
  
      /**
       * lxiv-embeddable (c) 2014 Daniel Wirtz <dcode@dcode.io>
       * Released under the Apache License, Version 2.0
       * see: https://github.com/dcodeIO/lxiv for details
       */
      var lxiv = function() {
          "use strict";
  
          /**
           * lxiv namespace.
           * @type {!Object.<string,*>}
           * @exports lxiv
           */
          var lxiv = {};
  
          /**
           * Character codes for output.
           * @type {!Array.<number>}
           * @inner
           */
          var aout = [
              65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80,
              81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 97, 98, 99, 100, 101, 102,
              103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118,
              119, 120, 121, 122, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 43, 47
          ];
  
          /**
           * Character codes for input.
           * @type {!Array.<number>}
           * @inner
           */
          var ain = [];
          for (var i=0, k=aout.length; i<k; ++i)
              ain[aout[i]] = i;
  
          /**
           * Encodes bytes to base64 char codes.
           * @param {!function():number|null} src Bytes source as a function returning the next byte respectively `null` if
           *  there are no more bytes left.
           * @param {!function(number)} dst Characters destination as a function successively called with each encoded char
           *  code.
           */
          lxiv.encode = function(src, dst) {
              var b, t;
              while ((b = src()) !== null) {
                  dst(aout[(b>>2)&0x3f]);
                  t = (b&0x3)<<4;
                  if ((b = src()) !== null) {
                      t |= (b>>4)&0xf;
                      dst(aout[(t|((b>>4)&0xf))&0x3f]);
                      t = (b&0xf)<<2;
                      if ((b = src()) !== null)
                          dst(aout[(t|((b>>6)&0x3))&0x3f]),
                          dst(aout[b&0x3f]);
                      else
                          dst(aout[t&0x3f]),
                          dst(61);
                  } else
                      dst(aout[t&0x3f]),
                      dst(61),
                      dst(61);
              }
          };
  
          /**
           * Decodes base64 char codes to bytes.
           * @param {!function():number|null} src Characters source as a function returning the next char code respectively
           *  `null` if there are no more characters left.
           * @param {!function(number)} dst Bytes destination as a function successively called with the next byte.
           * @throws {Error} If a character code is invalid
           */
          lxiv.decode = function(src, dst) {
              var c, t1, t2;
              function fail(c) {
                  throw Error("Illegal character code: "+c);
              }
              while ((c = src()) !== null) {
                  t1 = ain[c];
                  if (typeof t1 === 'undefined') fail(c);
                  if ((c = src()) !== null) {
                      t2 = ain[c];
                      if (typeof t2 === 'undefined') fail(c);
                      dst((t1<<2)>>>0|(t2&0x30)>>4);
                      if ((c = src()) !== null) {
                          t1 = ain[c];
                          if (typeof t1 === 'undefined')
                              if (c === 61) break; else fail(c);
                          dst(((t2&0xf)<<4)>>>0|(t1&0x3c)>>2);
                          if ((c = src()) !== null) {
                              t2 = ain[c];
                              if (typeof t2 === 'undefined')
                                  if (c === 61) break; else fail(c);
                              dst(((t1&0x3)<<6)>>>0|t2);
                          }
                      }
                  }
              }
          };
  
          /**
           * Tests if a string is valid base64.
           * @param {string} str String to test
           * @returns {boolean} `true` if valid, otherwise `false`
           */
          lxiv.test = function(str) {
              return /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/.test(str);
          };
  
          return lxiv;
      }();
  
      // encodings/base64
  
      /**
       * Encodes this ByteBuffer's contents to a base64 encoded string.
       * @param {number=} begin Offset to begin at, defaults to {@link ByteBuffer#offset}.
       * @param {number=} end Offset to end at, defaults to {@link ByteBuffer#limit}.
       * @returns {string} Base64 encoded string
       * @throws {RangeError} If `begin` or `end` is out of bounds
       * @expose
       */
      ByteBufferPrototype.toBase64 = function(begin, end) {
          if (typeof begin === 'undefined')
              begin = this.offset;
          if (typeof end === 'undefined')
              end = this.limit;
          begin = begin | 0; end = end | 0;
          if (begin < 0 || end > this.capacity || begin > end)
              throw RangeError("begin, end");
          var sd; lxiv.encode(function() {
              return begin < end ? this.view[begin++] : null;
          }.bind(this), sd = stringDestination());
          return sd();
      };
  
      /**
       * Decodes a base64 encoded string to a ByteBuffer.
       * @param {string} str String to decode
       * @param {boolean=} littleEndian Whether to use little or big endian byte order. Defaults to
       *  {@link ByteBuffer.DEFAULT_ENDIAN}.
       * @returns {!ByteBuffer} ByteBuffer
       * @expose
       */
      ByteBuffer.fromBase64 = function(str, littleEndian) {
          if (typeof str !== 'string')
              throw TypeError("str");
          var bb = new ByteBuffer(str.length/4*3, littleEndian),
              i = 0;
          lxiv.decode(stringSource(str), function(b) {
              bb.view[i++] = b;
          });
          bb.limit = i;
          return bb;
      };
  
      /**
       * Encodes a binary string to base64 like `window.btoa` does.
       * @param {string} str Binary string
       * @returns {string} Base64 encoded string
       * @see https://developer.mozilla.org/en-US/docs/Web/API/Window.btoa
       * @expose
       */
      ByteBuffer.btoa = function(str) {
          return ByteBuffer.fromBinary(str).toBase64();
      };
  
      /**
       * Decodes a base64 encoded string to binary like `window.atob` does.
       * @param {string} b64 Base64 encoded string
       * @returns {string} Binary string
       * @see https://developer.mozilla.org/en-US/docs/Web/API/Window.atob
       * @expose
       */
      ByteBuffer.atob = function(b64) {
          return ByteBuffer.fromBase64(b64).toBinary();
      };
  
      // encodings/binary
  
      /**
       * Encodes this ByteBuffer to a binary encoded string, that is using only characters 0x00-0xFF as bytes.
       * @param {number=} begin Offset to begin at. Defaults to {@link ByteBuffer#offset}.
       * @param {number=} end Offset to end at. Defaults to {@link ByteBuffer#limit}.
       * @returns {string} Binary encoded string
       * @throws {RangeError} If `offset > limit`
       * @expose
       */
      ByteBufferPrototype.toBinary = function(begin, end) {
          if (typeof begin === 'undefined')
              begin = this.offset;
          if (typeof end === 'undefined')
              end = this.limit;
          begin |= 0; end |= 0;
          if (begin < 0 || end > this.capacity() || begin > end)
              throw RangeError("begin, end");
          if (begin === end)
              return "";
          var chars = [],
              parts = [];
          while (begin < end) {
              chars.push(this.view[begin++]);
              if (chars.length >= 1024)
                  parts.push(String.fromCharCode.apply(String, chars)),
                  chars = [];
          }
          return parts.join('') + String.fromCharCode.apply(String, chars);
      };
  
      /**
       * Decodes a binary encoded string, that is using only characters 0x00-0xFF as bytes, to a ByteBuffer.
       * @param {string} str String to decode
       * @param {boolean=} littleEndian Whether to use little or big endian byte order. Defaults to
       *  {@link ByteBuffer.DEFAULT_ENDIAN}.
       * @returns {!ByteBuffer} ByteBuffer
       * @expose
       */
      ByteBuffer.fromBinary = function(str, littleEndian) {
          if (typeof str !== 'string')
              throw TypeError("str");
          var i = 0,
              k = str.length,
              charCode,
              bb = new ByteBuffer(k, littleEndian);
          while (i<k) {
              charCode = str.charCodeAt(i);
              if (charCode > 0xff)
                  throw RangeError("illegal char code: "+charCode);
              bb.view[i++] = charCode;
          }
          bb.limit = k;
          return bb;
      };
  
      // encodings/debug
  
      /**
       * Encodes this ByteBuffer to a hex encoded string with marked offsets. Offset symbols are:
       * * `<` : offset,
       * * `'` : markedOffset,
       * * `>` : limit,
       * * `|` : offset and limit,
       * * `[` : offset and markedOffset,
       * * `]` : markedOffset and limit,
       * * `!` : offset, markedOffset and limit
       * @param {boolean=} columns If `true` returns two columns hex + ascii, defaults to `false`
       * @returns {string|!Array.<string>} Debug string or array of lines if `asArray = true`
       * @expose
       * @example `>00'01 02<03` contains four bytes with `limit=0, markedOffset=1, offset=3`
       * @example `00[01 02 03>` contains four bytes with `offset=markedOffset=1, limit=4`
       * @example `00|01 02 03` contains four bytes with `offset=limit=1, markedOffset=-1`
       * @example `|` contains zero bytes with `offset=limit=0, markedOffset=-1`
       */
      ByteBufferPrototype.toDebug = function(columns) {
          var i = -1,
              k = this.buffer.byteLength,
              b,
              hex = "",
              asc = "",
              out = "";
          while (i<k) {
              if (i !== -1) {
                  b = this.view[i];
                  if (b < 0x10) hex += "0"+b.toString(16).toUpperCase();
                  else hex += b.toString(16).toUpperCase();
                  if (columns)
                      asc += b > 32 && b < 127 ? String.fromCharCode(b) : '.';
              }
              ++i;
              if (columns) {
                  if (i > 0 && i % 16 === 0 && i !== k) {
                      while (hex.length < 3*16+3) hex += " ";
                      out += hex+asc+"\n";
                      hex = asc = "";
                  }
              }
              if (i === this.offset && i === this.limit)
                  hex += i === this.markedOffset ? "!" : "|";
              else if (i === this.offset)
                  hex += i === this.markedOffset ? "[" : "<";
              else if (i === this.limit)
                  hex += i === this.markedOffset ? "]" : ">";
              else
                  hex += i === this.markedOffset ? "'" : (columns || (i !== 0 && i !== k) ? " " : "");
          }
          if (columns && hex !== " ") {
              while (hex.length < 3*16+3)
                  hex += " ";
              out += hex + asc + "\n";
          }
          return columns ? out : hex;
      };
  
      /**
       * Decodes a hex encoded string with marked offsets to a ByteBuffer.
       * @param {string} str Debug string to decode (not be generated with `columns = true`)
       * @param {boolean=} littleEndian Whether to use little or big endian byte order. Defaults to
       *  {@link ByteBuffer.DEFAULT_ENDIAN}.
       * @param {boolean=} noAssert Whether to skip assertions of offsets and values. Defaults to
       *  {@link ByteBuffer.DEFAULT_NOASSERT}.
       * @returns {!ByteBuffer} ByteBuffer
       * @expose
       * @see ByteBuffer#toDebug
       */
      ByteBuffer.fromDebug = function(str, littleEndian, noAssert) {
          var k = str.length,
              bb = new ByteBuffer(((k+1)/3)|0, littleEndian, noAssert);
          var i = 0, j = 0, ch, b,
              rs = false, // Require symbol next
              ho = false, hm = false, hl = false, // Already has offset (ho), markedOffset (hm), limit (hl)?
              fail = false;
          while (i<k) {
              switch (ch = str.charAt(i++)) {
                  case '!':
                      if (!noAssert) {
                          if (ho || hm || hl) {
                              fail = true;
                              break;
                          }
                          ho = hm = hl = true;
                      }
                      bb.offset = bb.markedOffset = bb.limit = j;
                      rs = false;
                      break;
                  case '|':
                      if (!noAssert) {
                          if (ho || hl) {
                              fail = true;
                              break;
                          }
                          ho = hl = true;
                      }
                      bb.offset = bb.limit = j;
                      rs = false;
                      break;
                  case '[':
                      if (!noAssert) {
                          if (ho || hm) {
                              fail = true;
                              break;
                          }
                          ho = hm = true;
                      }
                      bb.offset = bb.markedOffset = j;
                      rs = false;
                      break;
                  case '<':
                      if (!noAssert) {
                          if (ho) {
                              fail = true;
                              break;
                          }
                          ho = true;
                      }
                      bb.offset = j;
                      rs = false;
                      break;
                  case ']':
                      if (!noAssert) {
                          if (hl || hm) {
                              fail = true;
                              break;
                          }
                          hl = hm = true;
                      }
                      bb.limit = bb.markedOffset = j;
                      rs = false;
                      break;
                  case '>':
                      if (!noAssert) {
                          if (hl) {
                              fail = true;
                              break;
                          }
                          hl = true;
                      }
                      bb.limit = j;
                      rs = false;
                      break;
                  case "'":
                      if (!noAssert) {
                          if (hm) {
                              fail = true;
                              break;
                          }
                          hm = true;
                      }
                      bb.markedOffset = j;
                      rs = false;
                      break;
                  case ' ':
                      rs = false;
                      break;
                  default:
                      if (!noAssert) {
                          if (rs) {
                              fail = true;
                              break;
                          }
                      }
                      b = parseInt(ch+str.charAt(i++), 16);
                      if (!noAssert) {
                          if (isNaN(b) || b < 0 || b > 255)
                              throw TypeError("Illegal str: Not a debug encoded string");
                      }
                      bb.view[j++] = b;
                      rs = true;
              }
              if (fail)
                  throw TypeError("Illegal str: Invalid symbol at "+i);
          }
          if (!noAssert) {
              if (!ho || !hl)
                  throw TypeError("Illegal str: Missing offset or limit");
              if (j<bb.buffer.byteLength)
                  throw TypeError("Illegal str: Not a debug encoded string (is it hex?) "+j+" < "+k);
          }
          return bb;
      };
  
      // encodings/hex
  
      /**
       * Encodes this ByteBuffer's contents to a hex encoded string.
       * @param {number=} begin Offset to begin at. Defaults to {@link ByteBuffer#offset}.
       * @param {number=} end Offset to end at. Defaults to {@link ByteBuffer#limit}.
       * @returns {string} Hex encoded string
       * @expose
       */
      ByteBufferPrototype.toHex = function(begin, end) {
          begin = typeof begin === 'undefined' ? this.offset : begin;
          end = typeof end === 'undefined' ? this.limit : end;
          if (!this.noAssert) {
              if (typeof begin !== 'number' || begin % 1 !== 0)
                  throw TypeError("Illegal begin: Not an integer");
              begin >>>= 0;
              if (typeof end !== 'number' || end % 1 !== 0)
                  throw TypeError("Illegal end: Not an integer");
              end >>>= 0;
              if (begin < 0 || begin > end || end > this.buffer.byteLength)
                  throw RangeError("Illegal range: 0 <= "+begin+" <= "+end+" <= "+this.buffer.byteLength);
          }
          var out = new Array(end - begin),
              b;
          while (begin < end) {
              b = this.view[begin++];
              if (b < 0x10)
                  out.push("0", b.toString(16));
              else out.push(b.toString(16));
          }
          return out.join('');
      };
  
      /**
       * Decodes a hex encoded string to a ByteBuffer.
       * @param {string} str String to decode
       * @param {boolean=} littleEndian Whether to use little or big endian byte order. Defaults to
       *  {@link ByteBuffer.DEFAULT_ENDIAN}.
       * @param {boolean=} noAssert Whether to skip assertions of offsets and values. Defaults to
       *  {@link ByteBuffer.DEFAULT_NOASSERT}.
       * @returns {!ByteBuffer} ByteBuffer
       * @expose
       */
      ByteBuffer.fromHex = function(str, littleEndian, noAssert) {
          if (!noAssert) {
              if (typeof str !== 'string')
                  throw TypeError("Illegal str: Not a string");
              if (str.length % 2 !== 0)
                  throw TypeError("Illegal str: Length not a multiple of 2");
          }
          var k = str.length,
              bb = new ByteBuffer((k / 2) | 0, littleEndian),
              b;
          for (var i=0, j=0; i<k; i+=2) {
              b = parseInt(str.substring(i, i+2), 16);
              if (!noAssert)
                  if (!isFinite(b) || b < 0 || b > 255)
                      throw TypeError("Illegal str: Contains non-hex characters");
              bb.view[j++] = b;
          }
          bb.limit = j;
          return bb;
      };
  
      // utfx-embeddable
  
      /**
       * utfx-embeddable (c) 2014 Daniel Wirtz <dcode@dcode.io>
       * Released under the Apache License, Version 2.0
       * see: https://github.com/dcodeIO/utfx for details
       */
      var utfx = function() {
          "use strict";
  
          /**
           * utfx namespace.
           * @inner
           * @type {!Object.<string,*>}
           */
          var utfx = {};
  
          /**
           * Maximum valid code point.
           * @type {number}
           * @const
           */
          utfx.MAX_CODEPOINT = 0x10FFFF;
  
          /**
           * Encodes UTF8 code points to UTF8 bytes.
           * @param {(!function():number|null) | number} src Code points source, either as a function returning the next code point
           *  respectively `null` if there are no more code points left or a single numeric code point.
           * @param {!function(number)} dst Bytes destination as a function successively called with the next byte
           */
          utfx.encodeUTF8 = function(src, dst) {
              var cp = null;
              if (typeof src === 'number')
                  cp = src,
                  src = function() { return null; };
              while (cp !== null || (cp = src()) !== null) {
                  if (cp < 0x80)
                      dst(cp&0x7F);
                  else if (cp < 0x800)
                      dst(((cp>>6)&0x1F)|0xC0),
                      dst((cp&0x3F)|0x80);
                  else if (cp < 0x10000)
                      dst(((cp>>12)&0x0F)|0xE0),
                      dst(((cp>>6)&0x3F)|0x80),
                      dst((cp&0x3F)|0x80);
                  else
                      dst(((cp>>18)&0x07)|0xF0),
                      dst(((cp>>12)&0x3F)|0x80),
                      dst(((cp>>6)&0x3F)|0x80),
                      dst((cp&0x3F)|0x80);
                  cp = null;
              }
          };
  
          /**
           * Decodes UTF8 bytes to UTF8 code points.
           * @param {!function():number|null} src Bytes source as a function returning the next byte respectively `null` if there
           *  are no more bytes left.
           * @param {!function(number)} dst Code points destination as a function successively called with each decoded code point.
           * @throws {RangeError} If a starting byte is invalid in UTF8
           * @throws {Error} If the last sequence is truncated. Has an array property `bytes` holding the
           *  remaining bytes.
           */
          utfx.decodeUTF8 = function(src, dst) {
              var a, b, c, d, fail = function(b) {
                  b = b.slice(0, b.indexOf(null));
                  var err = Error(b.toString());
                  err.name = "TruncatedError";
                  err['bytes'] = b;
                  throw err;
              };
              while ((a = src()) !== null) {
                  if ((a&0x80) === 0)
                      dst(a);
                  else if ((a&0xE0) === 0xC0)
                      ((b = src()) === null) && fail([a, b]),
                      dst(((a&0x1F)<<6) | (b&0x3F));
                  else if ((a&0xF0) === 0xE0)
                      ((b=src()) === null || (c=src()) === null) && fail([a, b, c]),
                      dst(((a&0x0F)<<12) | ((b&0x3F)<<6) | (c&0x3F));
                  else if ((a&0xF8) === 0xF0)
                      ((b=src()) === null || (c=src()) === null || (d=src()) === null) && fail([a, b, c ,d]),
                      dst(((a&0x07)<<18) | ((b&0x3F)<<12) | ((c&0x3F)<<6) | (d&0x3F));
                  else throw RangeError("Illegal starting byte: "+a);
              }
          };
  
          /**
           * Converts UTF16 characters to UTF8 code points.
           * @param {!function():number|null} src Characters source as a function returning the next char code respectively
           *  `null` if there are no more characters left.
           * @param {!function(number)} dst Code points destination as a function successively called with each converted code
           *  point.
           */
          utfx.UTF16toUTF8 = function(src, dst) {
              var c1, c2 = null;
              while (true) {
                  if ((c1 = c2 !== null ? c2 : src()) === null)
                      break;
                  if (c1 >= 0xD800 && c1 <= 0xDFFF) {
                      if ((c2 = src()) !== null) {
                          if (c2 >= 0xDC00 && c2 <= 0xDFFF) {
                              dst((c1-0xD800)*0x400+c2-0xDC00+0x10000);
                              c2 = null; continue;
                          }
                      }
                  }
                  dst(c1);
              }
              if (c2 !== null) dst(c2);
          };
  
          /**
           * Converts UTF8 code points to UTF16 characters.
           * @param {(!function():number|null) | number} src Code points source, either as a function returning the next code point
           *  respectively `null` if there are no more code points left or a single numeric code point.
           * @param {!function(number)} dst Characters destination as a function successively called with each converted char code.
           * @throws {RangeError} If a code point is out of range
           */
          utfx.UTF8toUTF16 = function(src, dst) {
              var cp = null;
              if (typeof src === 'number')
                  cp = src, src = function() { return null; };
              while (cp !== null || (cp = src()) !== null) {
                  if (cp <= 0xFFFF)
                      dst(cp);
                  else
                      cp -= 0x10000,
                      dst((cp>>10)+0xD800),
                      dst((cp%0x400)+0xDC00);
                  cp = null;
              }
          };
  
          /**
           * Converts and encodes UTF16 characters to UTF8 bytes.
           * @param {!function():number|null} src Characters source as a function returning the next char code respectively `null`
           *  if there are no more characters left.
           * @param {!function(number)} dst Bytes destination as a function successively called with the next byte.
           */
          utfx.encodeUTF16toUTF8 = function(src, dst) {
              utfx.UTF16toUTF8(src, function(cp) {
                  utfx.encodeUTF8(cp, dst);
              });
          };
  
          /**
           * Decodes and converts UTF8 bytes to UTF16 characters.
           * @param {!function():number|null} src Bytes source as a function returning the next byte respectively `null` if there
           *  are no more bytes left.
           * @param {!function(number)} dst Characters destination as a function successively called with each converted char code.
           * @throws {RangeError} If a starting byte is invalid in UTF8
           * @throws {Error} If the last sequence is truncated. Has an array property `bytes` holding the remaining bytes.
           */
          utfx.decodeUTF8toUTF16 = function(src, dst) {
              utfx.decodeUTF8(src, function(cp) {
                  utfx.UTF8toUTF16(cp, dst);
              });
          };
  
          /**
           * Calculates the byte length of an UTF8 code point.
           * @param {number} cp UTF8 code point
           * @returns {number} Byte length
           */
          utfx.calculateCodePoint = function(cp) {
              return (cp < 0x80) ? 1 : (cp < 0x800) ? 2 : (cp < 0x10000) ? 3 : 4;
          };
  
          /**
           * Calculates the number of UTF8 bytes required to store UTF8 code points.
           * @param {(!function():number|null)} src Code points source as a function returning the next code point respectively
           *  `null` if there are no more code points left.
           * @returns {number} The number of UTF8 bytes required
           */
          utfx.calculateUTF8 = function(src) {
              var cp, l=0;
              while ((cp = src()) !== null)
                  l += (cp < 0x80) ? 1 : (cp < 0x800) ? 2 : (cp < 0x10000) ? 3 : 4;
              return l;
          };
  
          /**
           * Calculates the number of UTF8 code points respectively UTF8 bytes required to store UTF16 char codes.
           * @param {(!function():number|null)} src Characters source as a function returning the next char code respectively
           *  `null` if there are no more characters left.
           * @returns {!Array.<number>} The number of UTF8 code points at index 0 and the number of UTF8 bytes required at index 1.
           */
          utfx.calculateUTF16asUTF8 = function(src) {
              var n=0, l=0;
              utfx.UTF16toUTF8(src, function(cp) {
                  ++n; l += (cp < 0x80) ? 1 : (cp < 0x800) ? 2 : (cp < 0x10000) ? 3 : 4;
              });
              return [n,l];
          };
  
          return utfx;
      }();
  
      // encodings/utf8
  
      /**
       * Encodes this ByteBuffer's contents between {@link ByteBuffer#offset} and {@link ByteBuffer#limit} to an UTF8 encoded
       *  string.
       * @returns {string} Hex encoded string
       * @throws {RangeError} If `offset > limit`
       * @expose
       */
      ByteBufferPrototype.toUTF8 = function(begin, end) {
          if (typeof begin === 'undefined') begin = this.offset;
          if (typeof end === 'undefined') end = this.limit;
          if (!this.noAssert) {
              if (typeof begin !== 'number' || begin % 1 !== 0)
                  throw TypeError("Illegal begin: Not an integer");
              begin >>>= 0;
              if (typeof end !== 'number' || end % 1 !== 0)
                  throw TypeError("Illegal end: Not an integer");
              end >>>= 0;
              if (begin < 0 || begin > end || end > this.buffer.byteLength)
                  throw RangeError("Illegal range: 0 <= "+begin+" <= "+end+" <= "+this.buffer.byteLength);
          }
          var sd; try {
              utfx.decodeUTF8toUTF16(function() {
                  return begin < end ? this.view[begin++] : null;
              }.bind(this), sd = stringDestination());
          } catch (e) {
              if (begin !== end)
                  throw RangeError("Illegal range: Truncated data, "+begin+" != "+end);
          }
          return sd();
      };
  
      /**
       * Decodes an UTF8 encoded string to a ByteBuffer.
       * @param {string} str String to decode
       * @param {boolean=} littleEndian Whether to use little or big endian byte order. Defaults to
       *  {@link ByteBuffer.DEFAULT_ENDIAN}.
       * @param {boolean=} noAssert Whether to skip assertions of offsets and values. Defaults to
       *  {@link ByteBuffer.DEFAULT_NOASSERT}.
       * @returns {!ByteBuffer} ByteBuffer
       * @expose
       */
      ByteBuffer.fromUTF8 = function(str, littleEndian, noAssert) {
          if (!noAssert)
              if (typeof str !== 'string')
                  throw TypeError("Illegal str: Not a string");
          var bb = new ByteBuffer(utfx.calculateUTF16asUTF8(stringSource(str), true)[1], littleEndian, noAssert),
              i = 0;
          utfx.encodeUTF16toUTF8(stringSource(str), function(b) {
              bb.view[i++] = b;
          });
          bb.limit = i;
          return bb;
      };
  
      return ByteBuffer;
  });
  
  },{"long":64}],41:[function(require,module,exports){
  (function (Buffer){
  var Transform = require('stream').Transform
  var inherits = require('inherits')
  var StringDecoder = require('string_decoder').StringDecoder
  module.exports = CipherBase
  inherits(CipherBase, Transform)
  function CipherBase (hashMode) {
    Transform.call(this)
    this.hashMode = typeof hashMode === 'string'
    if (this.hashMode) {
      this[hashMode] = this._finalOrDigest
    } else {
      this.final = this._finalOrDigest
    }
    this._decoder = null
    this._encoding = null
  }
  CipherBase.prototype.update = function (data, inputEnc, outputEnc) {
    if (typeof data === 'string') {
      data = new Buffer(data, inputEnc)
    }
    var outData = this._update(data)
    if (this.hashMode) {
      return this
    }
    if (outputEnc) {
      outData = this._toString(outData, outputEnc)
    }
    return outData
  }
  
  CipherBase.prototype.setAutoPadding = function () {}
  
  CipherBase.prototype.getAuthTag = function () {
    throw new Error('trying to get auth tag in unsupported state')
  }
  
  CipherBase.prototype.setAuthTag = function () {
    throw new Error('trying to set auth tag in unsupported state')
  }
  
  CipherBase.prototype.setAAD = function () {
    throw new Error('trying to set aad in unsupported state')
  }
  
  CipherBase.prototype._transform = function (data, _, next) {
    var err
    try {
      if (this.hashMode) {
        this._update(data)
      } else {
        this.push(this._update(data))
      }
    } catch (e) {
      err = e
    } finally {
      next(err)
    }
  }
  CipherBase.prototype._flush = function (done) {
    var err
    try {
      this.push(this._final())
    } catch (e) {
      err = e
    } finally {
      done(err)
    }
  }
  CipherBase.prototype._finalOrDigest = function (outputEnc) {
    var outData = this._final() || new Buffer('')
    if (outputEnc) {
      outData = this._toString(outData, outputEnc, true)
    }
    return outData
  }
  
  CipherBase.prototype._toString = function (value, enc, fin) {
    if (!this._decoder) {
      this._decoder = new StringDecoder(enc)
      this._encoding = enc
    }
    if (this._encoding !== enc) {
      throw new Error('can\'t switch encodings')
    }
    var out = this._decoder.write(value)
    if (fin) {
      out += this._decoder.end()
    }
    return out
  }
  
  }).call(this,require("buffer").Buffer)
  },{"buffer":79,"inherits":63,"stream":99,"string_decoder":100}],42:[function(require,module,exports){
  (function (Buffer){
  'use strict';
  var inherits = require('inherits')
  var md5 = require('./md5')
  var rmd160 = require('ripemd160')
  var sha = require('sha.js')
  
  var Base = require('cipher-base')
  
  function HashNoConstructor(hash) {
    Base.call(this, 'digest')
  
    this._hash = hash
    this.buffers = []
  }
  
  inherits(HashNoConstructor, Base)
  
  HashNoConstructor.prototype._update = function (data) {
    this.buffers.push(data)
  }
  
  HashNoConstructor.prototype._final = function () {
    var buf = Buffer.concat(this.buffers)
    var r = this._hash(buf)
    this.buffers = null
  
    return r
  }
  
  function Hash(hash) {
    Base.call(this, 'digest')
  
    this._hash = hash
  }
  
  inherits(Hash, Base)
  
  Hash.prototype._update = function (data) {
    this._hash.update(data)
  }
  
  Hash.prototype._final = function () {
    return this._hash.digest()
  }
  
  module.exports = function createHash (alg) {
    alg = alg.toLowerCase()
    if ('md5' === alg) return new HashNoConstructor(md5)
    if ('rmd160' === alg || 'ripemd160' === alg) return new HashNoConstructor(rmd160)
  
    return new Hash(sha(alg))
  }
  
  }).call(this,require("buffer").Buffer)
  },{"./md5":44,"buffer":79,"cipher-base":41,"inherits":63,"ripemd160":65,"sha.js":68}],43:[function(require,module,exports){
  (function (Buffer){
  'use strict';
  var intSize = 4;
  var zeroBuffer = new Buffer(intSize); zeroBuffer.fill(0);
  var chrsz = 8;
  
  function toArray(buf, bigEndian) {
    if ((buf.length % intSize) !== 0) {
      var len = buf.length + (intSize - (buf.length % intSize));
      buf = Buffer.concat([buf, zeroBuffer], len);
    }
  
    var arr = [];
    var fn = bigEndian ? buf.readInt32BE : buf.readInt32LE;
    for (var i = 0; i < buf.length; i += intSize) {
      arr.push(fn.call(buf, i));
    }
    return arr;
  }
  
  function toBuffer(arr, size, bigEndian) {
    var buf = new Buffer(size);
    var fn = bigEndian ? buf.writeInt32BE : buf.writeInt32LE;
    for (var i = 0; i < arr.length; i++) {
      fn.call(buf, arr[i], i * 4, true);
    }
    return buf;
  }
  
  function hash(buf, fn, hashSize, bigEndian) {
    if (!Buffer.isBuffer(buf)) buf = new Buffer(buf);
    var arr = fn(toArray(buf, bigEndian), buf.length * chrsz);
    return toBuffer(arr, hashSize, bigEndian);
  }
  exports.hash = hash;
  }).call(this,require("buffer").Buffer)
  },{"buffer":79}],44:[function(require,module,exports){
  'use strict';
  /*
   * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message
   * Digest Algorithm, as defined in RFC 1321.
   * Version 2.1 Copyright (C) Paul Johnston 1999 - 2002.
   * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
   * Distributed under the BSD License
   * See http://pajhome.org.uk/crypt/md5 for more info.
   */
  
  var helpers = require('./helpers');
  
  /*
   * Calculate the MD5 of an array of little-endian words, and a bit length
   */
  function core_md5(x, len)
  {
    /* append padding */
    x[len >> 5] |= 0x80 << ((len) % 32);
    x[(((len + 64) >>> 9) << 4) + 14] = len;
  
    var a =  1732584193;
    var b = -271733879;
    var c = -1732584194;
    var d =  271733878;
  
    for(var i = 0; i < x.length; i += 16)
    {
      var olda = a;
      var oldb = b;
      var oldc = c;
      var oldd = d;
  
      a = md5_ff(a, b, c, d, x[i+ 0], 7 , -680876936);
      d = md5_ff(d, a, b, c, x[i+ 1], 12, -389564586);
      c = md5_ff(c, d, a, b, x[i+ 2], 17,  606105819);
      b = md5_ff(b, c, d, a, x[i+ 3], 22, -1044525330);
      a = md5_ff(a, b, c, d, x[i+ 4], 7 , -176418897);
      d = md5_ff(d, a, b, c, x[i+ 5], 12,  1200080426);
      c = md5_ff(c, d, a, b, x[i+ 6], 17, -1473231341);
      b = md5_ff(b, c, d, a, x[i+ 7], 22, -45705983);
      a = md5_ff(a, b, c, d, x[i+ 8], 7 ,  1770035416);
      d = md5_ff(d, a, b, c, x[i+ 9], 12, -1958414417);
      c = md5_ff(c, d, a, b, x[i+10], 17, -42063);
      b = md5_ff(b, c, d, a, x[i+11], 22, -1990404162);
      a = md5_ff(a, b, c, d, x[i+12], 7 ,  1804603682);
      d = md5_ff(d, a, b, c, x[i+13], 12, -40341101);
      c = md5_ff(c, d, a, b, x[i+14], 17, -1502002290);
      b = md5_ff(b, c, d, a, x[i+15], 22,  1236535329);
  
      a = md5_gg(a, b, c, d, x[i+ 1], 5 , -165796510);
      d = md5_gg(d, a, b, c, x[i+ 6], 9 , -1069501632);
      c = md5_gg(c, d, a, b, x[i+11], 14,  643717713);
      b = md5_gg(b, c, d, a, x[i+ 0], 20, -373897302);
      a = md5_gg(a, b, c, d, x[i+ 5], 5 , -701558691);
      d = md5_gg(d, a, b, c, x[i+10], 9 ,  38016083);
      c = md5_gg(c, d, a, b, x[i+15], 14, -660478335);
      b = md5_gg(b, c, d, a, x[i+ 4], 20, -405537848);
      a = md5_gg(a, b, c, d, x[i+ 9], 5 ,  568446438);
      d = md5_gg(d, a, b, c, x[i+14], 9 , -1019803690);
      c = md5_gg(c, d, a, b, x[i+ 3], 14, -187363961);
      b = md5_gg(b, c, d, a, x[i+ 8], 20,  1163531501);
      a = md5_gg(a, b, c, d, x[i+13], 5 , -1444681467);
      d = md5_gg(d, a, b, c, x[i+ 2], 9 , -51403784);
      c = md5_gg(c, d, a, b, x[i+ 7], 14,  1735328473);
      b = md5_gg(b, c, d, a, x[i+12], 20, -1926607734);
  
      a = md5_hh(a, b, c, d, x[i+ 5], 4 , -378558);
      d = md5_hh(d, a, b, c, x[i+ 8], 11, -2022574463);
      c = md5_hh(c, d, a, b, x[i+11], 16,  1839030562);
      b = md5_hh(b, c, d, a, x[i+14], 23, -35309556);
      a = md5_hh(a, b, c, d, x[i+ 1], 4 , -1530992060);
      d = md5_hh(d, a, b, c, x[i+ 4], 11,  1272893353);
      c = md5_hh(c, d, a, b, x[i+ 7], 16, -155497632);
      b = md5_hh(b, c, d, a, x[i+10], 23, -1094730640);
      a = md5_hh(a, b, c, d, x[i+13], 4 ,  681279174);
      d = md5_hh(d, a, b, c, x[i+ 0], 11, -358537222);
      c = md5_hh(c, d, a, b, x[i+ 3], 16, -722521979);
      b = md5_hh(b, c, d, a, x[i+ 6], 23,  76029189);
      a = md5_hh(a, b, c, d, x[i+ 9], 4 , -640364487);
      d = md5_hh(d, a, b, c, x[i+12], 11, -421815835);
      c = md5_hh(c, d, a, b, x[i+15], 16,  530742520);
      b = md5_hh(b, c, d, a, x[i+ 2], 23, -995338651);
  
      a = md5_ii(a, b, c, d, x[i+ 0], 6 , -198630844);
      d = md5_ii(d, a, b, c, x[i+ 7], 10,  1126891415);
      c = md5_ii(c, d, a, b, x[i+14], 15, -1416354905);
      b = md5_ii(b, c, d, a, x[i+ 5], 21, -57434055);
      a = md5_ii(a, b, c, d, x[i+12], 6 ,  1700485571);
      d = md5_ii(d, a, b, c, x[i+ 3], 10, -1894986606);
      c = md5_ii(c, d, a, b, x[i+10], 15, -1051523);
      b = md5_ii(b, c, d, a, x[i+ 1], 21, -2054922799);
      a = md5_ii(a, b, c, d, x[i+ 8], 6 ,  1873313359);
      d = md5_ii(d, a, b, c, x[i+15], 10, -30611744);
      c = md5_ii(c, d, a, b, x[i+ 6], 15, -1560198380);
      b = md5_ii(b, c, d, a, x[i+13], 21,  1309151649);
      a = md5_ii(a, b, c, d, x[i+ 4], 6 , -145523070);
      d = md5_ii(d, a, b, c, x[i+11], 10, -1120210379);
      c = md5_ii(c, d, a, b, x[i+ 2], 15,  718787259);
      b = md5_ii(b, c, d, a, x[i+ 9], 21, -343485551);
  
      a = safe_add(a, olda);
      b = safe_add(b, oldb);
      c = safe_add(c, oldc);
      d = safe_add(d, oldd);
    }
    return Array(a, b, c, d);
  
  }
  
  /*
   * These functions implement the four basic operations the algorithm uses.
   */
  function md5_cmn(q, a, b, x, s, t)
  {
    return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s),b);
  }
  function md5_ff(a, b, c, d, x, s, t)
  {
    return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t);
  }
  function md5_gg(a, b, c, d, x, s, t)
  {
    return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t);
  }
  function md5_hh(a, b, c, d, x, s, t)
  {
    return md5_cmn(b ^ c ^ d, a, b, x, s, t);
  }
  function md5_ii(a, b, c, d, x, s, t)
  {
    return md5_cmn(c ^ (b | (~d)), a, b, x, s, t);
  }
  
  /*
   * Add integers, wrapping at 2^32. This uses 16-bit operations internally
   * to work around bugs in some JS interpreters.
   */
  function safe_add(x, y)
  {
    var lsw = (x & 0xFFFF) + (y & 0xFFFF);
    var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
    return (msw << 16) | (lsw & 0xFFFF);
  }
  
  /*
   * Bitwise rotate a 32-bit number to the left.
   */
  function bit_rol(num, cnt)
  {
    return (num << cnt) | (num >>> (32 - cnt));
  }
  
  module.exports = function md5(buf) {
    return helpers.hash(buf, core_md5, 16);
  };
  },{"./helpers":43}],45:[function(require,module,exports){
  (function (Buffer){
  'use strict';
  var createHash = require('create-hash/browser');
  var inherits = require('inherits')
  
  var Transform = require('stream').Transform
  
  var ZEROS = new Buffer(128)
  ZEROS.fill(0)
  
  function Hmac(alg, key) {
    Transform.call(this)
    alg = alg.toLowerCase()
    if (typeof key === 'string') {
      key = new Buffer(key)
    }
  
    var blocksize = (alg === 'sha512' || alg === 'sha384') ? 128 : 64
  
    this._alg = alg
    this._key = key
  
    if (key.length > blocksize) {
      key = createHash(alg).update(key).digest()
  
    } else if (key.length < blocksize) {
      key = Buffer.concat([key, ZEROS], blocksize)
    }
  
    var ipad = this._ipad = new Buffer(blocksize)
    var opad = this._opad = new Buffer(blocksize)
  
    for (var i = 0; i < blocksize; i++) {
      ipad[i] = key[i] ^ 0x36
      opad[i] = key[i] ^ 0x5C
    }
  
    this._hash = createHash(alg).update(ipad)
  }
  
  inherits(Hmac, Transform)
  
  Hmac.prototype.update = function (data, enc) {
    this._hash.update(data, enc)
  
    return this
  }
  
  Hmac.prototype._transform = function (data, _, next) {
    this._hash.update(data)
  
    next()
  }
  
  Hmac.prototype._flush = function (next) {
    this.push(this.digest())
  
    next()
  }
  
  Hmac.prototype.digest = function (enc) {
    var h = this._hash.digest()
  
    return createHash(this._alg).update(this._opad).update(h).digest(enc)
  }
  
  module.exports = function createHmac(alg, key) {
    return new Hmac(alg, key)
  }
  
  }).call(this,require("buffer").Buffer)
  },{"buffer":79,"create-hash/browser":42,"inherits":63,"stream":99}],46:[function(require,module,exports){
  ;(function (root, factory, undef) {
  	if (typeof exports === "object") {
  		// CommonJS
  		module.exports = exports = factory(require("./core"), require("./enc-base64"), require("./md5"), require("./evpkdf"), require("./cipher-core"));
  	}
  	else if (typeof define === "function" && define.amd) {
  		// AMD
  		define(["./core", "./enc-base64", "./md5", "./evpkdf", "./cipher-core"], factory);
  	}
  	else {
  		// Global (browser)
  		factory(root.CryptoJS);
  	}
  }(this, function (CryptoJS) {
  
  	(function () {
  	    // Shortcuts
  	    var C = CryptoJS;
  	    var C_lib = C.lib;
  	    var BlockCipher = C_lib.BlockCipher;
  	    var C_algo = C.algo;
  
  	    // Lookup tables
  	    var SBOX = [];
  	    var INV_SBOX = [];
  	    var SUB_MIX_0 = [];
  	    var SUB_MIX_1 = [];
  	    var SUB_MIX_2 = [];
  	    var SUB_MIX_3 = [];
  	    var INV_SUB_MIX_0 = [];
  	    var INV_SUB_MIX_1 = [];
  	    var INV_SUB_MIX_2 = [];
  	    var INV_SUB_MIX_3 = [];
  
  	    // Compute lookup tables
  	    (function () {
  	        // Compute double table
  	        var d = [];
  	        for (var i = 0; i < 256; i++) {
  	            if (i < 128) {
  	                d[i] = i << 1;
  	            } else {
  	                d[i] = (i << 1) ^ 0x11b;
  	            }
  	        }
  
  	        // Walk GF(2^8)
  	        var x = 0;
  	        var xi = 0;
  	        for (var i = 0; i < 256; i++) {
  	            // Compute sbox
  	            var sx = xi ^ (xi << 1) ^ (xi << 2) ^ (xi << 3) ^ (xi << 4);
  	            sx = (sx >>> 8) ^ (sx & 0xff) ^ 0x63;
  	            SBOX[x] = sx;
  	            INV_SBOX[sx] = x;
  
  	            // Compute multiplication
  	            var x2 = d[x];
  	            var x4 = d[x2];
  	            var x8 = d[x4];
  
  	            // Compute sub bytes, mix columns tables
  	            var t = (d[sx] * 0x101) ^ (sx * 0x1010100);
  	            SUB_MIX_0[x] = (t << 24) | (t >>> 8);
  	            SUB_MIX_1[x] = (t << 16) | (t >>> 16);
  	            SUB_MIX_2[x] = (t << 8)  | (t >>> 24);
  	            SUB_MIX_3[x] = t;
  
  	            // Compute inv sub bytes, inv mix columns tables
  	            var t = (x8 * 0x1010101) ^ (x4 * 0x10001) ^ (x2 * 0x101) ^ (x * 0x1010100);
  	            INV_SUB_MIX_0[sx] = (t << 24) | (t >>> 8);
  	            INV_SUB_MIX_1[sx] = (t << 16) | (t >>> 16);
  	            INV_SUB_MIX_2[sx] = (t << 8)  | (t >>> 24);
  	            INV_SUB_MIX_3[sx] = t;
  
  	            // Compute next counter
  	            if (!x) {
  	                x = xi = 1;
  	            } else {
  	                x = x2 ^ d[d[d[x8 ^ x2]]];
  	                xi ^= d[d[xi]];
  	            }
  	        }
  	    }());
  
  	    // Precomputed Rcon lookup
  	    var RCON = [0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36];
  
  	    /**
  	     * AES block cipher algorithm.
  	     */
  	    var AES = C_algo.AES = BlockCipher.extend({
  	        _doReset: function () {
  	            // Skip reset of nRounds has been set before and key did not change
  	            if (this._nRounds && this._keyPriorReset === this._key) {
  	                return;
  	            }
  
  	            // Shortcuts
  	            var key = this._keyPriorReset = this._key;
  	            var keyWords = key.words;
  	            var keySize = key.sigBytes / 4;
  
  	            // Compute number of rounds
  	            var nRounds = this._nRounds = keySize + 6;
  
  	            // Compute number of key schedule rows
  	            var ksRows = (nRounds + 1) * 4;
  
  	            // Compute key schedule
  	            var keySchedule = this._keySchedule = [];
  	            for (var ksRow = 0; ksRow < ksRows; ksRow++) {
  	                if (ksRow < keySize) {
  	                    keySchedule[ksRow] = keyWords[ksRow];
  	                } else {
  	                    var t = keySchedule[ksRow - 1];
  
  	                    if (!(ksRow % keySize)) {
  	                        // Rot word
  	                        t = (t << 8) | (t >>> 24);
  
  	                        // Sub word
  	                        t = (SBOX[t >>> 24] << 24) | (SBOX[(t >>> 16) & 0xff] << 16) | (SBOX[(t >>> 8) & 0xff] << 8) | SBOX[t & 0xff];
  
  	                        // Mix Rcon
  	                        t ^= RCON[(ksRow / keySize) | 0] << 24;
  	                    } else if (keySize > 6 && ksRow % keySize == 4) {
  	                        // Sub word
  	                        t = (SBOX[t >>> 24] << 24) | (SBOX[(t >>> 16) & 0xff] << 16) | (SBOX[(t >>> 8) & 0xff] << 8) | SBOX[t & 0xff];
  	                    }
  
  	                    keySchedule[ksRow] = keySchedule[ksRow - keySize] ^ t;
  	                }
  	            }
  
  	            // Compute inv key schedule
  	            var invKeySchedule = this._invKeySchedule = [];
  	            for (var invKsRow = 0; invKsRow < ksRows; invKsRow++) {
  	                var ksRow = ksRows - invKsRow;
  
  	                if (invKsRow % 4) {
  	                    var t = keySchedule[ksRow];
  	                } else {
  	                    var t = keySchedule[ksRow - 4];
  	                }
  
  	                if (invKsRow < 4 || ksRow <= 4) {
  	                    invKeySchedule[invKsRow] = t;
  	                } else {
  	                    invKeySchedule[invKsRow] = INV_SUB_MIX_0[SBOX[t >>> 24]] ^ INV_SUB_MIX_1[SBOX[(t >>> 16) & 0xff]] ^
  	                                               INV_SUB_MIX_2[SBOX[(t >>> 8) & 0xff]] ^ INV_SUB_MIX_3[SBOX[t & 0xff]];
  	                }
  	            }
  	        },
  
  	        encryptBlock: function (M, offset) {
  	            this._doCryptBlock(M, offset, this._keySchedule, SUB_MIX_0, SUB_MIX_1, SUB_MIX_2, SUB_MIX_3, SBOX);
  	        },
  
  	        decryptBlock: function (M, offset) {
  	            // Swap 2nd and 4th rows
  	            var t = M[offset + 1];
  	            M[offset + 1] = M[offset + 3];
  	            M[offset + 3] = t;
  
  	            this._doCryptBlock(M, offset, this._invKeySchedule, INV_SUB_MIX_0, INV_SUB_MIX_1, INV_SUB_MIX_2, INV_SUB_MIX_3, INV_SBOX);
  
  	            // Inv swap 2nd and 4th rows
  	            var t = M[offset + 1];
  	            M[offset + 1] = M[offset + 3];
  	            M[offset + 3] = t;
  	        },
  
  	        _doCryptBlock: function (M, offset, keySchedule, SUB_MIX_0, SUB_MIX_1, SUB_MIX_2, SUB_MIX_3, SBOX) {
  	            // Shortcut
  	            var nRounds = this._nRounds;
  
  	            // Get input, add round key
  	            var s0 = M[offset]     ^ keySchedule[0];
  	            var s1 = M[offset + 1] ^ keySchedule[1];
  	            var s2 = M[offset + 2] ^ keySchedule[2];
  	            var s3 = M[offset + 3] ^ keySchedule[3];
  
  	            // Key schedule row counter
  	            var ksRow = 4;
  
  	            // Rounds
  	            for (var round = 1; round < nRounds; round++) {
  	                // Shift rows, sub bytes, mix columns, add round key
  	                var t0 = SUB_MIX_0[s0 >>> 24] ^ SUB_MIX_1[(s1 >>> 16) & 0xff] ^ SUB_MIX_2[(s2 >>> 8) & 0xff] ^ SUB_MIX_3[s3 & 0xff] ^ keySchedule[ksRow++];
  	                var t1 = SUB_MIX_0[s1 >>> 24] ^ SUB_MIX_1[(s2 >>> 16) & 0xff] ^ SUB_MIX_2[(s3 >>> 8) & 0xff] ^ SUB_MIX_3[s0 & 0xff] ^ keySchedule[ksRow++];
  	                var t2 = SUB_MIX_0[s2 >>> 24] ^ SUB_MIX_1[(s3 >>> 16) & 0xff] ^ SUB_MIX_2[(s0 >>> 8) & 0xff] ^ SUB_MIX_3[s1 & 0xff] ^ keySchedule[ksRow++];
  	                var t3 = SUB_MIX_0[s3 >>> 24] ^ SUB_MIX_1[(s0 >>> 16) & 0xff] ^ SUB_MIX_2[(s1 >>> 8) & 0xff] ^ SUB_MIX_3[s2 & 0xff] ^ keySchedule[ksRow++];
  
  	                // Update state
  	                s0 = t0;
  	                s1 = t1;
  	                s2 = t2;
  	                s3 = t3;
  	            }
  
  	            // Shift rows, sub bytes, add round key
  	            var t0 = ((SBOX[s0 >>> 24] << 24) | (SBOX[(s1 >>> 16) & 0xff] << 16) | (SBOX[(s2 >>> 8) & 0xff] << 8) | SBOX[s3 & 0xff]) ^ keySchedule[ksRow++];
  	            var t1 = ((SBOX[s1 >>> 24] << 24) | (SBOX[(s2 >>> 16) & 0xff] << 16) | (SBOX[(s3 >>> 8) & 0xff] << 8) | SBOX[s0 & 0xff]) ^ keySchedule[ksRow++];
  	            var t2 = ((SBOX[s2 >>> 24] << 24) | (SBOX[(s3 >>> 16) & 0xff] << 16) | (SBOX[(s0 >>> 8) & 0xff] << 8) | SBOX[s1 & 0xff]) ^ keySchedule[ksRow++];
  	            var t3 = ((SBOX[s3 >>> 24] << 24) | (SBOX[(s0 >>> 16) & 0xff] << 16) | (SBOX[(s1 >>> 8) & 0xff] << 8) | SBOX[s2 & 0xff]) ^ keySchedule[ksRow++];
  
  	            // Set output
  	            M[offset]     = t0;
  	            M[offset + 1] = t1;
  	            M[offset + 2] = t2;
  	            M[offset + 3] = t3;
  	        },
  
  	        keySize: 256/32
  	    });
  
  	    /**
  	     * Shortcut functions to the cipher's object interface.
  	     *
  	     * @example
  	     *
  	     *     var ciphertext = CryptoJS.AES.encrypt(message, key, cfg);
  	     *     var plaintext  = CryptoJS.AES.decrypt(ciphertext, key, cfg);
  	     */
  	    C.AES = BlockCipher._createHelper(AES);
  	}());
  
  
  	return CryptoJS.AES;
  
  }));
  },{"./cipher-core":47,"./core":48,"./enc-base64":49,"./evpkdf":51,"./md5":53}],47:[function(require,module,exports){
  ;(function (root, factory, undef) {
  	if (typeof exports === "object") {
  		// CommonJS
  		module.exports = exports = factory(require("./core"), require("./evpkdf"));
  	}
  	else if (typeof define === "function" && define.amd) {
  		// AMD
  		define(["./core", "./evpkdf"], factory);
  	}
  	else {
  		// Global (browser)
  		factory(root.CryptoJS);
  	}
  }(this, function (CryptoJS) {
  
  	/**
  	 * Cipher core components.
  	 */
  	CryptoJS.lib.Cipher || (function (undefined) {
  	    // Shortcuts
  	    var C = CryptoJS;
  	    var C_lib = C.lib;
  	    var Base = C_lib.Base;
  	    var WordArray = C_lib.WordArray;
  	    var BufferedBlockAlgorithm = C_lib.BufferedBlockAlgorithm;
  	    var C_enc = C.enc;
  	    var Utf8 = C_enc.Utf8;
  	    var Base64 = C_enc.Base64;
  	    var C_algo = C.algo;
  	    var EvpKDF = C_algo.EvpKDF;
  
  	    /**
  	     * Abstract base cipher template.
  	     *
  	     * @property {number} keySize This cipher's key size. Default: 4 (128 bits)
  	     * @property {number} ivSize This cipher's IV size. Default: 4 (128 bits)
  	     * @property {number} _ENC_XFORM_MODE A constant representing encryption mode.
  	     * @property {number} _DEC_XFORM_MODE A constant representing decryption mode.
  	     */
  	    var Cipher = C_lib.Cipher = BufferedBlockAlgorithm.extend({
  	        /**
  	         * Configuration options.
  	         *
  	         * @property {WordArray} iv The IV to use for this operation.
  	         */
  	        cfg: Base.extend(),
  
  	        /**
  	         * Creates this cipher in encryption mode.
  	         *
  	         * @param {WordArray} key The key.
  	         * @param {Object} cfg (Optional) The configuration options to use for this operation.
  	         *
  	         * @return {Cipher} A cipher instance.
  	         *
  	         * @static
  	         *
  	         * @example
  	         *
  	         *     var cipher = CryptoJS.algo.AES.createEncryptor(keyWordArray, { iv: ivWordArray });
  	         */
  	        createEncryptor: function (key, cfg) {
  	            return this.create(this._ENC_XFORM_MODE, key, cfg);
  	        },
  
  	        /**
  	         * Creates this cipher in decryption mode.
  	         *
  	         * @param {WordArray} key The key.
  	         * @param {Object} cfg (Optional) The configuration options to use for this operation.
  	         *
  	         * @return {Cipher} A cipher instance.
  	         *
  	         * @static
  	         *
  	         * @example
  	         *
  	         *     var cipher = CryptoJS.algo.AES.createDecryptor(keyWordArray, { iv: ivWordArray });
  	         */
  	        createDecryptor: function (key, cfg) {
  	            return this.create(this._DEC_XFORM_MODE, key, cfg);
  	        },
  
  	        /**
  	         * Initializes a newly created cipher.
  	         *
  	         * @param {number} xformMode Either the encryption or decryption transormation mode constant.
  	         * @param {WordArray} key The key.
  	         * @param {Object} cfg (Optional) The configuration options to use for this operation.
  	         *
  	         * @example
  	         *
  	         *     var cipher = CryptoJS.algo.AES.create(CryptoJS.algo.AES._ENC_XFORM_MODE, keyWordArray, { iv: ivWordArray });
  	         */
  	        init: function (xformMode, key, cfg) {
  	            // Apply config defaults
  	            this.cfg = this.cfg.extend(cfg);
  
  	            // Store transform mode and key
  	            this._xformMode = xformMode;
  	            this._key = key;
  
  	            // Set initial values
  	            this.reset();
  	        },
  
  	        /**
  	         * Resets this cipher to its initial state.
  	         *
  	         * @example
  	         *
  	         *     cipher.reset();
  	         */
  	        reset: function () {
  	            // Reset data buffer
  	            BufferedBlockAlgorithm.reset.call(this);
  
  	            // Perform concrete-cipher logic
  	            this._doReset();
  	        },
  
  	        /**
  	         * Adds data to be encrypted or decrypted.
  	         *
  	         * @param {WordArray|string} dataUpdate The data to encrypt or decrypt.
  	         *
  	         * @return {WordArray} The data after processing.
  	         *
  	         * @example
  	         *
  	         *     var encrypted = cipher.process('data');
  	         *     var encrypted = cipher.process(wordArray);
  	         */
  	        process: function (dataUpdate) {
  	            // Append
  	            this._append(dataUpdate);
  
  	            // Process available blocks
  	            return this._process();
  	        },
  
  	        /**
  	         * Finalizes the encryption or decryption process.
  	         * Note that the finalize operation is effectively a destructive, read-once operation.
  	         *
  	         * @param {WordArray|string} dataUpdate The final data to encrypt or decrypt.
  	         *
  	         * @return {WordArray} The data after final processing.
  	         *
  	         * @example
  	         *
  	         *     var encrypted = cipher.finalize();
  	         *     var encrypted = cipher.finalize('data');
  	         *     var encrypted = cipher.finalize(wordArray);
  	         */
  	        finalize: function (dataUpdate) {
  	            // Final data update
  	            if (dataUpdate) {
  	                this._append(dataUpdate);
  	            }
  
  	            // Perform concrete-cipher logic
  	            var finalProcessedData = this._doFinalize();
  
  	            return finalProcessedData;
  	        },
  
  	        keySize: 128/32,
  
  	        ivSize: 128/32,
  
  	        _ENC_XFORM_MODE: 1,
  
  	        _DEC_XFORM_MODE: 2,
  
  	        /**
  	         * Creates shortcut functions to a cipher's object interface.
  	         *
  	         * @param {Cipher} cipher The cipher to create a helper for.
  	         *
  	         * @return {Object} An object with encrypt and decrypt shortcut functions.
  	         *
  	         * @static
  	         *
  	         * @example
  	         *
  	         *     var AES = CryptoJS.lib.Cipher._createHelper(CryptoJS.algo.AES);
  	         */
  	        _createHelper: (function () {
  	            function selectCipherStrategy(key) {
  	                if (typeof key == 'string') {
  	                    return PasswordBasedCipher;
  	                } else {
  	                    return SerializableCipher;
  	                }
  	            }
  
  	            return function (cipher) {
  	                return {
  	                    encrypt: function (message, key, cfg) {
  	                        return selectCipherStrategy(key).encrypt(cipher, message, key, cfg);
  	                    },
  
  	                    decrypt: function (ciphertext, key, cfg) {
  	                        return selectCipherStrategy(key).decrypt(cipher, ciphertext, key, cfg);
  	                    }
  	                };
  	            };
  	        }())
  	    });
  
  	    /**
  	     * Abstract base stream cipher template.
  	     *
  	     * @property {number} blockSize The number of 32-bit words this cipher operates on. Default: 1 (32 bits)
  	     */
  	    var StreamCipher = C_lib.StreamCipher = Cipher.extend({
  	        _doFinalize: function () {
  	            // Process partial blocks
  	            var finalProcessedBlocks = this._process(!!'flush');
  
  	            return finalProcessedBlocks;
  	        },
  
  	        blockSize: 1
  	    });
  
  	    /**
  	     * Mode namespace.
  	     */
  	    var C_mode = C.mode = {};
  
  	    /**
  	     * Abstract base block cipher mode template.
  	     */
  	    var BlockCipherMode = C_lib.BlockCipherMode = Base.extend({
  	        /**
  	         * Creates this mode for encryption.
  	         *
  	         * @param {Cipher} cipher A block cipher instance.
  	         * @param {Array} iv The IV words.
  	         *
  	         * @static
  	         *
  	         * @example
  	         *
  	         *     var mode = CryptoJS.mode.CBC.createEncryptor(cipher, iv.words);
  	         */
  	        createEncryptor: function (cipher, iv) {
  	            return this.Encryptor.create(cipher, iv);
  	        },
  
  	        /**
  	         * Creates this mode for decryption.
  	         *
  	         * @param {Cipher} cipher A block cipher instance.
  	         * @param {Array} iv The IV words.
  	         *
  	         * @static
  	         *
  	         * @example
  	         *
  	         *     var mode = CryptoJS.mode.CBC.createDecryptor(cipher, iv.words);
  	         */
  	        createDecryptor: function (cipher, iv) {
  	            return this.Decryptor.create(cipher, iv);
  	        },
  
  	        /**
  	         * Initializes a newly created mode.
  	         *
  	         * @param {Cipher} cipher A block cipher instance.
  	         * @param {Array} iv The IV words.
  	         *
  	         * @example
  	         *
  	         *     var mode = CryptoJS.mode.CBC.Encryptor.create(cipher, iv.words);
  	         */
  	        init: function (cipher, iv) {
  	            this._cipher = cipher;
  	            this._iv = iv;
  	        }
  	    });
  
  	    /**
  	     * Cipher Block Chaining mode.
  	     */
  	    var CBC = C_mode.CBC = (function () {
  	        /**
  	         * Abstract base CBC mode.
  	         */
  	        var CBC = BlockCipherMode.extend();
  
  	        /**
  	         * CBC encryptor.
  	         */
  	        CBC.Encryptor = CBC.extend({
  	            /**
  	             * Processes the data block at offset.
  	             *
  	             * @param {Array} words The data words to operate on.
  	             * @param {number} offset The offset where the block starts.
  	             *
  	             * @example
  	             *
  	             *     mode.processBlock(data.words, offset);
  	             */
  	            processBlock: function (words, offset) {
  	                // Shortcuts
  	                var cipher = this._cipher;
  	                var blockSize = cipher.blockSize;
  
  	                // XOR and encrypt
  	                xorBlock.call(this, words, offset, blockSize);
  	                cipher.encryptBlock(words, offset);
  
  	                // Remember this block to use with next block
  	                this._prevBlock = words.slice(offset, offset + blockSize);
  	            }
  	        });
  
  	        /**
  	         * CBC decryptor.
  	         */
  	        CBC.Decryptor = CBC.extend({
  	            /**
  	             * Processes the data block at offset.
  	             *
  	             * @param {Array} words The data words to operate on.
  	             * @param {number} offset The offset where the block starts.
  	             *
  	             * @example
  	             *
  	             *     mode.processBlock(data.words, offset);
  	             */
  	            processBlock: function (words, offset) {
  	                // Shortcuts
  	                var cipher = this._cipher;
  	                var blockSize = cipher.blockSize;
  
  	                // Remember this block to use with next block
  	                var thisBlock = words.slice(offset, offset + blockSize);
  
  	                // Decrypt and XOR
  	                cipher.decryptBlock(words, offset);
  	                xorBlock.call(this, words, offset, blockSize);
  
  	                // This block becomes the previous block
  	                this._prevBlock = thisBlock;
  	            }
  	        });
  
  	        function xorBlock(words, offset, blockSize) {
  	            // Shortcut
  	            var iv = this._iv;
  
  	            // Choose mixing block
  	            if (iv) {
  	                var block = iv;
  
  	                // Remove IV for subsequent blocks
  	                this._iv = undefined;
  	            } else {
  	                var block = this._prevBlock;
  	            }
  
  	            // XOR blocks
  	            for (var i = 0; i < blockSize; i++) {
  	                words[offset + i] ^= block[i];
  	            }
  	        }
  
  	        return CBC;
  	    }());
  
  	    /**
  	     * Padding namespace.
  	     */
  	    var C_pad = C.pad = {};
  
  	    /**
  	     * PKCS #5/7 padding strategy.
  	     */
  	    var Pkcs7 = C_pad.Pkcs7 = {
  	        /**
  	         * Pads data using the algorithm defined in PKCS #5/7.
  	         *
  	         * @param {WordArray} data The data to pad.
  	         * @param {number} blockSize The multiple that the data should be padded to.
  	         *
  	         * @static
  	         *
  	         * @example
  	         *
  	         *     CryptoJS.pad.Pkcs7.pad(wordArray, 4);
  	         */
  	        pad: function (data, blockSize) {
  	            // Shortcut
  	            var blockSizeBytes = blockSize * 4;
  
  	            // Count padding bytes
  	            var nPaddingBytes = blockSizeBytes - data.sigBytes % blockSizeBytes;
  
  	            // Create padding word
  	            var paddingWord = (nPaddingBytes << 24) | (nPaddingBytes << 16) | (nPaddingBytes << 8) | nPaddingBytes;
  
  	            // Create padding
  	            var paddingWords = [];
  	            for (var i = 0; i < nPaddingBytes; i += 4) {
  	                paddingWords.push(paddingWord);
  	            }
  	            var padding = WordArray.create(paddingWords, nPaddingBytes);
  
  	            // Add padding
  	            data.concat(padding);
  	        },
  
  	        /**
  	         * Unpads data that had been padded using the algorithm defined in PKCS #5/7.
  	         *
  	         * @param {WordArray} data The data to unpad.
  	         *
  	         * @static
  	         *
  	         * @example
  	         *
  	         *     CryptoJS.pad.Pkcs7.unpad(wordArray);
  	         */
  	        unpad: function (data) {
  	            // Get number of padding bytes from last byte
  	            var nPaddingBytes = data.words[(data.sigBytes - 1) >>> 2] & 0xff;
  
  	            // Remove padding
  	            data.sigBytes -= nPaddingBytes;
  	        }
  	    };
  
  	    /**
  	     * Abstract base block cipher template.
  	     *
  	     * @property {number} blockSize The number of 32-bit words this cipher operates on. Default: 4 (128 bits)
  	     */
  	    var BlockCipher = C_lib.BlockCipher = Cipher.extend({
  	        /**
  	         * Configuration options.
  	         *
  	         * @property {Mode} mode The block mode to use. Default: CBC
  	         * @property {Padding} padding The padding strategy to use. Default: Pkcs7
  	         */
  	        cfg: Cipher.cfg.extend({
  	            mode: CBC,
  	            padding: Pkcs7
  	        }),
  
  	        reset: function () {
  	            // Reset cipher
  	            Cipher.reset.call(this);
  
  	            // Shortcuts
  	            var cfg = this.cfg;
  	            var iv = cfg.iv;
  	            var mode = cfg.mode;
  
  	            // Reset block mode
  	            if (this._xformMode == this._ENC_XFORM_MODE) {
  	                var modeCreator = mode.createEncryptor;
  	            } else /* if (this._xformMode == this._DEC_XFORM_MODE) */ {
  	                var modeCreator = mode.createDecryptor;
  	                // Keep at least one block in the buffer for unpadding
  	                this._minBufferSize = 1;
  	            }
  
  	            if (this._mode && this._mode.__creator == modeCreator) {
  	                this._mode.init(this, iv && iv.words);
  	            } else {
  	                this._mode = modeCreator.call(mode, this, iv && iv.words);
  	                this._mode.__creator = modeCreator;
  	            }
  	        },
  
  	        _doProcessBlock: function (words, offset) {
  	            this._mode.processBlock(words, offset);
  	        },
  
  	        _doFinalize: function () {
  	            // Shortcut
  	            var padding = this.cfg.padding;
  
  	            // Finalize
  	            if (this._xformMode == this._ENC_XFORM_MODE) {
  	                // Pad data
  	                padding.pad(this._data, this.blockSize);
  
  	                // Process final blocks
  	                var finalProcessedBlocks = this._process(!!'flush');
  	            } else /* if (this._xformMode == this._DEC_XFORM_MODE) */ {
  	                // Process final blocks
  	                var finalProcessedBlocks = this._process(!!'flush');
  
  	                // Unpad data
  	                padding.unpad(finalProcessedBlocks);
  	            }
  
  	            return finalProcessedBlocks;
  	        },
  
  	        blockSize: 128/32
  	    });
  
  	    /**
  	     * A collection of cipher parameters.
  	     *
  	     * @property {WordArray} ciphertext The raw ciphertext.
  	     * @property {WordArray} key The key to this ciphertext.
  	     * @property {WordArray} iv The IV used in the ciphering operation.
  	     * @property {WordArray} salt The salt used with a key derivation function.
  	     * @property {Cipher} algorithm The cipher algorithm.
  	     * @property {Mode} mode The block mode used in the ciphering operation.
  	     * @property {Padding} padding The padding scheme used in the ciphering operation.
  	     * @property {number} blockSize The block size of the cipher.
  	     * @property {Format} formatter The default formatting strategy to convert this cipher params object to a string.
  	     */
  	    var CipherParams = C_lib.CipherParams = Base.extend({
  	        /**
  	         * Initializes a newly created cipher params object.
  	         *
  	         * @param {Object} cipherParams An object with any of the possible cipher parameters.
  	         *
  	         * @example
  	         *
  	         *     var cipherParams = CryptoJS.lib.CipherParams.create({
  	         *         ciphertext: ciphertextWordArray,
  	         *         key: keyWordArray,
  	         *         iv: ivWordArray,
  	         *         salt: saltWordArray,
  	         *         algorithm: CryptoJS.algo.AES,
  	         *         mode: CryptoJS.mode.CBC,
  	         *         padding: CryptoJS.pad.PKCS7,
  	         *         blockSize: 4,
  	         *         formatter: CryptoJS.format.OpenSSL
  	         *     });
  	         */
  	        init: function (cipherParams) {
  	            this.mixIn(cipherParams);
  	        },
  
  	        /**
  	         * Converts this cipher params object to a string.
  	         *
  	         * @param {Format} formatter (Optional) The formatting strategy to use.
  	         *
  	         * @return {string} The stringified cipher params.
  	         *
  	         * @throws Error If neither the formatter nor the default formatter is set.
  	         *
  	         * @example
  	         *
  	         *     var string = cipherParams + '';
  	         *     var string = cipherParams.toString();
  	         *     var string = cipherParams.toString(CryptoJS.format.OpenSSL);
  	         */
  	        toString: function (formatter) {
  	            return (formatter || this.formatter).stringify(this);
  	        }
  	    });
  
  	    /**
  	     * Format namespace.
  	     */
  	    var C_format = C.format = {};
  
  	    /**
  	     * OpenSSL formatting strategy.
  	     */
  	    var OpenSSLFormatter = C_format.OpenSSL = {
  	        /**
  	         * Converts a cipher params object to an OpenSSL-compatible string.
  	         *
  	         * @param {CipherParams} cipherParams The cipher params object.
  	         *
  	         * @return {string} The OpenSSL-compatible string.
  	         *
  	         * @static
  	         *
  	         * @example
  	         *
  	         *     var openSSLString = CryptoJS.format.OpenSSL.stringify(cipherParams);
  	         */
  	        stringify: function (cipherParams) {
  	            // Shortcuts
  	            var ciphertext = cipherParams.ciphertext;
  	            var salt = cipherParams.salt;
  
  	            // Format
  	            if (salt) {
  	                var wordArray = WordArray.create([0x53616c74, 0x65645f5f]).concat(salt).concat(ciphertext);
  	            } else {
  	                var wordArray = ciphertext;
  	            }
  
  	            return wordArray.toString(Base64);
  	        },
  
  	        /**
  	         * Converts an OpenSSL-compatible string to a cipher params object.
  	         *
  	         * @param {string} openSSLStr The OpenSSL-compatible string.
  	         *
  	         * @return {CipherParams} The cipher params object.
  	         *
  	         * @static
  	         *
  	         * @example
  	         *
  	         *     var cipherParams = CryptoJS.format.OpenSSL.parse(openSSLString);
  	         */
  	        parse: function (openSSLStr) {
  	            // Parse base64
  	            var ciphertext = Base64.parse(openSSLStr);
  
  	            // Shortcut
  	            var ciphertextWords = ciphertext.words;
  
  	            // Test for salt
  	            if (ciphertextWords[0] == 0x53616c74 && ciphertextWords[1] == 0x65645f5f) {
  	                // Extract salt
  	                var salt = WordArray.create(ciphertextWords.slice(2, 4));
  
  	                // Remove salt from ciphertext
  	                ciphertextWords.splice(0, 4);
  	                ciphertext.sigBytes -= 16;
  	            }
  
  	            return CipherParams.create({ ciphertext: ciphertext, salt: salt });
  	        }
  	    };
  
  	    /**
  	     * A cipher wrapper that returns ciphertext as a serializable cipher params object.
  	     */
  	    var SerializableCipher = C_lib.SerializableCipher = Base.extend({
  	        /**
  	         * Configuration options.
  	         *
  	         * @property {Formatter} format The formatting strategy to convert cipher param objects to and from a string. Default: OpenSSL
  	         */
  	        cfg: Base.extend({
  	            format: OpenSSLFormatter
  	        }),
  
  	        /**
  	         * Encrypts a message.
  	         *
  	         * @param {Cipher} cipher The cipher algorithm to use.
  	         * @param {WordArray|string} message The message to encrypt.
  	         * @param {WordArray} key The key.
  	         * @param {Object} cfg (Optional) The configuration options to use for this operation.
  	         *
  	         * @return {CipherParams} A cipher params object.
  	         *
  	         * @static
  	         *
  	         * @example
  	         *
  	         *     var ciphertextParams = CryptoJS.lib.SerializableCipher.encrypt(CryptoJS.algo.AES, message, key);
  	         *     var ciphertextParams = CryptoJS.lib.SerializableCipher.encrypt(CryptoJS.algo.AES, message, key, { iv: iv });
  	         *     var ciphertextParams = CryptoJS.lib.SerializableCipher.encrypt(CryptoJS.algo.AES, message, key, { iv: iv, format: CryptoJS.format.OpenSSL });
  	         */
  	        encrypt: function (cipher, message, key, cfg) {
  	            // Apply config defaults
  	            cfg = this.cfg.extend(cfg);
  
  	            // Encrypt
  	            var encryptor = cipher.createEncryptor(key, cfg);
  	            var ciphertext = encryptor.finalize(message);
  
  	            // Shortcut
  	            var cipherCfg = encryptor.cfg;
  
  	            // Create and return serializable cipher params
  	            return CipherParams.create({
  	                ciphertext: ciphertext,
  	                key: key,
  	                iv: cipherCfg.iv,
  	                algorithm: cipher,
  	                mode: cipherCfg.mode,
  	                padding: cipherCfg.padding,
  	                blockSize: cipher.blockSize,
  	                formatter: cfg.format
  	            });
  	        },
  
  	        /**
  	         * Decrypts serialized ciphertext.
  	         *
  	         * @param {Cipher} cipher The cipher algorithm to use.
  	         * @param {CipherParams|string} ciphertext The ciphertext to decrypt.
  	         * @param {WordArray} key The key.
  	         * @param {Object} cfg (Optional) The configuration options to use for this operation.
  	         *
  	         * @return {WordArray} The plaintext.
  	         *
  	         * @static
  	         *
  	         * @example
  	         *
  	         *     var plaintext = CryptoJS.lib.SerializableCipher.decrypt(CryptoJS.algo.AES, formattedCiphertext, key, { iv: iv, format: CryptoJS.format.OpenSSL });
  	         *     var plaintext = CryptoJS.lib.SerializableCipher.decrypt(CryptoJS.algo.AES, ciphertextParams, key, { iv: iv, format: CryptoJS.format.OpenSSL });
  	         */
  	        decrypt: function (cipher, ciphertext, key, cfg) {
  	            // Apply config defaults
  	            cfg = this.cfg.extend(cfg);
  
  	            // Convert string to CipherParams
  	            ciphertext = this._parse(ciphertext, cfg.format);
  
  	            // Decrypt
  	            var plaintext = cipher.createDecryptor(key, cfg).finalize(ciphertext.ciphertext);
  
  	            return plaintext;
  	        },
  
  	        /**
  	         * Converts serialized ciphertext to CipherParams,
  	         * else assumed CipherParams already and returns ciphertext unchanged.
  	         *
  	         * @param {CipherParams|string} ciphertext The ciphertext.
  	         * @param {Formatter} format The formatting strategy to use to parse serialized ciphertext.
  	         *
  	         * @return {CipherParams} The unserialized ciphertext.
  	         *
  	         * @static
  	         *
  	         * @example
  	         *
  	         *     var ciphertextParams = CryptoJS.lib.SerializableCipher._parse(ciphertextStringOrParams, format);
  	         */
  	        _parse: function (ciphertext, format) {
  	            if (typeof ciphertext == 'string') {
  	                return format.parse(ciphertext, this);
  	            } else {
  	                return ciphertext;
  	            }
  	        }
  	    });
  
  	    /**
  	     * Key derivation function namespace.
  	     */
  	    var C_kdf = C.kdf = {};
  
  	    /**
  	     * OpenSSL key derivation function.
  	     */
  	    var OpenSSLKdf = C_kdf.OpenSSL = {
  	        /**
  	         * Derives a key and IV from a password.
  	         *
  	         * @param {string} password The password to derive from.
  	         * @param {number} keySize The size in words of the key to generate.
  	         * @param {number} ivSize The size in words of the IV to generate.
  	         * @param {WordArray|string} salt (Optional) A 64-bit salt to use. If omitted, a salt will be generated randomly.
  	         *
  	         * @return {CipherParams} A cipher params object with the key, IV, and salt.
  	         *
  	         * @static
  	         *
  	         * @example
  	         *
  	         *     var derivedParams = CryptoJS.kdf.OpenSSL.execute('Password', 256/32, 128/32);
  	         *     var derivedParams = CryptoJS.kdf.OpenSSL.execute('Password', 256/32, 128/32, 'saltsalt');
  	         */
  	        execute: function (password, keySize, ivSize, salt) {
  	            // Generate random salt
  	            if (!salt) {
  	                salt = WordArray.random(64/8);
  	            }
  
  	            // Derive key and IV
  	            var key = EvpKDF.create({ keySize: keySize + ivSize }).compute(password, salt);
  
  	            // Separate key and IV
  	            var iv = WordArray.create(key.words.slice(keySize), ivSize * 4);
  	            key.sigBytes = keySize * 4;
  
  	            // Return params
  	            return CipherParams.create({ key: key, iv: iv, salt: salt });
  	        }
  	    };
  
  	    /**
  	     * A serializable cipher wrapper that derives the key from a password,
  	     * and returns ciphertext as a serializable cipher params object.
  	     */
  	    var PasswordBasedCipher = C_lib.PasswordBasedCipher = SerializableCipher.extend({
  	        /**
  	         * Configuration options.
  	         *
  	         * @property {KDF} kdf The key derivation function to use to generate a key and IV from a password. Default: OpenSSL
  	         */
  	        cfg: SerializableCipher.cfg.extend({
  	            kdf: OpenSSLKdf
  	        }),
  
  	        /**
  	         * Encrypts a message using a password.
  	         *
  	         * @param {Cipher} cipher The cipher algorithm to use.
  	         * @param {WordArray|string} message The message to encrypt.
  	         * @param {string} password The password.
  	         * @param {Object} cfg (Optional) The configuration options to use for this operation.
  	         *
  	         * @return {CipherParams} A cipher params object.
  	         *
  	         * @static
  	         *
  	         * @example
  	         *
  	         *     var ciphertextParams = CryptoJS.lib.PasswordBasedCipher.encrypt(CryptoJS.algo.AES, message, 'password');
  	         *     var ciphertextParams = CryptoJS.lib.PasswordBasedCipher.encrypt(CryptoJS.algo.AES, message, 'password', { format: CryptoJS.format.OpenSSL });
  	         */
  	        encrypt: function (cipher, message, password, cfg) {
  	            // Apply config defaults
  	            cfg = this.cfg.extend(cfg);
  
  	            // Derive key and other params
  	            var derivedParams = cfg.kdf.execute(password, cipher.keySize, cipher.ivSize);
  
  	            // Add IV to config
  	            cfg.iv = derivedParams.iv;
  
  	            // Encrypt
  	            var ciphertext = SerializableCipher.encrypt.call(this, cipher, message, derivedParams.key, cfg);
  
  	            // Mix in derived params
  	            ciphertext.mixIn(derivedParams);
  
  	            return ciphertext;
  	        },
  
  	        /**
  	         * Decrypts serialized ciphertext using a password.
  	         *
  	         * @param {Cipher} cipher The cipher algorithm to use.
  	         * @param {CipherParams|string} ciphertext The ciphertext to decrypt.
  	         * @param {string} password The password.
  	         * @param {Object} cfg (Optional) The configuration options to use for this operation.
  	         *
  	         * @return {WordArray} The plaintext.
  	         *
  	         * @static
  	         *
  	         * @example
  	         *
  	         *     var plaintext = CryptoJS.lib.PasswordBasedCipher.decrypt(CryptoJS.algo.AES, formattedCiphertext, 'password', { format: CryptoJS.format.OpenSSL });
  	         *     var plaintext = CryptoJS.lib.PasswordBasedCipher.decrypt(CryptoJS.algo.AES, ciphertextParams, 'password', { format: CryptoJS.format.OpenSSL });
  	         */
  	        decrypt: function (cipher, ciphertext, password, cfg) {
  	            // Apply config defaults
  	            cfg = this.cfg.extend(cfg);
  
  	            // Convert string to CipherParams
  	            ciphertext = this._parse(ciphertext, cfg.format);
  
  	            // Derive key and other params
  	            var derivedParams = cfg.kdf.execute(password, cipher.keySize, cipher.ivSize, ciphertext.salt);
  
  	            // Add IV to config
  	            cfg.iv = derivedParams.iv;
  
  	            // Decrypt
  	            var plaintext = SerializableCipher.decrypt.call(this, cipher, ciphertext, derivedParams.key, cfg);
  
  	            return plaintext;
  	        }
  	    });
  	}());
  
  
  }));
  },{"./core":48,"./evpkdf":51}],48:[function(require,module,exports){
  ;(function (root, factory) {
  	if (typeof exports === "object") {
  		// CommonJS
  		module.exports = exports = factory();
  	}
  	else if (typeof define === "function" && define.amd) {
  		// AMD
  		define([], factory);
  	}
  	else {
  		// Global (browser)
  		root.CryptoJS = factory();
  	}
  }(this, function () {
  
  	/**
  	 * CryptoJS core components.
  	 */
  	var CryptoJS = CryptoJS || (function (Math, undefined) {
  	    /*
  	     * Local polyfil of Object.create
  	     */
  	    var create = Object.create || (function () {
  	        function F() {};
  
  	        return function (obj) {
  	            var subtype;
  
  	            F.prototype = obj;
  
  	            subtype = new F();
  
  	            F.prototype = null;
  
  	            return subtype;
  	        };
  	    }())
  
  	    /**
  	     * CryptoJS namespace.
  	     */
  	    var C = {};
  
  	    /**
  	     * Library namespace.
  	     */
  	    var C_lib = C.lib = {};
  
  	    /**
  	     * Base object for prototypal inheritance.
  	     */
  	    var Base = C_lib.Base = (function () {
  
  
  	        return {
  	            /**
  	             * Creates a new object that inherits from this object.
  	             *
  	             * @param {Object} overrides Properties to copy into the new object.
  	             *
  	             * @return {Object} The new object.
  	             *
  	             * @static
  	             *
  	             * @example
  	             *
  	             *     var MyType = CryptoJS.lib.Base.extend({
  	             *         field: 'value',
  	             *
  	             *         method: function () {
  	             *         }
  	             *     });
  	             */
  	            extend: function (overrides) {
  	                // Spawn
  	                var subtype = create(this);
  
  	                // Augment
  	                if (overrides) {
  	                    subtype.mixIn(overrides);
  	                }
  
  	                // Create default initializer
  	                if (!subtype.hasOwnProperty('init') || this.init === subtype.init) {
  	                    subtype.init = function () {
  	                        subtype.$super.init.apply(this, arguments);
  	                    };
  	                }
  
  	                // Initializer's prototype is the subtype object
  	                subtype.init.prototype = subtype;
  
  	                // Reference supertype
  	                subtype.$super = this;
  
  	                return subtype;
  	            },
  
  	            /**
  	             * Extends this object and runs the init method.
  	             * Arguments to create() will be passed to init().
  	             *
  	             * @return {Object} The new object.
  	             *
  	             * @static
  	             *
  	             * @example
  	             *
  	             *     var instance = MyType.create();
  	             */
  	            create: function () {
  	                var instance = this.extend();
  	                instance.init.apply(instance, arguments);
  
  	                return instance;
  	            },
  
  	            /**
  	             * Initializes a newly created object.
  	             * Override this method to add some logic when your objects are created.
  	             *
  	             * @example
  	             *
  	             *     var MyType = CryptoJS.lib.Base.extend({
  	             *         init: function () {
  	             *             // ...
  	             *         }
  	             *     });
  	             */
  	            init: function () {
  	            },
  
  	            /**
  	             * Copies properties into this object.
  	             *
  	             * @param {Object} properties The properties to mix in.
  	             *
  	             * @example
  	             *
  	             *     MyType.mixIn({
  	             *         field: 'value'
  	             *     });
  	             */
  	            mixIn: function (properties) {
  	                for (var propertyName in properties) {
  	                    if (properties.hasOwnProperty(propertyName)) {
  	                        this[propertyName] = properties[propertyName];
  	                    }
  	                }
  
  	                // IE won't copy toString using the loop above
  	                if (properties.hasOwnProperty('toString')) {
  	                    this.toString = properties.toString;
  	                }
  	            },
  
  	            /**
  	             * Creates a copy of this object.
  	             *
  	             * @return {Object} The clone.
  	             *
  	             * @example
  	             *
  	             *     var clone = instance.clone();
  	             */
  	            clone: function () {
  	                return this.init.prototype.extend(this);
  	            }
  	        };
  	    }());
  
  	    /**
  	     * An array of 32-bit words.
  	     *
  	     * @property {Array} words The array of 32-bit words.
  	     * @property {number} sigBytes The number of significant bytes in this word array.
  	     */
  	    var WordArray = C_lib.WordArray = Base.extend({
  	        /**
  	         * Initializes a newly created word array.
  	         *
  	         * @param {Array} words (Optional) An array of 32-bit words.
  	         * @param {number} sigBytes (Optional) The number of significant bytes in the words.
  	         *
  	         * @example
  	         *
  	         *     var wordArray = CryptoJS.lib.WordArray.create();
  	         *     var wordArray = CryptoJS.lib.WordArray.create([0x00010203, 0x04050607]);
  	         *     var wordArray = CryptoJS.lib.WordArray.create([0x00010203, 0x04050607], 6);
  	         */
  	        init: function (words, sigBytes) {
  	            words = this.words = words || [];
  
  	            if (sigBytes != undefined) {
  	                this.sigBytes = sigBytes;
  	            } else {
  	                this.sigBytes = words.length * 4;
  	            }
  	        },
  
  	        /**
  	         * Converts this word array to a string.
  	         *
  	         * @param {Encoder} encoder (Optional) The encoding strategy to use. Default: CryptoJS.enc.Hex
  	         *
  	         * @return {string} The stringified word array.
  	         *
  	         * @example
  	         *
  	         *     var string = wordArray + '';
  	         *     var string = wordArray.toString();
  	         *     var string = wordArray.toString(CryptoJS.enc.Utf8);
  	         */
  	        toString: function (encoder) {
  	            return (encoder || Hex).stringify(this);
  	        },
  
  	        /**
  	         * Concatenates a word array to this word array.
  	         *
  	         * @param {WordArray} wordArray The word array to append.
  	         *
  	         * @return {WordArray} This word array.
  	         *
  	         * @example
  	         *
  	         *     wordArray1.concat(wordArray2);
  	         */
  	        concat: function (wordArray) {
  	            // Shortcuts
  	            var thisWords = this.words;
  	            var thatWords = wordArray.words;
  	            var thisSigBytes = this.sigBytes;
  	            var thatSigBytes = wordArray.sigBytes;
  
  	            // Clamp excess bits
  	            this.clamp();
  
  	            // Concat
  	            if (thisSigBytes % 4) {
  	                // Copy one byte at a time
  	                for (var i = 0; i < thatSigBytes; i++) {
  	                    var thatByte = (thatWords[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff;
  	                    thisWords[(thisSigBytes + i) >>> 2] |= thatByte << (24 - ((thisSigBytes + i) % 4) * 8);
  	                }
  	            } else {
  	                // Copy one word at a time
  	                for (var i = 0; i < thatSigBytes; i += 4) {
  	                    thisWords[(thisSigBytes + i) >>> 2] = thatWords[i >>> 2];
  	                }
  	            }
  	            this.sigBytes += thatSigBytes;
  
  	            // Chainable
  	            return this;
  	        },
  
  	        /**
  	         * Removes insignificant bits.
  	         *
  	         * @example
  	         *
  	         *     wordArray.clamp();
  	         */
  	        clamp: function () {
  	            // Shortcuts
  	            var words = this.words;
  	            var sigBytes = this.sigBytes;
  
  	            // Clamp
  	            words[sigBytes >>> 2] &= 0xffffffff << (32 - (sigBytes % 4) * 8);
  	            words.length = Math.ceil(sigBytes / 4);
  	        },
  
  	        /**
  	         * Creates a copy of this word array.
  	         *
  	         * @return {WordArray} The clone.
  	         *
  	         * @example
  	         *
  	         *     var clone = wordArray.clone();
  	         */
  	        clone: function () {
  	            var clone = Base.clone.call(this);
  	            clone.words = this.words.slice(0);
  
  	            return clone;
  	        },
  
  	        /**
  	         * Creates a word array filled with random bytes.
  	         *
  	         * @param {number} nBytes The number of random bytes to generate.
  	         *
  	         * @return {WordArray} The random word array.
  	         *
  	         * @static
  	         *
  	         * @example
  	         *
  	         *     var wordArray = CryptoJS.lib.WordArray.random(16);
  	         */
  	        random: function (nBytes) {
  	            var words = [];
  
  	            var r = (function (m_w) {
  	                var m_w = m_w;
  	                var m_z = 0x3ade68b1;
  	                var mask = 0xffffffff;
  
  	                return function () {
  	                    m_z = (0x9069 * (m_z & 0xFFFF) + (m_z >> 0x10)) & mask;
  	                    m_w = (0x4650 * (m_w & 0xFFFF) + (m_w >> 0x10)) & mask;
  	                    var result = ((m_z << 0x10) + m_w) & mask;
  	                    result /= 0x100000000;
  	                    result += 0.5;
  	                    return result * (Math.random() > .5 ? 1 : -1);
  	                }
  	            });
  
  	            for (var i = 0, rcache; i < nBytes; i += 4) {
  	                var _r = r((rcache || Math.random()) * 0x100000000);
  
  	                rcache = _r() * 0x3ade67b7;
  	                words.push((_r() * 0x100000000) | 0);
  	            }
  
  	            return new WordArray.init(words, nBytes);
  	        }
  	    });
  
  	    /**
  	     * Encoder namespace.
  	     */
  	    var C_enc = C.enc = {};
  
  	    /**
  	     * Hex encoding strategy.
  	     */
  	    var Hex = C_enc.Hex = {
  	        /**
  	         * Converts a word array to a hex string.
  	         *
  	         * @param {WordArray} wordArray The word array.
  	         *
  	         * @return {string} The hex string.
  	         *
  	         * @static
  	         *
  	         * @example
  	         *
  	         *     var hexString = CryptoJS.enc.Hex.stringify(wordArray);
  	         */
  	        stringify: function (wordArray) {
  	            // Shortcuts
  	            var words = wordArray.words;
  	            var sigBytes = wordArray.sigBytes;
  
  	            // Convert
  	            var hexChars = [];
  	            for (var i = 0; i < sigBytes; i++) {
  	                var bite = (words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff;
  	                hexChars.push((bite >>> 4).toString(16));
  	                hexChars.push((bite & 0x0f).toString(16));
  	            }
  
  	            return hexChars.join('');
  	        },
  
  	        /**
  	         * Converts a hex string to a word array.
  	         *
  	         * @param {string} hexStr The hex string.
  	         *
  	         * @return {WordArray} The word array.
  	         *
  	         * @static
  	         *
  	         * @example
  	         *
  	         *     var wordArray = CryptoJS.enc.Hex.parse(hexString);
  	         */
  	        parse: function (hexStr) {
  	            // Shortcut
  	            var hexStrLength = hexStr.length;
  
  	            // Convert
  	            var words = [];
  	            for (var i = 0; i < hexStrLength; i += 2) {
  	                words[i >>> 3] |= parseInt(hexStr.substr(i, 2), 16) << (24 - (i % 8) * 4);
  	            }
  
  	            return new WordArray.init(words, hexStrLength / 2);
  	        }
  	    };
  
  	    /**
  	     * Latin1 encoding strategy.
  	     */
  	    var Latin1 = C_enc.Latin1 = {
  	        /**
  	         * Converts a word array to a Latin1 string.
  	         *
  	         * @param {WordArray} wordArray The word array.
  	         *
  	         * @return {string} The Latin1 string.
  	         *
  	         * @static
  	         *
  	         * @example
  	         *
  	         *     var latin1String = CryptoJS.enc.Latin1.stringify(wordArray);
  	         */
  	        stringify: function (wordArray) {
  	            // Shortcuts
  	            var words = wordArray.words;
  	            var sigBytes = wordArray.sigBytes;
  
  	            // Convert
  	            var latin1Chars = [];
  	            for (var i = 0; i < sigBytes; i++) {
  	                var bite = (words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff;
  	                latin1Chars.push(String.fromCharCode(bite));
  	            }
  
  	            return latin1Chars.join('');
  	        },
  
  	        /**
  	         * Converts a Latin1 string to a word array.
  	         *
  	         * @param {string} latin1Str The Latin1 string.
  	         *
  	         * @return {WordArray} The word array.
  	         *
  	         * @static
  	         *
  	         * @example
  	         *
  	         *     var wordArray = CryptoJS.enc.Latin1.parse(latin1String);
  	         */
  	        parse: function (latin1Str) {
  	            // Shortcut
  	            var latin1StrLength = latin1Str.length;
  
  	            // Convert
  	            var words = [];
  	            for (var i = 0; i < latin1StrLength; i++) {
  	                words[i >>> 2] |= (latin1Str.charCodeAt(i) & 0xff) << (24 - (i % 4) * 8);
  	            }
  
  	            return new WordArray.init(words, latin1StrLength);
  	        }
  	    };
  
  	    /**
  	     * UTF-8 encoding strategy.
  	     */
  	    var Utf8 = C_enc.Utf8 = {
  	        /**
  	         * Converts a word array to a UTF-8 string.
  	         *
  	         * @param {WordArray} wordArray The word array.
  	         *
  	         * @return {string} The UTF-8 string.
  	         *
  	         * @static
  	         *
  	         * @example
  	         *
  	         *     var utf8String = CryptoJS.enc.Utf8.stringify(wordArray);
  	         */
  	        stringify: function (wordArray) {
  	            try {
  	                return decodeURIComponent(escape(Latin1.stringify(wordArray)));
  	            } catch (e) {
  	                throw new Error('Malformed UTF-8 data');
  	            }
  	        },
  
  	        /**
  	         * Converts a UTF-8 string to a word array.
  	         *
  	         * @param {string} utf8Str The UTF-8 string.
  	         *
  	         * @return {WordArray} The word array.
  	         *
  	         * @static
  	         *
  	         * @example
  	         *
  	         *     var wordArray = CryptoJS.enc.Utf8.parse(utf8String);
  	         */
  	        parse: function (utf8Str) {
  	            return Latin1.parse(unescape(encodeURIComponent(utf8Str)));
  	        }
  	    };
  
  	    /**
  	     * Abstract buffered block algorithm template.
  	     *
  	     * The property blockSize must be implemented in a concrete subtype.
  	     *
  	     * @property {number} _minBufferSize The number of blocks that should be kept unprocessed in the buffer. Default: 0
  	     */
  	    var BufferedBlockAlgorithm = C_lib.BufferedBlockAlgorithm = Base.extend({
  	        /**
  	         * Resets this block algorithm's data buffer to its initial state.
  	         *
  	         * @example
  	         *
  	         *     bufferedBlockAlgorithm.reset();
  	         */
  	        reset: function () {
  	            // Initial values
  	            this._data = new WordArray.init();
  	            this._nDataBytes = 0;
  	        },
  
  	        /**
  	         * Adds new data to this block algorithm's buffer.
  	         *
  	         * @param {WordArray|string} data The data to append. Strings are converted to a WordArray using UTF-8.
  	         *
  	         * @example
  	         *
  	         *     bufferedBlockAlgorithm._append('data');
  	         *     bufferedBlockAlgorithm._append(wordArray);
  	         */
  	        _append: function (data) {
  	            // Convert string to WordArray, else assume WordArray already
  	            if (typeof data == 'string') {
  	                data = Utf8.parse(data);
  	            }
  
  	            // Append
  	            this._data.concat(data);
  	            this._nDataBytes += data.sigBytes;
  	        },
  
  	        /**
  	         * Processes available data blocks.
  	         *
  	         * This method invokes _doProcessBlock(offset), which must be implemented by a concrete subtype.
  	         *
  	         * @param {boolean} doFlush Whether all blocks and partial blocks should be processed.
  	         *
  	         * @return {WordArray} The processed data.
  	         *
  	         * @example
  	         *
  	         *     var processedData = bufferedBlockAlgorithm._process();
  	         *     var processedData = bufferedBlockAlgorithm._process(!!'flush');
  	         */
  	        _process: function (doFlush) {
  	            // Shortcuts
  	            var data = this._data;
  	            var dataWords = data.words;
  	            var dataSigBytes = data.sigBytes;
  	            var blockSize = this.blockSize;
  	            var blockSizeBytes = blockSize * 4;
  
  	            // Count blocks ready
  	            var nBlocksReady = dataSigBytes / blockSizeBytes;
  	            if (doFlush) {
  	                // Round up to include partial blocks
  	                nBlocksReady = Math.ceil(nBlocksReady);
  	            } else {
  	                // Round down to include only full blocks,
  	                // less the number of blocks that must remain in the buffer
  	                nBlocksReady = Math.max((nBlocksReady | 0) - this._minBufferSize, 0);
  	            }
  
  	            // Count words ready
  	            var nWordsReady = nBlocksReady * blockSize;
  
  	            // Count bytes ready
  	            var nBytesReady = Math.min(nWordsReady * 4, dataSigBytes);
  
  	            // Process blocks
  	            if (nWordsReady) {
  	                for (var offset = 0; offset < nWordsReady; offset += blockSize) {
  	                    // Perform concrete-algorithm logic
  	                    this._doProcessBlock(dataWords, offset);
  	                }
  
  	                // Remove processed words
  	                var processedWords = dataWords.splice(0, nWordsReady);
  	                data.sigBytes -= nBytesReady;
  	            }
  
  	            // Return processed words
  	            return new WordArray.init(processedWords, nBytesReady);
  	        },
  
  	        /**
  	         * Creates a copy of this object.
  	         *
  	         * @return {Object} The clone.
  	         *
  	         * @example
  	         *
  	         *     var clone = bufferedBlockAlgorithm.clone();
  	         */
  	        clone: function () {
  	            var clone = Base.clone.call(this);
  	            clone._data = this._data.clone();
  
  	            return clone;
  	        },
  
  	        _minBufferSize: 0
  	    });
  
  	    /**
  	     * Abstract hasher template.
  	     *
  	     * @property {number} blockSize The number of 32-bit words this hasher operates on. Default: 16 (512 bits)
  	     */
  	    var Hasher = C_lib.Hasher = BufferedBlockAlgorithm.extend({
  	        /**
  	         * Configuration options.
  	         */
  	        cfg: Base.extend(),
  
  	        /**
  	         * Initializes a newly created hasher.
  	         *
  	         * @param {Object} cfg (Optional) The configuration options to use for this hash computation.
  	         *
  	         * @example
  	         *
  	         *     var hasher = CryptoJS.algo.SHA256.create();
  	         */
  	        init: function (cfg) {
  	            // Apply config defaults
  	            this.cfg = this.cfg.extend(cfg);
  
  	            // Set initial values
  	            this.reset();
  	        },
  
  	        /**
  	         * Resets this hasher to its initial state.
  	         *
  	         * @example
  	         *
  	         *     hasher.reset();
  	         */
  	        reset: function () {
  	            // Reset data buffer
  	            BufferedBlockAlgorithm.reset.call(this);
  
  	            // Perform concrete-hasher logic
  	            this._doReset();
  	        },
  
  	        /**
  	         * Updates this hasher with a message.
  	         *
  	         * @param {WordArray|string} messageUpdate The message to append.
  	         *
  	         * @return {Hasher} This hasher.
  	         *
  	         * @example
  	         *
  	         *     hasher.update('message');
  	         *     hasher.update(wordArray);
  	         */
  	        update: function (messageUpdate) {
  	            // Append
  	            this._append(messageUpdate);
  
  	            // Update the hash
  	            this._process();
  
  	            // Chainable
  	            return this;
  	        },
  
  	        /**
  	         * Finalizes the hash computation.
  	         * Note that the finalize operation is effectively a destructive, read-once operation.
  	         *
  	         * @param {WordArray|string} messageUpdate (Optional) A final message update.
  	         *
  	         * @return {WordArray} The hash.
  	         *
  	         * @example
  	         *
  	         *     var hash = hasher.finalize();
  	         *     var hash = hasher.finalize('message');
  	         *     var hash = hasher.finalize(wordArray);
  	         */
  	        finalize: function (messageUpdate) {
  	            // Final message update
  	            if (messageUpdate) {
  	                this._append(messageUpdate);
  	            }
  
  	            // Perform concrete-hasher logic
  	            var hash = this._doFinalize();
  
  	            return hash;
  	        },
  
  	        blockSize: 512/32,
  
  	        /**
  	         * Creates a shortcut function to a hasher's object interface.
  	         *
  	         * @param {Hasher} hasher The hasher to create a helper for.
  	         *
  	         * @return {Function} The shortcut function.
  	         *
  	         * @static
  	         *
  	         * @example
  	         *
  	         *     var SHA256 = CryptoJS.lib.Hasher._createHelper(CryptoJS.algo.SHA256);
  	         */
  	        _createHelper: function (hasher) {
  	            return function (message, cfg) {
  	                return new hasher.init(cfg).finalize(message);
  	            };
  	        },
  
  	        /**
  	         * Creates a shortcut function to the HMAC's object interface.
  	         *
  	         * @param {Hasher} hasher The hasher to use in this HMAC helper.
  	         *
  	         * @return {Function} The shortcut function.
  	         *
  	         * @static
  	         *
  	         * @example
  	         *
  	         *     var HmacSHA256 = CryptoJS.lib.Hasher._createHmacHelper(CryptoJS.algo.SHA256);
  	         */
  	        _createHmacHelper: function (hasher) {
  	            return function (message, key) {
  	                return new C_algo.HMAC.init(hasher, key).finalize(message);
  	            };
  	        }
  	    });
  
  	    /**
  	     * Algorithm namespace.
  	     */
  	    var C_algo = C.algo = {};
  
  	    return C;
  	}(Math));
  
  
  	return CryptoJS;
  
  }));
  },{}],49:[function(require,module,exports){
  ;(function (root, factory) {
  	if (typeof exports === "object") {
  		// CommonJS
  		module.exports = exports = factory(require("./core"));
  	}
  	else if (typeof define === "function" && define.amd) {
  		// AMD
  		define(["./core"], factory);
  	}
  	else {
  		// Global (browser)
  		factory(root.CryptoJS);
  	}
  }(this, function (CryptoJS) {
  
  	(function () {
  	    // Shortcuts
  	    var C = CryptoJS;
  	    var C_lib = C.lib;
  	    var WordArray = C_lib.WordArray;
  	    var C_enc = C.enc;
  
  	    /**
  	     * Base64 encoding strategy.
  	     */
  	    var Base64 = C_enc.Base64 = {
  	        /**
  	         * Converts a word array to a Base64 string.
  	         *
  	         * @param {WordArray} wordArray The word array.
  	         *
  	         * @return {string} The Base64 string.
  	         *
  	         * @static
  	         *
  	         * @example
  	         *
  	         *     var base64String = CryptoJS.enc.Base64.stringify(wordArray);
  	         */
  	        stringify: function (wordArray) {
  	            // Shortcuts
  	            var words = wordArray.words;
  	            var sigBytes = wordArray.sigBytes;
  	            var map = this._map;
  
  	            // Clamp excess bits
  	            wordArray.clamp();
  
  	            // Convert
  	            var base64Chars = [];
  	            for (var i = 0; i < sigBytes; i += 3) {
  	                var byte1 = (words[i >>> 2]       >>> (24 - (i % 4) * 8))       & 0xff;
  	                var byte2 = (words[(i + 1) >>> 2] >>> (24 - ((i + 1) % 4) * 8)) & 0xff;
  	                var byte3 = (words[(i + 2) >>> 2] >>> (24 - ((i + 2) % 4) * 8)) & 0xff;
  
  	                var triplet = (byte1 << 16) | (byte2 << 8) | byte3;
  
  	                for (var j = 0; (j < 4) && (i + j * 0.75 < sigBytes); j++) {
  	                    base64Chars.push(map.charAt((triplet >>> (6 * (3 - j))) & 0x3f));
  	                }
  	            }
  
  	            // Add padding
  	            var paddingChar = map.charAt(64);
  	            if (paddingChar) {
  	                while (base64Chars.length % 4) {
  	                    base64Chars.push(paddingChar);
  	                }
  	            }
  
  	            return base64Chars.join('');
  	        },
  
  	        /**
  	         * Converts a Base64 string to a word array.
  	         *
  	         * @param {string} base64Str The Base64 string.
  	         *
  	         * @return {WordArray} The word array.
  	         *
  	         * @static
  	         *
  	         * @example
  	         *
  	         *     var wordArray = CryptoJS.enc.Base64.parse(base64String);
  	         */
  	        parse: function (base64Str) {
  	            // Shortcuts
  	            var base64StrLength = base64Str.length;
  	            var map = this._map;
  	            var reverseMap = this._reverseMap;
  
  	            if (!reverseMap) {
  	                    reverseMap = this._reverseMap = [];
  	                    for (var j = 0; j < map.length; j++) {
  	                        reverseMap[map.charCodeAt(j)] = j;
  	                    }
  	            }
  
  	            // Ignore padding
  	            var paddingChar = map.charAt(64);
  	            if (paddingChar) {
  	                var paddingIndex = base64Str.indexOf(paddingChar);
  	                if (paddingIndex !== -1) {
  	                    base64StrLength = paddingIndex;
  	                }
  	            }
  
  	            // Convert
  	            return parseLoop(base64Str, base64StrLength, reverseMap);
  
  	        },
  
  	        _map: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='
  	    };
  
  	    function parseLoop(base64Str, base64StrLength, reverseMap) {
  	      var words = [];
  	      var nBytes = 0;
  	      for (var i = 0; i < base64StrLength; i++) {
  	          if (i % 4) {
  	              var bits1 = reverseMap[base64Str.charCodeAt(i - 1)] << ((i % 4) * 2);
  	              var bits2 = reverseMap[base64Str.charCodeAt(i)] >>> (6 - (i % 4) * 2);
  	              words[nBytes >>> 2] |= (bits1 | bits2) << (24 - (nBytes % 4) * 8);
  	              nBytes++;
  	          }
  	      }
  	      return WordArray.create(words, nBytes);
  	    }
  	}());
  
  
  	return CryptoJS.enc.Base64;
  
  }));
  },{"./core":48}],50:[function(require,module,exports){
  ;(function (root, factory) {
  	if (typeof exports === "object") {
  		// CommonJS
  		module.exports = exports = factory(require("./core"));
  	}
  	else if (typeof define === "function" && define.amd) {
  		// AMD
  		define(["./core"], factory);
  	}
  	else {
  		// Global (browser)
  		factory(root.CryptoJS);
  	}
  }(this, function (CryptoJS) {
  
  	return CryptoJS.enc.Hex;
  
  }));
  },{"./core":48}],51:[function(require,module,exports){
  ;(function (root, factory, undef) {
  	if (typeof exports === "object") {
  		// CommonJS
  		module.exports = exports = factory(require("./core"), require("./sha1"), require("./hmac"));
  	}
  	else if (typeof define === "function" && define.amd) {
  		// AMD
  		define(["./core", "./sha1", "./hmac"], factory);
  	}
  	else {
  		// Global (browser)
  		factory(root.CryptoJS);
  	}
  }(this, function (CryptoJS) {
  
  	(function () {
  	    // Shortcuts
  	    var C = CryptoJS;
  	    var C_lib = C.lib;
  	    var Base = C_lib.Base;
  	    var WordArray = C_lib.WordArray;
  	    var C_algo = C.algo;
  	    var MD5 = C_algo.MD5;
  
  	    /**
  	     * This key derivation function is meant to conform with EVP_BytesToKey.
  	     * www.openssl.org/docs/crypto/EVP_BytesToKey.html
  	     */
  	    var EvpKDF = C_algo.EvpKDF = Base.extend({
  	        /**
  	         * Configuration options.
  	         *
  	         * @property {number} keySize The key size in words to generate. Default: 4 (128 bits)
  	         * @property {Hasher} hasher The hash algorithm to use. Default: MD5
  	         * @property {number} iterations The number of iterations to perform. Default: 1
  	         */
  	        cfg: Base.extend({
  	            keySize: 128/32,
  	            hasher: MD5,
  	            iterations: 1
  	        }),
  
  	        /**
  	         * Initializes a newly created key derivation function.
  	         *
  	         * @param {Object} cfg (Optional) The configuration options to use for the derivation.
  	         *
  	         * @example
  	         *
  	         *     var kdf = CryptoJS.algo.EvpKDF.create();
  	         *     var kdf = CryptoJS.algo.EvpKDF.create({ keySize: 8 });
  	         *     var kdf = CryptoJS.algo.EvpKDF.create({ keySize: 8, iterations: 1000 });
  	         */
  	        init: function (cfg) {
  	            this.cfg = this.cfg.extend(cfg);
  	        },
  
  	        /**
  	         * Derives a key from a password.
  	         *
  	         * @param {WordArray|string} password The password.
  	         * @param {WordArray|string} salt A salt.
  	         *
  	         * @return {WordArray} The derived key.
  	         *
  	         * @example
  	         *
  	         *     var key = kdf.compute(password, salt);
  	         */
  	        compute: function (password, salt) {
  	            // Shortcut
  	            var cfg = this.cfg;
  
  	            // Init hasher
  	            var hasher = cfg.hasher.create();
  
  	            // Initial values
  	            var derivedKey = WordArray.create();
  
  	            // Shortcuts
  	            var derivedKeyWords = derivedKey.words;
  	            var keySize = cfg.keySize;
  	            var iterations = cfg.iterations;
  
  	            // Generate key
  	            while (derivedKeyWords.length < keySize) {
  	                if (block) {
  	                    hasher.update(block);
  	                }
  	                var block = hasher.update(password).finalize(salt);
  	                hasher.reset();
  
  	                // Iterations
  	                for (var i = 1; i < iterations; i++) {
  	                    block = hasher.finalize(block);
  	                    hasher.reset();
  	                }
  
  	                derivedKey.concat(block);
  	            }
  	            derivedKey.sigBytes = keySize * 4;
  
  	            return derivedKey;
  	        }
  	    });
  
  	    /**
  	     * Derives a key from a password.
  	     *
  	     * @param {WordArray|string} password The password.
  	     * @param {WordArray|string} salt A salt.
  	     * @param {Object} cfg (Optional) The configuration options to use for this computation.
  	     *
  	     * @return {WordArray} The derived key.
  	     *
  	     * @static
  	     *
  	     * @example
  	     *
  	     *     var key = CryptoJS.EvpKDF(password, salt);
  	     *     var key = CryptoJS.EvpKDF(password, salt, { keySize: 8 });
  	     *     var key = CryptoJS.EvpKDF(password, salt, { keySize: 8, iterations: 1000 });
  	     */
  	    C.EvpKDF = function (password, salt, cfg) {
  	        return EvpKDF.create(cfg).compute(password, salt);
  	    };
  	}());
  
  
  	return CryptoJS.EvpKDF;
  
  }));
  },{"./core":48,"./hmac":52,"./sha1":54}],52:[function(require,module,exports){
  ;(function (root, factory) {
  	if (typeof exports === "object") {
  		// CommonJS
  		module.exports = exports = factory(require("./core"));
  	}
  	else if (typeof define === "function" && define.amd) {
  		// AMD
  		define(["./core"], factory);
  	}
  	else {
  		// Global (browser)
  		factory(root.CryptoJS);
  	}
  }(this, function (CryptoJS) {
  
  	(function () {
  	    // Shortcuts
  	    var C = CryptoJS;
  	    var C_lib = C.lib;
  	    var Base = C_lib.Base;
  	    var C_enc = C.enc;
  	    var Utf8 = C_enc.Utf8;
  	    var C_algo = C.algo;
  
  	    /**
  	     * HMAC algorithm.
  	     */
  	    var HMAC = C_algo.HMAC = Base.extend({
  	        /**
  	         * Initializes a newly created HMAC.
  	         *
  	         * @param {Hasher} hasher The hash algorithm to use.
  	         * @param {WordArray|string} key The secret key.
  	         *
  	         * @example
  	         *
  	         *     var hmacHasher = CryptoJS.algo.HMAC.create(CryptoJS.algo.SHA256, key);
  	         */
  	        init: function (hasher, key) {
  	            // Init hasher
  	            hasher = this._hasher = new hasher.init();
  
  	            // Convert string to WordArray, else assume WordArray already
  	            if (typeof key == 'string') {
  	                key = Utf8.parse(key);
  	            }
  
  	            // Shortcuts
  	            var hasherBlockSize = hasher.blockSize;
  	            var hasherBlockSizeBytes = hasherBlockSize * 4;
  
  	            // Allow arbitrary length keys
  	            if (key.sigBytes > hasherBlockSizeBytes) {
  	                key = hasher.finalize(key);
  	            }
  
  	            // Clamp excess bits
  	            key.clamp();
  
  	            // Clone key for inner and outer pads
  	            var oKey = this._oKey = key.clone();
  	            var iKey = this._iKey = key.clone();
  
  	            // Shortcuts
  	            var oKeyWords = oKey.words;
  	            var iKeyWords = iKey.words;
  
  	            // XOR keys with pad constants
  	            for (var i = 0; i < hasherBlockSize; i++) {
  	                oKeyWords[i] ^= 0x5c5c5c5c;
  	                iKeyWords[i] ^= 0x36363636;
  	            }
  	            oKey.sigBytes = iKey.sigBytes = hasherBlockSizeBytes;
  
  	            // Set initial values
  	            this.reset();
  	        },
  
  	        /**
  	         * Resets this HMAC to its initial state.
  	         *
  	         * @example
  	         *
  	         *     hmacHasher.reset();
  	         */
  	        reset: function () {
  	            // Shortcut
  	            var hasher = this._hasher;
  
  	            // Reset
  	            hasher.reset();
  	            hasher.update(this._iKey);
  	        },
  
  	        /**
  	         * Updates this HMAC with a message.
  	         *
  	         * @param {WordArray|string} messageUpdate The message to append.
  	         *
  	         * @return {HMAC} This HMAC instance.
  	         *
  	         * @example
  	         *
  	         *     hmacHasher.update('message');
  	         *     hmacHasher.update(wordArray);
  	         */
  	        update: function (messageUpdate) {
  	            this._hasher.update(messageUpdate);
  
  	            // Chainable
  	            return this;
  	        },
  
  	        /**
  	         * Finalizes the HMAC computation.
  	         * Note that the finalize operation is effectively a destructive, read-once operation.
  	         *
  	         * @param {WordArray|string} messageUpdate (Optional) A final message update.
  	         *
  	         * @return {WordArray} The HMAC.
  	         *
  	         * @example
  	         *
  	         *     var hmac = hmacHasher.finalize();
  	         *     var hmac = hmacHasher.finalize('message');
  	         *     var hmac = hmacHasher.finalize(wordArray);
  	         */
  	        finalize: function (messageUpdate) {
  	            // Shortcut
  	            var hasher = this._hasher;
  
  	            // Compute HMAC
  	            var innerHash = hasher.finalize(messageUpdate);
  	            hasher.reset();
  	            var hmac = hasher.finalize(this._oKey.clone().concat(innerHash));
  
  	            return hmac;
  	        }
  	    });
  	}());
  
  
  }));
  },{"./core":48}],53:[function(require,module,exports){
  ;(function (root, factory) {
  	if (typeof exports === "object") {
  		// CommonJS
  		module.exports = exports = factory(require("./core"));
  	}
  	else if (typeof define === "function" && define.amd) {
  		// AMD
  		define(["./core"], factory);
  	}
  	else {
  		// Global (browser)
  		factory(root.CryptoJS);
  	}
  }(this, function (CryptoJS) {
  
  	(function (Math) {
  	    // Shortcuts
  	    var C = CryptoJS;
  	    var C_lib = C.lib;
  	    var WordArray = C_lib.WordArray;
  	    var Hasher = C_lib.Hasher;
  	    var C_algo = C.algo;
  
  	    // Constants table
  	    var T = [];
  
  	    // Compute constants
  	    (function () {
  	        for (var i = 0; i < 64; i++) {
  	            T[i] = (Math.abs(Math.sin(i + 1)) * 0x100000000) | 0;
  	        }
  	    }());
  
  	    /**
  	     * MD5 hash algorithm.
  	     */
  	    var MD5 = C_algo.MD5 = Hasher.extend({
  	        _doReset: function () {
  	            this._hash = new WordArray.init([
  	                0x67452301, 0xefcdab89,
  	                0x98badcfe, 0x10325476
  	            ]);
  	        },
  
  	        _doProcessBlock: function (M, offset) {
  	            // Swap endian
  	            for (var i = 0; i < 16; i++) {
  	                // Shortcuts
  	                var offset_i = offset + i;
  	                var M_offset_i = M[offset_i];
  
  	                M[offset_i] = (
  	                    (((M_offset_i << 8)  | (M_offset_i >>> 24)) & 0x00ff00ff) |
  	                    (((M_offset_i << 24) | (M_offset_i >>> 8))  & 0xff00ff00)
  	                );
  	            }
  
  	            // Shortcuts
  	            var H = this._hash.words;
  
  	            var M_offset_0  = M[offset + 0];
  	            var M_offset_1  = M[offset + 1];
  	            var M_offset_2  = M[offset + 2];
  	            var M_offset_3  = M[offset + 3];
  	            var M_offset_4  = M[offset + 4];
  	            var M_offset_5  = M[offset + 5];
  	            var M_offset_6  = M[offset + 6];
  	            var M_offset_7  = M[offset + 7];
  	            var M_offset_8  = M[offset + 8];
  	            var M_offset_9  = M[offset + 9];
  	            var M_offset_10 = M[offset + 10];
  	            var M_offset_11 = M[offset + 11];
  	            var M_offset_12 = M[offset + 12];
  	            var M_offset_13 = M[offset + 13];
  	            var M_offset_14 = M[offset + 14];
  	            var M_offset_15 = M[offset + 15];
  
  	            // Working varialbes
  	            var a = H[0];
  	            var b = H[1];
  	            var c = H[2];
  	            var d = H[3];
  
  	            // Computation
  	            a = FF(a, b, c, d, M_offset_0,  7,  T[0]);
  	            d = FF(d, a, b, c, M_offset_1,  12, T[1]);
  	            c = FF(c, d, a, b, M_offset_2,  17, T[2]);
  	            b = FF(b, c, d, a, M_offset_3,  22, T[3]);
  	            a = FF(a, b, c, d, M_offset_4,  7,  T[4]);
  	            d = FF(d, a, b, c, M_offset_5,  12, T[5]);
  	            c = FF(c, d, a, b, M_offset_6,  17, T[6]);
  	            b = FF(b, c, d, a, M_offset_7,  22, T[7]);
  	            a = FF(a, b, c, d, M_offset_8,  7,  T[8]);
  	            d = FF(d, a, b, c, M_offset_9,  12, T[9]);
  	            c = FF(c, d, a, b, M_offset_10, 17, T[10]);
  	            b = FF(b, c, d, a, M_offset_11, 22, T[11]);
  	            a = FF(a, b, c, d, M_offset_12, 7,  T[12]);
  	            d = FF(d, a, b, c, M_offset_13, 12, T[13]);
  	            c = FF(c, d, a, b, M_offset_14, 17, T[14]);
  	            b = FF(b, c, d, a, M_offset_15, 22, T[15]);
  
  	            a = GG(a, b, c, d, M_offset_1,  5,  T[16]);
  	            d = GG(d, a, b, c, M_offset_6,  9,  T[17]);
  	            c = GG(c, d, a, b, M_offset_11, 14, T[18]);
  	            b = GG(b, c, d, a, M_offset_0,  20, T[19]);
  	            a = GG(a, b, c, d, M_offset_5,  5,  T[20]);
  	            d = GG(d, a, b, c, M_offset_10, 9,  T[21]);
  	            c = GG(c, d, a, b, M_offset_15, 14, T[22]);
  	            b = GG(b, c, d, a, M_offset_4,  20, T[23]);
  	            a = GG(a, b, c, d, M_offset_9,  5,  T[24]);
  	            d = GG(d, a, b, c, M_offset_14, 9,  T[25]);
  	            c = GG(c, d, a, b, M_offset_3,  14, T[26]);
  	            b = GG(b, c, d, a, M_offset_8,  20, T[27]);
  	            a = GG(a, b, c, d, M_offset_13, 5,  T[28]);
  	            d = GG(d, a, b, c, M_offset_2,  9,  T[29]);
  	            c = GG(c, d, a, b, M_offset_7,  14, T[30]);
  	            b = GG(b, c, d, a, M_offset_12, 20, T[31]);
  
  	            a = HH(a, b, c, d, M_offset_5,  4,  T[32]);
  	            d = HH(d, a, b, c, M_offset_8,  11, T[33]);
  	            c = HH(c, d, a, b, M_offset_11, 16, T[34]);
  	            b = HH(b, c, d, a, M_offset_14, 23, T[35]);
  	            a = HH(a, b, c, d, M_offset_1,  4,  T[36]);
  	            d = HH(d, a, b, c, M_offset_4,  11, T[37]);
  	            c = HH(c, d, a, b, M_offset_7,  16, T[38]);
  	            b = HH(b, c, d, a, M_offset_10, 23, T[39]);
  	            a = HH(a, b, c, d, M_offset_13, 4,  T[40]);
  	            d = HH(d, a, b, c, M_offset_0,  11, T[41]);
  	            c = HH(c, d, a, b, M_offset_3,  16, T[42]);
  	            b = HH(b, c, d, a, M_offset_6,  23, T[43]);
  	            a = HH(a, b, c, d, M_offset_9,  4,  T[44]);
  	            d = HH(d, a, b, c, M_offset_12, 11, T[45]);
  	            c = HH(c, d, a, b, M_offset_15, 16, T[46]);
  	            b = HH(b, c, d, a, M_offset_2,  23, T[47]);
  
  	            a = II(a, b, c, d, M_offset_0,  6,  T[48]);
  	            d = II(d, a, b, c, M_offset_7,  10, T[49]);
  	            c = II(c, d, a, b, M_offset_14, 15, T[50]);
  	            b = II(b, c, d, a, M_offset_5,  21, T[51]);
  	            a = II(a, b, c, d, M_offset_12, 6,  T[52]);
  	            d = II(d, a, b, c, M_offset_3,  10, T[53]);
  	            c = II(c, d, a, b, M_offset_10, 15, T[54]);
  	            b = II(b, c, d, a, M_offset_1,  21, T[55]);
  	            a = II(a, b, c, d, M_offset_8,  6,  T[56]);
  	            d = II(d, a, b, c, M_offset_15, 10, T[57]);
  	            c = II(c, d, a, b, M_offset_6,  15, T[58]);
  	            b = II(b, c, d, a, M_offset_13, 21, T[59]);
  	            a = II(a, b, c, d, M_offset_4,  6,  T[60]);
  	            d = II(d, a, b, c, M_offset_11, 10, T[61]);
  	            c = II(c, d, a, b, M_offset_2,  15, T[62]);
  	            b = II(b, c, d, a, M_offset_9,  21, T[63]);
  
  	            // Intermediate hash value
  	            H[0] = (H[0] + a) | 0;
  	            H[1] = (H[1] + b) | 0;
  	            H[2] = (H[2] + c) | 0;
  	            H[3] = (H[3] + d) | 0;
  	        },
  
  	        _doFinalize: function () {
  	            // Shortcuts
  	            var data = this._data;
  	            var dataWords = data.words;
  
  	            var nBitsTotal = this._nDataBytes * 8;
  	            var nBitsLeft = data.sigBytes * 8;
  
  	            // Add padding
  	            dataWords[nBitsLeft >>> 5] |= 0x80 << (24 - nBitsLeft % 32);
  
  	            var nBitsTotalH = Math.floor(nBitsTotal / 0x100000000);
  	            var nBitsTotalL = nBitsTotal;
  	            dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 15] = (
  	                (((nBitsTotalH << 8)  | (nBitsTotalH >>> 24)) & 0x00ff00ff) |
  	                (((nBitsTotalH << 24) | (nBitsTotalH >>> 8))  & 0xff00ff00)
  	            );
  	            dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 14] = (
  	                (((nBitsTotalL << 8)  | (nBitsTotalL >>> 24)) & 0x00ff00ff) |
  	                (((nBitsTotalL << 24) | (nBitsTotalL >>> 8))  & 0xff00ff00)
  	            );
  
  	            data.sigBytes = (dataWords.length + 1) * 4;
  
  	            // Hash final blocks
  	            this._process();
  
  	            // Shortcuts
  	            var hash = this._hash;
  	            var H = hash.words;
  
  	            // Swap endian
  	            for (var i = 0; i < 4; i++) {
  	                // Shortcut
  	                var H_i = H[i];
  
  	                H[i] = (((H_i << 8)  | (H_i >>> 24)) & 0x00ff00ff) |
  	                       (((H_i << 24) | (H_i >>> 8))  & 0xff00ff00);
  	            }
  
  	            // Return final computed hash
  	            return hash;
  	        },
  
  	        clone: function () {
  	            var clone = Hasher.clone.call(this);
  	            clone._hash = this._hash.clone();
  
  	            return clone;
  	        }
  	    });
  
  	    function FF(a, b, c, d, x, s, t) {
  	        var n = a + ((b & c) | (~b & d)) + x + t;
  	        return ((n << s) | (n >>> (32 - s))) + b;
  	    }
  
  	    function GG(a, b, c, d, x, s, t) {
  	        var n = a + ((b & d) | (c & ~d)) + x + t;
  	        return ((n << s) | (n >>> (32 - s))) + b;
  	    }
  
  	    function HH(a, b, c, d, x, s, t) {
  	        var n = a + (b ^ c ^ d) + x + t;
  	        return ((n << s) | (n >>> (32 - s))) + b;
  	    }
  
  	    function II(a, b, c, d, x, s, t) {
  	        var n = a + (c ^ (b | ~d)) + x + t;
  	        return ((n << s) | (n >>> (32 - s))) + b;
  	    }
  
  	    /**
  	     * Shortcut function to the hasher's object interface.
  	     *
  	     * @param {WordArray|string} message The message to hash.
  	     *
  	     * @return {WordArray} The hash.
  	     *
  	     * @static
  	     *
  	     * @example
  	     *
  	     *     var hash = CryptoJS.MD5('message');
  	     *     var hash = CryptoJS.MD5(wordArray);
  	     */
  	    C.MD5 = Hasher._createHelper(MD5);
  
  	    /**
  	     * Shortcut function to the HMAC's object interface.
  	     *
  	     * @param {WordArray|string} message The message to hash.
  	     * @param {WordArray|string} key The secret key.
  	     *
  	     * @return {WordArray} The HMAC.
  	     *
  	     * @static
  	     *
  	     * @example
  	     *
  	     *     var hmac = CryptoJS.HmacMD5(message, key);
  	     */
  	    C.HmacMD5 = Hasher._createHmacHelper(MD5);
  	}(Math));
  
  
  	return CryptoJS.MD5;
  
  }));
  },{"./core":48}],54:[function(require,module,exports){
  ;(function (root, factory) {
  	if (typeof exports === "object") {
  		// CommonJS
  		module.exports = exports = factory(require("./core"));
  	}
  	else if (typeof define === "function" && define.amd) {
  		// AMD
  		define(["./core"], factory);
  	}
  	else {
  		// Global (browser)
  		factory(root.CryptoJS);
  	}
  }(this, function (CryptoJS) {
  
  	(function () {
  	    // Shortcuts
  	    var C = CryptoJS;
  	    var C_lib = C.lib;
  	    var WordArray = C_lib.WordArray;
  	    var Hasher = C_lib.Hasher;
  	    var C_algo = C.algo;
  
  	    // Reusable object
  	    var W = [];
  
  	    /**
  	     * SHA-1 hash algorithm.
  	     */
  	    var SHA1 = C_algo.SHA1 = Hasher.extend({
  	        _doReset: function () {
  	            this._hash = new WordArray.init([
  	                0x67452301, 0xefcdab89,
  	                0x98badcfe, 0x10325476,
  	                0xc3d2e1f0
  	            ]);
  	        },
  
  	        _doProcessBlock: function (M, offset) {
  	            // Shortcut
  	            var H = this._hash.words;
  
  	            // Working variables
  	            var a = H[0];
  	            var b = H[1];
  	            var c = H[2];
  	            var d = H[3];
  	            var e = H[4];
  
  	            // Computation
  	            for (var i = 0; i < 80; i++) {
  	                if (i < 16) {
  	                    W[i] = M[offset + i] | 0;
  	                } else {
  	                    var n = W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16];
  	                    W[i] = (n << 1) | (n >>> 31);
  	                }
  
  	                var t = ((a << 5) | (a >>> 27)) + e + W[i];
  	                if (i < 20) {
  	                    t += ((b & c) | (~b & d)) + 0x5a827999;
  	                } else if (i < 40) {
  	                    t += (b ^ c ^ d) + 0x6ed9eba1;
  	                } else if (i < 60) {
  	                    t += ((b & c) | (b & d) | (c & d)) - 0x70e44324;
  	                } else /* if (i < 80) */ {
  	                    t += (b ^ c ^ d) - 0x359d3e2a;
  	                }
  
  	                e = d;
  	                d = c;
  	                c = (b << 30) | (b >>> 2);
  	                b = a;
  	                a = t;
  	            }
  
  	            // Intermediate hash value
  	            H[0] = (H[0] + a) | 0;
  	            H[1] = (H[1] + b) | 0;
  	            H[2] = (H[2] + c) | 0;
  	            H[3] = (H[3] + d) | 0;
  	            H[4] = (H[4] + e) | 0;
  	        },
  
  	        _doFinalize: function () {
  	            // Shortcuts
  	            var data = this._data;
  	            var dataWords = data.words;
  
  	            var nBitsTotal = this._nDataBytes * 8;
  	            var nBitsLeft = data.sigBytes * 8;
  
  	            // Add padding
  	            dataWords[nBitsLeft >>> 5] |= 0x80 << (24 - nBitsLeft % 32);
  	            dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 14] = Math.floor(nBitsTotal / 0x100000000);
  	            dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 15] = nBitsTotal;
  	            data.sigBytes = dataWords.length * 4;
  
  	            // Hash final blocks
  	            this._process();
  
  	            // Return final computed hash
  	            return this._hash;
  	        },
  
  	        clone: function () {
  	            var clone = Hasher.clone.call(this);
  	            clone._hash = this._hash.clone();
  
  	            return clone;
  	        }
  	    });
  
  	    /**
  	     * Shortcut function to the hasher's object interface.
  	     *
  	     * @param {WordArray|string} message The message to hash.
  	     *
  	     * @return {WordArray} The hash.
  	     *
  	     * @static
  	     *
  	     * @example
  	     *
  	     *     var hash = CryptoJS.SHA1('message');
  	     *     var hash = CryptoJS.SHA1(wordArray);
  	     */
  	    C.SHA1 = Hasher._createHelper(SHA1);
  
  	    /**
  	     * Shortcut function to the HMAC's object interface.
  	     *
  	     * @param {WordArray|string} message The message to hash.
  	     * @param {WordArray|string} key The secret key.
  	     *
  	     * @return {WordArray} The HMAC.
  	     *
  	     * @static
  	     *
  	     * @example
  	     *
  	     *     var hmac = CryptoJS.HmacSHA1(message, key);
  	     */
  	    C.HmacSHA1 = Hasher._createHmacHelper(SHA1);
  	}());
  
  
  	return CryptoJS.SHA1;
  
  }));
  },{"./core":48}],55:[function(require,module,exports){
  var pSlice = Array.prototype.slice;
  var objectKeys = require('./lib/keys.js');
  var isArguments = require('./lib/is_arguments.js');
  
  var deepEqual = module.exports = function (actual, expected, opts) {
    if (!opts) opts = {};
    // 7.1. All identical values are equivalent, as determined by ===.
    if (actual === expected) {
      return true;
  
    } else if (actual instanceof Date && expected instanceof Date) {
      return actual.getTime() === expected.getTime();
  
    // 7.3. Other pairs that do not both pass typeof value == 'object',
    // equivalence is determined by ==.
    } else if (!actual || !expected || typeof actual != 'object' && typeof expected != 'object') {
      return opts.strict ? actual === expected : actual == expected;
  
    // 7.4. For all other Object pairs, including Array objects, equivalence is
    // determined by having the same number of owned properties (as verified
    // with Object.prototype.hasOwnProperty.call), the same set of keys
    // (although not necessarily the same order), equivalent values for every
    // corresponding key, and an identical 'prototype' property. Note: this
    // accounts for both named and indexed properties on Arrays.
    } else {
      return objEquiv(actual, expected, opts);
    }
  }
  
  function isUndefinedOrNull(value) {
    return value === null || value === undefined;
  }
  
  function isBuffer (x) {
    if (!x || typeof x !== 'object' || typeof x.length !== 'number') return false;
    if (typeof x.copy !== 'function' || typeof x.slice !== 'function') {
      return false;
    }
    if (x.length > 0 && typeof x[0] !== 'number') return false;
    return true;
  }
  
  function objEquiv(a, b, opts) {
    var i, key;
    if (isUndefinedOrNull(a) || isUndefinedOrNull(b))
      return false;
    // an identical 'prototype' property.
    if (a.prototype !== b.prototype) return false;
    //~~~I've managed to break Object.keys through screwy arguments passing.
    //   Converting to array solves the problem.
    if (isArguments(a)) {
      if (!isArguments(b)) {
        return false;
      }
      a = pSlice.call(a);
      b = pSlice.call(b);
      return deepEqual(a, b, opts);
    }
    if (isBuffer(a)) {
      if (!isBuffer(b)) {
        return false;
      }
      if (a.length !== b.length) return false;
      for (i = 0; i < a.length; i++) {
        if (a[i] !== b[i]) return false;
      }
      return true;
    }
    try {
      var ka = objectKeys(a),
          kb = objectKeys(b);
    } catch (e) {//happens when one is a string literal and the other isn't
      return false;
    }
    // having the same number of owned properties (keys incorporates
    // hasOwnProperty)
    if (ka.length != kb.length)
      return false;
    //the same set of keys (although not necessarily the same order),
    ka.sort();
    kb.sort();
    //~~~cheap key test
    for (i = ka.length - 1; i >= 0; i--) {
      if (ka[i] != kb[i])
        return false;
    }
    //equivalent values for every corresponding key, and
    //~~~possibly expensive deep test
    for (i = ka.length - 1; i >= 0; i--) {
      key = ka[i];
      if (!deepEqual(a[key], b[key], opts)) return false;
    }
    return typeof a === typeof b;
  }
  
  },{"./lib/is_arguments.js":56,"./lib/keys.js":57}],56:[function(require,module,exports){
  var supportsArgumentsClass = (function(){
    return Object.prototype.toString.call(arguments)
  })() == '[object Arguments]';
  
  exports = module.exports = supportsArgumentsClass ? supported : unsupported;
  
  exports.supported = supported;
  function supported(object) {
    return Object.prototype.toString.call(object) == '[object Arguments]';
  };
  
  exports.unsupported = unsupported;
  function unsupported(object){
    return object &&
      typeof object == 'object' &&
      typeof object.length == 'number' &&
      Object.prototype.hasOwnProperty.call(object, 'callee') &&
      !Object.prototype.propertyIsEnumerable.call(object, 'callee') ||
      false;
  };
  
  },{}],57:[function(require,module,exports){
  exports = module.exports = typeof Object.keys === 'function'
    ? Object.keys : shim;
  
  exports.shim = shim;
  function shim (obj) {
    var keys = [];
    for (var key in obj) keys.push(key);
    return keys;
  }
  
  },{}],58:[function(require,module,exports){
  var assert = require('assert')
  var BigInteger = require('bigi')
  
  var Point = require('./point')
  
  function Curve (p, a, b, Gx, Gy, n, h) {
    this.p = p
    this.a = a
    this.b = b
    this.G = Point.fromAffine(this, Gx, Gy)
    this.n = n
    this.h = h
  
    this.infinity = new Point(this, null, null, BigInteger.ZERO)
  
    // result caching
    this.pOverFour = p.add(BigInteger.ONE).shiftRight(2)
  
    // determine size of p in bytes
    this.pLength = Math.floor((this.p.bitLength() + 7) / 8)
  }
  
  Curve.prototype.pointFromX = function (isOdd, x) {
    var alpha = x.pow(3).add(this.a.multiply(x)).add(this.b).mod(this.p)
    var beta = alpha.modPow(this.pOverFour, this.p) // XXX: not compatible with all curves
  
    var y = beta
    if (beta.isEven() ^ !isOdd) {
      y = this.p.subtract(y) // -y % p
    }
  
    return Point.fromAffine(this, x, y)
  }
  
  Curve.prototype.isInfinity = function (Q) {
    if (Q === this.infinity) return true
  
    return Q.z.signum() === 0 && Q.y.signum() !== 0
  }
  
  Curve.prototype.isOnCurve = function (Q) {
    if (this.isInfinity(Q)) return true
  
    var x = Q.affineX
    var y = Q.affineY
    var a = this.a
    var b = this.b
    var p = this.p
  
    // Check that xQ and yQ are integers in the interval [0, p - 1]
    if (x.signum() < 0 || x.compareTo(p) >= 0) return false
    if (y.signum() < 0 || y.compareTo(p) >= 0) return false
  
    // and check that y^2 = x^3 + ax + b (mod p)
    var lhs = y.square().mod(p)
    var rhs = x.pow(3).add(a.multiply(x)).add(b).mod(p)
    return lhs.equals(rhs)
  }
  
  /**
   * Validate an elliptic curve point.
   *
   * See SEC 1, section 3.2.2.1: Elliptic Curve Public Key Validation Primitive
   */
  Curve.prototype.validate = function (Q) {
    // Check Q != O
    assert(!this.isInfinity(Q), 'Point is at infinity')
    assert(this.isOnCurve(Q), 'Point is not on the curve')
  
    // Check nQ = O (where Q is a scalar multiple of G)
    var nQ = Q.multiply(this.n)
    assert(this.isInfinity(nQ), 'Point is not a scalar multiple of G')
  
    return true
  }
  
  module.exports = Curve
  
  },{"./point":62,"assert":75,"bigi":5}],59:[function(require,module,exports){
  module.exports={
    "secp128r1": {
      "p": "fffffffdffffffffffffffffffffffff",
      "a": "fffffffdfffffffffffffffffffffffc",
      "b": "e87579c11079f43dd824993c2cee5ed3",
      "n": "fffffffe0000000075a30d1b9038a115",
      "h": "01",
      "Gx": "161ff7528b899b2d0c28607ca52c5b86",
      "Gy": "cf5ac8395bafeb13c02da292dded7a83"
    },
    "secp160k1": {
      "p": "fffffffffffffffffffffffffffffffeffffac73",
      "a": "00",
      "b": "07",
      "n": "0100000000000000000001b8fa16dfab9aca16b6b3",
      "h": "01",
      "Gx": "3b4c382ce37aa192a4019e763036f4f5dd4d7ebb",
      "Gy": "938cf935318fdced6bc28286531733c3f03c4fee"
    },
    "secp160r1": {
      "p": "ffffffffffffffffffffffffffffffff7fffffff",
      "a": "ffffffffffffffffffffffffffffffff7ffffffc",
      "b": "1c97befc54bd7a8b65acf89f81d4d4adc565fa45",
      "n": "0100000000000000000001f4c8f927aed3ca752257",
      "h": "01",
      "Gx": "4a96b5688ef573284664698968c38bb913cbfc82",
      "Gy": "23a628553168947d59dcc912042351377ac5fb32"
    },
    "secp192k1": {
      "p": "fffffffffffffffffffffffffffffffffffffffeffffee37",
      "a": "00",
      "b": "03",
      "n": "fffffffffffffffffffffffe26f2fc170f69466a74defd8d",
      "h": "01",
      "Gx": "db4ff10ec057e9ae26b07d0280b7f4341da5d1b1eae06c7d",
      "Gy": "9b2f2f6d9c5628a7844163d015be86344082aa88d95e2f9d"
    },
    "secp192r1": {
      "p": "fffffffffffffffffffffffffffffffeffffffffffffffff",
      "a": "fffffffffffffffffffffffffffffffefffffffffffffffc",
      "b": "64210519e59c80e70fa7e9ab72243049feb8deecc146b9b1",
      "n": "ffffffffffffffffffffffff99def836146bc9b1b4d22831",
      "h": "01",
      "Gx": "188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012",
      "Gy": "07192b95ffc8da78631011ed6b24cdd573f977a11e794811"
    },
    "secp256k1": {
      "p": "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f",
      "a": "00",
      "b": "07",
      "n": "fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141",
      "h": "01",
      "Gx": "79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798",
      "Gy": "483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8"
    },
    "secp256r1": {
      "p": "ffffffff00000001000000000000000000000000ffffffffffffffffffffffff",
      "a": "ffffffff00000001000000000000000000000000fffffffffffffffffffffffc",
      "b": "5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b",
      "n": "ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551",
      "h": "01",
      "Gx": "6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296",
      "Gy": "4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5"
    }
  }
  
  },{}],60:[function(require,module,exports){
  var Point = require('./point')
  var Curve = require('./curve')
  
  var getCurveByName = require('./names')
  
  module.exports = {
    Curve: Curve,
    Point: Point,
    getCurveByName: getCurveByName
  }
  
  },{"./curve":58,"./names":61,"./point":62}],61:[function(require,module,exports){
  var BigInteger = require('bigi')
  
  var curves = require('./curves.json')
  var Curve = require('./curve')
  
  function getCurveByName (name) {
    var curve = curves[name]
    if (!curve) return null
  
    var p = new BigInteger(curve.p, 16)
    var a = new BigInteger(curve.a, 16)
    var b = new BigInteger(curve.b, 16)
    var n = new BigInteger(curve.n, 16)
    var h = new BigInteger(curve.h, 16)
    var Gx = new BigInteger(curve.Gx, 16)
    var Gy = new BigInteger(curve.Gy, 16)
  
    return new Curve(p, a, b, Gx, Gy, n, h)
  }
  
  module.exports = getCurveByName
  
  },{"./curve":58,"./curves.json":59,"bigi":5}],62:[function(require,module,exports){
  (function (Buffer){
  var assert = require('assert')
  var BigInteger = require('bigi')
  
  var THREE = BigInteger.valueOf(3)
  
  function Point (curve, x, y, z) {
    assert.notStrictEqual(z, undefined, 'Missing Z coordinate')
  
    this.curve = curve
    this.x = x
    this.y = y
    this.z = z
    this._zInv = null
  
    this.compressed = true
  }
  
  Object.defineProperty(Point.prototype, 'zInv', {
    get: function () {
      if (this._zInv === null) {
        this._zInv = this.z.modInverse(this.curve.p)
      }
  
      return this._zInv
    }
  })
  
  Object.defineProperty(Point.prototype, 'affineX', {
    get: function () {
      return this.x.multiply(this.zInv).mod(this.curve.p)
    }
  })
  
  Object.defineProperty(Point.prototype, 'affineY', {
    get: function () {
      return this.y.multiply(this.zInv).mod(this.curve.p)
    }
  })
  
  Point.fromAffine = function (curve, x, y) {
    return new Point(curve, x, y, BigInteger.ONE)
  }
  
  Point.prototype.equals = function (other) {
    if (other === this) return true
    if (this.curve.isInfinity(this)) return this.curve.isInfinity(other)
    if (this.curve.isInfinity(other)) return this.curve.isInfinity(this)
  
    // u = Y2 * Z1 - Y1 * Z2
    var u = other.y.multiply(this.z).subtract(this.y.multiply(other.z)).mod(this.curve.p)
  
    if (u.signum() !== 0) return false
  
    // v = X2 * Z1 - X1 * Z2
    var v = other.x.multiply(this.z).subtract(this.x.multiply(other.z)).mod(this.curve.p)
  
    return v.signum() === 0
  }
  
  Point.prototype.negate = function () {
    var y = this.curve.p.subtract(this.y)
  
    return new Point(this.curve, this.x, y, this.z)
  }
  
  Point.prototype.add = function (b) {
    if (this.curve.isInfinity(this)) return b
    if (this.curve.isInfinity(b)) return this
  
    var x1 = this.x
    var y1 = this.y
    var x2 = b.x
    var y2 = b.y
  
    // u = Y2 * Z1 - Y1 * Z2
    var u = y2.multiply(this.z).subtract(y1.multiply(b.z)).mod(this.curve.p)
    // v = X2 * Z1 - X1 * Z2
    var v = x2.multiply(this.z).subtract(x1.multiply(b.z)).mod(this.curve.p)
  
    if (v.signum() === 0) {
      if (u.signum() === 0) {
        return this.twice() // this == b, so double
      }
  
      return this.curve.infinity // this = -b, so infinity
    }
  
    var v2 = v.square()
    var v3 = v2.multiply(v)
    var x1v2 = x1.multiply(v2)
    var zu2 = u.square().multiply(this.z)
  
    // x3 = v * (z2 * (z1 * u^2 - 2 * x1 * v^2) - v^3)
    var x3 = zu2.subtract(x1v2.shiftLeft(1)).multiply(b.z).subtract(v3).multiply(v).mod(this.curve.p)
    // y3 = z2 * (3 * x1 * u * v^2 - y1 * v^3 - z1 * u^3) + u * v^3
    var y3 = x1v2.multiply(THREE).multiply(u).subtract(y1.multiply(v3)).subtract(zu2.multiply(u)).multiply(b.z).add(u.multiply(v3)).mod(this.curve.p)
    // z3 = v^3 * z1 * z2
    var z3 = v3.multiply(this.z).multiply(b.z).mod(this.curve.p)
  
    return new Point(this.curve, x3, y3, z3)
  }
  
  Point.prototype.twice = function () {
    if (this.curve.isInfinity(this)) return this
    if (this.y.signum() === 0) return this.curve.infinity
  
    var x1 = this.x
    var y1 = this.y
  
    var y1z1 = y1.multiply(this.z).mod(this.curve.p)
    var y1sqz1 = y1z1.multiply(y1).mod(this.curve.p)
    var a = this.curve.a
  
    // w = 3 * x1^2 + a * z1^2
    var w = x1.square().multiply(THREE)
  
    if (a.signum() !== 0) {
      w = w.add(this.z.square().multiply(a))
    }
  
    w = w.mod(this.curve.p)
    // x3 = 2 * y1 * z1 * (w^2 - 8 * x1 * y1^2 * z1)
    var x3 = w.square().subtract(x1.shiftLeft(3).multiply(y1sqz1)).shiftLeft(1).multiply(y1z1).mod(this.curve.p)
    // y3 = 4 * y1^2 * z1 * (3 * w * x1 - 2 * y1^2 * z1) - w^3
    var y3 = w.multiply(THREE).multiply(x1).subtract(y1sqz1.shiftLeft(1)).shiftLeft(2).multiply(y1sqz1).subtract(w.pow(3)).mod(this.curve.p)
    // z3 = 8 * (y1 * z1)^3
    var z3 = y1z1.pow(3).shiftLeft(3).mod(this.curve.p)
  
    return new Point(this.curve, x3, y3, z3)
  }
  
  // Simple NAF (Non-Adjacent Form) multiplication algorithm
  // TODO: modularize the multiplication algorithm
  Point.prototype.multiply = function (k) {
    if (this.curve.isInfinity(this)) return this
    if (k.signum() === 0) return this.curve.infinity
  
    var e = k
    var h = e.multiply(THREE)
  
    var neg = this.negate()
    var R = this
  
    for (var i = h.bitLength() - 2; i > 0; --i) {
      var hBit = h.testBit(i)
      var eBit = e.testBit(i)
  
      R = R.twice()
  
      if (hBit !== eBit) {
        R = R.add(hBit ? this : neg)
      }
    }
  
    return R
  }
  
  // Compute this*j + x*k (simultaneous multiplication)
  Point.prototype.multiplyTwo = function (j, x, k) {
    var i = Math.max(j.bitLength(), k.bitLength()) - 1
    var R = this.curve.infinity
    var both = this.add(x)
  
    while (i >= 0) {
      var jBit = j.testBit(i)
      var kBit = k.testBit(i)
  
      R = R.twice()
  
      if (jBit) {
        if (kBit) {
          R = R.add(both)
        } else {
          R = R.add(this)
        }
      } else if (kBit) {
        R = R.add(x)
      }
      --i
    }
  
    return R
  }
  
  Point.prototype.getEncoded = function (compressed) {
    if (compressed == null) compressed = this.compressed
    if (this.curve.isInfinity(this)) return new Buffer('00', 'hex') // Infinity point encoded is simply '00'
  
    var x = this.affineX
    var y = this.affineY
    var byteLength = this.curve.pLength
    var buffer
  
    // 0x02/0x03 | X
    if (compressed) {
      buffer = new Buffer(1 + byteLength)
      buffer.writeUInt8(y.isEven() ? 0x02 : 0x03, 0)
  
    // 0x04 | X | Y
    } else {
      buffer = new Buffer(1 + byteLength + byteLength)
      buffer.writeUInt8(0x04, 0)
  
      y.toBuffer(byteLength).copy(buffer, 1 + byteLength)
    }
  
    x.toBuffer(byteLength).copy(buffer, 1)
  
    return buffer
  }
  
  Point.decodeFrom = function (curve, buffer) {
    var type = buffer.readUInt8(0)
    var compressed = (type !== 4)
  
    var byteLength = Math.floor((curve.p.bitLength() + 7) / 8)
    var x = BigInteger.fromBuffer(buffer.slice(1, 1 + byteLength))
  
    var Q
    if (compressed) {
      assert.equal(buffer.length, byteLength + 1, 'Invalid sequence length')
      assert(type === 0x02 || type === 0x03, 'Invalid sequence tag')
  
      var isOdd = (type === 0x03)
      Q = curve.pointFromX(isOdd, x)
    } else {
      assert.equal(buffer.length, 1 + byteLength + byteLength, 'Invalid sequence length')
  
      var y = BigInteger.fromBuffer(buffer.slice(1 + byteLength))
      Q = Point.fromAffine(curve, x, y)
    }
  
    Q.compressed = compressed
    return Q
  }
  
  Point.prototype.toString = function () {
    if (this.curve.isInfinity(this)) return '(INFINITY)'
  
    return '(' + this.affineX.toString() + ',' + this.affineY.toString() + ')'
  }
  
  module.exports = Point
  
  }).call(this,require("buffer").Buffer)
  },{"assert":75,"bigi":5,"buffer":79}],63:[function(require,module,exports){
  if (typeof Object.create === 'function') {
    // implementation from standard node.js 'util' module
    module.exports = function inherits(ctor, superCtor) {
      ctor.super_ = superCtor
      ctor.prototype = Object.create(superCtor.prototype, {
        constructor: {
          value: ctor,
          enumerable: false,
          writable: true,
          configurable: true
        }
      });
    };
  } else {
    // old school shim for old browsers
    module.exports = function inherits(ctor, superCtor) {
      ctor.super_ = superCtor
      var TempCtor = function () {}
      TempCtor.prototype = superCtor.prototype
      ctor.prototype = new TempCtor()
      ctor.prototype.constructor = ctor
    }
  }
  
  },{}],64:[function(require,module,exports){
  /*
   Copyright 2013 Daniel Wirtz <dcode@dcode.io>
   Copyright 2009 The Closure Library Authors. All Rights Reserved.
  
   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at
  
   http://www.apache.org/licenses/LICENSE-2.0
  
   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS-IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
   */
  
  /**
   * @license long.js (c) 2013 Daniel Wirtz <dcode@dcode.io>
   * Released under the Apache License, Version 2.0
   * see: https://github.com/dcodeIO/long.js for details
   */
  (function(global, factory) {
  
      /* AMD */ if (typeof define === 'function' && define["amd"])
          define([], factory);
      /* CommonJS */ else if (typeof require === 'function' && typeof module === "object" && module && module["exports"])
          module["exports"] = factory();
      /* Global */ else
          (global["dcodeIO"] = global["dcodeIO"] || {})["Long"] = factory();
  
  })(this, function() {
      "use strict";
  
      /**
       * Constructs a 64 bit two's-complement integer, given its low and high 32 bit values as *signed* integers.
       *  See the from* functions below for more convenient ways of constructing Longs.
       * @exports Long
       * @class A Long class for representing a 64 bit two's-complement integer value.
       * @param {number} low The low (signed) 32 bits of the long
       * @param {number} high The high (signed) 32 bits of the long
       * @param {boolean=} unsigned Whether unsigned or not, defaults to `false` for signed
       * @constructor
       */
      function Long(low, high, unsigned) {
  
          /**
           * The low 32 bits as a signed value.
           * @type {number}
           */
          this.low = low | 0;
  
          /**
           * The high 32 bits as a signed value.
           * @type {number}
           */
          this.high = high | 0;
  
          /**
           * Whether unsigned or not.
           * @type {boolean}
           */
          this.unsigned = !!unsigned;
      }
  
      // The internal representation of a long is the two given signed, 32-bit values.
      // We use 32-bit pieces because these are the size of integers on which
      // Javascript performs bit-operations.  For operations like addition and
      // multiplication, we split each number into 16 bit pieces, which can easily be
      // multiplied within Javascript's floating-point representation without overflow
      // or change in sign.
      //
      // In the algorithms below, we frequently reduce the negative case to the
      // positive case by negating the input(s) and then post-processing the result.
      // Note that we must ALWAYS check specially whether those values are MIN_VALUE
      // (-2^63) because -MIN_VALUE == MIN_VALUE (since 2^63 cannot be represented as
      // a positive number, it overflows back into a negative).  Not handling this
      // case would often result in infinite recursion.
      //
      // Common constant values ZERO, ONE, NEG_ONE, etc. are defined below the from*
      // methods on which they depend.
  
      /**
       * An indicator used to reliably determine if an object is a Long or not.
       * @type {boolean}
       * @const
       * @private
       */
      Long.prototype.__isLong__;
  
      Object.defineProperty(Long.prototype, "__isLong__", {
          value: true,
          enumerable: false,
          configurable: false
      });
  
      /**
       * @function
       * @param {*} obj Object
       * @returns {boolean}
       * @inner
       */
      function isLong(obj) {
          return (obj && obj["__isLong__"]) === true;
      }
  
      /**
       * Tests if the specified object is a Long.
       * @function
       * @param {*} obj Object
       * @returns {boolean}
       */
      Long.isLong = isLong;
  
      /**
       * A cache of the Long representations of small integer values.
       * @type {!Object}
       * @inner
       */
      var INT_CACHE = {};
  
      /**
       * A cache of the Long representations of small unsigned integer values.
       * @type {!Object}
       * @inner
       */
      var UINT_CACHE = {};
  
      /**
       * @param {number} value
       * @param {boolean=} unsigned
       * @returns {!Long}
       * @inner
       */
      function fromInt(value, unsigned) {
          var obj, cachedObj, cache;
          if (unsigned) {
              value >>>= 0;
              if (cache = (0 <= value && value < 256)) {
                  cachedObj = UINT_CACHE[value];
                  if (cachedObj)
                      return cachedObj;
              }
              obj = fromBits(value, (value | 0) < 0 ? -1 : 0, true);
              if (cache)
                  UINT_CACHE[value] = obj;
              return obj;
          } else {
              value |= 0;
              if (cache = (-128 <= value && value < 128)) {
                  cachedObj = INT_CACHE[value];
                  if (cachedObj)
                      return cachedObj;
              }
              obj = fromBits(value, value < 0 ? -1 : 0, false);
              if (cache)
                  INT_CACHE[value] = obj;
              return obj;
          }
      }
  
      /**
       * Returns a Long representing the given 32 bit integer value.
       * @function
       * @param {number} value The 32 bit integer in question
       * @param {boolean=} unsigned Whether unsigned or not, defaults to `false` for signed
       * @returns {!Long} The corresponding Long value
       */
      Long.fromInt = fromInt;
  
      /**
       * @param {number} value
       * @param {boolean=} unsigned
       * @returns {!Long}
       * @inner
       */
      function fromNumber(value, unsigned) {
          if (isNaN(value) || !isFinite(value))
              return unsigned ? UZERO : ZERO;
          if (unsigned) {
              if (value < 0)
                  return UZERO;
              if (value >= TWO_PWR_64_DBL)
                  return MAX_UNSIGNED_VALUE;
          } else {
              if (value <= -TWO_PWR_63_DBL)
                  return MIN_VALUE;
              if (value + 1 >= TWO_PWR_63_DBL)
                  return MAX_VALUE;
          }
          if (value < 0)
              return fromNumber(-value, unsigned).neg();
          return fromBits((value % TWO_PWR_32_DBL) | 0, (value / TWO_PWR_32_DBL) | 0, unsigned);
      }
  
      /**
       * Returns a Long representing the given value, provided that it is a finite number. Otherwise, zero is returned.
       * @function
       * @param {number} value The number in question
       * @param {boolean=} unsigned Whether unsigned or not, defaults to `false` for signed
       * @returns {!Long} The corresponding Long value
       */
      Long.fromNumber = fromNumber;
  
      /**
       * @param {number} lowBits
       * @param {number} highBits
       * @param {boolean=} unsigned
       * @returns {!Long}
       * @inner
       */
      function fromBits(lowBits, highBits, unsigned) {
          return new Long(lowBits, highBits, unsigned);
      }
  
      /**
       * Returns a Long representing the 64 bit integer that comes by concatenating the given low and high bits. Each is
       *  assumed to use 32 bits.
       * @function
       * @param {number} lowBits The low 32 bits
       * @param {number} highBits The high 32 bits
       * @param {boolean=} unsigned Whether unsigned or not, defaults to `false` for signed
       * @returns {!Long} The corresponding Long value
       */
      Long.fromBits = fromBits;
  
      /**
       * @function
       * @param {number} base
       * @param {number} exponent
       * @returns {number}
       * @inner
       */
      var pow_dbl = Math.pow; // Used 4 times (4*8 to 15+4)
  
      /**
       * @param {string} str
       * @param {(boolean|number)=} unsigned
       * @param {number=} radix
       * @returns {!Long}
       * @inner
       */
      function fromString(str, unsigned, radix) {
          if (str.length === 0)
              throw Error('empty string');
          if (str === "NaN" || str === "Infinity" || str === "+Infinity" || str === "-Infinity")
              return ZERO;
          if (typeof unsigned === 'number') {
              // For goog.math.long compatibility
              radix = unsigned,
              unsigned = false;
          } else {
              unsigned = !! unsigned;
          }
          radix = radix || 10;
          if (radix < 2 || 36 < radix)
              throw RangeError('radix');
  
          var p;
          if ((p = str.indexOf('-')) > 0)
              throw Error('interior hyphen');
          else if (p === 0) {
              return fromString(str.substring(1), unsigned, radix).neg();
          }
  
          // Do several (8) digits each time through the loop, so as to
          // minimize the calls to the very expensive emulated div.
          var radixToPower = fromNumber(pow_dbl(radix, 8));
  
          var result = ZERO;
          for (var i = 0; i < str.length; i += 8) {
              var size = Math.min(8, str.length - i),
                  value = parseInt(str.substring(i, i + size), radix);
              if (size < 8) {
                  var power = fromNumber(pow_dbl(radix, size));
                  result = result.mul(power).add(fromNumber(value));
              } else {
                  result = result.mul(radixToPower);
                  result = result.add(fromNumber(value));
              }
          }
          result.unsigned = unsigned;
          return result;
      }
  
      /**
       * Returns a Long representation of the given string, written using the specified radix.
       * @function
       * @param {string} str The textual representation of the Long
       * @param {(boolean|number)=} unsigned Whether unsigned or not, defaults to `false` for signed
       * @param {number=} radix The radix in which the text is written (2-36), defaults to 10
       * @returns {!Long} The corresponding Long value
       */
      Long.fromString = fromString;
  
      /**
       * @function
       * @param {!Long|number|string|!{low: number, high: number, unsigned: boolean}} val
       * @returns {!Long}
       * @inner
       */
      function fromValue(val) {
          if (val /* is compatible */ instanceof Long)
              return val;
          if (typeof val === 'number')
              return fromNumber(val);
          if (typeof val === 'string')
              return fromString(val);
          // Throws for non-objects, converts non-instanceof Long:
          return fromBits(val.low, val.high, val.unsigned);
      }
  
      /**
       * Converts the specified value to a Long.
       * @function
       * @param {!Long|number|string|!{low: number, high: number, unsigned: boolean}} val Value
       * @returns {!Long}
       */
      Long.fromValue = fromValue;
  
      // NOTE: the compiler should inline these constant values below and then remove these variables, so there should be
      // no runtime penalty for these.
  
      /**
       * @type {number}
       * @const
       * @inner
       */
      var TWO_PWR_16_DBL = 1 << 16;
  
      /**
       * @type {number}
       * @const
       * @inner
       */
      var TWO_PWR_24_DBL = 1 << 24;
  
      /**
       * @type {number}
       * @const
       * @inner
       */
      var TWO_PWR_32_DBL = TWO_PWR_16_DBL * TWO_PWR_16_DBL;
  
      /**
       * @type {number}
       * @const
       * @inner
       */
      var TWO_PWR_64_DBL = TWO_PWR_32_DBL * TWO_PWR_32_DBL;
  
      /**
       * @type {number}
       * @const
       * @inner
       */
      var TWO_PWR_63_DBL = TWO_PWR_64_DBL / 2;
  
      /**
       * @type {!Long}
       * @const
       * @inner
       */
      var TWO_PWR_24 = fromInt(TWO_PWR_24_DBL);
  
      /**
       * @type {!Long}
       * @inner
       */
      var ZERO = fromInt(0);
  
      /**
       * Signed zero.
       * @type {!Long}
       */
      Long.ZERO = ZERO;
  
      /**
       * @type {!Long}
       * @inner
       */
      var UZERO = fromInt(0, true);
  
      /**
       * Unsigned zero.
       * @type {!Long}
       */
      Long.UZERO = UZERO;
  
      /**
       * @type {!Long}
       * @inner
       */
      var ONE = fromInt(1);
  
      /**
       * Signed one.
       * @type {!Long}
       */
      Long.ONE = ONE;
  
      /**
       * @type {!Long}
       * @inner
       */
      var UONE = fromInt(1, true);
  
      /**
       * Unsigned one.
       * @type {!Long}
       */
      Long.UONE = UONE;
  
      /**
       * @type {!Long}
       * @inner
       */
      var NEG_ONE = fromInt(-1);
  
      /**
       * Signed negative one.
       * @type {!Long}
       */
      Long.NEG_ONE = NEG_ONE;
  
      /**
       * @type {!Long}
       * @inner
       */
      var MAX_VALUE = fromBits(0xFFFFFFFF|0, 0x7FFFFFFF|0, false);
  
      /**
       * Maximum signed value.
       * @type {!Long}
       */
      Long.MAX_VALUE = MAX_VALUE;
  
      /**
       * @type {!Long}
       * @inner
       */
      var MAX_UNSIGNED_VALUE = fromBits(0xFFFFFFFF|0, 0xFFFFFFFF|0, true);
  
      /**
       * Maximum unsigned value.
       * @type {!Long}
       */
      Long.MAX_UNSIGNED_VALUE = MAX_UNSIGNED_VALUE;
  
      /**
       * @type {!Long}
       * @inner
       */
      var MIN_VALUE = fromBits(0, 0x80000000|0, false);
  
      /**
       * Minimum signed value.
       * @type {!Long}
       */
      Long.MIN_VALUE = MIN_VALUE;
  
      /**
       * @alias Long.prototype
       * @inner
       */
      var LongPrototype = Long.prototype;
  
      /**
       * Converts the Long to a 32 bit integer, assuming it is a 32 bit integer.
       * @returns {number}
       */
      LongPrototype.toInt = function toInt() {
          return this.unsigned ? this.low >>> 0 : this.low;
      };
  
      /**
       * Converts the Long to a the nearest floating-point representation of this value (double, 53 bit mantissa).
       * @returns {number}
       */
      LongPrototype.toNumber = function toNumber() {
          if (this.unsigned)
              return ((this.high >>> 0) * TWO_PWR_32_DBL) + (this.low >>> 0);
          return this.high * TWO_PWR_32_DBL + (this.low >>> 0);
      };
  
      /**
       * Converts the Long to a string written in the specified radix.
       * @param {number=} radix Radix (2-36), defaults to 10
       * @returns {string}
       * @override
       * @throws {RangeError} If `radix` is out of range
       */
      LongPrototype.toString = function toString(radix) {
          radix = radix || 10;
          if (radix < 2 || 36 < radix)
              throw RangeError('radix');
          if (this.isZero())
              return '0';
          if (this.isNegative()) { // Unsigned Longs are never negative
              if (this.eq(MIN_VALUE)) {
                  // We need to change the Long value before it can be negated, so we remove
                  // the bottom-most digit in this base and then recurse to do the rest.
                  var radixLong = fromNumber(radix),
                      div = this.div(radixLong),
                      rem1 = div.mul(radixLong).sub(this);
                  return div.toString(radix) + rem1.toInt().toString(radix);
              } else
                  return '-' + this.neg().toString(radix);
          }
  
          // Do several (6) digits each time through the loop, so as to
          // minimize the calls to the very expensive emulated div.
          var radixToPower = fromNumber(pow_dbl(radix, 6), this.unsigned),
              rem = this;
          var result = '';
          while (true) {
              var remDiv = rem.div(radixToPower),
                  intval = rem.sub(remDiv.mul(radixToPower)).toInt() >>> 0,
                  digits = intval.toString(radix);
              rem = remDiv;
              if (rem.isZero())
                  return digits + result;
              else {
                  while (digits.length < 6)
                      digits = '0' + digits;
                  result = '' + digits + result;
              }
          }
      };
  
      /**
       * Gets the high 32 bits as a signed integer.
       * @returns {number} Signed high bits
       */
      LongPrototype.getHighBits = function getHighBits() {
          return this.high;
      };
  
      /**
       * Gets the high 32 bits as an unsigned integer.
       * @returns {number} Unsigned high bits
       */
      LongPrototype.getHighBitsUnsigned = function getHighBitsUnsigned() {
          return this.high >>> 0;
      };
  
      /**
       * Gets the low 32 bits as a signed integer.
       * @returns {number} Signed low bits
       */
      LongPrototype.getLowBits = function getLowBits() {
          return this.low;
      };
  
      /**
       * Gets the low 32 bits as an unsigned integer.
       * @returns {number} Unsigned low bits
       */
      LongPrototype.getLowBitsUnsigned = function getLowBitsUnsigned() {
          return this.low >>> 0;
      };
  
      /**
       * Gets the number of bits needed to represent the absolute value of this Long.
       * @returns {number}
       */
      LongPrototype.getNumBitsAbs = function getNumBitsAbs() {
          if (this.isNegative()) // Unsigned Longs are never negative
              return this.eq(MIN_VALUE) ? 64 : this.neg().getNumBitsAbs();
          var val = this.high != 0 ? this.high : this.low;
          for (var bit = 31; bit > 0; bit--)
              if ((val & (1 << bit)) != 0)
                  break;
          return this.high != 0 ? bit + 33 : bit + 1;
      };
  
      /**
       * Tests if this Long's value equals zero.
       * @returns {boolean}
       */
      LongPrototype.isZero = function isZero() {
          return this.high === 0 && this.low === 0;
      };
  
      /**
       * Tests if this Long's value is negative.
       * @returns {boolean}
       */
      LongPrototype.isNegative = function isNegative() {
          return !this.unsigned && this.high < 0;
      };
  
      /**
       * Tests if this Long's value is positive.
       * @returns {boolean}
       */
      LongPrototype.isPositive = function isPositive() {
          return this.unsigned || this.high >= 0;
      };
  
      /**
       * Tests if this Long's value is odd.
       * @returns {boolean}
       */
      LongPrototype.isOdd = function isOdd() {
          return (this.low & 1) === 1;
      };
  
      /**
       * Tests if this Long's value is even.
       * @returns {boolean}
       */
      LongPrototype.isEven = function isEven() {
          return (this.low & 1) === 0;
      };
  
      /**
       * Tests if this Long's value equals the specified's.
       * @param {!Long|number|string} other Other value
       * @returns {boolean}
       */
      LongPrototype.equals = function equals(other) {
          if (!isLong(other))
              other = fromValue(other);
          if (this.unsigned !== other.unsigned && (this.high >>> 31) === 1 && (other.high >>> 31) === 1)
              return false;
          return this.high === other.high && this.low === other.low;
      };
  
      /**
       * Tests if this Long's value equals the specified's. This is an alias of {@link Long#equals}.
       * @function
       * @param {!Long|number|string} other Other value
       * @returns {boolean}
       */
      LongPrototype.eq = LongPrototype.equals;
  
      /**
       * Tests if this Long's value differs from the specified's.
       * @param {!Long|number|string} other Other value
       * @returns {boolean}
       */
      LongPrototype.notEquals = function notEquals(other) {
          return !this.eq(/* validates */ other);
      };
  
      /**
       * Tests if this Long's value differs from the specified's. This is an alias of {@link Long#notEquals}.
       * @function
       * @param {!Long|number|string} other Other value
       * @returns {boolean}
       */
      LongPrototype.neq = LongPrototype.notEquals;
  
      /**
       * Tests if this Long's value is less than the specified's.
       * @param {!Long|number|string} other Other value
       * @returns {boolean}
       */
      LongPrototype.lessThan = function lessThan(other) {
          return this.comp(/* validates */ other) < 0;
      };
  
      /**
       * Tests if this Long's value is less than the specified's. This is an alias of {@link Long#lessThan}.
       * @function
       * @param {!Long|number|string} other Other value
       * @returns {boolean}
       */
      LongPrototype.lt = LongPrototype.lessThan;
  
      /**
       * Tests if this Long's value is less than or equal the specified's.
       * @param {!Long|number|string} other Other value
       * @returns {boolean}
       */
      LongPrototype.lessThanOrEqual = function lessThanOrEqual(other) {
          return this.comp(/* validates */ other) <= 0;
      };
  
      /**
       * Tests if this Long's value is less than or equal the specified's. This is an alias of {@link Long#lessThanOrEqual}.
       * @function
       * @param {!Long|number|string} other Other value
       * @returns {boolean}
       */
      LongPrototype.lte = LongPrototype.lessThanOrEqual;
  
      /**
       * Tests if this Long's value is greater than the specified's.
       * @param {!Long|number|string} other Other value
       * @returns {boolean}
       */
      LongPrototype.greaterThan = function greaterThan(other) {
          return this.comp(/* validates */ other) > 0;
      };
  
      /**
       * Tests if this Long's value is greater than the specified's. This is an alias of {@link Long#greaterThan}.
       * @function
       * @param {!Long|number|string} other Other value
       * @returns {boolean}
       */
      LongPrototype.gt = LongPrototype.greaterThan;
  
      /**
       * Tests if this Long's value is greater than or equal the specified's.
       * @param {!Long|number|string} other Other value
       * @returns {boolean}
       */
      LongPrototype.greaterThanOrEqual = function greaterThanOrEqual(other) {
          return this.comp(/* validates */ other) >= 0;
      };
  
      /**
       * Tests if this Long's value is greater than or equal the specified's. This is an alias of {@link Long#greaterThanOrEqual}.
       * @function
       * @param {!Long|number|string} other Other value
       * @returns {boolean}
       */
      LongPrototype.gte = LongPrototype.greaterThanOrEqual;
  
      /**
       * Compares this Long's value with the specified's.
       * @param {!Long|number|string} other Other value
       * @returns {number} 0 if they are the same, 1 if the this is greater and -1
       *  if the given one is greater
       */
      LongPrototype.compare = function compare(other) {
          if (!isLong(other))
              other = fromValue(other);
          if (this.eq(other))
              return 0;
          var thisNeg = this.isNegative(),
              otherNeg = other.isNegative();
          if (thisNeg && !otherNeg)
              return -1;
          if (!thisNeg && otherNeg)
              return 1;
          // At this point the sign bits are the same
          if (!this.unsigned)
              return this.sub(other).isNegative() ? -1 : 1;
          // Both are positive if at least one is unsigned
          return (other.high >>> 0) > (this.high >>> 0) || (other.high === this.high && (other.low >>> 0) > (this.low >>> 0)) ? -1 : 1;
      };
  
      /**
       * Compares this Long's value with the specified's. This is an alias of {@link Long#compare}.
       * @function
       * @param {!Long|number|string} other Other value
       * @returns {number} 0 if they are the same, 1 if the this is greater and -1
       *  if the given one is greater
       */
      LongPrototype.comp = LongPrototype.compare;
  
      /**
       * Negates this Long's value.
       * @returns {!Long} Negated Long
       */
      LongPrototype.negate = function negate() {
          if (!this.unsigned && this.eq(MIN_VALUE))
              return MIN_VALUE;
          return this.not().add(ONE);
      };
  
      /**
       * Negates this Long's value. This is an alias of {@link Long#negate}.
       * @function
       * @returns {!Long} Negated Long
       */
      LongPrototype.neg = LongPrototype.negate;
  
      /**
       * Returns the sum of this and the specified Long.
       * @param {!Long|number|string} addend Addend
       * @returns {!Long} Sum
       */
      LongPrototype.add = function add(addend) {
          if (!isLong(addend))
              addend = fromValue(addend);
  
          // Divide each number into 4 chunks of 16 bits, and then sum the chunks.
  
          var a48 = this.high >>> 16;
          var a32 = this.high & 0xFFFF;
          var a16 = this.low >>> 16;
          var a00 = this.low & 0xFFFF;
  
          var b48 = addend.high >>> 16;
          var b32 = addend.high & 0xFFFF;
          var b16 = addend.low >>> 16;
          var b00 = addend.low & 0xFFFF;
  
          var c48 = 0, c32 = 0, c16 = 0, c00 = 0;
          c00 += a00 + b00;
          c16 += c00 >>> 16;
          c00 &= 0xFFFF;
          c16 += a16 + b16;
          c32 += c16 >>> 16;
          c16 &= 0xFFFF;
          c32 += a32 + b32;
          c48 += c32 >>> 16;
          c32 &= 0xFFFF;
          c48 += a48 + b48;
          c48 &= 0xFFFF;
          return fromBits((c16 << 16) | c00, (c48 << 16) | c32, this.unsigned);
      };
  
      /**
       * Returns the difference of this and the specified Long.
       * @param {!Long|number|string} subtrahend Subtrahend
       * @returns {!Long} Difference
       */
      LongPrototype.subtract = function subtract(subtrahend) {
          if (!isLong(subtrahend))
              subtrahend = fromValue(subtrahend);
          return this.add(subtrahend.neg());
      };
  
      /**
       * Returns the difference of this and the specified Long. This is an alias of {@link Long#subtract}.
       * @function
       * @param {!Long|number|string} subtrahend Subtrahend
       * @returns {!Long} Difference
       */
      LongPrototype.sub = LongPrototype.subtract;
  
      /**
       * Returns the product of this and the specified Long.
       * @param {!Long|number|string} multiplier Multiplier
       * @returns {!Long} Product
       */
      LongPrototype.multiply = function multiply(multiplier) {
          if (this.isZero())
              return ZERO;
          if (!isLong(multiplier))
              multiplier = fromValue(multiplier);
          if (multiplier.isZero())
              return ZERO;
          if (this.eq(MIN_VALUE))
              return multiplier.isOdd() ? MIN_VALUE : ZERO;
          if (multiplier.eq(MIN_VALUE))
              return this.isOdd() ? MIN_VALUE : ZERO;
  
          if (this.isNegative()) {
              if (multiplier.isNegative())
                  return this.neg().mul(multiplier.neg());
              else
                  return this.neg().mul(multiplier).neg();
          } else if (multiplier.isNegative())
              return this.mul(multiplier.neg()).neg();
  
          // If both longs are small, use float multiplication
          if (this.lt(TWO_PWR_24) && multiplier.lt(TWO_PWR_24))
              return fromNumber(this.toNumber() * multiplier.toNumber(), this.unsigned);
  
          // Divide each long into 4 chunks of 16 bits, and then add up 4x4 products.
          // We can skip products that would overflow.
  
          var a48 = this.high >>> 16;
          var a32 = this.high & 0xFFFF;
          var a16 = this.low >>> 16;
          var a00 = this.low & 0xFFFF;
  
          var b48 = multiplier.high >>> 16;
          var b32 = multiplier.high & 0xFFFF;
          var b16 = multiplier.low >>> 16;
          var b00 = multiplier.low & 0xFFFF;
  
          var c48 = 0, c32 = 0, c16 = 0, c00 = 0;
          c00 += a00 * b00;
          c16 += c00 >>> 16;
          c00 &= 0xFFFF;
          c16 += a16 * b00;
          c32 += c16 >>> 16;
          c16 &= 0xFFFF;
          c16 += a00 * b16;
          c32 += c16 >>> 16;
          c16 &= 0xFFFF;
          c32 += a32 * b00;
          c48 += c32 >>> 16;
          c32 &= 0xFFFF;
          c32 += a16 * b16;
          c48 += c32 >>> 16;
          c32 &= 0xFFFF;
          c32 += a00 * b32;
          c48 += c32 >>> 16;
          c32 &= 0xFFFF;
          c48 += a48 * b00 + a32 * b16 + a16 * b32 + a00 * b48;
          c48 &= 0xFFFF;
          return fromBits((c16 << 16) | c00, (c48 << 16) | c32, this.unsigned);
      };
  
      /**
       * Returns the product of this and the specified Long. This is an alias of {@link Long#multiply}.
       * @function
       * @param {!Long|number|string} multiplier Multiplier
       * @returns {!Long} Product
       */
      LongPrototype.mul = LongPrototype.multiply;
  
      /**
       * Returns this Long divided by the specified. The result is signed if this Long is signed or
       *  unsigned if this Long is unsigned.
       * @param {!Long|number|string} divisor Divisor
       * @returns {!Long} Quotient
       */
      LongPrototype.divide = function divide(divisor) {
          if (!isLong(divisor))
              divisor = fromValue(divisor);
          if (divisor.isZero())
              throw Error('division by zero');
          if (this.isZero())
              return this.unsigned ? UZERO : ZERO;
          var approx, rem, res;
          if (!this.unsigned) {
              // This section is only relevant for signed longs and is derived from the
              // closure library as a whole.
              if (this.eq(MIN_VALUE)) {
                  if (divisor.eq(ONE) || divisor.eq(NEG_ONE))
                      return MIN_VALUE;  // recall that -MIN_VALUE == MIN_VALUE
                  else if (divisor.eq(MIN_VALUE))
                      return ONE;
                  else {
                      // At this point, we have |other| >= 2, so |this/other| < |MIN_VALUE|.
                      var halfThis = this.shr(1);
                      approx = halfThis.div(divisor).shl(1);
                      if (approx.eq(ZERO)) {
                          return divisor.isNegative() ? ONE : NEG_ONE;
                      } else {
                          rem = this.sub(divisor.mul(approx));
                          res = approx.add(rem.div(divisor));
                          return res;
                      }
                  }
              } else if (divisor.eq(MIN_VALUE))
                  return this.unsigned ? UZERO : ZERO;
              if (this.isNegative()) {
                  if (divisor.isNegative())
                      return this.neg().div(divisor.neg());
                  return this.neg().div(divisor).neg();
              } else if (divisor.isNegative())
                  return this.div(divisor.neg()).neg();
              res = ZERO;
          } else {
              // The algorithm below has not been made for unsigned longs. It's therefore
              // required to take special care of the MSB prior to running it.
              if (!divisor.unsigned)
                  divisor = divisor.toUnsigned();
              if (divisor.gt(this))
                  return UZERO;
              if (divisor.gt(this.shru(1))) // 15 >>> 1 = 7 ; with divisor = 8 ; true
                  return UONE;
              res = UZERO;
          }
  
          // Repeat the following until the remainder is less than other:  find a
          // floating-point that approximates remainder / other *from below*, add this
          // into the result, and subtract it from the remainder.  It is critical that
          // the approximate value is less than or equal to the real value so that the
          // remainder never becomes negative.
          rem = this;
          while (rem.gte(divisor)) {
              // Approximate the result of division. This may be a little greater or
              // smaller than the actual value.
              approx = Math.max(1, Math.floor(rem.toNumber() / divisor.toNumber()));
  
              // We will tweak the approximate result by changing it in the 48-th digit or
              // the smallest non-fractional digit, whichever is larger.
              var log2 = Math.ceil(Math.log(approx) / Math.LN2),
                  delta = (log2 <= 48) ? 1 : pow_dbl(2, log2 - 48),
  
              // Decrease the approximation until it is smaller than the remainder.  Note
              // that if it is too large, the product overflows and is negative.
                  approxRes = fromNumber(approx),
                  approxRem = approxRes.mul(divisor);
              while (approxRem.isNegative() || approxRem.gt(rem)) {
                  approx -= delta;
                  approxRes = fromNumber(approx, this.unsigned);
                  approxRem = approxRes.mul(divisor);
              }
  
              // We know the answer can't be zero... and actually, zero would cause
              // infinite recursion since we would make no progress.
              if (approxRes.isZero())
                  approxRes = ONE;
  
              res = res.add(approxRes);
              rem = rem.sub(approxRem);
          }
          return res;
      };
  
      /**
       * Returns this Long divided by the specified. This is an alias of {@link Long#divide}.
       * @function
       * @param {!Long|number|string} divisor Divisor
       * @returns {!Long} Quotient
       */
      LongPrototype.div = LongPrototype.divide;
  
      /**
       * Returns this Long modulo the specified.
       * @param {!Long|number|string} divisor Divisor
       * @returns {!Long} Remainder
       */
      LongPrototype.modulo = function modulo(divisor) {
          if (!isLong(divisor))
              divisor = fromValue(divisor);
          return this.sub(this.div(divisor).mul(divisor));
      };
  
      /**
       * Returns this Long modulo the specified. This is an alias of {@link Long#modulo}.
       * @function
       * @param {!Long|number|string} divisor Divisor
       * @returns {!Long} Remainder
       */
      LongPrototype.mod = LongPrototype.modulo;
  
      /**
       * Returns the bitwise NOT of this Long.
       * @returns {!Long}
       */
      LongPrototype.not = function not() {
          return fromBits(~this.low, ~this.high, this.unsigned);
      };
  
      /**
       * Returns the bitwise AND of this Long and the specified.
       * @param {!Long|number|string} other Other Long
       * @returns {!Long}
       */
      LongPrototype.and = function and(other) {
          if (!isLong(other))
              other = fromValue(other);
          return fromBits(this.low & other.low, this.high & other.high, this.unsigned);
      };
  
      /**
       * Returns the bitwise OR of this Long and the specified.
       * @param {!Long|number|string} other Other Long
       * @returns {!Long}
       */
      LongPrototype.or = function or(other) {
          if (!isLong(other))
              other = fromValue(other);
          return fromBits(this.low | other.low, this.high | other.high, this.unsigned);
      };
  
      /**
       * Returns the bitwise XOR of this Long and the given one.
       * @param {!Long|number|string} other Other Long
       * @returns {!Long}
       */
      LongPrototype.xor = function xor(other) {
          if (!isLong(other))
              other = fromValue(other);
          return fromBits(this.low ^ other.low, this.high ^ other.high, this.unsigned);
      };
  
      /**
       * Returns this Long with bits shifted to the left by the given amount.
       * @param {number|!Long} numBits Number of bits
       * @returns {!Long} Shifted Long
       */
      LongPrototype.shiftLeft = function shiftLeft(numBits) {
          if (isLong(numBits))
              numBits = numBits.toInt();
          if ((numBits &= 63) === 0)
              return this;
          else if (numBits < 32)
              return fromBits(this.low << numBits, (this.high << numBits) | (this.low >>> (32 - numBits)), this.unsigned);
          else
              return fromBits(0, this.low << (numBits - 32), this.unsigned);
      };
  
      /**
       * Returns this Long with bits shifted to the left by the given amount. This is an alias of {@link Long#shiftLeft}.
       * @function
       * @param {number|!Long} numBits Number of bits
       * @returns {!Long} Shifted Long
       */
      LongPrototype.shl = LongPrototype.shiftLeft;
  
      /**
       * Returns this Long with bits arithmetically shifted to the right by the given amount.
       * @param {number|!Long} numBits Number of bits
       * @returns {!Long} Shifted Long
       */
      LongPrototype.shiftRight = function shiftRight(numBits) {
          if (isLong(numBits))
              numBits = numBits.toInt();
          if ((numBits &= 63) === 0)
              return this;
          else if (numBits < 32)
              return fromBits((this.low >>> numBits) | (this.high << (32 - numBits)), this.high >> numBits, this.unsigned);
          else
              return fromBits(this.high >> (numBits - 32), this.high >= 0 ? 0 : -1, this.unsigned);
      };
  
      /**
       * Returns this Long with bits arithmetically shifted to the right by the given amount. This is an alias of {@link Long#shiftRight}.
       * @function
       * @param {number|!Long} numBits Number of bits
       * @returns {!Long} Shifted Long
       */
      LongPrototype.shr = LongPrototype.shiftRight;
  
      /**
       * Returns this Long with bits logically shifted to the right by the given amount.
       * @param {number|!Long} numBits Number of bits
       * @returns {!Long} Shifted Long
       */
      LongPrototype.shiftRightUnsigned = function shiftRightUnsigned(numBits) {
          if (isLong(numBits))
              numBits = numBits.toInt();
          numBits &= 63;
          if (numBits === 0)
              return this;
          else {
              var high = this.high;
              if (numBits < 32) {
                  var low = this.low;
                  return fromBits((low >>> numBits) | (high << (32 - numBits)), high >>> numBits, this.unsigned);
              } else if (numBits === 32)
                  return fromBits(high, 0, this.unsigned);
              else
                  return fromBits(high >>> (numBits - 32), 0, this.unsigned);
          }
      };
  
      /**
       * Returns this Long with bits logically shifted to the right by the given amount. This is an alias of {@link Long#shiftRightUnsigned}.
       * @function
       * @param {number|!Long} numBits Number of bits
       * @returns {!Long} Shifted Long
       */
      LongPrototype.shru = LongPrototype.shiftRightUnsigned;
  
      /**
       * Converts this Long to signed.
       * @returns {!Long} Signed long
       */
      LongPrototype.toSigned = function toSigned() {
          if (!this.unsigned)
              return this;
          return fromBits(this.low, this.high, false);
      };
  
      /**
       * Converts this Long to unsigned.
       * @returns {!Long} Unsigned long
       */
      LongPrototype.toUnsigned = function toUnsigned() {
          if (this.unsigned)
              return this;
          return fromBits(this.low, this.high, true);
      };
  
      /**
       * Converts this Long to its byte representation.
       * @param {boolean=} le Whether little or big endian, defaults to big endian
       * @returns {!Array.<number>} Byte representation
       */
      LongPrototype.toBytes = function(le) {
          return le ? this.toBytesLE() : this.toBytesBE();
      }
  
      /**
       * Converts this Long to its little endian byte representation.
       * @returns {!Array.<number>} Little endian byte representation
       */
      LongPrototype.toBytesLE = function() {
          var hi = this.high,
              lo = this.low;
          return [
               lo         & 0xff,
              (lo >>>  8) & 0xff,
              (lo >>> 16) & 0xff,
              (lo >>> 24) & 0xff,
               hi         & 0xff,
              (hi >>>  8) & 0xff,
              (hi >>> 16) & 0xff,
              (hi >>> 24) & 0xff
          ];
      }
  
      /**
       * Converts this Long to its big endian byte representation.
       * @returns {!Array.<number>} Big endian byte representation
       */
      LongPrototype.toBytesBE = function() {
          var hi = this.high,
              lo = this.low;
          return [
              (hi >>> 24) & 0xff,
              (hi >>> 16) & 0xff,
              (hi >>>  8) & 0xff,
               hi         & 0xff,
              (lo >>> 24) & 0xff,
              (lo >>> 16) & 0xff,
              (lo >>>  8) & 0xff,
               lo         & 0xff
          ];
      }
  
      return Long;
  });
  
  },{}],65:[function(require,module,exports){
  (function (Buffer){
  /*
  CryptoJS v3.1.2
  code.google.com/p/crypto-js
  (c) 2009-2013 by Jeff Mott. All rights reserved.
  code.google.com/p/crypto-js/wiki/License
  */
  /** @preserve
  (c) 2012 by Cédric Mesnil. All rights reserved.
  
  Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
  
      - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
      - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
  
  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
  
  // constants table
  var zl = [
    0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
    7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8,
    3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12,
    1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2,
    4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13
  ]
  
  var zr = [
    5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12,
    6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2,
    15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13,
    8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14,
    12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11
  ]
  
  var sl = [
    11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8,
    7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12,
    11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5,
    11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12,
    9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6
  ]
  
  var sr = [
    8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6,
    9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11,
    9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5,
    15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8,
    8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11
  ]
  
  var hl = [0x00000000, 0x5A827999, 0x6ED9EBA1, 0x8F1BBCDC, 0xA953FD4E]
  var hr = [0x50A28BE6, 0x5C4DD124, 0x6D703EF3, 0x7A6D76E9, 0x00000000]
  
  function bytesToWords (bytes) {
    var words = []
    for (var i = 0, b = 0; i < bytes.length; i++, b += 8) {
      words[b >>> 5] |= bytes[i] << (24 - b % 32)
    }
    return words
  }
  
  function wordsToBytes (words) {
    var bytes = []
    for (var b = 0; b < words.length * 32; b += 8) {
      bytes.push((words[b >>> 5] >>> (24 - b % 32)) & 0xFF)
    }
    return bytes
  }
  
  function processBlock (H, M, offset) {
    // swap endian
    for (var i = 0; i < 16; i++) {
      var offset_i = offset + i
      var M_offset_i = M[offset_i]
  
      // Swap
      M[offset_i] = (
        (((M_offset_i << 8) | (M_offset_i >>> 24)) & 0x00ff00ff) |
        (((M_offset_i << 24) | (M_offset_i >>> 8)) & 0xff00ff00)
      )
    }
  
    // Working variables
    var al, bl, cl, dl, el
    var ar, br, cr, dr, er
  
    ar = al = H[0]
    br = bl = H[1]
    cr = cl = H[2]
    dr = dl = H[3]
    er = el = H[4]
  
    // computation
    var t
    for (i = 0; i < 80; i += 1) {
      t = (al + M[offset + zl[i]]) | 0
      if (i < 16) {
        t += f1(bl, cl, dl) + hl[0]
      } else if (i < 32) {
        t += f2(bl, cl, dl) + hl[1]
      } else if (i < 48) {
        t += f3(bl, cl, dl) + hl[2]
      } else if (i < 64) {
        t += f4(bl, cl, dl) + hl[3]
      } else {// if (i<80) {
        t += f5(bl, cl, dl) + hl[4]
      }
      t = t | 0
      t = rotl(t, sl[i])
      t = (t + el) | 0
      al = el
      el = dl
      dl = rotl(cl, 10)
      cl = bl
      bl = t
  
      t = (ar + M[offset + zr[i]]) | 0
      if (i < 16) {
        t += f5(br, cr, dr) + hr[0]
      } else if (i < 32) {
        t += f4(br, cr, dr) + hr[1]
      } else if (i < 48) {
        t += f3(br, cr, dr) + hr[2]
      } else if (i < 64) {
        t += f2(br, cr, dr) + hr[3]
      } else {// if (i<80) {
        t += f1(br, cr, dr) + hr[4]
      }
  
      t = t | 0
      t = rotl(t, sr[i])
      t = (t + er) | 0
      ar = er
      er = dr
      dr = rotl(cr, 10)
      cr = br
      br = t
    }
  
    // intermediate hash value
    t = (H[1] + cl + dr) | 0
    H[1] = (H[2] + dl + er) | 0
    H[2] = (H[3] + el + ar) | 0
    H[3] = (H[4] + al + br) | 0
    H[4] = (H[0] + bl + cr) | 0
    H[0] = t
  }
  
  function f1 (x, y, z) {
    return ((x) ^ (y) ^ (z))
  }
  
  function f2 (x, y, z) {
    return (((x) & (y)) | ((~x) & (z)))
  }
  
  function f3 (x, y, z) {
    return (((x) | (~(y))) ^ (z))
  }
  
  function f4 (x, y, z) {
    return (((x) & (z)) | ((y) & (~(z))))
  }
  
  function f5 (x, y, z) {
    return ((x) ^ ((y) | (~(z))))
  }
  
  function rotl (x, n) {
    return (x << n) | (x >>> (32 - n))
  }
  
  function ripemd160 (message) {
    var H = [0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0]
  
    if (typeof message === 'string') {
      message = new Buffer(message, 'utf8')
    }
  
    var m = bytesToWords(message)
  
    var nBitsLeft = message.length * 8
    var nBitsTotal = message.length * 8
  
    // Add padding
    m[nBitsLeft >>> 5] |= 0x80 << (24 - nBitsLeft % 32)
    m[(((nBitsLeft + 64) >>> 9) << 4) + 14] = (
      (((nBitsTotal << 8) | (nBitsTotal >>> 24)) & 0x00ff00ff) |
      (((nBitsTotal << 24) | (nBitsTotal >>> 8)) & 0xff00ff00)
    )
  
    for (var i = 0; i < m.length; i += 16) {
      processBlock(H, m, i)
    }
  
    // swap endian
    for (i = 0; i < 5; i++) {
      // shortcut
      var H_i = H[i]
  
      // Swap
      H[i] = (((H_i << 8) | (H_i >>> 24)) & 0x00ff00ff) |
        (((H_i << 24) | (H_i >>> 8)) & 0xff00ff00)
    }
  
    var digestbytes = wordsToBytes(H)
    return new Buffer(digestbytes)
  }
  
  module.exports = ripemd160
  
  }).call(this,require("buffer").Buffer)
  },{"buffer":79}],66:[function(require,module,exports){
  (function (process,Buffer){
  !function(globals){
  'use strict'
  
  //*** UMD BEGIN
  if (typeof define !== 'undefined' && define.amd) { //require.js / AMD
    define([], function() {
      return secureRandom
    })
  } else if (typeof module !== 'undefined' && module.exports) { //CommonJS
    module.exports = secureRandom
  } else { //script / browser
    globals.secureRandom = secureRandom
  }
  //*** UMD END
  
  //options.type is the only valid option
  function secureRandom(count, options) {
    options = options || {type: 'Array'}
    //we check for process.pid to prevent browserify from tricking us
    if (typeof process != 'undefined' && typeof process.pid == 'number') {
      return nodeRandom(count, options)
    } else {
      var crypto = window.crypto || window.msCrypto
      if (!crypto) throw new Error("Your browser does not support window.crypto.")
      return browserRandom(count, options)
    }
  }
  
  function nodeRandom(count, options) {
    var crypto = require('crypto')
    var buf = crypto.randomBytes(count)
  
    switch (options.type) {
      case 'Array':
        return [].slice.call(buf)
      case 'Buffer':
        return buf
      case 'Uint8Array':
        var arr = new Uint8Array(count)
        for (var i = 0; i < count; ++i) { arr[i] = buf.readUInt8(i) }
        return arr
      default:
        throw new Error(options.type + " is unsupported.")
    }
  }
  
  function browserRandom(count, options) {
    var nativeArr = new Uint8Array(count)
    var crypto = window.crypto || window.msCrypto
    crypto.getRandomValues(nativeArr)
  
    switch (options.type) {
      case 'Array':
        return [].slice.call(nativeArr)
      case 'Buffer':
        try { var b = new Buffer(1) } catch(e) { throw new Error('Buffer not supported in this environment. Use Node.js or Browserify for browser support.')}
        return new Buffer(nativeArr)
      case 'Uint8Array':
        return nativeArr
      default:
        throw new Error(options.type + " is unsupported.")
    }
  }
  
  secureRandom.randomArray = function(byteCount) {
    return secureRandom(byteCount, {type: 'Array'})
  }
  
  secureRandom.randomUint8Array = function(byteCount) {
    return secureRandom(byteCount, {type: 'Uint8Array'})
  }
  
  secureRandom.randomBuffer = function(byteCount) {
    return secureRandom(byteCount, {type: 'Buffer'})
  }
  
  
  }(this);
  
  }).call(this,require('_process'),require("buffer").Buffer)
  },{"_process":87,"buffer":79,"crypto":77}],67:[function(require,module,exports){
  (function (Buffer){
  // prototype class for hash functions
  function Hash (blockSize, finalSize) {
    this._block = new Buffer(blockSize)
    this._finalSize = finalSize
    this._blockSize = blockSize
    this._len = 0
    this._s = 0
  }
  
  Hash.prototype.update = function (data, enc) {
    if (typeof data === 'string') {
      enc = enc || 'utf8'
      data = new Buffer(data, enc)
    }
  
    var l = this._len += data.length
    var s = this._s || 0
    var f = 0
    var buffer = this._block
  
    while (s < l) {
      var t = Math.min(data.length, f + this._blockSize - (s % this._blockSize))
      var ch = (t - f)
  
      for (var i = 0; i < ch; i++) {
        buffer[(s % this._blockSize) + i] = data[i + f]
      }
  
      s += ch
      f += ch
  
      if ((s % this._blockSize) === 0) {
        this._update(buffer)
      }
    }
    this._s = s
  
    return this
  }
  
  Hash.prototype.digest = function (enc) {
    // Suppose the length of the message M, in bits, is l
    var l = this._len * 8
  
    // Append the bit 1 to the end of the message
    this._block[this._len % this._blockSize] = 0x80
  
    // and then k zero bits, where k is the smallest non-negative solution to the equation (l + 1 + k) === finalSize mod blockSize
    this._block.fill(0, this._len % this._blockSize + 1)
  
    if (l % (this._blockSize * 8) >= this._finalSize * 8) {
      this._update(this._block)
      this._block.fill(0)
    }
  
    // to this append the block which is equal to the number l written in binary
    // TODO: handle case where l is > Math.pow(2, 29)
    this._block.writeInt32BE(l, this._blockSize - 4)
  
    var hash = this._update(this._block) || this._hash()
  
    return enc ? hash.toString(enc) : hash
  }
  
  Hash.prototype._update = function () {
    throw new Error('_update must be implemented by subclass')
  }
  
  module.exports = Hash
  
  }).call(this,require("buffer").Buffer)
  },{"buffer":79}],68:[function(require,module,exports){
  var exports = module.exports = function SHA (algorithm) {
    algorithm = algorithm.toLowerCase()
  
    var Algorithm = exports[algorithm]
    if (!Algorithm) throw new Error(algorithm + ' is not supported (we accept pull requests)')
  
    return new Algorithm()
  }
  
  exports.sha = require('./sha')
  exports.sha1 = require('./sha1')
  exports.sha224 = require('./sha224')
  exports.sha256 = require('./sha256')
  exports.sha384 = require('./sha384')
  exports.sha512 = require('./sha512')
  
  },{"./sha":69,"./sha1":70,"./sha224":71,"./sha256":72,"./sha384":73,"./sha512":74}],69:[function(require,module,exports){
  (function (Buffer){
  /*
   * A JavaScript implementation of the Secure Hash Algorithm, SHA-0, as defined
   * in FIPS PUB 180-1
   * This source code is derived from sha1.js of the same repository.
   * The difference between SHA-0 and SHA-1 is just a bitwise rotate left
   * operation was added.
   */
  
  var inherits = require('inherits')
  var Hash = require('./hash')
  
  var K = [
    0x5a827999, 0x6ed9eba1, 0x8f1bbcdc | 0, 0xca62c1d6 | 0
  ]
  
  var W = new Array(80)
  
  function Sha () {
    this.init()
    this._w = W
  
    Hash.call(this, 64, 56)
  }
  
  inherits(Sha, Hash)
  
  Sha.prototype.init = function () {
    this._a = 0x67452301
    this._b = 0xefcdab89
    this._c = 0x98badcfe
    this._d = 0x10325476
    this._e = 0xc3d2e1f0
  
    return this
  }
  
  function rotl5 (num) {
    return (num << 5) | (num >>> 27)
  }
  
  function rotl30 (num) {
    return (num << 30) | (num >>> 2)
  }
  
  function ft (s, b, c, d) {
    if (s === 0) return (b & c) | ((~b) & d)
    if (s === 2) return (b & c) | (b & d) | (c & d)
    return b ^ c ^ d
  }
  
  Sha.prototype._update = function (M) {
    var W = this._w
  
    var a = this._a | 0
    var b = this._b | 0
    var c = this._c | 0
    var d = this._d | 0
    var e = this._e | 0
  
    for (var i = 0; i < 16; ++i) W[i] = M.readInt32BE(i * 4)
    for (; i < 80; ++i) W[i] = W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16]
  
    for (var j = 0; j < 80; ++j) {
      var s = ~~(j / 20)
      var t = (rotl5(a) + ft(s, b, c, d) + e + W[j] + K[s]) | 0
  
      e = d
      d = c
      c = rotl30(b)
      b = a
      a = t
    }
  
    this._a = (a + this._a) | 0
    this._b = (b + this._b) | 0
    this._c = (c + this._c) | 0
    this._d = (d + this._d) | 0
    this._e = (e + this._e) | 0
  }
  
  Sha.prototype._hash = function () {
    var H = new Buffer(20)
  
    H.writeInt32BE(this._a | 0, 0)
    H.writeInt32BE(this._b | 0, 4)
    H.writeInt32BE(this._c | 0, 8)
    H.writeInt32BE(this._d | 0, 12)
    H.writeInt32BE(this._e | 0, 16)
  
    return H
  }
  
  module.exports = Sha
  
  }).call(this,require("buffer").Buffer)
  },{"./hash":67,"buffer":79,"inherits":63}],70:[function(require,module,exports){
  (function (Buffer){
  /*
   * A JavaScript implementation of the Secure Hash Algorithm, SHA-1, as defined
   * in FIPS PUB 180-1
   * Version 2.1a Copyright Paul Johnston 2000 - 2002.
   * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
   * Distributed under the BSD License
   * See http://pajhome.org.uk/crypt/md5 for details.
   */
  
  var inherits = require('inherits')
  var Hash = require('./hash')
  
  var K = [
    0x5a827999, 0x6ed9eba1, 0x8f1bbcdc | 0, 0xca62c1d6 | 0
  ]
  
  var W = new Array(80)
  
  function Sha1 () {
    this.init()
    this._w = W
  
    Hash.call(this, 64, 56)
  }
  
  inherits(Sha1, Hash)
  
  Sha1.prototype.init = function () {
    this._a = 0x67452301
    this._b = 0xefcdab89
    this._c = 0x98badcfe
    this._d = 0x10325476
    this._e = 0xc3d2e1f0
  
    return this
  }
  
  function rotl1 (num) {
    return (num << 1) | (num >>> 31)
  }
  
  function rotl5 (num) {
    return (num << 5) | (num >>> 27)
  }
  
  function rotl30 (num) {
    return (num << 30) | (num >>> 2)
  }
  
  function ft (s, b, c, d) {
    if (s === 0) return (b & c) | ((~b) & d)
    if (s === 2) return (b & c) | (b & d) | (c & d)
    return b ^ c ^ d
  }
  
  Sha1.prototype._update = function (M) {
    var W = this._w
  
    var a = this._a | 0
    var b = this._b | 0
    var c = this._c | 0
    var d = this._d | 0
    var e = this._e | 0
  
    for (var i = 0; i < 16; ++i) W[i] = M.readInt32BE(i * 4)
    for (; i < 80; ++i) W[i] = rotl1(W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16])
  
    for (var j = 0; j < 80; ++j) {
      var s = ~~(j / 20)
      var t = (rotl5(a) + ft(s, b, c, d) + e + W[j] + K[s]) | 0
  
      e = d
      d = c
      c = rotl30(b)
      b = a
      a = t
    }
  
    this._a = (a + this._a) | 0
    this._b = (b + this._b) | 0
    this._c = (c + this._c) | 0
    this._d = (d + this._d) | 0
    this._e = (e + this._e) | 0
  }
  
  Sha1.prototype._hash = function () {
    var H = new Buffer(20)
  
    H.writeInt32BE(this._a | 0, 0)
    H.writeInt32BE(this._b | 0, 4)
    H.writeInt32BE(this._c | 0, 8)
    H.writeInt32BE(this._d | 0, 12)
    H.writeInt32BE(this._e | 0, 16)
  
    return H
  }
  
  module.exports = Sha1
  
  }).call(this,require("buffer").Buffer)
  },{"./hash":67,"buffer":79,"inherits":63}],71:[function(require,module,exports){
  (function (Buffer){
  /**
   * A JavaScript implementation of the Secure Hash Algorithm, SHA-256, as defined
   * in FIPS 180-2
   * Version 2.2-beta Copyright Angel Marin, Paul Johnston 2000 - 2009.
   * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
   *
   */
  
  var inherits = require('inherits')
  var Sha256 = require('./sha256')
  var Hash = require('./hash')
  
  var W = new Array(64)
  
  function Sha224 () {
    this.init()
  
    this._w = W // new Array(64)
  
    Hash.call(this, 64, 56)
  }
  
  inherits(Sha224, Sha256)
  
  Sha224.prototype.init = function () {
    this._a = 0xc1059ed8
    this._b = 0x367cd507
    this._c = 0x3070dd17
    this._d = 0xf70e5939
    this._e = 0xffc00b31
    this._f = 0x68581511
    this._g = 0x64f98fa7
    this._h = 0xbefa4fa4
  
    return this
  }
  
  Sha224.prototype._hash = function () {
    var H = new Buffer(28)
  
    H.writeInt32BE(this._a, 0)
    H.writeInt32BE(this._b, 4)
    H.writeInt32BE(this._c, 8)
    H.writeInt32BE(this._d, 12)
    H.writeInt32BE(this._e, 16)
    H.writeInt32BE(this._f, 20)
    H.writeInt32BE(this._g, 24)
  
    return H
  }
  
  module.exports = Sha224
  
  }).call(this,require("buffer").Buffer)
  },{"./hash":67,"./sha256":72,"buffer":79,"inherits":63}],72:[function(require,module,exports){
  (function (Buffer){
  /**
   * A JavaScript implementation of the Secure Hash Algorithm, SHA-256, as defined
   * in FIPS 180-2
   * Version 2.2-beta Copyright Angel Marin, Paul Johnston 2000 - 2009.
   * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
   *
   */
  
  var inherits = require('inherits')
  var Hash = require('./hash')
  
  var K = [
    0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5,
    0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5,
    0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3,
    0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174,
    0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC,
    0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA,
    0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7,
    0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967,
    0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13,
    0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85,
    0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3,
    0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070,
    0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5,
    0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3,
    0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208,
    0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2
  ]
  
  var W = new Array(64)
  
  function Sha256 () {
    this.init()
  
    this._w = W // new Array(64)
  
    Hash.call(this, 64, 56)
  }
  
  inherits(Sha256, Hash)
  
  Sha256.prototype.init = function () {
    this._a = 0x6a09e667
    this._b = 0xbb67ae85
    this._c = 0x3c6ef372
    this._d = 0xa54ff53a
    this._e = 0x510e527f
    this._f = 0x9b05688c
    this._g = 0x1f83d9ab
    this._h = 0x5be0cd19
  
    return this
  }
  
  function ch (x, y, z) {
    return z ^ (x & (y ^ z))
  }
  
  function maj (x, y, z) {
    return (x & y) | (z & (x | y))
  }
  
  function sigma0 (x) {
    return (x >>> 2 | x << 30) ^ (x >>> 13 | x << 19) ^ (x >>> 22 | x << 10)
  }
  
  function sigma1 (x) {
    return (x >>> 6 | x << 26) ^ (x >>> 11 | x << 21) ^ (x >>> 25 | x << 7)
  }
  
  function gamma0 (x) {
    return (x >>> 7 | x << 25) ^ (x >>> 18 | x << 14) ^ (x >>> 3)
  }
  
  function gamma1 (x) {
    return (x >>> 17 | x << 15) ^ (x >>> 19 | x << 13) ^ (x >>> 10)
  }
  
  Sha256.prototype._update = function (M) {
    var W = this._w
  
    var a = this._a | 0
    var b = this._b | 0
    var c = this._c | 0
    var d = this._d | 0
    var e = this._e | 0
    var f = this._f | 0
    var g = this._g | 0
    var h = this._h | 0
  
    for (var i = 0; i < 16; ++i) W[i] = M.readInt32BE(i * 4)
    for (; i < 64; ++i) W[i] = (gamma1(W[i - 2]) + W[i - 7] + gamma0(W[i - 15]) + W[i - 16]) | 0
  
    for (var j = 0; j < 64; ++j) {
      var T1 = (h + sigma1(e) + ch(e, f, g) + K[j] + W[j]) | 0
      var T2 = (sigma0(a) + maj(a, b, c)) | 0
  
      h = g
      g = f
      f = e
      e = (d + T1) | 0
      d = c
      c = b
      b = a
      a = (T1 + T2) | 0
    }
  
    this._a = (a + this._a) | 0
    this._b = (b + this._b) | 0
    this._c = (c + this._c) | 0
    this._d = (d + this._d) | 0
    this._e = (e + this._e) | 0
    this._f = (f + this._f) | 0
    this._g = (g + this._g) | 0
    this._h = (h + this._h) | 0
  }
  
  Sha256.prototype._hash = function () {
    var H = new Buffer(32)
  
    H.writeInt32BE(this._a, 0)
    H.writeInt32BE(this._b, 4)
    H.writeInt32BE(this._c, 8)
    H.writeInt32BE(this._d, 12)
    H.writeInt32BE(this._e, 16)
    H.writeInt32BE(this._f, 20)
    H.writeInt32BE(this._g, 24)
    H.writeInt32BE(this._h, 28)
  
    return H
  }
  
  module.exports = Sha256
  
  }).call(this,require("buffer").Buffer)
  },{"./hash":67,"buffer":79,"inherits":63}],73:[function(require,module,exports){
  (function (Buffer){
  var inherits = require('inherits')
  var SHA512 = require('./sha512')
  var Hash = require('./hash')
  
  var W = new Array(160)
  
  function Sha384 () {
    this.init()
    this._w = W
  
    Hash.call(this, 128, 112)
  }
  
  inherits(Sha384, SHA512)
  
  Sha384.prototype.init = function () {
    this._ah = 0xcbbb9d5d
    this._bh = 0x629a292a
    this._ch = 0x9159015a
    this._dh = 0x152fecd8
    this._eh = 0x67332667
    this._fh = 0x8eb44a87
    this._gh = 0xdb0c2e0d
    this._hh = 0x47b5481d
  
    this._al = 0xc1059ed8
    this._bl = 0x367cd507
    this._cl = 0x3070dd17
    this._dl = 0xf70e5939
    this._el = 0xffc00b31
    this._fl = 0x68581511
    this._gl = 0x64f98fa7
    this._hl = 0xbefa4fa4
  
    return this
  }
  
  Sha384.prototype._hash = function () {
    var H = new Buffer(48)
  
    function writeInt64BE (h, l, offset) {
      H.writeInt32BE(h, offset)
      H.writeInt32BE(l, offset + 4)
    }
  
    writeInt64BE(this._ah, this._al, 0)
    writeInt64BE(this._bh, this._bl, 8)
    writeInt64BE(this._ch, this._cl, 16)
    writeInt64BE(this._dh, this._dl, 24)
    writeInt64BE(this._eh, this._el, 32)
    writeInt64BE(this._fh, this._fl, 40)
  
    return H
  }
  
  module.exports = Sha384
  
  }).call(this,require("buffer").Buffer)
  },{"./hash":67,"./sha512":74,"buffer":79,"inherits":63}],74:[function(require,module,exports){
  (function (Buffer){
  var inherits = require('inherits')
  var Hash = require('./hash')
  
  var K = [
    0x428a2f98, 0xd728ae22, 0x71374491, 0x23ef65cd,
    0xb5c0fbcf, 0xec4d3b2f, 0xe9b5dba5, 0x8189dbbc,
    0x3956c25b, 0xf348b538, 0x59f111f1, 0xb605d019,
    0x923f82a4, 0xaf194f9b, 0xab1c5ed5, 0xda6d8118,
    0xd807aa98, 0xa3030242, 0x12835b01, 0x45706fbe,
    0x243185be, 0x4ee4b28c, 0x550c7dc3, 0xd5ffb4e2,
    0x72be5d74, 0xf27b896f, 0x80deb1fe, 0x3b1696b1,
    0x9bdc06a7, 0x25c71235, 0xc19bf174, 0xcf692694,
    0xe49b69c1, 0x9ef14ad2, 0xefbe4786, 0x384f25e3,
    0x0fc19dc6, 0x8b8cd5b5, 0x240ca1cc, 0x77ac9c65,
    0x2de92c6f, 0x592b0275, 0x4a7484aa, 0x6ea6e483,
    0x5cb0a9dc, 0xbd41fbd4, 0x76f988da, 0x831153b5,
    0x983e5152, 0xee66dfab, 0xa831c66d, 0x2db43210,
    0xb00327c8, 0x98fb213f, 0xbf597fc7, 0xbeef0ee4,
    0xc6e00bf3, 0x3da88fc2, 0xd5a79147, 0x930aa725,
    0x06ca6351, 0xe003826f, 0x14292967, 0x0a0e6e70,
    0x27b70a85, 0x46d22ffc, 0x2e1b2138, 0x5c26c926,
    0x4d2c6dfc, 0x5ac42aed, 0x53380d13, 0x9d95b3df,
    0x650a7354, 0x8baf63de, 0x766a0abb, 0x3c77b2a8,
    0x81c2c92e, 0x47edaee6, 0x92722c85, 0x1482353b,
    0xa2bfe8a1, 0x4cf10364, 0xa81a664b, 0xbc423001,
    0xc24b8b70, 0xd0f89791, 0xc76c51a3, 0x0654be30,
    0xd192e819, 0xd6ef5218, 0xd6990624, 0x5565a910,
    0xf40e3585, 0x5771202a, 0x106aa070, 0x32bbd1b8,
    0x19a4c116, 0xb8d2d0c8, 0x1e376c08, 0x5141ab53,
    0x2748774c, 0xdf8eeb99, 0x34b0bcb5, 0xe19b48a8,
    0x391c0cb3, 0xc5c95a63, 0x4ed8aa4a, 0xe3418acb,
    0x5b9cca4f, 0x7763e373, 0x682e6ff3, 0xd6b2b8a3,
    0x748f82ee, 0x5defb2fc, 0x78a5636f, 0x43172f60,
    0x84c87814, 0xa1f0ab72, 0x8cc70208, 0x1a6439ec,
    0x90befffa, 0x23631e28, 0xa4506ceb, 0xde82bde9,
    0xbef9a3f7, 0xb2c67915, 0xc67178f2, 0xe372532b,
    0xca273ece, 0xea26619c, 0xd186b8c7, 0x21c0c207,
    0xeada7dd6, 0xcde0eb1e, 0xf57d4f7f, 0xee6ed178,
    0x06f067aa, 0x72176fba, 0x0a637dc5, 0xa2c898a6,
    0x113f9804, 0xbef90dae, 0x1b710b35, 0x131c471b,
    0x28db77f5, 0x23047d84, 0x32caab7b, 0x40c72493,
    0x3c9ebe0a, 0x15c9bebc, 0x431d67c4, 0x9c100d4c,
    0x4cc5d4be, 0xcb3e42b6, 0x597f299c, 0xfc657e2a,
    0x5fcb6fab, 0x3ad6faec, 0x6c44198c, 0x4a475817
  ]
  
  var W = new Array(160)
  
  function Sha512 () {
    this.init()
    this._w = W
  
    Hash.call(this, 128, 112)
  }
  
  inherits(Sha512, Hash)
  
  Sha512.prototype.init = function () {
    this._ah = 0x6a09e667
    this._bh = 0xbb67ae85
    this._ch = 0x3c6ef372
    this._dh = 0xa54ff53a
    this._eh = 0x510e527f
    this._fh = 0x9b05688c
    this._gh = 0x1f83d9ab
    this._hh = 0x5be0cd19
  
    this._al = 0xf3bcc908
    this._bl = 0x84caa73b
    this._cl = 0xfe94f82b
    this._dl = 0x5f1d36f1
    this._el = 0xade682d1
    this._fl = 0x2b3e6c1f
    this._gl = 0xfb41bd6b
    this._hl = 0x137e2179
  
    return this
  }
  
  function Ch (x, y, z) {
    return z ^ (x & (y ^ z))
  }
  
  function maj (x, y, z) {
    return (x & y) | (z & (x | y))
  }
  
  function sigma0 (x, xl) {
    return (x >>> 28 | xl << 4) ^ (xl >>> 2 | x << 30) ^ (xl >>> 7 | x << 25)
  }
  
  function sigma1 (x, xl) {
    return (x >>> 14 | xl << 18) ^ (x >>> 18 | xl << 14) ^ (xl >>> 9 | x << 23)
  }
  
  function Gamma0 (x, xl) {
    return (x >>> 1 | xl << 31) ^ (x >>> 8 | xl << 24) ^ (x >>> 7)
  }
  
  function Gamma0l (x, xl) {
    return (x >>> 1 | xl << 31) ^ (x >>> 8 | xl << 24) ^ (x >>> 7 | xl << 25)
  }
  
  function Gamma1 (x, xl) {
    return (x >>> 19 | xl << 13) ^ (xl >>> 29 | x << 3) ^ (x >>> 6)
  }
  
  function Gamma1l (x, xl) {
    return (x >>> 19 | xl << 13) ^ (xl >>> 29 | x << 3) ^ (x >>> 6 | xl << 26)
  }
  
  function getCarry (a, b) {
    return (a >>> 0) < (b >>> 0) ? 1 : 0
  }
  
  Sha512.prototype._update = function (M) {
    var W = this._w
  
    var ah = this._ah | 0
    var bh = this._bh | 0
    var ch = this._ch | 0
    var dh = this._dh | 0
    var eh = this._eh | 0
    var fh = this._fh | 0
    var gh = this._gh | 0
    var hh = this._hh | 0
  
    var al = this._al | 0
    var bl = this._bl | 0
    var cl = this._cl | 0
    var dl = this._dl | 0
    var el = this._el | 0
    var fl = this._fl | 0
    var gl = this._gl | 0
    var hl = this._hl | 0
  
    for (var i = 0; i < 32; i += 2) {
      W[i] = M.readInt32BE(i * 4)
      W[i + 1] = M.readInt32BE(i * 4 + 4)
    }
    for (; i < 160; i += 2) {
      var xh = W[i - 15 * 2]
      var xl = W[i - 15 * 2 + 1]
      var gamma0 = Gamma0(xh, xl)
      var gamma0l = Gamma0l(xl, xh)
  
      xh = W[i - 2 * 2]
      xl = W[i - 2 * 2 + 1]
      var gamma1 = Gamma1(xh, xl)
      var gamma1l = Gamma1l(xl, xh)
  
      // W[i] = gamma0 + W[i - 7] + gamma1 + W[i - 16]
      var Wi7h = W[i - 7 * 2]
      var Wi7l = W[i - 7 * 2 + 1]
  
      var Wi16h = W[i - 16 * 2]
      var Wi16l = W[i - 16 * 2 + 1]
  
      var Wil = (gamma0l + Wi7l) | 0
      var Wih = (gamma0 + Wi7h + getCarry(Wil, gamma0l)) | 0
      Wil = (Wil + gamma1l) | 0
      Wih = (Wih + gamma1 + getCarry(Wil, gamma1l)) | 0
      Wil = (Wil + Wi16l) | 0
      Wih = (Wih + Wi16h + getCarry(Wil, Wi16l)) | 0
  
      W[i] = Wih
      W[i + 1] = Wil
    }
  
    for (var j = 0; j < 160; j += 2) {
      Wih = W[j]
      Wil = W[j + 1]
  
      var majh = maj(ah, bh, ch)
      var majl = maj(al, bl, cl)
  
      var sigma0h = sigma0(ah, al)
      var sigma0l = sigma0(al, ah)
      var sigma1h = sigma1(eh, el)
      var sigma1l = sigma1(el, eh)
  
      // t1 = h + sigma1 + ch + K[j] + W[j]
      var Kih = K[j]
      var Kil = K[j + 1]
  
      var chh = Ch(eh, fh, gh)
      var chl = Ch(el, fl, gl)
  
      var t1l = (hl + sigma1l) | 0
      var t1h = (hh + sigma1h + getCarry(t1l, hl)) | 0
      t1l = (t1l + chl) | 0
      t1h = (t1h + chh + getCarry(t1l, chl)) | 0
      t1l = (t1l + Kil) | 0
      t1h = (t1h + Kih + getCarry(t1l, Kil)) | 0
      t1l = (t1l + Wil) | 0
      t1h = (t1h + Wih + getCarry(t1l, Wil)) | 0
  
      // t2 = sigma0 + maj
      var t2l = (sigma0l + majl) | 0
      var t2h = (sigma0h + majh + getCarry(t2l, sigma0l)) | 0
  
      hh = gh
      hl = gl
      gh = fh
      gl = fl
      fh = eh
      fl = el
      el = (dl + t1l) | 0
      eh = (dh + t1h + getCarry(el, dl)) | 0
      dh = ch
      dl = cl
      ch = bh
      cl = bl
      bh = ah
      bl = al
      al = (t1l + t2l) | 0
      ah = (t1h + t2h + getCarry(al, t1l)) | 0
    }
  
    this._al = (this._al + al) | 0
    this._bl = (this._bl + bl) | 0
    this._cl = (this._cl + cl) | 0
    this._dl = (this._dl + dl) | 0
    this._el = (this._el + el) | 0
    this._fl = (this._fl + fl) | 0
    this._gl = (this._gl + gl) | 0
    this._hl = (this._hl + hl) | 0
  
    this._ah = (this._ah + ah + getCarry(this._al, al)) | 0
    this._bh = (this._bh + bh + getCarry(this._bl, bl)) | 0
    this._ch = (this._ch + ch + getCarry(this._cl, cl)) | 0
    this._dh = (this._dh + dh + getCarry(this._dl, dl)) | 0
    this._eh = (this._eh + eh + getCarry(this._el, el)) | 0
    this._fh = (this._fh + fh + getCarry(this._fl, fl)) | 0
    this._gh = (this._gh + gh + getCarry(this._gl, gl)) | 0
    this._hh = (this._hh + hh + getCarry(this._hl, hl)) | 0
  }
  
  Sha512.prototype._hash = function () {
    var H = new Buffer(64)
  
    function writeInt64BE (h, l, offset) {
      H.writeInt32BE(h, offset)
      H.writeInt32BE(l, offset + 4)
    }
  
    writeInt64BE(this._ah, this._al, 0)
    writeInt64BE(this._bh, this._bl, 8)
    writeInt64BE(this._ch, this._cl, 16)
    writeInt64BE(this._dh, this._dl, 24)
    writeInt64BE(this._eh, this._el, 32)
    writeInt64BE(this._fh, this._fl, 40)
    writeInt64BE(this._gh, this._gl, 48)
    writeInt64BE(this._hh, this._hl, 56)
  
    return H
  }
  
  module.exports = Sha512
  
  }).call(this,require("buffer").Buffer)
  },{"./hash":67,"buffer":79,"inherits":63}],75:[function(require,module,exports){
  (function (global){
  'use strict';
  
  // compare and isBuffer taken from https://github.com/feross/buffer/blob/680e9e5e488f22aac27599a57dc844a6315928dd/index.js
  // original notice:
  
  /*!
   * The buffer module from node.js, for the browser.
   *
   * @author   Feross Aboukhadijeh <feross@feross.org> <http://feross.org>
   * @license  MIT
   */
  function compare(a, b) {
    if (a === b) {
      return 0;
    }
  
    var x = a.length;
    var y = b.length;
  
    for (var i = 0, len = Math.min(x, y); i < len; ++i) {
      if (a[i] !== b[i]) {
        x = a[i];
        y = b[i];
        break;
      }
    }
  
    if (x < y) {
      return -1;
    }
    if (y < x) {
      return 1;
    }
    return 0;
  }
  function isBuffer(b) {
    if (global.Buffer && typeof global.Buffer.isBuffer === 'function') {
      return global.Buffer.isBuffer(b);
    }
    return !!(b != null && b._isBuffer);
  }
  
  // based on node assert, original notice:
  
  // http://wiki.commonjs.org/wiki/Unit_Testing/1.0
  //
  // THIS IS NOT TESTED NOR LIKELY TO WORK OUTSIDE V8!
  //
  // Originally from narwhal.js (http://narwhaljs.org)
  // Copyright (c) 2009 Thomas Robinson <280north.com>
  //
  // Permission is hereby granted, free of charge, to any person obtaining a copy
  // of this software and associated documentation files (the 'Software'), to
  // deal in the Software without restriction, including without limitation the
  // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  // sell copies of the Software, and to permit persons to whom the Software is
  // furnished to do so, subject to the following conditions:
  //
  // The above copyright notice and this permission notice shall be included in
  // all copies or substantial portions of the Software.
  //
  // THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  // AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
  // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  
  var util = require('util/');
  var hasOwn = Object.prototype.hasOwnProperty;
  var pSlice = Array.prototype.slice;
  var functionsHaveNames = (function () {
    return function foo() {}.name === 'foo';
  }());
  function pToString (obj) {
    return Object.prototype.toString.call(obj);
  }
  function isView(arrbuf) {
    if (isBuffer(arrbuf)) {
      return false;
    }
    if (typeof global.ArrayBuffer !== 'function') {
      return false;
    }
    if (typeof ArrayBuffer.isView === 'function') {
      return ArrayBuffer.isView(arrbuf);
    }
    if (!arrbuf) {
      return false;
    }
    if (arrbuf instanceof DataView) {
      return true;
    }
    if (arrbuf.buffer && arrbuf.buffer instanceof ArrayBuffer) {
      return true;
    }
    return false;
  }
  // 1. The assert module provides functions that throw
  // AssertionError's when particular conditions are not met. The
  // assert module must conform to the following interface.
  
  var assert = module.exports = ok;
  
  // 2. The AssertionError is defined in assert.
  // new assert.AssertionError({ message: message,
  //                             actual: actual,
  //                             expected: expected })
  
  var regex = /\s*function\s+([^\(\s]*)\s*/;
  // based on https://github.com/ljharb/function.prototype.name/blob/adeeeec8bfcc6068b187d7d9fb3d5bb1d3a30899/implementation.js
  function getName(func) {
    if (!util.isFunction(func)) {
      return;
    }
    if (functionsHaveNames) {
      return func.name;
    }
    var str = func.toString();
    var match = str.match(regex);
    return match && match[1];
  }
  assert.AssertionError = function AssertionError(options) {
    this.name = 'AssertionError';
    this.actual = options.actual;
    this.expected = options.expected;
    this.operator = options.operator;
    if (options.message) {
      this.message = options.message;
      this.generatedMessage = false;
    } else {
      this.message = getMessage(this);
      this.generatedMessage = true;
    }
    var stackStartFunction = options.stackStartFunction || fail;
    if (Error.captureStackTrace) {
      Error.captureStackTrace(this, stackStartFunction);
    } else {
      // non v8 browsers so we can have a stacktrace
      var err = new Error();
      if (err.stack) {
        var out = err.stack;
  
        // try to strip useless frames
        var fn_name = getName(stackStartFunction);
        var idx = out.indexOf('\n' + fn_name);
        if (idx >= 0) {
          // once we have located the function frame
          // we need to strip out everything before it (and its line)
          var next_line = out.indexOf('\n', idx + 1);
          out = out.substring(next_line + 1);
        }
  
        this.stack = out;
      }
    }
  };
  
  // assert.AssertionError instanceof Error
  util.inherits(assert.AssertionError, Error);
  
  function truncate(s, n) {
    if (typeof s === 'string') {
      return s.length < n ? s : s.slice(0, n);
    } else {
      return s;
    }
  }
  function inspect(something) {
    if (functionsHaveNames || !util.isFunction(something)) {
      return util.inspect(something);
    }
    var rawname = getName(something);
    var name = rawname ? ': ' + rawname : '';
    return '[Function' +  name + ']';
  }
  function getMessage(self) {
    return truncate(inspect(self.actual), 128) + ' ' +
           self.operator + ' ' +
           truncate(inspect(self.expected), 128);
  }
  
  // At present only the three keys mentioned above are used and
  // understood by the spec. Implementations or sub modules can pass
  // other keys to the AssertionError's constructor - they will be
  // ignored.
  
  // 3. All of the following functions must throw an AssertionError
  // when a corresponding condition is not met, with a message that
  // may be undefined if not provided.  All assertion methods provide
  // both the actual and expected values to the assertion error for
  // display purposes.
  
  function fail(actual, expected, message, operator, stackStartFunction) {
    throw new assert.AssertionError({
      message: message,
      actual: actual,
      expected: expected,
      operator: operator,
      stackStartFunction: stackStartFunction
    });
  }
  
  // EXTENSION! allows for well behaved errors defined elsewhere.
  assert.fail = fail;
  
  // 4. Pure assertion tests whether a value is truthy, as determined
  // by !!guard.
  // assert.ok(guard, message_opt);
  // This statement is equivalent to assert.equal(true, !!guard,
  // message_opt);. To test strictly for the value true, use
  // assert.strictEqual(true, guard, message_opt);.
  
  function ok(value, message) {
    if (!value) fail(value, true, message, '==', assert.ok);
  }
  assert.ok = ok;
  
  // 5. The equality assertion tests shallow, coercive equality with
  // ==.
  // assert.equal(actual, expected, message_opt);
  
  assert.equal = function equal(actual, expected, message) {
    if (actual != expected) fail(actual, expected, message, '==', assert.equal);
  };
  
  // 6. The non-equality assertion tests for whether two objects are not equal
  // with != assert.notEqual(actual, expected, message_opt);
  
  assert.notEqual = function notEqual(actual, expected, message) {
    if (actual == expected) {
      fail(actual, expected, message, '!=', assert.notEqual);
    }
  };
  
  // 7. The equivalence assertion tests a deep equality relation.
  // assert.deepEqual(actual, expected, message_opt);
  
  assert.deepEqual = function deepEqual(actual, expected, message) {
    if (!_deepEqual(actual, expected, false)) {
      fail(actual, expected, message, 'deepEqual', assert.deepEqual);
    }
  };
  
  assert.deepStrictEqual = function deepStrictEqual(actual, expected, message) {
    if (!_deepEqual(actual, expected, true)) {
      fail(actual, expected, message, 'deepStrictEqual', assert.deepStrictEqual);
    }
  };
  
  function _deepEqual(actual, expected, strict, memos) {
    // 7.1. All identical values are equivalent, as determined by ===.
    if (actual === expected) {
      return true;
    } else if (isBuffer(actual) && isBuffer(expected)) {
      return compare(actual, expected) === 0;
  
    // 7.2. If the expected value is a Date object, the actual value is
    // equivalent if it is also a Date object that refers to the same time.
    } else if (util.isDate(actual) && util.isDate(expected)) {
      return actual.getTime() === expected.getTime();
  
    // 7.3 If the expected value is a RegExp object, the actual value is
    // equivalent if it is also a RegExp object with the same source and
    // properties (`global`, `multiline`, `lastIndex`, `ignoreCase`).
    } else if (util.isRegExp(actual) && util.isRegExp(expected)) {
      return actual.source === expected.source &&
             actual.global === expected.global &&
             actual.multiline === expected.multiline &&
             actual.lastIndex === expected.lastIndex &&
             actual.ignoreCase === expected.ignoreCase;
  
    // 7.4. Other pairs that do not both pass typeof value == 'object',
    // equivalence is determined by ==.
    } else if ((actual === null || typeof actual !== 'object') &&
               (expected === null || typeof expected !== 'object')) {
      return strict ? actual === expected : actual == expected;
  
    // If both values are instances of typed arrays, wrap their underlying
    // ArrayBuffers in a Buffer each to increase performance
    // This optimization requires the arrays to have the same type as checked by
    // Object.prototype.toString (aka pToString). Never perform binary
    // comparisons for Float*Arrays, though, since e.g. +0 === -0 but their
    // bit patterns are not identical.
    } else if (isView(actual) && isView(expected) &&
               pToString(actual) === pToString(expected) &&
               !(actual instanceof Float32Array ||
                 actual instanceof Float64Array)) {
      return compare(new Uint8Array(actual.buffer),
                     new Uint8Array(expected.buffer)) === 0;
  
    // 7.5 For all other Object pairs, including Array objects, equivalence is
    // determined by having the same number of owned properties (as verified
    // with Object.prototype.hasOwnProperty.call), the same set of keys
    // (although not necessarily the same order), equivalent values for every
    // corresponding key, and an identical 'prototype' property. Note: this
    // accounts for both named and indexed properties on Arrays.
    } else if (isBuffer(actual) !== isBuffer(expected)) {
      return false;
    } else {
      memos = memos || {actual: [], expected: []};
  
      var actualIndex = memos.actual.indexOf(actual);
      if (actualIndex !== -1) {
        if (actualIndex === memos.expected.indexOf(expected)) {
          return true;
        }
      }
  
      memos.actual.push(actual);
      memos.expected.push(expected);
  
      return objEquiv(actual, expected, strict, memos);
    }
  }
  
  function isArguments(object) {
    return Object.prototype.toString.call(object) == '[object Arguments]';
  }
  
  function objEquiv(a, b, strict, actualVisitedObjects) {
    if (a === null || a === undefined || b === null || b === undefined)
      return false;
    // if one is a primitive, the other must be same
    if (util.isPrimitive(a) || util.isPrimitive(b))
      return a === b;
    if (strict && Object.getPrototypeOf(a) !== Object.getPrototypeOf(b))
      return false;
    var aIsArgs = isArguments(a);
    var bIsArgs = isArguments(b);
    if ((aIsArgs && !bIsArgs) || (!aIsArgs && bIsArgs))
      return false;
    if (aIsArgs) {
      a = pSlice.call(a);
      b = pSlice.call(b);
      return _deepEqual(a, b, strict);
    }
    var ka = objectKeys(a);
    var kb = objectKeys(b);
    var key, i;
    // having the same number of owned properties (keys incorporates
    // hasOwnProperty)
    if (ka.length !== kb.length)
      return false;
    //the same set of keys (although not necessarily the same order),
    ka.sort();
    kb.sort();
    //~~~cheap key test
    for (i = ka.length - 1; i >= 0; i--) {
      if (ka[i] !== kb[i])
        return false;
    }
    //equivalent values for every corresponding key, and
    //~~~possibly expensive deep test
    for (i = ka.length - 1; i >= 0; i--) {
      key = ka[i];
      if (!_deepEqual(a[key], b[key], strict, actualVisitedObjects))
        return false;
    }
    return true;
  }
  
  // 8. The non-equivalence assertion tests for any deep inequality.
  // assert.notDeepEqual(actual, expected, message_opt);
  
  assert.notDeepEqual = function notDeepEqual(actual, expected, message) {
    if (_deepEqual(actual, expected, false)) {
      fail(actual, expected, message, 'notDeepEqual', assert.notDeepEqual);
    }
  };
  
  assert.notDeepStrictEqual = notDeepStrictEqual;
  function notDeepStrictEqual(actual, expected, message) {
    if (_deepEqual(actual, expected, true)) {
      fail(actual, expected, message, 'notDeepStrictEqual', notDeepStrictEqual);
    }
  }
  
  
  // 9. The strict equality assertion tests strict equality, as determined by ===.
  // assert.strictEqual(actual, expected, message_opt);
  
  assert.strictEqual = function strictEqual(actual, expected, message) {
    if (actual !== expected) {
      fail(actual, expected, message, '===', assert.strictEqual);
    }
  };
  
  // 10. The strict non-equality assertion tests for strict inequality, as
  // determined by !==.  assert.notStrictEqual(actual, expected, message_opt);
  
  assert.notStrictEqual = function notStrictEqual(actual, expected, message) {
    if (actual === expected) {
      fail(actual, expected, message, '!==', assert.notStrictEqual);
    }
  };
  
  function expectedException(actual, expected) {
    if (!actual || !expected) {
      return false;
    }
  
    if (Object.prototype.toString.call(expected) == '[object RegExp]') {
      return expected.test(actual);
    }
  
    try {
      if (actual instanceof expected) {
        return true;
      }
    } catch (e) {
      // Ignore.  The instanceof check doesn't work for arrow functions.
    }
  
    if (Error.isPrototypeOf(expected)) {
      return false;
    }
  
    return expected.call({}, actual) === true;
  }
  
  function _tryBlock(block) {
    var error;
    try {
      block();
    } catch (e) {
      error = e;
    }
    return error;
  }
  
  function _throws(shouldThrow, block, expected, message) {
    var actual;
  
    if (typeof block !== 'function') {
      throw new TypeError('"block" argument must be a function');
    }
  
    if (typeof expected === 'string') {
      message = expected;
      expected = null;
    }
  
    actual = _tryBlock(block);
  
    message = (expected && expected.name ? ' (' + expected.name + ').' : '.') +
              (message ? ' ' + message : '.');
  
    if (shouldThrow && !actual) {
      fail(actual, expected, 'Missing expected exception' + message);
    }
  
    var userProvidedMessage = typeof message === 'string';
    var isUnwantedException = !shouldThrow && util.isError(actual);
    var isUnexpectedException = !shouldThrow && actual && !expected;
  
    if ((isUnwantedException &&
        userProvidedMessage &&
        expectedException(actual, expected)) ||
        isUnexpectedException) {
      fail(actual, expected, 'Got unwanted exception' + message);
    }
  
    if ((shouldThrow && actual && expected &&
        !expectedException(actual, expected)) || (!shouldThrow && actual)) {
      throw actual;
    }
  }
  
  // 11. Expected to throw an error:
  // assert.throws(block, Error_opt, message_opt);
  
  assert.throws = function(block, /*optional*/error, /*optional*/message) {
    _throws(true, block, error, message);
  };
  
  // EXTENSION! This is annoying to write outside this module.
  assert.doesNotThrow = function(block, /*optional*/error, /*optional*/message) {
    _throws(false, block, error, message);
  };
  
  assert.ifError = function(err) { if (err) throw err; };
  
  var objectKeys = Object.keys || function (obj) {
    var keys = [];
    for (var key in obj) {
      if (hasOwn.call(obj, key)) keys.push(key);
    }
    return keys;
  };
  
  }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
  },{"util/":104}],76:[function(require,module,exports){
  'use strict'
  
  exports.byteLength = byteLength
  exports.toByteArray = toByteArray
  exports.fromByteArray = fromByteArray
  
  var lookup = []
  var revLookup = []
  var Arr = typeof Uint8Array !== 'undefined' ? Uint8Array : Array
  
  var code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
  for (var i = 0, len = code.length; i < len; ++i) {
    lookup[i] = code[i]
    revLookup[code.charCodeAt(i)] = i
  }
  
  revLookup['-'.charCodeAt(0)] = 62
  revLookup['_'.charCodeAt(0)] = 63
  
  function placeHoldersCount (b64) {
    var len = b64.length
    if (len % 4 > 0) {
      throw new Error('Invalid string. Length must be a multiple of 4')
    }
  
    // the number of equal signs (place holders)
    // if there are two placeholders, than the two characters before it
    // represent one byte
    // if there is only one, then the three characters before it represent 2 bytes
    // this is just a cheap hack to not do indexOf twice
    return b64[len - 2] === '=' ? 2 : b64[len - 1] === '=' ? 1 : 0
  }
  
  function byteLength (b64) {
    // base64 is 4/3 + up to two characters of the original data
    return b64.length * 3 / 4 - placeHoldersCount(b64)
  }
  
  function toByteArray (b64) {
    var i, j, l, tmp, placeHolders, arr
    var len = b64.length
    placeHolders = placeHoldersCount(b64)
  
    arr = new Arr(len * 3 / 4 - placeHolders)
  
    // if there are placeholders, only get up to the last complete 4 chars
    l = placeHolders > 0 ? len - 4 : len
  
    var L = 0
  
    for (i = 0, j = 0; i < l; i += 4, j += 3) {
      tmp = (revLookup[b64.charCodeAt(i)] << 18) | (revLookup[b64.charCodeAt(i + 1)] << 12) | (revLookup[b64.charCodeAt(i + 2)] << 6) | revLookup[b64.charCodeAt(i + 3)]
      arr[L++] = (tmp >> 16) & 0xFF
      arr[L++] = (tmp >> 8) & 0xFF
      arr[L++] = tmp & 0xFF
    }
  
    if (placeHolders === 2) {
      tmp = (revLookup[b64.charCodeAt(i)] << 2) | (revLookup[b64.charCodeAt(i + 1)] >> 4)
      arr[L++] = tmp & 0xFF
    } else if (placeHolders === 1) {
      tmp = (revLookup[b64.charCodeAt(i)] << 10) | (revLookup[b64.charCodeAt(i + 1)] << 4) | (revLookup[b64.charCodeAt(i + 2)] >> 2)
      arr[L++] = (tmp >> 8) & 0xFF
      arr[L++] = tmp & 0xFF
    }
  
    return arr
  }
  
  function tripletToBase64 (num) {
    return lookup[num >> 18 & 0x3F] + lookup[num >> 12 & 0x3F] + lookup[num >> 6 & 0x3F] + lookup[num & 0x3F]
  }
  
  function encodeChunk (uint8, start, end) {
    var tmp
    var output = []
    for (var i = start; i < end; i += 3) {
      tmp = (uint8[i] << 16) + (uint8[i + 1] << 8) + (uint8[i + 2])
      output.push(tripletToBase64(tmp))
    }
    return output.join('')
  }
  
  function fromByteArray (uint8) {
    var tmp
    var len = uint8.length
    var extraBytes = len % 3 // if we have 1 byte left, pad 2 bytes
    var output = ''
    var parts = []
    var maxChunkLength = 16383 // must be multiple of 3
  
    // go through the array every three bytes, we'll deal with trailing stuff later
    for (var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) {
      parts.push(encodeChunk(uint8, i, (i + maxChunkLength) > len2 ? len2 : (i + maxChunkLength)))
    }
  
    // pad the end with zeros, but make sure to not forget the extra bytes
    if (extraBytes === 1) {
      tmp = uint8[len - 1]
      output += lookup[tmp >> 2]
      output += lookup[(tmp << 4) & 0x3F]
      output += '=='
    } else if (extraBytes === 2) {
      tmp = (uint8[len - 2] << 8) + (uint8[len - 1])
      output += lookup[tmp >> 10]
      output += lookup[(tmp >> 4) & 0x3F]
      output += lookup[(tmp << 2) & 0x3F]
      output += '='
    }
  
    parts.push(output)
  
    return parts.join('')
  }
  
  },{}],77:[function(require,module,exports){
  
  },{}],78:[function(require,module,exports){
  (function (global){
  'use strict';
  
  var buffer = require('buffer');
  var Buffer = buffer.Buffer;
  var SlowBuffer = buffer.SlowBuffer;
  var MAX_LEN = buffer.kMaxLength || 2147483647;
  exports.alloc = function alloc(size, fill, encoding) {
    if (typeof Buffer.alloc === 'function') {
      return Buffer.alloc(size, fill, encoding);
    }
    if (typeof encoding === 'number') {
      throw new TypeError('encoding must not be number');
    }
    if (typeof size !== 'number') {
      throw new TypeError('size must be a number');
    }
    if (size > MAX_LEN) {
      throw new RangeError('size is too large');
    }
    var enc = encoding;
    var _fill = fill;
    if (_fill === undefined) {
      enc = undefined;
      _fill = 0;
    }
    var buf = new Buffer(size);
    if (typeof _fill === 'string') {
      var fillBuf = new Buffer(_fill, enc);
      var flen = fillBuf.length;
      var i = -1;
      while (++i < size) {
        buf[i] = fillBuf[i % flen];
      }
    } else {
      buf.fill(_fill);
    }
    return buf;
  }
  exports.allocUnsafe = function allocUnsafe(size) {
    if (typeof Buffer.allocUnsafe === 'function') {
      return Buffer.allocUnsafe(size);
    }
    if (typeof size !== 'number') {
      throw new TypeError('size must be a number');
    }
    if (size > MAX_LEN) {
      throw new RangeError('size is too large');
    }
    return new Buffer(size);
  }
  exports.from = function from(value, encodingOrOffset, length) {
    if (typeof Buffer.from === 'function' && (!global.Uint8Array || Uint8Array.from !== Buffer.from)) {
      return Buffer.from(value, encodingOrOffset, length);
    }
    if (typeof value === 'number') {
      throw new TypeError('"value" argument must not be a number');
    }
    if (typeof value === 'string') {
      return new Buffer(value, encodingOrOffset);
    }
    if (typeof ArrayBuffer !== 'undefined' && value instanceof ArrayBuffer) {
      var offset = encodingOrOffset;
      if (arguments.length === 1) {
        return new Buffer(value);
      }
      if (typeof offset === 'undefined') {
        offset = 0;
      }
      var len = length;
      if (typeof len === 'undefined') {
        len = value.byteLength - offset;
      }
      if (offset >= value.byteLength) {
        throw new RangeError('\'offset\' is out of bounds');
      }
      if (len > value.byteLength - offset) {
        throw new RangeError('\'length\' is out of bounds');
      }
      return new Buffer(value.slice(offset, offset + len));
    }
    if (Buffer.isBuffer(value)) {
      var out = new Buffer(value.length);
      value.copy(out, 0, 0, value.length);
      return out;
    }
    if (value) {
      if (Array.isArray(value) || (typeof ArrayBuffer !== 'undefined' && value.buffer instanceof ArrayBuffer) || 'length' in value) {
        return new Buffer(value);
      }
      if (value.type === 'Buffer' && Array.isArray(value.data)) {
        return new Buffer(value.data);
      }
    }
  
    throw new TypeError('First argument must be a string, Buffer, ' + 'ArrayBuffer, Array, or array-like object.');
  }
  exports.allocUnsafeSlow = function allocUnsafeSlow(size) {
    if (typeof Buffer.allocUnsafeSlow === 'function') {
      return Buffer.allocUnsafeSlow(size);
    }
    if (typeof size !== 'number') {
      throw new TypeError('size must be a number');
    }
    if (size >= MAX_LEN) {
      throw new RangeError('size is too large');
    }
    return new SlowBuffer(size);
  }
  
  }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
  },{"buffer":79}],79:[function(require,module,exports){
  (function (global){
  /*!
   * The buffer module from node.js, for the browser.
   *
   * @author   Feross Aboukhadijeh <feross@feross.org> <http://feross.org>
   * @license  MIT
   */
  /* eslint-disable no-proto */
  
  'use strict'
  
  var base64 = require('base64-js')
  var ieee754 = require('ieee754')
  var isArray = require('isarray')
  
  exports.Buffer = Buffer
  exports.SlowBuffer = SlowBuffer
  exports.INSPECT_MAX_BYTES = 50
  
  /**
   * If `Buffer.TYPED_ARRAY_SUPPORT`:
   *   === true    Use Uint8Array implementation (fastest)
   *   === false   Use Object implementation (most compatible, even IE6)
   *
   * Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+,
   * Opera 11.6+, iOS 4.2+.
   *
   * Due to various browser bugs, sometimes the Object implementation will be used even
   * when the browser supports typed arrays.
   *
   * Note:
   *
   *   - Firefox 4-29 lacks support for adding new properties to `Uint8Array` instances,
   *     See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438.
   *
   *   - Chrome 9-10 is missing the `TypedArray.prototype.subarray` function.
   *
   *   - IE10 has a broken `TypedArray.prototype.subarray` function which returns arrays of
   *     incorrect length in some situations.
  
   * We detect these buggy browsers and set `Buffer.TYPED_ARRAY_SUPPORT` to `false` so they
   * get the Object implementation, which is slower but behaves correctly.
   */
  Buffer.TYPED_ARRAY_SUPPORT = global.TYPED_ARRAY_SUPPORT !== undefined
    ? global.TYPED_ARRAY_SUPPORT
    : typedArraySupport()
  
  /*
   * Export kMaxLength after typed array support is determined.
   */
  exports.kMaxLength = kMaxLength()
  
  function typedArraySupport () {
    try {
      var arr = new Uint8Array(1)
      arr.__proto__ = {__proto__: Uint8Array.prototype, foo: function () { return 42 }}
      return arr.foo() === 42 && // typed array instances can be augmented
          typeof arr.subarray === 'function' && // chrome 9-10 lack `subarray`
          arr.subarray(1, 1).byteLength === 0 // ie10 has broken `subarray`
    } catch (e) {
      return false
    }
  }
  
  function kMaxLength () {
    return Buffer.TYPED_ARRAY_SUPPORT
      ? 0x7fffffff
      : 0x3fffffff
  }
  
  function createBuffer (that, length) {
    if (kMaxLength() < length) {
      throw new RangeError('Invalid typed array length')
    }
    if (Buffer.TYPED_ARRAY_SUPPORT) {
      // Return an augmented `Uint8Array` instance, for best performance
      that = new Uint8Array(length)
      that.__proto__ = Buffer.prototype
    } else {
      // Fallback: Return an object instance of the Buffer class
      if (that === null) {
        that = new Buffer(length)
      }
      that.length = length
    }
  
    return that
  }
  
  /**
   * The Buffer constructor returns instances of `Uint8Array` that have their
   * prototype changed to `Buffer.prototype`. Furthermore, `Buffer` is a subclass of
   * `Uint8Array`, so the returned instances will have all the node `Buffer` methods
   * and the `Uint8Array` methods. Square bracket notation works as expected -- it
   * returns a single octet.
   *
   * The `Uint8Array` prototype remains unmodified.
   */
  
  function Buffer (arg, encodingOrOffset, length) {
    if (!Buffer.TYPED_ARRAY_SUPPORT && !(this instanceof Buffer)) {
      return new Buffer(arg, encodingOrOffset, length)
    }
  
    // Common case.
    if (typeof arg === 'number') {
      if (typeof encodingOrOffset === 'string') {
        throw new Error(
          'If encoding is specified then the first argument must be a string'
        )
      }
      return allocUnsafe(this, arg)
    }
    return from(this, arg, encodingOrOffset, length)
  }
  
  Buffer.poolSize = 8192 // not used by this implementation
  
  // TODO: Legacy, not needed anymore. Remove in next major version.
  Buffer._augment = function (arr) {
    arr.__proto__ = Buffer.prototype
    return arr
  }
  
  function from (that, value, encodingOrOffset, length) {
    if (typeof value === 'number') {
      throw new TypeError('"value" argument must not be a number')
    }
  
    if (typeof ArrayBuffer !== 'undefined' && value instanceof ArrayBuffer) {
      return fromArrayBuffer(that, value, encodingOrOffset, length)
    }
  
    if (typeof value === 'string') {
      return fromString(that, value, encodingOrOffset)
    }
  
    return fromObject(that, value)
  }
  
  /**
   * Functionally equivalent to Buffer(arg, encoding) but throws a TypeError
   * if value is a number.
   * Buffer.from(str[, encoding])
   * Buffer.from(array)
   * Buffer.from(buffer)
   * Buffer.from(arrayBuffer[, byteOffset[, length]])
   **/
  Buffer.from = function (value, encodingOrOffset, length) {
    return from(null, value, encodingOrOffset, length)
  }
  
  if (Buffer.TYPED_ARRAY_SUPPORT) {
    Buffer.prototype.__proto__ = Uint8Array.prototype
    Buffer.__proto__ = Uint8Array
    if (typeof Symbol !== 'undefined' && Symbol.species &&
        Buffer[Symbol.species] === Buffer) {
      // Fix subarray() in ES2016. See: https://github.com/feross/buffer/pull/97
      Object.defineProperty(Buffer, Symbol.species, {
        value: null,
        configurable: true
      })
    }
  }
  
  function assertSize (size) {
    if (typeof size !== 'number') {
      throw new TypeError('"size" argument must be a number')
    } else if (size < 0) {
      throw new RangeError('"size" argument must not be negative')
    }
  }
  
  function alloc (that, size, fill, encoding) {
    assertSize(size)
    if (size <= 0) {
      return createBuffer(that, size)
    }
    if (fill !== undefined) {
      // Only pay attention to encoding if it's a string. This
      // prevents accidentally sending in a number that would
      // be interpretted as a start offset.
      return typeof encoding === 'string'
        ? createBuffer(that, size).fill(fill, encoding)
        : createBuffer(that, size).fill(fill)
    }
    return createBuffer(that, size)
  }
  
  /**
   * Creates a new filled Buffer instance.
   * alloc(size[, fill[, encoding]])
   **/
  Buffer.alloc = function (size, fill, encoding) {
    return alloc(null, size, fill, encoding)
  }
  
  function allocUnsafe (that, size) {
    assertSize(size)
    that = createBuffer(that, size < 0 ? 0 : checked(size) | 0)
    if (!Buffer.TYPED_ARRAY_SUPPORT) {
      for (var i = 0; i < size; ++i) {
        that[i] = 0
      }
    }
    return that
  }
  
  /**
   * Equivalent to Buffer(num), by default creates a non-zero-filled Buffer instance.
   * */
  Buffer.allocUnsafe = function (size) {
    return allocUnsafe(null, size)
  }
  /**
   * Equivalent to SlowBuffer(num), by default creates a non-zero-filled Buffer instance.
   */
  Buffer.allocUnsafeSlow = function (size) {
    return allocUnsafe(null, size)
  }
  
  function fromString (that, string, encoding) {
    if (typeof encoding !== 'string' || encoding === '') {
      encoding = 'utf8'
    }
  
    if (!Buffer.isEncoding(encoding)) {
      throw new TypeError('"encoding" must be a valid string encoding')
    }
  
    var length = byteLength(string, encoding) | 0
    that = createBuffer(that, length)
  
    var actual = that.write(string, encoding)
  
    if (actual !== length) {
      // Writing a hex string, for example, that contains invalid characters will
      // cause everything after the first invalid character to be ignored. (e.g.
      // 'abxxcd' will be treated as 'ab')
      that = that.slice(0, actual)
    }
  
    return that
  }
  
  function fromArrayLike (that, array) {
    var length = array.length < 0 ? 0 : checked(array.length) | 0
    that = createBuffer(that, length)
    for (var i = 0; i < length; i += 1) {
      that[i] = array[i] & 255
    }
    return that
  }
  
  function fromArrayBuffer (that, array, byteOffset, length) {
    array.byteLength // this throws if `array` is not a valid ArrayBuffer
  
    if (byteOffset < 0 || array.byteLength < byteOffset) {
      throw new RangeError('\'offset\' is out of bounds')
    }
  
    if (array.byteLength < byteOffset + (length || 0)) {
      throw new RangeError('\'length\' is out of bounds')
    }
  
    if (byteOffset === undefined && length === undefined) {
      array = new Uint8Array(array)
    } else if (length === undefined) {
      array = new Uint8Array(array, byteOffset)
    } else {
      array = new Uint8Array(array, byteOffset, length)
    }
  
    if (Buffer.TYPED_ARRAY_SUPPORT) {
      // Return an augmented `Uint8Array` instance, for best performance
      that = array
      that.__proto__ = Buffer.prototype
    } else {
      // Fallback: Return an object instance of the Buffer class
      that = fromArrayLike(that, array)
    }
    return that
  }
  
  function fromObject (that, obj) {
    if (Buffer.isBuffer(obj)) {
      var len = checked(obj.length) | 0
      that = createBuffer(that, len)
  
      if (that.length === 0) {
        return that
      }
  
      obj.copy(that, 0, 0, len)
      return that
    }
  
    if (obj) {
      if ((typeof ArrayBuffer !== 'undefined' &&
          obj.buffer instanceof ArrayBuffer) || 'length' in obj) {
        if (typeof obj.length !== 'number' || isnan(obj.length)) {
          return createBuffer(that, 0)
        }
        return fromArrayLike(that, obj)
      }
  
      if (obj.type === 'Buffer' && isArray(obj.data)) {
        return fromArrayLike(that, obj.data)
      }
    }
  
    throw new TypeError('First argument must be a string, Buffer, ArrayBuffer, Array, or array-like object.')
  }
  
  function checked (length) {
    // Note: cannot use `length < kMaxLength()` here because that fails when
    // length is NaN (which is otherwise coerced to zero.)
    if (length >= kMaxLength()) {
      throw new RangeError('Attempt to allocate Buffer larger than maximum ' +
                           'size: 0x' + kMaxLength().toString(16) + ' bytes')
    }
    return length | 0
  }
  
  function SlowBuffer (length) {
    if (+length != length) { // eslint-disable-line eqeqeq
      length = 0
    }
    return Buffer.alloc(+length)
  }
  
  Buffer.isBuffer = function isBuffer (b) {
    return !!(b != null && b._isBuffer)
  }
  
  Buffer.compare = function compare (a, b) {
    if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) {
      throw new TypeError('Arguments must be Buffers')
    }
  
    if (a === b) return 0
  
    var x = a.length
    var y = b.length
  
    for (var i = 0, len = Math.min(x, y); i < len; ++i) {
      if (a[i] !== b[i]) {
        x = a[i]
        y = b[i]
        break
      }
    }
  
    if (x < y) return -1
    if (y < x) return 1
    return 0
  }
  
  Buffer.isEncoding = function isEncoding (encoding) {
    switch (String(encoding).toLowerCase()) {
      case 'hex':
      case 'utf8':
      case 'utf-8':
      case 'ascii':
      case 'latin1':
      case 'binary':
      case 'base64':
      case 'ucs2':
      case 'ucs-2':
      case 'utf16le':
      case 'utf-16le':
        return true
      default:
        return false
    }
  }
  
  Buffer.concat = function concat (list, length) {
    if (!isArray(list)) {
      throw new TypeError('"list" argument must be an Array of Buffers')
    }
  
    if (list.length === 0) {
      return Buffer.alloc(0)
    }
  
    var i
    if (length === undefined) {
      length = 0
      for (i = 0; i < list.length; ++i) {
        length += list[i].length
      }
    }
  
    var buffer = Buffer.allocUnsafe(length)
    var pos = 0
    for (i = 0; i < list.length; ++i) {
      var buf = list[i]
      if (!Buffer.isBuffer(buf)) {
        throw new TypeError('"list" argument must be an Array of Buffers')
      }
      buf.copy(buffer, pos)
      pos += buf.length
    }
    return buffer
  }
  
  function byteLength (string, encoding) {
    if (Buffer.isBuffer(string)) {
      return string.length
    }
    if (typeof ArrayBuffer !== 'undefined' && typeof ArrayBuffer.isView === 'function' &&
        (ArrayBuffer.isView(string) || string instanceof ArrayBuffer)) {
      return string.byteLength
    }
    if (typeof string !== 'string') {
      string = '' + string
    }
  
    var len = string.length
    if (len === 0) return 0
  
    // Use a for loop to avoid recursion
    var loweredCase = false
    for (;;) {
      switch (encoding) {
        case 'ascii':
        case 'latin1':
        case 'binary':
          return len
        case 'utf8':
        case 'utf-8':
        case undefined:
          return utf8ToBytes(string).length
        case 'ucs2':
        case 'ucs-2':
        case 'utf16le':
        case 'utf-16le':
          return len * 2
        case 'hex':
          return len >>> 1
        case 'base64':
          return base64ToBytes(string).length
        default:
          if (loweredCase) return utf8ToBytes(string).length // assume utf8
          encoding = ('' + encoding).toLowerCase()
          loweredCase = true
      }
    }
  }
  Buffer.byteLength = byteLength
  
  function slowToString (encoding, start, end) {
    var loweredCase = false
  
    // No need to verify that "this.length <= MAX_UINT32" since it's a read-only
    // property of a typed array.
  
    // This behaves neither like String nor Uint8Array in that we set start/end
    // to their upper/lower bounds if the value passed is out of range.
    // undefined is handled specially as per ECMA-262 6th Edition,
    // Section 13.3.3.7 Runtime Semantics: KeyedBindingInitialization.
    if (start === undefined || start < 0) {
      start = 0
    }
    // Return early if start > this.length. Done here to prevent potential uint32
    // coercion fail below.
    if (start > this.length) {
      return ''
    }
  
    if (end === undefined || end > this.length) {
      end = this.length
    }
  
    if (end <= 0) {
      return ''
    }
  
    // Force coersion to uint32. This will also coerce falsey/NaN values to 0.
    end >>>= 0
    start >>>= 0
  
    if (end <= start) {
      return ''
    }
  
    if (!encoding) encoding = 'utf8'
  
    while (true) {
      switch (encoding) {
        case 'hex':
          return hexSlice(this, start, end)
  
        case 'utf8':
        case 'utf-8':
          return utf8Slice(this, start, end)
  
        case 'ascii':
          return asciiSlice(this, start, end)
  
        case 'latin1':
        case 'binary':
          return latin1Slice(this, start, end)
  
        case 'base64':
          return base64Slice(this, start, end)
  
        case 'ucs2':
        case 'ucs-2':
        case 'utf16le':
        case 'utf-16le':
          return utf16leSlice(this, start, end)
  
        default:
          if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)
          encoding = (encoding + '').toLowerCase()
          loweredCase = true
      }
    }
  }
  
  // The property is used by `Buffer.isBuffer` and `is-buffer` (in Safari 5-7) to detect
  // Buffer instances.
  Buffer.prototype._isBuffer = true
  
  function swap (b, n, m) {
    var i = b[n]
    b[n] = b[m]
    b[m] = i
  }
  
  Buffer.prototype.swap16 = function swap16 () {
    var len = this.length
    if (len % 2 !== 0) {
      throw new RangeError('Buffer size must be a multiple of 16-bits')
    }
    for (var i = 0; i < len; i += 2) {
      swap(this, i, i + 1)
    }
    return this
  }
  
  Buffer.prototype.swap32 = function swap32 () {
    var len = this.length
    if (len % 4 !== 0) {
      throw new RangeError('Buffer size must be a multiple of 32-bits')
    }
    for (var i = 0; i < len; i += 4) {
      swap(this, i, i + 3)
      swap(this, i + 1, i + 2)
    }
    return this
  }
  
  Buffer.prototype.swap64 = function swap64 () {
    var len = this.length
    if (len % 8 !== 0) {
      throw new RangeError('Buffer size must be a multiple of 64-bits')
    }
    for (var i = 0; i < len; i += 8) {
      swap(this, i, i + 7)
      swap(this, i + 1, i + 6)
      swap(this, i + 2, i + 5)
      swap(this, i + 3, i + 4)
    }
    return this
  }
  
  Buffer.prototype.toString = function toString () {
    var length = this.length | 0
    if (length === 0) return ''
    if (arguments.length === 0) return utf8Slice(this, 0, length)
    return slowToString.apply(this, arguments)
  }
  
  Buffer.prototype.equals = function equals (b) {
    if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer')
    if (this === b) return true
    return Buffer.compare(this, b) === 0
  }
  
  Buffer.prototype.inspect = function inspect () {
    var str = ''
    var max = exports.INSPECT_MAX_BYTES
    if (this.length > 0) {
      str = this.toString('hex', 0, max).match(/.{2}/g).join(' ')
      if (this.length > max) str += ' ... '
    }
    return '<Buffer ' + str + '>'
  }
  
  Buffer.prototype.compare = function compare (target, start, end, thisStart, thisEnd) {
    if (!Buffer.isBuffer(target)) {
      throw new TypeError('Argument must be a Buffer')
    }
  
    if (start === undefined) {
      start = 0
    }
    if (end === undefined) {
      end = target ? target.length : 0
    }
    if (thisStart === undefined) {
      thisStart = 0
    }
    if (thisEnd === undefined) {
      thisEnd = this.length
    }
  
    if (start < 0 || end > target.length || thisStart < 0 || thisEnd > this.length) {
      throw new RangeError('out of range index')
    }
  
    if (thisStart >= thisEnd && start >= end) {
      return 0
    }
    if (thisStart >= thisEnd) {
      return -1
    }
    if (start >= end) {
      return 1
    }
  
    start >>>= 0
    end >>>= 0
    thisStart >>>= 0
    thisEnd >>>= 0
  
    if (this === target) return 0
  
    var x = thisEnd - thisStart
    var y = end - start
    var len = Math.min(x, y)
  
    var thisCopy = this.slice(thisStart, thisEnd)
    var targetCopy = target.slice(start, end)
  
    for (var i = 0; i < len; ++i) {
      if (thisCopy[i] !== targetCopy[i]) {
        x = thisCopy[i]
        y = targetCopy[i]
        break
      }
    }
  
    if (x < y) return -1
    if (y < x) return 1
    return 0
  }
  
  // Finds either the first index of `val` in `buffer` at offset >= `byteOffset`,
  // OR the last index of `val` in `buffer` at offset <= `byteOffset`.
  //
  // Arguments:
  // - buffer - a Buffer to search
  // - val - a string, Buffer, or number
  // - byteOffset - an index into `buffer`; will be clamped to an int32
  // - encoding - an optional encoding, relevant is val is a string
  // - dir - true for indexOf, false for lastIndexOf
  function bidirectionalIndexOf (buffer, val, byteOffset, encoding, dir) {
    // Empty buffer means no match
    if (buffer.length === 0) return -1
  
    // Normalize byteOffset
    if (typeof byteOffset === 'string') {
      encoding = byteOffset
      byteOffset = 0
    } else if (byteOffset > 0x7fffffff) {
      byteOffset = 0x7fffffff
    } else if (byteOffset < -0x80000000) {
      byteOffset = -0x80000000
    }
    byteOffset = +byteOffset  // Coerce to Number.
    if (isNaN(byteOffset)) {
      // byteOffset: it it's undefined, null, NaN, "foo", etc, search whole buffer
      byteOffset = dir ? 0 : (buffer.length - 1)
    }
  
    // Normalize byteOffset: negative offsets start from the end of the buffer
    if (byteOffset < 0) byteOffset = buffer.length + byteOffset
    if (byteOffset >= buffer.length) {
      if (dir) return -1
      else byteOffset = buffer.length - 1
    } else if (byteOffset < 0) {
      if (dir) byteOffset = 0
      else return -1
    }
  
    // Normalize val
    if (typeof val === 'string') {
      val = Buffer.from(val, encoding)
    }
  
    // Finally, search either indexOf (if dir is true) or lastIndexOf
    if (Buffer.isBuffer(val)) {
      // Special case: looking for empty string/buffer always fails
      if (val.length === 0) {
        return -1
      }
      return arrayIndexOf(buffer, val, byteOffset, encoding, dir)
    } else if (typeof val === 'number') {
      val = val & 0xFF // Search for a byte value [0-255]
      if (Buffer.TYPED_ARRAY_SUPPORT &&
          typeof Uint8Array.prototype.indexOf === 'function') {
        if (dir) {
          return Uint8Array.prototype.indexOf.call(buffer, val, byteOffset)
        } else {
          return Uint8Array.prototype.lastIndexOf.call(buffer, val, byteOffset)
        }
      }
      return arrayIndexOf(buffer, [ val ], byteOffset, encoding, dir)
    }
  
    throw new TypeError('val must be string, number or Buffer')
  }
  
  function arrayIndexOf (arr, val, byteOffset, encoding, dir) {
    var indexSize = 1
    var arrLength = arr.length
    var valLength = val.length
  
    if (encoding !== undefined) {
      encoding = String(encoding).toLowerCase()
      if (encoding === 'ucs2' || encoding === 'ucs-2' ||
          encoding === 'utf16le' || encoding === 'utf-16le') {
        if (arr.length < 2 || val.length < 2) {
          return -1
        }
        indexSize = 2
        arrLength /= 2
        valLength /= 2
        byteOffset /= 2
      }
    }
  
    function read (buf, i) {
      if (indexSize === 1) {
        return buf[i]
      } else {
        return buf.readUInt16BE(i * indexSize)
      }
    }
  
    var i
    if (dir) {
      var foundIndex = -1
      for (i = byteOffset; i < arrLength; i++) {
        if (read(arr, i) === read(val, foundIndex === -1 ? 0 : i - foundIndex)) {
          if (foundIndex === -1) foundIndex = i
          if (i - foundIndex + 1 === valLength) return foundIndex * indexSize
        } else {
          if (foundIndex !== -1) i -= i - foundIndex
          foundIndex = -1
        }
      }
    } else {
      if (byteOffset + valLength > arrLength) byteOffset = arrLength - valLength
      for (i = byteOffset; i >= 0; i--) {
        var found = true
        for (var j = 0; j < valLength; j++) {
          if (read(arr, i + j) !== read(val, j)) {
            found = false
            break
          }
        }
        if (found) return i
      }
    }
  
    return -1
  }
  
  Buffer.prototype.includes = function includes (val, byteOffset, encoding) {
    return this.indexOf(val, byteOffset, encoding) !== -1
  }
  
  Buffer.prototype.indexOf = function indexOf (val, byteOffset, encoding) {
    return bidirectionalIndexOf(this, val, byteOffset, encoding, true)
  }
  
  Buffer.prototype.lastIndexOf = function lastIndexOf (val, byteOffset, encoding) {
    return bidirectionalIndexOf(this, val, byteOffset, encoding, false)
  }
  
  function hexWrite (buf, string, offset, length) {
    offset = Number(offset) || 0
    var remaining = buf.length - offset
    if (!length) {
      length = remaining
    } else {
      length = Number(length)
      if (length > remaining) {
        length = remaining
      }
    }
  
    // must be an even number of digits
    var strLen = string.length
    if (strLen % 2 !== 0) throw new TypeError('Invalid hex string')
  
    if (length > strLen / 2) {
      length = strLen / 2
    }
    for (var i = 0; i < length; ++i) {
      var parsed = parseInt(string.substr(i * 2, 2), 16)
      if (isNaN(parsed)) return i
      buf[offset + i] = parsed
    }
    return i
  }
  
  function utf8Write (buf, string, offset, length) {
    return blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length)
  }
  
  function asciiWrite (buf, string, offset, length) {
    return blitBuffer(asciiToBytes(string), buf, offset, length)
  }
  
  function latin1Write (buf, string, offset, length) {
    return asciiWrite(buf, string, offset, length)
  }
  
  function base64Write (buf, string, offset, length) {
    return blitBuffer(base64ToBytes(string), buf, offset, length)
  }
  
  function ucs2Write (buf, string, offset, length) {
    return blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length)
  }
  
  Buffer.prototype.write = function write (string, offset, length, encoding) {
    // Buffer#write(string)
    if (offset === undefined) {
      encoding = 'utf8'
      length = this.length
      offset = 0
    // Buffer#write(string, encoding)
    } else if (length === undefined && typeof offset === 'string') {
      encoding = offset
      length = this.length
      offset = 0
    // Buffer#write(string, offset[, length][, encoding])
    } else if (isFinite(offset)) {
      offset = offset | 0
      if (isFinite(length)) {
        length = length | 0
        if (encoding === undefined) encoding = 'utf8'
      } else {
        encoding = length
        length = undefined
      }
    // legacy write(string, encoding, offset, length) - remove in v0.13
    } else {
      throw new Error(
        'Buffer.write(string, encoding, offset[, length]) is no longer supported'
      )
    }
  
    var remaining = this.length - offset
    if (length === undefined || length > remaining) length = remaining
  
    if ((string.length > 0 && (length < 0 || offset < 0)) || offset > this.length) {
      throw new RangeError('Attempt to write outside buffer bounds')
    }
  
    if (!encoding) encoding = 'utf8'
  
    var loweredCase = false
    for (;;) {
      switch (encoding) {
        case 'hex':
          return hexWrite(this, string, offset, length)
  
        case 'utf8':
        case 'utf-8':
          return utf8Write(this, string, offset, length)
  
        case 'ascii':
          return asciiWrite(this, string, offset, length)
  
        case 'latin1':
        case 'binary':
          return latin1Write(this, string, offset, length)
  
        case 'base64':
          // Warning: maxLength not taken into account in base64Write
          return base64Write(this, string, offset, length)
  
        case 'ucs2':
        case 'ucs-2':
        case 'utf16le':
        case 'utf-16le':
          return ucs2Write(this, string, offset, length)
  
        default:
          if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)
          encoding = ('' + encoding).toLowerCase()
          loweredCase = true
      }
    }
  }
  
  Buffer.prototype.toJSON = function toJSON () {
    return {
      type: 'Buffer',
      data: Array.prototype.slice.call(this._arr || this, 0)
    }
  }
  
  function base64Slice (buf, start, end) {
    if (start === 0 && end === buf.length) {
      return base64.fromByteArray(buf)
    } else {
      return base64.fromByteArray(buf.slice(start, end))
    }
  }
  
  function utf8Slice (buf, start, end) {
    end = Math.min(buf.length, end)
    var res = []
  
    var i = start
    while (i < end) {
      var firstByte = buf[i]
      var codePoint = null
      var bytesPerSequence = (firstByte > 0xEF) ? 4
        : (firstByte > 0xDF) ? 3
        : (firstByte > 0xBF) ? 2
        : 1
  
      if (i + bytesPerSequence <= end) {
        var secondByte, thirdByte, fourthByte, tempCodePoint
  
        switch (bytesPerSequence) {
          case 1:
            if (firstByte < 0x80) {
              codePoint = firstByte
            }
            break
          case 2:
            secondByte = buf[i + 1]
            if ((secondByte & 0xC0) === 0x80) {
              tempCodePoint = (firstByte & 0x1F) << 0x6 | (secondByte & 0x3F)
              if (tempCodePoint > 0x7F) {
                codePoint = tempCodePoint
              }
            }
            break
          case 3:
            secondByte = buf[i + 1]
            thirdByte = buf[i + 2]
            if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80) {
              tempCodePoint = (firstByte & 0xF) << 0xC | (secondByte & 0x3F) << 0x6 | (thirdByte & 0x3F)
              if (tempCodePoint > 0x7FF && (tempCodePoint < 0xD800 || tempCodePoint > 0xDFFF)) {
                codePoint = tempCodePoint
              }
            }
            break
          case 4:
            secondByte = buf[i + 1]
            thirdByte = buf[i + 2]
            fourthByte = buf[i + 3]
            if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80 && (fourthByte & 0xC0) === 0x80) {
              tempCodePoint = (firstByte & 0xF) << 0x12 | (secondByte & 0x3F) << 0xC | (thirdByte & 0x3F) << 0x6 | (fourthByte & 0x3F)
              if (tempCodePoint > 0xFFFF && tempCodePoint < 0x110000) {
                codePoint = tempCodePoint
              }
            }
        }
      }
  
      if (codePoint === null) {
        // we did not generate a valid codePoint so insert a
        // replacement char (U+FFFD) and advance only 1 byte
        codePoint = 0xFFFD
        bytesPerSequence = 1
      } else if (codePoint > 0xFFFF) {
        // encode to utf16 (surrogate pair dance)
        codePoint -= 0x10000
        res.push(codePoint >>> 10 & 0x3FF | 0xD800)
        codePoint = 0xDC00 | codePoint & 0x3FF
      }
  
      res.push(codePoint)
      i += bytesPerSequence
    }
  
    return decodeCodePointsArray(res)
  }
  
  // Based on http://stackoverflow.com/a/22747272/680742, the browser with
  // the lowest limit is Chrome, with 0x10000 args.
  // We go 1 magnitude less, for safety
  var MAX_ARGUMENTS_LENGTH = 0x1000
  
  function decodeCodePointsArray (codePoints) {
    var len = codePoints.length
    if (len <= MAX_ARGUMENTS_LENGTH) {
      return String.fromCharCode.apply(String, codePoints) // avoid extra slice()
    }
  
    // Decode in chunks to avoid "call stack size exceeded".
    var res = ''
    var i = 0
    while (i < len) {
      res += String.fromCharCode.apply(
        String,
        codePoints.slice(i, i += MAX_ARGUMENTS_LENGTH)
      )
    }
    return res
  }
  
  function asciiSlice (buf, start, end) {
    var ret = ''
    end = Math.min(buf.length, end)
  
    for (var i = start; i < end; ++i) {
      ret += String.fromCharCode(buf[i] & 0x7F)
    }
    return ret
  }
  
  function latin1Slice (buf, start, end) {
    var ret = ''
    end = Math.min(buf.length, end)
  
    for (var i = start; i < end; ++i) {
      ret += String.fromCharCode(buf[i])
    }
    return ret
  }
  
  function hexSlice (buf, start, end) {
    var len = buf.length
  
    if (!start || start < 0) start = 0
    if (!end || end < 0 || end > len) end = len
  
    var out = ''
    for (var i = start; i < end; ++i) {
      out += toHex(buf[i])
    }
    return out
  }
  
  function utf16leSlice (buf, start, end) {
    var bytes = buf.slice(start, end)
    var res = ''
    for (var i = 0; i < bytes.length; i += 2) {
      res += String.fromCharCode(bytes[i] + bytes[i + 1] * 256)
    }
    return res
  }
  
  Buffer.prototype.slice = function slice (start, end) {
    var len = this.length
    start = ~~start
    end = end === undefined ? len : ~~end
  
    if (start < 0) {
      start += len
      if (start < 0) start = 0
    } else if (start > len) {
      start = len
    }
  
    if (end < 0) {
      end += len
      if (end < 0) end = 0
    } else if (end > len) {
      end = len
    }
  
    if (end < start) end = start
  
    var newBuf
    if (Buffer.TYPED_ARRAY_SUPPORT) {
      newBuf = this.subarray(start, end)
      newBuf.__proto__ = Buffer.prototype
    } else {
      var sliceLen = end - start
      newBuf = new Buffer(sliceLen, undefined)
      for (var i = 0; i < sliceLen; ++i) {
        newBuf[i] = this[i + start]
      }
    }
  
    return newBuf
  }
  
  /*
   * Need to make sure that buffer isn't trying to write out of bounds.
   */
  function checkOffset (offset, ext, length) {
    if ((offset % 1) !== 0 || offset < 0) throw new RangeError('offset is not uint')
    if (offset + ext > length) throw new RangeError('Trying to access beyond buffer length')
  }
  
  Buffer.prototype.readUIntLE = function readUIntLE (offset, byteLength, noAssert) {
    offset = offset | 0
    byteLength = byteLength | 0
    if (!noAssert) checkOffset(offset, byteLength, this.length)
  
    var val = this[offset]
    var mul = 1
    var i = 0
    while (++i < byteLength && (mul *= 0x100)) {
      val += this[offset + i] * mul
    }
  
    return val
  }
  
  Buffer.prototype.readUIntBE = function readUIntBE (offset, byteLength, noAssert) {
    offset = offset | 0
    byteLength = byteLength | 0
    if (!noAssert) {
      checkOffset(offset, byteLength, this.length)
    }
  
    var val = this[offset + --byteLength]
    var mul = 1
    while (byteLength > 0 && (mul *= 0x100)) {
      val += this[offset + --byteLength] * mul
    }
  
    return val
  }
  
  Buffer.prototype.readUInt8 = function readUInt8 (offset, noAssert) {
    if (!noAssert) checkOffset(offset, 1, this.length)
    return this[offset]
  }
  
  Buffer.prototype.readUInt16LE = function readUInt16LE (offset, noAssert) {
    if (!noAssert) checkOffset(offset, 2, this.length)
    return this[offset] | (this[offset + 1] << 8)
  }
  
  Buffer.prototype.readUInt16BE = function readUInt16BE (offset, noAssert) {
    if (!noAssert) checkOffset(offset, 2, this.length)
    return (this[offset] << 8) | this[offset + 1]
  }
  
  Buffer.prototype.readUInt32LE = function readUInt32LE (offset, noAssert) {
    if (!noAssert) checkOffset(offset, 4, this.length)
  
    return ((this[offset]) |
        (this[offset + 1] << 8) |
        (this[offset + 2] << 16)) +
        (this[offset + 3] * 0x1000000)
  }
  
  Buffer.prototype.readUInt32BE = function readUInt32BE (offset, noAssert) {
    if (!noAssert) checkOffset(offset, 4, this.length)
  
    return (this[offset] * 0x1000000) +
      ((this[offset + 1] << 16) |
      (this[offset + 2] << 8) |
      this[offset + 3])
  }
  
  Buffer.prototype.readIntLE = function readIntLE (offset, byteLength, noAssert) {
    offset = offset | 0
    byteLength = byteLength | 0
    if (!noAssert) checkOffset(offset, byteLength, this.length)
  
    var val = this[offset]
    var mul = 1
    var i = 0
    while (++i < byteLength && (mul *= 0x100)) {
      val += this[offset + i] * mul
    }
    mul *= 0x80
  
    if (val >= mul) val -= Math.pow(2, 8 * byteLength)
  
    return val
  }
  
  Buffer.prototype.readIntBE = function readIntBE (offset, byteLength, noAssert) {
    offset = offset | 0
    byteLength = byteLength | 0
    if (!noAssert) checkOffset(offset, byteLength, this.length)
  
    var i = byteLength
    var mul = 1
    var val = this[offset + --i]
    while (i > 0 && (mul *= 0x100)) {
      val += this[offset + --i] * mul
    }
    mul *= 0x80
  
    if (val >= mul) val -= Math.pow(2, 8 * byteLength)
  
    return val
  }
  
  Buffer.prototype.readInt8 = function readInt8 (offset, noAssert) {
    if (!noAssert) checkOffset(offset, 1, this.length)
    if (!(this[offset] & 0x80)) return (this[offset])
    return ((0xff - this[offset] + 1) * -1)
  }
  
  Buffer.prototype.readInt16LE = function readInt16LE (offset, noAssert) {
    if (!noAssert) checkOffset(offset, 2, this.length)
    var val = this[offset] | (this[offset + 1] << 8)
    return (val & 0x8000) ? val | 0xFFFF0000 : val
  }
  
  Buffer.prototype.readInt16BE = function readInt16BE (offset, noAssert) {
    if (!noAssert) checkOffset(offset, 2, this.length)
    var val = this[offset + 1] | (this[offset] << 8)
    return (val & 0x8000) ? val | 0xFFFF0000 : val
  }
  
  Buffer.prototype.readInt32LE = function readInt32LE (offset, noAssert) {
    if (!noAssert) checkOffset(offset, 4, this.length)
  
    return (this[offset]) |
      (this[offset + 1] << 8) |
      (this[offset + 2] << 16) |
      (this[offset + 3] << 24)
  }
  
  Buffer.prototype.readInt32BE = function readInt32BE (offset, noAssert) {
    if (!noAssert) checkOffset(offset, 4, this.length)
  
    return (this[offset] << 24) |
      (this[offset + 1] << 16) |
      (this[offset + 2] << 8) |
      (this[offset + 3])
  }
  
  Buffer.prototype.readFloatLE = function readFloatLE (offset, noAssert) {
    if (!noAssert) checkOffset(offset, 4, this.length)
    return ieee754.read(this, offset, true, 23, 4)
  }
  
  Buffer.prototype.readFloatBE = function readFloatBE (offset, noAssert) {
    if (!noAssert) checkOffset(offset, 4, this.length)
    return ieee754.read(this, offset, false, 23, 4)
  }
  
  Buffer.prototype.readDoubleLE = function readDoubleLE (offset, noAssert) {
    if (!noAssert) checkOffset(offset, 8, this.length)
    return ieee754.read(this, offset, true, 52, 8)
  }
  
  Buffer.prototype.readDoubleBE = function readDoubleBE (offset, noAssert) {
    if (!noAssert) checkOffset(offset, 8, this.length)
    return ieee754.read(this, offset, false, 52, 8)
  }
  
  function checkInt (buf, value, offset, ext, max, min) {
    if (!Buffer.isBuffer(buf)) throw new TypeError('"buffer" argument must be a Buffer instance')
    if (value > max || value < min) throw new RangeError('"value" argument is out of bounds')
    if (offset + ext > buf.length) throw new RangeError('Index out of range')
  }
  
  Buffer.prototype.writeUIntLE = function writeUIntLE (value, offset, byteLength, noAssert) {
    value = +value
    offset = offset | 0
    byteLength = byteLength | 0
    if (!noAssert) {
      var maxBytes = Math.pow(2, 8 * byteLength) - 1
      checkInt(this, value, offset, byteLength, maxBytes, 0)
    }
  
    var mul = 1
    var i = 0
    this[offset] = value & 0xFF
    while (++i < byteLength && (mul *= 0x100)) {
      this[offset + i] = (value / mul) & 0xFF
    }
  
    return offset + byteLength
  }
  
  Buffer.prototype.writeUIntBE = function writeUIntBE (value, offset, byteLength, noAssert) {
    value = +value
    offset = offset | 0
    byteLength = byteLength | 0
    if (!noAssert) {
      var maxBytes = Math.pow(2, 8 * byteLength) - 1
      checkInt(this, value, offset, byteLength, maxBytes, 0)
    }
  
    var i = byteLength - 1
    var mul = 1
    this[offset + i] = value & 0xFF
    while (--i >= 0 && (mul *= 0x100)) {
      this[offset + i] = (value / mul) & 0xFF
    }
  
    return offset + byteLength
  }
  
  Buffer.prototype.writeUInt8 = function writeUInt8 (value, offset, noAssert) {
    value = +value
    offset = offset | 0
    if (!noAssert) checkInt(this, value, offset, 1, 0xff, 0)
    if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value)
    this[offset] = (value & 0xff)
    return offset + 1
  }
  
  function objectWriteUInt16 (buf, value, offset, littleEndian) {
    if (value < 0) value = 0xffff + value + 1
    for (var i = 0, j = Math.min(buf.length - offset, 2); i < j; ++i) {
      buf[offset + i] = (value & (0xff << (8 * (littleEndian ? i : 1 - i)))) >>>
        (littleEndian ? i : 1 - i) * 8
    }
  }
  
  Buffer.prototype.writeUInt16LE = function writeUInt16LE (value, offset, noAssert) {
    value = +value
    offset = offset | 0
    if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)
    if (Buffer.TYPED_ARRAY_SUPPORT) {
      this[offset] = (value & 0xff)
      this[offset + 1] = (value >>> 8)
    } else {
      objectWriteUInt16(this, value, offset, true)
    }
    return offset + 2
  }
  
  Buffer.prototype.writeUInt16BE = function writeUInt16BE (value, offset, noAssert) {
    value = +value
    offset = offset | 0
    if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)
    if (Buffer.TYPED_ARRAY_SUPPORT) {
      this[offset] = (value >>> 8)
      this[offset + 1] = (value & 0xff)
    } else {
      objectWriteUInt16(this, value, offset, false)
    }
    return offset + 2
  }
  
  function objectWriteUInt32 (buf, value, offset, littleEndian) {
    if (value < 0) value = 0xffffffff + value + 1
    for (var i = 0, j = Math.min(buf.length - offset, 4); i < j; ++i) {
      buf[offset + i] = (value >>> (littleEndian ? i : 3 - i) * 8) & 0xff
    }
  }
  
  Buffer.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert) {
    value = +value
    offset = offset | 0
    if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)
    if (Buffer.TYPED_ARRAY_SUPPORT) {
      this[offset + 3] = (value >>> 24)
      this[offset + 2] = (value >>> 16)
      this[offset + 1] = (value >>> 8)
      this[offset] = (value & 0xff)
    } else {
      objectWriteUInt32(this, value, offset, true)
    }
    return offset + 4
  }
  
  Buffer.prototype.writeUInt32BE = function writeUInt32BE (value, offset, noAssert) {
    value = +value
    offset = offset | 0
    if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)
    if (Buffer.TYPED_ARRAY_SUPPORT) {
      this[offset] = (value >>> 24)
      this[offset + 1] = (value >>> 16)
      this[offset + 2] = (value >>> 8)
      this[offset + 3] = (value & 0xff)
    } else {
      objectWriteUInt32(this, value, offset, false)
    }
    return offset + 4
  }
  
  Buffer.prototype.writeIntLE = function writeIntLE (value, offset, byteLength, noAssert) {
    value = +value
    offset = offset | 0
    if (!noAssert) {
      var limit = Math.pow(2, 8 * byteLength - 1)
  
      checkInt(this, value, offset, byteLength, limit - 1, -limit)
    }
  
    var i = 0
    var mul = 1
    var sub = 0
    this[offset] = value & 0xFF
    while (++i < byteLength && (mul *= 0x100)) {
      if (value < 0 && sub === 0 && this[offset + i - 1] !== 0) {
        sub = 1
      }
      this[offset + i] = ((value / mul) >> 0) - sub & 0xFF
    }
  
    return offset + byteLength
  }
  
  Buffer.prototype.writeIntBE = function writeIntBE (value, offset, byteLength, noAssert) {
    value = +value
    offset = offset | 0
    if (!noAssert) {
      var limit = Math.pow(2, 8 * byteLength - 1)
  
      checkInt(this, value, offset, byteLength, limit - 1, -limit)
    }
  
    var i = byteLength - 1
    var mul = 1
    var sub = 0
    this[offset + i] = value & 0xFF
    while (--i >= 0 && (mul *= 0x100)) {
      if (value < 0 && sub === 0 && this[offset + i + 1] !== 0) {
        sub = 1
      }
      this[offset + i] = ((value / mul) >> 0) - sub & 0xFF
    }
  
    return offset + byteLength
  }
  
  Buffer.prototype.writeInt8 = function writeInt8 (value, offset, noAssert) {
    value = +value
    offset = offset | 0
    if (!noAssert) checkInt(this, value, offset, 1, 0x7f, -0x80)
    if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value)
    if (value < 0) value = 0xff + value + 1
    this[offset] = (value & 0xff)
    return offset + 1
  }
  
  Buffer.prototype.writeInt16LE = function writeInt16LE (value, offset, noAssert) {
    value = +value
    offset = offset | 0
    if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)
    if (Buffer.TYPED_ARRAY_SUPPORT) {
      this[offset] = (value & 0xff)
      this[offset + 1] = (value >>> 8)
    } else {
      objectWriteUInt16(this, value, offset, true)
    }
    return offset + 2
  }
  
  Buffer.prototype.writeInt16BE = function writeInt16BE (value, offset, noAssert) {
    value = +value
    offset = offset | 0
    if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)
    if (Buffer.TYPED_ARRAY_SUPPORT) {
      this[offset] = (value >>> 8)
      this[offset + 1] = (value & 0xff)
    } else {
      objectWriteUInt16(this, value, offset, false)
    }
    return offset + 2
  }
  
  Buffer.prototype.writeInt32LE = function writeInt32LE (value, offset, noAssert) {
    value = +value
    offset = offset | 0
    if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)
    if (Buffer.TYPED_ARRAY_SUPPORT) {
      this[offset] = (value & 0xff)
      this[offset + 1] = (value >>> 8)
      this[offset + 2] = (value >>> 16)
      this[offset + 3] = (value >>> 24)
    } else {
      objectWriteUInt32(this, value, offset, true)
    }
    return offset + 4
  }
  
  Buffer.prototype.writeInt32BE = function writeInt32BE (value, offset, noAssert) {
    value = +value
    offset = offset | 0
    if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)
    if (value < 0) value = 0xffffffff + value + 1
    if (Buffer.TYPED_ARRAY_SUPPORT) {
      this[offset] = (value >>> 24)
      this[offset + 1] = (value >>> 16)
      this[offset + 2] = (value >>> 8)
      this[offset + 3] = (value & 0xff)
    } else {
      objectWriteUInt32(this, value, offset, false)
    }
    return offset + 4
  }
  
  function checkIEEE754 (buf, value, offset, ext, max, min) {
    if (offset + ext > buf.length) throw new RangeError('Index out of range')
    if (offset < 0) throw new RangeError('Index out of range')
  }
  
  function writeFloat (buf, value, offset, littleEndian, noAssert) {
    if (!noAssert) {
      checkIEEE754(buf, value, offset, 4, 3.4028234663852886e+38, -3.4028234663852886e+38)
    }
    ieee754.write(buf, value, offset, littleEndian, 23, 4)
    return offset + 4
  }
  
  Buffer.prototype.writeFloatLE = function writeFloatLE (value, offset, noAssert) {
    return writeFloat(this, value, offset, true, noAssert)
  }
  
  Buffer.prototype.writeFloatBE = function writeFloatBE (value, offset, noAssert) {
    return writeFloat(this, value, offset, false, noAssert)
  }
  
  function writeDouble (buf, value, offset, littleEndian, noAssert) {
    if (!noAssert) {
      checkIEEE754(buf, value, offset, 8, 1.7976931348623157E+308, -1.7976931348623157E+308)
    }
    ieee754.write(buf, value, offset, littleEndian, 52, 8)
    return offset + 8
  }
  
  Buffer.prototype.writeDoubleLE = function writeDoubleLE (value, offset, noAssert) {
    return writeDouble(this, value, offset, true, noAssert)
  }
  
  Buffer.prototype.writeDoubleBE = function writeDoubleBE (value, offset, noAssert) {
    return writeDouble(this, value, offset, false, noAssert)
  }
  
  // copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length)
  Buffer.prototype.copy = function copy (target, targetStart, start, end) {
    if (!start) start = 0
    if (!end && end !== 0) end = this.length
    if (targetStart >= target.length) targetStart = target.length
    if (!targetStart) targetStart = 0
    if (end > 0 && end < start) end = start
  
    // Copy 0 bytes; we're done
    if (end === start) return 0
    if (target.length === 0 || this.length === 0) return 0
  
    // Fatal error conditions
    if (targetStart < 0) {
      throw new RangeError('targetStart out of bounds')
    }
    if (start < 0 || start >= this.length) throw new RangeError('sourceStart out of bounds')
    if (end < 0) throw new RangeError('sourceEnd out of bounds')
  
    // Are we oob?
    if (end > this.length) end = this.length
    if (target.length - targetStart < end - start) {
      end = target.length - targetStart + start
    }
  
    var len = end - start
    var i
  
    if (this === target && start < targetStart && targetStart < end) {
      // descending copy from end
      for (i = len - 1; i >= 0; --i) {
        target[i + targetStart] = this[i + start]
      }
    } else if (len < 1000 || !Buffer.TYPED_ARRAY_SUPPORT) {
      // ascending copy from start
      for (i = 0; i < len; ++i) {
        target[i + targetStart] = this[i + start]
      }
    } else {
      Uint8Array.prototype.set.call(
        target,
        this.subarray(start, start + len),
        targetStart
      )
    }
  
    return len
  }
  
  // Usage:
  //    buffer.fill(number[, offset[, end]])
  //    buffer.fill(buffer[, offset[, end]])
  //    buffer.fill(string[, offset[, end]][, encoding])
  Buffer.prototype.fill = function fill (val, start, end, encoding) {
    // Handle string cases:
    if (typeof val === 'string') {
      if (typeof start === 'string') {
        encoding = start
        start = 0
        end = this.length
      } else if (typeof end === 'string') {
        encoding = end
        end = this.length
      }
      if (val.length === 1) {
        var code = val.charCodeAt(0)
        if (code < 256) {
          val = code
        }
      }
      if (encoding !== undefined && typeof encoding !== 'string') {
        throw new TypeError('encoding must be a string')
      }
      if (typeof encoding === 'string' && !Buffer.isEncoding(encoding)) {
        throw new TypeError('Unknown encoding: ' + encoding)
      }
    } else if (typeof val === 'number') {
      val = val & 255
    }
  
    // Invalid ranges are not set to a default, so can range check early.
    if (start < 0 || this.length < start || this.length < end) {
      throw new RangeError('Out of range index')
    }
  
    if (end <= start) {
      return this
    }
  
    start = start >>> 0
    end = end === undefined ? this.length : end >>> 0
  
    if (!val) val = 0
  
    var i
    if (typeof val === 'number') {
      for (i = start; i < end; ++i) {
        this[i] = val
      }
    } else {
      var bytes = Buffer.isBuffer(val)
        ? val
        : utf8ToBytes(new Buffer(val, encoding).toString())
      var len = bytes.length
      for (i = 0; i < end - start; ++i) {
        this[i + start] = bytes[i % len]
      }
    }
  
    return this
  }
  
  // HELPER FUNCTIONS
  // ================
  
  var INVALID_BASE64_RE = /[^+\/0-9A-Za-z-_]/g
  
  function base64clean (str) {
    // Node strips out invalid characters like \n and \t from the string, base64-js does not
    str = stringtrim(str).replace(INVALID_BASE64_RE, '')
    // Node converts strings with length < 2 to ''
    if (str.length < 2) return ''
    // Node allows for non-padded base64 strings (missing trailing ===), base64-js does not
    while (str.length % 4 !== 0) {
      str = str + '='
    }
    return str
  }
  
  function stringtrim (str) {
    if (str.trim) return str.trim()
    return str.replace(/^\s+|\s+$/g, '')
  }
  
  function toHex (n) {
    if (n < 16) return '0' + n.toString(16)
    return n.toString(16)
  }
  
  function utf8ToBytes (string, units) {
    units = units || Infinity
    var codePoint
    var length = string.length
    var leadSurrogate = null
    var bytes = []
  
    for (var i = 0; i < length; ++i) {
      codePoint = string.charCodeAt(i)
  
      // is surrogate component
      if (codePoint > 0xD7FF && codePoint < 0xE000) {
        // last char was a lead
        if (!leadSurrogate) {
          // no lead yet
          if (codePoint > 0xDBFF) {
            // unexpected trail
            if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
            continue
          } else if (i + 1 === length) {
            // unpaired lead
            if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
            continue
          }
  
          // valid lead
          leadSurrogate = codePoint
  
          continue
        }
  
        // 2 leads in a row
        if (codePoint < 0xDC00) {
          if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
          leadSurrogate = codePoint
          continue
        }
  
        // valid surrogate pair
        codePoint = (leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00) + 0x10000
      } else if (leadSurrogate) {
        // valid bmp char, but last char was a lead
        if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
      }
  
      leadSurrogate = null
  
      // encode utf8
      if (codePoint < 0x80) {
        if ((units -= 1) < 0) break
        bytes.push(codePoint)
      } else if (codePoint < 0x800) {
        if ((units -= 2) < 0) break
        bytes.push(
          codePoint >> 0x6 | 0xC0,
          codePoint & 0x3F | 0x80
        )
      } else if (codePoint < 0x10000) {
        if ((units -= 3) < 0) break
        bytes.push(
          codePoint >> 0xC | 0xE0,
          codePoint >> 0x6 & 0x3F | 0x80,
          codePoint & 0x3F | 0x80
        )
      } else if (codePoint < 0x110000) {
        if ((units -= 4) < 0) break
        bytes.push(
          codePoint >> 0x12 | 0xF0,
          codePoint >> 0xC & 0x3F | 0x80,
          codePoint >> 0x6 & 0x3F | 0x80,
          codePoint & 0x3F | 0x80
        )
      } else {
        throw new Error('Invalid code point')
      }
    }
  
    return bytes
  }
  
  function asciiToBytes (str) {
    var byteArray = []
    for (var i = 0; i < str.length; ++i) {
      // Node's code seems to be doing this and not & 0x7F..
      byteArray.push(str.charCodeAt(i) & 0xFF)
    }
    return byteArray
  }
  
  function utf16leToBytes (str, units) {
    var c, hi, lo
    var byteArray = []
    for (var i = 0; i < str.length; ++i) {
      if ((units -= 2) < 0) break
  
      c = str.charCodeAt(i)
      hi = c >> 8
      lo = c % 256
      byteArray.push(lo)
      byteArray.push(hi)
    }
  
    return byteArray
  }
  
  function base64ToBytes (str) {
    return base64.toByteArray(base64clean(str))
  }
  
  function blitBuffer (src, dst, offset, length) {
    for (var i = 0; i < length; ++i) {
      if ((i + offset >= dst.length) || (i >= src.length)) break
      dst[i + offset] = src[i]
    }
    return i
  }
  
  function isnan (val) {
    return val !== val // eslint-disable-line no-self-compare
  }
  
  }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
  },{"base64-js":76,"ieee754":82,"isarray":85}],80:[function(require,module,exports){
  (function (Buffer){
  // Copyright Joyent, Inc. and other Node contributors.
  //
  // Permission is hereby granted, free of charge, to any person obtaining a
  // copy of this software and associated documentation files (the
  // "Software"), to deal in the Software without restriction, including
  // without limitation the rights to use, copy, modify, merge, publish,
  // distribute, sublicense, and/or sell copies of the Software, and to permit
  // persons to whom the Software is furnished to do so, subject to the
  // following conditions:
  //
  // The above copyright notice and this permission notice shall be included
  // in all copies or substantial portions of the Software.
  //
  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
  // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
  // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
  // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
  // USE OR OTHER DEALINGS IN THE SOFTWARE.
  
  // NOTE: These type checking functions intentionally don't use `instanceof`
  // because it is fragile and can be easily faked with `Object.create()`.
  
  function isArray(arg) {
    if (Array.isArray) {
      return Array.isArray(arg);
    }
    return objectToString(arg) === '[object Array]';
  }
  exports.isArray = isArray;
  
  function isBoolean(arg) {
    return typeof arg === 'boolean';
  }
  exports.isBoolean = isBoolean;
  
  function isNull(arg) {
    return arg === null;
  }
  exports.isNull = isNull;
  
  function isNullOrUndefined(arg) {
    return arg == null;
  }
  exports.isNullOrUndefined = isNullOrUndefined;
  
  function isNumber(arg) {
    return typeof arg === 'number';
  }
  exports.isNumber = isNumber;
  
  function isString(arg) {
    return typeof arg === 'string';
  }
  exports.isString = isString;
  
  function isSymbol(arg) {
    return typeof arg === 'symbol';
  }
  exports.isSymbol = isSymbol;
  
  function isUndefined(arg) {
    return arg === void 0;
  }
  exports.isUndefined = isUndefined;
  
  function isRegExp(re) {
    return objectToString(re) === '[object RegExp]';
  }
  exports.isRegExp = isRegExp;
  
  function isObject(arg) {
    return typeof arg === 'object' && arg !== null;
  }
  exports.isObject = isObject;
  
  function isDate(d) {
    return objectToString(d) === '[object Date]';
  }
  exports.isDate = isDate;
  
  function isError(e) {
    return (objectToString(e) === '[object Error]' || e instanceof Error);
  }
  exports.isError = isError;
  
  function isFunction(arg) {
    return typeof arg === 'function';
  }
  exports.isFunction = isFunction;
  
  function isPrimitive(arg) {
    return arg === null ||
           typeof arg === 'boolean' ||
           typeof arg === 'number' ||
           typeof arg === 'string' ||
           typeof arg === 'symbol' ||  // ES6 symbol
           typeof arg === 'undefined';
  }
  exports.isPrimitive = isPrimitive;
  
  exports.isBuffer = Buffer.isBuffer;
  
  function objectToString(o) {
    return Object.prototype.toString.call(o);
  }
  
  }).call(this,{"isBuffer":require("../../is-buffer/index.js")})
  },{"../../is-buffer/index.js":84}],81:[function(require,module,exports){
  // Copyright Joyent, Inc. and other Node contributors.
  //
  // Permission is hereby granted, free of charge, to any person obtaining a
  // copy of this software and associated documentation files (the
  // "Software"), to deal in the Software without restriction, including
  // without limitation the rights to use, copy, modify, merge, publish,
  // distribute, sublicense, and/or sell copies of the Software, and to permit
  // persons to whom the Software is furnished to do so, subject to the
  // following conditions:
  //
  // The above copyright notice and this permission notice shall be included
  // in all copies or substantial portions of the Software.
  //
  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
  // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
  // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
  // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
  // USE OR OTHER DEALINGS IN THE SOFTWARE.
  
  function EventEmitter() {
    this._events = this._events || {};
    this._maxListeners = this._maxListeners || undefined;
  }
  module.exports = EventEmitter;
  
  // Backwards-compat with node 0.10.x
  EventEmitter.EventEmitter = EventEmitter;
  
  EventEmitter.prototype._events = undefined;
  EventEmitter.prototype._maxListeners = undefined;
  
  // By default EventEmitters will print a warning if more than 10 listeners are
  // added to it. This is a useful default which helps finding memory leaks.
  EventEmitter.defaultMaxListeners = 10;
  
  // Obviously not all Emitters should be limited to 10. This function allows
  // that to be increased. Set to zero for unlimited.
  EventEmitter.prototype.setMaxListeners = function(n) {
    if (!isNumber(n) || n < 0 || isNaN(n))
      throw TypeError('n must be a positive number');
    this._maxListeners = n;
    return this;
  };
  
  EventEmitter.prototype.emit = function(type) {
    var er, handler, len, args, i, listeners;
  
    if (!this._events)
      this._events = {};
  
    // If there is no 'error' event listener then throw.
    if (type === 'error') {
      if (!this._events.error ||
          (isObject(this._events.error) && !this._events.error.length)) {
        er = arguments[1];
        if (er instanceof Error) {
          throw er; // Unhandled 'error' event
        } else {
          // At least give some kind of context to the user
          var err = new Error('Uncaught, unspecified "error" event. (' + er + ')');
          err.context = er;
          throw err;
        }
      }
    }
  
    handler = this._events[type];
  
    if (isUndefined(handler))
      return false;
  
    if (isFunction(handler)) {
      switch (arguments.length) {
        // fast cases
        case 1:
          handler.call(this);
          break;
        case 2:
          handler.call(this, arguments[1]);
          break;
        case 3:
          handler.call(this, arguments[1], arguments[2]);
          break;
        // slower
        default:
          args = Array.prototype.slice.call(arguments, 1);
          handler.apply(this, args);
      }
    } else if (isObject(handler)) {
      args = Array.prototype.slice.call(arguments, 1);
      listeners = handler.slice();
      len = listeners.length;
      for (i = 0; i < len; i++)
        listeners[i].apply(this, args);
    }
  
    return true;
  };
  
  EventEmitter.prototype.addListener = function(type, listener) {
    var m;
  
    if (!isFunction(listener))
      throw TypeError('listener must be a function');
  
    if (!this._events)
      this._events = {};
  
    // To avoid recursion in the case that type === "newListener"! Before
    // adding it to the listeners, first emit "newListener".
    if (this._events.newListener)
      this.emit('newListener', type,
                isFunction(listener.listener) ?
                listener.listener : listener);
  
    if (!this._events[type])
      // Optimize the case of one listener. Don't need the extra array object.
      this._events[type] = listener;
    else if (isObject(this._events[type]))
      // If we've already got an array, just append.
      this._events[type].push(listener);
    else
      // Adding the second element, need to change to array.
      this._events[type] = [this._events[type], listener];
  
    // Check for listener leak
    if (isObject(this._events[type]) && !this._events[type].warned) {
      if (!isUndefined(this._maxListeners)) {
        m = this._maxListeners;
      } else {
        m = EventEmitter.defaultMaxListeners;
      }
  
      if (m && m > 0 && this._events[type].length > m) {
        this._events[type].warned = true;
        console.error('(node) warning: possible EventEmitter memory ' +
                      'leak detected. %d listeners added. ' +
                      'Use emitter.setMaxListeners() to increase limit.',
                      this._events[type].length);
        if (typeof console.trace === 'function') {
          // not supported in IE 10
          console.trace();
        }
      }
    }
  
    return this;
  };
  
  EventEmitter.prototype.on = EventEmitter.prototype.addListener;
  
  EventEmitter.prototype.once = function(type, listener) {
    if (!isFunction(listener))
      throw TypeError('listener must be a function');
  
    var fired = false;
  
    function g() {
      this.removeListener(type, g);
  
      if (!fired) {
        fired = true;
        listener.apply(this, arguments);
      }
    }
  
    g.listener = listener;
    this.on(type, g);
  
    return this;
  };
  
  // emits a 'removeListener' event iff the listener was removed
  EventEmitter.prototype.removeListener = function(type, listener) {
    var list, position, length, i;
  
    if (!isFunction(listener))
      throw TypeError('listener must be a function');
  
    if (!this._events || !this._events[type])
      return this;
  
    list = this._events[type];
    length = list.length;
    position = -1;
  
    if (list === listener ||
        (isFunction(list.listener) && list.listener === listener)) {
      delete this._events[type];
      if (this._events.removeListener)
        this.emit('removeListener', type, listener);
  
    } else if (isObject(list)) {
      for (i = length; i-- > 0;) {
        if (list[i] === listener ||
            (list[i].listener && list[i].listener === listener)) {
          position = i;
          break;
        }
      }
  
      if (position < 0)
        return this;
  
      if (list.length === 1) {
        list.length = 0;
        delete this._events[type];
      } else {
        list.splice(position, 1);
      }
  
      if (this._events.removeListener)
        this.emit('removeListener', type, listener);
    }
  
    return this;
  };
  
  EventEmitter.prototype.removeAllListeners = function(type) {
    var key, listeners;
  
    if (!this._events)
      return this;
  
    // not listening for removeListener, no need to emit
    if (!this._events.removeListener) {
      if (arguments.length === 0)
        this._events = {};
      else if (this._events[type])
        delete this._events[type];
      return this;
    }
  
    // emit removeListener for all listeners on all events
    if (arguments.length === 0) {
      for (key in this._events) {
        if (key === 'removeListener') continue;
        this.removeAllListeners(key);
      }
      this.removeAllListeners('removeListener');
      this._events = {};
      return this;
    }
  
    listeners = this._events[type];
  
    if (isFunction(listeners)) {
      this.removeListener(type, listeners);
    } else if (listeners) {
      // LIFO order
      while (listeners.length)
        this.removeListener(type, listeners[listeners.length - 1]);
    }
    delete this._events[type];
  
    return this;
  };
  
  EventEmitter.prototype.listeners = function(type) {
    var ret;
    if (!this._events || !this._events[type])
      ret = [];
    else if (isFunction(this._events[type]))
      ret = [this._events[type]];
    else
      ret = this._events[type].slice();
    return ret;
  };
  
  EventEmitter.prototype.listenerCount = function(type) {
    if (this._events) {
      var evlistener = this._events[type];
  
      if (isFunction(evlistener))
        return 1;
      else if (evlistener)
        return evlistener.length;
    }
    return 0;
  };
  
  EventEmitter.listenerCount = function(emitter, type) {
    return emitter.listenerCount(type);
  };
  
  function isFunction(arg) {
    return typeof arg === 'function';
  }
  
  function isNumber(arg) {
    return typeof arg === 'number';
  }
  
  function isObject(arg) {
    return typeof arg === 'object' && arg !== null;
  }
  
  function isUndefined(arg) {
    return arg === void 0;
  }
  
  },{}],82:[function(require,module,exports){
  exports.read = function (buffer, offset, isLE, mLen, nBytes) {
    var e, m
    var eLen = nBytes * 8 - mLen - 1
    var eMax = (1 << eLen) - 1
    var eBias = eMax >> 1
    var nBits = -7
    var i = isLE ? (nBytes - 1) : 0
    var d = isLE ? -1 : 1
    var s = buffer[offset + i]
  
    i += d
  
    e = s & ((1 << (-nBits)) - 1)
    s >>= (-nBits)
    nBits += eLen
    for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8) {}
  
    m = e & ((1 << (-nBits)) - 1)
    e >>= (-nBits)
    nBits += mLen
    for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8) {}
  
    if (e === 0) {
      e = 1 - eBias
    } else if (e === eMax) {
      return m ? NaN : ((s ? -1 : 1) * Infinity)
    } else {
      m = m + Math.pow(2, mLen)
      e = e - eBias
    }
    return (s ? -1 : 1) * m * Math.pow(2, e - mLen)
  }
  
  exports.write = function (buffer, value, offset, isLE, mLen, nBytes) {
    var e, m, c
    var eLen = nBytes * 8 - mLen - 1
    var eMax = (1 << eLen) - 1
    var eBias = eMax >> 1
    var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0)
    var i = isLE ? 0 : (nBytes - 1)
    var d = isLE ? 1 : -1
    var s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0
  
    value = Math.abs(value)
  
    if (isNaN(value) || value === Infinity) {
      m = isNaN(value) ? 1 : 0
      e = eMax
    } else {
      e = Math.floor(Math.log(value) / Math.LN2)
      if (value * (c = Math.pow(2, -e)) < 1) {
        e--
        c *= 2
      }
      if (e + eBias >= 1) {
        value += rt / c
      } else {
        value += rt * Math.pow(2, 1 - eBias)
      }
      if (value * c >= 2) {
        e++
        c /= 2
      }
  
      if (e + eBias >= eMax) {
        m = 0
        e = eMax
      } else if (e + eBias >= 1) {
        m = (value * c - 1) * Math.pow(2, mLen)
        e = e + eBias
      } else {
        m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen)
        e = 0
      }
    }
  
    for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {}
  
    e = (e << mLen) | m
    eLen += mLen
    for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {}
  
    buffer[offset + i - d] |= s * 128
  }
  
  },{}],83:[function(require,module,exports){
  arguments[4][63][0].apply(exports,arguments)
  },{"dup":63}],84:[function(require,module,exports){
  /*!
   * Determine if an object is a Buffer
   *
   * @author   Feross Aboukhadijeh <feross@feross.org> <http://feross.org>
   * @license  MIT
   */
  
  // The _isBuffer check is for Safari 5-7 support, because it's missing
  // Object.prototype.constructor. Remove this eventually
  module.exports = function (obj) {
    return obj != null && (isBuffer(obj) || isSlowBuffer(obj) || !!obj._isBuffer)
  }
  
  function isBuffer (obj) {
    return !!obj.constructor && typeof obj.constructor.isBuffer === 'function' && obj.constructor.isBuffer(obj)
  }
  
  // For Node v0.10 support. Remove this eventually.
  function isSlowBuffer (obj) {
    return typeof obj.readFloatLE === 'function' && typeof obj.slice === 'function' && isBuffer(obj.slice(0, 0))
  }
  
  },{}],85:[function(require,module,exports){
  var toString = {}.toString;
  
  module.exports = Array.isArray || function (arr) {
    return toString.call(arr) == '[object Array]';
  };
  
  },{}],86:[function(require,module,exports){
  (function (process){
  'use strict';
  
  if (!process.version ||
      process.version.indexOf('v0.') === 0 ||
      process.version.indexOf('v1.') === 0 && process.version.indexOf('v1.8.') !== 0) {
    module.exports = nextTick;
  } else {
    module.exports = process.nextTick;
  }
  
  function nextTick(fn, arg1, arg2, arg3) {
    if (typeof fn !== 'function') {
      throw new TypeError('"callback" argument must be a function');
    }
    var len = arguments.length;
    var args, i;
    switch (len) {
    case 0:
    case 1:
      return process.nextTick(fn);
    case 2:
      return process.nextTick(function afterTickOne() {
        fn.call(null, arg1);
      });
    case 3:
      return process.nextTick(function afterTickTwo() {
        fn.call(null, arg1, arg2);
      });
    case 4:
      return process.nextTick(function afterTickThree() {
        fn.call(null, arg1, arg2, arg3);
      });
    default:
      args = new Array(len - 1);
      i = 0;
      while (i < args.length) {
        args[i++] = arguments[i];
      }
      return process.nextTick(function afterTick() {
        fn.apply(null, args);
      });
    }
  }
  
  }).call(this,require('_process'))
  },{"_process":87}],87:[function(require,module,exports){
  // shim for using process in browser
  var process = module.exports = {};
  
  // cached from whatever global is present so that test runners that stub it
  // don't break things.  But we need to wrap it in a try catch in case it is
  // wrapped in strict mode code which doesn't define any globals.  It's inside a
  // function because try/catches deoptimize in certain engines.
  
  var cachedSetTimeout;
  var cachedClearTimeout;
  
  function defaultSetTimout() {
      throw new Error('setTimeout has not been defined');
  }
  function defaultClearTimeout () {
      throw new Error('clearTimeout has not been defined');
  }
  (function () {
      try {
          if (typeof setTimeout === 'function') {
              cachedSetTimeout = setTimeout;
          } else {
              cachedSetTimeout = defaultSetTimout;
          }
      } catch (e) {
          cachedSetTimeout = defaultSetTimout;
      }
      try {
          if (typeof clearTimeout === 'function') {
              cachedClearTimeout = clearTimeout;
          } else {
              cachedClearTimeout = defaultClearTimeout;
          }
      } catch (e) {
          cachedClearTimeout = defaultClearTimeout;
      }
  } ())
  function runTimeout(fun) {
      if (cachedSetTimeout === setTimeout) {
          //normal enviroments in sane situations
          return setTimeout(fun, 0);
      }
      // if setTimeout wasn't available but was latter defined
      if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {
          cachedSetTimeout = setTimeout;
          return setTimeout(fun, 0);
      }
      try {
          // when when somebody has screwed with setTimeout but no I.E. maddness
          return cachedSetTimeout(fun, 0);
      } catch(e){
          try {
              // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
              return cachedSetTimeout.call(null, fun, 0);
          } catch(e){
              // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error
              return cachedSetTimeout.call(this, fun, 0);
          }
      }
  
  
  }
  function runClearTimeout(marker) {
      if (cachedClearTimeout === clearTimeout) {
          //normal enviroments in sane situations
          return clearTimeout(marker);
      }
      // if clearTimeout wasn't available but was latter defined
      if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {
          cachedClearTimeout = clearTimeout;
          return clearTimeout(marker);
      }
      try {
          // when when somebody has screwed with setTimeout but no I.E. maddness
          return cachedClearTimeout(marker);
      } catch (e){
          try {
              // When we are in I.E. but the script has been evaled so I.E. doesn't  trust the global object when called normally
              return cachedClearTimeout.call(null, marker);
          } catch (e){
              // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.
              // Some versions of I.E. have different rules for clearTimeout vs setTimeout
              return cachedClearTimeout.call(this, marker);
          }
      }
  
  
  
  }
  var queue = [];
  var draining = false;
  var currentQueue;
  var queueIndex = -1;
  
  function cleanUpNextTick() {
      if (!draining || !currentQueue) {
          return;
      }
      draining = false;
      if (currentQueue.length) {
          queue = currentQueue.concat(queue);
      } else {
          queueIndex = -1;
      }
      if (queue.length) {
          drainQueue();
      }
  }
  
  function drainQueue() {
      if (draining) {
          return;
      }
      var timeout = runTimeout(cleanUpNextTick);
      draining = true;
  
      var len = queue.length;
      while(len) {
          currentQueue = queue;
          queue = [];
          while (++queueIndex < len) {
              if (currentQueue) {
                  currentQueue[queueIndex].run();
              }
          }
          queueIndex = -1;
          len = queue.length;
      }
      currentQueue = null;
      draining = false;
      runClearTimeout(timeout);
  }
  
  process.nextTick = function (fun) {
      var args = new Array(arguments.length - 1);
      if (arguments.length > 1) {
          for (var i = 1; i < arguments.length; i++) {
              args[i - 1] = arguments[i];
          }
      }
      queue.push(new Item(fun, args));
      if (queue.length === 1 && !draining) {
          runTimeout(drainQueue);
      }
  };
  
  // v8 likes predictible objects
  function Item(fun, array) {
      this.fun = fun;
      this.array = array;
  }
  Item.prototype.run = function () {
      this.fun.apply(null, this.array);
  };
  process.title = 'browser';
  process.browser = true;
  process.env = {};
  process.argv = [];
  process.version = ''; // empty string to avoid regexp issues
  process.versions = {};
  
  function noop() {}
  
  process.on = noop;
  process.addListener = noop;
  process.once = noop;
  process.off = noop;
  process.removeListener = noop;
  process.removeAllListeners = noop;
  process.emit = noop;
  
  process.binding = function (name) {
      throw new Error('process.binding is not supported');
  };
  
  process.cwd = function () { return '/' };
  process.chdir = function (dir) {
      throw new Error('process.chdir is not supported');
  };
  process.umask = function() { return 0; };
  
  },{}],88:[function(require,module,exports){
  module.exports = require("./lib/_stream_duplex.js")
  
  },{"./lib/_stream_duplex.js":89}],89:[function(require,module,exports){
  // a duplex stream is just a stream that is both readable and writable.
  // Since JS doesn't have multiple prototypal inheritance, this class
  // prototypally inherits from Readable, and then parasitically from
  // Writable.
  
  'use strict';
  
  /*<replacement>*/
  
  var objectKeys = Object.keys || function (obj) {
    var keys = [];
    for (var key in obj) {
      keys.push(key);
    }return keys;
  };
  /*</replacement>*/
  
  module.exports = Duplex;
  
  /*<replacement>*/
  var processNextTick = require('process-nextick-args');
  /*</replacement>*/
  
  /*<replacement>*/
  var util = require('core-util-is');
  util.inherits = require('inherits');
  /*</replacement>*/
  
  var Readable = require('./_stream_readable');
  var Writable = require('./_stream_writable');
  
  util.inherits(Duplex, Readable);
  
  var keys = objectKeys(Writable.prototype);
  for (var v = 0; v < keys.length; v++) {
    var method = keys[v];
    if (!Duplex.prototype[method]) Duplex.prototype[method] = Writable.prototype[method];
  }
  
  function Duplex(options) {
    if (!(this instanceof Duplex)) return new Duplex(options);
  
    Readable.call(this, options);
    Writable.call(this, options);
  
    if (options && options.readable === false) this.readable = false;
  
    if (options && options.writable === false) this.writable = false;
  
    this.allowHalfOpen = true;
    if (options && options.allowHalfOpen === false) this.allowHalfOpen = false;
  
    this.once('end', onend);
  }
  
  // the no-half-open enforcer
  function onend() {
    // if we allow half-open state, or if the writable side ended,
    // then we're ok.
    if (this.allowHalfOpen || this._writableState.ended) return;
  
    // no more data can be written.
    // But allow more writes to happen in this tick.
    processNextTick(onEndNT, this);
  }
  
  function onEndNT(self) {
    self.end();
  }
  
  function forEach(xs, f) {
    for (var i = 0, l = xs.length; i < l; i++) {
      f(xs[i], i);
    }
  }
  },{"./_stream_readable":91,"./_stream_writable":93,"core-util-is":80,"inherits":83,"process-nextick-args":86}],90:[function(require,module,exports){
  // a passthrough stream.
  // basically just the most minimal sort of Transform stream.
  // Every written chunk gets output as-is.
  
  'use strict';
  
  module.exports = PassThrough;
  
  var Transform = require('./_stream_transform');
  
  /*<replacement>*/
  var util = require('core-util-is');
  util.inherits = require('inherits');
  /*</replacement>*/
  
  util.inherits(PassThrough, Transform);
  
  function PassThrough(options) {
    if (!(this instanceof PassThrough)) return new PassThrough(options);
  
    Transform.call(this, options);
  }
  
  PassThrough.prototype._transform = function (chunk, encoding, cb) {
    cb(null, chunk);
  };
  },{"./_stream_transform":92,"core-util-is":80,"inherits":83}],91:[function(require,module,exports){
  (function (process){
  'use strict';
  
  module.exports = Readable;
  
  /*<replacement>*/
  var processNextTick = require('process-nextick-args');
  /*</replacement>*/
  
  /*<replacement>*/
  var isArray = require('isarray');
  /*</replacement>*/
  
  /*<replacement>*/
  var Duplex;
  /*</replacement>*/
  
  Readable.ReadableState = ReadableState;
  
  /*<replacement>*/
  var EE = require('events').EventEmitter;
  
  var EElistenerCount = function (emitter, type) {
    return emitter.listeners(type).length;
  };
  /*</replacement>*/
  
  /*<replacement>*/
  var Stream;
  (function () {
    try {
      Stream = require('st' + 'ream');
    } catch (_) {} finally {
      if (!Stream) Stream = require('events').EventEmitter;
    }
  })();
  /*</replacement>*/
  
  var Buffer = require('buffer').Buffer;
  /*<replacement>*/
  var bufferShim = require('buffer-shims');
  /*</replacement>*/
  
  /*<replacement>*/
  var util = require('core-util-is');
  util.inherits = require('inherits');
  /*</replacement>*/
  
  /*<replacement>*/
  var debugUtil = require('util');
  var debug = void 0;
  if (debugUtil && debugUtil.debuglog) {
    debug = debugUtil.debuglog('stream');
  } else {
    debug = function () {};
  }
  /*</replacement>*/
  
  var BufferList = require('./internal/streams/BufferList');
  var StringDecoder;
  
  util.inherits(Readable, Stream);
  
  function prependListener(emitter, event, fn) {
    // Sadly this is not cacheable as some libraries bundle their own
    // event emitter implementation with them.
    if (typeof emitter.prependListener === 'function') {
      return emitter.prependListener(event, fn);
    } else {
      // This is a hack to make sure that our error handler is attached before any
      // userland ones.  NEVER DO THIS. This is here only because this code needs
      // to continue to work with older versions of Node.js that do not include
      // the prependListener() method. The goal is to eventually remove this hack.
      if (!emitter._events || !emitter._events[event]) emitter.on(event, fn);else if (isArray(emitter._events[event])) emitter._events[event].unshift(fn);else emitter._events[event] = [fn, emitter._events[event]];
    }
  }
  
  function ReadableState(options, stream) {
    Duplex = Duplex || require('./_stream_duplex');
  
    options = options || {};
  
    // object stream flag. Used to make read(n) ignore n and to
    // make all the buffer merging and length checks go away
    this.objectMode = !!options.objectMode;
  
    if (stream instanceof Duplex) this.objectMode = this.objectMode || !!options.readableObjectMode;
  
    // the point at which it stops calling _read() to fill the buffer
    // Note: 0 is a valid value, means "don't call _read preemptively ever"
    var hwm = options.highWaterMark;
    var defaultHwm = this.objectMode ? 16 : 16 * 1024;
    this.highWaterMark = hwm || hwm === 0 ? hwm : defaultHwm;
  
    // cast to ints.
    this.highWaterMark = ~ ~this.highWaterMark;
  
    // A linked list is used to store data chunks instead of an array because the
    // linked list can remove elements from the beginning faster than
    // array.shift()
    this.buffer = new BufferList();
    this.length = 0;
    this.pipes = null;
    this.pipesCount = 0;
    this.flowing = null;
    this.ended = false;
    this.endEmitted = false;
    this.reading = false;
  
    // a flag to be able to tell if the onwrite cb is called immediately,
    // or on a later tick.  We set this to true at first, because any
    // actions that shouldn't happen until "later" should generally also
    // not happen before the first write call.
    this.sync = true;
  
    // whenever we return null, then we set a flag to say
    // that we're awaiting a 'readable' event emission.
    this.needReadable = false;
    this.emittedReadable = false;
    this.readableListening = false;
    this.resumeScheduled = false;
  
    // Crypto is kind of old and crusty.  Historically, its default string
    // encoding is 'binary' so we have to make this configurable.
    // Everything else in the universe uses 'utf8', though.
    this.defaultEncoding = options.defaultEncoding || 'utf8';
  
    // when piping, we only care about 'readable' events that happen
    // after read()ing all the bytes and not getting any pushback.
    this.ranOut = false;
  
    // the number of writers that are awaiting a drain event in .pipe()s
    this.awaitDrain = 0;
  
    // if true, a maybeReadMore has been scheduled
    this.readingMore = false;
  
    this.decoder = null;
    this.encoding = null;
    if (options.encoding) {
      if (!StringDecoder) StringDecoder = require('string_decoder/').StringDecoder;
      this.decoder = new StringDecoder(options.encoding);
      this.encoding = options.encoding;
    }
  }
  
  function Readable(options) {
    Duplex = Duplex || require('./_stream_duplex');
  
    if (!(this instanceof Readable)) return new Readable(options);
  
    this._readableState = new ReadableState(options, this);
  
    // legacy
    this.readable = true;
  
    if (options && typeof options.read === 'function') this._read = options.read;
  
    Stream.call(this);
  }
  
  // Manually shove something into the read() buffer.
  // This returns true if the highWaterMark has not been hit yet,
  // similar to how Writable.write() returns true if you should
  // write() some more.
  Readable.prototype.push = function (chunk, encoding) {
    var state = this._readableState;
  
    if (!state.objectMode && typeof chunk === 'string') {
      encoding = encoding || state.defaultEncoding;
      if (encoding !== state.encoding) {
        chunk = bufferShim.from(chunk, encoding);
        encoding = '';
      }
    }
  
    return readableAddChunk(this, state, chunk, encoding, false);
  };
  
  // Unshift should *always* be something directly out of read()
  Readable.prototype.unshift = function (chunk) {
    var state = this._readableState;
    return readableAddChunk(this, state, chunk, '', true);
  };
  
  Readable.prototype.isPaused = function () {
    return this._readableState.flowing === false;
  };
  
  function readableAddChunk(stream, state, chunk, encoding, addToFront) {
    var er = chunkInvalid(state, chunk);
    if (er) {
      stream.emit('error', er);
    } else if (chunk === null) {
      state.reading = false;
      onEofChunk(stream, state);
    } else if (state.objectMode || chunk && chunk.length > 0) {
      if (state.ended && !addToFront) {
        var e = new Error('stream.push() after EOF');
        stream.emit('error', e);
      } else if (state.endEmitted && addToFront) {
        var _e = new Error('stream.unshift() after end event');
        stream.emit('error', _e);
      } else {
        var skipAdd;
        if (state.decoder && !addToFront && !encoding) {
          chunk = state.decoder.write(chunk);
          skipAdd = !state.objectMode && chunk.length === 0;
        }
  
        if (!addToFront) state.reading = false;
  
        // Don't add to the buffer if we've decoded to an empty string chunk and
        // we're not in object mode
        if (!skipAdd) {
          // if we want the data now, just emit it.
          if (state.flowing && state.length === 0 && !state.sync) {
            stream.emit('data', chunk);
            stream.read(0);
          } else {
            // update the buffer info.
            state.length += state.objectMode ? 1 : chunk.length;
            if (addToFront) state.buffer.unshift(chunk);else state.buffer.push(chunk);
  
            if (state.needReadable) emitReadable(stream);
          }
        }
  
        maybeReadMore(stream, state);
      }
    } else if (!addToFront) {
      state.reading = false;
    }
  
    return needMoreData(state);
  }
  
  // if it's past the high water mark, we can push in some more.
  // Also, if we have no data yet, we can stand some
  // more bytes.  This is to work around cases where hwm=0,
  // such as the repl.  Also, if the push() triggered a
  // readable event, and the user called read(largeNumber) such that
  // needReadable was set, then we ought to push more, so that another
  // 'readable' event will be triggered.
  function needMoreData(state) {
    return !state.ended && (state.needReadable || state.length < state.highWaterMark || state.length === 0);
  }
  
  // backwards compatibility.
  Readable.prototype.setEncoding = function (enc) {
    if (!StringDecoder) StringDecoder = require('string_decoder/').StringDecoder;
    this._readableState.decoder = new StringDecoder(enc);
    this._readableState.encoding = enc;
    return this;
  };
  
  // Don't raise the hwm > 8MB
  var MAX_HWM = 0x800000;
  function computeNewHighWaterMark(n) {
    if (n >= MAX_HWM) {
      n = MAX_HWM;
    } else {
      // Get the next highest power of 2 to prevent increasing hwm excessively in
      // tiny amounts
      n--;
      n |= n >>> 1;
      n |= n >>> 2;
      n |= n >>> 4;
      n |= n >>> 8;
      n |= n >>> 16;
      n++;
    }
    return n;
  }
  
  // This function is designed to be inlinable, so please take care when making
  // changes to the function body.
  function howMuchToRead(n, state) {
    if (n <= 0 || state.length === 0 && state.ended) return 0;
    if (state.objectMode) return 1;
    if (n !== n) {
      // Only flow one buffer at a time
      if (state.flowing && state.length) return state.buffer.head.data.length;else return state.length;
    }
    // If we're asking for more than the current hwm, then raise the hwm.
    if (n > state.highWaterMark) state.highWaterMark = computeNewHighWaterMark(n);
    if (n <= state.length) return n;
    // Don't have enough
    if (!state.ended) {
      state.needReadable = true;
      return 0;
    }
    return state.length;
  }
  
  // you can override either this method, or the async _read(n) below.
  Readable.prototype.read = function (n) {
    debug('read', n);
    n = parseInt(n, 10);
    var state = this._readableState;
    var nOrig = n;
  
    if (n !== 0) state.emittedReadable = false;
  
    // if we're doing read(0) to trigger a readable event, but we
    // already have a bunch of data in the buffer, then just trigger
    // the 'readable' event and move on.
    if (n === 0 && state.needReadable && (state.length >= state.highWaterMark || state.ended)) {
      debug('read: emitReadable', state.length, state.ended);
      if (state.length === 0 && state.ended) endReadable(this);else emitReadable(this);
      return null;
    }
  
    n = howMuchToRead(n, state);
  
    // if we've ended, and we're now clear, then finish it up.
    if (n === 0 && state.ended) {
      if (state.length === 0) endReadable(this);
      return null;
    }
  
    // All the actual chunk generation logic needs to be
    // *below* the call to _read.  The reason is that in certain
    // synthetic stream cases, such as passthrough streams, _read
    // may be a completely synchronous operation which may change
    // the state of the read buffer, providing enough data when
    // before there was *not* enough.
    //
    // So, the steps are:
    // 1. Figure out what the state of things will be after we do
    // a read from the buffer.
    //
    // 2. If that resulting state will trigger a _read, then call _read.
    // Note that this may be asynchronous, or synchronous.  Yes, it is
    // deeply ugly to write APIs this way, but that still doesn't mean
    // that the Readable class should behave improperly, as streams are
    // designed to be sync/async agnostic.
    // Take note if the _read call is sync or async (ie, if the read call
    // has returned yet), so that we know whether or not it's safe to emit
    // 'readable' etc.
    //
    // 3. Actually pull the requested chunks out of the buffer and return.
  
    // if we need a readable event, then we need to do some reading.
    var doRead = state.needReadable;
    debug('need readable', doRead);
  
    // if we currently have less than the highWaterMark, then also read some
    if (state.length === 0 || state.length - n < state.highWaterMark) {
      doRead = true;
      debug('length less than watermark', doRead);
    }
  
    // however, if we've ended, then there's no point, and if we're already
    // reading, then it's unnecessary.
    if (state.ended || state.reading) {
      doRead = false;
      debug('reading or ended', doRead);
    } else if (doRead) {
      debug('do read');
      state.reading = true;
      state.sync = true;
      // if the length is currently zero, then we *need* a readable event.
      if (state.length === 0) state.needReadable = true;
      // call internal read method
      this._read(state.highWaterMark);
      state.sync = false;
      // If _read pushed data synchronously, then `reading` will be false,
      // and we need to re-evaluate how much data we can return to the user.
      if (!state.reading) n = howMuchToRead(nOrig, state);
    }
  
    var ret;
    if (n > 0) ret = fromList(n, state);else ret = null;
  
    if (ret === null) {
      state.needReadable = true;
      n = 0;
    } else {
      state.length -= n;
    }
  
    if (state.length === 0) {
      // If we have nothing in the buffer, then we want to know
      // as soon as we *do* get something into the buffer.
      if (!state.ended) state.needReadable = true;
  
      // If we tried to read() past the EOF, then emit end on the next tick.
      if (nOrig !== n && state.ended) endReadable(this);
    }
  
    if (ret !== null) this.emit('data', ret);
  
    return ret;
  };
  
  function chunkInvalid(state, chunk) {
    var er = null;
    if (!Buffer.isBuffer(chunk) && typeof chunk !== 'string' && chunk !== null && chunk !== undefined && !state.objectMode) {
      er = new TypeError('Invalid non-string/buffer chunk');
    }
    return er;
  }
  
  function onEofChunk(stream, state) {
    if (state.ended) return;
    if (state.decoder) {
      var chunk = state.decoder.end();
      if (chunk && chunk.length) {
        state.buffer.push(chunk);
        state.length += state.objectMode ? 1 : chunk.length;
      }
    }
    state.ended = true;
  
    // emit 'readable' now to make sure it gets picked up.
    emitReadable(stream);
  }
  
  // Don't emit readable right away in sync mode, because this can trigger
  // another read() call => stack overflow.  This way, it might trigger
  // a nextTick recursion warning, but that's not so bad.
  function emitReadable(stream) {
    var state = stream._readableState;
    state.needReadable = false;
    if (!state.emittedReadable) {
      debug('emitReadable', state.flowing);
      state.emittedReadable = true;
      if (state.sync) processNextTick(emitReadable_, stream);else emitReadable_(stream);
    }
  }
  
  function emitReadable_(stream) {
    debug('emit readable');
    stream.emit('readable');
    flow(stream);
  }
  
  // at this point, the user has presumably seen the 'readable' event,
  // and called read() to consume some data.  that may have triggered
  // in turn another _read(n) call, in which case reading = true if
  // it's in progress.
  // However, if we're not ended, or reading, and the length < hwm,
  // then go ahead and try to read some more preemptively.
  function maybeReadMore(stream, state) {
    if (!state.readingMore) {
      state.readingMore = true;
      processNextTick(maybeReadMore_, stream, state);
    }
  }
  
  function maybeReadMore_(stream, state) {
    var len = state.length;
    while (!state.reading && !state.flowing && !state.ended && state.length < state.highWaterMark) {
      debug('maybeReadMore read 0');
      stream.read(0);
      if (len === state.length)
        // didn't get any data, stop spinning.
        break;else len = state.length;
    }
    state.readingMore = false;
  }
  
  // abstract method.  to be overridden in specific implementation classes.
  // call cb(er, data) where data is <= n in length.
  // for virtual (non-string, non-buffer) streams, "length" is somewhat
  // arbitrary, and perhaps not very meaningful.
  Readable.prototype._read = function (n) {
    this.emit('error', new Error('_read() is not implemented'));
  };
  
  Readable.prototype.pipe = function (dest, pipeOpts) {
    var src = this;
    var state = this._readableState;
  
    switch (state.pipesCount) {
      case 0:
        state.pipes = dest;
        break;
      case 1:
        state.pipes = [state.pipes, dest];
        break;
      default:
        state.pipes.push(dest);
        break;
    }
    state.pipesCount += 1;
    debug('pipe count=%d opts=%j', state.pipesCount, pipeOpts);
  
    var doEnd = (!pipeOpts || pipeOpts.end !== false) && dest !== process.stdout && dest !== process.stderr;
  
    var endFn = doEnd ? onend : cleanup;
    if (state.endEmitted) processNextTick(endFn);else src.once('end', endFn);
  
    dest.on('unpipe', onunpipe);
    function onunpipe(readable) {
      debug('onunpipe');
      if (readable === src) {
        cleanup();
      }
    }
  
    function onend() {
      debug('onend');
      dest.end();
    }
  
    // when the dest drains, it reduces the awaitDrain counter
    // on the source.  This would be more elegant with a .once()
    // handler in flow(), but adding and removing repeatedly is
    // too slow.
    var ondrain = pipeOnDrain(src);
    dest.on('drain', ondrain);
  
    var cleanedUp = false;
    function cleanup() {
      debug('cleanup');
      // cleanup event handlers once the pipe is broken
      dest.removeListener('close', onclose);
      dest.removeListener('finish', onfinish);
      dest.removeListener('drain', ondrain);
      dest.removeListener('error', onerror);
      dest.removeListener('unpipe', onunpipe);
      src.removeListener('end', onend);
      src.removeListener('end', cleanup);
      src.removeListener('data', ondata);
  
      cleanedUp = true;
  
      // if the reader is waiting for a drain event from this
      // specific writer, then it would cause it to never start
      // flowing again.
      // So, if this is awaiting a drain, then we just call it now.
      // If we don't know, then assume that we are waiting for one.
      if (state.awaitDrain && (!dest._writableState || dest._writableState.needDrain)) ondrain();
    }
  
    // If the user pushes more data while we're writing to dest then we'll end up
    // in ondata again. However, we only want to increase awaitDrain once because
    // dest will only emit one 'drain' event for the multiple writes.
    // => Introduce a guard on increasing awaitDrain.
    var increasedAwaitDrain = false;
    src.on('data', ondata);
    function ondata(chunk) {
      debug('ondata');
      increasedAwaitDrain = false;
      var ret = dest.write(chunk);
      if (false === ret && !increasedAwaitDrain) {
        // If the user unpiped during `dest.write()`, it is possible
        // to get stuck in a permanently paused state if that write
        // also returned false.
        // => Check whether `dest` is still a piping destination.
        if ((state.pipesCount === 1 && state.pipes === dest || state.pipesCount > 1 && indexOf(state.pipes, dest) !== -1) && !cleanedUp) {
          debug('false write response, pause', src._readableState.awaitDrain);
          src._readableState.awaitDrain++;
          increasedAwaitDrain = true;
        }
        src.pause();
      }
    }
  
    // if the dest has an error, then stop piping into it.
    // however, don't suppress the throwing behavior for this.
    function onerror(er) {
      debug('onerror', er);
      unpipe();
      dest.removeListener('error', onerror);
      if (EElistenerCount(dest, 'error') === 0) dest.emit('error', er);
    }
  
    // Make sure our error handler is attached before userland ones.
    prependListener(dest, 'error', onerror);
  
    // Both close and finish should trigger unpipe, but only once.
    function onclose() {
      dest.removeListener('finish', onfinish);
      unpipe();
    }
    dest.once('close', onclose);
    function onfinish() {
      debug('onfinish');
      dest.removeListener('close', onclose);
      unpipe();
    }
    dest.once('finish', onfinish);
  
    function unpipe() {
      debug('unpipe');
      src.unpipe(dest);
    }
  
    // tell the dest that it's being piped to
    dest.emit('pipe', src);
  
    // start the flow if it hasn't been started already.
    if (!state.flowing) {
      debug('pipe resume');
      src.resume();
    }
  
    return dest;
  };
  
  function pipeOnDrain(src) {
    return function () {
      var state = src._readableState;
      debug('pipeOnDrain', state.awaitDrain);
      if (state.awaitDrain) state.awaitDrain--;
      if (state.awaitDrain === 0 && EElistenerCount(src, 'data')) {
        state.flowing = true;
        flow(src);
      }
    };
  }
  
  Readable.prototype.unpipe = function (dest) {
    var state = this._readableState;
  
    // if we're not piping anywhere, then do nothing.
    if (state.pipesCount === 0) return this;
  
    // just one destination.  most common case.
    if (state.pipesCount === 1) {
      // passed in one, but it's not the right one.
      if (dest && dest !== state.pipes) return this;
  
      if (!dest) dest = state.pipes;
  
      // got a match.
      state.pipes = null;
      state.pipesCount = 0;
      state.flowing = false;
      if (dest) dest.emit('unpipe', this);
      return this;
    }
  
    // slow case. multiple pipe destinations.
  
    if (!dest) {
      // remove all.
      var dests = state.pipes;
      var len = state.pipesCount;
      state.pipes = null;
      state.pipesCount = 0;
      state.flowing = false;
  
      for (var i = 0; i < len; i++) {
        dests[i].emit('unpipe', this);
      }return this;
    }
  
    // try to find the right one.
    var index = indexOf(state.pipes, dest);
    if (index === -1) return this;
  
    state.pipes.splice(index, 1);
    state.pipesCount -= 1;
    if (state.pipesCount === 1) state.pipes = state.pipes[0];
  
    dest.emit('unpipe', this);
  
    return this;
  };
  
  // set up data events if they are asked for
  // Ensure readable listeners eventually get something
  Readable.prototype.on = function (ev, fn) {
    var res = Stream.prototype.on.call(this, ev, fn);
  
    if (ev === 'data') {
      // Start flowing on next tick if stream isn't explicitly paused
      if (this._readableState.flowing !== false) this.resume();
    } else if (ev === 'readable') {
      var state = this._readableState;
      if (!state.endEmitted && !state.readableListening) {
        state.readableListening = state.needReadable = true;
        state.emittedReadable = false;
        if (!state.reading) {
          processNextTick(nReadingNextTick, this);
        } else if (state.length) {
          emitReadable(this, state);
        }
      }
    }
  
    return res;
  };
  Readable.prototype.addListener = Readable.prototype.on;
  
  function nReadingNextTick(self) {
    debug('readable nexttick read 0');
    self.read(0);
  }
  
  // pause() and resume() are remnants of the legacy readable stream API
  // If the user uses them, then switch into old mode.
  Readable.prototype.resume = function () {
    var state = this._readableState;
    if (!state.flowing) {
      debug('resume');
      state.flowing = true;
      resume(this, state);
    }
    return this;
  };
  
  function resume(stream, state) {
    if (!state.resumeScheduled) {
      state.resumeScheduled = true;
      processNextTick(resume_, stream, state);
    }
  }
  
  function resume_(stream, state) {
    if (!state.reading) {
      debug('resume read 0');
      stream.read(0);
    }
  
    state.resumeScheduled = false;
    state.awaitDrain = 0;
    stream.emit('resume');
    flow(stream);
    if (state.flowing && !state.reading) stream.read(0);
  }
  
  Readable.prototype.pause = function () {
    debug('call pause flowing=%j', this._readableState.flowing);
    if (false !== this._readableState.flowing) {
      debug('pause');
      this._readableState.flowing = false;
      this.emit('pause');
    }
    return this;
  };
  
  function flow(stream) {
    var state = stream._readableState;
    debug('flow', state.flowing);
    while (state.flowing && stream.read() !== null) {}
  }
  
  // wrap an old-style stream as the async data source.
  // This is *not* part of the readable stream interface.
  // It is an ugly unfortunate mess of history.
  Readable.prototype.wrap = function (stream) {
    var state = this._readableState;
    var paused = false;
  
    var self = this;
    stream.on('end', function () {
      debug('wrapped end');
      if (state.decoder && !state.ended) {
        var chunk = state.decoder.end();
        if (chunk && chunk.length) self.push(chunk);
      }
  
      self.push(null);
    });
  
    stream.on('data', function (chunk) {
      debug('wrapped data');
      if (state.decoder) chunk = state.decoder.write(chunk);
  
      // don't skip over falsy values in objectMode
      if (state.objectMode && (chunk === null || chunk === undefined)) return;else if (!state.objectMode && (!chunk || !chunk.length)) return;
  
      var ret = self.push(chunk);
      if (!ret) {
        paused = true;
        stream.pause();
      }
    });
  
    // proxy all the other methods.
    // important when wrapping filters and duplexes.
    for (var i in stream) {
      if (this[i] === undefined && typeof stream[i] === 'function') {
        this[i] = function (method) {
          return function () {
            return stream[method].apply(stream, arguments);
          };
        }(i);
      }
    }
  
    // proxy certain important events.
    var events = ['error', 'close', 'destroy', 'pause', 'resume'];
    forEach(events, function (ev) {
      stream.on(ev, self.emit.bind(self, ev));
    });
  
    // when we try to consume some more bytes, simply unpause the
    // underlying stream.
    self._read = function (n) {
      debug('wrapped _read', n);
      if (paused) {
        paused = false;
        stream.resume();
      }
    };
  
    return self;
  };
  
  // exposed for testing purposes only.
  Readable._fromList = fromList;
  
  // Pluck off n bytes from an array of buffers.
  // Length is the combined lengths of all the buffers in the list.
  // This function is designed to be inlinable, so please take care when making
  // changes to the function body.
  function fromList(n, state) {
    // nothing buffered
    if (state.length === 0) return null;
  
    var ret;
    if (state.objectMode) ret = state.buffer.shift();else if (!n || n >= state.length) {
      // read it all, truncate the list
      if (state.decoder) ret = state.buffer.join('');else if (state.buffer.length === 1) ret = state.buffer.head.data;else ret = state.buffer.concat(state.length);
      state.buffer.clear();
    } else {
      // read part of list
      ret = fromListPartial(n, state.buffer, state.decoder);
    }
  
    return ret;
  }
  
  // Extracts only enough buffered data to satisfy the amount requested.
  // This function is designed to be inlinable, so please take care when making
  // changes to the function body.
  function fromListPartial(n, list, hasStrings) {
    var ret;
    if (n < list.head.data.length) {
      // slice is the same for buffers and strings
      ret = list.head.data.slice(0, n);
      list.head.data = list.head.data.slice(n);
    } else if (n === list.head.data.length) {
      // first chunk is a perfect match
      ret = list.shift();
    } else {
      // result spans more than one buffer
      ret = hasStrings ? copyFromBufferString(n, list) : copyFromBuffer(n, list);
    }
    return ret;
  }
  
  // Copies a specified amount of characters from the list of buffered data
  // chunks.
  // This function is designed to be inlinable, so please take care when making
  // changes to the function body.
  function copyFromBufferString(n, list) {
    var p = list.head;
    var c = 1;
    var ret = p.data;
    n -= ret.length;
    while (p = p.next) {
      var str = p.data;
      var nb = n > str.length ? str.length : n;
      if (nb === str.length) ret += str;else ret += str.slice(0, n);
      n -= nb;
      if (n === 0) {
        if (nb === str.length) {
          ++c;
          if (p.next) list.head = p.next;else list.head = list.tail = null;
        } else {
          list.head = p;
          p.data = str.slice(nb);
        }
        break;
      }
      ++c;
    }
    list.length -= c;
    return ret;
  }
  
  // Copies a specified amount of bytes from the list of buffered data chunks.
  // This function is designed to be inlinable, so please take care when making
  // changes to the function body.
  function copyFromBuffer(n, list) {
    var ret = bufferShim.allocUnsafe(n);
    var p = list.head;
    var c = 1;
    p.data.copy(ret);
    n -= p.data.length;
    while (p = p.next) {
      var buf = p.data;
      var nb = n > buf.length ? buf.length : n;
      buf.copy(ret, ret.length - n, 0, nb);
      n -= nb;
      if (n === 0) {
        if (nb === buf.length) {
          ++c;
          if (p.next) list.head = p.next;else list.head = list.tail = null;
        } else {
          list.head = p;
          p.data = buf.slice(nb);
        }
        break;
      }
      ++c;
    }
    list.length -= c;
    return ret;
  }
  
  function endReadable(stream) {
    var state = stream._readableState;
  
    // If we get here before consuming all the bytes, then that is a
    // bug in node.  Should never happen.
    if (state.length > 0) throw new Error('"endReadable()" called on non-empty stream');
  
    if (!state.endEmitted) {
      state.ended = true;
      processNextTick(endReadableNT, state, stream);
    }
  }
  
  function endReadableNT(state, stream) {
    // Check that we didn't get one last unshift.
    if (!state.endEmitted && state.length === 0) {
      state.endEmitted = true;
      stream.readable = false;
      stream.emit('end');
    }
  }
  
  function forEach(xs, f) {
    for (var i = 0, l = xs.length; i < l; i++) {
      f(xs[i], i);
    }
  }
  
  function indexOf(xs, x) {
    for (var i = 0, l = xs.length; i < l; i++) {
      if (xs[i] === x) return i;
    }
    return -1;
  }
  }).call(this,require('_process'))
  },{"./_stream_duplex":89,"./internal/streams/BufferList":94,"_process":87,"buffer":79,"buffer-shims":78,"core-util-is":80,"events":81,"inherits":83,"isarray":85,"process-nextick-args":86,"string_decoder/":100,"util":77}],92:[function(require,module,exports){
  // a transform stream is a readable/writable stream where you do
  // something with the data.  Sometimes it's called a "filter",
  // but that's not a great name for it, since that implies a thing where
  // some bits pass through, and others are simply ignored.  (That would
  // be a valid example of a transform, of course.)
  //
  // While the output is causally related to the input, it's not a
  // necessarily symmetric or synchronous transformation.  For example,
  // a zlib stream might take multiple plain-text writes(), and then
  // emit a single compressed chunk some time in the future.
  //
  // Here's how this works:
  //
  // The Transform stream has all the aspects of the readable and writable
  // stream classes.  When you write(chunk), that calls _write(chunk,cb)
  // internally, and returns false if there's a lot of pending writes
  // buffered up.  When you call read(), that calls _read(n) until
  // there's enough pending readable data buffered up.
  //
  // In a transform stream, the written data is placed in a buffer.  When
  // _read(n) is called, it transforms the queued up data, calling the
  // buffered _write cb's as it consumes chunks.  If consuming a single
  // written chunk would result in multiple output chunks, then the first
  // outputted bit calls the readcb, and subsequent chunks just go into
  // the read buffer, and will cause it to emit 'readable' if necessary.
  //
  // This way, back-pressure is actually determined by the reading side,
  // since _read has to be called to start processing a new chunk.  However,
  // a pathological inflate type of transform can cause excessive buffering
  // here.  For example, imagine a stream where every byte of input is
  // interpreted as an integer from 0-255, and then results in that many
  // bytes of output.  Writing the 4 bytes {ff,ff,ff,ff} would result in
  // 1kb of data being output.  In this case, you could write a very small
  // amount of input, and end up with a very large amount of output.  In
  // such a pathological inflating mechanism, there'd be no way to tell
  // the system to stop doing the transform.  A single 4MB write could
  // cause the system to run out of memory.
  //
  // However, even in such a pathological case, only a single written chunk
  // would be consumed, and then the rest would wait (un-transformed) until
  // the results of the previous transformed chunk were consumed.
  
  'use strict';
  
  module.exports = Transform;
  
  var Duplex = require('./_stream_duplex');
  
  /*<replacement>*/
  var util = require('core-util-is');
  util.inherits = require('inherits');
  /*</replacement>*/
  
  util.inherits(Transform, Duplex);
  
  function TransformState(stream) {
    this.afterTransform = function (er, data) {
      return afterTransform(stream, er, data);
    };
  
    this.needTransform = false;
    this.transforming = false;
    this.writecb = null;
    this.writechunk = null;
    this.writeencoding = null;
  }
  
  function afterTransform(stream, er, data) {
    var ts = stream._transformState;
    ts.transforming = false;
  
    var cb = ts.writecb;
  
    if (!cb) return stream.emit('error', new Error('no writecb in Transform class'));
  
    ts.writechunk = null;
    ts.writecb = null;
  
    if (data !== null && data !== undefined) stream.push(data);
  
    cb(er);
  
    var rs = stream._readableState;
    rs.reading = false;
    if (rs.needReadable || rs.length < rs.highWaterMark) {
      stream._read(rs.highWaterMark);
    }
  }
  
  function Transform(options) {
    if (!(this instanceof Transform)) return new Transform(options);
  
    Duplex.call(this, options);
  
    this._transformState = new TransformState(this);
  
    var stream = this;
  
    // start out asking for a readable event once data is transformed.
    this._readableState.needReadable = true;
  
    // we have implemented the _read method, and done the other things
    // that Readable wants before the first _read call, so unset the
    // sync guard flag.
    this._readableState.sync = false;
  
    if (options) {
      if (typeof options.transform === 'function') this._transform = options.transform;
  
      if (typeof options.flush === 'function') this._flush = options.flush;
    }
  
    // When the writable side finishes, then flush out anything remaining.
    this.once('prefinish', function () {
      if (typeof this._flush === 'function') this._flush(function (er, data) {
        done(stream, er, data);
      });else done(stream);
    });
  }
  
  Transform.prototype.push = function (chunk, encoding) {
    this._transformState.needTransform = false;
    return Duplex.prototype.push.call(this, chunk, encoding);
  };
  
  // This is the part where you do stuff!
  // override this function in implementation classes.
  // 'chunk' is an input chunk.
  //
  // Call `push(newChunk)` to pass along transformed output
  // to the readable side.  You may call 'push' zero or more times.
  //
  // Call `cb(err)` when you are done with this chunk.  If you pass
  // an error, then that'll put the hurt on the whole operation.  If you
  // never call cb(), then you'll never get another chunk.
  Transform.prototype._transform = function (chunk, encoding, cb) {
    throw new Error('_transform() is not implemented');
  };
  
  Transform.prototype._write = function (chunk, encoding, cb) {
    var ts = this._transformState;
    ts.writecb = cb;
    ts.writechunk = chunk;
    ts.writeencoding = encoding;
    if (!ts.transforming) {
      var rs = this._readableState;
      if (ts.needTransform || rs.needReadable || rs.length < rs.highWaterMark) this._read(rs.highWaterMark);
    }
  };
  
  // Doesn't matter what the args are here.
  // _transform does all the work.
  // That we got here means that the readable side wants more data.
  Transform.prototype._read = function (n) {
    var ts = this._transformState;
  
    if (ts.writechunk !== null && ts.writecb && !ts.transforming) {
      ts.transforming = true;
      this._transform(ts.writechunk, ts.writeencoding, ts.afterTransform);
    } else {
      // mark that we need a transform, so that any data that comes in
      // will get processed, now that we've asked for it.
      ts.needTransform = true;
    }
  };
  
  function done(stream, er, data) {
    if (er) return stream.emit('error', er);
  
    if (data !== null && data !== undefined) stream.push(data);
  
    // if there's nothing in the write buffer, then that means
    // that nothing more will ever be provided
    var ws = stream._writableState;
    var ts = stream._transformState;
  
    if (ws.length) throw new Error('Calling transform done when ws.length != 0');
  
    if (ts.transforming) throw new Error('Calling transform done when still transforming');
  
    return stream.push(null);
  }
  },{"./_stream_duplex":89,"core-util-is":80,"inherits":83}],93:[function(require,module,exports){
  (function (process){
  // A bit simpler than readable streams.
  // Implement an async ._write(chunk, encoding, cb), and it'll handle all
  // the drain event emission and buffering.
  
  'use strict';
  
  module.exports = Writable;
  
  /*<replacement>*/
  var processNextTick = require('process-nextick-args');
  /*</replacement>*/
  
  /*<replacement>*/
  var asyncWrite = !process.browser && ['v0.10', 'v0.9.'].indexOf(process.version.slice(0, 5)) > -1 ? setImmediate : processNextTick;
  /*</replacement>*/
  
  /*<replacement>*/
  var Duplex;
  /*</replacement>*/
  
  Writable.WritableState = WritableState;
  
  /*<replacement>*/
  var util = require('core-util-is');
  util.inherits = require('inherits');
  /*</replacement>*/
  
  /*<replacement>*/
  var internalUtil = {
    deprecate: require('util-deprecate')
  };
  /*</replacement>*/
  
  /*<replacement>*/
  var Stream;
  (function () {
    try {
      Stream = require('st' + 'ream');
    } catch (_) {} finally {
      if (!Stream) Stream = require('events').EventEmitter;
    }
  })();
  /*</replacement>*/
  
  var Buffer = require('buffer').Buffer;
  /*<replacement>*/
  var bufferShim = require('buffer-shims');
  /*</replacement>*/
  
  util.inherits(Writable, Stream);
  
  function nop() {}
  
  function WriteReq(chunk, encoding, cb) {
    this.chunk = chunk;
    this.encoding = encoding;
    this.callback = cb;
    this.next = null;
  }
  
  function WritableState(options, stream) {
    Duplex = Duplex || require('./_stream_duplex');
  
    options = options || {};
  
    // object stream flag to indicate whether or not this stream
    // contains buffers or objects.
    this.objectMode = !!options.objectMode;
  
    if (stream instanceof Duplex) this.objectMode = this.objectMode || !!options.writableObjectMode;
  
    // the point at which write() starts returning false
    // Note: 0 is a valid value, means that we always return false if
    // the entire buffer is not flushed immediately on write()
    var hwm = options.highWaterMark;
    var defaultHwm = this.objectMode ? 16 : 16 * 1024;
    this.highWaterMark = hwm || hwm === 0 ? hwm : defaultHwm;
  
    // cast to ints.
    this.highWaterMark = ~ ~this.highWaterMark;
  
    // drain event flag.
    this.needDrain = false;
    // at the start of calling end()
    this.ending = false;
    // when end() has been called, and returned
    this.ended = false;
    // when 'finish' is emitted
    this.finished = false;
  
    // should we decode strings into buffers before passing to _write?
    // this is here so that some node-core streams can optimize string
    // handling at a lower level.
    var noDecode = options.decodeStrings === false;
    this.decodeStrings = !noDecode;
  
    // Crypto is kind of old and crusty.  Historically, its default string
    // encoding is 'binary' so we have to make this configurable.
    // Everything else in the universe uses 'utf8', though.
    this.defaultEncoding = options.defaultEncoding || 'utf8';
  
    // not an actual buffer we keep track of, but a measurement
    // of how much we're waiting to get pushed to some underlying
    // socket or file.
    this.length = 0;
  
    // a flag to see when we're in the middle of a write.
    this.writing = false;
  
    // when true all writes will be buffered until .uncork() call
    this.corked = 0;
  
    // a flag to be able to tell if the onwrite cb is called immediately,
    // or on a later tick.  We set this to true at first, because any
    // actions that shouldn't happen until "later" should generally also
    // not happen before the first write call.
    this.sync = true;
  
    // a flag to know if we're processing previously buffered items, which
    // may call the _write() callback in the same tick, so that we don't
    // end up in an overlapped onwrite situation.
    this.bufferProcessing = false;
  
    // the callback that's passed to _write(chunk,cb)
    this.onwrite = function (er) {
      onwrite(stream, er);
    };
  
    // the callback that the user supplies to write(chunk,encoding,cb)
    this.writecb = null;
  
    // the amount that is being written when _write is called.
    this.writelen = 0;
  
    this.bufferedRequest = null;
    this.lastBufferedRequest = null;
  
    // number of pending user-supplied write callbacks
    // this must be 0 before 'finish' can be emitted
    this.pendingcb = 0;
  
    // emit prefinish if the only thing we're waiting for is _write cbs
    // This is relevant for synchronous Transform streams
    this.prefinished = false;
  
    // True if the error was already emitted and should not be thrown again
    this.errorEmitted = false;
  
    // count buffered requests
    this.bufferedRequestCount = 0;
  
    // allocate the first CorkedRequest, there is always
    // one allocated and free to use, and we maintain at most two
    this.corkedRequestsFree = new CorkedRequest(this);
  }
  
  WritableState.prototype.getBuffer = function getBuffer() {
    var current = this.bufferedRequest;
    var out = [];
    while (current) {
      out.push(current);
      current = current.next;
    }
    return out;
  };
  
  (function () {
    try {
      Object.defineProperty(WritableState.prototype, 'buffer', {
        get: internalUtil.deprecate(function () {
          return this.getBuffer();
        }, '_writableState.buffer is deprecated. Use _writableState.getBuffer ' + 'instead.')
      });
    } catch (_) {}
  })();
  
  // Test _writableState for inheritance to account for Duplex streams,
  // whose prototype chain only points to Readable.
  var realHasInstance;
  if (typeof Symbol === 'function' && Symbol.hasInstance && typeof Function.prototype[Symbol.hasInstance] === 'function') {
    realHasInstance = Function.prototype[Symbol.hasInstance];
    Object.defineProperty(Writable, Symbol.hasInstance, {
      value: function (object) {
        if (realHasInstance.call(this, object)) return true;
  
        return object && object._writableState instanceof WritableState;
      }
    });
  } else {
    realHasInstance = function (object) {
      return object instanceof this;
    };
  }
  
  function Writable(options) {
    Duplex = Duplex || require('./_stream_duplex');
  
    // Writable ctor is applied to Duplexes, too.
    // `realHasInstance` is necessary because using plain `instanceof`
    // would return false, as no `_writableState` property is attached.
  
    // Trying to use the custom `instanceof` for Writable here will also break the
    // Node.js LazyTransform implementation, which has a non-trivial getter for
    // `_writableState` that would lead to infinite recursion.
    if (!realHasInstance.call(Writable, this) && !(this instanceof Duplex)) {
      return new Writable(options);
    }
  
    this._writableState = new WritableState(options, this);
  
    // legacy.
    this.writable = true;
  
    if (options) {
      if (typeof options.write === 'function') this._write = options.write;
  
      if (typeof options.writev === 'function') this._writev = options.writev;
    }
  
    Stream.call(this);
  }
  
  // Otherwise people can pipe Writable streams, which is just wrong.
  Writable.prototype.pipe = function () {
    this.emit('error', new Error('Cannot pipe, not readable'));
  };
  
  function writeAfterEnd(stream, cb) {
    var er = new Error('write after end');
    // TODO: defer error events consistently everywhere, not just the cb
    stream.emit('error', er);
    processNextTick(cb, er);
  }
  
  // If we get something that is not a buffer, string, null, or undefined,
  // and we're not in objectMode, then that's an error.
  // Otherwise stream chunks are all considered to be of length=1, and the
  // watermarks determine how many objects to keep in the buffer, rather than
  // how many bytes or characters.
  function validChunk(stream, state, chunk, cb) {
    var valid = true;
    var er = false;
    // Always throw error if a null is written
    // if we are not in object mode then throw
    // if it is not a buffer, string, or undefined.
    if (chunk === null) {
      er = new TypeError('May not write null values to stream');
    } else if (!Buffer.isBuffer(chunk) && typeof chunk !== 'string' && chunk !== undefined && !state.objectMode) {
      er = new TypeError('Invalid non-string/buffer chunk');
    }
    if (er) {
      stream.emit('error', er);
      processNextTick(cb, er);
      valid = false;
    }
    return valid;
  }
  
  Writable.prototype.write = function (chunk, encoding, cb) {
    var state = this._writableState;
    var ret = false;
  
    if (typeof encoding === 'function') {
      cb = encoding;
      encoding = null;
    }
  
    if (Buffer.isBuffer(chunk)) encoding = 'buffer';else if (!encoding) encoding = state.defaultEncoding;
  
    if (typeof cb !== 'function') cb = nop;
  
    if (state.ended) writeAfterEnd(this, cb);else if (validChunk(this, state, chunk, cb)) {
      state.pendingcb++;
      ret = writeOrBuffer(this, state, chunk, encoding, cb);
    }
  
    return ret;
  };
  
  Writable.prototype.cork = function () {
    var state = this._writableState;
  
    state.corked++;
  };
  
  Writable.prototype.uncork = function () {
    var state = this._writableState;
  
    if (state.corked) {
      state.corked--;
  
      if (!state.writing && !state.corked && !state.finished && !state.bufferProcessing && state.bufferedRequest) clearBuffer(this, state);
    }
  };
  
  Writable.prototype.setDefaultEncoding = function setDefaultEncoding(encoding) {
    // node::ParseEncoding() requires lower case.
    if (typeof encoding === 'string') encoding = encoding.toLowerCase();
    if (!(['hex', 'utf8', 'utf-8', 'ascii', 'binary', 'base64', 'ucs2', 'ucs-2', 'utf16le', 'utf-16le', 'raw'].indexOf((encoding + '').toLowerCase()) > -1)) throw new TypeError('Unknown encoding: ' + encoding);
    this._writableState.defaultEncoding = encoding;
    return this;
  };
  
  function decodeChunk(state, chunk, encoding) {
    if (!state.objectMode && state.decodeStrings !== false && typeof chunk === 'string') {
      chunk = bufferShim.from(chunk, encoding);
    }
    return chunk;
  }
  
  // if we're already writing something, then just put this
  // in the queue, and wait our turn.  Otherwise, call _write
  // If we return false, then we need a drain event, so set that flag.
  function writeOrBuffer(stream, state, chunk, encoding, cb) {
    chunk = decodeChunk(state, chunk, encoding);
  
    if (Buffer.isBuffer(chunk)) encoding = 'buffer';
    var len = state.objectMode ? 1 : chunk.length;
  
    state.length += len;
  
    var ret = state.length < state.highWaterMark;
    // we must ensure that previous needDrain will not be reset to false.
    if (!ret) state.needDrain = true;
  
    if (state.writing || state.corked) {
      var last = state.lastBufferedRequest;
      state.lastBufferedRequest = new WriteReq(chunk, encoding, cb);
      if (last) {
        last.next = state.lastBufferedRequest;
      } else {
        state.bufferedRequest = state.lastBufferedRequest;
      }
      state.bufferedRequestCount += 1;
    } else {
      doWrite(stream, state, false, len, chunk, encoding, cb);
    }
  
    return ret;
  }
  
  function doWrite(stream, state, writev, len, chunk, encoding, cb) {
    state.writelen = len;
    state.writecb = cb;
    state.writing = true;
    state.sync = true;
    if (writev) stream._writev(chunk, state.onwrite);else stream._write(chunk, encoding, state.onwrite);
    state.sync = false;
  }
  
  function onwriteError(stream, state, sync, er, cb) {
    --state.pendingcb;
    if (sync) processNextTick(cb, er);else cb(er);
  
    stream._writableState.errorEmitted = true;
    stream.emit('error', er);
  }
  
  function onwriteStateUpdate(state) {
    state.writing = false;
    state.writecb = null;
    state.length -= state.writelen;
    state.writelen = 0;
  }
  
  function onwrite(stream, er) {
    var state = stream._writableState;
    var sync = state.sync;
    var cb = state.writecb;
  
    onwriteStateUpdate(state);
  
    if (er) onwriteError(stream, state, sync, er, cb);else {
      // Check if we're actually ready to finish, but don't emit yet
      var finished = needFinish(state);
  
      if (!finished && !state.corked && !state.bufferProcessing && state.bufferedRequest) {
        clearBuffer(stream, state);
      }
  
      if (sync) {
        /*<replacement>*/
        asyncWrite(afterWrite, stream, state, finished, cb);
        /*</replacement>*/
      } else {
          afterWrite(stream, state, finished, cb);
        }
    }
  }
  
  function afterWrite(stream, state, finished, cb) {
    if (!finished) onwriteDrain(stream, state);
    state.pendingcb--;
    cb();
    finishMaybe(stream, state);
  }
  
  // Must force callback to be called on nextTick, so that we don't
  // emit 'drain' before the write() consumer gets the 'false' return
  // value, and has a chance to attach a 'drain' listener.
  function onwriteDrain(stream, state) {
    if (state.length === 0 && state.needDrain) {
      state.needDrain = false;
      stream.emit('drain');
    }
  }
  
  // if there's something in the buffer waiting, then process it
  function clearBuffer(stream, state) {
    state.bufferProcessing = true;
    var entry = state.bufferedRequest;
  
    if (stream._writev && entry && entry.next) {
      // Fast case, write everything using _writev()
      var l = state.bufferedRequestCount;
      var buffer = new Array(l);
      var holder = state.corkedRequestsFree;
      holder.entry = entry;
  
      var count = 0;
      while (entry) {
        buffer[count] = entry;
        entry = entry.next;
        count += 1;
      }
  
      doWrite(stream, state, true, state.length, buffer, '', holder.finish);
  
      // doWrite is almost always async, defer these to save a bit of time
      // as the hot path ends with doWrite
      state.pendingcb++;
      state.lastBufferedRequest = null;
      if (holder.next) {
        state.corkedRequestsFree = holder.next;
        holder.next = null;
      } else {
        state.corkedRequestsFree = new CorkedRequest(state);
      }
    } else {
      // Slow case, write chunks one-by-one
      while (entry) {
        var chunk = entry.chunk;
        var encoding = entry.encoding;
        var cb = entry.callback;
        var len = state.objectMode ? 1 : chunk.length;
  
        doWrite(stream, state, false, len, chunk, encoding, cb);
        entry = entry.next;
        // if we didn't call the onwrite immediately, then
        // it means that we need to wait until it does.
        // also, that means that the chunk and cb are currently
        // being processed, so move the buffer counter past them.
        if (state.writing) {
          break;
        }
      }
  
      if (entry === null) state.lastBufferedRequest = null;
    }
  
    state.bufferedRequestCount = 0;
    state.bufferedRequest = entry;
    state.bufferProcessing = false;
  }
  
  Writable.prototype._write = function (chunk, encoding, cb) {
    cb(new Error('_write() is not implemented'));
  };
  
  Writable.prototype._writev = null;
  
  Writable.prototype.end = function (chunk, encoding, cb) {
    var state = this._writableState;
  
    if (typeof chunk === 'function') {
      cb = chunk;
      chunk = null;
      encoding = null;
    } else if (typeof encoding === 'function') {
      cb = encoding;
      encoding = null;
    }
  
    if (chunk !== null && chunk !== undefined) this.write(chunk, encoding);
  
    // .end() fully uncorks
    if (state.corked) {
      state.corked = 1;
      this.uncork();
    }
  
    // ignore unnecessary end() calls.
    if (!state.ending && !state.finished) endWritable(this, state, cb);
  };
  
  function needFinish(state) {
    return state.ending && state.length === 0 && state.bufferedRequest === null && !state.finished && !state.writing;
  }
  
  function prefinish(stream, state) {
    if (!state.prefinished) {
      state.prefinished = true;
      stream.emit('prefinish');
    }
  }
  
  function finishMaybe(stream, state) {
    var need = needFinish(state);
    if (need) {
      if (state.pendingcb === 0) {
        prefinish(stream, state);
        state.finished = true;
        stream.emit('finish');
      } else {
        prefinish(stream, state);
      }
    }
    return need;
  }
  
  function endWritable(stream, state, cb) {
    state.ending = true;
    finishMaybe(stream, state);
    if (cb) {
      if (state.finished) processNextTick(cb);else stream.once('finish', cb);
    }
    state.ended = true;
    stream.writable = false;
  }
  
  // It seems a linked list but it is not
  // there will be only 2 of these for each stream
  function CorkedRequest(state) {
    var _this = this;
  
    this.next = null;
    this.entry = null;
  
    this.finish = function (err) {
      var entry = _this.entry;
      _this.entry = null;
      while (entry) {
        var cb = entry.callback;
        state.pendingcb--;
        cb(err);
        entry = entry.next;
      }
      if (state.corkedRequestsFree) {
        state.corkedRequestsFree.next = _this;
      } else {
        state.corkedRequestsFree = _this;
      }
    };
  }
  }).call(this,require('_process'))
  },{"./_stream_duplex":89,"_process":87,"buffer":79,"buffer-shims":78,"core-util-is":80,"events":81,"inherits":83,"process-nextick-args":86,"util-deprecate":101}],94:[function(require,module,exports){
  'use strict';
  
  var Buffer = require('buffer').Buffer;
  /*<replacement>*/
  var bufferShim = require('buffer-shims');
  /*</replacement>*/
  
  module.exports = BufferList;
  
  function BufferList() {
    this.head = null;
    this.tail = null;
    this.length = 0;
  }
  
  BufferList.prototype.push = function (v) {
    var entry = { data: v, next: null };
    if (this.length > 0) this.tail.next = entry;else this.head = entry;
    this.tail = entry;
    ++this.length;
  };
  
  BufferList.prototype.unshift = function (v) {
    var entry = { data: v, next: this.head };
    if (this.length === 0) this.tail = entry;
    this.head = entry;
    ++this.length;
  };
  
  BufferList.prototype.shift = function () {
    if (this.length === 0) return;
    var ret = this.head.data;
    if (this.length === 1) this.head = this.tail = null;else this.head = this.head.next;
    --this.length;
    return ret;
  };
  
  BufferList.prototype.clear = function () {
    this.head = this.tail = null;
    this.length = 0;
  };
  
  BufferList.prototype.join = function (s) {
    if (this.length === 0) return '';
    var p = this.head;
    var ret = '' + p.data;
    while (p = p.next) {
      ret += s + p.data;
    }return ret;
  };
  
  BufferList.prototype.concat = function (n) {
    if (this.length === 0) return bufferShim.alloc(0);
    if (this.length === 1) return this.head.data;
    var ret = bufferShim.allocUnsafe(n >>> 0);
    var p = this.head;
    var i = 0;
    while (p) {
      p.data.copy(ret, i);
      i += p.data.length;
      p = p.next;
    }
    return ret;
  };
  },{"buffer":79,"buffer-shims":78}],95:[function(require,module,exports){
  module.exports = require("./lib/_stream_passthrough.js")
  
  },{"./lib/_stream_passthrough.js":90}],96:[function(require,module,exports){
  (function (process){
  var Stream = (function (){
    try {
      return require('st' + 'ream'); // hack to fix a circular dependency issue when used with browserify
    } catch(_){}
  }());
  exports = module.exports = require('./lib/_stream_readable.js');
  exports.Stream = Stream || exports;
  exports.Readable = exports;
  exports.Writable = require('./lib/_stream_writable.js');
  exports.Duplex = require('./lib/_stream_duplex.js');
  exports.Transform = require('./lib/_stream_transform.js');
  exports.PassThrough = require('./lib/_stream_passthrough.js');
  
  if (!process.browser && process.env.READABLE_STREAM === 'disable' && Stream) {
    module.exports = Stream;
  }
  
  }).call(this,require('_process'))
  },{"./lib/_stream_duplex.js":89,"./lib/_stream_passthrough.js":90,"./lib/_stream_readable.js":91,"./lib/_stream_transform.js":92,"./lib/_stream_writable.js":93,"_process":87}],97:[function(require,module,exports){
  module.exports = require("./lib/_stream_transform.js")
  
  },{"./lib/_stream_transform.js":92}],98:[function(require,module,exports){
  module.exports = require("./lib/_stream_writable.js")
  
  },{"./lib/_stream_writable.js":93}],99:[function(require,module,exports){
  // Copyright Joyent, Inc. and other Node contributors.
  //
  // Permission is hereby granted, free of charge, to any person obtaining a
  // copy of this software and associated documentation files (the
  // "Software"), to deal in the Software without restriction, including
  // without limitation the rights to use, copy, modify, merge, publish,
  // distribute, sublicense, and/or sell copies of the Software, and to permit
  // persons to whom the Software is furnished to do so, subject to the
  // following conditions:
  //
  // The above copyright notice and this permission notice shall be included
  // in all copies or substantial portions of the Software.
  //
  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
  // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
  // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
  // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
  // USE OR OTHER DEALINGS IN THE SOFTWARE.
  
  module.exports = Stream;
  
  var EE = require('events').EventEmitter;
  var inherits = require('inherits');
  
  inherits(Stream, EE);
  Stream.Readable = require('readable-stream/readable.js');
  Stream.Writable = require('readable-stream/writable.js');
  Stream.Duplex = require('readable-stream/duplex.js');
  Stream.Transform = require('readable-stream/transform.js');
  Stream.PassThrough = require('readable-stream/passthrough.js');
  
  // Backwards-compat with node 0.4.x
  Stream.Stream = Stream;
  
  
  
  // old-style streams.  Note that the pipe method (the only relevant
  // part of this class) is overridden in the Readable class.
  
  function Stream() {
    EE.call(this);
  }
  
  Stream.prototype.pipe = function(dest, options) {
    var source = this;
  
    function ondata(chunk) {
      if (dest.writable) {
        if (false === dest.write(chunk) && source.pause) {
          source.pause();
        }
      }
    }
  
    source.on('data', ondata);
  
    function ondrain() {
      if (source.readable && source.resume) {
        source.resume();
      }
    }
  
    dest.on('drain', ondrain);
  
    // If the 'end' option is not supplied, dest.end() will be called when
    // source gets the 'end' or 'close' events.  Only dest.end() once.
    if (!dest._isStdio && (!options || options.end !== false)) {
      source.on('end', onend);
      source.on('close', onclose);
    }
  
    var didOnEnd = false;
    function onend() {
      if (didOnEnd) return;
      didOnEnd = true;
  
      dest.end();
    }
  
  
    function onclose() {
      if (didOnEnd) return;
      didOnEnd = true;
  
      if (typeof dest.destroy === 'function') dest.destroy();
    }
  
    // don't leave dangling pipes when there are errors.
    function onerror(er) {
      cleanup();
      if (EE.listenerCount(this, 'error') === 0) {
        throw er; // Unhandled stream error in pipe.
      }
    }
  
    source.on('error', onerror);
    dest.on('error', onerror);
  
    // remove all the event listeners that were added.
    function cleanup() {
      source.removeListener('data', ondata);
      dest.removeListener('drain', ondrain);
  
      source.removeListener('end', onend);
      source.removeListener('close', onclose);
  
      source.removeListener('error', onerror);
      dest.removeListener('error', onerror);
  
      source.removeListener('end', cleanup);
      source.removeListener('close', cleanup);
  
      dest.removeListener('close', cleanup);
    }
  
    source.on('end', cleanup);
    source.on('close', cleanup);
  
    dest.on('close', cleanup);
  
    dest.emit('pipe', source);
  
    // Allow for unix-like usage: A.pipe(B).pipe(C)
    return dest;
  };
  
  },{"events":81,"inherits":83,"readable-stream/duplex.js":88,"readable-stream/passthrough.js":95,"readable-stream/readable.js":96,"readable-stream/transform.js":97,"readable-stream/writable.js":98}],100:[function(require,module,exports){
  // Copyright Joyent, Inc. and other Node contributors.
  //
  // Permission is hereby granted, free of charge, to any person obtaining a
  // copy of this software and associated documentation files (the
  // "Software"), to deal in the Software without restriction, including
  // without limitation the rights to use, copy, modify, merge, publish,
  // distribute, sublicense, and/or sell copies of the Software, and to permit
  // persons to whom the Software is furnished to do so, subject to the
  // following conditions:
  //
  // The above copyright notice and this permission notice shall be included
  // in all copies or substantial portions of the Software.
  //
  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
  // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
  // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
  // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
  // USE OR OTHER DEALINGS IN THE SOFTWARE.
  
  var Buffer = require('buffer').Buffer;
  
  var isBufferEncoding = Buffer.isEncoding
    || function(encoding) {
         switch (encoding && encoding.toLowerCase()) {
           case 'hex': case 'utf8': case 'utf-8': case 'ascii': case 'binary': case 'base64': case 'ucs2': case 'ucs-2': case 'utf16le': case 'utf-16le': case 'raw': return true;
           default: return false;
         }
       }
  
  
  function assertEncoding(encoding) {
    if (encoding && !isBufferEncoding(encoding)) {
      throw new Error('Unknown encoding: ' + encoding);
    }
  }
  
  // StringDecoder provides an interface for efficiently splitting a series of
  // buffers into a series of JS strings without breaking apart multi-byte
  // characters. CESU-8 is handled as part of the UTF-8 encoding.
  //
  // @TODO Handling all encodings inside a single object makes it very difficult
  // to reason about this code, so it should be split up in the future.
  // @TODO There should be a utf8-strict encoding that rejects invalid UTF-8 code
  // points as used by CESU-8.
  var StringDecoder = exports.StringDecoder = function(encoding) {
    this.encoding = (encoding || 'utf8').toLowerCase().replace(/[-_]/, '');
    assertEncoding(encoding);
    switch (this.encoding) {
      case 'utf8':
        // CESU-8 represents each of Surrogate Pair by 3-bytes
        this.surrogateSize = 3;
        break;
      case 'ucs2':
      case 'utf16le':
        // UTF-16 represents each of Surrogate Pair by 2-bytes
        this.surrogateSize = 2;
        this.detectIncompleteChar = utf16DetectIncompleteChar;
        break;
      case 'base64':
        // Base-64 stores 3 bytes in 4 chars, and pads the remainder.
        this.surrogateSize = 3;
        this.detectIncompleteChar = base64DetectIncompleteChar;
        break;
      default:
        this.write = passThroughWrite;
        return;
    }
  
    // Enough space to store all bytes of a single character. UTF-8 needs 4
    // bytes, but CESU-8 may require up to 6 (3 bytes per surrogate).
    this.charBuffer = new Buffer(6);
    // Number of bytes received for the current incomplete multi-byte character.
    this.charReceived = 0;
    // Number of bytes expected for the current incomplete multi-byte character.
    this.charLength = 0;
  };
  
  
  // write decodes the given buffer and returns it as JS string that is
  // guaranteed to not contain any partial multi-byte characters. Any partial
  // character found at the end of the buffer is buffered up, and will be
  // returned when calling write again with the remaining bytes.
  //
  // Note: Converting a Buffer containing an orphan surrogate to a String
  // currently works, but converting a String to a Buffer (via `new Buffer`, or
  // Buffer#write) will replace incomplete surrogates with the unicode
  // replacement character. See https://codereview.chromium.org/121173009/ .
  StringDecoder.prototype.write = function(buffer) {
    var charStr = '';
    // if our last write ended with an incomplete multibyte character
    while (this.charLength) {
      // determine how many remaining bytes this buffer has to offer for this char
      var available = (buffer.length >= this.charLength - this.charReceived) ?
          this.charLength - this.charReceived :
          buffer.length;
  
      // add the new bytes to the char buffer
      buffer.copy(this.charBuffer, this.charReceived, 0, available);
      this.charReceived += available;
  
      if (this.charReceived < this.charLength) {
        // still not enough chars in this buffer? wait for more ...
        return '';
      }
  
      // remove bytes belonging to the current character from the buffer
      buffer = buffer.slice(available, buffer.length);
  
      // get the character that was split
      charStr = this.charBuffer.slice(0, this.charLength).toString(this.encoding);
  
      // CESU-8: lead surrogate (D800-DBFF) is also the incomplete character
      var charCode = charStr.charCodeAt(charStr.length - 1);
      if (charCode >= 0xD800 && charCode <= 0xDBFF) {
        this.charLength += this.surrogateSize;
        charStr = '';
        continue;
      }
      this.charReceived = this.charLength = 0;
  
      // if there are no more bytes in this buffer, just emit our char
      if (buffer.length === 0) {
        return charStr;
      }
      break;
    }
  
    // determine and set charLength / charReceived
    this.detectIncompleteChar(buffer);
  
    var end = buffer.length;
    if (this.charLength) {
      // buffer the incomplete character bytes we got
      buffer.copy(this.charBuffer, 0, buffer.length - this.charReceived, end);
      end -= this.charReceived;
    }
  
    charStr += buffer.toString(this.encoding, 0, end);
  
    var end = charStr.length - 1;
    var charCode = charStr.charCodeAt(end);
    // CESU-8: lead surrogate (D800-DBFF) is also the incomplete character
    if (charCode >= 0xD800 && charCode <= 0xDBFF) {
      var size = this.surrogateSize;
      this.charLength += size;
      this.charReceived += size;
      this.charBuffer.copy(this.charBuffer, size, 0, size);
      buffer.copy(this.charBuffer, 0, 0, size);
      return charStr.substring(0, end);
    }
  
    // or just emit the charStr
    return charStr;
  };
  
  // detectIncompleteChar determines if there is an incomplete UTF-8 character at
  // the end of the given buffer. If so, it sets this.charLength to the byte
  // length that character, and sets this.charReceived to the number of bytes
  // that are available for this character.
  StringDecoder.prototype.detectIncompleteChar = function(buffer) {
    // determine how many bytes we have to check at the end of this buffer
    var i = (buffer.length >= 3) ? 3 : buffer.length;
  
    // Figure out if one of the last i bytes of our buffer announces an
    // incomplete char.
    for (; i > 0; i--) {
      var c = buffer[buffer.length - i];
  
      // See http://en.wikipedia.org/wiki/UTF-8#Description
  
      // 110XXXXX
      if (i == 1 && c >> 5 == 0x06) {
        this.charLength = 2;
        break;
      }
  
      // 1110XXXX
      if (i <= 2 && c >> 4 == 0x0E) {
        this.charLength = 3;
        break;
      }
  
      // 11110XXX
      if (i <= 3 && c >> 3 == 0x1E) {
        this.charLength = 4;
        break;
      }
    }
    this.charReceived = i;
  };
  
  StringDecoder.prototype.end = function(buffer) {
    var res = '';
    if (buffer && buffer.length)
      res = this.write(buffer);
  
    if (this.charReceived) {
      var cr = this.charReceived;
      var buf = this.charBuffer;
      var enc = this.encoding;
      res += buf.slice(0, cr).toString(enc);
    }
  
    return res;
  };
  
  function passThroughWrite(buffer) {
    return buffer.toString(this.encoding);
  }
  
  function utf16DetectIncompleteChar(buffer) {
    this.charReceived = buffer.length % 2;
    this.charLength = this.charReceived ? 2 : 0;
  }
  
  function base64DetectIncompleteChar(buffer) {
    this.charReceived = buffer.length % 3;
    this.charLength = this.charReceived ? 3 : 0;
  }
  
  },{"buffer":79}],101:[function(require,module,exports){
  (function (global){
  
  /**
   * Module exports.
   */
  
  module.exports = deprecate;
  
  /**
   * Mark that a method should not be used.
   * Returns a modified function which warns once by default.
   *
   * If `localStorage.noDeprecation = true` is set, then it is a no-op.
   *
   * If `localStorage.throwDeprecation = true` is set, then deprecated functions
   * will throw an Error when invoked.
   *
   * If `localStorage.traceDeprecation = true` is set, then deprecated functions
   * will invoke `console.trace()` instead of `console.error()`.
   *
   * @param {Function} fn - the function to deprecate
   * @param {String} msg - the string to print to the console when `fn` is invoked
   * @returns {Function} a new "deprecated" version of `fn`
   * @api public
   */
  
  function deprecate (fn, msg) {
    if (config('noDeprecation')) {
      return fn;
    }
  
    var warned = false;
    function deprecated() {
      if (!warned) {
        if (config('throwDeprecation')) {
          throw new Error(msg);
        } else if (config('traceDeprecation')) {
          console.trace(msg);
        } else {
          console.warn(msg);
        }
        warned = true;
      }
      return fn.apply(this, arguments);
    }
  
    return deprecated;
  }
  
  /**
   * Checks `localStorage` for boolean values for the given `name`.
   *
   * @param {String} name
   * @returns {Boolean}
   * @api private
   */
  
  function config (name) {
    // accessing global.localStorage can trigger a DOMException in sandboxed iframes
    try {
      if (!global.localStorage) return false;
    } catch (_) {
      return false;
    }
    var val = global.localStorage[name];
    if (null == val) return false;
    return String(val).toLowerCase() === 'true';
  }
  
  }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
  },{}],102:[function(require,module,exports){
  arguments[4][63][0].apply(exports,arguments)
  },{"dup":63}],103:[function(require,module,exports){
  module.exports = function isBuffer(arg) {
    return arg && typeof arg === 'object'
      && typeof arg.copy === 'function'
      && typeof arg.fill === 'function'
      && typeof arg.readUInt8 === 'function';
  }
  },{}],104:[function(require,module,exports){
  (function (process,global){
  // Copyright Joyent, Inc. and other Node contributors.
  //
  // Permission is hereby granted, free of charge, to any person obtaining a
  // copy of this software and associated documentation files (the
  // "Software"), to deal in the Software without restriction, including
  // without limitation the rights to use, copy, modify, merge, publish,
  // distribute, sublicense, and/or sell copies of the Software, and to permit
  // persons to whom the Software is furnished to do so, subject to the
  // following conditions:
  //
  // The above copyright notice and this permission notice shall be included
  // in all copies or substantial portions of the Software.
  //
  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
  // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
  // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
  // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
  // USE OR OTHER DEALINGS IN THE SOFTWARE.
  
  var formatRegExp = /%[sdj%]/g;
  exports.format = function(f) {
    if (!isString(f)) {
      var objects = [];
      for (var i = 0; i < arguments.length; i++) {
        objects.push(inspect(arguments[i]));
      }
      return objects.join(' ');
    }
  
    var i = 1;
    var args = arguments;
    var len = args.length;
    var str = String(f).replace(formatRegExp, function(x) {
      if (x === '%%') return '%';
      if (i >= len) return x;
      switch (x) {
        case '%s': return String(args[i++]);
        case '%d': return Number(args[i++]);
        case '%j':
          try {
            return JSON.stringify(args[i++]);
          } catch (_) {
            return '[Circular]';
          }
        default:
          return x;
      }
    });
    for (var x = args[i]; i < len; x = args[++i]) {
      if (isNull(x) || !isObject(x)) {
        str += ' ' + x;
      } else {
        str += ' ' + inspect(x);
      }
    }
    return str;
  };
  
  
  // Mark that a method should not be used.
  // Returns a modified function which warns once by default.
  // If --no-deprecation is set, then it is a no-op.
  exports.deprecate = function(fn, msg) {
    // Allow for deprecating things in the process of starting up.
    if (isUndefined(global.process)) {
      return function() {
        return exports.deprecate(fn, msg).apply(this, arguments);
      };
    }
  
    if (process.noDeprecation === true) {
      return fn;
    }
  
    var warned = false;
    function deprecated() {
      if (!warned) {
        if (process.throwDeprecation) {
          throw new Error(msg);
        } else if (process.traceDeprecation) {
          console.trace(msg);
        } else {
          console.error(msg);
        }
        warned = true;
      }
      return fn.apply(this, arguments);
    }
  
    return deprecated;
  };
  
  
  var debugs = {};
  var debugEnviron;
  exports.debuglog = function(set) {
    if (isUndefined(debugEnviron))
      debugEnviron = process.env.NODE_DEBUG || '';
    set = set.toUpperCase();
    if (!debugs[set]) {
      if (new RegExp('\\b' + set + '\\b', 'i').test(debugEnviron)) {
        var pid = process.pid;
        debugs[set] = function() {
          var msg = exports.format.apply(exports, arguments);
          console.error('%s %d: %s', set, pid, msg);
        };
      } else {
        debugs[set] = function() {};
      }
    }
    return debugs[set];
  };
  
  
  /**
   * Echos the value of a value. Trys to print the value out
   * in the best way possible given the different types.
   *
   * @param {Object} obj The object to print out.
   * @param {Object} opts Optional options object that alters the output.
   */
  /* legacy: obj, showHidden, depth, colors*/
  function inspect(obj, opts) {
    // default options
    var ctx = {
      seen: [],
      stylize: stylizeNoColor
    };
    // legacy...
    if (arguments.length >= 3) ctx.depth = arguments[2];
    if (arguments.length >= 4) ctx.colors = arguments[3];
    if (isBoolean(opts)) {
      // legacy...
      ctx.showHidden = opts;
    } else if (opts) {
      // got an "options" object
      exports._extend(ctx, opts);
    }
    // set default options
    if (isUndefined(ctx.showHidden)) ctx.showHidden = false;
    if (isUndefined(ctx.depth)) ctx.depth = 2;
    if (isUndefined(ctx.colors)) ctx.colors = false;
    if (isUndefined(ctx.customInspect)) ctx.customInspect = true;
    if (ctx.colors) ctx.stylize = stylizeWithColor;
    return formatValue(ctx, obj, ctx.depth);
  }
  exports.inspect = inspect;
  
  
  // http://en.wikipedia.org/wiki/ANSI_escape_code#graphics
  inspect.colors = {
    'bold' : [1, 22],
    'italic' : [3, 23],
    'underline' : [4, 24],
    'inverse' : [7, 27],
    'white' : [37, 39],
    'grey' : [90, 39],
    'black' : [30, 39],
    'blue' : [34, 39],
    'cyan' : [36, 39],
    'green' : [32, 39],
    'magenta' : [35, 39],
    'red' : [31, 39],
    'yellow' : [33, 39]
  };
  
  // Don't use 'blue' not visible on cmd.exe
  inspect.styles = {
    'special': 'cyan',
    'number': 'yellow',
    'boolean': 'yellow',
    'undefined': 'grey',
    'null': 'bold',
    'string': 'green',
    'date': 'magenta',
    // "name": intentionally not styling
    'regexp': 'red'
  };
  
  
  function stylizeWithColor(str, styleType) {
    var style = inspect.styles[styleType];
  
    if (style) {
      return '\u001b[' + inspect.colors[style][0] + 'm' + str +
             '\u001b[' + inspect.colors[style][1] + 'm';
    } else {
      return str;
    }
  }
  
  
  function stylizeNoColor(str, styleType) {
    return str;
  }
  
  
  function arrayToHash(array) {
    var hash = {};
  
    array.forEach(function(val, idx) {
      hash[val] = true;
    });
  
    return hash;
  }
  
  
  function formatValue(ctx, value, recurseTimes) {
    // Provide a hook for user-specified inspect functions.
    // Check that value is an object with an inspect function on it
    if (ctx.customInspect &&
        value &&
        isFunction(value.inspect) &&
        // Filter out the util module, it's inspect function is special
        value.inspect !== exports.inspect &&
        // Also filter out any prototype objects using the circular check.
        !(value.constructor && value.constructor.prototype === value)) {
      var ret = value.inspect(recurseTimes, ctx);
      if (!isString(ret)) {
        ret = formatValue(ctx, ret, recurseTimes);
      }
      return ret;
    }
  
    // Primitive types cannot have properties
    var primitive = formatPrimitive(ctx, value);
    if (primitive) {
      return primitive;
    }
  
    // Look up the keys of the object.
    var keys = Object.keys(value);
    var visibleKeys = arrayToHash(keys);
  
    if (ctx.showHidden) {
      keys = Object.getOwnPropertyNames(value);
    }
  
    // IE doesn't make error fields non-enumerable
    // http://msdn.microsoft.com/en-us/library/ie/dww52sbt(v=vs.94).aspx
    if (isError(value)
        && (keys.indexOf('message') >= 0 || keys.indexOf('description') >= 0)) {
      return formatError(value);
    }
  
    // Some type of object without properties can be shortcutted.
    if (keys.length === 0) {
      if (isFunction(value)) {
        var name = value.name ? ': ' + value.name : '';
        return ctx.stylize('[Function' + name + ']', 'special');
      }
      if (isRegExp(value)) {
        return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
      }
      if (isDate(value)) {
        return ctx.stylize(Date.prototype.toString.call(value), 'date');
      }
      if (isError(value)) {
        return formatError(value);
      }
    }
  
    var base = '', array = false, braces = ['{', '}'];
  
    // Make Array say that they are Array
    if (isArray(value)) {
      array = true;
      braces = ['[', ']'];
    }
  
    // Make functions say that they are functions
    if (isFunction(value)) {
      var n = value.name ? ': ' + value.name : '';
      base = ' [Function' + n + ']';
    }
  
    // Make RegExps say that they are RegExps
    if (isRegExp(value)) {
      base = ' ' + RegExp.prototype.toString.call(value);
    }
  
    // Make dates with properties first say the date
    if (isDate(value)) {
      base = ' ' + Date.prototype.toUTCString.call(value);
    }
  
    // Make error with message first say the error
    if (isError(value)) {
      base = ' ' + formatError(value);
    }
  
    if (keys.length === 0 && (!array || value.length == 0)) {
      return braces[0] + base + braces[1];
    }
  
    if (recurseTimes < 0) {
      if (isRegExp(value)) {
        return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
      } else {
        return ctx.stylize('[Object]', 'special');
      }
    }
  
    ctx.seen.push(value);
  
    var output;
    if (array) {
      output = formatArray(ctx, value, recurseTimes, visibleKeys, keys);
    } else {
      output = keys.map(function(key) {
        return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array);
      });
    }
  
    ctx.seen.pop();
  
    return reduceToSingleString(output, base, braces);
  }
  
  
  function formatPrimitive(ctx, value) {
    if (isUndefined(value))
      return ctx.stylize('undefined', 'undefined');
    if (isString(value)) {
      var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '')
                                               .replace(/'/g, "\\'")
                                               .replace(/\\"/g, '"') + '\'';
      return ctx.stylize(simple, 'string');
    }
    if (isNumber(value))
      return ctx.stylize('' + value, 'number');
    if (isBoolean(value))
      return ctx.stylize('' + value, 'boolean');
    // For some reason typeof null is "object", so special case here.
    if (isNull(value))
      return ctx.stylize('null', 'null');
  }
  
  
  function formatError(value) {
    return '[' + Error.prototype.toString.call(value) + ']';
  }
  
  
  function formatArray(ctx, value, recurseTimes, visibleKeys, keys) {
    var output = [];
    for (var i = 0, l = value.length; i < l; ++i) {
      if (hasOwnProperty(value, String(i))) {
        output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
            String(i), true));
      } else {
        output.push('');
      }
    }
    keys.forEach(function(key) {
      if (!key.match(/^\d+$/)) {
        output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
            key, true));
      }
    });
    return output;
  }
  
  
  function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) {
    var name, str, desc;
    desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] };
    if (desc.get) {
      if (desc.set) {
        str = ctx.stylize('[Getter/Setter]', 'special');
      } else {
        str = ctx.stylize('[Getter]', 'special');
      }
    } else {
      if (desc.set) {
        str = ctx.stylize('[Setter]', 'special');
      }
    }
    if (!hasOwnProperty(visibleKeys, key)) {
      name = '[' + key + ']';
    }
    if (!str) {
      if (ctx.seen.indexOf(desc.value) < 0) {
        if (isNull(recurseTimes)) {
          str = formatValue(ctx, desc.value, null);
        } else {
          str = formatValue(ctx, desc.value, recurseTimes - 1);
        }
        if (str.indexOf('\n') > -1) {
          if (array) {
            str = str.split('\n').map(function(line) {
              return '  ' + line;
            }).join('\n').substr(2);
          } else {
            str = '\n' + str.split('\n').map(function(line) {
              return '   ' + line;
            }).join('\n');
          }
        }
      } else {
        str = ctx.stylize('[Circular]', 'special');
      }
    }
    if (isUndefined(name)) {
      if (array && key.match(/^\d+$/)) {
        return str;
      }
      name = JSON.stringify('' + key);
      if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) {
        name = name.substr(1, name.length - 2);
        name = ctx.stylize(name, 'name');
      } else {
        name = name.replace(/'/g, "\\'")
                   .replace(/\\"/g, '"')
                   .replace(/(^"|"$)/g, "'");
        name = ctx.stylize(name, 'string');
      }
    }
  
    return name + ': ' + str;
  }
  
  
  function reduceToSingleString(output, base, braces) {
    var numLinesEst = 0;
    var length = output.reduce(function(prev, cur) {
      numLinesEst++;
      if (cur.indexOf('\n') >= 0) numLinesEst++;
      return prev + cur.replace(/\u001b\[\d\d?m/g, '').length + 1;
    }, 0);
  
    if (length > 60) {
      return braces[0] +
             (base === '' ? '' : base + '\n ') +
             ' ' +
             output.join(',\n  ') +
             ' ' +
             braces[1];
    }
  
    return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1];
  }
  
  
  // NOTE: These type checking functions intentionally don't use `instanceof`
  // because it is fragile and can be easily faked with `Object.create()`.
  function isArray(ar) {
    return Array.isArray(ar);
  }
  exports.isArray = isArray;
  
  function isBoolean(arg) {
    return typeof arg === 'boolean';
  }
  exports.isBoolean = isBoolean;
  
  function isNull(arg) {
    return arg === null;
  }
  exports.isNull = isNull;
  
  function isNullOrUndefined(arg) {
    return arg == null;
  }
  exports.isNullOrUndefined = isNullOrUndefined;
  
  function isNumber(arg) {
    return typeof arg === 'number';
  }
  exports.isNumber = isNumber;
  
  function isString(arg) {
    return typeof arg === 'string';
  }
  exports.isString = isString;
  
  function isSymbol(arg) {
    return typeof arg === 'symbol';
  }
  exports.isSymbol = isSymbol;
  
  function isUndefined(arg) {
    return arg === void 0;
  }
  exports.isUndefined = isUndefined;
  
  function isRegExp(re) {
    return isObject(re) && objectToString(re) === '[object RegExp]';
  }
  exports.isRegExp = isRegExp;
  
  function isObject(arg) {
    return typeof arg === 'object' && arg !== null;
  }
  exports.isObject = isObject;
  
  function isDate(d) {
    return isObject(d) && objectToString(d) === '[object Date]';
  }
  exports.isDate = isDate;
  
  function isError(e) {
    return isObject(e) &&
        (objectToString(e) === '[object Error]' || e instanceof Error);
  }
  exports.isError = isError;
  
  function isFunction(arg) {
    return typeof arg === 'function';
  }
  exports.isFunction = isFunction;
  
  function isPrimitive(arg) {
    return arg === null ||
           typeof arg === 'boolean' ||
           typeof arg === 'number' ||
           typeof arg === 'string' ||
           typeof arg === 'symbol' ||  // ES6 symbol
           typeof arg === 'undefined';
  }
  exports.isPrimitive = isPrimitive;
  
  exports.isBuffer = require('./support/isBuffer');
  
  function objectToString(o) {
    return Object.prototype.toString.call(o);
  }
  
  
  function pad(n) {
    return n < 10 ? '0' + n.toString(10) : n.toString(10);
  }
  
  
  var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep',
                'Oct', 'Nov', 'Dec'];
  
  // 26 Feb 16:19:34
  function timestamp() {
    var d = new Date();
    var time = [pad(d.getHours()),
                pad(d.getMinutes()),
                pad(d.getSeconds())].join(':');
    return [d.getDate(), months[d.getMonth()], time].join(' ');
  }
  
  
  // log is just a thin wrapper to console.log that prepends a timestamp
  exports.log = function() {
    console.log('%s - %s', timestamp(), exports.format.apply(exports, arguments));
  };
  
  
  /**
   * Inherit the prototype methods from one constructor into another.
   *
   * The Function.prototype.inherits from lang.js rewritten as a standalone
   * function (not on Function.prototype). NOTE: If this file is to be loaded
   * during bootstrapping this function needs to be rewritten using some native
   * functions as prototype setup using normal JavaScript does not work as
   * expected during bootstrapping (see mirror.js in r114903).
   *
   * @param {function} ctor Constructor function which needs to inherit the
   *     prototype.
   * @param {function} superCtor Constructor function to inherit prototype from.
   */
  exports.inherits = require('inherits');
  
  exports._extend = function(origin, add) {
    // Don't do anything if add isn't an object
    if (!add || !isObject(add)) return origin;
  
    var keys = Object.keys(add);
    var i = keys.length;
    while (i--) {
      origin[keys[i]] = add[keys[i]];
    }
    return origin;
  };
  
  function hasOwnProperty(obj, prop) {
    return Object.prototype.hasOwnProperty.call(obj, prop);
  }
  
  }).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
  },{"./support/isBuffer":103,"_process":87,"inherits":102}]},{},[13])(13)
  });