ampache/ampache

View on GitHub
public/lib/modules/aurora.js/aurora.js

Summary

Maintainability
F
1 mo
Test Coverage
(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.AV = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
// Generated by CoffeeScript 1.12.7
(function() {
  var Asset, BufferSource, Decoder, Demuxer, EventEmitter, FileSource, HTTPSource,
    bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
    extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
    hasProp = {}.hasOwnProperty;

  EventEmitter = require('./core/events');

  HTTPSource = require('./sources/node/http');

  FileSource = require('./sources/node/file');

  BufferSource = require('./sources/buffer');

  Demuxer = require('./demuxer');

  Decoder = require('./decoder');

  Asset = (function(superClass) {
    extend(Asset, superClass);

    function Asset(source) {
      this.source = source;
      this._decode = bind(this._decode, this);
      this.findDecoder = bind(this.findDecoder, this);
      this.probe = bind(this.probe, this);
      this.buffered = 0;
      this.duration = null;
      this.format = null;
      this.metadata = null;
      this.active = false;
      this.demuxer = null;
      this.decoder = null;
      this.source.once('data', this.probe);
      this.source.on('error', (function(_this) {
        return function(err) {
          _this.emit('error', err);
          return _this.stop();
        };
      })(this));
      this.source.on('progress', (function(_this) {
        return function(buffered) {
          _this.buffered = buffered;
          return _this.emit('buffer', _this.buffered);
        };
      })(this));
    }

    Asset.fromURL = function(url, opts) {
      return new Asset(new HTTPSource(url, opts));
    };

    Asset.fromFile = function(file) {
      return new Asset(new FileSource(file));
    };

    Asset.fromBuffer = function(buffer) {
      return new Asset(new BufferSource(buffer));
    };

    Asset.prototype.start = function(decode) {
      if (this.active) {
        return;
      }
      if (decode != null) {
        this.shouldDecode = decode;
      }
      if (this.shouldDecode == null) {
        this.shouldDecode = true;
      }
      this.active = true;
      this.source.start();
      if (this.decoder && this.shouldDecode) {
        return this._decode();
      }
    };

    Asset.prototype.stop = function() {
      if (!this.active) {
        return;
      }
      this.active = false;
      return this.source.pause();
    };

    Asset.prototype.get = function(event, callback) {
      if (event !== 'format' && event !== 'duration' && event !== 'metadata') {
        return;
      }
      if (this[event] != null) {
        return callback(this[event]);
      } else {
        this.once(event, (function(_this) {
          return function(value) {
            _this.stop();
            return callback(value);
          };
        })(this));
        return this.start();
      }
    };

    Asset.prototype.decodePacket = function() {
      return this.decoder.decode();
    };

    Asset.prototype.decodeToBuffer = function(callback) {
      var chunks, dataHandler, length;
      length = 0;
      chunks = [];
      this.on('data', dataHandler = function(chunk) {
        length += chunk.length;
        return chunks.push(chunk);
      });
      this.once('end', function() {
        var buf, chunk, j, len, offset;
        buf = new Float32Array(length);
        offset = 0;
        for (j = 0, len = chunks.length; j < len; j++) {
          chunk = chunks[j];
          buf.set(chunk, offset);
          offset += chunk.length;
        }
        this.off('data', dataHandler);
        return callback(buf);
      });
      return this.start();
    };

    Asset.prototype.probe = function(chunk) {
      var demuxer;
      if (!this.active) {
        return;
      }
      demuxer = Demuxer.find(chunk);
      if (!demuxer) {
        return this.emit('error', 'A demuxer for this container was not found.');
      }
      this.demuxer = new demuxer(this.source, chunk);
      this.demuxer.on('format', this.findDecoder);
      this.demuxer.on('duration', (function(_this) {
        return function(duration) {
          _this.duration = duration;
          return _this.emit('duration', _this.duration);
        };
      })(this));
      this.demuxer.on('metadata', (function(_this) {
        return function(metadata) {
          _this.metadata = metadata;
          return _this.emit('metadata', _this.metadata);
        };
      })(this));
      return this.demuxer.on('error', (function(_this) {
        return function(err) {
          _this.emit('error', err);
          return _this.stop();
        };
      })(this));
    };

    Asset.prototype.findDecoder = function(format) {
      var decoder, div;
      this.format = format;
      if (!this.active) {
        return;
      }
      this.emit('format', this.format);
      decoder = Decoder.find(this.format.formatID);
      if (!decoder) {
        return this.emit('error', "A decoder for " + this.format.formatID + " was not found.");
      }
      this.decoder = new decoder(this.demuxer, this.format);
      if (this.format.floatingPoint) {
        this.decoder.on('data', (function(_this) {
          return function(buffer) {
            return _this.emit('data', buffer);
          };
        })(this));
      } else {
        div = Math.pow(2, this.format.bitsPerChannel - 1);
        this.decoder.on('data', (function(_this) {
          return function(buffer) {
            var buf, i, j, len, sample;
            buf = new Float32Array(buffer.length);
            for (i = j = 0, len = buffer.length; j < len; i = ++j) {
              sample = buffer[i];
              buf[i] = sample / div;
            }
            return _this.emit('data', buf);
          };
        })(this));
      }
      this.decoder.on('error', (function(_this) {
        return function(err) {
          _this.emit('error', err);
          return _this.stop();
        };
      })(this));
      this.decoder.on('end', (function(_this) {
        return function() {
          return _this.emit('end');
        };
      })(this));
      this.emit('decodeStart');
      if (this.shouldDecode) {
        return this._decode();
      }
    };

    Asset.prototype._decode = function() {
      while (this.decoder.decode() && this.active) {
        continue;
      }
      if (this.active) {
        return this.decoder.once('data', this._decode);
      }
    };

    Asset.prototype.destroy = function() {
      var ref, ref1, ref2;
      this.stop();
      if ((ref = this.demuxer) != null) {
        ref.off();
      }
      if ((ref1 = this.decoder) != null) {
        ref1.off();
      }
      if ((ref2 = this.source) != null) {
        ref2.off();
      }
      return this.off();
    };

    return Asset;

  })(EventEmitter);

  module.exports = Asset;

}).call(this);

},{"./core/events":8,"./decoder":11,"./demuxer":14,"./sources/buffer":31,"./sources/node/file":29,"./sources/node/http":30}],2:[function(require,module,exports){
// Generated by CoffeeScript 1.12.7
(function() {
  var key, ref, val;

  ref = require('./aurora_base');
  for (key in ref) {
    val = ref[key];
    exports[key] = val;
  }

  require('./demuxers/caf');

  require('./demuxers/m4a');

  require('./demuxers/aiff');

  require('./demuxers/wave');

  require('./demuxers/au');

  require('./decoders/lpcm');

  require('./decoders/xlaw');

}).call(this);

},{"./aurora_base":3,"./decoders/lpcm":12,"./decoders/xlaw":13,"./demuxers/aiff":15,"./demuxers/au":16,"./demuxers/caf":17,"./demuxers/m4a":18,"./demuxers/wave":19}],3:[function(require,module,exports){
// Generated by CoffeeScript 1.12.7
(function() {
  exports.Base = require('./core/base');

  exports.Buffer = require('./core/buffer');

  exports.BufferList = require('./core/bufferlist');

  exports.Stream = require('./core/stream');

  exports.Bitstream = require('./core/bitstream');

  exports.EventEmitter = require('./core/events');

  exports.UnderflowError = require('./core/underflow');

  exports.HTTPSource = require('./sources/node/http');

  exports.FileSource = require('./sources/node/file');

  exports.BufferSource = require('./sources/buffer');

  exports.Demuxer = require('./demuxer');

  exports.Decoder = require('./decoder');

  exports.AudioDevice = require('./device');

  exports.Asset = require('./asset');

  exports.Player = require('./player');

  exports.Filter = require('./filter');

  exports.VolumeFilter = require('./filters/volume');

  exports.BalanceFilter = require('./filters/balance');

}).call(this);

},{"./asset":1,"./core/base":4,"./core/bitstream":5,"./core/buffer":6,"./core/bufferlist":7,"./core/events":8,"./core/stream":9,"./core/underflow":10,"./decoder":11,"./demuxer":14,"./device":20,"./filter":24,"./filters/balance":25,"./filters/volume":26,"./player":27,"./sources/buffer":31,"./sources/node/file":29,"./sources/node/http":30}],4:[function(require,module,exports){
// Generated by CoffeeScript 1.12.7
(function() {
  var Base,
    extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
    hasProp = {}.hasOwnProperty,
    indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };

  Base = (function() {
    var fnTest;

    function Base() {}

    fnTest = /\b_super\b/;

    Base.extend = function(prop) {
      var Class, _super, fn, key, keys, ref;
      Class = (function(superClass) {
        extend(Class, superClass);

        function Class() {
          return Class.__super__.constructor.apply(this, arguments);
        }

        return Class;

      })(this);
      if (typeof prop === 'function') {
        keys = Object.keys(Class.prototype);
        prop.call(Class, Class);
        prop = {};
        ref = Class.prototype;
        for (key in ref) {
          fn = ref[key];
          if (indexOf.call(keys, key) < 0) {
            prop[key] = fn;
          }
        }
      }
      _super = Class.__super__;
      for (key in prop) {
        fn = prop[key];
        if (typeof fn === 'function' && fnTest.test(fn)) {
          (function(key, fn) {
            return Class.prototype[key] = function() {
              var ret, tmp;
              tmp = this._super;
              this._super = _super[key];
              ret = fn.apply(this, arguments);
              this._super = tmp;
              return ret;
            };
          })(key, fn);
        } else {
          Class.prototype[key] = fn;
        }
      }
      return Class;
    };

    return Base;

  })();

  module.exports = Base;

}).call(this);

},{}],5:[function(require,module,exports){
// Generated by CoffeeScript 1.12.7
(function() {
  var Bitstream;

  Bitstream = (function() {
    function Bitstream(stream) {
      this.stream = stream;
      this.bitPosition = 0;
    }

    Bitstream.prototype.copy = function() {
      var result;
      result = new Bitstream(this.stream.copy());
      result.bitPosition = this.bitPosition;
      return result;
    };

    Bitstream.prototype.offset = function() {
      return 8 * this.stream.offset + this.bitPosition;
    };

    Bitstream.prototype.available = function(bits) {
      return this.stream.available((bits + 8 - this.bitPosition) / 8);
    };

    Bitstream.prototype.advance = function(bits) {
      var pos;
      pos = this.bitPosition + bits;
      this.stream.advance(pos >> 3);
      return this.bitPosition = pos & 7;
    };

    Bitstream.prototype.rewind = function(bits) {
      var pos;
      pos = this.bitPosition - bits;
      this.stream.rewind(Math.abs(pos >> 3));
      return this.bitPosition = pos & 7;
    };

    Bitstream.prototype.seek = function(offset) {
      var curOffset;
      curOffset = this.offset();
      if (offset > curOffset) {
        return this.advance(offset - curOffset);
      } else if (offset < curOffset) {
        return this.rewind(curOffset - offset);
      }
    };

    Bitstream.prototype.align = function() {
      if (this.bitPosition !== 0) {
        this.bitPosition = 0;
        return this.stream.advance(1);
      }
    };

    Bitstream.prototype.read = function(bits, signed) {
      var a, a0, a1, a2, a3, a4, mBits;
      if (bits === 0) {
        return 0;
      }
      mBits = bits + this.bitPosition;
      if (mBits <= 8) {
        a = ((this.stream.peekUInt8() << this.bitPosition) & 0xff) >>> (8 - bits);
      } else if (mBits <= 16) {
        a = ((this.stream.peekUInt16() << this.bitPosition) & 0xffff) >>> (16 - bits);
      } else if (mBits <= 24) {
        a = ((this.stream.peekUInt24() << this.bitPosition) & 0xffffff) >>> (24 - bits);
      } else if (mBits <= 32) {
        a = (this.stream.peekUInt32() << this.bitPosition) >>> (32 - bits);
      } else if (mBits <= 40) {
        a0 = this.stream.peekUInt8(0) * 0x0100000000;
        a1 = this.stream.peekUInt8(1) << 24 >>> 0;
        a2 = this.stream.peekUInt8(2) << 16;
        a3 = this.stream.peekUInt8(3) << 8;
        a4 = this.stream.peekUInt8(4);
        a = a0 + a1 + a2 + a3 + a4;
        a %= Math.pow(2, 40 - this.bitPosition);
        a = Math.floor(a / Math.pow(2, 40 - this.bitPosition - bits));
      } else {
        throw new Error("Too many bits!");
      }
      if (signed) {
        if (mBits < 32) {
          if (a >>> (bits - 1)) {
            a = ((1 << bits >>> 0) - a) * -1;
          }
        } else {
          if (a / Math.pow(2, bits - 1) | 0) {
            a = (Math.pow(2, bits) - a) * -1;
          }
        }
      }
      this.advance(bits);
      return a;
    };

    Bitstream.prototype.peek = function(bits, signed) {
      var a, a0, a1, a2, a3, a4, mBits;
      if (bits === 0) {
        return 0;
      }
      mBits = bits + this.bitPosition;
      if (mBits <= 8) {
        a = ((this.stream.peekUInt8() << this.bitPosition) & 0xff) >>> (8 - bits);
      } else if (mBits <= 16) {
        a = ((this.stream.peekUInt16() << this.bitPosition) & 0xffff) >>> (16 - bits);
      } else if (mBits <= 24) {
        a = ((this.stream.peekUInt24() << this.bitPosition) & 0xffffff) >>> (24 - bits);
      } else if (mBits <= 32) {
        a = (this.stream.peekUInt32() << this.bitPosition) >>> (32 - bits);
      } else if (mBits <= 40) {
        a0 = this.stream.peekUInt8(0) * 0x0100000000;
        a1 = this.stream.peekUInt8(1) << 24 >>> 0;
        a2 = this.stream.peekUInt8(2) << 16;
        a3 = this.stream.peekUInt8(3) << 8;
        a4 = this.stream.peekUInt8(4);
        a = a0 + a1 + a2 + a3 + a4;
        a %= Math.pow(2, 40 - this.bitPosition);
        a = Math.floor(a / Math.pow(2, 40 - this.bitPosition - bits));
      } else {
        throw new Error("Too many bits!");
      }
      if (signed) {
        if (mBits < 32) {
          if (a >>> (bits - 1)) {
            a = ((1 << bits >>> 0) - a) * -1;
          }
        } else {
          if (a / Math.pow(2, bits - 1) | 0) {
            a = (Math.pow(2, bits) - a) * -1;
          }
        }
      }
      return a;
    };

    Bitstream.prototype.readLSB = function(bits, signed) {
      var a, mBits;
      if (bits === 0) {
        return 0;
      }
      if (bits > 40) {
        throw new Error("Too many bits!");
      }
      mBits = bits + this.bitPosition;
      a = (this.stream.peekUInt8(0)) >>> this.bitPosition;
      if (mBits > 8) {
        a |= (this.stream.peekUInt8(1)) << (8 - this.bitPosition);
      }
      if (mBits > 16) {
        a |= (this.stream.peekUInt8(2)) << (16 - this.bitPosition);
      }
      if (mBits > 24) {
        a += (this.stream.peekUInt8(3)) << (24 - this.bitPosition) >>> 0;
      }
      if (mBits > 32) {
        a += (this.stream.peekUInt8(4)) * Math.pow(2, 32 - this.bitPosition);
      }
      if (mBits >= 32) {
        a %= Math.pow(2, bits);
      } else {
        a &= (1 << bits) - 1;
      }
      if (signed) {
        if (mBits < 32) {
          if (a >>> (bits - 1)) {
            a = ((1 << bits >>> 0) - a) * -1;
          }
        } else {
          if (a / Math.pow(2, bits - 1) | 0) {
            a = (Math.pow(2, bits) - a) * -1;
          }
        }
      }
      this.advance(bits);
      return a;
    };

    Bitstream.prototype.peekLSB = function(bits, signed) {
      var a, mBits;
      if (bits === 0) {
        return 0;
      }
      if (bits > 40) {
        throw new Error("Too many bits!");
      }
      mBits = bits + this.bitPosition;
      a = (this.stream.peekUInt8(0)) >>> this.bitPosition;
      if (mBits > 8) {
        a |= (this.stream.peekUInt8(1)) << (8 - this.bitPosition);
      }
      if (mBits > 16) {
        a |= (this.stream.peekUInt8(2)) << (16 - this.bitPosition);
      }
      if (mBits > 24) {
        a += (this.stream.peekUInt8(3)) << (24 - this.bitPosition) >>> 0;
      }
      if (mBits > 32) {
        a += (this.stream.peekUInt8(4)) * Math.pow(2, 32 - this.bitPosition);
      }
      if (mBits >= 32) {
        a %= Math.pow(2, bits);
      } else {
        a &= (1 << bits) - 1;
      }
      if (signed) {
        if (mBits < 32) {
          if (a >>> (bits - 1)) {
            a = ((1 << bits >>> 0) - a) * -1;
          }
        } else {
          if (a / Math.pow(2, bits - 1) | 0) {
            a = (Math.pow(2, bits) - a) * -1;
          }
        }
      }
      return a;
    };

    return Bitstream;

  })();

  module.exports = Bitstream;

}).call(this);

},{}],6:[function(require,module,exports){
(function (global){(function (){
// Generated by CoffeeScript 1.12.7
(function() {
  var AVBuffer;

  AVBuffer = (function() {
    var BlobBuilder, URL;

    function AVBuffer(input) {
      var ref;
      if (input instanceof Uint8Array) {
        this.data = input;
      } else if (input instanceof ArrayBuffer || Array.isArray(input) || typeof input === 'number' || ((ref = global.Buffer) != null ? ref.isBuffer(input) : void 0)) {
        this.data = new Uint8Array(input);
      } else if (input.buffer instanceof ArrayBuffer) {
        this.data = new Uint8Array(input.buffer, input.byteOffset, input.length * input.BYTES_PER_ELEMENT);
      } else if (input instanceof AVBuffer) {
        this.data = input.data;
      } else {
        throw new Error("Constructing buffer with unknown type.");
      }
      this.length = this.data.length;
      this.next = null;
      this.prev = null;
    }

    AVBuffer.allocate = function(size) {
      return new AVBuffer(size);
    };

    AVBuffer.prototype.copy = function() {
      return new AVBuffer(new Uint8Array(this.data));
    };

    AVBuffer.prototype.slice = function(position, length) {
      if (length == null) {
        length = this.length;
      }
      if (position === 0 && length >= this.length) {
        return new AVBuffer(this.data);
      } else {
        return new AVBuffer(this.data.subarray(position, position + length));
      }
    };

    BlobBuilder = global.BlobBuilder || global.MozBlobBuilder || global.WebKitBlobBuilder;

    URL = global.URL || global.webkitURL || global.mozURL;

    AVBuffer.makeBlob = function(data, type) {
      var bb;
      if (type == null) {
        type = 'application/octet-stream';
      }
      try {
        return new Blob([data], {
          type: type
        });
      } catch (error) {}
      if (BlobBuilder != null) {
        bb = new BlobBuilder;
        bb.append(data);
        return bb.getBlob(type);
      }
      return null;
    };

    AVBuffer.makeBlobURL = function(data, type) {
      return URL != null ? URL.createObjectURL(this.makeBlob(data, type)) : void 0;
    };

    AVBuffer.revokeBlobURL = function(url) {
      return URL != null ? URL.revokeObjectURL(url) : void 0;
    };

    AVBuffer.prototype.toBlob = function() {
      return AVBuffer.makeBlob(this.data.buffer);
    };

    AVBuffer.prototype.toBlobURL = function() {
      return AVBuffer.makeBlobURL(this.data.buffer);
    };

    return AVBuffer;

  })();

  module.exports = AVBuffer;

}).call(this);

}).call(this)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})

},{}],7:[function(require,module,exports){
// Generated by CoffeeScript 1.12.7
(function() {
  var BufferList;

  BufferList = (function() {
    function BufferList() {
      this.first = null;
      this.last = null;
      this.numBuffers = 0;
      this.availableBytes = 0;
      this.availableBuffers = 0;
    }

    BufferList.prototype.copy = function() {
      var result;
      result = new BufferList;
      result.first = this.first;
      result.last = this.last;
      result.numBuffers = this.numBuffers;
      result.availableBytes = this.availableBytes;
      result.availableBuffers = this.availableBuffers;
      return result;
    };

    BufferList.prototype.append = function(buffer) {
      var ref;
      buffer.prev = this.last;
      if ((ref = this.last) != null) {
        ref.next = buffer;
      }
      this.last = buffer;
      if (this.first == null) {
        this.first = buffer;
      }
      this.availableBytes += buffer.length;
      this.availableBuffers++;
      return this.numBuffers++;
    };

    BufferList.prototype.advance = function() {
      if (this.first) {
        this.availableBytes -= this.first.length;
        this.availableBuffers--;
        this.first = this.first.next;
        return this.first != null;
      }
      return false;
    };

    BufferList.prototype.rewind = function() {
      var ref;
      if (this.first && !this.first.prev) {
        return false;
      }
      this.first = ((ref = this.first) != null ? ref.prev : void 0) || this.last;
      if (this.first) {
        this.availableBytes += this.first.length;
        this.availableBuffers++;
      }
      return this.first != null;
    };

    BufferList.prototype.reset = function() {
      var results;
      results = [];
      while (this.rewind()) {
        continue;
      }
      return results;
    };

    return BufferList;

  })();

  module.exports = BufferList;

}).call(this);

},{}],8:[function(require,module,exports){
// Generated by CoffeeScript 1.12.7
(function() {
  var Base, EventEmitter,
    extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
    hasProp = {}.hasOwnProperty,
    slice = [].slice;

  Base = require('./base');

  EventEmitter = (function(superClass) {
    extend(EventEmitter, superClass);

    function EventEmitter() {
      return EventEmitter.__super__.constructor.apply(this, arguments);
    }

    EventEmitter.prototype.on = function(event, fn) {
      var base;
      if (this.events == null) {
        this.events = {};
      }
      if ((base = this.events)[event] == null) {
        base[event] = [];
      }
      return this.events[event].push(fn);
    };

    EventEmitter.prototype.off = function(event, fn) {
      var events, index, ref;
      if (this.events == null) {
        return;
      }
      if ((ref = this.events) != null ? ref[event] : void 0) {
        if (fn != null) {
          index = this.events[event].indexOf(fn);
          if (~index) {
            return this.events[event].splice(index, 1);
          }
        } else {
          return this.events[event];
        }
      } else if (event == null) {
        return events = {};
      }
    };

    EventEmitter.prototype.once = function(event, fn) {
      var cb;
      return this.on(event, cb = function() {
        this.off(event, cb);
        return fn.apply(this, arguments);
      });
    };

    EventEmitter.prototype.emit = function() {
      var args, event, fn, i, len, ref, ref1;
      event = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : [];
      if (!((ref = this.events) != null ? ref[event] : void 0)) {
        return;
      }
      ref1 = this.events[event].slice();
      for (i = 0, len = ref1.length; i < len; i++) {
        fn = ref1[i];
        fn.apply(this, args);
      }
    };

    return EventEmitter;

  })(Base);

  module.exports = EventEmitter;

}).call(this);

},{"./base":4}],9:[function(require,module,exports){
// Generated by CoffeeScript 1.12.7
(function() {
  var AVBuffer, BufferList, Stream, UnderflowError;

  BufferList = require('./bufferlist');

  AVBuffer = require('./buffer');

  UnderflowError = require('./underflow');

  Stream = (function() {
    var buf, decodeString, float32, float64, float64Fallback, float80, int16, int32, int8, nativeEndian, uint16, uint32, uint8;

    buf = new ArrayBuffer(16);

    uint8 = new Uint8Array(buf);

    int8 = new Int8Array(buf);

    uint16 = new Uint16Array(buf);

    int16 = new Int16Array(buf);

    uint32 = new Uint32Array(buf);

    int32 = new Int32Array(buf);

    float32 = new Float32Array(buf);

    if (typeof Float64Array !== "undefined" && Float64Array !== null) {
      float64 = new Float64Array(buf);
    }

    nativeEndian = new Uint16Array(new Uint8Array([0x12, 0x34]).buffer)[0] === 0x3412;

    function Stream(list1) {
      this.list = list1;
      this.localOffset = 0;
      this.offset = 0;
    }

    Stream.fromBuffer = function(buffer) {
      var list;
      list = new BufferList;
      list.append(buffer);
      return new Stream(list);
    };

    Stream.prototype.copy = function() {
      var result;
      result = new Stream(this.list.copy());
      result.localOffset = this.localOffset;
      result.offset = this.offset;
      return result;
    };

    Stream.prototype.available = function(bytes) {
      return bytes <= this.list.availableBytes - this.localOffset;
    };

    Stream.prototype.remainingBytes = function() {
      return this.list.availableBytes - this.localOffset;
    };

    Stream.prototype.advance = function(bytes) {
      if (!this.available(bytes)) {
        throw new UnderflowError();
      }
      this.localOffset += bytes;
      this.offset += bytes;
      while (this.list.first && this.localOffset >= this.list.first.length) {
        this.localOffset -= this.list.first.length;
        this.list.advance();
      }
      return this;
    };

    Stream.prototype.rewind = function(bytes) {
      if (bytes > this.offset) {
        throw new UnderflowError();
      }
      if (!this.list.first) {
        this.list.rewind();
        this.localOffset = this.list.first.length;
      }
      this.localOffset -= bytes;
      this.offset -= bytes;
      while (this.list.first.prev && this.localOffset < 0) {
        this.list.rewind();
        this.localOffset += this.list.first.length;
      }
      return this;
    };

    Stream.prototype.seek = function(position) {
      if (position > this.offset) {
        return this.advance(position - this.offset);
      } else if (position < this.offset) {
        return this.rewind(this.offset - position);
      }
    };

    Stream.prototype.readUInt8 = function() {
      var a;
      if (!this.available(1)) {
        throw new UnderflowError();
      }
      a = this.list.first.data[this.localOffset];
      this.localOffset += 1;
      this.offset += 1;
      if (this.localOffset === this.list.first.length) {
        this.localOffset = 0;
        this.list.advance();
      }
      return a;
    };

    Stream.prototype.peekUInt8 = function(offset) {
      var buffer;
      if (offset == null) {
        offset = 0;
      }
      if (!this.available(offset + 1)) {
        throw new UnderflowError();
      }
      offset = this.localOffset + offset;
      buffer = this.list.first;
      while (buffer) {
        if (buffer.length > offset) {
          return buffer.data[offset];
        }
        offset -= buffer.length;
        buffer = buffer.next;
      }
      return 0;
    };

    Stream.prototype.read = function(bytes, littleEndian) {
      var i, j, k, ref, ref1;
      if (littleEndian == null) {
        littleEndian = false;
      }
      if (littleEndian === nativeEndian) {
        for (i = j = 0, ref = bytes; j < ref; i = j += 1) {
          uint8[i] = this.readUInt8();
        }
      } else {
        for (i = k = ref1 = bytes - 1; k >= 0; i = k += -1) {
          uint8[i] = this.readUInt8();
        }
      }
    };

    Stream.prototype.peek = function(bytes, offset, littleEndian) {
      var i, j, k, ref, ref1;
      if (littleEndian == null) {
        littleEndian = false;
      }
      if (littleEndian === nativeEndian) {
        for (i = j = 0, ref = bytes; j < ref; i = j += 1) {
          uint8[i] = this.peekUInt8(offset + i);
        }
      } else {
        for (i = k = 0, ref1 = bytes; k < ref1; i = k += 1) {
          uint8[bytes - i - 1] = this.peekUInt8(offset + i);
        }
      }
    };

    Stream.prototype.readInt8 = function() {
      this.read(1);
      return int8[0];
    };

    Stream.prototype.peekInt8 = function(offset) {
      if (offset == null) {
        offset = 0;
      }
      this.peek(1, offset);
      return int8[0];
    };

    Stream.prototype.readUInt16 = function(littleEndian) {
      this.read(2, littleEndian);
      return uint16[0];
    };

    Stream.prototype.peekUInt16 = function(offset, littleEndian) {
      if (offset == null) {
        offset = 0;
      }
      this.peek(2, offset, littleEndian);
      return uint16[0];
    };

    Stream.prototype.readInt16 = function(littleEndian) {
      this.read(2, littleEndian);
      return int16[0];
    };

    Stream.prototype.peekInt16 = function(offset, littleEndian) {
      if (offset == null) {
        offset = 0;
      }
      this.peek(2, offset, littleEndian);
      return int16[0];
    };

    Stream.prototype.readUInt24 = function(littleEndian) {
      if (littleEndian) {
        return this.readUInt16(true) + (this.readUInt8() << 16);
      } else {
        return (this.readUInt16() << 8) + this.readUInt8();
      }
    };

    Stream.prototype.peekUInt24 = function(offset, littleEndian) {
      if (offset == null) {
        offset = 0;
      }
      if (littleEndian) {
        return this.peekUInt16(offset, true) + (this.peekUInt8(offset + 2) << 16);
      } else {
        return (this.peekUInt16(offset) << 8) + this.peekUInt8(offset + 2);
      }
    };

    Stream.prototype.readInt24 = function(littleEndian) {
      if (littleEndian) {
        return this.readUInt16(true) + (this.readInt8() << 16);
      } else {
        return (this.readInt16() << 8) + this.readUInt8();
      }
    };

    Stream.prototype.peekInt24 = function(offset, littleEndian) {
      if (offset == null) {
        offset = 0;
      }
      if (littleEndian) {
        return this.peekUInt16(offset, true) + (this.peekInt8(offset + 2) << 16);
      } else {
        return (this.peekInt16(offset) << 8) + this.peekUInt8(offset + 2);
      }
    };

    Stream.prototype.readUInt32 = function(littleEndian) {
      this.read(4, littleEndian);
      return uint32[0];
    };

    Stream.prototype.peekUInt32 = function(offset, littleEndian) {
      if (offset == null) {
        offset = 0;
      }
      this.peek(4, offset, littleEndian);
      return uint32[0];
    };

    Stream.prototype.readInt32 = function(littleEndian) {
      this.read(4, littleEndian);
      return int32[0];
    };

    Stream.prototype.peekInt32 = function(offset, littleEndian) {
      if (offset == null) {
        offset = 0;
      }
      this.peek(4, offset, littleEndian);
      return int32[0];
    };

    Stream.prototype.readFloat32 = function(littleEndian) {
      this.read(4, littleEndian);
      return float32[0];
    };

    Stream.prototype.peekFloat32 = function(offset, littleEndian) {
      if (offset == null) {
        offset = 0;
      }
      this.peek(4, offset, littleEndian);
      return float32[0];
    };

    Stream.prototype.readFloat64 = function(littleEndian) {
      this.read(8, littleEndian);
      if (float64) {
        return float64[0];
      } else {
        return float64Fallback();
      }
    };

    float64Fallback = function() {
      var exp, frac, high, low, out, sign;
      low = uint32[0], high = uint32[1];
      if (!high || high === 0x80000000) {
        return 0.0;
      }
      sign = 1 - (high >>> 31) * 2;
      exp = (high >>> 20) & 0x7ff;
      frac = high & 0xfffff;
      if (exp === 0x7ff) {
        if (frac) {
          return 0/0;
        }
        return sign * 2e308;
      }
      exp -= 1023;
      out = (frac | 0x100000) * Math.pow(2, exp - 20);
      out += low * Math.pow(2, exp - 52);
      return sign * out;
    };

    Stream.prototype.peekFloat64 = function(offset, littleEndian) {
      if (offset == null) {
        offset = 0;
      }
      this.peek(8, offset, littleEndian);
      if (float64) {
        return float64[0];
      } else {
        return float64Fallback();
      }
    };

    Stream.prototype.readFloat80 = function(littleEndian) {
      this.read(10, littleEndian);
      return float80();
    };

    float80 = function() {
      var a0, a1, exp, high, low, out, sign;
      high = uint32[0], low = uint32[1];
      a0 = uint8[9];
      a1 = uint8[8];
      sign = 1 - (a0 >>> 7) * 2;
      exp = ((a0 & 0x7F) << 8) | a1;
      if (exp === 0 && low === 0 && high === 0) {
        return 0;
      }
      if (exp === 0x7fff) {
        if (low === 0 && high === 0) {
          return sign * 2e308;
        }
        return 0/0;
      }
      exp -= 16383;
      out = low * Math.pow(2, exp - 31);
      out += high * Math.pow(2, exp - 63);
      return sign * out;
    };

    Stream.prototype.peekFloat80 = function(offset, littleEndian) {
      if (offset == null) {
        offset = 0;
      }
      this.peek(10, offset, littleEndian);
      return float80();
    };

    Stream.prototype.readBuffer = function(length) {
      var i, j, ref, result, to;
      result = AVBuffer.allocate(length);
      to = result.data;
      for (i = j = 0, ref = length; j < ref; i = j += 1) {
        to[i] = this.readUInt8();
      }
      return result;
    };

    Stream.prototype.peekBuffer = function(offset, length) {
      var i, j, ref, result, to;
      if (offset == null) {
        offset = 0;
      }
      result = AVBuffer.allocate(length);
      to = result.data;
      for (i = j = 0, ref = length; j < ref; i = j += 1) {
        to[i] = this.peekUInt8(offset + i);
      }
      return result;
    };

    Stream.prototype.readSingleBuffer = function(length) {
      var result;
      result = this.list.first.slice(this.localOffset, length);
      this.advance(result.length);
      return result;
    };

    Stream.prototype.peekSingleBuffer = function(offset, length) {
      var result;
      result = this.list.first.slice(this.localOffset + offset, length);
      return result;
    };

    Stream.prototype.readString = function(length, encoding) {
      if (encoding == null) {
        encoding = 'ascii';
      }
      return decodeString.call(this, 0, length, encoding, true);
    };

    Stream.prototype.peekString = function(offset, length, encoding) {
      if (offset == null) {
        offset = 0;
      }
      if (encoding == null) {
        encoding = 'ascii';
      }
      return decodeString.call(this, offset, length, encoding, false);
    };

    decodeString = function(offset, length, encoding, advance) {
      var b1, b2, b3, b4, bom, c, end, littleEndian, nullEnd, pt, result, w1, w2;
      encoding = encoding.toLowerCase();
      nullEnd = length === null ? 0 : -1;
      if (length == null) {
        length = 2e308;
      }
      end = offset + length;
      result = '';
      switch (encoding) {
        case 'ascii':
        case 'latin1':
          while (offset < end && (c = this.peekUInt8(offset++)) !== nullEnd) {
            result += String.fromCharCode(c);
          }
          break;
        case 'utf8':
        case 'utf-8':
          while (offset < end && (b1 = this.peekUInt8(offset++)) !== nullEnd) {
            if ((b1 & 0x80) === 0) {
              result += String.fromCharCode(b1);
            } else if ((b1 & 0xe0) === 0xc0) {
              b2 = this.peekUInt8(offset++) & 0x3f;
              result += String.fromCharCode(((b1 & 0x1f) << 6) | b2);
            } else if ((b1 & 0xf0) === 0xe0) {
              b2 = this.peekUInt8(offset++) & 0x3f;
              b3 = this.peekUInt8(offset++) & 0x3f;
              result += String.fromCharCode(((b1 & 0x0f) << 12) | (b2 << 6) | b3);
            } else if ((b1 & 0xf8) === 0xf0) {
              b2 = this.peekUInt8(offset++) & 0x3f;
              b3 = this.peekUInt8(offset++) & 0x3f;
              b4 = this.peekUInt8(offset++) & 0x3f;
              pt = (((b1 & 0x0f) << 18) | (b2 << 12) | (b3 << 6) | b4) - 0x10000;
              result += String.fromCharCode(0xd800 + (pt >> 10), 0xdc00 + (pt & 0x3ff));
            }
          }
          break;
        case 'utf16-be':
        case 'utf16be':
        case 'utf16le':
        case 'utf16-le':
        case 'utf16bom':
        case 'utf16-bom':
          switch (encoding) {
            case 'utf16be':
            case 'utf16-be':
              littleEndian = false;
              break;
            case 'utf16le':
            case 'utf16-le':
              littleEndian = true;
              break;
            case 'utf16bom':
            case 'utf16-bom':
              if (length < 2 || (bom = this.peekUInt16(offset)) === nullEnd) {
                if (advance) {
                  this.advance(offset += 2);
                }
                return result;
              }
              littleEndian = bom === 0xfffe;
              offset += 2;
          }
          while (offset < end && (w1 = this.peekUInt16(offset, littleEndian)) !== nullEnd) {
            offset += 2;
            if (w1 < 0xd800 || w1 > 0xdfff) {
              result += String.fromCharCode(w1);
            } else {
              if (w1 > 0xdbff) {
                throw new Error("Invalid utf16 sequence.");
              }
              w2 = this.peekUInt16(offset, littleEndian);
              if (w2 < 0xdc00 || w2 > 0xdfff) {
                throw new Error("Invalid utf16 sequence.");
              }
              result += String.fromCharCode(w1, w2);
              offset += 2;
            }
          }
          if (w1 === nullEnd) {
            offset += 2;
          }
          break;
        default:
          throw new Error("Unknown encoding: " + encoding);
      }
      if (advance) {
        this.advance(offset);
      }
      return result;
    };

    return Stream;

  })();

  module.exports = Stream;

}).call(this);

},{"./buffer":6,"./bufferlist":7,"./underflow":10}],10:[function(require,module,exports){
// Generated by CoffeeScript 1.12.7
(function() {
  var UnderflowError,
    extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
    hasProp = {}.hasOwnProperty;

  UnderflowError = (function(superClass) {
    extend(UnderflowError, superClass);

    function UnderflowError() {
      UnderflowError.__super__.constructor.apply(this, arguments);
      this.name = 'UnderflowError';
      this.stack = new Error().stack;
    }

    return UnderflowError;

  })(Error);

  module.exports = UnderflowError;

}).call(this);

},{}],11:[function(require,module,exports){
// Generated by CoffeeScript 1.12.7
(function() {
  var Bitstream, BufferList, Decoder, EventEmitter, Stream, UnderflowError,
    extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
    hasProp = {}.hasOwnProperty;

  EventEmitter = require('./core/events');

  BufferList = require('./core/bufferlist');

  Stream = require('./core/stream');

  Bitstream = require('./core/bitstream');

  UnderflowError = require('./core/underflow');

  Decoder = (function(superClass) {
    var codecs;

    extend(Decoder, superClass);

    function Decoder(demuxer, format) {
      var list;
      this.demuxer = demuxer;
      this.format = format;
      list = new BufferList;
      this.stream = new Stream(list);
      this.bitstream = new Bitstream(this.stream);
      this.receivedFinalBuffer = false;
      this.waiting = false;
      this.demuxer.on('cookie', (function(_this) {
        return function(cookie) {
          var error;
          try {
            return _this.setCookie(cookie);
          } catch (error1) {
            error = error1;
            return _this.emit('error', error);
          }
        };
      })(this));
      this.demuxer.on('data', (function(_this) {
        return function(chunk) {
          list.append(chunk);
          if (_this.waiting) {
            return _this.decode();
          }
        };
      })(this));
      this.demuxer.on('end', (function(_this) {
        return function() {
          _this.receivedFinalBuffer = true;
          if (_this.waiting) {
            return _this.decode();
          }
        };
      })(this));
      this.init();
    }

    Decoder.prototype.init = function() {};

    Decoder.prototype.setCookie = function(cookie) {};

    Decoder.prototype.readChunk = function() {};

    Decoder.prototype.decode = function() {
      var error, offset, packet;
      this.waiting = !this.receivedFinalBuffer;
      offset = this.bitstream.offset();
      try {
        packet = this.readChunk();
      } catch (error1) {
        error = error1;
        if (!(error instanceof UnderflowError)) {
          this.emit('error', error);
          return false;
        }
      }
      if (packet) {
        this.emit('data', packet);
        if (this.receivedFinalBuffer) {
          this.emit('end');
        }
        return true;
      } else if (!this.receivedFinalBuffer) {
        this.bitstream.seek(offset);
        this.waiting = true;
      } else {
        this.emit('end');
      }
      return false;
    };

    Decoder.prototype.seek = function(timestamp) {
      var seekPoint;
      seekPoint = this.demuxer.seek(timestamp);
      this.stream.seek(seekPoint.offset);
      return seekPoint.timestamp;
    };

    codecs = {};

    Decoder.register = function(id, decoder) {
      return codecs[id] = decoder;
    };

    Decoder.find = function(id) {
      return codecs[id] || null;
    };

    return Decoder;

  })(EventEmitter);

  module.exports = Decoder;

}).call(this);

},{"./core/bitstream":5,"./core/bufferlist":7,"./core/events":8,"./core/stream":9,"./core/underflow":10}],12:[function(require,module,exports){
// Generated by CoffeeScript 1.12.7
(function() {
  var Decoder, LPCMDecoder,
    bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
    extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
    hasProp = {}.hasOwnProperty;

  Decoder = require('../decoder');

  LPCMDecoder = (function(superClass) {
    extend(LPCMDecoder, superClass);

    function LPCMDecoder() {
      this.readChunk = bind(this.readChunk, this);
      return LPCMDecoder.__super__.constructor.apply(this, arguments);
    }

    Decoder.register('lpcm', LPCMDecoder);

    LPCMDecoder.prototype.readChunk = function() {
      var chunkSize, i, j, k, l, littleEndian, m, n, o, output, ref, ref1, ref2, ref3, ref4, ref5, samples, stream;
      stream = this.stream;
      littleEndian = this.format.littleEndian;
      chunkSize = Math.min(4096, stream.remainingBytes());
      samples = chunkSize / (this.format.bitsPerChannel / 8) | 0;
      if (chunkSize < this.format.bitsPerChannel / 8) {
        return null;
      }
      if (this.format.floatingPoint) {
        switch (this.format.bitsPerChannel) {
          case 32:
            output = new Float32Array(samples);
            for (i = j = 0, ref = samples; j < ref; i = j += 1) {
              output[i] = stream.readFloat32(littleEndian);
            }
            break;
          case 64:
            output = new Float64Array(samples);
            for (i = k = 0, ref1 = samples; k < ref1; i = k += 1) {
              output[i] = stream.readFloat64(littleEndian);
            }
            break;
          default:
            throw new Error('Unsupported bit depth.');
        }
      } else {
        switch (this.format.bitsPerChannel) {
          case 8:
            output = new Int8Array(samples);
            for (i = l = 0, ref2 = samples; l < ref2; i = l += 1) {
              output[i] = stream.readInt8();
            }
            break;
          case 16:
            output = new Int16Array(samples);
            for (i = m = 0, ref3 = samples; m < ref3; i = m += 1) {
              output[i] = stream.readInt16(littleEndian);
            }
            break;
          case 24:
            output = new Int32Array(samples);
            for (i = n = 0, ref4 = samples; n < ref4; i = n += 1) {
              output[i] = stream.readInt24(littleEndian);
            }
            break;
          case 32:
            output = new Int32Array(samples);
            for (i = o = 0, ref5 = samples; o < ref5; i = o += 1) {
              output[i] = stream.readInt32(littleEndian);
            }
            break;
          default:
            throw new Error('Unsupported bit depth.');
        }
      }
      return output;
    };

    return LPCMDecoder;

  })(Decoder);

}).call(this);

},{"../decoder":11}],13:[function(require,module,exports){
// Generated by CoffeeScript 1.12.7
(function() {
  var Decoder, XLAWDecoder,
    bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
    extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
    hasProp = {}.hasOwnProperty;

  Decoder = require('../decoder');

  XLAWDecoder = (function(superClass) {
    var BIAS, QUANT_MASK, SEG_MASK, SEG_SHIFT, SIGN_BIT;

    extend(XLAWDecoder, superClass);

    function XLAWDecoder() {
      this.readChunk = bind(this.readChunk, this);
      return XLAWDecoder.__super__.constructor.apply(this, arguments);
    }

    Decoder.register('ulaw', XLAWDecoder);

    Decoder.register('alaw', XLAWDecoder);

    SIGN_BIT = 0x80;

    QUANT_MASK = 0xf;

    SEG_SHIFT = 4;

    SEG_MASK = 0x70;

    BIAS = 0x84;

    XLAWDecoder.prototype.init = function() {
      var i, j, k, seg, t, table, val;
      this.format.bitsPerChannel = 16;
      this.table = table = new Int16Array(256);
      if (this.format.formatID === 'ulaw') {
        for (i = j = 0; j < 256; i = ++j) {
          val = ~i;
          t = ((val & QUANT_MASK) << 3) + BIAS;
          t <<= (val & SEG_MASK) >>> SEG_SHIFT;
          table[i] = val & SIGN_BIT ? BIAS - t : t - BIAS;
        }
      } else {
        for (i = k = 0; k < 256; i = ++k) {
          val = i ^ 0x55;
          t = val & QUANT_MASK;
          seg = (val & SEG_MASK) >>> SEG_SHIFT;
          if (seg) {
            t = (t + t + 1 + 32) << (seg + 2);
          } else {
            t = (t + t + 1) << 3;
          }
          table[i] = val & SIGN_BIT ? t : -t;
        }
      }
    };

    XLAWDecoder.prototype.readChunk = function() {
      var i, j, output, ref, ref1, samples, stream, table;
      ref = this, stream = ref.stream, table = ref.table;
      samples = Math.min(4096, this.stream.remainingBytes());
      if (samples === 0) {
        return;
      }
      output = new Int16Array(samples);
      for (i = j = 0, ref1 = samples; j < ref1; i = j += 1) {
        output[i] = table[stream.readUInt8()];
      }
      return output;
    };

    return XLAWDecoder;

  })(Decoder);

}).call(this);

},{"../decoder":11}],14:[function(require,module,exports){
// Generated by CoffeeScript 1.12.7
(function() {
  var BufferList, Demuxer, EventEmitter, Stream,
    extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
    hasProp = {}.hasOwnProperty;

  EventEmitter = require('./core/events');

  BufferList = require('./core/bufferlist');

  Stream = require('./core/stream');

  Demuxer = (function(superClass) {
    var formats;

    extend(Demuxer, superClass);

    Demuxer.probe = function(buffer) {
      return false;
    };

    function Demuxer(source, chunk) {
      var list, received;
      list = new BufferList;
      list.append(chunk);
      this.stream = new Stream(list);
      received = false;
      source.on('data', (function(_this) {
        return function(chunk) {
          var e;
          received = true;
          list.append(chunk);
          try {
            return _this.readChunk(chunk);
          } catch (error) {
            e = error;
            return _this.emit('error', e);
          }
        };
      })(this));
      source.on('error', (function(_this) {
        return function(err) {
          return _this.emit('error', err);
        };
      })(this));
      source.on('end', (function(_this) {
        return function() {
          if (!received) {
            _this.readChunk(chunk);
          }
          return _this.emit('end');
        };
      })(this));
      this.seekPoints = [];
      this.init();
    }

    Demuxer.prototype.init = function() {};

    Demuxer.prototype.readChunk = function(chunk) {};

    Demuxer.prototype.addSeekPoint = function(offset, timestamp) {
      var index;
      index = this.searchTimestamp(timestamp);
      return this.seekPoints.splice(index, 0, {
        offset: offset,
        timestamp: timestamp
      });
    };

    Demuxer.prototype.searchTimestamp = function(timestamp, backward) {
      var high, low, mid, time;
      low = 0;
      high = this.seekPoints.length;
      if (high > 0 && this.seekPoints[high - 1].timestamp < timestamp) {
        return high;
      }
      while (low < high) {
        mid = (low + high) >> 1;
        time = this.seekPoints[mid].timestamp;
        if (time < timestamp) {
          low = mid + 1;
        } else if (time >= timestamp) {
          high = mid;
        }
      }
      if (high > this.seekPoints.length) {
        high = this.seekPoints.length;
      }
      return high;
    };

    Demuxer.prototype.seek = function(timestamp) {
      var index, seekPoint;
      if (this.format && this.format.framesPerPacket > 0 && this.format.bytesPerPacket > 0) {
        seekPoint = {
          timestamp: timestamp,
          offset: this.format.bytesPerPacket * timestamp / this.format.framesPerPacket
        };
        return seekPoint;
      } else {
        index = this.searchTimestamp(timestamp);
        return this.seekPoints[index];
      }
    };

    formats = [];

    Demuxer.register = function(demuxer) {
      return formats.push(demuxer);
    };

    Demuxer.find = function(buffer) {
      var e, format, i, len, offset, stream;
      stream = Stream.fromBuffer(buffer);
      for (i = 0, len = formats.length; i < len; i++) {
        format = formats[i];
        offset = stream.offset;
        try {
          if (format.probe(stream)) {
            return format;
          }
        } catch (error) {
          e = error;
        }
        stream.seek(offset);
      }
      return null;
    };

    return Demuxer;

  })(EventEmitter);

  module.exports = Demuxer;

}).call(this);

},{"./core/bufferlist":7,"./core/events":8,"./core/stream":9}],15:[function(require,module,exports){
// Generated by CoffeeScript 1.12.7
(function() {
  var AIFFDemuxer, Demuxer,
    extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
    hasProp = {}.hasOwnProperty;

  Demuxer = require('../demuxer');

  AIFFDemuxer = (function(superClass) {
    extend(AIFFDemuxer, superClass);

    function AIFFDemuxer() {
      return AIFFDemuxer.__super__.constructor.apply(this, arguments);
    }

    Demuxer.register(AIFFDemuxer);

    AIFFDemuxer.probe = function(buffer) {
      var ref;
      return buffer.peekString(0, 4) === 'FORM' && ((ref = buffer.peekString(8, 4)) === 'AIFF' || ref === 'AIFC');
    };

    AIFFDemuxer.prototype.readChunk = function() {
      var buffer, format, offset, ref;
      if (!this.readStart && this.stream.available(12)) {
        if (this.stream.readString(4) !== 'FORM') {
          return this.emit('error', 'Invalid AIFF.');
        }
        this.fileSize = this.stream.readUInt32();
        this.fileType = this.stream.readString(4);
        this.readStart = true;
        if ((ref = this.fileType) !== 'AIFF' && ref !== 'AIFC') {
          return this.emit('error', 'Invalid AIFF.');
        }
      }
      while (this.stream.available(1)) {
        if (!this.readHeaders && this.stream.available(8)) {
          this.type = this.stream.readString(4);
          this.len = this.stream.readUInt32();
        }
        switch (this.type) {
          case 'COMM':
            if (!this.stream.available(this.len)) {
              return;
            }
            this.format = {
              formatID: 'lpcm',
              channelsPerFrame: this.stream.readUInt16(),
              sampleCount: this.stream.readUInt32(),
              bitsPerChannel: this.stream.readUInt16(),
              sampleRate: this.stream.readFloat80(),
              framesPerPacket: 1,
              littleEndian: false,
              floatingPoint: false
            };
            this.format.bytesPerPacket = (this.format.bitsPerChannel / 8) * this.format.channelsPerFrame;
            if (this.fileType === 'AIFC') {
              format = this.stream.readString(4);
              this.format.littleEndian = format === 'sowt' && this.format.bitsPerChannel > 8;
              this.format.floatingPoint = format === 'fl32' || format === 'fl64';
              if (format === 'twos' || format === 'sowt' || format === 'fl32' || format === 'fl64' || format === 'NONE') {
                format = 'lpcm';
              }
              this.format.formatID = format;
              this.len -= 4;
            }
            this.stream.advance(this.len - 18);
            this.emit('format', this.format);
            this.emit('duration', this.format.sampleCount / this.format.sampleRate * 1000 | 0);
            break;
          case 'SSND':
            if (!(this.readSSNDHeader && this.stream.available(4))) {
              offset = this.stream.readUInt32();
              this.stream.advance(4);
              this.stream.advance(offset);
              this.readSSNDHeader = true;
            }
            buffer = this.stream.readSingleBuffer(this.len);
            this.len -= buffer.length;
            this.readHeaders = this.len > 0;
            this.emit('data', buffer);
            break;
          default:
            if (!this.stream.available(this.len)) {
              return;
            }
            this.stream.advance(this.len);
        }
        if (this.type !== 'SSND') {
          this.readHeaders = false;
        }
      }
    };

    return AIFFDemuxer;

  })(Demuxer);

}).call(this);

},{"../demuxer":14}],16:[function(require,module,exports){
// Generated by CoffeeScript 1.12.7
(function() {
  var AUDemuxer, Demuxer,
    extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
    hasProp = {}.hasOwnProperty;

  Demuxer = require('../demuxer');

  AUDemuxer = (function(superClass) {
    var bps, formats;

    extend(AUDemuxer, superClass);

    function AUDemuxer() {
      return AUDemuxer.__super__.constructor.apply(this, arguments);
    }

    Demuxer.register(AUDemuxer);

    AUDemuxer.probe = function(buffer) {
      return buffer.peekString(0, 4) === '.snd';
    };

    bps = [8, 8, 16, 24, 32, 32, 64];

    bps[26] = 8;

    formats = {
      1: 'ulaw',
      27: 'alaw'
    };

    AUDemuxer.prototype.readChunk = function() {
      var bytes, dataSize, encoding, size;
      if (!this.readHeader && this.stream.available(24)) {
        if (this.stream.readString(4) !== '.snd') {
          return this.emit('error', 'Invalid AU file.');
        }
        size = this.stream.readUInt32();
        dataSize = this.stream.readUInt32();
        encoding = this.stream.readUInt32();
        this.format = {
          formatID: formats[encoding] || 'lpcm',
          littleEndian: false,
          floatingPoint: encoding === 6 || encoding === 7,
          bitsPerChannel: bps[encoding - 1],
          sampleRate: this.stream.readUInt32(),
          channelsPerFrame: this.stream.readUInt32(),
          framesPerPacket: 1
        };
        if (this.format.bitsPerChannel == null) {
          return this.emit('error', 'Unsupported encoding in AU file.');
        }
        this.format.bytesPerPacket = (this.format.bitsPerChannel / 8) * this.format.channelsPerFrame;
        if (dataSize !== 0xffffffff) {
          bytes = this.format.bitsPerChannel / 8;
          this.emit('duration', dataSize / bytes / this.format.channelsPerFrame / this.format.sampleRate * 1000 | 0);
        }
        this.emit('format', this.format);
        this.readHeader = true;
      }
      if (this.readHeader) {
        while (this.stream.available(1)) {
          this.emit('data', this.stream.readSingleBuffer(this.stream.remainingBytes()));
        }
      }
    };

    return AUDemuxer;

  })(Demuxer);

}).call(this);

},{"../demuxer":14}],17:[function(require,module,exports){
// Generated by CoffeeScript 1.12.7
(function() {
  var CAFDemuxer, Demuxer, M4ADemuxer,
    extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
    hasProp = {}.hasOwnProperty;

  Demuxer = require('../demuxer');

  M4ADemuxer = require('./m4a');

  CAFDemuxer = (function(superClass) {
    extend(CAFDemuxer, superClass);

    function CAFDemuxer() {
      return CAFDemuxer.__super__.constructor.apply(this, arguments);
    }

    Demuxer.register(CAFDemuxer);

    CAFDemuxer.probe = function(buffer) {
      return buffer.peekString(0, 4) === 'caff';
    };

    CAFDemuxer.prototype.readChunk = function() {
      var buffer, byteOffset, cookie, entries, flags, i, j, k, key, metadata, offset, ref, ref1, sampleOffset, value;
      if (!this.format && this.stream.available(64)) {
        if (this.stream.readString(4) !== 'caff') {
          return this.emit('error', "Invalid CAF, does not begin with 'caff'");
        }
        this.stream.advance(4);
        if (this.stream.readString(4) !== 'desc') {
          return this.emit('error', "Invalid CAF, 'caff' is not followed by 'desc'");
        }
        if (!(this.stream.readUInt32() === 0 && this.stream.readUInt32() === 32)) {
          return this.emit('error', "Invalid 'desc' size, should be 32");
        }
        this.format = {};
        this.format.sampleRate = this.stream.readFloat64();
        this.format.formatID = this.stream.readString(4);
        flags = this.stream.readUInt32();
        if (this.format.formatID === 'lpcm') {
          this.format.floatingPoint = Boolean(flags & 1);
          this.format.littleEndian = Boolean(flags & 2);
        }
        this.format.bytesPerPacket = this.stream.readUInt32();
        this.format.framesPerPacket = this.stream.readUInt32();
        this.format.channelsPerFrame = this.stream.readUInt32();
        this.format.bitsPerChannel = this.stream.readUInt32();
        this.emit('format', this.format);
      }
      while (this.stream.available(1)) {
        if (!this.headerCache) {
          this.headerCache = {
            type: this.stream.readString(4),
            oversize: this.stream.readUInt32() !== 0,
            size: this.stream.readUInt32()
          };
          if (this.headerCache.oversize) {
            return this.emit('error', "Holy Shit, an oversized file, not supported in JS");
          }
        }
        switch (this.headerCache.type) {
          case 'kuki':
            if (this.stream.available(this.headerCache.size)) {
              if (this.format.formatID === 'aac ') {
                offset = this.stream.offset + this.headerCache.size;
                if (cookie = M4ADemuxer.readEsds(this.stream)) {
                  this.emit('cookie', cookie);
                }
                this.stream.seek(offset);
              } else {
                buffer = this.stream.readBuffer(this.headerCache.size);
                this.emit('cookie', buffer);
              }
              this.headerCache = null;
            }
            break;
          case 'pakt':
            if (this.stream.available(this.headerCache.size)) {
              if (this.stream.readUInt32() !== 0) {
                return this.emit('error', 'Sizes greater than 32 bits are not supported.');
              }
              this.numPackets = this.stream.readUInt32();
              if (this.stream.readUInt32() !== 0) {
                return this.emit('error', 'Sizes greater than 32 bits are not supported.');
              }
              this.numFrames = this.stream.readUInt32();
              this.primingFrames = this.stream.readUInt32();
              this.remainderFrames = this.stream.readUInt32();
              this.emit('duration', this.numFrames / this.format.sampleRate * 1000 | 0);
              this.sentDuration = true;
              byteOffset = 0;
              sampleOffset = 0;
              for (i = j = 0, ref = this.numPackets; j < ref; i = j += 1) {
                this.addSeekPoint(byteOffset, sampleOffset);
                byteOffset += this.format.bytesPerPacket || M4ADemuxer.readDescrLen(this.stream);
                sampleOffset += this.format.framesPerPacket || M4ADemuxer.readDescrLen(this.stream);
              }
              this.headerCache = null;
            }
            break;
          case 'info':
            entries = this.stream.readUInt32();
            metadata = {};
            for (i = k = 0, ref1 = entries; 0 <= ref1 ? k < ref1 : k > ref1; i = 0 <= ref1 ? ++k : --k) {
              key = this.stream.readString(null);
              value = this.stream.readString(null);
              metadata[key] = value;
            }
            this.emit('metadata', metadata);
            this.headerCache = null;
            break;
          case 'data':
            if (!this.sentFirstDataChunk) {
              this.stream.advance(4);
              this.headerCache.size -= 4;
              if (this.format.bytesPerPacket !== 0 && !this.sentDuration) {
                this.numFrames = this.headerCache.size / this.format.bytesPerPacket;
                this.emit('duration', this.numFrames / this.format.sampleRate * 1000 | 0);
              }
              this.sentFirstDataChunk = true;
            }
            buffer = this.stream.readSingleBuffer(this.headerCache.size);
            this.headerCache.size -= buffer.length;
            this.emit('data', buffer);
            if (this.headerCache.size <= 0) {
              this.headerCache = null;
            }
            break;
          default:
            if (this.stream.available(this.headerCache.size)) {
              this.stream.advance(this.headerCache.size);
              this.headerCache = null;
            }
        }
      }
    };

    return CAFDemuxer;

  })(Demuxer);

}).call(this);

},{"../demuxer":14,"./m4a":18}],18:[function(require,module,exports){
// Generated by CoffeeScript 1.12.7
(function() {
  var Demuxer, M4ADemuxer,
    extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
    hasProp = {}.hasOwnProperty,
    indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };

  Demuxer = require('../demuxer');

  M4ADemuxer = (function(superClass) {
    var BITS_PER_CHANNEL, TYPES, after, atom, atoms, bool, containers, diskTrack, genres, meta, string;

    extend(M4ADemuxer, superClass);

    function M4ADemuxer() {
      return M4ADemuxer.__super__.constructor.apply(this, arguments);
    }

    Demuxer.register(M4ADemuxer);

    TYPES = ['M4A ', 'M4P ', 'M4B ', 'M4V ', 'isom', 'mp42', 'qt  '];

    M4ADemuxer.probe = function(buffer) {
      var ref;
      return buffer.peekString(4, 4) === 'ftyp' && (ref = buffer.peekString(8, 4), indexOf.call(TYPES, ref) >= 0);
    };

    M4ADemuxer.prototype.init = function() {
      this.atoms = [];
      this.offsets = [];
      this.track = null;
      return this.tracks = [];
    };

    atoms = {};

    containers = {};

    atom = function(name, fn) {
      var c, container, k, len1, ref;
      c = [];
      ref = name.split('.').slice(0, -1);
      for (k = 0, len1 = ref.length; k < len1; k++) {
        container = ref[k];
        c.push(container);
        containers[c.join('.')] = true;
      }
      if (atoms[name] == null) {
        atoms[name] = {};
      }
      return atoms[name].fn = fn;
    };

    after = function(name, fn) {
      if (atoms[name] == null) {
        atoms[name] = {};
      }
      return atoms[name].after = fn;
    };

    M4ADemuxer.prototype.readChunk = function() {
      var handler, path, type;
      this["break"] = false;
      while (this.stream.available(1) && !this["break"]) {
        if (!this.readHeaders) {
          if (!this.stream.available(8)) {
            return;
          }
          this.len = this.stream.readUInt32() - 8;
          this.type = this.stream.readString(4);
          if (this.len === 0) {
            continue;
          }
          this.atoms.push(this.type);
          this.offsets.push(this.stream.offset + this.len);
          this.readHeaders = true;
        }
        path = this.atoms.join('.');
        handler = atoms[path];
        if (handler != null ? handler.fn : void 0) {
          if (!(this.stream.available(this.len) || path === 'mdat')) {
            return;
          }
          handler.fn.call(this);
          if (path in containers) {
            this.readHeaders = false;
          }
        } else if (path in containers) {
          this.readHeaders = false;
        } else {
          if (!this.stream.available(this.len)) {
            return;
          }
          this.stream.advance(this.len);
        }
        while (this.stream.offset >= this.offsets[this.offsets.length - 1]) {
          handler = atoms[this.atoms.join('.')];
          if (handler != null ? handler.after : void 0) {
            handler.after.call(this);
          }
          type = this.atoms.pop();
          this.offsets.pop();
          this.readHeaders = false;
        }
      }
    };

    atom('ftyp', function() {
      var ref;
      if (ref = this.stream.readString(4), indexOf.call(TYPES, ref) < 0) {
        return this.emit('error', 'Not a valid M4A file.');
      }
      return this.stream.advance(this.len - 4);
    });

    atom('moov.trak', function() {
      this.track = {};
      return this.tracks.push(this.track);
    });

    atom('moov.trak.tkhd', function() {
      this.stream.advance(4);
      this.stream.advance(8);
      this.track.id = this.stream.readUInt32();
      return this.stream.advance(this.len - 16);
    });

    atom('moov.trak.mdia.hdlr', function() {
      this.stream.advance(4);
      this.stream.advance(4);
      this.track.type = this.stream.readString(4);
      this.stream.advance(12);
      return this.stream.advance(this.len - 24);
    });

    atom('moov.trak.mdia.mdhd', function() {
      this.stream.advance(4);
      this.stream.advance(8);
      this.track.timeScale = this.stream.readUInt32();
      this.track.duration = this.stream.readUInt32();
      return this.stream.advance(4);
    });

    BITS_PER_CHANNEL = {
      ulaw: 8,
      alaw: 8,
      in24: 24,
      in32: 32,
      fl32: 32,
      fl64: 64
    };

    atom('moov.trak.mdia.minf.stbl.stsd', function() {
      var format, numEntries, ref, ref1, version;
      this.stream.advance(4);
      numEntries = this.stream.readUInt32();
      if (this.track.type !== 'soun') {
        return this.stream.advance(this.len - 8);
      }
      if (numEntries !== 1) {
        return this.emit('error', "Only expecting one entry in sample description atom!");
      }
      this.stream.advance(4);
      format = this.track.format = {};
      format.formatID = this.stream.readString(4);
      this.stream.advance(6);
      this.stream.advance(2);
      version = this.stream.readUInt16();
      this.stream.advance(6);
      format.channelsPerFrame = this.stream.readUInt16();
      format.bitsPerChannel = this.stream.readUInt16();
      this.stream.advance(4);
      format.sampleRate = this.stream.readUInt16();
      this.stream.advance(2);
      if (version === 1) {
        format.framesPerPacket = this.stream.readUInt32();
        this.stream.advance(4);
        format.bytesPerFrame = this.stream.readUInt32();
        this.stream.advance(4);
      } else if (version !== 0) {
        this.emit('error', 'Unknown version in stsd atom');
      }
      if (BITS_PER_CHANNEL[format.formatID] != null) {
        format.bitsPerChannel = BITS_PER_CHANNEL[format.formatID];
      }
      format.floatingPoint = (ref = format.formatID) === 'fl32' || ref === 'fl64';
      format.littleEndian = format.formatID === 'sowt' && format.bitsPerChannel > 8;
      if ((ref1 = format.formatID) === 'twos' || ref1 === 'sowt' || ref1 === 'in24' || ref1 === 'in32' || ref1 === 'fl32' || ref1 === 'fl64' || ref1 === 'raw ' || ref1 === 'NONE') {
        return format.formatID = 'lpcm';
      }
    });

    atom('moov.trak.mdia.minf.stbl.stsd.alac', function() {
      this.stream.advance(4);
      return this.track.cookie = this.stream.readBuffer(this.len - 4);
    });

    atom('moov.trak.mdia.minf.stbl.stsd.esds', function() {
      var offset;
      offset = this.stream.offset + this.len;
      this.track.cookie = M4ADemuxer.readEsds(this.stream);
      return this.stream.seek(offset);
    });

    atom('moov.trak.mdia.minf.stbl.stsd.wave.enda', function() {
      return this.track.format.littleEndian = !!this.stream.readUInt16();
    });

    M4ADemuxer.readDescrLen = function(stream) {
      var c, count, len;
      len = 0;
      count = 4;
      while (count--) {
        c = stream.readUInt8();
        len = (len << 7) | (c & 0x7f);
        if (!(c & 0x80)) {
          break;
        }
      }
      return len;
    };

    M4ADemuxer.readEsds = function(stream) {
      var codec_id, flags, len, tag;
      stream.advance(4);
      tag = stream.readUInt8();
      len = M4ADemuxer.readDescrLen(stream);
      if (tag === 0x03) {
        stream.advance(2);
        flags = stream.readUInt8();
        if (flags & 0x80) {
          stream.advance(2);
        }
        if (flags & 0x40) {
          stream.advance(stream.readUInt8());
        }
        if (flags & 0x20) {
          stream.advance(2);
        }
      } else {
        stream.advance(2);
      }
      tag = stream.readUInt8();
      len = M4ADemuxer.readDescrLen(stream);
      if (tag === 0x04) {
        codec_id = stream.readUInt8();
        stream.advance(1);
        stream.advance(3);
        stream.advance(4);
        stream.advance(4);
        tag = stream.readUInt8();
        len = M4ADemuxer.readDescrLen(stream);
        if (tag === 0x05) {
          return stream.readBuffer(len);
        }
      }
      return null;
    };

    atom('moov.trak.mdia.minf.stbl.stts', function() {
      var entries, i, k, ref;
      this.stream.advance(4);
      entries = this.stream.readUInt32();
      this.track.stts = [];
      for (i = k = 0, ref = entries; k < ref; i = k += 1) {
        this.track.stts[i] = {
          count: this.stream.readUInt32(),
          duration: this.stream.readUInt32()
        };
      }
      return this.setupSeekPoints();
    });

    atom('moov.trak.mdia.minf.stbl.stsc', function() {
      var entries, i, k, ref;
      this.stream.advance(4);
      entries = this.stream.readUInt32();
      this.track.stsc = [];
      for (i = k = 0, ref = entries; k < ref; i = k += 1) {
        this.track.stsc[i] = {
          first: this.stream.readUInt32(),
          count: this.stream.readUInt32(),
          id: this.stream.readUInt32()
        };
      }
      return this.setupSeekPoints();
    });

    atom('moov.trak.mdia.minf.stbl.stsz', function() {
      var entries, i, k, ref;
      this.stream.advance(4);
      this.track.sampleSize = this.stream.readUInt32();
      entries = this.stream.readUInt32();
      if (this.track.sampleSize === 0 && entries > 0) {
        this.track.sampleSizes = [];
        for (i = k = 0, ref = entries; k < ref; i = k += 1) {
          this.track.sampleSizes[i] = this.stream.readUInt32();
        }
      }
      return this.setupSeekPoints();
    });

    atom('moov.trak.mdia.minf.stbl.stco', function() {
      var entries, i, k, ref;
      this.stream.advance(4);
      entries = this.stream.readUInt32();
      this.track.chunkOffsets = [];
      for (i = k = 0, ref = entries; k < ref; i = k += 1) {
        this.track.chunkOffsets[i] = this.stream.readUInt32();
      }
      return this.setupSeekPoints();
    });

    atom('moov.trak.tref.chap', function() {
      var entries, i, k, ref;
      entries = this.len >> 2;
      this.track.chapterTracks = [];
      for (i = k = 0, ref = entries; k < ref; i = k += 1) {
        this.track.chapterTracks[i] = this.stream.readUInt32();
      }
    });

    M4ADemuxer.prototype.setupSeekPoints = function() {
      var i, j, k, l, len1, offset, position, ref, ref1, results, sampleIndex, size, stscIndex, sttsIndex, sttsSample, timestamp;
      if (!((this.track.chunkOffsets != null) && (this.track.stsc != null) && (this.track.sampleSize != null) && (this.track.stts != null))) {
        return;
      }
      stscIndex = 0;
      sttsIndex = 0;
      sttsIndex = 0;
      sttsSample = 0;
      sampleIndex = 0;
      offset = 0;
      timestamp = 0;
      this.track.seekPoints = [];
      ref = this.track.chunkOffsets;
      results = [];
      for (i = k = 0, len1 = ref.length; k < len1; i = ++k) {
        position = ref[i];
        for (j = l = 0, ref1 = this.track.stsc[stscIndex].count; l < ref1; j = l += 1) {
          this.track.seekPoints.push({
            offset: offset,
            position: position,
            timestamp: timestamp
          });
          size = this.track.sampleSize || this.track.sampleSizes[sampleIndex++];
          offset += size;
          position += size;
          timestamp += this.track.stts[sttsIndex].duration;
          if (sttsIndex + 1 < this.track.stts.length && ++sttsSample === this.track.stts[sttsIndex].count) {
            sttsSample = 0;
            sttsIndex++;
          }
        }
        if (stscIndex + 1 < this.track.stsc.length && i + 1 === this.track.stsc[stscIndex + 1].first) {
          results.push(stscIndex++);
        } else {
          results.push(void 0);
        }
      }
      return results;
    };

    after('moov', function() {
      var k, len1, ref, track;
      if (this.mdatOffset != null) {
        this.stream.seek(this.mdatOffset - 8);
      }
      ref = this.tracks;
      for (k = 0, len1 = ref.length; k < len1; k++) {
        track = ref[k];
        if (!(track.type === 'soun')) {
          continue;
        }
        this.track = track;
        break;
      }
      if (this.track.type !== 'soun') {
        this.track = null;
        return this.emit('error', 'No audio tracks in m4a file.');
      }
      this.emit('format', this.track.format);
      this.emit('duration', this.track.duration / this.track.timeScale * 1000 | 0);
      if (this.track.cookie) {
        this.emit('cookie', this.track.cookie);
      }
      return this.seekPoints = this.track.seekPoints;
    });

    atom('mdat', function() {
      var bytes, chunkSize, k, length, numSamples, offset, ref, sample, size;
      if (!this.startedData) {
        if (this.mdatOffset == null) {
          this.mdatOffset = this.stream.offset;
        }
        if (this.tracks.length === 0) {
          bytes = Math.min(this.stream.remainingBytes(), this.len);
          this.stream.advance(bytes);
          this.len -= bytes;
          return;
        }
        this.chunkIndex = 0;
        this.stscIndex = 0;
        this.sampleIndex = 0;
        this.tailOffset = 0;
        this.tailSamples = 0;
        this.startedData = true;
      }
      if (!this.readChapters) {
        this.readChapters = this.parseChapters();
        if (this["break"] = !this.readChapters) {
          return;
        }
        this.stream.seek(this.mdatOffset);
      }
      offset = this.track.chunkOffsets[this.chunkIndex] + this.tailOffset;
      length = 0;
      if (!this.stream.available(offset - this.stream.offset)) {
        this["break"] = true;
        return;
      }
      this.stream.seek(offset);
      while (this.chunkIndex < this.track.chunkOffsets.length) {
        numSamples = this.track.stsc[this.stscIndex].count - this.tailSamples;
        chunkSize = 0;
        for (sample = k = 0, ref = numSamples; k < ref; sample = k += 1) {
          size = this.track.sampleSize || this.track.sampleSizes[this.sampleIndex];
          if (!this.stream.available(length + size)) {
            break;
          }
          length += size;
          chunkSize += size;
          this.sampleIndex++;
        }
        if (sample < numSamples) {
          this.tailOffset += chunkSize;
          this.tailSamples += sample;
          break;
        } else {
          this.chunkIndex++;
          this.tailOffset = 0;
          this.tailSamples = 0;
          if (this.stscIndex + 1 < this.track.stsc.length && this.chunkIndex + 1 === this.track.stsc[this.stscIndex + 1].first) {
            this.stscIndex++;
          }
          if (offset + length !== this.track.chunkOffsets[this.chunkIndex]) {
            break;
          }
        }
      }
      if (length > 0) {
        this.emit('data', this.stream.readBuffer(length));
        return this["break"] = this.chunkIndex === this.track.chunkOffsets.length;
      } else {
        return this["break"] = true;
      }
    });

    M4ADemuxer.prototype.parseChapters = function() {
      var bom, id, k, len, len1, nextTimestamp, point, ref, ref1, ref2, ref3, title, track;
      if (!(((ref = this.track.chapterTracks) != null ? ref.length : void 0) > 0)) {
        return true;
      }
      id = this.track.chapterTracks[0];
      ref1 = this.tracks;
      for (k = 0, len1 = ref1.length; k < len1; k++) {
        track = ref1[k];
        if (track.id === id) {
          break;
        }
      }
      if (track.id !== id) {
        this.emit('error', 'Chapter track does not exist.');
      }
      if (this.chapters == null) {
        this.chapters = [];
      }
      while (this.chapters.length < track.seekPoints.length) {
        point = track.seekPoints[this.chapters.length];
        if (!this.stream.available(point.position - this.stream.offset + 32)) {
          return false;
        }
        this.stream.seek(point.position);
        len = this.stream.readUInt16();
        title = null;
        if (!this.stream.available(len)) {
          return false;
        }
        if (len > 2) {
          bom = this.stream.peekUInt16();
          if (bom === 0xfeff || bom === 0xfffe) {
            title = this.stream.readString(len, 'utf16-bom');
          }
        }
        if (title == null) {
          title = this.stream.readString(len, 'utf8');
        }
        nextTimestamp = (ref2 = (ref3 = track.seekPoints[this.chapters.length + 1]) != null ? ref3.timestamp : void 0) != null ? ref2 : track.duration;
        this.chapters.push({
          title: title,
          timestamp: point.timestamp / track.timeScale * 1000 | 0,
          duration: (nextTimestamp - point.timestamp) / track.timeScale * 1000 | 0
        });
      }
      this.emit('chapters', this.chapters);
      return true;
    };

    atom('moov.udta.meta', function() {
      this.metadata = {};
      return this.stream.advance(4);
    });

    after('moov.udta.meta', function() {
      return this.emit('metadata', this.metadata);
    });

    meta = function(field, name, fn) {
      return atom("moov.udta.meta.ilst." + field + ".data", function() {
        this.stream.advance(8);
        this.len -= 8;
        return fn.call(this, name);
      });
    };

    string = function(field) {
      return this.metadata[field] = this.stream.readString(this.len, 'utf8');
    };

    meta('©alb', 'album', string);

    meta('©arg', 'arranger', string);

    meta('©art', 'artist', string);

    meta('©ART', 'artist', string);

    meta('aART', 'albumArtist', string);

    meta('catg', 'category', string);

    meta('©com', 'composer', string);

    meta('©cpy', 'copyright', string);

    meta('cprt', 'copyright', string);

    meta('©cmt', 'comments', string);

    meta('©day', 'releaseDate', string);

    meta('desc', 'description', string);

    meta('©gen', 'genre', string);

    meta('©grp', 'grouping', string);

    meta('©isr', 'ISRC', string);

    meta('keyw', 'keywords', string);

    meta('©lab', 'recordLabel', string);

    meta('ldes', 'longDescription', string);

    meta('©lyr', 'lyrics', string);

    meta('©nam', 'title', string);

    meta('©phg', 'recordingCopyright', string);

    meta('©prd', 'producer', string);

    meta('©prf', 'performers', string);

    meta('purd', 'purchaseDate', string);

    meta('purl', 'podcastURL', string);

    meta('©swf', 'songwriter', string);

    meta('©too', 'encoder', string);

    meta('©wrt', 'composer', string);

    meta('covr', 'coverArt', function(field) {
      return this.metadata[field] = this.stream.readBuffer(this.len);
    });

    genres = ["Blues", "Classic Rock", "Country", "Dance", "Disco", "Funk", "Grunge", "Hip-Hop", "Jazz", "Metal", "New Age", "Oldies", "Other", "Pop", "R&B", "Rap", "Reggae", "Rock", "Techno", "Industrial", "Alternative", "Ska", "Death Metal", "Pranks", "Soundtrack", "Euro-Techno", "Ambient", "Trip-Hop", "Vocal", "Jazz+Funk", "Fusion", "Trance", "Classical", "Instrumental", "Acid", "House", "Game", "Sound Clip", "Gospel", "Noise", "AlternRock", "Bass", "Soul", "Punk", "Space", "Meditative", "Instrumental Pop", "Instrumental Rock", "Ethnic", "Gothic", "Darkwave", "Techno-Industrial", "Electronic", "Pop-Folk", "Eurodance", "Dream", "Southern Rock", "Comedy", "Cult", "Gangsta", "Top 40", "Christian Rap", "Pop/Funk", "Jungle", "Native American", "Cabaret", "New Wave", "Psychadelic", "Rave", "Showtunes", "Trailer", "Lo-Fi", "Tribal", "Acid Punk", "Acid Jazz", "Polka", "Retro", "Musical", "Rock & Roll", "Hard Rock", "Folk", "Folk/Rock", "National Folk", "Swing", "Fast Fusion", "Bebob", "Latin", "Revival", "Celtic", "Bluegrass", "Avantgarde", "Gothic Rock", "Progressive Rock", "Psychedelic Rock", "Symphonic Rock", "Slow Rock", "Big Band", "Chorus", "Easy Listening", "Acoustic", "Humour", "Speech", "Chanson", "Opera", "Chamber Music", "Sonata", "Symphony", "Booty Bass", "Primus", "Porn Groove", "Satire", "Slow Jam", "Club", "Tango", "Samba", "Folklore", "Ballad", "Power Ballad", "Rhythmic Soul", "Freestyle", "Duet", "Punk Rock", "Drum Solo", "A Capella", "Euro-House", "Dance Hall"];

    meta('gnre', 'genre', function(field) {
      return this.metadata[field] = genres[this.stream.readUInt16() - 1];
    });

    meta('tmpo', 'tempo', function(field) {
      return this.metadata[field] = this.stream.readUInt16();
    });

    meta('rtng', 'rating', function(field) {
      var rating;
      rating = this.stream.readUInt8();
      return this.metadata[field] = rating === 2 ? 'Clean' : rating !== 0 ? 'Explicit' : 'None';
    });

    diskTrack = function(field) {
      this.stream.advance(2);
      this.metadata[field] = this.stream.readUInt16() + ' of ' + this.stream.readUInt16();
      return this.stream.advance(this.len - 6);
    };

    meta('disk', 'diskNumber', diskTrack);

    meta('trkn', 'trackNumber', diskTrack);

    bool = function(field) {
      return this.metadata[field] = this.stream.readUInt8() === 1;
    };

    meta('cpil', 'compilation', bool);

    meta('pcst', 'podcast', bool);

    meta('pgap', 'gapless', bool);

    return M4ADemuxer;

  })(Demuxer);

  module.exports = M4ADemuxer;

}).call(this);

},{"../demuxer":14}],19:[function(require,module,exports){
// Generated by CoffeeScript 1.12.7
(function() {
  var Demuxer, WAVEDemuxer,
    extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
    hasProp = {}.hasOwnProperty;

  Demuxer = require('../demuxer');

  WAVEDemuxer = (function(superClass) {
    var formats;

    extend(WAVEDemuxer, superClass);

    function WAVEDemuxer() {
      return WAVEDemuxer.__super__.constructor.apply(this, arguments);
    }

    Demuxer.register(WAVEDemuxer);

    WAVEDemuxer.probe = function(buffer) {
      return buffer.peekString(0, 4) === 'RIFF' && buffer.peekString(8, 4) === 'WAVE';
    };

    formats = {
      0x0001: 'lpcm',
      0x0003: 'lpcm',
      0x0006: 'alaw',
      0x0007: 'ulaw'
    };

    WAVEDemuxer.prototype.readChunk = function() {
      var buffer, bytes, encoding;
      if (!this.readStart && this.stream.available(12)) {
        if (this.stream.readString(4) !== 'RIFF') {
          return this.emit('error', 'Invalid WAV file.');
        }
        this.fileSize = this.stream.readUInt32(true);
        this.readStart = true;
        if (this.stream.readString(4) !== 'WAVE') {
          return this.emit('error', 'Invalid WAV file.');
        }
      }
      while (this.stream.available(1)) {
        if (!this.readHeaders && this.stream.available(8)) {
          this.type = this.stream.readString(4);
          this.len = this.stream.readUInt32(true);
        }
        switch (this.type) {
          case 'fmt ':
            encoding = this.stream.readUInt16(true);
            if (!(encoding in formats)) {
              return this.emit('error', 'Unsupported format in WAV file.');
            }
            this.format = {
              formatID: formats[encoding],
              floatingPoint: encoding === 0x0003,
              littleEndian: formats[encoding] === 'lpcm',
              channelsPerFrame: this.stream.readUInt16(true),
              sampleRate: this.stream.readUInt32(true),
              framesPerPacket: 1
            };
            this.stream.advance(4);
            this.stream.advance(2);
            this.format.bitsPerChannel = this.stream.readUInt16(true);
            this.format.bytesPerPacket = (this.format.bitsPerChannel / 8) * this.format.channelsPerFrame;
            this.emit('format', this.format);
            this.stream.advance(this.len - 16);
            break;
          case 'data':
            if (!this.sentDuration) {
              bytes = this.format.bitsPerChannel / 8;
              this.emit('duration', this.len / bytes / this.format.channelsPerFrame / this.format.sampleRate * 1000 | 0);
              this.sentDuration = true;
            }
            buffer = this.stream.readSingleBuffer(this.len);
            this.len -= buffer.length;
            this.readHeaders = this.len > 0;
            this.emit('data', buffer);
            break;
          default:
            if (!this.stream.available(this.len)) {
              return;
            }
            this.stream.advance(this.len);
        }
        if (this.type !== 'data') {
          this.readHeaders = false;
        }
      }
    };

    return WAVEDemuxer;

  })(Demuxer);

}).call(this);

},{"../demuxer":14}],20:[function(require,module,exports){
// Generated by CoffeeScript 1.12.7
(function() {
  var AudioDevice, EventEmitter,
    bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
    extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
    hasProp = {}.hasOwnProperty;

  EventEmitter = require('./core/events');

  AudioDevice = (function(superClass) {
    var devices;

    extend(AudioDevice, superClass);

    function AudioDevice(sampleRate1, channels1) {
      this.sampleRate = sampleRate1;
      this.channels = channels1;
      this.updateTime = bind(this.updateTime, this);
      this.playing = false;
      this.currentTime = 0;
      this._lastTime = 0;
    }

    AudioDevice.prototype.start = function() {
      if (this.playing) {
        return;
      }
      this.playing = true;
      if (this.device == null) {
        this.device = AudioDevice.create(this.sampleRate, this.channels);
      }
      if (!this.device) {
        throw new Error("No supported audio device found.");
      }
      this._lastTime = this.device.getDeviceTime();
      this._timer = setInterval(this.updateTime, 200);
      return this.device.on('refill', this.refill = (function(_this) {
        return function(buffer) {
          return _this.emit('refill', buffer);
        };
      })(this));
    };

    AudioDevice.prototype.stop = function() {
      if (!this.playing) {
        return;
      }
      this.playing = false;
      this.device.off('refill', this.refill);
      return clearInterval(this._timer);
    };

    AudioDevice.prototype.destroy = function() {
      var ref;
      this.stop();
      return (ref = this.device) != null ? ref.destroy() : void 0;
    };

    AudioDevice.prototype.seek = function(currentTime) {
      this.currentTime = currentTime;
      if (this.playing) {
        this._lastTime = this.device.getDeviceTime();
      }
      return this.emit('timeUpdate', this.currentTime);
    };

    AudioDevice.prototype.updateTime = function() {
      var time;
      time = this.device.getDeviceTime();
      this.currentTime += (time - this._lastTime) / this.device.sampleRate * 1000 | 0;
      this._lastTime = time;
      return this.emit('timeUpdate', this.currentTime);
    };

    devices = [];

    AudioDevice.register = function(device) {
      return devices.push(device);
    };

    AudioDevice.create = function(sampleRate, channels) {
      var device, i, len;
      for (i = 0, len = devices.length; i < len; i++) {
        device = devices[i];
        if (device.supported) {
          return new device(sampleRate, channels);
        }
      }
      return null;
    };

    return AudioDevice;

  })(EventEmitter);

  module.exports = AudioDevice;

}).call(this);

},{"./core/events":8}],21:[function(require,module,exports){
// Generated by CoffeeScript 1.12.7
(function() {
  var AVBuffer, AudioDevice, EventEmitter, MozillaAudioDevice,
    bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
    extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
    hasProp = {}.hasOwnProperty;

  EventEmitter = require('../core/events');

  AudioDevice = require('../device');

  AVBuffer = require('../core/buffer');

  MozillaAudioDevice = (function(superClass) {
    var createTimer, destroyTimer;

    extend(MozillaAudioDevice, superClass);

    AudioDevice.register(MozillaAudioDevice);

    MozillaAudioDevice.supported = (typeof Audio !== "undefined" && Audio !== null) && 'mozWriteAudio' in new Audio;

    function MozillaAudioDevice(sampleRate, channels) {
      this.sampleRate = sampleRate;
      this.channels = channels;
      this.refill = bind(this.refill, this);
      this.audio = new Audio;
      this.audio.mozSetup(this.channels, this.sampleRate);
      this.writePosition = 0;
      this.prebufferSize = this.sampleRate / 2;
      this.tail = null;
      this.timer = createTimer(this.refill, 100);
    }

    MozillaAudioDevice.prototype.refill = function() {
      var available, buffer, currentPosition, written;
      if (this.tail) {
        written = this.audio.mozWriteAudio(this.tail);
        this.writePosition += written;
        if (this.writePosition < this.tail.length) {
          this.tail = this.tail.subarray(written);
        } else {
          this.tail = null;
        }
      }
      currentPosition = this.audio.mozCurrentSampleOffset();
      available = currentPosition + this.prebufferSize - this.writePosition;
      if (available > 0) {
        buffer = new Float32Array(available);
        this.emit('refill', buffer);
        written = this.audio.mozWriteAudio(buffer);
        if (written < buffer.length) {
          this.tail = buffer.subarray(written);
        }
        this.writePosition += written;
      }
    };

    MozillaAudioDevice.prototype.destroy = function() {
      return destroyTimer(this.timer);
    };

    MozillaAudioDevice.prototype.getDeviceTime = function() {
      return this.audio.mozCurrentSampleOffset() / this.channels;
    };

    createTimer = function(fn, interval) {
      var url, worker;
      url = AVBuffer.makeBlobURL("setInterval(function() { postMessage('ping'); }, " + interval + ");");
      if (url == null) {
        return setInterval(fn, interval);
      }
      worker = new Worker(url);
      worker.onmessage = fn;
      worker.url = url;
      return worker;
    };

    destroyTimer = function(timer) {
      if (timer.terminate) {
        timer.terminate();
        return URL.revokeObjectURL(timer.url);
      } else {
        return clearInterval(timer);
      }
    };

    return MozillaAudioDevice;

  })(EventEmitter);

}).call(this);

},{"../core/buffer":6,"../core/events":8,"../device":20}],22:[function(require,module,exports){
//JavaScript Audio Resampler
//Copyright (C) 2011-2015 Grant Galitz
//Released to Public Domain
function Resampler(fromSampleRate, toSampleRate, channels, inputBufferLength) {
  this.fromSampleRate = +fromSampleRate;
  this.toSampleRate = +toSampleRate;
  this.channels = channels | 0;
  this.inputBufferLength = inputBufferLength;
  this.initialize();
}

Resampler.prototype.initialize = function () {
  //Perform some checks:
  if (this.fromSampleRate > 0 && this.toSampleRate > 0 && this.channels > 0) {
    if (this.fromSampleRate == this.toSampleRate) {
      //Setup a resampler bypass:
      this.resampler = this.bypassResampler;    //Resampler just returns what was passed through.
      this.ratioWeight = 1;
    } else {
      this.ratioWeight = this.fromSampleRate / this.toSampleRate;
      if (this.fromSampleRate < this.toSampleRate) {
        /*
          Use generic linear interpolation if upsampling,
          as linear interpolation produces a gradient that we want
          and works fine with two input sample points per output in this case.
        */
        this.compileLinearInterpolationFunction();
        this.lastWeight = 1;
      } else {
        /*
          Custom resampler I wrote that doesn't skip samples
          like standard linear interpolation in high downsampling.
          This is more accurate than linear interpolation on downsampling.
        */
        this.compileMultiTapFunction();
        this.tailExists = false;
        this.lastWeight = 0;
      }

      var outputBufferSize = (Math.ceil(this.inputBufferLength * this.toSampleRate / this.fromSampleRate / this.channels * 1.01) * this.channels) + this.channels;
      this.outputBuffer = new Float32Array(outputBufferSize);
      this.lastOutput = new Float32Array(this.channels);
    }
  } else {
    throw(new Error("Invalid settings specified for the resampler."));
  }
};

Resampler.prototype.compileLinearInterpolationFunction = function () {
  var toCompile = "var outputOffset = 0;\
    var bufferLength = buffer.length;\
    if (bufferLength > 0) {\
      var weight = this.lastWeight;\
      var firstWeight = 0;\
      var secondWeight = 0;\
      var sourceOffset = 0;\
      var outputOffset = 0;\
      var outputBuffer = this.outputBuffer;\
      for (; weight < 1; weight += " + this.ratioWeight + ") {\
        secondWeight = weight % 1;\
        firstWeight = 1 - secondWeight;";
        for (var channel = 0; channel < this.channels; ++channel) {
          toCompile += "outputBuffer[outputOffset++] = (this.lastOutput[" + channel + "] * firstWeight) + (buffer[" + channel + "] * secondWeight);";
        }
      toCompile += "}\
      weight -= 1;\
      for (bufferLength -= " + this.channels + ", sourceOffset = Math.floor(weight) * " + this.channels + "; sourceOffset < bufferLength;) {\
        secondWeight = weight % 1;\
        firstWeight = 1 - secondWeight;";
        for (var channel = 0; channel < this.channels; ++channel) {
          toCompile += "outputBuffer[outputOffset++] = (buffer[sourceOffset" + ((channel > 0) ? (" + " + channel) : "") + "] * firstWeight) + (buffer[sourceOffset + " + (this.channels + channel) + "] * secondWeight);";
        }
        toCompile += "weight += " + this.ratioWeight + ";\
        sourceOffset = Math.floor(weight) * " + this.channels + ";\
      }";
      for (var channel = 0; channel < this.channels; ++channel) {
        toCompile += "this.lastOutput[" + channel + "] = buffer[sourceOffset++];";
      }
      toCompile += "this.lastWeight = weight % 1;\
    }\
    return this.outputBuffer;";

  this.resampler = Function("buffer", toCompile);
};

Resampler.prototype.compileMultiTapFunction = function () {
  var toCompile = "var outputOffset = 0;\
    var bufferLength = buffer.length;\
    if (bufferLength > 0) {\
      var weight = 0;";
      for (var channel = 0; channel < this.channels; ++channel) {
        toCompile += "var output" + channel + " = 0;"
      }
      toCompile += "var actualPosition = 0;\
      var amountToNext = 0;\
      var alreadyProcessedTail = !this.tailExists;\
      this.tailExists = false;\
      var outputBuffer = this.outputBuffer;\
      var currentPosition = 0;\
      do {\
        if (alreadyProcessedTail) {\
          weight = " + this.ratioWeight + ";";
          for (channel = 0; channel < this.channels; ++channel) {
            toCompile += "output" + channel + " = 0;"
          }
        toCompile += "}\
        else {\
          weight = this.lastWeight;";
          for (channel = 0; channel < this.channels; ++channel) {
            toCompile += "output" + channel + " = this.lastOutput[" + channel + "];"
          }
          toCompile += "alreadyProcessedTail = true;\
        }\
        while (weight > 0 && actualPosition < bufferLength) {\
          amountToNext = 1 + actualPosition - currentPosition;\
          if (weight >= amountToNext) {";
            for (channel = 0; channel < this.channels; ++channel) {
              toCompile += "output" + channel + " += buffer[actualPosition++] * amountToNext;"
            }
            toCompile += "currentPosition = actualPosition;\
            weight -= amountToNext;\
          }\
          else {";
            for (channel = 0; channel < this.channels; ++channel) {
              toCompile += "output" + channel + " += buffer[actualPosition" + ((channel > 0) ? (" + " + channel) : "") + "] * weight;"
            }
            toCompile += "currentPosition += weight;\
            weight = 0;\
            break;\
          }\
        }\
        if (weight <= 0) {";
          for (channel = 0; channel < this.channels; ++channel) {
            toCompile += "outputBuffer[outputOffset++] = output" + channel + " / " + this.ratioWeight + ";"
          }
        toCompile += "}\
        else {\
          this.lastWeight = weight;";
          for (channel = 0; channel < this.channels; ++channel) {
            toCompile += "this.lastOutput[" + channel + "] = output" + channel + ";"
          }
          toCompile += "this.tailExists = true;\
          break;\
        }\
      } while (actualPosition < bufferLength);\
    }\
    return this.outputBuffer;";

  this.resampler = Function("buffer", toCompile);
};

Resampler.prototype.bypassResampler = function (inputBuffer) {
  return inputBuffer;
};

module.exports = Resampler;

},{}],23:[function(require,module,exports){
(function (global){(function (){
// Generated by CoffeeScript 1.12.7
(function() {
  var AudioDevice, EventEmitter, Resampler, WebAudioDevice,
    bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
    extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
    hasProp = {}.hasOwnProperty;

  EventEmitter = require('../core/events');

  AudioDevice = require('../device');

  Resampler = require('./resampler');

  WebAudioDevice = (function(superClass) {
    var AudioContext, createProcessor, sharedContext;

    extend(WebAudioDevice, superClass);

    AudioDevice.register(WebAudioDevice);

    AudioContext = global.AudioContext || global.webkitAudioContext;

    WebAudioDevice.supported = AudioContext && (typeof AudioContext.prototype[createProcessor = 'createScriptProcessor'] === 'function' || typeof AudioContext.prototype[createProcessor = 'createJavaScriptNode'] === 'function');

    sharedContext = null;

    function WebAudioDevice(sampleRate, channels1) {
      this.sampleRate = sampleRate;
      this.channels = channels1;
      this.refill = bind(this.refill, this);
      this.context = sharedContext != null ? sharedContext : sharedContext = new AudioContext;
      this.deviceSampleRate = this.context.sampleRate;
      this.bufferSize = Math.ceil(4096 / (this.deviceSampleRate / this.sampleRate) * this.channels);
      this.bufferSize += this.bufferSize % this.channels;
      if (this.deviceSampleRate !== this.sampleRate) {
        this.resampler = new Resampler(this.sampleRate, this.deviceSampleRate, this.channels, this.bufferSize);
      }
      this.node = this.context[createProcessor](4096, this.channels, this.channels);
      this.node.onaudioprocess = this.refill;
      this.node.connect(this.context.destination);
    }

    WebAudioDevice.prototype.refill = function(event) {
      var channelCount, channels, data, i, j, k, l, n, outputBuffer, ref, ref1, ref2;
      outputBuffer = event.outputBuffer;
      channelCount = outputBuffer.numberOfChannels;
      channels = new Array(channelCount);
      for (i = j = 0, ref = channelCount; j < ref; i = j += 1) {
        channels[i] = outputBuffer.getChannelData(i);
      }
      data = new Float32Array(this.bufferSize);
      this.emit('refill', data);
      if (this.resampler) {
        data = this.resampler.resampler(data);
      }
      for (i = k = 0, ref1 = outputBuffer.length; k < ref1; i = k += 1) {
        for (n = l = 0, ref2 = channelCount; l < ref2; n = l += 1) {
          channels[n][i] = data[i * channelCount + n];
        }
      }
    };

    WebAudioDevice.prototype.destroy = function() {
      return this.node.disconnect(0);
    };

    WebAudioDevice.prototype.getDeviceTime = function() {
      return this.context.currentTime * this.sampleRate;
    };

    return WebAudioDevice;

  })(EventEmitter);

}).call(this);

}).call(this)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})

},{"../core/events":8,"../device":20,"./resampler":22}],24:[function(require,module,exports){
// Generated by CoffeeScript 1.12.7
(function() {
  var Filter;

  Filter = (function() {
    function Filter(context, key) {
      if (context && key) {
        Object.defineProperty(this, 'value', {
          get: function() {
            return context[key];
          }
        });
      }
    }

    Filter.prototype.process = function(buffer) {};

    return Filter;

  })();

  module.exports = Filter;

}).call(this);

},{}],25:[function(require,module,exports){
// Generated by CoffeeScript 1.12.7
(function() {
  var BalanceFilter, Filter,
    extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
    hasProp = {}.hasOwnProperty;

  Filter = require('../filter');

  BalanceFilter = (function(superClass) {
    extend(BalanceFilter, superClass);

    function BalanceFilter() {
      return BalanceFilter.__super__.constructor.apply(this, arguments);
    }

    BalanceFilter.prototype.process = function(buffer) {
      var i, j, pan, ref;
      if (this.value === 0) {
        return;
      }
      pan = Math.max(-50, Math.min(50, this.value));
      for (i = j = 0, ref = buffer.length; j < ref; i = j += 2) {
        buffer[i] *= Math.min(1, (50 - pan) / 50);
        buffer[i + 1] *= Math.min(1, (50 + pan) / 50);
      }
    };

    return BalanceFilter;

  })(Filter);

  module.exports = BalanceFilter;

}).call(this);

},{"../filter":24}],26:[function(require,module,exports){
// Generated by CoffeeScript 1.12.7
(function() {
  var Filter, VolumeFilter,
    extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
    hasProp = {}.hasOwnProperty;

  Filter = require('../filter');

  VolumeFilter = (function(superClass) {
    extend(VolumeFilter, superClass);

    function VolumeFilter() {
      return VolumeFilter.__super__.constructor.apply(this, arguments);
    }

    VolumeFilter.prototype.process = function(buffer) {
      var i, j, ref, vol;
      if (this.value >= 100) {
        return;
      }
      vol = Math.max(0, Math.min(100, this.value)) / 100;
      for (i = j = 0, ref = buffer.length; j < ref; i = j += 1) {
        buffer[i] *= vol;
      }
    };

    return VolumeFilter;

  })(Filter);

  module.exports = VolumeFilter;

}).call(this);

},{"../filter":24}],27:[function(require,module,exports){
// Generated by CoffeeScript 1.12.7
(function() {
  var Asset, AudioDevice, BalanceFilter, EventEmitter, Player, Queue, VolumeFilter,
    bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
    extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
    hasProp = {}.hasOwnProperty;

  EventEmitter = require('./core/events');

  Asset = require('./asset');

  VolumeFilter = require('./filters/volume');

  BalanceFilter = require('./filters/balance');

  Queue = require('./queue');

  AudioDevice = require('./device');

  Player = (function(superClass) {
    extend(Player, superClass);

    function Player(asset) {
      this.asset = asset;
      this.startPlaying = bind(this.startPlaying, this);
      this.playing = false;
      this.buffered = 0;
      this.currentTime = 0;
      this.duration = 0;
      this.volume = 100;
      this.pan = 0;
      this.metadata = {};
      this.filters = [new VolumeFilter(this, 'volume'), new BalanceFilter(this, 'pan')];
      this.asset.on('buffer', (function(_this) {
        return function(buffered) {
          _this.buffered = buffered;
          return _this.emit('buffer', _this.buffered);
        };
      })(this));
      this.asset.on('decodeStart', (function(_this) {
        return function() {
          _this.queue = new Queue(_this.asset);
          return _this.queue.once('ready', _this.startPlaying);
        };
      })(this));
      this.asset.on('format', (function(_this) {
        return function(format) {
          _this.format = format;
          return _this.emit('format', _this.format);
        };
      })(this));
      this.asset.on('metadata', (function(_this) {
        return function(metadata) {
          _this.metadata = metadata;
          return _this.emit('metadata', _this.metadata);
        };
      })(this));
      this.asset.on('duration', (function(_this) {
        return function(duration) {
          _this.duration = duration;
          return _this.emit('duration', _this.duration);
        };
      })(this));
      this.asset.on('error', (function(_this) {
        return function(error) {
          return _this.emit('error', error);
        };
      })(this));
    }

    Player.fromURL = function(url, opts) {
      return new Player(Asset.fromURL(url, opts));
    };

    Player.fromFile = function(file) {
      return new Player(Asset.fromFile(file));
    };

    Player.fromBuffer = function(buffer) {
      return new Player(Asset.fromBuffer(buffer));
    };

    Player.prototype.preload = function() {
      if (!this.asset) {
        return;
      }
      this.startedPreloading = true;
      return this.asset.start(false);
    };

    Player.prototype.play = function() {
      var ref;
      if (this.playing) {
        return;
      }
      if (!this.startedPreloading) {
        this.preload();
      }
      this.playing = true;
      return (ref = this.device) != null ? ref.start() : void 0;
    };

    Player.prototype.pause = function() {
      var ref;
      if (!this.playing) {
        return;
      }
      this.playing = false;
      return (ref = this.device) != null ? ref.stop() : void 0;
    };

    Player.prototype.togglePlayback = function() {
      if (this.playing) {
        return this.pause();
      } else {
        return this.play();
      }
    };

    Player.prototype.stop = function() {
      var ref;
      this.pause();
      this.asset.stop();
      return (ref = this.device) != null ? ref.destroy() : void 0;
    };

    Player.prototype.seek = function(timestamp) {
      var ref;
      if ((ref = this.device) != null) {
        ref.stop();
      }
      this.queue.once('ready', (function(_this) {
        return function() {
          var ref1, ref2;
          if ((ref1 = _this.device) != null) {
            ref1.seek(_this.currentTime);
          }
          if (_this.playing) {
            return (ref2 = _this.device) != null ? ref2.start() : void 0;
          }
        };
      })(this));
      timestamp = (timestamp / 1000) * this.format.sampleRate;
      timestamp = this.asset.decoder.seek(timestamp);
      this.currentTime = timestamp / this.format.sampleRate * 1000 | 0;
      this.queue.reset();
      return this.currentTime;
    };

    Player.prototype.startPlaying = function() {
      var frame, frameOffset;
      frame = this.queue.read();
      frameOffset = 0;
      this.device = new AudioDevice(this.format.sampleRate, this.format.channelsPerFrame);
      this.device.on('timeUpdate', (function(_this) {
        return function(currentTime) {
          _this.currentTime = currentTime;
          return _this.emit('progress', _this.currentTime);
        };
      })(this));
      this.refill = (function(_this) {
        return function(buffer) {
          var bufferOffset, filter, i, j, k, len, max, ref, ref1;
          if (!_this.playing) {
            return;
          }
          if (!frame) {
            frame = _this.queue.read();
            frameOffset = 0;
          }
          bufferOffset = 0;
          while (frame && bufferOffset < buffer.length) {
            max = Math.min(frame.length - frameOffset, buffer.length - bufferOffset);
            for (i = j = 0, ref = max; j < ref; i = j += 1) {
              buffer[bufferOffset++] = frame[frameOffset++];
            }
            if (frameOffset === frame.length) {
              frame = _this.queue.read();
              frameOffset = 0;
            }
          }
          ref1 = _this.filters;
          for (k = 0, len = ref1.length; k < len; k++) {
            filter = ref1[k];
            filter.process(buffer);
          }
          if (!frame) {
            if (_this.queue.ended) {
              _this.currentTime = _this.duration;
              _this.emit('progress', _this.currentTime);
              _this.emit('end');
              _this.stop();
            } else {
              _this.device.stop();
            }
          }
        };
      })(this);
      this.device.on('refill', this.refill);
      if (this.playing) {
        this.device.start();
      }
      return this.emit('ready');
    };

    Player.prototype.destroy = function() {
      var ref, ref1;
      this.stop();
      if ((ref = this.device) != null) {
        ref.off();
      }
      if ((ref1 = this.asset) != null) {
        ref1.destroy();
      }
      return this.off();
    };

    return Player;

  })(EventEmitter);

  module.exports = Player;

}).call(this);

},{"./asset":1,"./core/events":8,"./device":20,"./filters/balance":25,"./filters/volume":26,"./queue":28}],28:[function(require,module,exports){
// Generated by CoffeeScript 1.12.7
(function() {
  var EventEmitter, Queue,
    bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
    extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
    hasProp = {}.hasOwnProperty;

  EventEmitter = require('./core/events');

  Queue = (function(superClass) {
    extend(Queue, superClass);

    function Queue(asset) {
      this.asset = asset;
      this.write = bind(this.write, this);
      this.readyMark = 64;
      this.finished = false;
      this.buffering = true;
      this.ended = false;
      this.buffers = [];
      this.asset.on('data', this.write);
      this.asset.on('end', (function(_this) {
        return function() {
          return _this.ended = true;
        };
      })(this));
      this.asset.decodePacket();
    }

    Queue.prototype.write = function(buffer) {
      if (buffer) {
        this.buffers.push(buffer);
      }
      if (this.buffering) {
        if (this.buffers.length >= this.readyMark || this.ended) {
          this.buffering = false;
          return this.emit('ready');
        } else {
          return this.asset.decodePacket();
        }
      }
    };

    Queue.prototype.read = function() {
      if (this.buffers.length === 0) {
        return null;
      }
      this.asset.decodePacket();
      return this.buffers.shift();
    };

    Queue.prototype.reset = function() {
      this.buffers.length = 0;
      this.buffering = true;
      return this.asset.decodePacket();
    };

    return Queue;

  })(EventEmitter);

  module.exports = Queue;

}).call(this);

},{"./core/events":8}],29:[function(require,module,exports){
var AVBuffer, EventEmitter, FileSource,
  __hasProp = {}.hasOwnProperty,
  __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };

EventEmitter = require('../../core/events');

AVBuffer = require('../../core/buffer');

FileSource = (function(_super) {
  __extends(FileSource, _super);

  function FileSource(file) {
    this.file = file;
    if (typeof FileReader === "undefined" || FileReader === null) {
      return this.emit('error', 'This browser does not have FileReader support.');
    }
    this.offset = 0;
    this.length = this.file.size;
    this.chunkSize = 1 << 20;
    this.file[this.slice = 'slice'] || this.file[this.slice = 'webkitSlice'] || this.file[this.slice = 'mozSlice'];
  }

  FileSource.prototype.start = function() {
    if (this.reader) {
      if (!this.active) {
        return this.loop();
      }
    }
    this.reader = new FileReader;
    this.active = true;
    this.reader.onload = (function(_this) {
      return function(e) {
        var buf;
        buf = new AVBuffer(new Uint8Array(e.target.result));
        _this.offset += buf.length;
        _this.emit('data', buf);
        _this.active = false;
        if (_this.offset < _this.length) {
          return _this.loop();
        }
      };
    })(this);
    this.reader.onloadend = (function(_this) {
      return function() {
        if (_this.offset === _this.length) {
          _this.emit('end');
          return _this.reader = null;
        }
      };
    })(this);
    this.reader.onerror = (function(_this) {
      return function(e) {
        return _this.emit('error', e);
      };
    })(this);
    this.reader.onprogress = (function(_this) {
      return function(e) {
        return _this.emit('progress', (_this.offset + e.loaded) / _this.length * 100);
      };
    })(this);
    return this.loop();
  };

  FileSource.prototype.loop = function() {
    var blob, endPos;
    this.active = true;
    endPos = Math.min(this.offset + this.chunkSize, this.length);
    blob = this.file[this.slice](this.offset, endPos);
    return this.reader.readAsArrayBuffer(blob);
  };

  FileSource.prototype.pause = function() {
    var _ref;
    this.active = false;
    try {
      return (_ref = this.reader) != null ? _ref.abort() : void 0;
    } catch (_error) {}
  };

  FileSource.prototype.reset = function() {
    this.pause();
    return this.offset = 0;
  };

  return FileSource;

})(EventEmitter);

module.exports = FileSource;

},{"../../core/buffer":6,"../../core/events":8}],30:[function(require,module,exports){
var AVBuffer, EventEmitter, HTTPSource,
  __hasProp = {}.hasOwnProperty,
  __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };

EventEmitter = require('../../core/events');

AVBuffer = require('../../core/buffer');

HTTPSource = (function(_super) {
  __extends(HTTPSource, _super);

  function HTTPSource(url, opts) {
    this.url = url;
    this.opts = opts != null ? opts : {};
    this.chunkSize = 1 << 20;
    this.inflight = false;
    if (this.opts.length) {
      this.length = this.opts.length;
    }
    this.reset();
  }

  HTTPSource.prototype.start = function() {
    if (this.length) {
      if (!this.inflight) {
        return this.loop();
      }
    }
    this.inflight = true;
    this.xhr = new XMLHttpRequest();
    this.xhr.onload = (function(_this) {
      return function(event) {
        _this.length = parseInt(_this.xhr.getResponseHeader("Content-Length"));
        _this.inflight = false;
        return _this.loop();
      };
    })(this);
    this.xhr.onerror = (function(_this) {
      return function(err) {
        _this.pause();
        return _this.emit('error', err);
      };
    })(this);
    this.xhr.onabort = (function(_this) {
      return function(event) {
        return _this.inflight = false;
      };
    })(this);
    this.xhr.open("HEAD", this.url, true);
    return this.xhr.send(null);
  };

  HTTPSource.prototype.loop = function() {
    var endPos;
    if (this.inflight || !this.length) {
      return this.emit('error', 'Something is wrong in HTTPSource.loop');
    }
    this.inflight = true;
    this.xhr = new XMLHttpRequest();
    this.xhr.onload = (function(_this) {
      return function(event) {
        var buf, buffer, i, txt, _i, _ref;
        if (_this.xhr.response) {
          buf = new Uint8Array(_this.xhr.response);
        } else {
          txt = _this.xhr.responseText;
          buf = new Uint8Array(txt.length);
          for (i = _i = 0, _ref = txt.length; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) {
            buf[i] = txt.charCodeAt(i) & 0xff;
          }
        }
        buffer = new AVBuffer(buf);
        _this.offset += buffer.length;
        _this.emit('data', buffer);
        if (_this.offset >= _this.length) {
          _this.emit('end');
        }
        _this.inflight = false;
        if (!(_this.offset >= _this.length)) {
          return _this.loop();
        }
      };
    })(this);
    this.xhr.onprogress = (function(_this) {
      return function(event) {
        return _this.emit('progress', (_this.offset + event.loaded) / _this.length * 100);
      };
    })(this);
    this.xhr.onerror = (function(_this) {
      return function(err) {
        _this.emit('error', err);
        return _this.pause();
      };
    })(this);
    this.xhr.onabort = (function(_this) {
      return function(event) {
        return _this.inflight = false;
      };
    })(this);
    this.xhr.open("GET", this.url, true);
    this.xhr.responseType = "arraybuffer";
    endPos = Math.min(this.offset + this.chunkSize, this.length - 1);
    this.xhr.setRequestHeader("If-None-Match", "webkit-no-cache");
    this.xhr.setRequestHeader("Range", "bytes=" + this.offset + "-" + endPos);
    this.xhr.overrideMimeType('text/plain; charset=x-user-defined');
    return this.xhr.send(null);
  };

  HTTPSource.prototype.pause = function() {
    var _ref;
    this.inflight = false;
    return (_ref = this.xhr) != null ? _ref.abort() : void 0;
  };

  HTTPSource.prototype.reset = function() {
    this.pause();
    return this.offset = 0;
  };

  return HTTPSource;

})(EventEmitter);

module.exports = HTTPSource;

},{"../../core/buffer":6,"../../core/events":8}],31:[function(require,module,exports){
(function (global){(function (){
// Generated by CoffeeScript 1.12.7
(function() {
  var AVBuffer, BufferList, BufferSource, EventEmitter,
    bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
    extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
    hasProp = {}.hasOwnProperty;

  EventEmitter = require('../core/events');

  BufferList = require('../core/bufferlist');

  AVBuffer = require('../core/buffer');

  BufferSource = (function(superClass) {
    var clearImmediate, setImmediate;

    extend(BufferSource, superClass);

    function BufferSource(input) {
      this.loop = bind(this.loop, this);
      if (input instanceof BufferList) {
        this.list = input;
      } else {
        this.list = new BufferList;
        this.list.append(new AVBuffer(input));
      }
      this.paused = true;
    }

    setImmediate = global.setImmediate || function(fn) {
      return global.setTimeout(fn, 0);
    };

    clearImmediate = global.clearImmediate || function(timer) {
      return global.clearTimeout(timer);
    };

    BufferSource.prototype.start = function() {
      this.paused = false;
      return this._timer = setImmediate(this.loop);
    };

    BufferSource.prototype.loop = function() {
      this.emit('progress', (this.list.numBuffers - this.list.availableBuffers + 1) / this.list.numBuffers * 100 | 0);
      this.emit('data', this.list.first);
      if (this.list.advance()) {
        return setImmediate(this.loop);
      } else {
        return this.emit('end');
      }
    };

    BufferSource.prototype.pause = function() {
      clearImmediate(this._timer);
      return this.paused = true;
    };

    BufferSource.prototype.reset = function() {
      this.pause();
      return this.list.rewind();
    };

    return BufferSource;

  })(EventEmitter);

  module.exports = BufferSource;

}).call(this);

}).call(this)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})

},{"../core/buffer":6,"../core/bufferlist":7,"../core/events":8}],32:[function(require,module,exports){
var key, val, _ref;

_ref = require('./src/aurora');
for (key in _ref) {
  val = _ref[key];
  exports[key] = val;
}

require('./src/devices/webaudio');

require('./src/devices/mozilla');

},{"./src/aurora":2,"./src/devices/mozilla":21,"./src/devices/webaudio":23}]},{},[32])(32)
});

//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCJzcmMvYXNzZXQuanMiLCJzcmMvYXVyb3JhLmpzIiwic3JjL2F1cm9yYV9iYXNlLmpzIiwic3JjL2NvcmUvYmFzZS5qcyIsInNyYy9jb3JlL2JpdHN0cmVhbS5qcyIsInNyYy9jb3JlL2J1ZmZlci5qcyIsInNyYy9jb3JlL2J1ZmZlcmxpc3QuanMiLCJzcmMvY29yZS9ldmVudHMuanMiLCJzcmMvY29yZS9zdHJlYW0uanMiLCJzcmMvY29yZS91bmRlcmZsb3cuanMiLCJzcmMvZGVjb2Rlci5qcyIsInNyYy9kZWNvZGVycy9scGNtLmpzIiwic3JjL2RlY29kZXJzL3hsYXcuanMiLCJzcmMvZGVtdXhlci5qcyIsInNyYy9kZW11eGVycy9haWZmLmpzIiwic3JjL2RlbXV4ZXJzL2F1LmpzIiwic3JjL2RlbXV4ZXJzL2NhZi5qcyIsInNyYy9kZW11eGVycy9tNGEuanMiLCJzcmMvZGVtdXhlcnMvd2F2ZS5qcyIsInNyYy9kZXZpY2UuanMiLCJzcmMvZGV2aWNlcy9tb3ppbGxhLmpzIiwic3JjL2RldmljZXMvcmVzYW1wbGVyLmpzIiwic3JjL2RldmljZXMvd2ViYXVkaW8uanMiLCJzcmMvZmlsdGVyLmpzIiwic3JjL2ZpbHRlcnMvYmFsYW5jZS5qcyIsInNyYy9maWx0ZXJzL3ZvbHVtZS5qcyIsInNyYy9wbGF5ZXIuanMiLCJzcmMvcXVldWUuanMiLCIvaG9tZS91c2VyL2F1cm9yYS5qcy0wLjQuOS9zcmMvc291cmNlcy9icm93c2VyL2ZpbGUuY29mZmVlIiwiL2hvbWUvdXNlci9hdXJvcmEuanMtMC40Ljkvc3JjL3NvdXJjZXMvYnJvd3Nlci9odHRwLmNvZmZlZSIsInNyYy9zb3VyY2VzL2J1ZmZlci5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTtBQ0FBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDalBBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDekJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUNuT0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDekZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzlFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDMUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbGdCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3RCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3RIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbkZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzlFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeklBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25HQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDL0lBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4bkJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbEdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1RkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQzVKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQzNFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoT0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoRUEsSUFBQSxrQ0FBQTtFQUFBO2lTQUFBOztBQUFBLFlBQUEsR0FBZSxPQUFBLENBQVEsbUJBQVIsQ0FBZixDQUFBOztBQUFBLFFBQ0EsR0FBVyxPQUFBLENBQVEsbUJBQVIsQ0FEWCxDQUFBOztBQUFBO0FBSUksK0JBQUEsQ0FBQTs7QUFBYSxFQUFBLG9CQUFFLElBQUYsR0FBQTtBQUNULElBRFUsSUFBQyxDQUFBLE9BQUEsSUFDWCxDQUFBO0FBQUEsSUFBQSxJQUFPLHdEQUFQO0FBQ0ksYUFBTyxJQUFDLENBQUEsSUFBRCxDQUFNLE9BQU4sRUFBZSxnREFBZixDQUFQLENBREo7S0FBQTtBQUFBLElBR0EsSUFBQyxDQUFBLE1BQUQsR0FBVSxDQUhWLENBQUE7QUFBQSxJQUlBLElBQUMsQ0FBQSxNQUFELEdBQVUsSUFBQyxDQUFBLElBQUksQ0FBQyxJQUpoQixDQUFBO0FBQUEsSUFLQSxJQUFDLENBQUEsU0FBRCxHQUFhLENBQUEsSUFBSyxFQUxsQixDQUFBO0FBQUEsSUFNQSxJQUFDLENBQUEsSUFBSyxDQUFBLElBQUMsQ0FBQSxLQUFELEdBQVMsT0FBVCxDQUFOLElBQTJCLElBQUMsQ0FBQSxJQUFLLENBQUEsSUFBQyxDQUFBLEtBQUQsR0FBUyxhQUFULENBQWpDLElBQTRELElBQUMsQ0FBQSxJQUFLLENBQUEsSUFBQyxDQUFBLEtBQUQsR0FBUyxVQUFULENBTmxFLENBRFM7RUFBQSxDQUFiOztBQUFBLHVCQVNBLEtBQUEsR0FBTyxTQUFBLEdBQUE7QUFDSCxJQUFBLElBQUcsSUFBQyxDQUFBLE1BQUo7QUFDSSxNQUFBLElBQUEsQ0FBQSxJQUF1QixDQUFBLE1BQXZCO0FBQUEsZUFBTyxJQUFDLENBQUEsSUFBRCxDQUFBLENBQVAsQ0FBQTtPQURKO0tBQUE7QUFBQSxJQUdBLElBQUMsQ0FBQSxNQUFELEdBQVUsR0FBQSxDQUFBLFVBSFYsQ0FBQTtBQUFBLElBSUEsSUFBQyxDQUFBLE1BQUQsR0FBVSxJQUpWLENBQUE7QUFBQSxJQU1BLElBQUMsQ0FBQSxNQUFNLENBQUMsTUFBUixHQUFpQixDQUFBLFNBQUEsS0FBQSxHQUFBO2FBQUEsU0FBQyxDQUFELEdBQUE7QUFDYixZQUFBLEdBQUE7QUFBQSxRQUFBLEdBQUEsR0FBVSxJQUFBLFFBQUEsQ0FBYSxJQUFBLFVBQUEsQ0FBVyxDQUFDLENBQUMsTUFBTSxDQUFDLE1BQXBCLENBQWIsQ0FBVixDQUFBO0FBQUEsUUFDQSxLQUFDLENBQUEsTUFBRCxJQUFXLEdBQUcsQ0FBQyxNQURmLENBQUE7QUFBQSxRQUdBLEtBQUMsQ0FBQSxJQUFELENBQU0sTUFBTixFQUFjLEdBQWQsQ0FIQSxDQUFBO0FBQUEsUUFJQSxLQUFDLENBQUEsTUFBRCxHQUFVLEtBSlYsQ0FBQTtBQUtBLFFBQUEsSUFBVyxLQUFDLENBQUEsTUFBRCxHQUFVLEtBQUMsQ0FBQSxNQUF0QjtpQkFBQSxLQUFDLENBQUEsSUFBRCxDQUFBLEVBQUE7U0FOYTtNQUFBLEVBQUE7SUFBQSxDQUFBLENBQUEsQ0FBQSxJQUFBLENBTmpCLENBQUE7QUFBQSxJQWNBLElBQUMsQ0FBQSxNQUFNLENBQUMsU0FBUixHQUFvQixDQUFBLFNBQUEsS0FBQSxHQUFBO2FBQUEsU0FBQSxHQUFBO0FBQ2hCLFFBQUEsSUFBRyxLQUFDLENBQUEsTUFBRCxLQUFXLEtBQUMsQ0FBQSxNQUFmO0FBQ0ksVUFBQSxLQUFDLENBQUEsSUFBRCxDQUFNLEtBQU4sQ0FBQSxDQUFBO2lCQUNBLEtBQUMsQ0FBQSxNQUFELEdBQVUsS0FGZDtTQURnQjtNQUFBLEVBQUE7SUFBQSxDQUFBLENBQUEsQ0FBQSxJQUFBLENBZHBCLENBQUE7QUFBQSxJQW1CQSxJQUFDLENBQUEsTUFBTSxDQUFDLE9BQVIsR0FBa0IsQ0FBQSxTQUFBLEtBQUEsR0FBQTthQUFBLFNBQUMsQ0FBRCxHQUFBO2VBQ2QsS0FBQyxDQUFBLElBQUQsQ0FBTSxPQUFOLEVBQWUsQ0FBZixFQURjO01BQUEsRUFBQTtJQUFBLENBQUEsQ0FBQSxDQUFBLElBQUEsQ0FuQmxCLENBQUE7QUFBQSxJQXNCQSxJQUFDLENBQUEsTUFBTSxDQUFDLFVBQVIsR0FBcUIsQ0FBQSxTQUFBLEtBQUEsR0FBQTthQUFBLFNBQUMsQ0FBRCxHQUFBO2VBQ2pCLEtBQUMsQ0FBQSxJQUFELENBQU0sVUFBTixFQUFrQixDQUFDLEtBQUMsQ0FBQSxNQUFELEdBQVUsQ0FBQyxDQUFDLE1BQWIsQ0FBQSxHQUF1QixLQUFDLENBQUEsTUFBeEIsR0FBaUMsR0FBbkQsRUFEaUI7TUFBQSxFQUFBO0lBQUEsQ0FBQSxDQUFBLENBQUEsSUFBQSxDQXRCckIsQ0FBQTtXQXlCQSxJQUFDLENBQUEsSUFBRCxDQUFBLEVBMUJHO0VBQUEsQ0FUUCxDQUFBOztBQUFBLHVCQXFDQSxJQUFBLEdBQU0sU0FBQSxHQUFBO0FBQ0YsUUFBQSxZQUFBO0FBQUEsSUFBQSxJQUFDLENBQUEsTUFBRCxHQUFVLElBQVYsQ0FBQTtBQUFBLElBQ0EsTUFBQSxHQUFTLElBQUksQ0FBQyxHQUFMLENBQVMsSUFBQyxDQUFBLE1BQUQsR0FBVSxJQUFDLENBQUEsU0FBcEIsRUFBK0IsSUFBQyxDQUFBLE1BQWhDLENBRFQsQ0FBQTtBQUFBLElBR0EsSUFBQSxHQUFPLElBQUMsQ0FBQSxJQUFLLENBQUEsSUFBQyxDQUFBLEtBQUQsQ0FBTixDQUFjLElBQUMsQ0FBQSxNQUFmLEVBQXVCLE1BQXZCLENBSFAsQ0FBQTtXQUlBLElBQUMsQ0FBQSxNQUFNLENBQUMsaUJBQVIsQ0FBMEIsSUFBMUIsRUFMRTtFQUFBLENBckNOLENBQUE7O0FBQUEsdUJBNENBLEtBQUEsR0FBTyxTQUFBLEdBQUE7QUFDSCxRQUFBLElBQUE7QUFBQSxJQUFBLElBQUMsQ0FBQSxNQUFELEdBQVUsS0FBVixDQUFBO0FBQ0E7Z0RBQ1MsQ0FBRSxLQUFULENBQUEsV0FERjtLQUFBLGtCQUZHO0VBQUEsQ0E1Q1AsQ0FBQTs7QUFBQSx1QkFpREEsS0FBQSxHQUFPLFNBQUEsR0FBQTtBQUNILElBQUEsSUFBQyxDQUFBLEtBQUQsQ0FBQSxDQUFBLENBQUE7V0FDQSxJQUFDLENBQUEsTUFBRCxHQUFVLEVBRlA7RUFBQSxDQWpEUCxDQUFBOztvQkFBQTs7R0FEcUIsYUFIekIsQ0FBQTs7QUFBQSxNQXlETSxDQUFDLE9BQVAsR0FBaUIsVUF6RGpCLENBQUE7OztBQ0FBLElBQUEsa0NBQUE7RUFBQTtpU0FBQTs7QUFBQSxZQUFBLEdBQWUsT0FBQSxDQUFRLG1CQUFSLENBQWYsQ0FBQTs7QUFBQSxRQUNBLEdBQVcsT0FBQSxDQUFRLG1CQUFSLENBRFgsQ0FBQTs7QUFBQTtBQUlJLCtCQUFBLENBQUE7O0FBQWEsRUFBQSxvQkFBRSxHQUFGLEVBQVEsSUFBUixHQUFBO0FBQ1QsSUFEVSxJQUFDLENBQUEsTUFBQSxHQUNYLENBQUE7QUFBQSxJQURnQixJQUFDLENBQUEsc0JBQUEsT0FBTyxFQUN4QixDQUFBO0FBQUEsSUFBQSxJQUFDLENBQUEsU0FBRCxHQUFhLENBQUEsSUFBSyxFQUFsQixDQUFBO0FBQUEsSUFDQSxJQUFDLENBQUEsUUFBRCxHQUFZLEtBRFosQ0FBQTtBQUVBLElBQUEsSUFBRyxJQUFDLENBQUEsSUFBSSxDQUFDLE1BQVQ7QUFDSSxNQUFBLElBQUMsQ0FBQSxNQUFELEdBQVUsSUFBQyxDQUFBLElBQUksQ0FBQyxNQUFoQixDQURKO0tBRkE7QUFBQSxJQUlBLElBQUMsQ0FBQSxLQUFELENBQUEsQ0FKQSxDQURTO0VBQUEsQ0FBYjs7QUFBQSx1QkFPQSxLQUFBLEdBQU8sU0FBQSxHQUFBO0FBQ0gsSUFBQSxJQUFHLElBQUMsQ0FBQSxNQUFKO0FBQ0ksTUFBQSxJQUFBLENBQUEsSUFBdUIsQ0FBQSxRQUF2QjtBQUFBLGVBQU8sSUFBQyxDQUFBLElBQUQsQ0FBQSxDQUFQLENBQUE7T0FESjtLQUFBO0FBQUEsSUFHQSxJQUFDLENBQUEsUUFBRCxHQUFZLElBSFosQ0FBQTtBQUFBLElBSUEsSUFBQyxDQUFBLEdBQUQsR0FBVyxJQUFBLGNBQUEsQ0FBQSxDQUpYLENBQUE7QUFBQSxJQU1BLElBQUMsQ0FBQSxHQUFHLENBQUMsTUFBTCxHQUFjLENBQUEsU0FBQSxLQUFBLEdBQUE7YUFBQSxTQUFDLEtBQUQsR0FBQTtBQUNWLFFBQUEsS0FBQyxDQUFBLE1BQUQsR0FBVSxRQUFBLENBQVMsS0FBQyxDQUFBLEdBQUcsQ0FBQyxpQkFBTCxDQUF1QixnQkFBdkIsQ0FBVCxDQUFWLENBQUE7QUFBQSxRQUNBLEtBQUMsQ0FBQSxRQUFELEdBQVksS0FEWixDQUFBO2VBRUEsS0FBQyxDQUFBLElBQUQsQ0FBQSxFQUhVO01BQUEsRUFBQTtJQUFBLENBQUEsQ0FBQSxDQUFBLElBQUEsQ0FOZCxDQUFBO0FBQUEsSUFXQSxJQUFDLENBQUEsR0FBRyxDQUFDLE9BQUwsR0FBZSxDQUFBLFNBQUEsS0FBQSxHQUFBO2FBQUEsU0FBQyxHQUFELEdBQUE7QUFDWCxRQUFBLEtBQUMsQ0FBQSxLQUFELENBQUEsQ0FBQSxDQUFBO2VBQ0EsS0FBQyxDQUFBLElBQUQsQ0FBTSxPQUFOLEVBQWUsR0FBZixFQUZXO01BQUEsRUFBQTtJQUFBLENBQUEsQ0FBQSxDQUFBLElBQUEsQ0FYZixDQUFBO0FBQUEsSUFlQSxJQUFDLENBQUEsR0FBRyxDQUFDLE9BQUwsR0FBZSxDQUFBLFNBQUEsS0FBQSxHQUFBO2FBQUEsU0FBQyxLQUFELEdBQUE7ZUFDWCxLQUFDLENBQUEsUUFBRCxHQUFZLE1BREQ7TUFBQSxFQUFBO0lBQUEsQ0FBQSxDQUFBLENBQUEsSUFBQSxDQWZmLENBQUE7QUFBQSxJQWtCQSxJQUFDLENBQUEsR0FBRyxDQUFDLElBQUwsQ0FBVSxNQUFWLEVBQWtCLElBQUMsQ0FBQSxHQUFuQixFQUF3QixJQUF4QixDQWxCQSxDQUFBO1dBbUJBLElBQUMsQ0FBQSxHQUFHLENBQUMsSUFBTCxDQUFVLElBQVYsRUFwQkc7RUFBQSxDQVBQLENBQUE7O0FBQUEsdUJBNkJBLElBQUEsR0FBTSxTQUFBLEdBQUE7QUFDRixRQUFBLE1BQUE7QUFBQSxJQUFBLElBQUcsSUFBQyxDQUFBLFFBQUQsSUFBYSxDQUFBLElBQUssQ0FBQSxNQUFyQjtBQUNJLGFBQU8sSUFBQyxDQUFBLElBQUQsQ0FBTSxPQUFOLEVBQWUsdUNBQWYsQ0FBUCxDQURKO0tBQUE7QUFBQSxJQUdBLElBQUMsQ0FBQSxRQUFELEdBQVksSUFIWixDQUFBO0FBQUEsSUFJQSxJQUFDLENBQUEsR0FBRCxHQUFXLElBQUEsY0FBQSxDQUFBLENBSlgsQ0FBQTtBQUFBLElBTUEsSUFBQyxDQUFBLEdBQUcsQ0FBQyxNQUFMLEdBQWMsQ0FBQSxTQUFBLEtBQUEsR0FBQTthQUFBLFNBQUMsS0FBRCxHQUFBO0FBQ1YsWUFBQSw2QkFBQTtBQUFBLFFBQUEsSUFBRyxLQUFDLENBQUEsR0FBRyxDQUFDLFFBQVI7QUFDSSxVQUFBLEdBQUEsR0FBVSxJQUFBLFVBQUEsQ0FBVyxLQUFDLENBQUEsR0FBRyxDQUFDLFFBQWhCLENBQVYsQ0FESjtTQUFBLE1BQUE7QUFHSSxVQUFBLEdBQUEsR0FBTSxLQUFDLENBQUEsR0FBRyxDQUFDLFlBQVgsQ0FBQTtBQUFBLFVBQ0EsR0FBQSxHQUFVLElBQUEsVUFBQSxDQUFXLEdBQUcsQ0FBQyxNQUFmLENBRFYsQ0FBQTtBQUVBLGVBQVMsNkZBQVQsR0FBQTtBQUNJLFlBQUEsR0FBSSxDQUFBLENBQUEsQ0FBSixHQUFTLEdBQUcsQ0FBQyxVQUFKLENBQWUsQ0FBZixDQUFBLEdBQW9CLElBQTdCLENBREo7QUFBQSxXQUxKO1NBQUE7QUFBQSxRQVFBLE1BQUEsR0FBYSxJQUFBLFFBQUEsQ0FBUyxHQUFULENBUmIsQ0FBQTtBQUFBLFFBU0EsS0FBQyxDQUFBLE1BQUQsSUFBVyxNQUFNLENBQUMsTUFUbEIsQ0FBQTtBQUFBLFFBV0EsS0FBQyxDQUFBLElBQUQsQ0FBTSxNQUFOLEVBQWMsTUFBZCxDQVhBLENBQUE7QUFZQSxRQUFBLElBQWUsS0FBQyxDQUFBLE1BQUQsSUFBVyxLQUFDLENBQUEsTUFBM0I7QUFBQSxVQUFBLEtBQUMsQ0FBQSxJQUFELENBQU0sS0FBTixDQUFBLENBQUE7U0FaQTtBQUFBLFFBY0EsS0FBQyxDQUFBLFFBQUQsR0FBWSxLQWRaLENBQUE7QUFlQSxRQUFBLElBQUEsQ0FBQSxDQUFlLEtBQUMsQ0FBQSxNQUFELElBQVcsS0FBQyxDQUFBLE1BQTNCLENBQUE7aUJBQUEsS0FBQyxDQUFBLElBQUQsQ0FBQSxFQUFBO1NBaEJVO01BQUEsRUFBQTtJQUFBLENBQUEsQ0FBQSxDQUFBLElBQUEsQ0FOZCxDQUFBO0FBQUEsSUF3QkEsSUFBQyxDQUFBLEdBQUcsQ0FBQyxVQUFMLEdBQWtCLENBQUEsU0FBQSxLQUFBLEdBQUE7YUFBQSxTQUFDLEtBQUQsR0FBQTtlQUNkLEtBQUMsQ0FBQSxJQUFELENBQU0sVUFBTixFQUFrQixDQUFDLEtBQUMsQ0FBQSxNQUFELEdBQVUsS0FBSyxDQUFDLE1BQWpCLENBQUEsR0FBMkIsS0FBQyxDQUFBLE1BQTVCLEdBQXFDLEdBQXZELEVBRGM7TUFBQSxFQUFBO0lBQUEsQ0FBQSxDQUFBLENBQUEsSUFBQSxDQXhCbEIsQ0FBQTtBQUFBLElBMkJBLElBQUMsQ0FBQSxHQUFHLENBQUMsT0FBTCxHQUFlLENBQUEsU0FBQSxLQUFBLEdBQUE7YUFBQSxTQUFDLEdBQUQsR0FBQTtBQUNYLFFBQUEsS0FBQyxDQUFBLElBQUQsQ0FBTSxPQUFOLEVBQWUsR0FBZixDQUFBLENBQUE7ZUFDQSxLQUFDLENBQUEsS0FBRCxDQUFBLEVBRlc7TUFBQSxFQUFBO0lBQUEsQ0FBQSxDQUFBLENBQUEsSUFBQSxDQTNCZixDQUFBO0FBQUEsSUErQkEsSUFBQyxDQUFBLEdBQUcsQ0FBQyxPQUFMLEdBQWUsQ0FBQSxTQUFBLEtBQUEsR0FBQTthQUFBLFNBQUMsS0FBRCxHQUFBO2VBQ1gsS0FBQyxDQUFBLFFBQUQsR0FBWSxNQUREO01BQUEsRUFBQTtJQUFBLENBQUEsQ0FBQSxDQUFBLElBQUEsQ0EvQmYsQ0FBQTtBQUFBLElBa0NBLElBQUMsQ0FBQSxHQUFHLENBQUMsSUFBTCxDQUFVLEtBQVYsRUFBaUIsSUFBQyxDQUFBLEdBQWxCLEVBQXVCLElBQXZCLENBbENBLENBQUE7QUFBQSxJQW1DQSxJQUFDLENBQUEsR0FBRyxDQUFDLFlBQUwsR0FBb0IsYUFuQ3BCLENBQUE7QUFBQSxJQXFDQSxNQUFBLEdBQVMsSUFBSSxDQUFDLEdBQUwsQ0FBUyxJQUFDLENBQUEsTUFBRCxHQUFVLElBQUMsQ0FBQSxTQUFwQixFQUErQixJQUFDLENBQUEsTUFBRCxHQUFVLENBQXpDLENBckNULENBQUE7QUFBQSxJQXNDQSxJQUFDLENBQUEsR0FBRyxDQUFDLGdCQUFMLENBQXNCLGVBQXRCLEVBQXVDLGlCQUF2QyxDQXRDQSxDQUFBO0FBQUEsSUF1Q0EsSUFBQyxDQUFBLEdBQUcsQ0FBQyxnQkFBTCxDQUFzQixPQUF0QixFQUFnQyxRQUFBLEdBQU8sSUFBQyxDQUFBLE1BQVIsR0FBZ0IsR0FBaEIsR0FBa0IsTUFBbEQsQ0F2Q0EsQ0FBQTtBQUFBLElBd0NBLElBQUMsQ0FBQSxHQUFHLENBQUMsZ0JBQUwsQ0FBc0Isb0NBQXRCLENBeENBLENBQUE7V0F5Q0EsSUFBQyxDQUFBLEdBQUcsQ0FBQyxJQUFMLENBQVUsSUFBVixFQTFDRTtFQUFBLENBN0JOLENBQUE7O0FBQUEsdUJBeUVBLEtBQUEsR0FBTyxTQUFBLEdBQUE7QUFDSCxRQUFBLElBQUE7QUFBQSxJQUFBLElBQUMsQ0FBQSxRQUFELEdBQVksS0FBWixDQUFBOzJDQUNJLENBQUUsS0FBTixDQUFBLFdBRkc7RUFBQSxDQXpFUCxDQUFBOztBQUFBLHVCQTZFQSxLQUFBLEdBQU8sU0FBQSxHQUFBO0FBQ0gsSUFBQSxJQUFDLENBQUEsS0FBRCxDQUFBLENBQUEsQ0FBQTtXQUNBLElBQUMsQ0FBQSxNQUFELEdBQVUsRUFGUDtFQUFBLENBN0VQLENBQUE7O29CQUFBOztHQURxQixhQUh6QixDQUFBOztBQUFBLE1BcUZNLENBQUMsT0FBUCxHQUFpQixVQXJGakIsQ0FBQTs7OztBQ0FBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwiZmlsZSI6ImdlbmVyYXRlZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzQ29udGVudCI6WyIoZnVuY3Rpb24oKXtmdW5jdGlvbiByKGUsbix0KXtmdW5jdGlvbiBvKGksZil7aWYoIW5baV0pe2lmKCFlW2ldKXt2YXIgYz1cImZ1bmN0aW9uXCI9PXR5cGVvZiByZXF1aXJlJiZyZXF1aXJlO2lmKCFmJiZjKXJldHVybiBjKGksITApO2lmKHUpcmV0dXJuIHUoaSwhMCk7dmFyIGE9bmV3IEVycm9yKFwiQ2Fubm90IGZpbmQgbW9kdWxlICdcIitpK1wiJ1wiKTt0aHJvdyBhLmNvZGU9XCJNT0RVTEVfTk9UX0ZPVU5EXCIsYX12YXIgcD1uW2ldPXtleHBvcnRzOnt9fTtlW2ldWzBdLmNhbGwocC5leHBvcnRzLGZ1bmN0aW9uKHIpe3ZhciBuPWVbaV1bMV1bcl07cmV0dXJuIG8obnx8cil9LHAscC5leHBvcnRzLHIsZSxuLHQpfXJldHVybiBuW2ldLmV4cG9ydHN9Zm9yKHZhciB1PVwiZnVuY3Rpb25cIj09dHlwZW9mIHJlcXVpcmUmJnJlcXVpcmUsaT0wO2k8dC5sZW5ndGg7aSsrKW8odFtpXSk7cmV0dXJuIG99cmV0dXJuIHJ9KSgpIiwiLy8gR2VuZXJhdGVkIGJ5IENvZmZlZVNjcmlwdCAxLjEyLjdcbihmdW5jdGlvbigpIHtcbiAgdmFyIEFzc2V0LCBCdWZmZXJTb3VyY2UsIERlY29kZXIsIERlbXV4ZXIsIEV2ZW50RW1pdHRlciwgRmlsZVNvdXJjZSwgSFRUUFNvdXJjZSxcbiAgICBiaW5kID0gZnVuY3Rpb24oZm4sIG1lKXsgcmV0dXJuIGZ1bmN0aW9uKCl7IHJldHVybiBmbi5hcHBseShtZSwgYXJndW1lbnRzKTsgfTsgfSxcbiAgICBleHRlbmQgPSBmdW5jdGlvbihjaGlsZCwgcGFyZW50KSB7IGZvciAodmFyIGtleSBpbiBwYXJlbnQpIHsgaWYgKGhhc1Byb3AuY2FsbChwYXJlbnQsIGtleSkpIGNoaWxkW2tleV0gPSBwYXJlbnRba2V5XTsgfSBmdW5jdGlvbiBjdG9yKCkgeyB0aGlzLmNvbnN0cnVjdG9yID0gY2hpbGQ7IH0gY3Rvci5wcm90b3R5cGUgPSBwYXJlbnQucHJvdG90eXBlOyBjaGlsZC5wcm90b3R5cGUgPSBuZXcgY3RvcigpOyBjaGlsZC5fX3N1cGVyX18gPSBwYXJlbnQucHJvdG90eXBlOyByZXR1cm4gY2hpbGQ7IH0sXG4gICAgaGFzUHJvcCA9IHt9Lmhhc093blByb3BlcnR5O1xuXG4gIEV2ZW50RW1pdHRlciA9IHJlcXVpcmUoJy4vY29yZS9ldmVudHMnKTtcblxuICBIVFRQU291cmNlID0gcmVxdWlyZSgnLi9zb3VyY2VzL25vZGUvaHR0cCcpO1xuXG4gIEZpbGVTb3VyY2UgPSByZXF1aXJlKCcuL3NvdXJjZXMvbm9kZS9maWxlJyk7XG5cbiAgQnVmZmVyU291cmNlID0gcmVxdWlyZSgnLi9zb3VyY2VzL2J1ZmZlcicpO1xuXG4gIERlbXV4ZXIgPSByZXF1aXJlKCcuL2RlbXV4ZXInKTtcblxuICBEZWNvZGVyID0gcmVxdWlyZSgnLi9kZWNvZGVyJyk7XG5cbiAgQXNzZXQgPSAoZnVuY3Rpb24oc3VwZXJDbGFzcykge1xuICAgIGV4dGVuZChBc3NldCwgc3VwZXJDbGFzcyk7XG5cbiAgICBmdW5jdGlvbiBBc3NldChzb3VyY2UpIHtcbiAgICAgIHRoaXMuc291cmNlID0gc291cmNlO1xuICAgICAgdGhpcy5fZGVjb2RlID0gYmluZCh0aGlzLl9kZWNvZGUsIHRoaXMpO1xuICAgICAgdGhpcy5maW5kRGVjb2RlciA9IGJpbmQodGhpcy5maW5kRGVjb2RlciwgdGhpcyk7XG4gICAgICB0aGlzLnByb2JlID0gYmluZCh0aGlzLnByb2JlLCB0aGlzKTtcbiAgICAgIHRoaXMuYnVmZmVyZWQgPSAwO1xuICAgICAgdGhpcy5kdXJhdGlvbiA9IG51bGw7XG4gICAgICB0aGlzLmZvcm1hdCA9IG51bGw7XG4gICAgICB0aGlzLm1ldGFkYXRhID0gbnVsbDtcbiAgICAgIHRoaXMuYWN0aXZlID0gZmFsc2U7XG4gICAgICB0aGlzLmRlbXV4ZXIgPSBudWxsO1xuICAgICAgdGhpcy5kZWNvZGVyID0gbnVsbDtcbiAgICAgIHRoaXMuc291cmNlLm9uY2UoJ2RhdGEnLCB0aGlzLnByb2JlKTtcbiAgICAgIHRoaXMuc291cmNlLm9uKCdlcnJvcicsIChmdW5jdGlvbihfdGhpcykge1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24oZXJyKSB7XG4gICAgICAgICAgX3RoaXMuZW1pdCgnZXJyb3InLCBlcnIpO1xuICAgICAgICAgIHJldHVybiBfdGhpcy5zdG9wKCk7XG4gICAgICAgIH07XG4gICAgICB9KSh0aGlzKSk7XG4gICAgICB0aGlzLnNvdXJjZS5vbigncHJvZ3Jlc3MnLCAoZnVuY3Rpb24oX3RoaXMpIHtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKGJ1ZmZlcmVkKSB7XG4gICAgICAgICAgX3RoaXMuYnVmZmVyZWQgPSBidWZmZXJlZDtcbiAgICAgICAgICByZXR1cm4gX3RoaXMuZW1pdCgnYnVmZmVyJywgX3RoaXMuYnVmZmVyZWQpO1xuICAgICAgICB9O1xuICAgICAgfSkodGhpcykpO1xuICAgIH1cblxuICAgIEFzc2V0LmZyb21VUkwgPSBmdW5jdGlvbih1cmwsIG9wdHMpIHtcbiAgICAgIHJldHVybiBuZXcgQXNzZXQobmV3IEhUVFBTb3VyY2UodXJsLCBvcHRzKSk7XG4gICAgfTtcblxuICAgIEFzc2V0LmZyb21GaWxlID0gZnVuY3Rpb24oZmlsZSkge1xuICAgICAgcmV0dXJuIG5ldyBBc3NldChuZXcgRmlsZVNvdXJjZShmaWxlKSk7XG4gICAgfTtcblxuICAgIEFzc2V0LmZyb21CdWZmZXIgPSBmdW5jdGlvbihidWZmZXIpIHtcbiAgICAgIHJldHVybiBuZXcgQXNzZXQobmV3IEJ1ZmZlclNvdXJjZShidWZmZXIpKTtcbiAgICB9O1xuXG4gICAgQXNzZXQucHJvdG90eXBlLnN0YXJ0ID0gZnVuY3Rpb24oZGVjb2RlKSB7XG4gICAgICBpZiAodGhpcy5hY3RpdmUpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgaWYgKGRlY29kZSAhPSBudWxsKSB7XG4gICAgICAgIHRoaXMuc2hvdWxkRGVjb2RlID0gZGVjb2RlO1xuICAgICAgfVxuICAgICAgaWYgKHRoaXMuc2hvdWxkRGVjb2RlID09IG51bGwpIHtcbiAgICAgICAgdGhpcy5zaG91bGREZWNvZGUgPSB0cnVlO1xuICAgICAgfVxuICAgICAgdGhpcy5hY3RpdmUgPSB0cnVlO1xuICAgICAgdGhpcy5zb3VyY2Uuc3RhcnQoKTtcbiAgICAgIGlmICh0aGlzLmRlY29kZXIgJiYgdGhpcy5zaG91bGREZWNvZGUpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2RlY29kZSgpO1xuICAgICAgfVxuICAgIH07XG5cbiAgICBBc3NldC5wcm90b3R5cGUuc3RvcCA9IGZ1bmN0aW9uKCkge1xuICAgICAgaWYgKCF0aGlzLmFjdGl2ZSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICB0aGlzLmFjdGl2ZSA9IGZhbHNlO1xuICAgICAgcmV0dXJuIHRoaXMuc291cmNlLnBhdXNlKCk7XG4gICAgfTtcblxuICAgIEFzc2V0LnByb3RvdHlwZS5nZXQgPSBmdW5jdGlvbihldmVudCwgY2FsbGJhY2spIHtcbiAgICAgIGlmIChldmVudCAhPT0gJ2Zvcm1hdCcgJiYgZXZlbnQgIT09ICdkdXJhdGlvbicgJiYgZXZlbnQgIT09ICdtZXRhZGF0YScpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgaWYgKHRoaXNbZXZlbnRdICE9IG51bGwpIHtcbiAgICAgICAgcmV0dXJuIGNhbGxiYWNrKHRoaXNbZXZlbnRdKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMub25jZShldmVudCwgKGZ1bmN0aW9uKF90aGlzKSB7XG4gICAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgICAgICAgICBfdGhpcy5zdG9wKCk7XG4gICAgICAgICAgICByZXR1cm4gY2FsbGJhY2sodmFsdWUpO1xuICAgICAgICAgIH07XG4gICAgICAgIH0pKHRoaXMpKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuc3RhcnQoKTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgQXNzZXQucHJvdG90eXBlLmRlY29kZVBhY2tldCA9IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHRoaXMuZGVjb2Rlci5kZWNvZGUoKTtcbiAgICB9O1xuXG4gICAgQXNzZXQucHJvdG90eXBlLmRlY29kZVRvQnVmZmVyID0gZnVuY3Rpb24oY2FsbGJhY2spIHtcbiAgICAgIHZhciBjaHVua3MsIGRhdGFIYW5kbGVyLCBsZW5ndGg7XG4gICAgICBsZW5ndGggPSAwO1xuICAgICAgY2h1bmtzID0gW107XG4gICAgICB0aGlzLm9uKCdkYXRhJywgZGF0YUhhbmRsZXIgPSBmdW5jdGlvbihjaHVuaykge1xuICAgICAgICBsZW5ndGggKz0gY2h1bmsubGVuZ3RoO1xuICAgICAgICByZXR1cm4gY2h1bmtzLnB1c2goY2h1bmspO1xuICAgICAgfSk7XG4gICAgICB0aGlzLm9uY2UoJ2VuZCcsIGZ1bmN0aW9uKCkge1xuICAgICAgICB2YXIgYnVmLCBjaHVuaywgaiwgbGVuLCBvZmZzZXQ7XG4gICAgICAgIGJ1ZiA9IG5ldyBGbG9hdDMyQXJyYXkobGVuZ3RoKTtcbiAgICAgICAgb2Zmc2V0ID0gMDtcbiAgICAgICAgZm9yIChqID0gMCwgbGVuID0gY2h1bmtzLmxlbmd0aDsgaiA8IGxlbjsgaisrKSB7XG4gICAgICAgICAgY2h1bmsgPSBjaHVua3Nbal07XG4gICAgICAgICAgYnVmLnNldChjaHVuaywgb2Zmc2V0KTtcbiAgICAgICAgICBvZmZzZXQgKz0gY2h1bmsubGVuZ3RoO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMub2ZmKCdkYXRhJywgZGF0YUhhbmRsZXIpO1xuICAgICAgICByZXR1cm4gY2FsbGJhY2soYnVmKTtcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIHRoaXMuc3RhcnQoKTtcbiAgICB9O1xuXG4gICAgQXNzZXQucHJvdG90eXBlLnByb2JlID0gZnVuY3Rpb24oY2h1bmspIHtcbiAgICAgIHZhciBkZW11eGVyO1xuICAgICAgaWYgKCF0aGlzLmFjdGl2ZSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBkZW11eGVyID0gRGVtdXhlci5maW5kKGNodW5rKTtcbiAgICAgIGlmICghZGVtdXhlcikge1xuICAgICAgICByZXR1cm4gdGhpcy5lbWl0KCdlcnJvcicsICdBIGRlbXV4ZXIgZm9yIHRoaXMgY29udGFpbmVyIHdhcyBub3QgZm91bmQuJyk7XG4gICAgICB9XG4gICAgICB0aGlzLmRlbXV4ZXIgPSBuZXcgZGVtdXhlcih0aGlzLnNvdXJjZSwgY2h1bmspO1xuICAgICAgdGhpcy5kZW11eGVyLm9uKCdmb3JtYXQnLCB0aGlzLmZpbmREZWNvZGVyKTtcbiAgICAgIHRoaXMuZGVtdXhlci5vbignZHVyYXRpb24nLCAoZnVuY3Rpb24oX3RoaXMpIHtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKGR1cmF0aW9uKSB7XG4gICAgICAgICAgX3RoaXMuZHVyYXRpb24gPSBkdXJhdGlvbjtcbiAgICAgICAgICByZXR1cm4gX3RoaXMuZW1pdCgnZHVyYXRpb24nLCBfdGhpcy5kdXJhdGlvbik7XG4gICAgICAgIH07XG4gICAgICB9KSh0aGlzKSk7XG4gICAgICB0aGlzLmRlbXV4ZXIub24oJ21ldGFkYXRhJywgKGZ1bmN0aW9uKF90aGlzKSB7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbihtZXRhZGF0YSkge1xuICAgICAgICAgIF90aGlzLm1ldGFkYXRhID0gbWV0YWRhdGE7XG4gICAgICAgICAgcmV0dXJuIF90aGlzLmVtaXQoJ21ldGFkYXRhJywgX3RoaXMubWV0YWRhdGEpO1xuICAgICAgICB9O1xuICAgICAgfSkodGhpcykpO1xuICAgICAgcmV0dXJuIHRoaXMuZGVtdXhlci5vbignZXJyb3InLCAoZnVuY3Rpb24oX3RoaXMpIHtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKGVycikge1xuICAgICAgICAgIF90aGlzLmVtaXQoJ2Vycm9yJywgZXJyKTtcbiAgICAgICAgICByZXR1cm4gX3RoaXMuc3RvcCgpO1xuICAgICAgICB9O1xuICAgICAgfSkodGhpcykpO1xuICAgIH07XG5cbiAgICBBc3NldC5wcm90b3R5cGUuZmluZERlY29kZXIgPSBmdW5jdGlvbihmb3JtYXQpIHtcbiAgICAgIHZhciBkZWNvZGVyLCBkaXY7XG4gICAgICB0aGlzLmZvcm1hdCA9IGZvcm1hdDtcbiAgICAgIGlmICghdGhpcy5hY3RpdmUpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgdGhpcy5lbWl0KCdmb3JtYXQnLCB0aGlzLmZvcm1hdCk7XG4gICAgICBkZWNvZGVyID0gRGVjb2Rlci5maW5kKHRoaXMuZm9ybWF0LmZvcm1hdElEKTtcbiAgICAgIGlmICghZGVjb2Rlcikge1xuICAgICAgICByZXR1cm4gdGhpcy5lbWl0KCdlcnJvcicsIFwiQSBkZWNvZGVyIGZvciBcIiArIHRoaXMuZm9ybWF0LmZvcm1hdElEICsgXCIgd2FzIG5vdCBmb3VuZC5cIik7XG4gICAgICB9XG4gICAgICB0aGlzLmRlY29kZXIgPSBuZXcgZGVjb2Rlcih0aGlzLmRlbXV4ZXIsIHRoaXMuZm9ybWF0KTtcbiAgICAgIGlmICh0aGlzLmZvcm1hdC5mbG9hdGluZ1BvaW50KSB7XG4gICAgICAgIHRoaXMuZGVjb2Rlci5vbignZGF0YScsIChmdW5jdGlvbihfdGhpcykge1xuICAgICAgICAgIHJldHVybiBmdW5jdGlvbihidWZmZXIpIHtcbiAgICAgICAgICAgIHJldHVybiBfdGhpcy5lbWl0KCdkYXRhJywgYnVmZmVyKTtcbiAgICAgICAgICB9O1xuICAgICAgICB9KSh0aGlzKSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBkaXYgPSBNYXRoLnBvdygyLCB0aGlzLmZvcm1hdC5iaXRzUGVyQ2hhbm5lbCAtIDEpO1xuICAgICAgICB0aGlzLmRlY29kZXIub24oJ2RhdGEnLCAoZnVuY3Rpb24oX3RoaXMpIHtcbiAgICAgICAgICByZXR1cm4gZnVuY3Rpb24oYnVmZmVyKSB7XG4gICAgICAgICAgICB2YXIgYnVmLCBpLCBqLCBsZW4sIHNhbXBsZTtcbiAgICAgICAgICAgIGJ1ZiA9IG5ldyBGbG9hdDMyQXJyYXkoYnVmZmVyLmxlbmd0aCk7XG4gICAgICAgICAgICBmb3IgKGkgPSBqID0gMCwgbGVuID0gYnVmZmVyLmxlbmd0aDsgaiA8IGxlbjsgaSA9ICsraikge1xuICAgICAgICAgICAgICBzYW1wbGUgPSBidWZmZXJbaV07XG4gICAgICAgICAgICAgIGJ1ZltpXSA9IHNhbXBsZSAvIGRpdjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBfdGhpcy5lbWl0KCdkYXRhJywgYnVmKTtcbiAgICAgICAgICB9O1xuICAgICAgICB9KSh0aGlzKSk7XG4gICAgICB9XG4gICAgICB0aGlzLmRlY29kZXIub24oJ2Vycm9yJywgKGZ1bmN0aW9uKF90aGlzKSB7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbihlcnIpIHtcbiAgICAgICAgICBfdGhpcy5lbWl0KCdlcnJvcicsIGVycik7XG4gICAgICAgICAgcmV0dXJuIF90aGlzLnN0b3AoKTtcbiAgICAgICAgfTtcbiAgICAgIH0pKHRoaXMpKTtcbiAgICAgIHRoaXMuZGVjb2Rlci5vbignZW5kJywgKGZ1bmN0aW9uKF90aGlzKSB7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICAgICAgICByZXR1cm4gX3RoaXMuZW1pdCgnZW5kJyk7XG4gICAgICAgIH07XG4gICAgICB9KSh0aGlzKSk7XG4gICAgICB0aGlzLmVtaXQoJ2RlY29kZVN0YXJ0Jyk7XG4gICAgICBpZiAodGhpcy5zaG91bGREZWNvZGUpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2RlY29kZSgpO1xuICAgICAgfVxuICAgIH07XG5cbiAgICBBc3NldC5wcm90b3R5cGUuX2RlY29kZSA9IGZ1bmN0aW9uKCkge1xuICAgICAgd2hpbGUgKHRoaXMuZGVjb2Rlci5kZWNvZGUoKSAmJiB0aGlzLmFjdGl2ZSkge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIGlmICh0aGlzLmFjdGl2ZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5kZWNvZGVyLm9uY2UoJ2RhdGEnLCB0aGlzLl9kZWNvZGUpO1xuICAgICAgfVxuICAgIH07XG5cbiAgICBBc3NldC5wcm90b3R5cGUuZGVzdHJveSA9IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIHJlZiwgcmVmMSwgcmVmMjtcbiAgICAgIHRoaXMuc3RvcCgpO1xuICAgICAgaWYgKChyZWYgPSB0aGlzLmRlbXV4ZXIpICE9IG51bGwpIHtcbiAgICAgICAgcmVmLm9mZigpO1xuICAgICAgfVxuICAgICAgaWYgKChyZWYxID0gdGhpcy5kZWNvZGVyKSAhPSBudWxsKSB7XG4gICAgICAgIHJlZjEub2ZmKCk7XG4gICAgICB9XG4gICAgICBpZiAoKHJlZjIgPSB0aGlzLnNvdXJjZSkgIT0gbnVsbCkge1xuICAgICAgICByZWYyLm9mZigpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXMub2ZmKCk7XG4gICAgfTtcblxuICAgIHJldHVybiBBc3NldDtcblxuICB9KShFdmVudEVtaXR0ZXIpO1xuXG4gIG1vZHVsZS5leHBvcnRzID0gQXNzZXQ7XG5cbn0pLmNhbGwodGhpcyk7XG4iLCIvLyBHZW5lcmF0ZWQgYnkgQ29mZmVlU2NyaXB0IDEuMTIuN1xuKGZ1bmN0aW9uKCkge1xuICB2YXIga2V5LCByZWYsIHZhbDtcblxuICByZWYgPSByZXF1aXJlKCcuL2F1cm9yYV9iYXNlJyk7XG4gIGZvciAoa2V5IGluIHJlZikge1xuICAgIHZhbCA9IHJlZltrZXldO1xuICAgIGV4cG9ydHNba2V5XSA9IHZhbDtcbiAgfVxuXG4gIHJlcXVpcmUoJy4vZGVtdXhlcnMvY2FmJyk7XG5cbiAgcmVxdWlyZSgnLi9kZW11eGVycy9tNGEnKTtcblxuICByZXF1aXJlKCcuL2RlbXV4ZXJzL2FpZmYnKTtcblxuICByZXF1aXJlKCcuL2RlbXV4ZXJzL3dhdmUnKTtcblxuICByZXF1aXJlKCcuL2RlbXV4ZXJzL2F1Jyk7XG5cbiAgcmVxdWlyZSgnLi9kZWNvZGVycy9scGNtJyk7XG5cbiAgcmVxdWlyZSgnLi9kZWNvZGVycy94bGF3Jyk7XG5cbn0pLmNhbGwodGhpcyk7XG4iLCIvLyBHZW5lcmF0ZWQgYnkgQ29mZmVlU2NyaXB0IDEuMTIuN1xuKGZ1bmN0aW9uKCkge1xuICBleHBvcnRzLkJhc2UgPSByZXF1aXJlKCcuL2NvcmUvYmFzZScpO1xuXG4gIGV4cG9ydHMuQnVmZmVyID0gcmVxdWlyZSgnLi9jb3JlL2J1ZmZlcicpO1xuXG4gIGV4cG9ydHMuQnVmZmVyTGlzdCA9IHJlcXVpcmUoJy4vY29yZS9idWZmZXJsaXN0Jyk7XG5cbiAgZXhwb3J0cy5TdHJlYW0gPSByZXF1aXJlKCcuL2NvcmUvc3RyZWFtJyk7XG5cbiAgZXhwb3J0cy5CaXRzdHJlYW0gPSByZXF1aXJlKCcuL2NvcmUvYml0c3RyZWFtJyk7XG5cbiAgZXhwb3J0cy5FdmVudEVtaXR0ZXIgPSByZXF1aXJlKCcuL2NvcmUvZXZlbnRzJyk7XG5cbiAgZXhwb3J0cy5VbmRlcmZsb3dFcnJvciA9IHJlcXVpcmUoJy4vY29yZS91bmRlcmZsb3cnKTtcblxuICBleHBvcnRzLkhUVFBTb3VyY2UgPSByZXF1aXJlKCcuL3NvdXJjZXMvbm9kZS9odHRwJyk7XG5cbiAgZXhwb3J0cy5GaWxlU291cmNlID0gcmVxdWlyZSgnLi9zb3VyY2VzL25vZGUvZmlsZScpO1xuXG4gIGV4cG9ydHMuQnVmZmVyU291cmNlID0gcmVxdWlyZSgnLi9zb3VyY2VzL2J1ZmZlcicpO1xuXG4gIGV4cG9ydHMuRGVtdXhlciA9IHJlcXVpcmUoJy4vZGVtdXhlcicpO1xuXG4gIGV4cG9ydHMuRGVjb2RlciA9IHJlcXVpcmUoJy4vZGVjb2RlcicpO1xuXG4gIGV4cG9ydHMuQXVkaW9EZXZpY2UgPSByZXF1aXJlKCcuL2RldmljZScpO1xuXG4gIGV4cG9ydHMuQXNzZXQgPSByZXF1aXJlKCcuL2Fzc2V0Jyk7XG5cbiAgZXhwb3J0cy5QbGF5ZXIgPSByZXF1aXJlKCcuL3BsYXllcicpO1xuXG4gIGV4cG9ydHMuRmlsdGVyID0gcmVxdWlyZSgnLi9maWx0ZXInKTtcblxuICBleHBvcnRzLlZvbHVtZUZpbHRlciA9IHJlcXVpcmUoJy4vZmlsdGVycy92b2x1bWUnKTtcblxuICBleHBvcnRzLkJhbGFuY2VGaWx0ZXIgPSByZXF1aXJlKCcuL2ZpbHRlcnMvYmFsYW5jZScpO1xuXG59KS5jYWxsKHRoaXMpO1xuIiwiLy8gR2VuZXJhdGVkIGJ5IENvZmZlZVNjcmlwdCAxLjEyLjdcbihmdW5jdGlvbigpIHtcbiAgdmFyIEJhc2UsXG4gICAgZXh0ZW5kID0gZnVuY3Rpb24oY2hpbGQsIHBhcmVudCkgeyBmb3IgKHZhciBrZXkgaW4gcGFyZW50KSB7IGlmIChoYXNQcm9wLmNhbGwocGFyZW50LCBrZXkpKSBjaGlsZFtrZXldID0gcGFyZW50W2tleV07IH0gZnVuY3Rpb24gY3RvcigpIHsgdGhpcy5jb25zdHJ1Y3RvciA9IGNoaWxkOyB9IGN0b3IucHJvdG90eXBlID0gcGFyZW50LnByb3RvdHlwZTsgY2hpbGQucHJvdG90eXBlID0gbmV3IGN0b3IoKTsgY2hpbGQuX19zdXBlcl9fID0gcGFyZW50LnByb3RvdHlwZTsgcmV0dXJuIGNoaWxkOyB9LFxuICAgIGhhc1Byb3AgPSB7fS5oYXNPd25Qcm9wZXJ0eSxcbiAgICBpbmRleE9mID0gW10uaW5kZXhPZiB8fCBmdW5jdGlvbihpdGVtKSB7IGZvciAodmFyIGkgPSAwLCBsID0gdGhpcy5sZW5ndGg7IGkgPCBsOyBpKyspIHsgaWYgKGkgaW4gdGhpcyAmJiB0aGlzW2ldID09PSBpdGVtKSByZXR1cm4gaTsgfSByZXR1cm4gLTE7IH07XG5cbiAgQmFzZSA9IChmdW5jdGlvbigpIHtcbiAgICB2YXIgZm5UZXN0O1xuXG4gICAgZnVuY3Rpb24gQmFzZSgpIHt9XG5cbiAgICBmblRlc3QgPSAvXFxiX3N1cGVyXFxiLztcblxuICAgIEJhc2UuZXh0ZW5kID0gZnVuY3Rpb24ocHJvcCkge1xuICAgICAgdmFyIENsYXNzLCBfc3VwZXIsIGZuLCBrZXksIGtleXMsIHJlZjtcbiAgICAgIENsYXNzID0gKGZ1bmN0aW9uKHN1cGVyQ2xhc3MpIHtcbiAgICAgICAgZXh0ZW5kKENsYXNzLCBzdXBlckNsYXNzKTtcblxuICAgICAgICBmdW5jdGlvbiBDbGFzcygpIHtcbiAgICAgICAgICByZXR1cm4gQ2xhc3MuX19zdXBlcl9fLmNvbnN0cnVjdG9yLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gQ2xhc3M7XG5cbiAgICAgIH0pKHRoaXMpO1xuICAgICAgaWYgKHR5cGVvZiBwcm9wID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIGtleXMgPSBPYmplY3Qua2V5cyhDbGFzcy5wcm90b3R5cGUpO1xuICAgICAgICBwcm9wLmNhbGwoQ2xhc3MsIENsYXNzKTtcbiAgICAgICAgcHJvcCA9IHt9O1xuICAgICAgICByZWYgPSBDbGFzcy5wcm90b3R5cGU7XG4gICAgICAgIGZvciAoa2V5IGluIHJlZikge1xuICAgICAgICAgIGZuID0gcmVmW2tleV07XG4gICAgICAgICAgaWYgKGluZGV4T2YuY2FsbChrZXlzLCBrZXkpIDwgMCkge1xuICAgICAgICAgICAgcHJvcFtrZXldID0gZm47XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICBfc3VwZXIgPSBDbGFzcy5fX3N1cGVyX187XG4gICAgICBmb3IgKGtleSBpbiBwcm9wKSB7XG4gICAgICAgIGZuID0gcHJvcFtrZXldO1xuICAgICAgICBpZiAodHlwZW9mIGZuID09PSAnZnVuY3Rpb24nICYmIGZuVGVzdC50ZXN0KGZuKSkge1xuICAgICAgICAgIChmdW5jdGlvbihrZXksIGZuKSB7XG4gICAgICAgICAgICByZXR1cm4gQ2xhc3MucHJvdG90eXBlW2tleV0gPSBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgICAgdmFyIHJldCwgdG1wO1xuICAgICAgICAgICAgICB0bXAgPSB0aGlzLl9zdXBlcjtcbiAgICAgICAgICAgICAgdGhpcy5fc3VwZXIgPSBfc3VwZXJba2V5XTtcbiAgICAgICAgICAgICAgcmV0ID0gZm4uYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgICAgICAgICAgdGhpcy5fc3VwZXIgPSB0bXA7XG4gICAgICAgICAgICAgIHJldHVybiByZXQ7XG4gICAgICAgICAgICB9O1xuICAgICAgICAgIH0pKGtleSwgZm4pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIENsYXNzLnByb3RvdHlwZVtrZXldID0gZm47XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBDbGFzcztcbiAgICB9O1xuXG4gICAgcmV0dXJuIEJhc2U7XG5cbiAgfSkoKTtcblxuICBtb2R1bGUuZXhwb3J0cyA9IEJhc2U7XG5cbn0pLmNhbGwodGhpcyk7XG4iLCIvLyBHZW5lcmF0ZWQgYnkgQ29mZmVlU2NyaXB0IDEuMTIuN1xuKGZ1bmN0aW9uKCkge1xuICB2YXIgQml0c3RyZWFtO1xuXG4gIEJpdHN0cmVhbSA9IChmdW5jdGlvbigpIHtcbiAgICBmdW5jdGlvbiBCaXRzdHJlYW0oc3RyZWFtKSB7XG4gICAgICB0aGlzLnN0cmVhbSA9IHN0cmVhbTtcbiAgICAgIHRoaXMuYml0UG9zaXRpb24gPSAwO1xuICAgIH1cblxuICAgIEJpdHN0cmVhbS5wcm90b3R5cGUuY29weSA9IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIHJlc3VsdDtcbiAgICAgIHJlc3VsdCA9IG5ldyBCaXRzdHJlYW0odGhpcy5zdHJlYW0uY29weSgpKTtcbiAgICAgIHJlc3VsdC5iaXRQb3NpdGlvbiA9IHRoaXMuYml0UG9zaXRpb247XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH07XG5cbiAgICBCaXRzdHJlYW0ucHJvdG90eXBlLm9mZnNldCA9IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIDggKiB0aGlzLnN0cmVhbS5vZmZzZXQgKyB0aGlzLmJpdFBvc2l0aW9uO1xuICAgIH07XG5cbiAgICBCaXRzdHJlYW0ucHJvdG90eXBlLmF2YWlsYWJsZSA9IGZ1bmN0aW9uKGJpdHMpIHtcbiAgICAgIHJldHVybiB0aGlzLnN0cmVhbS5hdmFpbGFibGUoKGJpdHMgKyA4IC0gdGhpcy5iaXRQb3NpdGlvbikgLyA4KTtcbiAgICB9O1xuXG4gICAgQml0c3RyZWFtLnByb3RvdHlwZS5hZHZhbmNlID0gZnVuY3Rpb24oYml0cykge1xuICAgICAgdmFyIHBvcztcbiAgICAgIHBvcyA9IHRoaXMuYml0UG9zaXRpb24gKyBiaXRzO1xuICAgICAgdGhpcy5zdHJlYW0uYWR2YW5jZShwb3MgPj4gMyk7XG4gICAgICByZXR1cm4gdGhpcy5iaXRQb3NpdGlvbiA9IHBvcyAmIDc7XG4gICAgfTtcblxuICAgIEJpdHN0cmVhbS5wcm90b3R5cGUucmV3aW5kID0gZnVuY3Rpb24oYml0cykge1xuICAgICAgdmFyIHBvcztcbiAgICAgIHBvcyA9IHRoaXMuYml0UG9zaXRpb24gLSBiaXRzO1xuICAgICAgdGhpcy5zdHJlYW0ucmV3aW5kKE1hdGguYWJzKHBvcyA+PiAzKSk7XG4gICAgICByZXR1cm4gdGhpcy5iaXRQb3NpdGlvbiA9IHBvcyAmIDc7XG4gICAgfTtcblxuICAgIEJpdHN0cmVhbS5wcm90b3R5cGUuc2VlayA9IGZ1bmN0aW9uKG9mZnNldCkge1xuICAgICAgdmFyIGN1ck9mZnNldDtcbiAgICAgIGN1ck9mZnNldCA9IHRoaXMub2Zmc2V0KCk7XG4gICAgICBpZiAob2Zmc2V0ID4gY3VyT2Zmc2V0KSB7XG4gICAgICAgIHJldHVybiB0aGlzLmFkdmFuY2Uob2Zmc2V0IC0gY3VyT2Zmc2V0KTtcbiAgICAgIH0gZWxzZSBpZiAob2Zmc2V0IDwgY3VyT2Zmc2V0KSB7XG4gICAgICAgIHJldHVybiB0aGlzLnJld2luZChjdXJPZmZzZXQgLSBvZmZzZXQpO1xuICAgICAgfVxuICAgIH07XG5cbiAgICBCaXRzdHJlYW0ucHJvdG90eXBlLmFsaWduID0gZnVuY3Rpb24oKSB7XG4gICAgICBpZiAodGhpcy5iaXRQb3NpdGlvbiAhPT0gMCkge1xuICAgICAgICB0aGlzLmJpdFBvc2l0aW9uID0gMDtcbiAgICAgICAgcmV0dXJuIHRoaXMuc3RyZWFtLmFkdmFuY2UoMSk7XG4gICAgICB9XG4gICAgfTtcblxuICAgIEJpdHN0cmVhbS5wcm90b3R5cGUucmVhZCA9IGZ1bmN0aW9uKGJpdHMsIHNpZ25lZCkge1xuICAgICAgdmFyIGEsIGEwLCBhMSwgYTIsIGEzLCBhNCwgbUJpdHM7XG4gICAgICBpZiAoYml0cyA9PT0gMCkge1xuICAgICAgICByZXR1cm4gMDtcbiAgICAgIH1cbiAgICAgIG1CaXRzID0gYml0cyArIHRoaXMuYml0UG9zaXRpb247XG4gICAgICBpZiAobUJpdHMgPD0gOCkge1xuICAgICAgICBhID0gKCh0aGlzLnN0cmVhbS5wZWVrVUludDgoKSA8PCB0aGlzLmJpdFBvc2l0aW9uKSAmIDB4ZmYpID4+PiAoOCAtIGJpdHMpO1xuICAgICAgfSBlbHNlIGlmIChtQml0cyA8PSAxNikge1xuICAgICAgICBhID0gKCh0aGlzLnN0cmVhbS5wZWVrVUludDE2KCkgPDwgdGhpcy5iaXRQb3NpdGlvbikgJiAweGZmZmYpID4+PiAoMTYgLSBiaXRzKTtcbiAgICAgIH0gZWxzZSBpZiAobUJpdHMgPD0gMjQpIHtcbiAgICAgICAgYSA9ICgodGhpcy5zdHJlYW0ucGVla1VJbnQyNCgpIDw8IHRoaXMuYml0UG9zaXRpb24pICYgMHhmZmZmZmYpID4+PiAoMjQgLSBiaXRzKTtcbiAgICAgIH0gZWxzZSBpZiAobUJpdHMgPD0gMzIpIHtcbiAgICAgICAgYSA9ICh0aGlzLnN0cmVhbS5wZWVrVUludDMyKCkgPDwgdGhpcy5iaXRQb3NpdGlvbikgPj4+ICgzMiAtIGJpdHMpO1xuICAgICAgfSBlbHNlIGlmIChtQml0cyA8PSA0MCkge1xuICAgICAgICBhMCA9IHRoaXMuc3RyZWFtLnBlZWtVSW50OCgwKSAqIDB4MDEwMDAwMDAwMDtcbiAgICAgICAgYTEgPSB0aGlzLnN0cmVhbS5wZWVrVUludDgoMSkgPDwgMjQgPj4+IDA7XG4gICAgICAgIGEyID0gdGhpcy5zdHJlYW0ucGVla1VJbnQ4KDIpIDw8IDE2O1xuICAgICAgICBhMyA9IHRoaXMuc3RyZWFtLnBlZWtVSW50OCgzKSA8PCA4O1xuICAgICAgICBhNCA9IHRoaXMuc3RyZWFtLnBlZWtVSW50OCg0KTtcbiAgICAgICAgYSA9IGEwICsgYTEgKyBhMiArIGEzICsgYTQ7XG4gICAgICAgIGEgJT0gTWF0aC5wb3coMiwgNDAgLSB0aGlzLmJpdFBvc2l0aW9uKTtcbiAgICAgICAgYSA9IE1hdGguZmxvb3IoYSAvIE1hdGgucG93KDIsIDQwIC0gdGhpcy5iaXRQb3NpdGlvbiAtIGJpdHMpKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIlRvbyBtYW55IGJpdHMhXCIpO1xuICAgICAgfVxuICAgICAgaWYgKHNpZ25lZCkge1xuICAgICAgICBpZiAobUJpdHMgPCAzMikge1xuICAgICAgICAgIGlmIChhID4+PiAoYml0cyAtIDEpKSB7XG4gICAgICAgICAgICBhID0gKCgxIDw8IGJpdHMgPj4+IDApIC0gYSkgKiAtMTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgaWYgKGEgLyBNYXRoLnBvdygyLCBiaXRzIC0gMSkgfCAwKSB7XG4gICAgICAgICAgICBhID0gKE1hdGgucG93KDIsIGJpdHMpIC0gYSkgKiAtMTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHRoaXMuYWR2YW5jZShiaXRzKTtcbiAgICAgIHJldHVybiBhO1xuICAgIH07XG5cbiAgICBCaXRzdHJlYW0ucHJvdG90eXBlLnBlZWsgPSBmdW5jdGlvbihiaXRzLCBzaWduZWQpIHtcbiAgICAgIHZhciBhLCBhMCwgYTEsIGEyLCBhMywgYTQsIG1CaXRzO1xuICAgICAgaWYgKGJpdHMgPT09IDApIHtcbiAgICAgICAgcmV0dXJuIDA7XG4gICAgICB9XG4gICAgICBtQml0cyA9IGJpdHMgKyB0aGlzLmJpdFBvc2l0aW9uO1xuICAgICAgaWYgKG1CaXRzIDw9IDgpIHtcbiAgICAgICAgYSA9ICgodGhpcy5zdHJlYW0ucGVla1VJbnQ4KCkgPDwgdGhpcy5iaXRQb3NpdGlvbikgJiAweGZmKSA+Pj4gKDggLSBiaXRzKTtcbiAgICAgIH0gZWxzZSBpZiAobUJpdHMgPD0gMTYpIHtcbiAgICAgICAgYSA9ICgodGhpcy5zdHJlYW0ucGVla1VJbnQxNigpIDw8IHRoaXMuYml0UG9zaXRpb24pICYgMHhmZmZmKSA+Pj4gKDE2IC0gYml0cyk7XG4gICAgICB9IGVsc2UgaWYgKG1CaXRzIDw9IDI0KSB7XG4gICAgICAgIGEgPSAoKHRoaXMuc3RyZWFtLnBlZWtVSW50MjQoKSA8PCB0aGlzLmJpdFBvc2l0aW9uKSAmIDB4ZmZmZmZmKSA+Pj4gKDI0IC0gYml0cyk7XG4gICAgICB9IGVsc2UgaWYgKG1CaXRzIDw9IDMyKSB7XG4gICAgICAgIGEgPSAodGhpcy5zdHJlYW0ucGVla1VJbnQzMigpIDw8IHRoaXMuYml0UG9zaXRpb24pID4+PiAoMzIgLSBiaXRzKTtcbiAgICAgIH0gZWxzZSBpZiAobUJpdHMgPD0gNDApIHtcbiAgICAgICAgYTAgPSB0aGlzLnN0cmVhbS5wZWVrVUludDgoMCkgKiAweDAxMDAwMDAwMDA7XG4gICAgICAgIGExID0gdGhpcy5zdHJlYW0ucGVla1VJbnQ4KDEpIDw8IDI0ID4+PiAwO1xuICAgICAgICBhMiA9IHRoaXMuc3RyZWFtLnBlZWtVSW50OCgyKSA8PCAxNjtcbiAgICAgICAgYTMgPSB0aGlzLnN0cmVhbS5wZWVrVUludDgoMykgPDwgODtcbiAgICAgICAgYTQgPSB0aGlzLnN0cmVhbS5wZWVrVUludDgoNCk7XG4gICAgICAgIGEgPSBhMCArIGExICsgYTIgKyBhMyArIGE0O1xuICAgICAgICBhICU9IE1hdGgucG93KDIsIDQwIC0gdGhpcy5iaXRQb3NpdGlvbik7XG4gICAgICAgIGEgPSBNYXRoLmZsb29yKGEgLyBNYXRoLnBvdygyLCA0MCAtIHRoaXMuYml0UG9zaXRpb24gLSBiaXRzKSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJUb28gbWFueSBiaXRzIVwiKTtcbiAgICAgIH1cbiAgICAgIGlmIChzaWduZWQpIHtcbiAgICAgICAgaWYgKG1CaXRzIDwgMzIpIHtcbiAgICAgICAgICBpZiAoYSA+Pj4gKGJpdHMgLSAxKSkge1xuICAgICAgICAgICAgYSA9ICgoMSA8PCBiaXRzID4+PiAwKSAtIGEpICogLTE7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGlmIChhIC8gTWF0aC5wb3coMiwgYml0cyAtIDEpIHwgMCkge1xuICAgICAgICAgICAgYSA9IChNYXRoLnBvdygyLCBiaXRzKSAtIGEpICogLTE7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gYTtcbiAgICB9O1xuXG4gICAgQml0c3RyZWFtLnByb3RvdHlwZS5yZWFkTFNCID0gZnVuY3Rpb24oYml0cywgc2lnbmVkKSB7XG4gICAgICB2YXIgYSwgbUJpdHM7XG4gICAgICBpZiAoYml0cyA9PT0gMCkge1xuICAgICAgICByZXR1cm4gMDtcbiAgICAgIH1cbiAgICAgIGlmIChiaXRzID4gNDApIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVG9vIG1hbnkgYml0cyFcIik7XG4gICAgICB9XG4gICAgICBtQml0cyA9IGJpdHMgKyB0aGlzLmJpdFBvc2l0aW9uO1xuICAgICAgYSA9ICh0aGlzLnN0cmVhbS5wZWVrVUludDgoMCkpID4+PiB0aGlzLmJpdFBvc2l0aW9uO1xuICAgICAgaWYgKG1CaXRzID4gOCkge1xuICAgICAgICBhIHw9ICh0aGlzLnN0cmVhbS5wZWVrVUludDgoMSkpIDw8ICg4IC0gdGhpcy5iaXRQb3NpdGlvbik7XG4gICAgICB9XG4gICAgICBpZiAobUJpdHMgPiAxNikge1xuICAgICAgICBhIHw9ICh0aGlzLnN0cmVhbS5wZWVrVUludDgoMikpIDw8ICgxNiAtIHRoaXMuYml0UG9zaXRpb24pO1xuICAgICAgfVxuICAgICAgaWYgKG1CaXRzID4gMjQpIHtcbiAgICAgICAgYSArPSAodGhpcy5zdHJlYW0ucGVla1VJbnQ4KDMpKSA8PCAoMjQgLSB0aGlzLmJpdFBvc2l0aW9uKSA+Pj4gMDtcbiAgICAgIH1cbiAgICAgIGlmIChtQml0cyA+IDMyKSB7XG4gICAgICAgIGEgKz0gKHRoaXMuc3RyZWFtLnBlZWtVSW50OCg0KSkgKiBNYXRoLnBvdygyLCAzMiAtIHRoaXMuYml0UG9zaXRpb24pO1xuICAgICAgfVxuICAgICAgaWYgKG1CaXRzID49IDMyKSB7XG4gICAgICAgIGEgJT0gTWF0aC5wb3coMiwgYml0cyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBhICY9ICgxIDw8IGJpdHMpIC0gMTtcbiAgICAgIH1cbiAgICAgIGlmIChzaWduZWQpIHtcbiAgICAgICAgaWYgKG1CaXRzIDwgMzIpIHtcbiAgICAgICAgICBpZiAoYSA+Pj4gKGJpdHMgLSAxKSkge1xuICAgICAgICAgICAgYSA9ICgoMSA8PCBiaXRzID4+PiAwKSAtIGEpICogLTE7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGlmIChhIC8gTWF0aC5wb3coMiwgYml0cyAtIDEpIHwgMCkge1xuICAgICAgICAgICAgYSA9IChNYXRoLnBvdygyLCBiaXRzKSAtIGEpICogLTE7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICB0aGlzLmFkdmFuY2UoYml0cyk7XG4gICAgICByZXR1cm4gYTtcbiAgICB9O1xuXG4gICAgQml0c3RyZWFtLnByb3RvdHlwZS5wZWVrTFNCID0gZnVuY3Rpb24oYml0cywgc2lnbmVkKSB7XG4gICAgICB2YXIgYSwgbUJpdHM7XG4gICAgICBpZiAoYml0cyA9PT0gMCkge1xuICAgICAgICByZXR1cm4gMDtcbiAgICAgIH1cbiAgICAgIGlmIChiaXRzID4gNDApIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVG9vIG1hbnkgYml0cyFcIik7XG4gICAgICB9XG4gICAgICBtQml0cyA9IGJpdHMgKyB0aGlzLmJpdFBvc2l0aW9uO1xuICAgICAgYSA9ICh0aGlzLnN0cmVhbS5wZWVrVUludDgoMCkpID4+PiB0aGlzLmJpdFBvc2l0aW9uO1xuICAgICAgaWYgKG1CaXRzID4gOCkge1xuICAgICAgICBhIHw9ICh0aGlzLnN0cmVhbS5wZWVrVUludDgoMSkpIDw8ICg4IC0gdGhpcy5iaXRQb3NpdGlvbik7XG4gICAgICB9XG4gICAgICBpZiAobUJpdHMgPiAxNikge1xuICAgICAgICBhIHw9ICh0aGlzLnN0cmVhbS5wZWVrVUludDgoMikpIDw8ICgxNiAtIHRoaXMuYml0UG9zaXRpb24pO1xuICAgICAgfVxuICAgICAgaWYgKG1CaXRzID4gMjQpIHtcbiAgICAgICAgYSArPSAodGhpcy5zdHJlYW0ucGVla1VJbnQ4KDMpKSA8PCAoMjQgLSB0aGlzLmJpdFBvc2l0aW9uKSA+Pj4gMDtcbiAgICAgIH1cbiAgICAgIGlmIChtQml0cyA+IDMyKSB7XG4gICAgICAgIGEgKz0gKHRoaXMuc3RyZWFtLnBlZWtVSW50OCg0KSkgKiBNYXRoLnBvdygyLCAzMiAtIHRoaXMuYml0UG9zaXRpb24pO1xuICAgICAgfVxuICAgICAgaWYgKG1CaXRzID49IDMyKSB7XG4gICAgICAgIGEgJT0gTWF0aC5wb3coMiwgYml0cyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBhICY9ICgxIDw8IGJpdHMpIC0gMTtcbiAgICAgIH1cbiAgICAgIGlmIChzaWduZWQpIHtcbiAgICAgICAgaWYgKG1CaXRzIDwgMzIpIHtcbiAgICAgICAgICBpZiAoYSA+Pj4gKGJpdHMgLSAxKSkge1xuICAgICAgICAgICAgYSA9ICgoMSA8PCBiaXRzID4+PiAwKSAtIGEpICogLTE7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGlmIChhIC8gTWF0aC5wb3coMiwgYml0cyAtIDEpIHwgMCkge1xuICAgICAgICAgICAgYSA9IChNYXRoLnBvdygyLCBiaXRzKSAtIGEpICogLTE7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gYTtcbiAgICB9O1xuXG4gICAgcmV0dXJuIEJpdHN0cmVhbTtcblxuICB9KSgpO1xuXG4gIG1vZHVsZS5leHBvcnRzID0gQml0c3RyZWFtO1xuXG59KS5jYWxsKHRoaXMpO1xuIiwiLy8gR2VuZXJhdGVkIGJ5IENvZmZlZVNjcmlwdCAxLjEyLjdcbihmdW5jdGlvbigpIHtcbiAgdmFyIEFWQnVmZmVyO1xuXG4gIEFWQnVmZmVyID0gKGZ1bmN0aW9uKCkge1xuICAgIHZhciBCbG9iQnVpbGRlciwgVVJMO1xuXG4gICAgZnVuY3Rpb24gQVZCdWZmZXIoaW5wdXQpIHtcbiAgICAgIHZhciByZWY7XG4gICAgICBpZiAoaW5wdXQgaW5zdGFuY2VvZiBVaW50OEFycmF5KSB7XG4gICAgICAgIHRoaXMuZGF0YSA9IGlucHV0O1xuICAgICAgfSBlbHNlIGlmIChpbnB1dCBpbnN0YW5jZW9mIEFycmF5QnVmZmVyIHx8IEFycmF5LmlzQXJyYXkoaW5wdXQpIHx8IHR5cGVvZiBpbnB1dCA9PT0gJ251bWJlcicgfHwgKChyZWYgPSBnbG9iYWwuQnVmZmVyKSAhPSBudWxsID8gcmVmLmlzQnVmZmVyKGlucHV0KSA6IHZvaWQgMCkpIHtcbiAgICAgICAgdGhpcy5kYXRhID0gbmV3IFVpbnQ4QXJyYXkoaW5wdXQpO1xuICAgICAgfSBlbHNlIGlmIChpbnB1dC5idWZmZXIgaW5zdGFuY2VvZiBBcnJheUJ1ZmZlcikge1xuICAgICAgICB0aGlzLmRhdGEgPSBuZXcgVWludDhBcnJheShpbnB1dC5idWZmZXIsIGlucHV0LmJ5dGVPZmZzZXQsIGlucHV0Lmxlbmd0aCAqIGlucHV0LkJZVEVTX1BFUl9FTEVNRU5UKTtcbiAgICAgIH0gZWxzZSBpZiAoaW5wdXQgaW5zdGFuY2VvZiBBVkJ1ZmZlcikge1xuICAgICAgICB0aGlzLmRhdGEgPSBpbnB1dC5kYXRhO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQ29uc3RydWN0aW5nIGJ1ZmZlciB3aXRoIHVua25vd24gdHlwZS5cIik7XG4gICAgICB9XG4gICAgICB0aGlzLmxlbmd0aCA9IHRoaXMuZGF0YS5sZW5ndGg7XG4gICAgICB0aGlzLm5leHQgPSBudWxsO1xuICAgICAgdGhpcy5wcmV2ID0gbnVsbDtcbiAgICB9XG5cbiAgICBBVkJ1ZmZlci5hbGxvY2F0ZSA9IGZ1bmN0aW9uKHNpemUpIHtcbiAgICAgIHJldHVybiBuZXcgQVZCdWZmZXIoc2l6ZSk7XG4gICAgfTtcblxuICAgIEFWQnVmZmVyLnByb3RvdHlwZS5jb3B5ID0gZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gbmV3IEFWQnVmZmVyKG5ldyBVaW50OEFycmF5KHRoaXMuZGF0YSkpO1xuICAgIH07XG5cbiAgICBBVkJ1ZmZlci5wcm90b3R5cGUuc2xpY2UgPSBmdW5jdGlvbihwb3NpdGlvbiwgbGVuZ3RoKSB7XG4gICAgICBpZiAobGVuZ3RoID09IG51bGwpIHtcbiAgICAgICAgbGVuZ3RoID0gdGhpcy5sZW5ndGg7XG4gICAgICB9XG4gICAgICBpZiAocG9zaXRpb24gPT09IDAgJiYgbGVuZ3RoID49IHRoaXMubGVuZ3RoKSB7XG4gICAgICAgIHJldHVybiBuZXcgQVZCdWZmZXIodGhpcy5kYXRhKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBuZXcgQVZCdWZmZXIodGhpcy5kYXRhLnN1YmFycmF5KHBvc2l0aW9uLCBwb3NpdGlvbiArIGxlbmd0aCkpO1xuICAgICAgfVxuICAgIH07XG5cbiAgICBCbG9iQnVpbGRlciA9IGdsb2JhbC5CbG9iQnVpbGRlciB8fCBnbG9iYWwuTW96QmxvYkJ1aWxkZXIgfHwgZ2xvYmFsLldlYktpdEJsb2JCdWlsZGVyO1xuXG4gICAgVVJMID0gZ2xvYmFsLlVSTCB8fCBnbG9iYWwud2Via2l0VVJMIHx8IGdsb2JhbC5tb3pVUkw7XG5cbiAgICBBVkJ1ZmZlci5tYWtlQmxvYiA9IGZ1bmN0aW9uKGRhdGEsIHR5cGUpIHtcbiAgICAgIHZhciBiYjtcbiAgICAgIGlmICh0eXBlID09IG51bGwpIHtcbiAgICAgICAgdHlwZSA9ICdhcHBsaWNhdGlvbi9vY3RldC1zdHJlYW0nO1xuICAgICAgfVxuICAgICAgdHJ5IHtcbiAgICAgICAgcmV0dXJuIG5ldyBCbG9iKFtkYXRhXSwge1xuICAgICAgICAgIHR5cGU6IHR5cGVcbiAgICAgICAgfSk7XG4gICAgICB9IGNhdGNoIChlcnJvcikge31cbiAgICAgIGlmIChCbG9iQnVpbGRlciAhPSBudWxsKSB7XG4gICAgICAgIGJiID0gbmV3IEJsb2JCdWlsZGVyO1xuICAgICAgICBiYi5hcHBlbmQoZGF0YSk7XG4gICAgICAgIHJldHVybiBiYi5nZXRCbG9iKHR5cGUpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfTtcblxuICAgIEFWQnVmZmVyLm1ha2VCbG9iVVJMID0gZnVuY3Rpb24oZGF0YSwgdHlwZSkge1xuICAgICAgcmV0dXJuIFVSTCAhPSBudWxsID8gVVJMLmNyZWF0ZU9iamVjdFVSTCh0aGlzLm1ha2VCbG9iKGRhdGEsIHR5cGUpKSA6IHZvaWQgMDtcbiAgICB9O1xuXG4gICAgQVZCdWZmZXIucmV2b2tlQmxvYlVSTCA9IGZ1bmN0aW9uKHVybCkge1xuICAgICAgcmV0dXJuIFVSTCAhPSBudWxsID8gVVJMLnJldm9rZU9iamVjdFVSTCh1cmwpIDogdm9pZCAwO1xuICAgIH07XG5cbiAgICBBVkJ1ZmZlci5wcm90b3R5cGUudG9CbG9iID0gZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gQVZCdWZmZXIubWFrZUJsb2IodGhpcy5kYXRhLmJ1ZmZlcik7XG4gICAgfTtcblxuICAgIEFWQnVmZmVyLnByb3RvdHlwZS50b0Jsb2JVUkwgPSBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiBBVkJ1ZmZlci5tYWtlQmxvYlVSTCh0aGlzLmRhdGEuYnVmZmVyKTtcbiAgICB9O1xuXG4gICAgcmV0dXJuIEFWQnVmZmVyO1xuXG4gIH0pKCk7XG5cbiAgbW9kdWxlLmV4cG9ydHMgPSBBVkJ1ZmZlcjtcblxufSkuY2FsbCh0aGlzKTtcbiIsIi8vIEdlbmVyYXRlZCBieSBDb2ZmZWVTY3JpcHQgMS4xMi43XG4oZnVuY3Rpb24oKSB7XG4gIHZhciBCdWZmZXJMaXN0O1xuXG4gIEJ1ZmZlckxpc3QgPSAoZnVuY3Rpb24oKSB7XG4gICAgZnVuY3Rpb24gQnVmZmVyTGlzdCgpIHtcbiAgICAgIHRoaXMuZmlyc3QgPSBudWxsO1xuICAgICAgdGhpcy5sYXN0ID0gbnVsbDtcbiAgICAgIHRoaXMubnVtQnVmZmVycyA9IDA7XG4gICAgICB0aGlzLmF2YWlsYWJsZUJ5dGVzID0gMDtcbiAgICAgIHRoaXMuYXZhaWxhYmxlQnVmZmVycyA9IDA7XG4gICAgfVxuXG4gICAgQnVmZmVyTGlzdC5wcm90b3R5cGUuY29weSA9IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIHJlc3VsdDtcbiAgICAgIHJlc3VsdCA9IG5ldyBCdWZmZXJMaXN0O1xuICAgICAgcmVzdWx0LmZpcnN0ID0gdGhpcy5maXJzdDtcbiAgICAgIHJlc3VsdC5sYXN0ID0gdGhpcy5sYXN0O1xuICAgICAgcmVzdWx0Lm51bUJ1ZmZlcnMgPSB0aGlzLm51bUJ1ZmZlcnM7XG4gICAgICByZXN1bHQuYXZhaWxhYmxlQnl0ZXMgPSB0aGlzLmF2YWlsYWJsZUJ5dGVzO1xuICAgICAgcmVzdWx0LmF2YWlsYWJsZUJ1ZmZlcnMgPSB0aGlzLmF2YWlsYWJsZUJ1ZmZlcnM7XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH07XG5cbiAgICBCdWZmZXJMaXN0LnByb3RvdHlwZS5hcHBlbmQgPSBmdW5jdGlvbihidWZmZXIpIHtcbiAgICAgIHZhciByZWY7XG4gICAgICBidWZmZXIucHJldiA9IHRoaXMubGFzdDtcbiAgICAgIGlmICgocmVmID0gdGhpcy5sYXN0KSAhPSBudWxsKSB7XG4gICAgICAgIHJlZi5uZXh0ID0gYnVmZmVyO1xuICAgICAgfVxuICAgICAgdGhpcy5sYXN0ID0gYnVmZmVyO1xuICAgICAgaWYgKHRoaXMuZmlyc3QgPT0gbnVsbCkge1xuICAgICAgICB0aGlzLmZpcnN0ID0gYnVmZmVyO1xuICAgICAgfVxuICAgICAgdGhpcy5hdmFpbGFibGVCeXRlcyArPSBidWZmZXIubGVuZ3RoO1xuICAgICAgdGhpcy5hdmFpbGFibGVCdWZmZXJzKys7XG4gICAgICByZXR1cm4gdGhpcy5udW1CdWZmZXJzKys7XG4gICAgfTtcblxuICAgIEJ1ZmZlckxpc3QucHJvdG90eXBlLmFkdmFuY2UgPSBmdW5jdGlvbigpIHtcbiAgICAgIGlmICh0aGlzLmZpcnN0KSB7XG4gICAgICAgIHRoaXMuYXZhaWxhYmxlQnl0ZXMgLT0gdGhpcy5maXJzdC5sZW5ndGg7XG4gICAgICAgIHRoaXMuYXZhaWxhYmxlQnVmZmVycy0tO1xuICAgICAgICB0aGlzLmZpcnN0ID0gdGhpcy5maXJzdC5uZXh0O1xuICAgICAgICByZXR1cm4gdGhpcy5maXJzdCAhPSBudWxsO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH07XG5cbiAgICBCdWZmZXJMaXN0LnByb3RvdHlwZS5yZXdpbmQgPSBmdW5jdGlvbigpIHtcbiAgICAgIHZhciByZWY7XG4gICAgICBpZiAodGhpcy5maXJzdCAmJiAhdGhpcy5maXJzdC5wcmV2KSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICAgIHRoaXMuZmlyc3QgPSAoKHJlZiA9IHRoaXMuZmlyc3QpICE9IG51bGwgPyByZWYucHJldiA6IHZvaWQgMCkgfHwgdGhpcy5sYXN0O1xuICAgICAgaWYgKHRoaXMuZmlyc3QpIHtcbiAgICAgICAgdGhpcy5hdmFpbGFibGVCeXRlcyArPSB0aGlzLmZpcnN0Lmxlbmd0aDtcbiAgICAgICAgdGhpcy5hdmFpbGFibGVCdWZmZXJzKys7XG4gICAgICB9XG4gICAgICByZXR1cm4gdGhpcy5maXJzdCAhPSBudWxsO1xuICAgIH07XG5cbiAgICBCdWZmZXJMaXN0LnByb3RvdHlwZS5yZXNldCA9IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIHJlc3VsdHM7XG4gICAgICByZXN1bHRzID0gW107XG4gICAgICB3aGlsZSAodGhpcy5yZXdpbmQoKSkge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIHJldHVybiByZXN1bHRzO1xuICAgIH07XG5cbiAgICByZXR1cm4gQnVmZmVyTGlzdDtcblxuICB9KSgpO1xuXG4gIG1vZHVsZS5leHBvcnRzID0gQnVmZmVyTGlzdDtcblxufSkuY2FsbCh0aGlzKTtcbiIsIi8vIEdlbmVyYXRlZCBieSBDb2ZmZWVTY3JpcHQgMS4xMi43XG4oZnVuY3Rpb24oKSB7XG4gIHZhciBCYXNlLCBFdmVudEVtaXR0ZXIsXG4gICAgZXh0ZW5kID0gZnVuY3Rpb24oY2hpbGQsIHBhcmVudCkgeyBmb3IgKHZhciBrZXkgaW4gcGFyZW50KSB7IGlmIChoYXNQcm9wLmNhbGwocGFyZW50LCBrZXkpKSBjaGlsZFtrZXldID0gcGFyZW50W2tleV07IH0gZnVuY3Rpb24gY3RvcigpIHsgdGhpcy5jb25zdHJ1Y3RvciA9IGNoaWxkOyB9IGN0b3IucHJvdG90eXBlID0gcGFyZW50LnByb3RvdHlwZTsgY2hpbGQucHJvdG90eXBlID0gbmV3IGN0b3IoKTsgY2hpbGQuX19zdXBlcl9fID0gcGFyZW50LnByb3RvdHlwZTsgcmV0dXJuIGNoaWxkOyB9LFxuICAgIGhhc1Byb3AgPSB7fS5oYXNPd25Qcm9wZXJ0eSxcbiAgICBzbGljZSA9IFtdLnNsaWNlO1xuXG4gIEJhc2UgPSByZXF1aXJlKCcuL2Jhc2UnKTtcblxuICBFdmVudEVtaXR0ZXIgPSAoZnVuY3Rpb24oc3VwZXJDbGFzcykge1xuICAgIGV4dGVuZChFdmVudEVtaXR0ZXIsIHN1cGVyQ2xhc3MpO1xuXG4gICAgZnVuY3Rpb24gRXZlbnRFbWl0dGVyKCkge1xuICAgICAgcmV0dXJuIEV2ZW50RW1pdHRlci5fX3N1cGVyX18uY29uc3RydWN0b3IuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICB9XG5cbiAgICBFdmVudEVtaXR0ZXIucHJvdG90eXBlLm9uID0gZnVuY3Rpb24oZXZlbnQsIGZuKSB7XG4gICAgICB2YXIgYmFzZTtcbiAgICAgIGlmICh0aGlzLmV2ZW50cyA9PSBudWxsKSB7XG4gICAgICAgIHRoaXMuZXZlbnRzID0ge307XG4gICAgICB9XG4gICAgICBpZiAoKGJhc2UgPSB0aGlzLmV2ZW50cylbZXZlbnRdID09IG51bGwpIHtcbiAgICAgICAgYmFzZVtldmVudF0gPSBbXTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0aGlzLmV2ZW50c1tldmVudF0ucHVzaChmbik7XG4gICAgfTtcblxuICAgIEV2ZW50RW1pdHRlci5wcm90b3R5cGUub2ZmID0gZnVuY3Rpb24oZXZlbnQsIGZuKSB7XG4gICAgICB2YXIgZXZlbnRzLCBpbmRleCwgcmVmO1xuICAgICAgaWYgKHRoaXMuZXZlbnRzID09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgaWYgKChyZWYgPSB0aGlzLmV2ZW50cykgIT0gbnVsbCA/IHJlZltldmVudF0gOiB2b2lkIDApIHtcbiAgICAgICAgaWYgKGZuICE9IG51bGwpIHtcbiAgICAgICAgICBpbmRleCA9IHRoaXMuZXZlbnRzW2V2ZW50XS5pbmRleE9mKGZuKTtcbiAgICAgICAgICBpZiAofmluZGV4KSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5ldmVudHNbZXZlbnRdLnNwbGljZShpbmRleCwgMSk7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiB0aGlzLmV2ZW50c1tldmVudF07XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAoZXZlbnQgPT0gbnVsbCkge1xuICAgICAgICByZXR1cm4gZXZlbnRzID0ge307XG4gICAgICB9XG4gICAgfTtcblxuICAgIEV2ZW50RW1pdHRlci5wcm90b3R5cGUub25jZSA9IGZ1bmN0aW9uKGV2ZW50LCBmbikge1xuICAgICAgdmFyIGNiO1xuICAgICAgcmV0dXJuIHRoaXMub24oZXZlbnQsIGNiID0gZnVuY3Rpb24oKSB7XG4gICAgICAgIHRoaXMub2ZmKGV2ZW50LCBjYik7XG4gICAgICAgIHJldHVybiBmbi5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgfSk7XG4gICAgfTtcblxuICAgIEV2ZW50RW1pdHRlci5wcm90b3R5cGUuZW1pdCA9IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIGFyZ3MsIGV2ZW50LCBmbiwgaSwgbGVuLCByZWYsIHJlZjE7XG4gICAgICBldmVudCA9IGFyZ3VtZW50c1swXSwgYXJncyA9IDIgPD0gYXJndW1lbnRzLmxlbmd0aCA/IHNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKSA6IFtdO1xuICAgICAgaWYgKCEoKHJlZiA9IHRoaXMuZXZlbnRzKSAhPSBudWxsID8gcmVmW2V2ZW50XSA6IHZvaWQgMCkpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgcmVmMSA9IHRoaXMuZXZlbnRzW2V2ZW50XS5zbGljZSgpO1xuICAgICAgZm9yIChpID0gMCwgbGVuID0gcmVmMS5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgICAgICBmbiA9IHJlZjFbaV07XG4gICAgICAgIGZuLmFwcGx5KHRoaXMsIGFyZ3MpO1xuICAgICAgfVxuICAgIH07XG5cbiAgICByZXR1cm4gRXZlbnRFbWl0dGVyO1xuXG4gIH0pKEJhc2UpO1xuXG4gIG1vZHVsZS5leHBvcnRzID0gRXZlbnRFbWl0dGVyO1xuXG59KS5jYWxsKHRoaXMpO1xuIiwiLy8gR2VuZXJhdGVkIGJ5IENvZmZlZVNjcmlwdCAxLjEyLjdcbihmdW5jdGlvbigpIHtcbiAgdmFyIEFWQnVmZmVyLCBCdWZmZXJMaXN0LCBTdHJlYW0sIFVuZGVyZmxvd0Vycm9yO1xuXG4gIEJ1ZmZlckxpc3QgPSByZXF1aXJlKCcuL2J1ZmZlcmxpc3QnKTtcblxuICBBVkJ1ZmZlciA9IHJlcXVpcmUoJy4vYnVmZmVyJyk7XG5cbiAgVW5kZXJmbG93RXJyb3IgPSByZXF1aXJlKCcuL3VuZGVyZmxvdycpO1xuXG4gIFN0cmVhbSA9IChmdW5jdGlvbigpIHtcbiAgICB2YXIgYnVmLCBkZWNvZGVTdHJpbmcsIGZsb2F0MzIsIGZsb2F0NjQsIGZsb2F0NjRGYWxsYmFjaywgZmxvYXQ4MCwgaW50MTYsIGludDMyLCBpbnQ4LCBuYXRpdmVFbmRpYW4sIHVpbnQxNiwgdWludDMyLCB1aW50ODtcblxuICAgIGJ1ZiA9IG5ldyBBcnJheUJ1ZmZlcigxNik7XG5cbiAgICB1aW50OCA9IG5ldyBVaW50OEFycmF5KGJ1Zik7XG5cbiAgICBpbnQ4ID0gbmV3IEludDhBcnJheShidWYpO1xuXG4gICAgdWludDE2ID0gbmV3IFVpbnQxNkFycmF5KGJ1Zik7XG5cbiAgICBpbnQxNiA9IG5ldyBJbnQxNkFycmF5KGJ1Zik7XG5cbiAgICB1aW50MzIgPSBuZXcgVWludDMyQXJyYXkoYnVmKTtcblxuICAgIGludDMyID0gbmV3IEludDMyQXJyYXkoYnVmKTtcblxuICAgIGZsb2F0MzIgPSBuZXcgRmxvYXQzMkFycmF5KGJ1Zik7XG5cbiAgICBpZiAodHlwZW9mIEZsb2F0NjRBcnJheSAhPT0gXCJ1bmRlZmluZWRcIiAmJiBGbG9hdDY0QXJyYXkgIT09IG51bGwpIHtcbiAgICAgIGZsb2F0NjQgPSBuZXcgRmxvYXQ2NEFycmF5KGJ1Zik7XG4gICAgfVxuXG4gICAgbmF0aXZlRW5kaWFuID0gbmV3IFVpbnQxNkFycmF5KG5ldyBVaW50OEFycmF5KFsweDEyLCAweDM0XSkuYnVmZmVyKVswXSA9PT0gMHgzNDEyO1xuXG4gICAgZnVuY3Rpb24gU3RyZWFtKGxpc3QxKSB7XG4gICAgICB0aGlzLmxpc3QgPSBsaXN0MTtcbiAgICAgIHRoaXMubG9jYWxPZmZzZXQgPSAwO1xuICAgICAgdGhpcy5vZmZzZXQgPSAwO1xuICAgIH1cblxuICAgIFN0cmVhbS5mcm9tQnVmZmVyID0gZnVuY3Rpb24oYnVmZmVyKSB7XG4gICAgICB2YXIgbGlzdDtcbiAgICAgIGxpc3QgPSBuZXcgQnVmZmVyTGlzdDtcbiAgICAgIGxpc3QuYXBwZW5kKGJ1ZmZlcik7XG4gICAgICByZXR1cm4gbmV3IFN0cmVhbShsaXN0KTtcbiAgICB9O1xuXG4gICAgU3RyZWFtLnByb3RvdHlwZS5jb3B5ID0gZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgcmVzdWx0O1xuICAgICAgcmVzdWx0ID0gbmV3IFN0cmVhbSh0aGlzLmxpc3QuY29weSgpKTtcbiAgICAgIHJlc3VsdC5sb2NhbE9mZnNldCA9IHRoaXMubG9jYWxPZmZzZXQ7XG4gICAgICByZXN1bHQub2Zmc2V0ID0gdGhpcy5vZmZzZXQ7XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH07XG5cbiAgICBTdHJlYW0ucHJvdG90eXBlLmF2YWlsYWJsZSA9IGZ1bmN0aW9uKGJ5dGVzKSB7XG4gICAgICByZXR1cm4gYnl0ZXMgPD0gdGhpcy5saXN0LmF2YWlsYWJsZUJ5dGVzIC0gdGhpcy5sb2NhbE9mZnNldDtcbiAgICB9O1xuXG4gICAgU3RyZWFtLnByb3RvdHlwZS5yZW1haW5pbmdCeXRlcyA9IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHRoaXMubGlzdC5hdmFpbGFibGVCeXRlcyAtIHRoaXMubG9jYWxPZmZzZXQ7XG4gICAgfTtcblxuICAgIFN0cmVhbS5wcm90b3R5cGUuYWR2YW5jZSA9IGZ1bmN0aW9uKGJ5dGVzKSB7XG4gICAgICBpZiAoIXRoaXMuYXZhaWxhYmxlKGJ5dGVzKSkge1xuICAgICAgICB0aHJvdyBuZXcgVW5kZXJmbG93RXJyb3IoKTtcbiAgICAgIH1cbiAgICAgIHRoaXMubG9jYWxPZmZzZXQgKz0gYnl0ZXM7XG4gICAgICB0aGlzLm9mZnNldCArPSBieXRlcztcbiAgICAgIHdoaWxlICh0aGlzLmxpc3QuZmlyc3QgJiYgdGhpcy5sb2NhbE9mZnNldCA+PSB0aGlzLmxpc3QuZmlyc3QubGVuZ3RoKSB7XG4gICAgICAgIHRoaXMubG9jYWxPZmZzZXQgLT0gdGhpcy5saXN0LmZpcnN0Lmxlbmd0aDtcbiAgICAgICAgdGhpcy5saXN0LmFkdmFuY2UoKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG5cbiAgICBTdHJlYW0ucHJvdG90eXBlLnJld2luZCA9IGZ1bmN0aW9uKGJ5dGVzKSB7XG4gICAgICBpZiAoYnl0ZXMgPiB0aGlzLm9mZnNldCkge1xuICAgICAgICB0aHJvdyBuZXcgVW5kZXJmbG93RXJyb3IoKTtcbiAgICAgIH1cbiAgICAgIGlmICghdGhpcy5saXN0LmZpcnN0KSB7XG4gICAgICAgIHRoaXMubGlzdC5yZXdpbmQoKTtcbiAgICAgICAgdGhpcy5sb2NhbE9mZnNldCA9IHRoaXMubGlzdC5maXJzdC5sZW5ndGg7XG4gICAgICB9XG4gICAgICB0aGlzLmxvY2FsT2Zmc2V0IC09IGJ5dGVzO1xuICAgICAgdGhpcy5vZmZzZXQgLT0gYnl0ZXM7XG4gICAgICB3aGlsZSAodGhpcy5saXN0LmZpcnN0LnByZXYgJiYgdGhpcy5sb2NhbE9mZnNldCA8IDApIHtcbiAgICAgICAgdGhpcy5saXN0LnJld2luZCgpO1xuICAgICAgICB0aGlzLmxvY2FsT2Zmc2V0ICs9IHRoaXMubGlzdC5maXJzdC5sZW5ndGg7XG4gICAgICB9XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG4gICAgU3RyZWFtLnByb3RvdHlwZS5zZWVrID0gZnVuY3Rpb24ocG9zaXRpb24pIHtcbiAgICAgIGlmIChwb3NpdGlvbiA+IHRoaXMub2Zmc2V0KSB7XG4gICAgICAgIHJldHVybiB0aGlzLmFkdmFuY2UocG9zaXRpb24gLSB0aGlzLm9mZnNldCk7XG4gICAgICB9IGVsc2UgaWYgKHBvc2l0aW9uIDwgdGhpcy5vZmZzZXQpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucmV3aW5kKHRoaXMub2Zmc2V0IC0gcG9zaXRpb24pO1xuICAgICAgfVxuICAgIH07XG5cbiAgICBTdHJlYW0ucHJvdG90eXBlLnJlYWRVSW50OCA9IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIGE7XG4gICAgICBpZiAoIXRoaXMuYXZhaWxhYmxlKDEpKSB7XG4gICAgICAgIHRocm93IG5ldyBVbmRlcmZsb3dFcnJvcigpO1xuICAgICAgfVxuICAgICAgYSA9IHRoaXMubGlzdC5maXJzdC5kYXRhW3RoaXMubG9jYWxPZmZzZXRdO1xuICAgICAgdGhpcy5sb2NhbE9mZnNldCArPSAxO1xuICAgICAgdGhpcy5vZmZzZXQgKz0gMTtcbiAgICAgIGlmICh0aGlzLmxvY2FsT2Zmc2V0ID09PSB0aGlzLmxpc3QuZmlyc3QubGVuZ3RoKSB7XG4gICAgICAgIHRoaXMubG9jYWxPZmZzZXQgPSAwO1xuICAgICAgICB0aGlzLmxpc3QuYWR2YW5jZSgpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGE7XG4gICAgfTtcblxuICAgIFN0cmVhbS5wcm90b3R5cGUucGVla1VJbnQ4ID0gZnVuY3Rpb24ob2Zmc2V0KSB7XG4gICAgICB2YXIgYnVmZmVyO1xuICAgICAgaWYgKG9mZnNldCA9PSBudWxsKSB7XG4gICAgICAgIG9mZnNldCA9IDA7XG4gICAgICB9XG4gICAgICBpZiAoIXRoaXMuYXZhaWxhYmxlKG9mZnNldCArIDEpKSB7XG4gICAgICAgIHRocm93IG5ldyBVbmRlcmZsb3dFcnJvcigpO1xuICAgICAgfVxuICAgICAgb2Zmc2V0ID0gdGhpcy5sb2NhbE9mZnNldCArIG9mZnNldDtcbiAgICAgIGJ1ZmZlciA9IHRoaXMubGlzdC5maXJzdDtcbiAgICAgIHdoaWxlIChidWZmZXIpIHtcbiAgICAgICAgaWYgKGJ1ZmZlci5sZW5ndGggPiBvZmZzZXQpIHtcbiAgICAgICAgICByZXR1cm4gYnVmZmVyLmRhdGFbb2Zmc2V0XTtcbiAgICAgICAgfVxuICAgICAgICBvZmZzZXQgLT0gYnVmZmVyLmxlbmd0aDtcbiAgICAgICAgYnVmZmVyID0gYnVmZmVyLm5leHQ7XG4gICAgICB9XG4gICAgICByZXR1cm4gMDtcbiAgICB9O1xuXG4gICAgU3RyZWFtLnByb3RvdHlwZS5yZWFkID0gZnVuY3Rpb24oYnl0ZXMsIGxpdHRsZUVuZGlhbikge1xuICAgICAgdmFyIGksIGosIGssIHJlZiwgcmVmMTtcbiAgICAgIGlmIChsaXR0bGVFbmRpYW4gPT0gbnVsbCkge1xuICAgICAgICBsaXR0bGVFbmRpYW4gPSBmYWxzZTtcbiAgICAgIH1cbiAgICAgIGlmIChsaXR0bGVFbmRpYW4gPT09IG5hdGl2ZUVuZGlhbikge1xuICAgICAgICBmb3IgKGkgPSBqID0gMCwgcmVmID0gYnl0ZXM7IGogPCByZWY7IGkgPSBqICs9IDEpIHtcbiAgICAgICAgICB1aW50OFtpXSA9IHRoaXMucmVhZFVJbnQ4KCk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGZvciAoaSA9IGsgPSByZWYxID0gYnl0ZXMgLSAxOyBrID49IDA7IGkgPSBrICs9IC0xKSB7XG4gICAgICAgICAgdWludDhbaV0gPSB0aGlzLnJlYWRVSW50OCgpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfTtcblxuICAgIFN0cmVhbS5wcm90b3R5cGUucGVlayA9IGZ1bmN0aW9uKGJ5dGVzLCBvZmZzZXQsIGxpdHRsZUVuZGlhbikge1xuICAgICAgdmFyIGksIGosIGssIHJlZiwgcmVmMTtcbiAgICAgIGlmIChsaXR0bGVFbmRpYW4gPT0gbnVsbCkge1xuICAgICAgICBsaXR0bGVFbmRpYW4gPSBmYWxzZTtcbiAgICAgIH1cbiAgICAgIGlmIChsaXR0bGVFbmRpYW4gPT09IG5hdGl2ZUVuZGlhbikge1xuICAgICAgICBmb3IgKGkgPSBqID0gMCwgcmVmID0gYnl0ZXM7IGogPCByZWY7IGkgPSBqICs9IDEpIHtcbiAgICAgICAgICB1aW50OFtpXSA9IHRoaXMucGVla1VJbnQ4KG9mZnNldCArIGkpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBmb3IgKGkgPSBrID0gMCwgcmVmMSA9IGJ5dGVzOyBrIDwgcmVmMTsgaSA9IGsgKz0gMSkge1xuICAgICAgICAgIHVpbnQ4W2J5dGVzIC0gaSAtIDFdID0gdGhpcy5wZWVrVUludDgob2Zmc2V0ICsgaSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9O1xuXG4gICAgU3RyZWFtLnByb3RvdHlwZS5yZWFkSW50OCA9IGZ1bmN0aW9uKCkge1xuICAgICAgdGhpcy5yZWFkKDEpO1xuICAgICAgcmV0dXJuIGludDhbMF07XG4gICAgfTtcblxuICAgIFN0cmVhbS5wcm90b3R5cGUucGVla0ludDggPSBmdW5jdGlvbihvZmZzZXQpIHtcbiAgICAgIGlmIChvZmZzZXQgPT0gbnVsbCkge1xuICAgICAgICBvZmZzZXQgPSAwO1xuICAgICAgfVxuICAgICAgdGhpcy5wZWVrKDEsIG9mZnNldCk7XG4gICAgICByZXR1cm4gaW50OFswXTtcbiAgICB9O1xuXG4gICAgU3RyZWFtLnByb3RvdHlwZS5yZWFkVUludDE2ID0gZnVuY3Rpb24obGl0dGxlRW5kaWFuKSB7XG4gICAgICB0aGlzLnJlYWQoMiwgbGl0dGxlRW5kaWFuKTtcbiAgICAgIHJldHVybiB1aW50MTZbMF07XG4gICAgfTtcblxuICAgIFN0cmVhbS5wcm90b3R5cGUucGVla1VJbnQxNiA9IGZ1bmN0aW9uKG9mZnNldCwgbGl0dGxlRW5kaWFuKSB7XG4gICAgICBpZiAob2Zmc2V0ID09IG51bGwpIHtcbiAgICAgICAgb2Zmc2V0ID0gMDtcbiAgICAgIH1cbiAgICAgIHRoaXMucGVlaygyLCBvZmZzZXQsIGxpdHRsZUVuZGlhbik7XG4gICAgICByZXR1cm4gdWludDE2WzBdO1xuICAgIH07XG5cbiAgICBTdHJlYW0ucHJvdG90eXBlLnJlYWRJbnQxNiA9IGZ1bmN0aW9uKGxpdHRsZUVuZGlhbikge1xuICAgICAgdGhpcy5yZWFkKDIsIGxpdHRsZUVuZGlhbik7XG4gICAgICByZXR1cm4gaW50MTZbMF07XG4gICAgfTtcblxuICAgIFN0cmVhbS5wcm90b3R5cGUucGVla0ludDE2ID0gZnVuY3Rpb24ob2Zmc2V0LCBsaXR0bGVFbmRpYW4pIHtcbiAgICAgIGlmIChvZmZzZXQgPT0gbnVsbCkge1xuICAgICAgICBvZmZzZXQgPSAwO1xuICAgICAgfVxuICAgICAgdGhpcy5wZWVrKDIsIG9mZnNldCwgbGl0dGxlRW5kaWFuKTtcbiAgICAgIHJldHVybiBpbnQxNlswXTtcbiAgICB9O1xuXG4gICAgU3RyZWFtLnByb3RvdHlwZS5yZWFkVUludDI0ID0gZnVuY3Rpb24obGl0dGxlRW5kaWFuKSB7XG4gICAgICBpZiAobGl0dGxlRW5kaWFuKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnJlYWRVSW50MTYodHJ1ZSkgKyAodGhpcy5yZWFkVUludDgoKSA8PCAxNik7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gKHRoaXMucmVhZFVJbnQxNigpIDw8IDgpICsgdGhpcy5yZWFkVUludDgoKTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgU3RyZWFtLnByb3RvdHlwZS5wZWVrVUludDI0ID0gZnVuY3Rpb24ob2Zmc2V0LCBsaXR0bGVFbmRpYW4pIHtcbiAgICAgIGlmIChvZmZzZXQgPT0gbnVsbCkge1xuICAgICAgICBvZmZzZXQgPSAwO1xuICAgICAgfVxuICAgICAgaWYgKGxpdHRsZUVuZGlhbikge1xuICAgICAgICByZXR1cm4gdGhpcy5wZWVrVUludDE2KG9mZnNldCwgdHJ1ZSkgKyAodGhpcy5wZWVrVUludDgob2Zmc2V0ICsgMikgPDwgMTYpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuICh0aGlzLnBlZWtVSW50MTYob2Zmc2V0KSA8PCA4KSArIHRoaXMucGVla1VJbnQ4KG9mZnNldCArIDIpO1xuICAgICAgfVxuICAgIH07XG5cbiAgICBTdHJlYW0ucHJvdG90eXBlLnJlYWRJbnQyNCA9IGZ1bmN0aW9uKGxpdHRsZUVuZGlhbikge1xuICAgICAgaWYgKGxpdHRsZUVuZGlhbikge1xuICAgICAgICByZXR1cm4gdGhpcy5yZWFkVUludDE2KHRydWUpICsgKHRoaXMucmVhZEludDgoKSA8PCAxNik7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gKHRoaXMucmVhZEludDE2KCkgPDwgOCkgKyB0aGlzLnJlYWRVSW50OCgpO1xuICAgICAgfVxuICAgIH07XG5cbiAgICBTdHJlYW0ucHJvdG90eXBlLnBlZWtJbnQyNCA9IGZ1bmN0aW9uKG9mZnNldCwgbGl0dGxlRW5kaWFuKSB7XG4gICAgICBpZiAob2Zmc2V0ID09IG51bGwpIHtcbiAgICAgICAgb2Zmc2V0ID0gMDtcbiAgICAgIH1cbiAgICAgIGlmIChsaXR0bGVFbmRpYW4pIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucGVla1VJbnQxNihvZmZzZXQsIHRydWUpICsgKHRoaXMucGVla0ludDgob2Zmc2V0ICsgMikgPDwgMTYpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuICh0aGlzLnBlZWtJbnQxNihvZmZzZXQpIDw8IDgpICsgdGhpcy5wZWVrVUludDgob2Zmc2V0ICsgMik7XG4gICAgICB9XG4gICAgfTtcblxuICAgIFN0cmVhbS5wcm90b3R5cGUucmVhZFVJbnQzMiA9IGZ1bmN0aW9uKGxpdHRsZUVuZGlhbikge1xuICAgICAgdGhpcy5yZWFkKDQsIGxpdHRsZUVuZGlhbik7XG4gICAgICByZXR1cm4gdWludDMyWzBdO1xuICAgIH07XG5cbiAgICBTdHJlYW0ucHJvdG90eXBlLnBlZWtVSW50MzIgPSBmdW5jdGlvbihvZmZzZXQsIGxpdHRsZUVuZGlhbikge1xuICAgICAgaWYgKG9mZnNldCA9PSBudWxsKSB7XG4gICAgICAgIG9mZnNldCA9IDA7XG4gICAgICB9XG4gICAgICB0aGlzLnBlZWsoNCwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4pO1xuICAgICAgcmV0dXJuIHVpbnQzMlswXTtcbiAgICB9O1xuXG4gICAgU3RyZWFtLnByb3RvdHlwZS5yZWFkSW50MzIgPSBmdW5jdGlvbihsaXR0bGVFbmRpYW4pIHtcbiAgICAgIHRoaXMucmVhZCg0LCBsaXR0bGVFbmRpYW4pO1xuICAgICAgcmV0dXJuIGludDMyWzBdO1xuICAgIH07XG5cbiAgICBTdHJlYW0ucHJvdG90eXBlLnBlZWtJbnQzMiA9IGZ1bmN0aW9uKG9mZnNldCwgbGl0dGxlRW5kaWFuKSB7XG4gICAgICBpZiAob2Zmc2V0ID09IG51bGwpIHtcbiAgICAgICAgb2Zmc2V0ID0gMDtcbiAgICAgIH1cbiAgICAgIHRoaXMucGVlayg0LCBvZmZzZXQsIGxpdHRsZUVuZGlhbik7XG4gICAgICByZXR1cm4gaW50MzJbMF07XG4gICAgfTtcblxuICAgIFN0cmVhbS5wcm90b3R5cGUucmVhZEZsb2F0MzIgPSBmdW5jdGlvbihsaXR0bGVFbmRpYW4pIHtcbiAgICAgIHRoaXMucmVhZCg0LCBsaXR0bGVFbmRpYW4pO1xuICAgICAgcmV0dXJuIGZsb2F0MzJbMF07XG4gICAgfTtcblxuICAgIFN0cmVhbS5wcm90b3R5cGUucGVla0Zsb2F0MzIgPSBmdW5jdGlvbihvZmZzZXQsIGxpdHRsZUVuZGlhbikge1xuICAgICAgaWYgKG9mZnNldCA9PSBudWxsKSB7XG4gICAgICAgIG9mZnNldCA9IDA7XG4gICAgICB9XG4gICAgICB0aGlzLnBlZWsoNCwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4pO1xuICAgICAgcmV0dXJuIGZsb2F0MzJbMF07XG4gICAgfTtcblxuICAgIFN0cmVhbS5wcm90b3R5cGUucmVhZEZsb2F0NjQgPSBmdW5jdGlvbihsaXR0bGVFbmRpYW4pIHtcbiAgICAgIHRoaXMucmVhZCg4LCBsaXR0bGVFbmRpYW4pO1xuICAgICAgaWYgKGZsb2F0NjQpIHtcbiAgICAgICAgcmV0dXJuIGZsb2F0NjRbMF07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gZmxvYXQ2NEZhbGxiYWNrKCk7XG4gICAgICB9XG4gICAgfTtcblxuICAgIGZsb2F0NjRGYWxsYmFjayA9IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIGV4cCwgZnJhYywgaGlnaCwgbG93LCBvdXQsIHNpZ247XG4gICAgICBsb3cgPSB1aW50MzJbMF0sIGhpZ2ggPSB1aW50MzJbMV07XG4gICAgICBpZiAoIWhpZ2ggfHwgaGlnaCA9PT0gMHg4MDAwMDAwMCkge1xuICAgICAgICByZXR1cm4gMC4wO1xuICAgICAgfVxuICAgICAgc2lnbiA9IDEgLSAoaGlnaCA+Pj4gMzEpICogMjtcbiAgICAgIGV4cCA9IChoaWdoID4+PiAyMCkgJiAweDdmZjtcbiAgICAgIGZyYWMgPSBoaWdoICYgMHhmZmZmZjtcbiAgICAgIGlmIChleHAgPT09IDB4N2ZmKSB7XG4gICAgICAgIGlmIChmcmFjKSB7XG4gICAgICAgICAgcmV0dXJuIDAvMDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gc2lnbiAqIDJlMzA4O1xuICAgICAgfVxuICAgICAgZXhwIC09IDEwMjM7XG4gICAgICBvdXQgPSAoZnJhYyB8IDB4MTAwMDAwKSAqIE1hdGgucG93KDIsIGV4cCAtIDIwKTtcbiAgICAgIG91dCArPSBsb3cgKiBNYXRoLnBvdygyLCBleHAgLSA1Mik7XG4gICAgICByZXR1cm4gc2lnbiAqIG91dDtcbiAgICB9O1xuXG4gICAgU3RyZWFtLnByb3RvdHlwZS5wZWVrRmxvYXQ2NCA9IGZ1bmN0aW9uKG9mZnNldCwgbGl0dGxlRW5kaWFuKSB7XG4gICAgICBpZiAob2Zmc2V0ID09IG51bGwpIHtcbiAgICAgICAgb2Zmc2V0ID0gMDtcbiAgICAgIH1cbiAgICAgIHRoaXMucGVlayg4LCBvZmZzZXQsIGxpdHRsZUVuZGlhbik7XG4gICAgICBpZiAoZmxvYXQ2NCkge1xuICAgICAgICByZXR1cm4gZmxvYXQ2NFswXTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBmbG9hdDY0RmFsbGJhY2soKTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgU3RyZWFtLnByb3RvdHlwZS5yZWFkRmxvYXQ4MCA9IGZ1bmN0aW9uKGxpdHRsZUVuZGlhbikge1xuICAgICAgdGhpcy5yZWFkKDEwLCBsaXR0bGVFbmRpYW4pO1xuICAgICAgcmV0dXJuIGZsb2F0ODAoKTtcbiAgICB9O1xuXG4gICAgZmxvYXQ4MCA9IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIGEwLCBhMSwgZXhwLCBoaWdoLCBsb3csIG91dCwgc2lnbjtcbiAgICAgIGhpZ2ggPSB1aW50MzJbMF0sIGxvdyA9IHVpbnQzMlsxXTtcbiAgICAgIGEwID0gdWludDhbOV07XG4gICAgICBhMSA9IHVpbnQ4WzhdO1xuICAgICAgc2lnbiA9IDEgLSAoYTAgPj4+IDcpICogMjtcbiAgICAgIGV4cCA9ICgoYTAgJiAweDdGKSA8PCA4KSB8IGExO1xuICAgICAgaWYgKGV4cCA9PT0gMCAmJiBsb3cgPT09IDAgJiYgaGlnaCA9PT0gMCkge1xuICAgICAgICByZXR1cm4gMDtcbiAgICAgIH1cbiAgICAgIGlmIChleHAgPT09IDB4N2ZmZikge1xuICAgICAgICBpZiAobG93ID09PSAwICYmIGhpZ2ggPT09IDApIHtcbiAgICAgICAgICByZXR1cm4gc2lnbiAqIDJlMzA4O1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiAwLzA7XG4gICAgICB9XG4gICAgICBleHAgLT0gMTYzODM7XG4gICAgICBvdXQgPSBsb3cgKiBNYXRoLnBvdygyLCBleHAgLSAzMSk7XG4gICAgICBvdXQgKz0gaGlnaCAqIE1hdGgucG93KDIsIGV4cCAtIDYzKTtcbiAgICAgIHJldHVybiBzaWduICogb3V0O1xuICAgIH07XG5cbiAgICBTdHJlYW0ucHJvdG90eXBlLnBlZWtGbG9hdDgwID0gZnVuY3Rpb24ob2Zmc2V0LCBsaXR0bGVFbmRpYW4pIHtcbiAgICAgIGlmIChvZmZzZXQgPT0gbnVsbCkge1xuICAgICAgICBvZmZzZXQgPSAwO1xuICAgICAgfVxuICAgICAgdGhpcy5wZWVrKDEwLCBvZmZzZXQsIGxpdHRsZUVuZGlhbik7XG4gICAgICByZXR1cm4gZmxvYXQ4MCgpO1xuICAgIH07XG5cbiAgICBTdHJlYW0ucHJvdG90eXBlLnJlYWRCdWZmZXIgPSBmdW5jdGlvbihsZW5ndGgpIHtcbiAgICAgIHZhciBpLCBqLCByZWYsIHJlc3VsdCwgdG87XG4gICAgICByZXN1bHQgPSBBVkJ1ZmZlci5hbGxvY2F0ZShsZW5ndGgpO1xuICAgICAgdG8gPSByZXN1bHQuZGF0YTtcbiAgICAgIGZvciAoaSA9IGogPSAwLCByZWYgPSBsZW5ndGg7IGogPCByZWY7IGkgPSBqICs9IDEpIHtcbiAgICAgICAgdG9baV0gPSB0aGlzLnJlYWRVSW50OCgpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9O1xuXG4gICAgU3RyZWFtLnByb3RvdHlwZS5wZWVrQnVmZmVyID0gZnVuY3Rpb24ob2Zmc2V0LCBsZW5ndGgpIHtcbiAgICAgIHZhciBpLCBqLCByZWYsIHJlc3VsdCwgdG87XG4gICAgICBpZiAob2Zmc2V0ID09IG51bGwpIHtcbiAgICAgICAgb2Zmc2V0ID0gMDtcbiAgICAgIH1cbiAgICAgIHJlc3VsdCA9IEFWQnVmZmVyLmFsbG9jYXRlKGxlbmd0aCk7XG4gICAgICB0byA9IHJlc3VsdC5kYXRhO1xuICAgICAgZm9yIChpID0gaiA9IDAsIHJlZiA9IGxlbmd0aDsgaiA8IHJlZjsgaSA9IGogKz0gMSkge1xuICAgICAgICB0b1tpXSA9IHRoaXMucGVla1VJbnQ4KG9mZnNldCArIGkpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9O1xuXG4gICAgU3RyZWFtLnByb3RvdHlwZS5yZWFkU2luZ2xlQnVmZmVyID0gZnVuY3Rpb24obGVuZ3RoKSB7XG4gICAgICB2YXIgcmVzdWx0O1xuICAgICAgcmVzdWx0ID0gdGhpcy5saXN0LmZpcnN0LnNsaWNlKHRoaXMubG9jYWxPZmZzZXQsIGxlbmd0aCk7XG4gICAgICB0aGlzLmFkdmFuY2UocmVzdWx0Lmxlbmd0aCk7XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH07XG5cbiAgICBTdHJlYW0ucHJvdG90eXBlLnBlZWtTaW5nbGVCdWZmZXIgPSBmdW5jdGlvbihvZmZzZXQsIGxlbmd0aCkge1xuICAgICAgdmFyIHJlc3VsdDtcbiAgICAgIHJlc3VsdCA9IHRoaXMubGlzdC5maXJzdC5zbGljZSh0aGlzLmxvY2FsT2Zmc2V0ICsgb2Zmc2V0LCBsZW5ndGgpO1xuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9O1xuXG4gICAgU3RyZWFtLnByb3RvdHlwZS5yZWFkU3RyaW5nID0gZnVuY3Rpb24obGVuZ3RoLCBlbmNvZGluZykge1xuICAgICAgaWYgKGVuY29kaW5nID09IG51bGwpIHtcbiAgICAgICAgZW5jb2RpbmcgPSAnYXNjaWknO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGRlY29kZVN0cmluZy5jYWxsKHRoaXMsIDAsIGxlbmd0aCwgZW5jb2RpbmcsIHRydWUpO1xuICAgIH07XG5cbiAgICBTdHJlYW0ucHJvdG90eXBlLnBlZWtTdHJpbmcgPSBmdW5jdGlvbihvZmZzZXQsIGxlbmd0aCwgZW5jb2RpbmcpIHtcbiAgICAgIGlmIChvZmZzZXQgPT0gbnVsbCkge1xuICAgICAgICBvZmZzZXQgPSAwO1xuICAgICAgfVxuICAgICAgaWYgKGVuY29kaW5nID09IG51bGwpIHtcbiAgICAgICAgZW5jb2RpbmcgPSAnYXNjaWknO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGRlY29kZVN0cmluZy5jYWxsKHRoaXMsIG9mZnNldCwgbGVuZ3RoLCBlbmNvZGluZywgZmFsc2UpO1xuICAgIH07XG5cbiAgICBkZWNvZGVTdHJpbmcgPSBmdW5jdGlvbihvZmZzZXQsIGxlbmd0aCwgZW5jb2RpbmcsIGFkdmFuY2UpIHtcbiAgICAgIHZhciBiMSwgYjIsIGIzLCBiNCwgYm9tLCBjLCBlbmQsIGxpdHRsZUVuZGlhbiwgbnVsbEVuZCwgcHQsIHJlc3VsdCwgdzEsIHcyO1xuICAgICAgZW5jb2RpbmcgPSBlbmNvZGluZy50b0xvd2VyQ2FzZSgpO1xuICAgICAgbnVsbEVuZCA9IGxlbmd0aCA9PT0gbnVsbCA/IDAgOiAtMTtcbiAgICAgIGlmIChsZW5ndGggPT0gbnVsbCkge1xuICAgICAgICBsZW5ndGggPSAyZTMwODtcbiAgICAgIH1cbiAgICAgIGVuZCA9IG9mZnNldCArIGxlbmd0aDtcbiAgICAgIHJlc3VsdCA9ICcnO1xuICAgICAgc3dpdGNoIChlbmNvZGluZykge1xuICAgICAgICBjYXNlICdhc2NpaSc6XG4gICAgICAgIGNhc2UgJ2xhdGluMSc6XG4gICAgICAgICAgd2hpbGUgKG9mZnNldCA8IGVuZCAmJiAoYyA9IHRoaXMucGVla1VJbnQ4KG9mZnNldCsrKSkgIT09IG51bGxFbmQpIHtcbiAgICAgICAgICAgIHJlc3VsdCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGMpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAndXRmOCc6XG4gICAgICAgIGNhc2UgJ3V0Zi04JzpcbiAgICAgICAgICB3aGlsZSAob2Zmc2V0IDwgZW5kICYmIChiMSA9IHRoaXMucGVla1VJbnQ4KG9mZnNldCsrKSkgIT09IG51bGxFbmQpIHtcbiAgICAgICAgICAgIGlmICgoYjEgJiAweDgwKSA9PT0gMCkge1xuICAgICAgICAgICAgICByZXN1bHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShiMSk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKChiMSAmIDB4ZTApID09PSAweGMwKSB7XG4gICAgICAgICAgICAgIGIyID0gdGhpcy5wZWVrVUludDgob2Zmc2V0KyspICYgMHgzZjtcbiAgICAgICAgICAgICAgcmVzdWx0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoKChiMSAmIDB4MWYpIDw8IDYpIHwgYjIpO1xuICAgICAgICAgICAgfSBlbHNlIGlmICgoYjEgJiAweGYwKSA9PT0gMHhlMCkge1xuICAgICAgICAgICAgICBiMiA9IHRoaXMucGVla1VJbnQ4KG9mZnNldCsrKSAmIDB4M2Y7XG4gICAgICAgICAgICAgIGIzID0gdGhpcy5wZWVrVUludDgob2Zmc2V0KyspICYgMHgzZjtcbiAgICAgICAgICAgICAgcmVzdWx0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoKChiMSAmIDB4MGYpIDw8IDEyKSB8IChiMiA8PCA2KSB8IGIzKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoKGIxICYgMHhmOCkgPT09IDB4ZjApIHtcbiAgICAgICAgICAgICAgYjIgPSB0aGlzLnBlZWtVSW50OChvZmZzZXQrKykgJiAweDNmO1xuICAgICAgICAgICAgICBiMyA9IHRoaXMucGVla1VJbnQ4KG9mZnNldCsrKSAmIDB4M2Y7XG4gICAgICAgICAgICAgIGI0ID0gdGhpcy5wZWVrVUludDgob2Zmc2V0KyspICYgMHgzZjtcbiAgICAgICAgICAgICAgcHQgPSAoKChiMSAmIDB4MGYpIDw8IDE4KSB8IChiMiA8PCAxMikgfCAoYjMgPDwgNikgfCBiNCkgLSAweDEwMDAwO1xuICAgICAgICAgICAgICByZXN1bHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSgweGQ4MDAgKyAocHQgPj4gMTApLCAweGRjMDAgKyAocHQgJiAweDNmZikpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAndXRmMTYtYmUnOlxuICAgICAgICBjYXNlICd1dGYxNmJlJzpcbiAgICAgICAgY2FzZSAndXRmMTZsZSc6XG4gICAgICAgIGNhc2UgJ3V0ZjE2LWxlJzpcbiAgICAgICAgY2FzZSAndXRmMTZib20nOlxuICAgICAgICBjYXNlICd1dGYxNi1ib20nOlxuICAgICAgICAgIHN3aXRjaCAoZW5jb2RpbmcpIHtcbiAgICAgICAgICAgIGNhc2UgJ3V0ZjE2YmUnOlxuICAgICAgICAgICAgY2FzZSAndXRmMTYtYmUnOlxuICAgICAgICAgICAgICBsaXR0bGVFbmRpYW4gPSBmYWxzZTtcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICd1dGYxNmxlJzpcbiAgICAgICAgICAgIGNhc2UgJ3V0ZjE2LWxlJzpcbiAgICAgICAgICAgICAgbGl0dGxlRW5kaWFuID0gdHJ1ZTtcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICd1dGYxNmJvbSc6XG4gICAgICAgICAgICBjYXNlICd1dGYxNi1ib20nOlxuICAgICAgICAgICAgICBpZiAobGVuZ3RoIDwgMiB8fCAoYm9tID0gdGhpcy5wZWVrVUludDE2KG9mZnNldCkpID09PSBudWxsRW5kKSB7XG4gICAgICAgICAgICAgICAgaWYgKGFkdmFuY2UpIHtcbiAgICAgICAgICAgICAgICAgIHRoaXMuYWR2YW5jZShvZmZzZXQgKz0gMik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgbGl0dGxlRW5kaWFuID0gYm9tID09PSAweGZmZmU7XG4gICAgICAgICAgICAgIG9mZnNldCArPSAyO1xuICAgICAgICAgIH1cbiAgICAgICAgICB3aGlsZSAob2Zmc2V0IDwgZW5kICYmICh3MSA9IHRoaXMucGVla1VJbnQxNihvZmZzZXQsIGxpdHRsZUVuZGlhbikpICE9PSBudWxsRW5kKSB7XG4gICAgICAgICAgICBvZmZzZXQgKz0gMjtcbiAgICAgICAgICAgIGlmICh3MSA8IDB4ZDgwMCB8fCB3MSA+IDB4ZGZmZikge1xuICAgICAgICAgICAgICByZXN1bHQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSh3MSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBpZiAodzEgPiAweGRiZmYpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJJbnZhbGlkIHV0ZjE2IHNlcXVlbmNlLlwiKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB3MiA9IHRoaXMucGVla1VJbnQxNihvZmZzZXQsIGxpdHRsZUVuZGlhbik7XG4gICAgICAgICAgICAgIGlmICh3MiA8IDB4ZGMwMCB8fCB3MiA+IDB4ZGZmZikge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIkludmFsaWQgdXRmMTYgc2VxdWVuY2UuXCIpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHJlc3VsdCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKHcxLCB3Mik7XG4gICAgICAgICAgICAgIG9mZnNldCArPSAyO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAodzEgPT09IG51bGxFbmQpIHtcbiAgICAgICAgICAgIG9mZnNldCArPSAyO1xuICAgICAgICAgIH1cbiAgICAgICAgICBicmVhaztcbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJVbmtub3duIGVuY29kaW5nOiBcIiArIGVuY29kaW5nKTtcbiAgICAgIH1cbiAgICAgIGlmIChhZHZhbmNlKSB7XG4gICAgICAgIHRoaXMuYWR2YW5jZShvZmZzZXQpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9O1xuXG4gICAgcmV0dXJuIFN0cmVhbTtcblxuICB9KSgpO1xuXG4gIG1vZHVsZS5leHBvcnRzID0gU3RyZWFtO1xuXG59KS5jYWxsKHRoaXMpO1xuIiwiLy8gR2VuZXJhdGVkIGJ5IENvZmZlZVNjcmlwdCAxLjEyLjdcbihmdW5jdGlvbigpIHtcbiAgdmFyIFVuZGVyZmxvd0Vycm9yLFxuICAgIGV4dGVuZCA9IGZ1bmN0aW9uKGNoaWxkLCBwYXJlbnQpIHsgZm9yICh2YXIga2V5IGluIHBhcmVudCkgeyBpZiAoaGFzUHJvcC5jYWxsKHBhcmVudCwga2V5KSkgY2hpbGRba2V5XSA9IHBhcmVudFtrZXldOyB9IGZ1bmN0aW9uIGN0b3IoKSB7IHRoaXMuY29uc3RydWN0b3IgPSBjaGlsZDsgfSBjdG9yLnByb3RvdHlwZSA9IHBhcmVudC5wcm90b3R5cGU7IGNoaWxkLnByb3RvdHlwZSA9IG5ldyBjdG9yKCk7IGNoaWxkLl9fc3VwZXJfXyA9IHBhcmVudC5wcm90b3R5cGU7IHJldHVybiBjaGlsZDsgfSxcbiAgICBoYXNQcm9wID0ge30uaGFzT3duUHJvcGVydHk7XG5cbiAgVW5kZXJmbG93RXJyb3IgPSAoZnVuY3Rpb24oc3VwZXJDbGFzcykge1xuICAgIGV4dGVuZChVbmRlcmZsb3dFcnJvciwgc3VwZXJDbGFzcyk7XG5cbiAgICBmdW5jdGlvbiBVbmRlcmZsb3dFcnJvcigpIHtcbiAgICAgIFVuZGVyZmxvd0Vycm9yLl9fc3VwZXJfXy5jb25zdHJ1Y3Rvci5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgdGhpcy5uYW1lID0gJ1VuZGVyZmxvd0Vycm9yJztcbiAgICAgIHRoaXMuc3RhY2sgPSBuZXcgRXJyb3IoKS5zdGFjaztcbiAgICB9XG5cbiAgICByZXR1cm4gVW5kZXJmbG93RXJyb3I7XG5cbiAgfSkoRXJyb3IpO1xuXG4gIG1vZHVsZS5leHBvcnRzID0gVW5kZXJmbG93RXJyb3I7XG5cbn0pLmNhbGwodGhpcyk7XG4iLCIvLyBHZW5lcmF0ZWQgYnkgQ29mZmVlU2NyaXB0IDEuMTIuN1xuKGZ1bmN0aW9uKCkge1xuICB2YXIgQml0c3RyZWFtLCBCdWZmZXJMaXN0LCBEZWNvZGVyLCBFdmVudEVtaXR0ZXIsIFN0cmVhbSwgVW5kZXJmbG93RXJyb3IsXG4gICAgZXh0ZW5kID0gZnVuY3Rpb24oY2hpbGQsIHBhcmVudCkgeyBmb3IgKHZhciBrZXkgaW4gcGFyZW50KSB7IGlmIChoYXNQcm9wLmNhbGwocGFyZW50LCBrZXkpKSBjaGlsZFtrZXldID0gcGFyZW50W2tleV07IH0gZnVuY3Rpb24gY3RvcigpIHsgdGhpcy5jb25zdHJ1Y3RvciA9IGNoaWxkOyB9IGN0b3IucHJvdG90eXBlID0gcGFyZW50LnByb3RvdHlwZTsgY2hpbGQucHJvdG90eXBlID0gbmV3IGN0b3IoKTsgY2hpbGQuX19zdXBlcl9fID0gcGFyZW50LnByb3RvdHlwZTsgcmV0dXJuIGNoaWxkOyB9LFxuICAgIGhhc1Byb3AgPSB7fS5oYXNPd25Qcm9wZXJ0eTtcblxuICBFdmVudEVtaXR0ZXIgPSByZXF1aXJlKCcuL2NvcmUvZXZlbnRzJyk7XG5cbiAgQnVmZmVyTGlzdCA9IHJlcXVpcmUoJy4vY29yZS9idWZmZXJsaXN0Jyk7XG5cbiAgU3RyZWFtID0gcmVxdWlyZSgnLi9jb3JlL3N0cmVhbScpO1xuXG4gIEJpdHN0cmVhbSA9IHJlcXVpcmUoJy4vY29yZS9iaXRzdHJlYW0nKTtcblxuICBVbmRlcmZsb3dFcnJvciA9IHJlcXVpcmUoJy4vY29yZS91bmRlcmZsb3cnKTtcblxuICBEZWNvZGVyID0gKGZ1bmN0aW9uKHN1cGVyQ2xhc3MpIHtcbiAgICB2YXIgY29kZWNzO1xuXG4gICAgZXh0ZW5kKERlY29kZXIsIHN1cGVyQ2xhc3MpO1xuXG4gICAgZnVuY3Rpb24gRGVjb2RlcihkZW11eGVyLCBmb3JtYXQpIHtcbiAgICAgIHZhciBsaXN0O1xuICAgICAgdGhpcy5kZW11eGVyID0gZGVtdXhlcjtcbiAgICAgIHRoaXMuZm9ybWF0ID0gZm9ybWF0O1xuICAgICAgbGlzdCA9IG5ldyBCdWZmZXJMaXN0O1xuICAgICAgdGhpcy5zdHJlYW0gPSBuZXcgU3RyZWFtKGxpc3QpO1xuICAgICAgdGhpcy5iaXRzdHJlYW0gPSBuZXcgQml0c3RyZWFtKHRoaXMuc3RyZWFtKTtcbiAgICAgIHRoaXMucmVjZWl2ZWRGaW5hbEJ1ZmZlciA9IGZhbHNlO1xuICAgICAgdGhpcy53YWl0aW5nID0gZmFsc2U7XG4gICAgICB0aGlzLmRlbXV4ZXIub24oJ2Nvb2tpZScsIChmdW5jdGlvbihfdGhpcykge1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24oY29va2llKSB7XG4gICAgICAgICAgdmFyIGVycm9yO1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICByZXR1cm4gX3RoaXMuc2V0Q29va2llKGNvb2tpZSk7XG4gICAgICAgICAgfSBjYXRjaCAoZXJyb3IxKSB7XG4gICAgICAgICAgICBlcnJvciA9IGVycm9yMTtcbiAgICAgICAgICAgIHJldHVybiBfdGhpcy5lbWl0KCdlcnJvcicsIGVycm9yKTtcbiAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICB9KSh0aGlzKSk7XG4gICAgICB0aGlzLmRlbXV4ZXIub24oJ2RhdGEnLCAoZnVuY3Rpb24oX3RoaXMpIHtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKGNodW5rKSB7XG4gICAgICAgICAgbGlzdC5hcHBlbmQoY2h1bmspO1xuICAgICAgICAgIGlmIChfdGhpcy53YWl0aW5nKSB7XG4gICAgICAgICAgICByZXR1cm4gX3RoaXMuZGVjb2RlKCk7XG4gICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgfSkodGhpcykpO1xuICAgICAgdGhpcy5kZW11eGVyLm9uKCdlbmQnLCAoZnVuY3Rpb24oX3RoaXMpIHtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgICAgICAgIF90aGlzLnJlY2VpdmVkRmluYWxCdWZmZXIgPSB0cnVlO1xuICAgICAgICAgIGlmIChfdGhpcy53YWl0aW5nKSB7XG4gICAgICAgICAgICByZXR1cm4gX3RoaXMuZGVjb2RlKCk7XG4gICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgfSkodGhpcykpO1xuICAgICAgdGhpcy5pbml0KCk7XG4gICAgfVxuXG4gICAgRGVjb2Rlci5wcm90b3R5cGUuaW5pdCA9IGZ1bmN0aW9uKCkge307XG5cbiAgICBEZWNvZGVyLnByb3RvdHlwZS5zZXRDb29raWUgPSBmdW5jdGlvbihjb29raWUpIHt9O1xuXG4gICAgRGVjb2Rlci5wcm90b3R5cGUucmVhZENodW5rID0gZnVuY3Rpb24oKSB7fTtcblxuICAgIERlY29kZXIucHJvdG90eXBlLmRlY29kZSA9IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIGVycm9yLCBvZmZzZXQsIHBhY2tldDtcbiAgICAgIHRoaXMud2FpdGluZyA9ICF0aGlzLnJlY2VpdmVkRmluYWxCdWZmZXI7XG4gICAgICBvZmZzZXQgPSB0aGlzLmJpdHN0cmVhbS5vZmZzZXQoKTtcbiAgICAgIHRyeSB7XG4gICAgICAgIHBhY2tldCA9IHRoaXMucmVhZENodW5rKCk7XG4gICAgICB9IGNhdGNoIChlcnJvcjEpIHtcbiAgICAgICAgZXJyb3IgPSBlcnJvcjE7XG4gICAgICAgIGlmICghKGVycm9yIGluc3RhbmNlb2YgVW5kZXJmbG93RXJyb3IpKSB7XG4gICAgICAgICAgdGhpcy5lbWl0KCdlcnJvcicsIGVycm9yKTtcbiAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChwYWNrZXQpIHtcbiAgICAgICAgdGhpcy5lbWl0KCdkYXRhJywgcGFja2V0KTtcbiAgICAgICAgaWYgKHRoaXMucmVjZWl2ZWRGaW5hbEJ1ZmZlcikge1xuICAgICAgICAgIHRoaXMuZW1pdCgnZW5kJyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9IGVsc2UgaWYgKCF0aGlzLnJlY2VpdmVkRmluYWxCdWZmZXIpIHtcbiAgICAgICAgdGhpcy5iaXRzdHJlYW0uc2VlayhvZmZzZXQpO1xuICAgICAgICB0aGlzLndhaXRpbmcgPSB0cnVlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5lbWl0KCdlbmQnKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9O1xuXG4gICAgRGVjb2Rlci5wcm90b3R5cGUuc2VlayA9IGZ1bmN0aW9uKHRpbWVzdGFtcCkge1xuICAgICAgdmFyIHNlZWtQb2ludDtcbiAgICAgIHNlZWtQb2ludCA9IHRoaXMuZGVtdXhlci5zZWVrKHRpbWVzdGFtcCk7XG4gICAgICB0aGlzLnN0cmVhbS5zZWVrKHNlZWtQb2ludC5vZmZzZXQpO1xuICAgICAgcmV0dXJuIHNlZWtQb2ludC50aW1lc3RhbXA7XG4gICAgfTtcblxuICAgIGNvZGVjcyA9IHt9O1xuXG4gICAgRGVjb2Rlci5yZWdpc3RlciA9IGZ1bmN0aW9uKGlkLCBkZWNvZGVyKSB7XG4gICAgICByZXR1cm4gY29kZWNzW2lkXSA9IGRlY29kZXI7XG4gICAgfTtcblxuICAgIERlY29kZXIuZmluZCA9IGZ1bmN0aW9uKGlkKSB7XG4gICAgICByZXR1cm4gY29kZWNzW2lkXSB8fCBudWxsO1xuICAgIH07XG5cbiAgICByZXR1cm4gRGVjb2RlcjtcblxuICB9KShFdmVudEVtaXR0ZXIpO1xuXG4gIG1vZHVsZS5leHBvcnRzID0gRGVjb2RlcjtcblxufSkuY2FsbCh0aGlzKTtcbiIsIi8vIEdlbmVyYXRlZCBieSBDb2ZmZWVTY3JpcHQgMS4xMi43XG4oZnVuY3Rpb24oKSB7XG4gIHZhciBEZWNvZGVyLCBMUENNRGVjb2RlcixcbiAgICBiaW5kID0gZnVuY3Rpb24oZm4sIG1lKXsgcmV0dXJuIGZ1bmN0aW9uKCl7IHJldHVybiBmbi5hcHBseShtZSwgYXJndW1lbnRzKTsgfTsgfSxcbiAgICBleHRlbmQgPSBmdW5jdGlvbihjaGlsZCwgcGFyZW50KSB7IGZvciAodmFyIGtleSBpbiBwYXJlbnQpIHsgaWYgKGhhc1Byb3AuY2FsbChwYXJlbnQsIGtleSkpIGNoaWxkW2tleV0gPSBwYXJlbnRba2V5XTsgfSBmdW5jdGlvbiBjdG9yKCkgeyB0aGlzLmNvbnN0cnVjdG9yID0gY2hpbGQ7IH0gY3Rvci5wcm90b3R5cGUgPSBwYXJlbnQucHJvdG90eXBlOyBjaGlsZC5wcm90b3R5cGUgPSBuZXcgY3RvcigpOyBjaGlsZC5fX3N1cGVyX18gPSBwYXJlbnQucHJvdG90eXBlOyByZXR1cm4gY2hpbGQ7IH0sXG4gICAgaGFzUHJvcCA9IHt9Lmhhc093blByb3BlcnR5O1xuXG4gIERlY29kZXIgPSByZXF1aXJlKCcuLi9kZWNvZGVyJyk7XG5cbiAgTFBDTURlY29kZXIgPSAoZnVuY3Rpb24oc3VwZXJDbGFzcykge1xuICAgIGV4dGVuZChMUENNRGVjb2Rlciwgc3VwZXJDbGFzcyk7XG5cbiAgICBmdW5jdGlvbiBMUENNRGVjb2RlcigpIHtcbiAgICAgIHRoaXMucmVhZENodW5rID0gYmluZCh0aGlzLnJlYWRDaHVuaywgdGhpcyk7XG4gICAgICByZXR1cm4gTFBDTURlY29kZXIuX19zdXBlcl9fLmNvbnN0cnVjdG9yLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgfVxuXG4gICAgRGVjb2Rlci5yZWdpc3RlcignbHBjbScsIExQQ01EZWNvZGVyKTtcblxuICAgIExQQ01EZWNvZGVyLnByb3RvdHlwZS5yZWFkQ2h1bmsgPSBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBjaHVua1NpemUsIGksIGosIGssIGwsIGxpdHRsZUVuZGlhbiwgbSwgbiwgbywgb3V0cHV0LCByZWYsIHJlZjEsIHJlZjIsIHJlZjMsIHJlZjQsIHJlZjUsIHNhbXBsZXMsIHN0cmVhbTtcbiAgICAgIHN0cmVhbSA9IHRoaXMuc3RyZWFtO1xuICAgICAgbGl0dGxlRW5kaWFuID0gdGhpcy5mb3JtYXQubGl0dGxlRW5kaWFuO1xuICAgICAgY2h1bmtTaXplID0gTWF0aC5taW4oNDA5Niwgc3RyZWFtLnJlbWFpbmluZ0J5dGVzKCkpO1xuICAgICAgc2FtcGxlcyA9IGNodW5rU2l6ZSAvICh0aGlzLmZvcm1hdC5iaXRzUGVyQ2hhbm5lbCAvIDgpIHwgMDtcbiAgICAgIGlmIChjaHVua1NpemUgPCB0aGlzLmZvcm1hdC5iaXRzUGVyQ2hhbm5lbCAvIDgpIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9XG4gICAgICBpZiAodGhpcy5mb3JtYXQuZmxvYXRpbmdQb2ludCkge1xuICAgICAgICBzd2l0Y2ggKHRoaXMuZm9ybWF0LmJpdHNQZXJDaGFubmVsKSB7XG4gICAgICAgICAgY2FzZSAzMjpcbiAgICAgICAgICAgIG91dHB1dCA9IG5ldyBGbG9hdDMyQXJyYXkoc2FtcGxlcyk7XG4gICAgICAgICAgICBmb3IgKGkgPSBqID0gMCwgcmVmID0gc2FtcGxlczsgaiA8IHJlZjsgaSA9IGogKz0gMSkge1xuICAgICAgICAgICAgICBvdXRwdXRbaV0gPSBzdHJlYW0ucmVhZEZsb2F0MzIobGl0dGxlRW5kaWFuKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIGNhc2UgNjQ6XG4gICAgICAgICAgICBvdXRwdXQgPSBuZXcgRmxvYXQ2NEFycmF5KHNhbXBsZXMpO1xuICAgICAgICAgICAgZm9yIChpID0gayA9IDAsIHJlZjEgPSBzYW1wbGVzOyBrIDwgcmVmMTsgaSA9IGsgKz0gMSkge1xuICAgICAgICAgICAgICBvdXRwdXRbaV0gPSBzdHJlYW0ucmVhZEZsb2F0NjQobGl0dGxlRW5kaWFuKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1Vuc3VwcG9ydGVkIGJpdCBkZXB0aC4nKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc3dpdGNoICh0aGlzLmZvcm1hdC5iaXRzUGVyQ2hhbm5lbCkge1xuICAgICAgICAgIGNhc2UgODpcbiAgICAgICAgICAgIG91dHB1dCA9IG5ldyBJbnQ4QXJyYXkoc2FtcGxlcyk7XG4gICAgICAgICAgICBmb3IgKGkgPSBsID0gMCwgcmVmMiA9IHNhbXBsZXM7IGwgPCByZWYyOyBpID0gbCArPSAxKSB7XG4gICAgICAgICAgICAgIG91dHB1dFtpXSA9IHN0cmVhbS5yZWFkSW50OCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgY2FzZSAxNjpcbiAgICAgICAgICAgIG91dHB1dCA9IG5ldyBJbnQxNkFycmF5KHNhbXBsZXMpO1xuICAgICAgICAgICAgZm9yIChpID0gbSA9IDAsIHJlZjMgPSBzYW1wbGVzOyBtIDwgcmVmMzsgaSA9IG0gKz0gMSkge1xuICAgICAgICAgICAgICBvdXRwdXRbaV0gPSBzdHJlYW0ucmVhZEludDE2KGxpdHRsZUVuZGlhbik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICBjYXNlIDI0OlxuICAgICAgICAgICAgb3V0cHV0ID0gbmV3IEludDMyQXJyYXkoc2FtcGxlcyk7XG4gICAgICAgICAgICBmb3IgKGkgPSBuID0gMCwgcmVmNCA9IHNhbXBsZXM7IG4gPCByZWY0OyBpID0gbiArPSAxKSB7XG4gICAgICAgICAgICAgIG91dHB1dFtpXSA9IHN0cmVhbS5yZWFkSW50MjQobGl0dGxlRW5kaWFuKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIGNhc2UgMzI6XG4gICAgICAgICAgICBvdXRwdXQgPSBuZXcgSW50MzJBcnJheShzYW1wbGVzKTtcbiAgICAgICAgICAgIGZvciAoaSA9IG8gPSAwLCByZWY1ID0gc2FtcGxlczsgbyA8IHJlZjU7IGkgPSBvICs9IDEpIHtcbiAgICAgICAgICAgICAgb3V0cHV0W2ldID0gc3RyZWFtLnJlYWRJbnQzMihsaXR0bGVFbmRpYW4pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignVW5zdXBwb3J0ZWQgYml0IGRlcHRoLicpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gb3V0cHV0O1xuICAgIH07XG5cbiAgICByZXR1cm4gTFBDTURlY29kZXI7XG5cbiAgfSkoRGVjb2Rlcik7XG5cbn0pLmNhbGwodGhpcyk7XG4iLCIvLyBHZW5lcmF0ZWQgYnkgQ29mZmVlU2NyaXB0IDEuMTIuN1xuKGZ1bmN0aW9uKCkge1xuICB2YXIgRGVjb2RlciwgWExBV0RlY29kZXIsXG4gICAgYmluZCA9IGZ1bmN0aW9uKGZuLCBtZSl7IHJldHVybiBmdW5jdGlvbigpeyByZXR1cm4gZm4uYXBwbHkobWUsIGFyZ3VtZW50cyk7IH07IH0sXG4gICAgZXh0ZW5kID0gZnVuY3Rpb24oY2hpbGQsIHBhcmVudCkgeyBmb3IgKHZhciBrZXkgaW4gcGFyZW50KSB7IGlmIChoYXNQcm9wLmNhbGwocGFyZW50LCBrZXkpKSBjaGlsZFtrZXldID0gcGFyZW50W2tleV07IH0gZnVuY3Rpb24gY3RvcigpIHsgdGhpcy5jb25zdHJ1Y3RvciA9IGNoaWxkOyB9IGN0b3IucHJvdG90eXBlID0gcGFyZW50LnByb3RvdHlwZTsgY2hpbGQucHJvdG90eXBlID0gbmV3IGN0b3IoKTsgY2hpbGQuX19zdXBlcl9fID0gcGFyZW50LnByb3RvdHlwZTsgcmV0dXJuIGNoaWxkOyB9LFxuICAgIGhhc1Byb3AgPSB7fS5oYXNPd25Qcm9wZXJ0eTtcblxuICBEZWNvZGVyID0gcmVxdWlyZSgnLi4vZGVjb2RlcicpO1xuXG4gIFhMQVdEZWNvZGVyID0gKGZ1bmN0aW9uKHN1cGVyQ2xhc3MpIHtcbiAgICB2YXIgQklBUywgUVVBTlRfTUFTSywgU0VHX01BU0ssIFNFR19TSElGVCwgU0lHTl9CSVQ7XG5cbiAgICBleHRlbmQoWExBV0RlY29kZXIsIHN1cGVyQ2xhc3MpO1xuXG4gICAgZnVuY3Rpb24gWExBV0RlY29kZXIoKSB7XG4gICAgICB0aGlzLnJlYWRDaHVuayA9IGJpbmQodGhpcy5yZWFkQ2h1bmssIHRoaXMpO1xuICAgICAgcmV0dXJuIFhMQVdEZWNvZGVyLl9fc3VwZXJfXy5jb25zdHJ1Y3Rvci5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgIH1cblxuICAgIERlY29kZXIucmVnaXN0ZXIoJ3VsYXcnLCBYTEFXRGVjb2Rlcik7XG5cbiAgICBEZWNvZGVyLnJlZ2lzdGVyKCdhbGF3JywgWExBV0RlY29kZXIpO1xuXG4gICAgU0lHTl9CSVQgPSAweDgwO1xuXG4gICAgUVVBTlRfTUFTSyA9IDB4ZjtcblxuICAgIFNFR19TSElGVCA9IDQ7XG5cbiAgICBTRUdfTUFTSyA9IDB4NzA7XG5cbiAgICBCSUFTID0gMHg4NDtcblxuICAgIFhMQVdEZWNvZGVyLnByb3RvdHlwZS5pbml0ID0gZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgaSwgaiwgaywgc2VnLCB0LCB0YWJsZSwgdmFsO1xuICAgICAgdGhpcy5mb3JtYXQuYml0c1BlckNoYW5uZWwgPSAxNjtcbiAgICAgIHRoaXMudGFibGUgPSB0YWJsZSA9IG5ldyBJbnQxNkFycmF5KDI1Nik7XG4gICAgICBpZiAodGhpcy5mb3JtYXQuZm9ybWF0SUQgPT09ICd1bGF3Jykge1xuICAgICAgICBmb3IgKGkgPSBqID0gMDsgaiA8IDI1NjsgaSA9ICsraikge1xuICAgICAgICAgIHZhbCA9IH5pO1xuICAgICAgICAgIHQgPSAoKHZhbCAmIFFVQU5UX01BU0spIDw8IDMpICsgQklBUztcbiAgICAgICAgICB0IDw8PSAodmFsICYgU0VHX01BU0spID4+PiBTRUdfU0hJRlQ7XG4gICAgICAgICAgdGFibGVbaV0gPSB2YWwgJiBTSUdOX0JJVCA/IEJJQVMgLSB0IDogdCAtIEJJQVM7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGZvciAoaSA9IGsgPSAwOyBrIDwgMjU2OyBpID0gKytrKSB7XG4gICAgICAgICAgdmFsID0gaSBeIDB4NTU7XG4gICAgICAgICAgdCA9IHZhbCAmIFFVQU5UX01BU0s7XG4gICAgICAgICAgc2VnID0gKHZhbCAmIFNFR19NQVNLKSA+Pj4gU0VHX1NISUZUO1xuICAgICAgICAgIGlmIChzZWcpIHtcbiAgICAgICAgICAgIHQgPSAodCArIHQgKyAxICsgMzIpIDw8IChzZWcgKyAyKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdCA9ICh0ICsgdCArIDEpIDw8IDM7XG4gICAgICAgICAgfVxuICAgICAgICAgIHRhYmxlW2ldID0gdmFsICYgU0lHTl9CSVQgPyB0IDogLXQ7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9O1xuXG4gICAgWExBV0RlY29kZXIucHJvdG90eXBlLnJlYWRDaHVuayA9IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIGksIGosIG91dHB1dCwgcmVmLCByZWYxLCBzYW1wbGVzLCBzdHJlYW0sIHRhYmxlO1xuICAgICAgcmVmID0gdGhpcywgc3RyZWFtID0gcmVmLnN0cmVhbSwgdGFibGUgPSByZWYudGFibGU7XG4gICAgICBzYW1wbGVzID0gTWF0aC5taW4oNDA5NiwgdGhpcy5zdHJlYW0ucmVtYWluaW5nQnl0ZXMoKSk7XG4gICAgICBpZiAoc2FtcGxlcyA9PT0gMCkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBvdXRwdXQgPSBuZXcgSW50MTZBcnJheShzYW1wbGVzKTtcbiAgICAgIGZvciAoaSA9IGogPSAwLCByZWYxID0gc2FtcGxlczsgaiA8IHJlZjE7IGkgPSBqICs9IDEpIHtcbiAgICAgICAgb3V0cHV0W2ldID0gdGFibGVbc3RyZWFtLnJlYWRVSW50OCgpXTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBvdXRwdXQ7XG4gICAgfTtcblxuICAgIHJldHVybiBYTEFXRGVjb2RlcjtcblxuICB9KShEZWNvZGVyKTtcblxufSkuY2FsbCh0aGlzKTtcbiIsIi8vIEdlbmVyYXRlZCBieSBDb2ZmZWVTY3JpcHQgMS4xMi43XG4oZnVuY3Rpb24oKSB7XG4gIHZhciBCdWZmZXJMaXN0LCBEZW11eGVyLCBFdmVudEVtaXR0ZXIsIFN0cmVhbSxcbiAgICBleHRlbmQgPSBmdW5jdGlvbihjaGlsZCwgcGFyZW50KSB7IGZvciAodmFyIGtleSBpbiBwYXJlbnQpIHsgaWYgKGhhc1Byb3AuY2FsbChwYXJlbnQsIGtleSkpIGNoaWxkW2tleV0gPSBwYXJlbnRba2V5XTsgfSBmdW5jdGlvbiBjdG9yKCkgeyB0aGlzLmNvbnN0cnVjdG9yID0gY2hpbGQ7IH0gY3Rvci5wcm90b3R5cGUgPSBwYXJlbnQucHJvdG90eXBlOyBjaGlsZC5wcm90b3R5cGUgPSBuZXcgY3RvcigpOyBjaGlsZC5fX3N1cGVyX18gPSBwYXJlbnQucHJvdG90eXBlOyByZXR1cm4gY2hpbGQ7IH0sXG4gICAgaGFzUHJvcCA9IHt9Lmhhc093blByb3BlcnR5O1xuXG4gIEV2ZW50RW1pdHRlciA9IHJlcXVpcmUoJy4vY29yZS9ldmVudHMnKTtcblxuICBCdWZmZXJMaXN0ID0gcmVxdWlyZSgnLi9jb3JlL2J1ZmZlcmxpc3QnKTtcblxuICBTdHJlYW0gPSByZXF1aXJlKCcuL2NvcmUvc3RyZWFtJyk7XG5cbiAgRGVtdXhlciA9IChmdW5jdGlvbihzdXBlckNsYXNzKSB7XG4gICAgdmFyIGZvcm1hdHM7XG5cbiAgICBleHRlbmQoRGVtdXhlciwgc3VwZXJDbGFzcyk7XG5cbiAgICBEZW11eGVyLnByb2JlID0gZnVuY3Rpb24oYnVmZmVyKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfTtcblxuICAgIGZ1bmN0aW9uIERlbXV4ZXIoc291cmNlLCBjaHVuaykge1xuICAgICAgdmFyIGxpc3QsIHJlY2VpdmVkO1xuICAgICAgbGlzdCA9IG5ldyBCdWZmZXJMaXN0O1xuICAgICAgbGlzdC5hcHBlbmQoY2h1bmspO1xuICAgICAgdGhpcy5zdHJlYW0gPSBuZXcgU3RyZWFtKGxpc3QpO1xuICAgICAgcmVjZWl2ZWQgPSBmYWxzZTtcbiAgICAgIHNvdXJjZS5vbignZGF0YScsIChmdW5jdGlvbihfdGhpcykge1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24oY2h1bmspIHtcbiAgICAgICAgICB2YXIgZTtcbiAgICAgICAgICByZWNlaXZlZCA9IHRydWU7XG4gICAgICAgICAgbGlzdC5hcHBlbmQoY2h1bmspO1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICByZXR1cm4gX3RoaXMucmVhZENodW5rKGNodW5rKTtcbiAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgZSA9IGVycm9yO1xuICAgICAgICAgICAgcmV0dXJuIF90aGlzLmVtaXQoJ2Vycm9yJywgZSk7XG4gICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgfSkodGhpcykpO1xuICAgICAgc291cmNlLm9uKCdlcnJvcicsIChmdW5jdGlvbihfdGhpcykge1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24oZXJyKSB7XG4gICAgICAgICAgcmV0dXJuIF90aGlzLmVtaXQoJ2Vycm9yJywgZXJyKTtcbiAgICAgICAgfTtcbiAgICAgIH0pKHRoaXMpKTtcbiAgICAgIHNvdXJjZS5vbignZW5kJywgKGZ1bmN0aW9uKF90aGlzKSB7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICAgICAgICBpZiAoIXJlY2VpdmVkKSB7XG4gICAgICAgICAgICBfdGhpcy5yZWFkQ2h1bmsoY2h1bmspO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gX3RoaXMuZW1pdCgnZW5kJyk7XG4gICAgICAgIH07XG4gICAgICB9KSh0aGlzKSk7XG4gICAgICB0aGlzLnNlZWtQb2ludHMgPSBbXTtcbiAgICAgIHRoaXMuaW5pdCgpO1xuICAgIH1cblxuICAgIERlbXV4ZXIucHJvdG90eXBlLmluaXQgPSBmdW5jdGlvbigpIHt9O1xuXG4gICAgRGVtdXhlci5wcm90b3R5cGUucmVhZENodW5rID0gZnVuY3Rpb24oY2h1bmspIHt9O1xuXG4gICAgRGVtdXhlci5wcm90b3R5cGUuYWRkU2Vla1BvaW50ID0gZnVuY3Rpb24ob2Zmc2V0LCB0aW1lc3RhbXApIHtcbiAgICAgIHZhciBpbmRleDtcbiAgICAgIGluZGV4ID0gdGhpcy5zZWFyY2hUaW1lc3RhbXAodGltZXN0YW1wKTtcbiAgICAgIHJldHVybiB0aGlzLnNlZWtQb2ludHMuc3BsaWNlKGluZGV4LCAwLCB7XG4gICAgICAgIG9mZnNldDogb2Zmc2V0LFxuICAgICAgICB0aW1lc3RhbXA6IHRpbWVzdGFtcFxuICAgICAgfSk7XG4gICAgfTtcblxuICAgIERlbXV4ZXIucHJvdG90eXBlLnNlYXJjaFRpbWVzdGFtcCA9IGZ1bmN0aW9uKHRpbWVzdGFtcCwgYmFja3dhcmQpIHtcbiAgICAgIHZhciBoaWdoLCBsb3csIG1pZCwgdGltZTtcbiAgICAgIGxvdyA9IDA7XG4gICAgICBoaWdoID0gdGhpcy5zZWVrUG9pbnRzLmxlbmd0aDtcbiAgICAgIGlmIChoaWdoID4gMCAmJiB0aGlzLnNlZWtQb2ludHNbaGlnaCAtIDFdLnRpbWVzdGFtcCA8IHRpbWVzdGFtcCkge1xuICAgICAgICByZXR1cm4gaGlnaDtcbiAgICAgIH1cbiAgICAgIHdoaWxlIChsb3cgPCBoaWdoKSB7XG4gICAgICAgIG1pZCA9IChsb3cgKyBoaWdoKSA+PiAxO1xuICAgICAgICB0aW1lID0gdGhpcy5zZWVrUG9pbnRzW21pZF0udGltZXN0YW1wO1xuICAgICAgICBpZiAodGltZSA8IHRpbWVzdGFtcCkge1xuICAgICAgICAgIGxvdyA9IG1pZCArIDE7XG4gICAgICAgIH0gZWxzZSBpZiAodGltZSA+PSB0aW1lc3RhbXApIHtcbiAgICAgICAgICBoaWdoID0gbWlkO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAoaGlnaCA+IHRoaXMuc2Vla1BvaW50cy5sZW5ndGgpIHtcbiAgICAgICAgaGlnaCA9IHRoaXMuc2Vla1BvaW50cy5sZW5ndGg7XG4gICAgICB9XG4gICAgICByZXR1cm4gaGlnaDtcbiAgICB9O1xuXG4gICAgRGVtdXhlci5wcm90b3R5cGUuc2VlayA9IGZ1bmN0aW9uKHRpbWVzdGFtcCkge1xuICAgICAgdmFyIGluZGV4LCBzZWVrUG9pbnQ7XG4gICAgICBpZiAodGhpcy5mb3JtYXQgJiYgdGhpcy5mb3JtYXQuZnJhbWVzUGVyUGFja2V0ID4gMCAmJiB0aGlzLmZvcm1hdC5ieXRlc1BlclBhY2tldCA+IDApIHtcbiAgICAgICAgc2Vla1BvaW50ID0ge1xuICAgICAgICAgIHRpbWVzdGFtcDogdGltZXN0YW1wLFxuICAgICAgICAgIG9mZnNldDogdGhpcy5mb3JtYXQuYnl0ZXNQZXJQYWNrZXQgKiB0aW1lc3RhbXAgLyB0aGlzLmZvcm1hdC5mcmFtZXNQZXJQYWNrZXRcbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIHNlZWtQb2ludDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGluZGV4ID0gdGhpcy5zZWFyY2hUaW1lc3RhbXAodGltZXN0YW1wKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuc2Vla1BvaW50c1tpbmRleF07XG4gICAgICB9XG4gICAgfTtcblxuICAgIGZvcm1hdHMgPSBbXTtcblxuICAgIERlbXV4ZXIucmVnaXN0ZXIgPSBmdW5jdGlvbihkZW11eGVyKSB7XG4gICAgICByZXR1cm4gZm9ybWF0cy5wdXNoKGRlbXV4ZXIpO1xuICAgIH07XG5cbiAgICBEZW11eGVyLmZpbmQgPSBmdW5jdGlvbihidWZmZXIpIHtcbiAgICAgIHZhciBlLCBmb3JtYXQsIGksIGxlbiwgb2Zmc2V0LCBzdHJlYW07XG4gICAgICBzdHJlYW0gPSBTdHJlYW0uZnJvbUJ1ZmZlcihidWZmZXIpO1xuICAgICAgZm9yIChpID0gMCwgbGVuID0gZm9ybWF0cy5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgICAgICBmb3JtYXQgPSBmb3JtYXRzW2ldO1xuICAgICAgICBvZmZzZXQgPSBzdHJlYW0ub2Zmc2V0O1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGlmIChmb3JtYXQucHJvYmUoc3RyZWFtKSkge1xuICAgICAgICAgICAgcmV0dXJuIGZvcm1hdDtcbiAgICAgICAgICB9XG4gICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgZSA9IGVycm9yO1xuICAgICAgICB9XG4gICAgICAgIHN0cmVhbS5zZWVrKG9mZnNldCk7XG4gICAgICB9XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9O1xuXG4gICAgcmV0dXJuIERlbXV4ZXI7XG5cbiAgfSkoRXZlbnRFbWl0dGVyKTtcblxuICBtb2R1bGUuZXhwb3J0cyA9IERlbXV4ZXI7XG5cbn0pLmNhbGwodGhpcyk7XG4iLCIvLyBHZW5lcmF0ZWQgYnkgQ29mZmVlU2NyaXB0IDEuMTIuN1xuKGZ1bmN0aW9uKCkge1xuICB2YXIgQUlGRkRlbXV4ZXIsIERlbXV4ZXIsXG4gICAgZXh0ZW5kID0gZnVuY3Rpb24oY2hpbGQsIHBhcmVudCkgeyBmb3IgKHZhciBrZXkgaW4gcGFyZW50KSB7IGlmIChoYXNQcm9wLmNhbGwocGFyZW50LCBrZXkpKSBjaGlsZFtrZXldID0gcGFyZW50W2tleV07IH0gZnVuY3Rpb24gY3RvcigpIHsgdGhpcy5jb25zdHJ1Y3RvciA9IGNoaWxkOyB9IGN0b3IucHJvdG90eXBlID0gcGFyZW50LnByb3RvdHlwZTsgY2hpbGQucHJvdG90eXBlID0gbmV3IGN0b3IoKTsgY2hpbGQuX19zdXBlcl9fID0gcGFyZW50LnByb3RvdHlwZTsgcmV0dXJuIGNoaWxkOyB9LFxuICAgIGhhc1Byb3AgPSB7fS5oYXNPd25Qcm9wZXJ0eTtcblxuICBEZW11eGVyID0gcmVxdWlyZSgnLi4vZGVtdXhlcicpO1xuXG4gIEFJRkZEZW11eGVyID0gKGZ1bmN0aW9uKHN1cGVyQ2xhc3MpIHtcbiAgICBleHRlbmQoQUlGRkRlbXV4ZXIsIHN1cGVyQ2xhc3MpO1xuXG4gICAgZnVuY3Rpb24gQUlGRkRlbXV4ZXIoKSB7XG4gICAgICByZXR1cm4gQUlGRkRlbXV4ZXIuX19zdXBlcl9fLmNvbnN0cnVjdG9yLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgfVxuXG4gICAgRGVtdXhlci5yZWdpc3RlcihBSUZGRGVtdXhlcik7XG5cbiAgICBBSUZGRGVtdXhlci5wcm9iZSA9IGZ1bmN0aW9uKGJ1ZmZlcikge1xuICAgICAgdmFyIHJlZjtcbiAgICAgIHJldHVybiBidWZmZXIucGVla1N0cmluZygwLCA0KSA9PT0gJ0ZPUk0nICYmICgocmVmID0gYnVmZmVyLnBlZWtTdHJpbmcoOCwgNCkpID09PSAnQUlGRicgfHwgcmVmID09PSAnQUlGQycpO1xuICAgIH07XG5cbiAgICBBSUZGRGVtdXhlci5wcm90b3R5cGUucmVhZENodW5rID0gZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgYnVmZmVyLCBmb3JtYXQsIG9mZnNldCwgcmVmO1xuICAgICAgaWYgKCF0aGlzLnJlYWRTdGFydCAmJiB0aGlzLnN0cmVhbS5hdmFpbGFibGUoMTIpKSB7XG4gICAgICAgIGlmICh0aGlzLnN0cmVhbS5yZWFkU3RyaW5nKDQpICE9PSAnRk9STScpIHtcbiAgICAgICAgICByZXR1cm4gdGhpcy5lbWl0KCdlcnJvcicsICdJbnZhbGlkIEFJRkYuJyk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5maWxlU2l6ZSA9IHRoaXMuc3RyZWFtLnJlYWRVSW50MzIoKTtcbiAgICAgICAgdGhpcy5maWxlVHlwZSA9IHRoaXMuc3RyZWFtLnJlYWRTdHJpbmcoNCk7XG4gICAgICAgIHRoaXMucmVhZFN0YXJ0ID0gdHJ1ZTtcbiAgICAgICAgaWYgKChyZWYgPSB0aGlzLmZpbGVUeXBlKSAhPT0gJ0FJRkYnICYmIHJlZiAhPT0gJ0FJRkMnKSB7XG4gICAgICAgICAgcmV0dXJuIHRoaXMuZW1pdCgnZXJyb3InLCAnSW52YWxpZCBBSUZGLicpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICB3aGlsZSAodGhpcy5zdHJlYW0uYXZhaWxhYmxlKDEpKSB7XG4gICAgICAgIGlmICghdGhpcy5yZWFkSGVhZGVycyAmJiB0aGlzLnN0cmVhbS5hdmFpbGFibGUoOCkpIHtcbiAgICAgICAgICB0aGlzLnR5cGUgPSB0aGlzLnN0cmVhbS5yZWFkU3RyaW5nKDQpO1xuICAgICAgICAgIHRoaXMubGVuID0gdGhpcy5zdHJlYW0ucmVhZFVJbnQzMigpO1xuICAgICAgICB9XG4gICAgICAgIHN3aXRjaCAodGhpcy50eXBlKSB7XG4gICAgICAgICAgY2FzZSAnQ09NTSc6XG4gICAgICAgICAgICBpZiAoIXRoaXMuc3RyZWFtLmF2YWlsYWJsZSh0aGlzLmxlbikpIHtcbiAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5mb3JtYXQgPSB7XG4gICAgICAgICAgICAgIGZvcm1hdElEOiAnbHBjbScsXG4gICAgICAgICAgICAgIGNoYW5uZWxzUGVyRnJhbWU6IHRoaXMuc3RyZWFtLnJlYWRVSW50MTYoKSxcbiAgICAgICAgICAgICAgc2FtcGxlQ291bnQ6IHRoaXMuc3RyZWFtLnJlYWRVSW50MzIoKSxcbiAgICAgICAgICAgICAgYml0c1BlckNoYW5uZWw6IHRoaXMuc3RyZWFtLnJlYWRVSW50MTYoKSxcbiAgICAgICAgICAgICAgc2FtcGxlUmF0ZTogdGhpcy5zdHJlYW0ucmVhZEZsb2F0ODAoKSxcbiAgICAgICAgICAgICAgZnJhbWVzUGVyUGFja2V0OiAxLFxuICAgICAgICAgICAgICBsaXR0bGVFbmRpYW46IGZhbHNlLFxuICAgICAgICAgICAgICBmbG9hdGluZ1BvaW50OiBmYWxzZVxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIHRoaXMuZm9ybWF0LmJ5dGVzUGVyUGFja2V0ID0gKHRoaXMuZm9ybWF0LmJpdHNQZXJDaGFubmVsIC8gOCkgKiB0aGlzLmZvcm1hdC5jaGFubmVsc1BlckZyYW1lO1xuICAgICAgICAgICAgaWYgKHRoaXMuZmlsZVR5cGUgPT09ICdBSUZDJykge1xuICAgICAgICAgICAgICBmb3JtYXQgPSB0aGlzLnN0cmVhbS5yZWFkU3RyaW5nKDQpO1xuICAgICAgICAgICAgICB0aGlzLmZvcm1hdC5saXR0bGVFbmRpYW4gPSBmb3JtYXQgPT09ICdzb3d0JyAmJiB0aGlzLmZvcm1hdC5iaXRzUGVyQ2hhbm5lbCA+IDg7XG4gICAgICAgICAgICAgIHRoaXMuZm9ybWF0LmZsb2F0aW5nUG9pbnQgPSBmb3JtYXQgPT09ICdmbDMyJyB8fCBmb3JtYXQgPT09ICdmbDY0JztcbiAgICAgICAgICAgICAgaWYgKGZvcm1hdCA9PT0gJ3R3b3MnIHx8IGZvcm1hdCA9PT0gJ3Nvd3QnIHx8IGZvcm1hdCA9PT0gJ2ZsMzInIHx8IGZvcm1hdCA9PT0gJ2ZsNjQnIHx8IGZvcm1hdCA9PT0gJ05PTkUnKSB7XG4gICAgICAgICAgICAgICAgZm9ybWF0ID0gJ2xwY20nO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHRoaXMuZm9ybWF0LmZvcm1hdElEID0gZm9ybWF0O1xuICAgICAgICAgICAgICB0aGlzLmxlbiAtPSA0O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5zdHJlYW0uYWR2YW5jZSh0aGlzLmxlbiAtIDE4KTtcbiAgICAgICAgICAgIHRoaXMuZW1pdCgnZm9ybWF0JywgdGhpcy5mb3JtYXQpO1xuICAgICAgICAgICAgdGhpcy5lbWl0KCdkdXJhdGlvbicsIHRoaXMuZm9ybWF0LnNhbXBsZUNvdW50IC8gdGhpcy5mb3JtYXQuc2FtcGxlUmF0ZSAqIDEwMDAgfCAwKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIGNhc2UgJ1NTTkQnOlxuICAgICAgICAgICAgaWYgKCEodGhpcy5yZWFkU1NOREhlYWRlciAmJiB0aGlzLnN0cmVhbS5hdmFpbGFibGUoNCkpKSB7XG4gICAgICAgICAgICAgIG9mZnNldCA9IHRoaXMuc3RyZWFtLnJlYWRVSW50MzIoKTtcbiAgICAgICAgICAgICAgdGhpcy5zdHJlYW0uYWR2YW5jZSg0KTtcbiAgICAgICAgICAgICAgdGhpcy5zdHJlYW0uYWR2YW5jZShvZmZzZXQpO1xuICAgICAgICAgICAgICB0aGlzLnJlYWRTU05ESGVhZGVyID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGJ1ZmZlciA9IHRoaXMuc3RyZWFtLnJlYWRTaW5nbGVCdWZmZXIodGhpcy5sZW4pO1xuICAgICAgICAgICAgdGhpcy5sZW4gLT0gYnVmZmVyLmxlbmd0aDtcbiAgICAgICAgICAgIHRoaXMucmVhZEhlYWRlcnMgPSB0aGlzLmxlbiA+IDA7XG4gICAgICAgICAgICB0aGlzLmVtaXQoJ2RhdGEnLCBidWZmZXIpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgIGlmICghdGhpcy5zdHJlYW0uYXZhaWxhYmxlKHRoaXMubGVuKSkge1xuICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLnN0cmVhbS5hZHZhbmNlKHRoaXMubGVuKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy50eXBlICE9PSAnU1NORCcpIHtcbiAgICAgICAgICB0aGlzLnJlYWRIZWFkZXJzID0gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9O1xuXG4gICAgcmV0dXJuIEFJRkZEZW11eGVyO1xuXG4gIH0pKERlbXV4ZXIpO1xuXG59KS5jYWxsKHRoaXMpO1xuIiwiLy8gR2VuZXJhdGVkIGJ5IENvZmZlZVNjcmlwdCAxLjEyLjdcbihmdW5jdGlvbigpIHtcbiAgdmFyIEFVRGVtdXhlciwgRGVtdXhlcixcbiAgICBleHRlbmQgPSBmdW5jdGlvbihjaGlsZCwgcGFyZW50KSB7IGZvciAodmFyIGtleSBpbiBwYXJlbnQpIHsgaWYgKGhhc1Byb3AuY2FsbChwYXJlbnQsIGtleSkpIGNoaWxkW2tleV0gPSBwYXJlbnRba2V5XTsgfSBmdW5jdGlvbiBjdG9yKCkgeyB0aGlzLmNvbnN0cnVjdG9yID0gY2hpbGQ7IH0gY3Rvci5wcm90b3R5cGUgPSBwYXJlbnQucHJvdG90eXBlOyBjaGlsZC5wcm90b3R5cGUgPSBuZXcgY3RvcigpOyBjaGlsZC5fX3N1cGVyX18gPSBwYXJlbnQucHJvdG90eXBlOyByZXR1cm4gY2hpbGQ7IH0sXG4gICAgaGFzUHJvcCA9IHt9Lmhhc093blByb3BlcnR5O1xuXG4gIERlbXV4ZXIgPSByZXF1aXJlKCcuLi9kZW11eGVyJyk7XG5cbiAgQVVEZW11eGVyID0gKGZ1bmN0aW9uKHN1cGVyQ2xhc3MpIHtcbiAgICB2YXIgYnBzLCBmb3JtYXRzO1xuXG4gICAgZXh0ZW5kKEFVRGVtdXhlciwgc3VwZXJDbGFzcyk7XG5cbiAgICBmdW5jdGlvbiBBVURlbXV4ZXIoKSB7XG4gICAgICByZXR1cm4gQVVEZW11eGVyLl9fc3VwZXJfXy5jb25zdHJ1Y3Rvci5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgIH1cblxuICAgIERlbXV4ZXIucmVnaXN0ZXIoQVVEZW11eGVyKTtcblxuICAgIEFVRGVtdXhlci5wcm9iZSA9IGZ1bmN0aW9uKGJ1ZmZlcikge1xuICAgICAgcmV0dXJuIGJ1ZmZlci5wZWVrU3RyaW5nKDAsIDQpID09PSAnLnNuZCc7XG4gICAgfTtcblxuICAgIGJwcyA9IFs4LCA4LCAxNiwgMjQsIDMyLCAzMiwgNjRdO1xuXG4gICAgYnBzWzI2XSA9IDg7XG5cbiAgICBmb3JtYXRzID0ge1xuICAgICAgMTogJ3VsYXcnLFxuICAgICAgMjc6ICdhbGF3J1xuICAgIH07XG5cbiAgICBBVURlbXV4ZXIucHJvdG90eXBlLnJlYWRDaHVuayA9IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIGJ5dGVzLCBkYXRhU2l6ZSwgZW5jb2RpbmcsIHNpemU7XG4gICAgICBpZiAoIXRoaXMucmVhZEhlYWRlciAmJiB0aGlzLnN0cmVhbS5hdmFpbGFibGUoMjQpKSB7XG4gICAgICAgIGlmICh0aGlzLnN0cmVhbS5yZWFkU3RyaW5nKDQpICE9PSAnLnNuZCcpIHtcbiAgICAgICAgICByZXR1cm4gdGhpcy5lbWl0KCdlcnJvcicsICdJbnZhbGlkIEFVIGZpbGUuJyk7XG4gICAgICAgIH1cbiAgICAgICAgc2l6ZSA9IHRoaXMuc3RyZWFtLnJlYWRVSW50MzIoKTtcbiAgICAgICAgZGF0YVNpemUgPSB0aGlzLnN0cmVhbS5yZWFkVUludDMyKCk7XG4gICAgICAgIGVuY29kaW5nID0gdGhpcy5zdHJlYW0ucmVhZFVJbnQzMigpO1xuICAgICAgICB0aGlzLmZvcm1hdCA9IHtcbiAgICAgICAgICBmb3JtYXRJRDogZm9ybWF0c1tlbmNvZGluZ10gfHwgJ2xwY20nLFxuICAgICAgICAgIGxpdHRsZUVuZGlhbjogZmFsc2UsXG4gICAgICAgICAgZmxvYXRpbmdQb2ludDogZW5jb2RpbmcgPT09IDYgfHwgZW5jb2RpbmcgPT09IDcsXG4gICAgICAgICAgYml0c1BlckNoYW5uZWw6IGJwc1tlbmNvZGluZyAtIDFdLFxuICAgICAgICAgIHNhbXBsZVJhdGU6IHRoaXMuc3RyZWFtLnJlYWRVSW50MzIoKSxcbiAgICAgICAgICBjaGFubmVsc1BlckZyYW1lOiB0aGlzLnN0cmVhbS5yZWFkVUludDMyKCksXG4gICAgICAgICAgZnJhbWVzUGVyUGFja2V0OiAxXG4gICAgICAgIH07XG4gICAgICAgIGlmICh0aGlzLmZvcm1hdC5iaXRzUGVyQ2hhbm5lbCA9PSBudWxsKSB7XG4gICAgICAgICAgcmV0dXJuIHRoaXMuZW1pdCgnZXJyb3InLCAnVW5zdXBwb3J0ZWQgZW5jb2RpbmcgaW4gQVUgZmlsZS4nKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmZvcm1hdC5ieXRlc1BlclBhY2tldCA9ICh0aGlzLmZvcm1hdC5iaXRzUGVyQ2hhbm5lbCAvIDgpICogdGhpcy5mb3JtYXQuY2hhbm5lbHNQZXJGcmFtZTtcbiAgICAgICAgaWYgKGRhdGFTaXplICE9PSAweGZmZmZmZmZmKSB7XG4gICAgICAgICAgYnl0ZXMgPSB0aGlzLmZvcm1hdC5iaXRzUGVyQ2hhbm5lbCAvIDg7XG4gICAgICAgICAgdGhpcy5lbWl0KCdkdXJhdGlvbicsIGRhdGFTaXplIC8gYnl0ZXMgLyB0aGlzLmZvcm1hdC5jaGFubmVsc1BlckZyYW1lIC8gdGhpcy5mb3JtYXQuc2FtcGxlUmF0ZSAqIDEwMDAgfCAwKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmVtaXQoJ2Zvcm1hdCcsIHRoaXMuZm9ybWF0KTtcbiAgICAgICAgdGhpcy5yZWFkSGVhZGVyID0gdHJ1ZTtcbiAgICAgIH1cbiAgICAgIGlmICh0aGlzLnJlYWRIZWFkZXIpIHtcbiAgICAgICAgd2hpbGUgKHRoaXMuc3RyZWFtLmF2YWlsYWJsZSgxKSkge1xuICAgICAgICAgIHRoaXMuZW1pdCgnZGF0YScsIHRoaXMuc3RyZWFtLnJlYWRTaW5nbGVCdWZmZXIodGhpcy5zdHJlYW0ucmVtYWluaW5nQnl0ZXMoKSkpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfTtcblxuICAgIHJldHVybiBBVURlbXV4ZXI7XG5cbiAgfSkoRGVtdXhlcik7XG5cbn0pLmNhbGwodGhpcyk7XG4iLCIvLyBHZW5lcmF0ZWQgYnkgQ29mZmVlU2NyaXB0IDEuMTIuN1xuKGZ1bmN0aW9uKCkge1xuICB2YXIgQ0FGRGVtdXhlciwgRGVtdXhlciwgTTRBRGVtdXhlcixcbiAgICBleHRlbmQgPSBmdW5jdGlvbihjaGlsZCwgcGFyZW50KSB7IGZvciAodmFyIGtleSBpbiBwYXJlbnQpIHsgaWYgKGhhc1Byb3AuY2FsbChwYXJlbnQsIGtleSkpIGNoaWxkW2tleV0gPSBwYXJlbnRba2V5XTsgfSBmdW5jdGlvbiBjdG9yKCkgeyB0aGlzLmNvbnN0cnVjdG9yID0gY2hpbGQ7IH0gY3Rvci5wcm90b3R5cGUgPSBwYXJlbnQucHJvdG90eXBlOyBjaGlsZC5wcm90b3R5cGUgPSBuZXcgY3RvcigpOyBjaGlsZC5fX3N1cGVyX18gPSBwYXJlbnQucHJvdG90eXBlOyByZXR1cm4gY2hpbGQ7IH0sXG4gICAgaGFzUHJvcCA9IHt9Lmhhc093blByb3BlcnR5O1xuXG4gIERlbXV4ZXIgPSByZXF1aXJlKCcuLi9kZW11eGVyJyk7XG5cbiAgTTRBRGVtdXhlciA9IHJlcXVpcmUoJy4vbTRhJyk7XG5cbiAgQ0FGRGVtdXhlciA9IChmdW5jdGlvbihzdXBlckNsYXNzKSB7XG4gICAgZXh0ZW5kKENBRkRlbXV4ZXIsIHN1cGVyQ2xhc3MpO1xuXG4gICAgZnVuY3Rpb24gQ0FGRGVtdXhlcigpIHtcbiAgICAgIHJldHVybiBDQUZEZW11eGVyLl9fc3VwZXJfXy5jb25zdHJ1Y3Rvci5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgIH1cblxuICAgIERlbXV4ZXIucmVnaXN0ZXIoQ0FGRGVtdXhlcik7XG5cbiAgICBDQUZEZW11eGVyLnByb2JlID0gZnVuY3Rpb24oYnVmZmVyKSB7XG4gICAgICByZXR1cm4gYnVmZmVyLnBlZWtTdHJpbmcoMCwgNCkgPT09ICdjYWZmJztcbiAgICB9O1xuXG4gICAgQ0FGRGVtdXhlci5wcm90b3R5cGUucmVhZENodW5rID0gZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgYnVmZmVyLCBieXRlT2Zmc2V0LCBjb29raWUsIGVudHJpZXMsIGZsYWdzLCBpLCBqLCBrLCBrZXksIG1ldGFkYXRhLCBvZmZzZXQsIHJlZiwgcmVmMSwgc2FtcGxlT2Zmc2V0LCB2YWx1ZTtcbiAgICAgIGlmICghdGhpcy5mb3JtYXQgJiYgdGhpcy5zdHJlYW0uYXZhaWxhYmxlKDY0KSkge1xuICAgICAgICBpZiAodGhpcy5zdHJlYW0ucmVhZFN0cmluZyg0KSAhPT0gJ2NhZmYnKSB7XG4gICAgICAgICAgcmV0dXJuIHRoaXMuZW1pdCgnZXJyb3InLCBcIkludmFsaWQgQ0FGLCBkb2VzIG5vdCBiZWdpbiB3aXRoICdjYWZmJ1wiKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnN0cmVhbS5hZHZhbmNlKDQpO1xuICAgICAgICBpZiAodGhpcy5zdHJlYW0ucmVhZFN0cmluZyg0KSAhPT0gJ2Rlc2MnKSB7XG4gICAgICAgICAgcmV0dXJuIHRoaXMuZW1pdCgnZXJyb3InLCBcIkludmFsaWQgQ0FGLCAnY2FmZicgaXMgbm90IGZvbGxvd2VkIGJ5ICdkZXNjJ1wiKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoISh0aGlzLnN0cmVhbS5yZWFkVUludDMyKCkgPT09IDAgJiYgdGhpcy5zdHJlYW0ucmVhZFVJbnQzMigpID09PSAzMikpIHtcbiAgICAgICAgICByZXR1cm4gdGhpcy5lbWl0KCdlcnJvcicsIFwiSW52YWxpZCAnZGVzYycgc2l6ZSwgc2hvdWxkIGJlIDMyXCIpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuZm9ybWF0ID0ge307XG4gICAgICAgIHRoaXMuZm9ybWF0LnNhbXBsZVJhdGUgPSB0aGlzLnN0cmVhbS5yZWFkRmxvYXQ2NCgpO1xuICAgICAgICB0aGlzLmZvcm1hdC5mb3JtYXRJRCA9IHRoaXMuc3RyZWFtLnJlYWRTdHJpbmcoNCk7XG4gICAgICAgIGZsYWdzID0gdGhpcy5zdHJlYW0ucmVhZFVJbnQzMigpO1xuICAgICAgICBpZiAodGhpcy5mb3JtYXQuZm9ybWF0SUQgPT09ICdscGNtJykge1xuICAgICAgICAgIHRoaXMuZm9ybWF0LmZsb2F0aW5nUG9pbnQgPSBCb29sZWFuKGZsYWdzICYgMSk7XG4gICAgICAgICAgdGhpcy5mb3JtYXQubGl0dGxlRW5kaWFuID0gQm9vbGVhbihmbGFncyAmIDIpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuZm9ybWF0LmJ5dGVzUGVyUGFja2V0ID0gdGhpcy5zdHJlYW0ucmVhZFVJbnQzMigpO1xuICAgICAgICB0aGlzLmZvcm1hdC5mcmFtZXNQZXJQYWNrZXQgPSB0aGlzLnN0cmVhbS5yZWFkVUludDMyKCk7XG4gICAgICAgIHRoaXMuZm9ybWF0LmNoYW5uZWxzUGVyRnJhbWUgPSB0aGlzLnN0cmVhbS5yZWFkVUludDMyKCk7XG4gICAgICAgIHRoaXMuZm9ybWF0LmJpdHNQZXJDaGFubmVsID0gdGhpcy5zdHJlYW0ucmVhZFVJbnQzMigpO1xuICAgICAgICB0aGlzLmVtaXQoJ2Zvcm1hdCcsIHRoaXMuZm9ybWF0KTtcbiAgICAgIH1cbiAgICAgIHdoaWxlICh0aGlzLnN0cmVhbS5hdmFpbGFibGUoMSkpIHtcbiAgICAgICAgaWYgKCF0aGlzLmhlYWRlckNhY2hlKSB7XG4gICAgICAgICAgdGhpcy5oZWFkZXJDYWNoZSA9IHtcbiAgICAgICAgICAgIHR5cGU6IHRoaXMuc3RyZWFtLnJlYWRTdHJpbmcoNCksXG4gICAgICAgICAgICBvdmVyc2l6ZTogdGhpcy5zdHJlYW0ucmVhZFVJbnQzMigpICE9PSAwLFxuICAgICAgICAgICAgc2l6ZTogdGhpcy5zdHJlYW0ucmVhZFVJbnQzMigpXG4gICAgICAgICAgfTtcbiAgICAgICAgICBpZiAodGhpcy5oZWFkZXJDYWNoZS5vdmVyc2l6ZSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZW1pdCgnZXJyb3InLCBcIkhvbHkgU2hpdCwgYW4gb3ZlcnNpemVkIGZpbGUsIG5vdCBzdXBwb3J0ZWQgaW4gSlNcIik7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHN3aXRjaCAodGhpcy5oZWFkZXJDYWNoZS50eXBlKSB7XG4gICAgICAgICAgY2FzZSAna3VraSc6XG4gICAgICAgICAgICBpZiAodGhpcy5zdHJlYW0uYXZhaWxhYmxlKHRoaXMuaGVhZGVyQ2FjaGUuc2l6ZSkpIHtcbiAgICAgICAgICAgICAgaWYgKHRoaXMuZm9ybWF0LmZvcm1hdElEID09PSAnYWFjICcpIHtcbiAgICAgICAgICAgICAgICBvZmZzZXQgPSB0aGlzLnN0cmVhbS5vZmZzZXQgKyB0aGlzLmhlYWRlckNhY2hlLnNpemU7XG4gICAgICAgICAgICAgICAgaWYgKGNvb2tpZSA9IE00QURlbXV4ZXIucmVhZEVzZHModGhpcy5zdHJlYW0pKSB7XG4gICAgICAgICAgICAgICAgICB0aGlzLmVtaXQoJ2Nvb2tpZScsIGNvb2tpZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRoaXMuc3RyZWFtLnNlZWsob2Zmc2V0KTtcbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBidWZmZXIgPSB0aGlzLnN0cmVhbS5yZWFkQnVmZmVyKHRoaXMuaGVhZGVyQ2FjaGUuc2l6ZSk7XG4gICAgICAgICAgICAgICAgdGhpcy5lbWl0KCdjb29raWUnLCBidWZmZXIpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHRoaXMuaGVhZGVyQ2FjaGUgPSBudWxsO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgY2FzZSAncGFrdCc6XG4gICAgICAgICAgICBpZiAodGhpcy5zdHJlYW0uYXZhaWxhYmxlKHRoaXMuaGVhZGVyQ2FjaGUuc2l6ZSkpIHtcbiAgICAgICAgICAgICAgaWYgKHRoaXMuc3RyZWFtLnJlYWRVSW50MzIoKSAhPT0gMCkge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmVtaXQoJ2Vycm9yJywgJ1NpemVzIGdyZWF0ZXIgdGhhbiAzMiBiaXRzIGFyZSBub3Qgc3VwcG9ydGVkLicpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHRoaXMubnVtUGFja2V0cyA9IHRoaXMuc3RyZWFtLnJlYWRVSW50MzIoKTtcbiAgICAgICAgICAgICAgaWYgKHRoaXMuc3RyZWFtLnJlYWRVSW50MzIoKSAhPT0gMCkge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmVtaXQoJ2Vycm9yJywgJ1NpemVzIGdyZWF0ZXIgdGhhbiAzMiBiaXRzIGFyZSBub3Qgc3VwcG9ydGVkLicpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHRoaXMubnVtRnJhbWVzID0gdGhpcy5zdHJlYW0ucmVhZFVJbnQzMigpO1xuICAgICAgICAgICAgICB0aGlzLnByaW1pbmdGcmFtZXMgPSB0aGlzLnN0cmVhbS5yZWFkVUludDMyKCk7XG4gICAgICAgICAgICAgIHRoaXMucmVtYWluZGVyRnJhbWVzID0gdGhpcy5zdHJlYW0ucmVhZFVJbnQzMigpO1xuICAgICAgICAgICAgICB0aGlzLmVtaXQoJ2R1cmF0aW9uJywgdGhpcy5udW1GcmFtZXMgLyB0aGlzLmZvcm1hdC5zYW1wbGVSYXRlICogMTAwMCB8IDApO1xuICAgICAgICAgICAgICB0aGlzLnNlbnREdXJhdGlvbiA9IHRydWU7XG4gICAgICAgICAgICAgIGJ5dGVPZmZzZXQgPSAwO1xuICAgICAgICAgICAgICBzYW1wbGVPZmZzZXQgPSAwO1xuICAgICAgICAgICAgICBmb3IgKGkgPSBqID0gMCwgcmVmID0gdGhpcy5udW1QYWNrZXRzOyBqIDwgcmVmOyBpID0gaiArPSAxKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5hZGRTZWVrUG9pbnQoYnl0ZU9mZnNldCwgc2FtcGxlT2Zmc2V0KTtcbiAgICAgICAgICAgICAgICBieXRlT2Zmc2V0ICs9IHRoaXMuZm9ybWF0LmJ5dGVzUGVyUGFja2V0IHx8IE00QURlbXV4ZXIucmVhZERlc2NyTGVuKHRoaXMuc3RyZWFtKTtcbiAgICAgICAgICAgICAgICBzYW1wbGVPZmZzZXQgKz0gdGhpcy5mb3JtYXQuZnJhbWVzUGVyUGFja2V0IHx8IE00QURlbXV4ZXIucmVhZERlc2NyTGVuKHRoaXMuc3RyZWFtKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB0aGlzLmhlYWRlckNhY2hlID0gbnVsbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIGNhc2UgJ2luZm8nOlxuICAgICAgICAgICAgZW50cmllcyA9IHRoaXMuc3RyZWFtLnJlYWRVSW50MzIoKTtcbiAgICAgICAgICAgIG1ldGFkYXRhID0ge307XG4gICAgICAgICAgICBmb3IgKGkgPSBrID0gMCwgcmVmMSA9IGVudHJpZXM7IDAgPD0gcmVmMSA/IGsgPCByZWYxIDogayA+IHJlZjE7IGkgPSAwIDw9IHJlZjEgPyArK2sgOiAtLWspIHtcbiAgICAgICAgICAgICAga2V5ID0gdGhpcy5zdHJlYW0ucmVhZFN0cmluZyhudWxsKTtcbiAgICAgICAgICAgICAgdmFsdWUgPSB0aGlzLnN0cmVhbS5yZWFkU3RyaW5nKG51bGwpO1xuICAgICAgICAgICAgICBtZXRhZGF0YVtrZXldID0gdmFsdWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLmVtaXQoJ21ldGFkYXRhJywgbWV0YWRhdGEpO1xuICAgICAgICAgICAgdGhpcy5oZWFkZXJDYWNoZSA9IG51bGw7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICBjYXNlICdkYXRhJzpcbiAgICAgICAgICAgIGlmICghdGhpcy5zZW50Rmlyc3REYXRhQ2h1bmspIHtcbiAgICAgICAgICAgICAgdGhpcy5zdHJlYW0uYWR2YW5jZSg0KTtcbiAgICAgICAgICAgICAgdGhpcy5oZWFkZXJDYWNoZS5zaXplIC09IDQ7XG4gICAgICAgICAgICAgIGlmICh0aGlzLmZvcm1hdC5ieXRlc1BlclBhY2tldCAhPT0gMCAmJiAhdGhpcy5zZW50RHVyYXRpb24pIHtcbiAgICAgICAgICAgICAgICB0aGlzLm51bUZyYW1lcyA9IHRoaXMuaGVhZGVyQ2FjaGUuc2l6ZSAvIHRoaXMuZm9ybWF0LmJ5dGVzUGVyUGFja2V0O1xuICAgICAgICAgICAgICAgIHRoaXMuZW1pdCgnZHVyYXRpb24nLCB0aGlzLm51bUZyYW1lcyAvIHRoaXMuZm9ybWF0LnNhbXBsZVJhdGUgKiAxMDAwIHwgMCk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgdGhpcy5zZW50Rmlyc3REYXRhQ2h1bmsgPSB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYnVmZmVyID0gdGhpcy5zdHJlYW0ucmVhZFNpbmdsZUJ1ZmZlcih0aGlzLmhlYWRlckNhY2hlLnNpemUpO1xuICAgICAgICAgICAgdGhpcy5oZWFkZXJDYWNoZS5zaXplIC09IGJ1ZmZlci5sZW5ndGg7XG4gICAgICAgICAgICB0aGlzLmVtaXQoJ2RhdGEnLCBidWZmZXIpO1xuICAgICAgICAgICAgaWYgKHRoaXMuaGVhZGVyQ2FjaGUuc2l6ZSA8PSAwKSB7XG4gICAgICAgICAgICAgIHRoaXMuaGVhZGVyQ2FjaGUgPSBudWxsO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgIGlmICh0aGlzLnN0cmVhbS5hdmFpbGFibGUodGhpcy5oZWFkZXJDYWNoZS5zaXplKSkge1xuICAgICAgICAgICAgICB0aGlzLnN0cmVhbS5hZHZhbmNlKHRoaXMuaGVhZGVyQ2FjaGUuc2l6ZSk7XG4gICAgICAgICAgICAgIHRoaXMuaGVhZGVyQ2FjaGUgPSBudWxsO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfTtcblxuICAgIHJldHVybiBDQUZEZW11eGVyO1xuXG4gIH0pKERlbXV4ZXIpO1xuXG59KS5jYWxsKHRoaXMpO1xuIiwiLy8gR2VuZXJhdGVkIGJ5IENvZmZlZVNjcmlwdCAxLjEyLjdcbihmdW5jdGlvbigpIHtcbiAgdmFyIERlbXV4ZXIsIE00QURlbXV4ZXIsXG4gICAgZXh0ZW5kID0gZnVuY3Rpb24oY2hpbGQsIHBhcmVudCkgeyBmb3IgKHZhciBrZXkgaW4gcGFyZW50KSB7IGlmIChoYXNQcm9wLmNhbGwocGFyZW50LCBrZXkpKSBjaGlsZFtrZXldID0gcGFyZW50W2tleV07IH0gZnVuY3Rpb24gY3RvcigpIHsgdGhpcy5jb25zdHJ1Y3RvciA9IGNoaWxkOyB9IGN0b3IucHJvdG90eXBlID0gcGFyZW50LnByb3RvdHlwZTsgY2hpbGQucHJvdG90eXBlID0gbmV3IGN0b3IoKTsgY2hpbGQuX19zdXBlcl9fID0gcGFyZW50LnByb3RvdHlwZTsgcmV0dXJuIGNoaWxkOyB9LFxuICAgIGhhc1Byb3AgPSB7fS5oYXNPd25Qcm9wZXJ0eSxcbiAgICBpbmRleE9mID0gW10uaW5kZXhPZiB8fCBmdW5jdGlvbihpdGVtKSB7IGZvciAodmFyIGkgPSAwLCBsID0gdGhpcy5sZW5ndGg7IGkgPCBsOyBpKyspIHsgaWYgKGkgaW4gdGhpcyAmJiB0aGlzW2ldID09PSBpdGVtKSByZXR1cm4gaTsgfSByZXR1cm4gLTE7IH07XG5cbiAgRGVtdXhlciA9IHJlcXVpcmUoJy4uL2RlbXV4ZXInKTtcblxuICBNNEFEZW11eGVyID0gKGZ1bmN0aW9uKHN1cGVyQ2xhc3MpIHtcbiAgICB2YXIgQklUU19QRVJfQ0hBTk5FTCwgVFlQRVMsIGFmdGVyLCBhdG9tLCBhdG9tcywgYm9vbCwgY29udGFpbmVycywgZGlza1RyYWNrLCBnZW5yZXMsIG1ldGEsIHN0cmluZztcblxuICAgIGV4dGVuZChNNEFEZW11eGVyLCBzdXBlckNsYXNzKTtcblxuICAgIGZ1bmN0aW9uIE00QURlbXV4ZXIoKSB7XG4gICAgICByZXR1cm4gTTRBRGVtdXhlci5fX3N1cGVyX18uY29uc3RydWN0b3IuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICB9XG5cbiAgICBEZW11eGVyLnJlZ2lzdGVyKE00QURlbXV4ZXIpO1xuXG4gICAgVFlQRVMgPSBbJ000QSAnLCAnTTRQICcsICdNNEIgJywgJ000ViAnLCAnaXNvbScsICdtcDQyJywgJ3F0ICAnXTtcblxuICAgIE00QURlbXV4ZXIucHJvYmUgPSBmdW5jdGlvbihidWZmZXIpIHtcbiAgICAgIHZhciByZWY7XG4gICAgICByZXR1cm4gYnVmZmVyLnBlZWtTdHJpbmcoNCwgNCkgPT09ICdmdHlwJyAmJiAocmVmID0gYnVmZmVyLnBlZWtTdHJpbmcoOCwgNCksIGluZGV4T2YuY2FsbChUWVBFUywgcmVmKSA+PSAwKTtcbiAgICB9O1xuXG4gICAgTTRBRGVtdXhlci5wcm90b3R5cGUuaW5pdCA9IGZ1bmN0aW9uKCkge1xuICAgICAgdGhpcy5hdG9tcyA9IFtdO1xuICAgICAgdGhpcy5vZmZzZXRzID0gW107XG4gICAgICB0aGlzLnRyYWNrID0gbnVsbDtcbiAgICAgIHJldHVybiB0aGlzLnRyYWNrcyA9IFtdO1xuICAgIH07XG5cbiAgICBhdG9tcyA9IHt9O1xuXG4gICAgY29udGFpbmVycyA9IHt9O1xuXG4gICAgYXRvbSA9IGZ1bmN0aW9uKG5hbWUsIGZuKSB7XG4gICAgICB2YXIgYywgY29udGFpbmVyLCBrLCBsZW4xLCByZWY7XG4gICAgICBjID0gW107XG4gICAgICByZWYgPSBuYW1lLnNwbGl0KCcuJykuc2xpY2UoMCwgLTEpO1xuICAgICAgZm9yIChrID0gMCwgbGVuMSA9IHJlZi5sZW5ndGg7IGsgPCBsZW4xOyBrKyspIHtcbiAgICAgICAgY29udGFpbmVyID0gcmVmW2tdO1xuICAgICAgICBjLnB1c2goY29udGFpbmVyKTtcbiAgICAgICAgY29udGFpbmVyc1tjLmpvaW4oJy4nKV0gPSB0cnVlO1xuICAgICAgfVxuICAgICAgaWYgKGF0b21zW25hbWVdID09IG51bGwpIHtcbiAgICAgICAgYXRvbXNbbmFtZV0gPSB7fTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBhdG9tc1tuYW1lXS5mbiA9IGZuO1xuICAgIH07XG5cbiAgICBhZnRlciA9IGZ1bmN0aW9uKG5hbWUsIGZuKSB7XG4gICAgICBpZiAoYXRvbXNbbmFtZV0gPT0gbnVsbCkge1xuICAgICAgICBhdG9tc1tuYW1lXSA9IHt9O1xuICAgICAgfVxuICAgICAgcmV0dXJuIGF0b21zW25hbWVdLmFmdGVyID0gZm47XG4gICAgfTtcblxuICAgIE00QURlbXV4ZXIucHJvdG90eXBlLnJlYWRDaHVuayA9IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIGhhbmRsZXIsIHBhdGgsIHR5cGU7XG4gICAgICB0aGlzW1wiYnJlYWtcIl0gPSBmYWxzZTtcbiAgICAgIHdoaWxlICh0aGlzLnN0cmVhbS5hdmFpbGFibGUoMSkgJiYgIXRoaXNbXCJicmVha1wiXSkge1xuICAgICAgICBpZiAoIXRoaXMucmVhZEhlYWRlcnMpIHtcbiAgICAgICAgICBpZiAoIXRoaXMuc3RyZWFtLmF2YWlsYWJsZSg4KSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgIH1cbiAgICAgICAgICB0aGlzLmxlbiA9IHRoaXMuc3RyZWFtLnJlYWRVSW50MzIoKSAtIDg7XG4gICAgICAgICAgdGhpcy50eXBlID0gdGhpcy5zdHJlYW0ucmVhZFN0cmluZyg0KTtcbiAgICAgICAgICBpZiAodGhpcy5sZW4gPT09IDApIHtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgICB0aGlzLmF0b21zLnB1c2godGhpcy50eXBlKTtcbiAgICAgICAgICB0aGlzLm9mZnNldHMucHVzaCh0aGlzLnN0cmVhbS5vZmZzZXQgKyB0aGlzLmxlbik7XG4gICAgICAgICAgdGhpcy5yZWFkSGVhZGVycyA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgcGF0aCA9IHRoaXMuYXRvbXMuam9pbignLicpO1xuICAgICAgICBoYW5kbGVyID0gYXRvbXNbcGF0aF07XG4gICAgICAgIGlmIChoYW5kbGVyICE9IG51bGwgPyBoYW5kbGVyLmZuIDogdm9pZCAwKSB7XG4gICAgICAgICAgaWYgKCEodGhpcy5zdHJlYW0uYXZhaWxhYmxlKHRoaXMubGVuKSB8fCBwYXRoID09PSAnbWRhdCcpKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfVxuICAgICAgICAgIGhhbmRsZXIuZm4uY2FsbCh0aGlzKTtcbiAgICAgICAgICBpZiAocGF0aCBpbiBjb250YWluZXJzKSB7XG4gICAgICAgICAgICB0aGlzLnJlYWRIZWFkZXJzID0gZmFsc2U7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2UgaWYgKHBhdGggaW4gY29udGFpbmVycykge1xuICAgICAgICAgIHRoaXMucmVhZEhlYWRlcnMgPSBmYWxzZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBpZiAoIXRoaXMuc3RyZWFtLmF2YWlsYWJsZSh0aGlzLmxlbikpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9XG4gICAgICAgICAgdGhpcy5zdHJlYW0uYWR2YW5jZSh0aGlzLmxlbik7XG4gICAgICAgIH1cbiAgICAgICAgd2hpbGUgKHRoaXMuc3RyZWFtLm9mZnNldCA+PSB0aGlzLm9mZnNldHNbdGhpcy5vZmZzZXRzLmxlbmd0aCAtIDFdKSB7XG4gICAgICAgICAgaGFuZGxlciA9IGF0b21zW3RoaXMuYXRvbXMuam9pbignLicpXTtcbiAgICAgICAgICBpZiAoaGFuZGxlciAhPSBudWxsID8gaGFuZGxlci5hZnRlciA6IHZvaWQgMCkge1xuICAgICAgICAgICAgaGFuZGxlci5hZnRlci5jYWxsKHRoaXMpO1xuICAgICAgICAgIH1cbiAgICAgICAgICB0eXBlID0gdGhpcy5hdG9tcy5wb3AoKTtcbiAgICAgICAgICB0aGlzLm9mZnNldHMucG9wKCk7XG4gICAgICAgICAgdGhpcy5yZWFkSGVhZGVycyA9IGZhbHNlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfTtcblxuICAgIGF0b20oJ2Z0eXAnLCBmdW5jdGlvbigpIHtcbiAgICAgIHZhciByZWY7XG4gICAgICBpZiAocmVmID0gdGhpcy5zdHJlYW0ucmVhZFN0cmluZyg0KSwgaW5kZXhPZi5jYWxsKFRZUEVTLCByZWYpIDwgMCkge1xuICAgICAgICByZXR1cm4gdGhpcy5lbWl0KCdlcnJvcicsICdOb3QgYSB2YWxpZCBNNEEgZmlsZS4nKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0aGlzLnN0cmVhbS5hZHZhbmNlKHRoaXMubGVuIC0gNCk7XG4gICAgfSk7XG5cbiAgICBhdG9tKCdtb292LnRyYWsnLCBmdW5jdGlvbigpIHtcbiAgICAgIHRoaXMudHJhY2sgPSB7fTtcbiAgICAgIHJldHVybiB0aGlzLnRyYWNrcy5wdXNoKHRoaXMudHJhY2spO1xuICAgIH0pO1xuXG4gICAgYXRvbSgnbW9vdi50cmFrLnRraGQnLCBmdW5jdGlvbigpIHtcbiAgICAgIHRoaXMuc3RyZWFtLmFkdmFuY2UoNCk7XG4gICAgICB0aGlzLnN0cmVhbS5hZHZhbmNlKDgpO1xuICAgICAgdGhpcy50cmFjay5pZCA9IHRoaXMuc3RyZWFtLnJlYWRVSW50MzIoKTtcbiAgICAgIHJldHVybiB0aGlzLnN0cmVhbS5hZHZhbmNlKHRoaXMubGVuIC0gMTYpO1xuICAgIH0pO1xuXG4gICAgYXRvbSgnbW9vdi50cmFrLm1kaWEuaGRscicsIGZ1bmN0aW9uKCkge1xuICAgICAgdGhpcy5zdHJlYW0uYWR2YW5jZSg0KTtcbiAgICAgIHRoaXMuc3RyZWFtLmFkdmFuY2UoNCk7XG4gICAgICB0aGlzLnRyYWNrLnR5cGUgPSB0aGlzLnN0cmVhbS5yZWFkU3RyaW5nKDQpO1xuICAgICAgdGhpcy5zdHJlYW0uYWR2YW5jZSgxMik7XG4gICAgICByZXR1cm4gdGhpcy5zdHJlYW0uYWR2YW5jZSh0aGlzLmxlbiAtIDI0KTtcbiAgICB9KTtcblxuICAgIGF0b20oJ21vb3YudHJhay5tZGlhLm1kaGQnLCBmdW5jdGlvbigpIHtcbiAgICAgIHRoaXMuc3RyZWFtLmFkdmFuY2UoNCk7XG4gICAgICB0aGlzLnN0cmVhbS5hZHZhbmNlKDgpO1xuICAgICAgdGhpcy50cmFjay50aW1lU2NhbGUgPSB0aGlzLnN0cmVhbS5yZWFkVUludDMyKCk7XG4gICAgICB0aGlzLnRyYWNrLmR1cmF0aW9uID0gdGhpcy5zdHJlYW0ucmVhZFVJbnQzMigpO1xuICAgICAgcmV0dXJuIHRoaXMuc3RyZWFtLmFkdmFuY2UoNCk7XG4gICAgfSk7XG5cbiAgICBCSVRTX1BFUl9DSEFOTkVMID0ge1xuICAgICAgdWxhdzogOCxcbiAgICAgIGFsYXc6IDgsXG4gICAgICBpbjI0OiAyNCxcbiAgICAgIGluMzI6IDMyLFxuICAgICAgZmwzMjogMzIsXG4gICAgICBmbDY0OiA2NFxuICAgIH07XG5cbiAgICBhdG9tKCdtb292LnRyYWsubWRpYS5taW5mLnN0Ymwuc3RzZCcsIGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIGZvcm1hdCwgbnVtRW50cmllcywgcmVmLCByZWYxLCB2ZXJzaW9uO1xuICAgICAgdGhpcy5zdHJlYW0uYWR2YW5jZSg0KTtcbiAgICAgIG51bUVudHJpZXMgPSB0aGlzLnN0cmVhbS5yZWFkVUludDMyKCk7XG4gICAgICBpZiAodGhpcy50cmFjay50eXBlICE9PSAnc291bicpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuc3RyZWFtLmFkdmFuY2UodGhpcy5sZW4gLSA4KTtcbiAgICAgIH1cbiAgICAgIGlmIChudW1FbnRyaWVzICE9PSAxKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmVtaXQoJ2Vycm9yJywgXCJPbmx5IGV4cGVjdGluZyBvbmUgZW50cnkgaW4gc2FtcGxlIGRlc2NyaXB0aW9uIGF0b20hXCIpO1xuICAgICAgfVxuICAgICAgdGhpcy5zdHJlYW0uYWR2YW5jZSg0KTtcbiAgICAgIGZvcm1hdCA9IHRoaXMudHJhY2suZm9ybWF0ID0ge307XG4gICAgICBmb3JtYXQuZm9ybWF0SUQgPSB0aGlzLnN0cmVhbS5yZWFkU3RyaW5nKDQpO1xuICAgICAgdGhpcy5zdHJlYW0uYWR2YW5jZSg2KTtcbiAgICAgIHRoaXMuc3RyZWFtLmFkdmFuY2UoMik7XG4gICAgICB2ZXJzaW9uID0gdGhpcy5zdHJlYW0ucmVhZFVJbnQxNigpO1xuICAgICAgdGhpcy5zdHJlYW0uYWR2YW5jZSg2KTtcbiAgICAgIGZvcm1hdC5jaGFubmVsc1BlckZyYW1lID0gdGhpcy5zdHJlYW0ucmVhZFVJbnQxNigpO1xuICAgICAgZm9ybWF0LmJpdHNQZXJDaGFubmVsID0gdGhpcy5zdHJlYW0ucmVhZFVJbnQxNigpO1xuICAgICAgdGhpcy5zdHJlYW0uYWR2YW5jZSg0KTtcbiAgICAgIGZvcm1hdC5zYW1wbGVSYXRlID0gdGhpcy5zdHJlYW0ucmVhZFVJbnQxNigpO1xuICAgICAgdGhpcy5zdHJlYW0uYWR2YW5jZSgyKTtcbiAgICAgIGlmICh2ZXJzaW9uID09PSAxKSB7XG4gICAgICAgIGZvcm1hdC5mcmFtZXNQZXJQYWNrZXQgPSB0aGlzLnN0cmVhbS5yZWFkVUludDMyKCk7XG4gICAgICAgIHRoaXMuc3RyZWFtLmFkdmFuY2UoNCk7XG4gICAgICAgIGZvcm1hdC5ieXRlc1BlckZyYW1lID0gdGhpcy5zdHJlYW0ucmVhZFVJbnQzMigpO1xuICAgICAgICB0aGlzLnN0cmVhbS5hZHZhbmNlKDQpO1xuICAgICAgfSBlbHNlIGlmICh2ZXJzaW9uICE9PSAwKSB7XG4gICAgICAgIHRoaXMuZW1pdCgnZXJyb3InLCAnVW5rbm93biB2ZXJzaW9uIGluIHN0c2QgYXRvbScpO1xuICAgICAgfVxuICAgICAgaWYgKEJJVFNfUEVSX0NIQU5ORUxbZm9ybWF0LmZvcm1hdElEXSAhPSBudWxsKSB7XG4gICAgICAgIGZvcm1hdC5iaXRzUGVyQ2hhbm5lbCA9IEJJVFNfUEVSX0NIQU5ORUxbZm9ybWF0LmZvcm1hdElEXTtcbiAgICAgIH1cbiAgICAgIGZvcm1hdC5mbG9hdGluZ1BvaW50ID0gKHJlZiA9IGZvcm1hdC5mb3JtYXRJRCkgPT09ICdmbDMyJyB8fCByZWYgPT09ICdmbDY0JztcbiAgICAgIGZvcm1hdC5saXR0bGVFbmRpYW4gPSBmb3JtYXQuZm9ybWF0SUQgPT09ICdzb3d0JyAmJiBmb3JtYXQuYml0c1BlckNoYW5uZWwgPiA4O1xuICAgICAgaWYgKChyZWYxID0gZm9ybWF0LmZvcm1hdElEKSA9PT0gJ3R3b3MnIHx8IHJlZjEgPT09ICdzb3d0JyB8fCByZWYxID09PSAnaW4yNCcgfHwgcmVmMSA9PT0gJ2luMzInIHx8IHJlZjEgPT09ICdmbDMyJyB8fCByZWYxID09PSAnZmw2NCcgfHwgcmVmMSA9PT0gJ3JhdyAnIHx8IHJlZjEgPT09ICdOT05FJykge1xuICAgICAgICByZXR1cm4gZm9ybWF0LmZvcm1hdElEID0gJ2xwY20nO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgYXRvbSgnbW9vdi50cmFrLm1kaWEubWluZi5zdGJsLnN0c2QuYWxhYycsIGZ1bmN0aW9uKCkge1xuICAgICAgdGhpcy5zdHJlYW0uYWR2YW5jZSg0KTtcbiAgICAgIHJldHVybiB0aGlzLnRyYWNrLmNvb2tpZSA9IHRoaXMuc3RyZWFtLnJlYWRCdWZmZXIodGhpcy5sZW4gLSA0KTtcbiAgICB9KTtcblxuICAgIGF0b20oJ21vb3YudHJhay5tZGlhLm1pbmYuc3RibC5zdHNkLmVzZHMnLCBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBvZmZzZXQ7XG4gICAgICBvZmZzZXQgPSB0aGlzLnN0cmVhbS5vZmZzZXQgKyB0aGlzLmxlbjtcbiAgICAgIHRoaXMudHJhY2suY29va2llID0gTTRBRGVtdXhlci5yZWFkRXNkcyh0aGlzLnN0cmVhbSk7XG4gICAgICByZXR1cm4gdGhpcy5zdHJlYW0uc2VlayhvZmZzZXQpO1xuICAgIH0pO1xuXG4gICAgYXRvbSgnbW9vdi50cmFrLm1kaWEubWluZi5zdGJsLnN0c2Qud2F2ZS5lbmRhJywgZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gdGhpcy50cmFjay5mb3JtYXQubGl0dGxlRW5kaWFuID0gISF0aGlzLnN0cmVhbS5yZWFkVUludDE2KCk7XG4gICAgfSk7XG5cbiAgICBNNEFEZW11eGVyLnJlYWREZXNjckxlbiA9IGZ1bmN0aW9uKHN0cmVhbSkge1xuICAgICAgdmFyIGMsIGNvdW50LCBsZW47XG4gICAgICBsZW4gPSAwO1xuICAgICAgY291bnQgPSA0O1xuICAgICAgd2hpbGUgKGNvdW50LS0pIHtcbiAgICAgICAgYyA9IHN0cmVhbS5yZWFkVUludDgoKTtcbiAgICAgICAgbGVuID0gKGxlbiA8PCA3KSB8IChjICYgMHg3Zik7XG4gICAgICAgIGlmICghKGMgJiAweDgwKSkge1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gbGVuO1xuICAgIH07XG5cbiAgICBNNEFEZW11eGVyLnJlYWRFc2RzID0gZnVuY3Rpb24oc3RyZWFtKSB7XG4gICAgICB2YXIgY29kZWNfaWQsIGZsYWdzLCBsZW4sIHRhZztcbiAgICAgIHN0cmVhbS5hZHZhbmNlKDQpO1xuICAgICAgdGFnID0gc3RyZWFtLnJlYWRVSW50OCgpO1xuICAgICAgbGVuID0gTTRBRGVtdXhlci5yZWFkRGVzY3JMZW4oc3RyZWFtKTtcbiAgICAgIGlmICh0YWcgPT09IDB4MDMpIHtcbiAgICAgICAgc3RyZWFtLmFkdmFuY2UoMik7XG4gICAgICAgIGZsYWdzID0gc3RyZWFtLnJlYWRVSW50OCgpO1xuICAgICAgICBpZiAoZmxhZ3MgJiAweDgwKSB7XG4gICAgICAgICAgc3RyZWFtLmFkdmFuY2UoMik7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGZsYWdzICYgMHg0MCkge1xuICAgICAgICAgIHN0cmVhbS5hZHZhbmNlKHN0cmVhbS5yZWFkVUludDgoKSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGZsYWdzICYgMHgyMCkge1xuICAgICAgICAgIHN0cmVhbS5hZHZhbmNlKDIpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzdHJlYW0uYWR2YW5jZSgyKTtcbiAgICAgIH1cbiAgICAgIHRhZyA9IHN0cmVhbS5yZWFkVUludDgoKTtcbiAgICAgIGxlbiA9IE00QURlbXV4ZXIucmVhZERlc2NyTGVuKHN0cmVhbSk7XG4gICAgICBpZiAodGFnID09PSAweDA0KSB7XG4gICAgICAgIGNvZGVjX2lkID0gc3RyZWFtLnJlYWRVSW50OCgpO1xuICAgICAgICBzdHJlYW0uYWR2YW5jZSgxKTtcbiAgICAgICAgc3RyZWFtLmFkdmFuY2UoMyk7XG4gICAgICAgIHN0cmVhbS5hZHZhbmNlKDQpO1xuICAgICAgICBzdHJlYW0uYWR2YW5jZSg0KTtcbiAgICAgICAgdGFnID0gc3RyZWFtLnJlYWRVSW50OCgpO1xuICAgICAgICBsZW4gPSBNNEFEZW11eGVyLnJlYWREZXNjckxlbihzdHJlYW0pO1xuICAgICAgICBpZiAodGFnID09PSAweDA1KSB7XG4gICAgICAgICAgcmV0dXJuIHN0cmVhbS5yZWFkQnVmZmVyKGxlbik7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBudWxsO1xuICAgIH07XG5cbiAgICBhdG9tKCdtb292LnRyYWsubWRpYS5taW5mLnN0Ymwuc3R0cycsIGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIGVudHJpZXMsIGksIGssIHJlZjtcbiAgICAgIHRoaXMuc3RyZWFtLmFkdmFuY2UoNCk7XG4gICAgICBlbnRyaWVzID0gdGhpcy5zdHJlYW0ucmVhZFVJbnQzMigpO1xuICAgICAgdGhpcy50cmFjay5zdHRzID0gW107XG4gICAgICBmb3IgKGkgPSBrID0gMCwgcmVmID0gZW50cmllczsgayA8IHJlZjsgaSA9IGsgKz0gMSkge1xuICAgICAgICB0aGlzLnRyYWNrLnN0dHNbaV0gPSB7XG4gICAgICAgICAgY291bnQ6IHRoaXMuc3RyZWFtLnJlYWRVSW50MzIoKSxcbiAgICAgICAgICBkdXJhdGlvbjogdGhpcy5zdHJlYW0ucmVhZFVJbnQzMigpXG4gICAgICAgIH07XG4gICAgICB9XG4gICAgICByZXR1cm4gdGhpcy5zZXR1cFNlZWtQb2ludHMoKTtcbiAgICB9KTtcblxuICAgIGF0b20oJ21vb3YudHJhay5tZGlhLm1pbmYuc3RibC5zdHNjJywgZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgZW50cmllcywgaSwgaywgcmVmO1xuICAgICAgdGhpcy5zdHJlYW0uYWR2YW5jZSg0KTtcbiAgICAgIGVudHJpZXMgPSB0aGlzLnN0cmVhbS5yZWFkVUludDMyKCk7XG4gICAgICB0aGlzLnRyYWNrLnN0c2MgPSBbXTtcbiAgICAgIGZvciAoaSA9IGsgPSAwLCByZWYgPSBlbnRyaWVzOyBrIDwgcmVmOyBpID0gayArPSAxKSB7XG4gICAgICAgIHRoaXMudHJhY2suc3RzY1tpXSA9IHtcbiAgICAgICAgICBmaXJzdDogdGhpcy5zdHJlYW0ucmVhZFVJbnQzMigpLFxuICAgICAgICAgIGNvdW50OiB0aGlzLnN0cmVhbS5yZWFkVUludDMyKCksXG4gICAgICAgICAgaWQ6IHRoaXMuc3RyZWFtLnJlYWRVSW50MzIoKVxuICAgICAgICB9O1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXMuc2V0dXBTZWVrUG9pbnRzKCk7XG4gICAgfSk7XG5cbiAgICBhdG9tKCdtb292LnRyYWsubWRpYS5taW5mLnN0Ymwuc3RzeicsIGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIGVudHJpZXMsIGksIGssIHJlZjtcbiAgICAgIHRoaXMuc3RyZWFtLmFkdmFuY2UoNCk7XG4gICAgICB0aGlzLnRyYWNrLnNhbXBsZVNpemUgPSB0aGlzLnN0cmVhbS5yZWFkVUludDMyKCk7XG4gICAgICBlbnRyaWVzID0gdGhpcy5zdHJlYW0ucmVhZFVJbnQzMigpO1xuICAgICAgaWYgKHRoaXMudHJhY2suc2FtcGxlU2l6ZSA9PT0gMCAmJiBlbnRyaWVzID4gMCkge1xuICAgICAgICB0aGlzLnRyYWNrLnNhbXBsZVNpemVzID0gW107XG4gICAgICAgIGZvciAoaSA9IGsgPSAwLCByZWYgPSBlbnRyaWVzOyBrIDwgcmVmOyBpID0gayArPSAxKSB7XG4gICAgICAgICAgdGhpcy50cmFjay5zYW1wbGVTaXplc1tpXSA9IHRoaXMuc3RyZWFtLnJlYWRVSW50MzIoKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXMuc2V0dXBTZWVrUG9pbnRzKCk7XG4gICAgfSk7XG5cbiAgICBhdG9tKCdtb292LnRyYWsubWRpYS5taW5mLnN0Ymwuc3RjbycsIGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIGVudHJpZXMsIGksIGssIHJlZjtcbiAgICAgIHRoaXMuc3RyZWFtLmFkdmFuY2UoNCk7XG4gICAgICBlbnRyaWVzID0gdGhpcy5zdHJlYW0ucmVhZFVJbnQzMigpO1xuICAgICAgdGhpcy50cmFjay5jaHVua09mZnNldHMgPSBbXTtcbiAgICAgIGZvciAoaSA9IGsgPSAwLCByZWYgPSBlbnRyaWVzOyBrIDwgcmVmOyBpID0gayArPSAxKSB7XG4gICAgICAgIHRoaXMudHJhY2suY2h1bmtPZmZzZXRzW2ldID0gdGhpcy5zdHJlYW0ucmVhZFVJbnQzMigpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXMuc2V0dXBTZWVrUG9pbnRzKCk7XG4gICAgfSk7XG5cbiAgICBhdG9tKCdtb292LnRyYWsudHJlZi5jaGFwJywgZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgZW50cmllcywgaSwgaywgcmVmO1xuICAgICAgZW50cmllcyA9IHRoaXMubGVuID4+IDI7XG4gICAgICB0aGlzLnRyYWNrLmNoYXB0ZXJUcmFja3MgPSBbXTtcbiAgICAgIGZvciAoaSA9IGsgPSAwLCByZWYgPSBlbnRyaWVzOyBrIDwgcmVmOyBpID0gayArPSAxKSB7XG4gICAgICAgIHRoaXMudHJhY2suY2hhcHRlclRyYWNrc1tpXSA9IHRoaXMuc3RyZWFtLnJlYWRVSW50MzIoKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIE00QURlbXV4ZXIucHJvdG90eXBlLnNldHVwU2Vla1BvaW50cyA9IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIGksIGosIGssIGwsIGxlbjEsIG9mZnNldCwgcG9zaXRpb24sIHJlZiwgcmVmMSwgcmVzdWx0cywgc2FtcGxlSW5kZXgsIHNpemUsIHN0c2NJbmRleCwgc3R0c0luZGV4LCBzdHRzU2FtcGxlLCB0aW1lc3RhbXA7XG4gICAgICBpZiAoISgodGhpcy50cmFjay5jaHVua09mZnNldHMgIT0gbnVsbCkgJiYgKHRoaXMudHJhY2suc3RzYyAhPSBudWxsKSAmJiAodGhpcy50cmFjay5zYW1wbGVTaXplICE9IG51bGwpICYmICh0aGlzLnRyYWNrLnN0dHMgIT0gbnVsbCkpKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIHN0c2NJbmRleCA9IDA7XG4gICAgICBzdHRzSW5kZXggPSAwO1xuICAgICAgc3R0c0luZGV4ID0gMDtcbiAgICAgIHN0dHNTYW1wbGUgPSAwO1xuICAgICAgc2FtcGxlSW5kZXggPSAwO1xuICAgICAgb2Zmc2V0ID0gMDtcbiAgICAgIHRpbWVzdGFtcCA9IDA7XG4gICAgICB0aGlzLnRyYWNrLnNlZWtQb2ludHMgPSBbXTtcbiAgICAgIHJlZiA9IHRoaXMudHJhY2suY2h1bmtPZmZzZXRzO1xuICAgICAgcmVzdWx0cyA9IFtdO1xuICAgICAgZm9yIChpID0gayA9IDAsIGxlbjEgPSByZWYubGVuZ3RoOyBrIDwgbGVuMTsgaSA9ICsraykge1xuICAgICAgICBwb3NpdGlvbiA9IHJlZltpXTtcbiAgICAgICAgZm9yIChqID0gbCA9IDAsIHJlZjEgPSB0aGlzLnRyYWNrLnN0c2Nbc3RzY0luZGV4XS5jb3VudDsgbCA8IHJlZjE7IGogPSBsICs9IDEpIHtcbiAgICAgICAgICB0aGlzLnRyYWNrLnNlZWtQb2ludHMucHVzaCh7XG4gICAgICAgICAgICBvZmZzZXQ6IG9mZnNldCxcbiAgICAgICAgICAgIHBvc2l0aW9uOiBwb3NpdGlvbixcbiAgICAgICAgICAgIHRpbWVzdGFtcDogdGltZXN0YW1wXG4gICAgICAgICAgfSk7XG4gICAgICAgICAgc2l6ZSA9IHRoaXMudHJhY2suc2FtcGxlU2l6ZSB8fCB0aGlzLnRyYWNrLnNhbXBsZVNpemVzW3NhbXBsZUluZGV4KytdO1xuICAgICAgICAgIG9mZnNldCArPSBzaXplO1xuICAgICAgICAgIHBvc2l0aW9uICs9IHNpemU7XG4gICAgICAgICAgdGltZXN0YW1wICs9IHRoaXMudHJhY2suc3R0c1tzdHRzSW5kZXhdLmR1cmF0aW9uO1xuICAgICAgICAgIGlmIChzdHRzSW5kZXggKyAxIDwgdGhpcy50cmFjay5zdHRzLmxlbmd0aCAmJiArK3N0dHNTYW1wbGUgPT09IHRoaXMudHJhY2suc3R0c1tzdHRzSW5kZXhdLmNvdW50KSB7XG4gICAgICAgICAgICBzdHRzU2FtcGxlID0gMDtcbiAgICAgICAgICAgIHN0dHNJbmRleCsrO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAoc3RzY0luZGV4ICsgMSA8IHRoaXMudHJhY2suc3RzYy5sZW5ndGggJiYgaSArIDEgPT09IHRoaXMudHJhY2suc3RzY1tzdHNjSW5kZXggKyAxXS5maXJzdCkge1xuICAgICAgICAgIHJlc3VsdHMucHVzaChzdHNjSW5kZXgrKyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmVzdWx0cy5wdXNoKHZvaWQgMCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiByZXN1bHRzO1xuICAgIH07XG5cbiAgICBhZnRlcignbW9vdicsIGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIGssIGxlbjEsIHJlZiwgdHJhY2s7XG4gICAgICBpZiAodGhpcy5tZGF0T2Zmc2V0ICE9IG51bGwpIHtcbiAgICAgICAgdGhpcy5zdHJlYW0uc2Vlayh0aGlzLm1kYXRPZmZzZXQgLSA4KTtcbiAgICAgIH1cbiAgICAgIHJlZiA9IHRoaXMudHJhY2tzO1xuICAgICAgZm9yIChrID0gMCwgbGVuMSA9IHJlZi5sZW5ndGg7IGsgPCBsZW4xOyBrKyspIHtcbiAgICAgICAgdHJhY2sgPSByZWZba107XG4gICAgICAgIGlmICghKHRyYWNrLnR5cGUgPT09ICdzb3VuJykpIHtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnRyYWNrID0gdHJhY2s7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgaWYgKHRoaXMudHJhY2sudHlwZSAhPT0gJ3NvdW4nKSB7XG4gICAgICAgIHRoaXMudHJhY2sgPSBudWxsO1xuICAgICAgICByZXR1cm4gdGhpcy5lbWl0KCdlcnJvcicsICdObyBhdWRpbyB0cmFja3MgaW4gbTRhIGZpbGUuJyk7XG4gICAgICB9XG4gICAgICB0aGlzLmVtaXQoJ2Zvcm1hdCcsIHRoaXMudHJhY2suZm9ybWF0KTtcbiAgICAgIHRoaXMuZW1pdCgnZHVyYXRpb24nLCB0aGlzLnRyYWNrLmR1cmF0aW9uIC8gdGhpcy50cmFjay50aW1lU2NhbGUgKiAxMDAwIHwgMCk7XG4gICAgICBpZiAodGhpcy50cmFjay5jb29raWUpIHtcbiAgICAgICAgdGhpcy5lbWl0KCdjb29raWUnLCB0aGlzLnRyYWNrLmNvb2tpZSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gdGhpcy5zZWVrUG9pbnRzID0gdGhpcy50cmFjay5zZWVrUG9pbnRzO1xuICAgIH0pO1xuXG4gICAgYXRvbSgnbWRhdCcsIGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIGJ5dGVzLCBjaHVua1NpemUsIGssIGxlbmd0aCwgbnVtU2FtcGxlcywgb2Zmc2V0LCByZWYsIHNhbXBsZSwgc2l6ZTtcbiAgICAgIGlmICghdGhpcy5zdGFydGVkRGF0YSkge1xuICAgICAgICBpZiAodGhpcy5tZGF0T2Zmc2V0ID09IG51bGwpIHtcbiAgICAgICAgICB0aGlzLm1kYXRPZmZzZXQgPSB0aGlzLnN0cmVhbS5vZmZzZXQ7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMudHJhY2tzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgIGJ5dGVzID0gTWF0aC5taW4odGhpcy5zdHJlYW0ucmVtYWluaW5nQnl0ZXMoKSwgdGhpcy5sZW4pO1xuICAgICAgICAgIHRoaXMuc3RyZWFtLmFkdmFuY2UoYnl0ZXMpO1xuICAgICAgICAgIHRoaXMubGVuIC09IGJ5dGVzO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmNodW5rSW5kZXggPSAwO1xuICAgICAgICB0aGlzLnN0c2NJbmRleCA9IDA7XG4gICAgICAgIHRoaXMuc2FtcGxlSW5kZXggPSAwO1xuICAgICAgICB0aGlzLnRhaWxPZmZzZXQgPSAwO1xuICAgICAgICB0aGlzLnRhaWxTYW1wbGVzID0gMDtcbiAgICAgICAgdGhpcy5zdGFydGVkRGF0YSA9IHRydWU7XG4gICAgICB9XG4gICAgICBpZiAoIXRoaXMucmVhZENoYXB0ZXJzKSB7XG4gICAgICAgIHRoaXMucmVhZENoYXB0ZXJzID0gdGhpcy5wYXJzZUNoYXB0ZXJzKCk7XG4gICAgICAgIGlmICh0aGlzW1wiYnJlYWtcIl0gPSAhdGhpcy5yZWFkQ2hhcHRlcnMpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5zdHJlYW0uc2Vlayh0aGlzLm1kYXRPZmZzZXQpO1xuICAgICAgfVxuICAgICAgb2Zmc2V0ID0gdGhpcy50cmFjay5jaHVua09mZnNldHNbdGhpcy5jaHVua0luZGV4XSArIHRoaXMudGFpbE9mZnNldDtcbiAgICAgIGxlbmd0aCA9IDA7XG4gICAgICBpZiAoIXRoaXMuc3RyZWFtLmF2YWlsYWJsZShvZmZzZXQgLSB0aGlzLnN0cmVhbS5vZmZzZXQpKSB7XG4gICAgICAgIHRoaXNbXCJicmVha1wiXSA9IHRydWU7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIHRoaXMuc3RyZWFtLnNlZWsob2Zmc2V0KTtcbiAgICAgIHdoaWxlICh0aGlzLmNodW5rSW5kZXggPCB0aGlzLnRyYWNrLmNodW5rT2Zmc2V0cy5sZW5ndGgpIHtcbiAgICAgICAgbnVtU2FtcGxlcyA9IHRoaXMudHJhY2suc3RzY1t0aGlzLnN0c2NJbmRleF0uY291bnQgLSB0aGlzLnRhaWxTYW1wbGVzO1xuICAgICAgICBjaHVua1NpemUgPSAwO1xuICAgICAgICBmb3IgKHNhbXBsZSA9IGsgPSAwLCByZWYgPSBudW1TYW1wbGVzOyBrIDwgcmVmOyBzYW1wbGUgPSBrICs9IDEpIHtcbiAgICAgICAgICBzaXplID0gdGhpcy50cmFjay5zYW1wbGVTaXplIHx8IHRoaXMudHJhY2suc2FtcGxlU2l6ZXNbdGhpcy5zYW1wbGVJbmRleF07XG4gICAgICAgICAgaWYgKCF0aGlzLnN0cmVhbS5hdmFpbGFibGUobGVuZ3RoICsgc2l6ZSkpIHtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgICBsZW5ndGggKz0gc2l6ZTtcbiAgICAgICAgICBjaHVua1NpemUgKz0gc2l6ZTtcbiAgICAgICAgICB0aGlzLnNhbXBsZUluZGV4Kys7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHNhbXBsZSA8IG51bVNhbXBsZXMpIHtcbiAgICAgICAgICB0aGlzLnRhaWxPZmZzZXQgKz0gY2h1bmtTaXplO1xuICAgICAgICAgIHRoaXMudGFpbFNhbXBsZXMgKz0gc2FtcGxlO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRoaXMuY2h1bmtJbmRleCsrO1xuICAgICAgICAgIHRoaXMudGFpbE9mZnNldCA9IDA7XG4gICAgICAgICAgdGhpcy50YWlsU2FtcGxlcyA9IDA7XG4gICAgICAgICAgaWYgKHRoaXMuc3RzY0luZGV4ICsgMSA8IHRoaXMudHJhY2suc3RzYy5sZW5ndGggJiYgdGhpcy5jaHVua0luZGV4ICsgMSA9PT0gdGhpcy50cmFjay5zdHNjW3RoaXMuc3RzY0luZGV4ICsgMV0uZmlyc3QpIHtcbiAgICAgICAgICAgIHRoaXMuc3RzY0luZGV4Kys7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChvZmZzZXQgKyBsZW5ndGggIT09IHRoaXMudHJhY2suY2h1bmtPZmZzZXRzW3RoaXMuY2h1bmtJbmRleF0pIHtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKGxlbmd0aCA+IDApIHtcbiAgICAgICAgdGhpcy5lbWl0KCdkYXRhJywgdGhpcy5zdHJlYW0ucmVhZEJ1ZmZlcihsZW5ndGgpKTtcbiAgICAgICAgcmV0dXJuIHRoaXNbXCJicmVha1wiXSA9IHRoaXMuY2h1bmtJbmRleCA9PT0gdGhpcy50cmFjay5jaHVua09mZnNldHMubGVuZ3RoO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIHRoaXNbXCJicmVha1wiXSA9IHRydWU7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBNNEFEZW11eGVyLnByb3RvdHlwZS5wYXJzZUNoYXB0ZXJzID0gZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgYm9tLCBpZCwgaywgbGVuLCBsZW4xLCBuZXh0VGltZXN0YW1wLCBwb2ludCwgcmVmLCByZWYxLCByZWYyLCByZWYzLCB0aXRsZSwgdHJhY2s7XG4gICAgICBpZiAoISgoKHJlZiA9IHRoaXMudHJhY2suY2hhcHRlclRyYWNrcykgIT0gbnVsbCA/IHJlZi5sZW5ndGggOiB2b2lkIDApID4gMCkpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgICBpZCA9IHRoaXMudHJhY2suY2hhcHRlclRyYWNrc1swXTtcbiAgICAgIHJlZjEgPSB0aGlzLnRyYWNrcztcbiAgICAgIGZvciAoayA9IDAsIGxlbjEgPSByZWYxLmxlbmd0aDsgayA8IGxlbjE7IGsrKykge1xuICAgICAgICB0cmFjayA9IHJlZjFba107XG4gICAgICAgIGlmICh0cmFjay5pZCA9PT0gaWQpIHtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKHRyYWNrLmlkICE9PSBpZCkge1xuICAgICAgICB0aGlzLmVtaXQoJ2Vycm9yJywgJ0NoYXB0ZXIgdHJhY2sgZG9lcyBub3QgZXhpc3QuJyk7XG4gICAgICB9XG4gICAgICBpZiAodGhpcy5jaGFwdGVycyA9PSBudWxsKSB7XG4gICAgICAgIHRoaXMuY2hhcHRlcnMgPSBbXTtcbiAgICAgIH1cbiAgICAgIHdoaWxlICh0aGlzLmNoYXB0ZXJzLmxlbmd0aCA8IHRyYWNrLnNlZWtQb2ludHMubGVuZ3RoKSB7XG4gICAgICAgIHBvaW50ID0gdHJhY2suc2Vla1BvaW50c1t0aGlzLmNoYXB0ZXJzLmxlbmd0aF07XG4gICAgICAgIGlmICghdGhpcy5zdHJlYW0uYXZhaWxhYmxlKHBvaW50LnBvc2l0aW9uIC0gdGhpcy5zdHJlYW0ub2Zmc2V0ICsgMzIpKSB7XG4gICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuc3RyZWFtLnNlZWsocG9pbnQucG9zaXRpb24pO1xuICAgICAgICBsZW4gPSB0aGlzLnN0cmVhbS5yZWFkVUludDE2KCk7XG4gICAgICAgIHRpdGxlID0gbnVsbDtcbiAgICAgICAgaWYgKCF0aGlzLnN0cmVhbS5hdmFpbGFibGUobGVuKSkge1xuICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAobGVuID4gMikge1xuICAgICAgICAgIGJvbSA9IHRoaXMuc3RyZWFtLnBlZWtVSW50MTYoKTtcbiAgICAgICAgICBpZiAoYm9tID09PSAweGZlZmYgfHwgYm9tID09PSAweGZmZmUpIHtcbiAgICAgICAgICAgIHRpdGxlID0gdGhpcy5zdHJlYW0ucmVhZFN0cmluZyhsZW4sICd1dGYxNi1ib20nKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRpdGxlID09IG51bGwpIHtcbiAgICAgICAgICB0aXRsZSA9IHRoaXMuc3RyZWFtLnJlYWRTdHJpbmcobGVuLCAndXRmOCcpO1xuICAgICAgICB9XG4gICAgICAgIG5leHRUaW1lc3RhbXAgPSAocmVmMiA9IChyZWYzID0gdHJhY2suc2Vla1BvaW50c1t0aGlzLmNoYXB0ZXJzLmxlbmd0aCArIDFdKSAhPSBudWxsID8gcmVmMy50aW1lc3RhbXAgOiB2b2lkIDApICE9IG51bGwgPyByZWYyIDogdHJhY2suZHVyYXRpb247XG4gICAgICAgIHRoaXMuY2hhcHRlcnMucHVzaCh7XG4gICAgICAgICAgdGl0bGU6IHRpdGxlLFxuICAgICAgICAgIHRpbWVzdGFtcDogcG9pbnQudGltZXN0YW1wIC8gdHJhY2sudGltZVNjYWxlICogMTAwMCB8IDAsXG4gICAgICAgICAgZHVyYXRpb246IChuZXh0VGltZXN0YW1wIC0gcG9pbnQudGltZXN0YW1wKSAvIHRyYWNrLnRpbWVTY2FsZSAqIDEwMDAgfCAwXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgdGhpcy5lbWl0KCdjaGFwdGVycycsIHRoaXMuY2hhcHRlcnMpO1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfTtcblxuICAgIGF0b20oJ21vb3YudWR0YS5tZXRhJywgZnVuY3Rpb24oKSB7XG4gICAgICB0aGlzLm1ldGFkYXRhID0ge307XG4gICAgICByZXR1cm4gdGhpcy5zdHJlYW0uYWR2YW5jZSg0KTtcbiAgICB9KTtcblxuICAgIGFmdGVyKCdtb292LnVkdGEubWV0YScsIGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHRoaXMuZW1pdCgnbWV0YWRhdGEnLCB0aGlzLm1ldGFkYXRhKTtcbiAgICB9KTtcblxuICAgIG1ldGEgPSBmdW5jdGlvbihmaWVsZCwgbmFtZSwgZm4pIHtcbiAgICAgIHJldHVybiBhdG9tKFwibW9vdi51ZHRhLm1ldGEuaWxzdC5cIiArIGZpZWxkICsgXCIuZGF0YVwiLCBmdW5jdGlvbigpIHtcbiAgICAgICAgdGhpcy5zdHJlYW0uYWR2YW5jZSg4KTtcbiAgICAgICAgdGhpcy5sZW4gLT0gODtcbiAgICAgICAgcmV0dXJuIGZuLmNhbGwodGhpcywgbmFtZSk7XG4gICAgICB9KTtcbiAgICB9O1xuXG4gICAgc3RyaW5nID0gZnVuY3Rpb24oZmllbGQpIHtcbiAgICAgIHJldHVybiB0aGlzLm1ldGFkYXRhW2ZpZWxkXSA9IHRoaXMuc3RyZWFtLnJlYWRTdHJpbmcodGhpcy5sZW4sICd1dGY4Jyk7XG4gICAgfTtcblxuICAgIG1ldGEoJ8KpYWxiJywgJ2FsYnVtJywgc3RyaW5nKTtcblxuICAgIG1ldGEoJ8KpYXJnJywgJ2FycmFuZ2VyJywgc3RyaW5nKTtcblxuICAgIG1ldGEoJ8KpYXJ0JywgJ2FydGlzdCcsIHN0cmluZyk7XG5cbiAgICBtZXRhKCfCqUFSVCcsICdhcnRpc3QnLCBzdHJpbmcpO1xuXG4gICAgbWV0YSgnYUFSVCcsICdhbGJ1bUFydGlzdCcsIHN0cmluZyk7XG5cbiAgICBtZXRhKCdjYXRnJywgJ2NhdGVnb3J5Jywgc3RyaW5nKTtcblxuICAgIG1ldGEoJ8KpY29tJywgJ2NvbXBvc2VyJywgc3RyaW5nKTtcblxuICAgIG1ldGEoJ8KpY3B5JywgJ2NvcHlyaWdodCcsIHN0cmluZyk7XG5cbiAgICBtZXRhKCdjcHJ0JywgJ2NvcHlyaWdodCcsIHN0cmluZyk7XG5cbiAgICBtZXRhKCfCqWNtdCcsICdjb21tZW50cycsIHN0cmluZyk7XG5cbiAgICBtZXRhKCfCqWRheScsICdyZWxlYXNlRGF0ZScsIHN0cmluZyk7XG5cbiAgICBtZXRhKCdkZXNjJywgJ2Rlc2NyaXB0aW9uJywgc3RyaW5nKTtcblxuICAgIG1ldGEoJ8KpZ2VuJywgJ2dlbnJlJywgc3RyaW5nKTtcblxuICAgIG1ldGEoJ8KpZ3JwJywgJ2dyb3VwaW5nJywgc3RyaW5nKTtcblxuICAgIG1ldGEoJ8KpaXNyJywgJ0lTUkMnLCBzdHJpbmcpO1xuXG4gICAgbWV0YSgna2V5dycsICdrZXl3b3JkcycsIHN0cmluZyk7XG5cbiAgICBtZXRhKCfCqWxhYicsICdyZWNvcmRMYWJlbCcsIHN0cmluZyk7XG5cbiAgICBtZXRhKCdsZGVzJywgJ2xvbmdEZXNjcmlwdGlvbicsIHN0cmluZyk7XG5cbiAgICBtZXRhKCfCqWx5cicsICdseXJpY3MnLCBzdHJpbmcpO1xuXG4gICAgbWV0YSgnwqluYW0nLCAndGl0bGUnLCBzdHJpbmcpO1xuXG4gICAgbWV0YSgnwqlwaGcnLCAncmVjb3JkaW5nQ29weXJpZ2h0Jywgc3RyaW5nKTtcblxuICAgIG1ldGEoJ8KpcHJkJywgJ3Byb2R1Y2VyJywgc3RyaW5nKTtcblxuICAgIG1ldGEoJ8KpcHJmJywgJ3BlcmZvcm1lcnMnLCBzdHJpbmcpO1xuXG4gICAgbWV0YSgncHVyZCcsICdwdXJjaGFzZURhdGUnLCBzdHJpbmcpO1xuXG4gICAgbWV0YSgncHVybCcsICdwb2RjYXN0VVJMJywgc3RyaW5nKTtcblxuICAgIG1ldGEoJ8Kpc3dmJywgJ3Nvbmd3cml0ZXInLCBzdHJpbmcpO1xuXG4gICAgbWV0YSgnwql0b28nLCAnZW5jb2RlcicsIHN0cmluZyk7XG5cbiAgICBtZXRhKCfCqXdydCcsICdjb21wb3NlcicsIHN0cmluZyk7XG5cbiAgICBtZXRhKCdjb3ZyJywgJ2NvdmVyQXJ0JywgZnVuY3Rpb24oZmllbGQpIHtcbiAgICAgIHJldHVybiB0aGlzLm1ldGFkYXRhW2ZpZWxkXSA9IHRoaXMuc3RyZWFtLnJlYWRCdWZmZXIodGhpcy5sZW4pO1xuICAgIH0pO1xuXG4gICAgZ2VucmVzID0gW1wiQmx1ZXNcIiwgXCJDbGFzc2ljIFJvY2tcIiwgXCJDb3VudHJ5XCIsIFwiRGFuY2VcIiwgXCJEaXNjb1wiLCBcIkZ1bmtcIiwgXCJHcnVuZ2VcIiwgXCJIaXAtSG9wXCIsIFwiSmF6elwiLCBcIk1ldGFsXCIsIFwiTmV3IEFnZVwiLCBcIk9sZGllc1wiLCBcIk90aGVyXCIsIFwiUG9wXCIsIFwiUiZCXCIsIFwiUmFwXCIsIFwiUmVnZ2FlXCIsIFwiUm9ja1wiLCBcIlRlY2hub1wiLCBcIkluZHVzdHJpYWxcIiwgXCJBbHRlcm5hdGl2ZVwiLCBcIlNrYVwiLCBcIkRlYXRoIE1ldGFsXCIsIFwiUHJhbmtzXCIsIFwiU291bmR0cmFja1wiLCBcIkV1cm8tVGVjaG5vXCIsIFwiQW1iaWVudFwiLCBcIlRyaXAtSG9wXCIsIFwiVm9jYWxcIiwgXCJKYXp6K0Z1bmtcIiwgXCJGdXNpb25cIiwgXCJUcmFuY2VcIiwgXCJDbGFzc2ljYWxcIiwgXCJJbnN0cnVtZW50YWxcIiwgXCJBY2lkXCIsIFwiSG91c2VcIiwgXCJHYW1lXCIsIFwiU291bmQgQ2xpcFwiLCBcIkdvc3BlbFwiLCBcIk5vaXNlXCIsIFwiQWx0ZXJuUm9ja1wiLCBcIkJhc3NcIiwgXCJTb3VsXCIsIFwiUHVua1wiLCBcIlNwYWNlXCIsIFwiTWVkaXRhdGl2ZVwiLCBcIkluc3RydW1lbnRhbCBQb3BcIiwgXCJJbnN0cnVtZW50YWwgUm9ja1wiLCBcIkV0aG5pY1wiLCBcIkdvdGhpY1wiLCBcIkRhcmt3YXZlXCIsIFwiVGVjaG5vLUluZHVzdHJpYWxcIiwgXCJFbGVjdHJvbmljXCIsIFwiUG9wLUZvbGtcIiwgXCJFdXJvZGFuY2VcIiwgXCJEcmVhbVwiLCBcIlNvdXRoZXJuIFJvY2tcIiwgXCJDb21lZHlcIiwgXCJDdWx0XCIsIFwiR2FuZ3N0YVwiLCBcIlRvcCA0MFwiLCBcIkNocmlzdGlhbiBSYXBcIiwgXCJQb3AvRnVua1wiLCBcIkp1bmdsZVwiLCBcIk5hdGl2ZSBBbWVyaWNhblwiLCBcIkNhYmFyZXRcIiwgXCJOZXcgV2F2ZVwiLCBcIlBzeWNoYWRlbGljXCIsIFwiUmF2ZVwiLCBcIlNob3d0dW5lc1wiLCBcIlRyYWlsZXJcIiwgXCJMby1GaVwiLCBcIlRyaWJhbFwiLCBcIkFjaWQgUHVua1wiLCBcIkFjaWQgSmF6elwiLCBcIlBvbGthXCIsIFwiUmV0cm9cIiwgXCJNdXNpY2FsXCIsIFwiUm9jayAmIFJvbGxcIiwgXCJIYXJkIFJvY2tcIiwgXCJGb2xrXCIsIFwiRm9say9Sb2NrXCIsIFwiTmF0aW9uYWwgRm9sa1wiLCBcIlN3aW5nXCIsIFwiRmFzdCBGdXNpb25cIiwgXCJCZWJvYlwiLCBcIkxhdGluXCIsIFwiUmV2aXZhbFwiLCBcIkNlbHRpY1wiLCBcIkJsdWVncmFzc1wiLCBcIkF2YW50Z2FyZGVcIiwgXCJHb3RoaWMgUm9ja1wiLCBcIlByb2dyZXNzaXZlIFJvY2tcIiwgXCJQc3ljaGVkZWxpYyBSb2NrXCIsIFwiU3ltcGhvbmljIFJvY2tcIiwgXCJTbG93IFJvY2tcIiwgXCJCaWcgQmFuZFwiLCBcIkNob3J1c1wiLCBcIkVhc3kgTGlzdGVuaW5nXCIsIFwiQWNvdXN0aWNcIiwgXCJIdW1vdXJcIiwgXCJTcGVlY2hcIiwgXCJDaGFuc29uXCIsIFwiT3BlcmFcIiwgXCJDaGFtYmVyIE11c2ljXCIsIFwiU29uYXRhXCIsIFwiU3ltcGhvbnlcIiwgXCJCb290eSBCYXNzXCIsIFwiUHJpbXVzXCIsIFwiUG9ybiBHcm9vdmVcIiwgXCJTYXRpcmVcIiwgXCJTbG93IEphbVwiLCBcIkNsdWJcIiwgXCJUYW5nb1wiLCBcIlNhbWJhXCIsIFwiRm9sa2xvcmVcIiwgXCJCYWxsYWRcIiwgXCJQb3dlciBCYWxsYWRcIiwgXCJSaHl0aG1pYyBTb3VsXCIsIFwiRnJlZXN0eWxlXCIsIFwiRHVldFwiLCBcIlB1bmsgUm9ja1wiLCBcIkRydW0gU29sb1wiLCBcIkEgQ2FwZWxsYVwiLCBcIkV1cm8tSG91c2VcIiwgXCJEYW5jZSBIYWxsXCJdO1xuXG4gICAgbWV0YSgnZ25yZScsICdnZW5yZScsIGZ1bmN0aW9uKGZpZWxkKSB7XG4gICAgICByZXR1cm4gdGhpcy5tZXRhZGF0YVtmaWVsZF0gPSBnZW5yZXNbdGhpcy5zdHJlYW0ucmVhZFVJbnQxNigpIC0gMV07XG4gICAgfSk7XG5cbiAgICBtZXRhKCd0bXBvJywgJ3RlbXBvJywgZnVuY3Rpb24oZmllbGQpIHtcbiAgICAgIHJldHVybiB0aGlzLm1ldGFkYXRhW2ZpZWxkXSA9IHRoaXMuc3RyZWFtLnJlYWRVSW50MTYoKTtcbiAgICB9KTtcblxuICAgIG1ldGEoJ3J0bmcnLCAncmF0aW5nJywgZnVuY3Rpb24oZmllbGQpIHtcbiAgICAgIHZhciByYXRpbmc7XG4gICAgICByYXRpbmcgPSB0aGlzLnN0cmVhbS5yZWFkVUludDgoKTtcbiAgICAgIHJldHVybiB0aGlzLm1ldGFkYXRhW2ZpZWxkXSA9IHJhdGluZyA9PT0gMiA/ICdDbGVhbicgOiByYXRpbmcgIT09IDAgPyAnRXhwbGljaXQnIDogJ05vbmUnO1xuICAgIH0pO1xuXG4gICAgZGlza1RyYWNrID0gZnVuY3Rpb24oZmllbGQpIHtcbiAgICAgIHRoaXMuc3RyZWFtLmFkdmFuY2UoMik7XG4gICAgICB0aGlzLm1ldGFkYXRhW2ZpZWxkXSA9IHRoaXMuc3RyZWFtLnJlYWRVSW50MTYoKSArICcgb2YgJyArIHRoaXMuc3RyZWFtLnJlYWRVSW50MTYoKTtcbiAgICAgIHJldHVybiB0aGlzLnN0cmVhbS5hZHZhbmNlKHRoaXMubGVuIC0gNik7XG4gICAgfTtcblxuICAgIG1ldGEoJ2Rpc2snLCAnZGlza051bWJlcicsIGRpc2tUcmFjayk7XG5cbiAgICBtZXRhKCd0cmtuJywgJ3RyYWNrTnVtYmVyJywgZGlza1RyYWNrKTtcblxuICAgIGJvb2wgPSBmdW5jdGlvbihmaWVsZCkge1xuICAgICAgcmV0dXJuIHRoaXMubWV0YWRhdGFbZmllbGRdID0gdGhpcy5zdHJlYW0ucmVhZFVJbnQ4KCkgPT09IDE7XG4gICAgfTtcblxuICAgIG1ldGEoJ2NwaWwnLCAnY29tcGlsYXRpb24nLCBib29sKTtcblxuICAgIG1ldGEoJ3Bjc3QnLCAncG9kY2FzdCcsIGJvb2wpO1xuXG4gICAgbWV0YSgncGdhcCcsICdnYXBsZXNzJywgYm9vbCk7XG5cbiAgICByZXR1cm4gTTRBRGVtdXhlcjtcblxuICB9KShEZW11eGVyKTtcblxuICBtb2R1bGUuZXhwb3J0cyA9IE00QURlbXV4ZXI7XG5cbn0pLmNhbGwodGhpcyk7XG4iLCIvLyBHZW5lcmF0ZWQgYnkgQ29mZmVlU2NyaXB0IDEuMTIuN1xuKGZ1bmN0aW9uKCkge1xuICB2YXIgRGVtdXhlciwgV0FWRURlbXV4ZXIsXG4gICAgZXh0ZW5kID0gZnVuY3Rpb24oY2hpbGQsIHBhcmVudCkgeyBmb3IgKHZhciBrZXkgaW4gcGFyZW50KSB7IGlmIChoYXNQcm9wLmNhbGwocGFyZW50LCBrZXkpKSBjaGlsZFtrZXldID0gcGFyZW50W2tleV07IH0gZnVuY3Rpb24gY3RvcigpIHsgdGhpcy5jb25zdHJ1Y3RvciA9IGNoaWxkOyB9IGN0b3IucHJvdG90eXBlID0gcGFyZW50LnByb3RvdHlwZTsgY2hpbGQucHJvdG90eXBlID0gbmV3IGN0b3IoKTsgY2hpbGQuX19zdXBlcl9fID0gcGFyZW50LnByb3RvdHlwZTsgcmV0dXJuIGNoaWxkOyB9LFxuICAgIGhhc1Byb3AgPSB7fS5oYXNPd25Qcm9wZXJ0eTtcblxuICBEZW11eGVyID0gcmVxdWlyZSgnLi4vZGVtdXhlcicpO1xuXG4gIFdBVkVEZW11eGVyID0gKGZ1bmN0aW9uKHN1cGVyQ2xhc3MpIHtcbiAgICB2YXIgZm9ybWF0cztcblxuICAgIGV4dGVuZChXQVZFRGVtdXhlciwgc3VwZXJDbGFzcyk7XG5cbiAgICBmdW5jdGlvbiBXQVZFRGVtdXhlcigpIHtcbiAgICAgIHJldHVybiBXQVZFRGVtdXhlci5fX3N1cGVyX18uY29uc3RydWN0b3IuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICB9XG5cbiAgICBEZW11eGVyLnJlZ2lzdGVyKFdBVkVEZW11eGVyKTtcblxuICAgIFdBVkVEZW11eGVyLnByb2JlID0gZnVuY3Rpb24oYnVmZmVyKSB7XG4gICAgICByZXR1cm4gYnVmZmVyLnBlZWtTdHJpbmcoMCwgNCkgPT09ICdSSUZGJyAmJiBidWZmZXIucGVla1N0cmluZyg4LCA0KSA9PT0gJ1dBVkUnO1xuICAgIH07XG5cbiAgICBmb3JtYXRzID0ge1xuICAgICAgMHgwMDAxOiAnbHBjbScsXG4gICAgICAweDAwMDM6ICdscGNtJyxcbiAgICAgIDB4MDAwNjogJ2FsYXcnLFxuICAgICAgMHgwMDA3OiAndWxhdydcbiAgICB9O1xuXG4gICAgV0FWRURlbXV4ZXIucHJvdG90eXBlLnJlYWRDaHVuayA9IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIGJ1ZmZlciwgYnl0ZXMsIGVuY29kaW5nO1xuICAgICAgaWYgKCF0aGlzLnJlYWRTdGFydCAmJiB0aGlzLnN0cmVhbS5hdmFpbGFibGUoMTIpKSB7XG4gICAgICAgIGlmICh0aGlzLnN0cmVhbS5yZWFkU3RyaW5nKDQpICE9PSAnUklGRicpIHtcbiAgICAgICAgICByZXR1cm4gdGhpcy5lbWl0KCdlcnJvcicsICdJbnZhbGlkIFdBViBmaWxlLicpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuZmlsZVNpemUgPSB0aGlzLnN0cmVhbS5yZWFkVUludDMyKHRydWUpO1xuICAgICAgICB0aGlzLnJlYWRTdGFydCA9IHRydWU7XG4gICAgICAgIGlmICh0aGlzLnN0cmVhbS5yZWFkU3RyaW5nKDQpICE9PSAnV0FWRScpIHtcbiAgICAgICAgICByZXR1cm4gdGhpcy5lbWl0KCdlcnJvcicsICdJbnZhbGlkIFdBViBmaWxlLicpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICB3aGlsZSAodGhpcy5zdHJlYW0uYXZhaWxhYmxlKDEpKSB7XG4gICAgICAgIGlmICghdGhpcy5yZWFkSGVhZGVycyAmJiB0aGlzLnN0cmVhbS5hdmFpbGFibGUoOCkpIHtcbiAgICAgICAgICB0aGlzLnR5cGUgPSB0aGlzLnN0cmVhbS5yZWFkU3RyaW5nKDQpO1xuICAgICAgICAgIHRoaXMubGVuID0gdGhpcy5zdHJlYW0ucmVhZFVJbnQzMih0cnVlKTtcbiAgICAgICAgfVxuICAgICAgICBzd2l0Y2ggKHRoaXMudHlwZSkge1xuICAgICAgICAgIGNhc2UgJ2ZtdCAnOlxuICAgICAgICAgICAgZW5jb2RpbmcgPSB0aGlzLnN0cmVhbS5yZWFkVUludDE2KHRydWUpO1xuICAgICAgICAgICAgaWYgKCEoZW5jb2RpbmcgaW4gZm9ybWF0cykpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZW1pdCgnZXJyb3InLCAnVW5zdXBwb3J0ZWQgZm9ybWF0IGluIFdBViBmaWxlLicpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5mb3JtYXQgPSB7XG4gICAgICAgICAgICAgIGZvcm1hdElEOiBmb3JtYXRzW2VuY29kaW5nXSxcbiAgICAgICAgICAgICAgZmxvYXRpbmdQb2ludDogZW5jb2RpbmcgPT09IDB4MDAwMyxcbiAgICAgICAgICAgICAgbGl0dGxlRW5kaWFuOiBmb3JtYXRzW2VuY29kaW5nXSA9PT0gJ2xwY20nLFxuICAgICAgICAgICAgICBjaGFubmVsc1BlckZyYW1lOiB0aGlzLnN0cmVhbS5yZWFkVUludDE2KHRydWUpLFxuICAgICAgICAgICAgICBzYW1wbGVSYXRlOiB0aGlzLnN0cmVhbS5yZWFkVUludDMyKHRydWUpLFxuICAgICAgICAgICAgICBmcmFtZXNQZXJQYWNrZXQ6IDFcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICB0aGlzLnN0cmVhbS5hZHZhbmNlKDQpO1xuICAgICAgICAgICAgdGhpcy5zdHJlYW0uYWR2YW5jZSgyKTtcbiAgICAgICAgICAgIHRoaXMuZm9ybWF0LmJpdHNQZXJDaGFubmVsID0gdGhpcy5zdHJlYW0ucmVhZFVJbnQxNih0cnVlKTtcbiAgICAgICAgICAgIHRoaXMuZm9ybWF0LmJ5dGVzUGVyUGFja2V0ID0gKHRoaXMuZm9ybWF0LmJpdHNQZXJDaGFubmVsIC8gOCkgKiB0aGlzLmZvcm1hdC5jaGFubmVsc1BlckZyYW1lO1xuICAgICAgICAgICAgdGhpcy5lbWl0KCdmb3JtYXQnLCB0aGlzLmZvcm1hdCk7XG4gICAgICAgICAgICB0aGlzLnN0cmVhbS5hZHZhbmNlKHRoaXMubGVuIC0gMTYpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgY2FzZSAnZGF0YSc6XG4gICAgICAgICAgICBpZiAoIXRoaXMuc2VudER1cmF0aW9uKSB7XG4gICAgICAgICAgICAgIGJ5dGVzID0gdGhpcy5mb3JtYXQuYml0c1BlckNoYW5uZWwgLyA4O1xuICAgICAgICAgICAgICB0aGlzLmVtaXQoJ2R1cmF0aW9uJywgdGhpcy5sZW4gLyBieXRlcyAvIHRoaXMuZm9ybWF0LmNoYW5uZWxzUGVyRnJhbWUgLyB0aGlzLmZvcm1hdC5zYW1wbGVSYXRlICogMTAwMCB8IDApO1xuICAgICAgICAgICAgICB0aGlzLnNlbnREdXJhdGlvbiA9IHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBidWZmZXIgPSB0aGlzLnN0cmVhbS5yZWFkU2luZ2xlQnVmZmVyKHRoaXMubGVuKTtcbiAgICAgICAgICAgIHRoaXMubGVuIC09IGJ1ZmZlci5sZW5ndGg7XG4gICAgICAgICAgICB0aGlzLnJlYWRIZWFkZXJzID0gdGhpcy5sZW4gPiAwO1xuICAgICAgICAgICAgdGhpcy5lbWl0KCdkYXRhJywgYnVmZmVyKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICBpZiAoIXRoaXMuc3RyZWFtLmF2YWlsYWJsZSh0aGlzLmxlbikpIHtcbiAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5zdHJlYW0uYWR2YW5jZSh0aGlzLmxlbik7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMudHlwZSAhPT0gJ2RhdGEnKSB7XG4gICAgICAgICAgdGhpcy5yZWFkSGVhZGVycyA9IGZhbHNlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfTtcblxuICAgIHJldHVybiBXQVZFRGVtdXhlcjtcblxuICB9KShEZW11eGVyKTtcblxufSkuY2FsbCh0aGlzKTtcbiIsIi8vIEdlbmVyYXRlZCBieSBDb2ZmZWVTY3JpcHQgMS4xMi43XG4oZnVuY3Rpb24oKSB7XG4gIHZhciBBdWRpb0RldmljZSwgRXZlbnRFbWl0dGVyLFxuICAgIGJpbmQgPSBmdW5jdGlvbihmbiwgbWUpeyByZXR1cm4gZnVuY3Rpb24oKXsgcmV0dXJuIGZuLmFwcGx5KG1lLCBhcmd1bWVudHMpOyB9OyB9LFxuICAgIGV4dGVuZCA9IGZ1bmN0aW9uKGNoaWxkLCBwYXJlbnQpIHsgZm9yICh2YXIga2V5IGluIHBhcmVudCkgeyBpZiAoaGFzUHJvcC5jYWxsKHBhcmVudCwga2V5KSkgY2hpbGRba2V5XSA9IHBhcmVudFtrZXldOyB9IGZ1bmN0aW9uIGN0b3IoKSB7IHRoaXMuY29uc3RydWN0b3IgPSBjaGlsZDsgfSBjdG9yLnByb3RvdHlwZSA9IHBhcmVudC5wcm90b3R5cGU7IGNoaWxkLnByb3RvdHlwZSA9IG5ldyBjdG9yKCk7IGNoaWxkLl9fc3VwZXJfXyA9IHBhcmVudC5wcm90b3R5cGU7IHJldHVybiBjaGlsZDsgfSxcbiAgICBoYXNQcm9wID0ge30uaGFzT3duUHJvcGVydHk7XG5cbiAgRXZlbnRFbWl0dGVyID0gcmVxdWlyZSgnLi9jb3JlL2V2ZW50cycpO1xuXG4gIEF1ZGlvRGV2aWNlID0gKGZ1bmN0aW9uKHN1cGVyQ2xhc3MpIHtcbiAgICB2YXIgZGV2aWNlcztcblxuICAgIGV4dGVuZChBdWRpb0RldmljZSwgc3VwZXJDbGFzcyk7XG5cbiAgICBmdW5jdGlvbiBBdWRpb0RldmljZShzYW1wbGVSYXRlMSwgY2hhbm5lbHMxKSB7XG4gICAgICB0aGlzLnNhbXBsZVJhdGUgPSBzYW1wbGVSYXRlMTtcbiAgICAgIHRoaXMuY2hhbm5lbHMgPSBjaGFubmVsczE7XG4gICAgICB0aGlzLnVwZGF0ZVRpbWUgPSBiaW5kKHRoaXMudXBkYXRlVGltZSwgdGhpcyk7XG4gICAgICB0aGlzLnBsYXlpbmcgPSBmYWxzZTtcbiAgICAgIHRoaXMuY3VycmVudFRpbWUgPSAwO1xuICAgICAgdGhpcy5fbGFzdFRpbWUgPSAwO1xuICAgIH1cblxuICAgIEF1ZGlvRGV2aWNlLnByb3RvdHlwZS5zdGFydCA9IGZ1bmN0aW9uKCkge1xuICAgICAgaWYgKHRoaXMucGxheWluZykge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICB0aGlzLnBsYXlpbmcgPSB0cnVlO1xuICAgICAgaWYgKHRoaXMuZGV2aWNlID09IG51bGwpIHtcbiAgICAgICAgdGhpcy5kZXZpY2UgPSBBdWRpb0RldmljZS5jcmVhdGUodGhpcy5zYW1wbGVSYXRlLCB0aGlzLmNoYW5uZWxzKTtcbiAgICAgIH1cbiAgICAgIGlmICghdGhpcy5kZXZpY2UpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTm8gc3VwcG9ydGVkIGF1ZGlvIGRldmljZSBmb3VuZC5cIik7XG4gICAgICB9XG4gICAgICB0aGlzLl9sYXN0VGltZSA9IHRoaXMuZGV2aWNlLmdldERldmljZVRpbWUoKTtcbiAgICAgIHRoaXMuX3RpbWVyID0gc2V0SW50ZXJ2YWwodGhpcy51cGRhdGVUaW1lLCAyMDApO1xuICAgICAgcmV0dXJuIHRoaXMuZGV2aWNlLm9uKCdyZWZpbGwnLCB0aGlzLnJlZmlsbCA9IChmdW5jdGlvbihfdGhpcykge1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24oYnVmZmVyKSB7XG4gICAgICAgICAgcmV0dXJuIF90aGlzLmVtaXQoJ3JlZmlsbCcsIGJ1ZmZlcik7XG4gICAgICAgIH07XG4gICAgICB9KSh0aGlzKSk7XG4gICAgfTtcblxuICAgIEF1ZGlvRGV2aWNlLnByb3RvdHlwZS5zdG9wID0gZnVuY3Rpb24oKSB7XG4gICAgICBpZiAoIXRoaXMucGxheWluZykge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICB0aGlzLnBsYXlpbmcgPSBmYWxzZTtcbiAgICAgIHRoaXMuZGV2aWNlLm9mZigncmVmaWxsJywgdGhpcy5yZWZpbGwpO1xuICAgICAgcmV0dXJuIGNsZWFySW50ZXJ2YWwodGhpcy5fdGltZXIpO1xuICAgIH07XG5cbiAgICBBdWRpb0RldmljZS5wcm90b3R5cGUuZGVzdHJveSA9IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIHJlZjtcbiAgICAgIHRoaXMuc3RvcCgpO1xuICAgICAgcmV0dXJuIChyZWYgPSB0aGlzLmRldmljZSkgIT0gbnVsbCA/IHJlZi5kZXN0cm95KCkgOiB2b2lkIDA7XG4gICAgfTtcblxuICAgIEF1ZGlvRGV2aWNlLnByb3RvdHlwZS5zZWVrID0gZnVuY3Rpb24oY3VycmVudFRpbWUpIHtcbiAgICAgIHRoaXMuY3VycmVudFRpbWUgPSBjdXJyZW50VGltZTtcbiAgICAgIGlmICh0aGlzLnBsYXlpbmcpIHtcbiAgICAgICAgdGhpcy5fbGFzdFRpbWUgPSB0aGlzLmRldmljZS5nZXREZXZpY2VUaW1lKCk7XG4gICAgICB9XG4gICAgICByZXR1cm4gdGhpcy5lbWl0KCd0aW1lVXBkYXRlJywgdGhpcy5jdXJyZW50VGltZSk7XG4gICAgfTtcblxuICAgIEF1ZGlvRGV2aWNlLnByb3RvdHlwZS51cGRhdGVUaW1lID0gZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgdGltZTtcbiAgICAgIHRpbWUgPSB0aGlzLmRldmljZS5nZXREZXZpY2VUaW1lKCk7XG4gICAgICB0aGlzLmN1cnJlbnRUaW1lICs9ICh0aW1lIC0gdGhpcy5fbGFzdFRpbWUpIC8gdGhpcy5kZXZpY2Uuc2FtcGxlUmF0ZSAqIDEwMDAgfCAwO1xuICAgICAgdGhpcy5fbGFzdFRpbWUgPSB0aW1lO1xuICAgICAgcmV0dXJuIHRoaXMuZW1pdCgndGltZVVwZGF0ZScsIHRoaXMuY3VycmVudFRpbWUpO1xuICAgIH07XG5cbiAgICBkZXZpY2VzID0gW107XG5cbiAgICBBdWRpb0RldmljZS5yZWdpc3RlciA9IGZ1bmN0aW9uKGRldmljZSkge1xuICAgICAgcmV0dXJuIGRldmljZXMucHVzaChkZXZpY2UpO1xuICAgIH07XG5cbiAgICBBdWRpb0RldmljZS5jcmVhdGUgPSBmdW5jdGlvbihzYW1wbGVSYXRlLCBjaGFubmVscykge1xuICAgICAgdmFyIGRldmljZSwgaSwgbGVuO1xuICAgICAgZm9yIChpID0gMCwgbGVuID0gZGV2aWNlcy5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgICAgICBkZXZpY2UgPSBkZXZpY2VzW2ldO1xuICAgICAgICBpZiAoZGV2aWNlLnN1cHBvcnRlZCkge1xuICAgICAgICAgIHJldHVybiBuZXcgZGV2aWNlKHNhbXBsZVJhdGUsIGNoYW5uZWxzKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfTtcblxuICAgIHJldHVybiBBdWRpb0RldmljZTtcblxuICB9KShFdmVudEVtaXR0ZXIpO1xuXG4gIG1vZHVsZS5leHBvcnRzID0gQXVkaW9EZXZpY2U7XG5cbn0pLmNhbGwodGhpcyk7XG4iLCIvLyBHZW5lcmF0ZWQgYnkgQ29mZmVlU2NyaXB0IDEuMTIuN1xuKGZ1bmN0aW9uKCkge1xuICB2YXIgQVZCdWZmZXIsIEF1ZGlvRGV2aWNlLCBFdmVudEVtaXR0ZXIsIE1vemlsbGFBdWRpb0RldmljZSxcbiAgICBiaW5kID0gZnVuY3Rpb24oZm4sIG1lKXsgcmV0dXJuIGZ1bmN0aW9uKCl7IHJldHVybiBmbi5hcHBseShtZSwgYXJndW1lbnRzKTsgfTsgfSxcbiAgICBleHRlbmQgPSBmdW5jdGlvbihjaGlsZCwgcGFyZW50KSB7IGZvciAodmFyIGtleSBpbiBwYXJlbnQpIHsgaWYgKGhhc1Byb3AuY2FsbChwYXJlbnQsIGtleSkpIGNoaWxkW2tleV0gPSBwYXJlbnRba2V5XTsgfSBmdW5jdGlvbiBjdG9yKCkgeyB0aGlzLmNvbnN0cnVjdG9yID0gY2hpbGQ7IH0gY3Rvci5wcm90b3R5cGUgPSBwYXJlbnQucHJvdG90eXBlOyBjaGlsZC5wcm90b3R5cGUgPSBuZXcgY3RvcigpOyBjaGlsZC5fX3N1cGVyX18gPSBwYXJlbnQucHJvdG90eXBlOyByZXR1cm4gY2hpbGQ7IH0sXG4gICAgaGFzUHJvcCA9IHt9Lmhhc093blByb3BlcnR5O1xuXG4gIEV2ZW50RW1pdHRlciA9IHJlcXVpcmUoJy4uL2NvcmUvZXZlbnRzJyk7XG5cbiAgQXVkaW9EZXZpY2UgPSByZXF1aXJlKCcuLi9kZXZpY2UnKTtcblxuICBBVkJ1ZmZlciA9IHJlcXVpcmUoJy4uL2NvcmUvYnVmZmVyJyk7XG5cbiAgTW96aWxsYUF1ZGlvRGV2aWNlID0gKGZ1bmN0aW9uKHN1cGVyQ2xhc3MpIHtcbiAgICB2YXIgY3JlYXRlVGltZXIsIGRlc3Ryb3lUaW1lcjtcblxuICAgIGV4dGVuZChNb3ppbGxhQXVkaW9EZXZpY2UsIHN1cGVyQ2xhc3MpO1xuXG4gICAgQXVkaW9EZXZpY2UucmVnaXN0ZXIoTW96aWxsYUF1ZGlvRGV2aWNlKTtcblxuICAgIE1vemlsbGFBdWRpb0RldmljZS5zdXBwb3J0ZWQgPSAodHlwZW9mIEF1ZGlvICE9PSBcInVuZGVmaW5lZFwiICYmIEF1ZGlvICE9PSBudWxsKSAmJiAnbW96V3JpdGVBdWRpbycgaW4gbmV3IEF1ZGlvO1xuXG4gICAgZnVuY3Rpb24gTW96aWxsYUF1ZGlvRGV2aWNlKHNhbXBsZVJhdGUsIGNoYW5uZWxzKSB7XG4gICAgICB0aGlzLnNhbXBsZVJhdGUgPSBzYW1wbGVSYXRlO1xuICAgICAgdGhpcy5jaGFubmVscyA9IGNoYW5uZWxzO1xuICAgICAgdGhpcy5yZWZpbGwgPSBiaW5kKHRoaXMucmVmaWxsLCB0aGlzKTtcbiAgICAgIHRoaXMuYXVkaW8gPSBuZXcgQXVkaW87XG4gICAgICB0aGlzLmF1ZGlvLm1velNldHVwKHRoaXMuY2hhbm5lbHMsIHRoaXMuc2FtcGxlUmF0ZSk7XG4gICAgICB0aGlzLndyaXRlUG9zaXRpb24gPSAwO1xuICAgICAgdGhpcy5wcmVidWZmZXJTaXplID0gdGhpcy5zYW1wbGVSYXRlIC8gMjtcbiAgICAgIHRoaXMudGFpbCA9IG51bGw7XG4gICAgICB0aGlzLnRpbWVyID0gY3JlYXRlVGltZXIodGhpcy5yZWZpbGwsIDEwMCk7XG4gICAgfVxuXG4gICAgTW96aWxsYUF1ZGlvRGV2aWNlLnByb3RvdHlwZS5yZWZpbGwgPSBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBhdmFpbGFibGUsIGJ1ZmZlciwgY3VycmVudFBvc2l0aW9uLCB3cml0dGVuO1xuICAgICAgaWYgKHRoaXMudGFpbCkge1xuICAgICAgICB3cml0dGVuID0gdGhpcy5hdWRpby5tb3pXcml0ZUF1ZGlvKHRoaXMudGFpbCk7XG4gICAgICAgIHRoaXMud3JpdGVQb3NpdGlvbiArPSB3cml0dGVuO1xuICAgICAgICBpZiAodGhpcy53cml0ZVBvc2l0aW9uIDwgdGhpcy50YWlsLmxlbmd0aCkge1xuICAgICAgICAgIHRoaXMudGFpbCA9IHRoaXMudGFpbC5zdWJhcnJheSh3cml0dGVuKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLnRhaWwgPSBudWxsO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBjdXJyZW50UG9zaXRpb24gPSB0aGlzLmF1ZGlvLm1vekN1cnJlbnRTYW1wbGVPZmZzZXQoKTtcbiAgICAgIGF2YWlsYWJsZSA9IGN1cnJlbnRQb3NpdGlvbiArIHRoaXMucHJlYnVmZmVyU2l6ZSAtIHRoaXMud3JpdGVQb3NpdGlvbjtcbiAgICAgIGlmIChhdmFpbGFibGUgPiAwKSB7XG4gICAgICAgIGJ1ZmZlciA9IG5ldyBGbG9hdDMyQXJyYXkoYXZhaWxhYmxlKTtcbiAgICAgICAgdGhpcy5lbWl0KCdyZWZpbGwnLCBidWZmZXIpO1xuICAgICAgICB3cml0dGVuID0gdGhpcy5hdWRpby5tb3pXcml0ZUF1ZGlvKGJ1ZmZlcik7XG4gICAgICAgIGlmICh3cml0dGVuIDwgYnVmZmVyLmxlbmd0aCkge1xuICAgICAgICAgIHRoaXMudGFpbCA9IGJ1ZmZlci5zdWJhcnJheSh3cml0dGVuKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLndyaXRlUG9zaXRpb24gKz0gd3JpdHRlbjtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgTW96aWxsYUF1ZGlvRGV2aWNlLnByb3RvdHlwZS5kZXN0cm95ID0gZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gZGVzdHJveVRpbWVyKHRoaXMudGltZXIpO1xuICAgIH07XG5cbiAgICBNb3ppbGxhQXVkaW9EZXZpY2UucHJvdG90eXBlLmdldERldmljZVRpbWUgPSBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiB0aGlzLmF1ZGlvLm1vekN1cnJlbnRTYW1wbGVPZmZzZXQoKSAvIHRoaXMuY2hhbm5lbHM7XG4gICAgfTtcblxuICAgIGNyZWF0ZVRpbWVyID0gZnVuY3Rpb24oZm4sIGludGVydmFsKSB7XG4gICAgICB2YXIgdXJsLCB3b3JrZXI7XG4gICAgICB1cmwgPSBBVkJ1ZmZlci5tYWtlQmxvYlVSTChcInNldEludGVydmFsKGZ1bmN0aW9uKCkgeyBwb3N0TWVzc2FnZSgncGluZycpOyB9LCBcIiArIGludGVydmFsICsgXCIpO1wiKTtcbiAgICAgIGlmICh1cmwgPT0gbnVsbCkge1xuICAgICAgICByZXR1cm4gc2V0SW50ZXJ2YWwoZm4sIGludGVydmFsKTtcbiAgICAgIH1cbiAgICAgIHdvcmtlciA9IG5ldyBXb3JrZXIodXJsKTtcbiAgICAgIHdvcmtlci5vbm1lc3NhZ2UgPSBmbjtcbiAgICAgIHdvcmtlci51cmwgPSB1cmw7XG4gICAgICByZXR1cm4gd29ya2VyO1xuICAgIH07XG5cbiAgICBkZXN0cm95VGltZXIgPSBmdW5jdGlvbih0aW1lcikge1xuICAgICAgaWYgKHRpbWVyLnRlcm1pbmF0ZSkge1xuICAgICAgICB0aW1lci50ZXJtaW5hdGUoKTtcbiAgICAgICAgcmV0dXJuIFVSTC5yZXZva2VPYmplY3RVUkwodGltZXIudXJsKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBjbGVhckludGVydmFsKHRpbWVyKTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgcmV0dXJuIE1vemlsbGFBdWRpb0RldmljZTtcblxuICB9KShFdmVudEVtaXR0ZXIpO1xuXG59KS5jYWxsKHRoaXMpO1xuIiwiLy9KYXZhU2NyaXB0IEF1ZGlvIFJlc2FtcGxlclxuLy9Db3B5cmlnaHQgKEMpIDIwMTEtMjAxNSBHcmFudCBHYWxpdHpcbi8vUmVsZWFzZWQgdG8gUHVibGljIERvbWFpblxuZnVuY3Rpb24gUmVzYW1wbGVyKGZyb21TYW1wbGVSYXRlLCB0b1NhbXBsZVJhdGUsIGNoYW5uZWxzLCBpbnB1dEJ1ZmZlckxlbmd0aCkge1xuICB0aGlzLmZyb21TYW1wbGVSYXRlID0gK2Zyb21TYW1wbGVSYXRlO1xuICB0aGlzLnRvU2FtcGxlUmF0ZSA9ICt0b1NhbXBsZVJhdGU7XG4gIHRoaXMuY2hhbm5lbHMgPSBjaGFubmVscyB8IDA7XG4gIHRoaXMuaW5wdXRCdWZmZXJMZW5ndGggPSBpbnB1dEJ1ZmZlckxlbmd0aDtcbiAgdGhpcy5pbml0aWFsaXplKCk7XG59XG5cblJlc2FtcGxlci5wcm90b3R5cGUuaW5pdGlhbGl6ZSA9IGZ1bmN0aW9uICgpIHtcbiAgLy9QZXJmb3JtIHNvbWUgY2hlY2tzOlxuICBpZiAodGhpcy5mcm9tU2FtcGxlUmF0ZSA+IDAgJiYgdGhpcy50b1NhbXBsZVJhdGUgPiAwICYmIHRoaXMuY2hhbm5lbHMgPiAwKSB7XG4gICAgaWYgKHRoaXMuZnJvbVNhbXBsZVJhdGUgPT0gdGhpcy50b1NhbXBsZVJhdGUpIHtcbiAgICAgIC8vU2V0dXAgYSByZXNhbXBsZXIgYnlwYXNzOlxuICAgICAgdGhpcy5yZXNhbXBsZXIgPSB0aGlzLmJ5cGFzc1Jlc2FtcGxlcjsgICAgLy9SZXNhbXBsZXIganVzdCByZXR1cm5zIHdoYXQgd2FzIHBhc3NlZCB0aHJvdWdoLlxuICAgICAgdGhpcy5yYXRpb1dlaWdodCA9IDE7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMucmF0aW9XZWlnaHQgPSB0aGlzLmZyb21TYW1wbGVSYXRlIC8gdGhpcy50b1NhbXBsZVJhdGU7XG4gICAgICBpZiAodGhpcy5mcm9tU2FtcGxlUmF0ZSA8IHRoaXMudG9TYW1wbGVSYXRlKSB7XG4gICAgICAgIC8qXG4gICAgICAgICAgVXNlIGdlbmVyaWMgbGluZWFyIGludGVycG9sYXRpb24gaWYgdXBzYW1wbGluZyxcbiAgICAgICAgICBhcyBsaW5lYXIgaW50ZXJwb2xhdGlvbiBwcm9kdWNlcyBhIGdyYWRpZW50IHRoYXQgd2Ugd2FudFxuICAgICAgICAgIGFuZCB3b3JrcyBmaW5lIHdpdGggdHdvIGlucHV0IHNhbXBsZSBwb2ludHMgcGVyIG91dHB1dCBpbiB0aGlzIGNhc2UuXG4gICAgICAgICovXG4gICAgICAgIHRoaXMuY29tcGlsZUxpbmVhckludGVycG9sYXRpb25GdW5jdGlvbigpO1xuICAgICAgICB0aGlzLmxhc3RXZWlnaHQgPSAxO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLypcbiAgICAgICAgICBDdXN0b20gcmVzYW1wbGVyIEkgd3JvdGUgdGhhdCBkb2Vzbid0IHNraXAgc2FtcGxlc1xuICAgICAgICAgIGxpa2Ugc3RhbmRhcmQgbGluZWFyIGludGVycG9sYXRpb24gaW4gaGlnaCBkb3duc2FtcGxpbmcuXG4gICAgICAgICAgVGhpcyBpcyBtb3JlIGFjY3VyYXRlIHRoYW4gbGluZWFyIGludGVycG9sYXRpb24gb24gZG93bnNhbXBsaW5nLlxuICAgICAgICAqL1xuICAgICAgICB0aGlzLmNvbXBpbGVNdWx0aVRhcEZ1bmN0aW9uKCk7XG4gICAgICAgIHRoaXMudGFpbEV4aXN0cyA9IGZhbHNlO1xuICAgICAgICB0aGlzLmxhc3RXZWlnaHQgPSAwO1xuICAgICAgfVxuICAgICAgXG4gICAgICB2YXIgb3V0cHV0QnVmZmVyU2l6ZSA9IChNYXRoLmNlaWwodGhpcy5pbnB1dEJ1ZmZlckxlbmd0aCAqIHRoaXMudG9TYW1wbGVSYXRlIC8gdGhpcy5mcm9tU2FtcGxlUmF0ZSAvIHRoaXMuY2hhbm5lbHMgKiAxLjAxKSAqIHRoaXMuY2hhbm5lbHMpICsgdGhpcy5jaGFubmVscztcbiAgICAgIHRoaXMub3V0cHV0QnVmZmVyID0gbmV3IEZsb2F0MzJBcnJheShvdXRwdXRCdWZmZXJTaXplKTtcbiAgICAgIHRoaXMubGFzdE91dHB1dCA9IG5ldyBGbG9hdDMyQXJyYXkodGhpcy5jaGFubmVscyk7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIHRocm93KG5ldyBFcnJvcihcIkludmFsaWQgc2V0dGluZ3Mgc3BlY2lmaWVkIGZvciB0aGUgcmVzYW1wbGVyLlwiKSk7XG4gIH1cbn07XG5cblJlc2FtcGxlci5wcm90b3R5cGUuY29tcGlsZUxpbmVhckludGVycG9sYXRpb25GdW5jdGlvbiA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIHRvQ29tcGlsZSA9IFwidmFyIG91dHB1dE9mZnNldCA9IDA7XFxcbiAgICB2YXIgYnVmZmVyTGVuZ3RoID0gYnVmZmVyLmxlbmd0aDtcXFxuICAgIGlmIChidWZmZXJMZW5ndGggPiAwKSB7XFxcbiAgICAgIHZhciB3ZWlnaHQgPSB0aGlzLmxhc3RXZWlnaHQ7XFxcbiAgICAgIHZhciBmaXJzdFdlaWdodCA9IDA7XFxcbiAgICAgIHZhciBzZWNvbmRXZWlnaHQgPSAwO1xcXG4gICAgICB2YXIgc291cmNlT2Zmc2V0ID0gMDtcXFxuICAgICAgdmFyIG91dHB1dE9mZnNldCA9IDA7XFxcbiAgICAgIHZhciBvdXRwdXRCdWZmZXIgPSB0aGlzLm91dHB1dEJ1ZmZlcjtcXFxuICAgICAgZm9yICg7IHdlaWdodCA8IDE7IHdlaWdodCArPSBcIiArIHRoaXMucmF0aW9XZWlnaHQgKyBcIikge1xcXG4gICAgICAgIHNlY29uZFdlaWdodCA9IHdlaWdodCAlIDE7XFxcbiAgICAgICAgZmlyc3RXZWlnaHQgPSAxIC0gc2Vjb25kV2VpZ2h0O1wiO1xuICAgICAgICBmb3IgKHZhciBjaGFubmVsID0gMDsgY2hhbm5lbCA8IHRoaXMuY2hhbm5lbHM7ICsrY2hhbm5lbCkge1xuICAgICAgICAgIHRvQ29tcGlsZSArPSBcIm91dHB1dEJ1ZmZlcltvdXRwdXRPZmZzZXQrK10gPSAodGhpcy5sYXN0T3V0cHV0W1wiICsgY2hhbm5lbCArIFwiXSAqIGZpcnN0V2VpZ2h0KSArIChidWZmZXJbXCIgKyBjaGFubmVsICsgXCJdICogc2Vjb25kV2VpZ2h0KTtcIjtcbiAgICAgICAgfVxuICAgICAgdG9Db21waWxlICs9IFwifVxcXG4gICAgICB3ZWlnaHQgLT0gMTtcXFxuICAgICAgZm9yIChidWZmZXJMZW5ndGggLT0gXCIgKyB0aGlzLmNoYW5uZWxzICsgXCIsIHNvdXJjZU9mZnNldCA9IE1hdGguZmxvb3Iod2VpZ2h0KSAqIFwiICsgdGhpcy5jaGFubmVscyArIFwiOyBzb3VyY2VPZmZzZXQgPCBidWZmZXJMZW5ndGg7KSB7XFxcbiAgICAgICAgc2Vjb25kV2VpZ2h0ID0gd2VpZ2h0ICUgMTtcXFxuICAgICAgICBmaXJzdFdlaWdodCA9IDEgLSBzZWNvbmRXZWlnaHQ7XCI7XG4gICAgICAgIGZvciAodmFyIGNoYW5uZWwgPSAwOyBjaGFubmVsIDwgdGhpcy5jaGFubmVsczsgKytjaGFubmVsKSB7XG4gICAgICAgICAgdG9Db21waWxlICs9IFwib3V0cHV0QnVmZmVyW291dHB1dE9mZnNldCsrXSA9IChidWZmZXJbc291cmNlT2Zmc2V0XCIgKyAoKGNoYW5uZWwgPiAwKSA/IChcIiArIFwiICsgY2hhbm5lbCkgOiBcIlwiKSArIFwiXSAqIGZpcnN0V2VpZ2h0KSArIChidWZmZXJbc291cmNlT2Zmc2V0ICsgXCIgKyAodGhpcy5jaGFubmVscyArIGNoYW5uZWwpICsgXCJdICogc2Vjb25kV2VpZ2h0KTtcIjtcbiAgICAgICAgfVxuICAgICAgICB0b0NvbXBpbGUgKz0gXCJ3ZWlnaHQgKz0gXCIgKyB0aGlzLnJhdGlvV2VpZ2h0ICsgXCI7XFxcbiAgICAgICAgc291cmNlT2Zmc2V0ID0gTWF0aC5mbG9vcih3ZWlnaHQpICogXCIgKyB0aGlzLmNoYW5uZWxzICsgXCI7XFxcbiAgICAgIH1cIjtcbiAgICAgIGZvciAodmFyIGNoYW5uZWwgPSAwOyBjaGFubmVsIDwgdGhpcy5jaGFubmVsczsgKytjaGFubmVsKSB7XG4gICAgICAgIHRvQ29tcGlsZSArPSBcInRoaXMubGFzdE91dHB1dFtcIiArIGNoYW5uZWwgKyBcIl0gPSBidWZmZXJbc291cmNlT2Zmc2V0KytdO1wiO1xuICAgICAgfVxuICAgICAgdG9Db21waWxlICs9IFwidGhpcy5sYXN0V2VpZ2h0ID0gd2VpZ2h0ICUgMTtcXFxuICAgIH1cXFxuICAgIHJldHVybiB0aGlzLm91dHB1dEJ1ZmZlcjtcIjtcbiAgICBcbiAgdGhpcy5yZXNhbXBsZXIgPSBGdW5jdGlvbihcImJ1ZmZlclwiLCB0b0NvbXBpbGUpO1xufTtcblxuUmVzYW1wbGVyLnByb3RvdHlwZS5jb21waWxlTXVsdGlUYXBGdW5jdGlvbiA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIHRvQ29tcGlsZSA9IFwidmFyIG91dHB1dE9mZnNldCA9IDA7XFxcbiAgICB2YXIgYnVmZmVyTGVuZ3RoID0gYnVmZmVyLmxlbmd0aDtcXFxuICAgIGlmIChidWZmZXJMZW5ndGggPiAwKSB7XFxcbiAgICAgIHZhciB3ZWlnaHQgPSAwO1wiO1xuICAgICAgZm9yICh2YXIgY2hhbm5lbCA9IDA7IGNoYW5uZWwgPCB0aGlzLmNoYW5uZWxzOyArK2NoYW5uZWwpIHtcbiAgICAgICAgdG9Db21waWxlICs9IFwidmFyIG91dHB1dFwiICsgY2hhbm5lbCArIFwiID0gMDtcIlxuICAgICAgfVxuICAgICAgdG9Db21waWxlICs9IFwidmFyIGFjdHVhbFBvc2l0aW9uID0gMDtcXFxuICAgICAgdmFyIGFtb3VudFRvTmV4dCA9IDA7XFxcbiAgICAgIHZhciBhbHJlYWR5UHJvY2Vzc2VkVGFpbCA9ICF0aGlzLnRhaWxFeGlzdHM7XFxcbiAgICAgIHRoaXMudGFpbEV4aXN0cyA9IGZhbHNlO1xcXG4gICAgICB2YXIgb3V0cHV0QnVmZmVyID0gdGhpcy5vdXRwdXRCdWZmZXI7XFxcbiAgICAgIHZhciBjdXJyZW50UG9zaXRpb24gPSAwO1xcXG4gICAgICBkbyB7XFxcbiAgICAgICAgaWYgKGFscmVhZHlQcm9jZXNzZWRUYWlsKSB7XFxcbiAgICAgICAgICB3ZWlnaHQgPSBcIiArIHRoaXMucmF0aW9XZWlnaHQgKyBcIjtcIjtcbiAgICAgICAgICBmb3IgKGNoYW5uZWwgPSAwOyBjaGFubmVsIDwgdGhpcy5jaGFubmVsczsgKytjaGFubmVsKSB7XG4gICAgICAgICAgICB0b0NvbXBpbGUgKz0gXCJvdXRwdXRcIiArIGNoYW5uZWwgKyBcIiA9IDA7XCJcbiAgICAgICAgICB9XG4gICAgICAgIHRvQ29tcGlsZSArPSBcIn1cXFxuICAgICAgICBlbHNlIHtcXFxuICAgICAgICAgIHdlaWdodCA9IHRoaXMubGFzdFdlaWdodDtcIjtcbiAgICAgICAgICBmb3IgKGNoYW5uZWwgPSAwOyBjaGFubmVsIDwgdGhpcy5jaGFubmVsczsgKytjaGFubmVsKSB7XG4gICAgICAgICAgICB0b0NvbXBpbGUgKz0gXCJvdXRwdXRcIiArIGNoYW5uZWwgKyBcIiA9IHRoaXMubGFzdE91dHB1dFtcIiArIGNoYW5uZWwgKyBcIl07XCJcbiAgICAgICAgICB9XG4gICAgICAgICAgdG9Db21waWxlICs9IFwiYWxyZWFkeVByb2Nlc3NlZFRhaWwgPSB0cnVlO1xcXG4gICAgICAgIH1cXFxuICAgICAgICB3aGlsZSAod2VpZ2h0ID4gMCAmJiBhY3R1YWxQb3NpdGlvbiA8IGJ1ZmZlckxlbmd0aCkge1xcXG4gICAgICAgICAgYW1vdW50VG9OZXh0ID0gMSArIGFjdHVhbFBvc2l0aW9uIC0gY3VycmVudFBvc2l0aW9uO1xcXG4gICAgICAgICAgaWYgKHdlaWdodCA+PSBhbW91bnRUb05leHQpIHtcIjtcbiAgICAgICAgICAgIGZvciAoY2hhbm5lbCA9IDA7IGNoYW5uZWwgPCB0aGlzLmNoYW5uZWxzOyArK2NoYW5uZWwpIHtcbiAgICAgICAgICAgICAgdG9Db21waWxlICs9IFwib3V0cHV0XCIgKyBjaGFubmVsICsgXCIgKz0gYnVmZmVyW2FjdHVhbFBvc2l0aW9uKytdICogYW1vdW50VG9OZXh0O1wiXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0b0NvbXBpbGUgKz0gXCJjdXJyZW50UG9zaXRpb24gPSBhY3R1YWxQb3NpdGlvbjtcXFxuICAgICAgICAgICAgd2VpZ2h0IC09IGFtb3VudFRvTmV4dDtcXFxuICAgICAgICAgIH1cXFxuICAgICAgICAgIGVsc2Uge1wiO1xuICAgICAgICAgICAgZm9yIChjaGFubmVsID0gMDsgY2hhbm5lbCA8IHRoaXMuY2hhbm5lbHM7ICsrY2hhbm5lbCkge1xuICAgICAgICAgICAgICB0b0NvbXBpbGUgKz0gXCJvdXRwdXRcIiArIGNoYW5uZWwgKyBcIiArPSBidWZmZXJbYWN0dWFsUG9zaXRpb25cIiArICgoY2hhbm5lbCA+IDApID8gKFwiICsgXCIgKyBjaGFubmVsKSA6IFwiXCIpICsgXCJdICogd2VpZ2h0O1wiXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0b0NvbXBpbGUgKz0gXCJjdXJyZW50UG9zaXRpb24gKz0gd2VpZ2h0O1xcXG4gICAgICAgICAgICB3ZWlnaHQgPSAwO1xcXG4gICAgICAgICAgICBicmVhaztcXFxuICAgICAgICAgIH1cXFxuICAgICAgICB9XFxcbiAgICAgICAgaWYgKHdlaWdodCA8PSAwKSB7XCI7XG4gICAgICAgICAgZm9yIChjaGFubmVsID0gMDsgY2hhbm5lbCA8IHRoaXMuY2hhbm5lbHM7ICsrY2hhbm5lbCkge1xuICAgICAgICAgICAgdG9Db21waWxlICs9IFwib3V0cHV0QnVmZmVyW291dHB1dE9mZnNldCsrXSA9IG91dHB1dFwiICsgY2hhbm5lbCArIFwiIC8gXCIgKyB0aGlzLnJhdGlvV2VpZ2h0ICsgXCI7XCJcbiAgICAgICAgICB9XG4gICAgICAgIHRvQ29tcGlsZSArPSBcIn1cXFxuICAgICAgICBlbHNlIHtcXFxuICAgICAgICAgIHRoaXMubGFzdFdlaWdodCA9IHdlaWdodDtcIjtcbiAgICAgICAgICBmb3IgKGNoYW5uZWwgPSAwOyBjaGFubmVsIDwgdGhpcy5jaGFubmVsczsgKytjaGFubmVsKSB7XG4gICAgICAgICAgICB0b0NvbXBpbGUgKz0gXCJ0aGlzLmxhc3RPdXRwdXRbXCIgKyBjaGFubmVsICsgXCJdID0gb3V0cHV0XCIgKyBjaGFubmVsICsgXCI7XCJcbiAgICAgICAgICB9XG4gICAgICAgICAgdG9Db21waWxlICs9IFwidGhpcy50YWlsRXhpc3RzID0gdHJ1ZTtcXFxuICAgICAgICAgIGJyZWFrO1xcXG4gICAgICAgIH1cXFxuICAgICAgfSB3aGlsZSAoYWN0dWFsUG9zaXRpb24gPCBidWZmZXJMZW5ndGgpO1xcXG4gICAgfVxcXG4gICAgcmV0dXJuIHRoaXMub3V0cHV0QnVmZmVyO1wiO1xuICBcbiAgdGhpcy5yZXNhbXBsZXIgPSBGdW5jdGlvbihcImJ1ZmZlclwiLCB0b0NvbXBpbGUpO1xufTtcblxuUmVzYW1wbGVyLnByb3RvdHlwZS5ieXBhc3NSZXNhbXBsZXIgPSBmdW5jdGlvbiAoaW5wdXRCdWZmZXIpIHtcbiAgcmV0dXJuIGlucHV0QnVmZmVyO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBSZXNhbXBsZXI7XG4iLCIvLyBHZW5lcmF0ZWQgYnkgQ29mZmVlU2NyaXB0IDEuMTIuN1xuKGZ1bmN0aW9uKCkge1xuICB2YXIgQXVkaW9EZXZpY2UsIEV2ZW50RW1pdHRlciwgUmVzYW1wbGVyLCBXZWJBdWRpb0RldmljZSxcbiAgICBiaW5kID0gZnVuY3Rpb24oZm4sIG1lKXsgcmV0dXJuIGZ1bmN0aW9uKCl7IHJldHVybiBmbi5hcHBseShtZSwgYXJndW1lbnRzKTsgfTsgfSxcbiAgICBleHRlbmQgPSBmdW5jdGlvbihjaGlsZCwgcGFyZW50KSB7IGZvciAodmFyIGtleSBpbiBwYXJlbnQpIHsgaWYgKGhhc1Byb3AuY2FsbChwYXJlbnQsIGtleSkpIGNoaWxkW2tleV0gPSBwYXJlbnRba2V5XTsgfSBmdW5jdGlvbiBjdG9yKCkgeyB0aGlzLmNvbnN0cnVjdG9yID0gY2hpbGQ7IH0gY3Rvci5wcm90b3R5cGUgPSBwYXJlbnQucHJvdG90eXBlOyBjaGlsZC5wcm90b3R5cGUgPSBuZXcgY3RvcigpOyBjaGlsZC5fX3N1cGVyX18gPSBwYXJlbnQucHJvdG90eXBlOyByZXR1cm4gY2hpbGQ7IH0sXG4gICAgaGFzUHJvcCA9IHt9Lmhhc093blByb3BlcnR5O1xuXG4gIEV2ZW50RW1pdHRlciA9IHJlcXVpcmUoJy4uL2NvcmUvZXZlbnRzJyk7XG5cbiAgQXVkaW9EZXZpY2UgPSByZXF1aXJlKCcuLi9kZXZpY2UnKTtcblxuICBSZXNhbXBsZXIgPSByZXF1aXJlKCcuL3Jlc2FtcGxlcicpO1xuXG4gIFdlYkF1ZGlvRGV2aWNlID0gKGZ1bmN0aW9uKHN1cGVyQ2xhc3MpIHtcbiAgICB2YXIgQXVkaW9Db250ZXh0LCBjcmVhdGVQcm9jZXNzb3IsIHNoYXJlZENvbnRleHQ7XG5cbiAgICBleHRlbmQoV2ViQXVkaW9EZXZpY2UsIHN1cGVyQ2xhc3MpO1xuXG4gICAgQXVkaW9EZXZpY2UucmVnaXN0ZXIoV2ViQXVkaW9EZXZpY2UpO1xuXG4gICAgQXVkaW9Db250ZXh0ID0gZ2xvYmFsLkF1ZGlvQ29udGV4dCB8fCBnbG9iYWwud2Via2l0QXVkaW9Db250ZXh0O1xuXG4gICAgV2ViQXVkaW9EZXZpY2Uuc3VwcG9ydGVkID0gQXVkaW9Db250ZXh0ICYmICh0eXBlb2YgQXVkaW9Db250ZXh0LnByb3RvdHlwZVtjcmVhdGVQcm9jZXNzb3IgPSAnY3JlYXRlU2NyaXB0UHJvY2Vzc29yJ10gPT09ICdmdW5jdGlvbicgfHwgdHlwZW9mIEF1ZGlvQ29udGV4dC5wcm90b3R5cGVbY3JlYXRlUHJvY2Vzc29yID0gJ2NyZWF0ZUphdmFTY3JpcHROb2RlJ10gPT09ICdmdW5jdGlvbicpO1xuXG4gICAgc2hhcmVkQ29udGV4dCA9IG51bGw7XG5cbiAgICBmdW5jdGlvbiBXZWJBdWRpb0RldmljZShzYW1wbGVSYXRlLCBjaGFubmVsczEpIHtcbiAgICAgIHRoaXMuc2FtcGxlUmF0ZSA9IHNhbXBsZVJhdGU7XG4gICAgICB0aGlzLmNoYW5uZWxzID0gY2hhbm5lbHMxO1xuICAgICAgdGhpcy5yZWZpbGwgPSBiaW5kKHRoaXMucmVmaWxsLCB0aGlzKTtcbiAgICAgIHRoaXMuY29udGV4dCA9IHNoYXJlZENvbnRleHQgIT0gbnVsbCA/IHNoYXJlZENvbnRleHQgOiBzaGFyZWRDb250ZXh0ID0gbmV3IEF1ZGlvQ29udGV4dDtcbiAgICAgIHRoaXMuZGV2aWNlU2FtcGxlUmF0ZSA9IHRoaXMuY29udGV4dC5zYW1wbGVSYXRlO1xuICAgICAgdGhpcy5idWZmZXJTaXplID0gTWF0aC5jZWlsKDQwOTYgLyAodGhpcy5kZXZpY2VTYW1wbGVSYXRlIC8gdGhpcy5zYW1wbGVSYXRlKSAqIHRoaXMuY2hhbm5lbHMpO1xuICAgICAgdGhpcy5idWZmZXJTaXplICs9IHRoaXMuYnVmZmVyU2l6ZSAlIHRoaXMuY2hhbm5lbHM7XG4gICAgICBpZiAodGhpcy5kZXZpY2VTYW1wbGVSYXRlICE9PSB0aGlzLnNhbXBsZVJhdGUpIHtcbiAgICAgICAgdGhpcy5yZXNhbXBsZXIgPSBuZXcgUmVzYW1wbGVyKHRoaXMuc2FtcGxlUmF0ZSwgdGhpcy5kZXZpY2VTYW1wbGVSYXRlLCB0aGlzLmNoYW5uZWxzLCB0aGlzLmJ1ZmZlclNpemUpO1xuICAgICAgfVxuICAgICAgdGhpcy5ub2RlID0gdGhpcy5jb250ZXh0W2NyZWF0ZVByb2Nlc3Nvcl0oNDA5NiwgdGhpcy5jaGFubmVscywgdGhpcy5jaGFubmVscyk7XG4gICAgICB0aGlzLm5vZGUub25hdWRpb3Byb2Nlc3MgPSB0aGlzLnJlZmlsbDtcbiAgICAgIHRoaXMubm9kZS5jb25uZWN0KHRoaXMuY29udGV4dC5kZXN0aW5hdGlvbik7XG4gICAgfVxuXG4gICAgV2ViQXVkaW9EZXZpY2UucHJvdG90eXBlLnJlZmlsbCA9IGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgICB2YXIgY2hhbm5lbENvdW50LCBjaGFubmVscywgZGF0YSwgaSwgaiwgaywgbCwgbiwgb3V0cHV0QnVmZmVyLCByZWYsIHJlZjEsIHJlZjI7XG4gICAgICBvdXRwdXRCdWZmZXIgPSBldmVudC5vdXRwdXRCdWZmZXI7XG4gICAgICBjaGFubmVsQ291bnQgPSBvdXRwdXRCdWZmZXIubnVtYmVyT2ZDaGFubmVscztcbiAgICAgIGNoYW5uZWxzID0gbmV3IEFycmF5KGNoYW5uZWxDb3VudCk7XG4gICAgICBmb3IgKGkgPSBqID0gMCwgcmVmID0gY2hhbm5lbENvdW50OyBqIDwgcmVmOyBpID0gaiArPSAxKSB7XG4gICAgICAgIGNoYW5uZWxzW2ldID0gb3V0cHV0QnVmZmVyLmdldENoYW5uZWxEYXRhKGkpO1xuICAgICAgfVxuICAgICAgZGF0YSA9IG5ldyBGbG9hdDMyQXJyYXkodGhpcy5idWZmZXJTaXplKTtcbiAgICAgIHRoaXMuZW1pdCgncmVmaWxsJywgZGF0YSk7XG4gICAgICBpZiAodGhpcy5yZXNhbXBsZXIpIHtcbiAgICAgICAgZGF0YSA9IHRoaXMucmVzYW1wbGVyLnJlc2FtcGxlcihkYXRhKTtcbiAgICAgIH1cbiAgICAgIGZvciAoaSA9IGsgPSAwLCByZWYxID0gb3V0cHV0QnVmZmVyLmxlbmd0aDsgayA8IHJlZjE7IGkgPSBrICs9IDEpIHtcbiAgICAgICAgZm9yIChuID0gbCA9IDAsIHJlZjIgPSBjaGFubmVsQ291bnQ7IGwgPCByZWYyOyBuID0gbCArPSAxKSB7XG4gICAgICAgICAgY2hhbm5lbHNbbl1baV0gPSBkYXRhW2kgKiBjaGFubmVsQ291bnQgKyBuXTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH07XG5cbiAgICBXZWJBdWRpb0RldmljZS5wcm90b3R5cGUuZGVzdHJveSA9IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHRoaXMubm9kZS5kaXNjb25uZWN0KDApO1xuICAgIH07XG5cbiAgICBXZWJBdWRpb0RldmljZS5wcm90b3R5cGUuZ2V0RGV2aWNlVGltZSA9IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHRoaXMuY29udGV4dC5jdXJyZW50VGltZSAqIHRoaXMuc2FtcGxlUmF0ZTtcbiAgICB9O1xuXG4gICAgcmV0dXJuIFdlYkF1ZGlvRGV2aWNlO1xuXG4gIH0pKEV2ZW50RW1pdHRlcik7XG5cbn0pLmNhbGwodGhpcyk7XG4iLCIvLyBHZW5lcmF0ZWQgYnkgQ29mZmVlU2NyaXB0IDEuMTIuN1xuKGZ1bmN0aW9uKCkge1xuICB2YXIgRmlsdGVyO1xuXG4gIEZpbHRlciA9IChmdW5jdGlvbigpIHtcbiAgICBmdW5jdGlvbiBGaWx0ZXIoY29udGV4dCwga2V5KSB7XG4gICAgICBpZiAoY29udGV4dCAmJiBrZXkpIHtcbiAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsICd2YWx1ZScsIHtcbiAgICAgICAgICBnZXQ6IGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgcmV0dXJuIGNvbnRleHRba2V5XTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIEZpbHRlci5wcm90b3R5cGUucHJvY2VzcyA9IGZ1bmN0aW9uKGJ1ZmZlcikge307XG5cbiAgICByZXR1cm4gRmlsdGVyO1xuXG4gIH0pKCk7XG5cbiAgbW9kdWxlLmV4cG9ydHMgPSBGaWx0ZXI7XG5cbn0pLmNhbGwodGhpcyk7XG4iLCIvLyBHZW5lcmF0ZWQgYnkgQ29mZmVlU2NyaXB0IDEuMTIuN1xuKGZ1bmN0aW9uKCkge1xuICB2YXIgQmFsYW5jZUZpbHRlciwgRmlsdGVyLFxuICAgIGV4dGVuZCA9IGZ1bmN0aW9uKGNoaWxkLCBwYXJlbnQpIHsgZm9yICh2YXIga2V5IGluIHBhcmVudCkgeyBpZiAoaGFzUHJvcC5jYWxsKHBhcmVudCwga2V5KSkgY2hpbGRba2V5XSA9IHBhcmVudFtrZXldOyB9IGZ1bmN0aW9uIGN0b3IoKSB7IHRoaXMuY29uc3RydWN0b3IgPSBjaGlsZDsgfSBjdG9yLnByb3RvdHlwZSA9IHBhcmVudC5wcm90b3R5cGU7IGNoaWxkLnByb3RvdHlwZSA9IG5ldyBjdG9yKCk7IGNoaWxkLl9fc3VwZXJfXyA9IHBhcmVudC5wcm90b3R5cGU7IHJldHVybiBjaGlsZDsgfSxcbiAgICBoYXNQcm9wID0ge30uaGFzT3duUHJvcGVydHk7XG5cbiAgRmlsdGVyID0gcmVxdWlyZSgnLi4vZmlsdGVyJyk7XG5cbiAgQmFsYW5jZUZpbHRlciA9IChmdW5jdGlvbihzdXBlckNsYXNzKSB7XG4gICAgZXh0ZW5kKEJhbGFuY2VGaWx0ZXIsIHN1cGVyQ2xhc3MpO1xuXG4gICAgZnVuY3Rpb24gQmFsYW5jZUZpbHRlcigpIHtcbiAgICAgIHJldHVybiBCYWxhbmNlRmlsdGVyLl9fc3VwZXJfXy5jb25zdHJ1Y3Rvci5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgIH1cblxuICAgIEJhbGFuY2VGaWx0ZXIucHJvdG90eXBlLnByb2Nlc3MgPSBmdW5jdGlvbihidWZmZXIpIHtcbiAgICAgIHZhciBpLCBqLCBwYW4sIHJlZjtcbiAgICAgIGlmICh0aGlzLnZhbHVlID09PSAwKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIHBhbiA9IE1hdGgubWF4KC01MCwgTWF0aC5taW4oNTAsIHRoaXMudmFsdWUpKTtcbiAgICAgIGZvciAoaSA9IGogPSAwLCByZWYgPSBidWZmZXIubGVuZ3RoOyBqIDwgcmVmOyBpID0gaiArPSAyKSB7XG4gICAgICAgIGJ1ZmZlcltpXSAqPSBNYXRoLm1pbigxLCAoNTAgLSBwYW4pIC8gNTApO1xuICAgICAgICBidWZmZXJbaSArIDFdICo9IE1hdGgubWluKDEsICg1MCArIHBhbikgLyA1MCk7XG4gICAgICB9XG4gICAgfTtcblxuICAgIHJldHVybiBCYWxhbmNlRmlsdGVyO1xuXG4gIH0pKEZpbHRlcik7XG5cbiAgbW9kdWxlLmV4cG9ydHMgPSBCYWxhbmNlRmlsdGVyO1xuXG59KS5jYWxsKHRoaXMpO1xuIiwiLy8gR2VuZXJhdGVkIGJ5IENvZmZlZVNjcmlwdCAxLjEyLjdcbihmdW5jdGlvbigpIHtcbiAgdmFyIEZpbHRlciwgVm9sdW1lRmlsdGVyLFxuICAgIGV4dGVuZCA9IGZ1bmN0aW9uKGNoaWxkLCBwYXJlbnQpIHsgZm9yICh2YXIga2V5IGluIHBhcmVudCkgeyBpZiAoaGFzUHJvcC5jYWxsKHBhcmVudCwga2V5KSkgY2hpbGRba2V5XSA9IHBhcmVudFtrZXldOyB9IGZ1bmN0aW9uIGN0b3IoKSB7IHRoaXMuY29uc3RydWN0b3IgPSBjaGlsZDsgfSBjdG9yLnByb3RvdHlwZSA9IHBhcmVudC5wcm90b3R5cGU7IGNoaWxkLnByb3RvdHlwZSA9IG5ldyBjdG9yKCk7IGNoaWxkLl9fc3VwZXJfXyA9IHBhcmVudC5wcm90b3R5cGU7IHJldHVybiBjaGlsZDsgfSxcbiAgICBoYXNQcm9wID0ge30uaGFzT3duUHJvcGVydHk7XG5cbiAgRmlsdGVyID0gcmVxdWlyZSgnLi4vZmlsdGVyJyk7XG5cbiAgVm9sdW1lRmlsdGVyID0gKGZ1bmN0aW9uKHN1cGVyQ2xhc3MpIHtcbiAgICBleHRlbmQoVm9sdW1lRmlsdGVyLCBzdXBlckNsYXNzKTtcblxuICAgIGZ1bmN0aW9uIFZvbHVtZUZpbHRlcigpIHtcbiAgICAgIHJldHVybiBWb2x1bWVGaWx0ZXIuX19zdXBlcl9fLmNvbnN0cnVjdG9yLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgfVxuXG4gICAgVm9sdW1lRmlsdGVyLnByb3RvdHlwZS5wcm9jZXNzID0gZnVuY3Rpb24oYnVmZmVyKSB7XG4gICAgICB2YXIgaSwgaiwgcmVmLCB2b2w7XG4gICAgICBpZiAodGhpcy52YWx1ZSA+PSAxMDApIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgdm9sID0gTWF0aC5tYXgoMCwgTWF0aC5taW4oMTAwLCB0aGlzLnZhbHVlKSkgLyAxMDA7XG4gICAgICBmb3IgKGkgPSBqID0gMCwgcmVmID0gYnVmZmVyLmxlbmd0aDsgaiA8IHJlZjsgaSA9IGogKz0gMSkge1xuICAgICAgICBidWZmZXJbaV0gKj0gdm9sO1xuICAgICAgfVxuICAgIH07XG5cbiAgICByZXR1cm4gVm9sdW1lRmlsdGVyO1xuXG4gIH0pKEZpbHRlcik7XG5cbiAgbW9kdWxlLmV4cG9ydHMgPSBWb2x1bWVGaWx0ZXI7XG5cbn0pLmNhbGwodGhpcyk7XG4iLCIvLyBHZW5lcmF0ZWQgYnkgQ29mZmVlU2NyaXB0IDEuMTIuN1xuKGZ1bmN0aW9uKCkge1xuICB2YXIgQXNzZXQsIEF1ZGlvRGV2aWNlLCBCYWxhbmNlRmlsdGVyLCBFdmVudEVtaXR0ZXIsIFBsYXllciwgUXVldWUsIFZvbHVtZUZpbHRlcixcbiAgICBiaW5kID0gZnVuY3Rpb24oZm4sIG1lKXsgcmV0dXJuIGZ1bmN0aW9uKCl7IHJldHVybiBmbi5hcHBseShtZSwgYXJndW1lbnRzKTsgfTsgfSxcbiAgICBleHRlbmQgPSBmdW5jdGlvbihjaGlsZCwgcGFyZW50KSB7IGZvciAodmFyIGtleSBpbiBwYXJlbnQpIHsgaWYgKGhhc1Byb3AuY2FsbChwYXJlbnQsIGtleSkpIGNoaWxkW2tleV0gPSBwYXJlbnRba2V5XTsgfSBmdW5jdGlvbiBjdG9yKCkgeyB0aGlzLmNvbnN0cnVjdG9yID0gY2hpbGQ7IH0gY3Rvci5wcm90b3R5cGUgPSBwYXJlbnQucHJvdG90eXBlOyBjaGlsZC5wcm90b3R5cGUgPSBuZXcgY3RvcigpOyBjaGlsZC5fX3N1cGVyX18gPSBwYXJlbnQucHJvdG90eXBlOyByZXR1cm4gY2hpbGQ7IH0sXG4gICAgaGFzUHJvcCA9IHt9Lmhhc093blByb3BlcnR5O1xuXG4gIEV2ZW50RW1pdHRlciA9IHJlcXVpcmUoJy4vY29yZS9ldmVudHMnKTtcblxuICBBc3NldCA9IHJlcXVpcmUoJy4vYXNzZXQnKTtcblxuICBWb2x1bWVGaWx0ZXIgPSByZXF1aXJlKCcuL2ZpbHRlcnMvdm9sdW1lJyk7XG5cbiAgQmFsYW5jZUZpbHRlciA9IHJlcXVpcmUoJy4vZmlsdGVycy9iYWxhbmNlJyk7XG5cbiAgUXVldWUgPSByZXF1aXJlKCcuL3F1ZXVlJyk7XG5cbiAgQXVkaW9EZXZpY2UgPSByZXF1aXJlKCcuL2RldmljZScpO1xuXG4gIFBsYXllciA9IChmdW5jdGlvbihzdXBlckNsYXNzKSB7XG4gICAgZXh0ZW5kKFBsYXllciwgc3VwZXJDbGFzcyk7XG5cbiAgICBmdW5jdGlvbiBQbGF5ZXIoYXNzZXQpIHtcbiAgICAgIHRoaXMuYXNzZXQgPSBhc3NldDtcbiAgICAgIHRoaXMuc3RhcnRQbGF5aW5nID0gYmluZCh0aGlzLnN0YXJ0UGxheWluZywgdGhpcyk7XG4gICAgICB0aGlzLnBsYXlpbmcgPSBmYWxzZTtcbiAgICAgIHRoaXMuYnVmZmVyZWQgPSAwO1xuICAgICAgdGhpcy5jdXJyZW50VGltZSA9IDA7XG4gICAgICB0aGlzLmR1cmF0aW9uID0gMDtcbiAgICAgIHRoaXMudm9sdW1lID0gMTAwO1xuICAgICAgdGhpcy5wYW4gPSAwO1xuICAgICAgdGhpcy5tZXRhZGF0YSA9IHt9O1xuICAgICAgdGhpcy5maWx0ZXJzID0gW25ldyBWb2x1bWVGaWx0ZXIodGhpcywgJ3ZvbHVtZScpLCBuZXcgQmFsYW5jZUZpbHRlcih0aGlzLCAncGFuJyldO1xuICAgICAgdGhpcy5hc3NldC5vbignYnVmZmVyJywgKGZ1bmN0aW9uKF90aGlzKSB7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbihidWZmZXJlZCkge1xuICAgICAgICAgIF90aGlzLmJ1ZmZlcmVkID0gYnVmZmVyZWQ7XG4gICAgICAgICAgcmV0dXJuIF90aGlzLmVtaXQoJ2J1ZmZlcicsIF90aGlzLmJ1ZmZlcmVkKTtcbiAgICAgICAgfTtcbiAgICAgIH0pKHRoaXMpKTtcbiAgICAgIHRoaXMuYXNzZXQub24oJ2RlY29kZVN0YXJ0JywgKGZ1bmN0aW9uKF90aGlzKSB7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICAgICAgICBfdGhpcy5xdWV1ZSA9IG5ldyBRdWV1ZShfdGhpcy5hc3NldCk7XG4gICAgICAgICAgcmV0dXJuIF90aGlzLnF1ZXVlLm9uY2UoJ3JlYWR5JywgX3RoaXMuc3RhcnRQbGF5aW5nKTtcbiAgICAgICAgfTtcbiAgICAgIH0pKHRoaXMpKTtcbiAgICAgIHRoaXMuYXNzZXQub24oJ2Zvcm1hdCcsIChmdW5jdGlvbihfdGhpcykge1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24oZm9ybWF0KSB7XG4gICAgICAgICAgX3RoaXMuZm9ybWF0ID0gZm9ybWF0O1xuICAgICAgICAgIHJldHVybiBfdGhpcy5lbWl0KCdmb3JtYXQnLCBfdGhpcy5mb3JtYXQpO1xuICAgICAgICB9O1xuICAgICAgfSkodGhpcykpO1xuICAgICAgdGhpcy5hc3NldC5vbignbWV0YWRhdGEnLCAoZnVuY3Rpb24oX3RoaXMpIHtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKG1ldGFkYXRhKSB7XG4gICAgICAgICAgX3RoaXMubWV0YWRhdGEgPSBtZXRhZGF0YTtcbiAgICAgICAgICByZXR1cm4gX3RoaXMuZW1pdCgnbWV0YWRhdGEnLCBfdGhpcy5tZXRhZGF0YSk7XG4gICAgICAgIH07XG4gICAgICB9KSh0aGlzKSk7XG4gICAgICB0aGlzLmFzc2V0Lm9uKCdkdXJhdGlvbicsIChmdW5jdGlvbihfdGhpcykge1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24oZHVyYXRpb24pIHtcbiAgICAgICAgICBfdGhpcy5kdXJhdGlvbiA9IGR1cmF0aW9uO1xuICAgICAgICAgIHJldHVybiBfdGhpcy5lbWl0KCdkdXJhdGlvbicsIF90aGlzLmR1cmF0aW9uKTtcbiAgICAgICAgfTtcbiAgICAgIH0pKHRoaXMpKTtcbiAgICAgIHRoaXMuYXNzZXQub24oJ2Vycm9yJywgKGZ1bmN0aW9uKF90aGlzKSB7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbihlcnJvcikge1xuICAgICAgICAgIHJldHVybiBfdGhpcy5lbWl0KCdlcnJvcicsIGVycm9yKTtcbiAgICAgICAgfTtcbiAgICAgIH0pKHRoaXMpKTtcbiAgICB9XG5cbiAgICBQbGF5ZXIuZnJvbVVSTCA9IGZ1bmN0aW9uKHVybCwgb3B0cykge1xuICAgICAgcmV0dXJuIG5ldyBQbGF5ZXIoQXNzZXQuZnJvbVVSTCh1cmwsIG9wdHMpKTtcbiAgICB9O1xuXG4gICAgUGxheWVyLmZyb21GaWxlID0gZnVuY3Rpb24oZmlsZSkge1xuICAgICAgcmV0dXJuIG5ldyBQbGF5ZXIoQXNzZXQuZnJvbUZpbGUoZmlsZSkpO1xuICAgIH07XG5cbiAgICBQbGF5ZXIuZnJvbUJ1ZmZlciA9IGZ1bmN0aW9uKGJ1ZmZlcikge1xuICAgICAgcmV0dXJuIG5ldyBQbGF5ZXIoQXNzZXQuZnJvbUJ1ZmZlcihidWZmZXIpKTtcbiAgICB9O1xuXG4gICAgUGxheWVyLnByb3RvdHlwZS5wcmVsb2FkID0gZnVuY3Rpb24oKSB7XG4gICAgICBpZiAoIXRoaXMuYXNzZXQpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgdGhpcy5zdGFydGVkUHJlbG9hZGluZyA9IHRydWU7XG4gICAgICByZXR1cm4gdGhpcy5hc3NldC5zdGFydChmYWxzZSk7XG4gICAgfTtcblxuICAgIFBsYXllci5wcm90b3R5cGUucGxheSA9IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIHJlZjtcbiAgICAgIGlmICh0aGlzLnBsYXlpbmcpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgaWYgKCF0aGlzLnN0YXJ0ZWRQcmVsb2FkaW5nKSB7XG4gICAgICAgIHRoaXMucHJlbG9hZCgpO1xuICAgICAgfVxuICAgICAgdGhpcy5wbGF5aW5nID0gdHJ1ZTtcbiAgICAgIHJldHVybiAocmVmID0gdGhpcy5kZXZpY2UpICE9IG51bGwgPyByZWYuc3RhcnQoKSA6IHZvaWQgMDtcbiAgICB9O1xuXG4gICAgUGxheWVyLnByb3RvdHlwZS5wYXVzZSA9IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIHJlZjtcbiAgICAgIGlmICghdGhpcy5wbGF5aW5nKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIHRoaXMucGxheWluZyA9IGZhbHNlO1xuICAgICAgcmV0dXJuIChyZWYgPSB0aGlzLmRldmljZSkgIT0gbnVsbCA/IHJlZi5zdG9wKCkgOiB2b2lkIDA7XG4gICAgfTtcblxuICAgIFBsYXllci5wcm90b3R5cGUudG9nZ2xlUGxheWJhY2sgPSBmdW5jdGlvbigpIHtcbiAgICAgIGlmICh0aGlzLnBsYXlpbmcpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucGF1c2UoKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiB0aGlzLnBsYXkoKTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgUGxheWVyLnByb3RvdHlwZS5zdG9wID0gZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgcmVmO1xuICAgICAgdGhpcy5wYXVzZSgpO1xuICAgICAgdGhpcy5hc3NldC5zdG9wKCk7XG4gICAgICByZXR1cm4gKHJlZiA9IHRoaXMuZGV2aWNlKSAhPSBudWxsID8gcmVmLmRlc3Ryb3koKSA6IHZvaWQgMDtcbiAgICB9O1xuXG4gICAgUGxheWVyLnByb3RvdHlwZS5zZWVrID0gZnVuY3Rpb24odGltZXN0YW1wKSB7XG4gICAgICB2YXIgcmVmO1xuICAgICAgaWYgKChyZWYgPSB0aGlzLmRldmljZSkgIT0gbnVsbCkge1xuICAgICAgICByZWYuc3RvcCgpO1xuICAgICAgfVxuICAgICAgdGhpcy5xdWV1ZS5vbmNlKCdyZWFkeScsIChmdW5jdGlvbihfdGhpcykge1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgICAgICAgdmFyIHJlZjEsIHJlZjI7XG4gICAgICAgICAgaWYgKChyZWYxID0gX3RoaXMuZGV2aWNlKSAhPSBudWxsKSB7XG4gICAgICAgICAgICByZWYxLnNlZWsoX3RoaXMuY3VycmVudFRpbWUpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoX3RoaXMucGxheWluZykge1xuICAgICAgICAgICAgcmV0dXJuIChyZWYyID0gX3RoaXMuZGV2aWNlKSAhPSBudWxsID8gcmVmMi5zdGFydCgpIDogdm9pZCAwO1xuICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgIH0pKHRoaXMpKTtcbiAgICAgIHRpbWVzdGFtcCA9ICh0aW1lc3RhbXAgLyAxMDAwKSAqIHRoaXMuZm9ybWF0LnNhbXBsZVJhdGU7XG4gICAgICB0aW1lc3RhbXAgPSB0aGlzLmFzc2V0LmRlY29kZXIuc2Vlayh0aW1lc3RhbXApO1xuICAgICAgdGhpcy5jdXJyZW50VGltZSA9IHRpbWVzdGFtcCAvIHRoaXMuZm9ybWF0LnNhbXBsZVJhdGUgKiAxMDAwIHwgMDtcbiAgICAgIHRoaXMucXVldWUucmVzZXQoKTtcbiAgICAgIHJldHVybiB0aGlzLmN1cnJlbnRUaW1lO1xuICAgIH07XG5cbiAgICBQbGF5ZXIucHJvdG90eXBlLnN0YXJ0UGxheWluZyA9IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIGZyYW1lLCBmcmFtZU9mZnNldDtcbiAgICAgIGZyYW1lID0gdGhpcy5xdWV1ZS5yZWFkKCk7XG4gICAgICBmcmFtZU9mZnNldCA9IDA7XG4gICAgICB0aGlzLmRldmljZSA9IG5ldyBBdWRpb0RldmljZSh0aGlzLmZvcm1hdC5zYW1wbGVSYXRlLCB0aGlzLmZvcm1hdC5jaGFubmVsc1BlckZyYW1lKTtcbiAgICAgIHRoaXMuZGV2aWNlLm9uKCd0aW1lVXBkYXRlJywgKGZ1bmN0aW9uKF90aGlzKSB7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbihjdXJyZW50VGltZSkge1xuICAgICAgICAgIF90aGlzLmN1cnJlbnRUaW1lID0gY3VycmVudFRpbWU7XG4gICAgICAgICAgcmV0dXJuIF90aGlzLmVtaXQoJ3Byb2dyZXNzJywgX3RoaXMuY3VycmVudFRpbWUpO1xuICAgICAgICB9O1xuICAgICAgfSkodGhpcykpO1xuICAgICAgdGhpcy5yZWZpbGwgPSAoZnVuY3Rpb24oX3RoaXMpIHtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKGJ1ZmZlcikge1xuICAgICAgICAgIHZhciBidWZmZXJPZmZzZXQsIGZpbHRlciwgaSwgaiwgaywgbGVuLCBtYXgsIHJlZiwgcmVmMTtcbiAgICAgICAgICBpZiAoIV90aGlzLnBsYXlpbmcpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKCFmcmFtZSkge1xuICAgICAgICAgICAgZnJhbWUgPSBfdGhpcy5xdWV1ZS5yZWFkKCk7XG4gICAgICAgICAgICBmcmFtZU9mZnNldCA9IDA7XG4gICAgICAgICAgfVxuICAgICAgICAgIGJ1ZmZlck9mZnNldCA9IDA7XG4gICAgICAgICAgd2hpbGUgKGZyYW1lICYmIGJ1ZmZlck9mZnNldCA8IGJ1ZmZlci5sZW5ndGgpIHtcbiAgICAgICAgICAgIG1heCA9IE1hdGgubWluKGZyYW1lLmxlbmd0aCAtIGZyYW1lT2Zmc2V0LCBidWZmZXIubGVuZ3RoIC0gYnVmZmVyT2Zmc2V0KTtcbiAgICAgICAgICAgIGZvciAoaSA9IGogPSAwLCByZWYgPSBtYXg7IGogPCByZWY7IGkgPSBqICs9IDEpIHtcbiAgICAgICAgICAgICAgYnVmZmVyW2J1ZmZlck9mZnNldCsrXSA9IGZyYW1lW2ZyYW1lT2Zmc2V0KytdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGZyYW1lT2Zmc2V0ID09PSBmcmFtZS5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgZnJhbWUgPSBfdGhpcy5xdWV1ZS5yZWFkKCk7XG4gICAgICAgICAgICAgIGZyYW1lT2Zmc2V0ID0gMDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgcmVmMSA9IF90aGlzLmZpbHRlcnM7XG4gICAgICAgICAgZm9yIChrID0gMCwgbGVuID0gcmVmMS5sZW5ndGg7IGsgPCBsZW47IGsrKykge1xuICAgICAgICAgICAgZmlsdGVyID0gcmVmMVtrXTtcbiAgICAgICAgICAgIGZpbHRlci5wcm9jZXNzKGJ1ZmZlcik7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmICghZnJhbWUpIHtcbiAgICAgICAgICAgIGlmIChfdGhpcy5xdWV1ZS5lbmRlZCkge1xuICAgICAgICAgICAgICBfdGhpcy5jdXJyZW50VGltZSA9IF90aGlzLmR1cmF0aW9uO1xuICAgICAgICAgICAgICBfdGhpcy5lbWl0KCdwcm9ncmVzcycsIF90aGlzLmN1cnJlbnRUaW1lKTtcbiAgICAgICAgICAgICAgX3RoaXMuZW1pdCgnZW5kJyk7XG4gICAgICAgICAgICAgIF90aGlzLnN0b3AoKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIF90aGlzLmRldmljZS5zdG9wKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgfSkodGhpcyk7XG4gICAgICB0aGlzLmRldmljZS5vbigncmVmaWxsJywgdGhpcy5yZWZpbGwpO1xuICAgICAgaWYgKHRoaXMucGxheWluZykge1xuICAgICAgICB0aGlzLmRldmljZS5zdGFydCgpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXMuZW1pdCgncmVhZHknKTtcbiAgICB9O1xuXG4gICAgUGxheWVyLnByb3RvdHlwZS5kZXN0cm95ID0gZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgcmVmLCByZWYxO1xuICAgICAgdGhpcy5zdG9wKCk7XG4gICAgICBpZiAoKHJlZiA9IHRoaXMuZGV2aWNlKSAhPSBudWxsKSB7XG4gICAgICAgIHJlZi5vZmYoKTtcbiAgICAgIH1cbiAgICAgIGlmICgocmVmMSA9IHRoaXMuYXNzZXQpICE9IG51bGwpIHtcbiAgICAgICAgcmVmMS5kZXN0cm95KCk7XG4gICAgICB9XG4gICAgICByZXR1cm4gdGhpcy5vZmYoKTtcbiAgICB9O1xuXG4gICAgcmV0dXJuIFBsYXllcjtcblxuICB9KShFdmVudEVtaXR0ZXIpO1xuXG4gIG1vZHVsZS5leHBvcnRzID0gUGxheWVyO1xuXG59KS5jYWxsKHRoaXMpO1xuIiwiLy8gR2VuZXJhdGVkIGJ5IENvZmZlZVNjcmlwdCAxLjEyLjdcbihmdW5jdGlvbigpIHtcbiAgdmFyIEV2ZW50RW1pdHRlciwgUXVldWUsXG4gICAgYmluZCA9IGZ1bmN0aW9uKGZuLCBtZSl7IHJldHVybiBmdW5jdGlvbigpeyByZXR1cm4gZm4uYXBwbHkobWUsIGFyZ3VtZW50cyk7IH07IH0sXG4gICAgZXh0ZW5kID0gZnVuY3Rpb24oY2hpbGQsIHBhcmVudCkgeyBmb3IgKHZhciBrZXkgaW4gcGFyZW50KSB7IGlmIChoYXNQcm9wLmNhbGwocGFyZW50LCBrZXkpKSBjaGlsZFtrZXldID0gcGFyZW50W2tleV07IH0gZnVuY3Rpb24gY3RvcigpIHsgdGhpcy5jb25zdHJ1Y3RvciA9IGNoaWxkOyB9IGN0b3IucHJvdG90eXBlID0gcGFyZW50LnByb3RvdHlwZTsgY2hpbGQucHJvdG90eXBlID0gbmV3IGN0b3IoKTsgY2hpbGQuX19zdXBlcl9fID0gcGFyZW50LnByb3RvdHlwZTsgcmV0dXJuIGNoaWxkOyB9LFxuICAgIGhhc1Byb3AgPSB7fS5oYXNPd25Qcm9wZXJ0eTtcblxuICBFdmVudEVtaXR0ZXIgPSByZXF1aXJlKCcuL2NvcmUvZXZlbnRzJyk7XG5cbiAgUXVldWUgPSAoZnVuY3Rpb24oc3VwZXJDbGFzcykge1xuICAgIGV4dGVuZChRdWV1ZSwgc3VwZXJDbGFzcyk7XG5cbiAgICBmdW5jdGlvbiBRdWV1ZShhc3NldCkge1xuICAgICAgdGhpcy5hc3NldCA9IGFzc2V0O1xuICAgICAgdGhpcy53cml0ZSA9IGJpbmQodGhpcy53cml0ZSwgdGhpcyk7XG4gICAgICB0aGlzLnJlYWR5TWFyayA9IDY0O1xuICAgICAgdGhpcy5maW5pc2hlZCA9IGZhbHNlO1xuICAgICAgdGhpcy5idWZmZXJpbmcgPSB0cnVlO1xuICAgICAgdGhpcy5lbmRlZCA9IGZhbHNlO1xuICAgICAgdGhpcy5idWZmZXJzID0gW107XG4gICAgICB0aGlzLmFzc2V0Lm9uKCdkYXRhJywgdGhpcy53cml0ZSk7XG4gICAgICB0aGlzLmFzc2V0Lm9uKCdlbmQnLCAoZnVuY3Rpb24oX3RoaXMpIHtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgICAgICAgIHJldHVybiBfdGhpcy5lbmRlZCA9IHRydWU7XG4gICAgICAgIH07XG4gICAgICB9KSh0aGlzKSk7XG4gICAgICB0aGlzLmFzc2V0LmRlY29kZVBhY2tldCgpO1xuICAgIH1cblxuICAgIFF1ZXVlLnByb3RvdHlwZS53cml0ZSA9IGZ1bmN0aW9uKGJ1ZmZlcikge1xuICAgICAgaWYgKGJ1ZmZlcikge1xuICAgICAgICB0aGlzLmJ1ZmZlcnMucHVzaChidWZmZXIpO1xuICAgICAgfVxuICAgICAgaWYgKHRoaXMuYnVmZmVyaW5nKSB7XG4gICAgICAgIGlmICh0aGlzLmJ1ZmZlcnMubGVuZ3RoID49IHRoaXMucmVhZHlNYXJrIHx8IHRoaXMuZW5kZWQpIHtcbiAgICAgICAgICB0aGlzLmJ1ZmZlcmluZyA9IGZhbHNlO1xuICAgICAgICAgIHJldHVybiB0aGlzLmVtaXQoJ3JlYWR5Jyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuIHRoaXMuYXNzZXQuZGVjb2RlUGFja2V0KCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9O1xuXG4gICAgUXVldWUucHJvdG90eXBlLnJlYWQgPSBmdW5jdGlvbigpIHtcbiAgICAgIGlmICh0aGlzLmJ1ZmZlcnMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfVxuICAgICAgdGhpcy5hc3NldC5kZWNvZGVQYWNrZXQoKTtcbiAgICAgIHJldHVybiB0aGlzLmJ1ZmZlcnMuc2hpZnQoKTtcbiAgICB9O1xuXG4gICAgUXVldWUucHJvdG90eXBlLnJlc2V0ID0gZnVuY3Rpb24oKSB7XG4gICAgICB0aGlzLmJ1ZmZlcnMubGVuZ3RoID0gMDtcbiAgICAgIHRoaXMuYnVmZmVyaW5nID0gdHJ1ZTtcbiAgICAgIHJldHVybiB0aGlzLmFzc2V0LmRlY29kZVBhY2tldCgpO1xuICAgIH07XG5cbiAgICByZXR1cm4gUXVldWU7XG5cbiAgfSkoRXZlbnRFbWl0dGVyKTtcblxuICBtb2R1bGUuZXhwb3J0cyA9IFF1ZXVlO1xuXG59KS5jYWxsKHRoaXMpO1xuIiwiRXZlbnRFbWl0dGVyID0gcmVxdWlyZSAnLi4vLi4vY29yZS9ldmVudHMnXG5BVkJ1ZmZlciA9IHJlcXVpcmUgJy4uLy4uL2NvcmUvYnVmZmVyJ1xuXG5jbGFzcyBGaWxlU291cmNlIGV4dGVuZHMgRXZlbnRFbWl0dGVyXG4gICAgY29uc3RydWN0b3I6IChAZmlsZSkgLT5cbiAgICAgICAgaWYgbm90IEZpbGVSZWFkZXI/XG4gICAgICAgICAgICByZXR1cm4gQGVtaXQgJ2Vycm9yJywgJ1RoaXMgYnJvd3NlciBkb2VzIG5vdCBoYXZlIEZpbGVSZWFkZXIgc3VwcG9ydC4nXG4gICAgICAgIFxuICAgICAgICBAb2Zmc2V0ID0gMFxuICAgICAgICBAbGVuZ3RoID0gQGZpbGUuc2l6ZVxuICAgICAgICBAY2h1bmtTaXplID0gMSA8PCAyMFxuICAgICAgICBAZmlsZVtAc2xpY2UgPSAnc2xpY2UnXSBvciBAZmlsZVtAc2xpY2UgPSAnd2Via2l0U2xpY2UnXSBvciBAZmlsZVtAc2xpY2UgPSAnbW96U2xpY2UnXVxuICAgICAgICAgICAgXG4gICAgc3RhcnQ6IC0+XG4gICAgICAgIGlmIEByZWFkZXJcbiAgICAgICAgICAgIHJldHVybiBAbG9vcCgpIHVubGVzcyBAYWN0aXZlXG4gICAgICAgIFxuICAgICAgICBAcmVhZGVyID0gbmV3IEZpbGVSZWFkZXJcbiAgICAgICAgQGFjdGl2ZSA9IHRydWVcbiAgICAgICAgXG4gICAgICAgIEByZWFkZXIub25sb2FkID0gKGUpID0+XG4gICAgICAgICAgICBidWYgPSBuZXcgQVZCdWZmZXIobmV3IFVpbnQ4QXJyYXkoZS50YXJnZXQucmVzdWx0KSlcbiAgICAgICAgICAgIEBvZmZzZXQgKz0gYnVmLmxlbmd0aFxuICAgICAgICBcbiAgICAgICAgICAgIEBlbWl0ICdkYXRhJywgYnVmICAgXG4gICAgICAgICAgICBAYWN0aXZlID0gZmFsc2UgICAgIFxuICAgICAgICAgICAgQGxvb3AoKSBpZiBAb2Zmc2V0IDwgQGxlbmd0aFxuICAgICAgICBcbiAgICAgICAgQHJlYWRlci5vbmxvYWRlbmQgPSA9PlxuICAgICAgICAgICAgaWYgQG9mZnNldCBpcyBAbGVuZ3RoXG4gICAgICAgICAgICAgICAgQGVtaXQgJ2VuZCdcbiAgICAgICAgICAgICAgICBAcmVhZGVyID0gbnVsbFxuICAgICAgICBcbiAgICAgICAgQHJlYWRlci5vbmVycm9yID0gKGUpID0+XG4gICAgICAgICAgICBAZW1pdCAnZXJyb3InLCBlXG4gICAgICAgIFxuICAgICAgICBAcmVhZGVyLm9ucHJvZ3Jlc3MgPSAoZSkgPT5cbiAgICAgICAgICAgIEBlbWl0ICdwcm9ncmVzcycsIChAb2Zmc2V0ICsgZS5sb2FkZWQpIC8gQGxlbmd0aCAqIDEwMFxuICAgICAgICBcbiAgICAgICAgQGxvb3AoKVxuICAgICAgICBcbiAgICBsb29wOiAtPlxuICAgICAgICBAYWN0aXZlID0gdHJ1ZVxuICAgICAgICBlbmRQb3MgPSBNYXRoLm1pbihAb2Zmc2V0ICsgQGNodW5rU2l6ZSwgQGxlbmd0aClcbiAgICAgICAgXG4gICAgICAgIGJsb2IgPSBAZmlsZVtAc2xpY2VdKEBvZmZzZXQsIGVuZFBvcylcbiAgICAgICAgQHJlYWRlci5yZWFkQXNBcnJheUJ1ZmZlcihibG9iKVxuICAgICAgICBcbiAgICBwYXVzZTogLT5cbiAgICAgICAgQGFjdGl2ZSA9IGZhbHNlXG4gICAgICAgIHRyeVxuICAgICAgICAgIEByZWFkZXI/LmFib3J0KClcbiAgICAgICAgXG4gICAgcmVzZXQ6IC0+XG4gICAgICAgIEBwYXVzZSgpXG4gICAgICAgIEBvZmZzZXQgPSAwXG5cbm1vZHVsZS5leHBvcnRzID0gRmlsZVNvdXJjZVxuIiwiRXZlbnRFbWl0dGVyID0gcmVxdWlyZSAnLi4vLi4vY29yZS9ldmVudHMnXG5BVkJ1ZmZlciA9IHJlcXVpcmUgJy4uLy4uL2NvcmUvYnVmZmVyJ1xuXG5jbGFzcyBIVFRQU291cmNlIGV4dGVuZHMgRXZlbnRFbWl0dGVyXG4gICAgY29uc3RydWN0b3I6IChAdXJsLCBAb3B0cyA9IHt9KSAtPlxuICAgICAgICBAY2h1bmtTaXplID0gMSA8PCAyMFxuICAgICAgICBAaW5mbGlnaHQgPSBmYWxzZVxuICAgICAgICBpZiBAb3B0cy5sZW5ndGhcbiAgICAgICAgICAgIEBsZW5ndGggPSBAb3B0cy5sZW5ndGhcbiAgICAgICAgQHJlc2V0KClcbiAgICAgICAgXG4gICAgc3RhcnQ6IC0+XG4gICAgICAgIGlmIEBsZW5ndGhcbiAgICAgICAgICAgIHJldHVybiBAbG9vcCgpIHVubGVzcyBAaW5mbGlnaHRcbiAgICAgICAgXG4gICAgICAgIEBpbmZsaWdodCA9IHRydWVcbiAgICAgICAgQHhociA9IG5ldyBYTUxIdHRwUmVxdWVzdCgpXG4gICAgICAgIFxuICAgICAgICBAeGhyLm9ubG9hZCA9IChldmVudCkgPT5cbiAgICAgICAgICAgIEBsZW5ndGggPSBwYXJzZUludCBAeGhyLmdldFJlc3BvbnNlSGVhZGVyKFwiQ29udGVudC1MZW5ndGhcIikgICAgICAgICAgICAgICAgXG4gICAgICAgICAgICBAaW5mbGlnaHQgPSBmYWxzZVxuICAgICAgICAgICAgQGxvb3AoKVxuICAgICAgICBcbiAgICAgICAgQHhoci5vbmVycm9yID0gKGVycikgPT5cbiAgICAgICAgICAgIEBwYXVzZSgpXG4gICAgICAgICAgICBAZW1pdCAnZXJyb3InLCBlcnJcbiAgICAgICAgICAgIFxuICAgICAgICBAeGhyLm9uYWJvcnQgPSAoZXZlbnQpID0+XG4gICAgICAgICAgICBAaW5mbGlnaHQgPSBmYWxzZVxuICAgICAgICBcbiAgICAgICAgQHhoci5vcGVuKFwiSEVBRFwiLCBAdXJsLCB0cnVlKVxuICAgICAgICBAeGhyLnNlbmQobnVsbClcbiAgICAgICAgXG4gICAgbG9vcDogLT5cbiAgICAgICAgaWYgQGluZmxpZ2h0IG9yIG5vdCBAbGVuZ3RoXG4gICAgICAgICAgICByZXR1cm4gQGVtaXQgJ2Vycm9yJywgJ1NvbWV0aGluZyBpcyB3cm9uZyBpbiBIVFRQU291cmNlLmxvb3AnXG4gICAgICAgICAgICBcbiAgICAgICAgQGluZmxpZ2h0ID0gdHJ1ZVxuICAgICAgICBAeGhyID0gbmV3IFhNTEh0dHBSZXF1ZXN0KClcbiAgICAgICAgXG4gICAgICAgIEB4aHIub25sb2FkID0gKGV2ZW50KSA9PlxuICAgICAgICAgICAgaWYgQHhoci5yZXNwb25zZVxuICAgICAgICAgICAgICAgIGJ1ZiA9IG5ldyBVaW50OEFycmF5KEB4aHIucmVzcG9uc2UpXG4gICAgICAgICAgICBlbHNlXG4gICAgICAgICAgICAgICAgdHh0ID0gQHhoci5yZXNwb25zZVRleHRcbiAgICAgICAgICAgICAgICBidWYgPSBuZXcgVWludDhBcnJheSh0eHQubGVuZ3RoKVxuICAgICAgICAgICAgICAgIGZvciBpIGluIFswLi4udHh0Lmxlbmd0aF1cbiAgICAgICAgICAgICAgICAgICAgYnVmW2ldID0gdHh0LmNoYXJDb2RlQXQoaSkgJiAweGZmXG5cbiAgICAgICAgICAgIGJ1ZmZlciA9IG5ldyBBVkJ1ZmZlcihidWYpXG4gICAgICAgICAgICBAb2Zmc2V0ICs9IGJ1ZmZlci5sZW5ndGhcbiAgICAgICAgICAgIFxuICAgICAgICAgICAgQGVtaXQgJ2RhdGEnLCBidWZmZXJcbiAgICAgICAgICAgIEBlbWl0ICdlbmQnIGlmIEBvZmZzZXQgPj0gQGxlbmd0aFxuXG4gICAgICAgICAgICBAaW5mbGlnaHQgPSBmYWxzZVxuICAgICAgICAgICAgQGxvb3AoKSB1bmxlc3MgQG9mZnNldCA+PSBAbGVuZ3RoXG4gICAgICAgICAgICBcbiAgICAgICAgQHhoci5vbnByb2dyZXNzID0gKGV2ZW50KSA9PlxuICAgICAgICAgICAgQGVtaXQgJ3Byb2dyZXNzJywgKEBvZmZzZXQgKyBldmVudC5sb2FkZWQpIC8gQGxlbmd0aCAqIDEwMFxuXG4gICAgICAgIEB4aHIub25lcnJvciA9IChlcnIpID0+XG4gICAgICAgICAgICBAZW1pdCAnZXJyb3InLCBlcnJcbiAgICAgICAgICAgIEBwYXVzZSgpXG5cbiAgICAgICAgQHhoci5vbmFib3J0ID0gKGV2ZW50KSA9PlxuICAgICAgICAgICAgQGluZmxpZ2h0ID0gZmFsc2VcblxuICAgICAgICBAeGhyLm9wZW4oXCJHRVRcIiwgQHVybCwgdHJ1ZSlcbiAgICAgICAgQHhoci5yZXNwb25zZVR5cGUgPSBcImFycmF5YnVmZmVyXCJcblxuICAgICAgICBlbmRQb3MgPSBNYXRoLm1pbihAb2Zmc2V0ICsgQGNodW5rU2l6ZSwgQGxlbmd0aCAtIDEpXG4gICAgICAgIEB4aHIuc2V0UmVxdWVzdEhlYWRlcihcIklmLU5vbmUtTWF0Y2hcIiwgXCJ3ZWJraXQtbm8tY2FjaGVcIilcbiAgICAgICAgQHhoci5zZXRSZXF1ZXN0SGVhZGVyKFwiUmFuZ2VcIiwgXCJieXRlcz0je0BvZmZzZXR9LSN7ZW5kUG9zfVwiKVxuICAgICAgICBAeGhyLm92ZXJyaWRlTWltZVR5cGUoJ3RleHQvcGxhaW47IGNoYXJzZXQ9eC11c2VyLWRlZmluZWQnKVxuICAgICAgICBAeGhyLnNlbmQobnVsbClcbiAgICAgICAgXG4gICAgcGF1c2U6IC0+XG4gICAgICAgIEBpbmZsaWdodCA9IGZhbHNlXG4gICAgICAgIEB4aHI/LmFib3J0KClcbiAgICAgICAgXG4gICAgcmVzZXQ6IC0+XG4gICAgICAgIEBwYXVzZSgpXG4gICAgICAgIEBvZmZzZXQgPSAwXG4gICAgICAgIFxubW9kdWxlLmV4cG9ydHMgPSBIVFRQU291cmNlXG4iLCIvLyBHZW5lcmF0ZWQgYnkgQ29mZmVlU2NyaXB0IDEuMTIuN1xuKGZ1bmN0aW9uKCkge1xuICB2YXIgQVZCdWZmZXIsIEJ1ZmZlckxpc3QsIEJ1ZmZlclNvdXJjZSwgRXZlbnRFbWl0dGVyLFxuICAgIGJpbmQgPSBmdW5jdGlvbihmbiwgbWUpeyByZXR1cm4gZnVuY3Rpb24oKXsgcmV0dXJuIGZuLmFwcGx5KG1lLCBhcmd1bWVudHMpOyB9OyB9LFxuICAgIGV4dGVuZCA9IGZ1bmN0aW9uKGNoaWxkLCBwYXJlbnQpIHsgZm9yICh2YXIga2V5IGluIHBhcmVudCkgeyBpZiAoaGFzUHJvcC5jYWxsKHBhcmVudCwga2V5KSkgY2hpbGRba2V5XSA9IHBhcmVudFtrZXldOyB9IGZ1bmN0aW9uIGN0b3IoKSB7IHRoaXMuY29uc3RydWN0b3IgPSBjaGlsZDsgfSBjdG9yLnByb3RvdHlwZSA9IHBhcmVudC5wcm90b3R5cGU7IGNoaWxkLnByb3RvdHlwZSA9IG5ldyBjdG9yKCk7IGNoaWxkLl9fc3VwZXJfXyA9IHBhcmVudC5wcm90b3R5cGU7IHJldHVybiBjaGlsZDsgfSxcbiAgICBoYXNQcm9wID0ge30uaGFzT3duUHJvcGVydHk7XG5cbiAgRXZlbnRFbWl0dGVyID0gcmVxdWlyZSgnLi4vY29yZS9ldmVudHMnKTtcblxuICBCdWZmZXJMaXN0ID0gcmVxdWlyZSgnLi4vY29yZS9idWZmZXJsaXN0Jyk7XG5cbiAgQVZCdWZmZXIgPSByZXF1aXJlKCcuLi9jb3JlL2J1ZmZlcicpO1xuXG4gIEJ1ZmZlclNvdXJjZSA9IChmdW5jdGlvbihzdXBlckNsYXNzKSB7XG4gICAgdmFyIGNsZWFySW1tZWRpYXRlLCBzZXRJbW1lZGlhdGU7XG5cbiAgICBleHRlbmQoQnVmZmVyU291cmNlLCBzdXBlckNsYXNzKTtcblxuICAgIGZ1bmN0aW9uIEJ1ZmZlclNvdXJjZShpbnB1dCkge1xuICAgICAgdGhpcy5sb29wID0gYmluZCh0aGlzLmxvb3AsIHRoaXMpO1xuICAgICAgaWYgKGlucHV0IGluc3RhbmNlb2YgQnVmZmVyTGlzdCkge1xuICAgICAgICB0aGlzLmxpc3QgPSBpbnB1dDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMubGlzdCA9IG5ldyBCdWZmZXJMaXN0O1xuICAgICAgICB0aGlzLmxpc3QuYXBwZW5kKG5ldyBBVkJ1ZmZlcihpbnB1dCkpO1xuICAgICAgfVxuICAgICAgdGhpcy5wYXVzZWQgPSB0cnVlO1xuICAgIH1cblxuICAgIHNldEltbWVkaWF0ZSA9IGdsb2JhbC5zZXRJbW1lZGlhdGUgfHwgZnVuY3Rpb24oZm4pIHtcbiAgICAgIHJldHVybiBnbG9iYWwuc2V0VGltZW91dChmbiwgMCk7XG4gICAgfTtcblxuICAgIGNsZWFySW1tZWRpYXRlID0gZ2xvYmFsLmNsZWFySW1tZWRpYXRlIHx8IGZ1bmN0aW9uKHRpbWVyKSB7XG4gICAgICByZXR1cm4gZ2xvYmFsLmNsZWFyVGltZW91dCh0aW1lcik7XG4gICAgfTtcblxuICAgIEJ1ZmZlclNvdXJjZS5wcm90b3R5cGUuc3RhcnQgPSBmdW5jdGlvbigpIHtcbiAgICAgIHRoaXMucGF1c2VkID0gZmFsc2U7XG4gICAgICByZXR1cm4gdGhpcy5fdGltZXIgPSBzZXRJbW1lZGlhdGUodGhpcy5sb29wKTtcbiAgICB9O1xuXG4gICAgQnVmZmVyU291cmNlLnByb3RvdHlwZS5sb29wID0gZnVuY3Rpb24oKSB7XG4gICAgICB0aGlzLmVtaXQoJ3Byb2dyZXNzJywgKHRoaXMubGlzdC5udW1CdWZmZXJzIC0gdGhpcy5saXN0LmF2YWlsYWJsZUJ1ZmZlcnMgKyAxKSAvIHRoaXMubGlzdC5udW1CdWZmZXJzICogMTAwIHwgMCk7XG4gICAgICB0aGlzLmVtaXQoJ2RhdGEnLCB0aGlzLmxpc3QuZmlyc3QpO1xuICAgICAgaWYgKHRoaXMubGlzdC5hZHZhbmNlKCkpIHtcbiAgICAgICAgcmV0dXJuIHNldEltbWVkaWF0ZSh0aGlzLmxvb3ApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZW1pdCgnZW5kJyk7XG4gICAgICB9XG4gICAgfTtcblxuICAgIEJ1ZmZlclNvdXJjZS5wcm90b3R5cGUucGF1c2UgPSBmdW5jdGlvbigpIHtcbiAgICAgIGNsZWFySW1tZWRpYXRlKHRoaXMuX3RpbWVyKTtcbiAgICAgIHJldHVybiB0aGlzLnBhdXNlZCA9IHRydWU7XG4gICAgfTtcblxuICAgIEJ1ZmZlclNvdXJjZS5wcm90b3R5cGUucmVzZXQgPSBmdW5jdGlvbigpIHtcbiAgICAgIHRoaXMucGF1c2UoKTtcbiAgICAgIHJldHVybiB0aGlzLmxpc3QucmV3aW5kKCk7XG4gICAgfTtcblxuICAgIHJldHVybiBCdWZmZXJTb3VyY2U7XG5cbiAgfSkoRXZlbnRFbWl0dGVyKTtcblxuICBtb2R1bGUuZXhwb3J0cyA9IEJ1ZmZlclNvdXJjZTtcblxufSkuY2FsbCh0aGlzKTtcbiJdfQ==