UNPKG

kinto

Version:

An Offline-First JavaScript client for Kinto.

18,622 lines 1.56 MB
(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.Kinto = 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){
(function (global){
"use strict";

require("core-js/es6");

require("core-js/fn/array/includes");

require("core-js/fn/string/pad-start");

require("core-js/fn/string/pad-end");

require("core-js/fn/symbol/async-iterator");

require("core-js/fn/object/get-own-property-descriptors");

require("core-js/fn/object/values");

require("core-js/fn/object/entries");

require("core-js/fn/promise/finally");

require("core-js/web");

require("regenerator-runtime/runtime");

if (global._babelPolyfill && typeof console !== "undefined" && console.warn) {
  console.warn("@babel/polyfill is loaded more than once on this page. This is probably not desirable/intended " + "and may have consequences if different versions of the polyfills are applied sequentially. " + "If you do need to load the polyfill more than once, use @babel/polyfill/noConflict " + "instead to bypass the warning.");
}

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

},{"core-js/es6":2,"core-js/fn/array/includes":3,"core-js/fn/object/entries":4,"core-js/fn/object/get-own-property-descriptors":5,"core-js/fn/object/values":6,"core-js/fn/promise/finally":7,"core-js/fn/string/pad-end":8,"core-js/fn/string/pad-start":9,"core-js/fn/symbol/async-iterator":10,"core-js/web":275,"regenerator-runtime/runtime":276}],2:[function(require,module,exports){
require('../modules/es6.symbol');
require('../modules/es6.object.create');
require('../modules/es6.object.define-property');
require('../modules/es6.object.define-properties');
require('../modules/es6.object.get-own-property-descriptor');
require('../modules/es6.object.get-prototype-of');
require('../modules/es6.object.keys');
require('../modules/es6.object.get-own-property-names');
require('../modules/es6.object.freeze');
require('../modules/es6.object.seal');
require('../modules/es6.object.prevent-extensions');
require('../modules/es6.object.is-frozen');
require('../modules/es6.object.is-sealed');
require('../modules/es6.object.is-extensible');
require('../modules/es6.object.assign');
require('../modules/es6.object.is');
require('../modules/es6.object.set-prototype-of');
require('../modules/es6.object.to-string');
require('../modules/es6.function.bind');
require('../modules/es6.function.name');
require('../modules/es6.function.has-instance');
require('../modules/es6.parse-int');
require('../modules/es6.parse-float');
require('../modules/es6.number.constructor');
require('../modules/es6.number.to-fixed');
require('../modules/es6.number.to-precision');
require('../modules/es6.number.epsilon');
require('../modules/es6.number.is-finite');
require('../modules/es6.number.is-integer');
require('../modules/es6.number.is-nan');
require('../modules/es6.number.is-safe-integer');
require('../modules/es6.number.max-safe-integer');
require('../modules/es6.number.min-safe-integer');
require('../modules/es6.number.parse-float');
require('../modules/es6.number.parse-int');
require('../modules/es6.math.acosh');
require('../modules/es6.math.asinh');
require('../modules/es6.math.atanh');
require('../modules/es6.math.cbrt');
require('../modules/es6.math.clz32');
require('../modules/es6.math.cosh');
require('../modules/es6.math.expm1');
require('../modules/es6.math.fround');
require('../modules/es6.math.hypot');
require('../modules/es6.math.imul');
require('../modules/es6.math.log10');
require('../modules/es6.math.log1p');
require('../modules/es6.math.log2');
require('../modules/es6.math.sign');
require('../modules/es6.math.sinh');
require('../modules/es6.math.tanh');
require('../modules/es6.math.trunc');
require('../modules/es6.string.from-code-point');
require('../modules/es6.string.raw');
require('../modules/es6.string.trim');
require('../modules/es6.string.iterator');
require('../modules/es6.string.code-point-at');
require('../modules/es6.string.ends-with');
require('../modules/es6.string.includes');
require('../modules/es6.string.repeat');
require('../modules/es6.string.starts-with');
require('../modules/es6.string.anchor');
require('../modules/es6.string.big');
require('../modules/es6.string.blink');
require('../modules/es6.string.bold');
require('../modules/es6.string.fixed');
require('../modules/es6.string.fontcolor');
require('../modules/es6.string.fontsize');
require('../modules/es6.string.italics');
require('../modules/es6.string.link');
require('../modules/es6.string.small');
require('../modules/es6.string.strike');
require('../modules/es6.string.sub');
require('../modules/es6.string.sup');
require('../modules/es6.date.now');
require('../modules/es6.date.to-json');
require('../modules/es6.date.to-iso-string');
require('../modules/es6.date.to-string');
require('../modules/es6.date.to-primitive');
require('../modules/es6.array.is-array');
require('../modules/es6.array.from');
require('../modules/es6.array.of');
require('../modules/es6.array.join');
require('../modules/es6.array.slice');
require('../modules/es6.array.sort');
require('../modules/es6.array.for-each');
require('../modules/es6.array.map');
require('../modules/es6.array.filter');
require('../modules/es6.array.some');
require('../modules/es6.array.every');
require('../modules/es6.array.reduce');
require('../modules/es6.array.reduce-right');
require('../modules/es6.array.index-of');
require('../modules/es6.array.last-index-of');
require('../modules/es6.array.copy-within');
require('../modules/es6.array.fill');
require('../modules/es6.array.find');
require('../modules/es6.array.find-index');
require('../modules/es6.array.species');
require('../modules/es6.array.iterator');
require('../modules/es6.regexp.constructor');
require('../modules/es6.regexp.to-string');
require('../modules/es6.regexp.flags');
require('../modules/es6.regexp.match');
require('../modules/es6.regexp.replace');
require('../modules/es6.regexp.search');
require('../modules/es6.regexp.split');
require('../modules/es6.promise');
require('../modules/es6.map');
require('../modules/es6.set');
require('../modules/es6.weak-map');
require('../modules/es6.weak-set');
require('../modules/es6.typed.array-buffer');
require('../modules/es6.typed.data-view');
require('../modules/es6.typed.int8-array');
require('../modules/es6.typed.uint8-array');
require('../modules/es6.typed.uint8-clamped-array');
require('../modules/es6.typed.int16-array');
require('../modules/es6.typed.uint16-array');
require('../modules/es6.typed.int32-array');
require('../modules/es6.typed.uint32-array');
require('../modules/es6.typed.float32-array');
require('../modules/es6.typed.float64-array');
require('../modules/es6.reflect.apply');
require('../modules/es6.reflect.construct');
require('../modules/es6.reflect.define-property');
require('../modules/es6.reflect.delete-property');
require('../modules/es6.reflect.enumerate');
require('../modules/es6.reflect.get');
require('../modules/es6.reflect.get-own-property-descriptor');
require('../modules/es6.reflect.get-prototype-of');
require('../modules/es6.reflect.has');
require('../modules/es6.reflect.is-extensible');
require('../modules/es6.reflect.own-keys');
require('../modules/es6.reflect.prevent-extensions');
require('../modules/es6.reflect.set');
require('../modules/es6.reflect.set-prototype-of');
module.exports = require('../modules/_core');

},{"../modules/_core":29,"../modules/es6.array.copy-within":127,"../modules/es6.array.every":128,"../modules/es6.array.fill":129,"../modules/es6.array.filter":130,"../modules/es6.array.find":132,"../modules/es6.array.find-index":131,"../modules/es6.array.for-each":133,"../modules/es6.array.from":134,"../modules/es6.array.index-of":135,"../modules/es6.array.is-array":136,"../modules/es6.array.iterator":137,"../modules/es6.array.join":138,"../modules/es6.array.last-index-of":139,"../modules/es6.array.map":140,"../modules/es6.array.of":141,"../modules/es6.array.reduce":143,"../modules/es6.array.reduce-right":142,"../modules/es6.array.slice":144,"../modules/es6.array.some":145,"../modules/es6.array.sort":146,"../modules/es6.array.species":147,"../modules/es6.date.now":148,"../modules/es6.date.to-iso-string":149,"../modules/es6.date.to-json":150,"../modules/es6.date.to-primitive":151,"../modules/es6.date.to-string":152,"../modules/es6.function.bind":153,"../modules/es6.function.has-instance":154,"../modules/es6.function.name":155,"../modules/es6.map":156,"../modules/es6.math.acosh":157,"../modules/es6.math.asinh":158,"../modules/es6.math.atanh":159,"../modules/es6.math.cbrt":160,"../modules/es6.math.clz32":161,"../modules/es6.math.cosh":162,"../modules/es6.math.expm1":163,"../modules/es6.math.fround":164,"../modules/es6.math.hypot":165,"../modules/es6.math.imul":166,"../modules/es6.math.log10":167,"../modules/es6.math.log1p":168,"../modules/es6.math.log2":169,"../modules/es6.math.sign":170,"../modules/es6.math.sinh":171,"../modules/es6.math.tanh":172,"../modules/es6.math.trunc":173,"../modules/es6.number.constructor":174,"../modules/es6.number.epsilon":175,"../modules/es6.number.is-finite":176,"../modules/es6.number.is-integer":177,"../modules/es6.number.is-nan":178,"../modules/es6.number.is-safe-integer":179,"../modules/es6.number.max-safe-integer":180,"../modules/es6.number.min-safe-integer":181,"../modules/es6.number.parse-float":182,"../modules/es6.number.parse-int":183,"../modules/es6.number.to-fixed":184,"../modules/es6.number.to-precision":185,"../modules/es6.object.assign":186,"../modules/es6.object.create":187,"../modules/es6.object.define-properties":188,"../modules/es6.object.define-property":189,"../modules/es6.object.freeze":190,"../modules/es6.object.get-own-property-descriptor":191,"../modules/es6.object.get-own-property-names":192,"../modules/es6.object.get-prototype-of":193,"../modules/es6.object.is":197,"../modules/es6.object.is-extensible":194,"../modules/es6.object.is-frozen":195,"../modules/es6.object.is-sealed":196,"../modules/es6.object.keys":198,"../modules/es6.object.prevent-extensions":199,"../modules/es6.object.seal":200,"../modules/es6.object.set-prototype-of":201,"../modules/es6.object.to-string":202,"../modules/es6.parse-float":203,"../modules/es6.parse-int":204,"../modules/es6.promise":205,"../modules/es6.reflect.apply":206,"../modules/es6.reflect.construct":207,"../modules/es6.reflect.define-property":208,"../modules/es6.reflect.delete-property":209,"../modules/es6.reflect.enumerate":210,"../modules/es6.reflect.get":213,"../modules/es6.reflect.get-own-property-descriptor":211,"../modules/es6.reflect.get-prototype-of":212,"../modules/es6.reflect.has":214,"../modules/es6.reflect.is-extensible":215,"../modules/es6.reflect.own-keys":216,"../modules/es6.reflect.prevent-extensions":217,"../modules/es6.reflect.set":219,"../modules/es6.reflect.set-prototype-of":218,"../modules/es6.regexp.constructor":220,"../modules/es6.regexp.flags":221,"../modules/es6.regexp.match":222,"../modules/es6.regexp.replace":223,"../modules/es6.regexp.search":224,"../modules/es6.regexp.split":225,"../modules/es6.regexp.to-string":226,"../modules/es6.set":227,"../modules/es6.string.anchor":228,"../modules/es6.string.big":229,"../modules/es6.string.blink":230,"../modules/es6.string.bold":231,"../modules/es6.string.code-point-at":232,"../modules/es6.string.ends-with":233,"../modules/es6.string.fixed":234,"../modules/es6.string.fontcolor":235,"../modules/es6.string.fontsize":236,"../modules/es6.string.from-code-point":237,"../modules/es6.string.includes":238,"../modules/es6.string.italics":239,"../modules/es6.string.iterator":240,"../modules/es6.string.link":241,"../modules/es6.string.raw":242,"../modules/es6.string.repeat":243,"../modules/es6.string.small":244,"../modules/es6.string.starts-with":245,"../modules/es6.string.strike":246,"../modules/es6.string.sub":247,"../modules/es6.string.sup":248,"../modules/es6.string.trim":249,"../modules/es6.symbol":250,"../modules/es6.typed.array-buffer":251,"../modules/es6.typed.data-view":252,"../modules/es6.typed.float32-array":253,"../modules/es6.typed.float64-array":254,"../modules/es6.typed.int16-array":255,"../modules/es6.typed.int32-array":256,"../modules/es6.typed.int8-array":257,"../modules/es6.typed.uint16-array":258,"../modules/es6.typed.uint32-array":259,"../modules/es6.typed.uint8-array":260,"../modules/es6.typed.uint8-clamped-array":261,"../modules/es6.weak-map":262,"../modules/es6.weak-set":263}],3:[function(require,module,exports){
require('../../modules/es7.array.includes');
module.exports = require('../../modules/_core').Array.includes;

},{"../../modules/_core":29,"../../modules/es7.array.includes":264}],4:[function(require,module,exports){
require('../../modules/es7.object.entries');
module.exports = require('../../modules/_core').Object.entries;

},{"../../modules/_core":29,"../../modules/es7.object.entries":265}],5:[function(require,module,exports){
require('../../modules/es7.object.get-own-property-descriptors');
module.exports = require('../../modules/_core').Object.getOwnPropertyDescriptors;

},{"../../modules/_core":29,"../../modules/es7.object.get-own-property-descriptors":266}],6:[function(require,module,exports){
require('../../modules/es7.object.values');
module.exports = require('../../modules/_core').Object.values;

},{"../../modules/_core":29,"../../modules/es7.object.values":267}],7:[function(require,module,exports){
'use strict';
require('../../modules/es6.promise');
require('../../modules/es7.promise.finally');
module.exports = require('../../modules/_core').Promise['finally'];

},{"../../modules/_core":29,"../../modules/es6.promise":205,"../../modules/es7.promise.finally":268}],8:[function(require,module,exports){
require('../../modules/es7.string.pad-end');
module.exports = require('../../modules/_core').String.padEnd;

},{"../../modules/_core":29,"../../modules/es7.string.pad-end":269}],9:[function(require,module,exports){
require('../../modules/es7.string.pad-start');
module.exports = require('../../modules/_core').String.padStart;

},{"../../modules/_core":29,"../../modules/es7.string.pad-start":270}],10:[function(require,module,exports){
require('../../modules/es7.symbol.async-iterator');
module.exports = require('../../modules/_wks-ext').f('asyncIterator');

},{"../../modules/_wks-ext":124,"../../modules/es7.symbol.async-iterator":271}],11:[function(require,module,exports){
module.exports = function (it) {
  if (typeof it != 'function') throw TypeError(it + ' is not a function!');
  return it;
};

},{}],12:[function(require,module,exports){
var cof = require('./_cof');
module.exports = function (it, msg) {
  if (typeof it != 'number' && cof(it) != 'Number') throw TypeError(msg);
  return +it;
};

},{"./_cof":25}],13:[function(require,module,exports){
// 22.1.3.31 Array.prototype[@@unscopables]
var UNSCOPABLES = require('./_wks')('unscopables');
var ArrayProto = Array.prototype;
if (ArrayProto[UNSCOPABLES] == undefined) require('./_hide')(ArrayProto, UNSCOPABLES, {});
module.exports = function (key) {
  ArrayProto[UNSCOPABLES][key] = true;
};

},{"./_hide":47,"./_wks":125}],14:[function(require,module,exports){
module.exports = function (it, Constructor, name, forbiddenField) {
  if (!(it instanceof Constructor) || (forbiddenField !== undefined && forbiddenField in it)) {
    throw TypeError(name + ': incorrect invocation!');
  } return it;
};

},{}],15:[function(require,module,exports){
var isObject = require('./_is-object');
module.exports = function (it) {
  if (!isObject(it)) throw TypeError(it + ' is not an object!');
  return it;
};

},{"./_is-object":56}],16:[function(require,module,exports){
// 22.1.3.3 Array.prototype.copyWithin(target, start, end = this.length)
'use strict';
var toObject = require('./_to-object');
var toAbsoluteIndex = require('./_to-absolute-index');
var toLength = require('./_to-length');

module.exports = [].copyWithin || function copyWithin(target /* = 0 */, start /* = 0, end = @length */) {
  var O = toObject(this);
  var len = toLength(O.length);
  var to = toAbsoluteIndex(target, len);
  var from = toAbsoluteIndex(start, len);
  var end = arguments.length > 2 ? arguments[2] : undefined;
  var count = Math.min((end === undefined ? len : toAbsoluteIndex(end, len)) - from, len - to);
  var inc = 1;
  if (from < to && to < from + count) {
    inc = -1;
    from += count - 1;
    to += count - 1;
  }
  while (count-- > 0) {
    if (from in O) O[to] = O[from];
    else delete O[to];
    to += inc;
    from += inc;
  } return O;
};

},{"./_to-absolute-index":110,"./_to-length":114,"./_to-object":115}],17:[function(require,module,exports){
// 22.1.3.6 Array.prototype.fill(value, start = 0, end = this.length)
'use strict';
var toObject = require('./_to-object');
var toAbsoluteIndex = require('./_to-absolute-index');
var toLength = require('./_to-length');
module.exports = function fill(value /* , start = 0, end = @length */) {
  var O = toObject(this);
  var length = toLength(O.length);
  var aLen = arguments.length;
  var index = toAbsoluteIndex(aLen > 1 ? arguments[1] : undefined, length);
  var end = aLen > 2 ? arguments[2] : undefined;
  var endPos = end === undefined ? length : toAbsoluteIndex(end, length);
  while (endPos > index) O[index++] = value;
  return O;
};

},{"./_to-absolute-index":110,"./_to-length":114,"./_to-object":115}],18:[function(require,module,exports){
// false -> Array#indexOf
// true  -> Array#includes
var toIObject = require('./_to-iobject');
var toLength = require('./_to-length');
var toAbsoluteIndex = require('./_to-absolute-index');
module.exports = function (IS_INCLUDES) {
  return function ($this, el, fromIndex) {
    var O = toIObject($this);
    var length = toLength(O.length);
    var index = toAbsoluteIndex(fromIndex, length);
    var value;
    // Array#includes uses SameValueZero equality algorithm
    // eslint-disable-next-line no-self-compare
    if (IS_INCLUDES && el != el) while (length > index) {
      value = O[index++];
      // eslint-disable-next-line no-self-compare
      if (value != value) return true;
    // Array#indexOf ignores holes, Array#includes - not
    } else for (;length > index; index++) if (IS_INCLUDES || index in O) {
      if (O[index] === el) return IS_INCLUDES || index || 0;
    } return !IS_INCLUDES && -1;
  };
};

},{"./_to-absolute-index":110,"./_to-iobject":113,"./_to-length":114}],19:[function(require,module,exports){
// 0 -> Array#forEach
// 1 -> Array#map
// 2 -> Array#filter
// 3 -> Array#some
// 4 -> Array#every
// 5 -> Array#find
// 6 -> Array#findIndex
var ctx = require('./_ctx');
var IObject = require('./_iobject');
var toObject = require('./_to-object');
var toLength = require('./_to-length');
var asc = require('./_array-species-create');
module.exports = function (TYPE, $create) {
  var IS_MAP = TYPE == 1;
  var IS_FILTER = TYPE == 2;
  var IS_SOME = TYPE == 3;
  var IS_EVERY = TYPE == 4;
  var IS_FIND_INDEX = TYPE == 6;
  var NO_HOLES = TYPE == 5 || IS_FIND_INDEX;
  var create = $create || asc;
  return function ($this, callbackfn, that) {
    var O = toObject($this);
    var self = IObject(O);
    var f = ctx(callbackfn, that, 3);
    var length = toLength(self.length);
    var index = 0;
    var result = IS_MAP ? create($this, length) : IS_FILTER ? create($this, 0) : undefined;
    var val, res;
    for (;length > index; index++) if (NO_HOLES || index in self) {
      val = self[index];
      res = f(val, index, O);
      if (TYPE) {
        if (IS_MAP) result[index] = res;   // map
        else if (res) switch (TYPE) {
          case 3: return true;             // some
          case 5: return val;              // find
          case 6: return index;            // findIndex
          case 2: result.push(val);        // filter
        } else if (IS_EVERY) return false; // every
      }
    }
    return IS_FIND_INDEX ? -1 : IS_SOME || IS_EVERY ? IS_EVERY : result;
  };
};

},{"./_array-species-create":22,"./_ctx":31,"./_iobject":52,"./_to-length":114,"./_to-object":115}],20:[function(require,module,exports){
var aFunction = require('./_a-function');
var toObject = require('./_to-object');
var IObject = require('./_iobject');
var toLength = require('./_to-length');

module.exports = function (that, callbackfn, aLen, memo, isRight) {
  aFunction(callbackfn);
  var O = toObject(that);
  var self = IObject(O);
  var length = toLength(O.length);
  var index = isRight ? length - 1 : 0;
  var i = isRight ? -1 : 1;
  if (aLen < 2) for (;;) {
    if (index in self) {
      memo = self[index];
      index += i;
      break;
    }
    index += i;
    if (isRight ? index < 0 : length <= index) {
      throw TypeError('Reduce of empty array with no initial value');
    }
  }
  for (;isRight ? index >= 0 : length > index; index += i) if (index in self) {
    memo = callbackfn(memo, self[index], index, O);
  }
  return memo;
};

},{"./_a-function":11,"./_iobject":52,"./_to-length":114,"./_to-object":115}],21:[function(require,module,exports){
var isObject = require('./_is-object');
var isArray = require('./_is-array');
var SPECIES = require('./_wks')('species');

module.exports = function (original) {
  var C;
  if (isArray(original)) {
    C = original.constructor;
    // cross-realm fallback
    if (typeof C == 'function' && (C === Array || isArray(C.prototype))) C = undefined;
    if (isObject(C)) {
      C = C[SPECIES];
      if (C === null) C = undefined;
    }
  } return C === undefined ? Array : C;
};

},{"./_is-array":54,"./_is-object":56,"./_wks":125}],22:[function(require,module,exports){
// 9.4.2.3 ArraySpeciesCreate(originalArray, length)
var speciesConstructor = require('./_array-species-constructor');

module.exports = function (original, length) {
  return new (speciesConstructor(original))(length);
};

},{"./_array-species-constructor":21}],23:[function(require,module,exports){
'use strict';
var aFunction = require('./_a-function');
var isObject = require('./_is-object');
var invoke = require('./_invoke');
var arraySlice = [].slice;
var factories = {};

var construct = function (F, len, args) {
  if (!(len in factories)) {
    for (var n = [], i = 0; i < len; i++) n[i] = 'a[' + i + ']';
    // eslint-disable-next-line no-new-func
    factories[len] = Function('F,a', 'return new F(' + n.join(',') + ')');
  } return factories[len](F, args);
};

module.exports = Function.bind || function bind(that /* , ...args */) {
  var fn = aFunction(this);
  var partArgs = arraySlice.call(arguments, 1);
  var bound = function (/* args... */) {
    var args = partArgs.concat(arraySlice.call(arguments));
    return this instanceof bound ? construct(fn, args.length, args) : invoke(fn, args, that);
  };
  if (isObject(fn.prototype)) bound.prototype = fn.prototype;
  return bound;
};

},{"./_a-function":11,"./_invoke":51,"./_is-object":56}],24:[function(require,module,exports){
// getting tag from 19.1.3.6 Object.prototype.toString()
var cof = require('./_cof');
var TAG = require('./_wks')('toStringTag');
// ES3 wrong here
var ARG = cof(function () { return arguments; }()) == 'Arguments';

// fallback for IE11 Script Access Denied error
var tryGet = function (it, key) {
  try {
    return it[key];
  } catch (e) { /* empty */ }
};

module.exports = function (it) {
  var O, T, B;
  return it === undefined ? 'Undefined' : it === null ? 'Null'
    // @@toStringTag case
    : typeof (T = tryGet(O = Object(it), TAG)) == 'string' ? T
    // builtinTag case
    : ARG ? cof(O)
    // ES3 arguments fallback
    : (B = cof(O)) == 'Object' && typeof O.callee == 'function' ? 'Arguments' : B;
};

},{"./_cof":25,"./_wks":125}],25:[function(require,module,exports){
var toString = {}.toString;

module.exports = function (it) {
  return toString.call(it).slice(8, -1);
};

},{}],26:[function(require,module,exports){
'use strict';
var dP = require('./_object-dp').f;
var create = require('./_object-create');
var redefineAll = require('./_redefine-all');
var ctx = require('./_ctx');
var anInstance = require('./_an-instance');
var forOf = require('./_for-of');
var $iterDefine = require('./_iter-define');
var step = require('./_iter-step');
var setSpecies = require('./_set-species');
var DESCRIPTORS = require('./_descriptors');
var fastKey = require('./_meta').fastKey;
var validate = require('./_validate-collection');
var SIZE = DESCRIPTORS ? '_s' : 'size';

var getEntry = function (that, key) {
  // fast case
  var index = fastKey(key);
  var entry;
  if (index !== 'F') return that._i[index];
  // frozen object case
  for (entry = that._f; entry; entry = entry.n) {
    if (entry.k == key) return entry;
  }
};

module.exports = {
  getConstructor: function (wrapper, NAME, IS_MAP, ADDER) {
    var C = wrapper(function (that, iterable) {
      anInstance(that, C, NAME, '_i');
      that._t = NAME;         // collection type
      that._i = create(null); // index
      that._f = undefined;    // first entry
      that._l = undefined;    // last entry
      that[SIZE] = 0;         // size
      if (iterable != undefined) forOf(iterable, IS_MAP, that[ADDER], that);
    });
    redefineAll(C.prototype, {
      // 23.1.3.1 Map.prototype.clear()
      // 23.2.3.2 Set.prototype.clear()
      clear: function clear() {
        for (var that = validate(this, NAME), data = that._i, entry = that._f; entry; entry = entry.n) {
          entry.r = true;
          if (entry.p) entry.p = entry.p.n = undefined;
          delete data[entry.i];
        }
        that._f = that._l = undefined;
        that[SIZE] = 0;
      },
      // 23.1.3.3 Map.prototype.delete(key)
      // 23.2.3.4 Set.prototype.delete(value)
      'delete': function (key) {
        var that = validate(this, NAME);
        var entry = getEntry(that, key);
        if (entry) {
          var next = entry.n;
          var prev = entry.p;
          delete that._i[entry.i];
          entry.r = true;
          if (prev) prev.n = next;
          if (next) next.p = prev;
          if (that._f == entry) that._f = next;
          if (that._l == entry) that._l = prev;
          that[SIZE]--;
        } return !!entry;
      },
      // 23.2.3.6 Set.prototype.forEach(callbackfn, thisArg = undefined)
      // 23.1.3.5 Map.prototype.forEach(callbackfn, thisArg = undefined)
      forEach: function forEach(callbackfn /* , that = undefined */) {
        validate(this, NAME);
        var f = ctx(callbackfn, arguments.length > 1 ? arguments[1] : undefined, 3);
        var entry;
        while (entry = entry ? entry.n : this._f) {
          f(entry.v, entry.k, this);
          // revert to the last existing entry
          while (entry && entry.r) entry = entry.p;
        }
      },
      // 23.1.3.7 Map.prototype.has(key)
      // 23.2.3.7 Set.prototype.has(value)
      has: function has(key) {
        return !!getEntry(validate(this, NAME), key);
      }
    });
    if (DESCRIPTORS) dP(C.prototype, 'size', {
      get: function () {
        return validate(this, NAME)[SIZE];
      }
    });
    return C;
  },
  def: function (that, key, value) {
    var entry = getEntry(that, key);
    var prev, index;
    // change existing entry
    if (entry) {
      entry.v = value;
    // create new entry
    } else {
      that._l = entry = {
        i: index = fastKey(key, true), // <- index
        k: key,                        // <- key
        v: value,                      // <- value
        p: prev = that._l,             // <- previous entry
        n: undefined,                  // <- next entry
        r: false                       // <- removed
      };
      if (!that._f) that._f = entry;
      if (prev) prev.n = entry;
      that[SIZE]++;
      // add to index
      if (index !== 'F') that._i[index] = entry;
    } return that;
  },
  getEntry: getEntry,
  setStrong: function (C, NAME, IS_MAP) {
    // add .keys, .values, .entries, [@@iterator]
    // 23.1.3.4, 23.1.3.8, 23.1.3.11, 23.1.3.12, 23.2.3.5, 23.2.3.8, 23.2.3.10, 23.2.3.11
    $iterDefine(C, NAME, function (iterated, kind) {
      this._t = validate(iterated, NAME); // target
      this._k = kind;                     // kind
      this._l = undefined;                // previous
    }, function () {
      var that = this;
      var kind = that._k;
      var entry = that._l;
      // revert to the last existing entry
      while (entry && entry.r) entry = entry.p;
      // get next entry
      if (!that._t || !(that._l = entry = entry ? entry.n : that._t._f)) {
        // or finish the iteration
        that._t = undefined;
        return step(1);
      }
      // return step by kind
      if (kind == 'keys') return step(0, entry.k);
      if (kind == 'values') return step(0, entry.v);
      return step(0, [entry.k, entry.v]);
    }, IS_MAP ? 'entries' : 'values', !IS_MAP, true);

    // add [@@species], 23.1.2.2, 23.2.2.2
    setSpecies(NAME);
  }
};

},{"./_an-instance":14,"./_ctx":31,"./_descriptors":35,"./_for-of":44,"./_iter-define":60,"./_iter-step":62,"./_meta":69,"./_object-create":73,"./_object-dp":74,"./_redefine-all":92,"./_set-species":96,"./_validate-collection":122}],27:[function(require,module,exports){
'use strict';
var redefineAll = require('./_redefine-all');
var getWeak = require('./_meta').getWeak;
var anObject = require('./_an-object');
var isObject = require('./_is-object');
var anInstance = require('./_an-instance');
var forOf = require('./_for-of');
var createArrayMethod = require('./_array-methods');
var $has = require('./_has');
var validate = require('./_validate-collection');
var arrayFind = createArrayMethod(5);
var arrayFindIndex = createArrayMethod(6);
var id = 0;

// fallback for uncaught frozen keys
var uncaughtFrozenStore = function (that) {
  return that._l || (that._l = new UncaughtFrozenStore());
};
var UncaughtFrozenStore = function () {
  this.a = [];
};
var findUncaughtFrozen = function (store, key) {
  return arrayFind(store.a, function (it) {
    return it[0] === key;
  });
};
UncaughtFrozenStore.prototype = {
  get: function (key) {
    var entry = findUncaughtFrozen(this, key);
    if (entry) return entry[1];
  },
  has: function (key) {
    return !!findUncaughtFrozen(this, key);
  },
  set: function (key, value) {
    var entry = findUncaughtFrozen(this, key);
    if (entry) entry[1] = value;
    else this.a.push([key, value]);
  },
  'delete': function (key) {
    var index = arrayFindIndex(this.a, function (it) {
      return it[0] === key;
    });
    if (~index) this.a.splice(index, 1);
    return !!~index;
  }
};

module.exports = {
  getConstructor: function (wrapper, NAME, IS_MAP, ADDER) {
    var C = wrapper(function (that, iterable) {
      anInstance(that, C, NAME, '_i');
      that._t = NAME;      // collection type
      that._i = id++;      // collection id
      that._l = undefined; // leak store for uncaught frozen objects
      if (iterable != undefined) forOf(iterable, IS_MAP, that[ADDER], that);
    });
    redefineAll(C.prototype, {
      // 23.3.3.2 WeakMap.prototype.delete(key)
      // 23.4.3.3 WeakSet.prototype.delete(value)
      'delete': function (key) {
        if (!isObject(key)) return false;
        var data = getWeak(key);
        if (data === true) return uncaughtFrozenStore(validate(this, NAME))['delete'](key);
        return data && $has(data, this._i) && delete data[this._i];
      },
      // 23.3.3.4 WeakMap.prototype.has(key)
      // 23.4.3.4 WeakSet.prototype.has(value)
      has: function has(key) {
        if (!isObject(key)) return false;
        var data = getWeak(key);
        if (data === true) return uncaughtFrozenStore(validate(this, NAME)).has(key);
        return data && $has(data, this._i);
      }
    });
    return C;
  },
  def: function (that, key, value) {
    var data = getWeak(anObject(key), true);
    if (data === true) uncaughtFrozenStore(that).set(key, value);
    else data[that._i] = value;
    return that;
  },
  ufstore: uncaughtFrozenStore
};

},{"./_an-instance":14,"./_an-object":15,"./_array-methods":19,"./_for-of":44,"./_has":46,"./_is-object":56,"./_meta":69,"./_redefine-all":92,"./_validate-collection":122}],28:[function(require,module,exports){
'use strict';
var global = require('./_global');
var $export = require('./_export');
var redefine = require('./_redefine');
var redefineAll = require('./_redefine-all');
var meta = require('./_meta');
var forOf = require('./_for-of');
var anInstance = require('./_an-instance');
var isObject = require('./_is-object');
var fails = require('./_fails');
var $iterDetect = require('./_iter-detect');
var setToStringTag = require('./_set-to-string-tag');
var inheritIfRequired = require('./_inherit-if-required');

module.exports = function (NAME, wrapper, methods, common, IS_MAP, IS_WEAK) {
  var Base = global[NAME];
  var C = Base;
  var ADDER = IS_MAP ? 'set' : 'add';
  var proto = C && C.prototype;
  var O = {};
  var fixMethod = function (KEY) {
    var fn = proto[KEY];
    redefine(proto, KEY,
      KEY == 'delete' ? function (a) {
        return IS_WEAK && !isObject(a) ? false : fn.call(this, a === 0 ? 0 : a);
      } : KEY == 'has' ? function has(a) {
        return IS_WEAK && !isObject(a) ? false : fn.call(this, a === 0 ? 0 : a);
      } : KEY == 'get' ? function get(a) {
        return IS_WEAK && !isObject(a) ? undefined : fn.call(this, a === 0 ? 0 : a);
      } : KEY == 'add' ? function add(a) { fn.call(this, a === 0 ? 0 : a); return this; }
        : function set(a, b) { fn.call(this, a === 0 ? 0 : a, b); return this; }
    );
  };
  if (typeof C != 'function' || !(IS_WEAK || proto.forEach && !fails(function () {
    new C().entries().next();
  }))) {
    // create collection constructor
    C = common.getConstructor(wrapper, NAME, IS_MAP, ADDER);
    redefineAll(C.prototype, methods);
    meta.NEED = true;
  } else {
    var instance = new C();
    // early implementations not supports chaining
    var HASNT_CHAINING = instance[ADDER](IS_WEAK ? {} : -0, 1) != instance;
    // V8 ~  Chromium 40- weak-collections throws on primitives, but should return false
    var THROWS_ON_PRIMITIVES = fails(function () { instance.has(1); });
    // most early implementations doesn't supports iterables, most modern - not close it correctly
    var ACCEPT_ITERABLES = $iterDetect(function (iter) { new C(iter); }); // eslint-disable-line no-new
    // for early implementations -0 and +0 not the same
    var BUGGY_ZERO = !IS_WEAK && fails(function () {
      // V8 ~ Chromium 42- fails only with 5+ elements
      var $instance = new C();
      var index = 5;
      while (index--) $instance[ADDER](index, index);
      return !$instance.has(-0);
    });
    if (!ACCEPT_ITERABLES) {
      C = wrapper(function (target, iterable) {
        anInstance(target, C, NAME);
        var that = inheritIfRequired(new Base(), target, C);
        if (iterable != undefined) forOf(iterable, IS_MAP, that[ADDER], that);
        return that;
      });
      C.prototype = proto;
      proto.constructor = C;
    }
    if (THROWS_ON_PRIMITIVES || BUGGY_ZERO) {
      fixMethod('delete');
      fixMethod('has');
      IS_MAP && fixMethod('get');
    }
    if (BUGGY_ZERO || HASNT_CHAINING) fixMethod(ADDER);
    // weak collections should not contains .clear method
    if (IS_WEAK && proto.clear) delete proto.clear;
  }

  setToStringTag(C, NAME);

  O[NAME] = C;
  $export($export.G + $export.W + $export.F * (C != Base), O);

  if (!IS_WEAK) common.setStrong(C, NAME, IS_MAP);

  return C;
};

},{"./_an-instance":14,"./_export":39,"./_fails":41,"./_for-of":44,"./_global":45,"./_inherit-if-required":50,"./_is-object":56,"./_iter-detect":61,"./_meta":69,"./_redefine":93,"./_redefine-all":92,"./_set-to-string-tag":97}],29:[function(require,module,exports){
var core = module.exports = { version: '2.5.7' };
if (typeof __e == 'number') __e = core; // eslint-disable-line no-undef

},{}],30:[function(require,module,exports){
'use strict';
var $defineProperty = require('./_object-dp');
var createDesc = require('./_property-desc');

module.exports = function (object, index, value) {
  if (index in object) $defineProperty.f(object, index, createDesc(0, value));
  else object[index] = value;
};

},{"./_object-dp":74,"./_property-desc":91}],31:[function(require,module,exports){
// optional / simple context binding
var aFunction = require('./_a-function');
module.exports = function (fn, that, length) {
  aFunction(fn);
  if (that === undefined) return fn;
  switch (length) {
    case 1: return function (a) {
      return fn.call(that, a);
    };
    case 2: return function (a, b) {
      return fn.call(that, a, b);
    };
    case 3: return function (a, b, c) {
      return fn.call(that, a, b, c);
    };
  }
  return function (/* ...args */) {
    return fn.apply(that, arguments);
  };
};

},{"./_a-function":11}],32:[function(require,module,exports){
'use strict';
// 20.3.4.36 / 15.9.5.43 Date.prototype.toISOString()
var fails = require('./_fails');
var getTime = Date.prototype.getTime;
var $toISOString = Date.prototype.toISOString;

var lz = function (num) {
  return num > 9 ? num : '0' + num;
};

// PhantomJS / old WebKit has a broken implementations
module.exports = (fails(function () {
  return $toISOString.call(new Date(-5e13 - 1)) != '0385-07-25T07:06:39.999Z';
}) || !fails(function () {
  $toISOString.call(new Date(NaN));
})) ? function toISOString() {
  if (!isFinite(getTime.call(this))) throw RangeError('Invalid time value');
  var d = this;
  var y = d.getUTCFullYear();
  var m = d.getUTCMilliseconds();
  var s = y < 0 ? '-' : y > 9999 ? '+' : '';
  return s + ('00000' + Math.abs(y)).slice(s ? -6 : -4) +
    '-' + lz(d.getUTCMonth() + 1) + '-' + lz(d.getUTCDate()) +
    'T' + lz(d.getUTCHours()) + ':' + lz(d.getUTCMinutes()) +
    ':' + lz(d.getUTCSeconds()) + '.' + (m > 99 ? m : '0' + lz(m)) + 'Z';
} : $toISOString;

},{"./_fails":41}],33:[function(require,module,exports){
'use strict';
var anObject = require('./_an-object');
var toPrimitive = require('./_to-primitive');
var NUMBER = 'number';

module.exports = function (hint) {
  if (hint !== 'string' && hint !== NUMBER && hint !== 'default') throw TypeError('Incorrect hint');
  return toPrimitive(anObject(this), hint != NUMBER);
};

},{"./_an-object":15,"./_to-primitive":116}],34:[function(require,module,exports){
// 7.2.1 RequireObjectCoercible(argument)
module.exports = function (it) {
  if (it == undefined) throw TypeError("Can't call method on  " + it);
  return it;
};

},{}],35:[function(require,module,exports){
// Thank's IE8 for his funny defineProperty
module.exports = !require('./_fails')(function () {
  return Object.defineProperty({}, 'a', { get: function () { return 7; } }).a != 7;
});

},{"./_fails":41}],36:[function(require,module,exports){
var isObject = require('./_is-object');
var document = require('./_global').document;
// typeof document.createElement is 'object' in old IE
var is = isObject(document) && isObject(document.createElement);
module.exports = function (it) {
  return is ? document.createElement(it) : {};
};

},{"./_global":45,"./_is-object":56}],37:[function(require,module,exports){
// IE 8- don't enum bug keys
module.exports = (
  'constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf'
).split(',');

},{}],38:[function(require,module,exports){
// all enumerable object keys, includes symbols
var getKeys = require('./_object-keys');
var gOPS = require('./_object-gops');
var pIE = require('./_object-pie');
module.exports = function (it) {
  var result = getKeys(it);
  var getSymbols = gOPS.f;
  if (getSymbols) {
    var symbols = getSymbols(it);
    var isEnum = pIE.f;
    var i = 0;
    var key;
    while (symbols.length > i) if (isEnum.call(it, key = symbols[i++])) result.push(key);
  } return result;
};

},{"./_object-gops":79,"./_object-keys":82,"./_object-pie":83}],39:[function(require,module,exports){
var global = require('./_global');
var core = require('./_core');
var hide = require('./_hide');
var redefine = require('./_redefine');
var ctx = require('./_ctx');
var PROTOTYPE = 'prototype';

var $export = function (type, name, source) {
  var IS_FORCED = type & $export.F;
  var IS_GLOBAL = type & $export.G;
  var IS_STATIC = type & $export.S;
  var IS_PROTO = type & $export.P;
  var IS_BIND = type & $export.B;
  var target = IS_GLOBAL ? global : IS_STATIC ? global[name] || (global[name] = {}) : (global[name] || {})[PROTOTYPE];
  var exports = IS_GLOBAL ? core : core[name] || (core[name] = {});
  var expProto = exports[PROTOTYPE] || (exports[PROTOTYPE] = {});
  var key, own, out, exp;
  if (IS_GLOBAL) source = name;
  for (key in source) {
    // contains in native
    own = !IS_FORCED && target && target[key] !== undefined;
    // export native or passed
    out = (own ? target : source)[key];
    // bind timers to global for call from export context
    exp = IS_BIND && own ? ctx(out, global) : IS_PROTO && typeof out == 'function' ? ctx(Function.call, out) : out;
    // extend global
    if (target) redefine(target, key, out, type & $export.U);
    // export
    if (exports[key] != out) hide(exports, key, exp);
    if (IS_PROTO && expProto[key] != out) expProto[key] = out;
  }
};
global.core = core;
// type bitmap
$export.F = 1;   // forced
$export.G = 2;   // global
$export.S = 4;   // static
$export.P = 8;   // proto
$export.B = 16;  // bind
$export.W = 32;  // wrap
$export.U = 64;  // safe
$export.R = 128; // real proto method for `library`
module.exports = $export;

},{"./_core":29,"./_ctx":31,"./_global":45,"./_hide":47,"./_redefine":93}],40:[function(require,module,exports){
var MATCH = require('./_wks')('match');
module.exports = function (KEY) {
  var re = /./;
  try {
    '/./'[KEY](re);
  } catch (e) {
    try {
      re[MATCH] = false;
      return !'/./'[KEY](re);
    } catch (f) { /* empty */ }
  } return true;
};

},{"./_wks":125}],41:[function(require,module,exports){
module.exports = function (exec) {
  try {
    return !!exec();
  } catch (e) {
    return true;
  }
};

},{}],42:[function(require,module,exports){
'use strict';
var hide = require('./_hide');
var redefine = require('./_redefine');
var fails = require('./_fails');
var defined = require('./_defined');
var wks = require('./_wks');

module.exports = function (KEY, length, exec) {
  var SYMBOL = wks(KEY);
  var fns = exec(defined, SYMBOL, ''[KEY]);
  var strfn = fns[0];
  var rxfn = fns[1];
  if (fails(function () {
    var O = {};
    O[SYMBOL] = function () { return 7; };
    return ''[KEY](O) != 7;
  })) {
    redefine(String.prototype, KEY, strfn);
    hide(RegExp.prototype, SYMBOL, length == 2
      // 21.2.5.8 RegExp.prototype[@@replace](string, replaceValue)
      // 21.2.5.11 RegExp.prototype[@@split](string, limit)
      ? function (string, arg) { return rxfn.call(string, this, arg); }
      // 21.2.5.6 RegExp.prototype[@@match](string)
      // 21.2.5.9 RegExp.prototype[@@search](string)
      : function (string) { return rxfn.call(string, this); }
    );
  }
};

},{"./_defined":34,"./_fails":41,"./_hide":47,"./_redefine":93,"./_wks":125}],43:[function(require,module,exports){
'use strict';
// 21.2.5.3 get RegExp.prototype.flags
var anObject = require('./_an-object');
module.exports = function () {
  var that = anObject(this);
  var result = '';
  if (that.global) result += 'g';
  if (that.ignoreCase) result += 'i';
  if (that.multiline) result += 'm';
  if (that.unicode) result += 'u';
  if (that.sticky) result += 'y';
  return result;
};

},{"./_an-object":15}],44:[function(require,module,exports){
var ctx = require('./_ctx');
var call = require('./_iter-call');
var isArrayIter = require('./_is-array-iter');
var anObject = require('./_an-object');
var toLength = require('./_to-length');
var getIterFn = require('./core.get-iterator-method');
var BREAK = {};
var RETURN = {};
var exports = module.exports = function (iterable, entries, fn, that, ITERATOR) {
  var iterFn = ITERATOR ? function () { return iterable; } : getIterFn(iterable);
  var f = ctx(fn, that, entries ? 2 : 1);
  var index = 0;
  var length, step, iterator, result;
  if (typeof iterFn != 'function') throw TypeError(iterable + ' is not iterable!');
  // fast case for arrays with default iterator
  if (isArrayIter(iterFn)) for (length = toLength(iterable.length); length > index; index++) {
    result = entries ? f(anObject(step = iterable[index])[0], step[1]) : f(iterable[index]);
    if (result === BREAK || result === RETURN) return result;
  } else for (iterator = iterFn.call(iterable); !(step = iterator.next()).done;) {
    result = call(iterator, f, step.value, entries);
    if (result === BREAK || result === RETURN) return result;
  }
};
exports.BREAK = BREAK;
exports.RETURN = RETURN;

},{"./_an-object":15,"./_ctx":31,"./_is-array-iter":53,"./_iter-call":58,"./_to-length":114,"./core.get-iterator-method":126}],45:[function(require,module,exports){
// https://github.com/zloirock/core-js/issues/86#issuecomment-115759028
var global = module.exports = typeof window != 'undefined' && window.Math == Math
  ? window : typeof self != 'undefined' && self.Math == Math ? self
  // eslint-disable-next-line no-new-func
  : Function('return this')();
if (typeof __g == 'number') __g = global; // eslint-disable-line no-undef

},{}],46:[function(require,module,exports){
var hasOwnProperty = {}.hasOwnProperty;
module.exports = function (it, key) {
  return hasOwnProperty.call(it, key);
};

},{}],47:[function(require,module,exports){
var dP = require('./_object-dp');
var createDesc = require('./_property-desc');
module.exports = require('./_descriptors') ? function (object, key, value) {
  return dP.f(object, key, createDesc(1, value));
} : function (object, key, value) {
  object[key] = value;
  return object;
};

},{"./_descriptors":35,"./_object-dp":74,"./_property-desc":91}],48:[function(require,module,exports){
var document = require('./_global').document;
module.exports = document && document.documentElement;

},{"./_global":45}],49:[function(require,module,exports){
module.exports = !require('./_descriptors') && !require('./_fails')(function () {
  return Object.defineProperty(require('./_dom-create')('div'), 'a', { get: function () { return 7; } }).a != 7;
});

},{"./_descriptors":35,"./_dom-create":36,"./_fails":41}],50:[function(require,module,exports){
var isObject = require('./_is-object');
var setPrototypeOf = require('./_set-proto').set;
module.exports = function (that, target, C) {
  var S = target.constructor;
  var P;
  if (S !== C && typeof S == 'function' && (P = S.prototype) !== C.prototype && isObject(P) && setPrototypeOf) {
    setPrototypeOf(that, P);
  } return that;
};

},{"./_is-object":56,"./_set-proto":95}],51:[function(require,module,exports){
// fast apply, http://jsperf.lnkit.com/fast-apply/5
module.exports = function (fn, args, that) {
  var un = that === undefined;
  switch (args.length) {
    case 0: return un ? fn()
                      : fn.call(that);
    case 1: return un ? fn(args[0])
                      : fn.call(that, args[0]);
    case 2: return un ? fn(args[0], args[1])
                      : fn.call(that, args[0], args[1]);
    case 3: return un ? fn(args[0], args[1], args[2])
                      : fn.call(that, args[0], args[1], args[2]);
    case 4: return un ? fn(args[0], args[1], args[2], args[3])
                      : fn.call(that, args[0], args[1], args[2], args[3]);
  } return fn.apply(that, args);
};

},{}],52:[function(require,module,exports){
// fallback for non-array-like ES3 and non-enumerable old V8 strings
var cof = require('./_cof');
// eslint-disable-next-line no-prototype-builtins
module.exports = Object('z').propertyIsEnumerable(0) ? Object : function (it) {
  return cof(it) == 'String' ? it.split('') : Object(it);
};

},{"./_cof":25}],53:[function(require,module,exports){
// check on default Array iterator
var Iterators = require('./_iterators');
var ITERATOR = require('./_wks')('iterator');
var ArrayProto = Array.prototype;

module.exports = function (it) {
  return it !== undefined && (Iterators.Array === it || ArrayProto[ITERATOR] === it);
};

},{"./_iterators":63,"./_wks":125}],54:[function(require,module,exports){
// 7.2.2 IsArray(argument)
var cof = require('./_cof');
module.exports = Array.isArray || function isArray(arg) {
  return cof(arg) == 'Array';
};

},{"./_cof":25}],55:[function(require,module,exports){
// 20.1.2.3 Number.isInteger(number)
var isObject = require('./_is-object');
var floor = Math.floor;
module.exports = function isInteger(it) {
  return !isObject(it) && isFinite(it) && floor(it) === it;
};

},{"./_is-object":56}],56:[function(require,module,exports){
module.exports = function (it) {
  return typeof it === 'object' ? it !== null : typeof it === 'function';
};

},{}],57:[function(require,module,exports){
// 7.2.8 IsRegExp(argument)
var isObject = require('./_is-object');
var cof = require('./_cof');
var MATCH = require('./_wks')('match');
module.exports = function (it) {
  var isRegExp;
  return isObject(it) && ((isRegExp = it[MATCH]) !== undefined ? !!isRegExp : cof(it) == 'RegExp');
};

},{"./_cof":25,"./_is-object":56,"./_wks":125}],58:[function(require,module,exports){
// call something on iterator step with safe closing on error
var anObject = require('./_an-object');
module.exports = function (iterator, fn, value, entries) {
  try {
    return entries ? fn(anObject(value)[0], value[1]) : fn(value);
  // 7.4.6 IteratorClose(iterator, completion)
  } catch (e) {
    var ret = iterator['return'];
    if (ret !== undefined) anObject(ret.call(iterator));
    throw e;
  }
};

},{"./_an-object":15}],59:[function(require,module,exports){
'use strict';
var create = require('./_object-create');
var descriptor = require('./_property-desc');
var setToStringTag = require('./_set-to-string-tag');
var IteratorPrototype = {};

// 25.1.2.1.1 %IteratorPrototype%[@@iterator]()
require('./_hide')(IteratorPrototype, require('./_wks')('iterator'), function () { return this; });

module.exports = function (Constructor, NAME, next) {
  Constructor.prototype = create(IteratorPrototype, { next: descriptor(1, next) });
  setToStringTag(Constructor, NAME + ' Iterator');
};

},{"./_hide":47,"./_object-create":73,"./_property-desc":91,"./_set-to-string-tag":97,"./_wks":125}],60:[function(require,module,exports){
'use strict';
var LIBRARY = require('./_library');
var $export = require('./_export');
var redefine = require('./_redefine');
var hide = require('./_hide');
var Iterators = require('./_iterators');
var $iterCreate = require('./_iter-create');
var setToStringTag = require('./_set-to-string-tag');
var getPrototypeOf = require('./_object-gpo');
var ITERATOR = require('./_wks')('iterator');
var BUGGY = !([].keys && 'next' in [].keys()); // Safari has buggy iterators w/o `next`
var FF_ITERATOR = '@@iterator';
var KEYS = 'keys';
var VALUES = 'values';

var returnThis = function () { return this; };

module.exports = function (Base, NAME, Constructor, next, DEFAULT, IS_SET, FORCED) {
  $iterCreate(Constructor, NAME, next);
  var getMethod = function (kind) {
    if (!BUGGY && kind in proto) return proto[kind];
    switch (kind) {
      case KEYS: return function keys() { return new Constructor(this, kind); };
      case VALUES: return function values() { return new Constructor(this, kind); };
    } return function entries() { return new Constructor(this, kind); };
  };
  var TAG = NAME + ' Iterator';
  var DEF_VALUES = DEFAULT == VALUES;
  var VALUES_BUG = false;
  var proto = Base.prototype;
  var $native = proto[ITERATOR] || proto[FF_ITERATOR] || DEFAULT && proto[DEFAULT];
  var $default = $native || getMethod(DEFAULT);
  var $entries = DEFAULT ? !DEF_VALUES ? $default : getMethod('entries') : undefined;
  var $anyNative = NAME == 'Array' ? proto.entries || $native : $native;
  var methods, key, IteratorPrototype;
  // Fix native
  if ($anyNative) {
    IteratorPrototype = getPrototypeOf($anyNative.call(new Base()));
    if (IteratorPrototype !== Object.prototype && IteratorPrototype.next) {
      // Set @@toStringTag to native iterators
      setToStringTag(IteratorPrototype, TAG, true);
      // fix for some old engines
      if (!LIBRARY && typeof IteratorPrototype[ITERATOR] != 'function') hide(IteratorPrototype, ITERATOR, returnThis);
    }
  }
  // fix Array#{values, @@iterator}.name in V8 / FF
  if (DEF_VALUES && $native && $native.name !== VALUES) {
    VALUES_BUG = true;
    $default = function values() { return $native.call(this); };
  }
  // Define iterator
  if ((!LIBRARY || FORCED) && (BUGGY || VALUES_BUG || !proto[ITERATOR])) {
    hide(proto, ITERATOR, $default);
  }
  // Plug for library
  Iterators[NAME] = $default;
  Iterators[TAG] = returnThis;
  if (DEFAULT) {
    methods = {
      values: DEF_VALUES ? $default : getMethod(VALUES),
      keys: IS_SET ? $default : getMethod(KEYS),
      entries: $entries
    };
    if (FORCED) for (key in methods) {
      if (!(key in proto)) redefine(proto, key, methods[key]);
    } else $export($export.P + $export.F * (BUGGY || VALUES_BUG), NAME, methods);
  }
  return methods;
};

},{"./_export":39,"./_hide":47,"./_iter-create":59,"./_iterators":63,"./_library":64,"./_object-gpo":80,"./_redefine":93,"./_set-to-string-tag":97,"./_wks":125}],61:[function(require,module,exports){
var ITERATOR = require('./_wks')('iterator');
var SAFE_CLOSING = false;

try {
  var riter = [7][ITERATOR]();
  riter['return'] = function () { SAFE_CLOSING = true; };
  // eslint-disable-next-line no-throw-literal
  Array.from(riter, function () { throw 2; });
} catch (e) { /* empty */ }

module.exports = function (exec, skipClosing) {
  if (!skipClosing && !SAFE_CLOSING) return false;
  var safe = false;
  try {
    var arr = [7];
    var iter = arr[ITERATOR]();
    iter.next = function () { return { done: safe = true }; };
    arr[ITERATOR] = function () { return iter; };
    exec(arr);
  } catch (e) { /* empty */ }
  return safe;
};

},{"./_wks":125}],62:[function(require,module,exports){
module.exports = function (done, value) {
  return { value: value, done: !!done };
};

},{}],63:[function(require,module,exports){
module.exports = {};

},{}],64:[function(require,module,exports){
module.exports = false;

},{}],65:[function(require,module,exports){
// 20.2.2.14 Math.expm1(x)
var $expm1 = Math.expm1;
module.exports = (!$expm1
  // Old FF bug
  || $expm1(10) > 22025.465794806719 || $expm1(10) < 22025.4657948067165168
  // Tor Browser bug
  || $expm1(-2e-17) != -2e-17
) ? function expm1(x) {
  return (x = +x) == 0 ? x : x > -1e-6 && x < 1e-6 ? x + x * x / 2 : Math.exp(x) - 1;
} : $expm1;

},{}],66:[function(require,module,exports){
// 20.2.2.16 Math.fround(x)
var sign = require('./_math-sign');
var pow = Math.pow;
var EPSILON = pow(2, -52);
var EPSILON32 = pow(2, -23);
var MAX32 = pow(2, 127) * (2 - EPSILON32);
var MIN32 = pow(2, -126);

var roundTiesToEven = function (n) {
  return n + 1 / EPSILON - 1 / EPSILON;
};

module.exports = Math.fround || function fround(x) {
  var $abs = Math.abs(x);
  var $sign = sign(x);
  var a, result;
  if ($abs < MIN32) return $sign * roundTiesToEven($abs / MIN32 / EPSILON32) * MIN32 * EPSILON32;
  a = (1 + EPSILON32 / EPSILON) * $abs;
  result = a - (a - $abs);
  // eslint-disable-next-line no-self-compare
  if (result > MAX32 || result != result) return $sign * Infinity;
  return $sign * result;
};

},{"./_math-sign":68}],67:[function(require,module,exports){
// 20.2.2.20 Math.log1p(x)
module.exports = Math.log1p || function log1p(x) {
  return (x = +x) > -1e-8 && x < 1e-8 ? x - x * x / 2 : Math.log(1 + x);
};

},{}],68:[function(require,module,exports){
// 20.2.2.28 Math.sign(x)
module.exports = Math.sign || function sign(x) {
  // eslint-disable-next-line no-self-compare
  return (x = +x) == 0 || x != x ? x : x < 0 ? -1 : 1;
};

},{}],69:[function(require,module,exports){
var META = require('./_uid')('meta');
var isObject = require('./_is-object');
var has = require('./_has');
var setDesc = require('./_object-dp').f;
var id = 0;
var isExtensible = Object.isExtensible || function () {
  return true;
};
var FREEZE = !require('./_fails')(function () {
  return isExtensible(Object.preventExtensions({}));
});
var setMeta = function (it) {
  setDesc(it, META, { value: {
    i: 'O' + ++id, // object ID
    w: {}          // weak collections IDs
  } });
};
var fastKey = function (it, create) {
  // return primitive with prefix
  if (!isObject(it)) return typeof it == 'symbol' ? it : (typeof it == 'string' ? 'S' : 'P') + it;
  if (!has(it, META)) {
    // can't set metadata to uncaught frozen object
    if (!isExtensible(it)) return 'F';
    // not necessary to add metadata
    if (!create) return 'E';
    // add missing metadata
    setMeta(it);
  // return object ID
  } return it[META].i;
};
var getWeak = function (it, create) {
  if (!has(it, META)) {
    // can't set metadata to uncaught frozen object
    if (!isExtensible(it)) return true;
    // not necessary to add metadata
    if (!create) return false;
    // add missing metadata
    setMeta(it);
  // return hash weak collections IDs
  } return it[META].w;
};
// add metadata on freeze-family methods calling
var onFreeze = function (it) {
  if (FREEZE && meta.NEED && isExtensible(it) && !has(it, META)) setMeta(it);
  return it;
};
var meta = module.exports = {
  KEY: META,
  NEED: false,
  fastKey: fastKey,
  getWeak: getWeak,
  onFreeze: onFreeze
};

},{"./_fails":41,"./_has":46,"./_is-object":56,"./_object-dp":74,"./_uid":120}],70:[function(require,module,exports){
var global = require('./_global');
var macrotask = require('./_task').set;
var Observer = global.MutationObserver || global.WebKitMutationObserver;
var process = global.process;
var Promise = global.Promise;
var isNode = require('./_cof')(process) == 'process';

module.exports = function () {
  var head, last, notify;

  var flush = function () {
    var parent, fn;
    if (isNode && (parent = process.domain)) parent.exit();
    while (head) {
      fn = head.fn;
      head = head.next;
      try {
        fn();
      } catch (e) {
        if (head) notify();
        else last = undefined;
        throw e;
      }
    } last = undefined;
    if (parent) parent.enter();
  };

  // Node.js
  if (isNode) {
    notify = function () {
      process.nextTick(flush);
    };
  // browsers with MutationObserver, except iOS Safari - https://github.com/zloirock/core-js/issues/339
  } else if (Observer && !(global.navigator && global.navigator.standalone)) {
    var toggle = true;
    var node = document.createTextNode('');
    new Observer(flush).observe(node, { characterData: true }); // eslint-disable-line no-new
    notify = function () {
      node.data = toggle = !toggle;
    };
  // environments with maybe non-completely correct, but existent Promise
  } else if (Promise && Promise.resolve) {
    // Promise.resolve without an argument throws an error in LG WebOS 2
    var promise = Promise.resolve(undefined);
    notify = function () {
      promise.then(flush);
    };
  // for other environments - macrotask based on:
  // - setImmediate
  // - MessageChannel
  // - window.postMessag
  // - onreadystatechange
  // - setTimeout
  } else {
    notify = function () {
      // strange IE + webpack dev server bug - use .call(global)
      macrotask.call(global, flush);
    };
  }

  return function (fn) {
    var task = { fn: fn, next: undefined };
    if (last) last.next = task;
    if (!head) {
      head = task;
      notify();
    } last = task;
  };
};

},{"./_cof":25,"./_global":45,"./_task":109}],71:[function(require,module,exports){
'use strict';
// 25.4.1.5 NewPromiseCapability(C)
var aFunction = require('./_a-function');

function PromiseCapability(C) {
  var resolve, reject;
  this.promise = new C(function ($$resolve, $$reject) {
    if (resolve !== undefined || reject !== undefined) throw TypeError('Bad Promise constructor');
    resolve = $$resolve;
    reject = $$reject;
  });
  this.resolve = aFunction(resolve);
  this.reject = aFunction(reject);
}

module.exports.f = function (C) {
  return new PromiseCapability(C);
};

},{"./_a-function":11}],72:[function(require,module,exports){
'use strict';
// 19.1.2.1 Object.assign(target, source, ...)
var getKeys = require('./_object-keys');
var gOPS = require('./_object-gops');
var pIE = require('./_object-pie');
var toObject = require('./_to-object');
var IObject = require('./_iobject');
var $assign = Object.assign;

// should work with symbols and should have deterministic property order (V8 bug)
module.exports = !$assign || require('./_fails')(function () {
  var A = {};
  var B = {};
  // eslint-disable-next-line no-undef
  var S = Symbol();
  var K = 'abcdefghijklmnopqrst';
  A[S] = 7;
  K.split('').forEach(function (k) { B[k] = k; });
  return $assign({}, A)[S] != 7 || Object.keys($assign({}, B)).join('') != K;
}) ? function assign(target, source) { // eslint-disable-line no-unused-vars
  var T = toObject(target);
  var aLen = arguments.length;
  var index = 1;
  var getSymbols = gOPS.f;
  var isEnum = pIE.f;
  while (aLen > index) {
    var S = IObject(arguments[index++]);
    var keys = getSymbols ? getKeys(S).concat(getSymbols(S)) : getKeys(S);
    var length = keys.length;
    var j = 0;
    var key;
    while (length > j) if (isEnum.call(S, key = keys[j++])) T[key] = S[key];
  } return T;
} : $assign;

},{"./_fails":41,"./_iobject":52,"./_object-gops":79,"./_object-keys":82,"./_object-pie":83,"./_to-object":115}],73:[function(require,module,exports){
// 19.1.2.2 / 15.2.3.5 Object.create(O [, Properties])
var anObject = require('./_an-object');
var dPs = require('./_object-dps');
var enumBugKeys = require('./_enum-bug-keys');
var IE_PROTO = require('./_shared-key')('IE_PROTO');
var Empty = function () { /* empty */ };
var PROTOTYPE = 'prototype';

// Create object with fake `null` prototype: use iframe Object with cleared prototype
var createDict = function () {
  // Thrash, waste and sodomy: IE GC bug
  var iframe = require('./_dom-create')('iframe');
  var i = enumBugKeys.length;
  var lt = '<';
  var gt = '>';
  var iframeDocument;
  iframe.style.display = 'none';
  require('./_html').appendChild(iframe);
  iframe.src = 'javascript:'; // eslint-disable-line no-script-url
  // createDict = iframe.contentWindow.Object;
  // html.removeChild(iframe);
  iframeDocument = iframe.contentWindow.document;
  iframeDocument.open();
  iframeDocument.write(lt + 'script' + gt + 'document.F=Object' + lt + '/script' + gt);
  iframeDocument.close();
  createDict = iframeDocument.F;
  while (i--) delete createDict[PROTOTYPE][enumBugKeys[i]];
  return createDict();
};

module.exports = Object.create || function create(O, Properties) {
  var result;
  if (O !== null) {
    Empty[PROTOTYPE] = anObject(O);
    result = new Empty();
    Empty[PROTOTYPE] = null;
    // add "__proto__" for Object.getPrototypeOf polyfill
    result[IE_PROTO] = O;
  } else result = createDict();
  return Properties === undefined ? result : dPs(result, Properties);
};

},{"./_an-object":15,"./_dom-create":36,"./_enum-bug-keys":37,"./_html":48,"./_object-dps":75,"./_shared-key":98}],74:[function(require,module,exports){
var anObject = require('./_an-object');
var IE8_DOM_DEFINE = require('./_ie8-dom-define');
var toPrimitive = require('./_to-primitive');
var dP = Object.defineProperty;

exports.f = require('./_descriptors') ? Object.defineProperty : function defineProperty(O, P, Attributes) {
  anObject(O);
  P = toPrimitive(P, true);
  anObject(Attributes);
  if (IE8_DOM_DEFINE) try {
    return dP(O, P, Attributes);
  } catch (e) { /* empty */ }
  if ('get' in Attributes || 'set' in Attributes) throw TypeError('Accessors not supported!');
  if ('value' in Attributes) O[P] = Attributes.value;
  return O;
};

},{"./_an-object":15,"./_descriptors":35,"./_ie8-dom-define":49,"./_to-primitive":116}],75:[function(require,module,exports){
var dP = require('./_object-dp');
var anObject = require('./_an-object');
var getKeys = require('./_object-keys');

module.exports = require('./_descriptors') ? Object.defineProperties : function defineProperties(O, Properties) {
  anObject(O);
  var keys = getKeys(Properties);
  var length = keys.length;
  var i = 0;
  var P;
  while (length > i) dP.f(O, P = keys[i++], Properties[P]);
  return O;
};

},{"./_an-object":15,"./_descriptors":35,"./_object-dp":74,"./_object-keys":82}],76:[function(require,module,exports){
var pIE = require('./_object-pie');
var createDesc = require('./_property-desc');
var toIObject = require('./_to-iobject');
var toPrimitive = require('./_to-primitive');
var has = require('./_has');
var IE8_DOM_DEFINE = require('./_ie8-dom-define');
var gOPD = Object.getOwnPropertyDescriptor;

exports.f = require('./_descriptors') ? gOPD : function getOwnPropertyDescriptor(O, P) {
  O = toIObject(O);
  P = toPrimitive(P, true);
  if (IE8_DOM_DEFINE) try {
    return gOPD(O, P);
  } catch (e) { /* empty */ }
  if (has(O, P)) return createDesc(!pIE.f.call(O, P), O[P]);
};

},{"./_descriptors":35,"./_has":46,"./_ie8-dom-define":49,"./_object-pie":83,"./_property-desc":91,"./_to-iobject":113,"./_to-primitive":116}],77:[function(require,module,exports){
// fallback for IE11 buggy Object.getOwnPropertyNames with iframe and window
var toIObject = require('./_to-iobject');
var gOPN = require('./_object-gopn').f;
var toString = {}.toString;

var windowNames = typeof window == 'object' && window && Object.getOwnPropertyNames
  ? Object.getOwnPropertyNames(window) : [];

var getWindowNames = function (it) {
  try {
    return gOPN(it);
  } catch (e) {
    return windowNames.slice();
  }
};

module.exports.f = function getOwnPropertyNames(it) {
  return windowNames && toString.call(it) == '[object Window]' ? getWindowNames(it) : gOPN(toIObject(it));
};

},{"./_object-gopn":78,"./_to-iobject":113}],78:[function(require,module,exports){
// 19.1.2.7 / 15.2.3.4 Object.getOwnPropertyNames(O)
var $keys = require('./_object-keys-internal');
var hiddenKeys = require('./_enum-bug-keys').concat('length', 'prototype');

exports.f = Object.getOwnPropertyNames || function getOwnPropertyNames(O) {
  return $keys(O, hiddenKeys);
};

},{"./_enum-bug-keys":37,"./_object-keys-internal":81}],79:[function(require,module,exports){
exports.f = Object.getOwnPropertySymbols;

},{}],80:[function(require,module,exports){
// 19.1.2.9 / 15.2.3.2 Object.getPrototypeOf(O)
var has = require('./_has');
var toObject = require('./_to-object');
var IE_PROTO = require('./_shared-key')('IE_PROTO');
var ObjectProto = Object.prototype;

module.exports = Object.getPrototypeOf || function (O) {
  O = toObject(O);
  if (has(O, IE_PROTO)) return O[IE_PROTO];
  if (typeof O.constructor == 'function' && O instanceof O.constructor) {
    return O.constructor.prototype;
  } return O instanceof Object ? ObjectProto : null;
};

},{"./_has":46,"./_shared-key":98,"./_to-object":115}],81:[function(require,module,exports){
var has = require('./_has');
var toIObject = require('./_to-iobject');
var arrayIndexOf = require('./_array-includes')(false);
var IE_PROTO = require('./_shared-key')('IE_PROTO');

module.exports = function (object, names) {
  var O = toIObject(object);
  var i = 0;
  var result = [];
  var key;
  for (key in O) if (key != IE_PROTO) has(O, key) && result.push(key);
  // Don't enum bug & hidden keys
  while (names.length > i) if (has(O, key = names[i++])) {
    ~arrayIndexOf(result, key) || result.push(key);
  }
  return result;
};

},{"./_array-includes":18,"./_has":46,"./_shared-key":98,"./_to-iobject":113}],82:[function(require,module,exports){
// 19.1.2.14 / 15.2.3.14 Object.keys(O)
var $keys = require('./_object-keys-internal');
var enumBugKeys = require('./_enum-bug-keys');

module.exports = Object.keys || function keys(O) {
  return $keys(O, enumBugKeys);
};

},{"./_enum-bug-keys":37,"./_object-keys-internal":81}],83:[function(require,module,exports){
exports.f = {}.propertyIsEnumerable;

},{}],84:[function(require,module,exports){
// most Object methods by ES6 should accept primitives
var $export = require('./_export');
var core = require('./_core');
var fails = require('./_fails');
module.exports = function (KEY, exec) {
  var fn = (core.Object || {})[KEY] || Object[KEY];
  var exp = {};
  exp[KEY] = exec(fn);
  $export($export.S + $export.F * fails(function () { fn(1); }), 'Object', exp);
};

},{"./_core":29,"./_export":39,"./_fails":41}],85:[function(require,module,exports){
var getKeys = require('./_object-keys');
var toIObject = require('./_to-iobject');
var isEnum = require('./_object-pie').f;
module.exports = function (isEntries) {
  return function (it) {
    var O = toIObject(it);
    var keys = getKeys(O);
    var length = keys.length;
    var i = 0;
    var result = [];
    var key;
    while (length > i) if (isEnum.call(O, key = keys[i++])) {
      result.push(isEntries ? [key, O[key]] : O[key]);
    } return result;
  };
};

},{"./_object-keys":82,"./_object-pie":83,"./_to-iobject":113}],86:[function(require,module,exports){
// all object keys, includes non-enumerable and symbols
var gOPN = require('./_object-gopn');
var gOPS = require('./_object-gops');
var anObject = require('./_an-object');
var Reflect = require('./_global').Reflect;
module.exports = Reflect && Reflect.ownKeys || function ownKeys(it) {
  var keys = gOPN.f(anObject(it));
  var getSymbols = gOPS.f;
  return getSymbols ? keys.concat(getSymbols(it)) : keys;
};

},{"./_an-object":15,"./_global":45,"./_object-gopn":78,"./_object-gops":79}],87:[function(require,module,exports){
var $parseFloat = require('./_global').parseFloat;
var $trim = require('./_string-trim').trim;

module.exports = 1 / $parseFloat(require('./_string-ws') + '-0') !== -Infinity ? function parseFloat(str) {
  var string = $trim(String(str), 3);
  var result = $parseFloat(string);
  return result === 0 && string.charAt(0) == '-' ? -0 : result;
} : $parseFloat;

},{"./_global":45,"./_string-trim":107,"./_string-ws":108}],88:[function(require,module,exports){
var $parseInt = require('./_global').parseInt;
var $trim = require('./_string-trim').trim;
var ws = require('./_string-ws');
var hex = /^[-+]?0[xX]/;

module.exports = $parseInt(ws + '08') !== 8 || $parseInt(ws + '0x16') !== 22 ? function parseInt(str, radix) {
  var string = $trim(String(str), 3);
  return $parseInt(string, (radix >>> 0) || (hex.test(string) ? 16 : 10));
} : $parseInt;

},{"./_global":45,"./_string-trim":107,"./_string-ws":108}],89:[function(require,module,exports){
module.exports = function (exec) {
  try {
    return { e: false, v: exec() };
  } catch (e) {
    return { e: true, v: e };
  }
};

},{}],90:[function(require,module,exports){
var anObject = require('./_an-object');
var isObject = require('./_is-object');
var newPromiseCapability = require('./_new-promise-capability');

module.exports = function (C, x) {
  anObject(C);
  if (isObject(x) && x.constructor === C) return x;
  var promiseCapability = newPromiseCapability.f(C);
  var resolve = promiseCapability.resolve;
  resolve(x);
  return promiseCapability.promise;
};

},{"./_an-object":15,"./_is-object":56,"./_new-promise-capability":71}],91:[function(require,module,exports){
module.exports = function (bitmap, value) {
  return {
    enumerable: !(bitmap & 1),
    configurable: !(bitmap & 2),
    writable: !(bitmap & 4),
    value: value
  };
};

},{}],92:[function(require,module,exports){
var redefine = require('./_redefine');
module.exports = function (target, src, safe) {
  for (var key in src) redefine(target, key, src[key], safe);
  return target;
};

},{"./_redefine":93}],93:[function(require,module,exports){
var global = require('./_global');
var hide = require('./_hide');
var has = require('./_has');
var SRC = require('./_uid')('src');
var TO_STRING = 'toString';
var $toString = Function[TO_STRING];
var TPL = ('' + $toString).split(TO_STRING);

require('./_core').inspectSource = function (it) {
  return $toString.call(it);
};

(module.exports = function (O, key, val, safe) {
  var isFunction = typeof val == 'function';
  if (isFunction) has(val, 'name') || hide(val, 'name', key);
  if (O[key] === val) return;
  if (isFunction) has(val, SRC) || hide(val, SRC, O[key] ? '' + O[key] : TPL.join(String(key)));
  if (O === global) {
    O[key] = val;
  } else if (!safe) {
    delete O[key];
    hide(O, key, val);
  } else if (O[key]) {
    O[key] = val;
  } else {
    hide(O, key, val);
  }
// add fake Function#toString for correct work wrapped methods / constructors with methods like LoDash isNative
})(Function.prototype, TO_STRING, function toString() {
  return typeof this == 'function' && this[SRC] || $toString.call(this);
});

},{"./_core":29,"./_global":45,"./_has":46,"./_hide":47,"./_uid":120}],94:[function(require,module,exports){
// 7.2.9 SameValue(x, y)
module.exports = Object.is || function is(x, y) {
  // eslint-disable-next-line no-self-compare
  return x === y ? x !== 0 || 1 / x === 1 / y : x != x && y != y;
};

},{}],95:[function(require,module,exports){
// Works with __proto__ only. Old v8 can't work with null proto objects.
/* eslint-disable no-proto */
var isObject = require('./_is-object');
var anObject = require('./_an-object');
var check = function (O, proto) {
  anObject(O);
  if (!isObject(proto) && proto !== null) throw TypeError(proto + ": can't set as prototype!");
};
module.exports = {
  set: Object.setPrototypeOf || ('__proto__' in {} ? // eslint-disable-line
    function (test, buggy, set) {
      try {
        set = require('./_ctx')(Function.call, require('./_object-gopd').f(Object.prototype, '__proto__').set, 2);
        set(test, []);
        buggy = !(test instanceof Array);
      } catch (e) { buggy = true; }
      return function setPrototypeOf(O, proto) {
        check(O, proto);
        if (buggy) O.__proto__ = proto;
        else set(O, proto);
        return O;
      };
    }({}, false) : undefined),
  check: check
};

},{"./_an-object":15,"./_ctx":31,"./_is-object":56,"./_object-gopd":76}],96:[function(require,module,exports){
'use strict';
var global = require('./_global');
var dP = require('./_object-dp');
var DESCRIPTORS = require('./_descriptors');
var SPECIES = require('./_wks')('species');

module.exports = function (KEY) {
  var C = global[KEY];
  if (DESCRIPTORS && C && !C[SPECIES]) dP.f(C, SPECIES, {
    configurable: true,
    get: function () { return this; }
  });
};

},{"./_descriptors":35,"./_global":45,"./_object-dp":74,"./_wks":125}],97:[function(require,module,exports){
var def = require('./_object-dp').f;
var has = require('./_has');
var TAG = require('./_wks')('toStringTag');

module.exports = function (it, tag, stat) {
  if (it && !has(it = stat ? it : it.prototype, TAG)) def(it, TAG, { configurable: true, value: tag });
};

},{"./_has":46,"./_object-dp":74,"./_wks":125}],98:[function(require,module,exports){
var shared = require('./_shared')('keys');
var uid = require('./_uid');
module.exports = function (key) {
  return shared[key] || (shared[key] = uid(key));
};

},{"./_shared":99,"./_uid":120}],99:[function(require,module,exports){
var core = require('./_core');
var global = require('./_global');
var SHARED = '__core-js_shared__';
var store = global[SHARED] || (global[SHARED] = {});

(module.exports = function (key, value) {
  return store[key] || (store[key] = value !== undefined ? value : {});
})('versions', []).push({
  version: core.version,
  mode: require('./_library') ? 'pure' : 'global',
  copyright: '© 2018 Denis Pushkarev (zloirock.ru)'
});

},{"./_core":29,"./_global":45,"./_library":64}],100:[function(require,module,exports){
// 7.3.20 SpeciesConstructor(O, defaultConstructor)
var anObject = require('./_an-object');
var aFunction = require('./_a-function');
var SPECIES = require('./_wks')('species');
module.exports = function (O, D) {
  var C = anObject(O).constructor;
  var S;
  return C === undefined || (S = anObject(C)[SPECIES]) == undefined ? D : aFunction(S);
};

},{"./_a-function":11,"./_an-object":15,"./_wks":125}],101:[function(require,module,exports){
'use strict';
var fails = require('./_fails');

module.exports = function (method, arg) {
  return !!method && fails(function () {
    // eslint-disable-next-line no-useless-call
    arg ? method.call(null, function () { /* empty */ }, 1) : method.call(null);
  });
};

},{"./_fails":41}],102:[function(require,module,exports){
var toInteger = require('./_to-integer');
var defined = require('./_defined');
// true  -> String#at
// false -> String#codePointAt
module.exports = function (TO_STRING) {
  return function (that, pos) {
    var s = String(defined(that));
    var i = toInteger(pos);
    var l = s.length;
    var a, b;
    if (i < 0 || i >= l) return TO_STRING ? '' : undefined;
    a = s.charCodeAt(i);
    return a < 0xd800 || a > 0xdbff || i + 1 === l || (b = s.charCodeAt(i + 1)) < 0xdc00 || b > 0xdfff
      ? TO_STRING ? s.charAt(i) : a
      : TO_STRING ? s.slice(i, i + 2) : (a - 0xd800 << 10) + (b - 0xdc00) + 0x10000;
  };
};

},{"./_defined":34,"./_to-integer":112}],103:[function(require,module,exports){
// helper for String#{startsWith, endsWith, includes}
var isRegExp = require('./_is-regexp');
var defined = require('./_defined');

module.exports = function (that, searchString, NAME) {
  if (isRegExp(searchString)) throw TypeError('String#' + NAME + " doesn't accept regex!");
  return String(defined(that));
};

},{"./_defined":34,"./_is-regexp":57}],104:[function(require,module,exports){
var $export = require('./_export');
var fails = require('./_fails');
var defined = require('./_defined');
var quot = /"/g;
// B.2.3.2.1 CreateHTML(string, tag, attribute, value)
var createHTML = function (string, tag, attribute, value) {
  var S = String(defined(string));
  var p1 = '<' + tag;
  if (attribute !== '') p1 += ' ' + attribute + '="' + String(value).replace(quot, '&quot;') + '"';
  return p1 + '>' + S + '</' + tag + '>';
};
module.exports = function (NAME, exec) {
  var O = {};
  O[NAME] = exec(createHTML);
  $export($export.P + $export.F * fails(function () {
    var test = ''[NAME]('"');
    return test !== test.toLowerCase() || test.split('"').length > 3;
  }), 'String', O);
};

},{"./_defined":34,"./_export":39,"./_fails":41}],105:[function(require,module,exports){
// https://github.com/tc39/proposal-string-pad-start-end
var toLength = require('./_to-length');
var repeat = require('./_string-repeat');
var defined = require('./_defined');

module.exports = function (that, maxLength, fillString, left) {
  var S = String(defined(that));
  var stringLength = S.length;
  var fillStr = fillString === undefined ? ' ' : String(fillString);
  var intMaxLength = toLength(maxLength);
  if (intMaxLength <= stringLength || fillStr == '') return S;
  var fillLen = intMaxLength - stringLength;
  var stringFiller = repeat.call(fillStr, Math.ceil(fillLen / fillStr.length));
  if (stringFiller.length > fillLen) stringFiller = stringFiller.slice(0, fillLen);
  return left ? stringFiller + S : S + stringFiller;
};

},{"./_defined":34,"./_string-repeat":106,"./_to-length":114}],106:[function(require,module,exports){
'use strict';
var toInteger = require('./_to-integer');
var defined = require('./_defined');

module.exports = function repeat(count) {
  var str = String(defined(this));
  var res = '';
  var n = toInteger(count);
  if (n < 0 || n == Infinity) throw RangeError("Count can't be negative");
  for (;n > 0; (n >>>= 1) && (str += str)) if (n & 1) res += str;
  return res;
};

},{"./_defined":34,"./_to-integer":112}],107:[function(require,module,exports){
var $export = require('./_export');
var defined = require('./_defined');
var fails = require('./_fails');
var spaces = require('./_string-ws');
var space = '[' + spaces + ']';
var non = '\u200b\u0085';
var ltrim = RegExp('^' + space + space + '*');
var rtrim = RegExp(space + space + '*$');

var exporter = function (KEY, exec, ALIAS) {
  var exp = {};
  var FORCE = fails(function () {
    return !!spaces[KEY]() || non[KEY]() != non;
  });
  var fn = exp[KEY] = FORCE ? exec(trim) : spaces[KEY];
  if (ALIAS) exp[ALIAS] = fn;
  $export($export.P + $export.F * FORCE, 'String', exp);
};

// 1 -> String#trimLeft
// 2 -> String#trimRight
// 3 -> String#trim
var trim = exporter.trim = function (string, TYPE) {
  string = String(defined(string));
  if (TYPE & 1) string = string.replace(ltrim, '');
  if (TYPE & 2) string = string.replace(rtrim, '');
  return string;
};

module.exports = exporter;

},{"./_defined":34,"./_export":39,"./_fails":41,"./_string-ws":108}],108:[function(require,module,exports){
module.exports = '\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u180E\u2000\u2001\u2002\u2003' +
  '\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028\u2029\uFEFF';

},{}],109:[function(require,module,exports){
var ctx = require('./_ctx');
var invoke = require('./_invoke');
var html = require('./_html');
var cel = require('./_dom-create');
var global = require('./_global');
var process = global.process;
var setTask = global.setImmediate;
var clearTask = global.clearImmediate;
var MessageChannel = global.MessageChannel;
var Dispatch = global.Dispatch;
var counter = 0;
var queue = {};
var ONREADYSTATECHANGE = 'onreadystatechange';
var defer, channel, port;
var run = function () {
  var id = +this;
  // eslint-disable-next-line no-prototype-builtins
  if (queue.hasOwnProperty(id)) {
    var fn = queue[id];
    delete queue[id];
    fn();
  }
};
var listener = function (event) {
  run.call(event.data);
};
// Node.js 0.9+ & IE10+ has setImmediate, otherwise:
if (!setTask || !clearTask) {
  setTask = function setImmediate(fn) {
    var args = [];
    var i = 1;
    while (arguments.length > i) args.push(arguments[i++]);
    queue[++counter] = function () {
      // eslint-disable-next-line no-new-func
      invoke(typeof fn == 'function' ? fn : Function(fn), args);
    };
    defer(counter);
    return counter;
  };
  clearTask = function clearImmediate(id) {
    delete queue[id];
  };
  // Node.js 0.8-
  if (require('./_cof')(process) == 'process') {
    defer = function (id) {
      process.nextTick(ctx(run, id, 1));
    };
  // Sphere (JS game engine) Dispatch API
  } else if (Dispatch && Dispatch.now) {
    defer = function (id) {
      Dispatch.now(ctx(run, id, 1));
    };
  // Browsers with MessageChannel, includes WebWorkers
  } else if (MessageChannel) {
    channel = new MessageChannel();
    port = channel.port2;
    channel.port1.onmessage = listener;
    defer = ctx(port.postMessage, port, 1);
  // Browsers with postMessage, skip WebWorkers
  // IE8 has postMessage, but it's sync & typeof its postMessage is 'object'
  } else if (global.addEventListener && typeof postMessage == 'function' && !global.importScripts) {
    defer = function (id) {
      global.postMessage(id + '', '*');
    };
    global.addEventListener('message', listener, false);
  // IE8-
  } else if (ONREADYSTATECHANGE in cel('script')) {
    defer = function (id) {
      html.appendChild(cel('script'))[ONREADYSTATECHANGE] = function () {
        html.removeChild(this);
        run.call(id);
      };
    };
  // Rest old browsers
  } else {
    defer = function (id) {
      setTimeout(ctx(run, id, 1), 0);
    };
  }
}
module.exports = {
  set: setTask,
  clear: clearTask
};

},{"./_cof":25,"./_ctx":31,"./_dom-create":36,"./_global":45,"./_html":48,"./_invoke":51}],110:[function(require,module,exports){
var toInteger = require('./_to-integer');
var max = Math.max;
var min = Math.min;
module.exports = function (index, length) {
  index = toInteger(index);
  return index < 0 ? max(index + length, 0) : min(index, length);
};

},{"./_to-integer":112}],111:[function(require,module,exports){
// https://tc39.github.io/ecma262/#sec-toindex
var toInteger = require('./_to-integer');
var toLength = require('./_to-length');
module.exports = function (it) {
  if (it === undefined) return 0;
  var number = toInteger(it);
  var length = toLength(number);
  if (number !== length) throw RangeError('Wrong length!');
  return length;
};

},{"./_to-integer":112,"./_to-length":114}],112:[function(require,module,exports){
// 7.1.4 ToInteger
var ceil = Math.ceil;
var floor = Math.floor;
module.exports = function (it) {
  return isNaN(it = +it) ? 0 : (it > 0 ? floor : ceil)(it);
};

},{}],113:[function(require,module,exports){
// to indexed object, toObject with fallback for non-array-like ES3 strings
var IObject = require('./_iobject');
var defined = require('./_defined');
module.exports = function (it) {
  return IObject(defined(it));
};

},{"./_defined":34,"./_iobject":52}],114:[function(require,module,exports){
// 7.1.15 ToLength
var toInteger = require('./_to-integer');
var min = Math.min;
module.exports = function (it) {
  return it > 0 ? min(toInteger(it), 0x1fffffffffffff) : 0; // pow(2, 53) - 1 == 9007199254740991
};

},{"./_to-integer":112}],115:[function(require,module,exports){
// 7.1.13 ToObject(argument)
var defined = require('./_defined');
module.exports = function (it) {
  return Object(defined(it));
};

},{"./_defined":34}],116:[function(require,module,exports){
// 7.1.1 ToPrimitive(input [, PreferredType])
var isObject = require('./_is-object');
// instead of the ES6 spec version, we didn't implement @@toPrimitive case
// and the second argument - flag - preferred type is a string
module.exports = function (it, S) {
  if (!isObject(it)) return it;
  var fn, val;
  if (S && typeof (fn = it.toString) == 'function' && !isObject(val = fn.call(it))) return val;
  if (typeof (fn = it.valueOf) == 'function' && !isObject(val = fn.call(it))) return val;
  if (!S && typeof (fn = it.toString) == 'function' && !isObject(val = fn.call(it))) return val;
  throw TypeError("Can't convert object to primitive value");
};

},{"./_is-object":56}],117:[function(require,module,exports){
'use strict';
if (require('./_descriptors')) {
  var LIBRARY = require('./_library');
  var global = require('./_global');
  var fails = require('./_fails');
  var $export = require('./_export');
  var $typed = require('./_typed');
  var $buffer = require('./_typed-buffer');
  var ctx = require('./_ctx');
  var anInstance = require('./_an-instance');
  var propertyDesc = require('./_property-desc');
  var hide = require('./_hide');
  var redefineAll = require('./_redefine-all');
  var toInteger = require('./_to-integer');
  var toLength = require('./_to-length');
  var toIndex = require('./_to-index');
  var toAbsoluteIndex = require('./_to-absolute-index');
  var toPrimitive = require('./_to-primitive');
  var has = require('./_has');
  var classof = require('./_classof');
  var isObject = require('./_is-object');
  var toObject = require('./_to-object');
  var isArrayIter = require('./_is-array-iter');
  var create = require('./_object-create');
  var getPrototypeOf = require('./_object-gpo');
  var gOPN = require('./_object-gopn').f;
  var getIterFn = require('./core.get-iterator-method');
  var uid = require('./_uid');
  var wks = require('./_wks');
  var createArrayMethod = require('./_array-methods');
  var createArrayIncludes = require('./_array-includes');
  var speciesConstructor = require('./_species-constructor');
  var ArrayIterators = require('./es6.array.iterator');
  var Iterators = require('./_iterators');
  var $iterDetect = require('./_iter-detect');
  var setSpecies = require('./_set-species');
  var arrayFill = require('./_array-fill');
  var arrayCopyWithin = require('./_array-copy-within');
  var $DP = require('./_object-dp');
  var $GOPD = require('./_object-gopd');
  var dP = $DP.f;
  var gOPD = $GOPD.f;
  var RangeError = global.RangeError;
  var TypeError = global.TypeError;
  var Uint8Array = global.Uint8Array;
  var ARRAY_BUFFER = 'ArrayBuffer';
  var SHARED_BUFFER = 'Shared' + ARRAY_BUFFER;
  var BYTES_PER_ELEMENT = 'BYTES_PER_ELEMENT';
  var PROTOTYPE = 'prototype';
  var ArrayProto = Array[PROTOTYPE];
  var $ArrayBuffer = $buffer.ArrayBuffer;
  var $DataView = $buffer.DataView;
  var arrayForEach = createArrayMethod(0);
  var arrayFilter = createArrayMethod(2);
  var arraySome = createArrayMethod(3);
  var arrayEvery = createArrayMethod(4);
  var arrayFind = createArrayMethod(5);
  var arrayFindIndex = createArrayMethod(6);
  var arrayIncludes = createArrayIncludes(true);
  var arrayIndexOf = createArrayIncludes(false);
  var arrayValues = ArrayIterators.values;
  var arrayKeys = ArrayIterators.keys;
  var arrayEntries = ArrayIterators.entries;
  var arrayLastIndexOf = ArrayProto.lastIndexOf;
  var arrayReduce = ArrayProto.reduce;
  var arrayReduceRight = ArrayProto.reduceRight;
  var arrayJoin = ArrayProto.join;
  var arraySort = ArrayProto.sort;
  var arraySlice = ArrayProto.slice;
  var arrayToString = ArrayProto.toString;
  var arrayToLocaleString = ArrayProto.toLocaleString;
  var ITERATOR = wks('iterator');
  var TAG = wks('toStringTag');
  var TYPED_CONSTRUCTOR = uid('typed_constructor');
  var DEF_CONSTRUCTOR = uid('def_constructor');
  var ALL_CONSTRUCTORS = $typed.CONSTR;
  var TYPED_ARRAY = $typed.TYPED;
  var VIEW = $typed.VIEW;
  var WRONG_LENGTH = 'Wrong length!';

  var $map = createArrayMethod(1, function (O, length) {
    return allocate(speciesConstructor(O, O[DEF_CONSTRUCTOR]), length);
  });

  var LITTLE_ENDIAN = fails(function () {
    // eslint-disable-next-line no-undef
    return new Uint8Array(new Uint16Array([1]).buffer)[0] === 1;
  });

  var FORCED_SET = !!Uint8Array && !!Uint8Array[PROTOTYPE].set && fails(function () {
    new Uint8Array(1).set({});
  });

  var toOffset = function (it, BYTES) {
    var offset = toInteger(it);
    if (offset < 0 || offset % BYTES) throw RangeError('Wrong offset!');
    return offset;
  };

  var validate = function (it) {
    if (isObject(it) && TYPED_ARRAY in it) return it;
    throw TypeError(it + ' is not a typed array!');
  };

  var allocate = function (C, length) {
    if (!(isObject(C) && TYPED_CONSTRUCTOR in C)) {
      throw TypeError('It is not a typed array constructor!');
    } return new C(length);
  };

  var speciesFromList = function (O, list) {
    return fromList(speciesConstructor(O, O[DEF_CONSTRUCTOR]), list);
  };

  var fromList = function (C, list) {
    var index = 0;
    var length = list.length;
    var result = allocate(C, length);
    while (length > index) result[index] = list[index++];
    return result;
  };

  var addGetter = function (it, key, internal) {
    dP(it, key, { get: function () { return this._d[internal]; } });
  };

  var $from = function from(source /* , mapfn, thisArg */) {
    var O = toObject(source);
    var aLen = arguments.length;
    var mapfn = aLen > 1 ? arguments[1] : undefined;
    var mapping = mapfn !== undefined;
    var iterFn = getIterFn(O);
    var i, length, values, result, step, iterator;
    if (iterFn != undefined && !isArrayIter(iterFn)) {
      for (iterator = iterFn.call(O), values = [], i = 0; !(step = iterator.next()).done; i++) {
        values.push(step.value);
      } O = values;
    }
    if (mapping && aLen > 2) mapfn = ctx(mapfn, arguments[2], 2);
    for (i = 0, length = toLength(O.length), result = allocate(this, length); length > i; i++) {
      result[i] = mapping ? mapfn(O[i], i) : O[i];
    }
    return result;
  };

  var $of = function of(/* ...items */) {
    var index = 0;
    var length = arguments.length;
    var result = allocate(this, length);
    while (length > index) result[index] = arguments[index++];
    return result;
  };

  // iOS Safari 6.x fails here
  var TO_LOCALE_BUG = !!Uint8Array && fails(function () { arrayToLocaleString.call(new Uint8Array(1)); });

  var $toLocaleString = function toLocaleString() {
    return arrayToLocaleString.apply(TO_LOCALE_BUG ? arraySlice.call(validate(this)) : validate(this), arguments);
  };

  var proto = {
    copyWithin: function copyWithin(target, start /* , end */) {
      return arrayCopyWithin.call(validate(this), target, start, arguments.length > 2 ? arguments[2] : undefined);
    },
    every: function every(callbackfn /* , thisArg */) {
      return arrayEvery(validate(this), callbackfn, arguments.length > 1 ? arguments[1] : undefined);
    },
    fill: function fill(value /* , start, end */) { // eslint-disable-line no-unused-vars
      return arrayFill.apply(validate(this), arguments);
    },
    filter: function filter(callbackfn /* , thisArg */) {
      return speciesFromList(this, arrayFilter(validate(this), callbackfn,
        arguments.length > 1 ? arguments[1] : undefined));
    },
    find: function find(predicate /* , thisArg */) {
      return arrayFind(validate(this), predicate, arguments.length > 1 ? arguments[1] : undefined);
    },
    findIndex: function findIndex(predicate /* , thisArg */) {
      return arrayFindIndex(validate(this), predicate, arguments.length > 1 ? arguments[1] : undefined);
    },
    forEach: function forEach(callbackfn /* , thisArg */) {
      arrayForEach(validate(this), callbackfn, arguments.length > 1 ? arguments[1] : undefined);
    },
    indexOf: function indexOf(searchElement /* , fromIndex */) {
      return arrayIndexOf(validate(this), searchElement, arguments.length > 1 ? arguments[1] : undefined);
    },
    includes: function includes(searchElement /* , fromIndex */) {
      return arrayIncludes(validate(this), searchElement, arguments.length > 1 ? arguments[1] : undefined);
    },
    join: function join(separator) { // eslint-disable-line no-unused-vars
      return arrayJoin.apply(validate(this), arguments);
    },
    lastIndexOf: function lastIndexOf(searchElement /* , fromIndex */) { // eslint-disable-line no-unused-vars
      return arrayLastIndexOf.apply(validate(this), arguments);
    },
    map: function map(mapfn /* , thisArg */) {
      return $map(validate(this), mapfn, arguments.length > 1 ? arguments[1] : undefined);
    },
    reduce: function reduce(callbackfn /* , initialValue */) { // eslint-disable-line no-unused-vars
      return arrayReduce.apply(validate(this), arguments);
    },
    reduceRight: function reduceRight(callbackfn /* , initialValue */) { // eslint-disable-line no-unused-vars
      return arrayReduceRight.apply(validate(this), arguments);
    },
    reverse: function reverse() {
      var that = this;
      var length = validate(that).length;
      var middle = Math.floor(length / 2);
      var index = 0;
      var value;
      while (index < middle) {
        value = that[index];
        that[index++] = that[--length];
        that[length] = value;
      } return that;
    },
    some: function some(callbackfn /* , thisArg */) {
      return arraySome(validate(this), callbackfn, arguments.length > 1 ? arguments[1] : undefined);
    },
    sort: function sort(comparefn) {
      return arraySort.call(validate(this), comparefn);
    },
    subarray: function subarray(begin, end) {
      var O = validate(this);
      var length = O.length;
      var $begin = toAbsoluteIndex(begin, length);
      return new (speciesConstructor(O, O[DEF_CONSTRUCTOR]))(
        O.buffer,
        O.byteOffset + $begin * O.BYTES_PER_ELEMENT,
        toLength((end === undefined ? length : toAbsoluteIndex(end, length)) - $begin)
      );
    }
  };

  var $slice = function slice(start, end) {
    return speciesFromList(this, arraySlice.call(validate(this), start, end));
  };

  var $set = function set(arrayLike /* , offset */) {
    validate(this);
    var offset = toOffset(arguments[1], 1);
    var length = this.length;
    var src = toObject(arrayLike);
    var len = toLength(src.length);
    var index = 0;
    if (len + offset > length) throw RangeError(WRONG_LENGTH);
    while (index < len) this[offset + index] = src[index++];
  };

  var $iterators = {
    entries: function entries() {
      return arrayEntries.call(validate(this));
    },
    keys: function keys() {
      return arrayKeys.call(validate(this));
    },
    values: function values() {
      return arrayValues.call(validate(this));
    }
  };

  var isTAIndex = function (target, key) {
    return isObject(target)
      && target[TYPED_ARRAY]
      && typeof key != 'symbol'
      && key in target
      && String(+key) == String(key);
  };
  var $getDesc = function getOwnPropertyDescriptor(target, key) {
    return isTAIndex(target, key = toPrimitive(key, true))
      ? propertyDesc(2, target[key])
      : gOPD(target, key);
  };
  var $setDesc = function defineProperty(target, key, desc) {
    if (isTAIndex(target, key = toPrimitive(key, true))
      && isObject(desc)
      && has(desc, 'value')
      && !has(desc, 'get')
      && !has(desc, 'set')
      // TODO: add validation descriptor w/o calling accessors
      && !desc.configurable
      && (!has(desc, 'writable') || desc.writable)
      && (!has(desc, 'enumerable') || desc.enumerable)
    ) {
      target[key] = desc.value;
      return target;
    } return dP(target, key, desc);
  };

  if (!ALL_CONSTRUCTORS) {
    $GOPD.f = $getDesc;
    $DP.f = $setDesc;
  }

  $export($export.S + $export.F * !ALL_CONSTRUCTORS, 'Object', {
    getOwnPropertyDescriptor: $getDesc,
    defineProperty: $setDesc
  });

  if (fails(function () { arrayToString.call({}); })) {
    arrayToString = arrayToLocaleString = function toString() {
      return arrayJoin.call(this);
    };
  }

  var $TypedArrayPrototype$ = redefineAll({}, proto);
  redefineAll($TypedArrayPrototype$, $iterators);
  hide($TypedArrayPrototype$, ITERATOR, $iterators.values);
  redefineAll($TypedArrayPrototype$, {
    slice: $slice,
    set: $set,
    constructor: function () { /* noop */ },
    toString: arrayToString,
    toLocaleString: $toLocaleString
  });
  addGetter($TypedArrayPrototype$, 'buffer', 'b');
  addGetter($TypedArrayPrototype$, 'byteOffset', 'o');
  addGetter($TypedArrayPrototype$, 'byteLength', 'l');
  addGetter($TypedArrayPrototype$, 'length', 'e');
  dP($TypedArrayPrototype$, TAG, {
    get: function () { return this[TYPED_ARRAY]; }
  });

  // eslint-disable-next-line max-statements
  module.exports = function (KEY, BYTES, wrapper, CLAMPED) {
    CLAMPED = !!CLAMPED;
    var NAME = KEY + (CLAMPED ? 'Clamped' : '') + 'Array';
    var GETTER = 'get' + KEY;
    var SETTER = 'set' + KEY;
    var TypedArray = global[NAME];
    var Base = TypedArray || {};
    var TAC = TypedArray && getPrototypeOf(TypedArray);
    var FORCED = !TypedArray || !$typed.ABV;
    var O = {};
    var TypedArrayPrototype = TypedArray && TypedArray[PROTOTYPE];
    var getter = function (that, index) {
      var data = that._d;
      return data.v[GETTER](index * BYTES + data.o, LITTLE_ENDIAN);
    };
    var setter = function (that, index, value) {
      var data = that._d;
      if (CLAMPED) value = (value = Math.round(value)) < 0 ? 0 : value > 0xff ? 0xff : value & 0xff;
      data.v[SETTER](index * BYTES + data.o, value, LITTLE_ENDIAN);
    };
    var addElement = function (that, index) {
      dP(that, index, {
        get: function () {
          return getter(this, index);
        },
        set: function (value) {
          return setter(this, index, value);
        },
        enumerable: true
      });
    };
    if (FORCED) {
      TypedArray = wrapper(function (that, data, $offset, $length) {
        anInstance(that, TypedArray, NAME, '_d');
        var index = 0;
        var offset = 0;
        var buffer, byteLength, length, klass;
        if (!isObject(data)) {
          length = toIndex(data);
          byteLength = length * BYTES;
          buffer = new $ArrayBuffer(byteLength);
        } else if (data instanceof $ArrayBuffer || (klass = classof(data)) == ARRAY_BUFFER || klass == SHARED_BUFFER) {
          buffer = data;
          offset = toOffset($offset, BYTES);
          var $len = data.byteLength;
          if ($length === undefined) {
            if ($len % BYTES) throw RangeError(WRONG_LENGTH);
            byteLength = $len - offset;
            if (byteLength < 0) throw RangeError(WRONG_LENGTH);
          } else {
            byteLength = toLength($length) * BYTES;
            if (byteLength + offset > $len) throw RangeError(WRONG_LENGTH);
          }
          length = byteLength / BYTES;
        } else if (TYPED_ARRAY in data) {
          return fromList(TypedArray, data);
        } else {
          return $from.call(TypedArray, data);
        }
        hide(that, '_d', {
          b: buffer,
          o: offset,
          l: byteLength,
          e: length,
          v: new $DataView(buffer)
        });
        while (index < length) addElement(that, index++);
      });
      TypedArrayPrototype = TypedArray[PROTOTYPE] = create($TypedArrayPrototype$);
      hide(TypedArrayPrototype, 'constructor', TypedArray);
    } else if (!fails(function () {
      TypedArray(1);
    }) || !fails(function () {
      new TypedArray(-1); // eslint-disable-line no-new
    }) || !$iterDetect(function (iter) {
      new TypedArray(); // eslint-disable-line no-new
      new TypedArray(null); // eslint-disable-line no-new
      new TypedArray(1.5); // eslint-disable-line no-new
      new TypedArray(iter); // eslint-disable-line no-new
    }, true)) {
      TypedArray = wrapper(function (that, data, $offset, $length) {
        anInstance(that, TypedArray, NAME);
        var klass;
        // `ws` module bug, temporarily remove validation length for Uint8Array
        // https://github.com/websockets/ws/pull/645
        if (!isObject(data)) return new Base(toIndex(data));
        if (data instanceof $ArrayBuffer || (klass = classof(data)) == ARRAY_BUFFER || klass == SHARED_BUFFER) {
          return $length !== undefined
            ? new Base(data, toOffset($offset, BYTES), $length)
            : $offset !== undefined
              ? new Base(data, toOffset($offset, BYTES))
              : new Base(data);
        }
        if (TYPED_ARRAY in data) return fromList(TypedArray, data);
        return $from.call(TypedArray, data);
      });
      arrayForEach(TAC !== Function.prototype ? gOPN(Base).concat(gOPN(TAC)) : gOPN(Base), function (key) {
        if (!(key in TypedArray)) hide(TypedArray, key, Base[key]);
      });
      TypedArray[PROTOTYPE] = TypedArrayPrototype;
      if (!LIBRARY) TypedArrayPrototype.constructor = TypedArray;
    }
    var $nativeIterator = TypedArrayPrototype[ITERATOR];
    var CORRECT_ITER_NAME = !!$nativeIterator
      && ($nativeIterator.name == 'values' || $nativeIterator.name == undefined);
    var $iterator = $iterators.values;
    hide(TypedArray, TYPED_CONSTRUCTOR, true);
    hide(TypedArrayPrototype, TYPED_ARRAY, NAME);
    hide(TypedArrayPrototype, VIEW, true);
    hide(TypedArrayPrototype, DEF_CONSTRUCTOR, TypedArray);

    if (CLAMPED ? new TypedArray(1)[TAG] != NAME : !(TAG in TypedArrayPrototype)) {
      dP(TypedArrayPrototype, TAG, {
        get: function () { return NAME; }
      });
    }

    O[NAME] = TypedArray;

    $export($export.G + $export.W + $export.F * (TypedArray != Base), O);

    $export($export.S, NAME, {
      BYTES_PER_ELEMENT: BYTES
    });

    $export($export.S + $export.F * fails(function () { Base.of.call(TypedArray, 1); }), NAME, {
      from: $from,
      of: $of
    });

    if (!(BYTES_PER_ELEMENT in TypedArrayPrototype)) hide(TypedArrayPrototype, BYTES_PER_ELEMENT, BYTES);

    $export($export.P, NAME, proto);

    setSpecies(NAME);

    $export($export.P + $export.F * FORCED_SET, NAME, { set: $set });

    $export($export.P + $export.F * !CORRECT_ITER_NAME, NAME, $iterators);

    if (!LIBRARY && TypedArrayPrototype.toString != arrayToString) TypedArrayPrototype.toString = arrayToString;

    $export($export.P + $export.F * fails(function () {
      new TypedArray(1).slice();
    }), NAME, { slice: $slice });

    $export($export.P + $export.F * (fails(function () {
      return [1, 2].toLocaleString() != new TypedArray([1, 2]).toLocaleString();
    }) || !fails(function () {
      TypedArrayPrototype.toLocaleString.call([1, 2]);
    })), NAME, { toLocaleString: $toLocaleString });

    Iterators[NAME] = CORRECT_ITER_NAME ? $nativeIterator : $iterator;
    if (!LIBRARY && !CORRECT_ITER_NAME) hide(TypedArrayPrototype, ITERATOR, $iterator);
  };
} else module.exports = function () { /* empty */ };

},{"./_an-instance":14,"./_array-copy-within":16,"./_array-fill":17,"./_array-includes":18,"./_array-methods":19,"./_classof":24,"./_ctx":31,"./_descriptors":35,"./_export":39,"./_fails":41,"./_global":45,"./_has":46,"./_hide":47,"./_is-array-iter":53,"./_is-object":56,"./_iter-detect":61,"./_iterators":63,"./_library":64,"./_object-create":73,"./_object-dp":74,"./_object-gopd":76,"./_object-gopn":78,"./_object-gpo":80,"./_property-desc":91,"./_redefine-all":92,"./_set-species":96,"./_species-constructor":100,"./_to-absolute-index":110,"./_to-index":111,"./_to-integer":112,"./_to-length":114,"./_to-object":115,"./_to-primitive":116,"./_typed":119,"./_typed-buffer":118,"./_uid":120,"./_wks":125,"./core.get-iterator-method":126,"./es6.array.iterator":137}],118:[function(require,module,exports){
'use strict';
var global = require('./_global');
var DESCRIPTORS = require('./_descriptors');
var LIBRARY = require('./_library');
var $typed = require('./_typed');
var hide = require('./_hide');
var redefineAll = require('./_redefine-all');
var fails = require('./_fails');
var anInstance = require('./_an-instance');
var toInteger = require('./_to-integer');
var toLength = require('./_to-length');
var toIndex = require('./_to-index');
var gOPN = require('./_object-gopn').f;
var dP = require('./_object-dp').f;
var arrayFill = require('./_array-fill');
var setToStringTag = require('./_set-to-string-tag');
var ARRAY_BUFFER = 'ArrayBuffer';
var DATA_VIEW = 'DataView';
var PROTOTYPE = 'prototype';
var WRONG_LENGTH = 'Wrong length!';
var WRONG_INDEX = 'Wrong index!';
var $ArrayBuffer = global[ARRAY_BUFFER];
var $DataView = global[DATA_VIEW];
var Math = global.Math;
var RangeError = global.RangeError;
// eslint-disable-next-line no-shadow-restricted-names
var Infinity = global.Infinity;
var BaseBuffer = $ArrayBuffer;
var abs = Math.abs;
var pow = Math.pow;
var floor = Math.floor;
var log = Math.log;
var LN2 = Math.LN2;
var BUFFER = 'buffer';
var BYTE_LENGTH = 'byteLength';
var BYTE_OFFSET = 'byteOffset';
var $BUFFER = DESCRIPTORS ? '_b' : BUFFER;
var $LENGTH = DESCRIPTORS ? '_l' : BYTE_LENGTH;
var $OFFSET = DESCRIPTORS ? '_o' : BYTE_OFFSET;

// IEEE754 conversions based on https://github.com/feross/ieee754
function packIEEE754(value, mLen, nBytes) {
  var buffer = new Array(nBytes);
  var eLen = nBytes * 8 - mLen - 1;
  var eMax = (1 << eLen) - 1;
  var eBias = eMax >> 1;
  var rt = mLen === 23 ? pow(2, -24) - pow(2, -77) : 0;
  var i = 0;
  var s = value < 0 || value === 0 && 1 / value < 0 ? 1 : 0;
  var e, m, c;
  value = abs(value);
  // eslint-disable-next-line no-self-compare
  if (value != value || value === Infinity) {
    // eslint-disable-next-line no-self-compare
    m = value != value ? 1 : 0;
    e = eMax;
  } else {
    e = floor(log(value) / LN2);
    if (value * (c = pow(2, -e)) < 1) {
      e--;
      c *= 2;
    }
    if (e + eBias >= 1) {
      value += rt / c;
    } else {
      value += rt * pow(2, 1 - eBias);
    }
    if (value * c >= 2) {
      e++;
      c /= 2;
    }
    if (e + eBias >= eMax) {
      m = 0;
      e = eMax;
    } else if (e + eBias >= 1) {
      m = (value * c - 1) * pow(2, mLen);
      e = e + eBias;
    } else {
      m = value * pow(2, eBias - 1) * pow(2, mLen);
      e = 0;
    }
  }
  for (; mLen >= 8; buffer[i++] = m & 255, m /= 256, mLen -= 8);
  e = e << mLen | m;
  eLen += mLen;
  for (; eLen > 0; buffer[i++] = e & 255, e /= 256, eLen -= 8);
  buffer[--i] |= s * 128;
  return buffer;
}
function unpackIEEE754(buffer, mLen, nBytes) {
  var eLen = nBytes * 8 - mLen - 1;
  var eMax = (1 << eLen) - 1;
  var eBias = eMax >> 1;
  var nBits = eLen - 7;
  var i = nBytes - 1;
  var s = buffer[i--];
  var e = s & 127;
  var m;
  s >>= 7;
  for (; nBits > 0; e = e * 256 + buffer[i], i--, nBits -= 8);
  m = e & (1 << -nBits) - 1;
  e >>= -nBits;
  nBits += mLen;
  for (; nBits > 0; m = m * 256 + buffer[i], i--, nBits -= 8);
  if (e === 0) {
    e = 1 - eBias;
  } else if (e === eMax) {
    return m ? NaN : s ? -Infinity : Infinity;
  } else {
    m = m + pow(2, mLen);
    e = e - eBias;
  } return (s ? -1 : 1) * m * pow(2, e - mLen);
}

function unpackI32(bytes) {
  return bytes[3] << 24 | bytes[2] << 16 | bytes[1] << 8 | bytes[0];
}
function packI8(it) {
  return [it & 0xff];
}
function packI16(it) {
  return [it & 0xff, it >> 8 & 0xff];
}
function packI32(it) {
  return [it & 0xff, it >> 8 & 0xff, it >> 16 & 0xff, it >> 24 & 0xff];
}
function packF64(it) {
  return packIEEE754(it, 52, 8);
}
function packF32(it) {
  return packIEEE754(it, 23, 4);
}

function addGetter(C, key, internal) {
  dP(C[PROTOTYPE], key, { get: function () { return this[internal]; } });
}

function get(view, bytes, index, isLittleEndian) {
  var numIndex = +index;
  var intIndex = toIndex(numIndex);
  if (intIndex + bytes > view[$LENGTH]) throw RangeError(WRONG_INDEX);
  var store = view[$BUFFER]._b;
  var start = intIndex + view[$OFFSET];
  var pack = store.slice(start, start + bytes);
  return isLittleEndian ? pack : pack.reverse();
}
function set(view, bytes, index, conversion, value, isLittleEndian) {
  var numIndex = +index;
  var intIndex = toIndex(numIndex);
  if (intIndex + bytes > view[$LENGTH]) throw RangeError(WRONG_INDEX);
  var store = view[$BUFFER]._b;
  var start = intIndex + view[$OFFSET];
  var pack = conversion(+value);
  for (var i = 0; i < bytes; i++) store[start + i] = pack[isLittleEndian ? i : bytes - i - 1];
}

if (!$typed.ABV) {
  $ArrayBuffer = function ArrayBuffer(length) {
    anInstance(this, $ArrayBuffer, ARRAY_BUFFER);
    var byteLength = toIndex(length);
    this._b = arrayFill.call(new Array(byteLength), 0);
    this[$LENGTH] = byteLength;
  };

  $DataView = function DataView(buffer, byteOffset, byteLength) {
    anInstance(this, $DataView, DATA_VIEW);
    anInstance(buffer, $ArrayBuffer, DATA_VIEW);
    var bufferLength = buffer[$LENGTH];
    var offset = toInteger(byteOffset);
    if (offset < 0 || offset > bufferLength) throw RangeError('Wrong offset!');
    byteLength = byteLength === undefined ? bufferLength - offset : toLength(byteLength);
    if (offset + byteLength > bufferLength) throw RangeError(WRONG_LENGTH);
    this[$BUFFER] = buffer;
    this[$OFFSET] = offset;
    this[$LENGTH] = byteLength;
  };

  if (DESCRIPTORS) {
    addGetter($ArrayBuffer, BYTE_LENGTH, '_l');
    addGetter($DataView, BUFFER, '_b');
    addGetter($DataView, BYTE_LENGTH, '_l');
    addGetter($DataView, BYTE_OFFSET, '_o');
  }

  redefineAll($DataView[PROTOTYPE], {
    getInt8: function getInt8(byteOffset) {
      return get(this, 1, byteOffset)[0] << 24 >> 24;
    },
    getUint8: function getUint8(byteOffset) {
      return get(this, 1, byteOffset)[0];
    },
    getInt16: function getInt16(byteOffset /* , littleEndian */) {
      var bytes = get(this, 2, byteOffset, arguments[1]);
      return (bytes[1] << 8 | bytes[0]) << 16 >> 16;
    },
    getUint16: function getUint16(byteOffset /* , littleEndian */) {
      var bytes = get(this, 2, byteOffset, arguments[1]);
      return bytes[1] << 8 | bytes[0];
    },
    getInt32: function getInt32(byteOffset /* , littleEndian */) {
      return unpackI32(get(this, 4, byteOffset, arguments[1]));
    },
    getUint32: function getUint32(byteOffset /* , littleEndian */) {
      return unpackI32(get(this, 4, byteOffset, arguments[1])) >>> 0;
    },
    getFloat32: function getFloat32(byteOffset /* , littleEndian */) {
      return unpackIEEE754(get(this, 4, byteOffset, arguments[1]), 23, 4);
    },
    getFloat64: function getFloat64(byteOffset /* , littleEndian */) {
      return unpackIEEE754(get(this, 8, byteOffset, arguments[1]), 52, 8);
    },
    setInt8: function setInt8(byteOffset, value) {
      set(this, 1, byteOffset, packI8, value);
    },
    setUint8: function setUint8(byteOffset, value) {
      set(this, 1, byteOffset, packI8, value);
    },
    setInt16: function setInt16(byteOffset, value /* , littleEndian */) {
      set(this, 2, byteOffset, packI16, value, arguments[2]);
    },
    setUint16: function setUint16(byteOffset, value /* , littleEndian */) {
      set(this, 2, byteOffset, packI16, value, arguments[2]);
    },
    setInt32: function setInt32(byteOffset, value /* , littleEndian */) {
      set(this, 4, byteOffset, packI32, value, arguments[2]);
    },
    setUint32: function setUint32(byteOffset, value /* , littleEndian */) {
      set(this, 4, byteOffset, packI32, value, arguments[2]);
    },
    setFloat32: function setFloat32(byteOffset, value /* , littleEndian */) {
      set(this, 4, byteOffset, packF32, value, arguments[2]);
    },
    setFloat64: function setFloat64(byteOffset, value /* , littleEndian */) {
      set(this, 8, byteOffset, packF64, value, arguments[2]);
    }
  });
} else {
  if (!fails(function () {
    $ArrayBuffer(1);
  }) || !fails(function () {
    new $ArrayBuffer(-1); // eslint-disable-line no-new
  }) || fails(function () {
    new $ArrayBuffer(); // eslint-disable-line no-new
    new $ArrayBuffer(1.5); // eslint-disable-line no-new
    new $ArrayBuffer(NaN); // eslint-disable-line no-new
    return $ArrayBuffer.name != ARRAY_BUFFER;
  })) {
    $ArrayBuffer = function ArrayBuffer(length) {
      anInstance(this, $ArrayBuffer);
      return new BaseBuffer(toIndex(length));
    };
    var ArrayBufferProto = $ArrayBuffer[PROTOTYPE] = BaseBuffer[PROTOTYPE];
    for (var keys = gOPN(BaseBuffer), j = 0, key; keys.length > j;) {
      if (!((key = keys[j++]) in $ArrayBuffer)) hide($ArrayBuffer, key, BaseBuffer[key]);
    }
    if (!LIBRARY) ArrayBufferProto.constructor = $ArrayBuffer;
  }
  // iOS Safari 7.x bug
  var view = new $DataView(new $ArrayBuffer(2));
  var $setInt8 = $DataView[PROTOTYPE].setInt8;
  view.setInt8(0, 2147483648);
  view.setInt8(1, 2147483649);
  if (view.getInt8(0) || !view.getInt8(1)) redefineAll($DataView[PROTOTYPE], {
    setInt8: function setInt8(byteOffset, value) {
      $setInt8.call(this, byteOffset, value << 24 >> 24);
    },
    setUint8: function setUint8(byteOffset, value) {
      $setInt8.call(this, byteOffset, value << 24 >> 24);
    }
  }, true);
}
setToStringTag($ArrayBuffer, ARRAY_BUFFER);
setToStringTag($DataView, DATA_VIEW);
hide($DataView[PROTOTYPE], $typed.VIEW, true);
exports[ARRAY_BUFFER] = $ArrayBuffer;
exports[DATA_VIEW] = $DataView;

},{"./_an-instance":14,"./_array-fill":17,"./_descriptors":35,"./_fails":41,"./_global":45,"./_hide":47,"./_library":64,"./_object-dp":74,"./_object-gopn":78,"./_redefine-all":92,"./_set-to-string-tag":97,"./_to-index":111,"./_to-integer":112,"./_to-length":114,"./_typed":119}],119:[function(require,module,exports){
var global = require('./_global');
var hide = require('./_hide');
var uid = require('./_uid');
var TYPED = uid('typed_array');
var VIEW = uid('view');
var ABV = !!(global.ArrayBuffer && global.DataView);
var CONSTR = ABV;
var i = 0;
var l = 9;
var Typed;

var TypedArrayConstructors = (
  'Int8Array,Uint8Array,Uint8ClampedArray,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array'
).split(',');

while (i < l) {
  if (Typed = global[TypedArrayConstructors[i++]]) {
    hide(Typed.prototype, TYPED, true);
    hide(Typed.prototype, VIEW, true);
  } else CONSTR = false;
}

module.exports = {
  ABV: ABV,
  CONSTR: CONSTR,
  TYPED: TYPED,
  VIEW: VIEW
};

},{"./_global":45,"./_hide":47,"./_uid":120}],120:[function(require,module,exports){
var id = 0;
var px = Math.random();
module.exports = function (key) {
  return 'Symbol('.concat(key === undefined ? '' : key, ')_', (++id + px).toString(36));
};

},{}],121:[function(require,module,exports){
var global = require('./_global');
var navigator = global.navigator;

module.exports = navigator && navigator.userAgent || '';

},{"./_global":45}],122:[function(require,module,exports){
var isObject = require('./_is-object');
module.exports = function (it, TYPE) {
  if (!isObject(it) || it._t !== TYPE) throw TypeError('Incompatible receiver, ' + TYPE + ' required!');
  return it;
};

},{"./_is-object":56}],123:[function(require,module,exports){
var global = require('./_global');
var core = require('./_core');
var LIBRARY = require('./_library');
var wksExt = require('./_wks-ext');
var defineProperty = require('./_object-dp').f;
module.exports = function (name) {
  var $Symbol = core.Symbol || (core.Symbol = LIBRARY ? {} : global.Symbol || {});
  if (name.charAt(0) != '_' && !(name in $Symbol)) defineProperty($Symbol, name, { value: wksExt.f(name) });
};

},{"./_core":29,"./_global":45,"./_library":64,"./_object-dp":74,"./_wks-ext":124}],124:[function(require,module,exports){
exports.f = require('./_wks');

},{"./_wks":125}],125:[function(require,module,exports){
var store = require('./_shared')('wks');
var uid = require('./_uid');
var Symbol = require('./_global').Symbol;
var USE_SYMBOL = typeof Symbol == 'function';

var $exports = module.exports = function (name) {
  return store[name] || (store[name] =
    USE_SYMBOL && Symbol[name] || (USE_SYMBOL ? Symbol : uid)('Symbol.' + name));
};

$exports.store = store;

},{"./_global":45,"./_shared":99,"./_uid":120}],126:[function(require,module,exports){
var classof = require('./_classof');
var ITERATOR = require('./_wks')('iterator');
var Iterators = require('./_iterators');
module.exports = require('./_core').getIteratorMethod = function (it) {
  if (it != undefined) return it[ITERATOR]
    || it['@@iterator']
    || Iterators[classof(it)];
};

},{"./_classof":24,"./_core":29,"./_iterators":63,"./_wks":125}],127:[function(require,module,exports){
// 22.1.3.3 Array.prototype.copyWithin(target, start, end = this.length)
var $export = require('./_export');

$export($export.P, 'Array', { copyWithin: require('./_array-copy-within') });

require('./_add-to-unscopables')('copyWithin');

},{"./_add-to-unscopables":13,"./_array-copy-within":16,"./_export":39}],128:[function(require,module,exports){
'use strict';
var $export = require('./_export');
var $every = require('./_array-methods')(4);

$export($export.P + $export.F * !require('./_strict-method')([].every, true), 'Array', {
  // 22.1.3.5 / 15.4.4.16 Array.prototype.every(callbackfn [, thisArg])
  every: function every(callbackfn /* , thisArg */) {
    return $every(this, callbackfn, arguments[1]);
  }
});

},{"./_array-methods":19,"./_export":39,"./_strict-method":101}],129:[function(require,module,exports){
// 22.1.3.6 Array.prototype.fill(value, start = 0, end = this.length)
var $export = require('./_export');

$export($export.P, 'Array', { fill: require('./_array-fill') });

require('./_add-to-unscopables')('fill');

},{"./_add-to-unscopables":13,"./_array-fill":17,"./_export":39}],130:[function(require,module,exports){
'use strict';
var $export = require('./_export');
var $filter = require('./_array-methods')(2);

$export($export.P + $export.F * !require('./_strict-method')([].filter, true), 'Array', {
  // 22.1.3.7 / 15.4.4.20 Array.prototype.filter(callbackfn [, thisArg])
  filter: function filter(callbackfn /* , thisArg */) {
    return $filter(this, callbackfn, arguments[1]);
  }
});

},{"./_array-methods":19,"./_export":39,"./_strict-method":101}],131:[function(require,module,exports){
'use strict';
// 22.1.3.9 Array.prototype.findIndex(predicate, thisArg = undefined)
var $export = require('./_export');
var $find = require('./_array-methods')(6);
var KEY = 'findIndex';
var forced = true;
// Shouldn't skip holes
if (KEY in []) Array(1)[KEY](function () { forced = false; });
$export($export.P + $export.F * forced, 'Array', {
  findIndex: function findIndex(callbackfn /* , that = undefined */) {
    return $find(this, callbackfn, arguments.length > 1 ? arguments[1] : undefined);
  }
});
require('./_add-to-unscopables')(KEY);

},{"./_add-to-unscopables":13,"./_array-methods":19,"./_export":39}],132:[function(require,module,exports){
'use strict';
// 22.1.3.8 Array.prototype.find(predicate, thisArg = undefined)
var $export = require('./_export');
var $find = require('./_array-methods')(5);
var KEY = 'find';
var forced = true;
// Shouldn't skip holes
if (KEY in []) Array(1)[KEY](function () { forced = false; });
$export($export.P + $export.F * forced, 'Array', {
  find: function find(callbackfn /* , that = undefined */) {
    return $find(this, callbackfn, arguments.length > 1 ? arguments[1] : undefined);
  }
});
require('./_add-to-unscopables')(KEY);

},{"./_add-to-unscopables":13,"./_array-methods":19,"./_export":39}],133:[function(require,module,exports){
'use strict';
var $export = require('./_export');
var $forEach = require('./_array-methods')(0);
var STRICT = require('./_strict-method')([].forEach, true);

$export($export.P + $export.F * !STRICT, 'Array', {
  // 22.1.3.10 / 15.4.4.18 Array.prototype.forEach(callbackfn [, thisArg])
  forEach: function forEach(callbackfn /* , thisArg */) {
    return $forEach(this, callbackfn, arguments[1]);
  }
});

},{"./_array-methods":19,"./_export":39,"./_strict-method":101}],134:[function(require,module,exports){
'use strict';
var ctx = require('./_ctx');
var $export = require('./_export');
var toObject = require('./_to-object');
var call = require('./_iter-call');
var isArrayIter = require('./_is-array-iter');
var toLength = require('./_to-length');
var createProperty = require('./_create-property');
var getIterFn = require('./core.get-iterator-method');

$export($export.S + $export.F * !require('./_iter-detect')(function (iter) { Array.from(iter); }), 'Array', {
  // 22.1.2.1 Array.from(arrayLike, mapfn = undefined, thisArg = undefined)
  from: function from(arrayLike /* , mapfn = undefined, thisArg = undefined */) {
    var O = toObject(arrayLike);
    var C = typeof this == 'function' ? this : Array;
    var aLen = arguments.length;
    var mapfn = aLen > 1 ? arguments[1] : undefined;
    var mapping = mapfn !== undefined;
    var index = 0;
    var iterFn = getIterFn(O);
    var length, result, step, iterator;
    if (mapping) mapfn = ctx(mapfn, aLen > 2 ? arguments[2] : undefined, 2);
    // if object isn't iterable or it's array with default iterator - use simple case
    if (iterFn != undefined && !(C == Array && isArrayIter(iterFn))) {
      for (iterator = iterFn.call(O), result = new C(); !(step = iterator.next()).done; index++) {
        createProperty(result, index, mapping ? call(iterator, mapfn, [step.value, index], true) : step.value);
      }
    } else {
      length = toLength(O.length);
      for (result = new C(length); length > index; index++) {
        createProperty(result, index, mapping ? mapfn(O[index], index) : O[index]);
      }
    }
    result.length = index;
    return result;
  }
});

},{"./_create-property":30,"./_ctx":31,"./_export":39,"./_is-array-iter":53,"./_iter-call":58,"./_iter-detect":61,"./_to-length":114,"./_to-object":115,"./core.get-iterator-method":126}],135:[function(require,module,exports){
'use strict';
var $export = require('./_export');
var $indexOf = require('./_array-includes')(false);
var $native = [].indexOf;
var NEGATIVE_ZERO = !!$native && 1 / [1].indexOf(1, -0) < 0;

$export($export.P + $export.F * (NEGATIVE_ZERO || !require('./_strict-method')($native)), 'Array', {
  // 22.1.3.11 / 15.4.4.14 Array.prototype.indexOf(searchElement [, fromIndex])
  indexOf: function indexOf(searchElement /* , fromIndex = 0 */) {
    return NEGATIVE_ZERO
      // convert -0 to +0
      ? $native.apply(this, arguments) || 0
      : $indexOf(this, searchElement, arguments[1]);
  }
});

},{"./_array-includes":18,"./_export":39,"./_strict-method":101}],136:[function(require,module,exports){
// 22.1.2.2 / 15.4.3.2 Array.isArray(arg)
var $export = require('./_export');

$export($export.S, 'Array', { isArray: require('./_is-array') });

},{"./_export":39,"./_is-array":54}],137:[function(require,module,exports){
'use strict';
var addToUnscopables = require('./_add-to-unscopables');
var step = require('./_iter-step');
var Iterators = require('./_iterators');
var toIObject = require('./_to-iobject');

// 22.1.3.4 Array.prototype.entries()
// 22.1.3.13 Array.prototype.keys()
// 22.1.3.29 Array.prototype.values()
// 22.1.3.30 Array.prototype[@@iterator]()
module.exports = require('./_iter-define')(Array, 'Array', function (iterated, kind) {
  this._t = toIObject(iterated); // target
  this._i = 0;                   // next index
  this._k = kind;                // kind
// 22.1.5.2.1 %ArrayIteratorPrototype%.next()
}, function () {
  var O = this._t;
  var kind = this._k;
  var index = this._i++;
  if (!O || index >= O.length) {
    this._t = undefined;
    return step(1);
  }
  if (kind == 'keys') return step(0, index);
  if (kind == 'values') return step(0, O[index]);
  return step(0, [index, O[index]]);
}, 'values');

// argumentsList[@@iterator] is %ArrayProto_values% (9.4.4.6, 9.4.4.7)
Iterators.Arguments = Iterators.Array;

addToUnscopables('keys');
addToUnscopables('values');
addToUnscopables('entries');

},{"./_add-to-unscopables":13,"./_iter-define":60,"./_iter-step":62,"./_iterators":63,"./_to-iobject":113}],138:[function(require,module,exports){
'use strict';
// 22.1.3.13 Array.prototype.join(separator)
var $export = require('./_export');
var toIObject = require('./_to-iobject');
var arrayJoin = [].join;

// fallback for not array-like strings
$export($export.P + $export.F * (require('./_iobject') != Object || !require('./_strict-method')(arrayJoin)), 'Array', {
  join: function join(separator) {
    return arrayJoin.call(toIObject(this), separator === undefined ? ',' : separator);
  }
});

},{"./_export":39,"./_iobject":52,"./_strict-method":101,"./_to-iobject":113}],139:[function(require,module,exports){
'use strict';
var $export = require('./_export');
var toIObject = require('./_to-iobject');
var toInteger = require('./_to-integer');
var toLength = require('./_to-length');
var $native = [].lastIndexOf;
var NEGATIVE_ZERO = !!$native && 1 / [1].lastIndexOf(1, -0) < 0;

$export($export.P + $export.F * (NEGATIVE_ZERO || !require('./_strict-method')($native)), 'Array', {
  // 22.1.3.14 / 15.4.4.15 Array.prototype.lastIndexOf(searchElement [, fromIndex])
  lastIndexOf: function lastIndexOf(searchElement /* , fromIndex = @[*-1] */) {
    // convert -0 to +0
    if (NEGATIVE_ZERO) return $native.apply(this, arguments) || 0;
    var O = toIObject(this);
    var length = toLength(O.length);
    var index = length - 1;
    if (arguments.length > 1) index = Math.min(index, toInteger(arguments[1]));
    if (index < 0) index = length + index;
    for (;index >= 0; index--) if (index in O) if (O[index] === searchElement) return index || 0;
    return -1;
  }
});

},{"./_export":39,"./_strict-method":101,"./_to-integer":112,"./_to-iobject":113,"./_to-length":114}],140:[function(require,module,exports){
'use strict';
var $export = require('./_export');
var $map = require('./_array-methods')(1);

$export($export.P + $export.F * !require('./_strict-method')([].map, true), 'Array', {
  // 22.1.3.15 / 15.4.4.19 Array.prototype.map(callbackfn [, thisArg])
  map: function map(callbackfn /* , thisArg */) {
    return $map(this, callbackfn, arguments[1]);
  }
});

},{"./_array-methods":19,"./_export":39,"./_strict-method":101}],141:[function(require,module,exports){
'use strict';
var $export = require('./_export');
var createProperty = require('./_create-property');

// WebKit Array.of isn't generic
$export($export.S + $export.F * require('./_fails')(function () {
  function F() { /* empty */ }
  return !(Array.of.call(F) instanceof F);
}), 'Array', {
  // 22.1.2.3 Array.of( ...items)
  of: function of(/* ...args */) {
    var index = 0;
    var aLen = arguments.length;
    var result = new (typeof this == 'function' ? this : Array)(aLen);
    while (aLen > index) createProperty(result, index, arguments[index++]);
    result.length = aLen;
    return result;
  }
});

},{"./_create-property":30,"./_export":39,"./_fails":41}],142:[function(require,module,exports){
'use strict';
var $export = require('./_export');
var $reduce = require('./_array-reduce');

$export($export.P + $export.F * !require('./_strict-method')([].reduceRight, true), 'Array', {
  // 22.1.3.19 / 15.4.4.22 Array.prototype.reduceRight(callbackfn [, initialValue])
  reduceRight: function reduceRight(callbackfn /* , initialValue */) {
    return $reduce(this, callbackfn, arguments.length, arguments[1], true);
  }
});

},{"./_array-reduce":20,"./_export":39,"./_strict-method":101}],143:[function(require,module,exports){
'use strict';
var $export = require('./_export');
var $reduce = require('./_array-reduce');

$export($export.P + $export.F * !require('./_strict-method')([].reduce, true), 'Array', {
  // 22.1.3.18 / 15.4.4.21 Array.prototype.reduce(callbackfn [, initialValue])
  reduce: function reduce(callbackfn /* , initialValue */) {
    return $reduce(this, callbackfn, arguments.length, arguments[1], false);
  }
});

},{"./_array-reduce":20,"./_export":39,"./_strict-method":101}],144:[function(require,module,exports){
'use strict';
var $export = require('./_export');
var html = require('./_html');
var cof = require('./_cof');
var toAbsoluteIndex = require('./_to-absolute-index');
var toLength = require('./_to-length');
var arraySlice = [].slice;

// fallback for not array-like ES3 strings and DOM objects
$export($export.P + $export.F * require('./_fails')(function () {
  if (html) arraySlice.call(html);
}), 'Array', {
  slice: function slice(begin, end) {
    var len = toLength(this.length);
    var klass = cof(this);
    end = end === undefined ? len : end;
    if (klass == 'Array') return arraySlice.call(this, begin, end);
    var start = toAbsoluteIndex(begin, len);
    var upTo = toAbsoluteIndex(end, len);
    var size = toLength(upTo - start);
    var cloned = new Array(size);
    var i = 0;
    for (; i < size; i++) cloned[i] = klass == 'String'
      ? this.charAt(start + i)
      : this[start + i];
    return cloned;
  }
});

},{"./_cof":25,"./_export":39,"./_fails":41,"./_html":48,"./_to-absolute-index":110,"./_to-length":114}],145:[function(require,module,exports){
'use strict';
var $export = require('./_export');
var $some = require('./_array-methods')(3);

$export($export.P + $export.F * !require('./_strict-method')([].some, true), 'Array', {
  // 22.1.3.23 / 15.4.4.17 Array.prototype.some(callbackfn [, thisArg])
  some: function some(callbackfn /* , thisArg */) {
    return $some(this, callbackfn, arguments[1]);
  }
});

},{"./_array-methods":19,"./_export":39,"./_strict-method":101}],146:[function(require,module,exports){
'use strict';
var $export = require('./_export');
var aFunction = require('./_a-function');
var toObject = require('./_to-object');
var fails = require('./_fails');
var $sort = [].sort;
var test = [1, 2, 3];

$export($export.P + $export.F * (fails(function () {
  // IE8-
  test.sort(undefined);
}) || !fails(function () {
  // V8 bug
  test.sort(null);
  // Old WebKit
}) || !require('./_strict-method')($sort)), 'Array', {
  // 22.1.3.25 Array.prototype.sort(comparefn)
  sort: function sort(comparefn) {
    return comparefn === undefined
      ? $sort.call(toObject(this))
      : $sort.call(toObject(this), aFunction(comparefn));
  }
});

},{"./_a-function":11,"./_export":39,"./_fails":41,"./_strict-method":101,"./_to-object":115}],147:[function(require,module,exports){
require('./_set-species')('Array');

},{"./_set-species":96}],148:[function(require,module,exports){
// 20.3.3.1 / 15.9.4.4 Date.now()
var $export = require('./_export');

$export($export.S, 'Date', { now: function () { return new Date().getTime(); } });

},{"./_export":39}],149:[function(require,module,exports){
// 20.3.4.36 / 15.9.5.43 Date.prototype.toISOString()
var $export = require('./_export');
var toISOString = require('./_date-to-iso-string');

// PhantomJS / old WebKit has a broken implementations
$export($export.P + $export.F * (Date.prototype.toISOString !== toISOString), 'Date', {
  toISOString: toISOString
});

},{"./_date-to-iso-string":32,"./_export":39}],150:[function(require,module,exports){
'use strict';
var $export = require('./_export');
var toObject = require('./_to-object');
var toPrimitive = require('./_to-primitive');

$export($export.P + $export.F * require('./_fails')(function () {
  return new Date(NaN).toJSON() !== null
    || Date.prototype.toJSON.call({ toISOString: function () { return 1; } }) !== 1;
}), 'Date', {
  // eslint-disable-next-line no-unused-vars
  toJSON: function toJSON(key) {
    var O = toObject(this);
    var pv = toPrimitive(O);
    return typeof pv == 'number' && !isFinite(pv) ? null : O.toISOString();
  }
});

},{"./_export":39,"./_fails":41,"./_to-object":115,"./_to-primitive":116}],151:[function(require,module,exports){
var TO_PRIMITIVE = require('./_wks')('toPrimitive');
var proto = Date.prototype;

if (!(TO_PRIMITIVE in proto)) require('./_hide')(proto, TO_PRIMITIVE, require('./_date-to-primitive'));

},{"./_date-to-primitive":33,"./_hide":47,"./_wks":125}],152:[function(require,module,exports){
var DateProto = Date.prototype;
var INVALID_DATE = 'Invalid Date';
var TO_STRING = 'toString';
var $toString = DateProto[TO_STRING];
var getTime = DateProto.getTime;
if (new Date(NaN) + '' != INVALID_DATE) {
  require('./_redefine')(DateProto, TO_STRING, function toString() {
    var value = getTime.call(this);
    // eslint-disable-next-line no-self-compare
    return value === value ? $toString.call(this) : INVALID_DATE;
  });
}

},{"./_redefine":93}],153:[function(require,module,exports){
// 19.2.3.2 / 15.3.4.5 Function.prototype.bind(thisArg, args...)
var $export = require('./_export');

$export($export.P, 'Function', { bind: require('./_bind') });

},{"./_bind":23,"./_export":39}],154:[function(require,module,exports){
'use strict';
var isObject = require('./_is-object');
var getPrototypeOf = require('./_object-gpo');
var HAS_INSTANCE = require('./_wks')('hasInstance');
var FunctionProto = Function.prototype;
// 19.2.3.6 Function.prototype[@@hasInstance](V)
if (!(HAS_INSTANCE in FunctionProto)) require('./_object-dp').f(FunctionProto, HAS_INSTANCE, { value: function (O) {
  if (typeof this != 'function' || !isObject(O)) return false;
  if (!isObject(this.prototype)) return O instanceof this;
  // for environment w/o native `@@hasInstance` logic enough `instanceof`, but add this:
  while (O = getPrototypeOf(O)) if (this.prototype === O) return true;
  return false;
} });

},{"./_is-object":56,"./_object-dp":74,"./_object-gpo":80,"./_wks":125}],155:[function(require,module,exports){
var dP = require('./_object-dp').f;
var FProto = Function.prototype;
var nameRE = /^\s*function ([^ (]*)/;
var NAME = 'name';

// 19.2.4.2 name
NAME in FProto || require('./_descriptors') && dP(FProto, NAME, {
  configurable: true,
  get: function () {
    try {
      return ('' + this).match(nameRE)[1];
    } catch (e) {
      return '';
    }
  }
});

},{"./_descriptors":35,"./_object-dp":74}],156:[function(require,module,exports){
'use strict';
var strong = require('./_collection-strong');
var validate = require('./_validate-collection');
var MAP = 'Map';

// 23.1 Map Objects
module.exports = require('./_collection')(MAP, function (get) {
  return function Map() { return get(this, arguments.length > 0 ? arguments[0] : undefined); };
}, {
  // 23.1.3.6 Map.prototype.get(key)
  get: function get(key) {
    var entry = strong.getEntry(validate(this, MAP), key);
    return entry && entry.v;
  },
  // 23.1.3.9 Map.prototype.set(key, value)
  set: function set(key, value) {
    return strong.def(validate(this, MAP), key === 0 ? 0 : key, value);
  }
}, strong, true);

},{"./_collection":28,"./_collection-strong":26,"./_validate-collection":122}],157:[function(require,module,exports){
// 20.2.2.3 Math.acosh(x)
var $export = require('./_export');
var log1p = require('./_math-log1p');
var sqrt = Math.sqrt;
var $acosh = Math.acosh;

$export($export.S + $export.F * !($acosh
  // V8 bug: https://code.google.com/p/v8/issues/detail?id=3509
  && Math.floor($acosh(Number.MAX_VALUE)) == 710
  // Tor Browser bug: Math.acosh(Infinity) -> NaN
  && $acosh(Infinity) == Infinity
), 'Math', {
  acosh: function acosh(x) {
    return (x = +x) < 1 ? NaN : x > 94906265.62425156
      ? Math.log(x) + Math.LN2
      : log1p(x - 1 + sqrt(x - 1) * sqrt(x + 1));
  }
});

},{"./_export":39,"./_math-log1p":67}],158:[function(require,module,exports){
// 20.2.2.5 Math.asinh(x)
var $export = require('./_export');
var $asinh = Math.asinh;

function asinh(x) {
  return !isFinite(x = +x) || x == 0 ? x : x < 0 ? -asinh(-x) : Math.log(x + Math.sqrt(x * x + 1));
}

// Tor Browser bug: Math.asinh(0) -> -0
$export($export.S + $export.F * !($asinh && 1 / $asinh(0) > 0), 'Math', { asinh: asinh });

},{"./_export":39}],159:[function(require,module,exports){
// 20.2.2.7 Math.atanh(x)
var $export = require('./_export');
var $atanh = Math.atanh;

// Tor Browser bug: Math.atanh(-0) -> 0
$export($export.S + $export.F * !($atanh && 1 / $atanh(-0) < 0), 'Math', {
  atanh: function atanh(x) {
    return (x = +x) == 0 ? x : Math.log((1 + x) / (1 - x)) / 2;
  }
});

},{"./_export":39}],160:[function(require,module,exports){
// 20.2.2.9 Math.cbrt(x)
var $export = require('./_export');
var sign = require('./_math-sign');

$export($export.S, 'Math', {
  cbrt: function cbrt(x) {
    return sign(x = +x) * Math.pow(Math.abs(x), 1 / 3);
  }
});

},{"./_export":39,"./_math-sign":68}],161:[function(require,module,exports){
// 20.2.2.11 Math.clz32(x)
var $export = require('./_export');

$export($export.S, 'Math', {
  clz32: function clz32(x) {
    return (x >>>= 0) ? 31 - Math.floor(Math.log(x + 0.5) * Math.LOG2E) : 32;
  }
});

},{"./_export":39}],162:[function(require,module,exports){
// 20.2.2.12 Math.cosh(x)
var $export = require('./_export');
var exp = Math.exp;

$export($export.S, 'Math', {
  cosh: function cosh(x) {
    return (exp(x = +x) + exp(-x)) / 2;
  }
});

},{"./_export":39}],163:[function(require,module,exports){
// 20.2.2.14 Math.expm1(x)
var $export = require('./_export');
var $expm1 = require('./_math-expm1');

$export($export.S + $export.F * ($expm1 != Math.expm1), 'Math', { expm1: $expm1 });

},{"./_export":39,"./_math-expm1":65}],164:[function(require,module,exports){
// 20.2.2.16 Math.fround(x)
var $export = require('./_export');

$export($export.S, 'Math', { fround: require('./_math-fround') });

},{"./_export":39,"./_math-fround":66}],165:[function(require,module,exports){
// 20.2.2.17 Math.hypot([value1[, value2[, … ]]])
var $export = require('./_export');
var abs = Math.abs;

$export($export.S, 'Math', {
  hypot: function hypot(value1, value2) { // eslint-disable-line no-unused-vars
    var sum = 0;
    var i = 0;
    var aLen = arguments.length;
    var larg = 0;
    var arg, div;
    while (i < aLen) {
      arg = abs(arguments[i++]);
      if (larg < arg) {
        div = larg / arg;
        sum = sum * div * div + 1;
        larg = arg;
      } else if (arg > 0) {
        div = arg / larg;
        sum += div * div;
      } else sum += arg;
    }
    return larg === Infinity ? Infinity : larg * Math.sqrt(sum);
  }
});

},{"./_export":39}],166:[function(require,module,exports){
// 20.2.2.18 Math.imul(x, y)
var $export = require('./_export');
var $imul = Math.imul;

// some WebKit versions fails with big numbers, some has wrong arity
$export($export.S + $export.F * require('./_fails')(function () {
  return $imul(0xffffffff, 5) != -5 || $imul.length != 2;
}), 'Math', {
  imul: function imul(x, y) {
    var UINT16 = 0xffff;
    var xn = +x;
    var yn = +y;
    var xl = UINT16 & xn;
    var yl = UINT16 & yn;
    return 0 | xl * yl + ((UINT16 & xn >>> 16) * yl + xl * (UINT16 & yn >>> 16) << 16 >>> 0);
  }
});

},{"./_export":39,"./_fails":41}],167:[function(require,module,exports){
// 20.2.2.21 Math.log10(x)
var $export = require('./_export');

$export($export.S, 'Math', {
  log10: function log10(x) {
    return Math.log(x) * Math.LOG10E;
  }
});

},{"./_export":39}],168:[function(require,module,exports){
// 20.2.2.20 Math.log1p(x)
var $export = require('./_export');

$export($export.S, 'Math', { log1p: require('./_math-log1p') });

},{"./_export":39,"./_math-log1p":67}],169:[function(require,module,exports){
// 20.2.2.22 Math.log2(x)
var $export = require('./_export');

$export($export.S, 'Math', {
  log2: function log2(x) {
    return Math.log(x) / Math.LN2;
  }
});

},{"./_export":39}],170:[function(require,module,exports){
// 20.2.2.28 Math.sign(x)
var $export = require('./_export');

$export($export.S, 'Math', { sign: require('./_math-sign') });

},{"./_export":39,"./_math-sign":68}],171:[function(require,module,exports){
// 20.2.2.30 Math.sinh(x)
var $export = require('./_export');
var expm1 = require('./_math-expm1');
var exp = Math.exp;

// V8 near Chromium 38 has a problem with very small numbers
$export($export.S + $export.F * require('./_fails')(function () {
  return !Math.sinh(-2e-17) != -2e-17;
}), 'Math', {
  sinh: function sinh(x) {
    return Math.abs(x = +x) < 1
      ? (expm1(x) - expm1(-x)) / 2
      : (exp(x - 1) - exp(-x - 1)) * (Math.E / 2);
  }
});

},{"./_export":39,"./_fails":41,"./_math-expm1":65}],172:[function(require,module,exports){
// 20.2.2.33 Math.tanh(x)
var $export = require('./_export');
var expm1 = require('./_math-expm1');
var exp = Math.exp;

$export($export.S, 'Math', {
  tanh: function tanh(x) {
    var a = expm1(x = +x);
    var b = expm1(-x);
    return a == Infinity ? 1 : b == Infinity ? -1 : (a - b) / (exp(x) + exp(-x));
  }
});

},{"./_export":39,"./_math-expm1":65}],173:[function(require,module,exports){
// 20.2.2.34 Math.trunc(x)
var $export = require('./_export');

$export($export.S, 'Math', {
  trunc: function trunc(it) {
    return (it > 0 ? Math.floor : Math.ceil)(it);
  }
});

},{"./_export":39}],174:[function(require,module,exports){
'use strict';
var global = require('./_global');
var has = require('./_has');
var cof = require('./_cof');
var inheritIfRequired = require('./_inherit-if-required');
var toPrimitive = require('./_to-primitive');
var fails = require('./_fails');
var gOPN = require('./_object-gopn').f;
var gOPD = require('./_object-gopd').f;
var dP = require('./_object-dp').f;
var $trim = require('./_string-trim').trim;
var NUMBER = 'Number';
var $Number = global[NUMBER];
var Base = $Number;
var proto = $Number.prototype;
// Opera ~12 has broken Object#toString
var BROKEN_COF = cof(require('./_object-create')(proto)) == NUMBER;
var TRIM = 'trim' in String.prototype;

// 7.1.3 ToNumber(argument)
var toNumber = function (argument) {
  var it = toPrimitive(argument, false);
  if (typeof it == 'string' && it.length > 2) {
    it = TRIM ? it.trim() : $trim(it, 3);
    var first = it.charCodeAt(0);
    var third, radix, maxCode;
    if (first === 43 || first === 45) {
      third = it.charCodeAt(2);
      if (third === 88 || third === 120) return NaN; // Number('+0x1') should be NaN, old V8 fix
    } else if (first === 48) {
      switch (it.charCodeAt(1)) {
        case 66: case 98: radix = 2; maxCode = 49; break; // fast equal /^0b[01]+$/i
        case 79: case 111: radix = 8; maxCode = 55; break; // fast equal /^0o[0-7]+$/i
        default: return +it;
      }
      for (var digits = it.slice(2), i = 0, l = digits.length, code; i < l; i++) {
        code = digits.charCodeAt(i);
        // parseInt parses a string to a first unavailable symbol
        // but ToNumber should return NaN if a string contains unavailable symbols
        if (code < 48 || code > maxCode) return NaN;
      } return parseInt(digits, radix);
    }
  } return +it;
};

if (!$Number(' 0o1') || !$Number('0b1') || $Number('+0x1')) {
  $Number = function Number(value) {
    var it = arguments.length < 1 ? 0 : value;
    var that = this;
    return that instanceof $Number
      // check on 1..constructor(foo) case
      && (BROKEN_COF ? fails(function () { proto.valueOf.call(that); }) : cof(that) != NUMBER)
        ? inheritIfRequired(new Base(toNumber(it)), that, $Number) : toNumber(it);
  };
  for (var keys = require('./_descriptors') ? gOPN(Base) : (
    // ES3:
    'MAX_VALUE,MIN_VALUE,NaN,NEGATIVE_INFINITY,POSITIVE_INFINITY,' +
    // ES6 (in case, if modules with ES6 Number statics required before):
    'EPSILON,isFinite,isInteger,isNaN,isSafeInteger,MAX_SAFE_INTEGER,' +
    'MIN_SAFE_INTEGER,parseFloat,parseInt,isInteger'
  ).split(','), j = 0, key; keys.length > j; j++) {
    if (has(Base, key = keys[j]) && !has($Number, key)) {
      dP($Number, key, gOPD(Base, key));
    }
  }
  $Number.prototype = proto;
  proto.constructor = $Number;
  require('./_redefine')(global, NUMBER, $Number);
}

},{"./_cof":25,"./_descriptors":35,"./_fails":41,"./_global":45,"./_has":46,"./_inherit-if-required":50,"./_object-create":73,"./_object-dp":74,"./_object-gopd":76,"./_object-gopn":78,"./_redefine":93,"./_string-trim":107,"./_to-primitive":116}],175:[function(require,module,exports){
// 20.1.2.1 Number.EPSILON
var $export = require('./_export');

$export($export.S, 'Number', { EPSILON: Math.pow(2, -52) });

},{"./_export":39}],176:[function(require,module,exports){
// 20.1.2.2 Number.isFinite(number)
var $export = require('./_export');
var _isFinite = require('./_global').isFinite;

$export($export.S, 'Number', {
  isFinite: function isFinite(it) {
    return typeof it == 'number' && _isFinite(it);
  }
});

},{"./_export":39,"./_global":45}],177:[function(require,module,exports){
// 20.1.2.3 Number.isInteger(number)
var $export = require('./_export');

$export($export.S, 'Number', { isInteger: require('./_is-integer') });

},{"./_export":39,"./_is-integer":55}],178:[function(require,module,exports){
// 20.1.2.4 Number.isNaN(number)
var $export = require('./_export');

$export($export.S, 'Number', {
  isNaN: function isNaN(number) {
    // eslint-disable-next-line no-self-compare
    return number != number;
  }
});

},{"./_export":39}],179:[function(require,module,exports){
// 20.1.2.5 Number.isSafeInteger(number)
var $export = require('./_export');
var isInteger = require('./_is-integer');
var abs = Math.abs;

$export($export.S, 'Number', {
  isSafeInteger: function isSafeInteger(number) {
    return isInteger(number) && abs(number) <= 0x1fffffffffffff;
  }
});

},{"./_export":39,"./_is-integer":55}],180:[function(require,module,exports){
// 20.1.2.6 Number.MAX_SAFE_INTEGER
var $export = require('./_export');

$export($export.S, 'Number', { MAX_SAFE_INTEGER: 0x1fffffffffffff });

},{"./_export":39}],181:[function(require,module,exports){
// 20.1.2.10 Number.MIN_SAFE_INTEGER
var $export = require('./_export');

$export($export.S, 'Number', { MIN_SAFE_INTEGER: -0x1fffffffffffff });

},{"./_export":39}],182:[function(require,module,exports){
var $export = require('./_export');
var $parseFloat = require('./_parse-float');
// 20.1.2.12 Number.parseFloat(string)
$export($export.S + $export.F * (Number.parseFloat != $parseFloat), 'Number', { parseFloat: $parseFloat });

},{"./_export":39,"./_parse-float":87}],183:[function(require,module,exports){
var $export = require('./_export');
var $parseInt = require('./_parse-int');
// 20.1.2.13 Number.parseInt(string, radix)
$export($export.S + $export.F * (Number.parseInt != $parseInt), 'Number', { parseInt: $parseInt });

},{"./_export":39,"./_parse-int":88}],184:[function(require,module,exports){
'use strict';
var $export = require('./_export');
var toInteger = require('./_to-integer');
var aNumberValue = require('./_a-number-value');
var repeat = require('./_string-repeat');
var $toFixed = 1.0.toFixed;
var floor = Math.floor;
var data = [0, 0, 0, 0, 0, 0];
var ERROR = 'Number.toFixed: incorrect invocation!';
var ZERO = '0';

var multiply = function (n, c) {
  var i = -1;
  var c2 = c;
  while (++i < 6) {
    c2 += n * data[i];
    data[i] = c2 % 1e7;
    c2 = floor(c2 / 1e7);
  }
};
var divide = function (n) {
  var i = 6;
  var c = 0;
  while (--i >= 0) {
    c += data[i];
    data[i] = floor(c / n);
    c = (c % n) * 1e7;
  }
};
var numToString = function () {
  var i = 6;
  var s = '';
  while (--i >= 0) {
    if (s !== '' || i === 0 || data[i] !== 0) {
      var t = String(data[i]);
      s = s === '' ? t : s + repeat.call(ZERO, 7 - t.length) + t;
    }
  } return s;
};
var pow = function (x, n, acc) {
  return n === 0 ? acc : n % 2 === 1 ? pow(x, n - 1, acc * x) : pow(x * x, n / 2, acc);
};
var log = function (x) {
  var n = 0;
  var x2 = x;
  while (x2 >= 4096) {
    n += 12;
    x2 /= 4096;
  }
  while (x2 >= 2) {
    n += 1;
    x2 /= 2;
  } return n;
};

$export($export.P + $export.F * (!!$toFixed && (
  0.00008.toFixed(3) !== '0.000' ||
  0.9.toFixed(0) !== '1' ||
  1.255.toFixed(2) !== '1.25' ||
  1000000000000000128.0.toFixed(0) !== '1000000000000000128'
) || !require('./_fails')(function () {
  // V8 ~ Android 4.3-
  $toFixed.call({});
})), 'Number', {
  toFixed: function toFixed(fractionDigits) {
    var x = aNumberValue(this, ERROR);
    var f = toInteger(fractionDigits);
    var s = '';
    var m = ZERO;
    var e, z, j, k;
    if (f < 0 || f > 20) throw RangeError(ERROR);
    // eslint-disable-next-line no-self-compare
    if (x != x) return 'NaN';
    if (x <= -1e21 || x >= 1e21) return String(x);
    if (x < 0) {
      s = '-';
      x = -x;
    }
    if (x > 1e-21) {
      e = log(x * pow(2, 69, 1)) - 69;
      z = e < 0 ? x * pow(2, -e, 1) : x / pow(2, e, 1);
      z *= 0x10000000000000;
      e = 52 - e;
      if (e > 0) {
        multiply(0, z);
        j = f;
        while (j >= 7) {
          multiply(1e7, 0);
          j -= 7;
        }
        multiply(pow(10, j, 1), 0);
        j = e - 1;
        while (j >= 23) {
          divide(1 << 23);
          j -= 23;
        }
        divide(1 << j);
        multiply(1, 1);
        divide(2);
        m = numToString();
      } else {
        multiply(0, z);
        multiply(1 << -e, 0);
        m = numToString() + repeat.call(ZERO, f);
      }
    }
    if (f > 0) {
      k = m.length;
      m = s + (k <= f ? '0.' + repeat.call(ZERO, f - k) + m : m.slice(0, k - f) + '.' + m.slice(k - f));
    } else {
      m = s + m;
    } return m;
  }
});

},{"./_a-number-value":12,"./_export":39,"./_fails":41,"./_string-repeat":106,"./_to-integer":112}],185:[function(require,module,exports){
'use strict';
var $export = require('./_export');
var $fails = require('./_fails');
var aNumberValue = require('./_a-number-value');
var $toPrecision = 1.0.toPrecision;

$export($export.P + $export.F * ($fails(function () {
  // IE7-
  return $toPrecision.call(1, undefined) !== '1';
}) || !$fails(function () {
  // V8 ~ Android 4.3-
  $toPrecision.call({});
})), 'Number', {
  toPrecision: function toPrecision(precision) {
    var that = aNumberValue(this, 'Number#toPrecision: incorrect invocation!');
    return precision === undefined ? $toPrecision.call(that) : $toPrecision.call(that, precision);
  }
});

},{"./_a-number-value":12,"./_export":39,"./_fails":41}],186:[function(require,module,exports){
// 19.1.3.1 Object.assign(target, source)
var $export = require('./_export');

$export($export.S + $export.F, 'Object', { assign: require('./_object-assign') });

},{"./_export":39,"./_object-assign":72}],187:[function(require,module,exports){
var $export = require('./_export');
// 19.1.2.2 / 15.2.3.5 Object.create(O [, Properties])
$export($export.S, 'Object', { create: require('./_object-create') });

},{"./_export":39,"./_object-create":73}],188:[function(require,module,exports){
var $export = require('./_export');
// 19.1.2.3 / 15.2.3.7 Object.defineProperties(O, Properties)
$export($export.S + $export.F * !require('./_descriptors'), 'Object', { defineProperties: require('./_object-dps') });

},{"./_descriptors":35,"./_export":39,"./_object-dps":75}],189:[function(require,module,exports){
var $export = require('./_export');
// 19.1.2.4 / 15.2.3.6 Object.defineProperty(O, P, Attributes)
$export($export.S + $export.F * !require('./_descriptors'), 'Object', { defineProperty: require('./_object-dp').f });

},{"./_descriptors":35,"./_export":39,"./_object-dp":74}],190:[function(require,module,exports){
// 19.1.2.5 Object.freeze(O)
var isObject = require('./_is-object');
var meta = require('./_meta').onFreeze;

require('./_object-sap')('freeze', function ($freeze) {
  return function freeze(it) {
    return $freeze && isObject(it) ? $freeze(meta(it)) : it;
  };
});

},{"./_is-object":56,"./_meta":69,"./_object-sap":84}],191:[function(require,module,exports){
// 19.1.2.6 Object.getOwnPropertyDescriptor(O, P)
var toIObject = require('./_to-iobject');
var $getOwnPropertyDescriptor = require('./_object-gopd').f;

require('./_object-sap')('getOwnPropertyDescriptor', function () {
  return function getOwnPropertyDescriptor(it, key) {
    return $getOwnPropertyDescriptor(toIObject(it), key);
  };
});

},{"./_object-gopd":76,"./_object-sap":84,"./_to-iobject":113}],192:[function(require,module,exports){
// 19.1.2.7 Object.getOwnPropertyNames(O)
require('./_object-sap')('getOwnPropertyNames', function () {
  return require('./_object-gopn-ext').f;
});

},{"./_object-gopn-ext":77,"./_object-sap":84}],193:[function(require,module,exports){
// 19.1.2.9 Object.getPrototypeOf(O)
var toObject = require('./_to-object');
var $getPrototypeOf = require('./_object-gpo');

require('./_object-sap')('getPrototypeOf', function () {
  return function getPrototypeOf(it) {
    return $getPrototypeOf(toObject(it));
  };
});

},{"./_object-gpo":80,"./_object-sap":84,"./_to-object":115}],194:[function(require,module,exports){
// 19.1.2.11 Object.isExtensible(O)
var isObject = require('./_is-object');

require('./_object-sap')('isExtensible', function ($isExtensible) {
  return function isExtensible(it) {
    return isObject(it) ? $isExtensible ? $isExtensible(it) : true : false;
  };
});

},{"./_is-object":56,"./_object-sap":84}],195:[function(require,module,exports){
// 19.1.2.12 Object.isFrozen(O)
var isObject = require('./_is-object');

require('./_object-sap')('isFrozen', function ($isFrozen) {
  return function isFrozen(it) {
    return isObject(it) ? $isFrozen ? $isFrozen(it) : false : true;
  };
});

},{"./_is-object":56,"./_object-sap":84}],196:[function(require,module,exports){
// 19.1.2.13 Object.isSealed(O)
var isObject = require('./_is-object');

require('./_object-sap')('isSealed', function ($isSealed) {
  return function isSealed(it) {
    return isObject(it) ? $isSealed ? $isSealed(it) : false : true;
  };
});

},{"./_is-object":56,"./_object-sap":84}],197:[function(require,module,exports){
// 19.1.3.10 Object.is(value1, value2)
var $export = require('./_export');
$export($export.S, 'Object', { is: require('./_same-value') });

},{"./_export":39,"./_same-value":94}],198:[function(require,module,exports){
// 19.1.2.14 Object.keys(O)
var toObject = require('./_to-object');
var $keys = require('./_object-keys');

require('./_object-sap')('keys', function () {
  return function keys(it) {
    return $keys(toObject(it));
  };
});

},{"./_object-keys":82,"./_object-sap":84,"./_to-object":115}],199:[function(require,module,exports){
// 19.1.2.15 Object.preventExtensions(O)
var isObject = require('./_is-object');
var meta = require('./_meta').onFreeze;

require('./_object-sap')('preventExtensions', function ($preventExtensions) {
  return function preventExtensions(it) {
    return $preventExtensions && isObject(it) ? $preventExtensions(meta(it)) : it;
  };
});

},{"./_is-object":56,"./_meta":69,"./_object-sap":84}],200:[function(require,module,exports){
// 19.1.2.17 Object.seal(O)
var isObject = require('./_is-object');
var meta = require('./_meta').onFreeze;

require('./_object-sap')('seal', function ($seal) {
  return function seal(it) {
    return $seal && isObject(it) ? $seal(meta(it)) : it;
  };
});

},{"./_is-object":56,"./_meta":69,"./_object-sap":84}],201:[function(require,module,exports){
// 19.1.3.19 Object.setPrototypeOf(O, proto)
var $export = require('./_export');
$export($export.S, 'Object', { setPrototypeOf: require('./_set-proto').set });

},{"./_export":39,"./_set-proto":95}],202:[function(require,module,exports){
'use strict';
// 19.1.3.6 Object.prototype.toString()
var classof = require('./_classof');
var test = {};
test[require('./_wks')('toStringTag')] = 'z';
if (test + '' != '[object z]') {
  require('./_redefine')(Object.prototype, 'toString', function toString() {
    return '[object ' + classof(this) + ']';
  }, true);
}

},{"./_classof":24,"./_redefine":93,"./_wks":125}],203:[function(require,module,exports){
var $export = require('./_export');
var $parseFloat = require('./_parse-float');
// 18.2.4 parseFloat(string)
$export($export.G + $export.F * (parseFloat != $parseFloat), { parseFloat: $parseFloat });

},{"./_export":39,"./_parse-float":87}],204:[function(require,module,exports){
var $export = require('./_export');
var $parseInt = require('./_parse-int');
// 18.2.5 parseInt(string, radix)
$export($export.G + $export.F * (parseInt != $parseInt), { parseInt: $parseInt });

},{"./_export":39,"./_parse-int":88}],205:[function(require,module,exports){
'use strict';
var LIBRARY = require('./_library');
var global = require('./_global');
var ctx = require('./_ctx');
var classof = require('./_classof');
var $export = require('./_export');
var isObject = require('./_is-object');
var aFunction = require('./_a-function');
var anInstance = require('./_an-instance');
var forOf = require('./_for-of');
var speciesConstructor = require('./_species-constructor');
var task = require('./_task').set;
var microtask = require('./_microtask')();
var newPromiseCapabilityModule = require('./_new-promise-capability');
var perform = require('./_perform');
var userAgent = require('./_user-agent');
var promiseResolve = require('./_promise-resolve');
var PROMISE = 'Promise';
var TypeError = global.TypeError;
var process = global.process;
var versions = process && process.versions;
var v8 = versions && versions.v8 || '';
var $Promise = global[PROMISE];
var isNode = classof(process) == 'process';
var empty = function () { /* empty */ };
var Internal, newGenericPromiseCapability, OwnPromiseCapability, Wrapper;
var newPromiseCapability = newGenericPromiseCapability = newPromiseCapabilityModule.f;

var USE_NATIVE = !!function () {
  try {
    // correct subclassing with @@species support
    var promise = $Promise.resolve(1);
    var FakePromise = (promise.constructor = {})[require('./_wks')('species')] = function (exec) {
      exec(empty, empty);
    };
    // unhandled rejections tracking support, NodeJS Promise without it fails @@species test
    return (isNode || typeof PromiseRejectionEvent == 'function')
      && promise.then(empty) instanceof FakePromise
      // v8 6.6 (Node 10 and Chrome 66) have a bug with resolving custom thenables
      // https://bugs.chromium.org/p/chromium/issues/detail?id=830565
      // we can't detect it synchronously, so just check versions
      && v8.indexOf('6.6') !== 0
      && userAgent.indexOf('Chrome/66') === -1;
  } catch (e) { /* empty */ }
}();

// helpers
var isThenable = function (it) {
  var then;
  return isObject(it) && typeof (then = it.then) == 'function' ? then : false;
};
var notify = function (promise, isReject) {
  if (promise._n) return;
  promise._n = true;
  var chain = promise._c;
  microtask(function () {
    var value = promise._v;
    var ok = promise._s == 1;
    var i = 0;
    var run = function (reaction) {
      var handler = ok ? reaction.ok : reaction.fail;
      var resolve = reaction.resolve;
      var reject = reaction.reject;
      var domain = reaction.domain;
      var result, then, exited;
      try {
        if (handler) {
          if (!ok) {
            if (promise._h == 2) onHandleUnhandled(promise);
            promise._h = 1;
          }
          if (handler === true) result = value;
          else {
            if (domain) domain.enter();
            result = handler(value); // may throw
            if (domain) {
              domain.exit();
              exited = true;
            }
          }
          if (result === reaction.promise) {
            reject(TypeError('Promise-chain cycle'));
          } else if (then = isThenable(result)) {
            then.call(result, resolve, reject);
          } else resolve(result);
        } else reject(value);
      } catch (e) {
        if (domain && !exited) domain.exit();
        reject(e);
      }
    };
    while (chain.length > i) run(chain[i++]); // variable length - can't use forEach
    promise._c = [];
    promise._n = false;
    if (isReject && !promise._h) onUnhandled(promise);
  });
};
var onUnhandled = function (promise) {
  task.call(global, function () {
    var value = promise._v;
    var unhandled = isUnhandled(promise);
    var result, handler, console;
    if (unhandled) {
      result = perform(function () {
        if (isNode) {
          process.emit('unhandledRejection', value, promise);
        } else if (handler = global.onunhandledrejection) {
          handler({ promise: promise, reason: value });
        } else if ((console = global.console) && console.error) {
          console.error('Unhandled promise rejection', value);
        }
      });
      // Browsers should not trigger `rejectionHandled` event if it was handled here, NodeJS - should
      promise._h = isNode || isUnhandled(promise) ? 2 : 1;
    } promise._a = undefined;
    if (unhandled && result.e) throw result.v;
  });
};
var isUnhandled = function (promise) {
  return promise._h !== 1 && (promise._a || promise._c).length === 0;
};
var onHandleUnhandled = function (promise) {
  task.call(global, function () {
    var handler;
    if (isNode) {
      process.emit('rejectionHandled', promise);
    } else if (handler = global.onrejectionhandled) {
      handler({ promise: promise, reason: promise._v });
    }
  });
};
var $reject = function (value) {
  var promise = this;
  if (promise._d) return;
  promise._d = true;
  promise = promise._w || promise; // unwrap
  promise._v = value;
  promise._s = 2;
  if (!promise._a) promise._a = promise._c.slice();
  notify(promise, true);
};
var $resolve = function (value) {
  var promise = this;
  var then;
  if (promise._d) return;
  promise._d = true;
  promise = promise._w || promise; // unwrap
  try {
    if (promise === value) throw TypeError("Promise can't be resolved itself");
    if (then = isThenable(value)) {
      microtask(function () {
        var wrapper = { _w: promise, _d: false }; // wrap
        try {
          then.call(value, ctx($resolve, wrapper, 1), ctx($reject, wrapper, 1));
        } catch (e) {
          $reject.call(wrapper, e);
        }
      });
    } else {
      promise._v = value;
      promise._s = 1;
      notify(promise, false);
    }
  } catch (e) {
    $reject.call({ _w: promise, _d: false }, e); // wrap
  }
};

// constructor polyfill
if (!USE_NATIVE) {
  // 25.4.3.1 Promise(executor)
  $Promise = function Promise(executor) {
    anInstance(this, $Promise, PROMISE, '_h');
    aFunction(executor);
    Internal.call(this);
    try {
      executor(ctx($resolve, this, 1), ctx($reject, this, 1));
    } catch (err) {
      $reject.call(this, err);
    }
  };
  // eslint-disable-next-line no-unused-vars
  Internal = function Promise(executor) {
    this._c = [];             // <- awaiting reactions
    this._a = undefined;      // <- checked in isUnhandled reactions
    this._s = 0;              // <- state
    this._d = false;          // <- done
    this._v = undefined;      // <- value
    this._h = 0;              // <- rejection state, 0 - default, 1 - handled, 2 - unhandled
    this._n = false;          // <- notify
  };
  Internal.prototype = require('./_redefine-all')($Promise.prototype, {
    // 25.4.5.3 Promise.prototype.then(onFulfilled, onRejected)
    then: function then(onFulfilled, onRejected) {
      var reaction = newPromiseCapability(speciesConstructor(this, $Promise));
      reaction.ok = typeof onFulfilled == 'function' ? onFulfilled : true;
      reaction.fail = typeof onRejected == 'function' && onRejected;
      reaction.domain = isNode ? process.domain : undefined;
      this._c.push(reaction);
      if (this._a) this._a.push(reaction);
      if (this._s) notify(this, false);
      return reaction.promise;
    },
    // 25.4.5.1 Promise.prototype.catch(onRejected)
    'catch': function (onRejected) {
      return this.then(undefined, onRejected);
    }
  });
  OwnPromiseCapability = function () {
    var promise = new Internal();
    this.promise = promise;
    this.resolve = ctx($resolve, promise, 1);
    this.reject = ctx($reject, promise, 1);
  };
  newPromiseCapabilityModule.f = newPromiseCapability = function (C) {
    return C === $Promise || C === Wrapper
      ? new OwnPromiseCapability(C)
      : newGenericPromiseCapability(C);
  };
}

$export($export.G + $export.W + $export.F * !USE_NATIVE, { Promise: $Promise });
require('./_set-to-string-tag')($Promise, PROMISE);
require('./_set-species')(PROMISE);
Wrapper = require('./_core')[PROMISE];

// statics
$export($export.S + $export.F * !USE_NATIVE, PROMISE, {
  // 25.4.4.5 Promise.reject(r)
  reject: function reject(r) {
    var capability = newPromiseCapability(this);
    var $$reject = capability.reject;
    $$reject(r);
    return capability.promise;
  }
});
$export($export.S + $export.F * (LIBRARY || !USE_NATIVE), PROMISE, {
  // 25.4.4.6 Promise.resolve(x)
  resolve: function resolve(x) {
    return promiseResolve(LIBRARY && this === Wrapper ? $Promise : this, x);
  }
});
$export($export.S + $export.F * !(USE_NATIVE && require('./_iter-detect')(function (iter) {
  $Promise.all(iter)['catch'](empty);
})), PROMISE, {
  // 25.4.4.1 Promise.all(iterable)
  all: function all(iterable) {
    var C = this;
    var capability = newPromiseCapability(C);
    var resolve = capability.resolve;
    var reject = capability.reject;
    var result = perform(function () {
      var values = [];
      var index = 0;
      var remaining = 1;
      forOf(iterable, false, function (promise) {
        var $index = index++;
        var alreadyCalled = false;
        values.push(undefined);
        remaining++;
        C.resolve(promise).then(function (value) {
          if (alreadyCalled) return;
          alreadyCalled = true;
          values[$index] = value;
          --remaining || resolve(values);
        }, reject);
      });
      --remaining || resolve(values);
    });
    if (result.e) reject(result.v);
    return capability.promise;
  },
  // 25.4.4.4 Promise.race(iterable)
  race: function race(iterable) {
    var C = this;
    var capability = newPromiseCapability(C);
    var reject = capability.reject;
    var result = perform(function () {
      forOf(iterable, false, function (promise) {
        C.resolve(promise).then(capability.resolve, reject);
      });
    });
    if (result.e) reject(result.v);
    return capability.promise;
  }
});

},{"./_a-function":11,"./_an-instance":14,"./_classof":24,"./_core":29,"./_ctx":31,"./_export":39,"./_for-of":44,"./_global":45,"./_is-object":56,"./_iter-detect":61,"./_library":64,"./_microtask":70,"./_new-promise-capability":71,"./_perform":89,"./_promise-resolve":90,"./_redefine-all":92,"./_set-species":96,"./_set-to-string-tag":97,"./_species-constructor":100,"./_task":109,"./_user-agent":121,"./_wks":125}],206:[function(require,module,exports){
// 26.1.1 Reflect.apply(target, thisArgument, argumentsList)
var $export = require('./_export');
var aFunction = require('./_a-function');
var anObject = require('./_an-object');
var rApply = (require('./_global').Reflect || {}).apply;
var fApply = Function.apply;
// MS Edge argumentsList argument is optional
$export($export.S + $export.F * !require('./_fails')(function () {
  rApply(function () { /* empty */ });
}), 'Reflect', {
  apply: function apply(target, thisArgument, argumentsList) {
    var T = aFunction(target);
    var L = anObject(argumentsList);
    return rApply ? rApply(T, thisArgument, L) : fApply.call(T, thisArgument, L);
  }
});

},{"./_a-function":11,"./_an-object":15,"./_export":39,"./_fails":41,"./_global":45}],207:[function(require,module,exports){
// 26.1.2 Reflect.construct(target, argumentsList [, newTarget])
var $export = require('./_export');
var create = require('./_object-create');
var aFunction = require('./_a-function');
var anObject = require('./_an-object');
var isObject = require('./_is-object');
var fails = require('./_fails');
var bind = require('./_bind');
var rConstruct = (require('./_global').Reflect || {}).construct;

// MS Edge supports only 2 arguments and argumentsList argument is optional
// FF Nightly sets third argument as `new.target`, but does not create `this` from it
var NEW_TARGET_BUG = fails(function () {
  function F() { /* empty */ }
  return !(rConstruct(function () { /* empty */ }, [], F) instanceof F);
});
var ARGS_BUG = !fails(function () {
  rConstruct(function () { /* empty */ });
});

$export($export.S + $export.F * (NEW_TARGET_BUG || ARGS_BUG), 'Reflect', {
  construct: function construct(Target, args /* , newTarget */) {
    aFunction(Target);
    anObject(args);
    var newTarget = arguments.length < 3 ? Target : aFunction(arguments[2]);
    if (ARGS_BUG && !NEW_TARGET_BUG) return rConstruct(Target, args, newTarget);
    if (Target == newTarget) {
      // w/o altered newTarget, optimization for 0-4 arguments
      switch (args.length) {
        case 0: return new Target();
        case 1: return new Target(args[0]);
        case 2: return new Target(args[0], args[1]);
        case 3: return new Target(args[0], args[1], args[2]);
        case 4: return new Target(args[0], args[1], args[2], args[3]);
      }
      // w/o altered newTarget, lot of arguments case
      var $args = [null];
      $args.push.apply($args, args);
      return new (bind.apply(Target, $args))();
    }
    // with altered newTarget, not support built-in constructors
    var proto = newTarget.prototype;
    var instance = create(isObject(proto) ? proto : Object.prototype);
    var result = Function.apply.call(Target, instance, args);
    return isObject(result) ? result : instance;
  }
});

},{"./_a-function":11,"./_an-object":15,"./_bind":23,"./_export":39,"./_fails":41,"./_global":45,"./_is-object":56,"./_object-create":73}],208:[function(require,module,exports){
// 26.1.3 Reflect.defineProperty(target, propertyKey, attributes)
var dP = require('./_object-dp');
var $export = require('./_export');
var anObject = require('./_an-object');
var toPrimitive = require('./_to-primitive');

// MS Edge has broken Reflect.defineProperty - throwing instead of returning false
$export($export.S + $export.F * require('./_fails')(function () {
  // eslint-disable-next-line no-undef
  Reflect.defineProperty(dP.f({}, 1, { value: 1 }), 1, { value: 2 });
}), 'Reflect', {
  defineProperty: function defineProperty(target, propertyKey, attributes) {
    anObject(target);
    propertyKey = toPrimitive(propertyKey, true);
    anObject(attributes);
    try {
      dP.f(target, propertyKey, attributes);
      return true;
    } catch (e) {
      return false;
    }
  }
});

},{"./_an-object":15,"./_export":39,"./_fails":41,"./_object-dp":74,"./_to-primitive":116}],209:[function(require,module,exports){
// 26.1.4 Reflect.deleteProperty(target, propertyKey)
var $export = require('./_export');
var gOPD = require('./_object-gopd').f;
var anObject = require('./_an-object');

$export($export.S, 'Reflect', {
  deleteProperty: function deleteProperty(target, propertyKey) {
    var desc = gOPD(anObject(target), propertyKey);
    return desc && !desc.configurable ? false : delete target[propertyKey];
  }
});

},{"./_an-object":15,"./_export":39,"./_object-gopd":76}],210:[function(require,module,exports){
'use strict';
// 26.1.5 Reflect.enumerate(target)
var $export = require('./_export');
var anObject = require('./_an-object');
var Enumerate = function (iterated) {
  this._t = anObject(iterated); // target
  this._i = 0;                  // next index
  var keys = this._k = [];      // keys
  var key;
  for (key in iterated) keys.push(key);
};
require('./_iter-create')(Enumerate, 'Object', function () {
  var that = this;
  var keys = that._k;
  var key;
  do {
    if (that._i >= keys.length) return { value: undefined, done: true };
  } while (!((key = keys[that._i++]) in that._t));
  return { value: key, done: false };
});

$export($export.S, 'Reflect', {
  enumerate: function enumerate(target) {
    return new Enumerate(target);
  }
});

},{"./_an-object":15,"./_export":39,"./_iter-create":59}],211:[function(require,module,exports){
// 26.1.7 Reflect.getOwnPropertyDescriptor(target, propertyKey)
var gOPD = require('./_object-gopd');
var $export = require('./_export');
var anObject = require('./_an-object');

$export($export.S, 'Reflect', {
  getOwnPropertyDescriptor: function getOwnPropertyDescriptor(target, propertyKey) {
    return gOPD.f(anObject(target), propertyKey);
  }
});

},{"./_an-object":15,"./_export":39,"./_object-gopd":76}],212:[function(require,module,exports){
// 26.1.8 Reflect.getPrototypeOf(target)
var $export = require('./_export');
var getProto = require('./_object-gpo');
var anObject = require('./_an-object');

$export($export.S, 'Reflect', {
  getPrototypeOf: function getPrototypeOf(target) {
    return getProto(anObject(target));
  }
});

},{"./_an-object":15,"./_export":39,"./_object-gpo":80}],213:[function(require,module,exports){
// 26.1.6 Reflect.get(target, propertyKey [, receiver])
var gOPD = require('./_object-gopd');
var getPrototypeOf = require('./_object-gpo');
var has = require('./_has');
var $export = require('./_export');
var isObject = require('./_is-object');
var anObject = require('./_an-object');

function get(target, propertyKey /* , receiver */) {
  var receiver = arguments.length < 3 ? target : arguments[2];
  var desc, proto;
  if (anObject(target) === receiver) return target[propertyKey];
  if (desc = gOPD.f(target, propertyKey)) return has(desc, 'value')
    ? desc.value
    : desc.get !== undefined
      ? desc.get.call(receiver)
      : undefined;
  if (isObject(proto = getPrototypeOf(target))) return get(proto, propertyKey, receiver);
}

$export($export.S, 'Reflect', { get: get });

},{"./_an-object":15,"./_export":39,"./_has":46,"./_is-object":56,"./_object-gopd":76,"./_object-gpo":80}],214:[function(require,module,exports){
// 26.1.9 Reflect.has(target, propertyKey)
var $export = require('./_export');

$export($export.S, 'Reflect', {
  has: function has(target, propertyKey) {
    return propertyKey in target;
  }
});

},{"./_export":39}],215:[function(require,module,exports){
// 26.1.10 Reflect.isExtensible(target)
var $export = require('./_export');
var anObject = require('./_an-object');
var $isExtensible = Object.isExtensible;

$export($export.S, 'Reflect', {
  isExtensible: function isExtensible(target) {
    anObject(target);
    return $isExtensible ? $isExtensible(target) : true;
  }
});

},{"./_an-object":15,"./_export":39}],216:[function(require,module,exports){
// 26.1.11 Reflect.ownKeys(target)
var $export = require('./_export');

$export($export.S, 'Reflect', { ownKeys: require('./_own-keys') });

},{"./_export":39,"./_own-keys":86}],217:[function(require,module,exports){
// 26.1.12 Reflect.preventExtensions(target)
var $export = require('./_export');
var anObject = require('./_an-object');
var $preventExtensions = Object.preventExtensions;

$export($export.S, 'Reflect', {
  preventExtensions: function preventExtensions(target) {
    anObject(target);
    try {
      if ($preventExtensions) $preventExtensions(target);
      return true;
    } catch (e) {
      return false;
    }
  }
});

},{"./_an-object":15,"./_export":39}],218:[function(require,module,exports){
// 26.1.14 Reflect.setPrototypeOf(target, proto)
var $export = require('./_export');
var setProto = require('./_set-proto');

if (setProto) $export($export.S, 'Reflect', {
  setPrototypeOf: function setPrototypeOf(target, proto) {
    setProto.check(target, proto);
    try {
      setProto.set(target, proto);
      return true;
    } catch (e) {
      return false;
    }
  }
});

},{"./_export":39,"./_set-proto":95}],219:[function(require,module,exports){
// 26.1.13 Reflect.set(target, propertyKey, V [, receiver])
var dP = require('./_object-dp');
var gOPD = require('./_object-gopd');
var getPrototypeOf = require('./_object-gpo');
var has = require('./_has');
var $export = require('./_export');
var createDesc = require('./_property-desc');
var anObject = require('./_an-object');
var isObject = require('./_is-object');

function set(target, propertyKey, V /* , receiver */) {
  var receiver = arguments.length < 4 ? target : arguments[3];
  var ownDesc = gOPD.f(anObject(target), propertyKey);
  var existingDescriptor, proto;
  if (!ownDesc) {
    if (isObject(proto = getPrototypeOf(target))) {
      return set(proto, propertyKey, V, receiver);
    }
    ownDesc = createDesc(0);
  }
  if (has(ownDesc, 'value')) {
    if (ownDesc.writable === false || !isObject(receiver)) return false;
    if (existingDescriptor = gOPD.f(receiver, propertyKey)) {
      if (existingDescriptor.get || existingDescriptor.set || existingDescriptor.writable === false) return false;
      existingDescriptor.value = V;
      dP.f(receiver, propertyKey, existingDescriptor);
    } else dP.f(receiver, propertyKey, createDesc(0, V));
    return true;
  }
  return ownDesc.set === undefined ? false : (ownDesc.set.call(receiver, V), true);
}

$export($export.S, 'Reflect', { set: set });

},{"./_an-object":15,"./_export":39,"./_has":46,"./_is-object":56,"./_object-dp":74,"./_object-gopd":76,"./_object-gpo":80,"./_property-desc":91}],220:[function(require,module,exports){
var global = require('./_global');
var inheritIfRequired = require('./_inherit-if-required');
var dP = require('./_object-dp').f;
var gOPN = require('./_object-gopn').f;
var isRegExp = require('./_is-regexp');
var $flags = require('./_flags');
var $RegExp = global.RegExp;
var Base = $RegExp;
var proto = $RegExp.prototype;
var re1 = /a/g;
var re2 = /a/g;
// "new" creates a new object, old webkit buggy here
var CORRECT_NEW = new $RegExp(re1) !== re1;

if (require('./_descriptors') && (!CORRECT_NEW || require('./_fails')(function () {
  re2[require('./_wks')('match')] = false;
  // RegExp constructor can alter flags and IsRegExp works correct with @@match
  return $RegExp(re1) != re1 || $RegExp(re2) == re2 || $RegExp(re1, 'i') != '/a/i';
}))) {
  $RegExp = function RegExp(p, f) {
    var tiRE = this instanceof $RegExp;
    var piRE = isRegExp(p);
    var fiU = f === undefined;
    return !tiRE && piRE && p.constructor === $RegExp && fiU ? p
      : inheritIfRequired(CORRECT_NEW
        ? new Base(piRE && !fiU ? p.source : p, f)
        : Base((piRE = p instanceof $RegExp) ? p.source : p, piRE && fiU ? $flags.call(p) : f)
      , tiRE ? this : proto, $RegExp);
  };
  var proxy = function (key) {
    key in $RegExp || dP($RegExp, key, {
      configurable: true,
      get: function () { return Base[key]; },
      set: function (it) { Base[key] = it; }
    });
  };
  for (var keys = gOPN(Base), i = 0; keys.length > i;) proxy(keys[i++]);
  proto.constructor = $RegExp;
  $RegExp.prototype = proto;
  require('./_redefine')(global, 'RegExp', $RegExp);
}

require('./_set-species')('RegExp');

},{"./_descriptors":35,"./_fails":41,"./_flags":43,"./_global":45,"./_inherit-if-required":50,"./_is-regexp":57,"./_object-dp":74,"./_object-gopn":78,"./_redefine":93,"./_set-species":96,"./_wks":125}],221:[function(require,module,exports){
// 21.2.5.3 get RegExp.prototype.flags()
if (require('./_descriptors') && /./g.flags != 'g') require('./_object-dp').f(RegExp.prototype, 'flags', {
  configurable: true,
  get: require('./_flags')
});

},{"./_descriptors":35,"./_flags":43,"./_object-dp":74}],222:[function(require,module,exports){
// @@match logic
require('./_fix-re-wks')('match', 1, function (defined, MATCH, $match) {
  // 21.1.3.11 String.prototype.match(regexp)
  return [function match(regexp) {
    'use strict';
    var O = defined(this);
    var fn = regexp == undefined ? undefined : regexp[MATCH];
    return fn !== undefined ? fn.call(regexp, O) : new RegExp(regexp)[MATCH](String(O));
  }, $match];
});

},{"./_fix-re-wks":42}],223:[function(require,module,exports){
// @@replace logic
require('./_fix-re-wks')('replace', 2, function (defined, REPLACE, $replace) {
  // 21.1.3.14 String.prototype.replace(searchValue, replaceValue)
  return [function replace(searchValue, replaceValue) {
    'use strict';
    var O = defined(this);
    var fn = searchValue == undefined ? undefined : searchValue[REPLACE];
    return fn !== undefined
      ? fn.call(searchValue, O, replaceValue)
      : $replace.call(String(O), searchValue, replaceValue);
  }, $replace];
});

},{"./_fix-re-wks":42}],224:[function(require,module,exports){
// @@search logic
require('./_fix-re-wks')('search', 1, function (defined, SEARCH, $search) {
  // 21.1.3.15 String.prototype.search(regexp)
  return [function search(regexp) {
    'use strict';
    var O = defined(this);
    var fn = regexp == undefined ? undefined : regexp[SEARCH];
    return fn !== undefined ? fn.call(regexp, O) : new RegExp(regexp)[SEARCH](String(O));
  }, $search];
});

},{"./_fix-re-wks":42}],225:[function(require,module,exports){
// @@split logic
require('./_fix-re-wks')('split', 2, function (defined, SPLIT, $split) {
  'use strict';
  var isRegExp = require('./_is-regexp');
  var _split = $split;
  var $push = [].push;
  var $SPLIT = 'split';
  var LENGTH = 'length';
  var LAST_INDEX = 'lastIndex';
  if (
    'abbc'[$SPLIT](/(b)*/)[1] == 'c' ||
    'test'[$SPLIT](/(?:)/, -1)[LENGTH] != 4 ||
    'ab'[$SPLIT](/(?:ab)*/)[LENGTH] != 2 ||
    '.'[$SPLIT](/(.?)(.?)/)[LENGTH] != 4 ||
    '.'[$SPLIT](/()()/)[LENGTH] > 1 ||
    ''[$SPLIT](/.?/)[LENGTH]
  ) {
    var NPCG = /()??/.exec('')[1] === undefined; // nonparticipating capturing group
    // based on es5-shim implementation, need to rework it
    $split = function (separator, limit) {
      var string = String(this);
      if (separator === undefined && limit === 0) return [];
      // If `separator` is not a regex, use native split
      if (!isRegExp(separator)) return _split.call(string, separator, limit);
      var output = [];
      var flags = (separator.ignoreCase ? 'i' : '') +
                  (separator.multiline ? 'm' : '') +
                  (separator.unicode ? 'u' : '') +
                  (separator.sticky ? 'y' : '');
      var lastLastIndex = 0;
      var splitLimit = limit === undefined ? 4294967295 : limit >>> 0;
      // Make `global` and avoid `lastIndex` issues by working with a copy
      var separatorCopy = new RegExp(separator.source, flags + 'g');
      var separator2, match, lastIndex, lastLength, i;
      // Doesn't need flags gy, but they don't hurt
      if (!NPCG) separator2 = new RegExp('^' + separatorCopy.source + '$(?!\\s)', flags);
      while (match = separatorCopy.exec(string)) {
        // `separatorCopy.lastIndex` is not reliable cross-browser
        lastIndex = match.index + match[0][LENGTH];
        if (lastIndex > lastLastIndex) {
          output.push(string.slice(lastLastIndex, match.index));
          // Fix browsers whose `exec` methods don't consistently return `undefined` for NPCG
          // eslint-disable-next-line no-loop-func
          if (!NPCG && match[LENGTH] > 1) match[0].replace(separator2, function () {
            for (i = 1; i < arguments[LENGTH] - 2; i++) if (arguments[i] === undefined) match[i] = undefined;
          });
          if (match[LENGTH] > 1 && match.index < string[LENGTH]) $push.apply(output, match.slice(1));
          lastLength = match[0][LENGTH];
          lastLastIndex = lastIndex;
          if (output[LENGTH] >= splitLimit) break;
        }
        if (separatorCopy[LAST_INDEX] === match.index) separatorCopy[LAST_INDEX]++; // Avoid an infinite loop
      }
      if (lastLastIndex === string[LENGTH]) {
        if (lastLength || !separatorCopy.test('')) output.push('');
      } else output.push(string.slice(lastLastIndex));
      return output[LENGTH] > splitLimit ? output.slice(0, splitLimit) : output;
    };
  // Chakra, V8
  } else if ('0'[$SPLIT](undefined, 0)[LENGTH]) {
    $split = function (separator, limit) {
      return separator === undefined && limit === 0 ? [] : _split.call(this, separator, limit);
    };
  }
  // 21.1.3.17 String.prototype.split(separator, limit)
  return [function split(separator, limit) {
    var O = defined(this);
    var fn = separator == undefined ? undefined : separator[SPLIT];
    return fn !== undefined ? fn.call(separator, O, limit) : $split.call(String(O), separator, limit);
  }, $split];
});

},{"./_fix-re-wks":42,"./_is-regexp":57}],226:[function(require,module,exports){
'use strict';
require('./es6.regexp.flags');
var anObject = require('./_an-object');
var $flags = require('./_flags');
var DESCRIPTORS = require('./_descriptors');
var TO_STRING = 'toString';
var $toString = /./[TO_STRING];

var define = function (fn) {
  require('./_redefine')(RegExp.prototype, TO_STRING, fn, true);
};

// 21.2.5.14 RegExp.prototype.toString()
if (require('./_fails')(function () { return $toString.call({ source: 'a', flags: 'b' }) != '/a/b'; })) {
  define(function toString() {
    var R = anObject(this);
    return '/'.concat(R.source, '/',
      'flags' in R ? R.flags : !DESCRIPTORS && R instanceof RegExp ? $flags.call(R) : undefined);
  });
// FF44- RegExp#toString has a wrong name
} else if ($toString.name != TO_STRING) {
  define(function toString() {
    return $toString.call(this);
  });
}

},{"./_an-object":15,"./_descriptors":35,"./_fails":41,"./_flags":43,"./_redefine":93,"./es6.regexp.flags":221}],227:[function(require,module,exports){
'use strict';
var strong = require('./_collection-strong');
var validate = require('./_validate-collection');
var SET = 'Set';

// 23.2 Set Objects
module.exports = require('./_collection')(SET, function (get) {
  return function Set() { return get(this, arguments.length > 0 ? arguments[0] : undefined); };
}, {
  // 23.2.3.1 Set.prototype.add(value)
  add: function add(value) {
    return strong.def(validate(this, SET), value = value === 0 ? 0 : value, value);
  }
}, strong);

},{"./_collection":28,"./_collection-strong":26,"./_validate-collection":122}],228:[function(require,module,exports){
'use strict';
// B.2.3.2 String.prototype.anchor(name)
require('./_string-html')('anchor', function (createHTML) {
  return function anchor(name) {
    return createHTML(this, 'a', 'name', name);
  };
});

},{"./_string-html":104}],229:[function(require,module,exports){
'use strict';
// B.2.3.3 String.prototype.big()
require('./_string-html')('big', function (createHTML) {
  return function big() {
    return createHTML(this, 'big', '', '');
  };
});

},{"./_string-html":104}],230:[function(require,module,exports){
'use strict';
// B.2.3.4 String.prototype.blink()
require('./_string-html')('blink', function (createHTML) {
  return function blink() {
    return createHTML(this, 'blink', '', '');
  };
});

},{"./_string-html":104}],231:[function(require,module,exports){
'use strict';
// B.2.3.5 String.prototype.bold()
require('./_string-html')('bold', function (createHTML) {
  return function bold() {
    return createHTML(this, 'b', '', '');
  };
});

},{"./_string-html":104}],232:[function(require,module,exports){
'use strict';
var $export = require('./_export');
var $at = require('./_string-at')(false);
$export($export.P, 'String', {
  // 21.1.3.3 String.prototype.codePointAt(pos)
  codePointAt: function codePointAt(pos) {
    return $at(this, pos);
  }
});

},{"./_export":39,"./_string-at":102}],233:[function(require,module,exports){
// 21.1.3.6 String.prototype.endsWith(searchString [, endPosition])
'use strict';
var $export = require('./_export');
var toLength = require('./_to-length');
var context = require('./_string-context');
var ENDS_WITH = 'endsWith';
var $endsWith = ''[ENDS_WITH];

$export($export.P + $export.F * require('./_fails-is-regexp')(ENDS_WITH), 'String', {
  endsWith: function endsWith(searchString /* , endPosition = @length */) {
    var that = context(this, searchString, ENDS_WITH);
    var endPosition = arguments.length > 1 ? arguments[1] : undefined;
    var len = toLength(that.length);
    var end = endPosition === undefined ? len : Math.min(toLength(endPosition), len);
    var search = String(searchString);
    return $endsWith
      ? $endsWith.call(that, search, end)
      : that.slice(end - search.length, end) === search;
  }
});

},{"./_export":39,"./_fails-is-regexp":40,"./_string-context":103,"./_to-length":114}],234:[function(require,module,exports){
'use strict';
// B.2.3.6 String.prototype.fixed()
require('./_string-html')('fixed', function (createHTML) {
  return function fixed() {
    return createHTML(this, 'tt', '', '');
  };
});

},{"./_string-html":104}],235:[function(require,module,exports){
'use strict';
// B.2.3.7 String.prototype.fontcolor(color)
require('./_string-html')('fontcolor', function (createHTML) {
  return function fontcolor(color) {
    return createHTML(this, 'font', 'color', color);
  };
});

},{"./_string-html":104}],236:[function(require,module,exports){
'use strict';
// B.2.3.8 String.prototype.fontsize(size)
require('./_string-html')('fontsize', function (createHTML) {
  return function fontsize(size) {
    return createHTML(this, 'font', 'size', size);
  };
});

},{"./_string-html":104}],237:[function(require,module,exports){
var $export = require('./_export');
var toAbsoluteIndex = require('./_to-absolute-index');
var fromCharCode = String.fromCharCode;
var $fromCodePoint = String.fromCodePoint;

// length should be 1, old FF problem
$export($export.S + $export.F * (!!$fromCodePoint && $fromCodePoint.length != 1), 'String', {
  // 21.1.2.2 String.fromCodePoint(...codePoints)
  fromCodePoint: function fromCodePoint(x) { // eslint-disable-line no-unused-vars
    var res = [];
    var aLen = arguments.length;
    var i = 0;
    var code;
    while (aLen > i) {
      code = +arguments[i++];
      if (toAbsoluteIndex(code, 0x10ffff) !== code) throw RangeError(code + ' is not a valid code point');
      res.push(code < 0x10000
        ? fromCharCode(code)
        : fromCharCode(((code -= 0x10000) >> 10) + 0xd800, code % 0x400 + 0xdc00)
      );
    } return res.join('');
  }
});

},{"./_export":39,"./_to-absolute-index":110}],238:[function(require,module,exports){
// 21.1.3.7 String.prototype.includes(searchString, position = 0)
'use strict';
var $export = require('./_export');
var context = require('./_string-context');
var INCLUDES = 'includes';

$export($export.P + $export.F * require('./_fails-is-regexp')(INCLUDES), 'String', {
  includes: function includes(searchString /* , position = 0 */) {
    return !!~context(this, searchString, INCLUDES)
      .indexOf(searchString, arguments.length > 1 ? arguments[1] : undefined);
  }
});

},{"./_export":39,"./_fails-is-regexp":40,"./_string-context":103}],239:[function(require,module,exports){
'use strict';
// B.2.3.9 String.prototype.italics()
require('./_string-html')('italics', function (createHTML) {
  return function italics() {
    return createHTML(this, 'i', '', '');
  };
});

},{"./_string-html":104}],240:[function(require,module,exports){
'use strict';
var $at = require('./_string-at')(true);

// 21.1.3.27 String.prototype[@@iterator]()
require('./_iter-define')(String, 'String', function (iterated) {
  this._t = String(iterated); // target
  this._i = 0;                // next index
// 21.1.5.2.1 %StringIteratorPrototype%.next()
}, function () {
  var O = this._t;
  var index = this._i;
  var point;
  if (index >= O.length) return { value: undefined, done: true };
  point = $at(O, index);
  this._i += point.length;
  return { value: point, done: false };
});

},{"./_iter-define":60,"./_string-at":102}],241:[function(require,module,exports){
'use strict';
// B.2.3.10 String.prototype.link(url)
require('./_string-html')('link', function (createHTML) {
  return function link(url) {
    return createHTML(this, 'a', 'href', url);
  };
});

},{"./_string-html":104}],242:[function(require,module,exports){
var $export = require('./_export');
var toIObject = require('./_to-iobject');
var toLength = require('./_to-length');

$export($export.S, 'String', {
  // 21.1.2.4 String.raw(callSite, ...substitutions)
  raw: function raw(callSite) {
    var tpl = toIObject(callSite.raw);
    var len = toLength(tpl.length);
    var aLen = arguments.length;
    var res = [];
    var i = 0;
    while (len > i) {
      res.push(String(tpl[i++]));
      if (i < aLen) res.push(String(arguments[i]));
    } return res.join('');
  }
});

},{"./_export":39,"./_to-iobject":113,"./_to-length":114}],243:[function(require,module,exports){
var $export = require('./_export');

$export($export.P, 'String', {
  // 21.1.3.13 String.prototype.repeat(count)
  repeat: require('./_string-repeat')
});

},{"./_export":39,"./_string-repeat":106}],244:[function(require,module,exports){
'use strict';
// B.2.3.11 String.prototype.small()
require('./_string-html')('small', function (createHTML) {
  return function small() {
    return createHTML(this, 'small', '', '');
  };
});

},{"./_string-html":104}],245:[function(require,module,exports){
// 21.1.3.18 String.prototype.startsWith(searchString [, position ])
'use strict';
var $export = require('./_export');
var toLength = require('./_to-length');
var context = require('./_string-context');
var STARTS_WITH = 'startsWith';
var $startsWith = ''[STARTS_WITH];

$export($export.P + $export.F * require('./_fails-is-regexp')(STARTS_WITH), 'String', {
  startsWith: function startsWith(searchString /* , position = 0 */) {
    var that = context(this, searchString, STARTS_WITH);
    var index = toLength(Math.min(arguments.length > 1 ? arguments[1] : undefined, that.length));
    var search = String(searchString);
    return $startsWith
      ? $startsWith.call(that, search, index)
      : that.slice(index, index + search.length) === search;
  }
});

},{"./_export":39,"./_fails-is-regexp":40,"./_string-context":103,"./_to-length":114}],246:[function(require,module,exports){
'use strict';
// B.2.3.12 String.prototype.strike()
require('./_string-html')('strike', function (createHTML) {
  return function strike() {
    return createHTML(this, 'strike', '', '');
  };
});

},{"./_string-html":104}],247:[function(require,module,exports){
'use strict';
// B.2.3.13 String.prototype.sub()
require('./_string-html')('sub', function (createHTML) {
  return function sub() {
    return createHTML(this, 'sub', '', '');
  };
});

},{"./_string-html":104}],248:[function(require,module,exports){
'use strict';
// B.2.3.14 String.prototype.sup()
require('./_string-html')('sup', function (createHTML) {
  return function sup() {
    return createHTML(this, 'sup', '', '');
  };
});

},{"./_string-html":104}],249:[function(require,module,exports){
'use strict';
// 21.1.3.25 String.prototype.trim()
require('./_string-trim')('trim', function ($trim) {
  return function trim() {
    return $trim(this, 3);
  };
});

},{"./_string-trim":107}],250:[function(require,module,exports){
'use strict';
// ECMAScript 6 symbols shim
var global = require('./_global');
var has = require('./_has');
var DESCRIPTORS = require('./_descriptors');
var $export = require('./_export');
var redefine = require('./_redefine');
var META = require('./_meta').KEY;
var $fails = require('./_fails');
var shared = require('./_shared');
var setToStringTag = require('./_set-to-string-tag');
var uid = require('./_uid');
var wks = require('./_wks');
var wksExt = require('./_wks-ext');
var wksDefine = require('./_wks-define');
var enumKeys = require('./_enum-keys');
var isArray = require('./_is-array');
var anObject = require('./_an-object');
var isObject = require('./_is-object');
var toIObject = require('./_to-iobject');
var toPrimitive = require('./_to-primitive');
var createDesc = require('./_property-desc');
var _create = require('./_object-create');
var gOPNExt = require('./_object-gopn-ext');
var $GOPD = require('./_object-gopd');
var $DP = require('./_object-dp');
var $keys = require('./_object-keys');
var gOPD = $GOPD.f;
var dP = $DP.f;
var gOPN = gOPNExt.f;
var $Symbol = global.Symbol;
var $JSON = global.JSON;
var _stringify = $JSON && $JSON.stringify;
var PROTOTYPE = 'prototype';
var HIDDEN = wks('_hidden');
var TO_PRIMITIVE = wks('toPrimitive');
var isEnum = {}.propertyIsEnumerable;
var SymbolRegistry = shared('symbol-registry');
var AllSymbols = shared('symbols');
var OPSymbols = shared('op-symbols');
var ObjectProto = Object[PROTOTYPE];
var USE_NATIVE = typeof $Symbol == 'function';
var QObject = global.QObject;
// Don't use setters in Qt Script, https://github.com/zloirock/core-js/issues/173
var setter = !QObject || !QObject[PROTOTYPE] || !QObject[PROTOTYPE].findChild;

// fallback for old Android, https://code.google.com/p/v8/issues/detail?id=687
var setSymbolDesc = DESCRIPTORS && $fails(function () {
  return _create(dP({}, 'a', {
    get: function () { return dP(this, 'a', { value: 7 }).a; }
  })).a != 7;
}) ? function (it, key, D) {
  var protoDesc = gOPD(ObjectProto, key);
  if (protoDesc) delete ObjectProto[key];
  dP(it, key, D);
  if (protoDesc && it !== ObjectProto) dP(ObjectProto, key, protoDesc);
} : dP;

var wrap = function (tag) {
  var sym = AllSymbols[tag] = _create($Symbol[PROTOTYPE]);
  sym._k = tag;
  return sym;
};

var isSymbol = USE_NATIVE && typeof $Symbol.iterator == 'symbol' ? function (it) {
  return typeof it == 'symbol';
} : function (it) {
  return it instanceof $Symbol;
};

var $defineProperty = function defineProperty(it, key, D) {
  if (it === ObjectProto) $defineProperty(OPSymbols, key, D);
  anObject(it);
  key = toPrimitive(key, true);
  anObject(D);
  if (has(AllSymbols, key)) {
    if (!D.enumerable) {
      if (!has(it, HIDDEN)) dP(it, HIDDEN, createDesc(1, {}));
      it[HIDDEN][key] = true;
    } else {
      if (has(it, HIDDEN) && it[HIDDEN][key]) it[HIDDEN][key] = false;
      D = _create(D, { enumerable: createDesc(0, false) });
    } return setSymbolDesc(it, key, D);
  } return dP(it, key, D);
};
var $defineProperties = function defineProperties(it, P) {
  anObject(it);
  var keys = enumKeys(P = toIObject(P));
  var i = 0;
  var l = keys.length;
  var key;
  while (l > i) $defineProperty(it, key = keys[i++], P[key]);
  return it;
};
var $create = function create(it, P) {
  return P === undefined ? _create(it) : $defineProperties(_create(it), P);
};
var $propertyIsEnumerable = function propertyIsEnumerable(key) {
  var E = isEnum.call(this, key = toPrimitive(key, true));
  if (this === ObjectProto && has(AllSymbols, key) && !has(OPSymbols, key)) return false;
  return E || !has(this, key) || !has(AllSymbols, key) || has(this, HIDDEN) && this[HIDDEN][key] ? E : true;
};
var $getOwnPropertyDescriptor = function getOwnPropertyDescriptor(it, key) {
  it = toIObject(it);
  key = toPrimitive(key, true);
  if (it === ObjectProto && has(AllSymbols, key) && !has(OPSymbols, key)) return;
  var D = gOPD(it, key);
  if (D && has(AllSymbols, key) && !(has(it, HIDDEN) && it[HIDDEN][key])) D.enumerable = true;
  return D;
};
var $getOwnPropertyNames = function getOwnPropertyNames(it) {
  var names = gOPN(toIObject(it));
  var result = [];
  var i = 0;
  var key;
  while (names.length > i) {
    if (!has(AllSymbols, key = names[i++]) && key != HIDDEN && key != META) result.push(key);
  } return result;
};
var $getOwnPropertySymbols = function getOwnPropertySymbols(it) {
  var IS_OP = it === ObjectProto;
  var names = gOPN(IS_OP ? OPSymbols : toIObject(it));
  var result = [];
  var i = 0;
  var key;
  while (names.length > i) {
    if (has(AllSymbols, key = names[i++]) && (IS_OP ? has(ObjectProto, key) : true)) result.push(AllSymbols[key]);
  } return result;
};

// 19.4.1.1 Symbol([description])
if (!USE_NATIVE) {
  $Symbol = function Symbol() {
    if (this instanceof $Symbol) throw TypeError('Symbol is not a constructor!');
    var tag = uid(arguments.length > 0 ? arguments[0] : undefined);
    var $set = function (value) {
      if (this === ObjectProto) $set.call(OPSymbols, value);
      if (has(this, HIDDEN) && has(this[HIDDEN], tag)) this[HIDDEN][tag] = false;
      setSymbolDesc(this, tag, createDesc(1, value));
    };
    if (DESCRIPTORS && setter) setSymbolDesc(ObjectProto, tag, { configurable: true, set: $set });
    return wrap(tag);
  };
  redefine($Symbol[PROTOTYPE], 'toString', function toString() {
    return this._k;
  });

  $GOPD.f = $getOwnPropertyDescriptor;
  $DP.f = $defineProperty;
  require('./_object-gopn').f = gOPNExt.f = $getOwnPropertyNames;
  require('./_object-pie').f = $propertyIsEnumerable;
  require('./_object-gops').f = $getOwnPropertySymbols;

  if (DESCRIPTORS && !require('./_library')) {
    redefine(ObjectProto, 'propertyIsEnumerable', $propertyIsEnumerable, true);
  }

  wksExt.f = function (name) {
    return wrap(wks(name));
  };
}

$export($export.G + $export.W + $export.F * !USE_NATIVE, { Symbol: $Symbol });

for (var es6Symbols = (
  // 19.4.2.2, 19.4.2.3, 19.4.2.4, 19.4.2.6, 19.4.2.8, 19.4.2.9, 19.4.2.10, 19.4.2.11, 19.4.2.12, 19.4.2.13, 19.4.2.14
  'hasInstance,isConcatSpreadable,iterator,match,replace,search,species,split,toPrimitive,toStringTag,unscopables'
).split(','), j = 0; es6Symbols.length > j;)wks(es6Symbols[j++]);

for (var wellKnownSymbols = $keys(wks.store), k = 0; wellKnownSymbols.length > k;) wksDefine(wellKnownSymbols[k++]);

$export($export.S + $export.F * !USE_NATIVE, 'Symbol', {
  // 19.4.2.1 Symbol.for(key)
  'for': function (key) {
    return has(SymbolRegistry, key += '')
      ? SymbolRegistry[key]
      : SymbolRegistry[key] = $Symbol(key);
  },
  // 19.4.2.5 Symbol.keyFor(sym)
  keyFor: function keyFor(sym) {
    if (!isSymbol(sym)) throw TypeError(sym + ' is not a symbol!');
    for (var key in SymbolRegistry) if (SymbolRegistry[key] === sym) return key;
  },
  useSetter: function () { setter = true; },
  useSimple: function () { setter = false; }
});

$export($export.S + $export.F * !USE_NATIVE, 'Object', {
  // 19.1.2.2 Object.create(O [, Properties])
  create: $create,
  // 19.1.2.4 Object.defineProperty(O, P, Attributes)
  defineProperty: $defineProperty,
  // 19.1.2.3 Object.defineProperties(O, Properties)
  defineProperties: $defineProperties,
  // 19.1.2.6 Object.getOwnPropertyDescriptor(O, P)
  getOwnPropertyDescriptor: $getOwnPropertyDescriptor,
  // 19.1.2.7 Object.getOwnPropertyNames(O)
  getOwnPropertyNames: $getOwnPropertyNames,
  // 19.1.2.8 Object.getOwnPropertySymbols(O)
  getOwnPropertySymbols: $getOwnPropertySymbols
});

// 24.3.2 JSON.stringify(value [, replacer [, space]])
$JSON && $export($export.S + $export.F * (!USE_NATIVE || $fails(function () {
  var S = $Symbol();
  // MS Edge converts symbol values to JSON as {}
  // WebKit converts symbol values to JSON as null
  // V8 throws on boxed symbols
  return _stringify([S]) != '[null]' || _stringify({ a: S }) != '{}' || _stringify(Object(S)) != '{}';
})), 'JSON', {
  stringify: function stringify(it) {
    var args = [it];
    var i = 1;
    var replacer, $replacer;
    while (arguments.length > i) args.push(arguments[i++]);
    $replacer = replacer = args[1];
    if (!isObject(replacer) && it === undefined || isSymbol(it)) return; // IE8 returns string on undefined
    if (!isArray(replacer)) replacer = function (key, value) {
      if (typeof $replacer == 'function') value = $replacer.call(this, key, value);
      if (!isSymbol(value)) return value;
    };
    args[1] = replacer;
    return _stringify.apply($JSON, args);
  }
});

// 19.4.3.4 Symbol.prototype[@@toPrimitive](hint)
$Symbol[PROTOTYPE][TO_PRIMITIVE] || require('./_hide')($Symbol[PROTOTYPE], TO_PRIMITIVE, $Symbol[PROTOTYPE].valueOf);
// 19.4.3.5 Symbol.prototype[@@toStringTag]
setToStringTag($Symbol, 'Symbol');
// 20.2.1.9 Math[@@toStringTag]
setToStringTag(Math, 'Math', true);
// 24.3.3 JSON[@@toStringTag]
setToStringTag(global.JSON, 'JSON', true);

},{"./_an-object":15,"./_descriptors":35,"./_enum-keys":38,"./_export":39,"./_fails":41,"./_global":45,"./_has":46,"./_hide":47,"./_is-array":54,"./_is-object":56,"./_library":64,"./_meta":69,"./_object-create":73,"./_object-dp":74,"./_object-gopd":76,"./_object-gopn":78,"./_object-gopn-ext":77,"./_object-gops":79,"./_object-keys":82,"./_object-pie":83,"./_property-desc":91,"./_redefine":93,"./_set-to-string-tag":97,"./_shared":99,"./_to-iobject":113,"./_to-primitive":116,"./_uid":120,"./_wks":125,"./_wks-define":123,"./_wks-ext":124}],251:[function(require,module,exports){
'use strict';
var $export = require('./_export');
var $typed = require('./_typed');
var buffer = require('./_typed-buffer');
var anObject = require('./_an-object');
var toAbsoluteIndex = require('./_to-absolute-index');
var toLength = require('./_to-length');
var isObject = require('./_is-object');
var ArrayBuffer = require('./_global').ArrayBuffer;
var speciesConstructor = require('./_species-constructor');
var $ArrayBuffer = buffer.ArrayBuffer;
var $DataView = buffer.DataView;
var $isView = $typed.ABV && ArrayBuffer.isView;
var $slice = $ArrayBuffer.prototype.slice;
var VIEW = $typed.VIEW;
var ARRAY_BUFFER = 'ArrayBuffer';

$export($export.G + $export.W + $export.F * (ArrayBuffer !== $ArrayBuffer), { ArrayBuffer: $ArrayBuffer });

$export($export.S + $export.F * !$typed.CONSTR, ARRAY_BUFFER, {
  // 24.1.3.1 ArrayBuffer.isView(arg)
  isView: function isView(it) {
    return $isView && $isView(it) || isObject(it) && VIEW in it;
  }
});

$export($export.P + $export.U + $export.F * require('./_fails')(function () {
  return !new $ArrayBuffer(2).slice(1, undefined).byteLength;
}), ARRAY_BUFFER, {
  // 24.1.4.3 ArrayBuffer.prototype.slice(start, end)
  slice: function slice(start, end) {
    if ($slice !== undefined && end === undefined) return $slice.call(anObject(this), start); // FF fix
    var len = anObject(this).byteLength;
    var first = toAbsoluteIndex(start, len);
    var fin = toAbsoluteIndex(end === undefined ? len : end, len);
    var result = new (speciesConstructor(this, $ArrayBuffer))(toLength(fin - first));
    var viewS = new $DataView(this);
    var viewT = new $DataView(result);
    var index = 0;
    while (first < fin) {
      viewT.setUint8(index++, viewS.getUint8(first++));
    } return result;
  }
});

require('./_set-species')(ARRAY_BUFFER);

},{"./_an-object":15,"./_export":39,"./_fails":41,"./_global":45,"./_is-object":56,"./_set-species":96,"./_species-constructor":100,"./_to-absolute-index":110,"./_to-length":114,"./_typed":119,"./_typed-buffer":118}],252:[function(require,module,exports){
var $export = require('./_export');
$export($export.G + $export.W + $export.F * !require('./_typed').ABV, {
  DataView: require('./_typed-buffer').DataView
});

},{"./_export":39,"./_typed":119,"./_typed-buffer":118}],253:[function(require,module,exports){
require('./_typed-array')('Float32', 4, function (init) {
  return function Float32Array(data, byteOffset, length) {
    return init(this, data, byteOffset, length);
  };
});

},{"./_typed-array":117}],254:[function(require,module,exports){
require('./_typed-array')('Float64', 8, function (init) {
  return function Float64Array(data, byteOffset, length) {
    return init(this, data, byteOffset, length);
  };
});

},{"./_typed-array":117}],255:[function(require,module,exports){
require('./_typed-array')('Int16', 2, function (init) {
  return function Int16Array(data, byteOffset, length) {
    return init(this, data, byteOffset, length);
  };
});

},{"./_typed-array":117}],256:[function(require,module,exports){
require('./_typed-array')('Int32', 4, function (init) {
  return function Int32Array(data, byteOffset, length) {
    return init(this, data, byteOffset, length);
  };
});

},{"./_typed-array":117}],257:[function(require,module,exports){
require('./_typed-array')('Int8', 1, function (init) {
  return function Int8Array(data, byteOffset, length) {
    return init(this, data, byteOffset, length);
  };
});

},{"./_typed-array":117}],258:[function(require,module,exports){
require('./_typed-array')('Uint16', 2, function (init) {
  return function Uint16Array(data, byteOffset, length) {
    return init(this, data, byteOffset, length);
  };
});

},{"./_typed-array":117}],259:[function(require,module,exports){
require('./_typed-array')('Uint32', 4, function (init) {
  return function Uint32Array(data, byteOffset, length) {
    return init(this, data, byteOffset, length);
  };
});

},{"./_typed-array":117}],260:[function(require,module,exports){
require('./_typed-array')('Uint8', 1, function (init) {
  return function Uint8Array(data, byteOffset, length) {
    return init(this, data, byteOffset, length);
  };
});

},{"./_typed-array":117}],261:[function(require,module,exports){
require('./_typed-array')('Uint8', 1, function (init) {
  return function Uint8ClampedArray(data, byteOffset, length) {
    return init(this, data, byteOffset, length);
  };
}, true);

},{"./_typed-array":117}],262:[function(require,module,exports){
'use strict';
var each = require('./_array-methods')(0);
var redefine = require('./_redefine');
var meta = require('./_meta');
var assign = require('./_object-assign');
var weak = require('./_collection-weak');
var isObject = require('./_is-object');
var fails = require('./_fails');
var validate = require('./_validate-collection');
var WEAK_MAP = 'WeakMap';
var getWeak = meta.getWeak;
var isExtensible = Object.isExtensible;
var uncaughtFrozenStore = weak.ufstore;
var tmp = {};
var InternalMap;

var wrapper = function (get) {
  return function WeakMap() {
    return get(this, arguments.length > 0 ? arguments[0] : undefined);
  };
};

var methods = {
  // 23.3.3.3 WeakMap.prototype.get(key)
  get: function get(key) {
    if (isObject(key)) {
      var data = getWeak(key);
      if (data === true) return uncaughtFrozenStore(validate(this, WEAK_MAP)).get(key);
      return data ? data[this._i] : undefined;
    }
  },
  // 23.3.3.5 WeakMap.prototype.set(key, value)
  set: function set(key, value) {
    return weak.def(validate(this, WEAK_MAP), key, value);
  }
};

// 23.3 WeakMap Objects
var $WeakMap = module.exports = require('./_collection')(WEAK_MAP, wrapper, methods, weak, true, true);

// IE11 WeakMap frozen keys fix
if (fails(function () { return new $WeakMap().set((Object.freeze || Object)(tmp), 7).get(tmp) != 7; })) {
  InternalMap = weak.getConstructor(wrapper, WEAK_MAP);
  assign(InternalMap.prototype, methods);
  meta.NEED = true;
  each(['delete', 'has', 'get', 'set'], function (key) {
    var proto = $WeakMap.prototype;
    var method = proto[key];
    redefine(proto, key, function (a, b) {
      // store frozen objects on internal weakmap shim
      if (isObject(a) && !isExtensible(a)) {
        if (!this._f) this._f = new InternalMap();
        var result = this._f[key](a, b);
        return key == 'set' ? this : result;
      // store all the rest on native weakmap
      } return method.call(this, a, b);
    });
  });
}

},{"./_array-methods":19,"./_collection":28,"./_collection-weak":27,"./_fails":41,"./_is-object":56,"./_meta":69,"./_object-assign":72,"./_redefine":93,"./_validate-collection":122}],263:[function(require,module,exports){
'use strict';
var weak = require('./_collection-weak');
var validate = require('./_validate-collection');
var WEAK_SET = 'WeakSet';

// 23.4 WeakSet Objects
require('./_collection')(WEAK_SET, function (get) {
  return function WeakSet() { return get(this, arguments.length > 0 ? arguments[0] : undefined); };
}, {
  // 23.4.3.1 WeakSet.prototype.add(value)
  add: function add(value) {
    return weak.def(validate(this, WEAK_SET), value, true);
  }
}, weak, false, true);

},{"./_collection":28,"./_collection-weak":27,"./_validate-collection":122}],264:[function(require,module,exports){
'use strict';
// https://github.com/tc39/Array.prototype.includes
var $export = require('./_export');
var $includes = require('./_array-includes')(true);

$export($export.P, 'Array', {
  includes: function includes(el /* , fromIndex = 0 */) {
    return $includes(this, el, arguments.length > 1 ? arguments[1] : undefined);
  }
});

require('./_add-to-unscopables')('includes');

},{"./_add-to-unscopables":13,"./_array-includes":18,"./_export":39}],265:[function(require,module,exports){
// https://github.com/tc39/proposal-object-values-entries
var $export = require('./_export');
var $entries = require('./_object-to-array')(true);

$export($export.S, 'Object', {
  entries: function entries(it) {
    return $entries(it);
  }
});

},{"./_export":39,"./_object-to-array":85}],266:[function(require,module,exports){
// https://github.com/tc39/proposal-object-getownpropertydescriptors
var $export = require('./_export');
var ownKeys = require('./_own-keys');
var toIObject = require('./_to-iobject');
var gOPD = require('./_object-gopd');
var createProperty = require('./_create-property');

$export($export.S, 'Object', {
  getOwnPropertyDescriptors: function getOwnPropertyDescriptors(object) {
    var O = toIObject(object);
    var getDesc = gOPD.f;
    var keys = ownKeys(O);
    var result = {};
    var i = 0;
    var key, desc;
    while (keys.length > i) {
      desc = getDesc(O, key = keys[i++]);
      if (desc !== undefined) createProperty(result, key, desc);
    }
    return result;
  }
});

},{"./_create-property":30,"./_export":39,"./_object-gopd":76,"./_own-keys":86,"./_to-iobject":113}],267:[function(require,module,exports){
// https://github.com/tc39/proposal-object-values-entries
var $export = require('./_export');
var $values = require('./_object-to-array')(false);

$export($export.S, 'Object', {
  values: function values(it) {
    return $values(it);
  }
});

},{"./_export":39,"./_object-to-array":85}],268:[function(require,module,exports){
// https://github.com/tc39/proposal-promise-finally
'use strict';
var $export = require('./_export');
var core = require('./_core');
var global = require('./_global');
var speciesConstructor = require('./_species-constructor');
var promiseResolve = require('./_promise-resolve');

$export($export.P + $export.R, 'Promise', { 'finally': function (onFinally) {
  var C = speciesConstructor(this, core.Promise || global.Promise);
  var isFunction = typeof onFinally == 'function';
  return this.then(
    isFunction ? function (x) {
      return promiseResolve(C, onFinally()).then(function () { return x; });
    } : onFinally,
    isFunction ? function (e) {
      return promiseResolve(C, onFinally()).then(function () { throw e; });
    } : onFinally
  );
} });

},{"./_core":29,"./_export":39,"./_global":45,"./_promise-resolve":90,"./_species-constructor":100}],269:[function(require,module,exports){
'use strict';
// https://github.com/tc39/proposal-string-pad-start-end
var $export = require('./_export');
var $pad = require('./_string-pad');
var userAgent = require('./_user-agent');

// https://github.com/zloirock/core-js/issues/280
$export($export.P + $export.F * /Version\/10\.\d+(\.\d+)? Safari\//.test(userAgent), 'String', {
  padEnd: function padEnd(maxLength /* , fillString = ' ' */) {
    return $pad(this, maxLength, arguments.length > 1 ? arguments[1] : undefined, false);
  }
});

},{"./_export":39,"./_string-pad":105,"./_user-agent":121}],270:[function(require,module,exports){
'use strict';
// https://github.com/tc39/proposal-string-pad-start-end
var $export = require('./_export');
var $pad = require('./_string-pad');
var userAgent = require('./_user-agent');

// https://github.com/zloirock/core-js/issues/280
$export($export.P + $export.F * /Version\/10\.\d+(\.\d+)? Safari\//.test(userAgent), 'String', {
  padStart: function padStart(maxLength /* , fillString = ' ' */) {
    return $pad(this, maxLength, arguments.length > 1 ? arguments[1] : undefined, true);
  }
});

},{"./_export":39,"./_string-pad":105,"./_user-agent":121}],271:[function(require,module,exports){
require('./_wks-define')('asyncIterator');

},{"./_wks-define":123}],272:[function(require,module,exports){
var $iterators = require('./es6.array.iterator');
var getKeys = require('./_object-keys');
var redefine = require('./_redefine');
var global = require('./_global');
var hide = require('./_hide');
var Iterators = require('./_iterators');
var wks = require('./_wks');
var ITERATOR = wks('iterator');
var TO_STRING_TAG = wks('toStringTag');
var ArrayValues = Iterators.Array;

var DOMIterables = {
  CSSRuleList: true, // TODO: Not spec compliant, should be false.
  CSSStyleDeclaration: false,
  CSSValueList: false,
  ClientRectList: false,
  DOMRectList: false,
  DOMStringList: false,
  DOMTokenList: true,
  DataTransferItemList: false,
  FileList: false,
  HTMLAllCollection: false,
  HTMLCollection: false,
  HTMLFormElement: false,
  HTMLSelectElement: false,
  MediaList: true, // TODO: Not spec compliant, should be false.
  MimeTypeArray: false,
  NamedNodeMap: false,
  NodeList: true,
  PaintRequestList: false,
  Plugin: false,
  PluginArray: false,
  SVGLengthList: false,
  SVGNumberList: false,
  SVGPathSegList: false,
  SVGPointList: false,
  SVGStringList: false,
  SVGTransformList: false,
  SourceBufferList: false,
  StyleSheetList: true, // TODO: Not spec compliant, should be false.
  TextTrackCueList: false,
  TextTrackList: false,
  TouchList: false
};

for (var collections = getKeys(DOMIterables), i = 0; i < collections.length; i++) {
  var NAME = collections[i];
  var explicit = DOMIterables[NAME];
  var Collection = global[NAME];
  var proto = Collection && Collection.prototype;
  var key;
  if (proto) {
    if (!proto[ITERATOR]) hide(proto, ITERATOR, ArrayValues);
    if (!proto[TO_STRING_TAG]) hide(proto, TO_STRING_TAG, NAME);
    Iterators[NAME] = ArrayValues;
    if (explicit) for (key in $iterators) if (!proto[key]) redefine(proto, key, $iterators[key], true);
  }
}

},{"./_global":45,"./_hide":47,"./_iterators":63,"./_object-keys":82,"./_redefine":93,"./_wks":125,"./es6.array.iterator":137}],273:[function(require,module,exports){
var $export = require('./_export');
var $task = require('./_task');
$export($export.G + $export.B, {
  setImmediate: $task.set,
  clearImmediate: $task.clear
});

},{"./_export":39,"./_task":109}],274:[function(require,module,exports){
// ie9- setTimeout & setInterval additional parameters fix
var global = require('./_global');
var $export = require('./_export');
var userAgent = require('./_user-agent');
var slice = [].slice;
var MSIE = /MSIE .\./.test(userAgent); // <- dirty ie9- check
var wrap = function (set) {
  return function (fn, time /* , ...args */) {
    var boundArgs = arguments.length > 2;
    var args = boundArgs ? slice.call(arguments, 2) : false;
    return set(boundArgs ? function () {
      // eslint-disable-next-line no-new-func
      (typeof fn == 'function' ? fn : Function(fn)).apply(this, args);
    } : fn, time);
  };
};
$export($export.G + $export.B + $export.F * MSIE, {
  setTimeout: wrap(global.setTimeout),
  setInterval: wrap(global.setInterval)
});

},{"./_export":39,"./_global":45,"./_user-agent":121}],275:[function(require,module,exports){
require('../modules/web.timers');
require('../modules/web.immediate');
require('../modules/web.dom.iterable');
module.exports = require('../modules/_core');

},{"../modules/_core":29,"../modules/web.dom.iterable":272,"../modules/web.immediate":273,"../modules/web.timers":274}],276:[function(require,module,exports){
/**
 * Copyright (c) 2014-present, Facebook, Inc.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

!(function(global) {
  "use strict";

  var Op = Object.prototype;
  var hasOwn = Op.hasOwnProperty;
  var undefined; // More compressible than void 0.
  var $Symbol = typeof Symbol === "function" ? Symbol : {};
  var iteratorSymbol = $Symbol.iterator || "@@iterator";
  var asyncIteratorSymbol = $Symbol.asyncIterator || "@@asyncIterator";
  var toStringTagSymbol = $Symbol.toStringTag || "@@toStringTag";

  var inModule = typeof module === "object";
  var runtime = global.regeneratorRuntime;
  if (runtime) {
    if (inModule) {
      // If regeneratorRuntime is defined globally and we're in a module,
      // make the exports object identical to regeneratorRuntime.
      module.exports = runtime;
    }
    // Don't bother evaluating the rest of this file if the runtime was
    // already defined globally.
    return;
  }

  // Define the runtime globally (as expected by generated code) as either
  // module.exports (if we're in a module) or a new, empty object.
  runtime = global.regeneratorRuntime = inModule ? module.exports : {};

  function wrap(innerFn, outerFn, self, tryLocsList) {
    // If outerFn provided and outerFn.prototype is a Generator, then outerFn.prototype instanceof Generator.
    var protoGenerator = outerFn && outerFn.prototype instanceof Generator ? outerFn : Generator;
    var generator = Object.create(protoGenerator.prototype);
    var context = new Context(tryLocsList || []);

    // The ._invoke method unifies the implementations of the .next,
    // .throw, and .return methods.
    generator._invoke = makeInvokeMethod(innerFn, self, context);

    return generator;
  }
  runtime.wrap = wrap;

  // Try/catch helper to minimize deoptimizations. Returns a completion
  // record like context.tryEntries[i].completion. This interface could
  // have been (and was previously) designed to take a closure to be
  // invoked without arguments, but in all the cases we care about we
  // already have an existing method we want to call, so there's no need
  // to create a new function object. We can even get away with assuming
  // the method takes exactly one argument, since that happens to be true
  // in every case, so we don't have to touch the arguments object. The
  // only additional allocation required is the completion record, which
  // has a stable shape and so hopefully should be cheap to allocate.
  function tryCatch(fn, obj, arg) {
    try {
      return { type: "normal", arg: fn.call(obj, arg) };
    } catch (err) {
      return { type: "throw", arg: err };
    }
  }

  var GenStateSuspendedStart = "suspendedStart";
  var GenStateSuspendedYield = "suspendedYield";
  var GenStateExecuting = "executing";
  var GenStateCompleted = "completed";

  // Returning this object from the innerFn has the same effect as
  // breaking out of the dispatch switch statement.
  var ContinueSentinel = {};

  // Dummy constructor functions that we use as the .constructor and
  // .constructor.prototype properties for functions that return Generator
  // objects. For full spec compliance, you may wish to configure your
  // minifier not to mangle the names of these two functions.
  function Generator() {}
  function GeneratorFunction() {}
  function GeneratorFunctionPrototype() {}

  // This is a polyfill for %IteratorPrototype% for environments that
  // don't natively support it.
  var IteratorPrototype = {};
  IteratorPrototype[iteratorSymbol] = function () {
    return this;
  };

  var getProto = Object.getPrototypeOf;
  var NativeIteratorPrototype = getProto && getProto(getProto(values([])));
  if (NativeIteratorPrototype &&
      NativeIteratorPrototype !== Op &&
      hasOwn.call(NativeIteratorPrototype, iteratorSymbol)) {
    // This environment has a native %IteratorPrototype%; use it instead
    // of the polyfill.
    IteratorPrototype = NativeIteratorPrototype;
  }

  var Gp = GeneratorFunctionPrototype.prototype =
    Generator.prototype = Object.create(IteratorPrototype);
  GeneratorFunction.prototype = Gp.constructor = GeneratorFunctionPrototype;
  GeneratorFunctionPrototype.constructor = GeneratorFunction;
  GeneratorFunctionPrototype[toStringTagSymbol] =
    GeneratorFunction.displayName = "GeneratorFunction";

  // Helper for defining the .next, .throw, and .return methods of the
  // Iterator interface in terms of a single ._invoke method.
  function defineIteratorMethods(prototype) {
    ["next", "throw", "return"].forEach(function(method) {
      prototype[method] = function(arg) {
        return this._invoke(method, arg);
      };
    });
  }

  runtime.isGeneratorFunction = function(genFun) {
    var ctor = typeof genFun === "function" && genFun.constructor;
    return ctor
      ? ctor === GeneratorFunction ||
        // For the native GeneratorFunction constructor, the best we can
        // do is to check its .name property.
        (ctor.displayName || ctor.name) === "GeneratorFunction"
      : false;
  };

  runtime.mark = function(genFun) {
    if (Object.setPrototypeOf) {
      Object.setPrototypeOf(genFun, GeneratorFunctionPrototype);
    } else {
      genFun.__proto__ = GeneratorFunctionPrototype;
      if (!(toStringTagSymbol in genFun)) {
        genFun[toStringTagSymbol] = "GeneratorFunction";
      }
    }
    genFun.prototype = Object.create(Gp);
    return genFun;
  };

  // Within the body of any async function, `await x` is transformed to
  // `yield regeneratorRuntime.awrap(x)`, so that the runtime can test
  // `hasOwn.call(value, "__await")` to determine if the yielded value is
  // meant to be awaited.
  runtime.awrap = function(arg) {
    return { __await: arg };
  };

  function AsyncIterator(generator) {
    function invoke(method, arg, resolve, reject) {
      var record = tryCatch(generator[method], generator, arg);
      if (record.type === "throw") {
        reject(record.arg);
      } else {
        var result = record.arg;
        var value = result.value;
        if (value &&
            typeof value === "object" &&
            hasOwn.call(value, "__await")) {
          return Promise.resolve(value.__await).then(function(value) {
            invoke("next", value, resolve, reject);
          }, function(err) {
            invoke("throw", err, resolve, reject);
          });
        }

        return Promise.resolve(value).then(function(unwrapped) {
          // When a yielded Promise is resolved, its final value becomes
          // the .value of the Promise<{value,done}> result for the
          // current iteration. If the Promise is rejected, however, the
          // result for this iteration will be rejected with the same
          // reason. Note that rejections of yielded Promises are not
          // thrown back into the generator function, as is the case
          // when an awaited Promise is rejected. This difference in
          // behavior between yield and await is important, because it
          // allows the consumer to decide what to do with the yielded
          // rejection (swallow it and continue, manually .throw it back
          // into the generator, abandon iteration, whatever). With
          // await, by contrast, there is no opportunity to examine the
          // rejection reason outside the generator function, so the
          // only option is to throw it from the await expression, and
          // let the generator function handle the exception.
          result.value = unwrapped;
          resolve(result);
        }, reject);
      }
    }

    var previousPromise;

    function enqueue(method, arg) {
      function callInvokeWithMethodAndArg() {
        return new Promise(function(resolve, reject) {
          invoke(method, arg, resolve, reject);
        });
      }

      return previousPromise =
        // If enqueue has been called before, then we want to wait until
        // all previous Promises have been resolved before calling invoke,
        // so that results are always delivered in the correct order. If
        // enqueue has not been called before, then it is important to
        // call invoke immediately, without waiting on a callback to fire,
        // so that the async generator function has the opportunity to do
        // any necessary setup in a predictable way. This predictability
        // is why the Promise constructor synchronously invokes its
        // executor callback, and why async functions synchronously
        // execute code before the first await. Since we implement simple
        // async functions in terms of async generators, it is especially
        // important to get this right, even though it requires care.
        previousPromise ? previousPromise.then(
          callInvokeWithMethodAndArg,
          // Avoid propagating failures to Promises returned by later
          // invocations of the iterator.
          callInvokeWithMethodAndArg
        ) : callInvokeWithMethodAndArg();
    }

    // Define the unified helper method that is used to implement .next,
    // .throw, and .return (see defineIteratorMethods).
    this._invoke = enqueue;
  }

  defineIteratorMethods(AsyncIterator.prototype);
  AsyncIterator.prototype[asyncIteratorSymbol] = function () {
    return this;
  };
  runtime.AsyncIterator = AsyncIterator;

  // Note that simple async functions are implemented on top of
  // AsyncIterator objects; they just return a Promise for the value of
  // the final result produced by the iterator.
  runtime.async = function(innerFn, outerFn, self, tryLocsList) {
    var iter = new AsyncIterator(
      wrap(innerFn, outerFn, self, tryLocsList)
    );

    return runtime.isGeneratorFunction(outerFn)
      ? iter // If outerFn is a generator, return the full iterator.
      : iter.next().then(function(result) {
          return result.done ? result.value : iter.next();
        });
  };

  function makeInvokeMethod(innerFn, self, context) {
    var state = GenStateSuspendedStart;

    return function invoke(method, arg) {
      if (state === GenStateExecuting) {
        throw new Error("Generator is already running");
      }

      if (state === GenStateCompleted) {
        if (method === "throw") {
          throw arg;
        }

        // Be forgiving, per 25.3.3.3.3 of the spec:
        // https://people.mozilla.org/~jorendorff/es6-draft.html#sec-generatorresume
        return doneResult();
      }

      context.method = method;
      context.arg = arg;

      while (true) {
        var delegate = context.delegate;
        if (delegate) {
          var delegateResult = maybeInvokeDelegate(delegate, context);
          if (delegateResult) {
            if (delegateResult === ContinueSentinel) continue;
            return delegateResult;
          }
        }

        if (context.method === "next") {
          // Setting context._sent for legacy support of Babel's
          // function.sent implementation.
          context.sent = context._sent = context.arg;

        } else if (context.method === "throw") {
          if (state === GenStateSuspendedStart) {
            state = GenStateCompleted;
            throw context.arg;
          }

          context.dispatchException(context.arg);

        } else if (context.method === "return") {
          context.abrupt("return", context.arg);
        }

        state = GenStateExecuting;

        var record = tryCatch(innerFn, self, context);
        if (record.type === "normal") {
          // If an exception is thrown from innerFn, we leave state ===
          // GenStateExecuting and loop back for another invocation.
          state = context.done
            ? GenStateCompleted
            : GenStateSuspendedYield;

          if (record.arg === ContinueSentinel) {
            continue;
          }

          return {
            value: record.arg,
            done: context.done
          };

        } else if (record.type === "throw") {
          state = GenStateCompleted;
          // Dispatch the exception by looping back around to the
          // context.dispatchException(context.arg) call above.
          context.method = "throw";
          context.arg = record.arg;
        }
      }
    };
  }

  // Call delegate.iterator[context.method](context.arg) and handle the
  // result, either by returning a { value, done } result from the
  // delegate iterator, or by modifying context.method and context.arg,
  // setting context.delegate to null, and returning the ContinueSentinel.
  function maybeInvokeDelegate(delegate, context) {
    var method = delegate.iterator[context.method];
    if (method === undefined) {
      // A .throw or .return when the delegate iterator has no .throw
      // method always terminates the yield* loop.
      context.delegate = null;

      if (context.method === "throw") {
        if (delegate.iterator.return) {
          // If the delegate iterator has a return method, give it a
          // chance to clean up.
          context.method = "return";
          context.arg = undefined;
          maybeInvokeDelegate(delegate, context);

          if (context.method === "throw") {
            // If maybeInvokeDelegate(context) changed context.method from
            // "return" to "throw", let that override the TypeError below.
            return ContinueSentinel;
          }
        }

        context.method = "throw";
        context.arg = new TypeError(
          "The iterator does not provide a 'throw' method");
      }

      return ContinueSentinel;
    }

    var record = tryCatch(method, delegate.iterator, context.arg);

    if (record.type === "throw") {
      context.method = "throw";
      context.arg = record.arg;
      context.delegate = null;
      return ContinueSentinel;
    }

    var info = record.arg;

    if (! info) {
      context.method = "throw";
      context.arg = new TypeError("iterator result is not an object");
      context.delegate = null;
      return ContinueSentinel;
    }

    if (info.done) {
      // Assign the result of the finished delegate to the temporary
      // variable specified by delegate.resultName (see delegateYield).
      context[delegate.resultName] = info.value;

      // Resume execution at the desired location (see delegateYield).
      context.next = delegate.nextLoc;

      // If context.method was "throw" but the delegate handled the
      // exception, let the outer generator proceed normally. If
      // context.method was "next", forget context.arg since it has been
      // "consumed" by the delegate iterator. If context.method was
      // "return", allow the original .return call to continue in the
      // outer generator.
      if (context.method !== "return") {
        context.method = "next";
        context.arg = undefined;
      }

    } else {
      // Re-yield the result returned by the delegate method.
      return info;
    }

    // The delegate iterator is finished, so forget it and continue with
    // the outer generator.
    context.delegate = null;
    return ContinueSentinel;
  }

  // Define Generator.prototype.{next,throw,return} in terms of the
  // unified ._invoke helper method.
  defineIteratorMethods(Gp);

  Gp[toStringTagSymbol] = "Generator";

  // A Generator should always return itself as the iterator object when the
  // @@iterator function is called on it. Some browsers' implementations of the
  // iterator prototype chain incorrectly implement this, causing the Generator
  // object to not be returned from this call. This ensures that doesn't happen.
  // See https://github.com/facebook/regenerator/issues/274 for more details.
  Gp[iteratorSymbol] = function() {
    return this;
  };

  Gp.toString = function() {
    return "[object Generator]";
  };

  function pushTryEntry(locs) {
    var entry = { tryLoc: locs[0] };

    if (1 in locs) {
      entry.catchLoc = locs[1];
    }

    if (2 in locs) {
      entry.finallyLoc = locs[2];
      entry.afterLoc = locs[3];
    }

    this.tryEntries.push(entry);
  }

  function resetTryEntry(entry) {
    var record = entry.completion || {};
    record.type = "normal";
    delete record.arg;
    entry.completion = record;
  }

  function Context(tryLocsList) {
    // The root entry object (effectively a try statement without a catch
    // or a finally block) gives us a place to store values thrown from
    // locations where there is no enclosing try statement.
    this.tryEntries = [{ tryLoc: "root" }];
    tryLocsList.forEach(pushTryEntry, this);
    this.reset(true);
  }

  runtime.keys = function(object) {
    var keys = [];
    for (var key in object) {
      keys.push(key);
    }
    keys.reverse();

    // Rather than returning an object with a next method, we keep
    // things simple and return the next function itself.
    return function next() {
      while (keys.length) {
        var key = keys.pop();
        if (key in object) {
          next.value = key;
          next.done = false;
          return next;
        }
      }

      // To avoid creating an additional object, we just hang the .value
      // and .done properties off the next function object itself. This
      // also ensures that the minifier will not anonymize the function.
      next.done = true;
      return next;
    };
  };

  function values(iterable) {
    if (iterable) {
      var iteratorMethod = iterable[iteratorSymbol];
      if (iteratorMethod) {
        return iteratorMethod.call(iterable);
      }

      if (typeof iterable.next === "function") {
        return iterable;
      }

      if (!isNaN(iterable.length)) {
        var i = -1, next = function next() {
          while (++i < iterable.length) {
            if (hasOwn.call(iterable, i)) {
              next.value = iterable[i];
              next.done = false;
              return next;
            }
          }

          next.value = undefined;
          next.done = true;

          return next;
        };

        return next.next = next;
      }
    }

    // Return an iterator with no values.
    return { next: doneResult };
  }
  runtime.values = values;

  function doneResult() {
    return { value: undefined, done: true };
  }

  Context.prototype = {
    constructor: Context,

    reset: function(skipTempReset) {
      this.prev = 0;
      this.next = 0;
      // Resetting context._sent for legacy support of Babel's
      // function.sent implementation.
      this.sent = this._sent = undefined;
      this.done = false;
      this.delegate = null;

      this.method = "next";
      this.arg = undefined;

      this.tryEntries.forEach(resetTryEntry);

      if (!skipTempReset) {
        for (var name in this) {
          // Not sure about the optimal order of these conditions:
          if (name.charAt(0) === "t" &&
              hasOwn.call(this, name) &&
              !isNaN(+name.slice(1))) {
            this[name] = undefined;
          }
        }
      }
    },

    stop: function() {
      this.done = true;

      var rootEntry = this.tryEntries[0];
      var rootRecord = rootEntry.completion;
      if (rootRecord.type === "throw") {
        throw rootRecord.arg;
      }

      return this.rval;
    },

    dispatchException: function(exception) {
      if (this.done) {
        throw exception;
      }

      var context = this;
      function handle(loc, caught) {
        record.type = "throw";
        record.arg = exception;
        context.next = loc;

        if (caught) {
          // If the dispatched exception was caught by a catch block,
          // then let that catch block handle the exception normally.
          context.method = "next";
          context.arg = undefined;
        }

        return !! caught;
      }

      for (var i = this.tryEntries.length - 1; i >= 0; --i) {
        var entry = this.tryEntries[i];
        var record = entry.completion;

        if (entry.tryLoc === "root") {
          // Exception thrown outside of any try block that could handle
          // it, so set the completion value of the entire function to
          // throw the exception.
          return handle("end");
        }

        if (entry.tryLoc <= this.prev) {
          var hasCatch = hasOwn.call(entry, "catchLoc");
          var hasFinally = hasOwn.call(entry, "finallyLoc");

          if (hasCatch && hasFinally) {
            if (this.prev < entry.catchLoc) {
              return handle(entry.catchLoc, true);
            } else if (this.prev < entry.finallyLoc) {
              return handle(entry.finallyLoc);
            }

          } else if (hasCatch) {
            if (this.prev < entry.catchLoc) {
              return handle(entry.catchLoc, true);
            }

          } else if (hasFinally) {
            if (this.prev < entry.finallyLoc) {
              return handle(entry.finallyLoc);
            }

          } else {
            throw new Error("try statement without catch or finally");
          }
        }
      }
    },

    abrupt: function(type, arg) {
      for (var i = this.tryEntries.length - 1; i >= 0; --i) {
        var entry = this.tryEntries[i];
        if (entry.tryLoc <= this.prev &&
            hasOwn.call(entry, "finallyLoc") &&
            this.prev < entry.finallyLoc) {
          var finallyEntry = entry;
          break;
        }
      }

      if (finallyEntry &&
          (type === "break" ||
           type === "continue") &&
          finallyEntry.tryLoc <= arg &&
          arg <= finallyEntry.finallyLoc) {
        // Ignore the finally entry if control is not jumping to a
        // location outside the try/catch block.
        finallyEntry = null;
      }

      var record = finallyEntry ? finallyEntry.completion : {};
      record.type = type;
      record.arg = arg;

      if (finallyEntry) {
        this.method = "next";
        this.next = finallyEntry.finallyLoc;
        return ContinueSentinel;
      }

      return this.complete(record);
    },

    complete: function(record, afterLoc) {
      if (record.type === "throw") {
        throw record.arg;
      }

      if (record.type === "break" ||
          record.type === "continue") {
        this.next = record.arg;
      } else if (record.type === "return") {
        this.rval = this.arg = record.arg;
        this.method = "return";
        this.next = "end";
      } else if (record.type === "normal" && afterLoc) {
        this.next = afterLoc;
      }

      return ContinueSentinel;
    },

    finish: function(finallyLoc) {
      for (var i = this.tryEntries.length - 1; i >= 0; --i) {
        var entry = this.tryEntries[i];
        if (entry.finallyLoc === finallyLoc) {
          this.complete(entry.completion, entry.afterLoc);
          resetTryEntry(entry);
          return ContinueSentinel;
        }
      }
    },

    "catch": function(tryLoc) {
      for (var i = this.tryEntries.length - 1; i >= 0; --i) {
        var entry = this.tryEntries[i];
        if (entry.tryLoc === tryLoc) {
          var record = entry.completion;
          if (record.type === "throw") {
            var thrown = record.arg;
            resetTryEntry(entry);
          }
          return thrown;
        }
      }

      // The context.catch method must only be called with a location
      // argument that corresponds to a known catch block.
      throw new Error("illegal catch attempt");
    },

    delegateYield: function(iterable, resultName, nextLoc) {
      this.delegate = {
        iterator: values(iterable),
        resultName: resultName,
        nextLoc: nextLoc
      };

      if (this.method === "next") {
        // Deliberately forget the last sent value so that we don't
        // accidentally pass it on to the delegate.
        this.arg = undefined;
      }

      return ContinueSentinel;
    }
  };
})(
  // In sloppy mode, unbound `this` refers to the global object, fallback to
  // Function constructor if we're in global strict mode. That is sadly a form
  // of indirect eval which violates Content Security Policy.
  (function() { return this })() || Function("return this")()
);

},{}],277:[function(require,module,exports){
function _applyDecoratedDescriptor(target, property, decorators, descriptor, context) {
  var desc = {};
  Object['ke' + 'ys'](descriptor).forEach(function (key) {
    desc[key] = descriptor[key];
  });
  desc.enumerable = !!desc.enumerable;
  desc.configurable = !!desc.configurable;

  if ('value' in desc || desc.initializer) {
    desc.writable = true;
  }

  desc = decorators.slice().reverse().reduce(function (desc, decorator) {
    return decorator(target, property, desc) || desc;
  }, desc);

  if (context && desc.initializer !== void 0) {
    desc.value = desc.initializer ? desc.initializer.call(context) : void 0;
    desc.initializer = undefined;
  }

  if (desc.initializer === void 0) {
    Object['define' + 'Property'](target, property, desc);
    desc = null;
  }

  return desc;
}

module.exports = _applyDecoratedDescriptor;
},{}],278:[function(require,module,exports){
function _arrayWithHoles(arr) {
  if (Array.isArray(arr)) return arr;
}

module.exports = _arrayWithHoles;
},{}],279:[function(require,module,exports){
function _arrayWithoutHoles(arr) {
  if (Array.isArray(arr)) {
    for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) {
      arr2[i] = arr[i];
    }

    return arr2;
  }
}

module.exports = _arrayWithoutHoles;
},{}],280:[function(require,module,exports){
function _assertThisInitialized(self) {
  if (self === void 0) {
    throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
  }

  return self;
}

module.exports = _assertThisInitialized;
},{}],281:[function(require,module,exports){
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
  try {
    var info = gen[key](arg);
    var value = info.value;
  } catch (error) {
    reject(error);
    return;
  }

  if (info.done) {
    resolve(value);
  } else {
    Promise.resolve(value).then(_next, _throw);
  }
}

function _asyncToGenerator(fn) {
  return function () {
    var self = this,
        args = arguments;
    return new Promise(function (resolve, reject) {
      var gen = fn.apply(self, args);

      function _next(value) {
        asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
      }

      function _throw(err) {
        asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
      }

      _next(undefined);
    });
  };
}

module.exports = _asyncToGenerator;
},{}],282:[function(require,module,exports){
function _classCallCheck(instance, Constructor) {
  if (!(instance instanceof Constructor)) {
    throw new TypeError("Cannot call a class as a function");
  }
}

module.exports = _classCallCheck;
},{}],283:[function(require,module,exports){
var setPrototypeOf = require("./setPrototypeOf");

function isNativeReflectConstruct() {
  if (typeof Reflect === "undefined" || !Reflect.construct) return false;
  if (Reflect.construct.sham) return false;
  if (typeof Proxy === "function") return true;

  try {
    Date.prototype.toString.call(Reflect.construct(Date, [], function () {}));
    return true;
  } catch (e) {
    return false;
  }
}

function _construct(Parent, args, Class) {
  if (isNativeReflectConstruct()) {
    module.exports = _construct = Reflect.construct;
  } else {
    module.exports = _construct = function _construct(Parent, args, Class) {
      var a = [null];
      a.push.apply(a, args);
      var Constructor = Function.bind.apply(Parent, a);
      var instance = new Constructor();
      if (Class) setPrototypeOf(instance, Class.prototype);
      return instance;
    };
  }

  return _construct.apply(null, arguments);
}

module.exports = _construct;
},{"./setPrototypeOf":297}],284:[function(require,module,exports){
function _defineProperties(target, props) {
  for (var i = 0; i < props.length; i++) {
    var descriptor = props[i];
    descriptor.enumerable = descriptor.enumerable || false;
    descriptor.configurable = true;
    if ("value" in descriptor) descriptor.writable = true;
    Object.defineProperty(target, descriptor.key, descriptor);
  }
}

function _createClass(Constructor, protoProps, staticProps) {
  if (protoProps) _defineProperties(Constructor.prototype, protoProps);
  if (staticProps) _defineProperties(Constructor, staticProps);
  return Constructor;
}

module.exports = _createClass;
},{}],285:[function(require,module,exports){
function _defineProperty(obj, key, value) {
  if (key in obj) {
    Object.defineProperty(obj, key, {
      value: value,
      enumerable: true,
      configurable: true,
      writable: true
    });
  } else {
    obj[key] = value;
  }

  return obj;
}

module.exports = _defineProperty;
},{}],286:[function(require,module,exports){
function _getPrototypeOf(o) {
  module.exports = _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) {
    return o.__proto__ || Object.getPrototypeOf(o);
  };
  return _getPrototypeOf(o);
}

module.exports = _getPrototypeOf;
},{}],287:[function(require,module,exports){
var setPrototypeOf = require("./setPrototypeOf");

function _inherits(subClass, superClass) {
  if (typeof superClass !== "function" && superClass !== null) {
    throw new TypeError("Super expression must either be null or a function");
  }

  subClass.prototype = Object.create(superClass && superClass.prototype, {
    constructor: {
      value: subClass,
      writable: true,
      configurable: true
    }
  });
  if (superClass) setPrototypeOf(subClass, superClass);
}

module.exports = _inherits;
},{"./setPrototypeOf":297}],288:[function(require,module,exports){
function _interopRequireDefault(obj) {
  return obj && obj.__esModule ? obj : {
    default: obj
  };
}

module.exports = _interopRequireDefault;
},{}],289:[function(require,module,exports){
function _interopRequireWildcard(obj) {
  if (obj && obj.__esModule) {
    return obj;
  } else {
    var newObj = {};

    if (obj != null) {
      for (var key in obj) {
        if (Object.prototype.hasOwnProperty.call(obj, key)) {
          var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {};

          if (desc.get || desc.set) {
            Object.defineProperty(newObj, key, desc);
          } else {
            newObj[key] = obj[key];
          }
        }
      }
    }

    newObj.default = obj;
    return newObj;
  }
}

module.exports = _interopRequireWildcard;
},{}],290:[function(require,module,exports){
function _isNativeFunction(fn) {
  return Function.toString.call(fn).indexOf("[native code]") !== -1;
}

module.exports = _isNativeFunction;
},{}],291:[function(require,module,exports){
function _iterableToArray(iter) {
  if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter);
}

module.exports = _iterableToArray;
},{}],292:[function(require,module,exports){
function _iterableToArrayLimit(arr, i) {
  var _arr = [];
  var _n = true;
  var _d = false;
  var _e = undefined;

  try {
    for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) {
      _arr.push(_s.value);

      if (i && _arr.length === i) break;
    }
  } catch (err) {
    _d = true;
    _e = err;
  } finally {
    try {
      if (!_n && _i["return"] != null) _i["return"]();
    } finally {
      if (_d) throw _e;
    }
  }

  return _arr;
}

module.exports = _iterableToArrayLimit;
},{}],293:[function(require,module,exports){
function _nonIterableRest() {
  throw new TypeError("Invalid attempt to destructure non-iterable instance");
}

module.exports = _nonIterableRest;
},{}],294:[function(require,module,exports){
function _nonIterableSpread() {
  throw new TypeError("Invalid attempt to spread non-iterable instance");
}

module.exports = _nonIterableSpread;
},{}],295:[function(require,module,exports){
var defineProperty = require("./defineProperty");

function _objectSpread(target) {
  for (var i = 1; i < arguments.length; i++) {
    var source = arguments[i] != null ? arguments[i] : {};
    var ownKeys = Object.keys(source);

    if (typeof Object.getOwnPropertySymbols === 'function') {
      ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) {
        return Object.getOwnPropertyDescriptor(source, sym).enumerable;
      }));
    }

    ownKeys.forEach(function (key) {
      defineProperty(target, key, source[key]);
    });
  }

  return target;
}

module.exports = _objectSpread;
},{"./defineProperty":285}],296:[function(require,module,exports){
var _typeof = require("../helpers/typeof");

var assertThisInitialized = require("./assertThisInitialized");

function _possibleConstructorReturn(self, call) {
  if (call && (_typeof(call) === "object" || typeof call === "function")) {
    return call;
  }

  return assertThisInitialized(self);
}

module.exports = _possibleConstructorReturn;
},{"../helpers/typeof":301,"./assertThisInitialized":280}],297:[function(require,module,exports){
function _setPrototypeOf(o, p) {
  module.exports = _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) {
    o.__proto__ = p;
    return o;
  };

  return _setPrototypeOf(o, p);
}

module.exports = _setPrototypeOf;
},{}],298:[function(require,module,exports){
var arrayWithHoles = require("./arrayWithHoles");

var iterableToArrayLimit = require("./iterableToArrayLimit");

var nonIterableRest = require("./nonIterableRest");

function _slicedToArray(arr, i) {
  return arrayWithHoles(arr) || iterableToArrayLimit(arr, i) || nonIterableRest();
}

module.exports = _slicedToArray;
},{"./arrayWithHoles":278,"./iterableToArrayLimit":292,"./nonIterableRest":293}],299:[function(require,module,exports){
var arrayWithHoles = require("./arrayWithHoles");

var iterableToArray = require("./iterableToArray");

var nonIterableRest = require("./nonIterableRest");

function _toArray(arr) {
  return arrayWithHoles(arr) || iterableToArray(arr) || nonIterableRest();
}

module.exports = _toArray;
},{"./arrayWithHoles":278,"./iterableToArray":291,"./nonIterableRest":293}],300:[function(require,module,exports){
var arrayWithoutHoles = require("./arrayWithoutHoles");

var iterableToArray = require("./iterableToArray");

var nonIterableSpread = require("./nonIterableSpread");

function _toConsumableArray(arr) {
  return arrayWithoutHoles(arr) || iterableToArray(arr) || nonIterableSpread();
}

module.exports = _toConsumableArray;
},{"./arrayWithoutHoles":279,"./iterableToArray":291,"./nonIterableSpread":294}],301:[function(require,module,exports){
function _typeof2(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof2 = function _typeof2(obj) { return typeof obj; }; } else { _typeof2 = function _typeof2(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof2(obj); }

function _typeof(obj) {
  if (typeof Symbol === "function" && _typeof2(Symbol.iterator) === "symbol") {
    module.exports = _typeof = function _typeof(obj) {
      return _typeof2(obj);
    };
  } else {
    module.exports = _typeof = function _typeof(obj) {
      return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : _typeof2(obj);
    };
  }

  return _typeof(obj);
}

module.exports = _typeof;
},{}],302:[function(require,module,exports){
var getPrototypeOf = require("./getPrototypeOf");

var setPrototypeOf = require("./setPrototypeOf");

var isNativeFunction = require("./isNativeFunction");

var construct = require("./construct");

function _wrapNativeSuper(Class) {
  var _cache = typeof Map === "function" ? new Map() : undefined;

  module.exports = _wrapNativeSuper = function _wrapNativeSuper(Class) {
    if (Class === null || !isNativeFunction(Class)) return Class;

    if (typeof Class !== "function") {
      throw new TypeError("Super expression must either be null or a function");
    }

    if (typeof _cache !== "undefined") {
      if (_cache.has(Class)) return _cache.get(Class);

      _cache.set(Class, Wrapper);
    }

    function Wrapper() {
      return construct(Class, arguments, getPrototypeOf(this).constructor);
    }

    Wrapper.prototype = Object.create(Class.prototype, {
      constructor: {
        value: Wrapper,
        enumerable: false,
        writable: true,
        configurable: true
      }
    });
    return setPrototypeOf(Wrapper, Class);
  };

  return _wrapNativeSuper(Class);
}

module.exports = _wrapNativeSuper;
},{"./construct":283,"./getPrototypeOf":286,"./isNativeFunction":290,"./setPrototypeOf":297}],303:[function(require,module,exports){
/**
 * Copyright (c) 2014-present, Facebook, Inc.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

// This method of obtaining a reference to the global object needs to be
// kept identical to the way it is obtained in runtime.js
var g = (function() {
  return this || (typeof self === "object" && self);
})() || Function("return this")();

// Use `getOwnPropertyNames` because not all browsers support calling
// `hasOwnProperty` on the global `self` object in a worker. See #183.
var hadRuntime = g.regeneratorRuntime &&
  Object.getOwnPropertyNames(g).indexOf("regeneratorRuntime") >= 0;

// Save the old regeneratorRuntime in case it needs to be restored later.
var oldRuntime = hadRuntime && g.regeneratorRuntime;

// Force reevalutation of runtime.js.
g.regeneratorRuntime = undefined;

module.exports = require("./runtime");

if (hadRuntime) {
  // Restore the original runtime.
  g.regeneratorRuntime = oldRuntime;
} else {
  // Remove the global property added by runtime.js.
  try {
    delete g.regeneratorRuntime;
  } catch(e) {
    g.regeneratorRuntime = undefined;
  }
}

},{"./runtime":304}],304:[function(require,module,exports){
/**
 * Copyright (c) 2014-present, Facebook, Inc.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

!(function(global) {
  "use strict";

  var Op = Object.prototype;
  var hasOwn = Op.hasOwnProperty;
  var undefined; // More compressible than void 0.
  var $Symbol = typeof Symbol === "function" ? Symbol : {};
  var iteratorSymbol = $Symbol.iterator || "@@iterator";
  var asyncIteratorSymbol = $Symbol.asyncIterator || "@@asyncIterator";
  var toStringTagSymbol = $Symbol.toStringTag || "@@toStringTag";

  var inModule = typeof module === "object";
  var runtime = global.regeneratorRuntime;
  if (runtime) {
    if (inModule) {
      // If regeneratorRuntime is defined globally and we're in a module,
      // make the exports object identical to regeneratorRuntime.
      module.exports = runtime;
    }
    // Don't bother evaluating the rest of this file if the runtime was
    // already defined globally.
    return;
  }

  // Define the runtime globally (as expected by generated code) as either
  // module.exports (if we're in a module) or a new, empty object.
  runtime = global.regeneratorRuntime = inModule ? module.exports : {};

  function wrap(innerFn, outerFn, self, tryLocsList) {
    // If outerFn provided and outerFn.prototype is a Generator, then outerFn.prototype instanceof Generator.
    var protoGenerator = outerFn && outerFn.prototype instanceof Generator ? outerFn : Generator;
    var generator = Object.create(protoGenerator.prototype);
    var context = new Context(tryLocsList || []);

    // The ._invoke method unifies the implementations of the .next,
    // .throw, and .return methods.
    generator._invoke = makeInvokeMethod(innerFn, self, context);

    return generator;
  }
  runtime.wrap = wrap;

  // Try/catch helper to minimize deoptimizations. Returns a completion
  // record like context.tryEntries[i].completion. This interface could
  // have been (and was previously) designed to take a closure to be
  // invoked without arguments, but in all the cases we care about we
  // already have an existing method we want to call, so there's no need
  // to create a new function object. We can even get away with assuming
  // the method takes exactly one argument, since that happens to be true
  // in every case, so we don't have to touch the arguments object. The
  // only additional allocation required is the completion record, which
  // has a stable shape and so hopefully should be cheap to allocate.
  function tryCatch(fn, obj, arg) {
    try {
      return { type: "normal", arg: fn.call(obj, arg) };
    } catch (err) {
      return { type: "throw", arg: err };
    }
  }

  var GenStateSuspendedStart = "suspendedStart";
  var GenStateSuspendedYield = "suspendedYield";
  var GenStateExecuting = "executing";
  var GenStateCompleted = "completed";

  // Returning this object from the innerFn has the same effect as
  // breaking out of the dispatch switch statement.
  var ContinueSentinel = {};

  // Dummy constructor functions that we use as the .constructor and
  // .constructor.prototype properties for functions that return Generator
  // objects. For full spec compliance, you may wish to configure your
  // minifier not to mangle the names of these two functions.
  function Generator() {}
  function GeneratorFunction() {}
  function GeneratorFunctionPrototype() {}

  // This is a polyfill for %IteratorPrototype% for environments that
  // don't natively support it.
  var IteratorPrototype = {};
  IteratorPrototype[iteratorSymbol] = function () {
    return this;
  };

  var getProto = Object.getPrototypeOf;
  var NativeIteratorPrototype = getProto && getProto(getProto(values([])));
  if (NativeIteratorPrototype &&
      NativeIteratorPrototype !== Op &&
      hasOwn.call(NativeIteratorPrototype, iteratorSymbol)) {
    // This environment has a native %IteratorPrototype%; use it instead
    // of the polyfill.
    IteratorPrototype = NativeIteratorPrototype;
  }

  var Gp = GeneratorFunctionPrototype.prototype =
    Generator.prototype = Object.create(IteratorPrototype);
  GeneratorFunction.prototype = Gp.constructor = GeneratorFunctionPrototype;
  GeneratorFunctionPrototype.constructor = GeneratorFunction;
  GeneratorFunctionPrototype[toStringTagSymbol] =
    GeneratorFunction.displayName = "GeneratorFunction";

  // Helper for defining the .next, .throw, and .return methods of the
  // Iterator interface in terms of a single ._invoke method.
  function defineIteratorMethods(prototype) {
    ["next", "throw", "return"].forEach(function(method) {
      prototype[method] = function(arg) {
        return this._invoke(method, arg);
      };
    });
  }

  runtime.isGeneratorFunction = function(genFun) {
    var ctor = typeof genFun === "function" && genFun.constructor;
    return ctor
      ? ctor === GeneratorFunction ||
        // For the native GeneratorFunction constructor, the best we can
        // do is to check its .name property.
        (ctor.displayName || ctor.name) === "GeneratorFunction"
      : false;
  };

  runtime.mark = function(genFun) {
    if (Object.setPrototypeOf) {
      Object.setPrototypeOf(genFun, GeneratorFunctionPrototype);
    } else {
      genFun.__proto__ = GeneratorFunctionPrototype;
      if (!(toStringTagSymbol in genFun)) {
        genFun[toStringTagSymbol] = "GeneratorFunction";
      }
    }
    genFun.prototype = Object.create(Gp);
    return genFun;
  };

  // Within the body of any async function, `await x` is transformed to
  // `yield regeneratorRuntime.awrap(x)`, so that the runtime can test
  // `hasOwn.call(value, "__await")` to determine if the yielded value is
  // meant to be awaited.
  runtime.awrap = function(arg) {
    return { __await: arg };
  };

  function AsyncIterator(generator) {
    function invoke(method, arg, resolve, reject) {
      var record = tryCatch(generator[method], generator, arg);
      if (record.type === "throw") {
        reject(record.arg);
      } else {
        var result = record.arg;
        var value = result.value;
        if (value &&
            typeof value === "object" &&
            hasOwn.call(value, "__await")) {
          return Promise.resolve(value.__await).then(function(value) {
            invoke("next", value, resolve, reject);
          }, function(err) {
            invoke("throw", err, resolve, reject);
          });
        }

        return Promise.resolve(value).then(function(unwrapped) {
          // When a yielded Promise is resolved, its final value becomes
          // the .value of the Promise<{value,done}> result for the
          // current iteration.
          result.value = unwrapped;
          resolve(result);
        }, function(error) {
          // If a rejected Promise was yielded, throw the rejection back
          // into the async generator function so it can be handled there.
          return invoke("throw", error, resolve, reject);
        });
      }
    }

    var previousPromise;

    function enqueue(method, arg) {
      function callInvokeWithMethodAndArg() {
        return new Promise(function(resolve, reject) {
          invoke(method, arg, resolve, reject);
        });
      }

      return previousPromise =
        // If enqueue has been called before, then we want to wait until
        // all previous Promises have been resolved before calling invoke,
        // so that results are always delivered in the correct order. If
        // enqueue has not been called before, then it is important to
        // call invoke immediately, without waiting on a callback to fire,
        // so that the async generator function has the opportunity to do
        // any necessary setup in a predictable way. This predictability
        // is why the Promise constructor synchronously invokes its
        // executor callback, and why async functions synchronously
        // execute code before the first await. Since we implement simple
        // async functions in terms of async generators, it is especially
        // important to get this right, even though it requires care.
        previousPromise ? previousPromise.then(
          callInvokeWithMethodAndArg,
          // Avoid propagating failures to Promises returned by later
          // invocations of the iterator.
          callInvokeWithMethodAndArg
        ) : callInvokeWithMethodAndArg();
    }

    // Define the unified helper method that is used to implement .next,
    // .throw, and .return (see defineIteratorMethods).
    this._invoke = enqueue;
  }

  defineIteratorMethods(AsyncIterator.prototype);
  AsyncIterator.prototype[asyncIteratorSymbol] = function () {
    return this;
  };
  runtime.AsyncIterator = AsyncIterator;

  // Note that simple async functions are implemented on top of
  // AsyncIterator objects; they just return a Promise for the value of
  // the final result produced by the iterator.
  runtime.async = function(innerFn, outerFn, self, tryLocsList) {
    var iter = new AsyncIterator(
      wrap(innerFn, outerFn, self, tryLocsList)
    );

    return runtime.isGeneratorFunction(outerFn)
      ? iter // If outerFn is a generator, return the full iterator.
      : iter.next().then(function(result) {
          return result.done ? result.value : iter.next();
        });
  };

  function makeInvokeMethod(innerFn, self, context) {
    var state = GenStateSuspendedStart;

    return function invoke(method, arg) {
      if (state === GenStateExecuting) {
        throw new Error("Generator is already running");
      }

      if (state === GenStateCompleted) {
        if (method === "throw") {
          throw arg;
        }

        // Be forgiving, per 25.3.3.3.3 of the spec:
        // https://people.mozilla.org/~jorendorff/es6-draft.html#sec-generatorresume
        return doneResult();
      }

      context.method = method;
      context.arg = arg;

      while (true) {
        var delegate = context.delegate;
        if (delegate) {
          var delegateResult = maybeInvokeDelegate(delegate, context);
          if (delegateResult) {
            if (delegateResult === ContinueSentinel) continue;
            return delegateResult;
          }
        }

        if (context.method === "next") {
          // Setting context._sent for legacy support of Babel's
          // function.sent implementation.
          context.sent = context._sent = context.arg;

        } else if (context.method === "throw") {
          if (state === GenStateSuspendedStart) {
            state = GenStateCompleted;
            throw context.arg;
          }

          context.dispatchException(context.arg);

        } else if (context.method === "return") {
          context.abrupt("return", context.arg);
        }

        state = GenStateExecuting;

        var record = tryCatch(innerFn, self, context);
        if (record.type === "normal") {
          // If an exception is thrown from innerFn, we leave state ===
          // GenStateExecuting and loop back for another invocation.
          state = context.done
            ? GenStateCompleted
            : GenStateSuspendedYield;

          if (record.arg === ContinueSentinel) {
            continue;
          }

          return {
            value: record.arg,
            done: context.done
          };

        } else if (record.type === "throw") {
          state = GenStateCompleted;
          // Dispatch the exception by looping back around to the
          // context.dispatchException(context.arg) call above.
          context.method = "throw";
          context.arg = record.arg;
        }
      }
    };
  }

  // Call delegate.iterator[context.method](context.arg) and handle the
  // result, either by returning a { value, done } result from the
  // delegate iterator, or by modifying context.method and context.arg,
  // setting context.delegate to null, and returning the ContinueSentinel.
  function maybeInvokeDelegate(delegate, context) {
    var method = delegate.iterator[context.method];
    if (method === undefined) {
      // A .throw or .return when the delegate iterator has no .throw
      // method always terminates the yield* loop.
      context.delegate = null;

      if (context.method === "throw") {
        if (delegate.iterator.return) {
          // If the delegate iterator has a return method, give it a
          // chance to clean up.
          context.method = "return";
          context.arg = undefined;
          maybeInvokeDelegate(delegate, context);

          if (context.method === "throw") {
            // If maybeInvokeDelegate(context) changed context.method from
            // "return" to "throw", let that override the TypeError below.
            return ContinueSentinel;
          }
        }

        context.method = "throw";
        context.arg = new TypeError(
          "The iterator does not provide a 'throw' method");
      }

      return ContinueSentinel;
    }

    var record = tryCatch(method, delegate.iterator, context.arg);

    if (record.type === "throw") {
      context.method = "throw";
      context.arg = record.arg;
      context.delegate = null;
      return ContinueSentinel;
    }

    var info = record.arg;

    if (! info) {
      context.method = "throw";
      context.arg = new TypeError("iterator result is not an object");
      context.delegate = null;
      return ContinueSentinel;
    }

    if (info.done) {
      // Assign the result of the finished delegate to the temporary
      // variable specified by delegate.resultName (see delegateYield).
      context[delegate.resultName] = info.value;

      // Resume execution at the desired location (see delegateYield).
      context.next = delegate.nextLoc;

      // If context.method was "throw" but the delegate handled the
      // exception, let the outer generator proceed normally. If
      // context.method was "next", forget context.arg since it has been
      // "consumed" by the delegate iterator. If context.method was
      // "return", allow the original .return call to continue in the
      // outer generator.
      if (context.method !== "return") {
        context.method = "next";
        context.arg = undefined;
      }

    } else {
      // Re-yield the result returned by the delegate method.
      return info;
    }

    // The delegate iterator is finished, so forget it and continue with
    // the outer generator.
    context.delegate = null;
    return ContinueSentinel;
  }

  // Define Generator.prototype.{next,throw,return} in terms of the
  // unified ._invoke helper method.
  defineIteratorMethods(Gp);

  Gp[toStringTagSymbol] = "Generator";

  // A Generator should always return itself as the iterator object when the
  // @@iterator function is called on it. Some browsers' implementations of the
  // iterator prototype chain incorrectly implement this, causing the Generator
  // object to not be returned from this call. This ensures that doesn't happen.
  // See https://github.com/facebook/regenerator/issues/274 for more details.
  Gp[iteratorSymbol] = function() {
    return this;
  };

  Gp.toString = function() {
    return "[object Generator]";
  };

  function pushTryEntry(locs) {
    var entry = { tryLoc: locs[0] };

    if (1 in locs) {
      entry.catchLoc = locs[1];
    }

    if (2 in locs) {
      entry.finallyLoc = locs[2];
      entry.afterLoc = locs[3];
    }

    this.tryEntries.push(entry);
  }

  function resetTryEntry(entry) {
    var record = entry.completion || {};
    record.type = "normal";
    delete record.arg;
    entry.completion = record;
  }

  function Context(tryLocsList) {
    // The root entry object (effectively a try statement without a catch
    // or a finally block) gives us a place to store values thrown from
    // locations where there is no enclosing try statement.
    this.tryEntries = [{ tryLoc: "root" }];
    tryLocsList.forEach(pushTryEntry, this);
    this.reset(true);
  }

  runtime.keys = function(object) {
    var keys = [];
    for (var key in object) {
      keys.push(key);
    }
    keys.reverse();

    // Rather than returning an object with a next method, we keep
    // things simple and return the next function itself.
    return function next() {
      while (keys.length) {
        var key = keys.pop();
        if (key in object) {
          next.value = key;
          next.done = false;
          return next;
        }
      }

      // To avoid creating an additional object, we just hang the .value
      // and .done properties off the next function object itself. This
      // also ensures that the minifier will not anonymize the function.
      next.done = true;
      return next;
    };
  };

  function values(iterable) {
    if (iterable) {
      var iteratorMethod = iterable[iteratorSymbol];
      if (iteratorMethod) {
        return iteratorMethod.call(iterable);
      }

      if (typeof iterable.next === "function") {
        return iterable;
      }

      if (!isNaN(iterable.length)) {
        var i = -1, next = function next() {
          while (++i < iterable.length) {
            if (hasOwn.call(iterable, i)) {
              next.value = iterable[i];
              next.done = false;
              return next;
            }
          }

          next.value = undefined;
          next.done = true;

          return next;
        };

        return next.next = next;
      }
    }

    // Return an iterator with no values.
    return { next: doneResult };
  }
  runtime.values = values;

  function doneResult() {
    return { value: undefined, done: true };
  }

  Context.prototype = {
    constructor: Context,

    reset: function(skipTempReset) {
      this.prev = 0;
      this.next = 0;
      // Resetting context._sent for legacy support of Babel's
      // function.sent implementation.
      this.sent = this._sent = undefined;
      this.done = false;
      this.delegate = null;

      this.method = "next";
      this.arg = undefined;

      this.tryEntries.forEach(resetTryEntry);

      if (!skipTempReset) {
        for (var name in this) {
          // Not sure about the optimal order of these conditions:
          if (name.charAt(0) === "t" &&
              hasOwn.call(this, name) &&
              !isNaN(+name.slice(1))) {
            this[name] = undefined;
          }
        }
      }
    },

    stop: function() {
      this.done = true;

      var rootEntry = this.tryEntries[0];
      var rootRecord = rootEntry.completion;
      if (rootRecord.type === "throw") {
        throw rootRecord.arg;
      }

      return this.rval;
    },

    dispatchException: function(exception) {
      if (this.done) {
        throw exception;
      }

      var context = this;
      function handle(loc, caught) {
        record.type = "throw";
        record.arg = exception;
        context.next = loc;

        if (caught) {
          // If the dispatched exception was caught by a catch block,
          // then let that catch block handle the exception normally.
          context.method = "next";
          context.arg = undefined;
        }

        return !! caught;
      }

      for (var i = this.tryEntries.length - 1; i >= 0; --i) {
        var entry = this.tryEntries[i];
        var record = entry.completion;

        if (entry.tryLoc === "root") {
          // Exception thrown outside of any try block that could handle
          // it, so set the completion value of the entire function to
          // throw the exception.
          return handle("end");
        }

        if (entry.tryLoc <= this.prev) {
          var hasCatch = hasOwn.call(entry, "catchLoc");
          var hasFinally = hasOwn.call(entry, "finallyLoc");

          if (hasCatch && hasFinally) {
            if (this.prev < entry.catchLoc) {
              return handle(entry.catchLoc, true);
            } else if (this.prev < entry.finallyLoc) {
              return handle(entry.finallyLoc);
            }

          } else if (hasCatch) {
            if (this.prev < entry.catchLoc) {
              return handle(entry.catchLoc, true);
            }

          } else if (hasFinally) {
            if (this.prev < entry.finallyLoc) {
              return handle(entry.finallyLoc);
            }

          } else {
            throw new Error("try statement without catch or finally");
          }
        }
      }
    },

    abrupt: function(type, arg) {
      for (var i = this.tryEntries.length - 1; i >= 0; --i) {
        var entry = this.tryEntries[i];
        if (entry.tryLoc <= this.prev &&
            hasOwn.call(entry, "finallyLoc") &&
            this.prev < entry.finallyLoc) {
          var finallyEntry = entry;
          break;
        }
      }

      if (finallyEntry &&
          (type === "break" ||
           type === "continue") &&
          finallyEntry.tryLoc <= arg &&
          arg <= finallyEntry.finallyLoc) {
        // Ignore the finally entry if control is not jumping to a
        // location outside the try/catch block.
        finallyEntry = null;
      }

      var record = finallyEntry ? finallyEntry.completion : {};
      record.type = type;
      record.arg = arg;

      if (finallyEntry) {
        this.method = "next";
        this.next = finallyEntry.finallyLoc;
        return ContinueSentinel;
      }

      return this.complete(record);
    },

    complete: function(record, afterLoc) {
      if (record.type === "throw") {
        throw record.arg;
      }

      if (record.type === "break" ||
          record.type === "continue") {
        this.next = record.arg;
      } else if (record.type === "return") {
        this.rval = this.arg = record.arg;
        this.method = "return";
        this.next = "end";
      } else if (record.type === "normal" && afterLoc) {
        this.next = afterLoc;
      }

      return ContinueSentinel;
    },

    finish: function(finallyLoc) {
      for (var i = this.tryEntries.length - 1; i >= 0; --i) {
        var entry = this.tryEntries[i];
        if (entry.finallyLoc === finallyLoc) {
          this.complete(entry.completion, entry.afterLoc);
          resetTryEntry(entry);
          return ContinueSentinel;
        }
      }
    },

    "catch": function(tryLoc) {
      for (var i = this.tryEntries.length - 1; i >= 0; --i) {
        var entry = this.tryEntries[i];
        if (entry.tryLoc === tryLoc) {
          var record = entry.completion;
          if (record.type === "throw") {
            var thrown = record.arg;
            resetTryEntry(entry);
          }
          return thrown;
        }
      }

      // The context.catch method must only be called with a location
      // argument that corresponds to a known catch block.
      throw new Error("illegal catch attempt");
    },

    delegateYield: function(iterable, resultName, nextLoc) {
      this.delegate = {
        iterator: values(iterable),
        resultName: resultName,
        nextLoc: nextLoc
      };

      if (this.method === "next") {
        // Deliberately forget the last sent value so that we don't
        // accidentally pass it on to the delegate.
        this.arg = undefined;
      }

      return ContinueSentinel;
    }
  };
})(
  // In sloppy mode, unbound `this` refers to the global object, fallback to
  // Function constructor if we're in global strict mode. That is sadly a form
  // of indirect eval which violates Content Security Policy.
  (function() {
    return this || (typeof self === "object" && self);
  })() || Function("return this")()
);

},{}],305:[function(require,module,exports){
module.exports = require("regenerator-runtime");

},{"regenerator-runtime":303}],306:[function(require,module,exports){
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.

var objectCreate = Object.create || objectCreatePolyfill
var objectKeys = Object.keys || objectKeysPolyfill
var bind = Function.prototype.bind || functionBindPolyfill

function EventEmitter() {
  if (!this._events || !Object.prototype.hasOwnProperty.call(this, '_events')) {
    this._events = objectCreate(null);
    this._eventsCount = 0;
  }

  this._maxListeners = this._maxListeners || undefined;
}
module.exports = EventEmitter;

// Backwards-compat with node 0.10.x
EventEmitter.EventEmitter = EventEmitter;

EventEmitter.prototype._events = undefined;
EventEmitter.prototype._maxListeners = undefined;

// By default EventEmitters will print a warning if more than 10 listeners are
// added to it. This is a useful default which helps finding memory leaks.
var defaultMaxListeners = 10;

var hasDefineProperty;
try {
  var o = {};
  if (Object.defineProperty) Object.defineProperty(o, 'x', { value: 0 });
  hasDefineProperty = o.x === 0;
} catch (err) { hasDefineProperty = false }
if (hasDefineProperty) {
  Object.defineProperty(EventEmitter, 'defaultMaxListeners', {
    enumerable: true,
    get: function() {
      return defaultMaxListeners;
    },
    set: function(arg) {
      // check whether the input is a positive number (whose value is zero or
      // greater and not a NaN).
      if (typeof arg !== 'number' || arg < 0 || arg !== arg)
        throw new TypeError('"defaultMaxListeners" must be a positive number');
      defaultMaxListeners = arg;
    }
  });
} else {
  EventEmitter.defaultMaxListeners = defaultMaxListeners;
}

// Obviously not all Emitters should be limited to 10. This function allows
// that to be increased. Set to zero for unlimited.
EventEmitter.prototype.setMaxListeners = function setMaxListeners(n) {
  if (typeof n !== 'number' || n < 0 || isNaN(n))
    throw new TypeError('"n" argument must be a positive number');
  this._maxListeners = n;
  return this;
};

function $getMaxListeners(that) {
  if (that._maxListeners === undefined)
    return EventEmitter.defaultMaxListeners;
  return that._maxListeners;
}

EventEmitter.prototype.getMaxListeners = function getMaxListeners() {
  return $getMaxListeners(this);
};

// These standalone emit* functions are used to optimize calling of event
// handlers for fast cases because emit() itself often has a variable number of
// arguments and can be deoptimized because of that. These functions always have
// the same number of arguments and thus do not get deoptimized, so the code
// inside them can execute faster.
function emitNone(handler, isFn, self) {
  if (isFn)
    handler.call(self);
  else {
    var len = handler.length;
    var listeners = arrayClone(handler, len);
    for (var i = 0; i < len; ++i)
      listeners[i].call(self);
  }
}
function emitOne(handler, isFn, self, arg1) {
  if (isFn)
    handler.call(self, arg1);
  else {
    var len = handler.length;
    var listeners = arrayClone(handler, len);
    for (var i = 0; i < len; ++i)
      listeners[i].call(self, arg1);
  }
}
function emitTwo(handler, isFn, self, arg1, arg2) {
  if (isFn)
    handler.call(self, arg1, arg2);
  else {
    var len = handler.length;
    var listeners = arrayClone(handler, len);
    for (var i = 0; i < len; ++i)
      listeners[i].call(self, arg1, arg2);
  }
}
function emitThree(handler, isFn, self, arg1, arg2, arg3) {
  if (isFn)
    handler.call(self, arg1, arg2, arg3);
  else {
    var len = handler.length;
    var listeners = arrayClone(handler, len);
    for (var i = 0; i < len; ++i)
      listeners[i].call(self, arg1, arg2, arg3);
  }
}

function emitMany(handler, isFn, self, args) {
  if (isFn)
    handler.apply(self, args);
  else {
    var len = handler.length;
    var listeners = arrayClone(handler, len);
    for (var i = 0; i < len; ++i)
      listeners[i].apply(self, args);
  }
}

EventEmitter.prototype.emit = function emit(type) {
  var er, handler, len, args, i, events;
  var doError = (type === 'error');

  events = this._events;
  if (events)
    doError = (doError && events.error == null);
  else if (!doError)
    return false;

  // If there is no 'error' event listener then throw.
  if (doError) {
    if (arguments.length > 1)
      er = arguments[1];
    if (er instanceof Error) {
      throw er; // Unhandled 'error' event
    } else {
      // At least give some kind of context to the user
      var err = new Error('Unhandled "error" event. (' + er + ')');
      err.context = er;
      throw err;
    }
    return false;
  }

  handler = events[type];

  if (!handler)
    return false;

  var isFn = typeof handler === 'function';
  len = arguments.length;
  switch (len) {
      // fast cases
    case 1:
      emitNone(handler, isFn, this);
      break;
    case 2:
      emitOne(handler, isFn, this, arguments[1]);
      break;
    case 3:
      emitTwo(handler, isFn, this, arguments[1], arguments[2]);
      break;
    case 4:
      emitThree(handler, isFn, this, arguments[1], arguments[2], arguments[3]);
      break;
      // slower
    default:
      args = new Array(len - 1);
      for (i = 1; i < len; i++)
        args[i - 1] = arguments[i];
      emitMany(handler, isFn, this, args);
  }

  return true;
};

function _addListener(target, type, listener, prepend) {
  var m;
  var events;
  var existing;

  if (typeof listener !== 'function')
    throw new TypeError('"listener" argument must be a function');

  events = target._events;
  if (!events) {
    events = target._events = objectCreate(null);
    target._eventsCount = 0;
  } else {
    // To avoid recursion in the case that type === "newListener"! Before
    // adding it to the listeners, first emit "newListener".
    if (events.newListener) {
      target.emit('newListener', type,
          listener.listener ? listener.listener : listener);

      // Re-assign `events` because a newListener handler could have caused the
      // this._events to be assigned to a new object
      events = target._events;
    }
    existing = events[type];
  }

  if (!existing) {
    // Optimize the case of one listener. Don't need the extra array object.
    existing = events[type] = listener;
    ++target._eventsCount;
  } else {
    if (typeof existing === 'function') {
      // Adding the second element, need to change to array.
      existing = events[type] =
          prepend ? [listener, existing] : [existing, listener];
    } else {
      // If we've already got an array, just append.
      if (prepend) {
        existing.unshift(listener);
      } else {
        existing.push(listener);
      }
    }

    // Check for listener leak
    if (!existing.warned) {
      m = $getMaxListeners(target);
      if (m && m > 0 && existing.length > m) {
        existing.warned = true;
        var w = new Error('Possible EventEmitter memory leak detected. ' +
            existing.length + ' "' + String(type) + '" listeners ' +
            'added. Use emitter.setMaxListeners() to ' +
            'increase limit.');
        w.name = 'MaxListenersExceededWarning';
        w.emitter = target;
        w.type = type;
        w.count = existing.length;
        if (typeof console === 'object' && console.warn) {
          console.warn('%s: %s', w.name, w.message);
        }
      }
    }
  }

  return target;
}

EventEmitter.prototype.addListener = function addListener(type, listener) {
  return _addListener(this, type, listener, false);
};

EventEmitter.prototype.on = EventEmitter.prototype.addListener;

EventEmitter.prototype.prependListener =
    function prependListener(type, listener) {
      return _addListener(this, type, listener, true);
    };

function onceWrapper() {
  if (!this.fired) {
    this.target.removeListener(this.type, this.wrapFn);
    this.fired = true;
    switch (arguments.length) {
      case 0:
        return this.listener.call(this.target);
      case 1:
        return this.listener.call(this.target, arguments[0]);
      case 2:
        return this.listener.call(this.target, arguments[0], arguments[1]);
      case 3:
        return this.listener.call(this.target, arguments[0], arguments[1],
            arguments[2]);
      default:
        var args = new Array(arguments.length);
        for (var i = 0; i < args.length; ++i)
          args[i] = arguments[i];
        this.listener.apply(this.target, args);
    }
  }
}

function _onceWrap(target, type, listener) {
  var state = { fired: false, wrapFn: undefined, target: target, type: type, listener: listener };
  var wrapped = bind.call(onceWrapper, state);
  wrapped.listener = listener;
  state.wrapFn = wrapped;
  return wrapped;
}

EventEmitter.prototype.once = function once(type, listener) {
  if (typeof listener !== 'function')
    throw new TypeError('"listener" argument must be a function');
  this.on(type, _onceWrap(this, type, listener));
  return this;
};

EventEmitter.prototype.prependOnceListener =
    function prependOnceListener(type, listener) {
      if (typeof listener !== 'function')
        throw new TypeError('"listener" argument must be a function');
      this.prependListener(type, _onceWrap(this, type, listener));
      return this;
    };

// Emits a 'removeListener' event if and only if the listener was removed.
EventEmitter.prototype.removeListener =
    function removeListener(type, listener) {
      var list, events, position, i, originalListener;

      if (typeof listener !== 'function')
        throw new TypeError('"listener" argument must be a function');

      events = this._events;
      if (!events)
        return this;

      list = events[type];
      if (!list)
        return this;

      if (list === listener || list.listener === listener) {
        if (--this._eventsCount === 0)
          this._events = objectCreate(null);
        else {
          delete events[type];
          if (events.removeListener)
            this.emit('removeListener', type, list.listener || listener);
        }
      } else if (typeof list !== 'function') {
        position = -1;

        for (i = list.length - 1; i >= 0; i--) {
          if (list[i] === listener || list[i].listener === listener) {
            originalListener = list[i].listener;
            position = i;
            break;
          }
        }

        if (position < 0)
          return this;

        if (position === 0)
          list.shift();
        else
          spliceOne(list, position);

        if (list.length === 1)
          events[type] = list[0];

        if (events.removeListener)
          this.emit('removeListener', type, originalListener || listener);
      }

      return this;
    };

EventEmitter.prototype.removeAllListeners =
    function removeAllListeners(type) {
      var listeners, events, i;

      events = this._events;
      if (!events)
        return this;

      // not listening for removeListener, no need to emit
      if (!events.removeListener) {
        if (arguments.length === 0) {
          this._events = objectCreate(null);
          this._eventsCount = 0;
        } else if (events[type]) {
          if (--this._eventsCount === 0)
            this._events = objectCreate(null);
          else
            delete events[type];
        }
        return this;
      }

      // emit removeListener for all listeners on all events
      if (arguments.length === 0) {
        var keys = objectKeys(events);
        var key;
        for (i = 0; i < keys.length; ++i) {
          key = keys[i];
          if (key === 'removeListener') continue;
          this.removeAllListeners(key);
        }
        this.removeAllListeners('removeListener');
        this._events = objectCreate(null);
        this._eventsCount = 0;
        return this;
      }

      listeners = events[type];

      if (typeof listeners === 'function') {
        this.removeListener(type, listeners);
      } else if (listeners) {
        // LIFO order
        for (i = listeners.length - 1; i >= 0; i--) {
          this.removeListener(type, listeners[i]);
        }
      }

      return this;
    };

function _listeners(target, type, unwrap) {
  var events = target._events;

  if (!events)
    return [];

  var evlistener = events[type];
  if (!evlistener)
    return [];

  if (typeof evlistener === 'function')
    return unwrap ? [evlistener.listener || evlistener] : [evlistener];

  return unwrap ? unwrapListeners(evlistener) : arrayClone(evlistener, evlistener.length);
}

EventEmitter.prototype.listeners = function listeners(type) {
  return _listeners(this, type, true);
};

EventEmitter.prototype.rawListeners = function rawListeners(type) {
  return _listeners(this, type, false);
};

EventEmitter.listenerCount = function(emitter, type) {
  if (typeof emitter.listenerCount === 'function') {
    return emitter.listenerCount(type);
  } else {
    return listenerCount.call(emitter, type);
  }
};

EventEmitter.prototype.listenerCount = listenerCount;
function listenerCount(type) {
  var events = this._events;

  if (events) {
    var evlistener = events[type];

    if (typeof evlistener === 'function') {
      return 1;
    } else if (evlistener) {
      return evlistener.length;
    }
  }

  return 0;
}

EventEmitter.prototype.eventNames = function eventNames() {
  return this._eventsCount > 0 ? Reflect.ownKeys(this._events) : [];
};

// About 1.5x faster than the two-arg version of Array#splice().
function spliceOne(list, index) {
  for (var i = index, k = i + 1, n = list.length; k < n; i += 1, k += 1)
    list[i] = list[k];
  list.pop();
}

function arrayClone(arr, n) {
  var copy = new Array(n);
  for (var i = 0; i < n; ++i)
    copy[i] = arr[i];
  return copy;
}

function unwrapListeners(arr) {
  var ret = new Array(arr.length);
  for (var i = 0; i < ret.length; ++i) {
    ret[i] = arr[i].listener || arr[i];
  }
  return ret;
}

function objectCreatePolyfill(proto) {
  var F = function() {};
  F.prototype = proto;
  return new F;
}
function objectKeysPolyfill(obj) {
  var keys = [];
  for (var k in obj) if (Object.prototype.hasOwnProperty.call(obj, k)) {
    keys.push(k);
  }
  return k;
}
function functionBindPolyfill(context) {
  var fn = this;
  return function () {
    return fn.apply(context, arguments);
  };
}

},{}],307:[function(require,module,exports){
"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");

var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard");

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = exports.SUPPORTED_PROTOCOL_VERSION = void 0;

var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));

var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));

var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread"));

var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));

var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));

var _applyDecoratedDescriptor2 = _interopRequireDefault(require("@babel/runtime/helpers/applyDecoratedDescriptor"));

var _utils = require("./utils");

var _http = _interopRequireDefault(require("./http"));

var _endpoint = _interopRequireDefault(require("./endpoint"));

var requests = _interopRequireWildcard(require("./requests"));

var _batch2 = require("./batch");

var _bucket = _interopRequireDefault(require("./bucket"));

var _dec, _dec2, _dec3, _dec4, _dec5, _dec6, _dec7, _class;

/**
 * Currently supported protocol version.
 * @type {String}
 */
var SUPPORTED_PROTOCOL_VERSION = "v1";
/**
 * High level HTTP client for the Kinto API.
 *
 * @example
 * const client = new KintoClient("https://kinto.dev.mozaws.net/v1");
 * client.bucket("default")
 *    .collection("my-blog")
 *    .createRecord({title: "First article"})
 *   .then(console.log.bind(console))
 *   .catch(console.error.bind(console));
 */

exports.SUPPORTED_PROTOCOL_VERSION = SUPPORTED_PROTOCOL_VERSION;
var KintoClientBase = (_dec = (0, _utils.nobatch)("This operation is not supported within a batch operation."), _dec2 = (0, _utils.nobatch)("This operation is not supported within a batch operation."), _dec3 = (0, _utils.nobatch)("This operation is not supported within a batch operation."), _dec4 = (0, _utils.nobatch)("This operation is not supported within a batch operation."), _dec5 = (0, _utils.nobatch)("Can't use batch within a batch!"), _dec6 = (0, _utils.capable)(["permissions_endpoint"]), _dec7 = (0, _utils.support)("1.4", "2.0"), (_class =
/*#__PURE__*/
function () {
  /**
   * Constructor.
   *
   * @param  {String}       remote  The remote URL.
   * @param  {Object}       [options={}]                  The options object.
   * @param  {Boolean}      [options.safe=true]           Adds concurrency headers to every requests.
   * @param  {EventEmitter} [options.events=EventEmitter] The events handler instance.
   * @param  {Object}       [options.headers={}]          The key-value headers to pass to each request.
   * @param  {Object}       [options.retry=0]             Number of retries when request fails (default: 0)
   * @param  {String}       [options.bucket="default"]    The default bucket to use.
   * @param  {String}       [options.requestMode="cors"]  The HTTP request mode (from ES6 fetch spec).
   * @param  {Number}       [options.timeout=null]        The request timeout in ms, if any.
   */
  function KintoClientBase(remote) {
    var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
    (0, _classCallCheck2.default)(this, KintoClientBase);

    if (typeof remote !== "string" || !remote.length) {
      throw new Error("Invalid remote URL: " + remote);
    }

    if (remote[remote.length - 1] === "/") {
      remote = remote.slice(0, -1);
    }

    this._backoffReleaseTime = null;
    this._requests = [];
    this._isBatch = !!options.batch;
    this._retry = options.retry || 0;
    this._safe = !!options.safe;
    this._headers = options.headers || {}; // public properties

    /**
     * The remote server base URL.
     * @type {String}
     */

    this.remote = remote;
    /**
     * Current server information.
     * @ignore
     * @type {Object|null}
     */

    this.serverInfo = null;
    /**
     * The event emitter instance. Should comply with the `EventEmitter`
     * interface.
     * @ignore
     * @type {Class}
     */

    this.events = options.events;
    var requestMode = options.requestMode,
        timeout = options.timeout;
    /**
     * The HTTP instance.
     * @ignore
     * @type {HTTP}
     */

    this.http = new _http.default(this.events, {
      requestMode: requestMode,
      timeout: timeout
    });

    this._registerHTTPEvents();
  }
  /**
   * The remote endpoint base URL. Setting the value will also extract and
   * validate the version.
   * @type {String}
   */


  (0, _createClass2.default)(KintoClientBase, [{
    key: "_registerHTTPEvents",

    /**
     * Registers HTTP events.
     * @private
     */
    value: function _registerHTTPEvents() {
      var _this = this;

      // Prevent registering event from a batch client instance
      if (!this._isBatch) {
        this.events.on("backoff", function (backoffMs) {
          _this._backoffReleaseTime = backoffMs;
        });
      }
    }
    /**
     * Retrieve a bucket object to perform operations on it.
     *
     * @param  {String}  name              The bucket name.
     * @param  {Object}  [options={}]      The request options.
     * @param  {Boolean} [options.safe]    The resulting safe option.
     * @param  {Number}  [options.retry]   The resulting retry option.
     * @param  {Object}  [options.headers] The extended headers object option.
     * @return {Bucket}
     */

  }, {
    key: "bucket",
    value: function bucket(name) {
      var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
      return new _bucket.default(this, name, {
        batch: this._isBatch,
        headers: this._getHeaders(options),
        safe: this._getSafe(options),
        retry: this._getRetry(options)
      });
    }
    /**
     * Set client "headers" for every request, updating previous headers (if any).
     *
     * @param {Object} headers The headers to merge with existing ones.
     */

  }, {
    key: "setHeaders",
    value: function setHeaders(headers) {
      this._headers = (0, _objectSpread2.default)({}, this._headers, headers);
      this.serverInfo = null;
    }
    /**
     * Get the value of "headers" for a given request, merging the
     * per-request headers with our own "default" headers.
     *
     * Note that unlike other options, headers aren't overridden, but
     * merged instead.
     *
     * @private
     * @param {Object} options The options for a request.
     * @returns {Object}
     */

  }, {
    key: "_getHeaders",
    value: function _getHeaders(options) {
      return (0, _objectSpread2.default)({}, this._headers, options.headers);
    }
    /**
     * Get the value of "safe" for a given request, using the
     * per-request option if present or falling back to our default
     * otherwise.
     *
     * @private
     * @param {Object} options The options for a request.
     * @returns {Boolean}
     */

  }, {
    key: "_getSafe",
    value: function _getSafe(options) {
      return (0, _objectSpread2.default)({
        safe: this._safe
      }, options).safe;
    }
    /**
     * As _getSafe, but for "retry".
     *
     * @private
     */

  }, {
    key: "_getRetry",
    value: function _getRetry(options) {
      return (0, _objectSpread2.default)({
        retry: this._retry
      }, options).retry;
    }
    /**
     * Retrieves the server's "hello" endpoint. This endpoint reveals
     * server capabilities and settings as well as telling the client
     * "who they are" according to their given authorization headers.
     *
     * @private
     * @param  {Object}  [options={}] The request options.
     * @param  {Object}  [options.headers={}] Headers to use when making
     *     this request.
     * @param  {Number}  [options.retry=0]    Number of retries to make
     *     when faced with transient errors.
     * @return {Promise<Object, Error>}
     */

  }, {
    key: "_getHello",
    value: function () {
      var _getHello2 = (0, _asyncToGenerator2.default)(
      /*#__PURE__*/
      _regenerator.default.mark(function _callee() {
        var options,
            path,
            _ref,
            json,
            _args = arguments;

        return _regenerator.default.wrap(function _callee$(_context) {
          while (1) {
            switch (_context.prev = _context.next) {
              case 0:
                options = _args.length > 0 && _args[0] !== undefined ? _args[0] : {};
                path = this.remote + (0, _endpoint.default)("root");
                _context.next = 4;
                return this.http.request(path, {
                  headers: this._getHeaders(options)
                }, {
                  retry: this._getRetry(options)
                });

              case 4:
                _ref = _context.sent;
                json = _ref.json;
                return _context.abrupt("return", json);

              case 7:
              case "end":
                return _context.stop();
            }
          }
        }, _callee, this);
      }));

      return function _getHello() {
        return _getHello2.apply(this, arguments);
      };
    }()
    /**
     * Retrieves server information and persist them locally. This operation is
     * usually performed a single time during the instance lifecycle.
     *
     * @param  {Object}  [options={}] The request options.
     * @param  {Number}  [options.retry=0]    Number of retries to make
     *     when faced with transient errors.
     * @return {Promise<Object, Error>}
     */

  }, {
    key: "fetchServerInfo",
    value: function () {
      var _fetchServerInfo = (0, _asyncToGenerator2.default)(
      /*#__PURE__*/
      _regenerator.default.mark(function _callee2() {
        var options,
            _args2 = arguments;
        return _regenerator.default.wrap(function _callee2$(_context2) {
          while (1) {
            switch (_context2.prev = _context2.next) {
              case 0:
                options = _args2.length > 0 && _args2[0] !== undefined ? _args2[0] : {};

                if (!this.serverInfo) {
                  _context2.next = 3;
                  break;
                }

                return _context2.abrupt("return", this.serverInfo);

              case 3:
                _context2.next = 5;
                return this._getHello({
                  retry: this._getRetry(options)
                });

              case 5:
                this.serverInfo = _context2.sent;
                return _context2.abrupt("return", this.serverInfo);

              case 7:
              case "end":
                return _context2.stop();
            }
          }
        }, _callee2, this);
      }));

      return function fetchServerInfo() {
        return _fetchServerInfo.apply(this, arguments);
      };
    }()
    /**
     * Retrieves Kinto server settings.
     *
     * @param  {Object}  [options={}] The request options.
     * @param  {Number}  [options.retry=0]    Number of retries to make
     *     when faced with transient errors.
     * @return {Promise<Object, Error>}
     */

  }, {
    key: "fetchServerSettings",
    value: function () {
      var _fetchServerSettings = (0, _asyncToGenerator2.default)(
      /*#__PURE__*/
      _regenerator.default.mark(function _callee3(options) {
        var _ref2, settings;

        return _regenerator.default.wrap(function _callee3$(_context3) {
          while (1) {
            switch (_context3.prev = _context3.next) {
              case 0:
                _context3.next = 2;
                return this.fetchServerInfo(options);

              case 2:
                _ref2 = _context3.sent;
                settings = _ref2.settings;
                return _context3.abrupt("return", settings);

              case 5:
              case "end":
                return _context3.stop();
            }
          }
        }, _callee3, this);
      }));

      return function fetchServerSettings(_x) {
        return _fetchServerSettings.apply(this, arguments);
      };
    }()
    /**
     * Retrieve server capabilities information.
     *
     * @param  {Object}  [options={}] The request options.
     * @param  {Number}  [options.retry=0]    Number of retries to make
     *     when faced with transient errors.
     * @return {Promise<Object, Error>}
     */

  }, {
    key: "fetchServerCapabilities",
    value: function () {
      var _fetchServerCapabilities = (0, _asyncToGenerator2.default)(
      /*#__PURE__*/
      _regenerator.default.mark(function _callee4() {
        var options,
            _ref3,
            capabilities,
            _args4 = arguments;

        return _regenerator.default.wrap(function _callee4$(_context4) {
          while (1) {
            switch (_context4.prev = _context4.next) {
              case 0:
                options = _args4.length > 0 && _args4[0] !== undefined ? _args4[0] : {};
                _context4.next = 3;
                return this.fetchServerInfo(options);

              case 3:
                _ref3 = _context4.sent;
                capabilities = _ref3.capabilities;
                return _context4.abrupt("return", capabilities);

              case 6:
              case "end":
                return _context4.stop();
            }
          }
        }, _callee4, this);
      }));

      return function fetchServerCapabilities() {
        return _fetchServerCapabilities.apply(this, arguments);
      };
    }()
    /**
     * Retrieve authenticated user information.
     *
     * @param  {Object}  [options={}] The request options.
     * @param  {Object}  [options.headers={}] Headers to use when making
     *     this request.
     * @param  {Number}  [options.retry=0]    Number of retries to make
     *     when faced with transient errors.
     * @return {Promise<Object, Error>}
     */

  }, {
    key: "fetchUser",
    value: function () {
      var _fetchUser = (0, _asyncToGenerator2.default)(
      /*#__PURE__*/
      _regenerator.default.mark(function _callee5() {
        var options,
            _ref4,
            user,
            _args5 = arguments;

        return _regenerator.default.wrap(function _callee5$(_context5) {
          while (1) {
            switch (_context5.prev = _context5.next) {
              case 0:
                options = _args5.length > 0 && _args5[0] !== undefined ? _args5[0] : {};
                _context5.next = 3;
                return this._getHello(options);

              case 3:
                _ref4 = _context5.sent;
                user = _ref4.user;
                return _context5.abrupt("return", user);

              case 6:
              case "end":
                return _context5.stop();
            }
          }
        }, _callee5, this);
      }));

      return function fetchUser() {
        return _fetchUser.apply(this, arguments);
      };
    }()
    /**
     * Retrieve authenticated user information.
     *
     * @param  {Object}  [options={}] The request options.
     * @param  {Number}  [options.retry=0]    Number of retries to make
     *     when faced with transient errors.
     * @return {Promise<Object, Error>}
     */

  }, {
    key: "fetchHTTPApiVersion",
    value: function () {
      var _fetchHTTPApiVersion = (0, _asyncToGenerator2.default)(
      /*#__PURE__*/
      _regenerator.default.mark(function _callee6() {
        var options,
            _ref5,
            http_api_version,
            _args6 = arguments;

        return _regenerator.default.wrap(function _callee6$(_context6) {
          while (1) {
            switch (_context6.prev = _context6.next) {
              case 0:
                options = _args6.length > 0 && _args6[0] !== undefined ? _args6[0] : {};
                _context6.next = 3;
                return this.fetchServerInfo(options);

              case 3:
                _ref5 = _context6.sent;
                http_api_version = _ref5.http_api_version;
                return _context6.abrupt("return", http_api_version);

              case 6:
              case "end":
                return _context6.stop();
            }
          }
        }, _callee6, this);
      }));

      return function fetchHTTPApiVersion() {
        return _fetchHTTPApiVersion.apply(this, arguments);
      };
    }()
    /**
     * Process batch requests, chunking them according to the batch_max_requests
     * server setting when needed.
     *
     * @param  {Array}  requests     The list of batch subrequests to perform.
     * @param  {Object} [options={}] The options object.
     * @return {Promise<Object, Error>}
     */

  }, {
    key: "_batchRequests",
    value: function () {
      var _batchRequests2 = (0, _asyncToGenerator2.default)(
      /*#__PURE__*/
      _regenerator.default.mark(function _callee7(requests) {
        var _this2 = this;

        var options,
            headers,
            serverSettings,
            maxRequests,
            chunks,
            _ref6,
            responses,
            _args7 = arguments;

        return _regenerator.default.wrap(function _callee7$(_context7) {
          while (1) {
            switch (_context7.prev = _context7.next) {
              case 0:
                options = _args7.length > 1 && _args7[1] !== undefined ? _args7[1] : {};
                headers = this._getHeaders(options);

                if (requests.length) {
                  _context7.next = 4;
                  break;
                }

                return _context7.abrupt("return", []);

              case 4:
                _context7.next = 6;
                return this.fetchServerSettings({
                  retry: this._getRetry(options)
                });

              case 6:
                serverSettings = _context7.sent;
                maxRequests = serverSettings["batch_max_requests"];

                if (!(maxRequests && requests.length > maxRequests)) {
                  _context7.next = 11;
                  break;
                }

                chunks = (0, _utils.partition)(requests, maxRequests);
                return _context7.abrupt("return", (0, _utils.pMap)(chunks, function (chunk) {
                  return _this2._batchRequests(chunk, options);
                }));

              case 11:
                _context7.next = 13;
                return this.execute({
                  // FIXME: is this really necessary, since it's also present in
                  // the "defaults"?
                  headers: headers,
                  path: (0, _endpoint.default)("batch"),
                  method: "POST",
                  body: {
                    defaults: {
                      headers: headers
                    },
                    requests: requests
                  }
                }, {
                  retry: this._getRetry(options)
                });

              case 13:
                _ref6 = _context7.sent;
                responses = _ref6.responses;
                return _context7.abrupt("return", responses);

              case 16:
              case "end":
                return _context7.stop();
            }
          }
        }, _callee7, this);
      }));

      return function _batchRequests(_x2) {
        return _batchRequests2.apply(this, arguments);
      };
    }()
    /**
     * Sends batch requests to the remote server.
     *
     * Note: Reserved for internal use only.
     *
     * @ignore
     * @param  {Function} fn                        The function to use for describing batch ops.
     * @param  {Object}   [options={}]              The options object.
     * @param  {Boolean}  [options.safe]            The safe option.
     * @param  {Number}   [options.retry]           The retry option.
     * @param  {String}   [options.bucket]          The bucket name option.
     * @param  {String}   [options.collection]      The collection name option.
     * @param  {Object}   [options.headers]         The headers object option.
     * @param  {Boolean}  [options.aggregate=false] Produces an aggregated result object.
     * @return {Promise<Object, Error>}
     */

  }, {
    key: "batch",
    value: function () {
      var _batch = (0, _asyncToGenerator2.default)(
      /*#__PURE__*/
      _regenerator.default.mark(function _callee8(fn) {
        var options,
            rootBatch,
            bucketBatch,
            collBatch,
            batchClient,
            responses,
            _args8 = arguments;
        return _regenerator.default.wrap(function _callee8$(_context8) {
          while (1) {
            switch (_context8.prev = _context8.next) {
              case 0:
                options = _args8.length > 1 && _args8[1] !== undefined ? _args8[1] : {};
                rootBatch = new KintoClientBase(this.remote, {
                  events: this.events,
                  batch: true,
                  safe: this._getSafe(options),
                  retry: this._getRetry(options)
                });

                if (options.bucket) {
                  bucketBatch = rootBatch.bucket(options.bucket);

                  if (options.collection) {
                    collBatch = bucketBatch.collection(options.collection);
                  }
                }

                batchClient = collBatch || bucketBatch || rootBatch;
                fn(batchClient);
                _context8.next = 7;
                return this._batchRequests(rootBatch._requests, options);

              case 7:
                responses = _context8.sent;

                if (!options.aggregate) {
                  _context8.next = 12;
                  break;
                }

                return _context8.abrupt("return", (0, _batch2.aggregate)(responses, rootBatch._requests));

              case 12:
                return _context8.abrupt("return", responses);

              case 13:
              case "end":
                return _context8.stop();
            }
          }
        }, _callee8, this);
      }));

      return function batch(_x3) {
        return _batch.apply(this, arguments);
      };
    }()
    /**
     * Executes an atomic HTTP request.
     *
     * @private
     * @param  {Object}  request             The request object.
     * @param  {String}  request.path        The path to fetch, relative
     *     to the Kinto server root.
     * @param  {String}  [request.method="GET"] The method to use in the
     *     request.
     * @param  {Body}    [request.body]      The request body.
     * @param  {Object}  [request.headers={}] The request headers.
     * @param  {Object}  [options={}]        The options object.
     * @param  {Boolean} [options.raw=false] If true, resolve with full response
     * @param  {Boolean} [options.stringify=true] If true, serialize body data to
     * @param  {Number}  [options.retry=0]   The number of times to
     *     retry a request if the server responds with Retry-After.
     * JSON.
     * @return {Promise<Object, Error>}
     */

  }, {
    key: "execute",
    value: function () {
      var _execute = (0, _asyncToGenerator2.default)(
      /*#__PURE__*/
      _regenerator.default.mark(function _callee9(request) {
        var options,
            _options$raw,
            raw,
            _options$stringify,
            stringify,
            msg,
            result,
            _args9 = arguments;

        return _regenerator.default.wrap(function _callee9$(_context9) {
          while (1) {
            switch (_context9.prev = _context9.next) {
              case 0:
                options = _args9.length > 1 && _args9[1] !== undefined ? _args9[1] : {};
                _options$raw = options.raw, raw = _options$raw === void 0 ? false : _options$raw, _options$stringify = options.stringify, stringify = _options$stringify === void 0 ? true : _options$stringify; // If we're within a batch, add the request to the stack to send at once.

                if (!this._isBatch) {
                  _context9.next = 6;
                  break;
                }

                this._requests.push(request); // Resolve with a message in case people attempt at consuming the result
                // from within a batch operation.


                msg = "This result is generated from within a batch " + "operation and should not be consumed.";
                return _context9.abrupt("return", raw ? {
                  json: msg,
                  headers: {
                    get: function get() {}
                  }
                } : msg);

              case 6:
                _context9.next = 8;
                return this.http.request(this.remote + request.path, (0, _utils.cleanUndefinedProperties)({
                  // Limit requests to only those parts that would be allowed in
                  // a batch request -- don't pass through other fancy fetch()
                  // options like integrity, redirect, mode because they will
                  // break on a batch request.  A batch request only allows
                  // headers, method, path (above), and body.
                  method: request.method,
                  headers: request.headers,
                  body: stringify ? JSON.stringify(request.body) : request.body
                }), {
                  retry: this._getRetry(options)
                });

              case 8:
                result = _context9.sent;
                return _context9.abrupt("return", raw ? result : result.json);

              case 10:
              case "end":
                return _context9.stop();
            }
          }
        }, _callee9, this);
      }));

      return function execute(_x4) {
        return _execute.apply(this, arguments);
      };
    }()
    /**
     * Fetch some pages from a paginated list, following the `next-page`
     * header automatically until we have fetched the requested number
     * of pages. Return a response with a `.next()` method that can be
     * called to fetch more results.
     *
     * @private
     * @param  {String}  path
     *     The path to make the request to.
     * @param  {Object}  params
     *     The parameters to use when making the request.
     * @param  {String}  [params.sort="-last_modified"]
     *     The sorting order to use when fetching.
     * @param  {Object}  [params.filters={}]
     *     The filters to send in the request.
     * @param  {Number}  [params.limit=undefined]
     *     The limit to send in the request. Undefined means no limit.
     * @param  {Number}  [params.pages=undefined]
     *     The number of pages to fetch. Undefined means one page. Pass
     *     Infinity to fetch everything.
     * @param  {String}  [params.since=undefined]
     *     The ETag from which to start fetching.
     * @param  {Object}  [options={}]
     *     Additional request-level parameters to use in all requests.
     * @param  {Object}  [options.headers={}]
     *     Headers to use during all requests.
     * @param  {Number}  [options.retry=0]
     *     Number of times to retry each request if the server responds
     *     with Retry-After.
     */

  }, {
    key: "paginatedList",
    value: function () {
      var _paginatedList = (0, _asyncToGenerator2.default)(
      /*#__PURE__*/
      _regenerator.default.mark(function _callee13(path, params) {
        var _this3 = this;

        var options,
            _sort$params,
            sort,
            filters,
            limit,
            pages,
            since,
            querystring,
            results,
            current,
            next,
            processNextPage,
            pageResults,
            handleResponse,
            _args13 = arguments;

        return _regenerator.default.wrap(function _callee13$(_context13) {
          while (1) {
            switch (_context13.prev = _context13.next) {
              case 0:
                options = _args13.length > 2 && _args13[2] !== undefined ? _args13[2] : {};
                // FIXME: this is called even in batch requests, which doesn't
                // make any sense (since all batch requests get a "dummy"
                // response; see execute() above).
                _sort$params = (0, _objectSpread2.default)({
                  sort: "-last_modified"
                }, params), sort = _sort$params.sort, filters = _sort$params.filters, limit = _sort$params.limit, pages = _sort$params.pages, since = _sort$params.since; // Safety/Consistency check on ETag value.

                if (!(since && typeof since !== "string")) {
                  _context13.next = 4;
                  break;
                }

                throw new Error("Invalid value for since (".concat(since, "), should be ETag value."));

              case 4:
                querystring = (0, _utils.qsify)((0, _objectSpread2.default)({}, filters, {
                  _sort: sort,
                  _limit: limit,
                  _since: since
                }));
                results = [], current = 0;

                next =
                /*#__PURE__*/
                function () {
                  var _ref7 = (0, _asyncToGenerator2.default)(
                  /*#__PURE__*/
                  _regenerator.default.mark(function _callee10(nextPage) {
                    return _regenerator.default.wrap(function _callee10$(_context10) {
                      while (1) {
                        switch (_context10.prev = _context10.next) {
                          case 0:
                            if (nextPage) {
                              _context10.next = 2;
                              break;
                            }

                            throw new Error("Pagination exhausted.");

                          case 2:
                            return _context10.abrupt("return", processNextPage(nextPage));

                          case 3:
                          case "end":
                            return _context10.stop();
                        }
                      }
                    }, _callee10, this);
                  }));

                  return function next(_x7) {
                    return _ref7.apply(this, arguments);
                  };
                }();

                processNextPage =
                /*#__PURE__*/
                function () {
                  var _ref8 = (0, _asyncToGenerator2.default)(
                  /*#__PURE__*/
                  _regenerator.default.mark(function _callee11(nextPage) {
                    var headers;
                    return _regenerator.default.wrap(function _callee11$(_context11) {
                      while (1) {
                        switch (_context11.prev = _context11.next) {
                          case 0:
                            headers = options.headers;
                            _context11.t0 = handleResponse;
                            _context11.next = 4;
                            return _this3.http.request(nextPage, {
                              headers: headers
                            });

                          case 4:
                            _context11.t1 = _context11.sent;
                            return _context11.abrupt("return", (0, _context11.t0)(_context11.t1));

                          case 6:
                          case "end":
                            return _context11.stop();
                        }
                      }
                    }, _callee11, this);
                  }));

                  return function processNextPage(_x8) {
                    return _ref8.apply(this, arguments);
                  };
                }();

                pageResults = function pageResults(results, nextPage, etag, totalRecords) {
                  // ETag string is supposed to be opaque and stored «as-is».
                  // ETag header values are quoted (because of * and W/"foo").
                  return {
                    last_modified: etag ? etag.replace(/"/g, "") : etag,
                    data: results,
                    next: next.bind(null, nextPage),
                    hasNextPage: !!nextPage,
                    totalRecords: totalRecords
                  };
                };

                handleResponse =
                /*#__PURE__*/
                function () {
                  var _ref9 = (0, _asyncToGenerator2.default)(
                  /*#__PURE__*/
                  _regenerator.default.mark(function _callee12(_ref10) {
                    var headers, json, nextPage, etag, totalRecords;
                    return _regenerator.default.wrap(function _callee12$(_context12) {
                      while (1) {
                        switch (_context12.prev = _context12.next) {
                          case 0:
                            headers = _ref10.headers, json = _ref10.json;
                            nextPage = headers.get("Next-Page");
                            etag = headers.get("ETag");
                            totalRecords = parseInt(headers.get("Total-Records"), 10);

                            if (pages) {
                              _context12.next = 6;
                              break;
                            }

                            return _context12.abrupt("return", pageResults(json.data, nextPage, etag, totalRecords));

                          case 6:
                            // Aggregate new results with previous ones
                            results = results.concat(json.data);
                            current += 1;

                            if (!(current >= pages || !nextPage)) {
                              _context12.next = 10;
                              break;
                            }

                            return _context12.abrupt("return", pageResults(results, nextPage, etag, totalRecords));

                          case 10:
                            return _context12.abrupt("return", processNextPage(nextPage));

                          case 11:
                          case "end":
                            return _context12.stop();
                        }
                      }
                    }, _callee12, this);
                  }));

                  return function handleResponse(_x9) {
                    return _ref9.apply(this, arguments);
                  };
                }();

                _context13.t0 = handleResponse;
                _context13.next = 13;
                return this.execute( // N.B.: This doesn't use _getHeaders, because all calls to
                // `paginatedList` are assumed to come from calls that already
                // have headers merged at e.g. the bucket or collection level.
                {
                  headers: options.headers,
                  path: path + "?" + querystring
                }, // N.B. This doesn't use _getRetry, because all calls to
                // `paginatedList` are assumed to come from calls that already
                // used `_getRetry` at e.g. the bucket or collection level.
                {
                  raw: true,
                  retry: options.retry || 0
                });

              case 13:
                _context13.t1 = _context13.sent;
                return _context13.abrupt("return", (0, _context13.t0)(_context13.t1));

              case 15:
              case "end":
                return _context13.stop();
            }
          }
        }, _callee13, this);
      }));

      return function paginatedList(_x5, _x6) {
        return _paginatedList.apply(this, arguments);
      };
    }()
    /**
     * Lists all permissions.
     *
     * @param  {Object} [options={}]      The options object.
     * @param  {Object} [options.headers={}] Headers to use when making
     *     this request.
     * @param  {Number} [options.retry=0]    Number of retries to make
     *     when faced with transient errors.
     * @return {Promise<Object[], Error>}
     */

  }, {
    key: "listPermissions",
    value: function () {
      var _listPermissions = (0, _asyncToGenerator2.default)(
      /*#__PURE__*/
      _regenerator.default.mark(function _callee14() {
        var options,
            path,
            paginationOptions,
            _args14 = arguments;
        return _regenerator.default.wrap(function _callee14$(_context14) {
          while (1) {
            switch (_context14.prev = _context14.next) {
              case 0:
                options = _args14.length > 0 && _args14[0] !== undefined ? _args14[0] : {};
                path = (0, _endpoint.default)("permissions"); // Ensure the default sort parameter is something that exists in permissions
                // entries, as `last_modified` doesn't; here, we pick "id".

                paginationOptions = (0, _objectSpread2.default)({
                  sort: "id"
                }, options);
                return _context14.abrupt("return", this.paginatedList(path, paginationOptions, {
                  headers: this._getHeaders(options),
                  retry: this._getRetry(options)
                }));

              case 4:
              case "end":
                return _context14.stop();
            }
          }
        }, _callee14, this);
      }));

      return function listPermissions() {
        return _listPermissions.apply(this, arguments);
      };
    }()
    /**
     * Retrieves the list of buckets.
     *
     * @param  {Object} [options={}]      The options object.
     * @param  {Object} [options.headers={}] Headers to use when making
     *     this request.
     * @param  {Number} [options.retry=0]    Number of retries to make
     *     when faced with transient errors.
     * @return {Promise<Object[], Error>}
     */

  }, {
    key: "listBuckets",
    value: function () {
      var _listBuckets = (0, _asyncToGenerator2.default)(
      /*#__PURE__*/
      _regenerator.default.mark(function _callee15() {
        var options,
            path,
            _args15 = arguments;
        return _regenerator.default.wrap(function _callee15$(_context15) {
          while (1) {
            switch (_context15.prev = _context15.next) {
              case 0:
                options = _args15.length > 0 && _args15[0] !== undefined ? _args15[0] : {};
                path = (0, _endpoint.default)("bucket");
                return _context15.abrupt("return", this.paginatedList(path, options, {
                  headers: this._getHeaders(options),
                  retry: this._getRetry(options)
                }));

              case 3:
              case "end":
                return _context15.stop();
            }
          }
        }, _callee15, this);
      }));

      return function listBuckets() {
        return _listBuckets.apply(this, arguments);
      };
    }()
    /**
     * Creates a new bucket on the server.
     *
     * @param  {String|null}  id                The bucket name (optional).
     * @param  {Object}       [options={}]      The options object.
     * @param  {Boolean}      [options.data]    The bucket data option.
     * @param  {Boolean}      [options.safe]    The safe option.
     * @param  {Object}       [options.headers] The headers object option.
     * @param  {Number}       [options.retry=0] Number of retries to make
     *     when faced with transient errors.
     * @return {Promise<Object, Error>}
     */

  }, {
    key: "createBucket",
    value: function () {
      var _createBucket = (0, _asyncToGenerator2.default)(
      /*#__PURE__*/
      _regenerator.default.mark(function _callee16(id) {
        var options,
            _options$data,
            data,
            permissions,
            path,
            _args16 = arguments;

        return _regenerator.default.wrap(function _callee16$(_context16) {
          while (1) {
            switch (_context16.prev = _context16.next) {
              case 0:
                options = _args16.length > 1 && _args16[1] !== undefined ? _args16[1] : {};
                _options$data = options.data, data = _options$data === void 0 ? {} : _options$data, permissions = options.permissions;

                if (id != null) {
                  data.id = id;
                }

                path = data.id ? (0, _endpoint.default)("bucket", data.id) : (0, _endpoint.default)("bucket");
                return _context16.abrupt("return", this.execute(requests.createRequest(path, {
                  data: data,
                  permissions: permissions
                }, {
                  headers: this._getHeaders(options),
                  safe: this._getSafe(options)
                }), {
                  retry: this._getRetry(options)
                }));

              case 5:
              case "end":
                return _context16.stop();
            }
          }
        }, _callee16, this);
      }));

      return function createBucket(_x10) {
        return _createBucket.apply(this, arguments);
      };
    }()
    /**
     * Deletes a bucket from the server.
     *
     * @ignore
     * @param  {Object|String} bucket                  The bucket to delete.
     * @param  {Object}        [options={}]            The options object.
     * @param  {Boolean}       [options.safe]          The safe option.
     * @param  {Object}        [options.headers]       The headers object option.
     * @param  {Number}        [options.retry=0]       Number of retries to make
     *     when faced with transient errors.
     * @param  {Number}        [options.last_modified] The last_modified option.
     * @return {Promise<Object, Error>}
     */

  }, {
    key: "deleteBucket",
    value: function () {
      var _deleteBucket = (0, _asyncToGenerator2.default)(
      /*#__PURE__*/
      _regenerator.default.mark(function _callee17(bucket) {
        var options,
            bucketObj,
            path,
            _bucketObj$options,
            last_modified,
            _args17 = arguments;

        return _regenerator.default.wrap(function _callee17$(_context17) {
          while (1) {
            switch (_context17.prev = _context17.next) {
              case 0:
                options = _args17.length > 1 && _args17[1] !== undefined ? _args17[1] : {};
                bucketObj = (0, _utils.toDataBody)(bucket);

                if (bucketObj.id) {
                  _context17.next = 4;
                  break;
                }

                throw new Error("A bucket id is required.");

              case 4:
                path = (0, _endpoint.default)("bucket", bucketObj.id);
                _bucketObj$options = (0, _objectSpread2.default)({}, bucketObj, options), last_modified = _bucketObj$options.last_modified;
                return _context17.abrupt("return", this.execute(requests.deleteRequest(path, {
                  last_modified: last_modified,
                  headers: this._getHeaders(options),
                  safe: this._getSafe(options)
                }), {
                  retry: this._getRetry(options)
                }));

              case 7:
              case "end":
                return _context17.stop();
            }
          }
        }, _callee17, this);
      }));

      return function deleteBucket(_x11) {
        return _deleteBucket.apply(this, arguments);
      };
    }()
    /**
     * Deletes all buckets on the server.
     *
     * @ignore
     * @param  {Object}  [options={}]            The options object.
     * @param  {Boolean} [options.safe]          The safe option.
     * @param  {Object}  [options.headers]       The headers object option.
     * @param  {Number}  [options.last_modified] The last_modified option.
     * @return {Promise<Object, Error>}
     */

  }, {
    key: "deleteBuckets",
    value: function () {
      var _deleteBuckets = (0, _asyncToGenerator2.default)(
      /*#__PURE__*/
      _regenerator.default.mark(function _callee18() {
        var options,
            path,
            _args18 = arguments;
        return _regenerator.default.wrap(function _callee18$(_context18) {
          while (1) {
            switch (_context18.prev = _context18.next) {
              case 0:
                options = _args18.length > 0 && _args18[0] !== undefined ? _args18[0] : {};
                path = (0, _endpoint.default)("bucket");
                return _context18.abrupt("return", this.execute(requests.deleteRequest(path, {
                  last_modified: options.last_modified,
                  headers: this._getHeaders(options),
                  safe: this._getSafe(options)
                }), {
                  retry: this._getRetry(options)
                }));

              case 3:
              case "end":
                return _context18.stop();
            }
          }
        }, _callee18, this);
      }));

      return function deleteBuckets() {
        return _deleteBuckets.apply(this, arguments);
      };
    }()
  }, {
    key: "remote",
    get: function get() {
      return this._remote;
    }
    /**
     * @ignore
     */
    ,
    set: function set(url) {
      var version;

      try {
        version = url.match(/\/(v\d+)\/?$/)[1];
      } catch (err) {
        throw new Error("The remote URL must contain the version: " + url);
      }

      if (version !== SUPPORTED_PROTOCOL_VERSION) {
        throw new Error("Unsupported protocol version: ".concat(version));
      }

      this._remote = url;
      this._version = version;
    }
    /**
     * The current server protocol version, eg. `v1`.
     * @type {String}
     */

  }, {
    key: "version",
    get: function get() {
      return this._version;
    }
    /**
     * Backoff remaining time, in milliseconds. Defaults to zero if no backoff is
     * ongoing.
     *
     * @type {Number}
     */

  }, {
    key: "backoff",
    get: function get() {
      var currentTime = new Date().getTime();

      if (this._backoffReleaseTime && currentTime < this._backoffReleaseTime) {
        return this._backoffReleaseTime - currentTime;
      }

      return 0;
    }
  }]);
  return KintoClientBase;
}(), ((0, _applyDecoratedDescriptor2.default)(_class.prototype, "fetchServerSettings", [_dec], Object.getOwnPropertyDescriptor(_class.prototype, "fetchServerSettings"), _class.prototype), (0, _applyDecoratedDescriptor2.default)(_class.prototype, "fetchServerCapabilities", [_dec2], Object.getOwnPropertyDescriptor(_class.prototype, "fetchServerCapabilities"), _class.prototype), (0, _applyDecoratedDescriptor2.default)(_class.prototype, "fetchUser", [_dec3], Object.getOwnPropertyDescriptor(_class.prototype, "fetchUser"), _class.prototype), (0, _applyDecoratedDescriptor2.default)(_class.prototype, "fetchHTTPApiVersion", [_dec4], Object.getOwnPropertyDescriptor(_class.prototype, "fetchHTTPApiVersion"), _class.prototype), (0, _applyDecoratedDescriptor2.default)(_class.prototype, "batch", [_dec5], Object.getOwnPropertyDescriptor(_class.prototype, "batch"), _class.prototype), (0, _applyDecoratedDescriptor2.default)(_class.prototype, "listPermissions", [_dec6], Object.getOwnPropertyDescriptor(_class.prototype, "listPermissions"), _class.prototype), (0, _applyDecoratedDescriptor2.default)(_class.prototype, "deleteBuckets", [_dec7], Object.getOwnPropertyDescriptor(_class.prototype, "deleteBuckets"), _class.prototype)), _class));
exports.default = KintoClientBase;
},{"./batch":308,"./bucket":309,"./endpoint":311,"./http":313,"./requests":315,"./utils":316,"@babel/runtime/helpers/applyDecoratedDescriptor":277,"@babel/runtime/helpers/asyncToGenerator":281,"@babel/runtime/helpers/classCallCheck":282,"@babel/runtime/helpers/createClass":284,"@babel/runtime/helpers/interopRequireDefault":288,"@babel/runtime/helpers/interopRequireWildcard":289,"@babel/runtime/helpers/objectSpread":295,"@babel/runtime/regenerator":305}],308:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.aggregate = aggregate;

/**
 * Exports batch responses as a result object.
 *
 * @private
 * @param  {Array} responses The batch subrequest responses.
 * @param  {Array} requests  The initial issued requests.
 * @return {Object}
 */
function aggregate() {
  var responses = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
  var requests = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];

  if (responses.length !== requests.length) {
    throw new Error("Responses length should match requests one.");
  }

  var results = {
    errors: [],
    published: [],
    conflicts: [],
    skipped: []
  };
  return responses.reduce(function (acc, response, index) {
    var status = response.status;
    var request = requests[index];

    if (status >= 200 && status < 400) {
      acc.published.push(response.body);
    } else if (status === 404) {
      // Extract the id manually from request path while waiting for Kinto/kinto#818
      var regex = /(buckets|groups|collections|records)\/([^/]+)$/;
      var extracts = request.path.match(regex);
      var id = extracts.length === 3 ? extracts[2] : undefined;
      acc.skipped.push({
        id: id,
        path: request.path,
        error: response.body
      });
    } else if (status === 412) {
      acc.conflicts.push({
        // XXX: specifying the type is probably superfluous
        type: "outgoing",
        local: request.body,
        remote: response.body.details && response.body.details.existing || null
      });
    } else {
      acc.errors.push({
        path: request.path,
        sent: request,
        error: response.body
      });
    }

    return acc;
  }, results);
}
},{}],309:[function(require,module,exports){
"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");

var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard");

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;

var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));

var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));

var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread"));

var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));

var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));

var _applyDecoratedDescriptor2 = _interopRequireDefault(require("@babel/runtime/helpers/applyDecoratedDescriptor"));

var _utils = require("./utils");

var _collection = _interopRequireDefault(require("./collection"));

var requests = _interopRequireWildcard(require("./requests"));

var _endpoint = _interopRequireDefault(require("./endpoint"));

var _dec, _class;

/**
 * Abstract representation of a selected bucket.
 *
 */
var Bucket = (_dec = (0, _utils.capable)(["history"]), (_class =
/*#__PURE__*/
function () {
  /**
   * Constructor.
   *
   * @param  {KintoClient} client            The client instance.
   * @param  {String}      name              The bucket name.
   * @param  {Object}      [options={}]      The headers object option.
   * @param  {Object}      [options.headers] The headers object option.
   * @param  {Boolean}     [options.safe]    The safe option.
   * @param  {Number}      [options.retry]   The retry option.
   */
  function Bucket(client, name) {
    var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
    (0, _classCallCheck2.default)(this, Bucket);

    /**
     * @ignore
     */
    this.client = client;
    /**
     * The bucket name.
     * @type {String}
     */

    this.name = name;
    /**
     * @ignore
     */

    this._isBatch = !!options.batch;
    /**
     * @ignore
     */

    this._headers = options.headers || {};
    this._retry = options.retry || 0;
    this._safe = !!options.safe;
  }
  /**
   * Get the value of "headers" for a given request, merging the
   * per-request headers with our own "default" headers.
   *
   * @private
   */


  (0, _createClass2.default)(Bucket, [{
    key: "_getHeaders",
    value: function _getHeaders(options) {
      return (0, _objectSpread2.default)({}, this._headers, options.headers);
    }
    /**
     * Get the value of "safe" for a given request, using the
     * per-request option if present or falling back to our default
     * otherwise.
     *
     * @private
     * @param {Object} options The options for a request.
     * @returns {Boolean}
     */

  }, {
    key: "_getSafe",
    value: function _getSafe(options) {
      return (0, _objectSpread2.default)({
        safe: this._safe
      }, options).safe;
    }
    /**
     * As _getSafe, but for "retry".
     *
     * @private
     */

  }, {
    key: "_getRetry",
    value: function _getRetry(options) {
      return (0, _objectSpread2.default)({
        retry: this._retry
      }, options).retry;
    }
    /**
     * Selects a collection.
     *
     * @param  {String}  name              The collection name.
     * @param  {Object}  [options={}]      The options object.
     * @param  {Object}  [options.headers] The headers object option.
     * @param  {Boolean} [options.safe]    The safe option.
     * @return {Collection}
     */

  }, {
    key: "collection",
    value: function collection(name) {
      var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
      return new _collection.default(this.client, this, name, {
        batch: this._isBatch,
        headers: this._getHeaders(options),
        retry: this._getRetry(options),
        safe: this._getSafe(options)
      });
    }
    /**
     * Retrieves bucket data.
     *
     * @param  {Object} [options={}]      The options object.
     * @param  {Object} [options.headers] The headers object option.
     * @param  {Number} [options.retry=0] Number of retries to make
     *     when faced with transient errors.
     * @return {Promise<Object, Error>}
     */

  }, {
    key: "getData",
    value: function () {
      var _getData = (0, _asyncToGenerator2.default)(
      /*#__PURE__*/
      _regenerator.default.mark(function _callee() {
        var options,
            request,
            _ref,
            data,
            _args = arguments;

        return _regenerator.default.wrap(function _callee$(_context) {
          while (1) {
            switch (_context.prev = _context.next) {
              case 0:
                options = _args.length > 0 && _args[0] !== undefined ? _args[0] : {};
                request = {
                  headers: this._getHeaders(options),
                  path: (0, _endpoint.default)("bucket", this.name)
                };
                _context.next = 4;
                return this.client.execute(request, {
                  retry: this._getRetry(options)
                });

              case 4:
                _ref = _context.sent;
                data = _ref.data;
                return _context.abrupt("return", data);

              case 7:
              case "end":
                return _context.stop();
            }
          }
        }, _callee, this);
      }));

      return function getData() {
        return _getData.apply(this, arguments);
      };
    }()
    /**
     * Set bucket data.
     * @param  {Object}  data                    The bucket data object.
     * @param  {Object}  [options={}]            The options object.
     * @param  {Object}  [options.headers={}]    The headers object option.
     * @param  {Boolean} [options.safe]          The safe option.
     * @param  {Number}  [options.retry=0]       Number of retries to make
     *     when faced with transient errors.
     * @param  {Boolean} [options.patch]         The patch option.
     * @param  {Number}  [options.last_modified] The last_modified option.
     * @return {Promise<Object, Error>}
     */

  }, {
    key: "setData",
    value: function () {
      var _setData = (0, _asyncToGenerator2.default)(
      /*#__PURE__*/
      _regenerator.default.mark(function _callee2(data) {
        var options,
            bucket,
            bucketId,
            path,
            patch,
            permissions,
            _data$options,
            last_modified,
            request,
            _args2 = arguments;

        return _regenerator.default.wrap(function _callee2$(_context2) {
          while (1) {
            switch (_context2.prev = _context2.next) {
              case 0:
                options = _args2.length > 1 && _args2[1] !== undefined ? _args2[1] : {};

                if ((0, _utils.isObject)(data)) {
                  _context2.next = 3;
                  break;
                }

                throw new Error("A bucket object is required.");

              case 3:
                bucket = (0, _objectSpread2.default)({}, data, {
                  id: this.name
                }); // For default bucket, we need to drop the id from the data object.
                // Bug in Kinto < 3.1.1

                bucketId = bucket.id;

                if (bucket.id === "default") {
                  delete bucket.id;
                }

                path = (0, _endpoint.default)("bucket", bucketId);
                patch = options.patch, permissions = options.permissions;
                _data$options = (0, _objectSpread2.default)({}, data, options), last_modified = _data$options.last_modified;
                request = requests.updateRequest(path, {
                  data: bucket,
                  permissions: permissions
                }, {
                  last_modified: last_modified,
                  patch: patch,
                  headers: this._getHeaders(options),
                  safe: this._getSafe(options)
                });
                return _context2.abrupt("return", this.client.execute(request, {
                  retry: this._getRetry(options)
                }));

              case 11:
              case "end":
                return _context2.stop();
            }
          }
        }, _callee2, this);
      }));

      return function setData(_x) {
        return _setData.apply(this, arguments);
      };
    }()
    /**
     * Retrieves the list of history entries in the current bucket.
     *
     * @param  {Object} [options={}]      The options object.
     * @param  {Object} [options.headers] The headers object option.
     * @param  {Number} [options.retry=0] Number of retries to make
     *     when faced with transient errors.
     * @return {Promise<Array<Object>, Error>}
     */

  }, {
    key: "listHistory",
    value: function () {
      var _listHistory = (0, _asyncToGenerator2.default)(
      /*#__PURE__*/
      _regenerator.default.mark(function _callee3() {
        var options,
            path,
            _args3 = arguments;
        return _regenerator.default.wrap(function _callee3$(_context3) {
          while (1) {
            switch (_context3.prev = _context3.next) {
              case 0:
                options = _args3.length > 0 && _args3[0] !== undefined ? _args3[0] : {};
                path = (0, _endpoint.default)("history", this.name);
                return _context3.abrupt("return", this.client.paginatedList(path, options, {
                  headers: this._getHeaders(options),
                  retry: this._getRetry(options)
                }));

              case 3:
              case "end":
                return _context3.stop();
            }
          }
        }, _callee3, this);
      }));

      return function listHistory() {
        return _listHistory.apply(this, arguments);
      };
    }()
    /**
     * Retrieves the list of collections in the current bucket.
     *
     * @param  {Object} [options={}]      The options object.
     * @param  {Object} [options.headers] The headers object option.
     * @param  {Number} [options.retry=0] Number of retries to make
     *     when faced with transient errors.
     * @return {Promise<Array<Object>, Error>}
     */

  }, {
    key: "listCollections",
    value: function () {
      var _listCollections = (0, _asyncToGenerator2.default)(
      /*#__PURE__*/
      _regenerator.default.mark(function _callee4() {
        var options,
            path,
            _args4 = arguments;
        return _regenerator.default.wrap(function _callee4$(_context4) {
          while (1) {
            switch (_context4.prev = _context4.next) {
              case 0:
                options = _args4.length > 0 && _args4[0] !== undefined ? _args4[0] : {};
                path = (0, _endpoint.default)("collection", this.name);
                return _context4.abrupt("return", this.client.paginatedList(path, options, {
                  headers: this._getHeaders(options),
                  retry: this._getRetry(options)
                }));

              case 3:
              case "end":
                return _context4.stop();
            }
          }
        }, _callee4, this);
      }));

      return function listCollections() {
        return _listCollections.apply(this, arguments);
      };
    }()
    /**
     * Creates a new collection in current bucket.
     *
     * @param  {String|undefined}  id          The collection id.
     * @param  {Object}  [options={}]          The options object.
     * @param  {Boolean} [options.safe]        The safe option.
     * @param  {Object}  [options.headers]     The headers object option.
     * @param  {Number}  [options.retry=0]     Number of retries to make
     *     when faced with transient errors.
     * @param  {Object}  [options.permissions] The permissions object.
     * @param  {Object}  [options.data]        The data object.
     * @return {Promise<Object, Error>}
     */

  }, {
    key: "createCollection",
    value: function () {
      var _createCollection = (0, _asyncToGenerator2.default)(
      /*#__PURE__*/
      _regenerator.default.mark(function _callee5(id) {
        var options,
            permissions,
            _options$data,
            data,
            path,
            request,
            _args5 = arguments;

        return _regenerator.default.wrap(function _callee5$(_context5) {
          while (1) {
            switch (_context5.prev = _context5.next) {
              case 0:
                options = _args5.length > 1 && _args5[1] !== undefined ? _args5[1] : {};
                permissions = options.permissions, _options$data = options.data, data = _options$data === void 0 ? {} : _options$data;
                data.id = id;
                path = (0, _endpoint.default)("collection", this.name, id);
                request = requests.createRequest(path, {
                  data: data,
                  permissions: permissions
                }, {
                  headers: this._getHeaders(options),
                  safe: this._getSafe(options)
                });
                return _context5.abrupt("return", this.client.execute(request, {
                  retry: this._getRetry(options)
                }));

              case 6:
              case "end":
                return _context5.stop();
            }
          }
        }, _callee5, this);
      }));

      return function createCollection(_x2) {
        return _createCollection.apply(this, arguments);
      };
    }()
    /**
     * Deletes a collection from the current bucket.
     *
     * @param  {Object|String} collection              The collection to delete.
     * @param  {Object}        [options={}]            The options object.
     * @param  {Object}        [options.headers]       The headers object option.
     * @param  {Number}        [options.retry=0]       Number of retries to make
     *     when faced with transient errors.
     * @param  {Boolean}       [options.safe]          The safe option.
     * @param  {Number}        [options.last_modified] The last_modified option.
     * @return {Promise<Object, Error>}
     */

  }, {
    key: "deleteCollection",
    value: function () {
      var _deleteCollection = (0, _asyncToGenerator2.default)(
      /*#__PURE__*/
      _regenerator.default.mark(function _callee6(collection) {
        var options,
            collectionObj,
            id,
            _collectionObj$option,
            last_modified,
            path,
            request,
            _args6 = arguments;

        return _regenerator.default.wrap(function _callee6$(_context6) {
          while (1) {
            switch (_context6.prev = _context6.next) {
              case 0:
                options = _args6.length > 1 && _args6[1] !== undefined ? _args6[1] : {};
                collectionObj = (0, _utils.toDataBody)(collection);

                if (collectionObj.id) {
                  _context6.next = 4;
                  break;
                }

                throw new Error("A collection id is required.");

              case 4:
                id = collectionObj.id;
                _collectionObj$option = (0, _objectSpread2.default)({}, collectionObj, options), last_modified = _collectionObj$option.last_modified;
                path = (0, _endpoint.default)("collection", this.name, id);
                request = requests.deleteRequest(path, {
                  last_modified: last_modified,
                  headers: this._getHeaders(options),
                  safe: this._getSafe(options)
                });
                return _context6.abrupt("return", this.client.execute(request, {
                  retry: this._getRetry(options)
                }));

              case 9:
              case "end":
                return _context6.stop();
            }
          }
        }, _callee6, this);
      }));

      return function deleteCollection(_x3) {
        return _deleteCollection.apply(this, arguments);
      };
    }()
    /**
     * Retrieves the list of groups in the current bucket.
     *
     * @param  {Object} [options={}]      The options object.
     * @param  {Object} [options.headers] The headers object option.
     * @param  {Number} [options.retry=0] Number of retries to make
     *     when faced with transient errors.
     * @return {Promise<Array<Object>, Error>}
     */

  }, {
    key: "listGroups",
    value: function () {
      var _listGroups = (0, _asyncToGenerator2.default)(
      /*#__PURE__*/
      _regenerator.default.mark(function _callee7() {
        var options,
            path,
            _args7 = arguments;
        return _regenerator.default.wrap(function _callee7$(_context7) {
          while (1) {
            switch (_context7.prev = _context7.next) {
              case 0:
                options = _args7.length > 0 && _args7[0] !== undefined ? _args7[0] : {};
                path = (0, _endpoint.default)("group", this.name);
                return _context7.abrupt("return", this.client.paginatedList(path, options, {
                  headers: this._getHeaders(options),
                  retry: this._getRetry(options)
                }));

              case 3:
              case "end":
                return _context7.stop();
            }
          }
        }, _callee7, this);
      }));

      return function listGroups() {
        return _listGroups.apply(this, arguments);
      };
    }()
    /**
     * Creates a new group in current bucket.
     *
     * @param  {String} id                The group id.
     * @param  {Object} [options={}]      The options object.
     * @param  {Object} [options.headers] The headers object option.
     * @param  {Number} [options.retry=0] Number of retries to make
     *     when faced with transient errors.
     * @return {Promise<Object, Error>}
     */

  }, {
    key: "getGroup",
    value: function () {
      var _getGroup = (0, _asyncToGenerator2.default)(
      /*#__PURE__*/
      _regenerator.default.mark(function _callee8(id) {
        var options,
            request,
            _args8 = arguments;
        return _regenerator.default.wrap(function _callee8$(_context8) {
          while (1) {
            switch (_context8.prev = _context8.next) {
              case 0:
                options = _args8.length > 1 && _args8[1] !== undefined ? _args8[1] : {};
                request = {
                  headers: this._getHeaders(options),
                  path: (0, _endpoint.default)("group", this.name, id)
                };
                return _context8.abrupt("return", this.client.execute(request, {
                  retry: this._getRetry(options)
                }));

              case 3:
              case "end":
                return _context8.stop();
            }
          }
        }, _callee8, this);
      }));

      return function getGroup(_x4) {
        return _getGroup.apply(this, arguments);
      };
    }()
    /**
     * Creates a new group in current bucket.
     *
     * @param  {String|undefined}  id                    The group id.
     * @param  {Array<String>}     [members=[]]          The list of principals.
     * @param  {Object}            [options={}]          The options object.
     * @param  {Object}            [options.data]        The data object.
     * @param  {Object}            [options.permissions] The permissions object.
     * @param  {Boolean}           [options.safe]        The safe option.
     * @param  {Object}            [options.headers]     The headers object option.
     * @param  {Number}            [options.retry=0]     Number of retries to make
     *     when faced with transient errors.
     * @return {Promise<Object, Error>}
     */

  }, {
    key: "createGroup",
    value: function () {
      var _createGroup = (0, _asyncToGenerator2.default)(
      /*#__PURE__*/
      _regenerator.default.mark(function _callee9(id) {
        var members,
            options,
            data,
            path,
            permissions,
            request,
            _args9 = arguments;
        return _regenerator.default.wrap(function _callee9$(_context9) {
          while (1) {
            switch (_context9.prev = _context9.next) {
              case 0:
                members = _args9.length > 1 && _args9[1] !== undefined ? _args9[1] : [];
                options = _args9.length > 2 && _args9[2] !== undefined ? _args9[2] : {};
                data = (0, _objectSpread2.default)({}, options.data, {
                  id: id,
                  members: members
                });
                path = (0, _endpoint.default)("group", this.name, id);
                permissions = options.permissions;
                request = requests.createRequest(path, {
                  data: data,
                  permissions: permissions
                }, {
                  headers: this._getHeaders(options),
                  safe: this._getSafe(options)
                });
                return _context9.abrupt("return", this.client.execute(request, {
                  retry: this._getRetry(options)
                }));

              case 7:
              case "end":
                return _context9.stop();
            }
          }
        }, _callee9, this);
      }));

      return function createGroup(_x5) {
        return _createGroup.apply(this, arguments);
      };
    }()
    /**
     * Updates an existing group in current bucket.
     *
     * @param  {Object}  group                   The group object.
     * @param  {Object}  [options={}]            The options object.
     * @param  {Object}  [options.data]          The data object.
     * @param  {Object}  [options.permissions]   The permissions object.
     * @param  {Boolean} [options.safe]          The safe option.
     * @param  {Object}  [options.headers]       The headers object option.
     * @param  {Number}  [options.retry=0]       Number of retries to make
     *     when faced with transient errors.
     * @param  {Number}  [options.last_modified] The last_modified option.
     * @return {Promise<Object, Error>}
     */

  }, {
    key: "updateGroup",
    value: function () {
      var _updateGroup = (0, _asyncToGenerator2.default)(
      /*#__PURE__*/
      _regenerator.default.mark(function _callee10(group) {
        var options,
            data,
            path,
            patch,
            permissions,
            _data$options2,
            last_modified,
            request,
            _args10 = arguments;

        return _regenerator.default.wrap(function _callee10$(_context10) {
          while (1) {
            switch (_context10.prev = _context10.next) {
              case 0:
                options = _args10.length > 1 && _args10[1] !== undefined ? _args10[1] : {};

                if ((0, _utils.isObject)(group)) {
                  _context10.next = 3;
                  break;
                }

                throw new Error("A group object is required.");

              case 3:
                if (group.id) {
                  _context10.next = 5;
                  break;
                }

                throw new Error("A group id is required.");

              case 5:
                data = (0, _objectSpread2.default)({}, options.data, group);
                path = (0, _endpoint.default)("group", this.name, group.id);
                patch = options.patch, permissions = options.permissions;
                _data$options2 = (0, _objectSpread2.default)({}, data, options), last_modified = _data$options2.last_modified;
                request = requests.updateRequest(path, {
                  data: data,
                  permissions: permissions
                }, {
                  last_modified: last_modified,
                  patch: patch,
                  headers: this._getHeaders(options),
                  safe: this._getSafe(options)
                });
                return _context10.abrupt("return", this.client.execute(request, {
                  retry: this._getRetry(options)
                }));

              case 11:
              case "end":
                return _context10.stop();
            }
          }
        }, _callee10, this);
      }));

      return function updateGroup(_x6) {
        return _updateGroup.apply(this, arguments);
      };
    }()
    /**
     * Deletes a group from the current bucket.
     *
     * @param  {Object|String} group                   The group to delete.
     * @param  {Object}        [options={}]            The options object.
     * @param  {Object}        [options.headers]       The headers object option.
     * @param  {Number}        [options.retry=0]       Number of retries to make
     *     when faced with transient errors.
     * @param  {Boolean}       [options.safe]          The safe option.
     * @param  {Number}        [options.last_modified] The last_modified option.
     * @return {Promise<Object, Error>}
     */

  }, {
    key: "deleteGroup",
    value: function () {
      var _deleteGroup = (0, _asyncToGenerator2.default)(
      /*#__PURE__*/
      _regenerator.default.mark(function _callee11(group) {
        var options,
            groupObj,
            id,
            _groupObj$options,
            last_modified,
            path,
            request,
            _args11 = arguments;

        return _regenerator.default.wrap(function _callee11$(_context11) {
          while (1) {
            switch (_context11.prev = _context11.next) {
              case 0:
                options = _args11.length > 1 && _args11[1] !== undefined ? _args11[1] : {};
                groupObj = (0, _utils.toDataBody)(group);
                id = groupObj.id;
                _groupObj$options = (0, _objectSpread2.default)({}, groupObj, options), last_modified = _groupObj$options.last_modified;
                path = (0, _endpoint.default)("group", this.name, id);
                request = requests.deleteRequest(path, {
                  last_modified: last_modified,
                  headers: this._getHeaders(options),
                  safe: this._getSafe(options)
                });
                return _context11.abrupt("return", this.client.execute(request, {
                  retry: this._getRetry(options)
                }));

              case 7:
              case "end":
                return _context11.stop();
            }
          }
        }, _callee11, this);
      }));

      return function deleteGroup(_x7) {
        return _deleteGroup.apply(this, arguments);
      };
    }()
    /**
     * Retrieves the list of permissions for this bucket.
     *
     * @param  {Object} [options={}]      The options object.
     * @param  {Object} [options.headers] The headers object option.
     * @param  {Number} [options.retry=0] Number of retries to make
     *     when faced with transient errors.
     * @return {Promise<Object, Error>}
     */

  }, {
    key: "getPermissions",
    value: function () {
      var _getPermissions = (0, _asyncToGenerator2.default)(
      /*#__PURE__*/
      _regenerator.default.mark(function _callee12() {
        var options,
            request,
            _ref2,
            permissions,
            _args12 = arguments;

        return _regenerator.default.wrap(function _callee12$(_context12) {
          while (1) {
            switch (_context12.prev = _context12.next) {
              case 0:
                options = _args12.length > 0 && _args12[0] !== undefined ? _args12[0] : {};
                request = {
                  headers: this._getHeaders(options),
                  path: (0, _endpoint.default)("bucket", this.name)
                };
                _context12.next = 4;
                return this.client.execute(request, {
                  retry: this._getRetry(options)
                });

              case 4:
                _ref2 = _context12.sent;
                permissions = _ref2.permissions;
                return _context12.abrupt("return", permissions);

              case 7:
              case "end":
                return _context12.stop();
            }
          }
        }, _callee12, this);
      }));

      return function getPermissions() {
        return _getPermissions.apply(this, arguments);
      };
    }()
    /**
     * Replaces all existing bucket permissions with the ones provided.
     *
     * @param  {Object}  permissions             The permissions object.
     * @param  {Object}  [options={}]            The options object
     * @param  {Boolean} [options.safe]          The safe option.
     * @param  {Object}  [options.headers={}]    The headers object option.
     * @param  {Number}  [options.retry=0]       Number of retries to make
     *     when faced with transient errors.
     * @param  {Object}  [options.last_modified] The last_modified option.
     * @return {Promise<Object, Error>}
     */

  }, {
    key: "setPermissions",
    value: function () {
      var _setPermissions = (0, _asyncToGenerator2.default)(
      /*#__PURE__*/
      _regenerator.default.mark(function _callee13(permissions) {
        var options,
            path,
            last_modified,
            data,
            request,
            _args13 = arguments;
        return _regenerator.default.wrap(function _callee13$(_context13) {
          while (1) {
            switch (_context13.prev = _context13.next) {
              case 0:
                options = _args13.length > 1 && _args13[1] !== undefined ? _args13[1] : {};

                if ((0, _utils.isObject)(permissions)) {
                  _context13.next = 3;
                  break;
                }

                throw new Error("A permissions object is required.");

              case 3:
                path = (0, _endpoint.default)("bucket", this.name);
                last_modified = options.last_modified;
                data = {
                  last_modified: last_modified
                };
                request = requests.updateRequest(path, {
                  data: data,
                  permissions: permissions
                }, {
                  headers: this._getHeaders(options),
                  safe: this._getSafe(options)
                });
                return _context13.abrupt("return", this.client.execute(request, {
                  retry: this._getRetry(options)
                }));

              case 8:
              case "end":
                return _context13.stop();
            }
          }
        }, _callee13, this);
      }));

      return function setPermissions(_x8) {
        return _setPermissions.apply(this, arguments);
      };
    }()
    /**
     * Append principals to the bucket permissions.
     *
     * @param  {Object}  permissions             The permissions object.
     * @param  {Object}  [options={}]            The options object
     * @param  {Boolean} [options.safe]          The safe option.
     * @param  {Object}  [options.headers]       The headers object option.
     * @param  {Number}  [options.retry=0]       Number of retries to make
     *     when faced with transient errors.
     * @param  {Object}  [options.last_modified] The last_modified option.
     * @return {Promise<Object, Error>}
     */

  }, {
    key: "addPermissions",
    value: function () {
      var _addPermissions = (0, _asyncToGenerator2.default)(
      /*#__PURE__*/
      _regenerator.default.mark(function _callee14(permissions) {
        var options,
            path,
            last_modified,
            request,
            _args14 = arguments;
        return _regenerator.default.wrap(function _callee14$(_context14) {
          while (1) {
            switch (_context14.prev = _context14.next) {
              case 0:
                options = _args14.length > 1 && _args14[1] !== undefined ? _args14[1] : {};

                if ((0, _utils.isObject)(permissions)) {
                  _context14.next = 3;
                  break;
                }

                throw new Error("A permissions object is required.");

              case 3:
                path = (0, _endpoint.default)("bucket", this.name);
                last_modified = options.last_modified;
                request = requests.jsonPatchPermissionsRequest(path, permissions, "add", {
                  last_modified: last_modified,
                  headers: this._getHeaders(options),
                  safe: this._getSafe(options)
                });
                return _context14.abrupt("return", this.client.execute(request, {
                  retry: this._getRetry(options)
                }));

              case 7:
              case "end":
                return _context14.stop();
            }
          }
        }, _callee14, this);
      }));

      return function addPermissions(_x9) {
        return _addPermissions.apply(this, arguments);
      };
    }()
    /**
     * Remove principals from the bucket permissions.
     *
     * @param  {Object}  permissions             The permissions object.
     * @param  {Object}  [options={}]            The options object
     * @param  {Boolean} [options.safe]          The safe option.
     * @param  {Object}  [options.headers]       The headers object option.
     * @param  {Number}  [options.retry=0]       Number of retries to make
     *     when faced with transient errors.
     * @param  {Object}  [options.last_modified] The last_modified option.
     * @return {Promise<Object, Error>}
     */

  }, {
    key: "removePermissions",
    value: function () {
      var _removePermissions = (0, _asyncToGenerator2.default)(
      /*#__PURE__*/
      _regenerator.default.mark(function _callee15(permissions) {
        var options,
            path,
            last_modified,
            request,
            _args15 = arguments;
        return _regenerator.default.wrap(function _callee15$(_context15) {
          while (1) {
            switch (_context15.prev = _context15.next) {
              case 0:
                options = _args15.length > 1 && _args15[1] !== undefined ? _args15[1] : {};

                if ((0, _utils.isObject)(permissions)) {
                  _context15.next = 3;
                  break;
                }

                throw new Error("A permissions object is required.");

              case 3:
                path = (0, _endpoint.default)("bucket", this.name);
                last_modified = options.last_modified;
                request = requests.jsonPatchPermissionsRequest(path, permissions, "remove", {
                  last_modified: last_modified,
                  headers: this._getHeaders(options),
                  safe: this._getSafe(options)
                });
                return _context15.abrupt("return", this.client.execute(request, {
                  retry: this._getRetry(options)
                }));

              case 7:
              case "end":
                return _context15.stop();
            }
          }
        }, _callee15, this);
      }));

      return function removePermissions(_x10) {
        return _removePermissions.apply(this, arguments);
      };
    }()
    /**
     * Performs batch operations at the current bucket level.
     *
     * @param  {Function} fn                   The batch operation function.
     * @param  {Object}   [options={}]         The options object.
     * @param  {Object}   [options.headers]    The headers object option.
     * @param  {Boolean}  [options.safe]       The safe option.
     * @param  {Number}   [options.retry=0]    The retry option.
     * @param  {Boolean}  [options.aggregate]  Produces a grouped result object.
     * @return {Promise<Object, Error>}
     */

  }, {
    key: "batch",
    value: function () {
      var _batch = (0, _asyncToGenerator2.default)(
      /*#__PURE__*/
      _regenerator.default.mark(function _callee16(fn) {
        var options,
            _args16 = arguments;
        return _regenerator.default.wrap(function _callee16$(_context16) {
          while (1) {
            switch (_context16.prev = _context16.next) {
              case 0:
                options = _args16.length > 1 && _args16[1] !== undefined ? _args16[1] : {};
                return _context16.abrupt("return", this.client.batch(fn, {
                  bucket: this.name,
                  headers: this._getHeaders(options),
                  retry: this._getRetry(options),
                  safe: this._getSafe(options),
                  aggregate: !!options.aggregate
                }));

              case 2:
              case "end":
                return _context16.stop();
            }
          }
        }, _callee16, this);
      }));

      return function batch(_x11) {
        return _batch.apply(this, arguments);
      };
    }()
  }]);
  return Bucket;
}(), ((0, _applyDecoratedDescriptor2.default)(_class.prototype, "listHistory", [_dec], Object.getOwnPropertyDescriptor(_class.prototype, "listHistory"), _class.prototype)), _class));
exports.default = Bucket;
},{"./collection":310,"./endpoint":311,"./requests":315,"./utils":316,"@babel/runtime/helpers/applyDecoratedDescriptor":277,"@babel/runtime/helpers/asyncToGenerator":281,"@babel/runtime/helpers/classCallCheck":282,"@babel/runtime/helpers/createClass":284,"@babel/runtime/helpers/interopRequireDefault":288,"@babel/runtime/helpers/interopRequireWildcard":289,"@babel/runtime/helpers/objectSpread":295,"@babel/runtime/regenerator":305}],310:[function(require,module,exports){
"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");

var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard");

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;

var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));

var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));

var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));

var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread"));

var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));

var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));

var _applyDecoratedDescriptor2 = _interopRequireDefault(require("@babel/runtime/helpers/applyDecoratedDescriptor"));

var _uuid = require("uuid");

var _utils = require("./utils");

var requests = _interopRequireWildcard(require("./requests"));

var _endpoint = _interopRequireDefault(require("./endpoint"));

var _dec, _dec2, _dec3, _class;

/**
 * Abstract representation of a selected collection.
 *
 */
var Collection = (_dec = (0, _utils.capable)(["attachments"]), _dec2 = (0, _utils.capable)(["attachments"]), _dec3 = (0, _utils.capable)(["history"]), (_class =
/*#__PURE__*/
function () {
  /**
   * Constructor.
   *
   * @param  {KintoClient}  client            The client instance.
   * @param  {Bucket}       bucket            The bucket instance.
   * @param  {String}       name              The collection name.
   * @param  {Object}       [options={}]      The options object.
   * @param  {Object}       [options.headers] The headers object option.
   * @param  {Boolean}      [options.safe]    The safe option.
   * @param  {Number}       [options.retry]   The retry option.
   * @param  {Boolean}      [options.batch]   (Private) Whether this
   *     Collection is operating as part of a batch.
   */
  function Collection(client, bucket, name) {
    var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
    (0, _classCallCheck2.default)(this, Collection);

    /**
     * @ignore
     */
    this.client = client;
    /**
     * @ignore
     */

    this.bucket = bucket;
    /**
     * The collection name.
     * @type {String}
     */

    this.name = name;
    /**
     * @ignore
     */

    this._isBatch = !!options.batch;
    /**
     * @ignore
     */

    this._retry = options.retry || 0;
    this._safe = !!options.safe; // FIXME: This is kind of ugly; shouldn't the bucket be responsible
    // for doing the merge?

    this._headers = (0, _objectSpread2.default)({}, this.bucket._headers, options.headers);
  }
  /**
   * Get the value of "headers" for a given request, merging the
   * per-request headers with our own "default" headers.
   *
   * @private
   */


  (0, _createClass2.default)(Collection, [{
    key: "_getHeaders",
    value: function _getHeaders(options) {
      return (0, _objectSpread2.default)({}, this._headers, options.headers);
    }
    /**
     * Get the value of "safe" for a given request, using the
     * per-request option if present or falling back to our default
     * otherwise.
     *
     * @private
     * @param {Object} options The options for a request.
     * @returns {Boolean}
     */

  }, {
    key: "_getSafe",
    value: function _getSafe(options) {
      return (0, _objectSpread2.default)({
        safe: this._safe
      }, options).safe;
    }
    /**
     * As _getSafe, but for "retry".
     *
     * @private
     */

  }, {
    key: "_getRetry",
    value: function _getRetry(options) {
      return (0, _objectSpread2.default)({
        retry: this._retry
      }, options).retry;
    }
    /**
     * Retrieves the total number of records in this collection.
     *
     * @param  {Object} [options={}]      The options object.
     * @param  {Object} [options.headers] The headers object option.
     * @param  {Number} [options.retry=0] Number of retries to make
     *     when faced with transient errors.
     * @return {Promise<Number, Error>}
     */

  }, {
    key: "getTotalRecords",
    value: function () {
      var _getTotalRecords = (0, _asyncToGenerator2.default)(
      /*#__PURE__*/
      _regenerator.default.mark(function _callee() {
        var options,
            path,
            request,
            _ref,
            headers,
            _args = arguments;

        return _regenerator.default.wrap(function _callee$(_context) {
          while (1) {
            switch (_context.prev = _context.next) {
              case 0:
                options = _args.length > 0 && _args[0] !== undefined ? _args[0] : {};
                path = (0, _endpoint.default)("record", this.bucket.name, this.name);
                request = {
                  headers: this._getHeaders(options),
                  path: path,
                  method: "HEAD"
                };
                _context.next = 5;
                return this.client.execute(request, {
                  raw: true,
                  retry: this._getRetry(options)
                });

              case 5:
                _ref = _context.sent;
                headers = _ref.headers;
                return _context.abrupt("return", parseInt(headers.get("Total-Records"), 10));

              case 8:
              case "end":
                return _context.stop();
            }
          }
        }, _callee, this);
      }));

      return function getTotalRecords() {
        return _getTotalRecords.apply(this, arguments);
      };
    }()
    /**
     * Retrieves collection data.
     *
     * @param  {Object} [options={}]      The options object.
     * @param  {Object} [options.headers] The headers object option.
     * @param  {Object} [options.query]   Query parameters to pass in
     *     the request. This might be useful for features that aren't
     *     yet supported by this library.
     * @param  {Number} [options.retry=0] Number of retries to make
     *     when faced with transient errors.
     * @return {Promise<Object, Error>}
     */

  }, {
    key: "getData",
    value: function () {
      var _getData = (0, _asyncToGenerator2.default)(
      /*#__PURE__*/
      _regenerator.default.mark(function _callee2() {
        var options,
            path,
            querystring,
            request,
            _ref2,
            data,
            _args2 = arguments;

        return _regenerator.default.wrap(function _callee2$(_context2) {
          while (1) {
            switch (_context2.prev = _context2.next) {
              case 0:
                options = _args2.length > 0 && _args2[0] !== undefined ? _args2[0] : {};
                path = (0, _endpoint.default)("collection", this.bucket.name, this.name);

                if (options.query) {
                  querystring = (0, _utils.qsify)(options.query);
                  path = path + "?" + querystring;
                }

                request = {
                  headers: this._getHeaders(options),
                  path: path
                };
                _context2.next = 6;
                return this.client.execute(request, {
                  retry: this._getRetry(options)
                });

              case 6:
                _ref2 = _context2.sent;
                data = _ref2.data;
                return _context2.abrupt("return", data);

              case 9:
              case "end":
                return _context2.stop();
            }
          }
        }, _callee2, this);
      }));

      return function getData() {
        return _getData.apply(this, arguments);
      };
    }()
    /**
     * Set collection data.
     * @param  {Object}   data                    The collection data object.
     * @param  {Object}   [options={}]            The options object.
     * @param  {Object}   [options.headers]       The headers object option.
     * @param  {Number}   [options.retry=0]       Number of retries to make
     *     when faced with transient errors.
     * @param  {Boolean}  [options.safe]          The safe option.
     * @param  {Boolean}  [options.patch]         The patch option.
     * @param  {Number}   [options.last_modified] The last_modified option.
     * @return {Promise<Object, Error>}
     */

  }, {
    key: "setData",
    value: function () {
      var _setData = (0, _asyncToGenerator2.default)(
      /*#__PURE__*/
      _regenerator.default.mark(function _callee3(data) {
        var options,
            patch,
            permissions,
            _data$options,
            last_modified,
            path,
            request,
            _args3 = arguments;

        return _regenerator.default.wrap(function _callee3$(_context3) {
          while (1) {
            switch (_context3.prev = _context3.next) {
              case 0:
                options = _args3.length > 1 && _args3[1] !== undefined ? _args3[1] : {};

                if ((0, _utils.isObject)(data)) {
                  _context3.next = 3;
                  break;
                }

                throw new Error("A collection object is required.");

              case 3:
                patch = options.patch, permissions = options.permissions;
                _data$options = (0, _objectSpread2.default)({}, data, options), last_modified = _data$options.last_modified;
                path = (0, _endpoint.default)("collection", this.bucket.name, this.name);
                request = requests.updateRequest(path, {
                  data: data,
                  permissions: permissions
                }, {
                  last_modified: last_modified,
                  patch: patch,
                  headers: this._getHeaders(options),
                  safe: this._getSafe(options)
                });
                return _context3.abrupt("return", this.client.execute(request, {
                  retry: this._getRetry(options)
                }));

              case 8:
              case "end":
                return _context3.stop();
            }
          }
        }, _callee3, this);
      }));

      return function setData(_x) {
        return _setData.apply(this, arguments);
      };
    }()
    /**
     * Retrieves the list of permissions for this collection.
     *
     * @param  {Object} [options={}]      The options object.
     * @param  {Object} [options.headers] The headers object option.
     * @param  {Number} [options.retry=0] Number of retries to make
     *     when faced with transient errors.
     * @return {Promise<Object, Error>}
     */

  }, {
    key: "getPermissions",
    value: function () {
      var _getPermissions = (0, _asyncToGenerator2.default)(
      /*#__PURE__*/
      _regenerator.default.mark(function _callee4() {
        var options,
            path,
            request,
            _ref3,
            permissions,
            _args4 = arguments;

        return _regenerator.default.wrap(function _callee4$(_context4) {
          while (1) {
            switch (_context4.prev = _context4.next) {
              case 0:
                options = _args4.length > 0 && _args4[0] !== undefined ? _args4[0] : {};
                path = (0, _endpoint.default)("collection", this.bucket.name, this.name);
                request = {
                  headers: this._getHeaders(options),
                  path: path
                };
                _context4.next = 5;
                return this.client.execute(request, {
                  retry: this._getRetry(options)
                });

              case 5:
                _ref3 = _context4.sent;
                permissions = _ref3.permissions;
                return _context4.abrupt("return", permissions);

              case 8:
              case "end":
                return _context4.stop();
            }
          }
        }, _callee4, this);
      }));

      return function getPermissions() {
        return _getPermissions.apply(this, arguments);
      };
    }()
    /**
     * Replaces all existing collection permissions with the ones provided.
     *
     * @param  {Object}   permissions             The permissions object.
     * @param  {Object}   [options={}]            The options object
     * @param  {Object}   [options.headers]       The headers object option.
     * @param  {Number}   [options.retry=0]       Number of retries to make
     *     when faced with transient errors.
     * @param  {Boolean}  [options.safe]          The safe option.
     * @param  {Number}   [options.last_modified] The last_modified option.
     * @return {Promise<Object, Error>}
     */

  }, {
    key: "setPermissions",
    value: function () {
      var _setPermissions = (0, _asyncToGenerator2.default)(
      /*#__PURE__*/
      _regenerator.default.mark(function _callee5(permissions) {
        var options,
            path,
            data,
            request,
            _args5 = arguments;
        return _regenerator.default.wrap(function _callee5$(_context5) {
          while (1) {
            switch (_context5.prev = _context5.next) {
              case 0:
                options = _args5.length > 1 && _args5[1] !== undefined ? _args5[1] : {};

                if ((0, _utils.isObject)(permissions)) {
                  _context5.next = 3;
                  break;
                }

                throw new Error("A permissions object is required.");

              case 3:
                path = (0, _endpoint.default)("collection", this.bucket.name, this.name);
                data = {
                  last_modified: options.last_modified
                };
                request = requests.updateRequest(path, {
                  data: data,
                  permissions: permissions
                }, {
                  headers: this._getHeaders(options),
                  safe: this._getSafe(options)
                });
                return _context5.abrupt("return", this.client.execute(request, {
                  retry: this._getRetry(options)
                }));

              case 7:
              case "end":
                return _context5.stop();
            }
          }
        }, _callee5, this);
      }));

      return function setPermissions(_x2) {
        return _setPermissions.apply(this, arguments);
      };
    }()
    /**
     * Append principals to the collection permissions.
     *
     * @param  {Object}  permissions             The permissions object.
     * @param  {Object}  [options={}]            The options object
     * @param  {Boolean} [options.safe]          The safe option.
     * @param  {Object}  [options.headers]       The headers object option.
     * @param  {Number}  [options.retry=0]       Number of retries to make
     *     when faced with transient errors.
     * @param  {Object}  [options.last_modified] The last_modified option.
     * @return {Promise<Object, Error>}
     */

  }, {
    key: "addPermissions",
    value: function () {
      var _addPermissions = (0, _asyncToGenerator2.default)(
      /*#__PURE__*/
      _regenerator.default.mark(function _callee6(permissions) {
        var options,
            path,
            last_modified,
            request,
            _args6 = arguments;
        return _regenerator.default.wrap(function _callee6$(_context6) {
          while (1) {
            switch (_context6.prev = _context6.next) {
              case 0:
                options = _args6.length > 1 && _args6[1] !== undefined ? _args6[1] : {};

                if ((0, _utils.isObject)(permissions)) {
                  _context6.next = 3;
                  break;
                }

                throw new Error("A permissions object is required.");

              case 3:
                path = (0, _endpoint.default)("collection", this.bucket.name, this.name);
                last_modified = options.last_modified;
                request = requests.jsonPatchPermissionsRequest(path, permissions, "add", {
                  last_modified: last_modified,
                  headers: this._getHeaders(options),
                  safe: this._getSafe(options)
                });
                return _context6.abrupt("return", this.client.execute(request, {
                  retry: this._getRetry(options)
                }));

              case 7:
              case "end":
                return _context6.stop();
            }
          }
        }, _callee6, this);
      }));

      return function addPermissions(_x3) {
        return _addPermissions.apply(this, arguments);
      };
    }()
    /**
     * Remove principals from the collection permissions.
     *
     * @param  {Object}  permissions             The permissions object.
     * @param  {Object}  [options={}]            The options object
     * @param  {Boolean} [options.safe]          The safe option.
     * @param  {Object}  [options.headers]       The headers object option.
     * @param  {Number}  [options.retry=0]       Number of retries to make
     *     when faced with transient errors.
     * @param  {Object}  [options.last_modified] The last_modified option.
     * @return {Promise<Object, Error>}
     */

  }, {
    key: "removePermissions",
    value: function () {
      var _removePermissions = (0, _asyncToGenerator2.default)(
      /*#__PURE__*/
      _regenerator.default.mark(function _callee7(permissions) {
        var options,
            path,
            last_modified,
            request,
            _args7 = arguments;
        return _regenerator.default.wrap(function _callee7$(_context7) {
          while (1) {
            switch (_context7.prev = _context7.next) {
              case 0:
                options = _args7.length > 1 && _args7[1] !== undefined ? _args7[1] : {};

                if ((0, _utils.isObject)(permissions)) {
                  _context7.next = 3;
                  break;
                }

                throw new Error("A permissions object is required.");

              case 3:
                path = (0, _endpoint.default)("collection", this.bucket.name, this.name);
                last_modified = options.last_modified;
                request = requests.jsonPatchPermissionsRequest(path, permissions, "remove", {
                  last_modified: last_modified,
                  headers: this._getHeaders(options),
                  safe: this._getSafe(options)
                });
                return _context7.abrupt("return", this.client.execute(request, {
                  retry: this._getRetry(options)
                }));

              case 7:
              case "end":
                return _context7.stop();
            }
          }
        }, _callee7, this);
      }));

      return function removePermissions(_x4) {
        return _removePermissions.apply(this, arguments);
      };
    }()
    /**
     * Creates a record in current collection.
     *
     * @param  {Object}  record                The record to create.
     * @param  {Object}  [options={}]          The options object.
     * @param  {Object}  [options.headers]     The headers object option.
     * @param  {Number}  [options.retry=0]     Number of retries to make
     *     when faced with transient errors.
     * @param  {Boolean} [options.safe]        The safe option.
     * @param  {Object}  [options.permissions] The permissions option.
     * @return {Promise<Object, Error>}
     */

  }, {
    key: "createRecord",
    value: function () {
      var _createRecord = (0, _asyncToGenerator2.default)(
      /*#__PURE__*/
      _regenerator.default.mark(function _callee8(record) {
        var options,
            permissions,
            path,
            request,
            _args8 = arguments;
        return _regenerator.default.wrap(function _callee8$(_context8) {
          while (1) {
            switch (_context8.prev = _context8.next) {
              case 0:
                options = _args8.length > 1 && _args8[1] !== undefined ? _args8[1] : {};
                permissions = options.permissions;
                path = (0, _endpoint.default)("record", this.bucket.name, this.name, record.id);
                request = requests.createRequest(path, {
                  data: record,
                  permissions: permissions
                }, {
                  headers: this._getHeaders(options),
                  safe: this._getSafe(options)
                });
                return _context8.abrupt("return", this.client.execute(request, {
                  retry: this._getRetry(options)
                }));

              case 5:
              case "end":
                return _context8.stop();
            }
          }
        }, _callee8, this);
      }));

      return function createRecord(_x5) {
        return _createRecord.apply(this, arguments);
      };
    }()
    /**
     * Adds an attachment to a record, creating the record when it doesn't exist.
     *
     * @param  {String}  dataURL                 The data url.
     * @param  {Object}  [record={}]             The record data.
     * @param  {Object}  [options={}]            The options object.
     * @param  {Object}  [options.headers]       The headers object option.
     * @param  {Number}  [options.retry=0]       Number of retries to make
     *     when faced with transient errors.
     * @param  {Boolean} [options.safe]          The safe option.
     * @param  {Number}  [options.last_modified] The last_modified option.
     * @param  {Object}  [options.permissions]   The permissions option.
     * @param  {String}  [options.filename]      Force the attachment filename.
     * @param  {String}  [options.gzipped]       Force the attachment to be gzipped or not.
     * @return {Promise<Object, Error>}
     */

  }, {
    key: "addAttachment",
    value: function () {
      var _addAttachment = (0, _asyncToGenerator2.default)(
      /*#__PURE__*/
      _regenerator.default.mark(function _callee9(dataURI) {
        var record,
            options,
            permissions,
            id,
            path,
            _record$options,
            last_modified,
            addAttachmentRequest,
            _args9 = arguments;

        return _regenerator.default.wrap(function _callee9$(_context9) {
          while (1) {
            switch (_context9.prev = _context9.next) {
              case 0:
                record = _args9.length > 1 && _args9[1] !== undefined ? _args9[1] : {};
                options = _args9.length > 2 && _args9[2] !== undefined ? _args9[2] : {};
                permissions = options.permissions;
                id = record.id || _uuid.v4.v4();
                path = (0, _endpoint.default)("attachment", this.bucket.name, this.name, id);
                _record$options = (0, _objectSpread2.default)({}, record, options), last_modified = _record$options.last_modified;
                addAttachmentRequest = requests.addAttachmentRequest(path, dataURI, {
                  data: record,
                  permissions: permissions
                }, {
                  last_modified: last_modified,
                  filename: options.filename,
                  gzipped: options.gzipped,
                  headers: this._getHeaders(options),
                  safe: this._getSafe(options)
                });
                _context9.next = 9;
                return this.client.execute(addAttachmentRequest, {
                  stringify: false,
                  retry: this._getRetry(options)
                });

              case 9:
                return _context9.abrupt("return", this.getRecord(id));

              case 10:
              case "end":
                return _context9.stop();
            }
          }
        }, _callee9, this);
      }));

      return function addAttachment(_x6) {
        return _addAttachment.apply(this, arguments);
      };
    }()
    /**
     * Removes an attachment from a given record.
     *
     * @param  {Object}  recordId                The record id.
     * @param  {Object}  [options={}]            The options object.
     * @param  {Object}  [options.headers]       The headers object option.
     * @param  {Number}  [options.retry=0]       Number of retries to make
     *     when faced with transient errors.
     * @param  {Boolean} [options.safe]          The safe option.
     * @param  {Number}  [options.last_modified] The last_modified option.
     */

  }, {
    key: "removeAttachment",
    value: function () {
      var _removeAttachment = (0, _asyncToGenerator2.default)(
      /*#__PURE__*/
      _regenerator.default.mark(function _callee10(recordId) {
        var options,
            last_modified,
            path,
            request,
            _args10 = arguments;
        return _regenerator.default.wrap(function _callee10$(_context10) {
          while (1) {
            switch (_context10.prev = _context10.next) {
              case 0:
                options = _args10.length > 1 && _args10[1] !== undefined ? _args10[1] : {};
                last_modified = options.last_modified;
                path = (0, _endpoint.default)("attachment", this.bucket.name, this.name, recordId);
                request = requests.deleteRequest(path, {
                  last_modified: last_modified,
                  headers: this._getHeaders(options),
                  safe: this._getSafe(options)
                });
                return _context10.abrupt("return", this.client.execute(request, {
                  retry: this._getRetry(options)
                }));

              case 5:
              case "end":
                return _context10.stop();
            }
          }
        }, _callee10, this);
      }));

      return function removeAttachment(_x7) {
        return _removeAttachment.apply(this, arguments);
      };
    }()
    /**
     * Updates a record in current collection.
     *
     * @param  {Object}  record                  The record to update.
     * @param  {Object}  [options={}]            The options object.
     * @param  {Object}  [options.headers]       The headers object option.
     * @param  {Number}  [options.retry=0]       Number of retries to make
     *     when faced with transient errors.
     * @param  {Boolean} [options.safe]          The safe option.
     * @param  {Number}  [options.last_modified] The last_modified option.
     * @param  {Object}  [options.permissions]   The permissions option.
     * @return {Promise<Object, Error>}
     */

  }, {
    key: "updateRecord",
    value: function () {
      var _updateRecord = (0, _asyncToGenerator2.default)(
      /*#__PURE__*/
      _regenerator.default.mark(function _callee11(record) {
        var options,
            permissions,
            _record$options2,
            last_modified,
            path,
            request,
            _args11 = arguments;

        return _regenerator.default.wrap(function _callee11$(_context11) {
          while (1) {
            switch (_context11.prev = _context11.next) {
              case 0:
                options = _args11.length > 1 && _args11[1] !== undefined ? _args11[1] : {};

                if ((0, _utils.isObject)(record)) {
                  _context11.next = 3;
                  break;
                }

                throw new Error("A record object is required.");

              case 3:
                if (record.id) {
                  _context11.next = 5;
                  break;
                }

                throw new Error("A record id is required.");

              case 5:
                permissions = options.permissions;
                _record$options2 = (0, _objectSpread2.default)({}, record, options), last_modified = _record$options2.last_modified;
                path = (0, _endpoint.default)("record", this.bucket.name, this.name, record.id);
                request = requests.updateRequest(path, {
                  data: record,
                  permissions: permissions
                }, {
                  headers: this._getHeaders(options),
                  safe: this._getSafe(options),
                  last_modified: last_modified,
                  patch: !!options.patch
                });
                return _context11.abrupt("return", this.client.execute(request, {
                  retry: this._getRetry(options)
                }));

              case 10:
              case "end":
                return _context11.stop();
            }
          }
        }, _callee11, this);
      }));

      return function updateRecord(_x8) {
        return _updateRecord.apply(this, arguments);
      };
    }()
    /**
     * Deletes a record from the current collection.
     *
     * @param  {Object|String} record                  The record to delete.
     * @param  {Object}        [options={}]            The options object.
     * @param  {Object}        [options.headers]       The headers object option.
     * @param  {Number}        [options.retry=0]       Number of retries to make
     *     when faced with transient errors.
     * @param  {Boolean}       [options.safe]          The safe option.
     * @param  {Number}        [options.last_modified] The last_modified option.
     * @return {Promise<Object, Error>}
     */

  }, {
    key: "deleteRecord",
    value: function () {
      var _deleteRecord = (0, _asyncToGenerator2.default)(
      /*#__PURE__*/
      _regenerator.default.mark(function _callee12(record) {
        var options,
            recordObj,
            id,
            _recordObj$options,
            last_modified,
            path,
            request,
            _args12 = arguments;

        return _regenerator.default.wrap(function _callee12$(_context12) {
          while (1) {
            switch (_context12.prev = _context12.next) {
              case 0:
                options = _args12.length > 1 && _args12[1] !== undefined ? _args12[1] : {};
                recordObj = (0, _utils.toDataBody)(record);

                if (recordObj.id) {
                  _context12.next = 4;
                  break;
                }

                throw new Error("A record id is required.");

              case 4:
                id = recordObj.id;
                _recordObj$options = (0, _objectSpread2.default)({}, recordObj, options), last_modified = _recordObj$options.last_modified;
                path = (0, _endpoint.default)("record", this.bucket.name, this.name, id);
                request = requests.deleteRequest(path, {
                  last_modified: last_modified,
                  headers: this._getHeaders(options),
                  safe: this._getSafe(options)
                });
                return _context12.abrupt("return", this.client.execute(request, {
                  retry: this._getRetry(options)
                }));

              case 9:
              case "end":
                return _context12.stop();
            }
          }
        }, _callee12, this);
      }));

      return function deleteRecord(_x9) {
        return _deleteRecord.apply(this, arguments);
      };
    }()
    /**
     * Retrieves a record from the current collection.
     *
     * @param  {String} id                The record id to retrieve.
     * @param  {Object} [options={}]      The options object.
     * @param  {Object} [options.headers] The headers object option.
     * @param  {Number} [options.retry=0] Number of retries to make
     *     when faced with transient errors.
     * @return {Promise<Object, Error>}
     */

  }, {
    key: "getRecord",
    value: function () {
      var _getRecord = (0, _asyncToGenerator2.default)(
      /*#__PURE__*/
      _regenerator.default.mark(function _callee13(id) {
        var options,
            path,
            request,
            _args13 = arguments;
        return _regenerator.default.wrap(function _callee13$(_context13) {
          while (1) {
            switch (_context13.prev = _context13.next) {
              case 0:
                options = _args13.length > 1 && _args13[1] !== undefined ? _args13[1] : {};
                path = (0, _endpoint.default)("record", this.bucket.name, this.name, id);
                request = {
                  headers: this._getHeaders(options),
                  path: path
                };
                return _context13.abrupt("return", this.client.execute(request, {
                  retry: this._getRetry(options)
                }));

              case 4:
              case "end":
                return _context13.stop();
            }
          }
        }, _callee13, this);
      }));

      return function getRecord(_x10) {
        return _getRecord.apply(this, arguments);
      };
    }()
    /**
     * Lists records from the current collection.
     *
     * Sorting is done by passing a `sort` string option:
     *
     * - The field to order the results by, prefixed with `-` for descending.
     * Default: `-last_modified`.
     *
     * @see http://kinto.readthedocs.io/en/stable/api/1.x/sorting.html
     *
     * Filtering is done by passing a `filters` option object:
     *
     * - `{fieldname: "value"}`
     * - `{min_fieldname: 4000}`
     * - `{in_fieldname: "1,2,3"}`
     * - `{not_fieldname: 0}`
     * - `{exclude_fieldname: "0,1"}`
     *
     * @see http://kinto.readthedocs.io/en/stable/api/1.x/filtering.html
     *
     * Paginating is done by passing a `limit` option, then calling the `next()`
     * method from the resolved result object to fetch the next page, if any.
     *
     * @param  {Object}   [options={}]                    The options object.
     * @param  {Object}   [options.headers]               The headers object option.
     * @param  {Number}   [options.retry=0]               Number of retries to make
     *     when faced with transient errors.
     * @param  {Object}   [options.filters=[]]            The filters object.
     * @param  {String}   [options.sort="-last_modified"] The sort field.
     * @param  {String}   [options.at]                    The timestamp to get a snapshot at.
     * @param  {String}   [options.limit=null]            The limit field.
     * @param  {String}   [options.pages=1]               The number of result pages to aggregate.
     * @param  {Number}   [options.since=null]            Only retrieve records modified since the provided timestamp.
     * @return {Promise<Object, Error>}
     */

  }, {
    key: "listRecords",
    value: function () {
      var _listRecords = (0, _asyncToGenerator2.default)(
      /*#__PURE__*/
      _regenerator.default.mark(function _callee14() {
        var options,
            path,
            _args14 = arguments;
        return _regenerator.default.wrap(function _callee14$(_context14) {
          while (1) {
            switch (_context14.prev = _context14.next) {
              case 0:
                options = _args14.length > 0 && _args14[0] !== undefined ? _args14[0] : {};
                path = (0, _endpoint.default)("record", this.bucket.name, this.name);

                if (!options.hasOwnProperty("at")) {
                  _context14.next = 6;
                  break;
                }

                return _context14.abrupt("return", this.getSnapshot(options.at));

              case 6:
                return _context14.abrupt("return", this.client.paginatedList(path, options, {
                  headers: this._getHeaders(options),
                  retry: this._getRetry(options)
                }));

              case 7:
              case "end":
                return _context14.stop();
            }
          }
        }, _callee14, this);
      }));

      return function listRecords() {
        return _listRecords.apply(this, arguments);
      };
    }()
    /**
     * @private
     */

  }, {
    key: "isHistoryComplete",
    value: function () {
      var _isHistoryComplete = (0, _asyncToGenerator2.default)(
      /*#__PURE__*/
      _regenerator.default.mark(function _callee15() {
        var _ref4, _ref4$data, oldestHistoryEntry;

        return _regenerator.default.wrap(function _callee15$(_context15) {
          while (1) {
            switch (_context15.prev = _context15.next) {
              case 0:
                _context15.next = 2;
                return this.bucket.listHistory({
                  limit: 1,
                  filters: {
                    action: "create",
                    resource_name: "collection",
                    collection_id: this.name
                  }
                });

              case 2:
                _ref4 = _context15.sent;
                _ref4$data = (0, _slicedToArray2.default)(_ref4.data, 1);
                oldestHistoryEntry = _ref4$data[0];
                return _context15.abrupt("return", !!oldestHistoryEntry);

              case 6:
              case "end":
                return _context15.stop();
            }
          }
        }, _callee15, this);
      }));

      return function isHistoryComplete() {
        return _isHistoryComplete.apply(this, arguments);
      };
    }()
    /**
     * @private
     */

  }, {
    key: "listChangesBackTo",
    value: function () {
      var _listChangesBackTo = (0, _asyncToGenerator2.default)(
      /*#__PURE__*/
      _regenerator.default.mark(function _callee16(at) {
        var _ref5, changes;

        return _regenerator.default.wrap(function _callee16$(_context16) {
          while (1) {
            switch (_context16.prev = _context16.next) {
              case 0:
                _context16.next = 2;
                return this.isHistoryComplete();

              case 2:
                if (_context16.sent) {
                  _context16.next = 4;
                  break;
                }

                throw new Error("Computing a snapshot is only possible when the full history for a " + "collection is available. Here, the history plugin seems to have " + "been enabled after the creation of the collection.");

              case 4:
                _context16.next = 6;
                return this.bucket.listHistory({
                  pages: Infinity,
                  // all pages up to target timestamp are required
                  sort: "-target.data.last_modified",
                  filters: {
                    resource_name: "record",
                    collection_id: this.name,
                    "max_target.data.last_modified": String(at) // eq. to <=

                  }
                });

              case 6:
                _ref5 = _context16.sent;
                changes = _ref5.data;
                return _context16.abrupt("return", changes);

              case 9:
              case "end":
                return _context16.stop();
            }
          }
        }, _callee16, this);
      }));

      return function listChangesBackTo(_x11) {
        return _listChangesBackTo.apply(this, arguments);
      };
    }()
    /**
     * @private
     */

  }, {
    key: "getSnapshot",
    value: function () {
      var _getSnapshot = (0, _asyncToGenerator2.default)(
      /*#__PURE__*/
      _regenerator.default.mark(function _callee17(at) {
        var changes, seenIds, snapshot, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _loop, _iterator, _step;

        return _regenerator.default.wrap(function _callee17$(_context17) {
          while (1) {
            switch (_context17.prev = _context17.next) {
              case 0:
                if (!(!Number.isInteger(at) || at <= 0)) {
                  _context17.next = 2;
                  break;
                }

                throw new Error("Invalid argument, expected a positive integer.");

              case 2:
                _context17.next = 4;
                return this.listChangesBackTo(at);

              case 4:
                changes = _context17.sent;
                // Replay changes to compute the requested snapshot.
                seenIds = new Set();
                snapshot = [];
                _iteratorNormalCompletion = true;
                _didIteratorError = false;
                _iteratorError = undefined;
                _context17.prev = 10;

                _loop = function _loop() {
                  var _ref6 = _step.value;
                  var action = _ref6.action,
                      record = _ref6.target.data;

                  if (action == "delete") {
                    seenIds.add(record.id); // ensure not reprocessing deleted entries

                    snapshot = snapshot.filter(function (r) {
                      return r.id !== record.id;
                    });
                  } else if (!seenIds.has(record.id)) {
                    seenIds.add(record.id);
                    snapshot.push(record);
                  }
                };

                for (_iterator = changes[Symbol.iterator](); !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
                  _loop();
                }

                _context17.next = 19;
                break;

              case 15:
                _context17.prev = 15;
                _context17.t0 = _context17["catch"](10);
                _didIteratorError = true;
                _iteratorError = _context17.t0;

              case 19:
                _context17.prev = 19;
                _context17.prev = 20;

                if (!_iteratorNormalCompletion && _iterator.return != null) {
                  _iterator.return();
                }

              case 22:
                _context17.prev = 22;

                if (!_didIteratorError) {
                  _context17.next = 25;
                  break;
                }

                throw _iteratorError;

              case 25:
                return _context17.finish(22);

              case 26:
                return _context17.finish(19);

              case 27:
                return _context17.abrupt("return", {
                  last_modified: String(at),
                  data: snapshot.sort(function (a, b) {
                    return b.last_modified - a.last_modified;
                  }),
                  next: function next() {
                    throw new Error("Snapshots don't support pagination");
                  },
                  hasNextPage: false,
                  totalRecords: snapshot.length
                });

              case 28:
              case "end":
                return _context17.stop();
            }
          }
        }, _callee17, this, [[10, 15, 19, 27], [20,, 22, 26]]);
      }));

      return function getSnapshot(_x12) {
        return _getSnapshot.apply(this, arguments);
      };
    }()
    /**
     * Performs batch operations at the current collection level.
     *
     * @param  {Function} fn                   The batch operation function.
     * @param  {Object}   [options={}]         The options object.
     * @param  {Object}   [options.headers]    The headers object option.
     * @param  {Boolean}  [options.safe]       The safe option.
     * @param  {Number}   [options.retry]      The retry option.
     * @param  {Boolean}  [options.aggregate]  Produces a grouped result object.
     * @return {Promise<Object, Error>}
     */

  }, {
    key: "batch",
    value: function () {
      var _batch = (0, _asyncToGenerator2.default)(
      /*#__PURE__*/
      _regenerator.default.mark(function _callee18(fn) {
        var options,
            _args18 = arguments;
        return _regenerator.default.wrap(function _callee18$(_context18) {
          while (1) {
            switch (_context18.prev = _context18.next) {
              case 0:
                options = _args18.length > 1 && _args18[1] !== undefined ? _args18[1] : {};
                return _context18.abrupt("return", this.client.batch(fn, {
                  bucket: this.bucket.name,
                  collection: this.name,
                  headers: this._getHeaders(options),
                  retry: this._getRetry(options),
                  safe: this._getSafe(options),
                  aggregate: !!options.aggregate
                }));

              case 2:
              case "end":
                return _context18.stop();
            }
          }
        }, _callee18, this);
      }));

      return function batch(_x13) {
        return _batch.apply(this, arguments);
      };
    }()
  }]);
  return Collection;
}(), ((0, _applyDecoratedDescriptor2.default)(_class.prototype, "addAttachment", [_dec], Object.getOwnPropertyDescriptor(_class.prototype, "addAttachment"), _class.prototype), (0, _applyDecoratedDescriptor2.default)(_class.prototype, "removeAttachment", [_dec2], Object.getOwnPropertyDescriptor(_class.prototype, "removeAttachment"), _class.prototype), (0, _applyDecoratedDescriptor2.default)(_class.prototype, "getSnapshot", [_dec3], Object.getOwnPropertyDescriptor(_class.prototype, "getSnapshot"), _class.prototype)), _class));
exports.default = Collection;
},{"./endpoint":311,"./requests":315,"./utils":316,"@babel/runtime/helpers/applyDecoratedDescriptor":277,"@babel/runtime/helpers/asyncToGenerator":281,"@babel/runtime/helpers/classCallCheck":282,"@babel/runtime/helpers/createClass":284,"@babel/runtime/helpers/interopRequireDefault":288,"@babel/runtime/helpers/interopRequireWildcard":289,"@babel/runtime/helpers/objectSpread":295,"@babel/runtime/helpers/slicedToArray":298,"@babel/runtime/regenerator":305,"uuid":317}],311:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = endpoint;

/**
 * Endpoints templates.
 * @type {Object}
 */
var ENDPOINTS = {
  root: function root() {
    return "/";
  },
  batch: function batch() {
    return "/batch";
  },
  permissions: function permissions() {
    return "/permissions";
  },
  bucket: function bucket(_bucket) {
    return "/buckets" + (_bucket ? "/".concat(_bucket) : "");
  },
  history: function history(bucket) {
    return "".concat(ENDPOINTS.bucket(bucket), "/history");
  },
  collection: function collection(bucket, coll) {
    return "".concat(ENDPOINTS.bucket(bucket), "/collections") + (coll ? "/".concat(coll) : "");
  },
  group: function group(bucket, _group) {
    return "".concat(ENDPOINTS.bucket(bucket), "/groups") + (_group ? "/".concat(_group) : "");
  },
  record: function record(bucket, coll, id) {
    return "".concat(ENDPOINTS.collection(bucket, coll), "/records") + (id ? "/".concat(id) : "");
  },
  attachment: function attachment(bucket, coll, id) {
    return "".concat(ENDPOINTS.record(bucket, coll, id), "/attachment");
  }
};
/**
 * Retrieves a server enpoint by its name.
 *
 * @private
 * @param  {String}    name The endpoint name.
 * @param  {...string} args The endpoint parameters.
 * @return {String}
 */

function endpoint(name) {
  for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
    args[_key - 1] = arguments[_key];
  }

  return ENDPOINTS[name].apply(ENDPOINTS, args);
}
},{}],312:[function(require,module,exports){
"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.UnparseableResponseError = exports.ServerResponse = exports.NetworkTimeoutError = exports.default = void 0;

var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));

var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn"));

var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf"));

var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits"));

var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized"));

function _extendableBuiltin5(cls) {
  function ExtendableBuiltin() {
    var instance = Reflect.construct(cls, Array.from(arguments));
    Object.setPrototypeOf(instance, Object.getPrototypeOf(this));
    return instance;
  }

  ExtendableBuiltin.prototype = Object.create(cls.prototype, {
    constructor: {
      value: cls,
      enumerable: false,
      writable: true,
      configurable: true
    }
  });

  if (Object.setPrototypeOf) {
    Object.setPrototypeOf(ExtendableBuiltin, cls);
  } else {
    ExtendableBuiltin.__proto__ = cls;
  }

  return ExtendableBuiltin;
}

function _extendableBuiltin3(cls) {
  function ExtendableBuiltin() {
    var instance = Reflect.construct(cls, Array.from(arguments));
    Object.setPrototypeOf(instance, Object.getPrototypeOf(this));
    return instance;
  }

  ExtendableBuiltin.prototype = Object.create(cls.prototype, {
    constructor: {
      value: cls,
      enumerable: false,
      writable: true,
      configurable: true
    }
  });

  if (Object.setPrototypeOf) {
    Object.setPrototypeOf(ExtendableBuiltin, cls);
  } else {
    ExtendableBuiltin.__proto__ = cls;
  }

  return ExtendableBuiltin;
}

function _extendableBuiltin(cls) {
  function ExtendableBuiltin() {
    var instance = Reflect.construct(cls, Array.from(arguments));
    Object.setPrototypeOf(instance, Object.getPrototypeOf(this));
    return instance;
  }

  ExtendableBuiltin.prototype = Object.create(cls.prototype, {
    constructor: {
      value: cls,
      enumerable: false,
      writable: true,
      configurable: true
    }
  });

  if (Object.setPrototypeOf) {
    Object.setPrototypeOf(ExtendableBuiltin, cls);
  } else {
    ExtendableBuiltin.__proto__ = cls;
  }

  return ExtendableBuiltin;
}

/**
 * Kinto server error code descriptors.
 * @type {Object}
 */
var ERROR_CODES = {
  104: "Missing Authorization Token",
  105: "Invalid Authorization Token",
  106: "Request body was not valid JSON",
  107: "Invalid request parameter",
  108: "Missing request parameter",
  109: "Invalid posted data",
  110: "Invalid Token / id",
  111: "Missing Token / id",
  112: "Content-Length header was not provided",
  113: "Request body too large",
  114: "Resource was created, updated or deleted meanwhile",
  115: "Method not allowed on this end point (hint: server may be readonly)",
  116: "Requested version not available on this server",
  117: "Client has sent too many requests",
  121: "Resource access is forbidden for this user",
  122: "Another resource violates constraint",
  201: "Service Temporary unavailable due to high load",
  202: "Service deprecated",
  999: "Internal Server Error"
};
var _default = ERROR_CODES;
exports.default = _default;

var NetworkTimeoutError =
/*#__PURE__*/
function (_extendableBuiltin2) {
  (0, _inherits2.default)(NetworkTimeoutError, _extendableBuiltin2);

  function NetworkTimeoutError(url, options) {
    var _this;

    (0, _classCallCheck2.default)(this, NetworkTimeoutError);
    _this = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(NetworkTimeoutError).call(this, "Timeout while trying to access ".concat(url, " with ").concat(JSON.stringify(options))));

    if (Error.captureStackTrace) {
      Error.captureStackTrace((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this)), NetworkTimeoutError);
    }

    _this.url = url;
    _this.options = options;
    return _this;
  }

  return NetworkTimeoutError;
}(_extendableBuiltin(Error));

exports.NetworkTimeoutError = NetworkTimeoutError;

var UnparseableResponseError =
/*#__PURE__*/
function (_extendableBuiltin4) {
  (0, _inherits2.default)(UnparseableResponseError, _extendableBuiltin4);

  function UnparseableResponseError(response, body, error) {
    var _this2;

    (0, _classCallCheck2.default)(this, UnparseableResponseError);
    var status = response.status;
    _this2 = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(UnparseableResponseError).call(this, "Response from server unparseable (HTTP ".concat(status || 0, "; ").concat(error, "): ").concat(body)));

    if (Error.captureStackTrace) {
      Error.captureStackTrace((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this2)), UnparseableResponseError);
    }

    _this2.status = status;
    _this2.response = response;
    _this2.stack = error.stack;
    _this2.error = error;
    return _this2;
  }

  return UnparseableResponseError;
}(_extendableBuiltin3(Error));
/**
 * "Error" subclass representing a >=400 response from the server.
 *
 * Whether or not this is an error depends on your application.
 *
 * The `json` field can be undefined if the server responded with an
 * empty response body. This shouldn't generally happen. Most "bad"
 * responses come with a JSON error description, or (if they're
 * fronted by a CDN or nginx or something) occasionally non-JSON
 * responses (which become UnparseableResponseErrors, above).
 */


exports.UnparseableResponseError = UnparseableResponseError;

var ServerResponse =
/*#__PURE__*/
function (_extendableBuiltin6) {
  (0, _inherits2.default)(ServerResponse, _extendableBuiltin6);

  function ServerResponse(response, json) {
    var _this3;

    (0, _classCallCheck2.default)(this, ServerResponse);
    var status = response.status;
    var statusText = response.statusText;
    var errnoMsg;

    if (json) {
      // Try to fill in information from the JSON error.
      statusText = json.error || statusText; // Take errnoMsg from either ERROR_CODES or json.message.

      if (json.errno && json.errno in ERROR_CODES) {
        errnoMsg = ERROR_CODES[json.errno];
      } else if (json.message) {
        errnoMsg = json.message;
      } // If we had both ERROR_CODES and json.message, and they differ,
      // combine them.


      if (errnoMsg && json.message && json.message !== errnoMsg) {
        errnoMsg += " (".concat(json.message, ")");
      }
    }

    var message = "HTTP ".concat(status, " ").concat(statusText);

    if (errnoMsg) {
      message += ": ".concat(errnoMsg);
    }

    _this3 = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(ServerResponse).call(this, message.trim()));

    if (Error.captureStackTrace) {
      Error.captureStackTrace((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this3)), ServerResponse);
    }

    _this3.response = response;
    _this3.data = json;
    return _this3;
  }

  return ServerResponse;
}(_extendableBuiltin5(Error));

exports.ServerResponse = ServerResponse;
},{"@babel/runtime/helpers/assertThisInitialized":280,"@babel/runtime/helpers/classCallCheck":282,"@babel/runtime/helpers/getPrototypeOf":286,"@babel/runtime/helpers/inherits":287,"@babel/runtime/helpers/interopRequireDefault":288,"@babel/runtime/helpers/possibleConstructorReturn":296}],313:[function(require,module,exports){
"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;

var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread"));

var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));

var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));

var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));

var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));

var _utils = require("./utils");

var _errors = require("./errors");

/**
 * Enhanced HTTP client for the Kinto protocol.
 * @private
 */
var HTTP =
/*#__PURE__*/
function () {
  (0, _createClass2.default)(HTTP, null, [{
    key: "DEFAULT_REQUEST_HEADERS",

    /**
     * Default HTTP request headers applied to each outgoing request.
     *
     * @type {Object}
     */
    get: function get() {
      return {
        Accept: "application/json",
        "Content-Type": "application/json"
      };
    }
    /**
     * Default options.
     *
     * @type {Object}
     */

  }, {
    key: "defaultOptions",
    get: function get() {
      return {
        timeout: null,
        requestMode: "cors"
      };
    }
    /**
     * Constructor.
     *
     * @param {EventEmitter} events                       The event handler.
     * @param {Object}       [options={}}                 The options object.
     * @param {Number}       [options.timeout=null]       The request timeout in ms, if any (default: `null`).
     * @param {String}       [options.requestMode="cors"] The HTTP request mode (default: `"cors"`).
     */

  }]);

  function HTTP(events) {
    var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
    (0, _classCallCheck2.default)(this, HTTP);

    // public properties

    /**
     * The event emitter instance.
     * @type {EventEmitter}
     */
    if (!events) {
      throw new Error("No events handler provided");
    }

    this.events = events;
    /**
     * The request mode.
     * @see  https://fetch.spec.whatwg.org/#requestmode
     * @type {String}
     */

    this.requestMode = options.requestMode || HTTP.defaultOptions.requestMode;
    /**
     * The request timeout.
     * @type {Number}
     */

    this.timeout = options.timeout || HTTP.defaultOptions.timeout;
  }
  /**
   * @private
   */


  (0, _createClass2.default)(HTTP, [{
    key: "timedFetch",
    value: function timedFetch(url, options) {
      var _this = this;

      var hasTimedout = false;
      return new Promise(function (resolve, reject) {
        // Detect if a request has timed out.
        var _timeoutId;

        if (_this.timeout) {
          _timeoutId = setTimeout(function () {
            hasTimedout = true;
            reject(new _errors.NetworkTimeoutError(url, options));
          }, _this.timeout);
        }

        function proceedWithHandler(fn) {
          return function (arg) {
            if (!hasTimedout) {
              if (_timeoutId) {
                clearTimeout(_timeoutId);
              }

              fn(arg);
            }
          };
        }

        fetch(url, options).then(proceedWithHandler(resolve)).catch(proceedWithHandler(reject));
      });
    }
    /**
     * @private
     */

  }, {
    key: "processResponse",
    value: function () {
      var _processResponse = (0, _asyncToGenerator2.default)(
      /*#__PURE__*/
      _regenerator.default.mark(function _callee(response) {
        var status, headers, text, json;
        return _regenerator.default.wrap(function _callee$(_context) {
          while (1) {
            switch (_context.prev = _context.next) {
              case 0:
                status = response.status, headers = response.headers;
                _context.next = 3;
                return response.text();

              case 3:
                text = _context.sent;

                if (!(text.length !== 0)) {
                  _context.next = 12;
                  break;
                }

                _context.prev = 5;
                json = JSON.parse(text);
                _context.next = 12;
                break;

              case 9:
                _context.prev = 9;
                _context.t0 = _context["catch"](5);
                throw new _errors.UnparseableResponseError(response, text, _context.t0);

              case 12:
                if (!(status >= 400)) {
                  _context.next = 14;
                  break;
                }

                throw new _errors.ServerResponse(response, json);

              case 14:
                return _context.abrupt("return", {
                  status: status,
                  json: json,
                  headers: headers
                });

              case 15:
              case "end":
                return _context.stop();
            }
          }
        }, _callee, this, [[5, 9]]);
      }));

      return function processResponse(_x) {
        return _processResponse.apply(this, arguments);
      };
    }()
    /**
     * @private
     */

  }, {
    key: "retry",
    value: function () {
      var _retry = (0, _asyncToGenerator2.default)(
      /*#__PURE__*/
      _regenerator.default.mark(function _callee2(url, retryAfter, request, options) {
        return _regenerator.default.wrap(function _callee2$(_context2) {
          while (1) {
            switch (_context2.prev = _context2.next) {
              case 0:
                _context2.next = 2;
                return (0, _utils.delay)(retryAfter);

              case 2:
                return _context2.abrupt("return", this.request(url, request, (0, _objectSpread2.default)({}, options, {
                  retry: options.retry - 1
                })));

              case 3:
              case "end":
                return _context2.stop();
            }
          }
        }, _callee2, this);
      }));

      return function retry(_x2, _x3, _x4, _x5) {
        return _retry.apply(this, arguments);
      };
    }()
    /**
     * Performs an HTTP request to the Kinto server.
     *
     * Resolves with an objet containing the following HTTP response properties:
     * - `{Number}  status`  The HTTP status code.
     * - `{Object}  json`    The JSON response body.
     * - `{Headers} headers` The response headers object; see the ES6 fetch() spec.
     *
     * @param  {String} url               The URL.
     * @param  {Object} [request={}]      The request object, passed to
     *     fetch() as its options object.
     * @param  {Object} [request.headers] The request headers object (default: {})
     * @param  {Object} [options={}]      Options for making the
     *     request
     * @param  {Number} [options.retry]   Number of retries (default: 0)
     * @return {Promise}
     */

  }, {
    key: "request",
    value: function () {
      var _request2 = (0, _asyncToGenerator2.default)(
      /*#__PURE__*/
      _regenerator.default.mark(function _callee3(url) {
        var _request,
            options,
            response,
            status,
            headers,
            retryAfter,
            _args3 = arguments;

        return _regenerator.default.wrap(function _callee3$(_context3) {
          while (1) {
            switch (_context3.prev = _context3.next) {
              case 0:
                _request = _args3.length > 1 && _args3[1] !== undefined ? _args3[1] : {
                  headers: {}
                };
                options = _args3.length > 2 && _args3[2] !== undefined ? _args3[2] : {
                  retry: 0
                };
                // Ensure default request headers are always set
                _request.headers = (0, _objectSpread2.default)({}, HTTP.DEFAULT_REQUEST_HEADERS, _request.headers); // If a multipart body is provided, remove any custom Content-Type header as
                // the fetch() implementation will add the correct one for us.

                if (_request.body && typeof _request.body.append === "function") {
                  delete _request.headers["Content-Type"];
                }

                _request.mode = this.requestMode;
                _context3.next = 7;
                return this.timedFetch(url, _request);

              case 7:
                response = _context3.sent;
                status = response.status, headers = response.headers;

                this._checkForDeprecationHeader(headers);

                this._checkForBackoffHeader(status, headers); // Check if the server summons the client to retry after a while.


                retryAfter = this._checkForRetryAfterHeader(status, headers); // If number of allowed of retries is not exhausted, retry the same request.

                if (!(retryAfter && options.retry > 0)) {
                  _context3.next = 16;
                  break;
                }

                return _context3.abrupt("return", this.retry(url, retryAfter, _request, options));

              case 16:
                return _context3.abrupt("return", this.processResponse(response));

              case 17:
              case "end":
                return _context3.stop();
            }
          }
        }, _callee3, this);
      }));

      return function request(_x6) {
        return _request2.apply(this, arguments);
      };
    }()
  }, {
    key: "_checkForDeprecationHeader",
    value: function _checkForDeprecationHeader(headers) {
      var alertHeader = headers.get("Alert");

      if (!alertHeader) {
        return;
      }

      var alert;

      try {
        alert = JSON.parse(alertHeader);
      } catch (err) {
        console.warn("Unable to parse Alert header message", alertHeader);
        return;
      }

      console.warn(alert.message, alert.url);
      this.events.emit("deprecated", alert);
    }
  }, {
    key: "_checkForBackoffHeader",
    value: function _checkForBackoffHeader(status, headers) {
      var backoffMs;
      var backoffSeconds = parseInt(headers.get("Backoff"), 10);

      if (backoffSeconds > 0) {
        backoffMs = new Date().getTime() + backoffSeconds * 1000;
      } else {
        backoffMs = 0;
      }

      this.events.emit("backoff", backoffMs);
    }
  }, {
    key: "_checkForRetryAfterHeader",
    value: function _checkForRetryAfterHeader(status, headers) {
      var retryAfter = headers.get("Retry-After");

      if (!retryAfter) {
        return;
      }

      var delay = parseInt(retryAfter, 10) * 1000;
      retryAfter = new Date().getTime() + delay;
      this.events.emit("retry-after", retryAfter);
      return delay;
    }
  }]);
  return HTTP;
}();

exports.default = HTTP;
},{"./errors":312,"./utils":316,"@babel/runtime/helpers/asyncToGenerator":281,"@babel/runtime/helpers/classCallCheck":282,"@babel/runtime/helpers/createClass":284,"@babel/runtime/helpers/interopRequireDefault":288,"@babel/runtime/helpers/objectSpread":295,"@babel/runtime/regenerator":305}],314:[function(require,module,exports){
"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;

var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof"));

var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));

var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn"));

var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf"));

var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits"));

var _events = require("events");

var _base = _interopRequireDefault(require("./base"));

var KintoClient =
/*#__PURE__*/
function (_KintoClientBase) {
  (0, _inherits2.default)(KintoClient, _KintoClientBase);

  function KintoClient(remote) {
    var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
    (0, _classCallCheck2.default)(this, KintoClient);
    var events = options.events || new _events.EventEmitter();
    return (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(KintoClient).call(this, remote, Object.assign({
      events: events
    }, options)));
  }

  return KintoClient;
}(_base.default); // This is a hack to avoid Browserify to expose the above class
// at `new KintoClient()` instead of `new KintoClient.default()`.
// See https://github.com/Kinto/kinto-http.js/issues/77


exports.default = KintoClient;

if ((typeof module === "undefined" ? "undefined" : (0, _typeof2.default)(module)) === "object") {
  module.exports = KintoClient;
}
},{"./base":307,"@babel/runtime/helpers/classCallCheck":282,"@babel/runtime/helpers/getPrototypeOf":286,"@babel/runtime/helpers/inherits":287,"@babel/runtime/helpers/interopRequireDefault":288,"@babel/runtime/helpers/possibleConstructorReturn":296,"@babel/runtime/helpers/typeof":301,"events":306}],315:[function(require,module,exports){
"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.createRequest = createRequest;
exports.updateRequest = updateRequest;
exports.jsonPatchPermissionsRequest = jsonPatchPermissionsRequest;
exports.deleteRequest = deleteRequest;
exports.addAttachmentRequest = addAttachmentRequest;

var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));

var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread"));

var _utils = require("./utils");

var requestDefaults = {
  safe: false,
  // check if we should set default content type here
  headers: {},
  permissions: undefined,
  data: undefined,
  patch: false
};
/**
 * @private
 */

function safeHeader(safe, last_modified) {
  if (!safe) {
    return {};
  }

  if (last_modified) {
    return {
      "If-Match": "\"".concat(last_modified, "\"")
    };
  }

  return {
    "If-None-Match": "*"
  };
}
/**
 * @private
 */


function createRequest(path, _ref) {
  var data = _ref.data,
      permissions = _ref.permissions;
  var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};

  var _requestDefaults$opti = (0, _objectSpread2.default)({}, requestDefaults, options),
      headers = _requestDefaults$opti.headers,
      safe = _requestDefaults$opti.safe;

  return {
    method: data && data.id ? "PUT" : "POST",
    path: path,
    headers: (0, _objectSpread2.default)({}, headers, safeHeader(safe)),
    body: {
      data: data,
      permissions: permissions
    }
  };
}
/**
 * @private
 */


function updateRequest(path, _ref2) {
  var data = _ref2.data,
      permissions = _ref2.permissions;
  var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};

  var _requestDefaults$opti2 = (0, _objectSpread2.default)({}, requestDefaults, options),
      headers = _requestDefaults$opti2.headers,
      safe = _requestDefaults$opti2.safe,
      patch = _requestDefaults$opti2.patch;

  var _data$options = (0, _objectSpread2.default)({}, data, options),
      last_modified = _data$options.last_modified;

  if (Object.keys((0, _utils.omit)(data, "id", "last_modified")).length === 0) {
    data = undefined;
  }

  return {
    method: patch ? "PATCH" : "PUT",
    path: path,
    headers: (0, _objectSpread2.default)({}, headers, safeHeader(safe, last_modified)),
    body: {
      data: data,
      permissions: permissions
    }
  };
}
/**
 * @private
 */


function jsonPatchPermissionsRequest(path, permissions, opType) {
  var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};

  var _requestDefaults$opti3 = (0, _objectSpread2.default)({}, requestDefaults, options),
      headers = _requestDefaults$opti3.headers,
      safe = _requestDefaults$opti3.safe,
      last_modified = _requestDefaults$opti3.last_modified;

  var ops = [];

  var _arr = Object.entries(permissions);

  for (var _i = 0; _i < _arr.length; _i++) {
    var _arr$_i = (0, _slicedToArray2.default)(_arr[_i], 2),
        type = _arr$_i[0],
        principals = _arr$_i[1];

    var _iteratorNormalCompletion = true;
    var _didIteratorError = false;
    var _iteratorError = undefined;

    try {
      for (var _iterator = principals[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
        var principal = _step.value;
        ops.push({
          op: opType,
          path: "/permissions/".concat(type, "/").concat(principal)
        });
      }
    } catch (err) {
      _didIteratorError = true;
      _iteratorError = err;
    } finally {
      try {
        if (!_iteratorNormalCompletion && _iterator.return != null) {
          _iterator.return();
        }
      } finally {
        if (_didIteratorError) {
          throw _iteratorError;
        }
      }
    }
  }

  return {
    method: "PATCH",
    path: path,
    headers: (0, _objectSpread2.default)({}, headers, safeHeader(safe, last_modified), {
      "Content-Type": "application/json-patch+json"
    }),
    body: ops
  };
}
/**
 * @private
 */


function deleteRequest(path) {
  var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};

  var _requestDefaults$opti4 = (0, _objectSpread2.default)({}, requestDefaults, options),
      headers = _requestDefaults$opti4.headers,
      safe = _requestDefaults$opti4.safe,
      last_modified = _requestDefaults$opti4.last_modified;

  if (safe && !last_modified) {
    throw new Error("Safe concurrency check requires a last_modified value.");
  }

  return {
    method: "DELETE",
    path: path,
    headers: (0, _objectSpread2.default)({}, headers, safeHeader(safe, last_modified))
  };
}
/**
 * @private
 */


function addAttachmentRequest(path, dataURI) {
  var _ref3 = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {},
      data = _ref3.data,
      permissions = _ref3.permissions;

  var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};

  var _requestDefaults$opti5 = (0, _objectSpread2.default)({}, requestDefaults, options),
      headers = _requestDefaults$opti5.headers,
      safe = _requestDefaults$opti5.safe,
      gzipped = _requestDefaults$opti5.gzipped;

  var _data$options2 = (0, _objectSpread2.default)({}, data, options),
      last_modified = _data$options2.last_modified;

  var body = {
    data: data,
    permissions: permissions
  };
  var formData = (0, _utils.createFormData)(dataURI, body, options);
  var customPath = gzipped != null ? customPath = path + "?gzipped=" + (gzipped ? "true" : "false") : path;
  return {
    method: "POST",
    path: customPath,
    headers: (0, _objectSpread2.default)({}, headers, safeHeader(safe, last_modified)),
    body: formData
  };
}
},{"./utils":316,"@babel/runtime/helpers/interopRequireDefault":288,"@babel/runtime/helpers/objectSpread":295,"@babel/runtime/helpers/slicedToArray":298}],316:[function(require,module,exports){
"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.partition = partition;
exports.delay = delay;
exports.pMap = pMap;
exports.omit = omit;
exports.toDataBody = toDataBody;
exports.qsify = qsify;
exports.checkVersion = checkVersion;
exports.support = support;
exports.capable = capable;
exports.nobatch = nobatch;
exports.isObject = isObject;
exports.parseDataURL = parseDataURL;
exports.extractFileInfo = extractFileInfo;
exports.createFormData = createFormData;
exports.cleanUndefinedProperties = cleanUndefinedProperties;

var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));

var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));

var _objectSpread3 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread"));

var _toArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toArray"));

var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof"));

var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));

var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));

/**
 * Chunks an array into n pieces.
 *
 * @private
 * @param  {Array}  array
 * @param  {Number} n
 * @return {Array}
 */
function partition(array, n) {
  if (n <= 0) {
    return array;
  }

  return array.reduce(function (acc, x, i) {
    if (i === 0 || i % n === 0) {
      acc.push([x]);
    } else {
      acc[acc.length - 1].push(x);
    }

    return acc;
  }, []);
}
/**
 * Returns a Promise always resolving after the specified amount in milliseconds.
 *
 * @return Promise<void>
 */


function delay(ms) {
  return new Promise(function (resolve) {
    return setTimeout(resolve, ms);
  });
}
/**
 * Maps a list to promises using the provided mapping function, executes them
 * sequentially then returns a Promise resolving with ordered results obtained.
 * Think of this as a sequential Promise.all.
 *
 * @private
 * @param  {Array}    list The list to map.
 * @param  {Function} fn   The mapping function.
 * @return {Promise}
 */


function pMap(_x, _x2) {
  return _pMap.apply(this, arguments);
}
/**
 * Takes an object and returns a copy of it with the provided keys omitted.
 *
 * @private
 * @param  {Object}    obj  The source object.
 * @param  {...String} keys The keys to omit.
 * @return {Object}
 */


function _pMap() {
  _pMap = (0, _asyncToGenerator2.default)(
  /*#__PURE__*/
  _regenerator.default.mark(function _callee2(list, fn) {
    var results;
    return _regenerator.default.wrap(function _callee2$(_context2) {
      while (1) {
        switch (_context2.prev = _context2.next) {
          case 0:
            results = [];
            _context2.next = 3;
            return list.reduce(
            /*#__PURE__*/
            function () {
              var _ref = (0, _asyncToGenerator2.default)(
              /*#__PURE__*/
              _regenerator.default.mark(function _callee(promise, entry) {
                return _regenerator.default.wrap(function _callee$(_context) {
                  while (1) {
                    switch (_context.prev = _context.next) {
                      case 0:
                        _context.next = 2;
                        return promise;

                      case 2:
                        _context.t0 = results;
                        _context.next = 5;
                        return fn(entry);

                      case 5:
                        _context.t1 = _context.sent;
                        results = _context.t0.concat.call(_context.t0, _context.t1);

                      case 7:
                      case "end":
                        return _context.stop();
                    }
                  }
                }, _callee, this);
              }));

              return function (_x3, _x4) {
                return _ref.apply(this, arguments);
              };
            }(), Promise.resolve());

          case 3:
            return _context2.abrupt("return", results);

          case 4:
          case "end":
            return _context2.stop();
        }
      }
    }, _callee2, this);
  }));
  return _pMap.apply(this, arguments);
}

function omit(obj) {
  for (var _len = arguments.length, keys = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
    keys[_key - 1] = arguments[_key];
  }

  return Object.keys(obj).reduce(function (acc, key) {
    if (!keys.includes(key)) {
      acc[key] = obj[key];
    }

    return acc;
  }, {});
}
/**
 * Always returns a resource data object from the provided argument.
 *
 * @private
 * @param  {Object|String} resource
 * @return {Object}
 */


function toDataBody(resource) {
  if (isObject(resource)) {
    return resource;
  }

  if (typeof resource === "string") {
    return {
      id: resource
    };
  }

  throw new Error("Invalid argument.");
}
/**
 * Transforms an object into an URL query string, stripping out any undefined
 * values.
 *
 * @param  {Object} obj
 * @return {String}
 */


function qsify(obj) {
  var encode = function encode(v) {
    return encodeURIComponent(typeof v === "boolean" ? String(v) : v);
  };

  var stripUndefined = function stripUndefined(o) {
    return JSON.parse(JSON.stringify(o));
  };

  var stripped = stripUndefined(obj);
  return Object.keys(stripped).map(function (k) {
    var ks = encode(k) + "=";

    if (Array.isArray(stripped[k])) {
      return ks + stripped[k].map(function (v) {
        return encode(v);
      }).join(",");
    } else {
      return ks + encode(stripped[k]);
    }
  }).join("&");
}
/**
 * Checks if a version is within the provided range.
 *
 * @param  {String} version    The version to check.
 * @param  {String} minVersion The minimum supported version (inclusive).
 * @param  {String} maxVersion The minimum supported version (exclusive).
 * @throws {Error} If the version is outside of the provided range.
 */


function checkVersion(version, minVersion, maxVersion) {
  var extract = function extract(str) {
    return str.split(".").map(function (x) {
      return parseInt(x, 10);
    });
  };

  var _extract = extract(version),
      _extract2 = (0, _slicedToArray2.default)(_extract, 2),
      verMajor = _extract2[0],
      verMinor = _extract2[1];

  var _extract3 = extract(minVersion),
      _extract4 = (0, _slicedToArray2.default)(_extract3, 2),
      minMajor = _extract4[0],
      minMinor = _extract4[1];

  var _extract5 = extract(maxVersion),
      _extract6 = (0, _slicedToArray2.default)(_extract5, 2),
      maxMajor = _extract6[0],
      maxMinor = _extract6[1];

  var checks = [verMajor < minMajor, verMajor === minMajor && verMinor < minMinor, verMajor > maxMajor, verMajor === maxMajor && verMinor >= maxMinor];

  if (checks.some(function (x) {
    return x;
  })) {
    throw new Error("Version ".concat(version, " doesn't satisfy ").concat(minVersion, " <= x < ").concat(maxVersion));
  }
}
/**
 * Generates a decorator function ensuring a version check is performed against
 * the provided requirements before executing it.
 *
 * @param  {String} min The required min version (inclusive).
 * @param  {String} max The required max version (inclusive).
 * @return {Function}
 */


function support(min, max) {
  return function (target, key, descriptor) {
    var fn = descriptor.value;
    return {
      configurable: true,
      get: function get() {
        var _this = this;

        var wrappedMethod = function wrappedMethod() {
          for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
            args[_key2] = arguments[_key2];
          }

          // "this" is the current instance which its method is decorated.
          var client = "client" in _this ? _this.client : _this;
          return client.fetchHTTPApiVersion().then(function (version) {
            return checkVersion(version, min, max);
          }).then(function () {
            return fn.apply(_this, args);
          });
        };

        Object.defineProperty(this, key, {
          value: wrappedMethod,
          configurable: true,
          writable: true
        });
        return wrappedMethod;
      }
    };
  };
}
/**
 * Generates a decorator function ensuring that the specified capabilities are
 * available on the server before executing it.
 *
 * @param  {Array<String>} capabilities The required capabilities.
 * @return {Function}
 */


function capable(capabilities) {
  return function (target, key, descriptor) {
    var fn = descriptor.value;
    return {
      configurable: true,
      get: function get() {
        var _this2 = this;

        var wrappedMethod = function wrappedMethod() {
          for (var _len3 = arguments.length, args = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
            args[_key3] = arguments[_key3];
          }

          // "this" is the current instance which its method is decorated.
          var client = "client" in _this2 ? _this2.client : _this2;
          return client.fetchServerCapabilities().then(function (available) {
            var missing = capabilities.filter(function (c) {
              return !(c in available);
            });

            if (missing.length > 0) {
              var missingStr = missing.join(", ");
              throw new Error("Required capabilities ".concat(missingStr, " not present on server"));
            }
          }).then(function () {
            return fn.apply(_this2, args);
          });
        };

        Object.defineProperty(this, key, {
          value: wrappedMethod,
          configurable: true,
          writable: true
        });
        return wrappedMethod;
      }
    };
  };
}
/**
 * Generates a decorator function ensuring an operation is not performed from
 * within a batch request.
 *
 * @param  {String} message The error message to throw.
 * @return {Function}
 */


function nobatch(message) {
  return function (target, key, descriptor) {
    var fn = descriptor.value;
    return {
      configurable: true,
      get: function get() {
        var _this3 = this;

        var wrappedMethod = function wrappedMethod() {
          // "this" is the current instance which its method is decorated.
          if (_this3._isBatch) {
            throw new Error(message);
          }

          for (var _len4 = arguments.length, args = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {
            args[_key4] = arguments[_key4];
          }

          return fn.apply(_this3, args);
        };

        Object.defineProperty(this, key, {
          value: wrappedMethod,
          configurable: true,
          writable: true
        });
        return wrappedMethod;
      }
    };
  };
}
/**
 * Returns true if the specified value is an object (i.e. not an array nor null).
 * @param  {Object} thing The value to inspect.
 * @return {bool}
 */


function isObject(thing) {
  return (0, _typeof2.default)(thing) === "object" && thing !== null && !Array.isArray(thing);
}
/**
 * Parses a data url.
 * @param  {String} dataURL The data url.
 * @return {Object}
 */


function parseDataURL(dataURL) {
  var regex = /^data:(.*);base64,(.*)/;
  var match = dataURL.match(regex);

  if (!match) {
    throw new Error("Invalid data-url: ".concat(String(dataURL).substr(0, 32), "..."));
  }

  var props = match[1];
  var base64 = match[2];

  var _props$split = props.split(";"),
      _props$split2 = (0, _toArray2.default)(_props$split),
      type = _props$split2[0],
      rawParams = _props$split2.slice(1);

  var params = rawParams.reduce(function (acc, param) {
    var _param$split = param.split("="),
        _param$split2 = (0, _slicedToArray2.default)(_param$split, 2),
        key = _param$split2[0],
        value = _param$split2[1];

    return (0, _objectSpread3.default)({}, acc, (0, _defineProperty2.default)({}, key, value));
  }, {});
  return (0, _objectSpread3.default)({}, params, {
    type: type,
    base64: base64
  });
}
/**
 * Extracts file information from a data url.
 * @param  {String} dataURL The data url.
 * @return {Object}
 */


function extractFileInfo(dataURL) {
  var _parseDataURL = parseDataURL(dataURL),
      name = _parseDataURL.name,
      type = _parseDataURL.type,
      base64 = _parseDataURL.base64;

  var binary = atob(base64);
  var array = [];

  for (var i = 0; i < binary.length; i++) {
    array.push(binary.charCodeAt(i));
  }

  var blob = new Blob([new Uint8Array(array)], {
    type: type
  });
  return {
    blob: blob,
    name: name
  };
}
/**
 * Creates a FormData instance from a data url and an existing JSON response
 * body.
 * @param  {String} dataURL            The data url.
 * @param  {Object} body               The response body.
 * @param  {Object} [options={}]       The options object.
 * @param  {Object} [options.filename] Force attachment file name.
 * @return {FormData}
 */


function createFormData(dataURL, body) {
  var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
  var _options$filename = options.filename,
      filename = _options$filename === void 0 ? "untitled" : _options$filename;

  var _extractFileInfo = extractFileInfo(dataURL),
      blob = _extractFileInfo.blob,
      name = _extractFileInfo.name;

  var formData = new FormData();
  formData.append("attachment", blob, name || filename);

  for (var property in body) {
    if (typeof body[property] !== "undefined") {
      formData.append(property, JSON.stringify(body[property]));
    }
  }

  return formData;
}
/**
 * Clones an object with all its undefined keys removed.
 * @private
 */


function cleanUndefinedProperties(obj) {
  var result = {};

  for (var key in obj) {
    if (typeof obj[key] !== "undefined") {
      result[key] = obj[key];
    }
  }

  return result;
}
},{"@babel/runtime/helpers/asyncToGenerator":281,"@babel/runtime/helpers/defineProperty":285,"@babel/runtime/helpers/interopRequireDefault":288,"@babel/runtime/helpers/objectSpread":295,"@babel/runtime/helpers/slicedToArray":298,"@babel/runtime/helpers/toArray":299,"@babel/runtime/helpers/typeof":301,"@babel/runtime/regenerator":305}],317:[function(require,module,exports){
var v1 = require('./v1');
var v4 = require('./v4');

var uuid = v4;
uuid.v1 = v1;
uuid.v4 = v4;

module.exports = uuid;

},{"./v1":320,"./v4":321}],318:[function(require,module,exports){
/**
 * Convert array of 16 byte values to UUID string format of the form:
 * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
 */
var byteToHex = [];
for (var i = 0; i < 256; ++i) {
  byteToHex[i] = (i + 0x100).toString(16).substr(1);
}

function bytesToUuid(buf, offset) {
  var i = offset || 0;
  var bth = byteToHex;
  // join used to fix memory issue caused by concatenation: https://bugs.chromium.org/p/v8/issues/detail?id=3175#c4
  return ([bth[buf[i++]], bth[buf[i++]], 
	bth[buf[i++]], bth[buf[i++]], '-',
	bth[buf[i++]], bth[buf[i++]], '-',
	bth[buf[i++]], bth[buf[i++]], '-',
	bth[buf[i++]], bth[buf[i++]], '-',
	bth[buf[i++]], bth[buf[i++]],
	bth[buf[i++]], bth[buf[i++]],
	bth[buf[i++]], bth[buf[i++]]]).join('');
}

module.exports = bytesToUuid;

},{}],319:[function(require,module,exports){
// Unique ID creation requires a high quality random # generator.  In the
// browser this is a little complicated due to unknown quality of Math.random()
// and inconsistent support for the `crypto` API.  We do the best we can via
// feature-detection

// getRandomValues needs to be invoked in a context where "this" is a Crypto
// implementation. Also, find the complete implementation of crypto on IE11.
var getRandomValues = (typeof(crypto) != 'undefined' && crypto.getRandomValues && crypto.getRandomValues.bind(crypto)) ||
                      (typeof(msCrypto) != 'undefined' && typeof window.msCrypto.getRandomValues == 'function' && msCrypto.getRandomValues.bind(msCrypto));

if (getRandomValues) {
  // WHATWG crypto RNG - http://wiki.whatwg.org/wiki/Crypto
  var rnds8 = new Uint8Array(16); // eslint-disable-line no-undef

  module.exports = function whatwgRNG() {
    getRandomValues(rnds8);
    return rnds8;
  };
} else {
  // Math.random()-based (RNG)
  //
  // If all else fails, use Math.random().  It's fast, but is of unspecified
  // quality.
  var rnds = new Array(16);

  module.exports = function mathRNG() {
    for (var i = 0, r; i < 16; i++) {
      if ((i & 0x03) === 0) r = Math.random() * 0x100000000;
      rnds[i] = r >>> ((i & 0x03) << 3) & 0xff;
    }

    return rnds;
  };
}

},{}],320:[function(require,module,exports){
var rng = require('./lib/rng');
var bytesToUuid = require('./lib/bytesToUuid');

// **`v1()` - Generate time-based UUID**
//
// Inspired by https://github.com/LiosK/UUID.js
// and http://docs.python.org/library/uuid.html

var _nodeId;
var _clockseq;

// Previous uuid creation time
var _lastMSecs = 0;
var _lastNSecs = 0;

// See https://github.com/broofa/node-uuid for API details
function v1(options, buf, offset) {
  var i = buf && offset || 0;
  var b = buf || [];

  options = options || {};
  var node = options.node || _nodeId;
  var clockseq = options.clockseq !== undefined ? options.clockseq : _clockseq;

  // node and clockseq need to be initialized to random values if they're not
  // specified.  We do this lazily to minimize issues related to insufficient
  // system entropy.  See #189
  if (node == null || clockseq == null) {
    var seedBytes = rng();
    if (node == null) {
      // Per 4.5, create and 48-bit node id, (47 random bits + multicast bit = 1)
      node = _nodeId = [
        seedBytes[0] | 0x01,
        seedBytes[1], seedBytes[2], seedBytes[3], seedBytes[4], seedBytes[5]
      ];
    }
    if (clockseq == null) {
      // Per 4.2.2, randomize (14 bit) clockseq
      clockseq = _clockseq = (seedBytes[6] << 8 | seedBytes[7]) & 0x3fff;
    }
  }

  // UUID timestamps are 100 nano-second units since the Gregorian epoch,
  // (1582-10-15 00:00).  JSNumbers aren't precise enough for this, so
  // time is handled internally as 'msecs' (integer milliseconds) and 'nsecs'
  // (100-nanoseconds offset from msecs) since unix epoch, 1970-01-01 00:00.
  var msecs = options.msecs !== undefined ? options.msecs : new Date().getTime();

  // Per 4.2.1.2, use count of uuid's generated during the current clock
  // cycle to simulate higher resolution clock
  var nsecs = options.nsecs !== undefined ? options.nsecs : _lastNSecs + 1;

  // Time since last uuid creation (in msecs)
  var dt = (msecs - _lastMSecs) + (nsecs - _lastNSecs)/10000;

  // Per 4.2.1.2, Bump clockseq on clock regression
  if (dt < 0 && options.clockseq === undefined) {
    clockseq = clockseq + 1 & 0x3fff;
  }

  // Reset nsecs if clock regresses (new clockseq) or we've moved onto a new
  // time interval
  if ((dt < 0 || msecs > _lastMSecs) && options.nsecs === undefined) {
    nsecs = 0;
  }

  // Per 4.2.1.2 Throw error if too many uuids are requested
  if (nsecs >= 10000) {
    throw new Error('uuid.v1(): Can\'t create more than 10M uuids/sec');
  }

  _lastMSecs = msecs;
  _lastNSecs = nsecs;
  _clockseq = clockseq;

  // Per 4.1.4 - Convert from unix epoch to Gregorian epoch
  msecs += 12219292800000;

  // `time_low`
  var tl = ((msecs & 0xfffffff) * 10000 + nsecs) % 0x100000000;
  b[i++] = tl >>> 24 & 0xff;
  b[i++] = tl >>> 16 & 0xff;
  b[i++] = tl >>> 8 & 0xff;
  b[i++] = tl & 0xff;

  // `time_mid`
  var tmh = (msecs / 0x100000000 * 10000) & 0xfffffff;
  b[i++] = tmh >>> 8 & 0xff;
  b[i++] = tmh & 0xff;

  // `time_high_and_version`
  b[i++] = tmh >>> 24 & 0xf | 0x10; // include version
  b[i++] = tmh >>> 16 & 0xff;

  // `clock_seq_hi_and_reserved` (Per 4.2.2 - include variant)
  b[i++] = clockseq >>> 8 | 0x80;

  // `clock_seq_low`
  b[i++] = clockseq & 0xff;

  // `node`
  for (var n = 0; n < 6; ++n) {
    b[i + n] = node[n];
  }

  return buf ? buf : bytesToUuid(b);
}

module.exports = v1;

},{"./lib/bytesToUuid":318,"./lib/rng":319}],321:[function(require,module,exports){
var rng = require('./lib/rng');
var bytesToUuid = require('./lib/bytesToUuid');

function v4(options, buf, offset) {
  var i = buf && offset || 0;

  if (typeof(options) == 'string') {
    buf = options === 'binary' ? new Array(16) : null;
    options = null;
  }
  options = options || {};

  var rnds = options.random || (options.rng || rng)();

  // Per 4.4, set bits for version and `clock_seq_hi_and_reserved`
  rnds[6] = (rnds[6] & 0x0f) | 0x40;
  rnds[8] = (rnds[8] & 0x3f) | 0x80;

  // Copy bytes to buffer, if provided
  if (buf) {
    for (var ii = 0; ii < 16; ++ii) {
      buf[i + ii] = rnds[ii];
    }
  }

  return buf || bytesToUuid(rnds);
}

module.exports = v4;

},{"./lib/bytesToUuid":318,"./lib/rng":319}],322:[function(require,module,exports){
"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;

var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread"));

var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));

var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));

var _collection = _interopRequireDefault(require("./collection"));

var _base = _interopRequireDefault(require("./adapters/base"));

var DEFAULT_BUCKET_NAME = "default";
var DEFAULT_REMOTE = "http://localhost:8888/v1";
var DEFAULT_RETRY = 1;
/**
 * KintoBase class.
 */

var KintoBase =
/*#__PURE__*/
function () {
  (0, _createClass2.default)(KintoBase, null, [{
    key: "adapters",

    /**
     * Provides a public access to the base adapter class. Users can create a
     * custom DB adapter by extending {@link BaseAdapter}.
     *
     * @type {Object}
     */
    get: function get() {
      return {
        BaseAdapter: _base.default
      };
    }
    /**
     * Synchronization strategies. Available strategies are:
     *
     * - `MANUAL`: Conflicts will be reported in a dedicated array.
     * - `SERVER_WINS`: Conflicts are resolved using remote data.
     * - `CLIENT_WINS`: Conflicts are resolved using local data.
     *
     * @type {Object}
     */

  }, {
    key: "syncStrategy",
    get: function get() {
      return _collection.default.strategy;
    }
    /**
     * Constructor.
     *
     * Options:
     * - `{String}`       `remote`         The server URL to use.
     * - `{String}`       `bucket`         The collection bucket name.
     * - `{EventEmitter}` `events`         Events handler.
     * - `{BaseAdapter}`  `adapter`        The base DB adapter class.
     * - `{Object}`       `adapterOptions` Options given to the adapter.
     * - `{Object}`       `headers`        The HTTP headers to use.
     * - `{Object}`       `retry`          Number of retries when the server fails to process the request (default: `1`)
     * - `{String}`       `requestMode`    The HTTP CORS mode to use.
     * - `{Number}`       `timeout`        The requests timeout in ms (default: `5000`).
     *
     * @param  {Object} options The options object.
     */

  }]);

  function KintoBase() {
    var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
    (0, _classCallCheck2.default)(this, KintoBase);
    var defaults = {
      bucket: DEFAULT_BUCKET_NAME,
      remote: DEFAULT_REMOTE,
      retry: DEFAULT_RETRY
    };
    this._options = (0, _objectSpread2.default)({}, defaults, options);

    if (!this._options.adapter) {
      throw new Error("No adapter provided");
    }

    var _this$_options = this._options,
        ApiClass = _this$_options.ApiClass,
        events = _this$_options.events,
        headers = _this$_options.headers,
        remote = _this$_options.remote,
        requestMode = _this$_options.requestMode,
        retry = _this$_options.retry,
        timeout = _this$_options.timeout; // public properties

    /**
     * The kinto HTTP client instance.
     * @type {KintoClient}
     */

    this.api = new ApiClass(remote, {
      events: events,
      headers: headers,
      requestMode: requestMode,
      retry: retry,
      timeout: timeout
    });
    /**
     * The event emitter instance.
     * @type {EventEmitter}
     */

    this.events = this._options.events;
  }
  /**
   * Creates a {@link Collection} instance. The second (optional) parameter
   * will set collection-level options like e.g. `remoteTransformers`.
   *
   * @param  {String} collName The collection name.
   * @param  {Object} [options={}]                 Extra options or override client's options.
   * @param  {Object} [options.idSchema]           IdSchema instance (default: UUID)
   * @param  {Object} [options.remoteTransformers] Array<RemoteTransformer> (default: `[]`])
   * @param  {Object} [options.hooks]              Array<Hook> (default: `[]`])
   * @param  {Object} [options.localFields]        Array<Field> (default: `[]`])
   * @return {Collection}
   */


  (0, _createClass2.default)(KintoBase, [{
    key: "collection",
    value: function collection(collName) {
      var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};

      if (!collName) {
        throw new Error("missing collection name");
      }

      var _this$_options$option = (0, _objectSpread2.default)({}, this._options, options),
          bucket = _this$_options$option.bucket,
          events = _this$_options$option.events,
          adapter = _this$_options$option.adapter,
          adapterOptions = _this$_options$option.adapterOptions;

      var idSchema = options.idSchema,
          remoteTransformers = options.remoteTransformers,
          hooks = options.hooks,
          localFields = options.localFields;
      return new _collection.default(bucket, collName, this.api, {
        events: events,
        adapter: adapter,
        adapterOptions: adapterOptions,
        idSchema: idSchema,
        remoteTransformers: remoteTransformers,
        hooks: hooks,
        localFields: localFields
      });
    }
  }]);
  return KintoBase;
}();

exports.default = KintoBase;

},{"./adapters/base":324,"./collection":325,"@babel/runtime/helpers/classCallCheck":282,"@babel/runtime/helpers/createClass":284,"@babel/runtime/helpers/interopRequireDefault":288,"@babel/runtime/helpers/objectSpread":295}],323:[function(require,module,exports){
"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.open = _open2;
exports.execute = execute;
exports.default = void 0;

var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread"));

var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));

var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));

var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));

var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));

var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn"));

var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf"));

var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits"));

var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));

var _base = _interopRequireDefault(require("./base.js"));

var _utils = require("../utils");

var INDEXED_FIELDS = ["id", "_status", "last_modified"];
/**
 * Small helper that wraps the opening of an IndexedDB into a Promise.
 *
 * @param dbname          {String}   The database name.
 * @param version         {Integer}  Schema version
 * @param onupgradeneeded {Function} The callback to execute if schema is
 *                                   missing or different.
 * @return {Promise<IDBDatabase>}
 */

function _open2(_x, _x2) {
  return _open.apply(this, arguments);
}
/**
 * Helper to run the specified callback in a single transaction on the
 * specified store.
 * The helper focuses on transaction wrapping into a promise.
 *
 * @param db           {IDBDatabase} The database instance.
 * @param name         {String}      The store name.
 * @param callback     {Function}    The piece of code to execute in the transaction.
 * @param options      {Object}      Options.
 * @param options.mode {String}      Transaction mode (default: read).
 * @return {Promise} any value returned by the callback.
 */


function _open() {
  _open = (0, _asyncToGenerator2.default)(
  /*#__PURE__*/
  _regenerator.default.mark(function _callee13(dbname, _ref) {
    var version, onupgradeneeded;
    return _regenerator.default.wrap(function _callee13$(_context13) {
      while (1) {
        switch (_context13.prev = _context13.next) {
          case 0:
            version = _ref.version, onupgradeneeded = _ref.onupgradeneeded;
            return _context13.abrupt("return", new Promise(function (resolve, reject) {
              var request = indexedDB.open(dbname, version);

              request.onupgradeneeded = function (event) {
                var db = event.target.result;

                db.onerror = function (event) {
                  return reject(event.target.error);
                };

                return onupgradeneeded(event);
              };

              request.onerror = function (event) {
                reject(event.target.error);
              };

              request.onsuccess = function (event) {
                var db = event.target.result;
                resolve(db);
              };
            }));

          case 2:
          case "end":
            return _context13.stop();
        }
      }
    }, _callee13, this);
  }));
  return _open.apply(this, arguments);
}

function execute(_x3, _x4, _x5) {
  return _execute.apply(this, arguments);
}
/**
 * Helper to wrap the deletion of an IndexedDB database into a promise.
 *
 * @param dbName {String} the database to delete
 * @return {Promise}
 */


function _execute() {
  _execute = (0, _asyncToGenerator2.default)(
  /*#__PURE__*/
  _regenerator.default.mark(function _callee14(db, name, callback) {
    var options,
        mode,
        _args14 = arguments;
    return _regenerator.default.wrap(function _callee14$(_context14) {
      while (1) {
        switch (_context14.prev = _context14.next) {
          case 0:
            options = _args14.length > 3 && _args14[3] !== undefined ? _args14[3] : {};
            mode = options.mode;
            return _context14.abrupt("return", new Promise(function (resolve, reject) {
              // On Safari, calling IDBDatabase.transaction with mode == undefined raises
              // a TypeError.
              var transaction = mode ? db.transaction([name], mode) : db.transaction([name]);
              var store = transaction.objectStore(name); // Let the callback abort this transaction.

              var abort = function abort(e) {
                transaction.abort();
                reject(e);
              }; // Execute the specified callback **synchronously**.


              var result;

              try {
                result = callback(store, abort);
              } catch (e) {
                abort(e);
              }

              transaction.onerror = function (event) {
                return reject(event.target.error);
              };

              transaction.oncomplete = function (event) {
                return resolve(result);
              };
            }));

          case 3:
          case "end":
            return _context14.stop();
        }
      }
    }, _callee14, this);
  }));
  return _execute.apply(this, arguments);
}

function deleteDatabase(_x6) {
  return _deleteDatabase.apply(this, arguments);
}
/**
 * IDB cursor handlers.
 * @type {Object}
 */


function _deleteDatabase() {
  _deleteDatabase = (0, _asyncToGenerator2.default)(
  /*#__PURE__*/
  _regenerator.default.mark(function _callee15(dbName) {
    return _regenerator.default.wrap(function _callee15$(_context15) {
      while (1) {
        switch (_context15.prev = _context15.next) {
          case 0:
            return _context15.abrupt("return", new Promise(function (resolve, reject) {
              var request = indexedDB.deleteDatabase(dbName);

              request.onsuccess = function (event) {
                return resolve(event.target);
              };

              request.onerror = function (event) {
                return reject(event.target.error);
              };
            }));

          case 1:
          case "end":
            return _context15.stop();
        }
      }
    }, _callee15, this);
  }));
  return _deleteDatabase.apply(this, arguments);
}

var cursorHandlers = {
  all: function all(filters, done) {
    var results = [];
    return function (event) {
      var cursor = event.target.result;

      if (cursor) {
        var value = cursor.value;

        if ((0, _utils.filterObject)(filters, value)) {
          results.push(value);
        }

        cursor.continue();
      } else {
        done(results);
      }
    };
  },
  in: function _in(values, filters, done) {
    var results = [];
    var i = 0;
    return function (event) {
      var cursor = event.target.result;

      if (!cursor) {
        done(results);
        return;
      }

      var key = cursor.key,
          value = cursor.value; // `key` can be an array of two values (see `keyPath` in indices definitions).
      // `values` can be an array of arrays if we filter using an index whose key path
      // is an array (eg. `cursorHandlers.in([["bid/cid", 42], ["bid/cid", 43]], ...)`)

      while (key > values[i]) {
        // The cursor has passed beyond this key. Check next.
        ++i;

        if (i === values.length) {
          done(results); // There is no next. Stop searching.

          return;
        }
      }

      var isEqual = Array.isArray(key) ? (0, _utils.arrayEqual)(key, values[i]) : key === values[i];

      if (isEqual) {
        if ((0, _utils.filterObject)(filters, value)) {
          results.push(value);
        }

        cursor.continue();
      } else {
        cursor.continue(values[i]);
      }
    };
  }
};
/**
 * Creates an IDB request and attach it the appropriate cursor event handler to
 * perform a list query.
 *
 * Multiple matching values are handled by passing an array.
 *
 * @param  {String}           cid        The collection id (ie. `{bid}/{cid}`)
 * @param  {IDBStore}         store      The IDB store.
 * @param  {Object}           filters    Filter the records by field.
 * @param  {Function}         done       The operation completion handler.
 * @return {IDBRequest}
 */

function createListRequest(cid, store, filters, done) {
  var filterFields = Object.keys(filters); // If no filters, get all results in one bulk.

  if (filterFields.length == 0) {
    var _request = store.index("cid").getAll(IDBKeyRange.only(cid));

    _request.onsuccess = function (event) {
      return done(event.target.result);
    };

    return _request;
  } // Introspect filters and check if they leverage an indexed field.


  var indexField = filterFields.find(function (field) {
    return INDEXED_FIELDS.includes(field);
  });

  if (!indexField) {
    // Iterate on all records for this collection (ie. cid)
    var isSubQuery = Object.keys(filters).some(function (key) {
      return key.includes(".");
    }); // (ie. filters: {"article.title": "hello"})

    if (isSubQuery) {
      var newFilter = (0, _utils.transformSubObjectFilters)(filters);

      var _request3 = store.index("cid").openCursor(IDBKeyRange.only(cid));

      _request3.onsuccess = cursorHandlers.all(newFilter, done);
      return _request3;
    }

    var _request2 = store.index("cid").openCursor(IDBKeyRange.only(cid));

    _request2.onsuccess = cursorHandlers.all(filters, done);
    return _request2;
  } // If `indexField` was used already, don't filter again.


  var remainingFilters = (0, _utils.omitKeys)(filters, [indexField]); // value specified in the filter (eg. `filters: { _status: ["created", "updated"] }`)

  var value = filters[indexField]; // For the "id" field, use the primary key.

  var indexStore = indexField == "id" ? store : store.index(indexField); // WHERE IN equivalent clause

  if (Array.isArray(value)) {
    if (value.length === 0) {
      return done([]);
    }

    var values = value.map(function (i) {
      return [cid, i];
    }).sort();
    var range = IDBKeyRange.bound(values[0], values[values.length - 1]);

    var _request4 = indexStore.openCursor(range);

    _request4.onsuccess = cursorHandlers.in(values, remainingFilters, done);
    return _request4;
  } // If no filters on custom attribute, get all results in one bulk.


  if (remainingFilters.length == 0) {
    var _request5 = indexStore.getAll(IDBKeyRange.only([cid, value]));

    _request5.onsuccess = function (event) {
      return done(event.target.result);
    };

    return _request5;
  } // WHERE field = value clause


  var request = indexStore.openCursor(IDBKeyRange.only([cid, value]));
  request.onsuccess = cursorHandlers.all(remainingFilters, done);
  return request;
}
/**
 * IndexedDB adapter.
 *
 * This adapter doesn't support any options.
 */


var IDB =
/*#__PURE__*/
function (_BaseAdapter) {
  (0, _inherits2.default)(IDB, _BaseAdapter);

  /**
   * Constructor.
   *
   * @param  {String} cid  The key base for this collection (eg. `bid/cid`)
   * @param  {Object} options
   * @param  {String} options.dbName         The IndexedDB name (default: `"KintoDB"`)
   * @param  {String} options.migrateOldData Whether old database data should be migrated (default: `false`)
   */
  function IDB(cid) {
    var _this;

    var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
    (0, _classCallCheck2.default)(this, IDB);
    _this = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(IDB).call(this));
    _this.cid = cid;
    _this.dbName = options.dbName || "KintoDB";
    _this._options = options;
    _this._db = null;
    return _this;
  }

  (0, _createClass2.default)(IDB, [{
    key: "_handleError",
    value: function _handleError(method, err) {
      var error = new Error("IndexedDB ".concat(method, "() ").concat(err.message));
      error.stack = err.stack;
      throw error;
    }
    /**
     * Ensures a connection to the IndexedDB database has been opened.
     *
     * @override
     * @return {Promise}
     */

  }, {
    key: "open",
    value: function () {
      var _open3 = (0, _asyncToGenerator2.default)(
      /*#__PURE__*/
      _regenerator.default.mark(function _callee() {
        var dataToMigrate, records, timestamp;
        return _regenerator.default.wrap(function _callee$(_context) {
          while (1) {
            switch (_context.prev = _context.next) {
              case 0:
                if (!this._db) {
                  _context.next = 2;
                  break;
                }

                return _context.abrupt("return", this);

              case 2:
                if (!this._options.migrateOldData) {
                  _context.next = 8;
                  break;
                }

                _context.next = 5;
                return migrationRequired(this.cid);

              case 5:
                _context.t0 = _context.sent;
                _context.next = 9;
                break;

              case 8:
                _context.t0 = null;

              case 9:
                dataToMigrate = _context.t0;
                _context.next = 12;
                return _open2(this.dbName, {
                  version: 2,
                  onupgradeneeded: function onupgradeneeded(event) {
                    var db = event.target.result;

                    if (event.oldVersion < 1) {
                      // Records store
                      var recordsStore = db.createObjectStore("records", {
                        keyPath: ["_cid", "id"]
                      }); // An index to obtain all the records in a collection.

                      recordsStore.createIndex("cid", "_cid"); // Here we create indices for every known field in records by collection.
                      // Local record status ("synced", "created", "updated", "deleted")

                      recordsStore.createIndex("_status", ["_cid", "_status"]); // Last modified field

                      recordsStore.createIndex("last_modified", ["_cid", "last_modified"]); // Timestamps store

                      db.createObjectStore("timestamps", {
                        keyPath: "cid"
                      });
                    }

                    if (event.oldVersion < 2) {
                      // Collections store
                      db.createObjectStore("collections", {
                        keyPath: "cid"
                      });
                    }
                  }
                });

              case 12:
                this._db = _context.sent;

                if (!dataToMigrate) {
                  _context.next = 23;
                  break;
                }

                records = dataToMigrate.records, timestamp = dataToMigrate.timestamp;
                _context.next = 17;
                return this.importBulk(records);

              case 17:
                _context.next = 19;
                return this.saveLastModified(timestamp);

              case 19:
                console.log("".concat(this.cid, ": data was migrated successfully.")); // Delete the old database.

                _context.next = 22;
                return deleteDatabase(this.cid);

              case 22:
                console.warn("".concat(this.cid, ": old database was deleted."));

              case 23:
                return _context.abrupt("return", this);

              case 24:
              case "end":
                return _context.stop();
            }
          }
        }, _callee, this);
      }));

      return function open() {
        return _open3.apply(this, arguments);
      };
    }()
    /**
     * Closes current connection to the database.
     *
     * @override
     * @return {Promise}
     */

  }, {
    key: "close",
    value: function close() {
      if (this._db) {
        this._db.close(); // indexedDB.close is synchronous


        this._db = null;
      }

      return Promise.resolve();
    }
    /**
     * Returns a transaction and an object store for a store name.
     *
     * To determine if a transaction has completed successfully, we should rather
     * listen to the transaction’s complete event rather than the IDBObjectStore
     * request’s success event, because the transaction may still fail after the
     * success event fires.
     *
     * @param  {String}      name  Store name
     * @param  {Function}    callback to execute
     * @param  {Object}      options Options
     * @param  {String}      options.mode  Transaction mode ("readwrite" or undefined)
     * @return {Object}
     */

  }, {
    key: "prepare",
    value: function () {
      var _prepare = (0, _asyncToGenerator2.default)(
      /*#__PURE__*/
      _regenerator.default.mark(function _callee2(name, callback, options) {
        return _regenerator.default.wrap(function _callee2$(_context2) {
          while (1) {
            switch (_context2.prev = _context2.next) {
              case 0:
                _context2.next = 2;
                return this.open();

              case 2:
                _context2.next = 4;
                return execute(this._db, name, callback, options);

              case 4:
              case "end":
                return _context2.stop();
            }
          }
        }, _callee2, this);
      }));

      return function prepare(_x7, _x8, _x9) {
        return _prepare.apply(this, arguments);
      };
    }()
    /**
     * Deletes every records in the current collection.
     *
     * @override
     * @return {Promise}
     */

  }, {
    key: "clear",
    value: function () {
      var _clear = (0, _asyncToGenerator2.default)(
      /*#__PURE__*/
      _regenerator.default.mark(function _callee3() {
        var _this2 = this;

        return _regenerator.default.wrap(function _callee3$(_context3) {
          while (1) {
            switch (_context3.prev = _context3.next) {
              case 0:
                _context3.prev = 0;
                _context3.next = 3;
                return this.prepare("records", function (store) {
                  var range = IDBKeyRange.only(_this2.cid);
                  var request = store.index("cid").openKeyCursor(range);

                  request.onsuccess = function (event) {
                    var cursor = event.target.result;

                    if (cursor) {
                      store.delete(cursor.primaryKey);
                      cursor.continue();
                    }
                  };

                  return request;
                }, {
                  mode: "readwrite"
                });

              case 3:
                _context3.next = 8;
                break;

              case 5:
                _context3.prev = 5;
                _context3.t0 = _context3["catch"](0);

                this._handleError("clear", _context3.t0);

              case 8:
              case "end":
                return _context3.stop();
            }
          }
        }, _callee3, this, [[0, 5]]);
      }));

      return function clear() {
        return _clear.apply(this, arguments);
      };
    }()
    /**
     * Executes the set of synchronous CRUD operations described in the provided
     * callback within an IndexedDB transaction, for current db store.
     *
     * The callback will be provided an object exposing the following synchronous
     * CRUD operation methods: get, create, update, delete.
     *
     * Important note: because limitations in IndexedDB implementations, no
     * asynchronous code should be performed within the provided callback; the
     * promise will therefore be rejected if the callback returns a Promise.
     *
     * Options:
     * - {Array} preload: The list of record IDs to fetch and make available to
     *   the transaction object get() method (default: [])
     *
     * @example
     * const db = new IDB("example");
     * const result = await db.execute(transaction => {
     *   transaction.create({id: 1, title: "foo"});
     *   transaction.update({id: 2, title: "bar"});
     *   transaction.delete(3);
     *   return "foo";
     * });
     *
     * @override
     * @param  {Function} callback The operation description callback.
     * @param  {Object}   options  The options object.
     * @return {Promise}
     */

  }, {
    key: "execute",
    value: function () {
      var _execute2 = (0, _asyncToGenerator2.default)(
      /*#__PURE__*/
      _regenerator.default.mark(function _callee4(callback) {
        var _this3 = this;

        var options,
            result,
            _args4 = arguments;
        return _regenerator.default.wrap(function _callee4$(_context4) {
          while (1) {
            switch (_context4.prev = _context4.next) {
              case 0:
                options = _args4.length > 1 && _args4[1] !== undefined ? _args4[1] : {
                  preload: []
                };
                _context4.next = 3;
                return this.prepare("records", function (store, abort) {
                  var runCallback = function runCallback() {
                    var preloaded = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
                    // Expose a consistent API for every adapter instead of raw store methods.
                    var proxy = transactionProxy(_this3, store, preloaded); // The callback is executed synchronously within the same transaction.

                    try {
                      var returned = callback(proxy);

                      if (returned instanceof Promise) {
                        // XXX: investigate how to provide documentation details in error.
                        throw new Error("execute() callback should not return a Promise.");
                      } // Bring to scope that will be returned (once promise awaited).


                      result = returned;
                    } catch (e) {
                      // The callback has thrown an error explicitly. Abort transaction cleanly.
                      abort(e);
                    }
                  }; // No option to preload records, go straight to `callback`.


                  if (!options.preload.length) {
                    return runCallback();
                  } // Preload specified records using a list request.


                  var filters = {
                    id: options.preload
                  };
                  createListRequest(_this3.cid, store, filters, function (records) {
                    // Store obtained records by id.
                    var preloaded = {};
                    var _iteratorNormalCompletion = true;
                    var _didIteratorError = false;
                    var _iteratorError = undefined;

                    try {
                      for (var _iterator = records[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
                        var record = _step.value;
                        delete record["_cid"];
                        preloaded[record.id] = record;
                      }
                    } catch (err) {
                      _didIteratorError = true;
                      _iteratorError = err;
                    } finally {
                      try {
                        if (!_iteratorNormalCompletion && _iterator.return != null) {
                          _iterator.return();
                        }
                      } finally {
                        if (_didIteratorError) {
                          throw _iteratorError;
                        }
                      }
                    }

                    runCallback(preloaded);
                  });
                }, {
                  mode: "readwrite"
                });

              case 3:
                return _context4.abrupt("return", result);

              case 4:
              case "end":
                return _context4.stop();
            }
          }
        }, _callee4, this);
      }));

      return function execute(_x10) {
        return _execute2.apply(this, arguments);
      };
    }()
    /**
     * Retrieve a record by its primary key from the IndexedDB database.
     *
     * @override
     * @param  {String} id The record id.
     * @return {Promise}
     */

  }, {
    key: "get",
    value: function () {
      var _get = (0, _asyncToGenerator2.default)(
      /*#__PURE__*/
      _regenerator.default.mark(function _callee5(id) {
        var _this4 = this;

        var record;
        return _regenerator.default.wrap(function _callee5$(_context5) {
          while (1) {
            switch (_context5.prev = _context5.next) {
              case 0:
                _context5.prev = 0;
                _context5.next = 3;
                return this.prepare("records", function (store) {
                  store.get([_this4.cid, id]).onsuccess = function (e) {
                    return record = e.target.result;
                  };
                });

              case 3:
                return _context5.abrupt("return", record);

              case 6:
                _context5.prev = 6;
                _context5.t0 = _context5["catch"](0);

                this._handleError("get", _context5.t0);

              case 9:
              case "end":
                return _context5.stop();
            }
          }
        }, _callee5, this, [[0, 6]]);
      }));

      return function get(_x11) {
        return _get.apply(this, arguments);
      };
    }()
    /**
     * Lists all records from the IndexedDB database.
     *
     * @override
     * @param  {Object} params  The filters and order to apply to the results.
     * @return {Promise}
     */

  }, {
    key: "list",
    value: function () {
      var _list = (0, _asyncToGenerator2.default)(
      /*#__PURE__*/
      _regenerator.default.mark(function _callee6() {
        var _this5 = this;

        var params,
            filters,
            results,
            _args6 = arguments;
        return _regenerator.default.wrap(function _callee6$(_context6) {
          while (1) {
            switch (_context6.prev = _context6.next) {
              case 0:
                params = _args6.length > 0 && _args6[0] !== undefined ? _args6[0] : {
                  filters: {}
                };
                filters = params.filters;
                _context6.prev = 2;
                results = [];
                _context6.next = 6;
                return this.prepare("records", function (store) {
                  createListRequest(_this5.cid, store, filters, function (_results) {
                    // we have received all requested records that match the filters,
                    // we now park them within current scope and hide the `_cid` attribute.
                    var _iteratorNormalCompletion2 = true;
                    var _didIteratorError2 = false;
                    var _iteratorError2 = undefined;

                    try {
                      for (var _iterator2 = _results[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
                        var result = _step2.value;
                        delete result["_cid"];
                      }
                    } catch (err) {
                      _didIteratorError2 = true;
                      _iteratorError2 = err;
                    } finally {
                      try {
                        if (!_iteratorNormalCompletion2 && _iterator2.return != null) {
                          _iterator2.return();
                        }
                      } finally {
                        if (_didIteratorError2) {
                          throw _iteratorError2;
                        }
                      }
                    }

                    results = _results;
                  });
                });

              case 6:
                return _context6.abrupt("return", params.order ? (0, _utils.sortObjects)(params.order, results) : results);

              case 9:
                _context6.prev = 9;
                _context6.t0 = _context6["catch"](2);

                this._handleError("list", _context6.t0);

              case 12:
              case "end":
                return _context6.stop();
            }
          }
        }, _callee6, this, [[2, 9]]);
      }));

      return function list() {
        return _list.apply(this, arguments);
      };
    }()
    /**
     * Store the lastModified value into metadata store.
     *
     * @override
     * @param  {Number}  lastModified
     * @return {Promise}
     */

  }, {
    key: "saveLastModified",
    value: function () {
      var _saveLastModified = (0, _asyncToGenerator2.default)(
      /*#__PURE__*/
      _regenerator.default.mark(function _callee7(lastModified) {
        var _this6 = this;

        var value;
        return _regenerator.default.wrap(function _callee7$(_context7) {
          while (1) {
            switch (_context7.prev = _context7.next) {
              case 0:
                value = parseInt(lastModified, 10) || null;
                _context7.prev = 1;
                _context7.next = 4;
                return this.prepare("timestamps", function (store) {
                  return store.put({
                    cid: _this6.cid,
                    value: value
                  });
                }, {
                  mode: "readwrite"
                });

              case 4:
                return _context7.abrupt("return", value);

              case 7:
                _context7.prev = 7;
                _context7.t0 = _context7["catch"](1);

                this._handleError("saveLastModified", _context7.t0);

              case 10:
              case "end":
                return _context7.stop();
            }
          }
        }, _callee7, this, [[1, 7]]);
      }));

      return function saveLastModified(_x12) {
        return _saveLastModified.apply(this, arguments);
      };
    }()
    /**
     * Retrieve saved lastModified value.
     *
     * @override
     * @return {Promise}
     */

  }, {
    key: "getLastModified",
    value: function () {
      var _getLastModified = (0, _asyncToGenerator2.default)(
      /*#__PURE__*/
      _regenerator.default.mark(function _callee8() {
        var _this7 = this;

        var entry;
        return _regenerator.default.wrap(function _callee8$(_context8) {
          while (1) {
            switch (_context8.prev = _context8.next) {
              case 0:
                _context8.prev = 0;
                entry = null;
                _context8.next = 4;
                return this.prepare("timestamps", function (store) {
                  store.get(_this7.cid).onsuccess = function (e) {
                    return entry = e.target.result;
                  };
                });

              case 4:
                return _context8.abrupt("return", entry ? entry.value : null);

              case 7:
                _context8.prev = 7;
                _context8.t0 = _context8["catch"](0);

                this._handleError("getLastModified", _context8.t0);

              case 10:
              case "end":
                return _context8.stop();
            }
          }
        }, _callee8, this, [[0, 7]]);
      }));

      return function getLastModified() {
        return _getLastModified.apply(this, arguments);
      };
    }()
    /**
     * Load a dump of records exported from a server.
     *
     * @deprecated Use {@link importBulk} instead.
     * @abstract
     * @param  {Array} records The records to load.
     * @return {Promise}
     */

  }, {
    key: "loadDump",
    value: function () {
      var _loadDump = (0, _asyncToGenerator2.default)(
      /*#__PURE__*/
      _regenerator.default.mark(function _callee9(records) {
        return _regenerator.default.wrap(function _callee9$(_context9) {
          while (1) {
            switch (_context9.prev = _context9.next) {
              case 0:
                return _context9.abrupt("return", this.importBulk(records));

              case 1:
              case "end":
                return _context9.stop();
            }
          }
        }, _callee9, this);
      }));

      return function loadDump(_x13) {
        return _loadDump.apply(this, arguments);
      };
    }()
    /**
     * Load records in bulk that were exported from a server.
     *
     * @abstract
     * @param  {Array} records The records to load.
     * @return {Promise}
     */

  }, {
    key: "importBulk",
    value: function () {
      var _importBulk = (0, _asyncToGenerator2.default)(
      /*#__PURE__*/
      _regenerator.default.mark(function _callee10(records) {
        var previousLastModified, lastModified;
        return _regenerator.default.wrap(function _callee10$(_context10) {
          while (1) {
            switch (_context10.prev = _context10.next) {
              case 0:
                _context10.prev = 0;
                _context10.next = 3;
                return this.execute(function (transaction) {
                  // Since the put operations are asynchronous, we chain
                  // them together. The last one will be waited for the
                  // `transaction.oncomplete` callback. (see #execute())
                  var i = 0;
                  putNext();

                  function putNext() {
                    if (i == records.length) {
                      return;
                    } // On error, `transaction.onerror` is called.


                    transaction.update(records[i]).onsuccess = putNext;
                    ++i;
                  }
                });

              case 3:
                _context10.next = 5;
                return this.getLastModified();

              case 5:
                previousLastModified = _context10.sent;
                lastModified = Math.max.apply(Math, (0, _toConsumableArray2.default)(records.map(function (record) {
                  return record.last_modified;
                })));

                if (!(lastModified > previousLastModified)) {
                  _context10.next = 10;
                  break;
                }

                _context10.next = 10;
                return this.saveLastModified(lastModified);

              case 10:
                return _context10.abrupt("return", records);

              case 13:
                _context10.prev = 13;
                _context10.t0 = _context10["catch"](0);

                this._handleError("importBulk", _context10.t0);

              case 16:
              case "end":
                return _context10.stop();
            }
          }
        }, _callee10, this, [[0, 13]]);
      }));

      return function importBulk(_x14) {
        return _importBulk.apply(this, arguments);
      };
    }()
  }, {
    key: "saveMetadata",
    value: function () {
      var _saveMetadata = (0, _asyncToGenerator2.default)(
      /*#__PURE__*/
      _regenerator.default.mark(function _callee11(metadata) {
        var _this8 = this;

        return _regenerator.default.wrap(function _callee11$(_context11) {
          while (1) {
            switch (_context11.prev = _context11.next) {
              case 0:
                _context11.prev = 0;
                _context11.next = 3;
                return this.prepare("collections", function (store) {
                  return store.put({
                    cid: _this8.cid,
                    metadata: metadata
                  });
                }, {
                  mode: "readwrite"
                });

              case 3:
                return _context11.abrupt("return", metadata);

              case 6:
                _context11.prev = 6;
                _context11.t0 = _context11["catch"](0);

                this._handleError("saveMetadata", _context11.t0);

              case 9:
              case "end":
                return _context11.stop();
            }
          }
        }, _callee11, this, [[0, 6]]);
      }));

      return function saveMetadata(_x15) {
        return _saveMetadata.apply(this, arguments);
      };
    }()
  }, {
    key: "getMetadata",
    value: function () {
      var _getMetadata = (0, _asyncToGenerator2.default)(
      /*#__PURE__*/
      _regenerator.default.mark(function _callee12() {
        var _this9 = this;

        var entry;
        return _regenerator.default.wrap(function _callee12$(_context12) {
          while (1) {
            switch (_context12.prev = _context12.next) {
              case 0:
                _context12.prev = 0;
                entry = null;
                _context12.next = 4;
                return this.prepare("collections", function (store) {
                  store.get(_this9.cid).onsuccess = function (e) {
                    return entry = e.target.result;
                  };
                });

              case 4:
                return _context12.abrupt("return", entry ? entry.metadata : null);

              case 7:
                _context12.prev = 7;
                _context12.t0 = _context12["catch"](0);

                this._handleError("getMetadata", _context12.t0);

              case 10:
              case "end":
                return _context12.stop();
            }
          }
        }, _callee12, this, [[0, 7]]);
      }));

      return function getMetadata() {
        return _getMetadata.apply(this, arguments);
      };
    }()
  }]);
  return IDB;
}(_base.default);
/**
 * IDB transaction proxy.
 *
 * @param  {IDB} adapter        The call IDB adapter
 * @param  {IDBStore} store     The IndexedDB database store.
 * @param  {Array}    preloaded The list of records to make available to
 *                              get() (default: []).
 * @return {Object}
 */


exports.default = IDB;

function transactionProxy(adapter, store) {
  var preloaded = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];
  var _cid = adapter.cid;
  return {
    create: function create(record) {
      store.add((0, _objectSpread2.default)({}, record, {
        _cid: _cid
      }));
    },
    update: function update(record) {
      return store.put((0, _objectSpread2.default)({}, record, {
        _cid: _cid
      }));
    },
    delete: function _delete(id) {
      store.delete([_cid, id]);
    },
    get: function get(id) {
      return preloaded[id];
    }
  };
}
/**
 * Up to version 10.X of kinto.js, each collection had its own collection.
 * The database name was `${bid}/${cid}` (eg. `"blocklists/certificates"`)
 * and contained only one store with the same name.
 */


function migrationRequired(_x16) {
  return _migrationRequired.apply(this, arguments);
}

function _migrationRequired() {
  _migrationRequired = (0, _asyncToGenerator2.default)(
  /*#__PURE__*/
  _regenerator.default.mark(function _callee16(dbName) {
    var exists, db, records, timestamp;
    return _regenerator.default.wrap(function _callee16$(_context16) {
      while (1) {
        switch (_context16.prev = _context16.next) {
          case 0:
            exists = true;
            _context16.next = 3;
            return _open2(dbName, {
              version: 1,
              onupgradeneeded: function onupgradeneeded(event) {
                exists = false;
              }
            });

          case 3:
            db = _context16.sent;
            // Check that the DB we're looking at is really a legacy one,
            // and not some remainder of the open() operation above.
            exists &= db.objectStoreNames.contains("__meta__") && db.objectStoreNames.contains(dbName);

            if (exists) {
              _context16.next = 10;
              break;
            }

            db.close(); // Testing the existence creates it, so delete it :)

            _context16.next = 9;
            return deleteDatabase(dbName);

          case 9:
            return _context16.abrupt("return", null);

          case 10:
            console.warn("".concat(dbName, ": old IndexedDB database found."));
            _context16.prev = 11;
            _context16.next = 14;
            return execute(db, dbName, function (store) {
              store.openCursor().onsuccess = cursorHandlers.all({}, function (res) {
                return records = res;
              });
            });

          case 14:
            console.log("".concat(dbName, ": found ").concat(records.length, " records.")); // Check if there's a entry for this.

            timestamp = null;
            _context16.next = 18;
            return execute(db, "__meta__", function (store) {
              store.get("".concat(dbName, "-lastModified")).onsuccess = function (e) {
                timestamp = e.target.result ? e.target.result.value : null;
              };
            });

          case 18:
            if (timestamp) {
              _context16.next = 21;
              break;
            }

            _context16.next = 21;
            return execute(db, "__meta__", function (store) {
              store.get("lastModified").onsuccess = function (e) {
                timestamp = e.target.result ? e.target.result.value : null;
              };
            });

          case 21:
            console.log("".concat(dbName, ": ").concat(timestamp ? "found" : "no", " timestamp.")); // Those will be inserted in the new database/schema.

            return _context16.abrupt("return", {
              records: records,
              timestamp: timestamp
            });

          case 25:
            _context16.prev = 25;
            _context16.t0 = _context16["catch"](11);
            console.error("Error occured during migration", _context16.t0);
            return _context16.abrupt("return", null);

          case 29:
            _context16.prev = 29;
            db.close();
            return _context16.finish(29);

          case 32:
          case "end":
            return _context16.stop();
        }
      }
    }, _callee16, this, [[11, 25, 29, 32]]);
  }));
  return _migrationRequired.apply(this, arguments);
}

},{"../utils":327,"./base.js":324,"@babel/runtime/helpers/asyncToGenerator":281,"@babel/runtime/helpers/classCallCheck":282,"@babel/runtime/helpers/createClass":284,"@babel/runtime/helpers/getPrototypeOf":286,"@babel/runtime/helpers/inherits":287,"@babel/runtime/helpers/interopRequireDefault":288,"@babel/runtime/helpers/objectSpread":295,"@babel/runtime/helpers/possibleConstructorReturn":296,"@babel/runtime/helpers/toConsumableArray":300,"@babel/runtime/regenerator":305}],324:[function(require,module,exports){
"use strict";
/**
 * Base db adapter.
 *
 * @abstract
 */

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;

var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));

var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));

var BaseAdapter =
/*#__PURE__*/
function () {
  function BaseAdapter() {
    (0, _classCallCheck2.default)(this, BaseAdapter);
  }

  (0, _createClass2.default)(BaseAdapter, [{
    key: "clear",

    /**
     * Deletes every records present in the database.
     *
     * @abstract
     * @return {Promise}
     */
    value: function clear() {
      throw new Error("Not Implemented.");
    }
    /**
     * Executes a batch of operations within a single transaction.
     *
     * @abstract
     * @param  {Function} callback The operation callback.
     * @param  {Object}   options  The options object.
     * @return {Promise}
     */

  }, {
    key: "execute",
    value: function execute(callback) {
      var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {
        preload: []
      };
      throw new Error("Not Implemented.");
    }
    /**
     * Retrieve a record by its primary key from the database.
     *
     * @abstract
     * @param  {String} id The record id.
     * @return {Promise}
     */

  }, {
    key: "get",
    value: function get(id) {
      throw new Error("Not Implemented.");
    }
    /**
     * Lists all records from the database.
     *
     * @abstract
     * @param  {Object} params  The filters and order to apply to the results.
     * @return {Promise}
     */

  }, {
    key: "list",
    value: function list() {
      var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {
        filters: {},
        order: ""
      };
      throw new Error("Not Implemented.");
    }
    /**
     * Store the lastModified value.
     *
     * @abstract
     * @param  {Number}  lastModified
     * @return {Promise}
     */

  }, {
    key: "saveLastModified",
    value: function saveLastModified(lastModified) {
      throw new Error("Not Implemented.");
    }
    /**
     * Retrieve saved lastModified value.
     *
     * @abstract
     * @return {Promise}
     */

  }, {
    key: "getLastModified",
    value: function getLastModified() {
      throw new Error("Not Implemented.");
    }
    /**
     * Load records in bulk that were exported from a server.
     *
     * @abstract
     * @param  {Array} records The records to load.
     * @return {Promise}
     */

  }, {
    key: "importBulk",
    value: function importBulk(records) {
      throw new Error("Not Implemented.");
    }
    /**
     * Load a dump of records exported from a server.
     *
     * @deprecated Use {@link importBulk} instead.
     * @abstract
     * @param  {Array} records The records to load.
     * @return {Promise}
     */

  }, {
    key: "loadDump",
    value: function loadDump(records) {
      throw new Error("Not Implemented.");
    }
  }, {
    key: "saveMetadata",
    value: function saveMetadata(metadata) {
      throw new Error("Not Implemented.");
    }
  }, {
    key: "getMetadata",
    value: function getMetadata() {
      throw new Error("Not Implemented.");
    }
  }]);
  return BaseAdapter;
}();

exports.default = BaseAdapter;

},{"@babel/runtime/helpers/classCallCheck":282,"@babel/runtime/helpers/createClass":284,"@babel/runtime/helpers/interopRequireDefault":288}],325:[function(require,module,exports){
"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.recordsEqual = recordsEqual;
exports.createKeyValueStoreIdSchema = createKeyValueStoreIdSchema;
exports.CollectionTransaction = exports.default = exports.ServerWasFlushedError = exports.SyncResultObject = void 0;

var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));

var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));

var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof"));

var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread"));

var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn"));

var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf"));

var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits"));

var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized"));

var _wrapNativeSuper2 = _interopRequireDefault(require("@babel/runtime/helpers/wrapNativeSuper"));

var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));

var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));

var _base = _interopRequireDefault(require("./adapters/base"));

var _IDB = _interopRequireDefault(require("./adapters/IDB"));

var _utils = require("./utils");

var _uuid = require("uuid");

var RECORD_FIELDS_TO_CLEAN = ["_status"];
var AVAILABLE_HOOKS = ["incoming-changes"];
var IMPORT_CHUNK_SIZE = 200;
/**
 * Compare two records omitting local fields and synchronization
 * attributes (like _status and last_modified)
 * @param {Object} a    A record to compare.
 * @param {Object} b    A record to compare.
 * @param {Array} localFields Additional fields to ignore during the comparison
 * @return {boolean}
 */

function recordsEqual(a, b) {
  var localFields = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];
  var fieldsToClean = RECORD_FIELDS_TO_CLEAN.concat(["last_modified"]).concat(localFields);

  var cleanLocal = function cleanLocal(r) {
    return (0, _utils.omitKeys)(r, fieldsToClean);
  };

  return (0, _utils.deepEqual)(cleanLocal(a), cleanLocal(b));
}
/**
 * Synchronization result object.
 */


var SyncResultObject =
/*#__PURE__*/
function () {
  /**
   * Public constructor.
   */
  function SyncResultObject() {
    var _this = this;

    (0, _classCallCheck2.default)(this, SyncResultObject);

    /**
     * Current synchronization result status; becomes `false` when conflicts or
     * errors are registered.
     * @type {Boolean}
     */
    this.lastModified = null;
    this._lists = {};
    ["errors", "created", "updated", "deleted", "published", "conflicts", "skipped", "resolved", "void"].forEach(function (l) {
      return _this._lists[l] = [];
    });
    this._cached = {};
  }
  /**
   * Adds entries for a given result type.
   *
   * @param {String} type    The result type.
   * @param {Array}  entries The result entries.
   * @return {SyncResultObject}
   */


  (0, _createClass2.default)(SyncResultObject, [{
    key: "add",
    value: function add(type, entries) {
      if (!Array.isArray(this._lists[type])) {
        console.warn("Unknown type \"".concat(type, "\""));
        return;
      }

      if (!Array.isArray(entries)) {
        entries = [entries];
      }

      this._lists[type] = this._lists[type].concat(entries);
      delete this._cached[type];
      return this;
    }
  }, {
    key: "_deduplicate",
    value: function _deduplicate(list) {
      if (!(list in this._cached)) {
        // Deduplicate entries by id. If the values don't have `id` attribute, just
        // keep all.
        var recordsWithoutId = new Set();
        var recordsById = new Map();

        this._lists[list].forEach(function (record) {
          if (!record.id) {
            recordsWithoutId.add(record);
          } else {
            recordsById.set(record.id, record);
          }
        });

        this._cached[list] = Array.from(recordsById.values()).concat(Array.from(recordsWithoutId));
      }

      return this._cached[list];
    }
    /**
     * Reinitializes result entries for a given result type.
     *
     * @param  {String} type The result type.
     * @return {SyncResultObject}
     */

  }, {
    key: "reset",
    value: function reset(type) {
      this._lists[type] = [];
      delete this._cached[type];
      return this;
    }
  }, {
    key: "toObject",
    value: function toObject() {
      // Only used in tests.
      return {
        ok: this.ok,
        lastModified: this.lastModified,
        errors: this.errors,
        created: this.created,
        updated: this.updated,
        deleted: this.deleted,
        skipped: this.skipped,
        published: this.published,
        conflicts: this.conflicts,
        resolved: this.resolved
      };
    }
  }, {
    key: "ok",
    get: function get() {
      return this.errors.length + this.conflicts.length === 0;
    }
  }, {
    key: "errors",
    get: function get() {
      return this._lists["errors"];
    }
  }, {
    key: "conflicts",
    get: function get() {
      return this._lists["conflicts"];
    }
  }, {
    key: "skipped",
    get: function get() {
      return this._deduplicate("skipped");
    }
  }, {
    key: "resolved",
    get: function get() {
      return this._deduplicate("resolved");
    }
  }, {
    key: "created",
    get: function get() {
      return this._deduplicate("created");
    }
  }, {
    key: "updated",
    get: function get() {
      return this._deduplicate("updated");
    }
  }, {
    key: "deleted",
    get: function get() {
      return this._deduplicate("deleted");
    }
  }, {
    key: "published",
    get: function get() {
      return this._deduplicate("published");
    }
  }]);
  return SyncResultObject;
}();

exports.SyncResultObject = SyncResultObject;

var ServerWasFlushedError =
/*#__PURE__*/
function (_Error) {
  (0, _inherits2.default)(ServerWasFlushedError, _Error);

  function ServerWasFlushedError(clientTimestamp, serverTimestamp, message) {
    var _this2;

    (0, _classCallCheck2.default)(this, ServerWasFlushedError);
    _this2 = (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(ServerWasFlushedError).call(this, message));

    if (Error.captureStackTrace) {
      Error.captureStackTrace((0, _assertThisInitialized2.default)((0, _assertThisInitialized2.default)(_this2)), ServerWasFlushedError);
    }

    _this2.clientTimestamp = clientTimestamp;
    _this2.serverTimestamp = serverTimestamp;
    return _this2;
  }

  return ServerWasFlushedError;
}((0, _wrapNativeSuper2.default)(Error));

exports.ServerWasFlushedError = ServerWasFlushedError;

function createUUIDSchema() {
  return {
    generate: function generate() {
      return (0, _uuid.v4)();
    },
    validate: function validate(id) {
      return typeof id == "string" && _utils.RE_RECORD_ID.test(id);
    }
  };
}
/**
 * IDSchema for when using kinto.js as a key-value store.
 * Using this IDSchema requires you to set a property as the id.
 * This will be the property used to retrieve this record.
 *
 * @example
 * const exampleCollection = db.collection("example", { idSchema: createKeyValueStoreIdSchema() })
 * await exampleCollection.create({ title: "How to tie a tie", favoriteColor: "blue", id: "user123" }, { useRecordId: true })
 * await exampleCollection.getAny("user123")
 */


function createKeyValueStoreIdSchema() {
  return {
    generate: function generate() {
      throw new Error("createKeyValueStoreIdSchema() does not generate an id");
    },
    validate: function validate() {
      return true;
    }
  };
}

function markStatus(record, status) {
  return (0, _objectSpread2.default)({}, record, {
    _status: status
  });
}

function markDeleted(record) {
  return markStatus(record, "deleted");
}

function markSynced(record) {
  return markStatus(record, "synced");
}
/**
 * Import a remote change into the local database.
 *
 * @param  {IDBTransactionProxy} transaction The transaction handler.
 * @param  {Object}              remote      The remote change object to import.
 * @param  {Array<String>}       localFields The list of fields that remain local.
 * @param  {String}              strategy    The {@link Collection.strategy}.
 * @return {Object}
 */


function importChange(transaction, remote, localFields, strategy) {
  var local = transaction.get(remote.id);

  if (!local) {
    // Not found locally but remote change is marked as deleted; skip to
    // avoid recreation.
    if (remote.deleted) {
      return {
        type: "skipped",
        data: remote
      };
    }

    var _synced = markSynced(remote);

    transaction.create(_synced);
    return {
      type: "created",
      data: _synced
    };
  } // Apply remote changes on local record.


  var synced = (0, _objectSpread2.default)({}, local, markSynced(remote)); // With pull only, we don't need to compare records since we override them.

  if (strategy === Collection.strategy.PULL_ONLY) {
    if (remote.deleted) {
      transaction.delete(remote.id);
      return {
        type: "deleted",
        data: local
      };
    }

    transaction.update(synced);
    return {
      type: "updated",
      data: {
        old: local,
        new: synced
      }
    };
  } // With other sync strategies, we detect conflicts,
  // by comparing local and remote, ignoring local fields.


  var isIdentical = recordsEqual(local, remote, localFields); // Detect or ignore conflicts if record has also been modified locally.

  if (local._status !== "synced") {
    // Locally deleted, unsynced: scheduled for remote deletion.
    if (local._status === "deleted") {
      return {
        type: "skipped",
        data: local
      };
    }

    if (isIdentical) {
      // If records are identical, import anyway, so we bump the
      // local last_modified value from the server and set record
      // status to "synced".
      transaction.update(synced);
      return {
        type: "updated",
        data: {
          old: local,
          new: synced
        }
      };
    }

    if (local.last_modified !== undefined && local.last_modified === remote.last_modified) {
      // If our local version has the same last_modified as the remote
      // one, this represents an object that corresponds to a resolved
      // conflict. Our local version represents the final output, so
      // we keep that one. (No transaction operation to do.)
      // But if our last_modified is undefined,
      // that means we've created the same object locally as one on
      // the server, which *must* be a conflict.
      return {
        type: "void"
      };
    }

    return {
      type: "conflicts",
      data: {
        type: "incoming",
        local: local,
        remote: remote
      }
    };
  } // Local record was synced.


  if (remote.deleted) {
    transaction.delete(remote.id);
    return {
      type: "deleted",
      data: local
    };
  } // Import locally.


  transaction.update(synced); // if identical, simply exclude it from all SyncResultObject lists

  var type = isIdentical ? "void" : "updated";
  return {
    type: type,
    data: {
      old: local,
      new: synced
    }
  };
}
/**
 * Abstracts a collection of records stored in the local database, providing
 * CRUD operations and synchronization helpers.
 */


var Collection =
/*#__PURE__*/
function () {
  /**
   * Constructor.
   *
   * Options:
   * - `{BaseAdapter} adapter` The DB adapter (default: `IDB`)
   *
   * @param  {String} bucket  The bucket identifier.
   * @param  {String} name    The collection name.
   * @param  {Api}    api     The Api instance.
   * @param  {Object} options The options object.
   */
  function Collection(bucket, name, api) {
    var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
    (0, _classCallCheck2.default)(this, Collection);
    this._bucket = bucket;
    this._name = name;
    this._lastModified = null;
    var DBAdapter = options.adapter || _IDB.default;

    if (!DBAdapter) {
      throw new Error("No adapter provided");
    }

    var db = new DBAdapter("".concat(bucket, "/").concat(name), options.adapterOptions);

    if (!(db instanceof _base.default)) {
      throw new Error("Unsupported adapter.");
    } // public properties

    /**
     * The db adapter instance
     * @type {BaseAdapter}
     */


    this.db = db;
    /**
     * The Api instance.
     * @type {KintoClient}
     */

    this.api = api;
    /**
     * The event emitter instance.
     * @type {EventEmitter}
     */

    this.events = options.events;
    /**
     * The IdSchema instance.
     * @type {Object}
     */

    this.idSchema = this._validateIdSchema(options.idSchema);
    /**
     * The list of remote transformers.
     * @type {Array}
     */

    this.remoteTransformers = this._validateRemoteTransformers(options.remoteTransformers);
    /**
     * The list of hooks.
     * @type {Object}
     */

    this.hooks = this._validateHooks(options.hooks);
    /**
     * The list of fields names that will remain local.
     * @type {Array}
     */

    this.localFields = options.localFields || [];
  }
  /**
   * The collection name.
   * @type {String}
   */


  (0, _createClass2.default)(Collection, [{
    key: "_validateIdSchema",

    /**
     * Validates an idSchema.
     *
     * @param  {Object|undefined} idSchema
     * @return {Object}
     */
    value: function _validateIdSchema(idSchema) {
      if (typeof idSchema === "undefined") {
        return createUUIDSchema();
      }

      if ((0, _typeof2.default)(idSchema) !== "object") {
        throw new Error("idSchema must be an object.");
      } else if (typeof idSchema.generate !== "function") {
        throw new Error("idSchema must provide a generate function.");
      } else if (typeof idSchema.validate !== "function") {
        throw new Error("idSchema must provide a validate function.");
      }

      return idSchema;
    }
    /**
     * Validates a list of remote transformers.
     *
     * @param  {Array|undefined} remoteTransformers
     * @return {Array}
     */

  }, {
    key: "_validateRemoteTransformers",
    value: function _validateRemoteTransformers(remoteTransformers) {
      if (typeof remoteTransformers === "undefined") {
        return [];
      }

      if (!Array.isArray(remoteTransformers)) {
        throw new Error("remoteTransformers should be an array.");
      }

      return remoteTransformers.map(function (transformer) {
        if ((0, _typeof2.default)(transformer) !== "object") {
          throw new Error("A transformer must be an object.");
        } else if (typeof transformer.encode !== "function") {
          throw new Error("A transformer must provide an encode function.");
        } else if (typeof transformer.decode !== "function") {
          throw new Error("A transformer must provide a decode function.");
        }

        return transformer;
      });
    }
    /**
     * Validate the passed hook is correct.
     *
     * @param {Array|undefined} hook.
     * @return {Array}
     **/

  }, {
    key: "_validateHook",
    value: function _validateHook(hook) {
      if (!Array.isArray(hook)) {
        throw new Error("A hook definition should be an array of functions.");
      }

      return hook.map(function (fn) {
        if (typeof fn !== "function") {
          throw new Error("A hook definition should be an array of functions.");
        }

        return fn;
      });
    }
    /**
     * Validates a list of hooks.
     *
     * @param  {Object|undefined} hooks
     * @return {Object}
     */

  }, {
    key: "_validateHooks",
    value: function _validateHooks(hooks) {
      if (typeof hooks === "undefined") {
        return {};
      }

      if (Array.isArray(hooks)) {
        throw new Error("hooks should be an object, not an array.");
      }

      if ((0, _typeof2.default)(hooks) !== "object") {
        throw new Error("hooks should be an object.");
      }

      var validatedHooks = {};

      for (var hook in hooks) {
        if (!AVAILABLE_HOOKS.includes(hook)) {
          throw new Error("The hook should be one of " + AVAILABLE_HOOKS.join(", "));
        }

        validatedHooks[hook] = this._validateHook(hooks[hook]);
      }

      return validatedHooks;
    }
    /**
     * Deletes every records in the current collection and marks the collection as
     * never synced.
     *
     * @return {Promise}
     */

  }, {
    key: "clear",
    value: function () {
      var _clear = (0, _asyncToGenerator2.default)(
      /*#__PURE__*/
      _regenerator.default.mark(function _callee() {
        return _regenerator.default.wrap(function _callee$(_context) {
          while (1) {
            switch (_context.prev = _context.next) {
              case 0:
                _context.next = 2;
                return this.db.clear();

              case 2:
                _context.next = 4;
                return this.db.saveMetadata(null);

              case 4:
                _context.next = 6;
                return this.db.saveLastModified(null);

              case 6:
                return _context.abrupt("return", {
                  data: [],
                  permissions: {}
                });

              case 7:
              case "end":
                return _context.stop();
            }
          }
        }, _callee, this);
      }));

      return function clear() {
        return _clear.apply(this, arguments);
      };
    }()
    /**
     * Encodes a record.
     *
     * @param  {String} type   Either "remote" or "local".
     * @param  {Object} record The record object to encode.
     * @return {Promise}
     */

  }, {
    key: "_encodeRecord",
    value: function _encodeRecord(type, record) {
      if (!this["".concat(type, "Transformers")].length) {
        return Promise.resolve(record);
      }

      return (0, _utils.waterfall)(this["".concat(type, "Transformers")].map(function (transformer) {
        return function (record) {
          return transformer.encode(record);
        };
      }), record);
    }
    /**
     * Decodes a record.
     *
     * @param  {String} type   Either "remote" or "local".
     * @param  {Object} record The record object to decode.
     * @return {Promise}
     */

  }, {
    key: "_decodeRecord",
    value: function _decodeRecord(type, record) {
      if (!this["".concat(type, "Transformers")].length) {
        return Promise.resolve(record);
      }

      return (0, _utils.waterfall)(this["".concat(type, "Transformers")].reverse().map(function (transformer) {
        return function (record) {
          return transformer.decode(record);
        };
      }), record);
    }
    /**
     * Adds a record to the local database, asserting that none
     * already exist with this ID.
     *
     * Note: If either the `useRecordId` or `synced` options are true, then the
     * record object must contain the id field to be validated. If none of these
     * options are true, an id is generated using the current IdSchema; in this
     * case, the record passed must not have an id.
     *
     * Options:
     * - {Boolean} synced       Sets record status to "synced" (default: `false`).
     * - {Boolean} useRecordId  Forces the `id` field from the record to be used,
     *                          instead of one that is generated automatically
     *                          (default: `false`).
     *
     * @param  {Object} record
     * @param  {Object} options
     * @return {Promise}
     */

  }, {
    key: "create",
    value: function create(record) {
      var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {
        useRecordId: false,
        synced: false
      };

      // Validate the record and its ID (if any), even though this
      // validation is also done in the CollectionTransaction method,
      // because we need to pass the ID to preloadIds.
      var reject = function reject(msg) {
        return Promise.reject(new Error(msg));
      };

      if ((0, _typeof2.default)(record) !== "object") {
        return reject("Record is not an object.");
      }

      if ((options.synced || options.useRecordId) && !Object.prototype.hasOwnProperty.call(record, "id")) {
        return reject("Missing required Id; synced and useRecordId options require one");
      }

      if (!options.synced && !options.useRecordId && Object.prototype.hasOwnProperty.call(record, "id")) {
        return reject("Extraneous Id; can't create a record having one set.");
      }

      var newRecord = (0, _objectSpread2.default)({}, record, {
        id: options.synced || options.useRecordId ? record.id : this.idSchema.generate(record),
        _status: options.synced ? "synced" : "created"
      });

      if (!this.idSchema.validate(newRecord.id)) {
        return reject("Invalid Id: ".concat(newRecord.id));
      }

      return this.execute(function (txn) {
        return txn.create(newRecord);
      }, {
        preloadIds: [newRecord.id]
      }).catch(function (err) {
        if (options.useRecordId) {
          throw new Error("Couldn't create record. It may have been virtually deleted.");
        }

        throw err;
      });
    }
    /**
     * Like {@link CollectionTransaction#update}, but wrapped in its own transaction.
     *
     * Options:
     * - {Boolean} synced: Sets record status to "synced" (default: false)
     * - {Boolean} patch:  Extends the existing record instead of overwriting it
     *   (default: false)
     *
     * @param  {Object} record
     * @param  {Object} options
     * @return {Promise}
     */

  }, {
    key: "update",
    value: function update(record) {
      var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {
        synced: false,
        patch: false
      };

      // Validate the record and its ID, even though this validation is
      // also done in the CollectionTransaction method, because we need
      // to pass the ID to preloadIds.
      if ((0, _typeof2.default)(record) !== "object") {
        return Promise.reject(new Error("Record is not an object."));
      }

      if (!Object.prototype.hasOwnProperty.call(record, "id")) {
        return Promise.reject(new Error("Cannot update a record missing id."));
      }

      if (!this.idSchema.validate(record.id)) {
        return Promise.reject(new Error("Invalid Id: ".concat(record.id)));
      }

      return this.execute(function (txn) {
        return txn.update(record, options);
      }, {
        preloadIds: [record.id]
      });
    }
    /**
     * Like {@link CollectionTransaction#upsert}, but wrapped in its own transaction.
     *
     * @param  {Object} record
     * @return {Promise}
     */

  }, {
    key: "upsert",
    value: function upsert(record) {
      // Validate the record and its ID, even though this validation is
      // also done in the CollectionTransaction method, because we need
      // to pass the ID to preloadIds.
      if ((0, _typeof2.default)(record) !== "object") {
        return Promise.reject(new Error("Record is not an object."));
      }

      if (!Object.prototype.hasOwnProperty.call(record, "id")) {
        return Promise.reject(new Error("Cannot update a record missing id."));
      }

      if (!this.idSchema.validate(record.id)) {
        return Promise.reject(new Error("Invalid Id: ".concat(record.id)));
      }

      return this.execute(function (txn) {
        return txn.upsert(record);
      }, {
        preloadIds: [record.id]
      });
    }
    /**
     * Like {@link CollectionTransaction#get}, but wrapped in its own transaction.
     *
     * Options:
     * - {Boolean} includeDeleted: Include virtually deleted records.
     *
     * @param  {String} id
     * @param  {Object} options
     * @return {Promise}
     */

  }, {
    key: "get",
    value: function get(id) {
      var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {
        includeDeleted: false
      };
      return this.execute(function (txn) {
        return txn.get(id, options);
      }, {
        preloadIds: [id]
      });
    }
    /**
     * Like {@link CollectionTransaction#getAny}, but wrapped in its own transaction.
     *
     * @param  {String} id
     * @return {Promise}
     */

  }, {
    key: "getAny",
    value: function getAny(id) {
      return this.execute(function (txn) {
        return txn.getAny(id);
      }, {
        preloadIds: [id]
      });
    }
    /**
     * Same as {@link Collection#delete}, but wrapped in its own transaction.
     *
     * Options:
     * - {Boolean} virtual: When set to `true`, doesn't actually delete the record,
     *   update its `_status` attribute to `deleted` instead (default: true)
     *
     * @param  {String} id       The record's Id.
     * @param  {Object} options  The options object.
     * @return {Promise}
     */

  }, {
    key: "delete",
    value: function _delete(id) {
      var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {
        virtual: true
      };
      return this.execute(function (transaction) {
        return transaction.delete(id, options);
      }, {
        preloadIds: [id]
      });
    }
    /**
     * Same as {@link Collection#deleteAll}, but wrapped in its own transaction, execulding the parameter.
     *
     * @return {Promise}
     */

  }, {
    key: "deleteAll",
    value: function () {
      var _deleteAll = (0, _asyncToGenerator2.default)(
      /*#__PURE__*/
      _regenerator.default.mark(function _callee2() {
        var _ref, data, recordIds;

        return _regenerator.default.wrap(function _callee2$(_context2) {
          while (1) {
            switch (_context2.prev = _context2.next) {
              case 0:
                _context2.next = 2;
                return this.list({}, {
                  includeDeleted: false
                });

              case 2:
                _ref = _context2.sent;
                data = _ref.data;
                recordIds = data.map(function (record) {
                  return record.id;
                });
                return _context2.abrupt("return", this.execute(function (transaction) {
                  return transaction.deleteAll(recordIds);
                }, {
                  preloadIds: recordIds
                }));

              case 6:
              case "end":
                return _context2.stop();
            }
          }
        }, _callee2, this);
      }));

      return function deleteAll() {
        return _deleteAll.apply(this, arguments);
      };
    }()
    /**
     * The same as {@link CollectionTransaction#deleteAny}, but wrapped
     * in its own transaction.
     *
     * @param  {String} id       The record's Id.
     * @return {Promise}
     */

  }, {
    key: "deleteAny",
    value: function deleteAny(id) {
      return this.execute(function (txn) {
        return txn.deleteAny(id);
      }, {
        preloadIds: [id]
      });
    }
    /**
     * Lists records from the local database.
     *
     * Params:
     * - {Object} filters Filter the results (default: `{}`).
     * - {String} order   The order to apply   (default: `-last_modified`).
     *
     * Options:
     * - {Boolean} includeDeleted: Include virtually deleted records.
     *
     * @param  {Object} params  The filters and order to apply to the results.
     * @param  {Object} options The options object.
     * @return {Promise}
     */

  }, {
    key: "list",
    value: function () {
      var _list = (0, _asyncToGenerator2.default)(
      /*#__PURE__*/
      _regenerator.default.mark(function _callee3() {
        var params,
            options,
            results,
            data,
            _args3 = arguments;
        return _regenerator.default.wrap(function _callee3$(_context3) {
          while (1) {
            switch (_context3.prev = _context3.next) {
              case 0:
                params = _args3.length > 0 && _args3[0] !== undefined ? _args3[0] : {};
                options = _args3.length > 1 && _args3[1] !== undefined ? _args3[1] : {
                  includeDeleted: false
                };
                params = (0, _objectSpread2.default)({
                  order: "-last_modified",
                  filters: {}
                }, params);
                _context3.next = 5;
                return this.db.list(params);

              case 5:
                results = _context3.sent;
                data = results;

                if (!options.includeDeleted) {
                  data = results.filter(function (record) {
                    return record._status !== "deleted";
                  });
                }

                return _context3.abrupt("return", {
                  data: data,
                  permissions: {}
                });

              case 9:
              case "end":
                return _context3.stop();
            }
          }
        }, _callee3, this);
      }));

      return function list() {
        return _list.apply(this, arguments);
      };
    }()
    /**
     * Imports remote changes into the local database.
     * This method is in charge of detecting the conflicts, and resolve them
     * according to the specified strategy.
     * @param  {SyncResultObject} syncResultObject The sync result object.
     * @param  {Array}            decodedChanges   The list of changes to import in the local database.
     * @param  {String}           strategy         The {@link Collection.strategy} (default: MANUAL)
     * @return {Promise}
     */

  }, {
    key: "importChanges",
    value: function () {
      var _importChanges = (0, _asyncToGenerator2.default)(
      /*#__PURE__*/
      _regenerator.default.mark(function _callee4(syncResultObject, decodedChanges) {
        var _this3 = this;

        var strategy,
            _loop,
            i,
            data,
            _args5 = arguments;

        return _regenerator.default.wrap(function _callee4$(_context5) {
          while (1) {
            switch (_context5.prev = _context5.next) {
              case 0:
                strategy = _args5.length > 2 && _args5[2] !== undefined ? _args5[2] : Collection.strategy.MANUAL;
                _context5.prev = 1;
                _loop =
                /*#__PURE__*/
                _regenerator.default.mark(function _loop(i) {
                  var slice, _ref2, imports, resolved;

                  return _regenerator.default.wrap(function _loop$(_context4) {
                    while (1) {
                      switch (_context4.prev = _context4.next) {
                        case 0:
                          slice = decodedChanges.slice(i, i + IMPORT_CHUNK_SIZE);
                          _context4.next = 3;
                          return _this3.db.execute(function (transaction) {
                            var imports = slice.map(function (remote) {
                              // Store remote change into local database.
                              return importChange(transaction, remote, _this3.localFields, strategy);
                            });
                            var conflicts = imports.filter(function (i) {
                              return i.type === "conflicts";
                            }).map(function (i) {
                              return i.data;
                            });

                            var resolved = _this3._handleConflicts(transaction, conflicts, strategy);

                            return {
                              imports: imports,
                              resolved: resolved
                            };
                          }, {
                            preload: slice.map(function (record) {
                              return record.id;
                            })
                          });

                        case 3:
                          _ref2 = _context4.sent;
                          imports = _ref2.imports;
                          resolved = _ref2.resolved;
                          // Lists of created/updated/deleted records
                          imports.forEach(function (_ref3) {
                            var type = _ref3.type,
                                data = _ref3.data;
                            return syncResultObject.add(type, data);
                          }); // Automatically resolved conflicts (if not manual)

                          if (resolved.length > 0) {
                            syncResultObject.reset("conflicts").add("resolved", resolved);
                          }

                        case 8:
                        case "end":
                          return _context4.stop();
                      }
                    }
                  }, _loop, this);
                });
                i = 0;

              case 4:
                if (!(i < decodedChanges.length)) {
                  _context5.next = 9;
                  break;
                }

                return _context5.delegateYield(_loop(i), "t0", 6);

              case 6:
                i += IMPORT_CHUNK_SIZE;
                _context5.next = 4;
                break;

              case 9:
                _context5.next = 15;
                break;

              case 11:
                _context5.prev = 11;
                _context5.t1 = _context5["catch"](1);
                data = {
                  type: "incoming",
                  message: _context5.t1.message,
                  stack: _context5.t1.stack
                }; // XXX one error of the whole transaction instead of per atomic op

                syncResultObject.add("errors", data);

              case 15:
                return _context5.abrupt("return", syncResultObject);

              case 16:
              case "end":
                return _context5.stop();
            }
          }
        }, _callee4, this, [[1, 11]]);
      }));

      return function importChanges(_x, _x2) {
        return _importChanges.apply(this, arguments);
      };
    }()
    /**
     * Imports the responses of pushed changes into the local database.
     * Basically it stores the timestamp assigned by the server into the local
     * database.
     * @param  {SyncResultObject} syncResultObject The sync result object.
     * @param  {Array}            toApplyLocally   The list of changes to import in the local database.
     * @param  {Array}            conflicts        The list of conflicts that have to be resolved.
     * @param  {String}           strategy         The {@link Collection.strategy}.
     * @return {Promise}
     */

  }, {
    key: "_applyPushedResults",
    value: function () {
      var _applyPushedResults2 = (0, _asyncToGenerator2.default)(
      /*#__PURE__*/
      _regenerator.default.mark(function _callee5(syncResultObject, toApplyLocally, conflicts) {
        var _this4 = this;

        var strategy,
            toDeleteLocally,
            toUpdateLocally,
            _ref4,
            published,
            resolved,
            _args6 = arguments;

        return _regenerator.default.wrap(function _callee5$(_context6) {
          while (1) {
            switch (_context6.prev = _context6.next) {
              case 0:
                strategy = _args6.length > 3 && _args6[3] !== undefined ? _args6[3] : Collection.strategy.MANUAL;
                toDeleteLocally = toApplyLocally.filter(function (r) {
                  return r.deleted;
                });
                toUpdateLocally = toApplyLocally.filter(function (r) {
                  return !r.deleted;
                });
                _context6.next = 5;
                return this.db.execute(function (transaction) {
                  var updated = toUpdateLocally.map(function (record) {
                    var synced = markSynced(record);
                    transaction.update(synced);
                    return synced;
                  });
                  var deleted = toDeleteLocally.map(function (record) {
                    transaction.delete(record.id); // Amend result data with the deleted attribute set

                    return {
                      id: record.id,
                      deleted: true
                    };
                  });
                  var published = updated.concat(deleted); // Handle conflicts, if any

                  var resolved = _this4._handleConflicts(transaction, conflicts, strategy);

                  return {
                    published: published,
                    resolved: resolved
                  };
                });

              case 5:
                _ref4 = _context6.sent;
                published = _ref4.published;
                resolved = _ref4.resolved;
                syncResultObject.add("published", published);

                if (resolved.length > 0) {
                  syncResultObject.reset("conflicts").reset("resolved").add("resolved", resolved);
                }

                return _context6.abrupt("return", syncResultObject);

              case 11:
              case "end":
                return _context6.stop();
            }
          }
        }, _callee5, this);
      }));

      return function _applyPushedResults(_x3, _x4, _x5) {
        return _applyPushedResults2.apply(this, arguments);
      };
    }()
    /**
     * Handles synchronization conflicts according to specified strategy.
     *
     * @param  {SyncResultObject} result    The sync result object.
     * @param  {String}           strategy  The {@link Collection.strategy}.
     * @return {Promise<Array<Object>>} The resolved conflicts, as an
     *    array of {accepted, rejected} objects
     */

  }, {
    key: "_handleConflicts",
    value: function _handleConflicts(transaction, conflicts, strategy) {
      var _this5 = this;

      if (strategy === Collection.strategy.MANUAL) {
        return [];
      }

      return conflicts.map(function (conflict) {
        var resolution = strategy === Collection.strategy.CLIENT_WINS ? conflict.local : conflict.remote;
        var rejected = strategy === Collection.strategy.CLIENT_WINS ? conflict.remote : conflict.local;
        var accepted, status, id;

        if (resolution === null) {
          // We "resolved" with the server-side deletion. Delete locally.
          // This only happens during SERVER_WINS because the local
          // version of a record can never be null.
          // We can get "null" from the remote side if we got a conflict
          // and there is no remote version available; see kinto-http.js
          // batch.js:aggregate.
          transaction.delete(conflict.local.id);
          accepted = null; // The record was deleted, but that status is "synced" with
          // the server, so we don't need to push the change.

          status = "synced";
          id = conflict.local.id;
        } else {
          var updated = _this5._resolveRaw(conflict, resolution);

          transaction.update(updated);
          accepted = updated;
          status = updated._status;
          id = updated.id;
        }

        return {
          rejected: rejected,
          accepted: accepted,
          id: id,
          _status: status
        };
      });
    }
    /**
     * Execute a bunch of operations in a transaction.
     *
     * This transaction should be atomic -- either all of its operations
     * will succeed, or none will.
     *
     * The argument to this function is itself a function which will be
     * called with a {@link CollectionTransaction}. Collection methods
     * are available on this transaction, but instead of returning
     * promises, they are synchronous. execute() returns a Promise whose
     * value will be the return value of the provided function.
     *
     * Most operations will require access to the record itself, which
     * must be preloaded by passing its ID in the preloadIds option.
     *
     * Options:
     * - {Array} preloadIds: list of IDs to fetch at the beginning of
     *   the transaction
     *
     * @return {Promise} Resolves with the result of the given function
     *    when the transaction commits.
     */

  }, {
    key: "execute",
    value: function execute(doOperations) {
      var _this6 = this;

      var _ref5 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
          _ref5$preloadIds = _ref5.preloadIds,
          preloadIds = _ref5$preloadIds === void 0 ? [] : _ref5$preloadIds;

      var _iteratorNormalCompletion = true;
      var _didIteratorError = false;
      var _iteratorError = undefined;

      try {
        for (var _iterator = preloadIds[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
          var id = _step.value;

          if (!this.idSchema.validate(id)) {
            return Promise.reject(Error("Invalid Id: ".concat(id)));
          }
        }
      } catch (err) {
        _didIteratorError = true;
        _iteratorError = err;
      } finally {
        try {
          if (!_iteratorNormalCompletion && _iterator.return != null) {
            _iterator.return();
          }
        } finally {
          if (_didIteratorError) {
            throw _iteratorError;
          }
        }
      }

      return this.db.execute(function (transaction) {
        var txn = new CollectionTransaction(_this6, transaction);
        var result = doOperations(txn);
        txn.emitEvents();
        return result;
      }, {
        preload: preloadIds
      });
    }
    /**
     * Resets the local records as if they were never synced; existing records are
     * marked as newly created, deleted records are dropped.
     *
     * A next call to {@link Collection.sync} will thus republish the whole
     * content of the local collection to the server.
     *
     * @return {Promise} Resolves with the number of processed records.
     */

  }, {
    key: "resetSyncStatus",
    value: function () {
      var _resetSyncStatus = (0, _asyncToGenerator2.default)(
      /*#__PURE__*/
      _regenerator.default.mark(function _callee6() {
        var unsynced;
        return _regenerator.default.wrap(function _callee6$(_context7) {
          while (1) {
            switch (_context7.prev = _context7.next) {
              case 0:
                _context7.next = 2;
                return this.list({
                  filters: {
                    _status: ["deleted", "synced"]
                  },
                  order: ""
                }, {
                  includeDeleted: true
                });

              case 2:
                unsynced = _context7.sent;
                _context7.next = 5;
                return this.db.execute(function (transaction) {
                  unsynced.data.forEach(function (record) {
                    if (record._status === "deleted") {
                      // Garbage collect deleted records.
                      transaction.delete(record.id);
                    } else {
                      // Records that were synced become «created».
                      transaction.update((0, _objectSpread2.default)({}, record, {
                        last_modified: undefined,
                        _status: "created"
                      }));
                    }
                  });
                });

              case 5:
                this._lastModified = null;
                _context7.next = 8;
                return this.db.saveLastModified(null);

              case 8:
                return _context7.abrupt("return", unsynced.data.length);

              case 9:
              case "end":
                return _context7.stop();
            }
          }
        }, _callee6, this);
      }));

      return function resetSyncStatus() {
        return _resetSyncStatus.apply(this, arguments);
      };
    }()
    /**
     * Returns an object containing two lists:
     *
     * - `toDelete`: unsynced deleted records we can safely delete;
     * - `toSync`: local updates to send to the server.
     *
     * @return {Promise}
     */

  }, {
    key: "gatherLocalChanges",
    value: function () {
      var _gatherLocalChanges = (0, _asyncToGenerator2.default)(
      /*#__PURE__*/
      _regenerator.default.mark(function _callee7() {
        var unsynced, deleted;
        return _regenerator.default.wrap(function _callee7$(_context8) {
          while (1) {
            switch (_context8.prev = _context8.next) {
              case 0:
                _context8.next = 2;
                return this.list({
                  filters: {
                    _status: ["created", "updated"]
                  },
                  order: ""
                });

              case 2:
                unsynced = _context8.sent;
                _context8.next = 5;
                return this.list({
                  filters: {
                    _status: "deleted"
                  },
                  order: ""
                }, {
                  includeDeleted: true
                });

              case 5:
                deleted = _context8.sent;
                _context8.next = 8;
                return Promise.all(unsynced.data.concat(deleted.data).map(this._encodeRecord.bind(this, "remote")));

              case 8:
                return _context8.abrupt("return", _context8.sent);

              case 9:
              case "end":
                return _context8.stop();
            }
          }
        }, _callee7, this);
      }));

      return function gatherLocalChanges() {
        return _gatherLocalChanges.apply(this, arguments);
      };
    }()
    /**
     * Fetch remote changes, import them to the local database, and handle
     * conflicts according to `options.strategy`. Then, updates the passed
     * {@link SyncResultObject} with import results.
     *
     * Options:
     * - {String} strategy: The selected sync strategy.
     * - {String} expectedTimestamp: A timestamp to use as a "cache busting" query parameter.
     * - {Array<String>} exclude: A list of record ids to exclude from pull.
     * - {Object} headers: The HTTP headers to use in the request.
     * - {int} retry: The number of retries to do if the HTTP request fails.
     * - {int} lastModified: The timestamp to use in `?_since` query.
     *
     * @param  {KintoClient.Collection} client           Kinto client Collection instance.
     * @param  {SyncResultObject}       syncResultObject The sync result object.
     * @param  {Object}                 options          The options object.
     * @return {Promise}
     */

  }, {
    key: "pullChanges",
    value: function () {
      var _pullChanges = (0, _asyncToGenerator2.default)(
      /*#__PURE__*/
      _regenerator.default.mark(function _callee8(client, syncResultObject) {
        var _this7 = this;

        var options,
            since,
            filters,
            exclude_id,
            _ref6,
            data,
            last_modified,
            unquoted,
            localSynced,
            serverChanged,
            emptyCollection,
            e,
            decodedChanges,
            payload,
            afterHooks,
            _args9 = arguments;

        return _regenerator.default.wrap(function _callee8$(_context9) {
          while (1) {
            switch (_context9.prev = _context9.next) {
              case 0:
                options = _args9.length > 2 && _args9[2] !== undefined ? _args9[2] : {};

                if (syncResultObject.ok) {
                  _context9.next = 3;
                  break;
                }

                return _context9.abrupt("return", syncResultObject);

              case 3:
                if (!this.lastModified) {
                  _context9.next = 7;
                  break;
                }

                _context9.t0 = this.lastModified;
                _context9.next = 10;
                break;

              case 7:
                _context9.next = 9;
                return this.db.getLastModified();

              case 9:
                _context9.t0 = _context9.sent;

              case 10:
                since = _context9.t0;
                options = (0, _objectSpread2.default)({
                  strategy: Collection.strategy.MANUAL,
                  lastModified: since,
                  headers: {}
                }, options); // Optionally ignore some records when pulling for changes.
                // (avoid redownloading our own changes on last step of #sync())

                if (options.exclude) {
                  // Limit the list of excluded records to the first 50 records in order
                  // to remain under de-facto URL size limit (~2000 chars).
                  // http://stackoverflow.com/questions/417142/what-is-the-maximum-length-of-a-url-in-different-browsers/417184#417184
                  exclude_id = options.exclude.slice(0, 50).map(function (r) {
                    return r.id;
                  }).join(",");
                  filters = {
                    exclude_id: exclude_id
                  };
                }

                if (options.expectedTimestamp) {
                  filters = (0, _objectSpread2.default)({}, filters, {
                    _expected: options.expectedTimestamp
                  });
                } // First fetch remote changes from the server


                _context9.next = 16;
                return client.listRecords({
                  // Since should be ETag (see https://github.com/Kinto/kinto.js/issues/356)
                  since: options.lastModified ? "".concat(options.lastModified) : undefined,
                  headers: options.headers,
                  retry: options.retry,
                  // Fetch every page by default (FIXME: option to limit pages, see #277)
                  pages: Infinity,
                  filters: filters
                });

              case 16:
                _ref6 = _context9.sent;
                data = _ref6.data;
                last_modified = _ref6.last_modified;
                // last_modified is the ETag header value (string).
                // For retro-compatibility with first kinto.js versions
                // parse it to integer.
                unquoted = last_modified ? parseInt(last_modified, 10) : undefined; // Check if server was flushed.
                // This is relevant for the Kinto demo server
                // (and thus for many new comers).

                localSynced = options.lastModified;
                serverChanged = unquoted > options.lastModified;
                emptyCollection = data.length === 0;

                if (!(!options.exclude && localSynced && serverChanged && emptyCollection)) {
                  _context9.next = 26;
                  break;
                }

                e = new ServerWasFlushedError(localSynced, unquoted, "Server has been flushed. Client Side Timestamp: " + localSynced + " Server Side Timestamp: " + unquoted);
                throw e;

              case 26:
                // Atomic updates are not sensible here because unquoted is not
                // computed as a function of syncResultObject.lastModified.
                // eslint-disable-next-line require-atomic-updates
                syncResultObject.lastModified = unquoted; // Decode incoming changes.

                _context9.next = 29;
                return Promise.all(data.map(function (change) {
                  return _this7._decodeRecord("remote", change);
                }));

              case 29:
                decodedChanges = _context9.sent;
                // Hook receives decoded records.
                payload = {
                  lastModified: unquoted,
                  changes: decodedChanges
                };
                _context9.next = 33;
                return this.applyHook("incoming-changes", payload);

              case 33:
                afterHooks = _context9.sent;

                if (!(afterHooks.changes.length > 0)) {
                  _context9.next = 37;
                  break;
                }

                _context9.next = 37;
                return this.importChanges(syncResultObject, afterHooks.changes, options.strategy);

              case 37:
                return _context9.abrupt("return", syncResultObject);

              case 38:
              case "end":
                return _context9.stop();
            }
          }
        }, _callee8, this);
      }));

      return function pullChanges(_x6, _x7) {
        return _pullChanges.apply(this, arguments);
      };
    }()
  }, {
    key: "applyHook",
    value: function applyHook(hookName, payload) {
      var _this8 = this;

      if (typeof this.hooks[hookName] == "undefined") {
        return Promise.resolve(payload);
      }

      return (0, _utils.waterfall)(this.hooks[hookName].map(function (hook) {
        return function (record) {
          var result = hook(payload, _this8);
          var resultThenable = result && typeof result.then === "function";
          var resultChanges = result && Object.prototype.hasOwnProperty.call(result, "changes");

          if (!(resultThenable || resultChanges)) {
            throw new Error("Invalid return value for hook: ".concat(JSON.stringify(result), " has no 'then()' or 'changes' properties"));
          }

          return result;
        };
      }), payload);
    }
    /**
     * Publish local changes to the remote server and updates the passed
     * {@link SyncResultObject} with publication results.
     *
     * Options:
     * - {String} strategy: The selected sync strategy.
     * - {Object} headers: The HTTP headers to use in the request.
     * - {int} retry: The number of retries to do if the HTTP request fails.
     *
     * @param  {KintoClient.Collection} client           Kinto client Collection instance.
     * @param  {SyncResultObject}       syncResultObject The sync result object.
     * @param  {Object}                 changes          The change object.
     * @param  {Array}                  changes.toDelete The list of records to delete.
     * @param  {Array}                  changes.toSync   The list of records to create/update.
     * @param  {Object}                 options          The options object.
     * @return {Promise}
     */

  }, {
    key: "pushChanges",
    value: function () {
      var _pushChanges = (0, _asyncToGenerator2.default)(
      /*#__PURE__*/
      _regenerator.default.mark(function _callee9(client, changes, syncResultObject) {
        var _this9 = this;

        var options,
            safe,
            toDelete,
            toSync,
            synced,
            conflicts,
            _iteratorNormalCompletion2,
            _didIteratorError2,
            _iteratorError2,
            _iterator2,
            _step2,
            _step2$value,
            type,
            local,
            remote,
            safeLocal,
            realLocal,
            realRemote,
            conflict,
            missingRemotely,
            published,
            toApplyLocally,
            decoded,
            _args10 = arguments;

        return _regenerator.default.wrap(function _callee9$(_context10) {
          while (1) {
            switch (_context10.prev = _context10.next) {
              case 0:
                options = _args10.length > 3 && _args10[3] !== undefined ? _args10[3] : {};

                if (syncResultObject.ok) {
                  _context10.next = 3;
                  break;
                }

                return _context10.abrupt("return", syncResultObject);

              case 3:
                safe = !options.strategy || options.strategy !== Collection.CLIENT_WINS;
                toDelete = changes.filter(function (r) {
                  return r._status == "deleted";
                });
                toSync = changes.filter(function (r) {
                  return r._status != "deleted";
                }); // Perform a batch request with every changes.

                _context10.next = 8;
                return client.batch(function (batch) {
                  toDelete.forEach(function (r) {
                    // never published locally deleted records should not be pusblished
                    if (r.last_modified) {
                      batch.deleteRecord(r);
                    }
                  });
                  toSync.forEach(function (r) {
                    // Clean local fields (like _status) before sending to server.
                    var published = _this9.cleanLocalFields(r);

                    if (r._status === "created") {
                      batch.createRecord(published);
                    } else {
                      batch.updateRecord(published);
                    }
                  });
                }, {
                  headers: options.headers,
                  retry: options.retry,
                  safe: safe,
                  aggregate: true
                });

              case 8:
                synced = _context10.sent;
                // Store outgoing errors into sync result object
                syncResultObject.add("errors", synced.errors.map(function (e) {
                  return (0, _objectSpread2.default)({}, e, {
                    type: "outgoing"
                  });
                })); // Store outgoing conflicts into sync result object

                conflicts = [];
                _iteratorNormalCompletion2 = true;
                _didIteratorError2 = false;
                _iteratorError2 = undefined;
                _context10.prev = 14;
                _iterator2 = synced.conflicts[Symbol.iterator]();

              case 16:
                if (_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done) {
                  _context10.next = 33;
                  break;
                }

                _step2$value = _step2.value, type = _step2$value.type, local = _step2$value.local, remote = _step2$value.remote;
                // Note: we ensure that local data are actually available, as they may
                // be missing in the case of a published deletion.
                safeLocal = local && local.data || {
                  id: remote.id
                };
                _context10.next = 21;
                return this._decodeRecord("remote", safeLocal);

              case 21:
                realLocal = _context10.sent;
                _context10.t0 = remote;

                if (!_context10.t0) {
                  _context10.next = 27;
                  break;
                }

                _context10.next = 26;
                return this._decodeRecord("remote", remote);

              case 26:
                _context10.t0 = _context10.sent;

              case 27:
                realRemote = _context10.t0;
                conflict = {
                  type: type,
                  local: realLocal,
                  remote: realRemote
                };
                conflicts.push(conflict);

              case 30:
                _iteratorNormalCompletion2 = true;
                _context10.next = 16;
                break;

              case 33:
                _context10.next = 39;
                break;

              case 35:
                _context10.prev = 35;
                _context10.t1 = _context10["catch"](14);
                _didIteratorError2 = true;
                _iteratorError2 = _context10.t1;

              case 39:
                _context10.prev = 39;
                _context10.prev = 40;

                if (!_iteratorNormalCompletion2 && _iterator2.return != null) {
                  _iterator2.return();
                }

              case 42:
                _context10.prev = 42;

                if (!_didIteratorError2) {
                  _context10.next = 45;
                  break;
                }

                throw _iteratorError2;

              case 45:
                return _context10.finish(42);

              case 46:
                return _context10.finish(39);

              case 47:
                syncResultObject.add("conflicts", conflicts); // Records that must be deleted are either deletions that were pushed
                // to server (published) or deleted records that were never pushed (skipped).

                missingRemotely = synced.skipped.map(function (r) {
                  return (0, _objectSpread2.default)({}, r, {
                    deleted: true
                  });
                }); // For created and updated records, the last_modified coming from server
                // will be stored locally.
                // Reflect publication results locally using the response from
                // the batch request.

                published = synced.published.map(function (c) {
                  return c.data;
                });
                toApplyLocally = published.concat(missingRemotely); // Apply the decode transformers, if any

                _context10.next = 53;
                return Promise.all(toApplyLocally.map(function (record) {
                  return _this9._decodeRecord("remote", record);
                }));

              case 53:
                decoded = _context10.sent;

                if (!(decoded.length > 0 || conflicts.length > 0)) {
                  _context10.next = 57;
                  break;
                }

                _context10.next = 57;
                return this._applyPushedResults(syncResultObject, decoded, conflicts, options.strategy);

              case 57:
                return _context10.abrupt("return", syncResultObject);

              case 58:
              case "end":
                return _context10.stop();
            }
          }
        }, _callee9, this, [[14, 35, 39, 47], [40,, 42, 46]]);
      }));

      return function pushChanges(_x8, _x9, _x10) {
        return _pushChanges.apply(this, arguments);
      };
    }()
    /**
     * Return a copy of the specified record without the local fields.
     *
     * @param  {Object} record  A record with potential local fields.
     * @return {Object}
     */

  }, {
    key: "cleanLocalFields",
    value: function cleanLocalFields(record) {
      var localKeys = RECORD_FIELDS_TO_CLEAN.concat(this.localFields);
      return (0, _utils.omitKeys)(record, localKeys);
    }
    /**
     * Resolves a conflict, updating local record according to proposed
     * resolution — keeping remote record `last_modified` value as a reference for
     * further batch sending.
     *
     * @param  {Object} conflict   The conflict object.
     * @param  {Object} resolution The proposed record.
     * @return {Promise}
     */

  }, {
    key: "resolve",
    value: function resolve(conflict, resolution) {
      var _this10 = this;

      return this.db.execute(function (transaction) {
        var updated = _this10._resolveRaw(conflict, resolution);

        transaction.update(updated);
        return {
          data: updated,
          permissions: {}
        };
      });
    }
    /**
     * @private
     */

  }, {
    key: "_resolveRaw",
    value: function _resolveRaw(conflict, resolution) {
      var resolved = (0, _objectSpread2.default)({}, resolution, {
        // Ensure local record has the latest authoritative timestamp
        last_modified: conflict.remote && conflict.remote.last_modified
      }); // If the resolution object is strictly equal to the
      // remote record, then we can mark it as synced locally.
      // Otherwise, mark it as updated (so that the resolution is pushed).

      var synced = (0, _utils.deepEqual)(resolved, conflict.remote);
      return markStatus(resolved, synced ? "synced" : "updated");
    }
    /**
     * Synchronize remote and local data. The promise will resolve with a
     * {@link SyncResultObject}, though will reject:
     *
     * - if the server is currently backed off;
     * - if the server has been detected flushed.
     *
     * Options:
     * - {Object} headers: HTTP headers to attach to outgoing requests.
     * - {String} expectedTimestamp: A timestamp to use as a "cache busting" query parameter.
     * - {Number} retry: Number of retries when server fails to process the request (default: 1).
     * - {Collection.strategy} strategy: See {@link Collection.strategy}.
     * - {Boolean} ignoreBackoff: Force synchronization even if server is currently
     *   backed off.
     * - {String} bucket: The remove bucket id to use (default: null)
     * - {String} collection: The remove collection id to use (default: null)
     * - {String} remote The remote Kinto server endpoint to use (default: null).
     *
     * @param  {Object} options Options.
     * @return {Promise}
     * @throws {Error} If an invalid remote option is passed.
     */

  }, {
    key: "sync",
    value: function () {
      var _sync = (0, _asyncToGenerator2.default)(
      /*#__PURE__*/
      _regenerator.default.mark(function _callee10() {
        var _this11 = this;

        var options,
            previousRemote,
            seconds,
            client,
            result,
            lastModified,
            toSync,
            resolvedUnsynced,
            resolvedEncoded,
            pullOpts,
            _args11 = arguments;
        return _regenerator.default.wrap(function _callee10$(_context11) {
          while (1) {
            switch (_context11.prev = _context11.next) {
              case 0:
                options = _args11.length > 0 && _args11[0] !== undefined ? _args11[0] : {
                  strategy: Collection.strategy.MANUAL,
                  headers: {},
                  retry: 1,
                  ignoreBackoff: false,
                  bucket: null,
                  collection: null,
                  remote: null,
                  expectedTimestamp: null
                };
                options = (0, _objectSpread2.default)({}, options, {
                  bucket: options.bucket || this.bucket,
                  collection: options.collection || this.name
                });
                previousRemote = this.api.remote;

                if (options.remote) {
                  // Note: setting the remote ensures it's valid, throws when invalid.
                  this.api.remote = options.remote;
                }

                if (!(!options.ignoreBackoff && this.api.backoff > 0)) {
                  _context11.next = 7;
                  break;
                }

                seconds = Math.ceil(this.api.backoff / 1000);
                return _context11.abrupt("return", Promise.reject(new Error("Server is asking clients to back off; retry in ".concat(seconds, "s or use the ignoreBackoff option."))));

              case 7:
                client = this.api.bucket(options.bucket).collection(options.collection);
                result = new SyncResultObject();
                _context11.prev = 9;
                _context11.next = 12;
                return this.pullMetadata(client, options);

              case 12:
                _context11.next = 14;
                return this.pullChanges(client, result, options);

              case 14:
                lastModified = result.lastModified;

                if (!(options.strategy != Collection.strategy.PULL_ONLY)) {
                  _context11.next = 32;
                  break;
                }

                _context11.next = 18;
                return this.gatherLocalChanges();

              case 18:
                toSync = _context11.sent;
                _context11.next = 21;
                return this.pushChanges(client, toSync, result, options);

              case 21:
                // Publish local resolution of push conflicts to server (on CLIENT_WINS)
                resolvedUnsynced = result.resolved.filter(function (r) {
                  return r._status !== "synced";
                });

                if (!(resolvedUnsynced.length > 0)) {
                  _context11.next = 28;
                  break;
                }

                _context11.next = 25;
                return Promise.all(resolvedUnsynced.map(function (resolution) {
                  var record = resolution.accepted;

                  if (record === null) {
                    record = {
                      id: resolution.id,
                      _status: resolution._status
                    };
                  }

                  return _this11._encodeRecord("remote", record);
                }));

              case 25:
                resolvedEncoded = _context11.sent;
                _context11.next = 28;
                return this.pushChanges(client, resolvedEncoded, result, options);

              case 28:
                if (!(result.published.length > 0)) {
                  _context11.next = 32;
                  break;
                }

                // Avoid redownloading our own changes during the last pull.
                pullOpts = (0, _objectSpread2.default)({}, options, {
                  lastModified: lastModified,
                  exclude: result.published
                });
                _context11.next = 32;
                return this.pullChanges(client, result, pullOpts);

              case 32:
                if (!result.ok) {
                  _context11.next = 36;
                  break;
                }

                _context11.next = 35;
                return this.db.saveLastModified(result.lastModified);

              case 35:
                this._lastModified = _context11.sent;

              case 36:
                _context11.next = 42;
                break;

              case 38:
                _context11.prev = 38;
                _context11.t0 = _context11["catch"](9);
                this.events.emit("sync:error", (0, _objectSpread2.default)({}, options, {
                  error: _context11.t0
                }));
                throw _context11.t0;

              case 42:
                _context11.prev = 42;
                // Ensure API default remote is reverted if a custom one's been used
                this.api.remote = previousRemote;
                return _context11.finish(42);

              case 45:
                this.events.emit("sync:success", (0, _objectSpread2.default)({}, options, {
                  result: result
                }));
                return _context11.abrupt("return", result);

              case 47:
              case "end":
                return _context11.stop();
            }
          }
        }, _callee10, this, [[9, 38, 42, 45]]);
      }));

      return function sync() {
        return _sync.apply(this, arguments);
      };
    }()
    /**
     * Load a list of records already synced with the remote server.
     *
     * The local records which are unsynced or whose timestamp is either missing
     * or superior to those being loaded will be ignored.
     *
     * @deprecated Use {@link importBulk} instead.
     * @param  {Array} records The previously exported list of records to load.
     * @return {Promise} with the effectively imported records.
     */

  }, {
    key: "loadDump",
    value: function () {
      var _loadDump = (0, _asyncToGenerator2.default)(
      /*#__PURE__*/
      _regenerator.default.mark(function _callee11(records) {
        return _regenerator.default.wrap(function _callee11$(_context12) {
          while (1) {
            switch (_context12.prev = _context12.next) {
              case 0:
                return _context12.abrupt("return", this.importBulk(records));

              case 1:
              case "end":
                return _context12.stop();
            }
          }
        }, _callee11, this);
      }));

      return function loadDump(_x11) {
        return _loadDump.apply(this, arguments);
      };
    }()
    /**
     * Load a list of records already synced with the remote server.
     *
     * The local records which are unsynced or whose timestamp is either missing
     * or superior to those being loaded will be ignored.
     *
     * @param  {Array} records The previously exported list of records to load.
     * @return {Promise} with the effectively imported records.
     */

  }, {
    key: "importBulk",
    value: function () {
      var _importBulk = (0, _asyncToGenerator2.default)(
      /*#__PURE__*/
      _regenerator.default.mark(function _callee12(records) {
        var _iteratorNormalCompletion3, _didIteratorError3, _iteratorError3, _iterator3, _step3, record, _ref7, data, existingById, newRecords;

        return _regenerator.default.wrap(function _callee12$(_context13) {
          while (1) {
            switch (_context13.prev = _context13.next) {
              case 0:
                if (Array.isArray(records)) {
                  _context13.next = 2;
                  break;
                }

                throw new Error("Records is not an array.");

              case 2:
                _iteratorNormalCompletion3 = true;
                _didIteratorError3 = false;
                _iteratorError3 = undefined;
                _context13.prev = 5;
                _iterator3 = records[Symbol.iterator]();

              case 7:
                if (_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done) {
                  _context13.next = 16;
                  break;
                }

                record = _step3.value;

                if (!(!Object.prototype.hasOwnProperty.call(record, "id") || !this.idSchema.validate(record.id))) {
                  _context13.next = 11;
                  break;
                }

                throw new Error("Record has invalid ID: " + JSON.stringify(record));

              case 11:
                if (record.last_modified) {
                  _context13.next = 13;
                  break;
                }

                throw new Error("Record has no last_modified value: " + JSON.stringify(record));

              case 13:
                _iteratorNormalCompletion3 = true;
                _context13.next = 7;
                break;

              case 16:
                _context13.next = 22;
                break;

              case 18:
                _context13.prev = 18;
                _context13.t0 = _context13["catch"](5);
                _didIteratorError3 = true;
                _iteratorError3 = _context13.t0;

              case 22:
                _context13.prev = 22;
                _context13.prev = 23;

                if (!_iteratorNormalCompletion3 && _iterator3.return != null) {
                  _iterator3.return();
                }

              case 25:
                _context13.prev = 25;

                if (!_didIteratorError3) {
                  _context13.next = 28;
                  break;
                }

                throw _iteratorError3;

              case 28:
                return _context13.finish(25);

              case 29:
                return _context13.finish(22);

              case 30:
                _context13.next = 32;
                return this.list({}, {
                  includeDeleted: true
                });

              case 32:
                _ref7 = _context13.sent;
                data = _ref7.data;
                existingById = data.reduce(function (acc, record) {
                  acc[record.id] = record;
                  return acc;
                }, {});
                newRecords = records.filter(function (record) {
                  var localRecord = existingById[record.id];
                  var shouldKeep = // No local record with this id.
                  localRecord === undefined || // Or local record is synced
                  localRecord._status === "synced" && // And was synced from server
                  localRecord.last_modified !== undefined && // And is older than imported one.
                  record.last_modified > localRecord.last_modified;
                  return shouldKeep;
                });
                _context13.next = 38;
                return this.db.importBulk(newRecords.map(markSynced));

              case 38:
                return _context13.abrupt("return", _context13.sent);

              case 39:
              case "end":
                return _context13.stop();
            }
          }
        }, _callee12, this, [[5, 18, 22, 30], [23,, 25, 29]]);
      }));

      return function importBulk(_x12) {
        return _importBulk.apply(this, arguments);
      };
    }()
  }, {
    key: "pullMetadata",
    value: function () {
      var _pullMetadata = (0, _asyncToGenerator2.default)(
      /*#__PURE__*/
      _regenerator.default.mark(function _callee13(client) {
        var options,
            expectedTimestamp,
            headers,
            query,
            metadata,
            _args14 = arguments;
        return _regenerator.default.wrap(function _callee13$(_context14) {
          while (1) {
            switch (_context14.prev = _context14.next) {
              case 0:
                options = _args14.length > 1 && _args14[1] !== undefined ? _args14[1] : {};
                expectedTimestamp = options.expectedTimestamp, headers = options.headers;
                query = expectedTimestamp ? {
                  query: {
                    _expected: expectedTimestamp
                  }
                } : undefined;
                _context14.next = 5;
                return client.getData((0, _objectSpread2.default)({}, query, {
                  headers: headers
                }));

              case 5:
                metadata = _context14.sent;
                return _context14.abrupt("return", this.db.saveMetadata(metadata));

              case 7:
              case "end":
                return _context14.stop();
            }
          }
        }, _callee13, this);
      }));

      return function pullMetadata(_x13) {
        return _pullMetadata.apply(this, arguments);
      };
    }()
  }, {
    key: "metadata",
    value: function () {
      var _metadata = (0, _asyncToGenerator2.default)(
      /*#__PURE__*/
      _regenerator.default.mark(function _callee14() {
        return _regenerator.default.wrap(function _callee14$(_context15) {
          while (1) {
            switch (_context15.prev = _context15.next) {
              case 0:
                return _context15.abrupt("return", this.db.getMetadata());

              case 1:
              case "end":
                return _context15.stop();
            }
          }
        }, _callee14, this);
      }));

      return function metadata() {
        return _metadata.apply(this, arguments);
      };
    }()
  }, {
    key: "name",
    get: function get() {
      return this._name;
    }
    /**
     * The bucket name.
     * @type {String}
     */

  }, {
    key: "bucket",
    get: function get() {
      return this._bucket;
    }
    /**
     * The last modified timestamp.
     * @type {Number}
     */

  }, {
    key: "lastModified",
    get: function get() {
      return this._lastModified;
    }
    /**
     * Synchronization strategies. Available strategies are:
     *
     * - `MANUAL`: Conflicts will be reported in a dedicated array.
     * - `SERVER_WINS`: Conflicts are resolved using remote data.
     * - `CLIENT_WINS`: Conflicts are resolved using local data.
     *
     * @type {Object}
     */

  }], [{
    key: "strategy",
    get: function get() {
      return {
        CLIENT_WINS: "client_wins",
        SERVER_WINS: "server_wins",
        PULL_ONLY: "pull_only",
        MANUAL: "manual"
      };
    }
  }]);
  return Collection;
}();
/**
 * A Collection-oriented wrapper for an adapter's transaction.
 *
 * This defines the high-level functions available on a collection.
 * The collection itself offers functions of the same name. These will
 * perform just one operation in its own transaction.
 */


exports.default = Collection;

var CollectionTransaction =
/*#__PURE__*/
function () {
  function CollectionTransaction(collection, adapterTransaction) {
    (0, _classCallCheck2.default)(this, CollectionTransaction);
    this.collection = collection;
    this.adapterTransaction = adapterTransaction;
    this._events = [];
  }

  (0, _createClass2.default)(CollectionTransaction, [{
    key: "_queueEvent",
    value: function _queueEvent(action, payload) {
      this._events.push({
        action: action,
        payload: payload
      });
    }
    /**
     * Emit queued events, to be called once every transaction operations have
     * been executed successfully.
     */

  }, {
    key: "emitEvents",
    value: function emitEvents() {
      var _iteratorNormalCompletion4 = true;
      var _didIteratorError4 = false;
      var _iteratorError4 = undefined;

      try {
        for (var _iterator4 = this._events[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) {
          var _step4$value = _step4.value,
              action = _step4$value.action,
              payload = _step4$value.payload;
          this.collection.events.emit(action, payload);
        }
      } catch (err) {
        _didIteratorError4 = true;
        _iteratorError4 = err;
      } finally {
        try {
          if (!_iteratorNormalCompletion4 && _iterator4.return != null) {
            _iterator4.return();
          }
        } finally {
          if (_didIteratorError4) {
            throw _iteratorError4;
          }
        }
      }

      if (this._events.length > 0) {
        var targets = this._events.map(function (_ref8) {
          var action = _ref8.action,
              payload = _ref8.payload;
          return (0, _objectSpread2.default)({
            action: action
          }, payload);
        });

        this.collection.events.emit("change", {
          targets: targets
        });
      }

      this._events = [];
    }
    /**
     * Retrieve a record by its id from the local database, or
     * undefined if none exists.
     *
     * This will also return virtually deleted records.
     *
     * @param  {String} id
     * @return {Object}
     */

  }, {
    key: "getAny",
    value: function getAny(id) {
      var record = this.adapterTransaction.get(id);
      return {
        data: record,
        permissions: {}
      };
    }
    /**
     * Retrieve a record by its id from the local database.
     *
     * Options:
     * - {Boolean} includeDeleted: Include virtually deleted records.
     *
     * @param  {String} id
     * @param  {Object} options
     * @return {Object}
     */

  }, {
    key: "get",
    value: function get(id) {
      var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {
        includeDeleted: false
      };
      var res = this.getAny(id);

      if (!res.data || !options.includeDeleted && res.data._status === "deleted") {
        throw new Error("Record with id=".concat(id, " not found."));
      }

      return res;
    }
    /**
     * Deletes a record from the local database.
     *
     * Options:
     * - {Boolean} virtual: When set to `true`, doesn't actually delete the record,
     *   update its `_status` attribute to `deleted` instead (default: true)
     *
     * @param  {String} id       The record's Id.
     * @param  {Object} options  The options object.
     * @return {Object}
     */

  }, {
    key: "delete",
    value: function _delete(id) {
      var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {
        virtual: true
      };
      // Ensure the record actually exists.
      var existing = this.adapterTransaction.get(id);
      var alreadyDeleted = existing && existing._status == "deleted";

      if (!existing || alreadyDeleted && options.virtual) {
        throw new Error("Record with id=".concat(id, " not found."));
      } // Virtual updates status.


      if (options.virtual) {
        this.adapterTransaction.update(markDeleted(existing));
      } else {
        // Delete for real.
        this.adapterTransaction.delete(id);
      }

      this._queueEvent("delete", {
        data: existing
      });

      return {
        data: existing,
        permissions: {}
      };
    }
    /**
     * Soft delete all records from the local database.
     *
     * @param  {Array} ids        Array of non-deleted Record Ids.
     * @return {Object}
     */

  }, {
    key: "deleteAll",
    value: function deleteAll(ids) {
      var _this12 = this;

      var existingRecords = [];
      ids.forEach(function (id) {
        existingRecords.push(_this12.adapterTransaction.get(id));

        _this12.delete(id);
      });

      this._queueEvent("deleteAll", {
        data: existingRecords
      });

      return {
        data: existingRecords,
        permissions: {}
      };
    }
    /**
     * Deletes a record from the local database, if any exists.
     * Otherwise, do nothing.
     *
     * @param  {String} id       The record's Id.
     * @return {Object}
     */

  }, {
    key: "deleteAny",
    value: function deleteAny(id) {
      var existing = this.adapterTransaction.get(id);

      if (existing) {
        this.adapterTransaction.update(markDeleted(existing));

        this._queueEvent("delete", {
          data: existing
        });
      }

      return {
        data: (0, _objectSpread2.default)({
          id: id
        }, existing),
        deleted: !!existing,
        permissions: {}
      };
    }
    /**
     * Adds a record to the local database, asserting that none
     * already exist with this ID.
     *
     * @param  {Object} record, which must contain an ID
     * @return {Object}
     */

  }, {
    key: "create",
    value: function create(record) {
      if ((0, _typeof2.default)(record) !== "object") {
        throw new Error("Record is not an object.");
      }

      if (!Object.prototype.hasOwnProperty.call(record, "id")) {
        throw new Error("Cannot create a record missing id");
      }

      if (!this.collection.idSchema.validate(record.id)) {
        throw new Error("Invalid Id: ".concat(record.id));
      }

      this.adapterTransaction.create(record);

      this._queueEvent("create", {
        data: record
      });

      return {
        data: record,
        permissions: {}
      };
    }
    /**
     * Updates a record from the local database.
     *
     * Options:
     * - {Boolean} synced: Sets record status to "synced" (default: false)
     * - {Boolean} patch:  Extends the existing record instead of overwriting it
     *   (default: false)
     *
     * @param  {Object} record
     * @param  {Object} options
     * @return {Object}
     */

  }, {
    key: "update",
    value: function update(record) {
      var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {
        synced: false,
        patch: false
      };

      if ((0, _typeof2.default)(record) !== "object") {
        throw new Error("Record is not an object.");
      }

      if (!Object.prototype.hasOwnProperty.call(record, "id")) {
        throw new Error("Cannot update a record missing id.");
      }

      if (!this.collection.idSchema.validate(record.id)) {
        throw new Error("Invalid Id: ".concat(record.id));
      }

      var oldRecord = this.adapterTransaction.get(record.id);

      if (!oldRecord) {
        throw new Error("Record with id=".concat(record.id, " not found."));
      }

      var newRecord = options.patch ? (0, _objectSpread2.default)({}, oldRecord, record) : record;

      var updated = this._updateRaw(oldRecord, newRecord, options);

      this.adapterTransaction.update(updated);

      this._queueEvent("update", {
        data: updated,
        oldRecord: oldRecord
      });

      return {
        data: updated,
        oldRecord: oldRecord,
        permissions: {}
      };
    }
    /**
     * Lower-level primitive for updating a record while respecting
     * _status and last_modified.
     *
     * @param  {Object} oldRecord: the record retrieved from the DB
     * @param  {Object} newRecord: the record to replace it with
     * @return {Object}
     */

  }, {
    key: "_updateRaw",
    value: function _updateRaw(oldRecord, newRecord) {
      var _ref9 = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {},
          _ref9$synced = _ref9.synced,
          synced = _ref9$synced === void 0 ? false : _ref9$synced;

      var updated = (0, _objectSpread2.default)({}, newRecord); // Make sure to never loose the existing timestamp.

      if (oldRecord && oldRecord.last_modified && !updated.last_modified) {
        updated.last_modified = oldRecord.last_modified;
      } // If only local fields have changed, then keep record as synced.
      // If status is created, keep record as created.
      // If status is deleted, mark as updated.


      var isIdentical = oldRecord && recordsEqual(oldRecord, updated, this.collection.localFields);
      var keepSynced = isIdentical && oldRecord._status == "synced";
      var neverSynced = !oldRecord || oldRecord && oldRecord._status == "created";
      var newStatus = keepSynced || synced ? "synced" : neverSynced ? "created" : "updated";
      return markStatus(updated, newStatus);
    }
    /**
     * Upsert a record into the local database.
     *
     * This record must have an ID.
     *
     * If a record with this ID already exists, it will be replaced.
     * Otherwise, this record will be inserted.
     *
     * @param  {Object} record
     * @return {Object}
     */

  }, {
    key: "upsert",
    value: function upsert(record) {
      if ((0, _typeof2.default)(record) !== "object") {
        throw new Error("Record is not an object.");
      }

      if (!Object.prototype.hasOwnProperty.call(record, "id")) {
        throw new Error("Cannot update a record missing id.");
      }

      if (!this.collection.idSchema.validate(record.id)) {
        throw new Error("Invalid Id: ".concat(record.id));
      }

      var oldRecord = this.adapterTransaction.get(record.id);

      var updated = this._updateRaw(oldRecord, record);

      this.adapterTransaction.update(updated); // Don't return deleted records -- pretend they are gone

      if (oldRecord && oldRecord._status == "deleted") {
        oldRecord = undefined;
      }

      if (oldRecord) {
        this._queueEvent("update", {
          data: updated,
          oldRecord: oldRecord
        });
      } else {
        this._queueEvent("create", {
          data: updated
        });
      }

      return {
        data: updated,
        oldRecord: oldRecord,
        permissions: {}
      };
    }
  }]);
  return CollectionTransaction;
}();

exports.CollectionTransaction = CollectionTransaction;

},{"./adapters/IDB":323,"./adapters/base":324,"./utils":327,"@babel/runtime/helpers/assertThisInitialized":280,"@babel/runtime/helpers/asyncToGenerator":281,"@babel/runtime/helpers/classCallCheck":282,"@babel/runtime/helpers/createClass":284,"@babel/runtime/helpers/getPrototypeOf":286,"@babel/runtime/helpers/inherits":287,"@babel/runtime/helpers/interopRequireDefault":288,"@babel/runtime/helpers/objectSpread":295,"@babel/runtime/helpers/possibleConstructorReturn":296,"@babel/runtime/helpers/typeof":301,"@babel/runtime/helpers/wrapNativeSuper":302,"@babel/runtime/regenerator":305,"uuid":317}],326:[function(require,module,exports){
(function (global){
"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;

var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof"));

var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread"));

var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));

var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn"));

var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf"));

var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));

var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits"));

var _events = require("events");

var _kintoHttp = _interopRequireDefault(require("kinto-http"));

var _base = _interopRequireDefault(require("./adapters/base"));

var _IDB = _interopRequireDefault(require("./adapters/IDB"));

var _KintoBase2 = _interopRequireDefault(require("./KintoBase"));

// babel-polyfill can only be imported once
if (!global._babelPolyfill) {
  require("@babel/polyfill");
}

var Kinto =
/*#__PURE__*/
function (_KintoBase) {
  (0, _inherits2.default)(Kinto, _KintoBase);
  (0, _createClass2.default)(Kinto, null, [{
    key: "adapters",

    /**
     * Provides a public access to the base adapter classes. Users can create
     * a custom DB adapter by extending BaseAdapter.
     *
     * @type {Object}
     */
    get: function get() {
      return {
        BaseAdapter: _base.default,
        IDB: _IDB.default
      };
    }
  }]);

  function Kinto() {
    var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
    (0, _classCallCheck2.default)(this, Kinto);
    var defaults = {
      adapter: Kinto.adapters.IDB,
      events: new _events.EventEmitter(),
      ApiClass: _kintoHttp.default
    };
    return (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(Kinto).call(this, (0, _objectSpread2.default)({}, defaults, options)));
  }

  return Kinto;
}(_KintoBase2.default); // This fixes compatibility with CommonJS required by browserify.
// See http://stackoverflow.com/questions/33505992/babel-6-changes-how-it-exports-default/33683495#33683495


exports.default = Kinto;

if ((typeof module === "undefined" ? "undefined" : (0, _typeof2.default)(module)) === "object") {
  module.exports = Kinto;
}

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

},{"./KintoBase":322,"./adapters/IDB":323,"./adapters/base":324,"@babel/polyfill":1,"@babel/runtime/helpers/classCallCheck":282,"@babel/runtime/helpers/createClass":284,"@babel/runtime/helpers/getPrototypeOf":286,"@babel/runtime/helpers/inherits":287,"@babel/runtime/helpers/interopRequireDefault":288,"@babel/runtime/helpers/objectSpread":295,"@babel/runtime/helpers/possibleConstructorReturn":296,"@babel/runtime/helpers/typeof":301,"events":306,"kinto-http":314}],327:[function(require,module,exports){
"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.sortObjects = sortObjects;
exports.filterObject = filterObject;
exports.filterObjects = filterObjects;
exports.waterfall = waterfall;
exports.deepEqual = deepEqual;
exports.omitKeys = omitKeys;
exports.arrayEqual = arrayEqual;
exports.transformSubObjectFilters = transformSubObjectFilters;
exports.RE_RECORD_ID = void 0;

var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread"));

var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof"));

var RE_RECORD_ID = /^[a-zA-Z0-9][a-zA-Z0-9_-]*$/;
/**
 * Checks if a value is undefined.
 * @param  {Any}  value
 * @return {Boolean}
 */

exports.RE_RECORD_ID = RE_RECORD_ID;

function _isUndefined(value) {
  return typeof value === "undefined";
}
/**
 * Sorts records in a list according to a given ordering.
 *
 * @param  {String} order The ordering, eg. `-last_modified`.
 * @param  {Array}  list  The collection to order.
 * @return {Array}
 */


function sortObjects(order, list) {
  var hasDash = order[0] === "-";
  var field = hasDash ? order.slice(1) : order;
  var direction = hasDash ? -1 : 1;
  return list.slice().sort(function (a, b) {
    if (a[field] && _isUndefined(b[field])) {
      return direction;
    }

    if (b[field] && _isUndefined(a[field])) {
      return -direction;
    }

    if (_isUndefined(a[field]) && _isUndefined(b[field])) {
      return 0;
    }

    return a[field] > b[field] ? direction : -direction;
  });
}
/**
 * Test if a single object matches all given filters.
 *
 * @param  {Object} filters  The filters object.
 * @param  {Object} entry    The object to filter.
 * @return {Boolean}
 */


function filterObject(filters, entry) {
  return Object.keys(filters).every(function (filter) {
    var value = filters[filter];

    if (Array.isArray(value)) {
      return value.some(function (candidate) {
        return candidate === entry[filter];
      });
    } else if ((0, _typeof2.default)(value) === "object") {
      return filterObject(value, entry[filter]);
    } else if (!Object.prototype.hasOwnProperty.call(entry, filter)) {
      console.error("The property ".concat(filter, " does not exist"));
      return false;
    }

    return entry[filter] === value;
  });
}
/**
 * Filters records in a list matching all given filters.
 *
 * @param  {Object} filters  The filters object.
 * @param  {Array}  list     The collection to filter.
 * @return {Array}
 */


function filterObjects(filters, list) {
  return list.filter(function (entry) {
    return filterObject(filters, entry);
  });
}
/**
 * Resolves a list of functions sequentially, which can be sync or async; in
 * case of async, functions must return a promise.
 *
 * @param  {Array} fns  The list of functions.
 * @param  {Any}   init The initial value.
 * @return {Promise}
 */


function waterfall(fns, init) {
  if (!fns.length) {
    return Promise.resolve(init);
  }

  return fns.reduce(function (promise, nextFn) {
    return promise.then(nextFn);
  }, Promise.resolve(init));
}
/**
 * Simple deep object comparison function. This only supports comparison of
 * serializable JavaScript objects.
 *
 * @param  {Object} a The source object.
 * @param  {Object} b The compared object.
 * @return {Boolean}
 */


function deepEqual(a, b) {
  if (a === b) {
    return true;
  }

  if ((0, _typeof2.default)(a) !== (0, _typeof2.default)(b)) {
    return false;
  }

  if (!(a && (0, _typeof2.default)(a) == "object") || !(b && (0, _typeof2.default)(b) == "object")) {
    return false;
  }

  if (Object.keys(a).length !== Object.keys(b).length) {
    return false;
  }

  for (var k in a) {
    if (!deepEqual(a[k], b[k])) {
      return false;
    }
  }

  return true;
}
/**
 * Return an object without the specified keys.
 *
 * @param  {Object} obj        The original object.
 * @param  {Array}  keys       The list of keys to exclude.
 * @return {Object}            A copy without the specified keys.
 */


function omitKeys(obj) {
  var keys = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
  var result = (0, _objectSpread2.default)({}, obj);
  var _iteratorNormalCompletion = true;
  var _didIteratorError = false;
  var _iteratorError = undefined;

  try {
    for (var _iterator = keys[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
      var key = _step.value;
      delete result[key];
    }
  } catch (err) {
    _didIteratorError = true;
    _iteratorError = err;
  } finally {
    try {
      if (!_iteratorNormalCompletion && _iterator.return != null) {
        _iterator.return();
      }
    } finally {
      if (_didIteratorError) {
        throw _iteratorError;
      }
    }
  }

  return result;
}

function arrayEqual(a, b) {
  if (a.length !== b.length) {
    return false;
  }

  for (var i = a.length; i--;) {
    if (a[i] !== b[i]) {
      return false;
    }
  }

  return true;
}

function makeNestedObjectFromArr(arr, val, nestedFiltersObj) {
  var last = arr.length - 1;
  return arr.reduce(function (acc, cv, i) {
    if (i === last) {
      return acc[cv] = val;
    } else if (Object.prototype.hasOwnProperty.call(acc, cv)) {
      return acc[cv];
    } else {
      return acc[cv] = {};
    }
  }, nestedFiltersObj);
}

function transformSubObjectFilters(filtersObj) {
  var transformedFilters = {};

  for (var key in filtersObj) {
    var keysArr = key.split(".");
    var val = filtersObj[key];
    makeNestedObjectFromArr(keysArr, val, transformedFilters);
  }

  return transformedFilters;
}

},{"@babel/runtime/helpers/interopRequireDefault":288,"@babel/runtime/helpers/objectSpread":295,"@babel/runtime/helpers/typeof":301}]},{},[326])(326)
});

//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL2xpYi9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvZXM2L2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9mbi9hcnJheS9pbmNsdWRlcy5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvZm4vb2JqZWN0L2VudHJpZXMuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL2ZuL29iamVjdC9nZXQtb3duLXByb3BlcnR5LWRlc2NyaXB0b3JzLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9mbi9vYmplY3QvdmFsdWVzLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9mbi9wcm9taXNlL2ZpbmFsbHkuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL2ZuL3N0cmluZy9wYWQtZW5kLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9mbi9zdHJpbmcvcGFkLXN0YXJ0LmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9mbi9zeW1ib2wvYXN5bmMtaXRlcmF0b3IuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2EtZnVuY3Rpb24uanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2EtbnVtYmVyLXZhbHVlLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19hZGQtdG8tdW5zY29wYWJsZXMuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2FuLWluc3RhbmNlLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19hbi1vYmplY3QuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2FycmF5LWNvcHktd2l0aGluLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19hcnJheS1maWxsLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19hcnJheS1pbmNsdWRlcy5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fYXJyYXktbWV0aG9kcy5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fYXJyYXktcmVkdWNlLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19hcnJheS1zcGVjaWVzLWNvbnN0cnVjdG9yLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19hcnJheS1zcGVjaWVzLWNyZWF0ZS5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fYmluZC5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fY2xhc3NvZi5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fY29mLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19jb2xsZWN0aW9uLXN0cm9uZy5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fY29sbGVjdGlvbi13ZWFrLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19jb2xsZWN0aW9uLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19jb3JlLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19jcmVhdGUtcHJvcGVydHkuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2N0eC5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZGF0ZS10by1pc28tc3RyaW5nLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19kYXRlLXRvLXByaW1pdGl2ZS5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZGVmaW5lZC5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZGVzY3JpcHRvcnMuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2RvbS1jcmVhdGUuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2VudW0tYnVnLWtleXMuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2VudW0ta2V5cy5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZXhwb3J0LmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19mYWlscy1pcy1yZWdleHAuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2ZhaWxzLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19maXgtcmUtd2tzLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19mbGFncy5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fZm9yLW9mLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19nbG9iYWwuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2hhcy5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9faGlkZS5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9faHRtbC5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9faWU4LWRvbS1kZWZpbmUuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2luaGVyaXQtaWYtcmVxdWlyZWQuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2ludm9rZS5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9faW9iamVjdC5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9faXMtYXJyYXktaXRlci5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9faXMtYXJyYXkuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2lzLWludGVnZXIuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2lzLW9iamVjdC5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9faXMtcmVnZXhwLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19pdGVyLWNhbGwuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2l0ZXItY3JlYXRlLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19pdGVyLWRlZmluZS5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9faXRlci1kZXRlY3QuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX2l0ZXItc3RlcC5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9faXRlcmF0b3JzLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19saWJyYXJ5LmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19tYXRoLWV4cG0xLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19tYXRoLWZyb3VuZC5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fbWF0aC1sb2cxcC5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fbWF0aC1zaWduLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19tZXRhLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19taWNyb3Rhc2suanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX25ldy1wcm9taXNlLWNhcGFiaWxpdHkuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX29iamVjdC1hc3NpZ24uanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX29iamVjdC1jcmVhdGUuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX29iamVjdC1kcC5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fb2JqZWN0LWRwcy5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fb2JqZWN0LWdvcGQuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX29iamVjdC1nb3BuLWV4dC5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fb2JqZWN0LWdvcG4uanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX29iamVjdC1nb3BzLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19vYmplY3QtZ3BvLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19vYmplY3Qta2V5cy1pbnRlcm5hbC5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fb2JqZWN0LWtleXMuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX29iamVjdC1waWUuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX29iamVjdC1zYXAuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX29iamVjdC10by1hcnJheS5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fb3duLWtleXMuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3BhcnNlLWZsb2F0LmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19wYXJzZS1pbnQuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3BlcmZvcm0uanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3Byb21pc2UtcmVzb2x2ZS5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fcHJvcGVydHktZGVzYy5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fcmVkZWZpbmUtYWxsLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19yZWRlZmluZS5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fc2FtZS12YWx1ZS5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fc2V0LXByb3RvLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19zZXQtc3BlY2llcy5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fc2V0LXRvLXN0cmluZy10YWcuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3NoYXJlZC1rZXkuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3NoYXJlZC5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fc3BlY2llcy1jb25zdHJ1Y3Rvci5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fc3RyaWN0LW1ldGhvZC5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fc3RyaW5nLWF0LmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19zdHJpbmctY29udGV4dC5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fc3RyaW5nLWh0bWwuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3N0cmluZy1wYWQuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3N0cmluZy1yZXBlYXQuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3N0cmluZy10cmltLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL19zdHJpbmctd3MuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3Rhc2suanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3RvLWFic29sdXRlLWluZGV4LmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL190by1pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fdG8taW50ZWdlci5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fdG8taW9iamVjdC5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fdG8tbGVuZ3RoLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL190by1vYmplY3QuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3RvLXByaW1pdGl2ZS5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fdHlwZWQtYXJyYXkuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3R5cGVkLWJ1ZmZlci5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fdHlwZWQuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvX3VpZC5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fdXNlci1hZ2VudC5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fdmFsaWRhdGUtY29sbGVjdGlvbi5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fd2tzLWRlZmluZS5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fd2tzLWV4dC5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9fd2tzLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2NvcmUuZ2V0LWl0ZXJhdG9yLW1ldGhvZC5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuYXJyYXkuY29weS13aXRoaW4uanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LmFycmF5LmV2ZXJ5LmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5hcnJheS5maWxsLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5hcnJheS5maWx0ZXIuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LmFycmF5LmZpbmQtaW5kZXguanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LmFycmF5LmZpbmQuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LmFycmF5LmZvci1lYWNoLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5hcnJheS5mcm9tLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5hcnJheS5pbmRleC1vZi5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuYXJyYXkuaXMtYXJyYXkuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LmFycmF5Lml0ZXJhdG9yLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5hcnJheS5qb2luLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5hcnJheS5sYXN0LWluZGV4LW9mLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5hcnJheS5tYXAuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LmFycmF5Lm9mLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5hcnJheS5yZWR1Y2UtcmlnaHQuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LmFycmF5LnJlZHVjZS5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuYXJyYXkuc2xpY2UuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LmFycmF5LnNvbWUuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LmFycmF5LnNvcnQuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LmFycmF5LnNwZWNpZXMuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LmRhdGUubm93LmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5kYXRlLnRvLWlzby1zdHJpbmcuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LmRhdGUudG8tanNvbi5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuZGF0ZS50by1wcmltaXRpdmUuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LmRhdGUudG8tc3RyaW5nLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5mdW5jdGlvbi5iaW5kLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5mdW5jdGlvbi5oYXMtaW5zdGFuY2UuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LmZ1bmN0aW9uLm5hbWUuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm1hcC5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYubWF0aC5hY29zaC5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYubWF0aC5hc2luaC5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYubWF0aC5hdGFuaC5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYubWF0aC5jYnJ0LmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5tYXRoLmNsejMyLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5tYXRoLmNvc2guanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm1hdGguZXhwbTEuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm1hdGguZnJvdW5kLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5tYXRoLmh5cG90LmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5tYXRoLmltdWwuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm1hdGgubG9nMTAuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm1hdGgubG9nMXAuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm1hdGgubG9nMi5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYubWF0aC5zaWduLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5tYXRoLnNpbmguanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm1hdGgudGFuaC5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYubWF0aC50cnVuYy5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYubnVtYmVyLmNvbnN0cnVjdG9yLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5udW1iZXIuZXBzaWxvbi5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYubnVtYmVyLmlzLWZpbml0ZS5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYubnVtYmVyLmlzLWludGVnZXIuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm51bWJlci5pcy1uYW4uanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm51bWJlci5pcy1zYWZlLWludGVnZXIuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm51bWJlci5tYXgtc2FmZS1pbnRlZ2VyLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5udW1iZXIubWluLXNhZmUtaW50ZWdlci5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYubnVtYmVyLnBhcnNlLWZsb2F0LmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5udW1iZXIucGFyc2UtaW50LmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5udW1iZXIudG8tZml4ZWQuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm51bWJlci50by1wcmVjaXNpb24uanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm9iamVjdC5hc3NpZ24uanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm9iamVjdC5jcmVhdGUuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm9iamVjdC5kZWZpbmUtcHJvcGVydGllcy5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYub2JqZWN0LmRlZmluZS1wcm9wZXJ0eS5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYub2JqZWN0LmZyZWV6ZS5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYub2JqZWN0LmdldC1vd24tcHJvcGVydHktZGVzY3JpcHRvci5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYub2JqZWN0LmdldC1vd24tcHJvcGVydHktbmFtZXMuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm9iamVjdC5nZXQtcHJvdG90eXBlLW9mLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5vYmplY3QuaXMtZXh0ZW5zaWJsZS5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYub2JqZWN0LmlzLWZyb3plbi5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYub2JqZWN0LmlzLXNlYWxlZC5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYub2JqZWN0LmlzLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5vYmplY3Qua2V5cy5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYub2JqZWN0LnByZXZlbnQtZXh0ZW5zaW9ucy5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYub2JqZWN0LnNlYWwuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2Lm9iamVjdC5zZXQtcHJvdG90eXBlLW9mLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5vYmplY3QudG8tc3RyaW5nLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5wYXJzZS1mbG9hdC5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYucGFyc2UtaW50LmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5wcm9taXNlLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5yZWZsZWN0LmFwcGx5LmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5yZWZsZWN0LmNvbnN0cnVjdC5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYucmVmbGVjdC5kZWZpbmUtcHJvcGVydHkuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnJlZmxlY3QuZGVsZXRlLXByb3BlcnR5LmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5yZWZsZWN0LmVudW1lcmF0ZS5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYucmVmbGVjdC5nZXQtb3duLXByb3BlcnR5LWRlc2NyaXB0b3IuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnJlZmxlY3QuZ2V0LXByb3RvdHlwZS1vZi5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYucmVmbGVjdC5nZXQuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnJlZmxlY3QuaGFzLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5yZWZsZWN0LmlzLWV4dGVuc2libGUuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnJlZmxlY3Qub3duLWtleXMuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnJlZmxlY3QucHJldmVudC1leHRlbnNpb25zLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5yZWZsZWN0LnNldC1wcm90b3R5cGUtb2YuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnJlZmxlY3Quc2V0LmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5yZWdleHAuY29uc3RydWN0b3IuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnJlZ2V4cC5mbGFncy5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYucmVnZXhwLm1hdGNoLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5yZWdleHAucmVwbGFjZS5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYucmVnZXhwLnNlYXJjaC5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYucmVnZXhwLnNwbGl0LmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5yZWdleHAudG8tc3RyaW5nLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5zZXQuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnN0cmluZy5hbmNob3IuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnN0cmluZy5iaWcuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnN0cmluZy5ibGluay5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuc3RyaW5nLmJvbGQuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnN0cmluZy5jb2RlLXBvaW50LWF0LmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5zdHJpbmcuZW5kcy13aXRoLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5zdHJpbmcuZml4ZWQuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnN0cmluZy5mb250Y29sb3IuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnN0cmluZy5mb250c2l6ZS5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuc3RyaW5nLmZyb20tY29kZS1wb2ludC5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuc3RyaW5nLmluY2x1ZGVzLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5zdHJpbmcuaXRhbGljcy5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuc3RyaW5nLml0ZXJhdG9yLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5zdHJpbmcubGluay5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuc3RyaW5nLnJhdy5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuc3RyaW5nLnJlcGVhdC5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYuc3RyaW5nLnNtYWxsLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5zdHJpbmcuc3RhcnRzLXdpdGguanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnN0cmluZy5zdHJpa2UuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnN0cmluZy5zdWIuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnN0cmluZy5zdXAuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnN0cmluZy50cmltLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi5zeW1ib2wuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnR5cGVkLmFycmF5LWJ1ZmZlci5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYudHlwZWQuZGF0YS12aWV3LmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi50eXBlZC5mbG9hdDMyLWFycmF5LmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi50eXBlZC5mbG9hdDY0LWFycmF5LmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi50eXBlZC5pbnQxNi1hcnJheS5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYudHlwZWQuaW50MzItYXJyYXkuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnR5cGVkLmludDgtYXJyYXkuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LnR5cGVkLnVpbnQxNi1hcnJheS5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYudHlwZWQudWludDMyLWFycmF5LmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNi50eXBlZC51aW50OC1hcnJheS5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYudHlwZWQudWludDgtY2xhbXBlZC1hcnJheS5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczYud2Vhay1tYXAuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM2LndlYWstc2V0LmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNy5hcnJheS5pbmNsdWRlcy5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy9lczcub2JqZWN0LmVudHJpZXMuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM3Lm9iamVjdC5nZXQtb3duLXByb3BlcnR5LWRlc2NyaXB0b3JzLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNy5vYmplY3QudmFsdWVzLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNy5wcm9taXNlLmZpbmFsbHkuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvZXM3LnN0cmluZy5wYWQtZW5kLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNy5zdHJpbmcucGFkLXN0YXJ0LmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL2VzNy5zeW1ib2wuYXN5bmMtaXRlcmF0b3IuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL21vZHVsZXMvd2ViLmRvbS5pdGVyYWJsZS5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL2NvcmUtanMvbW9kdWxlcy93ZWIuaW1tZWRpYXRlLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9wb2x5ZmlsbC9ub2RlX21vZHVsZXMvY29yZS1qcy9tb2R1bGVzL3dlYi50aW1lcnMuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3BvbHlmaWxsL25vZGVfbW9kdWxlcy9jb3JlLWpzL3dlYi9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcG9seWZpbGwvbm9kZV9tb2R1bGVzL3JlZ2VuZXJhdG9yLXJ1bnRpbWUvcnVudGltZS5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcnVudGltZS9oZWxwZXJzL2FwcGx5RGVjb3JhdGVkRGVzY3JpcHRvci5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcnVudGltZS9oZWxwZXJzL2FycmF5V2l0aEhvbGVzLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9ydW50aW1lL2hlbHBlcnMvYXJyYXlXaXRob3V0SG9sZXMuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3J1bnRpbWUvaGVscGVycy9hc3NlcnRUaGlzSW5pdGlhbGl6ZWQuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3J1bnRpbWUvaGVscGVycy9hc3luY1RvR2VuZXJhdG9yLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9ydW50aW1lL2hlbHBlcnMvY2xhc3NDYWxsQ2hlY2suanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3J1bnRpbWUvaGVscGVycy9jb25zdHJ1Y3QuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3J1bnRpbWUvaGVscGVycy9jcmVhdGVDbGFzcy5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcnVudGltZS9oZWxwZXJzL2RlZmluZVByb3BlcnR5LmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9ydW50aW1lL2hlbHBlcnMvZ2V0UHJvdG90eXBlT2YuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3J1bnRpbWUvaGVscGVycy9pbmhlcml0cy5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcnVudGltZS9oZWxwZXJzL2ludGVyb3BSZXF1aXJlRGVmYXVsdC5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcnVudGltZS9oZWxwZXJzL2ludGVyb3BSZXF1aXJlV2lsZGNhcmQuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3J1bnRpbWUvaGVscGVycy9pc05hdGl2ZUZ1bmN0aW9uLmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9ydW50aW1lL2hlbHBlcnMvaXRlcmFibGVUb0FycmF5LmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9ydW50aW1lL2hlbHBlcnMvaXRlcmFibGVUb0FycmF5TGltaXQuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3J1bnRpbWUvaGVscGVycy9ub25JdGVyYWJsZVJlc3QuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3J1bnRpbWUvaGVscGVycy9ub25JdGVyYWJsZVNwcmVhZC5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcnVudGltZS9oZWxwZXJzL29iamVjdFNwcmVhZC5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcnVudGltZS9oZWxwZXJzL3Bvc3NpYmxlQ29uc3RydWN0b3JSZXR1cm4uanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3J1bnRpbWUvaGVscGVycy9zZXRQcm90b3R5cGVPZi5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcnVudGltZS9oZWxwZXJzL3NsaWNlZFRvQXJyYXkuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3J1bnRpbWUvaGVscGVycy90b0FycmF5LmpzIiwibm9kZV9tb2R1bGVzL0BiYWJlbC9ydW50aW1lL2hlbHBlcnMvdG9Db25zdW1hYmxlQXJyYXkuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3J1bnRpbWUvaGVscGVycy90eXBlb2YuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3J1bnRpbWUvaGVscGVycy93cmFwTmF0aXZlU3VwZXIuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3J1bnRpbWUvbm9kZV9tb2R1bGVzL3JlZ2VuZXJhdG9yLXJ1bnRpbWUvcnVudGltZS1tb2R1bGUuanMiLCJub2RlX21vZHVsZXMvQGJhYmVsL3J1bnRpbWUvbm9kZV9tb2R1bGVzL3JlZ2VuZXJhdG9yLXJ1bnRpbWUvcnVudGltZS5qcyIsIm5vZGVfbW9kdWxlcy9AYmFiZWwvcnVudGltZS9yZWdlbmVyYXRvci9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9ldmVudHMvZXZlbnRzLmpzIiwibm9kZV9tb2R1bGVzL2tpbnRvLWh0dHAvbGliL2Jhc2UuanMiLCJub2RlX21vZHVsZXMva2ludG8taHR0cC9saWIvYmF0Y2guanMiLCJub2RlX21vZHVsZXMva2ludG8taHR0cC9saWIvYnVja2V0LmpzIiwibm9kZV9tb2R1bGVzL2tpbnRvLWh0dHAvbGliL2NvbGxlY3Rpb24uanMiLCJub2RlX21vZHVsZXMva2ludG8taHR0cC9saWIvZW5kcG9pbnQuanMiLCJub2RlX21vZHVsZXMva2ludG8taHR0cC9saWIvZXJyb3JzLmpzIiwibm9kZV9tb2R1bGVzL2tpbnRvLWh0dHAvbGliL2h0dHAuanMiLCJub2RlX21vZHVsZXMva2ludG8taHR0cC9saWIvaW5kZXguanMiLCJub2RlX21vZHVsZXMva2ludG8taHR0cC9saWIvcmVxdWVzdHMuanMiLCJub2RlX21vZHVsZXMva2ludG8taHR0cC9saWIvdXRpbHMuanMiLCJub2RlX21vZHVsZXMvdXVpZC9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy91dWlkL2xpYi9ieXRlc1RvVXVpZC5qcyIsIm5vZGVfbW9kdWxlcy91dWlkL2xpYi9ybmctYnJvd3Nlci5qcyIsIm5vZGVfbW9kdWxlcy91dWlkL3YxLmpzIiwibm9kZV9tb2R1bGVzL3V1aWQvdjQuanMiLCJzcmMvS2ludG9CYXNlLmpzIiwic3JjL2FkYXB0ZXJzL0lEQi5qcyIsInNyYy9hZGFwdGVycy9iYXNlLmpzIiwic3JjL2NvbGxlY3Rpb24uanMiLCJzcmMvaW5kZXguanMiLCJzcmMvdXRpbHMuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7O0FDQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQzVCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxSUE7QUFDQTtBQUNBOztBQ0ZBO0FBQ0E7QUFDQTs7QUNGQTtBQUNBO0FBQ0E7O0FDRkE7QUFDQTtBQUNBOztBQ0ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDSkE7QUFDQTtBQUNBOztBQ0ZBO0FBQ0E7QUFDQTs7QUNGQTtBQUNBO0FBQ0E7O0FDRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDTEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNQQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDTEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ0xBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDZkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ05BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDekJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ0xBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JGQTtBQUNBO0FBQ0E7O0FDRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNUQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDTEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1BBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDSkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDZkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMzQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDWkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNQQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDekJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ05BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDSkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1JBO0FBQ0E7QUFDQTs7QUNGQTtBQUNBO0FBQ0E7QUFDQTs7QUNIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNUQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNOQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDUkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ0xBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ05BO0FBQ0E7QUFDQTtBQUNBOztBQ0hBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNSQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNaQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3RCQTtBQUNBO0FBQ0E7QUFDQTs7QUNIQTtBQUNBOztBQ0RBO0FBQ0E7O0FDREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNWQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdkJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDSkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ0xBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDekNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDYkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNQQTtBQUNBOztBQ0RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDYkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1BBO0FBQ0E7O0FDREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNWQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNSQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNUQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1BBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1pBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNSQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDTEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ0xBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDekJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDYkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNQQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDTEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDWkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDVEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDVEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDUkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDWkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDOUJBO0FBQ0E7QUFDQTs7QUNGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNQQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ05BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ05BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ05BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNMQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNaQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoZUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcFJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNMQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ0pBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNMQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNUQTtBQUNBOztBQ0RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNYQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDUkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDTkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNWQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNOQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNkQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDZEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1hBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDSkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDWkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNWQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25CQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDVkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNWQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdkJBO0FBQ0E7O0FDREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDUkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNaQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ0pBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDYkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDVkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNWQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNUQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDUkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDVEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ0xBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDSkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDUkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDUkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNmQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNaQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDUkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDSkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDVEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNUQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDSkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ0pBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDSkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbEhBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ0pBO0FBQ0E7QUFDQTtBQUNBOztBQ0hBO0FBQ0E7QUFDQTtBQUNBOztBQ0hBO0FBQ0E7QUFDQTtBQUNBOztBQ0hBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDSkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDVEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNSQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDUkE7QUFDQTtBQUNBO0FBQ0E7O0FDSEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDVEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDVEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDVEE7QUFDQTtBQUNBO0FBQ0E7O0FDSEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNWQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ0pBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDSkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM5UkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQy9DQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdkJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNYQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDMUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDVkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNWQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNYQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ0pBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDTEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNWQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNaQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2RUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDUEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNQQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1BBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDUEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDVEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1BBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDUEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNQQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdkJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1pBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDUEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1BBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNOQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1BBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1BBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDUEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNQQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1BBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFPQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzlDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ0pBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNMQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDTEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ0xBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNMQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDTEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ0xBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNMQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDTEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ0xBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMzREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1pBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDWkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDWkE7QUFDQTs7QUNEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNOQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDSkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2dEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNSQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDTkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNmQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1BBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDTkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ0pBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ0pBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNaQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNUQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDVkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNWQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqdEJBO0FBQ0E7O0FDREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMzZ0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsMENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM5REE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNpQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDandDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3T0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyWEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQy9DQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4TkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDamdCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDUkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDN0dBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7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LEtBQUssSUFBVixFQUFnQjtBQUNkLGFBQVEsR0FBRyxDQUFDLEVBQUQsQ0FBSCxHQUFVLEdBQWxCO0FBQ0QsS0FGRCxNQUVPLElBQUksTUFBTSxDQUFDLFNBQVAsQ0FBaUIsY0FBakIsQ0FBZ0MsSUFBaEMsQ0FBcUMsR0FBckMsRUFBMEMsRUFBMUMsQ0FBSixFQUFtRDtBQUN4RCxhQUFPLEdBQUcsQ0FBQyxFQUFELENBQVY7QUFDRCxLQUZNLE1BRUE7QUFDTCxhQUFRLEdBQUcsQ0FBQyxFQUFELENBQUgsR0FBVSxFQUFsQjtBQUNEO0FBQ0YsR0FSTSxFQVFKLGdCQVJJLENBQVA7QUFTRDs7QUFFTSxTQUFTLHlCQUFULENBQW1DLFVBQW5DLEVBQStDO0FBQ3BELE1BQU0sa0JBQWtCLEdBQUcsRUFBM0I7O0FBQ0EsT0FBSyxJQUFNLEdBQVgsSUFBa0IsVUFBbEIsRUFBOEI7QUFDNUIsUUFBTSxPQUFPLEdBQUcsR0FBRyxDQUFDLEtBQUosQ0FBVSxHQUFWLENBQWhCO0FBQ0EsUUFBTSxHQUFHLEdBQUcsVUFBVSxDQUFDLEdBQUQsQ0FBdEI7QUFDQSxJQUFBLHVCQUF1QixDQUFDLE9BQUQsRUFBVSxHQUFWLEVBQWUsa0JBQWYsQ0FBdkI7QUFDRDs7QUFDRCxTQUFPLGtCQUFQO0FBQ0QiLCJmaWxlIjoiZ2VuZXJhdGVkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXNDb250ZW50IjpbIihmdW5jdGlvbigpe2Z1bmN0aW9uIHIoZSxuLHQpe2Z1bmN0aW9uIG8oaSxmKXtpZighbltpXSl7aWYoIWVbaV0pe3ZhciBjPVwiZnVuY3Rpb25cIj09dHlwZW9mIHJlcXVpcmUmJnJlcXVpcmU7aWYoIWYmJmMpcmV0dXJuIGMoaSwhMCk7aWYodSlyZXR1cm4gdShpLCEwKTt2YXIgYT1uZXcgRXJyb3IoXCJDYW5ub3QgZmluZCBtb2R1bGUgJ1wiK2krXCInXCIpO3Rocm93IGEuY29kZT1cIk1PRFVMRV9OT1RfRk9VTkRcIixhfXZhciBwPW5baV09e2V4cG9ydHM6e319O2VbaV1bMF0uY2FsbChwLmV4cG9ydHMsZnVuY3Rpb24ocil7dmFyIG49ZVtpXVsxXVtyXTtyZXR1cm4gbyhufHxyKX0scCxwLmV4cG9ydHMscixlLG4sdCl9cmV0dXJuIG5baV0uZXhwb3J0c31mb3IodmFyIHU9XCJmdW5jdGlvblwiPT10eXBlb2YgcmVxdWlyZSYmcmVxdWlyZSxpPTA7aTx0Lmxlbmd0aDtpKyspbyh0W2ldKTtyZXR1cm4gb31yZXR1cm4gcn0pKCkiLCJcInVzZSBzdHJpY3RcIjtcblxucmVxdWlyZShcImNvcmUtanMvZXM2XCIpO1xuXG5yZXF1aXJlKFwiY29yZS1qcy9mbi9hcnJheS9pbmNsdWRlc1wiKTtcblxucmVxdWlyZShcImNvcmUtanMvZm4vc3RyaW5nL3BhZC1zdGFydFwiKTtcblxucmVxdWlyZShcImNvcmUtanMvZm4vc3RyaW5nL3BhZC1lbmRcIik7XG5cbnJlcXVpcmUoXCJjb3JlLWpzL2ZuL3N5bWJvbC9hc3luYy1pdGVyYXRvclwiKTtcblxucmVxdWlyZShcImNvcmUtanMvZm4vb2JqZWN0L2dldC1vd24tcHJvcGVydHktZGVzY3JpcHRvcnNcIik7XG5cbnJlcXVpcmUoXCJjb3JlLWpzL2ZuL29iamVjdC92YWx1ZXNcIik7XG5cbnJlcXVpcmUoXCJjb3JlLWpzL2ZuL29iamVjdC9lbnRyaWVzXCIpO1xuXG5yZXF1aXJlKFwiY29yZS1qcy9mbi9wcm9taXNlL2ZpbmFsbHlcIik7XG5cbnJlcXVpcmUoXCJjb3JlLWpzL3dlYlwiKTtcblxucmVxdWlyZShcInJlZ2VuZXJhdG9yLXJ1bnRpbWUvcnVudGltZVwiKTtcblxuaWYgKGdsb2JhbC5fYmFiZWxQb2x5ZmlsbCAmJiB0eXBlb2YgY29uc29sZSAhPT0gXCJ1bmRlZmluZWRcIiAmJiBjb25zb2xlLndhcm4pIHtcbiAgY29uc29sZS53YXJuKFwiQGJhYmVsL3BvbHlmaWxsIGlzIGxvYWRlZCBtb3JlIHRoYW4gb25jZSBvbiB0aGlzIHBhZ2UuIFRoaXMgaXMgcHJvYmFibHkgbm90IGRlc2lyYWJsZS9pbnRlbmRlZCBcIiArIFwiYW5kIG1heSBoYXZlIGNvbnNlcXVlbmNlcyBpZiBkaWZmZXJlbnQgdmVyc2lvbnMgb2YgdGhlIHBvbHlmaWxscyBhcmUgYXBwbGllZCBzZXF1ZW50aWFsbHkuIFwiICsgXCJJZiB5b3UgZG8gbmVlZCB0byBsb2FkIHRoZSBwb2x5ZmlsbCBtb3JlIHRoYW4gb25jZSwgdXNlIEBiYWJlbC9wb2x5ZmlsbC9ub0NvbmZsaWN0IFwiICsgXCJpbnN0ZWFkIHRvIGJ5cGFzcyB0aGUgd2FybmluZy5cIik7XG59XG5cbmdsb2JhbC5fYmFiZWxQb2x5ZmlsbCA9IHRydWU7IiwicmVxdWlyZSgnLi4vbW9kdWxlcy9lczYuc3ltYm9sJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5vYmplY3QuY3JlYXRlJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5vYmplY3QuZGVmaW5lLXByb3BlcnR5Jyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5vYmplY3QuZGVmaW5lLXByb3BlcnRpZXMnKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2Lm9iamVjdC5nZXQtb3duLXByb3BlcnR5LWRlc2NyaXB0b3InKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2Lm9iamVjdC5nZXQtcHJvdG90eXBlLW9mJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5vYmplY3Qua2V5cycpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYub2JqZWN0LmdldC1vd24tcHJvcGVydHktbmFtZXMnKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2Lm9iamVjdC5mcmVlemUnKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2Lm9iamVjdC5zZWFsJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5vYmplY3QucHJldmVudC1leHRlbnNpb25zJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5vYmplY3QuaXMtZnJvemVuJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5vYmplY3QuaXMtc2VhbGVkJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5vYmplY3QuaXMtZXh0ZW5zaWJsZScpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYub2JqZWN0LmFzc2lnbicpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYub2JqZWN0LmlzJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5vYmplY3Quc2V0LXByb3RvdHlwZS1vZicpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYub2JqZWN0LnRvLXN0cmluZycpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYuZnVuY3Rpb24uYmluZCcpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYuZnVuY3Rpb24ubmFtZScpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYuZnVuY3Rpb24uaGFzLWluc3RhbmNlJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5wYXJzZS1pbnQnKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2LnBhcnNlLWZsb2F0Jyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5udW1iZXIuY29uc3RydWN0b3InKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2Lm51bWJlci50by1maXhlZCcpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYubnVtYmVyLnRvLXByZWNpc2lvbicpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYubnVtYmVyLmVwc2lsb24nKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2Lm51bWJlci5pcy1maW5pdGUnKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2Lm51bWJlci5pcy1pbnRlZ2VyJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5udW1iZXIuaXMtbmFuJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5udW1iZXIuaXMtc2FmZS1pbnRlZ2VyJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5udW1iZXIubWF4LXNhZmUtaW50ZWdlcicpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYubnVtYmVyLm1pbi1zYWZlLWludGVnZXInKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2Lm51bWJlci5wYXJzZS1mbG9hdCcpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYubnVtYmVyLnBhcnNlLWludCcpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYubWF0aC5hY29zaCcpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYubWF0aC5hc2luaCcpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYubWF0aC5hdGFuaCcpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYubWF0aC5jYnJ0Jyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5tYXRoLmNsejMyJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5tYXRoLmNvc2gnKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2Lm1hdGguZXhwbTEnKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2Lm1hdGguZnJvdW5kJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5tYXRoLmh5cG90Jyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5tYXRoLmltdWwnKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2Lm1hdGgubG9nMTAnKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2Lm1hdGgubG9nMXAnKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2Lm1hdGgubG9nMicpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYubWF0aC5zaWduJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5tYXRoLnNpbmgnKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2Lm1hdGgudGFuaCcpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYubWF0aC50cnVuYycpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYuc3RyaW5nLmZyb20tY29kZS1wb2ludCcpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYuc3RyaW5nLnJhdycpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYuc3RyaW5nLnRyaW0nKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2LnN0cmluZy5pdGVyYXRvcicpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYuc3RyaW5nLmNvZGUtcG9pbnQtYXQnKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2LnN0cmluZy5lbmRzLXdpdGgnKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2LnN0cmluZy5pbmNsdWRlcycpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYuc3RyaW5nLnJlcGVhdCcpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYuc3RyaW5nLnN0YXJ0cy13aXRoJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5zdHJpbmcuYW5jaG9yJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5zdHJpbmcuYmlnJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5zdHJpbmcuYmxpbmsnKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2LnN0cmluZy5ib2xkJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5zdHJpbmcuZml4ZWQnKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2LnN0cmluZy5mb250Y29sb3InKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2LnN0cmluZy5mb250c2l6ZScpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYuc3RyaW5nLml0YWxpY3MnKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2LnN0cmluZy5saW5rJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5zdHJpbmcuc21hbGwnKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2LnN0cmluZy5zdHJpa2UnKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2LnN0cmluZy5zdWInKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2LnN0cmluZy5zdXAnKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2LmRhdGUubm93Jyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5kYXRlLnRvLWpzb24nKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2LmRhdGUudG8taXNvLXN0cmluZycpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYuZGF0ZS50by1zdHJpbmcnKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2LmRhdGUudG8tcHJpbWl0aXZlJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5hcnJheS5pcy1hcnJheScpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYuYXJyYXkuZnJvbScpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYuYXJyYXkub2YnKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2LmFycmF5LmpvaW4nKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2LmFycmF5LnNsaWNlJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5hcnJheS5zb3J0Jyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5hcnJheS5mb3ItZWFjaCcpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYuYXJyYXkubWFwJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5hcnJheS5maWx0ZXInKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2LmFycmF5LnNvbWUnKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2LmFycmF5LmV2ZXJ5Jyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5hcnJheS5yZWR1Y2UnKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2LmFycmF5LnJlZHVjZS1yaWdodCcpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYuYXJyYXkuaW5kZXgtb2YnKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2LmFycmF5Lmxhc3QtaW5kZXgtb2YnKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2LmFycmF5LmNvcHktd2l0aGluJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5hcnJheS5maWxsJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5hcnJheS5maW5kJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5hcnJheS5maW5kLWluZGV4Jyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5hcnJheS5zcGVjaWVzJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5hcnJheS5pdGVyYXRvcicpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYucmVnZXhwLmNvbnN0cnVjdG9yJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5yZWdleHAudG8tc3RyaW5nJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5yZWdleHAuZmxhZ3MnKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2LnJlZ2V4cC5tYXRjaCcpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYucmVnZXhwLnJlcGxhY2UnKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2LnJlZ2V4cC5zZWFyY2gnKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2LnJlZ2V4cC5zcGxpdCcpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYucHJvbWlzZScpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYubWFwJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5zZXQnKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2LndlYWstbWFwJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi53ZWFrLXNldCcpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYudHlwZWQuYXJyYXktYnVmZmVyJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi50eXBlZC5kYXRhLXZpZXcnKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2LnR5cGVkLmludDgtYXJyYXknKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2LnR5cGVkLnVpbnQ4LWFycmF5Jyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi50eXBlZC51aW50OC1jbGFtcGVkLWFycmF5Jyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi50eXBlZC5pbnQxNi1hcnJheScpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYudHlwZWQudWludDE2LWFycmF5Jyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi50eXBlZC5pbnQzMi1hcnJheScpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYudHlwZWQudWludDMyLWFycmF5Jyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi50eXBlZC5mbG9hdDMyLWFycmF5Jyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi50eXBlZC5mbG9hdDY0LWFycmF5Jyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5yZWZsZWN0LmFwcGx5Jyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5yZWZsZWN0LmNvbnN0cnVjdCcpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYucmVmbGVjdC5kZWZpbmUtcHJvcGVydHknKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2LnJlZmxlY3QuZGVsZXRlLXByb3BlcnR5Jyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5yZWZsZWN0LmVudW1lcmF0ZScpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYucmVmbGVjdC5nZXQnKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2LnJlZmxlY3QuZ2V0LW93bi1wcm9wZXJ0eS1kZXNjcmlwdG9yJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5yZWZsZWN0LmdldC1wcm90b3R5cGUtb2YnKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2LnJlZmxlY3QuaGFzJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5yZWZsZWN0LmlzLWV4dGVuc2libGUnKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2LnJlZmxlY3Qub3duLWtleXMnKTtcbnJlcXVpcmUoJy4uL21vZHVsZXMvZXM2LnJlZmxlY3QucHJldmVudC1leHRlbnNpb25zJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL2VzNi5yZWZsZWN0LnNldCcpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy9lczYucmVmbGVjdC5zZXQtcHJvdG90eXBlLW9mJyk7XG5tb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4uL21vZHVsZXMvX2NvcmUnKTtcbiIsInJlcXVpcmUoJy4uLy4uL21vZHVsZXMvZXM3LmFycmF5LmluY2x1ZGVzJyk7XG5tb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4uLy4uL21vZHVsZXMvX2NvcmUnKS5BcnJheS5pbmNsdWRlcztcbiIsInJlcXVpcmUoJy4uLy4uL21vZHVsZXMvZXM3Lm9iamVjdC5lbnRyaWVzJyk7XG5tb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4uLy4uL21vZHVsZXMvX2NvcmUnKS5PYmplY3QuZW50cmllcztcbiIsInJlcXVpcmUoJy4uLy4uL21vZHVsZXMvZXM3Lm9iamVjdC5nZXQtb3duLXByb3BlcnR5LWRlc2NyaXB0b3JzJyk7XG5tb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4uLy4uL21vZHVsZXMvX2NvcmUnKS5PYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9ycztcbiIsInJlcXVpcmUoJy4uLy4uL21vZHVsZXMvZXM3Lm9iamVjdC52YWx1ZXMnKTtcbm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi4vLi4vbW9kdWxlcy9fY29yZScpLk9iamVjdC52YWx1ZXM7XG4iLCIndXNlIHN0cmljdCc7XG5yZXF1aXJlKCcuLi8uLi9tb2R1bGVzL2VzNi5wcm9taXNlJyk7XG5yZXF1aXJlKCcuLi8uLi9tb2R1bGVzL2VzNy5wcm9taXNlLmZpbmFsbHknKTtcbm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi4vLi4vbW9kdWxlcy9fY29yZScpLlByb21pc2VbJ2ZpbmFsbHknXTtcbiIsInJlcXVpcmUoJy4uLy4uL21vZHVsZXMvZXM3LnN0cmluZy5wYWQtZW5kJyk7XG5tb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4uLy4uL21vZHVsZXMvX2NvcmUnKS5TdHJpbmcucGFkRW5kO1xuIiwicmVxdWlyZSgnLi4vLi4vbW9kdWxlcy9lczcuc3RyaW5nLnBhZC1zdGFydCcpO1xubW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuLi8uLi9tb2R1bGVzL19jb3JlJykuU3RyaW5nLnBhZFN0YXJ0O1xuIiwicmVxdWlyZSgnLi4vLi4vbW9kdWxlcy9lczcuc3ltYm9sLmFzeW5jLWl0ZXJhdG9yJyk7XG5tb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4uLy4uL21vZHVsZXMvX3drcy1leHQnKS5mKCdhc3luY0l0ZXJhdG9yJyk7XG4iLCJtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChpdCkge1xuICBpZiAodHlwZW9mIGl0ICE9ICdmdW5jdGlvbicpIHRocm93IFR5cGVFcnJvcihpdCArICcgaXMgbm90IGEgZnVuY3Rpb24hJyk7XG4gIHJldHVybiBpdDtcbn07XG4iLCJ2YXIgY29mID0gcmVxdWlyZSgnLi9fY29mJyk7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChpdCwgbXNnKSB7XG4gIGlmICh0eXBlb2YgaXQgIT0gJ251bWJlcicgJiYgY29mKGl0KSAhPSAnTnVtYmVyJykgdGhyb3cgVHlwZUVycm9yKG1zZyk7XG4gIHJldHVybiAraXQ7XG59O1xuIiwiLy8gMjIuMS4zLjMxIEFycmF5LnByb3RvdHlwZVtAQHVuc2NvcGFibGVzXVxudmFyIFVOU0NPUEFCTEVTID0gcmVxdWlyZSgnLi9fd2tzJykoJ3Vuc2NvcGFibGVzJyk7XG52YXIgQXJyYXlQcm90byA9IEFycmF5LnByb3RvdHlwZTtcbmlmIChBcnJheVByb3RvW1VOU0NPUEFCTEVTXSA9PSB1bmRlZmluZWQpIHJlcXVpcmUoJy4vX2hpZGUnKShBcnJheVByb3RvLCBVTlNDT1BBQkxFUywge30pO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoa2V5KSB7XG4gIEFycmF5UHJvdG9bVU5TQ09QQUJMRVNdW2tleV0gPSB0cnVlO1xufTtcbiIsIm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGl0LCBDb25zdHJ1Y3RvciwgbmFtZSwgZm9yYmlkZGVuRmllbGQpIHtcbiAgaWYgKCEoaXQgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikgfHwgKGZvcmJpZGRlbkZpZWxkICE9PSB1bmRlZmluZWQgJiYgZm9yYmlkZGVuRmllbGQgaW4gaXQpKSB7XG4gICAgdGhyb3cgVHlwZUVycm9yKG5hbWUgKyAnOiBpbmNvcnJlY3QgaW52b2NhdGlvbiEnKTtcbiAgfSByZXR1cm4gaXQ7XG59O1xuIiwidmFyIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi9faXMtb2JqZWN0Jyk7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChpdCkge1xuICBpZiAoIWlzT2JqZWN0KGl0KSkgdGhyb3cgVHlwZUVycm9yKGl0ICsgJyBpcyBub3QgYW4gb2JqZWN0IScpO1xuICByZXR1cm4gaXQ7XG59O1xuIiwiLy8gMjIuMS4zLjMgQXJyYXkucHJvdG90eXBlLmNvcHlXaXRoaW4odGFyZ2V0LCBzdGFydCwgZW5kID0gdGhpcy5sZW5ndGgpXG4ndXNlIHN0cmljdCc7XG52YXIgdG9PYmplY3QgPSByZXF1aXJlKCcuL190by1vYmplY3QnKTtcbnZhciB0b0Fic29sdXRlSW5kZXggPSByZXF1aXJlKCcuL190by1hYnNvbHV0ZS1pbmRleCcpO1xudmFyIHRvTGVuZ3RoID0gcmVxdWlyZSgnLi9fdG8tbGVuZ3RoJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gW10uY29weVdpdGhpbiB8fCBmdW5jdGlvbiBjb3B5V2l0aGluKHRhcmdldCAvKiA9IDAgKi8sIHN0YXJ0IC8qID0gMCwgZW5kID0gQGxlbmd0aCAqLykge1xuICB2YXIgTyA9IHRvT2JqZWN0KHRoaXMpO1xuICB2YXIgbGVuID0gdG9MZW5ndGgoTy5sZW5ndGgpO1xuICB2YXIgdG8gPSB0b0Fic29sdXRlSW5kZXgodGFyZ2V0LCBsZW4pO1xuICB2YXIgZnJvbSA9IHRvQWJzb2x1dGVJbmRleChzdGFydCwgbGVuKTtcbiAgdmFyIGVuZCA9IGFyZ3VtZW50cy5sZW5ndGggPiAyID8gYXJndW1lbnRzWzJdIDogdW5kZWZpbmVkO1xuICB2YXIgY291bnQgPSBNYXRoLm1pbigoZW5kID09PSB1bmRlZmluZWQgPyBsZW4gOiB0b0Fic29sdXRlSW5kZXgoZW5kLCBsZW4pKSAtIGZyb20sIGxlbiAtIHRvKTtcbiAgdmFyIGluYyA9IDE7XG4gIGlmIChmcm9tIDwgdG8gJiYgdG8gPCBmcm9tICsgY291bnQpIHtcbiAgICBpbmMgPSAtMTtcbiAgICBmcm9tICs9IGNvdW50IC0gMTtcbiAgICB0byArPSBjb3VudCAtIDE7XG4gIH1cbiAgd2hpbGUgKGNvdW50LS0gPiAwKSB7XG4gICAgaWYgKGZyb20gaW4gTykgT1t0b10gPSBPW2Zyb21dO1xuICAgIGVsc2UgZGVsZXRlIE9bdG9dO1xuICAgIHRvICs9IGluYztcbiAgICBmcm9tICs9IGluYztcbiAgfSByZXR1cm4gTztcbn07XG4iLCIvLyAyMi4xLjMuNiBBcnJheS5wcm90b3R5cGUuZmlsbCh2YWx1ZSwgc3RhcnQgPSAwLCBlbmQgPSB0aGlzLmxlbmd0aClcbid1c2Ugc3RyaWN0JztcbnZhciB0b09iamVjdCA9IHJlcXVpcmUoJy4vX3RvLW9iamVjdCcpO1xudmFyIHRvQWJzb2x1dGVJbmRleCA9IHJlcXVpcmUoJy4vX3RvLWFic29sdXRlLWluZGV4Jyk7XG52YXIgdG9MZW5ndGggPSByZXF1aXJlKCcuL190by1sZW5ndGgnKTtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gZmlsbCh2YWx1ZSAvKiAsIHN0YXJ0ID0gMCwgZW5kID0gQGxlbmd0aCAqLykge1xuICB2YXIgTyA9IHRvT2JqZWN0KHRoaXMpO1xuICB2YXIgbGVuZ3RoID0gdG9MZW5ndGgoTy5sZW5ndGgpO1xuICB2YXIgYUxlbiA9IGFyZ3VtZW50cy5sZW5ndGg7XG4gIHZhciBpbmRleCA9IHRvQWJzb2x1dGVJbmRleChhTGVuID4gMSA/IGFyZ3VtZW50c1sxXSA6IHVuZGVmaW5lZCwgbGVuZ3RoKTtcbiAgdmFyIGVuZCA9IGFMZW4gPiAyID8gYXJndW1lbnRzWzJdIDogdW5kZWZpbmVkO1xuICB2YXIgZW5kUG9zID0gZW5kID09PSB1bmRlZmluZWQgPyBsZW5ndGggOiB0b0Fic29sdXRlSW5kZXgoZW5kLCBsZW5ndGgpO1xuICB3aGlsZSAoZW5kUG9zID4gaW5kZXgpIE9baW5kZXgrK10gPSB2YWx1ZTtcbiAgcmV0dXJuIE87XG59O1xuIiwiLy8gZmFsc2UgLT4gQXJyYXkjaW5kZXhPZlxuLy8gdHJ1ZSAgLT4gQXJyYXkjaW5jbHVkZXNcbnZhciB0b0lPYmplY3QgPSByZXF1aXJlKCcuL190by1pb2JqZWN0Jyk7XG52YXIgdG9MZW5ndGggPSByZXF1aXJlKCcuL190by1sZW5ndGgnKTtcbnZhciB0b0Fic29sdXRlSW5kZXggPSByZXF1aXJlKCcuL190by1hYnNvbHV0ZS1pbmRleCcpO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoSVNfSU5DTFVERVMpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uICgkdGhpcywgZWwsIGZyb21JbmRleCkge1xuICAgIHZhciBPID0gdG9JT2JqZWN0KCR0aGlzKTtcbiAgICB2YXIgbGVuZ3RoID0gdG9MZW5ndGgoTy5sZW5ndGgpO1xuICAgIHZhciBpbmRleCA9IHRvQWJzb2x1dGVJbmRleChmcm9tSW5kZXgsIGxlbmd0aCk7XG4gICAgdmFyIHZhbHVlO1xuICAgIC8vIEFycmF5I2luY2x1ZGVzIHVzZXMgU2FtZVZhbHVlWmVybyBlcXVhbGl0eSBhbGdvcml0aG1cbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tc2VsZi1jb21wYXJlXG4gICAgaWYgKElTX0lOQ0xVREVTICYmIGVsICE9IGVsKSB3aGlsZSAobGVuZ3RoID4gaW5kZXgpIHtcbiAgICAgIHZhbHVlID0gT1tpbmRleCsrXTtcbiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1zZWxmLWNvbXBhcmVcbiAgICAgIGlmICh2YWx1ZSAhPSB2YWx1ZSkgcmV0dXJuIHRydWU7XG4gICAgLy8gQXJyYXkjaW5kZXhPZiBpZ25vcmVzIGhvbGVzLCBBcnJheSNpbmNsdWRlcyAtIG5vdFxuICAgIH0gZWxzZSBmb3IgKDtsZW5ndGggPiBpbmRleDsgaW5kZXgrKykgaWYgKElTX0lOQ0xVREVTIHx8IGluZGV4IGluIE8pIHtcbiAgICAgIGlmIChPW2luZGV4XSA9PT0gZWwpIHJldHVybiBJU19JTkNMVURFUyB8fCBpbmRleCB8fCAwO1xuICAgIH0gcmV0dXJuICFJU19JTkNMVURFUyAmJiAtMTtcbiAgfTtcbn07XG4iLCIvLyAwIC0+IEFycmF5I2ZvckVhY2hcbi8vIDEgLT4gQXJyYXkjbWFwXG4vLyAyIC0+IEFycmF5I2ZpbHRlclxuLy8gMyAtPiBBcnJheSNzb21lXG4vLyA0IC0+IEFycmF5I2V2ZXJ5XG4vLyA1IC0+IEFycmF5I2ZpbmRcbi8vIDYgLT4gQXJyYXkjZmluZEluZGV4XG52YXIgY3R4ID0gcmVxdWlyZSgnLi9fY3R4Jyk7XG52YXIgSU9iamVjdCA9IHJlcXVpcmUoJy4vX2lvYmplY3QnKTtcbnZhciB0b09iamVjdCA9IHJlcXVpcmUoJy4vX3RvLW9iamVjdCcpO1xudmFyIHRvTGVuZ3RoID0gcmVxdWlyZSgnLi9fdG8tbGVuZ3RoJyk7XG52YXIgYXNjID0gcmVxdWlyZSgnLi9fYXJyYXktc3BlY2llcy1jcmVhdGUnKTtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKFRZUEUsICRjcmVhdGUpIHtcbiAgdmFyIElTX01BUCA9IFRZUEUgPT0gMTtcbiAgdmFyIElTX0ZJTFRFUiA9IFRZUEUgPT0gMjtcbiAgdmFyIElTX1NPTUUgPSBUWVBFID09IDM7XG4gIHZhciBJU19FVkVSWSA9IFRZUEUgPT0gNDtcbiAgdmFyIElTX0ZJTkRfSU5ERVggPSBUWVBFID09IDY7XG4gIHZhciBOT19IT0xFUyA9IFRZUEUgPT0gNSB8fCBJU19GSU5EX0lOREVYO1xuICB2YXIgY3JlYXRlID0gJGNyZWF0ZSB8fCBhc2M7XG4gIHJldHVybiBmdW5jdGlvbiAoJHRoaXMsIGNhbGxiYWNrZm4sIHRoYXQpIHtcbiAgICB2YXIgTyA9IHRvT2JqZWN0KCR0aGlzKTtcbiAgICB2YXIgc2VsZiA9IElPYmplY3QoTyk7XG4gICAgdmFyIGYgPSBjdHgoY2FsbGJhY2tmbiwgdGhhdCwgMyk7XG4gICAgdmFyIGxlbmd0aCA9IHRvTGVuZ3RoKHNlbGYubGVuZ3RoKTtcbiAgICB2YXIgaW5kZXggPSAwO1xuICAgIHZhciByZXN1bHQgPSBJU19NQVAgPyBjcmVhdGUoJHRoaXMsIGxlbmd0aCkgOiBJU19GSUxURVIgPyBjcmVhdGUoJHRoaXMsIDApIDogdW5kZWZpbmVkO1xuICAgIHZhciB2YWwsIHJlcztcbiAgICBmb3IgKDtsZW5ndGggPiBpbmRleDsgaW5kZXgrKykgaWYgKE5PX0hPTEVTIHx8IGluZGV4IGluIHNlbGYpIHtcbiAgICAgIHZhbCA9IHNlbGZbaW5kZXhdO1xuICAgICAgcmVzID0gZih2YWwsIGluZGV4LCBPKTtcbiAgICAgIGlmIChUWVBFKSB7XG4gICAgICAgIGlmIChJU19NQVApIHJlc3VsdFtpbmRleF0gPSByZXM7ICAgLy8gbWFwXG4gICAgICAgIGVsc2UgaWYgKHJlcykgc3dpdGNoIChUWVBFKSB7XG4gICAgICAgICAgY2FzZSAzOiByZXR1cm4gdHJ1ZTsgICAgICAgICAgICAgLy8gc29tZVxuICAgICAgICAgIGNhc2UgNTogcmV0dXJuIHZhbDsgICAgICAgICAgICAgIC8vIGZpbmRcbiAgICAgICAgICBjYXNlIDY6IHJldHVybiBpbmRleDsgICAgICAgICAgICAvLyBmaW5kSW5kZXhcbiAgICAgICAgICBjYXNlIDI6IHJlc3VsdC5wdXNoKHZhbCk7ICAgICAgICAvLyBmaWx0ZXJcbiAgICAgICAgfSBlbHNlIGlmIChJU19FVkVSWSkgcmV0dXJuIGZhbHNlOyAvLyBldmVyeVxuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gSVNfRklORF9JTkRFWCA/IC0xIDogSVNfU09NRSB8fCBJU19FVkVSWSA/IElTX0VWRVJZIDogcmVzdWx0O1xuICB9O1xufTtcbiIsInZhciBhRnVuY3Rpb24gPSByZXF1aXJlKCcuL19hLWZ1bmN0aW9uJyk7XG52YXIgdG9PYmplY3QgPSByZXF1aXJlKCcuL190by1vYmplY3QnKTtcbnZhciBJT2JqZWN0ID0gcmVxdWlyZSgnLi9faW9iamVjdCcpO1xudmFyIHRvTGVuZ3RoID0gcmVxdWlyZSgnLi9fdG8tbGVuZ3RoJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKHRoYXQsIGNhbGxiYWNrZm4sIGFMZW4sIG1lbW8sIGlzUmlnaHQpIHtcbiAgYUZ1bmN0aW9uKGNhbGxiYWNrZm4pO1xuICB2YXIgTyA9IHRvT2JqZWN0KHRoYXQpO1xuICB2YXIgc2VsZiA9IElPYmplY3QoTyk7XG4gIHZhciBsZW5ndGggPSB0b0xlbmd0aChPLmxlbmd0aCk7XG4gIHZhciBpbmRleCA9IGlzUmlnaHQgPyBsZW5ndGggLSAxIDogMDtcbiAgdmFyIGkgPSBpc1JpZ2h0ID8gLTEgOiAxO1xuICBpZiAoYUxlbiA8IDIpIGZvciAoOzspIHtcbiAgICBpZiAoaW5kZXggaW4gc2VsZikge1xuICAgICAgbWVtbyA9IHNlbGZbaW5kZXhdO1xuICAgICAgaW5kZXggKz0gaTtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgICBpbmRleCArPSBpO1xuICAgIGlmIChpc1JpZ2h0ID8gaW5kZXggPCAwIDogbGVuZ3RoIDw9IGluZGV4KSB7XG4gICAgICB0aHJvdyBUeXBlRXJyb3IoJ1JlZHVjZSBvZiBlbXB0eSBhcnJheSB3aXRoIG5vIGluaXRpYWwgdmFsdWUnKTtcbiAgICB9XG4gIH1cbiAgZm9yICg7aXNSaWdodCA/IGluZGV4ID49IDAgOiBsZW5ndGggPiBpbmRleDsgaW5kZXggKz0gaSkgaWYgKGluZGV4IGluIHNlbGYpIHtcbiAgICBtZW1vID0gY2FsbGJhY2tmbihtZW1vLCBzZWxmW2luZGV4XSwgaW5kZXgsIE8pO1xuICB9XG4gIHJldHVybiBtZW1vO1xufTtcbiIsInZhciBpc09iamVjdCA9IHJlcXVpcmUoJy4vX2lzLW9iamVjdCcpO1xudmFyIGlzQXJyYXkgPSByZXF1aXJlKCcuL19pcy1hcnJheScpO1xudmFyIFNQRUNJRVMgPSByZXF1aXJlKCcuL193a3MnKSgnc3BlY2llcycpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChvcmlnaW5hbCkge1xuICB2YXIgQztcbiAgaWYgKGlzQXJyYXkob3JpZ2luYWwpKSB7XG4gICAgQyA9IG9yaWdpbmFsLmNvbnN0cnVjdG9yO1xuICAgIC8vIGNyb3NzLXJlYWxtIGZhbGxiYWNrXG4gICAgaWYgKHR5cGVvZiBDID09ICdmdW5jdGlvbicgJiYgKEMgPT09IEFycmF5IHx8IGlzQXJyYXkoQy5wcm90b3R5cGUpKSkgQyA9IHVuZGVmaW5lZDtcbiAgICBpZiAoaXNPYmplY3QoQykpIHtcbiAgICAgIEMgPSBDW1NQRUNJRVNdO1xuICAgICAgaWYgKEMgPT09IG51bGwpIEMgPSB1bmRlZmluZWQ7XG4gICAgfVxuICB9IHJldHVybiBDID09PSB1bmRlZmluZWQgPyBBcnJheSA6IEM7XG59O1xuIiwiLy8gOS40LjIuMyBBcnJheVNwZWNpZXNDcmVhdGUob3JpZ2luYWxBcnJheSwgbGVuZ3RoKVxudmFyIHNwZWNpZXNDb25zdHJ1Y3RvciA9IHJlcXVpcmUoJy4vX2FycmF5LXNwZWNpZXMtY29uc3RydWN0b3InKTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAob3JpZ2luYWwsIGxlbmd0aCkge1xuICByZXR1cm4gbmV3IChzcGVjaWVzQ29uc3RydWN0b3Iob3JpZ2luYWwpKShsZW5ndGgpO1xufTtcbiIsIid1c2Ugc3RyaWN0JztcbnZhciBhRnVuY3Rpb24gPSByZXF1aXJlKCcuL19hLWZ1bmN0aW9uJyk7XG52YXIgaXNPYmplY3QgPSByZXF1aXJlKCcuL19pcy1vYmplY3QnKTtcbnZhciBpbnZva2UgPSByZXF1aXJlKCcuL19pbnZva2UnKTtcbnZhciBhcnJheVNsaWNlID0gW10uc2xpY2U7XG52YXIgZmFjdG9yaWVzID0ge307XG5cbnZhciBjb25zdHJ1Y3QgPSBmdW5jdGlvbiAoRiwgbGVuLCBhcmdzKSB7XG4gIGlmICghKGxlbiBpbiBmYWN0b3JpZXMpKSB7XG4gICAgZm9yICh2YXIgbiA9IFtdLCBpID0gMDsgaSA8IGxlbjsgaSsrKSBuW2ldID0gJ2FbJyArIGkgKyAnXSc7XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLW5ldy1mdW5jXG4gICAgZmFjdG9yaWVzW2xlbl0gPSBGdW5jdGlvbignRixhJywgJ3JldHVybiBuZXcgRignICsgbi5qb2luKCcsJykgKyAnKScpO1xuICB9IHJldHVybiBmYWN0b3JpZXNbbGVuXShGLCBhcmdzKTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gRnVuY3Rpb24uYmluZCB8fCBmdW5jdGlvbiBiaW5kKHRoYXQgLyogLCAuLi5hcmdzICovKSB7XG4gIHZhciBmbiA9IGFGdW5jdGlvbih0aGlzKTtcbiAgdmFyIHBhcnRBcmdzID0gYXJyYXlTbGljZS5jYWxsKGFyZ3VtZW50cywgMSk7XG4gIHZhciBib3VuZCA9IGZ1bmN0aW9uICgvKiBhcmdzLi4uICovKSB7XG4gICAgdmFyIGFyZ3MgPSBwYXJ0QXJncy5jb25jYXQoYXJyYXlTbGljZS5jYWxsKGFyZ3VtZW50cykpO1xuICAgIHJldHVybiB0aGlzIGluc3RhbmNlb2YgYm91bmQgPyBjb25zdHJ1Y3QoZm4sIGFyZ3MubGVuZ3RoLCBhcmdzKSA6IGludm9rZShmbiwgYXJncywgdGhhdCk7XG4gIH07XG4gIGlmIChpc09iamVjdChmbi5wcm90b3R5cGUpKSBib3VuZC5wcm90b3R5cGUgPSBmbi5wcm90b3R5cGU7XG4gIHJldHVybiBib3VuZDtcbn07XG4iLCIvLyBnZXR0aW5nIHRhZyBmcm9tIDE5LjEuMy42IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcoKVxudmFyIGNvZiA9IHJlcXVpcmUoJy4vX2NvZicpO1xudmFyIFRBRyA9IHJlcXVpcmUoJy4vX3drcycpKCd0b1N0cmluZ1RhZycpO1xuLy8gRVMzIHdyb25nIGhlcmVcbnZhciBBUkcgPSBjb2YoZnVuY3Rpb24gKCkgeyByZXR1cm4gYXJndW1lbnRzOyB9KCkpID09ICdBcmd1bWVudHMnO1xuXG4vLyBmYWxsYmFjayBmb3IgSUUxMSBTY3JpcHQgQWNjZXNzIERlbmllZCBlcnJvclxudmFyIHRyeUdldCA9IGZ1bmN0aW9uIChpdCwga2V5KSB7XG4gIHRyeSB7XG4gICAgcmV0dXJuIGl0W2tleV07XG4gIH0gY2F0Y2ggKGUpIHsgLyogZW1wdHkgKi8gfVxufTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoaXQpIHtcbiAgdmFyIE8sIFQsIEI7XG4gIHJldHVybiBpdCA9PT0gdW5kZWZpbmVkID8gJ1VuZGVmaW5lZCcgOiBpdCA9PT0gbnVsbCA/ICdOdWxsJ1xuICAgIC8vIEBAdG9TdHJpbmdUYWcgY2FzZVxuICAgIDogdHlwZW9mIChUID0gdHJ5R2V0KE8gPSBPYmplY3QoaXQpLCBUQUcpKSA9PSAnc3RyaW5nJyA/IFRcbiAgICAvLyBidWlsdGluVGFnIGNhc2VcbiAgICA6IEFSRyA/IGNvZihPKVxuICAgIC8vIEVTMyBhcmd1bWVudHMgZmFsbGJhY2tcbiAgICA6IChCID0gY29mKE8pKSA9PSAnT2JqZWN0JyAmJiB0eXBlb2YgTy5jYWxsZWUgPT0gJ2Z1bmN0aW9uJyA/ICdBcmd1bWVudHMnIDogQjtcbn07XG4iLCJ2YXIgdG9TdHJpbmcgPSB7fS50b1N0cmluZztcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoaXQpIHtcbiAgcmV0dXJuIHRvU3RyaW5nLmNhbGwoaXQpLnNsaWNlKDgsIC0xKTtcbn07XG4iLCIndXNlIHN0cmljdCc7XG52YXIgZFAgPSByZXF1aXJlKCcuL19vYmplY3QtZHAnKS5mO1xudmFyIGNyZWF0ZSA9IHJlcXVpcmUoJy4vX29iamVjdC1jcmVhdGUnKTtcbnZhciByZWRlZmluZUFsbCA9IHJlcXVpcmUoJy4vX3JlZGVmaW5lLWFsbCcpO1xudmFyIGN0eCA9IHJlcXVpcmUoJy4vX2N0eCcpO1xudmFyIGFuSW5zdGFuY2UgPSByZXF1aXJlKCcuL19hbi1pbnN0YW5jZScpO1xudmFyIGZvck9mID0gcmVxdWlyZSgnLi9fZm9yLW9mJyk7XG52YXIgJGl0ZXJEZWZpbmUgPSByZXF1aXJlKCcuL19pdGVyLWRlZmluZScpO1xudmFyIHN0ZXAgPSByZXF1aXJlKCcuL19pdGVyLXN0ZXAnKTtcbnZhciBzZXRTcGVjaWVzID0gcmVxdWlyZSgnLi9fc2V0LXNwZWNpZXMnKTtcbnZhciBERVNDUklQVE9SUyA9IHJlcXVpcmUoJy4vX2Rlc2NyaXB0b3JzJyk7XG52YXIgZmFzdEtleSA9IHJlcXVpcmUoJy4vX21ldGEnKS5mYXN0S2V5O1xudmFyIHZhbGlkYXRlID0gcmVxdWlyZSgnLi9fdmFsaWRhdGUtY29sbGVjdGlvbicpO1xudmFyIFNJWkUgPSBERVNDUklQVE9SUyA/ICdfcycgOiAnc2l6ZSc7XG5cbnZhciBnZXRFbnRyeSA9IGZ1bmN0aW9uICh0aGF0LCBrZXkpIHtcbiAgLy8gZmFzdCBjYXNlXG4gIHZhciBpbmRleCA9IGZhc3RLZXkoa2V5KTtcbiAgdmFyIGVudHJ5O1xuICBpZiAoaW5kZXggIT09ICdGJykgcmV0dXJuIHRoYXQuX2lbaW5kZXhdO1xuICAvLyBmcm96ZW4gb2JqZWN0IGNhc2VcbiAgZm9yIChlbnRyeSA9IHRoYXQuX2Y7IGVudHJ5OyBlbnRyeSA9IGVudHJ5Lm4pIHtcbiAgICBpZiAoZW50cnkuayA9PSBrZXkpIHJldHVybiBlbnRyeTtcbiAgfVxufTtcblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIGdldENvbnN0cnVjdG9yOiBmdW5jdGlvbiAod3JhcHBlciwgTkFNRSwgSVNfTUFQLCBBRERFUikge1xuICAgIHZhciBDID0gd3JhcHBlcihmdW5jdGlvbiAodGhhdCwgaXRlcmFibGUpIHtcbiAgICAgIGFuSW5zdGFuY2UodGhhdCwgQywgTkFNRSwgJ19pJyk7XG4gICAgICB0aGF0Ll90ID0gTkFNRTsgICAgICAgICAvLyBjb2xsZWN0aW9uIHR5cGVcbiAgICAgIHRoYXQuX2kgPSBjcmVhdGUobnVsbCk7IC8vIGluZGV4XG4gICAgICB0aGF0Ll9mID0gdW5kZWZpbmVkOyAgICAvLyBmaXJzdCBlbnRyeVxuICAgICAgdGhhdC5fbCA9IHVuZGVmaW5lZDsgICAgLy8gbGFzdCBlbnRyeVxuICAgICAgdGhhdFtTSVpFXSA9IDA7ICAgICAgICAgLy8gc2l6ZVxuICAgICAgaWYgKGl0ZXJhYmxlICE9IHVuZGVmaW5lZCkgZm9yT2YoaXRlcmFibGUsIElTX01BUCwgdGhhdFtBRERFUl0sIHRoYXQpO1xuICAgIH0pO1xuICAgIHJlZGVmaW5lQWxsKEMucHJvdG90eXBlLCB7XG4gICAgICAvLyAyMy4xLjMuMSBNYXAucHJvdG90eXBlLmNsZWFyKClcbiAgICAgIC8vIDIzLjIuMy4yIFNldC5wcm90b3R5cGUuY2xlYXIoKVxuICAgICAgY2xlYXI6IGZ1bmN0aW9uIGNsZWFyKCkge1xuICAgICAgICBmb3IgKHZhciB0aGF0ID0gdmFsaWRhdGUodGhpcywgTkFNRSksIGRhdGEgPSB0aGF0Ll9pLCBlbnRyeSA9IHRoYXQuX2Y7IGVudHJ5OyBlbnRyeSA9IGVudHJ5Lm4pIHtcbiAgICAgICAgICBlbnRyeS5yID0gdHJ1ZTtcbiAgICAgICAgICBpZiAoZW50cnkucCkgZW50cnkucCA9IGVudHJ5LnAubiA9IHVuZGVmaW5lZDtcbiAgICAgICAgICBkZWxldGUgZGF0YVtlbnRyeS5pXTtcbiAgICAgICAgfVxuICAgICAgICB0aGF0Ll9mID0gdGhhdC5fbCA9IHVuZGVmaW5lZDtcbiAgICAgICAgdGhhdFtTSVpFXSA9IDA7XG4gICAgICB9LFxuICAgICAgLy8gMjMuMS4zLjMgTWFwLnByb3RvdHlwZS5kZWxldGUoa2V5KVxuICAgICAgLy8gMjMuMi4zLjQgU2V0LnByb3RvdHlwZS5kZWxldGUodmFsdWUpXG4gICAgICAnZGVsZXRlJzogZnVuY3Rpb24gKGtleSkge1xuICAgICAgICB2YXIgdGhhdCA9IHZhbGlkYXRlKHRoaXMsIE5BTUUpO1xuICAgICAgICB2YXIgZW50cnkgPSBnZXRFbnRyeSh0aGF0LCBrZXkpO1xuICAgICAgICBpZiAoZW50cnkpIHtcbiAgICAgICAgICB2YXIgbmV4dCA9IGVudHJ5Lm47XG4gICAgICAgICAgdmFyIHByZXYgPSBlbnRyeS5wO1xuICAgICAgICAgIGRlbGV0ZSB0aGF0Ll9pW2VudHJ5LmldO1xuICAgICAgICAgIGVudHJ5LnIgPSB0cnVlO1xuICAgICAgICAgIGlmIChwcmV2KSBwcmV2Lm4gPSBuZXh0O1xuICAgICAgICAgIGlmIChuZXh0KSBuZXh0LnAgPSBwcmV2O1xuICAgICAgICAgIGlmICh0aGF0Ll9mID09IGVudHJ5KSB0aGF0Ll9mID0gbmV4dDtcbiAgICAgICAgICBpZiAodGhhdC5fbCA9PSBlbnRyeSkgdGhhdC5fbCA9IHByZXY7XG4gICAgICAgICAgdGhhdFtTSVpFXS0tO1xuICAgICAgICB9IHJldHVybiAhIWVudHJ5O1xuICAgICAgfSxcbiAgICAgIC8vIDIzLjIuMy42IFNldC5wcm90b3R5cGUuZm9yRWFjaChjYWxsYmFja2ZuLCB0aGlzQXJnID0gdW5kZWZpbmVkKVxuICAgICAgLy8gMjMuMS4zLjUgTWFwLnByb3RvdHlwZS5mb3JFYWNoKGNhbGxiYWNrZm4sIHRoaXNBcmcgPSB1bmRlZmluZWQpXG4gICAgICBmb3JFYWNoOiBmdW5jdGlvbiBmb3JFYWNoKGNhbGxiYWNrZm4gLyogLCB0aGF0ID0gdW5kZWZpbmVkICovKSB7XG4gICAgICAgIHZhbGlkYXRlKHRoaXMsIE5BTUUpO1xuICAgICAgICB2YXIgZiA9IGN0eChjYWxsYmFja2ZuLCBhcmd1bWVudHMubGVuZ3RoID4gMSA/IGFyZ3VtZW50c1sxXSA6IHVuZGVmaW5lZCwgMyk7XG4gICAgICAgIHZhciBlbnRyeTtcbiAgICAgICAgd2hpbGUgKGVudHJ5ID0gZW50cnkgPyBlbnRyeS5uIDogdGhpcy5fZikge1xuICAgICAgICAgIGYoZW50cnkudiwgZW50cnkuaywgdGhpcyk7XG4gICAgICAgICAgLy8gcmV2ZXJ0IHRvIHRoZSBsYXN0IGV4aXN0aW5nIGVudHJ5XG4gICAgICAgICAgd2hpbGUgKGVudHJ5ICYmIGVudHJ5LnIpIGVudHJ5ID0gZW50cnkucDtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIC8vIDIzLjEuMy43IE1hcC5wcm90b3R5cGUuaGFzKGtleSlcbiAgICAgIC8vIDIzLjIuMy43IFNldC5wcm90b3R5cGUuaGFzKHZhbHVlKVxuICAgICAgaGFzOiBmdW5jdGlvbiBoYXMoa2V5KSB7XG4gICAgICAgIHJldHVybiAhIWdldEVudHJ5KHZhbGlkYXRlKHRoaXMsIE5BTUUpLCBrZXkpO1xuICAgICAgfVxuICAgIH0pO1xuICAgIGlmIChERVNDUklQVE9SUykgZFAoQy5wcm90b3R5cGUsICdzaXplJywge1xuICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB2YWxpZGF0ZSh0aGlzLCBOQU1FKVtTSVpFXTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICByZXR1cm4gQztcbiAgfSxcbiAgZGVmOiBmdW5jdGlvbiAodGhhdCwga2V5LCB2YWx1ZSkge1xuICAgIHZhciBlbnRyeSA9IGdldEVudHJ5KHRoYXQsIGtleSk7XG4gICAgdmFyIHByZXYsIGluZGV4O1xuICAgIC8vIGNoYW5nZSBleGlzdGluZyBlbnRyeVxuICAgIGlmIChlbnRyeSkge1xuICAgICAgZW50cnkudiA9IHZhbHVlO1xuICAgIC8vIGNyZWF0ZSBuZXcgZW50cnlcbiAgICB9IGVsc2Uge1xuICAgICAgdGhhdC5fbCA9IGVudHJ5ID0ge1xuICAgICAgICBpOiBpbmRleCA9IGZhc3RLZXkoa2V5LCB0cnVlKSwgLy8gPC0gaW5kZXhcbiAgICAgICAgazoga2V5LCAgICAgICAgICAgICAgICAgICAgICAgIC8vIDwtIGtleVxuICAgICAgICB2OiB2YWx1ZSwgICAgICAgICAgICAgICAgICAgICAgLy8gPC0gdmFsdWVcbiAgICAgICAgcDogcHJldiA9IHRoYXQuX2wsICAgICAgICAgICAgIC8vIDwtIHByZXZpb3VzIGVudHJ5XG4gICAgICAgIG46IHVuZGVmaW5lZCwgICAgICAgICAgICAgICAgICAvLyA8LSBuZXh0IGVudHJ5XG4gICAgICAgIHI6IGZhbHNlICAgICAgICAgICAgICAgICAgICAgICAvLyA8LSByZW1vdmVkXG4gICAgICB9O1xuICAgICAgaWYgKCF0aGF0Ll9mKSB0aGF0Ll9mID0gZW50cnk7XG4gICAgICBpZiAocHJldikgcHJldi5uID0gZW50cnk7XG4gICAgICB0aGF0W1NJWkVdKys7XG4gICAgICAvLyBhZGQgdG8gaW5kZXhcbiAgICAgIGlmIChpbmRleCAhPT0gJ0YnKSB0aGF0Ll9pW2luZGV4XSA9IGVudHJ5O1xuICAgIH0gcmV0dXJuIHRoYXQ7XG4gIH0sXG4gIGdldEVudHJ5OiBnZXRFbnRyeSxcbiAgc2V0U3Ryb25nOiBmdW5jdGlvbiAoQywgTkFNRSwgSVNfTUFQKSB7XG4gICAgLy8gYWRkIC5rZXlzLCAudmFsdWVzLCAuZW50cmllcywgW0BAaXRlcmF0b3JdXG4gICAgLy8gMjMuMS4zLjQsIDIzLjEuMy44LCAyMy4xLjMuMTEsIDIzLjEuMy4xMiwgMjMuMi4zLjUsIDIzLjIuMy44LCAyMy4yLjMuMTAsIDIzLjIuMy4xMVxuICAgICRpdGVyRGVmaW5lKEMsIE5BTUUsIGZ1bmN0aW9uIChpdGVyYXRlZCwga2luZCkge1xuICAgICAgdGhpcy5fdCA9IHZhbGlkYXRlKGl0ZXJhdGVkLCBOQU1FKTsgLy8gdGFyZ2V0XG4gICAgICB0aGlzLl9rID0ga2luZDsgICAgICAgICAgICAgICAgICAgICAvLyBraW5kXG4gICAgICB0aGlzLl9sID0gdW5kZWZpbmVkOyAgICAgICAgICAgICAgICAvLyBwcmV2aW91c1xuICAgIH0sIGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciB0aGF0ID0gdGhpcztcbiAgICAgIHZhciBraW5kID0gdGhhdC5faztcbiAgICAgIHZhciBlbnRyeSA9IHRoYXQuX2w7XG4gICAgICAvLyByZXZlcnQgdG8gdGhlIGxhc3QgZXhpc3RpbmcgZW50cnlcbiAgICAgIHdoaWxlIChlbnRyeSAmJiBlbnRyeS5yKSBlbnRyeSA9IGVudHJ5LnA7XG4gICAgICAvLyBnZXQgbmV4dCBlbnRyeVxuICAgICAgaWYgKCF0aGF0Ll90IHx8ICEodGhhdC5fbCA9IGVudHJ5ID0gZW50cnkgPyBlbnRyeS5uIDogdGhhdC5fdC5fZikpIHtcbiAgICAgICAgLy8gb3IgZmluaXNoIHRoZSBpdGVyYXRpb25cbiAgICAgICAgdGhhdC5fdCA9IHVuZGVmaW5lZDtcbiAgICAgICAgcmV0dXJuIHN0ZXAoMSk7XG4gICAgICB9XG4gICAgICAvLyByZXR1cm4gc3RlcCBieSBraW5kXG4gICAgICBpZiAoa2luZCA9PSAna2V5cycpIHJldHVybiBzdGVwKDAsIGVudHJ5LmspO1xuICAgICAgaWYgKGtpbmQgPT0gJ3ZhbHVlcycpIHJldHVybiBzdGVwKDAsIGVudHJ5LnYpO1xuICAgICAgcmV0dXJuIHN0ZXAoMCwgW2VudHJ5LmssIGVudHJ5LnZdKTtcbiAgICB9LCBJU19NQVAgPyAnZW50cmllcycgOiAndmFsdWVzJywgIUlTX01BUCwgdHJ1ZSk7XG5cbiAgICAvLyBhZGQgW0BAc3BlY2llc10sIDIzLjEuMi4yLCAyMy4yLjIuMlxuICAgIHNldFNwZWNpZXMoTkFNRSk7XG4gIH1cbn07XG4iLCIndXNlIHN0cmljdCc7XG52YXIgcmVkZWZpbmVBbGwgPSByZXF1aXJlKCcuL19yZWRlZmluZS1hbGwnKTtcbnZhciBnZXRXZWFrID0gcmVxdWlyZSgnLi9fbWV0YScpLmdldFdlYWs7XG52YXIgYW5PYmplY3QgPSByZXF1aXJlKCcuL19hbi1vYmplY3QnKTtcbnZhciBpc09iamVjdCA9IHJlcXVpcmUoJy4vX2lzLW9iamVjdCcpO1xudmFyIGFuSW5zdGFuY2UgPSByZXF1aXJlKCcuL19hbi1pbnN0YW5jZScpO1xudmFyIGZvck9mID0gcmVxdWlyZSgnLi9fZm9yLW9mJyk7XG52YXIgY3JlYXRlQXJyYXlNZXRob2QgPSByZXF1aXJlKCcuL19hcnJheS1tZXRob2RzJyk7XG52YXIgJGhhcyA9IHJlcXVpcmUoJy4vX2hhcycpO1xudmFyIHZhbGlkYXRlID0gcmVxdWlyZSgnLi9fdmFsaWRhdGUtY29sbGVjdGlvbicpO1xudmFyIGFycmF5RmluZCA9IGNyZWF0ZUFycmF5TWV0aG9kKDUpO1xudmFyIGFycmF5RmluZEluZGV4ID0gY3JlYXRlQXJyYXlNZXRob2QoNik7XG52YXIgaWQgPSAwO1xuXG4vLyBmYWxsYmFjayBmb3IgdW5jYXVnaHQgZnJvemVuIGtleXNcbnZhciB1bmNhdWdodEZyb3plblN0b3JlID0gZnVuY3Rpb24gKHRoYXQpIHtcbiAgcmV0dXJuIHRoYXQuX2wgfHwgKHRoYXQuX2wgPSBuZXcgVW5jYXVnaHRGcm96ZW5TdG9yZSgpKTtcbn07XG52YXIgVW5jYXVnaHRGcm96ZW5TdG9yZSA9IGZ1bmN0aW9uICgpIHtcbiAgdGhpcy5hID0gW107XG59O1xudmFyIGZpbmRVbmNhdWdodEZyb3plbiA9IGZ1bmN0aW9uIChzdG9yZSwga2V5KSB7XG4gIHJldHVybiBhcnJheUZpbmQoc3RvcmUuYSwgZnVuY3Rpb24gKGl0KSB7XG4gICAgcmV0dXJuIGl0WzBdID09PSBrZXk7XG4gIH0pO1xufTtcblVuY2F1Z2h0RnJvemVuU3RvcmUucHJvdG90eXBlID0ge1xuICBnZXQ6IGZ1bmN0aW9uIChrZXkpIHtcbiAgICB2YXIgZW50cnkgPSBmaW5kVW5jYXVnaHRGcm96ZW4odGhpcywga2V5KTtcbiAgICBpZiAoZW50cnkpIHJldHVybiBlbnRyeVsxXTtcbiAgfSxcbiAgaGFzOiBmdW5jdGlvbiAoa2V5KSB7XG4gICAgcmV0dXJuICEhZmluZFVuY2F1Z2h0RnJvemVuKHRoaXMsIGtleSk7XG4gIH0sXG4gIHNldDogZnVuY3Rpb24gKGtleSwgdmFsdWUpIHtcbiAgICB2YXIgZW50cnkgPSBmaW5kVW5jYXVnaHRGcm96ZW4odGhpcywga2V5KTtcbiAgICBpZiAoZW50cnkpIGVudHJ5WzFdID0gdmFsdWU7XG4gICAgZWxzZSB0aGlzLmEucHVzaChba2V5LCB2YWx1ZV0pO1xuICB9LFxuICAnZGVsZXRlJzogZnVuY3Rpb24gKGtleSkge1xuICAgIHZhciBpbmRleCA9IGFycmF5RmluZEluZGV4KHRoaXMuYSwgZnVuY3Rpb24gKGl0KSB7XG4gICAgICByZXR1cm4gaXRbMF0gPT09IGtleTtcbiAgICB9KTtcbiAgICBpZiAofmluZGV4KSB0aGlzLmEuc3BsaWNlKGluZGV4LCAxKTtcbiAgICByZXR1cm4gISF+aW5kZXg7XG4gIH1cbn07XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICBnZXRDb25zdHJ1Y3RvcjogZnVuY3Rpb24gKHdyYXBwZXIsIE5BTUUsIElTX01BUCwgQURERVIpIHtcbiAgICB2YXIgQyA9IHdyYXBwZXIoZnVuY3Rpb24gKHRoYXQsIGl0ZXJhYmxlKSB7XG4gICAgICBhbkluc3RhbmNlKHRoYXQsIEMsIE5BTUUsICdfaScpO1xuICAgICAgdGhhdC5fdCA9IE5BTUU7ICAgICAgLy8gY29sbGVjdGlvbiB0eXBlXG4gICAgICB0aGF0Ll9pID0gaWQrKzsgICAgICAvLyBjb2xsZWN0aW9uIGlkXG4gICAgICB0aGF0Ll9sID0gdW5kZWZpbmVkOyAvLyBsZWFrIHN0b3JlIGZvciB1bmNhdWdodCBmcm96ZW4gb2JqZWN0c1xuICAgICAgaWYgKGl0ZXJhYmxlICE9IHVuZGVmaW5lZCkgZm9yT2YoaXRlcmFibGUsIElTX01BUCwgdGhhdFtBRERFUl0sIHRoYXQpO1xuICAgIH0pO1xuICAgIHJlZGVmaW5lQWxsKEMucHJvdG90eXBlLCB7XG4gICAgICAvLyAyMy4zLjMuMiBXZWFrTWFwLnByb3RvdHlwZS5kZWxldGUoa2V5KVxuICAgICAgLy8gMjMuNC4zLjMgV2Vha1NldC5wcm90b3R5cGUuZGVsZXRlKHZhbHVlKVxuICAgICAgJ2RlbGV0ZSc6IGZ1bmN0aW9uIChrZXkpIHtcbiAgICAgICAgaWYgKCFpc09iamVjdChrZXkpKSByZXR1cm4gZmFsc2U7XG4gICAgICAgIHZhciBkYXRhID0gZ2V0V2VhayhrZXkpO1xuICAgICAgICBpZiAoZGF0YSA9PT0gdHJ1ZSkgcmV0dXJuIHVuY2F1Z2h0RnJvemVuU3RvcmUodmFsaWRhdGUodGhpcywgTkFNRSkpWydkZWxldGUnXShrZXkpO1xuICAgICAgICByZXR1cm4gZGF0YSAmJiAkaGFzKGRhdGEsIHRoaXMuX2kpICYmIGRlbGV0ZSBkYXRhW3RoaXMuX2ldO1xuICAgICAgfSxcbiAgICAgIC8vIDIzLjMuMy40IFdlYWtNYXAucHJvdG90eXBlLmhhcyhrZXkpXG4gICAgICAvLyAyMy40LjMuNCBXZWFrU2V0LnByb3RvdHlwZS5oYXModmFsdWUpXG4gICAgICBoYXM6IGZ1bmN0aW9uIGhhcyhrZXkpIHtcbiAgICAgICAgaWYgKCFpc09iamVjdChrZXkpKSByZXR1cm4gZmFsc2U7XG4gICAgICAgIHZhciBkYXRhID0gZ2V0V2VhayhrZXkpO1xuICAgICAgICBpZiAoZGF0YSA9PT0gdHJ1ZSkgcmV0dXJuIHVuY2F1Z2h0RnJvemVuU3RvcmUodmFsaWRhdGUodGhpcywgTkFNRSkpLmhhcyhrZXkpO1xuICAgICAgICByZXR1cm4gZGF0YSAmJiAkaGFzKGRhdGEsIHRoaXMuX2kpO1xuICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiBDO1xuICB9LFxuICBkZWY6IGZ1bmN0aW9uICh0aGF0LCBrZXksIHZhbHVlKSB7XG4gICAgdmFyIGRhdGEgPSBnZXRXZWFrKGFuT2JqZWN0KGtleSksIHRydWUpO1xuICAgIGlmIChkYXRhID09PSB0cnVlKSB1bmNhdWdodEZyb3plblN0b3JlKHRoYXQpLnNldChrZXksIHZhbHVlKTtcbiAgICBlbHNlIGRhdGFbdGhhdC5faV0gPSB2YWx1ZTtcbiAgICByZXR1cm4gdGhhdDtcbiAgfSxcbiAgdWZzdG9yZTogdW5jYXVnaHRGcm96ZW5TdG9yZVxufTtcbiIsIid1c2Ugc3RyaWN0JztcbnZhciBnbG9iYWwgPSByZXF1aXJlKCcuL19nbG9iYWwnKTtcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgcmVkZWZpbmUgPSByZXF1aXJlKCcuL19yZWRlZmluZScpO1xudmFyIHJlZGVmaW5lQWxsID0gcmVxdWlyZSgnLi9fcmVkZWZpbmUtYWxsJyk7XG52YXIgbWV0YSA9IHJlcXVpcmUoJy4vX21ldGEnKTtcbnZhciBmb3JPZiA9IHJlcXVpcmUoJy4vX2Zvci1vZicpO1xudmFyIGFuSW5zdGFuY2UgPSByZXF1aXJlKCcuL19hbi1pbnN0YW5jZScpO1xudmFyIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi9faXMtb2JqZWN0Jyk7XG52YXIgZmFpbHMgPSByZXF1aXJlKCcuL19mYWlscycpO1xudmFyICRpdGVyRGV0ZWN0ID0gcmVxdWlyZSgnLi9faXRlci1kZXRlY3QnKTtcbnZhciBzZXRUb1N0cmluZ1RhZyA9IHJlcXVpcmUoJy4vX3NldC10by1zdHJpbmctdGFnJyk7XG52YXIgaW5oZXJpdElmUmVxdWlyZWQgPSByZXF1aXJlKCcuL19pbmhlcml0LWlmLXJlcXVpcmVkJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKE5BTUUsIHdyYXBwZXIsIG1ldGhvZHMsIGNvbW1vbiwgSVNfTUFQLCBJU19XRUFLKSB7XG4gIHZhciBCYXNlID0gZ2xvYmFsW05BTUVdO1xuICB2YXIgQyA9IEJhc2U7XG4gIHZhciBBRERFUiA9IElTX01BUCA/ICdzZXQnIDogJ2FkZCc7XG4gIHZhciBwcm90byA9IEMgJiYgQy5wcm90b3R5cGU7XG4gIHZhciBPID0ge307XG4gIHZhciBmaXhNZXRob2QgPSBmdW5jdGlvbiAoS0VZKSB7XG4gICAgdmFyIGZuID0gcHJvdG9bS0VZXTtcbiAgICByZWRlZmluZShwcm90bywgS0VZLFxuICAgICAgS0VZID09ICdkZWxldGUnID8gZnVuY3Rpb24gKGEpIHtcbiAgICAgICAgcmV0dXJuIElTX1dFQUsgJiYgIWlzT2JqZWN0KGEpID8gZmFsc2UgOiBmbi5jYWxsKHRoaXMsIGEgPT09IDAgPyAwIDogYSk7XG4gICAgICB9IDogS0VZID09ICdoYXMnID8gZnVuY3Rpb24gaGFzKGEpIHtcbiAgICAgICAgcmV0dXJuIElTX1dFQUsgJiYgIWlzT2JqZWN0KGEpID8gZmFsc2UgOiBmbi5jYWxsKHRoaXMsIGEgPT09IDAgPyAwIDogYSk7XG4gICAgICB9IDogS0VZID09ICdnZXQnID8gZnVuY3Rpb24gZ2V0KGEpIHtcbiAgICAgICAgcmV0dXJuIElTX1dFQUsgJiYgIWlzT2JqZWN0KGEpID8gdW5kZWZpbmVkIDogZm4uY2FsbCh0aGlzLCBhID09PSAwID8gMCA6IGEpO1xuICAgICAgfSA6IEtFWSA9PSAnYWRkJyA/IGZ1bmN0aW9uIGFkZChhKSB7IGZuLmNhbGwodGhpcywgYSA9PT0gMCA/IDAgOiBhKTsgcmV0dXJuIHRoaXM7IH1cbiAgICAgICAgOiBmdW5jdGlvbiBzZXQoYSwgYikgeyBmbi5jYWxsKHRoaXMsIGEgPT09IDAgPyAwIDogYSwgYik7IHJldHVybiB0aGlzOyB9XG4gICAgKTtcbiAgfTtcbiAgaWYgKHR5cGVvZiBDICE9ICdmdW5jdGlvbicgfHwgIShJU19XRUFLIHx8IHByb3RvLmZvckVhY2ggJiYgIWZhaWxzKGZ1bmN0aW9uICgpIHtcbiAgICBuZXcgQygpLmVudHJpZXMoKS5uZXh0KCk7XG4gIH0pKSkge1xuICAgIC8vIGNyZWF0ZSBjb2xsZWN0aW9uIGNvbnN0cnVjdG9yXG4gICAgQyA9IGNvbW1vbi5nZXRDb25zdHJ1Y3Rvcih3cmFwcGVyLCBOQU1FLCBJU19NQVAsIEFEREVSKTtcbiAgICByZWRlZmluZUFsbChDLnByb3RvdHlwZSwgbWV0aG9kcyk7XG4gICAgbWV0YS5ORUVEID0gdHJ1ZTtcbiAgfSBlbHNlIHtcbiAgICB2YXIgaW5zdGFuY2UgPSBuZXcgQygpO1xuICAgIC8vIGVhcmx5IGltcGxlbWVudGF0aW9ucyBub3Qgc3VwcG9ydHMgY2hhaW5pbmdcbiAgICB2YXIgSEFTTlRfQ0hBSU5JTkcgPSBpbnN0YW5jZVtBRERFUl0oSVNfV0VBSyA/IHt9IDogLTAsIDEpICE9IGluc3RhbmNlO1xuICAgIC8vIFY4IH4gIENocm9taXVtIDQwLSB3ZWFrLWNvbGxlY3Rpb25zIHRocm93cyBvbiBwcmltaXRpdmVzLCBidXQgc2hvdWxkIHJldHVybiBmYWxzZVxuICAgIHZhciBUSFJPV1NfT05fUFJJTUlUSVZFUyA9IGZhaWxzKGZ1bmN0aW9uICgpIHsgaW5zdGFuY2UuaGFzKDEpOyB9KTtcbiAgICAvLyBtb3N0IGVhcmx5IGltcGxlbWVudGF0aW9ucyBkb2Vzbid0IHN1cHBvcnRzIGl0ZXJhYmxlcywgbW9zdCBtb2Rlcm4gLSBub3QgY2xvc2UgaXQgY29ycmVjdGx5XG4gICAgdmFyIEFDQ0VQVF9JVEVSQUJMRVMgPSAkaXRlckRldGVjdChmdW5jdGlvbiAoaXRlcikgeyBuZXcgQyhpdGVyKTsgfSk7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tbmV3XG4gICAgLy8gZm9yIGVhcmx5IGltcGxlbWVudGF0aW9ucyAtMCBhbmQgKzAgbm90IHRoZSBzYW1lXG4gICAgdmFyIEJVR0dZX1pFUk8gPSAhSVNfV0VBSyAmJiBmYWlscyhmdW5jdGlvbiAoKSB7XG4gICAgICAvLyBWOCB+IENocm9taXVtIDQyLSBmYWlscyBvbmx5IHdpdGggNSsgZWxlbWVudHNcbiAgICAgIHZhciAkaW5zdGFuY2UgPSBuZXcgQygpO1xuICAgICAgdmFyIGluZGV4ID0gNTtcbiAgICAgIHdoaWxlIChpbmRleC0tKSAkaW5zdGFuY2VbQURERVJdKGluZGV4LCBpbmRleCk7XG4gICAgICByZXR1cm4gISRpbnN0YW5jZS5oYXMoLTApO1xuICAgIH0pO1xuICAgIGlmICghQUNDRVBUX0lURVJBQkxFUykge1xuICAgICAgQyA9IHdyYXBwZXIoZnVuY3Rpb24gKHRhcmdldCwgaXRlcmFibGUpIHtcbiAgICAgICAgYW5JbnN0YW5jZSh0YXJnZXQsIEMsIE5BTUUpO1xuICAgICAgICB2YXIgdGhhdCA9IGluaGVyaXRJZlJlcXVpcmVkKG5ldyBCYXNlKCksIHRhcmdldCwgQyk7XG4gICAgICAgIGlmIChpdGVyYWJsZSAhPSB1bmRlZmluZWQpIGZvck9mKGl0ZXJhYmxlLCBJU19NQVAsIHRoYXRbQURERVJdLCB0aGF0KTtcbiAgICAgICAgcmV0dXJuIHRoYXQ7XG4gICAgICB9KTtcbiAgICAgIEMucHJvdG90eXBlID0gcHJvdG87XG4gICAgICBwcm90by5jb25zdHJ1Y3RvciA9IEM7XG4gICAgfVxuICAgIGlmIChUSFJPV1NfT05fUFJJTUlUSVZFUyB8fCBCVUdHWV9aRVJPKSB7XG4gICAgICBmaXhNZXRob2QoJ2RlbGV0ZScpO1xuICAgICAgZml4TWV0aG9kKCdoYXMnKTtcbiAgICAgIElTX01BUCAmJiBmaXhNZXRob2QoJ2dldCcpO1xuICAgIH1cbiAgICBpZiAoQlVHR1lfWkVSTyB8fCBIQVNOVF9DSEFJTklORykgZml4TWV0aG9kKEFEREVSKTtcbiAgICAvLyB3ZWFrIGNvbGxlY3Rpb25zIHNob3VsZCBub3QgY29udGFpbnMgLmNsZWFyIG1ldGhvZFxuICAgIGlmIChJU19XRUFLICYmIHByb3RvLmNsZWFyKSBkZWxldGUgcHJvdG8uY2xlYXI7XG4gIH1cblxuICBzZXRUb1N0cmluZ1RhZyhDLCBOQU1FKTtcblxuICBPW05BTUVdID0gQztcbiAgJGV4cG9ydCgkZXhwb3J0LkcgKyAkZXhwb3J0LlcgKyAkZXhwb3J0LkYgKiAoQyAhPSBCYXNlKSwgTyk7XG5cbiAgaWYgKCFJU19XRUFLKSBjb21tb24uc2V0U3Ryb25nKEMsIE5BTUUsIElTX01BUCk7XG5cbiAgcmV0dXJuIEM7XG59O1xuIiwidmFyIGNvcmUgPSBtb2R1bGUuZXhwb3J0cyA9IHsgdmVyc2lvbjogJzIuNS43JyB9O1xuaWYgKHR5cGVvZiBfX2UgPT0gJ251bWJlcicpIF9fZSA9IGNvcmU7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tdW5kZWZcbiIsIid1c2Ugc3RyaWN0JztcbnZhciAkZGVmaW5lUHJvcGVydHkgPSByZXF1aXJlKCcuL19vYmplY3QtZHAnKTtcbnZhciBjcmVhdGVEZXNjID0gcmVxdWlyZSgnLi9fcHJvcGVydHktZGVzYycpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChvYmplY3QsIGluZGV4LCB2YWx1ZSkge1xuICBpZiAoaW5kZXggaW4gb2JqZWN0KSAkZGVmaW5lUHJvcGVydHkuZihvYmplY3QsIGluZGV4LCBjcmVhdGVEZXNjKDAsIHZhbHVlKSk7XG4gIGVsc2Ugb2JqZWN0W2luZGV4XSA9IHZhbHVlO1xufTtcbiIsIi8vIG9wdGlvbmFsIC8gc2ltcGxlIGNvbnRleHQgYmluZGluZ1xudmFyIGFGdW5jdGlvbiA9IHJlcXVpcmUoJy4vX2EtZnVuY3Rpb24nKTtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGZuLCB0aGF0LCBsZW5ndGgpIHtcbiAgYUZ1bmN0aW9uKGZuKTtcbiAgaWYgKHRoYXQgPT09IHVuZGVmaW5lZCkgcmV0dXJuIGZuO1xuICBzd2l0Y2ggKGxlbmd0aCkge1xuICAgIGNhc2UgMTogcmV0dXJuIGZ1bmN0aW9uIChhKSB7XG4gICAgICByZXR1cm4gZm4uY2FsbCh0aGF0LCBhKTtcbiAgICB9O1xuICAgIGNhc2UgMjogcmV0dXJuIGZ1bmN0aW9uIChhLCBiKSB7XG4gICAgICByZXR1cm4gZm4uY2FsbCh0aGF0LCBhLCBiKTtcbiAgICB9O1xuICAgIGNhc2UgMzogcmV0dXJuIGZ1bmN0aW9uIChhLCBiLCBjKSB7XG4gICAgICByZXR1cm4gZm4uY2FsbCh0aGF0LCBhLCBiLCBjKTtcbiAgICB9O1xuICB9XG4gIHJldHVybiBmdW5jdGlvbiAoLyogLi4uYXJncyAqLykge1xuICAgIHJldHVybiBmbi5hcHBseSh0aGF0LCBhcmd1bWVudHMpO1xuICB9O1xufTtcbiIsIid1c2Ugc3RyaWN0Jztcbi8vIDIwLjMuNC4zNiAvIDE1LjkuNS40MyBEYXRlLnByb3RvdHlwZS50b0lTT1N0cmluZygpXG52YXIgZmFpbHMgPSByZXF1aXJlKCcuL19mYWlscycpO1xudmFyIGdldFRpbWUgPSBEYXRlLnByb3RvdHlwZS5nZXRUaW1lO1xudmFyICR0b0lTT1N0cmluZyA9IERhdGUucHJvdG90eXBlLnRvSVNPU3RyaW5nO1xuXG52YXIgbHogPSBmdW5jdGlvbiAobnVtKSB7XG4gIHJldHVybiBudW0gPiA5ID8gbnVtIDogJzAnICsgbnVtO1xufTtcblxuLy8gUGhhbnRvbUpTIC8gb2xkIFdlYktpdCBoYXMgYSBicm9rZW4gaW1wbGVtZW50YXRpb25zXG5tb2R1bGUuZXhwb3J0cyA9IChmYWlscyhmdW5jdGlvbiAoKSB7XG4gIHJldHVybiAkdG9JU09TdHJpbmcuY2FsbChuZXcgRGF0ZSgtNWUxMyAtIDEpKSAhPSAnMDM4NS0wNy0yNVQwNzowNjozOS45OTlaJztcbn0pIHx8ICFmYWlscyhmdW5jdGlvbiAoKSB7XG4gICR0b0lTT1N0cmluZy5jYWxsKG5ldyBEYXRlKE5hTikpO1xufSkpID8gZnVuY3Rpb24gdG9JU09TdHJpbmcoKSB7XG4gIGlmICghaXNGaW5pdGUoZ2V0VGltZS5jYWxsKHRoaXMpKSkgdGhyb3cgUmFuZ2VFcnJvcignSW52YWxpZCB0aW1lIHZhbHVlJyk7XG4gIHZhciBkID0gdGhpcztcbiAgdmFyIHkgPSBkLmdldFVUQ0Z1bGxZZWFyKCk7XG4gIHZhciBtID0gZC5nZXRVVENNaWxsaXNlY29uZHMoKTtcbiAgdmFyIHMgPSB5IDwgMCA/ICctJyA6IHkgPiA5OTk5ID8gJysnIDogJyc7XG4gIHJldHVybiBzICsgKCcwMDAwMCcgKyBNYXRoLmFicyh5KSkuc2xpY2UocyA/IC02IDogLTQpICtcbiAgICAnLScgKyBseihkLmdldFVUQ01vbnRoKCkgKyAxKSArICctJyArIGx6KGQuZ2V0VVRDRGF0ZSgpKSArXG4gICAgJ1QnICsgbHooZC5nZXRVVENIb3VycygpKSArICc6JyArIGx6KGQuZ2V0VVRDTWludXRlcygpKSArXG4gICAgJzonICsgbHooZC5nZXRVVENTZWNvbmRzKCkpICsgJy4nICsgKG0gPiA5OSA/IG0gOiAnMCcgKyBseihtKSkgKyAnWic7XG59IDogJHRvSVNPU3RyaW5nO1xuIiwiJ3VzZSBzdHJpY3QnO1xudmFyIGFuT2JqZWN0ID0gcmVxdWlyZSgnLi9fYW4tb2JqZWN0Jyk7XG52YXIgdG9QcmltaXRpdmUgPSByZXF1aXJlKCcuL190by1wcmltaXRpdmUnKTtcbnZhciBOVU1CRVIgPSAnbnVtYmVyJztcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoaGludCkge1xuICBpZiAoaGludCAhPT0gJ3N0cmluZycgJiYgaGludCAhPT0gTlVNQkVSICYmIGhpbnQgIT09ICdkZWZhdWx0JykgdGhyb3cgVHlwZUVycm9yKCdJbmNvcnJlY3QgaGludCcpO1xuICByZXR1cm4gdG9QcmltaXRpdmUoYW5PYmplY3QodGhpcyksIGhpbnQgIT0gTlVNQkVSKTtcbn07XG4iLCIvLyA3LjIuMSBSZXF1aXJlT2JqZWN0Q29lcmNpYmxlKGFyZ3VtZW50KVxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoaXQpIHtcbiAgaWYgKGl0ID09IHVuZGVmaW5lZCkgdGhyb3cgVHlwZUVycm9yKFwiQ2FuJ3QgY2FsbCBtZXRob2Qgb24gIFwiICsgaXQpO1xuICByZXR1cm4gaXQ7XG59O1xuIiwiLy8gVGhhbmsncyBJRTggZm9yIGhpcyBmdW5ueSBkZWZpbmVQcm9wZXJ0eVxubW9kdWxlLmV4cG9ydHMgPSAhcmVxdWlyZSgnLi9fZmFpbHMnKShmdW5jdGlvbiAoKSB7XG4gIHJldHVybiBPYmplY3QuZGVmaW5lUHJvcGVydHkoe30sICdhJywgeyBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIDc7IH0gfSkuYSAhPSA3O1xufSk7XG4iLCJ2YXIgaXNPYmplY3QgPSByZXF1aXJlKCcuL19pcy1vYmplY3QnKTtcbnZhciBkb2N1bWVudCA9IHJlcXVpcmUoJy4vX2dsb2JhbCcpLmRvY3VtZW50O1xuLy8gdHlwZW9mIGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQgaXMgJ29iamVjdCcgaW4gb2xkIElFXG52YXIgaXMgPSBpc09iamVjdChkb2N1bWVudCkgJiYgaXNPYmplY3QoZG9jdW1lbnQuY3JlYXRlRWxlbWVudCk7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChpdCkge1xuICByZXR1cm4gaXMgPyBkb2N1bWVudC5jcmVhdGVFbGVtZW50KGl0KSA6IHt9O1xufTtcbiIsIi8vIElFIDgtIGRvbid0IGVudW0gYnVnIGtleXNcbm1vZHVsZS5leHBvcnRzID0gKFxuICAnY29uc3RydWN0b3IsaGFzT3duUHJvcGVydHksaXNQcm90b3R5cGVPZixwcm9wZXJ0eUlzRW51bWVyYWJsZSx0b0xvY2FsZVN0cmluZyx0b1N0cmluZyx2YWx1ZU9mJ1xuKS5zcGxpdCgnLCcpO1xuIiwiLy8gYWxsIGVudW1lcmFibGUgb2JqZWN0IGtleXMsIGluY2x1ZGVzIHN5bWJvbHNcbnZhciBnZXRLZXlzID0gcmVxdWlyZSgnLi9fb2JqZWN0LWtleXMnKTtcbnZhciBnT1BTID0gcmVxdWlyZSgnLi9fb2JqZWN0LWdvcHMnKTtcbnZhciBwSUUgPSByZXF1aXJlKCcuL19vYmplY3QtcGllJyk7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChpdCkge1xuICB2YXIgcmVzdWx0ID0gZ2V0S2V5cyhpdCk7XG4gIHZhciBnZXRTeW1ib2xzID0gZ09QUy5mO1xuICBpZiAoZ2V0U3ltYm9scykge1xuICAgIHZhciBzeW1ib2xzID0gZ2V0U3ltYm9scyhpdCk7XG4gICAgdmFyIGlzRW51bSA9IHBJRS5mO1xuICAgIHZhciBpID0gMDtcbiAgICB2YXIga2V5O1xuICAgIHdoaWxlIChzeW1ib2xzLmxlbmd0aCA+IGkpIGlmIChpc0VudW0uY2FsbChpdCwga2V5ID0gc3ltYm9sc1tpKytdKSkgcmVzdWx0LnB1c2goa2V5KTtcbiAgfSByZXR1cm4gcmVzdWx0O1xufTtcbiIsInZhciBnbG9iYWwgPSByZXF1aXJlKCcuL19nbG9iYWwnKTtcbnZhciBjb3JlID0gcmVxdWlyZSgnLi9fY29yZScpO1xudmFyIGhpZGUgPSByZXF1aXJlKCcuL19oaWRlJyk7XG52YXIgcmVkZWZpbmUgPSByZXF1aXJlKCcuL19yZWRlZmluZScpO1xudmFyIGN0eCA9IHJlcXVpcmUoJy4vX2N0eCcpO1xudmFyIFBST1RPVFlQRSA9ICdwcm90b3R5cGUnO1xuXG52YXIgJGV4cG9ydCA9IGZ1bmN0aW9uICh0eXBlLCBuYW1lLCBzb3VyY2UpIHtcbiAgdmFyIElTX0ZPUkNFRCA9IHR5cGUgJiAkZXhwb3J0LkY7XG4gIHZhciBJU19HTE9CQUwgPSB0eXBlICYgJGV4cG9ydC5HO1xuICB2YXIgSVNfU1RBVElDID0gdHlwZSAmICRleHBvcnQuUztcbiAgdmFyIElTX1BST1RPID0gdHlwZSAmICRleHBvcnQuUDtcbiAgdmFyIElTX0JJTkQgPSB0eXBlICYgJGV4cG9ydC5CO1xuICB2YXIgdGFyZ2V0ID0gSVNfR0xPQkFMID8gZ2xvYmFsIDogSVNfU1RBVElDID8gZ2xvYmFsW25hbWVdIHx8IChnbG9iYWxbbmFtZV0gPSB7fSkgOiAoZ2xvYmFsW25hbWVdIHx8IHt9KVtQUk9UT1RZUEVdO1xuICB2YXIgZXhwb3J0cyA9IElTX0dMT0JBTCA/IGNvcmUgOiBjb3JlW25hbWVdIHx8IChjb3JlW25hbWVdID0ge30pO1xuICB2YXIgZXhwUHJvdG8gPSBleHBvcnRzW1BST1RPVFlQRV0gfHwgKGV4cG9ydHNbUFJPVE9UWVBFXSA9IHt9KTtcbiAgdmFyIGtleSwgb3duLCBvdXQsIGV4cDtcbiAgaWYgKElTX0dMT0JBTCkgc291cmNlID0gbmFtZTtcbiAgZm9yIChrZXkgaW4gc291cmNlKSB7XG4gICAgLy8gY29udGFpbnMgaW4gbmF0aXZlXG4gICAgb3duID0gIUlTX0ZPUkNFRCAmJiB0YXJnZXQgJiYgdGFyZ2V0W2tleV0gIT09IHVuZGVmaW5lZDtcbiAgICAvLyBleHBvcnQgbmF0aXZlIG9yIHBhc3NlZFxuICAgIG91dCA9IChvd24gPyB0YXJnZXQgOiBzb3VyY2UpW2tleV07XG4gICAgLy8gYmluZCB0aW1lcnMgdG8gZ2xvYmFsIGZvciBjYWxsIGZyb20gZXhwb3J0IGNvbnRleHRcbiAgICBleHAgPSBJU19CSU5EICYmIG93biA/IGN0eChvdXQsIGdsb2JhbCkgOiBJU19QUk9UTyAmJiB0eXBlb2Ygb3V0ID09ICdmdW5jdGlvbicgPyBjdHgoRnVuY3Rpb24uY2FsbCwgb3V0KSA6IG91dDtcbiAgICAvLyBleHRlbmQgZ2xvYmFsXG4gICAgaWYgKHRhcmdldCkgcmVkZWZpbmUodGFyZ2V0LCBrZXksIG91dCwgdHlwZSAmICRleHBvcnQuVSk7XG4gICAgLy8gZXhwb3J0XG4gICAgaWYgKGV4cG9ydHNba2V5XSAhPSBvdXQpIGhpZGUoZXhwb3J0cywga2V5LCBleHApO1xuICAgIGlmIChJU19QUk9UTyAmJiBleHBQcm90b1trZXldICE9IG91dCkgZXhwUHJvdG9ba2V5XSA9IG91dDtcbiAgfVxufTtcbmdsb2JhbC5jb3JlID0gY29yZTtcbi8vIHR5cGUgYml0bWFwXG4kZXhwb3J0LkYgPSAxOyAgIC8vIGZvcmNlZFxuJGV4cG9ydC5HID0gMjsgICAvLyBnbG9iYWxcbiRleHBvcnQuUyA9IDQ7ICAgLy8gc3RhdGljXG4kZXhwb3J0LlAgPSA4OyAgIC8vIHByb3RvXG4kZXhwb3J0LkIgPSAxNjsgIC8vIGJpbmRcbiRleHBvcnQuVyA9IDMyOyAgLy8gd3JhcFxuJGV4cG9ydC5VID0gNjQ7ICAvLyBzYWZlXG4kZXhwb3J0LlIgPSAxMjg7IC8vIHJlYWwgcHJvdG8gbWV0aG9kIGZvciBgbGlicmFyeWBcbm1vZHVsZS5leHBvcnRzID0gJGV4cG9ydDtcbiIsInZhciBNQVRDSCA9IHJlcXVpcmUoJy4vX3drcycpKCdtYXRjaCcpO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoS0VZKSB7XG4gIHZhciByZSA9IC8uLztcbiAgdHJ5IHtcbiAgICAnLy4vJ1tLRVldKHJlKTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIHRyeSB7XG4gICAgICByZVtNQVRDSF0gPSBmYWxzZTtcbiAgICAgIHJldHVybiAhJy8uLydbS0VZXShyZSk7XG4gICAgfSBjYXRjaCAoZikgeyAvKiBlbXB0eSAqLyB9XG4gIH0gcmV0dXJuIHRydWU7XG59O1xuIiwibW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoZXhlYykge1xuICB0cnkge1xuICAgIHJldHVybiAhIWV4ZWMoKTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xudmFyIGhpZGUgPSByZXF1aXJlKCcuL19oaWRlJyk7XG52YXIgcmVkZWZpbmUgPSByZXF1aXJlKCcuL19yZWRlZmluZScpO1xudmFyIGZhaWxzID0gcmVxdWlyZSgnLi9fZmFpbHMnKTtcbnZhciBkZWZpbmVkID0gcmVxdWlyZSgnLi9fZGVmaW5lZCcpO1xudmFyIHdrcyA9IHJlcXVpcmUoJy4vX3drcycpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChLRVksIGxlbmd0aCwgZXhlYykge1xuICB2YXIgU1lNQk9MID0gd2tzKEtFWSk7XG4gIHZhciBmbnMgPSBleGVjKGRlZmluZWQsIFNZTUJPTCwgJydbS0VZXSk7XG4gIHZhciBzdHJmbiA9IGZuc1swXTtcbiAgdmFyIHJ4Zm4gPSBmbnNbMV07XG4gIGlmIChmYWlscyhmdW5jdGlvbiAoKSB7XG4gICAgdmFyIE8gPSB7fTtcbiAgICBPW1NZTUJPTF0gPSBmdW5jdGlvbiAoKSB7IHJldHVybiA3OyB9O1xuICAgIHJldHVybiAnJ1tLRVldKE8pICE9IDc7XG4gIH0pKSB7XG4gICAgcmVkZWZpbmUoU3RyaW5nLnByb3RvdHlwZSwgS0VZLCBzdHJmbik7XG4gICAgaGlkZShSZWdFeHAucHJvdG90eXBlLCBTWU1CT0wsIGxlbmd0aCA9PSAyXG4gICAgICAvLyAyMS4yLjUuOCBSZWdFeHAucHJvdG90eXBlW0BAcmVwbGFjZV0oc3RyaW5nLCByZXBsYWNlVmFsdWUpXG4gICAgICAvLyAyMS4yLjUuMTEgUmVnRXhwLnByb3RvdHlwZVtAQHNwbGl0XShzdHJpbmcsIGxpbWl0KVxuICAgICAgPyBmdW5jdGlvbiAoc3RyaW5nLCBhcmcpIHsgcmV0dXJuIHJ4Zm4uY2FsbChzdHJpbmcsIHRoaXMsIGFyZyk7IH1cbiAgICAgIC8vIDIxLjIuNS42IFJlZ0V4cC5wcm90b3R5cGVbQEBtYXRjaF0oc3RyaW5nKVxuICAgICAgLy8gMjEuMi41LjkgUmVnRXhwLnByb3RvdHlwZVtAQHNlYXJjaF0oc3RyaW5nKVxuICAgICAgOiBmdW5jdGlvbiAoc3RyaW5nKSB7IHJldHVybiByeGZuLmNhbGwoc3RyaW5nLCB0aGlzKTsgfVxuICAgICk7XG4gIH1cbn07XG4iLCIndXNlIHN0cmljdCc7XG4vLyAyMS4yLjUuMyBnZXQgUmVnRXhwLnByb3RvdHlwZS5mbGFnc1xudmFyIGFuT2JqZWN0ID0gcmVxdWlyZSgnLi9fYW4tb2JqZWN0Jyk7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIHRoYXQgPSBhbk9iamVjdCh0aGlzKTtcbiAgdmFyIHJlc3VsdCA9ICcnO1xuICBpZiAodGhhdC5nbG9iYWwpIHJlc3VsdCArPSAnZyc7XG4gIGlmICh0aGF0Lmlnbm9yZUNhc2UpIHJlc3VsdCArPSAnaSc7XG4gIGlmICh0aGF0Lm11bHRpbGluZSkgcmVzdWx0ICs9ICdtJztcbiAgaWYgKHRoYXQudW5pY29kZSkgcmVzdWx0ICs9ICd1JztcbiAgaWYgKHRoYXQuc3RpY2t5KSByZXN1bHQgKz0gJ3knO1xuICByZXR1cm4gcmVzdWx0O1xufTtcbiIsInZhciBjdHggPSByZXF1aXJlKCcuL19jdHgnKTtcbnZhciBjYWxsID0gcmVxdWlyZSgnLi9faXRlci1jYWxsJyk7XG52YXIgaXNBcnJheUl0ZXIgPSByZXF1aXJlKCcuL19pcy1hcnJheS1pdGVyJyk7XG52YXIgYW5PYmplY3QgPSByZXF1aXJlKCcuL19hbi1vYmplY3QnKTtcbnZhciB0b0xlbmd0aCA9IHJlcXVpcmUoJy4vX3RvLWxlbmd0aCcpO1xudmFyIGdldEl0ZXJGbiA9IHJlcXVpcmUoJy4vY29yZS5nZXQtaXRlcmF0b3ItbWV0aG9kJyk7XG52YXIgQlJFQUsgPSB7fTtcbnZhciBSRVRVUk4gPSB7fTtcbnZhciBleHBvcnRzID0gbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoaXRlcmFibGUsIGVudHJpZXMsIGZuLCB0aGF0LCBJVEVSQVRPUikge1xuICB2YXIgaXRlckZuID0gSVRFUkFUT1IgPyBmdW5jdGlvbiAoKSB7IHJldHVybiBpdGVyYWJsZTsgfSA6IGdldEl0ZXJGbihpdGVyYWJsZSk7XG4gIHZhciBmID0gY3R4KGZuLCB0aGF0LCBlbnRyaWVzID8gMiA6IDEpO1xuICB2YXIgaW5kZXggPSAwO1xuICB2YXIgbGVuZ3RoLCBzdGVwLCBpdGVyYXRvciwgcmVzdWx0O1xuICBpZiAodHlwZW9mIGl0ZXJGbiAhPSAnZnVuY3Rpb24nKSB0aHJvdyBUeXBlRXJyb3IoaXRlcmFibGUgKyAnIGlzIG5vdCBpdGVyYWJsZSEnKTtcbiAgLy8gZmFzdCBjYXNlIGZvciBhcnJheXMgd2l0aCBkZWZhdWx0IGl0ZXJhdG9yXG4gIGlmIChpc0FycmF5SXRlcihpdGVyRm4pKSBmb3IgKGxlbmd0aCA9IHRvTGVuZ3RoKGl0ZXJhYmxlLmxlbmd0aCk7IGxlbmd0aCA+IGluZGV4OyBpbmRleCsrKSB7XG4gICAgcmVzdWx0ID0gZW50cmllcyA/IGYoYW5PYmplY3Qoc3RlcCA9IGl0ZXJhYmxlW2luZGV4XSlbMF0sIHN0ZXBbMV0pIDogZihpdGVyYWJsZVtpbmRleF0pO1xuICAgIGlmIChyZXN1bHQgPT09IEJSRUFLIHx8IHJlc3VsdCA9PT0gUkVUVVJOKSByZXR1cm4gcmVzdWx0O1xuICB9IGVsc2UgZm9yIChpdGVyYXRvciA9IGl0ZXJGbi5jYWxsKGl0ZXJhYmxlKTsgIShzdGVwID0gaXRlcmF0b3IubmV4dCgpKS5kb25lOykge1xuICAgIHJlc3VsdCA9IGNhbGwoaXRlcmF0b3IsIGYsIHN0ZXAudmFsdWUsIGVudHJpZXMpO1xuICAgIGlmIChyZXN1bHQgPT09IEJSRUFLIHx8IHJlc3VsdCA9PT0gUkVUVVJOKSByZXR1cm4gcmVzdWx0O1xuICB9XG59O1xuZXhwb3J0cy5CUkVBSyA9IEJSRUFLO1xuZXhwb3J0cy5SRVRVUk4gPSBSRVRVUk47XG4iLCIvLyBodHRwczovL2dpdGh1Yi5jb20vemxvaXJvY2svY29yZS1qcy9pc3N1ZXMvODYjaXNzdWVjb21tZW50LTExNTc1OTAyOFxudmFyIGdsb2JhbCA9IG1vZHVsZS5leHBvcnRzID0gdHlwZW9mIHdpbmRvdyAhPSAndW5kZWZpbmVkJyAmJiB3aW5kb3cuTWF0aCA9PSBNYXRoXG4gID8gd2luZG93IDogdHlwZW9mIHNlbGYgIT0gJ3VuZGVmaW5lZCcgJiYgc2VsZi5NYXRoID09IE1hdGggPyBzZWxmXG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1uZXctZnVuY1xuICA6IEZ1bmN0aW9uKCdyZXR1cm4gdGhpcycpKCk7XG5pZiAodHlwZW9mIF9fZyA9PSAnbnVtYmVyJykgX19nID0gZ2xvYmFsOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXVuZGVmXG4iLCJ2YXIgaGFzT3duUHJvcGVydHkgPSB7fS5oYXNPd25Qcm9wZXJ0eTtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGl0LCBrZXkpIHtcbiAgcmV0dXJuIGhhc093blByb3BlcnR5LmNhbGwoaXQsIGtleSk7XG59O1xuIiwidmFyIGRQID0gcmVxdWlyZSgnLi9fb2JqZWN0LWRwJyk7XG52YXIgY3JlYXRlRGVzYyA9IHJlcXVpcmUoJy4vX3Byb3BlcnR5LWRlc2MnKTtcbm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi9fZGVzY3JpcHRvcnMnKSA/IGZ1bmN0aW9uIChvYmplY3QsIGtleSwgdmFsdWUpIHtcbiAgcmV0dXJuIGRQLmYob2JqZWN0LCBrZXksIGNyZWF0ZURlc2MoMSwgdmFsdWUpKTtcbn0gOiBmdW5jdGlvbiAob2JqZWN0LCBrZXksIHZhbHVlKSB7XG4gIG9iamVjdFtrZXldID0gdmFsdWU7XG4gIHJldHVybiBvYmplY3Q7XG59O1xuIiwidmFyIGRvY3VtZW50ID0gcmVxdWlyZSgnLi9fZ2xvYmFsJykuZG9jdW1lbnQ7XG5tb2R1bGUuZXhwb3J0cyA9IGRvY3VtZW50ICYmIGRvY3VtZW50LmRvY3VtZW50RWxlbWVudDtcbiIsIm1vZHVsZS5leHBvcnRzID0gIXJlcXVpcmUoJy4vX2Rlc2NyaXB0b3JzJykgJiYgIXJlcXVpcmUoJy4vX2ZhaWxzJykoZnVuY3Rpb24gKCkge1xuICByZXR1cm4gT2JqZWN0LmRlZmluZVByb3BlcnR5KHJlcXVpcmUoJy4vX2RvbS1jcmVhdGUnKSgnZGl2JyksICdhJywgeyBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIDc7IH0gfSkuYSAhPSA3O1xufSk7XG4iLCJ2YXIgaXNPYmplY3QgPSByZXF1aXJlKCcuL19pcy1vYmplY3QnKTtcbnZhciBzZXRQcm90b3R5cGVPZiA9IHJlcXVpcmUoJy4vX3NldC1wcm90bycpLnNldDtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKHRoYXQsIHRhcmdldCwgQykge1xuICB2YXIgUyA9IHRhcmdldC5jb25zdHJ1Y3RvcjtcbiAgdmFyIFA7XG4gIGlmIChTICE9PSBDICYmIHR5cGVvZiBTID09ICdmdW5jdGlvbicgJiYgKFAgPSBTLnByb3RvdHlwZSkgIT09IEMucHJvdG90eXBlICYmIGlzT2JqZWN0KFApICYmIHNldFByb3RvdHlwZU9mKSB7XG4gICAgc2V0UHJvdG90eXBlT2YodGhhdCwgUCk7XG4gIH0gcmV0dXJuIHRoYXQ7XG59O1xuIiwiLy8gZmFzdCBhcHBseSwgaHR0cDovL2pzcGVyZi5sbmtpdC5jb20vZmFzdC1hcHBseS81XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChmbiwgYXJncywgdGhhdCkge1xuICB2YXIgdW4gPSB0aGF0ID09PSB1bmRlZmluZWQ7XG4gIHN3aXRjaCAoYXJncy5sZW5ndGgpIHtcbiAgICBjYXNlIDA6IHJldHVybiB1biA/IGZuKClcbiAgICAgICAgICAgICAgICAgICAgICA6IGZuLmNhbGwodGhhdCk7XG4gICAgY2FzZSAxOiByZXR1cm4gdW4gPyBmbihhcmdzWzBdKVxuICAgICAgICAgICAgICAgICAgICAgIDogZm4uY2FsbCh0aGF0LCBhcmdzWzBdKTtcbiAgICBjYXNlIDI6IHJldHVybiB1biA/IGZuKGFyZ3NbMF0sIGFyZ3NbMV0pXG4gICAgICAgICAgICAgICAgICAgICAgOiBmbi5jYWxsKHRoYXQsIGFyZ3NbMF0sIGFyZ3NbMV0pO1xuICAgIGNhc2UgMzogcmV0dXJuIHVuID8gZm4oYXJnc1swXSwgYXJnc1sxXSwgYXJnc1syXSlcbiAgICAgICAgICAgICAgICAgICAgICA6IGZuLmNhbGwodGhhdCwgYXJnc1swXSwgYXJnc1sxXSwgYXJnc1syXSk7XG4gICAgY2FzZSA0OiByZXR1cm4gdW4gPyBmbihhcmdzWzBdLCBhcmdzWzFdLCBhcmdzWzJdLCBhcmdzWzNdKVxuICAgICAgICAgICAgICAgICAgICAgIDogZm4uY2FsbCh0aGF0LCBhcmdzWzBdLCBhcmdzWzFdLCBhcmdzWzJdLCBhcmdzWzNdKTtcbiAgfSByZXR1cm4gZm4uYXBwbHkodGhhdCwgYXJncyk7XG59O1xuIiwiLy8gZmFsbGJhY2sgZm9yIG5vbi1hcnJheS1saWtlIEVTMyBhbmQgbm9uLWVudW1lcmFibGUgb2xkIFY4IHN0cmluZ3NcbnZhciBjb2YgPSByZXF1aXJlKCcuL19jb2YnKTtcbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1wcm90b3R5cGUtYnVpbHRpbnNcbm1vZHVsZS5leHBvcnRzID0gT2JqZWN0KCd6JykucHJvcGVydHlJc0VudW1lcmFibGUoMCkgPyBPYmplY3QgOiBmdW5jdGlvbiAoaXQpIHtcbiAgcmV0dXJuIGNvZihpdCkgPT0gJ1N0cmluZycgPyBpdC5zcGxpdCgnJykgOiBPYmplY3QoaXQpO1xufTtcbiIsIi8vIGNoZWNrIG9uIGRlZmF1bHQgQXJyYXkgaXRlcmF0b3JcbnZhciBJdGVyYXRvcnMgPSByZXF1aXJlKCcuL19pdGVyYXRvcnMnKTtcbnZhciBJVEVSQVRPUiA9IHJlcXVpcmUoJy4vX3drcycpKCdpdGVyYXRvcicpO1xudmFyIEFycmF5UHJvdG8gPSBBcnJheS5wcm90b3R5cGU7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGl0KSB7XG4gIHJldHVybiBpdCAhPT0gdW5kZWZpbmVkICYmIChJdGVyYXRvcnMuQXJyYXkgPT09IGl0IHx8IEFycmF5UHJvdG9bSVRFUkFUT1JdID09PSBpdCk7XG59O1xuIiwiLy8gNy4yLjIgSXNBcnJheShhcmd1bWVudClcbnZhciBjb2YgPSByZXF1aXJlKCcuL19jb2YnKTtcbm1vZHVsZS5leHBvcnRzID0gQXJyYXkuaXNBcnJheSB8fCBmdW5jdGlvbiBpc0FycmF5KGFyZykge1xuICByZXR1cm4gY29mKGFyZykgPT0gJ0FycmF5Jztcbn07XG4iLCIvLyAyMC4xLjIuMyBOdW1iZXIuaXNJbnRlZ2VyKG51bWJlcilcbnZhciBpc09iamVjdCA9IHJlcXVpcmUoJy4vX2lzLW9iamVjdCcpO1xudmFyIGZsb29yID0gTWF0aC5mbG9vcjtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gaXNJbnRlZ2VyKGl0KSB7XG4gIHJldHVybiAhaXNPYmplY3QoaXQpICYmIGlzRmluaXRlKGl0KSAmJiBmbG9vcihpdCkgPT09IGl0O1xufTtcbiIsIm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGl0KSB7XG4gIHJldHVybiB0eXBlb2YgaXQgPT09ICdvYmplY3QnID8gaXQgIT09IG51bGwgOiB0eXBlb2YgaXQgPT09ICdmdW5jdGlvbic7XG59O1xuIiwiLy8gNy4yLjggSXNSZWdFeHAoYXJndW1lbnQpXG52YXIgaXNPYmplY3QgPSByZXF1aXJlKCcuL19pcy1vYmplY3QnKTtcbnZhciBjb2YgPSByZXF1aXJlKCcuL19jb2YnKTtcbnZhciBNQVRDSCA9IHJlcXVpcmUoJy4vX3drcycpKCdtYXRjaCcpO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoaXQpIHtcbiAgdmFyIGlzUmVnRXhwO1xuICByZXR1cm4gaXNPYmplY3QoaXQpICYmICgoaXNSZWdFeHAgPSBpdFtNQVRDSF0pICE9PSB1bmRlZmluZWQgPyAhIWlzUmVnRXhwIDogY29mKGl0KSA9PSAnUmVnRXhwJyk7XG59O1xuIiwiLy8gY2FsbCBzb21ldGhpbmcgb24gaXRlcmF0b3Igc3RlcCB3aXRoIHNhZmUgY2xvc2luZyBvbiBlcnJvclxudmFyIGFuT2JqZWN0ID0gcmVxdWlyZSgnLi9fYW4tb2JqZWN0Jyk7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChpdGVyYXRvciwgZm4sIHZhbHVlLCBlbnRyaWVzKSB7XG4gIHRyeSB7XG4gICAgcmV0dXJuIGVudHJpZXMgPyBmbihhbk9iamVjdCh2YWx1ZSlbMF0sIHZhbHVlWzFdKSA6IGZuKHZhbHVlKTtcbiAgLy8gNy40LjYgSXRlcmF0b3JDbG9zZShpdGVyYXRvciwgY29tcGxldGlvbilcbiAgfSBjYXRjaCAoZSkge1xuICAgIHZhciByZXQgPSBpdGVyYXRvclsncmV0dXJuJ107XG4gICAgaWYgKHJldCAhPT0gdW5kZWZpbmVkKSBhbk9iamVjdChyZXQuY2FsbChpdGVyYXRvcikpO1xuICAgIHRocm93IGU7XG4gIH1cbn07XG4iLCIndXNlIHN0cmljdCc7XG52YXIgY3JlYXRlID0gcmVxdWlyZSgnLi9fb2JqZWN0LWNyZWF0ZScpO1xudmFyIGRlc2NyaXB0b3IgPSByZXF1aXJlKCcuL19wcm9wZXJ0eS1kZXNjJyk7XG52YXIgc2V0VG9TdHJpbmdUYWcgPSByZXF1aXJlKCcuL19zZXQtdG8tc3RyaW5nLXRhZycpO1xudmFyIEl0ZXJhdG9yUHJvdG90eXBlID0ge307XG5cbi8vIDI1LjEuMi4xLjEgJUl0ZXJhdG9yUHJvdG90eXBlJVtAQGl0ZXJhdG9yXSgpXG5yZXF1aXJlKCcuL19oaWRlJykoSXRlcmF0b3JQcm90b3R5cGUsIHJlcXVpcmUoJy4vX3drcycpKCdpdGVyYXRvcicpLCBmdW5jdGlvbiAoKSB7IHJldHVybiB0aGlzOyB9KTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoQ29uc3RydWN0b3IsIE5BTUUsIG5leHQpIHtcbiAgQ29uc3RydWN0b3IucHJvdG90eXBlID0gY3JlYXRlKEl0ZXJhdG9yUHJvdG90eXBlLCB7IG5leHQ6IGRlc2NyaXB0b3IoMSwgbmV4dCkgfSk7XG4gIHNldFRvU3RyaW5nVGFnKENvbnN0cnVjdG9yLCBOQU1FICsgJyBJdGVyYXRvcicpO1xufTtcbiIsIid1c2Ugc3RyaWN0JztcbnZhciBMSUJSQVJZID0gcmVxdWlyZSgnLi9fbGlicmFyeScpO1xudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciByZWRlZmluZSA9IHJlcXVpcmUoJy4vX3JlZGVmaW5lJyk7XG52YXIgaGlkZSA9IHJlcXVpcmUoJy4vX2hpZGUnKTtcbnZhciBJdGVyYXRvcnMgPSByZXF1aXJlKCcuL19pdGVyYXRvcnMnKTtcbnZhciAkaXRlckNyZWF0ZSA9IHJlcXVpcmUoJy4vX2l0ZXItY3JlYXRlJyk7XG52YXIgc2V0VG9TdHJpbmdUYWcgPSByZXF1aXJlKCcuL19zZXQtdG8tc3RyaW5nLXRhZycpO1xudmFyIGdldFByb3RvdHlwZU9mID0gcmVxdWlyZSgnLi9fb2JqZWN0LWdwbycpO1xudmFyIElURVJBVE9SID0gcmVxdWlyZSgnLi9fd2tzJykoJ2l0ZXJhdG9yJyk7XG52YXIgQlVHR1kgPSAhKFtdLmtleXMgJiYgJ25leHQnIGluIFtdLmtleXMoKSk7IC8vIFNhZmFyaSBoYXMgYnVnZ3kgaXRlcmF0b3JzIHcvbyBgbmV4dGBcbnZhciBGRl9JVEVSQVRPUiA9ICdAQGl0ZXJhdG9yJztcbnZhciBLRVlTID0gJ2tleXMnO1xudmFyIFZBTFVFUyA9ICd2YWx1ZXMnO1xuXG52YXIgcmV0dXJuVGhpcyA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRoaXM7IH07XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKEJhc2UsIE5BTUUsIENvbnN0cnVjdG9yLCBuZXh0LCBERUZBVUxULCBJU19TRVQsIEZPUkNFRCkge1xuICAkaXRlckNyZWF0ZShDb25zdHJ1Y3RvciwgTkFNRSwgbmV4dCk7XG4gIHZhciBnZXRNZXRob2QgPSBmdW5jdGlvbiAoa2luZCkge1xuICAgIGlmICghQlVHR1kgJiYga2luZCBpbiBwcm90bykgcmV0dXJuIHByb3RvW2tpbmRdO1xuICAgIHN3aXRjaCAoa2luZCkge1xuICAgICAgY2FzZSBLRVlTOiByZXR1cm4gZnVuY3Rpb24ga2V5cygpIHsgcmV0dXJuIG5ldyBDb25zdHJ1Y3Rvcih0aGlzLCBraW5kKTsgfTtcbiAgICAgIGNhc2UgVkFMVUVTOiByZXR1cm4gZnVuY3Rpb24gdmFsdWVzKCkgeyByZXR1cm4gbmV3IENvbnN0cnVjdG9yKHRoaXMsIGtpbmQpOyB9O1xuICAgIH0gcmV0dXJuIGZ1bmN0aW9uIGVudHJpZXMoKSB7IHJldHVybiBuZXcgQ29uc3RydWN0b3IodGhpcywga2luZCk7IH07XG4gIH07XG4gIHZhciBUQUcgPSBOQU1FICsgJyBJdGVyYXRvcic7XG4gIHZhciBERUZfVkFMVUVTID0gREVGQVVMVCA9PSBWQUxVRVM7XG4gIHZhciBWQUxVRVNfQlVHID0gZmFsc2U7XG4gIHZhciBwcm90byA9IEJhc2UucHJvdG90eXBlO1xuICB2YXIgJG5hdGl2ZSA9IHByb3RvW0lURVJBVE9SXSB8fCBwcm90b1tGRl9JVEVSQVRPUl0gfHwgREVGQVVMVCAmJiBwcm90b1tERUZBVUxUXTtcbiAgdmFyICRkZWZhdWx0ID0gJG5hdGl2ZSB8fCBnZXRNZXRob2QoREVGQVVMVCk7XG4gIHZhciAkZW50cmllcyA9IERFRkFVTFQgPyAhREVGX1ZBTFVFUyA/ICRkZWZhdWx0IDogZ2V0TWV0aG9kKCdlbnRyaWVzJykgOiB1bmRlZmluZWQ7XG4gIHZhciAkYW55TmF0aXZlID0gTkFNRSA9PSAnQXJyYXknID8gcHJvdG8uZW50cmllcyB8fCAkbmF0aXZlIDogJG5hdGl2ZTtcbiAgdmFyIG1ldGhvZHMsIGtleSwgSXRlcmF0b3JQcm90b3R5cGU7XG4gIC8vIEZpeCBuYXRpdmVcbiAgaWYgKCRhbnlOYXRpdmUpIHtcbiAgICBJdGVyYXRvclByb3RvdHlwZSA9IGdldFByb3RvdHlwZU9mKCRhbnlOYXRpdmUuY2FsbChuZXcgQmFzZSgpKSk7XG4gICAgaWYgKEl0ZXJhdG9yUHJvdG90eXBlICE9PSBPYmplY3QucHJvdG90eXBlICYmIEl0ZXJhdG9yUHJvdG90eXBlLm5leHQpIHtcbiAgICAgIC8vIFNldCBAQHRvU3RyaW5nVGFnIHRvIG5hdGl2ZSBpdGVyYXRvcnNcbiAgICAgIHNldFRvU3RyaW5nVGFnKEl0ZXJhdG9yUHJvdG90eXBlLCBUQUcsIHRydWUpO1xuICAgICAgLy8gZml4IGZvciBzb21lIG9sZCBlbmdpbmVzXG4gICAgICBpZiAoIUxJQlJBUlkgJiYgdHlwZW9mIEl0ZXJhdG9yUHJvdG90eXBlW0lURVJBVE9SXSAhPSAnZnVuY3Rpb24nKSBoaWRlKEl0ZXJhdG9yUHJvdG90eXBlLCBJVEVSQVRPUiwgcmV0dXJuVGhpcyk7XG4gICAgfVxuICB9XG4gIC8vIGZpeCBBcnJheSN7dmFsdWVzLCBAQGl0ZXJhdG9yfS5uYW1lIGluIFY4IC8gRkZcbiAgaWYgKERFRl9WQUxVRVMgJiYgJG5hdGl2ZSAmJiAkbmF0aXZlLm5hbWUgIT09IFZBTFVFUykge1xuICAgIFZBTFVFU19CVUcgPSB0cnVlO1xuICAgICRkZWZhdWx0ID0gZnVuY3Rpb24gdmFsdWVzKCkgeyByZXR1cm4gJG5hdGl2ZS5jYWxsKHRoaXMpOyB9O1xuICB9XG4gIC8vIERlZmluZSBpdGVyYXRvclxuICBpZiAoKCFMSUJSQVJZIHx8IEZPUkNFRCkgJiYgKEJVR0dZIHx8IFZBTFVFU19CVUcgfHwgIXByb3RvW0lURVJBVE9SXSkpIHtcbiAgICBoaWRlKHByb3RvLCBJVEVSQVRPUiwgJGRlZmF1bHQpO1xuICB9XG4gIC8vIFBsdWcgZm9yIGxpYnJhcnlcbiAgSXRlcmF0b3JzW05BTUVdID0gJGRlZmF1bHQ7XG4gIEl0ZXJhdG9yc1tUQUddID0gcmV0dXJuVGhpcztcbiAgaWYgKERFRkFVTFQpIHtcbiAgICBtZXRob2RzID0ge1xuICAgICAgdmFsdWVzOiBERUZfVkFMVUVTID8gJGRlZmF1bHQgOiBnZXRNZXRob2QoVkFMVUVTKSxcbiAgICAgIGtleXM6IElTX1NFVCA/ICRkZWZhdWx0IDogZ2V0TWV0aG9kKEtFWVMpLFxuICAgICAgZW50cmllczogJGVudHJpZXNcbiAgICB9O1xuICAgIGlmIChGT1JDRUQpIGZvciAoa2V5IGluIG1ldGhvZHMpIHtcbiAgICAgIGlmICghKGtleSBpbiBwcm90bykpIHJlZGVmaW5lKHByb3RvLCBrZXksIG1ldGhvZHNba2V5XSk7XG4gICAgfSBlbHNlICRleHBvcnQoJGV4cG9ydC5QICsgJGV4cG9ydC5GICogKEJVR0dZIHx8IFZBTFVFU19CVUcpLCBOQU1FLCBtZXRob2RzKTtcbiAgfVxuICByZXR1cm4gbWV0aG9kcztcbn07XG4iLCJ2YXIgSVRFUkFUT1IgPSByZXF1aXJlKCcuL193a3MnKSgnaXRlcmF0b3InKTtcbnZhciBTQUZFX0NMT1NJTkcgPSBmYWxzZTtcblxudHJ5IHtcbiAgdmFyIHJpdGVyID0gWzddW0lURVJBVE9SXSgpO1xuICByaXRlclsncmV0dXJuJ10gPSBmdW5jdGlvbiAoKSB7IFNBRkVfQ0xPU0lORyA9IHRydWU7IH07XG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby10aHJvdy1saXRlcmFsXG4gIEFycmF5LmZyb20ocml0ZXIsIGZ1bmN0aW9uICgpIHsgdGhyb3cgMjsgfSk7XG59IGNhdGNoIChlKSB7IC8qIGVtcHR5ICovIH1cblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoZXhlYywgc2tpcENsb3NpbmcpIHtcbiAgaWYgKCFza2lwQ2xvc2luZyAmJiAhU0FGRV9DTE9TSU5HKSByZXR1cm4gZmFsc2U7XG4gIHZhciBzYWZlID0gZmFsc2U7XG4gIHRyeSB7XG4gICAgdmFyIGFyciA9IFs3XTtcbiAgICB2YXIgaXRlciA9IGFycltJVEVSQVRPUl0oKTtcbiAgICBpdGVyLm5leHQgPSBmdW5jdGlvbiAoKSB7IHJldHVybiB7IGRvbmU6IHNhZmUgPSB0cnVlIH07IH07XG4gICAgYXJyW0lURVJBVE9SXSA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIGl0ZXI7IH07XG4gICAgZXhlYyhhcnIpO1xuICB9IGNhdGNoIChlKSB7IC8qIGVtcHR5ICovIH1cbiAgcmV0dXJuIHNhZmU7XG59O1xuIiwibW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoZG9uZSwgdmFsdWUpIHtcbiAgcmV0dXJuIHsgdmFsdWU6IHZhbHVlLCBkb25lOiAhIWRvbmUgfTtcbn07XG4iLCJtb2R1bGUuZXhwb3J0cyA9IHt9O1xuIiwibW9kdWxlLmV4cG9ydHMgPSBmYWxzZTtcbiIsIi8vIDIwLjIuMi4xNCBNYXRoLmV4cG0xKHgpXG52YXIgJGV4cG0xID0gTWF0aC5leHBtMTtcbm1vZHVsZS5leHBvcnRzID0gKCEkZXhwbTFcbiAgLy8gT2xkIEZGIGJ1Z1xuICB8fCAkZXhwbTEoMTApID4gMjIwMjUuNDY1Nzk0ODA2NzE5IHx8ICRleHBtMSgxMCkgPCAyMjAyNS40NjU3OTQ4MDY3MTY1MTY4XG4gIC8vIFRvciBCcm93c2VyIGJ1Z1xuICB8fCAkZXhwbTEoLTJlLTE3KSAhPSAtMmUtMTdcbikgPyBmdW5jdGlvbiBleHBtMSh4KSB7XG4gIHJldHVybiAoeCA9ICt4KSA9PSAwID8geCA6IHggPiAtMWUtNiAmJiB4IDwgMWUtNiA/IHggKyB4ICogeCAvIDIgOiBNYXRoLmV4cCh4KSAtIDE7XG59IDogJGV4cG0xO1xuIiwiLy8gMjAuMi4yLjE2IE1hdGguZnJvdW5kKHgpXG52YXIgc2lnbiA9IHJlcXVpcmUoJy4vX21hdGgtc2lnbicpO1xudmFyIHBvdyA9IE1hdGgucG93O1xudmFyIEVQU0lMT04gPSBwb3coMiwgLTUyKTtcbnZhciBFUFNJTE9OMzIgPSBwb3coMiwgLTIzKTtcbnZhciBNQVgzMiA9IHBvdygyLCAxMjcpICogKDIgLSBFUFNJTE9OMzIpO1xudmFyIE1JTjMyID0gcG93KDIsIC0xMjYpO1xuXG52YXIgcm91bmRUaWVzVG9FdmVuID0gZnVuY3Rpb24gKG4pIHtcbiAgcmV0dXJuIG4gKyAxIC8gRVBTSUxPTiAtIDEgLyBFUFNJTE9OO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBNYXRoLmZyb3VuZCB8fCBmdW5jdGlvbiBmcm91bmQoeCkge1xuICB2YXIgJGFicyA9IE1hdGguYWJzKHgpO1xuICB2YXIgJHNpZ24gPSBzaWduKHgpO1xuICB2YXIgYSwgcmVzdWx0O1xuICBpZiAoJGFicyA8IE1JTjMyKSByZXR1cm4gJHNpZ24gKiByb3VuZFRpZXNUb0V2ZW4oJGFicyAvIE1JTjMyIC8gRVBTSUxPTjMyKSAqIE1JTjMyICogRVBTSUxPTjMyO1xuICBhID0gKDEgKyBFUFNJTE9OMzIgLyBFUFNJTE9OKSAqICRhYnM7XG4gIHJlc3VsdCA9IGEgLSAoYSAtICRhYnMpO1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tc2VsZi1jb21wYXJlXG4gIGlmIChyZXN1bHQgPiBNQVgzMiB8fCByZXN1bHQgIT0gcmVzdWx0KSByZXR1cm4gJHNpZ24gKiBJbmZpbml0eTtcbiAgcmV0dXJuICRzaWduICogcmVzdWx0O1xufTtcbiIsIi8vIDIwLjIuMi4yMCBNYXRoLmxvZzFwKHgpXG5tb2R1bGUuZXhwb3J0cyA9IE1hdGgubG9nMXAgfHwgZnVuY3Rpb24gbG9nMXAoeCkge1xuICByZXR1cm4gKHggPSAreCkgPiAtMWUtOCAmJiB4IDwgMWUtOCA/IHggLSB4ICogeCAvIDIgOiBNYXRoLmxvZygxICsgeCk7XG59O1xuIiwiLy8gMjAuMi4yLjI4IE1hdGguc2lnbih4KVxubW9kdWxlLmV4cG9ydHMgPSBNYXRoLnNpZ24gfHwgZnVuY3Rpb24gc2lnbih4KSB7XG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1zZWxmLWNvbXBhcmVcbiAgcmV0dXJuICh4ID0gK3gpID09IDAgfHwgeCAhPSB4ID8geCA6IHggPCAwID8gLTEgOiAxO1xufTtcbiIsInZhciBNRVRBID0gcmVxdWlyZSgnLi9fdWlkJykoJ21ldGEnKTtcbnZhciBpc09iamVjdCA9IHJlcXVpcmUoJy4vX2lzLW9iamVjdCcpO1xudmFyIGhhcyA9IHJlcXVpcmUoJy4vX2hhcycpO1xudmFyIHNldERlc2MgPSByZXF1aXJlKCcuL19vYmplY3QtZHAnKS5mO1xudmFyIGlkID0gMDtcbnZhciBpc0V4dGVuc2libGUgPSBPYmplY3QuaXNFeHRlbnNpYmxlIHx8IGZ1bmN0aW9uICgpIHtcbiAgcmV0dXJuIHRydWU7XG59O1xudmFyIEZSRUVaRSA9ICFyZXF1aXJlKCcuL19mYWlscycpKGZ1bmN0aW9uICgpIHtcbiAgcmV0dXJuIGlzRXh0ZW5zaWJsZShPYmplY3QucHJldmVudEV4dGVuc2lvbnMoe30pKTtcbn0pO1xudmFyIHNldE1ldGEgPSBmdW5jdGlvbiAoaXQpIHtcbiAgc2V0RGVzYyhpdCwgTUVUQSwgeyB2YWx1ZToge1xuICAgIGk6ICdPJyArICsraWQsIC8vIG9iamVjdCBJRFxuICAgIHc6IHt9ICAgICAgICAgIC8vIHdlYWsgY29sbGVjdGlvbnMgSURzXG4gIH0gfSk7XG59O1xudmFyIGZhc3RLZXkgPSBmdW5jdGlvbiAoaXQsIGNyZWF0ZSkge1xuICAvLyByZXR1cm4gcHJpbWl0aXZlIHdpdGggcHJlZml4XG4gIGlmICghaXNPYmplY3QoaXQpKSByZXR1cm4gdHlwZW9mIGl0ID09ICdzeW1ib2wnID8gaXQgOiAodHlwZW9mIGl0ID09ICdzdHJpbmcnID8gJ1MnIDogJ1AnKSArIGl0O1xuICBpZiAoIWhhcyhpdCwgTUVUQSkpIHtcbiAgICAvLyBjYW4ndCBzZXQgbWV0YWRhdGEgdG8gdW5jYXVnaHQgZnJvemVuIG9iamVjdFxuICAgIGlmICghaXNFeHRlbnNpYmxlKGl0KSkgcmV0dXJuICdGJztcbiAgICAvLyBub3QgbmVjZXNzYXJ5IHRvIGFkZCBtZXRhZGF0YVxuICAgIGlmICghY3JlYXRlKSByZXR1cm4gJ0UnO1xuICAgIC8vIGFkZCBtaXNzaW5nIG1ldGFkYXRhXG4gICAgc2V0TWV0YShpdCk7XG4gIC8vIHJldHVybiBvYmplY3QgSURcbiAgfSByZXR1cm4gaXRbTUVUQV0uaTtcbn07XG52YXIgZ2V0V2VhayA9IGZ1bmN0aW9uIChpdCwgY3JlYXRlKSB7XG4gIGlmICghaGFzKGl0LCBNRVRBKSkge1xuICAgIC8vIGNhbid0IHNldCBtZXRhZGF0YSB0byB1bmNhdWdodCBmcm96ZW4gb2JqZWN0XG4gICAgaWYgKCFpc0V4dGVuc2libGUoaXQpKSByZXR1cm4gdHJ1ZTtcbiAgICAvLyBub3QgbmVjZXNzYXJ5IHRvIGFkZCBtZXRhZGF0YVxuICAgIGlmICghY3JlYXRlKSByZXR1cm4gZmFsc2U7XG4gICAgLy8gYWRkIG1pc3NpbmcgbWV0YWRhdGFcbiAgICBzZXRNZXRhKGl0KTtcbiAgLy8gcmV0dXJuIGhhc2ggd2VhayBjb2xsZWN0aW9ucyBJRHNcbiAgfSByZXR1cm4gaXRbTUVUQV0udztcbn07XG4vLyBhZGQgbWV0YWRhdGEgb24gZnJlZXplLWZhbWlseSBtZXRob2RzIGNhbGxpbmdcbnZhciBvbkZyZWV6ZSA9IGZ1bmN0aW9uIChpdCkge1xuICBpZiAoRlJFRVpFICYmIG1ldGEuTkVFRCAmJiBpc0V4dGVuc2libGUoaXQpICYmICFoYXMoaXQsIE1FVEEpKSBzZXRNZXRhKGl0KTtcbiAgcmV0dXJuIGl0O1xufTtcbnZhciBtZXRhID0gbW9kdWxlLmV4cG9ydHMgPSB7XG4gIEtFWTogTUVUQSxcbiAgTkVFRDogZmFsc2UsXG4gIGZhc3RLZXk6IGZhc3RLZXksXG4gIGdldFdlYWs6IGdldFdlYWssXG4gIG9uRnJlZXplOiBvbkZyZWV6ZVxufTtcbiIsInZhciBnbG9iYWwgPSByZXF1aXJlKCcuL19nbG9iYWwnKTtcbnZhciBtYWNyb3Rhc2sgPSByZXF1aXJlKCcuL190YXNrJykuc2V0O1xudmFyIE9ic2VydmVyID0gZ2xvYmFsLk11dGF0aW9uT2JzZXJ2ZXIgfHwgZ2xvYmFsLldlYktpdE11dGF0aW9uT2JzZXJ2ZXI7XG52YXIgcHJvY2VzcyA9IGdsb2JhbC5wcm9jZXNzO1xudmFyIFByb21pc2UgPSBnbG9iYWwuUHJvbWlzZTtcbnZhciBpc05vZGUgPSByZXF1aXJlKCcuL19jb2YnKShwcm9jZXNzKSA9PSAncHJvY2Vzcyc7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKCkge1xuICB2YXIgaGVhZCwgbGFzdCwgbm90aWZ5O1xuXG4gIHZhciBmbHVzaCA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgcGFyZW50LCBmbjtcbiAgICBpZiAoaXNOb2RlICYmIChwYXJlbnQgPSBwcm9jZXNzLmRvbWFpbikpIHBhcmVudC5leGl0KCk7XG4gICAgd2hpbGUgKGhlYWQpIHtcbiAgICAgIGZuID0gaGVhZC5mbjtcbiAgICAgIGhlYWQgPSBoZWFkLm5leHQ7XG4gICAgICB0cnkge1xuICAgICAgICBmbigpO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBpZiAoaGVhZCkgbm90aWZ5KCk7XG4gICAgICAgIGVsc2UgbGFzdCA9IHVuZGVmaW5lZDtcbiAgICAgICAgdGhyb3cgZTtcbiAgICAgIH1cbiAgICB9IGxhc3QgPSB1bmRlZmluZWQ7XG4gICAgaWYgKHBhcmVudCkgcGFyZW50LmVudGVyKCk7XG4gIH07XG5cbiAgLy8gTm9kZS5qc1xuICBpZiAoaXNOb2RlKSB7XG4gICAgbm90aWZ5ID0gZnVuY3Rpb24gKCkge1xuICAgICAgcHJvY2Vzcy5uZXh0VGljayhmbHVzaCk7XG4gICAgfTtcbiAgLy8gYnJvd3NlcnMgd2l0aCBNdXRhdGlvbk9ic2VydmVyLCBleGNlcHQgaU9TIFNhZmFyaSAtIGh0dHBzOi8vZ2l0aHViLmNvbS96bG9pcm9jay9jb3JlLWpzL2lzc3Vlcy8zMzlcbiAgfSBlbHNlIGlmIChPYnNlcnZlciAmJiAhKGdsb2JhbC5uYXZpZ2F0b3IgJiYgZ2xvYmFsLm5hdmlnYXRvci5zdGFuZGFsb25lKSkge1xuICAgIHZhciB0b2dnbGUgPSB0cnVlO1xuICAgIHZhciBub2RlID0gZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUoJycpO1xuICAgIG5ldyBPYnNlcnZlcihmbHVzaCkub2JzZXJ2ZShub2RlLCB7IGNoYXJhY3RlckRhdGE6IHRydWUgfSk7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tbmV3XG4gICAgbm90aWZ5ID0gZnVuY3Rpb24gKCkge1xuICAgICAgbm9kZS5kYXRhID0gdG9nZ2xlID0gIXRvZ2dsZTtcbiAgICB9O1xuICAvLyBlbnZpcm9ubWVudHMgd2l0aCBtYXliZSBub24tY29tcGxldGVseSBjb3JyZWN0LCBidXQgZXhpc3RlbnQgUHJvbWlzZVxuICB9IGVsc2UgaWYgKFByb21pc2UgJiYgUHJvbWlzZS5yZXNvbHZlKSB7XG4gICAgLy8gUHJvbWlzZS5yZXNvbHZlIHdpdGhvdXQgYW4gYXJndW1lbnQgdGhyb3dzIGFuIGVycm9yIGluIExHIFdlYk9TIDJcbiAgICB2YXIgcHJvbWlzZSA9IFByb21pc2UucmVzb2x2ZSh1bmRlZmluZWQpO1xuICAgIG5vdGlmeSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgIHByb21pc2UudGhlbihmbHVzaCk7XG4gICAgfTtcbiAgLy8gZm9yIG90aGVyIGVudmlyb25tZW50cyAtIG1hY3JvdGFzayBiYXNlZCBvbjpcbiAgLy8gLSBzZXRJbW1lZGlhdGVcbiAgLy8gLSBNZXNzYWdlQ2hhbm5lbFxuICAvLyAtIHdpbmRvdy5wb3N0TWVzc2FnXG4gIC8vIC0gb25yZWFkeXN0YXRlY2hhbmdlXG4gIC8vIC0gc2V0VGltZW91dFxuICB9IGVsc2Uge1xuICAgIG5vdGlmeSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgIC8vIHN0cmFuZ2UgSUUgKyB3ZWJwYWNrIGRldiBzZXJ2ZXIgYnVnIC0gdXNlIC5jYWxsKGdsb2JhbClcbiAgICAgIG1hY3JvdGFzay5jYWxsKGdsb2JhbCwgZmx1c2gpO1xuICAgIH07XG4gIH1cblxuICByZXR1cm4gZnVuY3Rpb24gKGZuKSB7XG4gICAgdmFyIHRhc2sgPSB7IGZuOiBmbiwgbmV4dDogdW5kZWZpbmVkIH07XG4gICAgaWYgKGxhc3QpIGxhc3QubmV4dCA9IHRhc2s7XG4gICAgaWYgKCFoZWFkKSB7XG4gICAgICBoZWFkID0gdGFzaztcbiAgICAgIG5vdGlmeSgpO1xuICAgIH0gbGFzdCA9IHRhc2s7XG4gIH07XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuLy8gMjUuNC4xLjUgTmV3UHJvbWlzZUNhcGFiaWxpdHkoQylcbnZhciBhRnVuY3Rpb24gPSByZXF1aXJlKCcuL19hLWZ1bmN0aW9uJyk7XG5cbmZ1bmN0aW9uIFByb21pc2VDYXBhYmlsaXR5KEMpIHtcbiAgdmFyIHJlc29sdmUsIHJlamVjdDtcbiAgdGhpcy5wcm9taXNlID0gbmV3IEMoZnVuY3Rpb24gKCQkcmVzb2x2ZSwgJCRyZWplY3QpIHtcbiAgICBpZiAocmVzb2x2ZSAhPT0gdW5kZWZpbmVkIHx8IHJlamVjdCAhPT0gdW5kZWZpbmVkKSB0aHJvdyBUeXBlRXJyb3IoJ0JhZCBQcm9taXNlIGNvbnN0cnVjdG9yJyk7XG4gICAgcmVzb2x2ZSA9ICQkcmVzb2x2ZTtcbiAgICByZWplY3QgPSAkJHJlamVjdDtcbiAgfSk7XG4gIHRoaXMucmVzb2x2ZSA9IGFGdW5jdGlvbihyZXNvbHZlKTtcbiAgdGhpcy5yZWplY3QgPSBhRnVuY3Rpb24ocmVqZWN0KTtcbn1cblxubW9kdWxlLmV4cG9ydHMuZiA9IGZ1bmN0aW9uIChDKSB7XG4gIHJldHVybiBuZXcgUHJvbWlzZUNhcGFiaWxpdHkoQyk7XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuLy8gMTkuMS4yLjEgT2JqZWN0LmFzc2lnbih0YXJnZXQsIHNvdXJjZSwgLi4uKVxudmFyIGdldEtleXMgPSByZXF1aXJlKCcuL19vYmplY3Qta2V5cycpO1xudmFyIGdPUFMgPSByZXF1aXJlKCcuL19vYmplY3QtZ29wcycpO1xudmFyIHBJRSA9IHJlcXVpcmUoJy4vX29iamVjdC1waWUnKTtcbnZhciB0b09iamVjdCA9IHJlcXVpcmUoJy4vX3RvLW9iamVjdCcpO1xudmFyIElPYmplY3QgPSByZXF1aXJlKCcuL19pb2JqZWN0Jyk7XG52YXIgJGFzc2lnbiA9IE9iamVjdC5hc3NpZ247XG5cbi8vIHNob3VsZCB3b3JrIHdpdGggc3ltYm9scyBhbmQgc2hvdWxkIGhhdmUgZGV0ZXJtaW5pc3RpYyBwcm9wZXJ0eSBvcmRlciAoVjggYnVnKVxubW9kdWxlLmV4cG9ydHMgPSAhJGFzc2lnbiB8fCByZXF1aXJlKCcuL19mYWlscycpKGZ1bmN0aW9uICgpIHtcbiAgdmFyIEEgPSB7fTtcbiAgdmFyIEIgPSB7fTtcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXVuZGVmXG4gIHZhciBTID0gU3ltYm9sKCk7XG4gIHZhciBLID0gJ2FiY2RlZmdoaWprbG1ub3BxcnN0JztcbiAgQVtTXSA9IDc7XG4gIEsuc3BsaXQoJycpLmZvckVhY2goZnVuY3Rpb24gKGspIHsgQltrXSA9IGs7IH0pO1xuICByZXR1cm4gJGFzc2lnbih7fSwgQSlbU10gIT0gNyB8fCBPYmplY3Qua2V5cygkYXNzaWduKHt9LCBCKSkuam9pbignJykgIT0gSztcbn0pID8gZnVuY3Rpb24gYXNzaWduKHRhcmdldCwgc291cmNlKSB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tdW51c2VkLXZhcnNcbiAgdmFyIFQgPSB0b09iamVjdCh0YXJnZXQpO1xuICB2YXIgYUxlbiA9IGFyZ3VtZW50cy5sZW5ndGg7XG4gIHZhciBpbmRleCA9IDE7XG4gIHZhciBnZXRTeW1ib2xzID0gZ09QUy5mO1xuICB2YXIgaXNFbnVtID0gcElFLmY7XG4gIHdoaWxlIChhTGVuID4gaW5kZXgpIHtcbiAgICB2YXIgUyA9IElPYmplY3QoYXJndW1lbnRzW2luZGV4KytdKTtcbiAgICB2YXIga2V5cyA9IGdldFN5bWJvbHMgPyBnZXRLZXlzKFMpLmNvbmNhdChnZXRTeW1ib2xzKFMpKSA6IGdldEtleXMoUyk7XG4gICAgdmFyIGxlbmd0aCA9IGtleXMubGVuZ3RoO1xuICAgIHZhciBqID0gMDtcbiAgICB2YXIga2V5O1xuICAgIHdoaWxlIChsZW5ndGggPiBqKSBpZiAoaXNFbnVtLmNhbGwoUywga2V5ID0ga2V5c1tqKytdKSkgVFtrZXldID0gU1trZXldO1xuICB9IHJldHVybiBUO1xufSA6ICRhc3NpZ247XG4iLCIvLyAxOS4xLjIuMiAvIDE1LjIuMy41IE9iamVjdC5jcmVhdGUoTyBbLCBQcm9wZXJ0aWVzXSlcbnZhciBhbk9iamVjdCA9IHJlcXVpcmUoJy4vX2FuLW9iamVjdCcpO1xudmFyIGRQcyA9IHJlcXVpcmUoJy4vX29iamVjdC1kcHMnKTtcbnZhciBlbnVtQnVnS2V5cyA9IHJlcXVpcmUoJy4vX2VudW0tYnVnLWtleXMnKTtcbnZhciBJRV9QUk9UTyA9IHJlcXVpcmUoJy4vX3NoYXJlZC1rZXknKSgnSUVfUFJPVE8nKTtcbnZhciBFbXB0eSA9IGZ1bmN0aW9uICgpIHsgLyogZW1wdHkgKi8gfTtcbnZhciBQUk9UT1RZUEUgPSAncHJvdG90eXBlJztcblxuLy8gQ3JlYXRlIG9iamVjdCB3aXRoIGZha2UgYG51bGxgIHByb3RvdHlwZTogdXNlIGlmcmFtZSBPYmplY3Qgd2l0aCBjbGVhcmVkIHByb3RvdHlwZVxudmFyIGNyZWF0ZURpY3QgPSBmdW5jdGlvbiAoKSB7XG4gIC8vIFRocmFzaCwgd2FzdGUgYW5kIHNvZG9teTogSUUgR0MgYnVnXG4gIHZhciBpZnJhbWUgPSByZXF1aXJlKCcuL19kb20tY3JlYXRlJykoJ2lmcmFtZScpO1xuICB2YXIgaSA9IGVudW1CdWdLZXlzLmxlbmd0aDtcbiAgdmFyIGx0ID0gJzwnO1xuICB2YXIgZ3QgPSAnPic7XG4gIHZhciBpZnJhbWVEb2N1bWVudDtcbiAgaWZyYW1lLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG4gIHJlcXVpcmUoJy4vX2h0bWwnKS5hcHBlbmRDaGlsZChpZnJhbWUpO1xuICBpZnJhbWUuc3JjID0gJ2phdmFzY3JpcHQ6JzsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1zY3JpcHQtdXJsXG4gIC8vIGNyZWF0ZURpY3QgPSBpZnJhbWUuY29udGVudFdpbmRvdy5PYmplY3Q7XG4gIC8vIGh0bWwucmVtb3ZlQ2hpbGQoaWZyYW1lKTtcbiAgaWZyYW1lRG9jdW1lbnQgPSBpZnJhbWUuY29udGVudFdpbmRvdy5kb2N1bWVudDtcbiAgaWZyYW1lRG9jdW1lbnQub3BlbigpO1xuICBpZnJhbWVEb2N1bWVudC53cml0ZShsdCArICdzY3JpcHQnICsgZ3QgKyAnZG9jdW1lbnQuRj1PYmplY3QnICsgbHQgKyAnL3NjcmlwdCcgKyBndCk7XG4gIGlmcmFtZURvY3VtZW50LmNsb3NlKCk7XG4gIGNyZWF0ZURpY3QgPSBpZnJhbWVEb2N1bWVudC5GO1xuICB3aGlsZSAoaS0tKSBkZWxldGUgY3JlYXRlRGljdFtQUk9UT1RZUEVdW2VudW1CdWdLZXlzW2ldXTtcbiAgcmV0dXJuIGNyZWF0ZURpY3QoKTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gT2JqZWN0LmNyZWF0ZSB8fCBmdW5jdGlvbiBjcmVhdGUoTywgUHJvcGVydGllcykge1xuICB2YXIgcmVzdWx0O1xuICBpZiAoTyAhPT0gbnVsbCkge1xuICAgIEVtcHR5W1BST1RPVFlQRV0gPSBhbk9iamVjdChPKTtcbiAgICByZXN1bHQgPSBuZXcgRW1wdHkoKTtcbiAgICBFbXB0eVtQUk9UT1RZUEVdID0gbnVsbDtcbiAgICAvLyBhZGQgXCJfX3Byb3RvX19cIiBmb3IgT2JqZWN0LmdldFByb3RvdHlwZU9mIHBvbHlmaWxsXG4gICAgcmVzdWx0W0lFX1BST1RPXSA9IE87XG4gIH0gZWxzZSByZXN1bHQgPSBjcmVhdGVEaWN0KCk7XG4gIHJldHVybiBQcm9wZXJ0aWVzID09PSB1bmRlZmluZWQgPyByZXN1bHQgOiBkUHMocmVzdWx0LCBQcm9wZXJ0aWVzKTtcbn07XG4iLCJ2YXIgYW5PYmplY3QgPSByZXF1aXJlKCcuL19hbi1vYmplY3QnKTtcbnZhciBJRThfRE9NX0RFRklORSA9IHJlcXVpcmUoJy4vX2llOC1kb20tZGVmaW5lJyk7XG52YXIgdG9QcmltaXRpdmUgPSByZXF1aXJlKCcuL190by1wcmltaXRpdmUnKTtcbnZhciBkUCA9IE9iamVjdC5kZWZpbmVQcm9wZXJ0eTtcblxuZXhwb3J0cy5mID0gcmVxdWlyZSgnLi9fZGVzY3JpcHRvcnMnKSA/IE9iamVjdC5kZWZpbmVQcm9wZXJ0eSA6IGZ1bmN0aW9uIGRlZmluZVByb3BlcnR5KE8sIFAsIEF0dHJpYnV0ZXMpIHtcbiAgYW5PYmplY3QoTyk7XG4gIFAgPSB0b1ByaW1pdGl2ZShQLCB0cnVlKTtcbiAgYW5PYmplY3QoQXR0cmlidXRlcyk7XG4gIGlmIChJRThfRE9NX0RFRklORSkgdHJ5IHtcbiAgICByZXR1cm4gZFAoTywgUCwgQXR0cmlidXRlcyk7XG4gIH0gY2F0Y2ggKGUpIHsgLyogZW1wdHkgKi8gfVxuICBpZiAoJ2dldCcgaW4gQXR0cmlidXRlcyB8fCAnc2V0JyBpbiBBdHRyaWJ1dGVzKSB0aHJvdyBUeXBlRXJyb3IoJ0FjY2Vzc29ycyBub3Qgc3VwcG9ydGVkIScpO1xuICBpZiAoJ3ZhbHVlJyBpbiBBdHRyaWJ1dGVzKSBPW1BdID0gQXR0cmlidXRlcy52YWx1ZTtcbiAgcmV0dXJuIE87XG59O1xuIiwidmFyIGRQID0gcmVxdWlyZSgnLi9fb2JqZWN0LWRwJyk7XG52YXIgYW5PYmplY3QgPSByZXF1aXJlKCcuL19hbi1vYmplY3QnKTtcbnZhciBnZXRLZXlzID0gcmVxdWlyZSgnLi9fb2JqZWN0LWtleXMnKTtcblxubW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuL19kZXNjcmlwdG9ycycpID8gT2JqZWN0LmRlZmluZVByb3BlcnRpZXMgOiBmdW5jdGlvbiBkZWZpbmVQcm9wZXJ0aWVzKE8sIFByb3BlcnRpZXMpIHtcbiAgYW5PYmplY3QoTyk7XG4gIHZhciBrZXlzID0gZ2V0S2V5cyhQcm9wZXJ0aWVzKTtcbiAgdmFyIGxlbmd0aCA9IGtleXMubGVuZ3RoO1xuICB2YXIgaSA9IDA7XG4gIHZhciBQO1xuICB3aGlsZSAobGVuZ3RoID4gaSkgZFAuZihPLCBQID0ga2V5c1tpKytdLCBQcm9wZXJ0aWVzW1BdKTtcbiAgcmV0dXJuIE87XG59O1xuIiwidmFyIHBJRSA9IHJlcXVpcmUoJy4vX29iamVjdC1waWUnKTtcbnZhciBjcmVhdGVEZXNjID0gcmVxdWlyZSgnLi9fcHJvcGVydHktZGVzYycpO1xudmFyIHRvSU9iamVjdCA9IHJlcXVpcmUoJy4vX3RvLWlvYmplY3QnKTtcbnZhciB0b1ByaW1pdGl2ZSA9IHJlcXVpcmUoJy4vX3RvLXByaW1pdGl2ZScpO1xudmFyIGhhcyA9IHJlcXVpcmUoJy4vX2hhcycpO1xudmFyIElFOF9ET01fREVGSU5FID0gcmVxdWlyZSgnLi9faWU4LWRvbS1kZWZpbmUnKTtcbnZhciBnT1BEID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcjtcblxuZXhwb3J0cy5mID0gcmVxdWlyZSgnLi9fZGVzY3JpcHRvcnMnKSA/IGdPUEQgOiBmdW5jdGlvbiBnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IoTywgUCkge1xuICBPID0gdG9JT2JqZWN0KE8pO1xuICBQID0gdG9QcmltaXRpdmUoUCwgdHJ1ZSk7XG4gIGlmIChJRThfRE9NX0RFRklORSkgdHJ5IHtcbiAgICByZXR1cm4gZ09QRChPLCBQKTtcbiAgfSBjYXRjaCAoZSkgeyAvKiBlbXB0eSAqLyB9XG4gIGlmIChoYXMoTywgUCkpIHJldHVybiBjcmVhdGVEZXNjKCFwSUUuZi5jYWxsKE8sIFApLCBPW1BdKTtcbn07XG4iLCIvLyBmYWxsYmFjayBmb3IgSUUxMSBidWdneSBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyB3aXRoIGlmcmFtZSBhbmQgd2luZG93XG52YXIgdG9JT2JqZWN0ID0gcmVxdWlyZSgnLi9fdG8taW9iamVjdCcpO1xudmFyIGdPUE4gPSByZXF1aXJlKCcuL19vYmplY3QtZ29wbicpLmY7XG52YXIgdG9TdHJpbmcgPSB7fS50b1N0cmluZztcblxudmFyIHdpbmRvd05hbWVzID0gdHlwZW9mIHdpbmRvdyA9PSAnb2JqZWN0JyAmJiB3aW5kb3cgJiYgT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXNcbiAgPyBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyh3aW5kb3cpIDogW107XG5cbnZhciBnZXRXaW5kb3dOYW1lcyA9IGZ1bmN0aW9uIChpdCkge1xuICB0cnkge1xuICAgIHJldHVybiBnT1BOKGl0KTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIHJldHVybiB3aW5kb3dOYW1lcy5zbGljZSgpO1xuICB9XG59O1xuXG5tb2R1bGUuZXhwb3J0cy5mID0gZnVuY3Rpb24gZ2V0T3duUHJvcGVydHlOYW1lcyhpdCkge1xuICByZXR1cm4gd2luZG93TmFtZXMgJiYgdG9TdHJpbmcuY2FsbChpdCkgPT0gJ1tvYmplY3QgV2luZG93XScgPyBnZXRXaW5kb3dOYW1lcyhpdCkgOiBnT1BOKHRvSU9iamVjdChpdCkpO1xufTtcbiIsIi8vIDE5LjEuMi43IC8gMTUuMi4zLjQgT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXMoTylcbnZhciAka2V5cyA9IHJlcXVpcmUoJy4vX29iamVjdC1rZXlzLWludGVybmFsJyk7XG52YXIgaGlkZGVuS2V5cyA9IHJlcXVpcmUoJy4vX2VudW0tYnVnLWtleXMnKS5jb25jYXQoJ2xlbmd0aCcsICdwcm90b3R5cGUnKTtcblxuZXhwb3J0cy5mID0gT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXMgfHwgZnVuY3Rpb24gZ2V0T3duUHJvcGVydHlOYW1lcyhPKSB7XG4gIHJldHVybiAka2V5cyhPLCBoaWRkZW5LZXlzKTtcbn07XG4iLCJleHBvcnRzLmYgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlTeW1ib2xzO1xuIiwiLy8gMTkuMS4yLjkgLyAxNS4yLjMuMiBPYmplY3QuZ2V0UHJvdG90eXBlT2YoTylcbnZhciBoYXMgPSByZXF1aXJlKCcuL19oYXMnKTtcbnZhciB0b09iamVjdCA9IHJlcXVpcmUoJy4vX3RvLW9iamVjdCcpO1xudmFyIElFX1BST1RPID0gcmVxdWlyZSgnLi9fc2hhcmVkLWtleScpKCdJRV9QUk9UTycpO1xudmFyIE9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZTtcblxubW9kdWxlLmV4cG9ydHMgPSBPYmplY3QuZ2V0UHJvdG90eXBlT2YgfHwgZnVuY3Rpb24gKE8pIHtcbiAgTyA9IHRvT2JqZWN0KE8pO1xuICBpZiAoaGFzKE8sIElFX1BST1RPKSkgcmV0dXJuIE9bSUVfUFJPVE9dO1xuICBpZiAodHlwZW9mIE8uY29uc3RydWN0b3IgPT0gJ2Z1bmN0aW9uJyAmJiBPIGluc3RhbmNlb2YgTy5jb25zdHJ1Y3Rvcikge1xuICAgIHJldHVybiBPLmNvbnN0cnVjdG9yLnByb3RvdHlwZTtcbiAgfSByZXR1cm4gTyBpbnN0YW5jZW9mIE9iamVjdCA/IE9iamVjdFByb3RvIDogbnVsbDtcbn07XG4iLCJ2YXIgaGFzID0gcmVxdWlyZSgnLi9faGFzJyk7XG52YXIgdG9JT2JqZWN0ID0gcmVxdWlyZSgnLi9fdG8taW9iamVjdCcpO1xudmFyIGFycmF5SW5kZXhPZiA9IHJlcXVpcmUoJy4vX2FycmF5LWluY2x1ZGVzJykoZmFsc2UpO1xudmFyIElFX1BST1RPID0gcmVxdWlyZSgnLi9fc2hhcmVkLWtleScpKCdJRV9QUk9UTycpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChvYmplY3QsIG5hbWVzKSB7XG4gIHZhciBPID0gdG9JT2JqZWN0KG9iamVjdCk7XG4gIHZhciBpID0gMDtcbiAgdmFyIHJlc3VsdCA9IFtdO1xuICB2YXIga2V5O1xuICBmb3IgKGtleSBpbiBPKSBpZiAoa2V5ICE9IElFX1BST1RPKSBoYXMoTywga2V5KSAmJiByZXN1bHQucHVzaChrZXkpO1xuICAvLyBEb24ndCBlbnVtIGJ1ZyAmIGhpZGRlbiBrZXlzXG4gIHdoaWxlIChuYW1lcy5sZW5ndGggPiBpKSBpZiAoaGFzKE8sIGtleSA9IG5hbWVzW2krK10pKSB7XG4gICAgfmFycmF5SW5kZXhPZihyZXN1bHQsIGtleSkgfHwgcmVzdWx0LnB1c2goa2V5KTtcbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufTtcbiIsIi8vIDE5LjEuMi4xNCAvIDE1LjIuMy4xNCBPYmplY3Qua2V5cyhPKVxudmFyICRrZXlzID0gcmVxdWlyZSgnLi9fb2JqZWN0LWtleXMtaW50ZXJuYWwnKTtcbnZhciBlbnVtQnVnS2V5cyA9IHJlcXVpcmUoJy4vX2VudW0tYnVnLWtleXMnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBPYmplY3Qua2V5cyB8fCBmdW5jdGlvbiBrZXlzKE8pIHtcbiAgcmV0dXJuICRrZXlzKE8sIGVudW1CdWdLZXlzKTtcbn07XG4iLCJleHBvcnRzLmYgPSB7fS5wcm9wZXJ0eUlzRW51bWVyYWJsZTtcbiIsIi8vIG1vc3QgT2JqZWN0IG1ldGhvZHMgYnkgRVM2IHNob3VsZCBhY2NlcHQgcHJpbWl0aXZlc1xudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciBjb3JlID0gcmVxdWlyZSgnLi9fY29yZScpO1xudmFyIGZhaWxzID0gcmVxdWlyZSgnLi9fZmFpbHMnKTtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKEtFWSwgZXhlYykge1xuICB2YXIgZm4gPSAoY29yZS5PYmplY3QgfHwge30pW0tFWV0gfHwgT2JqZWN0W0tFWV07XG4gIHZhciBleHAgPSB7fTtcbiAgZXhwW0tFWV0gPSBleGVjKGZuKTtcbiAgJGV4cG9ydCgkZXhwb3J0LlMgKyAkZXhwb3J0LkYgKiBmYWlscyhmdW5jdGlvbiAoKSB7IGZuKDEpOyB9KSwgJ09iamVjdCcsIGV4cCk7XG59O1xuIiwidmFyIGdldEtleXMgPSByZXF1aXJlKCcuL19vYmplY3Qta2V5cycpO1xudmFyIHRvSU9iamVjdCA9IHJlcXVpcmUoJy4vX3RvLWlvYmplY3QnKTtcbnZhciBpc0VudW0gPSByZXF1aXJlKCcuL19vYmplY3QtcGllJykuZjtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGlzRW50cmllcykge1xuICByZXR1cm4gZnVuY3Rpb24gKGl0KSB7XG4gICAgdmFyIE8gPSB0b0lPYmplY3QoaXQpO1xuICAgIHZhciBrZXlzID0gZ2V0S2V5cyhPKTtcbiAgICB2YXIgbGVuZ3RoID0ga2V5cy5sZW5ndGg7XG4gICAgdmFyIGkgPSAwO1xuICAgIHZhciByZXN1bHQgPSBbXTtcbiAgICB2YXIga2V5O1xuICAgIHdoaWxlIChsZW5ndGggPiBpKSBpZiAoaXNFbnVtLmNhbGwoTywga2V5ID0ga2V5c1tpKytdKSkge1xuICAgICAgcmVzdWx0LnB1c2goaXNFbnRyaWVzID8gW2tleSwgT1trZXldXSA6IE9ba2V5XSk7XG4gICAgfSByZXR1cm4gcmVzdWx0O1xuICB9O1xufTtcbiIsIi8vIGFsbCBvYmplY3Qga2V5cywgaW5jbHVkZXMgbm9uLWVudW1lcmFibGUgYW5kIHN5bWJvbHNcbnZhciBnT1BOID0gcmVxdWlyZSgnLi9fb2JqZWN0LWdvcG4nKTtcbnZhciBnT1BTID0gcmVxdWlyZSgnLi9fb2JqZWN0LWdvcHMnKTtcbnZhciBhbk9iamVjdCA9IHJlcXVpcmUoJy4vX2FuLW9iamVjdCcpO1xudmFyIFJlZmxlY3QgPSByZXF1aXJlKCcuL19nbG9iYWwnKS5SZWZsZWN0O1xubW9kdWxlLmV4cG9ydHMgPSBSZWZsZWN0ICYmIFJlZmxlY3Qub3duS2V5cyB8fCBmdW5jdGlvbiBvd25LZXlzKGl0KSB7XG4gIHZhciBrZXlzID0gZ09QTi5mKGFuT2JqZWN0KGl0KSk7XG4gIHZhciBnZXRTeW1ib2xzID0gZ09QUy5mO1xuICByZXR1cm4gZ2V0U3ltYm9scyA/IGtleXMuY29uY2F0KGdldFN5bWJvbHMoaXQpKSA6IGtleXM7XG59O1xuIiwidmFyICRwYXJzZUZsb2F0ID0gcmVxdWlyZSgnLi9fZ2xvYmFsJykucGFyc2VGbG9hdDtcbnZhciAkdHJpbSA9IHJlcXVpcmUoJy4vX3N0cmluZy10cmltJykudHJpbTtcblxubW9kdWxlLmV4cG9ydHMgPSAxIC8gJHBhcnNlRmxvYXQocmVxdWlyZSgnLi9fc3RyaW5nLXdzJykgKyAnLTAnKSAhPT0gLUluZmluaXR5ID8gZnVuY3Rpb24gcGFyc2VGbG9hdChzdHIpIHtcbiAgdmFyIHN0cmluZyA9ICR0cmltKFN0cmluZyhzdHIpLCAzKTtcbiAgdmFyIHJlc3VsdCA9ICRwYXJzZUZsb2F0KHN0cmluZyk7XG4gIHJldHVybiByZXN1bHQgPT09IDAgJiYgc3RyaW5nLmNoYXJBdCgwKSA9PSAnLScgPyAtMCA6IHJlc3VsdDtcbn0gOiAkcGFyc2VGbG9hdDtcbiIsInZhciAkcGFyc2VJbnQgPSByZXF1aXJlKCcuL19nbG9iYWwnKS5wYXJzZUludDtcbnZhciAkdHJpbSA9IHJlcXVpcmUoJy4vX3N0cmluZy10cmltJykudHJpbTtcbnZhciB3cyA9IHJlcXVpcmUoJy4vX3N0cmluZy13cycpO1xudmFyIGhleCA9IC9eWy0rXT8wW3hYXS87XG5cbm1vZHVsZS5leHBvcnRzID0gJHBhcnNlSW50KHdzICsgJzA4JykgIT09IDggfHwgJHBhcnNlSW50KHdzICsgJzB4MTYnKSAhPT0gMjIgPyBmdW5jdGlvbiBwYXJzZUludChzdHIsIHJhZGl4KSB7XG4gIHZhciBzdHJpbmcgPSAkdHJpbShTdHJpbmcoc3RyKSwgMyk7XG4gIHJldHVybiAkcGFyc2VJbnQoc3RyaW5nLCAocmFkaXggPj4+IDApIHx8IChoZXgudGVzdChzdHJpbmcpID8gMTYgOiAxMCkpO1xufSA6ICRwYXJzZUludDtcbiIsIm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGV4ZWMpIHtcbiAgdHJ5IHtcbiAgICByZXR1cm4geyBlOiBmYWxzZSwgdjogZXhlYygpIH07XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICByZXR1cm4geyBlOiB0cnVlLCB2OiBlIH07XG4gIH1cbn07XG4iLCJ2YXIgYW5PYmplY3QgPSByZXF1aXJlKCcuL19hbi1vYmplY3QnKTtcbnZhciBpc09iamVjdCA9IHJlcXVpcmUoJy4vX2lzLW9iamVjdCcpO1xudmFyIG5ld1Byb21pc2VDYXBhYmlsaXR5ID0gcmVxdWlyZSgnLi9fbmV3LXByb21pc2UtY2FwYWJpbGl0eScpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChDLCB4KSB7XG4gIGFuT2JqZWN0KEMpO1xuICBpZiAoaXNPYmplY3QoeCkgJiYgeC5jb25zdHJ1Y3RvciA9PT0gQykgcmV0dXJuIHg7XG4gIHZhciBwcm9taXNlQ2FwYWJpbGl0eSA9IG5ld1Byb21pc2VDYXBhYmlsaXR5LmYoQyk7XG4gIHZhciByZXNvbHZlID0gcHJvbWlzZUNhcGFiaWxpdHkucmVzb2x2ZTtcbiAgcmVzb2x2ZSh4KTtcbiAgcmV0dXJuIHByb21pc2VDYXBhYmlsaXR5LnByb21pc2U7XG59O1xuIiwibW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoYml0bWFwLCB2YWx1ZSkge1xuICByZXR1cm4ge1xuICAgIGVudW1lcmFibGU6ICEoYml0bWFwICYgMSksXG4gICAgY29uZmlndXJhYmxlOiAhKGJpdG1hcCAmIDIpLFxuICAgIHdyaXRhYmxlOiAhKGJpdG1hcCAmIDQpLFxuICAgIHZhbHVlOiB2YWx1ZVxuICB9O1xufTtcbiIsInZhciByZWRlZmluZSA9IHJlcXVpcmUoJy4vX3JlZGVmaW5lJyk7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uICh0YXJnZXQsIHNyYywgc2FmZSkge1xuICBmb3IgKHZhciBrZXkgaW4gc3JjKSByZWRlZmluZSh0YXJnZXQsIGtleSwgc3JjW2tleV0sIHNhZmUpO1xuICByZXR1cm4gdGFyZ2V0O1xufTtcbiIsInZhciBnbG9iYWwgPSByZXF1aXJlKCcuL19nbG9iYWwnKTtcbnZhciBoaWRlID0gcmVxdWlyZSgnLi9faGlkZScpO1xudmFyIGhhcyA9IHJlcXVpcmUoJy4vX2hhcycpO1xudmFyIFNSQyA9IHJlcXVpcmUoJy4vX3VpZCcpKCdzcmMnKTtcbnZhciBUT19TVFJJTkcgPSAndG9TdHJpbmcnO1xudmFyICR0b1N0cmluZyA9IEZ1bmN0aW9uW1RPX1NUUklOR107XG52YXIgVFBMID0gKCcnICsgJHRvU3RyaW5nKS5zcGxpdChUT19TVFJJTkcpO1xuXG5yZXF1aXJlKCcuL19jb3JlJykuaW5zcGVjdFNvdXJjZSA9IGZ1bmN0aW9uIChpdCkge1xuICByZXR1cm4gJHRvU3RyaW5nLmNhbGwoaXQpO1xufTtcblxuKG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKE8sIGtleSwgdmFsLCBzYWZlKSB7XG4gIHZhciBpc0Z1bmN0aW9uID0gdHlwZW9mIHZhbCA9PSAnZnVuY3Rpb24nO1xuICBpZiAoaXNGdW5jdGlvbikgaGFzKHZhbCwgJ25hbWUnKSB8fCBoaWRlKHZhbCwgJ25hbWUnLCBrZXkpO1xuICBpZiAoT1trZXldID09PSB2YWwpIHJldHVybjtcbiAgaWYgKGlzRnVuY3Rpb24pIGhhcyh2YWwsIFNSQykgfHwgaGlkZSh2YWwsIFNSQywgT1trZXldID8gJycgKyBPW2tleV0gOiBUUEwuam9pbihTdHJpbmcoa2V5KSkpO1xuICBpZiAoTyA9PT0gZ2xvYmFsKSB7XG4gICAgT1trZXldID0gdmFsO1xuICB9IGVsc2UgaWYgKCFzYWZlKSB7XG4gICAgZGVsZXRlIE9ba2V5XTtcbiAgICBoaWRlKE8sIGtleSwgdmFsKTtcbiAgfSBlbHNlIGlmIChPW2tleV0pIHtcbiAgICBPW2tleV0gPSB2YWw7XG4gIH0gZWxzZSB7XG4gICAgaGlkZShPLCBrZXksIHZhbCk7XG4gIH1cbi8vIGFkZCBmYWtlIEZ1bmN0aW9uI3RvU3RyaW5nIGZvciBjb3JyZWN0IHdvcmsgd3JhcHBlZCBtZXRob2RzIC8gY29uc3RydWN0b3JzIHdpdGggbWV0aG9kcyBsaWtlIExvRGFzaCBpc05hdGl2ZVxufSkoRnVuY3Rpb24ucHJvdG90eXBlLCBUT19TVFJJTkcsIGZ1bmN0aW9uIHRvU3RyaW5nKCkge1xuICByZXR1cm4gdHlwZW9mIHRoaXMgPT0gJ2Z1bmN0aW9uJyAmJiB0aGlzW1NSQ10gfHwgJHRvU3RyaW5nLmNhbGwodGhpcyk7XG59KTtcbiIsIi8vIDcuMi45IFNhbWVWYWx1ZSh4LCB5KVxubW9kdWxlLmV4cG9ydHMgPSBPYmplY3QuaXMgfHwgZnVuY3Rpb24gaXMoeCwgeSkge1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tc2VsZi1jb21wYXJlXG4gIHJldHVybiB4ID09PSB5ID8geCAhPT0gMCB8fCAxIC8geCA9PT0gMSAvIHkgOiB4ICE9IHggJiYgeSAhPSB5O1xufTtcbiIsIi8vIFdvcmtzIHdpdGggX19wcm90b19fIG9ubHkuIE9sZCB2OCBjYW4ndCB3b3JrIHdpdGggbnVsbCBwcm90byBvYmplY3RzLlxuLyogZXNsaW50LWRpc2FibGUgbm8tcHJvdG8gKi9cbnZhciBpc09iamVjdCA9IHJlcXVpcmUoJy4vX2lzLW9iamVjdCcpO1xudmFyIGFuT2JqZWN0ID0gcmVxdWlyZSgnLi9fYW4tb2JqZWN0Jyk7XG52YXIgY2hlY2sgPSBmdW5jdGlvbiAoTywgcHJvdG8pIHtcbiAgYW5PYmplY3QoTyk7XG4gIGlmICghaXNPYmplY3QocHJvdG8pICYmIHByb3RvICE9PSBudWxsKSB0aHJvdyBUeXBlRXJyb3IocHJvdG8gKyBcIjogY2FuJ3Qgc2V0IGFzIHByb3RvdHlwZSFcIik7XG59O1xubW9kdWxlLmV4cG9ydHMgPSB7XG4gIHNldDogT2JqZWN0LnNldFByb3RvdHlwZU9mIHx8ICgnX19wcm90b19fJyBpbiB7fSA/IC8vIGVzbGludC1kaXNhYmxlLWxpbmVcbiAgICBmdW5jdGlvbiAodGVzdCwgYnVnZ3ksIHNldCkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgc2V0ID0gcmVxdWlyZSgnLi9fY3R4JykoRnVuY3Rpb24uY2FsbCwgcmVxdWlyZSgnLi9fb2JqZWN0LWdvcGQnKS5mKE9iamVjdC5wcm90b3R5cGUsICdfX3Byb3RvX18nKS5zZXQsIDIpO1xuICAgICAgICBzZXQodGVzdCwgW10pO1xuICAgICAgICBidWdneSA9ICEodGVzdCBpbnN0YW5jZW9mIEFycmF5KTtcbiAgICAgIH0gY2F0Y2ggKGUpIHsgYnVnZ3kgPSB0cnVlOyB9XG4gICAgICByZXR1cm4gZnVuY3Rpb24gc2V0UHJvdG90eXBlT2YoTywgcHJvdG8pIHtcbiAgICAgICAgY2hlY2soTywgcHJvdG8pO1xuICAgICAgICBpZiAoYnVnZ3kpIE8uX19wcm90b19fID0gcHJvdG87XG4gICAgICAgIGVsc2Ugc2V0KE8sIHByb3RvKTtcbiAgICAgICAgcmV0dXJuIE87XG4gICAgICB9O1xuICAgIH0oe30sIGZhbHNlKSA6IHVuZGVmaW5lZCksXG4gIGNoZWNrOiBjaGVja1xufTtcbiIsIid1c2Ugc3RyaWN0JztcbnZhciBnbG9iYWwgPSByZXF1aXJlKCcuL19nbG9iYWwnKTtcbnZhciBkUCA9IHJlcXVpcmUoJy4vX29iamVjdC1kcCcpO1xudmFyIERFU0NSSVBUT1JTID0gcmVxdWlyZSgnLi9fZGVzY3JpcHRvcnMnKTtcbnZhciBTUEVDSUVTID0gcmVxdWlyZSgnLi9fd2tzJykoJ3NwZWNpZXMnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoS0VZKSB7XG4gIHZhciBDID0gZ2xvYmFsW0tFWV07XG4gIGlmIChERVNDUklQVE9SUyAmJiBDICYmICFDW1NQRUNJRVNdKSBkUC5mKEMsIFNQRUNJRVMsIHtcbiAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiB0aGlzOyB9XG4gIH0pO1xufTtcbiIsInZhciBkZWYgPSByZXF1aXJlKCcuL19vYmplY3QtZHAnKS5mO1xudmFyIGhhcyA9IHJlcXVpcmUoJy4vX2hhcycpO1xudmFyIFRBRyA9IHJlcXVpcmUoJy4vX3drcycpKCd0b1N0cmluZ1RhZycpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChpdCwgdGFnLCBzdGF0KSB7XG4gIGlmIChpdCAmJiAhaGFzKGl0ID0gc3RhdCA/IGl0IDogaXQucHJvdG90eXBlLCBUQUcpKSBkZWYoaXQsIFRBRywgeyBjb25maWd1cmFibGU6IHRydWUsIHZhbHVlOiB0YWcgfSk7XG59O1xuIiwidmFyIHNoYXJlZCA9IHJlcXVpcmUoJy4vX3NoYXJlZCcpKCdrZXlzJyk7XG52YXIgdWlkID0gcmVxdWlyZSgnLi9fdWlkJyk7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChrZXkpIHtcbiAgcmV0dXJuIHNoYXJlZFtrZXldIHx8IChzaGFyZWRba2V5XSA9IHVpZChrZXkpKTtcbn07XG4iLCJ2YXIgY29yZSA9IHJlcXVpcmUoJy4vX2NvcmUnKTtcbnZhciBnbG9iYWwgPSByZXF1aXJlKCcuL19nbG9iYWwnKTtcbnZhciBTSEFSRUQgPSAnX19jb3JlLWpzX3NoYXJlZF9fJztcbnZhciBzdG9yZSA9IGdsb2JhbFtTSEFSRURdIHx8IChnbG9iYWxbU0hBUkVEXSA9IHt9KTtcblxuKG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGtleSwgdmFsdWUpIHtcbiAgcmV0dXJuIHN0b3JlW2tleV0gfHwgKHN0b3JlW2tleV0gPSB2YWx1ZSAhPT0gdW5kZWZpbmVkID8gdmFsdWUgOiB7fSk7XG59KSgndmVyc2lvbnMnLCBbXSkucHVzaCh7XG4gIHZlcnNpb246IGNvcmUudmVyc2lvbixcbiAgbW9kZTogcmVxdWlyZSgnLi9fbGlicmFyeScpID8gJ3B1cmUnIDogJ2dsb2JhbCcsXG4gIGNvcHlyaWdodDogJ8KpIDIwMTggRGVuaXMgUHVzaGthcmV2ICh6bG9pcm9jay5ydSknXG59KTtcbiIsIi8vIDcuMy4yMCBTcGVjaWVzQ29uc3RydWN0b3IoTywgZGVmYXVsdENvbnN0cnVjdG9yKVxudmFyIGFuT2JqZWN0ID0gcmVxdWlyZSgnLi9fYW4tb2JqZWN0Jyk7XG52YXIgYUZ1bmN0aW9uID0gcmVxdWlyZSgnLi9fYS1mdW5jdGlvbicpO1xudmFyIFNQRUNJRVMgPSByZXF1aXJlKCcuL193a3MnKSgnc3BlY2llcycpO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoTywgRCkge1xuICB2YXIgQyA9IGFuT2JqZWN0KE8pLmNvbnN0cnVjdG9yO1xuICB2YXIgUztcbiAgcmV0dXJuIEMgPT09IHVuZGVmaW5lZCB8fCAoUyA9IGFuT2JqZWN0KEMpW1NQRUNJRVNdKSA9PSB1bmRlZmluZWQgPyBEIDogYUZ1bmN0aW9uKFMpO1xufTtcbiIsIid1c2Ugc3RyaWN0JztcbnZhciBmYWlscyA9IHJlcXVpcmUoJy4vX2ZhaWxzJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKG1ldGhvZCwgYXJnKSB7XG4gIHJldHVybiAhIW1ldGhvZCAmJiBmYWlscyhmdW5jdGlvbiAoKSB7XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXVzZWxlc3MtY2FsbFxuICAgIGFyZyA/IG1ldGhvZC5jYWxsKG51bGwsIGZ1bmN0aW9uICgpIHsgLyogZW1wdHkgKi8gfSwgMSkgOiBtZXRob2QuY2FsbChudWxsKTtcbiAgfSk7XG59O1xuIiwidmFyIHRvSW50ZWdlciA9IHJlcXVpcmUoJy4vX3RvLWludGVnZXInKTtcbnZhciBkZWZpbmVkID0gcmVxdWlyZSgnLi9fZGVmaW5lZCcpO1xuLy8gdHJ1ZSAgLT4gU3RyaW5nI2F0XG4vLyBmYWxzZSAtPiBTdHJpbmcjY29kZVBvaW50QXRcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKFRPX1NUUklORykge1xuICByZXR1cm4gZnVuY3Rpb24gKHRoYXQsIHBvcykge1xuICAgIHZhciBzID0gU3RyaW5nKGRlZmluZWQodGhhdCkpO1xuICAgIHZhciBpID0gdG9JbnRlZ2VyKHBvcyk7XG4gICAgdmFyIGwgPSBzLmxlbmd0aDtcbiAgICB2YXIgYSwgYjtcbiAgICBpZiAoaSA8IDAgfHwgaSA+PSBsKSByZXR1cm4gVE9fU1RSSU5HID8gJycgOiB1bmRlZmluZWQ7XG4gICAgYSA9IHMuY2hhckNvZGVBdChpKTtcbiAgICByZXR1cm4gYSA8IDB4ZDgwMCB8fCBhID4gMHhkYmZmIHx8IGkgKyAxID09PSBsIHx8IChiID0gcy5jaGFyQ29kZUF0KGkgKyAxKSkgPCAweGRjMDAgfHwgYiA+IDB4ZGZmZlxuICAgICAgPyBUT19TVFJJTkcgPyBzLmNoYXJBdChpKSA6IGFcbiAgICAgIDogVE9fU1RSSU5HID8gcy5zbGljZShpLCBpICsgMikgOiAoYSAtIDB4ZDgwMCA8PCAxMCkgKyAoYiAtIDB4ZGMwMCkgKyAweDEwMDAwO1xuICB9O1xufTtcbiIsIi8vIGhlbHBlciBmb3IgU3RyaW5nI3tzdGFydHNXaXRoLCBlbmRzV2l0aCwgaW5jbHVkZXN9XG52YXIgaXNSZWdFeHAgPSByZXF1aXJlKCcuL19pcy1yZWdleHAnKTtcbnZhciBkZWZpbmVkID0gcmVxdWlyZSgnLi9fZGVmaW5lZCcpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uICh0aGF0LCBzZWFyY2hTdHJpbmcsIE5BTUUpIHtcbiAgaWYgKGlzUmVnRXhwKHNlYXJjaFN0cmluZykpIHRocm93IFR5cGVFcnJvcignU3RyaW5nIycgKyBOQU1FICsgXCIgZG9lc24ndCBhY2NlcHQgcmVnZXghXCIpO1xuICByZXR1cm4gU3RyaW5nKGRlZmluZWQodGhhdCkpO1xufTtcbiIsInZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgZmFpbHMgPSByZXF1aXJlKCcuL19mYWlscycpO1xudmFyIGRlZmluZWQgPSByZXF1aXJlKCcuL19kZWZpbmVkJyk7XG52YXIgcXVvdCA9IC9cIi9nO1xuLy8gQi4yLjMuMi4xIENyZWF0ZUhUTUwoc3RyaW5nLCB0YWcsIGF0dHJpYnV0ZSwgdmFsdWUpXG52YXIgY3JlYXRlSFRNTCA9IGZ1bmN0aW9uIChzdHJpbmcsIHRhZywgYXR0cmlidXRlLCB2YWx1ZSkge1xuICB2YXIgUyA9IFN0cmluZyhkZWZpbmVkKHN0cmluZykpO1xuICB2YXIgcDEgPSAnPCcgKyB0YWc7XG4gIGlmIChhdHRyaWJ1dGUgIT09ICcnKSBwMSArPSAnICcgKyBhdHRyaWJ1dGUgKyAnPVwiJyArIFN0cmluZyh2YWx1ZSkucmVwbGFjZShxdW90LCAnJnF1b3Q7JykgKyAnXCInO1xuICByZXR1cm4gcDEgKyAnPicgKyBTICsgJzwvJyArIHRhZyArICc+Jztcbn07XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChOQU1FLCBleGVjKSB7XG4gIHZhciBPID0ge307XG4gIE9bTkFNRV0gPSBleGVjKGNyZWF0ZUhUTUwpO1xuICAkZXhwb3J0KCRleHBvcnQuUCArICRleHBvcnQuRiAqIGZhaWxzKGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgdGVzdCA9ICcnW05BTUVdKCdcIicpO1xuICAgIHJldHVybiB0ZXN0ICE9PSB0ZXN0LnRvTG93ZXJDYXNlKCkgfHwgdGVzdC5zcGxpdCgnXCInKS5sZW5ndGggPiAzO1xuICB9KSwgJ1N0cmluZycsIE8pO1xufTtcbiIsIi8vIGh0dHBzOi8vZ2l0aHViLmNvbS90YzM5L3Byb3Bvc2FsLXN0cmluZy1wYWQtc3RhcnQtZW5kXG52YXIgdG9MZW5ndGggPSByZXF1aXJlKCcuL190by1sZW5ndGgnKTtcbnZhciByZXBlYXQgPSByZXF1aXJlKCcuL19zdHJpbmctcmVwZWF0Jyk7XG52YXIgZGVmaW5lZCA9IHJlcXVpcmUoJy4vX2RlZmluZWQnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAodGhhdCwgbWF4TGVuZ3RoLCBmaWxsU3RyaW5nLCBsZWZ0KSB7XG4gIHZhciBTID0gU3RyaW5nKGRlZmluZWQodGhhdCkpO1xuICB2YXIgc3RyaW5nTGVuZ3RoID0gUy5sZW5ndGg7XG4gIHZhciBmaWxsU3RyID0gZmlsbFN0cmluZyA9PT0gdW5kZWZpbmVkID8gJyAnIDogU3RyaW5nKGZpbGxTdHJpbmcpO1xuICB2YXIgaW50TWF4TGVuZ3RoID0gdG9MZW5ndGgobWF4TGVuZ3RoKTtcbiAgaWYgKGludE1heExlbmd0aCA8PSBzdHJpbmdMZW5ndGggfHwgZmlsbFN0ciA9PSAnJykgcmV0dXJuIFM7XG4gIHZhciBmaWxsTGVuID0gaW50TWF4TGVuZ3RoIC0gc3RyaW5nTGVuZ3RoO1xuICB2YXIgc3RyaW5nRmlsbGVyID0gcmVwZWF0LmNhbGwoZmlsbFN0ciwgTWF0aC5jZWlsKGZpbGxMZW4gLyBmaWxsU3RyLmxlbmd0aCkpO1xuICBpZiAoc3RyaW5nRmlsbGVyLmxlbmd0aCA+IGZpbGxMZW4pIHN0cmluZ0ZpbGxlciA9IHN0cmluZ0ZpbGxlci5zbGljZSgwLCBmaWxsTGVuKTtcbiAgcmV0dXJuIGxlZnQgPyBzdHJpbmdGaWxsZXIgKyBTIDogUyArIHN0cmluZ0ZpbGxlcjtcbn07XG4iLCIndXNlIHN0cmljdCc7XG52YXIgdG9JbnRlZ2VyID0gcmVxdWlyZSgnLi9fdG8taW50ZWdlcicpO1xudmFyIGRlZmluZWQgPSByZXF1aXJlKCcuL19kZWZpbmVkJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gcmVwZWF0KGNvdW50KSB7XG4gIHZhciBzdHIgPSBTdHJpbmcoZGVmaW5lZCh0aGlzKSk7XG4gIHZhciByZXMgPSAnJztcbiAgdmFyIG4gPSB0b0ludGVnZXIoY291bnQpO1xuICBpZiAobiA8IDAgfHwgbiA9PSBJbmZpbml0eSkgdGhyb3cgUmFuZ2VFcnJvcihcIkNvdW50IGNhbid0IGJlIG5lZ2F0aXZlXCIpO1xuICBmb3IgKDtuID4gMDsgKG4gPj4+PSAxKSAmJiAoc3RyICs9IHN0cikpIGlmIChuICYgMSkgcmVzICs9IHN0cjtcbiAgcmV0dXJuIHJlcztcbn07XG4iLCJ2YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyIGRlZmluZWQgPSByZXF1aXJlKCcuL19kZWZpbmVkJyk7XG52YXIgZmFpbHMgPSByZXF1aXJlKCcuL19mYWlscycpO1xudmFyIHNwYWNlcyA9IHJlcXVpcmUoJy4vX3N0cmluZy13cycpO1xudmFyIHNwYWNlID0gJ1snICsgc3BhY2VzICsgJ10nO1xudmFyIG5vbiA9ICdcXHUyMDBiXFx1MDA4NSc7XG52YXIgbHRyaW0gPSBSZWdFeHAoJ14nICsgc3BhY2UgKyBzcGFjZSArICcqJyk7XG52YXIgcnRyaW0gPSBSZWdFeHAoc3BhY2UgKyBzcGFjZSArICcqJCcpO1xuXG52YXIgZXhwb3J0ZXIgPSBmdW5jdGlvbiAoS0VZLCBleGVjLCBBTElBUykge1xuICB2YXIgZXhwID0ge307XG4gIHZhciBGT1JDRSA9IGZhaWxzKGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gISFzcGFjZXNbS0VZXSgpIHx8IG5vbltLRVldKCkgIT0gbm9uO1xuICB9KTtcbiAgdmFyIGZuID0gZXhwW0tFWV0gPSBGT1JDRSA/IGV4ZWModHJpbSkgOiBzcGFjZXNbS0VZXTtcbiAgaWYgKEFMSUFTKSBleHBbQUxJQVNdID0gZm47XG4gICRleHBvcnQoJGV4cG9ydC5QICsgJGV4cG9ydC5GICogRk9SQ0UsICdTdHJpbmcnLCBleHApO1xufTtcblxuLy8gMSAtPiBTdHJpbmcjdHJpbUxlZnRcbi8vIDIgLT4gU3RyaW5nI3RyaW1SaWdodFxuLy8gMyAtPiBTdHJpbmcjdHJpbVxudmFyIHRyaW0gPSBleHBvcnRlci50cmltID0gZnVuY3Rpb24gKHN0cmluZywgVFlQRSkge1xuICBzdHJpbmcgPSBTdHJpbmcoZGVmaW5lZChzdHJpbmcpKTtcbiAgaWYgKFRZUEUgJiAxKSBzdHJpbmcgPSBzdHJpbmcucmVwbGFjZShsdHJpbSwgJycpO1xuICBpZiAoVFlQRSAmIDIpIHN0cmluZyA9IHN0cmluZy5yZXBsYWNlKHJ0cmltLCAnJyk7XG4gIHJldHVybiBzdHJpbmc7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IGV4cG9ydGVyO1xuIiwibW9kdWxlLmV4cG9ydHMgPSAnXFx4MDlcXHgwQVxceDBCXFx4MENcXHgwRFxceDIwXFx4QTBcXHUxNjgwXFx1MTgwRVxcdTIwMDBcXHUyMDAxXFx1MjAwMlxcdTIwMDMnICtcbiAgJ1xcdTIwMDRcXHUyMDA1XFx1MjAwNlxcdTIwMDdcXHUyMDA4XFx1MjAwOVxcdTIwMEFcXHUyMDJGXFx1MjA1RlxcdTMwMDBcXHUyMDI4XFx1MjAyOVxcdUZFRkYnO1xuIiwidmFyIGN0eCA9IHJlcXVpcmUoJy4vX2N0eCcpO1xudmFyIGludm9rZSA9IHJlcXVpcmUoJy4vX2ludm9rZScpO1xudmFyIGh0bWwgPSByZXF1aXJlKCcuL19odG1sJyk7XG52YXIgY2VsID0gcmVxdWlyZSgnLi9fZG9tLWNyZWF0ZScpO1xudmFyIGdsb2JhbCA9IHJlcXVpcmUoJy4vX2dsb2JhbCcpO1xudmFyIHByb2Nlc3MgPSBnbG9iYWwucHJvY2VzcztcbnZhciBzZXRUYXNrID0gZ2xvYmFsLnNldEltbWVkaWF0ZTtcbnZhciBjbGVhclRhc2sgPSBnbG9iYWwuY2xlYXJJbW1lZGlhdGU7XG52YXIgTWVzc2FnZUNoYW5uZWwgPSBnbG9iYWwuTWVzc2FnZUNoYW5uZWw7XG52YXIgRGlzcGF0Y2ggPSBnbG9iYWwuRGlzcGF0Y2g7XG52YXIgY291bnRlciA9IDA7XG52YXIgcXVldWUgPSB7fTtcbnZhciBPTlJFQURZU1RBVEVDSEFOR0UgPSAnb25yZWFkeXN0YXRlY2hhbmdlJztcbnZhciBkZWZlciwgY2hhbm5lbCwgcG9ydDtcbnZhciBydW4gPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBpZCA9ICt0aGlzO1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tcHJvdG90eXBlLWJ1aWx0aW5zXG4gIGlmIChxdWV1ZS5oYXNPd25Qcm9wZXJ0eShpZCkpIHtcbiAgICB2YXIgZm4gPSBxdWV1ZVtpZF07XG4gICAgZGVsZXRlIHF1ZXVlW2lkXTtcbiAgICBmbigpO1xuICB9XG59O1xudmFyIGxpc3RlbmVyID0gZnVuY3Rpb24gKGV2ZW50KSB7XG4gIHJ1bi5jYWxsKGV2ZW50LmRhdGEpO1xufTtcbi8vIE5vZGUuanMgMC45KyAmIElFMTArIGhhcyBzZXRJbW1lZGlhdGUsIG90aGVyd2lzZTpcbmlmICghc2V0VGFzayB8fCAhY2xlYXJUYXNrKSB7XG4gIHNldFRhc2sgPSBmdW5jdGlvbiBzZXRJbW1lZGlhdGUoZm4pIHtcbiAgICB2YXIgYXJncyA9IFtdO1xuICAgIHZhciBpID0gMTtcbiAgICB3aGlsZSAoYXJndW1lbnRzLmxlbmd0aCA+IGkpIGFyZ3MucHVzaChhcmd1bWVudHNbaSsrXSk7XG4gICAgcXVldWVbKytjb3VudGVyXSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1uZXctZnVuY1xuICAgICAgaW52b2tlKHR5cGVvZiBmbiA9PSAnZnVuY3Rpb24nID8gZm4gOiBGdW5jdGlvbihmbiksIGFyZ3MpO1xuICAgIH07XG4gICAgZGVmZXIoY291bnRlcik7XG4gICAgcmV0dXJuIGNvdW50ZXI7XG4gIH07XG4gIGNsZWFyVGFzayA9IGZ1bmN0aW9uIGNsZWFySW1tZWRpYXRlKGlkKSB7XG4gICAgZGVsZXRlIHF1ZXVlW2lkXTtcbiAgfTtcbiAgLy8gTm9kZS5qcyAwLjgtXG4gIGlmIChyZXF1aXJlKCcuL19jb2YnKShwcm9jZXNzKSA9PSAncHJvY2VzcycpIHtcbiAgICBkZWZlciA9IGZ1bmN0aW9uIChpZCkge1xuICAgICAgcHJvY2Vzcy5uZXh0VGljayhjdHgocnVuLCBpZCwgMSkpO1xuICAgIH07XG4gIC8vIFNwaGVyZSAoSlMgZ2FtZSBlbmdpbmUpIERpc3BhdGNoIEFQSVxuICB9IGVsc2UgaWYgKERpc3BhdGNoICYmIERpc3BhdGNoLm5vdykge1xuICAgIGRlZmVyID0gZnVuY3Rpb24gKGlkKSB7XG4gICAgICBEaXNwYXRjaC5ub3coY3R4KHJ1biwgaWQsIDEpKTtcbiAgICB9O1xuICAvLyBCcm93c2VycyB3aXRoIE1lc3NhZ2VDaGFubmVsLCBpbmNsdWRlcyBXZWJXb3JrZXJzXG4gIH0gZWxzZSBpZiAoTWVzc2FnZUNoYW5uZWwpIHtcbiAgICBjaGFubmVsID0gbmV3IE1lc3NhZ2VDaGFubmVsKCk7XG4gICAgcG9ydCA9IGNoYW5uZWwucG9ydDI7XG4gICAgY2hhbm5lbC5wb3J0MS5vbm1lc3NhZ2UgPSBsaXN0ZW5lcjtcbiAgICBkZWZlciA9IGN0eChwb3J0LnBvc3RNZXNzYWdlLCBwb3J0LCAxKTtcbiAgLy8gQnJvd3NlcnMgd2l0aCBwb3N0TWVzc2FnZSwgc2tpcCBXZWJXb3JrZXJzXG4gIC8vIElFOCBoYXMgcG9zdE1lc3NhZ2UsIGJ1dCBpdCdzIHN5bmMgJiB0eXBlb2YgaXRzIHBvc3RNZXNzYWdlIGlzICdvYmplY3QnXG4gIH0gZWxzZSBpZiAoZ2xvYmFsLmFkZEV2ZW50TGlzdGVuZXIgJiYgdHlwZW9mIHBvc3RNZXNzYWdlID09ICdmdW5jdGlvbicgJiYgIWdsb2JhbC5pbXBvcnRTY3JpcHRzKSB7XG4gICAgZGVmZXIgPSBmdW5jdGlvbiAoaWQpIHtcbiAgICAgIGdsb2JhbC5wb3N0TWVzc2FnZShpZCArICcnLCAnKicpO1xuICAgIH07XG4gICAgZ2xvYmFsLmFkZEV2ZW50TGlzdGVuZXIoJ21lc3NhZ2UnLCBsaXN0ZW5lciwgZmFsc2UpO1xuICAvLyBJRTgtXG4gIH0gZWxzZSBpZiAoT05SRUFEWVNUQVRFQ0hBTkdFIGluIGNlbCgnc2NyaXB0JykpIHtcbiAgICBkZWZlciA9IGZ1bmN0aW9uIChpZCkge1xuICAgICAgaHRtbC5hcHBlbmRDaGlsZChjZWwoJ3NjcmlwdCcpKVtPTlJFQURZU1RBVEVDSEFOR0VdID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBodG1sLnJlbW92ZUNoaWxkKHRoaXMpO1xuICAgICAgICBydW4uY2FsbChpZCk7XG4gICAgICB9O1xuICAgIH07XG4gIC8vIFJlc3Qgb2xkIGJyb3dzZXJzXG4gIH0gZWxzZSB7XG4gICAgZGVmZXIgPSBmdW5jdGlvbiAoaWQpIHtcbiAgICAgIHNldFRpbWVvdXQoY3R4KHJ1biwgaWQsIDEpLCAwKTtcbiAgICB9O1xuICB9XG59XG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgc2V0OiBzZXRUYXNrLFxuICBjbGVhcjogY2xlYXJUYXNrXG59O1xuIiwidmFyIHRvSW50ZWdlciA9IHJlcXVpcmUoJy4vX3RvLWludGVnZXInKTtcbnZhciBtYXggPSBNYXRoLm1heDtcbnZhciBtaW4gPSBNYXRoLm1pbjtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGluZGV4LCBsZW5ndGgpIHtcbiAgaW5kZXggPSB0b0ludGVnZXIoaW5kZXgpO1xuICByZXR1cm4gaW5kZXggPCAwID8gbWF4KGluZGV4ICsgbGVuZ3RoLCAwKSA6IG1pbihpbmRleCwgbGVuZ3RoKTtcbn07XG4iLCIvLyBodHRwczovL3RjMzkuZ2l0aHViLmlvL2VjbWEyNjIvI3NlYy10b2luZGV4XG52YXIgdG9JbnRlZ2VyID0gcmVxdWlyZSgnLi9fdG8taW50ZWdlcicpO1xudmFyIHRvTGVuZ3RoID0gcmVxdWlyZSgnLi9fdG8tbGVuZ3RoJyk7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChpdCkge1xuICBpZiAoaXQgPT09IHVuZGVmaW5lZCkgcmV0dXJuIDA7XG4gIHZhciBudW1iZXIgPSB0b0ludGVnZXIoaXQpO1xuICB2YXIgbGVuZ3RoID0gdG9MZW5ndGgobnVtYmVyKTtcbiAgaWYgKG51bWJlciAhPT0gbGVuZ3RoKSB0aHJvdyBSYW5nZUVycm9yKCdXcm9uZyBsZW5ndGghJyk7XG4gIHJldHVybiBsZW5ndGg7XG59O1xuIiwiLy8gNy4xLjQgVG9JbnRlZ2VyXG52YXIgY2VpbCA9IE1hdGguY2VpbDtcbnZhciBmbG9vciA9IE1hdGguZmxvb3I7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChpdCkge1xuICByZXR1cm4gaXNOYU4oaXQgPSAraXQpID8gMCA6IChpdCA+IDAgPyBmbG9vciA6IGNlaWwpKGl0KTtcbn07XG4iLCIvLyB0byBpbmRleGVkIG9iamVjdCwgdG9PYmplY3Qgd2l0aCBmYWxsYmFjayBmb3Igbm9uLWFycmF5LWxpa2UgRVMzIHN0cmluZ3NcbnZhciBJT2JqZWN0ID0gcmVxdWlyZSgnLi9faW9iamVjdCcpO1xudmFyIGRlZmluZWQgPSByZXF1aXJlKCcuL19kZWZpbmVkJyk7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChpdCkge1xuICByZXR1cm4gSU9iamVjdChkZWZpbmVkKGl0KSk7XG59O1xuIiwiLy8gNy4xLjE1IFRvTGVuZ3RoXG52YXIgdG9JbnRlZ2VyID0gcmVxdWlyZSgnLi9fdG8taW50ZWdlcicpO1xudmFyIG1pbiA9IE1hdGgubWluO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoaXQpIHtcbiAgcmV0dXJuIGl0ID4gMCA/IG1pbih0b0ludGVnZXIoaXQpLCAweDFmZmZmZmZmZmZmZmZmKSA6IDA7IC8vIHBvdygyLCA1MykgLSAxID09IDkwMDcxOTkyNTQ3NDA5OTFcbn07XG4iLCIvLyA3LjEuMTMgVG9PYmplY3QoYXJndW1lbnQpXG52YXIgZGVmaW5lZCA9IHJlcXVpcmUoJy4vX2RlZmluZWQnKTtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGl0KSB7XG4gIHJldHVybiBPYmplY3QoZGVmaW5lZChpdCkpO1xufTtcbiIsIi8vIDcuMS4xIFRvUHJpbWl0aXZlKGlucHV0IFssIFByZWZlcnJlZFR5cGVdKVxudmFyIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi9faXMtb2JqZWN0Jyk7XG4vLyBpbnN0ZWFkIG9mIHRoZSBFUzYgc3BlYyB2ZXJzaW9uLCB3ZSBkaWRuJ3QgaW1wbGVtZW50IEBAdG9QcmltaXRpdmUgY2FzZVxuLy8gYW5kIHRoZSBzZWNvbmQgYXJndW1lbnQgLSBmbGFnIC0gcHJlZmVycmVkIHR5cGUgaXMgYSBzdHJpbmdcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGl0LCBTKSB7XG4gIGlmICghaXNPYmplY3QoaXQpKSByZXR1cm4gaXQ7XG4gIHZhciBmbiwgdmFsO1xuICBpZiAoUyAmJiB0eXBlb2YgKGZuID0gaXQudG9TdHJpbmcpID09ICdmdW5jdGlvbicgJiYgIWlzT2JqZWN0KHZhbCA9IGZuLmNhbGwoaXQpKSkgcmV0dXJuIHZhbDtcbiAgaWYgKHR5cGVvZiAoZm4gPSBpdC52YWx1ZU9mKSA9PSAnZnVuY3Rpb24nICYmICFpc09iamVjdCh2YWwgPSBmbi5jYWxsKGl0KSkpIHJldHVybiB2YWw7XG4gIGlmICghUyAmJiB0eXBlb2YgKGZuID0gaXQudG9TdHJpbmcpID09ICdmdW5jdGlvbicgJiYgIWlzT2JqZWN0KHZhbCA9IGZuLmNhbGwoaXQpKSkgcmV0dXJuIHZhbDtcbiAgdGhyb3cgVHlwZUVycm9yKFwiQ2FuJ3QgY29udmVydCBvYmplY3QgdG8gcHJpbWl0aXZlIHZhbHVlXCIpO1xufTtcbiIsIid1c2Ugc3RyaWN0JztcbmlmIChyZXF1aXJlKCcuL19kZXNjcmlwdG9ycycpKSB7XG4gIHZhciBMSUJSQVJZID0gcmVxdWlyZSgnLi9fbGlicmFyeScpO1xuICB2YXIgZ2xvYmFsID0gcmVxdWlyZSgnLi9fZ2xvYmFsJyk7XG4gIHZhciBmYWlscyA9IHJlcXVpcmUoJy4vX2ZhaWxzJyk7XG4gIHZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG4gIHZhciAkdHlwZWQgPSByZXF1aXJlKCcuL190eXBlZCcpO1xuICB2YXIgJGJ1ZmZlciA9IHJlcXVpcmUoJy4vX3R5cGVkLWJ1ZmZlcicpO1xuICB2YXIgY3R4ID0gcmVxdWlyZSgnLi9fY3R4Jyk7XG4gIHZhciBhbkluc3RhbmNlID0gcmVxdWlyZSgnLi9fYW4taW5zdGFuY2UnKTtcbiAgdmFyIHByb3BlcnR5RGVzYyA9IHJlcXVpcmUoJy4vX3Byb3BlcnR5LWRlc2MnKTtcbiAgdmFyIGhpZGUgPSByZXF1aXJlKCcuL19oaWRlJyk7XG4gIHZhciByZWRlZmluZUFsbCA9IHJlcXVpcmUoJy4vX3JlZGVmaW5lLWFsbCcpO1xuICB2YXIgdG9JbnRlZ2VyID0gcmVxdWlyZSgnLi9fdG8taW50ZWdlcicpO1xuICB2YXIgdG9MZW5ndGggPSByZXF1aXJlKCcuL190by1sZW5ndGgnKTtcbiAgdmFyIHRvSW5kZXggPSByZXF1aXJlKCcuL190by1pbmRleCcpO1xuICB2YXIgdG9BYnNvbHV0ZUluZGV4ID0gcmVxdWlyZSgnLi9fdG8tYWJzb2x1dGUtaW5kZXgnKTtcbiAgdmFyIHRvUHJpbWl0aXZlID0gcmVxdWlyZSgnLi9fdG8tcHJpbWl0aXZlJyk7XG4gIHZhciBoYXMgPSByZXF1aXJlKCcuL19oYXMnKTtcbiAgdmFyIGNsYXNzb2YgPSByZXF1aXJlKCcuL19jbGFzc29mJyk7XG4gIHZhciBpc09iamVjdCA9IHJlcXVpcmUoJy4vX2lzLW9iamVjdCcpO1xuICB2YXIgdG9PYmplY3QgPSByZXF1aXJlKCcuL190by1vYmplY3QnKTtcbiAgdmFyIGlzQXJyYXlJdGVyID0gcmVxdWlyZSgnLi9faXMtYXJyYXktaXRlcicpO1xuICB2YXIgY3JlYXRlID0gcmVxdWlyZSgnLi9fb2JqZWN0LWNyZWF0ZScpO1xuICB2YXIgZ2V0UHJvdG90eXBlT2YgPSByZXF1aXJlKCcuL19vYmplY3QtZ3BvJyk7XG4gIHZhciBnT1BOID0gcmVxdWlyZSgnLi9fb2JqZWN0LWdvcG4nKS5mO1xuICB2YXIgZ2V0SXRlckZuID0gcmVxdWlyZSgnLi9jb3JlLmdldC1pdGVyYXRvci1tZXRob2QnKTtcbiAgdmFyIHVpZCA9IHJlcXVpcmUoJy4vX3VpZCcpO1xuICB2YXIgd2tzID0gcmVxdWlyZSgnLi9fd2tzJyk7XG4gIHZhciBjcmVhdGVBcnJheU1ldGhvZCA9IHJlcXVpcmUoJy4vX2FycmF5LW1ldGhvZHMnKTtcbiAgdmFyIGNyZWF0ZUFycmF5SW5jbHVkZXMgPSByZXF1aXJlKCcuL19hcnJheS1pbmNsdWRlcycpO1xuICB2YXIgc3BlY2llc0NvbnN0cnVjdG9yID0gcmVxdWlyZSgnLi9fc3BlY2llcy1jb25zdHJ1Y3RvcicpO1xuICB2YXIgQXJyYXlJdGVyYXRvcnMgPSByZXF1aXJlKCcuL2VzNi5hcnJheS5pdGVyYXRvcicpO1xuICB2YXIgSXRlcmF0b3JzID0gcmVxdWlyZSgnLi9faXRlcmF0b3JzJyk7XG4gIHZhciAkaXRlckRldGVjdCA9IHJlcXVpcmUoJy4vX2l0ZXItZGV0ZWN0Jyk7XG4gIHZhciBzZXRTcGVjaWVzID0gcmVxdWlyZSgnLi9fc2V0LXNwZWNpZXMnKTtcbiAgdmFyIGFycmF5RmlsbCA9IHJlcXVpcmUoJy4vX2FycmF5LWZpbGwnKTtcbiAgdmFyIGFycmF5Q29weVdpdGhpbiA9IHJlcXVpcmUoJy4vX2FycmF5LWNvcHktd2l0aGluJyk7XG4gIHZhciAkRFAgPSByZXF1aXJlKCcuL19vYmplY3QtZHAnKTtcbiAgdmFyICRHT1BEID0gcmVxdWlyZSgnLi9fb2JqZWN0LWdvcGQnKTtcbiAgdmFyIGRQID0gJERQLmY7XG4gIHZhciBnT1BEID0gJEdPUEQuZjtcbiAgdmFyIFJhbmdlRXJyb3IgPSBnbG9iYWwuUmFuZ2VFcnJvcjtcbiAgdmFyIFR5cGVFcnJvciA9IGdsb2JhbC5UeXBlRXJyb3I7XG4gIHZhciBVaW50OEFycmF5ID0gZ2xvYmFsLlVpbnQ4QXJyYXk7XG4gIHZhciBBUlJBWV9CVUZGRVIgPSAnQXJyYXlCdWZmZXInO1xuICB2YXIgU0hBUkVEX0JVRkZFUiA9ICdTaGFyZWQnICsgQVJSQVlfQlVGRkVSO1xuICB2YXIgQllURVNfUEVSX0VMRU1FTlQgPSAnQllURVNfUEVSX0VMRU1FTlQnO1xuICB2YXIgUFJPVE9UWVBFID0gJ3Byb3RvdHlwZSc7XG4gIHZhciBBcnJheVByb3RvID0gQXJyYXlbUFJPVE9UWVBFXTtcbiAgdmFyICRBcnJheUJ1ZmZlciA9ICRidWZmZXIuQXJyYXlCdWZmZXI7XG4gIHZhciAkRGF0YVZpZXcgPSAkYnVmZmVyLkRhdGFWaWV3O1xuICB2YXIgYXJyYXlGb3JFYWNoID0gY3JlYXRlQXJyYXlNZXRob2QoMCk7XG4gIHZhciBhcnJheUZpbHRlciA9IGNyZWF0ZUFycmF5TWV0aG9kKDIpO1xuICB2YXIgYXJyYXlTb21lID0gY3JlYXRlQXJyYXlNZXRob2QoMyk7XG4gIHZhciBhcnJheUV2ZXJ5ID0gY3JlYXRlQXJyYXlNZXRob2QoNCk7XG4gIHZhciBhcnJheUZpbmQgPSBjcmVhdGVBcnJheU1ldGhvZCg1KTtcbiAgdmFyIGFycmF5RmluZEluZGV4ID0gY3JlYXRlQXJyYXlNZXRob2QoNik7XG4gIHZhciBhcnJheUluY2x1ZGVzID0gY3JlYXRlQXJyYXlJbmNsdWRlcyh0cnVlKTtcbiAgdmFyIGFycmF5SW5kZXhPZiA9IGNyZWF0ZUFycmF5SW5jbHVkZXMoZmFsc2UpO1xuICB2YXIgYXJyYXlWYWx1ZXMgPSBBcnJheUl0ZXJhdG9ycy52YWx1ZXM7XG4gIHZhciBhcnJheUtleXMgPSBBcnJheUl0ZXJhdG9ycy5rZXlzO1xuICB2YXIgYXJyYXlFbnRyaWVzID0gQXJyYXlJdGVyYXRvcnMuZW50cmllcztcbiAgdmFyIGFycmF5TGFzdEluZGV4T2YgPSBBcnJheVByb3RvLmxhc3RJbmRleE9mO1xuICB2YXIgYXJyYXlSZWR1Y2UgPSBBcnJheVByb3RvLnJlZHVjZTtcbiAgdmFyIGFycmF5UmVkdWNlUmlnaHQgPSBBcnJheVByb3RvLnJlZHVjZVJpZ2h0O1xuICB2YXIgYXJyYXlKb2luID0gQXJyYXlQcm90by5qb2luO1xuICB2YXIgYXJyYXlTb3J0ID0gQXJyYXlQcm90by5zb3J0O1xuICB2YXIgYXJyYXlTbGljZSA9IEFycmF5UHJvdG8uc2xpY2U7XG4gIHZhciBhcnJheVRvU3RyaW5nID0gQXJyYXlQcm90by50b1N0cmluZztcbiAgdmFyIGFycmF5VG9Mb2NhbGVTdHJpbmcgPSBBcnJheVByb3RvLnRvTG9jYWxlU3RyaW5nO1xuICB2YXIgSVRFUkFUT1IgPSB3a3MoJ2l0ZXJhdG9yJyk7XG4gIHZhciBUQUcgPSB3a3MoJ3RvU3RyaW5nVGFnJyk7XG4gIHZhciBUWVBFRF9DT05TVFJVQ1RPUiA9IHVpZCgndHlwZWRfY29uc3RydWN0b3InKTtcbiAgdmFyIERFRl9DT05TVFJVQ1RPUiA9IHVpZCgnZGVmX2NvbnN0cnVjdG9yJyk7XG4gIHZhciBBTExfQ09OU1RSVUNUT1JTID0gJHR5cGVkLkNPTlNUUjtcbiAgdmFyIFRZUEVEX0FSUkFZID0gJHR5cGVkLlRZUEVEO1xuICB2YXIgVklFVyA9ICR0eXBlZC5WSUVXO1xuICB2YXIgV1JPTkdfTEVOR1RIID0gJ1dyb25nIGxlbmd0aCEnO1xuXG4gIHZhciAkbWFwID0gY3JlYXRlQXJyYXlNZXRob2QoMSwgZnVuY3Rpb24gKE8sIGxlbmd0aCkge1xuICAgIHJldHVybiBhbGxvY2F0ZShzcGVjaWVzQ29uc3RydWN0b3IoTywgT1tERUZfQ09OU1RSVUNUT1JdKSwgbGVuZ3RoKTtcbiAgfSk7XG5cbiAgdmFyIExJVFRMRV9FTkRJQU4gPSBmYWlscyhmdW5jdGlvbiAoKSB7XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXVuZGVmXG4gICAgcmV0dXJuIG5ldyBVaW50OEFycmF5KG5ldyBVaW50MTZBcnJheShbMV0pLmJ1ZmZlcilbMF0gPT09IDE7XG4gIH0pO1xuXG4gIHZhciBGT1JDRURfU0VUID0gISFVaW50OEFycmF5ICYmICEhVWludDhBcnJheVtQUk9UT1RZUEVdLnNldCAmJiBmYWlscyhmdW5jdGlvbiAoKSB7XG4gICAgbmV3IFVpbnQ4QXJyYXkoMSkuc2V0KHt9KTtcbiAgfSk7XG5cbiAgdmFyIHRvT2Zmc2V0ID0gZnVuY3Rpb24gKGl0LCBCWVRFUykge1xuICAgIHZhciBvZmZzZXQgPSB0b0ludGVnZXIoaXQpO1xuICAgIGlmIChvZmZzZXQgPCAwIHx8IG9mZnNldCAlIEJZVEVTKSB0aHJvdyBSYW5nZUVycm9yKCdXcm9uZyBvZmZzZXQhJyk7XG4gICAgcmV0dXJuIG9mZnNldDtcbiAgfTtcblxuICB2YXIgdmFsaWRhdGUgPSBmdW5jdGlvbiAoaXQpIHtcbiAgICBpZiAoaXNPYmplY3QoaXQpICYmIFRZUEVEX0FSUkFZIGluIGl0KSByZXR1cm4gaXQ7XG4gICAgdGhyb3cgVHlwZUVycm9yKGl0ICsgJyBpcyBub3QgYSB0eXBlZCBhcnJheSEnKTtcbiAgfTtcblxuICB2YXIgYWxsb2NhdGUgPSBmdW5jdGlvbiAoQywgbGVuZ3RoKSB7XG4gICAgaWYgKCEoaXNPYmplY3QoQykgJiYgVFlQRURfQ09OU1RSVUNUT1IgaW4gQykpIHtcbiAgICAgIHRocm93IFR5cGVFcnJvcignSXQgaXMgbm90IGEgdHlwZWQgYXJyYXkgY29uc3RydWN0b3IhJyk7XG4gICAgfSByZXR1cm4gbmV3IEMobGVuZ3RoKTtcbiAgfTtcblxuICB2YXIgc3BlY2llc0Zyb21MaXN0ID0gZnVuY3Rpb24gKE8sIGxpc3QpIHtcbiAgICByZXR1cm4gZnJvbUxpc3Qoc3BlY2llc0NvbnN0cnVjdG9yKE8sIE9bREVGX0NPTlNUUlVDVE9SXSksIGxpc3QpO1xuICB9O1xuXG4gIHZhciBmcm9tTGlzdCA9IGZ1bmN0aW9uIChDLCBsaXN0KSB7XG4gICAgdmFyIGluZGV4ID0gMDtcbiAgICB2YXIgbGVuZ3RoID0gbGlzdC5sZW5ndGg7XG4gICAgdmFyIHJlc3VsdCA9IGFsbG9jYXRlKEMsIGxlbmd0aCk7XG4gICAgd2hpbGUgKGxlbmd0aCA+IGluZGV4KSByZXN1bHRbaW5kZXhdID0gbGlzdFtpbmRleCsrXTtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9O1xuXG4gIHZhciBhZGRHZXR0ZXIgPSBmdW5jdGlvbiAoaXQsIGtleSwgaW50ZXJuYWwpIHtcbiAgICBkUChpdCwga2V5LCB7IGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gdGhpcy5fZFtpbnRlcm5hbF07IH0gfSk7XG4gIH07XG5cbiAgdmFyICRmcm9tID0gZnVuY3Rpb24gZnJvbShzb3VyY2UgLyogLCBtYXBmbiwgdGhpc0FyZyAqLykge1xuICAgIHZhciBPID0gdG9PYmplY3Qoc291cmNlKTtcbiAgICB2YXIgYUxlbiA9IGFyZ3VtZW50cy5sZW5ndGg7XG4gICAgdmFyIG1hcGZuID0gYUxlbiA+IDEgPyBhcmd1bWVudHNbMV0gOiB1bmRlZmluZWQ7XG4gICAgdmFyIG1hcHBpbmcgPSBtYXBmbiAhPT0gdW5kZWZpbmVkO1xuICAgIHZhciBpdGVyRm4gPSBnZXRJdGVyRm4oTyk7XG4gICAgdmFyIGksIGxlbmd0aCwgdmFsdWVzLCByZXN1bHQsIHN0ZXAsIGl0ZXJhdG9yO1xuICAgIGlmIChpdGVyRm4gIT0gdW5kZWZpbmVkICYmICFpc0FycmF5SXRlcihpdGVyRm4pKSB7XG4gICAgICBmb3IgKGl0ZXJhdG9yID0gaXRlckZuLmNhbGwoTyksIHZhbHVlcyA9IFtdLCBpID0gMDsgIShzdGVwID0gaXRlcmF0b3IubmV4dCgpKS5kb25lOyBpKyspIHtcbiAgICAgICAgdmFsdWVzLnB1c2goc3RlcC52YWx1ZSk7XG4gICAgICB9IE8gPSB2YWx1ZXM7XG4gICAgfVxuICAgIGlmIChtYXBwaW5nICYmIGFMZW4gPiAyKSBtYXBmbiA9IGN0eChtYXBmbiwgYXJndW1lbnRzWzJdLCAyKTtcbiAgICBmb3IgKGkgPSAwLCBsZW5ndGggPSB0b0xlbmd0aChPLmxlbmd0aCksIHJlc3VsdCA9IGFsbG9jYXRlKHRoaXMsIGxlbmd0aCk7IGxlbmd0aCA+IGk7IGkrKykge1xuICAgICAgcmVzdWx0W2ldID0gbWFwcGluZyA/IG1hcGZuKE9baV0sIGkpIDogT1tpXTtcbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfTtcblxuICB2YXIgJG9mID0gZnVuY3Rpb24gb2YoLyogLi4uaXRlbXMgKi8pIHtcbiAgICB2YXIgaW5kZXggPSAwO1xuICAgIHZhciBsZW5ndGggPSBhcmd1bWVudHMubGVuZ3RoO1xuICAgIHZhciByZXN1bHQgPSBhbGxvY2F0ZSh0aGlzLCBsZW5ndGgpO1xuICAgIHdoaWxlIChsZW5ndGggPiBpbmRleCkgcmVzdWx0W2luZGV4XSA9IGFyZ3VtZW50c1tpbmRleCsrXTtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9O1xuXG4gIC8vIGlPUyBTYWZhcmkgNi54IGZhaWxzIGhlcmVcbiAgdmFyIFRPX0xPQ0FMRV9CVUcgPSAhIVVpbnQ4QXJyYXkgJiYgZmFpbHMoZnVuY3Rpb24gKCkgeyBhcnJheVRvTG9jYWxlU3RyaW5nLmNhbGwobmV3IFVpbnQ4QXJyYXkoMSkpOyB9KTtcblxuICB2YXIgJHRvTG9jYWxlU3RyaW5nID0gZnVuY3Rpb24gdG9Mb2NhbGVTdHJpbmcoKSB7XG4gICAgcmV0dXJuIGFycmF5VG9Mb2NhbGVTdHJpbmcuYXBwbHkoVE9fTE9DQUxFX0JVRyA/IGFycmF5U2xpY2UuY2FsbCh2YWxpZGF0ZSh0aGlzKSkgOiB2YWxpZGF0ZSh0aGlzKSwgYXJndW1lbnRzKTtcbiAgfTtcblxuICB2YXIgcHJvdG8gPSB7XG4gICAgY29weVdpdGhpbjogZnVuY3Rpb24gY29weVdpdGhpbih0YXJnZXQsIHN0YXJ0IC8qICwgZW5kICovKSB7XG4gICAgICByZXR1cm4gYXJyYXlDb3B5V2l0aGluLmNhbGwodmFsaWRhdGUodGhpcyksIHRhcmdldCwgc3RhcnQsIGFyZ3VtZW50cy5sZW5ndGggPiAyID8gYXJndW1lbnRzWzJdIDogdW5kZWZpbmVkKTtcbiAgICB9LFxuICAgIGV2ZXJ5OiBmdW5jdGlvbiBldmVyeShjYWxsYmFja2ZuIC8qICwgdGhpc0FyZyAqLykge1xuICAgICAgcmV0dXJuIGFycmF5RXZlcnkodmFsaWRhdGUodGhpcyksIGNhbGxiYWNrZm4sIGFyZ3VtZW50cy5sZW5ndGggPiAxID8gYXJndW1lbnRzWzFdIDogdW5kZWZpbmVkKTtcbiAgICB9LFxuICAgIGZpbGw6IGZ1bmN0aW9uIGZpbGwodmFsdWUgLyogLCBzdGFydCwgZW5kICovKSB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tdW51c2VkLXZhcnNcbiAgICAgIHJldHVybiBhcnJheUZpbGwuYXBwbHkodmFsaWRhdGUodGhpcyksIGFyZ3VtZW50cyk7XG4gICAgfSxcbiAgICBmaWx0ZXI6IGZ1bmN0aW9uIGZpbHRlcihjYWxsYmFja2ZuIC8qICwgdGhpc0FyZyAqLykge1xuICAgICAgcmV0dXJuIHNwZWNpZXNGcm9tTGlzdCh0aGlzLCBhcnJheUZpbHRlcih2YWxpZGF0ZSh0aGlzKSwgY2FsbGJhY2tmbixcbiAgICAgICAgYXJndW1lbnRzLmxlbmd0aCA+IDEgPyBhcmd1bWVudHNbMV0gOiB1bmRlZmluZWQpKTtcbiAgICB9LFxuICAgIGZpbmQ6IGZ1bmN0aW9uIGZpbmQocHJlZGljYXRlIC8qICwgdGhpc0FyZyAqLykge1xuICAgICAgcmV0dXJuIGFycmF5RmluZCh2YWxpZGF0ZSh0aGlzKSwgcHJlZGljYXRlLCBhcmd1bWVudHMubGVuZ3RoID4gMSA/IGFyZ3VtZW50c1sxXSA6IHVuZGVmaW5lZCk7XG4gICAgfSxcbiAgICBmaW5kSW5kZXg6IGZ1bmN0aW9uIGZpbmRJbmRleChwcmVkaWNhdGUgLyogLCB0aGlzQXJnICovKSB7XG4gICAgICByZXR1cm4gYXJyYXlGaW5kSW5kZXgodmFsaWRhdGUodGhpcyksIHByZWRpY2F0ZSwgYXJndW1lbnRzLmxlbmd0aCA+IDEgPyBhcmd1bWVudHNbMV0gOiB1bmRlZmluZWQpO1xuICAgIH0sXG4gICAgZm9yRWFjaDogZnVuY3Rpb24gZm9yRWFjaChjYWxsYmFja2ZuIC8qICwgdGhpc0FyZyAqLykge1xuICAgICAgYXJyYXlGb3JFYWNoKHZhbGlkYXRlKHRoaXMpLCBjYWxsYmFja2ZuLCBhcmd1bWVudHMubGVuZ3RoID4gMSA/IGFyZ3VtZW50c1sxXSA6IHVuZGVmaW5lZCk7XG4gICAgfSxcbiAgICBpbmRleE9mOiBmdW5jdGlvbiBpbmRleE9mKHNlYXJjaEVsZW1lbnQgLyogLCBmcm9tSW5kZXggKi8pIHtcbiAgICAgIHJldHVybiBhcnJheUluZGV4T2YodmFsaWRhdGUodGhpcyksIHNlYXJjaEVsZW1lbnQsIGFyZ3VtZW50cy5sZW5ndGggPiAxID8gYXJndW1lbnRzWzFdIDogdW5kZWZpbmVkKTtcbiAgICB9LFxuICAgIGluY2x1ZGVzOiBmdW5jdGlvbiBpbmNsdWRlcyhzZWFyY2hFbGVtZW50IC8qICwgZnJvbUluZGV4ICovKSB7XG4gICAgICByZXR1cm4gYXJyYXlJbmNsdWRlcyh2YWxpZGF0ZSh0aGlzKSwgc2VhcmNoRWxlbWVudCwgYXJndW1lbnRzLmxlbmd0aCA+IDEgPyBhcmd1bWVudHNbMV0gOiB1bmRlZmluZWQpO1xuICAgIH0sXG4gICAgam9pbjogZnVuY3Rpb24gam9pbihzZXBhcmF0b3IpIHsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby11bnVzZWQtdmFyc1xuICAgICAgcmV0dXJuIGFycmF5Sm9pbi5hcHBseSh2YWxpZGF0ZSh0aGlzKSwgYXJndW1lbnRzKTtcbiAgICB9LFxuICAgIGxhc3RJbmRleE9mOiBmdW5jdGlvbiBsYXN0SW5kZXhPZihzZWFyY2hFbGVtZW50IC8qICwgZnJvbUluZGV4ICovKSB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tdW51c2VkLXZhcnNcbiAgICAgIHJldHVybiBhcnJheUxhc3RJbmRleE9mLmFwcGx5KHZhbGlkYXRlKHRoaXMpLCBhcmd1bWVudHMpO1xuICAgIH0sXG4gICAgbWFwOiBmdW5jdGlvbiBtYXAobWFwZm4gLyogLCB0aGlzQXJnICovKSB7XG4gICAgICByZXR1cm4gJG1hcCh2YWxpZGF0ZSh0aGlzKSwgbWFwZm4sIGFyZ3VtZW50cy5sZW5ndGggPiAxID8gYXJndW1lbnRzWzFdIDogdW5kZWZpbmVkKTtcbiAgICB9LFxuICAgIHJlZHVjZTogZnVuY3Rpb24gcmVkdWNlKGNhbGxiYWNrZm4gLyogLCBpbml0aWFsVmFsdWUgKi8pIHsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby11bnVzZWQtdmFyc1xuICAgICAgcmV0dXJuIGFycmF5UmVkdWNlLmFwcGx5KHZhbGlkYXRlKHRoaXMpLCBhcmd1bWVudHMpO1xuICAgIH0sXG4gICAgcmVkdWNlUmlnaHQ6IGZ1bmN0aW9uIHJlZHVjZVJpZ2h0KGNhbGxiYWNrZm4gLyogLCBpbml0aWFsVmFsdWUgKi8pIHsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby11bnVzZWQtdmFyc1xuICAgICAgcmV0dXJuIGFycmF5UmVkdWNlUmlnaHQuYXBwbHkodmFsaWRhdGUodGhpcyksIGFyZ3VtZW50cyk7XG4gICAgfSxcbiAgICByZXZlcnNlOiBmdW5jdGlvbiByZXZlcnNlKCkge1xuICAgICAgdmFyIHRoYXQgPSB0aGlzO1xuICAgICAgdmFyIGxlbmd0aCA9IHZhbGlkYXRlKHRoYXQpLmxlbmd0aDtcbiAgICAgIHZhciBtaWRkbGUgPSBNYXRoLmZsb29yKGxlbmd0aCAvIDIpO1xuICAgICAgdmFyIGluZGV4ID0gMDtcbiAgICAgIHZhciB2YWx1ZTtcbiAgICAgIHdoaWxlIChpbmRleCA8IG1pZGRsZSkge1xuICAgICAgICB2YWx1ZSA9IHRoYXRbaW5kZXhdO1xuICAgICAgICB0aGF0W2luZGV4KytdID0gdGhhdFstLWxlbmd0aF07XG4gICAgICAgIHRoYXRbbGVuZ3RoXSA9IHZhbHVlO1xuICAgICAgfSByZXR1cm4gdGhhdDtcbiAgICB9LFxuICAgIHNvbWU6IGZ1bmN0aW9uIHNvbWUoY2FsbGJhY2tmbiAvKiAsIHRoaXNBcmcgKi8pIHtcbiAgICAgIHJldHVybiBhcnJheVNvbWUodmFsaWRhdGUodGhpcyksIGNhbGxiYWNrZm4sIGFyZ3VtZW50cy5sZW5ndGggPiAxID8gYXJndW1lbnRzWzFdIDogdW5kZWZpbmVkKTtcbiAgICB9LFxuICAgIHNvcnQ6IGZ1bmN0aW9uIHNvcnQoY29tcGFyZWZuKSB7XG4gICAgICByZXR1cm4gYXJyYXlTb3J0LmNhbGwodmFsaWRhdGUodGhpcyksIGNvbXBhcmVmbik7XG4gICAgfSxcbiAgICBzdWJhcnJheTogZnVuY3Rpb24gc3ViYXJyYXkoYmVnaW4sIGVuZCkge1xuICAgICAgdmFyIE8gPSB2YWxpZGF0ZSh0aGlzKTtcbiAgICAgIHZhciBsZW5ndGggPSBPLmxlbmd0aDtcbiAgICAgIHZhciAkYmVnaW4gPSB0b0Fic29sdXRlSW5kZXgoYmVnaW4sIGxlbmd0aCk7XG4gICAgICByZXR1cm4gbmV3IChzcGVjaWVzQ29uc3RydWN0b3IoTywgT1tERUZfQ09OU1RSVUNUT1JdKSkoXG4gICAgICAgIE8uYnVmZmVyLFxuICAgICAgICBPLmJ5dGVPZmZzZXQgKyAkYmVnaW4gKiBPLkJZVEVTX1BFUl9FTEVNRU5ULFxuICAgICAgICB0b0xlbmd0aCgoZW5kID09PSB1bmRlZmluZWQgPyBsZW5ndGggOiB0b0Fic29sdXRlSW5kZXgoZW5kLCBsZW5ndGgpKSAtICRiZWdpbilcbiAgICAgICk7XG4gICAgfVxuICB9O1xuXG4gIHZhciAkc2xpY2UgPSBmdW5jdGlvbiBzbGljZShzdGFydCwgZW5kKSB7XG4gICAgcmV0dXJuIHNwZWNpZXNGcm9tTGlzdCh0aGlzLCBhcnJheVNsaWNlLmNhbGwodmFsaWRhdGUodGhpcyksIHN0YXJ0LCBlbmQpKTtcbiAgfTtcblxuICB2YXIgJHNldCA9IGZ1bmN0aW9uIHNldChhcnJheUxpa2UgLyogLCBvZmZzZXQgKi8pIHtcbiAgICB2YWxpZGF0ZSh0aGlzKTtcbiAgICB2YXIgb2Zmc2V0ID0gdG9PZmZzZXQoYXJndW1lbnRzWzFdLCAxKTtcbiAgICB2YXIgbGVuZ3RoID0gdGhpcy5sZW5ndGg7XG4gICAgdmFyIHNyYyA9IHRvT2JqZWN0KGFycmF5TGlrZSk7XG4gICAgdmFyIGxlbiA9IHRvTGVuZ3RoKHNyYy5sZW5ndGgpO1xuICAgIHZhciBpbmRleCA9IDA7XG4gICAgaWYgKGxlbiArIG9mZnNldCA+IGxlbmd0aCkgdGhyb3cgUmFuZ2VFcnJvcihXUk9OR19MRU5HVEgpO1xuICAgIHdoaWxlIChpbmRleCA8IGxlbikgdGhpc1tvZmZzZXQgKyBpbmRleF0gPSBzcmNbaW5kZXgrK107XG4gIH07XG5cbiAgdmFyICRpdGVyYXRvcnMgPSB7XG4gICAgZW50cmllczogZnVuY3Rpb24gZW50cmllcygpIHtcbiAgICAgIHJldHVybiBhcnJheUVudHJpZXMuY2FsbCh2YWxpZGF0ZSh0aGlzKSk7XG4gICAgfSxcbiAgICBrZXlzOiBmdW5jdGlvbiBrZXlzKCkge1xuICAgICAgcmV0dXJuIGFycmF5S2V5cy5jYWxsKHZhbGlkYXRlKHRoaXMpKTtcbiAgICB9LFxuICAgIHZhbHVlczogZnVuY3Rpb24gdmFsdWVzKCkge1xuICAgICAgcmV0dXJuIGFycmF5VmFsdWVzLmNhbGwodmFsaWRhdGUodGhpcykpO1xuICAgIH1cbiAgfTtcblxuICB2YXIgaXNUQUluZGV4ID0gZnVuY3Rpb24gKHRhcmdldCwga2V5KSB7XG4gICAgcmV0dXJuIGlzT2JqZWN0KHRhcmdldClcbiAgICAgICYmIHRhcmdldFtUWVBFRF9BUlJBWV1cbiAgICAgICYmIHR5cGVvZiBrZXkgIT0gJ3N5bWJvbCdcbiAgICAgICYmIGtleSBpbiB0YXJnZXRcbiAgICAgICYmIFN0cmluZygra2V5KSA9PSBTdHJpbmcoa2V5KTtcbiAgfTtcbiAgdmFyICRnZXREZXNjID0gZnVuY3Rpb24gZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKHRhcmdldCwga2V5KSB7XG4gICAgcmV0dXJuIGlzVEFJbmRleCh0YXJnZXQsIGtleSA9IHRvUHJpbWl0aXZlKGtleSwgdHJ1ZSkpXG4gICAgICA/IHByb3BlcnR5RGVzYygyLCB0YXJnZXRba2V5XSlcbiAgICAgIDogZ09QRCh0YXJnZXQsIGtleSk7XG4gIH07XG4gIHZhciAkc2V0RGVzYyA9IGZ1bmN0aW9uIGRlZmluZVByb3BlcnR5KHRhcmdldCwga2V5LCBkZXNjKSB7XG4gICAgaWYgKGlzVEFJbmRleCh0YXJnZXQsIGtleSA9IHRvUHJpbWl0aXZlKGtleSwgdHJ1ZSkpXG4gICAgICAmJiBpc09iamVjdChkZXNjKVxuICAgICAgJiYgaGFzKGRlc2MsICd2YWx1ZScpXG4gICAgICAmJiAhaGFzKGRlc2MsICdnZXQnKVxuICAgICAgJiYgIWhhcyhkZXNjLCAnc2V0JylcbiAgICAgIC8vIFRPRE86IGFkZCB2YWxpZGF0aW9uIGRlc2NyaXB0b3Igdy9vIGNhbGxpbmcgYWNjZXNzb3JzXG4gICAgICAmJiAhZGVzYy5jb25maWd1cmFibGVcbiAgICAgICYmICghaGFzKGRlc2MsICd3cml0YWJsZScpIHx8IGRlc2Mud3JpdGFibGUpXG4gICAgICAmJiAoIWhhcyhkZXNjLCAnZW51bWVyYWJsZScpIHx8IGRlc2MuZW51bWVyYWJsZSlcbiAgICApIHtcbiAgICAgIHRhcmdldFtrZXldID0gZGVzYy52YWx1ZTtcbiAgICAgIHJldHVybiB0YXJnZXQ7XG4gICAgfSByZXR1cm4gZFAodGFyZ2V0LCBrZXksIGRlc2MpO1xuICB9O1xuXG4gIGlmICghQUxMX0NPTlNUUlVDVE9SUykge1xuICAgICRHT1BELmYgPSAkZ2V0RGVzYztcbiAgICAkRFAuZiA9ICRzZXREZXNjO1xuICB9XG5cbiAgJGV4cG9ydCgkZXhwb3J0LlMgKyAkZXhwb3J0LkYgKiAhQUxMX0NPTlNUUlVDVE9SUywgJ09iamVjdCcsIHtcbiAgICBnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3I6ICRnZXREZXNjLFxuICAgIGRlZmluZVByb3BlcnR5OiAkc2V0RGVzY1xuICB9KTtcblxuICBpZiAoZmFpbHMoZnVuY3Rpb24gKCkgeyBhcnJheVRvU3RyaW5nLmNhbGwoe30pOyB9KSkge1xuICAgIGFycmF5VG9TdHJpbmcgPSBhcnJheVRvTG9jYWxlU3RyaW5nID0gZnVuY3Rpb24gdG9TdHJpbmcoKSB7XG4gICAgICByZXR1cm4gYXJyYXlKb2luLmNhbGwodGhpcyk7XG4gICAgfTtcbiAgfVxuXG4gIHZhciAkVHlwZWRBcnJheVByb3RvdHlwZSQgPSByZWRlZmluZUFsbCh7fSwgcHJvdG8pO1xuICByZWRlZmluZUFsbCgkVHlwZWRBcnJheVByb3RvdHlwZSQsICRpdGVyYXRvcnMpO1xuICBoaWRlKCRUeXBlZEFycmF5UHJvdG90eXBlJCwgSVRFUkFUT1IsICRpdGVyYXRvcnMudmFsdWVzKTtcbiAgcmVkZWZpbmVBbGwoJFR5cGVkQXJyYXlQcm90b3R5cGUkLCB7XG4gICAgc2xpY2U6ICRzbGljZSxcbiAgICBzZXQ6ICRzZXQsXG4gICAgY29uc3RydWN0b3I6IGZ1bmN0aW9uICgpIHsgLyogbm9vcCAqLyB9LFxuICAgIHRvU3RyaW5nOiBhcnJheVRvU3RyaW5nLFxuICAgIHRvTG9jYWxlU3RyaW5nOiAkdG9Mb2NhbGVTdHJpbmdcbiAgfSk7XG4gIGFkZEdldHRlcigkVHlwZWRBcnJheVByb3RvdHlwZSQsICdidWZmZXInLCAnYicpO1xuICBhZGRHZXR0ZXIoJFR5cGVkQXJyYXlQcm90b3R5cGUkLCAnYnl0ZU9mZnNldCcsICdvJyk7XG4gIGFkZEdldHRlcigkVHlwZWRBcnJheVByb3RvdHlwZSQsICdieXRlTGVuZ3RoJywgJ2wnKTtcbiAgYWRkR2V0dGVyKCRUeXBlZEFycmF5UHJvdG90eXBlJCwgJ2xlbmd0aCcsICdlJyk7XG4gIGRQKCRUeXBlZEFycmF5UHJvdG90eXBlJCwgVEFHLCB7XG4gICAgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiB0aGlzW1RZUEVEX0FSUkFZXTsgfVxuICB9KTtcblxuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbWF4LXN0YXRlbWVudHNcbiAgbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoS0VZLCBCWVRFUywgd3JhcHBlciwgQ0xBTVBFRCkge1xuICAgIENMQU1QRUQgPSAhIUNMQU1QRUQ7XG4gICAgdmFyIE5BTUUgPSBLRVkgKyAoQ0xBTVBFRCA/ICdDbGFtcGVkJyA6ICcnKSArICdBcnJheSc7XG4gICAgdmFyIEdFVFRFUiA9ICdnZXQnICsgS0VZO1xuICAgIHZhciBTRVRURVIgPSAnc2V0JyArIEtFWTtcbiAgICB2YXIgVHlwZWRBcnJheSA9IGdsb2JhbFtOQU1FXTtcbiAgICB2YXIgQmFzZSA9IFR5cGVkQXJyYXkgfHwge307XG4gICAgdmFyIFRBQyA9IFR5cGVkQXJyYXkgJiYgZ2V0UHJvdG90eXBlT2YoVHlwZWRBcnJheSk7XG4gICAgdmFyIEZPUkNFRCA9ICFUeXBlZEFycmF5IHx8ICEkdHlwZWQuQUJWO1xuICAgIHZhciBPID0ge307XG4gICAgdmFyIFR5cGVkQXJyYXlQcm90b3R5cGUgPSBUeXBlZEFycmF5ICYmIFR5cGVkQXJyYXlbUFJPVE9UWVBFXTtcbiAgICB2YXIgZ2V0dGVyID0gZnVuY3Rpb24gKHRoYXQsIGluZGV4KSB7XG4gICAgICB2YXIgZGF0YSA9IHRoYXQuX2Q7XG4gICAgICByZXR1cm4gZGF0YS52W0dFVFRFUl0oaW5kZXggKiBCWVRFUyArIGRhdGEubywgTElUVExFX0VORElBTik7XG4gICAgfTtcbiAgICB2YXIgc2V0dGVyID0gZnVuY3Rpb24gKHRoYXQsIGluZGV4LCB2YWx1ZSkge1xuICAgICAgdmFyIGRhdGEgPSB0aGF0Ll9kO1xuICAgICAgaWYgKENMQU1QRUQpIHZhbHVlID0gKHZhbHVlID0gTWF0aC5yb3VuZCh2YWx1ZSkpIDwgMCA/IDAgOiB2YWx1ZSA+IDB4ZmYgPyAweGZmIDogdmFsdWUgJiAweGZmO1xuICAgICAgZGF0YS52W1NFVFRFUl0oaW5kZXggKiBCWVRFUyArIGRhdGEubywgdmFsdWUsIExJVFRMRV9FTkRJQU4pO1xuICAgIH07XG4gICAgdmFyIGFkZEVsZW1lbnQgPSBmdW5jdGlvbiAodGhhdCwgaW5kZXgpIHtcbiAgICAgIGRQKHRoYXQsIGluZGV4LCB7XG4gICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuICAgICAgICAgIHJldHVybiBnZXR0ZXIodGhpcywgaW5kZXgpO1xuICAgICAgICB9LFxuICAgICAgICBzZXQ6IGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICAgIHJldHVybiBzZXR0ZXIodGhpcywgaW5kZXgsIHZhbHVlKTtcbiAgICAgICAgfSxcbiAgICAgICAgZW51bWVyYWJsZTogdHJ1ZVxuICAgICAgfSk7XG4gICAgfTtcbiAgICBpZiAoRk9SQ0VEKSB7XG4gICAgICBUeXBlZEFycmF5ID0gd3JhcHBlcihmdW5jdGlvbiAodGhhdCwgZGF0YSwgJG9mZnNldCwgJGxlbmd0aCkge1xuICAgICAgICBhbkluc3RhbmNlKHRoYXQsIFR5cGVkQXJyYXksIE5BTUUsICdfZCcpO1xuICAgICAgICB2YXIgaW5kZXggPSAwO1xuICAgICAgICB2YXIgb2Zmc2V0ID0gMDtcbiAgICAgICAgdmFyIGJ1ZmZlciwgYnl0ZUxlbmd0aCwgbGVuZ3RoLCBrbGFzcztcbiAgICAgICAgaWYgKCFpc09iamVjdChkYXRhKSkge1xuICAgICAgICAgIGxlbmd0aCA9IHRvSW5kZXgoZGF0YSk7XG4gICAgICAgICAgYnl0ZUxlbmd0aCA9IGxlbmd0aCAqIEJZVEVTO1xuICAgICAgICAgIGJ1ZmZlciA9IG5ldyAkQXJyYXlCdWZmZXIoYnl0ZUxlbmd0aCk7XG4gICAgICAgIH0gZWxzZSBpZiAoZGF0YSBpbnN0YW5jZW9mICRBcnJheUJ1ZmZlciB8fCAoa2xhc3MgPSBjbGFzc29mKGRhdGEpKSA9PSBBUlJBWV9CVUZGRVIgfHwga2xhc3MgPT0gU0hBUkVEX0JVRkZFUikge1xuICAgICAgICAgIGJ1ZmZlciA9IGRhdGE7XG4gICAgICAgICAgb2Zmc2V0ID0gdG9PZmZzZXQoJG9mZnNldCwgQllURVMpO1xuICAgICAgICAgIHZhciAkbGVuID0gZGF0YS5ieXRlTGVuZ3RoO1xuICAgICAgICAgIGlmICgkbGVuZ3RoID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIGlmICgkbGVuICUgQllURVMpIHRocm93IFJhbmdlRXJyb3IoV1JPTkdfTEVOR1RIKTtcbiAgICAgICAgICAgIGJ5dGVMZW5ndGggPSAkbGVuIC0gb2Zmc2V0O1xuICAgICAgICAgICAgaWYgKGJ5dGVMZW5ndGggPCAwKSB0aHJvdyBSYW5nZUVycm9yKFdST05HX0xFTkdUSCk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGJ5dGVMZW5ndGggPSB0b0xlbmd0aCgkbGVuZ3RoKSAqIEJZVEVTO1xuICAgICAgICAgICAgaWYgKGJ5dGVMZW5ndGggKyBvZmZzZXQgPiAkbGVuKSB0aHJvdyBSYW5nZUVycm9yKFdST05HX0xFTkdUSCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGxlbmd0aCA9IGJ5dGVMZW5ndGggLyBCWVRFUztcbiAgICAgICAgfSBlbHNlIGlmIChUWVBFRF9BUlJBWSBpbiBkYXRhKSB7XG4gICAgICAgICAgcmV0dXJuIGZyb21MaXN0KFR5cGVkQXJyYXksIGRhdGEpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiAkZnJvbS5jYWxsKFR5cGVkQXJyYXksIGRhdGEpO1xuICAgICAgICB9XG4gICAgICAgIGhpZGUodGhhdCwgJ19kJywge1xuICAgICAgICAgIGI6IGJ1ZmZlcixcbiAgICAgICAgICBvOiBvZmZzZXQsXG4gICAgICAgICAgbDogYnl0ZUxlbmd0aCxcbiAgICAgICAgICBlOiBsZW5ndGgsXG4gICAgICAgICAgdjogbmV3ICREYXRhVmlldyhidWZmZXIpXG4gICAgICAgIH0pO1xuICAgICAgICB3aGlsZSAoaW5kZXggPCBsZW5ndGgpIGFkZEVsZW1lbnQodGhhdCwgaW5kZXgrKyk7XG4gICAgICB9KTtcbiAgICAgIFR5cGVkQXJyYXlQcm90b3R5cGUgPSBUeXBlZEFycmF5W1BST1RPVFlQRV0gPSBjcmVhdGUoJFR5cGVkQXJyYXlQcm90b3R5cGUkKTtcbiAgICAgIGhpZGUoVHlwZWRBcnJheVByb3RvdHlwZSwgJ2NvbnN0cnVjdG9yJywgVHlwZWRBcnJheSk7XG4gICAgfSBlbHNlIGlmICghZmFpbHMoZnVuY3Rpb24gKCkge1xuICAgICAgVHlwZWRBcnJheSgxKTtcbiAgICB9KSB8fCAhZmFpbHMoZnVuY3Rpb24gKCkge1xuICAgICAgbmV3IFR5cGVkQXJyYXkoLTEpOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLW5ld1xuICAgIH0pIHx8ICEkaXRlckRldGVjdChmdW5jdGlvbiAoaXRlcikge1xuICAgICAgbmV3IFR5cGVkQXJyYXkoKTsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1uZXdcbiAgICAgIG5ldyBUeXBlZEFycmF5KG51bGwpOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLW5ld1xuICAgICAgbmV3IFR5cGVkQXJyYXkoMS41KTsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1uZXdcbiAgICAgIG5ldyBUeXBlZEFycmF5KGl0ZXIpOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLW5ld1xuICAgIH0sIHRydWUpKSB7XG4gICAgICBUeXBlZEFycmF5ID0gd3JhcHBlcihmdW5jdGlvbiAodGhhdCwgZGF0YSwgJG9mZnNldCwgJGxlbmd0aCkge1xuICAgICAgICBhbkluc3RhbmNlKHRoYXQsIFR5cGVkQXJyYXksIE5BTUUpO1xuICAgICAgICB2YXIga2xhc3M7XG4gICAgICAgIC8vIGB3c2AgbW9kdWxlIGJ1ZywgdGVtcG9yYXJpbHkgcmVtb3ZlIHZhbGlkYXRpb24gbGVuZ3RoIGZvciBVaW50OEFycmF5XG4gICAgICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS93ZWJzb2NrZXRzL3dzL3B1bGwvNjQ1XG4gICAgICAgIGlmICghaXNPYmplY3QoZGF0YSkpIHJldHVybiBuZXcgQmFzZSh0b0luZGV4KGRhdGEpKTtcbiAgICAgICAgaWYgKGRhdGEgaW5zdGFuY2VvZiAkQXJyYXlCdWZmZXIgfHwgKGtsYXNzID0gY2xhc3NvZihkYXRhKSkgPT0gQVJSQVlfQlVGRkVSIHx8IGtsYXNzID09IFNIQVJFRF9CVUZGRVIpIHtcbiAgICAgICAgICByZXR1cm4gJGxlbmd0aCAhPT0gdW5kZWZpbmVkXG4gICAgICAgICAgICA/IG5ldyBCYXNlKGRhdGEsIHRvT2Zmc2V0KCRvZmZzZXQsIEJZVEVTKSwgJGxlbmd0aClcbiAgICAgICAgICAgIDogJG9mZnNldCAhPT0gdW5kZWZpbmVkXG4gICAgICAgICAgICAgID8gbmV3IEJhc2UoZGF0YSwgdG9PZmZzZXQoJG9mZnNldCwgQllURVMpKVxuICAgICAgICAgICAgICA6IG5ldyBCYXNlKGRhdGEpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChUWVBFRF9BUlJBWSBpbiBkYXRhKSByZXR1cm4gZnJvbUxpc3QoVHlwZWRBcnJheSwgZGF0YSk7XG4gICAgICAgIHJldHVybiAkZnJvbS5jYWxsKFR5cGVkQXJyYXksIGRhdGEpO1xuICAgICAgfSk7XG4gICAgICBhcnJheUZvckVhY2goVEFDICE9PSBGdW5jdGlvbi5wcm90b3R5cGUgPyBnT1BOKEJhc2UpLmNvbmNhdChnT1BOKFRBQykpIDogZ09QTihCYXNlKSwgZnVuY3Rpb24gKGtleSkge1xuICAgICAgICBpZiAoIShrZXkgaW4gVHlwZWRBcnJheSkpIGhpZGUoVHlwZWRBcnJheSwga2V5LCBCYXNlW2tleV0pO1xuICAgICAgfSk7XG4gICAgICBUeXBlZEFycmF5W1BST1RPVFlQRV0gPSBUeXBlZEFycmF5UHJvdG90eXBlO1xuICAgICAgaWYgKCFMSUJSQVJZKSBUeXBlZEFycmF5UHJvdG90eXBlLmNvbnN0cnVjdG9yID0gVHlwZWRBcnJheTtcbiAgICB9XG4gICAgdmFyICRuYXRpdmVJdGVyYXRvciA9IFR5cGVkQXJyYXlQcm90b3R5cGVbSVRFUkFUT1JdO1xuICAgIHZhciBDT1JSRUNUX0lURVJfTkFNRSA9ICEhJG5hdGl2ZUl0ZXJhdG9yXG4gICAgICAmJiAoJG5hdGl2ZUl0ZXJhdG9yLm5hbWUgPT0gJ3ZhbHVlcycgfHwgJG5hdGl2ZUl0ZXJhdG9yLm5hbWUgPT0gdW5kZWZpbmVkKTtcbiAgICB2YXIgJGl0ZXJhdG9yID0gJGl0ZXJhdG9ycy52YWx1ZXM7XG4gICAgaGlkZShUeXBlZEFycmF5LCBUWVBFRF9DT05TVFJVQ1RPUiwgdHJ1ZSk7XG4gICAgaGlkZShUeXBlZEFycmF5UHJvdG90eXBlLCBUWVBFRF9BUlJBWSwgTkFNRSk7XG4gICAgaGlkZShUeXBlZEFycmF5UHJvdG90eXBlLCBWSUVXLCB0cnVlKTtcbiAgICBoaWRlKFR5cGVkQXJyYXlQcm90b3R5cGUsIERFRl9DT05TVFJVQ1RPUiwgVHlwZWRBcnJheSk7XG5cbiAgICBpZiAoQ0xBTVBFRCA/IG5ldyBUeXBlZEFycmF5KDEpW1RBR10gIT0gTkFNRSA6ICEoVEFHIGluIFR5cGVkQXJyYXlQcm90b3R5cGUpKSB7XG4gICAgICBkUChUeXBlZEFycmF5UHJvdG90eXBlLCBUQUcsIHtcbiAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiBOQU1FOyB9XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBPW05BTUVdID0gVHlwZWRBcnJheTtcblxuICAgICRleHBvcnQoJGV4cG9ydC5HICsgJGV4cG9ydC5XICsgJGV4cG9ydC5GICogKFR5cGVkQXJyYXkgIT0gQmFzZSksIE8pO1xuXG4gICAgJGV4cG9ydCgkZXhwb3J0LlMsIE5BTUUsIHtcbiAgICAgIEJZVEVTX1BFUl9FTEVNRU5UOiBCWVRFU1xuICAgIH0pO1xuXG4gICAgJGV4cG9ydCgkZXhwb3J0LlMgKyAkZXhwb3J0LkYgKiBmYWlscyhmdW5jdGlvbiAoKSB7IEJhc2Uub2YuY2FsbChUeXBlZEFycmF5LCAxKTsgfSksIE5BTUUsIHtcbiAgICAgIGZyb206ICRmcm9tLFxuICAgICAgb2Y6ICRvZlxuICAgIH0pO1xuXG4gICAgaWYgKCEoQllURVNfUEVSX0VMRU1FTlQgaW4gVHlwZWRBcnJheVByb3RvdHlwZSkpIGhpZGUoVHlwZWRBcnJheVByb3RvdHlwZSwgQllURVNfUEVSX0VMRU1FTlQsIEJZVEVTKTtcblxuICAgICRleHBvcnQoJGV4cG9ydC5QLCBOQU1FLCBwcm90byk7XG5cbiAgICBzZXRTcGVjaWVzKE5BTUUpO1xuXG4gICAgJGV4cG9ydCgkZXhwb3J0LlAgKyAkZXhwb3J0LkYgKiBGT1JDRURfU0VULCBOQU1FLCB7IHNldDogJHNldCB9KTtcblxuICAgICRleHBvcnQoJGV4cG9ydC5QICsgJGV4cG9ydC5GICogIUNPUlJFQ1RfSVRFUl9OQU1FLCBOQU1FLCAkaXRlcmF0b3JzKTtcblxuICAgIGlmICghTElCUkFSWSAmJiBUeXBlZEFycmF5UHJvdG90eXBlLnRvU3RyaW5nICE9IGFycmF5VG9TdHJpbmcpIFR5cGVkQXJyYXlQcm90b3R5cGUudG9TdHJpbmcgPSBhcnJheVRvU3RyaW5nO1xuXG4gICAgJGV4cG9ydCgkZXhwb3J0LlAgKyAkZXhwb3J0LkYgKiBmYWlscyhmdW5jdGlvbiAoKSB7XG4gICAgICBuZXcgVHlwZWRBcnJheSgxKS5zbGljZSgpO1xuICAgIH0pLCBOQU1FLCB7IHNsaWNlOiAkc2xpY2UgfSk7XG5cbiAgICAkZXhwb3J0KCRleHBvcnQuUCArICRleHBvcnQuRiAqIChmYWlscyhmdW5jdGlvbiAoKSB7XG4gICAgICByZXR1cm4gWzEsIDJdLnRvTG9jYWxlU3RyaW5nKCkgIT0gbmV3IFR5cGVkQXJyYXkoWzEsIDJdKS50b0xvY2FsZVN0cmluZygpO1xuICAgIH0pIHx8ICFmYWlscyhmdW5jdGlvbiAoKSB7XG4gICAgICBUeXBlZEFycmF5UHJvdG90eXBlLnRvTG9jYWxlU3RyaW5nLmNhbGwoWzEsIDJdKTtcbiAgICB9KSksIE5BTUUsIHsgdG9Mb2NhbGVTdHJpbmc6ICR0b0xvY2FsZVN0cmluZyB9KTtcblxuICAgIEl0ZXJhdG9yc1tOQU1FXSA9IENPUlJFQ1RfSVRFUl9OQU1FID8gJG5hdGl2ZUl0ZXJhdG9yIDogJGl0ZXJhdG9yO1xuICAgIGlmICghTElCUkFSWSAmJiAhQ09SUkVDVF9JVEVSX05BTUUpIGhpZGUoVHlwZWRBcnJheVByb3RvdHlwZSwgSVRFUkFUT1IsICRpdGVyYXRvcik7XG4gIH07XG59IGVsc2UgbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoKSB7IC8qIGVtcHR5ICovIH07XG4iLCIndXNlIHN0cmljdCc7XG52YXIgZ2xvYmFsID0gcmVxdWlyZSgnLi9fZ2xvYmFsJyk7XG52YXIgREVTQ1JJUFRPUlMgPSByZXF1aXJlKCcuL19kZXNjcmlwdG9ycycpO1xudmFyIExJQlJBUlkgPSByZXF1aXJlKCcuL19saWJyYXJ5Jyk7XG52YXIgJHR5cGVkID0gcmVxdWlyZSgnLi9fdHlwZWQnKTtcbnZhciBoaWRlID0gcmVxdWlyZSgnLi9faGlkZScpO1xudmFyIHJlZGVmaW5lQWxsID0gcmVxdWlyZSgnLi9fcmVkZWZpbmUtYWxsJyk7XG52YXIgZmFpbHMgPSByZXF1aXJlKCcuL19mYWlscycpO1xudmFyIGFuSW5zdGFuY2UgPSByZXF1aXJlKCcuL19hbi1pbnN0YW5jZScpO1xudmFyIHRvSW50ZWdlciA9IHJlcXVpcmUoJy4vX3RvLWludGVnZXInKTtcbnZhciB0b0xlbmd0aCA9IHJlcXVpcmUoJy4vX3RvLWxlbmd0aCcpO1xudmFyIHRvSW5kZXggPSByZXF1aXJlKCcuL190by1pbmRleCcpO1xudmFyIGdPUE4gPSByZXF1aXJlKCcuL19vYmplY3QtZ29wbicpLmY7XG52YXIgZFAgPSByZXF1aXJlKCcuL19vYmplY3QtZHAnKS5mO1xudmFyIGFycmF5RmlsbCA9IHJlcXVpcmUoJy4vX2FycmF5LWZpbGwnKTtcbnZhciBzZXRUb1N0cmluZ1RhZyA9IHJlcXVpcmUoJy4vX3NldC10by1zdHJpbmctdGFnJyk7XG52YXIgQVJSQVlfQlVGRkVSID0gJ0FycmF5QnVmZmVyJztcbnZhciBEQVRBX1ZJRVcgPSAnRGF0YVZpZXcnO1xudmFyIFBST1RPVFlQRSA9ICdwcm90b3R5cGUnO1xudmFyIFdST05HX0xFTkdUSCA9ICdXcm9uZyBsZW5ndGghJztcbnZhciBXUk9OR19JTkRFWCA9ICdXcm9uZyBpbmRleCEnO1xudmFyICRBcnJheUJ1ZmZlciA9IGdsb2JhbFtBUlJBWV9CVUZGRVJdO1xudmFyICREYXRhVmlldyA9IGdsb2JhbFtEQVRBX1ZJRVddO1xudmFyIE1hdGggPSBnbG9iYWwuTWF0aDtcbnZhciBSYW5nZUVycm9yID0gZ2xvYmFsLlJhbmdlRXJyb3I7XG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tc2hhZG93LXJlc3RyaWN0ZWQtbmFtZXNcbnZhciBJbmZpbml0eSA9IGdsb2JhbC5JbmZpbml0eTtcbnZhciBCYXNlQnVmZmVyID0gJEFycmF5QnVmZmVyO1xudmFyIGFicyA9IE1hdGguYWJzO1xudmFyIHBvdyA9IE1hdGgucG93O1xudmFyIGZsb29yID0gTWF0aC5mbG9vcjtcbnZhciBsb2cgPSBNYXRoLmxvZztcbnZhciBMTjIgPSBNYXRoLkxOMjtcbnZhciBCVUZGRVIgPSAnYnVmZmVyJztcbnZhciBCWVRFX0xFTkdUSCA9ICdieXRlTGVuZ3RoJztcbnZhciBCWVRFX09GRlNFVCA9ICdieXRlT2Zmc2V0JztcbnZhciAkQlVGRkVSID0gREVTQ1JJUFRPUlMgPyAnX2InIDogQlVGRkVSO1xudmFyICRMRU5HVEggPSBERVNDUklQVE9SUyA/ICdfbCcgOiBCWVRFX0xFTkdUSDtcbnZhciAkT0ZGU0VUID0gREVTQ1JJUFRPUlMgPyAnX28nIDogQllURV9PRkZTRVQ7XG5cbi8vIElFRUU3NTQgY29udmVyc2lvbnMgYmFzZWQgb24gaHR0cHM6Ly9naXRodWIuY29tL2Zlcm9zcy9pZWVlNzU0XG5mdW5jdGlvbiBwYWNrSUVFRTc1NCh2YWx1ZSwgbUxlbiwgbkJ5dGVzKSB7XG4gIHZhciBidWZmZXIgPSBuZXcgQXJyYXkobkJ5dGVzKTtcbiAgdmFyIGVMZW4gPSBuQnl0ZXMgKiA4IC0gbUxlbiAtIDE7XG4gIHZhciBlTWF4ID0gKDEgPDwgZUxlbikgLSAxO1xuICB2YXIgZUJpYXMgPSBlTWF4ID4+IDE7XG4gIHZhciBydCA9IG1MZW4gPT09IDIzID8gcG93KDIsIC0yNCkgLSBwb3coMiwgLTc3KSA6IDA7XG4gIHZhciBpID0gMDtcbiAgdmFyIHMgPSB2YWx1ZSA8IDAgfHwgdmFsdWUgPT09IDAgJiYgMSAvIHZhbHVlIDwgMCA/IDEgOiAwO1xuICB2YXIgZSwgbSwgYztcbiAgdmFsdWUgPSBhYnModmFsdWUpO1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tc2VsZi1jb21wYXJlXG4gIGlmICh2YWx1ZSAhPSB2YWx1ZSB8fCB2YWx1ZSA9PT0gSW5maW5pdHkpIHtcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tc2VsZi1jb21wYXJlXG4gICAgbSA9IHZhbHVlICE9IHZhbHVlID8gMSA6IDA7XG4gICAgZSA9IGVNYXg7XG4gIH0gZWxzZSB7XG4gICAgZSA9IGZsb29yKGxvZyh2YWx1ZSkgLyBMTjIpO1xuICAgIGlmICh2YWx1ZSAqIChjID0gcG93KDIsIC1lKSkgPCAxKSB7XG4gICAgICBlLS07XG4gICAgICBjICo9IDI7XG4gICAgfVxuICAgIGlmIChlICsgZUJpYXMgPj0gMSkge1xuICAgICAgdmFsdWUgKz0gcnQgLyBjO1xuICAgIH0gZWxzZSB7XG4gICAgICB2YWx1ZSArPSBydCAqIHBvdygyLCAxIC0gZUJpYXMpO1xuICAgIH1cbiAgICBpZiAodmFsdWUgKiBjID49IDIpIHtcbiAgICAgIGUrKztcbiAgICAgIGMgLz0gMjtcbiAgICB9XG4gICAgaWYgKGUgKyBlQmlhcyA+PSBlTWF4KSB7XG4gICAgICBtID0gMDtcbiAgICAgIGUgPSBlTWF4O1xuICAgIH0gZWxzZSBpZiAoZSArIGVCaWFzID49IDEpIHtcbiAgICAgIG0gPSAodmFsdWUgKiBjIC0gMSkgKiBwb3coMiwgbUxlbik7XG4gICAgICBlID0gZSArIGVCaWFzO1xuICAgIH0gZWxzZSB7XG4gICAgICBtID0gdmFsdWUgKiBwb3coMiwgZUJpYXMgLSAxKSAqIHBvdygyLCBtTGVuKTtcbiAgICAgIGUgPSAwO1xuICAgIH1cbiAgfVxuICBmb3IgKDsgbUxlbiA+PSA4OyBidWZmZXJbaSsrXSA9IG0gJiAyNTUsIG0gLz0gMjU2LCBtTGVuIC09IDgpO1xuICBlID0gZSA8PCBtTGVuIHwgbTtcbiAgZUxlbiArPSBtTGVuO1xuICBmb3IgKDsgZUxlbiA+IDA7IGJ1ZmZlcltpKytdID0gZSAmIDI1NSwgZSAvPSAyNTYsIGVMZW4gLT0gOCk7XG4gIGJ1ZmZlclstLWldIHw9IHMgKiAxMjg7XG4gIHJldHVybiBidWZmZXI7XG59XG5mdW5jdGlvbiB1bnBhY2tJRUVFNzU0KGJ1ZmZlciwgbUxlbiwgbkJ5dGVzKSB7XG4gIHZhciBlTGVuID0gbkJ5dGVzICogOCAtIG1MZW4gLSAxO1xuICB2YXIgZU1heCA9ICgxIDw8IGVMZW4pIC0gMTtcbiAgdmFyIGVCaWFzID0gZU1heCA+PiAxO1xuICB2YXIgbkJpdHMgPSBlTGVuIC0gNztcbiAgdmFyIGkgPSBuQnl0ZXMgLSAxO1xuICB2YXIgcyA9IGJ1ZmZlcltpLS1dO1xuICB2YXIgZSA9IHMgJiAxMjc7XG4gIHZhciBtO1xuICBzID4+PSA3O1xuICBmb3IgKDsgbkJpdHMgPiAwOyBlID0gZSAqIDI1NiArIGJ1ZmZlcltpXSwgaS0tLCBuQml0cyAtPSA4KTtcbiAgbSA9IGUgJiAoMSA8PCAtbkJpdHMpIC0gMTtcbiAgZSA+Pj0gLW5CaXRzO1xuICBuQml0cyArPSBtTGVuO1xuICBmb3IgKDsgbkJpdHMgPiAwOyBtID0gbSAqIDI1NiArIGJ1ZmZlcltpXSwgaS0tLCBuQml0cyAtPSA4KTtcbiAgaWYgKGUgPT09IDApIHtcbiAgICBlID0gMSAtIGVCaWFzO1xuICB9IGVsc2UgaWYgKGUgPT09IGVNYXgpIHtcbiAgICByZXR1cm4gbSA/IE5hTiA6IHMgPyAtSW5maW5pdHkgOiBJbmZpbml0eTtcbiAgfSBlbHNlIHtcbiAgICBtID0gbSArIHBvdygyLCBtTGVuKTtcbiAgICBlID0gZSAtIGVCaWFzO1xuICB9IHJldHVybiAocyA/IC0xIDogMSkgKiBtICogcG93KDIsIGUgLSBtTGVuKTtcbn1cblxuZnVuY3Rpb24gdW5wYWNrSTMyKGJ5dGVzKSB7XG4gIHJldHVybiBieXRlc1szXSA8PCAyNCB8IGJ5dGVzWzJdIDw8IDE2IHwgYnl0ZXNbMV0gPDwgOCB8IGJ5dGVzWzBdO1xufVxuZnVuY3Rpb24gcGFja0k4KGl0KSB7XG4gIHJldHVybiBbaXQgJiAweGZmXTtcbn1cbmZ1bmN0aW9uIHBhY2tJMTYoaXQpIHtcbiAgcmV0dXJuIFtpdCAmIDB4ZmYsIGl0ID4+IDggJiAweGZmXTtcbn1cbmZ1bmN0aW9uIHBhY2tJMzIoaXQpIHtcbiAgcmV0dXJuIFtpdCAmIDB4ZmYsIGl0ID4+IDggJiAweGZmLCBpdCA+PiAxNiAmIDB4ZmYsIGl0ID4+IDI0ICYgMHhmZl07XG59XG5mdW5jdGlvbiBwYWNrRjY0KGl0KSB7XG4gIHJldHVybiBwYWNrSUVFRTc1NChpdCwgNTIsIDgpO1xufVxuZnVuY3Rpb24gcGFja0YzMihpdCkge1xuICByZXR1cm4gcGFja0lFRUU3NTQoaXQsIDIzLCA0KTtcbn1cblxuZnVuY3Rpb24gYWRkR2V0dGVyKEMsIGtleSwgaW50ZXJuYWwpIHtcbiAgZFAoQ1tQUk9UT1RZUEVdLCBrZXksIHsgZ2V0OiBmdW5jdGlvbiAoKSB7IHJldHVybiB0aGlzW2ludGVybmFsXTsgfSB9KTtcbn1cblxuZnVuY3Rpb24gZ2V0KHZpZXcsIGJ5dGVzLCBpbmRleCwgaXNMaXR0bGVFbmRpYW4pIHtcbiAgdmFyIG51bUluZGV4ID0gK2luZGV4O1xuICB2YXIgaW50SW5kZXggPSB0b0luZGV4KG51bUluZGV4KTtcbiAgaWYgKGludEluZGV4ICsgYnl0ZXMgPiB2aWV3WyRMRU5HVEhdKSB0aHJvdyBSYW5nZUVycm9yKFdST05HX0lOREVYKTtcbiAgdmFyIHN0b3JlID0gdmlld1skQlVGRkVSXS5fYjtcbiAgdmFyIHN0YXJ0ID0gaW50SW5kZXggKyB2aWV3WyRPRkZTRVRdO1xuICB2YXIgcGFjayA9IHN0b3JlLnNsaWNlKHN0YXJ0LCBzdGFydCArIGJ5dGVzKTtcbiAgcmV0dXJuIGlzTGl0dGxlRW5kaWFuID8gcGFjayA6IHBhY2sucmV2ZXJzZSgpO1xufVxuZnVuY3Rpb24gc2V0KHZpZXcsIGJ5dGVzLCBpbmRleCwgY29udmVyc2lvbiwgdmFsdWUsIGlzTGl0dGxlRW5kaWFuKSB7XG4gIHZhciBudW1JbmRleCA9ICtpbmRleDtcbiAgdmFyIGludEluZGV4ID0gdG9JbmRleChudW1JbmRleCk7XG4gIGlmIChpbnRJbmRleCArIGJ5dGVzID4gdmlld1skTEVOR1RIXSkgdGhyb3cgUmFuZ2VFcnJvcihXUk9OR19JTkRFWCk7XG4gIHZhciBzdG9yZSA9IHZpZXdbJEJVRkZFUl0uX2I7XG4gIHZhciBzdGFydCA9IGludEluZGV4ICsgdmlld1skT0ZGU0VUXTtcbiAgdmFyIHBhY2sgPSBjb252ZXJzaW9uKCt2YWx1ZSk7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgYnl0ZXM7IGkrKykgc3RvcmVbc3RhcnQgKyBpXSA9IHBhY2tbaXNMaXR0bGVFbmRpYW4gPyBpIDogYnl0ZXMgLSBpIC0gMV07XG59XG5cbmlmICghJHR5cGVkLkFCVikge1xuICAkQXJyYXlCdWZmZXIgPSBmdW5jdGlvbiBBcnJheUJ1ZmZlcihsZW5ndGgpIHtcbiAgICBhbkluc3RhbmNlKHRoaXMsICRBcnJheUJ1ZmZlciwgQVJSQVlfQlVGRkVSKTtcbiAgICB2YXIgYnl0ZUxlbmd0aCA9IHRvSW5kZXgobGVuZ3RoKTtcbiAgICB0aGlzLl9iID0gYXJyYXlGaWxsLmNhbGwobmV3IEFycmF5KGJ5dGVMZW5ndGgpLCAwKTtcbiAgICB0aGlzWyRMRU5HVEhdID0gYnl0ZUxlbmd0aDtcbiAgfTtcblxuICAkRGF0YVZpZXcgPSBmdW5jdGlvbiBEYXRhVmlldyhidWZmZXIsIGJ5dGVPZmZzZXQsIGJ5dGVMZW5ndGgpIHtcbiAgICBhbkluc3RhbmNlKHRoaXMsICREYXRhVmlldywgREFUQV9WSUVXKTtcbiAgICBhbkluc3RhbmNlKGJ1ZmZlciwgJEFycmF5QnVmZmVyLCBEQVRBX1ZJRVcpO1xuICAgIHZhciBidWZmZXJMZW5ndGggPSBidWZmZXJbJExFTkdUSF07XG4gICAgdmFyIG9mZnNldCA9IHRvSW50ZWdlcihieXRlT2Zmc2V0KTtcbiAgICBpZiAob2Zmc2V0IDwgMCB8fCBvZmZzZXQgPiBidWZmZXJMZW5ndGgpIHRocm93IFJhbmdlRXJyb3IoJ1dyb25nIG9mZnNldCEnKTtcbiAgICBieXRlTGVuZ3RoID0gYnl0ZUxlbmd0aCA9PT0gdW5kZWZpbmVkID8gYnVmZmVyTGVuZ3RoIC0gb2Zmc2V0IDogdG9MZW5ndGgoYnl0ZUxlbmd0aCk7XG4gICAgaWYgKG9mZnNldCArIGJ5dGVMZW5ndGggPiBidWZmZXJMZW5ndGgpIHRocm93IFJhbmdlRXJyb3IoV1JPTkdfTEVOR1RIKTtcbiAgICB0aGlzWyRCVUZGRVJdID0gYnVmZmVyO1xuICAgIHRoaXNbJE9GRlNFVF0gPSBvZmZzZXQ7XG4gICAgdGhpc1skTEVOR1RIXSA9IGJ5dGVMZW5ndGg7XG4gIH07XG5cbiAgaWYgKERFU0NSSVBUT1JTKSB7XG4gICAgYWRkR2V0dGVyKCRBcnJheUJ1ZmZlciwgQllURV9MRU5HVEgsICdfbCcpO1xuICAgIGFkZEdldHRlcigkRGF0YVZpZXcsIEJVRkZFUiwgJ19iJyk7XG4gICAgYWRkR2V0dGVyKCREYXRhVmlldywgQllURV9MRU5HVEgsICdfbCcpO1xuICAgIGFkZEdldHRlcigkRGF0YVZpZXcsIEJZVEVfT0ZGU0VULCAnX28nKTtcbiAgfVxuXG4gIHJlZGVmaW5lQWxsKCREYXRhVmlld1tQUk9UT1RZUEVdLCB7XG4gICAgZ2V0SW50ODogZnVuY3Rpb24gZ2V0SW50OChieXRlT2Zmc2V0KSB7XG4gICAgICByZXR1cm4gZ2V0KHRoaXMsIDEsIGJ5dGVPZmZzZXQpWzBdIDw8IDI0ID4+IDI0O1xuICAgIH0sXG4gICAgZ2V0VWludDg6IGZ1bmN0aW9uIGdldFVpbnQ4KGJ5dGVPZmZzZXQpIHtcbiAgICAgIHJldHVybiBnZXQodGhpcywgMSwgYnl0ZU9mZnNldClbMF07XG4gICAgfSxcbiAgICBnZXRJbnQxNjogZnVuY3Rpb24gZ2V0SW50MTYoYnl0ZU9mZnNldCAvKiAsIGxpdHRsZUVuZGlhbiAqLykge1xuICAgICAgdmFyIGJ5dGVzID0gZ2V0KHRoaXMsIDIsIGJ5dGVPZmZzZXQsIGFyZ3VtZW50c1sxXSk7XG4gICAgICByZXR1cm4gKGJ5dGVzWzFdIDw8IDggfCBieXRlc1swXSkgPDwgMTYgPj4gMTY7XG4gICAgfSxcbiAgICBnZXRVaW50MTY6IGZ1bmN0aW9uIGdldFVpbnQxNihieXRlT2Zmc2V0IC8qICwgbGl0dGxlRW5kaWFuICovKSB7XG4gICAgICB2YXIgYnl0ZXMgPSBnZXQodGhpcywgMiwgYnl0ZU9mZnNldCwgYXJndW1lbnRzWzFdKTtcbiAgICAgIHJldHVybiBieXRlc1sxXSA8PCA4IHwgYnl0ZXNbMF07XG4gICAgfSxcbiAgICBnZXRJbnQzMjogZnVuY3Rpb24gZ2V0SW50MzIoYnl0ZU9mZnNldCAvKiAsIGxpdHRsZUVuZGlhbiAqLykge1xuICAgICAgcmV0dXJuIHVucGFja0kzMihnZXQodGhpcywgNCwgYnl0ZU9mZnNldCwgYXJndW1lbnRzWzFdKSk7XG4gICAgfSxcbiAgICBnZXRVaW50MzI6IGZ1bmN0aW9uIGdldFVpbnQzMihieXRlT2Zmc2V0IC8qICwgbGl0dGxlRW5kaWFuICovKSB7XG4gICAgICByZXR1cm4gdW5wYWNrSTMyKGdldCh0aGlzLCA0LCBieXRlT2Zmc2V0LCBhcmd1bWVudHNbMV0pKSA+Pj4gMDtcbiAgICB9LFxuICAgIGdldEZsb2F0MzI6IGZ1bmN0aW9uIGdldEZsb2F0MzIoYnl0ZU9mZnNldCAvKiAsIGxpdHRsZUVuZGlhbiAqLykge1xuICAgICAgcmV0dXJuIHVucGFja0lFRUU3NTQoZ2V0KHRoaXMsIDQsIGJ5dGVPZmZzZXQsIGFyZ3VtZW50c1sxXSksIDIzLCA0KTtcbiAgICB9LFxuICAgIGdldEZsb2F0NjQ6IGZ1bmN0aW9uIGdldEZsb2F0NjQoYnl0ZU9mZnNldCAvKiAsIGxpdHRsZUVuZGlhbiAqLykge1xuICAgICAgcmV0dXJuIHVucGFja0lFRUU3NTQoZ2V0KHRoaXMsIDgsIGJ5dGVPZmZzZXQsIGFyZ3VtZW50c1sxXSksIDUyLCA4KTtcbiAgICB9LFxuICAgIHNldEludDg6IGZ1bmN0aW9uIHNldEludDgoYnl0ZU9mZnNldCwgdmFsdWUpIHtcbiAgICAgIHNldCh0aGlzLCAxLCBieXRlT2Zmc2V0LCBwYWNrSTgsIHZhbHVlKTtcbiAgICB9LFxuICAgIHNldFVpbnQ4OiBmdW5jdGlvbiBzZXRVaW50OChieXRlT2Zmc2V0LCB2YWx1ZSkge1xuICAgICAgc2V0KHRoaXMsIDEsIGJ5dGVPZmZzZXQsIHBhY2tJOCwgdmFsdWUpO1xuICAgIH0sXG4gICAgc2V0SW50MTY6IGZ1bmN0aW9uIHNldEludDE2KGJ5dGVPZmZzZXQsIHZhbHVlIC8qICwgbGl0dGxlRW5kaWFuICovKSB7XG4gICAgICBzZXQodGhpcywgMiwgYnl0ZU9mZnNldCwgcGFja0kxNiwgdmFsdWUsIGFyZ3VtZW50c1syXSk7XG4gICAgfSxcbiAgICBzZXRVaW50MTY6IGZ1bmN0aW9uIHNldFVpbnQxNihieXRlT2Zmc2V0LCB2YWx1ZSAvKiAsIGxpdHRsZUVuZGlhbiAqLykge1xuICAgICAgc2V0KHRoaXMsIDIsIGJ5dGVPZmZzZXQsIHBhY2tJMTYsIHZhbHVlLCBhcmd1bWVudHNbMl0pO1xuICAgIH0sXG4gICAgc2V0SW50MzI6IGZ1bmN0aW9uIHNldEludDMyKGJ5dGVPZmZzZXQsIHZhbHVlIC8qICwgbGl0dGxlRW5kaWFuICovKSB7XG4gICAgICBzZXQodGhpcywgNCwgYnl0ZU9mZnNldCwgcGFja0kzMiwgdmFsdWUsIGFyZ3VtZW50c1syXSk7XG4gICAgfSxcbiAgICBzZXRVaW50MzI6IGZ1bmN0aW9uIHNldFVpbnQzMihieXRlT2Zmc2V0LCB2YWx1ZSAvKiAsIGxpdHRsZUVuZGlhbiAqLykge1xuICAgICAgc2V0KHRoaXMsIDQsIGJ5dGVPZmZzZXQsIHBhY2tJMzIsIHZhbHVlLCBhcmd1bWVudHNbMl0pO1xuICAgIH0sXG4gICAgc2V0RmxvYXQzMjogZnVuY3Rpb24gc2V0RmxvYXQzMihieXRlT2Zmc2V0LCB2YWx1ZSAvKiAsIGxpdHRsZUVuZGlhbiAqLykge1xuICAgICAgc2V0KHRoaXMsIDQsIGJ5dGVPZmZzZXQsIHBhY2tGMzIsIHZhbHVlLCBhcmd1bWVudHNbMl0pO1xuICAgIH0sXG4gICAgc2V0RmxvYXQ2NDogZnVuY3Rpb24gc2V0RmxvYXQ2NChieXRlT2Zmc2V0LCB2YWx1ZSAvKiAsIGxpdHRsZUVuZGlhbiAqLykge1xuICAgICAgc2V0KHRoaXMsIDgsIGJ5dGVPZmZzZXQsIHBhY2tGNjQsIHZhbHVlLCBhcmd1bWVudHNbMl0pO1xuICAgIH1cbiAgfSk7XG59IGVsc2Uge1xuICBpZiAoIWZhaWxzKGZ1bmN0aW9uICgpIHtcbiAgICAkQXJyYXlCdWZmZXIoMSk7XG4gIH0pIHx8ICFmYWlscyhmdW5jdGlvbiAoKSB7XG4gICAgbmV3ICRBcnJheUJ1ZmZlcigtMSk7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tbmV3XG4gIH0pIHx8IGZhaWxzKGZ1bmN0aW9uICgpIHtcbiAgICBuZXcgJEFycmF5QnVmZmVyKCk7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tbmV3XG4gICAgbmV3ICRBcnJheUJ1ZmZlcigxLjUpOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLW5ld1xuICAgIG5ldyAkQXJyYXlCdWZmZXIoTmFOKTsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1uZXdcbiAgICByZXR1cm4gJEFycmF5QnVmZmVyLm5hbWUgIT0gQVJSQVlfQlVGRkVSO1xuICB9KSkge1xuICAgICRBcnJheUJ1ZmZlciA9IGZ1bmN0aW9uIEFycmF5QnVmZmVyKGxlbmd0aCkge1xuICAgICAgYW5JbnN0YW5jZSh0aGlzLCAkQXJyYXlCdWZmZXIpO1xuICAgICAgcmV0dXJuIG5ldyBCYXNlQnVmZmVyKHRvSW5kZXgobGVuZ3RoKSk7XG4gICAgfTtcbiAgICB2YXIgQXJyYXlCdWZmZXJQcm90byA9ICRBcnJheUJ1ZmZlcltQUk9UT1RZUEVdID0gQmFzZUJ1ZmZlcltQUk9UT1RZUEVdO1xuICAgIGZvciAodmFyIGtleXMgPSBnT1BOKEJhc2VCdWZmZXIpLCBqID0gMCwga2V5OyBrZXlzLmxlbmd0aCA+IGo7KSB7XG4gICAgICBpZiAoISgoa2V5ID0ga2V5c1tqKytdKSBpbiAkQXJyYXlCdWZmZXIpKSBoaWRlKCRBcnJheUJ1ZmZlciwga2V5LCBCYXNlQnVmZmVyW2tleV0pO1xuICAgIH1cbiAgICBpZiAoIUxJQlJBUlkpIEFycmF5QnVmZmVyUHJvdG8uY29uc3RydWN0b3IgPSAkQXJyYXlCdWZmZXI7XG4gIH1cbiAgLy8gaU9TIFNhZmFyaSA3LnggYnVnXG4gIHZhciB2aWV3ID0gbmV3ICREYXRhVmlldyhuZXcgJEFycmF5QnVmZmVyKDIpKTtcbiAgdmFyICRzZXRJbnQ4ID0gJERhdGFWaWV3W1BST1RPVFlQRV0uc2V0SW50ODtcbiAgdmlldy5zZXRJbnQ4KDAsIDIxNDc0ODM2NDgpO1xuICB2aWV3LnNldEludDgoMSwgMjE0NzQ4MzY0OSk7XG4gIGlmICh2aWV3LmdldEludDgoMCkgfHwgIXZpZXcuZ2V0SW50OCgxKSkgcmVkZWZpbmVBbGwoJERhdGFWaWV3W1BST1RPVFlQRV0sIHtcbiAgICBzZXRJbnQ4OiBmdW5jdGlvbiBzZXRJbnQ4KGJ5dGVPZmZzZXQsIHZhbHVlKSB7XG4gICAgICAkc2V0SW50OC5jYWxsKHRoaXMsIGJ5dGVPZmZzZXQsIHZhbHVlIDw8IDI0ID4+IDI0KTtcbiAgICB9LFxuICAgIHNldFVpbnQ4OiBmdW5jdGlvbiBzZXRVaW50OChieXRlT2Zmc2V0LCB2YWx1ZSkge1xuICAgICAgJHNldEludDguY2FsbCh0aGlzLCBieXRlT2Zmc2V0LCB2YWx1ZSA8PCAyNCA+PiAyNCk7XG4gICAgfVxuICB9LCB0cnVlKTtcbn1cbnNldFRvU3RyaW5nVGFnKCRBcnJheUJ1ZmZlciwgQVJSQVlfQlVGRkVSKTtcbnNldFRvU3RyaW5nVGFnKCREYXRhVmlldywgREFUQV9WSUVXKTtcbmhpZGUoJERhdGFWaWV3W1BST1RPVFlQRV0sICR0eXBlZC5WSUVXLCB0cnVlKTtcbmV4cG9ydHNbQVJSQVlfQlVGRkVSXSA9ICRBcnJheUJ1ZmZlcjtcbmV4cG9ydHNbREFUQV9WSUVXXSA9ICREYXRhVmlldztcbiIsInZhciBnbG9iYWwgPSByZXF1aXJlKCcuL19nbG9iYWwnKTtcbnZhciBoaWRlID0gcmVxdWlyZSgnLi9faGlkZScpO1xudmFyIHVpZCA9IHJlcXVpcmUoJy4vX3VpZCcpO1xudmFyIFRZUEVEID0gdWlkKCd0eXBlZF9hcnJheScpO1xudmFyIFZJRVcgPSB1aWQoJ3ZpZXcnKTtcbnZhciBBQlYgPSAhIShnbG9iYWwuQXJyYXlCdWZmZXIgJiYgZ2xvYmFsLkRhdGFWaWV3KTtcbnZhciBDT05TVFIgPSBBQlY7XG52YXIgaSA9IDA7XG52YXIgbCA9IDk7XG52YXIgVHlwZWQ7XG5cbnZhciBUeXBlZEFycmF5Q29uc3RydWN0b3JzID0gKFxuICAnSW50OEFycmF5LFVpbnQ4QXJyYXksVWludDhDbGFtcGVkQXJyYXksSW50MTZBcnJheSxVaW50MTZBcnJheSxJbnQzMkFycmF5LFVpbnQzMkFycmF5LEZsb2F0MzJBcnJheSxGbG9hdDY0QXJyYXknXG4pLnNwbGl0KCcsJyk7XG5cbndoaWxlIChpIDwgbCkge1xuICBpZiAoVHlwZWQgPSBnbG9iYWxbVHlwZWRBcnJheUNvbnN0cnVjdG9yc1tpKytdXSkge1xuICAgIGhpZGUoVHlwZWQucHJvdG90eXBlLCBUWVBFRCwgdHJ1ZSk7XG4gICAgaGlkZShUeXBlZC5wcm90b3R5cGUsIFZJRVcsIHRydWUpO1xuICB9IGVsc2UgQ09OU1RSID0gZmFsc2U7XG59XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICBBQlY6IEFCVixcbiAgQ09OU1RSOiBDT05TVFIsXG4gIFRZUEVEOiBUWVBFRCxcbiAgVklFVzogVklFV1xufTtcbiIsInZhciBpZCA9IDA7XG52YXIgcHggPSBNYXRoLnJhbmRvbSgpO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoa2V5KSB7XG4gIHJldHVybiAnU3ltYm9sKCcuY29uY2F0KGtleSA9PT0gdW5kZWZpbmVkID8gJycgOiBrZXksICcpXycsICgrK2lkICsgcHgpLnRvU3RyaW5nKDM2KSk7XG59O1xuIiwidmFyIGdsb2JhbCA9IHJlcXVpcmUoJy4vX2dsb2JhbCcpO1xudmFyIG5hdmlnYXRvciA9IGdsb2JhbC5uYXZpZ2F0b3I7XG5cbm1vZHVsZS5leHBvcnRzID0gbmF2aWdhdG9yICYmIG5hdmlnYXRvci51c2VyQWdlbnQgfHwgJyc7XG4iLCJ2YXIgaXNPYmplY3QgPSByZXF1aXJlKCcuL19pcy1vYmplY3QnKTtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGl0LCBUWVBFKSB7XG4gIGlmICghaXNPYmplY3QoaXQpIHx8IGl0Ll90ICE9PSBUWVBFKSB0aHJvdyBUeXBlRXJyb3IoJ0luY29tcGF0aWJsZSByZWNlaXZlciwgJyArIFRZUEUgKyAnIHJlcXVpcmVkIScpO1xuICByZXR1cm4gaXQ7XG59O1xuIiwidmFyIGdsb2JhbCA9IHJlcXVpcmUoJy4vX2dsb2JhbCcpO1xudmFyIGNvcmUgPSByZXF1aXJlKCcuL19jb3JlJyk7XG52YXIgTElCUkFSWSA9IHJlcXVpcmUoJy4vX2xpYnJhcnknKTtcbnZhciB3a3NFeHQgPSByZXF1aXJlKCcuL193a3MtZXh0Jyk7XG52YXIgZGVmaW5lUHJvcGVydHkgPSByZXF1aXJlKCcuL19vYmplY3QtZHAnKS5mO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAobmFtZSkge1xuICB2YXIgJFN5bWJvbCA9IGNvcmUuU3ltYm9sIHx8IChjb3JlLlN5bWJvbCA9IExJQlJBUlkgPyB7fSA6IGdsb2JhbC5TeW1ib2wgfHwge30pO1xuICBpZiAobmFtZS5jaGFyQXQoMCkgIT0gJ18nICYmICEobmFtZSBpbiAkU3ltYm9sKSkgZGVmaW5lUHJvcGVydHkoJFN5bWJvbCwgbmFtZSwgeyB2YWx1ZTogd2tzRXh0LmYobmFtZSkgfSk7XG59O1xuIiwiZXhwb3J0cy5mID0gcmVxdWlyZSgnLi9fd2tzJyk7XG4iLCJ2YXIgc3RvcmUgPSByZXF1aXJlKCcuL19zaGFyZWQnKSgnd2tzJyk7XG52YXIgdWlkID0gcmVxdWlyZSgnLi9fdWlkJyk7XG52YXIgU3ltYm9sID0gcmVxdWlyZSgnLi9fZ2xvYmFsJykuU3ltYm9sO1xudmFyIFVTRV9TWU1CT0wgPSB0eXBlb2YgU3ltYm9sID09ICdmdW5jdGlvbic7XG5cbnZhciAkZXhwb3J0cyA9IG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKG5hbWUpIHtcbiAgcmV0dXJuIHN0b3JlW25hbWVdIHx8IChzdG9yZVtuYW1lXSA9XG4gICAgVVNFX1NZTUJPTCAmJiBTeW1ib2xbbmFtZV0gfHwgKFVTRV9TWU1CT0wgPyBTeW1ib2wgOiB1aWQpKCdTeW1ib2wuJyArIG5hbWUpKTtcbn07XG5cbiRleHBvcnRzLnN0b3JlID0gc3RvcmU7XG4iLCJ2YXIgY2xhc3NvZiA9IHJlcXVpcmUoJy4vX2NsYXNzb2YnKTtcbnZhciBJVEVSQVRPUiA9IHJlcXVpcmUoJy4vX3drcycpKCdpdGVyYXRvcicpO1xudmFyIEl0ZXJhdG9ycyA9IHJlcXVpcmUoJy4vX2l0ZXJhdG9ycycpO1xubW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuL19jb3JlJykuZ2V0SXRlcmF0b3JNZXRob2QgPSBmdW5jdGlvbiAoaXQpIHtcbiAgaWYgKGl0ICE9IHVuZGVmaW5lZCkgcmV0dXJuIGl0W0lURVJBVE9SXVxuICAgIHx8IGl0WydAQGl0ZXJhdG9yJ11cbiAgICB8fCBJdGVyYXRvcnNbY2xhc3NvZihpdCldO1xufTtcbiIsIi8vIDIyLjEuMy4zIEFycmF5LnByb3RvdHlwZS5jb3B5V2l0aGluKHRhcmdldCwgc3RhcnQsIGVuZCA9IHRoaXMubGVuZ3RoKVxudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcblxuJGV4cG9ydCgkZXhwb3J0LlAsICdBcnJheScsIHsgY29weVdpdGhpbjogcmVxdWlyZSgnLi9fYXJyYXktY29weS13aXRoaW4nKSB9KTtcblxucmVxdWlyZSgnLi9fYWRkLXRvLXVuc2NvcGFibGVzJykoJ2NvcHlXaXRoaW4nKTtcbiIsIid1c2Ugc3RyaWN0JztcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgJGV2ZXJ5ID0gcmVxdWlyZSgnLi9fYXJyYXktbWV0aG9kcycpKDQpO1xuXG4kZXhwb3J0KCRleHBvcnQuUCArICRleHBvcnQuRiAqICFyZXF1aXJlKCcuL19zdHJpY3QtbWV0aG9kJykoW10uZXZlcnksIHRydWUpLCAnQXJyYXknLCB7XG4gIC8vIDIyLjEuMy41IC8gMTUuNC40LjE2IEFycmF5LnByb3RvdHlwZS5ldmVyeShjYWxsYmFja2ZuIFssIHRoaXNBcmddKVxuICBldmVyeTogZnVuY3Rpb24gZXZlcnkoY2FsbGJhY2tmbiAvKiAsIHRoaXNBcmcgKi8pIHtcbiAgICByZXR1cm4gJGV2ZXJ5KHRoaXMsIGNhbGxiYWNrZm4sIGFyZ3VtZW50c1sxXSk7XG4gIH1cbn0pO1xuIiwiLy8gMjIuMS4zLjYgQXJyYXkucHJvdG90eXBlLmZpbGwodmFsdWUsIHN0YXJ0ID0gMCwgZW5kID0gdGhpcy5sZW5ndGgpXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xuXG4kZXhwb3J0KCRleHBvcnQuUCwgJ0FycmF5JywgeyBmaWxsOiByZXF1aXJlKCcuL19hcnJheS1maWxsJykgfSk7XG5cbnJlcXVpcmUoJy4vX2FkZC10by11bnNjb3BhYmxlcycpKCdmaWxsJyk7XG4iLCIndXNlIHN0cmljdCc7XG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyICRmaWx0ZXIgPSByZXF1aXJlKCcuL19hcnJheS1tZXRob2RzJykoMik7XG5cbiRleHBvcnQoJGV4cG9ydC5QICsgJGV4cG9ydC5GICogIXJlcXVpcmUoJy4vX3N0cmljdC1tZXRob2QnKShbXS5maWx0ZXIsIHRydWUpLCAnQXJyYXknLCB7XG4gIC8vIDIyLjEuMy43IC8gMTUuNC40LjIwIEFycmF5LnByb3RvdHlwZS5maWx0ZXIoY2FsbGJhY2tmbiBbLCB0aGlzQXJnXSlcbiAgZmlsdGVyOiBmdW5jdGlvbiBmaWx0ZXIoY2FsbGJhY2tmbiAvKiAsIHRoaXNBcmcgKi8pIHtcbiAgICByZXR1cm4gJGZpbHRlcih0aGlzLCBjYWxsYmFja2ZuLCBhcmd1bWVudHNbMV0pO1xuICB9XG59KTtcbiIsIid1c2Ugc3RyaWN0Jztcbi8vIDIyLjEuMy45IEFycmF5LnByb3RvdHlwZS5maW5kSW5kZXgocHJlZGljYXRlLCB0aGlzQXJnID0gdW5kZWZpbmVkKVxudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciAkZmluZCA9IHJlcXVpcmUoJy4vX2FycmF5LW1ldGhvZHMnKSg2KTtcbnZhciBLRVkgPSAnZmluZEluZGV4JztcbnZhciBmb3JjZWQgPSB0cnVlO1xuLy8gU2hvdWxkbid0IHNraXAgaG9sZXNcbmlmIChLRVkgaW4gW10pIEFycmF5KDEpW0tFWV0oZnVuY3Rpb24gKCkgeyBmb3JjZWQgPSBmYWxzZTsgfSk7XG4kZXhwb3J0KCRleHBvcnQuUCArICRleHBvcnQuRiAqIGZvcmNlZCwgJ0FycmF5Jywge1xuICBmaW5kSW5kZXg6IGZ1bmN0aW9uIGZpbmRJbmRleChjYWxsYmFja2ZuIC8qICwgdGhhdCA9IHVuZGVmaW5lZCAqLykge1xuICAgIHJldHVybiAkZmluZCh0aGlzLCBjYWxsYmFja2ZuLCBhcmd1bWVudHMubGVuZ3RoID4gMSA/IGFyZ3VtZW50c1sxXSA6IHVuZGVmaW5lZCk7XG4gIH1cbn0pO1xucmVxdWlyZSgnLi9fYWRkLXRvLXVuc2NvcGFibGVzJykoS0VZKTtcbiIsIid1c2Ugc3RyaWN0Jztcbi8vIDIyLjEuMy44IEFycmF5LnByb3RvdHlwZS5maW5kKHByZWRpY2F0ZSwgdGhpc0FyZyA9IHVuZGVmaW5lZClcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgJGZpbmQgPSByZXF1aXJlKCcuL19hcnJheS1tZXRob2RzJykoNSk7XG52YXIgS0VZID0gJ2ZpbmQnO1xudmFyIGZvcmNlZCA9IHRydWU7XG4vLyBTaG91bGRuJ3Qgc2tpcCBob2xlc1xuaWYgKEtFWSBpbiBbXSkgQXJyYXkoMSlbS0VZXShmdW5jdGlvbiAoKSB7IGZvcmNlZCA9IGZhbHNlOyB9KTtcbiRleHBvcnQoJGV4cG9ydC5QICsgJGV4cG9ydC5GICogZm9yY2VkLCAnQXJyYXknLCB7XG4gIGZpbmQ6IGZ1bmN0aW9uIGZpbmQoY2FsbGJhY2tmbiAvKiAsIHRoYXQgPSB1bmRlZmluZWQgKi8pIHtcbiAgICByZXR1cm4gJGZpbmQodGhpcywgY2FsbGJhY2tmbiwgYXJndW1lbnRzLmxlbmd0aCA+IDEgPyBhcmd1bWVudHNbMV0gOiB1bmRlZmluZWQpO1xuICB9XG59KTtcbnJlcXVpcmUoJy4vX2FkZC10by11bnNjb3BhYmxlcycpKEtFWSk7XG4iLCIndXNlIHN0cmljdCc7XG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyICRmb3JFYWNoID0gcmVxdWlyZSgnLi9fYXJyYXktbWV0aG9kcycpKDApO1xudmFyIFNUUklDVCA9IHJlcXVpcmUoJy4vX3N0cmljdC1tZXRob2QnKShbXS5mb3JFYWNoLCB0cnVlKTtcblxuJGV4cG9ydCgkZXhwb3J0LlAgKyAkZXhwb3J0LkYgKiAhU1RSSUNULCAnQXJyYXknLCB7XG4gIC8vIDIyLjEuMy4xMCAvIDE1LjQuNC4xOCBBcnJheS5wcm90b3R5cGUuZm9yRWFjaChjYWxsYmFja2ZuIFssIHRoaXNBcmddKVxuICBmb3JFYWNoOiBmdW5jdGlvbiBmb3JFYWNoKGNhbGxiYWNrZm4gLyogLCB0aGlzQXJnICovKSB7XG4gICAgcmV0dXJuICRmb3JFYWNoKHRoaXMsIGNhbGxiYWNrZm4sIGFyZ3VtZW50c1sxXSk7XG4gIH1cbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xudmFyIGN0eCA9IHJlcXVpcmUoJy4vX2N0eCcpO1xudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciB0b09iamVjdCA9IHJlcXVpcmUoJy4vX3RvLW9iamVjdCcpO1xudmFyIGNhbGwgPSByZXF1aXJlKCcuL19pdGVyLWNhbGwnKTtcbnZhciBpc0FycmF5SXRlciA9IHJlcXVpcmUoJy4vX2lzLWFycmF5LWl0ZXInKTtcbnZhciB0b0xlbmd0aCA9IHJlcXVpcmUoJy4vX3RvLWxlbmd0aCcpO1xudmFyIGNyZWF0ZVByb3BlcnR5ID0gcmVxdWlyZSgnLi9fY3JlYXRlLXByb3BlcnR5Jyk7XG52YXIgZ2V0SXRlckZuID0gcmVxdWlyZSgnLi9jb3JlLmdldC1pdGVyYXRvci1tZXRob2QnKTtcblxuJGV4cG9ydCgkZXhwb3J0LlMgKyAkZXhwb3J0LkYgKiAhcmVxdWlyZSgnLi9faXRlci1kZXRlY3QnKShmdW5jdGlvbiAoaXRlcikgeyBBcnJheS5mcm9tKGl0ZXIpOyB9KSwgJ0FycmF5Jywge1xuICAvLyAyMi4xLjIuMSBBcnJheS5mcm9tKGFycmF5TGlrZSwgbWFwZm4gPSB1bmRlZmluZWQsIHRoaXNBcmcgPSB1bmRlZmluZWQpXG4gIGZyb206IGZ1bmN0aW9uIGZyb20oYXJyYXlMaWtlIC8qICwgbWFwZm4gPSB1bmRlZmluZWQsIHRoaXNBcmcgPSB1bmRlZmluZWQgKi8pIHtcbiAgICB2YXIgTyA9IHRvT2JqZWN0KGFycmF5TGlrZSk7XG4gICAgdmFyIEMgPSB0eXBlb2YgdGhpcyA9PSAnZnVuY3Rpb24nID8gdGhpcyA6IEFycmF5O1xuICAgIHZhciBhTGVuID0gYXJndW1lbnRzLmxlbmd0aDtcbiAgICB2YXIgbWFwZm4gPSBhTGVuID4gMSA/IGFyZ3VtZW50c1sxXSA6IHVuZGVmaW5lZDtcbiAgICB2YXIgbWFwcGluZyA9IG1hcGZuICE9PSB1bmRlZmluZWQ7XG4gICAgdmFyIGluZGV4ID0gMDtcbiAgICB2YXIgaXRlckZuID0gZ2V0SXRlckZuKE8pO1xuICAgIHZhciBsZW5ndGgsIHJlc3VsdCwgc3RlcCwgaXRlcmF0b3I7XG4gICAgaWYgKG1hcHBpbmcpIG1hcGZuID0gY3R4KG1hcGZuLCBhTGVuID4gMiA/IGFyZ3VtZW50c1syXSA6IHVuZGVmaW5lZCwgMik7XG4gICAgLy8gaWYgb2JqZWN0IGlzbid0IGl0ZXJhYmxlIG9yIGl0J3MgYXJyYXkgd2l0aCBkZWZhdWx0IGl0ZXJhdG9yIC0gdXNlIHNpbXBsZSBjYXNlXG4gICAgaWYgKGl0ZXJGbiAhPSB1bmRlZmluZWQgJiYgIShDID09IEFycmF5ICYmIGlzQXJyYXlJdGVyKGl0ZXJGbikpKSB7XG4gICAgICBmb3IgKGl0ZXJhdG9yID0gaXRlckZuLmNhbGwoTyksIHJlc3VsdCA9IG5ldyBDKCk7ICEoc3RlcCA9IGl0ZXJhdG9yLm5leHQoKSkuZG9uZTsgaW5kZXgrKykge1xuICAgICAgICBjcmVhdGVQcm9wZXJ0eShyZXN1bHQsIGluZGV4LCBtYXBwaW5nID8gY2FsbChpdGVyYXRvciwgbWFwZm4sIFtzdGVwLnZhbHVlLCBpbmRleF0sIHRydWUpIDogc3RlcC52YWx1ZSk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGxlbmd0aCA9IHRvTGVuZ3RoKE8ubGVuZ3RoKTtcbiAgICAgIGZvciAocmVzdWx0ID0gbmV3IEMobGVuZ3RoKTsgbGVuZ3RoID4gaW5kZXg7IGluZGV4KyspIHtcbiAgICAgICAgY3JlYXRlUHJvcGVydHkocmVzdWx0LCBpbmRleCwgbWFwcGluZyA/IG1hcGZuKE9baW5kZXhdLCBpbmRleCkgOiBPW2luZGV4XSk7XG4gICAgICB9XG4gICAgfVxuICAgIHJlc3VsdC5sZW5ndGggPSBpbmRleDtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG59KTtcbiIsIid1c2Ugc3RyaWN0JztcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgJGluZGV4T2YgPSByZXF1aXJlKCcuL19hcnJheS1pbmNsdWRlcycpKGZhbHNlKTtcbnZhciAkbmF0aXZlID0gW10uaW5kZXhPZjtcbnZhciBORUdBVElWRV9aRVJPID0gISEkbmF0aXZlICYmIDEgLyBbMV0uaW5kZXhPZigxLCAtMCkgPCAwO1xuXG4kZXhwb3J0KCRleHBvcnQuUCArICRleHBvcnQuRiAqIChORUdBVElWRV9aRVJPIHx8ICFyZXF1aXJlKCcuL19zdHJpY3QtbWV0aG9kJykoJG5hdGl2ZSkpLCAnQXJyYXknLCB7XG4gIC8vIDIyLjEuMy4xMSAvIDE1LjQuNC4xNCBBcnJheS5wcm90b3R5cGUuaW5kZXhPZihzZWFyY2hFbGVtZW50IFssIGZyb21JbmRleF0pXG4gIGluZGV4T2Y6IGZ1bmN0aW9uIGluZGV4T2Yoc2VhcmNoRWxlbWVudCAvKiAsIGZyb21JbmRleCA9IDAgKi8pIHtcbiAgICByZXR1cm4gTkVHQVRJVkVfWkVST1xuICAgICAgLy8gY29udmVydCAtMCB0byArMFxuICAgICAgPyAkbmF0aXZlLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgfHwgMFxuICAgICAgOiAkaW5kZXhPZih0aGlzLCBzZWFyY2hFbGVtZW50LCBhcmd1bWVudHNbMV0pO1xuICB9XG59KTtcbiIsIi8vIDIyLjEuMi4yIC8gMTUuNC4zLjIgQXJyYXkuaXNBcnJheShhcmcpXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xuXG4kZXhwb3J0KCRleHBvcnQuUywgJ0FycmF5JywgeyBpc0FycmF5OiByZXF1aXJlKCcuL19pcy1hcnJheScpIH0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xudmFyIGFkZFRvVW5zY29wYWJsZXMgPSByZXF1aXJlKCcuL19hZGQtdG8tdW5zY29wYWJsZXMnKTtcbnZhciBzdGVwID0gcmVxdWlyZSgnLi9faXRlci1zdGVwJyk7XG52YXIgSXRlcmF0b3JzID0gcmVxdWlyZSgnLi9faXRlcmF0b3JzJyk7XG52YXIgdG9JT2JqZWN0ID0gcmVxdWlyZSgnLi9fdG8taW9iamVjdCcpO1xuXG4vLyAyMi4xLjMuNCBBcnJheS5wcm90b3R5cGUuZW50cmllcygpXG4vLyAyMi4xLjMuMTMgQXJyYXkucHJvdG90eXBlLmtleXMoKVxuLy8gMjIuMS4zLjI5IEFycmF5LnByb3RvdHlwZS52YWx1ZXMoKVxuLy8gMjIuMS4zLjMwIEFycmF5LnByb3RvdHlwZVtAQGl0ZXJhdG9yXSgpXG5tb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoJy4vX2l0ZXItZGVmaW5lJykoQXJyYXksICdBcnJheScsIGZ1bmN0aW9uIChpdGVyYXRlZCwga2luZCkge1xuICB0aGlzLl90ID0gdG9JT2JqZWN0KGl0ZXJhdGVkKTsgLy8gdGFyZ2V0XG4gIHRoaXMuX2kgPSAwOyAgICAgICAgICAgICAgICAgICAvLyBuZXh0IGluZGV4XG4gIHRoaXMuX2sgPSBraW5kOyAgICAgICAgICAgICAgICAvLyBraW5kXG4vLyAyMi4xLjUuMi4xICVBcnJheUl0ZXJhdG9yUHJvdG90eXBlJS5uZXh0KClcbn0sIGZ1bmN0aW9uICgpIHtcbiAgdmFyIE8gPSB0aGlzLl90O1xuICB2YXIga2luZCA9IHRoaXMuX2s7XG4gIHZhciBpbmRleCA9IHRoaXMuX2krKztcbiAgaWYgKCFPIHx8IGluZGV4ID49IE8ubGVuZ3RoKSB7XG4gICAgdGhpcy5fdCA9IHVuZGVmaW5lZDtcbiAgICByZXR1cm4gc3RlcCgxKTtcbiAgfVxuICBpZiAoa2luZCA9PSAna2V5cycpIHJldHVybiBzdGVwKDAsIGluZGV4KTtcbiAgaWYgKGtpbmQgPT0gJ3ZhbHVlcycpIHJldHVybiBzdGVwKDAsIE9baW5kZXhdKTtcbiAgcmV0dXJuIHN0ZXAoMCwgW2luZGV4LCBPW2luZGV4XV0pO1xufSwgJ3ZhbHVlcycpO1xuXG4vLyBhcmd1bWVudHNMaXN0W0BAaXRlcmF0b3JdIGlzICVBcnJheVByb3RvX3ZhbHVlcyUgKDkuNC40LjYsIDkuNC40LjcpXG5JdGVyYXRvcnMuQXJndW1lbnRzID0gSXRlcmF0b3JzLkFycmF5O1xuXG5hZGRUb1Vuc2NvcGFibGVzKCdrZXlzJyk7XG5hZGRUb1Vuc2NvcGFibGVzKCd2YWx1ZXMnKTtcbmFkZFRvVW5zY29wYWJsZXMoJ2VudHJpZXMnKTtcbiIsIid1c2Ugc3RyaWN0Jztcbi8vIDIyLjEuMy4xMyBBcnJheS5wcm90b3R5cGUuam9pbihzZXBhcmF0b3IpXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyIHRvSU9iamVjdCA9IHJlcXVpcmUoJy4vX3RvLWlvYmplY3QnKTtcbnZhciBhcnJheUpvaW4gPSBbXS5qb2luO1xuXG4vLyBmYWxsYmFjayBmb3Igbm90IGFycmF5LWxpa2Ugc3RyaW5nc1xuJGV4cG9ydCgkZXhwb3J0LlAgKyAkZXhwb3J0LkYgKiAocmVxdWlyZSgnLi9faW9iamVjdCcpICE9IE9iamVjdCB8fCAhcmVxdWlyZSgnLi9fc3RyaWN0LW1ldGhvZCcpKGFycmF5Sm9pbikpLCAnQXJyYXknLCB7XG4gIGpvaW46IGZ1bmN0aW9uIGpvaW4oc2VwYXJhdG9yKSB7XG4gICAgcmV0dXJuIGFycmF5Sm9pbi5jYWxsKHRvSU9iamVjdCh0aGlzKSwgc2VwYXJhdG9yID09PSB1bmRlZmluZWQgPyAnLCcgOiBzZXBhcmF0b3IpO1xuICB9XG59KTtcbiIsIid1c2Ugc3RyaWN0JztcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgdG9JT2JqZWN0ID0gcmVxdWlyZSgnLi9fdG8taW9iamVjdCcpO1xudmFyIHRvSW50ZWdlciA9IHJlcXVpcmUoJy4vX3RvLWludGVnZXInKTtcbnZhciB0b0xlbmd0aCA9IHJlcXVpcmUoJy4vX3RvLWxlbmd0aCcpO1xudmFyICRuYXRpdmUgPSBbXS5sYXN0SW5kZXhPZjtcbnZhciBORUdBVElWRV9aRVJPID0gISEkbmF0aXZlICYmIDEgLyBbMV0ubGFzdEluZGV4T2YoMSwgLTApIDwgMDtcblxuJGV4cG9ydCgkZXhwb3J0LlAgKyAkZXhwb3J0LkYgKiAoTkVHQVRJVkVfWkVSTyB8fCAhcmVxdWlyZSgnLi9fc3RyaWN0LW1ldGhvZCcpKCRuYXRpdmUpKSwgJ0FycmF5Jywge1xuICAvLyAyMi4xLjMuMTQgLyAxNS40LjQuMTUgQXJyYXkucHJvdG90eXBlLmxhc3RJbmRleE9mKHNlYXJjaEVsZW1lbnQgWywgZnJvbUluZGV4XSlcbiAgbGFzdEluZGV4T2Y6IGZ1bmN0aW9uIGxhc3RJbmRleE9mKHNlYXJjaEVsZW1lbnQgLyogLCBmcm9tSW5kZXggPSBAWyotMV0gKi8pIHtcbiAgICAvLyBjb252ZXJ0IC0wIHRvICswXG4gICAgaWYgKE5FR0FUSVZFX1pFUk8pIHJldHVybiAkbmF0aXZlLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgfHwgMDtcbiAgICB2YXIgTyA9IHRvSU9iamVjdCh0aGlzKTtcbiAgICB2YXIgbGVuZ3RoID0gdG9MZW5ndGgoTy5sZW5ndGgpO1xuICAgIHZhciBpbmRleCA9IGxlbmd0aCAtIDE7XG4gICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPiAxKSBpbmRleCA9IE1hdGgubWluKGluZGV4LCB0b0ludGVnZXIoYXJndW1lbnRzWzFdKSk7XG4gICAgaWYgKGluZGV4IDwgMCkgaW5kZXggPSBsZW5ndGggKyBpbmRleDtcbiAgICBmb3IgKDtpbmRleCA+PSAwOyBpbmRleC0tKSBpZiAoaW5kZXggaW4gTykgaWYgKE9baW5kZXhdID09PSBzZWFyY2hFbGVtZW50KSByZXR1cm4gaW5kZXggfHwgMDtcbiAgICByZXR1cm4gLTE7XG4gIH1cbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciAkbWFwID0gcmVxdWlyZSgnLi9fYXJyYXktbWV0aG9kcycpKDEpO1xuXG4kZXhwb3J0KCRleHBvcnQuUCArICRleHBvcnQuRiAqICFyZXF1aXJlKCcuL19zdHJpY3QtbWV0aG9kJykoW10ubWFwLCB0cnVlKSwgJ0FycmF5Jywge1xuICAvLyAyMi4xLjMuMTUgLyAxNS40LjQuMTkgQXJyYXkucHJvdG90eXBlLm1hcChjYWxsYmFja2ZuIFssIHRoaXNBcmddKVxuICBtYXA6IGZ1bmN0aW9uIG1hcChjYWxsYmFja2ZuIC8qICwgdGhpc0FyZyAqLykge1xuICAgIHJldHVybiAkbWFwKHRoaXMsIGNhbGxiYWNrZm4sIGFyZ3VtZW50c1sxXSk7XG4gIH1cbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciBjcmVhdGVQcm9wZXJ0eSA9IHJlcXVpcmUoJy4vX2NyZWF0ZS1wcm9wZXJ0eScpO1xuXG4vLyBXZWJLaXQgQXJyYXkub2YgaXNuJ3QgZ2VuZXJpY1xuJGV4cG9ydCgkZXhwb3J0LlMgKyAkZXhwb3J0LkYgKiByZXF1aXJlKCcuL19mYWlscycpKGZ1bmN0aW9uICgpIHtcbiAgZnVuY3Rpb24gRigpIHsgLyogZW1wdHkgKi8gfVxuICByZXR1cm4gIShBcnJheS5vZi5jYWxsKEYpIGluc3RhbmNlb2YgRik7XG59KSwgJ0FycmF5Jywge1xuICAvLyAyMi4xLjIuMyBBcnJheS5vZiggLi4uaXRlbXMpXG4gIG9mOiBmdW5jdGlvbiBvZigvKiAuLi5hcmdzICovKSB7XG4gICAgdmFyIGluZGV4ID0gMDtcbiAgICB2YXIgYUxlbiA9IGFyZ3VtZW50cy5sZW5ndGg7XG4gICAgdmFyIHJlc3VsdCA9IG5ldyAodHlwZW9mIHRoaXMgPT0gJ2Z1bmN0aW9uJyA/IHRoaXMgOiBBcnJheSkoYUxlbik7XG4gICAgd2hpbGUgKGFMZW4gPiBpbmRleCkgY3JlYXRlUHJvcGVydHkocmVzdWx0LCBpbmRleCwgYXJndW1lbnRzW2luZGV4KytdKTtcbiAgICByZXN1bHQubGVuZ3RoID0gYUxlbjtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG59KTtcbiIsIid1c2Ugc3RyaWN0JztcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgJHJlZHVjZSA9IHJlcXVpcmUoJy4vX2FycmF5LXJlZHVjZScpO1xuXG4kZXhwb3J0KCRleHBvcnQuUCArICRleHBvcnQuRiAqICFyZXF1aXJlKCcuL19zdHJpY3QtbWV0aG9kJykoW10ucmVkdWNlUmlnaHQsIHRydWUpLCAnQXJyYXknLCB7XG4gIC8vIDIyLjEuMy4xOSAvIDE1LjQuNC4yMiBBcnJheS5wcm90b3R5cGUucmVkdWNlUmlnaHQoY2FsbGJhY2tmbiBbLCBpbml0aWFsVmFsdWVdKVxuICByZWR1Y2VSaWdodDogZnVuY3Rpb24gcmVkdWNlUmlnaHQoY2FsbGJhY2tmbiAvKiAsIGluaXRpYWxWYWx1ZSAqLykge1xuICAgIHJldHVybiAkcmVkdWNlKHRoaXMsIGNhbGxiYWNrZm4sIGFyZ3VtZW50cy5sZW5ndGgsIGFyZ3VtZW50c1sxXSwgdHJ1ZSk7XG4gIH1cbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciAkcmVkdWNlID0gcmVxdWlyZSgnLi9fYXJyYXktcmVkdWNlJyk7XG5cbiRleHBvcnQoJGV4cG9ydC5QICsgJGV4cG9ydC5GICogIXJlcXVpcmUoJy4vX3N0cmljdC1tZXRob2QnKShbXS5yZWR1Y2UsIHRydWUpLCAnQXJyYXknLCB7XG4gIC8vIDIyLjEuMy4xOCAvIDE1LjQuNC4yMSBBcnJheS5wcm90b3R5cGUucmVkdWNlKGNhbGxiYWNrZm4gWywgaW5pdGlhbFZhbHVlXSlcbiAgcmVkdWNlOiBmdW5jdGlvbiByZWR1Y2UoY2FsbGJhY2tmbiAvKiAsIGluaXRpYWxWYWx1ZSAqLykge1xuICAgIHJldHVybiAkcmVkdWNlKHRoaXMsIGNhbGxiYWNrZm4sIGFyZ3VtZW50cy5sZW5ndGgsIGFyZ3VtZW50c1sxXSwgZmFsc2UpO1xuICB9XG59KTtcbiIsIid1c2Ugc3RyaWN0JztcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgaHRtbCA9IHJlcXVpcmUoJy4vX2h0bWwnKTtcbnZhciBjb2YgPSByZXF1aXJlKCcuL19jb2YnKTtcbnZhciB0b0Fic29sdXRlSW5kZXggPSByZXF1aXJlKCcuL190by1hYnNvbHV0ZS1pbmRleCcpO1xudmFyIHRvTGVuZ3RoID0gcmVxdWlyZSgnLi9fdG8tbGVuZ3RoJyk7XG52YXIgYXJyYXlTbGljZSA9IFtdLnNsaWNlO1xuXG4vLyBmYWxsYmFjayBmb3Igbm90IGFycmF5LWxpa2UgRVMzIHN0cmluZ3MgYW5kIERPTSBvYmplY3RzXG4kZXhwb3J0KCRleHBvcnQuUCArICRleHBvcnQuRiAqIHJlcXVpcmUoJy4vX2ZhaWxzJykoZnVuY3Rpb24gKCkge1xuICBpZiAoaHRtbCkgYXJyYXlTbGljZS5jYWxsKGh0bWwpO1xufSksICdBcnJheScsIHtcbiAgc2xpY2U6IGZ1bmN0aW9uIHNsaWNlKGJlZ2luLCBlbmQpIHtcbiAgICB2YXIgbGVuID0gdG9MZW5ndGgodGhpcy5sZW5ndGgpO1xuICAgIHZhciBrbGFzcyA9IGNvZih0aGlzKTtcbiAgICBlbmQgPSBlbmQgPT09IHVuZGVmaW5lZCA/IGxlbiA6IGVuZDtcbiAgICBpZiAoa2xhc3MgPT0gJ0FycmF5JykgcmV0dXJuIGFycmF5U2xpY2UuY2FsbCh0aGlzLCBiZWdpbiwgZW5kKTtcbiAgICB2YXIgc3RhcnQgPSB0b0Fic29sdXRlSW5kZXgoYmVnaW4sIGxlbik7XG4gICAgdmFyIHVwVG8gPSB0b0Fic29sdXRlSW5kZXgoZW5kLCBsZW4pO1xuICAgIHZhciBzaXplID0gdG9MZW5ndGgodXBUbyAtIHN0YXJ0KTtcbiAgICB2YXIgY2xvbmVkID0gbmV3IEFycmF5KHNpemUpO1xuICAgIHZhciBpID0gMDtcbiAgICBmb3IgKDsgaSA8IHNpemU7IGkrKykgY2xvbmVkW2ldID0ga2xhc3MgPT0gJ1N0cmluZydcbiAgICAgID8gdGhpcy5jaGFyQXQoc3RhcnQgKyBpKVxuICAgICAgOiB0aGlzW3N0YXJ0ICsgaV07XG4gICAgcmV0dXJuIGNsb25lZDtcbiAgfVxufSk7XG4iLCIndXNlIHN0cmljdCc7XG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyICRzb21lID0gcmVxdWlyZSgnLi9fYXJyYXktbWV0aG9kcycpKDMpO1xuXG4kZXhwb3J0KCRleHBvcnQuUCArICRleHBvcnQuRiAqICFyZXF1aXJlKCcuL19zdHJpY3QtbWV0aG9kJykoW10uc29tZSwgdHJ1ZSksICdBcnJheScsIHtcbiAgLy8gMjIuMS4zLjIzIC8gMTUuNC40LjE3IEFycmF5LnByb3RvdHlwZS5zb21lKGNhbGxiYWNrZm4gWywgdGhpc0FyZ10pXG4gIHNvbWU6IGZ1bmN0aW9uIHNvbWUoY2FsbGJhY2tmbiAvKiAsIHRoaXNBcmcgKi8pIHtcbiAgICByZXR1cm4gJHNvbWUodGhpcywgY2FsbGJhY2tmbiwgYXJndW1lbnRzWzFdKTtcbiAgfVxufSk7XG4iLCIndXNlIHN0cmljdCc7XG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyIGFGdW5jdGlvbiA9IHJlcXVpcmUoJy4vX2EtZnVuY3Rpb24nKTtcbnZhciB0b09iamVjdCA9IHJlcXVpcmUoJy4vX3RvLW9iamVjdCcpO1xudmFyIGZhaWxzID0gcmVxdWlyZSgnLi9fZmFpbHMnKTtcbnZhciAkc29ydCA9IFtdLnNvcnQ7XG52YXIgdGVzdCA9IFsxLCAyLCAzXTtcblxuJGV4cG9ydCgkZXhwb3J0LlAgKyAkZXhwb3J0LkYgKiAoZmFpbHMoZnVuY3Rpb24gKCkge1xuICAvLyBJRTgtXG4gIHRlc3Quc29ydCh1bmRlZmluZWQpO1xufSkgfHwgIWZhaWxzKGZ1bmN0aW9uICgpIHtcbiAgLy8gVjggYnVnXG4gIHRlc3Quc29ydChudWxsKTtcbiAgLy8gT2xkIFdlYktpdFxufSkgfHwgIXJlcXVpcmUoJy4vX3N0cmljdC1tZXRob2QnKSgkc29ydCkpLCAnQXJyYXknLCB7XG4gIC8vIDIyLjEuMy4yNSBBcnJheS5wcm90b3R5cGUuc29ydChjb21wYXJlZm4pXG4gIHNvcnQ6IGZ1bmN0aW9uIHNvcnQoY29tcGFyZWZuKSB7XG4gICAgcmV0dXJuIGNvbXBhcmVmbiA9PT0gdW5kZWZpbmVkXG4gICAgICA/ICRzb3J0LmNhbGwodG9PYmplY3QodGhpcykpXG4gICAgICA6ICRzb3J0LmNhbGwodG9PYmplY3QodGhpcyksIGFGdW5jdGlvbihjb21wYXJlZm4pKTtcbiAgfVxufSk7XG4iLCJyZXF1aXJlKCcuL19zZXQtc3BlY2llcycpKCdBcnJheScpO1xuIiwiLy8gMjAuMy4zLjEgLyAxNS45LjQuNCBEYXRlLm5vdygpXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xuXG4kZXhwb3J0KCRleHBvcnQuUywgJ0RhdGUnLCB7IG5vdzogZnVuY3Rpb24gKCkgeyByZXR1cm4gbmV3IERhdGUoKS5nZXRUaW1lKCk7IH0gfSk7XG4iLCIvLyAyMC4zLjQuMzYgLyAxNS45LjUuNDMgRGF0ZS5wcm90b3R5cGUudG9JU09TdHJpbmcoKVxudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciB0b0lTT1N0cmluZyA9IHJlcXVpcmUoJy4vX2RhdGUtdG8taXNvLXN0cmluZycpO1xuXG4vLyBQaGFudG9tSlMgLyBvbGQgV2ViS2l0IGhhcyBhIGJyb2tlbiBpbXBsZW1lbnRhdGlvbnNcbiRleHBvcnQoJGV4cG9ydC5QICsgJGV4cG9ydC5GICogKERhdGUucHJvdG90eXBlLnRvSVNPU3RyaW5nICE9PSB0b0lTT1N0cmluZyksICdEYXRlJywge1xuICB0b0lTT1N0cmluZzogdG9JU09TdHJpbmdcbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciB0b09iamVjdCA9IHJlcXVpcmUoJy4vX3RvLW9iamVjdCcpO1xudmFyIHRvUHJpbWl0aXZlID0gcmVxdWlyZSgnLi9fdG8tcHJpbWl0aXZlJyk7XG5cbiRleHBvcnQoJGV4cG9ydC5QICsgJGV4cG9ydC5GICogcmVxdWlyZSgnLi9fZmFpbHMnKShmdW5jdGlvbiAoKSB7XG4gIHJldHVybiBuZXcgRGF0ZShOYU4pLnRvSlNPTigpICE9PSBudWxsXG4gICAgfHwgRGF0ZS5wcm90b3R5cGUudG9KU09OLmNhbGwoeyB0b0lTT1N0cmluZzogZnVuY3Rpb24gKCkgeyByZXR1cm4gMTsgfSB9KSAhPT0gMTtcbn0pLCAnRGF0ZScsIHtcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXVudXNlZC12YXJzXG4gIHRvSlNPTjogZnVuY3Rpb24gdG9KU09OKGtleSkge1xuICAgIHZhciBPID0gdG9PYmplY3QodGhpcyk7XG4gICAgdmFyIHB2ID0gdG9QcmltaXRpdmUoTyk7XG4gICAgcmV0dXJuIHR5cGVvZiBwdiA9PSAnbnVtYmVyJyAmJiAhaXNGaW5pdGUocHYpID8gbnVsbCA6IE8udG9JU09TdHJpbmcoKTtcbiAgfVxufSk7XG4iLCJ2YXIgVE9fUFJJTUlUSVZFID0gcmVxdWlyZSgnLi9fd2tzJykoJ3RvUHJpbWl0aXZlJyk7XG52YXIgcHJvdG8gPSBEYXRlLnByb3RvdHlwZTtcblxuaWYgKCEoVE9fUFJJTUlUSVZFIGluIHByb3RvKSkgcmVxdWlyZSgnLi9faGlkZScpKHByb3RvLCBUT19QUklNSVRJVkUsIHJlcXVpcmUoJy4vX2RhdGUtdG8tcHJpbWl0aXZlJykpO1xuIiwidmFyIERhdGVQcm90byA9IERhdGUucHJvdG90eXBlO1xudmFyIElOVkFMSURfREFURSA9ICdJbnZhbGlkIERhdGUnO1xudmFyIFRPX1NUUklORyA9ICd0b1N0cmluZyc7XG52YXIgJHRvU3RyaW5nID0gRGF0ZVByb3RvW1RPX1NUUklOR107XG52YXIgZ2V0VGltZSA9IERhdGVQcm90by5nZXRUaW1lO1xuaWYgKG5ldyBEYXRlKE5hTikgKyAnJyAhPSBJTlZBTElEX0RBVEUpIHtcbiAgcmVxdWlyZSgnLi9fcmVkZWZpbmUnKShEYXRlUHJvdG8sIFRPX1NUUklORywgZnVuY3Rpb24gdG9TdHJpbmcoKSB7XG4gICAgdmFyIHZhbHVlID0gZ2V0VGltZS5jYWxsKHRoaXMpO1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1zZWxmLWNvbXBhcmVcbiAgICByZXR1cm4gdmFsdWUgPT09IHZhbHVlID8gJHRvU3RyaW5nLmNhbGwodGhpcykgOiBJTlZBTElEX0RBVEU7XG4gIH0pO1xufVxuIiwiLy8gMTkuMi4zLjIgLyAxNS4zLjQuNSBGdW5jdGlvbi5wcm90b3R5cGUuYmluZCh0aGlzQXJnLCBhcmdzLi4uKVxudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcblxuJGV4cG9ydCgkZXhwb3J0LlAsICdGdW5jdGlvbicsIHsgYmluZDogcmVxdWlyZSgnLi9fYmluZCcpIH0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xudmFyIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi9faXMtb2JqZWN0Jyk7XG52YXIgZ2V0UHJvdG90eXBlT2YgPSByZXF1aXJlKCcuL19vYmplY3QtZ3BvJyk7XG52YXIgSEFTX0lOU1RBTkNFID0gcmVxdWlyZSgnLi9fd2tzJykoJ2hhc0luc3RhbmNlJyk7XG52YXIgRnVuY3Rpb25Qcm90byA9IEZ1bmN0aW9uLnByb3RvdHlwZTtcbi8vIDE5LjIuMy42IEZ1bmN0aW9uLnByb3RvdHlwZVtAQGhhc0luc3RhbmNlXShWKVxuaWYgKCEoSEFTX0lOU1RBTkNFIGluIEZ1bmN0aW9uUHJvdG8pKSByZXF1aXJlKCcuL19vYmplY3QtZHAnKS5mKEZ1bmN0aW9uUHJvdG8sIEhBU19JTlNUQU5DRSwgeyB2YWx1ZTogZnVuY3Rpb24gKE8pIHtcbiAgaWYgKHR5cGVvZiB0aGlzICE9ICdmdW5jdGlvbicgfHwgIWlzT2JqZWN0KE8pKSByZXR1cm4gZmFsc2U7XG4gIGlmICghaXNPYmplY3QodGhpcy5wcm90b3R5cGUpKSByZXR1cm4gTyBpbnN0YW5jZW9mIHRoaXM7XG4gIC8vIGZvciBlbnZpcm9ubWVudCB3L28gbmF0aXZlIGBAQGhhc0luc3RhbmNlYCBsb2dpYyBlbm91Z2ggYGluc3RhbmNlb2ZgLCBidXQgYWRkIHRoaXM6XG4gIHdoaWxlIChPID0gZ2V0UHJvdG90eXBlT2YoTykpIGlmICh0aGlzLnByb3RvdHlwZSA9PT0gTykgcmV0dXJuIHRydWU7XG4gIHJldHVybiBmYWxzZTtcbn0gfSk7XG4iLCJ2YXIgZFAgPSByZXF1aXJlKCcuL19vYmplY3QtZHAnKS5mO1xudmFyIEZQcm90byA9IEZ1bmN0aW9uLnByb3RvdHlwZTtcbnZhciBuYW1lUkUgPSAvXlxccypmdW5jdGlvbiAoW14gKF0qKS87XG52YXIgTkFNRSA9ICduYW1lJztcblxuLy8gMTkuMi40LjIgbmFtZVxuTkFNRSBpbiBGUHJvdG8gfHwgcmVxdWlyZSgnLi9fZGVzY3JpcHRvcnMnKSAmJiBkUChGUHJvdG8sIE5BTUUsIHtcbiAgY29uZmlndXJhYmxlOiB0cnVlLFxuICBnZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICB0cnkge1xuICAgICAgcmV0dXJuICgnJyArIHRoaXMpLm1hdGNoKG5hbWVSRSlbMV07XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgcmV0dXJuICcnO1xuICAgIH1cbiAgfVxufSk7XG4iLCIndXNlIHN0cmljdCc7XG52YXIgc3Ryb25nID0gcmVxdWlyZSgnLi9fY29sbGVjdGlvbi1zdHJvbmcnKTtcbnZhciB2YWxpZGF0ZSA9IHJlcXVpcmUoJy4vX3ZhbGlkYXRlLWNvbGxlY3Rpb24nKTtcbnZhciBNQVAgPSAnTWFwJztcblxuLy8gMjMuMSBNYXAgT2JqZWN0c1xubW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuL19jb2xsZWN0aW9uJykoTUFQLCBmdW5jdGlvbiAoZ2V0KSB7XG4gIHJldHVybiBmdW5jdGlvbiBNYXAoKSB7IHJldHVybiBnZXQodGhpcywgYXJndW1lbnRzLmxlbmd0aCA+IDAgPyBhcmd1bWVudHNbMF0gOiB1bmRlZmluZWQpOyB9O1xufSwge1xuICAvLyAyMy4xLjMuNiBNYXAucHJvdG90eXBlLmdldChrZXkpXG4gIGdldDogZnVuY3Rpb24gZ2V0KGtleSkge1xuICAgIHZhciBlbnRyeSA9IHN0cm9uZy5nZXRFbnRyeSh2YWxpZGF0ZSh0aGlzLCBNQVApLCBrZXkpO1xuICAgIHJldHVybiBlbnRyeSAmJiBlbnRyeS52O1xuICB9LFxuICAvLyAyMy4xLjMuOSBNYXAucHJvdG90eXBlLnNldChrZXksIHZhbHVlKVxuICBzZXQ6IGZ1bmN0aW9uIHNldChrZXksIHZhbHVlKSB7XG4gICAgcmV0dXJuIHN0cm9uZy5kZWYodmFsaWRhdGUodGhpcywgTUFQKSwga2V5ID09PSAwID8gMCA6IGtleSwgdmFsdWUpO1xuICB9XG59LCBzdHJvbmcsIHRydWUpO1xuIiwiLy8gMjAuMi4yLjMgTWF0aC5hY29zaCh4KVxudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciBsb2cxcCA9IHJlcXVpcmUoJy4vX21hdGgtbG9nMXAnKTtcbnZhciBzcXJ0ID0gTWF0aC5zcXJ0O1xudmFyICRhY29zaCA9IE1hdGguYWNvc2g7XG5cbiRleHBvcnQoJGV4cG9ydC5TICsgJGV4cG9ydC5GICogISgkYWNvc2hcbiAgLy8gVjggYnVnOiBodHRwczovL2NvZGUuZ29vZ2xlLmNvbS9wL3Y4L2lzc3Vlcy9kZXRhaWw/aWQ9MzUwOVxuICAmJiBNYXRoLmZsb29yKCRhY29zaChOdW1iZXIuTUFYX1ZBTFVFKSkgPT0gNzEwXG4gIC8vIFRvciBCcm93c2VyIGJ1ZzogTWF0aC5hY29zaChJbmZpbml0eSkgLT4gTmFOXG4gICYmICRhY29zaChJbmZpbml0eSkgPT0gSW5maW5pdHlcbiksICdNYXRoJywge1xuICBhY29zaDogZnVuY3Rpb24gYWNvc2goeCkge1xuICAgIHJldHVybiAoeCA9ICt4KSA8IDEgPyBOYU4gOiB4ID4gOTQ5MDYyNjUuNjI0MjUxNTZcbiAgICAgID8gTWF0aC5sb2coeCkgKyBNYXRoLkxOMlxuICAgICAgOiBsb2cxcCh4IC0gMSArIHNxcnQoeCAtIDEpICogc3FydCh4ICsgMSkpO1xuICB9XG59KTtcbiIsIi8vIDIwLjIuMi41IE1hdGguYXNpbmgoeClcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgJGFzaW5oID0gTWF0aC5hc2luaDtcblxuZnVuY3Rpb24gYXNpbmgoeCkge1xuICByZXR1cm4gIWlzRmluaXRlKHggPSAreCkgfHwgeCA9PSAwID8geCA6IHggPCAwID8gLWFzaW5oKC14KSA6IE1hdGgubG9nKHggKyBNYXRoLnNxcnQoeCAqIHggKyAxKSk7XG59XG5cbi8vIFRvciBCcm93c2VyIGJ1ZzogTWF0aC5hc2luaCgwKSAtPiAtMFxuJGV4cG9ydCgkZXhwb3J0LlMgKyAkZXhwb3J0LkYgKiAhKCRhc2luaCAmJiAxIC8gJGFzaW5oKDApID4gMCksICdNYXRoJywgeyBhc2luaDogYXNpbmggfSk7XG4iLCIvLyAyMC4yLjIuNyBNYXRoLmF0YW5oKHgpXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyICRhdGFuaCA9IE1hdGguYXRhbmg7XG5cbi8vIFRvciBCcm93c2VyIGJ1ZzogTWF0aC5hdGFuaCgtMCkgLT4gMFxuJGV4cG9ydCgkZXhwb3J0LlMgKyAkZXhwb3J0LkYgKiAhKCRhdGFuaCAmJiAxIC8gJGF0YW5oKC0wKSA8IDApLCAnTWF0aCcsIHtcbiAgYXRhbmg6IGZ1bmN0aW9uIGF0YW5oKHgpIHtcbiAgICByZXR1cm4gKHggPSAreCkgPT0gMCA/IHggOiBNYXRoLmxvZygoMSArIHgpIC8gKDEgLSB4KSkgLyAyO1xuICB9XG59KTtcbiIsIi8vIDIwLjIuMi45IE1hdGguY2JydCh4KVxudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciBzaWduID0gcmVxdWlyZSgnLi9fbWF0aC1zaWduJyk7XG5cbiRleHBvcnQoJGV4cG9ydC5TLCAnTWF0aCcsIHtcbiAgY2JydDogZnVuY3Rpb24gY2JydCh4KSB7XG4gICAgcmV0dXJuIHNpZ24oeCA9ICt4KSAqIE1hdGgucG93KE1hdGguYWJzKHgpLCAxIC8gMyk7XG4gIH1cbn0pO1xuIiwiLy8gMjAuMi4yLjExIE1hdGguY2x6MzIoeClcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG5cbiRleHBvcnQoJGV4cG9ydC5TLCAnTWF0aCcsIHtcbiAgY2x6MzI6IGZ1bmN0aW9uIGNsejMyKHgpIHtcbiAgICByZXR1cm4gKHggPj4+PSAwKSA/IDMxIC0gTWF0aC5mbG9vcihNYXRoLmxvZyh4ICsgMC41KSAqIE1hdGguTE9HMkUpIDogMzI7XG4gIH1cbn0pO1xuIiwiLy8gMjAuMi4yLjEyIE1hdGguY29zaCh4KVxudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciBleHAgPSBNYXRoLmV4cDtcblxuJGV4cG9ydCgkZXhwb3J0LlMsICdNYXRoJywge1xuICBjb3NoOiBmdW5jdGlvbiBjb3NoKHgpIHtcbiAgICByZXR1cm4gKGV4cCh4ID0gK3gpICsgZXhwKC14KSkgLyAyO1xuICB9XG59KTtcbiIsIi8vIDIwLjIuMi4xNCBNYXRoLmV4cG0xKHgpXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyICRleHBtMSA9IHJlcXVpcmUoJy4vX21hdGgtZXhwbTEnKTtcblxuJGV4cG9ydCgkZXhwb3J0LlMgKyAkZXhwb3J0LkYgKiAoJGV4cG0xICE9IE1hdGguZXhwbTEpLCAnTWF0aCcsIHsgZXhwbTE6ICRleHBtMSB9KTtcbiIsIi8vIDIwLjIuMi4xNiBNYXRoLmZyb3VuZCh4KVxudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcblxuJGV4cG9ydCgkZXhwb3J0LlMsICdNYXRoJywgeyBmcm91bmQ6IHJlcXVpcmUoJy4vX21hdGgtZnJvdW5kJykgfSk7XG4iLCIvLyAyMC4yLjIuMTcgTWF0aC5oeXBvdChbdmFsdWUxWywgdmFsdWUyWywg4oCmIF1dXSlcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgYWJzID0gTWF0aC5hYnM7XG5cbiRleHBvcnQoJGV4cG9ydC5TLCAnTWF0aCcsIHtcbiAgaHlwb3Q6IGZ1bmN0aW9uIGh5cG90KHZhbHVlMSwgdmFsdWUyKSB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tdW51c2VkLXZhcnNcbiAgICB2YXIgc3VtID0gMDtcbiAgICB2YXIgaSA9IDA7XG4gICAgdmFyIGFMZW4gPSBhcmd1bWVudHMubGVuZ3RoO1xuICAgIHZhciBsYXJnID0gMDtcbiAgICB2YXIgYXJnLCBkaXY7XG4gICAgd2hpbGUgKGkgPCBhTGVuKSB7XG4gICAgICBhcmcgPSBhYnMoYXJndW1lbnRzW2krK10pO1xuICAgICAgaWYgKGxhcmcgPCBhcmcpIHtcbiAgICAgICAgZGl2ID0gbGFyZyAvIGFyZztcbiAgICAgICAgc3VtID0gc3VtICogZGl2ICogZGl2ICsgMTtcbiAgICAgICAgbGFyZyA9IGFyZztcbiAgICAgIH0gZWxzZSBpZiAoYXJnID4gMCkge1xuICAgICAgICBkaXYgPSBhcmcgLyBsYXJnO1xuICAgICAgICBzdW0gKz0gZGl2ICogZGl2O1xuICAgICAgfSBlbHNlIHN1bSArPSBhcmc7XG4gICAgfVxuICAgIHJldHVybiBsYXJnID09PSBJbmZpbml0eSA/IEluZmluaXR5IDogbGFyZyAqIE1hdGguc3FydChzdW0pO1xuICB9XG59KTtcbiIsIi8vIDIwLjIuMi4xOCBNYXRoLmltdWwoeCwgeSlcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgJGltdWwgPSBNYXRoLmltdWw7XG5cbi8vIHNvbWUgV2ViS2l0IHZlcnNpb25zIGZhaWxzIHdpdGggYmlnIG51bWJlcnMsIHNvbWUgaGFzIHdyb25nIGFyaXR5XG4kZXhwb3J0KCRleHBvcnQuUyArICRleHBvcnQuRiAqIHJlcXVpcmUoJy4vX2ZhaWxzJykoZnVuY3Rpb24gKCkge1xuICByZXR1cm4gJGltdWwoMHhmZmZmZmZmZiwgNSkgIT0gLTUgfHwgJGltdWwubGVuZ3RoICE9IDI7XG59KSwgJ01hdGgnLCB7XG4gIGltdWw6IGZ1bmN0aW9uIGltdWwoeCwgeSkge1xuICAgIHZhciBVSU5UMTYgPSAweGZmZmY7XG4gICAgdmFyIHhuID0gK3g7XG4gICAgdmFyIHluID0gK3k7XG4gICAgdmFyIHhsID0gVUlOVDE2ICYgeG47XG4gICAgdmFyIHlsID0gVUlOVDE2ICYgeW47XG4gICAgcmV0dXJuIDAgfCB4bCAqIHlsICsgKChVSU5UMTYgJiB4biA+Pj4gMTYpICogeWwgKyB4bCAqIChVSU5UMTYgJiB5biA+Pj4gMTYpIDw8IDE2ID4+PiAwKTtcbiAgfVxufSk7XG4iLCIvLyAyMC4yLjIuMjEgTWF0aC5sb2cxMCh4KVxudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcblxuJGV4cG9ydCgkZXhwb3J0LlMsICdNYXRoJywge1xuICBsb2cxMDogZnVuY3Rpb24gbG9nMTAoeCkge1xuICAgIHJldHVybiBNYXRoLmxvZyh4KSAqIE1hdGguTE9HMTBFO1xuICB9XG59KTtcbiIsIi8vIDIwLjIuMi4yMCBNYXRoLmxvZzFwKHgpXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xuXG4kZXhwb3J0KCRleHBvcnQuUywgJ01hdGgnLCB7IGxvZzFwOiByZXF1aXJlKCcuL19tYXRoLWxvZzFwJykgfSk7XG4iLCIvLyAyMC4yLjIuMjIgTWF0aC5sb2cyKHgpXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xuXG4kZXhwb3J0KCRleHBvcnQuUywgJ01hdGgnLCB7XG4gIGxvZzI6IGZ1bmN0aW9uIGxvZzIoeCkge1xuICAgIHJldHVybiBNYXRoLmxvZyh4KSAvIE1hdGguTE4yO1xuICB9XG59KTtcbiIsIi8vIDIwLjIuMi4yOCBNYXRoLnNpZ24oeClcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG5cbiRleHBvcnQoJGV4cG9ydC5TLCAnTWF0aCcsIHsgc2lnbjogcmVxdWlyZSgnLi9fbWF0aC1zaWduJykgfSk7XG4iLCIvLyAyMC4yLjIuMzAgTWF0aC5zaW5oKHgpXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyIGV4cG0xID0gcmVxdWlyZSgnLi9fbWF0aC1leHBtMScpO1xudmFyIGV4cCA9IE1hdGguZXhwO1xuXG4vLyBWOCBuZWFyIENocm9taXVtIDM4IGhhcyBhIHByb2JsZW0gd2l0aCB2ZXJ5IHNtYWxsIG51bWJlcnNcbiRleHBvcnQoJGV4cG9ydC5TICsgJGV4cG9ydC5GICogcmVxdWlyZSgnLi9fZmFpbHMnKShmdW5jdGlvbiAoKSB7XG4gIHJldHVybiAhTWF0aC5zaW5oKC0yZS0xNykgIT0gLTJlLTE3O1xufSksICdNYXRoJywge1xuICBzaW5oOiBmdW5jdGlvbiBzaW5oKHgpIHtcbiAgICByZXR1cm4gTWF0aC5hYnMoeCA9ICt4KSA8IDFcbiAgICAgID8gKGV4cG0xKHgpIC0gZXhwbTEoLXgpKSAvIDJcbiAgICAgIDogKGV4cCh4IC0gMSkgLSBleHAoLXggLSAxKSkgKiAoTWF0aC5FIC8gMik7XG4gIH1cbn0pO1xuIiwiLy8gMjAuMi4yLjMzIE1hdGgudGFuaCh4KVxudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciBleHBtMSA9IHJlcXVpcmUoJy4vX21hdGgtZXhwbTEnKTtcbnZhciBleHAgPSBNYXRoLmV4cDtcblxuJGV4cG9ydCgkZXhwb3J0LlMsICdNYXRoJywge1xuICB0YW5oOiBmdW5jdGlvbiB0YW5oKHgpIHtcbiAgICB2YXIgYSA9IGV4cG0xKHggPSAreCk7XG4gICAgdmFyIGIgPSBleHBtMSgteCk7XG4gICAgcmV0dXJuIGEgPT0gSW5maW5pdHkgPyAxIDogYiA9PSBJbmZpbml0eSA/IC0xIDogKGEgLSBiKSAvIChleHAoeCkgKyBleHAoLXgpKTtcbiAgfVxufSk7XG4iLCIvLyAyMC4yLjIuMzQgTWF0aC50cnVuYyh4KVxudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcblxuJGV4cG9ydCgkZXhwb3J0LlMsICdNYXRoJywge1xuICB0cnVuYzogZnVuY3Rpb24gdHJ1bmMoaXQpIHtcbiAgICByZXR1cm4gKGl0ID4gMCA/IE1hdGguZmxvb3IgOiBNYXRoLmNlaWwpKGl0KTtcbiAgfVxufSk7XG4iLCIndXNlIHN0cmljdCc7XG52YXIgZ2xvYmFsID0gcmVxdWlyZSgnLi9fZ2xvYmFsJyk7XG52YXIgaGFzID0gcmVxdWlyZSgnLi9faGFzJyk7XG52YXIgY29mID0gcmVxdWlyZSgnLi9fY29mJyk7XG52YXIgaW5oZXJpdElmUmVxdWlyZWQgPSByZXF1aXJlKCcuL19pbmhlcml0LWlmLXJlcXVpcmVkJyk7XG52YXIgdG9QcmltaXRpdmUgPSByZXF1aXJlKCcuL190by1wcmltaXRpdmUnKTtcbnZhciBmYWlscyA9IHJlcXVpcmUoJy4vX2ZhaWxzJyk7XG52YXIgZ09QTiA9IHJlcXVpcmUoJy4vX29iamVjdC1nb3BuJykuZjtcbnZhciBnT1BEID0gcmVxdWlyZSgnLi9fb2JqZWN0LWdvcGQnKS5mO1xudmFyIGRQID0gcmVxdWlyZSgnLi9fb2JqZWN0LWRwJykuZjtcbnZhciAkdHJpbSA9IHJlcXVpcmUoJy4vX3N0cmluZy10cmltJykudHJpbTtcbnZhciBOVU1CRVIgPSAnTnVtYmVyJztcbnZhciAkTnVtYmVyID0gZ2xvYmFsW05VTUJFUl07XG52YXIgQmFzZSA9ICROdW1iZXI7XG52YXIgcHJvdG8gPSAkTnVtYmVyLnByb3RvdHlwZTtcbi8vIE9wZXJhIH4xMiBoYXMgYnJva2VuIE9iamVjdCN0b1N0cmluZ1xudmFyIEJST0tFTl9DT0YgPSBjb2YocmVxdWlyZSgnLi9fb2JqZWN0LWNyZWF0ZScpKHByb3RvKSkgPT0gTlVNQkVSO1xudmFyIFRSSU0gPSAndHJpbScgaW4gU3RyaW5nLnByb3RvdHlwZTtcblxuLy8gNy4xLjMgVG9OdW1iZXIoYXJndW1lbnQpXG52YXIgdG9OdW1iZXIgPSBmdW5jdGlvbiAoYXJndW1lbnQpIHtcbiAgdmFyIGl0ID0gdG9QcmltaXRpdmUoYXJndW1lbnQsIGZhbHNlKTtcbiAgaWYgKHR5cGVvZiBpdCA9PSAnc3RyaW5nJyAmJiBpdC5sZW5ndGggPiAyKSB7XG4gICAgaXQgPSBUUklNID8gaXQudHJpbSgpIDogJHRyaW0oaXQsIDMpO1xuICAgIHZhciBmaXJzdCA9IGl0LmNoYXJDb2RlQXQoMCk7XG4gICAgdmFyIHRoaXJkLCByYWRpeCwgbWF4Q29kZTtcbiAgICBpZiAoZmlyc3QgPT09IDQzIHx8IGZpcnN0ID09PSA0NSkge1xuICAgICAgdGhpcmQgPSBpdC5jaGFyQ29kZUF0KDIpO1xuICAgICAgaWYgKHRoaXJkID09PSA4OCB8fCB0aGlyZCA9PT0gMTIwKSByZXR1cm4gTmFOOyAvLyBOdW1iZXIoJysweDEnKSBzaG91bGQgYmUgTmFOLCBvbGQgVjggZml4XG4gICAgfSBlbHNlIGlmIChmaXJzdCA9PT0gNDgpIHtcbiAgICAgIHN3aXRjaCAoaXQuY2hhckNvZGVBdCgxKSkge1xuICAgICAgICBjYXNlIDY2OiBjYXNlIDk4OiByYWRpeCA9IDI7IG1heENvZGUgPSA0OTsgYnJlYWs7IC8vIGZhc3QgZXF1YWwgL14wYlswMV0rJC9pXG4gICAgICAgIGNhc2UgNzk6IGNhc2UgMTExOiByYWRpeCA9IDg7IG1heENvZGUgPSA1NTsgYnJlYWs7IC8vIGZhc3QgZXF1YWwgL14wb1swLTddKyQvaVxuICAgICAgICBkZWZhdWx0OiByZXR1cm4gK2l0O1xuICAgICAgfVxuICAgICAgZm9yICh2YXIgZGlnaXRzID0gaXQuc2xpY2UoMiksIGkgPSAwLCBsID0gZGlnaXRzLmxlbmd0aCwgY29kZTsgaSA8IGw7IGkrKykge1xuICAgICAgICBjb2RlID0gZGlnaXRzLmNoYXJDb2RlQXQoaSk7XG4gICAgICAgIC8vIHBhcnNlSW50IHBhcnNlcyBhIHN0cmluZyB0byBhIGZpcnN0IHVuYXZhaWxhYmxlIHN5bWJvbFxuICAgICAgICAvLyBidXQgVG9OdW1iZXIgc2hvdWxkIHJldHVybiBOYU4gaWYgYSBzdHJpbmcgY29udGFpbnMgdW5hdmFpbGFibGUgc3ltYm9sc1xuICAgICAgICBpZiAoY29kZSA8IDQ4IHx8IGNvZGUgPiBtYXhDb2RlKSByZXR1cm4gTmFOO1xuICAgICAgfSByZXR1cm4gcGFyc2VJbnQoZGlnaXRzLCByYWRpeCk7XG4gICAgfVxuICB9IHJldHVybiAraXQ7XG59O1xuXG5pZiAoISROdW1iZXIoJyAwbzEnKSB8fCAhJE51bWJlcignMGIxJykgfHwgJE51bWJlcignKzB4MScpKSB7XG4gICROdW1iZXIgPSBmdW5jdGlvbiBOdW1iZXIodmFsdWUpIHtcbiAgICB2YXIgaXQgPSBhcmd1bWVudHMubGVuZ3RoIDwgMSA/IDAgOiB2YWx1ZTtcbiAgICB2YXIgdGhhdCA9IHRoaXM7XG4gICAgcmV0dXJuIHRoYXQgaW5zdGFuY2VvZiAkTnVtYmVyXG4gICAgICAvLyBjaGVjayBvbiAxLi5jb25zdHJ1Y3Rvcihmb28pIGNhc2VcbiAgICAgICYmIChCUk9LRU5fQ09GID8gZmFpbHMoZnVuY3Rpb24gKCkgeyBwcm90by52YWx1ZU9mLmNhbGwodGhhdCk7IH0pIDogY29mKHRoYXQpICE9IE5VTUJFUilcbiAgICAgICAgPyBpbmhlcml0SWZSZXF1aXJlZChuZXcgQmFzZSh0b051bWJlcihpdCkpLCB0aGF0LCAkTnVtYmVyKSA6IHRvTnVtYmVyKGl0KTtcbiAgfTtcbiAgZm9yICh2YXIga2V5cyA9IHJlcXVpcmUoJy4vX2Rlc2NyaXB0b3JzJykgPyBnT1BOKEJhc2UpIDogKFxuICAgIC8vIEVTMzpcbiAgICAnTUFYX1ZBTFVFLE1JTl9WQUxVRSxOYU4sTkVHQVRJVkVfSU5GSU5JVFksUE9TSVRJVkVfSU5GSU5JVFksJyArXG4gICAgLy8gRVM2IChpbiBjYXNlLCBpZiBtb2R1bGVzIHdpdGggRVM2IE51bWJlciBzdGF0aWNzIHJlcXVpcmVkIGJlZm9yZSk6XG4gICAgJ0VQU0lMT04saXNGaW5pdGUsaXNJbnRlZ2VyLGlzTmFOLGlzU2FmZUludGVnZXIsTUFYX1NBRkVfSU5URUdFUiwnICtcbiAgICAnTUlOX1NBRkVfSU5URUdFUixwYXJzZUZsb2F0LHBhcnNlSW50LGlzSW50ZWdlcidcbiAgKS5zcGxpdCgnLCcpLCBqID0gMCwga2V5OyBrZXlzLmxlbmd0aCA+IGo7IGorKykge1xuICAgIGlmIChoYXMoQmFzZSwga2V5ID0ga2V5c1tqXSkgJiYgIWhhcygkTnVtYmVyLCBrZXkpKSB7XG4gICAgICBkUCgkTnVtYmVyLCBrZXksIGdPUEQoQmFzZSwga2V5KSk7XG4gICAgfVxuICB9XG4gICROdW1iZXIucHJvdG90eXBlID0gcHJvdG87XG4gIHByb3RvLmNvbnN0cnVjdG9yID0gJE51bWJlcjtcbiAgcmVxdWlyZSgnLi9fcmVkZWZpbmUnKShnbG9iYWwsIE5VTUJFUiwgJE51bWJlcik7XG59XG4iLCIvLyAyMC4xLjIuMSBOdW1iZXIuRVBTSUxPTlxudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcblxuJGV4cG9ydCgkZXhwb3J0LlMsICdOdW1iZXInLCB7IEVQU0lMT046IE1hdGgucG93KDIsIC01MikgfSk7XG4iLCIvLyAyMC4xLjIuMiBOdW1iZXIuaXNGaW5pdGUobnVtYmVyKVxudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciBfaXNGaW5pdGUgPSByZXF1aXJlKCcuL19nbG9iYWwnKS5pc0Zpbml0ZTtcblxuJGV4cG9ydCgkZXhwb3J0LlMsICdOdW1iZXInLCB7XG4gIGlzRmluaXRlOiBmdW5jdGlvbiBpc0Zpbml0ZShpdCkge1xuICAgIHJldHVybiB0eXBlb2YgaXQgPT0gJ251bWJlcicgJiYgX2lzRmluaXRlKGl0KTtcbiAgfVxufSk7XG4iLCIvLyAyMC4xLjIuMyBOdW1iZXIuaXNJbnRlZ2VyKG51bWJlcilcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG5cbiRleHBvcnQoJGV4cG9ydC5TLCAnTnVtYmVyJywgeyBpc0ludGVnZXI6IHJlcXVpcmUoJy4vX2lzLWludGVnZXInKSB9KTtcbiIsIi8vIDIwLjEuMi40IE51bWJlci5pc05hTihudW1iZXIpXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xuXG4kZXhwb3J0KCRleHBvcnQuUywgJ051bWJlcicsIHtcbiAgaXNOYU46IGZ1bmN0aW9uIGlzTmFOKG51bWJlcikge1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1zZWxmLWNvbXBhcmVcbiAgICByZXR1cm4gbnVtYmVyICE9IG51bWJlcjtcbiAgfVxufSk7XG4iLCIvLyAyMC4xLjIuNSBOdW1iZXIuaXNTYWZlSW50ZWdlcihudW1iZXIpXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyIGlzSW50ZWdlciA9IHJlcXVpcmUoJy4vX2lzLWludGVnZXInKTtcbnZhciBhYnMgPSBNYXRoLmFicztcblxuJGV4cG9ydCgkZXhwb3J0LlMsICdOdW1iZXInLCB7XG4gIGlzU2FmZUludGVnZXI6IGZ1bmN0aW9uIGlzU2FmZUludGVnZXIobnVtYmVyKSB7XG4gICAgcmV0dXJuIGlzSW50ZWdlcihudW1iZXIpICYmIGFicyhudW1iZXIpIDw9IDB4MWZmZmZmZmZmZmZmZmY7XG4gIH1cbn0pO1xuIiwiLy8gMjAuMS4yLjYgTnVtYmVyLk1BWF9TQUZFX0lOVEVHRVJcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG5cbiRleHBvcnQoJGV4cG9ydC5TLCAnTnVtYmVyJywgeyBNQVhfU0FGRV9JTlRFR0VSOiAweDFmZmZmZmZmZmZmZmZmIH0pO1xuIiwiLy8gMjAuMS4yLjEwIE51bWJlci5NSU5fU0FGRV9JTlRFR0VSXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xuXG4kZXhwb3J0KCRleHBvcnQuUywgJ051bWJlcicsIHsgTUlOX1NBRkVfSU5URUdFUjogLTB4MWZmZmZmZmZmZmZmZmYgfSk7XG4iLCJ2YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyICRwYXJzZUZsb2F0ID0gcmVxdWlyZSgnLi9fcGFyc2UtZmxvYXQnKTtcbi8vIDIwLjEuMi4xMiBOdW1iZXIucGFyc2VGbG9hdChzdHJpbmcpXG4kZXhwb3J0KCRleHBvcnQuUyArICRleHBvcnQuRiAqIChOdW1iZXIucGFyc2VGbG9hdCAhPSAkcGFyc2VGbG9hdCksICdOdW1iZXInLCB7IHBhcnNlRmxvYXQ6ICRwYXJzZUZsb2F0IH0pO1xuIiwidmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciAkcGFyc2VJbnQgPSByZXF1aXJlKCcuL19wYXJzZS1pbnQnKTtcbi8vIDIwLjEuMi4xMyBOdW1iZXIucGFyc2VJbnQoc3RyaW5nLCByYWRpeClcbiRleHBvcnQoJGV4cG9ydC5TICsgJGV4cG9ydC5GICogKE51bWJlci5wYXJzZUludCAhPSAkcGFyc2VJbnQpLCAnTnVtYmVyJywgeyBwYXJzZUludDogJHBhcnNlSW50IH0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciB0b0ludGVnZXIgPSByZXF1aXJlKCcuL190by1pbnRlZ2VyJyk7XG52YXIgYU51bWJlclZhbHVlID0gcmVxdWlyZSgnLi9fYS1udW1iZXItdmFsdWUnKTtcbnZhciByZXBlYXQgPSByZXF1aXJlKCcuL19zdHJpbmctcmVwZWF0Jyk7XG52YXIgJHRvRml4ZWQgPSAxLjAudG9GaXhlZDtcbnZhciBmbG9vciA9IE1hdGguZmxvb3I7XG52YXIgZGF0YSA9IFswLCAwLCAwLCAwLCAwLCAwXTtcbnZhciBFUlJPUiA9ICdOdW1iZXIudG9GaXhlZDogaW5jb3JyZWN0IGludm9jYXRpb24hJztcbnZhciBaRVJPID0gJzAnO1xuXG52YXIgbXVsdGlwbHkgPSBmdW5jdGlvbiAobiwgYykge1xuICB2YXIgaSA9IC0xO1xuICB2YXIgYzIgPSBjO1xuICB3aGlsZSAoKytpIDwgNikge1xuICAgIGMyICs9IG4gKiBkYXRhW2ldO1xuICAgIGRhdGFbaV0gPSBjMiAlIDFlNztcbiAgICBjMiA9IGZsb29yKGMyIC8gMWU3KTtcbiAgfVxufTtcbnZhciBkaXZpZGUgPSBmdW5jdGlvbiAobikge1xuICB2YXIgaSA9IDY7XG4gIHZhciBjID0gMDtcbiAgd2hpbGUgKC0taSA+PSAwKSB7XG4gICAgYyArPSBkYXRhW2ldO1xuICAgIGRhdGFbaV0gPSBmbG9vcihjIC8gbik7XG4gICAgYyA9IChjICUgbikgKiAxZTc7XG4gIH1cbn07XG52YXIgbnVtVG9TdHJpbmcgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBpID0gNjtcbiAgdmFyIHMgPSAnJztcbiAgd2hpbGUgKC0taSA+PSAwKSB7XG4gICAgaWYgKHMgIT09ICcnIHx8IGkgPT09IDAgfHwgZGF0YVtpXSAhPT0gMCkge1xuICAgICAgdmFyIHQgPSBTdHJpbmcoZGF0YVtpXSk7XG4gICAgICBzID0gcyA9PT0gJycgPyB0IDogcyArIHJlcGVhdC5jYWxsKFpFUk8sIDcgLSB0Lmxlbmd0aCkgKyB0O1xuICAgIH1cbiAgfSByZXR1cm4gcztcbn07XG52YXIgcG93ID0gZnVuY3Rpb24gKHgsIG4sIGFjYykge1xuICByZXR1cm4gbiA9PT0gMCA/IGFjYyA6IG4gJSAyID09PSAxID8gcG93KHgsIG4gLSAxLCBhY2MgKiB4KSA6IHBvdyh4ICogeCwgbiAvIDIsIGFjYyk7XG59O1xudmFyIGxvZyA9IGZ1bmN0aW9uICh4KSB7XG4gIHZhciBuID0gMDtcbiAgdmFyIHgyID0geDtcbiAgd2hpbGUgKHgyID49IDQwOTYpIHtcbiAgICBuICs9IDEyO1xuICAgIHgyIC89IDQwOTY7XG4gIH1cbiAgd2hpbGUgKHgyID49IDIpIHtcbiAgICBuICs9IDE7XG4gICAgeDIgLz0gMjtcbiAgfSByZXR1cm4gbjtcbn07XG5cbiRleHBvcnQoJGV4cG9ydC5QICsgJGV4cG9ydC5GICogKCEhJHRvRml4ZWQgJiYgKFxuICAwLjAwMDA4LnRvRml4ZWQoMykgIT09ICcwLjAwMCcgfHxcbiAgMC45LnRvRml4ZWQoMCkgIT09ICcxJyB8fFxuICAxLjI1NS50b0ZpeGVkKDIpICE9PSAnMS4yNScgfHxcbiAgMTAwMDAwMDAwMDAwMDAwMDEyOC4wLnRvRml4ZWQoMCkgIT09ICcxMDAwMDAwMDAwMDAwMDAwMTI4J1xuKSB8fCAhcmVxdWlyZSgnLi9fZmFpbHMnKShmdW5jdGlvbiAoKSB7XG4gIC8vIFY4IH4gQW5kcm9pZCA0LjMtXG4gICR0b0ZpeGVkLmNhbGwoe30pO1xufSkpLCAnTnVtYmVyJywge1xuICB0b0ZpeGVkOiBmdW5jdGlvbiB0b0ZpeGVkKGZyYWN0aW9uRGlnaXRzKSB7XG4gICAgdmFyIHggPSBhTnVtYmVyVmFsdWUodGhpcywgRVJST1IpO1xuICAgIHZhciBmID0gdG9JbnRlZ2VyKGZyYWN0aW9uRGlnaXRzKTtcbiAgICB2YXIgcyA9ICcnO1xuICAgIHZhciBtID0gWkVSTztcbiAgICB2YXIgZSwgeiwgaiwgaztcbiAgICBpZiAoZiA8IDAgfHwgZiA+IDIwKSB0aHJvdyBSYW5nZUVycm9yKEVSUk9SKTtcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tc2VsZi1jb21wYXJlXG4gICAgaWYgKHggIT0geCkgcmV0dXJuICdOYU4nO1xuICAgIGlmICh4IDw9IC0xZTIxIHx8IHggPj0gMWUyMSkgcmV0dXJuIFN0cmluZyh4KTtcbiAgICBpZiAoeCA8IDApIHtcbiAgICAgIHMgPSAnLSc7XG4gICAgICB4ID0gLXg7XG4gICAgfVxuICAgIGlmICh4ID4gMWUtMjEpIHtcbiAgICAgIGUgPSBsb2coeCAqIHBvdygyLCA2OSwgMSkpIC0gNjk7XG4gICAgICB6ID0gZSA8IDAgPyB4ICogcG93KDIsIC1lLCAxKSA6IHggLyBwb3coMiwgZSwgMSk7XG4gICAgICB6ICo9IDB4MTAwMDAwMDAwMDAwMDA7XG4gICAgICBlID0gNTIgLSBlO1xuICAgICAgaWYgKGUgPiAwKSB7XG4gICAgICAgIG11bHRpcGx5KDAsIHopO1xuICAgICAgICBqID0gZjtcbiAgICAgICAgd2hpbGUgKGogPj0gNykge1xuICAgICAgICAgIG11bHRpcGx5KDFlNywgMCk7XG4gICAgICAgICAgaiAtPSA3O1xuICAgICAgICB9XG4gICAgICAgIG11bHRpcGx5KHBvdygxMCwgaiwgMSksIDApO1xuICAgICAgICBqID0gZSAtIDE7XG4gICAgICAgIHdoaWxlIChqID49IDIzKSB7XG4gICAgICAgICAgZGl2aWRlKDEgPDwgMjMpO1xuICAgICAgICAgIGogLT0gMjM7XG4gICAgICAgIH1cbiAgICAgICAgZGl2aWRlKDEgPDwgaik7XG4gICAgICAgIG11bHRpcGx5KDEsIDEpO1xuICAgICAgICBkaXZpZGUoMik7XG4gICAgICAgIG0gPSBudW1Ub1N0cmluZygpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbXVsdGlwbHkoMCwgeik7XG4gICAgICAgIG11bHRpcGx5KDEgPDwgLWUsIDApO1xuICAgICAgICBtID0gbnVtVG9TdHJpbmcoKSArIHJlcGVhdC5jYWxsKFpFUk8sIGYpO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAoZiA+IDApIHtcbiAgICAgIGsgPSBtLmxlbmd0aDtcbiAgICAgIG0gPSBzICsgKGsgPD0gZiA/ICcwLicgKyByZXBlYXQuY2FsbChaRVJPLCBmIC0gaykgKyBtIDogbS5zbGljZSgwLCBrIC0gZikgKyAnLicgKyBtLnNsaWNlKGsgLSBmKSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIG0gPSBzICsgbTtcbiAgICB9IHJldHVybiBtO1xuICB9XG59KTtcbiIsIid1c2Ugc3RyaWN0JztcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgJGZhaWxzID0gcmVxdWlyZSgnLi9fZmFpbHMnKTtcbnZhciBhTnVtYmVyVmFsdWUgPSByZXF1aXJlKCcuL19hLW51bWJlci12YWx1ZScpO1xudmFyICR0b1ByZWNpc2lvbiA9IDEuMC50b1ByZWNpc2lvbjtcblxuJGV4cG9ydCgkZXhwb3J0LlAgKyAkZXhwb3J0LkYgKiAoJGZhaWxzKGZ1bmN0aW9uICgpIHtcbiAgLy8gSUU3LVxuICByZXR1cm4gJHRvUHJlY2lzaW9uLmNhbGwoMSwgdW5kZWZpbmVkKSAhPT0gJzEnO1xufSkgfHwgISRmYWlscyhmdW5jdGlvbiAoKSB7XG4gIC8vIFY4IH4gQW5kcm9pZCA0LjMtXG4gICR0b1ByZWNpc2lvbi5jYWxsKHt9KTtcbn0pKSwgJ051bWJlcicsIHtcbiAgdG9QcmVjaXNpb246IGZ1bmN0aW9uIHRvUHJlY2lzaW9uKHByZWNpc2lvbikge1xuICAgIHZhciB0aGF0ID0gYU51bWJlclZhbHVlKHRoaXMsICdOdW1iZXIjdG9QcmVjaXNpb246IGluY29ycmVjdCBpbnZvY2F0aW9uIScpO1xuICAgIHJldHVybiBwcmVjaXNpb24gPT09IHVuZGVmaW5lZCA/ICR0b1ByZWNpc2lvbi5jYWxsKHRoYXQpIDogJHRvUHJlY2lzaW9uLmNhbGwodGhhdCwgcHJlY2lzaW9uKTtcbiAgfVxufSk7XG4iLCIvLyAxOS4xLjMuMSBPYmplY3QuYXNzaWduKHRhcmdldCwgc291cmNlKVxudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcblxuJGV4cG9ydCgkZXhwb3J0LlMgKyAkZXhwb3J0LkYsICdPYmplY3QnLCB7IGFzc2lnbjogcmVxdWlyZSgnLi9fb2JqZWN0LWFzc2lnbicpIH0pO1xuIiwidmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbi8vIDE5LjEuMi4yIC8gMTUuMi4zLjUgT2JqZWN0LmNyZWF0ZShPIFssIFByb3BlcnRpZXNdKVxuJGV4cG9ydCgkZXhwb3J0LlMsICdPYmplY3QnLCB7IGNyZWF0ZTogcmVxdWlyZSgnLi9fb2JqZWN0LWNyZWF0ZScpIH0pO1xuIiwidmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbi8vIDE5LjEuMi4zIC8gMTUuMi4zLjcgT2JqZWN0LmRlZmluZVByb3BlcnRpZXMoTywgUHJvcGVydGllcylcbiRleHBvcnQoJGV4cG9ydC5TICsgJGV4cG9ydC5GICogIXJlcXVpcmUoJy4vX2Rlc2NyaXB0b3JzJyksICdPYmplY3QnLCB7IGRlZmluZVByb3BlcnRpZXM6IHJlcXVpcmUoJy4vX29iamVjdC1kcHMnKSB9KTtcbiIsInZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG4vLyAxOS4xLjIuNCAvIDE1LjIuMy42IE9iamVjdC5kZWZpbmVQcm9wZXJ0eShPLCBQLCBBdHRyaWJ1dGVzKVxuJGV4cG9ydCgkZXhwb3J0LlMgKyAkZXhwb3J0LkYgKiAhcmVxdWlyZSgnLi9fZGVzY3JpcHRvcnMnKSwgJ09iamVjdCcsIHsgZGVmaW5lUHJvcGVydHk6IHJlcXVpcmUoJy4vX29iamVjdC1kcCcpLmYgfSk7XG4iLCIvLyAxOS4xLjIuNSBPYmplY3QuZnJlZXplKE8pXG52YXIgaXNPYmplY3QgPSByZXF1aXJlKCcuL19pcy1vYmplY3QnKTtcbnZhciBtZXRhID0gcmVxdWlyZSgnLi9fbWV0YScpLm9uRnJlZXplO1xuXG5yZXF1aXJlKCcuL19vYmplY3Qtc2FwJykoJ2ZyZWV6ZScsIGZ1bmN0aW9uICgkZnJlZXplKSB7XG4gIHJldHVybiBmdW5jdGlvbiBmcmVlemUoaXQpIHtcbiAgICByZXR1cm4gJGZyZWV6ZSAmJiBpc09iamVjdChpdCkgPyAkZnJlZXplKG1ldGEoaXQpKSA6IGl0O1xuICB9O1xufSk7XG4iLCIvLyAxOS4xLjIuNiBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKE8sIFApXG52YXIgdG9JT2JqZWN0ID0gcmVxdWlyZSgnLi9fdG8taW9iamVjdCcpO1xudmFyICRnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IgPSByZXF1aXJlKCcuL19vYmplY3QtZ29wZCcpLmY7XG5cbnJlcXVpcmUoJy4vX29iamVjdC1zYXAnKSgnZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yJywgZnVuY3Rpb24gKCkge1xuICByZXR1cm4gZnVuY3Rpb24gZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKGl0LCBrZXkpIHtcbiAgICByZXR1cm4gJGdldE93blByb3BlcnR5RGVzY3JpcHRvcih0b0lPYmplY3QoaXQpLCBrZXkpO1xuICB9O1xufSk7XG4iLCIvLyAxOS4xLjIuNyBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyhPKVxucmVxdWlyZSgnLi9fb2JqZWN0LXNhcCcpKCdnZXRPd25Qcm9wZXJ0eU5hbWVzJywgZnVuY3Rpb24gKCkge1xuICByZXR1cm4gcmVxdWlyZSgnLi9fb2JqZWN0LWdvcG4tZXh0JykuZjtcbn0pO1xuIiwiLy8gMTkuMS4yLjkgT2JqZWN0LmdldFByb3RvdHlwZU9mKE8pXG52YXIgdG9PYmplY3QgPSByZXF1aXJlKCcuL190by1vYmplY3QnKTtcbnZhciAkZ2V0UHJvdG90eXBlT2YgPSByZXF1aXJlKCcuL19vYmplY3QtZ3BvJyk7XG5cbnJlcXVpcmUoJy4vX29iamVjdC1zYXAnKSgnZ2V0UHJvdG90eXBlT2YnLCBmdW5jdGlvbiAoKSB7XG4gIHJldHVybiBmdW5jdGlvbiBnZXRQcm90b3R5cGVPZihpdCkge1xuICAgIHJldHVybiAkZ2V0UHJvdG90eXBlT2YodG9PYmplY3QoaXQpKTtcbiAgfTtcbn0pO1xuIiwiLy8gMTkuMS4yLjExIE9iamVjdC5pc0V4dGVuc2libGUoTylcbnZhciBpc09iamVjdCA9IHJlcXVpcmUoJy4vX2lzLW9iamVjdCcpO1xuXG5yZXF1aXJlKCcuL19vYmplY3Qtc2FwJykoJ2lzRXh0ZW5zaWJsZScsIGZ1bmN0aW9uICgkaXNFeHRlbnNpYmxlKSB7XG4gIHJldHVybiBmdW5jdGlvbiBpc0V4dGVuc2libGUoaXQpIHtcbiAgICByZXR1cm4gaXNPYmplY3QoaXQpID8gJGlzRXh0ZW5zaWJsZSA/ICRpc0V4dGVuc2libGUoaXQpIDogdHJ1ZSA6IGZhbHNlO1xuICB9O1xufSk7XG4iLCIvLyAxOS4xLjIuMTIgT2JqZWN0LmlzRnJvemVuKE8pXG52YXIgaXNPYmplY3QgPSByZXF1aXJlKCcuL19pcy1vYmplY3QnKTtcblxucmVxdWlyZSgnLi9fb2JqZWN0LXNhcCcpKCdpc0Zyb3plbicsIGZ1bmN0aW9uICgkaXNGcm96ZW4pIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIGlzRnJvemVuKGl0KSB7XG4gICAgcmV0dXJuIGlzT2JqZWN0KGl0KSA/ICRpc0Zyb3plbiA/ICRpc0Zyb3plbihpdCkgOiBmYWxzZSA6IHRydWU7XG4gIH07XG59KTtcbiIsIi8vIDE5LjEuMi4xMyBPYmplY3QuaXNTZWFsZWQoTylcbnZhciBpc09iamVjdCA9IHJlcXVpcmUoJy4vX2lzLW9iamVjdCcpO1xuXG5yZXF1aXJlKCcuL19vYmplY3Qtc2FwJykoJ2lzU2VhbGVkJywgZnVuY3Rpb24gKCRpc1NlYWxlZCkge1xuICByZXR1cm4gZnVuY3Rpb24gaXNTZWFsZWQoaXQpIHtcbiAgICByZXR1cm4gaXNPYmplY3QoaXQpID8gJGlzU2VhbGVkID8gJGlzU2VhbGVkKGl0KSA6IGZhbHNlIDogdHJ1ZTtcbiAgfTtcbn0pO1xuIiwiLy8gMTkuMS4zLjEwIE9iamVjdC5pcyh2YWx1ZTEsIHZhbHVlMilcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG4kZXhwb3J0KCRleHBvcnQuUywgJ09iamVjdCcsIHsgaXM6IHJlcXVpcmUoJy4vX3NhbWUtdmFsdWUnKSB9KTtcbiIsIi8vIDE5LjEuMi4xNCBPYmplY3Qua2V5cyhPKVxudmFyIHRvT2JqZWN0ID0gcmVxdWlyZSgnLi9fdG8tb2JqZWN0Jyk7XG52YXIgJGtleXMgPSByZXF1aXJlKCcuL19vYmplY3Qta2V5cycpO1xuXG5yZXF1aXJlKCcuL19vYmplY3Qtc2FwJykoJ2tleXMnLCBmdW5jdGlvbiAoKSB7XG4gIHJldHVybiBmdW5jdGlvbiBrZXlzKGl0KSB7XG4gICAgcmV0dXJuICRrZXlzKHRvT2JqZWN0KGl0KSk7XG4gIH07XG59KTtcbiIsIi8vIDE5LjEuMi4xNSBPYmplY3QucHJldmVudEV4dGVuc2lvbnMoTylcbnZhciBpc09iamVjdCA9IHJlcXVpcmUoJy4vX2lzLW9iamVjdCcpO1xudmFyIG1ldGEgPSByZXF1aXJlKCcuL19tZXRhJykub25GcmVlemU7XG5cbnJlcXVpcmUoJy4vX29iamVjdC1zYXAnKSgncHJldmVudEV4dGVuc2lvbnMnLCBmdW5jdGlvbiAoJHByZXZlbnRFeHRlbnNpb25zKSB7XG4gIHJldHVybiBmdW5jdGlvbiBwcmV2ZW50RXh0ZW5zaW9ucyhpdCkge1xuICAgIHJldHVybiAkcHJldmVudEV4dGVuc2lvbnMgJiYgaXNPYmplY3QoaXQpID8gJHByZXZlbnRFeHRlbnNpb25zKG1ldGEoaXQpKSA6IGl0O1xuICB9O1xufSk7XG4iLCIvLyAxOS4xLjIuMTcgT2JqZWN0LnNlYWwoTylcbnZhciBpc09iamVjdCA9IHJlcXVpcmUoJy4vX2lzLW9iamVjdCcpO1xudmFyIG1ldGEgPSByZXF1aXJlKCcuL19tZXRhJykub25GcmVlemU7XG5cbnJlcXVpcmUoJy4vX29iamVjdC1zYXAnKSgnc2VhbCcsIGZ1bmN0aW9uICgkc2VhbCkge1xuICByZXR1cm4gZnVuY3Rpb24gc2VhbChpdCkge1xuICAgIHJldHVybiAkc2VhbCAmJiBpc09iamVjdChpdCkgPyAkc2VhbChtZXRhKGl0KSkgOiBpdDtcbiAgfTtcbn0pO1xuIiwiLy8gMTkuMS4zLjE5IE9iamVjdC5zZXRQcm90b3R5cGVPZihPLCBwcm90bylcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG4kZXhwb3J0KCRleHBvcnQuUywgJ09iamVjdCcsIHsgc2V0UHJvdG90eXBlT2Y6IHJlcXVpcmUoJy4vX3NldC1wcm90bycpLnNldCB9KTtcbiIsIid1c2Ugc3RyaWN0Jztcbi8vIDE5LjEuMy42IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcoKVxudmFyIGNsYXNzb2YgPSByZXF1aXJlKCcuL19jbGFzc29mJyk7XG52YXIgdGVzdCA9IHt9O1xudGVzdFtyZXF1aXJlKCcuL193a3MnKSgndG9TdHJpbmdUYWcnKV0gPSAneic7XG5pZiAodGVzdCArICcnICE9ICdbb2JqZWN0IHpdJykge1xuICByZXF1aXJlKCcuL19yZWRlZmluZScpKE9iamVjdC5wcm90b3R5cGUsICd0b1N0cmluZycsIGZ1bmN0aW9uIHRvU3RyaW5nKCkge1xuICAgIHJldHVybiAnW29iamVjdCAnICsgY2xhc3NvZih0aGlzKSArICddJztcbiAgfSwgdHJ1ZSk7XG59XG4iLCJ2YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyICRwYXJzZUZsb2F0ID0gcmVxdWlyZSgnLi9fcGFyc2UtZmxvYXQnKTtcbi8vIDE4LjIuNCBwYXJzZUZsb2F0KHN0cmluZylcbiRleHBvcnQoJGV4cG9ydC5HICsgJGV4cG9ydC5GICogKHBhcnNlRmxvYXQgIT0gJHBhcnNlRmxvYXQpLCB7IHBhcnNlRmxvYXQ6ICRwYXJzZUZsb2F0IH0pO1xuIiwidmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciAkcGFyc2VJbnQgPSByZXF1aXJlKCcuL19wYXJzZS1pbnQnKTtcbi8vIDE4LjIuNSBwYXJzZUludChzdHJpbmcsIHJhZGl4KVxuJGV4cG9ydCgkZXhwb3J0LkcgKyAkZXhwb3J0LkYgKiAocGFyc2VJbnQgIT0gJHBhcnNlSW50KSwgeyBwYXJzZUludDogJHBhcnNlSW50IH0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xudmFyIExJQlJBUlkgPSByZXF1aXJlKCcuL19saWJyYXJ5Jyk7XG52YXIgZ2xvYmFsID0gcmVxdWlyZSgnLi9fZ2xvYmFsJyk7XG52YXIgY3R4ID0gcmVxdWlyZSgnLi9fY3R4Jyk7XG52YXIgY2xhc3NvZiA9IHJlcXVpcmUoJy4vX2NsYXNzb2YnKTtcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgaXNPYmplY3QgPSByZXF1aXJlKCcuL19pcy1vYmplY3QnKTtcbnZhciBhRnVuY3Rpb24gPSByZXF1aXJlKCcuL19hLWZ1bmN0aW9uJyk7XG52YXIgYW5JbnN0YW5jZSA9IHJlcXVpcmUoJy4vX2FuLWluc3RhbmNlJyk7XG52YXIgZm9yT2YgPSByZXF1aXJlKCcuL19mb3Itb2YnKTtcbnZhciBzcGVjaWVzQ29uc3RydWN0b3IgPSByZXF1aXJlKCcuL19zcGVjaWVzLWNvbnN0cnVjdG9yJyk7XG52YXIgdGFzayA9IHJlcXVpcmUoJy4vX3Rhc2snKS5zZXQ7XG52YXIgbWljcm90YXNrID0gcmVxdWlyZSgnLi9fbWljcm90YXNrJykoKTtcbnZhciBuZXdQcm9taXNlQ2FwYWJpbGl0eU1vZHVsZSA9IHJlcXVpcmUoJy4vX25ldy1wcm9taXNlLWNhcGFiaWxpdHknKTtcbnZhciBwZXJmb3JtID0gcmVxdWlyZSgnLi9fcGVyZm9ybScpO1xudmFyIHVzZXJBZ2VudCA9IHJlcXVpcmUoJy4vX3VzZXItYWdlbnQnKTtcbnZhciBwcm9taXNlUmVzb2x2ZSA9IHJlcXVpcmUoJy4vX3Byb21pc2UtcmVzb2x2ZScpO1xudmFyIFBST01JU0UgPSAnUHJvbWlzZSc7XG52YXIgVHlwZUVycm9yID0gZ2xvYmFsLlR5cGVFcnJvcjtcbnZhciBwcm9jZXNzID0gZ2xvYmFsLnByb2Nlc3M7XG52YXIgdmVyc2lvbnMgPSBwcm9jZXNzICYmIHByb2Nlc3MudmVyc2lvbnM7XG52YXIgdjggPSB2ZXJzaW9ucyAmJiB2ZXJzaW9ucy52OCB8fCAnJztcbnZhciAkUHJvbWlzZSA9IGdsb2JhbFtQUk9NSVNFXTtcbnZhciBpc05vZGUgPSBjbGFzc29mKHByb2Nlc3MpID09ICdwcm9jZXNzJztcbnZhciBlbXB0eSA9IGZ1bmN0aW9uICgpIHsgLyogZW1wdHkgKi8gfTtcbnZhciBJbnRlcm5hbCwgbmV3R2VuZXJpY1Byb21pc2VDYXBhYmlsaXR5LCBPd25Qcm9taXNlQ2FwYWJpbGl0eSwgV3JhcHBlcjtcbnZhciBuZXdQcm9taXNlQ2FwYWJpbGl0eSA9IG5ld0dlbmVyaWNQcm9taXNlQ2FwYWJpbGl0eSA9IG5ld1Byb21pc2VDYXBhYmlsaXR5TW9kdWxlLmY7XG5cbnZhciBVU0VfTkFUSVZFID0gISFmdW5jdGlvbiAoKSB7XG4gIHRyeSB7XG4gICAgLy8gY29ycmVjdCBzdWJjbGFzc2luZyB3aXRoIEBAc3BlY2llcyBzdXBwb3J0XG4gICAgdmFyIHByb21pc2UgPSAkUHJvbWlzZS5yZXNvbHZlKDEpO1xuICAgIHZhciBGYWtlUHJvbWlzZSA9IChwcm9taXNlLmNvbnN0cnVjdG9yID0ge30pW3JlcXVpcmUoJy4vX3drcycpKCdzcGVjaWVzJyldID0gZnVuY3Rpb24gKGV4ZWMpIHtcbiAgICAgIGV4ZWMoZW1wdHksIGVtcHR5KTtcbiAgICB9O1xuICAgIC8vIHVuaGFuZGxlZCByZWplY3Rpb25zIHRyYWNraW5nIHN1cHBvcnQsIE5vZGVKUyBQcm9taXNlIHdpdGhvdXQgaXQgZmFpbHMgQEBzcGVjaWVzIHRlc3RcbiAgICByZXR1cm4gKGlzTm9kZSB8fCB0eXBlb2YgUHJvbWlzZVJlamVjdGlvbkV2ZW50ID09ICdmdW5jdGlvbicpXG4gICAgICAmJiBwcm9taXNlLnRoZW4oZW1wdHkpIGluc3RhbmNlb2YgRmFrZVByb21pc2VcbiAgICAgIC8vIHY4IDYuNiAoTm9kZSAxMCBhbmQgQ2hyb21lIDY2KSBoYXZlIGEgYnVnIHdpdGggcmVzb2x2aW5nIGN1c3RvbSB0aGVuYWJsZXNcbiAgICAgIC8vIGh0dHBzOi8vYnVncy5jaHJvbWl1bS5vcmcvcC9jaHJvbWl1bS9pc3N1ZXMvZGV0YWlsP2lkPTgzMDU2NVxuICAgICAgLy8gd2UgY2FuJ3QgZGV0ZWN0IGl0IHN5bmNocm9ub3VzbHksIHNvIGp1c3QgY2hlY2sgdmVyc2lvbnNcbiAgICAgICYmIHY4LmluZGV4T2YoJzYuNicpICE9PSAwXG4gICAgICAmJiB1c2VyQWdlbnQuaW5kZXhPZignQ2hyb21lLzY2JykgPT09IC0xO1xuICB9IGNhdGNoIChlKSB7IC8qIGVtcHR5ICovIH1cbn0oKTtcblxuLy8gaGVscGVyc1xudmFyIGlzVGhlbmFibGUgPSBmdW5jdGlvbiAoaXQpIHtcbiAgdmFyIHRoZW47XG4gIHJldHVybiBpc09iamVjdChpdCkgJiYgdHlwZW9mICh0aGVuID0gaXQudGhlbikgPT0gJ2Z1bmN0aW9uJyA/IHRoZW4gOiBmYWxzZTtcbn07XG52YXIgbm90aWZ5ID0gZnVuY3Rpb24gKHByb21pc2UsIGlzUmVqZWN0KSB7XG4gIGlmIChwcm9taXNlLl9uKSByZXR1cm47XG4gIHByb21pc2UuX24gPSB0cnVlO1xuICB2YXIgY2hhaW4gPSBwcm9taXNlLl9jO1xuICBtaWNyb3Rhc2soZnVuY3Rpb24gKCkge1xuICAgIHZhciB2YWx1ZSA9IHByb21pc2UuX3Y7XG4gICAgdmFyIG9rID0gcHJvbWlzZS5fcyA9PSAxO1xuICAgIHZhciBpID0gMDtcbiAgICB2YXIgcnVuID0gZnVuY3Rpb24gKHJlYWN0aW9uKSB7XG4gICAgICB2YXIgaGFuZGxlciA9IG9rID8gcmVhY3Rpb24ub2sgOiByZWFjdGlvbi5mYWlsO1xuICAgICAgdmFyIHJlc29sdmUgPSByZWFjdGlvbi5yZXNvbHZlO1xuICAgICAgdmFyIHJlamVjdCA9IHJlYWN0aW9uLnJlamVjdDtcbiAgICAgIHZhciBkb21haW4gPSByZWFjdGlvbi5kb21haW47XG4gICAgICB2YXIgcmVzdWx0LCB0aGVuLCBleGl0ZWQ7XG4gICAgICB0cnkge1xuICAgICAgICBpZiAoaGFuZGxlcikge1xuICAgICAgICAgIGlmICghb2spIHtcbiAgICAgICAgICAgIGlmIChwcm9taXNlLl9oID09IDIpIG9uSGFuZGxlVW5oYW5kbGVkKHByb21pc2UpO1xuICAgICAgICAgICAgcHJvbWlzZS5faCA9IDE7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChoYW5kbGVyID09PSB0cnVlKSByZXN1bHQgPSB2YWx1ZTtcbiAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGlmIChkb21haW4pIGRvbWFpbi5lbnRlcigpO1xuICAgICAgICAgICAgcmVzdWx0ID0gaGFuZGxlcih2YWx1ZSk7IC8vIG1heSB0aHJvd1xuICAgICAgICAgICAgaWYgKGRvbWFpbikge1xuICAgICAgICAgICAgICBkb21haW4uZXhpdCgpO1xuICAgICAgICAgICAgICBleGl0ZWQgPSB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAocmVzdWx0ID09PSByZWFjdGlvbi5wcm9taXNlKSB7XG4gICAgICAgICAgICByZWplY3QoVHlwZUVycm9yKCdQcm9taXNlLWNoYWluIGN5Y2xlJykpO1xuICAgICAgICAgIH0gZWxzZSBpZiAodGhlbiA9IGlzVGhlbmFibGUocmVzdWx0KSkge1xuICAgICAgICAgICAgdGhlbi5jYWxsKHJlc3VsdCwgcmVzb2x2ZSwgcmVqZWN0KTtcbiAgICAgICAgICB9IGVsc2UgcmVzb2x2ZShyZXN1bHQpO1xuICAgICAgICB9IGVsc2UgcmVqZWN0KHZhbHVlKTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgaWYgKGRvbWFpbiAmJiAhZXhpdGVkKSBkb21haW4uZXhpdCgpO1xuICAgICAgICByZWplY3QoZSk7XG4gICAgICB9XG4gICAgfTtcbiAgICB3aGlsZSAoY2hhaW4ubGVuZ3RoID4gaSkgcnVuKGNoYWluW2krK10pOyAvLyB2YXJpYWJsZSBsZW5ndGggLSBjYW4ndCB1c2UgZm9yRWFjaFxuICAgIHByb21pc2UuX2MgPSBbXTtcbiAgICBwcm9taXNlLl9uID0gZmFsc2U7XG4gICAgaWYgKGlzUmVqZWN0ICYmICFwcm9taXNlLl9oKSBvblVuaGFuZGxlZChwcm9taXNlKTtcbiAgfSk7XG59O1xudmFyIG9uVW5oYW5kbGVkID0gZnVuY3Rpb24gKHByb21pc2UpIHtcbiAgdGFzay5jYWxsKGdsb2JhbCwgZnVuY3Rpb24gKCkge1xuICAgIHZhciB2YWx1ZSA9IHByb21pc2UuX3Y7XG4gICAgdmFyIHVuaGFuZGxlZCA9IGlzVW5oYW5kbGVkKHByb21pc2UpO1xuICAgIHZhciByZXN1bHQsIGhhbmRsZXIsIGNvbnNvbGU7XG4gICAgaWYgKHVuaGFuZGxlZCkge1xuICAgICAgcmVzdWx0ID0gcGVyZm9ybShmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmIChpc05vZGUpIHtcbiAgICAgICAgICBwcm9jZXNzLmVtaXQoJ3VuaGFuZGxlZFJlamVjdGlvbicsIHZhbHVlLCBwcm9taXNlKTtcbiAgICAgICAgfSBlbHNlIGlmIChoYW5kbGVyID0gZ2xvYmFsLm9udW5oYW5kbGVkcmVqZWN0aW9uKSB7XG4gICAgICAgICAgaGFuZGxlcih7IHByb21pc2U6IHByb21pc2UsIHJlYXNvbjogdmFsdWUgfSk7XG4gICAgICAgIH0gZWxzZSBpZiAoKGNvbnNvbGUgPSBnbG9iYWwuY29uc29sZSkgJiYgY29uc29sZS5lcnJvcikge1xuICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ1VuaGFuZGxlZCBwcm9taXNlIHJlamVjdGlvbicsIHZhbHVlKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICAvLyBCcm93c2VycyBzaG91bGQgbm90IHRyaWdnZXIgYHJlamVjdGlvbkhhbmRsZWRgIGV2ZW50IGlmIGl0IHdhcyBoYW5kbGVkIGhlcmUsIE5vZGVKUyAtIHNob3VsZFxuICAgICAgcHJvbWlzZS5faCA9IGlzTm9kZSB8fCBpc1VuaGFuZGxlZChwcm9taXNlKSA/IDIgOiAxO1xuICAgIH0gcHJvbWlzZS5fYSA9IHVuZGVmaW5lZDtcbiAgICBpZiAodW5oYW5kbGVkICYmIHJlc3VsdC5lKSB0aHJvdyByZXN1bHQudjtcbiAgfSk7XG59O1xudmFyIGlzVW5oYW5kbGVkID0gZnVuY3Rpb24gKHByb21pc2UpIHtcbiAgcmV0dXJuIHByb21pc2UuX2ggIT09IDEgJiYgKHByb21pc2UuX2EgfHwgcHJvbWlzZS5fYykubGVuZ3RoID09PSAwO1xufTtcbnZhciBvbkhhbmRsZVVuaGFuZGxlZCA9IGZ1bmN0aW9uIChwcm9taXNlKSB7XG4gIHRhc2suY2FsbChnbG9iYWwsIGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgaGFuZGxlcjtcbiAgICBpZiAoaXNOb2RlKSB7XG4gICAgICBwcm9jZXNzLmVtaXQoJ3JlamVjdGlvbkhhbmRsZWQnLCBwcm9taXNlKTtcbiAgICB9IGVsc2UgaWYgKGhhbmRsZXIgPSBnbG9iYWwub25yZWplY3Rpb25oYW5kbGVkKSB7XG4gICAgICBoYW5kbGVyKHsgcHJvbWlzZTogcHJvbWlzZSwgcmVhc29uOiBwcm9taXNlLl92IH0pO1xuICAgIH1cbiAgfSk7XG59O1xudmFyICRyZWplY3QgPSBmdW5jdGlvbiAodmFsdWUpIHtcbiAgdmFyIHByb21pc2UgPSB0aGlzO1xuICBpZiAocHJvbWlzZS5fZCkgcmV0dXJuO1xuICBwcm9taXNlLl9kID0gdHJ1ZTtcbiAgcHJvbWlzZSA9IHByb21pc2UuX3cgfHwgcHJvbWlzZTsgLy8gdW53cmFwXG4gIHByb21pc2UuX3YgPSB2YWx1ZTtcbiAgcHJvbWlzZS5fcyA9IDI7XG4gIGlmICghcHJvbWlzZS5fYSkgcHJvbWlzZS5fYSA9IHByb21pc2UuX2Muc2xpY2UoKTtcbiAgbm90aWZ5KHByb21pc2UsIHRydWUpO1xufTtcbnZhciAkcmVzb2x2ZSA9IGZ1bmN0aW9uICh2YWx1ZSkge1xuICB2YXIgcHJvbWlzZSA9IHRoaXM7XG4gIHZhciB0aGVuO1xuICBpZiAocHJvbWlzZS5fZCkgcmV0dXJuO1xuICBwcm9taXNlLl9kID0gdHJ1ZTtcbiAgcHJvbWlzZSA9IHByb21pc2UuX3cgfHwgcHJvbWlzZTsgLy8gdW53cmFwXG4gIHRyeSB7XG4gICAgaWYgKHByb21pc2UgPT09IHZhbHVlKSB0aHJvdyBUeXBlRXJyb3IoXCJQcm9taXNlIGNhbid0IGJlIHJlc29sdmVkIGl0c2VsZlwiKTtcbiAgICBpZiAodGhlbiA9IGlzVGhlbmFibGUodmFsdWUpKSB7XG4gICAgICBtaWNyb3Rhc2soZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgd3JhcHBlciA9IHsgX3c6IHByb21pc2UsIF9kOiBmYWxzZSB9OyAvLyB3cmFwXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgdGhlbi5jYWxsKHZhbHVlLCBjdHgoJHJlc29sdmUsIHdyYXBwZXIsIDEpLCBjdHgoJHJlamVjdCwgd3JhcHBlciwgMSkpO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgJHJlamVjdC5jYWxsKHdyYXBwZXIsIGUpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgcHJvbWlzZS5fdiA9IHZhbHVlO1xuICAgICAgcHJvbWlzZS5fcyA9IDE7XG4gICAgICBub3RpZnkocHJvbWlzZSwgZmFsc2UpO1xuICAgIH1cbiAgfSBjYXRjaCAoZSkge1xuICAgICRyZWplY3QuY2FsbCh7IF93OiBwcm9taXNlLCBfZDogZmFsc2UgfSwgZSk7IC8vIHdyYXBcbiAgfVxufTtcblxuLy8gY29uc3RydWN0b3IgcG9seWZpbGxcbmlmICghVVNFX05BVElWRSkge1xuICAvLyAyNS40LjMuMSBQcm9taXNlKGV4ZWN1dG9yKVxuICAkUHJvbWlzZSA9IGZ1bmN0aW9uIFByb21pc2UoZXhlY3V0b3IpIHtcbiAgICBhbkluc3RhbmNlKHRoaXMsICRQcm9taXNlLCBQUk9NSVNFLCAnX2gnKTtcbiAgICBhRnVuY3Rpb24oZXhlY3V0b3IpO1xuICAgIEludGVybmFsLmNhbGwodGhpcyk7XG4gICAgdHJ5IHtcbiAgICAgIGV4ZWN1dG9yKGN0eCgkcmVzb2x2ZSwgdGhpcywgMSksIGN0eCgkcmVqZWN0LCB0aGlzLCAxKSk7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAkcmVqZWN0LmNhbGwodGhpcywgZXJyKTtcbiAgICB9XG4gIH07XG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby11bnVzZWQtdmFyc1xuICBJbnRlcm5hbCA9IGZ1bmN0aW9uIFByb21pc2UoZXhlY3V0b3IpIHtcbiAgICB0aGlzLl9jID0gW107ICAgICAgICAgICAgIC8vIDwtIGF3YWl0aW5nIHJlYWN0aW9uc1xuICAgIHRoaXMuX2EgPSB1bmRlZmluZWQ7ICAgICAgLy8gPC0gY2hlY2tlZCBpbiBpc1VuaGFuZGxlZCByZWFjdGlvbnNcbiAgICB0aGlzLl9zID0gMDsgICAgICAgICAgICAgIC8vIDwtIHN0YXRlXG4gICAgdGhpcy5fZCA9IGZhbHNlOyAgICAgICAgICAvLyA8LSBkb25lXG4gICAgdGhpcy5fdiA9IHVuZGVmaW5lZDsgICAgICAvLyA8LSB2YWx1ZVxuICAgIHRoaXMuX2ggPSAwOyAgICAgICAgICAgICAgLy8gPC0gcmVqZWN0aW9uIHN0YXRlLCAwIC0gZGVmYXVsdCwgMSAtIGhhbmRsZWQsIDIgLSB1bmhhbmRsZWRcbiAgICB0aGlzLl9uID0gZmFsc2U7ICAgICAgICAgIC8vIDwtIG5vdGlmeVxuICB9O1xuICBJbnRlcm5hbC5wcm90b3R5cGUgPSByZXF1aXJlKCcuL19yZWRlZmluZS1hbGwnKSgkUHJvbWlzZS5wcm90b3R5cGUsIHtcbiAgICAvLyAyNS40LjUuMyBQcm9taXNlLnByb3RvdHlwZS50aGVuKG9uRnVsZmlsbGVkLCBvblJlamVjdGVkKVxuICAgIHRoZW46IGZ1bmN0aW9uIHRoZW4ob25GdWxmaWxsZWQsIG9uUmVqZWN0ZWQpIHtcbiAgICAgIHZhciByZWFjdGlvbiA9IG5ld1Byb21pc2VDYXBhYmlsaXR5KHNwZWNpZXNDb25zdHJ1Y3Rvcih0aGlzLCAkUHJvbWlzZSkpO1xuICAgICAgcmVhY3Rpb24ub2sgPSB0eXBlb2Ygb25GdWxmaWxsZWQgPT0gJ2Z1bmN0aW9uJyA/IG9uRnVsZmlsbGVkIDogdHJ1ZTtcbiAgICAgIHJlYWN0aW9uLmZhaWwgPSB0eXBlb2Ygb25SZWplY3RlZCA9PSAnZnVuY3Rpb24nICYmIG9uUmVqZWN0ZWQ7XG4gICAgICByZWFjdGlvbi5kb21haW4gPSBpc05vZGUgPyBwcm9jZXNzLmRvbWFpbiA6IHVuZGVmaW5lZDtcbiAgICAgIHRoaXMuX2MucHVzaChyZWFjdGlvbik7XG4gICAgICBpZiAodGhpcy5fYSkgdGhpcy5fYS5wdXNoKHJlYWN0aW9uKTtcbiAgICAgIGlmICh0aGlzLl9zKSBub3RpZnkodGhpcywgZmFsc2UpO1xuICAgICAgcmV0dXJuIHJlYWN0aW9uLnByb21pc2U7XG4gICAgfSxcbiAgICAvLyAyNS40LjUuMSBQcm9taXNlLnByb3RvdHlwZS5jYXRjaChvblJlamVjdGVkKVxuICAgICdjYXRjaCc6IGZ1bmN0aW9uIChvblJlamVjdGVkKSB7XG4gICAgICByZXR1cm4gdGhpcy50aGVuKHVuZGVmaW5lZCwgb25SZWplY3RlZCk7XG4gICAgfVxuICB9KTtcbiAgT3duUHJvbWlzZUNhcGFiaWxpdHkgPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIHByb21pc2UgPSBuZXcgSW50ZXJuYWwoKTtcbiAgICB0aGlzLnByb21pc2UgPSBwcm9taXNlO1xuICAgIHRoaXMucmVzb2x2ZSA9IGN0eCgkcmVzb2x2ZSwgcHJvbWlzZSwgMSk7XG4gICAgdGhpcy5yZWplY3QgPSBjdHgoJHJlamVjdCwgcHJvbWlzZSwgMSk7XG4gIH07XG4gIG5ld1Byb21pc2VDYXBhYmlsaXR5TW9kdWxlLmYgPSBuZXdQcm9taXNlQ2FwYWJpbGl0eSA9IGZ1bmN0aW9uIChDKSB7XG4gICAgcmV0dXJuIEMgPT09ICRQcm9taXNlIHx8IEMgPT09IFdyYXBwZXJcbiAgICAgID8gbmV3IE93blByb21pc2VDYXBhYmlsaXR5KEMpXG4gICAgICA6IG5ld0dlbmVyaWNQcm9taXNlQ2FwYWJpbGl0eShDKTtcbiAgfTtcbn1cblxuJGV4cG9ydCgkZXhwb3J0LkcgKyAkZXhwb3J0LlcgKyAkZXhwb3J0LkYgKiAhVVNFX05BVElWRSwgeyBQcm9taXNlOiAkUHJvbWlzZSB9KTtcbnJlcXVpcmUoJy4vX3NldC10by1zdHJpbmctdGFnJykoJFByb21pc2UsIFBST01JU0UpO1xucmVxdWlyZSgnLi9fc2V0LXNwZWNpZXMnKShQUk9NSVNFKTtcbldyYXBwZXIgPSByZXF1aXJlKCcuL19jb3JlJylbUFJPTUlTRV07XG5cbi8vIHN0YXRpY3NcbiRleHBvcnQoJGV4cG9ydC5TICsgJGV4cG9ydC5GICogIVVTRV9OQVRJVkUsIFBST01JU0UsIHtcbiAgLy8gMjUuNC40LjUgUHJvbWlzZS5yZWplY3QocilcbiAgcmVqZWN0OiBmdW5jdGlvbiByZWplY3Qocikge1xuICAgIHZhciBjYXBhYmlsaXR5ID0gbmV3UHJvbWlzZUNhcGFiaWxpdHkodGhpcyk7XG4gICAgdmFyICQkcmVqZWN0ID0gY2FwYWJpbGl0eS5yZWplY3Q7XG4gICAgJCRyZWplY3Qocik7XG4gICAgcmV0dXJuIGNhcGFiaWxpdHkucHJvbWlzZTtcbiAgfVxufSk7XG4kZXhwb3J0KCRleHBvcnQuUyArICRleHBvcnQuRiAqIChMSUJSQVJZIHx8ICFVU0VfTkFUSVZFKSwgUFJPTUlTRSwge1xuICAvLyAyNS40LjQuNiBQcm9taXNlLnJlc29sdmUoeClcbiAgcmVzb2x2ZTogZnVuY3Rpb24gcmVzb2x2ZSh4KSB7XG4gICAgcmV0dXJuIHByb21pc2VSZXNvbHZlKExJQlJBUlkgJiYgdGhpcyA9PT0gV3JhcHBlciA/ICRQcm9taXNlIDogdGhpcywgeCk7XG4gIH1cbn0pO1xuJGV4cG9ydCgkZXhwb3J0LlMgKyAkZXhwb3J0LkYgKiAhKFVTRV9OQVRJVkUgJiYgcmVxdWlyZSgnLi9faXRlci1kZXRlY3QnKShmdW5jdGlvbiAoaXRlcikge1xuICAkUHJvbWlzZS5hbGwoaXRlcilbJ2NhdGNoJ10oZW1wdHkpO1xufSkpLCBQUk9NSVNFLCB7XG4gIC8vIDI1LjQuNC4xIFByb21pc2UuYWxsKGl0ZXJhYmxlKVxuICBhbGw6IGZ1bmN0aW9uIGFsbChpdGVyYWJsZSkge1xuICAgIHZhciBDID0gdGhpcztcbiAgICB2YXIgY2FwYWJpbGl0eSA9IG5ld1Byb21pc2VDYXBhYmlsaXR5KEMpO1xuICAgIHZhciByZXNvbHZlID0gY2FwYWJpbGl0eS5yZXNvbHZlO1xuICAgIHZhciByZWplY3QgPSBjYXBhYmlsaXR5LnJlamVjdDtcbiAgICB2YXIgcmVzdWx0ID0gcGVyZm9ybShmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgdmFsdWVzID0gW107XG4gICAgICB2YXIgaW5kZXggPSAwO1xuICAgICAgdmFyIHJlbWFpbmluZyA9IDE7XG4gICAgICBmb3JPZihpdGVyYWJsZSwgZmFsc2UsIGZ1bmN0aW9uIChwcm9taXNlKSB7XG4gICAgICAgIHZhciAkaW5kZXggPSBpbmRleCsrO1xuICAgICAgICB2YXIgYWxyZWFkeUNhbGxlZCA9IGZhbHNlO1xuICAgICAgICB2YWx1ZXMucHVzaCh1bmRlZmluZWQpO1xuICAgICAgICByZW1haW5pbmcrKztcbiAgICAgICAgQy5yZXNvbHZlKHByb21pc2UpLnRoZW4oZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICAgICAgaWYgKGFscmVhZHlDYWxsZWQpIHJldHVybjtcbiAgICAgICAgICBhbHJlYWR5Q2FsbGVkID0gdHJ1ZTtcbiAgICAgICAgICB2YWx1ZXNbJGluZGV4XSA9IHZhbHVlO1xuICAgICAgICAgIC0tcmVtYWluaW5nIHx8IHJlc29sdmUodmFsdWVzKTtcbiAgICAgICAgfSwgcmVqZWN0KTtcbiAgICAgIH0pO1xuICAgICAgLS1yZW1haW5pbmcgfHwgcmVzb2x2ZSh2YWx1ZXMpO1xuICAgIH0pO1xuICAgIGlmIChyZXN1bHQuZSkgcmVqZWN0KHJlc3VsdC52KTtcbiAgICByZXR1cm4gY2FwYWJpbGl0eS5wcm9taXNlO1xuICB9LFxuICAvLyAyNS40LjQuNCBQcm9taXNlLnJhY2UoaXRlcmFibGUpXG4gIHJhY2U6IGZ1bmN0aW9uIHJhY2UoaXRlcmFibGUpIHtcbiAgICB2YXIgQyA9IHRoaXM7XG4gICAgdmFyIGNhcGFiaWxpdHkgPSBuZXdQcm9taXNlQ2FwYWJpbGl0eShDKTtcbiAgICB2YXIgcmVqZWN0ID0gY2FwYWJpbGl0eS5yZWplY3Q7XG4gICAgdmFyIHJlc3VsdCA9IHBlcmZvcm0oZnVuY3Rpb24gKCkge1xuICAgICAgZm9yT2YoaXRlcmFibGUsIGZhbHNlLCBmdW5jdGlvbiAocHJvbWlzZSkge1xuICAgICAgICBDLnJlc29sdmUocHJvbWlzZSkudGhlbihjYXBhYmlsaXR5LnJlc29sdmUsIHJlamVjdCk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgICBpZiAocmVzdWx0LmUpIHJlamVjdChyZXN1bHQudik7XG4gICAgcmV0dXJuIGNhcGFiaWxpdHkucHJvbWlzZTtcbiAgfVxufSk7XG4iLCIvLyAyNi4xLjEgUmVmbGVjdC5hcHBseSh0YXJnZXQsIHRoaXNBcmd1bWVudCwgYXJndW1lbnRzTGlzdClcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgYUZ1bmN0aW9uID0gcmVxdWlyZSgnLi9fYS1mdW5jdGlvbicpO1xudmFyIGFuT2JqZWN0ID0gcmVxdWlyZSgnLi9fYW4tb2JqZWN0Jyk7XG52YXIgckFwcGx5ID0gKHJlcXVpcmUoJy4vX2dsb2JhbCcpLlJlZmxlY3QgfHwge30pLmFwcGx5O1xudmFyIGZBcHBseSA9IEZ1bmN0aW9uLmFwcGx5O1xuLy8gTVMgRWRnZSBhcmd1bWVudHNMaXN0IGFyZ3VtZW50IGlzIG9wdGlvbmFsXG4kZXhwb3J0KCRleHBvcnQuUyArICRleHBvcnQuRiAqICFyZXF1aXJlKCcuL19mYWlscycpKGZ1bmN0aW9uICgpIHtcbiAgckFwcGx5KGZ1bmN0aW9uICgpIHsgLyogZW1wdHkgKi8gfSk7XG59KSwgJ1JlZmxlY3QnLCB7XG4gIGFwcGx5OiBmdW5jdGlvbiBhcHBseSh0YXJnZXQsIHRoaXNBcmd1bWVudCwgYXJndW1lbnRzTGlzdCkge1xuICAgIHZhciBUID0gYUZ1bmN0aW9uKHRhcmdldCk7XG4gICAgdmFyIEwgPSBhbk9iamVjdChhcmd1bWVudHNMaXN0KTtcbiAgICByZXR1cm4gckFwcGx5ID8gckFwcGx5KFQsIHRoaXNBcmd1bWVudCwgTCkgOiBmQXBwbHkuY2FsbChULCB0aGlzQXJndW1lbnQsIEwpO1xuICB9XG59KTtcbiIsIi8vIDI2LjEuMiBSZWZsZWN0LmNvbnN0cnVjdCh0YXJnZXQsIGFyZ3VtZW50c0xpc3QgWywgbmV3VGFyZ2V0XSlcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgY3JlYXRlID0gcmVxdWlyZSgnLi9fb2JqZWN0LWNyZWF0ZScpO1xudmFyIGFGdW5jdGlvbiA9IHJlcXVpcmUoJy4vX2EtZnVuY3Rpb24nKTtcbnZhciBhbk9iamVjdCA9IHJlcXVpcmUoJy4vX2FuLW9iamVjdCcpO1xudmFyIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi9faXMtb2JqZWN0Jyk7XG52YXIgZmFpbHMgPSByZXF1aXJlKCcuL19mYWlscycpO1xudmFyIGJpbmQgPSByZXF1aXJlKCcuL19iaW5kJyk7XG52YXIgckNvbnN0cnVjdCA9IChyZXF1aXJlKCcuL19nbG9iYWwnKS5SZWZsZWN0IHx8IHt9KS5jb25zdHJ1Y3Q7XG5cbi8vIE1TIEVkZ2Ugc3VwcG9ydHMgb25seSAyIGFyZ3VtZW50cyBhbmQgYXJndW1lbnRzTGlzdCBhcmd1bWVudCBpcyBvcHRpb25hbFxuLy8gRkYgTmlnaHRseSBzZXRzIHRoaXJkIGFyZ3VtZW50IGFzIGBuZXcudGFyZ2V0YCwgYnV0IGRvZXMgbm90IGNyZWF0ZSBgdGhpc2AgZnJvbSBpdFxudmFyIE5FV19UQVJHRVRfQlVHID0gZmFpbHMoZnVuY3Rpb24gKCkge1xuICBmdW5jdGlvbiBGKCkgeyAvKiBlbXB0eSAqLyB9XG4gIHJldHVybiAhKHJDb25zdHJ1Y3QoZnVuY3Rpb24gKCkgeyAvKiBlbXB0eSAqLyB9LCBbXSwgRikgaW5zdGFuY2VvZiBGKTtcbn0pO1xudmFyIEFSR1NfQlVHID0gIWZhaWxzKGZ1bmN0aW9uICgpIHtcbiAgckNvbnN0cnVjdChmdW5jdGlvbiAoKSB7IC8qIGVtcHR5ICovIH0pO1xufSk7XG5cbiRleHBvcnQoJGV4cG9ydC5TICsgJGV4cG9ydC5GICogKE5FV19UQVJHRVRfQlVHIHx8IEFSR1NfQlVHKSwgJ1JlZmxlY3QnLCB7XG4gIGNvbnN0cnVjdDogZnVuY3Rpb24gY29uc3RydWN0KFRhcmdldCwgYXJncyAvKiAsIG5ld1RhcmdldCAqLykge1xuICAgIGFGdW5jdGlvbihUYXJnZXQpO1xuICAgIGFuT2JqZWN0KGFyZ3MpO1xuICAgIHZhciBuZXdUYXJnZXQgPSBhcmd1bWVudHMubGVuZ3RoIDwgMyA/IFRhcmdldCA6IGFGdW5jdGlvbihhcmd1bWVudHNbMl0pO1xuICAgIGlmIChBUkdTX0JVRyAmJiAhTkVXX1RBUkdFVF9CVUcpIHJldHVybiByQ29uc3RydWN0KFRhcmdldCwgYXJncywgbmV3VGFyZ2V0KTtcbiAgICBpZiAoVGFyZ2V0ID09IG5ld1RhcmdldCkge1xuICAgICAgLy8gdy9vIGFsdGVyZWQgbmV3VGFyZ2V0LCBvcHRpbWl6YXRpb24gZm9yIDAtNCBhcmd1bWVudHNcbiAgICAgIHN3aXRjaCAoYXJncy5sZW5ndGgpIHtcbiAgICAgICAgY2FzZSAwOiByZXR1cm4gbmV3IFRhcmdldCgpO1xuICAgICAgICBjYXNlIDE6IHJldHVybiBuZXcgVGFyZ2V0KGFyZ3NbMF0pO1xuICAgICAgICBjYXNlIDI6IHJldHVybiBuZXcgVGFyZ2V0KGFyZ3NbMF0sIGFyZ3NbMV0pO1xuICAgICAgICBjYXNlIDM6IHJldHVybiBuZXcgVGFyZ2V0KGFyZ3NbMF0sIGFyZ3NbMV0sIGFyZ3NbMl0pO1xuICAgICAgICBjYXNlIDQ6IHJldHVybiBuZXcgVGFyZ2V0KGFyZ3NbMF0sIGFyZ3NbMV0sIGFyZ3NbMl0sIGFyZ3NbM10pO1xuICAgICAgfVxuICAgICAgLy8gdy9vIGFsdGVyZWQgbmV3VGFyZ2V0LCBsb3Qgb2YgYXJndW1lbnRzIGNhc2VcbiAgICAgIHZhciAkYXJncyA9IFtudWxsXTtcbiAgICAgICRhcmdzLnB1c2guYXBwbHkoJGFyZ3MsIGFyZ3MpO1xuICAgICAgcmV0dXJuIG5ldyAoYmluZC5hcHBseShUYXJnZXQsICRhcmdzKSkoKTtcbiAgICB9XG4gICAgLy8gd2l0aCBhbHRlcmVkIG5ld1RhcmdldCwgbm90IHN1cHBvcnQgYnVpbHQtaW4gY29uc3RydWN0b3JzXG4gICAgdmFyIHByb3RvID0gbmV3VGFyZ2V0LnByb3RvdHlwZTtcbiAgICB2YXIgaW5zdGFuY2UgPSBjcmVhdGUoaXNPYmplY3QocHJvdG8pID8gcHJvdG8gOiBPYmplY3QucHJvdG90eXBlKTtcbiAgICB2YXIgcmVzdWx0ID0gRnVuY3Rpb24uYXBwbHkuY2FsbChUYXJnZXQsIGluc3RhbmNlLCBhcmdzKTtcbiAgICByZXR1cm4gaXNPYmplY3QocmVzdWx0KSA/IHJlc3VsdCA6IGluc3RhbmNlO1xuICB9XG59KTtcbiIsIi8vIDI2LjEuMyBSZWZsZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwgcHJvcGVydHlLZXksIGF0dHJpYnV0ZXMpXG52YXIgZFAgPSByZXF1aXJlKCcuL19vYmplY3QtZHAnKTtcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgYW5PYmplY3QgPSByZXF1aXJlKCcuL19hbi1vYmplY3QnKTtcbnZhciB0b1ByaW1pdGl2ZSA9IHJlcXVpcmUoJy4vX3RvLXByaW1pdGl2ZScpO1xuXG4vLyBNUyBFZGdlIGhhcyBicm9rZW4gUmVmbGVjdC5kZWZpbmVQcm9wZXJ0eSAtIHRocm93aW5nIGluc3RlYWQgb2YgcmV0dXJuaW5nIGZhbHNlXG4kZXhwb3J0KCRleHBvcnQuUyArICRleHBvcnQuRiAqIHJlcXVpcmUoJy4vX2ZhaWxzJykoZnVuY3Rpb24gKCkge1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tdW5kZWZcbiAgUmVmbGVjdC5kZWZpbmVQcm9wZXJ0eShkUC5mKHt9LCAxLCB7IHZhbHVlOiAxIH0pLCAxLCB7IHZhbHVlOiAyIH0pO1xufSksICdSZWZsZWN0Jywge1xuICBkZWZpbmVQcm9wZXJ0eTogZnVuY3Rpb24gZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBwcm9wZXJ0eUtleSwgYXR0cmlidXRlcykge1xuICAgIGFuT2JqZWN0KHRhcmdldCk7XG4gICAgcHJvcGVydHlLZXkgPSB0b1ByaW1pdGl2ZShwcm9wZXJ0eUtleSwgdHJ1ZSk7XG4gICAgYW5PYmplY3QoYXR0cmlidXRlcyk7XG4gICAgdHJ5IHtcbiAgICAgIGRQLmYodGFyZ2V0LCBwcm9wZXJ0eUtleSwgYXR0cmlidXRlcyk7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG59KTtcbiIsIi8vIDI2LjEuNCBSZWZsZWN0LmRlbGV0ZVByb3BlcnR5KHRhcmdldCwgcHJvcGVydHlLZXkpXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyIGdPUEQgPSByZXF1aXJlKCcuL19vYmplY3QtZ29wZCcpLmY7XG52YXIgYW5PYmplY3QgPSByZXF1aXJlKCcuL19hbi1vYmplY3QnKTtcblxuJGV4cG9ydCgkZXhwb3J0LlMsICdSZWZsZWN0Jywge1xuICBkZWxldGVQcm9wZXJ0eTogZnVuY3Rpb24gZGVsZXRlUHJvcGVydHkodGFyZ2V0LCBwcm9wZXJ0eUtleSkge1xuICAgIHZhciBkZXNjID0gZ09QRChhbk9iamVjdCh0YXJnZXQpLCBwcm9wZXJ0eUtleSk7XG4gICAgcmV0dXJuIGRlc2MgJiYgIWRlc2MuY29uZmlndXJhYmxlID8gZmFsc2UgOiBkZWxldGUgdGFyZ2V0W3Byb3BlcnR5S2V5XTtcbiAgfVxufSk7XG4iLCIndXNlIHN0cmljdCc7XG4vLyAyNi4xLjUgUmVmbGVjdC5lbnVtZXJhdGUodGFyZ2V0KVxudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciBhbk9iamVjdCA9IHJlcXVpcmUoJy4vX2FuLW9iamVjdCcpO1xudmFyIEVudW1lcmF0ZSA9IGZ1bmN0aW9uIChpdGVyYXRlZCkge1xuICB0aGlzLl90ID0gYW5PYmplY3QoaXRlcmF0ZWQpOyAvLyB0YXJnZXRcbiAgdGhpcy5faSA9IDA7ICAgICAgICAgICAgICAgICAgLy8gbmV4dCBpbmRleFxuICB2YXIga2V5cyA9IHRoaXMuX2sgPSBbXTsgICAgICAvLyBrZXlzXG4gIHZhciBrZXk7XG4gIGZvciAoa2V5IGluIGl0ZXJhdGVkKSBrZXlzLnB1c2goa2V5KTtcbn07XG5yZXF1aXJlKCcuL19pdGVyLWNyZWF0ZScpKEVudW1lcmF0ZSwgJ09iamVjdCcsIGZ1bmN0aW9uICgpIHtcbiAgdmFyIHRoYXQgPSB0aGlzO1xuICB2YXIga2V5cyA9IHRoYXQuX2s7XG4gIHZhciBrZXk7XG4gIGRvIHtcbiAgICBpZiAodGhhdC5faSA+PSBrZXlzLmxlbmd0aCkgcmV0dXJuIHsgdmFsdWU6IHVuZGVmaW5lZCwgZG9uZTogdHJ1ZSB9O1xuICB9IHdoaWxlICghKChrZXkgPSBrZXlzW3RoYXQuX2krK10pIGluIHRoYXQuX3QpKTtcbiAgcmV0dXJuIHsgdmFsdWU6IGtleSwgZG9uZTogZmFsc2UgfTtcbn0pO1xuXG4kZXhwb3J0KCRleHBvcnQuUywgJ1JlZmxlY3QnLCB7XG4gIGVudW1lcmF0ZTogZnVuY3Rpb24gZW51bWVyYXRlKHRhcmdldCkge1xuICAgIHJldHVybiBuZXcgRW51bWVyYXRlKHRhcmdldCk7XG4gIH1cbn0pO1xuIiwiLy8gMjYuMS43IFJlZmxlY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKHRhcmdldCwgcHJvcGVydHlLZXkpXG52YXIgZ09QRCA9IHJlcXVpcmUoJy4vX29iamVjdC1nb3BkJyk7XG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyIGFuT2JqZWN0ID0gcmVxdWlyZSgnLi9fYW4tb2JqZWN0Jyk7XG5cbiRleHBvcnQoJGV4cG9ydC5TLCAnUmVmbGVjdCcsIHtcbiAgZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yOiBmdW5jdGlvbiBnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IodGFyZ2V0LCBwcm9wZXJ0eUtleSkge1xuICAgIHJldHVybiBnT1BELmYoYW5PYmplY3QodGFyZ2V0KSwgcHJvcGVydHlLZXkpO1xuICB9XG59KTtcbiIsIi8vIDI2LjEuOCBSZWZsZWN0LmdldFByb3RvdHlwZU9mKHRhcmdldClcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgZ2V0UHJvdG8gPSByZXF1aXJlKCcuL19vYmplY3QtZ3BvJyk7XG52YXIgYW5PYmplY3QgPSByZXF1aXJlKCcuL19hbi1vYmplY3QnKTtcblxuJGV4cG9ydCgkZXhwb3J0LlMsICdSZWZsZWN0Jywge1xuICBnZXRQcm90b3R5cGVPZjogZnVuY3Rpb24gZ2V0UHJvdG90eXBlT2YodGFyZ2V0KSB7XG4gICAgcmV0dXJuIGdldFByb3RvKGFuT2JqZWN0KHRhcmdldCkpO1xuICB9XG59KTtcbiIsIi8vIDI2LjEuNiBSZWZsZWN0LmdldCh0YXJnZXQsIHByb3BlcnR5S2V5IFssIHJlY2VpdmVyXSlcbnZhciBnT1BEID0gcmVxdWlyZSgnLi9fb2JqZWN0LWdvcGQnKTtcbnZhciBnZXRQcm90b3R5cGVPZiA9IHJlcXVpcmUoJy4vX29iamVjdC1ncG8nKTtcbnZhciBoYXMgPSByZXF1aXJlKCcuL19oYXMnKTtcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgaXNPYmplY3QgPSByZXF1aXJlKCcuL19pcy1vYmplY3QnKTtcbnZhciBhbk9iamVjdCA9IHJlcXVpcmUoJy4vX2FuLW9iamVjdCcpO1xuXG5mdW5jdGlvbiBnZXQodGFyZ2V0LCBwcm9wZXJ0eUtleSAvKiAsIHJlY2VpdmVyICovKSB7XG4gIHZhciByZWNlaXZlciA9IGFyZ3VtZW50cy5sZW5ndGggPCAzID8gdGFyZ2V0IDogYXJndW1lbnRzWzJdO1xuICB2YXIgZGVzYywgcHJvdG87XG4gIGlmIChhbk9iamVjdCh0YXJnZXQpID09PSByZWNlaXZlcikgcmV0dXJuIHRhcmdldFtwcm9wZXJ0eUtleV07XG4gIGlmIChkZXNjID0gZ09QRC5mKHRhcmdldCwgcHJvcGVydHlLZXkpKSByZXR1cm4gaGFzKGRlc2MsICd2YWx1ZScpXG4gICAgPyBkZXNjLnZhbHVlXG4gICAgOiBkZXNjLmdldCAhPT0gdW5kZWZpbmVkXG4gICAgICA/IGRlc2MuZ2V0LmNhbGwocmVjZWl2ZXIpXG4gICAgICA6IHVuZGVmaW5lZDtcbiAgaWYgKGlzT2JqZWN0KHByb3RvID0gZ2V0UHJvdG90eXBlT2YodGFyZ2V0KSkpIHJldHVybiBnZXQocHJvdG8sIHByb3BlcnR5S2V5LCByZWNlaXZlcik7XG59XG5cbiRleHBvcnQoJGV4cG9ydC5TLCAnUmVmbGVjdCcsIHsgZ2V0OiBnZXQgfSk7XG4iLCIvLyAyNi4xLjkgUmVmbGVjdC5oYXModGFyZ2V0LCBwcm9wZXJ0eUtleSlcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG5cbiRleHBvcnQoJGV4cG9ydC5TLCAnUmVmbGVjdCcsIHtcbiAgaGFzOiBmdW5jdGlvbiBoYXModGFyZ2V0LCBwcm9wZXJ0eUtleSkge1xuICAgIHJldHVybiBwcm9wZXJ0eUtleSBpbiB0YXJnZXQ7XG4gIH1cbn0pO1xuIiwiLy8gMjYuMS4xMCBSZWZsZWN0LmlzRXh0ZW5zaWJsZSh0YXJnZXQpXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyIGFuT2JqZWN0ID0gcmVxdWlyZSgnLi9fYW4tb2JqZWN0Jyk7XG52YXIgJGlzRXh0ZW5zaWJsZSA9IE9iamVjdC5pc0V4dGVuc2libGU7XG5cbiRleHBvcnQoJGV4cG9ydC5TLCAnUmVmbGVjdCcsIHtcbiAgaXNFeHRlbnNpYmxlOiBmdW5jdGlvbiBpc0V4dGVuc2libGUodGFyZ2V0KSB7XG4gICAgYW5PYmplY3QodGFyZ2V0KTtcbiAgICByZXR1cm4gJGlzRXh0ZW5zaWJsZSA/ICRpc0V4dGVuc2libGUodGFyZ2V0KSA6IHRydWU7XG4gIH1cbn0pO1xuIiwiLy8gMjYuMS4xMSBSZWZsZWN0Lm93bktleXModGFyZ2V0KVxudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcblxuJGV4cG9ydCgkZXhwb3J0LlMsICdSZWZsZWN0JywgeyBvd25LZXlzOiByZXF1aXJlKCcuL19vd24ta2V5cycpIH0pO1xuIiwiLy8gMjYuMS4xMiBSZWZsZWN0LnByZXZlbnRFeHRlbnNpb25zKHRhcmdldClcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgYW5PYmplY3QgPSByZXF1aXJlKCcuL19hbi1vYmplY3QnKTtcbnZhciAkcHJldmVudEV4dGVuc2lvbnMgPSBPYmplY3QucHJldmVudEV4dGVuc2lvbnM7XG5cbiRleHBvcnQoJGV4cG9ydC5TLCAnUmVmbGVjdCcsIHtcbiAgcHJldmVudEV4dGVuc2lvbnM6IGZ1bmN0aW9uIHByZXZlbnRFeHRlbnNpb25zKHRhcmdldCkge1xuICAgIGFuT2JqZWN0KHRhcmdldCk7XG4gICAgdHJ5IHtcbiAgICAgIGlmICgkcHJldmVudEV4dGVuc2lvbnMpICRwcmV2ZW50RXh0ZW5zaW9ucyh0YXJnZXQpO1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxufSk7XG4iLCIvLyAyNi4xLjE0IFJlZmxlY3Quc2V0UHJvdG90eXBlT2YodGFyZ2V0LCBwcm90bylcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgc2V0UHJvdG8gPSByZXF1aXJlKCcuL19zZXQtcHJvdG8nKTtcblxuaWYgKHNldFByb3RvKSAkZXhwb3J0KCRleHBvcnQuUywgJ1JlZmxlY3QnLCB7XG4gIHNldFByb3RvdHlwZU9mOiBmdW5jdGlvbiBzZXRQcm90b3R5cGVPZih0YXJnZXQsIHByb3RvKSB7XG4gICAgc2V0UHJvdG8uY2hlY2sodGFyZ2V0LCBwcm90byk7XG4gICAgdHJ5IHtcbiAgICAgIHNldFByb3RvLnNldCh0YXJnZXQsIHByb3RvKTtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cbn0pO1xuIiwiLy8gMjYuMS4xMyBSZWZsZWN0LnNldCh0YXJnZXQsIHByb3BlcnR5S2V5LCBWIFssIHJlY2VpdmVyXSlcbnZhciBkUCA9IHJlcXVpcmUoJy4vX29iamVjdC1kcCcpO1xudmFyIGdPUEQgPSByZXF1aXJlKCcuL19vYmplY3QtZ29wZCcpO1xudmFyIGdldFByb3RvdHlwZU9mID0gcmVxdWlyZSgnLi9fb2JqZWN0LWdwbycpO1xudmFyIGhhcyA9IHJlcXVpcmUoJy4vX2hhcycpO1xudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciBjcmVhdGVEZXNjID0gcmVxdWlyZSgnLi9fcHJvcGVydHktZGVzYycpO1xudmFyIGFuT2JqZWN0ID0gcmVxdWlyZSgnLi9fYW4tb2JqZWN0Jyk7XG52YXIgaXNPYmplY3QgPSByZXF1aXJlKCcuL19pcy1vYmplY3QnKTtcblxuZnVuY3Rpb24gc2V0KHRhcmdldCwgcHJvcGVydHlLZXksIFYgLyogLCByZWNlaXZlciAqLykge1xuICB2YXIgcmVjZWl2ZXIgPSBhcmd1bWVudHMubGVuZ3RoIDwgNCA/IHRhcmdldCA6IGFyZ3VtZW50c1szXTtcbiAgdmFyIG93bkRlc2MgPSBnT1BELmYoYW5PYmplY3QodGFyZ2V0KSwgcHJvcGVydHlLZXkpO1xuICB2YXIgZXhpc3RpbmdEZXNjcmlwdG9yLCBwcm90bztcbiAgaWYgKCFvd25EZXNjKSB7XG4gICAgaWYgKGlzT2JqZWN0KHByb3RvID0gZ2V0UHJvdG90eXBlT2YodGFyZ2V0KSkpIHtcbiAgICAgIHJldHVybiBzZXQocHJvdG8sIHByb3BlcnR5S2V5LCBWLCByZWNlaXZlcik7XG4gICAgfVxuICAgIG93bkRlc2MgPSBjcmVhdGVEZXNjKDApO1xuICB9XG4gIGlmIChoYXMob3duRGVzYywgJ3ZhbHVlJykpIHtcbiAgICBpZiAob3duRGVzYy53cml0YWJsZSA9PT0gZmFsc2UgfHwgIWlzT2JqZWN0KHJlY2VpdmVyKSkgcmV0dXJuIGZhbHNlO1xuICAgIGlmIChleGlzdGluZ0Rlc2NyaXB0b3IgPSBnT1BELmYocmVjZWl2ZXIsIHByb3BlcnR5S2V5KSkge1xuICAgICAgaWYgKGV4aXN0aW5nRGVzY3JpcHRvci5nZXQgfHwgZXhpc3RpbmdEZXNjcmlwdG9yLnNldCB8fCBleGlzdGluZ0Rlc2NyaXB0b3Iud3JpdGFibGUgPT09IGZhbHNlKSByZXR1cm4gZmFsc2U7XG4gICAgICBleGlzdGluZ0Rlc2NyaXB0b3IudmFsdWUgPSBWO1xuICAgICAgZFAuZihyZWNlaXZlciwgcHJvcGVydHlLZXksIGV4aXN0aW5nRGVzY3JpcHRvcik7XG4gICAgfSBlbHNlIGRQLmYocmVjZWl2ZXIsIHByb3BlcnR5S2V5LCBjcmVhdGVEZXNjKDAsIFYpKTtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuICByZXR1cm4gb3duRGVzYy5zZXQgPT09IHVuZGVmaW5lZCA/IGZhbHNlIDogKG93bkRlc2Muc2V0LmNhbGwocmVjZWl2ZXIsIFYpLCB0cnVlKTtcbn1cblxuJGV4cG9ydCgkZXhwb3J0LlMsICdSZWZsZWN0JywgeyBzZXQ6IHNldCB9KTtcbiIsInZhciBnbG9iYWwgPSByZXF1aXJlKCcuL19nbG9iYWwnKTtcbnZhciBpbmhlcml0SWZSZXF1aXJlZCA9IHJlcXVpcmUoJy4vX2luaGVyaXQtaWYtcmVxdWlyZWQnKTtcbnZhciBkUCA9IHJlcXVpcmUoJy4vX29iamVjdC1kcCcpLmY7XG52YXIgZ09QTiA9IHJlcXVpcmUoJy4vX29iamVjdC1nb3BuJykuZjtcbnZhciBpc1JlZ0V4cCA9IHJlcXVpcmUoJy4vX2lzLXJlZ2V4cCcpO1xudmFyICRmbGFncyA9IHJlcXVpcmUoJy4vX2ZsYWdzJyk7XG52YXIgJFJlZ0V4cCA9IGdsb2JhbC5SZWdFeHA7XG52YXIgQmFzZSA9ICRSZWdFeHA7XG52YXIgcHJvdG8gPSAkUmVnRXhwLnByb3RvdHlwZTtcbnZhciByZTEgPSAvYS9nO1xudmFyIHJlMiA9IC9hL2c7XG4vLyBcIm5ld1wiIGNyZWF0ZXMgYSBuZXcgb2JqZWN0LCBvbGQgd2Via2l0IGJ1Z2d5IGhlcmVcbnZhciBDT1JSRUNUX05FVyA9IG5ldyAkUmVnRXhwKHJlMSkgIT09IHJlMTtcblxuaWYgKHJlcXVpcmUoJy4vX2Rlc2NyaXB0b3JzJykgJiYgKCFDT1JSRUNUX05FVyB8fCByZXF1aXJlKCcuL19mYWlscycpKGZ1bmN0aW9uICgpIHtcbiAgcmUyW3JlcXVpcmUoJy4vX3drcycpKCdtYXRjaCcpXSA9IGZhbHNlO1xuICAvLyBSZWdFeHAgY29uc3RydWN0b3IgY2FuIGFsdGVyIGZsYWdzIGFuZCBJc1JlZ0V4cCB3b3JrcyBjb3JyZWN0IHdpdGggQEBtYXRjaFxuICByZXR1cm4gJFJlZ0V4cChyZTEpICE9IHJlMSB8fCAkUmVnRXhwKHJlMikgPT0gcmUyIHx8ICRSZWdFeHAocmUxLCAnaScpICE9ICcvYS9pJztcbn0pKSkge1xuICAkUmVnRXhwID0gZnVuY3Rpb24gUmVnRXhwKHAsIGYpIHtcbiAgICB2YXIgdGlSRSA9IHRoaXMgaW5zdGFuY2VvZiAkUmVnRXhwO1xuICAgIHZhciBwaVJFID0gaXNSZWdFeHAocCk7XG4gICAgdmFyIGZpVSA9IGYgPT09IHVuZGVmaW5lZDtcbiAgICByZXR1cm4gIXRpUkUgJiYgcGlSRSAmJiBwLmNvbnN0cnVjdG9yID09PSAkUmVnRXhwICYmIGZpVSA/IHBcbiAgICAgIDogaW5oZXJpdElmUmVxdWlyZWQoQ09SUkVDVF9ORVdcbiAgICAgICAgPyBuZXcgQmFzZShwaVJFICYmICFmaVUgPyBwLnNvdXJjZSA6IHAsIGYpXG4gICAgICAgIDogQmFzZSgocGlSRSA9IHAgaW5zdGFuY2VvZiAkUmVnRXhwKSA/IHAuc291cmNlIDogcCwgcGlSRSAmJiBmaVUgPyAkZmxhZ3MuY2FsbChwKSA6IGYpXG4gICAgICAsIHRpUkUgPyB0aGlzIDogcHJvdG8sICRSZWdFeHApO1xuICB9O1xuICB2YXIgcHJveHkgPSBmdW5jdGlvbiAoa2V5KSB7XG4gICAga2V5IGluICRSZWdFeHAgfHwgZFAoJFJlZ0V4cCwga2V5LCB7XG4gICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgICBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIEJhc2Vba2V5XTsgfSxcbiAgICAgIHNldDogZnVuY3Rpb24gKGl0KSB7IEJhc2Vba2V5XSA9IGl0OyB9XG4gICAgfSk7XG4gIH07XG4gIGZvciAodmFyIGtleXMgPSBnT1BOKEJhc2UpLCBpID0gMDsga2V5cy5sZW5ndGggPiBpOykgcHJveHkoa2V5c1tpKytdKTtcbiAgcHJvdG8uY29uc3RydWN0b3IgPSAkUmVnRXhwO1xuICAkUmVnRXhwLnByb3RvdHlwZSA9IHByb3RvO1xuICByZXF1aXJlKCcuL19yZWRlZmluZScpKGdsb2JhbCwgJ1JlZ0V4cCcsICRSZWdFeHApO1xufVxuXG5yZXF1aXJlKCcuL19zZXQtc3BlY2llcycpKCdSZWdFeHAnKTtcbiIsIi8vIDIxLjIuNS4zIGdldCBSZWdFeHAucHJvdG90eXBlLmZsYWdzKClcbmlmIChyZXF1aXJlKCcuL19kZXNjcmlwdG9ycycpICYmIC8uL2cuZmxhZ3MgIT0gJ2cnKSByZXF1aXJlKCcuL19vYmplY3QtZHAnKS5mKFJlZ0V4cC5wcm90b3R5cGUsICdmbGFncycsIHtcbiAgY29uZmlndXJhYmxlOiB0cnVlLFxuICBnZXQ6IHJlcXVpcmUoJy4vX2ZsYWdzJylcbn0pO1xuIiwiLy8gQEBtYXRjaCBsb2dpY1xucmVxdWlyZSgnLi9fZml4LXJlLXdrcycpKCdtYXRjaCcsIDEsIGZ1bmN0aW9uIChkZWZpbmVkLCBNQVRDSCwgJG1hdGNoKSB7XG4gIC8vIDIxLjEuMy4xMSBTdHJpbmcucHJvdG90eXBlLm1hdGNoKHJlZ2V4cClcbiAgcmV0dXJuIFtmdW5jdGlvbiBtYXRjaChyZWdleHApIHtcbiAgICAndXNlIHN0cmljdCc7XG4gICAgdmFyIE8gPSBkZWZpbmVkKHRoaXMpO1xuICAgIHZhciBmbiA9IHJlZ2V4cCA9PSB1bmRlZmluZWQgPyB1bmRlZmluZWQgOiByZWdleHBbTUFUQ0hdO1xuICAgIHJldHVybiBmbiAhPT0gdW5kZWZpbmVkID8gZm4uY2FsbChyZWdleHAsIE8pIDogbmV3IFJlZ0V4cChyZWdleHApW01BVENIXShTdHJpbmcoTykpO1xuICB9LCAkbWF0Y2hdO1xufSk7XG4iLCIvLyBAQHJlcGxhY2UgbG9naWNcbnJlcXVpcmUoJy4vX2ZpeC1yZS13a3MnKSgncmVwbGFjZScsIDIsIGZ1bmN0aW9uIChkZWZpbmVkLCBSRVBMQUNFLCAkcmVwbGFjZSkge1xuICAvLyAyMS4xLjMuMTQgU3RyaW5nLnByb3RvdHlwZS5yZXBsYWNlKHNlYXJjaFZhbHVlLCByZXBsYWNlVmFsdWUpXG4gIHJldHVybiBbZnVuY3Rpb24gcmVwbGFjZShzZWFyY2hWYWx1ZSwgcmVwbGFjZVZhbHVlKSB7XG4gICAgJ3VzZSBzdHJpY3QnO1xuICAgIHZhciBPID0gZGVmaW5lZCh0aGlzKTtcbiAgICB2YXIgZm4gPSBzZWFyY2hWYWx1ZSA9PSB1bmRlZmluZWQgPyB1bmRlZmluZWQgOiBzZWFyY2hWYWx1ZVtSRVBMQUNFXTtcbiAgICByZXR1cm4gZm4gIT09IHVuZGVmaW5lZFxuICAgICAgPyBmbi5jYWxsKHNlYXJjaFZhbHVlLCBPLCByZXBsYWNlVmFsdWUpXG4gICAgICA6ICRyZXBsYWNlLmNhbGwoU3RyaW5nKE8pLCBzZWFyY2hWYWx1ZSwgcmVwbGFjZVZhbHVlKTtcbiAgfSwgJHJlcGxhY2VdO1xufSk7XG4iLCIvLyBAQHNlYXJjaCBsb2dpY1xucmVxdWlyZSgnLi9fZml4LXJlLXdrcycpKCdzZWFyY2gnLCAxLCBmdW5jdGlvbiAoZGVmaW5lZCwgU0VBUkNILCAkc2VhcmNoKSB7XG4gIC8vIDIxLjEuMy4xNSBTdHJpbmcucHJvdG90eXBlLnNlYXJjaChyZWdleHApXG4gIHJldHVybiBbZnVuY3Rpb24gc2VhcmNoKHJlZ2V4cCkge1xuICAgICd1c2Ugc3RyaWN0JztcbiAgICB2YXIgTyA9IGRlZmluZWQodGhpcyk7XG4gICAgdmFyIGZuID0gcmVnZXhwID09IHVuZGVmaW5lZCA/IHVuZGVmaW5lZCA6IHJlZ2V4cFtTRUFSQ0hdO1xuICAgIHJldHVybiBmbiAhPT0gdW5kZWZpbmVkID8gZm4uY2FsbChyZWdleHAsIE8pIDogbmV3IFJlZ0V4cChyZWdleHApW1NFQVJDSF0oU3RyaW5nKE8pKTtcbiAgfSwgJHNlYXJjaF07XG59KTtcbiIsIi8vIEBAc3BsaXQgbG9naWNcbnJlcXVpcmUoJy4vX2ZpeC1yZS13a3MnKSgnc3BsaXQnLCAyLCBmdW5jdGlvbiAoZGVmaW5lZCwgU1BMSVQsICRzcGxpdCkge1xuICAndXNlIHN0cmljdCc7XG4gIHZhciBpc1JlZ0V4cCA9IHJlcXVpcmUoJy4vX2lzLXJlZ2V4cCcpO1xuICB2YXIgX3NwbGl0ID0gJHNwbGl0O1xuICB2YXIgJHB1c2ggPSBbXS5wdXNoO1xuICB2YXIgJFNQTElUID0gJ3NwbGl0JztcbiAgdmFyIExFTkdUSCA9ICdsZW5ndGgnO1xuICB2YXIgTEFTVF9JTkRFWCA9ICdsYXN0SW5kZXgnO1xuICBpZiAoXG4gICAgJ2FiYmMnWyRTUExJVF0oLyhiKSovKVsxXSA9PSAnYycgfHxcbiAgICAndGVzdCdbJFNQTElUXSgvKD86KS8sIC0xKVtMRU5HVEhdICE9IDQgfHxcbiAgICAnYWInWyRTUExJVF0oLyg/OmFiKSovKVtMRU5HVEhdICE9IDIgfHxcbiAgICAnLidbJFNQTElUXSgvKC4/KSguPykvKVtMRU5HVEhdICE9IDQgfHxcbiAgICAnLidbJFNQTElUXSgvKCkoKS8pW0xFTkdUSF0gPiAxIHx8XG4gICAgJydbJFNQTElUXSgvLj8vKVtMRU5HVEhdXG4gICkge1xuICAgIHZhciBOUENHID0gLygpPz8vLmV4ZWMoJycpWzFdID09PSB1bmRlZmluZWQ7IC8vIG5vbnBhcnRpY2lwYXRpbmcgY2FwdHVyaW5nIGdyb3VwXG4gICAgLy8gYmFzZWQgb24gZXM1LXNoaW0gaW1wbGVtZW50YXRpb24sIG5lZWQgdG8gcmV3b3JrIGl0XG4gICAgJHNwbGl0ID0gZnVuY3Rpb24gKHNlcGFyYXRvciwgbGltaXQpIHtcbiAgICAgIHZhciBzdHJpbmcgPSBTdHJpbmcodGhpcyk7XG4gICAgICBpZiAoc2VwYXJhdG9yID09PSB1bmRlZmluZWQgJiYgbGltaXQgPT09IDApIHJldHVybiBbXTtcbiAgICAgIC8vIElmIGBzZXBhcmF0b3JgIGlzIG5vdCBhIHJlZ2V4LCB1c2UgbmF0aXZlIHNwbGl0XG4gICAgICBpZiAoIWlzUmVnRXhwKHNlcGFyYXRvcikpIHJldHVybiBfc3BsaXQuY2FsbChzdHJpbmcsIHNlcGFyYXRvciwgbGltaXQpO1xuICAgICAgdmFyIG91dHB1dCA9IFtdO1xuICAgICAgdmFyIGZsYWdzID0gKHNlcGFyYXRvci5pZ25vcmVDYXNlID8gJ2knIDogJycpICtcbiAgICAgICAgICAgICAgICAgIChzZXBhcmF0b3IubXVsdGlsaW5lID8gJ20nIDogJycpICtcbiAgICAgICAgICAgICAgICAgIChzZXBhcmF0b3IudW5pY29kZSA/ICd1JyA6ICcnKSArXG4gICAgICAgICAgICAgICAgICAoc2VwYXJhdG9yLnN0aWNreSA/ICd5JyA6ICcnKTtcbiAgICAgIHZhciBsYXN0TGFzdEluZGV4ID0gMDtcbiAgICAgIHZhciBzcGxpdExpbWl0ID0gbGltaXQgPT09IHVuZGVmaW5lZCA/IDQyOTQ5NjcyOTUgOiBsaW1pdCA+Pj4gMDtcbiAgICAgIC8vIE1ha2UgYGdsb2JhbGAgYW5kIGF2b2lkIGBsYXN0SW5kZXhgIGlzc3VlcyBieSB3b3JraW5nIHdpdGggYSBjb3B5XG4gICAgICB2YXIgc2VwYXJhdG9yQ29weSA9IG5ldyBSZWdFeHAoc2VwYXJhdG9yLnNvdXJjZSwgZmxhZ3MgKyAnZycpO1xuICAgICAgdmFyIHNlcGFyYXRvcjIsIG1hdGNoLCBsYXN0SW5kZXgsIGxhc3RMZW5ndGgsIGk7XG4gICAgICAvLyBEb2Vzbid0IG5lZWQgZmxhZ3MgZ3ksIGJ1dCB0aGV5IGRvbid0IGh1cnRcbiAgICAgIGlmICghTlBDRykgc2VwYXJhdG9yMiA9IG5ldyBSZWdFeHAoJ14nICsgc2VwYXJhdG9yQ29weS5zb3VyY2UgKyAnJCg/IVxcXFxzKScsIGZsYWdzKTtcbiAgICAgIHdoaWxlIChtYXRjaCA9IHNlcGFyYXRvckNvcHkuZXhlYyhzdHJpbmcpKSB7XG4gICAgICAgIC8vIGBzZXBhcmF0b3JDb3B5Lmxhc3RJbmRleGAgaXMgbm90IHJlbGlhYmxlIGNyb3NzLWJyb3dzZXJcbiAgICAgICAgbGFzdEluZGV4ID0gbWF0Y2guaW5kZXggKyBtYXRjaFswXVtMRU5HVEhdO1xuICAgICAgICBpZiAobGFzdEluZGV4ID4gbGFzdExhc3RJbmRleCkge1xuICAgICAgICAgIG91dHB1dC5wdXNoKHN0cmluZy5zbGljZShsYXN0TGFzdEluZGV4LCBtYXRjaC5pbmRleCkpO1xuICAgICAgICAgIC8vIEZpeCBicm93c2VycyB3aG9zZSBgZXhlY2AgbWV0aG9kcyBkb24ndCBjb25zaXN0ZW50bHkgcmV0dXJuIGB1bmRlZmluZWRgIGZvciBOUENHXG4gICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWxvb3AtZnVuY1xuICAgICAgICAgIGlmICghTlBDRyAmJiBtYXRjaFtMRU5HVEhdID4gMSkgbWF0Y2hbMF0ucmVwbGFjZShzZXBhcmF0b3IyLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBmb3IgKGkgPSAxOyBpIDwgYXJndW1lbnRzW0xFTkdUSF0gLSAyOyBpKyspIGlmIChhcmd1bWVudHNbaV0gPT09IHVuZGVmaW5lZCkgbWF0Y2hbaV0gPSB1bmRlZmluZWQ7XG4gICAgICAgICAgfSk7XG4gICAgICAgICAgaWYgKG1hdGNoW0xFTkdUSF0gPiAxICYmIG1hdGNoLmluZGV4IDwgc3RyaW5nW0xFTkdUSF0pICRwdXNoLmFwcGx5KG91dHB1dCwgbWF0Y2guc2xpY2UoMSkpO1xuICAgICAgICAgIGxhc3RMZW5ndGggPSBtYXRjaFswXVtMRU5HVEhdO1xuICAgICAgICAgIGxhc3RMYXN0SW5kZXggPSBsYXN0SW5kZXg7XG4gICAgICAgICAgaWYgKG91dHB1dFtMRU5HVEhdID49IHNwbGl0TGltaXQpIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIGlmIChzZXBhcmF0b3JDb3B5W0xBU1RfSU5ERVhdID09PSBtYXRjaC5pbmRleCkgc2VwYXJhdG9yQ29weVtMQVNUX0lOREVYXSsrOyAvLyBBdm9pZCBhbiBpbmZpbml0ZSBsb29wXG4gICAgICB9XG4gICAgICBpZiAobGFzdExhc3RJbmRleCA9PT0gc3RyaW5nW0xFTkdUSF0pIHtcbiAgICAgICAgaWYgKGxhc3RMZW5ndGggfHwgIXNlcGFyYXRvckNvcHkudGVzdCgnJykpIG91dHB1dC5wdXNoKCcnKTtcbiAgICAgIH0gZWxzZSBvdXRwdXQucHVzaChzdHJpbmcuc2xpY2UobGFzdExhc3RJbmRleCkpO1xuICAgICAgcmV0dXJuIG91dHB1dFtMRU5HVEhdID4gc3BsaXRMaW1pdCA/IG91dHB1dC5zbGljZSgwLCBzcGxpdExpbWl0KSA6IG91dHB1dDtcbiAgICB9O1xuICAvLyBDaGFrcmEsIFY4XG4gIH0gZWxzZSBpZiAoJzAnWyRTUExJVF0odW5kZWZpbmVkLCAwKVtMRU5HVEhdKSB7XG4gICAgJHNwbGl0ID0gZnVuY3Rpb24gKHNlcGFyYXRvciwgbGltaXQpIHtcbiAgICAgIHJldHVybiBzZXBhcmF0b3IgPT09IHVuZGVmaW5lZCAmJiBsaW1pdCA9PT0gMCA/IFtdIDogX3NwbGl0LmNhbGwodGhpcywgc2VwYXJhdG9yLCBsaW1pdCk7XG4gICAgfTtcbiAgfVxuICAvLyAyMS4xLjMuMTcgU3RyaW5nLnByb3RvdHlwZS5zcGxpdChzZXBhcmF0b3IsIGxpbWl0KVxuICByZXR1cm4gW2Z1bmN0aW9uIHNwbGl0KHNlcGFyYXRvciwgbGltaXQpIHtcbiAgICB2YXIgTyA9IGRlZmluZWQodGhpcyk7XG4gICAgdmFyIGZuID0gc2VwYXJhdG9yID09IHVuZGVmaW5lZCA/IHVuZGVmaW5lZCA6IHNlcGFyYXRvcltTUExJVF07XG4gICAgcmV0dXJuIGZuICE9PSB1bmRlZmluZWQgPyBmbi5jYWxsKHNlcGFyYXRvciwgTywgbGltaXQpIDogJHNwbGl0LmNhbGwoU3RyaW5nKE8pLCBzZXBhcmF0b3IsIGxpbWl0KTtcbiAgfSwgJHNwbGl0XTtcbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xucmVxdWlyZSgnLi9lczYucmVnZXhwLmZsYWdzJyk7XG52YXIgYW5PYmplY3QgPSByZXF1aXJlKCcuL19hbi1vYmplY3QnKTtcbnZhciAkZmxhZ3MgPSByZXF1aXJlKCcuL19mbGFncycpO1xudmFyIERFU0NSSVBUT1JTID0gcmVxdWlyZSgnLi9fZGVzY3JpcHRvcnMnKTtcbnZhciBUT19TVFJJTkcgPSAndG9TdHJpbmcnO1xudmFyICR0b1N0cmluZyA9IC8uL1tUT19TVFJJTkddO1xuXG52YXIgZGVmaW5lID0gZnVuY3Rpb24gKGZuKSB7XG4gIHJlcXVpcmUoJy4vX3JlZGVmaW5lJykoUmVnRXhwLnByb3RvdHlwZSwgVE9fU1RSSU5HLCBmbiwgdHJ1ZSk7XG59O1xuXG4vLyAyMS4yLjUuMTQgUmVnRXhwLnByb3RvdHlwZS50b1N0cmluZygpXG5pZiAocmVxdWlyZSgnLi9fZmFpbHMnKShmdW5jdGlvbiAoKSB7IHJldHVybiAkdG9TdHJpbmcuY2FsbCh7IHNvdXJjZTogJ2EnLCBmbGFnczogJ2InIH0pICE9ICcvYS9iJzsgfSkpIHtcbiAgZGVmaW5lKGZ1bmN0aW9uIHRvU3RyaW5nKCkge1xuICAgIHZhciBSID0gYW5PYmplY3QodGhpcyk7XG4gICAgcmV0dXJuICcvJy5jb25jYXQoUi5zb3VyY2UsICcvJyxcbiAgICAgICdmbGFncycgaW4gUiA/IFIuZmxhZ3MgOiAhREVTQ1JJUFRPUlMgJiYgUiBpbnN0YW5jZW9mIFJlZ0V4cCA/ICRmbGFncy5jYWxsKFIpIDogdW5kZWZpbmVkKTtcbiAgfSk7XG4vLyBGRjQ0LSBSZWdFeHAjdG9TdHJpbmcgaGFzIGEgd3JvbmcgbmFtZVxufSBlbHNlIGlmICgkdG9TdHJpbmcubmFtZSAhPSBUT19TVFJJTkcpIHtcbiAgZGVmaW5lKGZ1bmN0aW9uIHRvU3RyaW5nKCkge1xuICAgIHJldHVybiAkdG9TdHJpbmcuY2FsbCh0aGlzKTtcbiAgfSk7XG59XG4iLCIndXNlIHN0cmljdCc7XG52YXIgc3Ryb25nID0gcmVxdWlyZSgnLi9fY29sbGVjdGlvbi1zdHJvbmcnKTtcbnZhciB2YWxpZGF0ZSA9IHJlcXVpcmUoJy4vX3ZhbGlkYXRlLWNvbGxlY3Rpb24nKTtcbnZhciBTRVQgPSAnU2V0JztcblxuLy8gMjMuMiBTZXQgT2JqZWN0c1xubW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuL19jb2xsZWN0aW9uJykoU0VULCBmdW5jdGlvbiAoZ2V0KSB7XG4gIHJldHVybiBmdW5jdGlvbiBTZXQoKSB7IHJldHVybiBnZXQodGhpcywgYXJndW1lbnRzLmxlbmd0aCA+IDAgPyBhcmd1bWVudHNbMF0gOiB1bmRlZmluZWQpOyB9O1xufSwge1xuICAvLyAyMy4yLjMuMSBTZXQucHJvdG90eXBlLmFkZCh2YWx1ZSlcbiAgYWRkOiBmdW5jdGlvbiBhZGQodmFsdWUpIHtcbiAgICByZXR1cm4gc3Ryb25nLmRlZih2YWxpZGF0ZSh0aGlzLCBTRVQpLCB2YWx1ZSA9IHZhbHVlID09PSAwID8gMCA6IHZhbHVlLCB2YWx1ZSk7XG4gIH1cbn0sIHN0cm9uZyk7XG4iLCIndXNlIHN0cmljdCc7XG4vLyBCLjIuMy4yIFN0cmluZy5wcm90b3R5cGUuYW5jaG9yKG5hbWUpXG5yZXF1aXJlKCcuL19zdHJpbmctaHRtbCcpKCdhbmNob3InLCBmdW5jdGlvbiAoY3JlYXRlSFRNTCkge1xuICByZXR1cm4gZnVuY3Rpb24gYW5jaG9yKG5hbWUpIHtcbiAgICByZXR1cm4gY3JlYXRlSFRNTCh0aGlzLCAnYScsICduYW1lJywgbmFtZSk7XG4gIH07XG59KTtcbiIsIid1c2Ugc3RyaWN0Jztcbi8vIEIuMi4zLjMgU3RyaW5nLnByb3RvdHlwZS5iaWcoKVxucmVxdWlyZSgnLi9fc3RyaW5nLWh0bWwnKSgnYmlnJywgZnVuY3Rpb24gKGNyZWF0ZUhUTUwpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIGJpZygpIHtcbiAgICByZXR1cm4gY3JlYXRlSFRNTCh0aGlzLCAnYmlnJywgJycsICcnKTtcbiAgfTtcbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xuLy8gQi4yLjMuNCBTdHJpbmcucHJvdG90eXBlLmJsaW5rKClcbnJlcXVpcmUoJy4vX3N0cmluZy1odG1sJykoJ2JsaW5rJywgZnVuY3Rpb24gKGNyZWF0ZUhUTUwpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIGJsaW5rKCkge1xuICAgIHJldHVybiBjcmVhdGVIVE1MKHRoaXMsICdibGluaycsICcnLCAnJyk7XG4gIH07XG59KTtcbiIsIid1c2Ugc3RyaWN0Jztcbi8vIEIuMi4zLjUgU3RyaW5nLnByb3RvdHlwZS5ib2xkKClcbnJlcXVpcmUoJy4vX3N0cmluZy1odG1sJykoJ2JvbGQnLCBmdW5jdGlvbiAoY3JlYXRlSFRNTCkge1xuICByZXR1cm4gZnVuY3Rpb24gYm9sZCgpIHtcbiAgICByZXR1cm4gY3JlYXRlSFRNTCh0aGlzLCAnYicsICcnLCAnJyk7XG4gIH07XG59KTtcbiIsIid1c2Ugc3RyaWN0JztcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgJGF0ID0gcmVxdWlyZSgnLi9fc3RyaW5nLWF0JykoZmFsc2UpO1xuJGV4cG9ydCgkZXhwb3J0LlAsICdTdHJpbmcnLCB7XG4gIC8vIDIxLjEuMy4zIFN0cmluZy5wcm90b3R5cGUuY29kZVBvaW50QXQocG9zKVxuICBjb2RlUG9pbnRBdDogZnVuY3Rpb24gY29kZVBvaW50QXQocG9zKSB7XG4gICAgcmV0dXJuICRhdCh0aGlzLCBwb3MpO1xuICB9XG59KTtcbiIsIi8vIDIxLjEuMy42IFN0cmluZy5wcm90b3R5cGUuZW5kc1dpdGgoc2VhcmNoU3RyaW5nIFssIGVuZFBvc2l0aW9uXSlcbid1c2Ugc3RyaWN0JztcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgdG9MZW5ndGggPSByZXF1aXJlKCcuL190by1sZW5ndGgnKTtcbnZhciBjb250ZXh0ID0gcmVxdWlyZSgnLi9fc3RyaW5nLWNvbnRleHQnKTtcbnZhciBFTkRTX1dJVEggPSAnZW5kc1dpdGgnO1xudmFyICRlbmRzV2l0aCA9ICcnW0VORFNfV0lUSF07XG5cbiRleHBvcnQoJGV4cG9ydC5QICsgJGV4cG9ydC5GICogcmVxdWlyZSgnLi9fZmFpbHMtaXMtcmVnZXhwJykoRU5EU19XSVRIKSwgJ1N0cmluZycsIHtcbiAgZW5kc1dpdGg6IGZ1bmN0aW9uIGVuZHNXaXRoKHNlYXJjaFN0cmluZyAvKiAsIGVuZFBvc2l0aW9uID0gQGxlbmd0aCAqLykge1xuICAgIHZhciB0aGF0ID0gY29udGV4dCh0aGlzLCBzZWFyY2hTdHJpbmcsIEVORFNfV0lUSCk7XG4gICAgdmFyIGVuZFBvc2l0aW9uID0gYXJndW1lbnRzLmxlbmd0aCA+IDEgPyBhcmd1bWVudHNbMV0gOiB1bmRlZmluZWQ7XG4gICAgdmFyIGxlbiA9IHRvTGVuZ3RoKHRoYXQubGVuZ3RoKTtcbiAgICB2YXIgZW5kID0gZW5kUG9zaXRpb24gPT09IHVuZGVmaW5lZCA/IGxlbiA6IE1hdGgubWluKHRvTGVuZ3RoKGVuZFBvc2l0aW9uKSwgbGVuKTtcbiAgICB2YXIgc2VhcmNoID0gU3RyaW5nKHNlYXJjaFN0cmluZyk7XG4gICAgcmV0dXJuICRlbmRzV2l0aFxuICAgICAgPyAkZW5kc1dpdGguY2FsbCh0aGF0LCBzZWFyY2gsIGVuZClcbiAgICAgIDogdGhhdC5zbGljZShlbmQgLSBzZWFyY2gubGVuZ3RoLCBlbmQpID09PSBzZWFyY2g7XG4gIH1cbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xuLy8gQi4yLjMuNiBTdHJpbmcucHJvdG90eXBlLmZpeGVkKClcbnJlcXVpcmUoJy4vX3N0cmluZy1odG1sJykoJ2ZpeGVkJywgZnVuY3Rpb24gKGNyZWF0ZUhUTUwpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIGZpeGVkKCkge1xuICAgIHJldHVybiBjcmVhdGVIVE1MKHRoaXMsICd0dCcsICcnLCAnJyk7XG4gIH07XG59KTtcbiIsIid1c2Ugc3RyaWN0Jztcbi8vIEIuMi4zLjcgU3RyaW5nLnByb3RvdHlwZS5mb250Y29sb3IoY29sb3IpXG5yZXF1aXJlKCcuL19zdHJpbmctaHRtbCcpKCdmb250Y29sb3InLCBmdW5jdGlvbiAoY3JlYXRlSFRNTCkge1xuICByZXR1cm4gZnVuY3Rpb24gZm9udGNvbG9yKGNvbG9yKSB7XG4gICAgcmV0dXJuIGNyZWF0ZUhUTUwodGhpcywgJ2ZvbnQnLCAnY29sb3InLCBjb2xvcik7XG4gIH07XG59KTtcbiIsIid1c2Ugc3RyaWN0Jztcbi8vIEIuMi4zLjggU3RyaW5nLnByb3RvdHlwZS5mb250c2l6ZShzaXplKVxucmVxdWlyZSgnLi9fc3RyaW5nLWh0bWwnKSgnZm9udHNpemUnLCBmdW5jdGlvbiAoY3JlYXRlSFRNTCkge1xuICByZXR1cm4gZnVuY3Rpb24gZm9udHNpemUoc2l6ZSkge1xuICAgIHJldHVybiBjcmVhdGVIVE1MKHRoaXMsICdmb250JywgJ3NpemUnLCBzaXplKTtcbiAgfTtcbn0pO1xuIiwidmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciB0b0Fic29sdXRlSW5kZXggPSByZXF1aXJlKCcuL190by1hYnNvbHV0ZS1pbmRleCcpO1xudmFyIGZyb21DaGFyQ29kZSA9IFN0cmluZy5mcm9tQ2hhckNvZGU7XG52YXIgJGZyb21Db2RlUG9pbnQgPSBTdHJpbmcuZnJvbUNvZGVQb2ludDtcblxuLy8gbGVuZ3RoIHNob3VsZCBiZSAxLCBvbGQgRkYgcHJvYmxlbVxuJGV4cG9ydCgkZXhwb3J0LlMgKyAkZXhwb3J0LkYgKiAoISEkZnJvbUNvZGVQb2ludCAmJiAkZnJvbUNvZGVQb2ludC5sZW5ndGggIT0gMSksICdTdHJpbmcnLCB7XG4gIC8vIDIxLjEuMi4yIFN0cmluZy5mcm9tQ29kZVBvaW50KC4uLmNvZGVQb2ludHMpXG4gIGZyb21Db2RlUG9pbnQ6IGZ1bmN0aW9uIGZyb21Db2RlUG9pbnQoeCkgeyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXVudXNlZC12YXJzXG4gICAgdmFyIHJlcyA9IFtdO1xuICAgIHZhciBhTGVuID0gYXJndW1lbnRzLmxlbmd0aDtcbiAgICB2YXIgaSA9IDA7XG4gICAgdmFyIGNvZGU7XG4gICAgd2hpbGUgKGFMZW4gPiBpKSB7XG4gICAgICBjb2RlID0gK2FyZ3VtZW50c1tpKytdO1xuICAgICAgaWYgKHRvQWJzb2x1dGVJbmRleChjb2RlLCAweDEwZmZmZikgIT09IGNvZGUpIHRocm93IFJhbmdlRXJyb3IoY29kZSArICcgaXMgbm90IGEgdmFsaWQgY29kZSBwb2ludCcpO1xuICAgICAgcmVzLnB1c2goY29kZSA8IDB4MTAwMDBcbiAgICAgICAgPyBmcm9tQ2hhckNvZGUoY29kZSlcbiAgICAgICAgOiBmcm9tQ2hhckNvZGUoKChjb2RlIC09IDB4MTAwMDApID4+IDEwKSArIDB4ZDgwMCwgY29kZSAlIDB4NDAwICsgMHhkYzAwKVxuICAgICAgKTtcbiAgICB9IHJldHVybiByZXMuam9pbignJyk7XG4gIH1cbn0pO1xuIiwiLy8gMjEuMS4zLjcgU3RyaW5nLnByb3RvdHlwZS5pbmNsdWRlcyhzZWFyY2hTdHJpbmcsIHBvc2l0aW9uID0gMClcbid1c2Ugc3RyaWN0JztcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgY29udGV4dCA9IHJlcXVpcmUoJy4vX3N0cmluZy1jb250ZXh0Jyk7XG52YXIgSU5DTFVERVMgPSAnaW5jbHVkZXMnO1xuXG4kZXhwb3J0KCRleHBvcnQuUCArICRleHBvcnQuRiAqIHJlcXVpcmUoJy4vX2ZhaWxzLWlzLXJlZ2V4cCcpKElOQ0xVREVTKSwgJ1N0cmluZycsIHtcbiAgaW5jbHVkZXM6IGZ1bmN0aW9uIGluY2x1ZGVzKHNlYXJjaFN0cmluZyAvKiAsIHBvc2l0aW9uID0gMCAqLykge1xuICAgIHJldHVybiAhIX5jb250ZXh0KHRoaXMsIHNlYXJjaFN0cmluZywgSU5DTFVERVMpXG4gICAgICAuaW5kZXhPZihzZWFyY2hTdHJpbmcsIGFyZ3VtZW50cy5sZW5ndGggPiAxID8gYXJndW1lbnRzWzFdIDogdW5kZWZpbmVkKTtcbiAgfVxufSk7XG4iLCIndXNlIHN0cmljdCc7XG4vLyBCLjIuMy45IFN0cmluZy5wcm90b3R5cGUuaXRhbGljcygpXG5yZXF1aXJlKCcuL19zdHJpbmctaHRtbCcpKCdpdGFsaWNzJywgZnVuY3Rpb24gKGNyZWF0ZUhUTUwpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIGl0YWxpY3MoKSB7XG4gICAgcmV0dXJuIGNyZWF0ZUhUTUwodGhpcywgJ2knLCAnJywgJycpO1xuICB9O1xufSk7XG4iLCIndXNlIHN0cmljdCc7XG52YXIgJGF0ID0gcmVxdWlyZSgnLi9fc3RyaW5nLWF0JykodHJ1ZSk7XG5cbi8vIDIxLjEuMy4yNyBTdHJpbmcucHJvdG90eXBlW0BAaXRlcmF0b3JdKClcbnJlcXVpcmUoJy4vX2l0ZXItZGVmaW5lJykoU3RyaW5nLCAnU3RyaW5nJywgZnVuY3Rpb24gKGl0ZXJhdGVkKSB7XG4gIHRoaXMuX3QgPSBTdHJpbmcoaXRlcmF0ZWQpOyAvLyB0YXJnZXRcbiAgdGhpcy5faSA9IDA7ICAgICAgICAgICAgICAgIC8vIG5leHQgaW5kZXhcbi8vIDIxLjEuNS4yLjEgJVN0cmluZ0l0ZXJhdG9yUHJvdG90eXBlJS5uZXh0KClcbn0sIGZ1bmN0aW9uICgpIHtcbiAgdmFyIE8gPSB0aGlzLl90O1xuICB2YXIgaW5kZXggPSB0aGlzLl9pO1xuICB2YXIgcG9pbnQ7XG4gIGlmIChpbmRleCA+PSBPLmxlbmd0aCkgcmV0dXJuIHsgdmFsdWU6IHVuZGVmaW5lZCwgZG9uZTogdHJ1ZSB9O1xuICBwb2ludCA9ICRhdChPLCBpbmRleCk7XG4gIHRoaXMuX2kgKz0gcG9pbnQubGVuZ3RoO1xuICByZXR1cm4geyB2YWx1ZTogcG9pbnQsIGRvbmU6IGZhbHNlIH07XG59KTtcbiIsIid1c2Ugc3RyaWN0Jztcbi8vIEIuMi4zLjEwIFN0cmluZy5wcm90b3R5cGUubGluayh1cmwpXG5yZXF1aXJlKCcuL19zdHJpbmctaHRtbCcpKCdsaW5rJywgZnVuY3Rpb24gKGNyZWF0ZUhUTUwpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIGxpbmsodXJsKSB7XG4gICAgcmV0dXJuIGNyZWF0ZUhUTUwodGhpcywgJ2EnLCAnaHJlZicsIHVybCk7XG4gIH07XG59KTtcbiIsInZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgdG9JT2JqZWN0ID0gcmVxdWlyZSgnLi9fdG8taW9iamVjdCcpO1xudmFyIHRvTGVuZ3RoID0gcmVxdWlyZSgnLi9fdG8tbGVuZ3RoJyk7XG5cbiRleHBvcnQoJGV4cG9ydC5TLCAnU3RyaW5nJywge1xuICAvLyAyMS4xLjIuNCBTdHJpbmcucmF3KGNhbGxTaXRlLCAuLi5zdWJzdGl0dXRpb25zKVxuICByYXc6IGZ1bmN0aW9uIHJhdyhjYWxsU2l0ZSkge1xuICAgIHZhciB0cGwgPSB0b0lPYmplY3QoY2FsbFNpdGUucmF3KTtcbiAgICB2YXIgbGVuID0gdG9MZW5ndGgodHBsLmxlbmd0aCk7XG4gICAgdmFyIGFMZW4gPSBhcmd1bWVudHMubGVuZ3RoO1xuICAgIHZhciByZXMgPSBbXTtcbiAgICB2YXIgaSA9IDA7XG4gICAgd2hpbGUgKGxlbiA+IGkpIHtcbiAgICAgIHJlcy5wdXNoKFN0cmluZyh0cGxbaSsrXSkpO1xuICAgICAgaWYgKGkgPCBhTGVuKSByZXMucHVzaChTdHJpbmcoYXJndW1lbnRzW2ldKSk7XG4gICAgfSByZXR1cm4gcmVzLmpvaW4oJycpO1xuICB9XG59KTtcbiIsInZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG5cbiRleHBvcnQoJGV4cG9ydC5QLCAnU3RyaW5nJywge1xuICAvLyAyMS4xLjMuMTMgU3RyaW5nLnByb3RvdHlwZS5yZXBlYXQoY291bnQpXG4gIHJlcGVhdDogcmVxdWlyZSgnLi9fc3RyaW5nLXJlcGVhdCcpXG59KTtcbiIsIid1c2Ugc3RyaWN0Jztcbi8vIEIuMi4zLjExIFN0cmluZy5wcm90b3R5cGUuc21hbGwoKVxucmVxdWlyZSgnLi9fc3RyaW5nLWh0bWwnKSgnc21hbGwnLCBmdW5jdGlvbiAoY3JlYXRlSFRNTCkge1xuICByZXR1cm4gZnVuY3Rpb24gc21hbGwoKSB7XG4gICAgcmV0dXJuIGNyZWF0ZUhUTUwodGhpcywgJ3NtYWxsJywgJycsICcnKTtcbiAgfTtcbn0pO1xuIiwiLy8gMjEuMS4zLjE4IFN0cmluZy5wcm90b3R5cGUuc3RhcnRzV2l0aChzZWFyY2hTdHJpbmcgWywgcG9zaXRpb24gXSlcbid1c2Ugc3RyaWN0JztcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgdG9MZW5ndGggPSByZXF1aXJlKCcuL190by1sZW5ndGgnKTtcbnZhciBjb250ZXh0ID0gcmVxdWlyZSgnLi9fc3RyaW5nLWNvbnRleHQnKTtcbnZhciBTVEFSVFNfV0lUSCA9ICdzdGFydHNXaXRoJztcbnZhciAkc3RhcnRzV2l0aCA9ICcnW1NUQVJUU19XSVRIXTtcblxuJGV4cG9ydCgkZXhwb3J0LlAgKyAkZXhwb3J0LkYgKiByZXF1aXJlKCcuL19mYWlscy1pcy1yZWdleHAnKShTVEFSVFNfV0lUSCksICdTdHJpbmcnLCB7XG4gIHN0YXJ0c1dpdGg6IGZ1bmN0aW9uIHN0YXJ0c1dpdGgoc2VhcmNoU3RyaW5nIC8qICwgcG9zaXRpb24gPSAwICovKSB7XG4gICAgdmFyIHRoYXQgPSBjb250ZXh0KHRoaXMsIHNlYXJjaFN0cmluZywgU1RBUlRTX1dJVEgpO1xuICAgIHZhciBpbmRleCA9IHRvTGVuZ3RoKE1hdGgubWluKGFyZ3VtZW50cy5sZW5ndGggPiAxID8gYXJndW1lbnRzWzFdIDogdW5kZWZpbmVkLCB0aGF0Lmxlbmd0aCkpO1xuICAgIHZhciBzZWFyY2ggPSBTdHJpbmcoc2VhcmNoU3RyaW5nKTtcbiAgICByZXR1cm4gJHN0YXJ0c1dpdGhcbiAgICAgID8gJHN0YXJ0c1dpdGguY2FsbCh0aGF0LCBzZWFyY2gsIGluZGV4KVxuICAgICAgOiB0aGF0LnNsaWNlKGluZGV4LCBpbmRleCArIHNlYXJjaC5sZW5ndGgpID09PSBzZWFyY2g7XG4gIH1cbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xuLy8gQi4yLjMuMTIgU3RyaW5nLnByb3RvdHlwZS5zdHJpa2UoKVxucmVxdWlyZSgnLi9fc3RyaW5nLWh0bWwnKSgnc3RyaWtlJywgZnVuY3Rpb24gKGNyZWF0ZUhUTUwpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIHN0cmlrZSgpIHtcbiAgICByZXR1cm4gY3JlYXRlSFRNTCh0aGlzLCAnc3RyaWtlJywgJycsICcnKTtcbiAgfTtcbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xuLy8gQi4yLjMuMTMgU3RyaW5nLnByb3RvdHlwZS5zdWIoKVxucmVxdWlyZSgnLi9fc3RyaW5nLWh0bWwnKSgnc3ViJywgZnVuY3Rpb24gKGNyZWF0ZUhUTUwpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIHN1YigpIHtcbiAgICByZXR1cm4gY3JlYXRlSFRNTCh0aGlzLCAnc3ViJywgJycsICcnKTtcbiAgfTtcbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xuLy8gQi4yLjMuMTQgU3RyaW5nLnByb3RvdHlwZS5zdXAoKVxucmVxdWlyZSgnLi9fc3RyaW5nLWh0bWwnKSgnc3VwJywgZnVuY3Rpb24gKGNyZWF0ZUhUTUwpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIHN1cCgpIHtcbiAgICByZXR1cm4gY3JlYXRlSFRNTCh0aGlzLCAnc3VwJywgJycsICcnKTtcbiAgfTtcbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xuLy8gMjEuMS4zLjI1IFN0cmluZy5wcm90b3R5cGUudHJpbSgpXG5yZXF1aXJlKCcuL19zdHJpbmctdHJpbScpKCd0cmltJywgZnVuY3Rpb24gKCR0cmltKSB7XG4gIHJldHVybiBmdW5jdGlvbiB0cmltKCkge1xuICAgIHJldHVybiAkdHJpbSh0aGlzLCAzKTtcbiAgfTtcbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xuLy8gRUNNQVNjcmlwdCA2IHN5bWJvbHMgc2hpbVxudmFyIGdsb2JhbCA9IHJlcXVpcmUoJy4vX2dsb2JhbCcpO1xudmFyIGhhcyA9IHJlcXVpcmUoJy4vX2hhcycpO1xudmFyIERFU0NSSVBUT1JTID0gcmVxdWlyZSgnLi9fZGVzY3JpcHRvcnMnKTtcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgcmVkZWZpbmUgPSByZXF1aXJlKCcuL19yZWRlZmluZScpO1xudmFyIE1FVEEgPSByZXF1aXJlKCcuL19tZXRhJykuS0VZO1xudmFyICRmYWlscyA9IHJlcXVpcmUoJy4vX2ZhaWxzJyk7XG52YXIgc2hhcmVkID0gcmVxdWlyZSgnLi9fc2hhcmVkJyk7XG52YXIgc2V0VG9TdHJpbmdUYWcgPSByZXF1aXJlKCcuL19zZXQtdG8tc3RyaW5nLXRhZycpO1xudmFyIHVpZCA9IHJlcXVpcmUoJy4vX3VpZCcpO1xudmFyIHdrcyA9IHJlcXVpcmUoJy4vX3drcycpO1xudmFyIHdrc0V4dCA9IHJlcXVpcmUoJy4vX3drcy1leHQnKTtcbnZhciB3a3NEZWZpbmUgPSByZXF1aXJlKCcuL193a3MtZGVmaW5lJyk7XG52YXIgZW51bUtleXMgPSByZXF1aXJlKCcuL19lbnVtLWtleXMnKTtcbnZhciBpc0FycmF5ID0gcmVxdWlyZSgnLi9faXMtYXJyYXknKTtcbnZhciBhbk9iamVjdCA9IHJlcXVpcmUoJy4vX2FuLW9iamVjdCcpO1xudmFyIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi9faXMtb2JqZWN0Jyk7XG52YXIgdG9JT2JqZWN0ID0gcmVxdWlyZSgnLi9fdG8taW9iamVjdCcpO1xudmFyIHRvUHJpbWl0aXZlID0gcmVxdWlyZSgnLi9fdG8tcHJpbWl0aXZlJyk7XG52YXIgY3JlYXRlRGVzYyA9IHJlcXVpcmUoJy4vX3Byb3BlcnR5LWRlc2MnKTtcbnZhciBfY3JlYXRlID0gcmVxdWlyZSgnLi9fb2JqZWN0LWNyZWF0ZScpO1xudmFyIGdPUE5FeHQgPSByZXF1aXJlKCcuL19vYmplY3QtZ29wbi1leHQnKTtcbnZhciAkR09QRCA9IHJlcXVpcmUoJy4vX29iamVjdC1nb3BkJyk7XG52YXIgJERQID0gcmVxdWlyZSgnLi9fb2JqZWN0LWRwJyk7XG52YXIgJGtleXMgPSByZXF1aXJlKCcuL19vYmplY3Qta2V5cycpO1xudmFyIGdPUEQgPSAkR09QRC5mO1xudmFyIGRQID0gJERQLmY7XG52YXIgZ09QTiA9IGdPUE5FeHQuZjtcbnZhciAkU3ltYm9sID0gZ2xvYmFsLlN5bWJvbDtcbnZhciAkSlNPTiA9IGdsb2JhbC5KU09OO1xudmFyIF9zdHJpbmdpZnkgPSAkSlNPTiAmJiAkSlNPTi5zdHJpbmdpZnk7XG52YXIgUFJPVE9UWVBFID0gJ3Byb3RvdHlwZSc7XG52YXIgSElEREVOID0gd2tzKCdfaGlkZGVuJyk7XG52YXIgVE9fUFJJTUlUSVZFID0gd2tzKCd0b1ByaW1pdGl2ZScpO1xudmFyIGlzRW51bSA9IHt9LnByb3BlcnR5SXNFbnVtZXJhYmxlO1xudmFyIFN5bWJvbFJlZ2lzdHJ5ID0gc2hhcmVkKCdzeW1ib2wtcmVnaXN0cnknKTtcbnZhciBBbGxTeW1ib2xzID0gc2hhcmVkKCdzeW1ib2xzJyk7XG52YXIgT1BTeW1ib2xzID0gc2hhcmVkKCdvcC1zeW1ib2xzJyk7XG52YXIgT2JqZWN0UHJvdG8gPSBPYmplY3RbUFJPVE9UWVBFXTtcbnZhciBVU0VfTkFUSVZFID0gdHlwZW9mICRTeW1ib2wgPT0gJ2Z1bmN0aW9uJztcbnZhciBRT2JqZWN0ID0gZ2xvYmFsLlFPYmplY3Q7XG4vLyBEb24ndCB1c2Ugc2V0dGVycyBpbiBRdCBTY3JpcHQsIGh0dHBzOi8vZ2l0aHViLmNvbS96bG9pcm9jay9jb3JlLWpzL2lzc3Vlcy8xNzNcbnZhciBzZXR0ZXIgPSAhUU9iamVjdCB8fCAhUU9iamVjdFtQUk9UT1RZUEVdIHx8ICFRT2JqZWN0W1BST1RPVFlQRV0uZmluZENoaWxkO1xuXG4vLyBmYWxsYmFjayBmb3Igb2xkIEFuZHJvaWQsIGh0dHBzOi8vY29kZS5nb29nbGUuY29tL3AvdjgvaXNzdWVzL2RldGFpbD9pZD02ODdcbnZhciBzZXRTeW1ib2xEZXNjID0gREVTQ1JJUFRPUlMgJiYgJGZhaWxzKGZ1bmN0aW9uICgpIHtcbiAgcmV0dXJuIF9jcmVhdGUoZFAoe30sICdhJywge1xuICAgIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gZFAodGhpcywgJ2EnLCB7IHZhbHVlOiA3IH0pLmE7IH1cbiAgfSkpLmEgIT0gNztcbn0pID8gZnVuY3Rpb24gKGl0LCBrZXksIEQpIHtcbiAgdmFyIHByb3RvRGVzYyA9IGdPUEQoT2JqZWN0UHJvdG8sIGtleSk7XG4gIGlmIChwcm90b0Rlc2MpIGRlbGV0ZSBPYmplY3RQcm90b1trZXldO1xuICBkUChpdCwga2V5LCBEKTtcbiAgaWYgKHByb3RvRGVzYyAmJiBpdCAhPT0gT2JqZWN0UHJvdG8pIGRQKE9iamVjdFByb3RvLCBrZXksIHByb3RvRGVzYyk7XG59IDogZFA7XG5cbnZhciB3cmFwID0gZnVuY3Rpb24gKHRhZykge1xuICB2YXIgc3ltID0gQWxsU3ltYm9sc1t0YWddID0gX2NyZWF0ZSgkU3ltYm9sW1BST1RPVFlQRV0pO1xuICBzeW0uX2sgPSB0YWc7XG4gIHJldHVybiBzeW07XG59O1xuXG52YXIgaXNTeW1ib2wgPSBVU0VfTkFUSVZFICYmIHR5cGVvZiAkU3ltYm9sLml0ZXJhdG9yID09ICdzeW1ib2wnID8gZnVuY3Rpb24gKGl0KSB7XG4gIHJldHVybiB0eXBlb2YgaXQgPT0gJ3N5bWJvbCc7XG59IDogZnVuY3Rpb24gKGl0KSB7XG4gIHJldHVybiBpdCBpbnN0YW5jZW9mICRTeW1ib2w7XG59O1xuXG52YXIgJGRlZmluZVByb3BlcnR5ID0gZnVuY3Rpb24gZGVmaW5lUHJvcGVydHkoaXQsIGtleSwgRCkge1xuICBpZiAoaXQgPT09IE9iamVjdFByb3RvKSAkZGVmaW5lUHJvcGVydHkoT1BTeW1ib2xzLCBrZXksIEQpO1xuICBhbk9iamVjdChpdCk7XG4gIGtleSA9IHRvUHJpbWl0aXZlKGtleSwgdHJ1ZSk7XG4gIGFuT2JqZWN0KEQpO1xuICBpZiAoaGFzKEFsbFN5bWJvbHMsIGtleSkpIHtcbiAgICBpZiAoIUQuZW51bWVyYWJsZSkge1xuICAgICAgaWYgKCFoYXMoaXQsIEhJRERFTikpIGRQKGl0LCBISURERU4sIGNyZWF0ZURlc2MoMSwge30pKTtcbiAgICAgIGl0W0hJRERFTl1ba2V5XSA9IHRydWU7XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmIChoYXMoaXQsIEhJRERFTikgJiYgaXRbSElEREVOXVtrZXldKSBpdFtISURERU5dW2tleV0gPSBmYWxzZTtcbiAgICAgIEQgPSBfY3JlYXRlKEQsIHsgZW51bWVyYWJsZTogY3JlYXRlRGVzYygwLCBmYWxzZSkgfSk7XG4gICAgfSByZXR1cm4gc2V0U3ltYm9sRGVzYyhpdCwga2V5LCBEKTtcbiAgfSByZXR1cm4gZFAoaXQsIGtleSwgRCk7XG59O1xudmFyICRkZWZpbmVQcm9wZXJ0aWVzID0gZnVuY3Rpb24gZGVmaW5lUHJvcGVydGllcyhpdCwgUCkge1xuICBhbk9iamVjdChpdCk7XG4gIHZhciBrZXlzID0gZW51bUtleXMoUCA9IHRvSU9iamVjdChQKSk7XG4gIHZhciBpID0gMDtcbiAgdmFyIGwgPSBrZXlzLmxlbmd0aDtcbiAgdmFyIGtleTtcbiAgd2hpbGUgKGwgPiBpKSAkZGVmaW5lUHJvcGVydHkoaXQsIGtleSA9IGtleXNbaSsrXSwgUFtrZXldKTtcbiAgcmV0dXJuIGl0O1xufTtcbnZhciAkY3JlYXRlID0gZnVuY3Rpb24gY3JlYXRlKGl0LCBQKSB7XG4gIHJldHVybiBQID09PSB1bmRlZmluZWQgPyBfY3JlYXRlKGl0KSA6ICRkZWZpbmVQcm9wZXJ0aWVzKF9jcmVhdGUoaXQpLCBQKTtcbn07XG52YXIgJHByb3BlcnR5SXNFbnVtZXJhYmxlID0gZnVuY3Rpb24gcHJvcGVydHlJc0VudW1lcmFibGUoa2V5KSB7XG4gIHZhciBFID0gaXNFbnVtLmNhbGwodGhpcywga2V5ID0gdG9QcmltaXRpdmUoa2V5LCB0cnVlKSk7XG4gIGlmICh0aGlzID09PSBPYmplY3RQcm90byAmJiBoYXMoQWxsU3ltYm9scywga2V5KSAmJiAhaGFzKE9QU3ltYm9scywga2V5KSkgcmV0dXJuIGZhbHNlO1xuICByZXR1cm4gRSB8fCAhaGFzKHRoaXMsIGtleSkgfHwgIWhhcyhBbGxTeW1ib2xzLCBrZXkpIHx8IGhhcyh0aGlzLCBISURERU4pICYmIHRoaXNbSElEREVOXVtrZXldID8gRSA6IHRydWU7XG59O1xudmFyICRnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IgPSBmdW5jdGlvbiBnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IoaXQsIGtleSkge1xuICBpdCA9IHRvSU9iamVjdChpdCk7XG4gIGtleSA9IHRvUHJpbWl0aXZlKGtleSwgdHJ1ZSk7XG4gIGlmIChpdCA9PT0gT2JqZWN0UHJvdG8gJiYgaGFzKEFsbFN5bWJvbHMsIGtleSkgJiYgIWhhcyhPUFN5bWJvbHMsIGtleSkpIHJldHVybjtcbiAgdmFyIEQgPSBnT1BEKGl0LCBrZXkpO1xuICBpZiAoRCAmJiBoYXMoQWxsU3ltYm9scywga2V5KSAmJiAhKGhhcyhpdCwgSElEREVOKSAmJiBpdFtISURERU5dW2tleV0pKSBELmVudW1lcmFibGUgPSB0cnVlO1xuICByZXR1cm4gRDtcbn07XG52YXIgJGdldE93blByb3BlcnR5TmFtZXMgPSBmdW5jdGlvbiBnZXRPd25Qcm9wZXJ0eU5hbWVzKGl0KSB7XG4gIHZhciBuYW1lcyA9IGdPUE4odG9JT2JqZWN0KGl0KSk7XG4gIHZhciByZXN1bHQgPSBbXTtcbiAgdmFyIGkgPSAwO1xuICB2YXIga2V5O1xuICB3aGlsZSAobmFtZXMubGVuZ3RoID4gaSkge1xuICAgIGlmICghaGFzKEFsbFN5bWJvbHMsIGtleSA9IG5hbWVzW2krK10pICYmIGtleSAhPSBISURERU4gJiYga2V5ICE9IE1FVEEpIHJlc3VsdC5wdXNoKGtleSk7XG4gIH0gcmV0dXJuIHJlc3VsdDtcbn07XG52YXIgJGdldE93blByb3BlcnR5U3ltYm9scyA9IGZ1bmN0aW9uIGdldE93blByb3BlcnR5U3ltYm9scyhpdCkge1xuICB2YXIgSVNfT1AgPSBpdCA9PT0gT2JqZWN0UHJvdG87XG4gIHZhciBuYW1lcyA9IGdPUE4oSVNfT1AgPyBPUFN5bWJvbHMgOiB0b0lPYmplY3QoaXQpKTtcbiAgdmFyIHJlc3VsdCA9IFtdO1xuICB2YXIgaSA9IDA7XG4gIHZhciBrZXk7XG4gIHdoaWxlIChuYW1lcy5sZW5ndGggPiBpKSB7XG4gICAgaWYgKGhhcyhBbGxTeW1ib2xzLCBrZXkgPSBuYW1lc1tpKytdKSAmJiAoSVNfT1AgPyBoYXMoT2JqZWN0UHJvdG8sIGtleSkgOiB0cnVlKSkgcmVzdWx0LnB1c2goQWxsU3ltYm9sc1trZXldKTtcbiAgfSByZXR1cm4gcmVzdWx0O1xufTtcblxuLy8gMTkuNC4xLjEgU3ltYm9sKFtkZXNjcmlwdGlvbl0pXG5pZiAoIVVTRV9OQVRJVkUpIHtcbiAgJFN5bWJvbCA9IGZ1bmN0aW9uIFN5bWJvbCgpIHtcbiAgICBpZiAodGhpcyBpbnN0YW5jZW9mICRTeW1ib2wpIHRocm93IFR5cGVFcnJvcignU3ltYm9sIGlzIG5vdCBhIGNvbnN0cnVjdG9yIScpO1xuICAgIHZhciB0YWcgPSB1aWQoYXJndW1lbnRzLmxlbmd0aCA+IDAgPyBhcmd1bWVudHNbMF0gOiB1bmRlZmluZWQpO1xuICAgIHZhciAkc2V0ID0gZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICBpZiAodGhpcyA9PT0gT2JqZWN0UHJvdG8pICRzZXQuY2FsbChPUFN5bWJvbHMsIHZhbHVlKTtcbiAgICAgIGlmIChoYXModGhpcywgSElEREVOKSAmJiBoYXModGhpc1tISURERU5dLCB0YWcpKSB0aGlzW0hJRERFTl1bdGFnXSA9IGZhbHNlO1xuICAgICAgc2V0U3ltYm9sRGVzYyh0aGlzLCB0YWcsIGNyZWF0ZURlc2MoMSwgdmFsdWUpKTtcbiAgICB9O1xuICAgIGlmIChERVNDUklQVE9SUyAmJiBzZXR0ZXIpIHNldFN5bWJvbERlc2MoT2JqZWN0UHJvdG8sIHRhZywgeyBjb25maWd1cmFibGU6IHRydWUsIHNldDogJHNldCB9KTtcbiAgICByZXR1cm4gd3JhcCh0YWcpO1xuICB9O1xuICByZWRlZmluZSgkU3ltYm9sW1BST1RPVFlQRV0sICd0b1N0cmluZycsIGZ1bmN0aW9uIHRvU3RyaW5nKCkge1xuICAgIHJldHVybiB0aGlzLl9rO1xuICB9KTtcblxuICAkR09QRC5mID0gJGdldE93blByb3BlcnR5RGVzY3JpcHRvcjtcbiAgJERQLmYgPSAkZGVmaW5lUHJvcGVydHk7XG4gIHJlcXVpcmUoJy4vX29iamVjdC1nb3BuJykuZiA9IGdPUE5FeHQuZiA9ICRnZXRPd25Qcm9wZXJ0eU5hbWVzO1xuICByZXF1aXJlKCcuL19vYmplY3QtcGllJykuZiA9ICRwcm9wZXJ0eUlzRW51bWVyYWJsZTtcbiAgcmVxdWlyZSgnLi9fb2JqZWN0LWdvcHMnKS5mID0gJGdldE93blByb3BlcnR5U3ltYm9scztcblxuICBpZiAoREVTQ1JJUFRPUlMgJiYgIXJlcXVpcmUoJy4vX2xpYnJhcnknKSkge1xuICAgIHJlZGVmaW5lKE9iamVjdFByb3RvLCAncHJvcGVydHlJc0VudW1lcmFibGUnLCAkcHJvcGVydHlJc0VudW1lcmFibGUsIHRydWUpO1xuICB9XG5cbiAgd2tzRXh0LmYgPSBmdW5jdGlvbiAobmFtZSkge1xuICAgIHJldHVybiB3cmFwKHdrcyhuYW1lKSk7XG4gIH07XG59XG5cbiRleHBvcnQoJGV4cG9ydC5HICsgJGV4cG9ydC5XICsgJGV4cG9ydC5GICogIVVTRV9OQVRJVkUsIHsgU3ltYm9sOiAkU3ltYm9sIH0pO1xuXG5mb3IgKHZhciBlczZTeW1ib2xzID0gKFxuICAvLyAxOS40LjIuMiwgMTkuNC4yLjMsIDE5LjQuMi40LCAxOS40LjIuNiwgMTkuNC4yLjgsIDE5LjQuMi45LCAxOS40LjIuMTAsIDE5LjQuMi4xMSwgMTkuNC4yLjEyLCAxOS40LjIuMTMsIDE5LjQuMi4xNFxuICAnaGFzSW5zdGFuY2UsaXNDb25jYXRTcHJlYWRhYmxlLGl0ZXJhdG9yLG1hdGNoLHJlcGxhY2Usc2VhcmNoLHNwZWNpZXMsc3BsaXQsdG9QcmltaXRpdmUsdG9TdHJpbmdUYWcsdW5zY29wYWJsZXMnXG4pLnNwbGl0KCcsJyksIGogPSAwOyBlczZTeW1ib2xzLmxlbmd0aCA+IGo7KXdrcyhlczZTeW1ib2xzW2orK10pO1xuXG5mb3IgKHZhciB3ZWxsS25vd25TeW1ib2xzID0gJGtleXMod2tzLnN0b3JlKSwgayA9IDA7IHdlbGxLbm93blN5bWJvbHMubGVuZ3RoID4gazspIHdrc0RlZmluZSh3ZWxsS25vd25TeW1ib2xzW2srK10pO1xuXG4kZXhwb3J0KCRleHBvcnQuUyArICRleHBvcnQuRiAqICFVU0VfTkFUSVZFLCAnU3ltYm9sJywge1xuICAvLyAxOS40LjIuMSBTeW1ib2wuZm9yKGtleSlcbiAgJ2Zvcic6IGZ1bmN0aW9uIChrZXkpIHtcbiAgICByZXR1cm4gaGFzKFN5bWJvbFJlZ2lzdHJ5LCBrZXkgKz0gJycpXG4gICAgICA/IFN5bWJvbFJlZ2lzdHJ5W2tleV1cbiAgICAgIDogU3ltYm9sUmVnaXN0cnlba2V5XSA9ICRTeW1ib2woa2V5KTtcbiAgfSxcbiAgLy8gMTkuNC4yLjUgU3ltYm9sLmtleUZvcihzeW0pXG4gIGtleUZvcjogZnVuY3Rpb24ga2V5Rm9yKHN5bSkge1xuICAgIGlmICghaXNTeW1ib2woc3ltKSkgdGhyb3cgVHlwZUVycm9yKHN5bSArICcgaXMgbm90IGEgc3ltYm9sIScpO1xuICAgIGZvciAodmFyIGtleSBpbiBTeW1ib2xSZWdpc3RyeSkgaWYgKFN5bWJvbFJlZ2lzdHJ5W2tleV0gPT09IHN5bSkgcmV0dXJuIGtleTtcbiAgfSxcbiAgdXNlU2V0dGVyOiBmdW5jdGlvbiAoKSB7IHNldHRlciA9IHRydWU7IH0sXG4gIHVzZVNpbXBsZTogZnVuY3Rpb24gKCkgeyBzZXR0ZXIgPSBmYWxzZTsgfVxufSk7XG5cbiRleHBvcnQoJGV4cG9ydC5TICsgJGV4cG9ydC5GICogIVVTRV9OQVRJVkUsICdPYmplY3QnLCB7XG4gIC8vIDE5LjEuMi4yIE9iamVjdC5jcmVhdGUoTyBbLCBQcm9wZXJ0aWVzXSlcbiAgY3JlYXRlOiAkY3JlYXRlLFxuICAvLyAxOS4xLjIuNCBPYmplY3QuZGVmaW5lUHJvcGVydHkoTywgUCwgQXR0cmlidXRlcylcbiAgZGVmaW5lUHJvcGVydHk6ICRkZWZpbmVQcm9wZXJ0eSxcbiAgLy8gMTkuMS4yLjMgT2JqZWN0LmRlZmluZVByb3BlcnRpZXMoTywgUHJvcGVydGllcylcbiAgZGVmaW5lUHJvcGVydGllczogJGRlZmluZVByb3BlcnRpZXMsXG4gIC8vIDE5LjEuMi42IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IoTywgUClcbiAgZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yOiAkZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yLFxuICAvLyAxOS4xLjIuNyBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyhPKVxuICBnZXRPd25Qcm9wZXJ0eU5hbWVzOiAkZ2V0T3duUHJvcGVydHlOYW1lcyxcbiAgLy8gMTkuMS4yLjggT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scyhPKVxuICBnZXRPd25Qcm9wZXJ0eVN5bWJvbHM6ICRnZXRPd25Qcm9wZXJ0eVN5bWJvbHNcbn0pO1xuXG4vLyAyNC4zLjIgSlNPTi5zdHJpbmdpZnkodmFsdWUgWywgcmVwbGFjZXIgWywgc3BhY2VdXSlcbiRKU09OICYmICRleHBvcnQoJGV4cG9ydC5TICsgJGV4cG9ydC5GICogKCFVU0VfTkFUSVZFIHx8ICRmYWlscyhmdW5jdGlvbiAoKSB7XG4gIHZhciBTID0gJFN5bWJvbCgpO1xuICAvLyBNUyBFZGdlIGNvbnZlcnRzIHN5bWJvbCB2YWx1ZXMgdG8gSlNPTiBhcyB7fVxuICAvLyBXZWJLaXQgY29udmVydHMgc3ltYm9sIHZhbHVlcyB0byBKU09OIGFzIG51bGxcbiAgLy8gVjggdGhyb3dzIG9uIGJveGVkIHN5bWJvbHNcbiAgcmV0dXJuIF9zdHJpbmdpZnkoW1NdKSAhPSAnW251bGxdJyB8fCBfc3RyaW5naWZ5KHsgYTogUyB9KSAhPSAne30nIHx8IF9zdHJpbmdpZnkoT2JqZWN0KFMpKSAhPSAne30nO1xufSkpLCAnSlNPTicsIHtcbiAgc3RyaW5naWZ5OiBmdW5jdGlvbiBzdHJpbmdpZnkoaXQpIHtcbiAgICB2YXIgYXJncyA9IFtpdF07XG4gICAgdmFyIGkgPSAxO1xuICAgIHZhciByZXBsYWNlciwgJHJlcGxhY2VyO1xuICAgIHdoaWxlIChhcmd1bWVudHMubGVuZ3RoID4gaSkgYXJncy5wdXNoKGFyZ3VtZW50c1tpKytdKTtcbiAgICAkcmVwbGFjZXIgPSByZXBsYWNlciA9IGFyZ3NbMV07XG4gICAgaWYgKCFpc09iamVjdChyZXBsYWNlcikgJiYgaXQgPT09IHVuZGVmaW5lZCB8fCBpc1N5bWJvbChpdCkpIHJldHVybjsgLy8gSUU4IHJldHVybnMgc3RyaW5nIG9uIHVuZGVmaW5lZFxuICAgIGlmICghaXNBcnJheShyZXBsYWNlcikpIHJlcGxhY2VyID0gZnVuY3Rpb24gKGtleSwgdmFsdWUpIHtcbiAgICAgIGlmICh0eXBlb2YgJHJlcGxhY2VyID09ICdmdW5jdGlvbicpIHZhbHVlID0gJHJlcGxhY2VyLmNhbGwodGhpcywga2V5LCB2YWx1ZSk7XG4gICAgICBpZiAoIWlzU3ltYm9sKHZhbHVlKSkgcmV0dXJuIHZhbHVlO1xuICAgIH07XG4gICAgYXJnc1sxXSA9IHJlcGxhY2VyO1xuICAgIHJldHVybiBfc3RyaW5naWZ5LmFwcGx5KCRKU09OLCBhcmdzKTtcbiAgfVxufSk7XG5cbi8vIDE5LjQuMy40IFN5bWJvbC5wcm90b3R5cGVbQEB0b1ByaW1pdGl2ZV0oaGludClcbiRTeW1ib2xbUFJPVE9UWVBFXVtUT19QUklNSVRJVkVdIHx8IHJlcXVpcmUoJy4vX2hpZGUnKSgkU3ltYm9sW1BST1RPVFlQRV0sIFRPX1BSSU1JVElWRSwgJFN5bWJvbFtQUk9UT1RZUEVdLnZhbHVlT2YpO1xuLy8gMTkuNC4zLjUgU3ltYm9sLnByb3RvdHlwZVtAQHRvU3RyaW5nVGFnXVxuc2V0VG9TdHJpbmdUYWcoJFN5bWJvbCwgJ1N5bWJvbCcpO1xuLy8gMjAuMi4xLjkgTWF0aFtAQHRvU3RyaW5nVGFnXVxuc2V0VG9TdHJpbmdUYWcoTWF0aCwgJ01hdGgnLCB0cnVlKTtcbi8vIDI0LjMuMyBKU09OW0BAdG9TdHJpbmdUYWddXG5zZXRUb1N0cmluZ1RhZyhnbG9iYWwuSlNPTiwgJ0pTT04nLCB0cnVlKTtcbiIsIid1c2Ugc3RyaWN0JztcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgJHR5cGVkID0gcmVxdWlyZSgnLi9fdHlwZWQnKTtcbnZhciBidWZmZXIgPSByZXF1aXJlKCcuL190eXBlZC1idWZmZXInKTtcbnZhciBhbk9iamVjdCA9IHJlcXVpcmUoJy4vX2FuLW9iamVjdCcpO1xudmFyIHRvQWJzb2x1dGVJbmRleCA9IHJlcXVpcmUoJy4vX3RvLWFic29sdXRlLWluZGV4Jyk7XG52YXIgdG9MZW5ndGggPSByZXF1aXJlKCcuL190by1sZW5ndGgnKTtcbnZhciBpc09iamVjdCA9IHJlcXVpcmUoJy4vX2lzLW9iamVjdCcpO1xudmFyIEFycmF5QnVmZmVyID0gcmVxdWlyZSgnLi9fZ2xvYmFsJykuQXJyYXlCdWZmZXI7XG52YXIgc3BlY2llc0NvbnN0cnVjdG9yID0gcmVxdWlyZSgnLi9fc3BlY2llcy1jb25zdHJ1Y3RvcicpO1xudmFyICRBcnJheUJ1ZmZlciA9IGJ1ZmZlci5BcnJheUJ1ZmZlcjtcbnZhciAkRGF0YVZpZXcgPSBidWZmZXIuRGF0YVZpZXc7XG52YXIgJGlzVmlldyA9ICR0eXBlZC5BQlYgJiYgQXJyYXlCdWZmZXIuaXNWaWV3O1xudmFyICRzbGljZSA9ICRBcnJheUJ1ZmZlci5wcm90b3R5cGUuc2xpY2U7XG52YXIgVklFVyA9ICR0eXBlZC5WSUVXO1xudmFyIEFSUkFZX0JVRkZFUiA9ICdBcnJheUJ1ZmZlcic7XG5cbiRleHBvcnQoJGV4cG9ydC5HICsgJGV4cG9ydC5XICsgJGV4cG9ydC5GICogKEFycmF5QnVmZmVyICE9PSAkQXJyYXlCdWZmZXIpLCB7IEFycmF5QnVmZmVyOiAkQXJyYXlCdWZmZXIgfSk7XG5cbiRleHBvcnQoJGV4cG9ydC5TICsgJGV4cG9ydC5GICogISR0eXBlZC5DT05TVFIsIEFSUkFZX0JVRkZFUiwge1xuICAvLyAyNC4xLjMuMSBBcnJheUJ1ZmZlci5pc1ZpZXcoYXJnKVxuICBpc1ZpZXc6IGZ1bmN0aW9uIGlzVmlldyhpdCkge1xuICAgIHJldHVybiAkaXNWaWV3ICYmICRpc1ZpZXcoaXQpIHx8IGlzT2JqZWN0KGl0KSAmJiBWSUVXIGluIGl0O1xuICB9XG59KTtcblxuJGV4cG9ydCgkZXhwb3J0LlAgKyAkZXhwb3J0LlUgKyAkZXhwb3J0LkYgKiByZXF1aXJlKCcuL19mYWlscycpKGZ1bmN0aW9uICgpIHtcbiAgcmV0dXJuICFuZXcgJEFycmF5QnVmZmVyKDIpLnNsaWNlKDEsIHVuZGVmaW5lZCkuYnl0ZUxlbmd0aDtcbn0pLCBBUlJBWV9CVUZGRVIsIHtcbiAgLy8gMjQuMS40LjMgQXJyYXlCdWZmZXIucHJvdG90eXBlLnNsaWNlKHN0YXJ0LCBlbmQpXG4gIHNsaWNlOiBmdW5jdGlvbiBzbGljZShzdGFydCwgZW5kKSB7XG4gICAgaWYgKCRzbGljZSAhPT0gdW5kZWZpbmVkICYmIGVuZCA9PT0gdW5kZWZpbmVkKSByZXR1cm4gJHNsaWNlLmNhbGwoYW5PYmplY3QodGhpcyksIHN0YXJ0KTsgLy8gRkYgZml4XG4gICAgdmFyIGxlbiA9IGFuT2JqZWN0KHRoaXMpLmJ5dGVMZW5ndGg7XG4gICAgdmFyIGZpcnN0ID0gdG9BYnNvbHV0ZUluZGV4KHN0YXJ0LCBsZW4pO1xuICAgIHZhciBmaW4gPSB0b0Fic29sdXRlSW5kZXgoZW5kID09PSB1bmRlZmluZWQgPyBsZW4gOiBlbmQsIGxlbik7XG4gICAgdmFyIHJlc3VsdCA9IG5ldyAoc3BlY2llc0NvbnN0cnVjdG9yKHRoaXMsICRBcnJheUJ1ZmZlcikpKHRvTGVuZ3RoKGZpbiAtIGZpcnN0KSk7XG4gICAgdmFyIHZpZXdTID0gbmV3ICREYXRhVmlldyh0aGlzKTtcbiAgICB2YXIgdmlld1QgPSBuZXcgJERhdGFWaWV3KHJlc3VsdCk7XG4gICAgdmFyIGluZGV4ID0gMDtcbiAgICB3aGlsZSAoZmlyc3QgPCBmaW4pIHtcbiAgICAgIHZpZXdULnNldFVpbnQ4KGluZGV4KyssIHZpZXdTLmdldFVpbnQ4KGZpcnN0KyspKTtcbiAgICB9IHJldHVybiByZXN1bHQ7XG4gIH1cbn0pO1xuXG5yZXF1aXJlKCcuL19zZXQtc3BlY2llcycpKEFSUkFZX0JVRkZFUik7XG4iLCJ2YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xuJGV4cG9ydCgkZXhwb3J0LkcgKyAkZXhwb3J0LlcgKyAkZXhwb3J0LkYgKiAhcmVxdWlyZSgnLi9fdHlwZWQnKS5BQlYsIHtcbiAgRGF0YVZpZXc6IHJlcXVpcmUoJy4vX3R5cGVkLWJ1ZmZlcicpLkRhdGFWaWV3XG59KTtcbiIsInJlcXVpcmUoJy4vX3R5cGVkLWFycmF5JykoJ0Zsb2F0MzInLCA0LCBmdW5jdGlvbiAoaW5pdCkge1xuICByZXR1cm4gZnVuY3Rpb24gRmxvYXQzMkFycmF5KGRhdGEsIGJ5dGVPZmZzZXQsIGxlbmd0aCkge1xuICAgIHJldHVybiBpbml0KHRoaXMsIGRhdGEsIGJ5dGVPZmZzZXQsIGxlbmd0aCk7XG4gIH07XG59KTtcbiIsInJlcXVpcmUoJy4vX3R5cGVkLWFycmF5JykoJ0Zsb2F0NjQnLCA4LCBmdW5jdGlvbiAoaW5pdCkge1xuICByZXR1cm4gZnVuY3Rpb24gRmxvYXQ2NEFycmF5KGRhdGEsIGJ5dGVPZmZzZXQsIGxlbmd0aCkge1xuICAgIHJldHVybiBpbml0KHRoaXMsIGRhdGEsIGJ5dGVPZmZzZXQsIGxlbmd0aCk7XG4gIH07XG59KTtcbiIsInJlcXVpcmUoJy4vX3R5cGVkLWFycmF5JykoJ0ludDE2JywgMiwgZnVuY3Rpb24gKGluaXQpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIEludDE2QXJyYXkoZGF0YSwgYnl0ZU9mZnNldCwgbGVuZ3RoKSB7XG4gICAgcmV0dXJuIGluaXQodGhpcywgZGF0YSwgYnl0ZU9mZnNldCwgbGVuZ3RoKTtcbiAgfTtcbn0pO1xuIiwicmVxdWlyZSgnLi9fdHlwZWQtYXJyYXknKSgnSW50MzInLCA0LCBmdW5jdGlvbiAoaW5pdCkge1xuICByZXR1cm4gZnVuY3Rpb24gSW50MzJBcnJheShkYXRhLCBieXRlT2Zmc2V0LCBsZW5ndGgpIHtcbiAgICByZXR1cm4gaW5pdCh0aGlzLCBkYXRhLCBieXRlT2Zmc2V0LCBsZW5ndGgpO1xuICB9O1xufSk7XG4iLCJyZXF1aXJlKCcuL190eXBlZC1hcnJheScpKCdJbnQ4JywgMSwgZnVuY3Rpb24gKGluaXQpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIEludDhBcnJheShkYXRhLCBieXRlT2Zmc2V0LCBsZW5ndGgpIHtcbiAgICByZXR1cm4gaW5pdCh0aGlzLCBkYXRhLCBieXRlT2Zmc2V0LCBsZW5ndGgpO1xuICB9O1xufSk7XG4iLCJyZXF1aXJlKCcuL190eXBlZC1hcnJheScpKCdVaW50MTYnLCAyLCBmdW5jdGlvbiAoaW5pdCkge1xuICByZXR1cm4gZnVuY3Rpb24gVWludDE2QXJyYXkoZGF0YSwgYnl0ZU9mZnNldCwgbGVuZ3RoKSB7XG4gICAgcmV0dXJuIGluaXQodGhpcywgZGF0YSwgYnl0ZU9mZnNldCwgbGVuZ3RoKTtcbiAgfTtcbn0pO1xuIiwicmVxdWlyZSgnLi9fdHlwZWQtYXJyYXknKSgnVWludDMyJywgNCwgZnVuY3Rpb24gKGluaXQpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIFVpbnQzMkFycmF5KGRhdGEsIGJ5dGVPZmZzZXQsIGxlbmd0aCkge1xuICAgIHJldHVybiBpbml0KHRoaXMsIGRhdGEsIGJ5dGVPZmZzZXQsIGxlbmd0aCk7XG4gIH07XG59KTtcbiIsInJlcXVpcmUoJy4vX3R5cGVkLWFycmF5JykoJ1VpbnQ4JywgMSwgZnVuY3Rpb24gKGluaXQpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIFVpbnQ4QXJyYXkoZGF0YSwgYnl0ZU9mZnNldCwgbGVuZ3RoKSB7XG4gICAgcmV0dXJuIGluaXQodGhpcywgZGF0YSwgYnl0ZU9mZnNldCwgbGVuZ3RoKTtcbiAgfTtcbn0pO1xuIiwicmVxdWlyZSgnLi9fdHlwZWQtYXJyYXknKSgnVWludDgnLCAxLCBmdW5jdGlvbiAoaW5pdCkge1xuICByZXR1cm4gZnVuY3Rpb24gVWludDhDbGFtcGVkQXJyYXkoZGF0YSwgYnl0ZU9mZnNldCwgbGVuZ3RoKSB7XG4gICAgcmV0dXJuIGluaXQodGhpcywgZGF0YSwgYnl0ZU9mZnNldCwgbGVuZ3RoKTtcbiAgfTtcbn0sIHRydWUpO1xuIiwiJ3VzZSBzdHJpY3QnO1xudmFyIGVhY2ggPSByZXF1aXJlKCcuL19hcnJheS1tZXRob2RzJykoMCk7XG52YXIgcmVkZWZpbmUgPSByZXF1aXJlKCcuL19yZWRlZmluZScpO1xudmFyIG1ldGEgPSByZXF1aXJlKCcuL19tZXRhJyk7XG52YXIgYXNzaWduID0gcmVxdWlyZSgnLi9fb2JqZWN0LWFzc2lnbicpO1xudmFyIHdlYWsgPSByZXF1aXJlKCcuL19jb2xsZWN0aW9uLXdlYWsnKTtcbnZhciBpc09iamVjdCA9IHJlcXVpcmUoJy4vX2lzLW9iamVjdCcpO1xudmFyIGZhaWxzID0gcmVxdWlyZSgnLi9fZmFpbHMnKTtcbnZhciB2YWxpZGF0ZSA9IHJlcXVpcmUoJy4vX3ZhbGlkYXRlLWNvbGxlY3Rpb24nKTtcbnZhciBXRUFLX01BUCA9ICdXZWFrTWFwJztcbnZhciBnZXRXZWFrID0gbWV0YS5nZXRXZWFrO1xudmFyIGlzRXh0ZW5zaWJsZSA9IE9iamVjdC5pc0V4dGVuc2libGU7XG52YXIgdW5jYXVnaHRGcm96ZW5TdG9yZSA9IHdlYWsudWZzdG9yZTtcbnZhciB0bXAgPSB7fTtcbnZhciBJbnRlcm5hbE1hcDtcblxudmFyIHdyYXBwZXIgPSBmdW5jdGlvbiAoZ2V0KSB7XG4gIHJldHVybiBmdW5jdGlvbiBXZWFrTWFwKCkge1xuICAgIHJldHVybiBnZXQodGhpcywgYXJndW1lbnRzLmxlbmd0aCA+IDAgPyBhcmd1bWVudHNbMF0gOiB1bmRlZmluZWQpO1xuICB9O1xufTtcblxudmFyIG1ldGhvZHMgPSB7XG4gIC8vIDIzLjMuMy4zIFdlYWtNYXAucHJvdG90eXBlLmdldChrZXkpXG4gIGdldDogZnVuY3Rpb24gZ2V0KGtleSkge1xuICAgIGlmIChpc09iamVjdChrZXkpKSB7XG4gICAgICB2YXIgZGF0YSA9IGdldFdlYWsoa2V5KTtcbiAgICAgIGlmIChkYXRhID09PSB0cnVlKSByZXR1cm4gdW5jYXVnaHRGcm96ZW5TdG9yZSh2YWxpZGF0ZSh0aGlzLCBXRUFLX01BUCkpLmdldChrZXkpO1xuICAgICAgcmV0dXJuIGRhdGEgPyBkYXRhW3RoaXMuX2ldIDogdW5kZWZpbmVkO1xuICAgIH1cbiAgfSxcbiAgLy8gMjMuMy4zLjUgV2Vha01hcC5wcm90b3R5cGUuc2V0KGtleSwgdmFsdWUpXG4gIHNldDogZnVuY3Rpb24gc2V0KGtleSwgdmFsdWUpIHtcbiAgICByZXR1cm4gd2Vhay5kZWYodmFsaWRhdGUodGhpcywgV0VBS19NQVApLCBrZXksIHZhbHVlKTtcbiAgfVxufTtcblxuLy8gMjMuMyBXZWFrTWFwIE9iamVjdHNcbnZhciAkV2Vha01hcCA9IG1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi9fY29sbGVjdGlvbicpKFdFQUtfTUFQLCB3cmFwcGVyLCBtZXRob2RzLCB3ZWFrLCB0cnVlLCB0cnVlKTtcblxuLy8gSUUxMSBXZWFrTWFwIGZyb3plbiBrZXlzIGZpeFxuaWYgKGZhaWxzKGZ1bmN0aW9uICgpIHsgcmV0dXJuIG5ldyAkV2Vha01hcCgpLnNldCgoT2JqZWN0LmZyZWV6ZSB8fCBPYmplY3QpKHRtcCksIDcpLmdldCh0bXApICE9IDc7IH0pKSB7XG4gIEludGVybmFsTWFwID0gd2Vhay5nZXRDb25zdHJ1Y3Rvcih3cmFwcGVyLCBXRUFLX01BUCk7XG4gIGFzc2lnbihJbnRlcm5hbE1hcC5wcm90b3R5cGUsIG1ldGhvZHMpO1xuICBtZXRhLk5FRUQgPSB0cnVlO1xuICBlYWNoKFsnZGVsZXRlJywgJ2hhcycsICdnZXQnLCAnc2V0J10sIGZ1bmN0aW9uIChrZXkpIHtcbiAgICB2YXIgcHJvdG8gPSAkV2Vha01hcC5wcm90b3R5cGU7XG4gICAgdmFyIG1ldGhvZCA9IHByb3RvW2tleV07XG4gICAgcmVkZWZpbmUocHJvdG8sIGtleSwgZnVuY3Rpb24gKGEsIGIpIHtcbiAgICAgIC8vIHN0b3JlIGZyb3plbiBvYmplY3RzIG9uIGludGVybmFsIHdlYWttYXAgc2hpbVxuICAgICAgaWYgKGlzT2JqZWN0KGEpICYmICFpc0V4dGVuc2libGUoYSkpIHtcbiAgICAgICAgaWYgKCF0aGlzLl9mKSB0aGlzLl9mID0gbmV3IEludGVybmFsTWFwKCk7XG4gICAgICAgIHZhciByZXN1bHQgPSB0aGlzLl9mW2tleV0oYSwgYik7XG4gICAgICAgIHJldHVybiBrZXkgPT0gJ3NldCcgPyB0aGlzIDogcmVzdWx0O1xuICAgICAgLy8gc3RvcmUgYWxsIHRoZSByZXN0IG9uIG5hdGl2ZSB3ZWFrbWFwXG4gICAgICB9IHJldHVybiBtZXRob2QuY2FsbCh0aGlzLCBhLCBiKTtcbiAgICB9KTtcbiAgfSk7XG59XG4iLCIndXNlIHN0cmljdCc7XG52YXIgd2VhayA9IHJlcXVpcmUoJy4vX2NvbGxlY3Rpb24td2VhaycpO1xudmFyIHZhbGlkYXRlID0gcmVxdWlyZSgnLi9fdmFsaWRhdGUtY29sbGVjdGlvbicpO1xudmFyIFdFQUtfU0VUID0gJ1dlYWtTZXQnO1xuXG4vLyAyMy40IFdlYWtTZXQgT2JqZWN0c1xucmVxdWlyZSgnLi9fY29sbGVjdGlvbicpKFdFQUtfU0VULCBmdW5jdGlvbiAoZ2V0KSB7XG4gIHJldHVybiBmdW5jdGlvbiBXZWFrU2V0KCkgeyByZXR1cm4gZ2V0KHRoaXMsIGFyZ3VtZW50cy5sZW5ndGggPiAwID8gYXJndW1lbnRzWzBdIDogdW5kZWZpbmVkKTsgfTtcbn0sIHtcbiAgLy8gMjMuNC4zLjEgV2Vha1NldC5wcm90b3R5cGUuYWRkKHZhbHVlKVxuICBhZGQ6IGZ1bmN0aW9uIGFkZCh2YWx1ZSkge1xuICAgIHJldHVybiB3ZWFrLmRlZih2YWxpZGF0ZSh0aGlzLCBXRUFLX1NFVCksIHZhbHVlLCB0cnVlKTtcbiAgfVxufSwgd2VhaywgZmFsc2UsIHRydWUpO1xuIiwiJ3VzZSBzdHJpY3QnO1xuLy8gaHR0cHM6Ly9naXRodWIuY29tL3RjMzkvQXJyYXkucHJvdG90eXBlLmluY2x1ZGVzXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyICRpbmNsdWRlcyA9IHJlcXVpcmUoJy4vX2FycmF5LWluY2x1ZGVzJykodHJ1ZSk7XG5cbiRleHBvcnQoJGV4cG9ydC5QLCAnQXJyYXknLCB7XG4gIGluY2x1ZGVzOiBmdW5jdGlvbiBpbmNsdWRlcyhlbCAvKiAsIGZyb21JbmRleCA9IDAgKi8pIHtcbiAgICByZXR1cm4gJGluY2x1ZGVzKHRoaXMsIGVsLCBhcmd1bWVudHMubGVuZ3RoID4gMSA/IGFyZ3VtZW50c1sxXSA6IHVuZGVmaW5lZCk7XG4gIH1cbn0pO1xuXG5yZXF1aXJlKCcuL19hZGQtdG8tdW5zY29wYWJsZXMnKSgnaW5jbHVkZXMnKTtcbiIsIi8vIGh0dHBzOi8vZ2l0aHViLmNvbS90YzM5L3Byb3Bvc2FsLW9iamVjdC12YWx1ZXMtZW50cmllc1xudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciAkZW50cmllcyA9IHJlcXVpcmUoJy4vX29iamVjdC10by1hcnJheScpKHRydWUpO1xuXG4kZXhwb3J0KCRleHBvcnQuUywgJ09iamVjdCcsIHtcbiAgZW50cmllczogZnVuY3Rpb24gZW50cmllcyhpdCkge1xuICAgIHJldHVybiAkZW50cmllcyhpdCk7XG4gIH1cbn0pO1xuIiwiLy8gaHR0cHM6Ly9naXRodWIuY29tL3RjMzkvcHJvcG9zYWwtb2JqZWN0LWdldG93bnByb3BlcnR5ZGVzY3JpcHRvcnNcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgb3duS2V5cyA9IHJlcXVpcmUoJy4vX293bi1rZXlzJyk7XG52YXIgdG9JT2JqZWN0ID0gcmVxdWlyZSgnLi9fdG8taW9iamVjdCcpO1xudmFyIGdPUEQgPSByZXF1aXJlKCcuL19vYmplY3QtZ29wZCcpO1xudmFyIGNyZWF0ZVByb3BlcnR5ID0gcmVxdWlyZSgnLi9fY3JlYXRlLXByb3BlcnR5Jyk7XG5cbiRleHBvcnQoJGV4cG9ydC5TLCAnT2JqZWN0Jywge1xuICBnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3JzOiBmdW5jdGlvbiBnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3JzKG9iamVjdCkge1xuICAgIHZhciBPID0gdG9JT2JqZWN0KG9iamVjdCk7XG4gICAgdmFyIGdldERlc2MgPSBnT1BELmY7XG4gICAgdmFyIGtleXMgPSBvd25LZXlzKE8pO1xuICAgIHZhciByZXN1bHQgPSB7fTtcbiAgICB2YXIgaSA9IDA7XG4gICAgdmFyIGtleSwgZGVzYztcbiAgICB3aGlsZSAoa2V5cy5sZW5ndGggPiBpKSB7XG4gICAgICBkZXNjID0gZ2V0RGVzYyhPLCBrZXkgPSBrZXlzW2krK10pO1xuICAgICAgaWYgKGRlc2MgIT09IHVuZGVmaW5lZCkgY3JlYXRlUHJvcGVydHkocmVzdWx0LCBrZXksIGRlc2MpO1xuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG59KTtcbiIsIi8vIGh0dHBzOi8vZ2l0aHViLmNvbS90YzM5L3Byb3Bvc2FsLW9iamVjdC12YWx1ZXMtZW50cmllc1xudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciAkdmFsdWVzID0gcmVxdWlyZSgnLi9fb2JqZWN0LXRvLWFycmF5JykoZmFsc2UpO1xuXG4kZXhwb3J0KCRleHBvcnQuUywgJ09iamVjdCcsIHtcbiAgdmFsdWVzOiBmdW5jdGlvbiB2YWx1ZXMoaXQpIHtcbiAgICByZXR1cm4gJHZhbHVlcyhpdCk7XG4gIH1cbn0pO1xuIiwiLy8gaHR0cHM6Ly9naXRodWIuY29tL3RjMzkvcHJvcG9zYWwtcHJvbWlzZS1maW5hbGx5XG4ndXNlIHN0cmljdCc7XG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyIGNvcmUgPSByZXF1aXJlKCcuL19jb3JlJyk7XG52YXIgZ2xvYmFsID0gcmVxdWlyZSgnLi9fZ2xvYmFsJyk7XG52YXIgc3BlY2llc0NvbnN0cnVjdG9yID0gcmVxdWlyZSgnLi9fc3BlY2llcy1jb25zdHJ1Y3RvcicpO1xudmFyIHByb21pc2VSZXNvbHZlID0gcmVxdWlyZSgnLi9fcHJvbWlzZS1yZXNvbHZlJyk7XG5cbiRleHBvcnQoJGV4cG9ydC5QICsgJGV4cG9ydC5SLCAnUHJvbWlzZScsIHsgJ2ZpbmFsbHknOiBmdW5jdGlvbiAob25GaW5hbGx5KSB7XG4gIHZhciBDID0gc3BlY2llc0NvbnN0cnVjdG9yKHRoaXMsIGNvcmUuUHJvbWlzZSB8fCBnbG9iYWwuUHJvbWlzZSk7XG4gIHZhciBpc0Z1bmN0aW9uID0gdHlwZW9mIG9uRmluYWxseSA9PSAnZnVuY3Rpb24nO1xuICByZXR1cm4gdGhpcy50aGVuKFxuICAgIGlzRnVuY3Rpb24gPyBmdW5jdGlvbiAoeCkge1xuICAgICAgcmV0dXJuIHByb21pc2VSZXNvbHZlKEMsIG9uRmluYWxseSgpKS50aGVuKGZ1bmN0aW9uICgpIHsgcmV0dXJuIHg7IH0pO1xuICAgIH0gOiBvbkZpbmFsbHksXG4gICAgaXNGdW5jdGlvbiA/IGZ1bmN0aW9uIChlKSB7XG4gICAgICByZXR1cm4gcHJvbWlzZVJlc29sdmUoQywgb25GaW5hbGx5KCkpLnRoZW4oZnVuY3Rpb24gKCkgeyB0aHJvdyBlOyB9KTtcbiAgICB9IDogb25GaW5hbGx5XG4gICk7XG59IH0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xuLy8gaHR0cHM6Ly9naXRodWIuY29tL3RjMzkvcHJvcG9zYWwtc3RyaW5nLXBhZC1zdGFydC1lbmRcbnZhciAkZXhwb3J0ID0gcmVxdWlyZSgnLi9fZXhwb3J0Jyk7XG52YXIgJHBhZCA9IHJlcXVpcmUoJy4vX3N0cmluZy1wYWQnKTtcbnZhciB1c2VyQWdlbnQgPSByZXF1aXJlKCcuL191c2VyLWFnZW50Jyk7XG5cbi8vIGh0dHBzOi8vZ2l0aHViLmNvbS96bG9pcm9jay9jb3JlLWpzL2lzc3Vlcy8yODBcbiRleHBvcnQoJGV4cG9ydC5QICsgJGV4cG9ydC5GICogL1ZlcnNpb25cXC8xMFxcLlxcZCsoXFwuXFxkKyk/IFNhZmFyaVxcLy8udGVzdCh1c2VyQWdlbnQpLCAnU3RyaW5nJywge1xuICBwYWRFbmQ6IGZ1bmN0aW9uIHBhZEVuZChtYXhMZW5ndGggLyogLCBmaWxsU3RyaW5nID0gJyAnICovKSB7XG4gICAgcmV0dXJuICRwYWQodGhpcywgbWF4TGVuZ3RoLCBhcmd1bWVudHMubGVuZ3RoID4gMSA/IGFyZ3VtZW50c1sxXSA6IHVuZGVmaW5lZCwgZmFsc2UpO1xuICB9XG59KTtcbiIsIid1c2Ugc3RyaWN0Jztcbi8vIGh0dHBzOi8vZ2l0aHViLmNvbS90YzM5L3Byb3Bvc2FsLXN0cmluZy1wYWQtc3RhcnQtZW5kXG52YXIgJGV4cG9ydCA9IHJlcXVpcmUoJy4vX2V4cG9ydCcpO1xudmFyICRwYWQgPSByZXF1aXJlKCcuL19zdHJpbmctcGFkJyk7XG52YXIgdXNlckFnZW50ID0gcmVxdWlyZSgnLi9fdXNlci1hZ2VudCcpO1xuXG4vLyBodHRwczovL2dpdGh1Yi5jb20vemxvaXJvY2svY29yZS1qcy9pc3N1ZXMvMjgwXG4kZXhwb3J0KCRleHBvcnQuUCArICRleHBvcnQuRiAqIC9WZXJzaW9uXFwvMTBcXC5cXGQrKFxcLlxcZCspPyBTYWZhcmlcXC8vLnRlc3QodXNlckFnZW50KSwgJ1N0cmluZycsIHtcbiAgcGFkU3RhcnQ6IGZ1bmN0aW9uIHBhZFN0YXJ0KG1heExlbmd0aCAvKiAsIGZpbGxTdHJpbmcgPSAnICcgKi8pIHtcbiAgICByZXR1cm4gJHBhZCh0aGlzLCBtYXhMZW5ndGgsIGFyZ3VtZW50cy5sZW5ndGggPiAxID8gYXJndW1lbnRzWzFdIDogdW5kZWZpbmVkLCB0cnVlKTtcbiAgfVxufSk7XG4iLCJyZXF1aXJlKCcuL193a3MtZGVmaW5lJykoJ2FzeW5jSXRlcmF0b3InKTtcbiIsInZhciAkaXRlcmF0b3JzID0gcmVxdWlyZSgnLi9lczYuYXJyYXkuaXRlcmF0b3InKTtcbnZhciBnZXRLZXlzID0gcmVxdWlyZSgnLi9fb2JqZWN0LWtleXMnKTtcbnZhciByZWRlZmluZSA9IHJlcXVpcmUoJy4vX3JlZGVmaW5lJyk7XG52YXIgZ2xvYmFsID0gcmVxdWlyZSgnLi9fZ2xvYmFsJyk7XG52YXIgaGlkZSA9IHJlcXVpcmUoJy4vX2hpZGUnKTtcbnZhciBJdGVyYXRvcnMgPSByZXF1aXJlKCcuL19pdGVyYXRvcnMnKTtcbnZhciB3a3MgPSByZXF1aXJlKCcuL193a3MnKTtcbnZhciBJVEVSQVRPUiA9IHdrcygnaXRlcmF0b3InKTtcbnZhciBUT19TVFJJTkdfVEFHID0gd2tzKCd0b1N0cmluZ1RhZycpO1xudmFyIEFycmF5VmFsdWVzID0gSXRlcmF0b3JzLkFycmF5O1xuXG52YXIgRE9NSXRlcmFibGVzID0ge1xuICBDU1NSdWxlTGlzdDogdHJ1ZSwgLy8gVE9ETzogTm90IHNwZWMgY29tcGxpYW50LCBzaG91bGQgYmUgZmFsc2UuXG4gIENTU1N0eWxlRGVjbGFyYXRpb246IGZhbHNlLFxuICBDU1NWYWx1ZUxpc3Q6IGZhbHNlLFxuICBDbGllbnRSZWN0TGlzdDogZmFsc2UsXG4gIERPTVJlY3RMaXN0OiBmYWxzZSxcbiAgRE9NU3RyaW5nTGlzdDogZmFsc2UsXG4gIERPTVRva2VuTGlzdDogdHJ1ZSxcbiAgRGF0YVRyYW5zZmVySXRlbUxpc3Q6IGZhbHNlLFxuICBGaWxlTGlzdDogZmFsc2UsXG4gIEhUTUxBbGxDb2xsZWN0aW9uOiBmYWxzZSxcbiAgSFRNTENvbGxlY3Rpb246IGZhbHNlLFxuICBIVE1MRm9ybUVsZW1lbnQ6IGZhbHNlLFxuICBIVE1MU2VsZWN0RWxlbWVudDogZmFsc2UsXG4gIE1lZGlhTGlzdDogdHJ1ZSwgLy8gVE9ETzogTm90IHNwZWMgY29tcGxpYW50LCBzaG91bGQgYmUgZmFsc2UuXG4gIE1pbWVUeXBlQXJyYXk6IGZhbHNlLFxuICBOYW1lZE5vZGVNYXA6IGZhbHNlLFxuICBOb2RlTGlzdDogdHJ1ZSxcbiAgUGFpbnRSZXF1ZXN0TGlzdDogZmFsc2UsXG4gIFBsdWdpbjogZmFsc2UsXG4gIFBsdWdpbkFycmF5OiBmYWxzZSxcbiAgU1ZHTGVuZ3RoTGlzdDogZmFsc2UsXG4gIFNWR051bWJlckxpc3Q6IGZhbHNlLFxuICBTVkdQYXRoU2VnTGlzdDogZmFsc2UsXG4gIFNWR1BvaW50TGlzdDogZmFsc2UsXG4gIFNWR1N0cmluZ0xpc3Q6IGZhbHNlLFxuICBTVkdUcmFuc2Zvcm1MaXN0OiBmYWxzZSxcbiAgU291cmNlQnVmZmVyTGlzdDogZmFsc2UsXG4gIFN0eWxlU2hlZXRMaXN0OiB0cnVlLCAvLyBUT0RPOiBOb3Qgc3BlYyBjb21wbGlhbnQsIHNob3VsZCBiZSBmYWxzZS5cbiAgVGV4dFRyYWNrQ3VlTGlzdDogZmFsc2UsXG4gIFRleHRUcmFja0xpc3Q6IGZhbHNlLFxuICBUb3VjaExpc3Q6IGZhbHNlXG59O1xuXG5mb3IgKHZhciBjb2xsZWN0aW9ucyA9IGdldEtleXMoRE9NSXRlcmFibGVzKSwgaSA9IDA7IGkgPCBjb2xsZWN0aW9ucy5sZW5ndGg7IGkrKykge1xuICB2YXIgTkFNRSA9IGNvbGxlY3Rpb25zW2ldO1xuICB2YXIgZXhwbGljaXQgPSBET01JdGVyYWJsZXNbTkFNRV07XG4gIHZhciBDb2xsZWN0aW9uID0gZ2xvYmFsW05BTUVdO1xuICB2YXIgcHJvdG8gPSBDb2xsZWN0aW9uICYmIENvbGxlY3Rpb24ucHJvdG90eXBlO1xuICB2YXIga2V5O1xuICBpZiAocHJvdG8pIHtcbiAgICBpZiAoIXByb3RvW0lURVJBVE9SXSkgaGlkZShwcm90bywgSVRFUkFUT1IsIEFycmF5VmFsdWVzKTtcbiAgICBpZiAoIXByb3RvW1RPX1NUUklOR19UQUddKSBoaWRlKHByb3RvLCBUT19TVFJJTkdfVEFHLCBOQU1FKTtcbiAgICBJdGVyYXRvcnNbTkFNRV0gPSBBcnJheVZhbHVlcztcbiAgICBpZiAoZXhwbGljaXQpIGZvciAoa2V5IGluICRpdGVyYXRvcnMpIGlmICghcHJvdG9ba2V5XSkgcmVkZWZpbmUocHJvdG8sIGtleSwgJGl0ZXJhdG9yc1trZXldLCB0cnVlKTtcbiAgfVxufVxuIiwidmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciAkdGFzayA9IHJlcXVpcmUoJy4vX3Rhc2snKTtcbiRleHBvcnQoJGV4cG9ydC5HICsgJGV4cG9ydC5CLCB7XG4gIHNldEltbWVkaWF0ZTogJHRhc2suc2V0LFxuICBjbGVhckltbWVkaWF0ZTogJHRhc2suY2xlYXJcbn0pO1xuIiwiLy8gaWU5LSBzZXRUaW1lb3V0ICYgc2V0SW50ZXJ2YWwgYWRkaXRpb25hbCBwYXJhbWV0ZXJzIGZpeFxudmFyIGdsb2JhbCA9IHJlcXVpcmUoJy4vX2dsb2JhbCcpO1xudmFyICRleHBvcnQgPSByZXF1aXJlKCcuL19leHBvcnQnKTtcbnZhciB1c2VyQWdlbnQgPSByZXF1aXJlKCcuL191c2VyLWFnZW50Jyk7XG52YXIgc2xpY2UgPSBbXS5zbGljZTtcbnZhciBNU0lFID0gL01TSUUgLlxcLi8udGVzdCh1c2VyQWdlbnQpOyAvLyA8LSBkaXJ0eSBpZTktIGNoZWNrXG52YXIgd3JhcCA9IGZ1bmN0aW9uIChzZXQpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIChmbiwgdGltZSAvKiAsIC4uLmFyZ3MgKi8pIHtcbiAgICB2YXIgYm91bmRBcmdzID0gYXJndW1lbnRzLmxlbmd0aCA+IDI7XG4gICAgdmFyIGFyZ3MgPSBib3VuZEFyZ3MgPyBzbGljZS5jYWxsKGFyZ3VtZW50cywgMikgOiBmYWxzZTtcbiAgICByZXR1cm4gc2V0KGJvdW5kQXJncyA/IGZ1bmN0aW9uICgpIHtcbiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1uZXctZnVuY1xuICAgICAgKHR5cGVvZiBmbiA9PSAnZnVuY3Rpb24nID8gZm4gOiBGdW5jdGlvbihmbikpLmFwcGx5KHRoaXMsIGFyZ3MpO1xuICAgIH0gOiBmbiwgdGltZSk7XG4gIH07XG59O1xuJGV4cG9ydCgkZXhwb3J0LkcgKyAkZXhwb3J0LkIgKyAkZXhwb3J0LkYgKiBNU0lFLCB7XG4gIHNldFRpbWVvdXQ6IHdyYXAoZ2xvYmFsLnNldFRpbWVvdXQpLFxuICBzZXRJbnRlcnZhbDogd3JhcChnbG9iYWwuc2V0SW50ZXJ2YWwpXG59KTtcbiIsInJlcXVpcmUoJy4uL21vZHVsZXMvd2ViLnRpbWVycycpO1xucmVxdWlyZSgnLi4vbW9kdWxlcy93ZWIuaW1tZWRpYXRlJyk7XG5yZXF1aXJlKCcuLi9tb2R1bGVzL3dlYi5kb20uaXRlcmFibGUnKTtcbm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi4vbW9kdWxlcy9fY29yZScpO1xuIiwiLyoqXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTQtcHJlc2VudCwgRmFjZWJvb2ssIEluYy5cbiAqXG4gKiBUaGlzIHNvdXJjZSBjb2RlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgbGljZW5zZSBmb3VuZCBpbiB0aGVcbiAqIExJQ0VOU0UgZmlsZSBpbiB0aGUgcm9vdCBkaXJlY3Rvcnkgb2YgdGhpcyBzb3VyY2UgdHJlZS5cbiAqL1xuXG4hKGZ1bmN0aW9uKGdsb2JhbCkge1xuICBcInVzZSBzdHJpY3RcIjtcblxuICB2YXIgT3AgPSBPYmplY3QucHJvdG90eXBlO1xuICB2YXIgaGFzT3duID0gT3AuaGFzT3duUHJvcGVydHk7XG4gIHZhciB1bmRlZmluZWQ7IC8vIE1vcmUgY29tcHJlc3NpYmxlIHRoYW4gdm9pZCAwLlxuICB2YXIgJFN5bWJvbCA9IHR5cGVvZiBTeW1ib2wgPT09IFwiZnVuY3Rpb25cIiA/IFN5bWJvbCA6IHt9O1xuICB2YXIgaXRlcmF0b3JTeW1ib2wgPSAkU3ltYm9sLml0ZXJhdG9yIHx8IFwiQEBpdGVyYXRvclwiO1xuICB2YXIgYXN5bmNJdGVyYXRvclN5bWJvbCA9ICRTeW1ib2wuYXN5bmNJdGVyYXRvciB8fCBcIkBAYXN5bmNJdGVyYXRvclwiO1xuICB2YXIgdG9TdHJpbmdUYWdTeW1ib2wgPSAkU3ltYm9sLnRvU3RyaW5nVGFnIHx8IFwiQEB0b1N0cmluZ1RhZ1wiO1xuXG4gIHZhciBpbk1vZHVsZSA9IHR5cGVvZiBtb2R1bGUgPT09IFwib2JqZWN0XCI7XG4gIHZhciBydW50aW1lID0gZ2xvYmFsLnJlZ2VuZXJhdG9yUnVudGltZTtcbiAgaWYgKHJ1bnRpbWUpIHtcbiAgICBpZiAoaW5Nb2R1bGUpIHtcbiAgICAgIC8vIElmIHJlZ2VuZXJhdG9yUnVudGltZSBpcyBkZWZpbmVkIGdsb2JhbGx5IGFuZCB3ZSdyZSBpbiBhIG1vZHVsZSxcbiAgICAgIC8vIG1ha2UgdGhlIGV4cG9ydHMgb2JqZWN0IGlkZW50aWNhbCB0byByZWdlbmVyYXRvclJ1bnRpbWUuXG4gICAgICBtb2R1bGUuZXhwb3J0cyA9IHJ1bnRpbWU7XG4gICAgfVxuICAgIC8vIERvbid0IGJvdGhlciBldmFsdWF0aW5nIHRoZSByZXN0IG9mIHRoaXMgZmlsZSBpZiB0aGUgcnVudGltZSB3YXNcbiAgICAvLyBhbHJlYWR5IGRlZmluZWQgZ2xvYmFsbHkuXG4gICAgcmV0dXJuO1xuICB9XG5cbiAgLy8gRGVmaW5lIHRoZSBydW50aW1lIGdsb2JhbGx5IChhcyBleHBlY3RlZCBieSBnZW5lcmF0ZWQgY29kZSkgYXMgZWl0aGVyXG4gIC8vIG1vZHVsZS5leHBvcnRzIChpZiB3ZSdyZSBpbiBhIG1vZHVsZSkgb3IgYSBuZXcsIGVtcHR5IG9iamVjdC5cbiAgcnVudGltZSA9IGdsb2JhbC5yZWdlbmVyYXRvclJ1bnRpbWUgPSBpbk1vZHVsZSA/IG1vZHVsZS5leHBvcnRzIDoge307XG5cbiAgZnVuY3Rpb24gd3JhcChpbm5lckZuLCBvdXRlckZuLCBzZWxmLCB0cnlMb2NzTGlzdCkge1xuICAgIC8vIElmIG91dGVyRm4gcHJvdmlkZWQgYW5kIG91dGVyRm4ucHJvdG90eXBlIGlzIGEgR2VuZXJhdG9yLCB0aGVuIG91dGVyRm4ucHJvdG90eXBlIGluc3RhbmNlb2YgR2VuZXJhdG9yLlxuICAgIHZhciBwcm90b0dlbmVyYXRvciA9IG91dGVyRm4gJiYgb3V0ZXJGbi5wcm90b3R5cGUgaW5zdGFuY2VvZiBHZW5lcmF0b3IgPyBvdXRlckZuIDogR2VuZXJhdG9yO1xuICAgIHZhciBnZW5lcmF0b3IgPSBPYmplY3QuY3JlYXRlKHByb3RvR2VuZXJhdG9yLnByb3RvdHlwZSk7XG4gICAgdmFyIGNvbnRleHQgPSBuZXcgQ29udGV4dCh0cnlMb2NzTGlzdCB8fCBbXSk7XG5cbiAgICAvLyBUaGUgLl9pbnZva2UgbWV0aG9kIHVuaWZpZXMgdGhlIGltcGxlbWVudGF0aW9ucyBvZiB0aGUgLm5leHQsXG4gICAgLy8gLnRocm93LCBhbmQgLnJldHVybiBtZXRob2RzLlxuICAgIGdlbmVyYXRvci5faW52b2tlID0gbWFrZUludm9rZU1ldGhvZChpbm5lckZuLCBzZWxmLCBjb250ZXh0KTtcblxuICAgIHJldHVybiBnZW5lcmF0b3I7XG4gIH1cbiAgcnVudGltZS53cmFwID0gd3JhcDtcblxuICAvLyBUcnkvY2F0Y2ggaGVscGVyIHRvIG1pbmltaXplIGRlb3B0aW1pemF0aW9ucy4gUmV0dXJucyBhIGNvbXBsZXRpb25cbiAgLy8gcmVjb3JkIGxpa2UgY29udGV4dC50cnlFbnRyaWVzW2ldLmNvbXBsZXRpb24uIFRoaXMgaW50ZXJmYWNlIGNvdWxkXG4gIC8vIGhhdmUgYmVlbiAoYW5kIHdhcyBwcmV2aW91c2x5KSBkZXNpZ25lZCB0byB0YWtlIGEgY2xvc3VyZSB0byBiZVxuICAvLyBpbnZva2VkIHdpdGhvdXQgYXJndW1lbnRzLCBidXQgaW4gYWxsIHRoZSBjYXNlcyB3ZSBjYXJlIGFib3V0IHdlXG4gIC8vIGFscmVhZHkgaGF2ZSBhbiBleGlzdGluZyBtZXRob2Qgd2Ugd2FudCB0byBjYWxsLCBzbyB0aGVyZSdzIG5vIG5lZWRcbiAgLy8gdG8gY3JlYXRlIGEgbmV3IGZ1bmN0aW9uIG9iamVjdC4gV2UgY2FuIGV2ZW4gZ2V0IGF3YXkgd2l0aCBhc3N1bWluZ1xuICAvLyB0aGUgbWV0aG9kIHRha2VzIGV4YWN0bHkgb25lIGFyZ3VtZW50LCBzaW5jZSB0aGF0IGhhcHBlbnMgdG8gYmUgdHJ1ZVxuICAvLyBpbiBldmVyeSBjYXNlLCBzbyB3ZSBkb24ndCBoYXZlIHRvIHRvdWNoIHRoZSBhcmd1bWVudHMgb2JqZWN0LiBUaGVcbiAgLy8gb25seSBhZGRpdGlvbmFsIGFsbG9jYXRpb24gcmVxdWlyZWQgaXMgdGhlIGNvbXBsZXRpb24gcmVjb3JkLCB3aGljaFxuICAvLyBoYXMgYSBzdGFibGUgc2hhcGUgYW5kIHNvIGhvcGVmdWxseSBzaG91bGQgYmUgY2hlYXAgdG8gYWxsb2NhdGUuXG4gIGZ1bmN0aW9uIHRyeUNhdGNoKGZuLCBvYmosIGFyZykge1xuICAgIHRyeSB7XG4gICAgICByZXR1cm4geyB0eXBlOiBcIm5vcm1hbFwiLCBhcmc6IGZuLmNhbGwob2JqLCBhcmcpIH07XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICByZXR1cm4geyB0eXBlOiBcInRocm93XCIsIGFyZzogZXJyIH07XG4gICAgfVxuICB9XG5cbiAgdmFyIEdlblN0YXRlU3VzcGVuZGVkU3RhcnQgPSBcInN1c3BlbmRlZFN0YXJ0XCI7XG4gIHZhciBHZW5TdGF0ZVN1c3BlbmRlZFlpZWxkID0gXCJzdXNwZW5kZWRZaWVsZFwiO1xuICB2YXIgR2VuU3RhdGVFeGVjdXRpbmcgPSBcImV4ZWN1dGluZ1wiO1xuICB2YXIgR2VuU3RhdGVDb21wbGV0ZWQgPSBcImNvbXBsZXRlZFwiO1xuXG4gIC8vIFJldHVybmluZyB0aGlzIG9iamVjdCBmcm9tIHRoZSBpbm5lckZuIGhhcyB0aGUgc2FtZSBlZmZlY3QgYXNcbiAgLy8gYnJlYWtpbmcgb3V0IG9mIHRoZSBkaXNwYXRjaCBzd2l0Y2ggc3RhdGVtZW50LlxuICB2YXIgQ29udGludWVTZW50aW5lbCA9IHt9O1xuXG4gIC8vIER1bW15IGNvbnN0cnVjdG9yIGZ1bmN0aW9ucyB0aGF0IHdlIHVzZSBhcyB0aGUgLmNvbnN0cnVjdG9yIGFuZFxuICAvLyAuY29uc3RydWN0b3IucHJvdG90eXBlIHByb3BlcnRpZXMgZm9yIGZ1bmN0aW9ucyB0aGF0IHJldHVybiBHZW5lcmF0b3JcbiAgLy8gb2JqZWN0cy4gRm9yIGZ1bGwgc3BlYyBjb21wbGlhbmNlLCB5b3UgbWF5IHdpc2ggdG8gY29uZmlndXJlIHlvdXJcbiAgLy8gbWluaWZpZXIgbm90IHRvIG1hbmdsZSB0aGUgbmFtZXMgb2YgdGhlc2UgdHdvIGZ1bmN0aW9ucy5cbiAgZnVuY3Rpb24gR2VuZXJhdG9yKCkge31cbiAgZnVuY3Rpb24gR2VuZXJhdG9yRnVuY3Rpb24oKSB7fVxuICBmdW5jdGlvbiBHZW5lcmF0b3JGdW5jdGlvblByb3RvdHlwZSgpIHt9XG5cbiAgLy8gVGhpcyBpcyBhIHBvbHlmaWxsIGZvciAlSXRlcmF0b3JQcm90b3R5cGUlIGZvciBlbnZpcm9ubWVudHMgdGhhdFxuICAvLyBkb24ndCBuYXRpdmVseSBzdXBwb3J0IGl0LlxuICB2YXIgSXRlcmF0b3JQcm90b3R5cGUgPSB7fTtcbiAgSXRlcmF0b3JQcm90b3R5cGVbaXRlcmF0b3JTeW1ib2xdID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzO1xuICB9O1xuXG4gIHZhciBnZXRQcm90byA9IE9iamVjdC5nZXRQcm90b3R5cGVPZjtcbiAgdmFyIE5hdGl2ZUl0ZXJhdG9yUHJvdG90eXBlID0gZ2V0UHJvdG8gJiYgZ2V0UHJvdG8oZ2V0UHJvdG8odmFsdWVzKFtdKSkpO1xuICBpZiAoTmF0aXZlSXRlcmF0b3JQcm90b3R5cGUgJiZcbiAgICAgIE5hdGl2ZUl0ZXJhdG9yUHJvdG90eXBlICE9PSBPcCAmJlxuICAgICAgaGFzT3duLmNhbGwoTmF0aXZlSXRlcmF0b3JQcm90b3R5cGUsIGl0ZXJhdG9yU3ltYm9sKSkge1xuICAgIC8vIFRoaXMgZW52aXJvbm1lbnQgaGFzIGEgbmF0aXZlICVJdGVyYXRvclByb3RvdHlwZSU7IHVzZSBpdCBpbnN0ZWFkXG4gICAgLy8gb2YgdGhlIHBvbHlmaWxsLlxuICAgIEl0ZXJhdG9yUHJvdG90eXBlID0gTmF0aXZlSXRlcmF0b3JQcm90b3R5cGU7XG4gIH1cblxuICB2YXIgR3AgPSBHZW5lcmF0b3JGdW5jdGlvblByb3RvdHlwZS5wcm90b3R5cGUgPVxuICAgIEdlbmVyYXRvci5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKEl0ZXJhdG9yUHJvdG90eXBlKTtcbiAgR2VuZXJhdG9yRnVuY3Rpb24ucHJvdG90eXBlID0gR3AuY29uc3RydWN0b3IgPSBHZW5lcmF0b3JGdW5jdGlvblByb3RvdHlwZTtcbiAgR2VuZXJhdG9yRnVuY3Rpb25Qcm90b3R5cGUuY29uc3RydWN0b3IgPSBHZW5lcmF0b3JGdW5jdGlvbjtcbiAgR2VuZXJhdG9yRnVuY3Rpb25Qcm90b3R5cGVbdG9TdHJpbmdUYWdTeW1ib2xdID1cbiAgICBHZW5lcmF0b3JGdW5jdGlvbi5kaXNwbGF5TmFtZSA9IFwiR2VuZXJhdG9yRnVuY3Rpb25cIjtcblxuICAvLyBIZWxwZXIgZm9yIGRlZmluaW5nIHRoZSAubmV4dCwgLnRocm93LCBhbmQgLnJldHVybiBtZXRob2RzIG9mIHRoZVxuICAvLyBJdGVyYXRvciBpbnRlcmZhY2UgaW4gdGVybXMgb2YgYSBzaW5nbGUgLl9pbnZva2UgbWV0aG9kLlxuICBmdW5jdGlvbiBkZWZpbmVJdGVyYXRvck1ldGhvZHMocHJvdG90eXBlKSB7XG4gICAgW1wibmV4dFwiLCBcInRocm93XCIsIFwicmV0dXJuXCJdLmZvckVhY2goZnVuY3Rpb24obWV0aG9kKSB7XG4gICAgICBwcm90b3R5cGVbbWV0aG9kXSA9IGZ1bmN0aW9uKGFyZykge1xuICAgICAgICByZXR1cm4gdGhpcy5faW52b2tlKG1ldGhvZCwgYXJnKTtcbiAgICAgIH07XG4gICAgfSk7XG4gIH1cblxuICBydW50aW1lLmlzR2VuZXJhdG9yRnVuY3Rpb24gPSBmdW5jdGlvbihnZW5GdW4pIHtcbiAgICB2YXIgY3RvciA9IHR5cGVvZiBnZW5GdW4gPT09IFwiZnVuY3Rpb25cIiAmJiBnZW5GdW4uY29uc3RydWN0b3I7XG4gICAgcmV0dXJuIGN0b3JcbiAgICAgID8gY3RvciA9PT0gR2VuZXJhdG9yRnVuY3Rpb24gfHxcbiAgICAgICAgLy8gRm9yIHRoZSBuYXRpdmUgR2VuZXJhdG9yRnVuY3Rpb24gY29uc3RydWN0b3IsIHRoZSBiZXN0IHdlIGNhblxuICAgICAgICAvLyBkbyBpcyB0byBjaGVjayBpdHMgLm5hbWUgcHJvcGVydHkuXG4gICAgICAgIChjdG9yLmRpc3BsYXlOYW1lIHx8IGN0b3IubmFtZSkgPT09IFwiR2VuZXJhdG9yRnVuY3Rpb25cIlxuICAgICAgOiBmYWxzZTtcbiAgfTtcblxuICBydW50aW1lLm1hcmsgPSBmdW5jdGlvbihnZW5GdW4pIHtcbiAgICBpZiAoT2JqZWN0LnNldFByb3RvdHlwZU9mKSB7XG4gICAgICBPYmplY3Quc2V0UHJvdG90eXBlT2YoZ2VuRnVuLCBHZW5lcmF0b3JGdW5jdGlvblByb3RvdHlwZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGdlbkZ1bi5fX3Byb3RvX18gPSBHZW5lcmF0b3JGdW5jdGlvblByb3RvdHlwZTtcbiAgICAgIGlmICghKHRvU3RyaW5nVGFnU3ltYm9sIGluIGdlbkZ1bikpIHtcbiAgICAgICAgZ2VuRnVuW3RvU3RyaW5nVGFnU3ltYm9sXSA9IFwiR2VuZXJhdG9yRnVuY3Rpb25cIjtcbiAgICAgIH1cbiAgICB9XG4gICAgZ2VuRnVuLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoR3ApO1xuICAgIHJldHVybiBnZW5GdW47XG4gIH07XG5cbiAgLy8gV2l0aGluIHRoZSBib2R5IG9mIGFueSBhc3luYyBmdW5jdGlvbiwgYGF3YWl0IHhgIGlzIHRyYW5zZm9ybWVkIHRvXG4gIC8vIGB5aWVsZCByZWdlbmVyYXRvclJ1bnRpbWUuYXdyYXAoeClgLCBzbyB0aGF0IHRoZSBydW50aW1lIGNhbiB0ZXN0XG4gIC8vIGBoYXNPd24uY2FsbCh2YWx1ZSwgXCJfX2F3YWl0XCIpYCB0byBkZXRlcm1pbmUgaWYgdGhlIHlpZWxkZWQgdmFsdWUgaXNcbiAgLy8gbWVhbnQgdG8gYmUgYXdhaXRlZC5cbiAgcnVudGltZS5hd3JhcCA9IGZ1bmN0aW9uKGFyZykge1xuICAgIHJldHVybiB7IF9fYXdhaXQ6IGFyZyB9O1xuICB9O1xuXG4gIGZ1bmN0aW9uIEFzeW5jSXRlcmF0b3IoZ2VuZXJhdG9yKSB7XG4gICAgZnVuY3Rpb24gaW52b2tlKG1ldGhvZCwgYXJnLCByZXNvbHZlLCByZWplY3QpIHtcbiAgICAgIHZhciByZWNvcmQgPSB0cnlDYXRjaChnZW5lcmF0b3JbbWV0aG9kXSwgZ2VuZXJhdG9yLCBhcmcpO1xuICAgICAgaWYgKHJlY29yZC50eXBlID09PSBcInRocm93XCIpIHtcbiAgICAgICAgcmVqZWN0KHJlY29yZC5hcmcpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdmFyIHJlc3VsdCA9IHJlY29yZC5hcmc7XG4gICAgICAgIHZhciB2YWx1ZSA9IHJlc3VsdC52YWx1ZTtcbiAgICAgICAgaWYgKHZhbHVlICYmXG4gICAgICAgICAgICB0eXBlb2YgdmFsdWUgPT09IFwib2JqZWN0XCIgJiZcbiAgICAgICAgICAgIGhhc093bi5jYWxsKHZhbHVlLCBcIl9fYXdhaXRcIikpIHtcbiAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHZhbHVlLl9fYXdhaXQpLnRoZW4oZnVuY3Rpb24odmFsdWUpIHtcbiAgICAgICAgICAgIGludm9rZShcIm5leHRcIiwgdmFsdWUsIHJlc29sdmUsIHJlamVjdCk7XG4gICAgICAgICAgfSwgZnVuY3Rpb24oZXJyKSB7XG4gICAgICAgICAgICBpbnZva2UoXCJ0aHJvd1wiLCBlcnIsIHJlc29sdmUsIHJlamVjdCk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHZhbHVlKS50aGVuKGZ1bmN0aW9uKHVud3JhcHBlZCkge1xuICAgICAgICAgIC8vIFdoZW4gYSB5aWVsZGVkIFByb21pc2UgaXMgcmVzb2x2ZWQsIGl0cyBmaW5hbCB2YWx1ZSBiZWNvbWVzXG4gICAgICAgICAgLy8gdGhlIC52YWx1ZSBvZiB0aGUgUHJvbWlzZTx7dmFsdWUsZG9uZX0+IHJlc3VsdCBmb3IgdGhlXG4gICAgICAgICAgLy8gY3VycmVudCBpdGVyYXRpb24uIElmIHRoZSBQcm9taXNlIGlzIHJlamVjdGVkLCBob3dldmVyLCB0aGVcbiAgICAgICAgICAvLyByZXN1bHQgZm9yIHRoaXMgaXRlcmF0aW9uIHdpbGwgYmUgcmVqZWN0ZWQgd2l0aCB0aGUgc2FtZVxuICAgICAgICAgIC8vIHJlYXNvbi4gTm90ZSB0aGF0IHJlamVjdGlvbnMgb2YgeWllbGRlZCBQcm9taXNlcyBhcmUgbm90XG4gICAgICAgICAgLy8gdGhyb3duIGJhY2sgaW50byB0aGUgZ2VuZXJhdG9yIGZ1bmN0aW9uLCBhcyBpcyB0aGUgY2FzZVxuICAgICAgICAgIC8vIHdoZW4gYW4gYXdhaXRlZCBQcm9taXNlIGlzIHJlamVjdGVkLiBUaGlzIGRpZmZlcmVuY2UgaW5cbiAgICAgICAgICAvLyBiZWhhdmlvciBiZXR3ZWVuIHlpZWxkIGFuZCBhd2FpdCBpcyBpbXBvcnRhbnQsIGJlY2F1c2UgaXRcbiAgICAgICAgICAvLyBhbGxvd3MgdGhlIGNvbnN1bWVyIHRvIGRlY2lkZSB3aGF0IHRvIGRvIHdpdGggdGhlIHlpZWxkZWRcbiAgICAgICAgICAvLyByZWplY3Rpb24gKHN3YWxsb3cgaXQgYW5kIGNvbnRpbnVlLCBtYW51YWxseSAudGhyb3cgaXQgYmFja1xuICAgICAgICAgIC8vIGludG8gdGhlIGdlbmVyYXRvciwgYWJhbmRvbiBpdGVyYXRpb24sIHdoYXRldmVyKS4gV2l0aFxuICAgICAgICAgIC8vIGF3YWl0LCBieSBjb250cmFzdCwgdGhlcmUgaXMgbm8gb3Bwb3J0dW5pdHkgdG8gZXhhbWluZSB0aGVcbiAgICAgICAgICAvLyByZWplY3Rpb24gcmVhc29uIG91dHNpZGUgdGhlIGdlbmVyYXRvciBmdW5jdGlvbiwgc28gdGhlXG4gICAgICAgICAgLy8gb25seSBvcHRpb24gaXMgdG8gdGhyb3cgaXQgZnJvbSB0aGUgYXdhaXQgZXhwcmVzc2lvbiwgYW5kXG4gICAgICAgICAgLy8gbGV0IHRoZSBnZW5lcmF0b3IgZnVuY3Rpb24gaGFuZGxlIHRoZSBleGNlcHRpb24uXG4gICAgICAgICAgcmVzdWx0LnZhbHVlID0gdW53cmFwcGVkO1xuICAgICAgICAgIHJlc29sdmUocmVzdWx0KTtcbiAgICAgICAgfSwgcmVqZWN0KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB2YXIgcHJldmlvdXNQcm9taXNlO1xuXG4gICAgZnVuY3Rpb24gZW5xdWV1ZShtZXRob2QsIGFyZykge1xuICAgICAgZnVuY3Rpb24gY2FsbEludm9rZVdpdGhNZXRob2RBbmRBcmcoKSB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbihyZXNvbHZlLCByZWplY3QpIHtcbiAgICAgICAgICBpbnZva2UobWV0aG9kLCBhcmcsIHJlc29sdmUsIHJlamVjdCk7XG4gICAgICAgIH0pO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gcHJldmlvdXNQcm9taXNlID1cbiAgICAgICAgLy8gSWYgZW5xdWV1ZSBoYXMgYmVlbiBjYWxsZWQgYmVmb3JlLCB0aGVuIHdlIHdhbnQgdG8gd2FpdCB1bnRpbFxuICAgICAgICAvLyBhbGwgcHJldmlvdXMgUHJvbWlzZXMgaGF2ZSBiZWVuIHJlc29sdmVkIGJlZm9yZSBjYWxsaW5nIGludm9rZSxcbiAgICAgICAgLy8gc28gdGhhdCByZXN1bHRzIGFyZSBhbHdheXMgZGVsaXZlcmVkIGluIHRoZSBjb3JyZWN0IG9yZGVyLiBJZlxuICAgICAgICAvLyBlbnF1ZXVlIGhhcyBub3QgYmVlbiBjYWxsZWQgYmVmb3JlLCB0aGVuIGl0IGlzIGltcG9ydGFudCB0b1xuICAgICAgICAvLyBjYWxsIGludm9rZSBpbW1lZGlhdGVseSwgd2l0aG91dCB3YWl0aW5nIG9uIGEgY2FsbGJhY2sgdG8gZmlyZSxcbiAgICAgICAgLy8gc28gdGhhdCB0aGUgYXN5bmMgZ2VuZXJhdG9yIGZ1bmN0aW9uIGhhcyB0aGUgb3Bwb3J0dW5pdHkgdG8gZG9cbiAgICAgICAgLy8gYW55IG5lY2Vzc2FyeSBzZXR1cCBpbiBhIHByZWRpY3RhYmxlIHdheS4gVGhpcyBwcmVkaWN0YWJpbGl0eVxuICAgICAgICAvLyBpcyB3aHkgdGhlIFByb21pc2UgY29uc3RydWN0b3Igc3luY2hyb25vdXNseSBpbnZva2VzIGl0c1xuICAgICAgICAvLyBleGVjdXRvciBjYWxsYmFjaywgYW5kIHdoeSBhc3luYyBmdW5jdGlvbnMgc3luY2hyb25vdXNseVxuICAgICAgICAvLyBleGVjdXRlIGNvZGUgYmVmb3JlIHRoZSBmaXJzdCBhd2FpdC4gU2luY2Ugd2UgaW1wbGVtZW50IHNpbXBsZVxuICAgICAgICAvLyBhc3luYyBmdW5jdGlvbnMgaW4gdGVybXMgb2YgYXN5bmMgZ2VuZXJhdG9ycywgaXQgaXMgZXNwZWNpYWxseVxuICAgICAgICAvLyBpbXBvcnRhbnQgdG8gZ2V0IHRoaXMgcmlnaHQsIGV2ZW4gdGhvdWdoIGl0IHJlcXVpcmVzIGNhcmUuXG4gICAgICAgIHByZXZpb3VzUHJvbWlzZSA/IHByZXZpb3VzUHJvbWlzZS50aGVuKFxuICAgICAgICAgIGNhbGxJbnZva2VXaXRoTWV0aG9kQW5kQXJnLFxuICAgICAgICAgIC8vIEF2b2lkIHByb3BhZ2F0aW5nIGZhaWx1cmVzIHRvIFByb21pc2VzIHJldHVybmVkIGJ5IGxhdGVyXG4gICAgICAgICAgLy8gaW52b2NhdGlvbnMgb2YgdGhlIGl0ZXJhdG9yLlxuICAgICAgICAgIGNhbGxJbnZva2VXaXRoTWV0aG9kQW5kQXJnXG4gICAgICAgICkgOiBjYWxsSW52b2tlV2l0aE1ldGhvZEFuZEFyZygpO1xuICAgIH1cblxuICAgIC8vIERlZmluZSB0aGUgdW5pZmllZCBoZWxwZXIgbWV0aG9kIHRoYXQgaXMgdXNlZCB0byBpbXBsZW1lbnQgLm5leHQsXG4gICAgLy8gLnRocm93LCBhbmQgLnJldHVybiAoc2VlIGRlZmluZUl0ZXJhdG9yTWV0aG9kcykuXG4gICAgdGhpcy5faW52b2tlID0gZW5xdWV1ZTtcbiAgfVxuXG4gIGRlZmluZUl0ZXJhdG9yTWV0aG9kcyhBc3luY0l0ZXJhdG9yLnByb3RvdHlwZSk7XG4gIEFzeW5jSXRlcmF0b3IucHJvdG90eXBlW2FzeW5jSXRlcmF0b3JTeW1ib2xdID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzO1xuICB9O1xuICBydW50aW1lLkFzeW5jSXRlcmF0b3IgPSBBc3luY0l0ZXJhdG9yO1xuXG4gIC8vIE5vdGUgdGhhdCBzaW1wbGUgYXN5bmMgZnVuY3Rpb25zIGFyZSBpbXBsZW1lbnRlZCBvbiB0b3Agb2ZcbiAgLy8gQXN5bmNJdGVyYXRvciBvYmplY3RzOyB0aGV5IGp1c3QgcmV0dXJuIGEgUHJvbWlzZSBmb3IgdGhlIHZhbHVlIG9mXG4gIC8vIHRoZSBmaW5hbCByZXN1bHQgcHJvZHVjZWQgYnkgdGhlIGl0ZXJhdG9yLlxuICBydW50aW1lLmFzeW5jID0gZnVuY3Rpb24oaW5uZXJGbiwgb3V0ZXJGbiwgc2VsZiwgdHJ5TG9jc0xpc3QpIHtcbiAgICB2YXIgaXRlciA9IG5ldyBBc3luY0l0ZXJhdG9yKFxuICAgICAgd3JhcChpbm5lckZuLCBvdXRlckZuLCBzZWxmLCB0cnlMb2NzTGlzdClcbiAgICApO1xuXG4gICAgcmV0dXJuIHJ1bnRpbWUuaXNHZW5lcmF0b3JGdW5jdGlvbihvdXRlckZuKVxuICAgICAgPyBpdGVyIC8vIElmIG91dGVyRm4gaXMgYSBnZW5lcmF0b3IsIHJldHVybiB0aGUgZnVsbCBpdGVyYXRvci5cbiAgICAgIDogaXRlci5uZXh0KCkudGhlbihmdW5jdGlvbihyZXN1bHQpIHtcbiAgICAgICAgICByZXR1cm4gcmVzdWx0LmRvbmUgPyByZXN1bHQudmFsdWUgOiBpdGVyLm5leHQoKTtcbiAgICAgICAgfSk7XG4gIH07XG5cbiAgZnVuY3Rpb24gbWFrZUludm9rZU1ldGhvZChpbm5lckZuLCBzZWxmLCBjb250ZXh0KSB7XG4gICAgdmFyIHN0YXRlID0gR2VuU3RhdGVTdXNwZW5kZWRTdGFydDtcblxuICAgIHJldHVybiBmdW5jdGlvbiBpbnZva2UobWV0aG9kLCBhcmcpIHtcbiAgICAgIGlmIChzdGF0ZSA9PT0gR2VuU3RhdGVFeGVjdXRpbmcpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiR2VuZXJhdG9yIGlzIGFscmVhZHkgcnVubmluZ1wiKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHN0YXRlID09PSBHZW5TdGF0ZUNvbXBsZXRlZCkge1xuICAgICAgICBpZiAobWV0aG9kID09PSBcInRocm93XCIpIHtcbiAgICAgICAgICB0aHJvdyBhcmc7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBCZSBmb3JnaXZpbmcsIHBlciAyNS4zLjMuMy4zIG9mIHRoZSBzcGVjOlxuICAgICAgICAvLyBodHRwczovL3Blb3BsZS5tb3ppbGxhLm9yZy9+am9yZW5kb3JmZi9lczYtZHJhZnQuaHRtbCNzZWMtZ2VuZXJhdG9ycmVzdW1lXG4gICAgICAgIHJldHVybiBkb25lUmVzdWx0KCk7XG4gICAgICB9XG5cbiAgICAgIGNvbnRleHQubWV0aG9kID0gbWV0aG9kO1xuICAgICAgY29udGV4dC5hcmcgPSBhcmc7XG5cbiAgICAgIHdoaWxlICh0cnVlKSB7XG4gICAgICAgIHZhciBkZWxlZ2F0ZSA9IGNvbnRleHQuZGVsZWdhdGU7XG4gICAgICAgIGlmIChkZWxlZ2F0ZSkge1xuICAgICAgICAgIHZhciBkZWxlZ2F0ZVJlc3VsdCA9IG1heWJlSW52b2tlRGVsZWdhdGUoZGVsZWdhdGUsIGNvbnRleHQpO1xuICAgICAgICAgIGlmIChkZWxlZ2F0ZVJlc3VsdCkge1xuICAgICAgICAgICAgaWYgKGRlbGVnYXRlUmVzdWx0ID09PSBDb250aW51ZVNlbnRpbmVsKSBjb250aW51ZTtcbiAgICAgICAgICAgIHJldHVybiBkZWxlZ2F0ZVJlc3VsdDtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoY29udGV4dC5tZXRob2QgPT09IFwibmV4dFwiKSB7XG4gICAgICAgICAgLy8gU2V0dGluZyBjb250ZXh0Ll9zZW50IGZvciBsZWdhY3kgc3VwcG9ydCBvZiBCYWJlbCdzXG4gICAgICAgICAgLy8gZnVuY3Rpb24uc2VudCBpbXBsZW1lbnRhdGlvbi5cbiAgICAgICAgICBjb250ZXh0LnNlbnQgPSBjb250ZXh0Ll9zZW50ID0gY29udGV4dC5hcmc7XG5cbiAgICAgICAgfSBlbHNlIGlmIChjb250ZXh0Lm1ldGhvZCA9PT0gXCJ0aHJvd1wiKSB7XG4gICAgICAgICAgaWYgKHN0YXRlID09PSBHZW5TdGF0ZVN1c3BlbmRlZFN0YXJ0KSB7XG4gICAgICAgICAgICBzdGF0ZSA9IEdlblN0YXRlQ29tcGxldGVkO1xuICAgICAgICAgICAgdGhyb3cgY29udGV4dC5hcmc7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgY29udGV4dC5kaXNwYXRjaEV4Y2VwdGlvbihjb250ZXh0LmFyZyk7XG5cbiAgICAgICAgfSBlbHNlIGlmIChjb250ZXh0Lm1ldGhvZCA9PT0gXCJyZXR1cm5cIikge1xuICAgICAgICAgIGNvbnRleHQuYWJydXB0KFwicmV0dXJuXCIsIGNvbnRleHQuYXJnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHN0YXRlID0gR2VuU3RhdGVFeGVjdXRpbmc7XG5cbiAgICAgICAgdmFyIHJlY29yZCA9IHRyeUNhdGNoKGlubmVyRm4sIHNlbGYsIGNvbnRleHQpO1xuICAgICAgICBpZiAocmVjb3JkLnR5cGUgPT09IFwibm9ybWFsXCIpIHtcbiAgICAgICAgICAvLyBJZiBhbiBleGNlcHRpb24gaXMgdGhyb3duIGZyb20gaW5uZXJGbiwgd2UgbGVhdmUgc3RhdGUgPT09XG4gICAgICAgICAgLy8gR2VuU3RhdGVFeGVjdXRpbmcgYW5kIGxvb3AgYmFjayBmb3IgYW5vdGhlciBpbnZvY2F0aW9uLlxuICAgICAgICAgIHN0YXRlID0gY29udGV4dC5kb25lXG4gICAgICAgICAgICA/IEdlblN0YXRlQ29tcGxldGVkXG4gICAgICAgICAgICA6IEdlblN0YXRlU3VzcGVuZGVkWWllbGQ7XG5cbiAgICAgICAgICBpZiAocmVjb3JkLmFyZyA9PT0gQ29udGludWVTZW50aW5lbCkge1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHZhbHVlOiByZWNvcmQuYXJnLFxuICAgICAgICAgICAgZG9uZTogY29udGV4dC5kb25lXG4gICAgICAgICAgfTtcblxuICAgICAgICB9IGVsc2UgaWYgKHJlY29yZC50eXBlID09PSBcInRocm93XCIpIHtcbiAgICAgICAgICBzdGF0ZSA9IEdlblN0YXRlQ29tcGxldGVkO1xuICAgICAgICAgIC8vIERpc3BhdGNoIHRoZSBleGNlcHRpb24gYnkgbG9vcGluZyBiYWNrIGFyb3VuZCB0byB0aGVcbiAgICAgICAgICAvLyBjb250ZXh0LmRpc3BhdGNoRXhjZXB0aW9uKGNvbnRleHQuYXJnKSBjYWxsIGFib3ZlLlxuICAgICAgICAgIGNvbnRleHQubWV0aG9kID0gXCJ0aHJvd1wiO1xuICAgICAgICAgIGNvbnRleHQuYXJnID0gcmVjb3JkLmFyZztcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH07XG4gIH1cblxuICAvLyBDYWxsIGRlbGVnYXRlLml0ZXJhdG9yW2NvbnRleHQubWV0aG9kXShjb250ZXh0LmFyZykgYW5kIGhhbmRsZSB0aGVcbiAgLy8gcmVzdWx0LCBlaXRoZXIgYnkgcmV0dXJuaW5nIGEgeyB2YWx1ZSwgZG9uZSB9IHJlc3VsdCBmcm9tIHRoZVxuICAvLyBkZWxlZ2F0ZSBpdGVyYXRvciwgb3IgYnkgbW9kaWZ5aW5nIGNvbnRleHQubWV0aG9kIGFuZCBjb250ZXh0LmFyZyxcbiAgLy8gc2V0dGluZyBjb250ZXh0LmRlbGVnYXRlIHRvIG51bGwsIGFuZCByZXR1cm5pbmcgdGhlIENvbnRpbnVlU2VudGluZWwuXG4gIGZ1bmN0aW9uIG1heWJlSW52b2tlRGVsZWdhdGUoZGVsZWdhdGUsIGNvbnRleHQpIHtcbiAgICB2YXIgbWV0aG9kID0gZGVsZWdhdGUuaXRlcmF0b3JbY29udGV4dC5tZXRob2RdO1xuICAgIGlmIChtZXRob2QgPT09IHVuZGVmaW5lZCkge1xuICAgICAgLy8gQSAudGhyb3cgb3IgLnJldHVybiB3aGVuIHRoZSBkZWxlZ2F0ZSBpdGVyYXRvciBoYXMgbm8gLnRocm93XG4gICAgICAvLyBtZXRob2QgYWx3YXlzIHRlcm1pbmF0ZXMgdGhlIHlpZWxkKiBsb29wLlxuICAgICAgY29udGV4dC5kZWxlZ2F0ZSA9IG51bGw7XG5cbiAgICAgIGlmIChjb250ZXh0Lm1ldGhvZCA9PT0gXCJ0aHJvd1wiKSB7XG4gICAgICAgIGlmIChkZWxlZ2F0ZS5pdGVyYXRvci5yZXR1cm4pIHtcbiAgICAgICAgICAvLyBJZiB0aGUgZGVsZWdhdGUgaXRlcmF0b3IgaGFzIGEgcmV0dXJuIG1ldGhvZCwgZ2l2ZSBpdCBhXG4gICAgICAgICAgLy8gY2hhbmNlIHRvIGNsZWFuIHVwLlxuICAgICAgICAgIGNvbnRleHQubWV0aG9kID0gXCJyZXR1cm5cIjtcbiAgICAgICAgICBjb250ZXh0LmFyZyA9IHVuZGVmaW5lZDtcbiAgICAgICAgICBtYXliZUludm9rZURlbGVnYXRlKGRlbGVnYXRlLCBjb250ZXh0KTtcblxuICAgICAgICAgIGlmIChjb250ZXh0Lm1ldGhvZCA9PT0gXCJ0aHJvd1wiKSB7XG4gICAgICAgICAgICAvLyBJZiBtYXliZUludm9rZURlbGVnYXRlKGNvbnRleHQpIGNoYW5nZWQgY29udGV4dC5tZXRob2QgZnJvbVxuICAgICAgICAgICAgLy8gXCJyZXR1cm5cIiB0byBcInRocm93XCIsIGxldCB0aGF0IG92ZXJyaWRlIHRoZSBUeXBlRXJyb3IgYmVsb3cuXG4gICAgICAgICAgICByZXR1cm4gQ29udGludWVTZW50aW5lbDtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBjb250ZXh0Lm1ldGhvZCA9IFwidGhyb3dcIjtcbiAgICAgICAgY29udGV4dC5hcmcgPSBuZXcgVHlwZUVycm9yKFxuICAgICAgICAgIFwiVGhlIGl0ZXJhdG9yIGRvZXMgbm90IHByb3ZpZGUgYSAndGhyb3cnIG1ldGhvZFwiKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIENvbnRpbnVlU2VudGluZWw7XG4gICAgfVxuXG4gICAgdmFyIHJlY29yZCA9IHRyeUNhdGNoKG1ldGhvZCwgZGVsZWdhdGUuaXRlcmF0b3IsIGNvbnRleHQuYXJnKTtcblxuICAgIGlmIChyZWNvcmQudHlwZSA9PT0gXCJ0aHJvd1wiKSB7XG4gICAgICBjb250ZXh0Lm1ldGhvZCA9IFwidGhyb3dcIjtcbiAgICAgIGNvbnRleHQuYXJnID0gcmVjb3JkLmFyZztcbiAgICAgIGNvbnRleHQuZGVsZWdhdGUgPSBudWxsO1xuICAgICAgcmV0dXJuIENvbnRpbnVlU2VudGluZWw7XG4gICAgfVxuXG4gICAgdmFyIGluZm8gPSByZWNvcmQuYXJnO1xuXG4gICAgaWYgKCEgaW5mbykge1xuICAgICAgY29udGV4dC5tZXRob2QgPSBcInRocm93XCI7XG4gICAgICBjb250ZXh0LmFyZyA9IG5ldyBUeXBlRXJyb3IoXCJpdGVyYXRvciByZXN1bHQgaXMgbm90IGFuIG9iamVjdFwiKTtcbiAgICAgIGNvbnRleHQuZGVsZWdhdGUgPSBudWxsO1xuICAgICAgcmV0dXJuIENvbnRpbnVlU2VudGluZWw7XG4gICAgfVxuXG4gICAgaWYgKGluZm8uZG9uZSkge1xuICAgICAgLy8gQXNzaWduIHRoZSByZXN1bHQgb2YgdGhlIGZpbmlzaGVkIGRlbGVnYXRlIHRvIHRoZSB0ZW1wb3JhcnlcbiAgICAgIC8vIHZhcmlhYmxlIHNwZWNpZmllZCBieSBkZWxlZ2F0ZS5yZXN1bHROYW1lIChzZWUgZGVsZWdhdGVZaWVsZCkuXG4gICAgICBjb250ZXh0W2RlbGVnYXRlLnJlc3VsdE5hbWVdID0gaW5mby52YWx1ZTtcblxuICAgICAgLy8gUmVzdW1lIGV4ZWN1dGlvbiBhdCB0aGUgZGVzaXJlZCBsb2NhdGlvbiAoc2VlIGRlbGVnYXRlWWllbGQpLlxuICAgICAgY29udGV4dC5uZXh0ID0gZGVsZWdhdGUubmV4dExvYztcblxuICAgICAgLy8gSWYgY29udGV4dC5tZXRob2Qgd2FzIFwidGhyb3dcIiBidXQgdGhlIGRlbGVnYXRlIGhhbmRsZWQgdGhlXG4gICAgICAvLyBleGNlcHRpb24sIGxldCB0aGUgb3V0ZXIgZ2VuZXJhdG9yIHByb2NlZWQgbm9ybWFsbHkuIElmXG4gICAgICAvLyBjb250ZXh0Lm1ldGhvZCB3YXMgXCJuZXh0XCIsIGZvcmdldCBjb250ZXh0LmFyZyBzaW5jZSBpdCBoYXMgYmVlblxuICAgICAgLy8gXCJjb25zdW1lZFwiIGJ5IHRoZSBkZWxlZ2F0ZSBpdGVyYXRvci4gSWYgY29udGV4dC5tZXRob2Qgd2FzXG4gICAgICAvLyBcInJldHVyblwiLCBhbGxvdyB0aGUgb3JpZ2luYWwgLnJldHVybiBjYWxsIHRvIGNvbnRpbnVlIGluIHRoZVxuICAgICAgLy8gb3V0ZXIgZ2VuZXJhdG9yLlxuICAgICAgaWYgKGNvbnRleHQubWV0aG9kICE9PSBcInJldHVyblwiKSB7XG4gICAgICAgIGNvbnRleHQubWV0aG9kID0gXCJuZXh0XCI7XG4gICAgICAgIGNvbnRleHQuYXJnID0gdW5kZWZpbmVkO1xuICAgICAgfVxuXG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIFJlLXlpZWxkIHRoZSByZXN1bHQgcmV0dXJuZWQgYnkgdGhlIGRlbGVnYXRlIG1ldGhvZC5cbiAgICAgIHJldHVybiBpbmZvO1xuICAgIH1cblxuICAgIC8vIFRoZSBkZWxlZ2F0ZSBpdGVyYXRvciBpcyBmaW5pc2hlZCwgc28gZm9yZ2V0IGl0IGFuZCBjb250aW51ZSB3aXRoXG4gICAgLy8gdGhlIG91dGVyIGdlbmVyYXRvci5cbiAgICBjb250ZXh0LmRlbGVnYXRlID0gbnVsbDtcbiAgICByZXR1cm4gQ29udGludWVTZW50aW5lbDtcbiAgfVxuXG4gIC8vIERlZmluZSBHZW5lcmF0b3IucHJvdG90eXBlLntuZXh0LHRocm93LHJldHVybn0gaW4gdGVybXMgb2YgdGhlXG4gIC8vIHVuaWZpZWQgLl9pbnZva2UgaGVscGVyIG1ldGhvZC5cbiAgZGVmaW5lSXRlcmF0b3JNZXRob2RzKEdwKTtcblxuICBHcFt0b1N0cmluZ1RhZ1N5bWJvbF0gPSBcIkdlbmVyYXRvclwiO1xuXG4gIC8vIEEgR2VuZXJhdG9yIHNob3VsZCBhbHdheXMgcmV0dXJuIGl0c2VsZiBhcyB0aGUgaXRlcmF0b3Igb2JqZWN0IHdoZW4gdGhlXG4gIC8vIEBAaXRlcmF0b3IgZnVuY3Rpb24gaXMgY2FsbGVkIG9uIGl0LiBTb21lIGJyb3dzZXJzJyBpbXBsZW1lbnRhdGlvbnMgb2YgdGhlXG4gIC8vIGl0ZXJhdG9yIHByb3RvdHlwZSBjaGFpbiBpbmNvcnJlY3RseSBpbXBsZW1lbnQgdGhpcywgY2F1c2luZyB0aGUgR2VuZXJhdG9yXG4gIC8vIG9iamVjdCB0byBub3QgYmUgcmV0dXJuZWQgZnJvbSB0aGlzIGNhbGwuIFRoaXMgZW5zdXJlcyB0aGF0IGRvZXNuJ3QgaGFwcGVuLlxuICAvLyBTZWUgaHR0cHM6Ly9naXRodWIuY29tL2ZhY2Vib29rL3JlZ2VuZXJhdG9yL2lzc3Vlcy8yNzQgZm9yIG1vcmUgZGV0YWlscy5cbiAgR3BbaXRlcmF0b3JTeW1ib2xdID0gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH07XG5cbiAgR3AudG9TdHJpbmcgPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gXCJbb2JqZWN0IEdlbmVyYXRvcl1cIjtcbiAgfTtcblxuICBmdW5jdGlvbiBwdXNoVHJ5RW50cnkobG9jcykge1xuICAgIHZhciBlbnRyeSA9IHsgdHJ5TG9jOiBsb2NzWzBdIH07XG5cbiAgICBpZiAoMSBpbiBsb2NzKSB7XG4gICAgICBlbnRyeS5jYXRjaExvYyA9IGxvY3NbMV07XG4gICAgfVxuXG4gICAgaWYgKDIgaW4gbG9jcykge1xuICAgICAgZW50cnkuZmluYWxseUxvYyA9IGxvY3NbMl07XG4gICAgICBlbnRyeS5hZnRlckxvYyA9IGxvY3NbM107XG4gICAgfVxuXG4gICAgdGhpcy50cnlFbnRyaWVzLnB1c2goZW50cnkpO1xuICB9XG5cbiAgZnVuY3Rpb24gcmVzZXRUcnlFbnRyeShlbnRyeSkge1xuICAgIHZhciByZWNvcmQgPSBlbnRyeS5jb21wbGV0aW9uIHx8IHt9O1xuICAgIHJlY29yZC50eXBlID0gXCJub3JtYWxcIjtcbiAgICBkZWxldGUgcmVjb3JkLmFyZztcbiAgICBlbnRyeS5jb21wbGV0aW9uID0gcmVjb3JkO1xuICB9XG5cbiAgZnVuY3Rpb24gQ29udGV4dCh0cnlMb2NzTGlzdCkge1xuICAgIC8vIFRoZSByb290IGVudHJ5IG9iamVjdCAoZWZmZWN0aXZlbHkgYSB0cnkgc3RhdGVtZW50IHdpdGhvdXQgYSBjYXRjaFxuICAgIC8vIG9yIGEgZmluYWxseSBibG9jaykgZ2l2ZXMgdXMgYSBwbGFjZSB0byBzdG9yZSB2YWx1ZXMgdGhyb3duIGZyb21cbiAgICAvLyBsb2NhdGlvbnMgd2hlcmUgdGhlcmUgaXMgbm8gZW5jbG9zaW5nIHRyeSBzdGF0ZW1lbnQuXG4gICAgdGhpcy50cnlFbnRyaWVzID0gW3sgdHJ5TG9jOiBcInJvb3RcIiB9XTtcbiAgICB0cnlMb2NzTGlzdC5mb3JFYWNoKHB1c2hUcnlFbnRyeSwgdGhpcyk7XG4gICAgdGhpcy5yZXNldCh0cnVlKTtcbiAgfVxuXG4gIHJ1bnRpbWUua2V5cyA9IGZ1bmN0aW9uKG9iamVjdCkge1xuICAgIHZhciBrZXlzID0gW107XG4gICAgZm9yICh2YXIga2V5IGluIG9iamVjdCkge1xuICAgICAga2V5cy5wdXNoKGtleSk7XG4gICAgfVxuICAgIGtleXMucmV2ZXJzZSgpO1xuXG4gICAgLy8gUmF0aGVyIHRoYW4gcmV0dXJuaW5nIGFuIG9iamVjdCB3aXRoIGEgbmV4dCBtZXRob2QsIHdlIGtlZXBcbiAgICAvLyB0aGluZ3Mgc2ltcGxlIGFuZCByZXR1cm4gdGhlIG5leHQgZnVuY3Rpb24gaXRzZWxmLlxuICAgIHJldHVybiBmdW5jdGlvbiBuZXh0KCkge1xuICAgICAgd2hpbGUgKGtleXMubGVuZ3RoKSB7XG4gICAgICAgIHZhciBrZXkgPSBrZXlzLnBvcCgpO1xuICAgICAgICBpZiAoa2V5IGluIG9iamVjdCkge1xuICAgICAgICAgIG5leHQudmFsdWUgPSBrZXk7XG4gICAgICAgICAgbmV4dC5kb25lID0gZmFsc2U7XG4gICAgICAgICAgcmV0dXJuIG5leHQ7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gVG8gYXZvaWQgY3JlYXRpbmcgYW4gYWRkaXRpb25hbCBvYmplY3QsIHdlIGp1c3QgaGFuZyB0aGUgLnZhbHVlXG4gICAgICAvLyBhbmQgLmRvbmUgcHJvcGVydGllcyBvZmYgdGhlIG5leHQgZnVuY3Rpb24gb2JqZWN0IGl0c2VsZi4gVGhpc1xuICAgICAgLy8gYWxzbyBlbnN1cmVzIHRoYXQgdGhlIG1pbmlmaWVyIHdpbGwgbm90IGFub255bWl6ZSB0aGUgZnVuY3Rpb24uXG4gICAgICBuZXh0LmRvbmUgPSB0cnVlO1xuICAgICAgcmV0dXJuIG5leHQ7XG4gICAgfTtcbiAgfTtcblxuICBmdW5jdGlvbiB2YWx1ZXMoaXRlcmFibGUpIHtcbiAgICBpZiAoaXRlcmFibGUpIHtcbiAgICAgIHZhciBpdGVyYXRvck1ldGhvZCA9IGl0ZXJhYmxlW2l0ZXJhdG9yU3ltYm9sXTtcbiAgICAgIGlmIChpdGVyYXRvck1ldGhvZCkge1xuICAgICAgICByZXR1cm4gaXRlcmF0b3JNZXRob2QuY2FsbChpdGVyYWJsZSk7XG4gICAgICB9XG5cbiAgICAgIGlmICh0eXBlb2YgaXRlcmFibGUubmV4dCA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgIHJldHVybiBpdGVyYWJsZTtcbiAgICAgIH1cblxuICAgICAgaWYgKCFpc05hTihpdGVyYWJsZS5sZW5ndGgpKSB7XG4gICAgICAgIHZhciBpID0gLTEsIG5leHQgPSBmdW5jdGlvbiBuZXh0KCkge1xuICAgICAgICAgIHdoaWxlICgrK2kgPCBpdGVyYWJsZS5sZW5ndGgpIHtcbiAgICAgICAgICAgIGlmIChoYXNPd24uY2FsbChpdGVyYWJsZSwgaSkpIHtcbiAgICAgICAgICAgICAgbmV4dC52YWx1ZSA9IGl0ZXJhYmxlW2ldO1xuICAgICAgICAgICAgICBuZXh0LmRvbmUgPSBmYWxzZTtcbiAgICAgICAgICAgICAgcmV0dXJuIG5leHQ7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgbmV4dC52YWx1ZSA9IHVuZGVmaW5lZDtcbiAgICAgICAgICBuZXh0LmRvbmUgPSB0cnVlO1xuXG4gICAgICAgICAgcmV0dXJuIG5leHQ7XG4gICAgICAgIH07XG5cbiAgICAgICAgcmV0dXJuIG5leHQubmV4dCA9IG5leHQ7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gUmV0dXJuIGFuIGl0ZXJhdG9yIHdpdGggbm8gdmFsdWVzLlxuICAgIHJldHVybiB7IG5leHQ6IGRvbmVSZXN1bHQgfTtcbiAgfVxuICBydW50aW1lLnZhbHVlcyA9IHZhbHVlcztcblxuICBmdW5jdGlvbiBkb25lUmVzdWx0KCkge1xuICAgIHJldHVybiB7IHZhbHVlOiB1bmRlZmluZWQsIGRvbmU6IHRydWUgfTtcbiAgfVxuXG4gIENvbnRleHQucHJvdG90eXBlID0ge1xuICAgIGNvbnN0cnVjdG9yOiBDb250ZXh0LFxuXG4gICAgcmVzZXQ6IGZ1bmN0aW9uKHNraXBUZW1wUmVzZXQpIHtcbiAgICAgIHRoaXMucHJldiA9IDA7XG4gICAgICB0aGlzLm5leHQgPSAwO1xuICAgICAgLy8gUmVzZXR0aW5nIGNvbnRleHQuX3NlbnQgZm9yIGxlZ2FjeSBzdXBwb3J0IG9mIEJhYmVsJ3NcbiAgICAgIC8vIGZ1bmN0aW9uLnNlbnQgaW1wbGVtZW50YXRpb24uXG4gICAgICB0aGlzLnNlbnQgPSB0aGlzLl9zZW50ID0gdW5kZWZpbmVkO1xuICAgICAgdGhpcy5kb25lID0gZmFsc2U7XG4gICAgICB0aGlzLmRlbGVnYXRlID0gbnVsbDtcblxuICAgICAgdGhpcy5tZXRob2QgPSBcIm5leHRcIjtcbiAgICAgIHRoaXMuYXJnID0gdW5kZWZpbmVkO1xuXG4gICAgICB0aGlzLnRyeUVudHJpZXMuZm9yRWFjaChyZXNldFRyeUVudHJ5KTtcblxuICAgICAgaWYgKCFza2lwVGVtcFJlc2V0KSB7XG4gICAgICAgIGZvciAodmFyIG5hbWUgaW4gdGhpcykge1xuICAgICAgICAgIC8vIE5vdCBzdXJlIGFib3V0IHRoZSBvcHRpbWFsIG9yZGVyIG9mIHRoZXNlIGNvbmRpdGlvbnM6XG4gICAgICAgICAgaWYgKG5hbWUuY2hhckF0KDApID09PSBcInRcIiAmJlxuICAgICAgICAgICAgICBoYXNPd24uY2FsbCh0aGlzLCBuYW1lKSAmJlxuICAgICAgICAgICAgICAhaXNOYU4oK25hbWUuc2xpY2UoMSkpKSB7XG4gICAgICAgICAgICB0aGlzW25hbWVdID0gdW5kZWZpbmVkO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0sXG5cbiAgICBzdG9wOiBmdW5jdGlvbigpIHtcbiAgICAgIHRoaXMuZG9uZSA9IHRydWU7XG5cbiAgICAgIHZhciByb290RW50cnkgPSB0aGlzLnRyeUVudHJpZXNbMF07XG4gICAgICB2YXIgcm9vdFJlY29yZCA9IHJvb3RFbnRyeS5jb21wbGV0aW9uO1xuICAgICAgaWYgKHJvb3RSZWNvcmQudHlwZSA9PT0gXCJ0aHJvd1wiKSB7XG4gICAgICAgIHRocm93IHJvb3RSZWNvcmQuYXJnO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gdGhpcy5ydmFsO1xuICAgIH0sXG5cbiAgICBkaXNwYXRjaEV4Y2VwdGlvbjogZnVuY3Rpb24oZXhjZXB0aW9uKSB7XG4gICAgICBpZiAodGhpcy5kb25lKSB7XG4gICAgICAgIHRocm93IGV4Y2VwdGlvbjtcbiAgICAgIH1cblxuICAgICAgdmFyIGNvbnRleHQgPSB0aGlzO1xuICAgICAgZnVuY3Rpb24gaGFuZGxlKGxvYywgY2F1Z2h0KSB7XG4gICAgICAgIHJlY29yZC50eXBlID0gXCJ0aHJvd1wiO1xuICAgICAgICByZWNvcmQuYXJnID0gZXhjZXB0aW9uO1xuICAgICAgICBjb250ZXh0Lm5leHQgPSBsb2M7XG5cbiAgICAgICAgaWYgKGNhdWdodCkge1xuICAgICAgICAgIC8vIElmIHRoZSBkaXNwYXRjaGVkIGV4Y2VwdGlvbiB3YXMgY2F1Z2h0IGJ5IGEgY2F0Y2ggYmxvY2ssXG4gICAgICAgICAgLy8gdGhlbiBsZXQgdGhhdCBjYXRjaCBibG9jayBoYW5kbGUgdGhlIGV4Y2VwdGlvbiBub3JtYWxseS5cbiAgICAgICAgICBjb250ZXh0Lm1ldGhvZCA9IFwibmV4dFwiO1xuICAgICAgICAgIGNvbnRleHQuYXJnID0gdW5kZWZpbmVkO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuICEhIGNhdWdodDtcbiAgICAgIH1cblxuICAgICAgZm9yICh2YXIgaSA9IHRoaXMudHJ5RW50cmllcy5sZW5ndGggLSAxOyBpID49IDA7IC0taSkge1xuICAgICAgICB2YXIgZW50cnkgPSB0aGlzLnRyeUVudHJpZXNbaV07XG4gICAgICAgIHZhciByZWNvcmQgPSBlbnRyeS5jb21wbGV0aW9uO1xuXG4gICAgICAgIGlmIChlbnRyeS50cnlMb2MgPT09IFwicm9vdFwiKSB7XG4gICAgICAgICAgLy8gRXhjZXB0aW9uIHRocm93biBvdXRzaWRlIG9mIGFueSB0cnkgYmxvY2sgdGhhdCBjb3VsZCBoYW5kbGVcbiAgICAgICAgICAvLyBpdCwgc28gc2V0IHRoZSBjb21wbGV0aW9uIHZhbHVlIG9mIHRoZSBlbnRpcmUgZnVuY3Rpb24gdG9cbiAgICAgICAgICAvLyB0aHJvdyB0aGUgZXhjZXB0aW9uLlxuICAgICAgICAgIHJldHVybiBoYW5kbGUoXCJlbmRcIik7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoZW50cnkudHJ5TG9jIDw9IHRoaXMucHJldikge1xuICAgICAgICAgIHZhciBoYXNDYXRjaCA9IGhhc093bi5jYWxsKGVudHJ5LCBcImNhdGNoTG9jXCIpO1xuICAgICAgICAgIHZhciBoYXNGaW5hbGx5ID0gaGFzT3duLmNhbGwoZW50cnksIFwiZmluYWxseUxvY1wiKTtcblxuICAgICAgICAgIGlmIChoYXNDYXRjaCAmJiBoYXNGaW5hbGx5KSB7XG4gICAgICAgICAgICBpZiAodGhpcy5wcmV2IDwgZW50cnkuY2F0Y2hMb2MpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIGhhbmRsZShlbnRyeS5jYXRjaExvYywgdHJ1ZSk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHRoaXMucHJldiA8IGVudHJ5LmZpbmFsbHlMb2MpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIGhhbmRsZShlbnRyeS5maW5hbGx5TG9jKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgIH0gZWxzZSBpZiAoaGFzQ2F0Y2gpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLnByZXYgPCBlbnRyeS5jYXRjaExvYykge1xuICAgICAgICAgICAgICByZXR1cm4gaGFuZGxlKGVudHJ5LmNhdGNoTG9jLCB0cnVlKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgIH0gZWxzZSBpZiAoaGFzRmluYWxseSkge1xuICAgICAgICAgICAgaWYgKHRoaXMucHJldiA8IGVudHJ5LmZpbmFsbHlMb2MpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIGhhbmRsZShlbnRyeS5maW5hbGx5TG9jKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJ0cnkgc3RhdGVtZW50IHdpdGhvdXQgY2F0Y2ggb3IgZmluYWxseVwiKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9LFxuXG4gICAgYWJydXB0OiBmdW5jdGlvbih0eXBlLCBhcmcpIHtcbiAgICAgIGZvciAodmFyIGkgPSB0aGlzLnRyeUVudHJpZXMubGVuZ3RoIC0gMTsgaSA+PSAwOyAtLWkpIHtcbiAgICAgICAgdmFyIGVudHJ5ID0gdGhpcy50cnlFbnRyaWVzW2ldO1xuICAgICAgICBpZiAoZW50cnkudHJ5TG9jIDw9IHRoaXMucHJldiAmJlxuICAgICAgICAgICAgaGFzT3duLmNhbGwoZW50cnksIFwiZmluYWxseUxvY1wiKSAmJlxuICAgICAgICAgICAgdGhpcy5wcmV2IDwgZW50cnkuZmluYWxseUxvYykge1xuICAgICAgICAgIHZhciBmaW5hbGx5RW50cnkgPSBlbnRyeTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAoZmluYWxseUVudHJ5ICYmXG4gICAgICAgICAgKHR5cGUgPT09IFwiYnJlYWtcIiB8fFxuICAgICAgICAgICB0eXBlID09PSBcImNvbnRpbnVlXCIpICYmXG4gICAgICAgICAgZmluYWxseUVudHJ5LnRyeUxvYyA8PSBhcmcgJiZcbiAgICAgICAgICBhcmcgPD0gZmluYWxseUVudHJ5LmZpbmFsbHlMb2MpIHtcbiAgICAgICAgLy8gSWdub3JlIHRoZSBmaW5hbGx5IGVudHJ5IGlmIGNvbnRyb2wgaXMgbm90IGp1bXBpbmcgdG8gYVxuICAgICAgICAvLyBsb2NhdGlvbiBvdXRzaWRlIHRoZSB0cnkvY2F0Y2ggYmxvY2suXG4gICAgICAgIGZpbmFsbHlFbnRyeSA9IG51bGw7XG4gICAgICB9XG5cbiAgICAgIHZhciByZWNvcmQgPSBmaW5hbGx5RW50cnkgPyBmaW5hbGx5RW50cnkuY29tcGxldGlvbiA6IHt9O1xuICAgICAgcmVjb3JkLnR5cGUgPSB0eXBlO1xuICAgICAgcmVjb3JkLmFyZyA9IGFyZztcblxuICAgICAgaWYgKGZpbmFsbHlFbnRyeSkge1xuICAgICAgICB0aGlzLm1ldGhvZCA9IFwibmV4dFwiO1xuICAgICAgICB0aGlzLm5leHQgPSBmaW5hbGx5RW50cnkuZmluYWxseUxvYztcbiAgICAgICAgcmV0dXJuIENvbnRpbnVlU2VudGluZWw7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB0aGlzLmNvbXBsZXRlKHJlY29yZCk7XG4gICAgfSxcblxuICAgIGNvbXBsZXRlOiBmdW5jdGlvbihyZWNvcmQsIGFmdGVyTG9jKSB7XG4gICAgICBpZiAocmVjb3JkLnR5cGUgPT09IFwidGhyb3dcIikge1xuICAgICAgICB0aHJvdyByZWNvcmQuYXJnO1xuICAgICAgfVxuXG4gICAgICBpZiAocmVjb3JkLnR5cGUgPT09IFwiYnJlYWtcIiB8fFxuICAgICAgICAgIHJlY29yZC50eXBlID09PSBcImNvbnRpbnVlXCIpIHtcbiAgICAgICAgdGhpcy5uZXh0ID0gcmVjb3JkLmFyZztcbiAgICAgIH0gZWxzZSBpZiAocmVjb3JkLnR5cGUgPT09IFwicmV0dXJuXCIpIHtcbiAgICAgICAgdGhpcy5ydmFsID0gdGhpcy5hcmcgPSByZWNvcmQuYXJnO1xuICAgICAgICB0aGlzLm1ldGhvZCA9IFwicmV0dXJuXCI7XG4gICAgICAgIHRoaXMubmV4dCA9IFwiZW5kXCI7XG4gICAgICB9IGVsc2UgaWYgKHJlY29yZC50eXBlID09PSBcIm5vcm1hbFwiICYmIGFmdGVyTG9jKSB7XG4gICAgICAgIHRoaXMubmV4dCA9IGFmdGVyTG9jO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gQ29udGludWVTZW50aW5lbDtcbiAgICB9LFxuXG4gICAgZmluaXNoOiBmdW5jdGlvbihmaW5hbGx5TG9jKSB7XG4gICAgICBmb3IgKHZhciBpID0gdGhpcy50cnlFbnRyaWVzLmxlbmd0aCAtIDE7IGkgPj0gMDsgLS1pKSB7XG4gICAgICAgIHZhciBlbnRyeSA9IHRoaXMudHJ5RW50cmllc1tpXTtcbiAgICAgICAgaWYgKGVudHJ5LmZpbmFsbHlMb2MgPT09IGZpbmFsbHlMb2MpIHtcbiAgICAgICAgICB0aGlzLmNvbXBsZXRlKGVudHJ5LmNvbXBsZXRpb24sIGVudHJ5LmFmdGVyTG9jKTtcbiAgICAgICAgICByZXNldFRyeUVudHJ5KGVudHJ5KTtcbiAgICAgICAgICByZXR1cm4gQ29udGludWVTZW50aW5lbDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0sXG5cbiAgICBcImNhdGNoXCI6IGZ1bmN0aW9uKHRyeUxvYykge1xuICAgICAgZm9yICh2YXIgaSA9IHRoaXMudHJ5RW50cmllcy5sZW5ndGggLSAxOyBpID49IDA7IC0taSkge1xuICAgICAgICB2YXIgZW50cnkgPSB0aGlzLnRyeUVudHJpZXNbaV07XG4gICAgICAgIGlmIChlbnRyeS50cnlMb2MgPT09IHRyeUxvYykge1xuICAgICAgICAgIHZhciByZWNvcmQgPSBlbnRyeS5jb21wbGV0aW9uO1xuICAgICAgICAgIGlmIChyZWNvcmQudHlwZSA9PT0gXCJ0aHJvd1wiKSB7XG4gICAgICAgICAgICB2YXIgdGhyb3duID0gcmVjb3JkLmFyZztcbiAgICAgICAgICAgIHJlc2V0VHJ5RW50cnkoZW50cnkpO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gdGhyb3duO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIFRoZSBjb250ZXh0LmNhdGNoIG1ldGhvZCBtdXN0IG9ubHkgYmUgY2FsbGVkIHdpdGggYSBsb2NhdGlvblxuICAgICAgLy8gYXJndW1lbnQgdGhhdCBjb3JyZXNwb25kcyB0byBhIGtub3duIGNhdGNoIGJsb2NrLlxuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiaWxsZWdhbCBjYXRjaCBhdHRlbXB0XCIpO1xuICAgIH0sXG5cbiAgICBkZWxlZ2F0ZVlpZWxkOiBmdW5jdGlvbihpdGVyYWJsZSwgcmVzdWx0TmFtZSwgbmV4dExvYykge1xuICAgICAgdGhpcy5kZWxlZ2F0ZSA9IHtcbiAgICAgICAgaXRlcmF0b3I6IHZhbHVlcyhpdGVyYWJsZSksXG4gICAgICAgIHJlc3VsdE5hbWU6IHJlc3VsdE5hbWUsXG4gICAgICAgIG5leHRMb2M6IG5leHRMb2NcbiAgICAgIH07XG5cbiAgICAgIGlmICh0aGlzLm1ldGhvZCA9PT0gXCJuZXh0XCIpIHtcbiAgICAgICAgLy8gRGVsaWJlcmF0ZWx5IGZvcmdldCB0aGUgbGFzdCBzZW50IHZhbHVlIHNvIHRoYXQgd2UgZG9uJ3RcbiAgICAgICAgLy8gYWNjaWRlbnRhbGx5IHBhc3MgaXQgb24gdG8gdGhlIGRlbGVnYXRlLlxuICAgICAgICB0aGlzLmFyZyA9IHVuZGVmaW5lZDtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIENvbnRpbnVlU2VudGluZWw7XG4gICAgfVxuICB9O1xufSkoXG4gIC8vIEluIHNsb3BweSBtb2RlLCB1bmJvdW5kIGB0aGlzYCByZWZlcnMgdG8gdGhlIGdsb2JhbCBvYmplY3QsIGZhbGxiYWNrIHRvXG4gIC8vIEZ1bmN0aW9uIGNvbnN0cnVjdG9yIGlmIHdlJ3JlIGluIGdsb2JhbCBzdHJpY3QgbW9kZS4gVGhhdCBpcyBzYWRseSBhIGZvcm1cbiAgLy8gb2YgaW5kaXJlY3QgZXZhbCB3aGljaCB2aW9sYXRlcyBDb250ZW50IFNlY3VyaXR5IFBvbGljeS5cbiAgKGZ1bmN0aW9uKCkgeyByZXR1cm4gdGhpcyB9KSgpIHx8IEZ1bmN0aW9uKFwicmV0dXJuIHRoaXNcIikoKVxuKTtcbiIsImZ1bmN0aW9uIF9hcHBseURlY29yYXRlZERlc2NyaXB0b3IodGFyZ2V0LCBwcm9wZXJ0eSwgZGVjb3JhdG9ycywgZGVzY3JpcHRvciwgY29udGV4dCkge1xuICB2YXIgZGVzYyA9IHt9O1xuICBPYmplY3RbJ2tlJyArICd5cyddKGRlc2NyaXB0b3IpLmZvckVhY2goZnVuY3Rpb24gKGtleSkge1xuICAgIGRlc2Nba2V5XSA9IGRlc2NyaXB0b3Jba2V5XTtcbiAgfSk7XG4gIGRlc2MuZW51bWVyYWJsZSA9ICEhZGVzYy5lbnVtZXJhYmxlO1xuICBkZXNjLmNvbmZpZ3VyYWJsZSA9ICEhZGVzYy5jb25maWd1cmFibGU7XG5cbiAgaWYgKCd2YWx1ZScgaW4gZGVzYyB8fCBkZXNjLmluaXRpYWxpemVyKSB7XG4gICAgZGVzYy53cml0YWJsZSA9IHRydWU7XG4gIH1cblxuICBkZXNjID0gZGVjb3JhdG9ycy5zbGljZSgpLnJldmVyc2UoKS5yZWR1Y2UoZnVuY3Rpb24gKGRlc2MsIGRlY29yYXRvcikge1xuICAgIHJldHVybiBkZWNvcmF0b3IodGFyZ2V0LCBwcm9wZXJ0eSwgZGVzYykgfHwgZGVzYztcbiAgfSwgZGVzYyk7XG5cbiAgaWYgKGNvbnRleHQgJiYgZGVzYy5pbml0aWFsaXplciAhPT0gdm9pZCAwKSB7XG4gICAgZGVzYy52YWx1ZSA9IGRlc2MuaW5pdGlhbGl6ZXIgPyBkZXNjLmluaXRpYWxpemVyLmNhbGwoY29udGV4dCkgOiB2b2lkIDA7XG4gICAgZGVzYy5pbml0aWFsaXplciA9IHVuZGVmaW5lZDtcbiAgfVxuXG4gIGlmIChkZXNjLmluaXRpYWxpemVyID09PSB2b2lkIDApIHtcbiAgICBPYmplY3RbJ2RlZmluZScgKyAnUHJvcGVydHknXSh0YXJnZXQsIHByb3BlcnR5LCBkZXNjKTtcbiAgICBkZXNjID0gbnVsbDtcbiAgfVxuXG4gIHJldHVybiBkZXNjO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IF9hcHBseURlY29yYXRlZERlc2NyaXB0b3I7IiwiZnVuY3Rpb24gX2FycmF5V2l0aEhvbGVzKGFycikge1xuICBpZiAoQXJyYXkuaXNBcnJheShhcnIpKSByZXR1cm4gYXJyO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IF9hcnJheVdpdGhIb2xlczsiLCJmdW5jdGlvbiBfYXJyYXlXaXRob3V0SG9sZXMoYXJyKSB7XG4gIGlmIChBcnJheS5pc0FycmF5KGFycikpIHtcbiAgICBmb3IgKHZhciBpID0gMCwgYXJyMiA9IG5ldyBBcnJheShhcnIubGVuZ3RoKTsgaSA8IGFyci5sZW5ndGg7IGkrKykge1xuICAgICAgYXJyMltpXSA9IGFycltpXTtcbiAgICB9XG5cbiAgICByZXR1cm4gYXJyMjtcbiAgfVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IF9hcnJheVdpdGhvdXRIb2xlczsiLCJmdW5jdGlvbiBfYXNzZXJ0VGhpc0luaXRpYWxpemVkKHNlbGYpIHtcbiAgaWYgKHNlbGYgPT09IHZvaWQgMCkge1xuICAgIHRocm93IG5ldyBSZWZlcmVuY2VFcnJvcihcInRoaXMgaGFzbid0IGJlZW4gaW5pdGlhbGlzZWQgLSBzdXBlcigpIGhhc24ndCBiZWVuIGNhbGxlZFwiKTtcbiAgfVxuXG4gIHJldHVybiBzZWxmO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IF9hc3NlcnRUaGlzSW5pdGlhbGl6ZWQ7IiwiZnVuY3Rpb24gYXN5bmNHZW5lcmF0b3JTdGVwKGdlbiwgcmVzb2x2ZSwgcmVqZWN0LCBfbmV4dCwgX3Rocm93LCBrZXksIGFyZykge1xuICB0cnkge1xuICAgIHZhciBpbmZvID0gZ2VuW2tleV0oYXJnKTtcbiAgICB2YXIgdmFsdWUgPSBpbmZvLnZhbHVlO1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIHJlamVjdChlcnJvcik7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgaWYgKGluZm8uZG9uZSkge1xuICAgIHJlc29sdmUodmFsdWUpO1xuICB9IGVsc2Uge1xuICAgIFByb21pc2UucmVzb2x2ZSh2YWx1ZSkudGhlbihfbmV4dCwgX3Rocm93KTtcbiAgfVxufVxuXG5mdW5jdGlvbiBfYXN5bmNUb0dlbmVyYXRvcihmbikge1xuICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgIHZhciBzZWxmID0gdGhpcyxcbiAgICAgICAgYXJncyA9IGFyZ3VtZW50cztcbiAgICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xuICAgICAgdmFyIGdlbiA9IGZuLmFwcGx5KHNlbGYsIGFyZ3MpO1xuXG4gICAgICBmdW5jdGlvbiBfbmV4dCh2YWx1ZSkge1xuICAgICAgICBhc3luY0dlbmVyYXRvclN0ZXAoZ2VuLCByZXNvbHZlLCByZWplY3QsIF9uZXh0LCBfdGhyb3csIFwibmV4dFwiLCB2YWx1ZSk7XG4gICAgICB9XG5cbiAgICAgIGZ1bmN0aW9uIF90aHJvdyhlcnIpIHtcbiAgICAgICAgYXN5bmNHZW5lcmF0b3JTdGVwKGdlbiwgcmVzb2x2ZSwgcmVqZWN0LCBfbmV4dCwgX3Rocm93LCBcInRocm93XCIsIGVycik7XG4gICAgICB9XG5cbiAgICAgIF9uZXh0KHVuZGVmaW5lZCk7XG4gICAgfSk7XG4gIH07XG59XG5cbm1vZHVsZS5leHBvcnRzID0gX2FzeW5jVG9HZW5lcmF0b3I7IiwiZnVuY3Rpb24gX2NsYXNzQ2FsbENoZWNrKGluc3RhbmNlLCBDb25zdHJ1Y3Rvcikge1xuICBpZiAoIShpbnN0YW5jZSBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb25cIik7XG4gIH1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSBfY2xhc3NDYWxsQ2hlY2s7IiwidmFyIHNldFByb3RvdHlwZU9mID0gcmVxdWlyZShcIi4vc2V0UHJvdG90eXBlT2ZcIik7XG5cbmZ1bmN0aW9uIGlzTmF0aXZlUmVmbGVjdENvbnN0cnVjdCgpIHtcbiAgaWYgKHR5cGVvZiBSZWZsZWN0ID09PSBcInVuZGVmaW5lZFwiIHx8ICFSZWZsZWN0LmNvbnN0cnVjdCkgcmV0dXJuIGZhbHNlO1xuICBpZiAoUmVmbGVjdC5jb25zdHJ1Y3Quc2hhbSkgcmV0dXJuIGZhbHNlO1xuICBpZiAodHlwZW9mIFByb3h5ID09PSBcImZ1bmN0aW9uXCIpIHJldHVybiB0cnVlO1xuXG4gIHRyeSB7XG4gICAgRGF0ZS5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChSZWZsZWN0LmNvbnN0cnVjdChEYXRlLCBbXSwgZnVuY3Rpb24gKCkge30pKTtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxufVxuXG5mdW5jdGlvbiBfY29uc3RydWN0KFBhcmVudCwgYXJncywgQ2xhc3MpIHtcbiAgaWYgKGlzTmF0aXZlUmVmbGVjdENvbnN0cnVjdCgpKSB7XG4gICAgbW9kdWxlLmV4cG9ydHMgPSBfY29uc3RydWN0ID0gUmVmbGVjdC5jb25zdHJ1Y3Q7XG4gIH0gZWxzZSB7XG4gICAgbW9kdWxlLmV4cG9ydHMgPSBfY29uc3RydWN0ID0gZnVuY3Rpb24gX2NvbnN0cnVjdChQYXJlbnQsIGFyZ3MsIENsYXNzKSB7XG4gICAgICB2YXIgYSA9IFtudWxsXTtcbiAgICAgIGEucHVzaC5hcHBseShhLCBhcmdzKTtcbiAgICAgIHZhciBDb25zdHJ1Y3RvciA9IEZ1bmN0aW9uLmJpbmQuYXBwbHkoUGFyZW50LCBhKTtcbiAgICAgIHZhciBpbnN0YW5jZSA9IG5ldyBDb25zdHJ1Y3RvcigpO1xuICAgICAgaWYgKENsYXNzKSBzZXRQcm90b3R5cGVPZihpbnN0YW5jZSwgQ2xhc3MucHJvdG90eXBlKTtcbiAgICAgIHJldHVybiBpbnN0YW5jZTtcbiAgICB9O1xuICB9XG5cbiAgcmV0dXJuIF9jb25zdHJ1Y3QuYXBwbHkobnVsbCwgYXJndW1lbnRzKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBfY29uc3RydWN0OyIsImZ1bmN0aW9uIF9kZWZpbmVQcm9wZXJ0aWVzKHRhcmdldCwgcHJvcHMpIHtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBwcm9wcy5sZW5ndGg7IGkrKykge1xuICAgIHZhciBkZXNjcmlwdG9yID0gcHJvcHNbaV07XG4gICAgZGVzY3JpcHRvci5lbnVtZXJhYmxlID0gZGVzY3JpcHRvci5lbnVtZXJhYmxlIHx8IGZhbHNlO1xuICAgIGRlc2NyaXB0b3IuY29uZmlndXJhYmxlID0gdHJ1ZTtcbiAgICBpZiAoXCJ2YWx1ZVwiIGluIGRlc2NyaXB0b3IpIGRlc2NyaXB0b3Iud3JpdGFibGUgPSB0cnVlO1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGRlc2NyaXB0b3Iua2V5LCBkZXNjcmlwdG9yKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBfY3JlYXRlQ2xhc3MoQ29uc3RydWN0b3IsIHByb3RvUHJvcHMsIHN0YXRpY1Byb3BzKSB7XG4gIGlmIChwcm90b1Byb3BzKSBfZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvci5wcm90b3R5cGUsIHByb3RvUHJvcHMpO1xuICBpZiAoc3RhdGljUHJvcHMpIF9kZWZpbmVQcm9wZXJ0aWVzKENvbnN0cnVjdG9yLCBzdGF0aWNQcm9wcyk7XG4gIHJldHVybiBDb25zdHJ1Y3Rvcjtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBfY3JlYXRlQ2xhc3M7IiwiZnVuY3Rpb24gX2RlZmluZVByb3BlcnR5KG9iaiwga2V5LCB2YWx1ZSkge1xuICBpZiAoa2V5IGluIG9iaikge1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShvYmosIGtleSwge1xuICAgICAgdmFsdWU6IHZhbHVlLFxuICAgICAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgIHdyaXRhYmxlOiB0cnVlXG4gICAgfSk7XG4gIH0gZWxzZSB7XG4gICAgb2JqW2tleV0gPSB2YWx1ZTtcbiAgfVxuXG4gIHJldHVybiBvYmo7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gX2RlZmluZVByb3BlcnR5OyIsImZ1bmN0aW9uIF9nZXRQcm90b3R5cGVPZihvKSB7XG4gIG1vZHVsZS5leHBvcnRzID0gX2dldFByb3RvdHlwZU9mID0gT2JqZWN0LnNldFByb3RvdHlwZU9mID8gT2JqZWN0LmdldFByb3RvdHlwZU9mIDogZnVuY3Rpb24gX2dldFByb3RvdHlwZU9mKG8pIHtcbiAgICByZXR1cm4gby5fX3Byb3RvX18gfHwgT2JqZWN0LmdldFByb3RvdHlwZU9mKG8pO1xuICB9O1xuICByZXR1cm4gX2dldFByb3RvdHlwZU9mKG8pO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IF9nZXRQcm90b3R5cGVPZjsiLCJ2YXIgc2V0UHJvdG90eXBlT2YgPSByZXF1aXJlKFwiLi9zZXRQcm90b3R5cGVPZlwiKTtcblxuZnVuY3Rpb24gX2luaGVyaXRzKHN1YkNsYXNzLCBzdXBlckNsYXNzKSB7XG4gIGlmICh0eXBlb2Ygc3VwZXJDbGFzcyAhPT0gXCJmdW5jdGlvblwiICYmIHN1cGVyQ2xhc3MgIT09IG51bGwpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiU3VwZXIgZXhwcmVzc2lvbiBtdXN0IGVpdGhlciBiZSBudWxsIG9yIGEgZnVuY3Rpb25cIik7XG4gIH1cblxuICBzdWJDbGFzcy5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKHN1cGVyQ2xhc3MgJiYgc3VwZXJDbGFzcy5wcm90b3R5cGUsIHtcbiAgICBjb25zdHJ1Y3Rvcjoge1xuICAgICAgdmFsdWU6IHN1YkNsYXNzLFxuICAgICAgd3JpdGFibGU6IHRydWUsXG4gICAgICBjb25maWd1cmFibGU6IHRydWVcbiAgICB9XG4gIH0pO1xuICBpZiAoc3VwZXJDbGFzcykgc2V0UHJvdG90eXBlT2Yoc3ViQ2xhc3MsIHN1cGVyQ2xhc3MpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IF9pbmhlcml0czsiLCJmdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikge1xuICByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDoge1xuICAgIGRlZmF1bHQ6IG9ialxuICB9O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQ7IiwiZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlV2lsZGNhcmQob2JqKSB7XG4gIGlmIChvYmogJiYgb2JqLl9fZXNNb2R1bGUpIHtcbiAgICByZXR1cm4gb2JqO1xuICB9IGVsc2Uge1xuICAgIHZhciBuZXdPYmogPSB7fTtcblxuICAgIGlmIChvYmogIT0gbnVsbCkge1xuICAgICAgZm9yICh2YXIga2V5IGluIG9iaikge1xuICAgICAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9iaiwga2V5KSkge1xuICAgICAgICAgIHZhciBkZXNjID0gT2JqZWN0LmRlZmluZVByb3BlcnR5ICYmIE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IgPyBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKG9iaiwga2V5KSA6IHt9O1xuXG4gICAgICAgICAgaWYgKGRlc2MuZ2V0IHx8IGRlc2Muc2V0KSB7XG4gICAgICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkobmV3T2JqLCBrZXksIGRlc2MpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBuZXdPYmpba2V5XSA9IG9ialtrZXldO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIG5ld09iai5kZWZhdWx0ID0gb2JqO1xuICAgIHJldHVybiBuZXdPYmo7XG4gIH1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSBfaW50ZXJvcFJlcXVpcmVXaWxkY2FyZDsiLCJmdW5jdGlvbiBfaXNOYXRpdmVGdW5jdGlvbihmbikge1xuICByZXR1cm4gRnVuY3Rpb24udG9TdHJpbmcuY2FsbChmbikuaW5kZXhPZihcIltuYXRpdmUgY29kZV1cIikgIT09IC0xO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IF9pc05hdGl2ZUZ1bmN0aW9uOyIsImZ1bmN0aW9uIF9pdGVyYWJsZVRvQXJyYXkoaXRlcikge1xuICBpZiAoU3ltYm9sLml0ZXJhdG9yIGluIE9iamVjdChpdGVyKSB8fCBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoaXRlcikgPT09IFwiW29iamVjdCBBcmd1bWVudHNdXCIpIHJldHVybiBBcnJheS5mcm9tKGl0ZXIpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IF9pdGVyYWJsZVRvQXJyYXk7IiwiZnVuY3Rpb24gX2l0ZXJhYmxlVG9BcnJheUxpbWl0KGFyciwgaSkge1xuICB2YXIgX2FyciA9IFtdO1xuICB2YXIgX24gPSB0cnVlO1xuICB2YXIgX2QgPSBmYWxzZTtcbiAgdmFyIF9lID0gdW5kZWZpbmVkO1xuXG4gIHRyeSB7XG4gICAgZm9yICh2YXIgX2kgPSBhcnJbU3ltYm9sLml0ZXJhdG9yXSgpLCBfczsgIShfbiA9IChfcyA9IF9pLm5leHQoKSkuZG9uZSk7IF9uID0gdHJ1ZSkge1xuICAgICAgX2Fyci5wdXNoKF9zLnZhbHVlKTtcblxuICAgICAgaWYgKGkgJiYgX2Fyci5sZW5ndGggPT09IGkpIGJyZWFrO1xuICAgIH1cbiAgfSBjYXRjaCAoZXJyKSB7XG4gICAgX2QgPSB0cnVlO1xuICAgIF9lID0gZXJyO1xuICB9IGZpbmFsbHkge1xuICAgIHRyeSB7XG4gICAgICBpZiAoIV9uICYmIF9pW1wicmV0dXJuXCJdICE9IG51bGwpIF9pW1wicmV0dXJuXCJdKCk7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIGlmIChfZCkgdGhyb3cgX2U7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIF9hcnI7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gX2l0ZXJhYmxlVG9BcnJheUxpbWl0OyIsImZ1bmN0aW9uIF9ub25JdGVyYWJsZVJlc3QoKSB7XG4gIHRocm93IG5ldyBUeXBlRXJyb3IoXCJJbnZhbGlkIGF0dGVtcHQgdG8gZGVzdHJ1Y3R1cmUgbm9uLWl0ZXJhYmxlIGluc3RhbmNlXCIpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IF9ub25JdGVyYWJsZVJlc3Q7IiwiZnVuY3Rpb24gX25vbkl0ZXJhYmxlU3ByZWFkKCkge1xuICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiSW52YWxpZCBhdHRlbXB0IHRvIHNwcmVhZCBub24taXRlcmFibGUgaW5zdGFuY2VcIik7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gX25vbkl0ZXJhYmxlU3ByZWFkOyIsInZhciBkZWZpbmVQcm9wZXJ0eSA9IHJlcXVpcmUoXCIuL2RlZmluZVByb3BlcnR5XCIpO1xuXG5mdW5jdGlvbiBfb2JqZWN0U3ByZWFkKHRhcmdldCkge1xuICBmb3IgKHZhciBpID0gMTsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykge1xuICAgIHZhciBzb3VyY2UgPSBhcmd1bWVudHNbaV0gIT0gbnVsbCA/IGFyZ3VtZW50c1tpXSA6IHt9O1xuICAgIHZhciBvd25LZXlzID0gT2JqZWN0LmtleXMoc291cmNlKTtcblxuICAgIGlmICh0eXBlb2YgT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgb3duS2V5cyA9IG93bktleXMuY29uY2F0KE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMoc291cmNlKS5maWx0ZXIoZnVuY3Rpb24gKHN5bSkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihzb3VyY2UsIHN5bSkuZW51bWVyYWJsZTtcbiAgICAgIH0pKTtcbiAgICB9XG5cbiAgICBvd25LZXlzLmZvckVhY2goZnVuY3Rpb24gKGtleSkge1xuICAgICAgZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBrZXksIHNvdXJjZVtrZXldKTtcbiAgICB9KTtcbiAgfVxuXG4gIHJldHVybiB0YXJnZXQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gX29iamVjdFNwcmVhZDsiLCJ2YXIgX3R5cGVvZiA9IHJlcXVpcmUoXCIuLi9oZWxwZXJzL3R5cGVvZlwiKTtcblxudmFyIGFzc2VydFRoaXNJbml0aWFsaXplZCA9IHJlcXVpcmUoXCIuL2Fzc2VydFRoaXNJbml0aWFsaXplZFwiKTtcblxuZnVuY3Rpb24gX3Bvc3NpYmxlQ29uc3RydWN0b3JSZXR1cm4oc2VsZiwgY2FsbCkge1xuICBpZiAoY2FsbCAmJiAoX3R5cGVvZihjYWxsKSA9PT0gXCJvYmplY3RcIiB8fCB0eXBlb2YgY2FsbCA9PT0gXCJmdW5jdGlvblwiKSkge1xuICAgIHJldHVybiBjYWxsO1xuICB9XG5cbiAgcmV0dXJuIGFzc2VydFRoaXNJbml0aWFsaXplZChzZWxmKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBfcG9zc2libGVDb25zdHJ1Y3RvclJldHVybjsiLCJmdW5jdGlvbiBfc2V0UHJvdG90eXBlT2YobywgcCkge1xuICBtb2R1bGUuZXhwb3J0cyA9IF9zZXRQcm90b3R5cGVPZiA9IE9iamVjdC5zZXRQcm90b3R5cGVPZiB8fCBmdW5jdGlvbiBfc2V0UHJvdG90eXBlT2YobywgcCkge1xuICAgIG8uX19wcm90b19fID0gcDtcbiAgICByZXR1cm4gbztcbiAgfTtcblxuICByZXR1cm4gX3NldFByb3RvdHlwZU9mKG8sIHApO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IF9zZXRQcm90b3R5cGVPZjsiLCJ2YXIgYXJyYXlXaXRoSG9sZXMgPSByZXF1aXJlKFwiLi9hcnJheVdpdGhIb2xlc1wiKTtcblxudmFyIGl0ZXJhYmxlVG9BcnJheUxpbWl0ID0gcmVxdWlyZShcIi4vaXRlcmFibGVUb0FycmF5TGltaXRcIik7XG5cbnZhciBub25JdGVyYWJsZVJlc3QgPSByZXF1aXJlKFwiLi9ub25JdGVyYWJsZVJlc3RcIik7XG5cbmZ1bmN0aW9uIF9zbGljZWRUb0FycmF5KGFyciwgaSkge1xuICByZXR1cm4gYXJyYXlXaXRoSG9sZXMoYXJyKSB8fCBpdGVyYWJsZVRvQXJyYXlMaW1pdChhcnIsIGkpIHx8IG5vbkl0ZXJhYmxlUmVzdCgpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IF9zbGljZWRUb0FycmF5OyIsInZhciBhcnJheVdpdGhIb2xlcyA9IHJlcXVpcmUoXCIuL2FycmF5V2l0aEhvbGVzXCIpO1xuXG52YXIgaXRlcmFibGVUb0FycmF5ID0gcmVxdWlyZShcIi4vaXRlcmFibGVUb0FycmF5XCIpO1xuXG52YXIgbm9uSXRlcmFibGVSZXN0ID0gcmVxdWlyZShcIi4vbm9uSXRlcmFibGVSZXN0XCIpO1xuXG5mdW5jdGlvbiBfdG9BcnJheShhcnIpIHtcbiAgcmV0dXJuIGFycmF5V2l0aEhvbGVzKGFycikgfHwgaXRlcmFibGVUb0FycmF5KGFycikgfHwgbm9uSXRlcmFibGVSZXN0KCk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gX3RvQXJyYXk7IiwidmFyIGFycmF5V2l0aG91dEhvbGVzID0gcmVxdWlyZShcIi4vYXJyYXlXaXRob3V0SG9sZXNcIik7XG5cbnZhciBpdGVyYWJsZVRvQXJyYXkgPSByZXF1aXJlKFwiLi9pdGVyYWJsZVRvQXJyYXlcIik7XG5cbnZhciBub25JdGVyYWJsZVNwcmVhZCA9IHJlcXVpcmUoXCIuL25vbkl0ZXJhYmxlU3ByZWFkXCIpO1xuXG5mdW5jdGlvbiBfdG9Db25zdW1hYmxlQXJyYXkoYXJyKSB7XG4gIHJldHVybiBhcnJheVdpdGhvdXRIb2xlcyhhcnIpIHx8IGl0ZXJhYmxlVG9BcnJheShhcnIpIHx8IG5vbkl0ZXJhYmxlU3ByZWFkKCk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gX3RvQ29uc3VtYWJsZUFycmF5OyIsImZ1bmN0aW9uIF90eXBlb2YyKG9iaikgeyBpZiAodHlwZW9mIFN5bWJvbCA9PT0gXCJmdW5jdGlvblwiICYmIHR5cGVvZiBTeW1ib2wuaXRlcmF0b3IgPT09IFwic3ltYm9sXCIpIHsgX3R5cGVvZjIgPSBmdW5jdGlvbiBfdHlwZW9mMihvYmopIHsgcmV0dXJuIHR5cGVvZiBvYmo7IH07IH0gZWxzZSB7IF90eXBlb2YyID0gZnVuY3Rpb24gX3R5cGVvZjIob2JqKSB7IHJldHVybiBvYmogJiYgdHlwZW9mIFN5bWJvbCA9PT0gXCJmdW5jdGlvblwiICYmIG9iai5jb25zdHJ1Y3RvciA9PT0gU3ltYm9sICYmIG9iaiAhPT0gU3ltYm9sLnByb3RvdHlwZSA/IFwic3ltYm9sXCIgOiB0eXBlb2Ygb2JqOyB9OyB9IHJldHVybiBfdHlwZW9mMihvYmopOyB9XG5cbmZ1bmN0aW9uIF90eXBlb2Yob2JqKSB7XG4gIGlmICh0eXBlb2YgU3ltYm9sID09PSBcImZ1bmN0aW9uXCIgJiYgX3R5cGVvZjIoU3ltYm9sLml0ZXJhdG9yKSA9PT0gXCJzeW1ib2xcIikge1xuICAgIG1vZHVsZS5leHBvcnRzID0gX3R5cGVvZiA9IGZ1bmN0aW9uIF90eXBlb2Yob2JqKSB7XG4gICAgICByZXR1cm4gX3R5cGVvZjIob2JqKTtcbiAgICB9O1xuICB9IGVsc2Uge1xuICAgIG1vZHVsZS5leHBvcnRzID0gX3R5cGVvZiA9IGZ1bmN0aW9uIF90eXBlb2Yob2JqKSB7XG4gICAgICByZXR1cm4gb2JqICYmIHR5cGVvZiBTeW1ib2wgPT09IFwiZnVuY3Rpb25cIiAmJiBvYmouY29uc3RydWN0b3IgPT09IFN5bWJvbCAmJiBvYmogIT09IFN5bWJvbC5wcm90b3R5cGUgPyBcInN5bWJvbFwiIDogX3R5cGVvZjIob2JqKTtcbiAgICB9O1xuICB9XG5cbiAgcmV0dXJuIF90eXBlb2Yob2JqKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBfdHlwZW9mOyIsInZhciBnZXRQcm90b3R5cGVPZiA9IHJlcXVpcmUoXCIuL2dldFByb3RvdHlwZU9mXCIpO1xuXG52YXIgc2V0UHJvdG90eXBlT2YgPSByZXF1aXJlKFwiLi9zZXRQcm90b3R5cGVPZlwiKTtcblxudmFyIGlzTmF0aXZlRnVuY3Rpb24gPSByZXF1aXJlKFwiLi9pc05hdGl2ZUZ1bmN0aW9uXCIpO1xuXG52YXIgY29uc3RydWN0ID0gcmVxdWlyZShcIi4vY29uc3RydWN0XCIpO1xuXG5mdW5jdGlvbiBfd3JhcE5hdGl2ZVN1cGVyKENsYXNzKSB7XG4gIHZhciBfY2FjaGUgPSB0eXBlb2YgTWFwID09PSBcImZ1bmN0aW9uXCIgPyBuZXcgTWFwKCkgOiB1bmRlZmluZWQ7XG5cbiAgbW9kdWxlLmV4cG9ydHMgPSBfd3JhcE5hdGl2ZVN1cGVyID0gZnVuY3Rpb24gX3dyYXBOYXRpdmVTdXBlcihDbGFzcykge1xuICAgIGlmIChDbGFzcyA9PT0gbnVsbCB8fCAhaXNOYXRpdmVGdW5jdGlvbihDbGFzcykpIHJldHVybiBDbGFzcztcblxuICAgIGlmICh0eXBlb2YgQ2xhc3MgIT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlN1cGVyIGV4cHJlc3Npb24gbXVzdCBlaXRoZXIgYmUgbnVsbCBvciBhIGZ1bmN0aW9uXCIpO1xuICAgIH1cblxuICAgIGlmICh0eXBlb2YgX2NhY2hlICE9PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgICBpZiAoX2NhY2hlLmhhcyhDbGFzcykpIHJldHVybiBfY2FjaGUuZ2V0KENsYXNzKTtcblxuICAgICAgX2NhY2hlLnNldChDbGFzcywgV3JhcHBlcik7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gV3JhcHBlcigpIHtcbiAgICAgIHJldHVybiBjb25zdHJ1Y3QoQ2xhc3MsIGFyZ3VtZW50cywgZ2V0UHJvdG90eXBlT2YodGhpcykuY29uc3RydWN0b3IpO1xuICAgIH1cblxuICAgIFdyYXBwZXIucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShDbGFzcy5wcm90b3R5cGUsIHtcbiAgICAgIGNvbnN0cnVjdG9yOiB7XG4gICAgICAgIHZhbHVlOiBXcmFwcGVyLFxuICAgICAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICAgICAgd3JpdGFibGU6IHRydWUsXG4gICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZVxuICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiBzZXRQcm90b3R5cGVPZihXcmFwcGVyLCBDbGFzcyk7XG4gIH07XG5cbiAgcmV0dXJuIF93cmFwTmF0aXZlU3VwZXIoQ2xhc3MpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IF93cmFwTmF0aXZlU3VwZXI7IiwiLyoqXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTQtcHJlc2VudCwgRmFjZWJvb2ssIEluYy5cbiAqXG4gKiBUaGlzIHNvdXJjZSBjb2RlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgbGljZW5zZSBmb3VuZCBpbiB0aGVcbiAqIExJQ0VOU0UgZmlsZSBpbiB0aGUgcm9vdCBkaXJlY3Rvcnkgb2YgdGhpcyBzb3VyY2UgdHJlZS5cbiAqL1xuXG4vLyBUaGlzIG1ldGhvZCBvZiBvYnRhaW5pbmcgYSByZWZlcmVuY2UgdG8gdGhlIGdsb2JhbCBvYmplY3QgbmVlZHMgdG8gYmVcbi8vIGtlcHQgaWRlbnRpY2FsIHRvIHRoZSB3YXkgaXQgaXMgb2J0YWluZWQgaW4gcnVudGltZS5qc1xudmFyIGcgPSAoZnVuY3Rpb24oKSB7XG4gIHJldHVybiB0aGlzIHx8ICh0eXBlb2Ygc2VsZiA9PT0gXCJvYmplY3RcIiAmJiBzZWxmKTtcbn0pKCkgfHwgRnVuY3Rpb24oXCJyZXR1cm4gdGhpc1wiKSgpO1xuXG4vLyBVc2UgYGdldE93blByb3BlcnR5TmFtZXNgIGJlY2F1c2Ugbm90IGFsbCBicm93c2VycyBzdXBwb3J0IGNhbGxpbmdcbi8vIGBoYXNPd25Qcm9wZXJ0eWAgb24gdGhlIGdsb2JhbCBgc2VsZmAgb2JqZWN0IGluIGEgd29ya2VyLiBTZWUgIzE4My5cbnZhciBoYWRSdW50aW1lID0gZy5yZWdlbmVyYXRvclJ1bnRpbWUgJiZcbiAgT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXMoZykuaW5kZXhPZihcInJlZ2VuZXJhdG9yUnVudGltZVwiKSA+PSAwO1xuXG4vLyBTYXZlIHRoZSBvbGQgcmVnZW5lcmF0b3JSdW50aW1lIGluIGNhc2UgaXQgbmVlZHMgdG8gYmUgcmVzdG9yZWQgbGF0ZXIuXG52YXIgb2xkUnVudGltZSA9IGhhZFJ1bnRpbWUgJiYgZy5yZWdlbmVyYXRvclJ1bnRpbWU7XG5cbi8vIEZvcmNlIHJlZXZhbHV0YXRpb24gb2YgcnVudGltZS5qcy5cbmcucmVnZW5lcmF0b3JSdW50aW1lID0gdW5kZWZpbmVkO1xuXG5tb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCIuL3J1bnRpbWVcIik7XG5cbmlmIChoYWRSdW50aW1lKSB7XG4gIC8vIFJlc3RvcmUgdGhlIG9yaWdpbmFsIHJ1bnRpbWUuXG4gIGcucmVnZW5lcmF0b3JSdW50aW1lID0gb2xkUnVudGltZTtcbn0gZWxzZSB7XG4gIC8vIFJlbW92ZSB0aGUgZ2xvYmFsIHByb3BlcnR5IGFkZGVkIGJ5IHJ1bnRpbWUuanMuXG4gIHRyeSB7XG4gICAgZGVsZXRlIGcucmVnZW5lcmF0b3JSdW50aW1lO1xuICB9IGNhdGNoKGUpIHtcbiAgICBnLnJlZ2VuZXJhdG9yUnVudGltZSA9IHVuZGVmaW5lZDtcbiAgfVxufVxuIiwiLyoqXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTQtcHJlc2VudCwgRmFjZWJvb2ssIEluYy5cbiAqXG4gKiBUaGlzIHNvdXJjZSBjb2RlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgbGljZW5zZSBmb3VuZCBpbiB0aGVcbiAqIExJQ0VOU0UgZmlsZSBpbiB0aGUgcm9vdCBkaXJlY3Rvcnkgb2YgdGhpcyBzb3VyY2UgdHJlZS5cbiAqL1xuXG4hKGZ1bmN0aW9uKGdsb2JhbCkge1xuICBcInVzZSBzdHJpY3RcIjtcblxuICB2YXIgT3AgPSBPYmplY3QucHJvdG90eXBlO1xuICB2YXIgaGFzT3duID0gT3AuaGFzT3duUHJvcGVydHk7XG4gIHZhciB1bmRlZmluZWQ7IC8vIE1vcmUgY29tcHJlc3NpYmxlIHRoYW4gdm9pZCAwLlxuICB2YXIgJFN5bWJvbCA9IHR5cGVvZiBTeW1ib2wgPT09IFwiZnVuY3Rpb25cIiA/IFN5bWJvbCA6IHt9O1xuICB2YXIgaXRlcmF0b3JTeW1ib2wgPSAkU3ltYm9sLml0ZXJhdG9yIHx8IFwiQEBpdGVyYXRvclwiO1xuICB2YXIgYXN5bmNJdGVyYXRvclN5bWJvbCA9ICRTeW1ib2wuYXN5bmNJdGVyYXRvciB8fCBcIkBAYXN5bmNJdGVyYXRvclwiO1xuICB2YXIgdG9TdHJpbmdUYWdTeW1ib2wgPSAkU3ltYm9sLnRvU3RyaW5nVGFnIHx8IFwiQEB0b1N0cmluZ1RhZ1wiO1xuXG4gIHZhciBpbk1vZHVsZSA9IHR5cGVvZiBtb2R1bGUgPT09IFwib2JqZWN0XCI7XG4gIHZhciBydW50aW1lID0gZ2xvYmFsLnJlZ2VuZXJhdG9yUnVudGltZTtcbiAgaWYgKHJ1bnRpbWUpIHtcbiAgICBpZiAoaW5Nb2R1bGUpIHtcbiAgICAgIC8vIElmIHJlZ2VuZXJhdG9yUnVudGltZSBpcyBkZWZpbmVkIGdsb2JhbGx5IGFuZCB3ZSdyZSBpbiBhIG1vZHVsZSxcbiAgICAgIC8vIG1ha2UgdGhlIGV4cG9ydHMgb2JqZWN0IGlkZW50aWNhbCB0byByZWdlbmVyYXRvclJ1bnRpbWUuXG4gICAgICBtb2R1bGUuZXhwb3J0cyA9IHJ1bnRpbWU7XG4gICAgfVxuICAgIC8vIERvbid0IGJvdGhlciBldmFsdWF0aW5nIHRoZSByZXN0IG9mIHRoaXMgZmlsZSBpZiB0aGUgcnVudGltZSB3YXNcbiAgICAvLyBhbHJlYWR5IGRlZmluZWQgZ2xvYmFsbHkuXG4gICAgcmV0dXJuO1xuICB9XG5cbiAgLy8gRGVmaW5lIHRoZSBydW50aW1lIGdsb2JhbGx5IChhcyBleHBlY3RlZCBieSBnZW5lcmF0ZWQgY29kZSkgYXMgZWl0aGVyXG4gIC8vIG1vZHVsZS5leHBvcnRzIChpZiB3ZSdyZSBpbiBhIG1vZHVsZSkgb3IgYSBuZXcsIGVtcHR5IG9iamVjdC5cbiAgcnVudGltZSA9IGdsb2JhbC5yZWdlbmVyYXRvclJ1bnRpbWUgPSBpbk1vZHVsZSA/IG1vZHVsZS5leHBvcnRzIDoge307XG5cbiAgZnVuY3Rpb24gd3JhcChpbm5lckZuLCBvdXRlckZuLCBzZWxmLCB0cnlMb2NzTGlzdCkge1xuICAgIC8vIElmIG91dGVyRm4gcHJvdmlkZWQgYW5kIG91dGVyRm4ucHJvdG90eXBlIGlzIGEgR2VuZXJhdG9yLCB0aGVuIG91dGVyRm4ucHJvdG90eXBlIGluc3RhbmNlb2YgR2VuZXJhdG9yLlxuICAgIHZhciBwcm90b0dlbmVyYXRvciA9IG91dGVyRm4gJiYgb3V0ZXJGbi5wcm90b3R5cGUgaW5zdGFuY2VvZiBHZW5lcmF0b3IgPyBvdXRlckZuIDogR2VuZXJhdG9yO1xuICAgIHZhciBnZW5lcmF0b3IgPSBPYmplY3QuY3JlYXRlKHByb3RvR2VuZXJhdG9yLnByb3RvdHlwZSk7XG4gICAgdmFyIGNvbnRleHQgPSBuZXcgQ29udGV4dCh0cnlMb2NzTGlzdCB8fCBbXSk7XG5cbiAgICAvLyBUaGUgLl9pbnZva2UgbWV0aG9kIHVuaWZpZXMgdGhlIGltcGxlbWVudGF0aW9ucyBvZiB0aGUgLm5leHQsXG4gICAgLy8gLnRocm93LCBhbmQgLnJldHVybiBtZXRob2RzLlxuICAgIGdlbmVyYXRvci5faW52b2tlID0gbWFrZUludm9rZU1ldGhvZChpbm5lckZuLCBzZWxmLCBjb250ZXh0KTtcblxuICAgIHJldHVybiBnZW5lcmF0b3I7XG4gIH1cbiAgcnVudGltZS53cmFwID0gd3JhcDtcblxuICAvLyBUcnkvY2F0Y2ggaGVscGVyIHRvIG1pbmltaXplIGRlb3B0aW1pemF0aW9ucy4gUmV0dXJucyBhIGNvbXBsZXRpb25cbiAgLy8gcmVjb3JkIGxpa2UgY29udGV4dC50cnlFbnRyaWVzW2ldLmNvbXBsZXRpb24uIFRoaXMgaW50ZXJmYWNlIGNvdWxkXG4gIC8vIGhhdmUgYmVlbiAoYW5kIHdhcyBwcmV2aW91c2x5KSBkZXNpZ25lZCB0byB0YWtlIGEgY2xvc3VyZSB0byBiZVxuICAvLyBpbnZva2VkIHdpdGhvdXQgYXJndW1lbnRzLCBidXQgaW4gYWxsIHRoZSBjYXNlcyB3ZSBjYXJlIGFib3V0IHdlXG4gIC8vIGFscmVhZHkgaGF2ZSBhbiBleGlzdGluZyBtZXRob2Qgd2Ugd2FudCB0byBjYWxsLCBzbyB0aGVyZSdzIG5vIG5lZWRcbiAgLy8gdG8gY3JlYXRlIGEgbmV3IGZ1bmN0aW9uIG9iamVjdC4gV2UgY2FuIGV2ZW4gZ2V0IGF3YXkgd2l0aCBhc3N1bWluZ1xuICAvLyB0aGUgbWV0aG9kIHRha2VzIGV4YWN0bHkgb25lIGFyZ3VtZW50LCBzaW5jZSB0aGF0IGhhcHBlbnMgdG8gYmUgdHJ1ZVxuICAvLyBpbiBldmVyeSBjYXNlLCBzbyB3ZSBkb24ndCBoYXZlIHRvIHRvdWNoIHRoZSBhcmd1bWVudHMgb2JqZWN0LiBUaGVcbiAgLy8gb25seSBhZGRpdGlvbmFsIGFsbG9jYXRpb24gcmVxdWlyZWQgaXMgdGhlIGNvbXBsZXRpb24gcmVjb3JkLCB3aGljaFxuICAvLyBoYXMgYSBzdGFibGUgc2hhcGUgYW5kIHNvIGhvcGVmdWxseSBzaG91bGQgYmUgY2hlYXAgdG8gYWxsb2NhdGUuXG4gIGZ1bmN0aW9uIHRyeUNhdGNoKGZuLCBvYmosIGFyZykge1xuICAgIHRyeSB7XG4gICAgICByZXR1cm4geyB0eXBlOiBcIm5vcm1hbFwiLCBhcmc6IGZuLmNhbGwob2JqLCBhcmcpIH07XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICByZXR1cm4geyB0eXBlOiBcInRocm93XCIsIGFyZzogZXJyIH07XG4gICAgfVxuICB9XG5cbiAgdmFyIEdlblN0YXRlU3VzcGVuZGVkU3RhcnQgPSBcInN1c3BlbmRlZFN0YXJ0XCI7XG4gIHZhciBHZW5TdGF0ZVN1c3BlbmRlZFlpZWxkID0gXCJzdXNwZW5kZWRZaWVsZFwiO1xuICB2YXIgR2VuU3RhdGVFeGVjdXRpbmcgPSBcImV4ZWN1dGluZ1wiO1xuICB2YXIgR2VuU3RhdGVDb21wbGV0ZWQgPSBcImNvbXBsZXRlZFwiO1xuXG4gIC8vIFJldHVybmluZyB0aGlzIG9iamVjdCBmcm9tIHRoZSBpbm5lckZuIGhhcyB0aGUgc2FtZSBlZmZlY3QgYXNcbiAgLy8gYnJlYWtpbmcgb3V0IG9mIHRoZSBkaXNwYXRjaCBzd2l0Y2ggc3RhdGVtZW50LlxuICB2YXIgQ29udGludWVTZW50aW5lbCA9IHt9O1xuXG4gIC8vIER1bW15IGNvbnN0cnVjdG9yIGZ1bmN0aW9ucyB0aGF0IHdlIHVzZSBhcyB0aGUgLmNvbnN0cnVjdG9yIGFuZFxuICAvLyAuY29uc3RydWN0b3IucHJvdG90eXBlIHByb3BlcnRpZXMgZm9yIGZ1bmN0aW9ucyB0aGF0IHJldHVybiBHZW5lcmF0b3JcbiAgLy8gb2JqZWN0cy4gRm9yIGZ1bGwgc3BlYyBjb21wbGlhbmNlLCB5b3UgbWF5IHdpc2ggdG8gY29uZmlndXJlIHlvdXJcbiAgLy8gbWluaWZpZXIgbm90IHRvIG1hbmdsZSB0aGUgbmFtZXMgb2YgdGhlc2UgdHdvIGZ1bmN0aW9ucy5cbiAgZnVuY3Rpb24gR2VuZXJhdG9yKCkge31cbiAgZnVuY3Rpb24gR2VuZXJhdG9yRnVuY3Rpb24oKSB7fVxuICBmdW5jdGlvbiBHZW5lcmF0b3JGdW5jdGlvblByb3RvdHlwZSgpIHt9XG5cbiAgLy8gVGhpcyBpcyBhIHBvbHlmaWxsIGZvciAlSXRlcmF0b3JQcm90b3R5cGUlIGZvciBlbnZpcm9ubWVudHMgdGhhdFxuICAvLyBkb24ndCBuYXRpdmVseSBzdXBwb3J0IGl0LlxuICB2YXIgSXRlcmF0b3JQcm90b3R5cGUgPSB7fTtcbiAgSXRlcmF0b3JQcm90b3R5cGVbaXRlcmF0b3JTeW1ib2xdID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzO1xuICB9O1xuXG4gIHZhciBnZXRQcm90byA9IE9iamVjdC5nZXRQcm90b3R5cGVPZjtcbiAgdmFyIE5hdGl2ZUl0ZXJhdG9yUHJvdG90eXBlID0gZ2V0UHJvdG8gJiYgZ2V0UHJvdG8oZ2V0UHJvdG8odmFsdWVzKFtdKSkpO1xuICBpZiAoTmF0aXZlSXRlcmF0b3JQcm90b3R5cGUgJiZcbiAgICAgIE5hdGl2ZUl0ZXJhdG9yUHJvdG90eXBlICE9PSBPcCAmJlxuICAgICAgaGFzT3duLmNhbGwoTmF0aXZlSXRlcmF0b3JQcm90b3R5cGUsIGl0ZXJhdG9yU3ltYm9sKSkge1xuICAgIC8vIFRoaXMgZW52aXJvbm1lbnQgaGFzIGEgbmF0aXZlICVJdGVyYXRvclByb3RvdHlwZSU7IHVzZSBpdCBpbnN0ZWFkXG4gICAgLy8gb2YgdGhlIHBvbHlmaWxsLlxuICAgIEl0ZXJhdG9yUHJvdG90eXBlID0gTmF0aXZlSXRlcmF0b3JQcm90b3R5cGU7XG4gIH1cblxuICB2YXIgR3AgPSBHZW5lcmF0b3JGdW5jdGlvblByb3RvdHlwZS5wcm90b3R5cGUgPVxuICAgIEdlbmVyYXRvci5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKEl0ZXJhdG9yUHJvdG90eXBlKTtcbiAgR2VuZXJhdG9yRnVuY3Rpb24ucHJvdG90eXBlID0gR3AuY29uc3RydWN0b3IgPSBHZW5lcmF0b3JGdW5jdGlvblByb3RvdHlwZTtcbiAgR2VuZXJhdG9yRnVuY3Rpb25Qcm90b3R5cGUuY29uc3RydWN0b3IgPSBHZW5lcmF0b3JGdW5jdGlvbjtcbiAgR2VuZXJhdG9yRnVuY3Rpb25Qcm90b3R5cGVbdG9TdHJpbmdUYWdTeW1ib2xdID1cbiAgICBHZW5lcmF0b3JGdW5jdGlvbi5kaXNwbGF5TmFtZSA9IFwiR2VuZXJhdG9yRnVuY3Rpb25cIjtcblxuICAvLyBIZWxwZXIgZm9yIGRlZmluaW5nIHRoZSAubmV4dCwgLnRocm93LCBhbmQgLnJldHVybiBtZXRob2RzIG9mIHRoZVxuICAvLyBJdGVyYXRvciBpbnRlcmZhY2UgaW4gdGVybXMgb2YgYSBzaW5nbGUgLl9pbnZva2UgbWV0aG9kLlxuICBmdW5jdGlvbiBkZWZpbmVJdGVyYXRvck1ldGhvZHMocHJvdG90eXBlKSB7XG4gICAgW1wibmV4dFwiLCBcInRocm93XCIsIFwicmV0dXJuXCJdLmZvckVhY2goZnVuY3Rpb24obWV0aG9kKSB7XG4gICAgICBwcm90b3R5cGVbbWV0aG9kXSA9IGZ1bmN0aW9uKGFyZykge1xuICAgICAgICByZXR1cm4gdGhpcy5faW52b2tlKG1ldGhvZCwgYXJnKTtcbiAgICAgIH07XG4gICAgfSk7XG4gIH1cblxuICBydW50aW1lLmlzR2VuZXJhdG9yRnVuY3Rpb24gPSBmdW5jdGlvbihnZW5GdW4pIHtcbiAgICB2YXIgY3RvciA9IHR5cGVvZiBnZW5GdW4gPT09IFwiZnVuY3Rpb25cIiAmJiBnZW5GdW4uY29uc3RydWN0b3I7XG4gICAgcmV0dXJuIGN0b3JcbiAgICAgID8gY3RvciA9PT0gR2VuZXJhdG9yRnVuY3Rpb24gfHxcbiAgICAgICAgLy8gRm9yIHRoZSBuYXRpdmUgR2VuZXJhdG9yRnVuY3Rpb24gY29uc3RydWN0b3IsIHRoZSBiZXN0IHdlIGNhblxuICAgICAgICAvLyBkbyBpcyB0byBjaGVjayBpdHMgLm5hbWUgcHJvcGVydHkuXG4gICAgICAgIChjdG9yLmRpc3BsYXlOYW1lIHx8IGN0b3IubmFtZSkgPT09IFwiR2VuZXJhdG9yRnVuY3Rpb25cIlxuICAgICAgOiBmYWxzZTtcbiAgfTtcblxuICBydW50aW1lLm1hcmsgPSBmdW5jdGlvbihnZW5GdW4pIHtcbiAgICBpZiAoT2JqZWN0LnNldFByb3RvdHlwZU9mKSB7XG4gICAgICBPYmplY3Quc2V0UHJvdG90eXBlT2YoZ2VuRnVuLCBHZW5lcmF0b3JGdW5jdGlvblByb3RvdHlwZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGdlbkZ1bi5fX3Byb3RvX18gPSBHZW5lcmF0b3JGdW5jdGlvblByb3RvdHlwZTtcbiAgICAgIGlmICghKHRvU3RyaW5nVGFnU3ltYm9sIGluIGdlbkZ1bikpIHtcbiAgICAgICAgZ2VuRnVuW3RvU3RyaW5nVGFnU3ltYm9sXSA9IFwiR2VuZXJhdG9yRnVuY3Rpb25cIjtcbiAgICAgIH1cbiAgICB9XG4gICAgZ2VuRnVuLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoR3ApO1xuICAgIHJldHVybiBnZW5GdW47XG4gIH07XG5cbiAgLy8gV2l0aGluIHRoZSBib2R5IG9mIGFueSBhc3luYyBmdW5jdGlvbiwgYGF3YWl0IHhgIGlzIHRyYW5zZm9ybWVkIHRvXG4gIC8vIGB5aWVsZCByZWdlbmVyYXRvclJ1bnRpbWUuYXdyYXAoeClgLCBzbyB0aGF0IHRoZSBydW50aW1lIGNhbiB0ZXN0XG4gIC8vIGBoYXNPd24uY2FsbCh2YWx1ZSwgXCJfX2F3YWl0XCIpYCB0byBkZXRlcm1pbmUgaWYgdGhlIHlpZWxkZWQgdmFsdWUgaXNcbiAgLy8gbWVhbnQgdG8gYmUgYXdhaXRlZC5cbiAgcnVudGltZS5hd3JhcCA9IGZ1bmN0aW9uKGFyZykge1xuICAgIHJldHVybiB7IF9fYXdhaXQ6IGFyZyB9O1xuICB9O1xuXG4gIGZ1bmN0aW9uIEFzeW5jSXRlcmF0b3IoZ2VuZXJhdG9yKSB7XG4gICAgZnVuY3Rpb24gaW52b2tlKG1ldGhvZCwgYXJnLCByZXNvbHZlLCByZWplY3QpIHtcbiAgICAgIHZhciByZWNvcmQgPSB0cnlDYXRjaChnZW5lcmF0b3JbbWV0aG9kXSwgZ2VuZXJhdG9yLCBhcmcpO1xuICAgICAgaWYgKHJlY29yZC50eXBlID09PSBcInRocm93XCIpIHtcbiAgICAgICAgcmVqZWN0KHJlY29yZC5hcmcpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdmFyIHJlc3VsdCA9IHJlY29yZC5hcmc7XG4gICAgICAgIHZhciB2YWx1ZSA9IHJlc3VsdC52YWx1ZTtcbiAgICAgICAgaWYgKHZhbHVlICYmXG4gICAgICAgICAgICB0eXBlb2YgdmFsdWUgPT09IFwib2JqZWN0XCIgJiZcbiAgICAgICAgICAgIGhhc093bi5jYWxsKHZhbHVlLCBcIl9fYXdhaXRcIikpIHtcbiAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHZhbHVlLl9fYXdhaXQpLnRoZW4oZnVuY3Rpb24odmFsdWUpIHtcbiAgICAgICAgICAgIGludm9rZShcIm5leHRcIiwgdmFsdWUsIHJlc29sdmUsIHJlamVjdCk7XG4gICAgICAgICAgfSwgZnVuY3Rpb24oZXJyKSB7XG4gICAgICAgICAgICBpbnZva2UoXCJ0aHJvd1wiLCBlcnIsIHJlc29sdmUsIHJlamVjdCk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHZhbHVlKS50aGVuKGZ1bmN0aW9uKHVud3JhcHBlZCkge1xuICAgICAgICAgIC8vIFdoZW4gYSB5aWVsZGVkIFByb21pc2UgaXMgcmVzb2x2ZWQsIGl0cyBmaW5hbCB2YWx1ZSBiZWNvbWVzXG4gICAgICAgICAgLy8gdGhlIC52YWx1ZSBvZiB0aGUgUHJvbWlzZTx7dmFsdWUsZG9uZX0+IHJlc3VsdCBmb3IgdGhlXG4gICAgICAgICAgLy8gY3VycmVudCBpdGVyYXRpb24uXG4gICAgICAgICAgcmVzdWx0LnZhbHVlID0gdW53cmFwcGVkO1xuICAgICAgICAgIHJlc29sdmUocmVzdWx0KTtcbiAgICAgICAgfSwgZnVuY3Rpb24oZXJyb3IpIHtcbiAgICAgICAgICAvLyBJZiBhIHJlamVjdGVkIFByb21pc2Ugd2FzIHlpZWxkZWQsIHRocm93IHRoZSByZWplY3Rpb24gYmFja1xuICAgICAgICAgIC8vIGludG8gdGhlIGFzeW5jIGdlbmVyYXRvciBmdW5jdGlvbiBzbyBpdCBjYW4gYmUgaGFuZGxlZCB0aGVyZS5cbiAgICAgICAgICByZXR1cm4gaW52b2tlKFwidGhyb3dcIiwgZXJyb3IsIHJlc29sdmUsIHJlamVjdCk7XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIHZhciBwcmV2aW91c1Byb21pc2U7XG5cbiAgICBmdW5jdGlvbiBlbnF1ZXVlKG1ldGhvZCwgYXJnKSB7XG4gICAgICBmdW5jdGlvbiBjYWxsSW52b2tlV2l0aE1ldGhvZEFuZEFyZygpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uKHJlc29sdmUsIHJlamVjdCkge1xuICAgICAgICAgIGludm9rZShtZXRob2QsIGFyZywgcmVzb2x2ZSwgcmVqZWN0KTtcbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBwcmV2aW91c1Byb21pc2UgPVxuICAgICAgICAvLyBJZiBlbnF1ZXVlIGhhcyBiZWVuIGNhbGxlZCBiZWZvcmUsIHRoZW4gd2Ugd2FudCB0byB3YWl0IHVudGlsXG4gICAgICAgIC8vIGFsbCBwcmV2aW91cyBQcm9taXNlcyBoYXZlIGJlZW4gcmVzb2x2ZWQgYmVmb3JlIGNhbGxpbmcgaW52b2tlLFxuICAgICAgICAvLyBzbyB0aGF0IHJlc3VsdHMgYXJlIGFsd2F5cyBkZWxpdmVyZWQgaW4gdGhlIGNvcnJlY3Qgb3JkZXIuIElmXG4gICAgICAgIC8vIGVucXVldWUgaGFzIG5vdCBiZWVuIGNhbGxlZCBiZWZvcmUsIHRoZW4gaXQgaXMgaW1wb3J0YW50IHRvXG4gICAgICAgIC8vIGNhbGwgaW52b2tlIGltbWVkaWF0ZWx5LCB3aXRob3V0IHdhaXRpbmcgb24gYSBjYWxsYmFjayB0byBmaXJlLFxuICAgICAgICAvLyBzbyB0aGF0IHRoZSBhc3luYyBnZW5lcmF0b3IgZnVuY3Rpb24gaGFzIHRoZSBvcHBvcnR1bml0eSB0byBkb1xuICAgICAgICAvLyBhbnkgbmVjZXNzYXJ5IHNldHVwIGluIGEgcHJlZGljdGFibGUgd2F5LiBUaGlzIHByZWRpY3RhYmlsaXR5XG4gICAgICAgIC8vIGlzIHdoeSB0aGUgUHJvbWlzZSBjb25zdHJ1Y3RvciBzeW5jaHJvbm91c2x5IGludm9rZXMgaXRzXG4gICAgICAgIC8vIGV4ZWN1dG9yIGNhbGxiYWNrLCBhbmQgd2h5IGFzeW5jIGZ1bmN0aW9ucyBzeW5jaHJvbm91c2x5XG4gICAgICAgIC8vIGV4ZWN1dGUgY29kZSBiZWZvcmUgdGhlIGZpcnN0IGF3YWl0LiBTaW5jZSB3ZSBpbXBsZW1lbnQgc2ltcGxlXG4gICAgICAgIC8vIGFzeW5jIGZ1bmN0aW9ucyBpbiB0ZXJtcyBvZiBhc3luYyBnZW5lcmF0b3JzLCBpdCBpcyBlc3BlY2lhbGx5XG4gICAgICAgIC8vIGltcG9ydGFudCB0byBnZXQgdGhpcyByaWdodCwgZXZlbiB0aG91Z2ggaXQgcmVxdWlyZXMgY2FyZS5cbiAgICAgICAgcHJldmlvdXNQcm9taXNlID8gcHJldmlvdXNQcm9taXNlLnRoZW4oXG4gICAgICAgICAgY2FsbEludm9rZVdpdGhNZXRob2RBbmRBcmcsXG4gICAgICAgICAgLy8gQXZvaWQgcHJvcGFnYXRpbmcgZmFpbHVyZXMgdG8gUHJvbWlzZXMgcmV0dXJuZWQgYnkgbGF0ZXJcbiAgICAgICAgICAvLyBpbnZvY2F0aW9ucyBvZiB0aGUgaXRlcmF0b3IuXG4gICAgICAgICAgY2FsbEludm9rZVdpdGhNZXRob2RBbmRBcmdcbiAgICAgICAgKSA6IGNhbGxJbnZva2VXaXRoTWV0aG9kQW5kQXJnKCk7XG4gICAgfVxuXG4gICAgLy8gRGVmaW5lIHRoZSB1bmlmaWVkIGhlbHBlciBtZXRob2QgdGhhdCBpcyB1c2VkIHRvIGltcGxlbWVudCAubmV4dCxcbiAgICAvLyAudGhyb3csIGFuZCAucmV0dXJuIChzZWUgZGVmaW5lSXRlcmF0b3JNZXRob2RzKS5cbiAgICB0aGlzLl9pbnZva2UgPSBlbnF1ZXVlO1xuICB9XG5cbiAgZGVmaW5lSXRlcmF0b3JNZXRob2RzKEFzeW5jSXRlcmF0b3IucHJvdG90eXBlKTtcbiAgQXN5bmNJdGVyYXRvci5wcm90b3R5cGVbYXN5bmNJdGVyYXRvclN5bWJvbF0gPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH07XG4gIHJ1bnRpbWUuQXN5bmNJdGVyYXRvciA9IEFzeW5jSXRlcmF0b3I7XG5cbiAgLy8gTm90ZSB0aGF0IHNpbXBsZSBhc3luYyBmdW5jdGlvbnMgYXJlIGltcGxlbWVudGVkIG9uIHRvcCBvZlxuICAvLyBBc3luY0l0ZXJhdG9yIG9iamVjdHM7IHRoZXkganVzdCByZXR1cm4gYSBQcm9taXNlIGZvciB0aGUgdmFsdWUgb2ZcbiAgLy8gdGhlIGZpbmFsIHJlc3VsdCBwcm9kdWNlZCBieSB0aGUgaXRlcmF0b3IuXG4gIHJ1bnRpbWUuYXN5bmMgPSBmdW5jdGlvbihpbm5lckZuLCBvdXRlckZuLCBzZWxmLCB0cnlMb2NzTGlzdCkge1xuICAgIHZhciBpdGVyID0gbmV3IEFzeW5jSXRlcmF0b3IoXG4gICAgICB3cmFwKGlubmVyRm4sIG91dGVyRm4sIHNlbGYsIHRyeUxvY3NMaXN0KVxuICAgICk7XG5cbiAgICByZXR1cm4gcnVudGltZS5pc0dlbmVyYXRvckZ1bmN0aW9uKG91dGVyRm4pXG4gICAgICA/IGl0ZXIgLy8gSWYgb3V0ZXJGbiBpcyBhIGdlbmVyYXRvciwgcmV0dXJuIHRoZSBmdWxsIGl0ZXJhdG9yLlxuICAgICAgOiBpdGVyLm5leHQoKS50aGVuKGZ1bmN0aW9uKHJlc3VsdCkge1xuICAgICAgICAgIHJldHVybiByZXN1bHQuZG9uZSA/IHJlc3VsdC52YWx1ZSA6IGl0ZXIubmV4dCgpO1xuICAgICAgICB9KTtcbiAgfTtcblxuICBmdW5jdGlvbiBtYWtlSW52b2tlTWV0aG9kKGlubmVyRm4sIHNlbGYsIGNvbnRleHQpIHtcbiAgICB2YXIgc3RhdGUgPSBHZW5TdGF0ZVN1c3BlbmRlZFN0YXJ0O1xuXG4gICAgcmV0dXJuIGZ1bmN0aW9uIGludm9rZShtZXRob2QsIGFyZykge1xuICAgICAgaWYgKHN0YXRlID09PSBHZW5TdGF0ZUV4ZWN1dGluZykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJHZW5lcmF0b3IgaXMgYWxyZWFkeSBydW5uaW5nXCIpO1xuICAgICAgfVxuXG4gICAgICBpZiAoc3RhdGUgPT09IEdlblN0YXRlQ29tcGxldGVkKSB7XG4gICAgICAgIGlmIChtZXRob2QgPT09IFwidGhyb3dcIikge1xuICAgICAgICAgIHRocm93IGFyZztcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEJlIGZvcmdpdmluZywgcGVyIDI1LjMuMy4zLjMgb2YgdGhlIHNwZWM6XG4gICAgICAgIC8vIGh0dHBzOi8vcGVvcGxlLm1vemlsbGEub3JnL35qb3JlbmRvcmZmL2VzNi1kcmFmdC5odG1sI3NlYy1nZW5lcmF0b3JyZXN1bWVcbiAgICAgICAgcmV0dXJuIGRvbmVSZXN1bHQoKTtcbiAgICAgIH1cblxuICAgICAgY29udGV4dC5tZXRob2QgPSBtZXRob2Q7XG4gICAgICBjb250ZXh0LmFyZyA9IGFyZztcblxuICAgICAgd2hpbGUgKHRydWUpIHtcbiAgICAgICAgdmFyIGRlbGVnYXRlID0gY29udGV4dC5kZWxlZ2F0ZTtcbiAgICAgICAgaWYgKGRlbGVnYXRlKSB7XG4gICAgICAgICAgdmFyIGRlbGVnYXRlUmVzdWx0ID0gbWF5YmVJbnZva2VEZWxlZ2F0ZShkZWxlZ2F0ZSwgY29udGV4dCk7XG4gICAgICAgICAgaWYgKGRlbGVnYXRlUmVzdWx0KSB7XG4gICAgICAgICAgICBpZiAoZGVsZWdhdGVSZXN1bHQgPT09IENvbnRpbnVlU2VudGluZWwpIGNvbnRpbnVlO1xuICAgICAgICAgICAgcmV0dXJuIGRlbGVnYXRlUmVzdWx0O1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChjb250ZXh0Lm1ldGhvZCA9PT0gXCJuZXh0XCIpIHtcbiAgICAgICAgICAvLyBTZXR0aW5nIGNvbnRleHQuX3NlbnQgZm9yIGxlZ2FjeSBzdXBwb3J0IG9mIEJhYmVsJ3NcbiAgICAgICAgICAvLyBmdW5jdGlvbi5zZW50IGltcGxlbWVudGF0aW9uLlxuICAgICAgICAgIGNvbnRleHQuc2VudCA9IGNvbnRleHQuX3NlbnQgPSBjb250ZXh0LmFyZztcblxuICAgICAgICB9IGVsc2UgaWYgKGNvbnRleHQubWV0aG9kID09PSBcInRocm93XCIpIHtcbiAgICAgICAgICBpZiAoc3RhdGUgPT09IEdlblN0YXRlU3VzcGVuZGVkU3RhcnQpIHtcbiAgICAgICAgICAgIHN0YXRlID0gR2VuU3RhdGVDb21wbGV0ZWQ7XG4gICAgICAgICAgICB0aHJvdyBjb250ZXh0LmFyZztcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBjb250ZXh0LmRpc3BhdGNoRXhjZXB0aW9uKGNvbnRleHQuYXJnKTtcblxuICAgICAgICB9IGVsc2UgaWYgKGNvbnRleHQubWV0aG9kID09PSBcInJldHVyblwiKSB7XG4gICAgICAgICAgY29udGV4dC5hYnJ1cHQoXCJyZXR1cm5cIiwgY29udGV4dC5hcmcpO1xuICAgICAgICB9XG5cbiAgICAgICAgc3RhdGUgPSBHZW5TdGF0ZUV4ZWN1dGluZztcblxuICAgICAgICB2YXIgcmVjb3JkID0gdHJ5Q2F0Y2goaW5uZXJGbiwgc2VsZiwgY29udGV4dCk7XG4gICAgICAgIGlmIChyZWNvcmQudHlwZSA9PT0gXCJub3JtYWxcIikge1xuICAgICAgICAgIC8vIElmIGFuIGV4Y2VwdGlvbiBpcyB0aHJvd24gZnJvbSBpbm5lckZuLCB3ZSBsZWF2ZSBzdGF0ZSA9PT1cbiAgICAgICAgICAvLyBHZW5TdGF0ZUV4ZWN1dGluZyBhbmQgbG9vcCBiYWNrIGZvciBhbm90aGVyIGludm9jYXRpb24uXG4gICAgICAgICAgc3RhdGUgPSBjb250ZXh0LmRvbmVcbiAgICAgICAgICAgID8gR2VuU3RhdGVDb21wbGV0ZWRcbiAgICAgICAgICAgIDogR2VuU3RhdGVTdXNwZW5kZWRZaWVsZDtcblxuICAgICAgICAgIGlmIChyZWNvcmQuYXJnID09PSBDb250aW51ZVNlbnRpbmVsKSB7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdmFsdWU6IHJlY29yZC5hcmcsXG4gICAgICAgICAgICBkb25lOiBjb250ZXh0LmRvbmVcbiAgICAgICAgICB9O1xuXG4gICAgICAgIH0gZWxzZSBpZiAocmVjb3JkLnR5cGUgPT09IFwidGhyb3dcIikge1xuICAgICAgICAgIHN0YXRlID0gR2VuU3RhdGVDb21wbGV0ZWQ7XG4gICAgICAgICAgLy8gRGlzcGF0Y2ggdGhlIGV4Y2VwdGlvbiBieSBsb29waW5nIGJhY2sgYXJvdW5kIHRvIHRoZVxuICAgICAgICAgIC8vIGNvbnRleHQuZGlzcGF0Y2hFeGNlcHRpb24oY29udGV4dC5hcmcpIGNhbGwgYWJvdmUuXG4gICAgICAgICAgY29udGV4dC5tZXRob2QgPSBcInRocm93XCI7XG4gICAgICAgICAgY29udGV4dC5hcmcgPSByZWNvcmQuYXJnO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfTtcbiAgfVxuXG4gIC8vIENhbGwgZGVsZWdhdGUuaXRlcmF0b3JbY29udGV4dC5tZXRob2RdKGNvbnRleHQuYXJnKSBhbmQgaGFuZGxlIHRoZVxuICAvLyByZXN1bHQsIGVpdGhlciBieSByZXR1cm5pbmcgYSB7IHZhbHVlLCBkb25lIH0gcmVzdWx0IGZyb20gdGhlXG4gIC8vIGRlbGVnYXRlIGl0ZXJhdG9yLCBvciBieSBtb2RpZnlpbmcgY29udGV4dC5tZXRob2QgYW5kIGNvbnRleHQuYXJnLFxuICAvLyBzZXR0aW5nIGNvbnRleHQuZGVsZWdhdGUgdG8gbnVsbCwgYW5kIHJldHVybmluZyB0aGUgQ29udGludWVTZW50aW5lbC5cbiAgZnVuY3Rpb24gbWF5YmVJbnZva2VEZWxlZ2F0ZShkZWxlZ2F0ZSwgY29udGV4dCkge1xuICAgIHZhciBtZXRob2QgPSBkZWxlZ2F0ZS5pdGVyYXRvcltjb250ZXh0Lm1ldGhvZF07XG4gICAgaWYgKG1ldGhvZCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAvLyBBIC50aHJvdyBvciAucmV0dXJuIHdoZW4gdGhlIGRlbGVnYXRlIGl0ZXJhdG9yIGhhcyBubyAudGhyb3dcbiAgICAgIC8vIG1ldGhvZCBhbHdheXMgdGVybWluYXRlcyB0aGUgeWllbGQqIGxvb3AuXG4gICAgICBjb250ZXh0LmRlbGVnYXRlID0gbnVsbDtcblxuICAgICAgaWYgKGNvbnRleHQubWV0aG9kID09PSBcInRocm93XCIpIHtcbiAgICAgICAgaWYgKGRlbGVnYXRlLml0ZXJhdG9yLnJldHVybikge1xuICAgICAgICAgIC8vIElmIHRoZSBkZWxlZ2F0ZSBpdGVyYXRvciBoYXMgYSByZXR1cm4gbWV0aG9kLCBnaXZlIGl0IGFcbiAgICAgICAgICAvLyBjaGFuY2UgdG8gY2xlYW4gdXAuXG4gICAgICAgICAgY29udGV4dC5tZXRob2QgPSBcInJldHVyblwiO1xuICAgICAgICAgIGNvbnRleHQuYXJnID0gdW5kZWZpbmVkO1xuICAgICAgICAgIG1heWJlSW52b2tlRGVsZWdhdGUoZGVsZWdhdGUsIGNvbnRleHQpO1xuXG4gICAgICAgICAgaWYgKGNvbnRleHQubWV0aG9kID09PSBcInRocm93XCIpIHtcbiAgICAgICAgICAgIC8vIElmIG1heWJlSW52b2tlRGVsZWdhdGUoY29udGV4dCkgY2hhbmdlZCBjb250ZXh0Lm1ldGhvZCBmcm9tXG4gICAgICAgICAgICAvLyBcInJldHVyblwiIHRvIFwidGhyb3dcIiwgbGV0IHRoYXQgb3ZlcnJpZGUgdGhlIFR5cGVFcnJvciBiZWxvdy5cbiAgICAgICAgICAgIHJldHVybiBDb250aW51ZVNlbnRpbmVsO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnRleHQubWV0aG9kID0gXCJ0aHJvd1wiO1xuICAgICAgICBjb250ZXh0LmFyZyA9IG5ldyBUeXBlRXJyb3IoXG4gICAgICAgICAgXCJUaGUgaXRlcmF0b3IgZG9lcyBub3QgcHJvdmlkZSBhICd0aHJvdycgbWV0aG9kXCIpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gQ29udGludWVTZW50aW5lbDtcbiAgICB9XG5cbiAgICB2YXIgcmVjb3JkID0gdHJ5Q2F0Y2gobWV0aG9kLCBkZWxlZ2F0ZS5pdGVyYXRvciwgY29udGV4dC5hcmcpO1xuXG4gICAgaWYgKHJlY29yZC50eXBlID09PSBcInRocm93XCIpIHtcbiAgICAgIGNvbnRleHQubWV0aG9kID0gXCJ0aHJvd1wiO1xuICAgICAgY29udGV4dC5hcmcgPSByZWNvcmQuYXJnO1xuICAgICAgY29udGV4dC5kZWxlZ2F0ZSA9IG51bGw7XG4gICAgICByZXR1cm4gQ29udGludWVTZW50aW5lbDtcbiAgICB9XG5cbiAgICB2YXIgaW5mbyA9IHJlY29yZC5hcmc7XG5cbiAgICBpZiAoISBpbmZvKSB7XG4gICAgICBjb250ZXh0Lm1ldGhvZCA9IFwidGhyb3dcIjtcbiAgICAgIGNvbnRleHQuYXJnID0gbmV3IFR5cGVFcnJvcihcIml0ZXJhdG9yIHJlc3VsdCBpcyBub3QgYW4gb2JqZWN0XCIpO1xuICAgICAgY29udGV4dC5kZWxlZ2F0ZSA9IG51bGw7XG4gICAgICByZXR1cm4gQ29udGludWVTZW50aW5lbDtcbiAgICB9XG5cbiAgICBpZiAoaW5mby5kb25lKSB7XG4gICAgICAvLyBBc3NpZ24gdGhlIHJlc3VsdCBvZiB0aGUgZmluaXNoZWQgZGVsZWdhdGUgdG8gdGhlIHRlbXBvcmFyeVxuICAgICAgLy8gdmFyaWFibGUgc3BlY2lmaWVkIGJ5IGRlbGVnYXRlLnJlc3VsdE5hbWUgKHNlZSBkZWxlZ2F0ZVlpZWxkKS5cbiAgICAgIGNvbnRleHRbZGVsZWdhdGUucmVzdWx0TmFtZV0gPSBpbmZvLnZhbHVlO1xuXG4gICAgICAvLyBSZXN1bWUgZXhlY3V0aW9uIGF0IHRoZSBkZXNpcmVkIGxvY2F0aW9uIChzZWUgZGVsZWdhdGVZaWVsZCkuXG4gICAgICBjb250ZXh0Lm5leHQgPSBkZWxlZ2F0ZS5uZXh0TG9jO1xuXG4gICAgICAvLyBJZiBjb250ZXh0Lm1ldGhvZCB3YXMgXCJ0aHJvd1wiIGJ1dCB0aGUgZGVsZWdhdGUgaGFuZGxlZCB0aGVcbiAgICAgIC8vIGV4Y2VwdGlvbiwgbGV0IHRoZSBvdXRlciBnZW5lcmF0b3IgcHJvY2VlZCBub3JtYWxseS4gSWZcbiAgICAgIC8vIGNvbnRleHQubWV0aG9kIHdhcyBcIm5leHRcIiwgZm9yZ2V0IGNvbnRleHQuYXJnIHNpbmNlIGl0IGhhcyBiZWVuXG4gICAgICAvLyBcImNvbnN1bWVkXCIgYnkgdGhlIGRlbGVnYXRlIGl0ZXJhdG9yLiBJZiBjb250ZXh0Lm1ldGhvZCB3YXNcbiAgICAgIC8vIFwicmV0dXJuXCIsIGFsbG93IHRoZSBvcmlnaW5hbCAucmV0dXJuIGNhbGwgdG8gY29udGludWUgaW4gdGhlXG4gICAgICAvLyBvdXRlciBnZW5lcmF0b3IuXG4gICAgICBpZiAoY29udGV4dC5tZXRob2QgIT09IFwicmV0dXJuXCIpIHtcbiAgICAgICAgY29udGV4dC5tZXRob2QgPSBcIm5leHRcIjtcbiAgICAgICAgY29udGV4dC5hcmcgPSB1bmRlZmluZWQ7XG4gICAgICB9XG5cbiAgICB9IGVsc2Uge1xuICAgICAgLy8gUmUteWllbGQgdGhlIHJlc3VsdCByZXR1cm5lZCBieSB0aGUgZGVsZWdhdGUgbWV0aG9kLlxuICAgICAgcmV0dXJuIGluZm87XG4gICAgfVxuXG4gICAgLy8gVGhlIGRlbGVnYXRlIGl0ZXJhdG9yIGlzIGZpbmlzaGVkLCBzbyBmb3JnZXQgaXQgYW5kIGNvbnRpbnVlIHdpdGhcbiAgICAvLyB0aGUgb3V0ZXIgZ2VuZXJhdG9yLlxuICAgIGNvbnRleHQuZGVsZWdhdGUgPSBudWxsO1xuICAgIHJldHVybiBDb250aW51ZVNlbnRpbmVsO1xuICB9XG5cbiAgLy8gRGVmaW5lIEdlbmVyYXRvci5wcm90b3R5cGUue25leHQsdGhyb3cscmV0dXJufSBpbiB0ZXJtcyBvZiB0aGVcbiAgLy8gdW5pZmllZCAuX2ludm9rZSBoZWxwZXIgbWV0aG9kLlxuICBkZWZpbmVJdGVyYXRvck1ldGhvZHMoR3ApO1xuXG4gIEdwW3RvU3RyaW5nVGFnU3ltYm9sXSA9IFwiR2VuZXJhdG9yXCI7XG5cbiAgLy8gQSBHZW5lcmF0b3Igc2hvdWxkIGFsd2F5cyByZXR1cm4gaXRzZWxmIGFzIHRoZSBpdGVyYXRvciBvYmplY3Qgd2hlbiB0aGVcbiAgLy8gQEBpdGVyYXRvciBmdW5jdGlvbiBpcyBjYWxsZWQgb24gaXQuIFNvbWUgYnJvd3NlcnMnIGltcGxlbWVudGF0aW9ucyBvZiB0aGVcbiAgLy8gaXRlcmF0b3IgcHJvdG90eXBlIGNoYWluIGluY29ycmVjdGx5IGltcGxlbWVudCB0aGlzLCBjYXVzaW5nIHRoZSBHZW5lcmF0b3JcbiAgLy8gb2JqZWN0IHRvIG5vdCBiZSByZXR1cm5lZCBmcm9tIHRoaXMgY2FsbC4gVGhpcyBlbnN1cmVzIHRoYXQgZG9lc24ndCBoYXBwZW4uXG4gIC8vIFNlZSBodHRwczovL2dpdGh1Yi5jb20vZmFjZWJvb2svcmVnZW5lcmF0b3IvaXNzdWVzLzI3NCBmb3IgbW9yZSBkZXRhaWxzLlxuICBHcFtpdGVyYXRvclN5bWJvbF0gPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gdGhpcztcbiAgfTtcblxuICBHcC50b1N0cmluZyA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiBcIltvYmplY3QgR2VuZXJhdG9yXVwiO1xuICB9O1xuXG4gIGZ1bmN0aW9uIHB1c2hUcnlFbnRyeShsb2NzKSB7XG4gICAgdmFyIGVudHJ5ID0geyB0cnlMb2M6IGxvY3NbMF0gfTtcblxuICAgIGlmICgxIGluIGxvY3MpIHtcbiAgICAgIGVudHJ5LmNhdGNoTG9jID0gbG9jc1sxXTtcbiAgICB9XG5cbiAgICBpZiAoMiBpbiBsb2NzKSB7XG4gICAgICBlbnRyeS5maW5hbGx5TG9jID0gbG9jc1syXTtcbiAgICAgIGVudHJ5LmFmdGVyTG9jID0gbG9jc1szXTtcbiAgICB9XG5cbiAgICB0aGlzLnRyeUVudHJpZXMucHVzaChlbnRyeSk7XG4gIH1cblxuICBmdW5jdGlvbiByZXNldFRyeUVudHJ5KGVudHJ5KSB7XG4gICAgdmFyIHJlY29yZCA9IGVudHJ5LmNvbXBsZXRpb24gfHwge307XG4gICAgcmVjb3JkLnR5cGUgPSBcIm5vcm1hbFwiO1xuICAgIGRlbGV0ZSByZWNvcmQuYXJnO1xuICAgIGVudHJ5LmNvbXBsZXRpb24gPSByZWNvcmQ7XG4gIH1cblxuICBmdW5jdGlvbiBDb250ZXh0KHRyeUxvY3NMaXN0KSB7XG4gICAgLy8gVGhlIHJvb3QgZW50cnkgb2JqZWN0IChlZmZlY3RpdmVseSBhIHRyeSBzdGF0ZW1lbnQgd2l0aG91dCBhIGNhdGNoXG4gICAgLy8gb3IgYSBmaW5hbGx5IGJsb2NrKSBnaXZlcyB1cyBhIHBsYWNlIHRvIHN0b3JlIHZhbHVlcyB0aHJvd24gZnJvbVxuICAgIC8vIGxvY2F0aW9ucyB3aGVyZSB0aGVyZSBpcyBubyBlbmNsb3NpbmcgdHJ5IHN0YXRlbWVudC5cbiAgICB0aGlzLnRyeUVudHJpZXMgPSBbeyB0cnlMb2M6IFwicm9vdFwiIH1dO1xuICAgIHRyeUxvY3NMaXN0LmZvckVhY2gocHVzaFRyeUVudHJ5LCB0aGlzKTtcbiAgICB0aGlzLnJlc2V0KHRydWUpO1xuICB9XG5cbiAgcnVudGltZS5rZXlzID0gZnVuY3Rpb24ob2JqZWN0KSB7XG4gICAgdmFyIGtleXMgPSBbXTtcbiAgICBmb3IgKHZhciBrZXkgaW4gb2JqZWN0KSB7XG4gICAgICBrZXlzLnB1c2goa2V5KTtcbiAgICB9XG4gICAga2V5cy5yZXZlcnNlKCk7XG5cbiAgICAvLyBSYXRoZXIgdGhhbiByZXR1cm5pbmcgYW4gb2JqZWN0IHdpdGggYSBuZXh0IG1ldGhvZCwgd2Uga2VlcFxuICAgIC8vIHRoaW5ncyBzaW1wbGUgYW5kIHJldHVybiB0aGUgbmV4dCBmdW5jdGlvbiBpdHNlbGYuXG4gICAgcmV0dXJuIGZ1bmN0aW9uIG5leHQoKSB7XG4gICAgICB3aGlsZSAoa2V5cy5sZW5ndGgpIHtcbiAgICAgICAgdmFyIGtleSA9IGtleXMucG9wKCk7XG4gICAgICAgIGlmIChrZXkgaW4gb2JqZWN0KSB7XG4gICAgICAgICAgbmV4dC52YWx1ZSA9IGtleTtcbiAgICAgICAgICBuZXh0LmRvbmUgPSBmYWxzZTtcbiAgICAgICAgICByZXR1cm4gbmV4dDtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyBUbyBhdm9pZCBjcmVhdGluZyBhbiBhZGRpdGlvbmFsIG9iamVjdCwgd2UganVzdCBoYW5nIHRoZSAudmFsdWVcbiAgICAgIC8vIGFuZCAuZG9uZSBwcm9wZXJ0aWVzIG9mZiB0aGUgbmV4dCBmdW5jdGlvbiBvYmplY3QgaXRzZWxmLiBUaGlzXG4gICAgICAvLyBhbHNvIGVuc3VyZXMgdGhhdCB0aGUgbWluaWZpZXIgd2lsbCBub3QgYW5vbnltaXplIHRoZSBmdW5jdGlvbi5cbiAgICAgIG5leHQuZG9uZSA9IHRydWU7XG4gICAgICByZXR1cm4gbmV4dDtcbiAgICB9O1xuICB9O1xuXG4gIGZ1bmN0aW9uIHZhbHVlcyhpdGVyYWJsZSkge1xuICAgIGlmIChpdGVyYWJsZSkge1xuICAgICAgdmFyIGl0ZXJhdG9yTWV0aG9kID0gaXRlcmFibGVbaXRlcmF0b3JTeW1ib2xdO1xuICAgICAgaWYgKGl0ZXJhdG9yTWV0aG9kKSB7XG4gICAgICAgIHJldHVybiBpdGVyYXRvck1ldGhvZC5jYWxsKGl0ZXJhYmxlKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHR5cGVvZiBpdGVyYWJsZS5uZXh0ID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgcmV0dXJuIGl0ZXJhYmxlO1xuICAgICAgfVxuXG4gICAgICBpZiAoIWlzTmFOKGl0ZXJhYmxlLmxlbmd0aCkpIHtcbiAgICAgICAgdmFyIGkgPSAtMSwgbmV4dCA9IGZ1bmN0aW9uIG5leHQoKSB7XG4gICAgICAgICAgd2hpbGUgKCsraSA8IGl0ZXJhYmxlLmxlbmd0aCkge1xuICAgICAgICAgICAgaWYgKGhhc093bi5jYWxsKGl0ZXJhYmxlLCBpKSkge1xuICAgICAgICAgICAgICBuZXh0LnZhbHVlID0gaXRlcmFibGVbaV07XG4gICAgICAgICAgICAgIG5leHQuZG9uZSA9IGZhbHNlO1xuICAgICAgICAgICAgICByZXR1cm4gbmV4dDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG5cbiAgICAgICAgICBuZXh0LnZhbHVlID0gdW5kZWZpbmVkO1xuICAgICAgICAgIG5leHQuZG9uZSA9IHRydWU7XG5cbiAgICAgICAgICByZXR1cm4gbmV4dDtcbiAgICAgICAgfTtcblxuICAgICAgICByZXR1cm4gbmV4dC5uZXh0ID0gbmV4dDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBSZXR1cm4gYW4gaXRlcmF0b3Igd2l0aCBubyB2YWx1ZXMuXG4gICAgcmV0dXJuIHsgbmV4dDogZG9uZVJlc3VsdCB9O1xuICB9XG4gIHJ1bnRpbWUudmFsdWVzID0gdmFsdWVzO1xuXG4gIGZ1bmN0aW9uIGRvbmVSZXN1bHQoKSB7XG4gICAgcmV0dXJuIHsgdmFsdWU6IHVuZGVmaW5lZCwgZG9uZTogdHJ1ZSB9O1xuICB9XG5cbiAgQ29udGV4dC5wcm90b3R5cGUgPSB7XG4gICAgY29uc3RydWN0b3I6IENvbnRleHQsXG5cbiAgICByZXNldDogZnVuY3Rpb24oc2tpcFRlbXBSZXNldCkge1xuICAgICAgdGhpcy5wcmV2ID0gMDtcbiAgICAgIHRoaXMubmV4dCA9IDA7XG4gICAgICAvLyBSZXNldHRpbmcgY29udGV4dC5fc2VudCBmb3IgbGVnYWN5IHN1cHBvcnQgb2YgQmFiZWwnc1xuICAgICAgLy8gZnVuY3Rpb24uc2VudCBpbXBsZW1lbnRhdGlvbi5cbiAgICAgIHRoaXMuc2VudCA9IHRoaXMuX3NlbnQgPSB1bmRlZmluZWQ7XG4gICAgICB0aGlzLmRvbmUgPSBmYWxzZTtcbiAgICAgIHRoaXMuZGVsZWdhdGUgPSBudWxsO1xuXG4gICAgICB0aGlzLm1ldGhvZCA9IFwibmV4dFwiO1xuICAgICAgdGhpcy5hcmcgPSB1bmRlZmluZWQ7XG5cbiAgICAgIHRoaXMudHJ5RW50cmllcy5mb3JFYWNoKHJlc2V0VHJ5RW50cnkpO1xuXG4gICAgICBpZiAoIXNraXBUZW1wUmVzZXQpIHtcbiAgICAgICAgZm9yICh2YXIgbmFtZSBpbiB0aGlzKSB7XG4gICAgICAgICAgLy8gTm90IHN1cmUgYWJvdXQgdGhlIG9wdGltYWwgb3JkZXIgb2YgdGhlc2UgY29uZGl0aW9uczpcbiAgICAgICAgICBpZiAobmFtZS5jaGFyQXQoMCkgPT09IFwidFwiICYmXG4gICAgICAgICAgICAgIGhhc093bi5jYWxsKHRoaXMsIG5hbWUpICYmXG4gICAgICAgICAgICAgICFpc05hTigrbmFtZS5zbGljZSgxKSkpIHtcbiAgICAgICAgICAgIHRoaXNbbmFtZV0gPSB1bmRlZmluZWQ7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfSxcblxuICAgIHN0b3A6IGZ1bmN0aW9uKCkge1xuICAgICAgdGhpcy5kb25lID0gdHJ1ZTtcblxuICAgICAgdmFyIHJvb3RFbnRyeSA9IHRoaXMudHJ5RW50cmllc1swXTtcbiAgICAgIHZhciByb290UmVjb3JkID0gcm9vdEVudHJ5LmNvbXBsZXRpb247XG4gICAgICBpZiAocm9vdFJlY29yZC50eXBlID09PSBcInRocm93XCIpIHtcbiAgICAgICAgdGhyb3cgcm9vdFJlY29yZC5hcmc7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB0aGlzLnJ2YWw7XG4gICAgfSxcblxuICAgIGRpc3BhdGNoRXhjZXB0aW9uOiBmdW5jdGlvbihleGNlcHRpb24pIHtcbiAgICAgIGlmICh0aGlzLmRvbmUpIHtcbiAgICAgICAgdGhyb3cgZXhjZXB0aW9uO1xuICAgICAgfVxuXG4gICAgICB2YXIgY29udGV4dCA9IHRoaXM7XG4gICAgICBmdW5jdGlvbiBoYW5kbGUobG9jLCBjYXVnaHQpIHtcbiAgICAgICAgcmVjb3JkLnR5cGUgPSBcInRocm93XCI7XG4gICAgICAgIHJlY29yZC5hcmcgPSBleGNlcHRpb247XG4gICAgICAgIGNvbnRleHQubmV4dCA9IGxvYztcblxuICAgICAgICBpZiAoY2F1Z2h0KSB7XG4gICAgICAgICAgLy8gSWYgdGhlIGRpc3BhdGNoZWQgZXhjZXB0aW9uIHdhcyBjYXVnaHQgYnkgYSBjYXRjaCBibG9jayxcbiAgICAgICAgICAvLyB0aGVuIGxldCB0aGF0IGNhdGNoIGJsb2NrIGhhbmRsZSB0aGUgZXhjZXB0aW9uIG5vcm1hbGx5LlxuICAgICAgICAgIGNvbnRleHQubWV0aG9kID0gXCJuZXh0XCI7XG4gICAgICAgICAgY29udGV4dC5hcmcgPSB1bmRlZmluZWQ7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gISEgY2F1Z2h0O1xuICAgICAgfVxuXG4gICAgICBmb3IgKHZhciBpID0gdGhpcy50cnlFbnRyaWVzLmxlbmd0aCAtIDE7IGkgPj0gMDsgLS1pKSB7XG4gICAgICAgIHZhciBlbnRyeSA9IHRoaXMudHJ5RW50cmllc1tpXTtcbiAgICAgICAgdmFyIHJlY29yZCA9IGVudHJ5LmNvbXBsZXRpb247XG5cbiAgICAgICAgaWYgKGVudHJ5LnRyeUxvYyA9PT0gXCJyb290XCIpIHtcbiAgICAgICAgICAvLyBFeGNlcHRpb24gdGhyb3duIG91dHNpZGUgb2YgYW55IHRyeSBibG9jayB0aGF0IGNvdWxkIGhhbmRsZVxuICAgICAgICAgIC8vIGl0LCBzbyBzZXQgdGhlIGNvbXBsZXRpb24gdmFsdWUgb2YgdGhlIGVudGlyZSBmdW5jdGlvbiB0b1xuICAgICAgICAgIC8vIHRocm93IHRoZSBleGNlcHRpb24uXG4gICAgICAgICAgcmV0dXJuIGhhbmRsZShcImVuZFwiKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChlbnRyeS50cnlMb2MgPD0gdGhpcy5wcmV2KSB7XG4gICAgICAgICAgdmFyIGhhc0NhdGNoID0gaGFzT3duLmNhbGwoZW50cnksIFwiY2F0Y2hMb2NcIik7XG4gICAgICAgICAgdmFyIGhhc0ZpbmFsbHkgPSBoYXNPd24uY2FsbChlbnRyeSwgXCJmaW5hbGx5TG9jXCIpO1xuXG4gICAgICAgICAgaWYgKGhhc0NhdGNoICYmIGhhc0ZpbmFsbHkpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLnByZXYgPCBlbnRyeS5jYXRjaExvYykge1xuICAgICAgICAgICAgICByZXR1cm4gaGFuZGxlKGVudHJ5LmNhdGNoTG9jLCB0cnVlKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAodGhpcy5wcmV2IDwgZW50cnkuZmluYWxseUxvYykge1xuICAgICAgICAgICAgICByZXR1cm4gaGFuZGxlKGVudHJ5LmZpbmFsbHlMb2MpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgfSBlbHNlIGlmIChoYXNDYXRjaCkge1xuICAgICAgICAgICAgaWYgKHRoaXMucHJldiA8IGVudHJ5LmNhdGNoTG9jKSB7XG4gICAgICAgICAgICAgIHJldHVybiBoYW5kbGUoZW50cnkuY2F0Y2hMb2MsIHRydWUpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgfSBlbHNlIGlmIChoYXNGaW5hbGx5KSB7XG4gICAgICAgICAgICBpZiAodGhpcy5wcmV2IDwgZW50cnkuZmluYWxseUxvYykge1xuICAgICAgICAgICAgICByZXR1cm4gaGFuZGxlKGVudHJ5LmZpbmFsbHlMb2MpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcInRyeSBzdGF0ZW1lbnQgd2l0aG91dCBjYXRjaCBvciBmaW5hbGx5XCIpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0sXG5cbiAgICBhYnJ1cHQ6IGZ1bmN0aW9uKHR5cGUsIGFyZykge1xuICAgICAgZm9yICh2YXIgaSA9IHRoaXMudHJ5RW50cmllcy5sZW5ndGggLSAxOyBpID49IDA7IC0taSkge1xuICAgICAgICB2YXIgZW50cnkgPSB0aGlzLnRyeUVudHJpZXNbaV07XG4gICAgICAgIGlmIChlbnRyeS50cnlMb2MgPD0gdGhpcy5wcmV2ICYmXG4gICAgICAgICAgICBoYXNPd24uY2FsbChlbnRyeSwgXCJmaW5hbGx5TG9jXCIpICYmXG4gICAgICAgICAgICB0aGlzLnByZXYgPCBlbnRyeS5maW5hbGx5TG9jKSB7XG4gICAgICAgICAgdmFyIGZpbmFsbHlFbnRyeSA9IGVudHJ5O1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmIChmaW5hbGx5RW50cnkgJiZcbiAgICAgICAgICAodHlwZSA9PT0gXCJicmVha1wiIHx8XG4gICAgICAgICAgIHR5cGUgPT09IFwiY29udGludWVcIikgJiZcbiAgICAgICAgICBmaW5hbGx5RW50cnkudHJ5TG9jIDw9IGFyZyAmJlxuICAgICAgICAgIGFyZyA8PSBmaW5hbGx5RW50cnkuZmluYWxseUxvYykge1xuICAgICAgICAvLyBJZ25vcmUgdGhlIGZpbmFsbHkgZW50cnkgaWYgY29udHJvbCBpcyBub3QganVtcGluZyB0byBhXG4gICAgICAgIC8vIGxvY2F0aW9uIG91dHNpZGUgdGhlIHRyeS9jYXRjaCBibG9jay5cbiAgICAgICAgZmluYWxseUVudHJ5ID0gbnVsbDtcbiAgICAgIH1cblxuICAgICAgdmFyIHJlY29yZCA9IGZpbmFsbHlFbnRyeSA/IGZpbmFsbHlFbnRyeS5jb21wbGV0aW9uIDoge307XG4gICAgICByZWNvcmQudHlwZSA9IHR5cGU7XG4gICAgICByZWNvcmQuYXJnID0gYXJnO1xuXG4gICAgICBpZiAoZmluYWxseUVudHJ5KSB7XG4gICAgICAgIHRoaXMubWV0aG9kID0gXCJuZXh0XCI7XG4gICAgICAgIHRoaXMubmV4dCA9IGZpbmFsbHlFbnRyeS5maW5hbGx5TG9jO1xuICAgICAgICByZXR1cm4gQ29udGludWVTZW50aW5lbDtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHRoaXMuY29tcGxldGUocmVjb3JkKTtcbiAgICB9LFxuXG4gICAgY29tcGxldGU6IGZ1bmN0aW9uKHJlY29yZCwgYWZ0ZXJMb2MpIHtcbiAgICAgIGlmIChyZWNvcmQudHlwZSA9PT0gXCJ0aHJvd1wiKSB7XG4gICAgICAgIHRocm93IHJlY29yZC5hcmc7XG4gICAgICB9XG5cbiAgICAgIGlmIChyZWNvcmQudHlwZSA9PT0gXCJicmVha1wiIHx8XG4gICAgICAgICAgcmVjb3JkLnR5cGUgPT09IFwiY29udGludWVcIikge1xuICAgICAgICB0aGlzLm5leHQgPSByZWNvcmQuYXJnO1xuICAgICAgfSBlbHNlIGlmIChyZWNvcmQudHlwZSA9PT0gXCJyZXR1cm5cIikge1xuICAgICAgICB0aGlzLnJ2YWwgPSB0aGlzLmFyZyA9IHJlY29yZC5hcmc7XG4gICAgICAgIHRoaXMubWV0aG9kID0gXCJyZXR1cm5cIjtcbiAgICAgICAgdGhpcy5uZXh0ID0gXCJlbmRcIjtcbiAgICAgIH0gZWxzZSBpZiAocmVjb3JkLnR5cGUgPT09IFwibm9ybWFsXCIgJiYgYWZ0ZXJMb2MpIHtcbiAgICAgICAgdGhpcy5uZXh0ID0gYWZ0ZXJMb2M7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBDb250aW51ZVNlbnRpbmVsO1xuICAgIH0sXG5cbiAgICBmaW5pc2g6IGZ1bmN0aW9uKGZpbmFsbHlMb2MpIHtcbiAgICAgIGZvciAodmFyIGkgPSB0aGlzLnRyeUVudHJpZXMubGVuZ3RoIC0gMTsgaSA+PSAwOyAtLWkpIHtcbiAgICAgICAgdmFyIGVudHJ5ID0gdGhpcy50cnlFbnRyaWVzW2ldO1xuICAgICAgICBpZiAoZW50cnkuZmluYWxseUxvYyA9PT0gZmluYWxseUxvYykge1xuICAgICAgICAgIHRoaXMuY29tcGxldGUoZW50cnkuY29tcGxldGlvbiwgZW50cnkuYWZ0ZXJMb2MpO1xuICAgICAgICAgIHJlc2V0VHJ5RW50cnkoZW50cnkpO1xuICAgICAgICAgIHJldHVybiBDb250aW51ZVNlbnRpbmVsO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSxcblxuICAgIFwiY2F0Y2hcIjogZnVuY3Rpb24odHJ5TG9jKSB7XG4gICAgICBmb3IgKHZhciBpID0gdGhpcy50cnlFbnRyaWVzLmxlbmd0aCAtIDE7IGkgPj0gMDsgLS1pKSB7XG4gICAgICAgIHZhciBlbnRyeSA9IHRoaXMudHJ5RW50cmllc1tpXTtcbiAgICAgICAgaWYgKGVudHJ5LnRyeUxvYyA9PT0gdHJ5TG9jKSB7XG4gICAgICAgICAgdmFyIHJlY29yZCA9IGVudHJ5LmNvbXBsZXRpb247XG4gICAgICAgICAgaWYgKHJlY29yZC50eXBlID09PSBcInRocm93XCIpIHtcbiAgICAgICAgICAgIHZhciB0aHJvd24gPSByZWNvcmQuYXJnO1xuICAgICAgICAgICAgcmVzZXRUcnlFbnRyeShlbnRyeSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiB0aHJvd247XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gVGhlIGNvbnRleHQuY2F0Y2ggbWV0aG9kIG11c3Qgb25seSBiZSBjYWxsZWQgd2l0aCBhIGxvY2F0aW9uXG4gICAgICAvLyBhcmd1bWVudCB0aGF0IGNvcnJlc3BvbmRzIHRvIGEga25vd24gY2F0Y2ggYmxvY2suXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJpbGxlZ2FsIGNhdGNoIGF0dGVtcHRcIik7XG4gICAgfSxcblxuICAgIGRlbGVnYXRlWWllbGQ6IGZ1bmN0aW9uKGl0ZXJhYmxlLCByZXN1bHROYW1lLCBuZXh0TG9jKSB7XG4gICAgICB0aGlzLmRlbGVnYXRlID0ge1xuICAgICAgICBpdGVyYXRvcjogdmFsdWVzKGl0ZXJhYmxlKSxcbiAgICAgICAgcmVzdWx0TmFtZTogcmVzdWx0TmFtZSxcbiAgICAgICAgbmV4dExvYzogbmV4dExvY1xuICAgICAgfTtcblxuICAgICAgaWYgKHRoaXMubWV0aG9kID09PSBcIm5leHRcIikge1xuICAgICAgICAvLyBEZWxpYmVyYXRlbHkgZm9yZ2V0IHRoZSBsYXN0IHNlbnQgdmFsdWUgc28gdGhhdCB3ZSBkb24ndFxuICAgICAgICAvLyBhY2NpZGVudGFsbHkgcGFzcyBpdCBvbiB0byB0aGUgZGVsZWdhdGUuXG4gICAgICAgIHRoaXMuYXJnID0gdW5kZWZpbmVkO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gQ29udGludWVTZW50aW5lbDtcbiAgICB9XG4gIH07XG59KShcbiAgLy8gSW4gc2xvcHB5IG1vZGUsIHVuYm91bmQgYHRoaXNgIHJlZmVycyB0byB0aGUgZ2xvYmFsIG9iamVjdCwgZmFsbGJhY2sgdG9cbiAgLy8gRnVuY3Rpb24gY29uc3RydWN0b3IgaWYgd2UncmUgaW4gZ2xvYmFsIHN0cmljdCBtb2RlLiBUaGF0IGlzIHNhZGx5IGEgZm9ybVxuICAvLyBvZiBpbmRpcmVjdCBldmFsIHdoaWNoIHZpb2xhdGVzIENvbnRlbnQgU2VjdXJpdHkgUG9saWN5LlxuICAoZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHRoaXMgfHwgKHR5cGVvZiBzZWxmID09PSBcIm9iamVjdFwiICYmIHNlbGYpO1xuICB9KSgpIHx8IEZ1bmN0aW9uKFwicmV0dXJuIHRoaXNcIikoKVxuKTtcbiIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcInJlZ2VuZXJhdG9yLXJ1bnRpbWVcIik7XG4iLCIvLyBDb3B5cmlnaHQgSm95ZW50LCBJbmMuIGFuZCBvdGhlciBOb2RlIGNvbnRyaWJ1dG9ycy5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYVxuLy8gY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZVxuLy8gXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nXG4vLyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsXG4vLyBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0XG4vLyBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGVcbi8vIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy9cbi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkXG4vLyBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vXG4vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTXG4vLyBPUiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GXG4vLyBNRVJDSEFOVEFCSUxJVFksIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOXG4vLyBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSxcbi8vIERBTUFHRVMgT1IgT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUlxuLy8gT1RIRVJXSVNFLCBBUklTSU5HIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRVxuLy8gVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS5cblxudmFyIG9iamVjdENyZWF0ZSA9IE9iamVjdC5jcmVhdGUgfHwgb2JqZWN0Q3JlYXRlUG9seWZpbGxcbnZhciBvYmplY3RLZXlzID0gT2JqZWN0LmtleXMgfHwgb2JqZWN0S2V5c1BvbHlmaWxsXG52YXIgYmluZCA9IEZ1bmN0aW9uLnByb3RvdHlwZS5iaW5kIHx8IGZ1bmN0aW9uQmluZFBvbHlmaWxsXG5cbmZ1bmN0aW9uIEV2ZW50RW1pdHRlcigpIHtcbiAgaWYgKCF0aGlzLl9ldmVudHMgfHwgIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbCh0aGlzLCAnX2V2ZW50cycpKSB7XG4gICAgdGhpcy5fZXZlbnRzID0gb2JqZWN0Q3JlYXRlKG51bGwpO1xuICAgIHRoaXMuX2V2ZW50c0NvdW50ID0gMDtcbiAgfVxuXG4gIHRoaXMuX21heExpc3RlbmVycyA9IHRoaXMuX21heExpc3RlbmVycyB8fCB1bmRlZmluZWQ7XG59XG5tb2R1bGUuZXhwb3J0cyA9IEV2ZW50RW1pdHRlcjtcblxuLy8gQmFja3dhcmRzLWNvbXBhdCB3aXRoIG5vZGUgMC4xMC54XG5FdmVudEVtaXR0ZXIuRXZlbnRFbWl0dGVyID0gRXZlbnRFbWl0dGVyO1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLl9ldmVudHMgPSB1bmRlZmluZWQ7XG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLl9tYXhMaXN0ZW5lcnMgPSB1bmRlZmluZWQ7XG5cbi8vIEJ5IGRlZmF1bHQgRXZlbnRFbWl0dGVycyB3aWxsIHByaW50IGEgd2FybmluZyBpZiBtb3JlIHRoYW4gMTAgbGlzdGVuZXJzIGFyZVxuLy8gYWRkZWQgdG8gaXQuIFRoaXMgaXMgYSB1c2VmdWwgZGVmYXVsdCB3aGljaCBoZWxwcyBmaW5kaW5nIG1lbW9yeSBsZWFrcy5cbnZhciBkZWZhdWx0TWF4TGlzdGVuZXJzID0gMTA7XG5cbnZhciBoYXNEZWZpbmVQcm9wZXJ0eTtcbnRyeSB7XG4gIHZhciBvID0ge307XG4gIGlmIChPYmplY3QuZGVmaW5lUHJvcGVydHkpIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShvLCAneCcsIHsgdmFsdWU6IDAgfSk7XG4gIGhhc0RlZmluZVByb3BlcnR5ID0gby54ID09PSAwO1xufSBjYXRjaCAoZXJyKSB7IGhhc0RlZmluZVByb3BlcnR5ID0gZmFsc2UgfVxuaWYgKGhhc0RlZmluZVByb3BlcnR5KSB7XG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShFdmVudEVtaXR0ZXIsICdkZWZhdWx0TWF4TGlzdGVuZXJzJywge1xuICAgIGVudW1lcmFibGU6IHRydWUsXG4gICAgZ2V0OiBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiBkZWZhdWx0TWF4TGlzdGVuZXJzO1xuICAgIH0sXG4gICAgc2V0OiBmdW5jdGlvbihhcmcpIHtcbiAgICAgIC8vIGNoZWNrIHdoZXRoZXIgdGhlIGlucHV0IGlzIGEgcG9zaXRpdmUgbnVtYmVyICh3aG9zZSB2YWx1ZSBpcyB6ZXJvIG9yXG4gICAgICAvLyBncmVhdGVyIGFuZCBub3QgYSBOYU4pLlxuICAgICAgaWYgKHR5cGVvZiBhcmcgIT09ICdudW1iZXInIHx8IGFyZyA8IDAgfHwgYXJnICE9PSBhcmcpXG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ1wiZGVmYXVsdE1heExpc3RlbmVyc1wiIG11c3QgYmUgYSBwb3NpdGl2ZSBudW1iZXInKTtcbiAgICAgIGRlZmF1bHRNYXhMaXN0ZW5lcnMgPSBhcmc7XG4gICAgfVxuICB9KTtcbn0gZWxzZSB7XG4gIEV2ZW50RW1pdHRlci5kZWZhdWx0TWF4TGlzdGVuZXJzID0gZGVmYXVsdE1heExpc3RlbmVycztcbn1cblxuLy8gT2J2aW91c2x5IG5vdCBhbGwgRW1pdHRlcnMgc2hvdWxkIGJlIGxpbWl0ZWQgdG8gMTAuIFRoaXMgZnVuY3Rpb24gYWxsb3dzXG4vLyB0aGF0IHRvIGJlIGluY3JlYXNlZC4gU2V0IHRvIHplcm8gZm9yIHVubGltaXRlZC5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUuc2V0TWF4TGlzdGVuZXJzID0gZnVuY3Rpb24gc2V0TWF4TGlzdGVuZXJzKG4pIHtcbiAgaWYgKHR5cGVvZiBuICE9PSAnbnVtYmVyJyB8fCBuIDwgMCB8fCBpc05hTihuKSlcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdcIm5cIiBhcmd1bWVudCBtdXN0IGJlIGEgcG9zaXRpdmUgbnVtYmVyJyk7XG4gIHRoaXMuX21heExpc3RlbmVycyA9IG47XG4gIHJldHVybiB0aGlzO1xufTtcblxuZnVuY3Rpb24gJGdldE1heExpc3RlbmVycyh0aGF0KSB7XG4gIGlmICh0aGF0Ll9tYXhMaXN0ZW5lcnMgPT09IHVuZGVmaW5lZClcbiAgICByZXR1cm4gRXZlbnRFbWl0dGVyLmRlZmF1bHRNYXhMaXN0ZW5lcnM7XG4gIHJldHVybiB0aGF0Ll9tYXhMaXN0ZW5lcnM7XG59XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUuZ2V0TWF4TGlzdGVuZXJzID0gZnVuY3Rpb24gZ2V0TWF4TGlzdGVuZXJzKCkge1xuICByZXR1cm4gJGdldE1heExpc3RlbmVycyh0aGlzKTtcbn07XG5cbi8vIFRoZXNlIHN0YW5kYWxvbmUgZW1pdCogZnVuY3Rpb25zIGFyZSB1c2VkIHRvIG9wdGltaXplIGNhbGxpbmcgb2YgZXZlbnRcbi8vIGhhbmRsZXJzIGZvciBmYXN0IGNhc2VzIGJlY2F1c2UgZW1pdCgpIGl0c2VsZiBvZnRlbiBoYXMgYSB2YXJpYWJsZSBudW1iZXIgb2Zcbi8vIGFyZ3VtZW50cyBhbmQgY2FuIGJlIGRlb3B0aW1pemVkIGJlY2F1c2Ugb2YgdGhhdC4gVGhlc2UgZnVuY3Rpb25zIGFsd2F5cyBoYXZlXG4vLyB0aGUgc2FtZSBudW1iZXIgb2YgYXJndW1lbnRzIGFuZCB0aHVzIGRvIG5vdCBnZXQgZGVvcHRpbWl6ZWQsIHNvIHRoZSBjb2RlXG4vLyBpbnNpZGUgdGhlbSBjYW4gZXhlY3V0ZSBmYXN0ZXIuXG5mdW5jdGlvbiBlbWl0Tm9uZShoYW5kbGVyLCBpc0ZuLCBzZWxmKSB7XG4gIGlmIChpc0ZuKVxuICAgIGhhbmRsZXIuY2FsbChzZWxmKTtcbiAgZWxzZSB7XG4gICAgdmFyIGxlbiA9IGhhbmRsZXIubGVuZ3RoO1xuICAgIHZhciBsaXN0ZW5lcnMgPSBhcnJheUNsb25lKGhhbmRsZXIsIGxlbik7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47ICsraSlcbiAgICAgIGxpc3RlbmVyc1tpXS5jYWxsKHNlbGYpO1xuICB9XG59XG5mdW5jdGlvbiBlbWl0T25lKGhhbmRsZXIsIGlzRm4sIHNlbGYsIGFyZzEpIHtcbiAgaWYgKGlzRm4pXG4gICAgaGFuZGxlci5jYWxsKHNlbGYsIGFyZzEpO1xuICBlbHNlIHtcbiAgICB2YXIgbGVuID0gaGFuZGxlci5sZW5ndGg7XG4gICAgdmFyIGxpc3RlbmVycyA9IGFycmF5Q2xvbmUoaGFuZGxlciwgbGVuKTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgKytpKVxuICAgICAgbGlzdGVuZXJzW2ldLmNhbGwoc2VsZiwgYXJnMSk7XG4gIH1cbn1cbmZ1bmN0aW9uIGVtaXRUd28oaGFuZGxlciwgaXNGbiwgc2VsZiwgYXJnMSwgYXJnMikge1xuICBpZiAoaXNGbilcbiAgICBoYW5kbGVyLmNhbGwoc2VsZiwgYXJnMSwgYXJnMik7XG4gIGVsc2Uge1xuICAgIHZhciBsZW4gPSBoYW5kbGVyLmxlbmd0aDtcbiAgICB2YXIgbGlzdGVuZXJzID0gYXJyYXlDbG9uZShoYW5kbGVyLCBsZW4pO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyArK2kpXG4gICAgICBsaXN0ZW5lcnNbaV0uY2FsbChzZWxmLCBhcmcxLCBhcmcyKTtcbiAgfVxufVxuZnVuY3Rpb24gZW1pdFRocmVlKGhhbmRsZXIsIGlzRm4sIHNlbGYsIGFyZzEsIGFyZzIsIGFyZzMpIHtcbiAgaWYgKGlzRm4pXG4gICAgaGFuZGxlci5jYWxsKHNlbGYsIGFyZzEsIGFyZzIsIGFyZzMpO1xuICBlbHNlIHtcbiAgICB2YXIgbGVuID0gaGFuZGxlci5sZW5ndGg7XG4gICAgdmFyIGxpc3RlbmVycyA9IGFycmF5Q2xvbmUoaGFuZGxlciwgbGVuKTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgKytpKVxuICAgICAgbGlzdGVuZXJzW2ldLmNhbGwoc2VsZiwgYXJnMSwgYXJnMiwgYXJnMyk7XG4gIH1cbn1cblxuZnVuY3Rpb24gZW1pdE1hbnkoaGFuZGxlciwgaXNGbiwgc2VsZiwgYXJncykge1xuICBpZiAoaXNGbilcbiAgICBoYW5kbGVyLmFwcGx5KHNlbGYsIGFyZ3MpO1xuICBlbHNlIHtcbiAgICB2YXIgbGVuID0gaGFuZGxlci5sZW5ndGg7XG4gICAgdmFyIGxpc3RlbmVycyA9IGFycmF5Q2xvbmUoaGFuZGxlciwgbGVuKTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgKytpKVxuICAgICAgbGlzdGVuZXJzW2ldLmFwcGx5KHNlbGYsIGFyZ3MpO1xuICB9XG59XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUuZW1pdCA9IGZ1bmN0aW9uIGVtaXQodHlwZSkge1xuICB2YXIgZXIsIGhhbmRsZXIsIGxlbiwgYXJncywgaSwgZXZlbnRzO1xuICB2YXIgZG9FcnJvciA9ICh0eXBlID09PSAnZXJyb3InKTtcblxuICBldmVudHMgPSB0aGlzLl9ldmVudHM7XG4gIGlmIChldmVudHMpXG4gICAgZG9FcnJvciA9IChkb0Vycm9yICYmIGV2ZW50cy5lcnJvciA9PSBudWxsKTtcbiAgZWxzZSBpZiAoIWRvRXJyb3IpXG4gICAgcmV0dXJuIGZhbHNlO1xuXG4gIC8vIElmIHRoZXJlIGlzIG5vICdlcnJvcicgZXZlbnQgbGlzdGVuZXIgdGhlbiB0aHJvdy5cbiAgaWYgKGRvRXJyb3IpIHtcbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA+IDEpXG4gICAgICBlciA9IGFyZ3VtZW50c1sxXTtcbiAgICBpZiAoZXIgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgdGhyb3cgZXI7IC8vIFVuaGFuZGxlZCAnZXJyb3InIGV2ZW50XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIEF0IGxlYXN0IGdpdmUgc29tZSBraW5kIG9mIGNvbnRleHQgdG8gdGhlIHVzZXJcbiAgICAgIHZhciBlcnIgPSBuZXcgRXJyb3IoJ1VuaGFuZGxlZCBcImVycm9yXCIgZXZlbnQuICgnICsgZXIgKyAnKScpO1xuICAgICAgZXJyLmNvbnRleHQgPSBlcjtcbiAgICAgIHRocm93IGVycjtcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgaGFuZGxlciA9IGV2ZW50c1t0eXBlXTtcblxuICBpZiAoIWhhbmRsZXIpXG4gICAgcmV0dXJuIGZhbHNlO1xuXG4gIHZhciBpc0ZuID0gdHlwZW9mIGhhbmRsZXIgPT09ICdmdW5jdGlvbic7XG4gIGxlbiA9IGFyZ3VtZW50cy5sZW5ndGg7XG4gIHN3aXRjaCAobGVuKSB7XG4gICAgICAvLyBmYXN0IGNhc2VzXG4gICAgY2FzZSAxOlxuICAgICAgZW1pdE5vbmUoaGFuZGxlciwgaXNGbiwgdGhpcyk7XG4gICAgICBicmVhaztcbiAgICBjYXNlIDI6XG4gICAgICBlbWl0T25lKGhhbmRsZXIsIGlzRm4sIHRoaXMsIGFyZ3VtZW50c1sxXSk7XG4gICAgICBicmVhaztcbiAgICBjYXNlIDM6XG4gICAgICBlbWl0VHdvKGhhbmRsZXIsIGlzRm4sIHRoaXMsIGFyZ3VtZW50c1sxXSwgYXJndW1lbnRzWzJdKTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgNDpcbiAgICAgIGVtaXRUaHJlZShoYW5kbGVyLCBpc0ZuLCB0aGlzLCBhcmd1bWVudHNbMV0sIGFyZ3VtZW50c1syXSwgYXJndW1lbnRzWzNdKTtcbiAgICAgIGJyZWFrO1xuICAgICAgLy8gc2xvd2VyXG4gICAgZGVmYXVsdDpcbiAgICAgIGFyZ3MgPSBuZXcgQXJyYXkobGVuIC0gMSk7XG4gICAgICBmb3IgKGkgPSAxOyBpIDwgbGVuOyBpKyspXG4gICAgICAgIGFyZ3NbaSAtIDFdID0gYXJndW1lbnRzW2ldO1xuICAgICAgZW1pdE1hbnkoaGFuZGxlciwgaXNGbiwgdGhpcywgYXJncyk7XG4gIH1cblxuICByZXR1cm4gdHJ1ZTtcbn07XG5cbmZ1bmN0aW9uIF9hZGRMaXN0ZW5lcih0YXJnZXQsIHR5cGUsIGxpc3RlbmVyLCBwcmVwZW5kKSB7XG4gIHZhciBtO1xuICB2YXIgZXZlbnRzO1xuICB2YXIgZXhpc3Rpbmc7XG5cbiAgaWYgKHR5cGVvZiBsaXN0ZW5lciAhPT0gJ2Z1bmN0aW9uJylcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdcImxpc3RlbmVyXCIgYXJndW1lbnQgbXVzdCBiZSBhIGZ1bmN0aW9uJyk7XG5cbiAgZXZlbnRzID0gdGFyZ2V0Ll9ldmVudHM7XG4gIGlmICghZXZlbnRzKSB7XG4gICAgZXZlbnRzID0gdGFyZ2V0Ll9ldmVudHMgPSBvYmplY3RDcmVhdGUobnVsbCk7XG4gICAgdGFyZ2V0Ll9ldmVudHNDb3VudCA9IDA7XG4gIH0gZWxzZSB7XG4gICAgLy8gVG8gYXZvaWQgcmVjdXJzaW9uIGluIHRoZSBjYXNlIHRoYXQgdHlwZSA9PT0gXCJuZXdMaXN0ZW5lclwiISBCZWZvcmVcbiAgICAvLyBhZGRpbmcgaXQgdG8gdGhlIGxpc3RlbmVycywgZmlyc3QgZW1pdCBcIm5ld0xpc3RlbmVyXCIuXG4gICAgaWYgKGV2ZW50cy5uZXdMaXN0ZW5lcikge1xuICAgICAgdGFyZ2V0LmVtaXQoJ25ld0xpc3RlbmVyJywgdHlwZSxcbiAgICAgICAgICBsaXN0ZW5lci5saXN0ZW5lciA/IGxpc3RlbmVyLmxpc3RlbmVyIDogbGlzdGVuZXIpO1xuXG4gICAgICAvLyBSZS1hc3NpZ24gYGV2ZW50c2AgYmVjYXVzZSBhIG5ld0xpc3RlbmVyIGhhbmRsZXIgY291bGQgaGF2ZSBjYXVzZWQgdGhlXG4gICAgICAvLyB0aGlzLl9ldmVudHMgdG8gYmUgYXNzaWduZWQgdG8gYSBuZXcgb2JqZWN0XG4gICAgICBldmVudHMgPSB0YXJnZXQuX2V2ZW50cztcbiAgICB9XG4gICAgZXhpc3RpbmcgPSBldmVudHNbdHlwZV07XG4gIH1cblxuICBpZiAoIWV4aXN0aW5nKSB7XG4gICAgLy8gT3B0aW1pemUgdGhlIGNhc2Ugb2Ygb25lIGxpc3RlbmVyLiBEb24ndCBuZWVkIHRoZSBleHRyYSBhcnJheSBvYmplY3QuXG4gICAgZXhpc3RpbmcgPSBldmVudHNbdHlwZV0gPSBsaXN0ZW5lcjtcbiAgICArK3RhcmdldC5fZXZlbnRzQ291bnQ7XG4gIH0gZWxzZSB7XG4gICAgaWYgKHR5cGVvZiBleGlzdGluZyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgLy8gQWRkaW5nIHRoZSBzZWNvbmQgZWxlbWVudCwgbmVlZCB0byBjaGFuZ2UgdG8gYXJyYXkuXG4gICAgICBleGlzdGluZyA9IGV2ZW50c1t0eXBlXSA9XG4gICAgICAgICAgcHJlcGVuZCA/IFtsaXN0ZW5lciwgZXhpc3RpbmddIDogW2V4aXN0aW5nLCBsaXN0ZW5lcl07XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIElmIHdlJ3ZlIGFscmVhZHkgZ290IGFuIGFycmF5LCBqdXN0IGFwcGVuZC5cbiAgICAgIGlmIChwcmVwZW5kKSB7XG4gICAgICAgIGV4aXN0aW5nLnVuc2hpZnQobGlzdGVuZXIpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZXhpc3RpbmcucHVzaChsaXN0ZW5lcik7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gQ2hlY2sgZm9yIGxpc3RlbmVyIGxlYWtcbiAgICBpZiAoIWV4aXN0aW5nLndhcm5lZCkge1xuICAgICAgbSA9ICRnZXRNYXhMaXN0ZW5lcnModGFyZ2V0KTtcbiAgICAgIGlmIChtICYmIG0gPiAwICYmIGV4aXN0aW5nLmxlbmd0aCA+IG0pIHtcbiAgICAgICAgZXhpc3Rpbmcud2FybmVkID0gdHJ1ZTtcbiAgICAgICAgdmFyIHcgPSBuZXcgRXJyb3IoJ1Bvc3NpYmxlIEV2ZW50RW1pdHRlciBtZW1vcnkgbGVhayBkZXRlY3RlZC4gJyArXG4gICAgICAgICAgICBleGlzdGluZy5sZW5ndGggKyAnIFwiJyArIFN0cmluZyh0eXBlKSArICdcIiBsaXN0ZW5lcnMgJyArXG4gICAgICAgICAgICAnYWRkZWQuIFVzZSBlbWl0dGVyLnNldE1heExpc3RlbmVycygpIHRvICcgK1xuICAgICAgICAgICAgJ2luY3JlYXNlIGxpbWl0LicpO1xuICAgICAgICB3Lm5hbWUgPSAnTWF4TGlzdGVuZXJzRXhjZWVkZWRXYXJuaW5nJztcbiAgICAgICAgdy5lbWl0dGVyID0gdGFyZ2V0O1xuICAgICAgICB3LnR5cGUgPSB0eXBlO1xuICAgICAgICB3LmNvdW50ID0gZXhpc3RpbmcubGVuZ3RoO1xuICAgICAgICBpZiAodHlwZW9mIGNvbnNvbGUgPT09ICdvYmplY3QnICYmIGNvbnNvbGUud2Fybikge1xuICAgICAgICAgIGNvbnNvbGUud2FybignJXM6ICVzJywgdy5uYW1lLCB3Lm1lc3NhZ2UpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHRhcmdldDtcbn1cblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5hZGRMaXN0ZW5lciA9IGZ1bmN0aW9uIGFkZExpc3RlbmVyKHR5cGUsIGxpc3RlbmVyKSB7XG4gIHJldHVybiBfYWRkTGlzdGVuZXIodGhpcywgdHlwZSwgbGlzdGVuZXIsIGZhbHNlKTtcbn07XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUub24gPSBFdmVudEVtaXR0ZXIucHJvdG90eXBlLmFkZExpc3RlbmVyO1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLnByZXBlbmRMaXN0ZW5lciA9XG4gICAgZnVuY3Rpb24gcHJlcGVuZExpc3RlbmVyKHR5cGUsIGxpc3RlbmVyKSB7XG4gICAgICByZXR1cm4gX2FkZExpc3RlbmVyKHRoaXMsIHR5cGUsIGxpc3RlbmVyLCB0cnVlKTtcbiAgICB9O1xuXG5mdW5jdGlvbiBvbmNlV3JhcHBlcigpIHtcbiAgaWYgKCF0aGlzLmZpcmVkKSB7XG4gICAgdGhpcy50YXJnZXQucmVtb3ZlTGlzdGVuZXIodGhpcy50eXBlLCB0aGlzLndyYXBGbik7XG4gICAgdGhpcy5maXJlZCA9IHRydWU7XG4gICAgc3dpdGNoIChhcmd1bWVudHMubGVuZ3RoKSB7XG4gICAgICBjYXNlIDA6XG4gICAgICAgIHJldHVybiB0aGlzLmxpc3RlbmVyLmNhbGwodGhpcy50YXJnZXQpO1xuICAgICAgY2FzZSAxOlxuICAgICAgICByZXR1cm4gdGhpcy5saXN0ZW5lci5jYWxsKHRoaXMudGFyZ2V0LCBhcmd1bWVudHNbMF0pO1xuICAgICAgY2FzZSAyOlxuICAgICAgICByZXR1cm4gdGhpcy5saXN0ZW5lci5jYWxsKHRoaXMudGFyZ2V0LCBhcmd1bWVudHNbMF0sIGFyZ3VtZW50c1sxXSk7XG4gICAgICBjYXNlIDM6XG4gICAgICAgIHJldHVybiB0aGlzLmxpc3RlbmVyLmNhbGwodGhpcy50YXJnZXQsIGFyZ3VtZW50c1swXSwgYXJndW1lbnRzWzFdLFxuICAgICAgICAgICAgYXJndW1lbnRzWzJdKTtcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHZhciBhcmdzID0gbmV3IEFycmF5KGFyZ3VtZW50cy5sZW5ndGgpO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGFyZ3MubGVuZ3RoOyArK2kpXG4gICAgICAgICAgYXJnc1tpXSA9IGFyZ3VtZW50c1tpXTtcbiAgICAgICAgdGhpcy5saXN0ZW5lci5hcHBseSh0aGlzLnRhcmdldCwgYXJncyk7XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIF9vbmNlV3JhcCh0YXJnZXQsIHR5cGUsIGxpc3RlbmVyKSB7XG4gIHZhciBzdGF0ZSA9IHsgZmlyZWQ6IGZhbHNlLCB3cmFwRm46IHVuZGVmaW5lZCwgdGFyZ2V0OiB0YXJnZXQsIHR5cGU6IHR5cGUsIGxpc3RlbmVyOiBsaXN0ZW5lciB9O1xuICB2YXIgd3JhcHBlZCA9IGJpbmQuY2FsbChvbmNlV3JhcHBlciwgc3RhdGUpO1xuICB3cmFwcGVkLmxpc3RlbmVyID0gbGlzdGVuZXI7XG4gIHN0YXRlLndyYXBGbiA9IHdyYXBwZWQ7XG4gIHJldHVybiB3cmFwcGVkO1xufVxuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLm9uY2UgPSBmdW5jdGlvbiBvbmNlKHR5cGUsIGxpc3RlbmVyKSB7XG4gIGlmICh0eXBlb2YgbGlzdGVuZXIgIT09ICdmdW5jdGlvbicpXG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignXCJsaXN0ZW5lclwiIGFyZ3VtZW50IG11c3QgYmUgYSBmdW5jdGlvbicpO1xuICB0aGlzLm9uKHR5cGUsIF9vbmNlV3JhcCh0aGlzLCB0eXBlLCBsaXN0ZW5lcikpO1xuICByZXR1cm4gdGhpcztcbn07XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUucHJlcGVuZE9uY2VMaXN0ZW5lciA9XG4gICAgZnVuY3Rpb24gcHJlcGVuZE9uY2VMaXN0ZW5lcih0eXBlLCBsaXN0ZW5lcikge1xuICAgICAgaWYgKHR5cGVvZiBsaXN0ZW5lciAhPT0gJ2Z1bmN0aW9uJylcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignXCJsaXN0ZW5lclwiIGFyZ3VtZW50IG11c3QgYmUgYSBmdW5jdGlvbicpO1xuICAgICAgdGhpcy5wcmVwZW5kTGlzdGVuZXIodHlwZSwgX29uY2VXcmFwKHRoaXMsIHR5cGUsIGxpc3RlbmVyKSk7XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG4vLyBFbWl0cyBhICdyZW1vdmVMaXN0ZW5lcicgZXZlbnQgaWYgYW5kIG9ubHkgaWYgdGhlIGxpc3RlbmVyIHdhcyByZW1vdmVkLlxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5yZW1vdmVMaXN0ZW5lciA9XG4gICAgZnVuY3Rpb24gcmVtb3ZlTGlzdGVuZXIodHlwZSwgbGlzdGVuZXIpIHtcbiAgICAgIHZhciBsaXN0LCBldmVudHMsIHBvc2l0aW9uLCBpLCBvcmlnaW5hbExpc3RlbmVyO1xuXG4gICAgICBpZiAodHlwZW9mIGxpc3RlbmVyICE9PSAnZnVuY3Rpb24nKVxuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdcImxpc3RlbmVyXCIgYXJndW1lbnQgbXVzdCBiZSBhIGZ1bmN0aW9uJyk7XG5cbiAgICAgIGV2ZW50cyA9IHRoaXMuX2V2ZW50cztcbiAgICAgIGlmICghZXZlbnRzKVxuICAgICAgICByZXR1cm4gdGhpcztcblxuICAgICAgbGlzdCA9IGV2ZW50c1t0eXBlXTtcbiAgICAgIGlmICghbGlzdClcbiAgICAgICAgcmV0dXJuIHRoaXM7XG5cbiAgICAgIGlmIChsaXN0ID09PSBsaXN0ZW5lciB8fCBsaXN0Lmxpc3RlbmVyID09PSBsaXN0ZW5lcikge1xuICAgICAgICBpZiAoLS10aGlzLl9ldmVudHNDb3VudCA9PT0gMClcbiAgICAgICAgICB0aGlzLl9ldmVudHMgPSBvYmplY3RDcmVhdGUobnVsbCk7XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgIGRlbGV0ZSBldmVudHNbdHlwZV07XG4gICAgICAgICAgaWYgKGV2ZW50cy5yZW1vdmVMaXN0ZW5lcilcbiAgICAgICAgICAgIHRoaXMuZW1pdCgncmVtb3ZlTGlzdGVuZXInLCB0eXBlLCBsaXN0Lmxpc3RlbmVyIHx8IGxpc3RlbmVyKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmICh0eXBlb2YgbGlzdCAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICBwb3NpdGlvbiA9IC0xO1xuXG4gICAgICAgIGZvciAoaSA9IGxpc3QubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgICAgICBpZiAobGlzdFtpXSA9PT0gbGlzdGVuZXIgfHwgbGlzdFtpXS5saXN0ZW5lciA9PT0gbGlzdGVuZXIpIHtcbiAgICAgICAgICAgIG9yaWdpbmFsTGlzdGVuZXIgPSBsaXN0W2ldLmxpc3RlbmVyO1xuICAgICAgICAgICAgcG9zaXRpb24gPSBpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHBvc2l0aW9uIDwgMClcbiAgICAgICAgICByZXR1cm4gdGhpcztcblxuICAgICAgICBpZiAocG9zaXRpb24gPT09IDApXG4gICAgICAgICAgbGlzdC5zaGlmdCgpO1xuICAgICAgICBlbHNlXG4gICAgICAgICAgc3BsaWNlT25lKGxpc3QsIHBvc2l0aW9uKTtcblxuICAgICAgICBpZiAobGlzdC5sZW5ndGggPT09IDEpXG4gICAgICAgICAgZXZlbnRzW3R5cGVdID0gbGlzdFswXTtcblxuICAgICAgICBpZiAoZXZlbnRzLnJlbW92ZUxpc3RlbmVyKVxuICAgICAgICAgIHRoaXMuZW1pdCgncmVtb3ZlTGlzdGVuZXInLCB0eXBlLCBvcmlnaW5hbExpc3RlbmVyIHx8IGxpc3RlbmVyKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5yZW1vdmVBbGxMaXN0ZW5lcnMgPVxuICAgIGZ1bmN0aW9uIHJlbW92ZUFsbExpc3RlbmVycyh0eXBlKSB7XG4gICAgICB2YXIgbGlzdGVuZXJzLCBldmVudHMsIGk7XG5cbiAgICAgIGV2ZW50cyA9IHRoaXMuX2V2ZW50cztcbiAgICAgIGlmICghZXZlbnRzKVxuICAgICAgICByZXR1cm4gdGhpcztcblxuICAgICAgLy8gbm90IGxpc3RlbmluZyBmb3IgcmVtb3ZlTGlzdGVuZXIsIG5vIG5lZWQgdG8gZW1pdFxuICAgICAgaWYgKCFldmVudHMucmVtb3ZlTGlzdGVuZXIpIHtcbiAgICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICB0aGlzLl9ldmVudHMgPSBvYmplY3RDcmVhdGUobnVsbCk7XG4gICAgICAgICAgdGhpcy5fZXZlbnRzQ291bnQgPSAwO1xuICAgICAgICB9IGVsc2UgaWYgKGV2ZW50c1t0eXBlXSkge1xuICAgICAgICAgIGlmICgtLXRoaXMuX2V2ZW50c0NvdW50ID09PSAwKVxuICAgICAgICAgICAgdGhpcy5fZXZlbnRzID0gb2JqZWN0Q3JlYXRlKG51bGwpO1xuICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgIGRlbGV0ZSBldmVudHNbdHlwZV07XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICB9XG5cbiAgICAgIC8vIGVtaXQgcmVtb3ZlTGlzdGVuZXIgZm9yIGFsbCBsaXN0ZW5lcnMgb24gYWxsIGV2ZW50c1xuICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgdmFyIGtleXMgPSBvYmplY3RLZXlzKGV2ZW50cyk7XG4gICAgICAgIHZhciBrZXk7XG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCBrZXlzLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAga2V5ID0ga2V5c1tpXTtcbiAgICAgICAgICBpZiAoa2V5ID09PSAncmVtb3ZlTGlzdGVuZXInKSBjb250aW51ZTtcbiAgICAgICAgICB0aGlzLnJlbW92ZUFsbExpc3RlbmVycyhrZXkpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMucmVtb3ZlQWxsTGlzdGVuZXJzKCdyZW1vdmVMaXN0ZW5lcicpO1xuICAgICAgICB0aGlzLl9ldmVudHMgPSBvYmplY3RDcmVhdGUobnVsbCk7XG4gICAgICAgIHRoaXMuX2V2ZW50c0NvdW50ID0gMDtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICB9XG5cbiAgICAgIGxpc3RlbmVycyA9IGV2ZW50c1t0eXBlXTtcblxuICAgICAgaWYgKHR5cGVvZiBsaXN0ZW5lcnMgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgdGhpcy5yZW1vdmVMaXN0ZW5lcih0eXBlLCBsaXN0ZW5lcnMpO1xuICAgICAgfSBlbHNlIGlmIChsaXN0ZW5lcnMpIHtcbiAgICAgICAgLy8gTElGTyBvcmRlclxuICAgICAgICBmb3IgKGkgPSBsaXN0ZW5lcnMubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgICAgICB0aGlzLnJlbW92ZUxpc3RlbmVyKHR5cGUsIGxpc3RlbmVyc1tpXSk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuZnVuY3Rpb24gX2xpc3RlbmVycyh0YXJnZXQsIHR5cGUsIHVud3JhcCkge1xuICB2YXIgZXZlbnRzID0gdGFyZ2V0Ll9ldmVudHM7XG5cbiAgaWYgKCFldmVudHMpXG4gICAgcmV0dXJuIFtdO1xuXG4gIHZhciBldmxpc3RlbmVyID0gZXZlbnRzW3R5cGVdO1xuICBpZiAoIWV2bGlzdGVuZXIpXG4gICAgcmV0dXJuIFtdO1xuXG4gIGlmICh0eXBlb2YgZXZsaXN0ZW5lciA9PT0gJ2Z1bmN0aW9uJylcbiAgICByZXR1cm4gdW53cmFwID8gW2V2bGlzdGVuZXIubGlzdGVuZXIgfHwgZXZsaXN0ZW5lcl0gOiBbZXZsaXN0ZW5lcl07XG5cbiAgcmV0dXJuIHVud3JhcCA/IHVud3JhcExpc3RlbmVycyhldmxpc3RlbmVyKSA6IGFycmF5Q2xvbmUoZXZsaXN0ZW5lciwgZXZsaXN0ZW5lci5sZW5ndGgpO1xufVxuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLmxpc3RlbmVycyA9IGZ1bmN0aW9uIGxpc3RlbmVycyh0eXBlKSB7XG4gIHJldHVybiBfbGlzdGVuZXJzKHRoaXMsIHR5cGUsIHRydWUpO1xufTtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5yYXdMaXN0ZW5lcnMgPSBmdW5jdGlvbiByYXdMaXN0ZW5lcnModHlwZSkge1xuICByZXR1cm4gX2xpc3RlbmVycyh0aGlzLCB0eXBlLCBmYWxzZSk7XG59O1xuXG5FdmVudEVtaXR0ZXIubGlzdGVuZXJDb3VudCA9IGZ1bmN0aW9uKGVtaXR0ZXIsIHR5cGUpIHtcbiAgaWYgKHR5cGVvZiBlbWl0dGVyLmxpc3RlbmVyQ291bnQgPT09ICdmdW5jdGlvbicpIHtcbiAgICByZXR1cm4gZW1pdHRlci5saXN0ZW5lckNvdW50KHR5cGUpO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBsaXN0ZW5lckNvdW50LmNhbGwoZW1pdHRlciwgdHlwZSk7XG4gIH1cbn07XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUubGlzdGVuZXJDb3VudCA9IGxpc3RlbmVyQ291bnQ7XG5mdW5jdGlvbiBsaXN0ZW5lckNvdW50KHR5cGUpIHtcbiAgdmFyIGV2ZW50cyA9IHRoaXMuX2V2ZW50cztcblxuICBpZiAoZXZlbnRzKSB7XG4gICAgdmFyIGV2bGlzdGVuZXIgPSBldmVudHNbdHlwZV07XG5cbiAgICBpZiAodHlwZW9mIGV2bGlzdGVuZXIgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHJldHVybiAxO1xuICAgIH0gZWxzZSBpZiAoZXZsaXN0ZW5lcikge1xuICAgICAgcmV0dXJuIGV2bGlzdGVuZXIubGVuZ3RoO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiAwO1xufVxuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLmV2ZW50TmFtZXMgPSBmdW5jdGlvbiBldmVudE5hbWVzKCkge1xuICByZXR1cm4gdGhpcy5fZXZlbnRzQ291bnQgPiAwID8gUmVmbGVjdC5vd25LZXlzKHRoaXMuX2V2ZW50cykgOiBbXTtcbn07XG5cbi8vIEFib3V0IDEuNXggZmFzdGVyIHRoYW4gdGhlIHR3by1hcmcgdmVyc2lvbiBvZiBBcnJheSNzcGxpY2UoKS5cbmZ1bmN0aW9uIHNwbGljZU9uZShsaXN0LCBpbmRleCkge1xuICBmb3IgKHZhciBpID0gaW5kZXgsIGsgPSBpICsgMSwgbiA9IGxpc3QubGVuZ3RoOyBrIDwgbjsgaSArPSAxLCBrICs9IDEpXG4gICAgbGlzdFtpXSA9IGxpc3Rba107XG4gIGxpc3QucG9wKCk7XG59XG5cbmZ1bmN0aW9uIGFycmF5Q2xvbmUoYXJyLCBuKSB7XG4gIHZhciBjb3B5ID0gbmV3IEFycmF5KG4pO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IG47ICsraSlcbiAgICBjb3B5W2ldID0gYXJyW2ldO1xuICByZXR1cm4gY29weTtcbn1cblxuZnVuY3Rpb24gdW53cmFwTGlzdGVuZXJzKGFycikge1xuICB2YXIgcmV0ID0gbmV3IEFycmF5KGFyci5sZW5ndGgpO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IHJldC5sZW5ndGg7ICsraSkge1xuICAgIHJldFtpXSA9IGFycltpXS5saXN0ZW5lciB8fCBhcnJbaV07XG4gIH1cbiAgcmV0dXJuIHJldDtcbn1cblxuZnVuY3Rpb24gb2JqZWN0Q3JlYXRlUG9seWZpbGwocHJvdG8pIHtcbiAgdmFyIEYgPSBmdW5jdGlvbigpIHt9O1xuICBGLnByb3RvdHlwZSA9IHByb3RvO1xuICByZXR1cm4gbmV3IEY7XG59XG5mdW5jdGlvbiBvYmplY3RLZXlzUG9seWZpbGwob2JqKSB7XG4gIHZhciBrZXlzID0gW107XG4gIGZvciAodmFyIGsgaW4gb2JqKSBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9iaiwgaykpIHtcbiAgICBrZXlzLnB1c2goayk7XG4gIH1cbiAgcmV0dXJuIGs7XG59XG5mdW5jdGlvbiBmdW5jdGlvbkJpbmRQb2x5ZmlsbChjb250ZXh0KSB7XG4gIHZhciBmbiA9IHRoaXM7XG4gIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIGZuLmFwcGx5KGNvbnRleHQsIGFyZ3VtZW50cyk7XG4gIH07XG59XG4iLCJcInVzZSBzdHJpY3RcIjtcblxudmFyIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQgPSByZXF1aXJlKFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9pbnRlcm9wUmVxdWlyZURlZmF1bHRcIik7XG5cbnZhciBfaW50ZXJvcFJlcXVpcmVXaWxkY2FyZCA9IHJlcXVpcmUoXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2ludGVyb3BSZXF1aXJlV2lsZGNhcmRcIik7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwge1xuICB2YWx1ZTogdHJ1ZVxufSk7XG5leHBvcnRzLmRlZmF1bHQgPSBleHBvcnRzLlNVUFBPUlRFRF9QUk9UT0NPTF9WRVJTSU9OID0gdm9pZCAwO1xuXG52YXIgX3JlZ2VuZXJhdG9yID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChyZXF1aXJlKFwiQGJhYmVsL3J1bnRpbWUvcmVnZW5lcmF0b3JcIikpO1xuXG52YXIgX2FzeW5jVG9HZW5lcmF0b3IyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChyZXF1aXJlKFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9hc3luY1RvR2VuZXJhdG9yXCIpKTtcblxudmFyIF9vYmplY3RTcHJlYWQyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChyZXF1aXJlKFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9vYmplY3RTcHJlYWRcIikpO1xuXG52YXIgX2NsYXNzQ2FsbENoZWNrMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQocmVxdWlyZShcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvY2xhc3NDYWxsQ2hlY2tcIikpO1xuXG52YXIgX2NyZWF0ZUNsYXNzMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQocmVxdWlyZShcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvY3JlYXRlQ2xhc3NcIikpO1xuXG52YXIgX2FwcGx5RGVjb3JhdGVkRGVzY3JpcHRvcjIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KHJlcXVpcmUoXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2FwcGx5RGVjb3JhdGVkRGVzY3JpcHRvclwiKSk7XG5cbnZhciBfdXRpbHMgPSByZXF1aXJlKFwiLi91dGlsc1wiKTtcblxudmFyIF9odHRwID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChyZXF1aXJlKFwiLi9odHRwXCIpKTtcblxudmFyIF9lbmRwb2ludCA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQocmVxdWlyZShcIi4vZW5kcG9pbnRcIikpO1xuXG52YXIgcmVxdWVzdHMgPSBfaW50ZXJvcFJlcXVpcmVXaWxkY2FyZChyZXF1aXJlKFwiLi9yZXF1ZXN0c1wiKSk7XG5cbnZhciBfYmF0Y2gyID0gcmVxdWlyZShcIi4vYmF0Y2hcIik7XG5cbnZhciBfYnVja2V0ID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChyZXF1aXJlKFwiLi9idWNrZXRcIikpO1xuXG52YXIgX2RlYywgX2RlYzIsIF9kZWMzLCBfZGVjNCwgX2RlYzUsIF9kZWM2LCBfZGVjNywgX2NsYXNzO1xuXG4vKipcbiAqIEN1cnJlbnRseSBzdXBwb3J0ZWQgcHJvdG9jb2wgdmVyc2lvbi5cbiAqIEB0eXBlIHtTdHJpbmd9XG4gKi9cbnZhciBTVVBQT1JURURfUFJPVE9DT0xfVkVSU0lPTiA9IFwidjFcIjtcbi8qKlxuICogSGlnaCBsZXZlbCBIVFRQIGNsaWVudCBmb3IgdGhlIEtpbnRvIEFQSS5cbiAqXG4gKiBAZXhhbXBsZVxuICogY29uc3QgY2xpZW50ID0gbmV3IEtpbnRvQ2xpZW50KFwiaHR0cHM6Ly9raW50by5kZXYubW96YXdzLm5ldC92MVwiKTtcbiAqIGNsaWVudC5idWNrZXQoXCJkZWZhdWx0XCIpXG4gKiAgICAuY29sbGVjdGlvbihcIm15LWJsb2dcIilcbiAqICAgIC5jcmVhdGVSZWNvcmQoe3RpdGxlOiBcIkZpcnN0IGFydGljbGVcIn0pXG4gKiAgIC50aGVuKGNvbnNvbGUubG9nLmJpbmQoY29uc29sZSkpXG4gKiAgIC5jYXRjaChjb25zb2xlLmVycm9yLmJpbmQoY29uc29sZSkpO1xuICovXG5cbmV4cG9ydHMuU1VQUE9SVEVEX1BST1RPQ09MX1ZFUlNJT04gPSBTVVBQT1JURURfUFJPVE9DT0xfVkVSU0lPTjtcbnZhciBLaW50b0NsaWVudEJhc2UgPSAoX2RlYyA9ICgwLCBfdXRpbHMubm9iYXRjaCkoXCJUaGlzIG9wZXJhdGlvbiBpcyBub3Qgc3VwcG9ydGVkIHdpdGhpbiBhIGJhdGNoIG9wZXJhdGlvbi5cIiksIF9kZWMyID0gKDAsIF91dGlscy5ub2JhdGNoKShcIlRoaXMgb3BlcmF0aW9uIGlzIG5vdCBzdXBwb3J0ZWQgd2l0aGluIGEgYmF0Y2ggb3BlcmF0aW9uLlwiKSwgX2RlYzMgPSAoMCwgX3V0aWxzLm5vYmF0Y2gpKFwiVGhpcyBvcGVyYXRpb24gaXMgbm90IHN1cHBvcnRlZCB3aXRoaW4gYSBiYXRjaCBvcGVyYXRpb24uXCIpLCBfZGVjNCA9ICgwLCBfdXRpbHMubm9iYXRjaCkoXCJUaGlzIG9wZXJhdGlvbiBpcyBub3Qgc3VwcG9ydGVkIHdpdGhpbiBhIGJhdGNoIG9wZXJhdGlvbi5cIiksIF9kZWM1ID0gKDAsIF91dGlscy5ub2JhdGNoKShcIkNhbid0IHVzZSBiYXRjaCB3aXRoaW4gYSBiYXRjaCFcIiksIF9kZWM2ID0gKDAsIF91dGlscy5jYXBhYmxlKShbXCJwZXJtaXNzaW9uc19lbmRwb2ludFwiXSksIF9kZWM3ID0gKDAsIF91dGlscy5zdXBwb3J0KShcIjEuNFwiLCBcIjIuMFwiKSwgKF9jbGFzcyA9XG4vKiNfX1BVUkVfXyovXG5mdW5jdGlvbiAoKSB7XG4gIC8qKlxuICAgKiBDb25zdHJ1Y3Rvci5cbiAgICpcbiAgICogQHBhcmFtICB7U3RyaW5nfSAgICAgICByZW1vdGUgIFRoZSByZW1vdGUgVVJMLlxuICAgKiBAcGFyYW0gIHtPYmplY3R9ICAgICAgIFtvcHRpb25zPXt9XSAgICAgICAgICAgICAgICAgIFRoZSBvcHRpb25zIG9iamVjdC5cbiAgICogQHBhcmFtICB7Qm9vbGVhbn0gICAgICBbb3B0aW9ucy5zYWZlPXRydWVdICAgICAgICAgICBBZGRzIGNvbmN1cnJlbmN5IGhlYWRlcnMgdG8gZXZlcnkgcmVxdWVzdHMuXG4gICAqIEBwYXJhbSAge0V2ZW50RW1pdHRlcn0gW29wdGlvbnMuZXZlbnRzPUV2ZW50RW1pdHRlcl0gVGhlIGV2ZW50cyBoYW5kbGVyIGluc3RhbmNlLlxuICAgKiBAcGFyYW0gIHtPYmplY3R9ICAgICAgIFtvcHRpb25zLmhlYWRlcnM9e31dICAgICAgICAgIFRoZSBrZXktdmFsdWUgaGVhZGVycyB0byBwYXNzIHRvIGVhY2ggcmVxdWVzdC5cbiAgICogQHBhcmFtICB7T2JqZWN0fSAgICAgICBbb3B0aW9ucy5yZXRyeT0wXSAgICAgICAgICAgICBOdW1iZXIgb2YgcmV0cmllcyB3aGVuIHJlcXVlc3QgZmFpbHMgKGRlZmF1bHQ6IDApXG4gICAqIEBwYXJhbSAge1N0cmluZ30gICAgICAgW29wdGlvbnMuYnVja2V0PVwiZGVmYXVsdFwiXSAgICBUaGUgZGVmYXVsdCBidWNrZXQgdG8gdXNlLlxuICAgKiBAcGFyYW0gIHtTdHJpbmd9ICAgICAgIFtvcHRpb25zLnJlcXVlc3RNb2RlPVwiY29yc1wiXSAgVGhlIEhUVFAgcmVxdWVzdCBtb2RlIChmcm9tIEVTNiBmZXRjaCBzcGVjKS5cbiAgICogQHBhcmFtICB7TnVtYmVyfSAgICAgICBbb3B0aW9ucy50aW1lb3V0PW51bGxdICAgICAgICBUaGUgcmVxdWVzdCB0aW1lb3V0IGluIG1zLCBpZiBhbnkuXG4gICAqL1xuICBmdW5jdGlvbiBLaW50b0NsaWVudEJhc2UocmVtb3RlKSB7XG4gICAgdmFyIG9wdGlvbnMgPSBhcmd1bWVudHMubGVuZ3RoID4gMSAmJiBhcmd1bWVudHNbMV0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1sxXSA6IHt9O1xuICAgICgwLCBfY2xhc3NDYWxsQ2hlY2syLmRlZmF1bHQpKHRoaXMsIEtpbnRvQ2xpZW50QmFzZSk7XG5cbiAgICBpZiAodHlwZW9mIHJlbW90ZSAhPT0gXCJzdHJpbmdcIiB8fCAhcmVtb3RlLmxlbmd0aCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiSW52YWxpZCByZW1vdGUgVVJMOiBcIiArIHJlbW90ZSk7XG4gICAgfVxuXG4gICAgaWYgKHJlbW90ZVtyZW1vdGUubGVuZ3RoIC0gMV0gPT09IFwiL1wiKSB7XG4gICAgICByZW1vdGUgPSByZW1vdGUuc2xpY2UoMCwgLTEpO1xuICAgIH1cblxuICAgIHRoaXMuX2JhY2tvZmZSZWxlYXNlVGltZSA9IG51bGw7XG4gICAgdGhpcy5fcmVxdWVzdHMgPSBbXTtcbiAgICB0aGlzLl9pc0JhdGNoID0gISFvcHRpb25zLmJhdGNoO1xuICAgIHRoaXMuX3JldHJ5ID0gb3B0aW9ucy5yZXRyeSB8fCAwO1xuICAgIHRoaXMuX3NhZmUgPSAhIW9wdGlvbnMuc2FmZTtcbiAgICB0aGlzLl9oZWFkZXJzID0gb3B0aW9ucy5oZWFkZXJzIHx8IHt9OyAvLyBwdWJsaWMgcHJvcGVydGllc1xuXG4gICAgLyoqXG4gICAgICogVGhlIHJlbW90ZSBzZXJ2ZXIgYmFzZSBVUkwuXG4gICAgICogQHR5cGUge1N0cmluZ31cbiAgICAgKi9cblxuICAgIHRoaXMucmVtb3RlID0gcmVtb3RlO1xuICAgIC8qKlxuICAgICAqIEN1cnJlbnQgc2VydmVyIGluZm9ybWF0aW9uLlxuICAgICAqIEBpZ25vcmVcbiAgICAgKiBAdHlwZSB7T2JqZWN0fG51bGx9XG4gICAgICovXG5cbiAgICB0aGlzLnNlcnZlckluZm8gPSBudWxsO1xuICAgIC8qKlxuICAgICAqIFRoZSBldmVudCBlbWl0dGVyIGluc3RhbmNlLiBTaG91bGQgY29tcGx5IHdpdGggdGhlIGBFdmVudEVtaXR0ZXJgXG4gICAgICogaW50ZXJmYWNlLlxuICAgICAqIEBpZ25vcmVcbiAgICAgKiBAdHlwZSB7Q2xhc3N9XG4gICAgICovXG5cbiAgICB0aGlzLmV2ZW50cyA9IG9wdGlvbnMuZXZlbnRzO1xuICAgIHZhciByZXF1ZXN0TW9kZSA9IG9wdGlvbnMucmVxdWVzdE1vZGUsXG4gICAgICAgIHRpbWVvdXQgPSBvcHRpb25zLnRpbWVvdXQ7XG4gICAgLyoqXG4gICAgICogVGhlIEhUVFAgaW5zdGFuY2UuXG4gICAgICogQGlnbm9yZVxuICAgICAqIEB0eXBlIHtIVFRQfVxuICAgICAqL1xuXG4gICAgdGhpcy5odHRwID0gbmV3IF9odHRwLmRlZmF1bHQodGhpcy5ldmVudHMsIHtcbiAgICAgIHJlcXVlc3RNb2RlOiByZXF1ZXN0TW9kZSxcbiAgICAgIHRpbWVvdXQ6IHRpbWVvdXRcbiAgICB9KTtcblxuICAgIHRoaXMuX3JlZ2lzdGVySFRUUEV2ZW50cygpO1xuICB9XG4gIC8qKlxuICAgKiBUaGUgcmVtb3RlIGVuZHBvaW50IGJhc2UgVVJMLiBTZXR0aW5nIHRoZSB2YWx1ZSB3aWxsIGFsc28gZXh0cmFjdCBhbmRcbiAgICogdmFsaWRhdGUgdGhlIHZlcnNpb24uXG4gICAqIEB0eXBlIHtTdHJpbmd9XG4gICAqL1xuXG5cbiAgKDAsIF9jcmVhdGVDbGFzczIuZGVmYXVsdCkoS2ludG9DbGllbnRCYXNlLCBbe1xuICAgIGtleTogXCJfcmVnaXN0ZXJIVFRQRXZlbnRzXCIsXG5cbiAgICAvKipcbiAgICAgKiBSZWdpc3RlcnMgSFRUUCBldmVudHMuXG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cbiAgICB2YWx1ZTogZnVuY3Rpb24gX3JlZ2lzdGVySFRUUEV2ZW50cygpIHtcbiAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG5cbiAgICAgIC8vIFByZXZlbnQgcmVnaXN0ZXJpbmcgZXZlbnQgZnJvbSBhIGJhdGNoIGNsaWVudCBpbnN0YW5jZVxuICAgICAgaWYgKCF0aGlzLl9pc0JhdGNoKSB7XG4gICAgICAgIHRoaXMuZXZlbnRzLm9uKFwiYmFja29mZlwiLCBmdW5jdGlvbiAoYmFja29mZk1zKSB7XG4gICAgICAgICAgX3RoaXMuX2JhY2tvZmZSZWxlYXNlVGltZSA9IGJhY2tvZmZNcztcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHJpZXZlIGEgYnVja2V0IG9iamVjdCB0byBwZXJmb3JtIG9wZXJhdGlvbnMgb24gaXQuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gIHtTdHJpbmd9ICBuYW1lICAgICAgICAgICAgICBUaGUgYnVja2V0IG5hbWUuXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSAgW29wdGlvbnM9e31dICAgICAgVGhlIHJlcXVlc3Qgb3B0aW9ucy5cbiAgICAgKiBAcGFyYW0gIHtCb29sZWFufSBbb3B0aW9ucy5zYWZlXSAgICBUaGUgcmVzdWx0aW5nIHNhZmUgb3B0aW9uLlxuICAgICAqIEBwYXJhbSAge051bWJlcn0gIFtvcHRpb25zLnJldHJ5XSAgIFRoZSByZXN1bHRpbmcgcmV0cnkgb3B0aW9uLlxuICAgICAqIEBwYXJhbSAge09iamVjdH0gIFtvcHRpb25zLmhlYWRlcnNdIFRoZSBleHRlbmRlZCBoZWFkZXJzIG9iamVjdCBvcHRpb24uXG4gICAgICogQHJldHVybiB7QnVja2V0fVxuICAgICAqL1xuXG4gIH0sIHtcbiAgICBrZXk6IFwiYnVja2V0XCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIGJ1Y2tldChuYW1lKSB7XG4gICAgICB2YXIgb3B0aW9ucyA9IGFyZ3VtZW50cy5sZW5ndGggPiAxICYmIGFyZ3VtZW50c1sxXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzFdIDoge307XG4gICAgICByZXR1cm4gbmV3IF9idWNrZXQuZGVmYXVsdCh0aGlzLCBuYW1lLCB7XG4gICAgICAgIGJhdGNoOiB0aGlzLl9pc0JhdGNoLFxuICAgICAgICBoZWFkZXJzOiB0aGlzLl9nZXRIZWFkZXJzKG9wdGlvbnMpLFxuICAgICAgICBzYWZlOiB0aGlzLl9nZXRTYWZlKG9wdGlvbnMpLFxuICAgICAgICByZXRyeTogdGhpcy5fZ2V0UmV0cnkob3B0aW9ucylcbiAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTZXQgY2xpZW50IFwiaGVhZGVyc1wiIGZvciBldmVyeSByZXF1ZXN0LCB1cGRhdGluZyBwcmV2aW91cyBoZWFkZXJzIChpZiBhbnkpLlxuICAgICAqXG4gICAgICogQHBhcmFtIHtPYmplY3R9IGhlYWRlcnMgVGhlIGhlYWRlcnMgdG8gbWVyZ2Ugd2l0aCBleGlzdGluZyBvbmVzLlxuICAgICAqL1xuXG4gIH0sIHtcbiAgICBrZXk6IFwic2V0SGVhZGVyc1wiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBzZXRIZWFkZXJzKGhlYWRlcnMpIHtcbiAgICAgIHRoaXMuX2hlYWRlcnMgPSAoMCwgX29iamVjdFNwcmVhZDIuZGVmYXVsdCkoe30sIHRoaXMuX2hlYWRlcnMsIGhlYWRlcnMpO1xuICAgICAgdGhpcy5zZXJ2ZXJJbmZvID0gbnVsbDtcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IHRoZSB2YWx1ZSBvZiBcImhlYWRlcnNcIiBmb3IgYSBnaXZlbiByZXF1ZXN0LCBtZXJnaW5nIHRoZVxuICAgICAqIHBlci1yZXF1ZXN0IGhlYWRlcnMgd2l0aCBvdXIgb3duIFwiZGVmYXVsdFwiIGhlYWRlcnMuXG4gICAgICpcbiAgICAgKiBOb3RlIHRoYXQgdW5saWtlIG90aGVyIG9wdGlvbnMsIGhlYWRlcnMgYXJlbid0IG92ZXJyaWRkZW4sIGJ1dFxuICAgICAqIG1lcmdlZCBpbnN0ZWFkLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb3B0aW9ucyBUaGUgb3B0aW9ucyBmb3IgYSByZXF1ZXN0LlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9XG4gICAgICovXG5cbiAgfSwge1xuICAgIGtleTogXCJfZ2V0SGVhZGVyc1wiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBfZ2V0SGVhZGVycyhvcHRpb25zKSB7XG4gICAgICByZXR1cm4gKDAsIF9vYmplY3RTcHJlYWQyLmRlZmF1bHQpKHt9LCB0aGlzLl9oZWFkZXJzLCBvcHRpb25zLmhlYWRlcnMpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIHZhbHVlIG9mIFwic2FmZVwiIGZvciBhIGdpdmVuIHJlcXVlc3QsIHVzaW5nIHRoZVxuICAgICAqIHBlci1yZXF1ZXN0IG9wdGlvbiBpZiBwcmVzZW50IG9yIGZhbGxpbmcgYmFjayB0byBvdXIgZGVmYXVsdFxuICAgICAqIG90aGVyd2lzZS5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnMgVGhlIG9wdGlvbnMgZm9yIGEgcmVxdWVzdC5cbiAgICAgKiBAcmV0dXJucyB7Qm9vbGVhbn1cbiAgICAgKi9cblxuICB9LCB7XG4gICAga2V5OiBcIl9nZXRTYWZlXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIF9nZXRTYWZlKG9wdGlvbnMpIHtcbiAgICAgIHJldHVybiAoMCwgX29iamVjdFNwcmVhZDIuZGVmYXVsdCkoe1xuICAgICAgICBzYWZlOiB0aGlzLl9zYWZlXG4gICAgICB9LCBvcHRpb25zKS5zYWZlO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBBcyBfZ2V0U2FmZSwgYnV0IGZvciBcInJldHJ5XCIuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuXG4gIH0sIHtcbiAgICBrZXk6IFwiX2dldFJldHJ5XCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIF9nZXRSZXRyeShvcHRpb25zKSB7XG4gICAgICByZXR1cm4gKDAsIF9vYmplY3RTcHJlYWQyLmRlZmF1bHQpKHtcbiAgICAgICAgcmV0cnk6IHRoaXMuX3JldHJ5XG4gICAgICB9LCBvcHRpb25zKS5yZXRyeTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmV0cmlldmVzIHRoZSBzZXJ2ZXIncyBcImhlbGxvXCIgZW5kcG9pbnQuIFRoaXMgZW5kcG9pbnQgcmV2ZWFsc1xuICAgICAqIHNlcnZlciBjYXBhYmlsaXRpZXMgYW5kIHNldHRpbmdzIGFzIHdlbGwgYXMgdGVsbGluZyB0aGUgY2xpZW50XG4gICAgICogXCJ3aG8gdGhleSBhcmVcIiBhY2NvcmRpbmcgdG8gdGhlaXIgZ2l2ZW4gYXV0aG9yaXphdGlvbiBoZWFkZXJzLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9ICBbb3B0aW9ucz17fV0gVGhlIHJlcXVlc3Qgb3B0aW9ucy5cbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9ICBbb3B0aW9ucy5oZWFkZXJzPXt9XSBIZWFkZXJzIHRvIHVzZSB3aGVuIG1ha2luZ1xuICAgICAqICAgICB0aGlzIHJlcXVlc3QuXG4gICAgICogQHBhcmFtICB7TnVtYmVyfSAgW29wdGlvbnMucmV0cnk9MF0gICAgTnVtYmVyIG9mIHJldHJpZXMgdG8gbWFrZVxuICAgICAqICAgICB3aGVuIGZhY2VkIHdpdGggdHJhbnNpZW50IGVycm9ycy5cbiAgICAgKiBAcmV0dXJuIHtQcm9taXNlPE9iamVjdCwgRXJyb3I+fVxuICAgICAqL1xuXG4gIH0sIHtcbiAgICBrZXk6IFwiX2dldEhlbGxvXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciBfZ2V0SGVsbG8yID0gKDAsIF9hc3luY1RvR2VuZXJhdG9yMi5kZWZhdWx0KShcbiAgICAgIC8qI19fUFVSRV9fKi9cbiAgICAgIF9yZWdlbmVyYXRvci5kZWZhdWx0Lm1hcmsoZnVuY3Rpb24gX2NhbGxlZSgpIHtcbiAgICAgICAgdmFyIG9wdGlvbnMsXG4gICAgICAgICAgICBwYXRoLFxuICAgICAgICAgICAgX3JlZixcbiAgICAgICAgICAgIGpzb24sXG4gICAgICAgICAgICBfYXJncyA9IGFyZ3VtZW50cztcblxuICAgICAgICByZXR1cm4gX3JlZ2VuZXJhdG9yLmRlZmF1bHQud3JhcChmdW5jdGlvbiBfY2FsbGVlJChfY29udGV4dCkge1xuICAgICAgICAgIHdoaWxlICgxKSB7XG4gICAgICAgICAgICBzd2l0Y2ggKF9jb250ZXh0LnByZXYgPSBfY29udGV4dC5uZXh0KSB7XG4gICAgICAgICAgICAgIGNhc2UgMDpcbiAgICAgICAgICAgICAgICBvcHRpb25zID0gX2FyZ3MubGVuZ3RoID4gMCAmJiBfYXJnc1swXSAhPT0gdW5kZWZpbmVkID8gX2FyZ3NbMF0gOiB7fTtcbiAgICAgICAgICAgICAgICBwYXRoID0gdGhpcy5yZW1vdGUgKyAoMCwgX2VuZHBvaW50LmRlZmF1bHQpKFwicm9vdFwiKTtcbiAgICAgICAgICAgICAgICBfY29udGV4dC5uZXh0ID0gNDtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5odHRwLnJlcXVlc3QocGF0aCwge1xuICAgICAgICAgICAgICAgICAgaGVhZGVyczogdGhpcy5fZ2V0SGVhZGVycyhvcHRpb25zKVxuICAgICAgICAgICAgICAgIH0sIHtcbiAgICAgICAgICAgICAgICAgIHJldHJ5OiB0aGlzLl9nZXRSZXRyeShvcHRpb25zKVxuICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgIGNhc2UgNDpcbiAgICAgICAgICAgICAgICBfcmVmID0gX2NvbnRleHQuc2VudDtcbiAgICAgICAgICAgICAgICBqc29uID0gX3JlZi5qc29uO1xuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dC5hYnJ1cHQoXCJyZXR1cm5cIiwganNvbik7XG5cbiAgICAgICAgICAgICAgY2FzZSA3OlxuICAgICAgICAgICAgICBjYXNlIFwiZW5kXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0LnN0b3AoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0sIF9jYWxsZWUsIHRoaXMpO1xuICAgICAgfSkpO1xuXG4gICAgICByZXR1cm4gZnVuY3Rpb24gX2dldEhlbGxvKCkge1xuICAgICAgICByZXR1cm4gX2dldEhlbGxvMi5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgfTtcbiAgICB9KClcbiAgICAvKipcbiAgICAgKiBSZXRyaWV2ZXMgc2VydmVyIGluZm9ybWF0aW9uIGFuZCBwZXJzaXN0IHRoZW0gbG9jYWxseS4gVGhpcyBvcGVyYXRpb24gaXNcbiAgICAgKiB1c3VhbGx5IHBlcmZvcm1lZCBhIHNpbmdsZSB0aW1lIGR1cmluZyB0aGUgaW5zdGFuY2UgbGlmZWN5Y2xlLlxuICAgICAqXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSAgW29wdGlvbnM9e31dIFRoZSByZXF1ZXN0IG9wdGlvbnMuXG4gICAgICogQHBhcmFtICB7TnVtYmVyfSAgW29wdGlvbnMucmV0cnk9MF0gICAgTnVtYmVyIG9mIHJldHJpZXMgdG8gbWFrZVxuICAgICAqICAgICB3aGVuIGZhY2VkIHdpdGggdHJhbnNpZW50IGVycm9ycy5cbiAgICAgKiBAcmV0dXJuIHtQcm9taXNlPE9iamVjdCwgRXJyb3I+fVxuICAgICAqL1xuXG4gIH0sIHtcbiAgICBrZXk6IFwiZmV0Y2hTZXJ2ZXJJbmZvXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciBfZmV0Y2hTZXJ2ZXJJbmZvID0gKDAsIF9hc3luY1RvR2VuZXJhdG9yMi5kZWZhdWx0KShcbiAgICAgIC8qI19fUFVSRV9fKi9cbiAgICAgIF9yZWdlbmVyYXRvci5kZWZhdWx0Lm1hcmsoZnVuY3Rpb24gX2NhbGxlZTIoKSB7XG4gICAgICAgIHZhciBvcHRpb25zLFxuICAgICAgICAgICAgX2FyZ3MyID0gYXJndW1lbnRzO1xuICAgICAgICByZXR1cm4gX3JlZ2VuZXJhdG9yLmRlZmF1bHQud3JhcChmdW5jdGlvbiBfY2FsbGVlMiQoX2NvbnRleHQyKSB7XG4gICAgICAgICAgd2hpbGUgKDEpIHtcbiAgICAgICAgICAgIHN3aXRjaCAoX2NvbnRleHQyLnByZXYgPSBfY29udGV4dDIubmV4dCkge1xuICAgICAgICAgICAgICBjYXNlIDA6XG4gICAgICAgICAgICAgICAgb3B0aW9ucyA9IF9hcmdzMi5sZW5ndGggPiAwICYmIF9hcmdzMlswXSAhPT0gdW5kZWZpbmVkID8gX2FyZ3MyWzBdIDoge307XG5cbiAgICAgICAgICAgICAgICBpZiAoIXRoaXMuc2VydmVySW5mbykge1xuICAgICAgICAgICAgICAgICAgX2NvbnRleHQyLm5leHQgPSAzO1xuICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0Mi5hYnJ1cHQoXCJyZXR1cm5cIiwgdGhpcy5zZXJ2ZXJJbmZvKTtcblxuICAgICAgICAgICAgICBjYXNlIDM6XG4gICAgICAgICAgICAgICAgX2NvbnRleHQyLm5leHQgPSA1O1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9nZXRIZWxsbyh7XG4gICAgICAgICAgICAgICAgICByZXRyeTogdGhpcy5fZ2V0UmV0cnkob3B0aW9ucylcbiAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICBjYXNlIDU6XG4gICAgICAgICAgICAgICAgdGhpcy5zZXJ2ZXJJbmZvID0gX2NvbnRleHQyLnNlbnQ7XG4gICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0Mi5hYnJ1cHQoXCJyZXR1cm5cIiwgdGhpcy5zZXJ2ZXJJbmZvKTtcblxuICAgICAgICAgICAgICBjYXNlIDc6XG4gICAgICAgICAgICAgIGNhc2UgXCJlbmRcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQyLnN0b3AoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0sIF9jYWxsZWUyLCB0aGlzKTtcbiAgICAgIH0pKTtcblxuICAgICAgcmV0dXJuIGZ1bmN0aW9uIGZldGNoU2VydmVySW5mbygpIHtcbiAgICAgICAgcmV0dXJuIF9mZXRjaFNlcnZlckluZm8uYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgIH07XG4gICAgfSgpXG4gICAgLyoqXG4gICAgICogUmV0cmlldmVzIEtpbnRvIHNlcnZlciBzZXR0aW5ncy5cbiAgICAgKlxuICAgICAqIEBwYXJhbSAge09iamVjdH0gIFtvcHRpb25zPXt9XSBUaGUgcmVxdWVzdCBvcHRpb25zLlxuICAgICAqIEBwYXJhbSAge051bWJlcn0gIFtvcHRpb25zLnJldHJ5PTBdICAgIE51bWJlciBvZiByZXRyaWVzIHRvIG1ha2VcbiAgICAgKiAgICAgd2hlbiBmYWNlZCB3aXRoIHRyYW5zaWVudCBlcnJvcnMuXG4gICAgICogQHJldHVybiB7UHJvbWlzZTxPYmplY3QsIEVycm9yPn1cbiAgICAgKi9cblxuICB9LCB7XG4gICAga2V5OiBcImZldGNoU2VydmVyU2V0dGluZ3NcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gKCkge1xuICAgICAgdmFyIF9mZXRjaFNlcnZlclNldHRpbmdzID0gKDAsIF9hc3luY1RvR2VuZXJhdG9yMi5kZWZhdWx0KShcbiAgICAgIC8qI19fUFVSRV9fKi9cbiAgICAgIF9yZWdlbmVyYXRvci5kZWZhdWx0Lm1hcmsoZnVuY3Rpb24gX2NhbGxlZTMob3B0aW9ucykge1xuICAgICAgICB2YXIgX3JlZjIsIHNldHRpbmdzO1xuXG4gICAgICAgIHJldHVybiBfcmVnZW5lcmF0b3IuZGVmYXVsdC53cmFwKGZ1bmN0aW9uIF9jYWxsZWUzJChfY29udGV4dDMpIHtcbiAgICAgICAgICB3aGlsZSAoMSkge1xuICAgICAgICAgICAgc3dpdGNoIChfY29udGV4dDMucHJldiA9IF9jb250ZXh0My5uZXh0KSB7XG4gICAgICAgICAgICAgIGNhc2UgMDpcbiAgICAgICAgICAgICAgICBfY29udGV4dDMubmV4dCA9IDI7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZmV0Y2hTZXJ2ZXJJbmZvKG9wdGlvbnMpO1xuXG4gICAgICAgICAgICAgIGNhc2UgMjpcbiAgICAgICAgICAgICAgICBfcmVmMiA9IF9jb250ZXh0My5zZW50O1xuICAgICAgICAgICAgICAgIHNldHRpbmdzID0gX3JlZjIuc2V0dGluZ3M7XG4gICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0My5hYnJ1cHQoXCJyZXR1cm5cIiwgc2V0dGluZ3MpO1xuXG4gICAgICAgICAgICAgIGNhc2UgNTpcbiAgICAgICAgICAgICAgY2FzZSBcImVuZFwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDMuc3RvcCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSwgX2NhbGxlZTMsIHRoaXMpO1xuICAgICAgfSkpO1xuXG4gICAgICByZXR1cm4gZnVuY3Rpb24gZmV0Y2hTZXJ2ZXJTZXR0aW5ncyhfeCkge1xuICAgICAgICByZXR1cm4gX2ZldGNoU2VydmVyU2V0dGluZ3MuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgIH07XG4gICAgfSgpXG4gICAgLyoqXG4gICAgICogUmV0cmlldmUgc2VydmVyIGNhcGFiaWxpdGllcyBpbmZvcm1hdGlvbi5cbiAgICAgKlxuICAgICAqIEBwYXJhbSAge09iamVjdH0gIFtvcHRpb25zPXt9XSBUaGUgcmVxdWVzdCBvcHRpb25zLlxuICAgICAqIEBwYXJhbSAge051bWJlcn0gIFtvcHRpb25zLnJldHJ5PTBdICAgIE51bWJlciBvZiByZXRyaWVzIHRvIG1ha2VcbiAgICAgKiAgICAgd2hlbiBmYWNlZCB3aXRoIHRyYW5zaWVudCBlcnJvcnMuXG4gICAgICogQHJldHVybiB7UHJvbWlzZTxPYmplY3QsIEVycm9yPn1cbiAgICAgKi9cblxuICB9LCB7XG4gICAga2V5OiBcImZldGNoU2VydmVyQ2FwYWJpbGl0aWVzXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciBfZmV0Y2hTZXJ2ZXJDYXBhYmlsaXRpZXMgPSAoMCwgX2FzeW5jVG9HZW5lcmF0b3IyLmRlZmF1bHQpKFxuICAgICAgLyojX19QVVJFX18qL1xuICAgICAgX3JlZ2VuZXJhdG9yLmRlZmF1bHQubWFyayhmdW5jdGlvbiBfY2FsbGVlNCgpIHtcbiAgICAgICAgdmFyIG9wdGlvbnMsXG4gICAgICAgICAgICBfcmVmMyxcbiAgICAgICAgICAgIGNhcGFiaWxpdGllcyxcbiAgICAgICAgICAgIF9hcmdzNCA9IGFyZ3VtZW50cztcblxuICAgICAgICByZXR1cm4gX3JlZ2VuZXJhdG9yLmRlZmF1bHQud3JhcChmdW5jdGlvbiBfY2FsbGVlNCQoX2NvbnRleHQ0KSB7XG4gICAgICAgICAgd2hpbGUgKDEpIHtcbiAgICAgICAgICAgIHN3aXRjaCAoX2NvbnRleHQ0LnByZXYgPSBfY29udGV4dDQubmV4dCkge1xuICAgICAgICAgICAgICBjYXNlIDA6XG4gICAgICAgICAgICAgICAgb3B0aW9ucyA9IF9hcmdzNC5sZW5ndGggPiAwICYmIF9hcmdzNFswXSAhPT0gdW5kZWZpbmVkID8gX2FyZ3M0WzBdIDoge307XG4gICAgICAgICAgICAgICAgX2NvbnRleHQ0Lm5leHQgPSAzO1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmZldGNoU2VydmVySW5mbyhvcHRpb25zKTtcblxuICAgICAgICAgICAgICBjYXNlIDM6XG4gICAgICAgICAgICAgICAgX3JlZjMgPSBfY29udGV4dDQuc2VudDtcbiAgICAgICAgICAgICAgICBjYXBhYmlsaXRpZXMgPSBfcmVmMy5jYXBhYmlsaXRpZXM7XG4gICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0NC5hYnJ1cHQoXCJyZXR1cm5cIiwgY2FwYWJpbGl0aWVzKTtcblxuICAgICAgICAgICAgICBjYXNlIDY6XG4gICAgICAgICAgICAgIGNhc2UgXCJlbmRcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQ0LnN0b3AoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0sIF9jYWxsZWU0LCB0aGlzKTtcbiAgICAgIH0pKTtcblxuICAgICAgcmV0dXJuIGZ1bmN0aW9uIGZldGNoU2VydmVyQ2FwYWJpbGl0aWVzKCkge1xuICAgICAgICByZXR1cm4gX2ZldGNoU2VydmVyQ2FwYWJpbGl0aWVzLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICB9O1xuICAgIH0oKVxuICAgIC8qKlxuICAgICAqIFJldHJpZXZlIGF1dGhlbnRpY2F0ZWQgdXNlciBpbmZvcm1hdGlvbi5cbiAgICAgKlxuICAgICAqIEBwYXJhbSAge09iamVjdH0gIFtvcHRpb25zPXt9XSBUaGUgcmVxdWVzdCBvcHRpb25zLlxuICAgICAqIEBwYXJhbSAge09iamVjdH0gIFtvcHRpb25zLmhlYWRlcnM9e31dIEhlYWRlcnMgdG8gdXNlIHdoZW4gbWFraW5nXG4gICAgICogICAgIHRoaXMgcmVxdWVzdC5cbiAgICAgKiBAcGFyYW0gIHtOdW1iZXJ9ICBbb3B0aW9ucy5yZXRyeT0wXSAgICBOdW1iZXIgb2YgcmV0cmllcyB0byBtYWtlXG4gICAgICogICAgIHdoZW4gZmFjZWQgd2l0aCB0cmFuc2llbnQgZXJyb3JzLlxuICAgICAqIEByZXR1cm4ge1Byb21pc2U8T2JqZWN0LCBFcnJvcj59XG4gICAgICovXG5cbiAgfSwge1xuICAgIGtleTogXCJmZXRjaFVzZXJcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gKCkge1xuICAgICAgdmFyIF9mZXRjaFVzZXIgPSAoMCwgX2FzeW5jVG9HZW5lcmF0b3IyLmRlZmF1bHQpKFxuICAgICAgLyojX19QVVJFX18qL1xuICAgICAgX3JlZ2VuZXJhdG9yLmRlZmF1bHQubWFyayhmdW5jdGlvbiBfY2FsbGVlNSgpIHtcbiAgICAgICAgdmFyIG9wdGlvbnMsXG4gICAgICAgICAgICBfcmVmNCxcbiAgICAgICAgICAgIHVzZXIsXG4gICAgICAgICAgICBfYXJnczUgPSBhcmd1bWVudHM7XG5cbiAgICAgICAgcmV0dXJuIF9yZWdlbmVyYXRvci5kZWZhdWx0LndyYXAoZnVuY3Rpb24gX2NhbGxlZTUkKF9jb250ZXh0NSkge1xuICAgICAgICAgIHdoaWxlICgxKSB7XG4gICAgICAgICAgICBzd2l0Y2ggKF9jb250ZXh0NS5wcmV2ID0gX2NvbnRleHQ1Lm5leHQpIHtcbiAgICAgICAgICAgICAgY2FzZSAwOlxuICAgICAgICAgICAgICAgIG9wdGlvbnMgPSBfYXJnczUubGVuZ3RoID4gMCAmJiBfYXJnczVbMF0gIT09IHVuZGVmaW5lZCA/IF9hcmdzNVswXSA6IHt9O1xuICAgICAgICAgICAgICAgIF9jb250ZXh0NS5uZXh0ID0gMztcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fZ2V0SGVsbG8ob3B0aW9ucyk7XG5cbiAgICAgICAgICAgICAgY2FzZSAzOlxuICAgICAgICAgICAgICAgIF9yZWY0ID0gX2NvbnRleHQ1LnNlbnQ7XG4gICAgICAgICAgICAgICAgdXNlciA9IF9yZWY0LnVzZXI7XG4gICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0NS5hYnJ1cHQoXCJyZXR1cm5cIiwgdXNlcik7XG5cbiAgICAgICAgICAgICAgY2FzZSA2OlxuICAgICAgICAgICAgICBjYXNlIFwiZW5kXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0NS5zdG9wKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9LCBfY2FsbGVlNSwgdGhpcyk7XG4gICAgICB9KSk7XG5cbiAgICAgIHJldHVybiBmdW5jdGlvbiBmZXRjaFVzZXIoKSB7XG4gICAgICAgIHJldHVybiBfZmV0Y2hVc2VyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICB9O1xuICAgIH0oKVxuICAgIC8qKlxuICAgICAqIFJldHJpZXZlIGF1dGhlbnRpY2F0ZWQgdXNlciBpbmZvcm1hdGlvbi5cbiAgICAgKlxuICAgICAqIEBwYXJhbSAge09iamVjdH0gIFtvcHRpb25zPXt9XSBUaGUgcmVxdWVzdCBvcHRpb25zLlxuICAgICAqIEBwYXJhbSAge051bWJlcn0gIFtvcHRpb25zLnJldHJ5PTBdICAgIE51bWJlciBvZiByZXRyaWVzIHRvIG1ha2VcbiAgICAgKiAgICAgd2hlbiBmYWNlZCB3aXRoIHRyYW5zaWVudCBlcnJvcnMuXG4gICAgICogQHJldHVybiB7UHJvbWlzZTxPYmplY3QsIEVycm9yPn1cbiAgICAgKi9cblxuICB9LCB7XG4gICAga2V5OiBcImZldGNoSFRUUEFwaVZlcnNpb25cIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gKCkge1xuICAgICAgdmFyIF9mZXRjaEhUVFBBcGlWZXJzaW9uID0gKDAsIF9hc3luY1RvR2VuZXJhdG9yMi5kZWZhdWx0KShcbiAgICAgIC8qI19fUFVSRV9fKi9cbiAgICAgIF9yZWdlbmVyYXRvci5kZWZhdWx0Lm1hcmsoZnVuY3Rpb24gX2NhbGxlZTYoKSB7XG4gICAgICAgIHZhciBvcHRpb25zLFxuICAgICAgICAgICAgX3JlZjUsXG4gICAgICAgICAgICBodHRwX2FwaV92ZXJzaW9uLFxuICAgICAgICAgICAgX2FyZ3M2ID0gYXJndW1lbnRzO1xuXG4gICAgICAgIHJldHVybiBfcmVnZW5lcmF0b3IuZGVmYXVsdC53cmFwKGZ1bmN0aW9uIF9jYWxsZWU2JChfY29udGV4dDYpIHtcbiAgICAgICAgICB3aGlsZSAoMSkge1xuICAgICAgICAgICAgc3dpdGNoIChfY29udGV4dDYucHJldiA9IF9jb250ZXh0Ni5uZXh0KSB7XG4gICAgICAgICAgICAgIGNhc2UgMDpcbiAgICAgICAgICAgICAgICBvcHRpb25zID0gX2FyZ3M2Lmxlbmd0aCA+IDAgJiYgX2FyZ3M2WzBdICE9PSB1bmRlZmluZWQgPyBfYXJnczZbMF0gOiB7fTtcbiAgICAgICAgICAgICAgICBfY29udGV4dDYubmV4dCA9IDM7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZmV0Y2hTZXJ2ZXJJbmZvKG9wdGlvbnMpO1xuXG4gICAgICAgICAgICAgIGNhc2UgMzpcbiAgICAgICAgICAgICAgICBfcmVmNSA9IF9jb250ZXh0Ni5zZW50O1xuICAgICAgICAgICAgICAgIGh0dHBfYXBpX3ZlcnNpb24gPSBfcmVmNS5odHRwX2FwaV92ZXJzaW9uO1xuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDYuYWJydXB0KFwicmV0dXJuXCIsIGh0dHBfYXBpX3ZlcnNpb24pO1xuXG4gICAgICAgICAgICAgIGNhc2UgNjpcbiAgICAgICAgICAgICAgY2FzZSBcImVuZFwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDYuc3RvcCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSwgX2NhbGxlZTYsIHRoaXMpO1xuICAgICAgfSkpO1xuXG4gICAgICByZXR1cm4gZnVuY3Rpb24gZmV0Y2hIVFRQQXBpVmVyc2lvbigpIHtcbiAgICAgICAgcmV0dXJuIF9mZXRjaEhUVFBBcGlWZXJzaW9uLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICB9O1xuICAgIH0oKVxuICAgIC8qKlxuICAgICAqIFByb2Nlc3MgYmF0Y2ggcmVxdWVzdHMsIGNodW5raW5nIHRoZW0gYWNjb3JkaW5nIHRvIHRoZSBiYXRjaF9tYXhfcmVxdWVzdHNcbiAgICAgKiBzZXJ2ZXIgc2V0dGluZyB3aGVuIG5lZWRlZC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSAge0FycmF5fSAgcmVxdWVzdHMgICAgIFRoZSBsaXN0IG9mIGJhdGNoIHN1YnJlcXVlc3RzIHRvIHBlcmZvcm0uXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSBbb3B0aW9ucz17fV0gVGhlIG9wdGlvbnMgb2JqZWN0LlxuICAgICAqIEByZXR1cm4ge1Byb21pc2U8T2JqZWN0LCBFcnJvcj59XG4gICAgICovXG5cbiAgfSwge1xuICAgIGtleTogXCJfYmF0Y2hSZXF1ZXN0c1wiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgX2JhdGNoUmVxdWVzdHMyID0gKDAsIF9hc3luY1RvR2VuZXJhdG9yMi5kZWZhdWx0KShcbiAgICAgIC8qI19fUFVSRV9fKi9cbiAgICAgIF9yZWdlbmVyYXRvci5kZWZhdWx0Lm1hcmsoZnVuY3Rpb24gX2NhbGxlZTcocmVxdWVzdHMpIHtcbiAgICAgICAgdmFyIF90aGlzMiA9IHRoaXM7XG5cbiAgICAgICAgdmFyIG9wdGlvbnMsXG4gICAgICAgICAgICBoZWFkZXJzLFxuICAgICAgICAgICAgc2VydmVyU2V0dGluZ3MsXG4gICAgICAgICAgICBtYXhSZXF1ZXN0cyxcbiAgICAgICAgICAgIGNodW5rcyxcbiAgICAgICAgICAgIF9yZWY2LFxuICAgICAgICAgICAgcmVzcG9uc2VzLFxuICAgICAgICAgICAgX2FyZ3M3ID0gYXJndW1lbnRzO1xuXG4gICAgICAgIHJldHVybiBfcmVnZW5lcmF0b3IuZGVmYXVsdC53cmFwKGZ1bmN0aW9uIF9jYWxsZWU3JChfY29udGV4dDcpIHtcbiAgICAgICAgICB3aGlsZSAoMSkge1xuICAgICAgICAgICAgc3dpdGNoIChfY29udGV4dDcucHJldiA9IF9jb250ZXh0Ny5uZXh0KSB7XG4gICAgICAgICAgICAgIGNhc2UgMDpcbiAgICAgICAgICAgICAgICBvcHRpb25zID0gX2FyZ3M3Lmxlbmd0aCA+IDEgJiYgX2FyZ3M3WzFdICE9PSB1bmRlZmluZWQgPyBfYXJnczdbMV0gOiB7fTtcbiAgICAgICAgICAgICAgICBoZWFkZXJzID0gdGhpcy5fZ2V0SGVhZGVycyhvcHRpb25zKTtcblxuICAgICAgICAgICAgICAgIGlmIChyZXF1ZXN0cy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICAgIF9jb250ZXh0Ny5uZXh0ID0gNDtcbiAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDcuYWJydXB0KFwicmV0dXJuXCIsIFtdKTtcblxuICAgICAgICAgICAgICBjYXNlIDQ6XG4gICAgICAgICAgICAgICAgX2NvbnRleHQ3Lm5leHQgPSA2O1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmZldGNoU2VydmVyU2V0dGluZ3Moe1xuICAgICAgICAgICAgICAgICAgcmV0cnk6IHRoaXMuX2dldFJldHJ5KG9wdGlvbnMpXG4gICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgY2FzZSA2OlxuICAgICAgICAgICAgICAgIHNlcnZlclNldHRpbmdzID0gX2NvbnRleHQ3LnNlbnQ7XG4gICAgICAgICAgICAgICAgbWF4UmVxdWVzdHMgPSBzZXJ2ZXJTZXR0aW5nc1tcImJhdGNoX21heF9yZXF1ZXN0c1wiXTtcblxuICAgICAgICAgICAgICAgIGlmICghKG1heFJlcXVlc3RzICYmIHJlcXVlc3RzLmxlbmd0aCA+IG1heFJlcXVlc3RzKSkge1xuICAgICAgICAgICAgICAgICAgX2NvbnRleHQ3Lm5leHQgPSAxMTtcbiAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGNodW5rcyA9ICgwLCBfdXRpbHMucGFydGl0aW9uKShyZXF1ZXN0cywgbWF4UmVxdWVzdHMpO1xuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDcuYWJydXB0KFwicmV0dXJuXCIsICgwLCBfdXRpbHMucE1hcCkoY2h1bmtzLCBmdW5jdGlvbiAoY2h1bmspIHtcbiAgICAgICAgICAgICAgICAgIHJldHVybiBfdGhpczIuX2JhdGNoUmVxdWVzdHMoY2h1bmssIG9wdGlvbnMpO1xuICAgICAgICAgICAgICAgIH0pKTtcblxuICAgICAgICAgICAgICBjYXNlIDExOlxuICAgICAgICAgICAgICAgIF9jb250ZXh0Ny5uZXh0ID0gMTM7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZXhlY3V0ZSh7XG4gICAgICAgICAgICAgICAgICAvLyBGSVhNRTogaXMgdGhpcyByZWFsbHkgbmVjZXNzYXJ5LCBzaW5jZSBpdCdzIGFsc28gcHJlc2VudCBpblxuICAgICAgICAgICAgICAgICAgLy8gdGhlIFwiZGVmYXVsdHNcIj9cbiAgICAgICAgICAgICAgICAgIGhlYWRlcnM6IGhlYWRlcnMsXG4gICAgICAgICAgICAgICAgICBwYXRoOiAoMCwgX2VuZHBvaW50LmRlZmF1bHQpKFwiYmF0Y2hcIiksXG4gICAgICAgICAgICAgICAgICBtZXRob2Q6IFwiUE9TVFwiLFxuICAgICAgICAgICAgICAgICAgYm9keToge1xuICAgICAgICAgICAgICAgICAgICBkZWZhdWx0czoge1xuICAgICAgICAgICAgICAgICAgICAgIGhlYWRlcnM6IGhlYWRlcnNcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgcmVxdWVzdHM6IHJlcXVlc3RzXG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSwge1xuICAgICAgICAgICAgICAgICAgcmV0cnk6IHRoaXMuX2dldFJldHJ5KG9wdGlvbnMpXG4gICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgY2FzZSAxMzpcbiAgICAgICAgICAgICAgICBfcmVmNiA9IF9jb250ZXh0Ny5zZW50O1xuICAgICAgICAgICAgICAgIHJlc3BvbnNlcyA9IF9yZWY2LnJlc3BvbnNlcztcbiAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQ3LmFicnVwdChcInJldHVyblwiLCByZXNwb25zZXMpO1xuXG4gICAgICAgICAgICAgIGNhc2UgMTY6XG4gICAgICAgICAgICAgIGNhc2UgXCJlbmRcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQ3LnN0b3AoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0sIF9jYWxsZWU3LCB0aGlzKTtcbiAgICAgIH0pKTtcblxuICAgICAgcmV0dXJuIGZ1bmN0aW9uIF9iYXRjaFJlcXVlc3RzKF94Mikge1xuICAgICAgICByZXR1cm4gX2JhdGNoUmVxdWVzdHMyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICB9O1xuICAgIH0oKVxuICAgIC8qKlxuICAgICAqIFNlbmRzIGJhdGNoIHJlcXVlc3RzIHRvIHRoZSByZW1vdGUgc2VydmVyLlxuICAgICAqXG4gICAgICogTm90ZTogUmVzZXJ2ZWQgZm9yIGludGVybmFsIHVzZSBvbmx5LlxuICAgICAqXG4gICAgICogQGlnbm9yZVxuICAgICAqIEBwYXJhbSAge0Z1bmN0aW9ufSBmbiAgICAgICAgICAgICAgICAgICAgICAgIFRoZSBmdW5jdGlvbiB0byB1c2UgZm9yIGRlc2NyaWJpbmcgYmF0Y2ggb3BzLlxuICAgICAqIEBwYXJhbSAge09iamVjdH0gICBbb3B0aW9ucz17fV0gICAgICAgICAgICAgIFRoZSBvcHRpb25zIG9iamVjdC5cbiAgICAgKiBAcGFyYW0gIHtCb29sZWFufSAgW29wdGlvbnMuc2FmZV0gICAgICAgICAgICBUaGUgc2FmZSBvcHRpb24uXG4gICAgICogQHBhcmFtICB7TnVtYmVyfSAgIFtvcHRpb25zLnJldHJ5XSAgICAgICAgICAgVGhlIHJldHJ5IG9wdGlvbi5cbiAgICAgKiBAcGFyYW0gIHtTdHJpbmd9ICAgW29wdGlvbnMuYnVja2V0XSAgICAgICAgICBUaGUgYnVja2V0IG5hbWUgb3B0aW9uLlxuICAgICAqIEBwYXJhbSAge1N0cmluZ30gICBbb3B0aW9ucy5jb2xsZWN0aW9uXSAgICAgIFRoZSBjb2xsZWN0aW9uIG5hbWUgb3B0aW9uLlxuICAgICAqIEBwYXJhbSAge09iamVjdH0gICBbb3B0aW9ucy5oZWFkZXJzXSAgICAgICAgIFRoZSBoZWFkZXJzIG9iamVjdCBvcHRpb24uXG4gICAgICogQHBhcmFtICB7Qm9vbGVhbn0gIFtvcHRpb25zLmFnZ3JlZ2F0ZT1mYWxzZV0gUHJvZHVjZXMgYW4gYWdncmVnYXRlZCByZXN1bHQgb2JqZWN0LlxuICAgICAqIEByZXR1cm4ge1Byb21pc2U8T2JqZWN0LCBFcnJvcj59XG4gICAgICovXG5cbiAgfSwge1xuICAgIGtleTogXCJiYXRjaFwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgX2JhdGNoID0gKDAsIF9hc3luY1RvR2VuZXJhdG9yMi5kZWZhdWx0KShcbiAgICAgIC8qI19fUFVSRV9fKi9cbiAgICAgIF9yZWdlbmVyYXRvci5kZWZhdWx0Lm1hcmsoZnVuY3Rpb24gX2NhbGxlZTgoZm4pIHtcbiAgICAgICAgdmFyIG9wdGlvbnMsXG4gICAgICAgICAgICByb290QmF0Y2gsXG4gICAgICAgICAgICBidWNrZXRCYXRjaCxcbiAgICAgICAgICAgIGNvbGxCYXRjaCxcbiAgICAgICAgICAgIGJhdGNoQ2xpZW50LFxuICAgICAgICAgICAgcmVzcG9uc2VzLFxuICAgICAgICAgICAgX2FyZ3M4ID0gYXJndW1lbnRzO1xuICAgICAgICByZXR1cm4gX3JlZ2VuZXJhdG9yLmRlZmF1bHQud3JhcChmdW5jdGlvbiBfY2FsbGVlOCQoX2NvbnRleHQ4KSB7XG4gICAgICAgICAgd2hpbGUgKDEpIHtcbiAgICAgICAgICAgIHN3aXRjaCAoX2NvbnRleHQ4LnByZXYgPSBfY29udGV4dDgubmV4dCkge1xuICAgICAgICAgICAgICBjYXNlIDA6XG4gICAgICAgICAgICAgICAgb3B0aW9ucyA9IF9hcmdzOC5sZW5ndGggPiAxICYmIF9hcmdzOFsxXSAhPT0gdW5kZWZpbmVkID8gX2FyZ3M4WzFdIDoge307XG4gICAgICAgICAgICAgICAgcm9vdEJhdGNoID0gbmV3IEtpbnRvQ2xpZW50QmFzZSh0aGlzLnJlbW90ZSwge1xuICAgICAgICAgICAgICAgICAgZXZlbnRzOiB0aGlzLmV2ZW50cyxcbiAgICAgICAgICAgICAgICAgIGJhdGNoOiB0cnVlLFxuICAgICAgICAgICAgICAgICAgc2FmZTogdGhpcy5fZ2V0U2FmZShvcHRpb25zKSxcbiAgICAgICAgICAgICAgICAgIHJldHJ5OiB0aGlzLl9nZXRSZXRyeShvcHRpb25zKVxuICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgaWYgKG9wdGlvbnMuYnVja2V0KSB7XG4gICAgICAgICAgICAgICAgICBidWNrZXRCYXRjaCA9IHJvb3RCYXRjaC5idWNrZXQob3B0aW9ucy5idWNrZXQpO1xuXG4gICAgICAgICAgICAgICAgICBpZiAob3B0aW9ucy5jb2xsZWN0aW9uKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbGxCYXRjaCA9IGJ1Y2tldEJhdGNoLmNvbGxlY3Rpb24ob3B0aW9ucy5jb2xsZWN0aW9uKTtcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBiYXRjaENsaWVudCA9IGNvbGxCYXRjaCB8fCBidWNrZXRCYXRjaCB8fCByb290QmF0Y2g7XG4gICAgICAgICAgICAgICAgZm4oYmF0Y2hDbGllbnQpO1xuICAgICAgICAgICAgICAgIF9jb250ZXh0OC5uZXh0ID0gNztcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5fYmF0Y2hSZXF1ZXN0cyhyb290QmF0Y2guX3JlcXVlc3RzLCBvcHRpb25zKTtcblxuICAgICAgICAgICAgICBjYXNlIDc6XG4gICAgICAgICAgICAgICAgcmVzcG9uc2VzID0gX2NvbnRleHQ4LnNlbnQ7XG5cbiAgICAgICAgICAgICAgICBpZiAoIW9wdGlvbnMuYWdncmVnYXRlKSB7XG4gICAgICAgICAgICAgICAgICBfY29udGV4dDgubmV4dCA9IDEyO1xuICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0OC5hYnJ1cHQoXCJyZXR1cm5cIiwgKDAsIF9iYXRjaDIuYWdncmVnYXRlKShyZXNwb25zZXMsIHJvb3RCYXRjaC5fcmVxdWVzdHMpKTtcblxuICAgICAgICAgICAgICBjYXNlIDEyOlxuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDguYWJydXB0KFwicmV0dXJuXCIsIHJlc3BvbnNlcyk7XG5cbiAgICAgICAgICAgICAgY2FzZSAxMzpcbiAgICAgICAgICAgICAgY2FzZSBcImVuZFwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDguc3RvcCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSwgX2NhbGxlZTgsIHRoaXMpO1xuICAgICAgfSkpO1xuXG4gICAgICByZXR1cm4gZnVuY3Rpb24gYmF0Y2goX3gzKSB7XG4gICAgICAgIHJldHVybiBfYmF0Y2guYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgIH07XG4gICAgfSgpXG4gICAgLyoqXG4gICAgICogRXhlY3V0ZXMgYW4gYXRvbWljIEhUVFAgcmVxdWVzdC5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSAgcmVxdWVzdCAgICAgICAgICAgICBUaGUgcmVxdWVzdCBvYmplY3QuXG4gICAgICogQHBhcmFtICB7U3RyaW5nfSAgcmVxdWVzdC5wYXRoICAgICAgICBUaGUgcGF0aCB0byBmZXRjaCwgcmVsYXRpdmVcbiAgICAgKiAgICAgdG8gdGhlIEtpbnRvIHNlcnZlciByb290LlxuICAgICAqIEBwYXJhbSAge1N0cmluZ30gIFtyZXF1ZXN0Lm1ldGhvZD1cIkdFVFwiXSBUaGUgbWV0aG9kIHRvIHVzZSBpbiB0aGVcbiAgICAgKiAgICAgcmVxdWVzdC5cbiAgICAgKiBAcGFyYW0gIHtCb2R5fSAgICBbcmVxdWVzdC5ib2R5XSAgICAgIFRoZSByZXF1ZXN0IGJvZHkuXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSAgW3JlcXVlc3QuaGVhZGVycz17fV0gVGhlIHJlcXVlc3QgaGVhZGVycy5cbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9ICBbb3B0aW9ucz17fV0gICAgICAgIFRoZSBvcHRpb25zIG9iamVjdC5cbiAgICAgKiBAcGFyYW0gIHtCb29sZWFufSBbb3B0aW9ucy5yYXc9ZmFsc2VdIElmIHRydWUsIHJlc29sdmUgd2l0aCBmdWxsIHJlc3BvbnNlXG4gICAgICogQHBhcmFtICB7Qm9vbGVhbn0gW29wdGlvbnMuc3RyaW5naWZ5PXRydWVdIElmIHRydWUsIHNlcmlhbGl6ZSBib2R5IGRhdGEgdG9cbiAgICAgKiBAcGFyYW0gIHtOdW1iZXJ9ICBbb3B0aW9ucy5yZXRyeT0wXSAgIFRoZSBudW1iZXIgb2YgdGltZXMgdG9cbiAgICAgKiAgICAgcmV0cnkgYSByZXF1ZXN0IGlmIHRoZSBzZXJ2ZXIgcmVzcG9uZHMgd2l0aCBSZXRyeS1BZnRlci5cbiAgICAgKiBKU09OLlxuICAgICAqIEByZXR1cm4ge1Byb21pc2U8T2JqZWN0LCBFcnJvcj59XG4gICAgICovXG5cbiAgfSwge1xuICAgIGtleTogXCJleGVjdXRlXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciBfZXhlY3V0ZSA9ICgwLCBfYXN5bmNUb0dlbmVyYXRvcjIuZGVmYXVsdCkoXG4gICAgICAvKiNfX1BVUkVfXyovXG4gICAgICBfcmVnZW5lcmF0b3IuZGVmYXVsdC5tYXJrKGZ1bmN0aW9uIF9jYWxsZWU5KHJlcXVlc3QpIHtcbiAgICAgICAgdmFyIG9wdGlvbnMsXG4gICAgICAgICAgICBfb3B0aW9ucyRyYXcsXG4gICAgICAgICAgICByYXcsXG4gICAgICAgICAgICBfb3B0aW9ucyRzdHJpbmdpZnksXG4gICAgICAgICAgICBzdHJpbmdpZnksXG4gICAgICAgICAgICBtc2csXG4gICAgICAgICAgICByZXN1bHQsXG4gICAgICAgICAgICBfYXJnczkgPSBhcmd1bWVudHM7XG5cbiAgICAgICAgcmV0dXJuIF9yZWdlbmVyYXRvci5kZWZhdWx0LndyYXAoZnVuY3Rpb24gX2NhbGxlZTkkKF9jb250ZXh0OSkge1xuICAgICAgICAgIHdoaWxlICgxKSB7XG4gICAgICAgICAgICBzd2l0Y2ggKF9jb250ZXh0OS5wcmV2ID0gX2NvbnRleHQ5Lm5leHQpIHtcbiAgICAgICAgICAgICAgY2FzZSAwOlxuICAgICAgICAgICAgICAgIG9wdGlvbnMgPSBfYXJnczkubGVuZ3RoID4gMSAmJiBfYXJnczlbMV0gIT09IHVuZGVmaW5lZCA/IF9hcmdzOVsxXSA6IHt9O1xuICAgICAgICAgICAgICAgIF9vcHRpb25zJHJhdyA9IG9wdGlvbnMucmF3LCByYXcgPSBfb3B0aW9ucyRyYXcgPT09IHZvaWQgMCA/IGZhbHNlIDogX29wdGlvbnMkcmF3LCBfb3B0aW9ucyRzdHJpbmdpZnkgPSBvcHRpb25zLnN0cmluZ2lmeSwgc3RyaW5naWZ5ID0gX29wdGlvbnMkc3RyaW5naWZ5ID09PSB2b2lkIDAgPyB0cnVlIDogX29wdGlvbnMkc3RyaW5naWZ5OyAvLyBJZiB3ZSdyZSB3aXRoaW4gYSBiYXRjaCwgYWRkIHRoZSByZXF1ZXN0IHRvIHRoZSBzdGFjayB0byBzZW5kIGF0IG9uY2UuXG5cbiAgICAgICAgICAgICAgICBpZiAoIXRoaXMuX2lzQmF0Y2gpIHtcbiAgICAgICAgICAgICAgICAgIF9jb250ZXh0OS5uZXh0ID0gNjtcbiAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHRoaXMuX3JlcXVlc3RzLnB1c2gocmVxdWVzdCk7IC8vIFJlc29sdmUgd2l0aCBhIG1lc3NhZ2UgaW4gY2FzZSBwZW9wbGUgYXR0ZW1wdCBhdCBjb25zdW1pbmcgdGhlIHJlc3VsdFxuICAgICAgICAgICAgICAgIC8vIGZyb20gd2l0aGluIGEgYmF0Y2ggb3BlcmF0aW9uLlxuXG5cbiAgICAgICAgICAgICAgICBtc2cgPSBcIlRoaXMgcmVzdWx0IGlzIGdlbmVyYXRlZCBmcm9tIHdpdGhpbiBhIGJhdGNoIFwiICsgXCJvcGVyYXRpb24gYW5kIHNob3VsZCBub3QgYmUgY29uc3VtZWQuXCI7XG4gICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0OS5hYnJ1cHQoXCJyZXR1cm5cIiwgcmF3ID8ge1xuICAgICAgICAgICAgICAgICAganNvbjogbXNnLFxuICAgICAgICAgICAgICAgICAgaGVhZGVyczoge1xuICAgICAgICAgICAgICAgICAgICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHt9XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSA6IG1zZyk7XG5cbiAgICAgICAgICAgICAgY2FzZSA2OlxuICAgICAgICAgICAgICAgIF9jb250ZXh0OS5uZXh0ID0gODtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5odHRwLnJlcXVlc3QodGhpcy5yZW1vdGUgKyByZXF1ZXN0LnBhdGgsICgwLCBfdXRpbHMuY2xlYW5VbmRlZmluZWRQcm9wZXJ0aWVzKSh7XG4gICAgICAgICAgICAgICAgICAvLyBMaW1pdCByZXF1ZXN0cyB0byBvbmx5IHRob3NlIHBhcnRzIHRoYXQgd291bGQgYmUgYWxsb3dlZCBpblxuICAgICAgICAgICAgICAgICAgLy8gYSBiYXRjaCByZXF1ZXN0IC0tIGRvbid0IHBhc3MgdGhyb3VnaCBvdGhlciBmYW5jeSBmZXRjaCgpXG4gICAgICAgICAgICAgICAgICAvLyBvcHRpb25zIGxpa2UgaW50ZWdyaXR5LCByZWRpcmVjdCwgbW9kZSBiZWNhdXNlIHRoZXkgd2lsbFxuICAgICAgICAgICAgICAgICAgLy8gYnJlYWsgb24gYSBiYXRjaCByZXF1ZXN0LiAgQSBiYXRjaCByZXF1ZXN0IG9ubHkgYWxsb3dzXG4gICAgICAgICAgICAgICAgICAvLyBoZWFkZXJzLCBtZXRob2QsIHBhdGggKGFib3ZlKSwgYW5kIGJvZHkuXG4gICAgICAgICAgICAgICAgICBtZXRob2Q6IHJlcXVlc3QubWV0aG9kLFxuICAgICAgICAgICAgICAgICAgaGVhZGVyczogcmVxdWVzdC5oZWFkZXJzLFxuICAgICAgICAgICAgICAgICAgYm9keTogc3RyaW5naWZ5ID8gSlNPTi5zdHJpbmdpZnkocmVxdWVzdC5ib2R5KSA6IHJlcXVlc3QuYm9keVxuICAgICAgICAgICAgICAgIH0pLCB7XG4gICAgICAgICAgICAgICAgICByZXRyeTogdGhpcy5fZ2V0UmV0cnkob3B0aW9ucylcbiAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICBjYXNlIDg6XG4gICAgICAgICAgICAgICAgcmVzdWx0ID0gX2NvbnRleHQ5LnNlbnQ7XG4gICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0OS5hYnJ1cHQoXCJyZXR1cm5cIiwgcmF3ID8gcmVzdWx0IDogcmVzdWx0Lmpzb24pO1xuXG4gICAgICAgICAgICAgIGNhc2UgMTA6XG4gICAgICAgICAgICAgIGNhc2UgXCJlbmRcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQ5LnN0b3AoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0sIF9jYWxsZWU5LCB0aGlzKTtcbiAgICAgIH0pKTtcblxuICAgICAgcmV0dXJuIGZ1bmN0aW9uIGV4ZWN1dGUoX3g0KSB7XG4gICAgICAgIHJldHVybiBfZXhlY3V0ZS5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgfTtcbiAgICB9KClcbiAgICAvKipcbiAgICAgKiBGZXRjaCBzb21lIHBhZ2VzIGZyb20gYSBwYWdpbmF0ZWQgbGlzdCwgZm9sbG93aW5nIHRoZSBgbmV4dC1wYWdlYFxuICAgICAqIGhlYWRlciBhdXRvbWF0aWNhbGx5IHVudGlsIHdlIGhhdmUgZmV0Y2hlZCB0aGUgcmVxdWVzdGVkIG51bWJlclxuICAgICAqIG9mIHBhZ2VzLiBSZXR1cm4gYSByZXNwb25zZSB3aXRoIGEgYC5uZXh0KClgIG1ldGhvZCB0aGF0IGNhbiBiZVxuICAgICAqIGNhbGxlZCB0byBmZXRjaCBtb3JlIHJlc3VsdHMuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSAge1N0cmluZ30gIHBhdGhcbiAgICAgKiAgICAgVGhlIHBhdGggdG8gbWFrZSB0aGUgcmVxdWVzdCB0by5cbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9ICBwYXJhbXNcbiAgICAgKiAgICAgVGhlIHBhcmFtZXRlcnMgdG8gdXNlIHdoZW4gbWFraW5nIHRoZSByZXF1ZXN0LlxuICAgICAqIEBwYXJhbSAge1N0cmluZ30gIFtwYXJhbXMuc29ydD1cIi1sYXN0X21vZGlmaWVkXCJdXG4gICAgICogICAgIFRoZSBzb3J0aW5nIG9yZGVyIHRvIHVzZSB3aGVuIGZldGNoaW5nLlxuICAgICAqIEBwYXJhbSAge09iamVjdH0gIFtwYXJhbXMuZmlsdGVycz17fV1cbiAgICAgKiAgICAgVGhlIGZpbHRlcnMgdG8gc2VuZCBpbiB0aGUgcmVxdWVzdC5cbiAgICAgKiBAcGFyYW0gIHtOdW1iZXJ9ICBbcGFyYW1zLmxpbWl0PXVuZGVmaW5lZF1cbiAgICAgKiAgICAgVGhlIGxpbWl0IHRvIHNlbmQgaW4gdGhlIHJlcXVlc3QuIFVuZGVmaW5lZCBtZWFucyBubyBsaW1pdC5cbiAgICAgKiBAcGFyYW0gIHtOdW1iZXJ9ICBbcGFyYW1zLnBhZ2VzPXVuZGVmaW5lZF1cbiAgICAgKiAgICAgVGhlIG51bWJlciBvZiBwYWdlcyB0byBmZXRjaC4gVW5kZWZpbmVkIG1lYW5zIG9uZSBwYWdlLiBQYXNzXG4gICAgICogICAgIEluZmluaXR5IHRvIGZldGNoIGV2ZXJ5dGhpbmcuXG4gICAgICogQHBhcmFtICB7U3RyaW5nfSAgW3BhcmFtcy5zaW5jZT11bmRlZmluZWRdXG4gICAgICogICAgIFRoZSBFVGFnIGZyb20gd2hpY2ggdG8gc3RhcnQgZmV0Y2hpbmcuXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSAgW29wdGlvbnM9e31dXG4gICAgICogICAgIEFkZGl0aW9uYWwgcmVxdWVzdC1sZXZlbCBwYXJhbWV0ZXJzIHRvIHVzZSBpbiBhbGwgcmVxdWVzdHMuXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSAgW29wdGlvbnMuaGVhZGVycz17fV1cbiAgICAgKiAgICAgSGVhZGVycyB0byB1c2UgZHVyaW5nIGFsbCByZXF1ZXN0cy5cbiAgICAgKiBAcGFyYW0gIHtOdW1iZXJ9ICBbb3B0aW9ucy5yZXRyeT0wXVxuICAgICAqICAgICBOdW1iZXIgb2YgdGltZXMgdG8gcmV0cnkgZWFjaCByZXF1ZXN0IGlmIHRoZSBzZXJ2ZXIgcmVzcG9uZHNcbiAgICAgKiAgICAgd2l0aCBSZXRyeS1BZnRlci5cbiAgICAgKi9cblxuICB9LCB7XG4gICAga2V5OiBcInBhZ2luYXRlZExpc3RcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gKCkge1xuICAgICAgdmFyIF9wYWdpbmF0ZWRMaXN0ID0gKDAsIF9hc3luY1RvR2VuZXJhdG9yMi5kZWZhdWx0KShcbiAgICAgIC8qI19fUFVSRV9fKi9cbiAgICAgIF9yZWdlbmVyYXRvci5kZWZhdWx0Lm1hcmsoZnVuY3Rpb24gX2NhbGxlZTEzKHBhdGgsIHBhcmFtcykge1xuICAgICAgICB2YXIgX3RoaXMzID0gdGhpcztcblxuICAgICAgICB2YXIgb3B0aW9ucyxcbiAgICAgICAgICAgIF9zb3J0JHBhcmFtcyxcbiAgICAgICAgICAgIHNvcnQsXG4gICAgICAgICAgICBmaWx0ZXJzLFxuICAgICAgICAgICAgbGltaXQsXG4gICAgICAgICAgICBwYWdlcyxcbiAgICAgICAgICAgIHNpbmNlLFxuICAgICAgICAgICAgcXVlcnlzdHJpbmcsXG4gICAgICAgICAgICByZXN1bHRzLFxuICAgICAgICAgICAgY3VycmVudCxcbiAgICAgICAgICAgIG5leHQsXG4gICAgICAgICAgICBwcm9jZXNzTmV4dFBhZ2UsXG4gICAgICAgICAgICBwYWdlUmVzdWx0cyxcbiAgICAgICAgICAgIGhhbmRsZVJlc3BvbnNlLFxuICAgICAgICAgICAgX2FyZ3MxMyA9IGFyZ3VtZW50cztcblxuICAgICAgICByZXR1cm4gX3JlZ2VuZXJhdG9yLmRlZmF1bHQud3JhcChmdW5jdGlvbiBfY2FsbGVlMTMkKF9jb250ZXh0MTMpIHtcbiAgICAgICAgICB3aGlsZSAoMSkge1xuICAgICAgICAgICAgc3dpdGNoIChfY29udGV4dDEzLnByZXYgPSBfY29udGV4dDEzLm5leHQpIHtcbiAgICAgICAgICAgICAgY2FzZSAwOlxuICAgICAgICAgICAgICAgIG9wdGlvbnMgPSBfYXJnczEzLmxlbmd0aCA+IDIgJiYgX2FyZ3MxM1syXSAhPT0gdW5kZWZpbmVkID8gX2FyZ3MxM1syXSA6IHt9O1xuICAgICAgICAgICAgICAgIC8vIEZJWE1FOiB0aGlzIGlzIGNhbGxlZCBldmVuIGluIGJhdGNoIHJlcXVlc3RzLCB3aGljaCBkb2Vzbid0XG4gICAgICAgICAgICAgICAgLy8gbWFrZSBhbnkgc2Vuc2UgKHNpbmNlIGFsbCBiYXRjaCByZXF1ZXN0cyBnZXQgYSBcImR1bW15XCJcbiAgICAgICAgICAgICAgICAvLyByZXNwb25zZTsgc2VlIGV4ZWN1dGUoKSBhYm92ZSkuXG4gICAgICAgICAgICAgICAgX3NvcnQkcGFyYW1zID0gKDAsIF9vYmplY3RTcHJlYWQyLmRlZmF1bHQpKHtcbiAgICAgICAgICAgICAgICAgIHNvcnQ6IFwiLWxhc3RfbW9kaWZpZWRcIlxuICAgICAgICAgICAgICAgIH0sIHBhcmFtcyksIHNvcnQgPSBfc29ydCRwYXJhbXMuc29ydCwgZmlsdGVycyA9IF9zb3J0JHBhcmFtcy5maWx0ZXJzLCBsaW1pdCA9IF9zb3J0JHBhcmFtcy5saW1pdCwgcGFnZXMgPSBfc29ydCRwYXJhbXMucGFnZXMsIHNpbmNlID0gX3NvcnQkcGFyYW1zLnNpbmNlOyAvLyBTYWZldHkvQ29uc2lzdGVuY3kgY2hlY2sgb24gRVRhZyB2YWx1ZS5cblxuICAgICAgICAgICAgICAgIGlmICghKHNpbmNlICYmIHR5cGVvZiBzaW5jZSAhPT0gXCJzdHJpbmdcIikpIHtcbiAgICAgICAgICAgICAgICAgIF9jb250ZXh0MTMubmV4dCA9IDQ7XG4gICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJJbnZhbGlkIHZhbHVlIGZvciBzaW5jZSAoXCIuY29uY2F0KHNpbmNlLCBcIiksIHNob3VsZCBiZSBFVGFnIHZhbHVlLlwiKSk7XG5cbiAgICAgICAgICAgICAgY2FzZSA0OlxuICAgICAgICAgICAgICAgIHF1ZXJ5c3RyaW5nID0gKDAsIF91dGlscy5xc2lmeSkoKDAsIF9vYmplY3RTcHJlYWQyLmRlZmF1bHQpKHt9LCBmaWx0ZXJzLCB7XG4gICAgICAgICAgICAgICAgICBfc29ydDogc29ydCxcbiAgICAgICAgICAgICAgICAgIF9saW1pdDogbGltaXQsXG4gICAgICAgICAgICAgICAgICBfc2luY2U6IHNpbmNlXG4gICAgICAgICAgICAgICAgfSkpO1xuICAgICAgICAgICAgICAgIHJlc3VsdHMgPSBbXSwgY3VycmVudCA9IDA7XG5cbiAgICAgICAgICAgICAgICBuZXh0ID1cbiAgICAgICAgICAgICAgICAvKiNfX1BVUkVfXyovXG4gICAgICAgICAgICAgICAgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgdmFyIF9yZWY3ID0gKDAsIF9hc3luY1RvR2VuZXJhdG9yMi5kZWZhdWx0KShcbiAgICAgICAgICAgICAgICAgIC8qI19fUFVSRV9fKi9cbiAgICAgICAgICAgICAgICAgIF9yZWdlbmVyYXRvci5kZWZhdWx0Lm1hcmsoZnVuY3Rpb24gX2NhbGxlZTEwKG5leHRQYWdlKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBfcmVnZW5lcmF0b3IuZGVmYXVsdC53cmFwKGZ1bmN0aW9uIF9jYWxsZWUxMCQoX2NvbnRleHQxMCkge1xuICAgICAgICAgICAgICAgICAgICAgIHdoaWxlICgxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKF9jb250ZXh0MTAucHJldiA9IF9jb250ZXh0MTAubmV4dCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDA6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG5leHRQYWdlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfY29udGV4dDEwLm5leHQgPSAyO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiUGFnaW5hdGlvbiBleGhhdXN0ZWQuXCIpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMjpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQxMC5hYnJ1cHQoXCJyZXR1cm5cIiwgcHJvY2Vzc05leHRQYWdlKG5leHRQYWdlKSk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAzOlxuICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIFwiZW5kXCI6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0MTAuc3RvcCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSwgX2NhbGxlZTEwLCB0aGlzKTtcbiAgICAgICAgICAgICAgICAgIH0pKTtcblxuICAgICAgICAgICAgICAgICAgcmV0dXJuIGZ1bmN0aW9uIG5leHQoX3g3KSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBfcmVmNy5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICB9KCk7XG5cbiAgICAgICAgICAgICAgICBwcm9jZXNzTmV4dFBhZ2UgPVxuICAgICAgICAgICAgICAgIC8qI19fUFVSRV9fKi9cbiAgICAgICAgICAgICAgICBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICB2YXIgX3JlZjggPSAoMCwgX2FzeW5jVG9HZW5lcmF0b3IyLmRlZmF1bHQpKFxuICAgICAgICAgICAgICAgICAgLyojX19QVVJFX18qL1xuICAgICAgICAgICAgICAgICAgX3JlZ2VuZXJhdG9yLmRlZmF1bHQubWFyayhmdW5jdGlvbiBfY2FsbGVlMTEobmV4dFBhZ2UpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGhlYWRlcnM7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBfcmVnZW5lcmF0b3IuZGVmYXVsdC53cmFwKGZ1bmN0aW9uIF9jYWxsZWUxMSQoX2NvbnRleHQxMSkge1xuICAgICAgICAgICAgICAgICAgICAgIHdoaWxlICgxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKF9jb250ZXh0MTEucHJldiA9IF9jb250ZXh0MTEubmV4dCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDA6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaGVhZGVycyA9IG9wdGlvbnMuaGVhZGVycztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfY29udGV4dDExLnQwID0gaGFuZGxlUmVzcG9uc2U7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgX2NvbnRleHQxMS5uZXh0ID0gNDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gX3RoaXMzLmh0dHAucmVxdWVzdChuZXh0UGFnZSwge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGVhZGVyczogaGVhZGVyc1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgNDpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfY29udGV4dDExLnQxID0gX2NvbnRleHQxMS5zZW50O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDExLmFicnVwdChcInJldHVyblwiLCAoMCwgX2NvbnRleHQxMS50MCkoX2NvbnRleHQxMS50MSkpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgNjpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBcImVuZFwiOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDExLnN0b3AoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0sIF9jYWxsZWUxMSwgdGhpcyk7XG4gICAgICAgICAgICAgICAgICB9KSk7XG5cbiAgICAgICAgICAgICAgICAgIHJldHVybiBmdW5jdGlvbiBwcm9jZXNzTmV4dFBhZ2UoX3g4KSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBfcmVmOC5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICB9KCk7XG5cbiAgICAgICAgICAgICAgICBwYWdlUmVzdWx0cyA9IGZ1bmN0aW9uIHBhZ2VSZXN1bHRzKHJlc3VsdHMsIG5leHRQYWdlLCBldGFnLCB0b3RhbFJlY29yZHMpIHtcbiAgICAgICAgICAgICAgICAgIC8vIEVUYWcgc3RyaW5nIGlzIHN1cHBvc2VkIHRvIGJlIG9wYXF1ZSBhbmQgc3RvcmVkIMKrYXMtaXPCuy5cbiAgICAgICAgICAgICAgICAgIC8vIEVUYWcgaGVhZGVyIHZhbHVlcyBhcmUgcXVvdGVkIChiZWNhdXNlIG9mICogYW5kIFcvXCJmb29cIikuXG4gICAgICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgICAgICBsYXN0X21vZGlmaWVkOiBldGFnID8gZXRhZy5yZXBsYWNlKC9cIi9nLCBcIlwiKSA6IGV0YWcsXG4gICAgICAgICAgICAgICAgICAgIGRhdGE6IHJlc3VsdHMsXG4gICAgICAgICAgICAgICAgICAgIG5leHQ6IG5leHQuYmluZChudWxsLCBuZXh0UGFnZSksXG4gICAgICAgICAgICAgICAgICAgIGhhc05leHRQYWdlOiAhIW5leHRQYWdlLFxuICAgICAgICAgICAgICAgICAgICB0b3RhbFJlY29yZHM6IHRvdGFsUmVjb3Jkc1xuICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAgICAgaGFuZGxlUmVzcG9uc2UgPVxuICAgICAgICAgICAgICAgIC8qI19fUFVSRV9fKi9cbiAgICAgICAgICAgICAgICBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICB2YXIgX3JlZjkgPSAoMCwgX2FzeW5jVG9HZW5lcmF0b3IyLmRlZmF1bHQpKFxuICAgICAgICAgICAgICAgICAgLyojX19QVVJFX18qL1xuICAgICAgICAgICAgICAgICAgX3JlZ2VuZXJhdG9yLmRlZmF1bHQubWFyayhmdW5jdGlvbiBfY2FsbGVlMTIoX3JlZjEwKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBoZWFkZXJzLCBqc29uLCBuZXh0UGFnZSwgZXRhZywgdG90YWxSZWNvcmRzO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gX3JlZ2VuZXJhdG9yLmRlZmF1bHQud3JhcChmdW5jdGlvbiBfY2FsbGVlMTIkKF9jb250ZXh0MTIpIHtcbiAgICAgICAgICAgICAgICAgICAgICB3aGlsZSAoMSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgc3dpdGNoIChfY29udGV4dDEyLnByZXYgPSBfY29udGV4dDEyLm5leHQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAwOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhlYWRlcnMgPSBfcmVmMTAuaGVhZGVycywganNvbiA9IF9yZWYxMC5qc29uO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5leHRQYWdlID0gaGVhZGVycy5nZXQoXCJOZXh0LVBhZ2VcIik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZXRhZyA9IGhlYWRlcnMuZ2V0KFwiRVRhZ1wiKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbFJlY29yZHMgPSBwYXJzZUludChoZWFkZXJzLmdldChcIlRvdGFsLVJlY29yZHNcIiksIDEwKTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwYWdlcykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX2NvbnRleHQxMi5uZXh0ID0gNjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDEyLmFicnVwdChcInJldHVyblwiLCBwYWdlUmVzdWx0cyhqc29uLmRhdGEsIG5leHRQYWdlLCBldGFnLCB0b3RhbFJlY29yZHMpKTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDY6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQWdncmVnYXRlIG5ldyByZXN1bHRzIHdpdGggcHJldmlvdXMgb25lc1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdHMgPSByZXN1bHRzLmNvbmNhdChqc29uLmRhdGEpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN1cnJlbnQgKz0gMTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghKGN1cnJlbnQgPj0gcGFnZXMgfHwgIW5leHRQYWdlKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX2NvbnRleHQxMi5uZXh0ID0gMTA7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQxMi5hYnJ1cHQoXCJyZXR1cm5cIiwgcGFnZVJlc3VsdHMocmVzdWx0cywgbmV4dFBhZ2UsIGV0YWcsIHRvdGFsUmVjb3JkcykpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMTA6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0MTIuYWJydXB0KFwicmV0dXJuXCIsIHByb2Nlc3NOZXh0UGFnZShuZXh0UGFnZSkpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMTE6XG4gICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgXCJlbmRcIjpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQxMi5zdG9wKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9LCBfY2FsbGVlMTIsIHRoaXMpO1xuICAgICAgICAgICAgICAgICAgfSkpO1xuXG4gICAgICAgICAgICAgICAgICByZXR1cm4gZnVuY3Rpb24gaGFuZGxlUmVzcG9uc2UoX3g5KSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBfcmVmOS5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICB9KCk7XG5cbiAgICAgICAgICAgICAgICBfY29udGV4dDEzLnQwID0gaGFuZGxlUmVzcG9uc2U7XG4gICAgICAgICAgICAgICAgX2NvbnRleHQxMy5uZXh0ID0gMTM7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZXhlY3V0ZSggLy8gTi5CLjogVGhpcyBkb2Vzbid0IHVzZSBfZ2V0SGVhZGVycywgYmVjYXVzZSBhbGwgY2FsbHMgdG9cbiAgICAgICAgICAgICAgICAvLyBgcGFnaW5hdGVkTGlzdGAgYXJlIGFzc3VtZWQgdG8gY29tZSBmcm9tIGNhbGxzIHRoYXQgYWxyZWFkeVxuICAgICAgICAgICAgICAgIC8vIGhhdmUgaGVhZGVycyBtZXJnZWQgYXQgZS5nLiB0aGUgYnVja2V0IG9yIGNvbGxlY3Rpb24gbGV2ZWwuXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgaGVhZGVyczogb3B0aW9ucy5oZWFkZXJzLFxuICAgICAgICAgICAgICAgICAgcGF0aDogcGF0aCArIFwiP1wiICsgcXVlcnlzdHJpbmdcbiAgICAgICAgICAgICAgICB9LCAvLyBOLkIuIFRoaXMgZG9lc24ndCB1c2UgX2dldFJldHJ5LCBiZWNhdXNlIGFsbCBjYWxscyB0b1xuICAgICAgICAgICAgICAgIC8vIGBwYWdpbmF0ZWRMaXN0YCBhcmUgYXNzdW1lZCB0byBjb21lIGZyb20gY2FsbHMgdGhhdCBhbHJlYWR5XG4gICAgICAgICAgICAgICAgLy8gdXNlZCBgX2dldFJldHJ5YCBhdCBlLmcuIHRoZSBidWNrZXQgb3IgY29sbGVjdGlvbiBsZXZlbC5cbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICByYXc6IHRydWUsXG4gICAgICAgICAgICAgICAgICByZXRyeTogb3B0aW9ucy5yZXRyeSB8fCAwXG4gICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgY2FzZSAxMzpcbiAgICAgICAgICAgICAgICBfY29udGV4dDEzLnQxID0gX2NvbnRleHQxMy5zZW50O1xuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDEzLmFicnVwdChcInJldHVyblwiLCAoMCwgX2NvbnRleHQxMy50MCkoX2NvbnRleHQxMy50MSkpO1xuXG4gICAgICAgICAgICAgIGNhc2UgMTU6XG4gICAgICAgICAgICAgIGNhc2UgXCJlbmRcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQxMy5zdG9wKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9LCBfY2FsbGVlMTMsIHRoaXMpO1xuICAgICAgfSkpO1xuXG4gICAgICByZXR1cm4gZnVuY3Rpb24gcGFnaW5hdGVkTGlzdChfeDUsIF94Nikge1xuICAgICAgICByZXR1cm4gX3BhZ2luYXRlZExpc3QuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgIH07XG4gICAgfSgpXG4gICAgLyoqXG4gICAgICogTGlzdHMgYWxsIHBlcm1pc3Npb25zLlxuICAgICAqXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSBbb3B0aW9ucz17fV0gICAgICBUaGUgb3B0aW9ucyBvYmplY3QuXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSBbb3B0aW9ucy5oZWFkZXJzPXt9XSBIZWFkZXJzIHRvIHVzZSB3aGVuIG1ha2luZ1xuICAgICAqICAgICB0aGlzIHJlcXVlc3QuXG4gICAgICogQHBhcmFtICB7TnVtYmVyfSBbb3B0aW9ucy5yZXRyeT0wXSAgICBOdW1iZXIgb2YgcmV0cmllcyB0byBtYWtlXG4gICAgICogICAgIHdoZW4gZmFjZWQgd2l0aCB0cmFuc2llbnQgZXJyb3JzLlxuICAgICAqIEByZXR1cm4ge1Byb21pc2U8T2JqZWN0W10sIEVycm9yPn1cbiAgICAgKi9cblxuICB9LCB7XG4gICAga2V5OiBcImxpc3RQZXJtaXNzaW9uc1wiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgX2xpc3RQZXJtaXNzaW9ucyA9ICgwLCBfYXN5bmNUb0dlbmVyYXRvcjIuZGVmYXVsdCkoXG4gICAgICAvKiNfX1BVUkVfXyovXG4gICAgICBfcmVnZW5lcmF0b3IuZGVmYXVsdC5tYXJrKGZ1bmN0aW9uIF9jYWxsZWUxNCgpIHtcbiAgICAgICAgdmFyIG9wdGlvbnMsXG4gICAgICAgICAgICBwYXRoLFxuICAgICAgICAgICAgcGFnaW5hdGlvbk9wdGlvbnMsXG4gICAgICAgICAgICBfYXJnczE0ID0gYXJndW1lbnRzO1xuICAgICAgICByZXR1cm4gX3JlZ2VuZXJhdG9yLmRlZmF1bHQud3JhcChmdW5jdGlvbiBfY2FsbGVlMTQkKF9jb250ZXh0MTQpIHtcbiAgICAgICAgICB3aGlsZSAoMSkge1xuICAgICAgICAgICAgc3dpdGNoIChfY29udGV4dDE0LnByZXYgPSBfY29udGV4dDE0Lm5leHQpIHtcbiAgICAgICAgICAgICAgY2FzZSAwOlxuICAgICAgICAgICAgICAgIG9wdGlvbnMgPSBfYXJnczE0Lmxlbmd0aCA+IDAgJiYgX2FyZ3MxNFswXSAhPT0gdW5kZWZpbmVkID8gX2FyZ3MxNFswXSA6IHt9O1xuICAgICAgICAgICAgICAgIHBhdGggPSAoMCwgX2VuZHBvaW50LmRlZmF1bHQpKFwicGVybWlzc2lvbnNcIik7IC8vIEVuc3VyZSB0aGUgZGVmYXVsdCBzb3J0IHBhcmFtZXRlciBpcyBzb21ldGhpbmcgdGhhdCBleGlzdHMgaW4gcGVybWlzc2lvbnNcbiAgICAgICAgICAgICAgICAvLyBlbnRyaWVzLCBhcyBgbGFzdF9tb2RpZmllZGAgZG9lc24ndDsgaGVyZSwgd2UgcGljayBcImlkXCIuXG5cbiAgICAgICAgICAgICAgICBwYWdpbmF0aW9uT3B0aW9ucyA9ICgwLCBfb2JqZWN0U3ByZWFkMi5kZWZhdWx0KSh7XG4gICAgICAgICAgICAgICAgICBzb3J0OiBcImlkXCJcbiAgICAgICAgICAgICAgICB9LCBvcHRpb25zKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQxNC5hYnJ1cHQoXCJyZXR1cm5cIiwgdGhpcy5wYWdpbmF0ZWRMaXN0KHBhdGgsIHBhZ2luYXRpb25PcHRpb25zLCB7XG4gICAgICAgICAgICAgICAgICBoZWFkZXJzOiB0aGlzLl9nZXRIZWFkZXJzKG9wdGlvbnMpLFxuICAgICAgICAgICAgICAgICAgcmV0cnk6IHRoaXMuX2dldFJldHJ5KG9wdGlvbnMpXG4gICAgICAgICAgICAgICAgfSkpO1xuXG4gICAgICAgICAgICAgIGNhc2UgNDpcbiAgICAgICAgICAgICAgY2FzZSBcImVuZFwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDE0LnN0b3AoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0sIF9jYWxsZWUxNCwgdGhpcyk7XG4gICAgICB9KSk7XG5cbiAgICAgIHJldHVybiBmdW5jdGlvbiBsaXN0UGVybWlzc2lvbnMoKSB7XG4gICAgICAgIHJldHVybiBfbGlzdFBlcm1pc3Npb25zLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICB9O1xuICAgIH0oKVxuICAgIC8qKlxuICAgICAqIFJldHJpZXZlcyB0aGUgbGlzdCBvZiBidWNrZXRzLlxuICAgICAqXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSBbb3B0aW9ucz17fV0gICAgICBUaGUgb3B0aW9ucyBvYmplY3QuXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSBbb3B0aW9ucy5oZWFkZXJzPXt9XSBIZWFkZXJzIHRvIHVzZSB3aGVuIG1ha2luZ1xuICAgICAqICAgICB0aGlzIHJlcXVlc3QuXG4gICAgICogQHBhcmFtICB7TnVtYmVyfSBbb3B0aW9ucy5yZXRyeT0wXSAgICBOdW1iZXIgb2YgcmV0cmllcyB0byBtYWtlXG4gICAgICogICAgIHdoZW4gZmFjZWQgd2l0aCB0cmFuc2llbnQgZXJyb3JzLlxuICAgICAqIEByZXR1cm4ge1Byb21pc2U8T2JqZWN0W10sIEVycm9yPn1cbiAgICAgKi9cblxuICB9LCB7XG4gICAga2V5OiBcImxpc3RCdWNrZXRzXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciBfbGlzdEJ1Y2tldHMgPSAoMCwgX2FzeW5jVG9HZW5lcmF0b3IyLmRlZmF1bHQpKFxuICAgICAgLyojX19QVVJFX18qL1xuICAgICAgX3JlZ2VuZXJhdG9yLmRlZmF1bHQubWFyayhmdW5jdGlvbiBfY2FsbGVlMTUoKSB7XG4gICAgICAgIHZhciBvcHRpb25zLFxuICAgICAgICAgICAgcGF0aCxcbiAgICAgICAgICAgIF9hcmdzMTUgPSBhcmd1bWVudHM7XG4gICAgICAgIHJldHVybiBfcmVnZW5lcmF0b3IuZGVmYXVsdC53cmFwKGZ1bmN0aW9uIF9jYWxsZWUxNSQoX2NvbnRleHQxNSkge1xuICAgICAgICAgIHdoaWxlICgxKSB7XG4gICAgICAgICAgICBzd2l0Y2ggKF9jb250ZXh0MTUucHJldiA9IF9jb250ZXh0MTUubmV4dCkge1xuICAgICAgICAgICAgICBjYXNlIDA6XG4gICAgICAgICAgICAgICAgb3B0aW9ucyA9IF9hcmdzMTUubGVuZ3RoID4gMCAmJiBfYXJnczE1WzBdICE9PSB1bmRlZmluZWQgPyBfYXJnczE1WzBdIDoge307XG4gICAgICAgICAgICAgICAgcGF0aCA9ICgwLCBfZW5kcG9pbnQuZGVmYXVsdCkoXCJidWNrZXRcIik7XG4gICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0MTUuYWJydXB0KFwicmV0dXJuXCIsIHRoaXMucGFnaW5hdGVkTGlzdChwYXRoLCBvcHRpb25zLCB7XG4gICAgICAgICAgICAgICAgICBoZWFkZXJzOiB0aGlzLl9nZXRIZWFkZXJzKG9wdGlvbnMpLFxuICAgICAgICAgICAgICAgICAgcmV0cnk6IHRoaXMuX2dldFJldHJ5KG9wdGlvbnMpXG4gICAgICAgICAgICAgICAgfSkpO1xuXG4gICAgICAgICAgICAgIGNhc2UgMzpcbiAgICAgICAgICAgICAgY2FzZSBcImVuZFwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDE1LnN0b3AoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0sIF9jYWxsZWUxNSwgdGhpcyk7XG4gICAgICB9KSk7XG5cbiAgICAgIHJldHVybiBmdW5jdGlvbiBsaXN0QnVja2V0cygpIHtcbiAgICAgICAgcmV0dXJuIF9saXN0QnVja2V0cy5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgfTtcbiAgICB9KClcbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgbmV3IGJ1Y2tldCBvbiB0aGUgc2VydmVyLlxuICAgICAqXG4gICAgICogQHBhcmFtICB7U3RyaW5nfG51bGx9ICBpZCAgICAgICAgICAgICAgICBUaGUgYnVja2V0IG5hbWUgKG9wdGlvbmFsKS5cbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9ICAgICAgIFtvcHRpb25zPXt9XSAgICAgIFRoZSBvcHRpb25zIG9iamVjdC5cbiAgICAgKiBAcGFyYW0gIHtCb29sZWFufSAgICAgIFtvcHRpb25zLmRhdGFdICAgIFRoZSBidWNrZXQgZGF0YSBvcHRpb24uXG4gICAgICogQHBhcmFtICB7Qm9vbGVhbn0gICAgICBbb3B0aW9ucy5zYWZlXSAgICBUaGUgc2FmZSBvcHRpb24uXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSAgICAgICBbb3B0aW9ucy5oZWFkZXJzXSBUaGUgaGVhZGVycyBvYmplY3Qgb3B0aW9uLlxuICAgICAqIEBwYXJhbSAge051bWJlcn0gICAgICAgW29wdGlvbnMucmV0cnk9MF0gTnVtYmVyIG9mIHJldHJpZXMgdG8gbWFrZVxuICAgICAqICAgICB3aGVuIGZhY2VkIHdpdGggdHJhbnNpZW50IGVycm9ycy5cbiAgICAgKiBAcmV0dXJuIHtQcm9taXNlPE9iamVjdCwgRXJyb3I+fVxuICAgICAqL1xuXG4gIH0sIHtcbiAgICBrZXk6IFwiY3JlYXRlQnVja2V0XCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciBfY3JlYXRlQnVja2V0ID0gKDAsIF9hc3luY1RvR2VuZXJhdG9yMi5kZWZhdWx0KShcbiAgICAgIC8qI19fUFVSRV9fKi9cbiAgICAgIF9yZWdlbmVyYXRvci5kZWZhdWx0Lm1hcmsoZnVuY3Rpb24gX2NhbGxlZTE2KGlkKSB7XG4gICAgICAgIHZhciBvcHRpb25zLFxuICAgICAgICAgICAgX29wdGlvbnMkZGF0YSxcbiAgICAgICAgICAgIGRhdGEsXG4gICAgICAgICAgICBwZXJtaXNzaW9ucyxcbiAgICAgICAgICAgIHBhdGgsXG4gICAgICAgICAgICBfYXJnczE2ID0gYXJndW1lbnRzO1xuXG4gICAgICAgIHJldHVybiBfcmVnZW5lcmF0b3IuZGVmYXVsdC53cmFwKGZ1bmN0aW9uIF9jYWxsZWUxNiQoX2NvbnRleHQxNikge1xuICAgICAgICAgIHdoaWxlICgxKSB7XG4gICAgICAgICAgICBzd2l0Y2ggKF9jb250ZXh0MTYucHJldiA9IF9jb250ZXh0MTYubmV4dCkge1xuICAgICAgICAgICAgICBjYXNlIDA6XG4gICAgICAgICAgICAgICAgb3B0aW9ucyA9IF9hcmdzMTYubGVuZ3RoID4gMSAmJiBfYXJnczE2WzFdICE9PSB1bmRlZmluZWQgPyBfYXJnczE2WzFdIDoge307XG4gICAgICAgICAgICAgICAgX29wdGlvbnMkZGF0YSA9IG9wdGlvbnMuZGF0YSwgZGF0YSA9IF9vcHRpb25zJGRhdGEgPT09IHZvaWQgMCA/IHt9IDogX29wdGlvbnMkZGF0YSwgcGVybWlzc2lvbnMgPSBvcHRpb25zLnBlcm1pc3Npb25zO1xuXG4gICAgICAgICAgICAgICAgaWYgKGlkICE9IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgIGRhdGEuaWQgPSBpZDtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBwYXRoID0gZGF0YS5pZCA/ICgwLCBfZW5kcG9pbnQuZGVmYXVsdCkoXCJidWNrZXRcIiwgZGF0YS5pZCkgOiAoMCwgX2VuZHBvaW50LmRlZmF1bHQpKFwiYnVja2V0XCIpO1xuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDE2LmFicnVwdChcInJldHVyblwiLCB0aGlzLmV4ZWN1dGUocmVxdWVzdHMuY3JlYXRlUmVxdWVzdChwYXRoLCB7XG4gICAgICAgICAgICAgICAgICBkYXRhOiBkYXRhLFxuICAgICAgICAgICAgICAgICAgcGVybWlzc2lvbnM6IHBlcm1pc3Npb25zXG4gICAgICAgICAgICAgICAgfSwge1xuICAgICAgICAgICAgICAgICAgaGVhZGVyczogdGhpcy5fZ2V0SGVhZGVycyhvcHRpb25zKSxcbiAgICAgICAgICAgICAgICAgIHNhZmU6IHRoaXMuX2dldFNhZmUob3B0aW9ucylcbiAgICAgICAgICAgICAgICB9KSwge1xuICAgICAgICAgICAgICAgICAgcmV0cnk6IHRoaXMuX2dldFJldHJ5KG9wdGlvbnMpXG4gICAgICAgICAgICAgICAgfSkpO1xuXG4gICAgICAgICAgICAgIGNhc2UgNTpcbiAgICAgICAgICAgICAgY2FzZSBcImVuZFwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDE2LnN0b3AoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0sIF9jYWxsZWUxNiwgdGhpcyk7XG4gICAgICB9KSk7XG5cbiAgICAgIHJldHVybiBmdW5jdGlvbiBjcmVhdGVCdWNrZXQoX3gxMCkge1xuICAgICAgICByZXR1cm4gX2NyZWF0ZUJ1Y2tldC5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgfTtcbiAgICB9KClcbiAgICAvKipcbiAgICAgKiBEZWxldGVzIGEgYnVja2V0IGZyb20gdGhlIHNlcnZlci5cbiAgICAgKlxuICAgICAqIEBpZ25vcmVcbiAgICAgKiBAcGFyYW0gIHtPYmplY3R8U3RyaW5nfSBidWNrZXQgICAgICAgICAgICAgICAgICBUaGUgYnVja2V0IHRvIGRlbGV0ZS5cbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9ICAgICAgICBbb3B0aW9ucz17fV0gICAgICAgICAgICBUaGUgb3B0aW9ucyBvYmplY3QuXG4gICAgICogQHBhcmFtICB7Qm9vbGVhbn0gICAgICAgW29wdGlvbnMuc2FmZV0gICAgICAgICAgVGhlIHNhZmUgb3B0aW9uLlxuICAgICAqIEBwYXJhbSAge09iamVjdH0gICAgICAgIFtvcHRpb25zLmhlYWRlcnNdICAgICAgIFRoZSBoZWFkZXJzIG9iamVjdCBvcHRpb24uXG4gICAgICogQHBhcmFtICB7TnVtYmVyfSAgICAgICAgW29wdGlvbnMucmV0cnk9MF0gICAgICAgTnVtYmVyIG9mIHJldHJpZXMgdG8gbWFrZVxuICAgICAqICAgICB3aGVuIGZhY2VkIHdpdGggdHJhbnNpZW50IGVycm9ycy5cbiAgICAgKiBAcGFyYW0gIHtOdW1iZXJ9ICAgICAgICBbb3B0aW9ucy5sYXN0X21vZGlmaWVkXSBUaGUgbGFzdF9tb2RpZmllZCBvcHRpb24uXG4gICAgICogQHJldHVybiB7UHJvbWlzZTxPYmplY3QsIEVycm9yPn1cbiAgICAgKi9cblxuICB9LCB7XG4gICAga2V5OiBcImRlbGV0ZUJ1Y2tldFwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgX2RlbGV0ZUJ1Y2tldCA9ICgwLCBfYXN5bmNUb0dlbmVyYXRvcjIuZGVmYXVsdCkoXG4gICAgICAvKiNfX1BVUkVfXyovXG4gICAgICBfcmVnZW5lcmF0b3IuZGVmYXVsdC5tYXJrKGZ1bmN0aW9uIF9jYWxsZWUxNyhidWNrZXQpIHtcbiAgICAgICAgdmFyIG9wdGlvbnMsXG4gICAgICAgICAgICBidWNrZXRPYmosXG4gICAgICAgICAgICBwYXRoLFxuICAgICAgICAgICAgX2J1Y2tldE9iaiRvcHRpb25zLFxuICAgICAgICAgICAgbGFzdF9tb2RpZmllZCxcbiAgICAgICAgICAgIF9hcmdzMTcgPSBhcmd1bWVudHM7XG5cbiAgICAgICAgcmV0dXJuIF9yZWdlbmVyYXRvci5kZWZhdWx0LndyYXAoZnVuY3Rpb24gX2NhbGxlZTE3JChfY29udGV4dDE3KSB7XG4gICAgICAgICAgd2hpbGUgKDEpIHtcbiAgICAgICAgICAgIHN3aXRjaCAoX2NvbnRleHQxNy5wcmV2ID0gX2NvbnRleHQxNy5uZXh0KSB7XG4gICAgICAgICAgICAgIGNhc2UgMDpcbiAgICAgICAgICAgICAgICBvcHRpb25zID0gX2FyZ3MxNy5sZW5ndGggPiAxICYmIF9hcmdzMTdbMV0gIT09IHVuZGVmaW5lZCA/IF9hcmdzMTdbMV0gOiB7fTtcbiAgICAgICAgICAgICAgICBidWNrZXRPYmogPSAoMCwgX3V0aWxzLnRvRGF0YUJvZHkpKGJ1Y2tldCk7XG5cbiAgICAgICAgICAgICAgICBpZiAoYnVja2V0T2JqLmlkKSB7XG4gICAgICAgICAgICAgICAgICBfY29udGV4dDE3Lm5leHQgPSA0O1xuICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQSBidWNrZXQgaWQgaXMgcmVxdWlyZWQuXCIpO1xuXG4gICAgICAgICAgICAgIGNhc2UgNDpcbiAgICAgICAgICAgICAgICBwYXRoID0gKDAsIF9lbmRwb2ludC5kZWZhdWx0KShcImJ1Y2tldFwiLCBidWNrZXRPYmouaWQpO1xuICAgICAgICAgICAgICAgIF9idWNrZXRPYmokb3B0aW9ucyA9ICgwLCBfb2JqZWN0U3ByZWFkMi5kZWZhdWx0KSh7fSwgYnVja2V0T2JqLCBvcHRpb25zKSwgbGFzdF9tb2RpZmllZCA9IF9idWNrZXRPYmokb3B0aW9ucy5sYXN0X21vZGlmaWVkO1xuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDE3LmFicnVwdChcInJldHVyblwiLCB0aGlzLmV4ZWN1dGUocmVxdWVzdHMuZGVsZXRlUmVxdWVzdChwYXRoLCB7XG4gICAgICAgICAgICAgICAgICBsYXN0X21vZGlmaWVkOiBsYXN0X21vZGlmaWVkLFxuICAgICAgICAgICAgICAgICAgaGVhZGVyczogdGhpcy5fZ2V0SGVhZGVycyhvcHRpb25zKSxcbiAgICAgICAgICAgICAgICAgIHNhZmU6IHRoaXMuX2dldFNhZmUob3B0aW9ucylcbiAgICAgICAgICAgICAgICB9KSwge1xuICAgICAgICAgICAgICAgICAgcmV0cnk6IHRoaXMuX2dldFJldHJ5KG9wdGlvbnMpXG4gICAgICAgICAgICAgICAgfSkpO1xuXG4gICAgICAgICAgICAgIGNhc2UgNzpcbiAgICAgICAgICAgICAgY2FzZSBcImVuZFwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDE3LnN0b3AoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0sIF9jYWxsZWUxNywgdGhpcyk7XG4gICAgICB9KSk7XG5cbiAgICAgIHJldHVybiBmdW5jdGlvbiBkZWxldGVCdWNrZXQoX3gxMSkge1xuICAgICAgICByZXR1cm4gX2RlbGV0ZUJ1Y2tldC5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgfTtcbiAgICB9KClcbiAgICAvKipcbiAgICAgKiBEZWxldGVzIGFsbCBidWNrZXRzIG9uIHRoZSBzZXJ2ZXIuXG4gICAgICpcbiAgICAgKiBAaWdub3JlXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSAgW29wdGlvbnM9e31dICAgICAgICAgICAgVGhlIG9wdGlvbnMgb2JqZWN0LlxuICAgICAqIEBwYXJhbSAge0Jvb2xlYW59IFtvcHRpb25zLnNhZmVdICAgICAgICAgIFRoZSBzYWZlIG9wdGlvbi5cbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9ICBbb3B0aW9ucy5oZWFkZXJzXSAgICAgICBUaGUgaGVhZGVycyBvYmplY3Qgb3B0aW9uLlxuICAgICAqIEBwYXJhbSAge051bWJlcn0gIFtvcHRpb25zLmxhc3RfbW9kaWZpZWRdIFRoZSBsYXN0X21vZGlmaWVkIG9wdGlvbi5cbiAgICAgKiBAcmV0dXJuIHtQcm9taXNlPE9iamVjdCwgRXJyb3I+fVxuICAgICAqL1xuXG4gIH0sIHtcbiAgICBrZXk6IFwiZGVsZXRlQnVja2V0c1wiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgX2RlbGV0ZUJ1Y2tldHMgPSAoMCwgX2FzeW5jVG9HZW5lcmF0b3IyLmRlZmF1bHQpKFxuICAgICAgLyojX19QVVJFX18qL1xuICAgICAgX3JlZ2VuZXJhdG9yLmRlZmF1bHQubWFyayhmdW5jdGlvbiBfY2FsbGVlMTgoKSB7XG4gICAgICAgIHZhciBvcHRpb25zLFxuICAgICAgICAgICAgcGF0aCxcbiAgICAgICAgICAgIF9hcmdzMTggPSBhcmd1bWVudHM7XG4gICAgICAgIHJldHVybiBfcmVnZW5lcmF0b3IuZGVmYXVsdC53cmFwKGZ1bmN0aW9uIF9jYWxsZWUxOCQoX2NvbnRleHQxOCkge1xuICAgICAgICAgIHdoaWxlICgxKSB7XG4gICAgICAgICAgICBzd2l0Y2ggKF9jb250ZXh0MTgucHJldiA9IF9jb250ZXh0MTgubmV4dCkge1xuICAgICAgICAgICAgICBjYXNlIDA6XG4gICAgICAgICAgICAgICAgb3B0aW9ucyA9IF9hcmdzMTgubGVuZ3RoID4gMCAmJiBfYXJnczE4WzBdICE9PSB1bmRlZmluZWQgPyBfYXJnczE4WzBdIDoge307XG4gICAgICAgICAgICAgICAgcGF0aCA9ICgwLCBfZW5kcG9pbnQuZGVmYXVsdCkoXCJidWNrZXRcIik7XG4gICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0MTguYWJydXB0KFwicmV0dXJuXCIsIHRoaXMuZXhlY3V0ZShyZXF1ZXN0cy5kZWxldGVSZXF1ZXN0KHBhdGgsIHtcbiAgICAgICAgICAgICAgICAgIGxhc3RfbW9kaWZpZWQ6IG9wdGlvbnMubGFzdF9tb2RpZmllZCxcbiAgICAgICAgICAgICAgICAgIGhlYWRlcnM6IHRoaXMuX2dldEhlYWRlcnMob3B0aW9ucyksXG4gICAgICAgICAgICAgICAgICBzYWZlOiB0aGlzLl9nZXRTYWZlKG9wdGlvbnMpXG4gICAgICAgICAgICAgICAgfSksIHtcbiAgICAgICAgICAgICAgICAgIHJldHJ5OiB0aGlzLl9nZXRSZXRyeShvcHRpb25zKVxuICAgICAgICAgICAgICAgIH0pKTtcblxuICAgICAgICAgICAgICBjYXNlIDM6XG4gICAgICAgICAgICAgIGNhc2UgXCJlbmRcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQxOC5zdG9wKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9LCBfY2FsbGVlMTgsIHRoaXMpO1xuICAgICAgfSkpO1xuXG4gICAgICByZXR1cm4gZnVuY3Rpb24gZGVsZXRlQnVja2V0cygpIHtcbiAgICAgICAgcmV0dXJuIF9kZWxldGVCdWNrZXRzLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICB9O1xuICAgIH0oKVxuICB9LCB7XG4gICAga2V5OiBcInJlbW90ZVwiLFxuICAgIGdldDogZnVuY3Rpb24gZ2V0KCkge1xuICAgICAgcmV0dXJuIHRoaXMuX3JlbW90ZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQGlnbm9yZVxuICAgICAqL1xuICAgICxcbiAgICBzZXQ6IGZ1bmN0aW9uIHNldCh1cmwpIHtcbiAgICAgIHZhciB2ZXJzaW9uO1xuXG4gICAgICB0cnkge1xuICAgICAgICB2ZXJzaW9uID0gdXJsLm1hdGNoKC9cXC8odlxcZCspXFwvPyQvKVsxXTtcbiAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJUaGUgcmVtb3RlIFVSTCBtdXN0IGNvbnRhaW4gdGhlIHZlcnNpb246IFwiICsgdXJsKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHZlcnNpb24gIT09IFNVUFBPUlRFRF9QUk9UT0NPTF9WRVJTSU9OKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIlVuc3VwcG9ydGVkIHByb3RvY29sIHZlcnNpb246IFwiLmNvbmNhdCh2ZXJzaW9uKSk7XG4gICAgICB9XG5cbiAgICAgIHRoaXMuX3JlbW90ZSA9IHVybDtcbiAgICAgIHRoaXMuX3ZlcnNpb24gPSB2ZXJzaW9uO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBUaGUgY3VycmVudCBzZXJ2ZXIgcHJvdG9jb2wgdmVyc2lvbiwgZWcuIGB2MWAuXG4gICAgICogQHR5cGUge1N0cmluZ31cbiAgICAgKi9cblxuICB9LCB7XG4gICAga2V5OiBcInZlcnNpb25cIixcbiAgICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHtcbiAgICAgIHJldHVybiB0aGlzLl92ZXJzaW9uO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBCYWNrb2ZmIHJlbWFpbmluZyB0aW1lLCBpbiBtaWxsaXNlY29uZHMuIERlZmF1bHRzIHRvIHplcm8gaWYgbm8gYmFja29mZiBpc1xuICAgICAqIG9uZ29pbmcuXG4gICAgICpcbiAgICAgKiBAdHlwZSB7TnVtYmVyfVxuICAgICAqL1xuXG4gIH0sIHtcbiAgICBrZXk6IFwiYmFja29mZlwiLFxuICAgIGdldDogZnVuY3Rpb24gZ2V0KCkge1xuICAgICAgdmFyIGN1cnJlbnRUaW1lID0gbmV3IERhdGUoKS5nZXRUaW1lKCk7XG5cbiAgICAgIGlmICh0aGlzLl9iYWNrb2ZmUmVsZWFzZVRpbWUgJiYgY3VycmVudFRpbWUgPCB0aGlzLl9iYWNrb2ZmUmVsZWFzZVRpbWUpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2JhY2tvZmZSZWxlYXNlVGltZSAtIGN1cnJlbnRUaW1lO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gMDtcbiAgICB9XG4gIH1dKTtcbiAgcmV0dXJuIEtpbnRvQ2xpZW50QmFzZTtcbn0oKSwgKCgwLCBfYXBwbHlEZWNvcmF0ZWREZXNjcmlwdG9yMi5kZWZhdWx0KShfY2xhc3MucHJvdG90eXBlLCBcImZldGNoU2VydmVyU2V0dGluZ3NcIiwgW19kZWNdLCBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKF9jbGFzcy5wcm90b3R5cGUsIFwiZmV0Y2hTZXJ2ZXJTZXR0aW5nc1wiKSwgX2NsYXNzLnByb3RvdHlwZSksICgwLCBfYXBwbHlEZWNvcmF0ZWREZXNjcmlwdG9yMi5kZWZhdWx0KShfY2xhc3MucHJvdG90eXBlLCBcImZldGNoU2VydmVyQ2FwYWJpbGl0aWVzXCIsIFtfZGVjMl0sIE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IoX2NsYXNzLnByb3RvdHlwZSwgXCJmZXRjaFNlcnZlckNhcGFiaWxpdGllc1wiKSwgX2NsYXNzLnByb3RvdHlwZSksICgwLCBfYXBwbHlEZWNvcmF0ZWREZXNjcmlwdG9yMi5kZWZhdWx0KShfY2xhc3MucHJvdG90eXBlLCBcImZldGNoVXNlclwiLCBbX2RlYzNdLCBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKF9jbGFzcy5wcm90b3R5cGUsIFwiZmV0Y2hVc2VyXCIpLCBfY2xhc3MucHJvdG90eXBlKSwgKDAsIF9hcHBseURlY29yYXRlZERlc2NyaXB0b3IyLmRlZmF1bHQpKF9jbGFzcy5wcm90b3R5cGUsIFwiZmV0Y2hIVFRQQXBpVmVyc2lvblwiLCBbX2RlYzRdLCBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKF9jbGFzcy5wcm90b3R5cGUsIFwiZmV0Y2hIVFRQQXBpVmVyc2lvblwiKSwgX2NsYXNzLnByb3RvdHlwZSksICgwLCBfYXBwbHlEZWNvcmF0ZWREZXNjcmlwdG9yMi5kZWZhdWx0KShfY2xhc3MucHJvdG90eXBlLCBcImJhdGNoXCIsIFtfZGVjNV0sIE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IoX2NsYXNzLnByb3RvdHlwZSwgXCJiYXRjaFwiKSwgX2NsYXNzLnByb3RvdHlwZSksICgwLCBfYXBwbHlEZWNvcmF0ZWREZXNjcmlwdG9yMi5kZWZhdWx0KShfY2xhc3MucHJvdG90eXBlLCBcImxpc3RQZXJtaXNzaW9uc1wiLCBbX2RlYzZdLCBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKF9jbGFzcy5wcm90b3R5cGUsIFwibGlzdFBlcm1pc3Npb25zXCIpLCBfY2xhc3MucHJvdG90eXBlKSwgKDAsIF9hcHBseURlY29yYXRlZERlc2NyaXB0b3IyLmRlZmF1bHQpKF9jbGFzcy5wcm90b3R5cGUsIFwiZGVsZXRlQnVja2V0c1wiLCBbX2RlYzddLCBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKF9jbGFzcy5wcm90b3R5cGUsIFwiZGVsZXRlQnVja2V0c1wiKSwgX2NsYXNzLnByb3RvdHlwZSkpLCBfY2xhc3MpKTtcbmV4cG9ydHMuZGVmYXVsdCA9IEtpbnRvQ2xpZW50QmFzZTsiLCJcInVzZSBzdHJpY3RcIjtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG4gIHZhbHVlOiB0cnVlXG59KTtcbmV4cG9ydHMuYWdncmVnYXRlID0gYWdncmVnYXRlO1xuXG4vKipcbiAqIEV4cG9ydHMgYmF0Y2ggcmVzcG9uc2VzIGFzIGEgcmVzdWx0IG9iamVjdC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtICB7QXJyYXl9IHJlc3BvbnNlcyBUaGUgYmF0Y2ggc3VicmVxdWVzdCByZXNwb25zZXMuXG4gKiBAcGFyYW0gIHtBcnJheX0gcmVxdWVzdHMgIFRoZSBpbml0aWFsIGlzc3VlZCByZXF1ZXN0cy5cbiAqIEByZXR1cm4ge09iamVjdH1cbiAqL1xuZnVuY3Rpb24gYWdncmVnYXRlKCkge1xuICB2YXIgcmVzcG9uc2VzID0gYXJndW1lbnRzLmxlbmd0aCA+IDAgJiYgYXJndW1lbnRzWzBdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMF0gOiBbXTtcbiAgdmFyIHJlcXVlc3RzID0gYXJndW1lbnRzLmxlbmd0aCA+IDEgJiYgYXJndW1lbnRzWzFdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMV0gOiBbXTtcblxuICBpZiAocmVzcG9uc2VzLmxlbmd0aCAhPT0gcmVxdWVzdHMubGVuZ3RoKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFwiUmVzcG9uc2VzIGxlbmd0aCBzaG91bGQgbWF0Y2ggcmVxdWVzdHMgb25lLlwiKTtcbiAgfVxuXG4gIHZhciByZXN1bHRzID0ge1xuICAgIGVycm9yczogW10sXG4gICAgcHVibGlzaGVkOiBbXSxcbiAgICBjb25mbGljdHM6IFtdLFxuICAgIHNraXBwZWQ6IFtdXG4gIH07XG4gIHJldHVybiByZXNwb25zZXMucmVkdWNlKGZ1bmN0aW9uIChhY2MsIHJlc3BvbnNlLCBpbmRleCkge1xuICAgIHZhciBzdGF0dXMgPSByZXNwb25zZS5zdGF0dXM7XG4gICAgdmFyIHJlcXVlc3QgPSByZXF1ZXN0c1tpbmRleF07XG5cbiAgICBpZiAoc3RhdHVzID49IDIwMCAmJiBzdGF0dXMgPCA0MDApIHtcbiAgICAgIGFjYy5wdWJsaXNoZWQucHVzaChyZXNwb25zZS5ib2R5KTtcbiAgICB9IGVsc2UgaWYgKHN0YXR1cyA9PT0gNDA0KSB7XG4gICAgICAvLyBFeHRyYWN0IHRoZSBpZCBtYW51YWxseSBmcm9tIHJlcXVlc3QgcGF0aCB3aGlsZSB3YWl0aW5nIGZvciBLaW50by9raW50byM4MThcbiAgICAgIHZhciByZWdleCA9IC8oYnVja2V0c3xncm91cHN8Y29sbGVjdGlvbnN8cmVjb3JkcylcXC8oW14vXSspJC87XG4gICAgICB2YXIgZXh0cmFjdHMgPSByZXF1ZXN0LnBhdGgubWF0Y2gocmVnZXgpO1xuICAgICAgdmFyIGlkID0gZXh0cmFjdHMubGVuZ3RoID09PSAzID8gZXh0cmFjdHNbMl0gOiB1bmRlZmluZWQ7XG4gICAgICBhY2Muc2tpcHBlZC5wdXNoKHtcbiAgICAgICAgaWQ6IGlkLFxuICAgICAgICBwYXRoOiByZXF1ZXN0LnBhdGgsXG4gICAgICAgIGVycm9yOiByZXNwb25zZS5ib2R5XG4gICAgICB9KTtcbiAgICB9IGVsc2UgaWYgKHN0YXR1cyA9PT0gNDEyKSB7XG4gICAgICBhY2MuY29uZmxpY3RzLnB1c2goe1xuICAgICAgICAvLyBYWFg6IHNwZWNpZnlpbmcgdGhlIHR5cGUgaXMgcHJvYmFibHkgc3VwZXJmbHVvdXNcbiAgICAgICAgdHlwZTogXCJvdXRnb2luZ1wiLFxuICAgICAgICBsb2NhbDogcmVxdWVzdC5ib2R5LFxuICAgICAgICByZW1vdGU6IHJlc3BvbnNlLmJvZHkuZGV0YWlscyAmJiByZXNwb25zZS5ib2R5LmRldGFpbHMuZXhpc3RpbmcgfHwgbnVsbFxuICAgICAgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGFjYy5lcnJvcnMucHVzaCh7XG4gICAgICAgIHBhdGg6IHJlcXVlc3QucGF0aCxcbiAgICAgICAgc2VudDogcmVxdWVzdCxcbiAgICAgICAgZXJyb3I6IHJlc3BvbnNlLmJvZHlcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHJldHVybiBhY2M7XG4gIH0sIHJlc3VsdHMpO1xufSIsIlwidXNlIHN0cmljdFwiO1xuXG52YXIgX2ludGVyb3BSZXF1aXJlRGVmYXVsdCA9IHJlcXVpcmUoXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2ludGVyb3BSZXF1aXJlRGVmYXVsdFwiKTtcblxudmFyIF9pbnRlcm9wUmVxdWlyZVdpbGRjYXJkID0gcmVxdWlyZShcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvaW50ZXJvcFJlcXVpcmVXaWxkY2FyZFwiKTtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG4gIHZhbHVlOiB0cnVlXG59KTtcbmV4cG9ydHMuZGVmYXVsdCA9IHZvaWQgMDtcblxudmFyIF9yZWdlbmVyYXRvciA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQocmVxdWlyZShcIkBiYWJlbC9ydW50aW1lL3JlZ2VuZXJhdG9yXCIpKTtcblxudmFyIF9hc3luY1RvR2VuZXJhdG9yMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQocmVxdWlyZShcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvYXN5bmNUb0dlbmVyYXRvclwiKSk7XG5cbnZhciBfb2JqZWN0U3ByZWFkMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQocmVxdWlyZShcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvb2JqZWN0U3ByZWFkXCIpKTtcblxudmFyIF9jbGFzc0NhbGxDaGVjazIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KHJlcXVpcmUoXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2NsYXNzQ2FsbENoZWNrXCIpKTtcblxudmFyIF9jcmVhdGVDbGFzczIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KHJlcXVpcmUoXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2NyZWF0ZUNsYXNzXCIpKTtcblxudmFyIF9hcHBseURlY29yYXRlZERlc2NyaXB0b3IyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChyZXF1aXJlKFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9hcHBseURlY29yYXRlZERlc2NyaXB0b3JcIikpO1xuXG52YXIgX3V0aWxzID0gcmVxdWlyZShcIi4vdXRpbHNcIik7XG5cbnZhciBfY29sbGVjdGlvbiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQocmVxdWlyZShcIi4vY29sbGVjdGlvblwiKSk7XG5cbnZhciByZXF1ZXN0cyA9IF9pbnRlcm9wUmVxdWlyZVdpbGRjYXJkKHJlcXVpcmUoXCIuL3JlcXVlc3RzXCIpKTtcblxudmFyIF9lbmRwb2ludCA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQocmVxdWlyZShcIi4vZW5kcG9pbnRcIikpO1xuXG52YXIgX2RlYywgX2NsYXNzO1xuXG4vKipcbiAqIEFic3RyYWN0IHJlcHJlc2VudGF0aW9uIG9mIGEgc2VsZWN0ZWQgYnVja2V0LlxuICpcbiAqL1xudmFyIEJ1Y2tldCA9IChfZGVjID0gKDAsIF91dGlscy5jYXBhYmxlKShbXCJoaXN0b3J5XCJdKSwgKF9jbGFzcyA9XG4vKiNfX1BVUkVfXyovXG5mdW5jdGlvbiAoKSB7XG4gIC8qKlxuICAgKiBDb25zdHJ1Y3Rvci5cbiAgICpcbiAgICogQHBhcmFtICB7S2ludG9DbGllbnR9IGNsaWVudCAgICAgICAgICAgIFRoZSBjbGllbnQgaW5zdGFuY2UuXG4gICAqIEBwYXJhbSAge1N0cmluZ30gICAgICBuYW1lICAgICAgICAgICAgICBUaGUgYnVja2V0IG5hbWUuXG4gICAqIEBwYXJhbSAge09iamVjdH0gICAgICBbb3B0aW9ucz17fV0gICAgICBUaGUgaGVhZGVycyBvYmplY3Qgb3B0aW9uLlxuICAgKiBAcGFyYW0gIHtPYmplY3R9ICAgICAgW29wdGlvbnMuaGVhZGVyc10gVGhlIGhlYWRlcnMgb2JqZWN0IG9wdGlvbi5cbiAgICogQHBhcmFtICB7Qm9vbGVhbn0gICAgIFtvcHRpb25zLnNhZmVdICAgIFRoZSBzYWZlIG9wdGlvbi5cbiAgICogQHBhcmFtICB7TnVtYmVyfSAgICAgIFtvcHRpb25zLnJldHJ5XSAgIFRoZSByZXRyeSBvcHRpb24uXG4gICAqL1xuICBmdW5jdGlvbiBCdWNrZXQoY2xpZW50LCBuYW1lKSB7XG4gICAgdmFyIG9wdGlvbnMgPSBhcmd1bWVudHMubGVuZ3RoID4gMiAmJiBhcmd1bWVudHNbMl0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1syXSA6IHt9O1xuICAgICgwLCBfY2xhc3NDYWxsQ2hlY2syLmRlZmF1bHQpKHRoaXMsIEJ1Y2tldCk7XG5cbiAgICAvKipcbiAgICAgKiBAaWdub3JlXG4gICAgICovXG4gICAgdGhpcy5jbGllbnQgPSBjbGllbnQ7XG4gICAgLyoqXG4gICAgICogVGhlIGJ1Y2tldCBuYW1lLlxuICAgICAqIEB0eXBlIHtTdHJpbmd9XG4gICAgICovXG5cbiAgICB0aGlzLm5hbWUgPSBuYW1lO1xuICAgIC8qKlxuICAgICAqIEBpZ25vcmVcbiAgICAgKi9cblxuICAgIHRoaXMuX2lzQmF0Y2ggPSAhIW9wdGlvbnMuYmF0Y2g7XG4gICAgLyoqXG4gICAgICogQGlnbm9yZVxuICAgICAqL1xuXG4gICAgdGhpcy5faGVhZGVycyA9IG9wdGlvbnMuaGVhZGVycyB8fCB7fTtcbiAgICB0aGlzLl9yZXRyeSA9IG9wdGlvbnMucmV0cnkgfHwgMDtcbiAgICB0aGlzLl9zYWZlID0gISFvcHRpb25zLnNhZmU7XG4gIH1cbiAgLyoqXG4gICAqIEdldCB0aGUgdmFsdWUgb2YgXCJoZWFkZXJzXCIgZm9yIGEgZ2l2ZW4gcmVxdWVzdCwgbWVyZ2luZyB0aGVcbiAgICogcGVyLXJlcXVlc3QgaGVhZGVycyB3aXRoIG91ciBvd24gXCJkZWZhdWx0XCIgaGVhZGVycy5cbiAgICpcbiAgICogQHByaXZhdGVcbiAgICovXG5cblxuICAoMCwgX2NyZWF0ZUNsYXNzMi5kZWZhdWx0KShCdWNrZXQsIFt7XG4gICAga2V5OiBcIl9nZXRIZWFkZXJzXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIF9nZXRIZWFkZXJzKG9wdGlvbnMpIHtcbiAgICAgIHJldHVybiAoMCwgX29iamVjdFNwcmVhZDIuZGVmYXVsdCkoe30sIHRoaXMuX2hlYWRlcnMsIG9wdGlvbnMuaGVhZGVycyk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCB0aGUgdmFsdWUgb2YgXCJzYWZlXCIgZm9yIGEgZ2l2ZW4gcmVxdWVzdCwgdXNpbmcgdGhlXG4gICAgICogcGVyLXJlcXVlc3Qgb3B0aW9uIGlmIHByZXNlbnQgb3IgZmFsbGluZyBiYWNrIHRvIG91ciBkZWZhdWx0XG4gICAgICogb3RoZXJ3aXNlLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb3B0aW9ucyBUaGUgb3B0aW9ucyBmb3IgYSByZXF1ZXN0LlxuICAgICAqIEByZXR1cm5zIHtCb29sZWFufVxuICAgICAqL1xuXG4gIH0sIHtcbiAgICBrZXk6IFwiX2dldFNhZmVcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gX2dldFNhZmUob3B0aW9ucykge1xuICAgICAgcmV0dXJuICgwLCBfb2JqZWN0U3ByZWFkMi5kZWZhdWx0KSh7XG4gICAgICAgIHNhZmU6IHRoaXMuX3NhZmVcbiAgICAgIH0sIG9wdGlvbnMpLnNhZmU7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEFzIF9nZXRTYWZlLCBidXQgZm9yIFwicmV0cnlcIi5cbiAgICAgKlxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG5cbiAgfSwge1xuICAgIGtleTogXCJfZ2V0UmV0cnlcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gX2dldFJldHJ5KG9wdGlvbnMpIHtcbiAgICAgIHJldHVybiAoMCwgX29iamVjdFNwcmVhZDIuZGVmYXVsdCkoe1xuICAgICAgICByZXRyeTogdGhpcy5fcmV0cnlcbiAgICAgIH0sIG9wdGlvbnMpLnJldHJ5O1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTZWxlY3RzIGEgY29sbGVjdGlvbi5cbiAgICAgKlxuICAgICAqIEBwYXJhbSAge1N0cmluZ30gIG5hbWUgICAgICAgICAgICAgIFRoZSBjb2xsZWN0aW9uIG5hbWUuXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSAgW29wdGlvbnM9e31dICAgICAgVGhlIG9wdGlvbnMgb2JqZWN0LlxuICAgICAqIEBwYXJhbSAge09iamVjdH0gIFtvcHRpb25zLmhlYWRlcnNdIFRoZSBoZWFkZXJzIG9iamVjdCBvcHRpb24uXG4gICAgICogQHBhcmFtICB7Qm9vbGVhbn0gW29wdGlvbnMuc2FmZV0gICAgVGhlIHNhZmUgb3B0aW9uLlxuICAgICAqIEByZXR1cm4ge0NvbGxlY3Rpb259XG4gICAgICovXG5cbiAgfSwge1xuICAgIGtleTogXCJjb2xsZWN0aW9uXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIGNvbGxlY3Rpb24obmFtZSkge1xuICAgICAgdmFyIG9wdGlvbnMgPSBhcmd1bWVudHMubGVuZ3RoID4gMSAmJiBhcmd1bWVudHNbMV0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1sxXSA6IHt9O1xuICAgICAgcmV0dXJuIG5ldyBfY29sbGVjdGlvbi5kZWZhdWx0KHRoaXMuY2xpZW50LCB0aGlzLCBuYW1lLCB7XG4gICAgICAgIGJhdGNoOiB0aGlzLl9pc0JhdGNoLFxuICAgICAgICBoZWFkZXJzOiB0aGlzLl9nZXRIZWFkZXJzKG9wdGlvbnMpLFxuICAgICAgICByZXRyeTogdGhpcy5fZ2V0UmV0cnkob3B0aW9ucyksXG4gICAgICAgIHNhZmU6IHRoaXMuX2dldFNhZmUob3B0aW9ucylcbiAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZXRyaWV2ZXMgYnVja2V0IGRhdGEuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9IFtvcHRpb25zPXt9XSAgICAgIFRoZSBvcHRpb25zIG9iamVjdC5cbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9IFtvcHRpb25zLmhlYWRlcnNdIFRoZSBoZWFkZXJzIG9iamVjdCBvcHRpb24uXG4gICAgICogQHBhcmFtICB7TnVtYmVyfSBbb3B0aW9ucy5yZXRyeT0wXSBOdW1iZXIgb2YgcmV0cmllcyB0byBtYWtlXG4gICAgICogICAgIHdoZW4gZmFjZWQgd2l0aCB0cmFuc2llbnQgZXJyb3JzLlxuICAgICAqIEByZXR1cm4ge1Byb21pc2U8T2JqZWN0LCBFcnJvcj59XG4gICAgICovXG5cbiAgfSwge1xuICAgIGtleTogXCJnZXREYXRhXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciBfZ2V0RGF0YSA9ICgwLCBfYXN5bmNUb0dlbmVyYXRvcjIuZGVmYXVsdCkoXG4gICAgICAvKiNfX1BVUkVfXyovXG4gICAgICBfcmVnZW5lcmF0b3IuZGVmYXVsdC5tYXJrKGZ1bmN0aW9uIF9jYWxsZWUoKSB7XG4gICAgICAgIHZhciBvcHRpb25zLFxuICAgICAgICAgICAgcmVxdWVzdCxcbiAgICAgICAgICAgIF9yZWYsXG4gICAgICAgICAgICBkYXRhLFxuICAgICAgICAgICAgX2FyZ3MgPSBhcmd1bWVudHM7XG5cbiAgICAgICAgcmV0dXJuIF9yZWdlbmVyYXRvci5kZWZhdWx0LndyYXAoZnVuY3Rpb24gX2NhbGxlZSQoX2NvbnRleHQpIHtcbiAgICAgICAgICB3aGlsZSAoMSkge1xuICAgICAgICAgICAgc3dpdGNoIChfY29udGV4dC5wcmV2ID0gX2NvbnRleHQubmV4dCkge1xuICAgICAgICAgICAgICBjYXNlIDA6XG4gICAgICAgICAgICAgICAgb3B0aW9ucyA9IF9hcmdzLmxlbmd0aCA+IDAgJiYgX2FyZ3NbMF0gIT09IHVuZGVmaW5lZCA/IF9hcmdzWzBdIDoge307XG4gICAgICAgICAgICAgICAgcmVxdWVzdCA9IHtcbiAgICAgICAgICAgICAgICAgIGhlYWRlcnM6IHRoaXMuX2dldEhlYWRlcnMob3B0aW9ucyksXG4gICAgICAgICAgICAgICAgICBwYXRoOiAoMCwgX2VuZHBvaW50LmRlZmF1bHQpKFwiYnVja2V0XCIsIHRoaXMubmFtZSlcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIF9jb250ZXh0Lm5leHQgPSA0O1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmNsaWVudC5leGVjdXRlKHJlcXVlc3QsIHtcbiAgICAgICAgICAgICAgICAgIHJldHJ5OiB0aGlzLl9nZXRSZXRyeShvcHRpb25zKVxuICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgIGNhc2UgNDpcbiAgICAgICAgICAgICAgICBfcmVmID0gX2NvbnRleHQuc2VudDtcbiAgICAgICAgICAgICAgICBkYXRhID0gX3JlZi5kYXRhO1xuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dC5hYnJ1cHQoXCJyZXR1cm5cIiwgZGF0YSk7XG5cbiAgICAgICAgICAgICAgY2FzZSA3OlxuICAgICAgICAgICAgICBjYXNlIFwiZW5kXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0LnN0b3AoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0sIF9jYWxsZWUsIHRoaXMpO1xuICAgICAgfSkpO1xuXG4gICAgICByZXR1cm4gZnVuY3Rpb24gZ2V0RGF0YSgpIHtcbiAgICAgICAgcmV0dXJuIF9nZXREYXRhLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICB9O1xuICAgIH0oKVxuICAgIC8qKlxuICAgICAqIFNldCBidWNrZXQgZGF0YS5cbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9ICBkYXRhICAgICAgICAgICAgICAgICAgICBUaGUgYnVja2V0IGRhdGEgb2JqZWN0LlxuICAgICAqIEBwYXJhbSAge09iamVjdH0gIFtvcHRpb25zPXt9XSAgICAgICAgICAgIFRoZSBvcHRpb25zIG9iamVjdC5cbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9ICBbb3B0aW9ucy5oZWFkZXJzPXt9XSAgICBUaGUgaGVhZGVycyBvYmplY3Qgb3B0aW9uLlxuICAgICAqIEBwYXJhbSAge0Jvb2xlYW59IFtvcHRpb25zLnNhZmVdICAgICAgICAgIFRoZSBzYWZlIG9wdGlvbi5cbiAgICAgKiBAcGFyYW0gIHtOdW1iZXJ9ICBbb3B0aW9ucy5yZXRyeT0wXSAgICAgICBOdW1iZXIgb2YgcmV0cmllcyB0byBtYWtlXG4gICAgICogICAgIHdoZW4gZmFjZWQgd2l0aCB0cmFuc2llbnQgZXJyb3JzLlxuICAgICAqIEBwYXJhbSAge0Jvb2xlYW59IFtvcHRpb25zLnBhdGNoXSAgICAgICAgIFRoZSBwYXRjaCBvcHRpb24uXG4gICAgICogQHBhcmFtICB7TnVtYmVyfSAgW29wdGlvbnMubGFzdF9tb2RpZmllZF0gVGhlIGxhc3RfbW9kaWZpZWQgb3B0aW9uLlxuICAgICAqIEByZXR1cm4ge1Byb21pc2U8T2JqZWN0LCBFcnJvcj59XG4gICAgICovXG5cbiAgfSwge1xuICAgIGtleTogXCJzZXREYXRhXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciBfc2V0RGF0YSA9ICgwLCBfYXN5bmNUb0dlbmVyYXRvcjIuZGVmYXVsdCkoXG4gICAgICAvKiNfX1BVUkVfXyovXG4gICAgICBfcmVnZW5lcmF0b3IuZGVmYXVsdC5tYXJrKGZ1bmN0aW9uIF9jYWxsZWUyKGRhdGEpIHtcbiAgICAgICAgdmFyIG9wdGlvbnMsXG4gICAgICAgICAgICBidWNrZXQsXG4gICAgICAgICAgICBidWNrZXRJZCxcbiAgICAgICAgICAgIHBhdGgsXG4gICAgICAgICAgICBwYXRjaCxcbiAgICAgICAgICAgIHBlcm1pc3Npb25zLFxuICAgICAgICAgICAgX2RhdGEkb3B0aW9ucyxcbiAgICAgICAgICAgIGxhc3RfbW9kaWZpZWQsXG4gICAgICAgICAgICByZXF1ZXN0LFxuICAgICAgICAgICAgX2FyZ3MyID0gYXJndW1lbnRzO1xuXG4gICAgICAgIHJldHVybiBfcmVnZW5lcmF0b3IuZGVmYXVsdC53cmFwKGZ1bmN0aW9uIF9jYWxsZWUyJChfY29udGV4dDIpIHtcbiAgICAgICAgICB3aGlsZSAoMSkge1xuICAgICAgICAgICAgc3dpdGNoIChfY29udGV4dDIucHJldiA9IF9jb250ZXh0Mi5uZXh0KSB7XG4gICAgICAgICAgICAgIGNhc2UgMDpcbiAgICAgICAgICAgICAgICBvcHRpb25zID0gX2FyZ3MyLmxlbmd0aCA+IDEgJiYgX2FyZ3MyWzFdICE9PSB1bmRlZmluZWQgPyBfYXJnczJbMV0gOiB7fTtcblxuICAgICAgICAgICAgICAgIGlmICgoMCwgX3V0aWxzLmlzT2JqZWN0KShkYXRhKSkge1xuICAgICAgICAgICAgICAgICAgX2NvbnRleHQyLm5leHQgPSAzO1xuICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQSBidWNrZXQgb2JqZWN0IGlzIHJlcXVpcmVkLlwiKTtcblxuICAgICAgICAgICAgICBjYXNlIDM6XG4gICAgICAgICAgICAgICAgYnVja2V0ID0gKDAsIF9vYmplY3RTcHJlYWQyLmRlZmF1bHQpKHt9LCBkYXRhLCB7XG4gICAgICAgICAgICAgICAgICBpZDogdGhpcy5uYW1lXG4gICAgICAgICAgICAgICAgfSk7IC8vIEZvciBkZWZhdWx0IGJ1Y2tldCwgd2UgbmVlZCB0byBkcm9wIHRoZSBpZCBmcm9tIHRoZSBkYXRhIG9iamVjdC5cbiAgICAgICAgICAgICAgICAvLyBCdWcgaW4gS2ludG8gPCAzLjEuMVxuXG4gICAgICAgICAgICAgICAgYnVja2V0SWQgPSBidWNrZXQuaWQ7XG5cbiAgICAgICAgICAgICAgICBpZiAoYnVja2V0LmlkID09PSBcImRlZmF1bHRcIikge1xuICAgICAgICAgICAgICAgICAgZGVsZXRlIGJ1Y2tldC5pZDtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBwYXRoID0gKDAsIF9lbmRwb2ludC5kZWZhdWx0KShcImJ1Y2tldFwiLCBidWNrZXRJZCk7XG4gICAgICAgICAgICAgICAgcGF0Y2ggPSBvcHRpb25zLnBhdGNoLCBwZXJtaXNzaW9ucyA9IG9wdGlvbnMucGVybWlzc2lvbnM7XG4gICAgICAgICAgICAgICAgX2RhdGEkb3B0aW9ucyA9ICgwLCBfb2JqZWN0U3ByZWFkMi5kZWZhdWx0KSh7fSwgZGF0YSwgb3B0aW9ucyksIGxhc3RfbW9kaWZpZWQgPSBfZGF0YSRvcHRpb25zLmxhc3RfbW9kaWZpZWQ7XG4gICAgICAgICAgICAgICAgcmVxdWVzdCA9IHJlcXVlc3RzLnVwZGF0ZVJlcXVlc3QocGF0aCwge1xuICAgICAgICAgICAgICAgICAgZGF0YTogYnVja2V0LFxuICAgICAgICAgICAgICAgICAgcGVybWlzc2lvbnM6IHBlcm1pc3Npb25zXG4gICAgICAgICAgICAgICAgfSwge1xuICAgICAgICAgICAgICAgICAgbGFzdF9tb2RpZmllZDogbGFzdF9tb2RpZmllZCxcbiAgICAgICAgICAgICAgICAgIHBhdGNoOiBwYXRjaCxcbiAgICAgICAgICAgICAgICAgIGhlYWRlcnM6IHRoaXMuX2dldEhlYWRlcnMob3B0aW9ucyksXG4gICAgICAgICAgICAgICAgICBzYWZlOiB0aGlzLl9nZXRTYWZlKG9wdGlvbnMpXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0Mi5hYnJ1cHQoXCJyZXR1cm5cIiwgdGhpcy5jbGllbnQuZXhlY3V0ZShyZXF1ZXN0LCB7XG4gICAgICAgICAgICAgICAgICByZXRyeTogdGhpcy5fZ2V0UmV0cnkob3B0aW9ucylcbiAgICAgICAgICAgICAgICB9KSk7XG5cbiAgICAgICAgICAgICAgY2FzZSAxMTpcbiAgICAgICAgICAgICAgY2FzZSBcImVuZFwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDIuc3RvcCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSwgX2NhbGxlZTIsIHRoaXMpO1xuICAgICAgfSkpO1xuXG4gICAgICByZXR1cm4gZnVuY3Rpb24gc2V0RGF0YShfeCkge1xuICAgICAgICByZXR1cm4gX3NldERhdGEuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgIH07XG4gICAgfSgpXG4gICAgLyoqXG4gICAgICogUmV0cmlldmVzIHRoZSBsaXN0IG9mIGhpc3RvcnkgZW50cmllcyBpbiB0aGUgY3VycmVudCBidWNrZXQuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9IFtvcHRpb25zPXt9XSAgICAgIFRoZSBvcHRpb25zIG9iamVjdC5cbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9IFtvcHRpb25zLmhlYWRlcnNdIFRoZSBoZWFkZXJzIG9iamVjdCBvcHRpb24uXG4gICAgICogQHBhcmFtICB7TnVtYmVyfSBbb3B0aW9ucy5yZXRyeT0wXSBOdW1iZXIgb2YgcmV0cmllcyB0byBtYWtlXG4gICAgICogICAgIHdoZW4gZmFjZWQgd2l0aCB0cmFuc2llbnQgZXJyb3JzLlxuICAgICAqIEByZXR1cm4ge1Byb21pc2U8QXJyYXk8T2JqZWN0PiwgRXJyb3I+fVxuICAgICAqL1xuXG4gIH0sIHtcbiAgICBrZXk6IFwibGlzdEhpc3RvcnlcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gKCkge1xuICAgICAgdmFyIF9saXN0SGlzdG9yeSA9ICgwLCBfYXN5bmNUb0dlbmVyYXRvcjIuZGVmYXVsdCkoXG4gICAgICAvKiNfX1BVUkVfXyovXG4gICAgICBfcmVnZW5lcmF0b3IuZGVmYXVsdC5tYXJrKGZ1bmN0aW9uIF9jYWxsZWUzKCkge1xuICAgICAgICB2YXIgb3B0aW9ucyxcbiAgICAgICAgICAgIHBhdGgsXG4gICAgICAgICAgICBfYXJnczMgPSBhcmd1bWVudHM7XG4gICAgICAgIHJldHVybiBfcmVnZW5lcmF0b3IuZGVmYXVsdC53cmFwKGZ1bmN0aW9uIF9jYWxsZWUzJChfY29udGV4dDMpIHtcbiAgICAgICAgICB3aGlsZSAoMSkge1xuICAgICAgICAgICAgc3dpdGNoIChfY29udGV4dDMucHJldiA9IF9jb250ZXh0My5uZXh0KSB7XG4gICAgICAgICAgICAgIGNhc2UgMDpcbiAgICAgICAgICAgICAgICBvcHRpb25zID0gX2FyZ3MzLmxlbmd0aCA+IDAgJiYgX2FyZ3MzWzBdICE9PSB1bmRlZmluZWQgPyBfYXJnczNbMF0gOiB7fTtcbiAgICAgICAgICAgICAgICBwYXRoID0gKDAsIF9lbmRwb2ludC5kZWZhdWx0KShcImhpc3RvcnlcIiwgdGhpcy5uYW1lKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQzLmFicnVwdChcInJldHVyblwiLCB0aGlzLmNsaWVudC5wYWdpbmF0ZWRMaXN0KHBhdGgsIG9wdGlvbnMsIHtcbiAgICAgICAgICAgICAgICAgIGhlYWRlcnM6IHRoaXMuX2dldEhlYWRlcnMob3B0aW9ucyksXG4gICAgICAgICAgICAgICAgICByZXRyeTogdGhpcy5fZ2V0UmV0cnkob3B0aW9ucylcbiAgICAgICAgICAgICAgICB9KSk7XG5cbiAgICAgICAgICAgICAgY2FzZSAzOlxuICAgICAgICAgICAgICBjYXNlIFwiZW5kXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0My5zdG9wKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9LCBfY2FsbGVlMywgdGhpcyk7XG4gICAgICB9KSk7XG5cbiAgICAgIHJldHVybiBmdW5jdGlvbiBsaXN0SGlzdG9yeSgpIHtcbiAgICAgICAgcmV0dXJuIF9saXN0SGlzdG9yeS5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgfTtcbiAgICB9KClcbiAgICAvKipcbiAgICAgKiBSZXRyaWV2ZXMgdGhlIGxpc3Qgb2YgY29sbGVjdGlvbnMgaW4gdGhlIGN1cnJlbnQgYnVja2V0LlxuICAgICAqXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSBbb3B0aW9ucz17fV0gICAgICBUaGUgb3B0aW9ucyBvYmplY3QuXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSBbb3B0aW9ucy5oZWFkZXJzXSBUaGUgaGVhZGVycyBvYmplY3Qgb3B0aW9uLlxuICAgICAqIEBwYXJhbSAge051bWJlcn0gW29wdGlvbnMucmV0cnk9MF0gTnVtYmVyIG9mIHJldHJpZXMgdG8gbWFrZVxuICAgICAqICAgICB3aGVuIGZhY2VkIHdpdGggdHJhbnNpZW50IGVycm9ycy5cbiAgICAgKiBAcmV0dXJuIHtQcm9taXNlPEFycmF5PE9iamVjdD4sIEVycm9yPn1cbiAgICAgKi9cblxuICB9LCB7XG4gICAga2V5OiBcImxpc3RDb2xsZWN0aW9uc1wiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgX2xpc3RDb2xsZWN0aW9ucyA9ICgwLCBfYXN5bmNUb0dlbmVyYXRvcjIuZGVmYXVsdCkoXG4gICAgICAvKiNfX1BVUkVfXyovXG4gICAgICBfcmVnZW5lcmF0b3IuZGVmYXVsdC5tYXJrKGZ1bmN0aW9uIF9jYWxsZWU0KCkge1xuICAgICAgICB2YXIgb3B0aW9ucyxcbiAgICAgICAgICAgIHBhdGgsXG4gICAgICAgICAgICBfYXJnczQgPSBhcmd1bWVudHM7XG4gICAgICAgIHJldHVybiBfcmVnZW5lcmF0b3IuZGVmYXVsdC53cmFwKGZ1bmN0aW9uIF9jYWxsZWU0JChfY29udGV4dDQpIHtcbiAgICAgICAgICB3aGlsZSAoMSkge1xuICAgICAgICAgICAgc3dpdGNoIChfY29udGV4dDQucHJldiA9IF9jb250ZXh0NC5uZXh0KSB7XG4gICAgICAgICAgICAgIGNhc2UgMDpcbiAgICAgICAgICAgICAgICBvcHRpb25zID0gX2FyZ3M0Lmxlbmd0aCA+IDAgJiYgX2FyZ3M0WzBdICE9PSB1bmRlZmluZWQgPyBfYXJnczRbMF0gOiB7fTtcbiAgICAgICAgICAgICAgICBwYXRoID0gKDAsIF9lbmRwb2ludC5kZWZhdWx0KShcImNvbGxlY3Rpb25cIiwgdGhpcy5uYW1lKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQ0LmFicnVwdChcInJldHVyblwiLCB0aGlzLmNsaWVudC5wYWdpbmF0ZWRMaXN0KHBhdGgsIG9wdGlvbnMsIHtcbiAgICAgICAgICAgICAgICAgIGhlYWRlcnM6IHRoaXMuX2dldEhlYWRlcnMob3B0aW9ucyksXG4gICAgICAgICAgICAgICAgICByZXRyeTogdGhpcy5fZ2V0UmV0cnkob3B0aW9ucylcbiAgICAgICAgICAgICAgICB9KSk7XG5cbiAgICAgICAgICAgICAgY2FzZSAzOlxuICAgICAgICAgICAgICBjYXNlIFwiZW5kXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0NC5zdG9wKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9LCBfY2FsbGVlNCwgdGhpcyk7XG4gICAgICB9KSk7XG5cbiAgICAgIHJldHVybiBmdW5jdGlvbiBsaXN0Q29sbGVjdGlvbnMoKSB7XG4gICAgICAgIHJldHVybiBfbGlzdENvbGxlY3Rpb25zLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICB9O1xuICAgIH0oKVxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBuZXcgY29sbGVjdGlvbiBpbiBjdXJyZW50IGJ1Y2tldC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSAge1N0cmluZ3x1bmRlZmluZWR9ICBpZCAgICAgICAgICBUaGUgY29sbGVjdGlvbiBpZC5cbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9ICBbb3B0aW9ucz17fV0gICAgICAgICAgVGhlIG9wdGlvbnMgb2JqZWN0LlxuICAgICAqIEBwYXJhbSAge0Jvb2xlYW59IFtvcHRpb25zLnNhZmVdICAgICAgICBUaGUgc2FmZSBvcHRpb24uXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSAgW29wdGlvbnMuaGVhZGVyc10gICAgIFRoZSBoZWFkZXJzIG9iamVjdCBvcHRpb24uXG4gICAgICogQHBhcmFtICB7TnVtYmVyfSAgW29wdGlvbnMucmV0cnk9MF0gICAgIE51bWJlciBvZiByZXRyaWVzIHRvIG1ha2VcbiAgICAgKiAgICAgd2hlbiBmYWNlZCB3aXRoIHRyYW5zaWVudCBlcnJvcnMuXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSAgW29wdGlvbnMucGVybWlzc2lvbnNdIFRoZSBwZXJtaXNzaW9ucyBvYmplY3QuXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSAgW29wdGlvbnMuZGF0YV0gICAgICAgIFRoZSBkYXRhIG9iamVjdC5cbiAgICAgKiBAcmV0dXJuIHtQcm9taXNlPE9iamVjdCwgRXJyb3I+fVxuICAgICAqL1xuXG4gIH0sIHtcbiAgICBrZXk6IFwiY3JlYXRlQ29sbGVjdGlvblwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgX2NyZWF0ZUNvbGxlY3Rpb24gPSAoMCwgX2FzeW5jVG9HZW5lcmF0b3IyLmRlZmF1bHQpKFxuICAgICAgLyojX19QVVJFX18qL1xuICAgICAgX3JlZ2VuZXJhdG9yLmRlZmF1bHQubWFyayhmdW5jdGlvbiBfY2FsbGVlNShpZCkge1xuICAgICAgICB2YXIgb3B0aW9ucyxcbiAgICAgICAgICAgIHBlcm1pc3Npb25zLFxuICAgICAgICAgICAgX29wdGlvbnMkZGF0YSxcbiAgICAgICAgICAgIGRhdGEsXG4gICAgICAgICAgICBwYXRoLFxuICAgICAgICAgICAgcmVxdWVzdCxcbiAgICAgICAgICAgIF9hcmdzNSA9IGFyZ3VtZW50cztcblxuICAgICAgICByZXR1cm4gX3JlZ2VuZXJhdG9yLmRlZmF1bHQud3JhcChmdW5jdGlvbiBfY2FsbGVlNSQoX2NvbnRleHQ1KSB7XG4gICAgICAgICAgd2hpbGUgKDEpIHtcbiAgICAgICAgICAgIHN3aXRjaCAoX2NvbnRleHQ1LnByZXYgPSBfY29udGV4dDUubmV4dCkge1xuICAgICAgICAgICAgICBjYXNlIDA6XG4gICAgICAgICAgICAgICAgb3B0aW9ucyA9IF9hcmdzNS5sZW5ndGggPiAxICYmIF9hcmdzNVsxXSAhPT0gdW5kZWZpbmVkID8gX2FyZ3M1WzFdIDoge307XG4gICAgICAgICAgICAgICAgcGVybWlzc2lvbnMgPSBvcHRpb25zLnBlcm1pc3Npb25zLCBfb3B0aW9ucyRkYXRhID0gb3B0aW9ucy5kYXRhLCBkYXRhID0gX29wdGlvbnMkZGF0YSA9PT0gdm9pZCAwID8ge30gOiBfb3B0aW9ucyRkYXRhO1xuICAgICAgICAgICAgICAgIGRhdGEuaWQgPSBpZDtcbiAgICAgICAgICAgICAgICBwYXRoID0gKDAsIF9lbmRwb2ludC5kZWZhdWx0KShcImNvbGxlY3Rpb25cIiwgdGhpcy5uYW1lLCBpZCk7XG4gICAgICAgICAgICAgICAgcmVxdWVzdCA9IHJlcXVlc3RzLmNyZWF0ZVJlcXVlc3QocGF0aCwge1xuICAgICAgICAgICAgICAgICAgZGF0YTogZGF0YSxcbiAgICAgICAgICAgICAgICAgIHBlcm1pc3Npb25zOiBwZXJtaXNzaW9uc1xuICAgICAgICAgICAgICAgIH0sIHtcbiAgICAgICAgICAgICAgICAgIGhlYWRlcnM6IHRoaXMuX2dldEhlYWRlcnMob3B0aW9ucyksXG4gICAgICAgICAgICAgICAgICBzYWZlOiB0aGlzLl9nZXRTYWZlKG9wdGlvbnMpXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0NS5hYnJ1cHQoXCJyZXR1cm5cIiwgdGhpcy5jbGllbnQuZXhlY3V0ZShyZXF1ZXN0LCB7XG4gICAgICAgICAgICAgICAgICByZXRyeTogdGhpcy5fZ2V0UmV0cnkob3B0aW9ucylcbiAgICAgICAgICAgICAgICB9KSk7XG5cbiAgICAgICAgICAgICAgY2FzZSA2OlxuICAgICAgICAgICAgICBjYXNlIFwiZW5kXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0NS5zdG9wKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9LCBfY2FsbGVlNSwgdGhpcyk7XG4gICAgICB9KSk7XG5cbiAgICAgIHJldHVybiBmdW5jdGlvbiBjcmVhdGVDb2xsZWN0aW9uKF94Mikge1xuICAgICAgICByZXR1cm4gX2NyZWF0ZUNvbGxlY3Rpb24uYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgIH07XG4gICAgfSgpXG4gICAgLyoqXG4gICAgICogRGVsZXRlcyBhIGNvbGxlY3Rpb24gZnJvbSB0aGUgY3VycmVudCBidWNrZXQuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gIHtPYmplY3R8U3RyaW5nfSBjb2xsZWN0aW9uICAgICAgICAgICAgICBUaGUgY29sbGVjdGlvbiB0byBkZWxldGUuXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSAgICAgICAgW29wdGlvbnM9e31dICAgICAgICAgICAgVGhlIG9wdGlvbnMgb2JqZWN0LlxuICAgICAqIEBwYXJhbSAge09iamVjdH0gICAgICAgIFtvcHRpb25zLmhlYWRlcnNdICAgICAgIFRoZSBoZWFkZXJzIG9iamVjdCBvcHRpb24uXG4gICAgICogQHBhcmFtICB7TnVtYmVyfSAgICAgICAgW29wdGlvbnMucmV0cnk9MF0gICAgICAgTnVtYmVyIG9mIHJldHJpZXMgdG8gbWFrZVxuICAgICAqICAgICB3aGVuIGZhY2VkIHdpdGggdHJhbnNpZW50IGVycm9ycy5cbiAgICAgKiBAcGFyYW0gIHtCb29sZWFufSAgICAgICBbb3B0aW9ucy5zYWZlXSAgICAgICAgICBUaGUgc2FmZSBvcHRpb24uXG4gICAgICogQHBhcmFtICB7TnVtYmVyfSAgICAgICAgW29wdGlvbnMubGFzdF9tb2RpZmllZF0gVGhlIGxhc3RfbW9kaWZpZWQgb3B0aW9uLlxuICAgICAqIEByZXR1cm4ge1Byb21pc2U8T2JqZWN0LCBFcnJvcj59XG4gICAgICovXG5cbiAgfSwge1xuICAgIGtleTogXCJkZWxldGVDb2xsZWN0aW9uXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciBfZGVsZXRlQ29sbGVjdGlvbiA9ICgwLCBfYXN5bmNUb0dlbmVyYXRvcjIuZGVmYXVsdCkoXG4gICAgICAvKiNfX1BVUkVfXyovXG4gICAgICBfcmVnZW5lcmF0b3IuZGVmYXVsdC5tYXJrKGZ1bmN0aW9uIF9jYWxsZWU2KGNvbGxlY3Rpb24pIHtcbiAgICAgICAgdmFyIG9wdGlvbnMsXG4gICAgICAgICAgICBjb2xsZWN0aW9uT2JqLFxuICAgICAgICAgICAgaWQsXG4gICAgICAgICAgICBfY29sbGVjdGlvbk9iaiRvcHRpb24sXG4gICAgICAgICAgICBsYXN0X21vZGlmaWVkLFxuICAgICAgICAgICAgcGF0aCxcbiAgICAgICAgICAgIHJlcXVlc3QsXG4gICAgICAgICAgICBfYXJnczYgPSBhcmd1bWVudHM7XG5cbiAgICAgICAgcmV0dXJuIF9yZWdlbmVyYXRvci5kZWZhdWx0LndyYXAoZnVuY3Rpb24gX2NhbGxlZTYkKF9jb250ZXh0Nikge1xuICAgICAgICAgIHdoaWxlICgxKSB7XG4gICAgICAgICAgICBzd2l0Y2ggKF9jb250ZXh0Ni5wcmV2ID0gX2NvbnRleHQ2Lm5leHQpIHtcbiAgICAgICAgICAgICAgY2FzZSAwOlxuICAgICAgICAgICAgICAgIG9wdGlvbnMgPSBfYXJnczYubGVuZ3RoID4gMSAmJiBfYXJnczZbMV0gIT09IHVuZGVmaW5lZCA/IF9hcmdzNlsxXSA6IHt9O1xuICAgICAgICAgICAgICAgIGNvbGxlY3Rpb25PYmogPSAoMCwgX3V0aWxzLnRvRGF0YUJvZHkpKGNvbGxlY3Rpb24pO1xuXG4gICAgICAgICAgICAgICAgaWYgKGNvbGxlY3Rpb25PYmouaWQpIHtcbiAgICAgICAgICAgICAgICAgIF9jb250ZXh0Ni5uZXh0ID0gNDtcbiAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIkEgY29sbGVjdGlvbiBpZCBpcyByZXF1aXJlZC5cIik7XG5cbiAgICAgICAgICAgICAgY2FzZSA0OlxuICAgICAgICAgICAgICAgIGlkID0gY29sbGVjdGlvbk9iai5pZDtcbiAgICAgICAgICAgICAgICBfY29sbGVjdGlvbk9iaiRvcHRpb24gPSAoMCwgX29iamVjdFNwcmVhZDIuZGVmYXVsdCkoe30sIGNvbGxlY3Rpb25PYmosIG9wdGlvbnMpLCBsYXN0X21vZGlmaWVkID0gX2NvbGxlY3Rpb25PYmokb3B0aW9uLmxhc3RfbW9kaWZpZWQ7XG4gICAgICAgICAgICAgICAgcGF0aCA9ICgwLCBfZW5kcG9pbnQuZGVmYXVsdCkoXCJjb2xsZWN0aW9uXCIsIHRoaXMubmFtZSwgaWQpO1xuICAgICAgICAgICAgICAgIHJlcXVlc3QgPSByZXF1ZXN0cy5kZWxldGVSZXF1ZXN0KHBhdGgsIHtcbiAgICAgICAgICAgICAgICAgIGxhc3RfbW9kaWZpZWQ6IGxhc3RfbW9kaWZpZWQsXG4gICAgICAgICAgICAgICAgICBoZWFkZXJzOiB0aGlzLl9nZXRIZWFkZXJzKG9wdGlvbnMpLFxuICAgICAgICAgICAgICAgICAgc2FmZTogdGhpcy5fZ2V0U2FmZShvcHRpb25zKVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDYuYWJydXB0KFwicmV0dXJuXCIsIHRoaXMuY2xpZW50LmV4ZWN1dGUocmVxdWVzdCwge1xuICAgICAgICAgICAgICAgICAgcmV0cnk6IHRoaXMuX2dldFJldHJ5KG9wdGlvbnMpXG4gICAgICAgICAgICAgICAgfSkpO1xuXG4gICAgICAgICAgICAgIGNhc2UgOTpcbiAgICAgICAgICAgICAgY2FzZSBcImVuZFwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDYuc3RvcCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSwgX2NhbGxlZTYsIHRoaXMpO1xuICAgICAgfSkpO1xuXG4gICAgICByZXR1cm4gZnVuY3Rpb24gZGVsZXRlQ29sbGVjdGlvbihfeDMpIHtcbiAgICAgICAgcmV0dXJuIF9kZWxldGVDb2xsZWN0aW9uLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICB9O1xuICAgIH0oKVxuICAgIC8qKlxuICAgICAqIFJldHJpZXZlcyB0aGUgbGlzdCBvZiBncm91cHMgaW4gdGhlIGN1cnJlbnQgYnVja2V0LlxuICAgICAqXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSBbb3B0aW9ucz17fV0gICAgICBUaGUgb3B0aW9ucyBvYmplY3QuXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSBbb3B0aW9ucy5oZWFkZXJzXSBUaGUgaGVhZGVycyBvYmplY3Qgb3B0aW9uLlxuICAgICAqIEBwYXJhbSAge051bWJlcn0gW29wdGlvbnMucmV0cnk9MF0gTnVtYmVyIG9mIHJldHJpZXMgdG8gbWFrZVxuICAgICAqICAgICB3aGVuIGZhY2VkIHdpdGggdHJhbnNpZW50IGVycm9ycy5cbiAgICAgKiBAcmV0dXJuIHtQcm9taXNlPEFycmF5PE9iamVjdD4sIEVycm9yPn1cbiAgICAgKi9cblxuICB9LCB7XG4gICAga2V5OiBcImxpc3RHcm91cHNcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gKCkge1xuICAgICAgdmFyIF9saXN0R3JvdXBzID0gKDAsIF9hc3luY1RvR2VuZXJhdG9yMi5kZWZhdWx0KShcbiAgICAgIC8qI19fUFVSRV9fKi9cbiAgICAgIF9yZWdlbmVyYXRvci5kZWZhdWx0Lm1hcmsoZnVuY3Rpb24gX2NhbGxlZTcoKSB7XG4gICAgICAgIHZhciBvcHRpb25zLFxuICAgICAgICAgICAgcGF0aCxcbiAgICAgICAgICAgIF9hcmdzNyA9IGFyZ3VtZW50cztcbiAgICAgICAgcmV0dXJuIF9yZWdlbmVyYXRvci5kZWZhdWx0LndyYXAoZnVuY3Rpb24gX2NhbGxlZTckKF9jb250ZXh0Nykge1xuICAgICAgICAgIHdoaWxlICgxKSB7XG4gICAgICAgICAgICBzd2l0Y2ggKF9jb250ZXh0Ny5wcmV2ID0gX2NvbnRleHQ3Lm5leHQpIHtcbiAgICAgICAgICAgICAgY2FzZSAwOlxuICAgICAgICAgICAgICAgIG9wdGlvbnMgPSBfYXJnczcubGVuZ3RoID4gMCAmJiBfYXJnczdbMF0gIT09IHVuZGVmaW5lZCA/IF9hcmdzN1swXSA6IHt9O1xuICAgICAgICAgICAgICAgIHBhdGggPSAoMCwgX2VuZHBvaW50LmRlZmF1bHQpKFwiZ3JvdXBcIiwgdGhpcy5uYW1lKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQ3LmFicnVwdChcInJldHVyblwiLCB0aGlzLmNsaWVudC5wYWdpbmF0ZWRMaXN0KHBhdGgsIG9wdGlvbnMsIHtcbiAgICAgICAgICAgICAgICAgIGhlYWRlcnM6IHRoaXMuX2dldEhlYWRlcnMob3B0aW9ucyksXG4gICAgICAgICAgICAgICAgICByZXRyeTogdGhpcy5fZ2V0UmV0cnkob3B0aW9ucylcbiAgICAgICAgICAgICAgICB9KSk7XG5cbiAgICAgICAgICAgICAgY2FzZSAzOlxuICAgICAgICAgICAgICBjYXNlIFwiZW5kXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0Ny5zdG9wKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9LCBfY2FsbGVlNywgdGhpcyk7XG4gICAgICB9KSk7XG5cbiAgICAgIHJldHVybiBmdW5jdGlvbiBsaXN0R3JvdXBzKCkge1xuICAgICAgICByZXR1cm4gX2xpc3RHcm91cHMuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgIH07XG4gICAgfSgpXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIG5ldyBncm91cCBpbiBjdXJyZW50IGJ1Y2tldC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSAge1N0cmluZ30gaWQgICAgICAgICAgICAgICAgVGhlIGdyb3VwIGlkLlxuICAgICAqIEBwYXJhbSAge09iamVjdH0gW29wdGlvbnM9e31dICAgICAgVGhlIG9wdGlvbnMgb2JqZWN0LlxuICAgICAqIEBwYXJhbSAge09iamVjdH0gW29wdGlvbnMuaGVhZGVyc10gVGhlIGhlYWRlcnMgb2JqZWN0IG9wdGlvbi5cbiAgICAgKiBAcGFyYW0gIHtOdW1iZXJ9IFtvcHRpb25zLnJldHJ5PTBdIE51bWJlciBvZiByZXRyaWVzIHRvIG1ha2VcbiAgICAgKiAgICAgd2hlbiBmYWNlZCB3aXRoIHRyYW5zaWVudCBlcnJvcnMuXG4gICAgICogQHJldHVybiB7UHJvbWlzZTxPYmplY3QsIEVycm9yPn1cbiAgICAgKi9cblxuICB9LCB7XG4gICAga2V5OiBcImdldEdyb3VwXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciBfZ2V0R3JvdXAgPSAoMCwgX2FzeW5jVG9HZW5lcmF0b3IyLmRlZmF1bHQpKFxuICAgICAgLyojX19QVVJFX18qL1xuICAgICAgX3JlZ2VuZXJhdG9yLmRlZmF1bHQubWFyayhmdW5jdGlvbiBfY2FsbGVlOChpZCkge1xuICAgICAgICB2YXIgb3B0aW9ucyxcbiAgICAgICAgICAgIHJlcXVlc3QsXG4gICAgICAgICAgICBfYXJnczggPSBhcmd1bWVudHM7XG4gICAgICAgIHJldHVybiBfcmVnZW5lcmF0b3IuZGVmYXVsdC53cmFwKGZ1bmN0aW9uIF9jYWxsZWU4JChfY29udGV4dDgpIHtcbiAgICAgICAgICB3aGlsZSAoMSkge1xuICAgICAgICAgICAgc3dpdGNoIChfY29udGV4dDgucHJldiA9IF9jb250ZXh0OC5uZXh0KSB7XG4gICAgICAgICAgICAgIGNhc2UgMDpcbiAgICAgICAgICAgICAgICBvcHRpb25zID0gX2FyZ3M4Lmxlbmd0aCA+IDEgJiYgX2FyZ3M4WzFdICE9PSB1bmRlZmluZWQgPyBfYXJnczhbMV0gOiB7fTtcbiAgICAgICAgICAgICAgICByZXF1ZXN0ID0ge1xuICAgICAgICAgICAgICAgICAgaGVhZGVyczogdGhpcy5fZ2V0SGVhZGVycyhvcHRpb25zKSxcbiAgICAgICAgICAgICAgICAgIHBhdGg6ICgwLCBfZW5kcG9pbnQuZGVmYXVsdCkoXCJncm91cFwiLCB0aGlzLm5hbWUsIGlkKVxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0OC5hYnJ1cHQoXCJyZXR1cm5cIiwgdGhpcy5jbGllbnQuZXhlY3V0ZShyZXF1ZXN0LCB7XG4gICAgICAgICAgICAgICAgICByZXRyeTogdGhpcy5fZ2V0UmV0cnkob3B0aW9ucylcbiAgICAgICAgICAgICAgICB9KSk7XG5cbiAgICAgICAgICAgICAgY2FzZSAzOlxuICAgICAgICAgICAgICBjYXNlIFwiZW5kXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0OC5zdG9wKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9LCBfY2FsbGVlOCwgdGhpcyk7XG4gICAgICB9KSk7XG5cbiAgICAgIHJldHVybiBmdW5jdGlvbiBnZXRHcm91cChfeDQpIHtcbiAgICAgICAgcmV0dXJuIF9nZXRHcm91cC5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgfTtcbiAgICB9KClcbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgbmV3IGdyb3VwIGluIGN1cnJlbnQgYnVja2V0LlxuICAgICAqXG4gICAgICogQHBhcmFtICB7U3RyaW5nfHVuZGVmaW5lZH0gIGlkICAgICAgICAgICAgICAgICAgICBUaGUgZ3JvdXAgaWQuXG4gICAgICogQHBhcmFtICB7QXJyYXk8U3RyaW5nPn0gICAgIFttZW1iZXJzPVtdXSAgICAgICAgICBUaGUgbGlzdCBvZiBwcmluY2lwYWxzLlxuICAgICAqIEBwYXJhbSAge09iamVjdH0gICAgICAgICAgICBbb3B0aW9ucz17fV0gICAgICAgICAgVGhlIG9wdGlvbnMgb2JqZWN0LlxuICAgICAqIEBwYXJhbSAge09iamVjdH0gICAgICAgICAgICBbb3B0aW9ucy5kYXRhXSAgICAgICAgVGhlIGRhdGEgb2JqZWN0LlxuICAgICAqIEBwYXJhbSAge09iamVjdH0gICAgICAgICAgICBbb3B0aW9ucy5wZXJtaXNzaW9uc10gVGhlIHBlcm1pc3Npb25zIG9iamVjdC5cbiAgICAgKiBAcGFyYW0gIHtCb29sZWFufSAgICAgICAgICAgW29wdGlvbnMuc2FmZV0gICAgICAgIFRoZSBzYWZlIG9wdGlvbi5cbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9ICAgICAgICAgICAgW29wdGlvbnMuaGVhZGVyc10gICAgIFRoZSBoZWFkZXJzIG9iamVjdCBvcHRpb24uXG4gICAgICogQHBhcmFtICB7TnVtYmVyfSAgICAgICAgICAgIFtvcHRpb25zLnJldHJ5PTBdICAgICBOdW1iZXIgb2YgcmV0cmllcyB0byBtYWtlXG4gICAgICogICAgIHdoZW4gZmFjZWQgd2l0aCB0cmFuc2llbnQgZXJyb3JzLlxuICAgICAqIEByZXR1cm4ge1Byb21pc2U8T2JqZWN0LCBFcnJvcj59XG4gICAgICovXG5cbiAgfSwge1xuICAgIGtleTogXCJjcmVhdGVHcm91cFwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgX2NyZWF0ZUdyb3VwID0gKDAsIF9hc3luY1RvR2VuZXJhdG9yMi5kZWZhdWx0KShcbiAgICAgIC8qI19fUFVSRV9fKi9cbiAgICAgIF9yZWdlbmVyYXRvci5kZWZhdWx0Lm1hcmsoZnVuY3Rpb24gX2NhbGxlZTkoaWQpIHtcbiAgICAgICAgdmFyIG1lbWJlcnMsXG4gICAgICAgICAgICBvcHRpb25zLFxuICAgICAgICAgICAgZGF0YSxcbiAgICAgICAgICAgIHBhdGgsXG4gICAgICAgICAgICBwZXJtaXNzaW9ucyxcbiAgICAgICAgICAgIHJlcXVlc3QsXG4gICAgICAgICAgICBfYXJnczkgPSBhcmd1bWVudHM7XG4gICAgICAgIHJldHVybiBfcmVnZW5lcmF0b3IuZGVmYXVsdC53cmFwKGZ1bmN0aW9uIF9jYWxsZWU5JChfY29udGV4dDkpIHtcbiAgICAgICAgICB3aGlsZSAoMSkge1xuICAgICAgICAgICAgc3dpdGNoIChfY29udGV4dDkucHJldiA9IF9jb250ZXh0OS5uZXh0KSB7XG4gICAgICAgICAgICAgIGNhc2UgMDpcbiAgICAgICAgICAgICAgICBtZW1iZXJzID0gX2FyZ3M5Lmxlbmd0aCA+IDEgJiYgX2FyZ3M5WzFdICE9PSB1bmRlZmluZWQgPyBfYXJnczlbMV0gOiBbXTtcbiAgICAgICAgICAgICAgICBvcHRpb25zID0gX2FyZ3M5Lmxlbmd0aCA+IDIgJiYgX2FyZ3M5WzJdICE9PSB1bmRlZmluZWQgPyBfYXJnczlbMl0gOiB7fTtcbiAgICAgICAgICAgICAgICBkYXRhID0gKDAsIF9vYmplY3RTcHJlYWQyLmRlZmF1bHQpKHt9LCBvcHRpb25zLmRhdGEsIHtcbiAgICAgICAgICAgICAgICAgIGlkOiBpZCxcbiAgICAgICAgICAgICAgICAgIG1lbWJlcnM6IG1lbWJlcnNcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICBwYXRoID0gKDAsIF9lbmRwb2ludC5kZWZhdWx0KShcImdyb3VwXCIsIHRoaXMubmFtZSwgaWQpO1xuICAgICAgICAgICAgICAgIHBlcm1pc3Npb25zID0gb3B0aW9ucy5wZXJtaXNzaW9ucztcbiAgICAgICAgICAgICAgICByZXF1ZXN0ID0gcmVxdWVzdHMuY3JlYXRlUmVxdWVzdChwYXRoLCB7XG4gICAgICAgICAgICAgICAgICBkYXRhOiBkYXRhLFxuICAgICAgICAgICAgICAgICAgcGVybWlzc2lvbnM6IHBlcm1pc3Npb25zXG4gICAgICAgICAgICAgICAgfSwge1xuICAgICAgICAgICAgICAgICAgaGVhZGVyczogdGhpcy5fZ2V0SGVhZGVycyhvcHRpb25zKSxcbiAgICAgICAgICAgICAgICAgIHNhZmU6IHRoaXMuX2dldFNhZmUob3B0aW9ucylcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQ5LmFicnVwdChcInJldHVyblwiLCB0aGlzLmNsaWVudC5leGVjdXRlKHJlcXVlc3QsIHtcbiAgICAgICAgICAgICAgICAgIHJldHJ5OiB0aGlzLl9nZXRSZXRyeShvcHRpb25zKVxuICAgICAgICAgICAgICAgIH0pKTtcblxuICAgICAgICAgICAgICBjYXNlIDc6XG4gICAgICAgICAgICAgIGNhc2UgXCJlbmRcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQ5LnN0b3AoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0sIF9jYWxsZWU5LCB0aGlzKTtcbiAgICAgIH0pKTtcblxuICAgICAgcmV0dXJuIGZ1bmN0aW9uIGNyZWF0ZUdyb3VwKF94NSkge1xuICAgICAgICByZXR1cm4gX2NyZWF0ZUdyb3VwLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICB9O1xuICAgIH0oKVxuICAgIC8qKlxuICAgICAqIFVwZGF0ZXMgYW4gZXhpc3RpbmcgZ3JvdXAgaW4gY3VycmVudCBidWNrZXQuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9ICBncm91cCAgICAgICAgICAgICAgICAgICBUaGUgZ3JvdXAgb2JqZWN0LlxuICAgICAqIEBwYXJhbSAge09iamVjdH0gIFtvcHRpb25zPXt9XSAgICAgICAgICAgIFRoZSBvcHRpb25zIG9iamVjdC5cbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9ICBbb3B0aW9ucy5kYXRhXSAgICAgICAgICBUaGUgZGF0YSBvYmplY3QuXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSAgW29wdGlvbnMucGVybWlzc2lvbnNdICAgVGhlIHBlcm1pc3Npb25zIG9iamVjdC5cbiAgICAgKiBAcGFyYW0gIHtCb29sZWFufSBbb3B0aW9ucy5zYWZlXSAgICAgICAgICBUaGUgc2FmZSBvcHRpb24uXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSAgW29wdGlvbnMuaGVhZGVyc10gICAgICAgVGhlIGhlYWRlcnMgb2JqZWN0IG9wdGlvbi5cbiAgICAgKiBAcGFyYW0gIHtOdW1iZXJ9ICBbb3B0aW9ucy5yZXRyeT0wXSAgICAgICBOdW1iZXIgb2YgcmV0cmllcyB0byBtYWtlXG4gICAgICogICAgIHdoZW4gZmFjZWQgd2l0aCB0cmFuc2llbnQgZXJyb3JzLlxuICAgICAqIEBwYXJhbSAge051bWJlcn0gIFtvcHRpb25zLmxhc3RfbW9kaWZpZWRdIFRoZSBsYXN0X21vZGlmaWVkIG9wdGlvbi5cbiAgICAgKiBAcmV0dXJuIHtQcm9taXNlPE9iamVjdCwgRXJyb3I+fVxuICAgICAqL1xuXG4gIH0sIHtcbiAgICBrZXk6IFwidXBkYXRlR3JvdXBcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gKCkge1xuICAgICAgdmFyIF91cGRhdGVHcm91cCA9ICgwLCBfYXN5bmNUb0dlbmVyYXRvcjIuZGVmYXVsdCkoXG4gICAgICAvKiNfX1BVUkVfXyovXG4gICAgICBfcmVnZW5lcmF0b3IuZGVmYXVsdC5tYXJrKGZ1bmN0aW9uIF9jYWxsZWUxMChncm91cCkge1xuICAgICAgICB2YXIgb3B0aW9ucyxcbiAgICAgICAgICAgIGRhdGEsXG4gICAgICAgICAgICBwYXRoLFxuICAgICAgICAgICAgcGF0Y2gsXG4gICAgICAgICAgICBwZXJtaXNzaW9ucyxcbiAgICAgICAgICAgIF9kYXRhJG9wdGlvbnMyLFxuICAgICAgICAgICAgbGFzdF9tb2RpZmllZCxcbiAgICAgICAgICAgIHJlcXVlc3QsXG4gICAgICAgICAgICBfYXJnczEwID0gYXJndW1lbnRzO1xuXG4gICAgICAgIHJldHVybiBfcmVnZW5lcmF0b3IuZGVmYXVsdC53cmFwKGZ1bmN0aW9uIF9jYWxsZWUxMCQoX2NvbnRleHQxMCkge1xuICAgICAgICAgIHdoaWxlICgxKSB7XG4gICAgICAgICAgICBzd2l0Y2ggKF9jb250ZXh0MTAucHJldiA9IF9jb250ZXh0MTAubmV4dCkge1xuICAgICAgICAgICAgICBjYXNlIDA6XG4gICAgICAgICAgICAgICAgb3B0aW9ucyA9IF9hcmdzMTAubGVuZ3RoID4gMSAmJiBfYXJnczEwWzFdICE9PSB1bmRlZmluZWQgPyBfYXJnczEwWzFdIDoge307XG5cbiAgICAgICAgICAgICAgICBpZiAoKDAsIF91dGlscy5pc09iamVjdCkoZ3JvdXApKSB7XG4gICAgICAgICAgICAgICAgICBfY29udGV4dDEwLm5leHQgPSAzO1xuICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQSBncm91cCBvYmplY3QgaXMgcmVxdWlyZWQuXCIpO1xuXG4gICAgICAgICAgICAgIGNhc2UgMzpcbiAgICAgICAgICAgICAgICBpZiAoZ3JvdXAuaWQpIHtcbiAgICAgICAgICAgICAgICAgIF9jb250ZXh0MTAubmV4dCA9IDU7XG4gICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJBIGdyb3VwIGlkIGlzIHJlcXVpcmVkLlwiKTtcblxuICAgICAgICAgICAgICBjYXNlIDU6XG4gICAgICAgICAgICAgICAgZGF0YSA9ICgwLCBfb2JqZWN0U3ByZWFkMi5kZWZhdWx0KSh7fSwgb3B0aW9ucy5kYXRhLCBncm91cCk7XG4gICAgICAgICAgICAgICAgcGF0aCA9ICgwLCBfZW5kcG9pbnQuZGVmYXVsdCkoXCJncm91cFwiLCB0aGlzLm5hbWUsIGdyb3VwLmlkKTtcbiAgICAgICAgICAgICAgICBwYXRjaCA9IG9wdGlvbnMucGF0Y2gsIHBlcm1pc3Npb25zID0gb3B0aW9ucy5wZXJtaXNzaW9ucztcbiAgICAgICAgICAgICAgICBfZGF0YSRvcHRpb25zMiA9ICgwLCBfb2JqZWN0U3ByZWFkMi5kZWZhdWx0KSh7fSwgZGF0YSwgb3B0aW9ucyksIGxhc3RfbW9kaWZpZWQgPSBfZGF0YSRvcHRpb25zMi5sYXN0X21vZGlmaWVkO1xuICAgICAgICAgICAgICAgIHJlcXVlc3QgPSByZXF1ZXN0cy51cGRhdGVSZXF1ZXN0KHBhdGgsIHtcbiAgICAgICAgICAgICAgICAgIGRhdGE6IGRhdGEsXG4gICAgICAgICAgICAgICAgICBwZXJtaXNzaW9uczogcGVybWlzc2lvbnNcbiAgICAgICAgICAgICAgICB9LCB7XG4gICAgICAgICAgICAgICAgICBsYXN0X21vZGlmaWVkOiBsYXN0X21vZGlmaWVkLFxuICAgICAgICAgICAgICAgICAgcGF0Y2g6IHBhdGNoLFxuICAgICAgICAgICAgICAgICAgaGVhZGVyczogdGhpcy5fZ2V0SGVhZGVycyhvcHRpb25zKSxcbiAgICAgICAgICAgICAgICAgIHNhZmU6IHRoaXMuX2dldFNhZmUob3B0aW9ucylcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQxMC5hYnJ1cHQoXCJyZXR1cm5cIiwgdGhpcy5jbGllbnQuZXhlY3V0ZShyZXF1ZXN0LCB7XG4gICAgICAgICAgICAgICAgICByZXRyeTogdGhpcy5fZ2V0UmV0cnkob3B0aW9ucylcbiAgICAgICAgICAgICAgICB9KSk7XG5cbiAgICAgICAgICAgICAgY2FzZSAxMTpcbiAgICAgICAgICAgICAgY2FzZSBcImVuZFwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDEwLnN0b3AoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0sIF9jYWxsZWUxMCwgdGhpcyk7XG4gICAgICB9KSk7XG5cbiAgICAgIHJldHVybiBmdW5jdGlvbiB1cGRhdGVHcm91cChfeDYpIHtcbiAgICAgICAgcmV0dXJuIF91cGRhdGVHcm91cC5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgfTtcbiAgICB9KClcbiAgICAvKipcbiAgICAgKiBEZWxldGVzIGEgZ3JvdXAgZnJvbSB0aGUgY3VycmVudCBidWNrZXQuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gIHtPYmplY3R8U3RyaW5nfSBncm91cCAgICAgICAgICAgICAgICAgICBUaGUgZ3JvdXAgdG8gZGVsZXRlLlxuICAgICAqIEBwYXJhbSAge09iamVjdH0gICAgICAgIFtvcHRpb25zPXt9XSAgICAgICAgICAgIFRoZSBvcHRpb25zIG9iamVjdC5cbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9ICAgICAgICBbb3B0aW9ucy5oZWFkZXJzXSAgICAgICBUaGUgaGVhZGVycyBvYmplY3Qgb3B0aW9uLlxuICAgICAqIEBwYXJhbSAge051bWJlcn0gICAgICAgIFtvcHRpb25zLnJldHJ5PTBdICAgICAgIE51bWJlciBvZiByZXRyaWVzIHRvIG1ha2VcbiAgICAgKiAgICAgd2hlbiBmYWNlZCB3aXRoIHRyYW5zaWVudCBlcnJvcnMuXG4gICAgICogQHBhcmFtICB7Qm9vbGVhbn0gICAgICAgW29wdGlvbnMuc2FmZV0gICAgICAgICAgVGhlIHNhZmUgb3B0aW9uLlxuICAgICAqIEBwYXJhbSAge051bWJlcn0gICAgICAgIFtvcHRpb25zLmxhc3RfbW9kaWZpZWRdIFRoZSBsYXN0X21vZGlmaWVkIG9wdGlvbi5cbiAgICAgKiBAcmV0dXJuIHtQcm9taXNlPE9iamVjdCwgRXJyb3I+fVxuICAgICAqL1xuXG4gIH0sIHtcbiAgICBrZXk6IFwiZGVsZXRlR3JvdXBcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gKCkge1xuICAgICAgdmFyIF9kZWxldGVHcm91cCA9ICgwLCBfYXN5bmNUb0dlbmVyYXRvcjIuZGVmYXVsdCkoXG4gICAgICAvKiNfX1BVUkVfXyovXG4gICAgICBfcmVnZW5lcmF0b3IuZGVmYXVsdC5tYXJrKGZ1bmN0aW9uIF9jYWxsZWUxMShncm91cCkge1xuICAgICAgICB2YXIgb3B0aW9ucyxcbiAgICAgICAgICAgIGdyb3VwT2JqLFxuICAgICAgICAgICAgaWQsXG4gICAgICAgICAgICBfZ3JvdXBPYmokb3B0aW9ucyxcbiAgICAgICAgICAgIGxhc3RfbW9kaWZpZWQsXG4gICAgICAgICAgICBwYXRoLFxuICAgICAgICAgICAgcmVxdWVzdCxcbiAgICAgICAgICAgIF9hcmdzMTEgPSBhcmd1bWVudHM7XG5cbiAgICAgICAgcmV0dXJuIF9yZWdlbmVyYXRvci5kZWZhdWx0LndyYXAoZnVuY3Rpb24gX2NhbGxlZTExJChfY29udGV4dDExKSB7XG4gICAgICAgICAgd2hpbGUgKDEpIHtcbiAgICAgICAgICAgIHN3aXRjaCAoX2NvbnRleHQxMS5wcmV2ID0gX2NvbnRleHQxMS5uZXh0KSB7XG4gICAgICAgICAgICAgIGNhc2UgMDpcbiAgICAgICAgICAgICAgICBvcHRpb25zID0gX2FyZ3MxMS5sZW5ndGggPiAxICYmIF9hcmdzMTFbMV0gIT09IHVuZGVmaW5lZCA/IF9hcmdzMTFbMV0gOiB7fTtcbiAgICAgICAgICAgICAgICBncm91cE9iaiA9ICgwLCBfdXRpbHMudG9EYXRhQm9keSkoZ3JvdXApO1xuICAgICAgICAgICAgICAgIGlkID0gZ3JvdXBPYmouaWQ7XG4gICAgICAgICAgICAgICAgX2dyb3VwT2JqJG9wdGlvbnMgPSAoMCwgX29iamVjdFNwcmVhZDIuZGVmYXVsdCkoe30sIGdyb3VwT2JqLCBvcHRpb25zKSwgbGFzdF9tb2RpZmllZCA9IF9ncm91cE9iaiRvcHRpb25zLmxhc3RfbW9kaWZpZWQ7XG4gICAgICAgICAgICAgICAgcGF0aCA9ICgwLCBfZW5kcG9pbnQuZGVmYXVsdCkoXCJncm91cFwiLCB0aGlzLm5hbWUsIGlkKTtcbiAgICAgICAgICAgICAgICByZXF1ZXN0ID0gcmVxdWVzdHMuZGVsZXRlUmVxdWVzdChwYXRoLCB7XG4gICAgICAgICAgICAgICAgICBsYXN0X21vZGlmaWVkOiBsYXN0X21vZGlmaWVkLFxuICAgICAgICAgICAgICAgICAgaGVhZGVyczogdGhpcy5fZ2V0SGVhZGVycyhvcHRpb25zKSxcbiAgICAgICAgICAgICAgICAgIHNhZmU6IHRoaXMuX2dldFNhZmUob3B0aW9ucylcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQxMS5hYnJ1cHQoXCJyZXR1cm5cIiwgdGhpcy5jbGllbnQuZXhlY3V0ZShyZXF1ZXN0LCB7XG4gICAgICAgICAgICAgICAgICByZXRyeTogdGhpcy5fZ2V0UmV0cnkob3B0aW9ucylcbiAgICAgICAgICAgICAgICB9KSk7XG5cbiAgICAgICAgICAgICAgY2FzZSA3OlxuICAgICAgICAgICAgICBjYXNlIFwiZW5kXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0MTEuc3RvcCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSwgX2NhbGxlZTExLCB0aGlzKTtcbiAgICAgIH0pKTtcblxuICAgICAgcmV0dXJuIGZ1bmN0aW9uIGRlbGV0ZUdyb3VwKF94Nykge1xuICAgICAgICByZXR1cm4gX2RlbGV0ZUdyb3VwLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICB9O1xuICAgIH0oKVxuICAgIC8qKlxuICAgICAqIFJldHJpZXZlcyB0aGUgbGlzdCBvZiBwZXJtaXNzaW9ucyBmb3IgdGhpcyBidWNrZXQuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9IFtvcHRpb25zPXt9XSAgICAgIFRoZSBvcHRpb25zIG9iamVjdC5cbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9IFtvcHRpb25zLmhlYWRlcnNdIFRoZSBoZWFkZXJzIG9iamVjdCBvcHRpb24uXG4gICAgICogQHBhcmFtICB7TnVtYmVyfSBbb3B0aW9ucy5yZXRyeT0wXSBOdW1iZXIgb2YgcmV0cmllcyB0byBtYWtlXG4gICAgICogICAgIHdoZW4gZmFjZWQgd2l0aCB0cmFuc2llbnQgZXJyb3JzLlxuICAgICAqIEByZXR1cm4ge1Byb21pc2U8T2JqZWN0LCBFcnJvcj59XG4gICAgICovXG5cbiAgfSwge1xuICAgIGtleTogXCJnZXRQZXJtaXNzaW9uc1wiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgX2dldFBlcm1pc3Npb25zID0gKDAsIF9hc3luY1RvR2VuZXJhdG9yMi5kZWZhdWx0KShcbiAgICAgIC8qI19fUFVSRV9fKi9cbiAgICAgIF9yZWdlbmVyYXRvci5kZWZhdWx0Lm1hcmsoZnVuY3Rpb24gX2NhbGxlZTEyKCkge1xuICAgICAgICB2YXIgb3B0aW9ucyxcbiAgICAgICAgICAgIHJlcXVlc3QsXG4gICAgICAgICAgICBfcmVmMixcbiAgICAgICAgICAgIHBlcm1pc3Npb25zLFxuICAgICAgICAgICAgX2FyZ3MxMiA9IGFyZ3VtZW50cztcblxuICAgICAgICByZXR1cm4gX3JlZ2VuZXJhdG9yLmRlZmF1bHQud3JhcChmdW5jdGlvbiBfY2FsbGVlMTIkKF9jb250ZXh0MTIpIHtcbiAgICAgICAgICB3aGlsZSAoMSkge1xuICAgICAgICAgICAgc3dpdGNoIChfY29udGV4dDEyLnByZXYgPSBfY29udGV4dDEyLm5leHQpIHtcbiAgICAgICAgICAgICAgY2FzZSAwOlxuICAgICAgICAgICAgICAgIG9wdGlvbnMgPSBfYXJnczEyLmxlbmd0aCA+IDAgJiYgX2FyZ3MxMlswXSAhPT0gdW5kZWZpbmVkID8gX2FyZ3MxMlswXSA6IHt9O1xuICAgICAgICAgICAgICAgIHJlcXVlc3QgPSB7XG4gICAgICAgICAgICAgICAgICBoZWFkZXJzOiB0aGlzLl9nZXRIZWFkZXJzKG9wdGlvbnMpLFxuICAgICAgICAgICAgICAgICAgcGF0aDogKDAsIF9lbmRwb2ludC5kZWZhdWx0KShcImJ1Y2tldFwiLCB0aGlzLm5hbWUpXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICBfY29udGV4dDEyLm5leHQgPSA0O1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmNsaWVudC5leGVjdXRlKHJlcXVlc3QsIHtcbiAgICAgICAgICAgICAgICAgIHJldHJ5OiB0aGlzLl9nZXRSZXRyeShvcHRpb25zKVxuICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgIGNhc2UgNDpcbiAgICAgICAgICAgICAgICBfcmVmMiA9IF9jb250ZXh0MTIuc2VudDtcbiAgICAgICAgICAgICAgICBwZXJtaXNzaW9ucyA9IF9yZWYyLnBlcm1pc3Npb25zO1xuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDEyLmFicnVwdChcInJldHVyblwiLCBwZXJtaXNzaW9ucyk7XG5cbiAgICAgICAgICAgICAgY2FzZSA3OlxuICAgICAgICAgICAgICBjYXNlIFwiZW5kXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0MTIuc3RvcCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSwgX2NhbGxlZTEyLCB0aGlzKTtcbiAgICAgIH0pKTtcblxuICAgICAgcmV0dXJuIGZ1bmN0aW9uIGdldFBlcm1pc3Npb25zKCkge1xuICAgICAgICByZXR1cm4gX2dldFBlcm1pc3Npb25zLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICB9O1xuICAgIH0oKVxuICAgIC8qKlxuICAgICAqIFJlcGxhY2VzIGFsbCBleGlzdGluZyBidWNrZXQgcGVybWlzc2lvbnMgd2l0aCB0aGUgb25lcyBwcm92aWRlZC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSAge09iamVjdH0gIHBlcm1pc3Npb25zICAgICAgICAgICAgIFRoZSBwZXJtaXNzaW9ucyBvYmplY3QuXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSAgW29wdGlvbnM9e31dICAgICAgICAgICAgVGhlIG9wdGlvbnMgb2JqZWN0XG4gICAgICogQHBhcmFtICB7Qm9vbGVhbn0gW29wdGlvbnMuc2FmZV0gICAgICAgICAgVGhlIHNhZmUgb3B0aW9uLlxuICAgICAqIEBwYXJhbSAge09iamVjdH0gIFtvcHRpb25zLmhlYWRlcnM9e31dICAgIFRoZSBoZWFkZXJzIG9iamVjdCBvcHRpb24uXG4gICAgICogQHBhcmFtICB7TnVtYmVyfSAgW29wdGlvbnMucmV0cnk9MF0gICAgICAgTnVtYmVyIG9mIHJldHJpZXMgdG8gbWFrZVxuICAgICAqICAgICB3aGVuIGZhY2VkIHdpdGggdHJhbnNpZW50IGVycm9ycy5cbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9ICBbb3B0aW9ucy5sYXN0X21vZGlmaWVkXSBUaGUgbGFzdF9tb2RpZmllZCBvcHRpb24uXG4gICAgICogQHJldHVybiB7UHJvbWlzZTxPYmplY3QsIEVycm9yPn1cbiAgICAgKi9cblxuICB9LCB7XG4gICAga2V5OiBcInNldFBlcm1pc3Npb25zXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciBfc2V0UGVybWlzc2lvbnMgPSAoMCwgX2FzeW5jVG9HZW5lcmF0b3IyLmRlZmF1bHQpKFxuICAgICAgLyojX19QVVJFX18qL1xuICAgICAgX3JlZ2VuZXJhdG9yLmRlZmF1bHQubWFyayhmdW5jdGlvbiBfY2FsbGVlMTMocGVybWlzc2lvbnMpIHtcbiAgICAgICAgdmFyIG9wdGlvbnMsXG4gICAgICAgICAgICBwYXRoLFxuICAgICAgICAgICAgbGFzdF9tb2RpZmllZCxcbiAgICAgICAgICAgIGRhdGEsXG4gICAgICAgICAgICByZXF1ZXN0LFxuICAgICAgICAgICAgX2FyZ3MxMyA9IGFyZ3VtZW50cztcbiAgICAgICAgcmV0dXJuIF9yZWdlbmVyYXRvci5kZWZhdWx0LndyYXAoZnVuY3Rpb24gX2NhbGxlZTEzJChfY29udGV4dDEzKSB7XG4gICAgICAgICAgd2hpbGUgKDEpIHtcbiAgICAgICAgICAgIHN3aXRjaCAoX2NvbnRleHQxMy5wcmV2ID0gX2NvbnRleHQxMy5uZXh0KSB7XG4gICAgICAgICAgICAgIGNhc2UgMDpcbiAgICAgICAgICAgICAgICBvcHRpb25zID0gX2FyZ3MxMy5sZW5ndGggPiAxICYmIF9hcmdzMTNbMV0gIT09IHVuZGVmaW5lZCA/IF9hcmdzMTNbMV0gOiB7fTtcblxuICAgICAgICAgICAgICAgIGlmICgoMCwgX3V0aWxzLmlzT2JqZWN0KShwZXJtaXNzaW9ucykpIHtcbiAgICAgICAgICAgICAgICAgIF9jb250ZXh0MTMubmV4dCA9IDM7XG4gICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJBIHBlcm1pc3Npb25zIG9iamVjdCBpcyByZXF1aXJlZC5cIik7XG5cbiAgICAgICAgICAgICAgY2FzZSAzOlxuICAgICAgICAgICAgICAgIHBhdGggPSAoMCwgX2VuZHBvaW50LmRlZmF1bHQpKFwiYnVja2V0XCIsIHRoaXMubmFtZSk7XG4gICAgICAgICAgICAgICAgbGFzdF9tb2RpZmllZCA9IG9wdGlvbnMubGFzdF9tb2RpZmllZDtcbiAgICAgICAgICAgICAgICBkYXRhID0ge1xuICAgICAgICAgICAgICAgICAgbGFzdF9tb2RpZmllZDogbGFzdF9tb2RpZmllZFxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgcmVxdWVzdCA9IHJlcXVlc3RzLnVwZGF0ZVJlcXVlc3QocGF0aCwge1xuICAgICAgICAgICAgICAgICAgZGF0YTogZGF0YSxcbiAgICAgICAgICAgICAgICAgIHBlcm1pc3Npb25zOiBwZXJtaXNzaW9uc1xuICAgICAgICAgICAgICAgIH0sIHtcbiAgICAgICAgICAgICAgICAgIGhlYWRlcnM6IHRoaXMuX2dldEhlYWRlcnMob3B0aW9ucyksXG4gICAgICAgICAgICAgICAgICBzYWZlOiB0aGlzLl9nZXRTYWZlKG9wdGlvbnMpXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0MTMuYWJydXB0KFwicmV0dXJuXCIsIHRoaXMuY2xpZW50LmV4ZWN1dGUocmVxdWVzdCwge1xuICAgICAgICAgICAgICAgICAgcmV0cnk6IHRoaXMuX2dldFJldHJ5KG9wdGlvbnMpXG4gICAgICAgICAgICAgICAgfSkpO1xuXG4gICAgICAgICAgICAgIGNhc2UgODpcbiAgICAgICAgICAgICAgY2FzZSBcImVuZFwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDEzLnN0b3AoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0sIF9jYWxsZWUxMywgdGhpcyk7XG4gICAgICB9KSk7XG5cbiAgICAgIHJldHVybiBmdW5jdGlvbiBzZXRQZXJtaXNzaW9ucyhfeDgpIHtcbiAgICAgICAgcmV0dXJuIF9zZXRQZXJtaXNzaW9ucy5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgfTtcbiAgICB9KClcbiAgICAvKipcbiAgICAgKiBBcHBlbmQgcHJpbmNpcGFscyB0byB0aGUgYnVja2V0IHBlcm1pc3Npb25zLlxuICAgICAqXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSAgcGVybWlzc2lvbnMgICAgICAgICAgICAgVGhlIHBlcm1pc3Npb25zIG9iamVjdC5cbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9ICBbb3B0aW9ucz17fV0gICAgICAgICAgICBUaGUgb3B0aW9ucyBvYmplY3RcbiAgICAgKiBAcGFyYW0gIHtCb29sZWFufSBbb3B0aW9ucy5zYWZlXSAgICAgICAgICBUaGUgc2FmZSBvcHRpb24uXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSAgW29wdGlvbnMuaGVhZGVyc10gICAgICAgVGhlIGhlYWRlcnMgb2JqZWN0IG9wdGlvbi5cbiAgICAgKiBAcGFyYW0gIHtOdW1iZXJ9ICBbb3B0aW9ucy5yZXRyeT0wXSAgICAgICBOdW1iZXIgb2YgcmV0cmllcyB0byBtYWtlXG4gICAgICogICAgIHdoZW4gZmFjZWQgd2l0aCB0cmFuc2llbnQgZXJyb3JzLlxuICAgICAqIEBwYXJhbSAge09iamVjdH0gIFtvcHRpb25zLmxhc3RfbW9kaWZpZWRdIFRoZSBsYXN0X21vZGlmaWVkIG9wdGlvbi5cbiAgICAgKiBAcmV0dXJuIHtQcm9taXNlPE9iamVjdCwgRXJyb3I+fVxuICAgICAqL1xuXG4gIH0sIHtcbiAgICBrZXk6IFwiYWRkUGVybWlzc2lvbnNcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gKCkge1xuICAgICAgdmFyIF9hZGRQZXJtaXNzaW9ucyA9ICgwLCBfYXN5bmNUb0dlbmVyYXRvcjIuZGVmYXVsdCkoXG4gICAgICAvKiNfX1BVUkVfXyovXG4gICAgICBfcmVnZW5lcmF0b3IuZGVmYXVsdC5tYXJrKGZ1bmN0aW9uIF9jYWxsZWUxNChwZXJtaXNzaW9ucykge1xuICAgICAgICB2YXIgb3B0aW9ucyxcbiAgICAgICAgICAgIHBhdGgsXG4gICAgICAgICAgICBsYXN0X21vZGlmaWVkLFxuICAgICAgICAgICAgcmVxdWVzdCxcbiAgICAgICAgICAgIF9hcmdzMTQgPSBhcmd1bWVudHM7XG4gICAgICAgIHJldHVybiBfcmVnZW5lcmF0b3IuZGVmYXVsdC53cmFwKGZ1bmN0aW9uIF9jYWxsZWUxNCQoX2NvbnRleHQxNCkge1xuICAgICAgICAgIHdoaWxlICgxKSB7XG4gICAgICAgICAgICBzd2l0Y2ggKF9jb250ZXh0MTQucHJldiA9IF9jb250ZXh0MTQubmV4dCkge1xuICAgICAgICAgICAgICBjYXNlIDA6XG4gICAgICAgICAgICAgICAgb3B0aW9ucyA9IF9hcmdzMTQubGVuZ3RoID4gMSAmJiBfYXJnczE0WzFdICE9PSB1bmRlZmluZWQgPyBfYXJnczE0WzFdIDoge307XG5cbiAgICAgICAgICAgICAgICBpZiAoKDAsIF91dGlscy5pc09iamVjdCkocGVybWlzc2lvbnMpKSB7XG4gICAgICAgICAgICAgICAgICBfY29udGV4dDE0Lm5leHQgPSAzO1xuICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQSBwZXJtaXNzaW9ucyBvYmplY3QgaXMgcmVxdWlyZWQuXCIpO1xuXG4gICAgICAgICAgICAgIGNhc2UgMzpcbiAgICAgICAgICAgICAgICBwYXRoID0gKDAsIF9lbmRwb2ludC5kZWZhdWx0KShcImJ1Y2tldFwiLCB0aGlzLm5hbWUpO1xuICAgICAgICAgICAgICAgIGxhc3RfbW9kaWZpZWQgPSBvcHRpb25zLmxhc3RfbW9kaWZpZWQ7XG4gICAgICAgICAgICAgICAgcmVxdWVzdCA9IHJlcXVlc3RzLmpzb25QYXRjaFBlcm1pc3Npb25zUmVxdWVzdChwYXRoLCBwZXJtaXNzaW9ucywgXCJhZGRcIiwge1xuICAgICAgICAgICAgICAgICAgbGFzdF9tb2RpZmllZDogbGFzdF9tb2RpZmllZCxcbiAgICAgICAgICAgICAgICAgIGhlYWRlcnM6IHRoaXMuX2dldEhlYWRlcnMob3B0aW9ucyksXG4gICAgICAgICAgICAgICAgICBzYWZlOiB0aGlzLl9nZXRTYWZlKG9wdGlvbnMpXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0MTQuYWJydXB0KFwicmV0dXJuXCIsIHRoaXMuY2xpZW50LmV4ZWN1dGUocmVxdWVzdCwge1xuICAgICAgICAgICAgICAgICAgcmV0cnk6IHRoaXMuX2dldFJldHJ5KG9wdGlvbnMpXG4gICAgICAgICAgICAgICAgfSkpO1xuXG4gICAgICAgICAgICAgIGNhc2UgNzpcbiAgICAgICAgICAgICAgY2FzZSBcImVuZFwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDE0LnN0b3AoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0sIF9jYWxsZWUxNCwgdGhpcyk7XG4gICAgICB9KSk7XG5cbiAgICAgIHJldHVybiBmdW5jdGlvbiBhZGRQZXJtaXNzaW9ucyhfeDkpIHtcbiAgICAgICAgcmV0dXJuIF9hZGRQZXJtaXNzaW9ucy5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgfTtcbiAgICB9KClcbiAgICAvKipcbiAgICAgKiBSZW1vdmUgcHJpbmNpcGFscyBmcm9tIHRoZSBidWNrZXQgcGVybWlzc2lvbnMuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9ICBwZXJtaXNzaW9ucyAgICAgICAgICAgICBUaGUgcGVybWlzc2lvbnMgb2JqZWN0LlxuICAgICAqIEBwYXJhbSAge09iamVjdH0gIFtvcHRpb25zPXt9XSAgICAgICAgICAgIFRoZSBvcHRpb25zIG9iamVjdFxuICAgICAqIEBwYXJhbSAge0Jvb2xlYW59IFtvcHRpb25zLnNhZmVdICAgICAgICAgIFRoZSBzYWZlIG9wdGlvbi5cbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9ICBbb3B0aW9ucy5oZWFkZXJzXSAgICAgICBUaGUgaGVhZGVycyBvYmplY3Qgb3B0aW9uLlxuICAgICAqIEBwYXJhbSAge051bWJlcn0gIFtvcHRpb25zLnJldHJ5PTBdICAgICAgIE51bWJlciBvZiByZXRyaWVzIHRvIG1ha2VcbiAgICAgKiAgICAgd2hlbiBmYWNlZCB3aXRoIHRyYW5zaWVudCBlcnJvcnMuXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSAgW29wdGlvbnMubGFzdF9tb2RpZmllZF0gVGhlIGxhc3RfbW9kaWZpZWQgb3B0aW9uLlxuICAgICAqIEByZXR1cm4ge1Byb21pc2U8T2JqZWN0LCBFcnJvcj59XG4gICAgICovXG5cbiAgfSwge1xuICAgIGtleTogXCJyZW1vdmVQZXJtaXNzaW9uc1wiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgX3JlbW92ZVBlcm1pc3Npb25zID0gKDAsIF9hc3luY1RvR2VuZXJhdG9yMi5kZWZhdWx0KShcbiAgICAgIC8qI19fUFVSRV9fKi9cbiAgICAgIF9yZWdlbmVyYXRvci5kZWZhdWx0Lm1hcmsoZnVuY3Rpb24gX2NhbGxlZTE1KHBlcm1pc3Npb25zKSB7XG4gICAgICAgIHZhciBvcHRpb25zLFxuICAgICAgICAgICAgcGF0aCxcbiAgICAgICAgICAgIGxhc3RfbW9kaWZpZWQsXG4gICAgICAgICAgICByZXF1ZXN0LFxuICAgICAgICAgICAgX2FyZ3MxNSA9IGFyZ3VtZW50cztcbiAgICAgICAgcmV0dXJuIF9yZWdlbmVyYXRvci5kZWZhdWx0LndyYXAoZnVuY3Rpb24gX2NhbGxlZTE1JChfY29udGV4dDE1KSB7XG4gICAgICAgICAgd2hpbGUgKDEpIHtcbiAgICAgICAgICAgIHN3aXRjaCAoX2NvbnRleHQxNS5wcmV2ID0gX2NvbnRleHQxNS5uZXh0KSB7XG4gICAgICAgICAgICAgIGNhc2UgMDpcbiAgICAgICAgICAgICAgICBvcHRpb25zID0gX2FyZ3MxNS5sZW5ndGggPiAxICYmIF9hcmdzMTVbMV0gIT09IHVuZGVmaW5lZCA/IF9hcmdzMTVbMV0gOiB7fTtcblxuICAgICAgICAgICAgICAgIGlmICgoMCwgX3V0aWxzLmlzT2JqZWN0KShwZXJtaXNzaW9ucykpIHtcbiAgICAgICAgICAgICAgICAgIF9jb250ZXh0MTUubmV4dCA9IDM7XG4gICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJBIHBlcm1pc3Npb25zIG9iamVjdCBpcyByZXF1aXJlZC5cIik7XG5cbiAgICAgICAgICAgICAgY2FzZSAzOlxuICAgICAgICAgICAgICAgIHBhdGggPSAoMCwgX2VuZHBvaW50LmRlZmF1bHQpKFwiYnVja2V0XCIsIHRoaXMubmFtZSk7XG4gICAgICAgICAgICAgICAgbGFzdF9tb2RpZmllZCA9IG9wdGlvbnMubGFzdF9tb2RpZmllZDtcbiAgICAgICAgICAgICAgICByZXF1ZXN0ID0gcmVxdWVzdHMuanNvblBhdGNoUGVybWlzc2lvbnNSZXF1ZXN0KHBhdGgsIHBlcm1pc3Npb25zLCBcInJlbW92ZVwiLCB7XG4gICAgICAgICAgICAgICAgICBsYXN0X21vZGlmaWVkOiBsYXN0X21vZGlmaWVkLFxuICAgICAgICAgICAgICAgICAgaGVhZGVyczogdGhpcy5fZ2V0SGVhZGVycyhvcHRpb25zKSxcbiAgICAgICAgICAgICAgICAgIHNhZmU6IHRoaXMuX2dldFNhZmUob3B0aW9ucylcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQxNS5hYnJ1cHQoXCJyZXR1cm5cIiwgdGhpcy5jbGllbnQuZXhlY3V0ZShyZXF1ZXN0LCB7XG4gICAgICAgICAgICAgICAgICByZXRyeTogdGhpcy5fZ2V0UmV0cnkob3B0aW9ucylcbiAgICAgICAgICAgICAgICB9KSk7XG5cbiAgICAgICAgICAgICAgY2FzZSA3OlxuICAgICAgICAgICAgICBjYXNlIFwiZW5kXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0MTUuc3RvcCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSwgX2NhbGxlZTE1LCB0aGlzKTtcbiAgICAgIH0pKTtcblxuICAgICAgcmV0dXJuIGZ1bmN0aW9uIHJlbW92ZVBlcm1pc3Npb25zKF94MTApIHtcbiAgICAgICAgcmV0dXJuIF9yZW1vdmVQZXJtaXNzaW9ucy5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgfTtcbiAgICB9KClcbiAgICAvKipcbiAgICAgKiBQZXJmb3JtcyBiYXRjaCBvcGVyYXRpb25zIGF0IHRoZSBjdXJyZW50IGJ1Y2tldCBsZXZlbC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSAge0Z1bmN0aW9ufSBmbiAgICAgICAgICAgICAgICAgICBUaGUgYmF0Y2ggb3BlcmF0aW9uIGZ1bmN0aW9uLlxuICAgICAqIEBwYXJhbSAge09iamVjdH0gICBbb3B0aW9ucz17fV0gICAgICAgICBUaGUgb3B0aW9ucyBvYmplY3QuXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSAgIFtvcHRpb25zLmhlYWRlcnNdICAgIFRoZSBoZWFkZXJzIG9iamVjdCBvcHRpb24uXG4gICAgICogQHBhcmFtICB7Qm9vbGVhbn0gIFtvcHRpb25zLnNhZmVdICAgICAgIFRoZSBzYWZlIG9wdGlvbi5cbiAgICAgKiBAcGFyYW0gIHtOdW1iZXJ9ICAgW29wdGlvbnMucmV0cnk9MF0gICAgVGhlIHJldHJ5IG9wdGlvbi5cbiAgICAgKiBAcGFyYW0gIHtCb29sZWFufSAgW29wdGlvbnMuYWdncmVnYXRlXSAgUHJvZHVjZXMgYSBncm91cGVkIHJlc3VsdCBvYmplY3QuXG4gICAgICogQHJldHVybiB7UHJvbWlzZTxPYmplY3QsIEVycm9yPn1cbiAgICAgKi9cblxuICB9LCB7XG4gICAga2V5OiBcImJhdGNoXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciBfYmF0Y2ggPSAoMCwgX2FzeW5jVG9HZW5lcmF0b3IyLmRlZmF1bHQpKFxuICAgICAgLyojX19QVVJFX18qL1xuICAgICAgX3JlZ2VuZXJhdG9yLmRlZmF1bHQubWFyayhmdW5jdGlvbiBfY2FsbGVlMTYoZm4pIHtcbiAgICAgICAgdmFyIG9wdGlvbnMsXG4gICAgICAgICAgICBfYXJnczE2ID0gYXJndW1lbnRzO1xuICAgICAgICByZXR1cm4gX3JlZ2VuZXJhdG9yLmRlZmF1bHQud3JhcChmdW5jdGlvbiBfY2FsbGVlMTYkKF9jb250ZXh0MTYpIHtcbiAgICAgICAgICB3aGlsZSAoMSkge1xuICAgICAgICAgICAgc3dpdGNoIChfY29udGV4dDE2LnByZXYgPSBfY29udGV4dDE2Lm5leHQpIHtcbiAgICAgICAgICAgICAgY2FzZSAwOlxuICAgICAgICAgICAgICAgIG9wdGlvbnMgPSBfYXJnczE2Lmxlbmd0aCA+IDEgJiYgX2FyZ3MxNlsxXSAhPT0gdW5kZWZpbmVkID8gX2FyZ3MxNlsxXSA6IHt9O1xuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDE2LmFicnVwdChcInJldHVyblwiLCB0aGlzLmNsaWVudC5iYXRjaChmbiwge1xuICAgICAgICAgICAgICAgICAgYnVja2V0OiB0aGlzLm5hbWUsXG4gICAgICAgICAgICAgICAgICBoZWFkZXJzOiB0aGlzLl9nZXRIZWFkZXJzKG9wdGlvbnMpLFxuICAgICAgICAgICAgICAgICAgcmV0cnk6IHRoaXMuX2dldFJldHJ5KG9wdGlvbnMpLFxuICAgICAgICAgICAgICAgICAgc2FmZTogdGhpcy5fZ2V0U2FmZShvcHRpb25zKSxcbiAgICAgICAgICAgICAgICAgIGFnZ3JlZ2F0ZTogISFvcHRpb25zLmFnZ3JlZ2F0ZVxuICAgICAgICAgICAgICAgIH0pKTtcblxuICAgICAgICAgICAgICBjYXNlIDI6XG4gICAgICAgICAgICAgIGNhc2UgXCJlbmRcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQxNi5zdG9wKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9LCBfY2FsbGVlMTYsIHRoaXMpO1xuICAgICAgfSkpO1xuXG4gICAgICByZXR1cm4gZnVuY3Rpb24gYmF0Y2goX3gxMSkge1xuICAgICAgICByZXR1cm4gX2JhdGNoLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICB9O1xuICAgIH0oKVxuICB9XSk7XG4gIHJldHVybiBCdWNrZXQ7XG59KCksICgoMCwgX2FwcGx5RGVjb3JhdGVkRGVzY3JpcHRvcjIuZGVmYXVsdCkoX2NsYXNzLnByb3RvdHlwZSwgXCJsaXN0SGlzdG9yeVwiLCBbX2RlY10sIE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IoX2NsYXNzLnByb3RvdHlwZSwgXCJsaXN0SGlzdG9yeVwiKSwgX2NsYXNzLnByb3RvdHlwZSkpLCBfY2xhc3MpKTtcbmV4cG9ydHMuZGVmYXVsdCA9IEJ1Y2tldDsiLCJcInVzZSBzdHJpY3RcIjtcblxudmFyIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQgPSByZXF1aXJlKFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9pbnRlcm9wUmVxdWlyZURlZmF1bHRcIik7XG5cbnZhciBfaW50ZXJvcFJlcXVpcmVXaWxkY2FyZCA9IHJlcXVpcmUoXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2ludGVyb3BSZXF1aXJlV2lsZGNhcmRcIik7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwge1xuICB2YWx1ZTogdHJ1ZVxufSk7XG5leHBvcnRzLmRlZmF1bHQgPSB2b2lkIDA7XG5cbnZhciBfc2xpY2VkVG9BcnJheTIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KHJlcXVpcmUoXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL3NsaWNlZFRvQXJyYXlcIikpO1xuXG52YXIgX3JlZ2VuZXJhdG9yID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChyZXF1aXJlKFwiQGJhYmVsL3J1bnRpbWUvcmVnZW5lcmF0b3JcIikpO1xuXG52YXIgX2FzeW5jVG9HZW5lcmF0b3IyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChyZXF1aXJlKFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9hc3luY1RvR2VuZXJhdG9yXCIpKTtcblxudmFyIF9vYmplY3RTcHJlYWQyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChyZXF1aXJlKFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9vYmplY3RTcHJlYWRcIikpO1xuXG52YXIgX2NsYXNzQ2FsbENoZWNrMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQocmVxdWlyZShcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvY2xhc3NDYWxsQ2hlY2tcIikpO1xuXG52YXIgX2NyZWF0ZUNsYXNzMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQocmVxdWlyZShcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvY3JlYXRlQ2xhc3NcIikpO1xuXG52YXIgX2FwcGx5RGVjb3JhdGVkRGVzY3JpcHRvcjIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KHJlcXVpcmUoXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2FwcGx5RGVjb3JhdGVkRGVzY3JpcHRvclwiKSk7XG5cbnZhciBfdXVpZCA9IHJlcXVpcmUoXCJ1dWlkXCIpO1xuXG52YXIgX3V0aWxzID0gcmVxdWlyZShcIi4vdXRpbHNcIik7XG5cbnZhciByZXF1ZXN0cyA9IF9pbnRlcm9wUmVxdWlyZVdpbGRjYXJkKHJlcXVpcmUoXCIuL3JlcXVlc3RzXCIpKTtcblxudmFyIF9lbmRwb2ludCA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQocmVxdWlyZShcIi4vZW5kcG9pbnRcIikpO1xuXG52YXIgX2RlYywgX2RlYzIsIF9kZWMzLCBfY2xhc3M7XG5cbi8qKlxuICogQWJzdHJhY3QgcmVwcmVzZW50YXRpb24gb2YgYSBzZWxlY3RlZCBjb2xsZWN0aW9uLlxuICpcbiAqL1xudmFyIENvbGxlY3Rpb24gPSAoX2RlYyA9ICgwLCBfdXRpbHMuY2FwYWJsZSkoW1wiYXR0YWNobWVudHNcIl0pLCBfZGVjMiA9ICgwLCBfdXRpbHMuY2FwYWJsZSkoW1wiYXR0YWNobWVudHNcIl0pLCBfZGVjMyA9ICgwLCBfdXRpbHMuY2FwYWJsZSkoW1wiaGlzdG9yeVwiXSksIChfY2xhc3MgPVxuLyojX19QVVJFX18qL1xuZnVuY3Rpb24gKCkge1xuICAvKipcbiAgICogQ29uc3RydWN0b3IuXG4gICAqXG4gICAqIEBwYXJhbSAge0tpbnRvQ2xpZW50fSAgY2xpZW50ICAgICAgICAgICAgVGhlIGNsaWVudCBpbnN0YW5jZS5cbiAgICogQHBhcmFtICB7QnVja2V0fSAgICAgICBidWNrZXQgICAgICAgICAgICBUaGUgYnVja2V0IGluc3RhbmNlLlxuICAgKiBAcGFyYW0gIHtTdHJpbmd9ICAgICAgIG5hbWUgICAgICAgICAgICAgIFRoZSBjb2xsZWN0aW9uIG5hbWUuXG4gICAqIEBwYXJhbSAge09iamVjdH0gICAgICAgW29wdGlvbnM9e31dICAgICAgVGhlIG9wdGlvbnMgb2JqZWN0LlxuICAgKiBAcGFyYW0gIHtPYmplY3R9ICAgICAgIFtvcHRpb25zLmhlYWRlcnNdIFRoZSBoZWFkZXJzIG9iamVjdCBvcHRpb24uXG4gICAqIEBwYXJhbSAge0Jvb2xlYW59ICAgICAgW29wdGlvbnMuc2FmZV0gICAgVGhlIHNhZmUgb3B0aW9uLlxuICAgKiBAcGFyYW0gIHtOdW1iZXJ9ICAgICAgIFtvcHRpb25zLnJldHJ5XSAgIFRoZSByZXRyeSBvcHRpb24uXG4gICAqIEBwYXJhbSAge0Jvb2xlYW59ICAgICAgW29wdGlvbnMuYmF0Y2hdICAgKFByaXZhdGUpIFdoZXRoZXIgdGhpc1xuICAgKiAgICAgQ29sbGVjdGlvbiBpcyBvcGVyYXRpbmcgYXMgcGFydCBvZiBhIGJhdGNoLlxuICAgKi9cbiAgZnVuY3Rpb24gQ29sbGVjdGlvbihjbGllbnQsIGJ1Y2tldCwgbmFtZSkge1xuICAgIHZhciBvcHRpb25zID0gYXJndW1lbnRzLmxlbmd0aCA+IDMgJiYgYXJndW1lbnRzWzNdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbM10gOiB7fTtcbiAgICAoMCwgX2NsYXNzQ2FsbENoZWNrMi5kZWZhdWx0KSh0aGlzLCBDb2xsZWN0aW9uKTtcblxuICAgIC8qKlxuICAgICAqIEBpZ25vcmVcbiAgICAgKi9cbiAgICB0aGlzLmNsaWVudCA9IGNsaWVudDtcbiAgICAvKipcbiAgICAgKiBAaWdub3JlXG4gICAgICovXG5cbiAgICB0aGlzLmJ1Y2tldCA9IGJ1Y2tldDtcbiAgICAvKipcbiAgICAgKiBUaGUgY29sbGVjdGlvbiBuYW1lLlxuICAgICAqIEB0eXBlIHtTdHJpbmd9XG4gICAgICovXG5cbiAgICB0aGlzLm5hbWUgPSBuYW1lO1xuICAgIC8qKlxuICAgICAqIEBpZ25vcmVcbiAgICAgKi9cblxuICAgIHRoaXMuX2lzQmF0Y2ggPSAhIW9wdGlvbnMuYmF0Y2g7XG4gICAgLyoqXG4gICAgICogQGlnbm9yZVxuICAgICAqL1xuXG4gICAgdGhpcy5fcmV0cnkgPSBvcHRpb25zLnJldHJ5IHx8IDA7XG4gICAgdGhpcy5fc2FmZSA9ICEhb3B0aW9ucy5zYWZlOyAvLyBGSVhNRTogVGhpcyBpcyBraW5kIG9mIHVnbHk7IHNob3VsZG4ndCB0aGUgYnVja2V0IGJlIHJlc3BvbnNpYmxlXG4gICAgLy8gZm9yIGRvaW5nIHRoZSBtZXJnZT9cblxuICAgIHRoaXMuX2hlYWRlcnMgPSAoMCwgX29iamVjdFNwcmVhZDIuZGVmYXVsdCkoe30sIHRoaXMuYnVja2V0Ll9oZWFkZXJzLCBvcHRpb25zLmhlYWRlcnMpO1xuICB9XG4gIC8qKlxuICAgKiBHZXQgdGhlIHZhbHVlIG9mIFwiaGVhZGVyc1wiIGZvciBhIGdpdmVuIHJlcXVlc3QsIG1lcmdpbmcgdGhlXG4gICAqIHBlci1yZXF1ZXN0IGhlYWRlcnMgd2l0aCBvdXIgb3duIFwiZGVmYXVsdFwiIGhlYWRlcnMuXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuXG5cbiAgKDAsIF9jcmVhdGVDbGFzczIuZGVmYXVsdCkoQ29sbGVjdGlvbiwgW3tcbiAgICBrZXk6IFwiX2dldEhlYWRlcnNcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gX2dldEhlYWRlcnMob3B0aW9ucykge1xuICAgICAgcmV0dXJuICgwLCBfb2JqZWN0U3ByZWFkMi5kZWZhdWx0KSh7fSwgdGhpcy5faGVhZGVycywgb3B0aW9ucy5oZWFkZXJzKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IHRoZSB2YWx1ZSBvZiBcInNhZmVcIiBmb3IgYSBnaXZlbiByZXF1ZXN0LCB1c2luZyB0aGVcbiAgICAgKiBwZXItcmVxdWVzdCBvcHRpb24gaWYgcHJlc2VudCBvciBmYWxsaW5nIGJhY2sgdG8gb3VyIGRlZmF1bHRcbiAgICAgKiBvdGhlcndpc2UuXG4gICAgICpcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zIFRoZSBvcHRpb25zIGZvciBhIHJlcXVlc3QuXG4gICAgICogQHJldHVybnMge0Jvb2xlYW59XG4gICAgICovXG5cbiAgfSwge1xuICAgIGtleTogXCJfZ2V0U2FmZVwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBfZ2V0U2FmZShvcHRpb25zKSB7XG4gICAgICByZXR1cm4gKDAsIF9vYmplY3RTcHJlYWQyLmRlZmF1bHQpKHtcbiAgICAgICAgc2FmZTogdGhpcy5fc2FmZVxuICAgICAgfSwgb3B0aW9ucykuc2FmZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQXMgX2dldFNhZmUsIGJ1dCBmb3IgXCJyZXRyeVwiLlxuICAgICAqXG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cblxuICB9LCB7XG4gICAga2V5OiBcIl9nZXRSZXRyeVwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiBfZ2V0UmV0cnkob3B0aW9ucykge1xuICAgICAgcmV0dXJuICgwLCBfb2JqZWN0U3ByZWFkMi5kZWZhdWx0KSh7XG4gICAgICAgIHJldHJ5OiB0aGlzLl9yZXRyeVxuICAgICAgfSwgb3B0aW9ucykucmV0cnk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFJldHJpZXZlcyB0aGUgdG90YWwgbnVtYmVyIG9mIHJlY29yZHMgaW4gdGhpcyBjb2xsZWN0aW9uLlxuICAgICAqXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSBbb3B0aW9ucz17fV0gICAgICBUaGUgb3B0aW9ucyBvYmplY3QuXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSBbb3B0aW9ucy5oZWFkZXJzXSBUaGUgaGVhZGVycyBvYmplY3Qgb3B0aW9uLlxuICAgICAqIEBwYXJhbSAge051bWJlcn0gW29wdGlvbnMucmV0cnk9MF0gTnVtYmVyIG9mIHJldHJpZXMgdG8gbWFrZVxuICAgICAqICAgICB3aGVuIGZhY2VkIHdpdGggdHJhbnNpZW50IGVycm9ycy5cbiAgICAgKiBAcmV0dXJuIHtQcm9taXNlPE51bWJlciwgRXJyb3I+fVxuICAgICAqL1xuXG4gIH0sIHtcbiAgICBrZXk6IFwiZ2V0VG90YWxSZWNvcmRzXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciBfZ2V0VG90YWxSZWNvcmRzID0gKDAsIF9hc3luY1RvR2VuZXJhdG9yMi5kZWZhdWx0KShcbiAgICAgIC8qI19fUFVSRV9fKi9cbiAgICAgIF9yZWdlbmVyYXRvci5kZWZhdWx0Lm1hcmsoZnVuY3Rpb24gX2NhbGxlZSgpIHtcbiAgICAgICAgdmFyIG9wdGlvbnMsXG4gICAgICAgICAgICBwYXRoLFxuICAgICAgICAgICAgcmVxdWVzdCxcbiAgICAgICAgICAgIF9yZWYsXG4gICAgICAgICAgICBoZWFkZXJzLFxuICAgICAgICAgICAgX2FyZ3MgPSBhcmd1bWVudHM7XG5cbiAgICAgICAgcmV0dXJuIF9yZWdlbmVyYXRvci5kZWZhdWx0LndyYXAoZnVuY3Rpb24gX2NhbGxlZSQoX2NvbnRleHQpIHtcbiAgICAgICAgICB3aGlsZSAoMSkge1xuICAgICAgICAgICAgc3dpdGNoIChfY29udGV4dC5wcmV2ID0gX2NvbnRleHQubmV4dCkge1xuICAgICAgICAgICAgICBjYXNlIDA6XG4gICAgICAgICAgICAgICAgb3B0aW9ucyA9IF9hcmdzLmxlbmd0aCA+IDAgJiYgX2FyZ3NbMF0gIT09IHVuZGVmaW5lZCA/IF9hcmdzWzBdIDoge307XG4gICAgICAgICAgICAgICAgcGF0aCA9ICgwLCBfZW5kcG9pbnQuZGVmYXVsdCkoXCJyZWNvcmRcIiwgdGhpcy5idWNrZXQubmFtZSwgdGhpcy5uYW1lKTtcbiAgICAgICAgICAgICAgICByZXF1ZXN0ID0ge1xuICAgICAgICAgICAgICAgICAgaGVhZGVyczogdGhpcy5fZ2V0SGVhZGVycyhvcHRpb25zKSxcbiAgICAgICAgICAgICAgICAgIHBhdGg6IHBhdGgsXG4gICAgICAgICAgICAgICAgICBtZXRob2Q6IFwiSEVBRFwiXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICBfY29udGV4dC5uZXh0ID0gNTtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5jbGllbnQuZXhlY3V0ZShyZXF1ZXN0LCB7XG4gICAgICAgICAgICAgICAgICByYXc6IHRydWUsXG4gICAgICAgICAgICAgICAgICByZXRyeTogdGhpcy5fZ2V0UmV0cnkob3B0aW9ucylcbiAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICBjYXNlIDU6XG4gICAgICAgICAgICAgICAgX3JlZiA9IF9jb250ZXh0LnNlbnQ7XG4gICAgICAgICAgICAgICAgaGVhZGVycyA9IF9yZWYuaGVhZGVycztcbiAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQuYWJydXB0KFwicmV0dXJuXCIsIHBhcnNlSW50KGhlYWRlcnMuZ2V0KFwiVG90YWwtUmVjb3Jkc1wiKSwgMTApKTtcblxuICAgICAgICAgICAgICBjYXNlIDg6XG4gICAgICAgICAgICAgIGNhc2UgXCJlbmRcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQuc3RvcCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSwgX2NhbGxlZSwgdGhpcyk7XG4gICAgICB9KSk7XG5cbiAgICAgIHJldHVybiBmdW5jdGlvbiBnZXRUb3RhbFJlY29yZHMoKSB7XG4gICAgICAgIHJldHVybiBfZ2V0VG90YWxSZWNvcmRzLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICB9O1xuICAgIH0oKVxuICAgIC8qKlxuICAgICAqIFJldHJpZXZlcyBjb2xsZWN0aW9uIGRhdGEuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9IFtvcHRpb25zPXt9XSAgICAgIFRoZSBvcHRpb25zIG9iamVjdC5cbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9IFtvcHRpb25zLmhlYWRlcnNdIFRoZSBoZWFkZXJzIG9iamVjdCBvcHRpb24uXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSBbb3B0aW9ucy5xdWVyeV0gICBRdWVyeSBwYXJhbWV0ZXJzIHRvIHBhc3MgaW5cbiAgICAgKiAgICAgdGhlIHJlcXVlc3QuIFRoaXMgbWlnaHQgYmUgdXNlZnVsIGZvciBmZWF0dXJlcyB0aGF0IGFyZW4ndFxuICAgICAqICAgICB5ZXQgc3VwcG9ydGVkIGJ5IHRoaXMgbGlicmFyeS5cbiAgICAgKiBAcGFyYW0gIHtOdW1iZXJ9IFtvcHRpb25zLnJldHJ5PTBdIE51bWJlciBvZiByZXRyaWVzIHRvIG1ha2VcbiAgICAgKiAgICAgd2hlbiBmYWNlZCB3aXRoIHRyYW5zaWVudCBlcnJvcnMuXG4gICAgICogQHJldHVybiB7UHJvbWlzZTxPYmplY3QsIEVycm9yPn1cbiAgICAgKi9cblxuICB9LCB7XG4gICAga2V5OiBcImdldERhdGFcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gKCkge1xuICAgICAgdmFyIF9nZXREYXRhID0gKDAsIF9hc3luY1RvR2VuZXJhdG9yMi5kZWZhdWx0KShcbiAgICAgIC8qI19fUFVSRV9fKi9cbiAgICAgIF9yZWdlbmVyYXRvci5kZWZhdWx0Lm1hcmsoZnVuY3Rpb24gX2NhbGxlZTIoKSB7XG4gICAgICAgIHZhciBvcHRpb25zLFxuICAgICAgICAgICAgcGF0aCxcbiAgICAgICAgICAgIHF1ZXJ5c3RyaW5nLFxuICAgICAgICAgICAgcmVxdWVzdCxcbiAgICAgICAgICAgIF9yZWYyLFxuICAgICAgICAgICAgZGF0YSxcbiAgICAgICAgICAgIF9hcmdzMiA9IGFyZ3VtZW50cztcblxuICAgICAgICByZXR1cm4gX3JlZ2VuZXJhdG9yLmRlZmF1bHQud3JhcChmdW5jdGlvbiBfY2FsbGVlMiQoX2NvbnRleHQyKSB7XG4gICAgICAgICAgd2hpbGUgKDEpIHtcbiAgICAgICAgICAgIHN3aXRjaCAoX2NvbnRleHQyLnByZXYgPSBfY29udGV4dDIubmV4dCkge1xuICAgICAgICAgICAgICBjYXNlIDA6XG4gICAgICAgICAgICAgICAgb3B0aW9ucyA9IF9hcmdzMi5sZW5ndGggPiAwICYmIF9hcmdzMlswXSAhPT0gdW5kZWZpbmVkID8gX2FyZ3MyWzBdIDoge307XG4gICAgICAgICAgICAgICAgcGF0aCA9ICgwLCBfZW5kcG9pbnQuZGVmYXVsdCkoXCJjb2xsZWN0aW9uXCIsIHRoaXMuYnVja2V0Lm5hbWUsIHRoaXMubmFtZSk7XG5cbiAgICAgICAgICAgICAgICBpZiAob3B0aW9ucy5xdWVyeSkge1xuICAgICAgICAgICAgICAgICAgcXVlcnlzdHJpbmcgPSAoMCwgX3V0aWxzLnFzaWZ5KShvcHRpb25zLnF1ZXJ5KTtcbiAgICAgICAgICAgICAgICAgIHBhdGggPSBwYXRoICsgXCI/XCIgKyBxdWVyeXN0cmluZztcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICByZXF1ZXN0ID0ge1xuICAgICAgICAgICAgICAgICAgaGVhZGVyczogdGhpcy5fZ2V0SGVhZGVycyhvcHRpb25zKSxcbiAgICAgICAgICAgICAgICAgIHBhdGg6IHBhdGhcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIF9jb250ZXh0Mi5uZXh0ID0gNjtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5jbGllbnQuZXhlY3V0ZShyZXF1ZXN0LCB7XG4gICAgICAgICAgICAgICAgICByZXRyeTogdGhpcy5fZ2V0UmV0cnkob3B0aW9ucylcbiAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICBjYXNlIDY6XG4gICAgICAgICAgICAgICAgX3JlZjIgPSBfY29udGV4dDIuc2VudDtcbiAgICAgICAgICAgICAgICBkYXRhID0gX3JlZjIuZGF0YTtcbiAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQyLmFicnVwdChcInJldHVyblwiLCBkYXRhKTtcblxuICAgICAgICAgICAgICBjYXNlIDk6XG4gICAgICAgICAgICAgIGNhc2UgXCJlbmRcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQyLnN0b3AoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0sIF9jYWxsZWUyLCB0aGlzKTtcbiAgICAgIH0pKTtcblxuICAgICAgcmV0dXJuIGZ1bmN0aW9uIGdldERhdGEoKSB7XG4gICAgICAgIHJldHVybiBfZ2V0RGF0YS5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgfTtcbiAgICB9KClcbiAgICAvKipcbiAgICAgKiBTZXQgY29sbGVjdGlvbiBkYXRhLlxuICAgICAqIEBwYXJhbSAge09iamVjdH0gICBkYXRhICAgICAgICAgICAgICAgICAgICBUaGUgY29sbGVjdGlvbiBkYXRhIG9iamVjdC5cbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9ICAgW29wdGlvbnM9e31dICAgICAgICAgICAgVGhlIG9wdGlvbnMgb2JqZWN0LlxuICAgICAqIEBwYXJhbSAge09iamVjdH0gICBbb3B0aW9ucy5oZWFkZXJzXSAgICAgICBUaGUgaGVhZGVycyBvYmplY3Qgb3B0aW9uLlxuICAgICAqIEBwYXJhbSAge051bWJlcn0gICBbb3B0aW9ucy5yZXRyeT0wXSAgICAgICBOdW1iZXIgb2YgcmV0cmllcyB0byBtYWtlXG4gICAgICogICAgIHdoZW4gZmFjZWQgd2l0aCB0cmFuc2llbnQgZXJyb3JzLlxuICAgICAqIEBwYXJhbSAge0Jvb2xlYW59ICBbb3B0aW9ucy5zYWZlXSAgICAgICAgICBUaGUgc2FmZSBvcHRpb24uXG4gICAgICogQHBhcmFtICB7Qm9vbGVhbn0gIFtvcHRpb25zLnBhdGNoXSAgICAgICAgIFRoZSBwYXRjaCBvcHRpb24uXG4gICAgICogQHBhcmFtICB7TnVtYmVyfSAgIFtvcHRpb25zLmxhc3RfbW9kaWZpZWRdIFRoZSBsYXN0X21vZGlmaWVkIG9wdGlvbi5cbiAgICAgKiBAcmV0dXJuIHtQcm9taXNlPE9iamVjdCwgRXJyb3I+fVxuICAgICAqL1xuXG4gIH0sIHtcbiAgICBrZXk6IFwic2V0RGF0YVwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgX3NldERhdGEgPSAoMCwgX2FzeW5jVG9HZW5lcmF0b3IyLmRlZmF1bHQpKFxuICAgICAgLyojX19QVVJFX18qL1xuICAgICAgX3JlZ2VuZXJhdG9yLmRlZmF1bHQubWFyayhmdW5jdGlvbiBfY2FsbGVlMyhkYXRhKSB7XG4gICAgICAgIHZhciBvcHRpb25zLFxuICAgICAgICAgICAgcGF0Y2gsXG4gICAgICAgICAgICBwZXJtaXNzaW9ucyxcbiAgICAgICAgICAgIF9kYXRhJG9wdGlvbnMsXG4gICAgICAgICAgICBsYXN0X21vZGlmaWVkLFxuICAgICAgICAgICAgcGF0aCxcbiAgICAgICAgICAgIHJlcXVlc3QsXG4gICAgICAgICAgICBfYXJnczMgPSBhcmd1bWVudHM7XG5cbiAgICAgICAgcmV0dXJuIF9yZWdlbmVyYXRvci5kZWZhdWx0LndyYXAoZnVuY3Rpb24gX2NhbGxlZTMkKF9jb250ZXh0Mykge1xuICAgICAgICAgIHdoaWxlICgxKSB7XG4gICAgICAgICAgICBzd2l0Y2ggKF9jb250ZXh0My5wcmV2ID0gX2NvbnRleHQzLm5leHQpIHtcbiAgICAgICAgICAgICAgY2FzZSAwOlxuICAgICAgICAgICAgICAgIG9wdGlvbnMgPSBfYXJnczMubGVuZ3RoID4gMSAmJiBfYXJnczNbMV0gIT09IHVuZGVmaW5lZCA/IF9hcmdzM1sxXSA6IHt9O1xuXG4gICAgICAgICAgICAgICAgaWYgKCgwLCBfdXRpbHMuaXNPYmplY3QpKGRhdGEpKSB7XG4gICAgICAgICAgICAgICAgICBfY29udGV4dDMubmV4dCA9IDM7XG4gICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJBIGNvbGxlY3Rpb24gb2JqZWN0IGlzIHJlcXVpcmVkLlwiKTtcblxuICAgICAgICAgICAgICBjYXNlIDM6XG4gICAgICAgICAgICAgICAgcGF0Y2ggPSBvcHRpb25zLnBhdGNoLCBwZXJtaXNzaW9ucyA9IG9wdGlvbnMucGVybWlzc2lvbnM7XG4gICAgICAgICAgICAgICAgX2RhdGEkb3B0aW9ucyA9ICgwLCBfb2JqZWN0U3ByZWFkMi5kZWZhdWx0KSh7fSwgZGF0YSwgb3B0aW9ucyksIGxhc3RfbW9kaWZpZWQgPSBfZGF0YSRvcHRpb25zLmxhc3RfbW9kaWZpZWQ7XG4gICAgICAgICAgICAgICAgcGF0aCA9ICgwLCBfZW5kcG9pbnQuZGVmYXVsdCkoXCJjb2xsZWN0aW9uXCIsIHRoaXMuYnVja2V0Lm5hbWUsIHRoaXMubmFtZSk7XG4gICAgICAgICAgICAgICAgcmVxdWVzdCA9IHJlcXVlc3RzLnVwZGF0ZVJlcXVlc3QocGF0aCwge1xuICAgICAgICAgICAgICAgICAgZGF0YTogZGF0YSxcbiAgICAgICAgICAgICAgICAgIHBlcm1pc3Npb25zOiBwZXJtaXNzaW9uc1xuICAgICAgICAgICAgICAgIH0sIHtcbiAgICAgICAgICAgICAgICAgIGxhc3RfbW9kaWZpZWQ6IGxhc3RfbW9kaWZpZWQsXG4gICAgICAgICAgICAgICAgICBwYXRjaDogcGF0Y2gsXG4gICAgICAgICAgICAgICAgICBoZWFkZXJzOiB0aGlzLl9nZXRIZWFkZXJzKG9wdGlvbnMpLFxuICAgICAgICAgICAgICAgICAgc2FmZTogdGhpcy5fZ2V0U2FmZShvcHRpb25zKVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDMuYWJydXB0KFwicmV0dXJuXCIsIHRoaXMuY2xpZW50LmV4ZWN1dGUocmVxdWVzdCwge1xuICAgICAgICAgICAgICAgICAgcmV0cnk6IHRoaXMuX2dldFJldHJ5KG9wdGlvbnMpXG4gICAgICAgICAgICAgICAgfSkpO1xuXG4gICAgICAgICAgICAgIGNhc2UgODpcbiAgICAgICAgICAgICAgY2FzZSBcImVuZFwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDMuc3RvcCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSwgX2NhbGxlZTMsIHRoaXMpO1xuICAgICAgfSkpO1xuXG4gICAgICByZXR1cm4gZnVuY3Rpb24gc2V0RGF0YShfeCkge1xuICAgICAgICByZXR1cm4gX3NldERhdGEuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgIH07XG4gICAgfSgpXG4gICAgLyoqXG4gICAgICogUmV0cmlldmVzIHRoZSBsaXN0IG9mIHBlcm1pc3Npb25zIGZvciB0aGlzIGNvbGxlY3Rpb24uXG4gICAgICpcbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9IFtvcHRpb25zPXt9XSAgICAgIFRoZSBvcHRpb25zIG9iamVjdC5cbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9IFtvcHRpb25zLmhlYWRlcnNdIFRoZSBoZWFkZXJzIG9iamVjdCBvcHRpb24uXG4gICAgICogQHBhcmFtICB7TnVtYmVyfSBbb3B0aW9ucy5yZXRyeT0wXSBOdW1iZXIgb2YgcmV0cmllcyB0byBtYWtlXG4gICAgICogICAgIHdoZW4gZmFjZWQgd2l0aCB0cmFuc2llbnQgZXJyb3JzLlxuICAgICAqIEByZXR1cm4ge1Byb21pc2U8T2JqZWN0LCBFcnJvcj59XG4gICAgICovXG5cbiAgfSwge1xuICAgIGtleTogXCJnZXRQZXJtaXNzaW9uc1wiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgX2dldFBlcm1pc3Npb25zID0gKDAsIF9hc3luY1RvR2VuZXJhdG9yMi5kZWZhdWx0KShcbiAgICAgIC8qI19fUFVSRV9fKi9cbiAgICAgIF9yZWdlbmVyYXRvci5kZWZhdWx0Lm1hcmsoZnVuY3Rpb24gX2NhbGxlZTQoKSB7XG4gICAgICAgIHZhciBvcHRpb25zLFxuICAgICAgICAgICAgcGF0aCxcbiAgICAgICAgICAgIHJlcXVlc3QsXG4gICAgICAgICAgICBfcmVmMyxcbiAgICAgICAgICAgIHBlcm1pc3Npb25zLFxuICAgICAgICAgICAgX2FyZ3M0ID0gYXJndW1lbnRzO1xuXG4gICAgICAgIHJldHVybiBfcmVnZW5lcmF0b3IuZGVmYXVsdC53cmFwKGZ1bmN0aW9uIF9jYWxsZWU0JChfY29udGV4dDQpIHtcbiAgICAgICAgICB3aGlsZSAoMSkge1xuICAgICAgICAgICAgc3dpdGNoIChfY29udGV4dDQucHJldiA9IF9jb250ZXh0NC5uZXh0KSB7XG4gICAgICAgICAgICAgIGNhc2UgMDpcbiAgICAgICAgICAgICAgICBvcHRpb25zID0gX2FyZ3M0Lmxlbmd0aCA+IDAgJiYgX2FyZ3M0WzBdICE9PSB1bmRlZmluZWQgPyBfYXJnczRbMF0gOiB7fTtcbiAgICAgICAgICAgICAgICBwYXRoID0gKDAsIF9lbmRwb2ludC5kZWZhdWx0KShcImNvbGxlY3Rpb25cIiwgdGhpcy5idWNrZXQubmFtZSwgdGhpcy5uYW1lKTtcbiAgICAgICAgICAgICAgICByZXF1ZXN0ID0ge1xuICAgICAgICAgICAgICAgICAgaGVhZGVyczogdGhpcy5fZ2V0SGVhZGVycyhvcHRpb25zKSxcbiAgICAgICAgICAgICAgICAgIHBhdGg6IHBhdGhcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIF9jb250ZXh0NC5uZXh0ID0gNTtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5jbGllbnQuZXhlY3V0ZShyZXF1ZXN0LCB7XG4gICAgICAgICAgICAgICAgICByZXRyeTogdGhpcy5fZ2V0UmV0cnkob3B0aW9ucylcbiAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICBjYXNlIDU6XG4gICAgICAgICAgICAgICAgX3JlZjMgPSBfY29udGV4dDQuc2VudDtcbiAgICAgICAgICAgICAgICBwZXJtaXNzaW9ucyA9IF9yZWYzLnBlcm1pc3Npb25zO1xuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDQuYWJydXB0KFwicmV0dXJuXCIsIHBlcm1pc3Npb25zKTtcblxuICAgICAgICAgICAgICBjYXNlIDg6XG4gICAgICAgICAgICAgIGNhc2UgXCJlbmRcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQ0LnN0b3AoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0sIF9jYWxsZWU0LCB0aGlzKTtcbiAgICAgIH0pKTtcblxuICAgICAgcmV0dXJuIGZ1bmN0aW9uIGdldFBlcm1pc3Npb25zKCkge1xuICAgICAgICByZXR1cm4gX2dldFBlcm1pc3Npb25zLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICB9O1xuICAgIH0oKVxuICAgIC8qKlxuICAgICAqIFJlcGxhY2VzIGFsbCBleGlzdGluZyBjb2xsZWN0aW9uIHBlcm1pc3Npb25zIHdpdGggdGhlIG9uZXMgcHJvdmlkZWQuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9ICAgcGVybWlzc2lvbnMgICAgICAgICAgICAgVGhlIHBlcm1pc3Npb25zIG9iamVjdC5cbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9ICAgW29wdGlvbnM9e31dICAgICAgICAgICAgVGhlIG9wdGlvbnMgb2JqZWN0XG4gICAgICogQHBhcmFtICB7T2JqZWN0fSAgIFtvcHRpb25zLmhlYWRlcnNdICAgICAgIFRoZSBoZWFkZXJzIG9iamVjdCBvcHRpb24uXG4gICAgICogQHBhcmFtICB7TnVtYmVyfSAgIFtvcHRpb25zLnJldHJ5PTBdICAgICAgIE51bWJlciBvZiByZXRyaWVzIHRvIG1ha2VcbiAgICAgKiAgICAgd2hlbiBmYWNlZCB3aXRoIHRyYW5zaWVudCBlcnJvcnMuXG4gICAgICogQHBhcmFtICB7Qm9vbGVhbn0gIFtvcHRpb25zLnNhZmVdICAgICAgICAgIFRoZSBzYWZlIG9wdGlvbi5cbiAgICAgKiBAcGFyYW0gIHtOdW1iZXJ9ICAgW29wdGlvbnMubGFzdF9tb2RpZmllZF0gVGhlIGxhc3RfbW9kaWZpZWQgb3B0aW9uLlxuICAgICAqIEByZXR1cm4ge1Byb21pc2U8T2JqZWN0LCBFcnJvcj59XG4gICAgICovXG5cbiAgfSwge1xuICAgIGtleTogXCJzZXRQZXJtaXNzaW9uc1wiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgX3NldFBlcm1pc3Npb25zID0gKDAsIF9hc3luY1RvR2VuZXJhdG9yMi5kZWZhdWx0KShcbiAgICAgIC8qI19fUFVSRV9fKi9cbiAgICAgIF9yZWdlbmVyYXRvci5kZWZhdWx0Lm1hcmsoZnVuY3Rpb24gX2NhbGxlZTUocGVybWlzc2lvbnMpIHtcbiAgICAgICAgdmFyIG9wdGlvbnMsXG4gICAgICAgICAgICBwYXRoLFxuICAgICAgICAgICAgZGF0YSxcbiAgICAgICAgICAgIHJlcXVlc3QsXG4gICAgICAgICAgICBfYXJnczUgPSBhcmd1bWVudHM7XG4gICAgICAgIHJldHVybiBfcmVnZW5lcmF0b3IuZGVmYXVsdC53cmFwKGZ1bmN0aW9uIF9jYWxsZWU1JChfY29udGV4dDUpIHtcbiAgICAgICAgICB3aGlsZSAoMSkge1xuICAgICAgICAgICAgc3dpdGNoIChfY29udGV4dDUucHJldiA9IF9jb250ZXh0NS5uZXh0KSB7XG4gICAgICAgICAgICAgIGNhc2UgMDpcbiAgICAgICAgICAgICAgICBvcHRpb25zID0gX2FyZ3M1Lmxlbmd0aCA+IDEgJiYgX2FyZ3M1WzFdICE9PSB1bmRlZmluZWQgPyBfYXJnczVbMV0gOiB7fTtcblxuICAgICAgICAgICAgICAgIGlmICgoMCwgX3V0aWxzLmlzT2JqZWN0KShwZXJtaXNzaW9ucykpIHtcbiAgICAgICAgICAgICAgICAgIF9jb250ZXh0NS5uZXh0ID0gMztcbiAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIkEgcGVybWlzc2lvbnMgb2JqZWN0IGlzIHJlcXVpcmVkLlwiKTtcblxuICAgICAgICAgICAgICBjYXNlIDM6XG4gICAgICAgICAgICAgICAgcGF0aCA9ICgwLCBfZW5kcG9pbnQuZGVmYXVsdCkoXCJjb2xsZWN0aW9uXCIsIHRoaXMuYnVja2V0Lm5hbWUsIHRoaXMubmFtZSk7XG4gICAgICAgICAgICAgICAgZGF0YSA9IHtcbiAgICAgICAgICAgICAgICAgIGxhc3RfbW9kaWZpZWQ6IG9wdGlvbnMubGFzdF9tb2RpZmllZFxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgcmVxdWVzdCA9IHJlcXVlc3RzLnVwZGF0ZVJlcXVlc3QocGF0aCwge1xuICAgICAgICAgICAgICAgICAgZGF0YTogZGF0YSxcbiAgICAgICAgICAgICAgICAgIHBlcm1pc3Npb25zOiBwZXJtaXNzaW9uc1xuICAgICAgICAgICAgICAgIH0sIHtcbiAgICAgICAgICAgICAgICAgIGhlYWRlcnM6IHRoaXMuX2dldEhlYWRlcnMob3B0aW9ucyksXG4gICAgICAgICAgICAgICAgICBzYWZlOiB0aGlzLl9nZXRTYWZlKG9wdGlvbnMpXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0NS5hYnJ1cHQoXCJyZXR1cm5cIiwgdGhpcy5jbGllbnQuZXhlY3V0ZShyZXF1ZXN0LCB7XG4gICAgICAgICAgICAgICAgICByZXRyeTogdGhpcy5fZ2V0UmV0cnkob3B0aW9ucylcbiAgICAgICAgICAgICAgICB9KSk7XG5cbiAgICAgICAgICAgICAgY2FzZSA3OlxuICAgICAgICAgICAgICBjYXNlIFwiZW5kXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0NS5zdG9wKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9LCBfY2FsbGVlNSwgdGhpcyk7XG4gICAgICB9KSk7XG5cbiAgICAgIHJldHVybiBmdW5jdGlvbiBzZXRQZXJtaXNzaW9ucyhfeDIpIHtcbiAgICAgICAgcmV0dXJuIF9zZXRQZXJtaXNzaW9ucy5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgfTtcbiAgICB9KClcbiAgICAvKipcbiAgICAgKiBBcHBlbmQgcHJpbmNpcGFscyB0byB0aGUgY29sbGVjdGlvbiBwZXJtaXNzaW9ucy5cbiAgICAgKlxuICAgICAqIEBwYXJhbSAge09iamVjdH0gIHBlcm1pc3Npb25zICAgICAgICAgICAgIFRoZSBwZXJtaXNzaW9ucyBvYmplY3QuXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSAgW29wdGlvbnM9e31dICAgICAgICAgICAgVGhlIG9wdGlvbnMgb2JqZWN0XG4gICAgICogQHBhcmFtICB7Qm9vbGVhbn0gW29wdGlvbnMuc2FmZV0gICAgICAgICAgVGhlIHNhZmUgb3B0aW9uLlxuICAgICAqIEBwYXJhbSAge09iamVjdH0gIFtvcHRpb25zLmhlYWRlcnNdICAgICAgIFRoZSBoZWFkZXJzIG9iamVjdCBvcHRpb24uXG4gICAgICogQHBhcmFtICB7TnVtYmVyfSAgW29wdGlvbnMucmV0cnk9MF0gICAgICAgTnVtYmVyIG9mIHJldHJpZXMgdG8gbWFrZVxuICAgICAqICAgICB3aGVuIGZhY2VkIHdpdGggdHJhbnNpZW50IGVycm9ycy5cbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9ICBbb3B0aW9ucy5sYXN0X21vZGlmaWVkXSBUaGUgbGFzdF9tb2RpZmllZCBvcHRpb24uXG4gICAgICogQHJldHVybiB7UHJvbWlzZTxPYmplY3QsIEVycm9yPn1cbiAgICAgKi9cblxuICB9LCB7XG4gICAga2V5OiBcImFkZFBlcm1pc3Npb25zXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciBfYWRkUGVybWlzc2lvbnMgPSAoMCwgX2FzeW5jVG9HZW5lcmF0b3IyLmRlZmF1bHQpKFxuICAgICAgLyojX19QVVJFX18qL1xuICAgICAgX3JlZ2VuZXJhdG9yLmRlZmF1bHQubWFyayhmdW5jdGlvbiBfY2FsbGVlNihwZXJtaXNzaW9ucykge1xuICAgICAgICB2YXIgb3B0aW9ucyxcbiAgICAgICAgICAgIHBhdGgsXG4gICAgICAgICAgICBsYXN0X21vZGlmaWVkLFxuICAgICAgICAgICAgcmVxdWVzdCxcbiAgICAgICAgICAgIF9hcmdzNiA9IGFyZ3VtZW50cztcbiAgICAgICAgcmV0dXJuIF9yZWdlbmVyYXRvci5kZWZhdWx0LndyYXAoZnVuY3Rpb24gX2NhbGxlZTYkKF9jb250ZXh0Nikge1xuICAgICAgICAgIHdoaWxlICgxKSB7XG4gICAgICAgICAgICBzd2l0Y2ggKF9jb250ZXh0Ni5wcmV2ID0gX2NvbnRleHQ2Lm5leHQpIHtcbiAgICAgICAgICAgICAgY2FzZSAwOlxuICAgICAgICAgICAgICAgIG9wdGlvbnMgPSBfYXJnczYubGVuZ3RoID4gMSAmJiBfYXJnczZbMV0gIT09IHVuZGVmaW5lZCA/IF9hcmdzNlsxXSA6IHt9O1xuXG4gICAgICAgICAgICAgICAgaWYgKCgwLCBfdXRpbHMuaXNPYmplY3QpKHBlcm1pc3Npb25zKSkge1xuICAgICAgICAgICAgICAgICAgX2NvbnRleHQ2Lm5leHQgPSAzO1xuICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQSBwZXJtaXNzaW9ucyBvYmplY3QgaXMgcmVxdWlyZWQuXCIpO1xuXG4gICAgICAgICAgICAgIGNhc2UgMzpcbiAgICAgICAgICAgICAgICBwYXRoID0gKDAsIF9lbmRwb2ludC5kZWZhdWx0KShcImNvbGxlY3Rpb25cIiwgdGhpcy5idWNrZXQubmFtZSwgdGhpcy5uYW1lKTtcbiAgICAgICAgICAgICAgICBsYXN0X21vZGlmaWVkID0gb3B0aW9ucy5sYXN0X21vZGlmaWVkO1xuICAgICAgICAgICAgICAgIHJlcXVlc3QgPSByZXF1ZXN0cy5qc29uUGF0Y2hQZXJtaXNzaW9uc1JlcXVlc3QocGF0aCwgcGVybWlzc2lvbnMsIFwiYWRkXCIsIHtcbiAgICAgICAgICAgICAgICAgIGxhc3RfbW9kaWZpZWQ6IGxhc3RfbW9kaWZpZWQsXG4gICAgICAgICAgICAgICAgICBoZWFkZXJzOiB0aGlzLl9nZXRIZWFkZXJzKG9wdGlvbnMpLFxuICAgICAgICAgICAgICAgICAgc2FmZTogdGhpcy5fZ2V0U2FmZShvcHRpb25zKVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDYuYWJydXB0KFwicmV0dXJuXCIsIHRoaXMuY2xpZW50LmV4ZWN1dGUocmVxdWVzdCwge1xuICAgICAgICAgICAgICAgICAgcmV0cnk6IHRoaXMuX2dldFJldHJ5KG9wdGlvbnMpXG4gICAgICAgICAgICAgICAgfSkpO1xuXG4gICAgICAgICAgICAgIGNhc2UgNzpcbiAgICAgICAgICAgICAgY2FzZSBcImVuZFwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDYuc3RvcCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSwgX2NhbGxlZTYsIHRoaXMpO1xuICAgICAgfSkpO1xuXG4gICAgICByZXR1cm4gZnVuY3Rpb24gYWRkUGVybWlzc2lvbnMoX3gzKSB7XG4gICAgICAgIHJldHVybiBfYWRkUGVybWlzc2lvbnMuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgIH07XG4gICAgfSgpXG4gICAgLyoqXG4gICAgICogUmVtb3ZlIHByaW5jaXBhbHMgZnJvbSB0aGUgY29sbGVjdGlvbiBwZXJtaXNzaW9ucy5cbiAgICAgKlxuICAgICAqIEBwYXJhbSAge09iamVjdH0gIHBlcm1pc3Npb25zICAgICAgICAgICAgIFRoZSBwZXJtaXNzaW9ucyBvYmplY3QuXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSAgW29wdGlvbnM9e31dICAgICAgICAgICAgVGhlIG9wdGlvbnMgb2JqZWN0XG4gICAgICogQHBhcmFtICB7Qm9vbGVhbn0gW29wdGlvbnMuc2FmZV0gICAgICAgICAgVGhlIHNhZmUgb3B0aW9uLlxuICAgICAqIEBwYXJhbSAge09iamVjdH0gIFtvcHRpb25zLmhlYWRlcnNdICAgICAgIFRoZSBoZWFkZXJzIG9iamVjdCBvcHRpb24uXG4gICAgICogQHBhcmFtICB7TnVtYmVyfSAgW29wdGlvbnMucmV0cnk9MF0gICAgICAgTnVtYmVyIG9mIHJldHJpZXMgdG8gbWFrZVxuICAgICAqICAgICB3aGVuIGZhY2VkIHdpdGggdHJhbnNpZW50IGVycm9ycy5cbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9ICBbb3B0aW9ucy5sYXN0X21vZGlmaWVkXSBUaGUgbGFzdF9tb2RpZmllZCBvcHRpb24uXG4gICAgICogQHJldHVybiB7UHJvbWlzZTxPYmplY3QsIEVycm9yPn1cbiAgICAgKi9cblxuICB9LCB7XG4gICAga2V5OiBcInJlbW92ZVBlcm1pc3Npb25zXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciBfcmVtb3ZlUGVybWlzc2lvbnMgPSAoMCwgX2FzeW5jVG9HZW5lcmF0b3IyLmRlZmF1bHQpKFxuICAgICAgLyojX19QVVJFX18qL1xuICAgICAgX3JlZ2VuZXJhdG9yLmRlZmF1bHQubWFyayhmdW5jdGlvbiBfY2FsbGVlNyhwZXJtaXNzaW9ucykge1xuICAgICAgICB2YXIgb3B0aW9ucyxcbiAgICAgICAgICAgIHBhdGgsXG4gICAgICAgICAgICBsYXN0X21vZGlmaWVkLFxuICAgICAgICAgICAgcmVxdWVzdCxcbiAgICAgICAgICAgIF9hcmdzNyA9IGFyZ3VtZW50cztcbiAgICAgICAgcmV0dXJuIF9yZWdlbmVyYXRvci5kZWZhdWx0LndyYXAoZnVuY3Rpb24gX2NhbGxlZTckKF9jb250ZXh0Nykge1xuICAgICAgICAgIHdoaWxlICgxKSB7XG4gICAgICAgICAgICBzd2l0Y2ggKF9jb250ZXh0Ny5wcmV2ID0gX2NvbnRleHQ3Lm5leHQpIHtcbiAgICAgICAgICAgICAgY2FzZSAwOlxuICAgICAgICAgICAgICAgIG9wdGlvbnMgPSBfYXJnczcubGVuZ3RoID4gMSAmJiBfYXJnczdbMV0gIT09IHVuZGVmaW5lZCA/IF9hcmdzN1sxXSA6IHt9O1xuXG4gICAgICAgICAgICAgICAgaWYgKCgwLCBfdXRpbHMuaXNPYmplY3QpKHBlcm1pc3Npb25zKSkge1xuICAgICAgICAgICAgICAgICAgX2NvbnRleHQ3Lm5leHQgPSAzO1xuICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQSBwZXJtaXNzaW9ucyBvYmplY3QgaXMgcmVxdWlyZWQuXCIpO1xuXG4gICAgICAgICAgICAgIGNhc2UgMzpcbiAgICAgICAgICAgICAgICBwYXRoID0gKDAsIF9lbmRwb2ludC5kZWZhdWx0KShcImNvbGxlY3Rpb25cIiwgdGhpcy5idWNrZXQubmFtZSwgdGhpcy5uYW1lKTtcbiAgICAgICAgICAgICAgICBsYXN0X21vZGlmaWVkID0gb3B0aW9ucy5sYXN0X21vZGlmaWVkO1xuICAgICAgICAgICAgICAgIHJlcXVlc3QgPSByZXF1ZXN0cy5qc29uUGF0Y2hQZXJtaXNzaW9uc1JlcXVlc3QocGF0aCwgcGVybWlzc2lvbnMsIFwicmVtb3ZlXCIsIHtcbiAgICAgICAgICAgICAgICAgIGxhc3RfbW9kaWZpZWQ6IGxhc3RfbW9kaWZpZWQsXG4gICAgICAgICAgICAgICAgICBoZWFkZXJzOiB0aGlzLl9nZXRIZWFkZXJzKG9wdGlvbnMpLFxuICAgICAgICAgICAgICAgICAgc2FmZTogdGhpcy5fZ2V0U2FmZShvcHRpb25zKVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDcuYWJydXB0KFwicmV0dXJuXCIsIHRoaXMuY2xpZW50LmV4ZWN1dGUocmVxdWVzdCwge1xuICAgICAgICAgICAgICAgICAgcmV0cnk6IHRoaXMuX2dldFJldHJ5KG9wdGlvbnMpXG4gICAgICAgICAgICAgICAgfSkpO1xuXG4gICAgICAgICAgICAgIGNhc2UgNzpcbiAgICAgICAgICAgICAgY2FzZSBcImVuZFwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDcuc3RvcCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSwgX2NhbGxlZTcsIHRoaXMpO1xuICAgICAgfSkpO1xuXG4gICAgICByZXR1cm4gZnVuY3Rpb24gcmVtb3ZlUGVybWlzc2lvbnMoX3g0KSB7XG4gICAgICAgIHJldHVybiBfcmVtb3ZlUGVybWlzc2lvbnMuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgIH07XG4gICAgfSgpXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIHJlY29yZCBpbiBjdXJyZW50IGNvbGxlY3Rpb24uXG4gICAgICpcbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9ICByZWNvcmQgICAgICAgICAgICAgICAgVGhlIHJlY29yZCB0byBjcmVhdGUuXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSAgW29wdGlvbnM9e31dICAgICAgICAgIFRoZSBvcHRpb25zIG9iamVjdC5cbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9ICBbb3B0aW9ucy5oZWFkZXJzXSAgICAgVGhlIGhlYWRlcnMgb2JqZWN0IG9wdGlvbi5cbiAgICAgKiBAcGFyYW0gIHtOdW1iZXJ9ICBbb3B0aW9ucy5yZXRyeT0wXSAgICAgTnVtYmVyIG9mIHJldHJpZXMgdG8gbWFrZVxuICAgICAqICAgICB3aGVuIGZhY2VkIHdpdGggdHJhbnNpZW50IGVycm9ycy5cbiAgICAgKiBAcGFyYW0gIHtCb29sZWFufSBbb3B0aW9ucy5zYWZlXSAgICAgICAgVGhlIHNhZmUgb3B0aW9uLlxuICAgICAqIEBwYXJhbSAge09iamVjdH0gIFtvcHRpb25zLnBlcm1pc3Npb25zXSBUaGUgcGVybWlzc2lvbnMgb3B0aW9uLlxuICAgICAqIEByZXR1cm4ge1Byb21pc2U8T2JqZWN0LCBFcnJvcj59XG4gICAgICovXG5cbiAgfSwge1xuICAgIGtleTogXCJjcmVhdGVSZWNvcmRcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gKCkge1xuICAgICAgdmFyIF9jcmVhdGVSZWNvcmQgPSAoMCwgX2FzeW5jVG9HZW5lcmF0b3IyLmRlZmF1bHQpKFxuICAgICAgLyojX19QVVJFX18qL1xuICAgICAgX3JlZ2VuZXJhdG9yLmRlZmF1bHQubWFyayhmdW5jdGlvbiBfY2FsbGVlOChyZWNvcmQpIHtcbiAgICAgICAgdmFyIG9wdGlvbnMsXG4gICAgICAgICAgICBwZXJtaXNzaW9ucyxcbiAgICAgICAgICAgIHBhdGgsXG4gICAgICAgICAgICByZXF1ZXN0LFxuICAgICAgICAgICAgX2FyZ3M4ID0gYXJndW1lbnRzO1xuICAgICAgICByZXR1cm4gX3JlZ2VuZXJhdG9yLmRlZmF1bHQud3JhcChmdW5jdGlvbiBfY2FsbGVlOCQoX2NvbnRleHQ4KSB7XG4gICAgICAgICAgd2hpbGUgKDEpIHtcbiAgICAgICAgICAgIHN3aXRjaCAoX2NvbnRleHQ4LnByZXYgPSBfY29udGV4dDgubmV4dCkge1xuICAgICAgICAgICAgICBjYXNlIDA6XG4gICAgICAgICAgICAgICAgb3B0aW9ucyA9IF9hcmdzOC5sZW5ndGggPiAxICYmIF9hcmdzOFsxXSAhPT0gdW5kZWZpbmVkID8gX2FyZ3M4WzFdIDoge307XG4gICAgICAgICAgICAgICAgcGVybWlzc2lvbnMgPSBvcHRpb25zLnBlcm1pc3Npb25zO1xuICAgICAgICAgICAgICAgIHBhdGggPSAoMCwgX2VuZHBvaW50LmRlZmF1bHQpKFwicmVjb3JkXCIsIHRoaXMuYnVja2V0Lm5hbWUsIHRoaXMubmFtZSwgcmVjb3JkLmlkKTtcbiAgICAgICAgICAgICAgICByZXF1ZXN0ID0gcmVxdWVzdHMuY3JlYXRlUmVxdWVzdChwYXRoLCB7XG4gICAgICAgICAgICAgICAgICBkYXRhOiByZWNvcmQsXG4gICAgICAgICAgICAgICAgICBwZXJtaXNzaW9uczogcGVybWlzc2lvbnNcbiAgICAgICAgICAgICAgICB9LCB7XG4gICAgICAgICAgICAgICAgICBoZWFkZXJzOiB0aGlzLl9nZXRIZWFkZXJzKG9wdGlvbnMpLFxuICAgICAgICAgICAgICAgICAgc2FmZTogdGhpcy5fZ2V0U2FmZShvcHRpb25zKVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDguYWJydXB0KFwicmV0dXJuXCIsIHRoaXMuY2xpZW50LmV4ZWN1dGUocmVxdWVzdCwge1xuICAgICAgICAgICAgICAgICAgcmV0cnk6IHRoaXMuX2dldFJldHJ5KG9wdGlvbnMpXG4gICAgICAgICAgICAgICAgfSkpO1xuXG4gICAgICAgICAgICAgIGNhc2UgNTpcbiAgICAgICAgICAgICAgY2FzZSBcImVuZFwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDguc3RvcCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSwgX2NhbGxlZTgsIHRoaXMpO1xuICAgICAgfSkpO1xuXG4gICAgICByZXR1cm4gZnVuY3Rpb24gY3JlYXRlUmVjb3JkKF94NSkge1xuICAgICAgICByZXR1cm4gX2NyZWF0ZVJlY29yZC5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgfTtcbiAgICB9KClcbiAgICAvKipcbiAgICAgKiBBZGRzIGFuIGF0dGFjaG1lbnQgdG8gYSByZWNvcmQsIGNyZWF0aW5nIHRoZSByZWNvcmQgd2hlbiBpdCBkb2Vzbid0IGV4aXN0LlxuICAgICAqXG4gICAgICogQHBhcmFtICB7U3RyaW5nfSAgZGF0YVVSTCAgICAgICAgICAgICAgICAgVGhlIGRhdGEgdXJsLlxuICAgICAqIEBwYXJhbSAge09iamVjdH0gIFtyZWNvcmQ9e31dICAgICAgICAgICAgIFRoZSByZWNvcmQgZGF0YS5cbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9ICBbb3B0aW9ucz17fV0gICAgICAgICAgICBUaGUgb3B0aW9ucyBvYmplY3QuXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSAgW29wdGlvbnMuaGVhZGVyc10gICAgICAgVGhlIGhlYWRlcnMgb2JqZWN0IG9wdGlvbi5cbiAgICAgKiBAcGFyYW0gIHtOdW1iZXJ9ICBbb3B0aW9ucy5yZXRyeT0wXSAgICAgICBOdW1iZXIgb2YgcmV0cmllcyB0byBtYWtlXG4gICAgICogICAgIHdoZW4gZmFjZWQgd2l0aCB0cmFuc2llbnQgZXJyb3JzLlxuICAgICAqIEBwYXJhbSAge0Jvb2xlYW59IFtvcHRpb25zLnNhZmVdICAgICAgICAgIFRoZSBzYWZlIG9wdGlvbi5cbiAgICAgKiBAcGFyYW0gIHtOdW1iZXJ9ICBbb3B0aW9ucy5sYXN0X21vZGlmaWVkXSBUaGUgbGFzdF9tb2RpZmllZCBvcHRpb24uXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSAgW29wdGlvbnMucGVybWlzc2lvbnNdICAgVGhlIHBlcm1pc3Npb25zIG9wdGlvbi5cbiAgICAgKiBAcGFyYW0gIHtTdHJpbmd9ICBbb3B0aW9ucy5maWxlbmFtZV0gICAgICBGb3JjZSB0aGUgYXR0YWNobWVudCBmaWxlbmFtZS5cbiAgICAgKiBAcGFyYW0gIHtTdHJpbmd9ICBbb3B0aW9ucy5nemlwcGVkXSAgICAgICBGb3JjZSB0aGUgYXR0YWNobWVudCB0byBiZSBnemlwcGVkIG9yIG5vdC5cbiAgICAgKiBAcmV0dXJuIHtQcm9taXNlPE9iamVjdCwgRXJyb3I+fVxuICAgICAqL1xuXG4gIH0sIHtcbiAgICBrZXk6IFwiYWRkQXR0YWNobWVudFwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgX2FkZEF0dGFjaG1lbnQgPSAoMCwgX2FzeW5jVG9HZW5lcmF0b3IyLmRlZmF1bHQpKFxuICAgICAgLyojX19QVVJFX18qL1xuICAgICAgX3JlZ2VuZXJhdG9yLmRlZmF1bHQubWFyayhmdW5jdGlvbiBfY2FsbGVlOShkYXRhVVJJKSB7XG4gICAgICAgIHZhciByZWNvcmQsXG4gICAgICAgICAgICBvcHRpb25zLFxuICAgICAgICAgICAgcGVybWlzc2lvbnMsXG4gICAgICAgICAgICBpZCxcbiAgICAgICAgICAgIHBhdGgsXG4gICAgICAgICAgICBfcmVjb3JkJG9wdGlvbnMsXG4gICAgICAgICAgICBsYXN0X21vZGlmaWVkLFxuICAgICAgICAgICAgYWRkQXR0YWNobWVudFJlcXVlc3QsXG4gICAgICAgICAgICBfYXJnczkgPSBhcmd1bWVudHM7XG5cbiAgICAgICAgcmV0dXJuIF9yZWdlbmVyYXRvci5kZWZhdWx0LndyYXAoZnVuY3Rpb24gX2NhbGxlZTkkKF9jb250ZXh0OSkge1xuICAgICAgICAgIHdoaWxlICgxKSB7XG4gICAgICAgICAgICBzd2l0Y2ggKF9jb250ZXh0OS5wcmV2ID0gX2NvbnRleHQ5Lm5leHQpIHtcbiAgICAgICAgICAgICAgY2FzZSAwOlxuICAgICAgICAgICAgICAgIHJlY29yZCA9IF9hcmdzOS5sZW5ndGggPiAxICYmIF9hcmdzOVsxXSAhPT0gdW5kZWZpbmVkID8gX2FyZ3M5WzFdIDoge307XG4gICAgICAgICAgICAgICAgb3B0aW9ucyA9IF9hcmdzOS5sZW5ndGggPiAyICYmIF9hcmdzOVsyXSAhPT0gdW5kZWZpbmVkID8gX2FyZ3M5WzJdIDoge307XG4gICAgICAgICAgICAgICAgcGVybWlzc2lvbnMgPSBvcHRpb25zLnBlcm1pc3Npb25zO1xuICAgICAgICAgICAgICAgIGlkID0gcmVjb3JkLmlkIHx8IF91dWlkLnY0LnY0KCk7XG4gICAgICAgICAgICAgICAgcGF0aCA9ICgwLCBfZW5kcG9pbnQuZGVmYXVsdCkoXCJhdHRhY2htZW50XCIsIHRoaXMuYnVja2V0Lm5hbWUsIHRoaXMubmFtZSwgaWQpO1xuICAgICAgICAgICAgICAgIF9yZWNvcmQkb3B0aW9ucyA9ICgwLCBfb2JqZWN0U3ByZWFkMi5kZWZhdWx0KSh7fSwgcmVjb3JkLCBvcHRpb25zKSwgbGFzdF9tb2RpZmllZCA9IF9yZWNvcmQkb3B0aW9ucy5sYXN0X21vZGlmaWVkO1xuICAgICAgICAgICAgICAgIGFkZEF0dGFjaG1lbnRSZXF1ZXN0ID0gcmVxdWVzdHMuYWRkQXR0YWNobWVudFJlcXVlc3QocGF0aCwgZGF0YVVSSSwge1xuICAgICAgICAgICAgICAgICAgZGF0YTogcmVjb3JkLFxuICAgICAgICAgICAgICAgICAgcGVybWlzc2lvbnM6IHBlcm1pc3Npb25zXG4gICAgICAgICAgICAgICAgfSwge1xuICAgICAgICAgICAgICAgICAgbGFzdF9tb2RpZmllZDogbGFzdF9tb2RpZmllZCxcbiAgICAgICAgICAgICAgICAgIGZpbGVuYW1lOiBvcHRpb25zLmZpbGVuYW1lLFxuICAgICAgICAgICAgICAgICAgZ3ppcHBlZDogb3B0aW9ucy5nemlwcGVkLFxuICAgICAgICAgICAgICAgICAgaGVhZGVyczogdGhpcy5fZ2V0SGVhZGVycyhvcHRpb25zKSxcbiAgICAgICAgICAgICAgICAgIHNhZmU6IHRoaXMuX2dldFNhZmUob3B0aW9ucylcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICBfY29udGV4dDkubmV4dCA9IDk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuY2xpZW50LmV4ZWN1dGUoYWRkQXR0YWNobWVudFJlcXVlc3QsIHtcbiAgICAgICAgICAgICAgICAgIHN0cmluZ2lmeTogZmFsc2UsXG4gICAgICAgICAgICAgICAgICByZXRyeTogdGhpcy5fZ2V0UmV0cnkob3B0aW9ucylcbiAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICBjYXNlIDk6XG4gICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0OS5hYnJ1cHQoXCJyZXR1cm5cIiwgdGhpcy5nZXRSZWNvcmQoaWQpKTtcblxuICAgICAgICAgICAgICBjYXNlIDEwOlxuICAgICAgICAgICAgICBjYXNlIFwiZW5kXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0OS5zdG9wKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9LCBfY2FsbGVlOSwgdGhpcyk7XG4gICAgICB9KSk7XG5cbiAgICAgIHJldHVybiBmdW5jdGlvbiBhZGRBdHRhY2htZW50KF94Nikge1xuICAgICAgICByZXR1cm4gX2FkZEF0dGFjaG1lbnQuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgIH07XG4gICAgfSgpXG4gICAgLyoqXG4gICAgICogUmVtb3ZlcyBhbiBhdHRhY2htZW50IGZyb20gYSBnaXZlbiByZWNvcmQuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9ICByZWNvcmRJZCAgICAgICAgICAgICAgICBUaGUgcmVjb3JkIGlkLlxuICAgICAqIEBwYXJhbSAge09iamVjdH0gIFtvcHRpb25zPXt9XSAgICAgICAgICAgIFRoZSBvcHRpb25zIG9iamVjdC5cbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9ICBbb3B0aW9ucy5oZWFkZXJzXSAgICAgICBUaGUgaGVhZGVycyBvYmplY3Qgb3B0aW9uLlxuICAgICAqIEBwYXJhbSAge051bWJlcn0gIFtvcHRpb25zLnJldHJ5PTBdICAgICAgIE51bWJlciBvZiByZXRyaWVzIHRvIG1ha2VcbiAgICAgKiAgICAgd2hlbiBmYWNlZCB3aXRoIHRyYW5zaWVudCBlcnJvcnMuXG4gICAgICogQHBhcmFtICB7Qm9vbGVhbn0gW29wdGlvbnMuc2FmZV0gICAgICAgICAgVGhlIHNhZmUgb3B0aW9uLlxuICAgICAqIEBwYXJhbSAge051bWJlcn0gIFtvcHRpb25zLmxhc3RfbW9kaWZpZWRdIFRoZSBsYXN0X21vZGlmaWVkIG9wdGlvbi5cbiAgICAgKi9cblxuICB9LCB7XG4gICAga2V5OiBcInJlbW92ZUF0dGFjaG1lbnRcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gKCkge1xuICAgICAgdmFyIF9yZW1vdmVBdHRhY2htZW50ID0gKDAsIF9hc3luY1RvR2VuZXJhdG9yMi5kZWZhdWx0KShcbiAgICAgIC8qI19fUFVSRV9fKi9cbiAgICAgIF9yZWdlbmVyYXRvci5kZWZhdWx0Lm1hcmsoZnVuY3Rpb24gX2NhbGxlZTEwKHJlY29yZElkKSB7XG4gICAgICAgIHZhciBvcHRpb25zLFxuICAgICAgICAgICAgbGFzdF9tb2RpZmllZCxcbiAgICAgICAgICAgIHBhdGgsXG4gICAgICAgICAgICByZXF1ZXN0LFxuICAgICAgICAgICAgX2FyZ3MxMCA9IGFyZ3VtZW50cztcbiAgICAgICAgcmV0dXJuIF9yZWdlbmVyYXRvci5kZWZhdWx0LndyYXAoZnVuY3Rpb24gX2NhbGxlZTEwJChfY29udGV4dDEwKSB7XG4gICAgICAgICAgd2hpbGUgKDEpIHtcbiAgICAgICAgICAgIHN3aXRjaCAoX2NvbnRleHQxMC5wcmV2ID0gX2NvbnRleHQxMC5uZXh0KSB7XG4gICAgICAgICAgICAgIGNhc2UgMDpcbiAgICAgICAgICAgICAgICBvcHRpb25zID0gX2FyZ3MxMC5sZW5ndGggPiAxICYmIF9hcmdzMTBbMV0gIT09IHVuZGVmaW5lZCA/IF9hcmdzMTBbMV0gOiB7fTtcbiAgICAgICAgICAgICAgICBsYXN0X21vZGlmaWVkID0gb3B0aW9ucy5sYXN0X21vZGlmaWVkO1xuICAgICAgICAgICAgICAgIHBhdGggPSAoMCwgX2VuZHBvaW50LmRlZmF1bHQpKFwiYXR0YWNobWVudFwiLCB0aGlzLmJ1Y2tldC5uYW1lLCB0aGlzLm5hbWUsIHJlY29yZElkKTtcbiAgICAgICAgICAgICAgICByZXF1ZXN0ID0gcmVxdWVzdHMuZGVsZXRlUmVxdWVzdChwYXRoLCB7XG4gICAgICAgICAgICAgICAgICBsYXN0X21vZGlmaWVkOiBsYXN0X21vZGlmaWVkLFxuICAgICAgICAgICAgICAgICAgaGVhZGVyczogdGhpcy5fZ2V0SGVhZGVycyhvcHRpb25zKSxcbiAgICAgICAgICAgICAgICAgIHNhZmU6IHRoaXMuX2dldFNhZmUob3B0aW9ucylcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQxMC5hYnJ1cHQoXCJyZXR1cm5cIiwgdGhpcy5jbGllbnQuZXhlY3V0ZShyZXF1ZXN0LCB7XG4gICAgICAgICAgICAgICAgICByZXRyeTogdGhpcy5fZ2V0UmV0cnkob3B0aW9ucylcbiAgICAgICAgICAgICAgICB9KSk7XG5cbiAgICAgICAgICAgICAgY2FzZSA1OlxuICAgICAgICAgICAgICBjYXNlIFwiZW5kXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0MTAuc3RvcCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSwgX2NhbGxlZTEwLCB0aGlzKTtcbiAgICAgIH0pKTtcblxuICAgICAgcmV0dXJuIGZ1bmN0aW9uIHJlbW92ZUF0dGFjaG1lbnQoX3g3KSB7XG4gICAgICAgIHJldHVybiBfcmVtb3ZlQXR0YWNobWVudC5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgfTtcbiAgICB9KClcbiAgICAvKipcbiAgICAgKiBVcGRhdGVzIGEgcmVjb3JkIGluIGN1cnJlbnQgY29sbGVjdGlvbi5cbiAgICAgKlxuICAgICAqIEBwYXJhbSAge09iamVjdH0gIHJlY29yZCAgICAgICAgICAgICAgICAgIFRoZSByZWNvcmQgdG8gdXBkYXRlLlxuICAgICAqIEBwYXJhbSAge09iamVjdH0gIFtvcHRpb25zPXt9XSAgICAgICAgICAgIFRoZSBvcHRpb25zIG9iamVjdC5cbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9ICBbb3B0aW9ucy5oZWFkZXJzXSAgICAgICBUaGUgaGVhZGVycyBvYmplY3Qgb3B0aW9uLlxuICAgICAqIEBwYXJhbSAge051bWJlcn0gIFtvcHRpb25zLnJldHJ5PTBdICAgICAgIE51bWJlciBvZiByZXRyaWVzIHRvIG1ha2VcbiAgICAgKiAgICAgd2hlbiBmYWNlZCB3aXRoIHRyYW5zaWVudCBlcnJvcnMuXG4gICAgICogQHBhcmFtICB7Qm9vbGVhbn0gW29wdGlvbnMuc2FmZV0gICAgICAgICAgVGhlIHNhZmUgb3B0aW9uLlxuICAgICAqIEBwYXJhbSAge051bWJlcn0gIFtvcHRpb25zLmxhc3RfbW9kaWZpZWRdIFRoZSBsYXN0X21vZGlmaWVkIG9wdGlvbi5cbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9ICBbb3B0aW9ucy5wZXJtaXNzaW9uc10gICBUaGUgcGVybWlzc2lvbnMgb3B0aW9uLlxuICAgICAqIEByZXR1cm4ge1Byb21pc2U8T2JqZWN0LCBFcnJvcj59XG4gICAgICovXG5cbiAgfSwge1xuICAgIGtleTogXCJ1cGRhdGVSZWNvcmRcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gKCkge1xuICAgICAgdmFyIF91cGRhdGVSZWNvcmQgPSAoMCwgX2FzeW5jVG9HZW5lcmF0b3IyLmRlZmF1bHQpKFxuICAgICAgLyojX19QVVJFX18qL1xuICAgICAgX3JlZ2VuZXJhdG9yLmRlZmF1bHQubWFyayhmdW5jdGlvbiBfY2FsbGVlMTEocmVjb3JkKSB7XG4gICAgICAgIHZhciBvcHRpb25zLFxuICAgICAgICAgICAgcGVybWlzc2lvbnMsXG4gICAgICAgICAgICBfcmVjb3JkJG9wdGlvbnMyLFxuICAgICAgICAgICAgbGFzdF9tb2RpZmllZCxcbiAgICAgICAgICAgIHBhdGgsXG4gICAgICAgICAgICByZXF1ZXN0LFxuICAgICAgICAgICAgX2FyZ3MxMSA9IGFyZ3VtZW50cztcblxuICAgICAgICByZXR1cm4gX3JlZ2VuZXJhdG9yLmRlZmF1bHQud3JhcChmdW5jdGlvbiBfY2FsbGVlMTEkKF9jb250ZXh0MTEpIHtcbiAgICAgICAgICB3aGlsZSAoMSkge1xuICAgICAgICAgICAgc3dpdGNoIChfY29udGV4dDExLnByZXYgPSBfY29udGV4dDExLm5leHQpIHtcbiAgICAgICAgICAgICAgY2FzZSAwOlxuICAgICAgICAgICAgICAgIG9wdGlvbnMgPSBfYXJnczExLmxlbmd0aCA+IDEgJiYgX2FyZ3MxMVsxXSAhPT0gdW5kZWZpbmVkID8gX2FyZ3MxMVsxXSA6IHt9O1xuXG4gICAgICAgICAgICAgICAgaWYgKCgwLCBfdXRpbHMuaXNPYmplY3QpKHJlY29yZCkpIHtcbiAgICAgICAgICAgICAgICAgIF9jb250ZXh0MTEubmV4dCA9IDM7XG4gICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJBIHJlY29yZCBvYmplY3QgaXMgcmVxdWlyZWQuXCIpO1xuXG4gICAgICAgICAgICAgIGNhc2UgMzpcbiAgICAgICAgICAgICAgICBpZiAocmVjb3JkLmlkKSB7XG4gICAgICAgICAgICAgICAgICBfY29udGV4dDExLm5leHQgPSA1O1xuICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQSByZWNvcmQgaWQgaXMgcmVxdWlyZWQuXCIpO1xuXG4gICAgICAgICAgICAgIGNhc2UgNTpcbiAgICAgICAgICAgICAgICBwZXJtaXNzaW9ucyA9IG9wdGlvbnMucGVybWlzc2lvbnM7XG4gICAgICAgICAgICAgICAgX3JlY29yZCRvcHRpb25zMiA9ICgwLCBfb2JqZWN0U3ByZWFkMi5kZWZhdWx0KSh7fSwgcmVjb3JkLCBvcHRpb25zKSwgbGFzdF9tb2RpZmllZCA9IF9yZWNvcmQkb3B0aW9uczIubGFzdF9tb2RpZmllZDtcbiAgICAgICAgICAgICAgICBwYXRoID0gKDAsIF9lbmRwb2ludC5kZWZhdWx0KShcInJlY29yZFwiLCB0aGlzLmJ1Y2tldC5uYW1lLCB0aGlzLm5hbWUsIHJlY29yZC5pZCk7XG4gICAgICAgICAgICAgICAgcmVxdWVzdCA9IHJlcXVlc3RzLnVwZGF0ZVJlcXVlc3QocGF0aCwge1xuICAgICAgICAgICAgICAgICAgZGF0YTogcmVjb3JkLFxuICAgICAgICAgICAgICAgICAgcGVybWlzc2lvbnM6IHBlcm1pc3Npb25zXG4gICAgICAgICAgICAgICAgfSwge1xuICAgICAgICAgICAgICAgICAgaGVhZGVyczogdGhpcy5fZ2V0SGVhZGVycyhvcHRpb25zKSxcbiAgICAgICAgICAgICAgICAgIHNhZmU6IHRoaXMuX2dldFNhZmUob3B0aW9ucyksXG4gICAgICAgICAgICAgICAgICBsYXN0X21vZGlmaWVkOiBsYXN0X21vZGlmaWVkLFxuICAgICAgICAgICAgICAgICAgcGF0Y2g6ICEhb3B0aW9ucy5wYXRjaFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDExLmFicnVwdChcInJldHVyblwiLCB0aGlzLmNsaWVudC5leGVjdXRlKHJlcXVlc3QsIHtcbiAgICAgICAgICAgICAgICAgIHJldHJ5OiB0aGlzLl9nZXRSZXRyeShvcHRpb25zKVxuICAgICAgICAgICAgICAgIH0pKTtcblxuICAgICAgICAgICAgICBjYXNlIDEwOlxuICAgICAgICAgICAgICBjYXNlIFwiZW5kXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0MTEuc3RvcCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSwgX2NhbGxlZTExLCB0aGlzKTtcbiAgICAgIH0pKTtcblxuICAgICAgcmV0dXJuIGZ1bmN0aW9uIHVwZGF0ZVJlY29yZChfeDgpIHtcbiAgICAgICAgcmV0dXJuIF91cGRhdGVSZWNvcmQuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgIH07XG4gICAgfSgpXG4gICAgLyoqXG4gICAgICogRGVsZXRlcyBhIHJlY29yZCBmcm9tIHRoZSBjdXJyZW50IGNvbGxlY3Rpb24uXG4gICAgICpcbiAgICAgKiBAcGFyYW0gIHtPYmplY3R8U3RyaW5nfSByZWNvcmQgICAgICAgICAgICAgICAgICBUaGUgcmVjb3JkIHRvIGRlbGV0ZS5cbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9ICAgICAgICBbb3B0aW9ucz17fV0gICAgICAgICAgICBUaGUgb3B0aW9ucyBvYmplY3QuXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSAgICAgICAgW29wdGlvbnMuaGVhZGVyc10gICAgICAgVGhlIGhlYWRlcnMgb2JqZWN0IG9wdGlvbi5cbiAgICAgKiBAcGFyYW0gIHtOdW1iZXJ9ICAgICAgICBbb3B0aW9ucy5yZXRyeT0wXSAgICAgICBOdW1iZXIgb2YgcmV0cmllcyB0byBtYWtlXG4gICAgICogICAgIHdoZW4gZmFjZWQgd2l0aCB0cmFuc2llbnQgZXJyb3JzLlxuICAgICAqIEBwYXJhbSAge0Jvb2xlYW59ICAgICAgIFtvcHRpb25zLnNhZmVdICAgICAgICAgIFRoZSBzYWZlIG9wdGlvbi5cbiAgICAgKiBAcGFyYW0gIHtOdW1iZXJ9ICAgICAgICBbb3B0aW9ucy5sYXN0X21vZGlmaWVkXSBUaGUgbGFzdF9tb2RpZmllZCBvcHRpb24uXG4gICAgICogQHJldHVybiB7UHJvbWlzZTxPYmplY3QsIEVycm9yPn1cbiAgICAgKi9cblxuICB9LCB7XG4gICAga2V5OiBcImRlbGV0ZVJlY29yZFwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgX2RlbGV0ZVJlY29yZCA9ICgwLCBfYXN5bmNUb0dlbmVyYXRvcjIuZGVmYXVsdCkoXG4gICAgICAvKiNfX1BVUkVfXyovXG4gICAgICBfcmVnZW5lcmF0b3IuZGVmYXVsdC5tYXJrKGZ1bmN0aW9uIF9jYWxsZWUxMihyZWNvcmQpIHtcbiAgICAgICAgdmFyIG9wdGlvbnMsXG4gICAgICAgICAgICByZWNvcmRPYmosXG4gICAgICAgICAgICBpZCxcbiAgICAgICAgICAgIF9yZWNvcmRPYmokb3B0aW9ucyxcbiAgICAgICAgICAgIGxhc3RfbW9kaWZpZWQsXG4gICAgICAgICAgICBwYXRoLFxuICAgICAgICAgICAgcmVxdWVzdCxcbiAgICAgICAgICAgIF9hcmdzMTIgPSBhcmd1bWVudHM7XG5cbiAgICAgICAgcmV0dXJuIF9yZWdlbmVyYXRvci5kZWZhdWx0LndyYXAoZnVuY3Rpb24gX2NhbGxlZTEyJChfY29udGV4dDEyKSB7XG4gICAgICAgICAgd2hpbGUgKDEpIHtcbiAgICAgICAgICAgIHN3aXRjaCAoX2NvbnRleHQxMi5wcmV2ID0gX2NvbnRleHQxMi5uZXh0KSB7XG4gICAgICAgICAgICAgIGNhc2UgMDpcbiAgICAgICAgICAgICAgICBvcHRpb25zID0gX2FyZ3MxMi5sZW5ndGggPiAxICYmIF9hcmdzMTJbMV0gIT09IHVuZGVmaW5lZCA/IF9hcmdzMTJbMV0gOiB7fTtcbiAgICAgICAgICAgICAgICByZWNvcmRPYmogPSAoMCwgX3V0aWxzLnRvRGF0YUJvZHkpKHJlY29yZCk7XG5cbiAgICAgICAgICAgICAgICBpZiAocmVjb3JkT2JqLmlkKSB7XG4gICAgICAgICAgICAgICAgICBfY29udGV4dDEyLm5leHQgPSA0O1xuICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQSByZWNvcmQgaWQgaXMgcmVxdWlyZWQuXCIpO1xuXG4gICAgICAgICAgICAgIGNhc2UgNDpcbiAgICAgICAgICAgICAgICBpZCA9IHJlY29yZE9iai5pZDtcbiAgICAgICAgICAgICAgICBfcmVjb3JkT2JqJG9wdGlvbnMgPSAoMCwgX29iamVjdFNwcmVhZDIuZGVmYXVsdCkoe30sIHJlY29yZE9iaiwgb3B0aW9ucyksIGxhc3RfbW9kaWZpZWQgPSBfcmVjb3JkT2JqJG9wdGlvbnMubGFzdF9tb2RpZmllZDtcbiAgICAgICAgICAgICAgICBwYXRoID0gKDAsIF9lbmRwb2ludC5kZWZhdWx0KShcInJlY29yZFwiLCB0aGlzLmJ1Y2tldC5uYW1lLCB0aGlzLm5hbWUsIGlkKTtcbiAgICAgICAgICAgICAgICByZXF1ZXN0ID0gcmVxdWVzdHMuZGVsZXRlUmVxdWVzdChwYXRoLCB7XG4gICAgICAgICAgICAgICAgICBsYXN0X21vZGlmaWVkOiBsYXN0X21vZGlmaWVkLFxuICAgICAgICAgICAgICAgICAgaGVhZGVyczogdGhpcy5fZ2V0SGVhZGVycyhvcHRpb25zKSxcbiAgICAgICAgICAgICAgICAgIHNhZmU6IHRoaXMuX2dldFNhZmUob3B0aW9ucylcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQxMi5hYnJ1cHQoXCJyZXR1cm5cIiwgdGhpcy5jbGllbnQuZXhlY3V0ZShyZXF1ZXN0LCB7XG4gICAgICAgICAgICAgICAgICByZXRyeTogdGhpcy5fZ2V0UmV0cnkob3B0aW9ucylcbiAgICAgICAgICAgICAgICB9KSk7XG5cbiAgICAgICAgICAgICAgY2FzZSA5OlxuICAgICAgICAgICAgICBjYXNlIFwiZW5kXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0MTIuc3RvcCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSwgX2NhbGxlZTEyLCB0aGlzKTtcbiAgICAgIH0pKTtcblxuICAgICAgcmV0dXJuIGZ1bmN0aW9uIGRlbGV0ZVJlY29yZChfeDkpIHtcbiAgICAgICAgcmV0dXJuIF9kZWxldGVSZWNvcmQuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgIH07XG4gICAgfSgpXG4gICAgLyoqXG4gICAgICogUmV0cmlldmVzIGEgcmVjb3JkIGZyb20gdGhlIGN1cnJlbnQgY29sbGVjdGlvbi5cbiAgICAgKlxuICAgICAqIEBwYXJhbSAge1N0cmluZ30gaWQgICAgICAgICAgICAgICAgVGhlIHJlY29yZCBpZCB0byByZXRyaWV2ZS5cbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9IFtvcHRpb25zPXt9XSAgICAgIFRoZSBvcHRpb25zIG9iamVjdC5cbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9IFtvcHRpb25zLmhlYWRlcnNdIFRoZSBoZWFkZXJzIG9iamVjdCBvcHRpb24uXG4gICAgICogQHBhcmFtICB7TnVtYmVyfSBbb3B0aW9ucy5yZXRyeT0wXSBOdW1iZXIgb2YgcmV0cmllcyB0byBtYWtlXG4gICAgICogICAgIHdoZW4gZmFjZWQgd2l0aCB0cmFuc2llbnQgZXJyb3JzLlxuICAgICAqIEByZXR1cm4ge1Byb21pc2U8T2JqZWN0LCBFcnJvcj59XG4gICAgICovXG5cbiAgfSwge1xuICAgIGtleTogXCJnZXRSZWNvcmRcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gKCkge1xuICAgICAgdmFyIF9nZXRSZWNvcmQgPSAoMCwgX2FzeW5jVG9HZW5lcmF0b3IyLmRlZmF1bHQpKFxuICAgICAgLyojX19QVVJFX18qL1xuICAgICAgX3JlZ2VuZXJhdG9yLmRlZmF1bHQubWFyayhmdW5jdGlvbiBfY2FsbGVlMTMoaWQpIHtcbiAgICAgICAgdmFyIG9wdGlvbnMsXG4gICAgICAgICAgICBwYXRoLFxuICAgICAgICAgICAgcmVxdWVzdCxcbiAgICAgICAgICAgIF9hcmdzMTMgPSBhcmd1bWVudHM7XG4gICAgICAgIHJldHVybiBfcmVnZW5lcmF0b3IuZGVmYXVsdC53cmFwKGZ1bmN0aW9uIF9jYWxsZWUxMyQoX2NvbnRleHQxMykge1xuICAgICAgICAgIHdoaWxlICgxKSB7XG4gICAgICAgICAgICBzd2l0Y2ggKF9jb250ZXh0MTMucHJldiA9IF9jb250ZXh0MTMubmV4dCkge1xuICAgICAgICAgICAgICBjYXNlIDA6XG4gICAgICAgICAgICAgICAgb3B0aW9ucyA9IF9hcmdzMTMubGVuZ3RoID4gMSAmJiBfYXJnczEzWzFdICE9PSB1bmRlZmluZWQgPyBfYXJnczEzWzFdIDoge307XG4gICAgICAgICAgICAgICAgcGF0aCA9ICgwLCBfZW5kcG9pbnQuZGVmYXVsdCkoXCJyZWNvcmRcIiwgdGhpcy5idWNrZXQubmFtZSwgdGhpcy5uYW1lLCBpZCk7XG4gICAgICAgICAgICAgICAgcmVxdWVzdCA9IHtcbiAgICAgICAgICAgICAgICAgIGhlYWRlcnM6IHRoaXMuX2dldEhlYWRlcnMob3B0aW9ucyksXG4gICAgICAgICAgICAgICAgICBwYXRoOiBwYXRoXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQxMy5hYnJ1cHQoXCJyZXR1cm5cIiwgdGhpcy5jbGllbnQuZXhlY3V0ZShyZXF1ZXN0LCB7XG4gICAgICAgICAgICAgICAgICByZXRyeTogdGhpcy5fZ2V0UmV0cnkob3B0aW9ucylcbiAgICAgICAgICAgICAgICB9KSk7XG5cbiAgICAgICAgICAgICAgY2FzZSA0OlxuICAgICAgICAgICAgICBjYXNlIFwiZW5kXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0MTMuc3RvcCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSwgX2NhbGxlZTEzLCB0aGlzKTtcbiAgICAgIH0pKTtcblxuICAgICAgcmV0dXJuIGZ1bmN0aW9uIGdldFJlY29yZChfeDEwKSB7XG4gICAgICAgIHJldHVybiBfZ2V0UmVjb3JkLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICB9O1xuICAgIH0oKVxuICAgIC8qKlxuICAgICAqIExpc3RzIHJlY29yZHMgZnJvbSB0aGUgY3VycmVudCBjb2xsZWN0aW9uLlxuICAgICAqXG4gICAgICogU29ydGluZyBpcyBkb25lIGJ5IHBhc3NpbmcgYSBgc29ydGAgc3RyaW5nIG9wdGlvbjpcbiAgICAgKlxuICAgICAqIC0gVGhlIGZpZWxkIHRvIG9yZGVyIHRoZSByZXN1bHRzIGJ5LCBwcmVmaXhlZCB3aXRoIGAtYCBmb3IgZGVzY2VuZGluZy5cbiAgICAgKiBEZWZhdWx0OiBgLWxhc3RfbW9kaWZpZWRgLlxuICAgICAqXG4gICAgICogQHNlZSBodHRwOi8va2ludG8ucmVhZHRoZWRvY3MuaW8vZW4vc3RhYmxlL2FwaS8xLngvc29ydGluZy5odG1sXG4gICAgICpcbiAgICAgKiBGaWx0ZXJpbmcgaXMgZG9uZSBieSBwYXNzaW5nIGEgYGZpbHRlcnNgIG9wdGlvbiBvYmplY3Q6XG4gICAgICpcbiAgICAgKiAtIGB7ZmllbGRuYW1lOiBcInZhbHVlXCJ9YFxuICAgICAqIC0gYHttaW5fZmllbGRuYW1lOiA0MDAwfWBcbiAgICAgKiAtIGB7aW5fZmllbGRuYW1lOiBcIjEsMiwzXCJ9YFxuICAgICAqIC0gYHtub3RfZmllbGRuYW1lOiAwfWBcbiAgICAgKiAtIGB7ZXhjbHVkZV9maWVsZG5hbWU6IFwiMCwxXCJ9YFxuICAgICAqXG4gICAgICogQHNlZSBodHRwOi8va2ludG8ucmVhZHRoZWRvY3MuaW8vZW4vc3RhYmxlL2FwaS8xLngvZmlsdGVyaW5nLmh0bWxcbiAgICAgKlxuICAgICAqIFBhZ2luYXRpbmcgaXMgZG9uZSBieSBwYXNzaW5nIGEgYGxpbWl0YCBvcHRpb24sIHRoZW4gY2FsbGluZyB0aGUgYG5leHQoKWBcbiAgICAgKiBtZXRob2QgZnJvbSB0aGUgcmVzb2x2ZWQgcmVzdWx0IG9iamVjdCB0byBmZXRjaCB0aGUgbmV4dCBwYWdlLCBpZiBhbnkuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9ICAgW29wdGlvbnM9e31dICAgICAgICAgICAgICAgICAgICBUaGUgb3B0aW9ucyBvYmplY3QuXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSAgIFtvcHRpb25zLmhlYWRlcnNdICAgICAgICAgICAgICAgVGhlIGhlYWRlcnMgb2JqZWN0IG9wdGlvbi5cbiAgICAgKiBAcGFyYW0gIHtOdW1iZXJ9ICAgW29wdGlvbnMucmV0cnk9MF0gICAgICAgICAgICAgICBOdW1iZXIgb2YgcmV0cmllcyB0byBtYWtlXG4gICAgICogICAgIHdoZW4gZmFjZWQgd2l0aCB0cmFuc2llbnQgZXJyb3JzLlxuICAgICAqIEBwYXJhbSAge09iamVjdH0gICBbb3B0aW9ucy5maWx0ZXJzPVtdXSAgICAgICAgICAgIFRoZSBmaWx0ZXJzIG9iamVjdC5cbiAgICAgKiBAcGFyYW0gIHtTdHJpbmd9ICAgW29wdGlvbnMuc29ydD1cIi1sYXN0X21vZGlmaWVkXCJdIFRoZSBzb3J0IGZpZWxkLlxuICAgICAqIEBwYXJhbSAge1N0cmluZ30gICBbb3B0aW9ucy5hdF0gICAgICAgICAgICAgICAgICAgIFRoZSB0aW1lc3RhbXAgdG8gZ2V0IGEgc25hcHNob3QgYXQuXG4gICAgICogQHBhcmFtICB7U3RyaW5nfSAgIFtvcHRpb25zLmxpbWl0PW51bGxdICAgICAgICAgICAgVGhlIGxpbWl0IGZpZWxkLlxuICAgICAqIEBwYXJhbSAge1N0cmluZ30gICBbb3B0aW9ucy5wYWdlcz0xXSAgICAgICAgICAgICAgIFRoZSBudW1iZXIgb2YgcmVzdWx0IHBhZ2VzIHRvIGFnZ3JlZ2F0ZS5cbiAgICAgKiBAcGFyYW0gIHtOdW1iZXJ9ICAgW29wdGlvbnMuc2luY2U9bnVsbF0gICAgICAgICAgICBPbmx5IHJldHJpZXZlIHJlY29yZHMgbW9kaWZpZWQgc2luY2UgdGhlIHByb3ZpZGVkIHRpbWVzdGFtcC5cbiAgICAgKiBAcmV0dXJuIHtQcm9taXNlPE9iamVjdCwgRXJyb3I+fVxuICAgICAqL1xuXG4gIH0sIHtcbiAgICBrZXk6IFwibGlzdFJlY29yZHNcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gKCkge1xuICAgICAgdmFyIF9saXN0UmVjb3JkcyA9ICgwLCBfYXN5bmNUb0dlbmVyYXRvcjIuZGVmYXVsdCkoXG4gICAgICAvKiNfX1BVUkVfXyovXG4gICAgICBfcmVnZW5lcmF0b3IuZGVmYXVsdC5tYXJrKGZ1bmN0aW9uIF9jYWxsZWUxNCgpIHtcbiAgICAgICAgdmFyIG9wdGlvbnMsXG4gICAgICAgICAgICBwYXRoLFxuICAgICAgICAgICAgX2FyZ3MxNCA9IGFyZ3VtZW50cztcbiAgICAgICAgcmV0dXJuIF9yZWdlbmVyYXRvci5kZWZhdWx0LndyYXAoZnVuY3Rpb24gX2NhbGxlZTE0JChfY29udGV4dDE0KSB7XG4gICAgICAgICAgd2hpbGUgKDEpIHtcbiAgICAgICAgICAgIHN3aXRjaCAoX2NvbnRleHQxNC5wcmV2ID0gX2NvbnRleHQxNC5uZXh0KSB7XG4gICAgICAgICAgICAgIGNhc2UgMDpcbiAgICAgICAgICAgICAgICBvcHRpb25zID0gX2FyZ3MxNC5sZW5ndGggPiAwICYmIF9hcmdzMTRbMF0gIT09IHVuZGVmaW5lZCA/IF9hcmdzMTRbMF0gOiB7fTtcbiAgICAgICAgICAgICAgICBwYXRoID0gKDAsIF9lbmRwb2ludC5kZWZhdWx0KShcInJlY29yZFwiLCB0aGlzLmJ1Y2tldC5uYW1lLCB0aGlzLm5hbWUpO1xuXG4gICAgICAgICAgICAgICAgaWYgKCFvcHRpb25zLmhhc093blByb3BlcnR5KFwiYXRcIikpIHtcbiAgICAgICAgICAgICAgICAgIF9jb250ZXh0MTQubmV4dCA9IDY7XG4gICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQxNC5hYnJ1cHQoXCJyZXR1cm5cIiwgdGhpcy5nZXRTbmFwc2hvdChvcHRpb25zLmF0KSk7XG5cbiAgICAgICAgICAgICAgY2FzZSA2OlxuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDE0LmFicnVwdChcInJldHVyblwiLCB0aGlzLmNsaWVudC5wYWdpbmF0ZWRMaXN0KHBhdGgsIG9wdGlvbnMsIHtcbiAgICAgICAgICAgICAgICAgIGhlYWRlcnM6IHRoaXMuX2dldEhlYWRlcnMob3B0aW9ucyksXG4gICAgICAgICAgICAgICAgICByZXRyeTogdGhpcy5fZ2V0UmV0cnkob3B0aW9ucylcbiAgICAgICAgICAgICAgICB9KSk7XG5cbiAgICAgICAgICAgICAgY2FzZSA3OlxuICAgICAgICAgICAgICBjYXNlIFwiZW5kXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0MTQuc3RvcCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSwgX2NhbGxlZTE0LCB0aGlzKTtcbiAgICAgIH0pKTtcblxuICAgICAgcmV0dXJuIGZ1bmN0aW9uIGxpc3RSZWNvcmRzKCkge1xuICAgICAgICByZXR1cm4gX2xpc3RSZWNvcmRzLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICB9O1xuICAgIH0oKVxuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG5cbiAgfSwge1xuICAgIGtleTogXCJpc0hpc3RvcnlDb21wbGV0ZVwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgX2lzSGlzdG9yeUNvbXBsZXRlID0gKDAsIF9hc3luY1RvR2VuZXJhdG9yMi5kZWZhdWx0KShcbiAgICAgIC8qI19fUFVSRV9fKi9cbiAgICAgIF9yZWdlbmVyYXRvci5kZWZhdWx0Lm1hcmsoZnVuY3Rpb24gX2NhbGxlZTE1KCkge1xuICAgICAgICB2YXIgX3JlZjQsIF9yZWY0JGRhdGEsIG9sZGVzdEhpc3RvcnlFbnRyeTtcblxuICAgICAgICByZXR1cm4gX3JlZ2VuZXJhdG9yLmRlZmF1bHQud3JhcChmdW5jdGlvbiBfY2FsbGVlMTUkKF9jb250ZXh0MTUpIHtcbiAgICAgICAgICB3aGlsZSAoMSkge1xuICAgICAgICAgICAgc3dpdGNoIChfY29udGV4dDE1LnByZXYgPSBfY29udGV4dDE1Lm5leHQpIHtcbiAgICAgICAgICAgICAgY2FzZSAwOlxuICAgICAgICAgICAgICAgIF9jb250ZXh0MTUubmV4dCA9IDI7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuYnVja2V0Lmxpc3RIaXN0b3J5KHtcbiAgICAgICAgICAgICAgICAgIGxpbWl0OiAxLFxuICAgICAgICAgICAgICAgICAgZmlsdGVyczoge1xuICAgICAgICAgICAgICAgICAgICBhY3Rpb246IFwiY3JlYXRlXCIsXG4gICAgICAgICAgICAgICAgICAgIHJlc291cmNlX25hbWU6IFwiY29sbGVjdGlvblwiLFxuICAgICAgICAgICAgICAgICAgICBjb2xsZWN0aW9uX2lkOiB0aGlzLm5hbWVcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICBjYXNlIDI6XG4gICAgICAgICAgICAgICAgX3JlZjQgPSBfY29udGV4dDE1LnNlbnQ7XG4gICAgICAgICAgICAgICAgX3JlZjQkZGF0YSA9ICgwLCBfc2xpY2VkVG9BcnJheTIuZGVmYXVsdCkoX3JlZjQuZGF0YSwgMSk7XG4gICAgICAgICAgICAgICAgb2xkZXN0SGlzdG9yeUVudHJ5ID0gX3JlZjQkZGF0YVswXTtcbiAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQxNS5hYnJ1cHQoXCJyZXR1cm5cIiwgISFvbGRlc3RIaXN0b3J5RW50cnkpO1xuXG4gICAgICAgICAgICAgIGNhc2UgNjpcbiAgICAgICAgICAgICAgY2FzZSBcImVuZFwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDE1LnN0b3AoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0sIF9jYWxsZWUxNSwgdGhpcyk7XG4gICAgICB9KSk7XG5cbiAgICAgIHJldHVybiBmdW5jdGlvbiBpc0hpc3RvcnlDb21wbGV0ZSgpIHtcbiAgICAgICAgcmV0dXJuIF9pc0hpc3RvcnlDb21wbGV0ZS5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgfTtcbiAgICB9KClcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuXG4gIH0sIHtcbiAgICBrZXk6IFwibGlzdENoYW5nZXNCYWNrVG9cIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gKCkge1xuICAgICAgdmFyIF9saXN0Q2hhbmdlc0JhY2tUbyA9ICgwLCBfYXN5bmNUb0dlbmVyYXRvcjIuZGVmYXVsdCkoXG4gICAgICAvKiNfX1BVUkVfXyovXG4gICAgICBfcmVnZW5lcmF0b3IuZGVmYXVsdC5tYXJrKGZ1bmN0aW9uIF9jYWxsZWUxNihhdCkge1xuICAgICAgICB2YXIgX3JlZjUsIGNoYW5nZXM7XG5cbiAgICAgICAgcmV0dXJuIF9yZWdlbmVyYXRvci5kZWZhdWx0LndyYXAoZnVuY3Rpb24gX2NhbGxlZTE2JChfY29udGV4dDE2KSB7XG4gICAgICAgICAgd2hpbGUgKDEpIHtcbiAgICAgICAgICAgIHN3aXRjaCAoX2NvbnRleHQxNi5wcmV2ID0gX2NvbnRleHQxNi5uZXh0KSB7XG4gICAgICAgICAgICAgIGNhc2UgMDpcbiAgICAgICAgICAgICAgICBfY29udGV4dDE2Lm5leHQgPSAyO1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmlzSGlzdG9yeUNvbXBsZXRlKCk7XG5cbiAgICAgICAgICAgICAgY2FzZSAyOlxuICAgICAgICAgICAgICAgIGlmIChfY29udGV4dDE2LnNlbnQpIHtcbiAgICAgICAgICAgICAgICAgIF9jb250ZXh0MTYubmV4dCA9IDQ7XG4gICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJDb21wdXRpbmcgYSBzbmFwc2hvdCBpcyBvbmx5IHBvc3NpYmxlIHdoZW4gdGhlIGZ1bGwgaGlzdG9yeSBmb3IgYSBcIiArIFwiY29sbGVjdGlvbiBpcyBhdmFpbGFibGUuIEhlcmUsIHRoZSBoaXN0b3J5IHBsdWdpbiBzZWVtcyB0byBoYXZlIFwiICsgXCJiZWVuIGVuYWJsZWQgYWZ0ZXIgdGhlIGNyZWF0aW9uIG9mIHRoZSBjb2xsZWN0aW9uLlwiKTtcblxuICAgICAgICAgICAgICBjYXNlIDQ6XG4gICAgICAgICAgICAgICAgX2NvbnRleHQxNi5uZXh0ID0gNjtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5idWNrZXQubGlzdEhpc3Rvcnkoe1xuICAgICAgICAgICAgICAgICAgcGFnZXM6IEluZmluaXR5LFxuICAgICAgICAgICAgICAgICAgLy8gYWxsIHBhZ2VzIHVwIHRvIHRhcmdldCB0aW1lc3RhbXAgYXJlIHJlcXVpcmVkXG4gICAgICAgICAgICAgICAgICBzb3J0OiBcIi10YXJnZXQuZGF0YS5sYXN0X21vZGlmaWVkXCIsXG4gICAgICAgICAgICAgICAgICBmaWx0ZXJzOiB7XG4gICAgICAgICAgICAgICAgICAgIHJlc291cmNlX25hbWU6IFwicmVjb3JkXCIsXG4gICAgICAgICAgICAgICAgICAgIGNvbGxlY3Rpb25faWQ6IHRoaXMubmFtZSxcbiAgICAgICAgICAgICAgICAgICAgXCJtYXhfdGFyZ2V0LmRhdGEubGFzdF9tb2RpZmllZFwiOiBTdHJpbmcoYXQpIC8vIGVxLiB0byA8PVxuXG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgY2FzZSA2OlxuICAgICAgICAgICAgICAgIF9yZWY1ID0gX2NvbnRleHQxNi5zZW50O1xuICAgICAgICAgICAgICAgIGNoYW5nZXMgPSBfcmVmNS5kYXRhO1xuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDE2LmFicnVwdChcInJldHVyblwiLCBjaGFuZ2VzKTtcblxuICAgICAgICAgICAgICBjYXNlIDk6XG4gICAgICAgICAgICAgIGNhc2UgXCJlbmRcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQxNi5zdG9wKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9LCBfY2FsbGVlMTYsIHRoaXMpO1xuICAgICAgfSkpO1xuXG4gICAgICByZXR1cm4gZnVuY3Rpb24gbGlzdENoYW5nZXNCYWNrVG8oX3gxMSkge1xuICAgICAgICByZXR1cm4gX2xpc3RDaGFuZ2VzQmFja1RvLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICB9O1xuICAgIH0oKVxuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG5cbiAgfSwge1xuICAgIGtleTogXCJnZXRTbmFwc2hvdFwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgX2dldFNuYXBzaG90ID0gKDAsIF9hc3luY1RvR2VuZXJhdG9yMi5kZWZhdWx0KShcbiAgICAgIC8qI19fUFVSRV9fKi9cbiAgICAgIF9yZWdlbmVyYXRvci5kZWZhdWx0Lm1hcmsoZnVuY3Rpb24gX2NhbGxlZTE3KGF0KSB7XG4gICAgICAgIHZhciBjaGFuZ2VzLCBzZWVuSWRzLCBzbmFwc2hvdCwgX2l0ZXJhdG9yTm9ybWFsQ29tcGxldGlvbiwgX2RpZEl0ZXJhdG9yRXJyb3IsIF9pdGVyYXRvckVycm9yLCBfbG9vcCwgX2l0ZXJhdG9yLCBfc3RlcDtcblxuICAgICAgICByZXR1cm4gX3JlZ2VuZXJhdG9yLmRlZmF1bHQud3JhcChmdW5jdGlvbiBfY2FsbGVlMTckKF9jb250ZXh0MTcpIHtcbiAgICAgICAgICB3aGlsZSAoMSkge1xuICAgICAgICAgICAgc3dpdGNoIChfY29udGV4dDE3LnByZXYgPSBfY29udGV4dDE3Lm5leHQpIHtcbiAgICAgICAgICAgICAgY2FzZSAwOlxuICAgICAgICAgICAgICAgIGlmICghKCFOdW1iZXIuaXNJbnRlZ2VyKGF0KSB8fCBhdCA8PSAwKSkge1xuICAgICAgICAgICAgICAgICAgX2NvbnRleHQxNy5uZXh0ID0gMjtcbiAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIkludmFsaWQgYXJndW1lbnQsIGV4cGVjdGVkIGEgcG9zaXRpdmUgaW50ZWdlci5cIik7XG5cbiAgICAgICAgICAgICAgY2FzZSAyOlxuICAgICAgICAgICAgICAgIF9jb250ZXh0MTcubmV4dCA9IDQ7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMubGlzdENoYW5nZXNCYWNrVG8oYXQpO1xuXG4gICAgICAgICAgICAgIGNhc2UgNDpcbiAgICAgICAgICAgICAgICBjaGFuZ2VzID0gX2NvbnRleHQxNy5zZW50O1xuICAgICAgICAgICAgICAgIC8vIFJlcGxheSBjaGFuZ2VzIHRvIGNvbXB1dGUgdGhlIHJlcXVlc3RlZCBzbmFwc2hvdC5cbiAgICAgICAgICAgICAgICBzZWVuSWRzID0gbmV3IFNldCgpO1xuICAgICAgICAgICAgICAgIHNuYXBzaG90ID0gW107XG4gICAgICAgICAgICAgICAgX2l0ZXJhdG9yTm9ybWFsQ29tcGxldGlvbiA9IHRydWU7XG4gICAgICAgICAgICAgICAgX2RpZEl0ZXJhdG9yRXJyb3IgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICBfaXRlcmF0b3JFcnJvciA9IHVuZGVmaW5lZDtcbiAgICAgICAgICAgICAgICBfY29udGV4dDE3LnByZXYgPSAxMDtcblxuICAgICAgICAgICAgICAgIF9sb29wID0gZnVuY3Rpb24gX2xvb3AoKSB7XG4gICAgICAgICAgICAgICAgICB2YXIgX3JlZjYgPSBfc3RlcC52YWx1ZTtcbiAgICAgICAgICAgICAgICAgIHZhciBhY3Rpb24gPSBfcmVmNi5hY3Rpb24sXG4gICAgICAgICAgICAgICAgICAgICAgcmVjb3JkID0gX3JlZjYudGFyZ2V0LmRhdGE7XG5cbiAgICAgICAgICAgICAgICAgIGlmIChhY3Rpb24gPT0gXCJkZWxldGVcIikge1xuICAgICAgICAgICAgICAgICAgICBzZWVuSWRzLmFkZChyZWNvcmQuaWQpOyAvLyBlbnN1cmUgbm90IHJlcHJvY2Vzc2luZyBkZWxldGVkIGVudHJpZXNcblxuICAgICAgICAgICAgICAgICAgICBzbmFwc2hvdCA9IHNuYXBzaG90LmZpbHRlcihmdW5jdGlvbiAocikge1xuICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByLmlkICE9PSByZWNvcmQuaWQ7XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmICghc2Vlbklkcy5oYXMocmVjb3JkLmlkKSkge1xuICAgICAgICAgICAgICAgICAgICBzZWVuSWRzLmFkZChyZWNvcmQuaWQpO1xuICAgICAgICAgICAgICAgICAgICBzbmFwc2hvdC5wdXNoKHJlY29yZCk7XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgICAgIGZvciAoX2l0ZXJhdG9yID0gY2hhbmdlc1tTeW1ib2wuaXRlcmF0b3JdKCk7ICEoX2l0ZXJhdG9yTm9ybWFsQ29tcGxldGlvbiA9IChfc3RlcCA9IF9pdGVyYXRvci5uZXh0KCkpLmRvbmUpOyBfaXRlcmF0b3JOb3JtYWxDb21wbGV0aW9uID0gdHJ1ZSkge1xuICAgICAgICAgICAgICAgICAgX2xvb3AoKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBfY29udGV4dDE3Lm5leHQgPSAxOTtcbiAgICAgICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgICAgICBjYXNlIDE1OlxuICAgICAgICAgICAgICAgIF9jb250ZXh0MTcucHJldiA9IDE1O1xuICAgICAgICAgICAgICAgIF9jb250ZXh0MTcudDAgPSBfY29udGV4dDE3W1wiY2F0Y2hcIl0oMTApO1xuICAgICAgICAgICAgICAgIF9kaWRJdGVyYXRvckVycm9yID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICBfaXRlcmF0b3JFcnJvciA9IF9jb250ZXh0MTcudDA7XG5cbiAgICAgICAgICAgICAgY2FzZSAxOTpcbiAgICAgICAgICAgICAgICBfY29udGV4dDE3LnByZXYgPSAxOTtcbiAgICAgICAgICAgICAgICBfY29udGV4dDE3LnByZXYgPSAyMDtcblxuICAgICAgICAgICAgICAgIGlmICghX2l0ZXJhdG9yTm9ybWFsQ29tcGxldGlvbiAmJiBfaXRlcmF0b3IucmV0dXJuICE9IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgIF9pdGVyYXRvci5yZXR1cm4oKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgY2FzZSAyMjpcbiAgICAgICAgICAgICAgICBfY29udGV4dDE3LnByZXYgPSAyMjtcblxuICAgICAgICAgICAgICAgIGlmICghX2RpZEl0ZXJhdG9yRXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgIF9jb250ZXh0MTcubmV4dCA9IDI1O1xuICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgdGhyb3cgX2l0ZXJhdG9yRXJyb3I7XG5cbiAgICAgICAgICAgICAgY2FzZSAyNTpcbiAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQxNy5maW5pc2goMjIpO1xuXG4gICAgICAgICAgICAgIGNhc2UgMjY6XG4gICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0MTcuZmluaXNoKDE5KTtcblxuICAgICAgICAgICAgICBjYXNlIDI3OlxuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDE3LmFicnVwdChcInJldHVyblwiLCB7XG4gICAgICAgICAgICAgICAgICBsYXN0X21vZGlmaWVkOiBTdHJpbmcoYXQpLFxuICAgICAgICAgICAgICAgICAgZGF0YTogc25hcHNob3Quc29ydChmdW5jdGlvbiAoYSwgYikge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYi5sYXN0X21vZGlmaWVkIC0gYS5sYXN0X21vZGlmaWVkO1xuICAgICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgICAgICBuZXh0OiBmdW5jdGlvbiBuZXh0KCkge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJTbmFwc2hvdHMgZG9uJ3Qgc3VwcG9ydCBwYWdpbmF0aW9uXCIpO1xuICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgIGhhc05leHRQYWdlOiBmYWxzZSxcbiAgICAgICAgICAgICAgICAgIHRvdGFsUmVjb3Jkczogc25hcHNob3QubGVuZ3RoXG4gICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgY2FzZSAyODpcbiAgICAgICAgICAgICAgY2FzZSBcImVuZFwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDE3LnN0b3AoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0sIF9jYWxsZWUxNywgdGhpcywgW1sxMCwgMTUsIDE5LCAyN10sIFsyMCwsIDIyLCAyNl1dKTtcbiAgICAgIH0pKTtcblxuICAgICAgcmV0dXJuIGZ1bmN0aW9uIGdldFNuYXBzaG90KF94MTIpIHtcbiAgICAgICAgcmV0dXJuIF9nZXRTbmFwc2hvdC5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgfTtcbiAgICB9KClcbiAgICAvKipcbiAgICAgKiBQZXJmb3JtcyBiYXRjaCBvcGVyYXRpb25zIGF0IHRoZSBjdXJyZW50IGNvbGxlY3Rpb24gbGV2ZWwuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gIHtGdW5jdGlvbn0gZm4gICAgICAgICAgICAgICAgICAgVGhlIGJhdGNoIG9wZXJhdGlvbiBmdW5jdGlvbi5cbiAgICAgKiBAcGFyYW0gIHtPYmplY3R9ICAgW29wdGlvbnM9e31dICAgICAgICAgVGhlIG9wdGlvbnMgb2JqZWN0LlxuICAgICAqIEBwYXJhbSAge09iamVjdH0gICBbb3B0aW9ucy5oZWFkZXJzXSAgICBUaGUgaGVhZGVycyBvYmplY3Qgb3B0aW9uLlxuICAgICAqIEBwYXJhbSAge0Jvb2xlYW59ICBbb3B0aW9ucy5zYWZlXSAgICAgICBUaGUgc2FmZSBvcHRpb24uXG4gICAgICogQHBhcmFtICB7TnVtYmVyfSAgIFtvcHRpb25zLnJldHJ5XSAgICAgIFRoZSByZXRyeSBvcHRpb24uXG4gICAgICogQHBhcmFtICB7Qm9vbGVhbn0gIFtvcHRpb25zLmFnZ3JlZ2F0ZV0gIFByb2R1Y2VzIGEgZ3JvdXBlZCByZXN1bHQgb2JqZWN0LlxuICAgICAqIEByZXR1cm4ge1Byb21pc2U8T2JqZWN0LCBFcnJvcj59XG4gICAgICovXG5cbiAgfSwge1xuICAgIGtleTogXCJiYXRjaFwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgX2JhdGNoID0gKDAsIF9hc3luY1RvR2VuZXJhdG9yMi5kZWZhdWx0KShcbiAgICAgIC8qI19fUFVSRV9fKi9cbiAgICAgIF9yZWdlbmVyYXRvci5kZWZhdWx0Lm1hcmsoZnVuY3Rpb24gX2NhbGxlZTE4KGZuKSB7XG4gICAgICAgIHZhciBvcHRpb25zLFxuICAgICAgICAgICAgX2FyZ3MxOCA9IGFyZ3VtZW50cztcbiAgICAgICAgcmV0dXJuIF9yZWdlbmVyYXRvci5kZWZhdWx0LndyYXAoZnVuY3Rpb24gX2NhbGxlZTE4JChfY29udGV4dDE4KSB7XG4gICAgICAgICAgd2hpbGUgKDEpIHtcbiAgICAgICAgICAgIHN3aXRjaCAoX2NvbnRleHQxOC5wcmV2ID0gX2NvbnRleHQxOC5uZXh0KSB7XG4gICAgICAgICAgICAgIGNhc2UgMDpcbiAgICAgICAgICAgICAgICBvcHRpb25zID0gX2FyZ3MxOC5sZW5ndGggPiAxICYmIF9hcmdzMThbMV0gIT09IHVuZGVmaW5lZCA/IF9hcmdzMThbMV0gOiB7fTtcbiAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQxOC5hYnJ1cHQoXCJyZXR1cm5cIiwgdGhpcy5jbGllbnQuYmF0Y2goZm4sIHtcbiAgICAgICAgICAgICAgICAgIGJ1Y2tldDogdGhpcy5idWNrZXQubmFtZSxcbiAgICAgICAgICAgICAgICAgIGNvbGxlY3Rpb246IHRoaXMubmFtZSxcbiAgICAgICAgICAgICAgICAgIGhlYWRlcnM6IHRoaXMuX2dldEhlYWRlcnMob3B0aW9ucyksXG4gICAgICAgICAgICAgICAgICByZXRyeTogdGhpcy5fZ2V0UmV0cnkob3B0aW9ucyksXG4gICAgICAgICAgICAgICAgICBzYWZlOiB0aGlzLl9nZXRTYWZlKG9wdGlvbnMpLFxuICAgICAgICAgICAgICAgICAgYWdncmVnYXRlOiAhIW9wdGlvbnMuYWdncmVnYXRlXG4gICAgICAgICAgICAgICAgfSkpO1xuXG4gICAgICAgICAgICAgIGNhc2UgMjpcbiAgICAgICAgICAgICAgY2FzZSBcImVuZFwiOlxuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dDE4LnN0b3AoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0sIF9jYWxsZWUxOCwgdGhpcyk7XG4gICAgICB9KSk7XG5cbiAgICAgIHJldHVybiBmdW5jdGlvbiBiYXRjaChfeDEzKSB7XG4gICAgICAgIHJldHVybiBfYmF0Y2guYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgIH07XG4gICAgfSgpXG4gIH1dKTtcbiAgcmV0dXJuIENvbGxlY3Rpb247XG59KCksICgoMCwgX2FwcGx5RGVjb3JhdGVkRGVzY3JpcHRvcjIuZGVmYXVsdCkoX2NsYXNzLnByb3RvdHlwZSwgXCJhZGRBdHRhY2htZW50XCIsIFtfZGVjXSwgT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihfY2xhc3MucHJvdG90eXBlLCBcImFkZEF0dGFjaG1lbnRcIiksIF9jbGFzcy5wcm90b3R5cGUpLCAoMCwgX2FwcGx5RGVjb3JhdGVkRGVzY3JpcHRvcjIuZGVmYXVsdCkoX2NsYXNzLnByb3RvdHlwZSwgXCJyZW1vdmVBdHRhY2htZW50XCIsIFtfZGVjMl0sIE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IoX2NsYXNzLnByb3RvdHlwZSwgXCJyZW1vdmVBdHRhY2htZW50XCIpLCBfY2xhc3MucHJvdG90eXBlKSwgKDAsIF9hcHBseURlY29yYXRlZERlc2NyaXB0b3IyLmRlZmF1bHQpKF9jbGFzcy5wcm90b3R5cGUsIFwiZ2V0U25hcHNob3RcIiwgW19kZWMzXSwgT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihfY2xhc3MucHJvdG90eXBlLCBcImdldFNuYXBzaG90XCIpLCBfY2xhc3MucHJvdG90eXBlKSksIF9jbGFzcykpO1xuZXhwb3J0cy5kZWZhdWx0ID0gQ29sbGVjdGlvbjsiLCJcInVzZSBzdHJpY3RcIjtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG4gIHZhbHVlOiB0cnVlXG59KTtcbmV4cG9ydHMuZGVmYXVsdCA9IGVuZHBvaW50O1xuXG4vKipcbiAqIEVuZHBvaW50cyB0ZW1wbGF0ZXMuXG4gKiBAdHlwZSB7T2JqZWN0fVxuICovXG52YXIgRU5EUE9JTlRTID0ge1xuICByb290OiBmdW5jdGlvbiByb290KCkge1xuICAgIHJldHVybiBcIi9cIjtcbiAgfSxcbiAgYmF0Y2g6IGZ1bmN0aW9uIGJhdGNoKCkge1xuICAgIHJldHVybiBcIi9iYXRjaFwiO1xuICB9LFxuICBwZXJtaXNzaW9uczogZnVuY3Rpb24gcGVybWlzc2lvbnMoKSB7XG4gICAgcmV0dXJuIFwiL3Blcm1pc3Npb25zXCI7XG4gIH0sXG4gIGJ1Y2tldDogZnVuY3Rpb24gYnVja2V0KF9idWNrZXQpIHtcbiAgICByZXR1cm4gXCIvYnVja2V0c1wiICsgKF9idWNrZXQgPyBcIi9cIi5jb25jYXQoX2J1Y2tldCkgOiBcIlwiKTtcbiAgfSxcbiAgaGlzdG9yeTogZnVuY3Rpb24gaGlzdG9yeShidWNrZXQpIHtcbiAgICByZXR1cm4gXCJcIi5jb25jYXQoRU5EUE9JTlRTLmJ1Y2tldChidWNrZXQpLCBcIi9oaXN0b3J5XCIpO1xuICB9LFxuICBjb2xsZWN0aW9uOiBmdW5jdGlvbiBjb2xsZWN0aW9uKGJ1Y2tldCwgY29sbCkge1xuICAgIHJldHVybiBcIlwiLmNvbmNhdChFTkRQT0lOVFMuYnVja2V0KGJ1Y2tldCksIFwiL2NvbGxlY3Rpb25zXCIpICsgKGNvbGwgPyBcIi9cIi5jb25jYXQoY29sbCkgOiBcIlwiKTtcbiAgfSxcbiAgZ3JvdXA6IGZ1bmN0aW9uIGdyb3VwKGJ1Y2tldCwgX2dyb3VwKSB7XG4gICAgcmV0dXJuIFwiXCIuY29uY2F0KEVORFBPSU5UUy5idWNrZXQoYnVja2V0KSwgXCIvZ3JvdXBzXCIpICsgKF9ncm91cCA/IFwiL1wiLmNvbmNhdChfZ3JvdXApIDogXCJcIik7XG4gIH0sXG4gIHJlY29yZDogZnVuY3Rpb24gcmVjb3JkKGJ1Y2tldCwgY29sbCwgaWQpIHtcbiAgICByZXR1cm4gXCJcIi5jb25jYXQoRU5EUE9JTlRTLmNvbGxlY3Rpb24oYnVja2V0LCBjb2xsKSwgXCIvcmVjb3Jkc1wiKSArIChpZCA/IFwiL1wiLmNvbmNhdChpZCkgOiBcIlwiKTtcbiAgfSxcbiAgYXR0YWNobWVudDogZnVuY3Rpb24gYXR0YWNobWVudChidWNrZXQsIGNvbGwsIGlkKSB7XG4gICAgcmV0dXJuIFwiXCIuY29uY2F0KEVORFBPSU5UUy5yZWNvcmQoYnVja2V0LCBjb2xsLCBpZCksIFwiL2F0dGFjaG1lbnRcIik7XG4gIH1cbn07XG4vKipcbiAqIFJldHJpZXZlcyBhIHNlcnZlciBlbnBvaW50IGJ5IGl0cyBuYW1lLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0gIHtTdHJpbmd9ICAgIG5hbWUgVGhlIGVuZHBvaW50IG5hbWUuXG4gKiBAcGFyYW0gIHsuLi5zdHJpbmd9IGFyZ3MgVGhlIGVuZHBvaW50IHBhcmFtZXRlcnMuXG4gKiBAcmV0dXJuIHtTdHJpbmd9XG4gKi9cblxuZnVuY3Rpb24gZW5kcG9pbnQobmFtZSkge1xuICBmb3IgKHZhciBfbGVuID0gYXJndW1lbnRzLmxlbmd0aCwgYXJncyA9IG5ldyBBcnJheShfbGVuID4gMSA/IF9sZW4gLSAxIDogMCksIF9rZXkgPSAxOyBfa2V5IDwgX2xlbjsgX2tleSsrKSB7XG4gICAgYXJnc1tfa2V5IC0gMV0gPSBhcmd1bWVudHNbX2tleV07XG4gIH1cblxuICByZXR1cm4gRU5EUE9JTlRTW25hbWVdLmFwcGx5KEVORFBPSU5UUywgYXJncyk7XG59IiwiXCJ1c2Ugc3RyaWN0XCI7XG5cbnZhciBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0ID0gcmVxdWlyZShcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvaW50ZXJvcFJlcXVpcmVEZWZhdWx0XCIpO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHtcbiAgdmFsdWU6IHRydWVcbn0pO1xuZXhwb3J0cy5VbnBhcnNlYWJsZVJlc3BvbnNlRXJyb3IgPSBleHBvcnRzLlNlcnZlclJlc3BvbnNlID0gZXhwb3J0cy5OZXR3b3JrVGltZW91dEVycm9yID0gZXhwb3J0cy5kZWZhdWx0ID0gdm9pZCAwO1xuXG52YXIgX2NsYXNzQ2FsbENoZWNrMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQocmVxdWlyZShcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvY2xhc3NDYWxsQ2hlY2tcIikpO1xuXG52YXIgX3Bvc3NpYmxlQ29uc3RydWN0b3JSZXR1cm4yID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChyZXF1aXJlKFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9wb3NzaWJsZUNvbnN0cnVjdG9yUmV0dXJuXCIpKTtcblxudmFyIF9nZXRQcm90b3R5cGVPZjIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KHJlcXVpcmUoXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2dldFByb3RvdHlwZU9mXCIpKTtcblxudmFyIF9pbmhlcml0czIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KHJlcXVpcmUoXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2luaGVyaXRzXCIpKTtcblxudmFyIF9hc3NlcnRUaGlzSW5pdGlhbGl6ZWQyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChyZXF1aXJlKFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9hc3NlcnRUaGlzSW5pdGlhbGl6ZWRcIikpO1xuXG5mdW5jdGlvbiBfZXh0ZW5kYWJsZUJ1aWx0aW41KGNscykge1xuICBmdW5jdGlvbiBFeHRlbmRhYmxlQnVpbHRpbigpIHtcbiAgICB2YXIgaW5zdGFuY2UgPSBSZWZsZWN0LmNvbnN0cnVjdChjbHMsIEFycmF5LmZyb20oYXJndW1lbnRzKSk7XG4gICAgT2JqZWN0LnNldFByb3RvdHlwZU9mKGluc3RhbmNlLCBPYmplY3QuZ2V0UHJvdG90eXBlT2YodGhpcykpO1xuICAgIHJldHVybiBpbnN0YW5jZTtcbiAgfVxuXG4gIEV4dGVuZGFibGVCdWlsdGluLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoY2xzLnByb3RvdHlwZSwge1xuICAgIGNvbnN0cnVjdG9yOiB7XG4gICAgICB2YWx1ZTogY2xzLFxuICAgICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgICB3cml0YWJsZTogdHJ1ZSxcbiAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZVxuICAgIH1cbiAgfSk7XG5cbiAgaWYgKE9iamVjdC5zZXRQcm90b3R5cGVPZikge1xuICAgIE9iamVjdC5zZXRQcm90b3R5cGVPZihFeHRlbmRhYmxlQnVpbHRpbiwgY2xzKTtcbiAgfSBlbHNlIHtcbiAgICBFeHRlbmRhYmxlQnVpbHRpbi5fX3Byb3RvX18gPSBjbHM7XG4gIH1cblxuICByZXR1cm4gRXh0ZW5kYWJsZUJ1aWx0aW47XG59XG5cbmZ1bmN0aW9uIF9leHRlbmRhYmxlQnVpbHRpbjMoY2xzKSB7XG4gIGZ1bmN0aW9uIEV4dGVuZGFibGVCdWlsdGluKCkge1xuICAgIHZhciBpbnN0YW5jZSA9IFJlZmxlY3QuY29uc3RydWN0KGNscywgQXJyYXkuZnJvbShhcmd1bWVudHMpKTtcbiAgICBPYmplY3Quc2V0UHJvdG90eXBlT2YoaW5zdGFuY2UsIE9iamVjdC5nZXRQcm90b3R5cGVPZih0aGlzKSk7XG4gICAgcmV0dXJuIGluc3RhbmNlO1xuICB9XG5cbiAgRXh0ZW5kYWJsZUJ1aWx0aW4ucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShjbHMucHJvdG90eXBlLCB7XG4gICAgY29uc3RydWN0b3I6IHtcbiAgICAgIHZhbHVlOiBjbHMsXG4gICAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICAgIHdyaXRhYmxlOiB0cnVlLFxuICAgICAgY29uZmlndXJhYmxlOiB0cnVlXG4gICAgfVxuICB9KTtcblxuICBpZiAoT2JqZWN0LnNldFByb3RvdHlwZU9mKSB7XG4gICAgT2JqZWN0LnNldFByb3RvdHlwZU9mKEV4dGVuZGFibGVCdWlsdGluLCBjbHMpO1xuICB9IGVsc2Uge1xuICAgIEV4dGVuZGFibGVCdWlsdGluLl9fcHJvdG9fXyA9IGNscztcbiAgfVxuXG4gIHJldHVybiBFeHRlbmRhYmxlQnVpbHRpbjtcbn1cblxuZnVuY3Rpb24gX2V4dGVuZGFibGVCdWlsdGluKGNscykge1xuICBmdW5jdGlvbiBFeHRlbmRhYmxlQnVpbHRpbigpIHtcbiAgICB2YXIgaW5zdGFuY2UgPSBSZWZsZWN0LmNvbnN0cnVjdChjbHMsIEFycmF5LmZyb20oYXJndW1lbnRzKSk7XG4gICAgT2JqZWN0LnNldFByb3RvdHlwZU9mKGluc3RhbmNlLCBPYmplY3QuZ2V0UHJvdG90eXBlT2YodGhpcykpO1xuICAgIHJldHVybiBpbnN0YW5jZTtcbiAgfVxuXG4gIEV4dGVuZGFibGVCdWlsdGluLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoY2xzLnByb3RvdHlwZSwge1xuICAgIGNvbnN0cnVjdG9yOiB7XG4gICAgICB2YWx1ZTogY2xzLFxuICAgICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgICB3cml0YWJsZTogdHJ1ZSxcbiAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZVxuICAgIH1cbiAgfSk7XG5cbiAgaWYgKE9iamVjdC5zZXRQcm90b3R5cGVPZikge1xuICAgIE9iamVjdC5zZXRQcm90b3R5cGVPZihFeHRlbmRhYmxlQnVpbHRpbiwgY2xzKTtcbiAgfSBlbHNlIHtcbiAgICBFeHRlbmRhYmxlQnVpbHRpbi5fX3Byb3RvX18gPSBjbHM7XG4gIH1cblxuICByZXR1cm4gRXh0ZW5kYWJsZUJ1aWx0aW47XG59XG5cbi8qKlxuICogS2ludG8gc2VydmVyIGVycm9yIGNvZGUgZGVzY3JpcHRvcnMuXG4gKiBAdHlwZSB7T2JqZWN0fVxuICovXG52YXIgRVJST1JfQ09ERVMgPSB7XG4gIDEwNDogXCJNaXNzaW5nIEF1dGhvcml6YXRpb24gVG9rZW5cIixcbiAgMTA1OiBcIkludmFsaWQgQXV0aG9yaXphdGlvbiBUb2tlblwiLFxuICAxMDY6IFwiUmVxdWVzdCBib2R5IHdhcyBub3QgdmFsaWQgSlNPTlwiLFxuICAxMDc6IFwiSW52YWxpZCByZXF1ZXN0IHBhcmFtZXRlclwiLFxuICAxMDg6IFwiTWlzc2luZyByZXF1ZXN0IHBhcmFtZXRlclwiLFxuICAxMDk6IFwiSW52YWxpZCBwb3N0ZWQgZGF0YVwiLFxuICAxMTA6IFwiSW52YWxpZCBUb2tlbiAvIGlkXCIsXG4gIDExMTogXCJNaXNzaW5nIFRva2VuIC8gaWRcIixcbiAgMTEyOiBcIkNvbnRlbnQtTGVuZ3RoIGhlYWRlciB3YXMgbm90IHByb3ZpZGVkXCIsXG4gIDExMzogXCJSZXF1ZXN0IGJvZHkgdG9vIGxhcmdlXCIsXG4gIDExNDogXCJSZXNvdXJjZSB3YXMgY3JlYXRlZCwgdXBkYXRlZCBvciBkZWxldGVkIG1lYW53aGlsZVwiLFxuICAxMTU6IFwiTWV0aG9kIG5vdCBhbGxvd2VkIG9uIHRoaXMgZW5kIHBvaW50IChoaW50OiBzZXJ2ZXIgbWF5IGJlIHJlYWRvbmx5KVwiLFxuICAxMTY6IFwiUmVxdWVzdGVkIHZlcnNpb24gbm90IGF2YWlsYWJsZSBvbiB0aGlzIHNlcnZlclwiLFxuICAxMTc6IFwiQ2xpZW50IGhhcyBzZW50IHRvbyBtYW55IHJlcXVlc3RzXCIsXG4gIDEyMTogXCJSZXNvdXJjZSBhY2Nlc3MgaXMgZm9yYmlkZGVuIGZvciB0aGlzIHVzZXJcIixcbiAgMTIyOiBcIkFub3RoZXIgcmVzb3VyY2UgdmlvbGF0ZXMgY29uc3RyYWludFwiLFxuICAyMDE6IFwiU2VydmljZSBUZW1wb3JhcnkgdW5hdmFpbGFibGUgZHVlIHRvIGhpZ2ggbG9hZFwiLFxuICAyMDI6IFwiU2VydmljZSBkZXByZWNhdGVkXCIsXG4gIDk5OTogXCJJbnRlcm5hbCBTZXJ2ZXIgRXJyb3JcIlxufTtcbnZhciBfZGVmYXVsdCA9IEVSUk9SX0NPREVTO1xuZXhwb3J0cy5kZWZhdWx0ID0gX2RlZmF1bHQ7XG5cbnZhciBOZXR3b3JrVGltZW91dEVycm9yID1cbi8qI19fUFVSRV9fKi9cbmZ1bmN0aW9uIChfZXh0ZW5kYWJsZUJ1aWx0aW4yKSB7XG4gICgwLCBfaW5oZXJpdHMyLmRlZmF1bHQpKE5ldHdvcmtUaW1lb3V0RXJyb3IsIF9leHRlbmRhYmxlQnVpbHRpbjIpO1xuXG4gIGZ1bmN0aW9uIE5ldHdvcmtUaW1lb3V0RXJyb3IodXJsLCBvcHRpb25zKSB7XG4gICAgdmFyIF90aGlzO1xuXG4gICAgKDAsIF9jbGFzc0NhbGxDaGVjazIuZGVmYXVsdCkodGhpcywgTmV0d29ya1RpbWVvdXRFcnJvcik7XG4gICAgX3RoaXMgPSAoMCwgX3Bvc3NpYmxlQ29uc3RydWN0b3JSZXR1cm4yLmRlZmF1bHQpKHRoaXMsICgwLCBfZ2V0UHJvdG90eXBlT2YyLmRlZmF1bHQpKE5ldHdvcmtUaW1lb3V0RXJyb3IpLmNhbGwodGhpcywgXCJUaW1lb3V0IHdoaWxlIHRyeWluZyB0byBhY2Nlc3MgXCIuY29uY2F0KHVybCwgXCIgd2l0aCBcIikuY29uY2F0KEpTT04uc3RyaW5naWZ5KG9wdGlvbnMpKSkpO1xuXG4gICAgaWYgKEVycm9yLmNhcHR1cmVTdGFja1RyYWNlKSB7XG4gICAgICBFcnJvci5jYXB0dXJlU3RhY2tUcmFjZSgoMCwgX2Fzc2VydFRoaXNJbml0aWFsaXplZDIuZGVmYXVsdCkoKDAsIF9hc3NlcnRUaGlzSW5pdGlhbGl6ZWQyLmRlZmF1bHQpKF90aGlzKSksIE5ldHdvcmtUaW1lb3V0RXJyb3IpO1xuICAgIH1cblxuICAgIF90aGlzLnVybCA9IHVybDtcbiAgICBfdGhpcy5vcHRpb25zID0gb3B0aW9ucztcbiAgICByZXR1cm4gX3RoaXM7XG4gIH1cblxuICByZXR1cm4gTmV0d29ya1RpbWVvdXRFcnJvcjtcbn0oX2V4dGVuZGFibGVCdWlsdGluKEVycm9yKSk7XG5cbmV4cG9ydHMuTmV0d29ya1RpbWVvdXRFcnJvciA9IE5ldHdvcmtUaW1lb3V0RXJyb3I7XG5cbnZhciBVbnBhcnNlYWJsZVJlc3BvbnNlRXJyb3IgPVxuLyojX19QVVJFX18qL1xuZnVuY3Rpb24gKF9leHRlbmRhYmxlQnVpbHRpbjQpIHtcbiAgKDAsIF9pbmhlcml0czIuZGVmYXVsdCkoVW5wYXJzZWFibGVSZXNwb25zZUVycm9yLCBfZXh0ZW5kYWJsZUJ1aWx0aW40KTtcblxuICBmdW5jdGlvbiBVbnBhcnNlYWJsZVJlc3BvbnNlRXJyb3IocmVzcG9uc2UsIGJvZHksIGVycm9yKSB7XG4gICAgdmFyIF90aGlzMjtcblxuICAgICgwLCBfY2xhc3NDYWxsQ2hlY2syLmRlZmF1bHQpKHRoaXMsIFVucGFyc2VhYmxlUmVzcG9uc2VFcnJvcik7XG4gICAgdmFyIHN0YXR1cyA9IHJlc3BvbnNlLnN0YXR1cztcbiAgICBfdGhpczIgPSAoMCwgX3Bvc3NpYmxlQ29uc3RydWN0b3JSZXR1cm4yLmRlZmF1bHQpKHRoaXMsICgwLCBfZ2V0UHJvdG90eXBlT2YyLmRlZmF1bHQpKFVucGFyc2VhYmxlUmVzcG9uc2VFcnJvcikuY2FsbCh0aGlzLCBcIlJlc3BvbnNlIGZyb20gc2VydmVyIHVucGFyc2VhYmxlIChIVFRQIFwiLmNvbmNhdChzdGF0dXMgfHwgMCwgXCI7IFwiKS5jb25jYXQoZXJyb3IsIFwiKTogXCIpLmNvbmNhdChib2R5KSkpO1xuXG4gICAgaWYgKEVycm9yLmNhcHR1cmVTdGFja1RyYWNlKSB7XG4gICAgICBFcnJvci5jYXB0dXJlU3RhY2tUcmFjZSgoMCwgX2Fzc2VydFRoaXNJbml0aWFsaXplZDIuZGVmYXVsdCkoKDAsIF9hc3NlcnRUaGlzSW5pdGlhbGl6ZWQyLmRlZmF1bHQpKF90aGlzMikpLCBVbnBhcnNlYWJsZVJlc3BvbnNlRXJyb3IpO1xuICAgIH1cblxuICAgIF90aGlzMi5zdGF0dXMgPSBzdGF0dXM7XG4gICAgX3RoaXMyLnJlc3BvbnNlID0gcmVzcG9uc2U7XG4gICAgX3RoaXMyLnN0YWNrID0gZXJyb3Iuc3RhY2s7XG4gICAgX3RoaXMyLmVycm9yID0gZXJyb3I7XG4gICAgcmV0dXJuIF90aGlzMjtcbiAgfVxuXG4gIHJldHVybiBVbnBhcnNlYWJsZVJlc3BvbnNlRXJyb3I7XG59KF9leHRlbmRhYmxlQnVpbHRpbjMoRXJyb3IpKTtcbi8qKlxuICogXCJFcnJvclwiIHN1YmNsYXNzIHJlcHJlc2VudGluZyBhID49NDAwIHJlc3BvbnNlIGZyb20gdGhlIHNlcnZlci5cbiAqXG4gKiBXaGV0aGVyIG9yIG5vdCB0aGlzIGlzIGFuIGVycm9yIGRlcGVuZHMgb24geW91ciBhcHBsaWNhdGlvbi5cbiAqXG4gKiBUaGUgYGpzb25gIGZpZWxkIGNhbiBiZSB1bmRlZmluZWQgaWYgdGhlIHNlcnZlciByZXNwb25kZWQgd2l0aCBhblxuICogZW1wdHkgcmVzcG9uc2UgYm9keS4gVGhpcyBzaG91bGRuJ3QgZ2VuZXJhbGx5IGhhcHBlbi4gTW9zdCBcImJhZFwiXG4gKiByZXNwb25zZXMgY29tZSB3aXRoIGEgSlNPTiBlcnJvciBkZXNjcmlwdGlvbiwgb3IgKGlmIHRoZXkncmVcbiAqIGZyb250ZWQgYnkgYSBDRE4gb3Igbmdpbnggb3Igc29tZXRoaW5nKSBvY2Nhc2lvbmFsbHkgbm9uLUpTT05cbiAqIHJlc3BvbnNlcyAod2hpY2ggYmVjb21lIFVucGFyc2VhYmxlUmVzcG9uc2VFcnJvcnMsIGFib3ZlKS5cbiAqL1xuXG5cbmV4cG9ydHMuVW5wYXJzZWFibGVSZXNwb25zZUVycm9yID0gVW5wYXJzZWFibGVSZXNwb25zZUVycm9yO1xuXG52YXIgU2VydmVyUmVzcG9uc2UgPVxuLyojX19QVVJFX18qL1xuZnVuY3Rpb24gKF9leHRlbmRhYmxlQnVpbHRpbjYpIHtcbiAgKDAsIF9pbmhlcml0czIuZGVmYXVsdCkoU2VydmVyUmVzcG9uc2UsIF9leHRlbmRhYmxlQnVpbHRpbjYpO1xuXG4gIGZ1bmN0aW9uIFNlcnZlclJlc3BvbnNlKHJlc3BvbnNlLCBqc29uKSB7XG4gICAgdmFyIF90aGlzMztcblxuICAgICgwLCBfY2xhc3NDYWxsQ2hlY2syLmRlZmF1bHQpKHRoaXMsIFNlcnZlclJlc3BvbnNlKTtcbiAgICB2YXIgc3RhdHVzID0gcmVzcG9uc2Uuc3RhdHVzO1xuICAgIHZhciBzdGF0dXNUZXh0ID0gcmVzcG9uc2Uuc3RhdHVzVGV4dDtcbiAgICB2YXIgZXJybm9Nc2c7XG5cbiAgICBpZiAoanNvbikge1xuICAgICAgLy8gVHJ5IHRvIGZpbGwgaW4gaW5mb3JtYXRpb24gZnJvbSB0aGUgSlNPTiBlcnJvci5cbiAgICAgIHN0YXR1c1RleHQgPSBqc29uLmVycm9yIHx8IHN0YXR1c1RleHQ7IC8vIFRha2UgZXJybm9Nc2cgZnJvbSBlaXRoZXIgRVJST1JfQ09ERVMgb3IganNvbi5tZXNzYWdlLlxuXG4gICAgICBpZiAoanNvbi5lcnJubyAmJiBqc29uLmVycm5vIGluIEVSUk9SX0NPREVTKSB7XG4gICAgICAgIGVycm5vTXNnID0gRVJST1JfQ09ERVNbanNvbi5lcnJub107XG4gICAgICB9IGVsc2UgaWYgKGpzb24ubWVzc2FnZSkge1xuICAgICAgICBlcnJub01zZyA9IGpzb24ubWVzc2FnZTtcbiAgICAgIH0gLy8gSWYgd2UgaGFkIGJvdGggRVJST1JfQ09ERVMgYW5kIGpzb24ubWVzc2FnZSwgYW5kIHRoZXkgZGlmZmVyLFxuICAgICAgLy8gY29tYmluZSB0aGVtLlxuXG5cbiAgICAgIGlmIChlcnJub01zZyAmJiBqc29uLm1lc3NhZ2UgJiYganNvbi5tZXNzYWdlICE9PSBlcnJub01zZykge1xuICAgICAgICBlcnJub01zZyArPSBcIiAoXCIuY29uY2F0KGpzb24ubWVzc2FnZSwgXCIpXCIpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHZhciBtZXNzYWdlID0gXCJIVFRQIFwiLmNvbmNhdChzdGF0dXMsIFwiIFwiKS5jb25jYXQoc3RhdHVzVGV4dCk7XG5cbiAgICBpZiAoZXJybm9Nc2cpIHtcbiAgICAgIG1lc3NhZ2UgKz0gXCI6IFwiLmNvbmNhdChlcnJub01zZyk7XG4gICAgfVxuXG4gICAgX3RoaXMzID0gKDAsIF9wb3NzaWJsZUNvbnN0cnVjdG9yUmV0dXJuMi5kZWZhdWx0KSh0aGlzLCAoMCwgX2dldFByb3RvdHlwZU9mMi5kZWZhdWx0KShTZXJ2ZXJSZXNwb25zZSkuY2FsbCh0aGlzLCBtZXNzYWdlLnRyaW0oKSkpO1xuXG4gICAgaWYgKEVycm9yLmNhcHR1cmVTdGFja1RyYWNlKSB7XG4gICAgICBFcnJvci5jYXB0dXJlU3RhY2tUcmFjZSgoMCwgX2Fzc2VydFRoaXNJbml0aWFsaXplZDIuZGVmYXVsdCkoKDAsIF9hc3NlcnRUaGlzSW5pdGlhbGl6ZWQyLmRlZmF1bHQpKF90aGlzMykpLCBTZXJ2ZXJSZXNwb25zZSk7XG4gICAgfVxuXG4gICAgX3RoaXMzLnJlc3BvbnNlID0gcmVzcG9uc2U7XG4gICAgX3RoaXMzLmRhdGEgPSBqc29uO1xuICAgIHJldHVybiBfdGhpczM7XG4gIH1cblxuICByZXR1cm4gU2VydmVyUmVzcG9uc2U7XG59KF9leHRlbmRhYmxlQnVpbHRpbjUoRXJyb3IpKTtcblxuZXhwb3J0cy5TZXJ2ZXJSZXNwb25zZSA9IFNlcnZlclJlc3BvbnNlOyIsIlwidXNlIHN0cmljdFwiO1xuXG52YXIgX2ludGVyb3BSZXF1aXJlRGVmYXVsdCA9IHJlcXVpcmUoXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2ludGVyb3BSZXF1aXJlRGVmYXVsdFwiKTtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG4gIHZhbHVlOiB0cnVlXG59KTtcbmV4cG9ydHMuZGVmYXVsdCA9IHZvaWQgMDtcblxudmFyIF9vYmplY3RTcHJlYWQyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChyZXF1aXJlKFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9vYmplY3RTcHJlYWRcIikpO1xuXG52YXIgX3JlZ2VuZXJhdG9yID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChyZXF1aXJlKFwiQGJhYmVsL3J1bnRpbWUvcmVnZW5lcmF0b3JcIikpO1xuXG52YXIgX2FzeW5jVG9HZW5lcmF0b3IyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChyZXF1aXJlKFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9hc3luY1RvR2VuZXJhdG9yXCIpKTtcblxudmFyIF9jbGFzc0NhbGxDaGVjazIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KHJlcXVpcmUoXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2NsYXNzQ2FsbENoZWNrXCIpKTtcblxudmFyIF9jcmVhdGVDbGFzczIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KHJlcXVpcmUoXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2NyZWF0ZUNsYXNzXCIpKTtcblxudmFyIF91dGlscyA9IHJlcXVpcmUoXCIuL3V0aWxzXCIpO1xuXG52YXIgX2Vycm9ycyA9IHJlcXVpcmUoXCIuL2Vycm9yc1wiKTtcblxuLyoqXG4gKiBFbmhhbmNlZCBIVFRQIGNsaWVudCBmb3IgdGhlIEtpbnRvIHByb3RvY29sLlxuICogQHByaXZhdGVcbiAqL1xudmFyIEhUVFAgPVxuLyojX19QVVJFX18qL1xuZnVuY3Rpb24gKCkge1xuICAoMCwgX2NyZWF0ZUNsYXNzMi5kZWZhdWx0KShIVFRQLCBudWxsLCBbe1xuICAgIGtleTogXCJERUZBVUxUX1JFUVVFU1RfSEVBREVSU1wiLFxuXG4gICAgLyoqXG4gICAgICogRGVmYXVsdCBIVFRQIHJlcXVlc3QgaGVhZGVycyBhcHBsaWVkIHRvIGVhY2ggb3V0Z29pbmcgcmVxdWVzdC5cbiAgICAgKlxuICAgICAqIEB0eXBlIHtPYmplY3R9XG4gICAgICovXG4gICAgZ2V0OiBmdW5jdGlvbiBnZXQoKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBBY2NlcHQ6IFwiYXBwbGljYXRpb24vanNvblwiLFxuICAgICAgICBcIkNvbnRlbnQtVHlwZVwiOiBcImFwcGxpY2F0aW9uL2pzb25cIlxuICAgICAgfTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogRGVmYXVsdCBvcHRpb25zLlxuICAgICAqXG4gICAgICogQHR5cGUge09iamVjdH1cbiAgICAgKi9cblxuICB9LCB7XG4gICAga2V5OiBcImRlZmF1bHRPcHRpb25zXCIsXG4gICAgZ2V0OiBmdW5jdGlvbiBnZXQoKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICB0aW1lb3V0OiBudWxsLFxuICAgICAgICByZXF1ZXN0TW9kZTogXCJjb3JzXCJcbiAgICAgIH07XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENvbnN0cnVjdG9yLlxuICAgICAqXG4gICAgICogQHBhcmFtIHtFdmVudEVtaXR0ZXJ9IGV2ZW50cyAgICAgICAgICAgICAgICAgICAgICAgVGhlIGV2ZW50IGhhbmRsZXIuXG4gICAgICogQHBhcmFtIHtPYmplY3R9ICAgICAgIFtvcHRpb25zPXt9fSAgICAgICAgICAgICAgICAgVGhlIG9wdGlvbnMgb2JqZWN0LlxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSAgICAgICBbb3B0aW9ucy50aW1lb3V0PW51bGxdICAgICAgIFRoZSByZXF1ZXN0IHRpbWVvdXQgaW4gbXMsIGlmIGFueSAoZGVmYXVsdDogYG51bGxgKS5cbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gICAgICAgW29wdGlvbnMucmVxdWVzdE1vZGU9XCJjb3JzXCJdIFRoZSBIVFRQIHJlcXVlc3QgbW9kZSAoZGVmYXVsdDogYFwiY29yc1wiYCkuXG4gICAgICovXG5cbiAgfV0pO1xuXG4gIGZ1bmN0aW9uIEhUVFAoZXZlbnRzKSB7XG4gICAgdmFyIG9wdGlvbnMgPSBhcmd1bWVudHMubGVuZ3RoID4gMSAmJiBhcmd1bWVudHNbMV0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1sxXSA6IHt9O1xuICAgICgwLCBfY2xhc3NDYWxsQ2hlY2syLmRlZmF1bHQpKHRoaXMsIEhUVFApO1xuXG4gICAgLy8gcHVibGljIHByb3BlcnRpZXNcblxuICAgIC8qKlxuICAgICAqIFRoZSBldmVudCBlbWl0dGVyIGluc3RhbmNlLlxuICAgICAqIEB0eXBlIHtFdmVudEVtaXR0ZXJ9XG4gICAgICovXG4gICAgaWYgKCFldmVudHMpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIk5vIGV2ZW50cyBoYW5kbGVyIHByb3ZpZGVkXCIpO1xuICAgIH1cblxuICAgIHRoaXMuZXZlbnRzID0gZXZlbnRzO1xuICAgIC8qKlxuICAgICAqIFRoZSByZXF1ZXN0IG1vZGUuXG4gICAgICogQHNlZSAgaHR0cHM6Ly9mZXRjaC5zcGVjLndoYXR3Zy5vcmcvI3JlcXVlc3Rtb2RlXG4gICAgICogQHR5cGUge1N0cmluZ31cbiAgICAgKi9cblxuICAgIHRoaXMucmVxdWVzdE1vZGUgPSBvcHRpb25zLnJlcXVlc3RNb2RlIHx8IEhUVFAuZGVmYXVsdE9wdGlvbnMucmVxdWVzdE1vZGU7XG4gICAgLyoqXG4gICAgICogVGhlIHJlcXVlc3QgdGltZW91dC5cbiAgICAgKiBAdHlwZSB7TnVtYmVyfVxuICAgICAqL1xuXG4gICAgdGhpcy50aW1lb3V0ID0gb3B0aW9ucy50aW1lb3V0IHx8IEhUVFAuZGVmYXVsdE9wdGlvbnMudGltZW91dDtcbiAgfVxuICAvKipcbiAgICogQHByaXZhdGVcbiAgICovXG5cblxuICAoMCwgX2NyZWF0ZUNsYXNzMi5kZWZhdWx0KShIVFRQLCBbe1xuICAgIGtleTogXCJ0aW1lZEZldGNoXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIHRpbWVkRmV0Y2godXJsLCBvcHRpb25zKSB7XG4gICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuXG4gICAgICB2YXIgaGFzVGltZWRvdXQgPSBmYWxzZTtcbiAgICAgIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgICAgIC8vIERldGVjdCBpZiBhIHJlcXVlc3QgaGFzIHRpbWVkIG91dC5cbiAgICAgICAgdmFyIF90aW1lb3V0SWQ7XG5cbiAgICAgICAgaWYgKF90aGlzLnRpbWVvdXQpIHtcbiAgICAgICAgICBfdGltZW91dElkID0gc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBoYXNUaW1lZG91dCA9IHRydWU7XG4gICAgICAgICAgICByZWplY3QobmV3IF9lcnJvcnMuTmV0d29ya1RpbWVvdXRFcnJvcih1cmwsIG9wdGlvbnMpKTtcbiAgICAgICAgICB9LCBfdGhpcy50aW1lb3V0KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGZ1bmN0aW9uIHByb2NlZWRXaXRoSGFuZGxlcihmbikge1xuICAgICAgICAgIHJldHVybiBmdW5jdGlvbiAoYXJnKSB7XG4gICAgICAgICAgICBpZiAoIWhhc1RpbWVkb3V0KSB7XG4gICAgICAgICAgICAgIGlmIChfdGltZW91dElkKSB7XG4gICAgICAgICAgICAgICAgY2xlYXJUaW1lb3V0KF90aW1lb3V0SWQpO1xuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgZm4oYXJnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9O1xuICAgICAgICB9XG5cbiAgICAgICAgZmV0Y2godXJsLCBvcHRpb25zKS50aGVuKHByb2NlZWRXaXRoSGFuZGxlcihyZXNvbHZlKSkuY2F0Y2gocHJvY2VlZFdpdGhIYW5kbGVyKHJlamVjdCkpO1xuICAgICAgfSk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG5cbiAgfSwge1xuICAgIGtleTogXCJwcm9jZXNzUmVzcG9uc2VcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gKCkge1xuICAgICAgdmFyIF9wcm9jZXNzUmVzcG9uc2UgPSAoMCwgX2FzeW5jVG9HZW5lcmF0b3IyLmRlZmF1bHQpKFxuICAgICAgLyojX19QVVJFX18qL1xuICAgICAgX3JlZ2VuZXJhdG9yLmRlZmF1bHQubWFyayhmdW5jdGlvbiBfY2FsbGVlKHJlc3BvbnNlKSB7XG4gICAgICAgIHZhciBzdGF0dXMsIGhlYWRlcnMsIHRleHQsIGpzb247XG4gICAgICAgIHJldHVybiBfcmVnZW5lcmF0b3IuZGVmYXVsdC53cmFwKGZ1bmN0aW9uIF9jYWxsZWUkKF9jb250ZXh0KSB7XG4gICAgICAgICAgd2hpbGUgKDEpIHtcbiAgICAgICAgICAgIHN3aXRjaCAoX2NvbnRleHQucHJldiA9IF9jb250ZXh0Lm5leHQpIHtcbiAgICAgICAgICAgICAgY2FzZSAwOlxuICAgICAgICAgICAgICAgIHN0YXR1cyA9IHJlc3BvbnNlLnN0YXR1cywgaGVhZGVycyA9IHJlc3BvbnNlLmhlYWRlcnM7XG4gICAgICAgICAgICAgICAgX2NvbnRleHQubmV4dCA9IDM7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlc3BvbnNlLnRleHQoKTtcblxuICAgICAgICAgICAgICBjYXNlIDM6XG4gICAgICAgICAgICAgICAgdGV4dCA9IF9jb250ZXh0LnNlbnQ7XG5cbiAgICAgICAgICAgICAgICBpZiAoISh0ZXh0Lmxlbmd0aCAhPT0gMCkpIHtcbiAgICAgICAgICAgICAgICAgIF9jb250ZXh0Lm5leHQgPSAxMjtcbiAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIF9jb250ZXh0LnByZXYgPSA1O1xuICAgICAgICAgICAgICAgIGpzb24gPSBKU09OLnBhcnNlKHRleHQpO1xuICAgICAgICAgICAgICAgIF9jb250ZXh0Lm5leHQgPSAxMjtcbiAgICAgICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgICAgICBjYXNlIDk6XG4gICAgICAgICAgICAgICAgX2NvbnRleHQucHJldiA9IDk7XG4gICAgICAgICAgICAgICAgX2NvbnRleHQudDAgPSBfY29udGV4dFtcImNhdGNoXCJdKDUpO1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBfZXJyb3JzLlVucGFyc2VhYmxlUmVzcG9uc2VFcnJvcihyZXNwb25zZSwgdGV4dCwgX2NvbnRleHQudDApO1xuXG4gICAgICAgICAgICAgIGNhc2UgMTI6XG4gICAgICAgICAgICAgICAgaWYgKCEoc3RhdHVzID49IDQwMCkpIHtcbiAgICAgICAgICAgICAgICAgIF9jb250ZXh0Lm5leHQgPSAxNDtcbiAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBfZXJyb3JzLlNlcnZlclJlc3BvbnNlKHJlc3BvbnNlLCBqc29uKTtcblxuICAgICAgICAgICAgICBjYXNlIDE0OlxuICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dC5hYnJ1cHQoXCJyZXR1cm5cIiwge1xuICAgICAgICAgICAgICAgICAgc3RhdHVzOiBzdGF0dXMsXG4gICAgICAgICAgICAgICAgICBqc29uOiBqc29uLFxuICAgICAgICAgICAgICAgICAgaGVhZGVyczogaGVhZGVyc1xuICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgIGNhc2UgMTU6XG4gICAgICAgICAgICAgIGNhc2UgXCJlbmRcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQuc3RvcCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSwgX2NhbGxlZSwgdGhpcywgW1s1LCA5XV0pO1xuICAgICAgfSkpO1xuXG4gICAgICByZXR1cm4gZnVuY3Rpb24gcHJvY2Vzc1Jlc3BvbnNlKF94KSB7XG4gICAgICAgIHJldHVybiBfcHJvY2Vzc1Jlc3BvbnNlLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICB9O1xuICAgIH0oKVxuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG5cbiAgfSwge1xuICAgIGtleTogXCJyZXRyeVwiLFxuICAgIHZhbHVlOiBmdW5jdGlvbiAoKSB7XG4gICAgICB2YXIgX3JldHJ5ID0gKDAsIF9hc3luY1RvR2VuZXJhdG9yMi5kZWZhdWx0KShcbiAgICAgIC8qI19fUFVSRV9fKi9cbiAgICAgIF9yZWdlbmVyYXRvci5kZWZhdWx0Lm1hcmsoZnVuY3Rpb24gX2NhbGxlZTIodXJsLCByZXRyeUFmdGVyLCByZXF1ZXN0LCBvcHRpb25zKSB7XG4gICAgICAgIHJldHVybiBfcmVnZW5lcmF0b3IuZGVmYXVsdC53cmFwKGZ1bmN0aW9uIF9jYWxsZWUyJChfY29udGV4dDIpIHtcbiAgICAgICAgICB3aGlsZSAoMSkge1xuICAgICAgICAgICAgc3dpdGNoIChfY29udGV4dDIucHJldiA9IF9jb250ZXh0Mi5uZXh0KSB7XG4gICAgICAgICAgICAgIGNhc2UgMDpcbiAgICAgICAgICAgICAgICBfY29udGV4dDIubmV4dCA9IDI7XG4gICAgICAgICAgICAgICAgcmV0dXJuICgwLCBfdXRpbHMuZGVsYXkpKHJldHJ5QWZ0ZXIpO1xuXG4gICAgICAgICAgICAgIGNhc2UgMjpcbiAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQyLmFicnVwdChcInJldHVyblwiLCB0aGlzLnJlcXVlc3QodXJsLCByZXF1ZXN0LCAoMCwgX29iamVjdFNwcmVhZDIuZGVmYXVsdCkoe30sIG9wdGlvbnMsIHtcbiAgICAgICAgICAgICAgICAgIHJldHJ5OiBvcHRpb25zLnJldHJ5IC0gMVxuICAgICAgICAgICAgICAgIH0pKSk7XG5cbiAgICAgICAgICAgICAgY2FzZSAzOlxuICAgICAgICAgICAgICBjYXNlIFwiZW5kXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0Mi5zdG9wKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9LCBfY2FsbGVlMiwgdGhpcyk7XG4gICAgICB9KSk7XG5cbiAgICAgIHJldHVybiBmdW5jdGlvbiByZXRyeShfeDIsIF94MywgX3g0LCBfeDUpIHtcbiAgICAgICAgcmV0dXJuIF9yZXRyeS5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgfTtcbiAgICB9KClcbiAgICAvKipcbiAgICAgKiBQZXJmb3JtcyBhbiBIVFRQIHJlcXVlc3QgdG8gdGhlIEtpbnRvIHNlcnZlci5cbiAgICAgKlxuICAgICAqIFJlc29sdmVzIHdpdGggYW4gb2JqZXQgY29udGFpbmluZyB0aGUgZm9sbG93aW5nIEhUVFAgcmVzcG9uc2UgcHJvcGVydGllczpcbiAgICAgKiAtIGB7TnVtYmVyfSAgc3RhdHVzYCAgVGhlIEhUVFAgc3RhdHVzIGNvZGUuXG4gICAgICogLSBge09iamVjdH0gIGpzb25gICAgIFRoZSBKU09OIHJlc3BvbnNlIGJvZHkuXG4gICAgICogLSBge0hlYWRlcnN9IGhlYWRlcnNgIFRoZSByZXNwb25zZSBoZWFkZXJzIG9iamVjdDsgc2VlIHRoZSBFUzYgZmV0Y2goKSBzcGVjLlxuICAgICAqXG4gICAgICogQHBhcmFtICB7U3RyaW5nfSB1cmwgICAgICAgICAgICAgICBUaGUgVVJMLlxuICAgICAqIEBwYXJhbSAge09iamVjdH0gW3JlcXVlc3Q9e31dICAgICAgVGhlIHJlcXVlc3Qgb2JqZWN0LCBwYXNzZWQgdG9cbiAgICAgKiAgICAgZmV0Y2goKSBhcyBpdHMgb3B0aW9ucyBvYmplY3QuXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSBbcmVxdWVzdC5oZWFkZXJzXSBUaGUgcmVxdWVzdCBoZWFkZXJzIG9iamVjdCAoZGVmYXVsdDoge30pXG4gICAgICogQHBhcmFtICB7T2JqZWN0fSBbb3B0aW9ucz17fV0gICAgICBPcHRpb25zIGZvciBtYWtpbmcgdGhlXG4gICAgICogICAgIHJlcXVlc3RcbiAgICAgKiBAcGFyYW0gIHtOdW1iZXJ9IFtvcHRpb25zLnJldHJ5XSAgIE51bWJlciBvZiByZXRyaWVzIChkZWZhdWx0OiAwKVxuICAgICAqIEByZXR1cm4ge1Byb21pc2V9XG4gICAgICovXG5cbiAgfSwge1xuICAgIGtleTogXCJyZXF1ZXN0XCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciBfcmVxdWVzdDIgPSAoMCwgX2FzeW5jVG9HZW5lcmF0b3IyLmRlZmF1bHQpKFxuICAgICAgLyojX19QVVJFX18qL1xuICAgICAgX3JlZ2VuZXJhdG9yLmRlZmF1bHQubWFyayhmdW5jdGlvbiBfY2FsbGVlMyh1cmwpIHtcbiAgICAgICAgdmFyIF9yZXF1ZXN0LFxuICAgICAgICAgICAgb3B0aW9ucyxcbiAgICAgICAgICAgIHJlc3BvbnNlLFxuICAgICAgICAgICAgc3RhdHVzLFxuICAgICAgICAgICAgaGVhZGVycyxcbiAgICAgICAgICAgIHJldHJ5QWZ0ZXIsXG4gICAgICAgICAgICBfYXJnczMgPSBhcmd1bWVudHM7XG5cbiAgICAgICAgcmV0dXJuIF9yZWdlbmVyYXRvci5kZWZhdWx0LndyYXAoZnVuY3Rpb24gX2NhbGxlZTMkKF9jb250ZXh0Mykge1xuICAgICAgICAgIHdoaWxlICgxKSB7XG4gICAgICAgICAgICBzd2l0Y2ggKF9jb250ZXh0My5wcmV2ID0gX2NvbnRleHQzLm5leHQpIHtcbiAgICAgICAgICAgICAgY2FzZSAwOlxuICAgICAgICAgICAgICAgIF9yZXF1ZXN0ID0gX2FyZ3MzLmxlbmd0aCA+IDEgJiYgX2FyZ3MzWzFdICE9PSB1bmRlZmluZWQgPyBfYXJnczNbMV0gOiB7XG4gICAgICAgICAgICAgICAgICBoZWFkZXJzOiB7fVxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgb3B0aW9ucyA9IF9hcmdzMy5sZW5ndGggPiAyICYmIF9hcmdzM1syXSAhPT0gdW5kZWZpbmVkID8gX2FyZ3MzWzJdIDoge1xuICAgICAgICAgICAgICAgICAgcmV0cnk6IDBcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIC8vIEVuc3VyZSBkZWZhdWx0IHJlcXVlc3QgaGVhZGVycyBhcmUgYWx3YXlzIHNldFxuICAgICAgICAgICAgICAgIF9yZXF1ZXN0LmhlYWRlcnMgPSAoMCwgX29iamVjdFNwcmVhZDIuZGVmYXVsdCkoe30sIEhUVFAuREVGQVVMVF9SRVFVRVNUX0hFQURFUlMsIF9yZXF1ZXN0LmhlYWRlcnMpOyAvLyBJZiBhIG11bHRpcGFydCBib2R5IGlzIHByb3ZpZGVkLCByZW1vdmUgYW55IGN1c3RvbSBDb250ZW50LVR5cGUgaGVhZGVyIGFzXG4gICAgICAgICAgICAgICAgLy8gdGhlIGZldGNoKCkgaW1wbGVtZW50YXRpb24gd2lsbCBhZGQgdGhlIGNvcnJlY3Qgb25lIGZvciB1cy5cblxuICAgICAgICAgICAgICAgIGlmIChfcmVxdWVzdC5ib2R5ICYmIHR5cGVvZiBfcmVxdWVzdC5ib2R5LmFwcGVuZCA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgICAgICAgICBkZWxldGUgX3JlcXVlc3QuaGVhZGVyc1tcIkNvbnRlbnQtVHlwZVwiXTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBfcmVxdWVzdC5tb2RlID0gdGhpcy5yZXF1ZXN0TW9kZTtcbiAgICAgICAgICAgICAgICBfY29udGV4dDMubmV4dCA9IDc7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMudGltZWRGZXRjaCh1cmwsIF9yZXF1ZXN0KTtcblxuICAgICAgICAgICAgICBjYXNlIDc6XG4gICAgICAgICAgICAgICAgcmVzcG9uc2UgPSBfY29udGV4dDMuc2VudDtcbiAgICAgICAgICAgICAgICBzdGF0dXMgPSByZXNwb25zZS5zdGF0dXMsIGhlYWRlcnMgPSByZXNwb25zZS5oZWFkZXJzO1xuXG4gICAgICAgICAgICAgICAgdGhpcy5fY2hlY2tGb3JEZXByZWNhdGlvbkhlYWRlcihoZWFkZXJzKTtcblxuICAgICAgICAgICAgICAgIHRoaXMuX2NoZWNrRm9yQmFja29mZkhlYWRlcihzdGF0dXMsIGhlYWRlcnMpOyAvLyBDaGVjayBpZiB0aGUgc2VydmVyIHN1bW1vbnMgdGhlIGNsaWVudCB0byByZXRyeSBhZnRlciBhIHdoaWxlLlxuXG5cbiAgICAgICAgICAgICAgICByZXRyeUFmdGVyID0gdGhpcy5fY2hlY2tGb3JSZXRyeUFmdGVySGVhZGVyKHN0YXR1cywgaGVhZGVycyk7IC8vIElmIG51bWJlciBvZiBhbGxvd2VkIG9mIHJldHJpZXMgaXMgbm90IGV4aGF1c3RlZCwgcmV0cnkgdGhlIHNhbWUgcmVxdWVzdC5cblxuICAgICAgICAgICAgICAgIGlmICghKHJldHJ5QWZ0ZXIgJiYgb3B0aW9ucy5yZXRyeSA+IDApKSB7XG4gICAgICAgICAgICAgICAgICBfY29udGV4dDMubmV4dCA9IDE2O1xuICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgcmV0dXJuIF9jb250ZXh0My5hYnJ1cHQoXCJyZXR1cm5cIiwgdGhpcy5yZXRyeSh1cmwsIHJldHJ5QWZ0ZXIsIF9yZXF1ZXN0LCBvcHRpb25zKSk7XG5cbiAgICAgICAgICAgICAgY2FzZSAxNjpcbiAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQzLmFicnVwdChcInJldHVyblwiLCB0aGlzLnByb2Nlc3NSZXNwb25zZShyZXNwb25zZSkpO1xuXG4gICAgICAgICAgICAgIGNhc2UgMTc6XG4gICAgICAgICAgICAgIGNhc2UgXCJlbmRcIjpcbiAgICAgICAgICAgICAgICByZXR1cm4gX2NvbnRleHQzLnN0b3AoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0sIF9jYWxsZWUzLCB0aGlzKTtcbiAgICAgIH0pKTtcblxuICAgICAgcmV0dXJuIGZ1bmN0aW9uIHJlcXVlc3QoX3g2KSB7XG4gICAgICAgIHJldHVybiBfcmVxdWVzdDIuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgIH07XG4gICAgfSgpXG4gIH0sIHtcbiAgICBrZXk6IFwiX2NoZWNrRm9yRGVwcmVjYXRpb25IZWFkZXJcIixcbiAgICB2YWx1ZTogZnVuY3Rpb24gX2NoZWNrRm9yRGVwcmVjYXRpb25IZWFkZXIoaGVhZGVycykge1xuICAgICAgdmFyIGFsZXJ0SGVhZGVyID0gaGVhZGVycy5nZXQoXCJBbGVydFwiKTtcblxuICAgICAgaWYgKCFhbGVydEhlYWRlcikge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIHZhciBhbGVydDtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgYWxlcnQgPSBKU09OLnBhcnNlKGFsZXJ0SGVhZGVyKTtcbiAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICBjb25zb2xlLndhcm4oXCJVbmFibGUgdG8gcGFyc2UgQWxlcnQgaGVhZGVyIG1lc3NhZ2VcIiwgYWxlcnRIZWFkZXIpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGNvbnNvbGUud2FybihhbGVydC5tZXNzYWdlLCBhbGVydC51cmwpO1xuICAgICAgdGhpcy5ldmVudHMuZW1pdChcImRlcHJlY2F0ZWRcIiwgYWxlcnQpO1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJfY2hlY2tGb3JCYWNrb2ZmSGVhZGVyXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIF9jaGVja0ZvckJhY2tvZmZIZWFkZXIoc3RhdHVzLCBoZWFkZXJzKSB7XG4gICAgICB2YXIgYmFja29mZk1zO1xuICAgICAgdmFyIGJhY2tvZmZTZWNvbmRzID0gcGFyc2VJbnQoaGVhZGVycy5nZXQoXCJCYWNrb2ZmXCIpLCAxMCk7XG5cbiAgICAgIGlmIChiYWNrb2ZmU2Vjb25kcyA+IDApIHtcbiAgICAgICAgYmFja29mZk1zID0gbmV3IERhdGUoKS5nZXRUaW1lKCkgKyBiYWNrb2ZmU2Vjb25kcyAqIDEwMDA7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBiYWNrb2ZmTXMgPSAwO1xuICAgICAgfVxuXG4gICAgICB0aGlzLmV2ZW50cy5lbWl0KFwiYmFja29mZlwiLCBiYWNrb2ZmTXMpO1xuICAgIH1cbiAgfSwge1xuICAgIGtleTogXCJfY2hlY2tGb3JSZXRyeUFmdGVySGVhZGVyXCIsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIF9jaGVja0ZvclJldHJ5QWZ0ZXJIZWFkZXIoc3RhdHVzLCBoZWFkZXJzKSB7XG4gICAgICB2YXIgcmV0cnlBZnRlciA9IGhlYWRlcnMuZ2V0KFwiUmV0cnktQWZ0ZXJcIik7XG5cbiAgICAgIGlmICghcmV0cnlBZnRlcikge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIHZhciBkZWxheSA9IHBhcnNlSW50KHJldHJ5QWZ0ZXIsIDEwKSAqIDEwMDA7XG4gICAgICByZXRyeUFmdGVyID0gbmV3IERhdGUoKS5nZXRUaW1lKCkgKyBkZWxheTtcbiAgICAgIHRoaXMuZXZlbnRzLmVtaXQoXCJyZXRyeS1hZnRlclwiLCByZXRyeUFmdGVyKTtcbiAgICAgIHJldHVybiBkZWxheTtcbiAgICB9XG4gIH1dKTtcbiAgcmV0dXJuIEhUVFA7XG59KCk7XG5cbmV4cG9ydHMuZGVmYXVsdCA9IEhUVFA7IiwiXCJ1c2Ugc3RyaWN0XCI7XG5cbnZhciBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0ID0gcmVxdWlyZShcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvaW50ZXJvcFJlcXVpcmVEZWZhdWx0XCIpO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHtcbiAgdmFsdWU6IHRydWVcbn0pO1xuZXhwb3J0cy5kZWZhdWx0ID0gdm9pZCAwO1xuXG52YXIgX3R5cGVvZjIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KHJlcXVpcmUoXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL3R5cGVvZlwiKSk7XG5cbnZhciBfY2xhc3NDYWxsQ2hlY2syID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChyZXF1aXJlKFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9jbGFzc0NhbGxDaGVja1wiKSk7XG5cbnZhciBfcG9zc2libGVDb25zdHJ1Y3RvclJldHVybjIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KHJlcXVpcmUoXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL3Bvc3NpYmxlQ29uc3RydWN0b3JSZXR1cm5cIikpO1xuXG52YXIgX2dldFByb3RvdHlwZU9mMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQocmVxdWlyZShcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvZ2V0UHJvdG90eXBlT2ZcIikpO1xuXG52YXIgX2luaGVyaXRzMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQocmVxdWlyZShcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvaW5oZXJpdHNcIikpO1xuXG52YXIgX2V2ZW50cyA9IHJlcXVpcmUoXCJldmVudHNcIik7XG5cbnZhciBfYmFzZSA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQocmVxdWlyZShcIi4vYmFzZVwiKSk7XG5cbnZhciBLaW50b0NsaWVudCA9XG4vKiNfX1BVUkVfXyovXG5mdW5jdGlvbiAoX0tpbnRvQ2xpZW50QmFzZSkge1xuICAoMCwgX2luaGVyaXRzMi5kZWZhdWx0KShLaW50b0NsaWVudCwgX0tpbnRvQ2xpZW50QmFzZSk7XG5cbiAgZnVuY3Rpb24gS2ludG9DbGllbnQocmVtb3RlKSB7XG4gICAgdmFyIG9wdGlvbnMgPSBhcmd1bWVudHMubGVuZ3RoID4gMSAmJiBhcmd1bWVudHNbMV0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1sxXSA6IHt9O1xuICAgICgwLCBfY2xhc3NDYWxsQ2hlY2syLmRlZmF1bHQpKHRoaXMsIEtpbnRvQ2xpZW50KTtcbiAgICB2YXIgZXZlbnRzID0gb3B0aW9ucy5ldmVudHMgfHwgbmV3IF9ldmVudHMuRXZlbnRFbWl0dGVyKCk7XG4gICAgcmV0dXJuICgwLCBfcG9zc2libGVDb25zdHJ1Y3RvclJldHVybjIuZGVmYXVsdCkodGhpcywgKDAsIF9nZXRQcm90b3R5cGVPZjIuZGVmYXVsdCkoS2ludG9DbGllbnQpLmNhbGwodGhpcywgcmVtb3RlLCBPYmplY3QuYXNzaWduKHtcbiAgICAgIGV2ZW50czogZXZlbnRzXG4gICAgfSwgb3B0aW9ucykpKTtcbiAgfVxuXG4gIHJldHVybiBLaW50b0NsaWVudDtcbn0oX2Jhc2UuZGVmYXVsdCk7IC8vIFRoaXMgaXMgYSBoYWNrIHRvIGF2b2lkIEJyb3dzZXJpZnkgdG8gZXhwb3NlIHRoZSBhYm92ZSBjbGFzc1xuLy8gYXQgYG5ldyBLaW50b0NsaWVudCgpYCBpbnN0ZWFkIG9mIGBuZXcgS2ludG9DbGllbnQuZGVmYXVsdCgpYC5cbi8vIFNlZSBodHRwczovL2dpdGh1Yi5jb20vS2ludG8va2ludG8taHR0cC5qcy9pc3N1ZXMvNzdcblxuXG5leHBvcnRzLmRlZmF1bHQgPSBLaW50b0NsaWVudDtcblxuaWYgKCh0eXBlb2YgbW9kdWxlID09PSBcInVuZGVmaW5lZFwiID8gXCJ1bmRlZmluZWRcIiA6ICgwLCBfdHlwZW9mMi5kZWZhdWx0KShtb2R1bGUpKSA9PT0gXCJvYmplY3RcIikge1xuICBtb2R1bGUuZXhwb3J0cyA9IEtpbnRvQ2xpZW50O1xufSIsIlwidXNlIHN0cmljdFwiO1xuXG52YXIgX2ludGVyb3BSZXF1aXJlRGVmYXVsdCA9IHJlcXVpcmUoXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2ludGVyb3BSZXF1aXJlRGVmYXVsdFwiKTtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG4gIHZhbHVlOiB0cnVlXG59KTtcbmV4cG9ydHMuY3JlYXRlUmVxdWVzdCA9IGNyZWF0ZVJlcXVlc3Q7XG5leHBvcnRzLnVwZGF0ZVJlcXVlc3QgPSB1cGRhdGVSZXF1ZXN0O1xuZXhwb3J0cy5qc29uUGF0Y2hQZXJtaXNzaW9uc1JlcXVlc3QgPSBqc29uUGF0Y2hQZXJtaXNzaW9uc1JlcXVlc3Q7XG5leHBvcnRzLmRlbGV0ZVJlcXVlc3QgPSBkZWxldGVSZXF1ZXN0O1xuZXhwb3J0cy5hZGRBdHRhY2htZW50UmVxdWVzdCA9IGFkZEF0dGFjaG1lbnRSZXF1ZXN0O1xuXG52YXIgX3NsaWNlZFRvQXJyYXkyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChyZXF1aXJlKFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9zbGljZWRUb0FycmF5XCIpKTtcblxudmFyIF9vYmplY3RTcHJlYWQyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChyZXF1aXJlKFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9vYmplY3RTcHJlYWRcIikpO1xuXG52YXIgX3V0aWxzID0gcmVxdWlyZShcIi4vdXRpbHNcIik7XG5cbnZhciByZXF1ZXN0RGVmYXVsdHMgPSB7XG4gIHNhZmU6IGZhbHNlLFxuICAvLyBjaGVjayBpZiB3ZSBzaG91bGQgc2V0IGRlZmF1bHQgY29udGVudCB0eXBlIGhlcmVcbiAgaGVhZGVyczoge30sXG4gIHBlcm1pc3Npb25zOiB1bmRlZmluZWQsXG4gIGRhdGE6IHVuZGVmaW5lZCxcbiAgcGF0Y2g6IGZhbHNlXG59O1xuLyoqXG4gKiBAcHJpdmF0ZVxuICovXG5cbmZ1bmN0aW9uIHNhZmVIZWFkZXIoc2FmZSwgbGFzdF9tb2RpZmllZCkge1xuICBpZiAoIXNhZmUpIHtcbiAgICByZXR1cm4ge307XG4gIH1cblxuICBpZiAobGFzdF9tb2RpZmllZCkge1xuICAgIHJldHVybiB7XG4gICAgICBcIklmLU1hdGNoXCI6IFwiXFxcIlwiLmNvbmNhdChsYXN0X21vZGlmaWVkLCBcIlxcXCJcIilcbiAgICB9O1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBcIklmLU5vbmUtTWF0Y2hcIjogXCIqXCJcbiAgfTtcbn1cbi8qKlxuICogQHByaXZhdGVcbiAqL1xuXG5cbmZ1bmN0aW9uIGNyZWF0ZVJlcXVlc3QocGF0aCwgX3JlZikge1xuICB2YXIgZGF0YSA9IF9yZWYuZGF0YSxcbiAgICAgIHBlcm1pc3Npb25zID0gX3JlZi5wZXJtaXNzaW9ucztcbiAgdmFyIG9wdGlvbnMgPSBhcmd1bWVudHMubGVuZ3RoID4gMiAmJiBhcmd1bWVudHNbMl0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1syXSA6IHt9O1xuXG4gIHZhciBfcmVxdWVzdERlZmF1bHRzJG9wdGkgPSAoMCwgX29iamVjdFNwcmVhZDIuZGVmYXVsdCkoe30sIHJlcXVlc3REZWZhdWx0cywgb3B0aW9ucyksXG4gICAgICBoZWFkZXJzID0gX3JlcXVlc3REZWZhdWx0cyRvcHRpLmhlYWRlcnMsXG4gICAgICBzYWZlID0gX3JlcXVlc3REZWZhdWx0cyRvcHRpLnNhZmU7XG5cbiAgcmV0dXJuIHtcbiAgICBtZXRob2Q6IGRhdGEgJiYgZGF0YS5pZCA/IFwiUFVUXCIgOiBcIlBPU1RcIixcbiAgICBwYXRoOiBwYXRoLFxuICAgIGhlYWRlcnM6ICgwLCBfb2JqZWN0U3ByZWFkMi5kZWZhdWx0KSh7fSwgaGVhZGVycywgc2FmZUhlYWRlcihzYWZlKSksXG4gICAgYm9keToge1xuICAgICAgZGF0YTogZGF0YSxcbiAgICAgIHBlcm1pc3Npb25zOiBwZXJtaXNzaW9uc1xuICAgIH1cbiAgfTtcbn1cbi8qKlxuICogQHByaXZhdGVcbiAqL1xuXG5cbmZ1bmN0aW9uIHVwZGF0ZVJlcXVlc3QocGF0aCwgX3JlZjIpIHtcbiAgdmFyIGRhdGEgPSBfcmVmMi5kYXRhLFxuICAgICAgcGVybWlzc2lvbnMgPSBfcmVmMi5wZXJtaXNzaW9ucztcbiAgdmFyIG9wdGlvbnMgPSBhcmd1bWVudHMubGVuZ3RoID4gMiAmJiBhcmd1bWVudHNbMl0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1syXSA6IHt9O1xuXG4gIHZhciBfcmVxdWVzdERlZmF1bHRzJG9wdGkyID0gKDAsIF9vYmplY3RTcHJlYWQyLmRlZmF1bHQpKHt9LCByZXF1ZXN0RGVmYXVsdHMsIG9wdGlvbnMpLFxuICAgICAgaGVhZGVycyA9IF9yZXF1ZXN0RGVmYXVsdHMkb3B0aTIuaGVhZGVycyxcbiAgICAgIHNhZmUgPSBfcmVxdWVzdERlZmF1bHRzJG9wdGkyLnNhZmUsXG4gICAgICBwYXRjaCA9IF9yZXF1ZXN0RGVmYXVsdHMkb3B0aTIucGF0Y2g7XG5cbiAgdmFyIF9kYXRhJG9wdGlvbnMgPSAoMCwgX29iamVjdFNwcmVhZDIuZGVmYXVsdCkoe30sIGRhdGEsIG9wdGlvbnMpLFxuICAgICAgbGFzdF9tb2RpZmllZCA9IF9kYXRhJG9wdGlvbnMubGFzdF9tb2RpZmllZDtcblxuICBpZiAoT2JqZWN0LmtleXMoKDAsIF91dGlscy5vbWl0KShkYXRhLCBcImlkXCIsIFwibGFzdF9tb2RpZmllZFwiKSkubGVuZ3RoID09PSAwKSB7XG4gICAgZGF0YSA9IHVuZGVmaW5lZDtcbiAgfVxuXG4gIHJldHVybiB7XG4gICAgbWV0aG9kOiBwYXRjaCA/IFwiUEFUQ0hcIiA6IFwiUFVUXCIsXG4gICAgcGF0aDogcGF0aCxcbiAgICBoZWFkZXJzOiAoMCwgX29iamVjdFNwcmVhZDIuZGVmYXVsdCkoe30sIGhlYWRlcnMsIHNhZmVIZWFkZXIoc2FmZSwgbGFzdF9tb2RpZmllZCkpLFxuICAgIGJvZHk6IHtcbiAgICAgIGRhdGE6IGRhdGEsXG4gICAgICBwZXJtaXNzaW9uczogcGVybWlzc2lvbnNcbiAgICB9XG4gIH07XG59XG4vKipcbiAqIEBwcml2YXRlXG4gKi9cblxuXG5mdW5jdGlvbiBqc29uUGF0Y2hQZXJtaXNzaW9uc1JlcXVlc3QocGF0aCwgcGVybWlzc2lvbnMsIG9wVHlwZSkge1xuICB2YXIgb3B0aW9ucyA9IGFyZ3VtZW50cy5sZW5ndGggPiAzICYmIGFyZ3VtZW50c1szXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzNdIDoge307XG5cbiAgdmFyIF9yZXF1ZXN0RGVmYXVsdHMkb3B0aTMgPSAoMCwgX29iamVjdFNwcmVhZDIuZGVmYXVsdCkoe30sIHJlcXVlc3REZWZhdWx0cywgb3B0aW9ucyksXG4gICAgICBoZWFkZXJzID0gX3JlcXVlc3REZWZhdWx0cyRvcHRpMy5oZWFkZXJzLFxuICAgICAgc2FmZSA9IF9yZXF1ZXN0RGVmYXVsdHMkb3B0aTMuc2FmZSxcbiAgICAgIGxhc3RfbW9kaWZpZWQgPSBfcmVxdWVzdERlZmF1bHRzJG9wdGkzLmxhc3RfbW9kaWZpZWQ7XG5cbiAgdmFyIG9wcyA9IFtdO1xuXG4gIHZhciBfYXJyID0gT2JqZWN0LmVudHJpZXMocGVybWlzc2lvbnMpO1xuXG4gIGZvciAodmFyIF9pID0gMDsgX2kgPCBfYXJyLmxlbmd0aDsgX2krKykge1xuICAgIHZhciBfYXJyJF9pID0gKDAsIF9zbGljZWRUb0FycmF5Mi5kZWZhdWx0KShfYXJyW19pXSwgMiksXG4gICAgICAgIHR5cGUgPSBfYXJyJF9pWzBdLFxuICAgICAgICBwcmluY2lwYWxzID0gX2FyciRfaVsxXTtcblxuICAgIHZhciBfaXRlcmF0b3JOb3JtYWxDb21wbGV0aW9uID0gdHJ1ZTtcbiAgICB2YXIgX2RpZEl0ZXJhdG9yRXJyb3IgPSBmYWxzZTtcbiAgICB2YXIgX2l0ZXJhdG9yRXJyb3IgPSB1bmRlZmluZWQ7XG5cbiAgICB0cnkge1xuICAgICAgZm9yICh2YXIgX2l0ZXJhdG9yID0gcHJpbmNpcGFsc1tTeW1ib2wuaXRlcmF0b3JdKCksIF9zdGVwOyAhKF9pdGVyYXRvck5vcm1hbENvbXBsZXRpb24gPSAoX3N0ZXAgPSBfaXRlcmF0b3IubmV4dCgpKS5kb25lKTsgX2l0ZXJhdG9yTm9ybWFsQ29tcGxldGlvbiA9IHRydWUpIHtcbiAgICAgICAgdmFyIHByaW5jaXBhbCA9IF9zdGVwLnZhbHVlO1xuICAgICAgICBvcHMucHVzaCh7XG4gICAgICAgICAgb3A6IG9wVHlwZSxcbiAgICAgICAgICBwYXRoOiBcIi9wZXJtaXNzaW9ucy9cIi5jb25jYXQodHlwZSwgXCIvXCIpLmNvbmNhdChwcmluY2lwYWwpXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgX2RpZEl0ZXJhdG9yRXJyb3IgPSB0cnVlO1xuICAgICAgX2l0ZXJhdG9yRXJyb3IgPSBlcnI7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGlmICghX2l0ZXJhdG9yTm9ybWFsQ29tcGxldGlvbiAmJiBfaXRlcmF0b3IucmV0dXJuICE9IG51bGwpIHtcbiAgICAgICAgICBfaXRlcmF0b3IucmV0dXJuKCk7XG4gICAgICAgIH1cbiAgICAgIH0gZmluYWxseSB7XG4gICAgICAgIGlmIChfZGlkSXRlcmF0b3JFcnJvcikge1xuICAgICAgICAgIHRocm93IF9pdGVyYXRvckVycm9yO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBtZXRob2Q6IFwiUEFUQ0hcIixcbiAgICBwYXRoOiBwYXRoLFxuICAgIGhlYWRlcnM6ICgwLCBfb2JqZWN0U3ByZWFkMi5kZWZhdWx0KSh7fSwgaGVhZGVycywgc2FmZUhlYWRlcihzYWZlLCBsYXN0X21vZGlmaWVkKSwge1xuICAgICAgXCJDb250ZW50LVR5cGVcIjogXCJhcHBsaWNhdGlvbi9qc29uLXBhdGNoK2pzb25cIlxuICAgIH0pLFxuICAgIGJvZHk6IG9wc1xuICB9O1xufVxuLyoqXG4gKiBAcHJpdmF0ZVxuICovXG5cblxuZnVuY3Rpb24gZGVsZXRlUmVxdWVzdChwYXRoKSB7XG4gIHZhciBvcHRpb25zID0gYXJndW1lbnRzLmxlbmd0aCA+IDEgJiYgYXJndW1lbnRzWzFdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbMV0gOiB7fTtcblxuICB2YXIgX3JlcXVlc3REZWZhdWx0cyRvcHRpNCA9ICgwLCBfb2JqZWN0U3ByZWFkMi5kZWZhdWx0KSh7fSwgcmVxdWVzdERlZmF1bHRzLCBvcHRpb25zKSxcbiAgICAgIGhlYWRlcnMgPSBfcmVxdWVzdERlZmF1bHRzJG9wdGk0LmhlYWRlcnMsXG4gICAgICBzYWZlID0gX3JlcXVlc3REZWZhdWx0cyRvcHRpNC5zYWZlLFxuICAgICAgbGFzdF9tb2RpZmllZCA9IF9yZXF1ZXN0RGVmYXVsdHMkb3B0aTQubGFzdF9tb2RpZmllZDtcblxuICBpZiAoc2FmZSAmJiAhbGFzdF9tb2RpZmllZCkge1xuICAgIHRocm93IG5ldyBFcnJvcihcIlNhZmUgY29uY3VycmVuY3kgY2hlY2sgcmVxdWlyZXMgYSBsYXN0X21vZGlmaWVkIHZhbHVlLlwiKTtcbiAgfVxuXG4gIHJldHVybiB7XG4gICAgbWV0aG9kOiBcIkRFTEVURVwiLFxuICAgIHBhdGg6IHBhdGgsXG4gICAgaGVhZGVyczogKDAsIF9vYmplY3RTcHJlYWQyLmRlZmF1bHQpKHt9LCBoZWFkZXJzLCBzYWZlSGVhZGVyKHNhZmUsIGxhc3RfbW9kaWZpZWQpKVxuICB9O1xufVxuLyoqXG4gKiBAcHJpdmF0ZVxuICovXG5cblxuZnVuY3Rpb24gYWRkQXR0YWNobWVudFJlcXVlc3QocGF0aCwgZGF0YVVSSSkge1xuICB2YXIgX3JlZjMgPSBhcmd1bWVudHMubGVuZ3RoID4gMiAmJiBhcmd1bWVudHNbMl0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1syXSA6IHt9LFxuICAgICAgZGF0YSA9IF9yZWYzLmRhdGEsXG4gICAgICBwZXJtaXNzaW9ucyA9IF9yZWYzLnBlcm1pc3Npb25zO1xuXG4gIHZhciBvcHRpb25zID0gYXJndW1lbnRzLmxlbmd0aCA+IDMgJiYgYXJndW1lbnRzWzNdICE9PSB1bmRlZmluZWQgPyBhcmd1bWVudHNbM10gOiB7fTtcblxuICB2YXIgX3JlcXVlc3REZWZhdWx0cyRvcHRpNSA9ICgwLCBfb2JqZWN0U3ByZWFkMi5kZWZhdWx0KSh7fSwgcmVxdWVzdERlZmF1bHRzLCBvcHRpb25zKSxcbiAgICAgIGhlYWRlcnMgPSBfcmVxdWVzdERlZmF1bHRzJG9wdGk1LmhlYWRlcnMsXG4gICAgICBzYWZlID0gX3JlcXVlc3REZWZhdWx0cyRvcHRpNS5zYWZlLFxuICAgICAgZ3ppcHBlZCA9IF9yZXF1ZXN0RGVmYXVsdHMkb3B0aTUuZ3ppcHBlZDtcblxuICB2YXIgX2RhdGEkb3B0aW9uczIgPSAoMCwgX29iamVjdFNwcmVhZDIuZGVmYXVsdCkoe30sIGRhdGEsIG9wdGlvbnMpLFxuICAgICAgbGFzdF9tb2RpZmllZCA9IF9kYXRhJG9wdGlvbnMyLmxhc3RfbW9kaWZpZWQ7XG5cbiAgdmFyIGJvZHkgPSB7XG4gICAgZGF0YTogZGF0YSxcbiAgICBwZXJtaXNzaW9uczogcGVybWlzc2lvbnNcbiAgfTtcbiAgdmFyIGZvcm1EYXRhID0gKDAsIF91dGlscy5jcmVhdGVGb3JtRGF0YSkoZGF0YVVSSSwgYm9keSwgb3B0aW9ucyk7XG4gIHZhciBjdXN0b21QYXRoID0gZ3ppcHBlZCAhPSBudWxsID8gY3VzdG9tUGF0aCA9IHBhdGggKyBcIj9nemlwcGVkPVwiICsgKGd6aXBwZWQgPyBcInRydWVcIiA6IFwiZmFsc2VcIikgOiBwYXRoO1xuICByZXR1cm4ge1xuICAgIG1ldGhvZDogXCJQT1NUXCIsXG4gICAgcGF0aDogY3VzdG9tUGF0aCxcbiAgICBoZWFkZXJzOiAoMCwgX29iamVjdFNwcmVhZDIuZGVmYXVsdCkoe30sIGhlYWRlcnMsIHNhZmVIZWFkZXIoc2FmZSwgbGFzdF9tb2RpZmllZCkpLFxuICAgIGJvZHk6IGZvcm1EYXRhXG4gIH07XG59IiwiXCJ1c2Ugc3RyaWN0XCI7XG5cbnZhciBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0ID0gcmVxdWlyZShcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvaW50ZXJvcFJlcXVpcmVEZWZhdWx0XCIpO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHtcbiAgdmFsdWU6IHRydWVcbn0pO1xuZXhwb3J0cy5wYXJ0aXRpb24gPSBwYXJ0aXRpb247XG5leHBvcnRzLmRlbGF5ID0gZGVsYXk7XG5leHBvcnRzLnBNYXAgPSBwTWFwO1xuZXhwb3J0cy5vbWl0ID0gb21pdDtcbmV4cG9ydHMudG9EYXRhQm9keSA9IHRvRGF0YUJvZHk7XG5leHBvcnRzLnFzaWZ5ID0gcXNpZnk7XG5leHBvcnRzLmNoZWNrVmVyc2lvbiA9IGNoZWNrVmVyc2lvbjtcbmV4cG9ydHMuc3VwcG9ydCA9IHN1cHBvcnQ7XG5leHBvcnRzLmNhcGFibGUgPSBjYXBhYmxlO1xuZXhwb3J0cy5ub2JhdGNoID0gbm9iYXRjaDtcbmV4cG9ydHMuaXNPYmplY3QgPSBpc09iamVjdDtcbmV4cG9ydHMucGFyc2VEYXRhVVJMID0gcGFyc2VEYXRhVVJMO1xuZXhwb3J0cy5leHRyYWN0RmlsZUluZm8gPSBleHRyYWN0RmlsZUluZm87XG5leHBvcnRzLmNyZWF0ZUZvcm1EYXRhID0gY3JlYXRlRm9ybURhdGE7XG5leHBvcnRzLmNsZWFuVW5kZWZpbmVkUHJvcGVydGllcyA9IGNsZWFuVW5kZWZpbmVkUHJvcGVydGllcztcblxudmFyIF9yZWdlbmVyYXRvciA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQocmVxdWlyZShcIkBiYWJlbC9ydW50aW1lL3JlZ2VuZXJhdG9yXCIpKTtcblxudmFyIF9kZWZpbmVQcm9wZXJ0eTIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KHJlcXVpcmUoXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2RlZmluZVByb3BlcnR5XCIpKTtcblxudmFyIF9vYmplY3RTcHJlYWQzID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChyZXF1aXJlKFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9vYmplY3RTcHJlYWRcIikpO1xuXG52YXIgX3RvQXJyYXkyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChyZXF1aXJlKFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy90b0FycmF5XCIpKTtcblxudmFyIF90eXBlb2YyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChyZXF1aXJlKFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy90eXBlb2ZcIikpO1xuXG52YXIgX3NsaWNlZFRvQXJyYXkyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChyZXF1aXJlKFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9zbGljZWRUb0FycmF5XCIpKTtcblxudmFyIF9hc3luY1RvR2VuZXJhdG9yMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQocmVxdWlyZShcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvYXN5bmNUb0dlbmVyYXRvclwiKSk7XG5cbi8qKlxuICogQ2h1bmtzIGFuIGFycmF5IGludG8gbiBwaWVjZXMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSAge0FycmF5fSAgYXJyYXlcbiAqIEBwYXJhbSAge051bWJlcn0gblxuICogQHJldHVybiB7QXJyYXl9XG4gKi9cbmZ1bmN0aW9uIHBhcnRpdGlvbihhcnJheSwgbikge1xuICBpZiAobiA8PSAwKSB7XG4gICAgcmV0dXJuIGFycmF5O1xuICB9XG5cbiAgcmV0dXJuIGFycmF5LnJlZHVjZShmdW5jdGlvbiAoYWNjLCB4LCBpKSB7XG4gICAgaWYgKGkgPT09IDAgfHwgaSAlIG4gPT09IDApIHtcbiAgICAgIGFjYy5wdXNoKFt4XSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGFjY1thY2MubGVuZ3RoIC0gMV0ucHVzaCh4KTtcbiAgICB9XG5cbiAgICByZXR1cm4gYWNjO1xuICB9LCBbXSk7XG59XG4vKipcbiAqIFJldHVybnMgYSBQcm9taXNlIGFsd2F5cyByZXNvbHZpbmcgYWZ0ZXIgdGhlIHNwZWNpZmllZCBhbW91bnQgaW4gbWlsbGlzZWNvbmRzLlxuICpcbiAqIEByZXR1cm4gUHJvbWlzZTx2b2lkPlxuICovXG5cblxuZnVuY3Rpb24gZGVsYXkobXMpIHtcbiAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uIChyZXNvbHZlKSB7XG4gICAgcmV0dXJuIHNldFRpbWVvdXQocmVzb2x2ZSwgbXMpO1xuICB9KTtcbn1cbi8qKlxuICogTWFwcyBhIGxpc3QgdG8gcHJvbWlzZXMgdXNpbmcgdGhlIHByb3ZpZGVkIG1hcHBpbmcgZnVuY3Rpb24sIGV4ZWN1dGVzIHRoZW1cbiAqIHNlcXVlbnRpYWxseSB0aGVuIHJldHVybnMgYSBQcm9taXNlIHJlc29sdmluZyB3aXRoIG9yZGVyZWQgcmVzdWx0cyBvYnRhaW5lZC5cbiAqIFRoaW5rIG9mIHRoaXMgYXMgYSBzZXF1ZW50aWFsIFByb21pc2UuYWxsLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0gIHtBcnJheX0gICAgbGlzdCBUaGUgbGlzdCB0byBtYXAuXG4gKiBAcGFyYW0gIHtGdW5jdGlvbn0gZm4gICBUaGUgbWFwcGluZyBmdW5jdGlvbi5cbiAqIEByZXR1cm4ge1Byb21pc2V9XG4gKi9cblxuXG5mdW5jdGlvbiBwTWFwKF94LCBfeDIpIHtcbiAgcmV0dXJuIF9wTWFwLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG59XG4vKipcbiAqIFRha2VzIGFuIG9iamVjdCBhbmQgcmV0dXJucyBhIGNvcHkgb2YgaXQgd2l0aCB0aGUgcHJvdmlkZWQga2V5cyBvbWl0dGVkLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0gIHtPYmplY3R9ICAgIG9iaiAgVGhlIHNvdXJjZSBvYmplY3QuXG4gKiBAcGFyYW0gIHsuLi5TdHJpbmd9IGtleXMgVGhlIGtleXMgdG8gb21pdC5cbiAqIEByZXR1cm4ge09iamVjdH1cbiAqL1xuXG5cbmZ1bmN0aW9uIF9wTWFwKCkge1xuICBfcE1hcCA9ICgwLCBfYXN5bmNUb0dlbmVyYXRvcjIuZGVmYXVsdCkoXG4gIC8qI19fUFVSRV9fKi9cbiAgX3JlZ2VuZXJhdG9yLmRlZmF1bHQubWFyayhmdW5jdGlvbiBfY2FsbGVlMihsaXN0LCBmbikge1xuICAgIHZhciByZXN1bHRzO1xuICAgIHJldHVybiBfcmVnZW5lcmF0b3IuZGVmYXVsdC53cmFwKGZ1bmN0aW9uIF9jYWxsZWUyJChfY29udGV4dDIpIHtcbiAgICAgIHdoaWxlICgxKSB7XG4gICAgICAgIHN3aXRjaCAoX2NvbnRleHQyLnByZXYgPSBfY29udGV4dDIubmV4dCkge1xuICAgICAgICAgIGNhc2UgMDpcbiAgICAgICAgICAgIHJlc3VsdHMgPSBbXTtcbiAgICAgICAgICAgIF9jb250ZXh0Mi5uZXh0ID0gMztcbiAgICAgICAgICAgIHJldHVybiBsaXN0LnJlZHVjZShcbiAgICAgICAgICAgIC8qI19fUFVSRV9fKi9cbiAgICAgICAgICAgIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgdmFyIF9yZWYgPSAoMCwgX2FzeW5jVG9HZW5lcmF0b3IyLmRlZmF1bHQpKFxuICAgICAgICAgICAgICAvKiNfX1BVUkVfXyovXG4gICAgICAgICAgICAgIF9yZWdlbmVyYXRvci5kZWZhdWx0Lm1hcmsoZnVuY3Rpb24gX2NhbGxlZShwcm9taXNlLCBlbnRyeSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBfcmVnZW5lcmF0b3IuZGVmYXVsdC53cmFwKGZ1bmN0aW9uIF9jYWxsZWUkKF9jb250ZXh0KSB7XG4gICAgICAgICAgICAgICAgICB3aGlsZSAoMSkge1xuICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKF9jb250ZXh0LnByZXYgPSBfY29udGV4dC5uZXh0KSB7XG4gICAgICAgICAgICAgICAgICAgICAgY2FzZSAwOlxuICAgICAgICAgICAgICAgICAgICAgICAgX2NvbnRleHQubmV4dCA9IDI7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcHJvbWlzZTtcblxuICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMjpcbiAgICAgICAgICAgICAgICAgICAgICAgIF9jb250ZXh0LnQwID0gcmVzdWx0cztcbiAgICAgICAgICAgICAgICAgICAgICAgIF9jb250ZXh0Lm5leHQgPSA1O1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZuKGVudHJ5KTtcblxuICAgICAgICAgICAgICAgICAgICAgIGNhc2UgNTpcbiAgICAgICAgICAgICAgICAgICAgICAgIF9jb250ZXh0LnQxID0gX2NvbnRleHQuc2VudDtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdHMgPSBfY29udGV4dC50MC5jb25jYXQuY2FsbChfY29udGV4dC50MCwgX2NvbnRleHQudDEpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgY2FzZSA3OlxuICAgICAgICAgICAgICAgICAgICAgIGNhc2UgXCJlbmRcIjpcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBfY29udGV4dC5zdG9wKCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9LCBfY2FsbGVlLCB0aGlzKTtcbiAgICAgICAgICAgICAgfSkpO1xuXG4gICAgICAgICAgICAgIHJldHVybiBmdW5jdGlvbiAoX3gzLCBfeDQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gX3JlZi5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgfSgpLCBQcm9taXNlLnJlc29sdmUoKSk7XG5cbiAgICAgICAgICBjYXNlIDM6XG4gICAgICAgICAgICByZXR1cm4gX2NvbnRleHQyLmFicnVwdChcInJldHVyblwiLCByZXN1bHRzKTtcblxuICAgICAgICAgIGNhc2UgNDpcbiAgICAgICAgICBjYXNlIFwiZW5kXCI6XG4gICAgICAgICAgICByZXR1cm4gX2NvbnRleHQyLnN0b3AoKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0sIF9jYWxsZWUyLCB0aGlzKTtcbiAgfSkpO1xuICByZXR1cm4gX3BNYXAuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbn1cblxuZnVuY3Rpb24gb21pdChvYmopIHtcbiAgZm9yICh2YXIgX2xlbiA9IGFyZ3VtZW50cy5sZW5ndGgsIGtleXMgPSBuZXcgQXJyYXkoX2xlbiA+IDEgPyBfbGVuIC0gMSA6IDApLCBfa2V5ID0gMTsgX2tleSA8IF9sZW47IF9rZXkrKykge1xuICAgIGtleXNbX2tleSAtIDFdID0gYXJndW1lbnRzW19rZXldO1xuICB9XG5cbiAgcmV0dXJuIE9iamVjdC5rZXlzKG9iaikucmVkdWNlKGZ1bmN0aW9uIChhY2MsIGtleSkge1xuICAgIGlmICgha2V5cy5pbmNsdWRlcyhrZXkpKSB7XG4gICAgICBhY2Nba2V5XSA9IG9ialtrZXldO1xuICAgIH1cblxuICAgIHJldHVybiBhY2M7XG4gIH0sIHt9KTtcbn1cbi8qKlxuICogQWx3YXlzIHJldHVybnMgYSByZXNvdXJjZSBkYXRhIG9iamVjdCBmcm9tIHRoZSBwcm92aWRlZCBhcmd1bWVudC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtICB7T2JqZWN0fFN0cmluZ30gcmVzb3VyY2VcbiAqIEByZXR1cm4ge09iamVjdH1cbiAqL1xuXG5cbmZ1bmN0aW9uIHRvRGF0YUJvZHkocmVzb3VyY2UpIHtcbiAgaWYgKGlzT2JqZWN0KHJlc291cmNlKSkge1xuICAgIHJldHVybiByZXNvdXJjZTtcbiAgfVxuXG4gIGlmICh0eXBlb2YgcmVzb3VyY2UgPT09IFwic3RyaW5nXCIpIHtcbiAgICByZXR1cm4ge1xuICAgICAgaWQ6IHJlc291cmNlXG4gICAgfTtcbiAgfVxuXG4gIHRocm93IG5ldyBFcnJvcihcIkludmFsaWQgYXJndW1lbnQuXCIpO1xufVxuLyoqXG4gKiBUcmFuc2Zvcm1zIGFuIG9iamVjdCBpbnRvIGFuIFVSTCBxdWVyeSBzdHJpbmcsIHN0cmlwcGluZyBvdXQgYW55IHVuZGVmaW5lZFxuICogdmFsdWVzLlxuICpcbiAqIEBwYXJhbSAge09iamVjdH0gb2JqXG4gKiBAcmV0dXJuIHtTdHJpbmd9XG4gKi9cblxuXG5mdW5jdGlvbiBxc2lmeShvYmopIHtcbiAgdmFyIGVuY29kZSA9IGZ1bmN0aW9uIGVuY29kZSh2KSB7XG4gICAgcmV0dXJuIGVuY29kZVVSSUNvbXBvbmVudCh0eXBlb2YgdiA9PT0gXCJib29sZWFuXCIgPyBTdHJpbmcodikgOiB2KTtcbiAgfTtcblxuICB2YXIgc3RyaXBVbmRlZmluZWQgPSBmdW5jdGlvbiBzdHJpcFVuZGVmaW5lZChvKSB7XG4gICAgcmV0dXJuIEpTT04ucGFyc2UoSlNPTi5zdHJpbmdpZnkobykpO1xuICB9O1xuXG4gIHZhciBzdHJpcHBlZCA9IHN0cmlwVW5kZWZpbmVkKG9iaik7XG4gIHJldHVybiBPYmplY3Qua2V5cyhzdHJpcHBlZCkubWFwKGZ1bmN0aW9uIChrKSB7XG4gICAgdmFyIGtzID0gZW5jb2RlKGspICsgXCI9XCI7XG5cbiAgICBpZiAoQXJyYXkuaXNBcnJheShzdHJpcHBlZFtrXSkpIHtcbiAgICAgIHJldHVybiBrcyArIHN0cmlwcGVkW2tdLm1hcChmdW5jdGlvbiAodikge1xuICAgICAgICByZXR1cm4gZW5jb2RlKHYpO1xuICAgICAgfSkuam9pbihcIixcIik7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBrcyArIGVuY29kZShzdHJpcHBlZFtrXSk7XG4gICAgfVxuICB9KS5qb2luKFwiJlwiKTtcbn1cbi8qKlxuICogQ2hlY2tzIGlmIGEgdmVyc2lvbiBpcyB3aXRoaW4gdGhlIHByb3ZpZGVkIHJhbmdlLlxuICpcbiAqIEBwYXJhbSAge1N0cmluZ30gdmVyc2lvbiAgICBUaGUgdmVyc2lvbiB0byBjaGVjay5cbiAqIEBwYXJhbSAge1N0cmluZ30gbWluVmVyc2lvbiBUaGUgbWluaW11bSBzdXBwb3J0ZWQgdmVyc2lvbiAoaW5jbHVzaXZlKS5cbiAqIEBwYXJhbSAge1N0cmluZ30gbWF4VmVyc2lvbiBUaGUgbWluaW11bSBzdXBwb3J0ZWQgdmVyc2lvbiAoZXhjbHVzaXZlKS5cbiAqIEB0aHJvd3Mge0Vycm9yfSBJZiB0aGUgdmVyc2lvbiBpcyBvdXRzaWRlIG9mIHRoZSBwcm92aWRlZCByYW5nZS5cbiAqL1xuXG5cbmZ1bmN0aW9uIGNoZWNrVmVyc2lvbih2ZXJzaW9uLCBtaW5WZXJzaW9uLCBtYXhWZXJzaW9uKSB7XG4gIHZhciBleHRyYWN0ID0gZnVuY3Rpb24gZXh0cmFjdChzdHIpIHtcbiAgICByZXR1cm4gc3RyLnNwbGl0KFwiLlwiKS5tYXAoZnVuY3Rpb24gKHgpIHtcbiAgICAgIHJldHVybiBwYXJzZUludCh4LCAxMCk7XG4gICAgfSk7XG4gIH07XG5cbiAgdmFyIF9leHRyYWN0ID0gZXh0cmFjdCh2ZXJzaW9uKSxcbiAgICAgIF9leHRyYWN0MiA9ICgwLCBfc2xpY2VkVG9BcnJheTIuZGVmYXVsdCkoX2V4dHJhY3QsIDIpLFxuICAgICAgdmVyTWFqb3IgPSBfZXh0cmFjdDJbMF0sXG4gICAgICB2ZXJNaW5vciA9IF9leHRyYWN0MlsxXTtcblxuICB2YXIgX2V4dHJhY3QzID0gZXh0cmFjdChtaW5WZXJzaW9uKSxcbiAgICAgIF9leHRyYWN0NCA9ICgwLCBfc2xpY2VkVG9BcnJheTIuZGVmYXVsdCkoX2V4dHJhY3QzLCAyKSxcbiAgICAgIG1pbk1ham9yID0gX2V4dHJhY3Q0WzBdLFxuICAgICAgbWluTWlub3IgPSBfZXh0cmFjdDRbMV07XG5cbiAgdmFyIF9leHRyYWN0NSA9IGV4dHJhY3QobWF4VmVyc2lvbiksXG4gICAgICBfZXh0cmFjdDYgPSAoMCwgX3NsaWNlZFRvQXJyYXkyLmRlZmF1bHQpKF9leHRyYWN0NSwgMiksXG4gICAgICBtYXhNYWpvciA9IF9leHRyYWN0NlswXSxcbiAgICAgIG1heE1pbm9yID0gX2V4dHJhY3Q2WzFdO1xuXG4gIHZhciBjaGVja3MgPSBbdmVyTWFqb3IgPCBtaW5NYWpvciwgdmVyTWFqb3IgPT09IG1pbk1ham9yICYmIHZlck1pbm9yIDwgbWluTWlub3IsIHZlck1ham9yID4gbWF4TWFqb3IsIHZlck1ham9yID09PSBtYXhNYWpvciAmJiB2ZXJNaW5vciA+PSBtYXhNaW5vcl07XG5cbiAgaWYgKGNoZWNrcy5zb21lKGZ1bmN0aW9uICh4KSB7XG4gICAgcmV0dXJuIHg7XG4gIH0pKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFwiVmVyc2lvbiBcIi5jb25jYXQodmVyc2lvbiwgXCIgZG9lc24ndCBzYXRpc2Z5IFwiKS5jb25jYXQobWluVmVyc2lvbiwgXCIgPD0geCA8IFwiKS5jb25jYXQobWF4VmVyc2lvbikpO1xuICB9XG59XG4vKipcbiAqIEdlbmVyYXRlcyBhIGRlY29yYXRvciBmdW5jdGlvbiBlbnN1cmluZyBhIHZlcnNpb24gY2hlY2sgaXMgcGVyZm9ybWVkIGFnYWluc3RcbiAqIHRoZSBwcm92aWRlZCByZXF1aXJlbWVudHMgYmVmb3JlIGV4ZWN1dGluZyBpdC5cbiAqXG4gKiBAcGFyYW0gIHtTdHJpbmd9IG1pbiBUaGUgcmVxdWlyZWQgbWluIHZlcnNpb24gKGluY2x1c2l2ZSkuXG4gKiBAcGFyYW0gIHtTdHJpbmd9IG1heCBUaGUgcmVxdWlyZWQgbWF4IHZlcnNpb24gKGluY2x1c2l2ZSkuXG4gKiBAcmV0dXJuIHtGdW5jdGlvbn1cbiAqL1xuXG5cbmZ1bmN0aW9uIHN1cHBvcnQobWluLCBtYXgpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uICh0YXJnZXQsIGtleSwgZGVzY3JpcHRvcikge1xuICAgIHZhciBmbiA9IGRlc2NyaXB0b3IudmFsdWU7XG4gICAgcmV0dXJuIHtcbiAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgIGdldDogZnVuY3Rpb24gZ2V0KCkge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuXG4gICAgICAgIHZhciB3cmFwcGVkTWV0aG9kID0gZnVuY3Rpb24gd3JhcHBlZE1ldGhvZCgpIHtcbiAgICAgICAgICBmb3IgKHZhciBfbGVuMiA9IGFyZ3VtZW50cy5sZW5ndGgsIGFyZ3MgPSBuZXcgQXJyYXkoX2xlbjIpLCBfa2V5MiA9IDA7IF9rZXkyIDwgX2xlbjI7IF9rZXkyKyspIHtcbiAgICAgICAgICAgIGFyZ3NbX2tleTJdID0gYXJndW1lbnRzW19rZXkyXTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICAvLyBcInRoaXNcIiBpcyB0aGUgY3VycmVudCBpbnN0YW5jZSB3aGljaCBpdHMgbWV0aG9kIGlzIGRlY29yYXRlZC5cbiAgICAgICAgICB2YXIgY2xpZW50ID0gXCJjbGllbnRcIiBpbiBfdGhpcyA/IF90aGlzLmNsaWVudCA6IF90aGlzO1xuICAgICAgICAgIHJldHVybiBjbGllbnQuZmV0Y2hIVFRQQXBpVmVyc2lvbigpLnRoZW4oZnVuY3Rpb24gKHZlcnNpb24pIHtcbiAgICAgICAgICAgIHJldHVybiBjaGVja1ZlcnNpb24odmVyc2lvbiwgbWluLCBtYXgpO1xuICAgICAgICAgIH0pLnRoZW4oZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmV0dXJuIGZuLmFwcGx5KF90aGlzLCBhcmdzKTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfTtcblxuICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywga2V5LCB7XG4gICAgICAgICAgdmFsdWU6IHdyYXBwZWRNZXRob2QsXG4gICAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgICAgIHdyaXRhYmxlOiB0cnVlXG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gd3JhcHBlZE1ldGhvZDtcbiAgICAgIH1cbiAgICB9O1xuICB9O1xufVxuLyoqXG4gKiBHZW5lcmF0ZXMgYSBkZWNvcmF0b3IgZnVuY3Rpb24gZW5zdXJpbmcgdGhhdCB0aGUgc3BlY2lmaWVkIGNhcGFiaWxpdGllcyBhcmVcbiAqIGF2YWlsYWJsZSBvbiB0aGUgc2VydmVyIGJlZm9yZSBleGVjdXRpbmcgaXQuXG4gKlxuICogQHBhcmFtICB7QXJyYXk8U3RyaW5nPn0gY2FwYWJpbGl0aWVzIFRoZSByZXF1aXJlZCBjYXBhYmlsaXRpZXMuXG4gKiBAcmV0dXJuIHtGdW5jdGlvbn1cbiAqL1xuXG5cbmZ1bmN0aW9uIGNhcGFibGUoY2FwYWJpbGl0aWVzKSB7XG4gIHJldHVybiBmdW5jdGlvbiAodGFyZ2V0LCBrZXksIGRlc2NyaXB0b3IpIHtcbiAgICB2YXIgZm4gPSBkZXNjcmlwdG9yLnZhbHVlO1xuICAgIHJldHVybiB7XG4gICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHtcbiAgICAgICAgdmFyIF90aGlzMiA9IHRoaXM7XG5cbiAgICAgICAgdmFyIHdyYXBwZWRNZXRob2QgPSBmdW5jdGlvbiB3cmFwcGVkTWV0aG9kKCkge1xuICAgICAgICAgIGZvciAodmFyIF9sZW4zID0gYXJndW1lbnRzLmxlbmd0aCwgYXJncyA9IG5ldyBBcnJheShfbGVuMyksIF9rZXkzID0gMDsgX2tleTMgPCBfbGVuMzsgX2tleTMrKykge1xuICAgICAgICAgICAgYXJnc1tfa2V5M10gPSBhcmd1bWVudHNbX2tleTNdO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIC8vIFwidGhpc1wiIGlzIHRoZSBjdXJyZW50IGluc3RhbmNlIHdoaWNoIGl0cyBtZXRob2QgaXMgZGVjb3JhdGVkLlxuICAgICAgICAgIHZhciBjbGllbnQgPSBcImNsaWVudFwiIGluIF90aGlzMiA/IF90aGlzMi5jbGllbnQgOiBfdGhpczI7XG4gICAgICAgICAgcmV0dXJuIGNsaWVudC5mZXRjaFNlcnZlckNhcGFiaWxpdGllcygpLnRoZW4oZnVuY3Rpb24gKGF2YWlsYWJsZSkge1xuICAgICAgICAgICAgdmFyIG1pc3NpbmcgPSBjYXBhYmlsaXRpZXMuZmlsdGVyKGZ1bmN0aW9uIChjKSB7XG4gICAgICAgICAgICAgIHJldHVybiAhKGMgaW4gYXZhaWxhYmxlKTtcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICBpZiAobWlzc2luZy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgIHZhciBtaXNzaW5nU3RyID0gbWlzc2luZy5qb2luKFwiLCBcIik7XG4gICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIlJlcXVpcmVkIGNhcGFiaWxpdGllcyBcIi5jb25jYXQobWlzc2luZ1N0ciwgXCIgbm90IHByZXNlbnQgb24gc2VydmVyXCIpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KS50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHJldHVybiBmbi5hcHBseShfdGhpczIsIGFyZ3MpO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9O1xuXG4gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCBrZXksIHtcbiAgICAgICAgICB2YWx1ZTogd3JhcHBlZE1ldGhvZCxcbiAgICAgICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgICAgICAgd3JpdGFibGU6IHRydWVcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiB3cmFwcGVkTWV0aG9kO1xuICAgICAgfVxuICAgIH07XG4gIH07XG59XG4vKipcbiAqIEdlbmVyYXRlcyBhIGRlY29yYXRvciBmdW5jdGlvbiBlbnN1cmluZyBhbiBvcGVyYXRpb24gaXMgbm90IHBlcmZvcm1lZCBmcm9tXG4gKiB3aXRoaW4gYSBiYXRjaCByZXF1ZXN0LlxuICpcbiAqIEBwYXJhbSAge1N0cmluZ30gbWVzc2FnZSBUaGUgZXJyb3IgbWVzc2FnZSB0byB0aHJvdy5cbiAqIEByZXR1cm4ge0Z1bmN0aW9ufVxuICovXG5cblxuZnVuY3Rpb24gbm9iYXRjaChtZXNzYWdlKSB7XG4gIHJldHVybiBmdW5jdGlvbiAodGFyZ2V0LCBrZXksIGRlc2NyaXB0b3IpIHtcbiAgICB2YXIgZm4gPSBkZXNjcmlwdG9yLnZhbHVlO1xuICAgIHJldHVybiB7XG4gICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHtcbiAgICAgICAgdmFyIF90aGlzMyA9IHRoaXM7XG5cbiAgICAgICAgdmFyIHdyYXBwZWRNZXRob2QgPSBmdW5jdGlvbiB3cmFwcGVkTWV0aG9kKCkge1xuICAgICAgICAgIC8vIFwidGhpc1wiIGlzIHRoZSBjdXJyZW50IGluc3RhbmNlIHdoaWNoIGl0cyBtZXRob2QgaXMgZGVjb3JhdGVkLlxuICAgICAgICAgIGlmIChfdGhpczMuX2lzQmF0Y2gpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihtZXNzYWdlKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBmb3IgKHZhciBfbGVuNCA9IGFyZ3VtZW50cy5sZW5ndGgsIGFyZ3MgPSBuZXcgQXJyYXkoX2xlbjQpLCBfa2V5NCA9IDA7IF9rZXk0IDwgX2xlbjQ7IF9rZXk0KyspIHtcbiAgICAgICAgICAgIGFyZ3NbX2tleTRdID0gYXJndW1lbnRzW19rZXk0XTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZXR1cm4gZm4uYXBwbHkoX3RoaXMzLCBhcmdzKTtcbiAgICAgICAgfTtcblxuICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywga2V5LCB7XG4gICAgICAgICAgdmFsdWU6IHdyYXBwZWRNZXRob2QsXG4gICAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgICAgIHdyaXRhYmxlOiB0cnVlXG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gd3JhcHBlZE1ldGhvZDtcbiAgICAgIH1cbiAgICB9O1xuICB9O1xufVxuLyoqXG4gKiBSZXR1cm5zIHRydWUgaWYgdGhlIHNwZWNpZmllZCB2YWx1ZSBpcyBhbiBvYmplY3QgKGkuZS4gbm90IGFuIGFycmF5IG5vciBudWxsKS5cbiAqIEBwYXJhbSAge09iamVjdH0gdGhpbmcgVGhlIHZhbHVlIHRvIGluc3BlY3QuXG4gKiBAcmV0dXJuIHtib29sfVxuICovXG5cblxuZnVuY3Rpb24gaXNPYmplY3QodGhpbmcpIHtcbiAgcmV0dXJuICgwLCBfdHlwZW9mMi5kZWZhdWx0KSh0aGluZykgPT09IFwib2JqZWN0XCIgJiYgdGhpbmcgIT09IG51bGwgJiYgIUFycmF5LmlzQXJyYXkodGhpbmcpO1xufVxuLyoqXG4gKiBQYXJzZXMgYSBkYXRhIHVybC5cbiAqIEBwYXJhbSAge1N0cmluZ30gZGF0YVVSTCBUaGUgZGF0YSB1cmwuXG4gKiBAcmV0dXJuIHtPYmplY3R9XG4gKi9cblxuXG5mdW5jdGlvbiBwYXJzZURhdGFVUkwoZGF0YVVSTCkge1xuICB2YXIgcmVnZXggPSAvXmRhdGE6KC4qKTtiYXNlNjQsKC4qKS87XG4gIHZhciBtYXRjaCA9IGRhdGFVUkwubWF0Y2gocmVnZXgpO1xuXG4gIGlmICghbWF0Y2gpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJJbnZhbGlkIGRhdGEtdXJsOiBcIi5jb25jYXQoU3RyaW5nKGRhdGFVUkwpLnN1YnN0cigwLCAzMiksIFwiLi4uXCIpKTtcbiAgfVxuXG4gIHZhciBwcm9wcyA9IG1hdGNoWzFdO1xuICB2YXIgYmFzZTY0ID0gbWF0Y2hbMl07XG5cbiAgdmFyIF9wcm9wcyRzcGxpdCA9IHByb3BzLnNwbGl0KFwiO1wiKSxcbiAgICAgIF9wcm9wcyRzcGxpdDIgPSAoMCwgX3RvQXJyYXkyLmRlZmF1bHQpKF9wcm9wcyRzcGxpdCksXG4gICAgICB0eXBlID0gX3Byb3BzJHNwbGl0MlswXSxcbiAgICAgIHJhd1BhcmFtcyA9IF9wcm9wcyRzcGxpdDIuc2xpY2UoMSk7XG5cbiAgdmFyIHBhcmFtcyA9IHJhd1BhcmFtcy5yZWR1Y2UoZnVuY3Rpb24gKGFjYywgcGFyYW0pIHtcbiAgICB2YXIgX3BhcmFtJHNwbGl0ID0gcGFyYW0uc3BsaXQoXCI9XCIpLFxuICAgICAgICBfcGFyYW0kc3BsaXQyID0gKDAsIF9zbGljZWRUb0FycmF5Mi5kZWZhdWx0KShfcGFyYW0kc3BsaXQsIDIpLFxuICAgICAgICBrZXkgPSBfcGFyYW0kc3BsaXQyWzBdLFxuICAgICAgICB2YWx1ZSA9IF9wYXJhbSRzcGxpdDJbMV07XG5cbiAgICByZXR1cm4gKDAsIF9vYmplY3RTcHJlYWQzLmRlZmF1bHQpKHt9LCBhY2MsICgwLCBfZGVmaW5lUHJvcGVydHkyLmRlZmF1bHQpKHt9LCBrZXksIHZhbHVlKSk7XG4gIH0sIHt9KTtcbiAgcmV0dXJuICgwLCBfb2JqZWN0U3ByZWFkMy5kZWZhdWx0KSh7fSwgcGFyYW1zLCB7XG4gICAgdHlwZTogdHlwZSxcbiAgICBiYXNlNjQ6IGJhc2U2NFxuICB9KTtcbn1cbi8qKlxuICogRXh0cmFjdHMgZmlsZSBpbmZvcm1hdGlvbiBmcm9tIGEgZGF0YSB1cmwuXG4gKiBAcGFyYW0gIHtTdHJpbmd9IGRhdGFVUkwgVGhlIGRhdGEgdXJsLlxuICogQHJldHVybiB7T2JqZWN0fVxuICovXG5cblxuZnVuY3Rpb24gZXh0cmFjdEZpbGVJbmZvKGRhdGFVUkwpIHtcbiAgdmFyIF9wYXJzZURhdGFVUkwgPSBwYXJzZURhdGFVUkwoZGF0YVVSTCksXG4gICAgICBuYW1lID0gX3BhcnNlRGF0YVVSTC5uYW1lLFxuICAgICAgdHlwZSA9IF9wYXJzZURhdGFVUkwudHlwZSxcbiAgICAgIGJhc2U2NCA9IF9wYXJzZURhdGFVUkwuYmFzZTY0O1xuXG4gIHZhciBiaW5hcnkgPSBhdG9iKGJhc2U2NCk7XG4gIHZhciBhcnJheSA9IFtdO1xuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgYmluYXJ5Lmxlbmd0aDsgaSsrKSB7XG4gICAgYXJyYXkucHVzaChiaW5hcnkuY2hhckNvZGVBdChpKSk7XG4gIH1cblxuICB2YXIgYmxvYiA9IG5ldyBCbG9iKFtuZXcgVWludDhBcnJheShhcnJheSldLCB7XG4gICAgdHlwZTogdHlwZVxuICB9KTtcbiAgcmV0dXJuIHtcbiAgICBibG9iOiBibG9iLFxuICAgIG5hbWU6IG5hbWVcbiAgfTtcbn1cbi8qKlxuICogQ3JlYXRlcyBhIEZvcm1EYXRhIGluc3RhbmNlIGZyb20gYSBkYXRhIHVybCBhbmQgYW4gZXhpc3RpbmcgSlNPTiByZXNwb25zZVxuICogYm9keS5cbiAqIEBwYXJhbSAge1N0cmluZ30gZGF0YVVSTCAgICAgICAgICAgIFRoZSBkYXRhIHVybC5cbiAqIEBwYXJhbSAge09iamVjdH0gYm9keSAgICAgICAgICAgICAgIFRoZSByZXNwb25zZSBib2R5LlxuICogQHBhcmFtICB7T2JqZWN0fSBbb3B0aW9ucz17fV0gICAgICAgVGhlIG9wdGlvbnMgb2JqZWN0LlxuICogQHBhcmFtICB7T2JqZWN0fSBbb3B0aW9ucy5maWxlbmFtZV0gRm9yY2UgYXR0YWNobWVudCBmaWxlIG5hbWUuXG4gKiBAcmV0dXJuIHtGb3JtRGF0YX1cbiAqL1xuXG5cbmZ1bmN0aW9uIGNyZWF0ZUZvcm1EYXRhKGRhdGFVUkwsIGJvZHkpIHtcbiAgdmFyIG9wdGlvbnMgPSBhcmd1bWVudHMubGVuZ3RoID4gMiAmJiBhcmd1bWVudHNbMl0gIT09IHVuZGVmaW5lZCA/IGFyZ3VtZW50c1syXSA6IHt9O1xuICB2YXIgX29wdGlvbnMkZmlsZW5hbWUgPSBvcHRpb25zLmZpbGVuYW1lLFxuICAgICAgZmlsZW5hbWUgPSBfb3B0aW9ucyRmaWxlbmFtZSA9PT0gdm9pZCAwID8gXCJ1bnRpdGxlZFwiIDogX29wdGlvbnMkZmlsZW5hbWU7XG5cbiAgdmFyIF9leHRyYWN0RmlsZUluZm8gPSBleHRyYWN0RmlsZUluZm8oZGF0YVVSTCksXG4gICAgICBibG9iID0gX2V4dHJhY3RGaWxlSW5mby5ibG9iLFxuICAgICAgbmFtZSA9IF9leHRyYWN0RmlsZUluZm8ubmFtZTtcblxuICB2YXIgZm9ybURhdGEgPSBuZXcgRm9ybURhdGEoKTtcbiAgZm9ybURhdGEuYXBwZW5kKFwiYXR0YWNobWVudFwiLCBibG9iLCBuYW1lIHx8IGZpbGVuYW1lKTtcblxuICBmb3IgKHZhciBwcm9wZXJ0eSBpbiBib2R5KSB7XG4gICAgaWYgKHR5cGVvZiBib2R5W3Byb3BlcnR5XSAhPT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgZm9ybURhdGEuYXBwZW5kKHByb3BlcnR5LCBKU09OLnN0cmluZ2lmeShib2R5W3Byb3BlcnR5XSkpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBmb3JtRGF0YTtcbn1cbi8qKlxuICogQ2xvbmVzIGFuIG9iamVjdCB3aXRoIGFsbCBpdHMgdW5kZWZpbmVkIGtleXMgcmVtb3ZlZC5cbiAqIEBwcml2YXRlXG4gKi9cblxuXG5mdW5jdGlvbiBjbGVhblVuZGVmaW5lZFByb3BlcnRpZXMob2JqKSB7XG4gIHZhciByZXN1bHQgPSB7fTtcblxuICBmb3IgKHZhciBrZXkgaW4gb2JqKSB7XG4gICAgaWYgKHR5cGVvZiBvYmpba2V5XSAhPT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgcmVzdWx0W2tleV0gPSBvYmpba2V5XTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gcmVzdWx0O1xufSIsInZhciB2MSA9IHJlcXVpcmUoJy4vdjEnKTtcbnZhciB2NCA9IHJlcXVpcmUoJy4vdjQnKTtcblxudmFyIHV1aWQgPSB2NDtcbnV1aWQudjEgPSB2MTtcbnV1aWQudjQgPSB2NDtcblxubW9kdWxlLmV4cG9ydHMgPSB1dWlkO1xuIiwiLyoqXG4gKiBDb252ZXJ0IGFycmF5IG9mIDE2IGJ5dGUgdmFsdWVzIHRvIFVVSUQgc3RyaW5nIGZvcm1hdCBvZiB0aGUgZm9ybTpcbiAqIFhYWFhYWFhYLVhYWFgtWFhYWC1YWFhYLVhYWFhYWFhYWFhYWFxuICovXG52YXIgYnl0ZVRvSGV4ID0gW107XG5mb3IgKHZhciBpID0gMDsgaSA8IDI1NjsgKytpKSB7XG4gIGJ5dGVUb0hleFtpXSA9IChpICsgMHgxMDApLnRvU3RyaW5nKDE2KS5zdWJzdHIoMSk7XG59XG5cbmZ1bmN0aW9uIGJ5dGVzVG9VdWlkKGJ1Ziwgb2Zmc2V0KSB7XG4gIHZhciBpID0gb2Zmc2V0IHx8IDA7XG4gIHZhciBidGggPSBieXRlVG9IZXg7XG4gIC8vIGpvaW4gdXNlZCB0byBmaXggbWVtb3J5IGlzc3VlIGNhdXNlZCBieSBjb25jYXRlbmF0aW9uOiBodHRwczovL2J1Z3MuY2hyb21pdW0ub3JnL3AvdjgvaXNzdWVzL2RldGFpbD9pZD0zMTc1I2M0XG4gIHJldHVybiAoW2J0aFtidWZbaSsrXV0sIGJ0aFtidWZbaSsrXV0sIFxuXHRidGhbYnVmW2krK11dLCBidGhbYnVmW2krK11dLCAnLScsXG5cdGJ0aFtidWZbaSsrXV0sIGJ0aFtidWZbaSsrXV0sICctJyxcblx0YnRoW2J1ZltpKytdXSwgYnRoW2J1ZltpKytdXSwgJy0nLFxuXHRidGhbYnVmW2krK11dLCBidGhbYnVmW2krK11dLCAnLScsXG5cdGJ0aFtidWZbaSsrXV0sIGJ0aFtidWZbaSsrXV0sXG5cdGJ0aFtidWZbaSsrXV0sIGJ0aFtidWZbaSsrXV0sXG5cdGJ0aFtidWZbaSsrXV0sIGJ0aFtidWZbaSsrXV1dKS5qb2luKCcnKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBieXRlc1RvVXVpZDtcbiIsIi8vIFVuaXF1ZSBJRCBjcmVhdGlvbiByZXF1aXJlcyBhIGhpZ2ggcXVhbGl0eSByYW5kb20gIyBnZW5lcmF0b3IuICBJbiB0aGVcbi8vIGJyb3dzZXIgdGhpcyBpcyBhIGxpdHRsZSBjb21wbGljYXRlZCBkdWUgdG8gdW5rbm93biBxdWFsaXR5IG9mIE1hdGgucmFuZG9tKClcbi8vIGFuZCBpbmNvbnNpc3RlbnQgc3VwcG9ydCBmb3IgdGhlIGBjcnlwdG9gIEFQSS4gIFdlIGRvIHRoZSBiZXN0IHdlIGNhbiB2aWFcbi8vIGZlYXR1cmUtZGV0ZWN0aW9uXG5cbi8vIGdldFJhbmRvbVZhbHVlcyBuZWVkcyB0byBiZSBpbnZva2VkIGluIGEgY29udGV4dCB3aGVyZSBcInRoaXNcIiBpcyBhIENyeXB0b1xuLy8gaW1wbGVtZW50YXRpb24uIEFsc28sIGZpbmQgdGhlIGNvbXBsZXRlIGltcGxlbWVudGF0aW9uIG9mIGNyeXB0byBvbiBJRTExLlxudmFyIGdldFJhbmRvbVZhbHVlcyA9ICh0eXBlb2YoY3J5cHRvKSAhPSAndW5kZWZpbmVkJyAmJiBjcnlwdG8uZ2V0UmFuZG9tVmFsdWVzICYmIGNyeXB0by5nZXRSYW5kb21WYWx1ZXMuYmluZChjcnlwdG8pKSB8fFxuICAgICAgICAgICAgICAgICAgICAgICh0eXBlb2YobXNDcnlwdG8pICE9ICd1bmRlZmluZWQnICYmIHR5cGVvZiB3aW5kb3cubXNDcnlwdG8uZ2V0UmFuZG9tVmFsdWVzID09ICdmdW5jdGlvbicgJiYgbXNDcnlwdG8uZ2V0UmFuZG9tVmFsdWVzLmJpbmQobXNDcnlwdG8pKTtcblxuaWYgKGdldFJhbmRvbVZhbHVlcykge1xuICAvLyBXSEFUV0cgY3J5cHRvIFJORyAtIGh0dHA6Ly93aWtpLndoYXR3Zy5vcmcvd2lraS9DcnlwdG9cbiAgdmFyIHJuZHM4ID0gbmV3IFVpbnQ4QXJyYXkoMTYpOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXVuZGVmXG5cbiAgbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiB3aGF0d2dSTkcoKSB7XG4gICAgZ2V0UmFuZG9tVmFsdWVzKHJuZHM4KTtcbiAgICByZXR1cm4gcm5kczg7XG4gIH07XG59IGVsc2Uge1xuICAvLyBNYXRoLnJhbmRvbSgpLWJhc2VkIChSTkcpXG4gIC8vXG4gIC8vIElmIGFsbCBlbHNlIGZhaWxzLCB1c2UgTWF0aC5yYW5kb20oKS4gIEl0J3MgZmFzdCwgYnV0IGlzIG9mIHVuc3BlY2lmaWVkXG4gIC8vIHF1YWxpdHkuXG4gIHZhciBybmRzID0gbmV3IEFycmF5KDE2KTtcblxuICBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIG1hdGhSTkcoKSB7XG4gICAgZm9yICh2YXIgaSA9IDAsIHI7IGkgPCAxNjsgaSsrKSB7XG4gICAgICBpZiAoKGkgJiAweDAzKSA9PT0gMCkgciA9IE1hdGgucmFuZG9tKCkgKiAweDEwMDAwMDAwMDtcbiAgICAgIHJuZHNbaV0gPSByID4+PiAoKGkgJiAweDAzKSA8PCAzKSAmIDB4ZmY7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJuZHM7XG4gIH07XG59XG4iLCJ2YXIgcm5nID0gcmVxdWlyZSgnLi9saWIvcm5nJyk7XG52YXIgYnl0ZXNUb1V1aWQgPSByZXF1aXJlKCcuL2xpYi9ieXRlc1RvVXVpZCcpO1xuXG4vLyAqKmB2MSgpYCAtIEdlbmVyYXRlIHRpbWUtYmFzZWQgVVVJRCoqXG4vL1xuLy8gSW5zcGlyZWQgYnkgaHR0cHM6Ly9naXRodWIuY29tL0xpb3NLL1VVSUQuanNcbi8vIGFuZCBodHRwOi8vZG9jcy5weXRob24ub3JnL2xpYnJhcnkvdXVpZC5odG1sXG5cbnZhciBfbm9kZUlkO1xudmFyIF9jbG9ja3NlcTtcblxuLy8gUHJldmlvdXMgdXVpZCBjcmVhdGlvbiB0aW1lXG52YXIgX2xhc3RNU2VjcyA9IDA7XG52YXIgX2xhc3ROU2VjcyA9IDA7XG5cbi8vIFNlZSBodHRwczovL2dpdGh1Yi5jb20vYnJvb2ZhL25vZGUtdXVpZCBmb3IgQVBJIGRldGFpbHNcbmZ1bmN0aW9uIHYxKG9wdGlvbnMsIGJ1Ziwgb2Zmc2V0KSB7XG4gIHZhciBpID0gYnVmICYmIG9mZnNldCB8fCAwO1xuICB2YXIgYiA9IGJ1ZiB8fCBbXTtcblxuICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcbiAgdmFyIG5vZGUgPSBvcHRpb25zLm5vZGUgfHwgX25vZGVJZDtcbiAgdmFyIGNsb2Nrc2VxID0gb3B0aW9ucy5jbG9ja3NlcSAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy5jbG9ja3NlcSA6IF9jbG9ja3NlcTtcblxuICAvLyBub2RlIGFuZCBjbG9ja3NlcSBuZWVkIHRvIGJlIGluaXRpYWxpemVkIHRvIHJhbmRvbSB2YWx1ZXMgaWYgdGhleSdyZSBub3RcbiAgLy8gc3BlY2lmaWVkLiAgV2UgZG8gdGhpcyBsYXppbHkgdG8gbWluaW1pemUgaXNzdWVzIHJlbGF0ZWQgdG8gaW5zdWZmaWNpZW50XG4gIC8vIHN5c3RlbSBlbnRyb3B5LiAgU2VlICMxODlcbiAgaWYgKG5vZGUgPT0gbnVsbCB8fCBjbG9ja3NlcSA9PSBudWxsKSB7XG4gICAgdmFyIHNlZWRCeXRlcyA9IHJuZygpO1xuICAgIGlmIChub2RlID09IG51bGwpIHtcbiAgICAgIC8vIFBlciA0LjUsIGNyZWF0ZSBhbmQgNDgtYml0IG5vZGUgaWQsICg0NyByYW5kb20gYml0cyArIG11bHRpY2FzdCBiaXQgPSAxKVxuICAgICAgbm9kZSA9IF9ub2RlSWQgPSBbXG4gICAgICAgIHNlZWRCeXRlc1swXSB8IDB4MDEsXG4gICAgICAgIHNlZWRCeXRlc1sxXSwgc2VlZEJ5dGVzWzJdLCBzZWVkQnl0ZXNbM10sIHNlZWRCeXRlc1s0XSwgc2VlZEJ5dGVzWzVdXG4gICAgICBdO1xuICAgIH1cbiAgICBpZiAoY2xvY2tzZXEgPT0gbnVsbCkge1xuICAgICAgLy8gUGVyIDQuMi4yLCByYW5kb21pemUgKDE0IGJpdCkgY2xvY2tzZXFcbiAgICAgIGNsb2Nrc2VxID0gX2Nsb2Nrc2VxID0gKHNlZWRCeXRlc1s2XSA8PCA4IHwgc2VlZEJ5dGVzWzddKSAmIDB4M2ZmZjtcbiAgICB9XG4gIH1cblxuICAvLyBVVUlEIHRpbWVzdGFtcHMgYXJlIDEwMCBuYW5vLXNlY29uZCB1bml0cyBzaW5jZSB0aGUgR3JlZ29yaWFuIGVwb2NoLFxuICAvLyAoMTU4Mi0xMC0xNSAwMDowMCkuICBKU051bWJlcnMgYXJlbid0IHByZWNpc2UgZW5vdWdoIGZvciB0aGlzLCBzb1xuICAvLyB0aW1lIGlzIGhhbmRsZWQgaW50ZXJuYWxseSBhcyAnbXNlY3MnIChpbnRlZ2VyIG1pbGxpc2Vjb25kcykgYW5kICduc2VjcydcbiAgLy8gKDEwMC1uYW5vc2Vjb25kcyBvZmZzZXQgZnJvbSBtc2Vjcykgc2luY2UgdW5peCBlcG9jaCwgMTk3MC0wMS0wMSAwMDowMC5cbiAgdmFyIG1zZWNzID0gb3B0aW9ucy5tc2VjcyAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy5tc2VjcyA6IG5ldyBEYXRlKCkuZ2V0VGltZSgpO1xuXG4gIC8vIFBlciA0LjIuMS4yLCB1c2UgY291bnQgb2YgdXVpZCdzIGdlbmVyYXRlZCBkdXJpbmcgdGhlIGN1cnJlbnQgY2xvY2tcbiAgLy8gY3ljbGUgdG8gc2ltdWxhdGUgaGlnaGVyIHJlc29sdXRpb24gY2xvY2tcbiAgdmFyIG5zZWNzID0gb3B0aW9ucy5uc2VjcyAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy5uc2VjcyA6IF9sYXN0TlNlY3MgKyAxO1xuXG4gIC8vIFRpbWUgc2luY2UgbGFzdCB1dWlkIGNyZWF0aW9uIChpbiBtc2VjcylcbiAgdmFyIGR0ID0gKG1zZWNzIC0gX2xhc3RNU2VjcykgKyAobnNlY3MgLSBfbGFzdE5TZWNzKS8xMDAwMDtcblxuICAvLyBQZXIgNC4yLjEuMiwgQnVtcCBjbG9ja3NlcSBvbiBjbG9jayByZWdyZXNzaW9uXG4gIGlmIChkdCA8IDAgJiYgb3B0aW9ucy5jbG9ja3NlcSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgY2xvY2tzZXEgPSBjbG9ja3NlcSArIDEgJiAweDNmZmY7XG4gIH1cblxuICAvLyBSZXNldCBuc2VjcyBpZiBjbG9jayByZWdyZXNzZXMgKG5ldyBjbG9ja3NlcSkgb3Igd2UndmUgbW92ZWQgb250byBhIG5ld1xuICAvLyB0aW1lIGludGVydmFsXG4gIGlmICgoZHQgPCAwIHx8IG1zZWNzID4gX2xhc3RNU2VjcykgJiYgb3B0aW9ucy5uc2VjcyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgbnNlY3MgPSAwO1xuICB9XG5cbiAgLy8gUGVyIDQuMi4xLjIgVGhyb3cgZXJyb3IgaWYgdG9vIG1hbnkgdXVpZHMgYXJlIHJlcXVlc3RlZFxuICBpZiAobnNlY3MgPj0gMTAwMDApIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3V1aWQudjEoKTogQ2FuXFwndCBjcmVhdGUgbW9yZSB0aGFuIDEwTSB1dWlkcy9zZWMnKTtcbiAgfVxuXG4gIF9sYXN0TVNlY3MgPSBtc2VjcztcbiAgX2xhc3ROU2VjcyA9IG5zZWNzO1xuICBfY2xvY2tzZXEgPSBjbG9ja3NlcTtcblxuICAvLyBQZXIgNC4xLjQgLSBDb252ZXJ0IGZyb20gdW5peCBlcG9jaCB0byBHcmVnb3JpYW4gZXBvY2hcbiAgbXNlY3MgKz0gMTIyMTkyOTI4MDAwMDA7XG5cbiAgLy8gYHRpbWVfbG93YFxuICB2YXIgdGwgPSAoKG1zZWNzICYgMHhmZmZmZmZmKSAqIDEwMDAwICsgbnNlY3MpICUgMHgxMDAwMDAwMDA7XG4gIGJbaSsrXSA9IHRsID4+PiAyNCAmIDB4ZmY7XG4gIGJbaSsrXSA9IHRsID4+PiAxNiAmIDB4ZmY7XG4gIGJbaSsrXSA9IHRsID4+PiA4ICYgMHhmZjtcbiAgYltpKytdID0gdGwgJiAweGZmO1xuXG4gIC8vIGB0aW1lX21pZGBcbiAgdmFyIHRtaCA9IChtc2VjcyAvIDB4MTAwMDAwMDAwICogMTAwMDApICYgMHhmZmZmZmZmO1xuICBiW2krK10gPSB0bWggPj4+IDggJiAweGZmO1xuICBiW2krK10gPSB0bWggJiAweGZmO1xuXG4gIC8vIGB0aW1lX2hpZ2hfYW5kX3ZlcnNpb25gXG4gIGJbaSsrXSA9IHRtaCA+Pj4gMjQgJiAweGYgfCAweDEwOyAvLyBpbmNsdWRlIHZlcnNpb25cbiAgYltpKytdID0gdG1oID4+PiAxNiAmIDB4ZmY7XG5cbiAgLy8gYGNsb2NrX3NlcV9oaV9hbmRfcmVzZXJ2ZWRgIChQZXIgNC4yLjIgLSBpbmNsdWRlIHZhcmlhbnQpXG4gIGJbaSsrXSA9IGNsb2Nrc2VxID4+PiA4IHwgMHg4MDtcblxuICAvLyBgY2xvY2tfc2VxX2xvd2BcbiAgYltpKytdID0gY2xvY2tzZXEgJiAweGZmO1xuXG4gIC8vIGBub2RlYFxuICBmb3IgKHZhciBuID0gMDsgbiA8IDY7ICsrbikge1xuICAgIGJbaSArIG5dID0gbm9kZVtuXTtcbiAgfVxuXG4gIHJldHVybiBidWYgPyBidWYgOiBieXRlc1RvVXVpZChiKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB2MTtcbiIsInZhciBybmcgPSByZXF1aXJlKCcuL2xpYi9ybmcnKTtcbnZhciBieXRlc1RvVXVpZCA9IHJlcXVpcmUoJy4vbGliL2J5dGVzVG9VdWlkJyk7XG5cbmZ1bmN0aW9uIHY0KG9wdGlvbnMsIGJ1Ziwgb2Zmc2V0KSB7XG4gIHZhciBpID0gYnVmICYmIG9mZnNldCB8fCAwO1xuXG4gIGlmICh0eXBlb2Yob3B0aW9ucykgPT0gJ3N0cmluZycpIHtcbiAgICBidWYgPSBvcHRpb25zID09PSAnYmluYXJ5JyA/IG5ldyBBcnJheSgxNikgOiBudWxsO1xuICAgIG9wdGlvbnMgPSBudWxsO1xuICB9XG4gIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuXG4gIHZhciBybmRzID0gb3B0aW9ucy5yYW5kb20gfHwgKG9wdGlvbnMucm5nIHx8IHJuZykoKTtcblxuICAvLyBQZXIgNC40LCBzZXQgYml0cyBmb3IgdmVyc2lvbiBhbmQgYGNsb2NrX3NlcV9oaV9hbmRfcmVzZXJ2ZWRgXG4gIHJuZHNbNl0gPSAocm5kc1s2XSAmIDB4MGYpIHwgMHg0MDtcbiAgcm5kc1s4XSA9IChybmRzWzhdICYgMHgzZikgfCAweDgwO1xuXG4gIC8vIENvcHkgYnl0ZXMgdG8gYnVmZmVyLCBpZiBwcm92aWRlZFxuICBpZiAoYnVmKSB7XG4gICAgZm9yICh2YXIgaWkgPSAwOyBpaSA8IDE2OyArK2lpKSB7XG4gICAgICBidWZbaSArIGlpXSA9IHJuZHNbaWldO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBidWYgfHwgYnl0ZXNUb1V1aWQocm5kcyk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gdjQ7XG4iLCJcInVzZSBzdHJpY3RcIjtcblxuaW1wb3J0IENvbGxlY3Rpb24gZnJvbSBcIi4vY29sbGVjdGlvblwiO1xuaW1wb3J0IEJhc2VBZGFwdGVyIGZyb20gXCIuL2FkYXB0ZXJzL2Jhc2VcIjtcblxuY29uc3QgREVGQVVMVF9CVUNLRVRfTkFNRSA9IFwiZGVmYXVsdFwiO1xuY29uc3QgREVGQVVMVF9SRU1PVEUgPSBcImh0dHA6Ly9sb2NhbGhvc3Q6ODg4OC92MVwiO1xuY29uc3QgREVGQVVMVF9SRVRSWSA9IDE7XG5cbi8qKlxuICogS2ludG9CYXNlIGNsYXNzLlxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBLaW50b0Jhc2Uge1xuICAvKipcbiAgICogUHJvdmlkZXMgYSBwdWJsaWMgYWNjZXNzIHRvIHRoZSBiYXNlIGFkYXB0ZXIgY2xhc3MuIFVzZXJzIGNhbiBjcmVhdGUgYVxuICAgKiBjdXN0b20gREIgYWRhcHRlciBieSBleHRlbmRpbmcge0BsaW5rIEJhc2VBZGFwdGVyfS5cbiAgICpcbiAgICogQHR5cGUge09iamVjdH1cbiAgICovXG4gIHN0YXRpYyBnZXQgYWRhcHRlcnMoKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIEJhc2VBZGFwdGVyOiBCYXNlQWRhcHRlcixcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIFN5bmNocm9uaXphdGlvbiBzdHJhdGVnaWVzLiBBdmFpbGFibGUgc3RyYXRlZ2llcyBhcmU6XG4gICAqXG4gICAqIC0gYE1BTlVBTGA6IENvbmZsaWN0cyB3aWxsIGJlIHJlcG9ydGVkIGluIGEgZGVkaWNhdGVkIGFycmF5LlxuICAgKiAtIGBTRVJWRVJfV0lOU2A6IENvbmZsaWN0cyBhcmUgcmVzb2x2ZWQgdXNpbmcgcmVtb3RlIGRhdGEuXG4gICAqIC0gYENMSUVOVF9XSU5TYDogQ29uZmxpY3RzIGFyZSByZXNvbHZlZCB1c2luZyBsb2NhbCBkYXRhLlxuICAgKlxuICAgKiBAdHlwZSB7T2JqZWN0fVxuICAgKi9cbiAgc3RhdGljIGdldCBzeW5jU3RyYXRlZ3koKSB7XG4gICAgcmV0dXJuIENvbGxlY3Rpb24uc3RyYXRlZ3k7XG4gIH1cblxuICAvKipcbiAgICogQ29uc3RydWN0b3IuXG4gICAqXG4gICAqIE9wdGlvbnM6XG4gICAqIC0gYHtTdHJpbmd9YCAgICAgICBgcmVtb3RlYCAgICAgICAgIFRoZSBzZXJ2ZXIgVVJMIHRvIHVzZS5cbiAgICogLSBge1N0cmluZ31gICAgICAgIGBidWNrZXRgICAgICAgICAgVGhlIGNvbGxlY3Rpb24gYnVja2V0IG5hbWUuXG4gICAqIC0gYHtFdmVudEVtaXR0ZXJ9YCBgZXZlbnRzYCAgICAgICAgIEV2ZW50cyBoYW5kbGVyLlxuICAgKiAtIGB7QmFzZUFkYXB0ZXJ9YCAgYGFkYXB0ZXJgICAgICAgICBUaGUgYmFzZSBEQiBhZGFwdGVyIGNsYXNzLlxuICAgKiAtIGB7T2JqZWN0fWAgICAgICAgYGFkYXB0ZXJPcHRpb25zYCBPcHRpb25zIGdpdmVuIHRvIHRoZSBhZGFwdGVyLlxuICAgKiAtIGB7T2JqZWN0fWAgICAgICAgYGhlYWRlcnNgICAgICAgICBUaGUgSFRUUCBoZWFkZXJzIHRvIHVzZS5cbiAgICogLSBge09iamVjdH1gICAgICAgIGByZXRyeWAgICAgICAgICAgTnVtYmVyIG9mIHJldHJpZXMgd2hlbiB0aGUgc2VydmVyIGZhaWxzIHRvIHByb2Nlc3MgdGhlIHJlcXVlc3QgKGRlZmF1bHQ6IGAxYClcbiAgICogLSBge1N0cmluZ31gICAgICAgIGByZXF1ZXN0TW9kZWAgICAgVGhlIEhUVFAgQ09SUyBtb2RlIHRvIHVzZS5cbiAgICogLSBge051bWJlcn1gICAgICAgIGB0aW1lb3V0YCAgICAgICAgVGhlIHJlcXVlc3RzIHRpbWVvdXQgaW4gbXMgKGRlZmF1bHQ6IGA1MDAwYCkuXG4gICAqXG4gICAqIEBwYXJhbSAge09iamVjdH0gb3B0aW9ucyBUaGUgb3B0aW9ucyBvYmplY3QuXG4gICAqL1xuICBjb25zdHJ1Y3RvcihvcHRpb25zID0ge30pIHtcbiAgICBjb25zdCBkZWZhdWx0cyA9IHtcbiAgICAgIGJ1Y2tldDogREVGQVVMVF9CVUNLRVRfTkFNRSxcbiAgICAgIHJlbW90ZTogREVGQVVMVF9SRU1PVEUsXG4gICAgICByZXRyeTogREVGQVVMVF9SRVRSWSxcbiAgICB9O1xuICAgIHRoaXMuX29wdGlvbnMgPSB7IC4uLmRlZmF1bHRzLCAuLi5vcHRpb25zIH07XG4gICAgaWYgKCF0aGlzLl9vcHRpb25zLmFkYXB0ZXIpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIk5vIGFkYXB0ZXIgcHJvdmlkZWRcIik7XG4gICAgfVxuXG4gICAgY29uc3Qge1xuICAgICAgQXBpQ2xhc3MsXG4gICAgICBldmVudHMsXG4gICAgICBoZWFkZXJzLFxuICAgICAgcmVtb3RlLFxuICAgICAgcmVxdWVzdE1vZGUsXG4gICAgICByZXRyeSxcbiAgICAgIHRpbWVvdXQsXG4gICAgfSA9IHRoaXMuX29wdGlvbnM7XG5cbiAgICAvLyBwdWJsaWMgcHJvcGVydGllc1xuXG4gICAgLyoqXG4gICAgICogVGhlIGtpbnRvIEhUVFAgY2xpZW50IGluc3RhbmNlLlxuICAgICAqIEB0eXBlIHtLaW50b0NsaWVudH1cbiAgICAgKi9cbiAgICB0aGlzLmFwaSA9IG5ldyBBcGlDbGFzcyhyZW1vdGUsIHtcbiAgICAgIGV2ZW50cyxcbiAgICAgIGhlYWRlcnMsXG4gICAgICByZXF1ZXN0TW9kZSxcbiAgICAgIHJldHJ5LFxuICAgICAgdGltZW91dCxcbiAgICB9KTtcbiAgICAvKipcbiAgICAgKiBUaGUgZXZlbnQgZW1pdHRlciBpbnN0YW5jZS5cbiAgICAgKiBAdHlwZSB7RXZlbnRFbWl0dGVyfVxuICAgICAqL1xuICAgIHRoaXMuZXZlbnRzID0gdGhpcy5fb3B0aW9ucy5ldmVudHM7XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlcyBhIHtAbGluayBDb2xsZWN0aW9ufSBpbnN0YW5jZS4gVGhlIHNlY29uZCAob3B0aW9uYWwpIHBhcmFtZXRlclxuICAgKiB3aWxsIHNldCBjb2xsZWN0aW9uLWxldmVsIG9wdGlvbnMgbGlrZSBlLmcuIGByZW1vdGVUcmFuc2Zvcm1lcnNgLlxuICAgKlxuICAgKiBAcGFyYW0gIHtTdHJpbmd9IGNvbGxOYW1lIFRoZSBjb2xsZWN0aW9uIG5hbWUuXG4gICAqIEBwYXJhbSAge09iamVjdH0gW29wdGlvbnM9e31dICAgICAgICAgICAgICAgICBFeHRyYSBvcHRpb25zIG9yIG92ZXJyaWRlIGNsaWVudCdzIG9wdGlvbnMuXG4gICAqIEBwYXJhbSAge09iamVjdH0gW29wdGlvbnMuaWRTY2hlbWFdICAgICAgICAgICBJZFNjaGVtYSBpbnN0YW5jZSAoZGVmYXVsdDogVVVJRClcbiAgICogQHBhcmFtICB7T2JqZWN0fSBbb3B0aW9ucy5yZW1vdGVUcmFuc2Zvcm1lcnNdIEFycmF5PFJlbW90ZVRyYW5zZm9ybWVyPiAoZGVmYXVsdDogYFtdYF0pXG4gICAqIEBwYXJhbSAge09iamVjdH0gW29wdGlvbnMuaG9va3NdICAgICAgICAgICAgICBBcnJheTxIb29rPiAoZGVmYXVsdDogYFtdYF0pXG4gICAqIEBwYXJhbSAge09iamVjdH0gW29wdGlvbnMubG9jYWxGaWVsZHNdICAgICAgICBBcnJheTxGaWVsZD4gKGRlZmF1bHQ6IGBbXWBdKVxuICAgKiBAcmV0dXJuIHtDb2xsZWN0aW9ufVxuICAgKi9cbiAgY29sbGVjdGlvbihjb2xsTmFtZSwgb3B0aW9ucyA9IHt9KSB7XG4gICAgaWYgKCFjb2xsTmFtZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwibWlzc2luZyBjb2xsZWN0aW9uIG5hbWVcIik7XG4gICAgfVxuICAgIGNvbnN0IHsgYnVja2V0LCBldmVudHMsIGFkYXB0ZXIsIGFkYXB0ZXJPcHRpb25zIH0gPSB7XG4gICAgICAuLi50aGlzLl9vcHRpb25zLFxuICAgICAgLi4ub3B0aW9ucyxcbiAgICB9O1xuICAgIGNvbnN0IHsgaWRTY2hlbWEsIHJlbW90ZVRyYW5zZm9ybWVycywgaG9va3MsIGxvY2FsRmllbGRzIH0gPSBvcHRpb25zO1xuXG4gICAgcmV0dXJuIG5ldyBDb2xsZWN0aW9uKGJ1Y2tldCwgY29sbE5hbWUsIHRoaXMuYXBpLCB7XG4gICAgICBldmVudHMsXG4gICAgICBhZGFwdGVyLFxuICAgICAgYWRhcHRlck9wdGlvbnMsXG4gICAgICBpZFNjaGVtYSxcbiAgICAgIHJlbW90ZVRyYW5zZm9ybWVycyxcbiAgICAgIGhvb2tzLFxuICAgICAgbG9jYWxGaWVsZHMsXG4gICAgfSk7XG4gIH1cbn1cbiIsIlwidXNlIHN0cmljdFwiO1xuXG5pbXBvcnQgQmFzZUFkYXB0ZXIgZnJvbSBcIi4vYmFzZS5qc1wiO1xuaW1wb3J0IHtcbiAgZmlsdGVyT2JqZWN0LFxuICBvbWl0S2V5cyxcbiAgc29ydE9iamVjdHMsXG4gIGFycmF5RXF1YWwsXG4gIHRyYW5zZm9ybVN1Yk9iamVjdEZpbHRlcnMsXG59IGZyb20gXCIuLi91dGlsc1wiO1xuXG5jb25zdCBJTkRFWEVEX0ZJRUxEUyA9IFtcImlkXCIsIFwiX3N0YXR1c1wiLCBcImxhc3RfbW9kaWZpZWRcIl07XG5cbi8qKlxuICogU21hbGwgaGVscGVyIHRoYXQgd3JhcHMgdGhlIG9wZW5pbmcgb2YgYW4gSW5kZXhlZERCIGludG8gYSBQcm9taXNlLlxuICpcbiAqIEBwYXJhbSBkYm5hbWUgICAgICAgICAge1N0cmluZ30gICBUaGUgZGF0YWJhc2UgbmFtZS5cbiAqIEBwYXJhbSB2ZXJzaW9uICAgICAgICAge0ludGVnZXJ9ICBTY2hlbWEgdmVyc2lvblxuICogQHBhcmFtIG9udXBncmFkZW5lZWRlZCB7RnVuY3Rpb259IFRoZSBjYWxsYmFjayB0byBleGVjdXRlIGlmIHNjaGVtYSBpc1xuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1pc3Npbmcgb3IgZGlmZmVyZW50LlxuICogQHJldHVybiB7UHJvbWlzZTxJREJEYXRhYmFzZT59XG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBvcGVuKGRibmFtZSwgeyB2ZXJzaW9uLCBvbnVwZ3JhZGVuZWVkZWQgfSkge1xuICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgIGNvbnN0IHJlcXVlc3QgPSBpbmRleGVkREIub3BlbihkYm5hbWUsIHZlcnNpb24pO1xuICAgIHJlcXVlc3Qub251cGdyYWRlbmVlZGVkID0gZXZlbnQgPT4ge1xuICAgICAgY29uc3QgZGIgPSBldmVudC50YXJnZXQucmVzdWx0O1xuICAgICAgZGIub25lcnJvciA9IGV2ZW50ID0+IHJlamVjdChldmVudC50YXJnZXQuZXJyb3IpO1xuICAgICAgcmV0dXJuIG9udXBncmFkZW5lZWRlZChldmVudCk7XG4gICAgfTtcbiAgICByZXF1ZXN0Lm9uZXJyb3IgPSBldmVudCA9PiB7XG4gICAgICByZWplY3QoZXZlbnQudGFyZ2V0LmVycm9yKTtcbiAgICB9O1xuICAgIHJlcXVlc3Qub25zdWNjZXNzID0gZXZlbnQgPT4ge1xuICAgICAgY29uc3QgZGIgPSBldmVudC50YXJnZXQucmVzdWx0O1xuICAgICAgcmVzb2x2ZShkYik7XG4gICAgfTtcbiAgfSk7XG59XG5cbi8qKlxuICogSGVscGVyIHRvIHJ1biB0aGUgc3BlY2lmaWVkIGNhbGxiYWNrIGluIGEgc2luZ2xlIHRyYW5zYWN0aW9uIG9uIHRoZVxuICogc3BlY2lmaWVkIHN0b3JlLlxuICogVGhlIGhlbHBlciBmb2N1c2VzIG9uIHRyYW5zYWN0aW9uIHdyYXBwaW5nIGludG8gYSBwcm9taXNlLlxuICpcbiAqIEBwYXJhbSBkYiAgICAgICAgICAge0lEQkRhdGFiYXNlfSBUaGUgZGF0YWJhc2UgaW5zdGFuY2UuXG4gKiBAcGFyYW0gbmFtZSAgICAgICAgIHtTdHJpbmd9ICAgICAgVGhlIHN0b3JlIG5hbWUuXG4gKiBAcGFyYW0gY2FsbGJhY2sgICAgIHtGdW5jdGlvbn0gICAgVGhlIHBpZWNlIG9mIGNvZGUgdG8gZXhlY3V0ZSBpbiB0aGUgdHJhbnNhY3Rpb24uXG4gKiBAcGFyYW0gb3B0aW9ucyAgICAgIHtPYmplY3R9ICAgICAgT3B0aW9ucy5cbiAqIEBwYXJhbSBvcHRpb25zLm1vZGUge1N0cmluZ30gICAgICBUcmFuc2FjdGlvbiBtb2RlIChkZWZhdWx0OiByZWFkKS5cbiAqIEByZXR1cm4ge1Byb21pc2V9IGFueSB2YWx1ZSByZXR1cm5lZCBieSB0aGUgY2FsbGJhY2suXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBleGVjdXRlKGRiLCBuYW1lLCBjYWxsYmFjaywgb3B0aW9ucyA9IHt9KSB7XG4gIGNvbnN0IHsgbW9kZSB9ID0gb3B0aW9ucztcbiAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAvLyBPbiBTYWZhcmksIGNhbGxpbmcgSURCRGF0YWJhc2UudHJhbnNhY3Rpb24gd2l0aCBtb2RlID09IHVuZGVmaW5lZCByYWlzZXNcbiAgICAvLyBhIFR5cGVFcnJvci5cbiAgICBjb25zdCB0cmFuc2FjdGlvbiA9IG1vZGVcbiAgICAgID8gZGIudHJhbnNhY3Rpb24oW25hbWVdLCBtb2RlKVxuICAgICAgOiBkYi50cmFuc2FjdGlvbihbbmFtZV0pO1xuICAgIGNvbnN0IHN0b3JlID0gdHJhbnNhY3Rpb24ub2JqZWN0U3RvcmUobmFtZSk7XG5cbiAgICAvLyBMZXQgdGhlIGNhbGxiYWNrIGFib3J0IHRoaXMgdHJhbnNhY3Rpb24uXG4gICAgY29uc3QgYWJvcnQgPSBlID0+IHtcbiAgICAgIHRyYW5zYWN0aW9uLmFib3J0KCk7XG4gICAgICByZWplY3QoZSk7XG4gICAgfTtcbiAgICAvLyBFeGVjdXRlIHRoZSBzcGVjaWZpZWQgY2FsbGJhY2sgKipzeW5jaHJvbm91c2x5KiouXG4gICAgbGV0IHJlc3VsdDtcbiAgICB0cnkge1xuICAgICAgcmVzdWx0ID0gY2FsbGJhY2soc3RvcmUsIGFib3J0KTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBhYm9ydChlKTtcbiAgICB9XG4gICAgdHJhbnNhY3Rpb24ub25lcnJvciA9IGV2ZW50ID0+IHJlamVjdChldmVudC50YXJnZXQuZXJyb3IpO1xuICAgIHRyYW5zYWN0aW9uLm9uY29tcGxldGUgPSBldmVudCA9PiByZXNvbHZlKHJlc3VsdCk7XG4gIH0pO1xufVxuXG4vKipcbiAqIEhlbHBlciB0byB3cmFwIHRoZSBkZWxldGlvbiBvZiBhbiBJbmRleGVkREIgZGF0YWJhc2UgaW50byBhIHByb21pc2UuXG4gKlxuICogQHBhcmFtIGRiTmFtZSB7U3RyaW5nfSB0aGUgZGF0YWJhc2UgdG8gZGVsZXRlXG4gKiBAcmV0dXJuIHtQcm9taXNlfVxuICovXG5hc3luYyBmdW5jdGlvbiBkZWxldGVEYXRhYmFzZShkYk5hbWUpIHtcbiAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICBjb25zdCByZXF1ZXN0ID0gaW5kZXhlZERCLmRlbGV0ZURhdGFiYXNlKGRiTmFtZSk7XG4gICAgcmVxdWVzdC5vbnN1Y2Nlc3MgPSBldmVudCA9PiByZXNvbHZlKGV2ZW50LnRhcmdldCk7XG4gICAgcmVxdWVzdC5vbmVycm9yID0gZXZlbnQgPT4gcmVqZWN0KGV2ZW50LnRhcmdldC5lcnJvcik7XG4gIH0pO1xufVxuXG4vKipcbiAqIElEQiBjdXJzb3IgaGFuZGxlcnMuXG4gKiBAdHlwZSB7T2JqZWN0fVxuICovXG5jb25zdCBjdXJzb3JIYW5kbGVycyA9IHtcbiAgYWxsKGZpbHRlcnMsIGRvbmUpIHtcbiAgICBjb25zdCByZXN1bHRzID0gW107XG4gICAgcmV0dXJuIGV2ZW50ID0+IHtcbiAgICAgIGNvbnN0IGN1cnNvciA9IGV2ZW50LnRhcmdldC5yZXN1bHQ7XG4gICAgICBpZiAoY3Vyc29yKSB7XG4gICAgICAgIGNvbnN0IHsgdmFsdWUgfSA9IGN1cnNvcjtcbiAgICAgICAgaWYgKGZpbHRlck9iamVjdChmaWx0ZXJzLCB2YWx1ZSkpIHtcbiAgICAgICAgICByZXN1bHRzLnB1c2godmFsdWUpO1xuICAgICAgICB9XG4gICAgICAgIGN1cnNvci5jb250aW51ZSgpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZG9uZShyZXN1bHRzKTtcbiAgICAgIH1cbiAgICB9O1xuICB9LFxuXG4gIGluKHZhbHVlcywgZmlsdGVycywgZG9uZSkge1xuICAgIGNvbnN0IHJlc3VsdHMgPSBbXTtcbiAgICBsZXQgaSA9IDA7XG4gICAgcmV0dXJuIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgICBjb25zdCBjdXJzb3IgPSBldmVudC50YXJnZXQucmVzdWx0O1xuICAgICAgaWYgKCFjdXJzb3IpIHtcbiAgICAgICAgZG9uZShyZXN1bHRzKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgY29uc3QgeyBrZXksIHZhbHVlIH0gPSBjdXJzb3I7XG4gICAgICAvLyBga2V5YCBjYW4gYmUgYW4gYXJyYXkgb2YgdHdvIHZhbHVlcyAoc2VlIGBrZXlQYXRoYCBpbiBpbmRpY2VzIGRlZmluaXRpb25zKS5cbiAgICAgIC8vIGB2YWx1ZXNgIGNhbiBiZSBhbiBhcnJheSBvZiBhcnJheXMgaWYgd2UgZmlsdGVyIHVzaW5nIGFuIGluZGV4IHdob3NlIGtleSBwYXRoXG4gICAgICAvLyBpcyBhbiBhcnJheSAoZWcuIGBjdXJzb3JIYW5kbGVycy5pbihbW1wiYmlkL2NpZFwiLCA0Ml0sIFtcImJpZC9jaWRcIiwgNDNdXSwgLi4uKWApXG4gICAgICB3aGlsZSAoa2V5ID4gdmFsdWVzW2ldKSB7XG4gICAgICAgIC8vIFRoZSBjdXJzb3IgaGFzIHBhc3NlZCBiZXlvbmQgdGhpcyBrZXkuIENoZWNrIG5leHQuXG4gICAgICAgICsraTtcbiAgICAgICAgaWYgKGkgPT09IHZhbHVlcy5sZW5ndGgpIHtcbiAgICAgICAgICBkb25lKHJlc3VsdHMpOyAvLyBUaGVyZSBpcyBubyBuZXh0LiBTdG9wIHNlYXJjaGluZy5cbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGNvbnN0IGlzRXF1YWwgPSBBcnJheS5pc0FycmF5KGtleSlcbiAgICAgICAgPyBhcnJheUVxdWFsKGtleSwgdmFsdWVzW2ldKVxuICAgICAgICA6IGtleSA9PT0gdmFsdWVzW2ldO1xuICAgICAgaWYgKGlzRXF1YWwpIHtcbiAgICAgICAgaWYgKGZpbHRlck9iamVjdChmaWx0ZXJzLCB2YWx1ZSkpIHtcbiAgICAgICAgICByZXN1bHRzLnB1c2godmFsdWUpO1xuICAgICAgICB9XG4gICAgICAgIGN1cnNvci5jb250aW51ZSgpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY3Vyc29yLmNvbnRpbnVlKHZhbHVlc1tpXSk7XG4gICAgICB9XG4gICAgfTtcbiAgfSxcbn07XG5cbi8qKlxuICogQ3JlYXRlcyBhbiBJREIgcmVxdWVzdCBhbmQgYXR0YWNoIGl0IHRoZSBhcHByb3ByaWF0ZSBjdXJzb3IgZXZlbnQgaGFuZGxlciB0b1xuICogcGVyZm9ybSBhIGxpc3QgcXVlcnkuXG4gKlxuICogTXVsdGlwbGUgbWF0Y2hpbmcgdmFsdWVzIGFyZSBoYW5kbGVkIGJ5IHBhc3NpbmcgYW4gYXJyYXkuXG4gKlxuICogQHBhcmFtICB7U3RyaW5nfSAgICAgICAgICAgY2lkICAgICAgICBUaGUgY29sbGVjdGlvbiBpZCAoaWUuIGB7YmlkfS97Y2lkfWApXG4gKiBAcGFyYW0gIHtJREJTdG9yZX0gICAgICAgICBzdG9yZSAgICAgIFRoZSBJREIgc3RvcmUuXG4gKiBAcGFyYW0gIHtPYmplY3R9ICAgICAgICAgICBmaWx0ZXJzICAgIEZpbHRlciB0aGUgcmVjb3JkcyBieSBmaWVsZC5cbiAqIEBwYXJhbSAge0Z1bmN0aW9ufSAgICAgICAgIGRvbmUgICAgICAgVGhlIG9wZXJhdGlvbiBjb21wbGV0aW9uIGhhbmRsZXIuXG4gKiBAcmV0dXJuIHtJREJSZXF1ZXN0fVxuICovXG5mdW5jdGlvbiBjcmVhdGVMaXN0UmVxdWVzdChjaWQsIHN0b3JlLCBmaWx0ZXJzLCBkb25lKSB7XG4gIGNvbnN0IGZpbHRlckZpZWxkcyA9IE9iamVjdC5rZXlzKGZpbHRlcnMpO1xuXG4gIC8vIElmIG5vIGZpbHRlcnMsIGdldCBhbGwgcmVzdWx0cyBpbiBvbmUgYnVsay5cbiAgaWYgKGZpbHRlckZpZWxkcy5sZW5ndGggPT0gMCkge1xuICAgIGNvbnN0IHJlcXVlc3QgPSBzdG9yZS5pbmRleChcImNpZFwiKS5nZXRBbGwoSURCS2V5UmFuZ2Uub25seShjaWQpKTtcbiAgICByZXF1ZXN0Lm9uc3VjY2VzcyA9IGV2ZW50ID0+IGRvbmUoZXZlbnQudGFyZ2V0LnJlc3VsdCk7XG4gICAgcmV0dXJuIHJlcXVlc3Q7XG4gIH1cblxuICAvLyBJbnRyb3NwZWN0IGZpbHRlcnMgYW5kIGNoZWNrIGlmIHRoZXkgbGV2ZXJhZ2UgYW4gaW5kZXhlZCBmaWVsZC5cbiAgY29uc3QgaW5kZXhGaWVsZCA9IGZpbHRlckZpZWxkcy5maW5kKGZpZWxkID0+IHtcbiAgICByZXR1cm4gSU5ERVhFRF9GSUVMRFMuaW5jbHVkZXMoZmllbGQpO1xuICB9KTtcblxuICBpZiAoIWluZGV4RmllbGQpIHtcbiAgICAvLyBJdGVyYXRlIG9uIGFsbCByZWNvcmRzIGZvciB0aGlzIGNvbGxlY3Rpb24gKGllLiBjaWQpXG4gICAgY29uc3QgaXNTdWJRdWVyeSA9IE9iamVjdC5rZXlzKGZpbHRlcnMpLnNvbWUoa2V5ID0+IGtleS5pbmNsdWRlcyhcIi5cIikpOyAvLyAoaWUuIGZpbHRlcnM6IHtcImFydGljbGUudGl0bGVcIjogXCJoZWxsb1wifSlcbiAgICBpZiAoaXNTdWJRdWVyeSkge1xuICAgICAgY29uc3QgbmV3RmlsdGVyID0gdHJhbnNmb3JtU3ViT2JqZWN0RmlsdGVycyhmaWx0ZXJzKTtcbiAgICAgIGNvbnN0IHJlcXVlc3QgPSBzdG9yZS5pbmRleChcImNpZFwiKS5vcGVuQ3Vyc29yKElEQktleVJhbmdlLm9ubHkoY2lkKSk7XG4gICAgICByZXF1ZXN0Lm9uc3VjY2VzcyA9IGN1cnNvckhhbmRsZXJzLmFsbChuZXdGaWx0ZXIsIGRvbmUpO1xuICAgICAgcmV0dXJuIHJlcXVlc3Q7XG4gICAgfVxuXG4gICAgY29uc3QgcmVxdWVzdCA9IHN0b3JlLmluZGV4KFwiY2lkXCIpLm9wZW5DdXJzb3IoSURCS2V5UmFuZ2Uub25seShjaWQpKTtcbiAgICByZXF1ZXN0Lm9uc3VjY2VzcyA9IGN1cnNvckhhbmRsZXJzLmFsbChmaWx0ZXJzLCBkb25lKTtcbiAgICByZXR1cm4gcmVxdWVzdDtcbiAgfVxuICAvLyBJZiBgaW5kZXhGaWVsZGAgd2FzIHVzZWQgYWxyZWFkeSwgZG9uJ3QgZmlsdGVyIGFnYWluLlxuICBjb25zdCByZW1haW5pbmdGaWx0ZXJzID0gb21pdEtleXMoZmlsdGVycywgW2luZGV4RmllbGRdKTtcblxuICAvLyB2YWx1ZSBzcGVjaWZpZWQgaW4gdGhlIGZpbHRlciAoZWcuIGBmaWx0ZXJzOiB7IF9zdGF0dXM6IFtcImNyZWF0ZWRcIiwgXCJ1cGRhdGVkXCJdIH1gKVxuICBjb25zdCB2YWx1ZSA9IGZpbHRlcnNbaW5kZXhGaWVsZF07XG4gIC8vIEZvciB0aGUgXCJpZFwiIGZpZWxkLCB1c2UgdGhlIHByaW1hcnkga2V5LlxuICBjb25zdCBpbmRleFN0b3JlID0gaW5kZXhGaWVsZCA9PSBcImlkXCIgPyBzdG9yZSA6IHN0b3JlLmluZGV4KGluZGV4RmllbGQpO1xuXG4gIC8vIFdIRVJFIElOIGVxdWl2YWxlbnQgY2xhdXNlXG4gIGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuICAgIGlmICh2YWx1ZS5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiBkb25lKFtdKTtcbiAgICB9XG4gICAgY29uc3QgdmFsdWVzID0gdmFsdWUubWFwKGkgPT4gW2NpZCwgaV0pLnNvcnQoKTtcbiAgICBjb25zdCByYW5nZSA9IElEQktleVJhbmdlLmJvdW5kKHZhbHVlc1swXSwgdmFsdWVzW3ZhbHVlcy5sZW5ndGggLSAxXSk7XG4gICAgY29uc3QgcmVxdWVzdCA9IGluZGV4U3RvcmUub3BlbkN1cnNvcihyYW5nZSk7XG4gICAgcmVxdWVzdC5vbnN1Y2Nlc3MgPSBjdXJzb3JIYW5kbGVycy5pbih2YWx1ZXMsIHJlbWFpbmluZ0ZpbHRlcnMsIGRvbmUpO1xuICAgIHJldHVybiByZXF1ZXN0O1xuICB9XG5cbiAgLy8gSWYgbm8gZmlsdGVycyBvbiBjdXN0b20gYXR0cmlidXRlLCBnZXQgYWxsIHJlc3VsdHMgaW4gb25lIGJ1bGsuXG4gIGlmIChyZW1haW5pbmdGaWx0ZXJzLmxlbmd0aCA9PSAwKSB7XG4gICAgY29uc3QgcmVxdWVzdCA9IGluZGV4U3RvcmUuZ2V0QWxsKElEQktleVJhbmdlLm9ubHkoW2NpZCwgdmFsdWVdKSk7XG4gICAgcmVxdWVzdC5vbnN1Y2Nlc3MgPSBldmVudCA9PiBkb25lKGV2ZW50LnRhcmdldC5yZXN1bHQpO1xuICAgIHJldHVybiByZXF1ZXN0O1xuICB9XG5cbiAgLy8gV0hFUkUgZmllbGQgPSB2YWx1ZSBjbGF1c2VcbiAgY29uc3QgcmVxdWVzdCA9IGluZGV4U3RvcmUub3BlbkN1cnNvcihJREJLZXlSYW5nZS5vbmx5KFtjaWQsIHZhbHVlXSkpO1xuICByZXF1ZXN0Lm9uc3VjY2VzcyA9IGN1cnNvckhhbmRsZXJzLmFsbChyZW1haW5pbmdGaWx0ZXJzLCBkb25lKTtcbiAgcmV0dXJuIHJlcXVlc3Q7XG59XG5cbi8qKlxuICogSW5kZXhlZERCIGFkYXB0ZXIuXG4gKlxuICogVGhpcyBhZGFwdGVyIGRvZXNuJ3Qgc3VwcG9ydCBhbnkgb3B0aW9ucy5cbiAqL1xuZXhwb3J0IGRlZmF1bHQgY2xhc3MgSURCIGV4dGVuZHMgQmFzZUFkYXB0ZXIge1xuICAvKipcbiAgICogQ29uc3RydWN0b3IuXG4gICAqXG4gICAqIEBwYXJhbSAge1N0cmluZ30gY2lkICBUaGUga2V5IGJhc2UgZm9yIHRoaXMgY29sbGVjdGlvbiAoZWcuIGBiaWQvY2lkYClcbiAgICogQHBhcmFtICB7T2JqZWN0fSBvcHRpb25zXG4gICAqIEBwYXJhbSAge1N0cmluZ30gb3B0aW9ucy5kYk5hbWUgICAgICAgICBUaGUgSW5kZXhlZERCIG5hbWUgKGRlZmF1bHQ6IGBcIktpbnRvREJcImApXG4gICAqIEBwYXJhbSAge1N0cmluZ30gb3B0aW9ucy5taWdyYXRlT2xkRGF0YSBXaGV0aGVyIG9sZCBkYXRhYmFzZSBkYXRhIHNob3VsZCBiZSBtaWdyYXRlZCAoZGVmYXVsdDogYGZhbHNlYClcbiAgICovXG4gIGNvbnN0cnVjdG9yKGNpZCwgb3B0aW9ucyA9IHt9KSB7XG4gICAgc3VwZXIoKTtcblxuICAgIHRoaXMuY2lkID0gY2lkO1xuICAgIHRoaXMuZGJOYW1lID0gb3B0aW9ucy5kYk5hbWUgfHwgXCJLaW50b0RCXCI7XG5cbiAgICB0aGlzLl9vcHRpb25zID0gb3B0aW9ucztcbiAgICB0aGlzLl9kYiA9IG51bGw7XG4gIH1cblxuICBfaGFuZGxlRXJyb3IobWV0aG9kLCBlcnIpIHtcbiAgICBjb25zdCBlcnJvciA9IG5ldyBFcnJvcihgSW5kZXhlZERCICR7bWV0aG9kfSgpICR7ZXJyLm1lc3NhZ2V9YCk7XG4gICAgZXJyb3Iuc3RhY2sgPSBlcnIuc3RhY2s7XG4gICAgdGhyb3cgZXJyb3I7XG4gIH1cblxuICAvKipcbiAgICogRW5zdXJlcyBhIGNvbm5lY3Rpb24gdG8gdGhlIEluZGV4ZWREQiBkYXRhYmFzZSBoYXMgYmVlbiBvcGVuZWQuXG4gICAqXG4gICAqIEBvdmVycmlkZVxuICAgKiBAcmV0dXJuIHtQcm9taXNlfVxuICAgKi9cbiAgYXN5bmMgb3BlbigpIHtcbiAgICBpZiAodGhpcy5fZGIpIHtcbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIC8vIEluIHByZXZpb3VzIHZlcnNpb25zLCB3ZSB1c2VkIHRvIGhhdmUgYSBkYXRhYmFzZSB3aXRoIG5hbWUgYCR7YmlkfS8ke2NpZH1gLlxuICAgIC8vIENoZWNrIGlmIGl0IGV4aXN0cywgYW5kIG1pZ3JhdGUgZGF0YSBvbmNlIG5ldyBzY2hlbWEgaXMgaW4gcGxhY2UuXG4gICAgLy8gTm90ZTogdGhlIGJ1aWx0LWluIG1pZ3JhdGlvbnMgZnJvbSBJbmRleGVkREIgY2FuIG9ubHkgYmUgdXNlZCBpZiB0aGVcbiAgICAvLyBkYXRhYmFzZSBuYW1lIGRvZXMgbm90IGNoYW5nZS5cbiAgICBjb25zdCBkYXRhVG9NaWdyYXRlID0gdGhpcy5fb3B0aW9ucy5taWdyYXRlT2xkRGF0YVxuICAgICAgPyBhd2FpdCBtaWdyYXRpb25SZXF1aXJlZCh0aGlzLmNpZClcbiAgICAgIDogbnVsbDtcblxuICAgIHRoaXMuX2RiID0gYXdhaXQgb3Blbih0aGlzLmRiTmFtZSwge1xuICAgICAgdmVyc2lvbjogMixcbiAgICAgIG9udXBncmFkZW5lZWRlZDogZXZlbnQgPT4ge1xuICAgICAgICBjb25zdCBkYiA9IGV2ZW50LnRhcmdldC5yZXN1bHQ7XG5cbiAgICAgICAgaWYgKGV2ZW50Lm9sZFZlcnNpb24gPCAxKSB7XG4gICAgICAgICAgLy8gUmVjb3JkcyBzdG9yZVxuICAgICAgICAgIGNvbnN0IHJlY29yZHNTdG9yZSA9IGRiLmNyZWF0ZU9iamVjdFN0b3JlKFwicmVjb3Jkc1wiLCB7XG4gICAgICAgICAgICBrZXlQYXRoOiBbXCJfY2lkXCIsIFwiaWRcIl0sXG4gICAgICAgICAgfSk7XG4gICAgICAgICAgLy8gQW4gaW5kZXggdG8gb2J0YWluIGFsbCB0aGUgcmVjb3JkcyBpbiBhIGNvbGxlY3Rpb24uXG4gICAgICAgICAgcmVjb3Jkc1N0b3JlLmNyZWF0ZUluZGV4KFwiY2lkXCIsIFwiX2NpZFwiKTtcbiAgICAgICAgICAvLyBIZXJlIHdlIGNyZWF0ZSBpbmRpY2VzIGZvciBldmVyeSBrbm93biBmaWVsZCBpbiByZWNvcmRzIGJ5IGNvbGxlY3Rpb24uXG4gICAgICAgICAgLy8gTG9jYWwgcmVjb3JkIHN0YXR1cyAoXCJzeW5jZWRcIiwgXCJjcmVhdGVkXCIsIFwidXBkYXRlZFwiLCBcImRlbGV0ZWRcIilcbiAgICAgICAgICByZWNvcmRzU3RvcmUuY3JlYXRlSW5kZXgoXCJfc3RhdHVzXCIsIFtcIl9jaWRcIiwgXCJfc3RhdHVzXCJdKTtcbiAgICAgICAgICAvLyBMYXN0IG1vZGlmaWVkIGZpZWxkXG4gICAgICAgICAgcmVjb3Jkc1N0b3JlLmNyZWF0ZUluZGV4KFwibGFzdF9tb2RpZmllZFwiLCBbXCJfY2lkXCIsIFwibGFzdF9tb2RpZmllZFwiXSk7XG4gICAgICAgICAgLy8gVGltZXN0YW1wcyBzdG9yZVxuICAgICAgICAgIGRiLmNyZWF0ZU9iamVjdFN0b3JlKFwidGltZXN0YW1wc1wiLCB7XG4gICAgICAgICAgICBrZXlQYXRoOiBcImNpZFwiLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGV2ZW50Lm9sZFZlcnNpb24gPCAyKSB7XG4gICAgICAgICAgLy8gQ29sbGVjdGlvbnMgc3RvcmVcbiAgICAgICAgICBkYi5jcmVhdGVPYmplY3RTdG9yZShcImNvbGxlY3Rpb25zXCIsIHtcbiAgICAgICAgICAgIGtleVBhdGg6IFwiY2lkXCIsXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgfSk7XG5cbiAgICBpZiAoZGF0YVRvTWlncmF0ZSkge1xuICAgICAgY29uc3QgeyByZWNvcmRzLCB0aW1lc3RhbXAgfSA9IGRhdGFUb01pZ3JhdGU7XG4gICAgICBhd2FpdCB0aGlzLmltcG9ydEJ1bGsocmVjb3Jkcyk7XG4gICAgICBhd2FpdCB0aGlzLnNhdmVMYXN0TW9kaWZpZWQodGltZXN0YW1wKTtcbiAgICAgIGNvbnNvbGUubG9nKGAke3RoaXMuY2lkfTogZGF0YSB3YXMgbWlncmF0ZWQgc3VjY2Vzc2Z1bGx5LmApO1xuICAgICAgLy8gRGVsZXRlIHRoZSBvbGQgZGF0YWJhc2UuXG4gICAgICBhd2FpdCBkZWxldGVEYXRhYmFzZSh0aGlzLmNpZCk7XG4gICAgICBjb25zb2xlLndhcm4oYCR7dGhpcy5jaWR9OiBvbGQgZGF0YWJhc2Ugd2FzIGRlbGV0ZWQuYCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvKipcbiAgICogQ2xvc2VzIGN1cnJlbnQgY29ubmVjdGlvbiB0byB0aGUgZGF0YWJhc2UuXG4gICAqXG4gICAqIEBvdmVycmlkZVxuICAgKiBAcmV0dXJuIHtQcm9taXNlfVxuICAgKi9cbiAgY2xvc2UoKSB7XG4gICAgaWYgKHRoaXMuX2RiKSB7XG4gICAgICB0aGlzLl9kYi5jbG9zZSgpOyAvLyBpbmRleGVkREIuY2xvc2UgaXMgc3luY2hyb25vdXNcbiAgICAgIHRoaXMuX2RiID0gbnVsbDtcbiAgICB9XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgYSB0cmFuc2FjdGlvbiBhbmQgYW4gb2JqZWN0IHN0b3JlIGZvciBhIHN0b3JlIG5hbWUuXG4gICAqXG4gICAqIFRvIGRldGVybWluZSBpZiBhIHRyYW5zYWN0aW9uIGhhcyBjb21wbGV0ZWQgc3VjY2Vzc2Z1bGx5LCB3ZSBzaG91bGQgcmF0aGVyXG4gICAqIGxpc3RlbiB0byB0aGUgdHJhbnNhY3Rpb27igJlzIGNvbXBsZXRlIGV2ZW50IHJhdGhlciB0aGFuIHRoZSBJREJPYmplY3RTdG9yZVxuICAgKiByZXF1ZXN04oCZcyBzdWNjZXNzIGV2ZW50LCBiZWNhdXNlIHRoZSB0cmFuc2FjdGlvbiBtYXkgc3RpbGwgZmFpbCBhZnRlciB0aGVcbiAgICogc3VjY2VzcyBldmVudCBmaXJlcy5cbiAgICpcbiAgICogQHBhcmFtICB7U3RyaW5nfSAgICAgIG5hbWUgIFN0b3JlIG5hbWVcbiAgICogQHBhcmFtICB7RnVuY3Rpb259ICAgIGNhbGxiYWNrIHRvIGV4ZWN1dGVcbiAgICogQHBhcmFtICB7T2JqZWN0fSAgICAgIG9wdGlvbnMgT3B0aW9uc1xuICAgKiBAcGFyYW0gIHtTdHJpbmd9ICAgICAgb3B0aW9ucy5tb2RlICBUcmFuc2FjdGlvbiBtb2RlIChcInJlYWR3cml0ZVwiIG9yIHVuZGVmaW5lZClcbiAgICogQHJldHVybiB7T2JqZWN0fVxuICAgKi9cbiAgYXN5bmMgcHJlcGFyZShuYW1lLCBjYWxsYmFjaywgb3B0aW9ucykge1xuICAgIGF3YWl0IHRoaXMub3BlbigpO1xuICAgIGF3YWl0IGV4ZWN1dGUodGhpcy5fZGIsIG5hbWUsIGNhbGxiYWNrLCBvcHRpb25zKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBEZWxldGVzIGV2ZXJ5IHJlY29yZHMgaW4gdGhlIGN1cnJlbnQgY29sbGVjdGlvbi5cbiAgICpcbiAgICogQG92ZXJyaWRlXG4gICAqIEByZXR1cm4ge1Byb21pc2V9XG4gICAqL1xuICBhc3luYyBjbGVhcigpIHtcbiAgICB0cnkge1xuICAgICAgYXdhaXQgdGhpcy5wcmVwYXJlKFxuICAgICAgICBcInJlY29yZHNcIixcbiAgICAgICAgc3RvcmUgPT4ge1xuICAgICAgICAgIGNvbnN0IHJhbmdlID0gSURCS2V5UmFuZ2Uub25seSh0aGlzLmNpZCk7XG4gICAgICAgICAgY29uc3QgcmVxdWVzdCA9IHN0b3JlLmluZGV4KFwiY2lkXCIpLm9wZW5LZXlDdXJzb3IocmFuZ2UpO1xuICAgICAgICAgIHJlcXVlc3Qub25zdWNjZXNzID0gZXZlbnQgPT4ge1xuICAgICAgICAgICAgY29uc3QgY3Vyc29yID0gZXZlbnQudGFyZ2V0LnJlc3VsdDtcbiAgICAgICAgICAgIGlmIChjdXJzb3IpIHtcbiAgICAgICAgICAgICAgc3RvcmUuZGVsZXRlKGN1cnNvci5wcmltYXJ5S2V5KTtcbiAgICAgICAgICAgICAgY3Vyc29yLmNvbnRpbnVlKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfTtcbiAgICAgICAgICByZXR1cm4gcmVxdWVzdDtcbiAgICAgICAgfSxcbiAgICAgICAgeyBtb2RlOiBcInJlYWR3cml0ZVwiIH1cbiAgICAgICk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgdGhpcy5faGFuZGxlRXJyb3IoXCJjbGVhclwiLCBlKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogRXhlY3V0ZXMgdGhlIHNldCBvZiBzeW5jaHJvbm91cyBDUlVEIG9wZXJhdGlvbnMgZGVzY3JpYmVkIGluIHRoZSBwcm92aWRlZFxuICAgKiBjYWxsYmFjayB3aXRoaW4gYW4gSW5kZXhlZERCIHRyYW5zYWN0aW9uLCBmb3IgY3VycmVudCBkYiBzdG9yZS5cbiAgICpcbiAgICogVGhlIGNhbGxiYWNrIHdpbGwgYmUgcHJvdmlkZWQgYW4gb2JqZWN0IGV4cG9zaW5nIHRoZSBmb2xsb3dpbmcgc3luY2hyb25vdXNcbiAgICogQ1JVRCBvcGVyYXRpb24gbWV0aG9kczogZ2V0LCBjcmVhdGUsIHVwZGF0ZSwgZGVsZXRlLlxuICAgKlxuICAgKiBJbXBvcnRhbnQgbm90ZTogYmVjYXVzZSBsaW1pdGF0aW9ucyBpbiBJbmRleGVkREIgaW1wbGVtZW50YXRpb25zLCBub1xuICAgKiBhc3luY2hyb25vdXMgY29kZSBzaG91bGQgYmUgcGVyZm9ybWVkIHdpdGhpbiB0aGUgcHJvdmlkZWQgY2FsbGJhY2s7IHRoZVxuICAgKiBwcm9taXNlIHdpbGwgdGhlcmVmb3JlIGJlIHJlamVjdGVkIGlmIHRoZSBjYWxsYmFjayByZXR1cm5zIGEgUHJvbWlzZS5cbiAgICpcbiAgICogT3B0aW9uczpcbiAgICogLSB7QXJyYXl9IHByZWxvYWQ6IFRoZSBsaXN0IG9mIHJlY29yZCBJRHMgdG8gZmV0Y2ggYW5kIG1ha2UgYXZhaWxhYmxlIHRvXG4gICAqICAgdGhlIHRyYW5zYWN0aW9uIG9iamVjdCBnZXQoKSBtZXRob2QgKGRlZmF1bHQ6IFtdKVxuICAgKlxuICAgKiBAZXhhbXBsZVxuICAgKiBjb25zdCBkYiA9IG5ldyBJREIoXCJleGFtcGxlXCIpO1xuICAgKiBjb25zdCByZXN1bHQgPSBhd2FpdCBkYi5leGVjdXRlKHRyYW5zYWN0aW9uID0+IHtcbiAgICogICB0cmFuc2FjdGlvbi5jcmVhdGUoe2lkOiAxLCB0aXRsZTogXCJmb29cIn0pO1xuICAgKiAgIHRyYW5zYWN0aW9uLnVwZGF0ZSh7aWQ6IDIsIHRpdGxlOiBcImJhclwifSk7XG4gICAqICAgdHJhbnNhY3Rpb24uZGVsZXRlKDMpO1xuICAgKiAgIHJldHVybiBcImZvb1wiO1xuICAgKiB9KTtcbiAgICpcbiAgICogQG92ZXJyaWRlXG4gICAqIEBwYXJhbSAge0Z1bmN0aW9ufSBjYWxsYmFjayBUaGUgb3BlcmF0aW9uIGRlc2NyaXB0aW9uIGNhbGxiYWNrLlxuICAgKiBAcGFyYW0gIHtPYmplY3R9ICAgb3B0aW9ucyAgVGhlIG9wdGlvbnMgb2JqZWN0LlxuICAgKiBAcmV0dXJuIHtQcm9taXNlfVxuICAgKi9cbiAgYXN5bmMgZXhlY3V0ZShjYWxsYmFjaywgb3B0aW9ucyA9IHsgcHJlbG9hZDogW10gfSkge1xuICAgIC8vIFRyYW5zYWN0aW9ucyBpbiBJbmRleGVkREIgYXJlIGF1dG9jb21taXRlZCB3aGVuIGEgY2FsbGJhY2sgZG9lcyBub3RcbiAgICAvLyBwZXJmb3JtIGFueSBhZGRpdGlvbmFsIG9wZXJhdGlvbi5cbiAgICAvLyBUaGUgd2F5IFByb21pc2VzIGFyZSBpbXBsZW1lbnRlZCBpbiBGaXJlZm94IChzZWUgaHR0cHM6Ly9idWd6aWxsYS5tb3ppbGxhLm9yZy9zaG93X2J1Zy5jZ2k/aWQ9MTE5MzM5NClcbiAgICAvLyBwcmV2ZW50cyB1c2luZyB3aXRoaW4gYW4gb3BlbmVkIHRyYW5zYWN0aW9uLlxuICAgIC8vIFRvIGF2b2lkIG1hbmFnaW5nIGFzeW5jaHJvbm9jaXR5IGluIHRoZSBzcGVjaWZpZWQgYGNhbGxiYWNrYCwgd2UgcHJlbG9hZFxuICAgIC8vIGEgbGlzdCBvZiByZWNvcmQgaW4gb3JkZXIgdG8gZXhlY3V0ZSB0aGUgYGNhbGxiYWNrYCBzeW5jaHJvbm91c2x5LlxuICAgIC8vIFNlZSBhbHNvOlxuICAgIC8vIC0gaHR0cDovL3N0YWNrb3ZlcmZsb3cuY29tL2EvMjgzODg4MDUvMzMwOTExXG4gICAgLy8gLSBodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vYS8xMDQwNTE5NlxuICAgIC8vIC0gaHR0cHM6Ly9qYWtlYXJjaGliYWxkLmNvbS8yMDE1L3Rhc2tzLW1pY3JvdGFza3MtcXVldWVzLWFuZC1zY2hlZHVsZXMvXG4gICAgbGV0IHJlc3VsdDtcbiAgICBhd2FpdCB0aGlzLnByZXBhcmUoXG4gICAgICBcInJlY29yZHNcIixcbiAgICAgIChzdG9yZSwgYWJvcnQpID0+IHtcbiAgICAgICAgY29uc3QgcnVuQ2FsbGJhY2sgPSAocHJlbG9hZGVkID0gW10pID0+IHtcbiAgICAgICAgICAvLyBFeHBvc2UgYSBjb25zaXN0ZW50IEFQSSBmb3IgZXZlcnkgYWRhcHRlciBpbnN0ZWFkIG9mIHJhdyBzdG9yZSBtZXRob2RzLlxuICAgICAgICAgIGNvbnN0IHByb3h5ID0gdHJhbnNhY3Rpb25Qcm94eSh0aGlzLCBzdG9yZSwgcHJlbG9hZGVkKTtcbiAgICAgICAgICAvLyBUaGUgY2FsbGJhY2sgaXMgZXhlY3V0ZWQgc3luY2hyb25vdXNseSB3aXRoaW4gdGhlIHNhbWUgdHJhbnNhY3Rpb24uXG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGNvbnN0IHJldHVybmVkID0gY2FsbGJhY2socHJveHkpO1xuICAgICAgICAgICAgaWYgKHJldHVybmVkIGluc3RhbmNlb2YgUHJvbWlzZSkge1xuICAgICAgICAgICAgICAvLyBYWFg6IGludmVzdGlnYXRlIGhvdyB0byBwcm92aWRlIGRvY3VtZW50YXRpb24gZGV0YWlscyBpbiBlcnJvci5cbiAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgICAgICAgIFwiZXhlY3V0ZSgpIGNhbGxiYWNrIHNob3VsZCBub3QgcmV0dXJuIGEgUHJvbWlzZS5cIlxuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gQnJpbmcgdG8gc2NvcGUgdGhhdCB3aWxsIGJlIHJldHVybmVkIChvbmNlIHByb21pc2UgYXdhaXRlZCkuXG4gICAgICAgICAgICByZXN1bHQgPSByZXR1cm5lZDtcbiAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAvLyBUaGUgY2FsbGJhY2sgaGFzIHRocm93biBhbiBlcnJvciBleHBsaWNpdGx5LiBBYm9ydCB0cmFuc2FjdGlvbiBjbGVhbmx5LlxuICAgICAgICAgICAgYWJvcnQoZSk7XG4gICAgICAgICAgfVxuICAgICAgICB9O1xuXG4gICAgICAgIC8vIE5vIG9wdGlvbiB0byBwcmVsb2FkIHJlY29yZHMsIGdvIHN0cmFpZ2h0IHRvIGBjYWxsYmFja2AuXG4gICAgICAgIGlmICghb3B0aW9ucy5wcmVsb2FkLmxlbmd0aCkge1xuICAgICAgICAgIHJldHVybiBydW5DYWxsYmFjaygpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gUHJlbG9hZCBzcGVjaWZpZWQgcmVjb3JkcyB1c2luZyBhIGxpc3QgcmVxdWVzdC5cbiAgICAgICAgY29uc3QgZmlsdGVycyA9IHsgaWQ6IG9wdGlvbnMucHJlbG9hZCB9O1xuICAgICAgICBjcmVhdGVMaXN0UmVxdWVzdCh0aGlzLmNpZCwgc3RvcmUsIGZpbHRlcnMsIHJlY29yZHMgPT4ge1xuICAgICAgICAgIC8vIFN0b3JlIG9idGFpbmVkIHJlY29yZHMgYnkgaWQuXG4gICAgICAgICAgY29uc3QgcHJlbG9hZGVkID0ge307XG4gICAgICAgICAgZm9yIChjb25zdCByZWNvcmQgb2YgcmVjb3Jkcykge1xuICAgICAgICAgICAgZGVsZXRlIHJlY29yZFtcIl9jaWRcIl07XG4gICAgICAgICAgICBwcmVsb2FkZWRbcmVjb3JkLmlkXSA9IHJlY29yZDtcbiAgICAgICAgICB9XG4gICAgICAgICAgcnVuQ2FsbGJhY2socHJlbG9hZGVkKTtcbiAgICAgICAgfSk7XG4gICAgICB9LFxuICAgICAgeyBtb2RlOiBcInJlYWR3cml0ZVwiIH1cbiAgICApO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICAvKipcbiAgICogUmV0cmlldmUgYSByZWNvcmQgYnkgaXRzIHByaW1hcnkga2V5IGZyb20gdGhlIEluZGV4ZWREQiBkYXRhYmFzZS5cbiAgICpcbiAgICogQG92ZXJyaWRlXG4gICAqIEBwYXJhbSAge1N0cmluZ30gaWQgVGhlIHJlY29yZCBpZC5cbiAgICogQHJldHVybiB7UHJvbWlzZX1cbiAgICovXG4gIGFzeW5jIGdldChpZCkge1xuICAgIHRyeSB7XG4gICAgICBsZXQgcmVjb3JkO1xuICAgICAgYXdhaXQgdGhpcy5wcmVwYXJlKFwicmVjb3Jkc1wiLCBzdG9yZSA9PiB7XG4gICAgICAgIHN0b3JlLmdldChbdGhpcy5jaWQsIGlkXSkub25zdWNjZXNzID0gZSA9PiAocmVjb3JkID0gZS50YXJnZXQucmVzdWx0KTtcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIHJlY29yZDtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICB0aGlzLl9oYW5kbGVFcnJvcihcImdldFwiLCBlKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogTGlzdHMgYWxsIHJlY29yZHMgZnJvbSB0aGUgSW5kZXhlZERCIGRhdGFiYXNlLlxuICAgKlxuICAgKiBAb3ZlcnJpZGVcbiAgICogQHBhcmFtICB7T2JqZWN0fSBwYXJhbXMgIFRoZSBmaWx0ZXJzIGFuZCBvcmRlciB0byBhcHBseSB0byB0aGUgcmVzdWx0cy5cbiAgICogQHJldHVybiB7UHJvbWlzZX1cbiAgICovXG4gIGFzeW5jIGxpc3QocGFyYW1zID0geyBmaWx0ZXJzOiB7fSB9KSB7XG4gICAgY29uc3QgeyBmaWx0ZXJzIH0gPSBwYXJhbXM7XG4gICAgdHJ5IHtcbiAgICAgIGxldCByZXN1bHRzID0gW107XG4gICAgICBhd2FpdCB0aGlzLnByZXBhcmUoXCJyZWNvcmRzXCIsIHN0b3JlID0+IHtcbiAgICAgICAgY3JlYXRlTGlzdFJlcXVlc3QodGhpcy5jaWQsIHN0b3JlLCBmaWx0ZXJzLCBfcmVzdWx0cyA9PiB7XG4gICAgICAgICAgLy8gd2UgaGF2ZSByZWNlaXZlZCBhbGwgcmVxdWVzdGVkIHJlY29yZHMgdGhhdCBtYXRjaCB0aGUgZmlsdGVycyxcbiAgICAgICAgICAvLyB3ZSBub3cgcGFyayB0aGVtIHdpdGhpbiBjdXJyZW50IHNjb3BlIGFuZCBoaWRlIHRoZSBgX2NpZGAgYXR0cmlidXRlLlxuICAgICAgICAgIGZvciAoY29uc3QgcmVzdWx0IG9mIF9yZXN1bHRzKSB7XG4gICAgICAgICAgICBkZWxldGUgcmVzdWx0W1wiX2NpZFwiXTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmVzdWx0cyA9IF9yZXN1bHRzO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgICAgLy8gVGhlIHJlc3VsdGluZyBsaXN0IG9mIHJlY29yZHMgaXMgc29ydGVkLlxuICAgICAgLy8gWFhYOiB3aXRoIHNvbWUgZWZmb3J0cywgdGhpcyBjb3VsZCBiZSBmdWxseSBpbXBsZW1lbnRlZCB1c2luZyBJREIgQVBJLlxuICAgICAgcmV0dXJuIHBhcmFtcy5vcmRlciA/IHNvcnRPYmplY3RzKHBhcmFtcy5vcmRlciwgcmVzdWx0cykgOiByZXN1bHRzO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIHRoaXMuX2hhbmRsZUVycm9yKFwibGlzdFwiLCBlKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogU3RvcmUgdGhlIGxhc3RNb2RpZmllZCB2YWx1ZSBpbnRvIG1ldGFkYXRhIHN0b3JlLlxuICAgKlxuICAgKiBAb3ZlcnJpZGVcbiAgICogQHBhcmFtICB7TnVtYmVyfSAgbGFzdE1vZGlmaWVkXG4gICAqIEByZXR1cm4ge1Byb21pc2V9XG4gICAqL1xuICBhc3luYyBzYXZlTGFzdE1vZGlmaWVkKGxhc3RNb2RpZmllZCkge1xuICAgIGNvbnN0IHZhbHVlID0gcGFyc2VJbnQobGFzdE1vZGlmaWVkLCAxMCkgfHwgbnVsbDtcbiAgICB0cnkge1xuICAgICAgYXdhaXQgdGhpcy5wcmVwYXJlKFxuICAgICAgICBcInRpbWVzdGFtcHNcIixcbiAgICAgICAgc3RvcmUgPT4gc3RvcmUucHV0KHsgY2lkOiB0aGlzLmNpZCwgdmFsdWUgfSksXG4gICAgICAgIHsgbW9kZTogXCJyZWFkd3JpdGVcIiB9XG4gICAgICApO1xuICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIHRoaXMuX2hhbmRsZUVycm9yKFwic2F2ZUxhc3RNb2RpZmllZFwiLCBlKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUmV0cmlldmUgc2F2ZWQgbGFzdE1vZGlmaWVkIHZhbHVlLlxuICAgKlxuICAgKiBAb3ZlcnJpZGVcbiAgICogQHJldHVybiB7UHJvbWlzZX1cbiAgICovXG4gIGFzeW5jIGdldExhc3RNb2RpZmllZCgpIHtcbiAgICB0cnkge1xuICAgICAgbGV0IGVudHJ5ID0gbnVsbDtcbiAgICAgIGF3YWl0IHRoaXMucHJlcGFyZShcInRpbWVzdGFtcHNcIiwgc3RvcmUgPT4ge1xuICAgICAgICBzdG9yZS5nZXQodGhpcy5jaWQpLm9uc3VjY2VzcyA9IGUgPT4gKGVudHJ5ID0gZS50YXJnZXQucmVzdWx0KTtcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIGVudHJ5ID8gZW50cnkudmFsdWUgOiBudWxsO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIHRoaXMuX2hhbmRsZUVycm9yKFwiZ2V0TGFzdE1vZGlmaWVkXCIsIGUpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBMb2FkIGEgZHVtcCBvZiByZWNvcmRzIGV4cG9ydGVkIGZyb20gYSBzZXJ2ZXIuXG4gICAqXG4gICAqIEBkZXByZWNhdGVkIFVzZSB7QGxpbmsgaW1wb3J0QnVsa30gaW5zdGVhZC5cbiAgICogQGFic3RyYWN0XG4gICAqIEBwYXJhbSAge0FycmF5fSByZWNvcmRzIFRoZSByZWNvcmRzIHRvIGxvYWQuXG4gICAqIEByZXR1cm4ge1Byb21pc2V9XG4gICAqL1xuICBhc3luYyBsb2FkRHVtcChyZWNvcmRzKSB7XG4gICAgcmV0dXJuIHRoaXMuaW1wb3J0QnVsayhyZWNvcmRzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBMb2FkIHJlY29yZHMgaW4gYnVsayB0aGF0IHdlcmUgZXhwb3J0ZWQgZnJvbSBhIHNlcnZlci5cbiAgICpcbiAgICogQGFic3RyYWN0XG4gICAqIEBwYXJhbSAge0FycmF5fSByZWNvcmRzIFRoZSByZWNvcmRzIHRvIGxvYWQuXG4gICAqIEByZXR1cm4ge1Byb21pc2V9XG4gICAqL1xuICBhc3luYyBpbXBvcnRCdWxrKHJlY29yZHMpIHtcbiAgICB0cnkge1xuICAgICAgYXdhaXQgdGhpcy5leGVjdXRlKHRyYW5zYWN0aW9uID0+IHtcbiAgICAgICAgLy8gU2luY2UgdGhlIHB1dCBvcGVyYXRpb25zIGFyZSBhc3luY2hyb25vdXMsIHdlIGNoYWluXG4gICAgICAgIC8vIHRoZW0gdG9nZXRoZXIuIFRoZSBsYXN0IG9uZSB3aWxsIGJlIHdhaXRlZCBmb3IgdGhlXG4gICAgICAgIC8vIGB0cmFuc2FjdGlvbi5vbmNvbXBsZXRlYCBjYWxsYmFjay4gKHNlZSAjZXhlY3V0ZSgpKVxuICAgICAgICBsZXQgaSA9IDA7XG4gICAgICAgIHB1dE5leHQoKTtcblxuICAgICAgICBmdW5jdGlvbiBwdXROZXh0KCkge1xuICAgICAgICAgIGlmIChpID09IHJlY29yZHMubGVuZ3RoKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfVxuICAgICAgICAgIC8vIE9uIGVycm9yLCBgdHJhbnNhY3Rpb24ub25lcnJvcmAgaXMgY2FsbGVkLlxuICAgICAgICAgIHRyYW5zYWN0aW9uLnVwZGF0ZShyZWNvcmRzW2ldKS5vbnN1Y2Nlc3MgPSBwdXROZXh0O1xuICAgICAgICAgICsraTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICBjb25zdCBwcmV2aW91c0xhc3RNb2RpZmllZCA9IGF3YWl0IHRoaXMuZ2V0TGFzdE1vZGlmaWVkKCk7XG4gICAgICBjb25zdCBsYXN0TW9kaWZpZWQgPSBNYXRoLm1heChcbiAgICAgICAgLi4ucmVjb3Jkcy5tYXAocmVjb3JkID0+IHJlY29yZC5sYXN0X21vZGlmaWVkKVxuICAgICAgKTtcbiAgICAgIGlmIChsYXN0TW9kaWZpZWQgPiBwcmV2aW91c0xhc3RNb2RpZmllZCkge1xuICAgICAgICBhd2FpdCB0aGlzLnNhdmVMYXN0TW9kaWZpZWQobGFzdE1vZGlmaWVkKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiByZWNvcmRzO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIHRoaXMuX2hhbmRsZUVycm9yKFwiaW1wb3J0QnVsa1wiLCBlKTtcbiAgICB9XG4gIH1cblxuICBhc3luYyBzYXZlTWV0YWRhdGEobWV0YWRhdGEpIHtcbiAgICB0cnkge1xuICAgICAgYXdhaXQgdGhpcy5wcmVwYXJlKFxuICAgICAgICBcImNvbGxlY3Rpb25zXCIsXG4gICAgICAgIHN0b3JlID0+IHN0b3JlLnB1dCh7IGNpZDogdGhpcy5jaWQsIG1ldGFkYXRhIH0pLFxuICAgICAgICB7IG1vZGU6IFwicmVhZHdyaXRlXCIgfVxuICAgICAgKTtcbiAgICAgIHJldHVybiBtZXRhZGF0YTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICB0aGlzLl9oYW5kbGVFcnJvcihcInNhdmVNZXRhZGF0YVwiLCBlKTtcbiAgICB9XG4gIH1cblxuICBhc3luYyBnZXRNZXRhZGF0YSgpIHtcbiAgICB0cnkge1xuICAgICAgbGV0IGVudHJ5ID0gbnVsbDtcbiAgICAgIGF3YWl0IHRoaXMucHJlcGFyZShcImNvbGxlY3Rpb25zXCIsIHN0b3JlID0+IHtcbiAgICAgICAgc3RvcmUuZ2V0KHRoaXMuY2lkKS5vbnN1Y2Nlc3MgPSBlID0+IChlbnRyeSA9IGUudGFyZ2V0LnJlc3VsdCk7XG4gICAgICB9KTtcbiAgICAgIHJldHVybiBlbnRyeSA/IGVudHJ5Lm1ldGFkYXRhIDogbnVsbDtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICB0aGlzLl9oYW5kbGVFcnJvcihcImdldE1ldGFkYXRhXCIsIGUpO1xuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIElEQiB0cmFuc2FjdGlvbiBwcm94eS5cbiAqXG4gKiBAcGFyYW0gIHtJREJ9IGFkYXB0ZXIgICAgICAgIFRoZSBjYWxsIElEQiBhZGFwdGVyXG4gKiBAcGFyYW0gIHtJREJTdG9yZX0gc3RvcmUgICAgIFRoZSBJbmRleGVkREIgZGF0YWJhc2Ugc3RvcmUuXG4gKiBAcGFyYW0gIHtBcnJheX0gICAgcHJlbG9hZGVkIFRoZSBsaXN0IG9mIHJlY29yZHMgdG8gbWFrZSBhdmFpbGFibGUgdG9cbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2V0KCkgKGRlZmF1bHQ6IFtdKS5cbiAqIEByZXR1cm4ge09iamVjdH1cbiAqL1xuZnVuY3Rpb24gdHJhbnNhY3Rpb25Qcm94eShhZGFwdGVyLCBzdG9yZSwgcHJlbG9hZGVkID0gW10pIHtcbiAgY29uc3QgX2NpZCA9IGFkYXB0ZXIuY2lkO1xuICByZXR1cm4ge1xuICAgIGNyZWF0ZShyZWNvcmQpIHtcbiAgICAgIHN0b3JlLmFkZCh7IC4uLnJlY29yZCwgX2NpZCB9KTtcbiAgICB9LFxuXG4gICAgdXBkYXRlKHJlY29yZCkge1xuICAgICAgcmV0dXJuIHN0b3JlLnB1dCh7IC4uLnJlY29yZCwgX2NpZCB9KTtcbiAgICB9LFxuXG4gICAgZGVsZXRlKGlkKSB7XG4gICAgICBzdG9yZS5kZWxldGUoW19jaWQsIGlkXSk7XG4gICAgfSxcblxuICAgIGdldChpZCkge1xuICAgICAgcmV0dXJuIHByZWxvYWRlZFtpZF07XG4gICAgfSxcbiAgfTtcbn1cblxuLyoqXG4gKiBVcCB0byB2ZXJzaW9uIDEwLlggb2Yga2ludG8uanMsIGVhY2ggY29sbGVjdGlvbiBoYWQgaXRzIG93biBjb2xsZWN0aW9uLlxuICogVGhlIGRhdGFiYXNlIG5hbWUgd2FzIGAke2JpZH0vJHtjaWR9YCAoZWcuIGBcImJsb2NrbGlzdHMvY2VydGlmaWNhdGVzXCJgKVxuICogYW5kIGNvbnRhaW5lZCBvbmx5IG9uZSBzdG9yZSB3aXRoIHRoZSBzYW1lIG5hbWUuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIG1pZ3JhdGlvblJlcXVpcmVkKGRiTmFtZSkge1xuICBsZXQgZXhpc3RzID0gdHJ1ZTtcbiAgY29uc3QgZGIgPSBhd2FpdCBvcGVuKGRiTmFtZSwge1xuICAgIHZlcnNpb246IDEsXG4gICAgb251cGdyYWRlbmVlZGVkOiBldmVudCA9PiB7XG4gICAgICBleGlzdHMgPSBmYWxzZTtcbiAgICB9LFxuICB9KTtcblxuICAvLyBDaGVjayB0aGF0IHRoZSBEQiB3ZSdyZSBsb29raW5nIGF0IGlzIHJlYWxseSBhIGxlZ2FjeSBvbmUsXG4gIC8vIGFuZCBub3Qgc29tZSByZW1haW5kZXIgb2YgdGhlIG9wZW4oKSBvcGVyYXRpb24gYWJvdmUuXG4gIGV4aXN0cyAmPVxuICAgIGRiLm9iamVjdFN0b3JlTmFtZXMuY29udGFpbnMoXCJfX21ldGFfX1wiKSAmJlxuICAgIGRiLm9iamVjdFN0b3JlTmFtZXMuY29udGFpbnMoZGJOYW1lKTtcblxuICBpZiAoIWV4aXN0cykge1xuICAgIGRiLmNsb3NlKCk7XG4gICAgLy8gVGVzdGluZyB0aGUgZXhpc3RlbmNlIGNyZWF0ZXMgaXQsIHNvIGRlbGV0ZSBpdCA6KVxuICAgIGF3YWl0IGRlbGV0ZURhdGFiYXNlKGRiTmFtZSk7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBjb25zb2xlLndhcm4oYCR7ZGJOYW1lfTogb2xkIEluZGV4ZWREQiBkYXRhYmFzZSBmb3VuZC5gKTtcbiAgdHJ5IHtcbiAgICAvLyBTY2FuIGFsbCByZWNvcmRzLlxuICAgIGxldCByZWNvcmRzO1xuICAgIGF3YWl0IGV4ZWN1dGUoZGIsIGRiTmFtZSwgc3RvcmUgPT4ge1xuICAgICAgc3RvcmUub3BlbkN1cnNvcigpLm9uc3VjY2VzcyA9IGN1cnNvckhhbmRsZXJzLmFsbChcbiAgICAgICAge30sXG4gICAgICAgIHJlcyA9PiAocmVjb3JkcyA9IHJlcylcbiAgICAgICk7XG4gICAgfSk7XG4gICAgY29uc29sZS5sb2coYCR7ZGJOYW1lfTogZm91bmQgJHtyZWNvcmRzLmxlbmd0aH0gcmVjb3Jkcy5gKTtcblxuICAgIC8vIENoZWNrIGlmIHRoZXJlJ3MgYSBlbnRyeSBmb3IgdGhpcy5cbiAgICBsZXQgdGltZXN0YW1wID0gbnVsbDtcbiAgICBhd2FpdCBleGVjdXRlKGRiLCBcIl9fbWV0YV9fXCIsIHN0b3JlID0+IHtcbiAgICAgIHN0b3JlLmdldChgJHtkYk5hbWV9LWxhc3RNb2RpZmllZGApLm9uc3VjY2VzcyA9IGUgPT4ge1xuICAgICAgICB0aW1lc3RhbXAgPSBlLnRhcmdldC5yZXN1bHQgPyBlLnRhcmdldC5yZXN1bHQudmFsdWUgOiBudWxsO1xuICAgICAgfTtcbiAgICB9KTtcbiAgICAvLyBTb21lIHByZXZpb3VzIHZlcnNpb25zLCBhbHNvIHVzZWQgdG8gc3RvcmUgdGhlIHRpbWVzdGFtcHMgd2l0aG91dCBwcmVmaXguXG4gICAgaWYgKCF0aW1lc3RhbXApIHtcbiAgICAgIGF3YWl0IGV4ZWN1dGUoZGIsIFwiX19tZXRhX19cIiwgc3RvcmUgPT4ge1xuICAgICAgICBzdG9yZS5nZXQoXCJsYXN0TW9kaWZpZWRcIikub25zdWNjZXNzID0gZSA9PiB7XG4gICAgICAgICAgdGltZXN0YW1wID0gZS50YXJnZXQucmVzdWx0ID8gZS50YXJnZXQucmVzdWx0LnZhbHVlIDogbnVsbDtcbiAgICAgICAgfTtcbiAgICAgIH0pO1xuICAgIH1cbiAgICBjb25zb2xlLmxvZyhgJHtkYk5hbWV9OiAke3RpbWVzdGFtcCA/IFwiZm91bmRcIiA6IFwibm9cIn0gdGltZXN0YW1wLmApO1xuXG4gICAgLy8gVGhvc2Ugd2lsbCBiZSBpbnNlcnRlZCBpbiB0aGUgbmV3IGRhdGFiYXNlL3NjaGVtYS5cbiAgICByZXR1cm4geyByZWNvcmRzLCB0aW1lc3RhbXAgfTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIGNvbnNvbGUuZXJyb3IoXCJFcnJvciBvY2N1cmVkIGR1cmluZyBtaWdyYXRpb25cIiwgZSk7XG4gICAgcmV0dXJuIG51bGw7XG4gIH0gZmluYWxseSB7XG4gICAgZGIuY2xvc2UoKTtcbiAgfVxufVxuIiwiXCJ1c2Ugc3RyaWN0XCI7XG5cbi8qKlxuICogQmFzZSBkYiBhZGFwdGVyLlxuICpcbiAqIEBhYnN0cmFjdFxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBCYXNlQWRhcHRlciB7XG4gIC8qKlxuICAgKiBEZWxldGVzIGV2ZXJ5IHJlY29yZHMgcHJlc2VudCBpbiB0aGUgZGF0YWJhc2UuXG4gICAqXG4gICAqIEBhYnN0cmFjdFxuICAgKiBAcmV0dXJuIHtQcm9taXNlfVxuICAgKi9cbiAgY2xlYXIoKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFwiTm90IEltcGxlbWVudGVkLlwiKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBFeGVjdXRlcyBhIGJhdGNoIG9mIG9wZXJhdGlvbnMgd2l0aGluIGEgc2luZ2xlIHRyYW5zYWN0aW9uLlxuICAgKlxuICAgKiBAYWJzdHJhY3RcbiAgICogQHBhcmFtICB7RnVuY3Rpb259IGNhbGxiYWNrIFRoZSBvcGVyYXRpb24gY2FsbGJhY2suXG4gICAqIEBwYXJhbSAge09iamVjdH0gICBvcHRpb25zICBUaGUgb3B0aW9ucyBvYmplY3QuXG4gICAqIEByZXR1cm4ge1Byb21pc2V9XG4gICAqL1xuICBleGVjdXRlKGNhbGxiYWNrLCBvcHRpb25zID0geyBwcmVsb2FkOiBbXSB9KSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFwiTm90IEltcGxlbWVudGVkLlwiKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXRyaWV2ZSBhIHJlY29yZCBieSBpdHMgcHJpbWFyeSBrZXkgZnJvbSB0aGUgZGF0YWJhc2UuXG4gICAqXG4gICAqIEBhYnN0cmFjdFxuICAgKiBAcGFyYW0gIHtTdHJpbmd9IGlkIFRoZSByZWNvcmQgaWQuXG4gICAqIEByZXR1cm4ge1Byb21pc2V9XG4gICAqL1xuICBnZXQoaWQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJOb3QgSW1wbGVtZW50ZWQuXCIpO1xuICB9XG5cbiAgLyoqXG4gICAqIExpc3RzIGFsbCByZWNvcmRzIGZyb20gdGhlIGRhdGFiYXNlLlxuICAgKlxuICAgKiBAYWJzdHJhY3RcbiAgICogQHBhcmFtICB7T2JqZWN0fSBwYXJhbXMgIFRoZSBmaWx0ZXJzIGFuZCBvcmRlciB0byBhcHBseSB0byB0aGUgcmVzdWx0cy5cbiAgICogQHJldHVybiB7UHJvbWlzZX1cbiAgICovXG4gIGxpc3QocGFyYW1zID0geyBmaWx0ZXJzOiB7fSwgb3JkZXI6IFwiXCIgfSkge1xuICAgIHRocm93IG5ldyBFcnJvcihcIk5vdCBJbXBsZW1lbnRlZC5cIik7XG4gIH1cblxuICAvKipcbiAgICogU3RvcmUgdGhlIGxhc3RNb2RpZmllZCB2YWx1ZS5cbiAgICpcbiAgICogQGFic3RyYWN0XG4gICAqIEBwYXJhbSAge051bWJlcn0gIGxhc3RNb2RpZmllZFxuICAgKiBAcmV0dXJuIHtQcm9taXNlfVxuICAgKi9cbiAgc2F2ZUxhc3RNb2RpZmllZChsYXN0TW9kaWZpZWQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJOb3QgSW1wbGVtZW50ZWQuXCIpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHJpZXZlIHNhdmVkIGxhc3RNb2RpZmllZCB2YWx1ZS5cbiAgICpcbiAgICogQGFic3RyYWN0XG4gICAqIEByZXR1cm4ge1Byb21pc2V9XG4gICAqL1xuICBnZXRMYXN0TW9kaWZpZWQoKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFwiTm90IEltcGxlbWVudGVkLlwiKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBMb2FkIHJlY29yZHMgaW4gYnVsayB0aGF0IHdlcmUgZXhwb3J0ZWQgZnJvbSBhIHNlcnZlci5cbiAgICpcbiAgICogQGFic3RyYWN0XG4gICAqIEBwYXJhbSAge0FycmF5fSByZWNvcmRzIFRoZSByZWNvcmRzIHRvIGxvYWQuXG4gICAqIEByZXR1cm4ge1Byb21pc2V9XG4gICAqL1xuICBpbXBvcnRCdWxrKHJlY29yZHMpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJOb3QgSW1wbGVtZW50ZWQuXCIpO1xuICB9XG5cbiAgLyoqXG4gICAqIExvYWQgYSBkdW1wIG9mIHJlY29yZHMgZXhwb3J0ZWQgZnJvbSBhIHNlcnZlci5cbiAgICpcbiAgICogQGRlcHJlY2F0ZWQgVXNlIHtAbGluayBpbXBvcnRCdWxrfSBpbnN0ZWFkLlxuICAgKiBAYWJzdHJhY3RcbiAgICogQHBhcmFtICB7QXJyYXl9IHJlY29yZHMgVGhlIHJlY29yZHMgdG8gbG9hZC5cbiAgICogQHJldHVybiB7UHJvbWlzZX1cbiAgICovXG4gIGxvYWREdW1wKHJlY29yZHMpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJOb3QgSW1wbGVtZW50ZWQuXCIpO1xuICB9XG5cbiAgc2F2ZU1ldGFkYXRhKG1ldGFkYXRhKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFwiTm90IEltcGxlbWVudGVkLlwiKTtcbiAgfVxuXG4gIGdldE1ldGFkYXRhKCkge1xuICAgIHRocm93IG5ldyBFcnJvcihcIk5vdCBJbXBsZW1lbnRlZC5cIik7XG4gIH1cbn1cbiIsIlwidXNlIHN0cmljdFwiO1xuXG5pbXBvcnQgQmFzZUFkYXB0ZXIgZnJvbSBcIi4vYWRhcHRlcnMvYmFzZVwiO1xuaW1wb3J0IElEQiBmcm9tIFwiLi9hZGFwdGVycy9JREJcIjtcbmltcG9ydCB7IHdhdGVyZmFsbCwgZGVlcEVxdWFsIH0gZnJvbSBcIi4vdXRpbHNcIjtcbmltcG9ydCB7IHY0IGFzIHV1aWQ0IH0gZnJvbSBcInV1aWRcIjtcbmltcG9ydCB7IG9taXRLZXlzLCBSRV9SRUNPUkRfSUQgfSBmcm9tIFwiLi91dGlsc1wiO1xuXG5jb25zdCBSRUNPUkRfRklFTERTX1RPX0NMRUFOID0gW1wiX3N0YXR1c1wiXTtcbmNvbnN0IEFWQUlMQUJMRV9IT09LUyA9IFtcImluY29taW5nLWNoYW5nZXNcIl07XG5jb25zdCBJTVBPUlRfQ0hVTktfU0laRSA9IDIwMDtcblxuLyoqXG4gKiBDb21wYXJlIHR3byByZWNvcmRzIG9taXR0aW5nIGxvY2FsIGZpZWxkcyBhbmQgc3luY2hyb25pemF0aW9uXG4gKiBhdHRyaWJ1dGVzIChsaWtlIF9zdGF0dXMgYW5kIGxhc3RfbW9kaWZpZWQpXG4gKiBAcGFyYW0ge09iamVjdH0gYSAgICBBIHJlY29yZCB0byBjb21wYXJlLlxuICogQHBhcmFtIHtPYmplY3R9IGIgICAgQSByZWNvcmQgdG8gY29tcGFyZS5cbiAqIEBwYXJhbSB7QXJyYXl9IGxvY2FsRmllbGRzIEFkZGl0aW9uYWwgZmllbGRzIHRvIGlnbm9yZSBkdXJpbmcgdGhlIGNvbXBhcmlzb25cbiAqIEByZXR1cm4ge2Jvb2xlYW59XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZWNvcmRzRXF1YWwoYSwgYiwgbG9jYWxGaWVsZHMgPSBbXSkge1xuICBjb25zdCBmaWVsZHNUb0NsZWFuID0gUkVDT1JEX0ZJRUxEU19UT19DTEVBTi5jb25jYXQoW1wibGFzdF9tb2RpZmllZFwiXSkuY29uY2F0KFxuICAgIGxvY2FsRmllbGRzXG4gICk7XG4gIGNvbnN0IGNsZWFuTG9jYWwgPSByID0+IG9taXRLZXlzKHIsIGZpZWxkc1RvQ2xlYW4pO1xuICByZXR1cm4gZGVlcEVxdWFsKGNsZWFuTG9jYWwoYSksIGNsZWFuTG9jYWwoYikpO1xufVxuXG4vKipcbiAqIFN5bmNocm9uaXphdGlvbiByZXN1bHQgb2JqZWN0LlxuICovXG5leHBvcnQgY2xhc3MgU3luY1Jlc3VsdE9iamVjdCB7XG4gIC8qKlxuICAgKiBQdWJsaWMgY29uc3RydWN0b3IuXG4gICAqL1xuICBjb25zdHJ1Y3RvcigpIHtcbiAgICAvKipcbiAgICAgKiBDdXJyZW50IHN5bmNocm9uaXphdGlvbiByZXN1bHQgc3RhdHVzOyBiZWNvbWVzIGBmYWxzZWAgd2hlbiBjb25mbGljdHMgb3JcbiAgICAgKiBlcnJvcnMgYXJlIHJlZ2lzdGVyZWQuXG4gICAgICogQHR5cGUge0Jvb2xlYW59XG4gICAgICovXG4gICAgdGhpcy5sYXN0TW9kaWZpZWQgPSBudWxsO1xuICAgIHRoaXMuX2xpc3RzID0ge307XG4gICAgW1xuICAgICAgXCJlcnJvcnNcIixcbiAgICAgIFwiY3JlYXRlZFwiLFxuICAgICAgXCJ1cGRhdGVkXCIsXG4gICAgICBcImRlbGV0ZWRcIixcbiAgICAgIFwicHVibGlzaGVkXCIsXG4gICAgICBcImNvbmZsaWN0c1wiLFxuICAgICAgXCJza2lwcGVkXCIsXG4gICAgICBcInJlc29sdmVkXCIsXG4gICAgICBcInZvaWRcIixcbiAgICBdLmZvckVhY2gobCA9PiAodGhpcy5fbGlzdHNbbF0gPSBbXSkpO1xuICAgIHRoaXMuX2NhY2hlZCA9IHt9O1xuICB9XG5cbiAgLyoqXG4gICAqIEFkZHMgZW50cmllcyBmb3IgYSBnaXZlbiByZXN1bHQgdHlwZS5cbiAgICpcbiAgICogQHBhcmFtIHtTdHJpbmd9IHR5cGUgICAgVGhlIHJlc3VsdCB0eXBlLlxuICAgKiBAcGFyYW0ge0FycmF5fSAgZW50cmllcyBUaGUgcmVzdWx0IGVudHJpZXMuXG4gICAqIEByZXR1cm4ge1N5bmNSZXN1bHRPYmplY3R9XG4gICAqL1xuICBhZGQodHlwZSwgZW50cmllcykge1xuICAgIGlmICghQXJyYXkuaXNBcnJheSh0aGlzLl9saXN0c1t0eXBlXSkpIHtcbiAgICAgIGNvbnNvbGUud2FybihgVW5rbm93biB0eXBlIFwiJHt0eXBlfVwiYCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmICghQXJyYXkuaXNBcnJheShlbnRyaWVzKSkge1xuICAgICAgZW50cmllcyA9IFtlbnRyaWVzXTtcbiAgICB9XG4gICAgdGhpcy5fbGlzdHNbdHlwZV0gPSB0aGlzLl9saXN0c1t0eXBlXS5jb25jYXQoZW50cmllcyk7XG4gICAgZGVsZXRlIHRoaXMuX2NhY2hlZFt0eXBlXTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIGdldCBvaygpIHtcbiAgICByZXR1cm4gdGhpcy5lcnJvcnMubGVuZ3RoICsgdGhpcy5jb25mbGljdHMubGVuZ3RoID09PSAwO1xuICB9XG5cbiAgZ2V0IGVycm9ycygpIHtcbiAgICByZXR1cm4gdGhpcy5fbGlzdHNbXCJlcnJvcnNcIl07XG4gIH1cblxuICBnZXQgY29uZmxpY3RzKCkge1xuICAgIHJldHVybiB0aGlzLl9saXN0c1tcImNvbmZsaWN0c1wiXTtcbiAgfVxuXG4gIGdldCBza2lwcGVkKCkge1xuICAgIHJldHVybiB0aGlzLl9kZWR1cGxpY2F0ZShcInNraXBwZWRcIik7XG4gIH1cblxuICBnZXQgcmVzb2x2ZWQoKSB7XG4gICAgcmV0dXJuIHRoaXMuX2RlZHVwbGljYXRlKFwicmVzb2x2ZWRcIik7XG4gIH1cblxuICBnZXQgY3JlYXRlZCgpIHtcbiAgICByZXR1cm4gdGhpcy5fZGVkdXBsaWNhdGUoXCJjcmVhdGVkXCIpO1xuICB9XG5cbiAgZ2V0IHVwZGF0ZWQoKSB7XG4gICAgcmV0dXJuIHRoaXMuX2RlZHVwbGljYXRlKFwidXBkYXRlZFwiKTtcbiAgfVxuXG4gIGdldCBkZWxldGVkKCkge1xuICAgIHJldHVybiB0aGlzLl9kZWR1cGxpY2F0ZShcImRlbGV0ZWRcIik7XG4gIH1cblxuICBnZXQgcHVibGlzaGVkKCkge1xuICAgIHJldHVybiB0aGlzLl9kZWR1cGxpY2F0ZShcInB1Ymxpc2hlZFwiKTtcbiAgfVxuXG4gIF9kZWR1cGxpY2F0ZShsaXN0KSB7XG4gICAgaWYgKCEobGlzdCBpbiB0aGlzLl9jYWNoZWQpKSB7XG4gICAgICAvLyBEZWR1cGxpY2F0ZSBlbnRyaWVzIGJ5IGlkLiBJZiB0aGUgdmFsdWVzIGRvbid0IGhhdmUgYGlkYCBhdHRyaWJ1dGUsIGp1c3RcbiAgICAgIC8vIGtlZXAgYWxsLlxuICAgICAgY29uc3QgcmVjb3Jkc1dpdGhvdXRJZCA9IG5ldyBTZXQoKTtcbiAgICAgIGNvbnN0IHJlY29yZHNCeUlkID0gbmV3IE1hcCgpO1xuICAgICAgdGhpcy5fbGlzdHNbbGlzdF0uZm9yRWFjaChyZWNvcmQgPT4ge1xuICAgICAgICBpZiAoIXJlY29yZC5pZCkge1xuICAgICAgICAgIHJlY29yZHNXaXRob3V0SWQuYWRkKHJlY29yZCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmVjb3Jkc0J5SWQuc2V0KHJlY29yZC5pZCwgcmVjb3JkKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICB0aGlzLl9jYWNoZWRbbGlzdF0gPSBBcnJheS5mcm9tKHJlY29yZHNCeUlkLnZhbHVlcygpKS5jb25jYXQoXG4gICAgICAgIEFycmF5LmZyb20ocmVjb3Jkc1dpdGhvdXRJZClcbiAgICAgICk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLl9jYWNoZWRbbGlzdF07XG4gIH1cblxuICAvKipcbiAgICogUmVpbml0aWFsaXplcyByZXN1bHQgZW50cmllcyBmb3IgYSBnaXZlbiByZXN1bHQgdHlwZS5cbiAgICpcbiAgICogQHBhcmFtICB7U3RyaW5nfSB0eXBlIFRoZSByZXN1bHQgdHlwZS5cbiAgICogQHJldHVybiB7U3luY1Jlc3VsdE9iamVjdH1cbiAgICovXG4gIHJlc2V0KHR5cGUpIHtcbiAgICB0aGlzLl9saXN0c1t0eXBlXSA9IFtdO1xuICAgIGRlbGV0ZSB0aGlzLl9jYWNoZWRbdHlwZV07XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICB0b09iamVjdCgpIHtcbiAgICAvLyBPbmx5IHVzZWQgaW4gdGVzdHMuXG4gICAgcmV0dXJuIHtcbiAgICAgIG9rOiB0aGlzLm9rLFxuICAgICAgbGFzdE1vZGlmaWVkOiB0aGlzLmxhc3RNb2RpZmllZCxcbiAgICAgIGVycm9yczogdGhpcy5lcnJvcnMsXG4gICAgICBjcmVhdGVkOiB0aGlzLmNyZWF0ZWQsXG4gICAgICB1cGRhdGVkOiB0aGlzLnVwZGF0ZWQsXG4gICAgICBkZWxldGVkOiB0aGlzLmRlbGV0ZWQsXG4gICAgICBza2lwcGVkOiB0aGlzLnNraXBwZWQsXG4gICAgICBwdWJsaXNoZWQ6IHRoaXMucHVibGlzaGVkLFxuICAgICAgY29uZmxpY3RzOiB0aGlzLmNvbmZsaWN0cyxcbiAgICAgIHJlc29sdmVkOiB0aGlzLnJlc29sdmVkLFxuICAgIH07XG4gIH1cbn1cblxuZXhwb3J0IGNsYXNzIFNlcnZlcldhc0ZsdXNoZWRFcnJvciBleHRlbmRzIEVycm9yIHtcbiAgY29uc3RydWN0b3IoY2xpZW50VGltZXN0YW1wLCBzZXJ2ZXJUaW1lc3RhbXAsIG1lc3NhZ2UpIHtcbiAgICBzdXBlcihtZXNzYWdlKTtcblxuICAgIGlmIChFcnJvci5jYXB0dXJlU3RhY2tUcmFjZSkge1xuICAgICAgRXJyb3IuY2FwdHVyZVN0YWNrVHJhY2UodGhpcywgU2VydmVyV2FzRmx1c2hlZEVycm9yKTtcbiAgICB9XG5cbiAgICB0aGlzLmNsaWVudFRpbWVzdGFtcCA9IGNsaWVudFRpbWVzdGFtcDtcbiAgICB0aGlzLnNlcnZlclRpbWVzdGFtcCA9IHNlcnZlclRpbWVzdGFtcDtcbiAgfVxufVxuXG5mdW5jdGlvbiBjcmVhdGVVVUlEU2NoZW1hKCkge1xuICByZXR1cm4ge1xuICAgIGdlbmVyYXRlKCkge1xuICAgICAgcmV0dXJuIHV1aWQ0KCk7XG4gICAgfSxcblxuICAgIHZhbGlkYXRlKGlkKSB7XG4gICAgICByZXR1cm4gdHlwZW9mIGlkID09IFwic3RyaW5nXCIgJiYgUkVfUkVDT1JEX0lELnRlc3QoaWQpO1xuICAgIH0sXG4gIH07XG59XG5cbi8qKlxuICogSURTY2hlbWEgZm9yIHdoZW4gdXNpbmcga2ludG8uanMgYXMgYSBrZXktdmFsdWUgc3RvcmUuXG4gKiBVc2luZyB0aGlzIElEU2NoZW1hIHJlcXVpcmVzIHlvdSB0byBzZXQgYSBwcm9wZXJ0eSBhcyB0aGUgaWQuXG4gKiBUaGlzIHdpbGwgYmUgdGhlIHByb3BlcnR5IHVzZWQgdG8gcmV0cmlldmUgdGhpcyByZWNvcmQuXG4gKlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IGV4YW1wbGVDb2xsZWN0aW9uID0gZGIuY29sbGVjdGlvbihcImV4YW1wbGVcIiwgeyBpZFNjaGVtYTogY3JlYXRlS2V5VmFsdWVTdG9yZUlkU2NoZW1hKCkgfSlcbiAqIGF3YWl0IGV4YW1wbGVDb2xsZWN0aW9uLmNyZWF0ZSh7IHRpdGxlOiBcIkhvdyB0byB0aWUgYSB0aWVcIiwgZmF2b3JpdGVDb2xvcjogXCJibHVlXCIsIGlkOiBcInVzZXIxMjNcIiB9LCB7IHVzZVJlY29yZElkOiB0cnVlIH0pXG4gKiBhd2FpdCBleGFtcGxlQ29sbGVjdGlvbi5nZXRBbnkoXCJ1c2VyMTIzXCIpXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVLZXlWYWx1ZVN0b3JlSWRTY2hlbWEoKSB7XG4gIHJldHVybiB7XG4gICAgZ2VuZXJhdGUoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJjcmVhdGVLZXlWYWx1ZVN0b3JlSWRTY2hlbWEoKSBkb2VzIG5vdCBnZW5lcmF0ZSBhbiBpZFwiKTtcbiAgICB9LFxuICAgIHZhbGlkYXRlKCkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSxcbiAgfTtcbn1cblxuZnVuY3Rpb24gbWFya1N0YXR1cyhyZWNvcmQsIHN0YXR1cykge1xuICByZXR1cm4geyAuLi5yZWNvcmQsIF9zdGF0dXM6IHN0YXR1cyB9O1xufVxuXG5mdW5jdGlvbiBtYXJrRGVsZXRlZChyZWNvcmQpIHtcbiAgcmV0dXJuIG1hcmtTdGF0dXMocmVjb3JkLCBcImRlbGV0ZWRcIik7XG59XG5cbmZ1bmN0aW9uIG1hcmtTeW5jZWQocmVjb3JkKSB7XG4gIHJldHVybiBtYXJrU3RhdHVzKHJlY29yZCwgXCJzeW5jZWRcIik7XG59XG5cbi8qKlxuICogSW1wb3J0IGEgcmVtb3RlIGNoYW5nZSBpbnRvIHRoZSBsb2NhbCBkYXRhYmFzZS5cbiAqXG4gKiBAcGFyYW0gIHtJREJUcmFuc2FjdGlvblByb3h5fSB0cmFuc2FjdGlvbiBUaGUgdHJhbnNhY3Rpb24gaGFuZGxlci5cbiAqIEBwYXJhbSAge09iamVjdH0gICAgICAgICAgICAgIHJlbW90ZSAgICAgIFRoZSByZW1vdGUgY2hhbmdlIG9iamVjdCB0byBpbXBvcnQuXG4gKiBAcGFyYW0gIHtBcnJheTxTdHJpbmc+fSAgICAgICBsb2NhbEZpZWxkcyBUaGUgbGlzdCBvZiBmaWVsZHMgdGhhdCByZW1haW4gbG9jYWwuXG4gKiBAcGFyYW0gIHtTdHJpbmd9ICAgICAgICAgICAgICBzdHJhdGVneSAgICBUaGUge0BsaW5rIENvbGxlY3Rpb24uc3RyYXRlZ3l9LlxuICogQHJldHVybiB7T2JqZWN0fVxuICovXG5mdW5jdGlvbiBpbXBvcnRDaGFuZ2UodHJhbnNhY3Rpb24sIHJlbW90ZSwgbG9jYWxGaWVsZHMsIHN0cmF0ZWd5KSB7XG4gIGNvbnN0IGxvY2FsID0gdHJhbnNhY3Rpb24uZ2V0KHJlbW90ZS5pZCk7XG4gIGlmICghbG9jYWwpIHtcbiAgICAvLyBOb3QgZm91bmQgbG9jYWxseSBidXQgcmVtb3RlIGNoYW5nZSBpcyBtYXJrZWQgYXMgZGVsZXRlZDsgc2tpcCB0b1xuICAgIC8vIGF2b2lkIHJlY3JlYXRpb24uXG4gICAgaWYgKHJlbW90ZS5kZWxldGVkKSB7XG4gICAgICByZXR1cm4geyB0eXBlOiBcInNraXBwZWRcIiwgZGF0YTogcmVtb3RlIH07XG4gICAgfVxuICAgIGNvbnN0IHN5bmNlZCA9IG1hcmtTeW5jZWQocmVtb3RlKTtcbiAgICB0cmFuc2FjdGlvbi5jcmVhdGUoc3luY2VkKTtcbiAgICByZXR1cm4geyB0eXBlOiBcImNyZWF0ZWRcIiwgZGF0YTogc3luY2VkIH07XG4gIH1cbiAgLy8gQXBwbHkgcmVtb3RlIGNoYW5nZXMgb24gbG9jYWwgcmVjb3JkLlxuICBjb25zdCBzeW5jZWQgPSB7IC4uLmxvY2FsLCAuLi5tYXJrU3luY2VkKHJlbW90ZSkgfTtcblxuICAvLyBXaXRoIHB1bGwgb25seSwgd2UgZG9uJ3QgbmVlZCB0byBjb21wYXJlIHJlY29yZHMgc2luY2Ugd2Ugb3ZlcnJpZGUgdGhlbS5cbiAgaWYgKHN0cmF0ZWd5ID09PSBDb2xsZWN0aW9uLnN0cmF0ZWd5LlBVTExfT05MWSkge1xuICAgIGlmIChyZW1vdGUuZGVsZXRlZCkge1xuICAgICAgdHJhbnNhY3Rpb24uZGVsZXRlKHJlbW90ZS5pZCk7XG4gICAgICByZXR1cm4geyB0eXBlOiBcImRlbGV0ZWRcIiwgZGF0YTogbG9jYWwgfTtcbiAgICB9XG4gICAgdHJhbnNhY3Rpb24udXBkYXRlKHN5bmNlZCk7XG4gICAgcmV0dXJuIHsgdHlwZTogXCJ1cGRhdGVkXCIsIGRhdGE6IHsgb2xkOiBsb2NhbCwgbmV3OiBzeW5jZWQgfSB9O1xuICB9XG5cbiAgLy8gV2l0aCBvdGhlciBzeW5jIHN0cmF0ZWdpZXMsIHdlIGRldGVjdCBjb25mbGljdHMsXG4gIC8vIGJ5IGNvbXBhcmluZyBsb2NhbCBhbmQgcmVtb3RlLCBpZ25vcmluZyBsb2NhbCBmaWVsZHMuXG4gIGNvbnN0IGlzSWRlbnRpY2FsID0gcmVjb3Jkc0VxdWFsKGxvY2FsLCByZW1vdGUsIGxvY2FsRmllbGRzKTtcbiAgLy8gRGV0ZWN0IG9yIGlnbm9yZSBjb25mbGljdHMgaWYgcmVjb3JkIGhhcyBhbHNvIGJlZW4gbW9kaWZpZWQgbG9jYWxseS5cbiAgaWYgKGxvY2FsLl9zdGF0dXMgIT09IFwic3luY2VkXCIpIHtcbiAgICAvLyBMb2NhbGx5IGRlbGV0ZWQsIHVuc3luY2VkOiBzY2hlZHVsZWQgZm9yIHJlbW90ZSBkZWxldGlvbi5cbiAgICBpZiAobG9jYWwuX3N0YXR1cyA9PT0gXCJkZWxldGVkXCIpIHtcbiAgICAgIHJldHVybiB7IHR5cGU6IFwic2tpcHBlZFwiLCBkYXRhOiBsb2NhbCB9O1xuICAgIH1cbiAgICBpZiAoaXNJZGVudGljYWwpIHtcbiAgICAgIC8vIElmIHJlY29yZHMgYXJlIGlkZW50aWNhbCwgaW1wb3J0IGFueXdheSwgc28gd2UgYnVtcCB0aGVcbiAgICAgIC8vIGxvY2FsIGxhc3RfbW9kaWZpZWQgdmFsdWUgZnJvbSB0aGUgc2VydmVyIGFuZCBzZXQgcmVjb3JkXG4gICAgICAvLyBzdGF0dXMgdG8gXCJzeW5jZWRcIi5cbiAgICAgIHRyYW5zYWN0aW9uLnVwZGF0ZShzeW5jZWQpO1xuICAgICAgcmV0dXJuIHsgdHlwZTogXCJ1cGRhdGVkXCIsIGRhdGE6IHsgb2xkOiBsb2NhbCwgbmV3OiBzeW5jZWQgfSB9O1xuICAgIH1cbiAgICBpZiAoXG4gICAgICBsb2NhbC5sYXN0X21vZGlmaWVkICE9PSB1bmRlZmluZWQgJiZcbiAgICAgIGxvY2FsLmxhc3RfbW9kaWZpZWQgPT09IHJlbW90ZS5sYXN0X21vZGlmaWVkXG4gICAgKSB7XG4gICAgICAvLyBJZiBvdXIgbG9jYWwgdmVyc2lvbiBoYXMgdGhlIHNhbWUgbGFzdF9tb2RpZmllZCBhcyB0aGUgcmVtb3RlXG4gICAgICAvLyBvbmUsIHRoaXMgcmVwcmVzZW50cyBhbiBvYmplY3QgdGhhdCBjb3JyZXNwb25kcyB0byBhIHJlc29sdmVkXG4gICAgICAvLyBjb25mbGljdC4gT3VyIGxvY2FsIHZlcnNpb24gcmVwcmVzZW50cyB0aGUgZmluYWwgb3V0cHV0LCBzb1xuICAgICAgLy8gd2Uga2VlcCB0aGF0IG9uZS4gKE5vIHRyYW5zYWN0aW9uIG9wZXJhdGlvbiB0byBkby4pXG4gICAgICAvLyBCdXQgaWYgb3VyIGxhc3RfbW9kaWZpZWQgaXMgdW5kZWZpbmVkLFxuICAgICAgLy8gdGhhdCBtZWFucyB3ZSd2ZSBjcmVhdGVkIHRoZSBzYW1lIG9iamVjdCBsb2NhbGx5IGFzIG9uZSBvblxuICAgICAgLy8gdGhlIHNlcnZlciwgd2hpY2ggKm11c3QqIGJlIGEgY29uZmxpY3QuXG4gICAgICByZXR1cm4geyB0eXBlOiBcInZvaWRcIiB9O1xuICAgIH1cbiAgICByZXR1cm4ge1xuICAgICAgdHlwZTogXCJjb25mbGljdHNcIixcbiAgICAgIGRhdGE6IHsgdHlwZTogXCJpbmNvbWluZ1wiLCBsb2NhbDogbG9jYWwsIHJlbW90ZTogcmVtb3RlIH0sXG4gICAgfTtcbiAgfVxuICAvLyBMb2NhbCByZWNvcmQgd2FzIHN5bmNlZC5cbiAgaWYgKHJlbW90ZS5kZWxldGVkKSB7XG4gICAgdHJhbnNhY3Rpb24uZGVsZXRlKHJlbW90ZS5pZCk7XG4gICAgcmV0dXJuIHsgdHlwZTogXCJkZWxldGVkXCIsIGRhdGE6IGxvY2FsIH07XG4gIH1cbiAgLy8gSW1wb3J0IGxvY2FsbHkuXG4gIHRyYW5zYWN0aW9uLnVwZGF0ZShzeW5jZWQpO1xuICAvLyBpZiBpZGVudGljYWwsIHNpbXBseSBleGNsdWRlIGl0IGZyb20gYWxsIFN5bmNSZXN1bHRPYmplY3QgbGlzdHNcbiAgY29uc3QgdHlwZSA9IGlzSWRlbnRpY2FsID8gXCJ2b2lkXCIgOiBcInVwZGF0ZWRcIjtcbiAgcmV0dXJuIHsgdHlwZSwgZGF0YTogeyBvbGQ6IGxvY2FsLCBuZXc6IHN5bmNlZCB9IH07XG59XG5cbi8qKlxuICogQWJzdHJhY3RzIGEgY29sbGVjdGlvbiBvZiByZWNvcmRzIHN0b3JlZCBpbiB0aGUgbG9jYWwgZGF0YWJhc2UsIHByb3ZpZGluZ1xuICogQ1JVRCBvcGVyYXRpb25zIGFuZCBzeW5jaHJvbml6YXRpb24gaGVscGVycy5cbiAqL1xuZXhwb3J0IGRlZmF1bHQgY2xhc3MgQ29sbGVjdGlvbiB7XG4gIC8qKlxuICAgKiBDb25zdHJ1Y3Rvci5cbiAgICpcbiAgICogT3B0aW9uczpcbiAgICogLSBge0Jhc2VBZGFwdGVyfSBhZGFwdGVyYCBUaGUgREIgYWRhcHRlciAoZGVmYXVsdDogYElEQmApXG4gICAqXG4gICAqIEBwYXJhbSAge1N0cmluZ30gYnVja2V0ICBUaGUgYnVja2V0IGlkZW50aWZpZXIuXG4gICAqIEBwYXJhbSAge1N0cmluZ30gbmFtZSAgICBUaGUgY29sbGVjdGlvbiBuYW1lLlxuICAgKiBAcGFyYW0gIHtBcGl9ICAgIGFwaSAgICAgVGhlIEFwaSBpbnN0YW5jZS5cbiAgICogQHBhcmFtICB7T2JqZWN0fSBvcHRpb25zIFRoZSBvcHRpb25zIG9iamVjdC5cbiAgICovXG4gIGNvbnN0cnVjdG9yKGJ1Y2tldCwgbmFtZSwgYXBpLCBvcHRpb25zID0ge30pIHtcbiAgICB0aGlzLl9idWNrZXQgPSBidWNrZXQ7XG4gICAgdGhpcy5fbmFtZSA9IG5hbWU7XG4gICAgdGhpcy5fbGFzdE1vZGlmaWVkID0gbnVsbDtcblxuICAgIGNvbnN0IERCQWRhcHRlciA9IG9wdGlvbnMuYWRhcHRlciB8fCBJREI7XG4gICAgaWYgKCFEQkFkYXB0ZXIpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIk5vIGFkYXB0ZXIgcHJvdmlkZWRcIik7XG4gICAgfVxuICAgIGNvbnN0IGRiID0gbmV3IERCQWRhcHRlcihgJHtidWNrZXR9LyR7bmFtZX1gLCBvcHRpb25zLmFkYXB0ZXJPcHRpb25zKTtcbiAgICBpZiAoIShkYiBpbnN0YW5jZW9mIEJhc2VBZGFwdGVyKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVW5zdXBwb3J0ZWQgYWRhcHRlci5cIik7XG4gICAgfVxuICAgIC8vIHB1YmxpYyBwcm9wZXJ0aWVzXG4gICAgLyoqXG4gICAgICogVGhlIGRiIGFkYXB0ZXIgaW5zdGFuY2VcbiAgICAgKiBAdHlwZSB7QmFzZUFkYXB0ZXJ9XG4gICAgICovXG4gICAgdGhpcy5kYiA9IGRiO1xuICAgIC8qKlxuICAgICAqIFRoZSBBcGkgaW5zdGFuY2UuXG4gICAgICogQHR5cGUge0tpbnRvQ2xpZW50fVxuICAgICAqL1xuICAgIHRoaXMuYXBpID0gYXBpO1xuICAgIC8qKlxuICAgICAqIFRoZSBldmVudCBlbWl0dGVyIGluc3RhbmNlLlxuICAgICAqIEB0eXBlIHtFdmVudEVtaXR0ZXJ9XG4gICAgICovXG4gICAgdGhpcy5ldmVudHMgPSBvcHRpb25zLmV2ZW50cztcbiAgICAvKipcbiAgICAgKiBUaGUgSWRTY2hlbWEgaW5zdGFuY2UuXG4gICAgICogQHR5cGUge09iamVjdH1cbiAgICAgKi9cbiAgICB0aGlzLmlkU2NoZW1hID0gdGhpcy5fdmFsaWRhdGVJZFNjaGVtYShvcHRpb25zLmlkU2NoZW1hKTtcbiAgICAvKipcbiAgICAgKiBUaGUgbGlzdCBvZiByZW1vdGUgdHJhbnNmb3JtZXJzLlxuICAgICAqIEB0eXBlIHtBcnJheX1cbiAgICAgKi9cbiAgICB0aGlzLnJlbW90ZVRyYW5zZm9ybWVycyA9IHRoaXMuX3ZhbGlkYXRlUmVtb3RlVHJhbnNmb3JtZXJzKFxuICAgICAgb3B0aW9ucy5yZW1vdGVUcmFuc2Zvcm1lcnNcbiAgICApO1xuICAgIC8qKlxuICAgICAqIFRoZSBsaXN0IG9mIGhvb2tzLlxuICAgICAqIEB0eXBlIHtPYmplY3R9XG4gICAgICovXG4gICAgdGhpcy5ob29rcyA9IHRoaXMuX3ZhbGlkYXRlSG9va3Mob3B0aW9ucy5ob29rcyk7XG4gICAgLyoqXG4gICAgICogVGhlIGxpc3Qgb2YgZmllbGRzIG5hbWVzIHRoYXQgd2lsbCByZW1haW4gbG9jYWwuXG4gICAgICogQHR5cGUge0FycmF5fVxuICAgICAqL1xuICAgIHRoaXMubG9jYWxGaWVsZHMgPSBvcHRpb25zLmxvY2FsRmllbGRzIHx8IFtdO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSBjb2xsZWN0aW9uIG5hbWUuXG4gICAqIEB0eXBlIHtTdHJpbmd9XG4gICAqL1xuICBnZXQgbmFtZSgpIHtcbiAgICByZXR1cm4gdGhpcy5fbmFtZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgYnVja2V0IG5hbWUuXG4gICAqIEB0eXBlIHtTdHJpbmd9XG4gICAqL1xuICBnZXQgYnVja2V0KCkge1xuICAgIHJldHVybiB0aGlzLl9idWNrZXQ7XG4gIH1cblxuICAvKipcbiAgICogVGhlIGxhc3QgbW9kaWZpZWQgdGltZXN0YW1wLlxuICAgKiBAdHlwZSB7TnVtYmVyfVxuICAgKi9cbiAgZ2V0IGxhc3RNb2RpZmllZCgpIHtcbiAgICByZXR1cm4gdGhpcy5fbGFzdE1vZGlmaWVkO1xuICB9XG5cbiAgLyoqXG4gICAqIFN5bmNocm9uaXphdGlvbiBzdHJhdGVnaWVzLiBBdmFpbGFibGUgc3RyYXRlZ2llcyBhcmU6XG4gICAqXG4gICAqIC0gYE1BTlVBTGA6IENvbmZsaWN0cyB3aWxsIGJlIHJlcG9ydGVkIGluIGEgZGVkaWNhdGVkIGFycmF5LlxuICAgKiAtIGBTRVJWRVJfV0lOU2A6IENvbmZsaWN0cyBhcmUgcmVzb2x2ZWQgdXNpbmcgcmVtb3RlIGRhdGEuXG4gICAqIC0gYENMSUVOVF9XSU5TYDogQ29uZmxpY3RzIGFyZSByZXNvbHZlZCB1c2luZyBsb2NhbCBkYXRhLlxuICAgKlxuICAgKiBAdHlwZSB7T2JqZWN0fVxuICAgKi9cbiAgc3RhdGljIGdldCBzdHJhdGVneSgpIHtcbiAgICByZXR1cm4ge1xuICAgICAgQ0xJRU5UX1dJTlM6IFwiY2xpZW50X3dpbnNcIixcbiAgICAgIFNFUlZFUl9XSU5TOiBcInNlcnZlcl93aW5zXCIsXG4gICAgICBQVUxMX09OTFk6IFwicHVsbF9vbmx5XCIsXG4gICAgICBNQU5VQUw6IFwibWFudWFsXCIsXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBWYWxpZGF0ZXMgYW4gaWRTY2hlbWEuXG4gICAqXG4gICAqIEBwYXJhbSAge09iamVjdHx1bmRlZmluZWR9IGlkU2NoZW1hXG4gICAqIEByZXR1cm4ge09iamVjdH1cbiAgICovXG4gIF92YWxpZGF0ZUlkU2NoZW1hKGlkU2NoZW1hKSB7XG4gICAgaWYgKHR5cGVvZiBpZFNjaGVtYSA9PT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgcmV0dXJuIGNyZWF0ZVVVSURTY2hlbWEoKTtcbiAgICB9XG4gICAgaWYgKHR5cGVvZiBpZFNjaGVtYSAhPT0gXCJvYmplY3RcIikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiaWRTY2hlbWEgbXVzdCBiZSBhbiBvYmplY3QuXCIpO1xuICAgIH0gZWxzZSBpZiAodHlwZW9mIGlkU2NoZW1hLmdlbmVyYXRlICE9PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcImlkU2NoZW1hIG11c3QgcHJvdmlkZSBhIGdlbmVyYXRlIGZ1bmN0aW9uLlwiKTtcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBpZFNjaGVtYS52YWxpZGF0ZSAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJpZFNjaGVtYSBtdXN0IHByb3ZpZGUgYSB2YWxpZGF0ZSBmdW5jdGlvbi5cIik7XG4gICAgfVxuICAgIHJldHVybiBpZFNjaGVtYTtcbiAgfVxuXG4gIC8qKlxuICAgKiBWYWxpZGF0ZXMgYSBsaXN0IG9mIHJlbW90ZSB0cmFuc2Zvcm1lcnMuXG4gICAqXG4gICAqIEBwYXJhbSAge0FycmF5fHVuZGVmaW5lZH0gcmVtb3RlVHJhbnNmb3JtZXJzXG4gICAqIEByZXR1cm4ge0FycmF5fVxuICAgKi9cbiAgX3ZhbGlkYXRlUmVtb3RlVHJhbnNmb3JtZXJzKHJlbW90ZVRyYW5zZm9ybWVycykge1xuICAgIGlmICh0eXBlb2YgcmVtb3RlVHJhbnNmb3JtZXJzID09PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgICByZXR1cm4gW107XG4gICAgfVxuICAgIGlmICghQXJyYXkuaXNBcnJheShyZW1vdGVUcmFuc2Zvcm1lcnMpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJyZW1vdGVUcmFuc2Zvcm1lcnMgc2hvdWxkIGJlIGFuIGFycmF5LlwiKTtcbiAgICB9XG4gICAgcmV0dXJuIHJlbW90ZVRyYW5zZm9ybWVycy5tYXAodHJhbnNmb3JtZXIgPT4ge1xuICAgICAgaWYgKHR5cGVvZiB0cmFuc2Zvcm1lciAhPT0gXCJvYmplY3RcIikge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJBIHRyYW5zZm9ybWVyIG11c3QgYmUgYW4gb2JqZWN0LlwiKTtcbiAgICAgIH0gZWxzZSBpZiAodHlwZW9mIHRyYW5zZm9ybWVyLmVuY29kZSAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIkEgdHJhbnNmb3JtZXIgbXVzdCBwcm92aWRlIGFuIGVuY29kZSBmdW5jdGlvbi5cIik7XG4gICAgICB9IGVsc2UgaWYgKHR5cGVvZiB0cmFuc2Zvcm1lci5kZWNvZGUgIT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJBIHRyYW5zZm9ybWVyIG11c3QgcHJvdmlkZSBhIGRlY29kZSBmdW5jdGlvbi5cIik7XG4gICAgICB9XG4gICAgICByZXR1cm4gdHJhbnNmb3JtZXI7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogVmFsaWRhdGUgdGhlIHBhc3NlZCBob29rIGlzIGNvcnJlY3QuXG4gICAqXG4gICAqIEBwYXJhbSB7QXJyYXl8dW5kZWZpbmVkfSBob29rLlxuICAgKiBAcmV0dXJuIHtBcnJheX1cbiAgICoqL1xuICBfdmFsaWRhdGVIb29rKGhvb2spIHtcbiAgICBpZiAoIUFycmF5LmlzQXJyYXkoaG9vaykpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIkEgaG9vayBkZWZpbml0aW9uIHNob3VsZCBiZSBhbiBhcnJheSBvZiBmdW5jdGlvbnMuXCIpO1xuICAgIH1cbiAgICByZXR1cm4gaG9vay5tYXAoZm4gPT4ge1xuICAgICAgaWYgKHR5cGVvZiBmbiAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIkEgaG9vayBkZWZpbml0aW9uIHNob3VsZCBiZSBhbiBhcnJheSBvZiBmdW5jdGlvbnMuXCIpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGZuO1xuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFZhbGlkYXRlcyBhIGxpc3Qgb2YgaG9va3MuXG4gICAqXG4gICAqIEBwYXJhbSAge09iamVjdHx1bmRlZmluZWR9IGhvb2tzXG4gICAqIEByZXR1cm4ge09iamVjdH1cbiAgICovXG4gIF92YWxpZGF0ZUhvb2tzKGhvb2tzKSB7XG4gICAgaWYgKHR5cGVvZiBob29rcyA9PT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgcmV0dXJuIHt9O1xuICAgIH1cbiAgICBpZiAoQXJyYXkuaXNBcnJheShob29rcykpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcImhvb2tzIHNob3VsZCBiZSBhbiBvYmplY3QsIG5vdCBhbiBhcnJheS5cIik7XG4gICAgfVxuICAgIGlmICh0eXBlb2YgaG9va3MgIT09IFwib2JqZWN0XCIpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcImhvb2tzIHNob3VsZCBiZSBhbiBvYmplY3QuXCIpO1xuICAgIH1cblxuICAgIGNvbnN0IHZhbGlkYXRlZEhvb2tzID0ge307XG5cbiAgICBmb3IgKGNvbnN0IGhvb2sgaW4gaG9va3MpIHtcbiAgICAgIGlmICghQVZBSUxBQkxFX0hPT0tTLmluY2x1ZGVzKGhvb2spKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICBcIlRoZSBob29rIHNob3VsZCBiZSBvbmUgb2YgXCIgKyBBVkFJTEFCTEVfSE9PS1Muam9pbihcIiwgXCIpXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgICB2YWxpZGF0ZWRIb29rc1tob29rXSA9IHRoaXMuX3ZhbGlkYXRlSG9vayhob29rc1tob29rXSk7XG4gICAgfVxuICAgIHJldHVybiB2YWxpZGF0ZWRIb29rcztcbiAgfVxuXG4gIC8qKlxuICAgKiBEZWxldGVzIGV2ZXJ5IHJlY29yZHMgaW4gdGhlIGN1cnJlbnQgY29sbGVjdGlvbiBhbmQgbWFya3MgdGhlIGNvbGxlY3Rpb24gYXNcbiAgICogbmV2ZXIgc3luY2VkLlxuICAgKlxuICAgKiBAcmV0dXJuIHtQcm9taXNlfVxuICAgKi9cbiAgYXN5bmMgY2xlYXIoKSB7XG4gICAgYXdhaXQgdGhpcy5kYi5jbGVhcigpO1xuICAgIGF3YWl0IHRoaXMuZGIuc2F2ZU1ldGFkYXRhKG51bGwpO1xuICAgIGF3YWl0IHRoaXMuZGIuc2F2ZUxhc3RNb2RpZmllZChudWxsKTtcbiAgICByZXR1cm4geyBkYXRhOiBbXSwgcGVybWlzc2lvbnM6IHt9IH07XG4gIH1cblxuICAvKipcbiAgICogRW5jb2RlcyBhIHJlY29yZC5cbiAgICpcbiAgICogQHBhcmFtICB7U3RyaW5nfSB0eXBlICAgRWl0aGVyIFwicmVtb3RlXCIgb3IgXCJsb2NhbFwiLlxuICAgKiBAcGFyYW0gIHtPYmplY3R9IHJlY29yZCBUaGUgcmVjb3JkIG9iamVjdCB0byBlbmNvZGUuXG4gICAqIEByZXR1cm4ge1Byb21pc2V9XG4gICAqL1xuICBfZW5jb2RlUmVjb3JkKHR5cGUsIHJlY29yZCkge1xuICAgIGlmICghdGhpc1tgJHt0eXBlfVRyYW5zZm9ybWVyc2BdLmxlbmd0aCkge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShyZWNvcmQpO1xuICAgIH1cbiAgICByZXR1cm4gd2F0ZXJmYWxsKFxuICAgICAgdGhpc1tgJHt0eXBlfVRyYW5zZm9ybWVyc2BdLm1hcCh0cmFuc2Zvcm1lciA9PiB7XG4gICAgICAgIHJldHVybiByZWNvcmQgPT4gdHJhbnNmb3JtZXIuZW5jb2RlKHJlY29yZCk7XG4gICAgICB9KSxcbiAgICAgIHJlY29yZFxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogRGVjb2RlcyBhIHJlY29yZC5cbiAgICpcbiAgICogQHBhcmFtICB7U3RyaW5nfSB0eXBlICAgRWl0aGVyIFwicmVtb3RlXCIgb3IgXCJsb2NhbFwiLlxuICAgKiBAcGFyYW0gIHtPYmplY3R9IHJlY29yZCBUaGUgcmVjb3JkIG9iamVjdCB0byBkZWNvZGUuXG4gICAqIEByZXR1cm4ge1Byb21pc2V9XG4gICAqL1xuICBfZGVjb2RlUmVjb3JkKHR5cGUsIHJlY29yZCkge1xuICAgIGlmICghdGhpc1tgJHt0eXBlfVRyYW5zZm9ybWVyc2BdLmxlbmd0aCkge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShyZWNvcmQpO1xuICAgIH1cbiAgICByZXR1cm4gd2F0ZXJmYWxsKFxuICAgICAgdGhpc1tgJHt0eXBlfVRyYW5zZm9ybWVyc2BdLnJldmVyc2UoKS5tYXAodHJhbnNmb3JtZXIgPT4ge1xuICAgICAgICByZXR1cm4gcmVjb3JkID0+IHRyYW5zZm9ybWVyLmRlY29kZShyZWNvcmQpO1xuICAgICAgfSksXG4gICAgICByZWNvcmRcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIEFkZHMgYSByZWNvcmQgdG8gdGhlIGxvY2FsIGRhdGFiYXNlLCBhc3NlcnRpbmcgdGhhdCBub25lXG4gICAqIGFscmVhZHkgZXhpc3Qgd2l0aCB0aGlzIElELlxuICAgKlxuICAgKiBOb3RlOiBJZiBlaXRoZXIgdGhlIGB1c2VSZWNvcmRJZGAgb3IgYHN5bmNlZGAgb3B0aW9ucyBhcmUgdHJ1ZSwgdGhlbiB0aGVcbiAgICogcmVjb3JkIG9iamVjdCBtdXN0IGNvbnRhaW4gdGhlIGlkIGZpZWxkIHRvIGJlIHZhbGlkYXRlZC4gSWYgbm9uZSBvZiB0aGVzZVxuICAgKiBvcHRpb25zIGFyZSB0cnVlLCBhbiBpZCBpcyBnZW5lcmF0ZWQgdXNpbmcgdGhlIGN1cnJlbnQgSWRTY2hlbWE7IGluIHRoaXNcbiAgICogY2FzZSwgdGhlIHJlY29yZCBwYXNzZWQgbXVzdCBub3QgaGF2ZSBhbiBpZC5cbiAgICpcbiAgICogT3B0aW9uczpcbiAgICogLSB7Qm9vbGVhbn0gc3luY2VkICAgICAgIFNldHMgcmVjb3JkIHN0YXR1cyB0byBcInN5bmNlZFwiIChkZWZhdWx0OiBgZmFsc2VgKS5cbiAgICogLSB7Qm9vbGVhbn0gdXNlUmVjb3JkSWQgIEZvcmNlcyB0aGUgYGlkYCBmaWVsZCBmcm9tIHRoZSByZWNvcmQgdG8gYmUgdXNlZCxcbiAgICogICAgICAgICAgICAgICAgICAgICAgICAgIGluc3RlYWQgb2Ygb25lIHRoYXQgaXMgZ2VuZXJhdGVkIGF1dG9tYXRpY2FsbHlcbiAgICogICAgICAgICAgICAgICAgICAgICAgICAgIChkZWZhdWx0OiBgZmFsc2VgKS5cbiAgICpcbiAgICogQHBhcmFtICB7T2JqZWN0fSByZWNvcmRcbiAgICogQHBhcmFtICB7T2JqZWN0fSBvcHRpb25zXG4gICAqIEByZXR1cm4ge1Byb21pc2V9XG4gICAqL1xuICBjcmVhdGUocmVjb3JkLCBvcHRpb25zID0geyB1c2VSZWNvcmRJZDogZmFsc2UsIHN5bmNlZDogZmFsc2UgfSkge1xuICAgIC8vIFZhbGlkYXRlIHRoZSByZWNvcmQgYW5kIGl0cyBJRCAoaWYgYW55KSwgZXZlbiB0aG91Z2ggdGhpc1xuICAgIC8vIHZhbGlkYXRpb24gaXMgYWxzbyBkb25lIGluIHRoZSBDb2xsZWN0aW9uVHJhbnNhY3Rpb24gbWV0aG9kLFxuICAgIC8vIGJlY2F1c2Ugd2UgbmVlZCB0byBwYXNzIHRoZSBJRCB0byBwcmVsb2FkSWRzLlxuICAgIGNvbnN0IHJlamVjdCA9IG1zZyA9PiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IobXNnKSk7XG4gICAgaWYgKHR5cGVvZiByZWNvcmQgIT09IFwib2JqZWN0XCIpIHtcbiAgICAgIHJldHVybiByZWplY3QoXCJSZWNvcmQgaXMgbm90IGFuIG9iamVjdC5cIik7XG4gICAgfVxuICAgIGlmIChcbiAgICAgIChvcHRpb25zLnN5bmNlZCB8fCBvcHRpb25zLnVzZVJlY29yZElkKSAmJlxuICAgICAgIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChyZWNvcmQsIFwiaWRcIilcbiAgICApIHtcbiAgICAgIHJldHVybiByZWplY3QoXG4gICAgICAgIFwiTWlzc2luZyByZXF1aXJlZCBJZDsgc3luY2VkIGFuZCB1c2VSZWNvcmRJZCBvcHRpb25zIHJlcXVpcmUgb25lXCJcbiAgICAgICk7XG4gICAgfVxuICAgIGlmIChcbiAgICAgICFvcHRpb25zLnN5bmNlZCAmJlxuICAgICAgIW9wdGlvbnMudXNlUmVjb3JkSWQgJiZcbiAgICAgIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChyZWNvcmQsIFwiaWRcIilcbiAgICApIHtcbiAgICAgIHJldHVybiByZWplY3QoXCJFeHRyYW5lb3VzIElkOyBjYW4ndCBjcmVhdGUgYSByZWNvcmQgaGF2aW5nIG9uZSBzZXQuXCIpO1xuICAgIH1cbiAgICBjb25zdCBuZXdSZWNvcmQgPSB7XG4gICAgICAuLi5yZWNvcmQsXG4gICAgICBpZDpcbiAgICAgICAgb3B0aW9ucy5zeW5jZWQgfHwgb3B0aW9ucy51c2VSZWNvcmRJZFxuICAgICAgICAgID8gcmVjb3JkLmlkXG4gICAgICAgICAgOiB0aGlzLmlkU2NoZW1hLmdlbmVyYXRlKHJlY29yZCksXG4gICAgICBfc3RhdHVzOiBvcHRpb25zLnN5bmNlZCA/IFwic3luY2VkXCIgOiBcImNyZWF0ZWRcIixcbiAgICB9O1xuICAgIGlmICghdGhpcy5pZFNjaGVtYS52YWxpZGF0ZShuZXdSZWNvcmQuaWQpKSB7XG4gICAgICByZXR1cm4gcmVqZWN0KGBJbnZhbGlkIElkOiAke25ld1JlY29yZC5pZH1gKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuZXhlY3V0ZSh0eG4gPT4gdHhuLmNyZWF0ZShuZXdSZWNvcmQpLCB7XG4gICAgICBwcmVsb2FkSWRzOiBbbmV3UmVjb3JkLmlkXSxcbiAgICB9KS5jYXRjaChlcnIgPT4ge1xuICAgICAgaWYgKG9wdGlvbnMudXNlUmVjb3JkSWQpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgIFwiQ291bGRuJ3QgY3JlYXRlIHJlY29yZC4gSXQgbWF5IGhhdmUgYmVlbiB2aXJ0dWFsbHkgZGVsZXRlZC5cIlxuICAgICAgICApO1xuICAgICAgfVxuICAgICAgdGhyb3cgZXJyO1xuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIExpa2Uge0BsaW5rIENvbGxlY3Rpb25UcmFuc2FjdGlvbiN1cGRhdGV9LCBidXQgd3JhcHBlZCBpbiBpdHMgb3duIHRyYW5zYWN0aW9uLlxuICAgKlxuICAgKiBPcHRpb25zOlxuICAgKiAtIHtCb29sZWFufSBzeW5jZWQ6IFNldHMgcmVjb3JkIHN0YXR1cyB0byBcInN5bmNlZFwiIChkZWZhdWx0OiBmYWxzZSlcbiAgICogLSB7Qm9vbGVhbn0gcGF0Y2g6ICBFeHRlbmRzIHRoZSBleGlzdGluZyByZWNvcmQgaW5zdGVhZCBvZiBvdmVyd3JpdGluZyBpdFxuICAgKiAgIChkZWZhdWx0OiBmYWxzZSlcbiAgICpcbiAgICogQHBhcmFtICB7T2JqZWN0fSByZWNvcmRcbiAgICogQHBhcmFtICB7T2JqZWN0fSBvcHRpb25zXG4gICAqIEByZXR1cm4ge1Byb21pc2V9XG4gICAqL1xuICB1cGRhdGUocmVjb3JkLCBvcHRpb25zID0geyBzeW5jZWQ6IGZhbHNlLCBwYXRjaDogZmFsc2UgfSkge1xuICAgIC8vIFZhbGlkYXRlIHRoZSByZWNvcmQgYW5kIGl0cyBJRCwgZXZlbiB0aG91Z2ggdGhpcyB2YWxpZGF0aW9uIGlzXG4gICAgLy8gYWxzbyBkb25lIGluIHRoZSBDb2xsZWN0aW9uVHJhbnNhY3Rpb24gbWV0aG9kLCBiZWNhdXNlIHdlIG5lZWRcbiAgICAvLyB0byBwYXNzIHRoZSBJRCB0byBwcmVsb2FkSWRzLlxuICAgIGlmICh0eXBlb2YgcmVjb3JkICE9PSBcIm9iamVjdFwiKSB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiUmVjb3JkIGlzIG5vdCBhbiBvYmplY3QuXCIpKTtcbiAgICB9XG4gICAgaWYgKCFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwocmVjb3JkLCBcImlkXCIpKSB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKFwiQ2Fubm90IHVwZGF0ZSBhIHJlY29yZCBtaXNzaW5nIGlkLlwiKSk7XG4gICAgfVxuICAgIGlmICghdGhpcy5pZFNjaGVtYS52YWxpZGF0ZShyZWNvcmQuaWQpKSB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKGBJbnZhbGlkIElkOiAke3JlY29yZC5pZH1gKSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuZXhlY3V0ZSh0eG4gPT4gdHhuLnVwZGF0ZShyZWNvcmQsIG9wdGlvbnMpLCB7XG4gICAgICBwcmVsb2FkSWRzOiBbcmVjb3JkLmlkXSxcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBMaWtlIHtAbGluayBDb2xsZWN0aW9uVHJhbnNhY3Rpb24jdXBzZXJ0fSwgYnV0IHdyYXBwZWQgaW4gaXRzIG93biB0cmFuc2FjdGlvbi5cbiAgICpcbiAgICogQHBhcmFtICB7T2JqZWN0fSByZWNvcmRcbiAgICogQHJldHVybiB7UHJvbWlzZX1cbiAgICovXG4gIHVwc2VydChyZWNvcmQpIHtcbiAgICAvLyBWYWxpZGF0ZSB0aGUgcmVjb3JkIGFuZCBpdHMgSUQsIGV2ZW4gdGhvdWdoIHRoaXMgdmFsaWRhdGlvbiBpc1xuICAgIC8vIGFsc28gZG9uZSBpbiB0aGUgQ29sbGVjdGlvblRyYW5zYWN0aW9uIG1ldGhvZCwgYmVjYXVzZSB3ZSBuZWVkXG4gICAgLy8gdG8gcGFzcyB0aGUgSUQgdG8gcHJlbG9hZElkcy5cbiAgICBpZiAodHlwZW9mIHJlY29yZCAhPT0gXCJvYmplY3RcIikge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihcIlJlY29yZCBpcyBub3QgYW4gb2JqZWN0LlwiKSk7XG4gICAgfVxuICAgIGlmICghT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHJlY29yZCwgXCJpZFwiKSkge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihcIkNhbm5vdCB1cGRhdGUgYSByZWNvcmQgbWlzc2luZyBpZC5cIikpO1xuICAgIH1cbiAgICBpZiAoIXRoaXMuaWRTY2hlbWEudmFsaWRhdGUocmVjb3JkLmlkKSkge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBFcnJvcihgSW52YWxpZCBJZDogJHtyZWNvcmQuaWR9YCkpO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLmV4ZWN1dGUodHhuID0+IHR4bi51cHNlcnQocmVjb3JkKSwgeyBwcmVsb2FkSWRzOiBbcmVjb3JkLmlkXSB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBMaWtlIHtAbGluayBDb2xsZWN0aW9uVHJhbnNhY3Rpb24jZ2V0fSwgYnV0IHdyYXBwZWQgaW4gaXRzIG93biB0cmFuc2FjdGlvbi5cbiAgICpcbiAgICogT3B0aW9uczpcbiAgICogLSB7Qm9vbGVhbn0gaW5jbHVkZURlbGV0ZWQ6IEluY2x1ZGUgdmlydHVhbGx5IGRlbGV0ZWQgcmVjb3Jkcy5cbiAgICpcbiAgICogQHBhcmFtICB7U3RyaW5nfSBpZFxuICAgKiBAcGFyYW0gIHtPYmplY3R9IG9wdGlvbnNcbiAgICogQHJldHVybiB7UHJvbWlzZX1cbiAgICovXG4gIGdldChpZCwgb3B0aW9ucyA9IHsgaW5jbHVkZURlbGV0ZWQ6IGZhbHNlIH0pIHtcbiAgICByZXR1cm4gdGhpcy5leGVjdXRlKHR4biA9PiB0eG4uZ2V0KGlkLCBvcHRpb25zKSwgeyBwcmVsb2FkSWRzOiBbaWRdIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIExpa2Uge0BsaW5rIENvbGxlY3Rpb25UcmFuc2FjdGlvbiNnZXRBbnl9LCBidXQgd3JhcHBlZCBpbiBpdHMgb3duIHRyYW5zYWN0aW9uLlxuICAgKlxuICAgKiBAcGFyYW0gIHtTdHJpbmd9IGlkXG4gICAqIEByZXR1cm4ge1Byb21pc2V9XG4gICAqL1xuICBnZXRBbnkoaWQpIHtcbiAgICByZXR1cm4gdGhpcy5leGVjdXRlKHR4biA9PiB0eG4uZ2V0QW55KGlkKSwgeyBwcmVsb2FkSWRzOiBbaWRdIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFNhbWUgYXMge0BsaW5rIENvbGxlY3Rpb24jZGVsZXRlfSwgYnV0IHdyYXBwZWQgaW4gaXRzIG93biB0cmFuc2FjdGlvbi5cbiAgICpcbiAgICogT3B0aW9uczpcbiAgICogLSB7Qm9vbGVhbn0gdmlydHVhbDogV2hlbiBzZXQgdG8gYHRydWVgLCBkb2Vzbid0IGFjdHVhbGx5IGRlbGV0ZSB0aGUgcmVjb3JkLFxuICAgKiAgIHVwZGF0ZSBpdHMgYF9zdGF0dXNgIGF0dHJpYnV0ZSB0byBgZGVsZXRlZGAgaW5zdGVhZCAoZGVmYXVsdDogdHJ1ZSlcbiAgICpcbiAgICogQHBhcmFtICB7U3RyaW5nfSBpZCAgICAgICBUaGUgcmVjb3JkJ3MgSWQuXG4gICAqIEBwYXJhbSAge09iamVjdH0gb3B0aW9ucyAgVGhlIG9wdGlvbnMgb2JqZWN0LlxuICAgKiBAcmV0dXJuIHtQcm9taXNlfVxuICAgKi9cbiAgZGVsZXRlKGlkLCBvcHRpb25zID0geyB2aXJ0dWFsOiB0cnVlIH0pIHtcbiAgICByZXR1cm4gdGhpcy5leGVjdXRlKFxuICAgICAgdHJhbnNhY3Rpb24gPT4ge1xuICAgICAgICByZXR1cm4gdHJhbnNhY3Rpb24uZGVsZXRlKGlkLCBvcHRpb25zKTtcbiAgICAgIH0sXG4gICAgICB7IHByZWxvYWRJZHM6IFtpZF0gfVxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogU2FtZSBhcyB7QGxpbmsgQ29sbGVjdGlvbiNkZWxldGVBbGx9LCBidXQgd3JhcHBlZCBpbiBpdHMgb3duIHRyYW5zYWN0aW9uLCBleGVjdWxkaW5nIHRoZSBwYXJhbWV0ZXIuXG4gICAqXG4gICAqIEByZXR1cm4ge1Byb21pc2V9XG4gICAqL1xuICBhc3luYyBkZWxldGVBbGwoKSB7XG4gICAgY29uc3QgeyBkYXRhIH0gPSBhd2FpdCB0aGlzLmxpc3Qoe30sIHsgaW5jbHVkZURlbGV0ZWQ6IGZhbHNlIH0pO1xuICAgIGNvbnN0IHJlY29yZElkcyA9IGRhdGEubWFwKHJlY29yZCA9PiByZWNvcmQuaWQpO1xuICAgIHJldHVybiB0aGlzLmV4ZWN1dGUoXG4gICAgICB0cmFuc2FjdGlvbiA9PiB7XG4gICAgICAgIHJldHVybiB0cmFuc2FjdGlvbi5kZWxldGVBbGwocmVjb3JkSWRzKTtcbiAgICAgIH0sXG4gICAgICB7IHByZWxvYWRJZHM6IHJlY29yZElkcyB9XG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgc2FtZSBhcyB7QGxpbmsgQ29sbGVjdGlvblRyYW5zYWN0aW9uI2RlbGV0ZUFueX0sIGJ1dCB3cmFwcGVkXG4gICAqIGluIGl0cyBvd24gdHJhbnNhY3Rpb24uXG4gICAqXG4gICAqIEBwYXJhbSAge1N0cmluZ30gaWQgICAgICAgVGhlIHJlY29yZCdzIElkLlxuICAgKiBAcmV0dXJuIHtQcm9taXNlfVxuICAgKi9cbiAgZGVsZXRlQW55KGlkKSB7XG4gICAgcmV0dXJuIHRoaXMuZXhlY3V0ZSh0eG4gPT4gdHhuLmRlbGV0ZUFueShpZCksIHsgcHJlbG9hZElkczogW2lkXSB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBMaXN0cyByZWNvcmRzIGZyb20gdGhlIGxvY2FsIGRhdGFiYXNlLlxuICAgKlxuICAgKiBQYXJhbXM6XG4gICAqIC0ge09iamVjdH0gZmlsdGVycyBGaWx0ZXIgdGhlIHJlc3VsdHMgKGRlZmF1bHQ6IGB7fWApLlxuICAgKiAtIHtTdHJpbmd9IG9yZGVyICAgVGhlIG9yZGVyIHRvIGFwcGx5ICAgKGRlZmF1bHQ6IGAtbGFzdF9tb2RpZmllZGApLlxuICAgKlxuICAgKiBPcHRpb25zOlxuICAgKiAtIHtCb29sZWFufSBpbmNsdWRlRGVsZXRlZDogSW5jbHVkZSB2aXJ0dWFsbHkgZGVsZXRlZCByZWNvcmRzLlxuICAgKlxuICAgKiBAcGFyYW0gIHtPYmplY3R9IHBhcmFtcyAgVGhlIGZpbHRlcnMgYW5kIG9yZGVyIHRvIGFwcGx5IHRvIHRoZSByZXN1bHRzLlxuICAgKiBAcGFyYW0gIHtPYmplY3R9IG9wdGlvbnMgVGhlIG9wdGlvbnMgb2JqZWN0LlxuICAgKiBAcmV0dXJuIHtQcm9taXNlfVxuICAgKi9cbiAgYXN5bmMgbGlzdChwYXJhbXMgPSB7fSwgb3B0aW9ucyA9IHsgaW5jbHVkZURlbGV0ZWQ6IGZhbHNlIH0pIHtcbiAgICBwYXJhbXMgPSB7IG9yZGVyOiBcIi1sYXN0X21vZGlmaWVkXCIsIGZpbHRlcnM6IHt9LCAuLi5wYXJhbXMgfTtcbiAgICBjb25zdCByZXN1bHRzID0gYXdhaXQgdGhpcy5kYi5saXN0KHBhcmFtcyk7XG4gICAgbGV0IGRhdGEgPSByZXN1bHRzO1xuICAgIGlmICghb3B0aW9ucy5pbmNsdWRlRGVsZXRlZCkge1xuICAgICAgZGF0YSA9IHJlc3VsdHMuZmlsdGVyKHJlY29yZCA9PiByZWNvcmQuX3N0YXR1cyAhPT0gXCJkZWxldGVkXCIpO1xuICAgIH1cbiAgICByZXR1cm4geyBkYXRhLCBwZXJtaXNzaW9uczoge30gfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBJbXBvcnRzIHJlbW90ZSBjaGFuZ2VzIGludG8gdGhlIGxvY2FsIGRhdGFiYXNlLlxuICAgKiBUaGlzIG1ldGhvZCBpcyBpbiBjaGFyZ2Ugb2YgZGV0ZWN0aW5nIHRoZSBjb25mbGljdHMsIGFuZCByZXNvbHZlIHRoZW1cbiAgICogYWNjb3JkaW5nIHRvIHRoZSBzcGVjaWZpZWQgc3RyYXRlZ3kuXG4gICAqIEBwYXJhbSAge1N5bmNSZXN1bHRPYmplY3R9IHN5bmNSZXN1bHRPYmplY3QgVGhlIHN5bmMgcmVzdWx0IG9iamVjdC5cbiAgICogQHBhcmFtICB7QXJyYXl9ICAgICAgICAgICAgZGVjb2RlZENoYW5nZXMgICBUaGUgbGlzdCBvZiBjaGFuZ2VzIHRvIGltcG9ydCBpbiB0aGUgbG9jYWwgZGF0YWJhc2UuXG4gICAqIEBwYXJhbSAge1N0cmluZ30gICAgICAgICAgIHN0cmF0ZWd5ICAgICAgICAgVGhlIHtAbGluayBDb2xsZWN0aW9uLnN0cmF0ZWd5fSAoZGVmYXVsdDogTUFOVUFMKVxuICAgKiBAcmV0dXJuIHtQcm9taXNlfVxuICAgKi9cbiAgYXN5bmMgaW1wb3J0Q2hhbmdlcyhcbiAgICBzeW5jUmVzdWx0T2JqZWN0LFxuICAgIGRlY29kZWRDaGFuZ2VzLFxuICAgIHN0cmF0ZWd5ID0gQ29sbGVjdGlvbi5zdHJhdGVneS5NQU5VQUxcbiAgKSB7XG4gICAgLy8gUmV0cmlldmUgcmVjb3JkcyBtYXRjaGluZyBjaGFuZ2UgaWRzLlxuICAgIHRyeSB7XG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGRlY29kZWRDaGFuZ2VzLmxlbmd0aDsgaSArPSBJTVBPUlRfQ0hVTktfU0laRSkge1xuICAgICAgICBjb25zdCBzbGljZSA9IGRlY29kZWRDaGFuZ2VzLnNsaWNlKGksIGkgKyBJTVBPUlRfQ0hVTktfU0laRSk7XG5cbiAgICAgICAgY29uc3QgeyBpbXBvcnRzLCByZXNvbHZlZCB9ID0gYXdhaXQgdGhpcy5kYi5leGVjdXRlKFxuICAgICAgICAgIHRyYW5zYWN0aW9uID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGltcG9ydHMgPSBzbGljZS5tYXAocmVtb3RlID0+IHtcbiAgICAgICAgICAgICAgLy8gU3RvcmUgcmVtb3RlIGNoYW5nZSBpbnRvIGxvY2FsIGRhdGFiYXNlLlxuICAgICAgICAgICAgICByZXR1cm4gaW1wb3J0Q2hhbmdlKFxuICAgICAgICAgICAgICAgIHRyYW5zYWN0aW9uLFxuICAgICAgICAgICAgICAgIHJlbW90ZSxcbiAgICAgICAgICAgICAgICB0aGlzLmxvY2FsRmllbGRzLFxuICAgICAgICAgICAgICAgIHN0cmF0ZWd5XG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGNvbnN0IGNvbmZsaWN0cyA9IGltcG9ydHNcbiAgICAgICAgICAgICAgLmZpbHRlcihpID0+IGkudHlwZSA9PT0gXCJjb25mbGljdHNcIilcbiAgICAgICAgICAgICAgLm1hcChpID0+IGkuZGF0YSk7XG4gICAgICAgICAgICBjb25zdCByZXNvbHZlZCA9IHRoaXMuX2hhbmRsZUNvbmZsaWN0cyhcbiAgICAgICAgICAgICAgdHJhbnNhY3Rpb24sXG4gICAgICAgICAgICAgIGNvbmZsaWN0cyxcbiAgICAgICAgICAgICAgc3RyYXRlZ3lcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICByZXR1cm4geyBpbXBvcnRzLCByZXNvbHZlZCB9O1xuICAgICAgICAgIH0sXG4gICAgICAgICAgeyBwcmVsb2FkOiBzbGljZS5tYXAocmVjb3JkID0+IHJlY29yZC5pZCkgfVxuICAgICAgICApO1xuXG4gICAgICAgIC8vIExpc3RzIG9mIGNyZWF0ZWQvdXBkYXRlZC9kZWxldGVkIHJlY29yZHNcbiAgICAgICAgaW1wb3J0cy5mb3JFYWNoKCh7IHR5cGUsIGRhdGEgfSkgPT4gc3luY1Jlc3VsdE9iamVjdC5hZGQodHlwZSwgZGF0YSkpO1xuICAgICAgICAvLyBBdXRvbWF0aWNhbGx5IHJlc29sdmVkIGNvbmZsaWN0cyAoaWYgbm90IG1hbnVhbClcbiAgICAgICAgaWYgKHJlc29sdmVkLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICBzeW5jUmVzdWx0T2JqZWN0LnJlc2V0KFwiY29uZmxpY3RzXCIpLmFkZChcInJlc29sdmVkXCIsIHJlc29sdmVkKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgY29uc3QgZGF0YSA9IHtcbiAgICAgICAgdHlwZTogXCJpbmNvbWluZ1wiLFxuICAgICAgICBtZXNzYWdlOiBlcnIubWVzc2FnZSxcbiAgICAgICAgc3RhY2s6IGVyci5zdGFjayxcbiAgICAgIH07XG4gICAgICAvLyBYWFggb25lIGVycm9yIG9mIHRoZSB3aG9sZSB0cmFuc2FjdGlvbiBpbnN0ZWFkIG9mIHBlciBhdG9taWMgb3BcbiAgICAgIHN5bmNSZXN1bHRPYmplY3QuYWRkKFwiZXJyb3JzXCIsIGRhdGEpO1xuICAgIH1cblxuICAgIHJldHVybiBzeW5jUmVzdWx0T2JqZWN0O1xuICB9XG5cbiAgLyoqXG4gICAqIEltcG9ydHMgdGhlIHJlc3BvbnNlcyBvZiBwdXNoZWQgY2hhbmdlcyBpbnRvIHRoZSBsb2NhbCBkYXRhYmFzZS5cbiAgICogQmFzaWNhbGx5IGl0IHN0b3JlcyB0aGUgdGltZXN0YW1wIGFzc2lnbmVkIGJ5IHRoZSBzZXJ2ZXIgaW50byB0aGUgbG9jYWxcbiAgICogZGF0YWJhc2UuXG4gICAqIEBwYXJhbSAge1N5bmNSZXN1bHRPYmplY3R9IHN5bmNSZXN1bHRPYmplY3QgVGhlIHN5bmMgcmVzdWx0IG9iamVjdC5cbiAgICogQHBhcmFtICB7QXJyYXl9ICAgICAgICAgICAgdG9BcHBseUxvY2FsbHkgICBUaGUgbGlzdCBvZiBjaGFuZ2VzIHRvIGltcG9ydCBpbiB0aGUgbG9jYWwgZGF0YWJhc2UuXG4gICAqIEBwYXJhbSAge0FycmF5fSAgICAgICAgICAgIGNvbmZsaWN0cyAgICAgICAgVGhlIGxpc3Qgb2YgY29uZmxpY3RzIHRoYXQgaGF2ZSB0byBiZSByZXNvbHZlZC5cbiAgICogQHBhcmFtICB7U3RyaW5nfSAgICAgICAgICAgc3RyYXRlZ3kgICAgICAgICBUaGUge0BsaW5rIENvbGxlY3Rpb24uc3RyYXRlZ3l9LlxuICAgKiBAcmV0dXJuIHtQcm9taXNlfVxuICAgKi9cbiAgYXN5bmMgX2FwcGx5UHVzaGVkUmVzdWx0cyhcbiAgICBzeW5jUmVzdWx0T2JqZWN0LFxuICAgIHRvQXBwbHlMb2NhbGx5LFxuICAgIGNvbmZsaWN0cyxcbiAgICBzdHJhdGVneSA9IENvbGxlY3Rpb24uc3RyYXRlZ3kuTUFOVUFMXG4gICkge1xuICAgIGNvbnN0IHRvRGVsZXRlTG9jYWxseSA9IHRvQXBwbHlMb2NhbGx5LmZpbHRlcihyID0+IHIuZGVsZXRlZCk7XG4gICAgY29uc3QgdG9VcGRhdGVMb2NhbGx5ID0gdG9BcHBseUxvY2FsbHkuZmlsdGVyKHIgPT4gIXIuZGVsZXRlZCk7XG5cbiAgICBjb25zdCB7IHB1Ymxpc2hlZCwgcmVzb2x2ZWQgfSA9IGF3YWl0IHRoaXMuZGIuZXhlY3V0ZSh0cmFuc2FjdGlvbiA9PiB7XG4gICAgICBjb25zdCB1cGRhdGVkID0gdG9VcGRhdGVMb2NhbGx5Lm1hcChyZWNvcmQgPT4ge1xuICAgICAgICBjb25zdCBzeW5jZWQgPSBtYXJrU3luY2VkKHJlY29yZCk7XG4gICAgICAgIHRyYW5zYWN0aW9uLnVwZGF0ZShzeW5jZWQpO1xuICAgICAgICByZXR1cm4gc3luY2VkO1xuICAgICAgfSk7XG4gICAgICBjb25zdCBkZWxldGVkID0gdG9EZWxldGVMb2NhbGx5Lm1hcChyZWNvcmQgPT4ge1xuICAgICAgICB0cmFuc2FjdGlvbi5kZWxldGUocmVjb3JkLmlkKTtcbiAgICAgICAgLy8gQW1lbmQgcmVzdWx0IGRhdGEgd2l0aCB0aGUgZGVsZXRlZCBhdHRyaWJ1dGUgc2V0XG4gICAgICAgIHJldHVybiB7IGlkOiByZWNvcmQuaWQsIGRlbGV0ZWQ6IHRydWUgfTtcbiAgICAgIH0pO1xuICAgICAgY29uc3QgcHVibGlzaGVkID0gdXBkYXRlZC5jb25jYXQoZGVsZXRlZCk7XG4gICAgICAvLyBIYW5kbGUgY29uZmxpY3RzLCBpZiBhbnlcbiAgICAgIGNvbnN0IHJlc29sdmVkID0gdGhpcy5faGFuZGxlQ29uZmxpY3RzKHRyYW5zYWN0aW9uLCBjb25mbGljdHMsIHN0cmF0ZWd5KTtcbiAgICAgIHJldHVybiB7IHB1Ymxpc2hlZCwgcmVzb2x2ZWQgfTtcbiAgICB9KTtcblxuICAgIHN5bmNSZXN1bHRPYmplY3QuYWRkKFwicHVibGlzaGVkXCIsIHB1Ymxpc2hlZCk7XG5cbiAgICBpZiAocmVzb2x2ZWQubGVuZ3RoID4gMCkge1xuICAgICAgc3luY1Jlc3VsdE9iamVjdFxuICAgICAgICAucmVzZXQoXCJjb25mbGljdHNcIilcbiAgICAgICAgLnJlc2V0KFwicmVzb2x2ZWRcIilcbiAgICAgICAgLmFkZChcInJlc29sdmVkXCIsIHJlc29sdmVkKTtcbiAgICB9XG4gICAgcmV0dXJuIHN5bmNSZXN1bHRPYmplY3Q7XG4gIH1cblxuICAvKipcbiAgICogSGFuZGxlcyBzeW5jaHJvbml6YXRpb24gY29uZmxpY3RzIGFjY29yZGluZyB0byBzcGVjaWZpZWQgc3RyYXRlZ3kuXG4gICAqXG4gICAqIEBwYXJhbSAge1N5bmNSZXN1bHRPYmplY3R9IHJlc3VsdCAgICBUaGUgc3luYyByZXN1bHQgb2JqZWN0LlxuICAgKiBAcGFyYW0gIHtTdHJpbmd9ICAgICAgICAgICBzdHJhdGVneSAgVGhlIHtAbGluayBDb2xsZWN0aW9uLnN0cmF0ZWd5fS5cbiAgICogQHJldHVybiB7UHJvbWlzZTxBcnJheTxPYmplY3Q+Pn0gVGhlIHJlc29sdmVkIGNvbmZsaWN0cywgYXMgYW5cbiAgICogICAgYXJyYXkgb2Yge2FjY2VwdGVkLCByZWplY3RlZH0gb2JqZWN0c1xuICAgKi9cbiAgX2hhbmRsZUNvbmZsaWN0cyh0cmFuc2FjdGlvbiwgY29uZmxpY3RzLCBzdHJhdGVneSkge1xuICAgIGlmIChzdHJhdGVneSA9PT0gQ29sbGVjdGlvbi5zdHJhdGVneS5NQU5VQUwpIHtcbiAgICAgIHJldHVybiBbXTtcbiAgICB9XG4gICAgcmV0dXJuIGNvbmZsaWN0cy5tYXAoY29uZmxpY3QgPT4ge1xuICAgICAgY29uc3QgcmVzb2x1dGlvbiA9XG4gICAgICAgIHN0cmF0ZWd5ID09PSBDb2xsZWN0aW9uLnN0cmF0ZWd5LkNMSUVOVF9XSU5TXG4gICAgICAgICAgPyBjb25mbGljdC5sb2NhbFxuICAgICAgICAgIDogY29uZmxpY3QucmVtb3RlO1xuICAgICAgY29uc3QgcmVqZWN0ZWQgPVxuICAgICAgICBzdHJhdGVneSA9PT0gQ29sbGVjdGlvbi5zdHJhdGVneS5DTElFTlRfV0lOU1xuICAgICAgICAgID8gY29uZmxpY3QucmVtb3RlXG4gICAgICAgICAgOiBjb25mbGljdC5sb2NhbDtcbiAgICAgIGxldCBhY2NlcHRlZCwgc3RhdHVzLCBpZDtcbiAgICAgIGlmIChyZXNvbHV0aW9uID09PSBudWxsKSB7XG4gICAgICAgIC8vIFdlIFwicmVzb2x2ZWRcIiB3aXRoIHRoZSBzZXJ2ZXItc2lkZSBkZWxldGlvbi4gRGVsZXRlIGxvY2FsbHkuXG4gICAgICAgIC8vIFRoaXMgb25seSBoYXBwZW5zIGR1cmluZyBTRVJWRVJfV0lOUyBiZWNhdXNlIHRoZSBsb2NhbFxuICAgICAgICAvLyB2ZXJzaW9uIG9mIGEgcmVjb3JkIGNhbiBuZXZlciBiZSBudWxsLlxuICAgICAgICAvLyBXZSBjYW4gZ2V0IFwibnVsbFwiIGZyb20gdGhlIHJlbW90ZSBzaWRlIGlmIHdlIGdvdCBhIGNvbmZsaWN0XG4gICAgICAgIC8vIGFuZCB0aGVyZSBpcyBubyByZW1vdGUgdmVyc2lvbiBhdmFpbGFibGU7IHNlZSBraW50by1odHRwLmpzXG4gICAgICAgIC8vIGJhdGNoLmpzOmFnZ3JlZ2F0ZS5cbiAgICAgICAgdHJhbnNhY3Rpb24uZGVsZXRlKGNvbmZsaWN0LmxvY2FsLmlkKTtcbiAgICAgICAgYWNjZXB0ZWQgPSBudWxsO1xuICAgICAgICAvLyBUaGUgcmVjb3JkIHdhcyBkZWxldGVkLCBidXQgdGhhdCBzdGF0dXMgaXMgXCJzeW5jZWRcIiB3aXRoXG4gICAgICAgIC8vIHRoZSBzZXJ2ZXIsIHNvIHdlIGRvbid0IG5lZWQgdG8gcHVzaCB0aGUgY2hhbmdlLlxuICAgICAgICBzdGF0dXMgPSBcInN5bmNlZFwiO1xuICAgICAgICBpZCA9IGNvbmZsaWN0LmxvY2FsLmlkO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc3QgdXBkYXRlZCA9IHRoaXMuX3Jlc29sdmVSYXcoY29uZmxpY3QsIHJlc29sdXRpb24pO1xuICAgICAgICB0cmFuc2FjdGlvbi51cGRhdGUodXBkYXRlZCk7XG4gICAgICAgIGFjY2VwdGVkID0gdXBkYXRlZDtcbiAgICAgICAgc3RhdHVzID0gdXBkYXRlZC5fc3RhdHVzO1xuICAgICAgICBpZCA9IHVwZGF0ZWQuaWQ7XG4gICAgICB9XG4gICAgICByZXR1cm4geyByZWplY3RlZCwgYWNjZXB0ZWQsIGlkLCBfc3RhdHVzOiBzdGF0dXMgfTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBFeGVjdXRlIGEgYnVuY2ggb2Ygb3BlcmF0aW9ucyBpbiBhIHRyYW5zYWN0aW9uLlxuICAgKlxuICAgKiBUaGlzIHRyYW5zYWN0aW9uIHNob3VsZCBiZSBhdG9taWMgLS0gZWl0aGVyIGFsbCBvZiBpdHMgb3BlcmF0aW9uc1xuICAgKiB3aWxsIHN1Y2NlZWQsIG9yIG5vbmUgd2lsbC5cbiAgICpcbiAgICogVGhlIGFyZ3VtZW50IHRvIHRoaXMgZnVuY3Rpb24gaXMgaXRzZWxmIGEgZnVuY3Rpb24gd2hpY2ggd2lsbCBiZVxuICAgKiBjYWxsZWQgd2l0aCBhIHtAbGluayBDb2xsZWN0aW9uVHJhbnNhY3Rpb259LiBDb2xsZWN0aW9uIG1ldGhvZHNcbiAgICogYXJlIGF2YWlsYWJsZSBvbiB0aGlzIHRyYW5zYWN0aW9uLCBidXQgaW5zdGVhZCBvZiByZXR1cm5pbmdcbiAgICogcHJvbWlzZXMsIHRoZXkgYXJlIHN5bmNocm9ub3VzLiBleGVjdXRlKCkgcmV0dXJucyBhIFByb21pc2Ugd2hvc2VcbiAgICogdmFsdWUgd2lsbCBiZSB0aGUgcmV0dXJuIHZhbHVlIG9mIHRoZSBwcm92aWRlZCBmdW5jdGlvbi5cbiAgICpcbiAgICogTW9zdCBvcGVyYXRpb25zIHdpbGwgcmVxdWlyZSBhY2Nlc3MgdG8gdGhlIHJlY29yZCBpdHNlbGYsIHdoaWNoXG4gICAqIG11c3QgYmUgcHJlbG9hZGVkIGJ5IHBhc3NpbmcgaXRzIElEIGluIHRoZSBwcmVsb2FkSWRzIG9wdGlvbi5cbiAgICpcbiAgICogT3B0aW9uczpcbiAgICogLSB7QXJyYXl9IHByZWxvYWRJZHM6IGxpc3Qgb2YgSURzIHRvIGZldGNoIGF0IHRoZSBiZWdpbm5pbmcgb2ZcbiAgICogICB0aGUgdHJhbnNhY3Rpb25cbiAgICpcbiAgICogQHJldHVybiB7UHJvbWlzZX0gUmVzb2x2ZXMgd2l0aCB0aGUgcmVzdWx0IG9mIHRoZSBnaXZlbiBmdW5jdGlvblxuICAgKiAgICB3aGVuIHRoZSB0cmFuc2FjdGlvbiBjb21taXRzLlxuICAgKi9cbiAgZXhlY3V0ZShkb09wZXJhdGlvbnMsIHsgcHJlbG9hZElkcyA9IFtdIH0gPSB7fSkge1xuICAgIGZvciAoY29uc3QgaWQgb2YgcHJlbG9hZElkcykge1xuICAgICAgaWYgKCF0aGlzLmlkU2NoZW1hLnZhbGlkYXRlKGlkKSkge1xuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QoRXJyb3IoYEludmFsaWQgSWQ6ICR7aWR9YCkpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB0aGlzLmRiLmV4ZWN1dGUoXG4gICAgICB0cmFuc2FjdGlvbiA9PiB7XG4gICAgICAgIGNvbnN0IHR4biA9IG5ldyBDb2xsZWN0aW9uVHJhbnNhY3Rpb24odGhpcywgdHJhbnNhY3Rpb24pO1xuICAgICAgICBjb25zdCByZXN1bHQgPSBkb09wZXJhdGlvbnModHhuKTtcbiAgICAgICAgdHhuLmVtaXRFdmVudHMoKTtcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgIH0sXG4gICAgICB7IHByZWxvYWQ6IHByZWxvYWRJZHMgfVxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogUmVzZXRzIHRoZSBsb2NhbCByZWNvcmRzIGFzIGlmIHRoZXkgd2VyZSBuZXZlciBzeW5jZWQ7IGV4aXN0aW5nIHJlY29yZHMgYXJlXG4gICAqIG1hcmtlZCBhcyBuZXdseSBjcmVhdGVkLCBkZWxldGVkIHJlY29yZHMgYXJlIGRyb3BwZWQuXG4gICAqXG4gICAqIEEgbmV4dCBjYWxsIHRvIHtAbGluayBDb2xsZWN0aW9uLnN5bmN9IHdpbGwgdGh1cyByZXB1Ymxpc2ggdGhlIHdob2xlXG4gICAqIGNvbnRlbnQgb2YgdGhlIGxvY2FsIGNvbGxlY3Rpb24gdG8gdGhlIHNlcnZlci5cbiAgICpcbiAgICogQHJldHVybiB7UHJvbWlzZX0gUmVzb2x2ZXMgd2l0aCB0aGUgbnVtYmVyIG9mIHByb2Nlc3NlZCByZWNvcmRzLlxuICAgKi9cbiAgYXN5bmMgcmVzZXRTeW5jU3RhdHVzKCkge1xuICAgIGNvbnN0IHVuc3luY2VkID0gYXdhaXQgdGhpcy5saXN0KFxuICAgICAgeyBmaWx0ZXJzOiB7IF9zdGF0dXM6IFtcImRlbGV0ZWRcIiwgXCJzeW5jZWRcIl0gfSwgb3JkZXI6IFwiXCIgfSxcbiAgICAgIHsgaW5jbHVkZURlbGV0ZWQ6IHRydWUgfVxuICAgICk7XG4gICAgYXdhaXQgdGhpcy5kYi5leGVjdXRlKHRyYW5zYWN0aW9uID0+IHtcbiAgICAgIHVuc3luY2VkLmRhdGEuZm9yRWFjaChyZWNvcmQgPT4ge1xuICAgICAgICBpZiAocmVjb3JkLl9zdGF0dXMgPT09IFwiZGVsZXRlZFwiKSB7XG4gICAgICAgICAgLy8gR2FyYmFnZSBjb2xsZWN0IGRlbGV0ZWQgcmVjb3Jkcy5cbiAgICAgICAgICB0cmFuc2FjdGlvbi5kZWxldGUocmVjb3JkLmlkKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvLyBSZWNvcmRzIHRoYXQgd2VyZSBzeW5jZWQgYmVjb21lIMKrY3JlYXRlZMK7LlxuICAgICAgICAgIHRyYW5zYWN0aW9uLnVwZGF0ZSh7XG4gICAgICAgICAgICAuLi5yZWNvcmQsXG4gICAgICAgICAgICBsYXN0X21vZGlmaWVkOiB1bmRlZmluZWQsXG4gICAgICAgICAgICBfc3RhdHVzOiBcImNyZWF0ZWRcIixcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfSk7XG4gICAgdGhpcy5fbGFzdE1vZGlmaWVkID0gbnVsbDtcbiAgICBhd2FpdCB0aGlzLmRiLnNhdmVMYXN0TW9kaWZpZWQobnVsbCk7XG4gICAgcmV0dXJuIHVuc3luY2VkLmRhdGEubGVuZ3RoO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgYW4gb2JqZWN0IGNvbnRhaW5pbmcgdHdvIGxpc3RzOlxuICAgKlxuICAgKiAtIGB0b0RlbGV0ZWA6IHVuc3luY2VkIGRlbGV0ZWQgcmVjb3JkcyB3ZSBjYW4gc2FmZWx5IGRlbGV0ZTtcbiAgICogLSBgdG9TeW5jYDogbG9jYWwgdXBkYXRlcyB0byBzZW5kIHRvIHRoZSBzZXJ2ZXIuXG4gICAqXG4gICAqIEByZXR1cm4ge1Byb21pc2V9XG4gICAqL1xuICBhc3luYyBnYXRoZXJMb2NhbENoYW5nZXMoKSB7XG4gICAgY29uc3QgdW5zeW5jZWQgPSBhd2FpdCB0aGlzLmxpc3Qoe1xuICAgICAgZmlsdGVyczogeyBfc3RhdHVzOiBbXCJjcmVhdGVkXCIsIFwidXBkYXRlZFwiXSB9LFxuICAgICAgb3JkZXI6IFwiXCIsXG4gICAgfSk7XG4gICAgY29uc3QgZGVsZXRlZCA9IGF3YWl0IHRoaXMubGlzdChcbiAgICAgIHsgZmlsdGVyczogeyBfc3RhdHVzOiBcImRlbGV0ZWRcIiB9LCBvcmRlcjogXCJcIiB9LFxuICAgICAgeyBpbmNsdWRlRGVsZXRlZDogdHJ1ZSB9XG4gICAgKTtcblxuICAgIHJldHVybiBhd2FpdCBQcm9taXNlLmFsbChcbiAgICAgIHVuc3luY2VkLmRhdGFcbiAgICAgICAgLmNvbmNhdChkZWxldGVkLmRhdGEpXG4gICAgICAgIC5tYXAodGhpcy5fZW5jb2RlUmVjb3JkLmJpbmQodGhpcywgXCJyZW1vdGVcIikpXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGZXRjaCByZW1vdGUgY2hhbmdlcywgaW1wb3J0IHRoZW0gdG8gdGhlIGxvY2FsIGRhdGFiYXNlLCBhbmQgaGFuZGxlXG4gICAqIGNvbmZsaWN0cyBhY2NvcmRpbmcgdG8gYG9wdGlvbnMuc3RyYXRlZ3lgLiBUaGVuLCB1cGRhdGVzIHRoZSBwYXNzZWRcbiAgICoge0BsaW5rIFN5bmNSZXN1bHRPYmplY3R9IHdpdGggaW1wb3J0IHJlc3VsdHMuXG4gICAqXG4gICAqIE9wdGlvbnM6XG4gICAqIC0ge1N0cmluZ30gc3RyYXRlZ3k6IFRoZSBzZWxlY3RlZCBzeW5jIHN0cmF0ZWd5LlxuICAgKiAtIHtTdHJpbmd9IGV4cGVjdGVkVGltZXN0YW1wOiBBIHRpbWVzdGFtcCB0byB1c2UgYXMgYSBcImNhY2hlIGJ1c3RpbmdcIiBxdWVyeSBwYXJhbWV0ZXIuXG4gICAqIC0ge0FycmF5PFN0cmluZz59IGV4Y2x1ZGU6IEEgbGlzdCBvZiByZWNvcmQgaWRzIHRvIGV4Y2x1ZGUgZnJvbSBwdWxsLlxuICAgKiAtIHtPYmplY3R9IGhlYWRlcnM6IFRoZSBIVFRQIGhlYWRlcnMgdG8gdXNlIGluIHRoZSByZXF1ZXN0LlxuICAgKiAtIHtpbnR9IHJldHJ5OiBUaGUgbnVtYmVyIG9mIHJldHJpZXMgdG8gZG8gaWYgdGhlIEhUVFAgcmVxdWVzdCBmYWlscy5cbiAgICogLSB7aW50fSBsYXN0TW9kaWZpZWQ6IFRoZSB0aW1lc3RhbXAgdG8gdXNlIGluIGA/X3NpbmNlYCBxdWVyeS5cbiAgICpcbiAgICogQHBhcmFtICB7S2ludG9DbGllbnQuQ29sbGVjdGlvbn0gY2xpZW50ICAgICAgICAgICBLaW50byBjbGllbnQgQ29sbGVjdGlvbiBpbnN0YW5jZS5cbiAgICogQHBhcmFtICB7U3luY1Jlc3VsdE9iamVjdH0gICAgICAgc3luY1Jlc3VsdE9iamVjdCBUaGUgc3luYyByZXN1bHQgb2JqZWN0LlxuICAgKiBAcGFyYW0gIHtPYmplY3R9ICAgICAgICAgICAgICAgICBvcHRpb25zICAgICAgICAgIFRoZSBvcHRpb25zIG9iamVjdC5cbiAgICogQHJldHVybiB7UHJvbWlzZX1cbiAgICovXG4gIGFzeW5jIHB1bGxDaGFuZ2VzKGNsaWVudCwgc3luY1Jlc3VsdE9iamVjdCwgb3B0aW9ucyA9IHt9KSB7XG4gICAgaWYgKCFzeW5jUmVzdWx0T2JqZWN0Lm9rKSB7XG4gICAgICByZXR1cm4gc3luY1Jlc3VsdE9iamVjdDtcbiAgICB9XG5cbiAgICBjb25zdCBzaW5jZSA9IHRoaXMubGFzdE1vZGlmaWVkXG4gICAgICA/IHRoaXMubGFzdE1vZGlmaWVkXG4gICAgICA6IGF3YWl0IHRoaXMuZGIuZ2V0TGFzdE1vZGlmaWVkKCk7XG5cbiAgICBvcHRpb25zID0ge1xuICAgICAgc3RyYXRlZ3k6IENvbGxlY3Rpb24uc3RyYXRlZ3kuTUFOVUFMLFxuICAgICAgbGFzdE1vZGlmaWVkOiBzaW5jZSxcbiAgICAgIGhlYWRlcnM6IHt9LFxuICAgICAgLi4ub3B0aW9ucyxcbiAgICB9O1xuXG4gICAgLy8gT3B0aW9uYWxseSBpZ25vcmUgc29tZSByZWNvcmRzIHdoZW4gcHVsbGluZyBmb3IgY2hhbmdlcy5cbiAgICAvLyAoYXZvaWQgcmVkb3dubG9hZGluZyBvdXIgb3duIGNoYW5nZXMgb24gbGFzdCBzdGVwIG9mICNzeW5jKCkpXG4gICAgbGV0IGZpbHRlcnM7XG4gICAgaWYgKG9wdGlvbnMuZXhjbHVkZSkge1xuICAgICAgLy8gTGltaXQgdGhlIGxpc3Qgb2YgZXhjbHVkZWQgcmVjb3JkcyB0byB0aGUgZmlyc3QgNTAgcmVjb3JkcyBpbiBvcmRlclxuICAgICAgLy8gdG8gcmVtYWluIHVuZGVyIGRlLWZhY3RvIFVSTCBzaXplIGxpbWl0ICh+MjAwMCBjaGFycykuXG4gICAgICAvLyBodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zLzQxNzE0Mi93aGF0LWlzLXRoZS1tYXhpbXVtLWxlbmd0aC1vZi1hLXVybC1pbi1kaWZmZXJlbnQtYnJvd3NlcnMvNDE3MTg0IzQxNzE4NFxuICAgICAgY29uc3QgZXhjbHVkZV9pZCA9IG9wdGlvbnMuZXhjbHVkZVxuICAgICAgICAuc2xpY2UoMCwgNTApXG4gICAgICAgIC5tYXAociA9PiByLmlkKVxuICAgICAgICAuam9pbihcIixcIik7XG4gICAgICBmaWx0ZXJzID0geyBleGNsdWRlX2lkIH07XG4gICAgfVxuICAgIGlmIChvcHRpb25zLmV4cGVjdGVkVGltZXN0YW1wKSB7XG4gICAgICBmaWx0ZXJzID0ge1xuICAgICAgICAuLi5maWx0ZXJzLFxuICAgICAgICBfZXhwZWN0ZWQ6IG9wdGlvbnMuZXhwZWN0ZWRUaW1lc3RhbXAsXG4gICAgICB9O1xuICAgIH1cbiAgICAvLyBGaXJzdCBmZXRjaCByZW1vdGUgY2hhbmdlcyBmcm9tIHRoZSBzZXJ2ZXJcbiAgICBjb25zdCB7IGRhdGEsIGxhc3RfbW9kaWZpZWQgfSA9IGF3YWl0IGNsaWVudC5saXN0UmVjb3Jkcyh7XG4gICAgICAvLyBTaW5jZSBzaG91bGQgYmUgRVRhZyAoc2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9LaW50by9raW50by5qcy9pc3N1ZXMvMzU2KVxuICAgICAgc2luY2U6IG9wdGlvbnMubGFzdE1vZGlmaWVkID8gYCR7b3B0aW9ucy5sYXN0TW9kaWZpZWR9YCA6IHVuZGVmaW5lZCxcbiAgICAgIGhlYWRlcnM6IG9wdGlvbnMuaGVhZGVycyxcbiAgICAgIHJldHJ5OiBvcHRpb25zLnJldHJ5LFxuICAgICAgLy8gRmV0Y2ggZXZlcnkgcGFnZSBieSBkZWZhdWx0IChGSVhNRTogb3B0aW9uIHRvIGxpbWl0IHBhZ2VzLCBzZWUgIzI3NylcbiAgICAgIHBhZ2VzOiBJbmZpbml0eSxcbiAgICAgIGZpbHRlcnMsXG4gICAgfSk7XG4gICAgLy8gbGFzdF9tb2RpZmllZCBpcyB0aGUgRVRhZyBoZWFkZXIgdmFsdWUgKHN0cmluZykuXG4gICAgLy8gRm9yIHJldHJvLWNvbXBhdGliaWxpdHkgd2l0aCBmaXJzdCBraW50by5qcyB2ZXJzaW9uc1xuICAgIC8vIHBhcnNlIGl0IHRvIGludGVnZXIuXG4gICAgY29uc3QgdW5xdW90ZWQgPSBsYXN0X21vZGlmaWVkID8gcGFyc2VJbnQobGFzdF9tb2RpZmllZCwgMTApIDogdW5kZWZpbmVkO1xuXG4gICAgLy8gQ2hlY2sgaWYgc2VydmVyIHdhcyBmbHVzaGVkLlxuICAgIC8vIFRoaXMgaXMgcmVsZXZhbnQgZm9yIHRoZSBLaW50byBkZW1vIHNlcnZlclxuICAgIC8vIChhbmQgdGh1cyBmb3IgbWFueSBuZXcgY29tZXJzKS5cbiAgICBjb25zdCBsb2NhbFN5bmNlZCA9IG9wdGlvbnMubGFzdE1vZGlmaWVkO1xuICAgIGNvbnN0IHNlcnZlckNoYW5nZWQgPSB1bnF1b3RlZCA+IG9wdGlvbnMubGFzdE1vZGlmaWVkO1xuICAgIGNvbnN0IGVtcHR5Q29sbGVjdGlvbiA9IGRhdGEubGVuZ3RoID09PSAwO1xuICAgIGlmICghb3B0aW9ucy5leGNsdWRlICYmIGxvY2FsU3luY2VkICYmIHNlcnZlckNoYW5nZWQgJiYgZW1wdHlDb2xsZWN0aW9uKSB7XG4gICAgICBjb25zdCBlID0gbmV3IFNlcnZlcldhc0ZsdXNoZWRFcnJvcihcbiAgICAgICAgbG9jYWxTeW5jZWQsXG4gICAgICAgIHVucXVvdGVkLFxuICAgICAgICBcIlNlcnZlciBoYXMgYmVlbiBmbHVzaGVkLiBDbGllbnQgU2lkZSBUaW1lc3RhbXA6IFwiICtcbiAgICAgICAgICBsb2NhbFN5bmNlZCArXG4gICAgICAgICAgXCIgU2VydmVyIFNpZGUgVGltZXN0YW1wOiBcIiArXG4gICAgICAgICAgdW5xdW90ZWRcbiAgICAgICk7XG4gICAgICB0aHJvdyBlO1xuICAgIH1cblxuICAgIC8vIEF0b21pYyB1cGRhdGVzIGFyZSBub3Qgc2Vuc2libGUgaGVyZSBiZWNhdXNlIHVucXVvdGVkIGlzIG5vdFxuICAgIC8vIGNvbXB1dGVkIGFzIGEgZnVuY3Rpb24gb2Ygc3luY1Jlc3VsdE9iamVjdC5sYXN0TW9kaWZpZWQuXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIHJlcXVpcmUtYXRvbWljLXVwZGF0ZXNcbiAgICBzeW5jUmVzdWx0T2JqZWN0Lmxhc3RNb2RpZmllZCA9IHVucXVvdGVkO1xuXG4gICAgLy8gRGVjb2RlIGluY29taW5nIGNoYW5nZXMuXG4gICAgY29uc3QgZGVjb2RlZENoYW5nZXMgPSBhd2FpdCBQcm9taXNlLmFsbChcbiAgICAgIGRhdGEubWFwKGNoYW5nZSA9PiB7XG4gICAgICAgIHJldHVybiB0aGlzLl9kZWNvZGVSZWNvcmQoXCJyZW1vdGVcIiwgY2hhbmdlKTtcbiAgICAgIH0pXG4gICAgKTtcbiAgICAvLyBIb29rIHJlY2VpdmVzIGRlY29kZWQgcmVjb3Jkcy5cbiAgICBjb25zdCBwYXlsb2FkID0geyBsYXN0TW9kaWZpZWQ6IHVucXVvdGVkLCBjaGFuZ2VzOiBkZWNvZGVkQ2hhbmdlcyB9O1xuICAgIGNvbnN0IGFmdGVySG9va3MgPSBhd2FpdCB0aGlzLmFwcGx5SG9vayhcImluY29taW5nLWNoYW5nZXNcIiwgcGF5bG9hZCk7XG5cbiAgICAvLyBObyBjaGFuZ2UsIG5vdGhpbmcgdG8gaW1wb3J0LlxuICAgIGlmIChhZnRlckhvb2tzLmNoYW5nZXMubGVuZ3RoID4gMCkge1xuICAgICAgLy8gUmVmbGVjdCB0aGVzZSBjaGFuZ2VzIGxvY2FsbHlcbiAgICAgIGF3YWl0IHRoaXMuaW1wb3J0Q2hhbmdlcyhcbiAgICAgICAgc3luY1Jlc3VsdE9iamVjdCxcbiAgICAgICAgYWZ0ZXJIb29rcy5jaGFuZ2VzLFxuICAgICAgICBvcHRpb25zLnN0cmF0ZWd5XG4gICAgICApO1xuICAgIH1cbiAgICByZXR1cm4gc3luY1Jlc3VsdE9iamVjdDtcbiAgfVxuXG4gIGFwcGx5SG9vayhob29rTmFtZSwgcGF5bG9hZCkge1xuICAgIGlmICh0eXBlb2YgdGhpcy5ob29rc1tob29rTmFtZV0gPT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShwYXlsb2FkKTtcbiAgICB9XG4gICAgcmV0dXJuIHdhdGVyZmFsbChcbiAgICAgIHRoaXMuaG9va3NbaG9va05hbWVdLm1hcChob29rID0+IHtcbiAgICAgICAgcmV0dXJuIHJlY29yZCA9PiB7XG4gICAgICAgICAgY29uc3QgcmVzdWx0ID0gaG9vayhwYXlsb2FkLCB0aGlzKTtcbiAgICAgICAgICBjb25zdCByZXN1bHRUaGVuYWJsZSA9IHJlc3VsdCAmJiB0eXBlb2YgcmVzdWx0LnRoZW4gPT09IFwiZnVuY3Rpb25cIjtcbiAgICAgICAgICBjb25zdCByZXN1bHRDaGFuZ2VzID1cbiAgICAgICAgICAgIHJlc3VsdCAmJiBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwocmVzdWx0LCBcImNoYW5nZXNcIik7XG4gICAgICAgICAgaWYgKCEocmVzdWx0VGhlbmFibGUgfHwgcmVzdWx0Q2hhbmdlcykpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICAgICAgYEludmFsaWQgcmV0dXJuIHZhbHVlIGZvciBob29rOiAke0pTT04uc3RyaW5naWZ5KFxuICAgICAgICAgICAgICAgIHJlc3VsdFxuICAgICAgICAgICAgICApfSBoYXMgbm8gJ3RoZW4oKScgb3IgJ2NoYW5nZXMnIHByb3BlcnRpZXNgXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICB9O1xuICAgICAgfSksXG4gICAgICBwYXlsb2FkXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBQdWJsaXNoIGxvY2FsIGNoYW5nZXMgdG8gdGhlIHJlbW90ZSBzZXJ2ZXIgYW5kIHVwZGF0ZXMgdGhlIHBhc3NlZFxuICAgKiB7QGxpbmsgU3luY1Jlc3VsdE9iamVjdH0gd2l0aCBwdWJsaWNhdGlvbiByZXN1bHRzLlxuICAgKlxuICAgKiBPcHRpb25zOlxuICAgKiAtIHtTdHJpbmd9IHN0cmF0ZWd5OiBUaGUgc2VsZWN0ZWQgc3luYyBzdHJhdGVneS5cbiAgICogLSB7T2JqZWN0fSBoZWFkZXJzOiBUaGUgSFRUUCBoZWFkZXJzIHRvIHVzZSBpbiB0aGUgcmVxdWVzdC5cbiAgICogLSB7aW50fSByZXRyeTogVGhlIG51bWJlciBvZiByZXRyaWVzIHRvIGRvIGlmIHRoZSBIVFRQIHJlcXVlc3QgZmFpbHMuXG4gICAqXG4gICAqIEBwYXJhbSAge0tpbnRvQ2xpZW50LkNvbGxlY3Rpb259IGNsaWVudCAgICAgICAgICAgS2ludG8gY2xpZW50IENvbGxlY3Rpb24gaW5zdGFuY2UuXG4gICAqIEBwYXJhbSAge1N5bmNSZXN1bHRPYmplY3R9ICAgICAgIHN5bmNSZXN1bHRPYmplY3QgVGhlIHN5bmMgcmVzdWx0IG9iamVjdC5cbiAgICogQHBhcmFtICB7T2JqZWN0fSAgICAgICAgICAgICAgICAgY2hhbmdlcyAgICAgICAgICBUaGUgY2hhbmdlIG9iamVjdC5cbiAgICogQHBhcmFtICB7QXJyYXl9ICAgICAgICAgICAgICAgICAgY2hhbmdlcy50b0RlbGV0ZSBUaGUgbGlzdCBvZiByZWNvcmRzIHRvIGRlbGV0ZS5cbiAgICogQHBhcmFtICB7QXJyYXl9ICAgICAgICAgICAgICAgICAgY2hhbmdlcy50b1N5bmMgICBUaGUgbGlzdCBvZiByZWNvcmRzIHRvIGNyZWF0ZS91cGRhdGUuXG4gICAqIEBwYXJhbSAge09iamVjdH0gICAgICAgICAgICAgICAgIG9wdGlvbnMgICAgICAgICAgVGhlIG9wdGlvbnMgb2JqZWN0LlxuICAgKiBAcmV0dXJuIHtQcm9taXNlfVxuICAgKi9cbiAgYXN5bmMgcHVzaENoYW5nZXMoY2xpZW50LCBjaGFuZ2VzLCBzeW5jUmVzdWx0T2JqZWN0LCBvcHRpb25zID0ge30pIHtcbiAgICBpZiAoIXN5bmNSZXN1bHRPYmplY3Qub2spIHtcbiAgICAgIHJldHVybiBzeW5jUmVzdWx0T2JqZWN0O1xuICAgIH1cbiAgICBjb25zdCBzYWZlID1cbiAgICAgICFvcHRpb25zLnN0cmF0ZWd5IHx8IG9wdGlvbnMuc3RyYXRlZ3kgIT09IENvbGxlY3Rpb24uQ0xJRU5UX1dJTlM7XG4gICAgY29uc3QgdG9EZWxldGUgPSBjaGFuZ2VzLmZpbHRlcihyID0+IHIuX3N0YXR1cyA9PSBcImRlbGV0ZWRcIik7XG4gICAgY29uc3QgdG9TeW5jID0gY2hhbmdlcy5maWx0ZXIociA9PiByLl9zdGF0dXMgIT0gXCJkZWxldGVkXCIpO1xuXG4gICAgLy8gUGVyZm9ybSBhIGJhdGNoIHJlcXVlc3Qgd2l0aCBldmVyeSBjaGFuZ2VzLlxuICAgIGNvbnN0IHN5bmNlZCA9IGF3YWl0IGNsaWVudC5iYXRjaChcbiAgICAgIGJhdGNoID0+IHtcbiAgICAgICAgdG9EZWxldGUuZm9yRWFjaChyID0+IHtcbiAgICAgICAgICAvLyBuZXZlciBwdWJsaXNoZWQgbG9jYWxseSBkZWxldGVkIHJlY29yZHMgc2hvdWxkIG5vdCBiZSBwdXNibGlzaGVkXG4gICAgICAgICAgaWYgKHIubGFzdF9tb2RpZmllZCkge1xuICAgICAgICAgICAgYmF0Y2guZGVsZXRlUmVjb3JkKHIpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHRvU3luYy5mb3JFYWNoKHIgPT4ge1xuICAgICAgICAgIC8vIENsZWFuIGxvY2FsIGZpZWxkcyAobGlrZSBfc3RhdHVzKSBiZWZvcmUgc2VuZGluZyB0byBzZXJ2ZXIuXG4gICAgICAgICAgY29uc3QgcHVibGlzaGVkID0gdGhpcy5jbGVhbkxvY2FsRmllbGRzKHIpO1xuICAgICAgICAgIGlmIChyLl9zdGF0dXMgPT09IFwiY3JlYXRlZFwiKSB7XG4gICAgICAgICAgICBiYXRjaC5jcmVhdGVSZWNvcmQocHVibGlzaGVkKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgYmF0Y2gudXBkYXRlUmVjb3JkKHB1Ymxpc2hlZCk7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIGhlYWRlcnM6IG9wdGlvbnMuaGVhZGVycyxcbiAgICAgICAgcmV0cnk6IG9wdGlvbnMucmV0cnksXG4gICAgICAgIHNhZmUsXG4gICAgICAgIGFnZ3JlZ2F0ZTogdHJ1ZSxcbiAgICAgIH1cbiAgICApO1xuXG4gICAgLy8gU3RvcmUgb3V0Z29pbmcgZXJyb3JzIGludG8gc3luYyByZXN1bHQgb2JqZWN0XG4gICAgc3luY1Jlc3VsdE9iamVjdC5hZGQoXG4gICAgICBcImVycm9yc1wiLFxuICAgICAgc3luY2VkLmVycm9ycy5tYXAoZSA9PiAoeyAuLi5lLCB0eXBlOiBcIm91dGdvaW5nXCIgfSkpXG4gICAgKTtcblxuICAgIC8vIFN0b3JlIG91dGdvaW5nIGNvbmZsaWN0cyBpbnRvIHN5bmMgcmVzdWx0IG9iamVjdFxuICAgIGNvbnN0IGNvbmZsaWN0cyA9IFtdO1xuICAgIGZvciAoY29uc3QgeyB0eXBlLCBsb2NhbCwgcmVtb3RlIH0gb2Ygc3luY2VkLmNvbmZsaWN0cykge1xuICAgICAgLy8gTm90ZTogd2UgZW5zdXJlIHRoYXQgbG9jYWwgZGF0YSBhcmUgYWN0dWFsbHkgYXZhaWxhYmxlLCBhcyB0aGV5IG1heVxuICAgICAgLy8gYmUgbWlzc2luZyBpbiB0aGUgY2FzZSBvZiBhIHB1Ymxpc2hlZCBkZWxldGlvbi5cbiAgICAgIGNvbnN0IHNhZmVMb2NhbCA9IChsb2NhbCAmJiBsb2NhbC5kYXRhKSB8fCB7IGlkOiByZW1vdGUuaWQgfTtcbiAgICAgIGNvbnN0IHJlYWxMb2NhbCA9IGF3YWl0IHRoaXMuX2RlY29kZVJlY29yZChcInJlbW90ZVwiLCBzYWZlTG9jYWwpO1xuICAgICAgLy8gV2UgY2FuIGdldCBcIm51bGxcIiBmcm9tIHRoZSByZW1vdGUgc2lkZSBpZiB3ZSBnb3QgYSBjb25mbGljdFxuICAgICAgLy8gYW5kIHRoZXJlIGlzIG5vIHJlbW90ZSB2ZXJzaW9uIGF2YWlsYWJsZTsgc2VlIGtpbnRvLWh0dHAuanNcbiAgICAgIC8vIGJhdGNoLmpzOmFnZ3JlZ2F0ZS5cbiAgICAgIGNvbnN0IHJlYWxSZW1vdGUgPSByZW1vdGUgJiYgKGF3YWl0IHRoaXMuX2RlY29kZVJlY29yZChcInJlbW90ZVwiLCByZW1vdGUpKTtcbiAgICAgIGNvbnN0IGNvbmZsaWN0ID0geyB0eXBlLCBsb2NhbDogcmVhbExvY2FsLCByZW1vdGU6IHJlYWxSZW1vdGUgfTtcbiAgICAgIGNvbmZsaWN0cy5wdXNoKGNvbmZsaWN0KTtcbiAgICB9XG4gICAgc3luY1Jlc3VsdE9iamVjdC5hZGQoXCJjb25mbGljdHNcIiwgY29uZmxpY3RzKTtcblxuICAgIC8vIFJlY29yZHMgdGhhdCBtdXN0IGJlIGRlbGV0ZWQgYXJlIGVpdGhlciBkZWxldGlvbnMgdGhhdCB3ZXJlIHB1c2hlZFxuICAgIC8vIHRvIHNlcnZlciAocHVibGlzaGVkKSBvciBkZWxldGVkIHJlY29yZHMgdGhhdCB3ZXJlIG5ldmVyIHB1c2hlZCAoc2tpcHBlZCkuXG4gICAgY29uc3QgbWlzc2luZ1JlbW90ZWx5ID0gc3luY2VkLnNraXBwZWQubWFwKHIgPT4gKHsgLi4uciwgZGVsZXRlZDogdHJ1ZSB9KSk7XG5cbiAgICAvLyBGb3IgY3JlYXRlZCBhbmQgdXBkYXRlZCByZWNvcmRzLCB0aGUgbGFzdF9tb2RpZmllZCBjb21pbmcgZnJvbSBzZXJ2ZXJcbiAgICAvLyB3aWxsIGJlIHN0b3JlZCBsb2NhbGx5LlxuICAgIC8vIFJlZmxlY3QgcHVibGljYXRpb24gcmVzdWx0cyBsb2NhbGx5IHVzaW5nIHRoZSByZXNwb25zZSBmcm9tXG4gICAgLy8gdGhlIGJhdGNoIHJlcXVlc3QuXG4gICAgY29uc3QgcHVibGlzaGVkID0gc3luY2VkLnB1Ymxpc2hlZC5tYXAoYyA9PiBjLmRhdGEpO1xuICAgIGNvbnN0IHRvQXBwbHlMb2NhbGx5ID0gcHVibGlzaGVkLmNvbmNhdChtaXNzaW5nUmVtb3RlbHkpO1xuXG4gICAgLy8gQXBwbHkgdGhlIGRlY29kZSB0cmFuc2Zvcm1lcnMsIGlmIGFueVxuICAgIGNvbnN0IGRlY29kZWQgPSBhd2FpdCBQcm9taXNlLmFsbChcbiAgICAgIHRvQXBwbHlMb2NhbGx5Lm1hcChyZWNvcmQgPT4ge1xuICAgICAgICByZXR1cm4gdGhpcy5fZGVjb2RlUmVjb3JkKFwicmVtb3RlXCIsIHJlY29yZCk7XG4gICAgICB9KVxuICAgICk7XG5cbiAgICAvLyBXZSBoYXZlIHRvIHVwZGF0ZSB0aGUgbG9jYWwgcmVjb3JkcyB3aXRoIHRoZSByZXNwb25zZXMgb2YgdGhlIHNlcnZlclxuICAgIC8vIChlZy4gbGFzdF9tb2RpZmllZCB2YWx1ZXMgZXRjLikuXG4gICAgaWYgKGRlY29kZWQubGVuZ3RoID4gMCB8fCBjb25mbGljdHMubGVuZ3RoID4gMCkge1xuICAgICAgYXdhaXQgdGhpcy5fYXBwbHlQdXNoZWRSZXN1bHRzKFxuICAgICAgICBzeW5jUmVzdWx0T2JqZWN0LFxuICAgICAgICBkZWNvZGVkLFxuICAgICAgICBjb25mbGljdHMsXG4gICAgICAgIG9wdGlvbnMuc3RyYXRlZ3lcbiAgICAgICk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHN5bmNSZXN1bHRPYmplY3Q7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJuIGEgY29weSBvZiB0aGUgc3BlY2lmaWVkIHJlY29yZCB3aXRob3V0IHRoZSBsb2NhbCBmaWVsZHMuXG4gICAqXG4gICAqIEBwYXJhbSAge09iamVjdH0gcmVjb3JkICBBIHJlY29yZCB3aXRoIHBvdGVudGlhbCBsb2NhbCBmaWVsZHMuXG4gICAqIEByZXR1cm4ge09iamVjdH1cbiAgICovXG4gIGNsZWFuTG9jYWxGaWVsZHMocmVjb3JkKSB7XG4gICAgY29uc3QgbG9jYWxLZXlzID0gUkVDT1JEX0ZJRUxEU19UT19DTEVBTi5jb25jYXQodGhpcy5sb2NhbEZpZWxkcyk7XG4gICAgcmV0dXJuIG9taXRLZXlzKHJlY29yZCwgbG9jYWxLZXlzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXNvbHZlcyBhIGNvbmZsaWN0LCB1cGRhdGluZyBsb2NhbCByZWNvcmQgYWNjb3JkaW5nIHRvIHByb3Bvc2VkXG4gICAqIHJlc29sdXRpb24g4oCUIGtlZXBpbmcgcmVtb3RlIHJlY29yZCBgbGFzdF9tb2RpZmllZGAgdmFsdWUgYXMgYSByZWZlcmVuY2UgZm9yXG4gICAqIGZ1cnRoZXIgYmF0Y2ggc2VuZGluZy5cbiAgICpcbiAgICogQHBhcmFtICB7T2JqZWN0fSBjb25mbGljdCAgIFRoZSBjb25mbGljdCBvYmplY3QuXG4gICAqIEBwYXJhbSAge09iamVjdH0gcmVzb2x1dGlvbiBUaGUgcHJvcG9zZWQgcmVjb3JkLlxuICAgKiBAcmV0dXJuIHtQcm9taXNlfVxuICAgKi9cbiAgcmVzb2x2ZShjb25mbGljdCwgcmVzb2x1dGlvbikge1xuICAgIHJldHVybiB0aGlzLmRiLmV4ZWN1dGUodHJhbnNhY3Rpb24gPT4ge1xuICAgICAgY29uc3QgdXBkYXRlZCA9IHRoaXMuX3Jlc29sdmVSYXcoY29uZmxpY3QsIHJlc29sdXRpb24pO1xuICAgICAgdHJhbnNhY3Rpb24udXBkYXRlKHVwZGF0ZWQpO1xuICAgICAgcmV0dXJuIHsgZGF0YTogdXBkYXRlZCwgcGVybWlzc2lvbnM6IHt9IH07XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogQHByaXZhdGVcbiAgICovXG4gIF9yZXNvbHZlUmF3KGNvbmZsaWN0LCByZXNvbHV0aW9uKSB7XG4gICAgY29uc3QgcmVzb2x2ZWQgPSB7XG4gICAgICAuLi5yZXNvbHV0aW9uLFxuICAgICAgLy8gRW5zdXJlIGxvY2FsIHJlY29yZCBoYXMgdGhlIGxhdGVzdCBhdXRob3JpdGF0aXZlIHRpbWVzdGFtcFxuICAgICAgbGFzdF9tb2RpZmllZDogY29uZmxpY3QucmVtb3RlICYmIGNvbmZsaWN0LnJlbW90ZS5sYXN0X21vZGlmaWVkLFxuICAgIH07XG4gICAgLy8gSWYgdGhlIHJlc29sdXRpb24gb2JqZWN0IGlzIHN0cmljdGx5IGVxdWFsIHRvIHRoZVxuICAgIC8vIHJlbW90ZSByZWNvcmQsIHRoZW4gd2UgY2FuIG1hcmsgaXQgYXMgc3luY2VkIGxvY2FsbHkuXG4gICAgLy8gT3RoZXJ3aXNlLCBtYXJrIGl0IGFzIHVwZGF0ZWQgKHNvIHRoYXQgdGhlIHJlc29sdXRpb24gaXMgcHVzaGVkKS5cbiAgICBjb25zdCBzeW5jZWQgPSBkZWVwRXF1YWwocmVzb2x2ZWQsIGNvbmZsaWN0LnJlbW90ZSk7XG4gICAgcmV0dXJuIG1hcmtTdGF0dXMocmVzb2x2ZWQsIHN5bmNlZCA/IFwic3luY2VkXCIgOiBcInVwZGF0ZWRcIik7XG4gIH1cblxuICAvKipcbiAgICogU3luY2hyb25pemUgcmVtb3RlIGFuZCBsb2NhbCBkYXRhLiBUaGUgcHJvbWlzZSB3aWxsIHJlc29sdmUgd2l0aCBhXG4gICAqIHtAbGluayBTeW5jUmVzdWx0T2JqZWN0fSwgdGhvdWdoIHdpbGwgcmVqZWN0OlxuICAgKlxuICAgKiAtIGlmIHRoZSBzZXJ2ZXIgaXMgY3VycmVudGx5IGJhY2tlZCBvZmY7XG4gICAqIC0gaWYgdGhlIHNlcnZlciBoYXMgYmVlbiBkZXRlY3RlZCBmbHVzaGVkLlxuICAgKlxuICAgKiBPcHRpb25zOlxuICAgKiAtIHtPYmplY3R9IGhlYWRlcnM6IEhUVFAgaGVhZGVycyB0byBhdHRhY2ggdG8gb3V0Z29pbmcgcmVxdWVzdHMuXG4gICAqIC0ge1N0cmluZ30gZXhwZWN0ZWRUaW1lc3RhbXA6IEEgdGltZXN0YW1wIHRvIHVzZSBhcyBhIFwiY2FjaGUgYnVzdGluZ1wiIHF1ZXJ5IHBhcmFtZXRlci5cbiAgICogLSB7TnVtYmVyfSByZXRyeTogTnVtYmVyIG9mIHJldHJpZXMgd2hlbiBzZXJ2ZXIgZmFpbHMgdG8gcHJvY2VzcyB0aGUgcmVxdWVzdCAoZGVmYXVsdDogMSkuXG4gICAqIC0ge0NvbGxlY3Rpb24uc3RyYXRlZ3l9IHN0cmF0ZWd5OiBTZWUge0BsaW5rIENvbGxlY3Rpb24uc3RyYXRlZ3l9LlxuICAgKiAtIHtCb29sZWFufSBpZ25vcmVCYWNrb2ZmOiBGb3JjZSBzeW5jaHJvbml6YXRpb24gZXZlbiBpZiBzZXJ2ZXIgaXMgY3VycmVudGx5XG4gICAqICAgYmFja2VkIG9mZi5cbiAgICogLSB7U3RyaW5nfSBidWNrZXQ6IFRoZSByZW1vdmUgYnVja2V0IGlkIHRvIHVzZSAoZGVmYXVsdDogbnVsbClcbiAgICogLSB7U3RyaW5nfSBjb2xsZWN0aW9uOiBUaGUgcmVtb3ZlIGNvbGxlY3Rpb24gaWQgdG8gdXNlIChkZWZhdWx0OiBudWxsKVxuICAgKiAtIHtTdHJpbmd9IHJlbW90ZSBUaGUgcmVtb3RlIEtpbnRvIHNlcnZlciBlbmRwb2ludCB0byB1c2UgKGRlZmF1bHQ6IG51bGwpLlxuICAgKlxuICAgKiBAcGFyYW0gIHtPYmplY3R9IG9wdGlvbnMgT3B0aW9ucy5cbiAgICogQHJldHVybiB7UHJvbWlzZX1cbiAgICogQHRocm93cyB7RXJyb3J9IElmIGFuIGludmFsaWQgcmVtb3RlIG9wdGlvbiBpcyBwYXNzZWQuXG4gICAqL1xuICBhc3luYyBzeW5jKFxuICAgIG9wdGlvbnMgPSB7XG4gICAgICBzdHJhdGVneTogQ29sbGVjdGlvbi5zdHJhdGVneS5NQU5VQUwsXG4gICAgICBoZWFkZXJzOiB7fSxcbiAgICAgIHJldHJ5OiAxLFxuICAgICAgaWdub3JlQmFja29mZjogZmFsc2UsXG4gICAgICBidWNrZXQ6IG51bGwsXG4gICAgICBjb2xsZWN0aW9uOiBudWxsLFxuICAgICAgcmVtb3RlOiBudWxsLFxuICAgICAgZXhwZWN0ZWRUaW1lc3RhbXA6IG51bGwsXG4gICAgfVxuICApIHtcbiAgICBvcHRpb25zID0ge1xuICAgICAgLi4ub3B0aW9ucyxcbiAgICAgIGJ1Y2tldDogb3B0aW9ucy5idWNrZXQgfHwgdGhpcy5idWNrZXQsXG4gICAgICBjb2xsZWN0aW9uOiBvcHRpb25zLmNvbGxlY3Rpb24gfHwgdGhpcy5uYW1lLFxuICAgIH07XG5cbiAgICBjb25zdCBwcmV2aW91c1JlbW90ZSA9IHRoaXMuYXBpLnJlbW90ZTtcbiAgICBpZiAob3B0aW9ucy5yZW1vdGUpIHtcbiAgICAgIC8vIE5vdGU6IHNldHRpbmcgdGhlIHJlbW90ZSBlbnN1cmVzIGl0J3MgdmFsaWQsIHRocm93cyB3aGVuIGludmFsaWQuXG4gICAgICB0aGlzLmFwaS5yZW1vdGUgPSBvcHRpb25zLnJlbW90ZTtcbiAgICB9XG4gICAgaWYgKCFvcHRpb25zLmlnbm9yZUJhY2tvZmYgJiYgdGhpcy5hcGkuYmFja29mZiA+IDApIHtcbiAgICAgIGNvbnN0IHNlY29uZHMgPSBNYXRoLmNlaWwodGhpcy5hcGkuYmFja29mZiAvIDEwMDApO1xuICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KFxuICAgICAgICBuZXcgRXJyb3IoXG4gICAgICAgICAgYFNlcnZlciBpcyBhc2tpbmcgY2xpZW50cyB0byBiYWNrIG9mZjsgcmV0cnkgaW4gJHtzZWNvbmRzfXMgb3IgdXNlIHRoZSBpZ25vcmVCYWNrb2ZmIG9wdGlvbi5gXG4gICAgICAgIClcbiAgICAgICk7XG4gICAgfVxuXG4gICAgY29uc3QgY2xpZW50ID0gdGhpcy5hcGlcbiAgICAgIC5idWNrZXQob3B0aW9ucy5idWNrZXQpXG4gICAgICAuY29sbGVjdGlvbihvcHRpb25zLmNvbGxlY3Rpb24pO1xuXG4gICAgY29uc3QgcmVzdWx0ID0gbmV3IFN5bmNSZXN1bHRPYmplY3QoKTtcbiAgICB0cnkge1xuICAgICAgLy8gRmV0Y2ggY29sbGVjdGlvbiBtZXRhZGF0YS5cbiAgICAgIGF3YWl0IHRoaXMucHVsbE1ldGFkYXRhKGNsaWVudCwgb3B0aW9ucyk7XG5cbiAgICAgIC8vIEZldGNoIGxhc3QgY2hhbmdlcyBmcm9tIHRoZSBzZXJ2ZXIuXG4gICAgICBhd2FpdCB0aGlzLnB1bGxDaGFuZ2VzKGNsaWVudCwgcmVzdWx0LCBvcHRpb25zKTtcbiAgICAgIGNvbnN0IHsgbGFzdE1vZGlmaWVkIH0gPSByZXN1bHQ7XG5cbiAgICAgIGlmIChvcHRpb25zLnN0cmF0ZWd5ICE9IENvbGxlY3Rpb24uc3RyYXRlZ3kuUFVMTF9PTkxZKSB7XG4gICAgICAgIC8vIEZldGNoIGxvY2FsIGNoYW5nZXNcbiAgICAgICAgY29uc3QgdG9TeW5jID0gYXdhaXQgdGhpcy5nYXRoZXJMb2NhbENoYW5nZXMoKTtcblxuICAgICAgICAvLyBQdWJsaXNoIGxvY2FsIGNoYW5nZXMgYW5kIHB1bGwgbG9jYWwgcmVzb2x1dGlvbnNcbiAgICAgICAgYXdhaXQgdGhpcy5wdXNoQ2hhbmdlcyhjbGllbnQsIHRvU3luYywgcmVzdWx0LCBvcHRpb25zKTtcblxuICAgICAgICAvLyBQdWJsaXNoIGxvY2FsIHJlc29sdXRpb24gb2YgcHVzaCBjb25mbGljdHMgdG8gc2VydmVyIChvbiBDTElFTlRfV0lOUylcbiAgICAgICAgY29uc3QgcmVzb2x2ZWRVbnN5bmNlZCA9IHJlc3VsdC5yZXNvbHZlZC5maWx0ZXIoXG4gICAgICAgICAgciA9PiByLl9zdGF0dXMgIT09IFwic3luY2VkXCJcbiAgICAgICAgKTtcbiAgICAgICAgaWYgKHJlc29sdmVkVW5zeW5jZWQubGVuZ3RoID4gMCkge1xuICAgICAgICAgIGNvbnN0IHJlc29sdmVkRW5jb2RlZCA9IGF3YWl0IFByb21pc2UuYWxsKFxuICAgICAgICAgICAgcmVzb2x2ZWRVbnN5bmNlZC5tYXAocmVzb2x1dGlvbiA9PiB7XG4gICAgICAgICAgICAgIGxldCByZWNvcmQgPSByZXNvbHV0aW9uLmFjY2VwdGVkO1xuICAgICAgICAgICAgICBpZiAocmVjb3JkID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgcmVjb3JkID0geyBpZDogcmVzb2x1dGlvbi5pZCwgX3N0YXR1czogcmVzb2x1dGlvbi5fc3RhdHVzIH07XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2VuY29kZVJlY29yZChcInJlbW90ZVwiLCByZWNvcmQpO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICApO1xuICAgICAgICAgIGF3YWl0IHRoaXMucHVzaENoYW5nZXMoY2xpZW50LCByZXNvbHZlZEVuY29kZWQsIHJlc3VsdCwgb3B0aW9ucyk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gUGVyZm9ybSBhIGxhc3QgcHVsbCB0byBjYXRjaCBjaGFuZ2VzIHRoYXQgb2NjdXJlZCBhZnRlciB0aGUgbGFzdCBwdWxsLFxuICAgICAgICAvLyB3aGlsZSBsb2NhbCBjaGFuZ2VzIHdlcmUgcHVzaGVkLiBEbyBub3QgZG8gaXQgbm90aGluZyB3YXMgcHVzaGVkLlxuICAgICAgICBpZiAocmVzdWx0LnB1Ymxpc2hlZC5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgLy8gQXZvaWQgcmVkb3dubG9hZGluZyBvdXIgb3duIGNoYW5nZXMgZHVyaW5nIHRoZSBsYXN0IHB1bGwuXG4gICAgICAgICAgY29uc3QgcHVsbE9wdHMgPSB7XG4gICAgICAgICAgICAuLi5vcHRpb25zLFxuICAgICAgICAgICAgbGFzdE1vZGlmaWVkLFxuICAgICAgICAgICAgZXhjbHVkZTogcmVzdWx0LnB1Ymxpc2hlZCxcbiAgICAgICAgICB9O1xuICAgICAgICAgIGF3YWl0IHRoaXMucHVsbENoYW5nZXMoY2xpZW50LCByZXN1bHQsIHB1bGxPcHRzKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyBEb24ndCBwZXJzaXN0IGxhc3RNb2RpZmllZCB2YWx1ZSBpZiBhbnkgY29uZmxpY3Qgb3IgZXJyb3Igb2NjdXJlZFxuICAgICAgaWYgKHJlc3VsdC5vaykge1xuICAgICAgICAvLyBObyBjb25mbGljdCBvY2N1cmVkLCBwZXJzaXN0IGNvbGxlY3Rpb24ncyBsYXN0TW9kaWZpZWQgdmFsdWVcbiAgICAgICAgdGhpcy5fbGFzdE1vZGlmaWVkID0gYXdhaXQgdGhpcy5kYi5zYXZlTGFzdE1vZGlmaWVkKFxuICAgICAgICAgIHJlc3VsdC5sYXN0TW9kaWZpZWRcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICB0aGlzLmV2ZW50cy5lbWl0KFwic3luYzplcnJvclwiLCB7IC4uLm9wdGlvbnMsIGVycm9yOiBlIH0pO1xuICAgICAgdGhyb3cgZTtcbiAgICB9IGZpbmFsbHkge1xuICAgICAgLy8gRW5zdXJlIEFQSSBkZWZhdWx0IHJlbW90ZSBpcyByZXZlcnRlZCBpZiBhIGN1c3RvbSBvbmUncyBiZWVuIHVzZWRcbiAgICAgIHRoaXMuYXBpLnJlbW90ZSA9IHByZXZpb3VzUmVtb3RlO1xuICAgIH1cbiAgICB0aGlzLmV2ZW50cy5lbWl0KFwic3luYzpzdWNjZXNzXCIsIHsgLi4ub3B0aW9ucywgcmVzdWx0IH0pO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICAvKipcbiAgICogTG9hZCBhIGxpc3Qgb2YgcmVjb3JkcyBhbHJlYWR5IHN5bmNlZCB3aXRoIHRoZSByZW1vdGUgc2VydmVyLlxuICAgKlxuICAgKiBUaGUgbG9jYWwgcmVjb3JkcyB3aGljaCBhcmUgdW5zeW5jZWQgb3Igd2hvc2UgdGltZXN0YW1wIGlzIGVpdGhlciBtaXNzaW5nXG4gICAqIG9yIHN1cGVyaW9yIHRvIHRob3NlIGJlaW5nIGxvYWRlZCB3aWxsIGJlIGlnbm9yZWQuXG4gICAqXG4gICAqIEBkZXByZWNhdGVkIFVzZSB7QGxpbmsgaW1wb3J0QnVsa30gaW5zdGVhZC5cbiAgICogQHBhcmFtICB7QXJyYXl9IHJlY29yZHMgVGhlIHByZXZpb3VzbHkgZXhwb3J0ZWQgbGlzdCBvZiByZWNvcmRzIHRvIGxvYWQuXG4gICAqIEByZXR1cm4ge1Byb21pc2V9IHdpdGggdGhlIGVmZmVjdGl2ZWx5IGltcG9ydGVkIHJlY29yZHMuXG4gICAqL1xuICBhc3luYyBsb2FkRHVtcChyZWNvcmRzKSB7XG4gICAgcmV0dXJuIHRoaXMuaW1wb3J0QnVsayhyZWNvcmRzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBMb2FkIGEgbGlzdCBvZiByZWNvcmRzIGFscmVhZHkgc3luY2VkIHdpdGggdGhlIHJlbW90ZSBzZXJ2ZXIuXG4gICAqXG4gICAqIFRoZSBsb2NhbCByZWNvcmRzIHdoaWNoIGFyZSB1bnN5bmNlZCBvciB3aG9zZSB0aW1lc3RhbXAgaXMgZWl0aGVyIG1pc3NpbmdcbiAgICogb3Igc3VwZXJpb3IgdG8gdGhvc2UgYmVpbmcgbG9hZGVkIHdpbGwgYmUgaWdub3JlZC5cbiAgICpcbiAgICogQHBhcmFtICB7QXJyYXl9IHJlY29yZHMgVGhlIHByZXZpb3VzbHkgZXhwb3J0ZWQgbGlzdCBvZiByZWNvcmRzIHRvIGxvYWQuXG4gICAqIEByZXR1cm4ge1Byb21pc2V9IHdpdGggdGhlIGVmZmVjdGl2ZWx5IGltcG9ydGVkIHJlY29yZHMuXG4gICAqL1xuICBhc3luYyBpbXBvcnRCdWxrKHJlY29yZHMpIHtcbiAgICBpZiAoIUFycmF5LmlzQXJyYXkocmVjb3JkcykpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlJlY29yZHMgaXMgbm90IGFuIGFycmF5LlwiKTtcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IHJlY29yZCBvZiByZWNvcmRzKSB7XG4gICAgICBpZiAoXG4gICAgICAgICFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwocmVjb3JkLCBcImlkXCIpIHx8XG4gICAgICAgICF0aGlzLmlkU2NoZW1hLnZhbGlkYXRlKHJlY29yZC5pZClcbiAgICAgICkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJSZWNvcmQgaGFzIGludmFsaWQgSUQ6IFwiICsgSlNPTi5zdHJpbmdpZnkocmVjb3JkKSk7XG4gICAgICB9XG5cbiAgICAgIGlmICghcmVjb3JkLmxhc3RfbW9kaWZpZWQpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgIFwiUmVjb3JkIGhhcyBubyBsYXN0X21vZGlmaWVkIHZhbHVlOiBcIiArIEpTT04uc3RyaW5naWZ5KHJlY29yZClcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBGZXRjaCBhbGwgZXhpc3RpbmcgcmVjb3JkcyBmcm9tIGxvY2FsIGRhdGFiYXNlLFxuICAgIC8vIGFuZCBza2lwIHRob3NlIHdobyBhcmUgbmV3ZXIgb3Igbm90IG1hcmtlZCBhcyBzeW5jZWQuXG5cbiAgICAvLyBYWFggZmlsdGVyIGJ5IHN0YXR1cyAvIGlkcyBpbiByZWNvcmRzXG5cbiAgICBjb25zdCB7IGRhdGEgfSA9IGF3YWl0IHRoaXMubGlzdCh7fSwgeyBpbmNsdWRlRGVsZXRlZDogdHJ1ZSB9KTtcbiAgICBjb25zdCBleGlzdGluZ0J5SWQgPSBkYXRhLnJlZHVjZSgoYWNjLCByZWNvcmQpID0+IHtcbiAgICAgIGFjY1tyZWNvcmQuaWRdID0gcmVjb3JkO1xuICAgICAgcmV0dXJuIGFjYztcbiAgICB9LCB7fSk7XG5cbiAgICBjb25zdCBuZXdSZWNvcmRzID0gcmVjb3Jkcy5maWx0ZXIocmVjb3JkID0+IHtcbiAgICAgIGNvbnN0IGxvY2FsUmVjb3JkID0gZXhpc3RpbmdCeUlkW3JlY29yZC5pZF07XG4gICAgICBjb25zdCBzaG91bGRLZWVwID1cbiAgICAgICAgLy8gTm8gbG9jYWwgcmVjb3JkIHdpdGggdGhpcyBpZC5cbiAgICAgICAgbG9jYWxSZWNvcmQgPT09IHVuZGVmaW5lZCB8fFxuICAgICAgICAvLyBPciBsb2NhbCByZWNvcmQgaXMgc3luY2VkXG4gICAgICAgIChsb2NhbFJlY29yZC5fc3RhdHVzID09PSBcInN5bmNlZFwiICYmXG4gICAgICAgICAgLy8gQW5kIHdhcyBzeW5jZWQgZnJvbSBzZXJ2ZXJcbiAgICAgICAgICBsb2NhbFJlY29yZC5sYXN0X21vZGlmaWVkICE9PSB1bmRlZmluZWQgJiZcbiAgICAgICAgICAvLyBBbmQgaXMgb2xkZXIgdGhhbiBpbXBvcnRlZCBvbmUuXG4gICAgICAgICAgcmVjb3JkLmxhc3RfbW9kaWZpZWQgPiBsb2NhbFJlY29yZC5sYXN0X21vZGlmaWVkKTtcbiAgICAgIHJldHVybiBzaG91bGRLZWVwO1xuICAgIH0pO1xuXG4gICAgcmV0dXJuIGF3YWl0IHRoaXMuZGIuaW1wb3J0QnVsayhuZXdSZWNvcmRzLm1hcChtYXJrU3luY2VkKSk7XG4gIH1cblxuICBhc3luYyBwdWxsTWV0YWRhdGEoY2xpZW50LCBvcHRpb25zID0ge30pIHtcbiAgICBjb25zdCB7IGV4cGVjdGVkVGltZXN0YW1wLCBoZWFkZXJzIH0gPSBvcHRpb25zO1xuICAgIGNvbnN0IHF1ZXJ5ID0gZXhwZWN0ZWRUaW1lc3RhbXBcbiAgICAgID8geyBxdWVyeTogeyBfZXhwZWN0ZWQ6IGV4cGVjdGVkVGltZXN0YW1wIH0gfVxuICAgICAgOiB1bmRlZmluZWQ7XG4gICAgY29uc3QgbWV0YWRhdGEgPSBhd2FpdCBjbGllbnQuZ2V0RGF0YSh7XG4gICAgICAuLi5xdWVyeSxcbiAgICAgIGhlYWRlcnMsXG4gICAgfSk7XG4gICAgcmV0dXJuIHRoaXMuZGIuc2F2ZU1ldGFkYXRhKG1ldGFkYXRhKTtcbiAgfVxuXG4gIGFzeW5jIG1ldGFkYXRhKCkge1xuICAgIHJldHVybiB0aGlzLmRiLmdldE1ldGFkYXRhKCk7XG4gIH1cbn1cblxuLyoqXG4gKiBBIENvbGxlY3Rpb24tb3JpZW50ZWQgd3JhcHBlciBmb3IgYW4gYWRhcHRlcidzIHRyYW5zYWN0aW9uLlxuICpcbiAqIFRoaXMgZGVmaW5lcyB0aGUgaGlnaC1sZXZlbCBmdW5jdGlvbnMgYXZhaWxhYmxlIG9uIGEgY29sbGVjdGlvbi5cbiAqIFRoZSBjb2xsZWN0aW9uIGl0c2VsZiBvZmZlcnMgZnVuY3Rpb25zIG9mIHRoZSBzYW1lIG5hbWUuIFRoZXNlIHdpbGxcbiAqIHBlcmZvcm0ganVzdCBvbmUgb3BlcmF0aW9uIGluIGl0cyBvd24gdHJhbnNhY3Rpb24uXG4gKi9cbmV4cG9ydCBjbGFzcyBDb2xsZWN0aW9uVHJhbnNhY3Rpb24ge1xuICBjb25zdHJ1Y3Rvcihjb2xsZWN0aW9uLCBhZGFwdGVyVHJhbnNhY3Rpb24pIHtcbiAgICB0aGlzLmNvbGxlY3Rpb24gPSBjb2xsZWN0aW9uO1xuICAgIHRoaXMuYWRhcHRlclRyYW5zYWN0aW9uID0gYWRhcHRlclRyYW5zYWN0aW9uO1xuXG4gICAgdGhpcy5fZXZlbnRzID0gW107XG4gIH1cblxuICBfcXVldWVFdmVudChhY3Rpb24sIHBheWxvYWQpIHtcbiAgICB0aGlzLl9ldmVudHMucHVzaCh7IGFjdGlvbiwgcGF5bG9hZCB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBFbWl0IHF1ZXVlZCBldmVudHMsIHRvIGJlIGNhbGxlZCBvbmNlIGV2ZXJ5IHRyYW5zYWN0aW9uIG9wZXJhdGlvbnMgaGF2ZVxuICAgKiBiZWVuIGV4ZWN1dGVkIHN1Y2Nlc3NmdWxseS5cbiAgICovXG4gIGVtaXRFdmVudHMoKSB7XG4gICAgZm9yIChjb25zdCB7IGFjdGlvbiwgcGF5bG9hZCB9IG9mIHRoaXMuX2V2ZW50cykge1xuICAgICAgdGhpcy5jb2xsZWN0aW9uLmV2ZW50cy5lbWl0KGFjdGlvbiwgcGF5bG9hZCk7XG4gICAgfVxuICAgIGlmICh0aGlzLl9ldmVudHMubGVuZ3RoID4gMCkge1xuICAgICAgY29uc3QgdGFyZ2V0cyA9IHRoaXMuX2V2ZW50cy5tYXAoKHsgYWN0aW9uLCBwYXlsb2FkIH0pID0+ICh7XG4gICAgICAgIGFjdGlvbixcbiAgICAgICAgLi4ucGF5bG9hZCxcbiAgICAgIH0pKTtcbiAgICAgIHRoaXMuY29sbGVjdGlvbi5ldmVudHMuZW1pdChcImNoYW5nZVwiLCB7IHRhcmdldHMgfSk7XG4gICAgfVxuICAgIHRoaXMuX2V2ZW50cyA9IFtdO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHJpZXZlIGEgcmVjb3JkIGJ5IGl0cyBpZCBmcm9tIHRoZSBsb2NhbCBkYXRhYmFzZSwgb3JcbiAgICogdW5kZWZpbmVkIGlmIG5vbmUgZXhpc3RzLlxuICAgKlxuICAgKiBUaGlzIHdpbGwgYWxzbyByZXR1cm4gdmlydHVhbGx5IGRlbGV0ZWQgcmVjb3Jkcy5cbiAgICpcbiAgICogQHBhcmFtICB7U3RyaW5nfSBpZFxuICAgKiBAcmV0dXJuIHtPYmplY3R9XG4gICAqL1xuICBnZXRBbnkoaWQpIHtcbiAgICBjb25zdCByZWNvcmQgPSB0aGlzLmFkYXB0ZXJUcmFuc2FjdGlvbi5nZXQoaWQpO1xuICAgIHJldHVybiB7IGRhdGE6IHJlY29yZCwgcGVybWlzc2lvbnM6IHt9IH07XG4gIH1cblxuICAvKipcbiAgICogUmV0cmlldmUgYSByZWNvcmQgYnkgaXRzIGlkIGZyb20gdGhlIGxvY2FsIGRhdGFiYXNlLlxuICAgKlxuICAgKiBPcHRpb25zOlxuICAgKiAtIHtCb29sZWFufSBpbmNsdWRlRGVsZXRlZDogSW5jbHVkZSB2aXJ0dWFsbHkgZGVsZXRlZCByZWNvcmRzLlxuICAgKlxuICAgKiBAcGFyYW0gIHtTdHJpbmd9IGlkXG4gICAqIEBwYXJhbSAge09iamVjdH0gb3B0aW9uc1xuICAgKiBAcmV0dXJuIHtPYmplY3R9XG4gICAqL1xuICBnZXQoaWQsIG9wdGlvbnMgPSB7IGluY2x1ZGVEZWxldGVkOiBmYWxzZSB9KSB7XG4gICAgY29uc3QgcmVzID0gdGhpcy5nZXRBbnkoaWQpO1xuICAgIGlmIChcbiAgICAgICFyZXMuZGF0YSB8fFxuICAgICAgKCFvcHRpb25zLmluY2x1ZGVEZWxldGVkICYmIHJlcy5kYXRhLl9zdGF0dXMgPT09IFwiZGVsZXRlZFwiKVxuICAgICkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBSZWNvcmQgd2l0aCBpZD0ke2lkfSBub3QgZm91bmQuYCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlcztcbiAgfVxuXG4gIC8qKlxuICAgKiBEZWxldGVzIGEgcmVjb3JkIGZyb20gdGhlIGxvY2FsIGRhdGFiYXNlLlxuICAgKlxuICAgKiBPcHRpb25zOlxuICAgKiAtIHtCb29sZWFufSB2aXJ0dWFsOiBXaGVuIHNldCB0byBgdHJ1ZWAsIGRvZXNuJ3QgYWN0dWFsbHkgZGVsZXRlIHRoZSByZWNvcmQsXG4gICAqICAgdXBkYXRlIGl0cyBgX3N0YXR1c2AgYXR0cmlidXRlIHRvIGBkZWxldGVkYCBpbnN0ZWFkIChkZWZhdWx0OiB0cnVlKVxuICAgKlxuICAgKiBAcGFyYW0gIHtTdHJpbmd9IGlkICAgICAgIFRoZSByZWNvcmQncyBJZC5cbiAgICogQHBhcmFtICB7T2JqZWN0fSBvcHRpb25zICBUaGUgb3B0aW9ucyBvYmplY3QuXG4gICAqIEByZXR1cm4ge09iamVjdH1cbiAgICovXG4gIGRlbGV0ZShpZCwgb3B0aW9ucyA9IHsgdmlydHVhbDogdHJ1ZSB9KSB7XG4gICAgLy8gRW5zdXJlIHRoZSByZWNvcmQgYWN0dWFsbHkgZXhpc3RzLlxuICAgIGNvbnN0IGV4aXN0aW5nID0gdGhpcy5hZGFwdGVyVHJhbnNhY3Rpb24uZ2V0KGlkKTtcbiAgICBjb25zdCBhbHJlYWR5RGVsZXRlZCA9IGV4aXN0aW5nICYmIGV4aXN0aW5nLl9zdGF0dXMgPT0gXCJkZWxldGVkXCI7XG4gICAgaWYgKCFleGlzdGluZyB8fCAoYWxyZWFkeURlbGV0ZWQgJiYgb3B0aW9ucy52aXJ0dWFsKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBSZWNvcmQgd2l0aCBpZD0ke2lkfSBub3QgZm91bmQuYCk7XG4gICAgfVxuICAgIC8vIFZpcnR1YWwgdXBkYXRlcyBzdGF0dXMuXG4gICAgaWYgKG9wdGlvbnMudmlydHVhbCkge1xuICAgICAgdGhpcy5hZGFwdGVyVHJhbnNhY3Rpb24udXBkYXRlKG1hcmtEZWxldGVkKGV4aXN0aW5nKSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIERlbGV0ZSBmb3IgcmVhbC5cbiAgICAgIHRoaXMuYWRhcHRlclRyYW5zYWN0aW9uLmRlbGV0ZShpZCk7XG4gICAgfVxuICAgIHRoaXMuX3F1ZXVlRXZlbnQoXCJkZWxldGVcIiwgeyBkYXRhOiBleGlzdGluZyB9KTtcbiAgICByZXR1cm4geyBkYXRhOiBleGlzdGluZywgcGVybWlzc2lvbnM6IHt9IH07XG4gIH1cblxuICAvKipcbiAgICogU29mdCBkZWxldGUgYWxsIHJlY29yZHMgZnJvbSB0aGUgbG9jYWwgZGF0YWJhc2UuXG4gICAqXG4gICAqIEBwYXJhbSAge0FycmF5fSBpZHMgICAgICAgIEFycmF5IG9mIG5vbi1kZWxldGVkIFJlY29yZCBJZHMuXG4gICAqIEByZXR1cm4ge09iamVjdH1cbiAgICovXG4gIGRlbGV0ZUFsbChpZHMpIHtcbiAgICBjb25zdCBleGlzdGluZ1JlY29yZHMgPSBbXTtcbiAgICBpZHMuZm9yRWFjaChpZCA9PiB7XG4gICAgICBleGlzdGluZ1JlY29yZHMucHVzaCh0aGlzLmFkYXB0ZXJUcmFuc2FjdGlvbi5nZXQoaWQpKTtcbiAgICAgIHRoaXMuZGVsZXRlKGlkKTtcbiAgICB9KTtcblxuICAgIHRoaXMuX3F1ZXVlRXZlbnQoXCJkZWxldGVBbGxcIiwgeyBkYXRhOiBleGlzdGluZ1JlY29yZHMgfSk7XG4gICAgcmV0dXJuIHsgZGF0YTogZXhpc3RpbmdSZWNvcmRzLCBwZXJtaXNzaW9uczoge30gfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBEZWxldGVzIGEgcmVjb3JkIGZyb20gdGhlIGxvY2FsIGRhdGFiYXNlLCBpZiBhbnkgZXhpc3RzLlxuICAgKiBPdGhlcndpc2UsIGRvIG5vdGhpbmcuXG4gICAqXG4gICAqIEBwYXJhbSAge1N0cmluZ30gaWQgICAgICAgVGhlIHJlY29yZCdzIElkLlxuICAgKiBAcmV0dXJuIHtPYmplY3R9XG4gICAqL1xuICBkZWxldGVBbnkoaWQpIHtcbiAgICBjb25zdCBleGlzdGluZyA9IHRoaXMuYWRhcHRlclRyYW5zYWN0aW9uLmdldChpZCk7XG4gICAgaWYgKGV4aXN0aW5nKSB7XG4gICAgICB0aGlzLmFkYXB0ZXJUcmFuc2FjdGlvbi51cGRhdGUobWFya0RlbGV0ZWQoZXhpc3RpbmcpKTtcbiAgICAgIHRoaXMuX3F1ZXVlRXZlbnQoXCJkZWxldGVcIiwgeyBkYXRhOiBleGlzdGluZyB9KTtcbiAgICB9XG4gICAgcmV0dXJuIHsgZGF0YTogeyBpZCwgLi4uZXhpc3RpbmcgfSwgZGVsZXRlZDogISFleGlzdGluZywgcGVybWlzc2lvbnM6IHt9IH07XG4gIH1cblxuICAvKipcbiAgICogQWRkcyBhIHJlY29yZCB0byB0aGUgbG9jYWwgZGF0YWJhc2UsIGFzc2VydGluZyB0aGF0IG5vbmVcbiAgICogYWxyZWFkeSBleGlzdCB3aXRoIHRoaXMgSUQuXG4gICAqXG4gICAqIEBwYXJhbSAge09iamVjdH0gcmVjb3JkLCB3aGljaCBtdXN0IGNvbnRhaW4gYW4gSURcbiAgICogQHJldHVybiB7T2JqZWN0fVxuICAgKi9cbiAgY3JlYXRlKHJlY29yZCkge1xuICAgIGlmICh0eXBlb2YgcmVjb3JkICE9PSBcIm9iamVjdFwiKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJSZWNvcmQgaXMgbm90IGFuIG9iamVjdC5cIik7XG4gICAgfVxuICAgIGlmICghT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHJlY29yZCwgXCJpZFwiKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQ2Fubm90IGNyZWF0ZSBhIHJlY29yZCBtaXNzaW5nIGlkXCIpO1xuICAgIH1cbiAgICBpZiAoIXRoaXMuY29sbGVjdGlvbi5pZFNjaGVtYS52YWxpZGF0ZShyZWNvcmQuaWQpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQgSWQ6ICR7cmVjb3JkLmlkfWApO1xuICAgIH1cblxuICAgIHRoaXMuYWRhcHRlclRyYW5zYWN0aW9uLmNyZWF0ZShyZWNvcmQpO1xuICAgIHRoaXMuX3F1ZXVlRXZlbnQoXCJjcmVhdGVcIiwgeyBkYXRhOiByZWNvcmQgfSk7XG4gICAgcmV0dXJuIHsgZGF0YTogcmVjb3JkLCBwZXJtaXNzaW9uczoge30gfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBVcGRhdGVzIGEgcmVjb3JkIGZyb20gdGhlIGxvY2FsIGRhdGFiYXNlLlxuICAgKlxuICAgKiBPcHRpb25zOlxuICAgKiAtIHtCb29sZWFufSBzeW5jZWQ6IFNldHMgcmVjb3JkIHN0YXR1cyB0byBcInN5bmNlZFwiIChkZWZhdWx0OiBmYWxzZSlcbiAgICogLSB7Qm9vbGVhbn0gcGF0Y2g6ICBFeHRlbmRzIHRoZSBleGlzdGluZyByZWNvcmQgaW5zdGVhZCBvZiBvdmVyd3JpdGluZyBpdFxuICAgKiAgIChkZWZhdWx0OiBmYWxzZSlcbiAgICpcbiAgICogQHBhcmFtICB7T2JqZWN0fSByZWNvcmRcbiAgICogQHBhcmFtICB7T2JqZWN0fSBvcHRpb25zXG4gICAqIEByZXR1cm4ge09iamVjdH1cbiAgICovXG4gIHVwZGF0ZShyZWNvcmQsIG9wdGlvbnMgPSB7IHN5bmNlZDogZmFsc2UsIHBhdGNoOiBmYWxzZSB9KSB7XG4gICAgaWYgKHR5cGVvZiByZWNvcmQgIT09IFwib2JqZWN0XCIpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlJlY29yZCBpcyBub3QgYW4gb2JqZWN0LlwiKTtcbiAgICB9XG4gICAgaWYgKCFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwocmVjb3JkLCBcImlkXCIpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJDYW5ub3QgdXBkYXRlIGEgcmVjb3JkIG1pc3NpbmcgaWQuXCIpO1xuICAgIH1cbiAgICBpZiAoIXRoaXMuY29sbGVjdGlvbi5pZFNjaGVtYS52YWxpZGF0ZShyZWNvcmQuaWQpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQgSWQ6ICR7cmVjb3JkLmlkfWApO1xuICAgIH1cblxuICAgIGNvbnN0IG9sZFJlY29yZCA9IHRoaXMuYWRhcHRlclRyYW5zYWN0aW9uLmdldChyZWNvcmQuaWQpO1xuICAgIGlmICghb2xkUmVjb3JkKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYFJlY29yZCB3aXRoIGlkPSR7cmVjb3JkLmlkfSBub3QgZm91bmQuYCk7XG4gICAgfVxuICAgIGNvbnN0IG5ld1JlY29yZCA9IG9wdGlvbnMucGF0Y2ggPyB7IC4uLm9sZFJlY29yZCwgLi4ucmVjb3JkIH0gOiByZWNvcmQ7XG4gICAgY29uc3QgdXBkYXRlZCA9IHRoaXMuX3VwZGF0ZVJhdyhvbGRSZWNvcmQsIG5ld1JlY29yZCwgb3B0aW9ucyk7XG4gICAgdGhpcy5hZGFwdGVyVHJhbnNhY3Rpb24udXBkYXRlKHVwZGF0ZWQpO1xuICAgIHRoaXMuX3F1ZXVlRXZlbnQoXCJ1cGRhdGVcIiwgeyBkYXRhOiB1cGRhdGVkLCBvbGRSZWNvcmQgfSk7XG4gICAgcmV0dXJuIHsgZGF0YTogdXBkYXRlZCwgb2xkUmVjb3JkLCBwZXJtaXNzaW9uczoge30gfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBMb3dlci1sZXZlbCBwcmltaXRpdmUgZm9yIHVwZGF0aW5nIGEgcmVjb3JkIHdoaWxlIHJlc3BlY3RpbmdcbiAgICogX3N0YXR1cyBhbmQgbGFzdF9tb2RpZmllZC5cbiAgICpcbiAgICogQHBhcmFtICB7T2JqZWN0fSBvbGRSZWNvcmQ6IHRoZSByZWNvcmQgcmV0cmlldmVkIGZyb20gdGhlIERCXG4gICAqIEBwYXJhbSAge09iamVjdH0gbmV3UmVjb3JkOiB0aGUgcmVjb3JkIHRvIHJlcGxhY2UgaXQgd2l0aFxuICAgKiBAcmV0dXJuIHtPYmplY3R9XG4gICAqL1xuICBfdXBkYXRlUmF3KG9sZFJlY29yZCwgbmV3UmVjb3JkLCB7IHN5bmNlZCA9IGZhbHNlIH0gPSB7fSkge1xuICAgIGNvbnN0IHVwZGF0ZWQgPSB7IC4uLm5ld1JlY29yZCB9O1xuICAgIC8vIE1ha2Ugc3VyZSB0byBuZXZlciBsb29zZSB0aGUgZXhpc3RpbmcgdGltZXN0YW1wLlxuICAgIGlmIChvbGRSZWNvcmQgJiYgb2xkUmVjb3JkLmxhc3RfbW9kaWZpZWQgJiYgIXVwZGF0ZWQubGFzdF9tb2RpZmllZCkge1xuICAgICAgdXBkYXRlZC5sYXN0X21vZGlmaWVkID0gb2xkUmVjb3JkLmxhc3RfbW9kaWZpZWQ7XG4gICAgfVxuICAgIC8vIElmIG9ubHkgbG9jYWwgZmllbGRzIGhhdmUgY2hhbmdlZCwgdGhlbiBrZWVwIHJlY29yZCBhcyBzeW5jZWQuXG4gICAgLy8gSWYgc3RhdHVzIGlzIGNyZWF0ZWQsIGtlZXAgcmVjb3JkIGFzIGNyZWF0ZWQuXG4gICAgLy8gSWYgc3RhdHVzIGlzIGRlbGV0ZWQsIG1hcmsgYXMgdXBkYXRlZC5cbiAgICBjb25zdCBpc0lkZW50aWNhbCA9XG4gICAgICBvbGRSZWNvcmQgJiZcbiAgICAgIHJlY29yZHNFcXVhbChvbGRSZWNvcmQsIHVwZGF0ZWQsIHRoaXMuY29sbGVjdGlvbi5sb2NhbEZpZWxkcyk7XG4gICAgY29uc3Qga2VlcFN5bmNlZCA9IGlzSWRlbnRpY2FsICYmIG9sZFJlY29yZC5fc3RhdHVzID09IFwic3luY2VkXCI7XG4gICAgY29uc3QgbmV2ZXJTeW5jZWQgPVxuICAgICAgIW9sZFJlY29yZCB8fCAob2xkUmVjb3JkICYmIG9sZFJlY29yZC5fc3RhdHVzID09IFwiY3JlYXRlZFwiKTtcbiAgICBjb25zdCBuZXdTdGF0dXMgPVxuICAgICAga2VlcFN5bmNlZCB8fCBzeW5jZWQgPyBcInN5bmNlZFwiIDogbmV2ZXJTeW5jZWQgPyBcImNyZWF0ZWRcIiA6IFwidXBkYXRlZFwiO1xuICAgIHJldHVybiBtYXJrU3RhdHVzKHVwZGF0ZWQsIG5ld1N0YXR1cyk7XG4gIH1cblxuICAvKipcbiAgICogVXBzZXJ0IGEgcmVjb3JkIGludG8gdGhlIGxvY2FsIGRhdGFiYXNlLlxuICAgKlxuICAgKiBUaGlzIHJlY29yZCBtdXN0IGhhdmUgYW4gSUQuXG4gICAqXG4gICAqIElmIGEgcmVjb3JkIHdpdGggdGhpcyBJRCBhbHJlYWR5IGV4aXN0cywgaXQgd2lsbCBiZSByZXBsYWNlZC5cbiAgICogT3RoZXJ3aXNlLCB0aGlzIHJlY29yZCB3aWxsIGJlIGluc2VydGVkLlxuICAgKlxuICAgKiBAcGFyYW0gIHtPYmplY3R9IHJlY29yZFxuICAgKiBAcmV0dXJuIHtPYmplY3R9XG4gICAqL1xuICB1cHNlcnQocmVjb3JkKSB7XG4gICAgaWYgKHR5cGVvZiByZWNvcmQgIT09IFwib2JqZWN0XCIpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlJlY29yZCBpcyBub3QgYW4gb2JqZWN0LlwiKTtcbiAgICB9XG4gICAgaWYgKCFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwocmVjb3JkLCBcImlkXCIpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJDYW5ub3QgdXBkYXRlIGEgcmVjb3JkIG1pc3NpbmcgaWQuXCIpO1xuICAgIH1cbiAgICBpZiAoIXRoaXMuY29sbGVjdGlvbi5pZFNjaGVtYS52YWxpZGF0ZShyZWNvcmQuaWQpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQgSWQ6ICR7cmVjb3JkLmlkfWApO1xuICAgIH1cbiAgICBsZXQgb2xkUmVjb3JkID0gdGhpcy5hZGFwdGVyVHJhbnNhY3Rpb24uZ2V0KHJlY29yZC5pZCk7XG4gICAgY29uc3QgdXBkYXRlZCA9IHRoaXMuX3VwZGF0ZVJhdyhvbGRSZWNvcmQsIHJlY29yZCk7XG4gICAgdGhpcy5hZGFwdGVyVHJhbnNhY3Rpb24udXBkYXRlKHVwZGF0ZWQpO1xuICAgIC8vIERvbid0IHJldHVybiBkZWxldGVkIHJlY29yZHMgLS0gcHJldGVuZCB0aGV5IGFyZSBnb25lXG4gICAgaWYgKG9sZFJlY29yZCAmJiBvbGRSZWNvcmQuX3N0YXR1cyA9PSBcImRlbGV0ZWRcIikge1xuICAgICAgb2xkUmVjb3JkID0gdW5kZWZpbmVkO1xuICAgIH1cbiAgICBpZiAob2xkUmVjb3JkKSB7XG4gICAgICB0aGlzLl9xdWV1ZUV2ZW50KFwidXBkYXRlXCIsIHsgZGF0YTogdXBkYXRlZCwgb2xkUmVjb3JkIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLl9xdWV1ZUV2ZW50KFwiY3JlYXRlXCIsIHsgZGF0YTogdXBkYXRlZCB9KTtcbiAgICB9XG4gICAgcmV0dXJuIHsgZGF0YTogdXBkYXRlZCwgb2xkUmVjb3JkLCBwZXJtaXNzaW9uczoge30gfTtcbiAgfVxufVxuIiwiXCJ1c2Ugc3RyaWN0XCI7XG5cbmltcG9ydCB7IEV2ZW50RW1pdHRlciB9IGZyb20gXCJldmVudHNcIjtcblxuLy8gYmFiZWwtcG9seWZpbGwgY2FuIG9ubHkgYmUgaW1wb3J0ZWQgb25jZVxuaWYgKCFnbG9iYWwuX2JhYmVsUG9seWZpbGwpIHtcbiAgcmVxdWlyZShcIkBiYWJlbC9wb2x5ZmlsbFwiKTtcbn1cblxuaW1wb3J0IEFwaSBmcm9tIFwia2ludG8taHR0cFwiO1xuaW1wb3J0IEJhc2VBZGFwdGVyIGZyb20gXCIuL2FkYXB0ZXJzL2Jhc2VcIjtcbmltcG9ydCBJREIgZnJvbSBcIi4vYWRhcHRlcnMvSURCXCI7XG5pbXBvcnQgS2ludG9CYXNlIGZyb20gXCIuL0tpbnRvQmFzZVwiO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBLaW50byBleHRlbmRzIEtpbnRvQmFzZSB7XG4gIC8qKlxuICAgKiBQcm92aWRlcyBhIHB1YmxpYyBhY2Nlc3MgdG8gdGhlIGJhc2UgYWRhcHRlciBjbGFzc2VzLiBVc2VycyBjYW4gY3JlYXRlXG4gICAqIGEgY3VzdG9tIERCIGFkYXB0ZXIgYnkgZXh0ZW5kaW5nIEJhc2VBZGFwdGVyLlxuICAgKlxuICAgKiBAdHlwZSB7T2JqZWN0fVxuICAgKi9cbiAgc3RhdGljIGdldCBhZGFwdGVycygpIHtcbiAgICByZXR1cm4ge1xuICAgICAgQmFzZUFkYXB0ZXIsXG4gICAgICBJREIsXG4gICAgfTtcbiAgfVxuXG4gIGNvbnN0cnVjdG9yKG9wdGlvbnMgPSB7fSkge1xuICAgIGNvbnN0IGRlZmF1bHRzID0ge1xuICAgICAgYWRhcHRlcjogS2ludG8uYWRhcHRlcnMuSURCLFxuICAgICAgZXZlbnRzOiBuZXcgRXZlbnRFbWl0dGVyKCksXG4gICAgICBBcGlDbGFzczogQXBpLFxuICAgIH07XG5cbiAgICBzdXBlcih7IC4uLmRlZmF1bHRzLCAuLi5vcHRpb25zIH0pO1xuICB9XG59XG5cbi8vIFRoaXMgZml4ZXMgY29tcGF0aWJpbGl0eSB3aXRoIENvbW1vbkpTIHJlcXVpcmVkIGJ5IGJyb3dzZXJpZnkuXG4vLyBTZWUgaHR0cDovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy8zMzUwNTk5Mi9iYWJlbC02LWNoYW5nZXMtaG93LWl0LWV4cG9ydHMtZGVmYXVsdC8zMzY4MzQ5NSMzMzY4MzQ5NVxuaWYgKHR5cGVvZiBtb2R1bGUgPT09IFwib2JqZWN0XCIpIHtcbiAgbW9kdWxlLmV4cG9ydHMgPSBLaW50bztcbn1cbiIsIlwidXNlIHN0cmljdFwiO1xuXG5leHBvcnQgY29uc3QgUkVfUkVDT1JEX0lEID0gL15bYS16QS1aMC05XVthLXpBLVowLTlfLV0qJC87XG5cbi8qKlxuICogQ2hlY2tzIGlmIGEgdmFsdWUgaXMgdW5kZWZpbmVkLlxuICogQHBhcmFtICB7QW55fSAgdmFsdWVcbiAqIEByZXR1cm4ge0Jvb2xlYW59XG4gKi9cbmZ1bmN0aW9uIF9pc1VuZGVmaW5lZCh2YWx1ZSkge1xuICByZXR1cm4gdHlwZW9mIHZhbHVlID09PSBcInVuZGVmaW5lZFwiO1xufVxuXG4vKipcbiAqIFNvcnRzIHJlY29yZHMgaW4gYSBsaXN0IGFjY29yZGluZyB0byBhIGdpdmVuIG9yZGVyaW5nLlxuICpcbiAqIEBwYXJhbSAge1N0cmluZ30gb3JkZXIgVGhlIG9yZGVyaW5nLCBlZy4gYC1sYXN0X21vZGlmaWVkYC5cbiAqIEBwYXJhbSAge0FycmF5fSAgbGlzdCAgVGhlIGNvbGxlY3Rpb24gdG8gb3JkZXIuXG4gKiBAcmV0dXJuIHtBcnJheX1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNvcnRPYmplY3RzKG9yZGVyLCBsaXN0KSB7XG4gIGNvbnN0IGhhc0Rhc2ggPSBvcmRlclswXSA9PT0gXCItXCI7XG4gIGNvbnN0IGZpZWxkID0gaGFzRGFzaCA/IG9yZGVyLnNsaWNlKDEpIDogb3JkZXI7XG4gIGNvbnN0IGRpcmVjdGlvbiA9IGhhc0Rhc2ggPyAtMSA6IDE7XG4gIHJldHVybiBsaXN0LnNsaWNlKCkuc29ydCgoYSwgYikgPT4ge1xuICAgIGlmIChhW2ZpZWxkXSAmJiBfaXNVbmRlZmluZWQoYltmaWVsZF0pKSB7XG4gICAgICByZXR1cm4gZGlyZWN0aW9uO1xuICAgIH1cbiAgICBpZiAoYltmaWVsZF0gJiYgX2lzVW5kZWZpbmVkKGFbZmllbGRdKSkge1xuICAgICAgcmV0dXJuIC1kaXJlY3Rpb247XG4gICAgfVxuICAgIGlmIChfaXNVbmRlZmluZWQoYVtmaWVsZF0pICYmIF9pc1VuZGVmaW5lZChiW2ZpZWxkXSkpIHtcbiAgICAgIHJldHVybiAwO1xuICAgIH1cbiAgICByZXR1cm4gYVtmaWVsZF0gPiBiW2ZpZWxkXSA/IGRpcmVjdGlvbiA6IC1kaXJlY3Rpb247XG4gIH0pO1xufVxuXG4vKipcbiAqIFRlc3QgaWYgYSBzaW5nbGUgb2JqZWN0IG1hdGNoZXMgYWxsIGdpdmVuIGZpbHRlcnMuXG4gKlxuICogQHBhcmFtICB7T2JqZWN0fSBmaWx0ZXJzICBUaGUgZmlsdGVycyBvYmplY3QuXG4gKiBAcGFyYW0gIHtPYmplY3R9IGVudHJ5ICAgIFRoZSBvYmplY3QgdG8gZmlsdGVyLlxuICogQHJldHVybiB7Qm9vbGVhbn1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGZpbHRlck9iamVjdChmaWx0ZXJzLCBlbnRyeSkge1xuICByZXR1cm4gT2JqZWN0LmtleXMoZmlsdGVycykuZXZlcnkoZmlsdGVyID0+IHtcbiAgICBjb25zdCB2YWx1ZSA9IGZpbHRlcnNbZmlsdGVyXTtcbiAgICBpZiAoQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHtcbiAgICAgIHJldHVybiB2YWx1ZS5zb21lKGNhbmRpZGF0ZSA9PiBjYW5kaWRhdGUgPT09IGVudHJ5W2ZpbHRlcl0pO1xuICAgIH0gZWxzZSBpZiAodHlwZW9mIHZhbHVlID09PSBcIm9iamVjdFwiKSB7XG4gICAgICByZXR1cm4gZmlsdGVyT2JqZWN0KHZhbHVlLCBlbnRyeVtmaWx0ZXJdKTtcbiAgICB9IGVsc2UgaWYgKCFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoZW50cnksIGZpbHRlcikpIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoYFRoZSBwcm9wZXJ0eSAke2ZpbHRlcn0gZG9lcyBub3QgZXhpc3RgKTtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIGVudHJ5W2ZpbHRlcl0gPT09IHZhbHVlO1xuICB9KTtcbn1cblxuLyoqXG4gKiBGaWx0ZXJzIHJlY29yZHMgaW4gYSBsaXN0IG1hdGNoaW5nIGFsbCBnaXZlbiBmaWx0ZXJzLlxuICpcbiAqIEBwYXJhbSAge09iamVjdH0gZmlsdGVycyAgVGhlIGZpbHRlcnMgb2JqZWN0LlxuICogQHBhcmFtICB7QXJyYXl9ICBsaXN0ICAgICBUaGUgY29sbGVjdGlvbiB0byBmaWx0ZXIuXG4gKiBAcmV0dXJuIHtBcnJheX1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGZpbHRlck9iamVjdHMoZmlsdGVycywgbGlzdCkge1xuICByZXR1cm4gbGlzdC5maWx0ZXIoZW50cnkgPT4ge1xuICAgIHJldHVybiBmaWx0ZXJPYmplY3QoZmlsdGVycywgZW50cnkpO1xuICB9KTtcbn1cblxuLyoqXG4gKiBSZXNvbHZlcyBhIGxpc3Qgb2YgZnVuY3Rpb25zIHNlcXVlbnRpYWxseSwgd2hpY2ggY2FuIGJlIHN5bmMgb3IgYXN5bmM7IGluXG4gKiBjYXNlIG9mIGFzeW5jLCBmdW5jdGlvbnMgbXVzdCByZXR1cm4gYSBwcm9taXNlLlxuICpcbiAqIEBwYXJhbSAge0FycmF5fSBmbnMgIFRoZSBsaXN0IG9mIGZ1bmN0aW9ucy5cbiAqIEBwYXJhbSAge0FueX0gICBpbml0IFRoZSBpbml0aWFsIHZhbHVlLlxuICogQHJldHVybiB7UHJvbWlzZX1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHdhdGVyZmFsbChmbnMsIGluaXQpIHtcbiAgaWYgKCFmbnMubGVuZ3RoKSB7XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShpbml0KTtcbiAgfVxuICByZXR1cm4gZm5zLnJlZHVjZSgocHJvbWlzZSwgbmV4dEZuKSA9PiB7XG4gICAgcmV0dXJuIHByb21pc2UudGhlbihuZXh0Rm4pO1xuICB9LCBQcm9taXNlLnJlc29sdmUoaW5pdCkpO1xufVxuXG4vKipcbiAqIFNpbXBsZSBkZWVwIG9iamVjdCBjb21wYXJpc29uIGZ1bmN0aW9uLiBUaGlzIG9ubHkgc3VwcG9ydHMgY29tcGFyaXNvbiBvZlxuICogc2VyaWFsaXphYmxlIEphdmFTY3JpcHQgb2JqZWN0cy5cbiAqXG4gKiBAcGFyYW0gIHtPYmplY3R9IGEgVGhlIHNvdXJjZSBvYmplY3QuXG4gKiBAcGFyYW0gIHtPYmplY3R9IGIgVGhlIGNvbXBhcmVkIG9iamVjdC5cbiAqIEByZXR1cm4ge0Jvb2xlYW59XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBkZWVwRXF1YWwoYSwgYikge1xuICBpZiAoYSA9PT0gYikge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG4gIGlmICh0eXBlb2YgYSAhPT0gdHlwZW9mIGIpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgaWYgKCEoYSAmJiB0eXBlb2YgYSA9PSBcIm9iamVjdFwiKSB8fCAhKGIgJiYgdHlwZW9mIGIgPT0gXCJvYmplY3RcIikpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgaWYgKE9iamVjdC5rZXlzKGEpLmxlbmd0aCAhPT0gT2JqZWN0LmtleXMoYikubGVuZ3RoKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIGZvciAoY29uc3QgayBpbiBhKSB7XG4gICAgaWYgKCFkZWVwRXF1YWwoYVtrXSwgYltrXSkpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHRydWU7XG59XG5cbi8qKlxuICogUmV0dXJuIGFuIG9iamVjdCB3aXRob3V0IHRoZSBzcGVjaWZpZWQga2V5cy5cbiAqXG4gKiBAcGFyYW0gIHtPYmplY3R9IG9iaiAgICAgICAgVGhlIG9yaWdpbmFsIG9iamVjdC5cbiAqIEBwYXJhbSAge0FycmF5fSAga2V5cyAgICAgICBUaGUgbGlzdCBvZiBrZXlzIHRvIGV4Y2x1ZGUuXG4gKiBAcmV0dXJuIHtPYmplY3R9ICAgICAgICAgICAgQSBjb3B5IHdpdGhvdXQgdGhlIHNwZWNpZmllZCBrZXlzLlxuICovXG5leHBvcnQgZnVuY3Rpb24gb21pdEtleXMob2JqLCBrZXlzID0gW10pIHtcbiAgY29uc3QgcmVzdWx0ID0geyAuLi5vYmogfTtcbiAgZm9yIChjb25zdCBrZXkgb2Yga2V5cykge1xuICAgIGRlbGV0ZSByZXN1bHRba2V5XTtcbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gYXJyYXlFcXVhbChhLCBiKSB7XG4gIGlmIChhLmxlbmd0aCAhPT0gYi5sZW5ndGgpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgZm9yIChsZXQgaSA9IGEubGVuZ3RoOyBpLS07ICkge1xuICAgIGlmIChhW2ldICE9PSBiW2ldKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG4gIHJldHVybiB0cnVlO1xufVxuXG5mdW5jdGlvbiBtYWtlTmVzdGVkT2JqZWN0RnJvbUFycihhcnIsIHZhbCwgbmVzdGVkRmlsdGVyc09iaikge1xuICBjb25zdCBsYXN0ID0gYXJyLmxlbmd0aCAtIDE7XG4gIHJldHVybiBhcnIucmVkdWNlKChhY2MsIGN2LCBpKSA9PiB7XG4gICAgaWYgKGkgPT09IGxhc3QpIHtcbiAgICAgIHJldHVybiAoYWNjW2N2XSA9IHZhbCk7XG4gICAgfSBlbHNlIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYWNjLCBjdikpIHtcbiAgICAgIHJldHVybiBhY2NbY3ZdO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gKGFjY1tjdl0gPSB7fSk7XG4gICAgfVxuICB9LCBuZXN0ZWRGaWx0ZXJzT2JqKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHRyYW5zZm9ybVN1Yk9iamVjdEZpbHRlcnMoZmlsdGVyc09iaikge1xuICBjb25zdCB0cmFuc2Zvcm1lZEZpbHRlcnMgPSB7fTtcbiAgZm9yIChjb25zdCBrZXkgaW4gZmlsdGVyc09iaikge1xuICAgIGNvbnN0IGtleXNBcnIgPSBrZXkuc3BsaXQoXCIuXCIpO1xuICAgIGNvbnN0IHZhbCA9IGZpbHRlcnNPYmpba2V5XTtcbiAgICBtYWtlTmVzdGVkT2JqZWN0RnJvbUFycihrZXlzQXJyLCB2YWwsIHRyYW5zZm9ybWVkRmlsdGVycyk7XG4gIH1cbiAgcmV0dXJuIHRyYW5zZm9ybWVkRmlsdGVycztcbn1cbiJdfQ==